From 2b6de3424da2705a02cedb216d40e159c749da48 Mon Sep 17 00:00:00 2001 From: Bob Date: Thu, 11 Dec 2025 17:00:32 -0800 Subject: [PATCH] more on build --- components/wifi_cfg/wifi_cfg.c | 176 ++++++++++++++++++++++----------- esp32_deploy.py | 6 +- 2 files changed, 122 insertions(+), 60 deletions(-) diff --git a/components/wifi_cfg/wifi_cfg.c b/components/wifi_cfg/wifi_cfg.c index a719f5e..8c79e53 100644 --- a/components/wifi_cfg/wifi_cfg.c +++ b/components/wifi_cfg/wifi_cfg.c @@ -14,26 +14,28 @@ #include "esp_check.h" #include "wifi_cfg.h" -#include "cmd_transport.h" // Now uses the transport component +#include "cmd_transport.h" -// GUARDED INCLUDE #ifdef CONFIG_ESP_WIFI_CSI_ENABLED -#include "csi_manager.h" // For CSI enable/disable +#include "csi_manager.h" #endif static const char *TAG = "wifi_cfg"; static esp_netif_t *sta_netif = NULL; static bool cfg_dhcp = true; -// --- Helper Functions (Preserved) --- - +// --- NVS Helper --- static esp_err_t nvs_set_str2(nvs_handle_t h, const char *key, const char *val){ return val ? nvs_set_str(h, key, val) : nvs_erase_key(h, key); } -static void save_cfg(const char* ssid, const char* pass, const char* ip, const char* mask, const char* gw, bool dhcp, const char* band, const char* bw, const char* powersave, const char* mode, uint8_t mon_ch){ +// --- NVS Save Functions --- + +// 1. Save Network Settings (Namespace: "netcfg") +static void save_net_cfg(const char* ssid, const char* pass, const char* ip, const char* mask, const char* gw, bool dhcp, const char* band, const char* bw, const char* powersave, const char* mode, uint8_t mon_ch){ nvs_handle_t h; if (nvs_open("netcfg", NVS_READWRITE, &h) != ESP_OK) return; + if (ssid) nvs_set_str2(h, "ssid", ssid); if (pass) nvs_set_str2(h, "pass", pass); if (ip) nvs_set_str2(h, "ip", ip); @@ -45,12 +47,35 @@ static void save_cfg(const char* ssid, const char* pass, const char* ip, const c if (mode) nvs_set_str2(h, "mode", mode); nvs_set_u8(h, "mon_ch", mon_ch); nvs_set_u8(h, "dhcp", dhcp ? 1 : 0); + nvs_commit(h); nvs_close(h); cfg_dhcp = dhcp; - ESP_LOGI(TAG, "Config saved to NVS: SSID=%s Mode=%s MonCh=%d", ssid?ssid:"", mode?mode:"STA", mon_ch); + ESP_LOGI(TAG, "Net Config Saved: SSID=%s IP=%s DHCP=%d", ssid?ssid:"", ip?ip:"", dhcp); } +// 2. Save Iperf Settings (Namespace: "storage") -> Matches iperf.c keys +static void save_iperf_cfg(const char* dst_ip, const char* role, const char* proto, uint32_t period, uint32_t burst, uint32_t len, uint32_t port, bool enable){ + nvs_handle_t h; + if (nvs_open("storage", NVS_READWRITE, &h) != ESP_OK) return; + + // Note: Keys must match what iperf.c reads (NVS_KEY_IPERF_DST_IP etc) + if (dst_ip && dst_ip[0]) nvs_set_str(h, "iperf_dst_ip", dst_ip); + if (role && role[0]) nvs_set_str(h, "iperf_role", role); + if (proto && proto[0]) nvs_set_str(h, "iperf_proto", proto); + + nvs_set_u32(h, "iperf_period", period); + nvs_set_u32(h, "iperf_burst", burst); + nvs_set_u32(h, "iperf_len", len); + nvs_set_u32(h, "iperf_port", port); + nvs_set_u8(h, "iperf_enabled", enable ? 1 : 0); + + nvs_commit(h); + nvs_close(h); + ESP_LOGI(TAG, "Iperf Config Saved: Target=%s Role=%s Period=%lu", dst_ip?dst_ip:"", role?role:"", (unsigned long)period); +} + +// --- Load Logic (Network Only - Iperf loads itself) --- static bool load_cfg(char* ssid, size_t ssz, char* pass, size_t psz, char* ip, size_t isz, char* mask, size_t msz, char* gw, size_t gsz, char* band, size_t bsz, char* bw, size_t bwsz, char* powersave, size_t pssz, @@ -163,7 +188,6 @@ bool wifi_cfg_apply_from_nvs(void) { esp_wifi_set_mode(WIFI_MODE_STA); - // Protocol selection #if CONFIG_IDF_TARGET_ESP32C5 || CONFIG_IDF_TARGET_ESP32C6 wifi_protocols_t protocols = { .ghz_2g = WIFI_PROTOCOL_11B | WIFI_PROTOCOL_11G | WIFI_PROTOCOL_11N, @@ -179,7 +203,6 @@ bool wifi_cfg_apply_from_nvs(void) { if (!dhcp && ip[0]) apply_ip_static(ip, mask, gw); else if (sta_netif) esp_netif_dhcpc_start(sta_netif); - // Bandwidth selection #if CONFIG_IDF_TARGET_ESP32C5 || CONFIG_IDF_TARGET_ESP32C6 wifi_bandwidths_t bandwidths = {.ghz_2g = WIFI_BW_HT20, .ghz_5g = WIFI_BW_HT20}; if (strcmp(bw, "VHT80") == 0) { bandwidths.ghz_2g = WIFI_BW_HT40; bandwidths.ghz_5g = WIFI_BW80; } @@ -193,7 +216,6 @@ bool wifi_cfg_apply_from_nvs(void) { esp_wifi_start(); - // Power Save wifi_ps_type_t ps_mode = WIFI_PS_NONE; if (strcmp(powersave, "MIN") == 0) ps_mode = WIFI_PS_MIN_MODEM; else if (strcmp(powersave, "MAX") == 0) ps_mode = WIFI_PS_MAX_MODEM; @@ -203,86 +225,126 @@ bool wifi_cfg_apply_from_nvs(void) { return true; } -// --- Command Listener Logic --- +// --- Parsing State --- +typedef struct { + // Network + char ssid[64]; + char pass[64]; + char ip[32]; + char mask[32]; + char gw[32]; + char band[16]; + char bw[16]; + char powersave[16]; + char mode[16]; + uint8_t mon_ch; + bool dhcp; + bool csi_enable; -static void on_cfg_line(const char *line, char *ssid, char *pass, char *ip, char *mask, char *gw, char *band, char *bw, char *powersave, char *mode, uint8_t *mon_ch, bool *dhcp, bool *csi_enable){ - if (strncmp(line, "SSID:",5)==0){ strncpy(ssid, line+5, 63); ssid[63]=0; return; } - if (strncmp(line, "PASS:",5)==0){ strncpy(pass, line+5, 63); pass[63]=0; return; } - if (strncmp(line, "IP:",3)==0){ strncpy(ip, line+3, 31); ip[31]=0; return; } - if (strncmp(line, "MASK:",5)==0){ strncpy(mask, line+5, 31); mask[31]=0; return; } - if (strncmp(line, "GW:",3)==0){ strncpy(gw, line+3, 31); gw[31]=0; return; } - if (strncmp(line, "BAND:",5)==0){ strncpy(band, line+5, 15); band[15]=0; return; } - if (strncmp(line, "BW:",3)==0){ strncpy(bw, line+3, 15); bw[15]=0; return; } - if (strncmp(line, "POWERSAVE:",10)==0){ strncpy(powersave, line+10, 15); powersave[15]=0; return; } - if (strncmp(line, "MODE:",5)==0){ strncpy(mode, line+5, 15); mode[15]=0; return; } - if (strncmp(line, "MON_CH:",7)==0){ *mon_ch = atoi(line+7); return; } - if (strncmp(line, "DHCP:",5)==0){ *dhcp = atoi(line+5) ? true:false; return; } + // Iperf + char iperf_dest[32]; + char iperf_role[16]; + char iperf_proto[8]; + uint32_t iperf_period_us; + uint32_t iperf_burst; + uint32_t iperf_len; + uint32_t iperf_port; + bool iperf_enable; +} cfg_state_t; + +static void on_cfg_line(const char *line, cfg_state_t *s){ + // Network Parsing + if (strncmp(line, "SSID:",5)==0){ strncpy(s->ssid, line+5, 63); s->ssid[63]=0; return; } + if (strncmp(line, "PASS:",5)==0){ strncpy(s->pass, line+5, 63); s->pass[63]=0; return; } + if (strncmp(line, "IP:",3)==0){ strncpy(s->ip, line+3, 31); s->ip[31]=0; return; } + if (strncmp(line, "MASK:",5)==0){ strncpy(s->mask, line+5, 31); s->mask[31]=0; return; } + if (strncmp(line, "GW:",3)==0){ strncpy(s->gw, line+3, 31); s->gw[31]=0; return; } + if (strncmp(line, "BAND:",5)==0){ strncpy(s->band, line+5, 15); s->band[15]=0; return; } + if (strncmp(line, "BW:",3)==0){ strncpy(s->bw, line+3, 15); s->bw[15]=0; return; } + if (strncmp(line, "POWERSAVE:",10)==0){ strncpy(s->powersave, line+10, 15); s->powersave[15]=0; return; } + if (strncmp(line, "MODE:",5)==0){ strncpy(s->mode, line+5, 15); s->mode[15]=0; return; } + if (strncmp(line, "MON_CH:",7)==0){ s->mon_ch = atoi(line+7); return; } + if (strncmp(line, "DHCP:",5)==0){ s->dhcp = atoi(line+5) ? true:false; return; } + + // Iperf Parsing (Matches Python Script Keys) + // Support both DEST and DST to be safe + if (strncmp(line, "IPERF_DEST_IP:", 14) == 0) { strncpy(s->iperf_dest, line+14, 31); s->iperf_dest[31]=0; return; } + if (strncmp(line, "IPERF_DST_IP:", 13) == 0) { strncpy(s->iperf_dest, line+13, 31); s->iperf_dest[31]=0; return; } + + if (strncmp(line, "IPERF_ROLE:", 11) == 0) { strncpy(s->iperf_role, line+11, 15); s->iperf_role[15]=0; return; } + if (strncmp(line, "IPERF_PROTO:", 12) == 0) { strncpy(s->iperf_proto, line+12, 7); s->iperf_proto[7]=0; return; } + + if (strncmp(line, "IPERF_PERIOD_US:", 16) == 0) { s->iperf_period_us = atoi(line+16); return; } + if (strncmp(line, "IPERF_BURST:", 12) == 0) { s->iperf_burst = atoi(line+12); return; } + if (strncmp(line, "IPERF_LEN:", 10) == 0) { s->iperf_len = atoi(line+10); return; } + if (strncmp(line, "IPERF_PORT:", 11) == 0) { s->iperf_port = atoi(line+11); return; } + if (strncmp(line, "IPERF_ENABLED:", 14) == 0) { s->iperf_enable = atoi(line+14) ? true:false; return; } -// GUARDED CSI PARSING #ifdef CONFIG_ESP_WIFI_CSI_ENABLED - if (strncmp(line, "CSI:",4)==0){ *csi_enable = atoi(line+4) ? true:false; return; } + if (strncmp(line, "CSI:",4)==0){ s->csi_enable = atoi(line+4) ? true:false; return; } #endif } static bool wifi_cfg_cmd_handler(const char *line, cmd_reply_func_t reply_func, void *reply_ctx) { static bool in_cfg = false; - static char ssid[64]={0}, pass[64]={0}, ip[32]={0}, mask[32]={0}, gw[32]={0}; - static char band[16]={0}, bw[16]={0}, powersave[16]={0}, mode[16]={0}; - static uint8_t mon_ch = 36; - static bool dhcp = true; - static bool csi_enable = false; + static cfg_state_t s; if (!in_cfg) { if (strcmp(line, "CFG") == 0) { in_cfg = true; - // Reset buffers - ssid[0]=0; pass[0]=0; ip[0]=0; mask[0]=0; gw[0]=0; - band[0]=0; bw[0]=0; powersave[0]=0; mode[0]=0; - mon_ch = 36; dhcp = true; csi_enable = false; - return true; // Handled + // Clear all buffers + memset(&s, 0, sizeof(s)); + // Set Defaults + s.mon_ch = 36; + s.dhcp = true; + s.csi_enable = false; + s.iperf_period_us = 10000; + s.iperf_burst = 1; + s.iperf_len = 1470; + s.iperf_port = 5001; + s.iperf_enable = true; + strcpy(s.iperf_dest, "192.168.1.50"); + strcpy(s.iperf_role, "CLIENT"); + strcpy(s.iperf_proto, "UDP"); + return true; } - return false; // Not handled + return false; } - // Inside CFG block if (strcmp(line, "END") == 0) { - // Apply Defaults - if (!band[0]) strcpy(band, "2.4G"); - if (!bw[0]) strcpy(bw, "HT20"); - if (!powersave[0]) strcpy(powersave, "NONE"); - if (!mode[0]) strcpy(mode, "STA"); + // Apply Network Defaults if missing + if (!s.band[0]) strcpy(s.band, "2.4G"); + if (!s.bw[0]) strcpy(s.bw, "HT20"); + if (!s.powersave[0]) strcpy(s.powersave, "NONE"); + if (!s.mode[0]) strcpy(s.mode, "STA"); - save_cfg(ssid, pass, ip, mask, gw, dhcp, band, bw, powersave, mode, mon_ch); + // 1. Save Network + save_net_cfg(s.ssid, s.pass, s.ip, s.mask, s.gw, s.dhcp, s.band, s.bw, s.powersave, s.mode, s.mon_ch); -// GUARDED SAVE LOGIC + // 2. Save Iperf + save_iperf_cfg(s.iperf_dest, s.iperf_role, s.iperf_proto, s.iperf_period_us, s.iperf_burst, s.iperf_len, s.iperf_port, s.iperf_enable); + + // 3. Save CSI #ifdef CONFIG_ESP_WIFI_CSI_ENABLED - // Save CSI enable state - esp_err_t err = csi_mgr_save_enable_state(csi_enable); - if (err == ESP_OK) { - printf("CSI enable state saved: %s\n", csi_enable ? "ENABLED" : "DISABLED"); - } else { - printf("Failed to save CSI state: %s\n", esp_err_to_name(err)); - } + csi_mgr_save_enable_state(s.csi_enable); #endif - if (reply_func) reply_func("OK\n", reply_ctx); + if (reply_func) reply_func("Config saved. Reconnecting...\n", reply_ctx); + + // Apply changes immediately wifi_cfg_apply_from_nvs(); in_cfg = false; return true; } - on_cfg_line(line, ssid, pass, ip, mask, gw, band, bw, powersave, mode, &mon_ch, &dhcp, &csi_enable); + on_cfg_line(line, &s); return true; } void wifi_cfg_init(void){ nvs_flash_init(); - - // Init the shared transport (starts UART/USB tasks) cmd_transport_init(); - - // Register our callback to catch "CFG" blocks cmd_transport_register_listener(wifi_cfg_cmd_handler); } diff --git a/esp32_deploy.py b/esp32_deploy.py index f30d772..5f25887 100755 --- a/esp32_deploy.py +++ b/esp32_deploy.py @@ -330,7 +330,7 @@ class UnifiedDeployWorker: f"IPERF_PERIOD_US:{period_us}", f"IPERF_ROLE:{role_str}", f"IPERF_PROTO:{self.args.iperf_proto}", - f"IPERF_DEST_IP:{self.args.iperf_dest_ip}", + f"IPERF_DST_IP:{self.args.iperf_dest_ip}", f"IPERF_PORT:{self.args.iperf_port}", f"IPERF_BURST:{self.args.iperf_burst}", f"IPERF_LEN:{self.args.iperf_len}", @@ -338,13 +338,13 @@ class UnifiedDeployWorker: "END" ] - # CHANGED: Send line-by-line with a small delay to prevent UART FIFO overflow + # CHANGED: Send line-by-line with a delay to prevent UART FIFO overflow for line in config_lines: cmd = line + "\r\n" writer.write(cmd.encode('utf-8')) await writer.drain() # 50ms delay allows the ESP32 (running at 115200 baud) to process the line - await asyncio.sleep(0.05) + await asyncio.sleep(0.1) async def _verify_configuration(self, reader): timeout = time.time() + 15