#include #include "tcp_server.h" #include "sockbuf.h" #include "lwip/sockets.h" #include "station.h" static int strcmp_(const char* s1, const char* s2) { if (!s1) { return !s2; } if (!s2) { return !s1; } return strcmp(s1, s2); } static char* read_token(sockbuf_t* sockbuf, char* into, size_t sz) { int cur = 0; int ch = get_char(sockbuf); while (ch >= 0 && isspace(ch)) { ch = get_char(sockbuf); } while (ch >= 0 && !isspace(ch)) { if (sz > 1) { into[cur++] = (char) ch; sz --; } ch = get_char(sockbuf); } if (ch < 0) { return NULL; } if (sz >= 1) { into[cur] = 0; } return into; } static void handle_int_option( const char* attr, sockbuf_t* sockbuf, int* ptr) { char op_[8]; char buf_[32]; char* op = read_token(sockbuf, op_, sizeof(op_)); char* value = read_token(sockbuf, buf_, sizeof(buf_)); int curval = *ptr; int ivalue = atoi(value); if (!strcmp_(op, "+=")) { curval += ivalue; } else if (!strcmp_(op, "-=")) { curval -= ivalue; } else if (!strcmp_(op, "=")) { curval = ivalue; } else { sockbuf_write(sockbuf, "Unknown operation: '"); sockbuf_write(sockbuf, op); sockbuf_write(sockbuf, "'\n"); return; } snprintf(buf_, sizeof(buf_), "%s = %d\n", attr, curval); *ptr = curval; sockbuf_write(sockbuf, buf_); } static void handle_uint8_t_option( const char* attr, sockbuf_t* sockbuf, uint8_t* ptr) { int tmp = *ptr; handle_int_option(attr, sockbuf, &tmp); *ptr = tmp; } static void handle_uint32_t_option( const char* attr, sockbuf_t* sockbuf, uint32_t* ptr) { int tmp = *ptr; handle_int_option(attr, sockbuf, &tmp); *ptr = tmp; } static void handle_bool_option( const char* attr, sockbuf_t* sockbuf, bool* ptr) { char buf_[32]; char* op = read_token(sockbuf, buf_, sizeof(buf_)); bool curval = *ptr; if (!strcmp(op, "on")) { curval = 1; } else if (!strcmp(op, "off")) { curval = 0; } else if (!strcmp(op, "toggle")) { curval = !curval; } else { sockbuf_write(sockbuf, "Invalid value: '"); sockbuf_write(sockbuf, op); sockbuf_write(sockbuf, "'\n"); return; } *ptr = curval; snprintf(buf_, sizeof(buf_), "%s = %s\n", attr, curval ? "on" : "off"); sockbuf_write(sockbuf, buf_); } static void handle_set_cmd( sockbuf_t* sockbuf, ws_params_t* ws_params, const char* key) { if (false) {} #define STATE_PARAM(ty, attr, ...) \ else if (!strcmp_(key, #attr)) { \ handle_ ## ty ## _option(#attr, sockbuf, &ws_params->state. attr); \ } #include "state_params.i" #undef STATE_PARAM else { sockbuf_write(sockbuf, "Unknown attribute: '"); sockbuf_write(sockbuf, key); sockbuf_write(sockbuf, "'\n"); } } static void print_uint32_t(sockbuf_t* sockbuf, const char* attr, uint32_t val) { char buf[128]; snprintf(buf, sizeof(buf), "%s: %ld :: uint32_t\n", attr, val); sockbuf_write(sockbuf, buf); } static void print_uint8_t(sockbuf_t* sockbuf, const char* attr, uint8_t val) { char buf[128]; snprintf(buf, sizeof(buf), "%s: %d :: uint8_t\n", attr, (int) val); sockbuf_write(sockbuf, buf); } static void print_bool(sockbuf_t* sockbuf, const char* attr, bool val) { char buf[128]; snprintf(buf, sizeof(buf), "%s: %s :: bool\n", attr, val ? "on" : "off"); sockbuf_write(sockbuf, buf); } static void print_int(sockbuf_t* sockbuf, const char* attr, int val) { char buf[128]; snprintf(buf, sizeof(buf), "%s: %d :: int\n", attr, val); sockbuf_write(sockbuf, buf); } static void handle_print_cmd(sockbuf_t* sockbuf, ws_params_t* ws_params) { #define STATE_PARAM(ty, attr, ...) \ print_ ## ty ( sockbuf, #attr, ws_params->state. attr ); #include "state_params.i" #undef STATE_PARAM } static void run_sockbuf(sockbuf_t* sockbuf, ws_params_t* ws_params) { char buf[128]; while (true) { sockbuf_write(sockbuf, "\x1b[1;32mws2812b>\x1b[0m "); char* cmd = read_token(sockbuf, buf, sizeof(buf)); if (!cmd) { break; } if (!strcmp_(cmd, "set")) { char* key = read_token(sockbuf, buf, sizeof(buf)); if (key) { handle_set_cmd(sockbuf, ws_params, key); } } else if (!strcmp_(cmd, "print")) { handle_print_cmd(sockbuf, ws_params); } else if (!strcmp_(cmd, "end")) { close(sockbuf->socket); return; } else { sockbuf_write(sockbuf, "Unknown command: '"); sockbuf_write(sockbuf, cmd); sockbuf_write(sockbuf, "'\n"); } } } portTASK_FUNCTION(tcp_server, params) { ws_params_t* ws_params = (ws_params_t*) params; int s = socket(AF_INET, SOCK_STREAM, 0); struct sockaddr_in addr; memset(&addr, 0, sizeof(addr)); addr.sin_port = htons(1234); addr.sin_family = AF_INET; addr.sin_addr.s_addr = INADDR_ANY; int err = bind(s, (struct sockaddr*)&addr, sizeof(addr)); if (err) { printf("Error binding to sockaddr: %d\n", err); return; } printf("Listening ...\n"); listen(s, 1); while (true) { printf("Waiting for connection... \n"); struct sockaddr_in client_addr; socklen_t size; int sock = accept(s, (struct sockaddr*)&client_addr, &size); printf("Accepted connection\n"); sockbuf_t sockbuf; init_sockbuf(&sockbuf, sock); run_sockbuf(&sockbuf, ws_params); } }