WiFi SoftAP clients lose connection when ESP32S3 scans WiFi
Posted: Thu Jan 15, 2026 12:35 pm
Hello everyone!
I'm struggling with WiFi softAP connectivity stability. When ESP32S3 scans WiFi networks, softAP clients may lose connection to ESP32S3. It interrupts the device configuration.
The configuration is performed with HTTP server on ESP32S3.
First, I tried to scan WiFi networks on ESP32S3 in HTTP request handler. The answer may not delivered to client.
Second, I tried to scan WiFi networks periodically, then HTTP request handler just gets the last scan results.
It there the way to beat this problem?
wifi_management.c:
I'm struggling with WiFi softAP connectivity stability. When ESP32S3 scans WiFi networks, softAP clients may lose connection to ESP32S3. It interrupts the device configuration.
The configuration is performed with HTTP server on ESP32S3.
First, I tried to scan WiFi networks on ESP32S3 in HTTP request handler. The answer may not delivered to client.
Second, I tried to scan WiFi networks periodically, then HTTP request handler just gets the last scan results.
It there the way to beat this problem?
wifi_management.c:
Code: Select all
#include "wifi_management.h"
#include "wifi_management_defs.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
#include "esp_system.h"
#include "esp_event.h"
#include "esp_log.h"
#include "nvs_flash.h"
#include "esp_timer.h"
#include "lwip/err.h"
#include "lwip/sys.h"
#include "esp_check.h"
#include "esp_wifi.h"
#include <math.h>
#include "common_utils.h"
#include <math.h>
#define WIFI_MANAGEMENT_TAG "WifiManagement"
/* FreeRTOS event group to signal when we are connected*/
static EventGroupHandle_t s_wifi_event_group;
static wifi_config_t wifi_config;
static wifi_config_t wifi_config_ap;
esp_netif_t *sta_netif;
esp_netif_t* wifiAP;
static int s_retry_num = 0;
static uint8_t wifi_setup = 0;
static uint64_t traffic_received = 0;
static uint64_t traffic_transmitted = 0;
// 64 symbols+ending zero
static char esp_wifi_ssid[65];
static char esp_wifi_pass[65];
static char ap_wifi_ssid[65];
static char ap_wifi_pass[65];
uint8_t strongest_bssid[6];
// bool find_channel_is_working = false;
static wifi_management_ip_got_t _ip_info;
static esp_timer_handle_t wifi_scan_timer;
esp_event_handler_instance_t instance_any_id;
esp_event_handler_instance_t instance_got_ip;
esp_event_handler_instance_t instance_lost_ip;
esp_event_handler_instance_t instance_got_ip6;
esp_event_handler_instance_t instance_rxtx;
// esp_event_handler_instance_t instance_smart_connect;
void (*onWiFiconnect)() = NULL;
void (*onWiFidisconnect)() = NULL;
void (*onWiFiLostIP)() = NULL;
void (*onIPv6Got)() = NULL;
void (*onWiFiAPstaconnect)() = NULL;
void (*onWiFiAPstadisconnect)() = NULL;
void (*onWiFiScanStarted)() = NULL;
void (*onWiFiScanEnded)() = NULL;
int ap_connected_devices = 0;
int last_wifi_rssi = -127;
bool ap_state = false;
static bool force_reconnect = false;
static bool manual_disconnect = false;
static bool wifi_scan_finished = false;
static bool wifi_scan_in_progress = false;
static esp_timer_handle_t reconnect_timer;
static wifi_management_sta_scan_result_t wifi_scan_result;
// static EventGroupHandle_t wifi_scan_done_event_group;
// const int WIFI_SCAN_DONE_BIT = BIT0;
int get_current_sta_rssi();
void cleanup_wifi_sta_config();
void wifi_management_show_logs() {
esp_log_level_t log_level = ESP_LOG_VERBOSE;
esp_log_level_set(WIFI_MANAGEMENT_TAG, log_level);
esp_log_level_set("wifi", log_level);
esp_log_level_set("esp_netif_handlers", log_level);
esp_log_level_set("esp_netif_lwip", log_level);
}
void wifi_management_hide_logs() {
esp_log_level_t log_level = ESP_LOG_NONE;
esp_log_level_set(WIFI_MANAGEMENT_TAG, log_level);
esp_log_level_set("wifi", log_level);
esp_log_level_set("esp_netif_handlers", log_level);
esp_log_level_set("esp_netif_lwip", log_level);
}
void set_on_wifi_connect_cb(void (*event)()) {
onWiFiconnect = event;
}
void set_on_wifi_disconnect_cb(void (*event)()) {
onWiFidisconnect = event;
}
void set_on_wifi_lost_ip_cb(void (*event)()) {
onWiFiLostIP = event;
}
void set_on_wifiap_sta_got_ipv6_cb(void (*event)()) {
onIPv6Got = event;
}
void set_on_wifiap_sta_connect_cb(void (*event)()) {
onWiFiAPstaconnect = event;
}
void set_on_wifiap_sta_disconnect_cb(void (*event)()) {
onWiFiAPstadisconnect = event;
}
void set_on_wifi_scan_started_cb(void (*cb)()) {
onWiFiScanStarted = cb;
}
void set_on_wifi_scan_ended_cb(void (*cb)()) {
onWiFiScanEnded = cb;
}
void wifi_set_traffic_received(uint64_t cnt) {
traffic_received = cnt;
}
void wifi_set_traffic_transmitted(uint64_t cnt) {
traffic_transmitted = cnt;
}
uint64_t wifi_get_traffic_received() {
return traffic_received;
}
uint64_t wifi_get_traffic_transmitted() {
return traffic_transmitted;
}
bool wifi_management_is_sta_set() {
return (strlen(esp_wifi_ssid) > 0);
}
void wifi_management_defer_reconnect() {
if (esp_timer_is_active(reconnect_timer)) {
ESP_LOGW(WIFI_MANAGEMENT_TAG, "WiFi reconnection awaiting and deferring requested");
esp_timer_restart(reconnect_timer, WIFI_RECONNECT_BACKOFF_US);
}
}
const char * wifi_ip_type_to_str(wifi_management_ip_type_t ip_type) {
switch(ip_type) {
case IP_TYPE_NONE:
return "IP_TYPE_NONE";
case IP_TYPE_IPV4:
return "IP_TYPE_IPV4";
case IP_TYPE_IPV6:
return "IP_TYPE_IPV6";
default:
return "IP_TYPE_UNKNOWN";
}
}
static void print_auth_mode(int authmode)
{
switch (authmode) {
case WIFI_AUTH_OPEN:
ESP_LOGI(WIFI_MANAGEMENT_TAG, "Authmode \tWIFI_AUTH_OPEN");
break;
case WIFI_AUTH_WEP:
ESP_LOGI(WIFI_MANAGEMENT_TAG, "Authmode \tWIFI_AUTH_WEP");
break;
case WIFI_AUTH_WPA_PSK:
ESP_LOGI(WIFI_MANAGEMENT_TAG, "Authmode \tWIFI_AUTH_WPA_PSK");
break;
case WIFI_AUTH_WPA2_PSK:
ESP_LOGI(WIFI_MANAGEMENT_TAG, "Authmode \tWIFI_AUTH_WPA2_PSK");
break;
case WIFI_AUTH_WPA_WPA2_PSK:
ESP_LOGI(WIFI_MANAGEMENT_TAG, "Authmode \tWIFI_AUTH_WPA_WPA2_PSK");
break;
case WIFI_AUTH_WPA2_ENTERPRISE:
ESP_LOGI(WIFI_MANAGEMENT_TAG, "Authmode \tWIFI_AUTH_WPA2_ENTERPRISE");
break;
case WIFI_AUTH_WPA3_PSK:
ESP_LOGI(WIFI_MANAGEMENT_TAG, "Authmode \tWIFI_AUTH_WPA3_PSK");
break;
case WIFI_AUTH_WPA2_WPA3_PSK:
ESP_LOGI(WIFI_MANAGEMENT_TAG, "Authmode \tWIFI_AUTH_WPA2_WPA3_PSK");
break;
default:
ESP_LOGI(WIFI_MANAGEMENT_TAG, "Authmode \tWIFI_AUTH_UNKNOWN");
break;
}
}
static void print_cipher_type(int pairwise_cipher, int group_cipher)
{
switch (pairwise_cipher) {
case WIFI_CIPHER_TYPE_NONE:
ESP_LOGI(WIFI_MANAGEMENT_TAG, "Pairwise Cipher \tWIFI_CIPHER_TYPE_NONE");
break;
case WIFI_CIPHER_TYPE_WEP40:
ESP_LOGI(WIFI_MANAGEMENT_TAG, "Pairwise Cipher \tWIFI_CIPHER_TYPE_WEP40");
break;
case WIFI_CIPHER_TYPE_WEP104:
ESP_LOGI(WIFI_MANAGEMENT_TAG, "Pairwise Cipher \tWIFI_CIPHER_TYPE_WEP104");
break;
case WIFI_CIPHER_TYPE_TKIP:
ESP_LOGI(WIFI_MANAGEMENT_TAG, "Pairwise Cipher \tWIFI_CIPHER_TYPE_TKIP");
break;
case WIFI_CIPHER_TYPE_CCMP:
ESP_LOGI(WIFI_MANAGEMENT_TAG, "Pairwise Cipher \tWIFI_CIPHER_TYPE_CCMP");
break;
case WIFI_CIPHER_TYPE_TKIP_CCMP:
ESP_LOGI(WIFI_MANAGEMENT_TAG, "Pairwise Cipher \tWIFI_CIPHER_TYPE_TKIP_CCMP");
break;
default:
ESP_LOGI(WIFI_MANAGEMENT_TAG, "Pairwise Cipher \tWIFI_CIPHER_TYPE_UNKNOWN");
break;
}
switch (group_cipher) {
case WIFI_CIPHER_TYPE_NONE:
ESP_LOGI(WIFI_MANAGEMENT_TAG, "Group Cipher \tWIFI_CIPHER_TYPE_NONE");
break;
case WIFI_CIPHER_TYPE_WEP40:
ESP_LOGI(WIFI_MANAGEMENT_TAG, "Group Cipher \tWIFI_CIPHER_TYPE_WEP40");
break;
case WIFI_CIPHER_TYPE_WEP104:
ESP_LOGI(WIFI_MANAGEMENT_TAG, "Group Cipher \tWIFI_CIPHER_TYPE_WEP104");
break;
case WIFI_CIPHER_TYPE_TKIP:
ESP_LOGI(WIFI_MANAGEMENT_TAG, "Group Cipher \tWIFI_CIPHER_TYPE_TKIP");
break;
case WIFI_CIPHER_TYPE_CCMP:
ESP_LOGI(WIFI_MANAGEMENT_TAG, "Group Cipher \tWIFI_CIPHER_TYPE_CCMP");
break;
case WIFI_CIPHER_TYPE_TKIP_CCMP:
ESP_LOGI(WIFI_MANAGEMENT_TAG, "Group Cipher \tWIFI_CIPHER_TYPE_TKIP_CCMP");
break;
default:
ESP_LOGI(WIFI_MANAGEMENT_TAG, "Group Cipher \tWIFI_CIPHER_TYPE_UNKNOWN");
break;
}
}
const char * wifi_sta_connection_status_to_str(wifi_connect_status_t status) {
switch (status) {
case WL_TIMEOUT:
return "timeout";
case WL_IDLE_STATUS:
return "idle";
case WL_NO_SSID_AVAIL:
return "no SSID available";
case WL_SCAN_COMPLETED:
return "scan completed";
case WL_CONNECTED:
return "connected";
case WL_CONNECT_FAILED:
return "connect failed";
case WL_CONNECTION_LOST:
return "connection lost";
case WL_WRONG_PASSWORD:
return "wrong credentials";
case WL_DISCONNECTED:
return "disconnected";
default:
return "Unknown";
}
}
static const char* wifi_auth_mode_to_str(wifi_auth_mode_t auth_mode) {
switch (auth_mode) {
case WIFI_AUTH_OPEN: return "OPEN";
case WIFI_AUTH_WEP: return "WEP";
case WIFI_AUTH_WPA_PSK: return "WPA_PSK";
case WIFI_AUTH_WPA2_PSK: return "WPA2_PSK";
case WIFI_AUTH_WPA_WPA2_PSK: return "WPA_WPA2_PSK";
case WIFI_AUTH_WPA2_ENTERPRISE: return "WPA2_ENTERPRISE";
case WIFI_AUTH_WPA3_PSK: return "WPA3_PSK";
case WIFI_AUTH_WPA2_WPA3_PSK: return "WPA2_WPA3_PSK";
case WIFI_AUTH_WAPI_PSK: return "WAPI_PSK";
case WIFI_AUTH_OWE: return "OWE";
case WIFI_AUTH_WPA3_ENT_192: return "WPA3_ENT_SUITE_B_192_BIT";
case WIFI_AUTH_DPP: return "DPP";
case WIFI_AUTH_WPA3_ENTERPRISE: return "WPA3-Enterprise Only Mode";
case WIFI_AUTH_WPA2_WPA3_ENTERPRISE: return "WPA3-Enterprise Transition Mode";
case WIFI_AUTH_WPA_ENTERPRISE: return "WPA-Enterprise security";
default: return "UNKNOWN";
}
}
static const char* wifi_disconnect_reason_to_str(wifi_err_reason_t reason) {
switch (reason) {
case WIFI_REASON_UNSPECIFIED: return "UNSPECIFIED";
case WIFI_REASON_AUTH_EXPIRE: return "AUTH_EXPIRE";
case WIFI_REASON_AUTH_LEAVE: return "AUTH_LEAVE";
case WIFI_REASON_ASSOC_EXPIRE: return "ASSOC_EXPIRE";
case WIFI_REASON_ASSOC_TOOMANY: return "ASSOC_TOOMANY";
case WIFI_REASON_NOT_AUTHED: return "NOT_AUTHED";
case WIFI_REASON_NOT_ASSOCED: return "NOT_ASSOCED";
case WIFI_REASON_ASSOC_LEAVE: return "ASSOC_LEAVE";
case WIFI_REASON_ASSOC_NOT_AUTHED: return "ASSOC_NOT_AUTHED";
case WIFI_REASON_DISASSOC_PWRCAP_BAD: return "DISASSOC_PWRCAP_BAD";
case WIFI_REASON_DISASSOC_SUPCHAN_BAD: return "DISASSOC_SUPCHAN_BAD";
case WIFI_REASON_IE_INVALID: return "IE_INVALID";
case WIFI_REASON_MIC_FAILURE: return "MIC_FAILURE";
case WIFI_REASON_4WAY_HANDSHAKE_TIMEOUT: return "4WAY_HANDSHAKE_TIMEOUT";
case WIFI_REASON_GROUP_KEY_UPDATE_TIMEOUT: return "GROUP_KEY_UPDATE_TIMEOUT";
case WIFI_REASON_IE_IN_4WAY_DIFFERS: return "IE_IN_4WAY_DIFFERS";
case WIFI_REASON_GROUP_CIPHER_INVALID: return "GROUP_CIPHER_INVALID";
case WIFI_REASON_PAIRWISE_CIPHER_INVALID: return "PAIRWISE_CIPHER_INVALID";
case WIFI_REASON_AKMP_INVALID: return "AKMP_INVALID";
case WIFI_REASON_UNSUPP_RSN_IE_VERSION: return "UNSUPP_RSN_IE_VERSION";
case WIFI_REASON_INVALID_RSN_IE_CAP: return "INVALID_RSN_IE_CAP";
case WIFI_REASON_802_1X_AUTH_FAILED: return "802_1X_AUTH_FAILED";
case WIFI_REASON_CIPHER_SUITE_REJECTED: return "CIPHER_SUITE_REJECTED";
case WIFI_REASON_BEACON_TIMEOUT: return "BEACON_TIMEOUT";
case WIFI_REASON_NO_AP_FOUND: return "NO_AP_FOUND";
case WIFI_REASON_AUTH_FAIL: return "AUTH_FAIL";
case WIFI_REASON_ASSOC_FAIL: return "ASSOC_FAIL";
case WIFI_REASON_HANDSHAKE_TIMEOUT: return "HANDSHAKE_TIMEOUT";
case WIFI_REASON_CONNECTION_FAIL: return "CONNECTION_FAIL";
case WIFI_REASON_AP_TSF_RESET: return "AP_TSF_RESET";
case WIFI_REASON_ROAMING: return "ROAMING";
case WIFI_REASON_ASSOC_COMEBACK_TIME_TOO_LONG: return "ASSOC_COMEBACK_TIME_TOO_LONG";
case WIFI_REASON_SA_QUERY_TIMEOUT: return "SA_QUERY_TIMEOUT";
case WIFI_REASON_NO_AP_FOUND_IN_RSSI_THRESHOLD: return "NO_AP_FOUND_IN_RSSI_THRESHOLD";
case WIFI_REASON_NO_AP_FOUND_IN_AUTHMODE_THRESHOLD: return "NO_AP_FOUND_IN_AUTHMODE_THRESHOLD";
default: return "UNKNOWN";
}
}
static void _wifi_wait_connecting() {
int bits = 0;
uint32_t wifi_connecting_state_millis = millis();
do {
bits = xEventGroupGetBits(s_wifi_event_group);
if ((millis()-wifi_connecting_state_millis) > 5000) {
ESP_LOGW(WIFI_MANAGEMENT_TAG, "Wifi connecting end awaiting timeout");
break;
}
vTaskDelay(pdMS_TO_TICKS(1000));
} while ((bits & WIFI_CURRENTLY_CONNECTING_BIT) != 0);
}
void wifi_set_credentials(const char * wifi_ssid, const char * wifi_pwd) {
vTaskDelay(1);
bzero(esp_wifi_ssid, sizeof(esp_wifi_ssid));
bzero(esp_wifi_pass, sizeof(esp_wifi_pass));
if (wifi_ssid) strcpy(esp_wifi_ssid, wifi_ssid);
if (wifi_pwd) strcpy(esp_wifi_pass, wifi_pwd);
ESP_LOGI(WIFI_MANAGEMENT_TAG, "WiFi STA credentials set for network: %s", esp_wifi_ssid);
vTaskDelay(1);
}
void wifi_set_ap_credentials(const char * wifi_ssid, const char * wifi_pwd) {
vTaskDelay(1);
bzero(ap_wifi_ssid, sizeof(ap_wifi_ssid));
bzero(ap_wifi_pass, sizeof(ap_wifi_pass));
if (wifi_ssid) strcpy(ap_wifi_ssid, wifi_ssid);
if (wifi_pwd) strcpy(ap_wifi_pass, wifi_pwd);
vTaskDelay(1);
}
void wifi_ap_set_state(bool enable) {
// esp_wifi_disconnect();
// esp_wifi_clear_fast_connect();
vTaskDelay(pdMS_TO_TICKS(1000));
ap_state = enable;
if (enable) {
// if (strlen((char*)wifi_config.sta.ssid) > 0)
esp_wifi_set_mode(WIFI_MODE_APSTA);
// else esp_wifi_set_mode(WIFI_MODE_AP);
}
else {
if (strlen((char*)esp_wifi_ssid) > 0) esp_wifi_set_mode(WIFI_MODE_STA);
else {
esp_wifi_set_mode(WIFI_MODE_NULL);
ESP_LOGI(WIFI_MANAGEMENT_TAG, "Wifi credentials to STA are empty, exiting");
return;
}
// else esp_wifi_set_mode(WIFI_MODE_NAN);
}
ESP_LOGI(WIFI_MANAGEMENT_TAG, "Wifi STA SSID set: %s", esp_wifi_ssid);
esp_wifi_set_config(WIFI_IF_STA, &wifi_config);
vTaskDelay(1);
// esp_wifi_connect();
}
void wifi_management_sta_disconnect() {
manual_disconnect = true;
wifi_scan_in_progress = false;
esp_wifi_disconnect();
}
void wifi_sta_force_reconnect() {
s_retry_num = 0;
esp_err_t ret = ESP_OK;
wifi_scan_in_progress = false;
force_reconnect = true;
esp_wifi_disconnect();
// esp_wifi_stop();
vTaskDelay(pdMS_TO_TICKS(500));
esp_wifi_clear_fast_connect();
vTaskDelay(pdMS_TO_TICKS(1000));
ret = esp_wifi_get_config(WIFI_IF_STA, &wifi_config);
if (ret != ESP_OK) {
ESP_LOGW(WIFI_MANAGEMENT_TAG, "Cannot obtain Wifi config!");
}
else {
ESP_LOGW(WIFI_MANAGEMENT_TAG, "Wifi config memorized SSID before: %s", (char*)wifi_config.sta.ssid);
}
vTaskDelay(pdMS_TO_TICKS(500));
apply_wifi_sta_config();
// Clear all event bits
xEventGroupClearBits(s_wifi_event_group, WIFI_FAIL_BIT);
xEventGroupClearBits(s_wifi_event_group, WIFI_FAIL_WRONG_PASSWORD_BIT);
xEventGroupClearBits(s_wifi_event_group, WIFI_FAIL_STA_LOST);
xEventGroupClearBits(s_wifi_event_group, WIFI_CONNECTED_BIT);
if (strlen((char*)wifi_config.sta.ssid) > 0) {
// esp_wifi_set_mode(WIFI_MODE_STA);
ESP_LOGI(WIFI_MANAGEMENT_TAG, "Wifi STA SSID set: %s", wifi_config.sta.ssid);
manual_disconnect = false;
}
else {
ESP_LOGI(WIFI_MANAGEMENT_TAG, "Wifi credentials to STA are empty, exiting");
manual_disconnect = true;
return;
}
_wifi_wait_connecting();
vTaskDelay(pdMS_TO_TICKS(500));
ret = esp_wifi_set_config(WIFI_IF_STA, &wifi_config);
ESP_LOGW(WIFI_MANAGEMENT_TAG, "WiFi config set with result: %s", esp_err_to_name(ret));
if (ret != ESP_OK) {
ESP_LOGW(WIFI_MANAGEMENT_TAG, "Cannot obtain Wifi config!");
}
else {
ESP_LOGW(WIFI_MANAGEMENT_TAG, "Wifi config memorized SSID after: %s", (char*)wifi_config.sta.ssid);
}
force_reconnect = false;
vTaskDelay(pdMS_TO_TICKS(1000));
esp_wifi_connect();
}
bool wifi_scan_networks(wifi_management_sta_scan_result_t * wifi_scan_res) {
wifi_scan_in_progress = false;
wifi_mode_t wifi_mode = WIFI_MODE_NULL;
esp_wifi_get_mode(&wifi_mode);
if (wifi_mode != WIFI_MODE_APSTA && wifi_mode != WIFI_MODE_STA) {
return false;
}
bzero(wifi_scan_res, sizeof(wifi_management_sta_scan_result_t));
int bits = 0;
uint32_t wifi_connecting_await_ms = millis();
// do {
// bits = xEventGroupGetBits(s_wifi_event_group);
// // If WiFi is not connecting now, we can continue.
// // Otherwise, await within the timeout
// if ((bits & WIFI_CURRENTLY_CONNECTING_BIT) == 0) break;
// vTaskDelay(pdMS_TO_TICKS(200));
// } while(millis()-wifi_connecting_await_ms <= CONFIG_WIFI_SCAN_TIMEOUT);
bits = xEventGroupGetBits(s_wifi_event_group);
// if ((bits & WIFI_CURRENTLY_CONNECTING_BIT) != 0) {
// ESP_LOGW(WIFI_MANAGEMENT_TAG, "WiFi is still connecting, timeout");
// return false;
// }
// wifi_management_sta_disconnect();
// vTaskDelay(pdMS_TO_TICKS(100));
if ((bits & WIFI_CURRENTLY_CONNECTING_BIT) != 0) {
ESP_LOGW(WIFI_MANAGEMENT_TAG, "WiFi is still connecting, disconnect");
wifi_management_sta_disconnect();
vTaskDelay(pdMS_TO_TICKS(10));
// return false;
}
esp_wifi_clear_ap_list();
if (esp_wifi_scan_start(NULL, true) != ESP_OK) return false;
if (onWiFiScanStarted) onWiFiScanStarted();
vTaskDelay(pdMS_TO_TICKS(100));
ESP_ERROR_CHECK(esp_wifi_scan_get_ap_num(&(wifi_scan_res->ap_count)));
uint16_t ap_number = (uint16_t)fmin((float)MAXIMUM_AP_RECORDS, (float)wifi_scan_res->ap_count);
ESP_LOGI(WIFI_MANAGEMENT_TAG, "Found APs: %u", ap_number);
ESP_ERROR_CHECK(esp_wifi_scan_get_ap_records(&ap_number, wifi_scan_res->ap));
wifi_scan_res->ap_count = ap_number;
if (onWiFiScanEnded) onWiFiScanEnded();
// wifi_sta_force_reconnect();
wifi_scan_in_progress = false;
ESP_LOGW(WIFI_MANAGEMENT_TAG, "Scanned successfully");
return true;
}
/**
* @brief Returns the bitmap of channels to scan by chunk index
* 0 - all channels
* 1 - 1-4
* 2 - 5-9
* 3 - 10-14
*/
static wifi_scan_channel_bitmap_t _get_wifi_scan_channel_2_4_bitmap_by_chunk(int chunk_index) {
wifi_scan_channel_bitmap_t bitmap_out = {0};
switch(chunk_index) {
case 1:
bitmap_out.ghz_2_channels |= WIFI_CHANNEL_1;
bitmap_out.ghz_2_channels |= WIFI_CHANNEL_2;
bitmap_out.ghz_2_channels |= WIFI_CHANNEL_3;
bitmap_out.ghz_2_channels |= WIFI_CHANNEL_4;
break;
case 2:
bitmap_out.ghz_2_channels |= WIFI_CHANNEL_5;
bitmap_out.ghz_2_channels |= WIFI_CHANNEL_6;
bitmap_out.ghz_2_channels |= WIFI_CHANNEL_7;
bitmap_out.ghz_2_channels |= WIFI_CHANNEL_8;
bitmap_out.ghz_2_channels |= WIFI_CHANNEL_9;
break;
case 3:
bitmap_out.ghz_2_channels |= WIFI_CHANNEL_10;
bitmap_out.ghz_2_channels |= WIFI_CHANNEL_11;
bitmap_out.ghz_2_channels |= WIFI_CHANNEL_12;
bitmap_out.ghz_2_channels |= WIFI_CHANNEL_13;
bitmap_out.ghz_2_channels |= WIFI_CHANNEL_14;
break;
default:
break;
}
return bitmap_out;
}
bool wifi_management_sta_trigger_scan(int channels_chunk_index) {
wifi_mode_t wifi_mode = WIFI_MODE_NULL;
esp_wifi_get_mode(&wifi_mode);
if (wifi_mode != WIFI_MODE_APSTA && wifi_mode != WIFI_MODE_STA) {
return false;
}
bzero(&wifi_scan_result, sizeof(wifi_management_sta_scan_result_t));
wifi_scan_finished = false;
wifi_scan_in_progress = true;
wifi_scan_config_t wifi_scan_cfg = {
.show_hidden = false,
.scan_type = WIFI_SCAN_TYPE_PASSIVE,
.scan_time = {
.active = {
.min = 0,
.max = 150
},
.passive = 90
},
.home_chan_dwell_time = 120,
.channel_bitmap = _get_wifi_scan_channel_2_4_bitmap_by_chunk(channels_chunk_index)
};
esp_err_t ret = esp_wifi_scan_start(&wifi_scan_cfg, false);
if (ret != ESP_OK) {
ESP_LOGE(WIFI_MANAGEMENT_TAG, "Cannot trigger WiFi scan: %s", esp_err_to_name(ret));
return false;
}
if (onWiFiScanStarted) onWiFiScanStarted();
ESP_LOGI(WIFI_MANAGEMENT_TAG, "WiFi networks scan triggered");
return true;
}
bool wifi_management_is_scan_done() {
return wifi_scan_finished;
}
wifi_management_sta_scan_result_t wifi_management_get_scanned_networks() {
uint32_t scan_end_await_millis = millis();
while (wifi_scan_in_progress) {
if (millis()-scan_end_await_millis > 1000) {
break;
}
vTaskDelay(pdMS_TO_TICKS(100));
}
return wifi_scan_result;
}
static wifi_connect_status_t _get_wifi_last_status(int bits) {
wifi_connect_status_t wifi_connect_status = WL_TIMEOUT;
if (bits == 0) return wifi_connect_status;
else {
// If WIFI_CONNECTED_BIT is set, the we consider as WiFi connected
if ((bits & WIFI_CONNECTED_BIT) != 0) {
// ESP_LOGI(WIFI_MANAGEMENT_TAG, "WiFi STA connected on request");
wifi_connect_status = WL_CONNECTED;
}
else if ((bits & WIFI_FAIL_BIT) != 0) {
if ((bits & WIFI_FAIL_WRONG_PASSWORD_BIT) != 0) {
// ESP_LOGE(WIFI_MANAGEMENT_TAG, "Wrong password specified");
wifi_connect_status = WL_WRONG_PASSWORD;
}
else if ((bits & WIFI_FAIL_STA_LOST) != 0) {
// ESP_LOGE(WIFI_MANAGEMENT_TAG, "WiFi desired AP is lost during connection to it");
wifi_connect_status = WL_CONNECTION_LOST;
}
}
}
return wifi_connect_status;
}
wifi_management_general_state_t wifi_management_get_general_state() {
wifi_management_general_state_t general_state;
uint8_t mac_addr[6];
bzero(general_state.sta_ssid, sizeof(general_state.sta_ssid));
bzero(general_state.mac_address, sizeof(general_state.mac_address));
strcpy(general_state.sta_ssid, esp_wifi_ssid);
esp_wifi_get_mac(WIFI_IF_STA, mac_addr);
sprintf(general_state.mac_address, "%02x:%02x:%02x:%02x:%02x:%02x", mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);
wifi_mode_t wifi_mode = WIFI_MODE_NULL;
esp_wifi_get_mode(&wifi_mode);
int wifi_event_bits = xEventGroupGetBits(s_wifi_event_group);
wifi_connect_status_t wifi_connect_status = _get_wifi_last_status(wifi_event_bits);
general_state.ap_active = ((wifi_mode == WIFI_MODE_AP || wifi_mode == WIFI_MODE_APSTA) ? 1 : 0);
general_state.sta_active = ((wifi_mode == WIFI_MODE_STA || wifi_mode == WIFI_MODE_APSTA) ? 1 : 0);
general_state.ap_stations_connected = (uint8_t)ap_connected_devices;
general_state.sta_connected = ((wifi_connect_status == WL_CONNECTED) ? 1 : 0);
general_state.last_sta_connect_status = wifi_connect_status;
general_state.sta_rssi = get_current_sta_rssi();
return general_state;
}
wifi_connect_status_t wifi_connect_wait_for_result(uint32_t timeout_ms) {
ESP_LOGI(WIFI_MANAGEMENT_TAG, "Connecting to WiFi...");
wifi_connect_status_t wifi_connect_status = WL_DISCONNECTED;
wifi_mode_t wifi_mode = WIFI_MODE_NULL;
esp_wifi_get_mode(&wifi_mode);
// Check if wifi mode is suitable
if (wifi_mode != WIFI_MODE_STA && wifi_mode != WIFI_MODE_APSTA) {
ESP_LOGE(WIFI_MANAGEMENT_TAG, "Invalid WiFi mode to connection to STA");
return wifi_connect_status;
}
wifi_sta_force_reconnect();
vTaskDelay(pdMS_TO_TICKS(100));
int bits = xEventGroupWaitBits(s_wifi_event_group, (WIFI_CONNECTED_BIT | WIFI_FAIL_BIT), pdFALSE, pdFALSE, pdMS_TO_TICKS(timeout_ms));
wifi_connect_status = _get_wifi_last_status(bits);
switch(wifi_connect_status) {
case WL_TIMEOUT:
ESP_LOGE(WIFI_MANAGEMENT_TAG, "WiFi connect timed out");
break;
case WL_CONNECTED:
ESP_LOGI(WIFI_MANAGEMENT_TAG, "WiFi STA connected on request");
break;
case WL_WRONG_PASSWORD:
ESP_LOGE(WIFI_MANAGEMENT_TAG, "Wrong password specified");
break;
case WL_CONNECTION_LOST:
ESP_LOGE(WIFI_MANAGEMENT_TAG, "WiFi desired AP is lost during connection to it");
break;
default:
break;
}
vTaskDelay(pdMS_TO_TICKS(100));
return wifi_connect_status;
}
static void _wifi_periodic_scan(void * arg) {
int bits = xEventGroupGetBits(s_wifi_event_group);
static int channels_chunk_index = 1;
if ((bits & WIFI_CURRENTLY_CONNECTING_BIT) == 0) {
ESP_LOGI(WIFI_MANAGEMENT_TAG, "WiFi is not connecting, periodic scan allowed");
wifi_management_sta_trigger_scan(0);
// wifi_management_sta_trigger_scan(channels_chunk_index++);
// if (channels_chunk_index > 3) channels_chunk_index = 1;
}
else {
ESP_LOGW(WIFI_MANAGEMENT_TAG, "WiFi is currently connecting, skip it");
}
}
void network_stack_init(void) {
ESP_ERROR_CHECK(esp_netif_init());
// esp_netif_t *sta_netif = esp_netif_create_default_wifi_sta();
sta_netif = esp_netif_create_default_wifi_sta();
assert(sta_netif);
// esp_netif_t* wifiAP = esp_netif_create_default_wifi_ap();
wifiAP = esp_netif_create_default_wifi_ap();
esp_netif_ip_info_t ip_info;
esp_netif_ip_info_t ipInfo;
ipInfo.ip.addr = WIFI_MANAGEMENT_AP_IP_ADDR;
ipInfo.netmask.addr = WIFI_MANAGEMENT_AP_NETMASK;
ipInfo.gw.addr = WIFI_MANAGEMENT_AP_GATEWAY;
esp_netif_dhcps_stop(wifiAP);
esp_netif_set_ip_info(wifiAP, &ipInfo);
esp_netif_dhcps_start(wifiAP);
esp_netif_tx_rx_event_enable(sta_netif);
}
void network_stack_deinit() {
// esp_event_loop_delete_default();
esp_netif_destroy(sta_netif);
esp_netif_destroy(wifiAP);
// ESP_ERROR_CHECK(esp_netif_deinit());
}
int get_current_sta_rssi() {
wifi_ap_record_t ap_info;
memset(&ap_info, 0, sizeof(ap_info));
esp_err_t err = esp_wifi_sta_get_ap_info(&ap_info);
if (err != ESP_OK) {
if (err == ESP_ERR_WIFI_NOT_CONNECT) {
ESP_LOGW(WIFI_MANAGEMENT_TAG, "Cannot read WIFI STA info: %s, using the last RSSI: %d", esp_err_to_name(err), last_wifi_rssi);
return last_wifi_rssi;
}
ESP_LOGW(WIFI_MANAGEMENT_TAG, "Cannot read WIFI STA info: %s", esp_err_to_name(err));
return -127;
}
return ap_info.rssi;
}
int get_last_sta_rssi() {
return last_wifi_rssi;
}
wifi_management_ip_got_t wifi_get_current_ip_addr() {
return _ip_info;
}
static void handle_after_connection_fails(void *arg) {
ESP_LOGI(WIFI_MANAGEMENT_TAG, "Reconnect timer triggered");
// Проверить, не подключены ли мы уже
int bits = xEventGroupGetBits(s_wifi_event_group);
if (bits & WIFI_CONNECTED_BIT) {
ESP_LOGI(WIFI_MANAGEMENT_TAG, "Already connected, stopping reconnect timer");
return;
}
s_retry_num = 0;
xEventGroupClearBits(s_wifi_event_group, WIFI_FAIL_BIT | WIFI_FAIL_WRONG_PASSWORD_BIT | WIFI_FAIL_STA_LOST);
ESP_LOGI(WIFI_MANAGEMENT_TAG, "Attempting reconnect...");
esp_wifi_disconnect();
vTaskDelay(pdMS_TO_TICKS(1000));
esp_wifi_connect();
}
static void event_handler(void* arg, esp_event_base_t event_base,
int32_t event_id, void* event_data)
{
uint16_t ap_number = MAXIMUM_AP_RECORDS;
wifi_ap_record_t ap_info[MAXIMUM_AP_RECORDS];
uint16_t ap_count = 0;
uint16_t ap_with_requested_name_found = 0;
int strongest_ap_rssi = -100;
if (event_base == WIFI_EVENT) {
if (event_id == WIFI_EVENT_STA_START) {
ESP_LOGI(WIFI_MANAGEMENT_TAG, "WiFi STA starting...");
xEventGroupSetBits(s_wifi_event_group, WIFI_CURRENTLY_CONNECTING_BIT);
esp_wifi_connect();
} else if (event_id == WIFI_EVENT_STA_DISCONNECTED) {
wifi_event_sta_disconnected_t * evt = (wifi_event_sta_disconnected_t*)event_data;
ESP_LOGW(WIFI_MANAGEMENT_TAG, "WiFi disconnected, reason: %s", wifi_disconnect_reason_to_str(evt->reason));
xEventGroupClearBits(s_wifi_event_group, WIFI_CURRENTLY_CONNECTING_BIT | WIFI_CONNECTED_BIT);
// Обработка различных причин отключения
switch (evt->reason) {
case WIFI_REASON_AUTH_EXPIRE:
case WIFI_REASON_4WAY_HANDSHAKE_TIMEOUT:
case WIFI_REASON_GROUP_KEY_UPDATE_TIMEOUT:
case WIFI_REASON_IE_IN_4WAY_DIFFERS:
xEventGroupSetBits(s_wifi_event_group, WIFI_FAIL_WRONG_PASSWORD_BIT);
break;
case WIFI_REASON_NO_AP_FOUND:
case WIFI_REASON_NOT_AUTHED:
case WIFI_REASON_NOT_ASSOCED:
xEventGroupSetBits(s_wifi_event_group, WIFI_FAIL_STA_LOST);
break;
default:
xEventGroupSetBits(s_wifi_event_group, WIFI_FAIL_BIT);
break;
}
// Сброс IP информации
bzero(_ip_info.ip, sizeof(_ip_info.ip));
_ip_info.ip_type = IP_TYPE_NONE;
if (onWiFidisconnect) onWiFidisconnect();
if (s_retry_num < CONFIG_WIFI_RECONNECT_TRIES) {
if (!force_reconnect && !manual_disconnect && !wifi_scan_in_progress) {
ESP_LOGI(WIFI_MANAGEMENT_TAG, "Retry %d/%d", s_retry_num + 1, CONFIG_WIFI_RECONNECT_TRIES);
xEventGroupSetBits(s_wifi_event_group, WIFI_CURRENTLY_CONNECTING_BIT);
vTaskDelay(pdMS_TO_TICKS(1000)); // Задержка перед повторной попыткой
esp_wifi_connect();
s_retry_num++;
}
else {
if (force_reconnect) ESP_LOGI(WIFI_MANAGEMENT_TAG, "Disconnect event is caused by force reconnection, not retrying");
if (manual_disconnect) ESP_LOGI(WIFI_MANAGEMENT_TAG, "Disconnect event is caused by manual disconnect, not retrying");
if (wifi_scan_in_progress) ESP_LOGI(WIFI_MANAGEMENT_TAG, "WiFi scan in progress");
}
} else {
ESP_LOGW(WIFI_MANAGEMENT_TAG, "Max retries exceeded, scheduling reconnect timer");
if (!esp_timer_is_active(reconnect_timer)) {
esp_timer_start_once(reconnect_timer, WIFI_RECONNECT_BACKOFF_US);
}
}
} else if (event_id == WIFI_EVENT_STA_CONNECTED) {
// WiFi is connected successfully, so need to clear Connecting flag
xEventGroupClearBits(s_wifi_event_group, WIFI_CURRENTLY_CONNECTING_BIT);
wifi_event_sta_connected_t* event = (wifi_event_sta_connected_t*) event_data;
if (esp_timer_is_active(reconnect_timer))
esp_timer_stop(reconnect_timer);
ESP_LOGW(
WIFI_MANAGEMENT_TAG,
"WiFi connected - SSID: %s, BSSID: " MACSTR ", Auth: %s",
event->ssid, MAC2STR(event->bssid),
wifi_auth_mode_to_str(event->authmode)
);
//ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA) );
//ESP_LOGI(TAG, "station \"%s\" join, AID=%d", MAC2STR(event->mac), event->aid);
} else if (event_id == WIFI_EVENT_AP_STACONNECTED) {
// Call the procedure on STA connection to softAP
ap_connected_devices++;
if (ap_connected_devices >= 0) {
ESP_LOGW(WIFI_MANAGEMENT_TAG, "Devices connected: %d", ap_connected_devices);
if (onWiFiAPstaconnect) onWiFiAPstaconnect();
}
} else if (event_id == WIFI_EVENT_AP_STADISCONNECTED) {
wifi_event_ap_stadisconnected_t* event = (wifi_event_ap_stadisconnected_t*) event_data;
//ESP_LOGI(TAG, "station \"%s\" leave, AID=%d", MAC2STR(event->mac), event->aid);
ap_connected_devices--;
// Call the procedure on STA disconnection to softAP
if (ap_connected_devices <= 0) {
ap_connected_devices = 0;
ESP_LOGW(WIFI_MANAGEMENT_TAG, "All devices disconnected!");
if (onWiFiAPstadisconnect) onWiFiAPstadisconnect();
}
ESP_LOGW(WIFI_MANAGEMENT_TAG, "Devices connected: %d", ap_connected_devices);
} else if (event_id == WIFI_EVENT_SCAN_DONE) {
esp_err_t ret = esp_wifi_scan_get_ap_num(&(wifi_scan_result.ap_count));
if (ret != ESP_OK) {
ESP_LOGE(WIFI_MANAGEMENT_TAG, "Cannot get WiFi number of scanned APs");
wifi_scan_in_progress = false;
return;
}
uint16_t ap_number = (uint16_t)fmin((float)MAXIMUM_AP_RECORDS, (float)wifi_scan_result.ap_count);
ESP_LOGI(WIFI_MANAGEMENT_TAG, "Found APs: %u", ap_number);
ret = esp_wifi_scan_get_ap_records(&ap_number, wifi_scan_result.ap);
if (ret != ESP_OK) {
ESP_LOGE(WIFI_MANAGEMENT_TAG, "Cannot get WiFi scanned APs list");
esp_wifi_clear_ap_list();
wifi_scan_in_progress = false;
return;
}
wifi_scan_result.ap_count = ap_number;
wifi_scan_finished = true;
wifi_scan_in_progress = false;
if (onWiFiScanEnded) onWiFiScanEnded();
}
}
else if (event_base == IP_EVENT) {
if (event_id == IP_EVENT_STA_GOT_IP) {
ip_event_got_ip_t* event = (ip_event_got_ip_t*) event_data;
ESP_LOGI(WIFI_MANAGEMENT_TAG, "got ip: %d.%d.%d.%d", IP2STR(&event->ip_info.ip));
bzero(_ip_info.ip, sizeof(_ip_info.ip));
sprintf(_ip_info.ip, "%d.%d.%d.%d", IP2STR(&event->ip_info.ip));
_ip_info.ip_type = IP_TYPE_IPV4;
s_retry_num = 0;
if (onWiFiconnect) onWiFiconnect();
xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT);
}
else if (event_id == IP_EVENT_STA_LOST_IP) {
bzero(_ip_info.ip, sizeof(_ip_info.ip));
_ip_info.ip_type = IP_TYPE_NONE;
ESP_LOGI(WIFI_MANAGEMENT_TAG, "IP was lost, triggering the event");
if (onWiFiLostIP) onWiFiLostIP();
}
else if (event_id == IP_EVENT_GOT_IP6) {
ip_event_got_ip6_t* evt = (ip_event_got_ip6_t*) event_data;
bzero(_ip_info.ip, sizeof(_ip_info.ip));
sprintf(_ip_info.ip, IPV6STR, IPV62STR(evt->ip6_info.ip));
_ip_info.ip_type = IP_TYPE_IPV6;
ESP_LOGI(WIFI_MANAGEMENT_TAG, "got IPv6: %s", _ip_info.ip);
s_retry_num = 0;
if (onWiFiconnect) onWiFiconnect();
xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT);
}
else if (event_id == IP_EVENT_TX_RX) {
ip_event_tx_rx_t* evt = (ip_event_tx_rx_t*)event_data;
if (evt->dir == ESP_NETIF_TX) traffic_transmitted+=(uint64_t)evt->len;
else if (evt->dir == ESP_NETIF_RX) traffic_received+=(uint64_t)evt->len;
}
}
}
void cleanup_wifi_sta_config() {
memset(&wifi_config, 0, sizeof(wifi_config_t));
}
void apply_wifi_sta_config() {
bool wifi_sta_secure_connection = false;
memset(&wifi_config, 0, sizeof(wifi_config_t));
bzero(wifi_config.sta.ssid, sizeof(wifi_config.sta.ssid));
bzero(wifi_config.sta.password, sizeof(wifi_config.sta.password));
strncpy((char*)wifi_config.sta.ssid, esp_wifi_ssid, MIN(sizeof(wifi_config.sta.ssid), strlen(esp_wifi_ssid)));
strncpy((char*)wifi_config.sta.password, esp_wifi_pass, MIN(sizeof(wifi_config.sta.password), strlen(esp_wifi_pass)));
wifi_sta_secure_connection = (strlen((char*)wifi_config.sta.password) > 0);
ESP_LOGI(WIFI_MANAGEMENT_TAG, "Wifi STA SSID set to config: %s", wifi_config.sta.ssid);
wifi_config.sta.threshold.authmode = (wifi_sta_secure_connection ? WIFI_AUTH_WPA_WPA2_PSK : WIFI_AUTH_OPEN);
wifi_config.sta.scan_method = WIFI_FAST_SCAN;
wifi_config.sta.sort_method = WIFI_CONNECT_AP_BY_SIGNAL;
wifi_config.sta.pmf_cfg.capable = true;
wifi_config.sta.pmf_cfg.required = false;
wifi_config.sta.failure_retry_cnt = 10;
wifi_config.sta.rm_enabled = 1;
}
esp_err_t wifi_management_init(bool test_mode) {
esp_err_t ret = ESP_OK;
bzero(_ip_info.ip, sizeof(_ip_info.ip));
_ip_info.ip_type = IP_TYPE_NONE;
// bzero(&wifi_scan_res, sizeof(wifi_scan_res));
const esp_timer_create_args_t reconnect_timer_args = {
.callback = &handle_after_connection_fails,
/* argument specified here will be passed to timer callback function */
//.arg = (void*) periodic_timer,
.name = "reconnect timer"
};
ESP_GOTO_ON_ERROR(
esp_timer_create(&reconnect_timer_args, &reconnect_timer),
wifi_management_reconnect_timer_create_failed,
WIFI_MANAGEMENT_TAG,
"Cannot create timer for WiFi reconnect"
);
s_wifi_event_group = xEventGroupCreate();
// wifi_scan_done_event_group = xEventGroupCreate();
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_GOTO_ON_ERROR(
esp_wifi_init(&cfg),
wifi_management_init_failed,
WIFI_MANAGEMENT_TAG,
"Cannot initialize WiFi"
);
ESP_GOTO_ON_ERROR(
esp_event_handler_instance_register(
WIFI_EVENT,
ESP_EVENT_ANY_ID,
&event_handler,
NULL,
&instance_any_id
),
wifi_management_event_handler_any_event_register_failed,
WIFI_MANAGEMENT_TAG,
"Cannot register ANY WiFi event!"
);
ESP_GOTO_ON_ERROR(
esp_event_handler_instance_register(
IP_EVENT,
IP_EVENT_STA_GOT_IP,
&event_handler,
NULL,
&instance_got_ip),
wifi_management_event_handler_got_ip_event_register_failed,
WIFI_MANAGEMENT_TAG,
"Cannot register GOT_IP event!"
);
ESP_GOTO_ON_ERROR(
esp_event_handler_instance_register(
IP_EVENT,
IP_EVENT_STA_LOST_IP,
&event_handler,
NULL,
&instance_lost_ip),
wifi_management_event_handler_lost_ip_event_register_failed,
WIFI_MANAGEMENT_TAG,
"Cannot register LOST_IP event!"
);
ESP_GOTO_ON_ERROR(
esp_event_handler_instance_register(
IP_EVENT,
IP_EVENT_GOT_IP6,
&event_handler,
NULL,
&instance_got_ip6),
wifi_management_event_handler_got_ip6_event_register_failed,
WIFI_MANAGEMENT_TAG,
"Cannot register GOT_IP6 event!"
);
ESP_GOTO_ON_ERROR(
esp_event_handler_instance_register(
IP_EVENT,
IP_EVENT_TX_RX,
&event_handler,
NULL,
&instance_rxtx),
wifi_management_event_handler_rxtx_register_failed,
WIFI_MANAGEMENT_TAG,
"Cannot register RXTX event!"
);
//ESP_ERROR_CHECK( esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &event_handler, NULL) );
if (test_mode) esp_wifi_set_storage(WIFI_STORAGE_RAM);
else esp_wifi_set_storage(WIFI_STORAGE_FLASH);
// esp_wifi_set_storage(WIFI_STORAGE_RAM);
apply_wifi_sta_config();
memset(&wifi_config_ap, 0, sizeof(wifi_config_t));
//wifi_config.sta.ssid = ESP_WIFI_SSID;
//wifi_config.sta.password = ESP_WIFI_PASS;
strcpy((char*)wifi_config_ap.ap.ssid, ap_wifi_ssid);
strcpy((char*)wifi_config_ap.ap.password, ap_wifi_pass);
ESP_LOGI(WIFI_MANAGEMENT_TAG, "Wifi AP set: %s", wifi_config_ap.ap.ssid);
wifi_config_ap.ap.ssid_len = strlen(ap_wifi_ssid);
wifi_config_ap.ap.channel = 10;
wifi_config_ap.ap.max_connection = 5;
// wifi_config_ap.ap.csa_count = 10;
// wifi_config_ap.ap.beacon_interval = 3000;
// wifi_config_ap.ap.dtim_period = 3;
if (strlen(ap_wifi_pass) == 0) {
wifi_config_ap.ap.authmode = WIFI_AUTH_OPEN;
}
else wifi_config_ap.ap.authmode = WIFI_AUTH_WPA_WPA2_PSK;
//wifi_config_t conf;
//esp_wifi_get_config(WIFI_IF_STA, &conf);
//ESP_LOGI(TAG, "Got from WiFI: %s, %s", conf.sta.ssid, conf.sta.password);
if (strlen((char*)wifi_config.sta.ssid) > 0)
ESP_GOTO_ON_ERROR(
esp_wifi_set_mode(WIFI_MODE_APSTA),
wifi_management_set_mode_failed,
WIFI_MANAGEMENT_TAG,
"Cannot set WiFi mode"
);
else
ESP_GOTO_ON_ERROR(
esp_wifi_set_mode(WIFI_MODE_AP),
wifi_management_set_mode_failed,
WIFI_MANAGEMENT_TAG,
"Cannot set WiFi mode"
);
if (strlen((char*)wifi_config.sta.ssid) > 0)
ESP_GOTO_ON_ERROR(
esp_wifi_set_config(WIFI_IF_STA, &wifi_config),
wifi_management_sta_set_config_failed,
WIFI_MANAGEMENT_TAG,
"Cannot set WiFi STA config"
);
{
wifi_country_t country = {
.cc = "RU",
.schan = 1,
.nchan = 13,
.policy = WIFI_COUNTRY_POLICY_AUTO,
};
esp_wifi_set_country(&country);
}
ESP_GOTO_ON_ERROR(
esp_wifi_set_config(WIFI_IF_AP, &wifi_config_ap),
wifi_management_ap_set_config_failed,
WIFI_MANAGEMENT_TAG,
"Cannot set WiFi AP config"
);
ESP_GOTO_ON_ERROR(
esp_wifi_start(),
wifi_management_start_failed,
WIFI_MANAGEMENT_TAG,
"Cannot start WiFi"
);
// start_find_strongest_wifi_ap();
esp_wifi_set_max_tx_power(CONFIG_WIFI_MAX_TX_POWER);
esp_wifi_clear_fast_connect();
esp_wifi_set_ps(WIFI_PS_NONE);
{
const esp_timer_create_args_t wifi_periodic_scan_timer_args = {
.callback = &_wifi_periodic_scan,
/* argument specified here will be passed to timer callback function */
//.arg = (void*) periodic_timer,
.name = "wifi periodic scan timer"
};
ESP_ERROR_CHECK(esp_timer_create(&wifi_periodic_scan_timer_args, &wifi_scan_timer));
ESP_ERROR_CHECK(
esp_timer_start_periodic(
wifi_scan_timer,
(1000*(CONFIG_WIFI_CONTINUOUS_SCAN_PERIOD))
)
);
}
ESP_LOGI(WIFI_MANAGEMENT_TAG, "wifi_init_sta finished.");
return ret;
wifi_management_start_failed:
wifi_management_ap_set_config_failed:
wifi_management_sta_set_config_failed:
wifi_management_set_mode_failed:
esp_event_handler_instance_unregister(IP_EVENT, IP_EVENT_TX_RX, &instance_rxtx);
wifi_management_event_handler_rxtx_register_failed:
esp_event_handler_instance_unregister(IP_EVENT, IP_EVENT_GOT_IP6, &instance_got_ip6);
wifi_management_event_handler_got_ip6_event_register_failed:
esp_event_handler_instance_unregister(IP_EVENT, IP_EVENT_STA_LOST_IP, &instance_lost_ip);
wifi_management_event_handler_lost_ip_event_register_failed:
esp_event_handler_instance_unregister(IP_EVENT, IP_EVENT_STA_GOT_IP, &instance_got_ip);
wifi_management_event_handler_got_ip_event_register_failed:
esp_event_handler_instance_unregister(WIFI_EVENT, ESP_EVENT_ANY_ID, &instance_any_id);
wifi_management_event_handler_any_event_register_failed:
esp_wifi_deinit();
wifi_management_init_failed:
vEventGroupDelete(s_wifi_event_group);
esp_timer_stop(reconnect_timer);
esp_timer_delete(reconnect_timer);
wifi_management_reconnect_timer_create_failed:
return ret;
}
void wifi_management_deinit() {
esp_timer_stop(wifi_scan_timer);
esp_timer_delete(wifi_scan_timer);
wifi_scan_timer = NULL;
esp_wifi_stop();
esp_event_handler_instance_unregister(IP_EVENT, IP_EVENT_TX_RX, &instance_rxtx);
esp_event_handler_instance_unregister(IP_EVENT, IP_EVENT_GOT_IP6, &instance_got_ip6);
esp_event_handler_instance_unregister(IP_EVENT, IP_EVENT_STA_LOST_IP, &instance_lost_ip);
esp_event_handler_instance_unregister(IP_EVENT, IP_EVENT_STA_GOT_IP, &instance_got_ip);
esp_event_handler_instance_unregister(WIFI_EVENT, ESP_EVENT_ANY_ID, &instance_any_id);
esp_wifi_deinit();
// vEventGroupDelete(wifi_scan_done_event_group);
vEventGroupDelete(s_wifi_event_group);
esp_timer_stop(reconnect_timer);
esp_timer_delete(reconnect_timer);
}