]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
MBO: Add option to add MBO query list to ANQP query
authorAvraham Stern <avraham.stern@intel.com>
Thu, 9 Mar 2017 13:19:58 +0000 (15:19 +0200)
committerJouni Malinen <j@w1.fi>
Fri, 10 Mar 2017 14:53:10 +0000 (16:53 +0200)
MBO techspec v0.0_r27 changed the MBO ANQP-element format. The MBO
element in ANQP query should now include an MBO Query List element that
contains a list of MBO elements to query.

Add API to add the MBO Query List to an ANQP query.

Format:
ANQP_GET <addr> <info_id>[,<info_id>]...[,mbo:<subtype>...]

Example for querying neighbor report with MBO cellular data
connection preference:
ANQP_GET <bssid> 272,mbo:2

Signed-off-by: Avraham Stern <avraham.stern@intel.com>
src/common/ieee802_11_defs.h
wpa_supplicant/ctrl_iface.c
wpa_supplicant/interworking.c
wpa_supplicant/interworking.h
wpa_supplicant/mbo.c
wpa_supplicant/wpa_supplicant_i.h

index eecabd9450496480e30e791c308d5f7edd59f0c8..afe2651a820b1ed7ab154da4f1035c18fe15bef2 100644 (file)
@@ -1419,9 +1419,11 @@ enum wfa_wnm_notif_subelem_id {
        WFA_WNM_NOTIF_SUBELEM_CELL_DATA_CAPA = 3,
 };
 
-/* MBO v0.0_r25, 4.3: MBO ANQP-elements */
+/* MBO v0.0_r27, 4.3: MBO ANQP-elements */
 #define MBO_ANQP_OUI_TYPE 0x12
-#define MBO_ANQP_SUBTYPE_CELL_CONN_PREF 1
+#define MBO_ANQP_SUBTYPE_QUERY_LIST 1
+#define MBO_ANQP_SUBTYPE_CELL_CONN_PREF 2
+#define MAX_MBO_ANQP_SUBTYPE MBO_ANQP_SUBTYPE_CELL_CONN_PREF
 
 /* Wi-Fi Direct (P2P) */
 
index 14dcdcd9cc94a1a3e28740f78a73a3b9aafe9ca1..5aa3542bcc1162e96af2c263d79eb5d797b41ff0 100644 (file)
@@ -6712,7 +6712,7 @@ static int get_anqp(struct wpa_supplicant *wpa_s, char *dst)
        u16 id[MAX_ANQP_INFO_ID];
        size_t num_id = 0;
        u32 subtypes = 0;
-       int get_cell_pref = 0;
+       u32 mbo_subtypes = 0;
 
        used = hwaddr_aton2(dst, dst_addr);
        if (used < 0)
@@ -6733,9 +6733,10 @@ static int get_anqp(struct wpa_supplicant *wpa_s, char *dst)
                } else if (os_strncmp(pos, "mbo:", 4) == 0) {
 #ifdef CONFIG_MBO
                        int num = atoi(pos + 4);
-                       if (num != MBO_ANQP_SUBTYPE_CELL_CONN_PREF)
+
+                       if (num <= 0 || num > MAX_MBO_ANQP_SUBTYPE)
                                return -1;
-                       get_cell_pref = 1;
+                       mbo_subtypes |= BIT(num);
 #else /* CONFIG_MBO */
                        return -1;
 #endif /* CONFIG_MBO */
@@ -6754,7 +6755,7 @@ static int get_anqp(struct wpa_supplicant *wpa_s, char *dst)
                return -1;
 
        return anqp_send_req(wpa_s, dst_addr, id, num_id, subtypes,
-                            get_cell_pref);
+                            mbo_subtypes);
 }
 
 
