summary |
shortlog |
log |
commit | commitdiff |
tree
raw |
patch |
inline | side by side (from parent 1:
bcc4286)
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.
/* flasher for HM-CFG-USB
*
/* 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
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
+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[] = { '-', '\\', '|', '/' };
int main(int argc, char **argv)
{
const char twiddlie[] = { '-', '\\', '|', '/' };
struct recv_data rdata;
uint16_t len;
struct firmware *fw;
struct recv_data rdata;
uint16_t len;
struct firmware *fw;
+ char *serial = "ABC";
+ char *filename = NULL;
- 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]);
- fw = firmware_read_firmware(argv[1], debug);
+ fw = firmware_read_firmware(filename, debug);
if (!fw)
exit(EXIT_FAILURE);
if (!fw)
exit(EXIT_FAILURE);
memset(&rdata, 0, sizeof(rdata));
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);
if (!dev) {
fprintf(stderr, "Can't initialize HM-CFG-USB\n");
exit(EXIT_FAILURE);
hmcfgusb_close(dev);
}
sleep(1);
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");
}
printf("\nHM-CFG-USB opened.\n\n");
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-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");
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");
uint8_t msgid = 0x1;
uint16_t len;
struct firmware *fw;
uint8_t msgid = 0x1;
uint16_t len;
struct firmware *fw;
+ char *hmcfgusb_serial = NULL;
int block;
int pfd;
int debug = 0;
int block;
int pfd;
int debug = 0;
printf("HomeMatic OTA flasher version " VERSION "\n\n");
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);
switch (opt) {
case 'b':
bps = atoi(optarg);
+ case 'S':
+ hmcfgusb_serial = optarg;
+ break;
case 'h':
case ':':
case '?':
case 'h':
case ':':
case '?':
hmcfgusb_set_debug(debug);
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);
if (!dev.hmcfgusb) {
fprintf(stderr, "Can't initialize HM-CFG-USB\n");
exit(EXIT_FAILURE);
hmcfgusb_close(dev.hmcfgusb);
}
sleep(1);
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) {
}
if (dev.hmcfgusb->bootloader) {
hmcfgusb_close(dev.hmcfgusb);
}
sleep(1);
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));
-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;
libusb_device_handle *devh = NULL;
libusb_device **list;
ssize_t cnt;
+ 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));
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));
-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;
{
libusb_device_handle *devh = NULL;
const struct libusb_pollfd **usb_pfd = NULL;
}
libusb_initialized = 1;
}
libusb_initialized = 1;
- devh = hmcfgusb_find(ID_VENDOR, ID_PRODUCT);
+ devh = hmcfgusb_find(ID_VENDOR, ID_PRODUCT, serial);
- devh = hmcfgusb_find(ID_VENDOR, ID_PRODUCT_BL);
+ devh = hmcfgusb_find(ID_VENDOR, ID_PRODUCT_BL, serial);
- 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
#ifdef NEED_LIBUSB_EXIT
hmcfgusb_exit();
#endif
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);
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);
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);
static int reboot_set = 0;
static uint8_t *lan_read_buf = NULL;
static int lan_read_buflen = 0;
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;
struct queued_rx {
char *rx;
hmcfgusb_set_debug(debug);
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;
if (!dev) {
fprintf(stderr, "Can't initialize HM-CFG-USB!\n");
return 0;
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-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");
fprintf(stderr, "\t-v\t\tverbose mode\n");
fprintf(stderr, "\t-V\t\tshow version (" VERSION ")\n");
- 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;
switch (opt) {
case 'D':
debug = 1;
exit(EXIT_FAILURE);
}
break;
exit(EXIT_FAILURE);
}
break;
+ case 'S':
+ serial = optarg;
+ break;
case 'v':
verbose = 1;
break;
case 'v':
verbose = 1;
break;
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, "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");
fprintf(stderr, "\t-v\t\tverbose mode\n");
fprintf(stderr, "\t-V\t\tshow version (" VERSION ")\n");
{
struct hmcfgusb_dev *dev;
struct recv_data rdata;
{
struct hmcfgusb_dev *dev;
struct recv_data rdata;
int quit = 0;
int speed = 10;
uint8_t speed_buf[2];
int opt;
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;
switch (opt) {
case 'f':
speed = 100;
break;
+ case 'S':
+ serial = optarg;
+ break;
case 'v':
verbose = 1;
break;
case 'v':
verbose = 1;
break;
memset(&rdata, 0, sizeof(rdata));
rdata.wrong_hmid = 0;
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);
if (!dev) {
fprintf(stderr, "Can't initialize HM-CFG-USB, retrying in 1s...\n");
sleep(1);