diff options
| author | Dmitry Shmidt <dimitrysh@google.com> | 2014-07-16 09:55:28 -0700 |
|---|---|---|
| committer | Dmitry Shmidt <dimitrysh@google.com> | 2014-07-16 17:07:36 +0000 |
| commit | 2e67f06149ff649fb6f8782bad041d3d9124685e (patch) | |
| tree | 0fb28cadf2160ac5d6cad5a79135a0b61df0b7a0 /src/p2p | |
| parent | 2f9ffba33e8d57edccf0932cc0b1f8f3bbe77c54 (diff) | |
| download | android_external_wpa_supplicant_8-2e67f06149ff649fb6f8782bad041d3d9124685e.tar.gz android_external_wpa_supplicant_8-2e67f06149ff649fb6f8782bad041d3d9124685e.tar.bz2 android_external_wpa_supplicant_8-2e67f06149ff649fb6f8782bad041d3d9124685e.zip | |
Cumulative patch from commit 6d00ab04302df257cb3092b2b31b4eac42e77569
6d00ab0 nl80211: Ensure nl_preq unregistration on driver deinit
71a0e39 P2P: Make unrecognized vendor elements available in P2P_PEER
86bd36f Add generic mechanism for adding vendor elements into frames
Change-Id: I392072a37d8dbfc92769082b60f052f7095466b6
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
Diffstat (limited to 'src/p2p')
| -rw-r--r-- | src/p2p/p2p.c | 72 | ||||
| -rw-r--r-- | src/p2p/p2p.h | 10 | ||||
| -rw-r--r-- | src/p2p/p2p_go_neg.c | 18 | ||||
| -rw-r--r-- | src/p2p/p2p_group.c | 26 | ||||
| -rw-r--r-- | src/p2p/p2p_i.h | 2 | ||||
| -rw-r--r-- | src/p2p/p2p_invitation.c | 7 | ||||
| -rw-r--r-- | src/p2p/p2p_pd.c | 13 |
7 files changed, 148 insertions, 0 deletions
diff --git a/src/p2p/p2p.c b/src/p2p/p2p.c index 48f3aa65..565cbdbd 100644 --- a/src/p2p/p2p.c +++ b/src/p2p/p2p.c @@ -12,6 +12,7 @@ #include "eloop.h" #include "common/ieee802_11_defs.h" #include "common/ieee802_11_common.h" +#include "common/wpa_ctrl.h" #include "wps/wps_i.h" #include "p2p_i.h" #include "p2p.h" @@ -608,6 +609,46 @@ static void p2p_copy_wps_info(struct p2p_data *p2p, struct p2p_device *dev, } +static void p2p_update_peer_vendor_elems(struct p2p_device *dev, const u8 *ies, + size_t ies_len) +{ + const u8 *pos, *end; + u8 id, len; + + wpabuf_free(dev->info.vendor_elems); + dev->info.vendor_elems = NULL; + + end = ies + ies_len; + + for (pos = ies; pos + 1 < end; pos += len) { + id = *pos++; + len = *pos++; + + if (pos + len > end) + break; + + if (id != WLAN_EID_VENDOR_SPECIFIC || len < 3) + continue; + + if (len >= 4) { + u32 type = WPA_GET_BE32(pos); + + if (type == WPA_IE_VENDOR_TYPE || + type == WMM_IE_VENDOR_TYPE || + type == WPS_IE_VENDOR_TYPE || + type == P2P_IE_VENDOR_TYPE || + type == WFD_IE_VENDOR_TYPE) + continue; + } + + /* Unknown vendor element - make raw IE data available */ + if (wpabuf_resize(&dev->info.vendor_elems, 2 + len) < 0) + break; + wpabuf_put_data(dev->info.vendor_elems, pos - 2, 2 + len); + } +} + + /** * p2p_add_device - Add peer entries based on scan results or P2P frames * @p2p: P2P module context from p2p_init() @@ -756,6 +797,8 @@ int p2p_add_device(struct p2p_data *p2p, const u8 *addr, int freq, p2p_parse_free(&msg); + p2p_update_peer_vendor_elems(dev, ies, ies_len); + if (dev->flags & P2P_DEV_REPORTED) return 0; @@ -825,6 +868,7 @@ static void p2p_device_free(struct p2p_data *p2p, struct p2p_device *dev) } wpabuf_free(dev->info.wfd_subelems); + wpabuf_free(dev->info.vendor_elems); wpabuf_free(dev->go_neg_conf); os_free(dev); @@ -1957,6 +2001,9 @@ struct wpabuf * p2p_build_probe_resp_ies(struct p2p_data *p2p) extra = wpabuf_len(p2p->wfd_ie_probe_resp); #endif /* CONFIG_WIFI_DISPLAY */ + if (p2p->vendor_elem && p2p->vendor_elem[VENDOR_ELEM_PROBE_RESP_P2P]) + extra += wpabuf_len(p2p->vendor_elem[VENDOR_ELEM_PROBE_RESP_P2P]); + buf = wpabuf_alloc(1000 + extra); if (buf == NULL) return NULL; @@ -1977,6 +2024,10 @@ struct wpabuf * p2p_build_probe_resp_ies(struct p2p_data *p2p) wpabuf_put_buf(buf, p2p->wfd_ie_probe_resp); #endif /* CONFIG_WIFI_DISPLAY */ + if (p2p->vendor_elem && p2p->vendor_elem[VENDOR_ELEM_PROBE_RESP_P2P]) + wpabuf_put_buf(buf, + p2p->vendor_elem[VENDOR_ELEM_PROBE_RESP_P2P]); + /* P2P IE */ len = p2p_buf_add_ie_hdr(buf); p2p_buf_add_capability(buf, p2p->dev_capab & @@ -2252,6 +2303,9 @@ int p2p_assoc_req_ie(struct p2p_data *p2p, const u8 *bssid, u8 *buf, extra = wpabuf_len(p2p->wfd_ie_assoc_req); #endif /* CONFIG_WIFI_DISPLAY */ + if (p2p->vendor_elem && p2p->vendor_elem[VENDOR_ELEM_P2P_ASSOC_REQ]) + extra += wpabuf_len(p2p->vendor_elem[VENDOR_ELEM_P2P_ASSOC_REQ]); + /* * (Re)Association Request - P2P IE * P2P Capability attribute (shall be present) @@ -2267,6 +2321,10 @@ int p2p_assoc_req_ie(struct p2p_data *p2p, const u8 *bssid, u8 *buf, wpabuf_put_buf(tmp, p2p->wfd_ie_assoc_req); #endif /* CONFIG_WIFI_DISPLAY */ + if (p2p->vendor_elem && p2p->vendor_elem[VENDOR_ELEM_P2P_ASSOC_REQ]) + wpabuf_put_buf(tmp, + p2p->vendor_elem[VENDOR_ELEM_P2P_ASSOC_REQ]); + peer = bssid ? p2p_get_device(p2p, bssid) : NULL; lpos = p2p_buf_add_ie_hdr(tmp); @@ -2854,6 +2912,10 @@ void p2p_scan_ie(struct p2p_data *p2p, struct wpabuf *ies, const u8 *dev_id) wpabuf_put_buf(ies, p2p->wfd_ie_probe_req); #endif /* CONFIG_WIFI_DISPLAY */ + if (p2p->vendor_elem && p2p->vendor_elem[VENDOR_ELEM_PROBE_REQ_P2P]) + wpabuf_put_buf(ies, + p2p->vendor_elem[VENDOR_ELEM_PROBE_REQ_P2P]); + len = p2p_buf_add_ie_hdr(ies); p2p_buf_add_capability(ies, p2p->dev_capab & ~P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY, 0); @@ -2880,6 +2942,10 @@ size_t p2p_scan_ie_buf_len(struct p2p_data *p2p) len += wpabuf_len(p2p->wfd_ie_probe_req); #endif /* CONFIG_WIFI_DISPLAY */ + if (p2p && p2p->vendor_elem && + p2p->vendor_elem[VENDOR_ELEM_PROBE_REQ_P2P]) + len += wpabuf_len(p2p->vendor_elem[VENDOR_ELEM_PROBE_REQ_P2P]); + return len; } @@ -4742,3 +4808,9 @@ int p2p_set_passphrase_len(struct p2p_data *p2p, unsigned int len) p2p->cfg->passphrase_len = len; return 0; } + + +void p2p_set_vendor_elems(struct p2p_data *p2p, struct wpabuf **vendor_elem) +{ + p2p->vendor_elem = vendor_elem; +} diff --git a/src/p2p/p2p.h b/src/p2p/p2p.h index 16500a80..dee79dfb 100644 --- a/src/p2p/p2p.h +++ b/src/p2p/p2p.h @@ -230,6 +230,14 @@ struct p2p_peer_info { * wfd_subelems - Wi-Fi Display subelements from WFD IE(s) */ struct wpabuf *wfd_subelems; + + /** + * vendor_elems - Unrecognized vendor elements + * + * This buffer includes any other vendor element than P2P, WPS, and WFD + * IE(s) from the frame that was used to discover the peer. + */ + struct wpabuf *vendor_elems; }; enum p2p_prov_disc_status { @@ -1995,4 +2003,6 @@ void p2p_loop_on_known_peers(struct p2p_data *p2p, void *user_data), void *user_data); +void p2p_set_vendor_elems(struct p2p_data *p2p, struct wpabuf **vendor_elem); + #endif /* P2P_H */ diff --git a/src/p2p/p2p_go_neg.c b/src/p2p/p2p_go_neg.c index f24fe236..bd7a2cf5 100644 --- a/src/p2p/p2p_go_neg.c +++ b/src/p2p/p2p_go_neg.c @@ -10,6 +10,7 @@ #include "common.h" #include "common/ieee802_11_defs.h" +#include "common/wpa_ctrl.h" #include "wps/wps_defs.h" #include "p2p_i.h" #include "p2p.h" @@ -142,6 +143,9 @@ static struct wpabuf * p2p_build_go_neg_req(struct p2p_data *p2p, extra = wpabuf_len(p2p->wfd_ie_go_neg); #endif /* CONFIG_WIFI_DISPLAY */ + if (p2p->vendor_elem && p2p->vendor_elem[VENDOR_ELEM_P2P_GO_NEG_REQ]) + extra += wpabuf_len(p2p->vendor_elem[VENDOR_ELEM_P2P_GO_NEG_REQ]); + buf = wpabuf_alloc(1000 + extra); if (buf == NULL) return NULL; @@ -191,6 +195,9 @@ static struct wpabuf * p2p_build_go_neg_req(struct p2p_data *p2p, wpabuf_put_buf(buf, p2p->wfd_ie_go_neg); #endif /* CONFIG_WIFI_DISPLAY */ + if (p2p->vendor_elem && p2p->vendor_elem[VENDOR_ELEM_P2P_GO_NEG_REQ]) + wpabuf_put_buf(buf, p2p->vendor_elem[VENDOR_ELEM_P2P_GO_NEG_REQ]); + return buf; } @@ -268,6 +275,9 @@ static struct wpabuf * p2p_build_go_neg_resp(struct p2p_data *p2p, extra = wpabuf_len(p2p->wfd_ie_go_neg); #endif /* CONFIG_WIFI_DISPLAY */ + if (p2p->vendor_elem && p2p->vendor_elem[VENDOR_ELEM_P2P_GO_NEG_RESP]) + extra += wpabuf_len(p2p->vendor_elem[VENDOR_ELEM_P2P_GO_NEG_RESP]); + buf = wpabuf_alloc(1000 + extra); if (buf == NULL) return NULL; @@ -336,6 +346,8 @@ static struct wpabuf * p2p_build_go_neg_resp(struct p2p_data *p2p, wpabuf_put_buf(buf, p2p->wfd_ie_go_neg); #endif /* CONFIG_WIFI_DISPLAY */ + if (p2p->vendor_elem && p2p->vendor_elem[VENDOR_ELEM_P2P_GO_NEG_RESP]) + wpabuf_put_buf(buf, p2p->vendor_elem[VENDOR_ELEM_P2P_GO_NEG_RESP]); return buf; } @@ -844,6 +856,9 @@ static struct wpabuf * p2p_build_go_neg_conf(struct p2p_data *p2p, extra = wpabuf_len(p2p->wfd_ie_go_neg); #endif /* CONFIG_WIFI_DISPLAY */ + if (p2p->vendor_elem && p2p->vendor_elem[VENDOR_ELEM_P2P_GO_NEG_CONF]) + extra += wpabuf_len(p2p->vendor_elem[VENDOR_ELEM_P2P_GO_NEG_CONF]); + buf = wpabuf_alloc(1000 + extra); if (buf == NULL) return NULL; @@ -888,6 +903,9 @@ static struct wpabuf * p2p_build_go_neg_conf(struct p2p_data *p2p, wpabuf_put_buf(buf, p2p->wfd_ie_go_neg); #endif /* CONFIG_WIFI_DISPLAY */ + if (p2p->vendor_elem && p2p->vendor_elem[VENDOR_ELEM_P2P_GO_NEG_CONF]) + wpabuf_put_buf(buf, p2p->vendor_elem[VENDOR_ELEM_P2P_GO_NEG_CONF]); + return buf; } diff --git a/src/p2p/p2p_group.c b/src/p2p/p2p_group.c index aa075bdb..da8588aa 100644 --- a/src/p2p/p2p_group.c +++ b/src/p2p/p2p_group.c @@ -11,6 +11,7 @@ #include "common.h" #include "common/ieee802_11_defs.h" #include "common/ieee802_11_common.h" +#include "common/wpa_ctrl.h" #include "wps/wps_defs.h" #include "wps/wps_i.h" #include "p2p_i.h" @@ -214,6 +215,10 @@ static struct wpabuf * p2p_group_build_beacon_ie(struct p2p_group *group) extra = wpabuf_len(group->p2p->wfd_ie_beacon); #endif /* CONFIG_WIFI_DISPLAY */ + if (group->p2p->vendor_elem && + group->p2p->vendor_elem[VENDOR_ELEM_BEACON_P2P_GO]) + extra += wpabuf_len(group->p2p->vendor_elem[VENDOR_ELEM_BEACON_P2P_GO]); + ie = wpabuf_alloc(257 + extra); if (ie == NULL) return NULL; @@ -223,6 +228,11 @@ static struct wpabuf * p2p_group_build_beacon_ie(struct p2p_group *group) wpabuf_put_buf(ie, group->p2p->wfd_ie_beacon); #endif /* CONFIG_WIFI_DISPLAY */ + if (group->p2p->vendor_elem && + group->p2p->vendor_elem[VENDOR_ELEM_BEACON_P2P_GO]) + wpabuf_put_buf(ie, + group->p2p->vendor_elem[VENDOR_ELEM_BEACON_P2P_GO]); + len = p2p_buf_add_ie_hdr(ie); p2p_group_add_common_ies(group, ie); p2p_buf_add_device_id(ie, group->p2p->cfg->dev_addr); @@ -448,6 +458,13 @@ static struct wpabuf * p2p_group_build_probe_resp_ie(struct p2p_group *group) ie = p2p_group_encaps_probe_resp(p2p_subelems); wpabuf_free(p2p_subelems); + if (group->p2p->vendor_elem && + group->p2p->vendor_elem[VENDOR_ELEM_PROBE_RESP_P2P_GO]) { + struct wpabuf *extra; + extra = wpabuf_dup(group->p2p->vendor_elem[VENDOR_ELEM_PROBE_RESP_P2P_GO]); + ie = wpabuf_concat(extra, ie); + } + #ifdef CONFIG_WIFI_DISPLAY if (group->wfd_ie) { struct wpabuf *wfd = wpabuf_dup(group->wfd_ie); @@ -634,6 +651,10 @@ struct wpabuf * p2p_group_assoc_resp_ie(struct p2p_group *group, u8 status) extra = wpabuf_len(group->wfd_ie); #endif /* CONFIG_WIFI_DISPLAY */ + if (group->p2p->vendor_elem && + group->p2p->vendor_elem[VENDOR_ELEM_P2P_ASSOC_RESP]) + extra += wpabuf_len(group->p2p->vendor_elem[VENDOR_ELEM_P2P_ASSOC_RESP]); + /* * (Re)Association Response - P2P IE * Status attribute (shall be present when association request is @@ -649,6 +670,11 @@ struct wpabuf * p2p_group_assoc_resp_ie(struct p2p_group *group, u8 status) wpabuf_put_buf(resp, group->wfd_ie); #endif /* CONFIG_WIFI_DISPLAY */ + if (group->p2p->vendor_elem && + group->p2p->vendor_elem[VENDOR_ELEM_P2P_ASSOC_RESP]) + wpabuf_put_buf(resp, + group->p2p->vendor_elem[VENDOR_ELEM_P2P_ASSOC_RESP]); + rlen = p2p_buf_add_ie_hdr(resp); if (status != P2P_SC_SUCCESS) p2p_buf_add_status(resp, status); diff --git a/src/p2p/p2p_i.h b/src/p2p/p2p_i.h index 39a927a3..3b60582b 100644 --- a/src/p2p/p2p_i.h +++ b/src/p2p/p2p_i.h @@ -499,6 +499,8 @@ struct p2p_data { #endif /* CONFIG_WIFI_DISPLAY */ u16 authorized_oob_dev_pw_id; + + struct wpabuf **vendor_elem; }; /** diff --git a/src/p2p/p2p_invitation.c b/src/p2p/p2p_invitation.c index a36898e9..ef01a668 100644 --- a/src/p2p/p2p_invitation.c +++ b/src/p2p/p2p_invitation.c @@ -10,6 +10,7 @@ #include "common.h" #include "common/ieee802_11_defs.h" +#include "common/wpa_ctrl.h" #include "p2p_i.h" #include "p2p.h" @@ -45,6 +46,9 @@ static struct wpabuf * p2p_build_invitation_req(struct p2p_data *p2p, extra = wpabuf_len(wfd_ie); #endif /* CONFIG_WIFI_DISPLAY */ + if (p2p->vendor_elem && p2p->vendor_elem[VENDOR_ELEM_P2P_INV_REQ]) + extra += wpabuf_len(p2p->vendor_elem[VENDOR_ELEM_P2P_INV_REQ]); + buf = wpabuf_alloc(1000 + extra); if (buf == NULL) return NULL; @@ -86,6 +90,9 @@ static struct wpabuf * p2p_build_invitation_req(struct p2p_data *p2p, wpabuf_put_buf(buf, wfd_ie); #endif /* CONFIG_WIFI_DISPLAY */ + if (p2p->vendor_elem && p2p->vendor_elem[VENDOR_ELEM_P2P_INV_REQ]) + wpabuf_put_buf(buf, p2p->vendor_elem[VENDOR_ELEM_P2P_INV_REQ]); + if (dev_pw_id >= 0) { /* WSC IE in Invitation Request for NFC static handover */ p2p_build_wps_ie(p2p, buf, dev_pw_id, 0); diff --git a/src/p2p/p2p_pd.c b/src/p2p/p2p_pd.c index 68d79d23..e1013672 100644 --- a/src/p2p/p2p_pd.c +++ b/src/p2p/p2p_pd.c @@ -10,6 +10,7 @@ #include "common.h" #include "common/ieee802_11_defs.h" +#include "common/wpa_ctrl.h" #include "wps/wps_defs.h" #include "p2p_i.h" #include "p2p.h" @@ -53,6 +54,9 @@ static struct wpabuf * p2p_build_prov_disc_req(struct p2p_data *p2p, extra = wpabuf_len(p2p->wfd_ie_prov_disc_req); #endif /* CONFIG_WIFI_DISPLAY */ + if (p2p->vendor_elem && p2p->vendor_elem[VENDOR_ELEM_P2P_PD_REQ]) + extra += wpabuf_len(p2p->vendor_elem[VENDOR_ELEM_P2P_PD_REQ]); + buf = wpabuf_alloc(1000 + extra); if (buf == NULL) return NULL; @@ -77,6 +81,9 @@ static struct wpabuf * p2p_build_prov_disc_req(struct p2p_data *p2p, wpabuf_put_buf(buf, p2p->wfd_ie_prov_disc_req); #endif /* CONFIG_WIFI_DISPLAY */ + if (p2p->vendor_elem && p2p->vendor_elem[VENDOR_ELEM_P2P_PD_REQ]) + wpabuf_put_buf(buf, p2p->vendor_elem[VENDOR_ELEM_P2P_PD_REQ]); + return buf; } @@ -111,6 +118,9 @@ static struct wpabuf * p2p_build_prov_disc_resp(struct p2p_data *p2p, extra = wpabuf_len(wfd_ie); #endif /* CONFIG_WIFI_DISPLAY */ + if (p2p->vendor_elem && p2p->vendor_elem[VENDOR_ELEM_P2P_PD_RESP]) + extra += wpabuf_len(p2p->vendor_elem[VENDOR_ELEM_P2P_PD_RESP]); + buf = wpabuf_alloc(100 + extra); if (buf == NULL) return NULL; @@ -125,6 +135,9 @@ static struct wpabuf * p2p_build_prov_disc_resp(struct p2p_data *p2p, wpabuf_put_buf(buf, wfd_ie); #endif /* CONFIG_WIFI_DISPLAY */ + if (p2p->vendor_elem && p2p->vendor_elem[VENDOR_ELEM_P2P_PD_RESP]) + wpabuf_put_buf(buf, p2p->vendor_elem[VENDOR_ELEM_P2P_PD_RESP]); + return buf; } |
