hostapd: Add MBO IE to Beacon, Probe Response, Association Response
authorAvraham Stern <avraham.stern@intel.com>
Mon, 15 Feb 2016 14:53:52 +0000 (16:53 +0200)
committerJouni Malinen <j@w1.fi>
Mon, 22 Feb 2016 17:53:04 +0000 (19:53 +0200)
Add MBO IE with AP capability attribute to Beacon, Probe Response, and
(Re)Association Response frames to indicate the AP supports MBO.

Add option to add Association Disallowed attribute to Beacon, Probe
Response, and (Re)Association Response frames. Usage:

SET mbo_assoc_disallow <reason code>

Valid reason code values are between 1-5. Setting the reason code to
0 will remove the Association Disallowed attribute from the MBO IE
and will allow new associations.

MBO functionality is enabled by setting "mbo=1" in the config file.

Signed-off-by: Avraham Stern <avraham.stern@intel.com>
13 files changed:
hostapd/Android.mk
hostapd/Makefile
hostapd/android.config
hostapd/config_file.c
hostapd/ctrl_iface.c
hostapd/defconfig
src/ap/ap_config.h
src/ap/ap_drv_ops.c
src/ap/beacon.c
src/ap/hostapd.h
src/ap/ieee802_11.c
src/ap/ieee802_11.h
src/ap/ieee802_11_shared.c

index 799d150..7048484 100644 (file)
@@ -263,6 +263,10 @@ ifdef CONFIG_IEEE80211AC
 L_CFLAGS += -DCONFIG_IEEE80211AC
 endif
 
+ifdef CONFIG_MBO
+L_CFLAGS += -DCONFIG_MBO
+endif
+
 ifdef CONFIG_FST
 L_CFLAGS += -DCONFIG_FST
 OBJS += src/fst/fst.c
index 306f19d..43a96a5 100644 (file)
@@ -282,6 +282,10 @@ ifdef CONFIG_IEEE80211AC
 CFLAGS += -DCONFIG_IEEE80211AC
 endif
 
+ifdef CONFIG_MBO
+CFLAGS += -DCONFIG_MBO
+endif
+
 include ../src/drivers/drivers.mak
 OBJS += $(DRV_AP_OBJS)
 CFLAGS += $(DRV_AP_CFLAGS)
index c2d8b22..e382c40 100644 (file)
@@ -194,3 +194,8 @@ CONFIG_AP=y
 
 # Enable Fast Session Transfer (FST)
 #CONFIG_FST=y
