]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
MBO: Update STA cellular data capability based on WNM Notification
authorJouni Malinen <jouni@qca.qualcomm.com>
Mon, 22 Feb 2016 11:24:21 +0000 (13:24 +0200)
committerJouni Malinen <j@w1.fi>
Mon, 22 Feb 2016 17:53:05 +0000 (19:53 +0200)
This makes hostapd parse a received WNM Notification Request frame
subelements and if a WFA MBO cellular data capability subelement is
seen, update the cellular data capability for the STA.

Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
src/ap/mbo_ap.c
src/ap/mbo_ap.h
src/ap/wnm_ap.c
src/common/ieee802_11_defs.h

index 940f693420286f57f16ac85d88554a1e07bb3ed3..287cece7891b47dbeac96944f3316e2022b91ef0 100644 (file)
@@ -47,3 +47,68 @@ int mbo_ap_get_info(struct sta_info *sta, char *buf, size_t buflen)
                return 0;
        return ret;
 }
+
+
+static void mbo_ap_wnm_notif_req_cell_capa(struct sta_info *sta,
+                                          const u8 *buf, size_t len)
+{
+       if (len < 1)
+               return;
+       wpa_printf(MSG_DEBUG, "MBO: STA " MACSTR
+                  " updated cellular data capability: %u",
+                  MAC2STR(sta->addr), buf[0]);
+       sta->cell_capa = buf[0];
+}
+
+
+static void mbo_ap_wnm_notif_req_elem(struct sta_info *sta, u8 type,
+                                     const u8 *buf, size_t len)
+{
+       switch (type) {
+       case WFA_WNM_NOTIF_SUBELEM_CELL_DATA_CAPA:
+               mbo_ap_wnm_notif_req_cell_capa(sta, buf, len);
+               break;
+       default:
+               wpa_printf(MSG_DEBUG,
+                          "MBO: Ignore unknown WNM Notification WFA subelement %u",
+                          type);
+               break;
+       }
+}
+
+
+void mbo_ap_wnm_notification_req(struct hostapd_data *hapd, const u8 *addr,
+                                const u8 *buf, size_t len)
+{
+       const u8 *pos, *end;
+       u8 ie_len;
+       struct sta_info *sta;
+
+       if (!hapd->conf->mbo_enabled)
+               return;
+
+       sta = ap_get_sta(hapd, addr);
+       if (!sta)
+               return;
+
+       pos = buf;
+       end = buf + len;
+
+       while (end - pos > 1) {
+               ie_len = pos[1];
+
+               if (2 + ie_len > end - pos)
+                       break;
+
+               if (pos[0] == WLAN_EID_VENDOR_SPECIFIC &&
+                   ie_len >= 4 && WPA_GET_BE24(pos + 2) == OUI_WFA)
+                       mbo_ap_wnm_notif_req_elem(sta, pos[5],
+                                                 pos + 6, ie_len - 4);
+               else
+                       wpa_printf(MSG_DEBUG,
+                                  "MBO: Ignore unknown WNM Notification element %u (len=%u)",
+                                  pos[0], pos[1]);
+
+               pos += 2 + pos[1];
+       }
+}
index 9c6aedac5022167ab2b309e353cdb674ac4f1e01..cee2300d7a7d92299e294e5fc8a4ca6c629f7ec6 100644 (file)
@@ -18,6 +18,8 @@ struct ieee802_11_elems;
 void mbo_ap_check_sta_assoc(struct hostapd_data *hapd, struct sta_info *sta,
                            struct ieee802_11_elems *elems);
 int mbo_ap_get_info(struct sta_info *sta, char *buf, size_t buflen);
+void mbo_ap_wnm_notification_req(struct hostapd_data *hapd, const u8 *addr,
+                                const u8 *buf, size_t len);
 
 #else /* CONFIG_MBO */
 
@@ -33,6 +35,12 @@ static inline int mbo_ap_get_info(struct sta_info *sta, char *buf,
        return 0;
 }
 
+static inline void mbo_ap_wnm_notification_req(struct hostapd_data *hapd,
+                                              const u8 *addr,
+                                              const u8 *buf, size_t len)
+{
+}
+
 #endif /* CONFIG_MBO */
 
 #endif /* MBO_AP_H */
index 1cf84c66c7f7121241bd850613342398fba1ac07..6af460ab79eee1affa020a75877aa92903c5feda 100644 (file)
@@ -17,6 +17,7 @@
 #include "ap/ap_config.h"
 #include "ap/ap_drv_ops.h"
 #include "ap/wpa_auth.h"
+#include "mbo_ap.h"
 #include "wnm_ap.h"
 
 #define MAX_TFS_IE_LEN  1024
@@ -394,6 +395,8 @@ static void ieee802_11_rx_wnm_notification_req(struct hostapd_data *hapd,
                   MAC2STR(addr), dialog_token, type);
        wpa_hexdump(MSG_MSGDUMP, "WNM: Notification Request subelements",
                    buf, len);
+       if (type == WLAN_EID_VENDOR_SPECIFIC)
+               mbo_ap_wnm_notification_req(hapd, addr, buf, len);
 }
 
 
index 9b06daddbffa6aff53b6520ad346fa52e93f97a1..73ffc9998e8b5d7dba753d5c608c2b754613b888 100644 (file)
@@ -1113,6 +1113,12 @@ enum mbo_transition_reject_reason {
        MBO_TRANSITION_REJECT_REASON_SERVICES = 6,
 };
 
+/* MBO v0.0_r19, 4.4: WNM-Notification vendor subelements */
+enum wfa_wnm_notif_subelem_id {
+       WFA_WNM_NOTIF_SUBELEM_NON_PREF_CHAN_REPORT = 2,
+       WFA_WNM_NOTIF_SUBELEM_CELL_DATA_CAPA = 3,
+};
+
 /* Wi-Fi Direct (P2P) */
 
 #define P2P_OUI_TYPE 9