From a1b9bedbe42b76305d2d9e4272878ff3bd90ed92 Mon Sep 17 00:00:00 2001 From: Felipe Moura Date: Thu, 6 Aug 2026 15:22:05 -0300 Subject: [PATCH] arch/[risc-v|xtensa]/espressif: reconnect Wi-Fi STA on AP-side disconnect The disconnect handler only reconnects when the reported reason is WIFI_REASON_ASSOC_LEAVE, so an AP-initiated deauth (beacon timeout, auth or assoc expire) leaves the station down forever. Restore the intent flag the driver used before 1f7c3a32e5 and 20ff68bd650, matching the ESP-IDF rule of reconnecting unless the disconnection was requested locally. Signed-off-by: Felipe Moura --- .../src/common/espressif/esp_wifi_api.c | 22 +++++++++++++++++++ .../src/common/espressif/esp_wifi_api.h | 12 ++++++++++ .../common/espressif/esp_wifi_event_handler.c | 14 ++++-------- .../src/common/espressif/esp_wifi_api.c | 22 +++++++++++++++++++ .../src/common/espressif/esp_wifi_api.h | 12 ++++++++++ .../common/espressif/esp_wifi_event_handler.c | 14 ++++-------- 6 files changed, 76 insertions(+), 20 deletions(-) diff --git a/arch/risc-v/src/common/espressif/esp_wifi_api.c b/arch/risc-v/src/common/espressif/esp_wifi_api.c index 5c2f6e611cc..3c60c3f3985 100644 --- a/arch/risc-v/src/common/espressif/esp_wifi_api.c +++ b/arch/risc-v/src/common/espressif/esp_wifi_api.c @@ -59,6 +59,18 @@ * Private Types ****************************************************************************/ +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifdef ESP_WLAN_HAS_STA + +/* Whether the station should reconnect after an unsolicited disconnection */ + +volatile bool g_sta_reconnect; + +#endif /* ESP_WLAN_HAS_STA */ + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -527,6 +539,8 @@ int esp_wifi_sta_connect(void) esp_wifi_lock(true); + g_sta_reconnect = true; + ret = esp_wifi_connect(); if (ret) { @@ -563,6 +577,12 @@ int esp_wifi_sta_disconnect(bool allow_reconnect) wifi_config_t wifi_config; esp_wifi_lock(true); + + /* WARNING: failure_retry_cnt has no documented effect unless scan_method + * is WIFI_ALL_CHANNEL_SCAN, which NuttX never selects. Reconnection is + * gated by g_sta_reconnect. + */ + esp_wifi_get_config(WIFI_IF_STA, &wifi_config); if (allow_reconnect) @@ -576,6 +596,8 @@ int esp_wifi_sta_disconnect(bool allow_reconnect) esp_wifi_set_config(WIFI_IF_STA, &wifi_config); + g_sta_reconnect = allow_reconnect; + ret = esp_wifi_disconnect(); if (ret) { diff --git a/arch/risc-v/src/common/espressif/esp_wifi_api.h b/arch/risc-v/src/common/espressif/esp_wifi_api.h index ceb482670b4..43a4fb66e87 100644 --- a/arch/risc-v/src/common/espressif/esp_wifi_api.h +++ b/arch/risc-v/src/common/espressif/esp_wifi_api.h @@ -35,6 +35,18 @@ #include "esp_wlan_netdev.h" +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifdef ESP_WLAN_HAS_STA + +/* Whether the station should reconnect after an unsolicited disconnection */ + +extern volatile bool g_sta_reconnect; + +#endif /* ESP_WLAN_HAS_STA */ + /**************************************************************************** * Public Function Prototypes ****************************************************************************/ diff --git a/arch/risc-v/src/common/espressif/esp_wifi_event_handler.c b/arch/risc-v/src/common/espressif/esp_wifi_event_handler.c index 67273a9c220..eb64138b551 100644 --- a/arch/risc-v/src/common/espressif/esp_wifi_event_handler.c +++ b/arch/risc-v/src/common/espressif/esp_wifi_event_handler.c @@ -86,11 +86,8 @@ static bool g_wifi_handler_registered; * Name: esp_reconnect_work_cb * * Description: - * Function called by a work queue to reconnect to Wi-Fi in case of - * a disconnection event and WIFI_REASON_ASSOC_LEAVE reason. - * Must check if the failure_retry_cnt is not 0, otherwise it may - * reconnect when not desired, such as when the user has actually - * asked to disconnect from the AP. + * Function called by a work queue to reconnect the Wi-Fi station after an + * unsolicited disconnection. * * Input Parameters: * arg - Unused work queue argument. @@ -104,12 +101,9 @@ static void esp_reconnect_work_cb(void *arg) { UNUSED(arg); int ret; - wifi_config_t wifi_config; - esp_wifi_get_config(WIFI_IF_STA, &wifi_config); - if (wifi_config.sta.failure_retry_cnt == 0) + if (!g_sta_reconnect) { - wlinfo("Reconnect to Wi-Fi on callback: failure_retry_cnt is 0\n"); return; } @@ -206,7 +200,7 @@ static void esp_wifi_event_handler(void *arg, esp_event_base_t event_base, wlinfo("Wi-Fi station disconnected, reason: %u\n", reason); esp_wlan_sta_disconnect_hook(); - if (reason == WIFI_REASON_ASSOC_LEAVE) + if (g_sta_reconnect) { work_queue(LPWORK, &g_wifi_reconnect_work, esp_reconnect_work_cb, NULL, 0); diff --git a/arch/xtensa/src/common/espressif/esp_wifi_api.c b/arch/xtensa/src/common/espressif/esp_wifi_api.c index 8904a588789..b9486093995 100644 --- a/arch/xtensa/src/common/espressif/esp_wifi_api.c +++ b/arch/xtensa/src/common/espressif/esp_wifi_api.c @@ -59,6 +59,18 @@ * Private Types ****************************************************************************/ +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifdef ESP_WLAN_HAS_STA + +/* Whether the station should reconnect after an unsolicited disconnection */ + +volatile bool g_sta_reconnect; + +#endif /* ESP_WLAN_HAS_STA */ + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -680,6 +692,8 @@ int esp_wifi_sta_connect(void) esp_wifi_lock(true); + g_sta_reconnect = true; + ret = esp_wifi_connect(); if (ret != 0) { @@ -716,6 +730,12 @@ int esp_wifi_sta_disconnect(bool allow_reconnect) wifi_config_t wifi_config; esp_wifi_lock(true); + + /* WARNING: failure_retry_cnt has no documented effect unless scan_method + * is WIFI_ALL_CHANNEL_SCAN, which NuttX never selects. Reconnection is + * gated by g_sta_reconnect. + */ + esp_wifi_get_config(WIFI_IF_STA, &wifi_config); if (allow_reconnect) @@ -729,6 +749,8 @@ int esp_wifi_sta_disconnect(bool allow_reconnect) esp_wifi_set_config(WIFI_IF_STA, &wifi_config); + g_sta_reconnect = allow_reconnect; + ret = esp_wifi_disconnect(); if (ret != 0) { diff --git a/arch/xtensa/src/common/espressif/esp_wifi_api.h b/arch/xtensa/src/common/espressif/esp_wifi_api.h index 6e57cc340bb..2b15405203c 100644 --- a/arch/xtensa/src/common/espressif/esp_wifi_api.h +++ b/arch/xtensa/src/common/espressif/esp_wifi_api.h @@ -35,6 +35,18 @@ #include "esp_wlan_netdev.h" +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifdef ESP_WLAN_HAS_STA + +/* Whether the station should reconnect after an unsolicited disconnection */ + +extern volatile bool g_sta_reconnect; + +#endif /* ESP_WLAN_HAS_STA */ + /**************************************************************************** * Public Function Prototypes ****************************************************************************/ diff --git a/arch/xtensa/src/common/espressif/esp_wifi_event_handler.c b/arch/xtensa/src/common/espressif/esp_wifi_event_handler.c index 1e75b8554d5..4fee304e5c1 100644 --- a/arch/xtensa/src/common/espressif/esp_wifi_event_handler.c +++ b/arch/xtensa/src/common/espressif/esp_wifi_event_handler.c @@ -86,11 +86,8 @@ static bool g_wifi_handler_registered; * Name: esp_reconnect_work_cb * * Description: - * Function called by a work queue to reconnect to Wi-Fi in case of - * a disconnection event and WIFI_REASON_ASSOC_LEAVE reason. - * Must check if the failure_retry_cnt is not 0, otherwise it may - * reconnect when not desired, such as when the user has actually - * asked to disconnect from the AP. + * Function called by a work queue to reconnect the Wi-Fi station after an + * unsolicited disconnection. * * Input Parameters: * arg - Unused work queue argument. @@ -105,12 +102,9 @@ static void esp_reconnect_work_cb(void *arg) { UNUSED(arg); int ret; - wifi_config_t wifi_config; - esp_wifi_get_config(WIFI_IF_STA, &wifi_config); - if (wifi_config.sta.failure_retry_cnt == 0) + if (!g_sta_reconnect) { - wlinfo("Reconnect to Wi-Fi on callback: failure_retry_cnt is 0\n"); return; } @@ -202,7 +196,7 @@ static void esp_wifi_event_handler(void *arg, esp_event_base_t event_base, wlinfo("Wi-Fi station disconnected, reason: %u\n", reason); esp_wlan_sta_disconnect_hook(); - if (reason == WIFI_REASON_ASSOC_LEAVE) + if (g_sta_reconnect) { work_queue(LPWORK, &g_wifi_reconnect_work, esp_reconnect_work_cb, NULL, 0);