From 4c08c0bd5765aa5bc6b7093e3eaa2d7a8f1c20c7 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Tue, 6 Jul 2010 21:37:20 -0700 Subject: [PATCH] P2P: Include P2P IE in (Re)AssocReq to infra AP if it uses P2P IE While this is not strictly speaking required by the P2P specification for a not-P2P Managed Device, this can provide useful information for the P2P manager AP and may be needed to pass certification tests. --- src/p2p/p2p.c | 16 +++++++++------- src/p2p/p2p.h | 3 ++- wpa_supplicant/p2p_supplicant.c | 13 ++++++++++--- wpa_supplicant/p2p_supplicant.h | 2 +- wpa_supplicant/sme.c | 3 +-- wpa_supplicant/wpa_supplicant.c | 3 +-- 6 files changed, 24 insertions(+), 16 deletions(-) diff --git a/src/p2p/p2p.c b/src/p2p/p2p.c index 0adeda2d2..9fc6abff6 100644 --- a/src/p2p/p2p.c +++ b/src/p2p/p2p.c @@ -1606,20 +1606,21 @@ int p2p_probe_req_rx(struct p2p_data *p2p, const u8 *addr, const u8 *ie, static int p2p_assoc_req_ie_wlan_ap(struct p2p_data *p2p, const u8 *bssid, - u8 *buf, size_t len) + u8 *buf, size_t len, struct wpabuf *p2p_ie) { struct wpabuf *tmp; u8 *lpos; size_t tmplen; int res; - if (!(p2p->dev_capab & P2P_DEV_CAPAB_INFRA_MANAGED)) - return 0; + if (p2p_ie == NULL) + return 0; /* WLAN AP is not a P2P manager */ /* * (Re)Association Request - P2P IE * P2P Capability attribute (shall be present) - * P2P Interface attribute (present if concurrent device) + * P2P Interface attribute (present if concurrent device and + * P2P Management is enabled) */ tmp = wpabuf_alloc(200); if (tmp == NULL) @@ -1627,7 +1628,8 @@ static int p2p_assoc_req_ie_wlan_ap(struct p2p_data *p2p, const u8 *bssid, lpos = p2p_buf_add_ie_hdr(tmp); p2p_buf_add_capability(tmp, p2p->dev_capab, 0); - if (p2p->dev_capab & P2P_DEV_CAPAB_CONCURRENT_OPER) + if ((p2p->dev_capab & P2P_DEV_CAPAB_CONCURRENT_OPER) && + (p2p->dev_capab & P2P_DEV_CAPAB_INFRA_MANAGED)) p2p_buf_add_p2p_interface(tmp, p2p); p2p_buf_update_ie_hdr(tmp, lpos); @@ -1645,7 +1647,7 @@ static int p2p_assoc_req_ie_wlan_ap(struct p2p_data *p2p, const u8 *bssid, int p2p_assoc_req_ie(struct p2p_data *p2p, const u8 *bssid, u8 *buf, - size_t len, int p2p_group) + size_t len, int p2p_group, struct wpabuf *p2p_ie) { struct wpabuf *tmp; u8 *lpos; @@ -1654,7 +1656,7 @@ int p2p_assoc_req_ie(struct p2p_data *p2p, const u8 *bssid, u8 *buf, int res; if (!p2p_group) - return p2p_assoc_req_ie_wlan_ap(p2p, bssid, buf, len); + return p2p_assoc_req_ie_wlan_ap(p2p, bssid, buf, len, p2p_ie); /* * (Re)Association Request - P2P IE diff --git a/src/p2p/p2p.h b/src/p2p/p2p.h index 30483798b..e108172a0 100644 --- a/src/p2p/p2p.h +++ b/src/p2p/p2p.h @@ -1142,10 +1142,11 @@ int p2p_scan_result_text(const u8 *ies, size_t ies_len, char *buf, char *end); * @buf: Buffer for writing the P2P IE * @len: Maximum buf length in octets * @p2p_group: Whether this is for association with a P2P GO + * @p2p_ie: Reassembled P2P IE data from scan results or %NULL if none * Returns: Number of octets written into buf or -1 on failure */ int p2p_assoc_req_ie(struct p2p_data *p2p, const u8 *bssid, u8 *buf, - size_t len, int p2p_group); + size_t len, int p2p_group, struct wpabuf *p2p_ie); /** * p2p_scan_ie - Build P2P IE for Probe Request diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c index e14b58690..60a3c668f 100644 --- a/wpa_supplicant/p2p_supplicant.c +++ b/wpa_supplicant/p2p_supplicant.c @@ -2994,16 +2994,23 @@ int wpas_p2p_listen(struct wpa_supplicant *wpa_s, unsigned int timeout) } -int wpas_p2p_assoc_req_ie(struct wpa_supplicant *wpa_s, const u8 *bssid, +int wpas_p2p_assoc_req_ie(struct wpa_supplicant *wpa_s, struct wpa_bss *bss, u8 *buf, size_t len, int p2p_group) { + struct wpabuf *p2p_ie; + int ret; + if (wpa_s->global->p2p_disabled) return -1; if (wpa_s->global->p2p == NULL) return -1; - return p2p_assoc_req_ie(wpa_s->global->p2p, bssid, buf, len, - p2p_group); + p2p_ie = wpa_bss_get_vendor_ie_multi(bss, P2P_IE_VENDOR_TYPE); + ret = p2p_assoc_req_ie(wpa_s->global->p2p, bss->bssid, buf, len, + p2p_group, p2p_ie); + wpabuf_free(p2p_ie); + + return ret; } diff --git a/wpa_supplicant/p2p_supplicant.h b/wpa_supplicant/p2p_supplicant.h index 6b28dc315..075cda82b 100644 --- a/wpa_supplicant/p2p_supplicant.h +++ b/wpa_supplicant/p2p_supplicant.h @@ -50,7 +50,7 @@ int wpas_p2p_find(struct wpa_supplicant *wpa_s, unsigned int timeout, enum p2p_discovery_type type); void wpas_p2p_stop_find(struct wpa_supplicant *wpa_s); int wpas_p2p_listen(struct wpa_supplicant *wpa_s, unsigned int timeout); -int wpas_p2p_assoc_req_ie(struct wpa_supplicant *wpa_s, const u8 *bssid, +int wpas_p2p_assoc_req_ie(struct wpa_supplicant *wpa_s, struct wpa_bss *bss, u8 *buf, size_t len, int p2p_group); int wpas_p2p_probe_req_rx(struct wpa_supplicant *wpa_s, const u8 *addr, const u8 *ie, size_t ie_len); diff --git a/wpa_supplicant/sme.c b/wpa_supplicant/sme.c index 5308f87e0..23ffe800c 100644 --- a/wpa_supplicant/sme.c +++ b/wpa_supplicant/sme.c @@ -220,8 +220,7 @@ void sme_authenticate(struct wpa_supplicant *wpa_s, pos = wpa_s->sme.assoc_req_ie + wpa_s->sme.assoc_req_ie_len; len = sizeof(wpa_s->sme.assoc_req_ie) - wpa_s->sme.assoc_req_ie_len; - res = wpas_p2p_assoc_req_ie(wpa_s, bss->bssid, pos, len, - p2p_group); + res = wpas_p2p_assoc_req_ie(wpa_s, bss, pos, len, p2p_group); if (res >= 0) wpa_s->sme.assoc_req_ie_len += res; } diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c index 7bf7fbb33..177fe5bb5 100644 --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c @@ -1165,8 +1165,7 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s, p2p_group = wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_CAPABLE; pos = wpa_ie + wpa_ie_len; len = sizeof(wpa_ie) - wpa_ie_len; - res = wpas_p2p_assoc_req_ie(wpa_s, bss->bssid, pos, len, - p2p_group); + res = wpas_p2p_assoc_req_ie(wpa_s, bss, pos, len, p2p_group); if (res >= 0) wpa_ie_len += res; }