diff --git a/src/common/ieee802_11_defs.h b/src/common/ieee802_11_defs.h index 10ad2eeb1..bcef88abb 100644 --- a/src/common/ieee802_11_defs.h +++ b/src/common/ieee802_11_defs.h @@ -246,6 +246,7 @@ #define WLAN_EID_SECONDARY_CHANNEL_OFFSET 62 #define WLAN_EID_WAPI 68 #define WLAN_EID_TIME_ADVERTISEMENT 69 +#define WLAN_EID_RRM_ENABLED_CAPABILITIES 70 #define WLAN_EID_20_40_BSS_COEXISTENCE 72 #define WLAN_EID_20_40_BSS_INTOLERANT 73 #define WLAN_EID_OVERLAPPING_BSS_SCAN_PARAMS 74 diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c index 0ffda4de8..ffa980d77 100644 --- a/wpa_supplicant/events.c +++ b/wpa_supplicant/events.c @@ -228,6 +228,8 @@ void wpa_supplicant_mark_disassoc(struct wpa_supplicant *wpa_s) wpa_s->current_ssid = NULL; eapol_sm_notify_config(wpa_s->eapol, NULL, NULL); wpa_s->key_mgmt = 0; + + wpas_rrm_reset(wpa_s); } diff --git a/wpa_supplicant/sme.c b/wpa_supplicant/sme.c index 7269eb059..f1c49572e 100644 --- a/wpa_supplicant/sme.c +++ b/wpa_supplicant/sme.c @@ -137,6 +137,56 @@ static struct wpabuf * sme_auth_build_sae_confirm(struct wpa_supplicant *wpa_s) #endif /* CONFIG_SAE */ +/** + * sme_auth_handle_rrm - Handle RRM aspects of current authentication attempt + * @wpa_s: Pointer to wpa_supplicant data + * @bss: Pointer to the bss which is the target of authentication attempt + */ +static void sme_auth_handle_rrm(struct wpa_supplicant *wpa_s, + struct wpa_bss *bss) +{ + const u8 rrm_ie_len = 5; + u8 *pos; + const u8 *rrm_ie; + + wpa_s->rrm.rrm_used = 0; + + wpa_printf(MSG_DEBUG, + "RRM: Determining whether RRM can be used - device support: 0x%x", + wpa_s->drv_rrm_flags); + + rrm_ie = wpa_bss_get_ie(bss, WLAN_EID_RRM_ENABLED_CAPABILITIES); + if (!rrm_ie || !(bss->caps & IEEE80211_CAP_RRM)) { + wpa_printf(MSG_DEBUG, "RRM: No RRM in network"); + return; + } + + if (!(wpa_s->drv_rrm_flags & + WPA_DRIVER_FLAGS_DS_PARAM_SET_IE_IN_PROBES) || + !(wpa_s->drv_rrm_flags & WPA_DRIVER_FLAGS_QUIET)) { + wpa_printf(MSG_DEBUG, + "RRM: Insufficient RRM support in driver - do not use RRM"); + return; + } + + if (sizeof(wpa_s->sme.assoc_req_ie) - wpa_s->sme.assoc_req_ie_len < + rrm_ie_len + 2) { + wpa_printf(MSG_INFO, + "RRM: Unable to use RRM, no room for RRM IE"); + return; + } + + wpa_printf(MSG_DEBUG, "RRM: Adding RRM IE to Association Request"); + pos = wpa_s->sme.assoc_req_ie + wpa_s->sme.assoc_req_ie_len; + /* IE body is made of bit flags, all initialized to 0 */ + os_memset(pos, 0, 2 + rrm_ie_len); + *pos++ = WLAN_EID_RRM_ENABLED_CAPABILITIES; + *pos++ = rrm_ie_len; + wpa_s->sme.assoc_req_ie_len += rrm_ie_len + 2; + wpa_s->rrm.rrm_used = 1; +} + + static void sme_send_authentication(struct wpa_supplicant *wpa_s, struct wpa_bss *bss, struct wpa_ssid *ssid, int start) @@ -391,6 +441,8 @@ static void sme_send_authentication(struct wpa_supplicant *wpa_s, os_memcpy(pos, ext_capab, ext_capab_len); } + sme_auth_handle_rrm(wpa_s, bss); + #ifdef CONFIG_SAE if (params.auth_alg == WPA_AUTH_ALG_SAE && pmksa_cache_set_current(wpa_s->wpa, NULL, bss->bssid, ssid, 0) == 0) @@ -786,6 +838,7 @@ void sme_associate(struct wpa_supplicant *wpa_s, enum wpas_mode mode, #endif /* CONFIG_IEEE80211R */ params.mode = mode; params.mgmt_frame_protection = wpa_s->sme.mfp; + params.rrm_used = wpa_s->rrm.rrm_used; if (wpa_s->sme.prev_bssid_set) params.prev_bssid = wpa_s->sme.prev_bssid; diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c index 122b0993c..18d2e8e31 100644 --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c @@ -3913,6 +3913,8 @@ static int wpa_supplicant_init_iface(struct wpa_supplicant *wpa_s, if (wpas_init_ext_pw(wpa_s) < 0) return -1; + wpas_rrm_reset(wpa_s); + return 0; } @@ -4909,3 +4911,13 @@ int get_shared_radio_freqs(struct wpa_supplicant *wpa_s, return num; } + + +/* + * wpas_rrm_reset - Clear and reset all RRM data in wpa_supplicant + * @wpa_s: Pointer to wpa_supplicant + */ +void wpas_rrm_reset(struct wpa_supplicant *wpa_s) +{ + wpa_s->rrm.rrm_used = 0; +} diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h index 6a9aec7b8..071941e7d 100644 --- a/wpa_supplicant/wpa_supplicant_i.h +++ b/wpa_supplicant/wpa_supplicant_i.h @@ -378,6 +378,14 @@ struct wpa_used_freq_data { unsigned int flags; }; +/* + * struct rrm_data - Data used for managing RRM features + */ +struct rrm_data { + /* rrm_used - indication regarding the current connection */ + unsigned int rrm_used:1; +}; + /** * struct wpa_supplicant - Internal data for wpa_supplicant interface * @@ -897,6 +905,8 @@ struct wpa_supplicant { struct wmm_tspec_element *tspecs[WMM_AC_NUM][TS_DIR_IDX_COUNT]; struct wmm_ac_addts_request *addts_request; u8 wmm_ac_last_dialog_token; + + struct rrm_data rrm; }; @@ -995,6 +1005,8 @@ int wpas_update_random_addr(struct wpa_supplicant *wpa_s, int style); int wpas_update_random_addr_disassoc(struct wpa_supplicant *wpa_s); void add_freq(int *freqs, int *num_freqs, int freq); +void wpas_rrm_reset(struct wpa_supplicant *wpa_s); + /** * wpa_supplicant_ctrl_iface_ctrl_rsp_handle - Handle a control response * @wpa_s: Pointer to wpa_supplicant data