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