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