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