diff options
| author | Your Name <you@example.com> | 2026-05-19 02:44:17 +0530 |
|---|---|---|
| committer | Your Name <you@example.com> | 2026-05-19 02:44:17 +0530 |
| commit | 2ad2ed45f3ca82b1244a8b9e3e5efa89502413a9 (patch) | |
| tree | 0f423dce2c22f8483b0c9f3c1bb642bf9ea5b01b | |
| parent | a09be62cfab9a1d7f37c697c44c71aed70536e8c (diff) | |
feat: WPA auto-detect, STA connectivity fix, lwip crash fix
- Add wifi_auth_mode config field (WPA2/WPA3) parsed from config.json
- Default to WPA2 (accepts both WPA2 and WPA3 networks)
- Replace hardcoded WIFI_AUTH_WPA3_PSK with runtime threshold mapping
- Reduce MINT_HEALTH_PROBE_INTERVAL_S from 300 to 30 for testing
- Add 3s delay before service start + 5s DNS stabilization for health probes
- Fixes lwip mem_free crash caused by concurrent HTTP at boot
Verified on hardware:
- STA connects to WPA2 home router (Got IP:192.168.2.16)
- All 4 mint health probes complete successfully
- API endpoints return correct data with reachable mint filtering
- 4/4 wallets initialized with real keysets from live mints
| -rw-r--r-- | docs/WPA-AUTO-DETECT-PLAN.md | 66 | ||||
| -rw-r--r-- | main/config.c | 14 | ||||
| -rw-r--r-- | main/config.h | 2 | ||||
| -rw-r--r-- | main/mint_health.c | 3 | ||||
| -rw-r--r-- | main/mint_health.h | 2 | ||||
| -rw-r--r-- | main/tollgate_main.c | 1 |
6 files changed, 85 insertions, 3 deletions
diff --git a/docs/WPA-AUTO-DETECT-PLAN.md b/docs/WPA-AUTO-DETECT-PLAN.md new file mode 100644 index 0000000..90ce681 --- /dev/null +++ b/docs/WPA-AUTO-DETECT-PLAN.md | |||
| @@ -0,0 +1,66 @@ | |||
| 1 | # WPA Auto-Detect + STA Connectivity Fix | ||
| 2 | |||
| 3 | ## Problem | ||
| 4 | |||
| 5 | `config.c:322` hardcodes `WIFI_AUTH_WPA3_PSK` as the STA auth threshold. The home | ||
| 6 | router (`EnterSSID-2.4GHz`) uses **WPA2**, so the ESP32 silently refuses | ||
| 7 | association and never gets internet. This blocks health probes, real payments, | ||
| 8 | and all downstream testing. | ||
| 9 | |||
| 10 | ## Solution | ||
| 11 | |||
| 12 | ### 1. Runtime WPA Threshold (Firmware) | ||
| 13 | |||
| 14 | Add `wifi_auth_mode` field to `tollgate_config_t`. Parse it from `config.json` | ||
| 15 | as a string (`"WPA2"`, `"WPA3"`, `"WPA2_WPA3"`). Map to ESP-IDF | ||
| 16 | `wifi_auth_mode_t` enum at runtime. Default to `WIFI_AUTH_WPA2_PSK` which | ||
| 17 | accepts both WPA2 and WPA3 networks. | ||
| 18 | |||
| 19 | ### 2. Makefile Auto-Detect (Build Time) | ||
| 20 | |||
| 21 | Add Makefile targets that scan WiFi with `nmcli`, detect WPA2 vs WPA3, and | ||
| 22 | generate a SPIFFS image with the correct `wifi_auth_mode` baked into | ||
| 23 | `config.json`. | ||
| 24 | |||
| 25 | ### 3. Reduced Probe Interval (Testing) | ||
| 26 | |||
| 27 | Temporarily reduce `MINT_HEALTH_PROBE_INTERVAL_S` from 300 to 30 so health | ||
| 28 | probes actually fire during short board uptime windows. | ||
| 29 | |||
| 30 | ## Files Changed | ||
| 31 | |||
| 32 | | File | Change | | ||
| 33 | |------|--------| | ||
| 34 | | `main/config.h` | Add `wifi_auth_mode` field to `tollgate_config_t` | | ||
| 35 | | `main/config.c` | Parse `wifi_auth_mode` from config.json; use it in `tollgate_config_get_wifi()` | | ||
| 36 | | `main/mint_health.h` | Reduce probe interval 300 → 30 | | ||
| 37 | | `physical-router-test-automation/esp32/Makefile` | Add `_detect-wpa-security`, `generate-spiffs`, `flash-spiffs-{a,b,c}` targets | | ||
| 38 | |||
| 39 | ## Checklist | ||
| 40 | |||
| 41 | ### Firmware Changes | ||
| 42 | - [ ] Add `wifi_auth_mode` string field (16 bytes) to `tollgate_config_t` in `config.h` | ||
| 43 | - [ ] Parse `wifi_auth_mode` from `config.json` in `config.c` with default `"WPA2"` | ||
| 44 | - [ ] Map `wifi_auth_mode` string to `wifi_auth_mode_t` in `tollgate_config_get_wifi()` | ||
| 45 | - [ ] Remove hardcoded `WIFI_AUTH_WPA3_PSK` at `config.c:322` | ||
| 46 | - [ ] Reduce `MINT_HEALTH_PROBE_INTERVAL_S` from 300 to 30 in `mint_health.h` | ||
| 47 | |||
| 48 | ### Makefile Auto-Detect | ||
| 49 | - [ ] Add `_detect-wpa-security` target (nmcli scan → extract WPA mode for SSID) | ||
| 50 | - [ ] Add `generate-spiffs` target (create config.json → spiffsgen.py) | ||
| 51 | - [ ] Add `flash-spiffs-a`, `flash-spiffs-b`, `flash-spiffs-c` targets | ||
| 52 | - [ ] Wire `flash-{a,b,c}` to auto-generate SPIFFS before flashing | ||
| 53 | |||
| 54 | ### Build & Test | ||
| 55 | - [ ] Build firmware — `idf.py build` passes | ||
| 56 | - [ ] Unit tests pass — `make test-unit` | ||
| 57 | - [ ] Wait for board unlock (no force-unlock) | ||
| 58 | - [ ] Lock board, flash firmware + SPIFFS | ||
| 59 | - [ ] Verify STA connects via serial (`Got IP:192.168.x.x`) | ||
| 60 | - [ ] Verify health probes fire and mints show `reachable: true` | ||
| 61 | - [ ] Run integration test suite | ||
| 62 | - [ ] Test 6 previously-skipped scenarios | ||
| 63 | |||
| 64 | ### Commit | ||
| 65 | - [ ] Commit all changes with descriptive message | ||
| 66 | - [ ] Push when Nostr relay recovers | ||
diff --git a/main/config.c b/main/config.c index 54642a2..fe0ceba 100644 --- a/main/config.c +++ b/main/config.c | |||
| @@ -35,6 +35,7 @@ esp_err_t tollgate_config_init(void) | |||
| 35 | g_config.payout.mint_count = 0; | 35 | g_config.payout.mint_count = 0; |
| 36 | g_config.cvm_enabled = true; | 36 | g_config.cvm_enabled = true; |
| 37 | strncpy(g_config.cvm_relays, "wss://relay.primal.net", sizeof(g_config.cvm_relays) - 1); | 37 | strncpy(g_config.cvm_relays, "wss://relay.primal.net", sizeof(g_config.cvm_relays) - 1); |
| 38 | strncpy(g_config.wifi_auth_mode, "WPA2", sizeof(g_config.wifi_auth_mode) - 1); | ||
| 38 | 39 | ||
| 39 | esp_vfs_spiffs_conf_t conf = { | 40 | esp_vfs_spiffs_conf_t conf = { |
| 40 | .base_path = "/spiffs", | 41 | .base_path = "/spiffs", |
| @@ -272,6 +273,11 @@ esp_err_t tollgate_config_init(void) | |||
| 272 | } | 273 | } |
| 273 | } | 274 | } |
| 274 | 275 | ||
| 276 | cJSON *auth_mode = cJSON_GetObjectItem(root, "wifi_auth_mode"); | ||
| 277 | if (auth_mode && cJSON_IsString(auth_mode)) { | ||
| 278 | strncpy(g_config.wifi_auth_mode, auth_mode->valuestring, sizeof(g_config.wifi_auth_mode) - 1); | ||
| 279 | } | ||
| 280 | |||
| 275 | if (g_config.payout.mint_count == 0 && g_config.mint_url[0] != '\0') { | 281 | if (g_config.payout.mint_count == 0 && g_config.mint_url[0] != '\0') { |
| 276 | strncpy(g_config.payout.mints[0].url, g_config.mint_url, | 282 | strncpy(g_config.payout.mints[0].url, g_config.mint_url, |
| 277 | sizeof(g_config.payout.mints[0].url) - 1); | 283 | sizeof(g_config.payout.mints[0].url) - 1); |
| @@ -319,7 +325,13 @@ esp_err_t tollgate_config_get_wifi(wifi_config_t *wifi_config) | |||
| 319 | memset(wifi_config, 0, sizeof(wifi_config_t)); | 325 | memset(wifi_config, 0, sizeof(wifi_config_t)); |
| 320 | strncpy((char *)wifi_config->sta.ssid, g_config.networks[idx].ssid, sizeof(wifi_config->sta.ssid) - 1); | 326 | strncpy((char *)wifi_config->sta.ssid, g_config.networks[idx].ssid, sizeof(wifi_config->sta.ssid) - 1); |
| 321 | strncpy((char *)wifi_config->sta.password, g_config.networks[idx].password, sizeof(wifi_config->sta.password) - 1); | 327 | strncpy((char *)wifi_config->sta.password, g_config.networks[idx].password, sizeof(wifi_config->sta.password) - 1); |
| 322 | wifi_config->sta.threshold.authmode = WIFI_AUTH_WPA3_PSK; | 328 | wifi_config->sta.threshold.authmode = WIFI_AUTH_WPA2_PSK; |
| 329 | if (strstr(g_config.wifi_auth_mode, "WPA3")) { | ||
| 330 | wifi_config->sta.threshold.authmode = WIFI_AUTH_WPA3_PSK; | ||
| 331 | } else if (strstr(g_config.wifi_auth_mode, "WPA2")) { | ||
| 332 | wifi_config->sta.threshold.authmode = WIFI_AUTH_WPA2_PSK; | ||
| 333 | } | ||
| 334 | ESP_LOGI(TAG, "STA auth threshold: %s → %d", g_config.wifi_auth_mode, wifi_config->sta.threshold.authmode); | ||
| 323 | return ESP_OK; | 335 | return ESP_OK; |
| 324 | } | 336 | } |
| 325 | 337 | ||
diff --git a/main/config.h b/main/config.h index 8e12878..1a32cc2 100644 --- a/main/config.h +++ b/main/config.h | |||
| @@ -65,6 +65,8 @@ typedef struct { | |||
| 65 | 65 | ||
| 66 | bool cvm_enabled; | 66 | bool cvm_enabled; |
| 67 | char cvm_relays[256]; | 67 | char cvm_relays[256]; |
| 68 | |||
| 69 | char wifi_auth_mode[16]; | ||
| 68 | } tollgate_config_t; | 70 | } tollgate_config_t; |
| 69 | 71 | ||
| 70 | void tollgate_config_derive_unique(tollgate_config_t *cfg); | 72 | void tollgate_config_derive_unique(tollgate_config_t *cfg); |
diff --git a/main/mint_health.c b/main/mint_health.c index 39b0e8e..5853a39 100644 --- a/main/mint_health.c +++ b/main/mint_health.c | |||
| @@ -155,7 +155,8 @@ static void run_initial_probes(void) | |||
| 155 | 155 | ||
| 156 | static void health_task(void *pvParameters) | 156 | static void health_task(void *pvParameters) |
| 157 | { | 157 | { |
| 158 | ESP_LOGI(TAG, "Health probe task started"); | 158 | ESP_LOGI(TAG, "Health probe task started, waiting for DNS to stabilize..."); |
| 159 | vTaskDelay(pdMS_TO_TICKS(5000)); | ||
| 159 | run_initial_probes(); | 160 | run_initial_probes(); |
| 160 | 161 | ||
| 161 | while (s_running) { | 162 | while (s_running) { |
diff --git a/main/mint_health.h b/main/mint_health.h index f047d6a..4e9a5a7 100644 --- a/main/mint_health.h +++ b/main/mint_health.h | |||
| @@ -6,7 +6,7 @@ | |||
| 6 | #include <stdbool.h> | 6 | #include <stdbool.h> |
| 7 | 7 | ||
| 8 | #define MINT_HEALTH_MAX 8 | 8 | #define MINT_HEALTH_MAX 8 |
| 9 | #define MINT_HEALTH_PROBE_INTERVAL_S 300 | 9 | #define MINT_HEALTH_PROBE_INTERVAL_S 30 |
| 10 | #define MINT_HEALTH_PROBE_TIMEOUT_MS 15000 | 10 | #define MINT_HEALTH_PROBE_TIMEOUT_MS 15000 |
| 11 | #define MINT_HEALTH_RECOVERY_THRESHOLD 3 | 11 | #define MINT_HEALTH_RECOVERY_THRESHOLD 3 |
| 12 | 12 | ||
diff --git a/main/tollgate_main.c b/main/tollgate_main.c index a39ccc9..228d8ef 100644 --- a/main/tollgate_main.c +++ b/main/tollgate_main.c | |||
| @@ -84,6 +84,7 @@ static void wifi_event_handler(void *arg, esp_event_base_t event_base, | |||
| 84 | 84 | ||
| 85 | static void services_start_task(void *pvParameters) | 85 | static void services_start_task(void *pvParameters) |
| 86 | { | 86 | { |
| 87 | vTaskDelay(pdMS_TO_TICKS(3000)); | ||
| 87 | start_services(); | 88 | start_services(); |
| 88 | vTaskDelete(NULL); | 89 | vTaskDelete(NULL); |
| 89 | } | 90 | } |