Improve a comment in visomat-data-downloader.c
[visomat-utils.git] / src / visomat-data-downloader.c
index 8cb99e2..c2b8590 100644 (file)
@@ -21,6 +21,7 @@
 
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
 #include <errno.h>
 #include <unistd.h>
 #include <libusb.h>
@@ -118,7 +119,7 @@ static void print_record_csv_compat(struct datetime *d, struct pressure *p)
        printf("\n");
 }
 
-/* TODO separate better decoding data from printing it */
+/* TODO: it would be better to separate decoding data from printing it */
 static int decode_eeprom(unsigned char *buffer,
                         unsigned int len,
                         unsigned int user_mask)
@@ -316,10 +317,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 +332,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, &current_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 %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, "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 %hhu\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, &current_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: %hhu, current: %hhu\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;