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