X-Git-Url: https://git.ao2.it/visomat-utils.git/blobdiff_plain/f7a9b92e7107a03a92e64a7091f0dea908210cda..0daf8407efa5df5aa5113abcaa2aed1b11e44440:/src/visomat-data-downloader.c diff --git a/src/visomat-data-downloader.c b/src/visomat-data-downloader.c index 8cb99e2..1b4cde9 100644 --- a/src/visomat-data-downloader.c +++ b/src/visomat-data-downloader.c @@ -21,6 +21,7 @@ #include #include +#include #include #include #include @@ -70,7 +71,7 @@ struct pressure { unsigned int pulses; }; -static inline int extract_datetime(unsigned char *buffer, struct datetime *d) +static inline int extract_datetime(uint8_t *buffer, struct datetime *d) { int ret; @@ -118,8 +119,8 @@ static void print_record_csv_compat(struct datetime *d, struct pressure *p) printf("\n"); } -/* TODO separate better decoding data from printing it */ -static int decode_eeprom(unsigned char *buffer, +/* TODO: it would be better to separate decoding data from printing it */ +static int decode_eeprom(uint8_t *buffer, unsigned int len, unsigned int user_mask) { @@ -155,6 +156,13 @@ static int decode_eeprom(unsigned char *buffer, /* user_id and num_records take 3 bytes */ i += 3; + /* + * when there are no records, there is a dummy byte + * which has to be consumed + */ + if (num_records == 0) + i += 1; + for (j = 0; j < num_records; j++) { ret = extract_datetime(buffer + i, &d); if (ret < 0) @@ -188,12 +196,12 @@ static int decode_eeprom(unsigned char *buffer, return 0; } -static int decode_datetime(unsigned char *buffer, unsigned int len) +static int decode_datetime(uint8_t *buffer, unsigned int len) { int ret; - unsigned char code[4] = { 0 }; + uint8_t code[4] = { 0 }; struct datetime d; - unsigned char *pbuffer = buffer; + uint8_t *pbuffer = buffer; if (len != 15) return -EINVAL; @@ -216,7 +224,7 @@ static int send_command(libusb_device_handle *dev, visomat_command cmd) { int ret; int transferred; - unsigned char request[5]; + uint8_t request[5]; request[0] = STX; request[1] = command_codes[cmd][0]; @@ -235,12 +243,12 @@ static int send_command(libusb_device_handle *dev, visomat_command cmd) } static int get_response(libusb_device_handle *dev, - unsigned char *buffer, + uint8_t *buffer, unsigned int len) { int ret; int transferred; - unsigned char response[64] = { 0 }; + uint8_t response[64] = { 0 }; unsigned int i; i = 0; @@ -274,7 +282,7 @@ static int get_response(libusb_device_handle *dev, static int visomat_dump_eeprom(visomat_device *dev, unsigned int user_mask) { /* Assuming an EEPROM of 1 KiB */ - unsigned char buffer[1024] = { 0 }; + uint8_t buffer[1024] = { 0 }; int ret; ret = send_command(dev, VISOMAT_CMD_DUMP_EEPROM); @@ -294,7 +302,7 @@ static int visomat_dump_eeprom(visomat_device *dev, unsigned int user_mask) static int visomat_get_datetime(visomat_device *dev) { - unsigned char buffer[255] = { 0 }; + uint8_t buffer[255] = { 0 }; int ret; ret = send_command(dev, VISOMAT_CMD_GET_DATETIME); @@ -316,10 +324,12 @@ int main(void) { int ret; libusb_device_handle *dev; + int current_configuration; ret = libusb_init(NULL); if (ret < 0) { - fprintf(stderr, "error (%d): cannot initialize libusb.\n", ret); + fprintf(stderr, "libusb_init failed: %s\n", + libusb_error_name(ret)); goto out; } @@ -329,27 +339,59 @@ int main(void) VISOMAT_DEVICE_VID, VISOMAT_DEVICE_PID); if (dev == NULL) { - fprintf(stderr, "error (%d): cannot open device.\n", errno); + fprintf(stderr, "libusb_open failed: %s\n", strerror(errno)); ret = -errno; goto out_libusb_exit; } - ret = libusb_set_configuration(dev, VISOMAT_CONFIGURATION); + current_configuration = -1; + ret = libusb_get_configuration(dev, ¤t_configuration); if (ret < 0) { - fprintf(stderr, "error (%d): cannot set configuration %d.\n", - ret, VISOMAT_CONFIGURATION); + fprintf(stderr, "libusb_get_configuration failed: %s\n", + libusb_error_name(ret)); goto out_libusb_close; } + if (current_configuration != VISOMAT_CONFIGURATION) { + ret = libusb_set_configuration(dev, VISOMAT_CONFIGURATION); + if (ret < 0) { + fprintf(stderr, "libusb_set_configuration failed: %s\n", + libusb_error_name(ret)); + fprintf(stderr, "Cannot set configuration %d\n", + VISOMAT_CONFIGURATION); + goto out_libusb_close; + } + } + libusb_set_auto_detach_kernel_driver(dev, 1); ret = libusb_claim_interface(dev, VISOMAT_INTERFACE); if (ret < 0) { - fprintf(stderr, "error (%d): cannot claim interface %d.\n", - ret, VISOMAT_INTERFACE); + fprintf(stderr, "libusb_claim_interface failed: %s\n", + libusb_error_name(ret)); + fprintf(stderr, "Cannot claim interface %d\n", + VISOMAT_INTERFACE); goto out_libusb_close; } + /* Checking that the configuration has not changed, as suggested in + * http://libusb.sourceforge.net/api-1.0/caveats.html + */ + current_configuration = -1; + ret = libusb_get_configuration(dev, ¤t_configuration); + if (ret < 0) { + fprintf(stderr, "libusb_get_configuration after claim failed: %s\n", + libusb_error_name(ret)); + goto out_libusb_release_interface; + } + + if (current_configuration != VISOMAT_CONFIGURATION) { + fprintf(stderr, "libusb configuration changed (expected: %d, current: %d)\n", + VISOMAT_CONFIGURATION, current_configuration); + ret = -EINVAL; + goto out_libusb_release_interface; + } + ret = visomat_get_datetime(dev); if (ret < 0) goto out_libusb_release_interface;