]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/wpa/src/p2p/p2p_pd.c
Bring LLVM libunwind snapshot into contrib/llvm/projects
[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, struct wpabuf *buf)
44 {
45         int found;
46         u8 intended_addr[ETH_ALEN];
47         u8 ssid[32];
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                 p2p_buf_add_intended_addr(buf, intended_addr);
61         } else {
62                 if (!p2p->ssid_set) {
63                         p2p_build_ssid(p2p, p2p->ssid, &p2p->ssid_len);
64                         p2p->ssid_set = 1;
65                 }
66
67                 /* Add pre-composed P2P Group ID */
68                 p2p_buf_add_group_id(buf, p2p->cfg->dev_addr,
69                                      p2p->ssid, p2p->ssid_len);
70
71                 if (group_iface)
72                         p2p_buf_add_intended_addr(
73                                 buf, p2p->intended_addr);
74                 else
75                         p2p_buf_add_intended_addr(
76                                 buf, p2p->cfg->dev_addr);
77         }
78 }
79
80
81 static void p2ps_add_pd_req_attrs(struct p2p_data *p2p, struct p2p_device *dev,
82                                   struct wpabuf *buf, u16 config_methods)
83 {
84         struct p2ps_provision *prov = p2p->p2ps_prov;
85         u8 feat_cap_mask[] = { 1, 0 };
86         int shared_group = 0;
87         u8 ssid[32];
88         size_t ssid_len;
89         u8 go_dev_addr[ETH_ALEN];
90
91         /* If we might be explicite group owner, add GO details */
92         if (prov->conncap & (P2PS_SETUP_GROUP_OWNER |
93                              P2PS_SETUP_NEW))
94                 p2ps_add_new_group_info(p2p, buf);
95
96         if (prov->status >= 0)
97                 p2p_buf_add_status(buf, (u8) prov->status);
98         else
99                 prov->method = config_methods;
100
101         if (p2p->cfg->get_persistent_group) {
102                 shared_group = p2p->cfg->get_persistent_group(
103                         p2p->cfg->cb_ctx, dev->info.p2p_device_addr, NULL, 0,
104                         go_dev_addr, ssid, &ssid_len);
105         }
106
107         /* Add Operating Channel if conncap includes GO */
108         if (shared_group ||
109             (prov->conncap & (P2PS_SETUP_GROUP_OWNER |
110                               P2PS_SETUP_NEW))) {
111                 u8 tmp;
112
113                 p2p_go_select_channel(p2p, dev, &tmp);
114
115                 if (p2p->op_reg_class && p2p->op_channel)
116                         p2p_buf_add_operating_channel(buf, p2p->cfg->country,
117                                                       p2p->op_reg_class,
118                                                       p2p->op_channel);
119                 else
120                         p2p_buf_add_operating_channel(buf, p2p->cfg->country,
121                                                       p2p->cfg->op_reg_class,
122                                                       p2p->cfg->op_channel);
123         }
124
125         p2p_buf_add_channel_list(buf, p2p->cfg->country, &p2p->cfg->channels);
126
127         if (prov->info[0])
128                 p2p_buf_add_session_info(buf, prov->info);
129
130         p2p_buf_add_connection_capability(buf, prov->conncap);
131
132         p2p_buf_add_advertisement_id(buf, prov->adv_id, prov->adv_mac);
133
134         if (shared_group || prov->conncap == P2PS_SETUP_NEW ||
135             prov->conncap ==
136             (P2PS_SETUP_GROUP_OWNER | P2PS_SETUP_NEW) ||
137             prov->conncap ==
138             (P2PS_SETUP_GROUP_OWNER | P2PS_SETUP_CLIENT)) {
139                 /* Add Config Timeout */
140                 p2p_buf_add_config_timeout(buf, p2p->go_timeout,
141                                            p2p->client_timeout);
142         }
143
144         p2p_buf_add_listen_channel(buf, p2p->cfg->country, p2p->cfg->reg_class,
145                                    p2p->cfg->channel);
146
147         p2p_buf_add_session_id(buf, prov->session_id, prov->session_mac);
148
149         p2p_buf_add_feature_capability(buf, sizeof(feat_cap_mask),
150                                        feat_cap_mask);
151
152         if (shared_group)
153                 p2p_buf_add_persistent_group_info(buf, go_dev_addr,
154                                                   ssid, ssid_len);
155 }
156
157
158 static struct wpabuf * p2p_build_prov_disc_req(struct p2p_data *p2p,
159                                                struct p2p_device *dev,
160                                                int join)
161 {
162         struct wpabuf *buf;
163         u8 *len;
164         size_t extra = 0;
165         u8 dialog_token = dev->dialog_token;
166         u16 config_methods = dev->req_config_methods;
167         struct p2p_device *go = join ? dev : NULL;
168         u8 group_capab;
169
170 #ifdef CONFIG_WIFI_DISPLAY
171         if (p2p->wfd_ie_prov_disc_req)
172                 extra = wpabuf_len(p2p->wfd_ie_prov_disc_req);
173 #endif /* CONFIG_WIFI_DISPLAY */
174
175         if (p2p->vendor_elem && p2p->vendor_elem[VENDOR_ELEM_P2P_PD_REQ])
176                 extra += wpabuf_len(p2p->vendor_elem[VENDOR_ELEM_P2P_PD_REQ]);
177
178         if (p2p->p2ps_prov)
179                 extra += os_strlen(p2p->p2ps_prov->info) + 1 +
180                         sizeof(struct p2ps_provision);
181
182         buf = wpabuf_alloc(1000 + extra);
183         if (buf == NULL)
184                 return NULL;
185
186         p2p_buf_add_public_action_hdr(buf, P2P_PROV_DISC_REQ, dialog_token);
187
188         len = p2p_buf_add_ie_hdr(buf);
189
190         group_capab = 0;
191         if (p2p->p2ps_prov) {
192                 group_capab |= P2P_GROUP_CAPAB_PERSISTENT_GROUP;
193                 group_capab |= P2P_GROUP_CAPAB_PERSISTENT_RECONN;
194                 if (p2p->cross_connect)
195                         group_capab |= P2P_GROUP_CAPAB_CROSS_CONN;
196                 if (p2p->cfg->p2p_intra_bss)
197                         group_capab |= P2P_GROUP_CAPAB_INTRA_BSS_DIST;
198         }
199         p2p_buf_add_capability(buf, p2p->dev_capab &
200                                ~P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY,
201                                group_capab);
202         p2p_buf_add_device_info(buf, p2p, NULL);
203         if (p2p->p2ps_prov) {
204                 p2ps_add_pd_req_attrs(p2p, dev, buf, config_methods);
205         } else if (go) {
206                 p2p_buf_add_group_id(buf, go->info.p2p_device_addr,
207                                      go->oper_ssid, go->oper_ssid_len);
208         }
209         p2p_buf_update_ie_hdr(buf, len);
210
211         /* WPS IE with Config Methods attribute */
212         p2p_build_wps_ie_config_methods(buf, config_methods);
213
214 #ifdef CONFIG_WIFI_DISPLAY
215         if (p2p->wfd_ie_prov_disc_req)
216                 wpabuf_put_buf(buf, p2p->wfd_ie_prov_disc_req);
217 #endif /* CONFIG_WIFI_DISPLAY */
218
219         if (p2p->vendor_elem && p2p->vendor_elem[VENDOR_ELEM_P2P_PD_REQ])
220                 wpabuf_put_buf(buf, p2p->vendor_elem[VENDOR_ELEM_P2P_PD_REQ]);
221
222         return buf;
223 }
224
225
226 static struct wpabuf * p2p_build_prov_disc_resp(struct p2p_data *p2p,
227                                                 struct p2p_device *dev,
228                                                 u8 dialog_token,
229                                                 enum p2p_status_code status,
230                                                 u16 config_methods,
231                                                 u32 adv_id,
232                                                 const u8 *group_id,
233                                                 size_t group_id_len,
234                                                 const u8 *persist_ssid,
235                                                 size_t persist_ssid_len)
236 {
237         struct wpabuf *buf;
238         size_t extra = 0;
239         int persist = 0;
240
241 #ifdef CONFIG_WIFI_DISPLAY
242         struct wpabuf *wfd_ie = p2p->wfd_ie_prov_disc_resp;
243         if (wfd_ie && group_id) {
244                 size_t i;
245                 for (i = 0; i < p2p->num_groups; i++) {
246                         struct p2p_group *g = p2p->groups[i];
247                         struct wpabuf *ie;
248                         if (!p2p_group_is_group_id_match(g, group_id,
249                                                          group_id_len))
250                                 continue;
251                         ie = p2p_group_get_wfd_ie(g);
252                         if (ie) {
253                                 wfd_ie = ie;
254                                 break;
255                         }
256                 }
257         }
258         if (wfd_ie)
259                 extra = wpabuf_len(wfd_ie);
260 #endif /* CONFIG_WIFI_DISPLAY */
261
262         if (p2p->vendor_elem && p2p->vendor_elem[VENDOR_ELEM_P2P_PD_RESP])
263                 extra += wpabuf_len(p2p->vendor_elem[VENDOR_ELEM_P2P_PD_RESP]);
264
265         buf = wpabuf_alloc(1000 + extra);
266         if (buf == NULL)
267                 return NULL;
268
269         p2p_buf_add_public_action_hdr(buf, P2P_PROV_DISC_RESP, dialog_token);
270
271         /* Add P2P IE for P2PS */
272         if (p2p->p2ps_prov && p2p->p2ps_prov->adv_id == adv_id) {
273                 u8 feat_cap_mask[] = { 1, 0 };
274                 u8 *len = p2p_buf_add_ie_hdr(buf);
275                 struct p2ps_provision *prov = p2p->p2ps_prov;
276                 u8 group_capab;
277
278                 if (!status && prov->status != -1)
279                         status = prov->status;
280
281                 p2p_buf_add_status(buf, status);
282                 group_capab = P2P_GROUP_CAPAB_PERSISTENT_GROUP |
283                         P2P_GROUP_CAPAB_PERSISTENT_RECONN;
284                 if (p2p->cross_connect)
285                         group_capab |= P2P_GROUP_CAPAB_CROSS_CONN;
286                 if (p2p->cfg->p2p_intra_bss)
287                         group_capab |= P2P_GROUP_CAPAB_INTRA_BSS_DIST;
288                 p2p_buf_add_capability(buf, p2p->dev_capab &
289                                        ~P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY,
290                                        group_capab);
291                 p2p_buf_add_device_info(buf, p2p, NULL);
292
293                 if (persist_ssid && p2p->cfg->get_persistent_group &&
294                     (status == P2P_SC_SUCCESS ||
295                      status == P2P_SC_SUCCESS_DEFERRED)) {
296                         u8 ssid[32];
297                         size_t ssid_len;
298                         u8 go_dev_addr[ETH_ALEN];
299
300                         persist = p2p->cfg->get_persistent_group(
301                                 p2p->cfg->cb_ctx,
302                                 dev->info.p2p_device_addr,
303                                 persist_ssid, persist_ssid_len, go_dev_addr,
304                                 ssid, &ssid_len);
305                         if (persist)
306                                 p2p_buf_add_persistent_group_info(
307                                         buf, go_dev_addr, ssid, ssid_len);
308                 }
309
310                 if (!persist && (prov->conncap & P2PS_SETUP_GROUP_OWNER))
311                         p2ps_add_new_group_info(p2p, buf);
312
313                 /* Add Operating Channel if conncap indicates GO */
314                 if (persist || (prov->conncap & P2PS_SETUP_GROUP_OWNER)) {
315                         u8 tmp;
316
317                         if (dev)
318                                 p2p_go_select_channel(p2p, dev, &tmp);
319
320                         if (p2p->op_reg_class && p2p->op_channel)
321                                 p2p_buf_add_operating_channel(
322                                         buf, p2p->cfg->country,
323                                         p2p->op_reg_class,
324                                         p2p->op_channel);
325                         else
326                                 p2p_buf_add_operating_channel(
327                                         buf, p2p->cfg->country,
328                                         p2p->cfg->op_reg_class,
329                                         p2p->cfg->op_channel);
330                 }
331
332                 p2p_buf_add_channel_list(buf, p2p->cfg->country,
333                                          &p2p->cfg->channels);
334
335                 if (!persist && (status == P2P_SC_SUCCESS ||
336                                  status == P2P_SC_SUCCESS_DEFERRED))
337                         p2p_buf_add_connection_capability(buf, prov->conncap);
338
339                 p2p_buf_add_advertisement_id(buf, adv_id, prov->adv_mac);
340
341                 p2p_buf_add_config_timeout(buf, p2p->go_timeout,
342                                            p2p->client_timeout);
343
344                 p2p_buf_add_session_id(buf, prov->session_id,
345                                        prov->session_mac);
346
347                 p2p_buf_add_feature_capability(buf, sizeof(feat_cap_mask),
348                                                feat_cap_mask);
349                 p2p_buf_update_ie_hdr(buf, len);
350         } else if (status != P2P_SC_SUCCESS || adv_id) {
351                 u8 *len = p2p_buf_add_ie_hdr(buf);
352
353                 p2p_buf_add_status(buf, status);
354
355                 if (p2p->p2ps_prov)
356                         p2p_buf_add_advertisement_id(buf, adv_id,
357                                                      p2p->p2ps_prov->adv_mac);
358
359                 p2p_buf_update_ie_hdr(buf, len);
360         }
361
362         /* WPS IE with Config Methods attribute */
363         p2p_build_wps_ie_config_methods(buf, config_methods);
364
365 #ifdef CONFIG_WIFI_DISPLAY
366         if (wfd_ie)
367                 wpabuf_put_buf(buf, wfd_ie);
368 #endif /* CONFIG_WIFI_DISPLAY */
369
370         if (p2p->vendor_elem && p2p->vendor_elem[VENDOR_ELEM_P2P_PD_RESP])
371                 wpabuf_put_buf(buf, p2p->vendor_elem[VENDOR_ELEM_P2P_PD_RESP]);
372
373         return buf;
374 }
375
376
377 static int p2ps_setup_p2ps_prov(struct p2p_data *p2p, u32 adv_id,
378                                 u32 session_id, u16 method,
379                                 const u8 *session_mac, const u8 *adv_mac)
380 {
381         struct p2ps_provision *tmp;
382
383         if (!p2p->p2ps_prov) {
384                 p2p->p2ps_prov = os_zalloc(sizeof(struct p2ps_provision) + 1);
385                 if (!p2p->p2ps_prov)
386                         return -1;
387         } else {
388                 os_memset(p2p->p2ps_prov, 0, sizeof(struct p2ps_provision) + 1);
389         }
390
391         tmp = p2p->p2ps_prov;
392         tmp->adv_id = adv_id;
393         tmp->session_id = session_id;
394         tmp->method = method;
395         os_memcpy(tmp->session_mac, session_mac, ETH_ALEN);
396         os_memcpy(tmp->adv_mac, adv_mac, ETH_ALEN);
397         tmp->info[0] = '\0';
398
399         return 0;
400 }
401
402
403 void p2p_process_prov_disc_req(struct p2p_data *p2p, const u8 *sa,
404                                const u8 *data, size_t len, int rx_freq)
405 {
406         struct p2p_message msg;
407         struct p2p_device *dev;
408         int freq;
409         enum p2p_status_code reject = P2P_SC_FAIL_INCOMPATIBLE_PARAMS;
410         struct wpabuf *resp;
411         u32 adv_id = 0;
412         struct p2ps_advertisement *p2ps_adv = NULL;
413         u8 conncap = P2PS_SETUP_NEW;
414         u8 auto_accept = 0;
415         u32 session_id = 0;
416         u8 session_mac[ETH_ALEN];
417         u8 adv_mac[ETH_ALEN];
418         u8 group_mac[ETH_ALEN];
419         int passwd_id = DEV_PW_DEFAULT;
420         u16 config_methods;
421
422         if (p2p_parse(data, len, &msg))
423                 return;
424
425         p2p_dbg(p2p, "Received Provision Discovery Request from " MACSTR
426                 " with config methods 0x%x (freq=%d)",
427                 MAC2STR(sa), msg.wps_config_methods, rx_freq);
428
429         dev = p2p_get_device(p2p, sa);
430         if (dev == NULL || (dev->flags & P2P_DEV_PROBE_REQ_ONLY)) {
431                 p2p_dbg(p2p, "Provision Discovery Request from unknown peer "
432                         MACSTR, MAC2STR(sa));
433
434                 if (p2p_add_device(p2p, sa, rx_freq, NULL, 0, data + 1, len - 1,
435                                    0)) {
436                         p2p_dbg(p2p, "Provision Discovery Request add device failed "
437                                 MACSTR, MAC2STR(sa));
438                 }
439         } else if (msg.wfd_subelems) {
440                 wpabuf_free(dev->info.wfd_subelems);
441                 dev->info.wfd_subelems = wpabuf_dup(msg.wfd_subelems);
442         }
443
444         if (!(msg.wps_config_methods &
445               (WPS_CONFIG_DISPLAY | WPS_CONFIG_KEYPAD |
446                WPS_CONFIG_PUSHBUTTON | WPS_CONFIG_P2PS))) {
447                 p2p_dbg(p2p, "Unsupported Config Methods in Provision Discovery Request");
448                 goto out;
449         }
450
451         /* Legacy (non-P2PS) - Unknown groups allowed for P2PS */
452         if (!msg.adv_id && msg.group_id) {
453                 size_t i;
454                 for (i = 0; i < p2p->num_groups; i++) {
455                         if (p2p_group_is_group_id_match(p2p->groups[i],
456                                                         msg.group_id,
457                                                         msg.group_id_len))
458                                 break;
459                 }
460                 if (i == p2p->num_groups) {
461                         p2p_dbg(p2p, "PD request for unknown P2P Group ID - reject");
462                         goto out;
463                 }
464         }
465
466         if (dev) {
467                 dev->flags &= ~(P2P_DEV_PD_PEER_DISPLAY |
468                                 P2P_DEV_PD_PEER_KEYPAD |
469                                 P2P_DEV_PD_PEER_P2PS);
470
471                 /* Remove stale persistent groups */
472                 if (p2p->cfg->remove_stale_groups) {
473                         p2p->cfg->remove_stale_groups(
474                                 p2p->cfg->cb_ctx, dev->info.p2p_device_addr,
475                                 msg.persistent_dev,
476                                 msg.persistent_ssid, msg.persistent_ssid_len);
477                 }
478         }
479         if (msg.wps_config_methods & WPS_CONFIG_DISPLAY) {
480                 p2p_dbg(p2p, "Peer " MACSTR
481                         " requested us to show a PIN on display", MAC2STR(sa));
482                 if (dev)
483                         dev->flags |= P2P_DEV_PD_PEER_KEYPAD;
484                 passwd_id = DEV_PW_USER_SPECIFIED;
485         } else if (msg.wps_config_methods & WPS_CONFIG_KEYPAD) {
486                 p2p_dbg(p2p, "Peer " MACSTR
487                         " requested us to write its PIN using keypad",
488                         MAC2STR(sa));
489                 if (dev)
490                         dev->flags |= P2P_DEV_PD_PEER_DISPLAY;
491                 passwd_id = DEV_PW_REGISTRAR_SPECIFIED;
492         } else if (msg.wps_config_methods & WPS_CONFIG_P2PS) {
493                 p2p_dbg(p2p, "Peer " MACSTR " requesting P2PS PIN",
494                         MAC2STR(sa));
495                 if (dev)
496                         dev->flags |= P2P_DEV_PD_PEER_P2PS;
497                 passwd_id = DEV_PW_P2PS_DEFAULT;
498         }
499
500         reject = P2P_SC_SUCCESS;
501
502         os_memset(session_mac, 0, ETH_ALEN);
503         os_memset(adv_mac, 0, ETH_ALEN);
504         os_memset(group_mac, 0, ETH_ALEN);
505
506         if (msg.adv_id && msg.session_id && msg.session_mac && msg.adv_mac &&
507             (msg.status || msg.conn_cap)) {
508                 u8 remote_conncap;
509
510                 if (msg.intended_addr)
511                         os_memcpy(group_mac, msg.intended_addr, ETH_ALEN);
512
513                 os_memcpy(session_mac, msg.session_mac, ETH_ALEN);
514                 os_memcpy(adv_mac, msg.adv_mac, ETH_ALEN);
515
516                 session_id = WPA_GET_LE32(msg.session_id);
517                 adv_id = WPA_GET_LE32(msg.adv_id);
518
519                 if (!msg.status)
520                         p2ps_adv = p2p_service_p2ps_id(p2p, adv_id);
521
522                 p2p_dbg(p2p, "adv_id: %x - p2ps_adv - %p", adv_id, p2ps_adv);
523
524                 if (msg.conn_cap)
525                         conncap = *msg.conn_cap;
526                 remote_conncap = conncap;
527
528                 if (p2ps_adv) {
529                         auto_accept = p2ps_adv->auto_accept;
530                         conncap = p2p->cfg->p2ps_group_capability(
531                                 p2p->cfg->cb_ctx, conncap, auto_accept);
532
533                         p2p_dbg(p2p, "Conncap: local:%d remote:%d result:%d",
534                                 auto_accept, remote_conncap, conncap);
535
536                         if (p2ps_adv->config_methods &&
537                             !(msg.wps_config_methods &
538                               p2ps_adv->config_methods)) {
539                                 p2p_dbg(p2p,
540                                         "Unsupported config methods in Provision Discovery Request (own=0x%x peer=0x%x)",
541                                         p2ps_adv->config_methods,
542                                         msg.wps_config_methods);
543                                 reject = P2P_SC_FAIL_INCOMPATIBLE_PARAMS;
544                         } else if (!p2ps_adv->state) {
545                                 p2p_dbg(p2p, "P2PS state unavailable");
546                                 reject = P2P_SC_FAIL_UNABLE_TO_ACCOMMODATE;
547                         } else if (!conncap) {
548                                 p2p_dbg(p2p, "Conncap resolution failed");
549                                 reject = P2P_SC_FAIL_INCOMPATIBLE_PARAMS;
550                         }
551
552                         if (msg.wps_config_methods & WPS_CONFIG_KEYPAD) {
553                                 p2p_dbg(p2p, "Keypad - always defer");
554                                 auto_accept = 0;
555                         }
556
557                         if (auto_accept || reject != P2P_SC_SUCCESS) {
558                                 struct p2ps_provision *tmp;
559
560                                 if (reject == P2P_SC_SUCCESS && !conncap) {
561                                         reject =
562                                                 P2P_SC_FAIL_INCOMPATIBLE_PARAMS;
563                                 }
564
565                                 if (p2ps_setup_p2ps_prov(
566                                             p2p, adv_id, session_id,
567                                             msg.wps_config_methods,
568                                             session_mac, adv_mac) < 0) {
569                                         reject = P2P_SC_FAIL_UNABLE_TO_ACCOMMODATE;
570                                         goto out;
571                                 }
572
573                                 tmp = p2p->p2ps_prov;
574                                 if (conncap) {
575                                         tmp->conncap = conncap;
576                                         tmp->status = P2P_SC_SUCCESS;
577                                 } else {
578                                         tmp->conncap = auto_accept;
579                                         tmp->status = P2P_SC_FAIL_INCOMPATIBLE_PARAMS;
580                                 }
581
582                                 if (reject != P2P_SC_SUCCESS)
583                                         goto out;
584                         }
585                 } else if (!msg.status) {
586                         reject = P2P_SC_FAIL_INCOMPATIBLE_PARAMS;
587                         goto out;
588                 }
589
590                 if (!msg.status && !auto_accept &&
591                     (!p2p->p2ps_prov || p2p->p2ps_prov->adv_id != adv_id)) {
592                         struct p2ps_provision *tmp;
593
594                         if (!conncap) {
595                                 reject = P2P_SC_FAIL_INCOMPATIBLE_PARAMS;
596                                 goto out;
597                         }
598
599                         if (p2ps_setup_p2ps_prov(p2p, adv_id, session_id,
600                                                  msg.wps_config_methods,
601                                                  session_mac, adv_mac) < 0) {
602                                 reject = P2P_SC_FAIL_UNABLE_TO_ACCOMMODATE;
603                                 goto out;
604                         }
605                         tmp = p2p->p2ps_prov;
606                         reject = P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE;
607                         tmp->status = reject;
608                 }
609
610                 if (msg.status) {
611                         if (*msg.status &&
612                             *msg.status != P2P_SC_SUCCESS_DEFERRED) {
613                                 reject = *msg.status;
614                         } else if (*msg.status == P2P_SC_SUCCESS_DEFERRED &&
615                                    p2p->p2ps_prov) {
616                                 u16 method = p2p->p2ps_prov->method;
617
618                                 conncap = p2p->cfg->p2ps_group_capability(
619                                         p2p->cfg->cb_ctx, remote_conncap,
620                                         p2p->p2ps_prov->conncap);
621
622                                 p2p_dbg(p2p,
623                                         "Conncap: local:%d remote:%d result:%d",
624                                         p2p->p2ps_prov->conncap,
625                                         remote_conncap, conncap);
626
627                                 /*
628                                  * Ensure that if we asked for PIN originally,
629                                  * our method is consistent with original
630                                  * request.
631                                  */
632                                 if (method & WPS_CONFIG_DISPLAY)
633                                         method = WPS_CONFIG_KEYPAD;
634                                 else if (method & WPS_CONFIG_KEYPAD)
635                                         method = WPS_CONFIG_DISPLAY;
636
637                                 /* Reject this "Deferred Accept* if incompatible
638                                  * conncap or method */
639                                 if (!conncap ||
640                                     !(msg.wps_config_methods & method))
641                                         reject =
642                                                 P2P_SC_FAIL_INCOMPATIBLE_PARAMS;
643                                 else
644                                         reject = P2P_SC_SUCCESS;
645
646                                 p2p->p2ps_prov->status = reject;
647                                 p2p->p2ps_prov->conncap = conncap;
648                         }
649                 }
650         }
651
652 out:
653         if (reject == P2P_SC_SUCCESS ||
654             reject == P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE)
655                 config_methods = msg.wps_config_methods;
656         else
657                 config_methods = 0;
658         resp = p2p_build_prov_disc_resp(p2p, dev, msg.dialog_token, reject,
659                                         config_methods, adv_id,
660                                         msg.group_id, msg.group_id_len,
661                                         msg.persistent_ssid,
662                                         msg.persistent_ssid_len);
663         if (resp == NULL) {
664                 p2p_parse_free(&msg);
665                 return;
666         }
667         p2p_dbg(p2p, "Sending Provision Discovery Response");
668         if (rx_freq > 0)
669                 freq = rx_freq;
670         else
671                 freq = p2p_channel_to_freq(p2p->cfg->reg_class,
672                                            p2p->cfg->channel);
673         if (freq < 0) {
674                 p2p_dbg(p2p, "Unknown regulatory class/channel");
675                 wpabuf_free(resp);
676                 p2p_parse_free(&msg);
677                 return;
678         }
679         p2p->pending_action_state = P2P_PENDING_PD_RESPONSE;
680         if (p2p_send_action(p2p, freq, sa, p2p->cfg->dev_addr,
681                             p2p->cfg->dev_addr,
682                             wpabuf_head(resp), wpabuf_len(resp), 200) < 0) {
683                 p2p_dbg(p2p, "Failed to send Action frame");
684         } else
685                 p2p->send_action_in_progress = 1;
686
687         wpabuf_free(resp);
688
689         if (!p2p->cfg->p2ps_prov_complete) {
690                 /* Don't emit anything */
691         } else if (msg.status && *msg.status != P2P_SC_SUCCESS &&
692                    *msg.status != P2P_SC_SUCCESS_DEFERRED) {
693                 reject = *msg.status;
694                 p2p->cfg->p2ps_prov_complete(p2p->cfg->cb_ctx, reject,
695                                              sa, adv_mac, session_mac,
696                                              NULL, adv_id, session_id,
697                                              0, 0, msg.persistent_ssid,
698                                              msg.persistent_ssid_len,
699                                              0, 0, NULL);
700         } else if (msg.status && *msg.status == P2P_SC_SUCCESS_DEFERRED &&
701                    p2p->p2ps_prov) {
702                 p2p->p2ps_prov->status = reject;
703                 p2p->p2ps_prov->conncap = conncap;
704
705                 if (reject != P2P_SC_SUCCESS)
706                         p2p->cfg->p2ps_prov_complete(p2p->cfg->cb_ctx, reject,
707                                                      sa, adv_mac, session_mac,
708                                                      NULL, adv_id,
709                                                      session_id, conncap, 0,
710                                                      msg.persistent_ssid,
711                                                      msg.persistent_ssid_len, 0,
712                                                      0, NULL);
713                 else
714                         p2p->cfg->p2ps_prov_complete(p2p->cfg->cb_ctx,
715                                                      *msg.status,
716                                                      sa, adv_mac, session_mac,
717                                                      group_mac, adv_id,
718                                                      session_id, conncap,
719                                                      passwd_id,
720                                                      msg.persistent_ssid,
721                                                      msg.persistent_ssid_len, 0,
722                                                      0, NULL);
723         } else if (msg.status && p2p->p2ps_prov) {
724                 p2p->p2ps_prov->status = P2P_SC_SUCCESS;
725                 p2p->cfg->p2ps_prov_complete(p2p->cfg->cb_ctx, *msg.status, sa,
726                                              adv_mac, session_mac, group_mac,
727                                              adv_id, session_id, conncap,
728                                              passwd_id,
729                                              msg.persistent_ssid,
730                                              msg.persistent_ssid_len,
731                                              0, 0, NULL);
732         } else if (msg.status) {
733         } else if (auto_accept && reject == P2P_SC_SUCCESS) {
734                 p2p->cfg->p2ps_prov_complete(p2p->cfg->cb_ctx, P2P_SC_SUCCESS,
735                                              sa, adv_mac, session_mac,
736                                              group_mac, adv_id, session_id,
737                                              conncap, passwd_id,
738                                              msg.persistent_ssid,
739                                              msg.persistent_ssid_len,
740                                              0, 0, NULL);
741         } else if (reject == P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE &&
742                    (!msg.session_info || !msg.session_info_len)) {
743                 p2p->p2ps_prov->method = msg.wps_config_methods;
744
745                 p2p->cfg->p2ps_prov_complete(p2p->cfg->cb_ctx, P2P_SC_SUCCESS,
746                                              sa, adv_mac, session_mac,
747                                              group_mac, adv_id, session_id,
748                                              conncap, passwd_id,
749                                              msg.persistent_ssid,
750                                              msg.persistent_ssid_len,
751                                              0, 1, NULL);
752         } else if (reject == P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE) {
753                 size_t buf_len = msg.session_info_len;
754                 char *buf = os_malloc(2 * buf_len + 1);
755
756                 if (buf) {
757                         p2p->p2ps_prov->method = msg.wps_config_methods;
758
759                         utf8_escape((char *) msg.session_info, buf_len,
760                                     buf, 2 * buf_len + 1);
761
762                         p2p->cfg->p2ps_prov_complete(
763                                 p2p->cfg->cb_ctx, P2P_SC_SUCCESS, sa,
764                                 adv_mac, session_mac, group_mac, adv_id,
765                                 session_id, conncap, passwd_id,
766                                 msg.persistent_ssid, msg.persistent_ssid_len,
767                                 0, 1, buf);
768
769                         os_free(buf);
770                 }
771         }
772
773         if (reject == P2P_SC_SUCCESS && p2p->cfg->prov_disc_req) {
774                 const u8 *dev_addr = sa;
775                 if (msg.p2p_device_addr)
776                         dev_addr = msg.p2p_device_addr;
777                 p2p->cfg->prov_disc_req(p2p->cfg->cb_ctx, sa,
778                                         msg.wps_config_methods,
779                                         dev_addr, msg.pri_dev_type,
780                                         msg.device_name, msg.config_methods,
781                                         msg.capability ? msg.capability[0] : 0,
782                                         msg.capability ? msg.capability[1] :
783                                         0,
784                                         msg.group_id, msg.group_id_len);
785         }
786         p2p_parse_free(&msg);
787 }
788
789
790 void p2p_process_prov_disc_resp(struct p2p_data *p2p, const u8 *sa,
791                                 const u8 *data, size_t len)
792 {
793         struct p2p_message msg;
794         struct p2p_device *dev;
795         u16 report_config_methods = 0, req_config_methods;
796         u8 status = P2P_SC_SUCCESS;
797         int success = 0;
798         u32 adv_id = 0;
799         u8 conncap = P2PS_SETUP_NEW;
800         u8 adv_mac[ETH_ALEN];
801         u8 group_mac[ETH_ALEN];
802         int passwd_id = DEV_PW_DEFAULT;
803
804         if (p2p_parse(data, len, &msg))
805                 return;
806
807         /* Parse the P2PS members present */
808         if (msg.status)
809                 status = *msg.status;
810
811         if (msg.intended_addr)
812                 os_memcpy(group_mac, msg.intended_addr, ETH_ALEN);
813         else
814                 os_memset(group_mac, 0, ETH_ALEN);
815
816         if (msg.adv_mac)
817                 os_memcpy(adv_mac, msg.adv_mac, ETH_ALEN);
818         else
819                 os_memset(adv_mac, 0, ETH_ALEN);
820
821         if (msg.adv_id)
822                 adv_id = WPA_GET_LE32(msg.adv_id);
823
824         if (msg.conn_cap) {
825                 conncap = *msg.conn_cap;
826
827                 /* Switch bits to local relative */
828                 switch (conncap) {
829                 case P2PS_SETUP_GROUP_OWNER:
830                         conncap = P2PS_SETUP_CLIENT;
831                         break;
832                 case P2PS_SETUP_CLIENT:
833                         conncap = P2PS_SETUP_GROUP_OWNER;
834                         break;
835                 }
836         }
837
838         p2p_dbg(p2p, "Received Provision Discovery Response from " MACSTR
839                 " with config methods 0x%x",
840                 MAC2STR(sa), msg.wps_config_methods);
841
842         dev = p2p_get_device(p2p, sa);
843         if (dev == NULL || !dev->req_config_methods) {
844                 p2p_dbg(p2p, "Ignore Provision Discovery Response from " MACSTR
845                         " with no pending request", MAC2STR(sa));
846                 p2p_parse_free(&msg);
847                 return;
848         }
849
850         if (dev->dialog_token != msg.dialog_token) {
851                 p2p_dbg(p2p, "Ignore Provision Discovery Response with unexpected Dialog Token %u (expected %u)",
852                         msg.dialog_token, dev->dialog_token);
853                 p2p_parse_free(&msg);
854                 return;
855         }
856
857         if (p2p->pending_action_state == P2P_PENDING_PD) {
858                 os_memset(p2p->pending_pd_devaddr, 0, ETH_ALEN);
859                 p2p->pending_action_state = P2P_NO_PENDING_ACTION;
860         }
861
862         /*
863          * Use a local copy of the requested config methods since
864          * p2p_reset_pending_pd() can clear this in the peer entry.
865          */
866         req_config_methods = dev->req_config_methods;
867
868         /*
869          * If the response is from the peer to whom a user initiated request
870          * was sent earlier, we reset that state info here.
871          */
872         if (p2p->user_initiated_pd &&
873             os_memcmp(p2p->pending_pd_devaddr, sa, ETH_ALEN) == 0)
874                 p2p_reset_pending_pd(p2p);
875
876         if (msg.wps_config_methods != req_config_methods) {
877                 p2p_dbg(p2p, "Peer rejected our Provision Discovery Request (received config_methods 0x%x expected 0x%x",
878                         msg.wps_config_methods, req_config_methods);
879                 if (p2p->cfg->prov_disc_fail)
880                         p2p->cfg->prov_disc_fail(p2p->cfg->cb_ctx, sa,
881                                                  P2P_PROV_DISC_REJECTED,
882                                                  adv_id, adv_mac, NULL);
883                 p2p_parse_free(&msg);
884                 os_free(p2p->p2ps_prov);
885                 p2p->p2ps_prov = NULL;
886                 goto out;
887         }
888
889         report_config_methods = req_config_methods;
890         dev->flags &= ~(P2P_DEV_PD_PEER_DISPLAY |
891                         P2P_DEV_PD_PEER_KEYPAD |
892                         P2P_DEV_PD_PEER_P2PS);
893         if (req_config_methods & WPS_CONFIG_DISPLAY) {
894                 p2p_dbg(p2p, "Peer " MACSTR
895                         " accepted to show a PIN on display", MAC2STR(sa));
896                 dev->flags |= P2P_DEV_PD_PEER_DISPLAY;
897                 passwd_id = DEV_PW_REGISTRAR_SPECIFIED;
898         } else if (msg.wps_config_methods & WPS_CONFIG_KEYPAD) {
899                 p2p_dbg(p2p, "Peer " MACSTR
900                         " accepted to write our PIN using keypad",
901                         MAC2STR(sa));
902                 dev->flags |= P2P_DEV_PD_PEER_KEYPAD;
903                 passwd_id = DEV_PW_USER_SPECIFIED;
904         } else if (msg.wps_config_methods & WPS_CONFIG_P2PS) {
905                 p2p_dbg(p2p, "Peer " MACSTR " accepted P2PS PIN",
906                         MAC2STR(sa));
907                 dev->flags |= P2P_DEV_PD_PEER_P2PS;
908                 passwd_id = DEV_PW_P2PS_DEFAULT;
909         }
910
911         if ((msg.conn_cap || msg.persistent_dev) &&
912             msg.adv_id &&
913             (status == P2P_SC_SUCCESS || status == P2P_SC_SUCCESS_DEFERRED) &&
914             p2p->p2ps_prov) {
915                 if (p2p->cfg->p2ps_prov_complete) {
916                         p2p->cfg->p2ps_prov_complete(
917                                 p2p->cfg->cb_ctx, status, sa, adv_mac,
918                                 p2p->p2ps_prov->session_mac,
919                                 group_mac, adv_id, p2p->p2ps_prov->session_id,
920                                 conncap, passwd_id, msg.persistent_ssid,
921                                 msg.persistent_ssid_len, 1, 0, NULL);
922                 }
923                 os_free(p2p->p2ps_prov);
924                 p2p->p2ps_prov = NULL;
925         }
926
927         if (status != P2P_SC_SUCCESS &&
928             status != P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE &&
929             status != P2P_SC_SUCCESS_DEFERRED && p2p->p2ps_prov) {
930                 if (p2p->cfg->p2ps_prov_complete)
931                         p2p->cfg->p2ps_prov_complete(
932                                 p2p->cfg->cb_ctx, status, sa, adv_mac,
933                                 p2p->p2ps_prov->session_mac,
934                                 group_mac, adv_id, p2p->p2ps_prov->session_id,
935                                 0, 0, NULL, 0, 1, 0, NULL);
936                 os_free(p2p->p2ps_prov);
937                 p2p->p2ps_prov = NULL;
938         }
939
940         if (status == P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE) {
941                 if (p2p->cfg->remove_stale_groups) {
942                         p2p->cfg->remove_stale_groups(p2p->cfg->cb_ctx,
943                                                       dev->info.p2p_device_addr,
944                                                       NULL, NULL, 0);
945                 }
946
947                 if (msg.session_info && msg.session_info_len) {
948                         size_t info_len = msg.session_info_len;
949                         char *deferred_sess_resp = os_malloc(2 * info_len + 1);
950
951                         if (!deferred_sess_resp) {
952                                 p2p_parse_free(&msg);
953                                 os_free(p2p->p2ps_prov);
954                                 p2p->p2ps_prov = NULL;
955                                 goto out;
956                         }
957                         utf8_escape((char *) msg.session_info, info_len,
958                                     deferred_sess_resp, 2 * info_len + 1);
959
960                         if (p2p->cfg->prov_disc_fail)
961                                 p2p->cfg->prov_disc_fail(
962                                         p2p->cfg->cb_ctx, sa,
963                                         P2P_PROV_DISC_INFO_UNAVAILABLE,
964                                         adv_id, adv_mac,
965                                         deferred_sess_resp);
966                         os_free(deferred_sess_resp);
967                 } else
968                         if (p2p->cfg->prov_disc_fail)
969                                 p2p->cfg->prov_disc_fail(
970                                         p2p->cfg->cb_ctx, sa,
971                                         P2P_PROV_DISC_INFO_UNAVAILABLE,
972                                         adv_id, adv_mac, NULL);
973         } else if (msg.wps_config_methods != dev->req_config_methods ||
974                    status != P2P_SC_SUCCESS) {
975                 p2p_dbg(p2p, "Peer rejected our Provision Discovery Request");
976                 if (p2p->cfg->prov_disc_fail)
977                         p2p->cfg->prov_disc_fail(p2p->cfg->cb_ctx, sa,
978                                                  P2P_PROV_DISC_REJECTED, 0,
979                                                  NULL, NULL);
980                 p2p_parse_free(&msg);
981                 os_free(p2p->p2ps_prov);
982                 p2p->p2ps_prov = NULL;
983                 goto out;
984         }
985
986         /* Store the provisioning info */
987         dev->wps_prov_info = msg.wps_config_methods;
988
989         p2p_parse_free(&msg);
990         success = 1;
991
992 out:
993         dev->req_config_methods = 0;
994         p2p->cfg->send_action_done(p2p->cfg->cb_ctx);
995         if (dev->flags & P2P_DEV_PD_BEFORE_GO_NEG) {
996                 p2p_dbg(p2p, "Start GO Neg after the PD-before-GO-Neg workaround with "
997                         MACSTR, MAC2STR(dev->info.p2p_device_addr));
998                 dev->flags &= ~P2P_DEV_PD_BEFORE_GO_NEG;
999                 p2p_connect_send(p2p, dev);
1000                 return;
1001         }
1002         if (success && p2p->cfg->prov_disc_resp)
1003                 p2p->cfg->prov_disc_resp(p2p->cfg->cb_ctx, sa,
1004                                          report_config_methods);
1005
1006         if (p2p->state == P2P_PD_DURING_FIND) {
1007                 p2p_clear_timeout(p2p);
1008                 p2p_continue_find(p2p);
1009         }
1010 }
1011
1012
1013 int p2p_send_prov_disc_req(struct p2p_data *p2p, struct p2p_device *dev,
1014                            int join, int force_freq)
1015 {
1016         struct wpabuf *req;
1017         int freq;
1018
1019         if (force_freq > 0)
1020                 freq = force_freq;
1021         else
1022                 freq = dev->listen_freq > 0 ? dev->listen_freq :
1023                         dev->oper_freq;
1024         if (freq <= 0) {
1025                 p2p_dbg(p2p, "No Listen/Operating frequency known for the peer "
1026                         MACSTR " to send Provision Discovery Request",
1027                         MAC2STR(dev->info.p2p_device_addr));
1028                 return -1;
1029         }
1030
1031         if (dev->flags & P2P_DEV_GROUP_CLIENT_ONLY) {
1032                 if (!(dev->info.dev_capab &
1033                       P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY)) {
1034                         p2p_dbg(p2p, "Cannot use PD with P2P Device " MACSTR
1035                                 " that is in a group and is not discoverable",
1036                                 MAC2STR(dev->info.p2p_device_addr));
1037                         return -1;
1038                 }
1039                 /* TODO: use device discoverability request through GO */
1040         }
1041
1042         if (p2p->p2ps_prov) {
1043                 if (p2p->p2ps_prov->status == P2P_SC_SUCCESS_DEFERRED) {
1044                         if (p2p->p2ps_prov->method == WPS_CONFIG_DISPLAY)
1045                                 dev->req_config_methods = WPS_CONFIG_KEYPAD;
1046                         else if (p2p->p2ps_prov->method == WPS_CONFIG_KEYPAD)
1047                                 dev->req_config_methods = WPS_CONFIG_DISPLAY;
1048                         else
1049                                 dev->req_config_methods = WPS_CONFIG_P2PS;
1050                 } else {
1051                         /* Order of preference, based on peer's capabilities */
1052                         if (p2p->p2ps_prov->method)
1053                                 dev->req_config_methods =
1054                                         p2p->p2ps_prov->method;
1055                         else if (dev->info.config_methods & WPS_CONFIG_P2PS)
1056                                 dev->req_config_methods = WPS_CONFIG_P2PS;
1057                         else if (dev->info.config_methods & WPS_CONFIG_DISPLAY)
1058                                 dev->req_config_methods = WPS_CONFIG_DISPLAY;
1059                         else
1060                                 dev->req_config_methods = WPS_CONFIG_KEYPAD;
1061                 }
1062                 p2p_dbg(p2p,
1063                         "Building PD Request based on P2PS config method 0x%x status %d --> req_config_methods 0x%x",
1064                         p2p->p2ps_prov->method, p2p->p2ps_prov->status,
1065                         dev->req_config_methods);
1066         }
1067
1068         req = p2p_build_prov_disc_req(p2p, dev, join);
1069         if (req == NULL)
1070                 return -1;
1071
1072         if (p2p->state != P2P_IDLE)
1073                 p2p_stop_listen_for_freq(p2p, freq);
1074         p2p->pending_action_state = P2P_PENDING_PD;
1075         if (p2p_send_action(p2p, freq, dev->info.p2p_device_addr,
1076                             p2p->cfg->dev_addr, dev->info.p2p_device_addr,
1077                             wpabuf_head(req), wpabuf_len(req), 200) < 0) {
1078                 p2p_dbg(p2p, "Failed to send Action frame");
1079                 wpabuf_free(req);
1080                 return -1;
1081         }
1082
1083         os_memcpy(p2p->pending_pd_devaddr, dev->info.p2p_device_addr, ETH_ALEN);
1084
1085         wpabuf_free(req);
1086         return 0;
1087 }
1088
1089
1090 int p2p_prov_disc_req(struct p2p_data *p2p, const u8 *peer_addr,
1091                       struct p2ps_provision *p2ps_prov,
1092                       u16 config_methods, int join, int force_freq,
1093                       int user_initiated_pd)
1094 {
1095         struct p2p_device *dev;
1096
1097         dev = p2p_get_device(p2p, peer_addr);
1098         if (dev == NULL)
1099                 dev = p2p_get_device_interface(p2p, peer_addr);
1100         if (dev == NULL || (dev->flags & P2P_DEV_PROBE_REQ_ONLY)) {
1101                 p2p_dbg(p2p, "Provision Discovery Request destination " MACSTR
1102                         " not yet known", MAC2STR(peer_addr));
1103                 os_free(p2ps_prov);
1104                 return -1;
1105         }
1106
1107         p2p_dbg(p2p, "Provision Discovery Request with " MACSTR
1108                 " (config methods 0x%x)",
1109                 MAC2STR(peer_addr), config_methods);
1110         if (config_methods == 0 && !p2ps_prov) {
1111                 os_free(p2ps_prov);
1112                 return -1;
1113         }
1114
1115         if (p2ps_prov && p2ps_prov->status == P2P_SC_SUCCESS_DEFERRED &&
1116             p2p->p2ps_prov) {
1117                 /* Use cached method from deferred provisioning */
1118                 p2ps_prov->method = p2p->p2ps_prov->method;
1119         }
1120
1121         /* Reset provisioning info */
1122         dev->wps_prov_info = 0;
1123         os_free(p2p->p2ps_prov);
1124         p2p->p2ps_prov = p2ps_prov;
1125
1126         dev->req_config_methods = config_methods;
1127         if (join)
1128                 dev->flags |= P2P_DEV_PD_FOR_JOIN;
1129         else
1130                 dev->flags &= ~P2P_DEV_PD_FOR_JOIN;
1131
1132         if (p2p->state != P2P_IDLE && p2p->state != P2P_SEARCH &&
1133             p2p->state != P2P_LISTEN_ONLY) {
1134                 p2p_dbg(p2p, "Busy with other operations; postpone Provision Discovery Request with "
1135                         MACSTR " (config methods 0x%x)",
1136                         MAC2STR(peer_addr), config_methods);
1137                 return 0;
1138         }
1139
1140         p2p->user_initiated_pd = user_initiated_pd;
1141         p2p->pd_force_freq = force_freq;
1142
1143         if (p2p->user_initiated_pd)
1144                 p2p->pd_retries = MAX_PROV_DISC_REQ_RETRIES;
1145
1146         /*
1147          * Assign dialog token here to use the same value in each retry within
1148          * the same PD exchange.
1149          */
1150         dev->dialog_token++;
1151         if (dev->dialog_token == 0)
1152                 dev->dialog_token = 1;
1153
1154         return p2p_send_prov_disc_req(p2p, dev, join, force_freq);
1155 }
1156
1157
1158 void p2p_reset_pending_pd(struct p2p_data *p2p)
1159 {
1160         struct p2p_device *dev;
1161
1162         dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) {
1163                 if (os_memcmp(p2p->pending_pd_devaddr,
1164                               dev->info.p2p_device_addr, ETH_ALEN))
1165                         continue;
1166                 if (!dev->req_config_methods)
1167                         continue;
1168                 if (dev->flags & P2P_DEV_PD_FOR_JOIN)
1169                         continue;
1170                 /* Reset the config methods of the device */
1171                 dev->req_config_methods = 0;
1172         }
1173
1174         p2p->user_initiated_pd = 0;
1175         os_memset(p2p->pending_pd_devaddr, 0, ETH_ALEN);
1176         p2p->pd_retries = 0;
1177         p2p->pd_force_freq = 0;
1178 }