]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
HS 2.0: Add HS Capability element (AP)
authorJay Katabathuni <jkatabat@qca.qualcomm.com>
Mon, 30 Jul 2012 19:01:08 +0000 (22:01 +0300)
committerJouni Malinen <j@w1.fi>
Mon, 30 Jul 2012 19:25:23 +0000 (22:25 +0300)
Signed-hostap: Jouni Malinen <jouni@qca.qualcomm.com>

src/ap/gas_serv.c
src/ap/gas_serv.h

index 00272d1d7ce4df94b5f34183fc1575f7f57ce23c..14121684f802925a73f77571dfb8d4d314e5ea15 100644 (file)
@@ -128,6 +128,21 @@ static void gas_serv_free_dialogs(struct hostapd_data *hapd,
 }
 
 
+static void anqp_add_hs_capab_list(struct hostapd_data *hapd,
+                                  struct wpabuf *buf)
+{
+       u8 *len;
+
+       len = gas_anqp_add_element(buf, ANQP_VENDOR_SPECIFIC);
+       wpabuf_put_be24(buf, OUI_WFA);
+       wpabuf_put_u8(buf, HS20_ANQP_OUI_TYPE);
+       wpabuf_put_u8(buf, HS20_STYPE_CAPABILITY_LIST);
+       wpabuf_put_u8(buf, 0); /* Reserved */
+       wpabuf_put_u8(buf, HS20_STYPE_CAPABILITY_LIST);
+       gas_anqp_set_element_len(buf, len);
+}
+
+
 static void anqp_add_capab_list(struct hostapd_data *hapd,
                                struct wpabuf *buf)
 {
@@ -145,6 +160,7 @@ static void anqp_add_capab_list(struct hostapd_data *hapd,
                wpabuf_put_le16(buf, ANQP_IP_ADDR_TYPE_AVAILABILITY);
        if (hapd->conf->domain_name)
                wpabuf_put_le16(buf, ANQP_DOMAIN_NAME);
+       anqp_add_hs_capab_list(hapd, buf);
        gas_anqp_set_element_len(buf, len);
 }
 
@@ -244,6 +260,9 @@ gas_serv_build_gas_resp_payload(struct hostapd_data *hapd,
        if (request & ANQP_REQ_DOMAIN_NAME)
                anqp_add_domain_name(hapd, buf);
 
+       if (request & ANQP_REQ_HS_CAPABILITY_LIST)
+               anqp_add_hs_capab_list(hapd, buf);
+
        return buf;
 }
 
@@ -339,6 +358,71 @@ static void rx_anqp_query_list(struct hostapd_data *hapd,
 }
 
 
+static void rx_anqp_hs_query_list(struct hostapd_data *hapd, u8 subtype,
+                                 struct anqp_query_info *qi)
+{
+       switch (subtype) {
+       case HS20_STYPE_CAPABILITY_LIST:
+               set_anqp_req(ANQP_REQ_HS_CAPABILITY_LIST, "HS Capability List",
+                            1, 0, 0, qi);
+               break;
+       default:
+               wpa_printf(MSG_DEBUG, "ANQP: Unsupported HS 2.0 subtype %u",
+                          subtype);
+               break;
+       }
+}
+
+
+static void rx_anqp_vendor_specific(struct hostapd_data *hapd,
+                                   const u8 *pos, const u8 *end,
+                                   struct anqp_query_info *qi)
+{
+       u32 oui;
+       u8 subtype;
+
+       if (pos + 4 > end) {
+               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;
+       }
+
+       if (*pos != HS20_ANQP_OUI_TYPE) {
+               wpa_printf(MSG_DEBUG, "ANQP: Unsupported WFA vendor type %u",
+                          *pos);
+               return;
+       }
+       pos++;
+
+       if (pos + 1 >= end)
+               return;
+
+       subtype = *pos++;
+       pos++; /* Reserved */
+       switch (subtype) {
+       case HS20_STYPE_QUERY_LIST:
+               wpa_printf(MSG_DEBUG, "ANQP: HS 2.0 Query List");
+               while (pos < end) {
+                       rx_anqp_hs_query_list(hapd, *pos, qi);
+                       pos++;
+               }
+               break;
+       default:
+               wpa_printf(MSG_DEBUG, "ANQP: Unsupported HS 2.0 query subtype "
+                          "%u", subtype);
+               break;
+       }
+}
+
+
 static void gas_serv_req_local_processing(struct hostapd_data *hapd,
                                          const u8 *sa, u8 dialog_token,
                                          struct anqp_query_info *qi)
@@ -480,6 +564,9 @@ static void gas_serv_rx_gas_initial_req(struct hostapd_data *hapd,
                case ANQP_QUERY_LIST:
                        rx_anqp_query_list(hapd, pos, pos + elen, &qi);
                        break;
+               case ANQP_VENDOR_SPECIFIC:
+                       rx_anqp_vendor_specific(hapd, pos, pos + elen, &qi);
+                       break;
                default:
                        wpa_printf(MSG_DEBUG, "ANQP: Unsupported Query "
                                   "Request element %u", info_id);
index 5ca6b8d573bce044f790c7521993d81e2da25e35..ef71c2d75bd21a6f3aba0359841ebe904c2b271a 100644 (file)
@@ -21,6 +21,8 @@
        (1 << (ANQP_IP_ADDR_TYPE_AVAILABILITY - ANQP_QUERY_LIST))
 #define ANQP_REQ_DOMAIN_NAME \
        (1 << (ANQP_DOMAIN_NAME - ANQP_QUERY_LIST))
+#define ANQP_REQ_HS_CAPABILITY_LIST \
+       (0x10000 << HS20_STYPE_CAPABILITY_LIST)
 
 /* To account for latencies between hostapd and external ANQP processor */
 #define GAS_SERV_COMEBACK_DELAY_FUDGE 10