@@ -244,6 +244,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
@@ -227,6 +227,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);
}
@@ -137,6 +137,53 @@ 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: Attempting RRM. 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");
+ return;
+ }
+
+ if ((sizeof(wpa_s->sme.assoc_req_ie) - wpa_s->sme.assoc_req_ie_len) <
+ (rrm_ie_len + 2)) {
+ wpa_printf(MSG_WARNING,
+ "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, rrm_ie_len + 2);
+ *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 +438,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 +835,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;
@@ -3923,6 +3923,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;
}
@@ -4912,3 +4914,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;
+}
@@ -377,6 +377,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
*
@@ -886,6 +894,8 @@ struct wpa_supplicant {
struct l2_packet_data *l2_test;
unsigned int extra_roc_dur;
#endif /* CONFIG_TESTING_OPTIONS */
+
+ struct rrm_data rrm;
};
@@ -983,6 +993,8 @@ int wpas_build_ext_capab(struct wpa_supplicant *wpa_s, u8 *buf, size_t buflen);
int wpas_update_random_addr(struct wpa_supplicant *wpa_s, int style);
int wpas_update_random_addr_disassoc(struct wpa_supplicant *wpa_s);
+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