]> git.ipfire.org Git - thirdparty/hostap.git/blob - src/p2p/p2p_pd.c
P2PS: Add feature capability to PD events
[thirdparty/hostap.git] / src / p2p / p2p_pd.c
1 /*
2 * Wi-Fi Direct - P2P provision discovery
3 * Copyright (c) 2009-2010, Atheros Communications
4 *
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
7 */
8
9 #include "includes.h"
10
11 #include "common.h"
12 #include "common/ieee802_11_defs.h"
13 #include "common/wpa_ctrl.h"
14 #include "wps/wps_defs.h"
15 #include "p2p_i.h"
16 #include "p2p.h"
17
18
19 /*
20 * Number of retries to attempt for provision discovery requests
21 * in case the peer is not listening.
22 */
23 #define MAX_PROV_DISC_REQ_RETRIES 120
24
25
26 static void p2p_build_wps_ie_config_methods(struct wpabuf *buf,
27 u16 config_methods)
28 {
29 u8 *len;
30 wpabuf_put_u8(buf, WLAN_EID_VENDOR_SPECIFIC);
31 len = wpabuf_put(buf, 1);
32 wpabuf_put_be32(buf, WPS_DEV_OUI_WFA);
33
34 /* Config Methods */
35 wpabuf_put_be16(buf, ATTR_CONFIG_METHODS);
36 wpabuf_put_be16(buf, 2);
37 wpabuf_put_be16(buf, config_methods);
38
39 p2p_buf_update_ie_hdr(buf, len);
40 }
41
42
43 static void p2ps_add_new_group_info(struct p2p_data *p2p, struct wpabuf *buf)
44 {
45 int found;
46 u8 intended_addr[ETH_ALEN];
47 u8 ssid[SSID_MAX_LEN];
48 size_t ssid_len;
49 int group_iface;
50
51 if (!p2p->cfg->get_go_info)
52 return;
53
54 found = p2p->cfg->get_go_info(
55 p2p->cfg->cb_ctx, intended_addr, ssid,
56 &ssid_len, &group_iface);
57 if (found) {
58 p2p_buf_add_group_id(buf, p2p->cfg->dev_addr,
59 ssid, ssid_len);
60
61 if (group_iface)
62 p2p_buf_add_intended_addr(buf, p2p->intended_addr);
63 else
64 p2p_buf_add_intended_addr(buf, intended_addr);
65 } else {
66 if (!p2p->ssid_set) {
67 p2p_build_ssid(p2p, p2p->ssid, &p2p->ssid_len);
68 p2p->ssid_set = 1;
69 }
70
71 /* Add pre-composed P2P Group ID */
72 p2p_buf_add_group_id(buf, p2p->cfg->dev_addr,
73 p2p->ssid, p2p->ssid_len);
74
75 if (group_iface)
76 p2p_buf_add_intended_addr(
77 buf, p2p->intended_addr);
78 else
79 p2p_buf_add_intended_addr(
80 buf, p2p->cfg->dev_addr);
81 }
82 }
83
84
85 static void p2ps_add_pd_req_attrs(struct p2p_data *p2p, struct p2p_device *dev,
86 struct wpabuf *buf, u16 config_methods)
87 {
88 struct p2ps_provision *prov = p2p->p2ps_prov;
89 struct p2ps_feature_capab fcap = { prov->cpt_mask, 0 };
90 int shared_group = 0;
91 u8 ssid[SSID_MAX_LEN];
92 size_t ssid_len;
93 u8 go_dev_addr[ETH_ALEN];
94 u8 intended_addr[ETH_ALEN];
95
96 /* If we might be explicite group owner, add GO details */
97 if (prov->conncap & (P2PS_SETUP_GROUP_OWNER |
98 P2PS_SETUP_NEW))
99 p2ps_add_new_group_info(p2p, buf);
100
101 if (prov->status >= 0)
102 p2p_buf_add_status(buf, (u8) prov->status);
103 else
104 prov->method = config_methods;
105
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);
110 }
111
112 /* Add Operating Channel if conncap includes GO */
113 if (shared_group ||
114 (prov->conncap & (P2PS_SETUP_GROUP_OWNER |
115 P2PS_SETUP_NEW))) {
116 u8 tmp;
117
118 p2p_go_select_channel(p2p, dev, &tmp);
119
120 if (p2p->op_reg_class && p2p->op_channel)
121 p2p_buf_add_operating_channel(buf, p2p->cfg->country,
122 p2p->op_reg_class,
123 p2p->op_channel);
124 else
125 p2p_buf_add_operating_channel(buf, p2p->cfg->country,
126 p2p->cfg->op_reg_class,
127 p2p->cfg->op_channel);
128 }
129
130 p2p_buf_add_channel_list(buf, p2p->cfg->country, &p2p->cfg->channels);
131
132 if (prov->info[0])
133 p2p_buf_add_session_info(buf, prov->info);
134
135 p2p_buf_add_connection_capability(buf, prov->conncap);
136
137 p2p_buf_add_advertisement_id(buf, prov->adv_id, prov->adv_mac);
138
139 if (shared_group || prov->conncap == P2PS_SETUP_NEW ||
140 prov->conncap ==
141 (P2PS_SETUP_GROUP_OWNER | P2PS_SETUP_NEW) ||
142 prov->conncap ==
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);
147 }
148
149 p2p_buf_add_listen_channel(buf, p2p->cfg->country, p2p->cfg->reg_class,
150 p2p->cfg->channel);
151
152 p2p_buf_add_session_id(buf, prov->session_id, prov->session_mac);
153
154 p2p_buf_add_feature_capability(buf, sizeof(fcap), (const u8 *) &fcap);
155
156 if (shared_group) {
157 p2p_buf_add_persistent_group_info(buf, go_dev_addr,
158 ssid, ssid_len);
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);
164 }
165 }
166
167
168 static struct wpabuf * p2p_build_prov_disc_req(struct p2p_data *p2p,
169 struct p2p_device *dev,
170 int join)
171 {
172 struct wpabuf *buf;
173 u8 *len;
174 size_t extra = 0;
175 u8 dialog_token = dev->dialog_token;
176 u16 config_methods = dev->req_config_methods;
177 struct p2p_device *go = join ? dev : NULL;
178 u8 group_capab;
179
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 */
184
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]);
187
188 if (p2p->p2ps_prov)
189 extra += os_strlen(p2p->p2ps_prov->info) + 1 +
190 sizeof(struct p2ps_provision);
191
192 buf = wpabuf_alloc(1000 + extra);
193 if (buf == NULL)
194 return NULL;
195
196 p2p_buf_add_public_action_hdr(buf, P2P_PROV_DISC_REQ, dialog_token);
197
198 len = p2p_buf_add_ie_hdr(buf);
199
200 group_capab = 0;
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;
208 }
209 p2p_buf_add_capability(buf, p2p->dev_capab &
210 ~P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY,
211 group_capab);
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);
215 } else if (go) {
216 p2p_buf_add_group_id(buf, go->info.p2p_device_addr,
217 go->oper_ssid, go->oper_ssid_len);
218 }
219 p2p_buf_update_ie_hdr(buf, len);
220
221 /* WPS IE with Config Methods attribute */
222 p2p_build_wps_ie_config_methods(buf, config_methods);
223
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 */
228
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]);
231
232 return buf;
233 }
234
235
236 static struct wpabuf * p2p_build_prov_disc_resp(struct p2p_data *p2p,
237 struct p2p_device *dev,
238 u8 dialog_token,
239 enum p2p_status_code status,
240 u16 config_methods,
241 u32 adv_id,
242 const u8 *group_id,
243 size_t group_id_len,
244 const u8 *persist_ssid,
245 size_t persist_ssid_len,
246 const u8 *fcap,
247 u16 fcap_len)
248 {
249 struct wpabuf *buf;
250 size_t extra = 0;
251 int persist = 0;
252
253 #ifdef CONFIG_WIFI_DISPLAY
254 struct wpabuf *wfd_ie = p2p->wfd_ie_prov_disc_resp;
255 if (wfd_ie && group_id) {
256 size_t i;
257 for (i = 0; i < p2p->num_groups; i++) {
258 struct p2p_group *g = p2p->groups[i];
259 struct wpabuf *ie;
260 if (!p2p_group_is_group_id_match(g, group_id,
261 group_id_len))
262 continue;
263 ie = p2p_group_get_wfd_ie(g);
264 if (ie) {
265 wfd_ie = ie;
266 break;
267 }
268 }
269 }
270 if (wfd_ie)
271 extra = wpabuf_len(wfd_ie);
272 #endif /* CONFIG_WIFI_DISPLAY */
273
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]);
276
277 buf = wpabuf_alloc(1000 + extra);
278 if (buf == NULL)
279 return NULL;
280
281 p2p_buf_add_public_action_hdr(buf, P2P_PROV_DISC_RESP, dialog_token);
282
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;
287 u8 group_capab;
288
289 if (!status && prov->status != -1)
290 status = prov->status;
291
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,
301 group_capab);
302 p2p_buf_add_device_info(buf, p2p, NULL);
303
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];
308 size_t ssid_len;
309 u8 go_dev_addr[ETH_ALEN];
310 u8 intended_addr[ETH_ALEN];
311
312 persist = p2p->cfg->get_persistent_group(
313 p2p->cfg->cb_ctx,
314 dev->info.p2p_device_addr,
315 persist_ssid, persist_ssid_len, go_dev_addr,
316 ssid, &ssid_len, intended_addr);
317 if (persist) {
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(
322 buf, intended_addr);
323 }
324 }
325
326 if (!persist && (prov->conncap & P2PS_SETUP_GROUP_OWNER))
327 p2ps_add_new_group_info(p2p, buf);
328
329 /* Add Operating Channel if conncap indicates GO */
330 if (persist || (prov->conncap & P2PS_SETUP_GROUP_OWNER)) {
331 u8 tmp;
332
333 if (dev)
334 p2p_go_select_channel(p2p, dev, &tmp);
335
336 if (p2p->op_reg_class && p2p->op_channel)
337 p2p_buf_add_operating_channel(
338 buf, p2p->cfg->country,
339 p2p->op_reg_class,
340 p2p->op_channel);
341 else
342 p2p_buf_add_operating_channel(
343 buf, p2p->cfg->country,
344 p2p->cfg->op_reg_class,
345 p2p->cfg->op_channel);
346 }
347
348 p2p_buf_add_channel_list(buf, p2p->cfg->country,
349 &p2p->cfg->channels);
350
351 if (!persist && (status == P2P_SC_SUCCESS ||
352 status == P2P_SC_SUCCESS_DEFERRED))
353 p2p_buf_add_connection_capability(buf, prov->conncap);
354
355 p2p_buf_add_advertisement_id(buf, adv_id, prov->adv_mac);
356
357 p2p_buf_add_config_timeout(buf, p2p->go_timeout,
358 p2p->client_timeout);
359
360 p2p_buf_add_session_id(buf, prov->session_id,
361 prov->session_mac);
362
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);
367
368 p2p_buf_add_status(buf, status);
369
370 if (p2p->p2ps_prov)
371 p2p_buf_add_advertisement_id(buf, adv_id,
372 p2p->p2ps_prov->adv_mac);
373
374 p2p_buf_update_ie_hdr(buf, len);
375 }
376
377 /* WPS IE with Config Methods attribute */
378 p2p_build_wps_ie_config_methods(buf, config_methods);
379
380 #ifdef CONFIG_WIFI_DISPLAY
381 if (wfd_ie)
382 wpabuf_put_buf(buf, wfd_ie);
383 #endif /* CONFIG_WIFI_DISPLAY */
384
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]);
387
388 return buf;
389 }
390
391
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)
395 {
396 struct p2ps_provision *tmp;
397
398 if (!p2p->p2ps_prov) {
399 p2p->p2ps_prov = os_zalloc(sizeof(struct p2ps_provision) + 1);
400 if (!p2p->p2ps_prov)
401 return -1;
402 } else {
403 os_memset(p2p->p2ps_prov, 0, sizeof(struct p2ps_provision) + 1);
404 }
405
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);
412 tmp->info[0] = '\0';
413
414 return 0;
415 }
416
417
418 static u8 p2ps_own_preferred_cpt(const u8 *cpt_priority, u8 req_cpt_mask)
419 {
420 int i;
421
422 for (i = 0; cpt_priority[i]; i++)
423 if (req_cpt_mask & cpt_priority[i])
424 return cpt_priority[i];
425
426 return 0;
427 }
428
429
430 void p2p_process_prov_disc_req(struct p2p_data *p2p, const u8 *sa,
431 const u8 *data, size_t len, int rx_freq)
432 {
433 struct p2p_message msg;
434 struct p2p_device *dev;
435 int freq;
436 enum p2p_status_code reject = P2P_SC_FAIL_INCOMPATIBLE_PARAMS;
437 struct wpabuf *resp;
438 u32 adv_id = 0;
439 struct p2ps_advertisement *p2ps_adv = NULL;
440 u8 conncap = P2PS_SETUP_NEW;
441 u8 auto_accept = 0;
442 u32 session_id = 0;
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;
447 u16 config_methods;
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;
451
452 if (p2p_parse(data, len, &msg))
453 return;
454
455 p2p_dbg(p2p, "Received Provision Discovery Request from " MACSTR
456 " with config methods 0x%x (freq=%d)",
457 MAC2STR(sa), msg.wps_config_methods, rx_freq);
458
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));
463
464 if (p2p_add_device(p2p, sa, rx_freq, NULL, 0, data + 1, len - 1,
465 0)) {
466 p2p_dbg(p2p, "Provision Discovery Request add device failed "
467 MACSTR, MAC2STR(sa));
468 }
469 } else if (msg.wfd_subelems) {
470 wpabuf_free(dev->info.wfd_subelems);
471 dev->info.wfd_subelems = wpabuf_dup(msg.wfd_subelems);
472 }
473
474 if (msg.adv_id)
475 allowed_config_methods |= WPS_CONFIG_P2PS;
476 else
477 allowed_config_methods |= WPS_CONFIG_PUSHBUTTON;
478
479 if (!(msg.wps_config_methods & allowed_config_methods)) {
480 p2p_dbg(p2p, "Unsupported Config Methods in Provision Discovery Request");
481 goto out;
482 }
483
484 /* Legacy (non-P2PS) - Unknown groups allowed for P2PS */
485 if (!msg.adv_id && msg.group_id) {
486 size_t i;
487 for (i = 0; i < p2p->num_groups; i++) {
488 if (p2p_group_is_group_id_match(p2p->groups[i],
489 msg.group_id,
490 msg.group_id_len))
491 break;
492 }
493 if (i == p2p->num_groups) {
494 p2p_dbg(p2p, "PD request for unknown P2P Group ID - reject");
495 goto out;
496 }
497 }
498
499 if (dev) {
500 dev->flags &= ~(P2P_DEV_PD_PEER_DISPLAY |
501 P2P_DEV_PD_PEER_KEYPAD |
502 P2P_DEV_PD_PEER_P2PS);
503
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,
508 msg.persistent_dev,
509 msg.persistent_ssid, msg.persistent_ssid_len);
510 }
511 }
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));
515 if (dev)
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",
521 MAC2STR(sa));
522 if (dev)
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",
527 MAC2STR(sa));
528 if (dev)
529 dev->flags |= P2P_DEV_PD_PEER_P2PS;
530 passwd_id = DEV_PW_P2PS_DEFAULT;
531 }
532
533 reject = P2P_SC_SUCCESS;
534
535 os_memset(session_mac, 0, ETH_ALEN);
536 os_memset(adv_mac, 0, ETH_ALEN);
537 os_memset(group_mac, 0, ETH_ALEN);
538
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
543 * structure.
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.
548 */
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)) {
552 u8 remote_conncap;
553
554 req_fcap = (struct p2ps_feature_capab *) msg.feature_cap;
555
556 if (msg.intended_addr)
557 os_memcpy(group_mac, msg.intended_addr, ETH_ALEN);
558
559 os_memcpy(session_mac, msg.session_mac, ETH_ALEN);
560 os_memcpy(adv_mac, msg.adv_mac, ETH_ALEN);
561
562 session_id = WPA_GET_LE32(msg.session_id);
563 adv_id = WPA_GET_LE32(msg.adv_id);
564
565 if (!msg.status)
566 p2ps_adv = p2p_service_p2ps_id(p2p, adv_id);
567
568 p2p_dbg(p2p, "adv_id: %x - p2ps_adv - %p", adv_id, p2ps_adv);
569
570 if (msg.conn_cap)
571 conncap = *msg.conn_cap;
572 remote_conncap = conncap;
573
574 if (p2ps_adv) {
575 auto_accept = p2ps_adv->auto_accept;
576 conncap = p2p->cfg->p2ps_group_capability(
577 p2p->cfg->cb_ctx, conncap, auto_accept);
578
579 p2p_dbg(p2p, "Conncap: local:%d remote:%d result:%d",
580 auto_accept, remote_conncap, conncap);
581
582 resp_fcap.cpt =
583 p2ps_own_preferred_cpt(p2ps_adv->cpt_priority,
584 req_fcap->cpt);
585
586 p2p_dbg(p2p,
587 "cpt: service:0x%x remote:0x%x result:0x%x",
588 p2ps_adv->cpt_mask, req_fcap->cpt,
589 resp_fcap.cpt);
590
591 if (!resp_fcap.cpt) {
592 p2p_dbg(p2p,
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)) {
598 p2p_dbg(p2p,
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;
609 }
610
611 if (msg.wps_config_methods & WPS_CONFIG_KEYPAD) {
612 p2p_dbg(p2p, "Keypad - always defer");
613 auto_accept = 0;
614 }
615
616 if (auto_accept || reject != P2P_SC_SUCCESS) {
617 struct p2ps_provision *tmp;
618
619 if (reject == P2P_SC_SUCCESS && !conncap) {
620 reject =
621 P2P_SC_FAIL_INCOMPATIBLE_PARAMS;
622 }
623
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;
629 goto out;
630 }
631
632 tmp = p2p->p2ps_prov;
633 if (conncap) {
634 tmp->conncap = conncap;
635 tmp->status = P2P_SC_SUCCESS;
636 } else {
637 tmp->conncap = auto_accept;
638 tmp->status = P2P_SC_FAIL_INCOMPATIBLE_PARAMS;
639 }
640
641 if (reject != P2P_SC_SUCCESS)
642 goto out;
643 }
644 } else if (!msg.status) {
645 reject = P2P_SC_FAIL_INCOMPATIBLE_PARAMS;
646 goto out;
647 }
648
649 if (!msg.status && !auto_accept &&
650 (!p2p->p2ps_prov || p2p->p2ps_prov->adv_id != adv_id)) {
651 struct p2ps_provision *tmp;
652
653 if (!conncap) {
654 reject = P2P_SC_FAIL_INCOMPATIBLE_PARAMS;
655 goto out;
656 }
657
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;
662 goto out;
663 }
664 tmp = p2p->p2ps_prov;
665 reject = P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE;
666 tmp->status = reject;
667 }
668
669 if (msg.status) {
670 if (*msg.status &&
671 *msg.status != P2P_SC_SUCCESS_DEFERRED) {
672 reject = *msg.status;
673 } else if (*msg.status == P2P_SC_SUCCESS_DEFERRED &&
674 p2p->p2ps_prov) {
675 u16 method = p2p->p2ps_prov->method;
676
677 conncap = p2p->cfg->p2ps_group_capability(
678 p2p->cfg->cb_ctx, remote_conncap,
679 p2p->p2ps_prov->conncap);
680
681 p2p_dbg(p2p,
682 "Conncap: local:%d remote:%d result:%d",
683 p2p->p2ps_prov->conncap,
684 remote_conncap, conncap);
685
686 resp_fcap.cpt = p2ps_own_preferred_cpt(
687 p2p->p2ps_prov->cpt_priority,
688 req_fcap->cpt);
689
690 p2p_dbg(p2p,
691 "cpt: local:0x%x remote:0x%x result:0x%x",
692 p2p->p2ps_prov->cpt_mask,
693 req_fcap->cpt, resp_fcap.cpt);
694
695 /*
696 * Ensure that if we asked for PIN originally,
697 * our method is consistent with original
698 * request.
699 */
700 if (method & WPS_CONFIG_DISPLAY)
701 method = WPS_CONFIG_KEYPAD;
702 else if (method & WPS_CONFIG_KEYPAD)
703 method = WPS_CONFIG_DISPLAY;
704
705 if (!conncap ||
706 !(msg.wps_config_methods & method)) {
707 /*
708 * Reject this "Deferred Accept*
709 * if incompatible conncap or method
710 */
711 reject =
712 P2P_SC_FAIL_INCOMPATIBLE_PARAMS;
713 } else if (!resp_fcap.cpt) {
714 p2p_dbg(p2p,
715 "Incompatible P2PS feature capability CPT bitmask");
716 reject =
717 P2P_SC_FAIL_INCOMPATIBLE_PARAMS;
718 } else {
719 reject = P2P_SC_SUCCESS;
720 }
721
722 p2p->p2ps_prov->status = reject;
723 p2p->p2ps_prov->conncap = conncap;
724 }
725 }
726 }
727
728 out:
729 if (reject == P2P_SC_SUCCESS ||
730 reject == P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE)
731 config_methods = msg.wps_config_methods;
732 else
733 config_methods = 0;
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,
737 msg.persistent_ssid,
738 msg.persistent_ssid_len,
739 (const u8 *) &resp_fcap,
740 sizeof(resp_fcap));
741 if (resp == NULL) {
742 p2p_parse_free(&msg);
743 return;
744 }
745 p2p_dbg(p2p, "Sending Provision Discovery Response");
746 if (rx_freq > 0)
747 freq = rx_freq;
748 else
749 freq = p2p_channel_to_freq(p2p->cfg->reg_class,
750 p2p->cfg->channel);
751 if (freq < 0) {
752 p2p_dbg(p2p, "Unknown regulatory class/channel");
753 wpabuf_free(resp);
754 p2p_parse_free(&msg);
755 return;
756 }
757 p2p->pending_action_state = P2P_PENDING_PD_RESPONSE;
758 if (p2p_send_action(p2p, freq, sa, p2p->cfg->dev_addr,
759 p2p->cfg->dev_addr,
760 wpabuf_head(resp), wpabuf_len(resp), 200) < 0) {
761 p2p_dbg(p2p, "Failed to send Action frame");
762 } else
763 p2p->send_action_in_progress = 1;
764
765 wpabuf_free(resp);
766
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 &&
779 p2p->p2ps_prov) {
780 p2p->p2ps_prov->status = reject;
781 p2p->p2ps_prov->conncap = conncap;
782
783 if (reject != P2P_SC_SUCCESS)
784 p2p->cfg->p2ps_prov_complete(p2p->cfg->cb_ctx, reject,
785 sa, adv_mac, session_mac,
786 NULL, adv_id,
787 session_id, conncap, 0,
788 msg.persistent_ssid,
789 msg.persistent_ssid_len, 0,
790 0, NULL, NULL, 0);
791 else
792 p2p->cfg->p2ps_prov_complete(p2p->cfg->cb_ctx,
793 *msg.status,
794 sa, adv_mac, session_mac,
795 group_mac, adv_id,
796 session_id, conncap,
797 passwd_id,
798 msg.persistent_ssid,
799 msg.persistent_ssid_len, 0,
800 0, NULL,
801 (const u8 *) &resp_fcap,
802 sizeof(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,
808 passwd_id,
809 msg.persistent_ssid,
810 msg.persistent_ssid_len,
811 0, 0, NULL,
812 (const u8 *) &resp_fcap,
813 sizeof(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,
819 conncap, passwd_id,
820 msg.persistent_ssid,
821 msg.persistent_ssid_len,
822 0, 0, NULL,
823 (const u8 *) &resp_fcap,
824 sizeof(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;
828
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,
832 conncap, passwd_id,
833 msg.persistent_ssid,
834 msg.persistent_ssid_len,
835 0, 1, NULL,
836 (const u8 *) &resp_fcap,
837 sizeof(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);
841
842 if (buf) {
843 p2p->p2ps_prov->method = msg.wps_config_methods;
844
845 utf8_escape((char *) msg.session_info, buf_len,
846 buf, 2 * buf_len + 1);
847
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,
853 0, 1, buf,
854 (const u8 *) &resp_fcap, sizeof(resp_fcap));
855
856 os_free(buf);
857 }
858 }
859
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] :
870 0,
871 msg.group_id, msg.group_id_len);
872
873 if (dev) {
874 switch (config_methods) {
875 case WPS_CONFIG_DISPLAY:
876 dev->wps_prov_info = WPS_CONFIG_KEYPAD;
877 break;
878 case WPS_CONFIG_KEYPAD:
879 dev->wps_prov_info = WPS_CONFIG_DISPLAY;
880 break;
881 case WPS_CONFIG_PUSHBUTTON:
882 dev->wps_prov_info = WPS_CONFIG_PUSHBUTTON;
883 break;
884 case WPS_CONFIG_P2PS:
885 dev->wps_prov_info = WPS_CONFIG_P2PS;
886 break;
887 default:
888 dev->wps_prov_info = 0;
889 break;
890 }
891
892 if (msg.intended_addr)
893 os_memcpy(dev->interface_addr,
894 msg.intended_addr, ETH_ALEN);
895 }
896 }
897 p2p_parse_free(&msg);
898 }
899
900
901 static int p2p_validate_p2ps_pd_resp(struct p2p_data *p2p,
902 struct p2p_message *msg)
903 {
904 u8 conn_cap_go = 0;
905 u8 conn_cap_cli = 0;
906 u32 session_id;
907 u32 adv_id;
908
909 #define P2PS_PD_RESP_CHECK(_val, _attr) \
910 do { \
911 if ((_val) && !msg->_attr) { \
912 p2p_dbg(p2p, "P2PS PD Response missing " #_attr); \
913 return -1; \
914 } \
915 } while (0)
916
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);
925
926 session_id = WPA_GET_LE32(msg->session_id);
927 adv_id = WPA_GET_LE32(msg->adv_id);
928
929 if (p2p->p2ps_prov->session_id != session_id) {
930 p2p_dbg(p2p,
931 "Ignore PD Response with unexpected Session ID");
932 return -1;
933 }
934
935 if (os_memcmp(p2p->p2ps_prov->session_mac, msg->session_mac,
936 ETH_ALEN)) {
937 p2p_dbg(p2p,
938 "Ignore PD Response with unexpected Session MAC");
939 return -1;
940 }
941
942 if (p2p->p2ps_prov->adv_id != adv_id) {
943 p2p_dbg(p2p,
944 "Ignore PD Response with unexpected Advertisement ID");
945 return -1;
946 }
947
948 if (os_memcmp(p2p->p2ps_prov->adv_mac, msg->adv_mac, ETH_ALEN) != 0) {
949 p2p_dbg(p2p,
950 "Ignore PD Response with unexpected Advertisement MAC");
951 return -1;
952 }
953
954 if (msg->listen_channel) {
955 p2p_dbg(p2p,
956 "Ignore malformed PD Response - unexpected Listen Channel");
957 return -1;
958 }
959
960 if (*msg->status == P2P_SC_SUCCESS &&
961 !(!!msg->conn_cap ^ !!msg->persistent_dev)) {
962 p2p_dbg(p2p,
963 "Ignore malformed PD Response - either conn_cap or persistent group should be present");
964 return -1;
965 }
966
967 if (msg->persistent_dev && *msg->status != P2P_SC_SUCCESS) {
968 p2p_dbg(p2p,
969 "Ignore malformed PD Response - persistent group is present, but the status isn't success");
970 return -1;
971 }
972
973 if (msg->conn_cap) {
974 conn_cap_go = *msg->conn_cap == P2PS_SETUP_GROUP_OWNER;
975 conn_cap_cli = *msg->conn_cap == P2PS_SETUP_CLIENT;
976 }
977
978 P2PS_PD_RESP_CHECK(msg->persistent_dev || conn_cap_go || conn_cap_cli,
979 channel_list);
980 P2PS_PD_RESP_CHECK(msg->persistent_dev || conn_cap_go || conn_cap_cli,
981 config_timeout);
982
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);
986 /*
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
991 * passed to it.
992 */
993
994 #undef P2PS_PD_RESP_CHECK
995
996 return 0;
997 }
998
999
1000 void p2p_process_prov_disc_resp(struct p2p_data *p2p, const u8 *sa,
1001 const u8 *data, size_t len)
1002 {
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;
1007 int success = 0;
1008 u32 adv_id = 0;
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;
1013
1014 if (p2p_parse(data, len, &msg))
1015 return;
1016
1017 if (p2p->p2ps_prov && p2p_validate_p2ps_pd_resp(p2p, &msg)) {
1018 p2p_parse_free(&msg);
1019 return;
1020 }
1021
1022 /* Parse the P2PS members present */
1023 if (msg.status)
1024 status = *msg.status;
1025
1026 if (msg.intended_addr)
1027 os_memcpy(group_mac, msg.intended_addr, ETH_ALEN);
1028 else
1029 os_memset(group_mac, 0, ETH_ALEN);
1030
1031 if (msg.adv_mac)
1032 os_memcpy(adv_mac, msg.adv_mac, ETH_ALEN);
1033 else
1034 os_memset(adv_mac, 0, ETH_ALEN);
1035
1036 if (msg.adv_id)
1037 adv_id = WPA_GET_LE32(msg.adv_id);
1038
1039 if (msg.conn_cap) {
1040 conncap = *msg.conn_cap;
1041
1042 /* Switch bits to local relative */
1043 switch (conncap) {
1044 case P2PS_SETUP_GROUP_OWNER:
1045 conncap = P2PS_SETUP_CLIENT;
1046 break;
1047 case P2PS_SETUP_CLIENT:
1048 conncap = P2PS_SETUP_GROUP_OWNER;
1049 break;
1050 }
1051 }
1052
1053 p2p_dbg(p2p, "Received Provision Discovery Response from " MACSTR
1054 " with config methods 0x%x",
1055 MAC2STR(sa), msg.wps_config_methods);
1056
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);
1062 return;
1063 }
1064
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);
1069 return;
1070 }
1071
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;
1075 }
1076
1077 /*
1078 * Use a local copy of the requested config methods since
1079 * p2p_reset_pending_pd() can clear this in the peer entry.
1080 */
1081 req_config_methods = dev->req_config_methods;
1082
1083 /*
1084 * If the response is from the peer to whom a user initiated request
1085 * was sent earlier, we reset that state info here.
1086 */
1087 if (p2p->user_initiated_pd &&
1088 os_memcmp(p2p->pending_pd_devaddr, sa, ETH_ALEN) == 0)
1089 p2p_reset_pending_pd(p2p);
1090
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);
1100 goto out;
1101 }
1102
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",
1115 MAC2STR(sa));
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",
1120 MAC2STR(sa));
1121 dev->flags |= P2P_DEV_PD_PEER_P2PS;
1122 passwd_id = DEV_PW_P2PS_DEFAULT;
1123 }
1124
1125 if ((msg.conn_cap || msg.persistent_dev) &&
1126 (status == P2P_SC_SUCCESS || status == P2P_SC_SUCCESS_DEFERRED) &&
1127 p2p->p2ps_prov) {
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);
1136 }
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);
1148 }
1149
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,
1154 NULL, NULL, 0);
1155 }
1156
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);
1160
1161 if (!deferred_sess_resp) {
1162 p2p_parse_free(&msg);
1163 p2ps_prov_free(p2p);
1164 goto out;
1165 }
1166 utf8_escape((char *) msg.session_info, info_len,
1167 deferred_sess_resp, 2 * info_len + 1);
1168
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,
1173 adv_id, adv_mac,
1174 deferred_sess_resp);
1175 os_free(deferred_sess_resp);
1176 } else
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);
1190 goto out;
1191 }
1192
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);
1197
1198 p2p_parse_free(&msg);
1199 success = 1;
1200
1201 out:
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);
1209 return;
1210 }
1211 if (success && p2p->cfg->prov_disc_resp)
1212 p2p->cfg->prov_disc_resp(p2p->cfg->cb_ctx, sa,
1213 report_config_methods);
1214
1215 if (p2p->state == P2P_PD_DURING_FIND) {
1216 p2p_clear_timeout(p2p);
1217 p2p_continue_find(p2p);
1218 }
1219 }
1220
1221
1222 int p2p_send_prov_disc_req(struct p2p_data *p2p, struct p2p_device *dev,
1223 int join, int force_freq)
1224 {
1225 struct wpabuf *req;
1226 int freq;
1227
1228 if (force_freq > 0)
1229 freq = force_freq;
1230 else
1231 freq = dev->listen_freq > 0 ? dev->listen_freq :
1232 dev->oper_freq;
1233 if (freq <= 0) {
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));
1237 return -1;
1238 }
1239
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));
1246 return -1;
1247 }
1248 /* TODO: use device discoverability request through GO */
1249 }
1250
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;
1257 else
1258 dev->req_config_methods = WPS_CONFIG_P2PS;
1259 } else {
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;
1268 else
1269 dev->req_config_methods = WPS_CONFIG_KEYPAD;
1270 }
1271 p2p_dbg(p2p,
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);
1275 }
1276
1277 req = p2p_build_prov_disc_req(p2p, dev, join);
1278 if (req == NULL)
1279 return -1;
1280
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");
1288 wpabuf_free(req);
1289 return -1;
1290 }
1291
1292 os_memcpy(p2p->pending_pd_devaddr, dev->info.p2p_device_addr, ETH_ALEN);
1293
1294 wpabuf_free(req);
1295 return 0;
1296 }
1297
1298
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)
1303 {
1304 struct p2p_device *dev;
1305
1306 dev = p2p_get_device(p2p, peer_addr);
1307 if (dev == NULL)
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));
1312 os_free(p2ps_prov);
1313 return -1;
1314 }
1315
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) {
1320 os_free(p2ps_prov);
1321 return -1;
1322 }
1323
1324 if (p2ps_prov && p2ps_prov->status == P2P_SC_SUCCESS_DEFERRED &&
1325 p2p->p2ps_prov) {
1326 /* Use cached method from deferred provisioning */
1327 p2ps_prov->method = p2p->p2ps_prov->method;
1328 }
1329
1330 /* Reset provisioning info */
1331 dev->wps_prov_info = 0;
1332 p2ps_prov_free(p2p);
1333 p2p->p2ps_prov = p2ps_prov;
1334
1335 dev->req_config_methods = config_methods;
1336 if (join)
1337 dev->flags |= P2P_DEV_PD_FOR_JOIN;
1338 else
1339 dev->flags &= ~P2P_DEV_PD_FOR_JOIN;
1340
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);
1346 return 0;
1347 }
1348
1349 p2p->user_initiated_pd = user_initiated_pd;
1350 p2p->pd_force_freq = force_freq;
1351
1352 if (p2p->user_initiated_pd)
1353 p2p->pd_retries = MAX_PROV_DISC_REQ_RETRIES;
1354
1355 /*
1356 * Assign dialog token here to use the same value in each retry within
1357 * the same PD exchange.
1358 */
1359 dev->dialog_token++;
1360 if (dev->dialog_token == 0)
1361 dev->dialog_token = 1;
1362
1363 return p2p_send_prov_disc_req(p2p, dev, join, force_freq);
1364 }
1365
1366
1367 void p2p_reset_pending_pd(struct p2p_data *p2p)
1368 {
1369 struct p2p_device *dev;
1370
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))
1374 continue;
1375 if (!dev->req_config_methods)
1376 continue;
1377 if (dev->flags & P2P_DEV_PD_FOR_JOIN)
1378 continue;
1379 /* Reset the config methods of the device */
1380 dev->req_config_methods = 0;
1381 }
1382
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;
1387 }
1388
1389
1390 void p2ps_prov_free(struct p2p_data *p2p)
1391 {
1392 os_free(p2p->p2ps_prov);
1393 p2p->p2ps_prov = NULL;
1394 }