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];
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,
60 p2p_buf_add_intended_addr(buf, intended_addr);
63 p2p_build_ssid(p2p, p2p->ssid, &p2p->ssid_len);
67 /* Add pre-composed P2P Group ID */
68 p2p_buf_add_group_id(buf, p2p->cfg->dev_addr,
69 p2p->ssid, p2p->ssid_len);
72 p2p_buf_add_intended_addr(
73 buf, p2p->intended_addr);
75 p2p_buf_add_intended_addr(
76 buf, p2p->cfg->dev_addr);
81 static void p2ps_add_pd_req_attrs(struct p2p_data *p2p, struct p2p_device *dev,
82 struct wpabuf *buf, u16 config_methods)
84 struct p2ps_provision *prov = p2p->p2ps_prov;
85 u8 feat_cap_mask[] = { 1, 0 };
89 u8 go_dev_addr[ETH_ALEN];
91 /* If we might be explicite group owner, add GO details */
92 if (prov->conncap & (P2PS_SETUP_GROUP_OWNER |
94 p2ps_add_new_group_info(p2p, buf);
96 if (prov->status >= 0)
97 p2p_buf_add_status(buf, (u8) prov->status);
99 prov->method = config_methods;
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);
107 /* Add Operating Channel if conncap includes GO */
109 (prov->conncap & (P2PS_SETUP_GROUP_OWNER |
113 p2p_go_select_channel(p2p, dev, &tmp);
115 if (p2p->op_reg_class && p2p->op_channel)
116 p2p_buf_add_operating_channel(buf, p2p->cfg->country,
120 p2p_buf_add_operating_channel(buf, p2p->cfg->country,
121 p2p->cfg->op_reg_class,
122 p2p->cfg->op_channel);
125 p2p_buf_add_channel_list(buf, p2p->cfg->country, &p2p->cfg->channels);
128 p2p_buf_add_session_info(buf, prov->info);
130 p2p_buf_add_connection_capability(buf, prov->conncap);
132 p2p_buf_add_advertisement_id(buf, prov->adv_id, prov->adv_mac);
134 if (shared_group || prov->conncap == P2PS_SETUP_NEW ||
136 (P2PS_SETUP_GROUP_OWNER | P2PS_SETUP_NEW) ||
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);
144 p2p_buf_add_listen_channel(buf, p2p->cfg->country, p2p->cfg->reg_class,
147 p2p_buf_add_session_id(buf, prov->session_id, prov->session_mac);
149 p2p_buf_add_feature_capability(buf, sizeof(feat_cap_mask),
153 p2p_buf_add_persistent_group_info(buf, go_dev_addr,
158 static struct wpabuf * p2p_build_prov_disc_req(struct p2p_data *p2p,
159 struct p2p_device *dev,
165 u8 dialog_token = dev->dialog_token;
166 u16 config_methods = dev->req_config_methods;
167 struct p2p_device *go = join ? dev : NULL;
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 */
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]);
179 extra += os_strlen(p2p->p2ps_prov->info) + 1 +
180 sizeof(struct p2ps_provision);
182 buf = wpabuf_alloc(1000 + extra);
186 p2p_buf_add_public_action_hdr(buf, P2P_PROV_DISC_REQ, dialog_token);
188 len = p2p_buf_add_ie_hdr(buf);
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;
199 p2p_buf_add_capability(buf, p2p->dev_capab &
200 ~P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY,
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);
206 p2p_buf_add_group_id(buf, go->info.p2p_device_addr,
207 go->oper_ssid, go->oper_ssid_len);
209 p2p_buf_update_ie_hdr(buf, len);
211 /* WPS IE with Config Methods attribute */
212 p2p_build_wps_ie_config_methods(buf, config_methods);
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 */
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]);
226 static struct wpabuf * p2p_build_prov_disc_resp(struct p2p_data *p2p,
227 struct p2p_device *dev,
229 enum p2p_status_code status,
234 const u8 *persist_ssid,
235 size_t persist_ssid_len)
241 #ifdef CONFIG_WIFI_DISPLAY
242 struct wpabuf *wfd_ie = p2p->wfd_ie_prov_disc_resp;
243 if (wfd_ie && group_id) {
245 for (i = 0; i < p2p->num_groups; i++) {
246 struct p2p_group *g = p2p->groups[i];
248 if (!p2p_group_is_group_id_match(g, group_id,
251 ie = p2p_group_get_wfd_ie(g);
259 extra = wpabuf_len(wfd_ie);
260 #endif /* CONFIG_WIFI_DISPLAY */
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]);
265 buf = wpabuf_alloc(1000 + extra);
269 p2p_buf_add_public_action_hdr(buf, P2P_PROV_DISC_RESP, dialog_token);
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;
278 if (!status && prov->status != -1)
279 status = prov->status;
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,
291 p2p_buf_add_device_info(buf, p2p, NULL);
293 if (persist_ssid && p2p->cfg->get_persistent_group &&
294 (status == P2P_SC_SUCCESS ||
295 status == P2P_SC_SUCCESS_DEFERRED)) {
298 u8 go_dev_addr[ETH_ALEN];
300 persist = p2p->cfg->get_persistent_group(
302 dev->info.p2p_device_addr,
303 persist_ssid, persist_ssid_len, go_dev_addr,
306 p2p_buf_add_persistent_group_info(
307 buf, go_dev_addr, ssid, ssid_len);
310 if (!persist && (prov->conncap & P2PS_SETUP_GROUP_OWNER))
311 p2ps_add_new_group_info(p2p, buf);
313 /* Add Operating Channel if conncap indicates GO */
314 if (persist || (prov->conncap & P2PS_SETUP_GROUP_OWNER)) {
318 p2p_go_select_channel(p2p, dev, &tmp);
320 if (p2p->op_reg_class && p2p->op_channel)
321 p2p_buf_add_operating_channel(
322 buf, p2p->cfg->country,
326 p2p_buf_add_operating_channel(
327 buf, p2p->cfg->country,
328 p2p->cfg->op_reg_class,
329 p2p->cfg->op_channel);
332 p2p_buf_add_channel_list(buf, p2p->cfg->country,
333 &p2p->cfg->channels);
335 if (!persist && (status == P2P_SC_SUCCESS ||
336 status == P2P_SC_SUCCESS_DEFERRED))
337 p2p_buf_add_connection_capability(buf, prov->conncap);
339 p2p_buf_add_advertisement_id(buf, adv_id, prov->adv_mac);
341 p2p_buf_add_config_timeout(buf, p2p->go_timeout,
342 p2p->client_timeout);
344 p2p_buf_add_session_id(buf, prov->session_id,
347 p2p_buf_add_feature_capability(buf, sizeof(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);
353 p2p_buf_add_status(buf, status);
356 p2p_buf_add_advertisement_id(buf, adv_id,
357 p2p->p2ps_prov->adv_mac);
359 p2p_buf_update_ie_hdr(buf, len);
362 /* WPS IE with Config Methods attribute */
363 p2p_build_wps_ie_config_methods(buf, config_methods);
365 #ifdef CONFIG_WIFI_DISPLAY
367 wpabuf_put_buf(buf, wfd_ie);
368 #endif /* CONFIG_WIFI_DISPLAY */
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]);
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)
381 struct p2ps_provision *tmp;
383 if (!p2p->p2ps_prov) {
384 p2p->p2ps_prov = os_zalloc(sizeof(struct p2ps_provision) + 1);
388 os_memset(p2p->p2ps_prov, 0, sizeof(struct p2ps_provision) + 1);
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);
403 void p2p_process_prov_disc_req(struct p2p_data *p2p, const u8 *sa,
404 const u8 *data, size_t len, int rx_freq)
406 struct p2p_message msg;
407 struct p2p_device *dev;
409 enum p2p_status_code reject = P2P_SC_FAIL_INCOMPATIBLE_PARAMS;
412 struct p2ps_advertisement *p2ps_adv = NULL;
413 u8 conncap = P2PS_SETUP_NEW;
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;
422 if (p2p_parse(data, len, &msg))
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);
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));
434 if (p2p_add_device(p2p, sa, rx_freq, NULL, 0, data + 1, len - 1,
436 p2p_dbg(p2p, "Provision Discovery Request add device failed "
437 MACSTR, MAC2STR(sa));
439 } else if (msg.wfd_subelems) {
440 wpabuf_free(dev->info.wfd_subelems);
441 dev->info.wfd_subelems = wpabuf_dup(msg.wfd_subelems);
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");
451 /* Legacy (non-P2PS) - Unknown groups allowed for P2PS */
452 if (!msg.adv_id && msg.group_id) {
454 for (i = 0; i < p2p->num_groups; i++) {
455 if (p2p_group_is_group_id_match(p2p->groups[i],
460 if (i == p2p->num_groups) {
461 p2p_dbg(p2p, "PD request for unknown P2P Group ID - reject");
467 dev->flags &= ~(P2P_DEV_PD_PEER_DISPLAY |
468 P2P_DEV_PD_PEER_KEYPAD |
469 P2P_DEV_PD_PEER_P2PS);
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,
476 msg.persistent_ssid, msg.persistent_ssid_len);
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));
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",
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",
496 dev->flags |= P2P_DEV_PD_PEER_P2PS;
497 passwd_id = DEV_PW_P2PS_DEFAULT;
500 reject = P2P_SC_SUCCESS;
502 os_memset(session_mac, 0, ETH_ALEN);
503 os_memset(adv_mac, 0, ETH_ALEN);
504 os_memset(group_mac, 0, ETH_ALEN);
506 if (msg.adv_id && msg.session_id && msg.session_mac && msg.adv_mac &&
507 (msg.status || msg.conn_cap)) {
510 if (msg.intended_addr)
511 os_memcpy(group_mac, msg.intended_addr, ETH_ALEN);
513 os_memcpy(session_mac, msg.session_mac, ETH_ALEN);
514 os_memcpy(adv_mac, msg.adv_mac, ETH_ALEN);
516 session_id = WPA_GET_LE32(msg.session_id);
517 adv_id = WPA_GET_LE32(msg.adv_id);
520 p2ps_adv = p2p_service_p2ps_id(p2p, adv_id);
522 p2p_dbg(p2p, "adv_id: %x - p2ps_adv - %p", adv_id, p2ps_adv);
525 conncap = *msg.conn_cap;
526 remote_conncap = conncap;
529 auto_accept = p2ps_adv->auto_accept;
530 conncap = p2p->cfg->p2ps_group_capability(
531 p2p->cfg->cb_ctx, conncap, auto_accept);
533 p2p_dbg(p2p, "Conncap: local:%d remote:%d result:%d",
534 auto_accept, remote_conncap, conncap);
536 if (p2ps_adv->config_methods &&
537 !(msg.wps_config_methods &
538 p2ps_adv->config_methods)) {
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;
552 if (msg.wps_config_methods & WPS_CONFIG_KEYPAD) {
553 p2p_dbg(p2p, "Keypad - always defer");
557 if (auto_accept || reject != P2P_SC_SUCCESS) {
558 struct p2ps_provision *tmp;
560 if (reject == P2P_SC_SUCCESS && !conncap) {
562 P2P_SC_FAIL_INCOMPATIBLE_PARAMS;
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;
573 tmp = p2p->p2ps_prov;
575 tmp->conncap = conncap;
576 tmp->status = P2P_SC_SUCCESS;
578 tmp->conncap = auto_accept;
579 tmp->status = P2P_SC_FAIL_INCOMPATIBLE_PARAMS;
582 if (reject != P2P_SC_SUCCESS)
585 } else if (!msg.status) {
586 reject = P2P_SC_FAIL_INCOMPATIBLE_PARAMS;
590 if (!msg.status && !auto_accept &&
591 (!p2p->p2ps_prov || p2p->p2ps_prov->adv_id != adv_id)) {
592 struct p2ps_provision *tmp;
595 reject = P2P_SC_FAIL_INCOMPATIBLE_PARAMS;
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;
605 tmp = p2p->p2ps_prov;
606 reject = P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE;
607 tmp->status = reject;
612 *msg.status != P2P_SC_SUCCESS_DEFERRED) {
613 reject = *msg.status;
614 } else if (*msg.status == P2P_SC_SUCCESS_DEFERRED &&
616 u16 method = p2p->p2ps_prov->method;
618 conncap = p2p->cfg->p2ps_group_capability(
619 p2p->cfg->cb_ctx, remote_conncap,
620 p2p->p2ps_prov->conncap);
623 "Conncap: local:%d remote:%d result:%d",
624 p2p->p2ps_prov->conncap,
625 remote_conncap, conncap);
628 * Ensure that if we asked for PIN originally,
629 * our method is consistent with original
632 if (method & WPS_CONFIG_DISPLAY)
633 method = WPS_CONFIG_KEYPAD;
634 else if (method & WPS_CONFIG_KEYPAD)
635 method = WPS_CONFIG_DISPLAY;
637 /* Reject this "Deferred Accept* if incompatible
638 * conncap or method */
640 !(msg.wps_config_methods & method))
642 P2P_SC_FAIL_INCOMPATIBLE_PARAMS;
644 reject = P2P_SC_SUCCESS;
646 p2p->p2ps_prov->status = reject;
647 p2p->p2ps_prov->conncap = conncap;
653 if (reject == P2P_SC_SUCCESS ||
654 reject == P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE)
655 config_methods = msg.wps_config_methods;
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,
662 msg.persistent_ssid_len);
664 p2p_parse_free(&msg);
667 p2p_dbg(p2p, "Sending Provision Discovery Response");
671 freq = p2p_channel_to_freq(p2p->cfg->reg_class,
674 p2p_dbg(p2p, "Unknown regulatory class/channel");
676 p2p_parse_free(&msg);
679 p2p->pending_action_state = P2P_PENDING_PD_RESPONSE;
680 if (p2p_send_action(p2p, freq, sa, p2p->cfg->dev_addr,
682 wpabuf_head(resp), wpabuf_len(resp), 200) < 0) {
683 p2p_dbg(p2p, "Failed to send Action frame");
685 p2p->send_action_in_progress = 1;
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,
700 } else if (msg.status && *msg.status == P2P_SC_SUCCESS_DEFERRED &&
702 p2p->p2ps_prov->status = reject;
703 p2p->p2ps_prov->conncap = conncap;
705 if (reject != P2P_SC_SUCCESS)
706 p2p->cfg->p2ps_prov_complete(p2p->cfg->cb_ctx, reject,
707 sa, adv_mac, session_mac,
709 session_id, conncap, 0,
711 msg.persistent_ssid_len, 0,
714 p2p->cfg->p2ps_prov_complete(p2p->cfg->cb_ctx,
716 sa, adv_mac, session_mac,
721 msg.persistent_ssid_len, 0,
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,
730 msg.persistent_ssid_len,
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,
739 msg.persistent_ssid_len,
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;
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,
750 msg.persistent_ssid_len,
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);
757 p2p->p2ps_prov->method = msg.wps_config_methods;
759 utf8_escape((char *) msg.session_info, buf_len,
760 buf, 2 * buf_len + 1);
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,
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] :
784 msg.group_id, msg.group_id_len);
786 p2p_parse_free(&msg);
790 void p2p_process_prov_disc_resp(struct p2p_data *p2p, const u8 *sa,
791 const u8 *data, size_t len)
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;
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;
804 if (p2p_parse(data, len, &msg))
807 /* Parse the P2PS members present */
809 status = *msg.status;
811 if (msg.intended_addr)
812 os_memcpy(group_mac, msg.intended_addr, ETH_ALEN);
814 os_memset(group_mac, 0, ETH_ALEN);
817 os_memcpy(adv_mac, msg.adv_mac, ETH_ALEN);
819 os_memset(adv_mac, 0, ETH_ALEN);
822 adv_id = WPA_GET_LE32(msg.adv_id);
825 conncap = *msg.conn_cap;
827 /* Switch bits to local relative */
829 case P2PS_SETUP_GROUP_OWNER:
830 conncap = P2PS_SETUP_CLIENT;
832 case P2PS_SETUP_CLIENT:
833 conncap = P2PS_SETUP_GROUP_OWNER;
838 p2p_dbg(p2p, "Received Provision Discovery Response from " MACSTR
839 " with config methods 0x%x",
840 MAC2STR(sa), msg.wps_config_methods);
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);
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);
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;
863 * Use a local copy of the requested config methods since
864 * p2p_reset_pending_pd() can clear this in the peer entry.
866 req_config_methods = dev->req_config_methods;
869 * If the response is from the peer to whom a user initiated request
870 * was sent earlier, we reset that state info here.
872 if (p2p->user_initiated_pd &&
873 os_memcmp(p2p->pending_pd_devaddr, sa, ETH_ALEN) == 0)
874 p2p_reset_pending_pd(p2p);
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 os_free(p2p->p2ps_prov);
885 p2p->p2ps_prov = NULL;
889 report_config_methods = req_config_methods;
890 dev->flags &= ~(P2P_DEV_PD_PEER_DISPLAY |
891 P2P_DEV_PD_PEER_KEYPAD |
892 P2P_DEV_PD_PEER_P2PS);
893 if (req_config_methods & WPS_CONFIG_DISPLAY) {
894 p2p_dbg(p2p, "Peer " MACSTR
895 " accepted to show a PIN on display", MAC2STR(sa));
896 dev->flags |= P2P_DEV_PD_PEER_DISPLAY;
897 passwd_id = DEV_PW_REGISTRAR_SPECIFIED;
898 } else if (msg.wps_config_methods & WPS_CONFIG_KEYPAD) {
899 p2p_dbg(p2p, "Peer " MACSTR
900 " accepted to write our PIN using keypad",
902 dev->flags |= P2P_DEV_PD_PEER_KEYPAD;
903 passwd_id = DEV_PW_USER_SPECIFIED;
904 } else if (msg.wps_config_methods & WPS_CONFIG_P2PS) {
905 p2p_dbg(p2p, "Peer " MACSTR " accepted P2PS PIN",
907 dev->flags |= P2P_DEV_PD_PEER_P2PS;
908 passwd_id = DEV_PW_P2PS_DEFAULT;
911 if ((msg.conn_cap || msg.persistent_dev) &&
913 (status == P2P_SC_SUCCESS || status == P2P_SC_SUCCESS_DEFERRED) &&
915 if (p2p->cfg->p2ps_prov_complete) {
916 p2p->cfg->p2ps_prov_complete(
917 p2p->cfg->cb_ctx, status, sa, adv_mac,
918 p2p->p2ps_prov->session_mac,
919 group_mac, adv_id, p2p->p2ps_prov->session_id,
920 conncap, passwd_id, msg.persistent_ssid,
921 msg.persistent_ssid_len, 1, 0, NULL);
923 os_free(p2p->p2ps_prov);
924 p2p->p2ps_prov = NULL;
927 if (status != P2P_SC_SUCCESS &&
928 status != P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE &&
929 status != P2P_SC_SUCCESS_DEFERRED && p2p->p2ps_prov) {
930 if (p2p->cfg->p2ps_prov_complete)
931 p2p->cfg->p2ps_prov_complete(
932 p2p->cfg->cb_ctx, status, sa, adv_mac,
933 p2p->p2ps_prov->session_mac,
934 group_mac, adv_id, p2p->p2ps_prov->session_id,
935 0, 0, NULL, 0, 1, 0, NULL);
936 os_free(p2p->p2ps_prov);
937 p2p->p2ps_prov = NULL;
940 if (status == P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE) {
941 if (p2p->cfg->remove_stale_groups) {
942 p2p->cfg->remove_stale_groups(p2p->cfg->cb_ctx,
943 dev->info.p2p_device_addr,
947 if (msg.session_info && msg.session_info_len) {
948 size_t info_len = msg.session_info_len;
949 char *deferred_sess_resp = os_malloc(2 * info_len + 1);
951 if (!deferred_sess_resp) {
952 p2p_parse_free(&msg);
953 os_free(p2p->p2ps_prov);
954 p2p->p2ps_prov = NULL;
957 utf8_escape((char *) msg.session_info, info_len,
958 deferred_sess_resp, 2 * info_len + 1);
960 if (p2p->cfg->prov_disc_fail)
961 p2p->cfg->prov_disc_fail(
962 p2p->cfg->cb_ctx, sa,
963 P2P_PROV_DISC_INFO_UNAVAILABLE,
966 os_free(deferred_sess_resp);
968 if (p2p->cfg->prov_disc_fail)
969 p2p->cfg->prov_disc_fail(
970 p2p->cfg->cb_ctx, sa,
971 P2P_PROV_DISC_INFO_UNAVAILABLE,
972 adv_id, adv_mac, NULL);
973 } else if (msg.wps_config_methods != dev->req_config_methods ||
974 status != P2P_SC_SUCCESS) {
975 p2p_dbg(p2p, "Peer rejected our Provision Discovery Request");
976 if (p2p->cfg->prov_disc_fail)
977 p2p->cfg->prov_disc_fail(p2p->cfg->cb_ctx, sa,
978 P2P_PROV_DISC_REJECTED, 0,
980 p2p_parse_free(&msg);
981 os_free(p2p->p2ps_prov);
982 p2p->p2ps_prov = NULL;
986 /* Store the provisioning info */
987 dev->wps_prov_info = msg.wps_config_methods;
989 p2p_parse_free(&msg);
993 dev->req_config_methods = 0;
994 p2p->cfg->send_action_done(p2p->cfg->cb_ctx);
995 if (dev->flags & P2P_DEV_PD_BEFORE_GO_NEG) {
996 p2p_dbg(p2p, "Start GO Neg after the PD-before-GO-Neg workaround with "
997 MACSTR, MAC2STR(dev->info.p2p_device_addr));
998 dev->flags &= ~P2P_DEV_PD_BEFORE_GO_NEG;
999 p2p_connect_send(p2p, dev);
1002 if (success && p2p->cfg->prov_disc_resp)
1003 p2p->cfg->prov_disc_resp(p2p->cfg->cb_ctx, sa,
1004 report_config_methods);
1006 if (p2p->state == P2P_PD_DURING_FIND) {
1007 p2p_clear_timeout(p2p);
1008 p2p_continue_find(p2p);
1013 int p2p_send_prov_disc_req(struct p2p_data *p2p, struct p2p_device *dev,
1014 int join, int force_freq)
1022 freq = dev->listen_freq > 0 ? dev->listen_freq :
1025 p2p_dbg(p2p, "No Listen/Operating frequency known for the peer "
1026 MACSTR " to send Provision Discovery Request",
1027 MAC2STR(dev->info.p2p_device_addr));
1031 if (dev->flags & P2P_DEV_GROUP_CLIENT_ONLY) {
1032 if (!(dev->info.dev_capab &
1033 P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY)) {
1034 p2p_dbg(p2p, "Cannot use PD with P2P Device " MACSTR
1035 " that is in a group and is not discoverable",
1036 MAC2STR(dev->info.p2p_device_addr));
1039 /* TODO: use device discoverability request through GO */
1042 if (p2p->p2ps_prov) {
1043 if (p2p->p2ps_prov->status == P2P_SC_SUCCESS_DEFERRED) {
1044 if (p2p->p2ps_prov->method == WPS_CONFIG_DISPLAY)
1045 dev->req_config_methods = WPS_CONFIG_KEYPAD;
1046 else if (p2p->p2ps_prov->method == WPS_CONFIG_KEYPAD)
1047 dev->req_config_methods = WPS_CONFIG_DISPLAY;
1049 dev->req_config_methods = WPS_CONFIG_P2PS;
1051 /* Order of preference, based on peer's capabilities */
1052 if (p2p->p2ps_prov->method)
1053 dev->req_config_methods =
1054 p2p->p2ps_prov->method;
1055 else if (dev->info.config_methods & WPS_CONFIG_P2PS)
1056 dev->req_config_methods = WPS_CONFIG_P2PS;
1057 else if (dev->info.config_methods & WPS_CONFIG_DISPLAY)
1058 dev->req_config_methods = WPS_CONFIG_DISPLAY;
1060 dev->req_config_methods = WPS_CONFIG_KEYPAD;
1063 "Building PD Request based on P2PS config method 0x%x status %d --> req_config_methods 0x%x",
1064 p2p->p2ps_prov->method, p2p->p2ps_prov->status,
1065 dev->req_config_methods);
1068 req = p2p_build_prov_disc_req(p2p, dev, join);
1072 if (p2p->state != P2P_IDLE)
1073 p2p_stop_listen_for_freq(p2p, freq);
1074 p2p->pending_action_state = P2P_PENDING_PD;
1075 if (p2p_send_action(p2p, freq, dev->info.p2p_device_addr,
1076 p2p->cfg->dev_addr, dev->info.p2p_device_addr,
1077 wpabuf_head(req), wpabuf_len(req), 200) < 0) {
1078 p2p_dbg(p2p, "Failed to send Action frame");
1083 os_memcpy(p2p->pending_pd_devaddr, dev->info.p2p_device_addr, ETH_ALEN);
1090 int p2p_prov_disc_req(struct p2p_data *p2p, const u8 *peer_addr,
1091 struct p2ps_provision *p2ps_prov,
1092 u16 config_methods, int join, int force_freq,
1093 int user_initiated_pd)
1095 struct p2p_device *dev;
1097 dev = p2p_get_device(p2p, peer_addr);
1099 dev = p2p_get_device_interface(p2p, peer_addr);
1100 if (dev == NULL || (dev->flags & P2P_DEV_PROBE_REQ_ONLY)) {
1101 p2p_dbg(p2p, "Provision Discovery Request destination " MACSTR
1102 " not yet known", MAC2STR(peer_addr));
1107 p2p_dbg(p2p, "Provision Discovery Request with " MACSTR
1108 " (config methods 0x%x)",
1109 MAC2STR(peer_addr), config_methods);
1110 if (config_methods == 0 && !p2ps_prov) {
1115 if (p2ps_prov && p2ps_prov->status == P2P_SC_SUCCESS_DEFERRED &&
1117 /* Use cached method from deferred provisioning */
1118 p2ps_prov->method = p2p->p2ps_prov->method;
1121 /* Reset provisioning info */
1122 dev->wps_prov_info = 0;
1123 os_free(p2p->p2ps_prov);
1124 p2p->p2ps_prov = p2ps_prov;
1126 dev->req_config_methods = config_methods;
1128 dev->flags |= P2P_DEV_PD_FOR_JOIN;
1130 dev->flags &= ~P2P_DEV_PD_FOR_JOIN;
1132 if (p2p->state != P2P_IDLE && p2p->state != P2P_SEARCH &&
1133 p2p->state != P2P_LISTEN_ONLY) {
1134 p2p_dbg(p2p, "Busy with other operations; postpone Provision Discovery Request with "
1135 MACSTR " (config methods 0x%x)",
1136 MAC2STR(peer_addr), config_methods);
1140 p2p->user_initiated_pd = user_initiated_pd;
1141 p2p->pd_force_freq = force_freq;
1143 if (p2p->user_initiated_pd)
1144 p2p->pd_retries = MAX_PROV_DISC_REQ_RETRIES;
1147 * Assign dialog token here to use the same value in each retry within
1148 * the same PD exchange.
1150 dev->dialog_token++;
1151 if (dev->dialog_token == 0)
1152 dev->dialog_token = 1;
1154 return p2p_send_prov_disc_req(p2p, dev, join, force_freq);
1158 void p2p_reset_pending_pd(struct p2p_data *p2p)
1160 struct p2p_device *dev;
1162 dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) {
1163 if (os_memcmp(p2p->pending_pd_devaddr,
1164 dev->info.p2p_device_addr, ETH_ALEN))
1166 if (!dev->req_config_methods)
1168 if (dev->flags & P2P_DEV_PD_FOR_JOIN)
1170 /* Reset the config methods of the device */
1171 dev->req_config_methods = 0;
1174 p2p->user_initiated_pd = 0;
1175 os_memset(p2p->pending_pd_devaddr, 0, ETH_ALEN);
1176 p2p->pd_retries = 0;
1177 p2p->pd_force_freq = 0;