10 Commits

Author SHA1 Message Date
fffbf6e8db tcp_cmd
fix the tests
2023-12-27 13:00:21 +01:00
d627da2999 tcp_cnd
fix warning of casting const to non const
2023-12-27 13:00:21 +01:00
1ec27e9ee3 tcp_cmd
0 is alpha ff is opaque
2023-12-27 13:00:21 +01:00
6bc074a033 tcp_cmd
add capability of using ls as well as listfiles
2023-12-27 13:00:21 +01:00
87b6fecfd0 tcp_cmd
Doxygen: Add in, out
Move some stuff around to have a nicer ordering
2023-12-27 13:00:21 +01:00
3a745af9bf tcp_cmd
change the name of the define/ifdef to make it more obvious what it does
2023-12-27 13:00:21 +01:00
2a4de4fe34 tcp_cmd
split common code for colour conversion into a separate function
2023-12-27 13:00:21 +01:00
86f0a3bedc tcp_cmd
fix bug of tcp_cmd_bg_color writing to color_txt when in argb mode
2023-12-27 13:00:21 +01:00
a37213b128 tcp_cmd
add shift_args and use it in the parser function
2023-12-27 13:00:21 +01:00
992b9f3063 tcp_cmd
fix tests
2023-12-27 13:00:21 +01:00
2 changed files with 359 additions and 263 deletions

View File

