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 (ether_addr_equal(msg->persistent_dev, addr)) {
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 (!ether_addr_equal(p2p->cfg->dev_addr, msg.adv_mac)) {
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 !ether_addr_equal(p2p->p2ps_prov->adv_mac, msg.adv_mac)) {
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 !ether_addr_equal(p2p->p2ps_prov->session_mac, msg.session_mac)) {
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 (!ether_addr_equal(p2p->p2ps_prov->session_mac, msg->session_mac)) {
1243 p2p_dbg(p2p,
1244 "Ignore PD Response with unexpected Session MAC");
1245 return -1;
1246 }
1247
1248 if (p2p->p2ps_prov->adv_id != adv_id) {
1249 p2p_dbg(p2p,
1250 "Ignore PD Response with unexpected Advertisement ID");
1251 return -1;
1252 }
1253
1254 if (!ether_addr_equal(p2p->p2ps_prov->adv_mac, msg->adv_mac)) {
1255 p2p_dbg(p2p,
1256 "Ignore PD Response with unexpected Advertisement MAC");
1257 return -1;
1258 }
1259
1260 if (msg->listen_channel) {
1261 p2p_dbg(p2p,
1262 "Ignore malformed PD Response - unexpected Listen Channel");
1263 return -1;
1264 }
1265
1266 if (*msg->status == P2P_SC_SUCCESS &&
1267 !(!!msg->conn_cap ^ !!msg->persistent_dev)) {
1268 p2p_dbg(p2p,
1269 "Ignore malformed PD Response - either conn_cap or persistent group should be present");
1270 return -1;
1271 }
1272
1273 if (msg->persistent_dev && *msg->status != P2P_SC_SUCCESS) {
1274 p2p_dbg(p2p,
1275 "Ignore malformed PD Response - persistent group is present, but the status isn't success");
1276 return -1;
1277 }
1278
1279 if (msg->conn_cap) {
1280 conn_cap_go = *msg->conn_cap == P2PS_SETUP_GROUP_OWNER;
1281 conn_cap_cli = *msg->conn_cap == P2PS_SETUP_CLIENT;
1282 }
1283
1284 P2PS_PD_RESP_CHECK(msg->persistent_dev || conn_cap_go || conn_cap_cli,
1285 channel_list);
1286 P2PS_PD_RESP_CHECK(msg->persistent_dev || conn_cap_go || conn_cap_cli,
1287 config_timeout);
1288
1289 P2PS_PD_RESP_CHECK(conn_cap_go, group_id);
1290 P2PS_PD_RESP_CHECK(conn_cap_go, intended_addr);
1291 P2PS_PD_RESP_CHECK(conn_cap_go, operating_channel);
1292 /*
1293 * TODO: Also validate that operating channel is present if the device
1294 * is a GO in a persistent group. We can't do it here since we don't
1295 * know what is the role of the peer. It should be probably done in
1296 * p2ps_prov_complete callback, but currently operating channel isn't
1297 * passed to it.
1298 */
1299
1300 #undef P2PS_PD_RESP_CHECK
1301
1302 return 0;
1303 }
1304
1305
p2p_process_prov_disc_resp(struct p2p_data * p2p,const u8 * sa,const u8 * data,size_t len)1306 void p2p_process_prov_disc_resp(struct p2p_data *p2p, const u8 *sa,
1307 const u8 *data, size_t len)
1308 {
1309 struct p2p_message msg;
1310 struct p2p_device *dev;
1311 u16 report_config_methods = 0, req_config_methods;
1312 u8 status = P2P_SC_SUCCESS;
1313 u32 adv_id = 0;
1314 u8 conncap = P2PS_SETUP_NEW;
1315 u8 adv_mac[ETH_ALEN];
1316 const u8 *group_mac;
1317 int passwd_id = DEV_PW_DEFAULT;
1318 int p2ps_seeker;
1319
1320 if (p2p_parse(data, len, &msg))
1321 return;
1322
1323 if (p2p->p2ps_prov && p2p_validate_p2ps_pd_resp(p2p, &msg)) {
1324 p2p_parse_free(&msg);
1325 return;
1326 }
1327
1328 /* Parse the P2PS members present */
1329 if (msg.status)
1330 status = *msg.status;
1331
1332 group_mac = msg.intended_addr;
1333
1334 if (msg.adv_mac)
1335 os_memcpy(adv_mac, msg.adv_mac, ETH_ALEN);
1336 else
1337 os_memset(adv_mac, 0, ETH_ALEN);
1338
1339 if (msg.adv_id)
1340 adv_id = WPA_GET_LE32(msg.adv_id);
1341
1342 if (msg.conn_cap) {
1343 conncap = *msg.conn_cap;
1344
1345 /* Switch bits to local relative */
1346 switch (conncap) {
1347 case P2PS_SETUP_GROUP_OWNER:
1348 conncap = P2PS_SETUP_CLIENT;
1349 break;
1350 case P2PS_SETUP_CLIENT:
1351 conncap = P2PS_SETUP_GROUP_OWNER;
1352 break;
1353 }
1354 }
1355
1356 p2p_dbg(p2p, "Received Provision Discovery Response from " MACSTR
1357 " with config methods 0x%x",
1358 MAC2STR(sa), msg.wps_config_methods);
1359
1360 dev = p2p_get_device(p2p, sa);
1361 if (dev == NULL || !dev->req_config_methods) {
1362 p2p_dbg(p2p, "Ignore Provision Discovery Response from " MACSTR
1363 " with no pending request", MAC2STR(sa));
1364 p2p_parse_free(&msg);
1365 return;
1366 } else if (msg.wfd_subelems) {
1367 wpabuf_free(dev->info.wfd_subelems);
1368 dev->info.wfd_subelems = wpabuf_dup(msg.wfd_subelems);
1369 }
1370
1371 p2p_update_peer_6ghz_capab(dev, &msg);
1372
1373 if (dev->dialog_token != msg.dialog_token) {
1374 p2p_dbg(p2p, "Ignore Provision Discovery Response with unexpected Dialog Token %u (expected %u)",
1375 msg.dialog_token, dev->dialog_token);
1376 p2p_parse_free(&msg);
1377 return;
1378 }
1379
1380 if (p2p->pending_action_state == P2P_PENDING_PD) {
1381 os_memset(p2p->pending_pd_devaddr, 0, ETH_ALEN);
1382 p2p->pending_action_state = P2P_NO_PENDING_ACTION;
1383 }
1384
1385 p2ps_seeker = p2p->p2ps_prov && p2p->p2ps_prov->pd_seeker;
1386
1387 /*
1388 * Use a local copy of the requested config methods since
1389 * p2p_reset_pending_pd() can clear this in the peer entry.
1390 */
1391 req_config_methods = dev->req_config_methods;
1392
1393 /*
1394 * If the response is from the peer to whom a user initiated request
1395 * was sent earlier, we reset that state info here.
1396 */
1397 if (p2p->user_initiated_pd &&
1398 ether_addr_equal(p2p->pending_pd_devaddr, sa))
1399 p2p_reset_pending_pd(p2p);
1400
1401 if (msg.wps_config_methods != req_config_methods) {
1402 p2p_dbg(p2p, "Peer rejected our Provision Discovery Request (received config_methods 0x%x expected 0x%x",
1403 msg.wps_config_methods, req_config_methods);
1404 if (p2p->cfg->prov_disc_fail)
1405 p2p->cfg->prov_disc_fail(p2p->cfg->cb_ctx, sa,
1406 P2P_PROV_DISC_REJECTED,
1407 adv_id, adv_mac, NULL);
1408 p2p_parse_free(&msg);
1409 p2ps_prov_free(p2p);
1410 goto out;
1411 }
1412
1413 report_config_methods = req_config_methods;
1414 dev->flags &= ~(P2P_DEV_PD_PEER_DISPLAY |
1415 P2P_DEV_PD_PEER_KEYPAD |
1416 P2P_DEV_PD_PEER_P2PS);
1417 if (req_config_methods & WPS_CONFIG_DISPLAY) {
1418 p2p_dbg(p2p, "Peer " MACSTR
1419 " accepted to show a PIN on display", MAC2STR(sa));
1420 dev->flags |= P2P_DEV_PD_PEER_DISPLAY;
1421 passwd_id = DEV_PW_REGISTRAR_SPECIFIED;
1422 } else if (msg.wps_config_methods & WPS_CONFIG_KEYPAD) {
1423 p2p_dbg(p2p, "Peer " MACSTR
1424 " accepted to write our PIN using keypad",
1425 MAC2STR(sa));
1426 dev->flags |= P2P_DEV_PD_PEER_KEYPAD;
1427 passwd_id = DEV_PW_USER_SPECIFIED;
1428 } else if (msg.wps_config_methods & WPS_CONFIG_P2PS) {
1429 p2p_dbg(p2p, "Peer " MACSTR " accepted P2PS PIN",
1430 MAC2STR(sa));
1431 dev->flags |= P2P_DEV_PD_PEER_P2PS;
1432 passwd_id = DEV_PW_P2PS_DEFAULT;
1433 }
1434
1435 if ((status == P2P_SC_SUCCESS || status == P2P_SC_SUCCESS_DEFERRED) &&
1436 p2p->p2ps_prov) {
1437 dev->oper_freq = 0;
1438
1439 /*
1440 * Save the reported channel list and operating frequency.
1441 * Note that the specification mandates that the responder
1442 * should include in the channel list only channels reported by
1443 * the initiator, so this is only a validity check, and if this
1444 * fails the flow would continue, although it would probably
1445 * fail. Same is true for the operating channel.
1446 */
1447 if (msg.channel_list && msg.channel_list_len &&
1448 p2p_peer_channels_check(p2p, &p2p->channels, dev,
1449 msg.channel_list,
1450 msg.channel_list_len) < 0)
1451 p2p_dbg(p2p, "P2PS PD Response - no common channels");
1452
1453 if (msg.operating_channel) {
1454 if (p2p_channels_includes(&p2p->channels,
1455 msg.operating_channel[3],
1456 msg.operating_channel[4]) &&
1457 p2p_channels_includes(&dev->channels,
1458 msg.operating_channel[3],
1459 msg.operating_channel[4])) {
1460 dev->oper_freq =
1461 p2p_channel_to_freq(
1462 msg.operating_channel[3],
1463 msg.operating_channel[4]);
1464 } else {
1465 p2p_dbg(p2p,
1466 "P2PS PD Response - invalid operating channel");
1467 }
1468 }
1469
1470 if (p2p->cfg->p2ps_prov_complete) {
1471 int freq = 0;
1472
1473 if (conncap == P2PS_SETUP_GROUP_OWNER) {
1474 u8 tmp;
1475
1476 /*
1477 * Re-select the operating channel as it is
1478 * possible that original channel is no longer
1479 * valid. This should not really fail.
1480 */
1481 if (p2p_go_select_channel(p2p, dev, &tmp) < 0)
1482 p2p_dbg(p2p,
1483 "P2PS PD channel selection failed");
1484
1485 freq = p2p_channel_to_freq(p2p->op_reg_class,
1486 p2p->op_channel);
1487 if (freq < 0)
1488 freq = 0;
1489 }
1490
1491 p2p->cfg->p2ps_prov_complete(
1492 p2p->cfg->cb_ctx, status, sa, adv_mac,
1493 p2p->p2ps_prov->session_mac,
1494 group_mac, adv_id, p2p->p2ps_prov->session_id,
1495 conncap, passwd_id, msg.persistent_ssid,
1496 msg.persistent_ssid_len, 1, 0, NULL,
1497 msg.feature_cap, msg.feature_cap_len, freq,
1498 msg.group_id ? msg.group_id + ETH_ALEN : NULL,
1499 msg.group_id ? msg.group_id_len - ETH_ALEN : 0);
1500 }
1501 p2ps_prov_free(p2p);
1502 } else if (status != P2P_SC_SUCCESS &&
1503 status != P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE &&
1504 status != P2P_SC_SUCCESS_DEFERRED && p2p->p2ps_prov) {
1505 if (p2p->cfg->p2ps_prov_complete)
1506 p2p->cfg->p2ps_prov_complete(
1507 p2p->cfg->cb_ctx, status, sa, adv_mac,
1508 p2p->p2ps_prov->session_mac,
1509 group_mac, adv_id, p2p->p2ps_prov->session_id,
1510 0, 0, NULL, 0, 1, 0, NULL, NULL, 0, 0, NULL, 0);
1511 p2ps_prov_free(p2p);
1512 }
1513
1514 if (status == P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE) {
1515 if (p2p->cfg->remove_stale_groups) {
1516 p2p->cfg->remove_stale_groups(p2p->cfg->cb_ctx,
1517 dev->info.p2p_device_addr,
1518 NULL, NULL, 0);
1519 }
1520
1521 if (msg.session_info && msg.session_info_len) {
1522 size_t info_len = msg.session_info_len;
1523 char *deferred_sess_resp = os_malloc(2 * info_len + 1);
1524
1525 if (!deferred_sess_resp) {
1526 p2p_parse_free(&msg);
1527 p2ps_prov_free(p2p);
1528 goto out;
1529 }
1530 utf8_escape((char *) msg.session_info, info_len,
1531 deferred_sess_resp, 2 * info_len + 1);
1532
1533 if (p2p->cfg->prov_disc_fail)
1534 p2p->cfg->prov_disc_fail(
1535 p2p->cfg->cb_ctx, sa,
1536 P2P_PROV_DISC_INFO_UNAVAILABLE,
1537 adv_id, adv_mac,
1538 deferred_sess_resp);
1539 os_free(deferred_sess_resp);
1540 } else
1541 if (p2p->cfg->prov_disc_fail)
1542 p2p->cfg->prov_disc_fail(
1543 p2p->cfg->cb_ctx, sa,
1544 P2P_PROV_DISC_INFO_UNAVAILABLE,
1545 adv_id, adv_mac, NULL);
1546 } else if (status != P2P_SC_SUCCESS) {
1547 p2p_dbg(p2p, "Peer rejected our Provision Discovery Request");
1548 if (p2p->cfg->prov_disc_fail)
1549 p2p->cfg->prov_disc_fail(p2p->cfg->cb_ctx, sa,
1550 P2P_PROV_DISC_REJECTED,
1551 adv_id, adv_mac, NULL);
1552 p2p_parse_free(&msg);
1553 p2ps_prov_free(p2p);
1554 goto out;
1555 }
1556
1557 /* Store the provisioning info */
1558 dev->wps_prov_info = msg.wps_config_methods;
1559 if (msg.intended_addr)
1560 os_memcpy(dev->interface_addr, msg.intended_addr, ETH_ALEN);
1561
1562 p2p_parse_free(&msg);
1563
1564 out:
1565 dev->req_config_methods = 0;
1566 p2p->cfg->send_action_done(p2p->cfg->cb_ctx);
1567 if (dev->flags & P2P_DEV_PD_BEFORE_GO_NEG) {
1568 p2p_dbg(p2p, "Start GO Neg after the PD-before-GO-Neg workaround with "
1569 MACSTR, MAC2STR(dev->info.p2p_device_addr));
1570 dev->flags &= ~P2P_DEV_PD_BEFORE_GO_NEG;
1571 p2p_connect_send(p2p, dev);
1572 return;
1573 }
1574
1575 /*
1576 * prov_disc_resp callback is used to generate P2P-PROV-DISC-ENTER-PIN,
1577 * P2P-PROV-DISC-SHOW-PIN, and P2P-PROV-DISC-PBC-REQ events.
1578 * Call it only for a legacy P2P PD or for P2PS PD scenarios where
1579 * show/enter PIN events are needed.
1580 *
1581 * The callback is called in the following cases:
1582 * 1. Legacy P2P PD response with a status SUCCESS
1583 * 2. P2PS, advertiser method: DISPLAY, autoaccept: true,
1584 * response status: SUCCESS, local method KEYPAD
1585 * 3. P2PS, advertiser method: KEYPAD,Seeker side,
1586 * response status: INFO_CURRENTLY_UNAVAILABLE,
1587 * local method: DISPLAY
1588 */
1589 if (p2p->cfg->prov_disc_resp &&
1590 ((status == P2P_SC_SUCCESS && !adv_id) ||
1591 (p2ps_seeker && status == P2P_SC_SUCCESS &&
1592 passwd_id == DEV_PW_REGISTRAR_SPECIFIED) ||
1593 (p2ps_seeker &&
1594 status == P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE &&
1595 passwd_id == DEV_PW_USER_SPECIFIED)))
1596 p2p->cfg->prov_disc_resp(p2p->cfg->cb_ctx, sa,
1597 report_config_methods);
1598
1599 if (p2p->state == P2P_PD_DURING_FIND) {
1600 p2p_stop_listen_for_freq(p2p, 0);
1601 p2p_continue_find(p2p);
1602 }
1603 }
1604
1605
p2p_send_prov_disc_req(struct p2p_data * p2p,struct p2p_device * dev,int join,int force_freq)1606 int p2p_send_prov_disc_req(struct p2p_data *p2p, struct p2p_device *dev,
1607 int join, int force_freq)
1608 {
1609 struct wpabuf *req;
1610 int freq;
1611
1612 if (force_freq > 0)
1613 freq = force_freq;
1614 else
1615 freq = dev->listen_freq > 0 ? dev->listen_freq :
1616 dev->oper_freq;
1617 if (freq <= 0) {
1618 p2p_dbg(p2p, "No Listen/Operating frequency known for the peer "
1619 MACSTR " to send Provision Discovery Request",
1620 MAC2STR(dev->info.p2p_device_addr));
1621 return -1;
1622 }
1623
1624 if (dev->flags & P2P_DEV_GROUP_CLIENT_ONLY) {
1625 if (!(dev->info.dev_capab &
1626 P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY)) {
1627 p2p_dbg(p2p, "Cannot use PD with P2P Device " MACSTR
1628 " that is in a group and is not discoverable",
1629 MAC2STR(dev->info.p2p_device_addr));
1630 return -1;
1631 }
1632 /* TODO: use device discoverability request through GO */
1633 }
1634
1635 if (p2p->p2ps_prov) {
1636 if (p2p->p2ps_prov->status == P2P_SC_SUCCESS_DEFERRED) {
1637 if (p2p->p2ps_prov->method == WPS_CONFIG_DISPLAY)
1638 dev->req_config_methods = WPS_CONFIG_KEYPAD;
1639 else if (p2p->p2ps_prov->method == WPS_CONFIG_KEYPAD)
1640 dev->req_config_methods = WPS_CONFIG_DISPLAY;
1641 else
1642 dev->req_config_methods = WPS_CONFIG_P2PS;
1643 } else {
1644 /* Order of preference, based on peer's capabilities */
1645 if (p2p->p2ps_prov->method)
1646 dev->req_config_methods =
1647 p2p->p2ps_prov->method;
1648 else if (dev->info.config_methods & WPS_CONFIG_P2PS)
1649 dev->req_config_methods = WPS_CONFIG_P2PS;
1650 else if (dev->info.config_methods & WPS_CONFIG_DISPLAY)
1651 dev->req_config_methods = WPS_CONFIG_DISPLAY;
1652 else
1653 dev->req_config_methods = WPS_CONFIG_KEYPAD;
1654 }
1655 p2p_dbg(p2p,
1656 "Building PD Request based on P2PS config method 0x%x status %d --> req_config_methods 0x%x",
1657 p2p->p2ps_prov->method, p2p->p2ps_prov->status,
1658 dev->req_config_methods);
1659
1660 if (p2p_prepare_channel(p2p, dev, p2p->p2ps_prov->force_freq,
1661 p2p->p2ps_prov->pref_freq, 1) < 0)
1662 return -1;
1663 }
1664
1665 req = p2p_build_prov_disc_req(p2p, dev, join);
1666 if (req == NULL)
1667 return -1;
1668
1669 if (p2p->state != P2P_IDLE)
1670 p2p_stop_listen_for_freq(p2p, freq);
1671 p2p->pending_action_state = P2P_PENDING_PD;
1672 if (p2p_send_action(p2p, freq, dev->info.p2p_device_addr,
1673 p2p->cfg->dev_addr, dev->info.p2p_device_addr,
1674 wpabuf_head(req), wpabuf_len(req), 200) < 0) {
1675 p2p_dbg(p2p, "Failed to send Action frame");
1676 wpabuf_free(req);
1677 return -1;
1678 }
1679
1680 os_memcpy(p2p->pending_pd_devaddr, dev->info.p2p_device_addr, ETH_ALEN);
1681
1682 wpabuf_free(req);
1683 return 0;
1684 }
1685
1686
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)1687 int p2p_prov_disc_req(struct p2p_data *p2p, const u8 *peer_addr,
1688 struct p2ps_provision *p2ps_prov,
1689 u16 config_methods, int join, int force_freq,
1690 int user_initiated_pd)
1691 {
1692 struct p2p_device *dev;
1693
1694 dev = p2p_get_device(p2p, peer_addr);
1695 if (dev == NULL)
1696 dev = p2p_get_device_interface(p2p, peer_addr);
1697 if (dev == NULL || (dev->flags & P2P_DEV_PROBE_REQ_ONLY)) {
1698 p2p_dbg(p2p, "Provision Discovery Request destination " MACSTR
1699 " not yet known", MAC2STR(peer_addr));
1700 os_free(p2ps_prov);
1701 return -1;
1702 }
1703
1704 p2p_dbg(p2p, "Provision Discovery Request with " MACSTR
1705 " (config methods 0x%x)",
1706 MAC2STR(peer_addr), config_methods);
1707 if (config_methods == 0 && !p2ps_prov) {
1708 os_free(p2ps_prov);
1709 return -1;
1710 }
1711
1712 if (p2ps_prov && p2ps_prov->status == P2P_SC_SUCCESS_DEFERRED &&
1713 p2p->p2ps_prov) {
1714 /* Use cached method from deferred provisioning */
1715 p2ps_prov->method = p2p->p2ps_prov->method;
1716 }
1717
1718 /* Reset provisioning info */
1719 dev->wps_prov_info = 0;
1720 p2ps_prov_free(p2p);
1721 p2p->p2ps_prov = p2ps_prov;
1722
1723 dev->req_config_methods = config_methods;
1724 if (join)
1725 dev->flags |= P2P_DEV_PD_FOR_JOIN;
1726 else
1727 dev->flags &= ~P2P_DEV_PD_FOR_JOIN;
1728
1729 if (p2p->state != P2P_IDLE && p2p->state != P2P_SEARCH &&
1730 p2p->state != P2P_LISTEN_ONLY) {
1731 p2p_dbg(p2p, "Busy with other operations; postpone Provision Discovery Request with "
1732 MACSTR " (config methods 0x%x)",
1733 MAC2STR(peer_addr), config_methods);
1734 return 0;
1735 }
1736
1737 p2p->user_initiated_pd = user_initiated_pd;
1738 p2p->pd_force_freq = force_freq;
1739
1740 if (p2p->user_initiated_pd)
1741 p2p->pd_retries = MAX_PROV_DISC_REQ_RETRIES;
1742
1743 /*
1744 * Assign dialog token here to use the same value in each retry within
1745 * the same PD exchange.
1746 */
1747 dev->dialog_token++;
1748 if (dev->dialog_token == 0)
1749 dev->dialog_token = 1;
1750
1751 return p2p_send_prov_disc_req(p2p, dev, join, force_freq);
1752 }
1753
1754
p2p_reset_pending_pd(struct p2p_data * p2p)1755 void p2p_reset_pending_pd(struct p2p_data *p2p)
1756 {
1757 struct p2p_device *dev;
1758
1759 dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) {
1760 if (!ether_addr_equal(p2p->pending_pd_devaddr,
1761 dev->info.p2p_device_addr))
1762 continue;
1763 if (!dev->req_config_methods)
1764 continue;
1765 if (dev->flags & P2P_DEV_PD_FOR_JOIN)
1766 continue;
1767 /* Reset the config methods of the device */
1768 dev->req_config_methods = 0;
1769 }
1770
1771 p2p->user_initiated_pd = 0;
1772 os_memset(p2p->pending_pd_devaddr, 0, ETH_ALEN);
1773 p2p->pd_retries = 0;
1774 p2p->pd_force_freq = 0;
1775 }
1776
1777
p2ps_prov_free(struct p2p_data * p2p)1778 void p2ps_prov_free(struct p2p_data *p2p)
1779 {
1780 os_free(p2p->p2ps_prov);
1781 p2p->p2ps_prov = NULL;
1782 }
1783