From f8e58653bd2c90bdee9c91006cac7c6d79b62dd6 Mon Sep 17 00:00:00 2001 From: William Emfinger Date: Mon, 19 Jan 2026 23:07:26 -0600 Subject: [PATCH 1/2] feat(wifi): Improve Wifi STA + AP init/deinit to have better support for simultaneity --- components/wifi/CMakeLists.txt | 2 +- components/wifi/include/wifi_ap.hpp | 36 ++++++++++++++++++++-- components/wifi/include/wifi_sta.hpp | 45 +++++++++++++++++++++++----- 3 files changed, 71 insertions(+), 12 deletions(-) diff --git a/components/wifi/CMakeLists.txt b/components/wifi/CMakeLists.txt index ef3d7a97e..571cb1da9 100644 --- a/components/wifi/CMakeLists.txt +++ b/components/wifi/CMakeLists.txt @@ -1,4 +1,4 @@ idf_component_register( INCLUDE_DIRS "include" SRC_DIRS "src" - PRIV_REQUIRES esp_wifi nvs_flash base_component cli) + REQUIRES esp_wifi nvs_flash base_component cli) diff --git a/components/wifi/include/wifi_ap.hpp b/components/wifi/include/wifi_ap.hpp index 53333ec38..3a1912156 100644 --- a/components/wifi/include/wifi_ap.hpp +++ b/components/wifi/include/wifi_ap.hpp @@ -278,8 +278,22 @@ class WifiAp : public WifiBase { wifi_config.ap.authmode = WIFI_AUTH_OPEN; } - logger_.debug("Setting WiFi mode to AP"); - err = esp_wifi_set_mode(WIFI_MODE_AP); + // Get current mode and add AP to it if needed + wifi_mode_t current_mode; + err = esp_wifi_get_mode(¤t_mode); + wifi_mode_t new_mode = WIFI_MODE_AP; + if (err == ESP_OK) { + if (current_mode == WIFI_MODE_STA) { + new_mode = WIFI_MODE_APSTA; + logger_.debug("STA mode already active, setting mode to APSTA"); + } else if (current_mode == WIFI_MODE_APSTA) { + new_mode = WIFI_MODE_APSTA; + logger_.debug("APSTA mode already set"); + } + } + + logger_.debug("Setting WiFi mode to {}", new_mode); + err = esp_wifi_set_mode(new_mode); if (err != ESP_OK) { logger_.error("Could not set WiFi to AP: {}", err); return false; @@ -328,8 +342,24 @@ class WifiAp : public WifiBase { * @return True if the operation was successful, false otherwise. */ bool stop() override { + // Check if we're in APSTA mode - if so, just switch to STA mode, don't stop WiFi entirely + wifi_mode_t mode; + esp_err_t err = esp_wifi_get_mode(&mode); + if (err == ESP_OK && mode == WIFI_MODE_APSTA) { + // In APSTA mode, switch to STA-only mode + logger_.debug("In APSTA mode, switching to STA mode"); + err = esp_wifi_set_mode(WIFI_MODE_STA); + if (err != ESP_OK) { + logger_.error("Could not switch to STA mode: {}", esp_err_to_name(err)); + return false; + } + logger_.info("WiFi AP stopped, STA still running"); + return true; + } + + // In AP-only mode, stop WiFi entirely logger_.debug("Stopping WiFi"); - esp_err_t err = esp_wifi_stop(); + err = esp_wifi_stop(); if (err != ESP_OK) { logger_.error("Could not stop WiFi AP: {}", esp_err_to_name(err)); return false; diff --git a/components/wifi/include/wifi_sta.hpp b/components/wifi/include/wifi_sta.hpp index 270510fa8..f3b1edcdc 100644 --- a/components/wifi/include/wifi_sta.hpp +++ b/components/wifi/include/wifi_sta.hpp @@ -108,13 +108,28 @@ class WifiSta : public WifiBase { } // NOTE: Deinit phase - // stop the wifi - logger_.debug("Stopping WiFi"); - esp_err_t err = esp_wifi_stop(); - if (err != ESP_OK) { - logger_.error("Could not stop WiFiSta: {}", esp_err_to_name(err)); + // Check if we're in APSTA mode - if so, just disconnect STA, don't stop WiFi entirely + wifi_mode_t mode; + esp_err_t err = esp_wifi_get_mode(&mode); + if (err == ESP_OK && mode == WIFI_MODE_APSTA) { + // In APSTA mode, just disconnect the STA interface + logger_.debug("In APSTA mode, disconnecting STA interface"); + esp_wifi_disconnect(); + // Switch to AP-only mode + err = esp_wifi_set_mode(WIFI_MODE_AP); + if (err != ESP_OK) { + logger_.error("Could not switch to AP mode: {}", esp_err_to_name(err)); + } + logger_.info("WiFi STA disconnected, AP still running"); + } else { + // In STA-only mode, stop WiFi entirely + logger_.debug("Stopping WiFi"); + err = esp_wifi_stop(); + if (err != ESP_OK) { + logger_.error("Could not stop WiFiSta: {}", esp_err_to_name(err)); + } + logger_.info("WiFi STA stopped"); } - logger_.info("WiFi STA stopped"); // Note: WiFi deinit and netif destruction are handled by Wifi singleton } @@ -364,8 +379,22 @@ class WifiSta : public WifiBase { memcpy(wifi_config.sta.bssid, config.ap_mac, 6); } - logger_.debug("Setting WiFi mode to STA"); - esp_err_t err = esp_wifi_set_mode(WIFI_MODE_STA); + // Get current mode and add STA to it if needed + wifi_mode_t current_mode; + esp_err_t err = esp_wifi_get_mode(¤t_mode); + wifi_mode_t new_mode = WIFI_MODE_STA; + if (err == ESP_OK) { + if (current_mode == WIFI_MODE_AP) { + new_mode = WIFI_MODE_APSTA; + logger_.debug("AP mode already active, setting mode to APSTA"); + } else if (current_mode == WIFI_MODE_APSTA) { + new_mode = WIFI_MODE_APSTA; + logger_.debug("APSTA mode already set"); + } + } + + logger_.debug("Setting WiFi mode to {}", new_mode); + err = esp_wifi_set_mode(new_mode); if (err != ESP_OK) { logger_.error("Could not set WiFi mode STA: {}", err); return false; From e9f7d034d7ce1418f75d910c980879e56b327013 Mon Sep 17 00:00:00 2001 From: William Emfinger Date: Wed, 21 Jan 2026 22:16:46 -0600 Subject: [PATCH 2/2] minor improvement to mode switch in init --- components/wifi/include/wifi_ap.hpp | 15 +++++++++------ components/wifi/include/wifi_sta.hpp | 14 +++++++++----- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/components/wifi/include/wifi_ap.hpp b/components/wifi/include/wifi_ap.hpp index 3a1912156..c6ce0229a 100644 --- a/components/wifi/include/wifi_ap.hpp +++ b/components/wifi/include/wifi_ap.hpp @@ -288,15 +288,18 @@ class WifiAp : public WifiBase { logger_.debug("STA mode already active, setting mode to APSTA"); } else if (current_mode == WIFI_MODE_APSTA) { new_mode = WIFI_MODE_APSTA; - logger_.debug("APSTA mode already set"); } } - logger_.debug("Setting WiFi mode to {}", new_mode); - err = esp_wifi_set_mode(new_mode); - if (err != ESP_OK) { - logger_.error("Could not set WiFi to AP: {}", err); - return false; + if (current_mode != new_mode) { + logger_.debug("Setting WiFi mode to {}", new_mode); + err = esp_wifi_set_mode(new_mode); + if (err != ESP_OK) { + logger_.error("Could not set WiFi to AP: {}", err); + return false; + } + } else { + logger_.debug("WiFi mode already set to {}", new_mode); } logger_.debug("Setting WiFi config"); diff --git a/components/wifi/include/wifi_sta.hpp b/components/wifi/include/wifi_sta.hpp index f3b1edcdc..8639e2e74 100644 --- a/components/wifi/include/wifi_sta.hpp +++ b/components/wifi/include/wifi_sta.hpp @@ -393,11 +393,15 @@ class WifiSta : public WifiBase { } } - logger_.debug("Setting WiFi mode to {}", new_mode); - err = esp_wifi_set_mode(new_mode); - if (err != ESP_OK) { - logger_.error("Could not set WiFi mode STA: {}", err); - return false; + if (current_mode != new_mode) { + logger_.debug("Setting WiFi mode to {}", new_mode); + err = esp_wifi_set_mode(new_mode); + if (err != ESP_OK) { + logger_.error("Could not set WiFi mode STA: {}", err); + return false; + } + } else { + logger_.debug("WiFi mode already set to {}", new_mode); } logger_.debug("Setting WiFi config");