firmware-updater works now (needs hmusbif.enc)
authorMichael Gernoth <michael@gernoth.net>
Mon, 10 Feb 2014 21:35:58 +0000 (22:35 +0100)
committerMichael Gernoth <michael@gernoth.net>
Mon, 10 Feb 2014 21:35:58 +0000 (22:35 +0100)
.gitignore
Makefile
flash-hmcfgusb.c
hmcfgusb.c

index b372796..d96fed7 100644 (file)
@@ -9,3 +9,4 @@ hmland.o
 hmsniff
 hmsniff.d
 hmsniff.o
 hmsniff
 hmsniff.d
 hmsniff.o
+hmusbif.enc
index 56283ba..b1c1556 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -9,7 +9,7 @@ FLASH_HMCFGUSB_OBJS=hmcfgusb.o flash-hmcfgusb.o
 
 OBJS=$(HMLAN_OBJS) $(HMSNIFF_OBJS) $(FLASH_HMCFGUSB_OBJS)
 
 
 OBJS=$(HMLAN_OBJS) $(HMSNIFF_OBJS) $(FLASH_HMCFGUSB_OBJS)
 
-all: hmland hmsniff
+all: hmland hmsniff flash-hmcfgusb
 
 DEPEND=$(OBJS:.o=.d)
 -include $(DEPEND)
 
 DEPEND=$(OBJS:.o=.d)
 -include $(DEPEND)
index c7781a0..aebf781 100644 (file)
 #include "hmcfgusb.h"
 
 struct recv_data {
 #include "hmcfgusb.h"
 
 struct recv_data {
+       int ack;
 };
 
 static int parse_hmcfgusb(uint8_t *buf, int buf_len, void *data)
 {
 };
 
 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;
 
                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;
 }
 
        return 1;
 }
@@ -83,28 +77,46 @@ int main(int argc, char **argv)
        uint8_t buf[4096];
        uint8_t *outp;
        int fd;
        uint8_t buf[4096];
        uint8_t *outp;
        int fd;
+       int pfd;
        int r;
        int i;
        int cnt;
        int pkt;
        int r;
        int i;
        int cnt;
        int pkt;
+       int debug = 0;
 
 
-       hmcfgusb_set_debug(0);
+       hmcfgusb_set_debug(debug);
 
        memset(&rdata, 0, sizeof(rdata));
 
 
        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);
        }
        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 {
        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;
 
                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");
                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;
 
                memset(out, 0, sizeof(out));
                outp = out;
-               *outp++ = 'W';
                *outp++ = (pkt >> 8) & 0xff;
                *outp++ = pkt & 0xff;
                *outp++ = (len >> 8) & 0xff;
                *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++;
                }
                        *outp |= ascii_to_nibble(buf[i+1]) & 0xf;
                        outp++;
                }
-               cnt += r/2;
+               cnt = outp - out;
                printf("Flashing %d bytes...\n", cnt);
                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);
 
                pkt++;
        } while (r > 0);
 
index 01a50b7..90d741f 100644 (file)
@@ -201,13 +201,13 @@ int hmcfgusb_send(struct hmcfgusb_dev *usbdev, unsigned char* send_data, int len
        return 1;
 }
 
        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;
 
 {
        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;
        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,
        }
 
        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;
 
 
        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;
 
        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);
        if (!dev->transfer) {
                fprintf(stderr, "Can't prepare async device io!\n");
                free(dev);
Impressum, Datenschutz