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