• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
p2p_build_wps_ie_config_methods(struct wpabuf * buf,u16 config_methods)26 static 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 
p2ps_add_new_group_info(struct p2p_data * p2p,struct p2p_device * dev,struct wpabuf * buf)43 static void p2ps_add_new_group_info(struct p2p_data *p2p,
44 				    struct p2p_device *dev,
45 				    struct wpabuf *buf)
46 {
47 	int found;
48 	u8 intended_addr[ETH_ALEN];
49 	u8 ssid[SSID_MAX_LEN];
50 	size_t ssid_len;
51 	int group_iface;
52 	unsigned int force_freq;
53 
54 	if (!p2p->cfg->get_go_info)
55 		return;
56 
57 	found = p2p->cfg->get_go_info(
58 		p2p->cfg->cb_ctx, intended_addr, ssid,
59 		&ssid_len, &group_iface, &force_freq);
60 	if (found) {
61 		if (force_freq > 0) {
62 			p2p->p2ps_prov->force_freq = force_freq;
63 			p2p->p2ps_prov->pref_freq = 0;
64 
65 			if (dev)
66 				p2p_prepare_channel(p2p, dev, force_freq, 0, 0);
67 		}
68 		p2p_buf_add_group_id(buf, p2p->cfg->dev_addr,
69 				     ssid, ssid_len);
70 
71 		if (group_iface)
72 			p2p_buf_add_intended_addr(buf, p2p->intended_addr);
73 		else
74 			p2p_buf_add_intended_addr(buf, intended_addr);
75 	} else {
76 		if (!p2p->ssid_set) {
77 			p2p_build_ssid(p2p, p2p->ssid, &p2p->ssid_len);
78 			p2p->ssid_set = 1;
79 		}
80 
81 		/* Add pre-composed P2P Group ID */
82 		p2p_buf_add_group_id(buf, p2p->cfg->dev_addr,
83 				     p2p->ssid, p2p->ssid_len);
84 
85 		if (group_iface)
86 			p2p_buf_add_intended_addr(
87 				buf, p2p->intended_addr);
88 		else
89 			p2p_buf_add_intended_addr(
90 				buf, p2p->cfg->dev_addr);
91 	}
92 }
93 
94 
p2ps_add_pd_req_attrs(struct p2p_data * p2p,struct p2p_device * dev,struct wpabuf * buf,u16 config_methods)95 static void p2ps_add_pd_req_attrs(struct p2p_data *p2p, struct p2p_device *dev,
96 				  struct wpabuf *buf, u16 config_methods)
97 {
98 	struct p2ps_provision *prov = p2p->p2ps_prov;
99 	struct p2ps_feature_capab fcap = { prov->cpt_mask, 0 };
100 	int shared_group = 0;
101 	u8 ssid[SSID_MAX_LEN];
102 	size_t ssid_len;
103 	u8 go_dev_addr[ETH_ALEN];
104 	u8 intended_addr[ETH_ALEN];
105 	int follow_on_req_fail = prov->status >= 0 &&
106 		prov->status != P2P_SC_SUCCESS_DEFERRED;
107 
108 	/* If we might be explicite group owner, add GO details */
109 	if (!follow_on_req_fail &&
110 	    (prov->conncap & (P2PS_SETUP_GROUP_OWNER | P2PS_SETUP_NEW)))
111 		p2ps_add_new_group_info(p2p, dev, buf);
112 
113 	if (prov->status >= 0)
114 		p2p_buf_add_status(buf, (u8) prov->status);
115 	else
116 		prov->method = config_methods;
117 
118 	if (!follow_on_req_fail) {
119 		if (p2p->cfg->get_persistent_group) {
120 			shared_group = p2p->cfg->get_persistent_group(
121 				p2p->cfg->cb_ctx, dev->info.p2p_device_addr,
122 				NULL, 0, go_dev_addr, ssid, &ssid_len,
123 				intended_addr);
124 		}
125 
126 		if (shared_group ||
127 		    (prov->conncap & (P2PS_SETUP_CLIENT | P2PS_SETUP_NEW)))
128 			p2p_buf_add_channel_list(buf, p2p->cfg->country,
129 						 &p2p->channels);
130 
131 		if ((shared_group && !is_zero_ether_addr(intended_addr)) ||
132 		    (prov->conncap & (P2PS_SETUP_GROUP_OWNER | P2PS_SETUP_NEW)))
133 			p2p_buf_add_operating_channel(buf, p2p->cfg->country,
134 						      p2p->op_reg_class,
135 						      p2p->op_channel);
136 	}
137 
138 	if (prov->status < 0 && prov->info[0])
139 		p2p_buf_add_session_info(buf, prov->info);
140 
141 	if (!follow_on_req_fail)
142 		p2p_buf_add_connection_capability(buf, prov->conncap);
143 
144 	p2p_buf_add_advertisement_id(buf, prov->adv_id, prov->adv_mac);
145 
146 	if (!follow_on_req_fail) {
147 		if (shared_group || prov->conncap == P2PS_SETUP_NEW ||
148 		    prov->conncap ==
149 		    (P2PS_SETUP_GROUP_OWNER | P2PS_SETUP_NEW) ||
150 		    prov->conncap ==
151 		    (P2PS_SETUP_GROUP_OWNER | P2PS_SETUP_CLIENT)) {
152 			/* Add Config Timeout */
153 			p2p_buf_add_config_timeout(buf, p2p->go_timeout,
154 						   p2p->client_timeout);
155 		}
156 
157 		p2p_buf_add_listen_channel(buf, p2p->cfg->country,
158 					   p2p->cfg->reg_class,
159 					   p2p->cfg->channel);
160 	}
161 
162 	p2p_buf_add_session_id(buf, prov->session_id, prov->session_mac);
163 
164 	p2p_buf_add_feature_capability(buf, sizeof(fcap), (const u8 *) &fcap);
165 
166 	if (shared_group) {
167 		p2p_buf_add_persistent_group_info(buf, go_dev_addr,
168 						  ssid, ssid_len);
169 		/* Add intended interface address if it is not added yet */
170 		if ((prov->conncap == P2PS_SETUP_NONE ||
171 		     prov->conncap == P2PS_SETUP_CLIENT) &&
172 		    !is_zero_ether_addr(intended_addr))
173 			p2p_buf_add_intended_addr(buf, intended_addr);
174 	}
175 }
176 
177 
p2p_build_prov_disc_req(struct p2p_data * p2p,struct p2p_device * dev,int join)178 static struct wpabuf * p2p_build_prov_disc_req(struct p2p_data *p2p,
179 					       struct p2p_device *dev,
180 					       int join)
181 {
182 	struct wpabuf *buf;
183 	u8 *len;
184 	size_t extra = 0;
185 	u8 dialog_token = dev->dialog_token;
186 	u16 config_methods = dev->req_config_methods;
187 	struct p2p_device *go = join ? dev : NULL;
188 	u8 group_capab;
189 
190 #ifdef CONFIG_WIFI_DISPLAY
191 	if (p2p->wfd_ie_prov_disc_req)
192 		extra = wpabuf_len(p2p->wfd_ie_prov_disc_req);
193 #endif /* CONFIG_WIFI_DISPLAY */
194 
195 	if (p2p->vendor_elem && p2p->vendor_elem[VENDOR_ELEM_P2P_PD_REQ])
196 		extra += wpabuf_len(p2p->vendor_elem[VENDOR_ELEM_P2P_PD_REQ]);
197 
198 	if (p2p->p2ps_prov)
199 		extra += os_strlen(p2p->p2ps_prov->info) + 1 +
200 			sizeof(struct p2ps_provision);
201 
202 	buf = wpabuf_alloc(1000 + extra);
203 	if (buf == NULL)
204 		return NULL;
205 
206 	p2p_buf_add_public_action_hdr(buf, P2P_PROV_DISC_REQ, dialog_token);
207 
208 	len = p2p_buf_add_ie_hdr(buf);
209 
210 	group_capab = 0;
211 	if (p2p->p2ps_prov) {
212 		group_capab |= P2P_GROUP_CAPAB_PERSISTENT_GROUP;
213 		group_capab |= P2P_GROUP_CAPAB_PERSISTENT_RECONN;
214 		if (p2p->cross_connect)
215 			group_capab |= P2P_GROUP_CAPAB_CROSS_CONN;
216 		if (p2p->cfg->p2p_intra_bss)
217 			group_capab |= P2P_GROUP_CAPAB_INTRA_BSS_DIST;
218 	}
219 	p2p_buf_add_capability(buf, p2p->dev_capab &
220 			       ~P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY,
221 			       group_capab);
222 	p2p_buf_add_device_info(buf, p2p, NULL);
223 	if (p2p->p2ps_prov) {
224 		p2ps_add_pd_req_attrs(p2p, dev, buf, config_methods);
225 	} else if (go) {
226 		p2p_buf_add_group_id(buf, go->info.p2p_device_addr,
227 				     go->oper_ssid, go->oper_ssid_len);
228 	}
229 	p2p_buf_update_ie_hdr(buf, len);
230 
231 	/* WPS IE with Config Methods attribute */
232 	p2p_build_wps_ie_config_methods(buf, config_methods);
233 
234 #ifdef CONFIG_WIFI_DISPLAY
235 	if (p2p->wfd_ie_prov_disc_req)
236 		wpabuf_put_buf(buf, p2p->wfd_ie_prov_disc_req);
237 #endif /* CONFIG_WIFI_DISPLAY */
238 
239 	if (p2p->vendor_elem && p2p->vendor_elem[VENDOR_ELEM_P2P_PD_REQ])
240 		wpabuf_put_buf(buf, p2p->vendor_elem[VENDOR_ELEM_P2P_PD_REQ]);
241 
242 	return buf;
243 }
244 
245 
p2p_build_prov_disc_resp(struct p2p_data * p2p,struct p2p_device * dev,u8 dialog_token,enum p2p_status_code status,u16 config_methods,u32 adv_id,const u8 * group_id,size_t group_id_len,const u8 * persist_ssid,size_t persist_ssid_len,const u8 * fcap,u16 fcap_len)246 static struct wpabuf * p2p_build_prov_disc_resp(struct p2p_data *p2p,
247 						struct p2p_device *dev,
248 						u8 dialog_token,
249 						enum p2p_status_code status,
250 						u16 config_methods,
251 						u32 adv_id,
252 						const u8 *group_id,
253 						size_t group_id_len,
254 						const u8 *persist_ssid,
255 						size_t persist_ssid_len,
256 						const u8 *fcap,
257 						u16 fcap_len)
258 {
259 	struct wpabuf *buf;
260 	size_t extra = 0;
261 	int persist = 0;
262 
263 #ifdef CONFIG_WIFI_DISPLAY
264 	struct wpabuf *wfd_ie = p2p->wfd_ie_prov_disc_resp;
265 	if (wfd_ie && group_id) {
266 		size_t i;
267 		for (i = 0; i < p2p->num_groups; i++) {
268 			struct p2p_group *g = p2p->groups[i];
269 			struct wpabuf *ie;
270 			if (!p2p_group_is_group_id_match(g, group_id,
271 							 group_id_len))
272 				continue;
273 			ie = p2p_group_get_wfd_ie(g);
274 			if (ie) {
275 				wfd_ie = ie;
276 				break;
277 			}
278 		}
279 	}
280 	if (wfd_ie)
281 		extra = wpabuf_len(wfd_ie);
282 #endif /* CONFIG_WIFI_DISPLAY */
283 
284 	if (p2p->vendor_elem && p2p->vendor_elem[VENDOR_ELEM_P2P_PD_RESP])
285 		extra += wpabuf_len(p2p->vendor_elem[VENDOR_ELEM_P2P_PD_RESP]);
286 
287 	buf = wpabuf_alloc(1000 + extra);
288 	if (buf == NULL)
289 		return NULL;
290 
291 	p2p_buf_add_public_action_hdr(buf, P2P_PROV_DISC_RESP, dialog_token);
292 
293 	/* Add P2P IE for P2PS */
294 	if (p2p->p2ps_prov && p2p->p2ps_prov->adv_id == adv_id) {
295 		u8 *len = p2p_buf_add_ie_hdr(buf);
296 		struct p2ps_provision *prov = p2p->p2ps_prov;
297 		u8 group_capab;
298 		u8 conncap = 0;
299 
300 		if (status == P2P_SC_SUCCESS ||
301 		    status == P2P_SC_SUCCESS_DEFERRED)
302 			conncap = prov->conncap;
303 
304 		if (!status && prov->status != -1)
305 			status = prov->status;
306 
307 		p2p_buf_add_status(buf, status);
308 		group_capab = P2P_GROUP_CAPAB_PERSISTENT_GROUP |
309 			P2P_GROUP_CAPAB_PERSISTENT_RECONN;
310 		if (p2p->cross_connect)
311 			group_capab |= P2P_GROUP_CAPAB_CROSS_CONN;
312 		if (p2p->cfg->p2p_intra_bss)
313 			group_capab |= P2P_GROUP_CAPAB_INTRA_BSS_DIST;
314 		p2p_buf_add_capability(buf, p2p->dev_capab &
315 				       ~P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY,
316 				       group_capab);
317 		p2p_buf_add_device_info(buf, p2p, NULL);
318 
319 		if (persist_ssid && p2p->cfg->get_persistent_group && dev &&
320 		    (status == P2P_SC_SUCCESS ||
321 		     status == P2P_SC_SUCCESS_DEFERRED)) {
322 			u8 ssid[SSID_MAX_LEN];
323 			size_t ssid_len;
324 			u8 go_dev_addr[ETH_ALEN];
325 			u8 intended_addr[ETH_ALEN];
326 
327 			persist = p2p->cfg->get_persistent_group(
328 				p2p->cfg->cb_ctx,
329 				dev->info.p2p_device_addr,
330 				persist_ssid, persist_ssid_len, go_dev_addr,
331 				ssid, &ssid_len, intended_addr);
332 			if (persist) {
333 				p2p_buf_add_persistent_group_info(
334 					buf, go_dev_addr, ssid, ssid_len);
335 				if (!is_zero_ether_addr(intended_addr))
336 					p2p_buf_add_intended_addr(
337 						buf, intended_addr);
338 			}
339 		}
340 
341 		if (!persist && (conncap & P2PS_SETUP_GROUP_OWNER))
342 			p2ps_add_new_group_info(p2p, dev, buf);
343 
344 		/* Add Operating Channel if conncap indicates GO */
345 		if (persist || (conncap & P2PS_SETUP_GROUP_OWNER)) {
346 			if (p2p->op_reg_class && p2p->op_channel)
347 				p2p_buf_add_operating_channel(
348 					buf, p2p->cfg->country,
349 					p2p->op_reg_class,
350 					p2p->op_channel);
351 			else
352 				p2p_buf_add_operating_channel(
353 					buf, p2p->cfg->country,
354 					p2p->cfg->op_reg_class,
355 					p2p->cfg->op_channel);
356 		}
357 
358 		if (persist ||
359 		    (conncap & (P2PS_SETUP_CLIENT | P2PS_SETUP_GROUP_OWNER)))
360 			p2p_buf_add_channel_list(buf, p2p->cfg->country,
361 						 &p2p->channels);
362 
363 		if (!persist && conncap)
364 			p2p_buf_add_connection_capability(buf, conncap);
365 
366 		p2p_buf_add_advertisement_id(buf, adv_id, prov->adv_mac);
367 
368 		if (persist ||
369 		    (conncap & (P2PS_SETUP_CLIENT | P2PS_SETUP_GROUP_OWNER)))
370 			p2p_buf_add_config_timeout(buf, p2p->go_timeout,
371 						   p2p->client_timeout);
372 
373 		p2p_buf_add_session_id(buf, prov->session_id,
374 				       prov->session_mac);
375 
376 		p2p_buf_add_feature_capability(buf, fcap_len, fcap);
377 		p2p_buf_update_ie_hdr(buf, len);
378 	} else if (status != P2P_SC_SUCCESS || adv_id) {
379 		u8 *len = p2p_buf_add_ie_hdr(buf);
380 
381 		p2p_buf_add_status(buf, status);
382 
383 		if (p2p->p2ps_prov)
384 			p2p_buf_add_advertisement_id(buf, adv_id,
385 						     p2p->p2ps_prov->adv_mac);
386 
387 		p2p_buf_update_ie_hdr(buf, len);
388 	}
389 
390 	/* WPS IE with Config Methods attribute */
391 	p2p_build_wps_ie_config_methods(buf, config_methods);
392 
393 #ifdef CONFIG_WIFI_DISPLAY
394 	if (wfd_ie)
395 		wpabuf_put_buf(buf, wfd_ie);
396 #endif /* CONFIG_WIFI_DISPLAY */
397 
398 	if (p2p->vendor_elem && p2p->vendor_elem[VENDOR_ELEM_P2P_PD_RESP])
399 		wpabuf_put_buf(buf, p2p->vendor_elem[VENDOR_ELEM_P2P_PD_RESP]);
400 
401 	return buf;
402 }
403 
404 
p2ps_setup_p2ps_prov(struct p2p_data * p2p,u32 adv_id,u32 session_id,u16 method,const u8 * session_mac,const u8 * adv_mac)405 static int p2ps_setup_p2ps_prov(struct p2p_data *p2p, u32 adv_id,
406 				u32 session_id, u16 method,
407 				const u8 *session_mac, const u8 *adv_mac)
408 {
409 	struct p2ps_provision *tmp;
410 
411 	if (!p2p->p2ps_prov) {
412 		p2p->p2ps_prov = os_zalloc(sizeof(struct p2ps_provision) + 1);
413 		if (!p2p->p2ps_prov)
414 			return -1;
415 	} else {
416 		os_memset(p2p->p2ps_prov, 0, sizeof(struct p2ps_provision) + 1);
417 	}
418 
419 	tmp = p2p->p2ps_prov;
420 	tmp->adv_id = adv_id;
421 	tmp->session_id = session_id;
422 	tmp->method = method;
423 	os_memcpy(tmp->session_mac, session_mac, ETH_ALEN);
424 	os_memcpy(tmp->adv_mac, adv_mac, ETH_ALEN);
425 	tmp->info[0] = '\0';
426 
427 	return 0;
428 }
429 
430 
p2ps_own_preferred_cpt(const u8 * cpt_priority,u8 req_cpt_mask)431 static u8 p2ps_own_preferred_cpt(const u8 *cpt_priority, u8 req_cpt_mask)
432 {
433 	int i;
434 
435 	for (i = 0; cpt_priority[i]; i++)
436 		if (req_cpt_mask & cpt_priority[i])
437 			return cpt_priority[i];
438 
439 	return 0;
440 }
441 
442 
443 /* Check if the message contains a valid P2PS PD Request */
p2ps_validate_pd_req(struct p2p_data * p2p,struct p2p_message * msg,const u8 * addr)444 static int p2ps_validate_pd_req(struct p2p_data *p2p, struct p2p_message *msg,
445 				const u8 *addr)
446 {
447 	u8 group_id = 0;
448 	u8 intended_addr = 0;
449 	u8 operating_channel = 0;
450 	u8 channel_list = 0;
451 	u8 config_timeout = 0;
452 	u8 listen_channel = 0;
453 
454 #define P2PS_PD_REQ_CHECK(_val, _attr) \
455 do { \
456 	if ((_val) && !msg->_attr) { \
457 		p2p_dbg(p2p, "Not P2PS PD Request. Missing %s", #_attr); \
458 		return -1; \
459 	} \
460 } while (0)
461 
462 	P2PS_PD_REQ_CHECK(1, adv_id);
463 	P2PS_PD_REQ_CHECK(1, session_id);
464 	P2PS_PD_REQ_CHECK(1, session_mac);
465 	P2PS_PD_REQ_CHECK(1, adv_mac);
466 	P2PS_PD_REQ_CHECK(1, capability);
467 	P2PS_PD_REQ_CHECK(1, p2p_device_info);
468 	P2PS_PD_REQ_CHECK(1, feature_cap);
469 
470 	/*
471 	 * We don't need to check Connection Capability, Persistent Group,
472 	 * and related attributes for follow-on PD Request with a status
473 	 * other than SUCCESS_DEFERRED.
474 	 */
475 	if (msg->status && *msg->status != P2P_SC_SUCCESS_DEFERRED)
476 		return 0;
477 
478 	P2PS_PD_REQ_CHECK(1, conn_cap);
479 
480 	/*
481 	 * Note 1: A feature capability attribute structure can be changed
482 	 * in the future. The assumption is that such modifications are
483 	 * backward compatible, therefore we allow processing of msg.feature_cap
484 	 * exceeding the size of the p2ps_feature_capab structure.
485 	 * Note 2: Verification of msg.feature_cap_len below has to be changed
486 	 * to allow 2 byte feature capability processing if
487 	 * struct p2ps_feature_capab is extended to include additional fields
488 	 * and it affects the structure size.
489 	 */
490 	if (msg->feature_cap_len < sizeof(struct p2ps_feature_capab)) {
491 		p2p_dbg(p2p, "P2PS: Invalid feature capability len");
492 		return -1;
493 	}
494 
495 	switch (*msg->conn_cap) {
496 	case P2PS_SETUP_NEW:
497 		group_id = 1;
498 		intended_addr = 1;
499 		operating_channel = 1;
500 		channel_list = 1;
501 		config_timeout = 1;
502 		listen_channel = 1;
503 		break;
504 	case P2PS_SETUP_CLIENT:
505 		channel_list = 1;
506 		listen_channel = 1;
507 		break;
508 	case P2PS_SETUP_GROUP_OWNER:
509 		group_id = 1;
510 		intended_addr = 1;
511 		operating_channel = 1;
512 		break;
513 	case P2PS_SETUP_NEW | P2PS_SETUP_GROUP_OWNER:
514 		group_id = 1;
515 		operating_channel = 1;
516 		intended_addr = 1;
517 		channel_list = 1;
518 		config_timeout = 1;
519 		break;
520 	case P2PS_SETUP_CLIENT | P2PS_SETUP_GROUP_OWNER:
521 		group_id = 1;
522 		intended_addr = 1;
523 		operating_channel = 1;
524 		channel_list = 1;
525 		config_timeout = 1;
526 		break;
527 	default:
528 		p2p_dbg(p2p, "Invalid P2PS PD connection capability");
529 		return -1;
530 	}
531 
532 	if (msg->persistent_dev) {
533 		channel_list = 1;
534 		config_timeout = 1;
535 		if (os_memcmp(msg->persistent_dev, addr, ETH_ALEN) == 0) {
536 			intended_addr = 1;
537 			operating_channel = 1;
538 		}
539 	}
540 
541 	P2PS_PD_REQ_CHECK(group_id, group_id);
542 	P2PS_PD_REQ_CHECK(intended_addr, intended_addr);
543 	P2PS_PD_REQ_CHECK(operating_channel, operating_channel);
544 	P2PS_PD_REQ_CHECK(channel_list, channel_list);
545 	P2PS_PD_REQ_CHECK(config_timeout, config_timeout);
546 	P2PS_PD_REQ_CHECK(listen_channel, listen_channel);
547 
548 #undef P2PS_PD_REQ_CHECK
549 
550 	return 0;
551 }
552 
553 
p2p_process_prov_disc_req(struct p2p_data * p2p,const u8 * sa,const u8 * data,size_t len,int rx_freq)554 void p2p_process_prov_disc_req(struct p2p_data *p2p, const u8 *sa,
555 			       const u8 *data, size_t len, int rx_freq)
556 {
557 	struct p2p_message msg;
558 	struct p2p_device *dev;
559 	int freq;
560 	enum p2p_status_code reject = P2P_SC_FAIL_INCOMPATIBLE_PARAMS;
561 	struct wpabuf *resp;
562 	u32 adv_id = 0;
563 	struct p2ps_advertisement *p2ps_adv = NULL;
564 	u8 conncap = P2PS_SETUP_NEW;
565 	u8 auto_accept = 0;
566 	u32 session_id = 0;
567 	u8 session_mac[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 };
568 	u8 adv_mac[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 };
569 	const u8 *group_mac;
570 	int passwd_id = DEV_PW_DEFAULT;
571 	u16 config_methods;
572 	u16 allowed_config_methods = WPS_CONFIG_DISPLAY | WPS_CONFIG_KEYPAD;
573 	struct p2ps_feature_capab resp_fcap = { 0, 0 };
574 	struct p2ps_feature_capab *req_fcap = NULL;
575 	u8 remote_conncap;
576 	u16 method;
577 
578 	if (p2p_parse(data, len, &msg))
579 		return;
580 
581 	p2p_dbg(p2p, "Received Provision Discovery Request from " MACSTR
582 		" with config methods 0x%x (freq=%d)",
583 		MAC2STR(sa), msg.wps_config_methods, rx_freq);
584 	group_mac = msg.intended_addr;
585 
586 	dev = p2p_get_device(p2p, sa);
587 	if (dev == NULL || (dev->flags & P2P_DEV_PROBE_REQ_ONLY)) {
588 		p2p_dbg(p2p, "Provision Discovery Request from unknown peer "
589 			MACSTR, MAC2STR(sa));
590 
591 		if (p2p_add_device(p2p, sa, rx_freq, NULL, 0, data + 1, len - 1,
592 				   0)) {
593 			p2p_dbg(p2p, "Provision Discovery Request add device failed "
594 				MACSTR, MAC2STR(sa));
595 			goto out;
596 		}
597 
598 		if (!dev) {
599 			dev = p2p_get_device(p2p, sa);
600 			if (!dev) {
601 				p2p_dbg(p2p,
602 					"Provision Discovery device not found "
603 					MACSTR, MAC2STR(sa));
604 				goto out;
605 			}
606 		}
607 	} else if (msg.wfd_subelems) {
608 		wpabuf_free(dev->info.wfd_subelems);
609 		dev->info.wfd_subelems = wpabuf_dup(msg.wfd_subelems);
610 	}
611 
612 	if (!msg.adv_id) {
613 		allowed_config_methods |= WPS_CONFIG_PUSHBUTTON;
614 		if (!(msg.wps_config_methods & allowed_config_methods)) {
615 			p2p_dbg(p2p,
616 				"Unsupported Config Methods in Provision Discovery Request");
617 			goto out;
618 		}
619 
620 		/* Legacy (non-P2PS) - Unknown groups allowed for P2PS */
621 		if (msg.group_id) {
622 			size_t i;
623 
624 			for (i = 0; i < p2p->num_groups; i++) {
625 				if (p2p_group_is_group_id_match(
626 					    p2p->groups[i],
627 					    msg.group_id, msg.group_id_len))
628 					break;
629 			}
630 			if (i == p2p->num_groups) {
631 				p2p_dbg(p2p,
632 					"PD request for unknown P2P Group ID - reject");
633 				goto out;
634 			}
635 		}
636 	} else {
637 		allowed_config_methods |= WPS_CONFIG_P2PS;
638 
639 		/*
640 		 * Set adv_id here, so in case of an error, a P2PS PD Response
641 		 * will be sent.
642 		 */
643 		adv_id = WPA_GET_LE32(msg.adv_id);
644 		if (p2ps_validate_pd_req(p2p, &msg, sa) < 0) {
645 			reject = P2P_SC_FAIL_INVALID_PARAMS;
646 			goto out;
647 		}
648 
649 		req_fcap = (struct p2ps_feature_capab *) msg.feature_cap;
650 
651 		os_memcpy(session_mac, msg.session_mac, ETH_ALEN);
652 		os_memcpy(adv_mac, msg.adv_mac, ETH_ALEN);
653 
654 		session_id = WPA_GET_LE32(msg.session_id);
655 
656 		if (msg.conn_cap)
657 			conncap = *msg.conn_cap;
658 
659 		/*
660 		 * We need to verify a P2PS config methog in an initial PD
661 		 * request or in a follow-on PD request with the status
662 		 * SUCCESS_DEFERRED.
663 		 */
664 		if ((!msg.status || *msg.status == P2P_SC_SUCCESS_DEFERRED) &&
665 		    !(msg.wps_config_methods & allowed_config_methods)) {
666 			p2p_dbg(p2p,
667 				"Unsupported Config Methods in Provision Discovery Request");
668 			goto out;
669 		}
670 
671 		/*
672 		 * TODO: since we don't support multiple PD, reject PD request
673 		 * if we are in the middle of P2PS PD with some other peer
674 		 */
675 	}
676 
677 	dev->flags &= ~(P2P_DEV_PD_PEER_DISPLAY |
678 			P2P_DEV_PD_PEER_KEYPAD |
679 			P2P_DEV_PD_PEER_P2PS);
680 
681 	if (msg.wps_config_methods & WPS_CONFIG_DISPLAY) {
682 		p2p_dbg(p2p, "Peer " MACSTR
683 			" requested us to show a PIN on display", MAC2STR(sa));
684 		dev->flags |= P2P_DEV_PD_PEER_KEYPAD;
685 		passwd_id = DEV_PW_USER_SPECIFIED;
686 	} else if (msg.wps_config_methods & WPS_CONFIG_KEYPAD) {
687 		p2p_dbg(p2p, "Peer " MACSTR
688 			" requested us to write its PIN using keypad",
689 			MAC2STR(sa));
690 		dev->flags |= P2P_DEV_PD_PEER_DISPLAY;
691 		passwd_id = DEV_PW_REGISTRAR_SPECIFIED;
692 	} else if (msg.wps_config_methods & WPS_CONFIG_P2PS) {
693 		p2p_dbg(p2p, "Peer " MACSTR " requesting P2PS PIN",
694 			MAC2STR(sa));
695 		dev->flags |= P2P_DEV_PD_PEER_P2PS;
696 		passwd_id = DEV_PW_P2PS_DEFAULT;
697 	}
698 
699 	/* Remove stale persistent groups */
700 	if (p2p->cfg->remove_stale_groups) {
701 		p2p->cfg->remove_stale_groups(
702 			p2p->cfg->cb_ctx, dev->info.p2p_device_addr,
703 			msg.persistent_dev,
704 			msg.persistent_ssid, msg.persistent_ssid_len);
705 	}
706 
707 	reject = P2P_SC_SUCCESS;
708 
709 	/*
710 	 * End of a legacy P2P PD Request processing, from this point continue
711 	 * with P2PS one.
712 	 */
713 	if (!msg.adv_id)
714 		goto out;
715 
716 	remote_conncap = conncap;
717 
718 	if (!msg.status) {
719 		unsigned int forced_freq, pref_freq;
720 
721 		if (os_memcmp(p2p->cfg->dev_addr, msg.adv_mac, ETH_ALEN)) {
722 			p2p_dbg(p2p,
723 				"P2PS PD adv mac does not match the local one");
724 			reject = P2P_SC_FAIL_INCOMPATIBLE_PARAMS;
725 			goto out;
726 		}
727 
728 		p2ps_adv = p2p_service_p2ps_id(p2p, adv_id);
729 		if (!p2ps_adv) {
730 			p2p_dbg(p2p, "P2PS PD invalid adv_id=0x%X", adv_id);
731 			reject = P2P_SC_FAIL_INCOMPATIBLE_PARAMS;
732 			goto out;
733 		}
734 		p2p_dbg(p2p, "adv_id: 0x%X, p2ps_adv: %p", adv_id, p2ps_adv);
735 
736 		auto_accept = p2ps_adv->auto_accept;
737 		conncap = p2p->cfg->p2ps_group_capability(p2p->cfg->cb_ctx,
738 							  conncap, auto_accept,
739 							  &forced_freq,
740 							  &pref_freq);
741 
742 		p2p_dbg(p2p, "Conncap: local:%d remote:%d result:%d",
743 			auto_accept, remote_conncap, conncap);
744 
745 		p2p_prepare_channel(p2p, dev, forced_freq, pref_freq, 0);
746 
747 		resp_fcap.cpt = p2ps_own_preferred_cpt(p2ps_adv->cpt_priority,
748 						       req_fcap->cpt);
749 
750 		p2p_dbg(p2p, "cpt: service:0x%x remote:0x%x result:0x%x",
751 			p2ps_adv->cpt_mask, req_fcap->cpt, resp_fcap.cpt);
752 
753 		if (!resp_fcap.cpt) {
754 			p2p_dbg(p2p,
755 				"Incompatible P2PS feature capability CPT bitmask");
756 			reject = P2P_SC_FAIL_INCOMPATIBLE_PARAMS;
757 		} else if (p2ps_adv->config_methods &&
758 			   !(msg.wps_config_methods &
759 			     p2ps_adv->config_methods)) {
760 			p2p_dbg(p2p,
761 				"Unsupported config methods in Provision Discovery Request (own=0x%x peer=0x%x)",
762 				p2ps_adv->config_methods,
763 				msg.wps_config_methods);
764 			reject = P2P_SC_FAIL_INCOMPATIBLE_PARAMS;
765 		} else if (!p2ps_adv->state) {
766 			p2p_dbg(p2p, "P2PS state unavailable");
767 			reject = P2P_SC_FAIL_UNABLE_TO_ACCOMMODATE;
768 		} else if (!conncap) {
769 			p2p_dbg(p2p, "Conncap resolution failed");
770 			reject = P2P_SC_FAIL_INCOMPATIBLE_PARAMS;
771 		}
772 
773 		if (msg.wps_config_methods & WPS_CONFIG_KEYPAD) {
774 			p2p_dbg(p2p, "Keypad - always defer");
775 			auto_accept = 0;
776 		}
777 
778 		if ((remote_conncap & (P2PS_SETUP_NEW | P2PS_SETUP_CLIENT) ||
779 		     msg.persistent_dev) && conncap != P2PS_SETUP_NEW &&
780 		    msg.channel_list && msg.channel_list_len &&
781 		    p2p_peer_channels_check(p2p, &p2p->channels, dev,
782 					    msg.channel_list,
783 					    msg.channel_list_len) < 0) {
784 			p2p_dbg(p2p,
785 				"No common channels - force deferred flow");
786 			auto_accept = 0;
787 		}
788 
789 		if (((remote_conncap & P2PS_SETUP_GROUP_OWNER) ||
790 		     msg.persistent_dev) && msg.operating_channel) {
791 			struct p2p_channels intersect;
792 
793 			/*
794 			 * There are cases where only the operating channel is
795 			 * provided. This requires saving the channel as the
796 			 * supported channel list, and verifying that it is
797 			 * supported.
798 			 */
799 			if (dev->channels.reg_classes == 0 ||
800 			    !p2p_channels_includes(&dev->channels,
801 						   msg.operating_channel[3],
802 						   msg.operating_channel[4])) {
803 				struct p2p_channels *ch = &dev->channels;
804 
805 				os_memset(ch, 0, sizeof(*ch));
806 				ch->reg_class[0].reg_class =
807 					msg.operating_channel[3];
808 				ch->reg_class[0].channel[0] =
809 					msg.operating_channel[4];
810 				ch->reg_class[0].channels = 1;
811 				ch->reg_classes = 1;
812 			}
813 
814 			p2p_channels_intersect(&p2p->channels, &dev->channels,
815 					       &intersect);
816 
817 			if (intersect.reg_classes == 0) {
818 				p2p_dbg(p2p,
819 					"No common channels - force deferred flow");
820 				auto_accept = 0;
821 			}
822 		}
823 
824 		if (auto_accept || reject != P2P_SC_SUCCESS) {
825 			struct p2ps_provision *tmp;
826 
827 			if (p2ps_setup_p2ps_prov(p2p, adv_id, session_id,
828 						 msg.wps_config_methods,
829 						 session_mac, adv_mac) < 0) {
830 				reject = P2P_SC_FAIL_UNABLE_TO_ACCOMMODATE;
831 				goto out;
832 			}
833 
834 			tmp = p2p->p2ps_prov;
835 			tmp->force_freq = forced_freq;
836 			tmp->pref_freq = pref_freq;
837 			if (conncap) {
838 				tmp->conncap = conncap;
839 				tmp->status = P2P_SC_SUCCESS;
840 			} else {
841 				tmp->conncap = auto_accept;
842 				tmp->status = P2P_SC_FAIL_INCOMPATIBLE_PARAMS;
843 			}
844 
845 			if (reject != P2P_SC_SUCCESS)
846 				goto out;
847 		}
848 	}
849 
850 	if (!msg.status && !auto_accept &&
851 	    (!p2p->p2ps_prov || p2p->p2ps_prov->adv_id != adv_id)) {
852 		struct p2ps_provision *tmp;
853 
854 		if (!conncap) {
855 			reject = P2P_SC_FAIL_INCOMPATIBLE_PARAMS;
856 			goto out;
857 		}
858 
859 		if (p2ps_setup_p2ps_prov(p2p, adv_id, session_id,
860 					 msg.wps_config_methods,
861 					 session_mac, adv_mac) < 0) {
862 			reject = P2P_SC_FAIL_UNABLE_TO_ACCOMMODATE;
863 			goto out;
864 		}
865 		tmp = p2p->p2ps_prov;
866 		reject = P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE;
867 		tmp->status = reject;
868 	}
869 
870 	/* Not a P2PS Follow-on PD */
871 	if (!msg.status)
872 		goto out;
873 
874 	if (*msg.status && *msg.status != P2P_SC_SUCCESS_DEFERRED) {
875 		reject = *msg.status;
876 		goto out;
877 	}
878 
879 	if (*msg.status != P2P_SC_SUCCESS_DEFERRED || !p2p->p2ps_prov)
880 		goto out;
881 
882 	if (p2p->p2ps_prov->adv_id != adv_id ||
883 	    os_memcmp(p2p->p2ps_prov->adv_mac, msg.adv_mac, ETH_ALEN)) {
884 		p2p_dbg(p2p,
885 			"P2PS Follow-on PD with mismatch Advertisement ID/MAC");
886 		goto out;
887 	}
888 
889 	if (p2p->p2ps_prov->session_id != session_id ||
890 	    os_memcmp(p2p->p2ps_prov->session_mac, msg.session_mac, ETH_ALEN)) {
891 		p2p_dbg(p2p, "P2PS Follow-on PD with mismatch Session ID/MAC");
892 		goto out;
893 	}
894 
895 	method = p2p->p2ps_prov->method;
896 
897 	conncap = p2p->cfg->p2ps_group_capability(p2p->cfg->cb_ctx,
898 						  remote_conncap,
899 						  p2p->p2ps_prov->conncap,
900 						  &p2p->p2ps_prov->force_freq,
901 						  &p2p->p2ps_prov->pref_freq);
902 
903 	resp_fcap.cpt = p2ps_own_preferred_cpt(p2p->p2ps_prov->cpt_priority,
904 					       req_fcap->cpt);
905 
906 	p2p_dbg(p2p, "cpt: local:0x%x remote:0x%x result:0x%x",
907 		p2p->p2ps_prov->cpt_mask, req_fcap->cpt, resp_fcap.cpt);
908 
909 	p2p_prepare_channel(p2p, dev, p2p->p2ps_prov->force_freq,
910 			    p2p->p2ps_prov->pref_freq, 0);
911 
912 	/*
913 	 * Ensure that if we asked for PIN originally, our method is consistent
914 	 * with original request.
915 	 */
916 	if (method & WPS_CONFIG_DISPLAY)
917 		method = WPS_CONFIG_KEYPAD;
918 	else if (method & WPS_CONFIG_KEYPAD)
919 		method = WPS_CONFIG_DISPLAY;
920 
921 	if (!conncap || !(msg.wps_config_methods & method)) {
922 		/*
923 		 * Reject this "Deferred Accept*
924 		 * if incompatible conncap or method
925 		 */
926 		reject = P2P_SC_FAIL_INCOMPATIBLE_PARAMS;
927 	} else if (!resp_fcap.cpt) {
928 		p2p_dbg(p2p,
929 			"Incompatible P2PS feature capability CPT bitmask");
930 		reject = P2P_SC_FAIL_INCOMPATIBLE_PARAMS;
931 	} else if ((remote_conncap & (P2PS_SETUP_NEW | P2PS_SETUP_CLIENT) ||
932 		    msg.persistent_dev) && conncap != P2PS_SETUP_NEW &&
933 		   msg.channel_list && msg.channel_list_len &&
934 		   p2p_peer_channels_check(p2p, &p2p->channels, dev,
935 					   msg.channel_list,
936 					   msg.channel_list_len) < 0) {
937 		p2p_dbg(p2p,
938 			"No common channels in Follow-On Provision Discovery Request");
939 		reject = P2P_SC_FAIL_NO_COMMON_CHANNELS;
940 	} else {
941 		reject = P2P_SC_SUCCESS;
942 	}
943 
944 	dev->oper_freq = 0;
945 	if (reject == P2P_SC_SUCCESS || reject == P2P_SC_SUCCESS_DEFERRED) {
946 		u8 tmp;
947 
948 		if (msg.operating_channel)
949 			dev->oper_freq =
950 				p2p_channel_to_freq(msg.operating_channel[3],
951 						    msg.operating_channel[4]);
952 
953 		if ((conncap & P2PS_SETUP_GROUP_OWNER) &&
954 		    p2p_go_select_channel(p2p, dev, &tmp) < 0)
955 			reject = P2P_SC_FAIL_NO_COMMON_CHANNELS;
956 	}
957 
958 	p2p->p2ps_prov->status = reject;
959 	p2p->p2ps_prov->conncap = conncap;
960 
961 out:
962 	if (reject == P2P_SC_SUCCESS ||
963 	    reject == P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE)
964 		config_methods = msg.wps_config_methods;
965 	else
966 		config_methods = 0;
967 
968 	/*
969 	 * Send PD Response for an initial PD Request or for follow-on
970 	 * PD Request with P2P_SC_SUCCESS_DEFERRED status.
971 	 */
972 	if (!msg.status || *msg.status == P2P_SC_SUCCESS_DEFERRED) {
973 		resp = p2p_build_prov_disc_resp(p2p, dev, msg.dialog_token,
974 						reject, config_methods, adv_id,
975 						msg.group_id, msg.group_id_len,
976 						msg.persistent_ssid,
977 						msg.persistent_ssid_len,
978 						(const u8 *) &resp_fcap,
979 						sizeof(resp_fcap));
980 		if (!resp) {
981 			p2p_parse_free(&msg);
982 			return;
983 		}
984 		p2p_dbg(p2p, "Sending Provision Discovery Response");
985 		if (rx_freq > 0)
986 			freq = rx_freq;
987 		else
988 			freq = p2p_channel_to_freq(p2p->cfg->reg_class,
989 						   p2p->cfg->channel);
990 		if (freq < 0) {
991 			p2p_dbg(p2p, "Unknown regulatory class/channel");
992 			wpabuf_free(resp);
993 			p2p_parse_free(&msg);
994 			return;
995 		}
996 		p2p->pending_action_state = P2P_PENDING_PD_RESPONSE;
997 		if (p2p_send_action(p2p, freq, sa, p2p->cfg->dev_addr,
998 				    p2p->cfg->dev_addr,
999 				    wpabuf_head(resp), wpabuf_len(resp),
1000 				    50) < 0)
1001 			p2p_dbg(p2p, "Failed to send Action frame");
1002 		else
1003 			p2p->send_action_in_progress = 1;
1004 
1005 		wpabuf_free(resp);
1006 	}
1007 
1008 	if (!dev) {
1009 		p2p_parse_free(&msg);
1010 		return;
1011 	}
1012 
1013 	freq = 0;
1014 	if (reject == P2P_SC_SUCCESS && conncap == P2PS_SETUP_GROUP_OWNER) {
1015 		freq = p2p_channel_to_freq(p2p->op_reg_class,
1016 					   p2p->op_channel);
1017 		if (freq < 0)
1018 			freq = 0;
1019 	}
1020 
1021 	if (!p2p->cfg->p2ps_prov_complete) {
1022 		/* Don't emit anything */
1023 	} else if (msg.status && *msg.status != P2P_SC_SUCCESS &&
1024 		   *msg.status != P2P_SC_SUCCESS_DEFERRED) {
1025 		reject = *msg.status;
1026 		p2p->cfg->p2ps_prov_complete(p2p->cfg->cb_ctx, reject,
1027 					     sa, adv_mac, session_mac,
1028 					     NULL, adv_id, session_id,
1029 					     0, 0, msg.persistent_ssid,
1030 					     msg.persistent_ssid_len,
1031 					     0, 0, NULL, NULL, 0, freq,
1032 					     NULL, 0);
1033 	} else if (msg.status && *msg.status == P2P_SC_SUCCESS_DEFERRED &&
1034 		   p2p->p2ps_prov) {
1035 		p2p->p2ps_prov->status = reject;
1036 		p2p->p2ps_prov->conncap = conncap;
1037 
1038 		if (reject != P2P_SC_SUCCESS)
1039 			p2p->cfg->p2ps_prov_complete(p2p->cfg->cb_ctx, reject,
1040 						     sa, adv_mac, session_mac,
1041 						     NULL, adv_id,
1042 						     session_id, conncap, 0,
1043 						     msg.persistent_ssid,
1044 						     msg.persistent_ssid_len, 0,
1045 						     0, NULL, NULL, 0, freq,
1046 						     NULL, 0);
1047 		else
1048 			p2p->cfg->p2ps_prov_complete(p2p->cfg->cb_ctx,
1049 						     *msg.status,
1050 						     sa, adv_mac, session_mac,
1051 						     group_mac, adv_id,
1052 						     session_id, conncap,
1053 						     passwd_id,
1054 						     msg.persistent_ssid,
1055 						     msg.persistent_ssid_len, 0,
1056 						     0, NULL,
1057 						     (const u8 *) &resp_fcap,
1058 						     sizeof(resp_fcap), freq,
1059 						     NULL, 0);
1060 	} else if (msg.status && p2p->p2ps_prov) {
1061 		p2p->p2ps_prov->status = P2P_SC_SUCCESS;
1062 		p2p->cfg->p2ps_prov_complete(p2p->cfg->cb_ctx, *msg.status, sa,
1063 					     adv_mac, session_mac, group_mac,
1064 					     adv_id, session_id, conncap,
1065 					     passwd_id,
1066 					     msg.persistent_ssid,
1067 					     msg.persistent_ssid_len,
1068 					     0, 0, NULL,
1069 					     (const u8 *) &resp_fcap,
1070 					     sizeof(resp_fcap), freq, NULL, 0);
1071 	} else if (msg.status) {
1072 	} else if (auto_accept && reject == P2P_SC_SUCCESS) {
1073 		p2p->cfg->p2ps_prov_complete(p2p->cfg->cb_ctx, P2P_SC_SUCCESS,
1074 					     sa, adv_mac, session_mac,
1075 					     group_mac, adv_id, session_id,
1076 					     conncap, passwd_id,
1077 					     msg.persistent_ssid,
1078 					     msg.persistent_ssid_len,
1079 					     0, 0, NULL,
1080 					     (const u8 *) &resp_fcap,
1081 					     sizeof(resp_fcap), freq,
1082 					     msg.group_id ?
1083 					     msg.group_id + ETH_ALEN : NULL,
1084 					     msg.group_id ?
1085 					     msg.group_id_len - ETH_ALEN : 0);
1086 	} else if (reject == P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE &&
1087 		   (!msg.session_info || !msg.session_info_len)) {
1088 		p2p->p2ps_prov->method = msg.wps_config_methods;
1089 
1090 		p2p->cfg->p2ps_prov_complete(p2p->cfg->cb_ctx, P2P_SC_SUCCESS,
1091 					     sa, adv_mac, session_mac,
1092 					     group_mac, adv_id, session_id,
1093 					     conncap, passwd_id,
1094 					     msg.persistent_ssid,
1095 					     msg.persistent_ssid_len,
1096 					     0, 1, NULL,
1097 					     (const u8 *) &resp_fcap,
1098 					     sizeof(resp_fcap), freq, NULL, 0);
1099 	} else if (reject == P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE) {
1100 		size_t buf_len = msg.session_info_len;
1101 		char *buf = os_malloc(2 * buf_len + 1);
1102 
1103 		if (buf) {
1104 			p2p->p2ps_prov->method = msg.wps_config_methods;
1105 
1106 			utf8_escape((char *) msg.session_info, buf_len,
1107 				    buf, 2 * buf_len + 1);
1108 
1109 			p2p->cfg->p2ps_prov_complete(
1110 				p2p->cfg->cb_ctx, P2P_SC_SUCCESS, sa,
1111 				adv_mac, session_mac, group_mac, adv_id,
1112 				session_id, conncap, passwd_id,
1113 				msg.persistent_ssid, msg.persistent_ssid_len,
1114 				0, 1, buf,
1115 				(const u8 *) &resp_fcap, sizeof(resp_fcap),
1116 				freq, NULL, 0);
1117 
1118 			os_free(buf);
1119 		}
1120 	}
1121 
1122 	/*
1123 	 * prov_disc_req callback is used to generate P2P-PROV-DISC-ENTER-PIN,
1124 	 * P2P-PROV-DISC-SHOW-PIN, and P2P-PROV-DISC-PBC-REQ events.
1125 	 * Call it either on legacy P2P PD or on P2PS PD only if we need to
1126 	 * enter/show PIN.
1127 	 *
1128 	 * The callback is called in the following cases:
1129 	 * 1. Legacy P2P PD request, response status SUCCESS
1130 	 * 2. P2PS advertiser, method: DISPLAY, autoaccept: TRUE,
1131 	 *    response status: SUCCESS
1132 	 * 3. P2PS advertiser, method  DISPLAY, autoaccept: FALSE,
1133 	 *    response status: INFO_CURRENTLY_UNAVAILABLE
1134 	 * 4. P2PS advertiser, method: KEYPAD, autoaccept==any,
1135 	 *    response status: INFO_CURRENTLY_UNAVAILABLE
1136 	 * 5. P2PS follow-on with SUCCESS_DEFERRED,
1137 	 *    advertiser role: DISPLAY, autoaccept: FALSE,
1138 	 *    seeker: KEYPAD, response status: SUCCESS
1139 	 */
1140 	if (p2p->cfg->prov_disc_req &&
1141 	    ((reject == P2P_SC_SUCCESS && !msg.adv_id) ||
1142 	     (!msg.status &&
1143 	     (reject == P2P_SC_SUCCESS ||
1144 	      reject == P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE) &&
1145 	      passwd_id == DEV_PW_USER_SPECIFIED) ||
1146 	     (!msg.status &&
1147 	      reject == P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE &&
1148 	      passwd_id == DEV_PW_REGISTRAR_SPECIFIED) ||
1149 	     (reject == P2P_SC_SUCCESS &&
1150 	      msg.status && *msg.status == P2P_SC_SUCCESS_DEFERRED &&
1151 	       passwd_id == DEV_PW_REGISTRAR_SPECIFIED))) {
1152 		const u8 *dev_addr = sa;
1153 
1154 		if (msg.p2p_device_addr)
1155 			dev_addr = msg.p2p_device_addr;
1156 		p2p->cfg->prov_disc_req(p2p->cfg->cb_ctx, sa,
1157 					msg.wps_config_methods,
1158 					dev_addr, msg.pri_dev_type,
1159 					msg.device_name, msg.config_methods,
1160 					msg.capability ? msg.capability[0] : 0,
1161 					msg.capability ? msg.capability[1] :
1162 					0,
1163 					msg.group_id, msg.group_id_len);
1164 	}
1165 
1166 	if (reject != P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE)
1167 		p2ps_prov_free(p2p);
1168 
1169 	if (reject == P2P_SC_SUCCESS) {
1170 		switch (config_methods) {
1171 		case WPS_CONFIG_DISPLAY:
1172 			dev->wps_prov_info = WPS_CONFIG_KEYPAD;
1173 			break;
1174 		case WPS_CONFIG_KEYPAD:
1175 			dev->wps_prov_info = WPS_CONFIG_DISPLAY;
1176 			break;
1177 		case WPS_CONFIG_PUSHBUTTON:
1178 			dev->wps_prov_info = WPS_CONFIG_PUSHBUTTON;
1179 			break;
1180 		case WPS_CONFIG_P2PS:
1181 			dev->wps_prov_info = WPS_CONFIG_P2PS;
1182 			break;
1183 		default:
1184 			dev->wps_prov_info = 0;
1185 			break;
1186 		}
1187 
1188 		if (msg.intended_addr)
1189 			os_memcpy(dev->interface_addr, msg.intended_addr,
1190 				  ETH_ALEN);
1191 	}
1192 	p2p_parse_free(&msg);
1193 }
1194 
1195 
p2p_validate_p2ps_pd_resp(struct p2p_data * p2p,struct p2p_message * msg)1196 static int p2p_validate_p2ps_pd_resp(struct p2p_data *p2p,
1197 				     struct p2p_message *msg)
1198 {
1199 	u8 conn_cap_go = 0;
1200 	u8 conn_cap_cli = 0;
1201 	u32 session_id;
1202 	u32 adv_id;
1203 
1204 #define P2PS_PD_RESP_CHECK(_val, _attr) \
1205 	do { \
1206 		if ((_val) && !msg->_attr) { \
1207 			p2p_dbg(p2p, "P2PS PD Response missing " #_attr); \
1208 			return -1; \
1209 		} \
1210 	} while (0)
1211 
1212 	P2PS_PD_RESP_CHECK(1, status);
1213 	P2PS_PD_RESP_CHECK(1, adv_id);
1214 	P2PS_PD_RESP_CHECK(1, adv_mac);
1215 	P2PS_PD_RESP_CHECK(1, capability);
1216 	P2PS_PD_RESP_CHECK(1, p2p_device_info);
1217 	P2PS_PD_RESP_CHECK(1, session_id);
1218 	P2PS_PD_RESP_CHECK(1, session_mac);
1219 	P2PS_PD_RESP_CHECK(1, feature_cap);
1220 
1221 	session_id = WPA_GET_LE32(msg->session_id);
1222 	adv_id = WPA_GET_LE32(msg->adv_id);
1223 
1224 	if (p2p->p2ps_prov->session_id != session_id) {
1225 		p2p_dbg(p2p,
1226 			"Ignore PD Response with unexpected Session ID");
1227 		return -1;
1228 	}
1229 
1230 	if (os_memcmp(p2p->p2ps_prov->session_mac, msg->session_mac,
1231 		      ETH_ALEN)) {
1232 		p2p_dbg(p2p,
1233 			"Ignore PD Response with unexpected Session MAC");
1234 		return -1;
1235 	}
1236 
1237 	if (p2p->p2ps_prov->adv_id != adv_id) {
1238 		p2p_dbg(p2p,
1239 			"Ignore PD Response with unexpected Advertisement ID");
1240 		return -1;
1241 	}
1242 
1243 	if (os_memcmp(p2p->p2ps_prov->adv_mac, msg->adv_mac, ETH_ALEN) != 0) {
1244 		p2p_dbg(p2p,
1245 			"Ignore PD Response with unexpected Advertisement MAC");
1246 		return -1;
1247 	}
1248 
1249 	if (msg->listen_channel) {
1250 		p2p_dbg(p2p,
1251 			"Ignore malformed PD Response - unexpected Listen Channel");
1252 		return -1;
1253 	}
1254 
1255 	if (*msg->status == P2P_SC_SUCCESS &&
1256 	    !(!!msg->conn_cap ^ !!msg->persistent_dev)) {
1257 		p2p_dbg(p2p,
1258 			"Ignore malformed PD Response - either conn_cap or persistent group should be present");
1259 		return -1;
1260 	}
1261 
1262 	if (msg->persistent_dev && *msg->status != P2P_SC_SUCCESS) {
1263 		p2p_dbg(p2p,
1264 			"Ignore malformed PD Response - persistent group is present, but the status isn't success");
1265 		return -1;
1266 	}
1267 
1268 	if (msg->conn_cap) {
1269 		conn_cap_go = *msg->conn_cap == P2PS_SETUP_GROUP_OWNER;
1270 		conn_cap_cli = *msg->conn_cap == P2PS_SETUP_CLIENT;
1271 	}
1272 
1273 	P2PS_PD_RESP_CHECK(msg->persistent_dev || conn_cap_go || conn_cap_cli,
1274 			   channel_list);
1275 	P2PS_PD_RESP_CHECK(msg->persistent_dev || conn_cap_go || conn_cap_cli,
1276 			   config_timeout);
1277 
1278 	P2PS_PD_RESP_CHECK(conn_cap_go, group_id);
1279 	P2PS_PD_RESP_CHECK(conn_cap_go, intended_addr);
1280 	P2PS_PD_RESP_CHECK(conn_cap_go, operating_channel);
1281 	/*
1282 	 * TODO: Also validate that operating channel is present if the device
1283 	 * is a GO in a persistent group. We can't do it here since we don't
1284 	 * know what is the role of the peer. It should be probably done in
1285 	 * p2ps_prov_complete callback, but currently operating channel isn't
1286 	 * passed to it.
1287 	 */
1288 
1289 #undef P2PS_PD_RESP_CHECK
1290 
1291 	return 0;
1292 }
1293 
1294 
p2p_process_prov_disc_resp(struct p2p_data * p2p,const u8 * sa,const u8 * data,size_t len)1295 void p2p_process_prov_disc_resp(struct p2p_data *p2p, const u8 *sa,
1296 				const u8 *data, size_t len)
1297 {
1298 	struct p2p_message msg;
1299 	struct p2p_device *dev;
1300 	u16 report_config_methods = 0, req_config_methods;
1301 	u8 status = P2P_SC_SUCCESS;
1302 	u32 adv_id = 0;
1303 	u8 conncap = P2PS_SETUP_NEW;
1304 	u8 adv_mac[ETH_ALEN];
1305 	const u8 *group_mac;
1306 	int passwd_id = DEV_PW_DEFAULT;
1307 	int p2ps_seeker;
1308 
1309 	if (p2p_parse(data, len, &msg))
1310 		return;
1311 
1312 	if (p2p->p2ps_prov && p2p_validate_p2ps_pd_resp(p2p, &msg)) {
1313 		p2p_parse_free(&msg);
1314 		return;
1315 	}
1316 
1317 	/* Parse the P2PS members present */
1318 	if (msg.status)
1319 		status = *msg.status;
1320 
1321 	group_mac = msg.intended_addr;
1322 
1323 	if (msg.adv_mac)
1324 		os_memcpy(adv_mac, msg.adv_mac, ETH_ALEN);
1325 	else
1326 		os_memset(adv_mac, 0, ETH_ALEN);
1327 
1328 	if (msg.adv_id)
1329 		adv_id = WPA_GET_LE32(msg.adv_id);
1330 
1331 	if (msg.conn_cap) {
1332 		conncap = *msg.conn_cap;
1333 
1334 		/* Switch bits to local relative */
1335 		switch (conncap) {
1336 		case P2PS_SETUP_GROUP_OWNER:
1337 			conncap = P2PS_SETUP_CLIENT;
1338 			break;
1339 		case P2PS_SETUP_CLIENT:
1340 			conncap = P2PS_SETUP_GROUP_OWNER;
1341 			break;
1342 		}
1343 	}
1344 
1345 	p2p_dbg(p2p, "Received Provision Discovery Response from " MACSTR
1346 		" with config methods 0x%x",
1347 		MAC2STR(sa), msg.wps_config_methods);
1348 
1349 	dev = p2p_get_device(p2p, sa);
1350 	if (dev == NULL || !dev->req_config_methods) {
1351 		p2p_dbg(p2p, "Ignore Provision Discovery Response from " MACSTR
1352 			" with no pending request", MAC2STR(sa));
1353 		p2p_parse_free(&msg);
1354 		return;
1355 	} else if (msg.wfd_subelems) {
1356 		wpabuf_free(dev->info.wfd_subelems);
1357 		dev->info.wfd_subelems = wpabuf_dup(msg.wfd_subelems);
1358 	}
1359 
1360 	if (dev->dialog_token != msg.dialog_token) {
1361 		p2p_dbg(p2p, "Ignore Provision Discovery Response with unexpected Dialog Token %u (expected %u)",
1362 			msg.dialog_token, dev->dialog_token);
1363 		p2p_parse_free(&msg);
1364 		return;
1365 	}
1366 
1367 	if (p2p->pending_action_state == P2P_PENDING_PD) {
1368 		os_memset(p2p->pending_pd_devaddr, 0, ETH_ALEN);
1369 		p2p->pending_action_state = P2P_NO_PENDING_ACTION;
1370 	}
1371 
1372 	p2ps_seeker = p2p->p2ps_prov && p2p->p2ps_prov->pd_seeker;
1373 
1374 	/*
1375 	 * Use a local copy of the requested config methods since
1376 	 * p2p_reset_pending_pd() can clear this in the peer entry.
1377 	 */
1378 	req_config_methods = dev->req_config_methods;
1379 
1380 	/*
1381 	 * If the response is from the peer to whom a user initiated request
1382 	 * was sent earlier, we reset that state info here.
1383 	 */
1384 	if (p2p->user_initiated_pd &&
1385 	    os_memcmp(p2p->pending_pd_devaddr, sa, ETH_ALEN) == 0)
1386 		p2p_reset_pending_pd(p2p);
1387 
1388 	if (msg.wps_config_methods != req_config_methods) {
1389 		p2p_dbg(p2p, "Peer rejected our Provision Discovery Request (received config_methods 0x%x expected 0x%x",
1390 			msg.wps_config_methods, req_config_methods);
1391 		if (p2p->cfg->prov_disc_fail)
1392 			p2p->cfg->prov_disc_fail(p2p->cfg->cb_ctx, sa,
1393 						 P2P_PROV_DISC_REJECTED,
1394 						 adv_id, adv_mac, NULL);
1395 		p2p_parse_free(&msg);
1396 		p2ps_prov_free(p2p);
1397 		goto out;
1398 	}
1399 
1400 	report_config_methods = req_config_methods;
1401 	dev->flags &= ~(P2P_DEV_PD_PEER_DISPLAY |
1402 			P2P_DEV_PD_PEER_KEYPAD |
1403 			P2P_DEV_PD_PEER_P2PS);
1404 	if (req_config_methods & WPS_CONFIG_DISPLAY) {
1405 		p2p_dbg(p2p, "Peer " MACSTR
1406 			" accepted to show a PIN on display", MAC2STR(sa));
1407 		dev->flags |= P2P_DEV_PD_PEER_DISPLAY;
1408 		passwd_id = DEV_PW_REGISTRAR_SPECIFIED;
1409 	} else if (msg.wps_config_methods & WPS_CONFIG_KEYPAD) {
1410 		p2p_dbg(p2p, "Peer " MACSTR
1411 			" accepted to write our PIN using keypad",
1412 			MAC2STR(sa));
1413 		dev->flags |= P2P_DEV_PD_PEER_KEYPAD;
1414 		passwd_id = DEV_PW_USER_SPECIFIED;
1415 	} else if (msg.wps_config_methods & WPS_CONFIG_P2PS) {
1416 		p2p_dbg(p2p, "Peer " MACSTR " accepted P2PS PIN",
1417 			MAC2STR(sa));
1418 		dev->flags |= P2P_DEV_PD_PEER_P2PS;
1419 		passwd_id = DEV_PW_P2PS_DEFAULT;
1420 	}
1421 
1422 	if ((status == P2P_SC_SUCCESS || status == P2P_SC_SUCCESS_DEFERRED) &&
1423 	    p2p->p2ps_prov) {
1424 		dev->oper_freq = 0;
1425 
1426 		/*
1427 		 * Save the reported channel list and operating frequency.
1428 		 * Note that the specification mandates that the responder
1429 		 * should include in the channel list only channels reported by
1430 		 * the initiator, so this is only a sanity check, and if this
1431 		 * fails the flow would continue, although it would probably
1432 		 * fail. Same is true for the operating channel.
1433 		 */
1434 		if (msg.channel_list && msg.channel_list_len &&
1435 		    p2p_peer_channels_check(p2p, &p2p->channels, dev,
1436 					    msg.channel_list,
1437 					    msg.channel_list_len) < 0)
1438 			p2p_dbg(p2p, "P2PS PD Response - no common channels");
1439 
1440 		if (msg.operating_channel) {
1441 			if (p2p_channels_includes(&p2p->channels,
1442 						  msg.operating_channel[3],
1443 						  msg.operating_channel[4]) &&
1444 			    p2p_channels_includes(&dev->channels,
1445 						  msg.operating_channel[3],
1446 						  msg.operating_channel[4])) {
1447 				dev->oper_freq =
1448 					p2p_channel_to_freq(
1449 						msg.operating_channel[3],
1450 						msg.operating_channel[4]);
1451 			} else {
1452 				p2p_dbg(p2p,
1453 					"P2PS PD Response - invalid operating channel");
1454 			}
1455 		}
1456 
1457 		if (p2p->cfg->p2ps_prov_complete) {
1458 			int freq = 0;
1459 
1460 			if (conncap == P2PS_SETUP_GROUP_OWNER) {
1461 				u8 tmp;
1462 
1463 				/*
1464 				 * Re-select the operating channel as it is
1465 				 * possible that original channel is no longer
1466 				 * valid. This should not really fail.
1467 				 */
1468 				if (p2p_go_select_channel(p2p, dev, &tmp) < 0)
1469 					p2p_dbg(p2p,
1470 						"P2PS PD channel selection failed");
1471 
1472 				freq = p2p_channel_to_freq(p2p->op_reg_class,
1473 							   p2p->op_channel);
1474 				if (freq < 0)
1475 					freq = 0;
1476 			}
1477 
1478 			p2p->cfg->p2ps_prov_complete(
1479 				p2p->cfg->cb_ctx, status, sa, adv_mac,
1480 				p2p->p2ps_prov->session_mac,
1481 				group_mac, adv_id, p2p->p2ps_prov->session_id,
1482 				conncap, passwd_id, msg.persistent_ssid,
1483 				msg.persistent_ssid_len, 1, 0, NULL,
1484 				msg.feature_cap, msg.feature_cap_len, freq,
1485 				msg.group_id ? msg.group_id + ETH_ALEN : NULL,
1486 				msg.group_id ? msg.group_id_len - ETH_ALEN : 0);
1487 		}
1488 		p2ps_prov_free(p2p);
1489 	} else if (status != P2P_SC_SUCCESS &&
1490 		   status != P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE &&
1491 		   status != P2P_SC_SUCCESS_DEFERRED && p2p->p2ps_prov) {
1492 		if (p2p->cfg->p2ps_prov_complete)
1493 			p2p->cfg->p2ps_prov_complete(
1494 				p2p->cfg->cb_ctx, status, sa, adv_mac,
1495 				p2p->p2ps_prov->session_mac,
1496 				group_mac, adv_id, p2p->p2ps_prov->session_id,
1497 				0, 0, NULL, 0, 1, 0, NULL, NULL, 0, 0, NULL, 0);
1498 		p2ps_prov_free(p2p);
1499 	}
1500 
1501 	if (status == P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE) {
1502 		if (p2p->cfg->remove_stale_groups) {
1503 			p2p->cfg->remove_stale_groups(p2p->cfg->cb_ctx,
1504 						      dev->info.p2p_device_addr,
1505 						      NULL, NULL, 0);
1506 		}
1507 
1508 		if (msg.session_info && msg.session_info_len) {
1509 			size_t info_len = msg.session_info_len;
1510 			char *deferred_sess_resp = os_malloc(2 * info_len + 1);
1511 
1512 			if (!deferred_sess_resp) {
1513 				p2p_parse_free(&msg);
1514 				p2ps_prov_free(p2p);
1515 				goto out;
1516 			}
1517 			utf8_escape((char *) msg.session_info, info_len,
1518 				    deferred_sess_resp, 2 * info_len + 1);
1519 
1520 			if (p2p->cfg->prov_disc_fail)
1521 				p2p->cfg->prov_disc_fail(
1522 					p2p->cfg->cb_ctx, sa,
1523 					P2P_PROV_DISC_INFO_UNAVAILABLE,
1524 					adv_id, adv_mac,
1525 					deferred_sess_resp);
1526 			os_free(deferred_sess_resp);
1527 		} else
1528 			if (p2p->cfg->prov_disc_fail)
1529 				p2p->cfg->prov_disc_fail(
1530 					p2p->cfg->cb_ctx, sa,
1531 					P2P_PROV_DISC_INFO_UNAVAILABLE,
1532 					adv_id, adv_mac, NULL);
1533 	} else if (status != P2P_SC_SUCCESS) {
1534 		p2p_dbg(p2p, "Peer rejected our Provision Discovery Request");
1535 		if (p2p->cfg->prov_disc_fail)
1536 			p2p->cfg->prov_disc_fail(p2p->cfg->cb_ctx, sa,
1537 						 P2P_PROV_DISC_REJECTED,
1538 						 adv_id, adv_mac, NULL);
1539 		p2p_parse_free(&msg);
1540 		p2ps_prov_free(p2p);
1541 		goto out;
1542 	}
1543 
1544 	/* Store the provisioning info */
1545 	dev->wps_prov_info = msg.wps_config_methods;
1546 	if (msg.intended_addr)
1547 		os_memcpy(dev->interface_addr, msg.intended_addr, ETH_ALEN);
1548 
1549 	p2p_parse_free(&msg);
1550 
1551 out:
1552 	dev->req_config_methods = 0;
1553 	p2p->cfg->send_action_done(p2p->cfg->cb_ctx);
1554 	if (dev->flags & P2P_DEV_PD_BEFORE_GO_NEG) {
1555 		p2p_dbg(p2p, "Start GO Neg after the PD-before-GO-Neg workaround with "
1556 			MACSTR, MAC2STR(dev->info.p2p_device_addr));
1557 		dev->flags &= ~P2P_DEV_PD_BEFORE_GO_NEG;
1558 		p2p_connect_send(p2p, dev);
1559 		return;
1560 	}
1561 
1562 	/*
1563 	 * prov_disc_resp callback is used to generate P2P-PROV-DISC-ENTER-PIN,
1564 	 * P2P-PROV-DISC-SHOW-PIN, and P2P-PROV-DISC-PBC-REQ events.
1565 	 * Call it only for a legacy P2P PD or for P2PS PD scenarios where
1566 	 * show/enter PIN events are needed.
1567 	 *
1568 	 * The callback is called in the following cases:
1569 	 * 1. Legacy P2P PD response with a status SUCCESS
1570 	 * 2. P2PS, advertiser method: DISPLAY, autoaccept: true,
1571 	 *    response status: SUCCESS, local method KEYPAD
1572 	 * 3. P2PS, advertiser method: KEYPAD,Seeker side,
1573 	 *    response status: INFO_CURRENTLY_UNAVAILABLE,
1574 	 *    local method: DISPLAY
1575 	 */
1576 	if (p2p->cfg->prov_disc_resp &&
1577 	    ((status == P2P_SC_SUCCESS && !adv_id) ||
1578 	     (p2ps_seeker && status == P2P_SC_SUCCESS &&
1579 	      passwd_id == DEV_PW_REGISTRAR_SPECIFIED) ||
1580 	     (p2ps_seeker &&
1581 	      status == P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE &&
1582 	      passwd_id == DEV_PW_USER_SPECIFIED)))
1583 		p2p->cfg->prov_disc_resp(p2p->cfg->cb_ctx, sa,
1584 					 report_config_methods);
1585 
1586 	if (p2p->state == P2P_PD_DURING_FIND) {
1587 		p2p_stop_listen_for_freq(p2p, 0);
1588 		p2p_continue_find(p2p);
1589 	}
1590 }
1591 
1592 
p2p_send_prov_disc_req(struct p2p_data * p2p,struct p2p_device * dev,int join,int force_freq)1593 int p2p_send_prov_disc_req(struct p2p_data *p2p, struct p2p_device *dev,
1594 			   int join, int force_freq)
1595 {
1596 	struct wpabuf *req;
1597 	int freq;
1598 
1599 	if (force_freq > 0)
1600 		freq = force_freq;
1601 	else
1602 		freq = dev->listen_freq > 0 ? dev->listen_freq :
1603 			dev->oper_freq;
1604 	if (freq <= 0) {
1605 		p2p_dbg(p2p, "No Listen/Operating frequency known for the peer "
1606 			MACSTR " to send Provision Discovery Request",
1607 			MAC2STR(dev->info.p2p_device_addr));
1608 		return -1;
1609 	}
1610 
1611 	if (dev->flags & P2P_DEV_GROUP_CLIENT_ONLY) {
1612 		if (!(dev->info.dev_capab &
1613 		      P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY)) {
1614 			p2p_dbg(p2p, "Cannot use PD with P2P Device " MACSTR
1615 				" that is in a group and is not discoverable",
1616 				MAC2STR(dev->info.p2p_device_addr));
1617 			return -1;
1618 		}
1619 		/* TODO: use device discoverability request through GO */
1620 	}
1621 
1622 	if (p2p->p2ps_prov) {
1623 		if (p2p->p2ps_prov->status == P2P_SC_SUCCESS_DEFERRED) {
1624 			if (p2p->p2ps_prov->method == WPS_CONFIG_DISPLAY)
1625 				dev->req_config_methods = WPS_CONFIG_KEYPAD;
1626 			else if (p2p->p2ps_prov->method == WPS_CONFIG_KEYPAD)
1627 				dev->req_config_methods = WPS_CONFIG_DISPLAY;
1628 			else
1629 				dev->req_config_methods = WPS_CONFIG_P2PS;
1630 		} else {
1631 			/* Order of preference, based on peer's capabilities */
1632 			if (p2p->p2ps_prov->method)
1633 				dev->req_config_methods =
1634 					p2p->p2ps_prov->method;
1635 			else if (dev->info.config_methods & WPS_CONFIG_P2PS)
1636 				dev->req_config_methods = WPS_CONFIG_P2PS;
1637 			else if (dev->info.config_methods & WPS_CONFIG_DISPLAY)
1638 				dev->req_config_methods = WPS_CONFIG_DISPLAY;
1639 			else
1640 				dev->req_config_methods = WPS_CONFIG_KEYPAD;
1641 		}
1642 		p2p_dbg(p2p,
1643 			"Building PD Request based on P2PS config method 0x%x status %d --> req_config_methods 0x%x",
1644 			p2p->p2ps_prov->method, p2p->p2ps_prov->status,
1645 			dev->req_config_methods);
1646 
1647 		if (p2p_prepare_channel(p2p, dev, p2p->p2ps_prov->force_freq,
1648 					p2p->p2ps_prov->pref_freq, 1) < 0)
1649 			return -1;
1650 	}
1651 
1652 	req = p2p_build_prov_disc_req(p2p, dev, join);
1653 	if (req == NULL)
1654 		return -1;
1655 
1656 	if (p2p->state != P2P_IDLE)
1657 		p2p_stop_listen_for_freq(p2p, freq);
1658 	p2p->pending_action_state = P2P_PENDING_PD;
1659 	if (p2p_send_action(p2p, freq, dev->info.p2p_device_addr,
1660 			    p2p->cfg->dev_addr, dev->info.p2p_device_addr,
1661 			    wpabuf_head(req), wpabuf_len(req), 200) < 0) {
1662 		p2p_dbg(p2p, "Failed to send Action frame");
1663 		wpabuf_free(req);
1664 		return -1;
1665 	}
1666 
1667 	os_memcpy(p2p->pending_pd_devaddr, dev->info.p2p_device_addr, ETH_ALEN);
1668 
1669 	wpabuf_free(req);
1670 	return 0;
1671 }
1672 
1673 
p2p_prov_disc_req(struct p2p_data * p2p,const u8 * peer_addr,struct p2ps_provision * p2ps_prov,u16 config_methods,int join,int force_freq,int user_initiated_pd)1674 int p2p_prov_disc_req(struct p2p_data *p2p, const u8 *peer_addr,
1675 		      struct p2ps_provision *p2ps_prov,
1676 		      u16 config_methods, int join, int force_freq,
1677 		      int user_initiated_pd)
1678 {
1679 	struct p2p_device *dev;
1680 
1681 	dev = p2p_get_device(p2p, peer_addr);
1682 	if (dev == NULL)
1683 		dev = p2p_get_device_interface(p2p, peer_addr);
1684 	if (dev == NULL || (dev->flags & P2P_DEV_PROBE_REQ_ONLY)) {
1685 		p2p_dbg(p2p, "Provision Discovery Request destination " MACSTR
1686 			" not yet known", MAC2STR(peer_addr));
1687 		os_free(p2ps_prov);
1688 		return -1;
1689 	}
1690 
1691 	p2p_dbg(p2p, "Provision Discovery Request with " MACSTR
1692 		" (config methods 0x%x)",
1693 		MAC2STR(peer_addr), config_methods);
1694 	if (config_methods == 0 && !p2ps_prov) {
1695 		os_free(p2ps_prov);
1696 		return -1;
1697 	}
1698 
1699 	if (p2ps_prov && p2ps_prov->status == P2P_SC_SUCCESS_DEFERRED &&
1700 	    p2p->p2ps_prov) {
1701 		/* Use cached method from deferred provisioning */
1702 		p2ps_prov->method = p2p->p2ps_prov->method;
1703 	}
1704 
1705 	/* Reset provisioning info */
1706 	dev->wps_prov_info = 0;
1707 	p2ps_prov_free(p2p);
1708 	p2p->p2ps_prov = p2ps_prov;
1709 
1710 	dev->req_config_methods = config_methods;
1711 	if (join)
1712 		dev->flags |= P2P_DEV_PD_FOR_JOIN;
1713 	else
1714 		dev->flags &= ~P2P_DEV_PD_FOR_JOIN;
1715 
1716 	if (p2p->state != P2P_IDLE && p2p->state != P2P_SEARCH &&
1717 	    p2p->state != P2P_LISTEN_ONLY) {
1718 		p2p_dbg(p2p, "Busy with other operations; postpone Provision Discovery Request with "
1719 			MACSTR " (config methods 0x%x)",
1720 			MAC2STR(peer_addr), config_methods);
1721 		return 0;
1722 	}
1723 
1724 	p2p->user_initiated_pd = user_initiated_pd;
1725 	p2p->pd_force_freq = force_freq;
1726 
1727 	if (p2p->user_initiated_pd)
1728 		p2p->pd_retries = MAX_PROV_DISC_REQ_RETRIES;
1729 
1730 	/*
1731 	 * Assign dialog token here to use the same value in each retry within
1732 	 * the same PD exchange.
1733 	 */
1734 	dev->dialog_token++;
1735 	if (dev->dialog_token == 0)
1736 		dev->dialog_token = 1;
1737 
1738 	return p2p_send_prov_disc_req(p2p, dev, join, force_freq);
1739 }
1740 
1741 
p2p_reset_pending_pd(struct p2p_data * p2p)1742 void p2p_reset_pending_pd(struct p2p_data *p2p)
1743 {
1744 	struct p2p_device *dev;
1745 
1746 	dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) {
1747 		if (os_memcmp(p2p->pending_pd_devaddr,
1748 			      dev->info.p2p_device_addr, ETH_ALEN))
1749 			continue;
1750 		if (!dev->req_config_methods)
1751 			continue;
1752 		if (dev->flags & P2P_DEV_PD_FOR_JOIN)
1753 			continue;
1754 		/* Reset the config methods of the device */
1755 		dev->req_config_methods = 0;
1756 	}
1757 
1758 	p2p->user_initiated_pd = 0;
1759 	os_memset(p2p->pending_pd_devaddr, 0, ETH_ALEN);
1760 	p2p->pd_retries = 0;
1761 	p2p->pd_force_freq = 0;
1762 }
1763 
1764 
p2ps_prov_free(struct p2p_data * p2p)1765 void p2ps_prov_free(struct p2p_data *p2p)
1766 {
1767 	os_free(p2p->p2ps_prov);
1768 	p2p->p2ps_prov = NULL;
1769 }
1770