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
];
445 u8 group_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
);
459 dev
= p2p_get_device(p2p
, sa
);
460 if (dev
== NULL
|| (dev
->flags
& P2P_DEV_PROBE_REQ_ONLY
)) {
461 p2p_dbg(p2p
, "Provision Discovery Request from unknown peer "
462 MACSTR
, MAC2STR(sa
));
464 if (p2p_add_device(p2p
, sa
, rx_freq
, NULL
, 0, data
+ 1, len
- 1,
466 p2p_dbg(p2p
, "Provision Discovery Request add device failed "
467 MACSTR
, MAC2STR(sa
));
469 } else if (msg
.wfd_subelems
) {
470 wpabuf_free(dev
->info
.wfd_subelems
);
471 dev
->info
.wfd_subelems
= wpabuf_dup(msg
.wfd_subelems
);
475 allowed_config_methods
|= WPS_CONFIG_P2PS
;
477 allowed_config_methods
|= WPS_CONFIG_PUSHBUTTON
;
479 if (!(msg
.wps_config_methods
& allowed_config_methods
)) {
480 p2p_dbg(p2p
, "Unsupported Config Methods in Provision Discovery Request");
484 /* Legacy (non-P2PS) - Unknown groups allowed for P2PS */
485 if (!msg
.adv_id
&& msg
.group_id
) {
487 for (i
= 0; i
< p2p
->num_groups
; i
++) {
488 if (p2p_group_is_group_id_match(p2p
->groups
[i
],
493 if (i
== p2p
->num_groups
) {
494 p2p_dbg(p2p
, "PD request for unknown P2P Group ID - reject");
500 dev
->flags
&= ~(P2P_DEV_PD_PEER_DISPLAY
|
501 P2P_DEV_PD_PEER_KEYPAD
|
502 P2P_DEV_PD_PEER_P2PS
);
504 /* Remove stale persistent groups */
505 if (p2p
->cfg
->remove_stale_groups
) {
506 p2p
->cfg
->remove_stale_groups(
507 p2p
->cfg
->cb_ctx
, dev
->info
.p2p_device_addr
,
509 msg
.persistent_ssid
, msg
.persistent_ssid_len
);
512 if (msg
.wps_config_methods
& WPS_CONFIG_DISPLAY
) {
513 p2p_dbg(p2p
, "Peer " MACSTR
514 " requested us to show a PIN on display", MAC2STR(sa
));
516 dev
->flags
|= P2P_DEV_PD_PEER_KEYPAD
;
517 passwd_id
= DEV_PW_USER_SPECIFIED
;
518 } else if (msg
.wps_config_methods
& WPS_CONFIG_KEYPAD
) {
519 p2p_dbg(p2p
, "Peer " MACSTR
520 " requested us to write its PIN using keypad",
523 dev
->flags
|= P2P_DEV_PD_PEER_DISPLAY
;
524 passwd_id
= DEV_PW_REGISTRAR_SPECIFIED
;
525 } else if (msg
.wps_config_methods
& WPS_CONFIG_P2PS
) {
526 p2p_dbg(p2p
, "Peer " MACSTR
" requesting P2PS PIN",
529 dev
->flags
|= P2P_DEV_PD_PEER_P2PS
;
530 passwd_id
= DEV_PW_P2PS_DEFAULT
;
533 reject
= P2P_SC_SUCCESS
;
535 os_memset(session_mac
, 0, ETH_ALEN
);
536 os_memset(adv_mac
, 0, ETH_ALEN
);
537 os_memset(group_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 if (msg
.intended_addr
)
557 os_memcpy(group_mac
, msg
.intended_addr
, ETH_ALEN
);
559 os_memcpy(session_mac
, msg
.session_mac
, ETH_ALEN
);
560 os_memcpy(adv_mac
, msg
.adv_mac
, ETH_ALEN
);
562 session_id
= WPA_GET_LE32(msg
.session_id
);
563 adv_id
= WPA_GET_LE32(msg
.adv_id
);
566 p2ps_adv
= p2p_service_p2ps_id(p2p
, adv_id
);
568 p2p_dbg(p2p
, "adv_id: %x - p2ps_adv - %p", adv_id
, p2ps_adv
);
571 conncap
= *msg
.conn_cap
;
572 remote_conncap
= conncap
;
575 auto_accept
= p2ps_adv
->auto_accept
;
576 conncap
= p2p
->cfg
->p2ps_group_capability(
577 p2p
->cfg
->cb_ctx
, conncap
, auto_accept
);
579 p2p_dbg(p2p
, "Conncap: local:%d remote:%d result:%d",
580 auto_accept
, remote_conncap
, conncap
);
583 p2ps_own_preferred_cpt(p2ps_adv
->cpt_priority
,
587 "cpt: service:0x%x remote:0x%x result:0x%x",
588 p2ps_adv
->cpt_mask
, req_fcap
->cpt
,
591 if (!resp_fcap
.cpt
) {
593 "Incompatible P2PS feature capability CPT bitmask");
594 reject
= P2P_SC_FAIL_INCOMPATIBLE_PARAMS
;
595 } else if (p2ps_adv
->config_methods
&&
596 !(msg
.wps_config_methods
&
597 p2ps_adv
->config_methods
)) {
599 "Unsupported config methods in Provision Discovery Request (own=0x%x peer=0x%x)",
600 p2ps_adv
->config_methods
,
601 msg
.wps_config_methods
);
602 reject
= P2P_SC_FAIL_INCOMPATIBLE_PARAMS
;
603 } else if (!p2ps_adv
->state
) {
604 p2p_dbg(p2p
, "P2PS state unavailable");
605 reject
= P2P_SC_FAIL_UNABLE_TO_ACCOMMODATE
;
606 } else if (!conncap
) {
607 p2p_dbg(p2p
, "Conncap resolution failed");
608 reject
= P2P_SC_FAIL_INCOMPATIBLE_PARAMS
;
611 if (msg
.wps_config_methods
& WPS_CONFIG_KEYPAD
) {
612 p2p_dbg(p2p
, "Keypad - always defer");
616 if (auto_accept
|| reject
!= P2P_SC_SUCCESS
) {
617 struct p2ps_provision
*tmp
;
619 if (reject
== P2P_SC_SUCCESS
&& !conncap
) {
621 P2P_SC_FAIL_INCOMPATIBLE_PARAMS
;
624 if (p2ps_setup_p2ps_prov(
625 p2p
, adv_id
, session_id
,
626 msg
.wps_config_methods
,
627 session_mac
, adv_mac
) < 0) {
628 reject
= P2P_SC_FAIL_UNABLE_TO_ACCOMMODATE
;
632 tmp
= p2p
->p2ps_prov
;
634 tmp
->conncap
= conncap
;
635 tmp
->status
= P2P_SC_SUCCESS
;
637 tmp
->conncap
= auto_accept
;
638 tmp
->status
= P2P_SC_FAIL_INCOMPATIBLE_PARAMS
;
641 if (reject
!= P2P_SC_SUCCESS
)
644 } else if (!msg
.status
) {
645 reject
= P2P_SC_FAIL_INCOMPATIBLE_PARAMS
;
649 if (!msg
.status
&& !auto_accept
&&
650 (!p2p
->p2ps_prov
|| p2p
->p2ps_prov
->adv_id
!= adv_id
)) {
651 struct p2ps_provision
*tmp
;
654 reject
= P2P_SC_FAIL_INCOMPATIBLE_PARAMS
;
658 if (p2ps_setup_p2ps_prov(p2p
, adv_id
, session_id
,
659 msg
.wps_config_methods
,
660 session_mac
, adv_mac
) < 0) {
661 reject
= P2P_SC_FAIL_UNABLE_TO_ACCOMMODATE
;
664 tmp
= p2p
->p2ps_prov
;
665 reject
= P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE
;
666 tmp
->status
= reject
;
671 *msg
.status
!= P2P_SC_SUCCESS_DEFERRED
) {
672 reject
= *msg
.status
;
673 } else if (*msg
.status
== P2P_SC_SUCCESS_DEFERRED
&&
675 u16 method
= p2p
->p2ps_prov
->method
;
677 conncap
= p2p
->cfg
->p2ps_group_capability(
678 p2p
->cfg
->cb_ctx
, remote_conncap
,
679 p2p
->p2ps_prov
->conncap
);
682 "Conncap: local:%d remote:%d result:%d",
683 p2p
->p2ps_prov
->conncap
,
684 remote_conncap
, conncap
);
686 resp_fcap
.cpt
= p2ps_own_preferred_cpt(
687 p2p
->p2ps_prov
->cpt_priority
,
691 "cpt: local:0x%x remote:0x%x result:0x%x",
692 p2p
->p2ps_prov
->cpt_mask
,
693 req_fcap
->cpt
, resp_fcap
.cpt
);
696 * Ensure that if we asked for PIN originally,
697 * our method is consistent with original
700 if (method
& WPS_CONFIG_DISPLAY
)
701 method
= WPS_CONFIG_KEYPAD
;
702 else if (method
& WPS_CONFIG_KEYPAD
)
703 method
= WPS_CONFIG_DISPLAY
;
706 !(msg
.wps_config_methods
& method
)) {
708 * Reject this "Deferred Accept*
709 * if incompatible conncap or method
712 P2P_SC_FAIL_INCOMPATIBLE_PARAMS
;
713 } else if (!resp_fcap
.cpt
) {
715 "Incompatible P2PS feature capability CPT bitmask");
717 P2P_SC_FAIL_INCOMPATIBLE_PARAMS
;
719 reject
= P2P_SC_SUCCESS
;
722 p2p
->p2ps_prov
->status
= reject
;
723 p2p
->p2ps_prov
->conncap
= conncap
;
729 if (reject
== P2P_SC_SUCCESS
||
730 reject
== P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE
)
731 config_methods
= msg
.wps_config_methods
;
734 resp
= p2p_build_prov_disc_resp(p2p
, dev
, msg
.dialog_token
, reject
,
735 config_methods
, adv_id
,
736 msg
.group_id
, msg
.group_id_len
,
738 msg
.persistent_ssid_len
,
739 (const u8
*) &resp_fcap
,
742 p2p_parse_free(&msg
);
745 p2p_dbg(p2p
, "Sending Provision Discovery Response");
749 freq
= p2p_channel_to_freq(p2p
->cfg
->reg_class
,
752 p2p_dbg(p2p
, "Unknown regulatory class/channel");
754 p2p_parse_free(&msg
);
757 p2p
->pending_action_state
= P2P_PENDING_PD_RESPONSE
;
758 if (p2p_send_action(p2p
, freq
, sa
, p2p
->cfg
->dev_addr
,
760 wpabuf_head(resp
), wpabuf_len(resp
), 200) < 0) {
761 p2p_dbg(p2p
, "Failed to send Action frame");
763 p2p
->send_action_in_progress
= 1;
767 if (!p2p
->cfg
->p2ps_prov_complete
) {
768 /* Don't emit anything */
769 } else if (msg
.status
&& *msg
.status
!= P2P_SC_SUCCESS
&&
770 *msg
.status
!= P2P_SC_SUCCESS_DEFERRED
) {
771 reject
= *msg
.status
;
772 p2p
->cfg
->p2ps_prov_complete(p2p
->cfg
->cb_ctx
, reject
,
773 sa
, adv_mac
, session_mac
,
774 NULL
, adv_id
, session_id
,
775 0, 0, msg
.persistent_ssid
,
776 msg
.persistent_ssid_len
,
777 0, 0, NULL
, NULL
, 0);
778 } else if (msg
.status
&& *msg
.status
== P2P_SC_SUCCESS_DEFERRED
&&
780 p2p
->p2ps_prov
->status
= reject
;
781 p2p
->p2ps_prov
->conncap
= conncap
;
783 if (reject
!= P2P_SC_SUCCESS
)
784 p2p
->cfg
->p2ps_prov_complete(p2p
->cfg
->cb_ctx
, reject
,
785 sa
, adv_mac
, session_mac
,
787 session_id
, conncap
, 0,
789 msg
.persistent_ssid_len
, 0,
792 p2p
->cfg
->p2ps_prov_complete(p2p
->cfg
->cb_ctx
,
794 sa
, adv_mac
, session_mac
,
799 msg
.persistent_ssid_len
, 0,
801 (const u8
*) &resp_fcap
,
803 } else if (msg
.status
&& p2p
->p2ps_prov
) {
804 p2p
->p2ps_prov
->status
= P2P_SC_SUCCESS
;
805 p2p
->cfg
->p2ps_prov_complete(p2p
->cfg
->cb_ctx
, *msg
.status
, sa
,
806 adv_mac
, session_mac
, group_mac
,
807 adv_id
, session_id
, conncap
,
810 msg
.persistent_ssid_len
,
812 (const u8
*) &resp_fcap
,
814 } else if (msg
.status
) {
815 } else if (auto_accept
&& reject
== P2P_SC_SUCCESS
) {
816 p2p
->cfg
->p2ps_prov_complete(p2p
->cfg
->cb_ctx
, P2P_SC_SUCCESS
,
817 sa
, adv_mac
, session_mac
,
818 group_mac
, adv_id
, session_id
,
821 msg
.persistent_ssid_len
,
823 (const u8
*) &resp_fcap
,
825 } else if (reject
== P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE
&&
826 (!msg
.session_info
|| !msg
.session_info_len
)) {
827 p2p
->p2ps_prov
->method
= msg
.wps_config_methods
;
829 p2p
->cfg
->p2ps_prov_complete(p2p
->cfg
->cb_ctx
, P2P_SC_SUCCESS
,
830 sa
, adv_mac
, session_mac
,
831 group_mac
, adv_id
, session_id
,
834 msg
.persistent_ssid_len
,
836 (const u8
*) &resp_fcap
,
838 } else if (reject
== P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE
) {
839 size_t buf_len
= msg
.session_info_len
;
840 char *buf
= os_malloc(2 * buf_len
+ 1);
843 p2p
->p2ps_prov
->method
= msg
.wps_config_methods
;
845 utf8_escape((char *) msg
.session_info
, buf_len
,
846 buf
, 2 * buf_len
+ 1);
848 p2p
->cfg
->p2ps_prov_complete(
849 p2p
->cfg
->cb_ctx
, P2P_SC_SUCCESS
, sa
,
850 adv_mac
, session_mac
, group_mac
, adv_id
,
851 session_id
, conncap
, passwd_id
,
852 msg
.persistent_ssid
, msg
.persistent_ssid_len
,
854 (const u8
*) &resp_fcap
, sizeof(resp_fcap
));
860 if (reject
== P2P_SC_SUCCESS
&& p2p
->cfg
->prov_disc_req
) {
861 const u8
*dev_addr
= sa
;
862 if (msg
.p2p_device_addr
)
863 dev_addr
= msg
.p2p_device_addr
;
864 p2p
->cfg
->prov_disc_req(p2p
->cfg
->cb_ctx
, sa
,
865 msg
.wps_config_methods
,
866 dev_addr
, msg
.pri_dev_type
,
867 msg
.device_name
, msg
.config_methods
,
868 msg
.capability
? msg
.capability
[0] : 0,
869 msg
.capability
? msg
.capability
[1] :
871 msg
.group_id
, msg
.group_id_len
);
874 switch (config_methods
) {
875 case WPS_CONFIG_DISPLAY
:
876 dev
->wps_prov_info
= WPS_CONFIG_KEYPAD
;
878 case WPS_CONFIG_KEYPAD
:
879 dev
->wps_prov_info
= WPS_CONFIG_DISPLAY
;
881 case WPS_CONFIG_PUSHBUTTON
:
882 dev
->wps_prov_info
= WPS_CONFIG_PUSHBUTTON
;
884 case WPS_CONFIG_P2PS
:
885 dev
->wps_prov_info
= WPS_CONFIG_P2PS
;
888 dev
->wps_prov_info
= 0;
892 if (msg
.intended_addr
)
893 os_memcpy(dev
->interface_addr
,
894 msg
.intended_addr
, ETH_ALEN
);
897 p2p_parse_free(&msg
);
901 static int p2p_validate_p2ps_pd_resp(struct p2p_data
*p2p
,
902 struct p2p_message
*msg
)
909 #define P2PS_PD_RESP_CHECK(_val, _attr) \
911 if ((_val) && !msg->_attr) { \
912 p2p_dbg(p2p, "P2PS PD Response missing " #_attr); \
917 P2PS_PD_RESP_CHECK(1, status
);
918 P2PS_PD_RESP_CHECK(1, adv_id
);
919 P2PS_PD_RESP_CHECK(1, adv_mac
);
920 P2PS_PD_RESP_CHECK(1, capability
);
921 P2PS_PD_RESP_CHECK(1, p2p_device_info
);
922 P2PS_PD_RESP_CHECK(1, session_id
);
923 P2PS_PD_RESP_CHECK(1, session_mac
);
924 P2PS_PD_RESP_CHECK(1, feature_cap
);
926 session_id
= WPA_GET_LE32(msg
->session_id
);
927 adv_id
= WPA_GET_LE32(msg
->adv_id
);
929 if (p2p
->p2ps_prov
->session_id
!= session_id
) {
931 "Ignore PD Response with unexpected Session ID");
935 if (os_memcmp(p2p
->p2ps_prov
->session_mac
, msg
->session_mac
,
938 "Ignore PD Response with unexpected Session MAC");
942 if (p2p
->p2ps_prov
->adv_id
!= adv_id
) {
944 "Ignore PD Response with unexpected Advertisement ID");
948 if (os_memcmp(p2p
->p2ps_prov
->adv_mac
, msg
->adv_mac
, ETH_ALEN
) != 0) {
950 "Ignore PD Response with unexpected Advertisement MAC");
954 if (msg
->listen_channel
) {
956 "Ignore malformed PD Response - unexpected Listen Channel");
960 if (*msg
->status
== P2P_SC_SUCCESS
&&
961 !(!!msg
->conn_cap
^ !!msg
->persistent_dev
)) {
963 "Ignore malformed PD Response - either conn_cap or persistent group should be present");
967 if (msg
->persistent_dev
&& *msg
->status
!= P2P_SC_SUCCESS
) {
969 "Ignore malformed PD Response - persistent group is present, but the status isn't success");
974 conn_cap_go
= *msg
->conn_cap
== P2PS_SETUP_GROUP_OWNER
;
975 conn_cap_cli
= *msg
->conn_cap
== P2PS_SETUP_CLIENT
;
978 P2PS_PD_RESP_CHECK(msg
->persistent_dev
|| conn_cap_go
|| conn_cap_cli
,
980 P2PS_PD_RESP_CHECK(msg
->persistent_dev
|| conn_cap_go
|| conn_cap_cli
,
983 P2PS_PD_RESP_CHECK(conn_cap_go
, group_id
);
984 P2PS_PD_RESP_CHECK(conn_cap_go
, intended_addr
);
985 P2PS_PD_RESP_CHECK(conn_cap_go
, operating_channel
);
987 * TODO: Also validate that operating channel is present if the device
988 * is a GO in a persistent group. We can't do it here since we don't
989 * know what is the role of the peer. It should be probably done in
990 * p2ps_prov_complete callback, but currently operating channel isn't
994 #undef P2PS_PD_RESP_CHECK
1000 void p2p_process_prov_disc_resp(struct p2p_data
*p2p
, const u8
*sa
,
1001 const u8
*data
, size_t len
)
1003 struct p2p_message msg
;
1004 struct p2p_device
*dev
;
1005 u16 report_config_methods
= 0, req_config_methods
;
1006 u8 status
= P2P_SC_SUCCESS
;
1009 u8 conncap
= P2PS_SETUP_NEW
;
1010 u8 adv_mac
[ETH_ALEN
];
1011 u8 group_mac
[ETH_ALEN
];
1012 int passwd_id
= DEV_PW_DEFAULT
;
1014 if (p2p_parse(data
, len
, &msg
))
1017 if (p2p
->p2ps_prov
&& p2p_validate_p2ps_pd_resp(p2p
, &msg
)) {
1018 p2p_parse_free(&msg
);
1022 /* Parse the P2PS members present */
1024 status
= *msg
.status
;
1026 if (msg
.intended_addr
)
1027 os_memcpy(group_mac
, msg
.intended_addr
, ETH_ALEN
);
1029 os_memset(group_mac
, 0, ETH_ALEN
);
1032 os_memcpy(adv_mac
, msg
.adv_mac
, ETH_ALEN
);
1034 os_memset(adv_mac
, 0, ETH_ALEN
);
1037 adv_id
= WPA_GET_LE32(msg
.adv_id
);
1040 conncap
= *msg
.conn_cap
;
1042 /* Switch bits to local relative */
1044 case P2PS_SETUP_GROUP_OWNER
:
1045 conncap
= P2PS_SETUP_CLIENT
;
1047 case P2PS_SETUP_CLIENT
:
1048 conncap
= P2PS_SETUP_GROUP_OWNER
;
1053 p2p_dbg(p2p
, "Received Provision Discovery Response from " MACSTR
1054 " with config methods 0x%x",
1055 MAC2STR(sa
), msg
.wps_config_methods
);
1057 dev
= p2p_get_device(p2p
, sa
);
1058 if (dev
== NULL
|| !dev
->req_config_methods
) {
1059 p2p_dbg(p2p
, "Ignore Provision Discovery Response from " MACSTR
1060 " with no pending request", MAC2STR(sa
));
1061 p2p_parse_free(&msg
);
1065 if (dev
->dialog_token
!= msg
.dialog_token
) {
1066 p2p_dbg(p2p
, "Ignore Provision Discovery Response with unexpected Dialog Token %u (expected %u)",
1067 msg
.dialog_token
, dev
->dialog_token
);
1068 p2p_parse_free(&msg
);
1072 if (p2p
->pending_action_state
== P2P_PENDING_PD
) {
1073 os_memset(p2p
->pending_pd_devaddr
, 0, ETH_ALEN
);
1074 p2p
->pending_action_state
= P2P_NO_PENDING_ACTION
;
1078 * Use a local copy of the requested config methods since
1079 * p2p_reset_pending_pd() can clear this in the peer entry.
1081 req_config_methods
= dev
->req_config_methods
;
1084 * If the response is from the peer to whom a user initiated request
1085 * was sent earlier, we reset that state info here.
1087 if (p2p
->user_initiated_pd
&&
1088 os_memcmp(p2p
->pending_pd_devaddr
, sa
, ETH_ALEN
) == 0)
1089 p2p_reset_pending_pd(p2p
);
1091 if (msg
.wps_config_methods
!= req_config_methods
) {
1092 p2p_dbg(p2p
, "Peer rejected our Provision Discovery Request (received config_methods 0x%x expected 0x%x",
1093 msg
.wps_config_methods
, req_config_methods
);
1094 if (p2p
->cfg
->prov_disc_fail
)
1095 p2p
->cfg
->prov_disc_fail(p2p
->cfg
->cb_ctx
, sa
,
1096 P2P_PROV_DISC_REJECTED
,
1097 adv_id
, adv_mac
, NULL
);
1098 p2p_parse_free(&msg
);
1099 p2ps_prov_free(p2p
);
1103 report_config_methods
= req_config_methods
;
1104 dev
->flags
&= ~(P2P_DEV_PD_PEER_DISPLAY
|
1105 P2P_DEV_PD_PEER_KEYPAD
|
1106 P2P_DEV_PD_PEER_P2PS
);
1107 if (req_config_methods
& WPS_CONFIG_DISPLAY
) {
1108 p2p_dbg(p2p
, "Peer " MACSTR
1109 " accepted to show a PIN on display", MAC2STR(sa
));
1110 dev
->flags
|= P2P_DEV_PD_PEER_DISPLAY
;
1111 passwd_id
= DEV_PW_REGISTRAR_SPECIFIED
;
1112 } else if (msg
.wps_config_methods
& WPS_CONFIG_KEYPAD
) {
1113 p2p_dbg(p2p
, "Peer " MACSTR
1114 " accepted to write our PIN using keypad",
1116 dev
->flags
|= P2P_DEV_PD_PEER_KEYPAD
;
1117 passwd_id
= DEV_PW_USER_SPECIFIED
;
1118 } else if (msg
.wps_config_methods
& WPS_CONFIG_P2PS
) {
1119 p2p_dbg(p2p
, "Peer " MACSTR
" accepted P2PS PIN",
1121 dev
->flags
|= P2P_DEV_PD_PEER_P2PS
;
1122 passwd_id
= DEV_PW_P2PS_DEFAULT
;
1125 if ((msg
.conn_cap
|| msg
.persistent_dev
) &&
1126 (status
== P2P_SC_SUCCESS
|| status
== P2P_SC_SUCCESS_DEFERRED
) &&
1128 if (p2p
->cfg
->p2ps_prov_complete
) {
1129 p2p
->cfg
->p2ps_prov_complete(
1130 p2p
->cfg
->cb_ctx
, status
, sa
, adv_mac
,
1131 p2p
->p2ps_prov
->session_mac
,
1132 group_mac
, adv_id
, p2p
->p2ps_prov
->session_id
,
1133 conncap
, passwd_id
, msg
.persistent_ssid
,
1134 msg
.persistent_ssid_len
, 1, 0, NULL
,
1135 msg
.feature_cap
, msg
.feature_cap_len
);
1137 p2ps_prov_free(p2p
);
1138 } else if (status
!= P2P_SC_SUCCESS
&&
1139 status
!= P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE
&&
1140 status
!= P2P_SC_SUCCESS_DEFERRED
&& p2p
->p2ps_prov
) {
1141 if (p2p
->cfg
->p2ps_prov_complete
)
1142 p2p
->cfg
->p2ps_prov_complete(
1143 p2p
->cfg
->cb_ctx
, status
, sa
, adv_mac
,
1144 p2p
->p2ps_prov
->session_mac
,
1145 group_mac
, adv_id
, p2p
->p2ps_prov
->session_id
,
1146 0, 0, NULL
, 0, 1, 0, NULL
, NULL
, 0);
1147 p2ps_prov_free(p2p
);
1150 if (status
== P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE
) {
1151 if (p2p
->cfg
->remove_stale_groups
) {
1152 p2p
->cfg
->remove_stale_groups(p2p
->cfg
->cb_ctx
,
1153 dev
->info
.p2p_device_addr
,
1157 if (msg
.session_info
&& msg
.session_info_len
) {
1158 size_t info_len
= msg
.session_info_len
;
1159 char *deferred_sess_resp
= os_malloc(2 * info_len
+ 1);
1161 if (!deferred_sess_resp
) {
1162 p2p_parse_free(&msg
);
1163 p2ps_prov_free(p2p
);
1166 utf8_escape((char *) msg
.session_info
, info_len
,
1167 deferred_sess_resp
, 2 * info_len
+ 1);
1169 if (p2p
->cfg
->prov_disc_fail
)
1170 p2p
->cfg
->prov_disc_fail(
1171 p2p
->cfg
->cb_ctx
, sa
,
1172 P2P_PROV_DISC_INFO_UNAVAILABLE
,
1174 deferred_sess_resp
);
1175 os_free(deferred_sess_resp
);
1177 if (p2p
->cfg
->prov_disc_fail
)
1178 p2p
->cfg
->prov_disc_fail(
1179 p2p
->cfg
->cb_ctx
, sa
,
1180 P2P_PROV_DISC_INFO_UNAVAILABLE
,
1181 adv_id
, adv_mac
, NULL
);
1182 } else if (status
!= P2P_SC_SUCCESS
) {
1183 p2p_dbg(p2p
, "Peer rejected our Provision Discovery Request");
1184 if (p2p
->cfg
->prov_disc_fail
)
1185 p2p
->cfg
->prov_disc_fail(p2p
->cfg
->cb_ctx
, sa
,
1186 P2P_PROV_DISC_REJECTED
,
1187 adv_id
, adv_mac
, NULL
);
1188 p2p_parse_free(&msg
);
1189 p2ps_prov_free(p2p
);
1193 /* Store the provisioning info */
1194 dev
->wps_prov_info
= msg
.wps_config_methods
;
1195 if (msg
.intended_addr
)
1196 os_memcpy(dev
->interface_addr
, msg
.intended_addr
, ETH_ALEN
);
1198 p2p_parse_free(&msg
);
1202 dev
->req_config_methods
= 0;
1203 p2p
->cfg
->send_action_done(p2p
->cfg
->cb_ctx
);
1204 if (dev
->flags
& P2P_DEV_PD_BEFORE_GO_NEG
) {
1205 p2p_dbg(p2p
, "Start GO Neg after the PD-before-GO-Neg workaround with "
1206 MACSTR
, MAC2STR(dev
->info
.p2p_device_addr
));
1207 dev
->flags
&= ~P2P_DEV_PD_BEFORE_GO_NEG
;
1208 p2p_connect_send(p2p
, dev
);
1211 if (success
&& p2p
->cfg
->prov_disc_resp
)
1212 p2p
->cfg
->prov_disc_resp(p2p
->cfg
->cb_ctx
, sa
,
1213 report_config_methods
);
1215 if (p2p
->state
== P2P_PD_DURING_FIND
) {
1216 p2p_clear_timeout(p2p
);
1217 p2p_continue_find(p2p
);
1222 int p2p_send_prov_disc_req(struct p2p_data
*p2p
, struct p2p_device
*dev
,
1223 int join
, int force_freq
)
1231 freq
= dev
->listen_freq
> 0 ? dev
->listen_freq
:
1234 p2p_dbg(p2p
, "No Listen/Operating frequency known for the peer "
1235 MACSTR
" to send Provision Discovery Request",
1236 MAC2STR(dev
->info
.p2p_device_addr
));
1240 if (dev
->flags
& P2P_DEV_GROUP_CLIENT_ONLY
) {
1241 if (!(dev
->info
.dev_capab
&
1242 P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY
)) {
1243 p2p_dbg(p2p
, "Cannot use PD with P2P Device " MACSTR
1244 " that is in a group and is not discoverable",
1245 MAC2STR(dev
->info
.p2p_device_addr
));
1248 /* TODO: use device discoverability request through GO */
1251 if (p2p
->p2ps_prov
) {
1252 if (p2p
->p2ps_prov
->status
== P2P_SC_SUCCESS_DEFERRED
) {
1253 if (p2p
->p2ps_prov
->method
== WPS_CONFIG_DISPLAY
)
1254 dev
->req_config_methods
= WPS_CONFIG_KEYPAD
;
1255 else if (p2p
->p2ps_prov
->method
== WPS_CONFIG_KEYPAD
)
1256 dev
->req_config_methods
= WPS_CONFIG_DISPLAY
;
1258 dev
->req_config_methods
= WPS_CONFIG_P2PS
;
1260 /* Order of preference, based on peer's capabilities */
1261 if (p2p
->p2ps_prov
->method
)
1262 dev
->req_config_methods
=
1263 p2p
->p2ps_prov
->method
;
1264 else if (dev
->info
.config_methods
& WPS_CONFIG_P2PS
)
1265 dev
->req_config_methods
= WPS_CONFIG_P2PS
;
1266 else if (dev
->info
.config_methods
& WPS_CONFIG_DISPLAY
)
1267 dev
->req_config_methods
= WPS_CONFIG_DISPLAY
;
1269 dev
->req_config_methods
= WPS_CONFIG_KEYPAD
;
1272 "Building PD Request based on P2PS config method 0x%x status %d --> req_config_methods 0x%x",
1273 p2p
->p2ps_prov
->method
, p2p
->p2ps_prov
->status
,
1274 dev
->req_config_methods
);
1277 req
= p2p_build_prov_disc_req(p2p
, dev
, join
);
1281 if (p2p
->state
!= P2P_IDLE
)
1282 p2p_stop_listen_for_freq(p2p
, freq
);
1283 p2p
->pending_action_state
= P2P_PENDING_PD
;
1284 if (p2p_send_action(p2p
, freq
, dev
->info
.p2p_device_addr
,
1285 p2p
->cfg
->dev_addr
, dev
->info
.p2p_device_addr
,
1286 wpabuf_head(req
), wpabuf_len(req
), 200) < 0) {
1287 p2p_dbg(p2p
, "Failed to send Action frame");
1292 os_memcpy(p2p
->pending_pd_devaddr
, dev
->info
.p2p_device_addr
, ETH_ALEN
);
1299 int p2p_prov_disc_req(struct p2p_data
*p2p
, const u8
*peer_addr
,
1300 struct p2ps_provision
*p2ps_prov
,
1301 u16 config_methods
, int join
, int force_freq
,
1302 int user_initiated_pd
)
1304 struct p2p_device
*dev
;
1306 dev
= p2p_get_device(p2p
, peer_addr
);
1308 dev
= p2p_get_device_interface(p2p
, peer_addr
);
1309 if (dev
== NULL
|| (dev
->flags
& P2P_DEV_PROBE_REQ_ONLY
)) {
1310 p2p_dbg(p2p
, "Provision Discovery Request destination " MACSTR
1311 " not yet known", MAC2STR(peer_addr
));
1316 p2p_dbg(p2p
, "Provision Discovery Request with " MACSTR
1317 " (config methods 0x%x)",
1318 MAC2STR(peer_addr
), config_methods
);
1319 if (config_methods
== 0 && !p2ps_prov
) {
1324 if (p2ps_prov
&& p2ps_prov
->status
== P2P_SC_SUCCESS_DEFERRED
&&
1326 /* Use cached method from deferred provisioning */
1327 p2ps_prov
->method
= p2p
->p2ps_prov
->method
;
1330 /* Reset provisioning info */
1331 dev
->wps_prov_info
= 0;
1332 p2ps_prov_free(p2p
);
1333 p2p
->p2ps_prov
= p2ps_prov
;
1335 dev
->req_config_methods
= config_methods
;
1337 dev
->flags
|= P2P_DEV_PD_FOR_JOIN
;
1339 dev
->flags
&= ~P2P_DEV_PD_FOR_JOIN
;
1341 if (p2p
->state
!= P2P_IDLE
&& p2p
->state
!= P2P_SEARCH
&&
1342 p2p
->state
!= P2P_LISTEN_ONLY
) {
1343 p2p_dbg(p2p
, "Busy with other operations; postpone Provision Discovery Request with "
1344 MACSTR
" (config methods 0x%x)",
1345 MAC2STR(peer_addr
), config_methods
);
1349 p2p
->user_initiated_pd
= user_initiated_pd
;
1350 p2p
->pd_force_freq
= force_freq
;
1352 if (p2p
->user_initiated_pd
)
1353 p2p
->pd_retries
= MAX_PROV_DISC_REQ_RETRIES
;
1356 * Assign dialog token here to use the same value in each retry within
1357 * the same PD exchange.
1359 dev
->dialog_token
++;
1360 if (dev
->dialog_token
== 0)
1361 dev
->dialog_token
= 1;
1363 return p2p_send_prov_disc_req(p2p
, dev
, join
, force_freq
);
1367 void p2p_reset_pending_pd(struct p2p_data
*p2p
)
1369 struct p2p_device
*dev
;
1371 dl_list_for_each(dev
, &p2p
->devices
, struct p2p_device
, list
) {
1372 if (os_memcmp(p2p
->pending_pd_devaddr
,
1373 dev
->info
.p2p_device_addr
, ETH_ALEN
))
1375 if (!dev
->req_config_methods
)
1377 if (dev
->flags
& P2P_DEV_PD_FOR_JOIN
)
1379 /* Reset the config methods of the device */
1380 dev
->req_config_methods
= 0;
1383 p2p
->user_initiated_pd
= 0;
1384 os_memset(p2p
->pending_pd_devaddr
, 0, ETH_ALEN
);
1385 p2p
->pd_retries
= 0;
1386 p2p
->pd_force_freq
= 0;
1390 void p2ps_prov_free(struct p2p_data
*p2p
)
1392 os_free(p2p
->p2ps_prov
);
1393 p2p
->p2ps_prov
= NULL
;