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)
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);
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;
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
* @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
}
-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;
}
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);
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;
}
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;
}