#include #include #include #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "esp_log.h" #include "nvs_flash.h" #include "nvs.h" #include "esp_netif.h" #include "esp_wifi.h" #include "esp_event.h" #include "wifi_cfg.h" // Removed unused TAG static esp_netif_t *sta_netif = NULL; // --- Helper: NVS Write --- static void nvs_write_str(const char *key, const char *val) { nvs_handle_t h; if (nvs_open("netcfg", NVS_READWRITE, &h) == ESP_OK) { if (val) nvs_set_str(h, key, val); else nvs_erase_key(h, key); nvs_commit(h); nvs_close(h); } } static void nvs_write_u8(const char *key, uint8_t val) { nvs_handle_t h; if (nvs_open("netcfg", NVS_READWRITE, &h) == ESP_OK) { nvs_set_u8(h, key, val); nvs_commit(h); nvs_close(h); } } // --- Public Setters --- void wifi_cfg_set_credentials(const char* ssid, const char* pass) { nvs_write_str("ssid", ssid); nvs_write_str("pass", pass); } void wifi_cfg_set_static_ip(const char* ip, const char* mask, const char* gw) { nvs_write_str("ip", ip); nvs_write_str("mask", mask); nvs_write_str("gw", gw); } void wifi_cfg_set_dhcp(bool enable) { nvs_write_u8("dhcp", enable ? 1 : 0); } // --- Init & Load --- void wifi_cfg_init(void) { nvs_flash_init(); } 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, char* mode, size_t modesz, uint8_t* mon_ch, bool* dhcp){ nvs_handle_t h; if (nvs_open("netcfg", NVS_READONLY, &h) != ESP_OK) return false; size_t len; // Load SSID (Mandatory) len = ssz; if (nvs_get_str(h, "ssid", ssid, &len) != ESP_OK) { nvs_close(h); return false; } // Load Optionals len = psz; if (nvs_get_str(h, "pass", pass, &len) != ESP_OK) pass[0]=0; len = isz; if (nvs_get_str(h, "ip", ip, &len) != ESP_OK) ip[0]=0; len = msz; if (nvs_get_str(h, "mask", mask, &len) != ESP_OK) mask[0]=0; len = gsz; if (nvs_get_str(h, "gw", gw, &len) != ESP_OK) gw[0]=0; // Defaults len = bsz; if (nvs_get_str(h, "band", band, &len) != ESP_OK) strcpy(band, "2.4G"); len = bwsz; if (nvs_get_str(h, "bw", bw, &len) != ESP_OK) strcpy(bw, "HT20"); len = pssz; if (nvs_get_str(h, "powersave", powersave, &len) != ESP_OK) strcpy(powersave, "NONE"); len = modesz; if (nvs_get_str(h, "mode", mode, &len) != ESP_OK) strcpy(mode, "STA"); uint8_t ch=36; nvs_get_u8(h, "mon_ch", &ch); *mon_ch = ch; uint8_t d=1; nvs_get_u8(h, "dhcp", &d); *dhcp = (d!=0); nvs_close(h); return true; } static void apply_ip_static(const char* ip, const char* mask, const char* gw){ if (!sta_netif) return; if (!ip || !ip[0]) return; esp_netif_ip_info_t info = {0}; esp_netif_dhcpc_stop(sta_netif); info.ip.addr = esp_ip4addr_aton(ip); info.netmask.addr = (mask && mask[0]) ? esp_ip4addr_aton(mask) : esp_ip4addr_aton("255.255.255.0"); info.gw.addr = (gw && gw[0]) ? esp_ip4addr_aton(gw) : 0; esp_netif_set_ip_info(sta_netif, &info); } bool wifi_cfg_apply_from_nvs(void) { char ssid[64]={0}, pass[64]={0}, ip[32]={0}, mask[32]={0}, gw[32]={0}; char band[16]={0}, bw[16]={0}, powersave[16]={0}, mode[16]={0}; uint8_t mon_ch = 36; bool dhcp = true; if (!load_cfg(ssid,sizeof(ssid), pass,sizeof(pass), ip,sizeof(ip), mask,sizeof(mask), gw,sizeof(gw), band,sizeof(band), bw,sizeof(bw), powersave,sizeof(powersave), mode,sizeof(mode), &mon_ch, &dhcp)){ return false; } if (sta_netif == NULL) sta_netif = esp_netif_create_default_wifi_sta(); wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); esp_wifi_init(&cfg); wifi_config_t wcfg = {0}; strlcpy((char*)wcfg.sta.ssid, ssid, sizeof(wcfg.sta.ssid)); strlcpy((char*)wcfg.sta.password, pass, sizeof(wcfg.sta.password)); wcfg.sta.threshold.authmode = WIFI_AUTH_WPA2_PSK; wcfg.sta.sae_pwe_h2e = WPA3_SAE_PWE_BOTH; wcfg.sta.scan_method = WIFI_ALL_CHANNEL_SCAN; esp_wifi_set_mode(WIFI_MODE_STA); esp_wifi_set_config(WIFI_IF_STA, &wcfg); if (!dhcp && ip[0]) apply_ip_static(ip, mask, gw); else esp_netif_dhcpc_start(sta_netif); esp_wifi_start(); esp_wifi_connect(); return true; } wifi_ps_type_t wifi_cfg_get_power_save_mode(void) { return WIFI_PS_NONE; } bool wifi_cfg_get_bandwidth(char *buf, size_t buf_size) { if (buf) strncpy(buf, "HT20", buf_size); return true; } bool wifi_cfg_get_mode(char *mode, uint8_t *mon_ch) { nvs_handle_t h; if (nvs_open("netcfg", NVS_READONLY, &h) != ESP_OK) return false; size_t len = 16; if (nvs_get_str(h, "mode", mode, &len) != ESP_OK) strcpy(mode, "STA"); nvs_get_u8(h, "mon_ch", mon_ch); nvs_close(h); return true; } // --- State Checkers --- bool wifi_cfg_monitor_channel_is_unsaved(uint8_t ram_value) { nvs_handle_t h; if (nvs_open("netcfg", NVS_READONLY, &h) != ESP_OK) return true; // Assume dirty if error uint8_t nvs_val = 0; esp_err_t err = nvs_get_u8(h, "mon_ch", &nvs_val); nvs_close(h); if (err != ESP_OK) return true; // Key missing = dirty (using default) return (nvs_val != ram_value); } // --- Setters --- bool wifi_cfg_set_monitor_channel(uint8_t channel) { nvs_handle_t h; if (nvs_open("netcfg", NVS_READWRITE, &h) != ESP_OK) return false; uint8_t current = 0; // Check if write is necessary if (nvs_get_u8(h, "mon_ch", ¤t) == ESP_OK) { if (current == channel) { nvs_close(h); return false; // No change needed } } nvs_set_u8(h, "mon_ch", channel); nvs_commit(h); nvs_close(h); return true; // Write occurred }