fix(wpa_supplicant): Add two separate flags for RRM and WNM

Added two separate flags CONFIG_RRM(80211k) and CONFIG_WNM(80211v)
    flags under IEEE80211KV support flag.
This commit is contained in:
Aditi
2024-10-01 18:35:32 +05:30
committed by Shreyas Sheth
parent 356d2511eb
commit b49a48ae8e
6 changed files with 184 additions and 110 deletions

View File

@ -540,9 +540,37 @@ menu "Wi-Fi"
and on the radio environment. Current implementation adds beacon report,
link measurement, neighbor report.
config ESP_WIFI_RRM_SUPPORT
bool "Enable 802.11k APIs Support"
depends on ESP_WIFI_11KV_SUPPORT
default n
help
Select this option to enable 802.11k APIs(RRM support).
Only APIs which are helpful for network assisted roaming
are supported for now.
Enable this option with RRM enabled in sta config
to make device ready for network assisted roaming.
RRM: Radio measurements enable STAs to understand the radio environment,
it enables STAs to observe and gather data on radio link performance
and on the radio environment. Current implementation adds beacon report,
link measurement, neighbor report.
config ESP_WIFI_WNM_SUPPORT
bool "Enable 802.11v APIs Support"
depends on ESP_WIFI_11KV_SUPPORT
default n
help
Select this option to enable 802.11v APIs(BTM support).
Only APIs which are helpful for network assisted roaming
are supported for now.
Enable this option with BTM enabled in sta config
to make device ready for network assisted roaming.
BTM: BSS transition management enables an AP to request a station to transition
to a specific AP, or to indicate to a station a set of preferred APs.
config ESP_WIFI_SCAN_CACHE
bool "Keep scan results in cache"
depends on ESP_WIFI_11KV_SUPPORT
depends on ESP_WIFI_RRM_SUPPORT
default n
help
Keep scan results in cache, if not enabled, those
@ -551,6 +579,8 @@ menu "Wi-Fi"
config ESP_WIFI_MBO_SUPPORT
bool "Enable Multi Band Operation Certification Support"
default n
select ESP_WIFI_RRM_SUPPORT
select ESP_WIFI_WNM_SUPPORT
select ESP_WIFI_11KV_SUPPORT
select ESP_WIFI_SCAN_CACHE
help

View File

@ -174,8 +174,11 @@ endif()
if(CONFIG_ESP_WIFI_11KV_SUPPORT OR CONFIG_ESP_WIFI_11R_SUPPORT)
set(roaming_src
"src/common/ieee802_11_common.c")
if(CONFIG_ESP_WIFI_11KV_SUPPORT)
set(roaming_src ${roaming_src} "src/common/rrm.c" "src/common/wnm_sta.c")
if(CONFIG_ESP_WIFI_RRM_SUPPORT)
set(roaming_src ${roaming_src} "src/common/rrm.c")
endif()
if(CONFIG_ESP_WIFI_WNM_SUPPORT)
set(roaming_src ${roaming_src} "src/common/wnm_sta.c")
endif()
if(CONFIG_ESP_WIFI_11R_SUPPORT)
set(roaming_src ${roaming_src} "src/rsn_supp/wpa_ft.c")
@ -285,6 +288,12 @@ endif()
if(CONFIG_ESP_WIFI_11KV_SUPPORT)
target_compile_definitions(${COMPONENT_LIB} PRIVATE CONFIG_SUPPLICANT_TASK CONFIG_WNM CONFIG_RRM CONFIG_IEEE80211KV)
endif()
if(CONFIG_ESP_WIFI_RRM_SUPPORT)
target_compile_definitions(${COMPONENT_LIB} PRIVATE CONFIG_SUPPLICANT_TASK CONFIG_RRM)
endif()
if(CONFIG_ESP_WIFI_WNM_SUPPORT)
target_compile_definitions(${COMPONENT_LIB} PRIVATE CONFIG_SUPPLICANT_TASK CONFIG_WNM)
endif()
if(CONFIG_ESP_WIFI_11R_SUPPORT)
target_compile_definitions(${COMPONENT_LIB} PRIVATE CONFIG_IEEE80211R)
endif()

