#include "ws.h" #include "esp_websocket_client.h" #include "esp_log.h" #include #include "sdkconfig.h" #include "fw_command.h" static const char* TAG = "WS"; static esp_websocket_client_handle_t client = nullptr; static bool connected = false; static void ws_event_handler(void* handler_args, esp_event_base_t base, int32_t event_id, void* event_data) { switch (event_id) { case WEBSOCKET_EVENT_CONNECTED: connected = true; ESP_LOGI(TAG, "Connected"); break; case WEBSOCKET_EVENT_DISCONNECTED: connected = false; ESP_LOGI(TAG, "Disconnected"); break; case WEBSOCKET_EVENT_ERROR: connected = false; ESP_LOGE(TAG, "Error"); break; case WEBSOCKET_EVENT_DATA: { auto* data = (esp_websocket_event_data_t*)event_data; ESP_LOGI(TAG, "Recv: %.*s", data->data_len, (char*)data->data_ptr); // ⚠️ делаем null-terminated копию char buf[512]; // подбери размер под свой максимум int len = data->data_len; if (len >= sizeof(buf)) { ESP_LOGW(TAG, "Message too large"); break; } memcpy(buf, data->data_ptr, len); buf[len] = '\0'; fw_cmd_t cmd {}; if (parse_fw_command(buf, &cmd)) { ESP_LOGI(TAG, "FW command received"); ESP_LOGI(TAG, "URL: %s", cmd.url); ESP_LOGI(TAG, "SHA256: %s", cmd.sha256); // пока просто лог, без OTA } break; } } } void ws_init(const char* uri) { esp_websocket_client_config_t config = {}; config.uri = uri; config.reconnect_timeout_ms = 5000; config.network_timeout_ms = 5000; client = esp_websocket_client_init(&config); esp_websocket_register_events(client, WEBSOCKET_EVENT_ANY, ws_event_handler, NULL); } void ws_start() { if (client) { esp_websocket_client_start(client); } } bool ws_is_connected() { return connected; } void ws_send(const char* data) { if (connected && client) { esp_websocket_client_send_text(client, data, strlen(data), portMAX_DELAY); } } void ws_go() { char uri[128]; snprintf(uri, sizeof(uri), "ws://%s:%d/ws", CONFIG_SERVER_HOST, CONFIG_SERVER_PORT); ws_init(uri); ws_start(); }