]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
MBO: Add MBO ANQP-element processing on AP
authorJouni Malinen <jouni@qca.qualcomm.com>
Fri, 10 Mar 2017 16:33:51 +0000 (18:33 +0200)
committerJouni Malinen <j@w1.fi>
Fri, 10 Mar 2017 16:33:51 +0000 (18:33 +0200)
This extends the GAS server to process MBO ANQP-elements and reply to a
query for the Cellular Data Connection Preference (if configured). The
new configuration parameter mbo_cell_data_conn_pref can be used to set
the value (0, 1, or 255) for the preference to indicate.

Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
hostapd/config_file.c
hostapd/hostapd.conf
src/ap/ap_config.c
src/ap/ap_config.h
src/ap/gas_serv.c
src/ap/gas_serv.h

index cb54c7740838f6f9311ba4346b2d1663bfd24fb1..4ff4691942b95fb45c3d6f20242bb14b7f581ae5 100644 (file)
@@ -3442,6 +3442,8 @@ static int hostapd_config_fill(struct hostapd_config *conf,
 #ifdef CONFIG_MBO
        } else if (os_strcmp(buf, "mbo") == 0) {
                bss->mbo_enabled = atoi(pos);
+       } else if (os_strcmp(buf, "mbo_cell_data_conn_pref") == 0) {
+               bss->mbo_cell_data_conn_pref = atoi(pos);
 #endif /* CONFIG_MBO */
 #ifdef CONFIG_TESTING_OPTIONS
 #define PARSE_TEST_PROBABILITY(_val)                           \
index 821910c10ea0e3999610758dc32658007d36e35a..19596ce001e917509b44cd2c62bb99ad53513eae 100644 (file)
@@ -2035,6 +2035,19 @@ own_ip_addr=127.0.0.1
 #
 #osu_server_uri=...
 
+##### Multiband Operation (MBO) ###############################################
+#
+# MBO enabled
+# 0 = disabled (default)
+# 1 = enabled
+#mbo=1
+#
+# Cellular data connection preference
+# 0 = Excluded - AP does not want STA to use the cellular data connection
+# 1 = AP prefers the STA not to use cellular data connection
+# 255 = AP prefers the STA to use cellular data connection
+#mbo_cell_data_conn_pref=1
+
 ##### Fast Session Transfer (FST) support #####################################
 #
 # The options in this section are only available when the build configuration
index a03c006ab76a91ade881969064ac98e2f73ac4d4..6b3d4e86299170a25de011533b3c6b305a8dee09 100644 (file)
@@ -109,6 +109,10 @@ void hostapd_config_defaults_bss(struct hostapd_bss_config *bss)
 #endif /* CONFIG_FILS */
 
        bss->broadcast_deauth = 1;
+
+#ifdef CONFIG_MBO
+       bss->mbo_cell_data_conn_pref = -1;
+#endif /* CONFIG_MBO */
 }
 
 
