Merge branch 'bugfix/roaming_app_support_wifi_disconnect' into 'master'

Stops roaming app upon application initiated disconnect

Closes WIFIBUG-551 and WIFIBUG-636

See merge request espressif/esp-idf!30738
This commit is contained in:
Jiang Jiang Jian
2024-09-11 16:10:33 +08:00
9 changed files with 118 additions and 34 deletions

View File

@@ -750,6 +750,33 @@ esp_err_t esp_nan_internal_datapath_resp(wifi_nan_datapath_resp_t *resp);
*/ */
esp_err_t esp_nan_internal_datapath_end(wifi_nan_datapath_end_req_t *req); esp_err_t esp_nan_internal_datapath_end(wifi_nan_datapath_end_req_t *req);
/**
* @brief Connect WiFi station to the AP.
*
* @attention 1. This API only impact WIFI_MODE_STA or WIFI_MODE_APSTA mode
*
* @return
* - ESP_OK: succeed
* - ESP_ERR_WIFI_NOT_INIT: WiFi is not initialized by esp_wifi_init
* - ESP_ERR_WIFI_NOT_STARTED: WiFi is not started by esp_wifi_start
* - ESP_ERR_WIFI_MODE: WiFi mode error
* - ESP_ERR_WIFI_CONN: WiFi internal error, station or soft-AP control block wrong
* - ESP_ERR_WIFI_SSID: SSID of AP which station connects is invalid
*/
esp_err_t esp_wifi_connect_internal(void);
/**
* @brief Disconnect WiFi station from the AP.
*
* @return
* - ESP_OK: succeed
* - ESP_ERR_WIFI_NOT_INIT: WiFi was not initialized by esp_wifi_init
* - ESP_ERR_WIFI_NOT_STARTED: WiFi was not started by esp_wifi_start
* - ESP_FAIL: other WiFi internal errors
*
*/
esp_err_t esp_wifi_disconnect_internal(void);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@@ -38,6 +38,10 @@
#include "esp_private/sleep_retention.h" #include "esp_private/sleep_retention.h"
#endif #endif
#if CONFIG_ESP_WIFI_ENABLE_ROAMING_APP
#include "esp_roaming.h"
#endif
static bool s_wifi_inited = false; static bool s_wifi_inited = false;
#if (CONFIG_ESP_WIFI_RX_BA_WIN > CONFIG_ESP_WIFI_DYNAMIC_RX_BUFFER_NUM) #if (CONFIG_ESP_WIFI_RX_BA_WIN > CONFIG_ESP_WIFI_DYNAMIC_RX_BUFFER_NUM)
@@ -176,6 +180,11 @@ static esp_err_t wifi_deinit_internal(void)
#endif #endif
esp_supplicant_deinit(); esp_supplicant_deinit();
#if CONFIG_ESP_WIFI_ENABLE_ROAMING_APP
deinit_roaming_app();
#endif
err = esp_wifi_deinit_internal(); err = esp_wifi_deinit_internal();
if (err != ESP_OK) { if (err != ESP_OK) {
ESP_LOGE(TAG, "Failed to deinit Wi-Fi driver (0x%x)", err); ESP_LOGE(TAG, "Failed to deinit Wi-Fi driver (0x%x)", err);
@@ -435,6 +444,11 @@ esp_err_t esp_wifi_init(const wifi_init_config_t *config)
ESP_LOGE(TAG, "Failed to init supplicant (0x%x)", result); ESP_LOGE(TAG, "Failed to init supplicant (0x%x)", result);
goto _deinit; goto _deinit;
} }
#if CONFIG_ESP_WIFI_ENABLE_ROAMING_APP
init_roaming_app();
#endif
} else { } else {
goto _deinit; goto _deinit;
} }
@@ -464,6 +478,28 @@ _deinit:
return result; return result;
} }
esp_err_t esp_wifi_connect(void)
{
esp_err_t ret = ESP_OK;
ret = esp_wifi_connect_internal();
#if CONFIG_ESP_WIFI_ENABLE_ROAMING_APP
roaming_app_enable_reconnect();
#endif
return ret;
}
esp_err_t esp_wifi_disconnect(void)
{
esp_err_t ret = ESP_OK;
ret = esp_wifi_disconnect_internal();
#if CONFIG_ESP_WIFI_ENABLE_ROAMING_APP
roaming_app_disable_reconnect();
#endif
return ret;
}
#ifdef CONFIG_PM_ENABLE #ifdef CONFIG_PM_ENABLE
void wifi_apb80m_request(void) void wifi_apb80m_request(void)
{ {

View File

@@ -112,6 +112,7 @@ struct roaming_app {
#if PERIODIC_SCAN_MONITORING #if PERIODIC_SCAN_MONITORING
bool periodic_scan_active; bool periodic_scan_active;
#endif #endif
bool allow_reconnect;
}; };
void init_roaming_app(void); void init_roaming_app(void);
@@ -126,6 +127,9 @@ void roaming_app_periodic_scan_internal_handler(void *data, void *ctx);
#endif /*PERIODIC_SCAN_ROAM_MONITORING*/ #endif /*PERIODIC_SCAN_ROAM_MONITORING*/
void roaming_app_trigger_roam_internal_handler(void *data, void *ctx); void roaming_app_trigger_roam_internal_handler(void *data, void *ctx);
void roaming_app_disable_reconnect(void);
void roaming_app_enable_reconnect(void);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@@ -50,6 +50,19 @@ static inline long time_diff_sec(struct timeval *a, struct timeval *b)
{ {
return (a->tv_sec - b->tv_sec); return (a->tv_sec - b->tv_sec);
} }
void roaming_app_disable_reconnect(void)
{
ESP_LOGD(ROAMING_TAG, "Switching off reconnect due to application trigerred disconnect");
g_roaming_app.allow_reconnect = false;
}
void roaming_app_enable_reconnect(void)
{
ESP_LOGD(ROAMING_TAG, "Switching on reconnect due to application trigerred reconnect");
g_roaming_app.allow_reconnect = true;
}
static void roaming_app_get_ap_info(wifi_ap_record_t *ap_info) static void roaming_app_get_ap_info(wifi_ap_record_t *ap_info)
{ {
esp_wifi_sta_get_ap_info(ap_info); esp_wifi_sta_get_ap_info(ap_info);
@@ -65,6 +78,7 @@ static void roaming_app_get_ap_info(wifi_ap_record_t *ap_info)
} }
#endif /*LOW_RSSI_ROAMING_ENABLED*/ #endif /*LOW_RSSI_ROAMING_ENABLED*/
} }
#if LEGACY_ROAM_ENABLED #if LEGACY_ROAM_ENABLED
static void legacy_roam_clear_bssid_flag(void) static void legacy_roam_clear_bssid_flag(void)
{ {
@@ -145,6 +159,8 @@ static void roaming_app_disconnected_event_handler(void* arg, esp_event_base_t e
ESP_LOGD(ROAMING_TAG, "station got disconnected reason=%d", disconn->reason); ESP_LOGD(ROAMING_TAG, "station got disconnected reason=%d", disconn->reason);
if (disconn->reason == WIFI_REASON_ROAMING) { if (disconn->reason == WIFI_REASON_ROAMING) {
ESP_LOGD(ROAMING_TAG, "station roaming, do nothing"); ESP_LOGD(ROAMING_TAG, "station roaming, do nothing");
} else if (g_roaming_app.allow_reconnect == false) {
ESP_LOGD(ROAMING_TAG, "station initiated disconnect, do nothing");
} else { } else {
#if LEGACY_ROAM_ENABLED #if LEGACY_ROAM_ENABLED
/* /*
@@ -160,6 +176,12 @@ static void roaming_app_disconnected_event_handler(void* arg, esp_event_base_t e
} }
} }
static void roaming_app_sta_stop_event_handler(void* arg, esp_event_base_t event_base,
int32_t event_id, void* event_data)
{
g_roaming_app.allow_reconnect = false;
}
static void roaming_app_connected_event_handler(void* arg, esp_event_base_t event_base, static void roaming_app_connected_event_handler(void* arg, esp_event_base_t event_base,
int32_t event_id, void* event_data) int32_t event_id, void* event_data)
{ {
@@ -198,6 +220,7 @@ static void roaming_app_connected_event_handler(void* arg, esp_event_base_t even
#if LEGACY_ROAM_ENABLED #if LEGACY_ROAM_ENABLED
g_roaming_app.force_roam_ongoing = true; g_roaming_app.force_roam_ongoing = true;
#endif /*LEGACY_ROAM_ENABLED*/ #endif /*LEGACY_ROAM_ENABLED*/
g_roaming_app.allow_reconnect = true;
} }
#define MAX_NEIGHBOR_LEN 512 #define MAX_NEIGHBOR_LEN 512
#if PERIODIC_RRM_MONITORING #if PERIODIC_RRM_MONITORING
@@ -475,8 +498,6 @@ static void periodic_rrm_request(struct timeval *now)
g_roaming_app.rrm_request_active = true; g_roaming_app.rrm_request_active = true;
} }
} }
#else
static void periodic_rrm_request(struct timeval *now) { }
#endif #endif
static bool candidate_security_match(wifi_ap_record_t candidate) static bool candidate_security_match(wifi_ap_record_t candidate)
@@ -763,7 +784,7 @@ esp_err_t init_scan_params(void)
void init_roaming_app(void) void init_roaming_app(void)
{ {
#if !LOW_RSSI_ROAMING_ENABLED && !PERIODIC_SCAN_MONITORING #if !LOW_RSSI_ROAMING_ENABLED && !PERIODIC_SCAN_MONITORING
ESP_LOGE(ROAMING_TAG, "No roaming method enabled. Roaming app cannot be initialized"); ESP_LOGE(ROAMING_TAG, "No roaming trigger enabled. Roaming app cannot be initialized");
return; return;
#endif #endif
@@ -773,6 +794,7 @@ void init_roaming_app(void)
#endif #endif
ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_CONNECTED, roaming_app_connected_event_handler, NULL)); ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_CONNECTED, roaming_app_connected_event_handler, NULL));
ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_DISCONNECTED, roaming_app_disconnected_event_handler, NULL)); ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_DISCONNECTED, roaming_app_disconnected_event_handler, NULL));
ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_STOP, roaming_app_sta_stop_event_handler, NULL));
#if LOW_RSSI_ROAMING_ENABLED #if LOW_RSSI_ROAMING_ENABLED
ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_BSS_RSSI_LOW, ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_BSS_RSSI_LOW,
&roaming_app_rssi_low_handler, NULL)); &roaming_app_rssi_low_handler, NULL));
@@ -799,6 +821,7 @@ void deinit_roaming_app(void)
/* Unregister Event handlers */ /* Unregister Event handlers */
ESP_ERROR_CHECK(esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_STA_CONNECTED, roaming_app_connected_event_handler)); ESP_ERROR_CHECK(esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_STA_CONNECTED, roaming_app_connected_event_handler));
ESP_ERROR_CHECK(esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_STA_DISCONNECTED, roaming_app_disconnected_event_handler)); ESP_ERROR_CHECK(esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_STA_DISCONNECTED, roaming_app_disconnected_event_handler));
ESP_ERROR_CHECK(esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_STA_STOP, roaming_app_sta_stop_event_handler));
#if LOW_RSSI_ROAMING_ENABLED #if LOW_RSSI_ROAMING_ENABLED
ESP_ERROR_CHECK(esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_STA_BSS_RSSI_LOW, ESP_ERROR_CHECK(esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_STA_BSS_RSSI_LOW,
&roaming_app_rssi_low_handler)); &roaming_app_rssi_low_handler));

