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