2 * Wi-Fi Direct - P2P provision discovery
3 * Copyright (c) 2009-2010, Atheros Communications
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
12 #include "common/ieee802_11_defs.h"
13 #include "common/wpa_ctrl.h"
14 #include "wps/wps_defs.h"
20 * Number of retries to attempt for provision discovery requests
21 * in case the peer is not listening.
23 #define MAX_PROV_DISC_REQ_RETRIES 120
26 static void p2p_build_wps_ie_config_methods(struct wpabuf *buf,
30 wpabuf_put_u8(buf, WLAN_EID_VENDOR_SPECIFIC);
31 len = wpabuf_put(buf, 1);
32 wpabuf_put_be32(buf, WPS_DEV_OUI_WFA);
35 wpabuf_put_be16(buf, ATTR_CONFIG_METHODS);
36 wpabuf_put_be16(buf, 2);
37 wpabuf_put_be16(buf, config_methods);
39 p2p_buf_update_ie_hdr(buf, len);
43 static void p2ps_add_new_group_info(struct p2p_data *p2p, struct wpabuf *buf)
46 u8 intended_addr[ETH_ALEN];
47 u8 ssid[SSID_MAX_LEN];
51 if (!p2p->cfg->get_go_info)
54 found = p2p->cfg->get_go_info(
55 p2p->cfg->cb_ctx, intended_addr, ssid,
56 &ssid_len, &group_iface);
58 p2p_buf_add_group_id(buf, p2p->cfg->dev_addr,
62 p2p_buf_add_intended_addr(buf, p2p->intended_addr);
64 p2p_buf_add_intended_addr(buf, intended_addr);
67 p2p_build_ssid(p2p, p2p->ssid, &p2p->ssid_len);
71 /* Add pre-composed P2P Group ID */
72 p2p_buf_add_group_id(buf, p2p->cfg->dev_addr,
73 p2p->ssid, p2p->ssid_len);
76 p2p_buf_add_intended_addr(
77 buf, p2p->intended_addr);
79 p2p_buf_add_intended_addr(
80 buf, p2p->cfg->dev_addr);
85 static void p2ps_add_pd_req_attrs(struct p2p_data *p2p, struct p2p_device *dev,
86 struct wpabuf *buf, u16 config_methods)
88 struct p2ps_provision *prov = p2p->p2ps_prov;
89 struct p2ps_feature_capab fcap = { prov->cpt_mask, 0 };
91 u8 ssid[SSID_MAX_LEN];
93 u8 go_dev_addr[ETH_ALEN];
94 u8 intended_addr[ETH_ALEN];
96 /* If we might be explicite group owner, add GO details */
97 if (prov->conncap & (P2PS_SETUP_GROUP_OWNER |
99 p2ps_add_new_group_info(p2p, buf);
101 if (prov->status >= 0)
102 p2p_buf_add_status(buf, (u8) prov->status);
104 prov->method = config_methods;
106 if (p2p->cfg->get_persistent_group) {
107 shared_group = p2p->cfg->get_persistent_group(
108 p2p->cfg->cb_ctx, dev->info.p2p_device_addr, NULL, 0,
109 go_dev_addr, ssid, &ssid_len, intended_addr);
112 /* Add Operating Channel if conncap includes GO */
114 (prov->conncap & (P2PS_SETUP_GROUP_OWNER |
118 p2p_go_select_channel(p2p, dev, &tmp);
120 if (p2p->op_reg_class && p2p->op_channel)
121 p2p_buf_add_operating_channel(buf, p2p->cfg->country,
125 p2p_buf_add_operating_channel(buf, p2p->cfg->country,
126 p2p->cfg->op_reg_class,
127 p2p->cfg->op_channel);
130 p2p_buf_add_channel_list(buf, p2p->cfg->country, &p2p->cfg->channels);
133 p2p_buf_add_session_info(buf, prov->info);
135 p2p_buf_add_connection_capability(buf, prov->conncap);
137 p2p_buf_add_advertisement_id(buf, prov->adv_id, prov->adv_mac);
139 if (shared_group || prov->conncap == P2PS_SETUP_NEW ||
141 (P2PS_SETUP_GROUP_OWNER | P2PS_SETUP_NEW) ||
143 (P2PS_SETUP_GROUP_OWNER | P2PS_SETUP_CLIENT)) {
144 /* Add Config Timeout */
145 p2p_buf_add_config_timeout(buf, p2p->go_timeout,
146 p2p->client_timeout);
149 p2p_buf_add_listen_channel(buf, p2p->cfg->country, p2p->cfg->reg_class,
152 p2p_buf_add_session_id(buf, prov->session_id, prov->session_mac);
154 p2p_buf_add_feature_capability(buf, sizeof(fcap), (const u8 *) &fcap);
157 p2p_buf_add_persistent_group_info(buf, go_dev_addr,
159 /* Add intended interface address if it is not added yet */
160 if ((prov->conncap == P2PS_SETUP_NONE ||
161 prov->conncap == P2PS_SETUP_CLIENT) &&
162 !is_zero_ether_addr(intended_addr))
163 p2p_buf_add_intended_addr(buf, intended_addr);
168 static struct wpabuf * p2p_build_prov_disc_req(struct p2p_data *p2p,
169 struct p2p_device *dev,
175 u8 dialog_token = dev->dialog_token;
176 u16 config_methods = dev->req_config_methods;
177 struct p2p_device *go = join ? dev : NULL;
180 #ifdef CONFIG_WIFI_DISPLAY
181 if (p2p->wfd_ie_prov_disc_req)
182 extra = wpabuf_len(p2p->wfd_ie_prov_disc_req);
183 #endif /* CONFIG_WIFI_DISPLAY */
185 if (p2p->vendor_elem && p2p->vendor_elem[VENDOR_ELEM_P2P_PD_REQ])
186 extra += wpabuf_len(p2p->vendor_elem[VENDOR_ELEM_P2P_PD_REQ]);
189 extra += os_strlen(p2p->p2ps_prov->info) + 1 +
190 sizeof(struct p2ps_provision);
192 buf = wpabuf_alloc(1000 + extra);
196 p2p_buf_add_public_action_hdr(buf, P2P_PROV_DISC_REQ, dialog_token);
198 len = p2p_buf_add_ie_hdr(buf);
201 if (p2p->p2ps_prov) {
202 group_capab |= P2P_GROUP_CAPAB_PERSISTENT_GROUP;
203 group_capab |= P2P_GROUP_CAPAB_PERSISTENT_RECONN;
204 if (p2p->cross_connect)
205 group_capab |= P2P_GROUP_CAPAB_CROSS_CONN;
206 if (p2p->cfg->p2p_intra_bss)
207 group_capab |= P2P_GROUP_CAPAB_INTRA_BSS_DIST;
209 p2p_buf_add_capability(buf, p2p->dev_capab &
210 ~P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY,
212 p2p_buf_add_device_info(buf, p2p, NULL);
213 if (p2p->p2ps_prov) {
214 p2ps_add_pd_req_attrs(p2p, dev, buf, config_methods);
216 p2p_buf_add_group_id(buf, go->info.p2p_device_addr,
217 go->oper_ssid, go->oper_ssid_len);
219 p2p_buf_update_ie_hdr(buf, len);
221 /* WPS IE with Config Methods attribute */
222 p2p_build_wps_ie_config_methods(buf, config_methods);
224 #ifdef CONFIG_WIFI_DISPLAY
225 if (p2p->wfd_ie_prov_disc_req)
226 wpabuf_put_buf(buf, p2p->wfd_ie_prov_disc_req);
227 #endif /* CONFIG_WIFI_DISPLAY */
229 if (p2p->vendor_elem && p2p->vendor_elem[VENDOR_ELEM_P2P_PD_REQ])
230 wpabuf_put_buf(buf, p2p->vendor_elem[VENDOR_ELEM_P2P_PD_REQ]);
236 static struct wpabuf * p2p_build_prov_disc_resp(struct p2p_data *p2p,
237 struct p2p_device *dev,
239 enum p2p_status_code status,
244 const u8 *persist_ssid,
245 size_t persist_ssid_len,
253 #ifdef CONFIG_WIFI_DISPLAY
254 struct wpabuf *wfd_ie = p2p->wfd_ie_prov_disc_resp;
255 if (wfd_ie && group_id) {
257 for (i = 0; i < p2p->num_groups; i++) {
258 struct p2p_group *g = p2p->groups[i];
260 if (!p2p_group_is_group_id_match(g, group_id,
263 ie = p2p_group_get_wfd_ie(g);
271 extra = wpabuf_len(wfd_ie);
272 #endif /* CONFIG_WIFI_DISPLAY */
274 if (p2p->vendor_elem && p2p->vendor_elem[VENDOR_ELEM_P2P_PD_RESP])
275 extra += wpabuf_len(p2p->vendor_elem[VENDOR_ELEM_P2P_PD_RESP]);
277 buf = wpabuf_alloc(1000 + extra);
281 p2p_buf_add_public_action_hdr(buf, P2P_PROV_DISC_RESP, dialog_token);
283 /* Add P2P IE for P2PS */
284 if (p2p->p2ps_prov && p2p->p2ps_prov->adv_id == adv_id) {
285 u8 *len = p2p_buf_add_ie_hdr(buf);
286 struct p2ps_provision *prov = p2p->p2ps_prov;
289 if (!status && prov->status != -1)
290 status = prov->status;
292 p2p_buf_add_status(buf, status);
293 group_capab = P2P_GROUP_CAPAB_PERSISTENT_GROUP |
294 P2P_GROUP_CAPAB_PERSISTENT_RECONN;
295 if (p2p->cross_connect)
296 group_capab |= P2P_GROUP_CAPAB_CROSS_CONN;
297 if (p2p->cfg->p2p_intra_bss)
298 group_capab |= P2P_GROUP_CAPAB_INTRA_BSS_DIST;
299 p2p_buf_add_capability(buf, p2p->dev_capab &
300 ~P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY,
302 p2p_buf_add_device_info(buf, p2p, NULL);
304 if (persist_ssid && p2p->cfg->get_persistent_group &&
305 (status == P2P_SC_SUCCESS ||
306 status == P2P_SC_SUCCESS_DEFERRED)) {
307 u8 ssid[SSID_MAX_LEN];
309 u8 go_dev_addr[ETH_ALEN];
310 u8 intended_addr[ETH_ALEN];
312 persist = p2p->cfg->get_persistent_group(
314 dev->info.p2p_device_addr,
315 persist_ssid, persist_ssid_len, go_dev_addr,
316 ssid, &ssid_len, intended_addr);
318 p2p_buf_add_persistent_group_info(
319 buf, go_dev_addr, ssid, ssid_len);
320 if (!is_zero_ether_addr(intended_addr))
321 p2p_buf_add_intended_addr(
326 if (!persist && (prov->conncap & P2PS_SETUP_GROUP_OWNER))
327 p2ps_add_new_group_info(p2p, buf);
329 /* Add Operating Channel if conncap indicates GO */
330 if (persist || (prov->conncap & P2PS_SETUP_GROUP_OWNER)) {
334 p2p_go_select_channel(p2p, dev, &tmp);
336 if (p2p->op_reg_class && p2p->op_channel)
337 p2p_buf_add_operating_channel(
338 buf, p2p->cfg->country,
342 p2p_buf_add_operating_channel(
343 buf, p2p->cfg->country,
344 p2p->cfg->op_reg_class,
345 p2p->cfg->op_channel);
348 p2p_buf_add_channel_list(buf, p2p->cfg->country,
349 &p2p->cfg->channels);
351 if (!persist && (status == P2P_SC_SUCCESS ||
352 status == P2P_SC_SUCCESS_DEFERRED))
353 p2p_buf_add_connection_capability(buf, prov->conncap);
355 p2p_buf_add_advertisement_id(buf, adv_id, prov->adv_mac);
357 p2p_buf_add_config_timeout(buf, p2p->go_timeout,
358 p2p->client_timeout);
360 p2p_buf_add_session_id(buf, prov->session_id,
363 p2p_buf_add_feature_capability(buf, fcap_len, fcap);
364 p2p_buf_update_ie_hdr(buf, len);
365 } else if (status != P2P_SC_SUCCESS || adv_id) {
366 u8 *len = p2p_buf_add_ie_hdr(buf);
368 p2p_buf_add_status(buf, status);
371 p2p_buf_add_advertisement_id(buf, adv_id,
372 p2p->p2ps_prov->adv_mac);
374 p2p_buf_update_ie_hdr(buf, len);
377 /* WPS IE with Config Methods attribute */
378 p2p_build_wps_ie_config_methods(buf, config_methods);
380 #ifdef CONFIG_WIFI_DISPLAY
382 wpabuf_put_buf(buf, wfd_ie);
383 #endif /* CONFIG_WIFI_DISPLAY */
385 if (p2p->vendor_elem && p2p->vendor_elem[VENDOR_ELEM_P2P_PD_RESP])
386 wpabuf_put_buf(buf, p2p->vendor_elem[VENDOR_ELEM_P2P_PD_RESP]);
392 static int p2ps_setup_p2ps_prov(struct p2p_data *p2p, u32 adv_id,
393 u32 session_id, u16 method,
394 const u8 *session_mac, const u8 *adv_mac)
396 struct p2ps_provision *tmp;
398 if (!p2p->p2ps_prov) {
399 p2p->p2ps_prov = os_zalloc(sizeof(struct p2ps_provision) + 1);
403 os_memset(p2p->p2ps_prov, 0, sizeof(struct p2ps_provision) + 1);
406 tmp = p2p->p2ps_prov;
407 tmp->adv_id = adv_id;
408 tmp->session_id = session_id;
409 tmp->method = method;
410 os_memcpy(tmp->session_mac, session_mac, ETH_ALEN);
411 os_memcpy(tmp->adv_mac, adv_mac, ETH_ALEN);
418 static u8 p2ps_own_preferred_cpt(const u8 *cpt_priority, u8 req_cpt_mask)
422 for (i = 0; cpt_priority[i]; i++)
423 if (req_cpt_mask & cpt_priority[i])
424 return cpt_priority[i];
430 void p2p_process_prov_disc_req(struct p2p_data *p2p, const u8 *sa,
431 const u8 *data, size_t len, int rx_freq)
433 struct p2p_message msg;
434 struct p2p_device *dev;
436 enum p2p_status_code reject = P2P_SC_FAIL_INCOMPATIBLE_PARAMS;
439 struct p2ps_advertisement *p2ps_adv = NULL;
440 u8 conncap = P2PS_SETUP_NEW;
443 u8 session_mac[ETH_ALEN];
444 u8 adv_mac[ETH_ALEN];
446 int passwd_id = DEV_PW_DEFAULT;
448 u16 allowed_config_methods = WPS_CONFIG_DISPLAY | WPS_CONFIG_KEYPAD;
449 struct p2ps_feature_capab resp_fcap = { 0, 0 };
450 struct p2ps_feature_capab *req_fcap;
452 if (p2p_parse(data, len, &msg))
455 p2p_dbg(p2p, "Received Provision Discovery Request from " MACSTR
456 " with config methods 0x%x (freq=%d)",
457 MAC2STR(sa), msg.wps_config_methods, rx_freq);
458 group_mac = msg.intended_addr;
460 dev = p2p_get_device(p2p, sa);
461 if (dev == NULL || (dev->flags & P2P_DEV_PROBE_REQ_ONLY)) {
462 p2p_dbg(p2p, "Provision Discovery Request from unknown peer "
463 MACSTR, MAC2STR(sa));
465 if (p2p_add_device(p2p, sa, rx_freq, NULL, 0, data + 1, len - 1,
467 p2p_dbg(p2p, "Provision Discovery Request add device failed "
468 MACSTR, MAC2STR(sa));
470 } else if (msg.wfd_subelems) {
471 wpabuf_free(dev->info.wfd_subelems);
472 dev->info.wfd_subelems = wpabuf_dup(msg.wfd_subelems);
476 allowed_config_methods |= WPS_CONFIG_P2PS;
478 allowed_config_methods |= WPS_CONFIG_PUSHBUTTON;
480 if (!(msg.wps_config_methods & allowed_config_methods)) {
481 p2p_dbg(p2p, "Unsupported Config Methods in Provision Discovery Request");
485 /* Legacy (non-P2PS) - Unknown groups allowed for P2PS */
486 if (!msg.adv_id && msg.group_id) {
488 for (i = 0; i < p2p->num_groups; i++) {
489 if (p2p_group_is_group_id_match(p2p->groups[i],
494 if (i == p2p->num_groups) {
495 p2p_dbg(p2p, "PD request for unknown P2P Group ID - reject");
501 dev->flags &= ~(P2P_DEV_PD_PEER_DISPLAY |
502 P2P_DEV_PD_PEER_KEYPAD |
503 P2P_DEV_PD_PEER_P2PS);
505 /* Remove stale persistent groups */
506 if (p2p->cfg->remove_stale_groups) {
507 p2p->cfg->remove_stale_groups(
508 p2p->cfg->cb_ctx, dev->info.p2p_device_addr,
510 msg.persistent_ssid, msg.persistent_ssid_len);
513 if (msg.wps_config_methods & WPS_CONFIG_DISPLAY) {
514 p2p_dbg(p2p, "Peer " MACSTR
515 " requested us to show a PIN on display", MAC2STR(sa));
517 dev->flags |= P2P_DEV_PD_PEER_KEYPAD;
518 passwd_id = DEV_PW_USER_SPECIFIED;
519 } else if (msg.wps_config_methods & WPS_CONFIG_KEYPAD) {
520 p2p_dbg(p2p, "Peer " MACSTR
521 " requested us to write its PIN using keypad",
524 dev->flags |= P2P_DEV_PD_PEER_DISPLAY;
525 passwd_id = DEV_PW_REGISTRAR_SPECIFIED;
526 } else if (msg.wps_config_methods & WPS_CONFIG_P2PS) {
527 p2p_dbg(p2p, "Peer " MACSTR " requesting P2PS PIN",
530 dev->flags |= P2P_DEV_PD_PEER_P2PS;
531 passwd_id = DEV_PW_P2PS_DEFAULT;
534 reject = P2P_SC_SUCCESS;
536 os_memset(session_mac, 0, ETH_ALEN);
537 os_memset(adv_mac, 0, ETH_ALEN);
539 /* Note 1: A feature capability attribute structure can be changed
540 * in the future. The assumption is that such modifications are
541 * backwards compatible, therefore we allow processing of
542 * msg.feature_cap exceeding the size of the p2ps_feature_capab
544 * Note 2: Vverification of msg.feature_cap_len below has to be changed
545 * to allow 2 byte feature capability processing if struct
546 * p2ps_feature_capab is extended to include additional fields and it
547 * affects the structure size.
549 if (msg.adv_id && msg.session_id && msg.session_mac && msg.adv_mac &&
550 msg.feature_cap && msg.feature_cap_len >= sizeof(*req_fcap) &&
551 (msg.status || msg.conn_cap)) {
554 req_fcap = (struct p2ps_feature_capab *) msg.feature_cap;
556 os_memcpy(session_mac, msg.session_mac, ETH_ALEN);
557 os_memcpy(adv_mac, msg.adv_mac, ETH_ALEN);
559 session_id = WPA_GET_LE32(msg.session_id);
560 adv_id = WPA_GET_LE32(msg.adv_id);
563 p2ps_adv = p2p_service_p2ps_id(p2p, adv_id);
565 p2p_dbg(p2p, "adv_id: %x - p2ps_adv - %p", adv_id, p2ps_adv);
568 conncap = *msg.conn_cap;
569 remote_conncap = conncap;
572 auto_accept = p2ps_adv->auto_accept;
573 conncap = p2p->cfg->p2ps_group_capability(
574 p2p->cfg->cb_ctx, conncap, auto_accept);
576 p2p_dbg(p2p, "Conncap: local:%d remote:%d result:%d",
577 auto_accept, remote_conncap, conncap);
580 p2ps_own_preferred_cpt(p2ps_adv->cpt_priority,
584 "cpt: service:0x%x remote:0x%x result:0x%x",
585 p2ps_adv->cpt_mask, req_fcap->cpt,
588 if (!resp_fcap.cpt) {
590 "Incompatible P2PS feature capability CPT bitmask");
591 reject = P2P_SC_FAIL_INCOMPATIBLE_PARAMS;
592 } else if (p2ps_adv->config_methods &&
593 !(msg.wps_config_methods &
594 p2ps_adv->config_methods)) {
596 "Unsupported config methods in Provision Discovery Request (own=0x%x peer=0x%x)",
597 p2ps_adv->config_methods,
598 msg.wps_config_methods);
599 reject = P2P_SC_FAIL_INCOMPATIBLE_PARAMS;
600 } else if (!p2ps_adv->state) {
601 p2p_dbg(p2p, "P2PS state unavailable");
602 reject = P2P_SC_FAIL_UNABLE_TO_ACCOMMODATE;
603 } else if (!conncap) {
604 p2p_dbg(p2p, "Conncap resolution failed");
605 reject = P2P_SC_FAIL_INCOMPATIBLE_PARAMS;
608 if (msg.wps_config_methods & WPS_CONFIG_KEYPAD) {
609 p2p_dbg(p2p, "Keypad - always defer");
613 if (auto_accept || reject != P2P_SC_SUCCESS) {
614 struct p2ps_provision *tmp;
616 if (reject == P2P_SC_SUCCESS && !conncap) {
618 P2P_SC_FAIL_INCOMPATIBLE_PARAMS;
621 if (p2ps_setup_p2ps_prov(
622 p2p, adv_id, session_id,
623 msg.wps_config_methods,
624 session_mac, adv_mac) < 0) {
625 reject = P2P_SC_FAIL_UNABLE_TO_ACCOMMODATE;
629 tmp = p2p->p2ps_prov;
631 tmp->conncap = conncap;
632 tmp->status = P2P_SC_SUCCESS;
634 tmp->conncap = auto_accept;
635 tmp->status = P2P_SC_FAIL_INCOMPATIBLE_PARAMS;
638 if (reject != P2P_SC_SUCCESS)
641 } else if (!msg.status) {
642 reject = P2P_SC_FAIL_INCOMPATIBLE_PARAMS;
646 if (!msg.status && !auto_accept &&
647 (!p2p->p2ps_prov || p2p->p2ps_prov->adv_id != adv_id)) {
648 struct p2ps_provision *tmp;
651 reject = P2P_SC_FAIL_INCOMPATIBLE_PARAMS;
655 if (p2ps_setup_p2ps_prov(p2p, adv_id, session_id,
656 msg.wps_config_methods,
657 session_mac, adv_mac) < 0) {
658 reject = P2P_SC_FAIL_UNABLE_TO_ACCOMMODATE;
661 tmp = p2p->p2ps_prov;
662 reject = P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE;
663 tmp->status = reject;
668 *msg.status != P2P_SC_SUCCESS_DEFERRED) {
669 reject = *msg.status;
670 } else if (*msg.status == P2P_SC_SUCCESS_DEFERRED &&
672 u16 method = p2p->p2ps_prov->method;
674 conncap = p2p->cfg->p2ps_group_capability(
675 p2p->cfg->cb_ctx, remote_conncap,
676 p2p->p2ps_prov->conncap);
679 "Conncap: local:%d remote:%d result:%d",
680 p2p->p2ps_prov->conncap,
681 remote_conncap, conncap);
683 resp_fcap.cpt = p2ps_own_preferred_cpt(
684 p2p->p2ps_prov->cpt_priority,
688 "cpt: local:0x%x remote:0x%x result:0x%x",
689 p2p->p2ps_prov->cpt_mask,
690 req_fcap->cpt, resp_fcap.cpt);
693 * Ensure that if we asked for PIN originally,
694 * our method is consistent with original
697 if (method & WPS_CONFIG_DISPLAY)
698 method = WPS_CONFIG_KEYPAD;
699 else if (method & WPS_CONFIG_KEYPAD)
700 method = WPS_CONFIG_DISPLAY;
703 !(msg.wps_config_methods & method)) {
705 * Reject this "Deferred Accept*
706 * if incompatible conncap or method
709 P2P_SC_FAIL_INCOMPATIBLE_PARAMS;
710 } else if (!resp_fcap.cpt) {
712 "Incompatible P2PS feature capability CPT bitmask");
714 P2P_SC_FAIL_INCOMPATIBLE_PARAMS;
716 reject = P2P_SC_SUCCESS;
719 p2p->p2ps_prov->status = reject;
720 p2p->p2ps_prov->conncap = conncap;
726 if (reject == P2P_SC_SUCCESS ||
727 reject == P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE)
728 config_methods = msg.wps_config_methods;
731 resp = p2p_build_prov_disc_resp(p2p, dev, msg.dialog_token, reject,
732 config_methods, adv_id,
733 msg.group_id, msg.group_id_len,
735 msg.persistent_ssid_len,
736 (const u8 *) &resp_fcap,
739 p2p_parse_free(&msg);
742 p2p_dbg(p2p, "Sending Provision Discovery Response");
746 freq = p2p_channel_to_freq(p2p->cfg->reg_class,
749 p2p_dbg(p2p, "Unknown regulatory class/channel");
751 p2p_parse_free(&msg);
754 p2p->pending_action_state = P2P_PENDING_PD_RESPONSE;
755 if (p2p_send_action(p2p, freq, sa, p2p->cfg->dev_addr,
757 wpabuf_head(resp), wpabuf_len(resp), 200) < 0) {
758 p2p_dbg(p2p, "Failed to send Action frame");
760 p2p->send_action_in_progress = 1;
764 if (!p2p->cfg->p2ps_prov_complete) {
765 /* Don't emit anything */
766 } else if (msg.status && *msg.status != P2P_SC_SUCCESS &&
767 *msg.status != P2P_SC_SUCCESS_DEFERRED) {
768 reject = *msg.status;
769 p2p->cfg->p2ps_prov_complete(p2p->cfg->cb_ctx, reject,
770 sa, adv_mac, session_mac,
771 NULL, adv_id, session_id,
772 0, 0, msg.persistent_ssid,
773 msg.persistent_ssid_len,
774 0, 0, NULL, NULL, 0);
775 } else if (msg.status && *msg.status == P2P_SC_SUCCESS_DEFERRED &&
777 p2p->p2ps_prov->status = reject;
778 p2p->p2ps_prov->conncap = conncap;
780 if (reject != P2P_SC_SUCCESS)
781 p2p->cfg->p2ps_prov_complete(p2p->cfg->cb_ctx, reject,
782 sa, adv_mac, session_mac,
784 session_id, conncap, 0,
786 msg.persistent_ssid_len, 0,
789 p2p->cfg->p2ps_prov_complete(p2p->cfg->cb_ctx,
791 sa, adv_mac, session_mac,
796 msg.persistent_ssid_len, 0,
798 (const u8 *) &resp_fcap,
800 } else if (msg.status && p2p->p2ps_prov) {
801 p2p->p2ps_prov->status = P2P_SC_SUCCESS;
802 p2p->cfg->p2ps_prov_complete(p2p->cfg->cb_ctx, *msg.status, sa,
803 adv_mac, session_mac, group_mac,
804 adv_id, session_id, conncap,
807 msg.persistent_ssid_len,
809 (const u8 *) &resp_fcap,
811 } else if (msg.status) {
812 } else if (auto_accept && reject == P2P_SC_SUCCESS) {
813 p2p->cfg->p2ps_prov_complete(p2p->cfg->cb_ctx, P2P_SC_SUCCESS,
814 sa, adv_mac, session_mac,
815 group_mac, adv_id, session_id,
818 msg.persistent_ssid_len,
820 (const u8 *) &resp_fcap,
822 } else if (reject == P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE &&
823 (!msg.session_info || !msg.session_info_len)) {
824 p2p->p2ps_prov->method = msg.wps_config_methods;
826 p2p->cfg->p2ps_prov_complete(p2p->cfg->cb_ctx, P2P_SC_SUCCESS,
827 sa, adv_mac, session_mac,
828 group_mac, adv_id, session_id,
831 msg.persistent_ssid_len,
833 (const u8 *) &resp_fcap,
835 } else if (reject == P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE) {
836 size_t buf_len = msg.session_info_len;
837 char *buf = os_malloc(2 * buf_len + 1);
840 p2p->p2ps_prov->method = msg.wps_config_methods;
842 utf8_escape((char *) msg.session_info, buf_len,
843 buf, 2 * buf_len + 1);
845 p2p->cfg->p2ps_prov_complete(
846 p2p->cfg->cb_ctx, P2P_SC_SUCCESS, sa,
847 adv_mac, session_mac, group_mac, adv_id,
848 session_id, conncap, passwd_id,
849 msg.persistent_ssid, msg.persistent_ssid_len,
851 (const u8 *) &resp_fcap, sizeof(resp_fcap));
858 * prov_disc_req callback is used to generate P2P-PROV-DISC-ENTER-PIN,
859 * P2P-PROV-DISC-SHOW-PIN, and P2P-PROV-DISC-PBC-REQ events.
860 * Call it either on legacy P2P PD or on P2PS PD only if we need to
863 * The callback is called in the following cases:
864 * 1. Legacy P2P PD request, response status SUCCESS
865 * 2. P2PS advertiser, method: DISPLAY, autoaccept: TRUE,
866 * response status: SUCCESS
867 * 3. P2PS advertiser, method DISPLAY, autoaccept: FALSE,
868 * response status: INFO_CURRENTLY_UNAVAILABLE
869 * 4. P2PS advertiser, method: KEYPAD, autoaccept==any,
870 * response status: INFO_CURRENTLY_UNAVAILABLE
871 * 5. P2PS follow-on with SUCCESS_DEFERRED,
872 * advertiser role: DISPLAY, autoaccept: FALSE,
873 * seeker: KEYPAD, response status: SUCCESS
875 if (p2p->cfg->prov_disc_req &&
876 ((reject == P2P_SC_SUCCESS && !msg.adv_id) ||
878 (reject == P2P_SC_SUCCESS ||
879 reject == P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE) &&
880 passwd_id == DEV_PW_USER_SPECIFIED) ||
882 reject == P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE &&
883 passwd_id == DEV_PW_REGISTRAR_SPECIFIED) ||
884 (reject == P2P_SC_SUCCESS &&
885 msg.status && *msg.status == P2P_SC_SUCCESS_DEFERRED &&
886 passwd_id == DEV_PW_REGISTRAR_SPECIFIED))) {
887 const u8 *dev_addr = sa;
889 if (msg.p2p_device_addr)
890 dev_addr = msg.p2p_device_addr;
891 p2p->cfg->prov_disc_req(p2p->cfg->cb_ctx, sa,
892 msg.wps_config_methods,
893 dev_addr, msg.pri_dev_type,
894 msg.device_name, msg.config_methods,
895 msg.capability ? msg.capability[0] : 0,
896 msg.capability ? msg.capability[1] :
898 msg.group_id, msg.group_id_len);
901 if (dev && reject == P2P_SC_SUCCESS) {
902 switch (config_methods) {
903 case WPS_CONFIG_DISPLAY:
904 dev->wps_prov_info = WPS_CONFIG_KEYPAD;
906 case WPS_CONFIG_KEYPAD:
907 dev->wps_prov_info = WPS_CONFIG_DISPLAY;
909 case WPS_CONFIG_PUSHBUTTON:
910 dev->wps_prov_info = WPS_CONFIG_PUSHBUTTON;
912 case WPS_CONFIG_P2PS:
913 dev->wps_prov_info = WPS_CONFIG_P2PS;
916 dev->wps_prov_info = 0;
920 if (msg.intended_addr)
921 os_memcpy(dev->interface_addr, msg.intended_addr,
924 p2p_parse_free(&msg);
928 static int p2p_validate_p2ps_pd_resp(struct p2p_data *p2p,
929 struct p2p_message *msg)
936 #define P2PS_PD_RESP_CHECK(_val, _attr) \
938 if ((_val) && !msg->_attr) { \
939 p2p_dbg(p2p, "P2PS PD Response missing " #_attr); \
944 P2PS_PD_RESP_CHECK(1, status);
945 P2PS_PD_RESP_CHECK(1, adv_id);
946 P2PS_PD_RESP_CHECK(1, adv_mac);
947 P2PS_PD_RESP_CHECK(1, capability);
948 P2PS_PD_RESP_CHECK(1, p2p_device_info);
949 P2PS_PD_RESP_CHECK(1, session_id);
950 P2PS_PD_RESP_CHECK(1, session_mac);
951 P2PS_PD_RESP_CHECK(1, feature_cap);
953 session_id = WPA_GET_LE32(msg->session_id);
954 adv_id = WPA_GET_LE32(msg->adv_id);
956 if (p2p->p2ps_prov->session_id != session_id) {
958 "Ignore PD Response with unexpected Session ID");
962 if (os_memcmp(p2p->p2ps_prov->session_mac, msg->session_mac,
965 "Ignore PD Response with unexpected Session MAC");
969 if (p2p->p2ps_prov->adv_id != adv_id) {
971 "Ignore PD Response with unexpected Advertisement ID");
975 if (os_memcmp(p2p->p2ps_prov->adv_mac, msg->adv_mac, ETH_ALEN) != 0) {
977 "Ignore PD Response with unexpected Advertisement MAC");
981 if (msg->listen_channel) {
983 "Ignore malformed PD Response - unexpected Listen Channel");
987 if (*msg->status == P2P_SC_SUCCESS &&
988 !(!!msg->conn_cap ^ !!msg->persistent_dev)) {
990 "Ignore malformed PD Response - either conn_cap or persistent group should be present");
994 if (msg->persistent_dev && *msg->status != P2P_SC_SUCCESS) {
996 "Ignore malformed PD Response - persistent group is present, but the status isn't success");
1000 if (msg->conn_cap) {
1001 conn_cap_go = *msg->conn_cap == P2PS_SETUP_GROUP_OWNER;
1002 conn_cap_cli = *msg->conn_cap == P2PS_SETUP_CLIENT;
1005 P2PS_PD_RESP_CHECK(msg->persistent_dev || conn_cap_go || conn_cap_cli,
1007 P2PS_PD_RESP_CHECK(msg->persistent_dev || conn_cap_go || conn_cap_cli,
1010 P2PS_PD_RESP_CHECK(conn_cap_go, group_id);
1011 P2PS_PD_RESP_CHECK(conn_cap_go, intended_addr);
1012 P2PS_PD_RESP_CHECK(conn_cap_go, operating_channel);
1014 * TODO: Also validate that operating channel is present if the device
1015 * is a GO in a persistent group. We can't do it here since we don't
1016 * know what is the role of the peer. It should be probably done in
1017 * p2ps_prov_complete callback, but currently operating channel isn't
1021 #undef P2PS_PD_RESP_CHECK
1027 void p2p_process_prov_disc_resp(struct p2p_data *p2p, const u8 *sa,
1028 const u8 *data, size_t len)
1030 struct p2p_message msg;
1031 struct p2p_device *dev;
1032 u16 report_config_methods = 0, req_config_methods;
1033 u8 status = P2P_SC_SUCCESS;
1035 u8 conncap = P2PS_SETUP_NEW;
1036 u8 adv_mac[ETH_ALEN];
1037 const u8 *group_mac;
1038 int passwd_id = DEV_PW_DEFAULT;
1041 if (p2p_parse(data, len, &msg))
1044 if (p2p->p2ps_prov && p2p_validate_p2ps_pd_resp(p2p, &msg)) {
1045 p2p_parse_free(&msg);
1049 /* Parse the P2PS members present */
1051 status = *msg.status;
1053 group_mac = msg.intended_addr;
1056 os_memcpy(adv_mac, msg.adv_mac, ETH_ALEN);
1058 os_memset(adv_mac, 0, ETH_ALEN);
1061 adv_id = WPA_GET_LE32(msg.adv_id);
1064 conncap = *msg.conn_cap;
1066 /* Switch bits to local relative */
1068 case P2PS_SETUP_GROUP_OWNER:
1069 conncap = P2PS_SETUP_CLIENT;
1071 case P2PS_SETUP_CLIENT:
1072 conncap = P2PS_SETUP_GROUP_OWNER;
1077 p2p_dbg(p2p, "Received Provision Discovery Response from " MACSTR
1078 " with config methods 0x%x",
1079 MAC2STR(sa), msg.wps_config_methods);
1081 dev = p2p_get_device(p2p, sa);
1082 if (dev == NULL || !dev->req_config_methods) {
1083 p2p_dbg(p2p, "Ignore Provision Discovery Response from " MACSTR
1084 " with no pending request", MAC2STR(sa));
1085 p2p_parse_free(&msg);
1089 if (dev->dialog_token != msg.dialog_token) {
1090 p2p_dbg(p2p, "Ignore Provision Discovery Response with unexpected Dialog Token %u (expected %u)",
1091 msg.dialog_token, dev->dialog_token);
1092 p2p_parse_free(&msg);
1096 if (p2p->pending_action_state == P2P_PENDING_PD) {
1097 os_memset(p2p->pending_pd_devaddr, 0, ETH_ALEN);
1098 p2p->pending_action_state = P2P_NO_PENDING_ACTION;
1101 p2ps_seeker = p2p->p2ps_prov && p2p->p2ps_prov->pd_seeker;
1104 * Use a local copy of the requested config methods since
1105 * p2p_reset_pending_pd() can clear this in the peer entry.
1107 req_config_methods = dev->req_config_methods;
1110 * If the response is from the peer to whom a user initiated request
1111 * was sent earlier, we reset that state info here.
1113 if (p2p->user_initiated_pd &&
1114 os_memcmp(p2p->pending_pd_devaddr, sa, ETH_ALEN) == 0)
1115 p2p_reset_pending_pd(p2p);
1117 if (msg.wps_config_methods != req_config_methods) {
1118 p2p_dbg(p2p, "Peer rejected our Provision Discovery Request (received config_methods 0x%x expected 0x%x",
1119 msg.wps_config_methods, req_config_methods);
1120 if (p2p->cfg->prov_disc_fail)
1121 p2p->cfg->prov_disc_fail(p2p->cfg->cb_ctx, sa,
1122 P2P_PROV_DISC_REJECTED,
1123 adv_id, adv_mac, NULL);
1124 p2p_parse_free(&msg);
1125 p2ps_prov_free(p2p);
1129 report_config_methods = req_config_methods;
1130 dev->flags &= ~(P2P_DEV_PD_PEER_DISPLAY |
1131 P2P_DEV_PD_PEER_KEYPAD |
1132 P2P_DEV_PD_PEER_P2PS);
1133 if (req_config_methods & WPS_CONFIG_DISPLAY) {
1134 p2p_dbg(p2p, "Peer " MACSTR
1135 " accepted to show a PIN on display", MAC2STR(sa));
1136 dev->flags |= P2P_DEV_PD_PEER_DISPLAY;
1137 passwd_id = DEV_PW_REGISTRAR_SPECIFIED;
1138 } else if (msg.wps_config_methods & WPS_CONFIG_KEYPAD) {
1139 p2p_dbg(p2p, "Peer " MACSTR
1140 " accepted to write our PIN using keypad",
1142 dev->flags |= P2P_DEV_PD_PEER_KEYPAD;
1143 passwd_id = DEV_PW_USER_SPECIFIED;
1144 } else if (msg.wps_config_methods & WPS_CONFIG_P2PS) {
1145 p2p_dbg(p2p, "Peer " MACSTR " accepted P2PS PIN",
1147 dev->flags |= P2P_DEV_PD_PEER_P2PS;
1148 passwd_id = DEV_PW_P2PS_DEFAULT;
1151 if ((msg.conn_cap || msg.persistent_dev) &&
1152 (status == P2P_SC_SUCCESS || status == P2P_SC_SUCCESS_DEFERRED) &&
1154 if (p2p->cfg->p2ps_prov_complete) {
1155 p2p->cfg->p2ps_prov_complete(
1156 p2p->cfg->cb_ctx, status, sa, adv_mac,
1157 p2p->p2ps_prov->session_mac,
1158 group_mac, adv_id, p2p->p2ps_prov->session_id,
1159 conncap, passwd_id, msg.persistent_ssid,
1160 msg.persistent_ssid_len, 1, 0, NULL,
1161 msg.feature_cap, msg.feature_cap_len);
1163 p2ps_prov_free(p2p);
1164 } else if (status != P2P_SC_SUCCESS &&
1165 status != P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE &&
1166 status != P2P_SC_SUCCESS_DEFERRED && p2p->p2ps_prov) {
1167 if (p2p->cfg->p2ps_prov_complete)
1168 p2p->cfg->p2ps_prov_complete(
1169 p2p->cfg->cb_ctx, status, sa, adv_mac,
1170 p2p->p2ps_prov->session_mac,
1171 group_mac, adv_id, p2p->p2ps_prov->session_id,
1172 0, 0, NULL, 0, 1, 0, NULL, NULL, 0);
1173 p2ps_prov_free(p2p);
1176 if (status == P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE) {
1177 if (p2p->cfg->remove_stale_groups) {
1178 p2p->cfg->remove_stale_groups(p2p->cfg->cb_ctx,
1179 dev->info.p2p_device_addr,
1183 if (msg.session_info && msg.session_info_len) {
1184 size_t info_len = msg.session_info_len;
1185 char *deferred_sess_resp = os_malloc(2 * info_len + 1);
1187 if (!deferred_sess_resp) {
1188 p2p_parse_free(&msg);
1189 p2ps_prov_free(p2p);
1192 utf8_escape((char *) msg.session_info, info_len,
1193 deferred_sess_resp, 2 * info_len + 1);
1195 if (p2p->cfg->prov_disc_fail)
1196 p2p->cfg->prov_disc_fail(
1197 p2p->cfg->cb_ctx, sa,
1198 P2P_PROV_DISC_INFO_UNAVAILABLE,
1200 deferred_sess_resp);
1201 os_free(deferred_sess_resp);
1203 if (p2p->cfg->prov_disc_fail)
1204 p2p->cfg->prov_disc_fail(
1205 p2p->cfg->cb_ctx, sa,
1206 P2P_PROV_DISC_INFO_UNAVAILABLE,
1207 adv_id, adv_mac, NULL);
1208 } else if (status != P2P_SC_SUCCESS) {
1209 p2p_dbg(p2p, "Peer rejected our Provision Discovery Request");
1210 if (p2p->cfg->prov_disc_fail)
1211 p2p->cfg->prov_disc_fail(p2p->cfg->cb_ctx, sa,
1212 P2P_PROV_DISC_REJECTED,
1213 adv_id, adv_mac, NULL);
1214 p2p_parse_free(&msg);
1215 p2ps_prov_free(p2p);
1219 /* Store the provisioning info */
1220 dev->wps_prov_info = msg.wps_config_methods;
1221 if (msg.intended_addr)
1222 os_memcpy(dev->interface_addr, msg.intended_addr, ETH_ALEN);
1224 p2p_parse_free(&msg);
1227 dev->req_config_methods = 0;
1228 p2p->cfg->send_action_done(p2p->cfg->cb_ctx);
1229 if (dev->flags & P2P_DEV_PD_BEFORE_GO_NEG) {
1230 p2p_dbg(p2p, "Start GO Neg after the PD-before-GO-Neg workaround with "
1231 MACSTR, MAC2STR(dev->info.p2p_device_addr));
1232 dev->flags &= ~P2P_DEV_PD_BEFORE_GO_NEG;
1233 p2p_connect_send(p2p, dev);
1238 * prov_disc_resp callback is used to generate P2P-PROV-DISC-ENTER-PIN,
1239 * P2P-PROV-DISC-SHOW-PIN, and P2P-PROV-DISC-PBC-REQ events.
1240 * Call it only for a legacy P2P PD or for P2PS PD scenarios where
1241 * show/enter PIN events are needed.
1243 * The callback is called in the following cases:
1244 * 1. Legacy P2P PD response with a status SUCCESS
1245 * 2. P2PS, advertiser method: DISPLAY, autoaccept: true,
1246 * response status: SUCCESS, local method KEYPAD
1247 * 3. P2PS, advertiser method: KEYPAD,Seeker side,
1248 * response status: INFO_CURRENTLY_UNAVAILABLE,
1249 * local method: DISPLAY
1251 if (p2p->cfg->prov_disc_resp &&
1252 ((status == P2P_SC_SUCCESS && !adv_id) ||
1253 (p2ps_seeker && status == P2P_SC_SUCCESS &&
1254 passwd_id == DEV_PW_REGISTRAR_SPECIFIED) ||
1256 status == P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE &&
1257 passwd_id == DEV_PW_USER_SPECIFIED)))
1258 p2p->cfg->prov_disc_resp(p2p->cfg->cb_ctx, sa,
1259 report_config_methods);
1261 if (p2p->state == P2P_PD_DURING_FIND) {
1262 p2p_clear_timeout(p2p);
1263 p2p_continue_find(p2p);
1268 int p2p_send_prov_disc_req(struct p2p_data *p2p, struct p2p_device *dev,
1269 int join, int force_freq)
1277 freq = dev->listen_freq > 0 ? dev->listen_freq :
1280 p2p_dbg(p2p, "No Listen/Operating frequency known for the peer "
1281 MACSTR " to send Provision Discovery Request",
1282 MAC2STR(dev->info.p2p_device_addr));
1286 if (dev->flags & P2P_DEV_GROUP_CLIENT_ONLY) {
1287 if (!(dev->info.dev_capab &
1288 P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY)) {
1289 p2p_dbg(p2p, "Cannot use PD with P2P Device " MACSTR
1290 " that is in a group and is not discoverable",
1291 MAC2STR(dev->info.p2p_device_addr));
1294 /* TODO: use device discoverability request through GO */
1297 if (p2p->p2ps_prov) {
1298 if (p2p->p2ps_prov->status == P2P_SC_SUCCESS_DEFERRED) {
1299 if (p2p->p2ps_prov->method == WPS_CONFIG_DISPLAY)
1300 dev->req_config_methods = WPS_CONFIG_KEYPAD;
1301 else if (p2p->p2ps_prov->method == WPS_CONFIG_KEYPAD)
1302 dev->req_config_methods = WPS_CONFIG_DISPLAY;
1304 dev->req_config_methods = WPS_CONFIG_P2PS;
1306 /* Order of preference, based on peer's capabilities */
1307 if (p2p->p2ps_prov->method)
1308 dev->req_config_methods =
1309 p2p->p2ps_prov->method;
1310 else if (dev->info.config_methods & WPS_CONFIG_P2PS)
1311 dev->req_config_methods = WPS_CONFIG_P2PS;
1312 else if (dev->info.config_methods & WPS_CONFIG_DISPLAY)
1313 dev->req_config_methods = WPS_CONFIG_DISPLAY;
1315 dev->req_config_methods = WPS_CONFIG_KEYPAD;
1318 "Building PD Request based on P2PS config method 0x%x status %d --> req_config_methods 0x%x",
1319 p2p->p2ps_prov->method, p2p->p2ps_prov->status,
1320 dev->req_config_methods);
1323 req = p2p_build_prov_disc_req(p2p, dev, join);
1327 if (p2p->state != P2P_IDLE)
1328 p2p_stop_listen_for_freq(p2p, freq);
1329 p2p->pending_action_state = P2P_PENDING_PD;
1330 if (p2p_send_action(p2p, freq, dev->info.p2p_device_addr,
1331 p2p->cfg->dev_addr, dev->info.p2p_device_addr,
1332 wpabuf_head(req), wpabuf_len(req), 200) < 0) {
1333 p2p_dbg(p2p, "Failed to send Action frame");
1338 os_memcpy(p2p->pending_pd_devaddr, dev->info.p2p_device_addr, ETH_ALEN);
1345 int p2p_prov_disc_req(struct p2p_data *p2p, const u8 *peer_addr,
1346 struct p2ps_provision *p2ps_prov,
1347 u16 config_methods, int join, int force_freq,
1348 int user_initiated_pd)
1350 struct p2p_device *dev;
1352 dev = p2p_get_device(p2p, peer_addr);
1354 dev = p2p_get_device_interface(p2p, peer_addr);
1355 if (dev == NULL || (dev->flags & P2P_DEV_PROBE_REQ_ONLY)) {
1356 p2p_dbg(p2p, "Provision Discovery Request destination " MACSTR
1357 " not yet known", MAC2STR(peer_addr));
1362 p2p_dbg(p2p, "Provision Discovery Request with " MACSTR
1363 " (config methods 0x%x)",
1364 MAC2STR(peer_addr), config_methods);
1365 if (config_methods == 0 && !p2ps_prov) {
1370 if (p2ps_prov && p2ps_prov->status == P2P_SC_SUCCESS_DEFERRED &&
1372 /* Use cached method from deferred provisioning */
1373 p2ps_prov->method = p2p->p2ps_prov->method;
1376 /* Reset provisioning info */
1377 dev->wps_prov_info = 0;
1378 p2ps_prov_free(p2p);
1379 p2p->p2ps_prov = p2ps_prov;
1381 dev->req_config_methods = config_methods;
1383 dev->flags |= P2P_DEV_PD_FOR_JOIN;
1385 dev->flags &= ~P2P_DEV_PD_FOR_JOIN;
1387 if (p2p->state != P2P_IDLE && p2p->state != P2P_SEARCH &&
1388 p2p->state != P2P_LISTEN_ONLY) {
1389 p2p_dbg(p2p, "Busy with other operations; postpone Provision Discovery Request with "
1390 MACSTR " (config methods 0x%x)",
1391 MAC2STR(peer_addr), config_methods);
1395 p2p->user_initiated_pd = user_initiated_pd;
1396 p2p->pd_force_freq = force_freq;
1398 if (p2p->user_initiated_pd)
1399 p2p->pd_retries = MAX_PROV_DISC_REQ_RETRIES;
1402 * Assign dialog token here to use the same value in each retry within
1403 * the same PD exchange.
1405 dev->dialog_token++;
1406 if (dev->dialog_token == 0)
1407 dev->dialog_token = 1;
1409 return p2p_send_prov_disc_req(p2p, dev, join, force_freq);
1413 void p2p_reset_pending_pd(struct p2p_data *p2p)
1415 struct p2p_device *dev;
1417 dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) {
1418 if (os_memcmp(p2p->pending_pd_devaddr,
1419 dev->info.p2p_device_addr, ETH_ALEN))
1421 if (!dev->req_config_methods)
1423 if (dev->flags & P2P_DEV_PD_FOR_JOIN)
1425 /* Reset the config methods of the device */
1426 dev->req_config_methods = 0;
1429 p2p->user_initiated_pd = 0;
1430 os_memset(p2p->pending_pd_devaddr, 0, ETH_ALEN);
1431 p2p->pd_retries = 0;
1432 p2p->pd_force_freq = 0;
1436 void p2ps_prov_free(struct p2p_data *p2p)
1438 os_free(p2p->p2ps_prov);
1439 p2p->p2ps_prov = NULL;