View File

@@ -427,9 +427,6 @@ void esp_supplicant_common_deinit(void)
} }
s_supplicant_task_init_done = false; s_supplicant_task_init_done = false;
#endif /* CONFIG_SUPPLICANT_TASK */ #endif /* CONFIG_SUPPLICANT_TASK */
#if CONFIG_ESP_WIFI_ENABLE_ROAMING_APP
deinit_roaming_app();
#endif
#endif /* defined(CONFIG_IEEE80211KV) || defined(CONFIG_IEEE80211R) */ #endif /* defined(CONFIG_IEEE80211KV) || defined(CONFIG_IEEE80211R) */
} }
@@ -744,15 +741,6 @@ static uint8_t get_extended_caps_ie(uint8_t *ie, size_t len)
} }
#else /* CONFIG_IEEE80211KV */ #else /* CONFIG_IEEE80211KV */
bool esp_rrm_is_rrm_supported_connection(void)
{
return false;
}
bool esp_wnm_is_btm_supported_connection(void)
{
return false;
}
#endif /* CONFIG_IEEE80211KV */ #endif /* CONFIG_IEEE80211KV */
void esp_set_scan_ie(void) void esp_set_scan_ie(void)
@@ -920,6 +908,20 @@ int esp_supplicant_post_evt(uint32_t evt_id, uint32_t data)
} }
#endif /* CONFIG_SUPPLICANT_TASK */ #endif /* CONFIG_SUPPLICANT_TASK */
#else /* defined(CONFIG_IEEE80211KV) || defined(CONFIG_IEEE80211R) */ #else /* defined(CONFIG_IEEE80211KV) || defined(CONFIG_IEEE80211R) */
void esp_set_scan_ie(void) { }
#endif /* defined(CONFIG_IEEE80211KV) || defined(CONFIG_IEEE80211R) */
#ifndef CONFIG_IEEE80211KV
bool esp_rrm_is_rrm_supported_connection(void)
{
return false;
}
bool esp_wnm_is_btm_supported_connection(void)
{
return false;
}
int esp_rrm_send_neighbor_report_request(void) int esp_rrm_send_neighbor_report_request(void)
{ {
return -1; return -1;
@@ -937,8 +939,7 @@ int esp_wnm_send_bss_transition_mgmt_query(enum btm_query_reason query_reason,
return -1; return -1;
} }
void esp_set_scan_ie(void) { } #endif /* !CONFIG_IEEE80211KV */
#endif /* defined(CONFIG_IEEE80211KV) || defined(CONFIG_IEEE80211R) */
#if defined(CONFIG_IEEE80211KV) || defined(CONFIG_IEEE80211R) || defined(CONFIG_WPA3_SAE) #if defined(CONFIG_IEEE80211KV) || defined(CONFIG_IEEE80211R) || defined(CONFIG_WPA3_SAE)
void esp_set_assoc_ie(uint8_t *bssid, const u8 *ies, size_t ies_len, bool mdie) void esp_set_assoc_ie(uint8_t *bssid, const u8 *ies, size_t ies_len, bool mdie)

View File

@@ -481,6 +481,7 @@ int esp_supplicant_init(void)
#ifdef CONFIG_OWE_STA #ifdef CONFIG_OWE_STA
esp_wifi_register_owe_cb(wpa_cb); esp_wifi_register_owe_cb(wpa_cb);
#endif /* CONFIG_OWE_STA */ #endif /* CONFIG_OWE_STA */
eloop_init(); eloop_init();
ret = esp_supplicant_common_init(wpa_cb); ret = esp_supplicant_common_init(wpa_cb);
@@ -494,10 +495,6 @@ int esp_supplicant_init(void)
ret = esp_wifi_internal_wapi_init(); ret = esp_wifi_internal_wapi_init();
#endif #endif
#if CONFIG_ESP_WIFI_ENABLE_ROAMING_APP
init_roaming_app();
#endif
return ret; return ret;
} }

