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