From a65c08fc834ac57cb4aab5470ca144d13076a2bd Mon Sep 17 00:00:00 2001 From: Michael Gernoth Date: Wed, 5 Mar 2014 11:41:00 +0100 Subject: [PATCH] add culfw firmware version-check --- culfw.c | 31 ++++++++++++++++ culfw.h | 1 + flash-ota.c | 105 +++++++++++++++++++++++++++++++++++++++++----------- 3 files changed, 116 insertions(+), 21 deletions(-) diff --git a/culfw.c b/culfw.c index 0dfb807..a4c949b 100644 --- a/culfw.c +++ b/culfw.c @@ -175,3 +175,34 @@ void culfw_close(struct culfw_dev *dev) { close(dev->fd); } + +void culfw_flush(struct culfw_dev *dev) +{ + struct pollfd pfds[1]; + int ret; + int r = 0; + uint8_t buf[1024]; + + tcflush(dev->fd, TCIOFLUSH); + + while(1) { + memset(pfds, 0, sizeof(struct pollfd) * 1); + + pfds[0].fd = dev->fd; + pfds[0].events = POLLIN; + + ret = poll(pfds, 1, 100); + if (ret <= 0) + break; + + if (!(pfds[0].revents & POLLIN)) + break; + + memset(buf, 0, sizeof(buf)); + r = read(dev->fd, buf, sizeof(buf)); + if (r <= 0) + break; + } + + return; +} diff --git a/culfw.h b/culfw.h index 29aacaf..6f310fc 100644 --- a/culfw.h +++ b/culfw.h @@ -35,3 +35,4 @@ struct culfw_dev *culfw_init(char *device, uint32_t speed, culfw_cb_fn cb, void int culfw_send(struct culfw_dev *dev, char *cmd, int cmdlen); int culfw_poll(struct culfw_dev *dev, int timeout); void culfw_close(struct culfw_dev *dev); +void culfw_flush(struct culfw_dev *dev); diff --git a/flash-ota.c b/flash-ota.c index fdd5936..31e2ab5 100644 --- a/flash-ota.c +++ b/flash-ota.c @@ -71,7 +71,7 @@ struct recv_data { enum message_type message_type; uint16_t status; int speed; - uint16_t hmcfgusb_version; + uint16_t version; }; static int parse_hmcfgusb(uint8_t *buf, int buf_len, void *data) @@ -102,7 +102,7 @@ static int parse_hmcfgusb(uint8_t *buf, int buf_len, void *data) rdata->speed = buf[1]; break; case 'H': - rdata->hmcfgusb_version = (buf[11] << 8) | buf[12]; + rdata->version = (buf[11] << 8) | buf[12]; my_hmid = (buf[0x1b] << 16) | (buf[0x1c] << 8) | buf[0x1d]; break; default: @@ -125,25 +125,57 @@ static int parse_culfw(uint8_t *buf, int buf_len, void *data) if (buf_len <= 3) return 0; - if (buf[0] != 'A') - return 0; + switch(buf[0]) { + case 'A': + if (buf[1] == 's') + return 0; + + while(validate_nibble(buf[(pos * 2) + 1]) && + validate_nibble(buf[(pos * 2) + 2]) && + (pos + 1 < buf_len)) { + rdata->message[pos] = ascii_to_nibble(buf[(pos * 2) + 1]) << 4; + rdata->message[pos] |= ascii_to_nibble(buf[(pos * 2) + 2]); + pos++; + } - if (buf[1] == 's') - return 0; + if (hmid && (SRC(rdata->message) != hmid)) + return 0; - while(validate_nibble(buf[(pos * 2) + 1]) && - validate_nibble(buf[(pos * 2) + 2]) && - (pos + 1 < buf_len)) { - rdata->message[pos] = ascii_to_nibble(buf[(pos * 2) + 1]) << 4; - rdata->message[pos] |= ascii_to_nibble(buf[(pos * 2) + 2]); - pos++; + rdata->message_type = MESSAGE_TYPE_E; + break; + case 'V': + { + uint8_t v; + char *s; + char *e; + + s = ((char*)buf) + 2; + e = strchr(s, '.'); + if (!e) { + fprintf(stderr, "Unknown response from CUL: %s", buf); + return 0; + } + *e = '\0'; + v = atoi(s); + rdata->version = v << 8; + + s = e + 1; + e = strchr(s, ' '); + if (!e) { + fprintf(stderr, "Unknown response from CUL: %s", buf); + return 0; + } + *e = '\0'; + v = atoi(s); + rdata->version |= v; + } + break; + default: + fprintf(stderr, "Unknown response from CUL: %s", buf); + return 0; + break; } - if (hmid && (SRC(rdata->message) != hmid)) - return 0; - - rdata->message_type = MESSAGE_TYPE_E; - return 1; } @@ -372,12 +404,43 @@ int main(int argc, char **argv) memset(&dev, 0, sizeof(struct ota_dev)); if (culfw_dev) { + printf("Opening culfw-device at path %s with speed %u\n", culfw_dev, bps); dev.culfw = culfw_init(culfw_dev, bps, parse_culfw, &rdata); if (!dev.culfw) { fprintf(stderr, "Can't initialize CUL at %s with rate %u\n", culfw_dev, bps); exit(EXIT_FAILURE); } dev.type = DEVICE_TYPE_CULFW; + + printf("Requesting firmware-version\n"); + culfw_send(dev.culfw, "\r\n", 2); + culfw_flush(dev.culfw); + + while (1) { + culfw_send(dev.culfw, "V\r\n", 3); + + errno = 0; + pfd = culfw_poll(dev.culfw, 1); + if ((pfd < 0) && errno) { + if (errno != ETIMEDOUT) { + perror("\n\nhmcfgusb_poll"); + exit(EXIT_FAILURE); + } + } + if (rdata.version) + break; + } + + printf("culfw-device firmware version: %u.%02u\n", + (rdata.version >> 8) & 0xff, + rdata.version & 0xff); + + if (rdata.version < 0x0139) { + fprintf(stderr, "\nThis version does _not_ support firmware upgrade mode!\n"); + exit(EXIT_FAILURE); + } else if (rdata.version < 0x0140) { + printf("\n*** This version probably not supports firmware upgrade mode! ***\n\n"); + } } else { hmcfgusb_set_debug(debug); @@ -430,16 +493,16 @@ int main(int argc, char **argv) exit(EXIT_FAILURE); } } - if (rdata.hmcfgusb_version) + if (rdata.version) break; } - if (rdata.hmcfgusb_version < 0x3c7) { - fprintf(stderr, "HM-CFG-USB firmware too low: %u < 967\n", rdata.hmcfgusb_version); + if (rdata.version < 0x3c7) { + fprintf(stderr, "HM-CFG-USB firmware too low: %u < 967\n", rdata.version); exit(EXIT_FAILURE); } - printf("HM-CFG-USB firmware version: %u\n", rdata.hmcfgusb_version); + printf("HM-CFG-USB firmware version: %u\n", rdata.version); } if (!switch_speed(&dev, &rdata, 10)) { -- 2.39.5