1/*
2 * Wi-Fi Direct - P2P provision discovery
3 * Copyright (c) 2009-2010, Atheros Communications
4 *
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
7 */
8
9#include "includes.h"
10
11#include "common.h"
12#include "common/ieee802_11_defs.h"
13#include "common/wpa_ctrl.h"
14#include "wps/wps_defs.h"
15#include "p2p_i.h"
16#include "p2p.h"
17
18
19/*
20 * Number of retries to attempt for provision discovery requests
21 * in case the peer is not listening.
22 */
23#define MAX_PROV_DISC_REQ_RETRIES 120
24
25
26static void p2p_build_wps_ie_config_methods(struct wpabuf *buf,
27					    u16 config_methods)
28{
29	u8 *len;
30	wpabuf_put_u8(buf, WLAN_EID_VENDOR_SPECIFIC);
31	len = wpabuf_put(buf, 1);
32	wpabuf_put_be32(buf, WPS_DEV_OUI_WFA);
33
34	/* Config Methods */
35	wpabuf_put_be16(buf, ATTR_CONFIG_METHODS);
36	wpabuf_put_be16(buf, 2);
37	wpabuf_put_be16(buf, config_methods);
38
39	p2p_buf_update_ie_hdr(buf, len);
40}
41
42
43static void p2ps_add_new_group_info(struct p2p_data *p2p, struct wpabuf *buf)
44{
45	int found;
46	u8 intended_addr[ETH_ALEN];
47	u8 ssid[SSID_MAX_LEN];
48	size_t ssid_len;
49	int group_iface;
50
51	if (!p2p->cfg->get_go_info)
52		return;
53
54	found = p2p->cfg->get_go_info(
55		p2p->cfg->cb_ctx, intended_addr, ssid,
56		&ssid_len, &group_iface);
57	if (found) {
58		p2p_buf_add_group_id(buf, p2p->cfg->dev_addr,
59				     ssid, ssid_len);
60		p2p_buf_add_intended_addr(buf, intended_addr);
61	} else {
62		if (!p2p->ssid_set) {
63			p2p_build_ssid(p2p, p2p->ssid, &p2p->ssid_len);
64			p2p->ssid_set = 1;
65		}
66
67		/* Add pre-composed P2P Group ID */
68		p2p_buf_add_group_id(buf, p2p->cfg->dev_addr,
69				     p2p->ssid, p2p->ssid_len);
70
71		if (group_iface)
72			p2p_buf_add_intended_addr(
73				buf, p2p->intended_addr);
74		else
75			p2p_buf_add_intended_addr(
76				buf, p2p->cfg->dev_addr);
77	}
78}
79
80
81static void p2ps_add_pd_req_attrs(struct p2p_data *p2p, struct p2p_device *dev,
82				  struct wpabuf *buf, u16 config_methods)
83{
84	struct p2ps_provision *prov = p2p->p2ps_prov;
85	u8 feat_cap_mask[] = { 1, 0 };
86	int shared_group = 0;
87	u8 ssid[SSID_MAX_LEN];
88	size_t ssid_len;
89	u8 go_dev_addr[ETH_ALEN];
90
91	/* If we might be explicite group owner, add GO details */
92	if (prov->conncap & (P2PS_SETUP_GROUP_OWNER |
93			     P2PS_SETUP_NEW))
94		p2ps_add_new_group_info(p2p, buf);
95
96	if (prov->status >= 0)
97		p2p_buf_add_status(buf, (u8) prov->status);
98	else
99		prov->method = config_methods;
100
101	if (p2p->cfg->get_persistent_group) {
102		shared_group = p2p->cfg->get_persistent_group(
103			p2p->cfg->cb_ctx, dev->info.p2p_device_addr, NULL, 0,
104			go_dev_addr, ssid, &ssid_len);
105	}
106
107	/* Add Operating Channel if conncap includes GO */
108	if (shared_group ||
109	    (prov->conncap & (P2PS_SETUP_GROUP_OWNER |
110			      P2PS_SETUP_NEW))) {
111		u8 tmp;
112
113		p2p_go_select_channel(p2p, dev, &tmp);
114
115		if (p2p->op_reg_class && p2p->op_channel)
116			p2p_buf_add_operating_channel(buf, p2p->cfg->country,
117						      p2p->op_reg_class,
118						      p2p->op_channel);
119		else
120			p2p_buf_add_operating_channel(buf, p2p->cfg->country,
121						      p2p->cfg->op_reg_class,
122						      p2p->cfg->op_channel);
123	}
124
125	p2p_buf_add_channel_list(buf, p2p->cfg->country, &p2p->cfg->channels);
126
127	if (prov->info[0])
128		p2p_buf_add_session_info(buf, prov->info);
129
130	p2p_buf_add_connection_capability(buf, prov->conncap);
131
132	p2p_buf_add_advertisement_id(buf, prov->adv_id, prov->adv_mac);
133
134	if (shared_group || prov->conncap == P2PS_SETUP_NEW ||
135	    prov->conncap ==
136	    (P2PS_SETUP_GROUP_OWNER | P2PS_SETUP_NEW) ||
137	    prov->conncap ==
138	    (P2PS_SETUP_GROUP_OWNER | P2PS_SETUP_CLIENT)) {
139		/* Add Config Timeout */
140		p2p_buf_add_config_timeout(buf, p2p->go_timeout,
141					   p2p->client_timeout);
142	}
143
144	p2p_buf_add_listen_channel(buf, p2p->cfg->country, p2p->cfg->reg_class,
145				   p2p->cfg->channel);
146
147	p2p_buf_add_session_id(buf, prov->session_id, prov->session_mac);
148
149	p2p_buf_add_feature_capability(buf, sizeof(feat_cap_mask),
150				       feat_cap_mask);
151
152	if (shared_group)
153		p2p_buf_add_persistent_group_info(buf, go_dev_addr,
154						  ssid, ssid_len);
155}
156
157
158static struct wpabuf * p2p_build_prov_disc_req(struct p2p_data *p2p,
159					       struct p2p_device *dev,
160					       int join)
161{
162	struct wpabuf *buf;
163	u8 *len;
164	size_t extra = 0;
165	u8 dialog_token = dev->dialog_token;
166	u16 config_methods = dev->req_config_methods;
167	struct p2p_device *go = join ? dev : NULL;
168	u8 group_capab;
169
170#ifdef CONFIG_WIFI_DISPLAY
171	if (p2p->wfd_ie_prov_disc_req)
172		extra = wpabuf_len(p2p->wfd_ie_prov_disc_req);
173#endif /* CONFIG_WIFI_DISPLAY */
174
175	if (p2p->vendor_elem && p2p->vendor_elem[VENDOR_ELEM_P2P_PD_REQ])
176		extra += wpabuf_len(p2p->vendor_elem[VENDOR_ELEM_P2P_PD_REQ]);
177
178	if (p2p->p2ps_prov)
179		extra += os_strlen(p2p->p2ps_prov->info) + 1 +
180			sizeof(struct p2ps_provision);
181
182	buf = wpabuf_alloc(1000 + extra);
183	if (buf == NULL)
184		return NULL;
185
186	p2p_buf_add_public_action_hdr(buf, P2P_PROV_DISC_REQ, dialog_token);
187
188	len = p2p_buf_add_ie_hdr(buf);
189
190	group_capab = 0;
191	if (p2p->p2ps_prov) {
192		group_capab |= P2P_GROUP_CAPAB_PERSISTENT_GROUP;
193		group_capab |= P2P_GROUP_CAPAB_PERSISTENT_RECONN;
194		if (p2p->cross_connect)
195			group_capab |= P2P_GROUP_CAPAB_CROSS_CONN;
196		if (p2p->cfg->p2p_intra_bss)
197			group_capab |= P2P_GROUP_CAPAB_INTRA_BSS_DIST;
198	}
199	p2p_buf_add_capability(buf, p2p->dev_capab &
200			       ~P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY,
201			       group_capab);
202	p2p_buf_add_device_info(buf, p2p, NULL);
203	if (p2p->p2ps_prov) {
204		p2ps_add_pd_req_attrs(p2p, dev, buf, config_methods);
205	} else if (go) {
206		p2p_buf_add_group_id(buf, go->info.p2p_device_addr,
207				     go->oper_ssid, go->oper_ssid_len);
208	}
209	p2p_buf_update_ie_hdr(buf, len);
210
211	/* WPS IE with Config Methods attribute */
212	p2p_build_wps_ie_config_methods(buf, config_methods);
213
214#ifdef CONFIG_WIFI_DISPLAY
215	if (p2p->wfd_ie_prov_disc_req)
216		wpabuf_put_buf(buf, p2p->wfd_ie_prov_disc_req);
217#endif /* CONFIG_WIFI_DISPLAY */
218
219	if (p2p->vendor_elem && p2p->vendor_elem[VENDOR_ELEM_P2P_PD_REQ])
220		wpabuf_put_buf(buf, p2p->vendor_elem[VENDOR_ELEM_P2P_PD_REQ]);
221
222	return buf;
223}
224
225
226static struct wpabuf * p2p_build_prov_disc_resp(struct p2p_data *p2p,
227						struct p2p_device *dev,
228						u8 dialog_token,
229						enum p2p_status_code status,
230						u16 config_methods,
231						u32 adv_id,
232						const u8 *group_id,
233						size_t group_id_len,
234						const u8 *persist_ssid,
235						size_t persist_ssid_len)
236{
237	struct wpabuf *buf;
238	size_t extra = 0;
239	int persist = 0;
240
241#ifdef CONFIG_WIFI_DISPLAY
242	struct wpabuf *wfd_ie = p2p->wfd_ie_prov_disc_resp;
243	if (wfd_ie && group_id) {
244		size_t i;
245		for (i = 0; i < p2p->num_groups; i++) {
246			struct p2p_group *g = p2p->groups[i];
247			struct wpabuf *ie;
248			if (!p2p_group_is_group_id_match(g, group_id,
249							 group_id_len))
250				continue;
251			ie = p2p_group_get_wfd_ie(g);
252			if (ie) {
253				wfd_ie = ie;
254				break;
255			}
256		}
257	}
258	if (wfd_ie)
259		extra = wpabuf_len(wfd_ie);
260#endif /* CONFIG_WIFI_DISPLAY */
261
262	if (p2p->vendor_elem && p2p->vendor_elem[VENDOR_ELEM_P2P_PD_RESP])
263		extra += wpabuf_len(p2p->vendor_elem[VENDOR_ELEM_P2P_PD_RESP]);
264
265	buf = wpabuf_alloc(1000 + extra);
266	if (buf == NULL)
267		return NULL;
268
269	p2p_buf_add_public_action_hdr(buf, P2P_PROV_DISC_RESP, dialog_token);
270
271	/* Add P2P IE for P2PS */
272	if (p2p->p2ps_prov && p2p->p2ps_prov->adv_id == adv_id) {
273		u8 feat_cap_mask[] = { 1, 0 };
274		u8 *len = p2p_buf_add_ie_hdr(buf);
275		struct p2ps_provision *prov = p2p->p2ps_prov;
276		u8 group_capab;
277
278		if (!status && prov->status != -1)
279			status = prov->status;
280
281		p2p_buf_add_status(buf, status);
282		group_capab = P2P_GROUP_CAPAB_PERSISTENT_GROUP |
283			P2P_GROUP_CAPAB_PERSISTENT_RECONN;
284		if (p2p->cross_connect)
285			group_capab |= P2P_GROUP_CAPAB_CROSS_CONN;
286		if (p2p->cfg->p2p_intra_bss)
287			group_capab |= P2P_GROUP_CAPAB_INTRA_BSS_DIST;
288		p2p_buf_add_capability(buf, p2p->dev_capab &
289				       ~P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY,
290				       group_capab);
291		p2p_buf_add_device_info(buf, p2p, NULL);
292
293		if (persist_ssid && p2p->cfg->get_persistent_group &&
294		    (status == P2P_SC_SUCCESS ||
295		     status == P2P_SC_SUCCESS_DEFERRED)) {
296			u8 ssid[SSID_MAX_LEN];
297			size_t ssid_len;
298			u8 go_dev_addr[ETH_ALEN];
299
300			persist = p2p->cfg->get_persistent_group(
301				p2p->cfg->cb_ctx,
302				dev->info.p2p_device_addr,
303				persist_ssid, persist_ssid_len, go_dev_addr,
304				ssid, &ssid_len);
305			if (persist)
306				p2p_buf_add_persistent_group_info(
307					buf, go_dev_addr, ssid, ssid_len);
308		}
309
310		if (!persist && (prov->conncap & P2PS_SETUP_GROUP_OWNER))
311			p2ps_add_new_group_info(p2p, buf);
312
313		/* Add Operating Channel if conncap indicates GO */
314		if (persist || (prov->conncap & P2PS_SETUP_GROUP_OWNER)) {
315			u8 tmp;
316
317			if (dev)
318				p2p_go_select_channel(p2p, dev, &tmp);
319
320			if (p2p->op_reg_class && p2p->op_channel)
321				p2p_buf_add_operating_channel(
322					buf, p2p->cfg->country,
323					p2p->op_reg_class,
324					p2p->op_channel);
325			else
326				p2p_buf_add_operating_channel(
327					buf, p2p->cfg->country,
328					p2p->cfg->op_reg_class,
329					p2p->cfg->op_channel);
330		}
331
332		p2p_buf_add_channel_list(buf, p2p->cfg->country,
333					 &p2p->cfg->channels);
334
335		if (!persist && (status == P2P_SC_SUCCESS ||
336				 status == P2P_SC_SUCCESS_DEFERRED))
337			p2p_buf_add_connection_capability(buf, prov->conncap);
338
339		p2p_buf_add_advertisement_id(buf, adv_id, prov->adv_mac);
340
341		p2p_buf_add_config_timeout(buf, p2p->go_timeout,
342					   p2p->client_timeout);
343
344		p2p_buf_add_session_id(buf, prov->session_id,
345				       prov->session_mac);
346
347		p2p_buf_add_feature_capability(buf, sizeof(feat_cap_mask),
348					       feat_cap_mask);
349		p2p_buf_update_ie_hdr(buf, len);
350	} else if (status != P2P_SC_SUCCESS || adv_id) {
351		u8 *len = p2p_buf_add_ie_hdr(buf);
352
353		p2p_buf_add_status(buf, status);
354
355		if (p2p->p2ps_prov)
356			p2p_buf_add_advertisement_id(buf, adv_id,
357						     p2p->p2ps_prov->adv_mac);
358
359		p2p_buf_update_ie_hdr(buf, len);
360	}
361
362	/* WPS IE with Config Methods attribute */
363	p2p_build_wps_ie_config_methods(buf, config_methods);
364
365#ifdef CONFIG_WIFI_DISPLAY
366	if (wfd_ie)
367		wpabuf_put_buf(buf, wfd_ie);
368#endif /* CONFIG_WIFI_DISPLAY */
369
370	if (p2p->vendor_elem && p2p->vendor_elem[VENDOR_ELEM_P2P_PD_RESP])
371		wpabuf_put_buf(buf, p2p->vendor_elem[VENDOR_ELEM_P2P_PD_RESP]);
372
373	return buf;
374}
375
376
377static int p2ps_setup_p2ps_prov(struct p2p_data *p2p, u32 adv_id,
378				u32 session_id, u16 method,
379				const u8 *session_mac, const u8 *adv_mac)
380{
381	struct p2ps_provision *tmp;
382
383	if (!p2p->p2ps_prov) {
384		p2p->p2ps_prov = os_zalloc(sizeof(struct p2ps_provision) + 1);
385		if (!p2p->p2ps_prov)
386			return -1;
387	} else {
388		os_memset(p2p->p2ps_prov, 0, sizeof(struct p2ps_provision) + 1);
389	}
390
391	tmp = p2p->p2ps_prov;
392	tmp->adv_id = adv_id;
393	tmp->session_id = session_id;
394	tmp->method = method;
395	os_memcpy(tmp->session_mac, session_mac, ETH_ALEN);
396	os_memcpy(tmp->adv_mac, adv_mac, ETH_ALEN);
397	tmp->info[0] = '\0';
398
399	return 0;
400}
401
402
403void p2p_process_prov_disc_req(struct p2p_data *p2p, const u8 *sa,
404			       const u8 *data, size_t len, int rx_freq)
405{
406	struct p2p_message msg;
407	struct p2p_device *dev;
408	int freq;
409	enum p2p_status_code reject = P2P_SC_FAIL_INCOMPATIBLE_PARAMS;
410	struct wpabuf *resp;
411	u32 adv_id = 0;
412	struct p2ps_advertisement *p2ps_adv = NULL;
413	u8 conncap = P2PS_SETUP_NEW;
414	u8 auto_accept = 0;
415	u32 session_id = 0;
416	u8 session_mac[ETH_ALEN];
417	u8 adv_mac[ETH_ALEN];
418	u8 group_mac[ETH_ALEN];
419	int passwd_id = DEV_PW_DEFAULT;
420	u16 config_methods;
421
422	if (p2p_parse(data, len, &msg))
423		return;
424
425	p2p_dbg(p2p, "Received Provision Discovery Request from " MACSTR
426		" with config methods 0x%x (freq=%d)",
427		MAC2STR(sa), msg.wps_config_methods, rx_freq);
428
429	dev = p2p_get_device(p2p, sa);
430	if (dev == NULL || (dev->flags & P2P_DEV_PROBE_REQ_ONLY)) {
431		p2p_dbg(p2p, "Provision Discovery Request from unknown peer "
432			MACSTR, MAC2STR(sa));
433
434		if (p2p_add_device(p2p, sa, rx_freq, NULL, 0, data + 1, len - 1,
435				   0)) {
436			p2p_dbg(p2p, "Provision Discovery Request add device failed "
437				MACSTR, MAC2STR(sa));
438		}
439	} else if (msg.wfd_subelems) {
440		wpabuf_free(dev->info.wfd_subelems);
441		dev->info.wfd_subelems = wpabuf_dup(msg.wfd_subelems);
442	}
443
444	if (!(msg.wps_config_methods &
445	      (WPS_CONFIG_DISPLAY | WPS_CONFIG_KEYPAD |
446	       WPS_CONFIG_PUSHBUTTON | WPS_CONFIG_P2PS))) {
447		p2p_dbg(p2p, "Unsupported Config Methods in Provision Discovery Request");
448		goto out;
449	}
450
451	/* Legacy (non-P2PS) - Unknown groups allowed for P2PS */
452	if (!msg.adv_id && msg.group_id) {
453		size_t i;
454		for (i = 0; i < p2p->num_groups; i++) {
455			if (p2p_group_is_group_id_match(p2p->groups[i],
456							msg.group_id,
457							msg.group_id_len))
458				break;
459		}
460		if (i == p2p->num_groups) {
461			p2p_dbg(p2p, "PD request for unknown P2P Group ID - reject");
462			goto out;
463		}
464	}
465
466	if (dev) {
467		dev->flags &= ~(P2P_DEV_PD_PEER_DISPLAY |
468				P2P_DEV_PD_PEER_KEYPAD |
469				P2P_DEV_PD_PEER_P2PS);
470
471		/* Remove stale persistent groups */
472		if (p2p->cfg->remove_stale_groups) {
473			p2p->cfg->remove_stale_groups(
474				p2p->cfg->cb_ctx, dev->info.p2p_device_addr,
475				msg.persistent_dev,
476				msg.persistent_ssid, msg.persistent_ssid_len);
477		}
478	}
479	if (msg.wps_config_methods & WPS_CONFIG_DISPLAY) {
480		p2p_dbg(p2p, "Peer " MACSTR
481			" requested us to show a PIN on display", MAC2STR(sa));
482		if (dev)
483			dev->flags |= P2P_DEV_PD_PEER_KEYPAD;
484		passwd_id = DEV_PW_USER_SPECIFIED;
485	} else if (msg.wps_config_methods & WPS_CONFIG_KEYPAD) {
486		p2p_dbg(p2p, "Peer " MACSTR
487			" requested us to write its PIN using keypad",
488			MAC2STR(sa));
489		if (dev)
490			dev->flags |= P2P_DEV_PD_PEER_DISPLAY;
491		passwd_id = DEV_PW_REGISTRAR_SPECIFIED;
492	} else if (msg.wps_config_methods & WPS_CONFIG_P2PS) {
493		p2p_dbg(p2p, "Peer " MACSTR " requesting P2PS PIN",
494			MAC2STR(sa));
495		if (dev)
496			dev->flags |= P2P_DEV_PD_PEER_P2PS;
497		passwd_id = DEV_PW_P2PS_DEFAULT;
498	}
499
500	reject = P2P_SC_SUCCESS;
501
502	os_memset(session_mac, 0, ETH_ALEN);
503	os_memset(adv_mac, 0, ETH_ALEN);
504	os_memset(group_mac, 0, ETH_ALEN);
505
506	if (msg.adv_id && msg.session_id && msg.session_mac && msg.adv_mac &&
507	    (msg.status || msg.conn_cap)) {
508		u8 remote_conncap;
509
510		if (msg.intended_addr)
511			os_memcpy(group_mac, msg.intended_addr, ETH_ALEN);
512
513		os_memcpy(session_mac, msg.session_mac, ETH_ALEN);
514		os_memcpy(adv_mac, msg.adv_mac, ETH_ALEN);
515
516		session_id = WPA_GET_LE32(msg.session_id);
517		adv_id = WPA_GET_LE32(msg.adv_id);
518
519		if (!msg.status)
520			p2ps_adv = p2p_service_p2ps_id(p2p, adv_id);
521
522		p2p_dbg(p2p, "adv_id: %x - p2ps_adv - %p", adv_id, p2ps_adv);
523
524		if (msg.conn_cap)
525			conncap = *msg.conn_cap;
526		remote_conncap = conncap;
527
528		if (p2ps_adv) {
529			auto_accept = p2ps_adv->auto_accept;
530			conncap = p2p->cfg->p2ps_group_capability(
531				p2p->cfg->cb_ctx, conncap, auto_accept);
532
533			p2p_dbg(p2p, "Conncap: local:%d remote:%d result:%d",
534				auto_accept, remote_conncap, conncap);
535
536			if (p2ps_adv->config_methods &&
537			    !(msg.wps_config_methods &
538			      p2ps_adv->config_methods)) {
539				p2p_dbg(p2p,
540					"Unsupported config methods in Provision Discovery Request (own=0x%x peer=0x%x)",
541					p2ps_adv->config_methods,
542					msg.wps_config_methods);
543				reject = P2P_SC_FAIL_INCOMPATIBLE_PARAMS;
544			} else if (!p2ps_adv->state) {
545				p2p_dbg(p2p, "P2PS state unavailable");
546				reject = P2P_SC_FAIL_UNABLE_TO_ACCOMMODATE;
547			} else if (!conncap) {
548				p2p_dbg(p2p, "Conncap resolution failed");
549				reject = P2P_SC_FAIL_INCOMPATIBLE_PARAMS;
550			}
551
552			if (msg.wps_config_methods & WPS_CONFIG_KEYPAD) {
553				p2p_dbg(p2p, "Keypad - always defer");
554				auto_accept = 0;
555			}
556
557			if (auto_accept || reject != P2P_SC_SUCCESS) {
558				struct p2ps_provision *tmp;
559
560				if (reject == P2P_SC_SUCCESS && !conncap) {
561					reject =
562						P2P_SC_FAIL_INCOMPATIBLE_PARAMS;
563				}
564
565				if (p2ps_setup_p2ps_prov(
566					    p2p, adv_id, session_id,
567					    msg.wps_config_methods,
568					    session_mac, adv_mac) < 0) {
569					reject = P2P_SC_FAIL_UNABLE_TO_ACCOMMODATE;
570					goto out;
571				}
572
573				tmp = p2p->p2ps_prov;
574				if (conncap) {
575					tmp->conncap = conncap;
576					tmp->status = P2P_SC_SUCCESS;
577				} else {
578					tmp->conncap = auto_accept;
579					tmp->status = P2P_SC_FAIL_INCOMPATIBLE_PARAMS;
580				}
581
582				if (reject != P2P_SC_SUCCESS)
583					goto out;
584			}
585		} else if (!msg.status) {
586			reject = P2P_SC_FAIL_INCOMPATIBLE_PARAMS;
587			goto out;
588		}
589
590		if (!msg.status && !auto_accept &&
591		    (!p2p->p2ps_prov || p2p->p2ps_prov->adv_id != adv_id)) {
592			struct p2ps_provision *tmp;
593
594			if (!conncap) {
595				reject = P2P_SC_FAIL_INCOMPATIBLE_PARAMS;
596				goto out;
597			}
598
599			if (p2ps_setup_p2ps_prov(p2p, adv_id, session_id,
600						 msg.wps_config_methods,
601						 session_mac, adv_mac) < 0) {
602				reject = P2P_SC_FAIL_UNABLE_TO_ACCOMMODATE;
603				goto out;
604			}
605			tmp = p2p->p2ps_prov;
606			reject = P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE;
607			tmp->status = reject;
608		}
609
610		if (msg.status) {
611			if (*msg.status &&
612			    *msg.status != P2P_SC_SUCCESS_DEFERRED) {
613				reject = *msg.status;
614			} else if (*msg.status == P2P_SC_SUCCESS_DEFERRED &&
615				   p2p->p2ps_prov) {
616				u16 method = p2p->p2ps_prov->method;
617
618				conncap = p2p->cfg->p2ps_group_capability(
619					p2p->cfg->cb_ctx, remote_conncap,
620					p2p->p2ps_prov->conncap);
621
622				p2p_dbg(p2p,
623					"Conncap: local:%d remote:%d result:%d",
624					p2p->p2ps_prov->conncap,
625					remote_conncap, conncap);
626
627				/*
628				 * Ensure that if we asked for PIN originally,
629				 * our method is consistent with original
630				 * request.
631				 */
632				if (method & WPS_CONFIG_DISPLAY)
633					method = WPS_CONFIG_KEYPAD;
634				else if (method & WPS_CONFIG_KEYPAD)
635					method = WPS_CONFIG_DISPLAY;
636
637				/* Reject this "Deferred Accept* if incompatible
638				 * conncap or method */
639				if (!conncap ||
640				    !(msg.wps_config_methods & method))
641					reject =
642						P2P_SC_FAIL_INCOMPATIBLE_PARAMS;
643				else
644					reject = P2P_SC_SUCCESS;
645
646				p2p->p2ps_prov->status = reject;
647				p2p->p2ps_prov->conncap = conncap;
648			}
649		}
650	}
651
652out:
653	if (reject == P2P_SC_SUCCESS ||
654	    reject == P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE)
655		config_methods = msg.wps_config_methods;
656	else
657		config_methods = 0;
658	resp = p2p_build_prov_disc_resp(p2p, dev, msg.dialog_token, reject,
659					config_methods, adv_id,
660					msg.group_id, msg.group_id_len,
661					msg.persistent_ssid,
662					msg.persistent_ssid_len);
663	if (resp == NULL) {
664		p2p_parse_free(&msg);
665		return;
666	}
667	p2p_dbg(p2p, "Sending Provision Discovery Response");
668	if (rx_freq > 0)
669		freq = rx_freq;
670	else
671		freq = p2p_channel_to_freq(p2p->cfg->reg_class,
672					   p2p->cfg->channel);
673	if (freq < 0) {
674		p2p_dbg(p2p, "Unknown regulatory class/channel");
675		wpabuf_free(resp);
676		p2p_parse_free(&msg);
677		return;
678	}
679	p2p->pending_action_state = P2P_PENDING_PD_RESPONSE;
680	if (p2p_send_action(p2p, freq, sa, p2p->cfg->dev_addr,
681			    p2p->cfg->dev_addr,
682			    wpabuf_head(resp), wpabuf_len(resp), 200) < 0) {
683		p2p_dbg(p2p, "Failed to send Action frame");
684	} else
685		p2p->send_action_in_progress = 1;
686
687	wpabuf_free(resp);
688
689	if (!p2p->cfg->p2ps_prov_complete) {
690		/* Don't emit anything */
691	} else if (msg.status && *msg.status != P2P_SC_SUCCESS &&
692		   *msg.status != P2P_SC_SUCCESS_DEFERRED) {
693		reject = *msg.status;
694		p2p->cfg->p2ps_prov_complete(p2p->cfg->cb_ctx, reject,
695					     sa, adv_mac, session_mac,
696					     NULL, adv_id, session_id,
697					     0, 0, msg.persistent_ssid,
698					     msg.persistent_ssid_len,
699					     0, 0, NULL);
700	} else if (msg.status && *msg.status == P2P_SC_SUCCESS_DEFERRED &&
701		   p2p->p2ps_prov) {
702		p2p->p2ps_prov->status = reject;
703		p2p->p2ps_prov->conncap = conncap;
704
705		if (reject != P2P_SC_SUCCESS)
706			p2p->cfg->p2ps_prov_complete(p2p->cfg->cb_ctx, reject,
707						     sa, adv_mac, session_mac,
708						     NULL, adv_id,
709						     session_id, conncap, 0,
710						     msg.persistent_ssid,
711						     msg.persistent_ssid_len, 0,
712						     0, NULL);
713		else
714			p2p->cfg->p2ps_prov_complete(p2p->cfg->cb_ctx,
715						     *msg.status,
716						     sa, adv_mac, session_mac,
717						     group_mac, adv_id,
718						     session_id, conncap,
719						     passwd_id,
720						     msg.persistent_ssid,
721						     msg.persistent_ssid_len, 0,
722						     0, NULL);
723	} else if (msg.status && p2p->p2ps_prov) {
724		p2p->p2ps_prov->status = P2P_SC_SUCCESS;
725		p2p->cfg->p2ps_prov_complete(p2p->cfg->cb_ctx, *msg.status, sa,
726					     adv_mac, session_mac, group_mac,
727					     adv_id, session_id, conncap,
728					     passwd_id,
729					     msg.persistent_ssid,
730					     msg.persistent_ssid_len,
731					     0, 0, NULL);
732	} else if (msg.status) {
733	} else if (auto_accept && reject == P2P_SC_SUCCESS) {
734		p2p->cfg->p2ps_prov_complete(p2p->cfg->cb_ctx, P2P_SC_SUCCESS,
735					     sa, adv_mac, session_mac,
736					     group_mac, adv_id, session_id,
737					     conncap, passwd_id,
738					     msg.persistent_ssid,
739					     msg.persistent_ssid_len,
740					     0, 0, NULL);
741	} else if (reject == P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE &&
742		   (!msg.session_info || !msg.session_info_len)) {
743		p2p->p2ps_prov->method = msg.wps_config_methods;
744
745		p2p->cfg->p2ps_prov_complete(p2p->cfg->cb_ctx, P2P_SC_SUCCESS,
746					     sa, adv_mac, session_mac,
747					     group_mac, adv_id, session_id,
748					     conncap, passwd_id,
749					     msg.persistent_ssid,
750					     msg.persistent_ssid_len,
751					     0, 1, NULL);
752	} else if (reject == P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE) {
753		size_t buf_len = msg.session_info_len;
754		char *buf = os_malloc(2 * buf_len + 1);
755
756		if (buf) {
757			p2p->p2ps_prov->method = msg.wps_config_methods;
758
759			utf8_escape((char *) msg.session_info, buf_len,
760				    buf, 2 * buf_len + 1);
761
762			p2p->cfg->p2ps_prov_complete(
763				p2p->cfg->cb_ctx, P2P_SC_SUCCESS, sa,
764				adv_mac, session_mac, group_mac, adv_id,
765				session_id, conncap, passwd_id,
766				msg.persistent_ssid, msg.persistent_ssid_len,
767				0, 1, buf);
768
769			os_free(buf);
770		}
771	}
772
773	if (reject == P2P_SC_SUCCESS && p2p->cfg->prov_disc_req) {
774		const u8 *dev_addr = sa;
775		if (msg.p2p_device_addr)
776			dev_addr = msg.p2p_device_addr;
777		p2p->cfg->prov_disc_req(p2p->cfg->cb_ctx, sa,
778					msg.wps_config_methods,
779					dev_addr, msg.pri_dev_type,
780					msg.device_name, msg.config_methods,
781					msg.capability ? msg.capability[0] : 0,
782					msg.capability ? msg.capability[1] :
783					0,
784					msg.group_id, msg.group_id_len);
785	}
786	p2p_parse_free(&msg);
787}
788
789
790void p2p_process_prov_disc_resp(struct p2p_data *p2p, const u8 *sa,
791				const u8 *data, size_t len)
792{
793	struct p2p_message msg;
794	struct p2p_device *dev;
795	u16 report_config_methods = 0, req_config_methods;
796	u8 status = P2P_SC_SUCCESS;
797	int success = 0;
798	u32 adv_id = 0;
799	u8 conncap = P2PS_SETUP_NEW;
800	u8 adv_mac[ETH_ALEN];
801	u8 group_mac[ETH_ALEN];
802	int passwd_id = DEV_PW_DEFAULT;
803
804	if (p2p_parse(data, len, &msg))
805		return;
806
807	/* Parse the P2PS members present */
808	if (msg.status)
809		status = *msg.status;
810
811	if (msg.intended_addr)
812		os_memcpy(group_mac, msg.intended_addr, ETH_ALEN);
813	else
814		os_memset(group_mac, 0, ETH_ALEN);
815
816	if (msg.adv_mac)
817		os_memcpy(adv_mac, msg.adv_mac, ETH_ALEN);
818	else
819		os_memset(adv_mac, 0, ETH_ALEN);
820
821	if (msg.adv_id)
822		adv_id = WPA_GET_LE32(msg.adv_id);
823
824	if (msg.conn_cap) {
825		conncap = *msg.conn_cap;
826
827		/* Switch bits to local relative */
828		switch (conncap) {
829		case P2PS_SETUP_GROUP_OWNER:
830			conncap = P2PS_SETUP_CLIENT;
831			break;
832		case P2PS_SETUP_CLIENT:
833			conncap = P2PS_SETUP_GROUP_OWNER;
834			break;
835		}
836	}
837
838	p2p_dbg(p2p, "Received Provision Discovery Response from " MACSTR
839		" with config methods 0x%x",
840		MAC2STR(sa), msg.wps_config_methods);
841
842	dev = p2p_get_device(p2p, sa);
843	if (dev == NULL || !dev->req_config_methods) {
844		p2p_dbg(p2p, "Ignore Provision Discovery Response from " MACSTR
845			" with no pending request", MAC2STR(sa));
846		p2p_parse_free(&msg);
847		return;
848	}
849
850	if (dev->dialog_token != msg.dialog_token) {
851		p2p_dbg(p2p, "Ignore Provision Discovery Response with unexpected Dialog Token %u (expected %u)",
852			msg.dialog_token, dev->dialog_token);
853		p2p_parse_free(&msg);
854		return;
855	}
856
857	if (p2p->pending_action_state == P2P_PENDING_PD) {
858		os_memset(p2p->pending_pd_devaddr, 0, ETH_ALEN);
859		p2p->pending_action_state = P2P_NO_PENDING_ACTION;
860	}
861
862	/*
863	 * Use a local copy of the requested config methods since
864	 * p2p_reset_pending_pd() can clear this in the peer entry.
865	 */
866	req_config_methods = dev->req_config_methods;
867
868	/*
869	 * If the response is from the peer to whom a user initiated request
870	 * was sent earlier, we reset that state info here.
871	 */
872	if (p2p->user_initiated_pd &&
873	    os_memcmp(p2p->pending_pd_devaddr, sa, ETH_ALEN) == 0)
874		p2p_reset_pending_pd(p2p);
875
876	if (msg.wps_config_methods != req_config_methods) {
877		p2p_dbg(p2p, "Peer rejected our Provision Discovery Request (received config_methods 0x%x expected 0x%x",
878			msg.wps_config_methods, req_config_methods);
879		if (p2p->cfg->prov_disc_fail)
880			p2p->cfg->prov_disc_fail(p2p->cfg->cb_ctx, sa,
881						 P2P_PROV_DISC_REJECTED,
882						 adv_id, adv_mac, NULL);
883		p2p_parse_free(&msg);
884		p2ps_prov_free(p2p);
885		goto out;
886	}
887
888	report_config_methods = req_config_methods;
889	dev->flags &= ~(P2P_DEV_PD_PEER_DISPLAY |
890			P2P_DEV_PD_PEER_KEYPAD |
891			P2P_DEV_PD_PEER_P2PS);
892	if (req_config_methods & WPS_CONFIG_DISPLAY) {
893		p2p_dbg(p2p, "Peer " MACSTR
894			" accepted to show a PIN on display", MAC2STR(sa));
895		dev->flags |= P2P_DEV_PD_PEER_DISPLAY;
896		passwd_id = DEV_PW_REGISTRAR_SPECIFIED;
897	} else if (msg.wps_config_methods & WPS_CONFIG_KEYPAD) {
898		p2p_dbg(p2p, "Peer " MACSTR
899			" accepted to write our PIN using keypad",
900			MAC2STR(sa));
901		dev->flags |= P2P_DEV_PD_PEER_KEYPAD;
902		passwd_id = DEV_PW_USER_SPECIFIED;
903	} else if (msg.wps_config_methods & WPS_CONFIG_P2PS) {
904		p2p_dbg(p2p, "Peer " MACSTR " accepted P2PS PIN",
905			MAC2STR(sa));
906		dev->flags |= P2P_DEV_PD_PEER_P2PS;
907		passwd_id = DEV_PW_P2PS_DEFAULT;
908	}
909
910	if ((msg.conn_cap || msg.persistent_dev) &&
911	    msg.adv_id &&
912	    (status == P2P_SC_SUCCESS || status == P2P_SC_SUCCESS_DEFERRED) &&
913	    p2p->p2ps_prov) {
914		if (p2p->cfg->p2ps_prov_complete) {
915			p2p->cfg->p2ps_prov_complete(
916				p2p->cfg->cb_ctx, status, sa, adv_mac,
917				p2p->p2ps_prov->session_mac,
918				group_mac, adv_id, p2p->p2ps_prov->session_id,
919				conncap, passwd_id, msg.persistent_ssid,
920				msg.persistent_ssid_len, 1, 0, NULL);
921		}
922		p2ps_prov_free(p2p);
923	}
924
925	if (status != P2P_SC_SUCCESS &&
926	    status != P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE &&
927	    status != P2P_SC_SUCCESS_DEFERRED && p2p->p2ps_prov) {
928		if (p2p->cfg->p2ps_prov_complete)
929			p2p->cfg->p2ps_prov_complete(
930				p2p->cfg->cb_ctx, status, sa, adv_mac,
931				p2p->p2ps_prov->session_mac,
932				group_mac, adv_id, p2p->p2ps_prov->session_id,
933				0, 0, NULL, 0, 1, 0, NULL);
934		p2ps_prov_free(p2p);
935	}
936
937	if (status == P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE) {
938		if (p2p->cfg->remove_stale_groups) {
939			p2p->cfg->remove_stale_groups(p2p->cfg->cb_ctx,
940						      dev->info.p2p_device_addr,
941						      NULL, NULL, 0);
942		}
943
944		if (msg.session_info && msg.session_info_len) {
945			size_t info_len = msg.session_info_len;
946			char *deferred_sess_resp = os_malloc(2 * info_len + 1);
947
948			if (!deferred_sess_resp) {
949				p2p_parse_free(&msg);
950				p2ps_prov_free(p2p);
951				goto out;
952			}
953			utf8_escape((char *) msg.session_info, info_len,
954				    deferred_sess_resp, 2 * info_len + 1);
955
956			if (p2p->cfg->prov_disc_fail)
957				p2p->cfg->prov_disc_fail(
958					p2p->cfg->cb_ctx, sa,
959					P2P_PROV_DISC_INFO_UNAVAILABLE,
960					adv_id, adv_mac,
961					deferred_sess_resp);
962			os_free(deferred_sess_resp);
963		} else
964			if (p2p->cfg->prov_disc_fail)
965				p2p->cfg->prov_disc_fail(
966					p2p->cfg->cb_ctx, sa,
967					P2P_PROV_DISC_INFO_UNAVAILABLE,
968					adv_id, adv_mac, NULL);
969	} else if (msg.wps_config_methods != dev->req_config_methods ||
970		   status != P2P_SC_SUCCESS) {
971		p2p_dbg(p2p, "Peer rejected our Provision Discovery Request");
972		if (p2p->cfg->prov_disc_fail)
973			p2p->cfg->prov_disc_fail(p2p->cfg->cb_ctx, sa,
974						 P2P_PROV_DISC_REJECTED, 0,
975						 NULL, NULL);
976		p2p_parse_free(&msg);
977		p2ps_prov_free(p2p);
978		goto out;
979	}
980
981	/* Store the provisioning info */
982	dev->wps_prov_info = msg.wps_config_methods;
983
984	p2p_parse_free(&msg);
985	success = 1;
986
987out:
988	dev->req_config_methods = 0;
989	p2p->cfg->send_action_done(p2p->cfg->cb_ctx);
990	if (dev->flags & P2P_DEV_PD_BEFORE_GO_NEG) {
991		p2p_dbg(p2p, "Start GO Neg after the PD-before-GO-Neg workaround with "
992			MACSTR, MAC2STR(dev->info.p2p_device_addr));
993		dev->flags &= ~P2P_DEV_PD_BEFORE_GO_NEG;
994		p2p_connect_send(p2p, dev);
995		return;
996	}
997	if (success && p2p->cfg->prov_disc_resp)
998		p2p->cfg->prov_disc_resp(p2p->cfg->cb_ctx, sa,
999					 report_config_methods);
1000
1001	if (p2p->state == P2P_PD_DURING_FIND) {
1002		p2p_clear_timeout(p2p);
1003		p2p_continue_find(p2p);
1004	}
1005}
1006
1007
1008int p2p_send_prov_disc_req(struct p2p_data *p2p, struct p2p_device *dev,
1009			   int join, int force_freq)
1010{
1011	struct wpabuf *req;
1012	int freq;
1013
1014	if (force_freq > 0)
1015		freq = force_freq;
1016	else
1017		freq = dev->listen_freq > 0 ? dev->listen_freq :
1018			dev->oper_freq;
1019	if (freq <= 0) {
1020		p2p_dbg(p2p, "No Listen/Operating frequency known for the peer "
1021			MACSTR " to send Provision Discovery Request",
1022			MAC2STR(dev->info.p2p_device_addr));
1023		return -1;
1024	}
1025
1026	if (dev->flags & P2P_DEV_GROUP_CLIENT_ONLY) {
1027		if (!(dev->info.dev_capab &
1028		      P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY)) {
1029			p2p_dbg(p2p, "Cannot use PD with P2P Device " MACSTR
1030				" that is in a group and is not discoverable",
1031				MAC2STR(dev->info.p2p_device_addr));
1032			return -1;
1033		}
1034		/* TODO: use device discoverability request through GO */
1035	}
1036
1037	if (p2p->p2ps_prov) {
1038		if (p2p->p2ps_prov->status == P2P_SC_SUCCESS_DEFERRED) {
1039			if (p2p->p2ps_prov->method == WPS_CONFIG_DISPLAY)
1040				dev->req_config_methods = WPS_CONFIG_KEYPAD;
1041			else if (p2p->p2ps_prov->method == WPS_CONFIG_KEYPAD)
1042				dev->req_config_methods = WPS_CONFIG_DISPLAY;
1043			else
1044				dev->req_config_methods = WPS_CONFIG_P2PS;
1045		} else {
1046			/* Order of preference, based on peer's capabilities */
1047			if (p2p->p2ps_prov->method)
1048				dev->req_config_methods =
1049					p2p->p2ps_prov->method;
1050			else if (dev->info.config_methods & WPS_CONFIG_P2PS)
1051				dev->req_config_methods = WPS_CONFIG_P2PS;
1052			else if (dev->info.config_methods & WPS_CONFIG_DISPLAY)
1053				dev->req_config_methods = WPS_CONFIG_DISPLAY;
1054			else
1055				dev->req_config_methods = WPS_CONFIG_KEYPAD;
1056		}
1057		p2p_dbg(p2p,
1058			"Building PD Request based on P2PS config method 0x%x status %d --> req_config_methods 0x%x",
1059			p2p->p2ps_prov->method, p2p->p2ps_prov->status,
1060			dev->req_config_methods);
1061	}
1062
1063	req = p2p_build_prov_disc_req(p2p, dev, join);
1064	if (req == NULL)
1065		return -1;
1066
1067	if (p2p->state != P2P_IDLE)
1068		p2p_stop_listen_for_freq(p2p, freq);
1069	p2p->pending_action_state = P2P_PENDING_PD;
1070	if (p2p_send_action(p2p, freq, dev->info.p2p_device_addr,
1071			    p2p->cfg->dev_addr, dev->info.p2p_device_addr,
1072			    wpabuf_head(req), wpabuf_len(req), 200) < 0) {
1073		p2p_dbg(p2p, "Failed to send Action frame");
1074		wpabuf_free(req);
1075		return -1;
1076	}
1077
1078	os_memcpy(p2p->pending_pd_devaddr, dev->info.p2p_device_addr, ETH_ALEN);
1079
1080	wpabuf_free(req);
1081	return 0;
1082}
1083
1084
1085int p2p_prov_disc_req(struct p2p_data *p2p, const u8 *peer_addr,
1086		      struct p2ps_provision *p2ps_prov,
1087		      u16 config_methods, int join, int force_freq,
1088		      int user_initiated_pd)
1089{
1090	struct p2p_device *dev;
1091
1092	dev = p2p_get_device(p2p, peer_addr);
1093	if (dev == NULL)
1094		dev = p2p_get_device_interface(p2p, peer_addr);
1095	if (dev == NULL || (dev->flags & P2P_DEV_PROBE_REQ_ONLY)) {
1096		p2p_dbg(p2p, "Provision Discovery Request destination " MACSTR
1097			" not yet known", MAC2STR(peer_addr));
1098		os_free(p2ps_prov);
1099		return -1;
1100	}
1101
1102	p2p_dbg(p2p, "Provision Discovery Request with " MACSTR
1103		" (config methods 0x%x)",
1104		MAC2STR(peer_addr), config_methods);
1105	if (config_methods == 0 && !p2ps_prov) {
1106		os_free(p2ps_prov);
1107		return -1;
1108	}
1109
1110	if (p2ps_prov && p2ps_prov->status == P2P_SC_SUCCESS_DEFERRED &&
1111	    p2p->p2ps_prov) {
1112		/* Use cached method from deferred provisioning */
1113		p2ps_prov->method = p2p->p2ps_prov->method;
1114	}
1115
1116	/* Reset provisioning info */
1117	dev->wps_prov_info = 0;
1118	p2ps_prov_free(p2p);
1119	p2p->p2ps_prov = p2ps_prov;
1120
1121	dev->req_config_methods = config_methods;
1122	if (join)
1123		dev->flags |= P2P_DEV_PD_FOR_JOIN;
1124	else
1125		dev->flags &= ~P2P_DEV_PD_FOR_JOIN;
1126
1127	if (p2p->state != P2P_IDLE && p2p->state != P2P_SEARCH &&
1128	    p2p->state != P2P_LISTEN_ONLY) {
1129		p2p_dbg(p2p, "Busy with other operations; postpone Provision Discovery Request with "
1130			MACSTR " (config methods 0x%x)",
1131			MAC2STR(peer_addr), config_methods);
1132		return 0;
1133	}
1134
1135	p2p->user_initiated_pd = user_initiated_pd;
1136	p2p->pd_force_freq = force_freq;
1137
1138	if (p2p->user_initiated_pd)
1139		p2p->pd_retries = MAX_PROV_DISC_REQ_RETRIES;
1140
1141	/*
1142	 * Assign dialog token here to use the same value in each retry within
1143	 * the same PD exchange.
1144	 */
1145	dev->dialog_token++;
1146	if (dev->dialog_token == 0)
1147		dev->dialog_token = 1;
1148
1149	return p2p_send_prov_disc_req(p2p, dev, join, force_freq);
1150}
1151
1152
1153void p2p_reset_pending_pd(struct p2p_data *p2p)
1154{
1155	struct p2p_device *dev;
1156
1157	dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) {
1158		if (os_memcmp(p2p->pending_pd_devaddr,
1159			      dev->info.p2p_device_addr, ETH_ALEN))
1160			continue;
1161		if (!dev->req_config_methods)
1162			continue;
1163		if (dev->flags & P2P_DEV_PD_FOR_JOIN)
1164			continue;
1165		/* Reset the config methods of the device */
1166		dev->req_config_methods = 0;
1167	}
1168
1169	p2p->user_initiated_pd = 0;
1170	os_memset(p2p->pending_pd_devaddr, 0, ETH_ALEN);
1171	p2p->pd_retries = 0;
1172	p2p->pd_force_freq = 0;
1173}
1174
1175
1176void p2ps_prov_free(struct p2p_data *p2p)
1177{
1178	os_free(p2p->p2ps_prov);
1179	p2p->p2ps_prov = NULL;
1180}
1181