mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-02 11:10:54 +03:00
Merge branch 'bugfix/concurrency_issue_roam_app_v5.4' into 'release/v5.4'
Add blacklist logic and some fixes in roaming app (v5.4) See merge request espressif/esp-idf!44114
This commit is contained in:
@@ -67,7 +67,7 @@ idf_component_register(SRCS "${srcs}"
|
|||||||
PRIV_REQUIRES driver esptool_py esp_pm esp_timer nvs_flash
|
PRIV_REQUIRES driver esptool_py esp_pm esp_timer nvs_flash
|
||||||
wpa_supplicant hal lwip esp_coex ${extra_priv_requires}
|
wpa_supplicant hal lwip esp_coex ${extra_priv_requires}
|
||||||
PRIV_INCLUDE_DIRS ../wpa_supplicant/src/ ../wpa_supplicant/esp_supplicant/src/
|
PRIV_INCLUDE_DIRS ../wpa_supplicant/src/ ../wpa_supplicant/esp_supplicant/src/
|
||||||
wifi_apps/roaming_app/include
|
wifi_apps/roaming_app/include wifi_apps/roaming_app/src
|
||||||
LDFRAGMENTS "${ldfragments}")
|
LDFRAGMENTS "${ldfragments}")
|
||||||
|
|
||||||
if(CONFIG_ESP_WIFI_ENABLED OR CONFIG_ESP_HOST_WIFI_ENABLED)
|
if(CONFIG_ESP_WIFI_ENABLED OR CONFIG_ESP_HOST_WIFI_ENABLED)
|
||||||
|
|||||||
@@ -181,8 +181,9 @@ static esp_err_t wifi_deinit_internal(void)
|
|||||||
|
|
||||||
esp_supplicant_deinit();
|
esp_supplicant_deinit();
|
||||||
|
|
||||||
#if CONFIG_ESP_WIFI_ENABLE_ROAMING_APP
|
#if CONFIG_ESP_WIFI_SLP_SAMPLE_BEACON_FEATURE
|
||||||
roam_deinit_app();
|
wifi_beacon_offset_config_t offset_config = WIFI_BEACON_OFFSET_CONFIG_DEFAULT(false);
|
||||||
|
esp_wifi_beacon_offset_configure(&offset_config);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
err = esp_wifi_deinit_internal();
|
err = esp_wifi_deinit_internal();
|
||||||
@@ -446,10 +447,6 @@ esp_err_t esp_wifi_init(const wifi_init_config_t *config)
|
|||||||
goto _deinit;
|
goto _deinit;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if CONFIG_ESP_WIFI_ENABLE_ROAMING_APP
|
|
||||||
roam_init_app();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
goto _deinit;
|
goto _deinit;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,9 +16,11 @@ struct roam_config {
|
|||||||
int8_t low_rssi_threshold;
|
int8_t low_rssi_threshold;
|
||||||
uint8_t rssi_threshold_reduction_offset;
|
uint8_t rssi_threshold_reduction_offset;
|
||||||
bool scan_monitor;
|
bool scan_monitor;
|
||||||
|
#if CONFIG_ESP_WIFI_ROAMING_PERIODIC_SCAN_MONITOR
|
||||||
uint8_t scan_interval;
|
uint8_t scan_interval;
|
||||||
int8_t scan_rssi_threshold;
|
int8_t scan_rssi_threshold;
|
||||||
uint8_t scan_rssi_diff;
|
uint8_t scan_rssi_diff;
|
||||||
|
#endif
|
||||||
bool legacy_roam_enabled;
|
bool legacy_roam_enabled;
|
||||||
uint8_t btm_retry_cnt;
|
uint8_t btm_retry_cnt;
|
||||||
bool btm_roaming_enabled;
|
bool btm_roaming_enabled;
|
||||||
@@ -37,6 +39,10 @@ void roam_sta_disconnected(void *disconn);
|
|||||||
esp_err_t roam_get_config_params(struct roam_config *config);
|
esp_err_t roam_get_config_params(struct roam_config *config);
|
||||||
esp_err_t roam_set_config_params(struct roam_config *config);
|
esp_err_t roam_set_config_params(struct roam_config *config);
|
||||||
|
|
||||||
|
#if CONFIG_ESP_WIFI_ENABLE_ROAMING_APP
|
||||||
|
void esp_wifi_roaming_set_current_bssid(const uint8_t *bssid);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ menu "Roaming Methods"
|
|||||||
config ESP_WIFI_ROAMING_NETWORK_ASSISTED_ROAM
|
config ESP_WIFI_ROAMING_NETWORK_ASSISTED_ROAM
|
||||||
bool "Support Network Assisted roaming using 802.11v"
|
bool "Support Network Assisted roaming using 802.11v"
|
||||||
depends on ESP_WIFI_WNM_SUPPORT
|
depends on ESP_WIFI_WNM_SUPPORT
|
||||||
default n
|
default y
|
||||||
help
|
help
|
||||||
Roaming between APs using network assisted Roaming.
|
Roaming between APs using network assisted Roaming.
|
||||||
This involves BSS Transition Management mechanisms outlined in 802.11v.
|
This involves BSS Transition Management mechanisms outlined in 802.11v.
|
||||||
@@ -139,13 +139,7 @@ menu "Scan Configuration"
|
|||||||
Duration for which the results from the most recent scans can be used
|
Duration for which the results from the most recent scans can be used
|
||||||
by the roaming app for determining the roaming candidates.
|
by the roaming app for determining the roaming candidates.
|
||||||
|
|
||||||
config ESP_WIFI_ROAMING_MAX_CANDIDATES
|
|
||||||
int "Max Candidates in the network"
|
|
||||||
default 3
|
|
||||||
range 3 20
|
|
||||||
help
|
|
||||||
Max candidates that can be considered while scanning as a part of the
|
|
||||||
network at one time.
|
|
||||||
|
|
||||||
endmenu #"Scan Configuration"
|
endmenu #"Scan Configuration"
|
||||||
|
|
||||||
@@ -160,7 +154,7 @@ config ESP_WIFI_ROAMING_BACKOFF_TIME
|
|||||||
config ESP_WIFI_ROAMING_PERIODIC_RRM_MONITORING
|
config ESP_WIFI_ROAMING_PERIODIC_RRM_MONITORING
|
||||||
bool "Send periodic neighbor report request to AP for internal list updation"
|
bool "Send periodic neighbor report request to AP for internal list updation"
|
||||||
depends on ESP_WIFI_RRM_SUPPORT
|
depends on ESP_WIFI_RRM_SUPPORT
|
||||||
default y
|
default n
|
||||||
help
|
help
|
||||||
This option will enable station to keep sending RRM neighbor list request to AP and
|
This option will enable station to keep sending RRM neighbor list request to AP and
|
||||||
update its internal list.
|
update its internal list.
|
||||||
@@ -182,3 +176,50 @@ config ESP_WIFI_ROAMING_RRM_MONITOR_THRESHOLD
|
|||||||
range -99 0
|
range -99 0
|
||||||
help
|
help
|
||||||
The RSSI threshold beyond which we start sending periodic neighbor report requests.
|
The RSSI threshold beyond which we start sending periodic neighbor report requests.
|
||||||
|
|
||||||
|
menu "Blacklist Configuration"
|
||||||
|
config ESP_WIFI_ROAMING_BSSID_BLACKLIST
|
||||||
|
bool "Enable BSSID blacklisting"
|
||||||
|
default n
|
||||||
|
help
|
||||||
|
Enable this to blacklist BSSIDs.
|
||||||
|
|
||||||
|
config ESP_WIFI_ROAMING_AUTO_BLACKLISTING
|
||||||
|
bool "Enable automatic BSSID blacklisting"
|
||||||
|
depends on ESP_WIFI_ROAMING_BSSID_BLACKLIST
|
||||||
|
help
|
||||||
|
Enable this to automatically blacklist BSSIDs after multiple failed connection attempts.
|
||||||
|
|
||||||
|
config ESP_WIFI_ROAMING_MAX_CONN_FAILURES
|
||||||
|
int "Maximum connection failures"
|
||||||
|
depends on ESP_WIFI_ROAMING_AUTO_BLACKLISTING
|
||||||
|
range 1 10
|
||||||
|
default 3
|
||||||
|
help
|
||||||
|
Maximum number of connection failures before a BSSID is blacklisted.
|
||||||
|
|
||||||
|
config ESP_WIFI_ROAMING_BLACKLIST_TIMEOUT
|
||||||
|
int "Blacklist timeout (in seconds)"
|
||||||
|
depends on ESP_WIFI_ROAMING_BSSID_BLACKLIST
|
||||||
|
range 10 3600
|
||||||
|
default 300
|
||||||
|
help
|
||||||
|
Time in seconds for which a BSSID remains in the blacklist.
|
||||||
|
This applies to both automatically and manually blacklisted BSSIDs.
|
||||||
|
|
||||||
|
config ESP_WIFI_ROAMING_MAX_CANDIDATES
|
||||||
|
int "Maximum number of roaming candidates"
|
||||||
|
range 1 10
|
||||||
|
default 5
|
||||||
|
help
|
||||||
|
Maximum number of roaming candidates to consider. This also defines the size of the blacklist.
|
||||||
|
|
||||||
|
config ESP_WIFI_ROAMING_PREVENT_DOWNGRADE
|
||||||
|
bool "Prevent security downgrade when roaming"
|
||||||
|
default n
|
||||||
|
help
|
||||||
|
If the currently connected AP sends a "transition disable" bit,
|
||||||
|
this option will make the roaming logic ignore less secure APs.
|
||||||
|
This helps prevent security downgrades when roaming in a mixed
|
||||||
|
security environment (e.g., WPA2/WPA3).
|
||||||
|
endmenu # "Blacklist Configuration"
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@@ -22,12 +22,18 @@ extern "C" {
|
|||||||
#define ROAMING_BACKOFF_TIME CONFIG_ESP_WIFI_ROAMING_BACKOFF_TIME
|
#define ROAMING_BACKOFF_TIME CONFIG_ESP_WIFI_ROAMING_BACKOFF_TIME
|
||||||
|
|
||||||
/* Low RSSI based roaming configuration */
|
/* Low RSSI based roaming configuration */
|
||||||
|
#ifndef CONFIG_ESP_WIFI_ROAMING_LOW_RSSI_ROAMING
|
||||||
|
#define CONFIG_ESP_WIFI_ROAMING_LOW_RSSI_ROAMING 0
|
||||||
|
#endif
|
||||||
#define LOW_RSSI_ROAMING_ENABLED CONFIG_ESP_WIFI_ROAMING_LOW_RSSI_ROAMING
|
#define LOW_RSSI_ROAMING_ENABLED CONFIG_ESP_WIFI_ROAMING_LOW_RSSI_ROAMING
|
||||||
#if LOW_RSSI_ROAMING_ENABLED
|
#if LOW_RSSI_ROAMING_ENABLED
|
||||||
#define ROAMING_LOW_RSSI_THRESHOLD CONFIG_ESP_WIFI_ROAMING_LOW_RSSI_THRESHOLD
|
#define ROAMING_LOW_RSSI_THRESHOLD CONFIG_ESP_WIFI_ROAMING_LOW_RSSI_THRESHOLD
|
||||||
#define RSSI_THRESHOLD_REDUCTION_OFFSET CONFIG_ESP_WIFI_ROAMING_LOW_RSSI_OFFSET
|
#define RSSI_THRESHOLD_REDUCTION_OFFSET CONFIG_ESP_WIFI_ROAMING_LOW_RSSI_OFFSET
|
||||||
#endif /*LOW_RSSI_ROAMING_ENABLED*/
|
#endif /*LOW_RSSI_ROAMING_ENABLED*/
|
||||||
|
|
||||||
|
#ifndef CONFIG_ESP_WIFI_ROAMING_PERIODIC_SCAN_MONITOR
|
||||||
|
#define CONFIG_ESP_WIFI_ROAMING_PERIODIC_SCAN_MONITOR 0
|
||||||
|
#endif
|
||||||
/* Periodic Scan based Roaming configuration */
|
/* Periodic Scan based Roaming configuration */
|
||||||
#define PERIODIC_SCAN_MONITORING CONFIG_ESP_WIFI_ROAMING_PERIODIC_SCAN_MONITOR
|
#define PERIODIC_SCAN_MONITORING CONFIG_ESP_WIFI_ROAMING_PERIODIC_SCAN_MONITOR
|
||||||
#if PERIODIC_SCAN_MONITORING
|
#if PERIODIC_SCAN_MONITORING
|
||||||
@@ -134,6 +140,16 @@ struct roaming_app {
|
|||||||
#endif
|
#endif
|
||||||
#if PERIODIC_SCAN_MONITORING
|
#if PERIODIC_SCAN_MONITORING
|
||||||
bool periodic_scan_active;
|
bool periodic_scan_active;
|
||||||
|
#endif
|
||||||
|
#if CONFIG_ESP_WIFI_ROAMING_BSSID_BLACKLIST
|
||||||
|
struct blacklist_entry {
|
||||||
|
uint8_t bssid[ETH_ALEN];
|
||||||
|
#if CONFIG_ESP_WIFI_ROAMING_AUTO_BLACKLISTING
|
||||||
|
uint8_t failures;
|
||||||
|
#endif
|
||||||
|
struct timeval timestamp;
|
||||||
|
} bssid_blacklist[CONFIG_ESP_WIFI_ROAMING_MAX_CANDIDATES];
|
||||||
|
uint8_t bssid_blacklist_count;
|
||||||
#endif
|
#endif
|
||||||
bool allow_reconnect;
|
bool allow_reconnect;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -28,22 +28,17 @@
|
|||||||
#include "utils/eloop.h"
|
#include "utils/eloop.h"
|
||||||
#include "rom/ets_sys.h"
|
#include "rom/ets_sys.h"
|
||||||
#include "common/ieee802_11_defs.h"
|
#include "common/ieee802_11_defs.h"
|
||||||
static struct roaming_app g_roaming_app;
|
#include "common/wpa_common.h"
|
||||||
|
#include "esp_wpas_glue.h"
|
||||||
|
|
||||||
|
struct roaming_app g_roaming_app;
|
||||||
|
|
||||||
typedef void (* scan_done_cb_t)(void *arg, ETS_STATUS status);
|
typedef void (* scan_done_cb_t)(void *arg, ETS_STATUS status);
|
||||||
extern int esp_wifi_promiscuous_scan_start(wifi_scan_config_t *config, scan_done_cb_t cb);
|
extern int esp_wifi_promiscuous_scan_start(wifi_scan_config_t *config, scan_done_cb_t cb);
|
||||||
static void *scan_results_lock = NULL;
|
|
||||||
#define ROAM_SCAN_RESULTS_LOCK() os_mutex_lock(scan_results_lock)
|
|
||||||
#define ROAM_SCAN_RESULTS_UNLOCK() os_mutex_unlock(scan_results_lock)
|
|
||||||
|
|
||||||
#if PERIODIC_RRM_MONITORING
|
|
||||||
static void *neighbor_list_lock = NULL;
|
|
||||||
#define ROAM_NEIGHBOR_LIST_LOCK() os_mutex_lock(neighbor_list_lock)
|
|
||||||
#define ROAM_NEIGHBOR_LIST_UNLOCK() os_mutex_unlock(neighbor_list_lock)
|
|
||||||
#endif /*PERIODIC_RRM_MONITORING*/
|
|
||||||
|
|
||||||
static int wifi_post_roam_event(struct cand_bss *bss);
|
static int wifi_post_roam_event(struct cand_bss *bss);
|
||||||
static void determine_best_ap(int8_t rssi_threshold);
|
static void determine_best_ap(int8_t rssi_threshold);
|
||||||
|
static bool is_bssid_blacklisted(const uint8_t *bssid);
|
||||||
#if PERIODIC_RRM_MONITORING
|
#if PERIODIC_RRM_MONITORING
|
||||||
static void roaming_app_periodic_rrm_internal_handler(void *data, void *ctx);
|
static void roaming_app_periodic_rrm_internal_handler(void *data, void *ctx);
|
||||||
#endif
|
#endif
|
||||||
@@ -53,6 +48,13 @@ static void roaming_app_periodic_scan_internal_handler(void *data, void *ctx);
|
|||||||
|
|
||||||
static const char *ROAMING_TAG = "ROAM";
|
static const char *ROAMING_TAG = "ROAM";
|
||||||
|
|
||||||
|
void esp_wifi_roaming_set_current_bssid(const uint8_t *bssid)
|
||||||
|
{
|
||||||
|
if (bssid) {
|
||||||
|
memcpy(g_roaming_app.current_bss.ap.bssid, bssid, ETH_ALEN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static inline long time_diff_sec(struct timeval *a, struct timeval *b)
|
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);
|
||||||
@@ -139,12 +141,6 @@ static void init_periodic_rrm_event(void)
|
|||||||
ESP_LOGI(ROAMING_TAG, "RRM monitor is disabled in config");
|
ESP_LOGI(ROAMING_TAG, "RRM monitor is disabled in config");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!neighbor_list_lock) {
|
|
||||||
neighbor_list_lock = os_recursive_mutex_create();
|
|
||||||
if (!neighbor_list_lock) {
|
|
||||||
ESP_LOGE(ROAMING_TAG, "%s: failed to create roaming neighbor list lock", __func__);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ESP_LOGV(ROAMING_TAG, "Initialised Periodic RRM Monitoring event!");
|
ESP_LOGV(ROAMING_TAG, "Initialised Periodic RRM Monitoring event!");
|
||||||
g_roaming_app.periodic_rrm_active = true;
|
g_roaming_app.periodic_rrm_active = true;
|
||||||
if (eloop_register_timeout(g_roaming_app.config.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)) {
|
||||||
@@ -179,23 +175,77 @@ static void roaming_app_disconnected_event_handler(void *ctx, void *data)
|
|||||||
#endif /*PERIODIC_SCAN_MONITORING*/
|
#endif /*PERIODIC_SCAN_MONITORING*/
|
||||||
|
|
||||||
wifi_event_sta_disconnected_t *disconn = data;
|
wifi_event_sta_disconnected_t *disconn = data;
|
||||||
ESP_LOGD(ROAMING_TAG, "station got disconnected reason=%d", disconn->reason);
|
#define RSSI_INVALID -128
|
||||||
|
g_roaming_app.current_bss.ap.rssi = RSSI_INVALID;
|
||||||
|
#undef RSSI_INVALID
|
||||||
|
|
||||||
|
ESP_LOGD(ROAMING_TAG, "station got disconnected reason=%d, rssi =%d", disconn->reason, disconn->rssi);
|
||||||
|
#if CONFIG_ESP_WIFI_ROAMING_AUTO_BLACKLISTING
|
||||||
|
if (disconn->reason == WIFI_REASON_CONNECTION_FAIL || disconn->reason == WIFI_REASON_AUTH_FAIL) {
|
||||||
|
bool found = false;
|
||||||
|
for (int i = 0; i < g_roaming_app.bssid_blacklist_count; i++) {
|
||||||
|
if (memcmp(g_roaming_app.bssid_blacklist[i].bssid, g_roaming_app.current_bss.ap.bssid, ETH_ALEN) == 0) {
|
||||||
|
g_roaming_app.bssid_blacklist[i].failures++;
|
||||||
|
gettimeofday(&g_roaming_app.bssid_blacklist[i].timestamp, NULL);
|
||||||
|
ESP_LOGD(ROAMING_TAG, "BSSID " MACSTR " connection failures: %d", MAC2STR(g_roaming_app.current_bss.ap.bssid), g_roaming_app.bssid_blacklist[i].failures);
|
||||||
|
if (g_roaming_app.bssid_blacklist[i].failures >= CONFIG_ESP_WIFI_ROAMING_MAX_CONN_FAILURES) {
|
||||||
|
ESP_LOGI(ROAMING_TAG, "BSSID " MACSTR " blacklisted", MAC2STR(g_roaming_app.current_bss.ap.bssid));
|
||||||
|
/* The BSSID is now blacklisted. The logic later in this function
|
||||||
|
* will check the blacklist and trigger a scan for a new AP
|
||||||
|
* instead of trying to reconnect to this one. */
|
||||||
|
}
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found) {
|
||||||
|
if (g_roaming_app.bssid_blacklist_count < CONFIG_ESP_WIFI_ROAMING_MAX_CANDIDATES) {
|
||||||
|
memcpy(g_roaming_app.bssid_blacklist[g_roaming_app.bssid_blacklist_count].bssid, g_roaming_app.current_bss.ap.bssid, ETH_ALEN);
|
||||||
|
g_roaming_app.bssid_blacklist[g_roaming_app.bssid_blacklist_count].failures = 1;
|
||||||
|
gettimeofday(&g_roaming_app.bssid_blacklist[g_roaming_app.bssid_blacklist_count].timestamp, NULL);
|
||||||
|
g_roaming_app.bssid_blacklist_count++;
|
||||||
|
ESP_LOGD(ROAMING_TAG, "BSSID " MACSTR " added to blacklist tracking", MAC2STR(g_roaming_app.current_bss.ap.bssid));
|
||||||
|
} else {
|
||||||
|
int oldest_idx = 0;
|
||||||
|
for (int i = 1; i < g_roaming_app.bssid_blacklist_count; i++) {
|
||||||
|
if (g_roaming_app.bssid_blacklist[i].timestamp.tv_sec < g_roaming_app.bssid_blacklist[oldest_idx].timestamp.tv_sec) {
|
||||||
|
oldest_idx = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ESP_LOGD(ROAMING_TAG, "Blacklist is full. Replacing oldest entry for " MACSTR, MAC2STR(g_roaming_app.bssid_blacklist[oldest_idx].bssid));
|
||||||
|
memcpy(g_roaming_app.bssid_blacklist[oldest_idx].bssid, g_roaming_app.current_bss.ap.bssid, ETH_ALEN);
|
||||||
|
g_roaming_app.bssid_blacklist[oldest_idx].failures = 1;
|
||||||
|
gettimeofday(&g_roaming_app.bssid_blacklist[oldest_idx].timestamp, NULL);
|
||||||
|
ESP_LOGD(ROAMING_TAG, "BSSID " MACSTR " added to blacklist tracking", MAC2STR(g_roaming_app.current_bss.ap.bssid));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
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) {
|
} else if (g_roaming_app.allow_reconnect == false) {
|
||||||
ESP_LOGD(ROAMING_TAG, "station initiated disconnect, do nothing");
|
ESP_LOGD(ROAMING_TAG, "station initiated disconnect, do nothing");
|
||||||
} else {
|
} else {
|
||||||
|
#if CONFIG_ESP_WIFI_ROAMING_BSSID_BLACKLIST
|
||||||
|
if (is_bssid_blacklisted(g_roaming_app.current_bss.ap.bssid)) {
|
||||||
|
ESP_LOGD(ROAMING_TAG, "AP " MACSTR " is blacklisted, finding another AP", MAC2STR(g_roaming_app.current_bss.ap.bssid));
|
||||||
|
determine_best_ap(0);
|
||||||
|
} else {
|
||||||
|
#endif
|
||||||
#if LEGACY_ROAM_ENABLED
|
#if LEGACY_ROAM_ENABLED
|
||||||
/*
|
/*
|
||||||
* Resetting the Bssid param as it is possible that a previous force
|
* Resetting the Bssid param as it is possible that a previous force
|
||||||
* roam has set config to connect to a specific bssid and now further
|
* roam has set config to connect to a specific bssid and now further
|
||||||
* roaming attempts using BTM could lead to a spiral of connecting to
|
* roaming attempts using BTM could lead to a spiral of connecting to
|
||||||
* the previous AP */
|
* the previous AP */
|
||||||
if (g_roaming_app.force_roam_ongoing) {
|
if (g_roaming_app.force_roam_ongoing) {
|
||||||
legacy_roam_clear_bssid_flag();
|
legacy_roam_clear_bssid_flag();
|
||||||
}
|
}
|
||||||
#endif /*LEGACY_ROAM_ENABLED*/
|
#endif /*LEGACY_ROAM_ENABLED*/
|
||||||
esp_wifi_connect();
|
esp_wifi_connect();
|
||||||
|
#if CONFIG_ESP_WIFI_ROAMING_BSSID_BLACKLIST
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
os_free(disconn);
|
os_free(disconn);
|
||||||
}
|
}
|
||||||
@@ -357,26 +407,27 @@ cleanup:
|
|||||||
}
|
}
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
static void roaming_app_neighbor_report_recv_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data)
|
|
||||||
|
static void roaming_app_neighbor_report_recv_internal_handler(void *ctx, void *data)
|
||||||
{
|
{
|
||||||
|
wifi_event_neighbor_report_t *neighbor_report_event = data;
|
||||||
if (!g_roaming_app.rrm_request_active) {
|
if (!g_roaming_app.rrm_request_active) {
|
||||||
ESP_LOGV(ROAMING_TAG, "Not the response for our Neighbor Report Request");
|
ESP_LOGV(ROAMING_TAG, "Not the response for our Neighbor Report Request");
|
||||||
return;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
g_roaming_app.rrm_request_active = false;
|
g_roaming_app.rrm_request_active = false;
|
||||||
|
|
||||||
if (!event_data) {
|
if (!neighbor_report_event) {
|
||||||
ESP_LOGE(ROAMING_TAG, "No data received for neighbor report");
|
ESP_LOGE(ROAMING_TAG, "No data received for neighbor report");
|
||||||
return;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
wifi_event_neighbor_report_t *neighbor_report_event = (wifi_event_neighbor_report_t*)event_data;
|
|
||||||
ESP_LOGD(ROAMING_TAG, "Received cb for Neighbor Report Request");
|
ESP_LOGD(ROAMING_TAG, "Received cb for Neighbor Report Request");
|
||||||
|
|
||||||
uint8_t *pos = (uint8_t *)neighbor_report_event->report;
|
uint8_t *pos = (uint8_t *)neighbor_report_event->report;
|
||||||
if (!pos) {
|
if (!pos) {
|
||||||
ESP_LOGE(ROAMING_TAG, "Neighbor report is empty");
|
ESP_LOGE(ROAMING_TAG, "Neighbor report is empty");
|
||||||
return;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t report_len = neighbor_report_event->report_len;
|
uint8_t report_len = neighbor_report_event->report_len;
|
||||||
@@ -384,22 +435,42 @@ static void roaming_app_neighbor_report_recv_handler(void* arg, esp_event_base_t
|
|||||||
ESP_LOGD(ROAMING_TAG, "rrm: neighbor report len=%d", report_len);
|
ESP_LOGD(ROAMING_TAG, "rrm: neighbor report len=%d", report_len);
|
||||||
ESP_LOG_BUFFER_HEXDUMP(ROAMING_TAG, pos, report_len, ESP_LOG_DEBUG);
|
ESP_LOG_BUFFER_HEXDUMP(ROAMING_TAG, pos, report_len, ESP_LOG_DEBUG);
|
||||||
|
|
||||||
ROAM_NEIGHBOR_LIST_LOCK();
|
|
||||||
if (g_roaming_app.btm_neighbor_list) {
|
if (g_roaming_app.btm_neighbor_list) {
|
||||||
os_free(g_roaming_app.btm_neighbor_list);
|
os_free(g_roaming_app.btm_neighbor_list);
|
||||||
g_roaming_app.btm_neighbor_list = NULL;
|
g_roaming_app.btm_neighbor_list = NULL;
|
||||||
}
|
}
|
||||||
/* create neighbor list */
|
/* create neighbor list */
|
||||||
g_roaming_app.btm_neighbor_list = get_btm_neighbor_list(pos + 1, report_len - 1);
|
g_roaming_app.btm_neighbor_list = get_btm_neighbor_list(pos + 1, report_len - 1);
|
||||||
ROAM_NEIGHBOR_LIST_UNLOCK();
|
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
if (neighbor_report_event) {
|
||||||
|
os_free(neighbor_report_event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void roaming_app_neighbor_report_recv_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data)
|
||||||
|
{
|
||||||
|
wifi_event_neighbor_report_t *event = (wifi_event_neighbor_report_t*)event_data;
|
||||||
|
if (!event) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
wifi_event_neighbor_report_t *event_copy = os_malloc(sizeof(wifi_event_neighbor_report_t) + event->report_len);
|
||||||
|
if (!event_copy) {
|
||||||
|
ESP_LOGE(ROAMING_TAG, "Failed to allocate memory for neighbor report event");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
memcpy(event_copy, event, sizeof(wifi_event_neighbor_report_t) + event->report_len);
|
||||||
|
|
||||||
|
if (eloop_register_timeout(0, 0, roaming_app_neighbor_report_recv_internal_handler, NULL, event_copy) != 0) {
|
||||||
|
os_free(event_copy);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif /*PERIODIC_RRM_MONITORING*/
|
#endif /*PERIODIC_RRM_MONITORING*/
|
||||||
|
|
||||||
#if LOW_RSSI_ROAMING_ENABLED
|
#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)
|
static void roaming_app_rssi_low_internal_handler(void *ctx, void *data)
|
||||||
{
|
{
|
||||||
wifi_event_bss_rssi_low_t *event = event_data;
|
wifi_event_bss_rssi_low_t *event = data;
|
||||||
ESP_LOGI(ROAMING_TAG, "%s:bss rssi is=%ld", __func__, event->rssi);
|
ESP_LOGI(ROAMING_TAG, "%s:bss rssi is=%ld", __func__, event->rssi);
|
||||||
|
|
||||||
roaming_app_get_ap_info(&g_roaming_app.current_bss.ap);
|
roaming_app_get_ap_info(&g_roaming_app.current_bss.ap);
|
||||||
@@ -408,25 +479,34 @@ static void roaming_app_rssi_low_handler(void* arg, esp_event_base_t event_base,
|
|||||||
ESP_LOGD(ROAMING_TAG, "Resetting RSSI Threshold to %d", g_roaming_app.current_low_rssi_threshold);
|
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);
|
esp_wifi_set_rssi_threshold(g_roaming_app.current_low_rssi_threshold);
|
||||||
|
|
||||||
|
os_free(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void roaming_app_rssi_low_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data)
|
||||||
|
{
|
||||||
|
wifi_event_bss_rssi_low_t *event = event_data;
|
||||||
|
if (!event) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
wifi_event_bss_rssi_low_t *event_copy = os_malloc(sizeof(wifi_event_bss_rssi_low_t));
|
||||||
|
if (!event_copy) {
|
||||||
|
ESP_LOGE(ROAMING_TAG, "Failed to allocate memory for rssi low event");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
memcpy(event_copy, event, sizeof(wifi_event_bss_rssi_low_t));
|
||||||
|
|
||||||
|
if (eloop_register_timeout(0, 0, roaming_app_rssi_low_internal_handler, NULL, event_copy) != 0) {
|
||||||
|
os_free(event_copy);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if NETWORK_ASSISTED_ROAMING_ENABLED
|
#if NETWORK_ASSISTED_ROAMING_ENABLED
|
||||||
static void trigger_network_assisted_roam(void)
|
static void trigger_network_assisted_roam(void)
|
||||||
{
|
{
|
||||||
#if PERIODIC_RRM_MONITORING
|
|
||||||
if (g_roaming_app.current_bss.rrm_support) {
|
|
||||||
ROAM_NEIGHBOR_LIST_LOCK();
|
|
||||||
}
|
|
||||||
#endif /*PERIODIC_RRM_MONITORING*/
|
|
||||||
if (esp_wnm_send_bss_transition_mgmt_query(REASON_RSSI, g_roaming_app.btm_neighbor_list, 1) < 0) {
|
if (esp_wnm_send_bss_transition_mgmt_query(REASON_RSSI, g_roaming_app.btm_neighbor_list, 1) < 0) {
|
||||||
ESP_LOGD(ROAMING_TAG, "failed to send btm query");
|
ESP_LOGD(ROAMING_TAG, "failed to send btm query");
|
||||||
}
|
}
|
||||||
#if PERIODIC_RRM_MONITORING
|
|
||||||
if (g_roaming_app.current_bss.rrm_support) {
|
|
||||||
ROAM_NEIGHBOR_LIST_UNLOCK();
|
|
||||||
}
|
|
||||||
#endif /*PERIODIC_RRM_MONITORING*/
|
|
||||||
ESP_LOGD(ROAMING_TAG, "Sent BTM Query");
|
ESP_LOGD(ROAMING_TAG, "Sent BTM Query");
|
||||||
gettimeofday(&g_roaming_app.last_roamed_time, NULL);
|
gettimeofday(&g_roaming_app.last_roamed_time, NULL);
|
||||||
#if LEGACY_ROAM_ENABLED
|
#if LEGACY_ROAM_ENABLED
|
||||||
@@ -444,6 +524,7 @@ static void trigger_legacy_roam(struct cand_bss *bss)
|
|||||||
wifi_cfg.sta.bssid_set = true;
|
wifi_cfg.sta.bssid_set = true;
|
||||||
os_memcpy(wifi_cfg.sta.bssid, bss->bssid, ETH_ALEN);
|
os_memcpy(wifi_cfg.sta.bssid, bss->bssid, ETH_ALEN);
|
||||||
esp_wifi_internal_issue_disconnect(WIFI_REASON_BSS_TRANSITION_DISASSOC);
|
esp_wifi_internal_issue_disconnect(WIFI_REASON_BSS_TRANSITION_DISASSOC);
|
||||||
|
esp_wifi_roaming_set_current_bssid(bss->bssid);
|
||||||
esp_wifi_set_config(WIFI_IF_STA, &wifi_cfg);
|
esp_wifi_set_config(WIFI_IF_STA, &wifi_cfg);
|
||||||
esp_wifi_connect();
|
esp_wifi_connect();
|
||||||
ESP_LOGI(ROAMING_TAG, "Disconnecting and connecting to "MACSTR" on account of better rssi",MAC2STR(bss->bssid));
|
ESP_LOGI(ROAMING_TAG, "Disconnecting and connecting to "MACSTR" on account of better rssi",MAC2STR(bss->bssid));
|
||||||
@@ -458,7 +539,7 @@ void roaming_app_trigger_roam(struct cand_bss *bss)
|
|||||||
gettimeofday(&now, NULL);
|
gettimeofday(&now, NULL);
|
||||||
ESP_LOGD(ROAMING_TAG,"Processing trigger roaming request.");
|
ESP_LOGD(ROAMING_TAG,"Processing trigger roaming request.");
|
||||||
if (time_diff_sec(&now, &g_roaming_app.last_roamed_time) < g_roaming_app.config.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));
|
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;
|
goto free_bss;
|
||||||
}
|
}
|
||||||
#if NETWORK_ASSISTED_ROAMING_ENABLED
|
#if NETWORK_ASSISTED_ROAMING_ENABLED
|
||||||
@@ -492,7 +573,6 @@ void roaming_app_trigger_roam_internal_handler(void *ctx, void *data)
|
|||||||
} else {
|
} else {
|
||||||
roaming_app_trigger_roam((struct cand_bss *)data);
|
roaming_app_trigger_roam((struct cand_bss *)data);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int wifi_post_roam_event(struct cand_bss *bss)
|
static int wifi_post_roam_event(struct cand_bss *bss)
|
||||||
@@ -529,7 +609,6 @@ void print_ap_records(struct scanned_ap_info *ap_info)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if PERIODIC_RRM_MONITORING
|
#if PERIODIC_RRM_MONITORING
|
||||||
static void periodic_rrm_request(struct timeval *now)
|
static void periodic_rrm_request(struct timeval *now)
|
||||||
{
|
{
|
||||||
@@ -546,6 +625,31 @@ static void periodic_rrm_request(struct timeval *now)
|
|||||||
|
|
||||||
static bool candidate_security_match(wifi_ap_record_t candidate)
|
static bool candidate_security_match(wifi_ap_record_t candidate)
|
||||||
{
|
{
|
||||||
|
#if CONFIG_ESP_WIFI_ROAMING_PREVENT_DOWNGRADE
|
||||||
|
u8 transition_disable = wpa_supplicant_get_transition_disable();
|
||||||
|
if (transition_disable & TRANSITION_DISABLE_WPA3_PERSONAL) {
|
||||||
|
if (candidate.authmode == WIFI_AUTH_WPA2_PSK) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (transition_disable & TRANSITION_DISABLE_ENHANCED_OPEN) {
|
||||||
|
if (candidate.authmode == WIFI_AUTH_OPEN) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (transition_disable & TRANSITION_DISABLE_WPA3_ENTERPRISE) {
|
||||||
|
if (candidate.authmode == WIFI_AUTH_WPA2_ENTERPRISE) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#if TODO // application doesn't have a way to know SAE-PK enabled AP atm
|
||||||
|
if (transition_disable & TRANSITION_DISABLE_SAE_PK) {
|
||||||
|
if (candidate.authmode == WIFI_AUTH_WPA3_PSK) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
wifi_auth_mode_t curr_auth = g_roaming_app.current_bss.ap.authmode;
|
wifi_auth_mode_t curr_auth = g_roaming_app.current_bss.ap.authmode;
|
||||||
wifi_auth_mode_t cand_auth = candidate.authmode;
|
wifi_auth_mode_t cand_auth = candidate.authmode;
|
||||||
ESP_LOGV(ROAMING_TAG, "Cand authmode : %d, Current Authmode : %d", cand_auth, curr_auth);
|
ESP_LOGV(ROAMING_TAG, "Cand authmode : %d, Current Authmode : %d", cand_auth, curr_auth);
|
||||||
@@ -556,9 +660,6 @@ static bool candidate_security_match(wifi_ap_record_t candidate)
|
|||||||
wifi_config_t wifi_cfg = {0};
|
wifi_config_t wifi_cfg = {0};
|
||||||
esp_wifi_get_config(WIFI_IF_STA, &wifi_cfg);
|
esp_wifi_get_config(WIFI_IF_STA, &wifi_cfg);
|
||||||
if (wifi_cfg.sta.owe_enabled && OWE_COMPATIBLE(curr_auth, cand_auth)) {
|
if (wifi_cfg.sta.owe_enabled && OWE_COMPATIBLE(curr_auth, cand_auth)) {
|
||||||
/*
|
|
||||||
* OWE <--> Open allowed if threshold is Open
|
|
||||||
*/
|
|
||||||
if (wifi_cfg.sta.threshold.authmode == WIFI_AUTH_OPEN) {
|
if (wifi_cfg.sta.threshold.authmode == WIFI_AUTH_OPEN) {
|
||||||
ESP_LOGV(ROAMING_TAG, "transition between OWE and open permitted");
|
ESP_LOGV(ROAMING_TAG, "transition between OWE and open permitted");
|
||||||
return true;
|
return true;
|
||||||
@@ -568,7 +669,7 @@ static bool candidate_security_match(wifi_ap_record_t candidate)
|
|||||||
}
|
}
|
||||||
} else if (wifi_cfg.sta.threshold.authmode > cand_auth) {
|
} else if (wifi_cfg.sta.threshold.authmode > cand_auth) {
|
||||||
/* If the authmode of the candidate AP is less than our threshold, it
|
/* If the authmode of the candidate AP is less than our threshold, it
|
||||||
* will fail during connection*/
|
* will fail during connection */
|
||||||
ESP_LOGV(ROAMING_TAG, "Authmode threshold failure %d -> %d", wifi_cfg.sta.threshold.authmode, cand_auth);
|
ESP_LOGV(ROAMING_TAG, "Authmode threshold failure %d -> %d", wifi_cfg.sta.threshold.authmode, cand_auth);
|
||||||
return false;
|
return false;
|
||||||
} else if (PSK_COMPATIBLE(curr_auth, cand_auth)) {
|
} else if (PSK_COMPATIBLE(curr_auth, cand_auth)) {
|
||||||
@@ -581,11 +682,45 @@ static bool candidate_security_match(wifi_ap_record_t candidate)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool candidate_profile_match(wifi_ap_record_t candidate)
|
#if CONFIG_ESP_WIFI_ROAMING_BSSID_BLACKLIST
|
||||||
|
static void remove_expired_blacklist_entries(void)
|
||||||
{
|
{
|
||||||
return candidate_security_match(candidate);
|
struct timeval now;
|
||||||
|
gettimeofday(&now, NULL);
|
||||||
|
int j = 0;
|
||||||
|
for (int i = 0; i < g_roaming_app.bssid_blacklist_count; i++) {
|
||||||
|
if (time_diff_sec(&now, &g_roaming_app.bssid_blacklist[i].timestamp) <= CONFIG_ESP_WIFI_ROAMING_BLACKLIST_TIMEOUT) {
|
||||||
|
if (i != j) {
|
||||||
|
g_roaming_app.bssid_blacklist[j] = g_roaming_app.bssid_blacklist[i];
|
||||||
|
}
|
||||||
|
j++;
|
||||||
|
} else {
|
||||||
|
ESP_LOGI(ROAMING_TAG, "BSSID " MACSTR " removed from blacklist due to timeout", MAC2STR(g_roaming_app.bssid_blacklist[i].bssid));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
g_roaming_app.bssid_blacklist_count = j;
|
||||||
}
|
}
|
||||||
/* Remember to always call this function with the ROAM_SCAN_RESULTS_LOCK */
|
#endif
|
||||||
|
|
||||||
|
static bool is_bssid_blacklisted(const uint8_t *bssid)
|
||||||
|
{
|
||||||
|
#if CONFIG_ESP_WIFI_ROAMING_BSSID_BLACKLIST
|
||||||
|
remove_expired_blacklist_entries();
|
||||||
|
for (int i = 0; i < g_roaming_app.bssid_blacklist_count; i++) {
|
||||||
|
if (memcmp(g_roaming_app.bssid_blacklist[i].bssid, bssid, ETH_ALEN) == 0) {
|
||||||
|
#if CONFIG_ESP_WIFI_ROAMING_AUTO_BLACKLISTING
|
||||||
|
if (g_roaming_app.bssid_blacklist[i].failures >= CONFIG_ESP_WIFI_ROAMING_MAX_CONN_FAILURES) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
return true;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
static void parse_scan_results_and_roam(void)
|
static void parse_scan_results_and_roam(void)
|
||||||
{
|
{
|
||||||
int8_t rssi_threshold = g_roaming_app.current_rssi_threshold;
|
int8_t rssi_threshold = g_roaming_app.current_rssi_threshold;
|
||||||
@@ -594,16 +729,18 @@ static void parse_scan_results_and_roam(void)
|
|||||||
int8_t rssi_diff = 0;
|
int8_t rssi_diff = 0;
|
||||||
uint8_t i;
|
uint8_t i;
|
||||||
int8_t best_ap_index = -1;
|
int8_t best_ap_index = -1;
|
||||||
wifi_ap_record_t ap_info;
|
|
||||||
roaming_app_get_ap_info(&ap_info);
|
|
||||||
for (i = 0; i < g_roaming_app.scanned_aps.current_count; i++) {
|
for (i = 0; i < g_roaming_app.scanned_aps.current_count; i++) {
|
||||||
rssi_diff = g_roaming_app.scanned_aps.ap_records[i].rssi - ap_info.rssi;
|
if (is_bssid_blacklisted(g_roaming_app.scanned_aps.ap_records[i].bssid)) {
|
||||||
|
ESP_LOGD(ROAMING_TAG, "BSSID " MACSTR " is blacklisted, skipping", MAC2STR(g_roaming_app.scanned_aps.ap_records[i].bssid));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
rssi_diff = g_roaming_app.scanned_aps.ap_records[i].rssi - g_roaming_app.current_bss.ap.rssi;
|
||||||
ESP_LOGD(ROAMING_TAG, "The difference between ("MACSTR", "MACSTR") with rssi (%d,%d) is : %d while the threshold is %d and the best rssi diff yet is %d, thecand_auth is %d",
|
ESP_LOGD(ROAMING_TAG, "The difference between ("MACSTR", "MACSTR") with rssi (%d,%d) is : %d while the threshold is %d and the best rssi diff yet is %d, thecand_auth is %d",
|
||||||
MAC2STR(g_roaming_app.scanned_aps.ap_records[i].bssid),MAC2STR(ap_info.bssid),
|
MAC2STR(g_roaming_app.scanned_aps.ap_records[i].bssid),MAC2STR(g_roaming_app.current_bss.ap.bssid),
|
||||||
g_roaming_app.scanned_aps.ap_records[i].rssi, ap_info.rssi,
|
g_roaming_app.scanned_aps.ap_records[i].rssi, g_roaming_app.current_bss.ap.rssi,
|
||||||
rssi_diff, rssi_threshold, best_rssi_diff, g_roaming_app.scanned_aps.ap_records[i].authmode);
|
rssi_diff, rssi_threshold, best_rssi_diff, g_roaming_app.scanned_aps.ap_records[i].authmode);
|
||||||
if ((memcmp(g_roaming_app.scanned_aps.ap_records[i].bssid, ap_info.bssid, ETH_ALEN) != 0) &&
|
if ((memcmp(g_roaming_app.scanned_aps.ap_records[i].bssid, g_roaming_app.current_bss.ap.bssid, ETH_ALEN) != 0) &&
|
||||||
candidate_profile_match(g_roaming_app.scanned_aps.ap_records[i]) && rssi_diff > best_rssi_diff ) {
|
candidate_security_match(g_roaming_app.scanned_aps.ap_records[i]) && rssi_diff > best_rssi_diff ) {
|
||||||
best_rssi_diff = rssi_diff;
|
best_rssi_diff = rssi_diff;
|
||||||
best_ap_index = i;
|
best_ap_index = i;
|
||||||
}
|
}
|
||||||
@@ -632,44 +769,41 @@ static void parse_scan_results_and_roam(void)
|
|||||||
static void scan_done_event_handler(void *arg, ETS_STATUS status)
|
static void scan_done_event_handler(void *arg, ETS_STATUS status)
|
||||||
{
|
{
|
||||||
if (status == ETS_OK) {
|
if (status == ETS_OK) {
|
||||||
ROAM_SCAN_RESULTS_LOCK();
|
|
||||||
ESP_LOGD(ROAMING_TAG, "Scan Done properly");
|
ESP_LOGD(ROAMING_TAG, "Scan Done properly");
|
||||||
g_roaming_app.scanned_aps.current_count = MAX_CANDIDATE_COUNT;
|
g_roaming_app.scanned_aps.current_count = MAX_CANDIDATE_COUNT;
|
||||||
esp_wifi_scan_get_ap_records(&g_roaming_app.scanned_aps.current_count, g_roaming_app.scanned_aps.ap_records);
|
esp_wifi_scan_get_ap_records(&g_roaming_app.scanned_aps.current_count, g_roaming_app.scanned_aps.ap_records);
|
||||||
print_ap_records(&g_roaming_app.scanned_aps);
|
print_ap_records(&g_roaming_app.scanned_aps);
|
||||||
parse_scan_results_and_roam();
|
parse_scan_results_and_roam();
|
||||||
ROAM_SCAN_RESULTS_UNLOCK();
|
|
||||||
} else {
|
} else {
|
||||||
ESP_LOGD(ROAMING_TAG, "Scan Done with error %d ", status);
|
ESP_LOGD(ROAMING_TAG, "Scan Done with error %d ", status);
|
||||||
}
|
}
|
||||||
ROAM_SCAN_RESULTS_LOCK();
|
|
||||||
g_roaming_app.scan_ongoing = false;
|
g_roaming_app.scan_ongoing = false;
|
||||||
ROAM_SCAN_RESULTS_UNLOCK();
|
|
||||||
}
|
}
|
||||||
static void conduct_scan(void)
|
static bool conduct_scan(void)
|
||||||
{
|
{
|
||||||
/* Update scan time in global structure */
|
|
||||||
gettimeofday(&g_roaming_app.scanned_aps.time, NULL);
|
gettimeofday(&g_roaming_app.scanned_aps.time, NULL);
|
||||||
/* Issue scan */
|
|
||||||
os_memset(&g_roaming_app.scanned_aps, 0, sizeof(struct scanned_ap_info));
|
os_memset(&g_roaming_app.scanned_aps, 0, sizeof(struct scanned_ap_info));
|
||||||
|
/* Issue scan */
|
||||||
if (esp_wifi_promiscuous_scan_start(&g_roaming_app.config.scan_config, scan_done_event_handler) < 0) {
|
if (esp_wifi_promiscuous_scan_start(&g_roaming_app.config.scan_config, scan_done_event_handler) < 0) {
|
||||||
ESP_LOGE(ROAMING_TAG, "failed to issue scan");
|
ESP_LOGE(ROAMING_TAG, "failed to issue scan");
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
ESP_LOGI(ROAMING_TAG, "Issued Scan");
|
ESP_LOGI(ROAMING_TAG, "Issued Scan");
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void determine_best_ap(int8_t rssi_threshold)
|
static void determine_best_ap(int8_t rssi_threshold)
|
||||||
{
|
{
|
||||||
struct timeval now;
|
struct timeval now;
|
||||||
gettimeofday(&now, NULL);
|
gettimeofday(&now, NULL);
|
||||||
ROAM_SCAN_RESULTS_LOCK();
|
|
||||||
/* If the scan results are recent enough or a scan is already ongoing we should not trigger a new scan */
|
/* If the scan results are recent enough or a scan is already ongoing we should not trigger a new scan */
|
||||||
if (!g_roaming_app.scan_ongoing) {
|
if (!g_roaming_app.scan_ongoing) {
|
||||||
g_roaming_app.scan_ongoing = true;
|
g_roaming_app.scan_ongoing = true;
|
||||||
g_roaming_app.current_rssi_threshold = rssi_threshold;
|
g_roaming_app.current_rssi_threshold = rssi_threshold;
|
||||||
if (time_diff_sec(&now,&g_roaming_app.scanned_aps.time) > SCAN_RESULTS_USABILITY_WINDOW) {
|
if (time_diff_sec(&now,&g_roaming_app.scanned_aps.time) > SCAN_RESULTS_USABILITY_WINDOW) {
|
||||||
conduct_scan();
|
if (!conduct_scan()) {
|
||||||
|
g_roaming_app.scan_ongoing = false;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
parse_scan_results_and_roam();
|
parse_scan_results_and_roam();
|
||||||
g_roaming_app.scan_ongoing = false;
|
g_roaming_app.scan_ongoing = false;
|
||||||
@@ -677,7 +811,6 @@ static void determine_best_ap(int8_t rssi_threshold)
|
|||||||
} else if(rssi_threshold < g_roaming_app.current_rssi_threshold) {
|
} else if(rssi_threshold < g_roaming_app.current_rssi_threshold) {
|
||||||
g_roaming_app.current_rssi_threshold = rssi_threshold;
|
g_roaming_app.current_rssi_threshold = rssi_threshold;
|
||||||
}
|
}
|
||||||
ROAM_SCAN_RESULTS_UNLOCK();
|
|
||||||
}
|
}
|
||||||
#if PERIODIC_SCAN_MONITORING
|
#if PERIODIC_SCAN_MONITORING
|
||||||
static void periodic_scan_roam(struct timeval *now)
|
static void periodic_scan_roam(struct timeval *now)
|
||||||
@@ -780,6 +913,7 @@ static int8_t parse_scan_chan_list(void)
|
|||||||
{
|
{
|
||||||
int8_t ret = 0;
|
int8_t ret = 0;
|
||||||
char *scan_chan_string = NULL;
|
char *scan_chan_string = NULL;
|
||||||
|
char *scan_chan_string_p = NULL;
|
||||||
if (validate_scan_chan_list(SCAN_PREFERRED_CHAN_LIST) == false) {
|
if (validate_scan_chan_list(SCAN_PREFERRED_CHAN_LIST) == false) {
|
||||||
ESP_LOGE(ROAMING_TAG, "scan chan list validation failed.");
|
ESP_LOGE(ROAMING_TAG, "scan chan list validation failed.");
|
||||||
ret = -1;
|
ret = -1;
|
||||||
@@ -793,22 +927,27 @@ static int8_t parse_scan_chan_list(void)
|
|||||||
}
|
}
|
||||||
strlcpy(scan_chan_string, SCAN_PREFERRED_CHAN_LIST, strlen(SCAN_PREFERRED_CHAN_LIST) + 1);
|
strlcpy(scan_chan_string, SCAN_PREFERRED_CHAN_LIST, strlen(SCAN_PREFERRED_CHAN_LIST) + 1);
|
||||||
char* token;
|
char* token;
|
||||||
token = strsep(&scan_chan_string, ",");
|
scan_chan_string_p = scan_chan_string;
|
||||||
|
token = strsep(&scan_chan_string_p, ",");
|
||||||
|
|
||||||
g_roaming_app.config.scan_config.channel_bitmap.ghz_2_channels = 0;
|
g_roaming_app.config.scan_config.channel_bitmap.ghz_2_channels = 0;
|
||||||
|
g_roaming_app.config.scan_config.channel_bitmap.ghz_5_channels = 0;
|
||||||
|
|
||||||
while (token != NULL) {
|
while (token != NULL) {
|
||||||
uint8_t channel = atoi(token);
|
uint8_t channel = atoi(token);
|
||||||
/* Check if the number is within the required range */
|
/* Check if the number is within the required range */
|
||||||
if (channel >= 1 && channel <= 14) {
|
if (channel >= 1 && channel <= 14) {
|
||||||
/* Check if the number is already present in the array */
|
|
||||||
g_roaming_app.config.scan_config.channel_bitmap.ghz_2_channels |= (1 << channel);
|
g_roaming_app.config.scan_config.channel_bitmap.ghz_2_channels |= (1 << channel);
|
||||||
|
#if CONFIG_SOC_WIFI_SUPPORT_5G
|
||||||
|
} else if (channel >= 36 && channel <= 177) {
|
||||||
|
g_roaming_app.config.scan_config.channel_bitmap.ghz_5_channels |= CHANNEL_TO_BIT(channel);
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
ESP_LOGE(ROAMING_TAG, "Channel out of range: %d", channel);
|
ESP_LOGE(ROAMING_TAG, "Channel out of range: %d", channel);
|
||||||
ret = -1;
|
ret = -1;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
token = strsep(&scan_chan_string, ",");
|
token = strsep(&scan_chan_string_p, ",");
|
||||||
}
|
}
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
@@ -818,7 +957,6 @@ cleanup:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static esp_err_t init_config_params(void)
|
static esp_err_t init_config_params(void)
|
||||||
{
|
{
|
||||||
g_roaming_app.config.backoff_time = ROAMING_BACKOFF_TIME;
|
g_roaming_app.config.backoff_time = ROAMING_BACKOFF_TIME;
|
||||||
@@ -828,9 +966,11 @@ static esp_err_t init_config_params(void)
|
|||||||
g_roaming_app.config.rssi_threshold_reduction_offset = RSSI_THRESHOLD_REDUCTION_OFFSET;
|
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_monitor = PERIODIC_SCAN_MONITORING;
|
||||||
|
#if PERIODIC_SCAN_MONITORING
|
||||||
g_roaming_app.config.scan_interval = SCAN_MONITOR_INTERVAL;
|
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_threshold = SCAN_MONITOR_RSSI_THRESHOLD;
|
||||||
g_roaming_app.config.scan_rssi_diff = SCAN_ROAM_RSSI_DIFF;
|
g_roaming_app.config.scan_rssi_diff = SCAN_ROAM_RSSI_DIFF;
|
||||||
|
#endif /* PERIODIC_SCAN_MONITORING */
|
||||||
|
|
||||||
g_roaming_app.config.legacy_roam_enabled = LEGACY_ROAM_ENABLED;
|
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_retry_cnt = BSS_TM_RETRY_COUNT;
|
||||||
@@ -846,9 +986,11 @@ static esp_err_t init_config_params(void)
|
|||||||
g_roaming_app.config.backoff_time, g_roaming_app.config.low_rssi_roam_trigger,
|
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);
|
g_roaming_app.config.low_rssi_threshold, g_roaming_app.config.rssi_threshold_reduction_offset);
|
||||||
|
|
||||||
|
#if PERIODIC_SCAN_MONITORING
|
||||||
ESP_LOGD(ROAMING_TAG, "scan_monitor=%d scan_interval=%d scan_rssi_threshold=%d scan_rssi_diff=%d",
|
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_monitor, g_roaming_app.config.scan_interval,
|
||||||
g_roaming_app.config.scan_rssi_threshold, g_roaming_app.config.scan_rssi_diff);
|
g_roaming_app.config.scan_rssi_threshold, g_roaming_app.config.scan_rssi_diff);
|
||||||
|
#endif /* PERIODIC_SCAN_MONITORING */
|
||||||
|
|
||||||
ESP_LOGD(ROAMING_TAG, "legacy_roam_enabled=%d, btm_retry_cnt=%d btm_roaming_enabled=%d",
|
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.legacy_roam_enabled,
|
||||||
@@ -864,14 +1006,6 @@ static esp_err_t init_config_params(void)
|
|||||||
|
|
||||||
static esp_err_t init_scan_config(void)
|
static esp_err_t init_scan_config(void)
|
||||||
{
|
{
|
||||||
if (!scan_results_lock) {
|
|
||||||
scan_results_lock = os_recursive_mutex_create();
|
|
||||||
if (!scan_results_lock) {
|
|
||||||
ESP_LOGE(ROAMING_TAG, "%s: failed to create scan results lock", __func__);
|
|
||||||
return ESP_FAIL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strcmp(DEFAULT_PREFERRED_SCAN_CHAN_LIST, SCAN_PREFERRED_CHAN_LIST)) {
|
if (strcmp(DEFAULT_PREFERRED_SCAN_CHAN_LIST, SCAN_PREFERRED_CHAN_LIST)) {
|
||||||
ESP_ERROR_CHECK(parse_scan_chan_list());
|
ESP_ERROR_CHECK(parse_scan_chan_list());
|
||||||
}
|
}
|
||||||
@@ -895,6 +1029,7 @@ void roam_init_app(void)
|
|||||||
ESP_LOGE(ROAMING_TAG, "No roaming method enabled. Roaming app cannot be initialized");
|
ESP_LOGE(ROAMING_TAG, "No roaming method enabled. Roaming app cannot be initialized");
|
||||||
return;
|
return;
|
||||||
#endif
|
#endif
|
||||||
|
memset(&g_roaming_app, 0, sizeof(g_roaming_app));
|
||||||
#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));
|
||||||
@@ -926,23 +1061,107 @@ void roam_deinit_app(void)
|
|||||||
|
|
||||||
#if PERIODIC_SCAN_MONITORING
|
#if PERIODIC_SCAN_MONITORING
|
||||||
g_roaming_app.periodic_scan_active = false;
|
g_roaming_app.periodic_scan_active = false;
|
||||||
|
eloop_cancel_timeout(roaming_app_periodic_scan_internal_handler, NULL, NULL);
|
||||||
#endif /*PERIODIC_SCAN_MONITORING*/
|
#endif /*PERIODIC_SCAN_MONITORING*/
|
||||||
#if PERIODIC_RRM_MONITORING
|
#if PERIODIC_RRM_MONITORING
|
||||||
ESP_ERROR_CHECK(esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_STA_NEIGHBOR_REP,
|
ESP_ERROR_CHECK(esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_STA_NEIGHBOR_REP,
|
||||||
&roaming_app_neighbor_report_recv_handler));
|
&roaming_app_neighbor_report_recv_handler));
|
||||||
/* Disabling the periodic scan and RRM events */
|
/* Disabling the periodic scan and RRM events */
|
||||||
g_roaming_app.periodic_rrm_active = false;
|
g_roaming_app.periodic_rrm_active = false;
|
||||||
if (neighbor_list_lock) {
|
eloop_cancel_timeout(roaming_app_periodic_rrm_internal_handler, NULL, NULL);
|
||||||
os_mutex_delete(neighbor_list_lock);
|
if (g_roaming_app.btm_neighbor_list) {
|
||||||
neighbor_list_lock = NULL;
|
os_free(g_roaming_app.btm_neighbor_list);
|
||||||
|
g_roaming_app.btm_neighbor_list = NULL;
|
||||||
}
|
}
|
||||||
#endif /*PERIODIC_RRM_MONITORING*/
|
#endif /*PERIODIC_RRM_MONITORING*/
|
||||||
if (scan_results_lock) {
|
|
||||||
os_mutex_delete(scan_results_lock);
|
|
||||||
scan_results_lock = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if CONFIG_ESP_WIFI_ROAMING_BSSID_BLACKLIST
|
||||||
|
static void roaming_app_blacklist_add_handler(void *ctx, void *data)
|
||||||
|
{
|
||||||
|
uint8_t *bssid = data;
|
||||||
|
if (g_roaming_app.bssid_blacklist_count >= CONFIG_ESP_WIFI_ROAMING_MAX_CANDIDATES) {
|
||||||
|
ESP_LOGE(ROAMING_TAG, "Blacklist is full");
|
||||||
|
os_free(bssid);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < g_roaming_app.bssid_blacklist_count; i++) {
|
||||||
|
if (memcmp(g_roaming_app.bssid_blacklist[i].bssid, bssid, ETH_ALEN) == 0) {
|
||||||
|
ESP_LOGD(ROAMING_TAG, "BSSID " MACSTR " already in blacklist", MAC2STR(bssid));
|
||||||
|
os_free(bssid);
|
||||||
|
return; // Already blacklisted
|
||||||
|
}
|
||||||
|
}
|
||||||
|
memcpy(g_roaming_app.bssid_blacklist[g_roaming_app.bssid_blacklist_count].bssid, bssid, ETH_ALEN);
|
||||||
|
#if CONFIG_ESP_WIFI_ROAMING_AUTO_BLACKLISTING
|
||||||
|
g_roaming_app.bssid_blacklist[g_roaming_app.bssid_blacklist_count].failures = CONFIG_ESP_WIFI_ROAMING_MAX_CONN_FAILURES;
|
||||||
|
#endif
|
||||||
|
gettimeofday(&g_roaming_app.bssid_blacklist[g_roaming_app.bssid_blacklist_count].timestamp, NULL);
|
||||||
|
g_roaming_app.bssid_blacklist_count++;
|
||||||
|
ESP_LOGI(ROAMING_TAG, "BSSID " MACSTR " added to blacklist", MAC2STR(bssid));
|
||||||
|
os_free(bssid);
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t esp_wifi_blacklist_add(const uint8_t *bssid)
|
||||||
|
{
|
||||||
|
if (!bssid) {
|
||||||
|
return ESP_ERR_INVALID_ARG;
|
||||||
|
}
|
||||||
|
uint8_t *bssid_copy = os_malloc(ETH_ALEN);
|
||||||
|
if (!bssid_copy) {
|
||||||
|
return ESP_ERR_NO_MEM;
|
||||||
|
}
|
||||||
|
memcpy(bssid_copy, bssid, ETH_ALEN);
|
||||||
|
if (eloop_register_timeout(0, 0, roaming_app_blacklist_add_handler, NULL, bssid_copy) != 0) {
|
||||||
|
os_free(bssid_copy);
|
||||||
|
return ESP_FAIL;
|
||||||
|
}
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void roaming_app_blacklist_remove_handler(void *ctx, void *data)
|
||||||
|
{
|
||||||
|
uint8_t *bssid = data;
|
||||||
|
int found_index = -1;
|
||||||
|
for (int i = 0; i < g_roaming_app.bssid_blacklist_count; i++) {
|
||||||
|
if (memcmp(g_roaming_app.bssid_blacklist[i].bssid, bssid, ETH_ALEN) == 0) {
|
||||||
|
found_index = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (found_index != -1) {
|
||||||
|
// Shift elements to fill the gap
|
||||||
|
int remaining_entries = g_roaming_app.bssid_blacklist_count - found_index - 1;
|
||||||
|
if (remaining_entries > 0) {
|
||||||
|
memmove(&g_roaming_app.bssid_blacklist[found_index], &g_roaming_app.bssid_blacklist[found_index + 1], remaining_entries * sizeof(struct blacklist_entry));
|
||||||
|
}
|
||||||
|
g_roaming_app.bssid_blacklist_count--;
|
||||||
|
ESP_LOGI(ROAMING_TAG, "BSSID " MACSTR " removed from blacklist", MAC2STR(bssid));
|
||||||
|
} else {
|
||||||
|
ESP_LOGD(ROAMING_TAG, "BSSID " MACSTR " not found in blacklist", MAC2STR(bssid));
|
||||||
|
}
|
||||||
|
os_free(bssid);
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t esp_wifi_blacklist_remove(const uint8_t *bssid)
|
||||||
|
{
|
||||||
|
if (!bssid) {
|
||||||
|
return ESP_ERR_INVALID_ARG;
|
||||||
|
}
|
||||||
|
uint8_t *bssid_copy = os_malloc(ETH_ALEN);
|
||||||
|
if (!bssid_copy) {
|
||||||
|
return ESP_ERR_NO_MEM;
|
||||||
|
}
|
||||||
|
memcpy(bssid_copy, bssid, ETH_ALEN);
|
||||||
|
if (eloop_register_timeout(0, 0, roaming_app_blacklist_remove_handler, NULL, bssid_copy) != 0) {
|
||||||
|
os_free(bssid_copy);
|
||||||
|
return ESP_FAIL;
|
||||||
|
}
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* No need for this to be done in pptask ctx */
|
/* No need for this to be done in pptask ctx */
|
||||||
esp_err_t roam_get_config_params(struct roam_config *config)
|
esp_err_t roam_get_config_params(struct roam_config *config)
|
||||||
{
|
{
|
||||||
@@ -962,9 +1181,11 @@ static int update_config_params(void *data)
|
|||||||
g_roaming_app.config.backoff_time, g_roaming_app.config.low_rssi_roam_trigger,
|
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);
|
g_roaming_app.config.low_rssi_threshold, g_roaming_app.config.rssi_threshold_reduction_offset);
|
||||||
|
|
||||||
|
#if PERIODIC_SCAN_MONITORING
|
||||||
ESP_LOGI(ROAMING_TAG, "scan_monitor=%d scan_interval=%d scan_rssi_threshold=%d scan_rssi_diff=%d",
|
ESP_LOGI(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_monitor, g_roaming_app.config.scan_interval,
|
||||||
g_roaming_app.config.scan_rssi_threshold, g_roaming_app.config.scan_rssi_diff);
|
g_roaming_app.config.scan_rssi_threshold, g_roaming_app.config.scan_rssi_diff);
|
||||||
|
#endif
|
||||||
|
|
||||||
ESP_LOGI(ROAMING_TAG, "legacy_roam_enabled=%d, btm_retry_cnt=%d btm_roaming_enabled=%d",
|
ESP_LOGI(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.legacy_roam_enabled,
|
||||||
|
|||||||
@@ -245,6 +245,7 @@ idf_component_register(SRCS "${srcs}" "${esp_srcs}" "${tls_src}" "${roaming_src}
|
|||||||
INCLUDE_DIRS include port/include esp_supplicant/include
|
INCLUDE_DIRS include port/include esp_supplicant/include
|
||||||
PRIV_INCLUDE_DIRS src src/utils esp_supplicant/src src/crypto
|
PRIV_INCLUDE_DIRS src src/utils esp_supplicant/src src/crypto
|
||||||
../esp_wifi/wifi_apps/roaming_app/include
|
../esp_wifi/wifi_apps/roaming_app/include
|
||||||
|
../esp_wifi/wifi_apps/roaming_app/src
|
||||||
LDFRAGMENTS ${linker_fragments}
|
LDFRAGMENTS ${linker_fragments}
|
||||||
PRIV_REQUIRES mbedtls esp_timer esp_wifi)
|
PRIV_REQUIRES mbedtls esp_timer esp_wifi)
|
||||||
|
|
||||||
|
|||||||
@@ -23,6 +23,8 @@
|
|||||||
#include "rsn_supp/wpa_i.h"
|
#include "rsn_supp/wpa_i.h"
|
||||||
#include "rsn_supp/wpa.h"
|
#include "rsn_supp/wpa.h"
|
||||||
#include "esp_private/wifi.h"
|
#include "esp_private/wifi.h"
|
||||||
|
#include "esp_wifi_types_generic.h"
|
||||||
|
#include "esp_roaming.h"
|
||||||
|
|
||||||
/* Utility Functions */
|
/* Utility Functions */
|
||||||
esp_err_t esp_supplicant_str_to_mac(const char *str, uint8_t dest[6])
|
esp_err_t esp_supplicant_str_to_mac(const char *str, uint8_t dest[6])
|
||||||
@@ -628,6 +630,9 @@ void wpa_supplicant_connect(struct wpa_supplicant *wpa_s,
|
|||||||
config->sta.channel = bss->channel;
|
config->sta.channel = bss->channel;
|
||||||
/* supplicant connect will only be called in case of bss transition(roaming) */
|
/* supplicant connect will only be called in case of bss transition(roaming) */
|
||||||
esp_wifi_internal_issue_disconnect(WIFI_REASON_BSS_TRANSITION_DISASSOC);
|
esp_wifi_internal_issue_disconnect(WIFI_REASON_BSS_TRANSITION_DISASSOC);
|
||||||
|
#if CONFIG_ESP_WIFI_ENABLE_ROAMING_APP
|
||||||
|
esp_wifi_roaming_set_current_bssid(bss->bssid);
|
||||||
|
#endif
|
||||||
esp_wifi_set_config(WIFI_IF_STA, config);
|
esp_wifi_set_config(WIFI_IF_STA, config);
|
||||||
os_free(config);
|
os_free(config);
|
||||||
esp_wifi_connect();
|
esp_wifi_connect();
|
||||||
|
|||||||
@@ -31,6 +31,7 @@
|
|||||||
#include "esp_eap_client.h"
|
#include "esp_eap_client.h"
|
||||||
#include "esp_common_i.h"
|
#include "esp_common_i.h"
|
||||||
#include "esp_owe_i.h"
|
#include "esp_owe_i.h"
|
||||||
|
#include "esp_roaming.h"
|
||||||
|
|
||||||
#include "esp_wps.h"
|
#include "esp_wps.h"
|
||||||
#include "esp_wps_i.h"
|
#include "esp_wps_i.h"
|
||||||
@@ -140,6 +141,9 @@ bool wpa_attach(void)
|
|||||||
ret = (esp_wifi_register_eapol_txdonecb_internal(eapol_txcb) == ESP_OK);
|
ret = (esp_wifi_register_eapol_txdonecb_internal(eapol_txcb) == ESP_OK);
|
||||||
}
|
}
|
||||||
esp_set_scan_ie();
|
esp_set_scan_ie();
|
||||||
|
#if CONFIG_ESP_WIFI_ENABLE_ROAMING_APP
|
||||||
|
roam_init_app();
|
||||||
|
#endif
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -192,6 +196,9 @@ void wpa_ap_get_peer_spp_msg(void *sm_data, bool *spp_cap, bool *spp_req)
|
|||||||
bool wpa_deattach(void)
|
bool wpa_deattach(void)
|
||||||
{
|
{
|
||||||
struct wpa_sm *sm = &gWpaSm;
|
struct wpa_sm *sm = &gWpaSm;
|
||||||
|
#if CONFIG_ESP_WIFI_ENABLE_ROAMING_APP
|
||||||
|
roam_deinit_app();
|
||||||
|
#endif
|
||||||
esp_wpa3_free_sae_data();
|
esp_wpa3_free_sae_data();
|
||||||
#ifdef CONFIG_ESP_WIFI_ENTERPRISE_SUPPORT
|
#ifdef CONFIG_ESP_WIFI_ENTERPRISE_SUPPORT
|
||||||
if (sm->wpa_sm_eap_disable) {
|
if (sm->wpa_sm_eap_disable) {
|
||||||
|
|||||||
@@ -189,4 +189,9 @@ void wpa_sm_disassociate(struct wpa_sm *sm, int reason_code)
|
|||||||
{
|
{
|
||||||
/*check if need clear internal state and data value*/
|
/*check if need clear internal state and data value*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u8 wpa_supplicant_get_transition_disable(void)
|
||||||
|
{
|
||||||
|
return wpa_sm_get_transition_disable(&gWpaSm);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2019-2021 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2019-2025 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@@ -7,6 +7,8 @@
|
|||||||
#ifndef WPAS_GLUE_H
|
#ifndef WPAS_GLUE_H
|
||||||
#define WPAS_GLUE_H
|
#define WPAS_GLUE_H
|
||||||
|
|
||||||
|
#include "rsn_supp/wpa_i.h"
|
||||||
|
|
||||||
u8 *wpa_sm_alloc_eapol(struct wpa_sm *sm, u8 type,
|
u8 *wpa_sm_alloc_eapol(struct wpa_sm *sm, u8 type,
|
||||||
const void *data, u16 data_len,
|
const void *data, u16 data_len,
|
||||||
size_t *msg_len, void **data_pos);
|
size_t *msg_len, void **data_pos);
|
||||||
@@ -35,4 +37,6 @@ void wpa_supplicant_transition_disable(struct wpa_sm *sm, u8 bitmap);
|
|||||||
|
|
||||||
int hostapd_send_eapol(const u8 *source, const u8 *sta_addr,
|
int hostapd_send_eapol(const u8 *source, const u8 *sta_addr,
|
||||||
const u8 *data, size_t data_len);
|
const u8 *data, size_t data_len);
|
||||||
|
|
||||||
|
u8 wpa_supplicant_get_transition_disable(void);
|
||||||
#endif /* WPAS_GLUE_H */
|
#endif /* WPAS_GLUE_H */
|
||||||
|
|||||||
@@ -1340,6 +1340,7 @@ static void wpa_supplicant_process_3_of_4(struct wpa_sm *sm,
|
|||||||
|
|
||||||
if (ie.transition_disable) {
|
if (ie.transition_disable) {
|
||||||
wpa_supplicant_transition_disable(sm, ie.transition_disable[0]);
|
wpa_supplicant_transition_disable(sm, ie.transition_disable[0]);
|
||||||
|
sm->transition_disable = ie.transition_disable[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sm->key_install && sm->key_info & WPA_KEY_INFO_INSTALL && sm->use_ext_key_id) {
|
if (sm->key_install && sm->key_info & WPA_KEY_INFO_INSTALL && sm->use_ext_key_id) {
|
||||||
@@ -1357,6 +1358,11 @@ failed:
|
|||||||
wpa_sm_deauthenticate(sm, WLAN_REASON_UNSPECIFIED);
|
wpa_sm_deauthenticate(sm, WLAN_REASON_UNSPECIFIED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u8 wpa_sm_get_transition_disable(struct wpa_sm *sm)
|
||||||
|
{
|
||||||
|
return sm->transition_disable;
|
||||||
|
}
|
||||||
|
|
||||||
static int wpa_supplicant_activate_ptk(struct wpa_sm *sm)
|
static int wpa_supplicant_activate_ptk(struct wpa_sm *sm)
|
||||||
{
|
{
|
||||||
int keylen;
|
int keylen;
|
||||||
|
|||||||
@@ -9,6 +9,8 @@
|
|||||||
#ifndef WPA_I_H
|
#ifndef WPA_I_H
|
||||||
#define WPA_I_H
|
#define WPA_I_H
|
||||||
|
|
||||||
|
#include "common/defs.h"
|
||||||
|
|
||||||
extern struct wpa_sm gWpaSm;
|
extern struct wpa_sm gWpaSm;
|
||||||
#define DEFAULT_EAPOL_VERSION 1
|
#define DEFAULT_EAPOL_VERSION 1
|
||||||
|
|
||||||
@@ -86,6 +88,7 @@ struct wpa_sm {
|
|||||||
struct wpa_gtk_data gd; //used for calllback save param
|
struct wpa_gtk_data gd; //used for calllback save param
|
||||||
u16 key_info; //used for txcallback param
|
u16 key_info; //used for txcallback param
|
||||||
u16 txcb_flags;
|
u16 txcb_flags;
|
||||||
|
u8 transition_disable;
|
||||||
bool ap_notify_completed_rsne;
|
bool ap_notify_completed_rsne;
|
||||||
wifi_pmf_config_t pmf_cfg;
|
wifi_pmf_config_t pmf_cfg;
|
||||||
u8 eapol1_count;
|
u8 eapol1_count;
|
||||||
@@ -207,6 +210,8 @@ int wpa_set_bss(char *macddr, char * bssid, u8 pairwise_cipher, u8 group_cipher,
|
|||||||
|
|
||||||
int wpa_sm_rx_eapol(u8 *src_addr, u8 *buf, u32 len);
|
int wpa_sm_rx_eapol(u8 *src_addr, u8 *buf, u32 len);
|
||||||
|
|
||||||
|
u8 wpa_sm_get_transition_disable(struct wpa_sm *sm);
|
||||||
|
|
||||||
int wpa_derive_ptk_ft(struct wpa_sm *sm, const unsigned char *src_addr,
|
int wpa_derive_ptk_ft(struct wpa_sm *sm, const unsigned char *src_addr,
|
||||||
const struct wpa_eapol_key *key, struct wpa_ptk *ptk);
|
const struct wpa_eapol_key *key, struct wpa_ptk *ptk);
|
||||||
#endif /* WPA_I_H */
|
#endif /* WPA_I_H */
|
||||||
|
|||||||
Reference in New Issue
Block a user