[PATCH] HS20: Extend ANQP_GET to accept HS20 subtypes

Dmitry Shmidt dimitrysh at google.com
Mon Mar 24 20:36:13 EDT 2014


Change-Id: Ic5c4bd32e42fe58d5f1eac42cd01b06ce2619a9f
Signed-off-by: Dmitry Shmidt <dimitrysh at google.com>
---
 wpa_supplicant/ctrl_iface.c      | 21 +++++++++++++++++----
 wpa_supplicant/hs20_supplicant.c | 23 +++++++++++++++++++----
 wpa_supplicant/hs20_supplicant.h |  2 ++
 wpa_supplicant/interworking.c    | 15 +++++++++++++--
 wpa_supplicant/interworking.h    |  2 +-
 5 files changed, 52 insertions(+), 11 deletions(-)

diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c
index 704caa1..b76379a 100644
--- a/wpa_supplicant/ctrl_iface.c
+++ b/wpa_supplicant/ctrl_iface.c
@@ -4947,15 +4947,28 @@ static int get_anqp(struct wpa_supplicant *wpa_s, char *dst)
 #define MAX_ANQP_INFO_ID 100
 	u16 id[MAX_ANQP_INFO_ID];
 	size_t num_id = 0;
+	u32 subtypes = 0;
 
 	used = hwaddr_aton2(dst, dst_addr);
 	if (used < 0)
 		return -1;
 	pos = dst + used;
 	while (num_id < MAX_ANQP_INFO_ID) {
-		id[num_id] = atoi(pos);
-		if (id[num_id])
-			num_id++;
+#ifdef CONFIG_HS20
+		int num;
+		if (os_strncmp(pos, "hs20:", 5) == 0) {
+			num = atoi(pos + 5);
+			if (num <= 0 || num > 31)
+				return -1;
+			subtypes |= BIT(num);
+		} else {
+#endif
+			id[num_id] = atoi(pos);
+			if (id[num_id])
+				num_id++;
+#ifdef CONFIG_HS20
+		}
+#endif
 		pos = os_strchr(pos + 1, ',');
 		if (pos == NULL)
 			break;
@@ -4965,7 +4978,7 @@ static int get_anqp(struct wpa_supplicant *wpa_s, char *dst)
 	if (num_id == 0)
 		return -1;
 
-	return anqp_send_req(wpa_s, dst_addr, id, num_id);
+	return anqp_send_req(wpa_s, dst_addr, id, num_id, subtypes);
 }
 
 
diff --git a/wpa_supplicant/hs20_supplicant.c b/wpa_supplicant/hs20_supplicant.c
index b342d5d..7f6dd68 100644
--- a/wpa_supplicant/hs20_supplicant.c
+++ b/wpa_supplicant/hs20_supplicant.c
@@ -121,13 +121,11 @@ int hs20_get_pps_mo_id(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
 }
 
 
-struct wpabuf * hs20_build_anqp_req(u32 stypes, const u8 *payload,
-				    size_t payload_len)
+struct wpabuf * hs20_put_anqp_req(u32 stypes, const u8 *payload,
+				  size_t payload_len, struct wpabuf *buf)
 {
-	struct wpabuf *buf;
 	u8 *len_pos;
 
-	buf = gas_anqp_build_initial_req(0, 100 + payload_len);
 	if (buf == NULL)
 		return NULL;
 
@@ -153,6 +151,7 @@ struct wpabuf * hs20_build_anqp_req(u32 stypes, const u8 *payload,
 				wpabuf_put_u8(buf, i);
 		}
 	}
+
 	gas_anqp_set_element_len(buf, len_pos);
 
 	gas_anqp_set_len(buf);
@@ -161,6 +160,22 @@ struct wpabuf * hs20_build_anqp_req(u32 stypes, const u8 *payload,
 }
 
 
+struct wpabuf * hs20_build_anqp_req(u32 stypes, const u8 *payload,
+				    size_t payload_len)
+{
+	struct wpabuf *buf;
+	u8 *len_pos;
+
+	buf = gas_anqp_build_initial_req(0, 100 + payload_len);
+	if (buf == NULL)
+		return NULL;
+
+	hs20_put_anqp_req(stypes, payload, payload_len, buf);
+
+	return buf;
+}
+
+
 int hs20_anqp_send_req(struct wpa_supplicant *wpa_s, const u8 *dst, u32 stypes,
 		       const u8 *payload, size_t payload_len)
 {
diff --git a/wpa_supplicant/hs20_supplicant.h b/wpa_supplicant/hs20_supplicant.h
index 88e5062..2a0aa1c 100644
--- a/wpa_supplicant/hs20_supplicant.h
+++ b/wpa_supplicant/hs20_supplicant.h
@@ -14,6 +14,8 @@ int hs20_anqp_send_req(struct wpa_supplicant *wpa_s, const u8 *dst, u32 stypes,
 		       const u8 *payload, size_t payload_len);
 struct wpabuf * hs20_build_anqp_req(u32 stypes, const u8 *payload,
 				    size_t payload_len);
+struct wpabuf * hs20_put_anqp_req(u32 stypes, const u8 *payload,
+				  size_t payload_len, struct wpabuf *buf);
 void hs20_parse_rx_hs20_anqp_resp(struct wpa_supplicant *wpa_s,
 				  const u8 *sa, const u8 *data, size_t slen);
 int is_hs20_network(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
diff --git a/wpa_supplicant/interworking.c b/wpa_supplicant/interworking.c
index e3ad931..69dfe43 100644
--- a/wpa_supplicant/interworking.c
+++ b/wpa_supplicant/interworking.c
@@ -2531,9 +2531,10 @@ 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)
+		  u16 info_ids[], size_t num_ids, u32 subtypes)
 {
 	struct wpabuf *buf;
+	struct wpabuf *hs20_buf = NULL;
 	int ret = 0;
 	int freq;
 	struct wpa_bss *bss;
@@ -2551,7 +2552,17 @@ int anqp_send_req(struct wpa_supplicant *wpa_s, const u8 *dst,
 	wpa_printf(MSG_DEBUG, "ANQP: Query Request to " MACSTR " for %u id(s)",
 		   MAC2STR(dst), (unsigned int) num_ids);
 
-	buf = anqp_build_req(info_ids, num_ids, NULL);
+#ifdef CONFIG_HS20
+	if (subtypes != 0) {
+		hs20_buf = wpabuf_alloc(100);
+		if (hs20_buf == NULL)
+			return -1;
+		hs20_put_anqp_req(subtypes, NULL, 0, hs20_buf);
+	}
+#endif
+
+	buf = anqp_build_req(info_ids, num_ids, hs20_buf);
+	wpabuf_free(hs20_buf);
 	if (buf == NULL)
 		return -1;
 
diff --git a/wpa_supplicant/interworking.h b/wpa_supplicant/interworking.h
index bb0ceb8..38ef745 100644
--- a/wpa_supplicant/interworking.h
+++ b/wpa_supplicant/interworking.h
@@ -12,7 +12,7 @@
 enum gas_query_result;
 
 int anqp_send_req(struct wpa_supplicant *wpa_s, const u8 *dst,
-		  u16 info_ids[], size_t num_ids);
+		  u16 info_ids[], size_t num_ids, u32 subtypes);
 void anqp_resp_cb(void *ctx, const u8 *dst, u8 dialog_token,
 		  enum gas_query_result result,
 		  const struct wpabuf *adv_proto,
-- 
1.9.1.423.g4596e3a



More information about the HostAP mailing list