From 9e6700110afcb84dfc63ebd44f557a7c53eca592 Mon Sep 17 00:00:00 2001 From: Kapil Gupta Date: Tue, 29 Oct 2024 23:53:55 +0530 Subject: [PATCH] fix(wifi): Fix some issues observed in roaming app --- .../roaming_app/include/esp_roaming.h | 32 +++- .../wifi_apps/roaming_app/src/roaming_app.c | 141 +++++++++++++----- components/wpa_supplicant/port/eloop.c | 1 + 3 files changed, 134 insertions(+), 40 deletions(-) diff --git a/components/esp_wifi/wifi_apps/roaming_app/include/esp_roaming.h b/components/esp_wifi/wifi_apps/roaming_app/include/esp_roaming.h index 8fa7402e6a..64b4575937 100644 --- a/components/esp_wifi/wifi_apps/roaming_app/include/esp_roaming.h +++ b/components/esp_wifi/wifi_apps/roaming_app/include/esp_roaming.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -46,12 +46,24 @@ extern "C" { #define MAX_CANDIDATE_COUNT CONFIG_ESP_WIFI_ROAMING_MAX_CANDIDATES /* Legacy roaming configuration */ +#ifdef CONFIG_ESP_WIFI_ROAMING_LEGACY_ROAMING #define LEGACY_ROAM_ENABLED CONFIG_ESP_WIFI_ROAMING_LEGACY_ROAMING +#else +#define LEGACY_ROAM_ENABLED 0 +#endif +#ifdef CONFIG_ESP_WIFI_NETWORK_ASSISTED_ROAMING_RETRY_COUNT #define BSS_TM_RETRY_COUNT CONFIG_ESP_WIFI_NETWORK_ASSISTED_ROAMING_RETRY_COUNT +#else +#define BSS_TM_RETRY_COUNT 0 +#endif /* Network Assisted Roaming */ +#ifdef CONFIG_ESP_WIFI_ROAMING_NETWORK_ASSISTED_ROAM #define NETWORK_ASSISTED_ROAMING_ENABLED CONFIG_ESP_WIFI_ROAMING_NETWORK_ASSISTED_ROAM +#else +#define NETWORK_ASSISTED_ROAMING_ENABLED 0 +#endif /* Periodic RRM configuration */ #define PERIODIC_RRM_MONITORING CONFIG_ESP_WIFI_ROAMING_PERIODIC_RRM_MONITORING @@ -85,8 +97,26 @@ struct cand_bss { uint8_t bssid[ETH_ALEN]; }; +struct roam_config { + uint8_t backoff_time; + bool low_rssi_roam_trigger; + uint8_t low_rssi_threshold; + uint8_t rssi_threshold_reduction_offset; + bool scan_monitor; + uint8_t scan_interval; + uint8_t scan_rssi_threshold; + uint8_t scan_rssi_diff; + bool legacy_roam_enabled; + uint8_t btm_retry_cnt; + bool btm_roaming_enabled; + bool rrm_monitor; + uint8_t rrm_monitor_time; + uint8_t rrm_monitor_rssi_threshold; +}; + struct roaming_app { wifi_scan_config_t scan_params; + struct roam_config config; bool scan_ongoing; int8_t current_rssi_threshold; char *btm_neighbor_list; diff --git a/components/esp_wifi/wifi_apps/roaming_app/src/roaming_app.c b/components/esp_wifi/wifi_apps/roaming_app/src/roaming_app.c index e7ca6cbc53..8c00e6c6cc 100644 --- a/components/esp_wifi/wifi_apps/roaming_app/src/roaming_app.c +++ b/components/esp_wifi/wifi_apps/roaming_app/src/roaming_app.c @@ -71,10 +71,10 @@ static void roaming_app_get_ap_info(wifi_ap_record_t *ap_info) * If the current rssi is below the configured rssi threshold for * low rssi based roaming and the current rssi threshold is below that, * we should reset the rssi threshold back to the configured rssi threshold */ - if ((ap_info->rssi > ROAMING_LOW_RSSI_THRESHOLD) && (g_roaming_app.current_low_rssi_threshold < ROAMING_LOW_RSSI_THRESHOLD)) { - g_roaming_app.current_low_rssi_threshold = ROAMING_LOW_RSSI_THRESHOLD; - esp_wifi_set_rssi_threshold(ROAMING_LOW_RSSI_THRESHOLD); - ESP_LOGD(ROAMING_TAG, "Reset the low rssi threshold back to %d", ROAMING_LOW_RSSI_THRESHOLD); + if ((ap_info->rssi > g_roaming_app.config.low_rssi_threshold) && (g_roaming_app.current_low_rssi_threshold < g_roaming_app.config.low_rssi_threshold)) { + g_roaming_app.current_low_rssi_threshold = g_roaming_app.config.low_rssi_threshold; + esp_wifi_set_rssi_threshold(g_roaming_app.config.low_rssi_threshold); + ESP_LOGD(ROAMING_TAG, "Reset the low rssi threshold back to %d", g_roaming_app.config.low_rssi_threshold); } #endif /*LOW_RSSI_ROAMING_ENABLED*/ } @@ -118,6 +118,10 @@ static int8_t initialize_roaming_event(void) #if PERIODIC_RRM_MONITORING static void init_periodic_rrm_event(void) { + if (!g_roaming_app.config.rrm_monitor) { + ESP_LOGI(ROAMING_TAG, "RRM monitor is disabled in config"); + return; + } if (!neighbor_list_lock) { neighbor_list_lock = os_recursive_mutex_create(); if (!neighbor_list_lock) { @@ -126,7 +130,7 @@ static void init_periodic_rrm_event(void) } ESP_LOGV(ROAMING_TAG, "Initialised Periodic RRM Monitoring event!"); g_roaming_app.periodic_rrm_active = true; - if (eloop_register_timeout(RRM_MONITOR_TIME, 0, roaming_app_periodic_rrm_internal_handler, NULL, NULL)) { + if (eloop_register_timeout(g_roaming_app.config.rrm_monitor_time, 0, roaming_app_periodic_rrm_internal_handler, NULL, NULL)) { ESP_LOGE(ROAMING_TAG, "Could not register periodic neighbor report event."); } } @@ -135,9 +139,13 @@ static void init_periodic_rrm_event(void) #if PERIODIC_SCAN_MONITORING static void init_periodic_scan_roam_event(void) { + if (!g_roaming_app.config.scan_monitor) { + ESP_LOGI(ROAMING_TAG, "%s: Scan monitor is disabled in config", __func__); + return; + } ESP_LOGV(ROAMING_TAG, "Initialised Periodic Scan Roam event!"); g_roaming_app.periodic_scan_active = true; - if (eloop_register_timeout(SCAN_MONITOR_INTERVAL, 0, roaming_app_periodic_scan_internal_handler, NULL, NULL)) { + if (eloop_register_timeout(g_roaming_app.config.scan_interval, 0, roaming_app_periodic_scan_internal_handler, NULL, NULL)) { ESP_LOGE(ROAMING_TAG, "Could not register periodic scan monitoring event"); } } @@ -185,15 +193,15 @@ static void roaming_app_sta_stop_event_handler(void* arg, esp_event_base_t event static void roaming_app_connected_event_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data) { -#if LOW_RSSI_ROAMING_ENABLED roaming_app_get_ap_info(&g_roaming_app.ap_info); g_roaming_app.scan_params.ssid = g_roaming_app.ap_info.ssid; - if (g_roaming_app.ap_info.rssi < ROAMING_LOW_RSSI_THRESHOLD) { +#if LOW_RSSI_ROAMING_ENABLED + if (g_roaming_app.ap_info.rssi < g_roaming_app.config.low_rssi_threshold) { /* To ensure that the threshold is set to one offset below the current AP RSSI * in case, the AP is already below the RSSI threshold */ - g_roaming_app.current_low_rssi_threshold = g_roaming_app.ap_info.rssi - RSSI_THRESHOLD_REDUCTION_OFFSET; + g_roaming_app.current_low_rssi_threshold = g_roaming_app.ap_info.rssi - g_roaming_app.config.rssi_threshold_reduction_offset; } else { - g_roaming_app.current_low_rssi_threshold = ROAMING_LOW_RSSI_THRESHOLD; + g_roaming_app.current_low_rssi_threshold = g_roaming_app.config.low_rssi_threshold; } ESP_LOGD(ROAMING_TAG, "setting rssi threshold as %d", g_roaming_app.current_low_rssi_threshold); esp_wifi_set_rssi_threshold(g_roaming_app.current_low_rssi_threshold); @@ -218,7 +226,7 @@ static void roaming_app_connected_event_handler(void* arg, esp_event_base_t even ESP_LOGE(ROAMING_TAG, "Failed to Initialise roaming events"); } #if LEGACY_ROAM_ENABLED - g_roaming_app.force_roam_ongoing = true; + g_roaming_app.force_roam_ongoing = false; #endif /*LEGACY_ROAM_ENABLED*/ g_roaming_app.allow_reconnect = true; } @@ -359,6 +367,7 @@ static void roaming_app_neighbor_report_recv_handler(void* arg, esp_event_base_t } #endif /*PERIODIC_RRM_MONITORING*/ + #if LOW_RSSI_ROAMING_ENABLED static void roaming_app_rssi_low_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data) { @@ -367,7 +376,7 @@ static void roaming_app_rssi_low_handler(void* arg, esp_event_base_t event_base, roaming_app_get_ap_info(&g_roaming_app.ap_info); determine_best_ap(0); - g_roaming_app.current_low_rssi_threshold -= RSSI_THRESHOLD_REDUCTION_OFFSET; + g_roaming_app.current_low_rssi_threshold -= g_roaming_app.config.rssi_threshold_reduction_offset; ESP_LOGD(ROAMING_TAG, "Resetting RSSI Threshold to %d", g_roaming_app.current_low_rssi_threshold); esp_wifi_set_rssi_threshold(g_roaming_app.current_low_rssi_threshold); @@ -388,8 +397,9 @@ static void trigger_network_assisted_roam(void) #endif /*PERIODIC_RRM_MONITORING*/ ESP_LOGD(ROAMING_TAG, "Sent BTM Query"); gettimeofday(&g_roaming_app.last_roamed_time, NULL); +#if LEGACY_ROAM_ENABLED g_roaming_app.btm_attempt++; - +#endif } #endif /*NETWORK_ASSISTED_ROAMING*/ @@ -415,14 +425,14 @@ void roaming_app_trigger_roam(struct cand_bss *bss) struct timeval now; gettimeofday(&now, NULL); ESP_LOGD(ROAMING_TAG,"Processing trigger roaming request."); - if (time_diff_sec(&now, &g_roaming_app.last_roamed_time) < ROAMING_BACKOFF_TIME ) { + if (time_diff_sec(&now, &g_roaming_app.last_roamed_time) < g_roaming_app.config.backoff_time ) { ESP_LOGD(ROAMING_TAG,"Ignoring request as time difference to last request is %ld",time_diff_sec(&now, &g_roaming_app.last_roamed_time)); goto free_bss; } #if NETWORK_ASSISTED_ROAMING_ENABLED - if (g_roaming_app.btm_support) { + if (g_roaming_app.config.btm_roaming_enabled && g_roaming_app.btm_support) { #if LEGACY_ROAM_ENABLED && NETWORK_ASSISTED_ROAMING_ENABLED - if (g_roaming_app.btm_attempt <= BSS_TM_RETRY_COUNT) { + if (g_roaming_app.btm_attempt <= g_roaming_app.config.btm_retry_cnt) { #endif trigger_network_assisted_roam(); goto free_bss; @@ -435,7 +445,9 @@ void roaming_app_trigger_roam(struct cand_bss *bss) } #endif /*NETWORK_ASSISTED_ROAMING_ENABLED*/ #if LEGACY_ROAM_ENABLED - trigger_legacy_roam(bss); + if (g_roaming_app.config.legacy_roam_enabled) { + trigger_legacy_roam(bss); + } #endif /*LEGACY_ROAM_ENABLED*/ free_bss : os_free(bss); @@ -490,7 +502,7 @@ void print_ap_records(struct scanned_ap_info *ap_info) static void periodic_rrm_request(struct timeval *now) { roaming_app_get_ap_info(&g_roaming_app.ap_info); - if (esp_rrm_is_rrm_supported_connection() && (g_roaming_app.ap_info.rssi < RRM_MONITOR_RSSI_THRESHOLD)) { + if (esp_rrm_is_rrm_supported_connection() && (g_roaming_app.ap_info.rssi < g_roaming_app.config.rrm_monitor_rssi_threshold)) { if (esp_rrm_send_neighbor_report_request() < 0) { ESP_LOGE(ROAMING_TAG, "failed to send neighbor report request"); return; @@ -643,18 +655,19 @@ static void periodic_scan_roam(struct timeval *now) * as the results produced by a scan at this time would not be used by * supplicant to build candidate lists. * */ - if (time_diff_sec(now, &g_roaming_app.last_roamed_time) < ROAMING_BACKOFF_TIME - SUPPLICANT_CANDIDATE_LIST_EXPIRY) { + if (time_diff_sec(now, &g_roaming_app.last_roamed_time) < g_roaming_app.config.backoff_time - SUPPLICANT_CANDIDATE_LIST_EXPIRY) { return; } #endif /*NETWORK_ASSISTED_ROAMING_ENABLED && !LEGACY_ROAM_ENABLED*/ /* If the current RSSI is not worse than the configured threshold * for station initiated roam, then do not trigger roam */ roaming_app_get_ap_info(&g_roaming_app.ap_info); - if (g_roaming_app.ap_info.rssi > SCAN_MONITOR_RSSI_THRESHOLD) { + ESP_LOGD(ROAMING_TAG, "Connected AP's RSSI=%d", g_roaming_app.ap_info.rssi); + if (g_roaming_app.ap_info.rssi > g_roaming_app.config.scan_rssi_threshold) { return; } - determine_best_ap(SCAN_ROAM_RSSI_DIFF - 1); + determine_best_ap(g_roaming_app.config.scan_rssi_diff - 1); } #endif /*PERIODIC_SCAN_MONITORING*/ @@ -662,13 +675,19 @@ static void periodic_scan_roam(struct timeval *now) void roaming_app_periodic_rrm_internal_handler(void *data, void *ctx) { struct timeval now; + + if (!g_roaming_app.config.rrm_monitor) { + ESP_LOGI(ROAMING_TAG, "%s:RRM monitor is disabled in config", __func__); + return; + } + if (g_roaming_app.periodic_rrm_active) { ESP_LOGD(ROAMING_TAG,"Triggered periodic rrm event!"); gettimeofday(&now, NULL); - /* This will be done every RRM_MONITOR_TIME */ + /* This will be done every g_roaming_app.config.rrm_monitor_time */ periodic_rrm_request(&now); - if (eloop_register_timeout(RRM_MONITOR_TIME, 0, roaming_app_periodic_rrm_internal_handler, NULL, NULL)) { + if (eloop_register_timeout(g_roaming_app.config.rrm_monitor_time, 0, roaming_app_periodic_rrm_internal_handler, NULL, NULL)) { ESP_LOGE(ROAMING_TAG,"Could not register periodic neighbor report request event."); } } @@ -679,14 +698,20 @@ void roaming_app_periodic_rrm_internal_handler(void *data, void *ctx) void roaming_app_periodic_scan_internal_handler(void *data, void *ctx) { struct timeval now; + + if (!g_roaming_app.config.scan_monitor) { + ESP_LOGI(ROAMING_TAG, "%s: Scan monitor is disabled in config", __func__); + return; + } + if (g_roaming_app.periodic_scan_active) { ESP_LOGD(ROAMING_TAG,"Started the periodic scan roam event!"); gettimeofday(&now, NULL); - /* This will be done every SCAN_MONITOR_INTERVAL */ + /* This will be done every g_roaming_app.config.scan_interval */ periodic_scan_roam(&now); - if (eloop_register_timeout(SCAN_MONITOR_INTERVAL, 0, roaming_app_periodic_scan_internal_handler, NULL, NULL)) { + if (eloop_register_timeout(g_roaming_app.config.scan_interval, 0, roaming_app_periodic_scan_internal_handler, NULL, NULL)) { ESP_LOGE(ROAMING_TAG,"Could not register periodic scan event."); } } @@ -759,7 +784,51 @@ cleanup: return ret; } -esp_err_t init_scan_params(void) + +static esp_err_t init_config_params(void) +{ + g_roaming_app.config.backoff_time = ROAMING_BACKOFF_TIME; + + g_roaming_app.config.low_rssi_roam_trigger = LOW_RSSI_ROAMING_ENABLED; + g_roaming_app.config.low_rssi_threshold = ROAMING_LOW_RSSI_THRESHOLD; + g_roaming_app.config.rssi_threshold_reduction_offset = RSSI_THRESHOLD_REDUCTION_OFFSET; + + g_roaming_app.config.scan_monitor = PERIODIC_SCAN_MONITORING; + g_roaming_app.config.scan_interval = SCAN_MONITOR_INTERVAL; + g_roaming_app.config.scan_rssi_threshold = SCAN_MONITOR_RSSI_THRESHOLD; + g_roaming_app.config.scan_rssi_diff = SCAN_ROAM_RSSI_DIFF; + + g_roaming_app.config.legacy_roam_enabled = LEGACY_ROAM_ENABLED; + g_roaming_app.config.btm_retry_cnt = BSS_TM_RETRY_COUNT; + g_roaming_app.config.btm_roaming_enabled = NETWORK_ASSISTED_ROAMING_ENABLED; + + g_roaming_app.config.rrm_monitor = PERIODIC_RRM_MONITORING; + g_roaming_app.config.rrm_monitor_time = RRM_MONITOR_TIME; + g_roaming_app.config.rrm_monitor_rssi_threshold = RRM_MONITOR_RSSI_THRESHOLD; + + ESP_LOGD(ROAMING_TAG, "Roaming app config :"); + + ESP_LOGD(ROAMING_TAG, "backoff time=%d low_rssi_roam_trigger=%d low_rssi_threshold=%d rssi_threshold_reduction_offset=%d", + g_roaming_app.config.backoff_time, g_roaming_app.config.low_rssi_roam_trigger, + g_roaming_app.config.low_rssi_threshold, g_roaming_app.config.rssi_threshold_reduction_offset); + + ESP_LOGD(ROAMING_TAG, "scan_monitor=%d scan_interval=%d scan_rssi_threshold=%d scan_rssi_diff=%d", + g_roaming_app.config.scan_monitor, g_roaming_app.config.scan_interval, + g_roaming_app.config.scan_rssi_threshold, g_roaming_app.config.scan_rssi_diff); + + ESP_LOGD(ROAMING_TAG, "legacy_roam_enabled=%d, btm_retry_cnt=%d btm_roaming_enabled=%d", + g_roaming_app.config.legacy_roam_enabled, + g_roaming_app.config.btm_retry_cnt, g_roaming_app.config.btm_roaming_enabled); + + ESP_LOGD(ROAMING_TAG, "rrm_monitor=%d, rrm_monitor_time=%d rrm_monitor_rssi_threshold=%d", + g_roaming_app.config.rrm_monitor, + g_roaming_app.config.rrm_monitor_time, + g_roaming_app.config.rrm_monitor_rssi_threshold); + + return ESP_OK; +} + +static esp_err_t init_scan_params(void) { if (!scan_results_lock) { scan_results_lock = os_recursive_mutex_create(); @@ -798,8 +867,9 @@ void init_roaming_app(void) #if LOW_RSSI_ROAMING_ENABLED ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_BSS_RSSI_LOW, &roaming_app_rssi_low_handler, NULL)); -#endif /*ROAMING_LOW_RSSI_THRESHOLD*/ +#endif /*LOW_RSSI_ROAMING_ENABLED*/ ESP_ERROR_CHECK(init_scan_params()); + ESP_ERROR_CHECK(init_config_params()); #if PERIODIC_RRM_MONITORING ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_NEIGHBOR_REP, &roaming_app_neighbor_report_recv_handler, NULL)); @@ -825,23 +895,16 @@ void deinit_roaming_app(void) #if LOW_RSSI_ROAMING_ENABLED ESP_ERROR_CHECK(esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_STA_BSS_RSSI_LOW, &roaming_app_rssi_low_handler)); -#endif /*ROAMING_LOW_RSSI_THRESHOLD*/ - -#if PERIODIC_RRM_MONITORING - ESP_ERROR_CHECK(esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_STA_NEIGHBOR_REP, - &roaming_app_neighbor_report_recv_handler)); -#endif /*PERIODIC_RRM_MONITORING*/ - - /* Disabling the periodic scan and RRM events */ -#if PERIODIC_RRM_MONITORING - g_roaming_app.periodic_rrm_active = false; -#endif /*PERIODIC_RRM_MONITORING*/ +#endif /*LOW_RSSI_ROAMING_ENABLED*/ #if PERIODIC_SCAN_MONITORING g_roaming_app.periodic_scan_active = false; #endif /*PERIODIC_SCAN_MONITORING*/ - #if PERIODIC_RRM_MONITORING + ESP_ERROR_CHECK(esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_STA_NEIGHBOR_REP, + &roaming_app_neighbor_report_recv_handler)); + /* Disabling the periodic scan and RRM events */ + g_roaming_app.periodic_rrm_active = false; if (neighbor_list_lock) { os_mutex_delete(neighbor_list_lock); neighbor_list_lock = NULL; diff --git a/components/wpa_supplicant/port/eloop.c b/components/wpa_supplicant/port/eloop.c index c1c71f274b..758e78151c 100644 --- a/components/wpa_supplicant/port/eloop.c +++ b/components/wpa_supplicant/port/eloop.c @@ -17,6 +17,7 @@ #include "list.h" #include "eloop.h" #include "esp_wifi_driver.h" +#include "rom/ets_sys.h" struct eloop_timeout { struct dl_list list;