From 42902a36bc52e009a1e8d3c371741e30a9cb4c33 Mon Sep 17 00:00:00 2001 From: Your Name Date: Tue, 19 May 2026 01:10:06 +0530 Subject: feat: ContextVM (MCP over Nostr) server with full integration Complete CVM implementation: persistent WebSocket relay listener, kind 25910 event subscription, MCP protocol handlers, CEP-6 announcements, 10 MCP tools, per-board hardware locks, WiFi EU regulatory fix. Architecture: - cvm_server.c: WS relay listener, kind 25910 subscription, MCP dispatch - mcp_handler.c/h: 10 MCP tools (get_config, set_config, get_balance, wallet_send, get_sessions, get_usage, set_payout, set_metric, set_price, wallet_melt) - Responses published via existing WS connection (not new TLS) - Auth check: only owner npub accepted - CEP-6: kinds 11316 (server), 11317 (tools), 10002 (relay list) - WS ping/pong keepalive every 30s, 60s TLS read timeout Critical fixes: - WiFi country code DE (ESP-IDF defaults to CN, breaks EU APs) - Subscription #p filter must be array not string - Use-after-free: tags_str freed before nostr_event_to_json - MCP responses via existing WS (ESP32 can't open multiple TLS) - EVENT msg buffer underflow, WS frame masking, TLS write loop Per-board hardware locks: - Lock files in physical-router-test-automation/locks/ - lock-a/b/c, unlock-a/b/c targets in 3 Makefiles - All hardware-touching targets require board lock Verified on Board B via relay.primal.net: - 282 unit tests passing (61 CVM + 60 MCP + 161 existing) - MCP initialize roundtrip: PASS - tools/list: PASS - tools/call get_config: PASS - tools/call get_balance: PASS - tools/call set_price: PASS (write operation) - CEP-6 announcements (11316, 11317, 10002): all accepted by relay - WiFi STA connection (EnterSSID-2.4GHz): PASS with country code DE - Board A WiFi confirmed hardware issue (not firmware) --- main/tollgate_main.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'main/tollgate_main.c') diff --git a/main/tollgate_main.c b/main/tollgate_main.c index 1350d70..ad5211a 100644 --- a/main/tollgate_main.c +++ b/main/tollgate_main.c @@ -9,6 +9,7 @@ #include "esp_netif.h" #include "lwip/netif.h" #include "lwip/dns.h" +#include "esp_sntp.h" #include "dhcpserver/dhcpserver.h" #include "config.h" #include "identity.h" @@ -22,6 +23,7 @@ #include "tollgate_client.h" #include "lightning_payout.h" #include "cvm_server.h" +#include "display.h" #define MAX_STA_RETRY 5 static const char *TAG = "tollgate_main"; @@ -54,6 +56,7 @@ static void wifi_event_handler(void *arg, esp_event_base_t event_base, tollgate_client_on_sta_disconnected(); if (s_services_running) stop_services(); if (s_retry_count < MAX_STA_RETRY) { + vTaskDelay(pdMS_TO_TICKS(2000)); esp_wifi_connect(); } else { wifi_config_t wifi_cfg; @@ -94,6 +97,13 @@ static void ip_event_handler(void *arg, esp_event_base_t event_base, s_retry_count = 0; xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT); + esp_sntp_stop(); + esp_sntp_setoperatingmode(SNTP_OPMODE_POLL); + esp_sntp_setservername(0, "pool.ntp.org"); + esp_sntp_setservername(1, "time.google.com"); + esp_sntp_init(); + ESP_LOGI(TAG, "SNTP time sync started"); + char gw_ip_str[16]; snprintf(gw_ip_str, sizeof(gw_ip_str), IPSTR, IP2STR(&event->ip_info.gw)); tollgate_client_on_sta_connected(gw_ip_str); @@ -160,6 +170,11 @@ static void start_services(void) s_services_running = true; if (s_services_mutex) xSemaphoreGive(s_services_mutex); ESP_LOGI(TAG, "=== TollGate services started ==="); + + display_set_state(DISPLAY_READY); + char portal_url[128]; + snprintf(portal_url, sizeof(portal_url), "http://%s/", cfg->ap_ip_str); + display_update(cfg->ap_ssid, 0, 0, portal_url); } static void stop_services(void) @@ -240,6 +255,9 @@ void app_main(void) { ESP_LOGI(TAG, "=== TollGate ESP32 Starting ==="); + display_init(); + display_set_state(DISPLAY_BOOT); + esp_err_t ret = nvs_flash_init(); if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { ESP_ERROR_CHECK(nvs_flash_erase()); @@ -288,6 +306,9 @@ void app_main(void) ESP_LOGI(TAG, "STA configured for SSID: %s", tcfg2->networks[tcfg2->current_network].ssid); } + ESP_ERROR_CHECK(esp_wifi_set_country_code("DE", false)); + ESP_LOGI(TAG, "WiFi country code set to DE (EU regulatory domain)"); + ESP_ERROR_CHECK(esp_wifi_start()); ESP_LOGI(TAG, "WiFi AP+STA started, waiting for connection..."); -- cgit v1.2.3