diff --git a/project/Core/Src/tcp_cmd.c b/project/Core/Src/tcp_cmd.c index 0b3a0b2..3ed2e84 100644 --- a/project/Core/Src/tcp_cmd.c +++ b/project/Core/Src/tcp_cmd.c @@ -25,11 +25,27 @@ 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 void tcp_cmd_unknown_cmd(struct tcp_pcb* pcb, char* cmd); 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); +/** + * @brief This function shifts the arguments in argv and argc + * @param argc The argc pointer + * @param argv The argv pointer + * @return The shifted argument + */ +static char* shift_args(int* argc, char*** argv) { + if (*argc == 0) { + return NULL; + } + char* arg = (*argv)[0]; + (*argv)++; + (*argc)--; + return arg; +} + /** * @brief This function is a wrapper for tcp_write and tcp_output * @param pcb The tcp_pcb struct to write to @@ -69,19 +85,19 @@ static void tcp_cmd_print_help(struct tcp_pcb* pcb) { } static void tcp_cmd_clear(struct tcp_pcb* pcb, int argc, char** argv) { - if (argc == 1) { + if (argc == 0) { LOG_INFO(TAG, "Clearing screen"); lcd_clear_text(); lcd_clear_images(); return; } - if (argc == 2) { - if (strcmp(argv[1], "text") == 0) { + if (argc == 1) { + if (strcmp(argv[0], "text") == 0) { LOG_INFO(TAG, "Clearing text"); lcd_clear_text(); return; } - if (strcmp(argv[1], "images") == 0) { + if (strcmp(argv[0], "images") == 0) { LOG_INFO(TAG, "Clearing images"); lcd_clear_images(); return; @@ -95,14 +111,16 @@ 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) { - 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); + if (argc == 1) { + LOG_INFO(TAG, "Setting text %s @ 10, 10", argv[0]); + lcd_display_text((const char*)argv[0], 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); + if (argc == 3) { + LOG_INFO(TAG, "Setting text %s @ %lu, %lu", argv[0], (uint32_t)strtoul(argv[1], NULL, 10), + (uint32_t)strtoul(argv[2], NULL, 10)); + lcd_display_text((const char*)argv[0], (uint32_t)strtoul(argv[1], NULL, 10), + (uint32_t)strtoul(argv[2], NULL, 10), color_txt, color_bg, LCD_FONT24); return; } LOG_WARN(TAG, "Bad usage of text"); @@ -112,27 +130,27 @@ 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) { - if (argc == 2) { - LOG_INFO(TAG, "Setting background color to %s", argv[1]); - color_bg = (uint32_t)strtoul(argv[1], NULL, 16); + if (argc == 1) { + LOG_INFO(TAG, "Setting background color to %s", argv[0]); + color_bg = (uint32_t)strtoul(argv[0], 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]); + if (argc == 3) { + LOG_INFO(TAG, "Setting background color to %s %s %s", argv[0], argv[1], argv[2]); 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); + color_bg |= (uint32_t)strtoul(argv[0], NULL, 10) << 16; + color_bg |= (uint32_t)strtoul(argv[1], NULL, 10) << 8; + color_bg |= (uint32_t)strtoul(argv[2], 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]); + if (argc == 4) { + LOG_INFO(TAG, "Setting background color to %s %s %s %s", argv[0], argv[1], argv[2], argv[3]); 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); + color_txt ^= (uint32_t)strtoul(argv[0], NULL, 10) << 24; + 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; } LOG_WARN(TAG, "Bad usage of bgcolor"); @@ -143,29 +161,29 @@ 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) { - if (argc == 2) { - LOG_INFO(TAG, "Setting text color to %s", argv[1]); - color_txt = (uint32_t)strtoul(argv[1], NULL, 16); + if (argc == 1) { + LOG_INFO(TAG, "Setting text color to %s", argv[0]); + color_txt = (uint32_t)strtoul(argv[0], 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]); + if (argc == 3) { + LOG_INFO(TAG, "Setting text color to %s %s %s", argv[0], argv[1], argv[2]); color_txt = 0xff000000; + color_txt |= (uint32_t)strtoul(argv[0], NULL, 10) << 16; + color_txt |= (uint32_t)strtoul(argv[1], NULL, 10) << 8; + color_txt |= (uint32_t)strtoul(argv[2], NULL, 10); + return; + } + if (argc == 4) { + LOG_INFO(TAG, "Setting text color to %s %s %s %s", argv[0], argv[1], argv[2], argv[3]); + color_txt = 0xff000000; + color_txt ^= (uint32_t)strtoul(argv[0], NULL, 10) << 24; 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\n"); tcp_cmd_write(pcb, "Usage: color 0x\n"); @@ -174,35 +192,41 @@ 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) { - 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"); + if (argc == 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"); + } + return; } + LOG_WARN(TAG, "Bad usage of listfiles"); + tcp_cmd_write(pcb, "Usage: listfiles\n"); + return; } 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 (argc >= 1) { + ext = llfs_get_filename_ext(argv[0]); 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); + if (argc == 1) { + LOG_INFO(TAG, "Setting image %s @ 0, 0", argv[0]); + lcd_draw_img_from_fs(argv[0], 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)); + if (argc == 3) { + LOG_INFO(TAG, "Setting image %s @ %lu, %lu", argv[0], (uint32_t)strtoul(argv[1], NULL, 10), + (uint32_t)strtoul(argv[2], NULL, 10)); + lcd_draw_img_from_fs(argv[0], (uint32_t)strtoul(argv[1], NULL, 10), (uint32_t)strtoul(argv[2], NULL, 10)); return; } LOG_WARN(TAG, "Bad usage of setimage"); @@ -212,22 +236,23 @@ 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) { char* ext = NULL; - if (argc >= 2) { - ext = llfs_get_filename_ext(argv[1]); + if (argc >= 1) { + ext = llfs_get_filename_ext(argv[0]); 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); + if (argc == 1) { + LOG_INFO(TAG, "Setting gif %s @ 0, 0", argv[0]); + lcd_draw_gif_from_fs(argv[0], 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)); + if (argc == 3) { + LOG_INFO(TAG, "Setting gif %s @ %lu, %lu", argv[0], (uint32_t)strtoul(argv[1], NULL, 10), + (uint32_t)strtoul(argv[2], NULL, 10)); + lcd_draw_gif_from_fs(argv[0], (uint32_t)strtoul(argv[1], NULL, 10), (uint32_t)strtoul(argv[2], NULL, 10)); return; } @@ -237,20 +262,24 @@ 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) { - UNUSED(argc); UNUSED(argv); - LOG_INFO(TAG, "Closing connection"); - tcp_cmd_write(pcb, "Exiting...\n"); - lcd_clear_images(); - lcd_clear_text(); - tcp_close(pcb); + if (argc == 0) { + LOG_INFO(TAG, "Closing connection"); + tcp_cmd_write(pcb, "Exiting...\n"); + lcd_clear_images(); + lcd_clear_text(); + tcp_close(pcb); + return; + } + + LOG_WARN(TAG, "Bad usage of exit"); + tcp_cmd_write(pcb, "Usage: exit\n"); } -static void tcp_cmd_unknown_cmd(struct tcp_pcb* pcb, int argc, char** argv) { - UNUSED(argc); - LOG_WARN(TAG, "Unknown command: %s", argv[0]); +static void tcp_cmd_unknown_cmd(struct tcp_pcb* pcb, char* cmd) { + LOG_WARN(TAG, "Unknown command: %s", cmd); tcp_cmd_write(pcb, "Unknown command: "); - tcp_cmd_write(pcb, argv[0]); + tcp_cmd_write(pcb, cmd); tcp_cmd_write(pcb, "\n"); tcp_cmd_write(pcb, "Type help for list of commands\n"); } @@ -356,44 +385,45 @@ static bool tcp_cmd_parser(struct tcp_pcb* pcb, int argc, char** argv) { LOG_WARN(TAG, "No command given"); return false; } - tcp_cmd_str_tolower(argv[0]); - if (strcmp(argv[0], "help") == 0) { + char* cmd = shift_args(&argc, &argv); + tcp_cmd_str_tolower(cmd); + if (strcmp(cmd, "help") == 0) { tcp_cmd_print_help(pcb); return false; } - if (strcmp(argv[0], "clear") == 0) { + if (strcmp(cmd, "clear") == 0) { tcp_cmd_clear(pcb, argc, argv); return false; } - if (strcmp(argv[0], "text") == 0) { + if (strcmp(cmd, "text") == 0) { tcp_cmd_text(pcb, argc, argv); return false; } - if (strcmp(argv[0], "bgcolor") == 0) { + if (strcmp(cmd, "bgcolor") == 0) { tcp_cmd_bg_color(pcb, argc, argv); return false; } - if (strcmp(argv[0], "color") == 0) { + if (strcmp(cmd, "color") == 0) { tcp_cmd_color(pcb, argc, argv); return false; } - if (strcmp(argv[0], "listfiles") == 0) { + if (strcmp(cmd, "listfiles") == 0) { tcp_cmd_list_files(pcb, argc, argv); return false; } - if (strcmp(argv[0], "setimage") == 0) { + if (strcmp(cmd, "setimage") == 0) { tcp_cmd_set_image(pcb, argc, argv); return false; } - if (strcmp(argv[0], "setgif") == 0) { + if (strcmp(cmd, "setgif") == 0) { tcp_cmd_set_gif(pcb, argc, argv); return false; } - if (strcmp(argv[0], "exit") == 0) { + if (strcmp(cmd, "exit") == 0) { tcp_cmd_exit(pcb, argc, argv); return true; } - tcp_cmd_unknown_cmd(pcb, argc, argv); + tcp_cmd_unknown_cmd(pcb, cmd); return false; } @@ -445,7 +475,7 @@ err_t tcp_cmd_recv(void* arg, struct tcp_pcb* pcb, struct pbuf* p, err_t err) { // Split string into tokens by delimiter (space) cmd_ptr = tcp_cmd_remove_leading_space(cmd, strlen(cmd)); argv[0] = tcp_cmd_get_next_token(cmd_ptr, " ", &next); - if(argv[0] != NULL) { + if (argv[0] != NULL) { argc = 1; } while (argv[argc - 1] != NULL && argc < MAX_TOKENS) { @@ -472,7 +502,7 @@ err_t tcp_cmd_recv(void* arg, struct tcp_pcb* pcb, struct pbuf* p, err_t err) { tcp_cmd_write(pcb, "$>"); } #else - } else if(argc > 0) { + } else if (argc > 0) { tcp_cmd_write(pcb, "$>"); } else { tcp_cmd_write(pcb, "");