#include "sys_wifi.h" #include "web_server.h" #include "os_event.h" #include "os_status.h" #include "sdkconfig.h" #include "esp_event.h" #include "esp_log.h" #include "esp_netif.h" #include "esp_wifi.h" #include "nvs.h" #include "nvs_flash.h" #include #include static const char *TAG = "SYS_WIFI"; static esp_netif_t *s_sta_netif; static esp_netif_t *s_ap_netif; static char s_sta_ssid[33]; static char s_sta_password[65]; static void copy_wifi_string(uint8_t *destination, size_t destination_size, const char *source) { size_t length = strlen(source); if (length >= destination_size) length = destination_size - 1; memcpy(destination, source, length); destination[length] = '\0'; } static void set_status(wifi_state_t state, int8_t rssi) { sys_status_set_wifi(state, rssi); sys_event_post(SYS_EVENT_WIFI_STATUS_CHANGED, (int32_t)state, NULL); } static esp_err_t load_credentials(void) { nvs_handle_t nvs; size_t ssid_len = sizeof(s_sta_ssid); size_t password_len = sizeof(s_sta_password); esp_err_t err = nvs_open("wifi", NVS_READONLY, &nvs); if (err != ESP_OK) return err; err = nvs_get_str(nvs, "ssid", s_sta_ssid, &ssid_len); if (err == ESP_OK) err = nvs_get_str(nvs, "password", s_sta_password, &password_len); nvs_close(nvs); return err; } static void start_softap(void) { wifi_config_t ap_config = {0}; copy_wifi_string(ap_config.ap.ssid, sizeof(ap_config.ap.ssid), CONFIG_SYS_WIFI_AP_SSID); copy_wifi_string(ap_config.ap.password, sizeof(ap_config.ap.password), CONFIG_SYS_WIFI_AP_PASSWORD); ap_config.ap.authmode = WIFI_AUTH_WPA2_PSK; ap_config.ap.max_connection = 2; esp_wifi_set_mode(WIFI_MODE_APSTA); esp_wifi_set_config(WIFI_IF_AP, &ap_config); esp_wifi_start(); set_status(WIFI_STATE_AP_MODE, 0); web_server_start(); ESP_LOGI(TAG, "Provisioning AP '%s', browse to http://192.168.4.1", CONFIG_SYS_WIFI_AP_SSID); } static void start_station(void) { wifi_config_t config = {0}; copy_wifi_string(config.sta.ssid, sizeof(config.sta.ssid), s_sta_ssid); copy_wifi_string(config.sta.password, sizeof(config.sta.password), s_sta_password); esp_wifi_set_mode(WIFI_MODE_STA); esp_wifi_set_config(WIFI_IF_STA, &config); esp_wifi_start(); set_status(WIFI_STATE_CONNECTING, 0); esp_wifi_connect(); ESP_LOGI(TAG, "Connecting to Wi-Fi network '%s'", s_sta_ssid); } static void wifi_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data) { if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) { set_status(WIFI_STATE_CONNECTING, 0); esp_wifi_connect(); } else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) { wifi_ap_record_t record; int8_t rssi = 0; if (esp_wifi_sta_get_ap_info(&record) == ESP_OK) rssi = record.rssi; set_status(WIFI_STATE_CONNECTED, rssi); web_server_start(); const ip_event_got_ip_t *got_ip = (const ip_event_got_ip_t *)event_data; ESP_LOGI(TAG, "Wi-Fi connected, web server at http://" IPSTR, IP2STR(&got_ip->ip_info.ip)); } } esp_err_t sys_wifi_clear_credentials(void) { nvs_handle_t nvs; esp_err_t err = nvs_open("wifi", NVS_READWRITE, &nvs); if (err != ESP_OK) return err; err = nvs_erase_all(nvs); if (err == ESP_OK) err = nvs_commit(nvs); nvs_close(nvs); return err; } esp_err_t sys_wifi_init(void) { #if !CONFIG_SYS_WIFI_ENABLED set_status(WIFI_STATE_OFF, 0); return ESP_OK; #else esp_err_t err = nvs_flash_init(); if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) { ESP_ERROR_CHECK(nvs_flash_erase()); err = nvs_flash_init(); } if (err != ESP_OK) return err; err = esp_netif_init(); if (err != ESP_OK && err != ESP_ERR_INVALID_STATE) return err; err = esp_event_loop_create_default(); if (err != ESP_OK && err != ESP_ERR_INVALID_STATE) return err; s_sta_netif = esp_netif_create_default_wifi_sta(); s_ap_netif = esp_netif_create_default_wifi_ap(); if (!s_sta_netif || !s_ap_netif) return ESP_ERR_NO_MEM; wifi_init_config_t wifi_config = WIFI_INIT_CONFIG_DEFAULT(); err = esp_wifi_init(&wifi_config); if (err != ESP_OK) return err; ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &wifi_event_handler, NULL)); ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &wifi_event_handler, NULL)); if (load_credentials() == ESP_OK && s_sta_ssid[0] != '\0' && s_sta_password[0] != '\0') { start_station(); } else { start_softap(); } return ESP_OK; #endif }