#include #include #include #include #include typedef int (*cmd_command)(int, const struct param*, int, char**); static int cmd_boot(int fd, const struct param *param, int argc, char **args) { int err = 0; uint8_t bank; uint16_t address; if (argc != 2) { fputs("BOOT expects 2 arguments\n", stderr); return 1; } errno = 0; bank = strtoul(args[0], NULL, 16); if (errno) goto error; address = strtoul(args[1], NULL, 16); if (errno) goto error; return z_boot(fd, bank, address); error: perror("BOOT: Invalid arguments\n"); return -1; } static int cmd_read(int fd, const struct param *param, int argc, char **args) { int err = 0; uint8_t bank; uint16_t address; uint16_t length; const char *pathname; if (!((argc == 4 && !param->human_readable) || (argc == 3 && param->human_readable))) { fputs("READ expects 4 arguments\n", stderr); return 1; } errno = 0; bank = strtoul(args[0], NULL, 16); err |= errno; errno = 0; address = strtoul(args[1], NULL, 16); err |= errno; errno = 0; length = strtoul(args[2], NULL, 16); err |= errno; pathname = args[3]; if (err) { fputs("READ: Invalid arguments\n", stderr); return -1; } uint8_t buf[MAX_PACKET_SIZE]; if ((err = z_read(fd, bank, address, length, buf))) return err; if (param->human_readable) { hexdump(address, length, buf); } else { FILE *file; if (!(file = fopen(pathname, "w"))) { perror("File could not be opened"); return -1; } fwrite(buf, sizeof(uint8_t), length, file); fclose(file); } return 0; } // TODO: Handle length 0 at protcol level static int cmd_write(int fd, const struct param *param, int argc, char **args) { int err = 0; uint8_t bank; uint16_t address; uint16_t length; const char *pathname; if (argc != 3) { fputs("WRITE expects 3 arguments\n", stderr); return -1; } errno = 0; bank = strtoul(args[0], NULL, 16); err |= errno; errno = 0; address = strtoul(args[1], NULL, 16); err |= errno; pathname = args[2]; if (err) { fputs("WRITE: Invalid arguments\n", stderr); return -1; } uint8_t buf[MAX_PACKET_SIZE]; FILE *fp; if (!(fp = fopen(pathname, "r"))) { perror("File could not be opened"); return -1; } // Split file into packets while ((length = fread(buf, sizeof(uint8_t), 8, fp))) { if ((err = z_write(fd, bank, address, length, buf))) break; address += length; } fclose(fp); return err; } static int cmd_io_read(int fd, const struct param *param, int argc, char **args) { return 0; } static int cmd_io_write(int fd, const struct param *param, int argc, char **args) { return 0; } int run_commands(int fd, const struct param *param, int ncmd, char **cmds) { struct command { const char *name; cmd_command fptr; }; const struct command cmd_table[] = { {"b", cmd_boot}, {"r", cmd_read}, {"w", cmd_write}, {"i", cmd_io_read}, {"o", cmd_io_write} }; for (int i = 0; i < ncmd; ++i) { int err; int argc = 1; char *args[MAX_ARGS] = { NULL }; // Parse command args[0] = strtok(cmds[i], ":"); while(argc < MAX_ARGS && (args[argc] = strtok(NULL, ":"))) ++argc; // Match action int cmdi; for (cmdi = 0; cmdi < LEN(cmd_table); ++cmdi) { if (!strcmp(args[0], cmd_table[cmdi].name)) break; } // Call action if (cmdi == LEN(cmd_table)) { fprintf(stderr, "Unknown command %s\n", args[0]); return 1; } if ((err = cmd_table[cmdi].fptr(fd, param, argc - 1, &args[1]))) { print_error(err); return err; } } return 0; }