]> git.ipfire.org Git - thirdparty/hostap.git/blame - src/p2p/p2p_pd.c
P2PS: Indicate the chosen operating frequency
[thirdparty/hostap.git] / src / p2p / p2p_pd.c
CommitLineData
b22128ef
JM
1/*
2 * Wi-Fi Direct - P2P provision discovery
3 * Copyright (c) 2009-2010, Atheros Communications
4 *
e22d4d95
JM
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
b22128ef
JM
7 */
8
9#include "includes.h"
10
11#include "common.h"
12#include "common/ieee802_11_defs.h"
86bd36f0 13#include "common/wpa_ctrl.h"
b22128ef
JM
14#include "wps/wps_defs.h"
15#include "p2p_i.h"
16#include "p2p.h"
17
18
6b56cc2d 19/*
488f4a71
JM
20 * Number of retries to attempt for provision discovery requests
21 * in case the peer is not listening.
6b56cc2d 22 */
ffa45a13 23#define MAX_PROV_DISC_REQ_RETRIES 120
6b56cc2d
JS
24
25
b22128ef
JM
26static void p2p_build_wps_ie_config_methods(struct wpabuf *buf,
27 u16 config_methods)
28{
29 u8 *len;
30 wpabuf_put_u8(buf, WLAN_EID_VENDOR_SPECIFIC);
31 len = wpabuf_put(buf, 1);
32 wpabuf_put_be32(buf, WPS_DEV_OUI_WFA);
33
34 /* Config Methods */
35 wpabuf_put_be16(buf, ATTR_CONFIG_METHODS);
36 wpabuf_put_be16(buf, 2);
37 wpabuf_put_be16(buf, config_methods);
38
39 p2p_buf_update_ie_hdr(buf, len);
40}
41
42
ebd32943
IP
43static void p2ps_add_new_group_info(struct p2p_data *p2p,
44 struct p2p_device *dev,
45 struct wpabuf *buf)
369678ad
KV
46{
47 int found;
48 u8 intended_addr[ETH_ALEN];
d9d1b952 49 u8 ssid[SSID_MAX_LEN];
369678ad
KV
50 size_t ssid_len;
51 int group_iface;
ebd32943 52 unsigned int force_freq;
369678ad
KV
53
54 if (!p2p->cfg->get_go_info)
55 return;
56
57 found = p2p->cfg->get_go_info(
58 p2p->cfg->cb_ctx, intended_addr, ssid,
ebd32943 59 &ssid_len, &group_iface, &force_freq);
369678ad 60 if (found) {
ebd32943
IP
61 if (force_freq > 0) {
62 p2p->p2ps_prov->force_freq = force_freq;
63 p2p->p2ps_prov->pref_freq = 0;
64
65 if (dev)
66 p2p_prepare_channel(p2p, dev, force_freq, 0, 0);
67 }
369678ad
KV
68 p2p_buf_add_group_id(buf, p2p->cfg->dev_addr,
69 ssid, ssid_len);
5cc6ec0f
AO
70
71 if (group_iface)
72 p2p_buf_add_intended_addr(buf, p2p->intended_addr);
73 else
74 p2p_buf_add_intended_addr(buf, intended_addr);
369678ad
KV
75 } else {
76 if (!p2p->ssid_set) {
77 p2p_build_ssid(p2p, p2p->ssid, &p2p->ssid_len);
78 p2p->ssid_set = 1;
79 }
80
81 /* Add pre-composed P2P Group ID */
82 p2p_buf_add_group_id(buf, p2p->cfg->dev_addr,
83 p2p->ssid, p2p->ssid_len);
84
85 if (group_iface)
86 p2p_buf_add_intended_addr(
87 buf, p2p->intended_addr);
88 else
89 p2p_buf_add_intended_addr(
90 buf, p2p->cfg->dev_addr);
91 }
92}
93
94
95static void p2ps_add_pd_req_attrs(struct p2p_data *p2p, struct p2p_device *dev,
96 struct wpabuf *buf, u16 config_methods)
97{
98 struct p2ps_provision *prov = p2p->p2ps_prov;
c3ddf2c7 99 struct p2ps_feature_capab fcap = { prov->cpt_mask, 0 };
369678ad 100 int shared_group = 0;
d9d1b952 101 u8 ssid[SSID_MAX_LEN];
369678ad
KV
102 size_t ssid_len;
103 u8 go_dev_addr[ETH_ALEN];
1f1a08b4 104 u8 intended_addr[ETH_ALEN];
369678ad
KV
105
106 /* If we might be explicite group owner, add GO details */
107 if (prov->conncap & (P2PS_SETUP_GROUP_OWNER |
108 P2PS_SETUP_NEW))
ebd32943 109 p2ps_add_new_group_info(p2p, dev, buf);
369678ad
KV
110
111 if (prov->status >= 0)
112 p2p_buf_add_status(buf, (u8) prov->status);
113 else
114 prov->method = config_methods;
115
116 if (p2p->cfg->get_persistent_group) {
117 shared_group = p2p->cfg->get_persistent_group(
118 p2p->cfg->cb_ctx, dev->info.p2p_device_addr, NULL, 0,
1f1a08b4 119 go_dev_addr, ssid, &ssid_len, intended_addr);
369678ad
KV
120 }
121
369678ad 122 if (shared_group ||
ebd32943
IP
123 (prov->conncap & (P2PS_SETUP_CLIENT | P2PS_SETUP_NEW)))
124 p2p_buf_add_channel_list(buf, p2p->cfg->country,
125 &p2p->channels);
369678ad 126
ebd32943
IP
127 if ((shared_group && !is_zero_ether_addr(intended_addr)) ||
128 (prov->conncap & (P2PS_SETUP_GROUP_OWNER | P2PS_SETUP_NEW)))
129 p2p_buf_add_operating_channel(buf, p2p->cfg->country,
130 p2p->op_reg_class,
131 p2p->op_channel);
369678ad
KV
132
133 if (prov->info[0])
134 p2p_buf_add_session_info(buf, prov->info);
135
136 p2p_buf_add_connection_capability(buf, prov->conncap);
137
138 p2p_buf_add_advertisement_id(buf, prov->adv_id, prov->adv_mac);
139
140 if (shared_group || prov->conncap == P2PS_SETUP_NEW ||
141 prov->conncap ==
142 (P2PS_SETUP_GROUP_OWNER | P2PS_SETUP_NEW) ||
143 prov->conncap ==
144 (P2PS_SETUP_GROUP_OWNER | P2PS_SETUP_CLIENT)) {
145 /* Add Config Timeout */
146 p2p_buf_add_config_timeout(buf, p2p->go_timeout,
147 p2p->client_timeout);
148 }
149
150 p2p_buf_add_listen_channel(buf, p2p->cfg->country, p2p->cfg->reg_class,
151 p2p->cfg->channel);
152
153 p2p_buf_add_session_id(buf, prov->session_id, prov->session_mac);
154
c3ddf2c7 155 p2p_buf_add_feature_capability(buf, sizeof(fcap), (const u8 *) &fcap);
369678ad 156
1f1a08b4 157 if (shared_group) {
369678ad
KV
158 p2p_buf_add_persistent_group_info(buf, go_dev_addr,
159 ssid, ssid_len);
1f1a08b4
AO
160 /* Add intended interface address if it is not added yet */
161 if ((prov->conncap == P2PS_SETUP_NONE ||
162 prov->conncap == P2PS_SETUP_CLIENT) &&
163 !is_zero_ether_addr(intended_addr))
164 p2p_buf_add_intended_addr(buf, intended_addr);
165 }
369678ad
KV
166}
167
168
b22128ef 169static struct wpabuf * p2p_build_prov_disc_req(struct p2p_data *p2p,
369678ad
KV
170 struct p2p_device *dev,
171 int join)
b22128ef
JM
172{
173 struct wpabuf *buf;
174 u8 *len;
9675ce35 175 size_t extra = 0;
369678ad
KV
176 u8 dialog_token = dev->dialog_token;
177 u16 config_methods = dev->req_config_methods;
178 struct p2p_device *go = join ? dev : NULL;
1300cc8e 179 u8 group_capab;
b22128ef 180
9675ce35
JM
181#ifdef CONFIG_WIFI_DISPLAY
182 if (p2p->wfd_ie_prov_disc_req)
183 extra = wpabuf_len(p2p->wfd_ie_prov_disc_req);
184#endif /* CONFIG_WIFI_DISPLAY */
185
86bd36f0
JM
186 if (p2p->vendor_elem && p2p->vendor_elem[VENDOR_ELEM_P2P_PD_REQ])
187 extra += wpabuf_len(p2p->vendor_elem[VENDOR_ELEM_P2P_PD_REQ]);
188
369678ad
KV
189 if (p2p->p2ps_prov)
190 extra += os_strlen(p2p->p2ps_prov->info) + 1 +
191 sizeof(struct p2ps_provision);
192
9675ce35 193 buf = wpabuf_alloc(1000 + extra);
b22128ef
JM
194 if (buf == NULL)
195 return NULL;
196
197 p2p_buf_add_public_action_hdr(buf, P2P_PROV_DISC_REQ, dialog_token);
198
199 len = p2p_buf_add_ie_hdr(buf);
1300cc8e
KV
200
201 group_capab = 0;
202 if (p2p->p2ps_prov) {
203 group_capab |= P2P_GROUP_CAPAB_PERSISTENT_GROUP;
204 group_capab |= P2P_GROUP_CAPAB_PERSISTENT_RECONN;
205 if (p2p->cross_connect)
206 group_capab |= P2P_GROUP_CAPAB_CROSS_CONN;
207 if (p2p->cfg->p2p_intra_bss)
208 group_capab |= P2P_GROUP_CAPAB_INTRA_BSS_DIST;
209 }
18485b54 210 p2p_buf_add_capability(buf, p2p->dev_capab &
1300cc8e
KV
211 ~P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY,
212 group_capab);
b22128ef 213 p2p_buf_add_device_info(buf, p2p, NULL);
369678ad
KV
214 if (p2p->p2ps_prov) {
215 p2ps_add_pd_req_attrs(p2p, dev, buf, config_methods);
216 } else if (go) {
c5db8e51
KRK
217 p2p_buf_add_group_id(buf, go->info.p2p_device_addr,
218 go->oper_ssid, go->oper_ssid_len);
b22128ef
JM
219 }
220 p2p_buf_update_ie_hdr(buf, len);
221
222 /* WPS IE with Config Methods attribute */
223 p2p_build_wps_ie_config_methods(buf, config_methods);
224
9675ce35
JM
225#ifdef CONFIG_WIFI_DISPLAY
226 if (p2p->wfd_ie_prov_disc_req)
227 wpabuf_put_buf(buf, p2p->wfd_ie_prov_disc_req);
228#endif /* CONFIG_WIFI_DISPLAY */
229
86bd36f0
JM
230 if (p2p->vendor_elem && p2p->vendor_elem[VENDOR_ELEM_P2P_PD_REQ])
231 wpabuf_put_buf(buf, p2p->vendor_elem[VENDOR_ELEM_P2P_PD_REQ]);
232
b22128ef
JM
233 return buf;
234}
235
236
237static struct wpabuf * p2p_build_prov_disc_resp(struct p2p_data *p2p,
1300cc8e 238 struct p2p_device *dev,
b22128ef 239 u8 dialog_token,
1300cc8e 240 enum p2p_status_code status,
9675ce35 241 u16 config_methods,
1300cc8e 242 u32 adv_id,
9675ce35 243 const u8 *group_id,
1300cc8e
KV
244 size_t group_id_len,
245 const u8 *persist_ssid,
c3ddf2c7
MS
246 size_t persist_ssid_len,
247 const u8 *fcap,
248 u16 fcap_len)
b22128ef
JM
249{
250 struct wpabuf *buf;
9675ce35 251 size_t extra = 0;
1300cc8e 252 int persist = 0;
b22128ef 253
9675ce35
JM
254#ifdef CONFIG_WIFI_DISPLAY
255 struct wpabuf *wfd_ie = p2p->wfd_ie_prov_disc_resp;
256 if (wfd_ie && group_id) {
257 size_t i;
258 for (i = 0; i < p2p->num_groups; i++) {
259 struct p2p_group *g = p2p->groups[i];
260 struct wpabuf *ie;
261 if (!p2p_group_is_group_id_match(g, group_id,
262 group_id_len))
263 continue;
264 ie = p2p_group_get_wfd_ie(g);
265 if (ie) {
266 wfd_ie = ie;
267 break;
268 }
269 }
270 }
271 if (wfd_ie)
272 extra = wpabuf_len(wfd_ie);
273#endif /* CONFIG_WIFI_DISPLAY */
274
86bd36f0
JM
275 if (p2p->vendor_elem && p2p->vendor_elem[VENDOR_ELEM_P2P_PD_RESP])
276 extra += wpabuf_len(p2p->vendor_elem[VENDOR_ELEM_P2P_PD_RESP]);
277
1300cc8e 278 buf = wpabuf_alloc(1000 + extra);
b22128ef
JM
279 if (buf == NULL)
280 return NULL;
281
282 p2p_buf_add_public_action_hdr(buf, P2P_PROV_DISC_RESP, dialog_token);
283
1300cc8e
KV
284 /* Add P2P IE for P2PS */
285 if (p2p->p2ps_prov && p2p->p2ps_prov->adv_id == adv_id) {
1300cc8e
KV
286 u8 *len = p2p_buf_add_ie_hdr(buf);
287 struct p2ps_provision *prov = p2p->p2ps_prov;
288 u8 group_capab;
289
290 if (!status && prov->status != -1)
291 status = prov->status;
292
293 p2p_buf_add_status(buf, status);
294 group_capab = P2P_GROUP_CAPAB_PERSISTENT_GROUP |
295 P2P_GROUP_CAPAB_PERSISTENT_RECONN;
296 if (p2p->cross_connect)
297 group_capab |= P2P_GROUP_CAPAB_CROSS_CONN;
298 if (p2p->cfg->p2p_intra_bss)
299 group_capab |= P2P_GROUP_CAPAB_INTRA_BSS_DIST;
300 p2p_buf_add_capability(buf, p2p->dev_capab &
301 ~P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY,
302 group_capab);
303 p2p_buf_add_device_info(buf, p2p, NULL);
304
572f1ead 305 if (persist_ssid && p2p->cfg->get_persistent_group && dev &&
1300cc8e
KV
306 (status == P2P_SC_SUCCESS ||
307 status == P2P_SC_SUCCESS_DEFERRED)) {
d9d1b952 308 u8 ssid[SSID_MAX_LEN];
1300cc8e
KV
309 size_t ssid_len;
310 u8 go_dev_addr[ETH_ALEN];
1f1a08b4 311 u8 intended_addr[ETH_ALEN];
1300cc8e
KV
312
313 persist = p2p->cfg->get_persistent_group(
314 p2p->cfg->cb_ctx,
315 dev->info.p2p_device_addr,
316 persist_ssid, persist_ssid_len, go_dev_addr,
1f1a08b4
AO
317 ssid, &ssid_len, intended_addr);
318 if (persist) {
1300cc8e
KV
319 p2p_buf_add_persistent_group_info(
320 buf, go_dev_addr, ssid, ssid_len);
1f1a08b4
AO
321 if (!is_zero_ether_addr(intended_addr))
322 p2p_buf_add_intended_addr(
323 buf, intended_addr);
324 }
1300cc8e
KV
325 }
326
327 if (!persist && (prov->conncap & P2PS_SETUP_GROUP_OWNER))
ebd32943 328 p2ps_add_new_group_info(p2p, dev, buf);
1300cc8e
KV
329
330 /* Add Operating Channel if conncap indicates GO */
331 if (persist || (prov->conncap & P2PS_SETUP_GROUP_OWNER)) {
1300cc8e
KV
332 if (p2p->op_reg_class && p2p->op_channel)
333 p2p_buf_add_operating_channel(
334 buf, p2p->cfg->country,
335 p2p->op_reg_class,
336 p2p->op_channel);
337 else
338 p2p_buf_add_operating_channel(
339 buf, p2p->cfg->country,
340 p2p->cfg->op_reg_class,
341 p2p->cfg->op_channel);
342 }
343
344 p2p_buf_add_channel_list(buf, p2p->cfg->country,
ebd32943 345 &p2p->channels);
1300cc8e
KV
346
347 if (!persist && (status == P2P_SC_SUCCESS ||
348 status == P2P_SC_SUCCESS_DEFERRED))
349 p2p_buf_add_connection_capability(buf, prov->conncap);
350
351 p2p_buf_add_advertisement_id(buf, adv_id, prov->adv_mac);
352
353 p2p_buf_add_config_timeout(buf, p2p->go_timeout,
354 p2p->client_timeout);
355
356 p2p_buf_add_session_id(buf, prov->session_id,
357 prov->session_mac);
358
c3ddf2c7 359 p2p_buf_add_feature_capability(buf, fcap_len, fcap);
1300cc8e
KV
360 p2p_buf_update_ie_hdr(buf, len);
361 } else if (status != P2P_SC_SUCCESS || adv_id) {
362 u8 *len = p2p_buf_add_ie_hdr(buf);
363
364 p2p_buf_add_status(buf, status);
365
366 if (p2p->p2ps_prov)
367 p2p_buf_add_advertisement_id(buf, adv_id,
368 p2p->p2ps_prov->adv_mac);
369
370 p2p_buf_update_ie_hdr(buf, len);
371 }
372
b22128ef
JM
373 /* WPS IE with Config Methods attribute */
374 p2p_build_wps_ie_config_methods(buf, config_methods);
375
9675ce35
JM
376#ifdef CONFIG_WIFI_DISPLAY
377 if (wfd_ie)
378 wpabuf_put_buf(buf, wfd_ie);
379#endif /* CONFIG_WIFI_DISPLAY */
380
86bd36f0
JM
381 if (p2p->vendor_elem && p2p->vendor_elem[VENDOR_ELEM_P2P_PD_RESP])
382 wpabuf_put_buf(buf, p2p->vendor_elem[VENDOR_ELEM_P2P_PD_RESP]);
383
b22128ef
JM
384 return buf;
385}
386
387
1300cc8e
KV
388static int p2ps_setup_p2ps_prov(struct p2p_data *p2p, u32 adv_id,
389 u32 session_id, u16 method,
390 const u8 *session_mac, const u8 *adv_mac)
391{
392 struct p2ps_provision *tmp;
393
394 if (!p2p->p2ps_prov) {
395 p2p->p2ps_prov = os_zalloc(sizeof(struct p2ps_provision) + 1);
396 if (!p2p->p2ps_prov)
397 return -1;
398 } else {
399 os_memset(p2p->p2ps_prov, 0, sizeof(struct p2ps_provision) + 1);
400 }
401
402 tmp = p2p->p2ps_prov;
403 tmp->adv_id = adv_id;
404 tmp->session_id = session_id;
405 tmp->method = method;
406 os_memcpy(tmp->session_mac, session_mac, ETH_ALEN);
407 os_memcpy(tmp->adv_mac, adv_mac, ETH_ALEN);
408 tmp->info[0] = '\0';
409
410 return 0;
411}
412
413
c3ddf2c7
MS
414static u8 p2ps_own_preferred_cpt(const u8 *cpt_priority, u8 req_cpt_mask)
415{
416 int i;
417
418 for (i = 0; cpt_priority[i]; i++)
419 if (req_cpt_mask & cpt_priority[i])
420 return cpt_priority[i];
421
422 return 0;
423}
424
425
e4f90a6a
IP
426/* Check if the message contains a valid P2PS PD Request */
427static int p2ps_validate_pd_req(struct p2p_data *p2p, struct p2p_message *msg,
428 const u8 *addr)
429{
430 u8 group_id = 0;
431 u8 intended_addr = 0;
432 u8 operating_channel = 0;
433 u8 channel_list = 0;
434 u8 config_timeout = 0;
435 u8 listen_channel = 0;
436
437#define P2PS_PD_REQ_CHECK(_val, _attr) \
438do { \
439 if ((_val) && !msg->_attr) { \
440 p2p_dbg(p2p, "Not P2PS PD Request. Missing %s", #_attr); \
441 return -1; \
442 } \
443} while (0)
444
445 P2PS_PD_REQ_CHECK(1, adv_id);
446 P2PS_PD_REQ_CHECK(1, session_id);
447 P2PS_PD_REQ_CHECK(1, session_mac);
448 P2PS_PD_REQ_CHECK(1, adv_mac);
449 P2PS_PD_REQ_CHECK(1, capability);
450 P2PS_PD_REQ_CHECK(1, p2p_device_info);
451 P2PS_PD_REQ_CHECK(1, feature_cap);
452
453 /*
454 * We don't need to check Connection Capability, Persistent Group,
455 * and related attributes for follow-on PD Request with a status
456 * other than SUCCESS_DEFERRED.
457 */
458 if (msg->status && *msg->status != P2P_SC_SUCCESS_DEFERRED)
459 return 0;
460
461 P2PS_PD_REQ_CHECK(1, conn_cap);
462
463 /*
464 * Note 1: A feature capability attribute structure can be changed
465 * in the future. The assumption is that such modifications are
466 * backward compatible, therefore we allow processing of msg.feature_cap
467 * exceeding the size of the p2ps_feature_capab structure.
468 * Note 2: Verification of msg.feature_cap_len below has to be changed
469 * to allow 2 byte feature capability processing if
470 * struct p2ps_feature_capab is extended to include additional fields
471 * and it affects the structure size.
472 */
473 if (msg->feature_cap_len < sizeof(struct p2ps_feature_capab)) {
474 p2p_dbg(p2p, "P2PS: Invalid feature capability len");
475 return -1;
476 }
477
478 switch (*msg->conn_cap) {
479 case P2PS_SETUP_NEW:
480 group_id = 1;
481 intended_addr = 1;
482 operating_channel = 1;
483 channel_list = 1;
484 config_timeout = 1;
485 listen_channel = 1;
486 break;
487 case P2PS_SETUP_CLIENT:
488 channel_list = 1;
489 listen_channel = 1;
490 break;
491 case P2PS_SETUP_GROUP_OWNER:
492 group_id = 1;
493 intended_addr = 1;
494 operating_channel = 1;
495 break;
496 case P2PS_SETUP_NEW | P2PS_SETUP_GROUP_OWNER:
497 group_id = 1;
498 operating_channel = 1;
499 intended_addr = 1;
500 channel_list = 1;
501 config_timeout = 1;
502 break;
503 case P2PS_SETUP_CLIENT | P2PS_SETUP_GROUP_OWNER:
504 group_id = 1;
505 intended_addr = 1;
506 operating_channel = 1;
507 channel_list = 1;
508 config_timeout = 1;
509 break;
510 default:
511 p2p_dbg(p2p, "Invalid P2PS PD connection capability");
512 return -1;
513 }
514
515 if (msg->persistent_dev) {
516 channel_list = 1;
517 config_timeout = 1;
518 if (os_memcmp(msg->persistent_dev, addr, ETH_ALEN) == 0) {
519 intended_addr = 1;
520 operating_channel = 1;
521 }
522 }
523
524 P2PS_PD_REQ_CHECK(group_id, group_id);
525 P2PS_PD_REQ_CHECK(intended_addr, intended_addr);
526 P2PS_PD_REQ_CHECK(operating_channel, operating_channel);
527 P2PS_PD_REQ_CHECK(channel_list, channel_list);
528 P2PS_PD_REQ_CHECK(config_timeout, config_timeout);
529 P2PS_PD_REQ_CHECK(listen_channel, listen_channel);
530
531#undef P2PS_PD_REQ_CHECK
532
533 return 0;
534}
535
536
b22128ef
JM
537void p2p_process_prov_disc_req(struct p2p_data *p2p, const u8 *sa,
538 const u8 *data, size_t len, int rx_freq)
539{
540 struct p2p_message msg;
541 struct p2p_device *dev;
542 int freq;
1300cc8e 543 enum p2p_status_code reject = P2P_SC_FAIL_INCOMPATIBLE_PARAMS;
b22128ef 544 struct wpabuf *resp;
1300cc8e
KV
545 u32 adv_id = 0;
546 struct p2ps_advertisement *p2ps_adv = NULL;
547 u8 conncap = P2PS_SETUP_NEW;
548 u8 auto_accept = 0;
549 u32 session_id = 0;
550 u8 session_mac[ETH_ALEN];
551 u8 adv_mac[ETH_ALEN];
2a098e36 552 const u8 *group_mac;
1300cc8e
KV
553 int passwd_id = DEV_PW_DEFAULT;
554 u16 config_methods;
2fc866d1 555 u16 allowed_config_methods = WPS_CONFIG_DISPLAY | WPS_CONFIG_KEYPAD;
c3ddf2c7
MS
556 struct p2ps_feature_capab resp_fcap = { 0, 0 };
557 struct p2ps_feature_capab *req_fcap;
20324d47
IP
558 u8 remote_conncap;
559 u16 method;
b22128ef
JM
560
561 if (p2p_parse(data, len, &msg))
562 return;
563
ed496f13 564 p2p_dbg(p2p, "Received Provision Discovery Request from " MACSTR
b22128ef
JM
565 " with config methods 0x%x (freq=%d)",
566 MAC2STR(sa), msg.wps_config_methods, rx_freq);
2a098e36 567 group_mac = msg.intended_addr;
b22128ef
JM
568
569 dev = p2p_get_device(p2p, sa);
bfe3557a 570 if (dev == NULL || (dev->flags & P2P_DEV_PROBE_REQ_ONLY)) {
ed496f13
JM
571 p2p_dbg(p2p, "Provision Discovery Request from unknown peer "
572 MACSTR, MAC2STR(sa));
3dfd0484 573
c5f10e80 574 if (p2p_add_device(p2p, sa, rx_freq, NULL, 0, data + 1, len - 1,
3dfd0484 575 0)) {
ed496f13
JM
576 p2p_dbg(p2p, "Provision Discovery Request add device failed "
577 MACSTR, MAC2STR(sa));
4acd5ac6
IP
578 goto out;
579 }
580
581 if (!dev) {
582 dev = p2p_get_device(p2p, sa);
583 if (!dev) {
584 p2p_dbg(p2p,
585 "Provision Discovery device not found "
586 MACSTR, MAC2STR(sa));
587 goto out;
588 }
17bef1e9 589 }
9675ce35
JM
590 } else if (msg.wfd_subelems) {
591 wpabuf_free(dev->info.wfd_subelems);
592 dev->info.wfd_subelems = wpabuf_dup(msg.wfd_subelems);
b22128ef
JM
593 }
594
2fc866d1
AO
595 if (msg.adv_id)
596 allowed_config_methods |= WPS_CONFIG_P2PS;
597 else
598 allowed_config_methods |= WPS_CONFIG_PUSHBUTTON;
599
600 if (!(msg.wps_config_methods & allowed_config_methods)) {
ed496f13 601 p2p_dbg(p2p, "Unsupported Config Methods in Provision Discovery Request");
b22128ef
JM
602 goto out;
603 }
604
1300cc8e
KV
605 /* Legacy (non-P2PS) - Unknown groups allowed for P2PS */
606 if (!msg.adv_id && msg.group_id) {
051c7bbd
JM
607 size_t i;
608 for (i = 0; i < p2p->num_groups; i++) {
609 if (p2p_group_is_group_id_match(p2p->groups[i],
610 msg.group_id,
611 msg.group_id_len))
612 break;
613 }
614 if (i == p2p->num_groups) {
ed496f13 615 p2p_dbg(p2p, "PD request for unknown P2P Group ID - reject");
051c7bbd
JM
616 goto out;
617 }
618 }
619
4acd5ac6
IP
620 dev->flags &= ~(P2P_DEV_PD_PEER_DISPLAY |
621 P2P_DEV_PD_PEER_KEYPAD |
622 P2P_DEV_PD_PEER_P2PS);
623
624 /* Remove stale persistent groups */
625 if (p2p->cfg->remove_stale_groups) {
626 p2p->cfg->remove_stale_groups(
627 p2p->cfg->cb_ctx, dev->info.p2p_device_addr,
628 msg.persistent_dev,
629 msg.persistent_ssid, msg.persistent_ssid_len);
1300cc8e 630 }
4acd5ac6 631
b22128ef 632 if (msg.wps_config_methods & WPS_CONFIG_DISPLAY) {
ed496f13 633 p2p_dbg(p2p, "Peer " MACSTR
b22128ef 634 " requested us to show a PIN on display", MAC2STR(sa));
4acd5ac6 635 dev->flags |= P2P_DEV_PD_PEER_KEYPAD;
1300cc8e 636 passwd_id = DEV_PW_USER_SPECIFIED;
b22128ef 637 } else if (msg.wps_config_methods & WPS_CONFIG_KEYPAD) {
ed496f13 638 p2p_dbg(p2p, "Peer " MACSTR
b22128ef
JM
639 " requested us to write its PIN using keypad",
640 MAC2STR(sa));
4acd5ac6 641 dev->flags |= P2P_DEV_PD_PEER_DISPLAY;
1300cc8e
KV
642 passwd_id = DEV_PW_REGISTRAR_SPECIFIED;
643 } else if (msg.wps_config_methods & WPS_CONFIG_P2PS) {
644 p2p_dbg(p2p, "Peer " MACSTR " requesting P2PS PIN",
645 MAC2STR(sa));
4acd5ac6 646 dev->flags |= P2P_DEV_PD_PEER_P2PS;
1300cc8e 647 passwd_id = DEV_PW_P2PS_DEFAULT;
b22128ef
JM
648 }
649
1300cc8e
KV
650 reject = P2P_SC_SUCCESS;
651
652 os_memset(session_mac, 0, ETH_ALEN);
653 os_memset(adv_mac, 0, ETH_ALEN);
1300cc8e 654
e4f90a6a
IP
655 /*
656 * Validate a P2PS PD Request and skip P2PS processing if not a valid
657 * P2PS PD.
c3ddf2c7 658 */
e4f90a6a
IP
659 if (msg.adv_id) {
660 /*
661 * Set adv_id here, so that in case of an error, a P2PS PD
662 * Response will be sent.
663 */
664 adv_id = WPA_GET_LE32(msg.adv_id);
665 if (p2ps_validate_pd_req(p2p, &msg, sa) < 0) {
666 reject = P2P_SC_FAIL_INVALID_PARAMS;
667 goto out;
668 }
669 } else {
20324d47 670 goto out;
e4f90a6a 671 }
1300cc8e 672
20324d47 673 req_fcap = (struct p2ps_feature_capab *) msg.feature_cap;
c3ddf2c7 674
20324d47
IP
675 os_memcpy(session_mac, msg.session_mac, ETH_ALEN);
676 os_memcpy(adv_mac, msg.adv_mac, ETH_ALEN);
1300cc8e 677
20324d47 678 session_id = WPA_GET_LE32(msg.session_id);
1300cc8e 679
20324d47
IP
680 if (msg.conn_cap)
681 conncap = *msg.conn_cap;
682 remote_conncap = conncap;
1300cc8e 683
e4f90a6a
IP
684 if (!msg.status) {
685 if (os_memcmp(p2p->cfg->dev_addr, msg.adv_mac, ETH_ALEN)) {
686 p2p_dbg(p2p,
687 "P2PS PD adv mac does not match the local one");
688 reject = P2P_SC_FAIL_INCOMPATIBLE_PARAMS;
689 goto out;
690 }
691
692 p2ps_adv = p2p_service_p2ps_id(p2p, adv_id);
693 if (!p2ps_adv) {
694 p2p_dbg(p2p, "P2PS PD invalid adv_id=0x%X", adv_id);
695 reject = P2P_SC_FAIL_INCOMPATIBLE_PARAMS;
696 goto out;
697 }
698 p2p_dbg(p2p, "adv_id: 0x%X, p2ps_adv: %p", adv_id, p2ps_adv);
699 }
700
20324d47 701 if (p2ps_adv) {
ebd32943
IP
702 unsigned int forced_freq, pref_freq;
703
20324d47
IP
704 auto_accept = p2ps_adv->auto_accept;
705 conncap = p2p->cfg->p2ps_group_capability(p2p->cfg->cb_ctx,
ebd32943
IP
706 conncap, auto_accept,
707 &forced_freq,
708 &pref_freq);
709
710 p2p_prepare_channel(p2p, dev, forced_freq, pref_freq, 0);
1300cc8e 711
20324d47
IP
712 p2p_dbg(p2p, "Conncap: local:%d remote:%d result:%d",
713 auto_accept, remote_conncap, conncap);
1300cc8e 714
20324d47 715 resp_fcap.cpt = p2ps_own_preferred_cpt(p2ps_adv->cpt_priority,
c3ddf2c7
MS
716 req_fcap->cpt);
717
20324d47
IP
718 p2p_dbg(p2p, "cpt: service:0x%x remote:0x%x result:0x%x",
719 p2ps_adv->cpt_mask, req_fcap->cpt, resp_fcap.cpt);
c3ddf2c7 720
20324d47
IP
721 if (!resp_fcap.cpt) {
722 p2p_dbg(p2p,
723 "Incompatible P2PS feature capability CPT bitmask");
724 reject = P2P_SC_FAIL_INCOMPATIBLE_PARAMS;
725 } else if (p2ps_adv->config_methods &&
726 !(msg.wps_config_methods &
727 p2ps_adv->config_methods)) {
728 p2p_dbg(p2p,
729 "Unsupported config methods in Provision Discovery Request (own=0x%x peer=0x%x)",
730 p2ps_adv->config_methods,
731 msg.wps_config_methods);
732 reject = P2P_SC_FAIL_INCOMPATIBLE_PARAMS;
733 } else if (!p2ps_adv->state) {
734 p2p_dbg(p2p, "P2PS state unavailable");
735 reject = P2P_SC_FAIL_UNABLE_TO_ACCOMMODATE;
736 } else if (!conncap) {
737 p2p_dbg(p2p, "Conncap resolution failed");
1300cc8e 738 reject = P2P_SC_FAIL_INCOMPATIBLE_PARAMS;
1300cc8e
KV
739 }
740
20324d47
IP
741 if (msg.wps_config_methods & WPS_CONFIG_KEYPAD) {
742 p2p_dbg(p2p, "Keypad - always defer");
743 auto_accept = 0;
744 }
745
23eef570
IP
746 if ((remote_conncap & (P2PS_SETUP_NEW | P2PS_SETUP_CLIENT) ||
747 msg.persistent_dev) && conncap != P2PS_SETUP_NEW &&
748 msg.channel_list && msg.channel_list_len &&
749 p2p_peer_channels_check(p2p, &p2p->channels, dev,
750 msg.channel_list,
751 msg.channel_list_len) < 0) {
752 p2p_dbg(p2p,
753 "No common channels - force deferred flow");
754 auto_accept = 0;
755 }
756
757 if (((remote_conncap & P2PS_SETUP_GROUP_OWNER) ||
758 msg.persistent_dev) && msg.operating_channel) {
759 struct p2p_channels intersect;
760
761 /*
762 * There are cases where only the operating channel is
763 * provided. This requires saving the channel as the
764 * supported channel list, and verifying that it is
765 * supported.
766 */
767 if (dev->channels.reg_classes == 0 ||
768 !p2p_channels_includes(&dev->channels,
769 msg.operating_channel[3],
770 msg.operating_channel[4])) {
771 struct p2p_channels *ch = &dev->channels;
772
773 os_memset(ch, 0, sizeof(*ch));
774 ch->reg_class[0].reg_class =
775 msg.operating_channel[3];
776 ch->reg_class[0].channel[0] =
777 msg.operating_channel[4];
778 ch->reg_class[0].channels = 1;
779 ch->reg_classes = 1;
780 }
781
782 p2p_channels_intersect(&p2p->channels, &dev->channels,
783 &intersect);
784
785 if (intersect.reg_classes == 0) {
786 p2p_dbg(p2p,
787 "No common channels - force deferred flow");
788 auto_accept = 0;
789 }
790 }
791
20324d47 792 if (auto_accept || reject != P2P_SC_SUCCESS) {
1300cc8e
KV
793 struct p2ps_provision *tmp;
794
1300cc8e
KV
795 if (p2ps_setup_p2ps_prov(p2p, adv_id, session_id,
796 msg.wps_config_methods,
797 session_mac, adv_mac) < 0) {
798 reject = P2P_SC_FAIL_UNABLE_TO_ACCOMMODATE;
799 goto out;
800 }
20324d47 801
1300cc8e 802 tmp = p2p->p2ps_prov;
ebd32943
IP
803 tmp->force_freq = forced_freq;
804 tmp->pref_freq = pref_freq;
20324d47
IP
805 if (conncap) {
806 tmp->conncap = conncap;
807 tmp->status = P2P_SC_SUCCESS;
808 } else {
809 tmp->conncap = auto_accept;
810 tmp->status = P2P_SC_FAIL_INCOMPATIBLE_PARAMS;
811 }
812
813 if (reject != P2P_SC_SUCCESS)
814 goto out;
815 }
20324d47
IP
816 }
817
818 if (!msg.status && !auto_accept &&
819 (!p2p->p2ps_prov || p2p->p2ps_prov->adv_id != adv_id)) {
820 struct p2ps_provision *tmp;
821
822 if (!conncap) {
823 reject = P2P_SC_FAIL_INCOMPATIBLE_PARAMS;
824 goto out;
1300cc8e
KV
825 }
826
20324d47
IP
827 if (p2ps_setup_p2ps_prov(p2p, adv_id, session_id,
828 msg.wps_config_methods,
829 session_mac, adv_mac) < 0) {
830 reject = P2P_SC_FAIL_UNABLE_TO_ACCOMMODATE;
831 goto out;
1300cc8e 832 }
20324d47
IP
833 tmp = p2p->p2ps_prov;
834 reject = P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE;
835 tmp->status = reject;
836 }
837
838 /* Not a P2PS Follow-on PD */
839 if (!msg.status)
840 goto out;
841
842 if (*msg.status && *msg.status != P2P_SC_SUCCESS_DEFERRED) {
843 reject = *msg.status;
844 goto out;
1300cc8e 845 }
b22128ef 846
20324d47
IP
847 if (*msg.status != P2P_SC_SUCCESS_DEFERRED || !p2p->p2ps_prov)
848 goto out;
849
e4f90a6a
IP
850 if (p2p->p2ps_prov->adv_id != adv_id ||
851 os_memcmp(p2p->p2ps_prov->adv_mac, msg.adv_mac, ETH_ALEN)) {
852 p2p_dbg(p2p,
853 "P2PS Follow-on PD with mismatch Advertisement ID/MAC");
854 goto out;
855 }
856
857 if (p2p->p2ps_prov->session_id != session_id ||
858 os_memcmp(p2p->p2ps_prov->session_mac, msg.session_mac, ETH_ALEN)) {
859 p2p_dbg(p2p, "P2PS Follow-on PD with mismatch Session ID/MAC");
860 goto out;
861 }
862
20324d47
IP
863 method = p2p->p2ps_prov->method;
864
865 conncap = p2p->cfg->p2ps_group_capability(p2p->cfg->cb_ctx,
866 remote_conncap,
ebd32943
IP
867 p2p->p2ps_prov->conncap,
868 &p2p->p2ps_prov->force_freq,
869 &p2p->p2ps_prov->pref_freq);
20324d47
IP
870
871 resp_fcap.cpt = p2ps_own_preferred_cpt(p2p->p2ps_prov->cpt_priority,
872 req_fcap->cpt);
873
874 p2p_dbg(p2p, "cpt: local:0x%x remote:0x%x result:0x%x",
875 p2p->p2ps_prov->cpt_mask, req_fcap->cpt, resp_fcap.cpt);
876
ebd32943
IP
877 p2p_prepare_channel(p2p, dev, p2p->p2ps_prov->force_freq,
878 p2p->p2ps_prov->pref_freq, 0);
879
20324d47
IP
880 /*
881 * Ensure that if we asked for PIN originally, our method is consistent
882 * with original request.
883 */
884 if (method & WPS_CONFIG_DISPLAY)
885 method = WPS_CONFIG_KEYPAD;
886 else if (method & WPS_CONFIG_KEYPAD)
887 method = WPS_CONFIG_DISPLAY;
888
889 if (!conncap || !(msg.wps_config_methods & method)) {
890 /*
891 * Reject this "Deferred Accept*
892 * if incompatible conncap or method
893 */
894 reject = P2P_SC_FAIL_INCOMPATIBLE_PARAMS;
895 } else if (!resp_fcap.cpt) {
896 p2p_dbg(p2p,
897 "Incompatible P2PS feature capability CPT bitmask");
898 reject = P2P_SC_FAIL_INCOMPATIBLE_PARAMS;
23eef570
IP
899 } else if ((remote_conncap & (P2PS_SETUP_NEW | P2PS_SETUP_CLIENT) ||
900 msg.persistent_dev) && conncap != P2PS_SETUP_NEW &&
901 msg.channel_list && msg.channel_list_len &&
902 p2p_peer_channels_check(p2p, &p2p->channels, dev,
903 msg.channel_list,
904 msg.channel_list_len) < 0) {
905 p2p_dbg(p2p,
906 "No common channels in Follow-On Provision Discovery Request");
907 reject = P2P_SC_FAIL_NO_COMMON_CHANNELS;
20324d47
IP
908 } else {
909 reject = P2P_SC_SUCCESS;
910 }
911
23eef570
IP
912 dev->oper_freq = 0;
913 if (reject == P2P_SC_SUCCESS || reject == P2P_SC_SUCCESS_DEFERRED) {
914 u8 tmp;
915
916 if (msg.operating_channel)
917 dev->oper_freq =
918 p2p_channel_to_freq(msg.operating_channel[3],
919 msg.operating_channel[4]);
920
921 if ((conncap & P2PS_SETUP_GROUP_OWNER) &&
922 p2p_go_select_channel(p2p, dev, &tmp) < 0)
923 reject = P2P_SC_FAIL_NO_COMMON_CHANNELS;
924 }
925
20324d47
IP
926 p2p->p2ps_prov->status = reject;
927 p2p->p2ps_prov->conncap = conncap;
928
b22128ef 929out:
1300cc8e
KV
930 if (reject == P2P_SC_SUCCESS ||
931 reject == P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE)
932 config_methods = msg.wps_config_methods;
933 else
934 config_methods = 0;
f94e4c20
MS
935
936 /*
937 * Send PD Response for an initial PD Request or for follow-on
938 * PD Request with P2P_SC_SUCCESS_DEFERRED status.
939 */
940 if (!msg.status || *msg.status == P2P_SC_SUCCESS_DEFERRED) {
941 resp = p2p_build_prov_disc_resp(p2p, dev, msg.dialog_token,
942 reject, config_methods, adv_id,
943 msg.group_id, msg.group_id_len,
944 msg.persistent_ssid,
945 msg.persistent_ssid_len,
946 (const u8 *) &resp_fcap,
947 sizeof(resp_fcap));
948 if (!resp) {
949 p2p_parse_free(&msg);
950 return;
951 }
952 p2p_dbg(p2p, "Sending Provision Discovery Response");
953 if (rx_freq > 0)
954 freq = rx_freq;
955 else
956 freq = p2p_channel_to_freq(p2p->cfg->reg_class,
957 p2p->cfg->channel);
958 if (freq < 0) {
959 p2p_dbg(p2p, "Unknown regulatory class/channel");
960 wpabuf_free(resp);
961 p2p_parse_free(&msg);
962 return;
963 }
964 p2p->pending_action_state = P2P_PENDING_PD_RESPONSE;
965 if (p2p_send_action(p2p, freq, sa, p2p->cfg->dev_addr,
966 p2p->cfg->dev_addr,
967 wpabuf_head(resp), wpabuf_len(resp),
968 200) < 0)
969 p2p_dbg(p2p, "Failed to send Action frame");
970 else
971 p2p->send_action_in_progress = 1;
972
b22128ef 973 wpabuf_free(resp);
b22128ef 974 }
b22128ef 975
4acd5ac6
IP
976 if (!dev) {
977 p2p_parse_free(&msg);
978 return;
979 }
980
8bb8e6ed
IP
981 freq = 0;
982 if (reject == P2P_SC_SUCCESS && conncap == P2PS_SETUP_GROUP_OWNER) {
983 freq = p2p_channel_to_freq(p2p->op_reg_class,
984 p2p->op_channel);
985 if (freq < 0)
986 freq = 0;
987 }
988
1300cc8e
KV
989 if (!p2p->cfg->p2ps_prov_complete) {
990 /* Don't emit anything */
991 } else if (msg.status && *msg.status != P2P_SC_SUCCESS &&
992 *msg.status != P2P_SC_SUCCESS_DEFERRED) {
993 reject = *msg.status;
994 p2p->cfg->p2ps_prov_complete(p2p->cfg->cb_ctx, reject,
995 sa, adv_mac, session_mac,
996 NULL, adv_id, session_id,
997 0, 0, msg.persistent_ssid,
998 msg.persistent_ssid_len,
8bb8e6ed 999 0, 0, NULL, NULL, 0, freq);
1300cc8e
KV
1000 } else if (msg.status && *msg.status == P2P_SC_SUCCESS_DEFERRED &&
1001 p2p->p2ps_prov) {
1002 p2p->p2ps_prov->status = reject;
1003 p2p->p2ps_prov->conncap = conncap;
1004
1005 if (reject != P2P_SC_SUCCESS)
1006 p2p->cfg->p2ps_prov_complete(p2p->cfg->cb_ctx, reject,
1007 sa, adv_mac, session_mac,
1008 NULL, adv_id,
1009 session_id, conncap, 0,
1010 msg.persistent_ssid,
1011 msg.persistent_ssid_len, 0,
8bb8e6ed 1012 0, NULL, NULL, 0, freq);
1300cc8e
KV
1013 else
1014 p2p->cfg->p2ps_prov_complete(p2p->cfg->cb_ctx,
1015 *msg.status,
1016 sa, adv_mac, session_mac,
1017 group_mac, adv_id,
1018 session_id, conncap,
1019 passwd_id,
1020 msg.persistent_ssid,
1021 msg.persistent_ssid_len, 0,
88f3d7c9
MS
1022 0, NULL,
1023 (const u8 *) &resp_fcap,
8bb8e6ed 1024 sizeof(resp_fcap), freq);
1300cc8e
KV
1025 } else if (msg.status && p2p->p2ps_prov) {
1026 p2p->p2ps_prov->status = P2P_SC_SUCCESS;
1027 p2p->cfg->p2ps_prov_complete(p2p->cfg->cb_ctx, *msg.status, sa,
1028 adv_mac, session_mac, group_mac,
1029 adv_id, session_id, conncap,
1030 passwd_id,
1031 msg.persistent_ssid,
1032 msg.persistent_ssid_len,
88f3d7c9
MS
1033 0, 0, NULL,
1034 (const u8 *) &resp_fcap,
8bb8e6ed 1035 sizeof(resp_fcap), freq);
1300cc8e
KV
1036 } else if (msg.status) {
1037 } else if (auto_accept && reject == P2P_SC_SUCCESS) {
1038 p2p->cfg->p2ps_prov_complete(p2p->cfg->cb_ctx, P2P_SC_SUCCESS,
1039 sa, adv_mac, session_mac,
1040 group_mac, adv_id, session_id,
1041 conncap, passwd_id,
1042 msg.persistent_ssid,
1043 msg.persistent_ssid_len,
88f3d7c9
MS
1044 0, 0, NULL,
1045 (const u8 *) &resp_fcap,
8bb8e6ed 1046 sizeof(resp_fcap), freq);
1300cc8e
KV
1047 } else if (reject == P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE &&
1048 (!msg.session_info || !msg.session_info_len)) {
1049 p2p->p2ps_prov->method = msg.wps_config_methods;
1050
1051 p2p->cfg->p2ps_prov_complete(p2p->cfg->cb_ctx, P2P_SC_SUCCESS,
1052 sa, adv_mac, session_mac,
1053 group_mac, adv_id, session_id,
1054 conncap, passwd_id,
1055 msg.persistent_ssid,
1056 msg.persistent_ssid_len,
88f3d7c9
MS
1057 0, 1, NULL,
1058 (const u8 *) &resp_fcap,
8bb8e6ed 1059 sizeof(resp_fcap), freq);
1300cc8e
KV
1060 } else if (reject == P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE) {
1061 size_t buf_len = msg.session_info_len;
1062 char *buf = os_malloc(2 * buf_len + 1);
1063
1064 if (buf) {
1065 p2p->p2ps_prov->method = msg.wps_config_methods;
1066
1067 utf8_escape((char *) msg.session_info, buf_len,
1068 buf, 2 * buf_len + 1);
1069
1070 p2p->cfg->p2ps_prov_complete(
1071 p2p->cfg->cb_ctx, P2P_SC_SUCCESS, sa,
1072 adv_mac, session_mac, group_mac, adv_id,
1073 session_id, conncap, passwd_id,
1074 msg.persistent_ssid, msg.persistent_ssid_len,
88f3d7c9 1075 0, 1, buf,
8bb8e6ed
IP
1076 (const u8 *) &resp_fcap, sizeof(resp_fcap),
1077 freq);
1300cc8e
KV
1078
1079 os_free(buf);
1080 }
1081 }
1082
93f22b45
MS
1083 /*
1084 * prov_disc_req callback is used to generate P2P-PROV-DISC-ENTER-PIN,
1085 * P2P-PROV-DISC-SHOW-PIN, and P2P-PROV-DISC-PBC-REQ events.
1086 * Call it either on legacy P2P PD or on P2PS PD only if we need to
1087 * enter/show PIN.
1088 *
1089 * The callback is called in the following cases:
1090 * 1. Legacy P2P PD request, response status SUCCESS
1091 * 2. P2PS advertiser, method: DISPLAY, autoaccept: TRUE,
1092 * response status: SUCCESS
1093 * 3. P2PS advertiser, method DISPLAY, autoaccept: FALSE,
1094 * response status: INFO_CURRENTLY_UNAVAILABLE
1095 * 4. P2PS advertiser, method: KEYPAD, autoaccept==any,
1096 * response status: INFO_CURRENTLY_UNAVAILABLE
1097 * 5. P2PS follow-on with SUCCESS_DEFERRED,
1098 * advertiser role: DISPLAY, autoaccept: FALSE,
1099 * seeker: KEYPAD, response status: SUCCESS
1100 */
1101 if (p2p->cfg->prov_disc_req &&
1102 ((reject == P2P_SC_SUCCESS && !msg.adv_id) ||
1103 (!msg.status &&
1104 (reject == P2P_SC_SUCCESS ||
1105 reject == P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE) &&
1106 passwd_id == DEV_PW_USER_SPECIFIED) ||
1107 (!msg.status &&
1108 reject == P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE &&
1109 passwd_id == DEV_PW_REGISTRAR_SPECIFIED) ||
1110 (reject == P2P_SC_SUCCESS &&
1111 msg.status && *msg.status == P2P_SC_SUCCESS_DEFERRED &&
1112 passwd_id == DEV_PW_REGISTRAR_SPECIFIED))) {
b22128ef 1113 const u8 *dev_addr = sa;
93f22b45 1114
b22128ef
JM
1115 if (msg.p2p_device_addr)
1116 dev_addr = msg.p2p_device_addr;
1117 p2p->cfg->prov_disc_req(p2p->cfg->cb_ctx, sa,
1118 msg.wps_config_methods,
1119 dev_addr, msg.pri_dev_type,
1120 msg.device_name, msg.config_methods,
1121 msg.capability ? msg.capability[0] : 0,
1122 msg.capability ? msg.capability[1] :
c3f42784
JM
1123 0,
1124 msg.group_id, msg.group_id_len);
93f22b45 1125 }
223ccebf 1126
4acd5ac6 1127 if (reject == P2P_SC_SUCCESS) {
93f22b45
MS
1128 switch (config_methods) {
1129 case WPS_CONFIG_DISPLAY:
1130 dev->wps_prov_info = WPS_CONFIG_KEYPAD;
1131 break;
1132 case WPS_CONFIG_KEYPAD:
1133 dev->wps_prov_info = WPS_CONFIG_DISPLAY;
1134 break;
1135 case WPS_CONFIG_PUSHBUTTON:
1136 dev->wps_prov_info = WPS_CONFIG_PUSHBUTTON;
1137 break;
1138 case WPS_CONFIG_P2PS:
1139 dev->wps_prov_info = WPS_CONFIG_P2PS;
1140 break;
1141 default:
1142 dev->wps_prov_info = 0;
1143 break;
223ccebf 1144 }
93f22b45
MS
1145
1146 if (msg.intended_addr)
1147 os_memcpy(dev->interface_addr, msg.intended_addr,
1148 ETH_ALEN);
b22128ef
JM
1149 }
1150 p2p_parse_free(&msg);
1151}
1152
1153
1f14e2bf
AO
1154static int p2p_validate_p2ps_pd_resp(struct p2p_data *p2p,
1155 struct p2p_message *msg)
1156{
1157 u8 conn_cap_go = 0;
1158 u8 conn_cap_cli = 0;
1159 u32 session_id;
1160 u32 adv_id;
1161
1162#define P2PS_PD_RESP_CHECK(_val, _attr) \
1163 do { \
1164 if ((_val) && !msg->_attr) { \
1165 p2p_dbg(p2p, "P2PS PD Response missing " #_attr); \
1166 return -1; \
1167 } \
1168 } while (0)
1169
1170 P2PS_PD_RESP_CHECK(1, status);
1171 P2PS_PD_RESP_CHECK(1, adv_id);
1172 P2PS_PD_RESP_CHECK(1, adv_mac);
1173 P2PS_PD_RESP_CHECK(1, capability);
1174 P2PS_PD_RESP_CHECK(1, p2p_device_info);
1175 P2PS_PD_RESP_CHECK(1, session_id);
1176 P2PS_PD_RESP_CHECK(1, session_mac);
1177 P2PS_PD_RESP_CHECK(1, feature_cap);
1178
1179 session_id = WPA_GET_LE32(msg->session_id);
1180 adv_id = WPA_GET_LE32(msg->adv_id);
1181
1182 if (p2p->p2ps_prov->session_id != session_id) {
1183 p2p_dbg(p2p,
1184 "Ignore PD Response with unexpected Session ID");
1185 return -1;
1186 }
1187
1188 if (os_memcmp(p2p->p2ps_prov->session_mac, msg->session_mac,
1189 ETH_ALEN)) {
1190 p2p_dbg(p2p,
1191 "Ignore PD Response with unexpected Session MAC");
1192 return -1;
1193 }
1194
1195 if (p2p->p2ps_prov->adv_id != adv_id) {
1196 p2p_dbg(p2p,
1197 "Ignore PD Response with unexpected Advertisement ID");
1198 return -1;
1199 }
1200
1201 if (os_memcmp(p2p->p2ps_prov->adv_mac, msg->adv_mac, ETH_ALEN) != 0) {
1202 p2p_dbg(p2p,
1203 "Ignore PD Response with unexpected Advertisement MAC");
1204 return -1;
1205 }
1206
1207 if (msg->listen_channel) {
1208 p2p_dbg(p2p,
1209 "Ignore malformed PD Response - unexpected Listen Channel");
1210 return -1;
1211 }
1212
1213 if (*msg->status == P2P_SC_SUCCESS &&
1214 !(!!msg->conn_cap ^ !!msg->persistent_dev)) {
1215 p2p_dbg(p2p,
1216 "Ignore malformed PD Response - either conn_cap or persistent group should be present");
1217 return -1;
1218 }
1219
1220 if (msg->persistent_dev && *msg->status != P2P_SC_SUCCESS) {
1221 p2p_dbg(p2p,
1222 "Ignore malformed PD Response - persistent group is present, but the status isn't success");
1223 return -1;
1224 }
1225
1226 if (msg->conn_cap) {
1227 conn_cap_go = *msg->conn_cap == P2PS_SETUP_GROUP_OWNER;
1228 conn_cap_cli = *msg->conn_cap == P2PS_SETUP_CLIENT;
1229 }
1230
1231 P2PS_PD_RESP_CHECK(msg->persistent_dev || conn_cap_go || conn_cap_cli,
1232 channel_list);
1233 P2PS_PD_RESP_CHECK(msg->persistent_dev || conn_cap_go || conn_cap_cli,
1234 config_timeout);
1235
1236 P2PS_PD_RESP_CHECK(conn_cap_go, group_id);
1237 P2PS_PD_RESP_CHECK(conn_cap_go, intended_addr);
1238 P2PS_PD_RESP_CHECK(conn_cap_go, operating_channel);
1239 /*
1240 * TODO: Also validate that operating channel is present if the device
1241 * is a GO in a persistent group. We can't do it here since we don't
1242 * know what is the role of the peer. It should be probably done in
1243 * p2ps_prov_complete callback, but currently operating channel isn't
1244 * passed to it.
1245 */
1246
1247#undef P2PS_PD_RESP_CHECK
1248
1249 return 0;
1250}
1251
1252
b22128ef
JM
1253void p2p_process_prov_disc_resp(struct p2p_data *p2p, const u8 *sa,
1254 const u8 *data, size_t len)
1255{
1256 struct p2p_message msg;
1257 struct p2p_device *dev;
66f1f751 1258 u16 report_config_methods = 0, req_config_methods;
9e96e464 1259 u8 status = P2P_SC_SUCCESS;
9e96e464
KV
1260 u32 adv_id = 0;
1261 u8 conncap = P2PS_SETUP_NEW;
1262 u8 adv_mac[ETH_ALEN];
2a098e36 1263 const u8 *group_mac;
9e96e464 1264 int passwd_id = DEV_PW_DEFAULT;
93f22b45 1265 int p2ps_seeker;
b22128ef
JM
1266
1267 if (p2p_parse(data, len, &msg))
1268 return;
1269
1f14e2bf
AO
1270 if (p2p->p2ps_prov && p2p_validate_p2ps_pd_resp(p2p, &msg)) {
1271 p2p_parse_free(&msg);
1272 return;
1273 }
1274
9e96e464
KV
1275 /* Parse the P2PS members present */
1276 if (msg.status)
1277 status = *msg.status;
1278
2a098e36 1279 group_mac = msg.intended_addr;
9e96e464
KV
1280
1281 if (msg.adv_mac)
1282 os_memcpy(adv_mac, msg.adv_mac, ETH_ALEN);
1283 else
1284 os_memset(adv_mac, 0, ETH_ALEN);
1285
1286 if (msg.adv_id)
1287 adv_id = WPA_GET_LE32(msg.adv_id);
1288
1289 if (msg.conn_cap) {
1290 conncap = *msg.conn_cap;
1291
1292 /* Switch bits to local relative */
1293 switch (conncap) {
1294 case P2PS_SETUP_GROUP_OWNER:
1295 conncap = P2PS_SETUP_CLIENT;
1296 break;
1297 case P2PS_SETUP_CLIENT:
1298 conncap = P2PS_SETUP_GROUP_OWNER;
1299 break;
1300 }
1301 }
1302
ed496f13 1303 p2p_dbg(p2p, "Received Provision Discovery Response from " MACSTR
b22128ef
JM
1304 " with config methods 0x%x",
1305 MAC2STR(sa), msg.wps_config_methods);
1306
1307 dev = p2p_get_device(p2p, sa);
1308 if (dev == NULL || !dev->req_config_methods) {
ed496f13
JM
1309 p2p_dbg(p2p, "Ignore Provision Discovery Response from " MACSTR
1310 " with no pending request", MAC2STR(sa));
b22128ef
JM
1311 p2p_parse_free(&msg);
1312 return;
1313 }
1314
1315 if (dev->dialog_token != msg.dialog_token) {
ed496f13 1316 p2p_dbg(p2p, "Ignore Provision Discovery Response with unexpected Dialog Token %u (expected %u)",
b22128ef
JM
1317 msg.dialog_token, dev->dialog_token);
1318 p2p_parse_free(&msg);
1319 return;
1320 }
1321
213c1fa8
JM
1322 if (p2p->pending_action_state == P2P_PENDING_PD) {
1323 os_memset(p2p->pending_pd_devaddr, 0, ETH_ALEN);
1324 p2p->pending_action_state = P2P_NO_PENDING_ACTION;
1325 }
1326
93f22b45
MS
1327 p2ps_seeker = p2p->p2ps_prov && p2p->p2ps_prov->pd_seeker;
1328
66f1f751
JM
1329 /*
1330 * Use a local copy of the requested config methods since
1331 * p2p_reset_pending_pd() can clear this in the peer entry.
1332 */
1333 req_config_methods = dev->req_config_methods;
1334
6b56cc2d
JS
1335 /*
1336 * If the response is from the peer to whom a user initiated request
1337 * was sent earlier, we reset that state info here.
1338 */
1339 if (p2p->user_initiated_pd &&
1340 os_memcmp(p2p->pending_pd_devaddr, sa, ETH_ALEN) == 0)
1341 p2p_reset_pending_pd(p2p);
1342
66f1f751 1343 if (msg.wps_config_methods != req_config_methods) {
ed496f13 1344 p2p_dbg(p2p, "Peer rejected our Provision Discovery Request (received config_methods 0x%x expected 0x%x",
66f1f751 1345 msg.wps_config_methods, req_config_methods);
349b213c
JS
1346 if (p2p->cfg->prov_disc_fail)
1347 p2p->cfg->prov_disc_fail(p2p->cfg->cb_ctx, sa,
ab8ee776 1348 P2P_PROV_DISC_REJECTED,
9e96e464 1349 adv_id, adv_mac, NULL);
b22128ef 1350 p2p_parse_free(&msg);
3f048aa8 1351 p2ps_prov_free(p2p);
b22128ef
JM
1352 goto out;
1353 }
1354
66f1f751 1355 report_config_methods = req_config_methods;
b22128ef 1356 dev->flags &= ~(P2P_DEV_PD_PEER_DISPLAY |
9e96e464
KV
1357 P2P_DEV_PD_PEER_KEYPAD |
1358 P2P_DEV_PD_PEER_P2PS);
66f1f751 1359 if (req_config_methods & WPS_CONFIG_DISPLAY) {
ed496f13 1360 p2p_dbg(p2p, "Peer " MACSTR
b22128ef
JM
1361 " accepted to show a PIN on display", MAC2STR(sa));
1362 dev->flags |= P2P_DEV_PD_PEER_DISPLAY;
9e96e464 1363 passwd_id = DEV_PW_REGISTRAR_SPECIFIED;
b22128ef 1364 } else if (msg.wps_config_methods & WPS_CONFIG_KEYPAD) {
ed496f13 1365 p2p_dbg(p2p, "Peer " MACSTR
b22128ef
JM
1366 " accepted to write our PIN using keypad",
1367 MAC2STR(sa));
1368 dev->flags |= P2P_DEV_PD_PEER_KEYPAD;
9e96e464
KV
1369 passwd_id = DEV_PW_USER_SPECIFIED;
1370 } else if (msg.wps_config_methods & WPS_CONFIG_P2PS) {
1371 p2p_dbg(p2p, "Peer " MACSTR " accepted P2PS PIN",
1372 MAC2STR(sa));
1373 dev->flags |= P2P_DEV_PD_PEER_P2PS;
1374 passwd_id = DEV_PW_P2PS_DEFAULT;
1375 }
1376
685b2098 1377 if ((status == P2P_SC_SUCCESS || status == P2P_SC_SUCCESS_DEFERRED) &&
9e96e464 1378 p2p->p2ps_prov) {
685b2098
IP
1379 dev->oper_freq = 0;
1380
1381 /*
1382 * Save the reported channel list and operating frequency.
1383 * Note that the specification mandates that the responder
1384 * should include in the channel list only channels reported by
1385 * the initiator, so this is only a sanity check, and if this
1386 * fails the flow would continue, although it would probably
1387 * fail. Same is true for the operating channel.
1388 */
1389 if (msg.channel_list && msg.channel_list_len &&
1390 p2p_peer_channels_check(p2p, &p2p->channels, dev,
1391 msg.channel_list,
1392 msg.channel_list_len) < 0)
1393 p2p_dbg(p2p, "P2PS PD Response - no common channels");
1394
1395 if (msg.operating_channel) {
1396 if (p2p_channels_includes(&p2p->channels,
1397 msg.operating_channel[3],
1398 msg.operating_channel[4]) &&
1399 p2p_channels_includes(&dev->channels,
1400 msg.operating_channel[3],
1401 msg.operating_channel[4])) {
1402 dev->oper_freq =
1403 p2p_channel_to_freq(
1404 msg.operating_channel[3],
1405 msg.operating_channel[4]);
1406 } else {
1407 p2p_dbg(p2p,
1408 "P2PS PD Response - invalid operating channel");
1409 }
1410 }
1411
9e96e464 1412 if (p2p->cfg->p2ps_prov_complete) {
8bb8e6ed
IP
1413 int freq = 0;
1414
685b2098
IP
1415 if (conncap == P2PS_SETUP_GROUP_OWNER) {
1416 u8 tmp;
1417
1418 /*
1419 * Re-select the operating channel as it is
1420 * possible that original channel is no longer
1421 * valid. This should not really fail.
1422 */
1423 if (p2p_go_select_channel(p2p, dev, &tmp) < 0)
1424 p2p_dbg(p2p,
1425 "P2PS PD channel selection failed");
8bb8e6ed
IP
1426
1427 freq = p2p_channel_to_freq(p2p->op_reg_class,
1428 p2p->op_channel);
1429 if (freq < 0)
1430 freq = 0;
685b2098
IP
1431 }
1432
9e96e464
KV
1433 p2p->cfg->p2ps_prov_complete(
1434 p2p->cfg->cb_ctx, status, sa, adv_mac,
1435 p2p->p2ps_prov->session_mac,
1436 group_mac, adv_id, p2p->p2ps_prov->session_id,
1437 conncap, passwd_id, msg.persistent_ssid,
88f3d7c9 1438 msg.persistent_ssid_len, 1, 0, NULL,
8bb8e6ed 1439 msg.feature_cap, msg.feature_cap_len, freq);
9e96e464 1440 }
3f048aa8 1441 p2ps_prov_free(p2p);
ea210b9f
MS
1442 } else if (status != P2P_SC_SUCCESS &&
1443 status != P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE &&
1444 status != P2P_SC_SUCCESS_DEFERRED && p2p->p2ps_prov) {
9e96e464
KV
1445 if (p2p->cfg->p2ps_prov_complete)
1446 p2p->cfg->p2ps_prov_complete(
1447 p2p->cfg->cb_ctx, status, sa, adv_mac,
1448 p2p->p2ps_prov->session_mac,
1449 group_mac, adv_id, p2p->p2ps_prov->session_id,
8bb8e6ed 1450 0, 0, NULL, 0, 1, 0, NULL, NULL, 0, 0);
3f048aa8 1451 p2ps_prov_free(p2p);
9e96e464
KV
1452 }
1453
1454 if (status == P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE) {
1455 if (p2p->cfg->remove_stale_groups) {
1456 p2p->cfg->remove_stale_groups(p2p->cfg->cb_ctx,
1457 dev->info.p2p_device_addr,
1458 NULL, NULL, 0);
1459 }
1460
1461 if (msg.session_info && msg.session_info_len) {
1462 size_t info_len = msg.session_info_len;
1463 char *deferred_sess_resp = os_malloc(2 * info_len + 1);
1464
1465 if (!deferred_sess_resp) {
1466 p2p_parse_free(&msg);
3f048aa8 1467 p2ps_prov_free(p2p);
9e96e464
KV
1468 goto out;
1469 }
1470 utf8_escape((char *) msg.session_info, info_len,
1471 deferred_sess_resp, 2 * info_len + 1);
1472
1473 if (p2p->cfg->prov_disc_fail)
1474 p2p->cfg->prov_disc_fail(
1475 p2p->cfg->cb_ctx, sa,
1476 P2P_PROV_DISC_INFO_UNAVAILABLE,
1477 adv_id, adv_mac,
1478 deferred_sess_resp);
1479 os_free(deferred_sess_resp);
1480 } else
1481 if (p2p->cfg->prov_disc_fail)
1482 p2p->cfg->prov_disc_fail(
1483 p2p->cfg->cb_ctx, sa,
1484 P2P_PROV_DISC_INFO_UNAVAILABLE,
1485 adv_id, adv_mac, NULL);
20f4c3d7 1486 } else if (status != P2P_SC_SUCCESS) {
9e96e464
KV
1487 p2p_dbg(p2p, "Peer rejected our Provision Discovery Request");
1488 if (p2p->cfg->prov_disc_fail)
1489 p2p->cfg->prov_disc_fail(p2p->cfg->cb_ctx, sa,
82d61135
MS
1490 P2P_PROV_DISC_REJECTED,
1491 adv_id, adv_mac, NULL);
9e96e464 1492 p2p_parse_free(&msg);
3f048aa8 1493 p2ps_prov_free(p2p);
9e96e464 1494 goto out;
b22128ef 1495 }
ec437d9e
JJ
1496
1497 /* Store the provisioning info */
1498 dev->wps_prov_info = msg.wps_config_methods;
b843a8b8
AO
1499 if (msg.intended_addr)
1500 os_memcpy(dev->interface_addr, msg.intended_addr, ETH_ALEN);
ec437d9e 1501
b22128ef
JM
1502 p2p_parse_free(&msg);
1503
1504out:
1505 dev->req_config_methods = 0;
1506 p2p->cfg->send_action_done(p2p->cfg->cb_ctx);
3bc462cb 1507 if (dev->flags & P2P_DEV_PD_BEFORE_GO_NEG) {
ed496f13
JM
1508 p2p_dbg(p2p, "Start GO Neg after the PD-before-GO-Neg workaround with "
1509 MACSTR, MAC2STR(dev->info.p2p_device_addr));
3bc462cb
JM
1510 dev->flags &= ~P2P_DEV_PD_BEFORE_GO_NEG;
1511 p2p_connect_send(p2p, dev);
1512 return;
1513 }
93f22b45
MS
1514
1515 /*
1516 * prov_disc_resp callback is used to generate P2P-PROV-DISC-ENTER-PIN,
1517 * P2P-PROV-DISC-SHOW-PIN, and P2P-PROV-DISC-PBC-REQ events.
1518 * Call it only for a legacy P2P PD or for P2PS PD scenarios where
1519 * show/enter PIN events are needed.
1520 *
1521 * The callback is called in the following cases:
1522 * 1. Legacy P2P PD response with a status SUCCESS
1523 * 2. P2PS, advertiser method: DISPLAY, autoaccept: true,
1524 * response status: SUCCESS, local method KEYPAD
1525 * 3. P2PS, advertiser method: KEYPAD,Seeker side,
1526 * response status: INFO_CURRENTLY_UNAVAILABLE,
1527 * local method: DISPLAY
1528 */
1529 if (p2p->cfg->prov_disc_resp &&
1530 ((status == P2P_SC_SUCCESS && !adv_id) ||
1531 (p2ps_seeker && status == P2P_SC_SUCCESS &&
1532 passwd_id == DEV_PW_REGISTRAR_SPECIFIED) ||
1533 (p2ps_seeker &&
1534 status == P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE &&
1535 passwd_id == DEV_PW_USER_SPECIFIED)))
b22128ef
JM
1536 p2p->cfg->prov_disc_resp(p2p->cfg->cb_ctx, sa,
1537 report_config_methods);
52728dcd
JM
1538
1539 if (p2p->state == P2P_PD_DURING_FIND) {
1540 p2p_clear_timeout(p2p);
1541 p2p_continue_find(p2p);
1542 }
b22128ef
JM
1543}
1544
1545
1546int p2p_send_prov_disc_req(struct p2p_data *p2p, struct p2p_device *dev,
1ef2f7ff 1547 int join, int force_freq)
b22128ef
JM
1548{
1549 struct wpabuf *req;
1550 int freq;
1551
1ef2f7ff
JM
1552 if (force_freq > 0)
1553 freq = force_freq;
1554 else
1555 freq = dev->listen_freq > 0 ? dev->listen_freq :
1556 dev->oper_freq;
b22128ef 1557 if (freq <= 0) {
ed496f13
JM
1558 p2p_dbg(p2p, "No Listen/Operating frequency known for the peer "
1559 MACSTR " to send Provision Discovery Request",
c5db8e51 1560 MAC2STR(dev->info.p2p_device_addr));
b22128ef
JM
1561 return -1;
1562 }
1563
1564 if (dev->flags & P2P_DEV_GROUP_CLIENT_ONLY) {
c5db8e51
KRK
1565 if (!(dev->info.dev_capab &
1566 P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY)) {
ed496f13 1567 p2p_dbg(p2p, "Cannot use PD with P2P Device " MACSTR
b22128ef 1568 " that is in a group and is not discoverable",
c5db8e51 1569 MAC2STR(dev->info.p2p_device_addr));
b22128ef
JM
1570 return -1;
1571 }
1572 /* TODO: use device discoverability request through GO */
1573 }
1574
369678ad
KV
1575 if (p2p->p2ps_prov) {
1576 if (p2p->p2ps_prov->status == P2P_SC_SUCCESS_DEFERRED) {
1577 if (p2p->p2ps_prov->method == WPS_CONFIG_DISPLAY)
1578 dev->req_config_methods = WPS_CONFIG_KEYPAD;
1579 else if (p2p->p2ps_prov->method == WPS_CONFIG_KEYPAD)
1580 dev->req_config_methods = WPS_CONFIG_DISPLAY;
1581 else
1582 dev->req_config_methods = WPS_CONFIG_P2PS;
1583 } else {
1584 /* Order of preference, based on peer's capabilities */
1585 if (p2p->p2ps_prov->method)
1586 dev->req_config_methods =
1587 p2p->p2ps_prov->method;
1588 else if (dev->info.config_methods & WPS_CONFIG_P2PS)
1589 dev->req_config_methods = WPS_CONFIG_P2PS;
1590 else if (dev->info.config_methods & WPS_CONFIG_DISPLAY)
1591 dev->req_config_methods = WPS_CONFIG_DISPLAY;
1592 else
1593 dev->req_config_methods = WPS_CONFIG_KEYPAD;
1594 }
1595 p2p_dbg(p2p,
1596 "Building PD Request based on P2PS config method 0x%x status %d --> req_config_methods 0x%x",
1597 p2p->p2ps_prov->method, p2p->p2ps_prov->status,
1598 dev->req_config_methods);
ebd32943
IP
1599
1600 if (p2p_prepare_channel(p2p, dev, p2p->p2ps_prov->force_freq,
1601 p2p->p2ps_prov->pref_freq, 1) < 0)
1602 return -1;
369678ad
KV
1603 }
1604
1605 req = p2p_build_prov_disc_req(p2p, dev, join);
b22128ef
JM
1606 if (req == NULL)
1607 return -1;
1608
1a9c618d
JM
1609 if (p2p->state != P2P_IDLE)
1610 p2p_stop_listen_for_freq(p2p, freq);
b22128ef 1611 p2p->pending_action_state = P2P_PENDING_PD;
c5db8e51
KRK
1612 if (p2p_send_action(p2p, freq, dev->info.p2p_device_addr,
1613 p2p->cfg->dev_addr, dev->info.p2p_device_addr,
3f9285ff 1614 wpabuf_head(req), wpabuf_len(req), 200) < 0) {
ed496f13 1615 p2p_dbg(p2p, "Failed to send Action frame");
b22128ef
JM
1616 wpabuf_free(req);
1617 return -1;
1618 }
1619
6b56cc2d
JS
1620 os_memcpy(p2p->pending_pd_devaddr, dev->info.p2p_device_addr, ETH_ALEN);
1621
b22128ef
JM
1622 wpabuf_free(req);
1623 return 0;
1624}
1625
1626
1627int p2p_prov_disc_req(struct p2p_data *p2p, const u8 *peer_addr,
369678ad 1628 struct p2ps_provision *p2ps_prov,
67527166
SD
1629 u16 config_methods, int join, int force_freq,
1630 int user_initiated_pd)
b22128ef
JM
1631{
1632 struct p2p_device *dev;
1633
1634 dev = p2p_get_device(p2p, peer_addr);
1635 if (dev == NULL)
1636 dev = p2p_get_device_interface(p2p, peer_addr);
1637 if (dev == NULL || (dev->flags & P2P_DEV_PROBE_REQ_ONLY)) {
ed496f13 1638 p2p_dbg(p2p, "Provision Discovery Request destination " MACSTR
b22128ef 1639 " not yet known", MAC2STR(peer_addr));
369678ad 1640 os_free(p2ps_prov);
b22128ef
JM
1641 return -1;
1642 }
1643
ed496f13
JM
1644 p2p_dbg(p2p, "Provision Discovery Request with " MACSTR
1645 " (config methods 0x%x)",
b22128ef 1646 MAC2STR(peer_addr), config_methods);
369678ad
KV
1647 if (config_methods == 0 && !p2ps_prov) {
1648 os_free(p2ps_prov);
b22128ef 1649 return -1;
369678ad
KV
1650 }
1651
1652 if (p2ps_prov && p2ps_prov->status == P2P_SC_SUCCESS_DEFERRED &&
1653 p2p->p2ps_prov) {
1654 /* Use cached method from deferred provisioning */
1655 p2ps_prov->method = p2p->p2ps_prov->method;
1656 }
b22128ef 1657
ec437d9e
JJ
1658 /* Reset provisioning info */
1659 dev->wps_prov_info = 0;
3f048aa8 1660 p2ps_prov_free(p2p);
369678ad 1661 p2p->p2ps_prov = p2ps_prov;
ec437d9e 1662
b22128ef 1663 dev->req_config_methods = config_methods;
10c4edde
JM
1664 if (join)
1665 dev->flags |= P2P_DEV_PD_FOR_JOIN;
1666 else
1667 dev->flags &= ~P2P_DEV_PD_FOR_JOIN;
b22128ef 1668
e12b85d3
JB
1669 if (p2p->state != P2P_IDLE && p2p->state != P2P_SEARCH &&
1670 p2p->state != P2P_LISTEN_ONLY) {
ed496f13
JM
1671 p2p_dbg(p2p, "Busy with other operations; postpone Provision Discovery Request with "
1672 MACSTR " (config methods 0x%x)",
b22128ef
JM
1673 MAC2STR(peer_addr), config_methods);
1674 return 0;
1675 }
1676
67527166 1677 p2p->user_initiated_pd = user_initiated_pd;
8d82c210 1678 p2p->pd_force_freq = force_freq;
6b56cc2d 1679
488f4a71 1680 if (p2p->user_initiated_pd)
6b56cc2d
JS
1681 p2p->pd_retries = MAX_PROV_DISC_REQ_RETRIES;
1682
c0810ddb
SD
1683 /*
1684 * Assign dialog token here to use the same value in each retry within
1685 * the same PD exchange.
1686 */
1687 dev->dialog_token++;
1688 if (dev->dialog_token == 0)
1689 dev->dialog_token = 1;
1690
1ef2f7ff 1691 return p2p_send_prov_disc_req(p2p, dev, join, force_freq);
b22128ef 1692}
6b56cc2d
JS
1693
1694
1695void p2p_reset_pending_pd(struct p2p_data *p2p)
1696{
5aff6fc6
JMB
1697 struct p2p_device *dev;
1698
1699 dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) {
1700 if (os_memcmp(p2p->pending_pd_devaddr,
1701 dev->info.p2p_device_addr, ETH_ALEN))
1702 continue;
1703 if (!dev->req_config_methods)
1704 continue;
1705 if (dev->flags & P2P_DEV_PD_FOR_JOIN)
1706 continue;
1707 /* Reset the config methods of the device */
1708 dev->req_config_methods = 0;
1709 }
1710
6b56cc2d
JS
1711 p2p->user_initiated_pd = 0;
1712 os_memset(p2p->pending_pd_devaddr, 0, ETH_ALEN);
1713 p2p->pd_retries = 0;
8d82c210 1714 p2p->pd_force_freq = 0;
6b56cc2d 1715}
3f048aa8
MS
1716
1717
1718void p2ps_prov_free(struct p2p_data *p2p)
1719{
1720 os_free(p2p->p2ps_prov);
1721 p2p->p2ps_prov = NULL;
1722}