From b5e57d268fe86cf58116c03166d45c130280dfb6 Mon Sep 17 00:00:00 2001 From: Michael Gernoth Date: Mon, 10 Feb 2014 22:35:58 +0100 Subject: [PATCH] firmware-updater works now (needs hmusbif.enc) --- .gitignore | 1 + Makefile | 2 +- flash-hmcfgusb.c | 79 ++++++++++++++++++++++++++++++++++-------------- hmcfgusb.c | 13 +++++--- 4 files changed, 67 insertions(+), 28 deletions(-) diff --git a/.gitignore b/.gitignore index b372796..d96fed7 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,4 @@ hmland.o hmsniff hmsniff.d hmsniff.o +hmusbif.enc diff --git a/Makefile b/Makefile index 56283ba..b1c1556 100644 --- a/Makefile +++ b/Makefile @@ -9,7 +9,7 @@ FLASH_HMCFGUSB_OBJS=hmcfgusb.o flash-hmcfgusb.o OBJS=$(HMLAN_OBJS) $(HMSNIFF_OBJS) $(FLASH_HMCFGUSB_OBJS) -all: hmland hmsniff +all: hmland hmsniff flash-hmcfgusb DEPEND=$(OBJS:.o=.d) -include $(DEPEND) diff --git a/flash-hmcfgusb.c b/flash-hmcfgusb.c index c7781a0..aebf781 100644 --- a/flash-hmcfgusb.c +++ b/flash-hmcfgusb.c @@ -39,23 +39,17 @@ #include "hmcfgusb.h" struct recv_data { + int ack; }; static int parse_hmcfgusb(uint8_t *buf, int buf_len, void *data) { - if (buf_len < 1) + struct recv_data *rdata = data; + + if (buf_len != 1) return 1; - switch(buf[0]) { - case 'E': - case 'H': - case 'R': - case 'I': - break; - default: - hexdump(buf, buf_len, "Unknown> "); - break; - } + rdata->ack = buf[0]; return 1; } @@ -83,28 +77,46 @@ int main(int argc, char **argv) uint8_t buf[4096]; uint8_t *outp; int fd; + int pfd; int r; int i; int cnt; int pkt; + int debug = 0; - hmcfgusb_set_debug(0); + hmcfgusb_set_debug(debug); memset(&rdata, 0, sizeof(rdata)); + fd = open("hmusbif.enc", O_RDONLY); + if (fd < 0) { + perror("Can't open hmusbif.enc"); + exit(EXIT_FAILURE); + } + dev = hmcfgusb_init(parse_hmcfgusb, &rdata); if (!dev) { fprintf(stderr, "Can't initialize HM-CFG-USB\n"); exit(EXIT_FAILURE); } - printf("HM-CFG-USB opened!\n"); - fd = open("hmusbif.enc", O_RDONLY); - if (fd < 0) { - perror("Can't open hmusbif.enc"); - exit(EXIT_FAILURE); + if (!dev->bootloader) { + fprintf(stderr, "HM-CFG-USB not in bootloader mode, entering bootloader.\n"); + hmcfgusb_enter_bootloader(dev); + fprintf(stderr, "\nWaiting for device to reappear...\n"); + + do { + sleep(1); + } while ((dev = hmcfgusb_init(parse_hmcfgusb, &rdata)) == NULL); + + if (!dev->bootloader) { + fprintf(stderr, "Can't enter bootloader, giving up!\n"); + exit(EXIT_FAILURE); + } } + printf("HM-CFG-USB opened!\n"); + cnt = 0; pkt = 0; do { @@ -128,8 +140,6 @@ int main(int argc, char **argv) len |= (ascii_to_nibble(buf[2]) & 0xf)<< 4; len |= ascii_to_nibble(buf[3]) & 0xf; - printf("packet length: %x\n", len); - r = read(fd, buf, len * 2); if (r < 0) { perror("read"); @@ -141,7 +151,6 @@ int main(int argc, char **argv) memset(out, 0, sizeof(out)); outp = out; - *outp++ = 'W'; *outp++ = (pkt >> 8) & 0xff; *outp++ = pkt & 0xff; *outp++ = (len >> 8) & 0xff; @@ -151,10 +160,34 @@ int main(int argc, char **argv) *outp |= ascii_to_nibble(buf[i+1]) & 0xf; outp++; } - cnt += r/2; + cnt = outp - out; printf("Flashing %d bytes...\n", cnt); - hexdump(out, outp-out, "F> "); - //hmcfgusb_send(dev, out, r/2, 1); + if (debug) + hexdump(out, cnt, "F> "); + + rdata.ack = 0; + if (!hmcfgusb_send(dev, out, cnt, 0)) { + perror("hmcfgusb_send"); + exit(EXIT_FAILURE); + } + + printf("Waiting for ack...\n"); + do { + errno = 0; + pfd = hmcfgusb_poll(dev, 1); + if ((pfd < 0) && errno) { + perror("hmcfgusb_poll"); + exit(EXIT_FAILURE); + } + if (rdata.ack) { + break; + } + } while (pfd < 0); + + if (rdata.ack == 2) { + printf("Firmware update successfull!\n"); + break; + } pkt++; } while (r > 0); diff --git a/hmcfgusb.c b/hmcfgusb.c index 01a50b7..90d741f 100644 --- a/hmcfgusb.c +++ b/hmcfgusb.c @@ -201,13 +201,13 @@ int hmcfgusb_send(struct hmcfgusb_dev *usbdev, unsigned char* send_data, int len return 1; } -static struct libusb_transfer *hmcfgusb_prepare_int(libusb_device_handle *devh, libusb_transfer_cb_fn cb, void *data) +static struct libusb_transfer *hmcfgusb_prepare_int(libusb_device_handle *devh, libusb_transfer_cb_fn cb, void *data, int in_size) { unsigned char *data_buf; struct libusb_transfer *transfer; int err; - data_buf = malloc(ASYNC_SIZE); + data_buf = malloc(in_size); if (!data_buf) { fprintf(stderr, "Can't allocate memory for data-buffer!\n"); return NULL; @@ -221,7 +221,7 @@ static struct libusb_transfer *hmcfgusb_prepare_int(libusb_device_handle *devh, } libusb_fill_interrupt_transfer(transfer, devh, EP_IN, - data_buf, ASYNC_SIZE, cb, data, USB_TIMEOUT); + data_buf, in_size, cb, data, USB_TIMEOUT); transfer->flags = LIBUSB_TRANSFER_SHORT_NOT_OK | LIBUSB_TRANSFER_FREE_BUFFER; @@ -345,7 +345,12 @@ struct hmcfgusb_dev *hmcfgusb_init(hmcfgusb_cb_fn cb, void *data) cb_data->cb = cb; cb_data->data = data; - dev->transfer = hmcfgusb_prepare_int(devh, hmcfgusb_interrupt, cb_data); + /* Bootloader can only say ack/nack/done */ + if (dev->bootloader) + dev->transfer = hmcfgusb_prepare_int(devh, hmcfgusb_interrupt, cb_data, 1); + else + dev->transfer = hmcfgusb_prepare_int(devh, hmcfgusb_interrupt, cb_data, ASYNC_SIZE); + if (!dev->transfer) { fprintf(stderr, "Can't prepare async device io!\n"); free(dev); -- 2.39.5