1 /* 2 * Wi-Fi Direct - P2P group operations 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/ieee802_11_common.h" 14 #include "common/wpa_ctrl.h" 15 #include "wps/wps_defs.h" 16 #include "wps/wps_i.h" 17 #include "p2p_i.h" 18 #include "p2p.h" 19 20 21 struct p2p_group_member { 22 struct p2p_group_member *next; 23 u8 addr[ETH_ALEN]; /* P2P Interface Address */ 24 u8 dev_addr[ETH_ALEN]; /* P2P Device Address */ 25 struct wpabuf *p2p_ie; 26 struct wpabuf *wfd_ie; 27 struct wpabuf *client_info; 28 u8 dev_capab; 29 }; 30 31 /** 32 * struct p2p_group - Internal P2P module per-group data 33 */ 34 struct p2p_group { 35 struct p2p_data *p2p; 36 struct p2p_group_config *cfg; 37 struct p2p_group_member *members; 38 unsigned int num_members; 39 int group_formation; 40 int beacon_update; 41 struct wpabuf *noa; 42 struct wpabuf *wfd_ie; 43 }; 44 45 p2p_group_init(struct p2p_data * p2p,struct p2p_group_config * config)46 struct p2p_group * p2p_group_init(struct p2p_data *p2p, 47 struct p2p_group_config *config) 48 { 49 struct p2p_group *group, **groups; 50 51 group = os_zalloc(sizeof(*group)); 52 if (group == NULL) 53 return NULL; 54 55 groups = os_realloc_array(p2p->groups, p2p->num_groups + 1, 56 sizeof(struct p2p_group *)); 57 if (groups == NULL) { 58 os_free(group); 59 return NULL; 60 } 61 groups[p2p->num_groups++] = group; 62 p2p->groups = groups; 63 64 group->p2p = p2p; 65 group->cfg = config; 66 group->group_formation = 1; 67 group->beacon_update = 1; 68 p2p_group_update_ies(group); 69 group->cfg->idle_update(group->cfg->cb_ctx, 1); 70 71 return group; 72 } 73 74 p2p_group_free_member(struct p2p_group_member * m)75 static void p2p_group_free_member(struct p2p_group_member *m) 76 { 77 wpabuf_free(m->wfd_ie); 78 wpabuf_free(m->p2p_ie); 79 wpabuf_free(m->client_info); 80 os_free(m); 81 } 82 83 p2p_group_free_members(struct p2p_group * group)84 static void p2p_group_free_members(struct p2p_group *group) 85 { 86 struct p2p_group_member *m, *prev; 87 m = group->members; 88 group->members = NULL; 89 group->num_members = 0; 90 while (m) { 91 prev = m; 92 m = m->next; 93 p2p_group_free_member(prev); 94 } 95 } 96 97 p2p_group_deinit(struct p2p_group * group)98 void p2p_group_deinit(struct p2p_group *group) 99 { 100 size_t g; 101 struct p2p_data *p2p; 102 103 if (group == NULL) 104 return; 105 106 p2p = group->p2p; 107 108 for (g = 0; g < p2p->num_groups; g++) { 109 if (p2p->groups[g] == group) { 110 while (g + 1 < p2p->num_groups) { 111 p2p->groups[g] = p2p->groups[g + 1]; 112 g++; 113 } 114 p2p->num_groups--; 115 break; 116 } 117 } 118 119 p2p_group_free_members(group); 120 os_free(group->cfg); 121 wpabuf_free(group->noa); 122 wpabuf_free(group->wfd_ie); 123 os_free(group); 124 } 125 126 p2p_client_info(struct wpabuf * ie,struct p2p_group_member * m)127 static void p2p_client_info(struct wpabuf *ie, struct p2p_group_member *m) 128 { 129 if (m->client_info == NULL) 130 return; 131 if (wpabuf_tailroom(ie) < wpabuf_len(m->client_info) + 1) 132 return; 133 wpabuf_put_buf(ie, m->client_info); 134 } 135 136 p2p_group_add_common_ies(struct p2p_group * group,struct wpabuf * ie)137 static void p2p_group_add_common_ies(struct p2p_group *group, 138 struct wpabuf *ie) 139 { 140 u8 dev_capab = group->p2p->dev_capab, group_capab = 0; 141 142 /* P2P Capability */ 143 dev_capab &= ~P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY; 144 group_capab |= P2P_GROUP_CAPAB_GROUP_OWNER; 145 if (group->cfg->persistent_group) { 146 group_capab |= P2P_GROUP_CAPAB_PERSISTENT_GROUP; 147 if (group->cfg->persistent_group == 2) 148 group_capab |= P2P_GROUP_CAPAB_PERSISTENT_RECONN; 149 } 150 if (group->p2p->cfg->p2p_intra_bss) 151 group_capab |= P2P_GROUP_CAPAB_INTRA_BSS_DIST; 152 if (group->group_formation) 153 group_capab |= P2P_GROUP_CAPAB_GROUP_FORMATION; 154 if (group->p2p->cross_connect) 155 group_capab |= P2P_GROUP_CAPAB_CROSS_CONN; 156 if (group->num_members >= group->cfg->max_clients) 157 group_capab |= P2P_GROUP_CAPAB_GROUP_LIMIT; 158 if (group->cfg->ip_addr_alloc) 159 group_capab |= P2P_GROUP_CAPAB_IP_ADDR_ALLOCATION; 160 p2p_buf_add_capability(ie, dev_capab, group_capab); 161 } 162 163 p2p_group_add_noa(struct wpabuf * ie,struct wpabuf * noa)164 static void p2p_group_add_noa(struct wpabuf *ie, struct wpabuf *noa) 165 { 166 if (noa == NULL) 167 return; 168 /* Notice of Absence */ 169 wpabuf_put_u8(ie, P2P_ATTR_NOTICE_OF_ABSENCE); 170 wpabuf_put_le16(ie, wpabuf_len(noa)); 171 wpabuf_put_buf(ie, noa); 172 } 173 174 p2p_group_encaps_probe_resp(struct wpabuf * subelems)175 static struct wpabuf * p2p_group_encaps_probe_resp(struct wpabuf *subelems) 176 { 177 struct wpabuf *ie; 178 const u8 *pos, *end; 179 size_t len; 180 181 if (subelems == NULL) 182 return NULL; 183 184 len = wpabuf_len(subelems) + 100; 185 186 ie = wpabuf_alloc(len); 187 if (ie == NULL) 188 return NULL; 189 190 pos = wpabuf_head(subelems); 191 end = pos + wpabuf_len(subelems); 192 193 while (end > pos) { 194 size_t frag_len = end - pos; 195 if (frag_len > 251) 196 frag_len = 251; 197 wpabuf_put_u8(ie, WLAN_EID_VENDOR_SPECIFIC); 198 wpabuf_put_u8(ie, 4 + frag_len); 199 wpabuf_put_be32(ie, P2P_IE_VENDOR_TYPE); 200 wpabuf_put_data(ie, pos, frag_len); 201 pos += frag_len; 202 } 203 204 return ie; 205 } 206 207 p2p_group_build_p2p2_ie(struct p2p_data * p2p,struct wpabuf * p2p2_ie,int freq)208 struct wpabuf * p2p_group_build_p2p2_ie(struct p2p_data *p2p, 209 struct wpabuf *p2p2_ie, int freq) 210 { 211 u8 *len; 212 213 wpabuf_put_u8(p2p2_ie, WLAN_EID_VENDOR_SPECIFIC); 214 len = wpabuf_put(p2p2_ie, 1); 215 wpabuf_put_be32(p2p2_ie, P2P2_IE_VENDOR_TYPE); 216 wpa_printf(MSG_DEBUG, "P2P: * P2P2 IE header"); 217 p2p_buf_add_pcea(p2p2_ie, p2p); 218 *len = (u8 *) wpabuf_put(p2p2_ie, 0) - len - 1; 219 220 return p2p2_ie; 221 } 222 223 p2p_group_build_beacon_ie(struct p2p_group * group)224 static struct wpabuf * p2p_group_build_beacon_ie(struct p2p_group *group) 225 { 226 struct wpabuf *ie; 227 u8 *len; 228 size_t extra = 0; 229 struct wpabuf *p2p2_ie; 230 231 #ifdef CONFIG_WIFI_DISPLAY 232 if (group->p2p->wfd_ie_beacon) 233 extra = wpabuf_len(group->p2p->wfd_ie_beacon); 234 #endif /* CONFIG_WIFI_DISPLAY */ 235 236 if (group->p2p->vendor_elem && 237 group->p2p->vendor_elem[VENDOR_ELEM_BEACON_P2P_GO]) 238 extra += wpabuf_len(group->p2p->vendor_elem[VENDOR_ELEM_BEACON_P2P_GO]); 239 240 ie = wpabuf_alloc(500 + extra); 241 if (ie == NULL) 242 return NULL; 243 244 #ifdef CONFIG_WIFI_DISPLAY 245 if (group->p2p->wfd_ie_beacon) 246 wpabuf_put_buf(ie, group->p2p->wfd_ie_beacon); 247 #endif /* CONFIG_WIFI_DISPLAY */ 248 249 if (group->p2p->vendor_elem && 250 group->p2p->vendor_elem[VENDOR_ELEM_BEACON_P2P_GO]) 251 wpabuf_put_buf(ie, 252 group->p2p->vendor_elem[VENDOR_ELEM_BEACON_P2P_GO]); 253 254 len = p2p_buf_add_ie_hdr(ie); 255 p2p_group_add_common_ies(group, ie); 256 p2p_buf_add_device_id(ie, group->p2p->cfg->dev_addr); 257 p2p_group_add_noa(ie, group->noa); 258 p2p_buf_update_ie_hdr(ie, len); 259 260 if (group->cfg->p2p2) { 261 p2p2_ie = wpabuf_alloc(255); 262 if (!p2p2_ie) { 263 wpabuf_free(ie); 264 return NULL; 265 } 266 267 p2p_group_build_p2p2_ie(group->p2p, p2p2_ie, group->cfg->freq); 268 ie = wpabuf_concat(p2p2_ie, ie); 269 } 270 271 return ie; 272 } 273 274 275 #ifdef CONFIG_WIFI_DISPLAY 276 p2p_group_get_wfd_ie(struct p2p_group * g)277 struct wpabuf * p2p_group_get_wfd_ie(struct p2p_group *g) 278 { 279 return g->wfd_ie; 280 } 281 282 wifi_display_encaps(struct wpabuf * subelems)283 struct wpabuf * wifi_display_encaps(struct wpabuf *subelems) 284 { 285 struct wpabuf *ie; 286 const u8 *pos, *end; 287 288 if (subelems == NULL) 289 return NULL; 290 291 ie = wpabuf_alloc(wpabuf_len(subelems) + 100); 292 if (ie == NULL) 293 return NULL; 294 295 pos = wpabuf_head(subelems); 296 end = pos + wpabuf_len(subelems); 297 298 while (end > pos) { 299 size_t frag_len = end - pos; 300 if (frag_len > 251) 301 frag_len = 251; 302 wpabuf_put_u8(ie, WLAN_EID_VENDOR_SPECIFIC); 303 wpabuf_put_u8(ie, 4 + frag_len); 304 wpabuf_put_be32(ie, WFD_IE_VENDOR_TYPE); 305 wpabuf_put_data(ie, pos, frag_len); 306 pos += frag_len; 307 } 308 309 return ie; 310 } 311 312 wifi_display_add_dev_info_descr(struct wpabuf * buf,struct p2p_group_member * m)313 static int wifi_display_add_dev_info_descr(struct wpabuf *buf, 314 struct p2p_group_member *m) 315 { 316 const u8 *pos, *end; 317 const u8 *dev_info = NULL; 318 const u8 *assoc_bssid = NULL; 319 const u8 *coupled_sink = NULL; 320 u8 zero_addr[ETH_ALEN]; 321 322 if (m->wfd_ie == NULL) 323 return 0; 324 325 os_memset(zero_addr, 0, ETH_ALEN); 326 pos = wpabuf_head_u8(m->wfd_ie); 327 end = pos + wpabuf_len(m->wfd_ie); 328 while (end - pos >= 3) { 329 u8 id; 330 u16 len; 331 332 id = *pos++; 333 len = WPA_GET_BE16(pos); 334 pos += 2; 335 if (len > end - pos) 336 break; 337 338 switch (id) { 339 case WFD_SUBELEM_DEVICE_INFO: 340 if (len < 6) 341 break; 342 dev_info = pos; 343 break; 344 case WFD_SUBELEM_ASSOCIATED_BSSID: 345 if (len < ETH_ALEN) 346 break; 347 assoc_bssid = pos; 348 break; 349 case WFD_SUBELEM_COUPLED_SINK: 350 if (len < 1 + ETH_ALEN) 351 break; 352 coupled_sink = pos; 353 break; 354 } 355 356 pos += len; 357 } 358 359 if (dev_info == NULL) 360 return 0; 361 362 wpabuf_put_u8(buf, 23); 363 wpabuf_put_data(buf, m->dev_addr, ETH_ALEN); 364 if (assoc_bssid) 365 wpabuf_put_data(buf, assoc_bssid, ETH_ALEN); 366 else 367 wpabuf_put_data(buf, zero_addr, ETH_ALEN); 368 wpabuf_put_data(buf, dev_info, 2); /* WFD Device Info */ 369 wpabuf_put_data(buf, dev_info + 4, 2); /* WFD Device Max Throughput */ 370 if (coupled_sink) { 371 wpabuf_put_data(buf, coupled_sink, 1 + ETH_ALEN); 372 } else { 373 wpabuf_put_u8(buf, 0); 374 wpabuf_put_data(buf, zero_addr, ETH_ALEN); 375 } 376 377 return 1; 378 } 379 380 381 static struct wpabuf * wifi_display_build_go_ie(struct p2p_group * group)382 wifi_display_build_go_ie(struct p2p_group *group) 383 { 384 struct wpabuf *wfd_subelems, *wfd_ie; 385 struct p2p_group_member *m; 386 u8 *len; 387 unsigned int count = 0; 388 389 if (!group->p2p->wfd_ie_probe_resp) 390 return NULL; 391 392 wfd_subelems = wpabuf_alloc(wpabuf_len(group->p2p->wfd_ie_probe_resp) + 393 group->num_members * 24 + 100); 394 if (wfd_subelems == NULL) 395 return NULL; 396 if (group->p2p->wfd_dev_info) 397 wpabuf_put_buf(wfd_subelems, group->p2p->wfd_dev_info); 398 if (group->p2p->wfd_r2_dev_info) 399 wpabuf_put_buf(wfd_subelems, group->p2p->wfd_r2_dev_info); 400 if (group->p2p->wfd_assoc_bssid) 401 wpabuf_put_buf(wfd_subelems, 402 group->p2p->wfd_assoc_bssid); 403 if (group->p2p->wfd_coupled_sink_info) 404 wpabuf_put_buf(wfd_subelems, 405 group->p2p->wfd_coupled_sink_info); 406 407 /* Build WFD Session Info */ 408 wpabuf_put_u8(wfd_subelems, WFD_SUBELEM_SESSION_INFO); 409 len = wpabuf_put(wfd_subelems, 2); 410 m = group->members; 411 while (m) { 412 if (wifi_display_add_dev_info_descr(wfd_subelems, m)) 413 count++; 414 m = m->next; 415 } 416 417 if (count == 0) { 418 /* No Wi-Fi Display clients - do not include subelement */ 419 wfd_subelems->used -= 3; 420 } else { 421 WPA_PUT_BE16(len, (u8 *) wpabuf_put(wfd_subelems, 0) - len - 422 2); 423 p2p_dbg(group->p2p, "WFD: WFD Session Info: %u descriptors", 424 count); 425 } 426 427 wfd_ie = wifi_display_encaps(wfd_subelems); 428 wpabuf_free(wfd_subelems); 429 430 return wfd_ie; 431 } 432 wifi_display_group_update(struct p2p_group * group)433 static void wifi_display_group_update(struct p2p_group *group) 434 { 435 wpabuf_free(group->wfd_ie); 436 group->wfd_ie = wifi_display_build_go_ie(group); 437 } 438 439 #endif /* CONFIG_WIFI_DISPLAY */ 440 441 p2p_buf_add_group_info(struct p2p_group * group,struct wpabuf * buf,int max_clients)442 void p2p_buf_add_group_info(struct p2p_group *group, struct wpabuf *buf, 443 int max_clients) 444 { 445 u8 *group_info; 446 int count = 0; 447 struct p2p_group_member *m; 448 449 p2p_dbg(group->p2p, "* P2P Group Info"); 450 group_info = wpabuf_put(buf, 0); 451 wpabuf_put_u8(buf, P2P_ATTR_GROUP_INFO); 452 wpabuf_put_le16(buf, 0); /* Length to be filled */ 453 for (m = group->members; m; m = m->next) { 454 p2p_client_info(buf, m); 455 count++; 456 if (max_clients >= 0 && count >= max_clients) 457 break; 458 } 459 WPA_PUT_LE16(group_info + 1, 460 (u8 *) wpabuf_put(buf, 0) - group_info - 3); 461 } 462 463 p2p_group_buf_add_id(struct p2p_group * group,struct wpabuf * buf)464 void p2p_group_buf_add_id(struct p2p_group *group, struct wpabuf *buf) 465 { 466 p2p_buf_add_group_id(buf, group->p2p->cfg->dev_addr, group->cfg->ssid, 467 group->cfg->ssid_len); 468 } 469 470 p2p_group_build_probe_resp_ie(struct p2p_group * group)471 static struct wpabuf * p2p_group_build_probe_resp_ie(struct p2p_group *group) 472 { 473 struct wpabuf *p2p_subelems, *ie; 474 struct wpabuf *p2p2_ie; 475 476 p2p_subelems = wpabuf_alloc(500); 477 if (p2p_subelems == NULL) 478 return NULL; 479 480 p2p_group_add_common_ies(group, p2p_subelems); 481 p2p_group_add_noa(p2p_subelems, group->noa); 482 483 /* P2P Device Info */ 484 p2p_buf_add_device_info(p2p_subelems, group->p2p, NULL); 485 486 /* P2P Group Info: Only when at least one P2P Client is connected */ 487 if (group->members) 488 p2p_buf_add_group_info(group, p2p_subelems, -1); 489 490 ie = p2p_group_encaps_probe_resp(p2p_subelems); 491 wpabuf_free(p2p_subelems); 492 493 if (group->p2p->vendor_elem && 494 group->p2p->vendor_elem[VENDOR_ELEM_PROBE_RESP_P2P_GO]) { 495 struct wpabuf *extra; 496 extra = wpabuf_dup(group->p2p->vendor_elem[VENDOR_ELEM_PROBE_RESP_P2P_GO]); 497 ie = wpabuf_concat(extra, ie); 498 } 499 500 #ifdef CONFIG_WIFI_DISPLAY 501 if (group->wfd_ie) { 502 struct wpabuf *wfd = wpabuf_dup(group->wfd_ie); 503 ie = wpabuf_concat(wfd, ie); 504 } 505 #endif /* CONFIG_WIFI_DISPLAY */ 506 if (group->cfg->p2p2) { 507 p2p2_ie = wpabuf_alloc(255); 508 if (!p2p2_ie) { 509 wpabuf_free(ie); 510 return NULL; 511 } 512 513 p2p_group_build_p2p2_ie(group->p2p, p2p2_ie, group->cfg->freq); 514 ie = wpabuf_concat(p2p2_ie, ie); 515 } 516 return ie; 517 } 518 519 p2p_group_update_ies(struct p2p_group * group)520 void p2p_group_update_ies(struct p2p_group *group) 521 { 522 struct wpabuf *beacon_ie; 523 struct wpabuf *probe_resp_ie; 524 525 #ifdef CONFIG_WIFI_DISPLAY 526 wifi_display_group_update(group); 527 #endif /* CONFIG_WIFI_DISPLAY */ 528 529 probe_resp_ie = p2p_group_build_probe_resp_ie(group); 530 if (probe_resp_ie == NULL) 531 return; 532 wpa_hexdump_buf(MSG_MSGDUMP, "P2P: Update GO Probe Response P2P IE", 533 probe_resp_ie); 534 535 if (group->beacon_update) { 536 beacon_ie = p2p_group_build_beacon_ie(group); 537 if (beacon_ie) 538 group->beacon_update = 0; 539 wpa_hexdump_buf(MSG_MSGDUMP, "P2P: Update GO Beacon P2P IE", 540 beacon_ie); 541 } else 542 beacon_ie = NULL; 543 544 group->cfg->ie_update(group->cfg->cb_ctx, beacon_ie, probe_resp_ie); 545 } 546 547 548 /** 549 * p2p_build_client_info - Build P2P Client Info Descriptor 550 * @addr: MAC address of the peer device 551 * @p2p_ie: P2P IE from (Re)Association Request 552 * @dev_capab: Buffer for returning Device Capability 553 * @dev_addr: Buffer for returning P2P Device Address 554 * Returns: P2P Client Info Descriptor or %NULL on failure 555 * 556 * This function builds P2P Client Info Descriptor based on the information 557 * available from (Re)Association Request frame. Group owner can use this to 558 * build the P2P Group Info attribute for Probe Response frames. 559 */ p2p_build_client_info(const u8 * addr,struct wpabuf * p2p_ie,u8 * dev_capab,u8 * dev_addr)560 static struct wpabuf * p2p_build_client_info(const u8 *addr, 561 struct wpabuf *p2p_ie, 562 u8 *dev_capab, u8 *dev_addr) 563 { 564 const u8 *spos; 565 struct p2p_message msg; 566 u8 *len_pos; 567 struct wpabuf *buf; 568 569 if (p2p_ie == NULL) 570 return NULL; 571 572 os_memset(&msg, 0, sizeof(msg)); 573 if (p2p_parse_p2p_ie(p2p_ie, &msg) || 574 msg.capability == NULL || msg.p2p_device_info == NULL) 575 return NULL; 576 577 buf = wpabuf_alloc(ETH_ALEN + 1 + 1 + msg.p2p_device_info_len); 578 if (buf == NULL) 579 return NULL; 580 581 *dev_capab = msg.capability[0]; 582 os_memcpy(dev_addr, msg.p2p_device_addr, ETH_ALEN); 583 584 spos = msg.p2p_device_info; /* P2P Device address */ 585 586 /* P2P Client Info Descriptor */ 587 /* Length to be set */ 588 len_pos = wpabuf_put(buf, 1); 589 /* P2P Device address */ 590 wpabuf_put_data(buf, spos, ETH_ALEN); 591 /* P2P Interface address */ 592 wpabuf_put_data(buf, addr, ETH_ALEN); 593 /* Device Capability Bitmap */ 594 wpabuf_put_u8(buf, msg.capability[0]); 595 /* 596 * Config Methods, Primary Device Type, Number of Secondary Device 597 * Types, Secondary Device Type List, Device Name copied from 598 * Device Info 599 */ 600 wpabuf_put_data(buf, spos + ETH_ALEN, 601 msg.p2p_device_info_len - ETH_ALEN); 602 603 *len_pos = wpabuf_len(buf) - 1; 604 605 606 return buf; 607 } 608 609 p2p_group_remove_member(struct p2p_group * group,const u8 * addr)610 static int p2p_group_remove_member(struct p2p_group *group, const u8 *addr) 611 { 612 struct p2p_group_member *m, *prev; 613 614 if (group == NULL) 615 return 0; 616 617 m = group->members; 618 prev = NULL; 619 while (m) { 620 if (ether_addr_equal(m->addr, addr)) 621 break; 622 prev = m; 623 m = m->next; 624 } 625 626 if (m == NULL) 627 return 0; 628 629 if (prev) 630 prev->next = m->next; 631 else 632 group->members = m->next; 633 p2p_group_free_member(m); 634 group->num_members--; 635 636 return 1; 637 } 638 639 p2p_group_notif_assoc(struct p2p_group * group,const u8 * addr,const u8 * ie,size_t len)640 int p2p_group_notif_assoc(struct p2p_group *group, const u8 *addr, 641 const u8 *ie, size_t len) 642 { 643 struct p2p_group_member *m; 644 645 if (group == NULL) 646 return -1; 647 648 p2p_add_device(group->p2p, addr, 0, NULL, 0, ie, len, 0); 649 650 m = os_zalloc(sizeof(*m)); 651 if (m == NULL) 652 return -1; 653 os_memcpy(m->addr, addr, ETH_ALEN); 654 m->p2p_ie = ieee802_11_vendor_ie_concat(ie, len, P2P_IE_VENDOR_TYPE); 655 if (m->p2p_ie) { 656 m->client_info = p2p_build_client_info(addr, m->p2p_ie, 657 &m->dev_capab, 658 m->dev_addr); 659 } 660 #ifdef CONFIG_WIFI_DISPLAY 661 m->wfd_ie = ieee802_11_vendor_ie_concat(ie, len, WFD_IE_VENDOR_TYPE); 662 #endif /* CONFIG_WIFI_DISPLAY */ 663 664 p2p_group_remove_member(group, addr); 665 666 m->next = group->members; 667 group->members = m; 668 group->num_members++; 669 p2p_dbg(group->p2p, "Add client " MACSTR 670 " to group (p2p=%d wfd=%d client_info=%d); num_members=%u/%u", 671 MAC2STR(addr), m->p2p_ie ? 1 : 0, m->wfd_ie ? 1 : 0, 672 m->client_info ? 1 : 0, 673 group->num_members, group->cfg->max_clients); 674 if (group->num_members == group->cfg->max_clients) 675 group->beacon_update = 1; 676 p2p_group_update_ies(group); 677 if (group->num_members == 1) 678 group->cfg->idle_update(group->cfg->cb_ctx, 0); 679 680 return 0; 681 } 682 683 p2p_group_assoc_resp_ie(struct p2p_group * group,u8 status)684 struct wpabuf * p2p_group_assoc_resp_ie(struct p2p_group *group, u8 status) 685 { 686 struct wpabuf *resp; 687 u8 *rlen; 688 size_t extra = 0; 689 struct wpabuf *p2p2_ie; 690 691 #ifdef CONFIG_WIFI_DISPLAY 692 if (group->wfd_ie) 693 extra = wpabuf_len(group->wfd_ie); 694 #endif /* CONFIG_WIFI_DISPLAY */ 695 696 if (group->p2p->vendor_elem && 697 group->p2p->vendor_elem[VENDOR_ELEM_P2P_ASSOC_RESP]) 698 extra += wpabuf_len(group->p2p->vendor_elem[VENDOR_ELEM_P2P_ASSOC_RESP]); 699 700 /* 701 * (Re)Association Response - P2P IE 702 * Status attribute (shall be present when association request is 703 * denied) 704 * Extended Listen Timing (may be present) 705 */ 706 resp = wpabuf_alloc(20 + extra); 707 if (resp == NULL) 708 return NULL; 709 710 #ifdef CONFIG_WIFI_DISPLAY 711 if (group->wfd_ie) 712 wpabuf_put_buf(resp, group->wfd_ie); 713 #endif /* CONFIG_WIFI_DISPLAY */ 714 715 if (group->p2p->vendor_elem && 716 group->p2p->vendor_elem[VENDOR_ELEM_P2P_ASSOC_RESP]) 717 wpabuf_put_buf(resp, 718 group->p2p->vendor_elem[VENDOR_ELEM_P2P_ASSOC_RESP]); 719 720 rlen = p2p_buf_add_ie_hdr(resp); 721 if (status != P2P_SC_SUCCESS) 722 p2p_buf_add_status(resp, status); 723 p2p_buf_update_ie_hdr(resp, rlen); 724 725 if (group->cfg->p2p2) { 726 p2p2_ie = wpabuf_alloc(255); 727 if (!p2p2_ie) { 728 wpabuf_free(resp); 729 return NULL; 730 } 731 732 p2p_group_build_p2p2_ie(group->p2p, p2p2_ie, group->cfg->freq); 733 resp = wpabuf_concat(p2p2_ie, resp); 734 } 735 736 return resp; 737 } 738 739 p2p_group_notif_disassoc(struct p2p_group * group,const u8 * addr)740 void p2p_group_notif_disassoc(struct p2p_group *group, const u8 *addr) 741 { 742 if (p2p_group_remove_member(group, addr)) { 743 p2p_dbg(group->p2p, "Remove client " MACSTR 744 " from group; num_members=%u/%u", 745 MAC2STR(addr), group->num_members, 746 group->cfg->max_clients); 747 if (group->num_members == group->cfg->max_clients - 1) 748 group->beacon_update = 1; 749 p2p_group_update_ies(group); 750 if (group->num_members == 0) 751 group->cfg->idle_update(group->cfg->cb_ctx, 1); 752 } 753 } 754 755 756 /** 757 * p2p_match_dev_type_member - Match client device type with requested type 758 * @m: Group member 759 * @wps: WPS TLVs from Probe Request frame (concatenated WPS IEs) 760 * Returns: 1 on match, 0 on mismatch 761 * 762 * This function can be used to match the Requested Device Type attribute in 763 * WPS IE with the device types of a group member for deciding whether a GO 764 * should reply to a Probe Request frame. 765 */ p2p_match_dev_type_member(struct p2p_group_member * m,struct wpabuf * wps)766 static int p2p_match_dev_type_member(struct p2p_group_member *m, 767 struct wpabuf *wps) 768 { 769 const u8 *pos, *end; 770 struct wps_parse_attr attr; 771 u8 num_sec; 772 773 if (m->client_info == NULL || wps == NULL) 774 return 0; 775 776 pos = wpabuf_head(m->client_info); 777 end = pos + wpabuf_len(m->client_info); 778 779 pos += 1 + 2 * ETH_ALEN + 1 + 2; 780 if (end - pos < WPS_DEV_TYPE_LEN + 1) 781 return 0; 782 783 if (wps_parse_msg(wps, &attr)) 784 return 1; /* assume no Requested Device Type attributes */ 785 786 if (attr.num_req_dev_type == 0) 787 return 1; /* no Requested Device Type attributes -> match */ 788 789 if (dev_type_list_match(pos, attr.req_dev_type, attr.num_req_dev_type)) 790 return 1; /* Match with client Primary Device Type */ 791 792 pos += WPS_DEV_TYPE_LEN; 793 num_sec = *pos++; 794 if (end - pos < num_sec * WPS_DEV_TYPE_LEN) 795 return 0; 796 while (num_sec > 0) { 797 num_sec--; 798 if (dev_type_list_match(pos, attr.req_dev_type, 799 attr.num_req_dev_type)) 800 return 1; /* Match with client Secondary Device Type */ 801 pos += WPS_DEV_TYPE_LEN; 802 } 803 804 /* No matching device type found */ 805 return 0; 806 } 807 808 p2p_group_match_dev_type(struct p2p_group * group,struct wpabuf * wps)809 int p2p_group_match_dev_type(struct p2p_group *group, struct wpabuf *wps) 810 { 811 struct p2p_group_member *m; 812 813 if (p2p_match_dev_type(group->p2p, wps)) 814 return 1; /* Match with own device type */ 815 816 for (m = group->members; m; m = m->next) { 817 if (p2p_match_dev_type_member(m, wps)) 818 return 1; /* Match with group client device type */ 819 } 820 821 /* No match with Requested Device Type */ 822 return 0; 823 } 824 825 p2p_group_match_dev_id(struct p2p_group * group,struct wpabuf * p2p)826 int p2p_group_match_dev_id(struct p2p_group *group, struct wpabuf *p2p) 827 { 828 struct p2p_group_member *m; 829 struct p2p_message msg; 830 831 os_memset(&msg, 0, sizeof(msg)); 832 if (p2p_parse_p2p_ie(p2p, &msg)) 833 return 1; /* Failed to parse - assume no filter on Device ID */ 834 835 if (!msg.device_id) 836 return 1; /* No filter on Device ID */ 837 838 if (ether_addr_equal(msg.device_id, group->p2p->cfg->dev_addr)) 839 return 1; /* Match with our P2P Device Address */ 840 841 for (m = group->members; m; m = m->next) { 842 if (ether_addr_equal(msg.device_id, m->dev_addr)) 843 return 1; /* Match with group client P2P Device Address */ 844 } 845 846 /* No match with Device ID */ 847 return 0; 848 } 849 850 p2p_group_notif_formation_done(struct p2p_group * group)851 void p2p_group_notif_formation_done(struct p2p_group *group) 852 { 853 if (group == NULL) 854 return; 855 group->group_formation = 0; 856 group->beacon_update = 1; 857 p2p_group_update_ies(group); 858 } 859 860 p2p_group_notif_noa(struct p2p_group * group,const u8 * noa,size_t noa_len)861 int p2p_group_notif_noa(struct p2p_group *group, const u8 *noa, 862 size_t noa_len) 863 { 864 if (noa == NULL) { 865 wpabuf_free(group->noa); 866 group->noa = NULL; 867 } else { 868 if (group->noa) { 869 if (wpabuf_size(group->noa) >= noa_len) { 870 group->noa->used = 0; 871 wpabuf_put_data(group->noa, noa, noa_len); 872 } else { 873 wpabuf_free(group->noa); 874 group->noa = NULL; 875 } 876 } 877 878 if (!group->noa) { 879 group->noa = wpabuf_alloc_copy(noa, noa_len); 880 if (group->noa == NULL) 881 return -1; 882 } 883 } 884 885 group->beacon_update = 1; 886 p2p_group_update_ies(group); 887 return 0; 888 } 889 890 p2p_group_get_client(struct p2p_group * group,const u8 * dev_id)891 static struct p2p_group_member * p2p_group_get_client(struct p2p_group *group, 892 const u8 *dev_id) 893 { 894 struct p2p_group_member *m; 895 896 for (m = group->members; m; m = m->next) { 897 if (ether_addr_equal(dev_id, m->dev_addr)) 898 return m; 899 } 900 901 return NULL; 902 } 903 904 p2p_group_get_client_interface_addr(struct p2p_group * group,const u8 * dev_addr)905 const u8 * p2p_group_get_client_interface_addr(struct p2p_group *group, 906 const u8 *dev_addr) 907 { 908 struct p2p_group_member *m; 909 910 if (!group) 911 return NULL; 912 m = p2p_group_get_client(group, dev_addr); 913 if (m) 914 return m->addr; 915 return NULL; 916 } 917 918 p2p_group_get_client_iface(struct p2p_group * group,const u8 * interface_addr)919 static struct p2p_group_member * p2p_group_get_client_iface( 920 struct p2p_group *group, const u8 *interface_addr) 921 { 922 struct p2p_group_member *m; 923 924 for (m = group->members; m; m = m->next) { 925 if (ether_addr_equal(interface_addr, m->addr)) 926 return m; 927 } 928 929 return NULL; 930 } 931 932 p2p_group_get_dev_addr(struct p2p_group * group,const u8 * addr)933 const u8 * p2p_group_get_dev_addr(struct p2p_group *group, const u8 *addr) 934 { 935 struct p2p_group_member *m; 936 937 if (group == NULL) 938 return NULL; 939 m = p2p_group_get_client_iface(group, addr); 940 if (m && !is_zero_ether_addr(m->dev_addr)) 941 return m->dev_addr; 942 return NULL; 943 } 944 945 p2p_build_go_disc_req(void)946 static struct wpabuf * p2p_build_go_disc_req(void) 947 { 948 struct wpabuf *buf; 949 950 buf = wpabuf_alloc(100); 951 if (buf == NULL) 952 return NULL; 953 954 p2p_buf_add_action_hdr(buf, P2P_GO_DISC_REQ, 0); 955 956 return buf; 957 } 958 959 p2p_group_go_discover(struct p2p_group * group,const u8 * dev_id,const u8 * searching_dev,int rx_freq)960 int p2p_group_go_discover(struct p2p_group *group, const u8 *dev_id, 961 const u8 *searching_dev, int rx_freq) 962 { 963 struct p2p_group_member *m; 964 struct wpabuf *req; 965 struct p2p_data *p2p = group->p2p; 966 int freq; 967 968 m = p2p_group_get_client(group, dev_id); 969 if (m == NULL || m->client_info == NULL) { 970 p2p_dbg(group->p2p, "Requested client was not in this group " 971 MACSTR, MAC2STR(group->cfg->interface_addr)); 972 return -1; 973 } 974 975 if (!(m->dev_capab & P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY)) { 976 p2p_dbg(group->p2p, "Requested client does not support client discoverability"); 977 return -1; 978 } 979 980 p2p_dbg(group->p2p, "Schedule GO Discoverability Request to be sent to " 981 MACSTR, MAC2STR(dev_id)); 982 983 req = p2p_build_go_disc_req(); 984 if (req == NULL) 985 return -1; 986 987 /* TODO: Should really use group operating frequency here */ 988 freq = rx_freq; 989 990 p2p->pending_action_state = P2P_PENDING_GO_DISC_REQ; 991 if (p2p->cfg->send_action(p2p->cfg->cb_ctx, freq, m->addr, 992 group->cfg->interface_addr, 993 group->cfg->interface_addr, 994 wpabuf_head(req), wpabuf_len(req), 200, NULL) 995 < 0) 996 { 997 p2p_dbg(p2p, "Failed to send Action frame"); 998 } 999 1000 wpabuf_free(req); 1001 1002 return 0; 1003 } 1004 1005 p2p_group_get_interface_addr(struct p2p_group * group)1006 const u8 * p2p_group_get_interface_addr(struct p2p_group *group) 1007 { 1008 return group->cfg->interface_addr; 1009 } 1010 1011 p2p_group_presence_req(struct p2p_group * group,const u8 * client_interface_addr,const u8 * noa,size_t noa_len)1012 u8 p2p_group_presence_req(struct p2p_group *group, 1013 const u8 *client_interface_addr, 1014 const u8 *noa, size_t noa_len) 1015 { 1016 struct p2p_group_member *m; 1017 u8 curr_noa[50]; 1018 int curr_noa_len; 1019 1020 m = p2p_group_get_client_iface(group, client_interface_addr); 1021 if (m == NULL || m->client_info == NULL) { 1022 p2p_dbg(group->p2p, "Client was not in this group"); 1023 return P2P_SC_FAIL_UNABLE_TO_ACCOMMODATE; 1024 } 1025 1026 wpa_hexdump(MSG_DEBUG, "P2P: Presence Request NoA", noa, noa_len); 1027 1028 if (group->p2p->cfg->get_noa) 1029 curr_noa_len = group->p2p->cfg->get_noa( 1030 group->p2p->cfg->cb_ctx, group->cfg->interface_addr, 1031 curr_noa, sizeof(curr_noa)); 1032 else 1033 curr_noa_len = -1; 1034 if (curr_noa_len < 0) 1035 p2p_dbg(group->p2p, "Failed to fetch current NoA"); 1036 else if (curr_noa_len == 0) 1037 p2p_dbg(group->p2p, "No NoA being advertized"); 1038 else 1039 wpa_hexdump(MSG_DEBUG, "P2P: Current NoA", curr_noa, 1040 curr_noa_len); 1041 1042 /* TODO: properly process request and store copy */ 1043 if (curr_noa_len > 0 || curr_noa_len == -1) 1044 return P2P_SC_FAIL_UNABLE_TO_ACCOMMODATE; 1045 1046 return P2P_SC_SUCCESS; 1047 } 1048 1049 p2p_get_group_num_members(struct p2p_group * group)1050 unsigned int p2p_get_group_num_members(struct p2p_group *group) 1051 { 1052 if (!group) 1053 return 0; 1054 1055 return group->num_members; 1056 } 1057 1058 p2p_client_limit_reached(struct p2p_group * group)1059 int p2p_client_limit_reached(struct p2p_group *group) 1060 { 1061 if (!group || !group->cfg) 1062 return 1; 1063 1064 return group->num_members >= group->cfg->max_clients; 1065 } 1066 1067 p2p_iterate_group_members(struct p2p_group * group,void ** next)1068 const u8 * p2p_iterate_group_members(struct p2p_group *group, void **next) 1069 { 1070 struct p2p_group_member *iter = *next; 1071 1072 if (!iter) 1073 iter = group->members; 1074 else 1075 iter = iter->next; 1076 1077 *next = iter; 1078 1079 if (!iter) 1080 return NULL; 1081 1082 return iter->dev_addr; 1083 } 1084 1085 p2p_group_is_client_connected(struct p2p_group * group,const u8 * dev_addr)1086 int p2p_group_is_client_connected(struct p2p_group *group, const u8 *dev_addr) 1087 { 1088 struct p2p_group_member *m; 1089 1090 for (m = group->members; m; m = m->next) { 1091 if (ether_addr_equal(m->dev_addr, dev_addr)) 1092 return 1; 1093 } 1094 1095 return 0; 1096 } 1097 1098 p2p_group_is_group_id_match(struct p2p_group * group,const u8 * group_id,size_t group_id_len)1099 int p2p_group_is_group_id_match(struct p2p_group *group, const u8 *group_id, 1100 size_t group_id_len) 1101 { 1102 if (group_id_len != ETH_ALEN + group->cfg->ssid_len) 1103 return 0; 1104 if (!ether_addr_equal(group_id, group->p2p->cfg->dev_addr)) 1105 return 0; 1106 return os_memcmp(group_id + ETH_ALEN, group->cfg->ssid, 1107 group->cfg->ssid_len) == 0; 1108 } 1109 1110 p2p_group_force_beacon_update_ies(struct p2p_group * group)1111 void p2p_group_force_beacon_update_ies(struct p2p_group *group) 1112 { 1113 group->beacon_update = 1; 1114 p2p_group_update_ies(group); 1115 } 1116 1117 p2p_group_get_freq(struct p2p_group * group)1118 int p2p_group_get_freq(struct p2p_group *group) 1119 { 1120 return group->cfg->freq; 1121 } 1122 1123 p2p_group_get_config(struct p2p_group * group)1124 const struct p2p_group_config * p2p_group_get_config(struct p2p_group *group) 1125 { 1126 return group->cfg; 1127 } 1128 1129 p2p_loop_on_all_groups(struct p2p_data * p2p,int (* group_callback)(struct p2p_group * group,void * user_data),void * user_data)1130 void p2p_loop_on_all_groups(struct p2p_data *p2p, 1131 int (*group_callback)(struct p2p_group *group, 1132 void *user_data), 1133 void *user_data) 1134 { 1135 unsigned int i; 1136 1137 for (i = 0; i < p2p->num_groups; i++) { 1138 if (!group_callback(p2p->groups[i], user_data)) 1139 break; 1140 } 1141 } 1142 1143 p2p_group_get_common_freqs(struct p2p_group * group,int * common_freqs,unsigned int * num)1144 int p2p_group_get_common_freqs(struct p2p_group *group, int *common_freqs, 1145 unsigned int *num) 1146 1147 { 1148 struct p2p_channels intersect, res; 1149 struct p2p_group_member *m; 1150 1151 if (!group || !common_freqs || !num) 1152 return -1; 1153 1154 os_memset(&intersect, 0, sizeof(intersect)); 1155 os_memset(&res, 0, sizeof(res)); 1156 1157 p2p_channels_union(&intersect, &group->p2p->cfg->channels, 1158 &intersect); 1159 1160 p2p_channels_dump(group->p2p, 1161 "Group common freqs before iterating members", 1162 &intersect); 1163 1164 for (m = group->members; m; m = m->next) { 1165 struct p2p_device *dev; 1166 1167 dev = p2p_get_device(group->p2p, m->dev_addr); 1168 if (!dev || dev->channels.reg_classes == 0) 1169 continue; 1170 1171 p2p_channels_intersect(&intersect, &dev->channels, &res); 1172 intersect = res; 1173 } 1174 1175 p2p_channels_dump(group->p2p, "Group common channels", &intersect); 1176 1177 os_memset(common_freqs, 0, *num * sizeof(int)); 1178 *num = p2p_channels_to_freqs(&intersect, common_freqs, *num); 1179 1180 return 0; 1181 } 1182