+
+# Multiband Operation support
+# These extentions facilitate efficient use of multiple frequency bands
+# available to the AP and the devices that may associate with it.
+#CONFIG_MBO=y
index 76f02ca..a157a74 100644 (file)
@@ -3300,6 +3300,10 @@ static int hostapd_config_fill(struct hostapd_config *conf,
        } else if (os_strcmp(buf, "subscr_remediation_method") == 0) {
                bss->subscr_remediation_method = atoi(pos);
 #endif /* CONFIG_HS20 */
+#ifdef CONFIG_MBO
+       } else if (os_strcmp(buf, "mbo") == 0) {
+               bss->mbo_enabled = atoi(pos);
+#endif /* CONFIG_MBO */
 #ifdef CONFIG_TESTING_OPTIONS
 #define PARSE_TEST_PROBABILITY(_val)                           \
        } else if (os_strcmp(buf, #_val) == 0) {                \
index 0939d6e..ba98a1c 100644 (file)
@@ -1320,6 +1320,25 @@ static int hostapd_ctrl_iface_set(struct hostapd_data *hapd, char *cmd)
        } else if (os_strcasecmp(cmd, "ext_eapol_frame_io") == 0) {
                hapd->ext_eapol_frame_io = atoi(value);
 #endif /* CONFIG_TESTING_OPTIONS */
+#ifdef CONFIG_MBO
+       } else if (os_strcasecmp(cmd, "mbo_assoc_disallow") == 0) {
+               int val;
+
+               if (!hapd->conf->mbo_enabled)
+                       return -1;
+
+               val = atoi(value);
+               if (val < 0 || val > 1)
+                       return -1;
+
+               hapd->mbo_assoc_disallow = val;
+               ieee802_11_update_beacons(hapd->iface);
+
+               /*
+                * TODO: Need to configure drivers that do AP MLME offload with
+                * disallowing station logic.
+                */
+#endif /* CONFIG_MBO */
        } else {
                struct sta_info *sta;
                struct vlan_description vlan_id;
index 6f4e587..f7b60e0 100644 (file)
@@ -332,3 +332,8 @@ CONFIG_IPV6=y
 # http://wireless.kernel.org/en/users/Documentation/acs
 #
 #CONFIG_ACS=y
+
+# Multiband Operation support
+# These extentions facilitate efficient use of multiple frequency bands
+# available to the AP and the devices that may associate with it.
+#CONFIG_MBO=y
index 763eaaa..9afca48 100644 (file)
@@ -575,6 +575,10 @@ struct hostapd_bss_config {
        char *no_auth_if_seen_on;
 
        int pbss;
+
+#ifdef CONFIG_MBO
+       int mbo_enabled;
+#endif /* CONFIG_MBO */
 };
 
 
index 195cb19..713ad0b 100644 (file)
@@ -204,6 +204,25 @@ int hostapd_build_ap_extra_ies(struct hostapd_data *hapd,
        }
 #endif /* CONFIG_HS20 */
 
+#ifdef CONFIG_MBO
+       if (hapd->conf->mbo_enabled) {
+               pos = hostapd_eid_mbo(hapd, buf, sizeof(buf));
+               if (pos != buf) {
+                       if (wpabuf_resize(&beacon, pos - buf) != 0)
+                               goto fail;
+                       wpabuf_put_data(beacon, buf, pos - buf);
+
+                       if (wpabuf_resize(&proberesp, pos - buf) != 0)
+                               goto fail;
+                       wpabuf_put_data(proberesp, buf, pos - buf);
+
+                       if (wpabuf_resize(&assocresp, pos - buf) != 0)
+                               goto fail;
+                       wpabuf_put_data(assocresp, buf, pos - buf);
+               }
+       }
+#endif /* CONFIG_MBO */
+
        if (hapd->conf->vendor_elements) {
                size_t add = wpabuf_len(hapd->conf->vendor_elements);
                if (wpabuf_resize(&beacon, add) == 0)
index 560b19c..0720e14 100644 (file)
@@ -387,6 +387,9 @@ static u8 * hostapd_gen_probe_resp(struct hostapd_data *hapd,
                buflen += 5 + 2 + sizeof(struct ieee80211_vht_capabilities) +
                        2 + sizeof(struct ieee80211_vht_operation);
        }
+
+       buflen += hostapd_mbo_ie_len(hapd);
+
        resp = os_zalloc(buflen);
        if (resp == NULL)
                return NULL;
@@ -518,6 +521,8 @@ static u8 * hostapd_gen_probe_resp(struct hostapd_data *hapd,
        pos = hostapd_eid_osen(hapd, pos);
 #endif /* CONFIG_HS20 */
 
+       pos = hostapd_eid_mbo(hapd, pos, (u8 *) resp + buflen - pos);
+
        if (hapd->conf->vendor_elements) {
                os_memcpy(pos, wpabuf_head(hapd->conf->vendor_elements),
                          wpabuf_len(hapd->conf->vendor_elements));
@@ -980,6 +985,8 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd,
        }
 #endif /* CONFIG_IEEE80211AC */
 
+       tail_len += hostapd_mbo_ie_len(hapd);
+
        tailpos = tail = os_malloc(tail_len);
        if (head == NULL || tail == NULL) {
                wpa_printf(MSG_ERROR, "Failed to set beacon data");
@@ -1133,6 +1140,8 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd,
        tailpos = hostapd_eid_osen(hapd, tailpos);
 #endif /* CONFIG_HS20 */
 
+       tailpos = hostapd_eid_mbo(hapd, tailpos, tail + tail_len - tailpos);
+
        if (hapd->conf->vendor_elements) {
                os_memcpy(tailpos, wpabuf_head(hapd->conf->vendor_elements),
                          wpabuf_len(hapd->conf->vendor_elements));
index 0f31dd4..d6d96db 100644 (file)
@@ -281,6 +281,10 @@ struct hostapd_data {
 
        struct l2_packet_data *l2_test;
 #endif /* CONFIG_TESTING_OPTIONS */
+
+#ifdef CONFIG_MBO
+       unsigned int mbo_assoc_disallow;
+#endif /* CONFIG_MBO */
 };
 
 
index 09a85f8..251c1a9 100644 (file)
@@ -1915,6 +1915,8 @@ static u16 send_assoc_resp(struct hostapd_data *hapd, struct sta_info *sta,
                p = hostapd_eid_p2p_manage(hapd, p);
 #endif /* CONFIG_P2P_MANAGER */
 
+       p = hostapd_eid_mbo(hapd, p, buf + sizeof(buf) - p);
+
        send_len += p - reply->u.assoc_resp.variable;
 
        if (hostapd_drv_send_mlme(hapd, reply, send_len, 0) < 0) {
@@ -2048,6 +2050,13 @@ static void handle_assoc(struct hostapd_data *hapd,
                goto fail;
        }
 
+#ifdef CONFIG_MBO
+       if (hapd->conf->mbo_enabled && hapd->mbo_assoc_disallow) {
+               resp = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
+               goto fail;
+       }
+#endif /* CONFIG_MBO */
+
        /* followed by SSID and Supported rates; and HT capabilities if 802.11n
         * is used */
        resp = check_assoc_ies(hapd, sta, pos, left, reassoc);
index 0020ff5..78db204 100644 (file)
@@ -109,4 +109,25 @@ static inline void sae_clear_retransmit_timer(struct hostapd_data *hapd,
 }
 #endif /* CONFIG_SAE */
 
+#ifdef CONFIG_MBO
+
+u8 * hostapd_eid_mbo(struct hostapd_data *hapd, u8 *eid, size_t len);
+
+u8 hostapd_mbo_ie_len(struct hostapd_data *hapd);
+
+#else /* CONFIG_MBO */
+
+static inline u8 * hostapd_eid_mbo(struct hostapd_data *hapd, u8 *eid,
+                                  size_t len)
+{
+       return eid;
+}
+
+static inline u8 hostapd_mbo_ie_len(struct hostapd_data *hapd)
+{
+       return 0;
+}
+
+#endif /* CONFIG_MBO */
+
 #endif /* IEEE802_11_H */
index 9e3363e..48083e2 100644 (file)
@@ -508,3 +508,45 @@ u8 * hostapd_eid_bss_max_idle_period(struct hostapd_data *hapd, u8 *eid)
 
        return pos;
 }
+
+
+#ifdef CONFIG_MBO
+
+u8 * hostapd_eid_mbo(struct hostapd_data *hapd, u8 *eid, size_t len)
+{
+       u8 mbo[6], *mbo_pos = mbo;
+       u8 *pos = eid;
+
+       if (!hapd->conf->mbo_enabled)
+               return eid;
+
+       *mbo_pos++ = MBO_ATTR_ID_AP_CAPA_IND;
+       *mbo_pos++ = 1;
+       /* Not Cellular aware */
+       *mbo_pos++ = 0;
+
+       if (hapd->mbo_assoc_disallow) {
+               *mbo_pos++ = MBO_ATTR_ID_ASSOC_DISALLOW;
+               *mbo_pos++ = 1;
+               *mbo_pos++ = hapd->mbo_assoc_disallow;
+       }
+
+       pos += mbo_add_ie(pos, len, mbo, mbo_pos - mbo);
+
+       return pos;
+}
+
+
+u8 hostapd_mbo_ie_len(struct hostapd_data *hapd)
+{
+       if (!hapd->conf->mbo_enabled)
+               return 0;
+
+       /*
+        * MBO IE header (6) + Capability Indication attribute (3) +
+        * Association Disallowed attribute (3) = 12
+        */
+       return 6 + 3 + (hapd->mbo_assoc_disallow ? 3 : 0);
+}
+
+#endif /* CONFIG_MBO */