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:
Assaf Krauss 2014-11-05 03:42:48 -05:00 committed by Jouni Malinen
parent f936b73c4f
commit b361d580ec
5 changed files with 80 additions and 0 deletions

View File

@ -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

View File

@ -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);
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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