index 30b9c88a7bbcb0025e3be87849fa62b2883afd0a..24bbeff33717103bc39c5bf83d0bb02c98dc59e1 100644 (file)
@@ -2694,7 +2694,7 @@ void interworking_stop_fetch_anqp(struct wpa_supplicant *wpa_s)
 
 int anqp_send_req(struct wpa_supplicant *wpa_s, const u8 *dst,
                  u16 info_ids[], size_t num_ids, u32 subtypes,
-                 int get_cell_pref)
+                 u32 mbo_subtypes)
 {
        struct wpabuf *buf;
        struct wpabuf *extra_buf = NULL;
@@ -2728,10 +2728,10 @@ int anqp_send_req(struct wpa_supplicant *wpa_s, const u8 *dst,
 #endif /* CONFIG_HS20 */
 
 #ifdef CONFIG_MBO
-       if (get_cell_pref) {
+       if (mbo_subtypes) {
                struct wpabuf *mbo;
 
-               mbo = mbo_build_anqp_buf(wpa_s, bss);
+               mbo = mbo_build_anqp_buf(wpa_s, bss, mbo_subtypes);
                if (mbo) {
                        if (wpabuf_resize(&extra_buf, wpabuf_len(mbo))) {
                                wpabuf_free(extra_buf);
index 3d22292618b2200fc8bdc1d2bb0925c8eef3a3bd..37ee2e904e48ef9f1084a88763f71d30641d24d3 100644 (file)
@@ -13,7 +13,7 @@ enum gas_query_result;
 
 int anqp_send_req(struct wpa_supplicant *wpa_s, const u8 *dst,
                  u16 info_ids[], size_t num_ids, u32 subtypes,
-                 int get_cell_pref);
+                 u32 mbo_subtypes);
 void anqp_resp_cb(void *ctx, const u8 *dst, u8 dialog_token,
                  enum gas_query_result result,
                  const struct wpabuf *adv_proto,
index 5488f446afe1ce908d9d2789bdbf3438a200f6a9..5348b9a96ad0d8ca0430db384031f22f6ac8545c 100644 (file)
@@ -515,10 +515,11 @@ void wpas_mbo_update_cell_capa(struct wpa_supplicant *wpa_s, u8 mbo_cell_capa)
 
 
 struct wpabuf * mbo_build_anqp_buf(struct wpa_supplicant *wpa_s,
-                                  struct wpa_bss *bss)
+                                  struct wpa_bss *bss, u32 mbo_subtypes)
 {
        struct wpabuf *anqp_buf;
        u8 *len_pos;
+       u8 i;
 
        if (!wpa_bss_get_vendor_ie(bss, MBO_IE_VENDOR_TYPE)) {
                wpa_printf(MSG_INFO, "MBO: " MACSTR
@@ -527,7 +528,8 @@ struct wpabuf * mbo_build_anqp_buf(struct wpa_supplicant *wpa_s,
                return NULL;
        }
 
-       anqp_buf = wpabuf_alloc(10);
+       /* Allocate size for the maximum case - all MBO subtypes are set */
+       anqp_buf = wpabuf_alloc(9 + MAX_MBO_ANQP_SUBTYPE);
        if (!anqp_buf)
                return NULL;
 
@@ -535,7 +537,14 @@ struct wpabuf * mbo_build_anqp_buf(struct wpa_supplicant *wpa_s,
        wpabuf_put_be24(anqp_buf, OUI_WFA);
        wpabuf_put_u8(anqp_buf, MBO_ANQP_OUI_TYPE);
 
-       wpabuf_put_u8(anqp_buf, MBO_ANQP_SUBTYPE_CELL_CONN_PREF);
+       wpabuf_put_u8(anqp_buf, MBO_ANQP_SUBTYPE_QUERY_LIST);
+
+       /* The first valid MBO subtype is 1 */
+       for (i = 1; i <= MAX_MBO_ANQP_SUBTYPE; i++) {
+               if (mbo_subtypes & BIT(i))
+                       wpabuf_put_u8(anqp_buf, i);
+       }
+
        gas_anqp_set_element_len(anqp_buf, len_pos);
 
        return anqp_buf;
index 87065cf9e7462e442fe4a619e8a56544e0c1d9bd..08df4cca19b102e400bee0938bf9a6934d31d1bf 100644 (file)
@@ -1294,7 +1294,7 @@ size_t wpas_mbo_ie_bss_trans_reject(struct wpa_supplicant *wpa_s, u8 *pos,
                                    enum mbo_transition_reject_reason reason);
 void wpas_mbo_update_cell_capa(struct wpa_supplicant *wpa_s, u8 mbo_cell_capa);
 struct wpabuf * mbo_build_anqp_buf(struct wpa_supplicant *wpa_s,
-                                  struct wpa_bss *bss);
+                                  struct wpa_bss *bss, u32 mbo_subtypes);
 
 /* op_classes.c */
 enum chan_allowed {