View File

@@ -46,7 +46,12 @@ static void example_handler_on_wifi_disconnect(void *arg, esp_event_base_t event
example_wifi_sta_do_disconnect(); example_wifi_sta_do_disconnect();
return; return;
} }
ESP_LOGI(TAG, "Wi-Fi disconnected, trying to reconnect..."); wifi_event_sta_disconnected_t *disconn = event_data;
if (disconn->reason == WIFI_REASON_ROAMING) {
ESP_LOGD(TAG, "station roaming, do nothing");
return;
}
ESP_LOGI(TAG, "Wi-Fi disconnected %d, trying to reconnect...", disconn->reason);
esp_err_t err = esp_wifi_connect(); esp_err_t err = esp_wifi_connect();
if (err == ESP_ERR_WIFI_NOT_STARTED) { if (err == ESP_ERR_WIFI_NOT_STARTED) {
return; return;

View File

@@ -43,8 +43,6 @@ static EventGroupHandle_t s_wifi_event_group;
#define MAXIMUM_RETRY 5 #define MAXIMUM_RETRY 5
const char *TAG = "wifi roaming app"; const char *TAG = "wifi roaming app";
static int s_retry_num = 0;
static void event_handler(void* arg, esp_event_base_t event_base, static void event_handler(void* arg, esp_event_base_t event_base,
int32_t event_id, void* event_data) int32_t event_id, void* event_data)
{ {
@@ -55,19 +53,12 @@ static void event_handler(void* arg, esp_event_base_t event_base,
if (disconn->reason == WIFI_REASON_ROAMING) { if (disconn->reason == WIFI_REASON_ROAMING) {
ESP_LOGI(TAG, "station disconnected during roaming"); ESP_LOGI(TAG, "station disconnected during roaming");
} else { } else {
if (s_retry_num < MAXIMUM_RETRY) { ESP_LOGI(TAG, "station disconnected with reason %d", disconn->reason);
ESP_LOGI(TAG, "station disconnected with reason %d", disconn->reason); xEventGroupSetBits(s_wifi_event_group, WIFI_FAIL_BIT);
esp_wifi_connect();
s_retry_num++;
ESP_LOGI(TAG, "retry to connect to the AP");
} else {
xEventGroupSetBits(s_wifi_event_group, WIFI_FAIL_BIT);
}
} }
} else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) { } else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {
ip_event_got_ip_t* event = (ip_event_got_ip_t*) event_data; ip_event_got_ip_t* event = (ip_event_got_ip_t*) event_data;
ESP_LOGI(TAG, "got ip:" IPSTR, IP2STR(&event->ip_info.ip)); ESP_LOGI(TAG, "got ip:" IPSTR, IP2STR(&event->ip_info.ip));
s_retry_num = 0;
xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT); xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT);
} }
} }