From c26b55a06e50736567802922563e996a918e8c6c Mon Sep 17 00:00:00 2001 From: s3lph Date: Sat, 30 Nov 2024 14:13:36 +0100 Subject: [PATCH] feat: improved error handling --- honeywell-config.c | 74 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 51 insertions(+), 23 deletions(-) diff --git a/honeywell-config.c b/honeywell-config.c index 657319d..e49c598 100644 --- a/honeywell-config.c +++ b/honeywell-config.c @@ -8,6 +8,17 @@ #include +#define S_ENQ 0x05 +#define S_ACK 0x06 +#define S_NAK 0x15 + +#define USBERR(msg, rc) { dprintf(2, "%s: %s\n", msg, libusb_strerror(rc)); } +#define DEBUG(...) { if (debug >= 1) { dprintf(2, __VA_ARGS__); } } +#define DEBUG2(...) { if (debug >= 2) { dprintf(2, __VA_ARGS__); } } +#define DEBUG3(...) { if (debug >= 3) { dprintf(2, __VA_ARGS__); } } +#define HEXBUF(msg, buf, n) { if (debug >= 3) { dprintf(2, "%s:", msg); for (uint8_t *__h = buf; __h < buf+n;++__h) { dprintf(2, " %02x", *__h); } dprintf(2, "\n"); } } + + uint16_t vendor_id = 0; uint16_t product_id = 0; uint8_t reset = 0; @@ -20,12 +31,6 @@ uint8_t explicit_in = 0; libusb_device_handle *devh = NULL; uint8_t endpoint = 0; -#define USBERR(msg, rc) { dprintf(2, "%s: %s\n", msg, libusb_strerror(rc)); } -#define DEBUG(...) { if (debug >= 1) { dprintf(2, __VA_ARGS__); } } -#define DEBUG2(...) { if (debug >= 2) { dprintf(2, __VA_ARGS__); } } -#define DEBUG3(...) { if (debug >= 3) { dprintf(2, __VA_ARGS__); } } -#define HEXBUF(msg, buf, n) { if (debug >= 3) { dprintf(2, "%s:", msg); for (uint8_t *__h = buf; __h < buf+n;++__h) { dprintf(2, " %02x", *__h); } dprintf(2, "\n"); } } - uint32_t vidpid[] = { 0x0c2e0b01, @@ -38,14 +43,16 @@ struct tokenizer { char tokbuf[1024]; char *tok; uint8_t eot; - int (*cb)(const char *tok, uint8_t last); + uint8_t status; + int (*cb)(const char *, uint8_t , uint8_t); }; -void tok_init(struct tokenizer *t, int (*cb)(const char *tok, uint8_t last)) { +void tok_init(struct tokenizer *t, int (*cb)(const char *, uint8_t, uint8_t)) { memset(t->tokbuf, 0, 1024); t->tok = t->tokbuf; t->eot = 0; + t->status = 0; t->cb = cb; } @@ -63,14 +70,16 @@ int tok_read(struct tokenizer *t, char *buf, size_t n) { } if (end) { if (end > start) { - for (char *c = start; c < end; ++c) { + for (char *c = start; c < end < buf+n; ++c) { if (isprint(*c)) { *(t->tok++) = *c; + } else { + t->status = *c; } } } *(t->tok) = 0; - if (t->cb(t->tokbuf, t->eot)) { + if (t->cb(t->tokbuf, t->status, t->eot)) { return 1; } t->tok = t->tokbuf; @@ -86,6 +95,8 @@ int tok_read(struct tokenizer *t, char *buf, size_t n) { for (char *c = start; *c != 0; ++c) { if (isprint(*c)) { *(t->tok++) = *c; + } else { + t->status = *c; } } *(t->tok) = 0; @@ -99,28 +110,45 @@ struct tokenizer in_tok; struct tokenizer out_tok; -int print_token(const char *tok, uint8_t last) { - int rc; - if (oneline && !last) { - rc = dprintf(outfd, "%s;", tok); - } else { - rc = dprintf(outfd, "%s.\n", tok); +int print_token(const char *tok, uint8_t status, uint8_t last) { + switch (status) { + case S_ACK: + int rc; + if (oneline && !last) { + rc = dprintf(outfd, "%s;", tok); + } else { + rc = dprintf(outfd, "%s.\n", tok); + } + return rc < 0; + case S_ENQ: + dprintf(2, "command not recognized by device: %s\n", tok); + return 1; + case S_NAK: + dprintf(2, "command data out of bounds: %s\n", tok); + return 1; + default: + dprintf(2, "device responded to command %s with unknown status 0x%02x\n", tok, status); + return 1; } - return rc < 0; } -int send_token(const char *tok, uint8_t last) { +int send_token(const char *tok, uint8_t status, uint8_t last) { in_tok.eot = 0; - uint8_t cmd[64] = { 0 }; + uint8_t cmd[65] = { 0 }; + uint8_t *cmdend = cmd + 64; uint8_t *cmdptr = cmd + 5; int rc; - memset(cmdptr, 0, 59); - for (uint8_t i = 0; i < strlen(tok); ++i) { + memset(cmdptr, 0, 60); + for (uint8_t i = 0; i < strlen(tok) && cmdptr < cmdend; ++i) { if (isprint(tok[i])) { *(cmdptr++) = tok[i]; } } + if (cmdptr >= cmdend) { + dprintf(2, "token too long: %s\n", tok); + return 1; + } *cmdptr = '.'; cmd[0] = 0xfd; cmd[1] = cmdptr - cmd - 1; @@ -159,7 +187,7 @@ int config(int argc, char **args) { // If commands are provided on the CLI, execute only those if (argc > 0) { for (int i = 0; i < argc; ++i) { - if (send_token(args[i], i >= argc-1)) { + if (send_token(args[i], S_ACK, i >= argc-1)) { return 1; } } @@ -168,7 +196,7 @@ int config(int argc, char **args) { // If input is a tty, dump config // Can be overwritten with "-i -" on the cli if (isatty(infd) && !explicit_in) { - return send_token("?", 1); + return send_token("?", S_ACK, 1); } // Otherwhise parse tokens from stdin char buf[65];