hmcfgusb: add possibility to use a specific HM-CFG-USB with -S
authorMichael Gernoth <michael@gernoth.net>
Sun, 13 Sep 2015 15:17:44 +0000 (17:17 +0200)
committerMichael Gernoth <michael@gernoth.net>
Sun, 13 Sep 2015 15:23:22 +0000 (17:23 +0200)
This makes it possible to connect multiple HM-CFG-USB-devices to a
machine and run multiple instances of hmland, update the firmware
of a specific HM-CFG-USB or use a specific device for OTA updates.

flash-hmcfgusb.c
flash-ota.c
hmcfgusb.c
hmcfgusb.h
hmland.c
hmsniff.c

index a9ff876..7f296de 100644 (file)
@@ -1,6 +1,6 @@
 /* flasher for HM-CFG-USB
  *
- * Copyright (c) 2013-14 Michael Gernoth <michael@gernoth.net>
+ * Copyright (c) 2013-15 Michael Gernoth <michael@gernoth.net>
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
  * of this software and associated documentation files (the "Software"), to
@@ -56,6 +56,15 @@ static int parse_hmcfgusb(uint8_t *buf, int buf_len, void *data)
        return 1;
 }
 
+void flash_hmcfgusb_syntax(char *prog)
+{
+       fprintf(stderr, "Syntax: %s [options] filename.enc\n\n", prog);
+       fprintf(stderr, "Possible options:\n");
+       fprintf(stderr, "\t-S serial\tuse HM-CFG-USB with given serial\n");
+       fprintf(stderr, "\t-V\t\tshow version (" VERSION ")\n");
+
+}
+
 int main(int argc, char **argv)
 {
        const char twiddlie[] = { '-', '\\', '|', '/' };
@@ -63,21 +72,45 @@ int main(int argc, char **argv)
        struct recv_data rdata;
        uint16_t len;
        struct firmware *fw;
+       char *serial = "ABC";
+       char *filename = NULL;
        int block;
        int pfd;
+       int opt;
        int debug = 0;
 
-       printf("HM-CFG-USB flasher version " VERSION "\n\n");
+       while((opt = getopt(argc, argv, "S:V")) != -1) {
+               switch (opt) {
+                       case 'S':
+                               serial = optarg;
+                               break;
+                       case 'V':
+                               printf("flash-hmcfgusb " VERSION "\n");
+                               printf("Copyright (c) 2013-15 Michael Gernoth\n\n");
+                               exit(EXIT_SUCCESS);
+                       case 'h':
+                       case ':':
+                       case '?':
+                       default:
+                               flash_hmcfgusb_syntax(argv[0]);
+                               exit(EXIT_FAILURE);
+                               break;
+               }
+       }
 
-       if (argc != 2) {
-               if (argc == 1)
-                       fprintf(stderr, "Missing firmware filename!\n\n");
+       if (optind == argc - 1) {
+               filename = argv[optind];
+       }
+
+       printf("HM-CFG-USB flasher version " VERSION "\n\n");
 
-               fprintf(stderr, "Syntax: %s hmusbif.enc\n\n", argv[0]);
+       if (!filename) {
+               fprintf(stderr, "Missing firmware filename!\n\n");
+               flash_hmcfgusb_syntax(argv[0]);
                exit(EXIT_FAILURE);
        }
 
-       fw = firmware_read_firmware(argv[1], debug);
+       fw = firmware_read_firmware(filename, debug);
        if (!fw)
                exit(EXIT_FAILURE);
 
@@ -85,7 +118,7 @@ int main(int argc, char **argv)
 
        memset(&rdata, 0, sizeof(rdata));
 
-       dev = hmcfgusb_init(parse_hmcfgusb, &rdata);
+       dev = hmcfgusb_init(parse_hmcfgusb, &rdata, serial);
        if (!dev) {
                fprintf(stderr, "Can't initialize HM-CFG-USB\n");
                exit(EXIT_FAILURE);
@@ -102,7 +135,7 @@ int main(int argc, char **argv)
                                hmcfgusb_close(dev);
                        }
                        sleep(1);
-               } while (((dev = hmcfgusb_init(parse_hmcfgusb, &rdata)) == NULL) || (!dev->bootloader));
+               } while (((dev = hmcfgusb_init(parse_hmcfgusb, &rdata, serial)) == NULL) || (!dev->bootloader));
        }
 
        printf("\nHM-CFG-USB opened.\n\n");
index a93446f..22f98ce 100644 (file)
@@ -406,6 +406,7 @@ void flash_ota_syntax(char *prog)
        fprintf(stderr, "\t-c device\tenable CUL-mode with CUL at path \"device\"\n");
        fprintf(stderr, "\t-b bps\t\tuse CUL with speed \"bps\" (default: %u)\n", DEFAULT_CUL_BPS);
        fprintf(stderr, "\t-l\t\tlower payloadlen (required for devices with little RAM, e.g. CUL v2 and CUL v4)\n");
+       fprintf(stderr, "\t-S serial\tuse HM-CFG-USB with given serial\n");
        fprintf(stderr, "\t-h\t\tthis help\n");
        fprintf(stderr, "\nOptional parameters for automatically sending device to bootloader\n");
        fprintf(stderr, "\t-C\t\tHMID of central (3 hex-bytes, no prefix, e.g. ABCDEF)\n");
@@ -429,6 +430,7 @@ int main(int argc, char **argv)
        uint8_t msgid = 0x1;
        uint16_t len;
        struct firmware *fw;
+       char *hmcfgusb_serial = NULL;
        int block;
        int pfd;
        int debug = 0;
@@ -440,7 +442,7 @@ int main(int argc, char **argv)
 
        printf("HomeMatic OTA flasher version " VERSION "\n\n");
 
-       while((opt = getopt(argc, argv, "b:c:f:hls:C:D:K:")) != -1) {
+       while((opt = getopt(argc, argv, "b:c:f:hls:C:D:K:S:")) != -1) {
                switch (opt) {
                        case 'b':
                                bps = atoi(optarg);
@@ -494,6 +496,9 @@ int main(int argc, char **argv)
                                        endptr += 2;
                                }
                                break;
+                       case 'S':
+                               hmcfgusb_serial = optarg;
+                               break;
                        case 'h':
                        case ':':
                        case '?':
@@ -563,7 +568,7 @@ int main(int argc, char **argv)
 
                hmcfgusb_set_debug(debug);
 
-               dev.hmcfgusb = hmcfgusb_init(parse_hmcfgusb, &rdata);
+               dev.hmcfgusb = hmcfgusb_init(parse_hmcfgusb, &rdata, hmcfgusb_serial);
                if (!dev.hmcfgusb) {
                        fprintf(stderr, "Can't initialize HM-CFG-USB\n");
                        exit(EXIT_FAILURE);
@@ -608,7 +613,7 @@ int main(int argc, char **argv)
                                                hmcfgusb_close(dev.hmcfgusb);
                                        }
                                        sleep(1);
-                               } while (((dev.hmcfgusb = hmcfgusb_init(parse_hmcfgusb, &rdata)) == NULL) || (!dev.hmcfgusb->bootloader));
+                               } while (((dev.hmcfgusb = hmcfgusb_init(parse_hmcfgusb, &rdata, hmcfgusb_serial)) == NULL) || (!dev.hmcfgusb->bootloader));
                        }
 
                        if (dev.hmcfgusb->bootloader) {
@@ -621,7 +626,7 @@ int main(int argc, char **argv)
                                                hmcfgusb_close(dev.hmcfgusb);
                                        }
                                        sleep(1);
-                               } while (((dev.hmcfgusb = hmcfgusb_init(parse_hmcfgusb, &rdata)) == NULL) || (dev.hmcfgusb->bootloader));
+                               } while (((dev.hmcfgusb = hmcfgusb_init(parse_hmcfgusb, &rdata, hmcfgusb_serial)) == NULL) || (dev.hmcfgusb->bootloader));
                        }
                }
 
index 652eb42..c82613f 100644 (file)
@@ -99,7 +99,7 @@ static char * usb_strerror(int e)
        return unknerr;
 }
 
-static libusb_device_handle *hmcfgusb_find(int vid, int pid) {
+static libusb_device_handle *hmcfgusb_find(int vid, int pid, char *serial) {
        libusb_device_handle *devh = NULL;
        libusb_device **list;
        ssize_t cnt;
@@ -129,6 +129,26 @@ static libusb_device_handle *hmcfgusb_find(int vid, int pid) {
                                return NULL;
                        }
 
+                       if (serial) {
+                               if (desc.iSerialNumber > 0) {
+                                       uint8_t devSerial[256];
+                                       err = libusb_get_string_descriptor_ascii(devh, desc.iSerialNumber, devSerial, sizeof(devSerial));
+                                       if (err < 0) {
+                                               fprintf(stderr, "Can't read serial-number: %s\n", usb_strerror(err));
+                                               libusb_close(devh);
+                                               libusb_free_device_list(list, 1);
+                                               return NULL;
+                                       }
+                                       if (strcmp((char*)devSerial, (char*)serial)) {
+                                               libusb_close(devh);
+                                               continue;
+                                       }
+                               } else {
+                                       libusb_close(devh);
+                                       continue;
+                               }
+                       }
+
                        err = libusb_detach_kernel_driver(devh, INTERFACE);
                        if ((err != 0) && (err != LIBUSB_ERROR_NOT_FOUND)) {
                                fprintf(stderr, "Can't detach kernel driver: %s\n", usb_strerror(err));
@@ -296,7 +316,7 @@ out:
        }
 }
 
-struct hmcfgusb_dev *hmcfgusb_init(hmcfgusb_cb_fn cb, void *data)
+struct hmcfgusb_dev *hmcfgusb_init(hmcfgusb_cb_fn cb, void *data, char *serial)
 {
        libusb_device_handle *devh = NULL;
        const struct libusb_pollfd **usb_pfd = NULL;
@@ -315,11 +335,15 @@ struct hmcfgusb_dev *hmcfgusb_init(hmcfgusb_cb_fn cb, void *data)
        }
        libusb_initialized = 1;
 
-       devh = hmcfgusb_find(ID_VENDOR, ID_PRODUCT);
+       devh = hmcfgusb_find(ID_VENDOR, ID_PRODUCT, serial);
        if (!devh) {
-               devh = hmcfgusb_find(ID_VENDOR, ID_PRODUCT_BL);
+               devh = hmcfgusb_find(ID_VENDOR, ID_PRODUCT_BL, serial);
                if (!devh) {
-                       fprintf(stderr, "Can't find/open hmcfgusb!\n");
+                       if (serial) {
+                               fprintf(stderr, "Can't find/open HM-CFG-USB with serial %s!\n", serial);
+                       } else {
+                               fprintf(stderr, "Can't find/open HM-CFG-USB!\n");
+                       }
 #ifdef NEED_LIBUSB_EXIT
                        hmcfgusb_exit();
 #endif
index 7bfc53d..de94f23 100644 (file)
@@ -35,7 +35,7 @@ struct hmcfgusb_dev {
 
 int hmcfgusb_send(struct hmcfgusb_dev *usbdev, unsigned char* send_data, int len, int done);
 int hmcfgusb_send_null_frame(struct hmcfgusb_dev *usbdev, int silent);
-struct hmcfgusb_dev *hmcfgusb_init(hmcfgusb_cb_fn cb, void *data);
+struct hmcfgusb_dev *hmcfgusb_init(hmcfgusb_cb_fn cb, void *data, char *serial);
 int hmcfgusb_add_pfd(struct hmcfgusb_dev *dev, int fd, short events);
 int hmcfgusb_poll(struct hmcfgusb_dev *dev, int timeout);
 void hmcfgusb_enter_bootloader(struct hmcfgusb_dev *dev);
index f0b07f2..8e5d6da 100644 (file)
--- a/hmland.c
+++ b/hmland.c
@@ -65,6 +65,7 @@ static int reboot_at_minute = -1;
 static int reboot_set = 0;
 static uint8_t *lan_read_buf = NULL;
 static int lan_read_buflen = 0;
+static char *serial = NULL;
 
 struct queued_rx {
        char *rx;
@@ -505,7 +506,7 @@ static int comm(int fd_in, int fd_out, int master_socket, int flags)
 
        hmcfgusb_set_debug(debug);
 
-       dev = hmcfgusb_init(hmlan_format_out, &fd_out);
+       dev = hmcfgusb_init(hmlan_format_out, &fd_out, serial);
        if (!dev) {
                fprintf(stderr, "Can't initialize HM-CFG-USB!\n");
                return 0;
@@ -808,6 +809,7 @@ void hmlan_syntax(char *prog)
        fprintf(stderr, "\t-p n\t\tlisten on port n (default: 1000)\n");
        fprintf(stderr, "\t-r n\t\treboot HM-CFG-USB after n seconds (0: no reboot, default: %u if FW < 0.967, 0 otherwise)\n", DEFAULT_REBOOT_SECONDS);
        fprintf(stderr, "\t   hh:mm\treboot HM-CFG-USB daily at hh:mm\n");
+       fprintf(stderr, "\t-S serial\tuse HM-CFG-USB with given serial (for multiple hmland instances)\n");
        fprintf(stderr, "\t-v\t\tverbose mode\n");
        fprintf(stderr, "\t-V\t\tshow version (" VERSION ")\n");
 
@@ -822,7 +824,7 @@ int main(int argc, char **argv)
        char *ep;
        int opt;
        
-       while((opt = getopt(argc, argv, "DdhIiPp:Rr:l:L:vV")) != -1) {
+       while((opt = getopt(argc, argv, "DdhIiPp:Rr:l:L:S:vV")) != -1) {
                switch (opt) {
                        case 'D':
                                debug = 1;
@@ -880,6 +882,9 @@ int main(int argc, char **argv)
                                        exit(EXIT_FAILURE);
                                }
                                break;
+                       case 'S':
+                               serial = optarg;
+                               break;
                        case 'v':
                                verbose = 1;
                                break;
index f341044..9b59e2f 100644 (file)
--- a/hmsniff.c
+++ b/hmsniff.c
@@ -214,6 +214,7 @@ void hmsniff_syntax(char *prog)
        fprintf(stderr, "Syntax: %s options\n\n", prog);
        fprintf(stderr, "Possible options:\n");
        fprintf(stderr, "\t-f\t\tfast (100k/firmware update) mode\n");
+       fprintf(stderr, "\t-S serial\tuse HM-CFG-USB with given serial\n");
        fprintf(stderr, "\t-v\t\tverbose mode\n");
        fprintf(stderr, "\t-V\t\tshow version (" VERSION ")\n");
 
@@ -223,16 +224,20 @@ int main(int argc, char **argv)
 {
        struct hmcfgusb_dev *dev;
        struct recv_data rdata;
+       char *serial = NULL;
        int quit = 0;
        int speed = 10;
        uint8_t speed_buf[2];
        int opt;
 
-       while((opt = getopt(argc, argv, "fvV")) != -1) {
+       while((opt = getopt(argc, argv, "fS:vV")) != -1) {
                switch (opt) {
                        case 'f':
                                speed = 100;
                                break;
+                       case 'S':
+                               serial = optarg;
+                               break;
                        case 'v':
                                verbose = 1;
                                break;
@@ -256,7 +261,7 @@ int main(int argc, char **argv)
                memset(&rdata, 0, sizeof(rdata));
                rdata.wrong_hmid = 0;
 
-               dev = hmcfgusb_init(parse_hmcfgusb, &rdata);
+               dev = hmcfgusb_init(parse_hmcfgusb, &rdata, serial);
                if (!dev) {
                        fprintf(stderr, "Can't initialize HM-CFG-USB, retrying in 1s...\n");
                        sleep(1);
Impressum, Datenschutz