@@ -8,7 +8,7 @@
#define MAX_TOKENS 10
#define MAX_CMD_LEN 50
#define LINUX
#define NCAT
static const char* TAG = "tcp_cmd";
static uint32_t color_txt = 0xffffffff; // Store text color
@@ -25,239 +25,61 @@ 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 is a wrapper for tcp_write and tcp_output
* @param pcb The tcp_pcb struct to write to
* @param str The string to write
* @brief This function shifts the arguments in argv and argc
* @param[in,out] argc The argc pointer
* @param[in,out] argv The argv pointer
* @return The shifted argument
*/
static void tcp_cmd_write(struct tcp_pcb* pcb, const char* str) {
tcp_write(pcb, str, strlen(str), TCP_WRITE_FLAG_COPY | TCP_WRITE_FLAG_MORE);
tcp_output(pcb);
static char* shift_args(int* argc, char*** argv) {
if (*argc == 0) {
return NULL;
}
char* arg = (*argv)[0];
(*argv)++;
(*argc)--;
return arg;
}
/**
* @brief This function prints the header of the tcp command interface
* @param pcb The tcp_pcb struct to write to
* @brief This function converts a string to a color
* @param[in] argc The number of arguments
* @param[in] argv The arguments
* @param[out] color The color to write to
* @return true The conversion failed
* @return false The conversion succeeded
*/
static void tcp_cmd_print_header(struct tcp_pcb* pcb) {
tcp_cmd_write(pcb, " Welcome to the TCP CMD interface\n"
"(Type help for a list of the commands! exit to close)\n"
"============================================================\n"
"$>");
}
/**
* @brief This function prints the help text
* @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"
"bgColor (<a>) <r> <g> <b> : set the background color of the lcd\n"
"color (<a>) <r> <g> <b> : set the color of the text\n"
"listFiles : shows a list with images in the filesystem\n"
"setImage <image_name> : put an image on the screen\n"
"setGif <image_name> : put a gif on the screen\n"
"exit : closes the connection\n");
}
static void tcp_cmd_clear(struct tcp_pcb* pcb, int argc, char** argv) {
static bool str_to_color(int argc, char** argv, uint32_t* color) {
if (argc == 1) {
LOG_INFO(TAG, "Clearing screen");
lcd_clear_text();
lcd_clear_images();
return;
*color = (uint32_t)strtoul(argv[0], NULL, 16);
return false;
}
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 == 3) {
*color = 0xff000000;
*color |= (uint32_t)strtoul(argv[0], NULL, 10) << 16;
*color |= (uint32_t)strtoul(argv[1], NULL, 10) << 8;
*color |= (uint32_t)strtoul(argv[2], NULL, 10);
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;
}
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;
*color = (uint32_t)strtoul(argv[0], NULL, 10) << 24;
*color |= (uint32_t)strtoul(argv[1], NULL, 10) << 16;
*color |= (uint32_t)strtoul(argv[2], NULL, 10) << 8;
*color |= (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");
}
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");
return true;
}
/**
* @brief This function removes the newline from a string the string can contain multiple lines
* @param str The string to remove the newline from
* @param[in,out] str The string to remove the newline from
*/
void tcp_cmd_remove_newline(char* str, size_t len) {
size_t i = 0;
@@ -272,6 +94,12 @@ void tcp_cmd_remove_newline(char* str, size_t len) {
str[i] = '\0';
}
/**
* @brief This function 'removes' the leading spaces from a string
* @param[in] str The string to remove the leading spaces from
* @param[in] len The length of the string
* @return char* A pointer to the first non-space character
*/
char* tcp_cmd_remove_leading_space(char* str, size_t len) {
size_t i = 0;
if (str == NULL || str[0] == '\0' || len == 0) {
@@ -288,7 +116,7 @@ char* tcp_cmd_remove_leading_space(char* str, size_t len) {
/**
* @brief This function converts a string to lowercase
* @param str The string to convert
* @param[in,out] str The string to convert
*/
void tcp_cmd_str_tolower(char* str) {
int i = 0;
@@ -301,9 +129,9 @@ void tcp_cmd_str_tolower(char* str) {
/**
* @brief This function finds the next token in the input string
* If the token is between quotes, return the whole string between quotes
* @param input The input string
* @param delimiter The delimiters to use
* @param next The next token
* @param[in] input The input string
* @param[in] delimiter The delimiters to use
* @param[in,out] next The next token
* @return char* The next token
*/
char* tcp_cmd_get_next_token(char* input, const char* delimiters, char** next) {
@@ -342,12 +170,275 @@ char* tcp_cmd_get_next_token(char* input, const char* delimiters, char** next) {
return input;
}
/**
* @brief This function is a wrapper for tcp_write and tcp_output
* @param[in] pcb The tcp_pcb struct to write to
* @param[in] str The string to write
*/
static void tcp_cmd_write(struct tcp_pcb* pcb, const char* str) {
tcp_write(pcb, str, strlen(str), TCP_WRITE_FLAG_COPY | TCP_WRITE_FLAG_MORE);
tcp_output(pcb);
}
/**
* @brief This function prints the header of the tcp command interface
* @param[in] pcb The tcp_pcb struct to write to
*/
static void tcp_cmd_print_header(struct tcp_pcb* pcb) {
tcp_cmd_write(pcb, " Welcome to the TCP CMD interface\n"
"(Type help for a list of the commands! exit to close)\n"
"============================================================\n"
"$>");
}
/**
* @brief This function prints the help text
* @param[in] 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"
"bgColor (<a>) <r> <g> <b> : set the background color of the lcd\n"
"color (<a>) <r> <g> <b> : set the color of the text\n"
"listFiles : shows a list with images in the filesystem\n"
"setImage <image_name> : put an image on the screen\n"
"setGif <image_name> : put a gif on the screen\n"
"exit : closes the connection\n");
}
/**
* @brief This function handles the clear command
*
* @param[in] pcb The tcp_pcb struct to write to
* @param[in] argc The number of arguments
* @param[in] argv The arguments
*/
static void tcp_cmd_clear(struct tcp_pcb* pcb, int argc, char** argv) {
if (argc == 0) {
LOG_INFO(TAG, "Clearing screen");
lcd_clear_text();
lcd_clear_images();
return;
}
if (argc == 1) {
if (strcmp(argv[0], "text") == 0) {
LOG_INFO(TAG, "Clearing text");
lcd_clear_text();
return;
}
if (strcmp(argv[0], "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;
}
}
/**
* @brief This function handles the text command
*
* @param[in] pcb The tcp_pcb struct to write to
* @param[in] argc The number of arguments
* @param[in] argv The arguments
*/
static void tcp_cmd_text(struct tcp_pcb* pcb, int argc, char** argv) {
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 == 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");
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");
}
/**
* @brief This function handles the bgcolor command
*
* @param[in] pcb The tcp_pcb struct to write to
* @param[in] argc The number of arguments
* @param[in] argv The arguments
*/
static void tcp_cmd_bg_color(struct tcp_pcb* pcb, int argc, char** argv) {
if (!str_to_color(argc, argv, &color_bg)) {
LOG_INFO(TAG, "Setting background color to %08lX", color_bg);
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");
}
/**
* @brief This function handles the color command
*
* @param[in] pcb The tcp_pcb struct to write to
* @param[in] argc The number of arguments
* @param[in] argv The arguments
*/
static void tcp_cmd_color(struct tcp_pcb* pcb, int argc, char** argv) {
if (!str_to_color(argc, argv, &color_txt)) {
LOG_INFO(TAG, "Setting color to %08lX", color_txt);
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");
}
/**
* @brief This function handles the listfiles command
*
* @param[in] pcb The tcp_pcb struct to write to
* @param[in] argc The number of arguments
* @param[in] argv The arguments
*/
static void tcp_cmd_list_files(struct tcp_pcb* pcb, int argc, char** argv) {
UNUSED(argv);
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");
tcp_cmd_write(pcb, "Usage: ls\n");
return;
}
/**
* @brief This function handles the setimage command
*
* @param[in] pcb The tcp_pcb struct to write to
* @param[in] argc The number of arguments
* @param[in] argv The arguments
*/
static void tcp_cmd_set_image(struct tcp_pcb* pcb, int argc, char** argv) {
const char* ext = NULL;
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 == 1) {
LOG_INFO(TAG, "Setting image %s @ 0, 0", argv[0]);
lcd_draw_img_from_fs(argv[0], 0, 0);
return;
}
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");
tcp_cmd_write(pcb, "Usage: setimage <filename>\n");
tcp_cmd_write(pcb, "Usage: setimage <filename> <x> <y>\n");
}
/**
* @brief This function handles the setgif command
*
* @param[in] pcb The tcp_pcb struct to write to
* @param[in] argc The number of arguments
* @param[in] argv The arguments
*/
static void tcp_cmd_set_gif(struct tcp_pcb* pcb, int argc, char** argv) {
const char* ext = NULL;
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 == 1) {
LOG_INFO(TAG, "Setting gif %s @ 0, 0", argv[0]);
lcd_draw_gif_from_fs(argv[0], 0, 0);
return;
}
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;
}
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");
}
/**
* @brief This function handles the exit command
*
* @param[in] pcb The tcp_pcb struct to write to
* @param[in] argc The number of arguments
* @param[in] argv The arguments
*/
static void tcp_cmd_exit(struct tcp_pcb* pcb, int argc, char** argv) {
UNUSED(argv);
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");
}
/**
* @brief This function handles unknown commands
*
* @param[in] pcb The tcp_pcb struct to write to
* @param[in] cmd The command
*/
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, cmd);
tcp_cmd_write(pcb, "\n");
tcp_cmd_write(pcb, "Type help for list of commands\n");
}
/**
* @brief This function parses the command and calls the appropriate function
*
* @param pcb Pointer to the tcp_pcb struct to write to
* @param argc Count of arguments
* @param argv Array of arguments
* @param[in] pcb Pointer to the tcp_pcb struct to write to
* @param[in] argc Count of arguments
* @param[in] argv Array of arguments
* @return true Connection should be closed
* @return false Connection should be kept open
*/
@@ -356,53 +447,58 @@ 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, "ls") == 0) {
tcp_cmd_list_files(pcb, argc, argv);
return false;
}
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;
}
/**
* @brief This function is called when the tcp connection receives data
* @param arg The argument ptr
* @param pcb The tcp_pcb struct
* @param p The pbuf struct
* @param err The error code from the tcp stack
* @param[in] arg The argument ptr
* @param[in] pcb The tcp_pcb struct
* @param[in] p The pbuf struct
* @param[in] err The error code from the tcp stack
* @return err_t ERR_OK if successful
*/
err_t tcp_cmd_recv(void* arg, struct tcp_pcb* pcb, struct pbuf* p, err_t err) {
@@ -445,7 +541,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) {
@@ -467,12 +563,12 @@ err_t tcp_cmd_recv(void* arg, struct tcp_pcb* pcb, struct pbuf* p, err_t err) {
if (close_conn) {
LOG_INFO(TAG, "Closing connection");
tcp_cmd_close(pcb);
#ifdef LINUX
#ifdef NCAT
} else {
tcp_cmd_write(pcb, "$>");
}
#else
} else if(argc > 0) {
} else if (argc > 0) {
tcp_cmd_write(pcb, "$>");
} else {
tcp_cmd_write(pcb, "");
@@ -486,9 +582,9 @@ defer:
/**
* @brief This function is called when a new tcp connection is accepted
* @param arg The argument
* @param pcb The tcp_pcb struct
* @param err The error
* @param[in] arg The argument
* @param[in] pcb The tcp_pcb struct
* @param[in] err The error
* @return err_t ERR_OK
*/
static err_t tcp_cmd_accept(void* arg, struct tcp_pcb* pcb, err_t err) {
@@ -505,7 +601,7 @@ static err_t tcp_cmd_accept(void* arg, struct tcp_pcb* pcb, err_t err) {
}
/**
* @brief This function closes the tcp connection
* @param pcb The tcp_pcb struct to close
* @param[in] pcb The tcp_pcb struct to close
*/
static void tcp_cmd_close(struct tcp_pcb* pcb) {
tcp_arg(pcb, NULL);

View File

@@ -81,26 +81,26 @@ TEST(TCP_CMD, tcp_data_cb) {
tcp_cmd_recv(NULL, NULL, &p, ERR_OK);
output = testing::internal::GetCapturedStdout();
#ifndef DEBUG
EXPECT_EQ(output, "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"
"bgColor <r> <g> <b> : set the background color of the lcd\n"
"color <r> <g> <b> : set the color of the text\n"
"listFiles : shows a list with images in the filesystem\n"
"setImage <image_name> : put an image on the screen\n"
"setGif <image_name> : put a gif on the screen\n"
"exit : closes the connection\n\n$>\n");
EXPECT_EQ(output, "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"
"bgColor (<a>) <r> <g> <b> : set the background color of the lcd\n"
"color (<a>) <r> <g> <b> : set the color of the text\n"
"listFiles : shows a list with images in the filesystem\n"
"setImage <image_name> : put an image on the screen\n"
"setGif <image_name> : put a gif on the screen\n"
"exit : closes the connection\n\n$>\n");
#else
EXPECT_EQ(output, "tcp_recved\ntcp_write:\n"
"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"
"bgColor <r> <g> <b> : set the background color of the lcd\n"
"color <r> <g> <b> : set the color of the text\n"
"listFiles : shows a list with images in the filesystem\n"
"setImage <image_name> : put an image on the screen\n"
"setGif <image_name> : put a gif on the screen\n"
"exit : closes the connection\n"
"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"
"bgColor (<a>) <r> <g> <b> : set the background color of the lcd\n"
"color (<a>) <r> <g> <b> : set the color of the text\n"
"listFiles : shows a list with images in the filesystem\n"
"setImage <image_name> : put an image on the screen\n"
"setGif <image_name> : put a gif on the screen\n"
"exit : closes the connection\n"
"\ntcp_output\ntcp_write:\n$>\ntcp_output\npbuf_free\n");
#endif
@@ -113,7 +113,7 @@ TEST(TCP_CMD, tcp_data_cb) {
#ifndef DEBUG
EXPECT_EQ(output, "$>\n");
#else
EXPECT_EQ(output, "tcp_recved\nlcd_display_text @ 10 10 with color 0xFF000000 bg color 0xFF000000\nThis is printed on the display\ntcp_write:\n$>\ntcp_output\npbuf_free\n");
EXPECT_EQ(output, "tcp_recved\nlcd_display_text @ 10 10 with color 0xFFFFFFFF bg color 0xFF000000\nThis is printed on the display\ntcp_write:\n$>\ntcp_output\npbuf_free\n");
#endif
strcpy(cmd, "color 0x555555");
@@ -149,7 +149,7 @@ TEST(TCP_CMD, tcp_data_cb) {
#ifndef DEBUG
EXPECT_EQ(output, "$>\n");
#else
EXPECT_EQ(output, "tcp_recved\nlcd_display_text @ 10 10 with color 0xFF555555 bg color 0xFFAAAAAA\nThis is printed on the display\ntcp_write:\n$>\ntcp_output\npbuf_free\n");
EXPECT_EQ(output, "tcp_recved\nlcd_display_text @ 10 10 with color 0x00555555 bg color 0x00AAAAAA\nThis is printed on the display\ntcp_write:\n$>\ntcp_output\npbuf_free\n");
#endif
strcpy(cmd, "color 255 255 255");