tcp_cmd
move functions from test file to project
This commit is contained in:
@@ -13,12 +13,17 @@
|
|||||||
#endif
|
#endif
|
||||||
#include "llfs.h"
|
#include "llfs.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
#include <tcp.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
|
||||||
void tcp_cmd_init(void);
|
void tcp_cmd_init(void);
|
||||||
|
|
||||||
void tcp_cmd_init( void );
|
|
||||||
void tcp_cmd_write(struct tcp_pcb* pcb, const char* str);
|
void tcp_cmd_write(struct tcp_pcb* pcb, const char* str);
|
||||||
void tcp_cmd_print_help(struct tcp_pcb* pcb);
|
void tcp_cmd_print_help(struct tcp_pcb* pcb);
|
||||||
|
err_t tcp_cmd_recv(void* arg, struct tcp_pcb* pcb, struct pbuf* p, err_t err);
|
||||||
|
|
||||||
#endif /* INC_TCP_CMD_H_ */
|
#endif /* INC_TCP_CMD_H_ */
|
||||||
|
|||||||
@@ -6,8 +6,12 @@
|
|||||||
*/
|
*/
|
||||||
#include "tcp_cmd.h"
|
#include "tcp_cmd.h"
|
||||||
|
|
||||||
static uint32_t result_txt = 0xff000000; // Store text color
|
#define MAX_TOKENS 10
|
||||||
static uint32_t result_bg = 0xff000000; // Store background color
|
#define MAX_CMD_LEN 50
|
||||||
|
|
||||||
|
static const char* TAG = "tcp_cmd";
|
||||||
|
static uint32_t color_txt = 0xff000000; // Store text color
|
||||||
|
static uint32_t color_bg = 0xff000000; // Store background color
|
||||||
|
|
||||||
static void tcp_cmd_close(struct tcp_pcb* pcb) {
|
static void tcp_cmd_close(struct tcp_pcb* pcb) {
|
||||||
tcp_arg(pcb, NULL);
|
tcp_arg(pcb, NULL);
|
||||||
@@ -40,146 +44,239 @@ void tcp_cmd_print_help(struct tcp_pcb* pcb) {
|
|||||||
"exit : closes the connection\r\n");
|
"exit : closes the connection\r\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
static err_t tcp_cmd_recv(void* arg, struct tcp_pcb* pcb, struct pbuf* p, err_t err) {
|
void remove_newline(char* str) {
|
||||||
size_t i;
|
int i = 0;
|
||||||
size_t len;
|
while (str[i] != '\0') {
|
||||||
size_t number_of_files;
|
if (str[i] == '\n' || str[i] == '\r') {
|
||||||
uint8_t file_in_fs;
|
str[i] = '\0';
|
||||||
uint8_t check = 0;
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
char* pc;
|
void str_tolower(char* str) {
|
||||||
char text[256];
|
int i = 0;
|
||||||
char color_r[3];
|
while (str[i] != '\0') {
|
||||||
char color_g[3];
|
str[i] = (char)tolower((int)str[i]);
|
||||||
char color_b[3];
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
char text_color_r[3];
|
char* get_filename_ext(char* filename) {
|
||||||
char text_color_g[3];
|
char* dot = strrchr(filename, '.');
|
||||||
char text_color_b[3];
|
if (!dot || dot == filename)
|
||||||
|
return NULL;
|
||||||
|
return dot + 1;
|
||||||
|
}
|
||||||
|
|
||||||
char extension[4];
|
// Function to find the next token in the input string
|
||||||
|
// If the token is between quotes, return the whole string between quotes
|
||||||
|
char* get_next_token(char* input, const char* delimiters, char** next) {
|
||||||
|
if (input == NULL) {
|
||||||
|
input = *next;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skip leading delimiters
|
||||||
|
input += strspn(input, delimiters);
|
||||||
|
if (*input == '\0') {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the token is between quotes, return the whole string between quotes
|
||||||
|
if (*input == '"') {
|
||||||
|
char* end = strchr(++input, '"');
|
||||||
|
if (end == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
*end = '\0';
|
||||||
|
*next = end + 1;
|
||||||
|
return input;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find the end of the token
|
||||||
|
char* end = input + strcspn(input, delimiters);
|
||||||
|
if (*end == '\0') {
|
||||||
|
*next = end;
|
||||||
|
} else {
|
||||||
|
*end = '\0';
|
||||||
|
*next = end + 1;
|
||||||
|
}
|
||||||
|
return input;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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
|
||||||
|
* @return true Connection should be closed
|
||||||
|
* @return false Connection should be kept open
|
||||||
|
*/
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
str_tolower(argv[0]);
|
||||||
|
if (strcmp(argv[0], "help") == 0) {
|
||||||
|
tcp_cmd_print_help(pcb);
|
||||||
|
return false;
|
||||||
|
} if (strcmp(argv[0], "text") == 0) {
|
||||||
|
if (argc == 2) {
|
||||||
|
lcd_clear_text();
|
||||||
|
lcd_display_text((uint8_t*)argv[1], 10, 10, color_txt, color_bg, LCD_FONT24);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
tcp_cmd_write(pcb, "Usage: text \"<text>\"\n");
|
||||||
|
tcp_cmd_write(pcb, "Usage: text <word>\n");
|
||||||
|
return false;
|
||||||
|
} if (strcmp(argv[0], "bgcolor") == 0) {
|
||||||
|
if (argc == 2) {
|
||||||
|
color_bg = (uint32_t)strtol(argv[1], NULL, 16);
|
||||||
|
color_bg |= 0xff000000;
|
||||||
|
return false;
|
||||||
|
} if (argc == 4) {
|
||||||
|
color_bg = 0xff000000;
|
||||||
|
color_bg |= (uint32_t)strtol(argv[1], NULL, 10) << 16;
|
||||||
|
color_bg |= (uint32_t)strtol(argv[2], NULL, 10) << 8;
|
||||||
|
color_bg |= (uint32_t)strtol(argv[3], NULL, 10);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
tcp_cmd_write(pcb, "Usage: bgcolor <background color>\n");
|
||||||
|
tcp_cmd_write(pcb, "Usage: bgcolor r g b\n");
|
||||||
|
return false;
|
||||||
|
} if (strcmp(argv[0], "color") == 0) {
|
||||||
|
if (argc == 2) {
|
||||||
|
color_txt = (uint32_t)strtol(argv[1], NULL, 16);
|
||||||
|
color_txt |= 0xff000000;
|
||||||
|
return false;
|
||||||
|
} if (argc == 4) {
|
||||||
|
color_txt = 0xff000000;
|
||||||
|
color_txt |= (uint32_t)strtol(argv[1], NULL, 10) << 16;
|
||||||
|
color_txt |= (uint32_t)strtol(argv[2], NULL, 10) << 8;
|
||||||
|
color_txt |= (uint32_t)strtol(argv[3], NULL, 10);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
tcp_cmd_write(pcb, "Usage: color 0x<txt color>\n");
|
||||||
|
tcp_cmd_write(pcb, "Usage: color <r> <g> <b>\n");
|
||||||
|
return false;
|
||||||
|
} if (strcmp(argv[0], "listimages") == 0) {
|
||||||
|
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, "\r\n");
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
} if (strcmp(argv[0], "setimage") == 0) {
|
||||||
|
if (argc >= 2) {
|
||||||
|
ext = get_filename_ext(argv[1]);
|
||||||
|
if (strcmp(ext, "bmp") != 0) {
|
||||||
|
tcp_cmd_write(pcb, "File is not a bmp\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} if (argc == 2) {
|
||||||
|
lcd_clear_images();
|
||||||
|
lcd_draw_img_from_fs(argv[1], 0, 0);
|
||||||
|
return false;
|
||||||
|
} if (argc == 4) {
|
||||||
|
lcd_clear_images();
|
||||||
|
lcd_draw_img_from_fs(argv[1], (uint32_t)atoi(argv[2]), (uint32_t)atoi(argv[3]));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
tcp_cmd_write(pcb, "Usage: setimage <filename>\n");
|
||||||
|
tcp_cmd_write(pcb, "Usage: setimage <filename> <x> <y>\n");
|
||||||
|
return false;
|
||||||
|
} if (strcmp(argv[0], "setgif") == 0) {
|
||||||
|
if (argc >= 2) {
|
||||||
|
char* ext = get_filename_ext(argv[1]);
|
||||||
|
if (strcmp(ext, "gif") != 0) {
|
||||||
|
tcp_cmd_write(pcb, "File is not a gif\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} if (argc == 2) {
|
||||||
|
lcd_clear_images();
|
||||||
|
lcd_draw_gif_from_fs(argv[1], 0, 0);
|
||||||
|
return false;
|
||||||
|
} if (argc == 4) {
|
||||||
|
lcd_clear_images();
|
||||||
|
lcd_draw_gif_from_fs(argv[1], (uint32_t)atoi(argv[2]), (uint32_t)atoi(argv[3]));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
tcp_cmd_write(pcb, "Usage: setgif <filename>\n");
|
||||||
|
tcp_cmd_write(pcb, "Usage: setgif <filename> <x> <y>\n");
|
||||||
|
return false;
|
||||||
|
} if (strcmp(argv[0], "exit") == 0) {
|
||||||
|
tcp_cmd_write(pcb, "Exiting...\n");
|
||||||
|
lcd_clear_images();
|
||||||
|
lcd_clear_text();
|
||||||
|
tcp_close(pcb);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
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\r\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
err_t tcp_cmd_recv(void* arg, struct tcp_pcb* pcb, struct pbuf* p, err_t err) {
|
||||||
|
int argc = 0;
|
||||||
|
char cmd[MAX_CMD_LEN];
|
||||||
|
char* argv[MAX_TOKENS];
|
||||||
|
bool close_conn = false;
|
||||||
|
char* next;
|
||||||
|
|
||||||
LWIP_UNUSED_ARG(arg);
|
LWIP_UNUSED_ARG(arg);
|
||||||
|
LOG_DEBUG(TAG, "TCP data received");
|
||||||
|
|
||||||
if (err == ERR_OK && p != NULL) {
|
// Connection closed?
|
||||||
tcp_recved(pcb, p->tot_len);
|
if (p == NULL && err == ERR_OK) {
|
||||||
pc = (char*)p->payload;
|
LOG_INFO(TAG, "Remote closed connection");
|
||||||
len = p->tot_len;
|
return tcp_close(pcb);
|
||||||
|
|
||||||
if (!strncmp(pc, "help", 4)) {
|
|
||||||
check = 1;
|
|
||||||
tcp_cmd_print_help(pcb);
|
|
||||||
} else if (!strncmp(pc, "text ", 5)) {
|
|
||||||
for (i = 0; i < len - 4; i++) {
|
|
||||||
text[i] = pc[i + 5];
|
|
||||||
}
|
|
||||||
text[i - 1] = '\0';
|
|
||||||
lcd_clear_text();
|
|
||||||
lcd_display_text((uint8_t*)text, 10, 10, result_txt, result_bg, LCD_FONT24);
|
|
||||||
|
|
||||||
check = 1;
|
|
||||||
} else if (!strncmp(pc, "color", 5)) {
|
|
||||||
for (size_t i = 0; i < 3; i++) {
|
|
||||||
color_r[i] = pc[i + 6];
|
|
||||||
color_g[i] = pc[i + 10];
|
|
||||||
color_b[i] = pc[i + 14];
|
|
||||||
}
|
|
||||||
result_bg |= (uint32_t)strtoul(color_r, NULL, 10) << 16;
|
|
||||||
result_bg |= (uint32_t)strtoul(color_g, NULL, 10) << 8;
|
|
||||||
result_bg |= (uint32_t)strtoul(color_b, NULL, 10);
|
|
||||||
|
|
||||||
check = 1;
|
|
||||||
} else if (!strncmp(pc, "textColor", 9)) {
|
|
||||||
for (size_t i = 0; i < 3; i++) {
|
|
||||||
text_color_r[i] = pc[i + 10];
|
|
||||||
text_color_g[i] = pc[i + 14];
|
|
||||||
text_color_b[i] = pc[i + 18];
|
|
||||||
}
|
|
||||||
result_txt |= (uint32_t)strtoul(text_color_r, NULL, 10) << 16;
|
|
||||||
result_txt |= (uint32_t)strtoul(text_color_g, NULL, 10) << 8;
|
|
||||||
result_txt |= (uint32_t)strtoul(text_color_b, NULL, 10);
|
|
||||||
|
|
||||||
check = 1;
|
|
||||||
} else if (!strncmp(pc, "listImages", 10)) {
|
|
||||||
number_of_files = llfs_file_count();
|
|
||||||
|
|
||||||
llfs_file_t file_list[number_of_files];
|
|
||||||
|
|
||||||
number_of_files = llfs_file_list(file_list, number_of_files, NULL);
|
|
||||||
|
|
||||||
for (size_t i = 0; i < number_of_files; i++) {
|
|
||||||
tcp_cmd_write(pcb, file_list[i].name);
|
|
||||||
tcp_cmd_write(pcb, "\r\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
check = 1;
|
|
||||||
} else if (!strncmp(pc, "setImage", 8)) {
|
|
||||||
char filename[len - 8];
|
|
||||||
for (size_t i = 0; i < len - 9; i++) {
|
|
||||||
filename[i] = pc[i + 9];
|
|
||||||
}
|
|
||||||
for (size_t i = 0; i < 3; i++) {
|
|
||||||
extension[i] = pc[i + len - 3];
|
|
||||||
}
|
|
||||||
filename[sizeof(filename) - 1] = '\0';
|
|
||||||
extension[3] = '\0';
|
|
||||||
|
|
||||||
number_of_files = llfs_file_count();
|
|
||||||
|
|
||||||
if(number_of_files > 0) {
|
|
||||||
llfs_file_t file_list[number_of_files];
|
|
||||||
|
|
||||||
number_of_files = llfs_file_list(file_list, number_of_files, NULL);
|
|
||||||
|
|
||||||
file_in_fs = 0;
|
|
||||||
for (size_t i = 0; i < number_of_files; i++) {
|
|
||||||
if (!strcmp(filename, file_list[i].name)) {
|
|
||||||
file_in_fs = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check which file extension is used and call right function
|
|
||||||
if (!strncmp(extension, "bmp", 3) && file_in_fs) {
|
|
||||||
lcd_clear_images();
|
|
||||||
lcd_draw_img_from_fs(filename, 10, 10);
|
|
||||||
} else if (!strncmp(extension, "gif", 3) && file_in_fs) {
|
|
||||||
lcd_clear_images();
|
|
||||||
lcd_draw_gif_from_fs(filename, 10, 10);
|
|
||||||
} else if (!file_in_fs) {
|
|
||||||
tcp_cmd_write(pcb, "File NOT in filesystem\n\r");
|
|
||||||
} else {
|
|
||||||
tcp_cmd_write(pcb, "Extension NOT supported\n\r");
|
|
||||||
}
|
|
||||||
|
|
||||||
check = 1;
|
|
||||||
} else if (!strncmp(pc, "exit", 4)) {
|
|
||||||
lcd_clear_images();
|
|
||||||
lcd_clear_text();
|
|
||||||
tcp_cmd_close(pcb);
|
|
||||||
check = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!check && (strncmp(pc, "\r\n", 2) != 0)) {
|
|
||||||
tcp_cmd_write(pcb, "Nonexistent command: help for list of commands\r\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
pbuf_free(p);
|
|
||||||
|
|
||||||
if (len > tcp_sndbuf(pcb)) {
|
|
||||||
len = tcp_sndbuf(pcb);
|
|
||||||
}
|
|
||||||
tcp_sent(pcb, NULL);
|
|
||||||
} else {
|
|
||||||
pbuf_free(p);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (err == ERR_OK && p == NULL) {
|
if (err != ERR_OK) {
|
||||||
|
LOG_WARN(TAG, "TCP data received with error(%d): %s", err, lwip_strerr(err));
|
||||||
|
return ERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure the string is null terminated
|
||||||
|
if (p->len >= MAX_CMD_LEN) {
|
||||||
|
LOG_WARN(TAG, "Command too long");
|
||||||
|
}
|
||||||
|
uint16_t len = p->tot_len >= MAX_CMD_LEN ? MAX_CMD_LEN : p->tot_len;
|
||||||
|
|
||||||
|
pbuf_copy_partial(p, cmd, len, 0);
|
||||||
|
cmd[len] = '\0';
|
||||||
|
|
||||||
|
// Tell the tcp stack that we have taken the data
|
||||||
|
tcp_recved(pcb, p->tot_len);
|
||||||
|
|
||||||
|
remove_newline(cmd);
|
||||||
|
// Split string into tokens by delimiter (space)
|
||||||
|
argv[0] = get_next_token(cmd, " ", &next);
|
||||||
|
argc = 1;
|
||||||
|
while (argv[argc - 1] != NULL && argc < MAX_TOKENS) {
|
||||||
|
argv[argc] = get_next_token(NULL, " ", &next);
|
||||||
|
if (argv[argc] == NULL) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
argc++;
|
||||||
|
}
|
||||||
|
|
||||||
|
close_conn = tcp_cmd_parser(pcb, argc, argv);
|
||||||
|
|
||||||
|
if (close_conn) {
|
||||||
tcp_cmd_close(pcb);
|
tcp_cmd_close(pcb);
|
||||||
}
|
} else {
|
||||||
if (strncmp(pc, "\r\n", 2) != 0) {
|
tcp_cmd_write(pcb, "$> ");
|
||||||
tcp_cmd_write(pcb, "User: ");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
defer:
|
||||||
|
pbuf_free(p);
|
||||||
return ERR_OK;
|
return ERR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,310 +9,60 @@ extern "C" {
|
|||||||
#include "tcp_cmd.h"
|
#include "tcp_cmd.h"
|
||||||
}
|
}
|
||||||
|
|
||||||
#define MAX_TOKENS 10
|
|
||||||
#define MAX_CMD_LEN 50
|
|
||||||
|
|
||||||
static uint32_t color_txt = 0;
|
|
||||||
static uint32_t color_bg = 0;
|
|
||||||
static const char* TAG = "tcp_cmd";
|
|
||||||
|
|
||||||
static void tcp_cmd_close(struct tcp_pcb* pcb) {
|
|
||||||
tcp_arg(pcb, NULL);
|
|
||||||
tcp_sent(pcb, NULL);
|
|
||||||
tcp_recv(pcb, NULL);
|
|
||||||
tcp_close(pcb);
|
|
||||||
}
|
|
||||||
|
|
||||||
void remove_newline(char* str) {
|
|
||||||
int i = 0;
|
|
||||||
while (str[i] != '\0') {
|
|
||||||
if (str[i] == '\n' || str[i] == '\r') {
|
|
||||||
str[i] = '\0';
|
|
||||||
}
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void str_tolower(char* str) {
|
|
||||||
int i = 0;
|
|
||||||
while (str[i] != '\0') {
|
|
||||||
str[i] = (char)tolower((int)str[i]);
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
char* get_filename_ext(char* filename) {
|
|
||||||
char* dot = strrchr(filename, '.');
|
|
||||||
if (!dot || dot == filename)
|
|
||||||
return NULL;
|
|
||||||
return dot + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Function to find the next token in the input string
|
|
||||||
// If the token is between quotes, return the whole string between quotes
|
|
||||||
char* get_next_token(char* input, const char* delimiters, char** next) {
|
|
||||||
if (input == NULL) {
|
|
||||||
input = *next;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Skip leading delimiters
|
|
||||||
input += strspn(input, delimiters);
|
|
||||||
if (*input == '\0') {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the token is between quotes, return the whole string between quotes
|
|
||||||
if (*input == '"') {
|
|
||||||
char* end = strchr(++input, '"');
|
|
||||||
if (end == NULL) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
*end = '\0';
|
|
||||||
*next = end + 1;
|
|
||||||
return input;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find the end of the token
|
|
||||||
char* end = input + strcspn(input, delimiters);
|
|
||||||
if (*end == '\0') {
|
|
||||||
*next = end;
|
|
||||||
} else {
|
|
||||||
*end = '\0';
|
|
||||||
*next = end + 1;
|
|
||||||
}
|
|
||||||
return input;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @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
|
|
||||||
* @return true Connection should be closed
|
|
||||||
* @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;
|
|
||||||
}
|
|
||||||
str_tolower(argv[0]);
|
|
||||||
if (strcmp(argv[0], "help") == 0) {
|
|
||||||
tcp_cmd_print_help(pcb);
|
|
||||||
return false;
|
|
||||||
} if (strcmp(argv[0], "text") == 0) {
|
|
||||||
if (argc == 2) {
|
|
||||||
lcd_clear_text();
|
|
||||||
lcd_display_text((uint8_t*)argv[1], 10, 10, color_txt, color_bg, LCD_FONT24);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
tcp_cmd_write(pcb, "Usage: text \"<text>\"\n");
|
|
||||||
tcp_cmd_write(pcb, "Usage: text <word>\n");
|
|
||||||
return false;
|
|
||||||
} if (strcmp(argv[0], "bgcolor") == 0) {
|
|
||||||
if (argc == 2) {
|
|
||||||
color_bg = (uint32_t)strtol(argv[1], NULL, 16);
|
|
||||||
color_bg |= 0xff000000;
|
|
||||||
return false;
|
|
||||||
} if (argc == 4) {
|
|
||||||
color_bg = 0xff000000;
|
|
||||||
color_bg |= (uint32_t)strtol(argv[1], NULL, 10) << 16;
|
|
||||||
color_bg |= (uint32_t)strtol(argv[2], NULL, 10) << 8;
|
|
||||||
color_bg |= (uint32_t)strtol(argv[3], NULL, 10);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
tcp_cmd_write(pcb, "Usage: bgcolor <background color>\n");
|
|
||||||
tcp_cmd_write(pcb, "Usage: bgcolor r g b\n");
|
|
||||||
return false;
|
|
||||||
} if (strcmp(argv[0], "color") == 0) {
|
|
||||||
if (argc == 2) {
|
|
||||||
color_txt = (uint32_t)strtol(argv[1], NULL, 16);
|
|
||||||
color_txt |= 0xff000000;
|
|
||||||
return false;
|
|
||||||
} if (argc == 4) {
|
|
||||||
color_txt = 0xff000000;
|
|
||||||
color_txt |= (uint32_t)strtol(argv[1], NULL, 10) << 16;
|
|
||||||
color_txt |= (uint32_t)strtol(argv[2], NULL, 10) << 8;
|
|
||||||
color_txt |= (uint32_t)strtol(argv[3], NULL, 10);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
tcp_cmd_write(pcb, "Usage: color 0x<txt color>\n");
|
|
||||||
tcp_cmd_write(pcb, "Usage: color <r> <g> <b>\n");
|
|
||||||
return false;
|
|
||||||
} if (strcmp(argv[0], "listimages") == 0) {
|
|
||||||
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, "\r\n");
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
} if (strcmp(argv[0], "setimage") == 0) {
|
|
||||||
if (argc >= 2) {
|
|
||||||
ext = get_filename_ext(argv[1]);
|
|
||||||
if (strcmp(ext, "bmp") != 0) {
|
|
||||||
tcp_cmd_write(pcb, "File is not a bmp\n");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} if (argc == 2) {
|
|
||||||
lcd_clear_images();
|
|
||||||
lcd_draw_img_from_fs(argv[1], 0, 0);
|
|
||||||
return false;
|
|
||||||
} if (argc == 4) {
|
|
||||||
lcd_clear_images();
|
|
||||||
lcd_draw_img_from_fs(argv[1], (uint32_t)atoi(argv[2]), (uint32_t)atoi(argv[3]));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
tcp_cmd_write(pcb, "Usage: setimage <filename>\n");
|
|
||||||
tcp_cmd_write(pcb, "Usage: setimage <filename> <x> <y>\n");
|
|
||||||
return false;
|
|
||||||
} if (strcmp(argv[0], "setgif") == 0) {
|
|
||||||
if (argc >= 2) {
|
|
||||||
char* ext = get_filename_ext(argv[1]);
|
|
||||||
if (strcmp(ext, "gif") != 0) {
|
|
||||||
tcp_cmd_write(pcb, "File is not a gif\n");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} if (argc == 2) {
|
|
||||||
lcd_clear_images();
|
|
||||||
lcd_draw_gif_from_fs(argv[1], 0, 0);
|
|
||||||
return false;
|
|
||||||
} if (argc == 4) {
|
|
||||||
lcd_clear_images();
|
|
||||||
lcd_draw_gif_from_fs(argv[1], (uint32_t)atoi(argv[2]), (uint32_t)atoi(argv[3]));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
tcp_cmd_write(pcb, "Usage: setgif <filename>\n");
|
|
||||||
tcp_cmd_write(pcb, "Usage: setgif <filename> <x> <y>\n");
|
|
||||||
return false;
|
|
||||||
} if (strcmp(argv[0], "exit") == 0) {
|
|
||||||
tcp_cmd_write(pcb, "Exiting...\n");
|
|
||||||
lcd_clear_images();
|
|
||||||
lcd_clear_text();
|
|
||||||
tcp_close(pcb);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
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\r\n");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static err_t tcp_cmd_recv_new(void* arg, struct tcp_pcb* pcb, struct pbuf* p, err_t err) {
|
|
||||||
int argc = 0;
|
|
||||||
char cmd[MAX_CMD_LEN];
|
|
||||||
char* argv[MAX_TOKENS];
|
|
||||||
bool close_conn = false;
|
|
||||||
char* next;
|
|
||||||
|
|
||||||
LWIP_UNUSED_ARG(arg);
|
|
||||||
LOG_DEBUG(TAG, "TCP data received");
|
|
||||||
|
|
||||||
// Connection closed?
|
|
||||||
if (p == NULL && err == ERR_OK) {
|
|
||||||
LOG_INFO(TAG, "Remote closed connection");
|
|
||||||
return tcp_close(pcb);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (err != ERR_OK) {
|
|
||||||
LOG_WARN(TAG, "TCP data received with error(%d): %s", err, lwip_strerr(err));
|
|
||||||
return ERR_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make sure the string is null terminated
|
|
||||||
if (p->len >= MAX_CMD_LEN) {
|
|
||||||
LOG_WARN(TAG, "Command too long");
|
|
||||||
}
|
|
||||||
uint16_t len = p->tot_len >= MAX_CMD_LEN ? MAX_CMD_LEN : p->tot_len;
|
|
||||||
|
|
||||||
pbuf_copy_partial(p, cmd, len, 0);
|
|
||||||
cmd[len] = '\0';
|
|
||||||
|
|
||||||
// Tell the tcp stack that we have taken the data
|
|
||||||
tcp_recved(pcb, p->tot_len);
|
|
||||||
|
|
||||||
remove_newline(cmd);
|
|
||||||
// Split string into tokens by delimiter (space)
|
|
||||||
argv[0] = get_next_token(cmd, " ", &next);
|
|
||||||
argc = 1;
|
|
||||||
while (argv[argc - 1] != NULL && argc < MAX_TOKENS) {
|
|
||||||
argv[argc] = get_next_token(NULL, " ", &next);
|
|
||||||
if (argv[argc] == NULL) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
argc++;
|
|
||||||
}
|
|
||||||
|
|
||||||
close_conn = tcp_cmd_parser(pcb, argc, argv);
|
|
||||||
|
|
||||||
if (close_conn) {
|
|
||||||
tcp_cmd_close(pcb);
|
|
||||||
} else {
|
|
||||||
tcp_cmd_write(pcb, "$> ");
|
|
||||||
}
|
|
||||||
|
|
||||||
defer:
|
|
||||||
pbuf_free(p);
|
|
||||||
return ERR_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(TCP_CMD, tcp_data_cb) {
|
TEST(TCP_CMD, tcp_data_cb) {
|
||||||
char* cmd = (char*)calloc(50, 1);
|
char* cmd = (char*)calloc(50, 1);
|
||||||
pbuf p = {.next = NULL, .payload = (void*)cmd, .tot_len = 4, .len = 0, .type_internal = 0, .flags = 0, .if_idx = 0};
|
pbuf p = {.next = NULL, .payload = (void*)cmd, .tot_len = 4, .len = 0, .type_internal = 0, .flags = 0, .if_idx = 0};
|
||||||
strcpy(cmd, "help");
|
strcpy(cmd, "help");
|
||||||
p.tot_len = (uint16_t)strlen(cmd);
|
p.tot_len = (uint16_t)strlen(cmd);
|
||||||
tcp_cmd_recv_new(NULL, NULL, &p, ERR_OK);
|
tcp_cmd_recv(NULL, NULL, &p, ERR_OK);
|
||||||
|
|
||||||
strcpy(cmd, "text \"This is printed on the display\"");
|
strcpy(cmd, "text \"This is printed on the display\"");
|
||||||
p.tot_len = (uint16_t)strlen(cmd);
|
p.tot_len = (uint16_t)strlen(cmd);
|
||||||
tcp_cmd_recv_new(NULL, NULL, &p, ERR_OK);
|
tcp_cmd_recv(NULL, NULL, &p, ERR_OK);
|
||||||
|
|
||||||
strcpy(cmd, "color 0x555555");
|
strcpy(cmd, "color 0x555555");
|
||||||
p.tot_len = (uint16_t)strlen(cmd);
|
p.tot_len = (uint16_t)strlen(cmd);
|
||||||
tcp_cmd_recv_new(NULL, NULL, &p, ERR_OK);
|
tcp_cmd_recv(NULL, NULL, &p, ERR_OK);
|
||||||
|
|
||||||
strcpy(cmd, "bgcolor 0xAAAAAA");
|
strcpy(cmd, "bgcolor 0xAAAAAA");
|
||||||
p.tot_len = (uint16_t)strlen(cmd);
|
p.tot_len = (uint16_t)strlen(cmd);
|
||||||
tcp_cmd_recv_new(NULL, NULL, &p, ERR_OK);
|
tcp_cmd_recv(NULL, NULL, &p, ERR_OK);
|
||||||
|
|
||||||
strcpy(cmd, "text \"This is printed on the display\"");
|
strcpy(cmd, "text \"This is printed on the display\"");
|
||||||
p.tot_len = (uint16_t)strlen(cmd);
|
p.tot_len = (uint16_t)strlen(cmd);
|
||||||
tcp_cmd_recv_new(NULL, NULL, &p, ERR_OK);
|
tcp_cmd_recv(NULL, NULL, &p, ERR_OK);
|
||||||
|
|
||||||
strcpy(cmd, "color 255 255 255");
|
strcpy(cmd, "color 255 255 255");
|
||||||
p.tot_len = (uint16_t)strlen(cmd);
|
p.tot_len = (uint16_t)strlen(cmd);
|
||||||
tcp_cmd_recv_new(NULL, NULL, &p, ERR_OK);
|
tcp_cmd_recv(NULL, NULL, &p, ERR_OK);
|
||||||
|
|
||||||
strcpy(cmd, "bgcolor 255 255 255");
|
strcpy(cmd, "bgcolor 255 255 255");
|
||||||
p.tot_len = (uint16_t)strlen(cmd);
|
p.tot_len = (uint16_t)strlen(cmd);
|
||||||
tcp_cmd_recv_new(NULL, NULL, &p, ERR_OK);
|
tcp_cmd_recv(NULL, NULL, &p, ERR_OK);
|
||||||
|
|
||||||
strcpy(cmd, "text \"This is printed on the display\"");
|
strcpy(cmd, "text \"This is printed on the display\"");
|
||||||
p.tot_len = (uint16_t)strlen(cmd);
|
p.tot_len = (uint16_t)strlen(cmd);
|
||||||
tcp_cmd_recv_new(NULL, NULL, &p, ERR_OK);
|
tcp_cmd_recv(NULL, NULL, &p, ERR_OK);
|
||||||
|
|
||||||
strcpy(cmd, "setImage \"test.bmp\"");
|
strcpy(cmd, "setImage \"test.bmp\"");
|
||||||
p.tot_len = (uint16_t)strlen(cmd);
|
p.tot_len = (uint16_t)strlen(cmd);
|
||||||
tcp_cmd_recv_new(NULL, NULL, &p, ERR_OK);
|
tcp_cmd_recv(NULL, NULL, &p, ERR_OK);
|
||||||
|
|
||||||
strcpy(cmd, "setImage \"test.gif\"");
|
strcpy(cmd, "setImage \"test.gif\"");
|
||||||
p.tot_len = (uint16_t)strlen(cmd);
|
p.tot_len = (uint16_t)strlen(cmd);
|
||||||
tcp_cmd_recv_new(NULL, NULL, &p, ERR_OK);
|
tcp_cmd_recv(NULL, NULL, &p, ERR_OK);
|
||||||
|
|
||||||
strcpy(cmd, "setGif \"test.gif\"");
|
strcpy(cmd, "setGif \"test.gif\"");
|
||||||
p.tot_len = (uint16_t)strlen(cmd);
|
p.tot_len = (uint16_t)strlen(cmd);
|
||||||
tcp_cmd_recv_new(NULL, NULL, &p, ERR_OK);
|
tcp_cmd_recv(NULL, NULL, &p, ERR_OK);
|
||||||
|
|
||||||
strcpy(cmd, "setGif \"test.bmp\"");
|
strcpy(cmd, "setGif \"test.bmp\"");
|
||||||
p.tot_len = (uint16_t)strlen(cmd);
|
p.tot_len = (uint16_t)strlen(cmd);
|
||||||
tcp_cmd_recv_new(NULL, NULL, &p, ERR_OK);
|
tcp_cmd_recv(NULL, NULL, &p, ERR_OK);
|
||||||
|
|
||||||
strcpy(cmd, "exit");
|
strcpy(cmd, "exit");
|
||||||
p.tot_len = (uint16_t)strlen(cmd);
|
p.tot_len = (uint16_t)strlen(cmd);
|
||||||
tcp_cmd_recv_new(NULL, NULL, &p, ERR_OK);
|
tcp_cmd_recv(NULL, NULL, &p, ERR_OK);
|
||||||
|
|
||||||
free(cmd);
|
free(cmd);
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user