index 82eb0063f38ead9c5cfebbcc885669ba4142bff6..5394339074fdf269cc4c30b85cf6acf0a5b0d602 100644 (file)
@@ -600,6 +600,7 @@ struct hostapd_bss_config {
 
 #ifdef CONFIG_MBO
        int mbo_enabled;
+       int mbo_cell_data_conn_pref;
 #endif /* CONFIG_MBO */
 
        int ftm_responder;
index 96cd7030a102826984a1f22563adf040343855f0..da00bdcec2efdd22f6c8207e12cffc9dfb17223d 100644 (file)
@@ -828,6 +828,22 @@ static void anqp_add_icon_binary_file(struct hostapd_data *hapd,
 #endif /* CONFIG_HS20 */
 
 
+#ifdef CONFIG_MBO
+static void anqp_add_mbo_cell_data_conn_pref(struct hostapd_data *hapd,
+                                            struct wpabuf *buf)
+{
+       if (hapd->conf->mbo_cell_data_conn_pref >= 0) {
+               u8 *len = gas_anqp_add_element(buf, ANQP_VENDOR_SPECIFIC);
+               wpabuf_put_be24(buf, OUI_WFA);
+               wpabuf_put_u8(buf, MBO_ANQP_OUI_TYPE);
+               wpabuf_put_u8(buf, MBO_ANQP_SUBTYPE_CELL_CONN_PREF);
+               wpabuf_put_u8(buf, hapd->conf->mbo_cell_data_conn_pref);
+               gas_anqp_set_element_len(buf, len);
+       }
+}
+#endif /* CONFIG_MBO */
+
+
 static size_t anqp_get_required_len(struct hostapd_data *hapd,
                                    const u16 *infoid,
                                    unsigned int num_infoid)
@@ -933,6 +949,11 @@ gas_serv_build_gas_resp_payload(struct hostapd_data *hapd,
                anqp_add_icon_binary_file(hapd, buf, icon_name, icon_name_len);
 #endif /* CONFIG_HS20 */
 
+#ifdef CONFIG_MBO
+       if (request & ANQP_REQ_MBO_CELL_DATA_CONN_PREF)
+               anqp_add_mbo_cell_data_conn_pref(hapd, buf);
+#endif /* CONFIG_MBO */
+
        return buf;
 }
 
@@ -1152,49 +1173,12 @@ static void rx_anqp_hs_icon_request(struct hostapd_data *hapd,
 }
 
 
-static void rx_anqp_vendor_specific(struct hostapd_data *hapd,
-                                   const u8 *pos, const u8 *end,
-                                   struct anqp_query_info *qi)
+static void rx_anqp_vendor_specific_hs20(struct hostapd_data *hapd,
+                                        const u8 *pos, const u8 *end,
+                                        struct anqp_query_info *qi)
 {
-       u32 oui;
        u8 subtype;
 
-       if (end - pos < 4) {
-               wpa_printf(MSG_DEBUG, "ANQP: Too short vendor specific ANQP "
-                          "Query element");
-               return;
-       }
-
-       oui = WPA_GET_BE24(pos);
-       pos += 3;
-       if (oui != OUI_WFA) {
-               wpa_printf(MSG_DEBUG, "ANQP: Unsupported vendor OUI %06x",
-                          oui);
-               return;
-       }
-
-#ifdef CONFIG_P2P
-       if (*pos == P2P_OUI_TYPE) {
-               /*
-                * This is for P2P SD and will be taken care of by the P2P
-                * implementation. This query needs to be ignored in the generic
-                * GAS server to avoid duplicated response.
-                */
-               wpa_printf(MSG_DEBUG,
-                          "ANQP: Ignore WFA vendor type %u (P2P SD) in generic GAS server",
-                          *pos);
-               qi->p2p_sd = 1;
-               return;
-       }
-#endif /* CONFIG_P2P */
-
-       if (*pos != HS20_ANQP_OUI_TYPE) {
-               wpa_printf(MSG_DEBUG, "ANQP: Unsupported WFA vendor type %u",
-                          *pos);
-               return;
-       }
-       pos++;
-
        if (end - pos <= 1)
                return;
 
@@ -1224,6 +1208,115 @@ static void rx_anqp_vendor_specific(struct hostapd_data *hapd,
 #endif /* CONFIG_HS20 */
 
 
+#ifdef CONFIG_P2P
+static void rx_anqp_vendor_specific_p2p(struct hostapd_data *hapd,
+                                       struct anqp_query_info *qi)
+{
+       /*
+        * This is for P2P SD and will be taken care of by the P2P
+        * implementation. This query needs to be ignored in the generic
+        * GAS server to avoid duplicated response.
+        */
+       wpa_printf(MSG_DEBUG,
+                  "ANQP: Ignore WFA vendor type %u (P2P SD) in generic GAS server",
+                  P2P_OUI_TYPE);
+       qi->p2p_sd = 1;
+       return;
+}
+#endif /* CONFIG_P2P */
+
+
+#ifdef CONFIG_MBO
+
+static void rx_anqp_mbo_query_list(struct hostapd_data *hapd, u8 subtype,
+                                 struct anqp_query_info *qi)
+{
+       switch (subtype) {
+       case MBO_ANQP_SUBTYPE_CELL_CONN_PREF:
+               set_anqp_req(ANQP_REQ_MBO_CELL_DATA_CONN_PREF,
+                            "Cellular Data Connection Preference",
+                            hapd->conf->mbo_cell_data_conn_pref >= 0, qi);
+               break;
+       default:
+               wpa_printf(MSG_DEBUG, "ANQP: Unsupported MBO subtype %u",
+                          subtype);
+               break;
+       }
+}
+
+
+static void rx_anqp_vendor_specific_mbo(struct hostapd_data *hapd,
+                                       const u8 *pos, const u8 *end,
+                                       struct anqp_query_info *qi)
+{
+       u8 subtype;
+
+       if (end - pos < 1)
+               return;
+
+       subtype = *pos++;
+       switch (subtype) {
+       case MBO_ANQP_SUBTYPE_QUERY_LIST:
+               wpa_printf(MSG_DEBUG, "ANQP: MBO Query List");
+               while (pos < end) {
+                       rx_anqp_mbo_query_list(hapd, *pos, qi);
+                       pos++;
+               }
+               break;
+       default:
+               wpa_printf(MSG_DEBUG, "ANQP: Unsupported MBO query subtype %u",
+                          subtype);
+               break;
+       }
+}
+
+#endif /* CONFIG_MBO */
+
+
+static void rx_anqp_vendor_specific(struct hostapd_data *hapd,
+                                   const u8 *pos, const u8 *end,
+                                   struct anqp_query_info *qi)
+{
+       u32 oui;
+
+       if (end - pos < 4) {
+               wpa_printf(MSG_DEBUG, "ANQP: Too short vendor specific ANQP "
+                          "Query element");
+               return;
+       }
+
+       oui = WPA_GET_BE24(pos);
+       pos += 3;
+       if (oui != OUI_WFA) {
+               wpa_printf(MSG_DEBUG, "ANQP: Unsupported vendor OUI %06x",
+                          oui);
+               return;
+       }
+
+       switch (*pos) {
+#ifdef CONFIG_P2P
+       case P2P_OUI_TYPE:
+               rx_anqp_vendor_specific_p2p(hapd, qi);
+               break;
+#endif /* CONFIG_P2P */
+#ifdef CONFIG_HS20
+       case HS20_ANQP_OUI_TYPE:
+               rx_anqp_vendor_specific_hs20(hapd, pos + 1, end, qi);
+               break;
+#endif /* CONFIG_HS20 */
+#ifdef CONFIG_MBO
+       case MBO_ANQP_OUI_TYPE:
+               rx_anqp_vendor_specific_mbo(hapd, pos + 1, end, qi);
+               break;
+#endif /* CONFIG_MBO */
+       default:
+               wpa_printf(MSG_DEBUG, "ANQP: Unsupported WFA vendor type %u",
+                          *pos);
+               break;
+       }
+}
+
+
 static void gas_serv_req_local_processing(struct hostapd_data *hapd,
                                          const u8 *sa, u8 dialog_token,
                                          struct anqp_query_info *qi, int prot,
index 9051e4f905135ac4b7f65882709ee10e8529050a..4af6ddafb9b6ede6a6f57699dd46c7f9936f8402 100644 (file)
@@ -41,7 +41,7 @@
 #define ANQP_REQ_EMERGENCY_NAI \
        (1 << (ANQP_EMERGENCY_NAI - ANQP_QUERY_LIST))
 /*
- * First 16 Hotspot 2.0 vendor specific ANQP-elements can be included in the
+ * First 15 Hotspot 2.0 vendor specific ANQP-elements can be included in the
  * optimized bitmap.
  */
 #define ANQP_REQ_HS_CAPABILITY_LIST \
@@ -60,6 +60,9 @@
        (0x10000 << HS20_STYPE_OSU_PROVIDERS_LIST)
 #define ANQP_REQ_ICON_REQUEST \
        (0x10000 << HS20_STYPE_ICON_REQUEST)
+/* The first MBO ANQP-element can be included in the optimized bitmap. */
+#define ANQP_REQ_MBO_CELL_DATA_CONN_PREF \
+       (BIT(29) << MBO_ANQP_SUBTYPE_CELL_CONN_PREF)
 
 struct gas_dialog_info {
        u8 valid;