View File

@ -71,7 +71,7 @@ static int handle_action_frm(u8 *frame, size_t len,
}
#endif /* CONFIG_SUPPLICANT_TASK */
#if defined(CONFIG_IEEE80211KV)
#if defined(CONFIG_RRM)
static void handle_rrm_frame(struct wpa_supplicant *wpa_s, u8 *sender,
u8 *payload, size_t len, int8_t rssi)
{
@ -88,6 +88,7 @@ static void handle_rrm_frame(struct wpa_supplicant *wpa_s, u8 *sender,
payload + 1, len - 1, rssi);
}
}
#endif /* CONFIG_RRM */
static int mgmt_rx_action(u8 *frame, size_t len, u8 *sender, int8_t rssi, u8 channel)
{
@ -103,15 +104,18 @@ static int mgmt_rx_action(u8 *frame, size_t len, u8 *sender, int8_t rssi, u8 cha
category = *frame++;
len--;
#if defined(CONFIG_WNM)
if (category == WLAN_ACTION_WNM) {
ieee802_11_rx_wnm_action(wpa_s, sender, frame, len);
} else if (category == WLAN_ACTION_RADIO_MEASUREMENT) {
}
#endif /* CONFIG_WNM */
#if defined(CONFIG_RRM)
if (category == WLAN_ACTION_RADIO_MEASUREMENT) {
handle_rrm_frame(wpa_s, sender, frame, len, rssi);
}
#endif /* CONFIG_RRM */
return 0;
}
#endif /* defined(CONFIG_IEEE80211KV) */
#ifdef CONFIG_SUPPLICANT_TASK
static void btm_rrm_task(void *pvParameters)
@ -189,16 +193,20 @@ static void register_mgmt_frames(struct wpa_supplicant *wpa_s)
/* subtype is defined only for action frame */
wpa_s->subtype = 0;
#ifdef CONFIG_IEEE80211KV
#ifdef CONFIG_RRM
/* current supported features in supplicant: rrm and btm */
if (esp_wifi_is_rm_enabled_internal(WIFI_IF_STA))
if (esp_wifi_is_rm_enabled_internal(WIFI_IF_STA)) {
wpa_s->subtype = 1 << WLAN_ACTION_RADIO_MEASUREMENT;
if (esp_wifi_is_btm_enabled_internal(WIFI_IF_STA))
}
#endif /* CONFIG_RRM */
#ifdef CONFIG_WNM
if (esp_wifi_is_btm_enabled_internal(WIFI_IF_STA)) {
wpa_s->subtype |= 1 << WLAN_ACTION_WNM;
if (wpa_s->subtype)
}
#endif /* CONFIG_WNM */
if (wpa_s->subtype) {
wpa_s->type |= 1 << WLAN_FC_STYPE_ACTION;
#endif /* CONFIG_IEEE80211KV */
}
#ifdef CONFIG_IEEE80211R
/* register auth/assoc frames if FT is enabled */
@ -270,7 +278,7 @@ static int ieee80211_handle_rx_frm(u8 type, u8 *frame, size_t len, u8 *sender,
int ret = 0;
switch (type) {
#if defined(CONFIG_IEEE80211R) || defined(CONFIG_IEEE80211KV)
#if defined(CONFIG_IEEE80211KV) || defined(CONFIG_IEEE80211R)
case WLAN_FC_STYPE_BEACON:
case WLAN_FC_STYPE_PROBE_RESP:
ret = esp_handle_beacon_probe(type, frame, len, sender, rssi, channel, current_tsf);
@ -365,10 +373,10 @@ int esp_supplicant_common_init(struct wpa_funcs *wpa_cb)
}
s_supplicant_task_init_done = true;
#endif /* CONFIG_SUPPLICANT_TASK */
#ifdef CONFIG_IEEE80211KV
#if defined(CONFIG_RRM)
wpas_rrm_reset(wpa_s);
wpas_clear_beacon_rep_data(wpa_s);
#endif /* CONFIG_IEEE80211KV */
#endif /* defined(CONFIG_RRM) */
esp_scan_init(wpa_s);
#endif /* defined(CONFIG_IEEE80211KV) || defined(CONFIG_IEEE80211R) */
@ -398,10 +406,10 @@ void esp_supplicant_common_deinit(void)
#if defined(CONFIG_IEEE80211KV) || defined(CONFIG_IEEE80211R)
esp_scan_deinit(wpa_s);
#ifdef CONFIG_IEEE80211KV
#if defined(CONFIG_RRM)
wpas_rrm_reset(wpa_s);
wpas_clear_beacon_rep_data(wpa_s);
#endif /* CONFIG_IEEE80211KV */
#endif /* defined(CONFIG_RRM) */
#endif /* defined(CONFIG_IEEE80211KV) || defined(CONFIG_IEEE80211R) */
if (wpa_s->type) {
wpa_s->type = 0;
@ -459,10 +467,16 @@ void supplicant_sta_disconn_handler(void)
#if defined(CONFIG_IEEE80211KV) || defined(CONFIG_IEEE80211R)
struct wpa_supplicant *wpa_s = &g_wpa_supp;
#ifdef CONFIG_IEEE80211KV
#if defined(CONFIG_RRM)
wpas_rrm_reset(wpa_s);
wpas_clear_beacon_rep_data(wpa_s);
#endif /* CONFIG_IEEE80211KV */
/* Not clearing in case of roaming disconnect as BTM induced connection
* itself sets a specific bssid and channel to connect to before disconnection.
* Subsequent connections or disconnections will clear this flag */
if (reason_code != WIFI_REASON_ROAMING) {
clear_bssid_flag_and_channel(wpa_s);
}
#endif /* defined(CONFIG_RRM) */
if (wpa_s->current_bss) {
wpa_s->current_bss = NULL;
}
@ -476,7 +490,7 @@ void supplicant_sta_disconn_handler(void)
}
#if defined(CONFIG_IEEE80211KV) || defined(CONFIG_IEEE80211R)
#ifdef CONFIG_IEEE80211KV
#if defined(CONFIG_RRM)
bool esp_rrm_is_rrm_supported_connection(void)
{
struct wpa_supplicant *wpa_s = &g_wpa_supp;
@ -520,6 +534,33 @@ int esp_rrm_send_neighbor_rep_request(neighbor_rep_request_cb cb,
return wpas_rrm_send_neighbor_rep_request(wpa_s, &wpa_ssid, 0, 0, cb, cb_ctx);
}
static size_t get_rm_enabled_ie(uint8_t *ie, size_t len)
{
uint8_t rrm_ie[7] = {0};
uint8_t rrm_ie_len = 5;
uint8_t *pos = rrm_ie;
if (!esp_wifi_is_rm_enabled_internal(WIFI_IF_STA)) {
return 0;
}
*pos++ = WLAN_EID_RRM_ENABLED_CAPABILITIES;
*pos++ = rrm_ie_len;
*pos |= WLAN_RRM_CAPS_LINK_MEASUREMENT;
*pos |= WLAN_RRM_CAPS_BEACON_REPORT_PASSIVE |
#ifdef SCAN_CACHE_SUPPORTED
WLAN_RRM_CAPS_BEACON_REPORT_TABLE |
#endif /* SCAN_CACHE_SUPPORTED */
WLAN_RRM_CAPS_BEACON_REPORT_ACTIVE;
os_memcpy(ie, rrm_ie, sizeof(rrm_ie));
return rrm_ie_len + 2;
}
#endif /* defined(CONFIG_RRM) */
#if defined(CONFIG_WNM)
bool esp_wnm_is_btm_supported_connection(void)
{
struct wpa_supplicant *wpa_s = &g_wpa_supp;
@ -555,62 +596,45 @@ int esp_wnm_send_bss_transition_mgmt_query(enum btm_query_reason query_reason,
return wnm_send_bss_transition_mgmt_query(wpa_s, query_reason, btm_candidates, cand_list);
}
#ifdef CONFIG_MBO
int esp_mbo_update_non_pref_chan(struct non_pref_chan_s *non_pref_chan)
static uint8_t get_extended_caps_ie(uint8_t *ie, size_t len)
{
int ret = wpas_mbo_update_non_pref_chan(&g_wpa_supp, non_pref_chan);
uint8_t ext_caps_ie[5] = {0};
uint8_t ext_caps_ie_len = 3;
uint8_t *pos = ext_caps_ie;
wifi_ioctl_config_t cfg = {0};
esp_err_t err = 0;
return ret;
}
#endif /* CONFIG_MBO */
void wpa_supplicant_connect(struct wpa_supplicant *wpa_s,
struct wpa_bss *bss, char *ssid)
{
wifi_config_t *config = os_zalloc(sizeof(wifi_config_t));
if (!config) {
wpa_printf(MSG_ERROR, "failed to allocate memory");
return;
}
esp_wifi_get_config(WIFI_IF_STA, config);
/* We only support roaming in same ESS, therefore only bssid setting is needed */
os_memcpy(config->sta.bssid, bss->bssid, ETH_ALEN);
config->sta.bssid_set = 1;
/* supplicant connect will only be called in case of bss transition(roaming) */
esp_wifi_internal_issue_disconnect(WIFI_REASON_BSS_TRANSITION_DISASSOC);
esp_wifi_set_config(WIFI_IF_STA, config);
os_free(config);
esp_wifi_connect();
}
static size_t get_rm_enabled_ie(uint8_t *ie, size_t len)
{
uint8_t rrm_ie[7] = {0};
uint8_t rrm_ie_len = 5;
uint8_t *pos = rrm_ie;
if (!esp_wifi_is_rm_enabled_internal(WIFI_IF_STA)) {
if (!esp_wifi_is_btm_enabled_internal(WIFI_IF_STA)) {
return 0;
}
*pos++ = WLAN_EID_RRM_ENABLED_CAPABILITIES;
*pos++ = rrm_ie_len;
*pos |= WLAN_RRM_CAPS_LINK_MEASUREMENT;
*pos++ = WLAN_EID_EXT_CAPAB;
*pos++ = ext_caps_ie_len;
*pos |= WLAN_RRM_CAPS_BEACON_REPORT_PASSIVE |
#ifdef SCAN_CACHE_SUPPORTED
WLAN_RRM_CAPS_BEACON_REPORT_TABLE |
#endif /* SCAN_CACHE_SUPPORTED */
WLAN_RRM_CAPS_BEACON_REPORT_ACTIVE;
err = esp_wifi_internal_ioctl(WIFI_IOCTL_GET_STA_HT2040_COEX, &cfg);
if (err == ESP_OK && cfg.data.ht2040_coex.enable) {
*pos++ |= BIT(WLAN_EXT_CAPAB_20_40_COEX);
} else {
*pos++ = 0;
}
*pos ++ = 0;
#define CAPAB_BSS_TRANSITION BIT(3)
*pos |= CAPAB_BSS_TRANSITION;
#undef CAPAB_BSS_TRANSITION
os_memcpy(ie, ext_caps_ie, sizeof(ext_caps_ie));
os_memcpy(ie, rrm_ie, sizeof(rrm_ie));
return rrm_ie_len + 2;
return ext_caps_ie_len + 2;
}
#endif /* defined(CONFIG_WNM) */
#ifdef CONFIG_MBO
int esp_mbo_update_non_pref_chan(struct non_pref_chan_s *non_pref_chan)
{
int ret = wpas_mbo_update_non_pref_chan(&g_wpa_supp, non_pref_chan);
return ret;
}
static size_t get_mbo_oce_scan_ie(uint8_t *ie, size_t len)
{
uint8_t mbo_ie[32] = {0};
@ -667,41 +691,31 @@ static uint8_t get_operating_class_ie(uint8_t *ie, size_t len)
}
#endif /* CONFIG_MBO */
static uint8_t get_extended_caps_ie(uint8_t *ie, size_t len)
void wpa_supplicant_connect(struct wpa_supplicant *wpa_s,
struct wpa_bss *bss, char *ssid)
{
uint8_t ext_caps_ie[5] = {0};
uint8_t ext_caps_ie_len = 3;
uint8_t *pos = ext_caps_ie;
wifi_ioctl_config_t cfg = {0};
esp_err_t err = 0;
wifi_config_t *config = os_zalloc(sizeof(wifi_config_t));
if (!esp_wifi_is_btm_enabled_internal(WIFI_IF_STA)) {
return 0;
if (!config) {
wpa_printf(MSG_ERROR, "failed to allocate memory");
return;
}
*pos++ = WLAN_EID_EXT_CAPAB;
*pos++ = ext_caps_ie_len;
err = esp_wifi_internal_ioctl(WIFI_IOCTL_GET_STA_HT2040_COEX, &cfg);
if (err == ESP_OK && cfg.data.ht2040_coex.enable) {
*pos++ |= BIT(WLAN_EXT_CAPAB_20_40_COEX);
} else {
*pos++ = 0;
}
*pos ++ = 0;
#define CAPAB_BSS_TRANSITION BIT(3)
*pos |= CAPAB_BSS_TRANSITION;
#undef CAPAB_BSS_TRANSITION
os_memcpy(ie, ext_caps_ie, sizeof(ext_caps_ie));
return ext_caps_ie_len + 2;
esp_wifi_get_config(WIFI_IF_STA, config);
/* We only support roaming in same ESS, therefore only bssid setting is needed */
os_memcpy(config->sta.bssid, bss->bssid, ETH_ALEN);
config->sta.bssid_set = 1;
config->sta.channel = bss->channel;
/* supplicant connect will only be called in case of bss transition(roaming) */
esp_wifi_internal_issue_disconnect(WIFI_REASON_BSS_TRANSITION_DISASSOC);
esp_wifi_set_config(WIFI_IF_STA, config);
os_free(config);
esp_wifi_connect();
}
#endif /* CONFIG_IEEE80211KV */
void esp_set_scan_ie(void)
{
#ifdef CONFIG_IEEE80211KV
#ifdef CONFIG_WNM
#define SCAN_IE_LEN 64
uint8_t *ie, *pos;
size_t len = SCAN_IE_LEN, ie_len;
@ -724,7 +738,7 @@ void esp_set_scan_ie(void)
esp_wifi_set_appie_internal(WIFI_APPIE_PROBEREQ, ie, SCAN_IE_LEN - len, 0);
os_free(ie);
#undef SCAN_IE_LEN
#endif /* CONFIG_IEEE80211KV */
#endif /* defined(CONFIG_WNM) */
}
#ifdef CONFIG_IEEE80211R
@ -758,10 +772,12 @@ static size_t add_mdie(uint8_t *bssid, uint8_t *ie, size_t len)
return mdie_len;
}
#endif /* CONFIG_IEEE80211R */
<<<<<<< HEAD
#ifdef CONFIG_IEEE80211R
=======
>>>>>>> 9cce89fea9e... fix(wpa_supplicant): Add two separate flags for RRM and WNM
int wpa_sm_update_ft_ies(struct wpa_sm *sm, const u8 *md,
const u8 *ies, size_t ies_len, bool auth_ie)
{
@ -859,6 +875,23 @@ int esp_supplicant_post_evt(uint32_t evt_id, uint32_t data)
}
#endif /* CONFIG_SUPPLICANT_TASK */
#else /* defined(CONFIG_IEEE80211KV) || defined(CONFIG_IEEE80211R) */
void esp_set_scan_ie(void) { }
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)
{
return -1;
}
int esp_rrm_send_neighbor_rep_request(neighbor_rep_request_cb cb,
void *cb_ctx)
{
@ -872,7 +905,6 @@ int esp_wnm_send_bss_transition_mgmt_query(enum btm_query_reason query_reason,
return -1;
}
void esp_set_scan_ie(void) { }
#endif /* defined(CONFIG_IEEE80211KV) || defined(CONFIG_IEEE80211R) */
#if defined(CONFIG_IEEE80211KV) || defined(CONFIG_IEEE80211R) || defined(CONFIG_WPA3_SAE)
@ -887,10 +919,10 @@ void esp_set_assoc_ie(uint8_t *bssid, const u8 *ies, size_t ies_len, bool mdie)
ie = os_malloc(ASSOC_IE_LEN + ies_len);
if (!ie) {
wpa_printf(MSG_ERROR, "failed to allocate ie");
return;
}
return;
}
pos = ie;
#ifdef CONFIG_IEEE80211KV
#if defined(CONFIG_RRM)
ie_len = get_rm_enabled_ie(pos, len);
pos += ie_len;
len -= ie_len;
@ -902,7 +934,7 @@ void esp_set_assoc_ie(uint8_t *bssid, const u8 *ies, size_t ies_len, bool mdie)
pos += ie_len;
len -= ie_len;
#endif /* CONFIG_MBO */
#endif /* CONFIG_IEEE80211KV */
#endif /* defined(CONFIG_RRM) */
#ifdef CONFIG_IEEE80211R
if (mdie) {
ie_len = add_mdie(bssid, pos, len);

View File

@ -12,7 +12,7 @@
struct wpa_funcs;
extern struct wpa_supplicant g_wpa_supp;
#ifdef CONFIG_IEEE80211KV
#if defined(CONFIG_RRM) || defined(CONFIG_WNM)
struct ieee_mgmt_frame {
u8 sender[ETH_ALEN];
u8 channel;
@ -39,7 +39,7 @@ void esp_get_tx_power(uint8_t *tx_power);
#ifdef CONFIG_MBO
bool mbo_bss_profile_match(u8 *bssid);
#endif
#endif
#endif /* defined(CONFIG_RRM) || defined(CONFIG_WNM) */
int esp_supplicant_common_init(struct wpa_funcs *wpa_cb);
void esp_supplicant_common_deinit(void);
void esp_supplicant_unset_all_appie(void);

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -44,7 +44,7 @@ static void scan_done_event_handler(void *arg, ETS_STATUS status)
#endif /*CONFIG_SUPPLICANT_TASK*/
}
#if defined(CONFIG_IEEE80211KV)
#if defined(CONFIG_WNM)
static void handle_wnm_scan_done(struct wpa_supplicant *wpa_s)
{
struct wpa_bss *bss = wpa_bss_get_next_bss(wpa_s, wpa_s->current_bss);
@ -77,11 +77,14 @@ void esp_supplicant_handle_scan_done_evt(void)
struct wpa_supplicant *wpa_s = &g_wpa_supp;
wpa_printf(MSG_INFO, "scan done received");
#if defined(CONFIG_IEEE80211KV)
#if defined(CONFIG_RRM)
/* Check which module started this, call the respective function */
if (wpa_s->scan_reason == REASON_RRM_BEACON_REPORT) {
wpas_beacon_rep_scan_process(wpa_s, wpa_s->scan_start_tsf);
} else if (wpa_s->scan_reason == REASON_WNM_BSS_TRANS_REQ) {
}
#endif
#if defined(CONFIG_WNM)
if (wpa_s->scan_reason == REASON_WNM_BSS_TRANS_REQ) {
handle_wnm_scan_done(wpa_s);
}
#endif

View File

@ -268,7 +268,7 @@ static int ieee802_11_parse_extension(struct wpa_supplicant *wpa_s, const struct
*/
int ieee802_11_parse_elems(struct wpa_supplicant *wpa_s, const u8 *start, size_t len)
{
#if defined(CONFIG_RRM) || defined(CONFIG_SAE_PK)
#if defined(CONFIG_RRM) || defined(CONFIG_WNM) || defined(CONFIG_SAE_PK)
const struct element *elem;
u8 unknown = 0;
@ -297,7 +297,7 @@ int ieee802_11_parse_elems(struct wpa_supplicant *wpa_s, const u8 *start, size_t
}
break;
#endif /*CONFIG_SAE_PK*/
#ifdef CONFIG_RRM
#ifdef CONFIG_WNM
case WLAN_EID_EXT_CAPAB:
/* extended caps can go beyond 8 octacts but we aren't using them now */
os_memcpy(wpa_s->extend_caps, pos, 5);
@ -311,7 +311,7 @@ int ieee802_11_parse_elems(struct wpa_supplicant *wpa_s, const u8 *start, size_t
if (unknown)
return -1;
#endif /* defined(CONFIG_RRM) || defined(CONFIG_SAE_PK) */
#endif /* defined(CONFIG_RRM) || defined(CONFIG_WNM) || defined(CONFIG_SAE_PK) */
return 0;
}