scan.c revision 687922c7347bdc3b4f8c921efe1d1388cb3baac0
18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * WPA Supplicant - Scanning 38d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Copyright (c) 2003-2010, Jouni Malinen <j@w1.fi> 48d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 5c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * This software may be distributed under the terms of the BSD license. 6c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * See README for more details. 78d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "utils/includes.h" 108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "utils/common.h" 128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "utils/eloop.h" 138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common/ieee802_11_defs.h" 148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "config.h" 158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "wpa_supplicant_i.h" 168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "driver_i.h" 178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "wps_supplicant.h" 188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "p2p_supplicant.h" 198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "p2p/p2p.h" 208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "notify.h" 218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "bss.h" 228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "scan.h" 238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpa_supplicant_gen_assoc_event(struct wpa_supplicant *wpa_s) 268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_ssid *ssid; 288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt union wpa_event_data data; 298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid = wpa_supplicant_get_ssid(wpa_s); 318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid == NULL) 328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->current_ssid == NULL) { 358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->current_ssid = ssid; 368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->current_ssid != NULL) 378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_notify_network_changed(wpa_s); 388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_initiate_eapol(wpa_s); 408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "Already associated with a configured " 418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "network - generating associated event"); 428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&data, 0, sizeof(data)); 438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_event(wpa_s, EVENT_ASSOC, &data); 448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_WPS 481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic int wpas_wps_in_use(struct wpa_supplicant *wpa_s, 498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum wps_request_type *req_type) 508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_ssid *ssid; 528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int wps = 0; 538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 541f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) { 558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!(ssid->key_mgmt & WPA_KEY_MGMT_WPS)) 568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wps = 1; 598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *req_type = wpas_wps_get_req_type(ssid); 608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!ssid->eap.phase1) 618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_strstr(ssid->eap.phase1, "pbc=1")) 648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 2; 658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 671f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef CONFIG_P2P 68c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (!wpa_s->global->p2p_disabled && wpa_s->global->p2p) { 69c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpa_s->wps->dev.p2p = 1; 70c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (!wps) { 71c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wps = 1; 72c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt *req_type = WPS_REQ_ENROLLEE_INFO; 73c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt } 741f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 751f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* CONFIG_P2P */ 761f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return wps; 788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_WPS */ 808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpa_supplicant_enabled_networks(struct wpa_config *conf) 838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_ssid *ssid = conf->ssid; 858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int count = 0; 868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (ssid) { 878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!ssid->disabled) 888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt count++; 898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid = ssid->next; 908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return count; 928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpa_supplicant_assoc_try(struct wpa_supplicant *wpa_s, 968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_ssid *ssid) 978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (ssid) { 998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!ssid->disabled) 1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid = ssid->next; 1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* ap_scan=2 mode - try to associate with each SSID. */ 1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid == NULL) { 1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "wpa_supplicant_assoc_try: Reached " 1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "end of scan list - go back to beginning"); 1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->prev_scan_ssid = WILDCARD_SSID_SCAN; 1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_req_scan(wpa_s, 0, 0); 1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid->next) { 1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Continue from the next SSID on the next attempt. */ 1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->prev_scan_ssid = ssid; 1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Start from the beginning of the SSID list. */ 1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->prev_scan_ssid = WILDCARD_SSID_SCAN; 1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_associate(wpa_s, NULL, ssid); 1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int int_array_len(const int *a) 1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; a && a[i]; i++) 1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ; 1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return i; 1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void int_array_concat(int **res, const int *a) 1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int reslen, alen, i; 1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int *n; 1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reslen = int_array_len(*res); 1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt alen = int_array_len(a); 1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt n = os_realloc(*res, (reslen + alen + 1) * sizeof(int)); 1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (n == NULL) { 1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(*res); 1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *res = NULL; 1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i <= alen; i++) 1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt n[reslen + i] = a[i]; 1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *res = n; 1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int freq_cmp(const void *a, const void *b) 1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int _a = *(int *) a; 1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int _b = *(int *) b; 1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (_a == 0) 1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (_b == 0) 1608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return _a - _b; 1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void int_array_sort_unique(int *a) 1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int alen; 1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i, j; 1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (a == NULL) 1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt alen = int_array_len(a); 1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt qsort(a, alen, sizeof(int), freq_cmp); 1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt i = 0; 1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt j = 1; 1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (a[i] && a[j]) { 1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (a[i] == a[j]) { 1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt j++; 1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt a[++i] = a[j++]; 1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (a[i]) 1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt i++; 1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt a[i] = 0; 1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpa_supplicant_trigger_scan(struct wpa_supplicant *wpa_s, 1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_driver_scan_params *params) 1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret; 1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_notify_scanning(wpa_s, 1); 1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1981f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt ret = wpa_drv_scan(wpa_s, params); 1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret) { 2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_notify_scanning(wpa_s, 0); 2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_notify_scan_done(wpa_s, 0); 2021f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } else { 2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->scan_runs++; 2041f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s->normal_scans++; 2051f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 2061f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 2071f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return ret; 2081f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 2091f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 2101f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 2111f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic void 2121f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtwpa_supplicant_delayed_sched_scan_timeout(void *eloop_ctx, void *timeout_ctx) 2131f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 2141f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct wpa_supplicant *wpa_s = eloop_ctx; 2151f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 2161f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "Starting delayed sched scan"); 2171f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 2181f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (wpa_supplicant_req_sched_scan(wpa_s)) 2191f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_supplicant_req_scan(wpa_s, 0, 0); 2201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 2211f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 2221f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 2231f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic void 2241f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtwpa_supplicant_sched_scan_timeout(void *eloop_ctx, void *timeout_ctx) 2251f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 2261f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct wpa_supplicant *wpa_s = eloop_ctx; 2271f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 2281f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "Sched scan timeout - stopping it"); 2291f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 2301f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s->sched_scan_timed_out = 1; 2311f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_supplicant_cancel_sched_scan(wpa_s); 2321f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 2331f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 2341f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 2351f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic int 2361f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtwpa_supplicant_start_sched_scan(struct wpa_supplicant *wpa_s, 2371f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct wpa_driver_scan_params *params, 2381f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt int interval) 2391f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 2401f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt int ret; 241687922c7347bdc3b4f8c921efe1d1388cb3baac0Dmitry Shmidt#ifndef ANDROID_P2P 2421f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_supplicant_notify_scanning(wpa_s, 1); 243687922c7347bdc3b4f8c921efe1d1388cb3baac0Dmitry Shmidt#endif 2441f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt ret = wpa_drv_sched_scan(wpa_s, params, interval * 1000); 2451f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (ret) 2461f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_supplicant_notify_scanning(wpa_s, 0); 247687922c7347bdc3b4f8c921efe1d1388cb3baac0Dmitry Shmidt else { 2481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s->sched_scanning = 1; 249687922c7347bdc3b4f8c921efe1d1388cb3baac0Dmitry Shmidt#ifdef ANDROID_P2P 250687922c7347bdc3b4f8c921efe1d1388cb3baac0Dmitry Shmidt wpa_supplicant_notify_scanning(wpa_s, 1); 251687922c7347bdc3b4f8c921efe1d1388cb3baac0Dmitry Shmidt#endif 252687922c7347bdc3b4f8c921efe1d1388cb3baac0Dmitry Shmidt } 2531f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 2541f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return ret; 2551f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 2561f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 2571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 2581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic int wpa_supplicant_stop_sched_scan(struct wpa_supplicant *wpa_s) 2591f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 2601f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt int ret; 2611f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 2621f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt ret = wpa_drv_stop_sched_scan(wpa_s); 2631f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (ret) { 2641f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "stopping sched_scan failed!"); 2651f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* TODO: what to do if stopping fails? */ 2661f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return -1; 2671f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 2688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 2708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpa_driver_scan_filter * 2748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtwpa_supplicant_build_filter_ssids(struct wpa_config *conf, size_t *num_ssids) 2758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_driver_scan_filter *ssids; 2778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_ssid *ssid; 2788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t count; 2798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *num_ssids = 0; 2818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!conf->filter_ssids) 2828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 2838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (count = 0, ssid = conf->ssid; ssid; ssid = ssid->next) { 2858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid->ssid && ssid->ssid_len) 2868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt count++; 2878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (count == 0) 2898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 2908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssids = os_zalloc(count * sizeof(struct wpa_driver_scan_filter)); 2918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssids == NULL) 2928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 2938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (ssid = conf->ssid; ssid; ssid = ssid->next) { 2958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!ssid->ssid || !ssid->ssid_len) 2968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 2978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(ssids[*num_ssids].ssid, ssid->ssid, ssid->ssid_len); 2988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssids[*num_ssids].ssid_len = ssid->ssid_len; 2998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (*num_ssids)++; 3008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ssids; 3038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3061f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic void wpa_supplicant_optimize_freqs( 3071f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct wpa_supplicant *wpa_s, struct wpa_driver_scan_params *params) 3088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3091f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef CONFIG_P2P 3101f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (params->freqs == NULL && wpa_s->p2p_in_provisioning && 3111f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s->go_params) { 3121f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* Optimize provisioning state scan based on GO information */ 3131f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (wpa_s->p2p_in_provisioning < 5 && 3141f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s->go_params->freq > 0) { 3151f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Scan only GO " 3161f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "preferred frequency %d MHz", 3171f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s->go_params->freq); 3181f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt params->freqs = os_zalloc(2 * sizeof(int)); 3191f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (params->freqs) 3201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt params->freqs[0] = wpa_s->go_params->freq; 3211f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } else if (wpa_s->p2p_in_provisioning < 8 && 3221f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s->go_params->freq_list[0]) { 3231f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Scan only common " 3241f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "channels"); 3251f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt int_array_concat(¶ms->freqs, 3261f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s->go_params->freq_list); 3271f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (params->freqs) 3281f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt int_array_sort_unique(params->freqs); 3291f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 3301f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s->p2p_in_provisioning++; 3311f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 3321f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* CONFIG_P2P */ 3331f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 3341f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef CONFIG_WPS 3351f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (params->freqs == NULL && wpa_s->after_wps && wpa_s->wps_freq) { 3361f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* 3371f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * Optimize post-provisioning scan based on channel used 3381f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * during provisioning. 3391f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt */ 3401f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "WPS: Scan only frequency %u MHz " 3411f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "that was used during provisioning", wpa_s->wps_freq); 3421f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt params->freqs = os_zalloc(2 * sizeof(int)); 3431f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (params->freqs) 3441f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt params->freqs[0] = wpa_s->wps_freq; 3451f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s->after_wps--; 3461f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 3471f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 348c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (params->freqs == NULL && wpa_s->known_wps_freq && wpa_s->wps_freq) 349c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt { 350c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt /* Optimize provisioning scan based on already known channel */ 351c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "WPS: Scan only frequency %u MHz", 352c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpa_s->wps_freq); 353c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt params->freqs = os_zalloc(2 * sizeof(int)); 354c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (params->freqs) 355c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt params->freqs[0] = wpa_s->wps_freq; 356c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpa_s->known_wps_freq = 0; /* only do this once */ 357c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt } 3581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* CONFIG_WPS */ 3591f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 3601f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 3611f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 3621f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef CONFIG_INTERWORKING 3631f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic void wpas_add_interworking_elements(struct wpa_supplicant *wpa_s, 3641f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct wpabuf *buf) 3651f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 3661f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (wpa_s->conf->interworking == 0) 3671f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return; 3681f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 3691f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpabuf_put_u8(buf, WLAN_EID_EXT_CAPAB); 3701f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpabuf_put_u8(buf, 4); 3711f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpabuf_put_u8(buf, 0x00); 3721f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpabuf_put_u8(buf, 0x00); 3731f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpabuf_put_u8(buf, 0x00); 3741f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpabuf_put_u8(buf, 0x80); /* Bit 31 - Interworking */ 3751f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 3761f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpabuf_put_u8(buf, WLAN_EID_INTERWORKING); 3771f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpabuf_put_u8(buf, is_zero_ether_addr(wpa_s->conf->hessid) ? 1 : 3781f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 1 + ETH_ALEN); 3791f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpabuf_put_u8(buf, wpa_s->conf->access_network_type); 3801f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* No Venue Info */ 3811f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (!is_zero_ether_addr(wpa_s->conf->hessid)) 3821f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpabuf_put_data(buf, wpa_s->conf->hessid, ETH_ALEN); 3831f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 3841f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* CONFIG_INTERWORKING */ 3851f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 3861f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 3871f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic struct wpabuf * 3881f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtwpa_supplicant_extra_ies(struct wpa_supplicant *wpa_s, 3891f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct wpa_driver_scan_params *params) 3901f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 3911f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct wpabuf *extra_ie = NULL; 3928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_WPS 3938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int wps = 0; 3948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum wps_request_type req_type = WPS_REQ_ENROLLEE_INFO; 3958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_WPS */ 3961f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 3971f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef CONFIG_INTERWORKING 3981f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (wpa_s->conf->interworking && 3991f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpabuf_resize(&extra_ie, 100) == 0) 4001f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpas_add_interworking_elements(wpa_s, extra_ie); 4011f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* CONFIG_INTERWORKING */ 4021f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 4031f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef CONFIG_WPS 4041f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wps = wpas_wps_in_use(wpa_s, &req_type); 4051f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 4061f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (wps) { 4071f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct wpabuf *wps_ie; 4081f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wps_ie = wps_build_probe_req_ie(wps == 2, &wpa_s->wps->dev, 4091f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s->wps->uuid, req_type, 4101f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 0, NULL); 4111f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (wps_ie) { 4121f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (wpabuf_resize(&extra_ie, wpabuf_len(wps_ie)) == 0) 4131f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpabuf_put_buf(extra_ie, wps_ie); 4141f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpabuf_free(wps_ie); 4151f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 4161f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 4171f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 4181f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef CONFIG_P2P 4191f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (wps) { 4201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt size_t ielen = p2p_scan_ie_buf_len(wpa_s->global->p2p); 4211f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (wpabuf_resize(&extra_ie, ielen) == 0) 4221f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpas_p2p_scan_ie(wpa_s, extra_ie); 4231f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 4241f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* CONFIG_P2P */ 4251f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 4261f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* CONFIG_WPS */ 4271f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 4281f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return extra_ie; 4291f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 4301f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 4311f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 4321f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic void wpa_supplicant_scan(void *eloop_ctx, void *timeout_ctx) 4331f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 4341f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct wpa_supplicant *wpa_s = eloop_ctx; 4351f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct wpa_ssid *ssid; 4361f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt int scan_req = 0, ret; 4371f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct wpabuf *extra_ie; 4388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_driver_scan_params params; 4398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t max_ssids; 4408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum wpa_states prev_state; 4418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) { 4438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "Skip scan - interface disabled"); 4448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 4458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->disconnected && !wpa_s->scan_req) { 4488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED); 4498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 4508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!wpa_supplicant_enabled_networks(wpa_s->conf) && 4538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !wpa_s->scan_req) { 4548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "No enabled networks - do not scan"); 4558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_set_state(wpa_s, WPA_INACTIVE); 4568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 4578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->conf->ap_scan != 0 && 4608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (wpa_s->drv_flags & WPA_DRIVER_FLAGS_WIRED)) { 4618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "Using wired authentication - " 4628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "overriding ap_scan configuration"); 4638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->conf->ap_scan = 0; 4648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_notify_ap_scan_changed(wpa_s); 4658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->conf->ap_scan == 0) { 4688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_gen_assoc_event(wpa_s); 4698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 4708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4721f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef CONFIG_P2P 4731f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (wpas_p2p_in_progress(wpa_s)) { 4741f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (wpa_s->wpa_state == WPA_SCANNING) { 4751f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "Delay station mode scan " 4761f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "while P2P operation is in progress"); 4771f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_supplicant_req_scan(wpa_s, 5, 0); 4781f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } else { 4791f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "Do not request scan while " 4801f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "P2P operation is in progress"); 4811f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 4821f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return; 4831f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 4841f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* CONFIG_P2P */ 4851f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 4861f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (wpa_s->conf->ap_scan == 2) 4878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt max_ssids = 1; 4888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else { 4898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt max_ssids = wpa_s->max_scan_ssids; 4908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (max_ssids > WPAS_MAX_SCAN_SSIDS) 4918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt max_ssids = WPAS_MAX_SCAN_SSIDS; 4928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt scan_req = wpa_s->scan_req; 4958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->scan_req = 0; 4968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(¶ms, 0, sizeof(params)); 4988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt prev_state = wpa_s->wpa_state; 5008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->wpa_state == WPA_DISCONNECTED || 5018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->wpa_state == WPA_INACTIVE) 5028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_set_state(wpa_s, WPA_SCANNING); 5038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 50475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (scan_req != 2 && wpa_s->connect_without_scan) { 50575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) { 50675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (ssid == wpa_s->connect_without_scan) 50775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen break; 50875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen } 50975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen wpa_s->connect_without_scan = NULL; 51075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (ssid) { 51175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen wpa_printf(MSG_DEBUG, "Start a pre-selected network " 51275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen "without scan step"); 51375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen wpa_supplicant_associate(wpa_s, NULL, ssid); 51475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen return; 51575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen } 51675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen } 51775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 5188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Find the starting point from which to continue scanning */ 5198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid = wpa_s->conf->ssid; 5208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->prev_scan_ssid != WILDCARD_SSID_SCAN) { 5218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (ssid) { 5228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid == wpa_s->prev_scan_ssid) { 5238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid = ssid->next; 5248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 5258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid = ssid->next; 5278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 53075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (scan_req != 2 && wpa_s->conf->ap_scan == 2) { 53175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen wpa_s->connect_without_scan = NULL; 532c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpa_s->prev_scan_wildcard = 0; 5338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_assoc_try(wpa_s, ssid); 5348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 535e25ba1592df19d46a7a1e1a1fca1fb02ebd7be8fDmitry Shmidt#ifndef ANDROID 5368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (wpa_s->conf->ap_scan == 2) { 5378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 5388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * User-initiated scan request in ap_scan == 2; scan with 5398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wildcard SSID. 5408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 5418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid = NULL; 542e25ba1592df19d46a7a1e1a1fca1fb02ebd7be8fDmitry Shmidt#endif 5438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 5448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_ssid *start = ssid, *tssid; 5458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int freqs_set = 0; 5468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid == NULL && max_ssids > 1) 5478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid = wpa_s->conf->ssid; 5488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (ssid) { 5498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!ssid->disabled && ssid->scan_ssid) { 5508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_ascii(MSG_DEBUG, "Scan SSID", 5518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid->ssid, ssid->ssid_len); 5528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.ssids[params.num_ssids].ssid = 5538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid->ssid; 5548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.ssids[params.num_ssids].ssid_len = 5558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid->ssid_len; 5568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.num_ssids++; 5578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (params.num_ssids + 1 >= max_ssids) 5588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 5598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid = ssid->next; 5618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid == start) 5628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 5638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid == NULL && max_ssids > 1 && 5648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt start != wpa_s->conf->ssid) 5658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid = wpa_s->conf->ssid; 5668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (tssid = wpa_s->conf->ssid; tssid; tssid = tssid->next) { 5698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tssid->disabled) 5708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 5718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((params.freqs || !freqs_set) && tssid->scan_freq) { 5728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int_array_concat(¶ms.freqs, 5738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tssid->scan_freq); 5748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 5758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(params.freqs); 5768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.freqs = NULL; 5778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt freqs_set = 1; 5798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int_array_sort_unique(params.freqs); 5818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 583c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (ssid && max_ssids == 1) { 584c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt /* 585c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * If the driver is limited to 1 SSID at a time interleave 586c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * wildcard SSID scans with specific SSID scans to avoid 587c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * waiting a long time for a wildcard scan. 588c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt */ 589c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (!wpa_s->prev_scan_wildcard) { 590c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt params.ssids[0].ssid = NULL; 591c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt params.ssids[0].ssid_len = 0; 592c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpa_s->prev_scan_wildcard = 1; 593c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "Starting AP scan for " 594c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt "wildcard SSID (Interleave with specific)"); 595c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt } else { 596c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpa_s->prev_scan_ssid = ssid; 597c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpa_s->prev_scan_wildcard = 0; 598c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, 599c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt "Starting AP scan for specific SSID: %s", 600c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpa_ssid_txt(ssid->ssid, ssid->ssid_len)); 6018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 602c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt } else if (ssid) { 603c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt /* max_ssids > 1 */ 604c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 605c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpa_s->prev_scan_ssid = ssid; 606c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "Include wildcard SSID in " 607c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt "the scan request"); 608c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt params.num_ssids++; 6098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 6108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->prev_scan_ssid = WILDCARD_SSID_SCAN; 6118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.num_ssids++; 6128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "Starting AP scan for wildcard " 6138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "SSID"); 6148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6161f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_supplicant_optimize_freqs(wpa_s, ¶ms); 6171f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt extra_ie = wpa_supplicant_extra_ies(wpa_s, ¶ms); 6188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (params.freqs == NULL && wpa_s->next_scan_freqs) { 6208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "Optimize scan based on previously " 6218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "generated frequency list"); 6228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.freqs = wpa_s->next_scan_freqs; 6238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 6248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(wpa_s->next_scan_freqs); 6258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->next_scan_freqs = NULL; 6268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.filter_ssids = wpa_supplicant_build_filter_ssids( 6288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->conf, ¶ms.num_filter_ssids); 6291f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (extra_ie) { 6301f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt params.extra_ies = wpabuf_head(extra_ie); 6311f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt params.extra_ies_len = wpabuf_len(extra_ie); 6321f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 6331f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 6341f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef CONFIG_P2P 6351f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (wpa_s->p2p_in_provisioning) { 6361f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* 6371f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * The interface may not yet be in P2P mode, so we have to 6381f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * explicitly request P2P probe to disable CCK rates. 6391f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt */ 6401f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt params.p2p_probe = 1; 6411f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 6421f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* CONFIG_P2P */ 6438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = wpa_supplicant_trigger_scan(wpa_s, ¶ms); 6458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6461f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpabuf_free(extra_ie); 6478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(params.freqs); 6488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(params.filter_ssids); 6498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret) { 6518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(wpa_s, MSG_WARNING, "Failed to initiate AP scan"); 6528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (prev_state != wpa_s->wpa_state) 6538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_set_state(wpa_s, prev_state); 6548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_req_scan(wpa_s, 1, 0); 6558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 6608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_supplicant_req_scan - Schedule a scan for neighboring access points 6618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: Pointer to wpa_supplicant data 6628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sec: Number of seconds after which to scan 6638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @usec: Number of microseconds after which to scan 6648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 6658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function is used to schedule a scan for neighboring access points after 6668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * the specified time. 6678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 6688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpa_supplicant_req_scan(struct wpa_supplicant *wpa_s, int sec, int usec) 6698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 67081e9700b8fb135b898181ad3aeb44d39f0a01907Dmitry Shmidt#ifndef ANDROID 6718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* If there's at least one network that should be specifically scanned 6728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * then don't cancel the scan and reschedule. Some drivers do 6738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * background scanning which generates frequent scan results, and that 6748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * causes the specific SSID scan to get continually pushed back and 6758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * never happen, which causes hidden APs to never get probe-scanned. 6768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 6778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eloop_is_timeout_registered(wpa_supplicant_scan, wpa_s, NULL) && 6788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->conf->ap_scan == 1) { 6798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_ssid *ssid = wpa_s->conf->ssid; 6808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (ssid) { 6828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!ssid->disabled && ssid->scan_ssid) 6838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 6848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid = ssid->next; 6858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid) { 6878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "Not rescheduling scan to " 6888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "ensure that specific SSID scans occur"); 6898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 6908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 69281e9700b8fb135b898181ad3aeb44d39f0a01907Dmitry Shmidt#endif 6938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "Setting scan request: %d sec %d usec", 6948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sec, usec); 6958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(wpa_supplicant_scan, wpa_s, NULL); 6968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(sec, usec, wpa_supplicant_scan, wpa_s, NULL); 6978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 7011f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * wpa_supplicant_delayed_sched_scan - Request a delayed scheduled scan 7021f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * @wpa_s: Pointer to wpa_supplicant data 7031f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * @sec: Number of seconds after which to scan 7041f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * @usec: Number of microseconds after which to scan 7051f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * 7061f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * This function is used to schedule periodic scans for neighboring 7071f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * access points after the specified time. 7081f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt */ 7091f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtint wpa_supplicant_delayed_sched_scan(struct wpa_supplicant *wpa_s, 7101f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt int sec, int usec) 7111f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 7121f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (!wpa_s->sched_scan_supported) 7131f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return -1; 7141f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 7151f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt eloop_register_timeout(sec, usec, 7161f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_supplicant_delayed_sched_scan_timeout, 7171f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s, NULL); 7181f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 7191f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return 0; 7201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 7211f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 7221f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 7231f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt/** 7241f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * wpa_supplicant_req_sched_scan - Start a periodic scheduled scan 7251f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * @wpa_s: Pointer to wpa_supplicant data 7261f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * 7271f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * This function is used to schedule periodic scans for neighboring 7281f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * access points repeating the scan continuously. 7291f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt */ 7301f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtint wpa_supplicant_req_sched_scan(struct wpa_supplicant *wpa_s) 7311f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 7321f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct wpa_driver_scan_params params; 7331f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt enum wpa_states prev_state; 7341f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct wpa_ssid *ssid; 7351f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct wpabuf *wps_ie = NULL; 7361f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt int ret; 7371f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt unsigned int max_sched_scan_ssids; 7381f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt int wildcard = 0; 7391f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt int need_ssids; 7401f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 7411f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (!wpa_s->sched_scan_supported) 7421f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return -1; 7431f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 7441f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (wpa_s->max_sched_scan_ssids > WPAS_MAX_SCAN_SSIDS) 7451f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt max_sched_scan_ssids = WPAS_MAX_SCAN_SSIDS; 7461f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt else 7471f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt max_sched_scan_ssids = wpa_s->max_sched_scan_ssids; 7481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (max_sched_scan_ssids < 1) 7491f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return -1; 7501f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 7511f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (wpa_s->sched_scanning) { 7521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "Already sched scanning"); 7531f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return 0; 7541f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 7551f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 7561f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt need_ssids = 0; 7571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) { 7581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (!ssid->disabled && !ssid->scan_ssid) { 7591f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* Use wildcard SSID to find this network */ 7601f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wildcard = 1; 7611f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } else if (!ssid->disabled && ssid->ssid_len) 7621f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt need_ssids++; 7631f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 7641f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (wildcard) 7651f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt need_ssids++; 7661f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 7671f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (wpa_s->normal_scans < 3 && 7681f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt (need_ssids <= wpa_s->max_scan_ssids || 7691f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s->max_scan_ssids >= (int) max_sched_scan_ssids)) { 7701f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* 7711f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * When normal scan can speed up operations, use that for the 7721f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * first operations before starting the sched_scan to allow 7731f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * user space sleep more. We do this only if the normal scan 7741f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * has functionality that is suitable for this or if the 7751f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * sched_scan does not have better support for multiple SSIDs. 7761f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt */ 7771f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "Use normal scan instead of " 7781f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "sched_scan for initial scans (normal_scans=%d)", 7791f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s->normal_scans); 7801f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return -1; 7811f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 7821f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 7831f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt os_memset(¶ms, 0, sizeof(params)); 7841f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 7851f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* If we can't allocate space for the filters, we just don't filter */ 7861f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt params.filter_ssids = os_zalloc(wpa_s->max_match_sets * 7871f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt sizeof(struct wpa_driver_scan_filter)); 7881f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 7891f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt prev_state = wpa_s->wpa_state; 790687922c7347bdc3b4f8c921efe1d1388cb3baac0Dmitry Shmidt#ifndef ANDROID_P2P 7911f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (wpa_s->wpa_state == WPA_DISCONNECTED || 7921f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s->wpa_state == WPA_INACTIVE) 7931f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_supplicant_set_state(wpa_s, WPA_SCANNING); 794687922c7347bdc3b4f8c921efe1d1388cb3baac0Dmitry Shmidt#endif 7951f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 7961f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* Find the starting point from which to continue scanning */ 7971f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt ssid = wpa_s->conf->ssid; 7981f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (wpa_s->prev_sched_ssid) { 7991f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt while (ssid) { 8001f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (ssid == wpa_s->prev_sched_ssid) { 8011f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt ssid = ssid->next; 8021f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt break; 8031f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 8041f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt ssid = ssid->next; 8051f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 8061f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 8071f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 8081f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (!ssid || !wpa_s->prev_sched_ssid) { 8091f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "Beginning of SSID list"); 8101f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 8111f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s->sched_scan_interval = 10; 8121f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s->sched_scan_timeout = max_sched_scan_ssids * 2; 8131f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s->first_sched_scan = 1; 8141f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt ssid = wpa_s->conf->ssid; 8151f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s->prev_sched_ssid = ssid; 8161f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 8171f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 8181f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (wildcard) { 8191f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "Add wildcard SSID to sched_scan"); 8201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt params.num_ssids++; 8211f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 8221f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 8231f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt while (ssid) { 8241f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (ssid->disabled) 8251f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt goto next; 8261f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 8271f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (params.num_filter_ssids < wpa_s->max_match_sets && 8281f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt params.filter_ssids && ssid->ssid && ssid->ssid_len) { 8291f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "add to filter ssid: %s", 8301f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_ssid_txt(ssid->ssid, ssid->ssid_len)); 8311f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt os_memcpy(params.filter_ssids[params.num_filter_ssids].ssid, 8321f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt ssid->ssid, ssid->ssid_len); 8331f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt params.filter_ssids[params.num_filter_ssids].ssid_len = 8341f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt ssid->ssid_len; 8351f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt params.num_filter_ssids++; 8361f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } else if (params.filter_ssids && ssid->ssid && ssid->ssid_len) 8371f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt { 8381f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "Not enough room for SSID " 8391f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "filter for sched_scan - drop filter"); 8401f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt os_free(params.filter_ssids); 8411f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt params.filter_ssids = NULL; 8421f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt params.num_filter_ssids = 0; 8431f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 8441f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 8451f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (ssid->scan_ssid && ssid->ssid && ssid->ssid_len) { 8461f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (params.num_ssids == max_sched_scan_ssids) 8471f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt break; /* only room for broadcast SSID */ 8481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, 8491f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "add to active scan ssid: %s", 8501f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_ssid_txt(ssid->ssid, ssid->ssid_len)); 8511f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt params.ssids[params.num_ssids].ssid = 8521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt ssid->ssid; 8531f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt params.ssids[params.num_ssids].ssid_len = 8541f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt ssid->ssid_len; 8551f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt params.num_ssids++; 8561f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (params.num_ssids >= max_sched_scan_ssids) { 8571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s->prev_sched_ssid = ssid; 8581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt break; 8591f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 8601f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 8611f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 8621f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt next: 8631f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s->prev_sched_ssid = ssid; 8641f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt ssid = ssid->next; 8651f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 8661f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 8671f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (params.num_filter_ssids == 0) { 8681f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt os_free(params.filter_ssids); 8691f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt params.filter_ssids = NULL; 8701f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 8711f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 8721f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (wpa_s->wps) 8731f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wps_ie = wpa_supplicant_extra_ies(wpa_s, ¶ms); 8741f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 8751f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (ssid || !wpa_s->first_sched_scan) { 8761f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, 8771f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "Starting sched scan: interval %d (no timeout)", 8781f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s->sched_scan_interval); 8791f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } else { 8801f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, 8811f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "Starting sched scan: interval %d timeout %d", 8821f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s->sched_scan_interval, wpa_s->sched_scan_timeout); 8831f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 8841f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 8851f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt ret = wpa_supplicant_start_sched_scan(wpa_s, ¶ms, 8861f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s->sched_scan_interval); 8871f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpabuf_free(wps_ie); 8881f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt os_free(params.filter_ssids); 8891f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (ret) { 8901f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_msg(wpa_s, MSG_WARNING, "Failed to initiate sched scan"); 8911f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (prev_state != wpa_s->wpa_state) 8921f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_supplicant_set_state(wpa_s, prev_state); 8931f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return ret; 8941f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 8951f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 8961f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* If we have more SSIDs to scan, add a timeout so we scan them too */ 8971f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (ssid || !wpa_s->first_sched_scan) { 8981f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s->sched_scan_timed_out = 0; 8991f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt eloop_register_timeout(wpa_s->sched_scan_timeout, 0, 9001f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_supplicant_sched_scan_timeout, 9011f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s, NULL); 9021f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s->first_sched_scan = 0; 9031f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s->sched_scan_timeout /= 2; 9041f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s->sched_scan_interval *= 2; 9051f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 9061f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 9071f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return 0; 9081f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 9091f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 9101f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 9111f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt/** 9128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_supplicant_cancel_scan - Cancel a scheduled scan request 9138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: Pointer to wpa_supplicant data 9148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 9158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function is used to cancel a scan request scheduled with 9168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_supplicant_req_scan(). 9178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 9188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpa_supplicant_cancel_scan(struct wpa_supplicant *wpa_s) 9198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "Cancelling scan request"); 9218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(wpa_supplicant_scan, wpa_s, NULL); 922c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt#ifdef ANDROID 92320df807cb700c516ff346732f1bc8f914d0d26d8Dmitry Shmidt wpa_supplicant_notify_scanning(wpa_s, 0); 924c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt#endif 9258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9281f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt/** 9291f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * wpa_supplicant_cancel_sched_scan - Stop running scheduled scans 9301f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * @wpa_s: Pointer to wpa_supplicant data 9311f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * 9321f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * This function is used to stop a periodic scheduled scan. 9331f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt */ 9341f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtvoid wpa_supplicant_cancel_sched_scan(struct wpa_supplicant *wpa_s) 9351f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 9361f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (!wpa_s->sched_scanning) 9371f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return; 9381f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 9391f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "Cancelling sched scan"); 9401f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt eloop_cancel_timeout(wpa_supplicant_sched_scan_timeout, wpa_s, NULL); 9411f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_supplicant_stop_sched_scan(wpa_s); 9421f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 9431f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 9441f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 9458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpa_supplicant_notify_scanning(struct wpa_supplicant *wpa_s, 9468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int scanning) 9478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->scanning != scanning) { 949687922c7347bdc3b4f8c921efe1d1388cb3baac0Dmitry Shmidt#ifdef ANDROID_P2P 950687922c7347bdc3b4f8c921efe1d1388cb3baac0Dmitry Shmidt if(!wpa_s->sched_scanning) 951687922c7347bdc3b4f8c921efe1d1388cb3baac0Dmitry Shmidt wpa_s->scanning = scanning; 952687922c7347bdc3b4f8c921efe1d1388cb3baac0Dmitry Shmidt#else 9538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->scanning = scanning; 954687922c7347bdc3b4f8c921efe1d1388cb3baac0Dmitry Shmidt#endif 9558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_notify_scanning(wpa_s); 9568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_scan_get_max_rate(const struct wpa_scan_res *res) 9618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int rate = 0; 9638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *ie; 9648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 9658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ie = wpa_scan_get_ie(res, WLAN_EID_SUPP_RATES); 9678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; ie && i < ie[1]; i++) { 9688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((ie[i + 2] & 0x7f) > rate) 9698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rate = ie[i + 2] & 0x7f; 9708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ie = wpa_scan_get_ie(res, WLAN_EID_EXT_SUPP_RATES); 9738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; ie && i < ie[1]; i++) { 9748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((ie[i + 2] & 0x7f) > rate) 9758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rate = ie[i + 2] & 0x7f; 9768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return rate; 9798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtconst u8 * wpa_scan_get_ie(const struct wpa_scan_res *res, u8 ie) 9838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *end, *pos; 9858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = (const u8 *) (res + 1); 9878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = pos + res->ie_len; 9888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (pos + 1 < end) { 9908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos + 2 + pos[1] > end) 9918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 9928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos[0] == ie) 9938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos; 9948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 2 + pos[1]; 9958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 9988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtconst u8 * wpa_scan_get_vendor_ie(const struct wpa_scan_res *res, 10028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u32 vendor_type) 10038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 10048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *end, *pos; 10058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = (const u8 *) (res + 1); 10078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = pos + res->ie_len; 10088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (pos + 1 < end) { 10108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos + 2 + pos[1] > end) 10118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 10128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 && 10138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt vendor_type == WPA_GET_BE32(&pos[2])) 10148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos; 10158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 2 + pos[1]; 10168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 10198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct wpabuf * wpa_scan_get_vendor_ie_multi(const struct wpa_scan_res *res, 10238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u32 vendor_type) 10248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 10258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *buf; 10268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *end, *pos; 10278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf = wpabuf_alloc(res->ie_len); 10298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (buf == NULL) 10308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 10318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = (const u8 *) (res + 1); 10338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = pos + res->ie_len; 10348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (pos + 1 < end) { 10368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos + 2 + pos[1] > end) 10378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 10388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 && 10398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt vendor_type == WPA_GET_BE32(&pos[2])) 10408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_data(buf, pos + 2 + 4, pos[1] - 4); 10418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 2 + pos[1]; 10428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpabuf_len(buf) == 0) { 10458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(buf); 10468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf = NULL; 10478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return buf; 10508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct wpabuf * wpa_scan_get_vendor_ie_multi_beacon( 10548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct wpa_scan_res *res, u32 vendor_type) 10558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 10568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *buf; 10578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *end, *pos; 10588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res->beacon_ie_len == 0) 10608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 10618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf = wpabuf_alloc(res->beacon_ie_len); 10628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (buf == NULL) 10638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 10648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = (const u8 *) (res + 1); 10668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += res->ie_len; 10678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = pos + res->beacon_ie_len; 10688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (pos + 1 < end) { 10708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos + 2 + pos[1] > end) 10718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 10728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 && 10738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt vendor_type == WPA_GET_BE32(&pos[2])) 10748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_data(buf, pos + 2 + 4, pos[1] - 4); 10758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 2 + pos[1]; 10768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpabuf_len(buf) == 0) { 10798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(buf); 10808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf = NULL; 10818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return buf; 10848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10871f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt/* 10881f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * Channels with a great SNR can operate at full rate. What is a great SNR? 10891f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * This doc https://supportforums.cisco.com/docs/DOC-12954 says, "the general 10901f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * rule of thumb is that any SNR above 20 is good." This one 10911f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * http://www.cisco.com/en/US/tech/tk722/tk809/technologies_q_and_a_item09186a00805e9a96.shtml#qa23 10921f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * recommends 25 as a minimum SNR for 54 Mbps data rate. 30 is chosen here as a 10931f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * conservative value. 10941f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt */ 10951f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#define GREAT_SNR 30 10961f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 10978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* Compare function for sorting scan results. Return >0 if @b is considered 10988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * better. */ 10998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_scan_result_compar(const void *a, const void *b) 11008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 11011f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#define IS_5GHZ(n) (n > 4000) 11021f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#define MIN(a,b) a < b ? a : b 11038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_scan_res **_wa = (void *) a; 11048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_scan_res **_wb = (void *) b; 11058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_scan_res *wa = *_wa; 11068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_scan_res *wb = *_wb; 11078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int wpa_a, wpa_b, maxrate_a, maxrate_b; 11081f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt int snr_a, snr_b; 11098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* WPA/WPA2 support preferred */ 11118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_a = wpa_scan_get_vendor_ie(wa, WPA_IE_VENDOR_TYPE) != NULL || 11128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_scan_get_ie(wa, WLAN_EID_RSN) != NULL; 11138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_b = wpa_scan_get_vendor_ie(wb, WPA_IE_VENDOR_TYPE) != NULL || 11148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_scan_get_ie(wb, WLAN_EID_RSN) != NULL; 11158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_b && !wpa_a) 11178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 11188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!wpa_b && wpa_a) 11198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 11208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* privacy support preferred */ 11228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((wa->caps & IEEE80211_CAP_PRIVACY) == 0 && 11238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (wb->caps & IEEE80211_CAP_PRIVACY)) 11248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 11258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((wa->caps & IEEE80211_CAP_PRIVACY) && 11268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (wb->caps & IEEE80211_CAP_PRIVACY) == 0) 11278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 11288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11291f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if ((wa->flags & wb->flags & WPA_SCAN_LEVEL_DBM) && 11301f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt !((wa->flags | wb->flags) & WPA_SCAN_NOISE_INVALID)) { 11311f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt snr_a = MIN(wa->level - wa->noise, GREAT_SNR); 11321f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt snr_b = MIN(wb->level - wb->noise, GREAT_SNR); 11331f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } else { 11341f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* Not suitable information to calculate SNR, so use level */ 11351f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt snr_a = wa->level; 11361f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt snr_b = wb->level; 11371f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 11381f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 11391f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* best/max rate preferred if SNR close enough */ 11401f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if ((snr_a && snr_b && abs(snr_b - snr_a) < 5) || 11418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (wa->qual && wb->qual && abs(wb->qual - wa->qual) < 10)) { 11428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt maxrate_a = wpa_scan_get_max_rate(wa); 11438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt maxrate_b = wpa_scan_get_max_rate(wb); 11448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (maxrate_a != maxrate_b) 11458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return maxrate_b - maxrate_a; 11461f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (IS_5GHZ(wa->freq) ^ IS_5GHZ(wb->freq)) 11471f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return IS_5GHZ(wa->freq) ? -1 : 1; 11488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* use freq for channel preference */ 11518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* all things being equal, use SNR; if SNRs are 11538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * identical, use quality values since some drivers may only report 11548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * that value and leave the signal level zero */ 11551f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (snr_b == snr_a) 11568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return wb->qual - wa->qual; 11571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return snr_b - snr_a; 11581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#undef MIN 11591f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#undef IS_5GHZ 11608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 11618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_WPS 11648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* Compare function for sorting scan results when searching a WPS AP for 11658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * provisioning. Return >0 if @b is considered better. */ 11668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_scan_result_wps_compar(const void *a, const void *b) 11678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 11688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_scan_res **_wa = (void *) a; 11698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_scan_res **_wb = (void *) b; 11708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_scan_res *wa = *_wa; 11718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_scan_res *wb = *_wb; 11728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int uses_wps_a, uses_wps_b; 11738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *wps_a, *wps_b; 11748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 11758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Optimization - check WPS IE existence before allocated memory and 11778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * doing full reassembly. */ 11788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt uses_wps_a = wpa_scan_get_vendor_ie(wa, WPS_IE_VENDOR_TYPE) != NULL; 11798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt uses_wps_b = wpa_scan_get_vendor_ie(wb, WPS_IE_VENDOR_TYPE) != NULL; 11808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (uses_wps_a && !uses_wps_b) 11818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 11828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!uses_wps_a && uses_wps_b) 11838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 11848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (uses_wps_a && uses_wps_b) { 11868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wps_a = wpa_scan_get_vendor_ie_multi(wa, WPS_IE_VENDOR_TYPE); 11878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wps_b = wpa_scan_get_vendor_ie_multi(wb, WPS_IE_VENDOR_TYPE); 11888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = wps_ap_priority_compar(wps_a, wps_b); 11898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(wps_a); 11908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(wps_b); 11918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res) 11928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return res; 11938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 11968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Do not use current AP security policy as a sorting criteria during 11978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * WPS provisioning step since the AP may get reconfigured at the 11988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * completion of provisioning. 11998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 12008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* all things being equal, use signal level; if signal levels are 12028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * identical, use quality values since some drivers may only report 12038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * that value and leave the signal level zero */ 12048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wb->level == wa->level) 12058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return wb->qual - wa->qual; 12068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return wb->level - wa->level; 12078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 12088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_WPS */ 12098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12111f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic void dump_scan_res(struct wpa_scan_results *scan_res) 12121f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 12131f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifndef CONFIG_NO_STDOUT_DEBUG 12141f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt size_t i; 12151f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 12161f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (scan_res->res == NULL || scan_res->num == 0) 12171f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return; 12181f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 12191f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_printf(MSG_EXCESSIVE, "Sorted scan results"); 12201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 12211f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt for (i = 0; i < scan_res->num; i++) { 12221f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct wpa_scan_res *r = scan_res->res[i]; 12231f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if ((r->flags & (WPA_SCAN_LEVEL_DBM | WPA_SCAN_NOISE_INVALID)) 12241f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt == WPA_SCAN_LEVEL_DBM) { 12251f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt int snr = r->level - r->noise; 12261f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_printf(MSG_EXCESSIVE, MACSTR " freq=%d qual=%d " 12271f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "noise=%d level=%d snr=%d%s flags=0x%x", 12281f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt MAC2STR(r->bssid), r->freq, r->qual, 12291f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt r->noise, r->level, snr, 12301f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt snr >= GREAT_SNR ? "*" : "", r->flags); 12311f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } else { 12321f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_printf(MSG_EXCESSIVE, MACSTR " freq=%d qual=%d " 12331f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "noise=%d level=%d flags=0x%x", 12341f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt MAC2STR(r->bssid), r->freq, r->qual, 12351f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt r->noise, r->level, r->flags); 12361f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 12371f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 12381f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* CONFIG_NO_STDOUT_DEBUG */ 12391f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 12401f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 12411f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 12428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 12438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_supplicant_get_scan_results - Get scan results 12448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: Pointer to wpa_supplicant data 12458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @info: Information about what was scanned or %NULL if not available 12468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @new_scan: Whether a new scan was performed 12478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Scan results, %NULL on failure 12488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 12498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function request the current scan results from the driver and updates 12508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * the local BSS list wpa_s->bss. The caller is responsible for freeing the 12518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * results with wpa_scan_results_free(). 12528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 12538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct wpa_scan_results * 12548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtwpa_supplicant_get_scan_results(struct wpa_supplicant *wpa_s, 12558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct scan_info *info, int new_scan) 12568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 12578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_scan_results *scan_res; 12588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t i; 12598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int (*compar)(const void *, const void *) = wpa_scan_result_compar; 12608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12611f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt scan_res = wpa_drv_get_scan_results2(wpa_s); 12628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (scan_res == NULL) { 12638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "Failed to get scan results"); 12648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 12658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_WPS 12688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpas_wps_in_progress(wpa_s)) { 12698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "WPS: Order scan results with WPS " 12708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "provisioning rules"); 12718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt compar = wpa_scan_result_wps_compar; 12728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_WPS */ 12748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt qsort(scan_res->res, scan_res->num, sizeof(struct wpa_scan_res *), 12768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt compar); 12771f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt dump_scan_res(scan_res); 12788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_bss_update_start(wpa_s); 12808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < scan_res->num; i++) 12818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_bss_update_scan_res(wpa_s, scan_res->res[i]); 12828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_bss_update_end(wpa_s, info, new_scan); 12838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return scan_res; 12858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 12868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpa_supplicant_update_scan_results(struct wpa_supplicant *wpa_s) 12898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 12908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_scan_results *scan_res; 12918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt scan_res = wpa_supplicant_get_scan_results(wpa_s, NULL, 0); 12928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (scan_res == NULL) 12938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 12948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_scan_results_free(scan_res); 12958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 12978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1298