1 /* 2 * WPA Supplicant - Scanning 3 * Copyright (c) 2003-2010, Jouni Malinen <j (at) w1.fi> 4 * 5 * This software may be distributed under the terms of the BSD license. 6 * See README for more details. 7 */ 8 9 #include "utils/includes.h" 10 11 #include "utils/common.h" 12 #include "utils/eloop.h" 13 #include "common/ieee802_11_defs.h" 14 #include "config.h" 15 #include "wpa_supplicant_i.h" 16 #include "driver_i.h" 17 #include "wps_supplicant.h" 18 #include "p2p_supplicant.h" 19 #include "p2p/p2p.h" 20 #include "hs20_supplicant.h" 21 #include "notify.h" 22 #include "bss.h" 23 #include "scan.h" 24 25 26 static void wpa_supplicant_gen_assoc_event(struct wpa_supplicant *wpa_s) 27 { 28 struct wpa_ssid *ssid; 29 union wpa_event_data data; 30 31 ssid = wpa_supplicant_get_ssid(wpa_s); 32 if (ssid == NULL) 33 return; 34 35 if (wpa_s->current_ssid == NULL) { 36 wpa_s->current_ssid = ssid; 37 if (wpa_s->current_ssid != NULL) 38 wpas_notify_network_changed(wpa_s); 39 } 40 wpa_supplicant_initiate_eapol(wpa_s); 41 wpa_dbg(wpa_s, MSG_DEBUG, "Already associated with a configured " 42 "network - generating associated event"); 43 os_memset(&data, 0, sizeof(data)); 44 wpa_supplicant_event(wpa_s, EVENT_ASSOC, &data); 45 } 46 47 48 #ifdef CONFIG_WPS 49 static int wpas_wps_in_use(struct wpa_supplicant *wpa_s, 50 enum wps_request_type *req_type) 51 { 52 struct wpa_ssid *ssid; 53 int wps = 0; 54 55 for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) { 56 if (!(ssid->key_mgmt & WPA_KEY_MGMT_WPS)) 57 continue; 58 59 wps = 1; 60 *req_type = wpas_wps_get_req_type(ssid); 61 if (!ssid->eap.phase1) 62 continue; 63 64 if (os_strstr(ssid->eap.phase1, "pbc=1")) 65 return 2; 66 } 67 68 #ifdef CONFIG_P2P 69 if (!wpa_s->global->p2p_disabled && wpa_s->global->p2p) { 70 wpa_s->wps->dev.p2p = 1; 71 if (!wps) { 72 wps = 1; 73 *req_type = WPS_REQ_ENROLLEE_INFO; 74 } 75 } 76 #endif /* CONFIG_P2P */ 77 78 return wps; 79 } 80 #endif /* CONFIG_WPS */ 81 82 83 int wpa_supplicant_enabled_networks(struct wpa_supplicant *wpa_s) 84 { 85 struct wpa_ssid *ssid = wpa_s->conf->ssid; 86 int count = 0, disabled = 0; 87 while (ssid) { 88 if (!wpas_network_disabled(wpa_s, ssid)) 89 count++; 90 else 91 disabled++; 92 ssid = ssid->next; 93 } 94 if (wpa_s->conf->cred && wpa_s->conf->interworking && 95 wpa_s->conf->auto_interworking) 96 count++; 97 if (count == 0 && disabled > 0) { 98 wpa_dbg(wpa_s, MSG_DEBUG, "No enabled networks (%d disabled " 99 "networks)", disabled); 100 } 101 return count; 102 } 103 104 105 static void wpa_supplicant_assoc_try(struct wpa_supplicant *wpa_s, 106 struct wpa_ssid *ssid) 107 { 108 while (ssid) { 109 if (!wpas_network_disabled(wpa_s, ssid)) 110 break; 111 ssid = ssid->next; 112 } 113 114 /* ap_scan=2 mode - try to associate with each SSID. */ 115 if (ssid == NULL) { 116 wpa_dbg(wpa_s, MSG_DEBUG, "wpa_supplicant_assoc_try: Reached " 117 "end of scan list - go back to beginning"); 118 wpa_s->prev_scan_ssid = WILDCARD_SSID_SCAN; 119 wpa_supplicant_req_scan(wpa_s, 0, 0); 120 return; 121 } 122 if (ssid->next) { 123 /* Continue from the next SSID on the next attempt. */ 124 wpa_s->prev_scan_ssid = ssid; 125 } else { 126 /* Start from the beginning of the SSID list. */ 127 wpa_s->prev_scan_ssid = WILDCARD_SSID_SCAN; 128 } 129 wpa_supplicant_associate(wpa_s, NULL, ssid); 130 } 131 132 133 static int int_array_len(const int *a) 134 { 135 int i; 136 for (i = 0; a && a[i]; i++) 137 ; 138 return i; 139 } 140 141 142 static void int_array_concat(int **res, const int *a) 143 { 144 int reslen, alen, i; 145 int *n; 146 147 reslen = int_array_len(*res); 148 alen = int_array_len(a); 149 150 n = os_realloc_array(*res, reslen + alen + 1, sizeof(int)); 151 if (n == NULL) { 152 os_free(*res); 153 *res = NULL; 154 return; 155 } 156 for (i = 0; i <= alen; i++) 157 n[reslen + i] = a[i]; 158 *res = n; 159 } 160 161 162 static int freq_cmp(const void *a, const void *b) 163 { 164 int _a = *(int *) a; 165 int _b = *(int *) b; 166 167 if (_a == 0) 168 return 1; 169 if (_b == 0) 170 return -1; 171 return _a - _b; 172 } 173 174 175 static void int_array_sort_unique(int *a) 176 { 177 int alen; 178 int i, j; 179 180 if (a == NULL) 181 return; 182 183 alen = int_array_len(a); 184 qsort(a, alen, sizeof(int), freq_cmp); 185 186 i = 0; 187 j = 1; 188 while (a[i] && a[j]) { 189 if (a[i] == a[j]) { 190 j++; 191 continue; 192 } 193 a[++i] = a[j++]; 194 } 195 if (a[i]) 196 i++; 197 a[i] = 0; 198 } 199 200 201 int wpa_supplicant_trigger_scan(struct wpa_supplicant *wpa_s, 202 struct wpa_driver_scan_params *params) 203 { 204 int ret; 205 206 wpa_supplicant_notify_scanning(wpa_s, 1); 207 208 ret = wpa_drv_scan(wpa_s, params); 209 if (ret) { 210 wpa_supplicant_notify_scanning(wpa_s, 0); 211 wpas_notify_scan_done(wpa_s, 0); 212 } else { 213 wpa_s->scan_runs++; 214 wpa_s->normal_scans++; 215 } 216 217 return ret; 218 } 219 220 221 static void 222 wpa_supplicant_delayed_sched_scan_timeout(void *eloop_ctx, void *timeout_ctx) 223 { 224 struct wpa_supplicant *wpa_s = eloop_ctx; 225 226 wpa_dbg(wpa_s, MSG_DEBUG, "Starting delayed sched scan"); 227 228 if (wpa_supplicant_req_sched_scan(wpa_s)) 229 wpa_supplicant_req_scan(wpa_s, 0, 0); 230 } 231 232 233 static void 234 wpa_supplicant_sched_scan_timeout(void *eloop_ctx, void *timeout_ctx) 235 { 236 struct wpa_supplicant *wpa_s = eloop_ctx; 237 238 wpa_dbg(wpa_s, MSG_DEBUG, "Sched scan timeout - stopping it"); 239 240 wpa_s->sched_scan_timed_out = 1; 241 wpa_supplicant_cancel_sched_scan(wpa_s); 242 } 243 244 245 static int 246 wpa_supplicant_start_sched_scan(struct wpa_supplicant *wpa_s, 247 struct wpa_driver_scan_params *params, 248 int interval) 249 { 250 int ret; 251 #ifndef ANDROID_P2P 252 wpa_supplicant_notify_scanning(wpa_s, 1); 253 #endif 254 ret = wpa_drv_sched_scan(wpa_s, params, interval * 1000); 255 if (ret) 256 wpa_supplicant_notify_scanning(wpa_s, 0); 257 else { 258 wpa_s->sched_scanning = 1; 259 #ifdef ANDROID_P2P 260 wpa_supplicant_notify_scanning(wpa_s, 1); 261 #endif 262 } 263 264 return ret; 265 } 266 267 268 static int wpa_supplicant_stop_sched_scan(struct wpa_supplicant *wpa_s) 269 { 270 int ret; 271 272 ret = wpa_drv_stop_sched_scan(wpa_s); 273 if (ret) { 274 wpa_dbg(wpa_s, MSG_DEBUG, "stopping sched_scan failed!"); 275 /* TODO: what to do if stopping fails? */ 276 return -1; 277 } 278 279 return ret; 280 } 281 282 283 static struct wpa_driver_scan_filter * 284 wpa_supplicant_build_filter_ssids(struct wpa_config *conf, size_t *num_ssids) 285 { 286 struct wpa_driver_scan_filter *ssids; 287 struct wpa_ssid *ssid; 288 size_t count; 289 290 *num_ssids = 0; 291 if (!conf->filter_ssids) 292 return NULL; 293 294 for (count = 0, ssid = conf->ssid; ssid; ssid = ssid->next) { 295 if (ssid->ssid && ssid->ssid_len) 296 count++; 297 } 298 if (count == 0) 299 return NULL; 300 ssids = os_zalloc(count * sizeof(struct wpa_driver_scan_filter)); 301 if (ssids == NULL) 302 return NULL; 303 304 for (ssid = conf->ssid; ssid; ssid = ssid->next) { 305 if (!ssid->ssid || !ssid->ssid_len) 306 continue; 307 os_memcpy(ssids[*num_ssids].ssid, ssid->ssid, ssid->ssid_len); 308 ssids[*num_ssids].ssid_len = ssid->ssid_len; 309 (*num_ssids)++; 310 } 311 312 return ssids; 313 } 314 315 316 static void wpa_supplicant_optimize_freqs( 317 struct wpa_supplicant *wpa_s, struct wpa_driver_scan_params *params) 318 { 319 #ifdef CONFIG_P2P 320 if (params->freqs == NULL && wpa_s->p2p_in_provisioning && 321 wpa_s->go_params) { 322 /* Optimize provisioning state scan based on GO information */ 323 if (wpa_s->p2p_in_provisioning < 5 && 324 wpa_s->go_params->freq > 0) { 325 wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Scan only GO " 326 "preferred frequency %d MHz", 327 wpa_s->go_params->freq); 328 params->freqs = os_zalloc(2 * sizeof(int)); 329 if (params->freqs) 330 params->freqs[0] = wpa_s->go_params->freq; 331 } else if (wpa_s->p2p_in_provisioning < 8 && 332 wpa_s->go_params->freq_list[0]) { 333 wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Scan only common " 334 "channels"); 335 int_array_concat(¶ms->freqs, 336 wpa_s->go_params->freq_list); 337 if (params->freqs) 338 int_array_sort_unique(params->freqs); 339 } 340 wpa_s->p2p_in_provisioning++; 341 } 342 #endif /* CONFIG_P2P */ 343 344 #ifdef CONFIG_WPS 345 if (params->freqs == NULL && wpa_s->after_wps && wpa_s->wps_freq) { 346 /* 347 * Optimize post-provisioning scan based on channel used 348 * during provisioning. 349 */ 350 wpa_dbg(wpa_s, MSG_DEBUG, "WPS: Scan only frequency %u MHz " 351 "that was used during provisioning", wpa_s->wps_freq); 352 params->freqs = os_zalloc(2 * sizeof(int)); 353 if (params->freqs) 354 params->freqs[0] = wpa_s->wps_freq; 355 wpa_s->after_wps--; 356 } 357 358 if (params->freqs == NULL && wpa_s->known_wps_freq && wpa_s->wps_freq) 359 { 360 /* Optimize provisioning scan based on already known channel */ 361 wpa_dbg(wpa_s, MSG_DEBUG, "WPS: Scan only frequency %u MHz", 362 wpa_s->wps_freq); 363 params->freqs = os_zalloc(2 * sizeof(int)); 364 if (params->freqs) 365 params->freqs[0] = wpa_s->wps_freq; 366 wpa_s->known_wps_freq = 0; /* only do this once */ 367 } 368 #endif /* CONFIG_WPS */ 369 } 370 371 372 #ifdef CONFIG_INTERWORKING 373 static void wpas_add_interworking_elements(struct wpa_supplicant *wpa_s, 374 struct wpabuf *buf) 375 { 376 if (wpa_s->conf->interworking == 0) 377 return; 378 379 wpabuf_put_u8(buf, WLAN_EID_EXT_CAPAB); 380 wpabuf_put_u8(buf, 4); 381 wpabuf_put_u8(buf, 0x00); 382 wpabuf_put_u8(buf, 0x00); 383 wpabuf_put_u8(buf, 0x00); 384 wpabuf_put_u8(buf, 0x80); /* Bit 31 - Interworking */ 385 386 wpabuf_put_u8(buf, WLAN_EID_INTERWORKING); 387 wpabuf_put_u8(buf, is_zero_ether_addr(wpa_s->conf->hessid) ? 1 : 388 1 + ETH_ALEN); 389 wpabuf_put_u8(buf, wpa_s->conf->access_network_type); 390 /* No Venue Info */ 391 if (!is_zero_ether_addr(wpa_s->conf->hessid)) 392 wpabuf_put_data(buf, wpa_s->conf->hessid, ETH_ALEN); 393 } 394 #endif /* CONFIG_INTERWORKING */ 395 396 397 static struct wpabuf * wpa_supplicant_extra_ies(struct wpa_supplicant *wpa_s) 398 { 399 struct wpabuf *extra_ie = NULL; 400 #ifdef CONFIG_WPS 401 int wps = 0; 402 enum wps_request_type req_type = WPS_REQ_ENROLLEE_INFO; 403 #endif /* CONFIG_WPS */ 404 405 #ifdef CONFIG_INTERWORKING 406 if (wpa_s->conf->interworking && 407 wpabuf_resize(&extra_ie, 100) == 0) 408 wpas_add_interworking_elements(wpa_s, extra_ie); 409 #endif /* CONFIG_INTERWORKING */ 410 411 #ifdef CONFIG_WPS 412 wps = wpas_wps_in_use(wpa_s, &req_type); 413 414 if (wps) { 415 struct wpabuf *wps_ie; 416 wps_ie = wps_build_probe_req_ie(wps == 2 ? DEV_PW_PUSHBUTTON : 417 DEV_PW_DEFAULT, 418 &wpa_s->wps->dev, 419 wpa_s->wps->uuid, req_type, 420 0, NULL); 421 if (wps_ie) { 422 if (wpabuf_resize(&extra_ie, wpabuf_len(wps_ie)) == 0) 423 wpabuf_put_buf(extra_ie, wps_ie); 424 wpabuf_free(wps_ie); 425 } 426 } 427 428 #ifdef CONFIG_P2P 429 if (wps) { 430 size_t ielen = p2p_scan_ie_buf_len(wpa_s->global->p2p); 431 if (wpabuf_resize(&extra_ie, ielen) == 0) 432 wpas_p2p_scan_ie(wpa_s, extra_ie); 433 } 434 #endif /* CONFIG_P2P */ 435 436 #endif /* CONFIG_WPS */ 437 438 return extra_ie; 439 } 440 441 442 static void wpa_supplicant_scan(void *eloop_ctx, void *timeout_ctx) 443 { 444 struct wpa_supplicant *wpa_s = eloop_ctx; 445 struct wpa_ssid *ssid; 446 int scan_req = 0, ret; 447 struct wpabuf *extra_ie = NULL; 448 struct wpa_driver_scan_params params; 449 struct wpa_driver_scan_params *scan_params; 450 size_t max_ssids; 451 enum wpa_states prev_state; 452 453 if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) { 454 wpa_dbg(wpa_s, MSG_DEBUG, "Skip scan - interface disabled"); 455 return; 456 } 457 458 if (wpa_s->disconnected && !wpa_s->scan_req) { 459 wpa_dbg(wpa_s, MSG_DEBUG, "Disconnected - do not scan"); 460 wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED); 461 return; 462 } 463 #ifdef ANDROID 464 if (wpa_s->scanning) { 465 /* If we are already in scanning state, we shall ignore this new scan request*/ 466 wpa_dbg(wpa_s, MSG_DEBUG, "Skip scan - already scanning"); 467 return; 468 } 469 #endif 470 if (!wpa_supplicant_enabled_networks(wpa_s) && 471 !wpa_s->scan_req) { 472 wpa_dbg(wpa_s, MSG_DEBUG, "No enabled networks - do not scan"); 473 wpa_supplicant_set_state(wpa_s, WPA_INACTIVE); 474 #ifdef CONFIG_P2P 475 wpa_s->sta_scan_pending = 0; 476 #endif /* CONFIG_P2P */ 477 return; 478 } 479 480 if (wpa_s->conf->ap_scan != 0 && 481 (wpa_s->drv_flags & WPA_DRIVER_FLAGS_WIRED)) { 482 wpa_dbg(wpa_s, MSG_DEBUG, "Using wired authentication - " 483 "overriding ap_scan configuration"); 484 wpa_s->conf->ap_scan = 0; 485 wpas_notify_ap_scan_changed(wpa_s); 486 } 487 488 if (wpa_s->conf->ap_scan == 0) { 489 wpa_supplicant_gen_assoc_event(wpa_s); 490 return; 491 } 492 493 #ifdef CONFIG_P2P 494 if (wpas_p2p_in_progress(wpa_s)) { 495 if (wpa_s->sta_scan_pending && 496 wpas_p2p_in_progress(wpa_s) == 2 && 497 wpa_s->global->p2p_cb_on_scan_complete) { 498 wpa_dbg(wpa_s, MSG_DEBUG, "Process pending station " 499 "mode scan during P2P search"); 500 } else { 501 wpa_dbg(wpa_s, MSG_DEBUG, "Delay station mode scan " 502 "while P2P operation is in progress"); 503 wpa_s->sta_scan_pending = 1; 504 wpa_supplicant_req_scan(wpa_s, 5, 0); 505 return; 506 } 507 } 508 #endif /* CONFIG_P2P */ 509 510 if (wpa_s->conf->ap_scan == 2) 511 max_ssids = 1; 512 else { 513 max_ssids = wpa_s->max_scan_ssids; 514 if (max_ssids > WPAS_MAX_SCAN_SSIDS) 515 max_ssids = WPAS_MAX_SCAN_SSIDS; 516 } 517 518 scan_req = wpa_s->scan_req; 519 wpa_s->scan_req = 0; 520 521 os_memset(¶ms, 0, sizeof(params)); 522 523 prev_state = wpa_s->wpa_state; 524 if (wpa_s->wpa_state == WPA_DISCONNECTED || 525 wpa_s->wpa_state == WPA_INACTIVE) 526 wpa_supplicant_set_state(wpa_s, WPA_SCANNING); 527 528 /* 529 * If autoscan has set its own scanning parameters 530 */ 531 if (wpa_s->autoscan_params != NULL) { 532 scan_params = wpa_s->autoscan_params; 533 goto scan; 534 } 535 536 if (scan_req != 2 && wpa_s->connect_without_scan) { 537 for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) { 538 if (ssid == wpa_s->connect_without_scan) 539 break; 540 } 541 wpa_s->connect_without_scan = NULL; 542 if (ssid) { 543 wpa_printf(MSG_DEBUG, "Start a pre-selected network " 544 "without scan step"); 545 wpa_supplicant_associate(wpa_s, NULL, ssid); 546 return; 547 } 548 } 549 550 #ifdef CONFIG_P2P 551 if ((wpa_s->p2p_in_provisioning || wpa_s->show_group_started) && 552 wpa_s->go_params) { 553 wpa_printf(MSG_DEBUG, "P2P: Use specific SSID for scan during " 554 "P2P group formation"); 555 params.ssids[0].ssid = wpa_s->go_params->ssid; 556 params.ssids[0].ssid_len = wpa_s->go_params->ssid_len; 557 params.num_ssids = 1; 558 goto ssid_list_set; 559 } 560 #endif /* CONFIG_P2P */ 561 562 /* Find the starting point from which to continue scanning */ 563 ssid = wpa_s->conf->ssid; 564 if (wpa_s->prev_scan_ssid != WILDCARD_SSID_SCAN) { 565 while (ssid) { 566 if (ssid == wpa_s->prev_scan_ssid) { 567 ssid = ssid->next; 568 break; 569 } 570 ssid = ssid->next; 571 } 572 } 573 574 if (scan_req != 2 && wpa_s->conf->ap_scan == 2) { 575 wpa_s->connect_without_scan = NULL; 576 wpa_s->prev_scan_wildcard = 0; 577 wpa_supplicant_assoc_try(wpa_s, ssid); 578 return; 579 #ifndef ANDROID 580 } else if (wpa_s->conf->ap_scan == 2) { 581 /* 582 * User-initiated scan request in ap_scan == 2; scan with 583 * wildcard SSID. 584 */ 585 ssid = NULL; 586 #endif 587 } else { 588 struct wpa_ssid *start = ssid, *tssid; 589 int freqs_set = 0; 590 if (ssid == NULL && max_ssids > 1) 591 ssid = wpa_s->conf->ssid; 592 while (ssid) { 593 if (!wpas_network_disabled(wpa_s, ssid) && 594 ssid->scan_ssid) { 595 wpa_hexdump_ascii(MSG_DEBUG, "Scan SSID", 596 ssid->ssid, ssid->ssid_len); 597 params.ssids[params.num_ssids].ssid = 598 ssid->ssid; 599 params.ssids[params.num_ssids].ssid_len = 600 ssid->ssid_len; 601 params.num_ssids++; 602 if (params.num_ssids + 1 >= max_ssids) 603 break; 604 } 605 ssid = ssid->next; 606 if (ssid == start) 607 break; 608 if (ssid == NULL && max_ssids > 1 && 609 start != wpa_s->conf->ssid) 610 ssid = wpa_s->conf->ssid; 611 } 612 613 for (tssid = wpa_s->conf->ssid; tssid; tssid = tssid->next) { 614 if (wpas_network_disabled(wpa_s, tssid)) 615 continue; 616 if ((params.freqs || !freqs_set) && tssid->scan_freq) { 617 int_array_concat(¶ms.freqs, 618 tssid->scan_freq); 619 } else { 620 os_free(params.freqs); 621 params.freqs = NULL; 622 } 623 freqs_set = 1; 624 } 625 int_array_sort_unique(params.freqs); 626 } 627 628 if (ssid && max_ssids == 1) { 629 /* 630 * If the driver is limited to 1 SSID at a time interleave 631 * wildcard SSID scans with specific SSID scans to avoid 632 * waiting a long time for a wildcard scan. 633 */ 634 if (!wpa_s->prev_scan_wildcard) { 635 params.ssids[0].ssid = NULL; 636 params.ssids[0].ssid_len = 0; 637 wpa_s->prev_scan_wildcard = 1; 638 wpa_dbg(wpa_s, MSG_DEBUG, "Starting AP scan for " 639 "wildcard SSID (Interleave with specific)"); 640 } else { 641 wpa_s->prev_scan_ssid = ssid; 642 wpa_s->prev_scan_wildcard = 0; 643 wpa_dbg(wpa_s, MSG_DEBUG, 644 "Starting AP scan for specific SSID: %s", 645 wpa_ssid_txt(ssid->ssid, ssid->ssid_len)); 646 } 647 } else if (ssid) { 648 /* max_ssids > 1 */ 649 650 wpa_s->prev_scan_ssid = ssid; 651 wpa_dbg(wpa_s, MSG_DEBUG, "Include wildcard SSID in " 652 "the scan request"); 653 params.num_ssids++; 654 } else { 655 wpa_s->prev_scan_ssid = WILDCARD_SSID_SCAN; 656 params.num_ssids++; 657 wpa_dbg(wpa_s, MSG_DEBUG, "Starting AP scan for wildcard " 658 "SSID"); 659 } 660 #ifdef CONFIG_P2P 661 ssid_list_set: 662 #endif /* CONFIG_P2P */ 663 664 wpa_supplicant_optimize_freqs(wpa_s, ¶ms); 665 extra_ie = wpa_supplicant_extra_ies(wpa_s); 666 667 #ifdef CONFIG_HS20 668 if (wpa_s->conf->hs20 && wpabuf_resize(&extra_ie, 6) == 0) 669 wpas_hs20_add_indication(extra_ie); 670 #endif /* CONFIG_HS20 */ 671 672 if (params.freqs == NULL && wpa_s->next_scan_freqs) { 673 wpa_dbg(wpa_s, MSG_DEBUG, "Optimize scan based on previously " 674 "generated frequency list"); 675 params.freqs = wpa_s->next_scan_freqs; 676 } else 677 os_free(wpa_s->next_scan_freqs); 678 wpa_s->next_scan_freqs = NULL; 679 680 params.filter_ssids = wpa_supplicant_build_filter_ssids( 681 wpa_s->conf, ¶ms.num_filter_ssids); 682 if (extra_ie) { 683 params.extra_ies = wpabuf_head(extra_ie); 684 params.extra_ies_len = wpabuf_len(extra_ie); 685 } 686 687 #ifdef CONFIG_P2P 688 if (wpa_s->p2p_in_provisioning || 689 (wpa_s->show_group_started && wpa_s->go_params)) { 690 /* 691 * The interface may not yet be in P2P mode, so we have to 692 * explicitly request P2P probe to disable CCK rates. 693 */ 694 params.p2p_probe = 1; 695 } 696 #endif /* CONFIG_P2P */ 697 698 scan_params = ¶ms; 699 700 scan: 701 ret = wpa_supplicant_trigger_scan(wpa_s, scan_params); 702 703 wpabuf_free(extra_ie); 704 os_free(params.freqs); 705 os_free(params.filter_ssids); 706 707 if (ret) { 708 wpa_msg(wpa_s, MSG_WARNING, "Failed to initiate AP scan"); 709 #ifdef ANDROID_P2P 710 /* Restore back the wpa_s->scan_req if we failed the scan because of any reason */ 711 wpa_msg(wpa_s, MSG_DEBUG, "Restoring back the wpa_s->scan_req " 712 "to the original value %d", scan_req); 713 wpa_s->scan_req = scan_req; 714 #endif 715 if (prev_state != wpa_s->wpa_state) 716 wpa_supplicant_set_state(wpa_s, prev_state); 717 wpa_supplicant_req_scan(wpa_s, 1, 0); 718 } 719 } 720 721 722 /** 723 * wpa_supplicant_req_scan - Schedule a scan for neighboring access points 724 * @wpa_s: Pointer to wpa_supplicant data 725 * @sec: Number of seconds after which to scan 726 * @usec: Number of microseconds after which to scan 727 * 728 * This function is used to schedule a scan for neighboring access points after 729 * the specified time. 730 */ 731 void wpa_supplicant_req_scan(struct wpa_supplicant *wpa_s, int sec, int usec) 732 { 733 #ifndef ANDROID 734 /* If there's at least one network that should be specifically scanned 735 * then don't cancel the scan and reschedule. Some drivers do 736 * background scanning which generates frequent scan results, and that 737 * causes the specific SSID scan to get continually pushed back and 738 * never happen, which causes hidden APs to never get probe-scanned. 739 */ 740 if (eloop_is_timeout_registered(wpa_supplicant_scan, wpa_s, NULL) && 741 wpa_s->conf->ap_scan == 1) { 742 struct wpa_ssid *ssid = wpa_s->conf->ssid; 743 744 while (ssid) { 745 if (!wpas_network_disabled(wpa_s, ssid) && 746 ssid->scan_ssid) 747 break; 748 ssid = ssid->next; 749 } 750 if (ssid) { 751 wpa_dbg(wpa_s, MSG_DEBUG, "Not rescheduling scan to " 752 "ensure that specific SSID scans occur"); 753 return; 754 } 755 } 756 #endif 757 wpa_dbg(wpa_s, MSG_DEBUG, "Setting scan request: %d sec %d usec", 758 sec, usec); 759 eloop_cancel_timeout(wpa_supplicant_scan, wpa_s, NULL); 760 eloop_register_timeout(sec, usec, wpa_supplicant_scan, wpa_s, NULL); 761 } 762 763 764 /** 765 * wpa_supplicant_delayed_sched_scan - Request a delayed scheduled scan 766 * @wpa_s: Pointer to wpa_supplicant data 767 * @sec: Number of seconds after which to scan 768 * @usec: Number of microseconds after which to scan 769 * 770 * This function is used to schedule periodic scans for neighboring 771 * access points after the specified time. 772 */ 773 int wpa_supplicant_delayed_sched_scan(struct wpa_supplicant *wpa_s, 774 int sec, int usec) 775 { 776 if (!wpa_s->sched_scan_supported) 777 return -1; 778 779 eloop_register_timeout(sec, usec, 780 wpa_supplicant_delayed_sched_scan_timeout, 781 wpa_s, NULL); 782 783 return 0; 784 } 785 786 787 /** 788 * wpa_supplicant_req_sched_scan - Start a periodic scheduled scan 789 * @wpa_s: Pointer to wpa_supplicant data 790 * 791 * This function is used to schedule periodic scans for neighboring 792 * access points repeating the scan continuously. 793 */ 794 int wpa_supplicant_req_sched_scan(struct wpa_supplicant *wpa_s) 795 { 796 struct wpa_driver_scan_params params; 797 struct wpa_driver_scan_params *scan_params; 798 enum wpa_states prev_state; 799 struct wpa_ssid *ssid = NULL; 800 struct wpabuf *extra_ie = NULL; 801 int ret; 802 unsigned int max_sched_scan_ssids; 803 int wildcard = 0; 804 int need_ssids; 805 806 if (!wpa_s->sched_scan_supported) 807 return -1; 808 809 if (wpa_s->max_sched_scan_ssids > WPAS_MAX_SCAN_SSIDS) 810 max_sched_scan_ssids = WPAS_MAX_SCAN_SSIDS; 811 else 812 max_sched_scan_ssids = wpa_s->max_sched_scan_ssids; 813 if (max_sched_scan_ssids < 1 || wpa_s->conf->disable_scan_offload) 814 return -1; 815 816 if (wpa_s->sched_scanning) { 817 wpa_dbg(wpa_s, MSG_DEBUG, "Already sched scanning"); 818 return 0; 819 } 820 821 need_ssids = 0; 822 for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) { 823 if (!wpas_network_disabled(wpa_s, ssid) && !ssid->scan_ssid) { 824 /* Use wildcard SSID to find this network */ 825 wildcard = 1; 826 } else if (!wpas_network_disabled(wpa_s, ssid) && 827 ssid->ssid_len) 828 need_ssids++; 829 830 #ifdef CONFIG_WPS 831 if (!wpas_network_disabled(wpa_s, ssid) && 832 ssid->key_mgmt == WPA_KEY_MGMT_WPS) { 833 /* 834 * Normal scan is more reliable and faster for WPS 835 * operations and since these are for short periods of 836 * time, the benefit of trying to use sched_scan would 837 * be limited. 838 */ 839 wpa_dbg(wpa_s, MSG_DEBUG, "Use normal scan instead of " 840 "sched_scan for WPS"); 841 return -1; 842 } 843 #endif /* CONFIG_WPS */ 844 } 845 if (wildcard) 846 need_ssids++; 847 848 if (wpa_s->normal_scans < 3 && 849 (need_ssids <= wpa_s->max_scan_ssids || 850 wpa_s->max_scan_ssids >= (int) max_sched_scan_ssids)) { 851 /* 852 * When normal scan can speed up operations, use that for the 853 * first operations before starting the sched_scan to allow 854 * user space sleep more. We do this only if the normal scan 855 * has functionality that is suitable for this or if the 856 * sched_scan does not have better support for multiple SSIDs. 857 */ 858 wpa_dbg(wpa_s, MSG_DEBUG, "Use normal scan instead of " 859 "sched_scan for initial scans (normal_scans=%d)", 860 wpa_s->normal_scans); 861 return -1; 862 } 863 864 os_memset(¶ms, 0, sizeof(params)); 865 866 /* If we can't allocate space for the filters, we just don't filter */ 867 params.filter_ssids = os_zalloc(wpa_s->max_match_sets * 868 sizeof(struct wpa_driver_scan_filter)); 869 870 prev_state = wpa_s->wpa_state; 871 #ifndef ANDROID_P2P 872 if (wpa_s->wpa_state == WPA_DISCONNECTED || 873 wpa_s->wpa_state == WPA_INACTIVE) 874 wpa_supplicant_set_state(wpa_s, WPA_SCANNING); 875 #endif 876 877 if (wpa_s->autoscan_params != NULL) { 878 scan_params = wpa_s->autoscan_params; 879 goto scan; 880 } 881 882 /* Find the starting point from which to continue scanning */ 883 ssid = wpa_s->conf->ssid; 884 if (wpa_s->prev_sched_ssid) { 885 while (ssid) { 886 if (ssid == wpa_s->prev_sched_ssid) { 887 ssid = ssid->next; 888 break; 889 } 890 ssid = ssid->next; 891 } 892 } 893 894 if (!ssid || !wpa_s->prev_sched_ssid) { 895 wpa_dbg(wpa_s, MSG_DEBUG, "Beginning of SSID list"); 896 897 if (wpa_s->sched_scan_interval == 0) 898 wpa_s->sched_scan_interval = 10; 899 wpa_s->sched_scan_timeout = max_sched_scan_ssids * 2; 900 wpa_s->first_sched_scan = 1; 901 ssid = wpa_s->conf->ssid; 902 wpa_s->prev_sched_ssid = ssid; 903 } 904 905 if (wildcard) { 906 wpa_dbg(wpa_s, MSG_DEBUG, "Add wildcard SSID to sched_scan"); 907 params.num_ssids++; 908 } 909 910 while (ssid) { 911 if (wpas_network_disabled(wpa_s, ssid)) 912 goto next; 913 914 if (params.num_filter_ssids < wpa_s->max_match_sets && 915 params.filter_ssids && ssid->ssid && ssid->ssid_len) { 916 wpa_dbg(wpa_s, MSG_DEBUG, "add to filter ssid: %s", 917 wpa_ssid_txt(ssid->ssid, ssid->ssid_len)); 918 os_memcpy(params.filter_ssids[params.num_filter_ssids].ssid, 919 ssid->ssid, ssid->ssid_len); 920 params.filter_ssids[params.num_filter_ssids].ssid_len = 921 ssid->ssid_len; 922 params.num_filter_ssids++; 923 } else if (params.filter_ssids && ssid->ssid && ssid->ssid_len) 924 { 925 wpa_dbg(wpa_s, MSG_DEBUG, "Not enough room for SSID " 926 "filter for sched_scan - drop filter"); 927 os_free(params.filter_ssids); 928 params.filter_ssids = NULL; 929 params.num_filter_ssids = 0; 930 } 931 932 if (ssid->scan_ssid && ssid->ssid && ssid->ssid_len) { 933 if (params.num_ssids == max_sched_scan_ssids) 934 break; /* only room for broadcast SSID */ 935 wpa_dbg(wpa_s, MSG_DEBUG, 936 "add to active scan ssid: %s", 937 wpa_ssid_txt(ssid->ssid, ssid->ssid_len)); 938 params.ssids[params.num_ssids].ssid = 939 ssid->ssid; 940 params.ssids[params.num_ssids].ssid_len = 941 ssid->ssid_len; 942 params.num_ssids++; 943 if (params.num_ssids >= max_sched_scan_ssids) { 944 wpa_s->prev_sched_ssid = ssid; 945 do { 946 ssid = ssid->next; 947 } while (ssid && 948 (wpas_network_disabled(wpa_s, ssid) || 949 !ssid->scan_ssid)); 950 break; 951 } 952 } 953 954 next: 955 wpa_s->prev_sched_ssid = ssid; 956 ssid = ssid->next; 957 } 958 959 if (params.num_filter_ssids == 0) { 960 os_free(params.filter_ssids); 961 params.filter_ssids = NULL; 962 } 963 964 extra_ie = wpa_supplicant_extra_ies(wpa_s); 965 if (extra_ie) { 966 params.extra_ies = wpabuf_head(extra_ie); 967 params.extra_ies_len = wpabuf_len(extra_ie); 968 } 969 970 scan_params = ¶ms; 971 972 scan: 973 if (ssid || !wpa_s->first_sched_scan) { 974 wpa_dbg(wpa_s, MSG_DEBUG, 975 "Starting sched scan: interval %d timeout %d", 976 wpa_s->sched_scan_interval, wpa_s->sched_scan_timeout); 977 } else { 978 wpa_dbg(wpa_s, MSG_DEBUG, 979 "Starting sched scan: interval %d (no timeout)", 980 wpa_s->sched_scan_interval); 981 } 982 983 ret = wpa_supplicant_start_sched_scan(wpa_s, scan_params, 984 wpa_s->sched_scan_interval); 985 wpabuf_free(extra_ie); 986 os_free(params.filter_ssids); 987 if (ret) { 988 wpa_msg(wpa_s, MSG_WARNING, "Failed to initiate sched scan"); 989 if (prev_state != wpa_s->wpa_state) 990 wpa_supplicant_set_state(wpa_s, prev_state); 991 return ret; 992 } 993 994 /* If we have more SSIDs to scan, add a timeout so we scan them too */ 995 if (ssid || !wpa_s->first_sched_scan) { 996 wpa_s->sched_scan_timed_out = 0; 997 eloop_register_timeout(wpa_s->sched_scan_timeout, 0, 998 wpa_supplicant_sched_scan_timeout, 999 wpa_s, NULL); 1000 wpa_s->first_sched_scan = 0; 1001 wpa_s->sched_scan_timeout /= 2; 1002 wpa_s->sched_scan_interval *= 2; 1003 } 1004 1005 return 0; 1006 } 1007 1008 1009 /** 1010 * wpa_supplicant_cancel_scan - Cancel a scheduled scan request 1011 * @wpa_s: Pointer to wpa_supplicant data 1012 * 1013 * This function is used to cancel a scan request scheduled with 1014 * wpa_supplicant_req_scan(). 1015 */ 1016 void wpa_supplicant_cancel_scan(struct wpa_supplicant *wpa_s) 1017 { 1018 wpa_dbg(wpa_s, MSG_DEBUG, "Cancelling scan request"); 1019 eloop_cancel_timeout(wpa_supplicant_scan, wpa_s, NULL); 1020 #ifdef ANDROID 1021 wpa_supplicant_notify_scanning(wpa_s, 0); 1022 #endif 1023 } 1024 1025 1026 /** 1027 * wpa_supplicant_cancel_sched_scan - Stop running scheduled scans 1028 * @wpa_s: Pointer to wpa_supplicant data 1029 * 1030 * This function is used to stop a periodic scheduled scan. 1031 */ 1032 void wpa_supplicant_cancel_sched_scan(struct wpa_supplicant *wpa_s) 1033 { 1034 if (!wpa_s->sched_scanning) 1035 return; 1036 1037 wpa_dbg(wpa_s, MSG_DEBUG, "Cancelling sched scan"); 1038 eloop_cancel_timeout(wpa_supplicant_sched_scan_timeout, wpa_s, NULL); 1039 wpa_supplicant_stop_sched_scan(wpa_s); 1040 } 1041 1042 1043 void wpa_supplicant_notify_scanning(struct wpa_supplicant *wpa_s, 1044 int scanning) 1045 { 1046 if (wpa_s->scanning != scanning) { 1047 #ifdef ANDROID_P2P 1048 if(!wpa_s->sched_scanning) 1049 wpa_s->scanning = scanning; 1050 #else 1051 wpa_s->scanning = scanning; 1052 #endif 1053 wpas_notify_scanning(wpa_s); 1054 } 1055 } 1056 1057 1058 static int wpa_scan_get_max_rate(const struct wpa_scan_res *res) 1059 { 1060 int rate = 0; 1061 const u8 *ie; 1062 int i; 1063 1064 ie = wpa_scan_get_ie(res, WLAN_EID_SUPP_RATES); 1065 for (i = 0; ie && i < ie[1]; i++) { 1066 if ((ie[i + 2] & 0x7f) > rate) 1067 rate = ie[i + 2] & 0x7f; 1068 } 1069 1070 ie = wpa_scan_get_ie(res, WLAN_EID_EXT_SUPP_RATES); 1071 for (i = 0; ie && i < ie[1]; i++) { 1072 if ((ie[i + 2] & 0x7f) > rate) 1073 rate = ie[i + 2] & 0x7f; 1074 } 1075 1076 return rate; 1077 } 1078 1079 1080 const u8 * wpa_scan_get_ie(const struct wpa_scan_res *res, u8 ie) 1081 { 1082 const u8 *end, *pos; 1083 1084 pos = (const u8 *) (res + 1); 1085 end = pos + res->ie_len; 1086 1087 while (pos + 1 < end) { 1088 if (pos + 2 + pos[1] > end) 1089 break; 1090 if (pos[0] == ie) 1091 return pos; 1092 pos += 2 + pos[1]; 1093 } 1094 1095 return NULL; 1096 } 1097 1098 1099 const u8 * wpa_scan_get_vendor_ie(const struct wpa_scan_res *res, 1100 u32 vendor_type) 1101 { 1102 const u8 *end, *pos; 1103 1104 pos = (const u8 *) (res + 1); 1105 end = pos + res->ie_len; 1106 1107 while (pos + 1 < end) { 1108 if (pos + 2 + pos[1] > end) 1109 break; 1110 if (pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 && 1111 vendor_type == WPA_GET_BE32(&pos[2])) 1112 return pos; 1113 pos += 2 + pos[1]; 1114 } 1115 1116 return NULL; 1117 } 1118 1119 1120 struct wpabuf * wpa_scan_get_vendor_ie_multi(const struct wpa_scan_res *res, 1121 u32 vendor_type) 1122 { 1123 struct wpabuf *buf; 1124 const u8 *end, *pos; 1125 1126 buf = wpabuf_alloc(res->ie_len); 1127 if (buf == NULL) 1128 return NULL; 1129 1130 pos = (const u8 *) (res + 1); 1131 end = pos + res->ie_len; 1132 1133 while (pos + 1 < end) { 1134 if (pos + 2 + pos[1] > end) 1135 break; 1136 if (pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 && 1137 vendor_type == WPA_GET_BE32(&pos[2])) 1138 wpabuf_put_data(buf, pos + 2 + 4, pos[1] - 4); 1139 pos += 2 + pos[1]; 1140 } 1141 1142 if (wpabuf_len(buf) == 0) { 1143 wpabuf_free(buf); 1144 buf = NULL; 1145 } 1146 1147 return buf; 1148 } 1149 1150 1151 struct wpabuf * wpa_scan_get_vendor_ie_multi_beacon( 1152 const struct wpa_scan_res *res, u32 vendor_type) 1153 { 1154 struct wpabuf *buf; 1155 const u8 *end, *pos; 1156 1157 if (res->beacon_ie_len == 0) 1158 return NULL; 1159 buf = wpabuf_alloc(res->beacon_ie_len); 1160 if (buf == NULL) 1161 return NULL; 1162 1163 pos = (const u8 *) (res + 1); 1164 pos += res->ie_len; 1165 end = pos + res->beacon_ie_len; 1166 1167 while (pos + 1 < end) { 1168 if (pos + 2 + pos[1] > end) 1169 break; 1170 if (pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 && 1171 vendor_type == WPA_GET_BE32(&pos[2])) 1172 wpabuf_put_data(buf, pos + 2 + 4, pos[1] - 4); 1173 pos += 2 + pos[1]; 1174 } 1175 1176 if (wpabuf_len(buf) == 0) { 1177 wpabuf_free(buf); 1178 buf = NULL; 1179 } 1180 1181 return buf; 1182 } 1183 1184 1185 /* 1186 * Channels with a great SNR can operate at full rate. What is a great SNR? 1187 * This doc https://supportforums.cisco.com/docs/DOC-12954 says, "the general 1188 * rule of thumb is that any SNR above 20 is good." This one 1189 * http://www.cisco.com/en/US/tech/tk722/tk809/technologies_q_and_a_item09186a00805e9a96.shtml#qa23 1190 * recommends 25 as a minimum SNR for 54 Mbps data rate. 30 is chosen here as a 1191 * conservative value. 1192 */ 1193 #define GREAT_SNR 30 1194 1195 /* Compare function for sorting scan results. Return >0 if @b is considered 1196 * better. */ 1197 static int wpa_scan_result_compar(const void *a, const void *b) 1198 { 1199 #define IS_5GHZ(n) (n > 4000) 1200 #define MIN(a,b) a < b ? a : b 1201 struct wpa_scan_res **_wa = (void *) a; 1202 struct wpa_scan_res **_wb = (void *) b; 1203 struct wpa_scan_res *wa = *_wa; 1204 struct wpa_scan_res *wb = *_wb; 1205 int wpa_a, wpa_b, maxrate_a, maxrate_b; 1206 int snr_a, snr_b; 1207 1208 /* WPA/WPA2 support preferred */ 1209 wpa_a = wpa_scan_get_vendor_ie(wa, WPA_IE_VENDOR_TYPE) != NULL || 1210 wpa_scan_get_ie(wa, WLAN_EID_RSN) != NULL; 1211 wpa_b = wpa_scan_get_vendor_ie(wb, WPA_IE_VENDOR_TYPE) != NULL || 1212 wpa_scan_get_ie(wb, WLAN_EID_RSN) != NULL; 1213 1214 if (wpa_b && !wpa_a) 1215 return 1; 1216 if (!wpa_b && wpa_a) 1217 return -1; 1218 1219 /* privacy support preferred */ 1220 if ((wa->caps & IEEE80211_CAP_PRIVACY) == 0 && 1221 (wb->caps & IEEE80211_CAP_PRIVACY)) 1222 return 1; 1223 if ((wa->caps & IEEE80211_CAP_PRIVACY) && 1224 (wb->caps & IEEE80211_CAP_PRIVACY) == 0) 1225 return -1; 1226 1227 if ((wa->flags & wb->flags & WPA_SCAN_LEVEL_DBM) && 1228 !((wa->flags | wb->flags) & WPA_SCAN_NOISE_INVALID)) { 1229 snr_a = MIN(wa->level - wa->noise, GREAT_SNR); 1230 snr_b = MIN(wb->level - wb->noise, GREAT_SNR); 1231 } else { 1232 /* Not suitable information to calculate SNR, so use level */ 1233 snr_a = wa->level; 1234 snr_b = wb->level; 1235 } 1236 1237 /* best/max rate preferred if SNR close enough */ 1238 if ((snr_a && snr_b && abs(snr_b - snr_a) < 5) || 1239 (wa->qual && wb->qual && abs(wb->qual - wa->qual) < 10)) { 1240 maxrate_a = wpa_scan_get_max_rate(wa); 1241 maxrate_b = wpa_scan_get_max_rate(wb); 1242 if (maxrate_a != maxrate_b) 1243 return maxrate_b - maxrate_a; 1244 if (IS_5GHZ(wa->freq) ^ IS_5GHZ(wb->freq)) 1245 return IS_5GHZ(wa->freq) ? -1 : 1; 1246 } 1247 1248 /* use freq for channel preference */ 1249 1250 /* all things being equal, use SNR; if SNRs are 1251 * identical, use quality values since some drivers may only report 1252 * that value and leave the signal level zero */ 1253 if (snr_b == snr_a) 1254 return wb->qual - wa->qual; 1255 return snr_b - snr_a; 1256 #undef MIN 1257 #undef IS_5GHZ 1258 } 1259 1260 1261 #ifdef CONFIG_WPS 1262 /* Compare function for sorting scan results when searching a WPS AP for 1263 * provisioning. Return >0 if @b is considered better. */ 1264 static int wpa_scan_result_wps_compar(const void *a, const void *b) 1265 { 1266 struct wpa_scan_res **_wa = (void *) a; 1267 struct wpa_scan_res **_wb = (void *) b; 1268 struct wpa_scan_res *wa = *_wa; 1269 struct wpa_scan_res *wb = *_wb; 1270 int uses_wps_a, uses_wps_b; 1271 struct wpabuf *wps_a, *wps_b; 1272 int res; 1273 1274 /* Optimization - check WPS IE existence before allocated memory and 1275 * doing full reassembly. */ 1276 uses_wps_a = wpa_scan_get_vendor_ie(wa, WPS_IE_VENDOR_TYPE) != NULL; 1277 uses_wps_b = wpa_scan_get_vendor_ie(wb, WPS_IE_VENDOR_TYPE) != NULL; 1278 if (uses_wps_a && !uses_wps_b) 1279 return -1; 1280 if (!uses_wps_a && uses_wps_b) 1281 return 1; 1282 1283 if (uses_wps_a && uses_wps_b) { 1284 wps_a = wpa_scan_get_vendor_ie_multi(wa, WPS_IE_VENDOR_TYPE); 1285 wps_b = wpa_scan_get_vendor_ie_multi(wb, WPS_IE_VENDOR_TYPE); 1286 res = wps_ap_priority_compar(wps_a, wps_b); 1287 wpabuf_free(wps_a); 1288 wpabuf_free(wps_b); 1289 if (res) 1290 return res; 1291 } 1292 1293 /* 1294 * Do not use current AP security policy as a sorting criteria during 1295 * WPS provisioning step since the AP may get reconfigured at the 1296 * completion of provisioning. 1297 */ 1298 1299 /* all things being equal, use signal level; if signal levels are 1300 * identical, use quality values since some drivers may only report 1301 * that value and leave the signal level zero */ 1302 if (wb->level == wa->level) 1303 return wb->qual - wa->qual; 1304 return wb->level - wa->level; 1305 } 1306 #endif /* CONFIG_WPS */ 1307 1308 1309 static void dump_scan_res(struct wpa_scan_results *scan_res) 1310 { 1311 #ifndef CONFIG_NO_STDOUT_DEBUG 1312 size_t i; 1313 1314 if (scan_res->res == NULL || scan_res->num == 0) 1315 return; 1316 1317 wpa_printf(MSG_EXCESSIVE, "Sorted scan results"); 1318 1319 for (i = 0; i < scan_res->num; i++) { 1320 struct wpa_scan_res *r = scan_res->res[i]; 1321 u8 *pos; 1322 if ((r->flags & (WPA_SCAN_LEVEL_DBM | WPA_SCAN_NOISE_INVALID)) 1323 == WPA_SCAN_LEVEL_DBM) { 1324 int snr = r->level - r->noise; 1325 wpa_printf(MSG_EXCESSIVE, MACSTR " freq=%d qual=%d " 1326 "noise=%d level=%d snr=%d%s flags=0x%x", 1327 MAC2STR(r->bssid), r->freq, r->qual, 1328 r->noise, r->level, snr, 1329 snr >= GREAT_SNR ? "*" : "", r->flags); 1330 } else { 1331 wpa_printf(MSG_EXCESSIVE, MACSTR " freq=%d qual=%d " 1332 "noise=%d level=%d flags=0x%x", 1333 MAC2STR(r->bssid), r->freq, r->qual, 1334 r->noise, r->level, r->flags); 1335 } 1336 pos = (u8 *) (r + 1); 1337 if (r->ie_len) 1338 wpa_hexdump(MSG_EXCESSIVE, "IEs", pos, r->ie_len); 1339 pos += r->ie_len; 1340 if (r->beacon_ie_len) 1341 wpa_hexdump(MSG_EXCESSIVE, "Beacon IEs", 1342 pos, r->beacon_ie_len); 1343 } 1344 #endif /* CONFIG_NO_STDOUT_DEBUG */ 1345 } 1346 1347 1348 int wpa_supplicant_filter_bssid_match(struct wpa_supplicant *wpa_s, 1349 const u8 *bssid) 1350 { 1351 size_t i; 1352 1353 if (wpa_s->bssid_filter == NULL) 1354 return 1; 1355 1356 for (i = 0; i < wpa_s->bssid_filter_count; i++) { 1357 if (os_memcmp(wpa_s->bssid_filter + i * ETH_ALEN, bssid, 1358 ETH_ALEN) == 0) 1359 return 1; 1360 } 1361 1362 return 0; 1363 } 1364 1365 1366 static void filter_scan_res(struct wpa_supplicant *wpa_s, 1367 struct wpa_scan_results *res) 1368 { 1369 size_t i, j; 1370 1371 if (wpa_s->bssid_filter == NULL) 1372 return; 1373 1374 for (i = 0, j = 0; i < res->num; i++) { 1375 if (wpa_supplicant_filter_bssid_match(wpa_s, 1376 res->res[i]->bssid)) { 1377 res->res[j++] = res->res[i]; 1378 } else { 1379 os_free(res->res[i]); 1380 res->res[i] = NULL; 1381 } 1382 } 1383 1384 if (res->num != j) { 1385 wpa_printf(MSG_DEBUG, "Filtered out %d scan results", 1386 (int) (res->num - j)); 1387 res->num = j; 1388 } 1389 } 1390 1391 1392 /** 1393 * wpa_supplicant_get_scan_results - Get scan results 1394 * @wpa_s: Pointer to wpa_supplicant data 1395 * @info: Information about what was scanned or %NULL if not available 1396 * @new_scan: Whether a new scan was performed 1397 * Returns: Scan results, %NULL on failure 1398 * 1399 * This function request the current scan results from the driver and updates 1400 * the local BSS list wpa_s->bss. The caller is responsible for freeing the 1401 * results with wpa_scan_results_free(). 1402 */ 1403 struct wpa_scan_results * 1404 wpa_supplicant_get_scan_results(struct wpa_supplicant *wpa_s, 1405 struct scan_info *info, int new_scan) 1406 { 1407 struct wpa_scan_results *scan_res; 1408 size_t i; 1409 int (*compar)(const void *, const void *) = wpa_scan_result_compar; 1410 1411 scan_res = wpa_drv_get_scan_results2(wpa_s); 1412 if (scan_res == NULL) { 1413 wpa_dbg(wpa_s, MSG_DEBUG, "Failed to get scan results"); 1414 return NULL; 1415 } 1416 filter_scan_res(wpa_s, scan_res); 1417 1418 #ifdef CONFIG_WPS 1419 if (wpas_wps_in_progress(wpa_s)) { 1420 wpa_dbg(wpa_s, MSG_DEBUG, "WPS: Order scan results with WPS " 1421 "provisioning rules"); 1422 compar = wpa_scan_result_wps_compar; 1423 } 1424 #endif /* CONFIG_WPS */ 1425 1426 qsort(scan_res->res, scan_res->num, sizeof(struct wpa_scan_res *), 1427 compar); 1428 dump_scan_res(scan_res); 1429 1430 wpa_bss_update_start(wpa_s); 1431 for (i = 0; i < scan_res->num; i++) 1432 wpa_bss_update_scan_res(wpa_s, scan_res->res[i]); 1433 wpa_bss_update_end(wpa_s, info, new_scan); 1434 1435 return scan_res; 1436 } 1437 1438 1439 int wpa_supplicant_update_scan_results(struct wpa_supplicant *wpa_s) 1440 { 1441 struct wpa_scan_results *scan_res; 1442 scan_res = wpa_supplicant_get_scan_results(wpa_s, NULL, 0); 1443 if (scan_res == NULL) 1444 return -1; 1445 wpa_scan_results_free(scan_res); 1446 1447 return 0; 1448 } 1449