#include "tcp_server.h" #include #include #include "freertos/semphr.h" #include "lwip/sockets.h" #include "param.h" #include "sockbuf.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 void handle_set_cmd( sockbuf_t* sockbuf, ws_params_t* ws_params, const char* key) { ws_state_t snapshot; bool should_save = false; if (xSemaphoreTake(ws_params->state_lock, portMAX_DELAY) != pdTRUE) { sockbuf_write(sockbuf, "Failed to lock state\n"); return; } bool handled = false; if (false) { } #define STATE_PARAM(ty, attr, ...) \ else if (!strcmp_(key, #attr)) \ { \ cmd_handle(ty)(#attr, sockbuf, &ws_params->state.attr); \ handled = true; \ } #include "state_params.i" #undef STATE_PARAM if (!handled) { sockbuf_write(sockbuf, "Unknown attribute: '"); sockbuf_write(sockbuf, key); sockbuf_write(sockbuf, "'\n"); } else { snapshot = ws_params->state; should_save = true; } xSemaphoreGive(ws_params->state_lock); if (should_save) { ws_state_save(&snapshot); } } static void handle_print_cmd(sockbuf_t* sockbuf, ws_params_t* ws_params) { ws_state_t snapshot; if (xSemaphoreTake(ws_params->state_lock, portMAX_DELAY) != pdTRUE) { sockbuf_write(sockbuf, "Failed to lock state\n"); return; } snapshot = ws_params->state; xSemaphoreGive(ws_params->state_lock); #define STATE_PARAM(ty, attr, ...) print(ty)(sockbuf, #attr, snapshot.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); } }