From f51714bea4af46dd81d3ed97acffea57201f108f Mon Sep 17 00:00:00 2001 From: Michael Gernoth Date: Sun, 13 Sep 2015 17:17:44 +0200 Subject: [PATCH] hmcfgusb: add possibility to use a specific HM-CFG-USB with -S 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 | 51 +++++++++++++++++++++++++++++++++++++++--------- flash-ota.c | 13 ++++++++---- hmcfgusb.c | 34 +++++++++++++++++++++++++++----- hmcfgusb.h | 2 +- hmland.c | 9 +++++++-- hmsniff.c | 9 +++++++-- 6 files changed, 95 insertions(+), 23 deletions(-) diff --git a/flash-hmcfgusb.c b/flash-hmcfgusb.c index a9ff876..7f296de 100644 --- a/flash-hmcfgusb.c +++ b/flash-hmcfgusb.c @@ -1,6 +1,6 @@ /* flasher for HM-CFG-USB * - * Copyright (c) 2013-14 Michael Gernoth + * Copyright (c) 2013-15 Michael Gernoth * * 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"); diff --git a/flash-ota.c b/flash-ota.c index a93446f..22f98ce 100644 --- a/flash-ota.c +++ b/flash-ota.c @@ -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)); } } diff --git a/hmcfgusb.c b/hmcfgusb.c index 652eb42..c82613f 100644 --- a/hmcfgusb.c +++ b/hmcfgusb.c @@ -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 diff --git a/hmcfgusb.h b/hmcfgusb.h index 7bfc53d..de94f23 100644 --- a/hmcfgusb.h +++ b/hmcfgusb.h @@ -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); diff --git a/hmland.c b/hmland.c index f0b07f2..8e5d6da 100644 --- 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; diff --git a/hmsniff.c b/hmsniff.c index f341044..9b59e2f 100644 --- 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); -- 2.39.2