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