split parser into separate functions that handle specific commands
This commit is contained in:
2023-12-05 21:48:07 +01:00
parent bd89deceb6
commit 589f56ecbd
2 changed files with 208 additions and 155 deletions

View File

@@ -22,6 +22,7 @@
void tcp_cmd_remove_newline(char* str, size_t len);
char* tcp_cmd_remove_leading_space(char* str, size_t len);
void tcp_cmd_str_tolower(char* str);
char* tcp_cmd_get_next_token(char* input, const char* delimiters, char** next);
void tcp_cmd_init(void);
err_t tcp_cmd_recv(void* arg, struct tcp_pcb* pcb, struct pbuf* p, err_t err);

View File

@@ -17,6 +17,15 @@ static uint32_t color_bg = 0xff000000; // Store background color
static void tcp_cmd_write(struct tcp_pcb* pcb, const char* str);
static void tcp_cmd_print_header(struct tcp_pcb* pcb);
static void tcp_cmd_print_help(struct tcp_pcb* pcb);
static void tcp_cmd_clear(struct tcp_pcb* pcb, int argc, char** argv);
static void tcp_cmd_text(struct tcp_pcb* pcb, int argc, char** argv);
static void tcp_cmd_bg_color(struct tcp_pcb* pcb, int argc, char** argv);
static void tcp_cmd_color(struct tcp_pcb* pcb, int argc, char** argv);
static void tcp_cmd_list_files(struct tcp_pcb* pcb, int argc, char** argv);
static void tcp_cmd_set_image(struct tcp_pcb* pcb, int argc, char** argv);
static void tcp_cmd_set_gif(struct tcp_pcb* pcb, int argc, char** argv);
static void tcp_cmd_exit(struct tcp_pcb* pcb, int argc, char** argv);
static void tcp_cmd_unknown_cmd(struct tcp_pcb* pcb, int argc, char** argv);
static bool tcp_cmd_parser(struct tcp_pcb* pcb, int argc, char** argv);
static err_t tcp_cmd_accept(void* arg, struct tcp_pcb* pcb, err_t err);
static void tcp_cmd_close(struct tcp_pcb* pcb);
@@ -47,6 +56,7 @@ static void tcp_cmd_print_header(struct tcp_pcb* pcb) {
* @param pcb The tcp_pcb struct to write to
*/
static void tcp_cmd_print_help(struct tcp_pcb* pcb) {
LOG_INFO(TAG, "Printing help");
tcp_cmd_write(pcb, "help : shows a list of commands\n"
"clear text/images : clears the text or images on the lcd\n"
"text \"<text>\" : puts text on the lcd\n"
@@ -58,6 +68,193 @@ static void tcp_cmd_print_help(struct tcp_pcb* pcb) {
"exit : closes the connection\n");
}
static void tcp_cmd_clear(struct tcp_pcb* pcb, int argc, char** argv) {
if (argc == 1) {
LOG_INFO(TAG, "Clearing screen");
lcd_clear_text();
lcd_clear_images();
return;
}
if (argc == 2) {
if (strcmp(argv[1], "text") == 0) {
LOG_INFO(TAG, "Clearing text");
lcd_clear_text();
return;
}
if (strcmp(argv[1], "images") == 0) {
LOG_INFO(TAG, "Clearing images");
lcd_clear_images();
return;
}
LOG_WARN(TAG, "Bad usage of clear");
tcp_cmd_write(pcb, "Usage: clear\n");
tcp_cmd_write(pcb, "Usage: clear text\n");
tcp_cmd_write(pcb, "Usage: clear images\n");
return;
}
}
static void tcp_cmd_text(struct tcp_pcb* pcb, int argc, char** argv) {
if (argc == 2) {
LOG_INFO(TAG, "Setting text %s @ 10, 10", argv[1]);
lcd_display_text((const char*)argv[1], 10, 10, color_txt, color_bg, LCD_FONT24);
return;
}
if (argc == 4) {
LOG_INFO(TAG, "Setting text %s @ %lu, %lu", argv[1], (uint32_t)strtoul(argv[2], NULL, 10), (uint32_t)strtoul(argv[3], NULL, 10));
lcd_display_text((const char*)argv[1], (uint32_t)strtoul(argv[2], NULL, 10), (uint32_t)strtoul(argv[3], NULL, 10), color_txt, color_bg, LCD_FONT24);
return;
}
LOG_WARN(TAG, "Bad usage of text");
tcp_cmd_write(pcb, "Usage: text \"<text>\"\n");
tcp_cmd_write(pcb, "Usage: text <word>\n");
tcp_cmd_write(pcb, "Usage: text \"<text>\" <x> <y>\n");
}
static void tcp_cmd_bg_color(struct tcp_pcb* pcb, int argc, char** argv) {
if (argc == 2) {
LOG_INFO(TAG, "Setting background color to %s", argv[1]);
color_bg = (uint32_t)strtoul(argv[1], NULL, 16);
color_bg ^= 0xff000000;
return;
}
if (argc == 4) {
LOG_INFO(TAG, "Setting background color to %s %s %s", argv[1], argv[2], argv[3]);
color_bg = 0xff000000;
color_bg |= (uint32_t)strtoul(argv[1], NULL, 10) << 16;
color_bg |= (uint32_t)strtoul(argv[2], NULL, 10) << 8;
color_bg |= (uint32_t)strtoul(argv[3], NULL, 10);
return;
}
if (argc == 5) {
LOG_INFO(TAG, "Setting background color to %s %s %s %s", argv[1], argv[2], argv[3], argv[4]);
color_txt = 0xff000000;
color_txt ^= (uint32_t)strtoul(argv[1], NULL, 10) << 24;
color_txt |= (uint32_t)strtoul(argv[2], NULL, 10) << 16;
color_txt |= (uint32_t)strtoul(argv[3], NULL, 10) << 8;
color_txt |= (uint32_t)strtoul(argv[4], NULL, 10);
return;
}
LOG_WARN(TAG, "Bad usage of bgcolor");
tcp_cmd_write(pcb, "Usage: bgcolor 0x<rrggbb>\n");
tcp_cmd_write(pcb, "Usage: bgcolor 0x<aarrggbb>\n");
tcp_cmd_write(pcb, "Usage: bgcolor <r> <g> <b>\n");
tcp_cmd_write(pcb, "Usage: bgcolor <a> <r> <g> <b>\n");
}
static void tcp_cmd_color(struct tcp_pcb* pcb, int argc, char** argv) {
if (argc == 2) {
LOG_INFO(TAG, "Setting text color to %s", argv[1]);
color_txt = (uint32_t)strtoul(argv[1], NULL, 16);
color_txt ^= 0xff000000;
return;
}
if (argc == 4) {
LOG_INFO(TAG, "Setting text color to %s %s %s", argv[1], argv[2], argv[3]);
color_txt = 0xff000000;
color_txt |= (uint32_t)strtoul(argv[1], NULL, 10) << 16;
color_txt |= (uint32_t)strtoul(argv[2], NULL, 10) << 8;
color_txt |= (uint32_t)strtoul(argv[3], NULL, 10);
return;
}
if (argc == 5) {
LOG_INFO(TAG, "Setting text color to %s %s %s %s", argv[1], argv[2], argv[3], argv[4]);
color_txt = 0xff000000;
color_txt ^= (uint32_t)strtoul(argv[1], NULL, 10) << 24;
color_txt |= (uint32_t)strtoul(argv[2], NULL, 10) << 16;
color_txt |= (uint32_t)strtoul(argv[3], NULL, 10) << 8;
color_txt |= (uint32_t)strtoul(argv[4], NULL, 10);
return;
}
LOG_WARN(TAG, "Bad usage of color");
tcp_cmd_write(pcb, "Usage: color 0x<rrggbb>\n");
tcp_cmd_write(pcb, "Usage: color 0x<aarrggbb>\n");
tcp_cmd_write(pcb, "Usage: color <r> <g> <b>\n");
tcp_cmd_write(pcb, "Usage: color <a> <r> <g> <b>\n");
}
static void tcp_cmd_list_files(struct tcp_pcb* pcb, int argc, char** argv) {
UNUSED(argc);
UNUSED(argv);
LOG_INFO(TAG, "Listing files");
void* mem = NULL; // Pointer for internal use by the llfs library
llfs_file_t* file;
while ((file = llfs_next_file(&mem, NULL)) != NULL) {
tcp_cmd_write(pcb, file->name);
tcp_cmd_write(pcb, "\n");
}
}
static void tcp_cmd_set_image(struct tcp_pcb* pcb, int argc, char** argv) {
char* ext = NULL;
if (argc >= 2) {
ext = llfs_get_filename_ext(argv[1]);
if (strcmp(ext, "bmp") != 0) {
LOG_WARN(TAG, "setimage: File is not a bmp");
tcp_cmd_write(pcb, "File is not a bmp\n");
return;
}
}
if (argc == 2) {
LOG_INFO(TAG, "Setting image %s @ 0, 0", argv[1]);
lcd_draw_img_from_fs(argv[1], 0, 0);
return;
}
if (argc == 4) {
LOG_INFO(TAG, "Setting image %s @ %lu, %lu", argv[1], (uint32_t)strtoul(argv[2], NULL, 10), (uint32_t)strtoul(argv[3], NULL, 10));
lcd_draw_img_from_fs(argv[1], (uint32_t)strtoul(argv[2], NULL, 10), (uint32_t)strtoul(argv[3], NULL, 10));
return;
}
LOG_WARN(TAG, "Bad usage of setimage");
tcp_cmd_write(pcb, "Usage: setimage <filename>\n");
tcp_cmd_write(pcb, "Usage: setimage <filename> <x> <y>\n");
}
static void tcp_cmd_set_gif(struct tcp_pcb* pcb, int argc, char** argv) {
char* ext = NULL;
if (argc >= 2) {
ext = llfs_get_filename_ext(argv[1]);
if (strcmp(ext, "gif") != 0) {
LOG_WARN(TAG, "setgif: File is not a gif");
tcp_cmd_write(pcb, "File is not a gif\n");
return;
}
}
if (argc == 2) {
LOG_INFO(TAG, "Setting gif %s @ 0, 0", argv[1]);
lcd_draw_gif_from_fs(argv[1], 0, 0);
return;
}
if (argc == 4) {
LOG_INFO(TAG, "Setting gif %s @ %lu, %lu", argv[1], (uint32_t)strtoul(argv[2], NULL, 10), (uint32_t)strtoul(argv[3], NULL, 10));
lcd_draw_gif_from_fs(argv[1], (uint32_t)strtoul(argv[2], NULL, 10), (uint32_t)strtoul(argv[3], NULL, 10));
return;
}
LOG_WARN(TAG, "Bad usage of setgif");
tcp_cmd_write(pcb, "Usage: setgif <filename>\n");
tcp_cmd_write(pcb, "Usage: setgif <filename> <x> <y>\n");
}
static void tcp_cmd_exit(struct tcp_pcb* pcb, int argc, char** argv) {
UNUSED(argc);
UNUSED(argv);
LOG_INFO(TAG, "Closing connection");
tcp_cmd_write(pcb, "Exiting...\n");
lcd_clear_images();
lcd_clear_text();
tcp_close(pcb);
}
static void tcp_cmd_unknown_cmd(struct tcp_pcb* pcb, int argc, char** argv) {
UNUSED(argc);
LOG_WARN(TAG, "Unknown command: %s", argv[0]);
tcp_cmd_write(pcb, "Unknown command: ");
tcp_cmd_write(pcb, argv[0]);
tcp_cmd_write(pcb, "\n");
tcp_cmd_write(pcb, "Type help for list of commands\n");
}
/**
* @brief This function removes the newline from a string the string can contain multiple lines
* @param str The string to remove the newline from
@@ -155,193 +352,48 @@ char* tcp_cmd_get_next_token(char* input, const char* delimiters, char** next) {
* @return false Connection should be kept open
*/
static bool tcp_cmd_parser(struct tcp_pcb* pcb, int argc, char** argv) {
char* ext;
if (argc == 0) {
LOG_WARN(TAG, "No command given");
return false;
}
tcp_cmd_str_tolower(argv[0]);
if (strcmp(argv[0], "help") == 0) {
LOG_INFO(TAG, "Printing help");
tcp_cmd_print_help(pcb);
return false;
}
if (strcmp(argv[0], "clear") == 0) {
if (argc == 1) {
LOG_INFO(TAG, "Clearing screen");
lcd_clear_text();
lcd_clear_images();
return false;
}
if (argc == 2) {
if (strcmp(argv[1], "text") == 0) {
LOG_INFO(TAG, "Clearing text");
lcd_clear_text();
return false;
}
if (strcmp(argv[1], "images") == 0) {
LOG_INFO(TAG, "Clearing images");
lcd_clear_images();
return false;
}
LOG_WARN(TAG, "Bad usage of clear");
tcp_cmd_write(pcb, "Usage: clear\n");
tcp_cmd_write(pcb, "Usage: clear text\n");
tcp_cmd_write(pcb, "Usage: clear images\n");
return false;
}
tcp_cmd_clear(pcb, argc, argv);
return false;
}
if (strcmp(argv[0], "text") == 0) {
if (argc == 2) {
LOG_INFO(TAG, "Setting text %s @ 10, 10", argv[1]);
lcd_display_text((const char*)argv[1], 10, 10, color_txt, color_bg, LCD_FONT24);
return false;
}
if (argc == 4) {
LOG_INFO(TAG, "Setting text %s @ %lu, %lu", argv[1], (uint32_t)strtoul(argv[2], NULL, 10), (uint32_t)strtoul(argv[3], NULL, 10));
lcd_display_text((const char*)argv[1], (uint32_t)strtoul(argv[2], NULL, 10), (uint32_t)strtoul(argv[3], NULL, 10), color_txt, color_bg, LCD_FONT24);
return false;
}
LOG_WARN(TAG, "Bad usage of text");
tcp_cmd_write(pcb, "Usage: text \"<text>\"\n");
tcp_cmd_write(pcb, "Usage: text <word>\n");
tcp_cmd_write(pcb, "Usage: text \"<text>\" <x> <y>\n");
tcp_cmd_text(pcb, argc, argv);
return false;
}
if (strcmp(argv[0], "bgcolor") == 0) {
if (argc == 2) {
LOG_INFO(TAG, "Setting background color to %s", argv[1]);
color_bg = (uint32_t)strtoul(argv[1], NULL, 16);
color_bg ^= 0xff000000;
return false;
}
if (argc == 4) {
LOG_INFO(TAG, "Setting background color to %s %s %s", argv[1], argv[2], argv[3]);
color_bg = 0xff000000;
color_bg |= (uint32_t)strtoul(argv[1], NULL, 10) << 16;
color_bg |= (uint32_t)strtoul(argv[2], NULL, 10) << 8;
color_bg |= (uint32_t)strtoul(argv[3], NULL, 10);
return false;
}
if (argc == 5) {
LOG_INFO(TAG, "Setting background color to %s %s %s %s", argv[1], argv[2], argv[3], argv[4]);
color_txt = 0xff000000;
color_txt ^= (uint32_t)strtoul(argv[1], NULL, 10) << 24;
color_txt |= (uint32_t)strtoul(argv[2], NULL, 10) << 16;
color_txt |= (uint32_t)strtoul(argv[3], NULL, 10) << 8;
color_txt |= (uint32_t)strtoul(argv[4], NULL, 10);
return false;
}
LOG_WARN(TAG, "Bad usage of bgcolor");
tcp_cmd_write(pcb, "Usage: bgcolor 0x<rrggbb>\n");
tcp_cmd_write(pcb, "Usage: bgcolor 0x<aarrggbb>\n");
tcp_cmd_write(pcb, "Usage: bgcolor <r> <g> <b>\n");
tcp_cmd_write(pcb, "Usage: bgcolor <a> <r> <g> <b>\n");
tcp_cmd_bg_color(pcb, argc, argv);
return false;
}
if (strcmp(argv[0], "color") == 0) {
if (argc == 2) {
LOG_INFO(TAG, "Setting text color to %s", argv[1]);
color_txt = (uint32_t)strtoul(argv[1], NULL, 16);
color_txt ^= 0xff000000;
return false;
}
if (argc == 4) {
LOG_INFO(TAG, "Setting text color to %s %s %s", argv[1], argv[2], argv[3]);
color_txt = 0xff000000;
color_txt |= (uint32_t)strtoul(argv[1], NULL, 10) << 16;
color_txt |= (uint32_t)strtoul(argv[2], NULL, 10) << 8;
color_txt |= (uint32_t)strtoul(argv[3], NULL, 10);
return false;
}
if (argc == 5) {
LOG_INFO(TAG, "Setting text color to %s %s %s %s", argv[1], argv[2], argv[3], argv[4]);
color_txt = 0xff000000;
color_txt ^= (uint32_t)strtoul(argv[1], NULL, 10) << 24;
color_txt |= (uint32_t)strtoul(argv[2], NULL, 10) << 16;
color_txt |= (uint32_t)strtoul(argv[3], NULL, 10) << 8;
color_txt |= (uint32_t)strtoul(argv[4], NULL, 10);
return false;
}
LOG_WARN(TAG, "Bad usage of color");
tcp_cmd_write(pcb, "Usage: color 0x<rrggbb>\n");
tcp_cmd_write(pcb, "Usage: color 0x<aarrggbb>\n");
tcp_cmd_write(pcb, "Usage: color <r> <g> <b>\n");
tcp_cmd_write(pcb, "Usage: color <a> <r> <g> <b>\n");
tcp_cmd_color(pcb, argc, argv);
return false;
}
if (strcmp(argv[0], "listfiles") == 0) {
LOG_INFO(TAG, "Listing files");
void* mem = NULL; // Pointer for internal use by the llfs library
llfs_file_t* file;
while ((file = llfs_next_file(&mem, NULL)) != NULL) {
tcp_cmd_write(pcb, file->name);
tcp_cmd_write(pcb, "\n");
}
tcp_cmd_list_files(pcb, argc, argv);
return false;
}
if (strcmp(argv[0], "setimage") == 0) {
if (argc >= 2) {
ext = llfs_get_filename_ext(argv[1]);
if (strcmp(ext, "bmp") != 0) {
LOG_WARN(TAG, "setimage: File is not a bmp");
tcp_cmd_write(pcb, "File is not a bmp\n");
return false;
}
}
if (argc == 2) {
LOG_INFO(TAG, "Setting image %s @ 0, 0", argv[1]);
lcd_draw_img_from_fs(argv[1], 0, 0);
return false;
}
if (argc == 4) {
LOG_INFO(TAG, "Setting image %s @ %lu, %lu", argv[1], (uint32_t)strtoul(argv[2], NULL, 10), (uint32_t)strtoul(argv[3], NULL, 10));
lcd_draw_img_from_fs(argv[1], (uint32_t)strtoul(argv[2], NULL, 10), (uint32_t)strtoul(argv[3], NULL, 10));
return false;
}
LOG_WARN(TAG, "Bad usage of setimage");
tcp_cmd_write(pcb, "Usage: setimage <filename>\n");
tcp_cmd_write(pcb, "Usage: setimage <filename> <x> <y>\n");
tcp_cmd_set_image(pcb, argc, argv);
return false;
}
if (strcmp(argv[0], "setgif") == 0) {
if (argc >= 2) {
ext = llfs_get_filename_ext(argv[1]);
if (strcmp(ext, "gif") != 0) {
LOG_WARN(TAG, "setgif: File is not a gif");
tcp_cmd_write(pcb, "File is not a gif\n");
return false;
}
}
if (argc == 2) {
LOG_INFO(TAG, "Setting gif %s @ 0, 0", argv[1]);
lcd_draw_gif_from_fs(argv[1], 0, 0);
return false;
}
if (argc == 4) {
LOG_INFO(TAG, "Setting gif %s @ %lu, %lu", argv[1], (uint32_t)strtoul(argv[2], NULL, 10), (uint32_t)strtoul(argv[3], NULL, 10));
lcd_draw_gif_from_fs(argv[1], (uint32_t)strtoul(argv[2], NULL, 10), (uint32_t)strtoul(argv[3], NULL, 10));
return false;
}
LOG_WARN(TAG, "Bad usage of setgif");
tcp_cmd_write(pcb, "Usage: setgif <filename>\n");
tcp_cmd_write(pcb, "Usage: setgif <filename> <x> <y>\n");
tcp_cmd_set_gif(pcb, argc, argv);
return false;
}
if (strcmp(argv[0], "exit") == 0) {
LOG_INFO(TAG, "Closing connection");
tcp_cmd_write(pcb, "Exiting...\n");
lcd_clear_images();
lcd_clear_text();
tcp_close(pcb);
tcp_cmd_exit(pcb, argc, argv);
return true;
}
LOG_WARN(TAG, "Unknown command: %s", argv[0]);
tcp_cmd_write(pcb, "Unknown command: ");
tcp_cmd_write(pcb, argv[0]);
tcp_cmd_write(pcb, "\n");
tcp_cmd_write(pcb, "Type help for list of commands\n");
tcp_cmd_unknown_cmd(pcb, argc, argv);
return false;
}