X-Git-Url: https://git.ao2.it/visomat-utils.git/blobdiff_plain/ec6cf524733f65ff40ac2e086e96e0dfd38e1dda..687aee331eeb10d36367dc6a6c612a5466fc40df:/src/visomat-data-downloader.c?ds=inline diff --git a/src/visomat-data-downloader.c b/src/visomat-data-downloader.c index 0eca9c1..f93757d 100644 --- a/src/visomat-data-downloader.c +++ b/src/visomat-data-downloader.c @@ -21,19 +21,21 @@ #include #include +#include #include #include #include +#define VISOMAT_DEVICE_VID 0x1247 +#define VISOMAT_DEVICE_PID 0x00f8 +#define VISOMAT_CONFIGURATION 1 +#define VISOMAT_INTERFACE 1 +#define VISOMAT_EP_IN 0x82 +#define VISOMAT_EP_OUT 0x03 + #define STX 0x02 #define ETX 0x03 -#define DEVICE_VID 0x1247 -#define DEVICE_PID 0x00f8 - -#define EP_IN 0x82 -#define EP_OUT 0x03 - #define BASE_YEAR 2000 typedef enum { @@ -63,6 +65,7 @@ struct datetime { }; struct pressure { + unsigned int flag; /* XXX Maybe this means arrhythmia? */ unsigned int systolic; unsigned int diastolic; unsigned int pulses; @@ -102,16 +105,24 @@ static void print_record_csv_compat(struct datetime *d, struct pressure *p) pulse_pressure = p->systolic - p->diastolic; printf("%u;", pulse_pressure); + if (p->flag) + printf("x"); + +#if 0 + /* The original software does not seem to be doing that */ if (p->pulses > 100) printf("tachycardia"); else if (p->pulses < 60) printf("bradycardia"); +#endif printf("\n"); } /* TODO separate better decoding data from printing it */ -static int decode_eeprom(unsigned char *buffer, unsigned int len) +static int decode_eeprom(unsigned char *buffer, + unsigned int len, + unsigned int user_mask) { int ret; unsigned int n; @@ -137,7 +148,6 @@ static int decode_eeprom(unsigned char *buffer, unsigned int len) /* i tracks the bytes consumed */ i += 1; - ret = sscanf((char *)(buffer + i), "%1u%02u", &user_id, &num_records); if (ret != 2) @@ -146,8 +156,6 @@ static int decode_eeprom(unsigned char *buffer, unsigned int len) /* user_id and num_records take 3 bytes */ i += 3; - printf("# User: %d\n", user_id); - for (j = 0; j < num_records; j++) { ret = extract_datetime(buffer + i, &d); if (ret < 0) @@ -157,17 +165,23 @@ static int decode_eeprom(unsigned char *buffer, unsigned int len) i += 10; ret = sscanf((char *)(buffer + i), - "%04u%03u%03u", + "%1u%03u%03u%03u", + &p.flag, &p.systolic, &p.diastolic, &p.pulses); - if (ret != 3) + if (ret != 4) return -EINVAL; /* pressure data is 10 bytes */ i += 10; - print_record_csv_compat(&d, &p); + /* TODO: split out the printing part */ + if (user_id & user_mask) { + if (j == 0) + printf("# User: %d\n", user_id); + print_record_csv_compat(&d, &p); + } } } } @@ -212,7 +226,7 @@ static int send_command(libusb_device_handle *dev, visomat_command cmd) request[4] = ETX; transferred = 0; - ret = libusb_bulk_transfer(dev, EP_OUT, request, sizeof(request), &transferred, 0); + ret = libusb_bulk_transfer(dev, VISOMAT_EP_OUT, request, sizeof(request), &transferred, 0); if (ret != 0 || transferred != sizeof(request)) { fprintf(stderr, "Error: sending request: %d (%s)\ttransferred: %d (expected %zu)\n", ret, libusb_error_name(ret), transferred, sizeof(request)); @@ -235,7 +249,7 @@ static int get_response(libusb_device_handle *dev, unsigned int j; transferred = 0; - ret = libusb_bulk_transfer(dev, EP_IN, response, sizeof(response), &transferred, 5000); + ret = libusb_bulk_transfer(dev, VISOMAT_EP_IN, response, sizeof(response), &transferred, 5000); if (ret != 0) { fprintf(stderr, "Error getting response: %d (%s)\ttransferred: %d (expected %zu)\n", ret, libusb_error_name(ret), transferred, sizeof(response)); @@ -258,7 +272,7 @@ static int get_response(libusb_device_handle *dev, /* Candidates for a future public API, if a shared library will ever be made */ #define visomat_device libusb_device_handle -static int visomat_dump_eeprom(visomat_device *dev) +static int visomat_dump_eeprom(visomat_device *dev, unsigned int user_mask) { /* Assuming an EEPROM of 1 KiB */ unsigned char buffer[1024] = { 0 }; @@ -272,7 +286,7 @@ static int visomat_dump_eeprom(visomat_device *dev) if (ret < 0) return ret; - ret = decode_eeprom(buffer, ret); + ret = decode_eeprom(buffer, ret, user_mask); if (ret < 0) return ret; @@ -304,29 +318,58 @@ int main(void) int ret; libusb_device_handle *dev; - libusb_init(NULL); + ret = libusb_init(NULL); + if (ret < 0) { + fprintf(stderr, "libusb_init failed: %s\n", libusb_error_name(ret)); + goto out; + } + libusb_set_debug(NULL, LIBUSB_LOG_LEVEL_INFO); - dev = libusb_open_device_with_vid_pid(NULL, DEVICE_VID, DEVICE_PID); + dev = libusb_open_device_with_vid_pid(NULL, + VISOMAT_DEVICE_VID, + VISOMAT_DEVICE_PID); if (dev == NULL) { - fprintf(stderr, "Couldn't open device.\n"); - ret = -ENODEV; + fprintf(stderr, "libusb_open failed: %s\n", strerror(errno)); + ret = -errno; goto out_libusb_exit; } - libusb_set_configuration(dev, 1); - libusb_claim_interface(dev, 1); - libusb_detach_kernel_driver(dev, 1); + 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 %hhu\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, "libusb_claim_interface failed: %s\n", + libusb_error_name(ret)); + fprintf(stderr, "Cannot claim interface %hhu\n", + VISOMAT_INTERFACE); + goto out_libusb_close; + } ret = visomat_get_datetime(dev); if (ret < 0) - goto out; + goto out_libusb_release_interface; - ret = visomat_dump_eeprom(dev); + ret = visomat_dump_eeprom(dev, 0x01 | 0x02); + if (ret < 0) + goto out_libusb_release_interface; -out: +out_libusb_release_interface: + libusb_release_interface(dev, VISOMAT_INTERFACE); +out_libusb_close: libusb_close(dev); + dev = NULL; out_libusb_exit: libusb_exit(NULL); +out: return ret; }