]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
SME: Add RRM support to association request
authorAssaf Krauss <assaf.krauss@intel.com>
Wed, 5 Nov 2014 08:42:48 +0000 (03:42 -0500)
committerJouni Malinen <j@w1.fi>
Sat, 22 Nov 2014 19:13:45 +0000 (21:13 +0200)
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>
src/common/ieee802_11_defs.h
wpa_supplicant/events.c
wpa_supplicant/sme.c
wpa_supplicant/wpa_supplicant.c
wpa_supplicant/wpa_supplicant_i.h

index 10ad2eeb1f085938e0e2112c41cfcef336ea7dc5..bcef88abbb0809df192f64c5de1e44cbc457edf5 100644 (file)
 #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
index 0ffda4de8f102a122a2b98368862e6687b05ae8a..ffa980d77abc8b15b06e2855725179ac22aaff80 100644 (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);
 }
 
 
index 7269eb0594f2ca3c581dbe110d39bfac61469983..f1c49572ede20a3279bed8b8bb9f912d27840798 100644 (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;
 
index 122b0993cde6764de180c478f7a04c565e2da03d..18d2e8e318486d0c7be0aeeb9f3fd106c43072e8 100644 (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;
+}
index 6a9aec7b80b562ebcdc082be5f71348cfb65d9dc..071941e7de1814042eeaf48322455b77ec6f8ef3 100644 (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