Add generic mechanism for adding vendor elements into frames

This adds following new control interface commands to allow arbitrary
vendor elements to be added into number of frames:

VENDOR_ELEM_ADD <frame id> <hexdump of elem(s)>
VENDOR_ELEM_GET <frame id>
VENDOR_ELEM_REMOVE <frame id> <hexdump of elem(s)>
VENDOR_ELEM_REMOVE <frame id> *

The following frames are supported in this commit (additional frames can
be added in the future):

0 = Probe Request frame in P2P device discovery
1 = Probe Response frame from P2P Device role
2 = Probe Response frame from P2P GO
3 = Beacon frame from P2P GO
4 = PD Req
5 = PD Resp
6 = GO Neg Req
7 = GO Neg Resp
8 = GO Neg Conf
9 = Invitation Request
10 = Invitation Response
11 = P2P Association Request
12 = P2P Association Response

One or more vendor element can be added/removed with the commands. The
hexdump of the element(s) needs to contain the full element (id, len,
payload) and the buffer needs to pass IE parsing requirements to be
accepted.

Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
This commit is contained in:
Jouni Malinen 2014-07-04 18:23:43 +03:00 committed by Jouni Malinen
parent 4ed3492206
commit 86bd36f0d5
11 changed files with 339 additions and 0 deletions

View file

@ -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"
@ -1957,6 +1958,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 +1981,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 +2260,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 +2278,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 +2869,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 +2899,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 +4765,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;
}