aboutsummaryrefslogtreecommitdiffstats
path: root/wpa_supplicant/bss.c
diff options
context:
space:
mode:
authorJouni Malinen <jouni@qca.qualcomm.com>2012-10-03 11:17:41 (GMT)
committerJouni Malinen <j@w1.fi>2012-10-03 11:17:41 (GMT)
commit485e3a92285c8c6da95427d4a2b633e3c24a8a5e (patch)
tree9a533b7a62cda9e20b2f4a83353c2d7553a0c17d /wpa_supplicant/bss.c
parent2edcd5046a8e090de69e162088925317393eb66b (diff)
downloadhostap-485e3a92285c8c6da95427d4a2b633e3c24a8a5e.zip
hostap-485e3a92285c8c6da95427d4a2b633e3c24a8a5e.tar.gz
hostap-485e3a92285c8c6da95427d4a2b633e3c24a8a5e.tar.bz2
Interworking: Unshare ANQP results on explicit ANQP requests
When ANQP_GET or HS20_ANQP_GET is used to request ANQP information, unshare the ANQP information (i.e., create a per-BSS copy of it) to make sure the information from the specified BSS is available in case the APs provide different information within HESSID. Signed-hostap: Jouni Malinen <jouni@qca.qualcomm.com>
Diffstat (limited to 'wpa_supplicant/bss.c')
-rw-r--r--wpa_supplicant/bss.c54
1 files changed, 54 insertions, 0 deletions
diff --git a/wpa_supplicant/bss.c b/wpa_supplicant/bss.c
index 6223beb..0babbd5 100644
--- a/wpa_supplicant/bss.c
+++ b/wpa_supplicant/bss.c
@@ -62,6 +62,60 @@ struct wpa_bss_anqp * wpa_bss_anqp_alloc(void)
}
+static struct wpa_bss_anqp * wpa_bss_anqp_clone(struct wpa_bss_anqp *anqp)
+{
+ struct wpa_bss_anqp *n;
+
+ n = os_zalloc(sizeof(*n));
+ if (n == NULL)
+ return NULL;
+
+#define ANQP_DUP(f) if (anqp->f) n->f = wpabuf_dup(anqp->f)
+#ifdef CONFIG_INTERWORKING
+ ANQP_DUP(venue_name);
+ ANQP_DUP(network_auth_type);
+ ANQP_DUP(roaming_consortium);
+ ANQP_DUP(ip_addr_type_availability);
+ ANQP_DUP(nai_realm);
+ ANQP_DUP(anqp_3gpp);
+ ANQP_DUP(domain_name);
+#endif /* CONFIG_INTERWORKING */
+#ifdef CONFIG_HS20
+ ANQP_DUP(hs20_operator_friendly_name);
+ ANQP_DUP(hs20_wan_metrics);
+ ANQP_DUP(hs20_connection_capability);
+ ANQP_DUP(hs20_operating_class);
+#endif /* CONFIG_HS20 */
+#undef ANQP_DUP
+
+ return n;
+}
+
+
+int wpa_bss_anqp_unshare_alloc(struct wpa_bss *bss)
+{
+ struct wpa_bss_anqp *anqp;
+
+ if (bss->anqp && bss->anqp->users > 1) {
+ /* allocated, but shared - clone an unshared copy */
+ anqp = wpa_bss_anqp_clone(bss->anqp);
+ if (anqp == NULL)
+ return -1;
+ anqp->users = 1;
+ bss->anqp->users--;
+ bss->anqp = anqp;
+ return 0;
+ }
+
+ if (bss->anqp)
+ return 0; /* already allocated and not shared */
+
+ /* not allocated - allocate a new storage area */
+ bss->anqp = wpa_bss_anqp_alloc();
+ return bss->anqp ? 0 : -1;
+}
+
+
static void wpa_bss_anqp_free(struct wpa_bss_anqp *anqp)
{
if (anqp == NULL)