P2P: Include P2P IE in (Re)AssocReq to infra AP if it uses P2P IE
authorJouni Malinen <jouni.malinen@atheros.com>
Wed, 7 Jul 2010 04:37:20 +0000 (21:37 -0700)
committerJouni Malinen <j@w1.fi>
Thu, 9 Sep 2010 14:17:20 +0000 (07:17 -0700)
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
src/p2p/p2p.h
wpa_supplicant/p2p_supplicant.c
wpa_supplicant/p2p_supplicant.h
wpa_supplicant/sme.c
wpa_supplicant/wpa_supplicant.c

index 0adeda2..9fc6abf 100644 (file)
@@ -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
index 3048379..e108172 100644 (file)
@@ -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
index e14b586..60a3c66 100644 (file)
@@ -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;
 }
 
 
index 6b28dc3..075cda8 100644 (file)
@@ -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);
index 5308f87..23ffe80 100644 (file)
@@ -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;
        }
index 7bf7fbb..177fe5b 100644 (file)
@@ -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;
        }