SME: Add RRM support to association request
In case the AP we are associating with advertises support for RRM, advertise our own RRM support in the (Re)Association Request frame. This is done by adding an RRM Capabilities IE. The underlying driver is expected to further add a Power Capabilities IE to the request, and set the Radio Measurement flag in the Capability Info field. At this point the RRM Capabilities IE advertises no measurement support. Signed-off-by: Assaf Krauss <assaf.krauss@intel.com>
This commit is contained in:
parent
f936b73c4f
commit
b361d580ec
5 changed files with 80 additions and 0 deletions
|
@ -246,6 +246,7 @@
|
||||||
#define WLAN_EID_SECONDARY_CHANNEL_OFFSET 62
|
#define WLAN_EID_SECONDARY_CHANNEL_OFFSET 62
|
||||||
#define WLAN_EID_WAPI 68
|
#define WLAN_EID_WAPI 68
|
||||||
#define WLAN_EID_TIME_ADVERTISEMENT 69
|
#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_COEXISTENCE 72
|
||||||
#define WLAN_EID_20_40_BSS_INTOLERANT 73
|
#define WLAN_EID_20_40_BSS_INTOLERANT 73
|
||||||
#define WLAN_EID_OVERLAPPING_BSS_SCAN_PARAMS 74
|
#define WLAN_EID_OVERLAPPING_BSS_SCAN_PARAMS 74
|
||||||
|
|
|
@ -228,6 +228,8 @@ void wpa_supplicant_mark_disassoc(struct wpa_supplicant *wpa_s)
|
||||||
wpa_s->current_ssid = NULL;
|
wpa_s->current_ssid = NULL;
|
||||||
eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
|
eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
|
||||||
wpa_s->key_mgmt = 0;
|
wpa_s->key_mgmt = 0;
|
||||||
|
|
||||||
|
wpas_rrm_reset(wpa_s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -137,6 +137,56 @@ static struct wpabuf * sme_auth_build_sae_confirm(struct wpa_supplicant *wpa_s)
|
||||||
#endif /* CONFIG_SAE */
|
#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,
|
static void sme_send_authentication(struct wpa_supplicant *wpa_s,
|
||||||
struct wpa_bss *bss, struct wpa_ssid *ssid,
|
struct wpa_bss *bss, struct wpa_ssid *ssid,
|
||||||
int start)
|
int start)
|
||||||
|
@ -391,6 +441,8 @@ static void sme_send_authentication(struct wpa_supplicant *wpa_s,
|
||||||
os_memcpy(pos, ext_capab, ext_capab_len);
|
os_memcpy(pos, ext_capab, ext_capab_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sme_auth_handle_rrm(wpa_s, bss);
|
||||||
|
|
||||||
#ifdef CONFIG_SAE
|
#ifdef CONFIG_SAE
|
||||||
if (params.auth_alg == WPA_AUTH_ALG_SAE &&
|
if (params.auth_alg == WPA_AUTH_ALG_SAE &&
|
||||||
pmksa_cache_set_current(wpa_s->wpa, NULL, bss->bssid, ssid, 0) == 0)
|
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 */
|
#endif /* CONFIG_IEEE80211R */
|
||||||
params.mode = mode;
|
params.mode = mode;
|
||||||
params.mgmt_frame_protection = wpa_s->sme.mfp;
|
params.mgmt_frame_protection = wpa_s->sme.mfp;
|
||||||
|
params.rrm_used = wpa_s->rrm.rrm_used;
|
||||||
if (wpa_s->sme.prev_bssid_set)
|
if (wpa_s->sme.prev_bssid_set)
|
||||||
params.prev_bssid = wpa_s->sme.prev_bssid;
|
params.prev_bssid = wpa_s->sme.prev_bssid;
|
||||||
|
|
||||||
|
|
|
@ -3913,6 +3913,8 @@ static int wpa_supplicant_init_iface(struct wpa_supplicant *wpa_s,
|
||||||
if (wpas_init_ext_pw(wpa_s) < 0)
|
if (wpas_init_ext_pw(wpa_s) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
wpas_rrm_reset(wpa_s);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4909,3 +4911,13 @@ int get_shared_radio_freqs(struct wpa_supplicant *wpa_s,
|
||||||
|
|
||||||
return num;
|
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;
|
||||||
|
}
|
||||||
|
|
|
@ -378,6 +378,14 @@ struct wpa_used_freq_data {
|
||||||
unsigned int flags;
|
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
|
* 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_tspec_element *tspecs[WMM_AC_NUM][TS_DIR_IDX_COUNT];
|
||||||
struct wmm_ac_addts_request *addts_request;
|
struct wmm_ac_addts_request *addts_request;
|
||||||
u8 wmm_ac_last_dialog_token;
|
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);
|
int wpas_update_random_addr_disassoc(struct wpa_supplicant *wpa_s);
|
||||||
void add_freq(int *freqs, int *num_freqs, int freq);
|
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_supplicant_ctrl_iface_ctrl_rsp_handle - Handle a control response
|
||||||
* @wpa_s: Pointer to wpa_supplicant data
|
* @wpa_s: Pointer to wpa_supplicant data
|
||||||
|
|
Loading…
Reference in a new issue