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