summaryrefslogtreecommitdiff
path: root/cmd.c
diff options
context:
space:
mode:
authorThomas Albers <thomas@thomaslabs.org>2023-08-06 10:01:18 +0200
committerThomas Albers <thomas@thomaslabs.org>2023-08-06 10:01:18 +0200
commitb50e1f74202e18ea10f1f2cd46e9e02a9d4f0e65 (patch)
tree3b408615595bf82c2ac4f6ec62009ab2f05a6bd5 /cmd.c
parent56157d2cc9385e5df65ba310abef2873429c8af5 (diff)
Rewrite for new serial protocol
Diffstat (limited to 'cmd.c')
-rw-r--r--cmd.c201
1 files changed, 201 insertions, 0 deletions
diff --git a/cmd.c b/cmd.c
new file mode 100644
index 0000000..c4a7d20
--- /dev/null
+++ b/cmd.c
@@ -0,0 +1,201 @@
+#include <zup.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+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;
+}