void hexdump(unsigned char *p, int len) { char str[48]; int n, y = 0, m, c; str[y++] = '\r'; str[y++] = '\n'; str[y++] = '\0'; usb_queue_string(str); y = 0; for (n = 0; n < len; n++) { if (!y) { hex4(n, str); y = 4; str[y++] = ':'; str[y++] = ' ' ; } str[y++] = hex[(p[n] >> 4) & 0xf]; str[y++] = hex[p[n] & 0xf]; if ((n & 7) == 7 || n == len - 1) { m = n; while ((m & 7) != 7) { str[y++] = ' '; str[y++] = ' '; str[y++] = ' '; m++; } str[y++] = ' '; str[y++] = ' '; c = 8; m = n & ~7; if (m + 8 > len) c = len - m; while (c--) { if (p[m] < 32 || p[m] > 126) str[y++] = '.'; else str[y++] = p[m]; m++; } str[y++] = '\r'; str[y++] = '\n'; str[y++] = '\0'; usb_queue_string(str); y = 0; } else str[y++] = ' ' ; } }
int process_ihexfile(const char *ihexfile, struct record **rec_p) { int fd; int rc; int i; int len; uint8_t *ptr; uint8_t c; uint8_t ih_count; uint16_t ih_address; uint8_t ih_type; uint8_t ih_data[256]; uint8_t ih_checksum; uint32_t ip = 0; struct record *rec; fd = open(ihexfile, O_RDONLY); if (fd < 0) { fprintf(stderr, "process_ihexfile: open failed (%s) :%s\n", ihexfile, strerror(errno)); return -1; } while (1) { ptr = io_buffer; len = read_fully(fd, ptr, 1); if (len < 0) goto read_error; else if (len == 0) break; c = *(ptr++); if (c == '\n') continue; else if (c == '\r') continue; if (c != ':') goto data_error; ptr = io_buffer; len = read_fully(fd, ptr, 8); if (len < 0) goto read_error; else if (len == 0) goto data_error; if (hex2(&ptr, &ih_count) < 0) goto data_error; if (hex4(&ptr, &ih_address) < 0) goto data_error; if (hex2(&ptr, &ih_type) < 0) goto data_error; if (ih_count > 0) { ptr = io_buffer; len = read_fully(fd, ptr, (ih_count * 2)); if (len < 0) goto read_error; else if (len == 0) goto data_error; for (i = 0; i < ih_count; i++) { if (hex2(&ptr, &ih_data[i]) < 0) goto data_error; } } ptr = io_buffer; len = read_fully(fd, ptr, 2); if (len < 0) goto read_error; else if (len == 0) goto data_error; if (hex2(&ptr, &ih_checksum) < 0) goto data_error; if (ih_type == 0x00) { rec = malloc(sizeof(struct record) + (sizeof(uint8_t) * ih_count)); if (rec == NULL) goto memory_error; rec->next = NULL; rec->count = ih_count; rec->address = ip + ih_address; memcpy(rec->data, ih_data, ih_count); *(rec_p) = rec; rec_p = &rec->next; } else if (ih_type == 0x02) { ip = (((ih_data[0] << 8) | (ih_data[1] << 0)) << 4); } else if (ih_type == 0x04) { ip = (((ih_data[0] << 8) | (ih_data[1] << 0)) << 16); } } rc = 0; goto close; memory_error: fprintf(stderr, "process_ihexfile: memory error\n"); rc = -1; goto close; read_error: fprintf(stderr, "process_ihexfile: read error\n"); rc = -1; goto close; data_error: fprintf(stderr, "process_ihexfile: data error\n"); rc = -1; goto close; close: if (close(fd) < 0) { fprintf(stderr, "process_ihexfile: close failed %s\n", strerror(errno)); return -1; } return rc; }
uint8_t hex8(char s[]) { // Converts a string representation of a hexadecimal byte into a uint8. // TODO: handle the case of hex4 failing. return hex4(s[1]) + 16*hex4(s[0]); }