scan.c revision 051af73b8f8014eff33330aead0f36944b3403e6
18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * WPA Supplicant - Scanning 3a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * Copyright (c) 2003-2012, 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" 143a787e6f7c987ba5a9a56a2066467d20ab40ec58Dmitry Shmidt#include "common/wpa_ctrl.h" 158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "config.h" 168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "wpa_supplicant_i.h" 178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "driver_i.h" 188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "wps_supplicant.h" 198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "p2p_supplicant.h" 208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "p2p/p2p.h" 2104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#include "hs20_supplicant.h" 228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "notify.h" 238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "bss.h" 24051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt#include "gas_query.h" 258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "scan.h" 268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpa_supplicant_gen_assoc_event(struct wpa_supplicant *wpa_s) 298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_ssid *ssid; 318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt union wpa_event_data data; 328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid = wpa_supplicant_get_ssid(wpa_s); 348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid == NULL) 358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->current_ssid == NULL) { 388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->current_ssid = ssid; 398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->current_ssid != NULL) 408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_notify_network_changed(wpa_s); 418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_initiate_eapol(wpa_s); 438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "Already associated with a configured " 448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "network - generating associated event"); 458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&data, 0, sizeof(data)); 468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_event(wpa_s, EVENT_ASSOC, &data); 478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_WPS 511f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic int wpas_wps_in_use(struct wpa_supplicant *wpa_s, 528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum wps_request_type *req_type) 538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_ssid *ssid; 558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int wps = 0; 568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) { 588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!(ssid->key_mgmt & WPA_KEY_MGMT_WPS)) 598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wps = 1; 628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *req_type = wpas_wps_get_req_type(ssid); 638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!ssid->eap.phase1) 648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_strstr(ssid->eap.phase1, "pbc=1")) 678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 2; 688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 701f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef CONFIG_P2P 71d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (!wpa_s->global->p2p_disabled && wpa_s->global->p2p && 72d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt !wpa_s->conf->p2p_disabled) { 73c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpa_s->wps->dev.p2p = 1; 74c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (!wps) { 75c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wps = 1; 76c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt *req_type = WPS_REQ_ENROLLEE_INFO; 77c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt } 781f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 791f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* CONFIG_P2P */ 801f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return wps; 828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_WPS */ 848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 86a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt/** 87a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * wpa_supplicant_enabled_networks - Check whether there are enabled networks 88a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * @wpa_s: Pointer to wpa_supplicant data 89a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * Returns: 0 if no networks are enabled, >0 if networks are enabled 90a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * 91a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * This function is used to figure out whether any networks (or Interworking 92a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * with enabled credentials and auto_interworking) are present in the current 93a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * configuration. 94a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt */ 9504949598a23f501be6eec21697465fd46a28840aDmitry Shmidtint wpa_supplicant_enabled_networks(struct wpa_supplicant *wpa_s) 968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct wpa_ssid *ssid = wpa_s->conf->ssid; 98aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt int count = 0, disabled = 0; 998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (ssid) { 10004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (!wpas_network_disabled(wpa_s, ssid)) 1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt count++; 102aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt else 103aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt disabled++; 1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid = ssid->next; 1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (wpa_s->conf->cred && wpa_s->conf->interworking && 10761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_s->conf->auto_interworking) 10861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt count++; 109aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt if (count == 0 && disabled > 0) { 110aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "No enabled networks (%d disabled " 111aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt "networks)", disabled); 112aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt } 1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return count; 1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpa_supplicant_assoc_try(struct wpa_supplicant *wpa_s, 1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_ssid *ssid) 1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (ssid) { 12104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (!wpas_network_disabled(wpa_s, ssid)) 1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid = ssid->next; 1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* ap_scan=2 mode - try to associate with each SSID. */ 1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid == NULL) { 1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "wpa_supplicant_assoc_try: Reached " 1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "end of scan list - go back to beginning"); 1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->prev_scan_ssid = WILDCARD_SSID_SCAN; 1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_req_scan(wpa_s, 0, 0); 1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid->next) { 1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Continue from the next SSID on the next attempt. */ 1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->prev_scan_ssid = ssid; 1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Start from the beginning of the SSID list. */ 1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->prev_scan_ssid = WILDCARD_SSID_SCAN; 1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_associate(wpa_s, NULL, ssid); 1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int int_array_len(const int *a) 1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; a && a[i]; i++) 1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ; 1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return i; 1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void int_array_concat(int **res, const int *a) 1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int reslen, alen, i; 1578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int *n; 1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reslen = int_array_len(*res); 1608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt alen = int_array_len(a); 1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt n = os_realloc_array(*res, reslen + alen + 1, sizeof(int)); 1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (n == NULL) { 1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(*res); 1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *res = NULL; 1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i <= alen; i++) 1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt n[reslen + i] = a[i]; 1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *res = n; 1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int freq_cmp(const void *a, const void *b) 1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int _a = *(int *) a; 1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int _b = *(int *) b; 1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (_a == 0) 1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (_b == 0) 1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return _a - _b; 1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void int_array_sort_unique(int *a) 1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int alen; 1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i, j; 1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (a == NULL) 1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt alen = int_array_len(a); 1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt qsort(a, alen, sizeof(int), freq_cmp); 1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt i = 0; 1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt j = 1; 2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (a[i] && a[j]) { 2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (a[i] == a[j]) { 2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt j++; 2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt a[++i] = a[j++]; 2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (a[i]) 2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt i++; 2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt a[i] = 0; 2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 213a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt/** 214a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * wpa_supplicant_trigger_scan - Request driver to start a scan 215a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * @wpa_s: Pointer to wpa_supplicant data 216a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * @params: Scan parameters 217a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * Returns: 0 on success, -1 on failure 218a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt */ 2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpa_supplicant_trigger_scan(struct wpa_supplicant *wpa_s, 2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_driver_scan_params *params) 2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret; 2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_notify_scanning(wpa_s, 1); 2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2261f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt ret = wpa_drv_scan(wpa_s, params); 2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret) { 2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_notify_scanning(wpa_s, 0); 2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_notify_scan_done(wpa_s, 0); 2301f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } else { 231444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt os_get_time(&wpa_s->scan_trigger_time); 2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->scan_runs++; 2331f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s->normal_scans++; 2341f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 2351f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 2361f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return ret; 2371f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 2381f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 2391f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 2401f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic void 2411f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtwpa_supplicant_delayed_sched_scan_timeout(void *eloop_ctx, void *timeout_ctx) 2421f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 2431f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct wpa_supplicant *wpa_s = eloop_ctx; 2441f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 2451f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "Starting delayed sched scan"); 2461f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 2471f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (wpa_supplicant_req_sched_scan(wpa_s)) 2481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_supplicant_req_scan(wpa_s, 0, 0); 2491f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 2501f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 2511f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 2521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic void 2531f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtwpa_supplicant_sched_scan_timeout(void *eloop_ctx, void *timeout_ctx) 2541f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 2551f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct wpa_supplicant *wpa_s = eloop_ctx; 2561f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 2571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "Sched scan timeout - stopping it"); 2581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 2591f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s->sched_scan_timed_out = 1; 2601f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_supplicant_cancel_sched_scan(wpa_s); 2611f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 2621f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 2631f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 2641f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic int 2651f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtwpa_supplicant_start_sched_scan(struct wpa_supplicant *wpa_s, 2661f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct wpa_driver_scan_params *params, 2671f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt int interval) 2681f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 2691f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt int ret; 270b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt 2711f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_supplicant_notify_scanning(wpa_s, 1); 2721f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt ret = wpa_drv_sched_scan(wpa_s, params, interval * 1000); 2731f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (ret) 2741f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_supplicant_notify_scanning(wpa_s, 0); 275687922c7347bdc3b4f8c921efe1d1388cb3baac0Dmitry Shmidt else { 2761f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s->sched_scanning = 1; 277687922c7347bdc3b4f8c921efe1d1388cb3baac0Dmitry Shmidt } 2781f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 2791f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return ret; 2801f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 2811f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 2821f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 2831f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic int wpa_supplicant_stop_sched_scan(struct wpa_supplicant *wpa_s) 2841f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 2851f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt int ret; 2861f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 2871f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt ret = wpa_drv_stop_sched_scan(wpa_s); 2881f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (ret) { 2891f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "stopping sched_scan failed!"); 2901f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* TODO: what to do if stopping fails? */ 2911f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return -1; 2921f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 2938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 2958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpa_driver_scan_filter * 2998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtwpa_supplicant_build_filter_ssids(struct wpa_config *conf, size_t *num_ssids) 3008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_driver_scan_filter *ssids; 3028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_ssid *ssid; 3038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t count; 3048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *num_ssids = 0; 3068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!conf->filter_ssids) 3078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 3088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (count = 0, ssid = conf->ssid; ssid; ssid = ssid->next) { 3108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid->ssid && ssid->ssid_len) 3118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt count++; 3128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (count == 0) 3148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 3158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssids = os_zalloc(count * sizeof(struct wpa_driver_scan_filter)); 3168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssids == NULL) 3178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 3188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (ssid = conf->ssid; ssid; ssid = ssid->next) { 3208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!ssid->ssid || !ssid->ssid_len) 3218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 3228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(ssids[*num_ssids].ssid, ssid->ssid, ssid->ssid_len); 3238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssids[*num_ssids].ssid_len = ssid->ssid_len; 3248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (*num_ssids)++; 3258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ssids; 3288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3311f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic void wpa_supplicant_optimize_freqs( 3321f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct wpa_supplicant *wpa_s, struct wpa_driver_scan_params *params) 3338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3341f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef CONFIG_P2P 3351f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (params->freqs == NULL && wpa_s->p2p_in_provisioning && 3361f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s->go_params) { 3371f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* Optimize provisioning state scan based on GO information */ 3381f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (wpa_s->p2p_in_provisioning < 5 && 3391f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s->go_params->freq > 0) { 3401f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Scan only GO " 3411f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "preferred frequency %d MHz", 3421f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s->go_params->freq); 3431f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt params->freqs = os_zalloc(2 * sizeof(int)); 3441f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (params->freqs) 3451f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt params->freqs[0] = wpa_s->go_params->freq; 3461f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } else if (wpa_s->p2p_in_provisioning < 8 && 3471f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s->go_params->freq_list[0]) { 3481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Scan only common " 3491f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "channels"); 3501f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt int_array_concat(¶ms->freqs, 3511f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s->go_params->freq_list); 3521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (params->freqs) 3531f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt int_array_sort_unique(params->freqs); 3541f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 3551f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s->p2p_in_provisioning++; 3561f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 3571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* CONFIG_P2P */ 3581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 3591f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef CONFIG_WPS 3601f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (params->freqs == NULL && wpa_s->after_wps && wpa_s->wps_freq) { 3611f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* 3621f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * Optimize post-provisioning scan based on channel used 3631f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * during provisioning. 3641f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt */ 3651f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "WPS: Scan only frequency %u MHz " 3661f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "that was used during provisioning", wpa_s->wps_freq); 3671f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt params->freqs = os_zalloc(2 * sizeof(int)); 3681f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (params->freqs) 3691f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt params->freqs[0] = wpa_s->wps_freq; 3701f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s->after_wps--; 3711f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 3721f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 373c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (params->freqs == NULL && wpa_s->known_wps_freq && wpa_s->wps_freq) 374c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt { 375c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt /* Optimize provisioning scan based on already known channel */ 376c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "WPS: Scan only frequency %u MHz", 377c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpa_s->wps_freq); 378c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt params->freqs = os_zalloc(2 * sizeof(int)); 379c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (params->freqs) 380c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt params->freqs[0] = wpa_s->wps_freq; 381c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpa_s->known_wps_freq = 0; /* only do this once */ 382c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt } 3831f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* CONFIG_WPS */ 3841f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 3851f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 3861f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 3871f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef CONFIG_INTERWORKING 3881f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic void wpas_add_interworking_elements(struct wpa_supplicant *wpa_s, 3891f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct wpabuf *buf) 3901f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 3911f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (wpa_s->conf->interworking == 0) 3921f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return; 3931f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 3941f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpabuf_put_u8(buf, WLAN_EID_EXT_CAPAB); 3951f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpabuf_put_u8(buf, 4); 3961f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpabuf_put_u8(buf, 0x00); 3971f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpabuf_put_u8(buf, 0x00); 3981f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpabuf_put_u8(buf, 0x00); 3991f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpabuf_put_u8(buf, 0x80); /* Bit 31 - Interworking */ 4001f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 4011f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpabuf_put_u8(buf, WLAN_EID_INTERWORKING); 4021f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpabuf_put_u8(buf, is_zero_ether_addr(wpa_s->conf->hessid) ? 1 : 4031f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 1 + ETH_ALEN); 4041f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpabuf_put_u8(buf, wpa_s->conf->access_network_type); 4051f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* No Venue Info */ 4061f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (!is_zero_ether_addr(wpa_s->conf->hessid)) 4071f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpabuf_put_data(buf, wpa_s->conf->hessid, ETH_ALEN); 4081f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 4091f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* CONFIG_INTERWORKING */ 4101f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 4111f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 41261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtstatic struct wpabuf * wpa_supplicant_extra_ies(struct wpa_supplicant *wpa_s) 4131f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 4141f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct wpabuf *extra_ie = NULL; 4158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_WPS 4168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int wps = 0; 4178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum wps_request_type req_type = WPS_REQ_ENROLLEE_INFO; 4188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_WPS */ 4191f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 4201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef CONFIG_INTERWORKING 4211f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (wpa_s->conf->interworking && 4221f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpabuf_resize(&extra_ie, 100) == 0) 4231f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpas_add_interworking_elements(wpa_s, extra_ie); 4241f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* CONFIG_INTERWORKING */ 4251f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 4261f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef CONFIG_WPS 4271f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wps = wpas_wps_in_use(wpa_s, &req_type); 4281f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 4291f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (wps) { 4301f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct wpabuf *wps_ie; 43104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wps_ie = wps_build_probe_req_ie(wps == 2 ? DEV_PW_PUSHBUTTON : 43204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt DEV_PW_DEFAULT, 43304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt &wpa_s->wps->dev, 4341f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s->wps->uuid, req_type, 4351f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 0, NULL); 4361f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (wps_ie) { 4371f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (wpabuf_resize(&extra_ie, wpabuf_len(wps_ie)) == 0) 4381f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpabuf_put_buf(extra_ie, wps_ie); 4391f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpabuf_free(wps_ie); 4401f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 4411f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 4421f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 4431f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef CONFIG_P2P 4441f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (wps) { 4451f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt size_t ielen = p2p_scan_ie_buf_len(wpa_s->global->p2p); 4461f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (wpabuf_resize(&extra_ie, ielen) == 0) 4471f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpas_p2p_scan_ie(wpa_s, extra_ie); 4481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 4491f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* CONFIG_P2P */ 4501f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 4511f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* CONFIG_WPS */ 4521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 45351b6ea882f234c14cd1fe1332a3840cf61fafccaDmitry Shmidt#ifdef CONFIG_HS20 45451b6ea882f234c14cd1fe1332a3840cf61fafccaDmitry Shmidt if (wpa_s->conf->hs20 && wpabuf_resize(&extra_ie, 7) == 0) 45551b6ea882f234c14cd1fe1332a3840cf61fafccaDmitry Shmidt wpas_hs20_add_indication(extra_ie); 45651b6ea882f234c14cd1fe1332a3840cf61fafccaDmitry Shmidt#endif /* CONFIG_HS20 */ 45751b6ea882f234c14cd1fe1332a3840cf61fafccaDmitry Shmidt 4581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return extra_ie; 4591f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 4601f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 4611f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 462d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt#ifdef CONFIG_P2P 463d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 464d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt/* 465d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt * Check whether there are any enabled networks or credentials that could be 466d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt * used for a non-P2P connection. 467d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt */ 468d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidtstatic int non_p2p_network_enabled(struct wpa_supplicant *wpa_s) 469d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt{ 470d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt struct wpa_ssid *ssid; 471d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 472d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) { 473d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (wpas_network_disabled(wpa_s, ssid)) 474d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt continue; 475d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (!ssid->p2p_group) 476d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return 1; 477d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt } 478d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 479d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (wpa_s->conf->cred && wpa_s->conf->interworking && 480d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_s->conf->auto_interworking) 481d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return 1; 482d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 483d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return 0; 484d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt} 485d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 486ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt#endif /* CONFIG_P2P */ 487d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 488d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 489b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidtstatic struct hostapd_hw_modes * get_mode(struct hostapd_hw_modes *modes, 490b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt u16 num_modes, 491b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt enum hostapd_hw_mode mode) 492b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt{ 493b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt u16 i; 494b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt 495b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt for (i = 0; i < num_modes; i++) { 496b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt if (modes[i].mode == mode) 497b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt return &modes[i]; 498b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt } 499b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt 500b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt return NULL; 501b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt} 502b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt 503b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt 504b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidtstatic void wpa_setband_scan_freqs_list(struct wpa_supplicant *wpa_s, 505b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt enum hostapd_hw_mode band, 506b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt struct wpa_driver_scan_params *params) 507b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt{ 508b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt /* Include only supported channels for the specified band */ 509b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt struct hostapd_hw_modes *mode; 510b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt int count, i; 511b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt 512b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt mode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes, band); 513b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt if (mode == NULL) { 514b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt /* No channels supported in this band - use empty list */ 515b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt params->freqs = os_zalloc(sizeof(int)); 516b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt return; 517b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt } 518b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt 519b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt params->freqs = os_zalloc((mode->num_channels + 1) * sizeof(int)); 520b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt if (params->freqs == NULL) 521b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt return; 522b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt for (count = 0, i = 0; i < mode->num_channels; i++) { 523b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt if (mode->channels[i].flag & HOSTAPD_CHAN_DISABLED) 524b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt continue; 525b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt params->freqs[count++] = mode->channels[i].freq; 526b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt } 527b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt} 528b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt 529b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt 530b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidtstatic void wpa_setband_scan_freqs(struct wpa_supplicant *wpa_s, 531b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt struct wpa_driver_scan_params *params) 532b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt{ 533b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt if (wpa_s->hw.modes == NULL) 534b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt return; /* unknown what channels the driver supports */ 535b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt if (params->freqs) 536b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt return; /* already using a limited channel set */ 537b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt if (wpa_s->setband == WPA_SETBAND_5G) 538b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt wpa_setband_scan_freqs_list(wpa_s, HOSTAPD_MODE_IEEE80211A, 539b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt params); 540b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt else if (wpa_s->setband == WPA_SETBAND_2G) 541b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt wpa_setband_scan_freqs_list(wpa_s, HOSTAPD_MODE_IEEE80211G, 542b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt params); 543b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt} 544b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt 545b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt 5461f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic void wpa_supplicant_scan(void *eloop_ctx, void *timeout_ctx) 5471f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 5481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct wpa_supplicant *wpa_s = eloop_ctx; 5491f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct wpa_ssid *ssid; 550d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt enum scan_req_type scan_req = NORMAL_SCAN_REQ; 551d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt int ret; 55204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct wpabuf *extra_ie = NULL; 5538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_driver_scan_params params; 55404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct wpa_driver_scan_params *scan_params; 5558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t max_ssids; 5568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum wpa_states prev_state; 5578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) { 5598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "Skip scan - interface disabled"); 56037d4d6a4efea4ef4f864347ac8ed8d62a9e19f90Dmitry Shmidt wpas_p2p_continue_after_scan(wpa_s); 5618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 5628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 564d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (wpa_s->disconnected && wpa_s->scan_req == NORMAL_SCAN_REQ) { 565aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "Disconnected - do not scan"); 5668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED); 56737d4d6a4efea4ef4f864347ac8ed8d62a9e19f90Dmitry Shmidt wpas_p2p_continue_after_scan(wpa_s); 5688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 5698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5705887a9d552f3d9d612011daba073e076daab5b2aDmitry Shmidt#ifdef ANDROID 5715887a9d552f3d9d612011daba073e076daab5b2aDmitry Shmidt if (wpa_s->scanning) { 5725887a9d552f3d9d612011daba073e076daab5b2aDmitry Shmidt /* If we are already in scanning state, we shall ignore this new scan request*/ 5735887a9d552f3d9d612011daba073e076daab5b2aDmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "Skip scan - already scanning"); 5745887a9d552f3d9d612011daba073e076daab5b2aDmitry Shmidt return; 5755887a9d552f3d9d612011daba073e076daab5b2aDmitry Shmidt } 5765887a9d552f3d9d612011daba073e076daab5b2aDmitry Shmidt#endif 57704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (!wpa_supplicant_enabled_networks(wpa_s) && 578d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_s->scan_req == NORMAL_SCAN_REQ) { 5798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "No enabled networks - do not scan"); 5808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_set_state(wpa_s, WPA_INACTIVE); 58137d4d6a4efea4ef4f864347ac8ed8d62a9e19f90Dmitry Shmidt wpas_p2p_continue_after_scan(wpa_s); 5828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 5838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->conf->ap_scan != 0 && 5868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (wpa_s->drv_flags & WPA_DRIVER_FLAGS_WIRED)) { 5878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "Using wired authentication - " 5888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "overriding ap_scan configuration"); 5898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->conf->ap_scan = 0; 5908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_notify_ap_scan_changed(wpa_s); 5918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->conf->ap_scan == 0) { 5948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_gen_assoc_event(wpa_s); 5958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 5968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5981f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef CONFIG_P2P 599051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt if (wpas_p2p_in_progress(wpa_s) || wpas_wpa_is_in_progress(wpa_s, 0)) { 60061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (wpa_s->sta_scan_pending && 60161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpas_p2p_in_progress(wpa_s) == 2 && 602dc7b71324df9788e194745e8ab9386a4619a623aJouni Malinen wpa_s->global->p2p_cb_on_scan_complete) { 60361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "Process pending station " 60461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt "mode scan during P2P search"); 60561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } else { 6061f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "Delay station mode scan " 6071f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "while P2P operation is in progress"); 60861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_s->sta_scan_pending = 1; 6091f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_supplicant_req_scan(wpa_s, 5, 0); 61061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return; 6111f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 6121f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 6131f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* CONFIG_P2P */ 6141f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 615051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt#ifdef CONFIG_GAS 616051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt if (gas_query_in_progress(wpa_s->gas)) { 617051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "Delay scan while GAS query is in progress"); 618051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt wpa_supplicant_req_scan(wpa_s, 1, 0); 619051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt return; 620051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt } 621051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt#endif /* CONFIG_GAS */ 622051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 6231f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (wpa_s->conf->ap_scan == 2) 6248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt max_ssids = 1; 6258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else { 6268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt max_ssids = wpa_s->max_scan_ssids; 6278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (max_ssids > WPAS_MAX_SCAN_SSIDS) 6288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt max_ssids = WPAS_MAX_SCAN_SSIDS; 6298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt scan_req = wpa_s->scan_req; 632d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_s->scan_req = NORMAL_SCAN_REQ; 6338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(¶ms, 0, sizeof(params)); 6358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt prev_state = wpa_s->wpa_state; 6378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->wpa_state == WPA_DISCONNECTED || 6388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->wpa_state == WPA_INACTIVE) 6398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_set_state(wpa_s, WPA_SCANNING); 6408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 64104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt /* 64204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * If autoscan has set its own scanning parameters 64304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt */ 64404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (wpa_s->autoscan_params != NULL) { 64504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt scan_params = wpa_s->autoscan_params; 64604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt goto scan; 64704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 64804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 649d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (scan_req != MANUAL_SCAN_REQ && wpa_s->connect_without_scan) { 65075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) { 65175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (ssid == wpa_s->connect_without_scan) 65275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen break; 65375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen } 65475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen wpa_s->connect_without_scan = NULL; 65575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen if (ssid) { 65675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen wpa_printf(MSG_DEBUG, "Start a pre-selected network " 65775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen "without scan step"); 65875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen wpa_supplicant_associate(wpa_s, NULL, ssid); 65975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen return; 66075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen } 66175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen } 66275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 66304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#ifdef CONFIG_P2P 66404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if ((wpa_s->p2p_in_provisioning || wpa_s->show_group_started) && 66504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->go_params) { 66604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Use specific SSID for scan during " 66704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt "P2P group formation"); 66804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt params.ssids[0].ssid = wpa_s->go_params->ssid; 66904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt params.ssids[0].ssid_len = wpa_s->go_params->ssid_len; 67004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt params.num_ssids = 1; 67104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt goto ssid_list_set; 67204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 67304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#endif /* CONFIG_P2P */ 67404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 6758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Find the starting point from which to continue scanning */ 6768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid = wpa_s->conf->ssid; 6778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->prev_scan_ssid != WILDCARD_SSID_SCAN) { 6788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (ssid) { 6798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid == wpa_s->prev_scan_ssid) { 6808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid = ssid->next; 6818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 6828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid = ssid->next; 6848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 687d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (scan_req != MANUAL_SCAN_REQ && wpa_s->conf->ap_scan == 2) { 68875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen wpa_s->connect_without_scan = NULL; 689c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpa_s->prev_scan_wildcard = 0; 6908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_assoc_try(wpa_s, ssid); 6918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 692e25ba1592df19d46a7a1e1a1fca1fb02ebd7be8fDmitry Shmidt#ifndef ANDROID 6938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (wpa_s->conf->ap_scan == 2) { 6948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 6958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * User-initiated scan request in ap_scan == 2; scan with 6968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wildcard SSID. 6978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 6988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid = NULL; 699e25ba1592df19d46a7a1e1a1fca1fb02ebd7be8fDmitry Shmidt#endif 7008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 7018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_ssid *start = ssid, *tssid; 7028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int freqs_set = 0; 7038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid == NULL && max_ssids > 1) 7048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid = wpa_s->conf->ssid; 7058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (ssid) { 70604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (!wpas_network_disabled(wpa_s, ssid) && 70704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ssid->scan_ssid) { 7088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_ascii(MSG_DEBUG, "Scan SSID", 7098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid->ssid, ssid->ssid_len); 7108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.ssids[params.num_ssids].ssid = 7118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid->ssid; 7128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.ssids[params.num_ssids].ssid_len = 7138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid->ssid_len; 7148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.num_ssids++; 7158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (params.num_ssids + 1 >= max_ssids) 7168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 7178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid = ssid->next; 7198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid == start) 7208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 7218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid == NULL && max_ssids > 1 && 7228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt start != wpa_s->conf->ssid) 7238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid = wpa_s->conf->ssid; 7248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (tssid = wpa_s->conf->ssid; tssid; tssid = tssid->next) { 72704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (wpas_network_disabled(wpa_s, tssid)) 7288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 7298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((params.freqs || !freqs_set) && tssid->scan_freq) { 7308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int_array_concat(¶ms.freqs, 7318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tssid->scan_freq); 7328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 7338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(params.freqs); 7348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.freqs = NULL; 7358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt freqs_set = 1; 7378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int_array_sort_unique(params.freqs); 7398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 741c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (ssid && max_ssids == 1) { 742c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt /* 743c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * If the driver is limited to 1 SSID at a time interleave 744c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * wildcard SSID scans with specific SSID scans to avoid 745c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * waiting a long time for a wildcard scan. 746c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt */ 747c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (!wpa_s->prev_scan_wildcard) { 748c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt params.ssids[0].ssid = NULL; 749c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt params.ssids[0].ssid_len = 0; 750c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpa_s->prev_scan_wildcard = 1; 751c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "Starting AP scan for " 752c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt "wildcard SSID (Interleave with specific)"); 753c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt } else { 754c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpa_s->prev_scan_ssid = ssid; 755c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpa_s->prev_scan_wildcard = 0; 756c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, 757c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt "Starting AP scan for specific SSID: %s", 758c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpa_ssid_txt(ssid->ssid, ssid->ssid_len)); 7598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 760c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt } else if (ssid) { 761c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt /* max_ssids > 1 */ 762c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt 763c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpa_s->prev_scan_ssid = ssid; 764c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "Include wildcard SSID in " 765c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt "the scan request"); 766c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt params.num_ssids++; 7678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 7688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->prev_scan_ssid = WILDCARD_SSID_SCAN; 7698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.num_ssids++; 7708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "Starting AP scan for wildcard " 7718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "SSID"); 7728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 77304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#ifdef CONFIG_P2P 77404949598a23f501be6eec21697465fd46a28840aDmitry Shmidtssid_list_set: 77504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#endif /* CONFIG_P2P */ 7768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7771f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_supplicant_optimize_freqs(wpa_s, ¶ms); 77861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt extra_ie = wpa_supplicant_extra_ies(wpa_s); 7798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (params.freqs == NULL && wpa_s->next_scan_freqs) { 7818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "Optimize scan based on previously " 7828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "generated frequency list"); 7838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.freqs = wpa_s->next_scan_freqs; 7848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 7858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(wpa_s->next_scan_freqs); 7868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->next_scan_freqs = NULL; 787b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt wpa_setband_scan_freqs(wpa_s, ¶ms); 7888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 78951b6ea882f234c14cd1fe1332a3840cf61fafccaDmitry Shmidt /* See if user specified frequencies. If so, scan only those. */ 79051b6ea882f234c14cd1fe1332a3840cf61fafccaDmitry Shmidt if (wpa_s->conf->freq_list && !params.freqs) { 79151b6ea882f234c14cd1fe1332a3840cf61fafccaDmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, 79251b6ea882f234c14cd1fe1332a3840cf61fafccaDmitry Shmidt "Optimize scan based on conf->freq_list"); 79351b6ea882f234c14cd1fe1332a3840cf61fafccaDmitry Shmidt int_array_concat(¶ms.freqs, wpa_s->conf->freq_list); 79451b6ea882f234c14cd1fe1332a3840cf61fafccaDmitry Shmidt } 79551b6ea882f234c14cd1fe1332a3840cf61fafccaDmitry Shmidt 796ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt /* Use current associated channel? */ 797ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt if (wpa_s->conf->scan_cur_freq && !params.freqs) { 798c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt unsigned int num = wpa_s->num_multichan_concurrent; 799c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt 800c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt params.freqs = os_calloc(num + 1, sizeof(int)); 801c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt if (params.freqs) { 802c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt num = get_shared_radio_freqs(wpa_s, params.freqs, num); 803c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt if (num > 0) { 804c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "Scan only the " 805c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt "current operating channels since " 806c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt "scan_cur_freq is enabled"); 807c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt } else { 808c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt os_free(params.freqs); 809c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt params.freqs = NULL; 810c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt } 811ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt } 812ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt } 813ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt 8148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.filter_ssids = wpa_supplicant_build_filter_ssids( 8158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->conf, ¶ms.num_filter_ssids); 8161f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (extra_ie) { 8171f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt params.extra_ies = wpabuf_head(extra_ie); 8181f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt params.extra_ies_len = wpabuf_len(extra_ie); 8191f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 8201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 8211f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef CONFIG_P2P 82204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (wpa_s->p2p_in_provisioning || 82304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt (wpa_s->show_group_started && wpa_s->go_params)) { 8241f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* 8251f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * The interface may not yet be in P2P mode, so we have to 8261f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * explicitly request P2P probe to disable CCK rates. 8271f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt */ 8281f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt params.p2p_probe = 1; 8291f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 8301f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* CONFIG_P2P */ 8318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 83204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt scan_params = ¶ms; 83304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 83404949598a23f501be6eec21697465fd46a28840aDmitry Shmidtscan: 835d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt#ifdef CONFIG_P2P 836d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt /* 837d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt * If the driver does not support multi-channel concurrency and a 838d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt * virtual interface that shares the same radio with the wpa_s interface 839d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt * is operating there may not be need to scan other channels apart from 840d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt * the current operating channel on the other virtual interface. Filter 841d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt * out other channels in case we are trying to find a connection for a 842d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt * station interface when we are not configured to prefer station 843d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt * connection and a concurrent operation is already in process. 844d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt */ 845d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (wpa_s->scan_for_connection && scan_req == NORMAL_SCAN_REQ && 846d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt !scan_params->freqs && !params.freqs && 847d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpas_is_p2p_prioritized(wpa_s) && 848d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_s->p2p_group_interface == NOT_P2P_GROUP_INTERFACE && 849d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt non_p2p_network_enabled(wpa_s)) { 850c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt unsigned int num = wpa_s->num_multichan_concurrent; 851c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt 852c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt params.freqs = os_calloc(num + 1, sizeof(int)); 853c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt if (params.freqs) { 854c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt num = get_shared_radio_freqs(wpa_s, params.freqs, num); 855c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt if (num > 0 && num == wpa_s->num_multichan_concurrent) { 856c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "Scan only the current operating channels since all channels are already used"); 857c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt } else { 858c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt os_free(params.freqs); 859c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt params.freqs = NULL; 860c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt } 861d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt } 862d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt } 863d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt#endif /* CONFIG_P2P */ 864d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 86504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ret = wpa_supplicant_trigger_scan(wpa_s, scan_params); 8668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8671f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpabuf_free(extra_ie); 8688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(params.freqs); 8698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(params.filter_ssids); 8708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret) { 8728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(wpa_s, MSG_WARNING, "Failed to initiate AP scan"); 8738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (prev_state != wpa_s->wpa_state) 8748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_set_state(wpa_s, prev_state); 875d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt /* Restore scan_req since we will try to scan again */ 876d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_s->scan_req = scan_req; 8778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_req_scan(wpa_s, 1, 0); 878d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt } else { 879d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_s->scan_for_connection = 0; 8808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 8828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8844b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidtvoid wpa_supplicant_update_scan_int(struct wpa_supplicant *wpa_s, int sec) 8854b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt{ 8864b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt struct os_time remaining, new_int; 8874b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt int cancelled; 8884b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt 8894b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt cancelled = eloop_cancel_timeout_one(wpa_supplicant_scan, wpa_s, NULL, 8904b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt &remaining); 8914b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt 8924b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt new_int.sec = sec; 8934b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt new_int.usec = 0; 8944b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt if (cancelled && os_time_before(&remaining, &new_int)) { 8954b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt new_int.sec = remaining.sec; 8964b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt new_int.usec = remaining.usec; 8974b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt } 8984b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt 899051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt if (cancelled) { 900051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt eloop_register_timeout(new_int.sec, new_int.usec, 901051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt wpa_supplicant_scan, wpa_s, NULL); 902051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt } 9034b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt wpa_s->scan_interval = sec; 9044b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt} 9054b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt 9064b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt 9078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 9088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_supplicant_req_scan - Schedule a scan for neighboring access points 9098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: Pointer to wpa_supplicant data 9108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sec: Number of seconds after which to scan 9118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @usec: Number of microseconds after which to scan 9128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 9138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function is used to schedule a scan for neighboring access points after 9148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * the specified time. 9158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 9168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpa_supplicant_req_scan(struct wpa_supplicant *wpa_s, int sec, int usec) 9178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 91881e9700b8fb135b898181ad3aeb44d39f0a01907Dmitry Shmidt#ifndef ANDROID 9198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* If there's at least one network that should be specifically scanned 9208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * then don't cancel the scan and reschedule. Some drivers do 9218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * background scanning which generates frequent scan results, and that 9228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * causes the specific SSID scan to get continually pushed back and 9238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * never happen, which causes hidden APs to never get probe-scanned. 9248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 9258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eloop_is_timeout_registered(wpa_supplicant_scan, wpa_s, NULL) && 9268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->conf->ap_scan == 1) { 9278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_ssid *ssid = wpa_s->conf->ssid; 9288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (ssid) { 93004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (!wpas_network_disabled(wpa_s, ssid) && 93104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ssid->scan_ssid) 9328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 9338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid = ssid->next; 9348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid) { 9368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "Not rescheduling scan to " 9378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "ensure that specific SSID scans occur"); 9388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 9398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 94181e9700b8fb135b898181ad3aeb44d39f0a01907Dmitry Shmidt#endif 9428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "Setting scan request: %d sec %d usec", 9438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sec, usec); 9448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(wpa_supplicant_scan, wpa_s, NULL); 9458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(sec, usec, wpa_supplicant_scan, wpa_s, NULL); 9468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 9501f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * wpa_supplicant_delayed_sched_scan - Request a delayed scheduled scan 9511f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * @wpa_s: Pointer to wpa_supplicant data 9521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * @sec: Number of seconds after which to scan 9531f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * @usec: Number of microseconds after which to scan 954a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * Returns: 0 on success or -1 otherwise 9551f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * 9561f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * This function is used to schedule periodic scans for neighboring 9571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * access points after the specified time. 9581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt */ 9591f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtint wpa_supplicant_delayed_sched_scan(struct wpa_supplicant *wpa_s, 9601f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt int sec, int usec) 9611f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 9621f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (!wpa_s->sched_scan_supported) 9631f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return -1; 9641f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 9651f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt eloop_register_timeout(sec, usec, 9661f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_supplicant_delayed_sched_scan_timeout, 9671f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s, NULL); 9681f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 9691f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return 0; 9701f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 9711f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 9721f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 9731f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt/** 9741f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * wpa_supplicant_req_sched_scan - Start a periodic scheduled scan 9751f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * @wpa_s: Pointer to wpa_supplicant data 976a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * Returns: 0 is sched_scan was started or -1 otherwise 9771f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * 9781f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * This function is used to schedule periodic scans for neighboring 9791f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * access points repeating the scan continuously. 9801f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt */ 9811f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtint wpa_supplicant_req_sched_scan(struct wpa_supplicant *wpa_s) 9821f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 9831f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct wpa_driver_scan_params params; 98404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct wpa_driver_scan_params *scan_params; 9851f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt enum wpa_states prev_state; 98604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct wpa_ssid *ssid = NULL; 98761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt struct wpabuf *extra_ie = NULL; 9881f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt int ret; 9891f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt unsigned int max_sched_scan_ssids; 9901f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt int wildcard = 0; 9911f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt int need_ssids; 9921f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 9931f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (!wpa_s->sched_scan_supported) 9941f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return -1; 9951f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 9961f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (wpa_s->max_sched_scan_ssids > WPAS_MAX_SCAN_SSIDS) 9971f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt max_sched_scan_ssids = WPAS_MAX_SCAN_SSIDS; 9981f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt else 9991f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt max_sched_scan_ssids = wpa_s->max_sched_scan_ssids; 100004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (max_sched_scan_ssids < 1 || wpa_s->conf->disable_scan_offload) 10011f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return -1; 10021f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 10031f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (wpa_s->sched_scanning) { 10041f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "Already sched scanning"); 10051f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return 0; 10061f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 10071f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 10081f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt need_ssids = 0; 10091f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) { 101004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (!wpas_network_disabled(wpa_s, ssid) && !ssid->scan_ssid) { 10111f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* Use wildcard SSID to find this network */ 10121f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wildcard = 1; 101304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } else if (!wpas_network_disabled(wpa_s, ssid) && 101404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ssid->ssid_len) 10151f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt need_ssids++; 101604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 101704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#ifdef CONFIG_WPS 101804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (!wpas_network_disabled(wpa_s, ssid) && 101904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ssid->key_mgmt == WPA_KEY_MGMT_WPS) { 102004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt /* 102104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * Normal scan is more reliable and faster for WPS 102204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * operations and since these are for short periods of 102304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * time, the benefit of trying to use sched_scan would 102404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * be limited. 102504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt */ 102604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "Use normal scan instead of " 102704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt "sched_scan for WPS"); 102804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return -1; 102904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 103004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#endif /* CONFIG_WPS */ 10311f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 10321f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (wildcard) 10331f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt need_ssids++; 10341f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 10351f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (wpa_s->normal_scans < 3 && 10361f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt (need_ssids <= wpa_s->max_scan_ssids || 10371f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s->max_scan_ssids >= (int) max_sched_scan_ssids)) { 10381f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* 10391f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * When normal scan can speed up operations, use that for the 10401f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * first operations before starting the sched_scan to allow 10411f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * user space sleep more. We do this only if the normal scan 10421f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * has functionality that is suitable for this or if the 10431f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * sched_scan does not have better support for multiple SSIDs. 10441f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt */ 10451f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "Use normal scan instead of " 10461f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "sched_scan for initial scans (normal_scans=%d)", 10471f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s->normal_scans); 10481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return -1; 10491f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 10501f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 10511f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt os_memset(¶ms, 0, sizeof(params)); 10521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 10531f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* If we can't allocate space for the filters, we just don't filter */ 10541f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt params.filter_ssids = os_zalloc(wpa_s->max_match_sets * 10551f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt sizeof(struct wpa_driver_scan_filter)); 10561f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 10571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt prev_state = wpa_s->wpa_state; 10581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (wpa_s->wpa_state == WPA_DISCONNECTED || 10591f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s->wpa_state == WPA_INACTIVE) 10601f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_supplicant_set_state(wpa_s, WPA_SCANNING); 10611f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 106204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (wpa_s->autoscan_params != NULL) { 106304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt scan_params = wpa_s->autoscan_params; 106404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt goto scan; 106504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 106604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 10671f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* Find the starting point from which to continue scanning */ 10681f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt ssid = wpa_s->conf->ssid; 10691f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (wpa_s->prev_sched_ssid) { 10701f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt while (ssid) { 10711f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (ssid == wpa_s->prev_sched_ssid) { 10721f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt ssid = ssid->next; 10731f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt break; 10741f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 10751f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt ssid = ssid->next; 10761f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 10771f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 10781f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 10791f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (!ssid || !wpa_s->prev_sched_ssid) { 10801f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "Beginning of SSID list"); 108151b6ea882f234c14cd1fe1332a3840cf61fafccaDmitry Shmidt if (wpa_s->conf->sched_scan_interval) 108251b6ea882f234c14cd1fe1332a3840cf61fafccaDmitry Shmidt wpa_s->sched_scan_interval = 108351b6ea882f234c14cd1fe1332a3840cf61fafccaDmitry Shmidt wpa_s->conf->sched_scan_interval; 108404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (wpa_s->sched_scan_interval == 0) 108504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->sched_scan_interval = 10; 10861f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s->sched_scan_timeout = max_sched_scan_ssids * 2; 10871f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s->first_sched_scan = 1; 10881f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt ssid = wpa_s->conf->ssid; 10891f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s->prev_sched_ssid = ssid; 10901f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 10911f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 10921f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (wildcard) { 10931f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "Add wildcard SSID to sched_scan"); 10941f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt params.num_ssids++; 10951f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 10961f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 10971f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt while (ssid) { 109804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (wpas_network_disabled(wpa_s, ssid)) 10991f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt goto next; 11001f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 11011f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (params.num_filter_ssids < wpa_s->max_match_sets && 11021f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt params.filter_ssids && ssid->ssid && ssid->ssid_len) { 11031f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "add to filter ssid: %s", 11041f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_ssid_txt(ssid->ssid, ssid->ssid_len)); 11051f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt os_memcpy(params.filter_ssids[params.num_filter_ssids].ssid, 11061f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt ssid->ssid, ssid->ssid_len); 11071f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt params.filter_ssids[params.num_filter_ssids].ssid_len = 11081f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt ssid->ssid_len; 11091f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt params.num_filter_ssids++; 11101f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } else if (params.filter_ssids && ssid->ssid && ssid->ssid_len) 11111f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt { 11121f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "Not enough room for SSID " 11131f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "filter for sched_scan - drop filter"); 11141f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt os_free(params.filter_ssids); 11151f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt params.filter_ssids = NULL; 11161f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt params.num_filter_ssids = 0; 11171f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 11181f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 11191f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (ssid->scan_ssid && ssid->ssid && ssid->ssid_len) { 11201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (params.num_ssids == max_sched_scan_ssids) 11211f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt break; /* only room for broadcast SSID */ 11221f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, 11231f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "add to active scan ssid: %s", 11241f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_ssid_txt(ssid->ssid, ssid->ssid_len)); 11251f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt params.ssids[params.num_ssids].ssid = 11261f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt ssid->ssid; 11271f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt params.ssids[params.num_ssids].ssid_len = 11281f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt ssid->ssid_len; 11291f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt params.num_ssids++; 11301f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (params.num_ssids >= max_sched_scan_ssids) { 11311f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s->prev_sched_ssid = ssid; 113204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt do { 113304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ssid = ssid->next; 113404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } while (ssid && 113504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt (wpas_network_disabled(wpa_s, ssid) || 113604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt !ssid->scan_ssid)); 11371f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt break; 11381f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 11391f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 11401f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 11411f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt next: 11421f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s->prev_sched_ssid = ssid; 11431f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt ssid = ssid->next; 11441f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 11451f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 11461f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (params.num_filter_ssids == 0) { 11471f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt os_free(params.filter_ssids); 11481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt params.filter_ssids = NULL; 11491f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 11501f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 115161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt extra_ie = wpa_supplicant_extra_ies(wpa_s); 115261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (extra_ie) { 115361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt params.extra_ies = wpabuf_head(extra_ie); 115461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt params.extra_ies_len = wpabuf_len(extra_ie); 115561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 11561f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 115704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt scan_params = ¶ms; 115804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 115904949598a23f501be6eec21697465fd46a28840aDmitry Shmidtscan: 11601f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (ssid || !wpa_s->first_sched_scan) { 11611f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, 11621f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "Starting sched scan: interval %d timeout %d", 11631f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s->sched_scan_interval, wpa_s->sched_scan_timeout); 116404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } else { 116504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, 116604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt "Starting sched scan: interval %d (no timeout)", 116704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->sched_scan_interval); 11681f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 11691f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 1170b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt wpa_setband_scan_freqs(wpa_s, scan_params); 1171b6e9aaf735990dc64cdb6efccc03d076768eabf3Dmitry Shmidt 117204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ret = wpa_supplicant_start_sched_scan(wpa_s, scan_params, 11731f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s->sched_scan_interval); 117461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(extra_ie); 11751f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt os_free(params.filter_ssids); 11761f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (ret) { 11771f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_msg(wpa_s, MSG_WARNING, "Failed to initiate sched scan"); 11781f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (prev_state != wpa_s->wpa_state) 11791f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_supplicant_set_state(wpa_s, prev_state); 11801f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return ret; 11811f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 11821f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 11831f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* If we have more SSIDs to scan, add a timeout so we scan them too */ 11841f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (ssid || !wpa_s->first_sched_scan) { 11851f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s->sched_scan_timed_out = 0; 11861f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt eloop_register_timeout(wpa_s->sched_scan_timeout, 0, 11871f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_supplicant_sched_scan_timeout, 11881f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s, NULL); 11891f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s->first_sched_scan = 0; 11901f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s->sched_scan_timeout /= 2; 11911f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s->sched_scan_interval *= 2; 11922f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt if (wpa_s->sched_scan_timeout < wpa_s->sched_scan_interval) { 11932f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt wpa_s->sched_scan_interval = 10; 11942f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt wpa_s->sched_scan_timeout = max_sched_scan_ssids * 2; 11952f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt } 11961f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 11971f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 11982f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt /* If there is no more ssids, start next time from the beginning */ 11992f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt if (!ssid) 12002f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt wpa_s->prev_sched_ssid = NULL; 12012f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt 12021f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return 0; 12031f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 12041f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 12051f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 12061f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt/** 12078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_supplicant_cancel_scan - Cancel a scheduled scan request 12088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: Pointer to wpa_supplicant data 12098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 12108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function is used to cancel a scan request scheduled with 12118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_supplicant_req_scan(). 12128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 12138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpa_supplicant_cancel_scan(struct wpa_supplicant *wpa_s) 12148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 12158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "Cancelling scan request"); 12168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(wpa_supplicant_scan, wpa_s, NULL); 121737d4d6a4efea4ef4f864347ac8ed8d62a9e19f90Dmitry Shmidt wpas_p2p_continue_after_scan(wpa_s); 1218c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt#ifdef ANDROID 121920df807cb700c516ff346732f1bc8f914d0d26d8Dmitry Shmidt wpa_supplicant_notify_scanning(wpa_s, 0); 1220c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt#endif 12218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 12228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12241f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt/** 1225c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt * wpa_supplicant_cancel_delayed_sched_scan - Stop a delayed scheduled scan 1226c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt * @wpa_s: Pointer to wpa_supplicant data 1227c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt * 1228c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt * This function is used to stop a delayed scheduled scan. 1229c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt */ 1230c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidtvoid wpa_supplicant_cancel_delayed_sched_scan(struct wpa_supplicant *wpa_s) 1231c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt{ 1232c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt if (!wpa_s->sched_scan_supported) 1233c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt return; 1234c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt 1235c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "Cancelling delayed sched scan"); 1236c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt eloop_cancel_timeout(wpa_supplicant_delayed_sched_scan_timeout, 1237c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt wpa_s, NULL); 1238c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt} 1239c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt 1240c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt 1241c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt/** 12421f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * wpa_supplicant_cancel_sched_scan - Stop running scheduled scans 12431f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * @wpa_s: Pointer to wpa_supplicant data 12441f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * 12451f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * This function is used to stop a periodic scheduled scan. 12461f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt */ 12471f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtvoid wpa_supplicant_cancel_sched_scan(struct wpa_supplicant *wpa_s) 12481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 12491f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (!wpa_s->sched_scanning) 12501f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return; 12511f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 12521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "Cancelling sched scan"); 12531f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt eloop_cancel_timeout(wpa_supplicant_sched_scan_timeout, wpa_s, NULL); 12541f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_supplicant_stop_sched_scan(wpa_s); 12551f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 12561f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 12571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 1258a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt/** 1259a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * wpa_supplicant_notify_scanning - Indicate possible scan state change 1260a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * @wpa_s: Pointer to wpa_supplicant data 1261a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * @scanning: Whether scanning is currently in progress 1262a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * 1263a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * This function is to generate scanning notifycations. It is called whenever 1264a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * there may have been a change in scanning (scan started, completed, stopped). 1265a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * wpas_notify_scanning() is called whenever the scanning state changed from the 1266a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * previously notified state. 1267a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt */ 12688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpa_supplicant_notify_scanning(struct wpa_supplicant *wpa_s, 12698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int scanning) 12708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 12718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->scanning != scanning) { 12728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->scanning = scanning; 12738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_notify_scanning(wpa_s); 12748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 12768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_scan_get_max_rate(const struct wpa_scan_res *res) 12798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 12808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int rate = 0; 12818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *ie; 12828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 12838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ie = wpa_scan_get_ie(res, WLAN_EID_SUPP_RATES); 12858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; ie && i < ie[1]; i++) { 12868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((ie[i + 2] & 0x7f) > rate) 12878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rate = ie[i + 2] & 0x7f; 12888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ie = wpa_scan_get_ie(res, WLAN_EID_EXT_SUPP_RATES); 12918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; ie && i < ie[1]; i++) { 12928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((ie[i + 2] & 0x7f) > rate) 12938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rate = ie[i + 2] & 0x7f; 12948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return rate; 12978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 12988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1300a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt/** 1301a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * wpa_scan_get_ie - Fetch a specified information element from a scan result 1302a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * @res: Scan result entry 1303a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * @ie: Information element identitifier (WLAN_EID_*) 1304a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * Returns: Pointer to the information element (id field) or %NULL if not found 1305a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * 1306a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * This function returns the first matching information element in the scan 1307a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * result. 1308a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt */ 13098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtconst u8 * wpa_scan_get_ie(const struct wpa_scan_res *res, u8 ie) 13108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 13118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *end, *pos; 13128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = (const u8 *) (res + 1); 13148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = pos + res->ie_len; 13158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (pos + 1 < end) { 13178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos + 2 + pos[1] > end) 13188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 13198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos[0] == ie) 13208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos; 13218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 2 + pos[1]; 13228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 13258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 13268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1328a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt/** 1329a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * wpa_scan_get_vendor_ie - Fetch vendor information element from a scan result 1330a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * @res: Scan result entry 1331a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * @vendor_type: Vendor type (four octets starting the IE payload) 1332a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * Returns: Pointer to the information element (id field) or %NULL if not found 1333a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * 1334a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * This function returns the first matching information element in the scan 1335a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * result. 1336a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt */ 13378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtconst u8 * wpa_scan_get_vendor_ie(const struct wpa_scan_res *res, 13388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u32 vendor_type) 13398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 13408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *end, *pos; 13418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = (const u8 *) (res + 1); 13438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = pos + res->ie_len; 13448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (pos + 1 < end) { 13468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos + 2 + pos[1] > end) 13478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 13488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 && 13498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt vendor_type == WPA_GET_BE32(&pos[2])) 13508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos; 13518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 2 + pos[1]; 13528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 13558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 13568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1358a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt/** 13599657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt * wpa_scan_get_vendor_ie_beacon - Fetch vendor information from a scan result 13609657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt * @res: Scan result entry 13619657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt * @vendor_type: Vendor type (four octets starting the IE payload) 13629657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt * Returns: Pointer to the information element (id field) or %NULL if not found 13639657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt * 13649657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt * This function returns the first matching information element in the scan 13659657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt * result. 13669657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt * 13679657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt * This function is like wpa_scan_get_vendor_ie(), but uses IE buffer only 13689657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt * from Beacon frames instead of either Beacon or Probe Response frames. 13699657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt */ 13709657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidtconst u8 * wpa_scan_get_vendor_ie_beacon(const struct wpa_scan_res *res, 13719657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt u32 vendor_type) 13729657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt{ 13739657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt const u8 *end, *pos; 13749657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt 13759657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt if (res->beacon_ie_len == 0) 13769657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt return NULL; 13779657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt 13789657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt pos = (const u8 *) (res + 1); 13799657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt pos += res->ie_len; 13809657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt end = pos + res->beacon_ie_len; 13819657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt 13829657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt while (pos + 1 < end) { 13839657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt if (pos + 2 + pos[1] > end) 13849657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt break; 13859657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt if (pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 && 13869657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt vendor_type == WPA_GET_BE32(&pos[2])) 13879657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt return pos; 13889657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt pos += 2 + pos[1]; 13899657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt } 13909657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt 13919657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt return NULL; 13929657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt} 13939657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt 13949657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt 13959657139ca0bbea9a84e0a3c7e9438d1f53c9ed24Dmitry Shmidt/** 1396a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * wpa_scan_get_vendor_ie_multi - Fetch vendor IE data from a scan result 1397a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * @res: Scan result entry 1398a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * @vendor_type: Vendor type (four octets starting the IE payload) 1399a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * Returns: Pointer to the information element payload or %NULL if not found 1400a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * 1401a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * This function returns concatenated payload of possibly fragmented vendor 1402a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * specific information elements in the scan result. The caller is responsible 1403a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * for freeing the returned buffer. 1404a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt */ 14058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct wpabuf * wpa_scan_get_vendor_ie_multi(const struct wpa_scan_res *res, 14068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u32 vendor_type) 14078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 14088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *buf; 14098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *end, *pos; 14108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf = wpabuf_alloc(res->ie_len); 14128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (buf == NULL) 14138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 14148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = (const u8 *) (res + 1); 14168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = pos + res->ie_len; 14178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (pos + 1 < end) { 14198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos + 2 + pos[1] > end) 14208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 14218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 && 14228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt vendor_type == WPA_GET_BE32(&pos[2])) 14238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_data(buf, pos + 2 + 4, pos[1] - 4); 14248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 2 + pos[1]; 14258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpabuf_len(buf) == 0) { 14288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(buf); 14298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf = NULL; 14308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return buf; 14338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 14348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14361f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt/* 14371f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * Channels with a great SNR can operate at full rate. What is a great SNR? 14381f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * This doc https://supportforums.cisco.com/docs/DOC-12954 says, "the general 14391f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * rule of thumb is that any SNR above 20 is good." This one 14401f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * http://www.cisco.com/en/US/tech/tk722/tk809/technologies_q_and_a_item09186a00805e9a96.shtml#qa23 14411f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * recommends 25 as a minimum SNR for 54 Mbps data rate. 30 is chosen here as a 14421f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * conservative value. 14431f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt */ 14441f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#define GREAT_SNR 30 14451f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 14468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* Compare function for sorting scan results. Return >0 if @b is considered 14478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * better. */ 14488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_scan_result_compar(const void *a, const void *b) 14498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 14501f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#define IS_5GHZ(n) (n > 4000) 14511f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#define MIN(a,b) a < b ? a : b 14528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_scan_res **_wa = (void *) a; 14538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_scan_res **_wb = (void *) b; 14548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_scan_res *wa = *_wa; 14558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_scan_res *wb = *_wb; 14568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int wpa_a, wpa_b, maxrate_a, maxrate_b; 14571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt int snr_a, snr_b; 14588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* WPA/WPA2 support preferred */ 14608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_a = wpa_scan_get_vendor_ie(wa, WPA_IE_VENDOR_TYPE) != NULL || 14618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_scan_get_ie(wa, WLAN_EID_RSN) != NULL; 14628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_b = wpa_scan_get_vendor_ie(wb, WPA_IE_VENDOR_TYPE) != NULL || 14638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_scan_get_ie(wb, WLAN_EID_RSN) != NULL; 14648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_b && !wpa_a) 14668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 14678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!wpa_b && wpa_a) 14688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 14698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* privacy support preferred */ 14718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((wa->caps & IEEE80211_CAP_PRIVACY) == 0 && 14728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (wb->caps & IEEE80211_CAP_PRIVACY)) 14738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 14748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((wa->caps & IEEE80211_CAP_PRIVACY) && 14758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (wb->caps & IEEE80211_CAP_PRIVACY) == 0) 14768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 14778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14781f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if ((wa->flags & wb->flags & WPA_SCAN_LEVEL_DBM) && 14791f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt !((wa->flags | wb->flags) & WPA_SCAN_NOISE_INVALID)) { 14801f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt snr_a = MIN(wa->level - wa->noise, GREAT_SNR); 14811f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt snr_b = MIN(wb->level - wb->noise, GREAT_SNR); 14821f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } else { 14831f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* Not suitable information to calculate SNR, so use level */ 14841f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt snr_a = wa->level; 14851f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt snr_b = wb->level; 14861f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 14871f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 14881f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* best/max rate preferred if SNR close enough */ 14891f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if ((snr_a && snr_b && abs(snr_b - snr_a) < 5) || 14908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (wa->qual && wb->qual && abs(wb->qual - wa->qual) < 10)) { 14918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt maxrate_a = wpa_scan_get_max_rate(wa); 14928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt maxrate_b = wpa_scan_get_max_rate(wb); 14938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (maxrate_a != maxrate_b) 14948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return maxrate_b - maxrate_a; 14951f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (IS_5GHZ(wa->freq) ^ IS_5GHZ(wb->freq)) 14961f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return IS_5GHZ(wa->freq) ? -1 : 1; 14978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* use freq for channel preference */ 15008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15011f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* all things being equal, use SNR; if SNRs are 15028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * identical, use quality values since some drivers may only report 15038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * that value and leave the signal level zero */ 15041f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (snr_b == snr_a) 15058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return wb->qual - wa->qual; 15061f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return snr_b - snr_a; 15071f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#undef MIN 15081f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#undef IS_5GHZ 15098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 15108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_WPS 15138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* Compare function for sorting scan results when searching a WPS AP for 15148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * provisioning. Return >0 if @b is considered better. */ 15158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_scan_result_wps_compar(const void *a, const void *b) 15168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 15178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_scan_res **_wa = (void *) a; 15188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_scan_res **_wb = (void *) b; 15198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_scan_res *wa = *_wa; 15208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_scan_res *wb = *_wb; 15218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int uses_wps_a, uses_wps_b; 15228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *wps_a, *wps_b; 15238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 15248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Optimization - check WPS IE existence before allocated memory and 15268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * doing full reassembly. */ 15278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt uses_wps_a = wpa_scan_get_vendor_ie(wa, WPS_IE_VENDOR_TYPE) != NULL; 15288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt uses_wps_b = wpa_scan_get_vendor_ie(wb, WPS_IE_VENDOR_TYPE) != NULL; 15298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (uses_wps_a && !uses_wps_b) 15308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 15318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!uses_wps_a && uses_wps_b) 15328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 15338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (uses_wps_a && uses_wps_b) { 15358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wps_a = wpa_scan_get_vendor_ie_multi(wa, WPS_IE_VENDOR_TYPE); 15368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wps_b = wpa_scan_get_vendor_ie_multi(wb, WPS_IE_VENDOR_TYPE); 15378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = wps_ap_priority_compar(wps_a, wps_b); 15388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(wps_a); 15398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(wps_b); 15408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res) 15418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return res; 15428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 15458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Do not use current AP security policy as a sorting criteria during 15468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * WPS provisioning step since the AP may get reconfigured at the 15478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * completion of provisioning. 15488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 15498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* all things being equal, use signal level; if signal levels are 15518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * identical, use quality values since some drivers may only report 15528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * that value and leave the signal level zero */ 15538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wb->level == wa->level) 15548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return wb->qual - wa->qual; 15558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return wb->level - wa->level; 15568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 15578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_WPS */ 15588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15601f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic void dump_scan_res(struct wpa_scan_results *scan_res) 15611f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 15621f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifndef CONFIG_NO_STDOUT_DEBUG 15631f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt size_t i; 15641f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 15651f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (scan_res->res == NULL || scan_res->num == 0) 15661f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return; 15671f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 15681f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_printf(MSG_EXCESSIVE, "Sorted scan results"); 15691f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 15701f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt for (i = 0; i < scan_res->num; i++) { 15711f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct wpa_scan_res *r = scan_res->res[i]; 157204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt u8 *pos; 15731f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if ((r->flags & (WPA_SCAN_LEVEL_DBM | WPA_SCAN_NOISE_INVALID)) 15741f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt == WPA_SCAN_LEVEL_DBM) { 15751f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt int snr = r->level - r->noise; 15761f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_printf(MSG_EXCESSIVE, MACSTR " freq=%d qual=%d " 1577f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt "noise=%d level=%d snr=%d%s flags=0x%x " 1578f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt "age=%u", 15791f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt MAC2STR(r->bssid), r->freq, r->qual, 15801f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt r->noise, r->level, snr, 1581f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt snr >= GREAT_SNR ? "*" : "", r->flags, 1582f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt r->age); 15831f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } else { 15841f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_printf(MSG_EXCESSIVE, MACSTR " freq=%d qual=%d " 1585f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt "noise=%d level=%d flags=0x%x age=%u", 15861f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt MAC2STR(r->bssid), r->freq, r->qual, 1587f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt r->noise, r->level, r->flags, r->age); 15881f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 158904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt pos = (u8 *) (r + 1); 159004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (r->ie_len) 159104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_hexdump(MSG_EXCESSIVE, "IEs", pos, r->ie_len); 159204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt pos += r->ie_len; 159304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (r->beacon_ie_len) 159404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_hexdump(MSG_EXCESSIVE, "Beacon IEs", 159504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt pos, r->beacon_ie_len); 15961f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 15971f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* CONFIG_NO_STDOUT_DEBUG */ 15981f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 15991f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 16001f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 1601a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt/** 1602a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * wpa_supplicant_filter_bssid_match - Is the specified BSSID allowed 1603a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * @wpa_s: Pointer to wpa_supplicant data 1604a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * @bssid: BSSID to check 1605a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * Returns: 0 if the BSSID is filtered or 1 if not 1606a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * 1607a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * This function is used to filter out specific BSSIDs from scan reslts mainly 1608a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * for testing purposes (SET bssid_filter ctrl_iface command). 1609a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt */ 161004949598a23f501be6eec21697465fd46a28840aDmitry Shmidtint wpa_supplicant_filter_bssid_match(struct wpa_supplicant *wpa_s, 161104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt const u8 *bssid) 161204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 161304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt size_t i; 161404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 161504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (wpa_s->bssid_filter == NULL) 161604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return 1; 161704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 161804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt for (i = 0; i < wpa_s->bssid_filter_count; i++) { 161904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (os_memcmp(wpa_s->bssid_filter + i * ETH_ALEN, bssid, 162004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ETH_ALEN) == 0) 162104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return 1; 162204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 162304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 162404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return 0; 162504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 162604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 162704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 162804949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic void filter_scan_res(struct wpa_supplicant *wpa_s, 162904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct wpa_scan_results *res) 163004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 163104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt size_t i, j; 163204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 163304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (wpa_s->bssid_filter == NULL) 163404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return; 163504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 163604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt for (i = 0, j = 0; i < res->num; i++) { 163704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (wpa_supplicant_filter_bssid_match(wpa_s, 163804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt res->res[i]->bssid)) { 163904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt res->res[j++] = res->res[i]; 164004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } else { 164104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_free(res->res[i]); 164204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt res->res[i] = NULL; 164304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 164404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 164504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 164604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (res->num != j) { 164704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_DEBUG, "Filtered out %d scan results", 164804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt (int) (res->num - j)); 164904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt res->num = j; 165004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 165104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 165204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 165304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 16548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 16558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_supplicant_get_scan_results - Get scan results 16568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: Pointer to wpa_supplicant data 16578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @info: Information about what was scanned or %NULL if not available 16588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @new_scan: Whether a new scan was performed 16598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Scan results, %NULL on failure 16608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 16618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function request the current scan results from the driver and updates 16628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * the local BSS list wpa_s->bss. The caller is responsible for freeing the 16638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * results with wpa_scan_results_free(). 16648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 16658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct wpa_scan_results * 16668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtwpa_supplicant_get_scan_results(struct wpa_supplicant *wpa_s, 16678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct scan_info *info, int new_scan) 16688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 16698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_scan_results *scan_res; 16708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t i; 16718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int (*compar)(const void *, const void *) = wpa_scan_result_compar; 16728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16731f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt scan_res = wpa_drv_get_scan_results2(wpa_s); 16748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (scan_res == NULL) { 16758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "Failed to get scan results"); 16768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 16778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1678f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt if (scan_res->fetch_time.sec == 0) { 1679f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt /* 1680f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * Make sure we have a valid timestamp if the driver wrapper 1681f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * does not set this. 1682f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt */ 1683f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt os_get_time(&scan_res->fetch_time); 1684f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt } 168504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt filter_scan_res(wpa_s, scan_res); 16868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_WPS 16888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpas_wps_in_progress(wpa_s)) { 16898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "WPS: Order scan results with WPS " 16908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "provisioning rules"); 16918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt compar = wpa_scan_result_wps_compar; 16928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_WPS */ 16948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt qsort(scan_res->res, scan_res->num, sizeof(struct wpa_scan_res *), 16968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt compar); 16971f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt dump_scan_res(scan_res); 16988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_bss_update_start(wpa_s); 17008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < scan_res->num; i++) 1701f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt wpa_bss_update_scan_res(wpa_s, scan_res->res[i], 1702f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt &scan_res->fetch_time); 17038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_bss_update_end(wpa_s, info, new_scan); 17048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return scan_res; 17068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 17078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1709a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt/** 1710a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * wpa_supplicant_update_scan_results - Update scan results from the driver 1711a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * @wpa_s: Pointer to wpa_supplicant data 1712a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * Returns: 0 on success, -1 on failure 1713a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * 1714a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * This function updates the BSS table within wpa_supplicant based on the 1715a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * currently available scan results from the driver without requesting a new 1716a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * scan. This is used in cases where the driver indicates an association 1717a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * (including roaming within ESS) and wpa_supplicant does not yet have the 1718a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * needed information to complete the connection (e.g., to perform validation 1719a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt * steps in 4-way handshake). 1720a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt */ 17218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpa_supplicant_update_scan_results(struct wpa_supplicant *wpa_s) 17228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 17238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_scan_results *scan_res; 17248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt scan_res = wpa_supplicant_get_scan_results(wpa_s, NULL, 0); 17258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (scan_res == NULL) 17268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 17278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_scan_results_free(scan_res); 17288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 17308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 17313a787e6f7c987ba5a9a56a2066467d20ab40ec58Dmitry Shmidt 17323a787e6f7c987ba5a9a56a2066467d20ab40ec58Dmitry Shmidt 17333a787e6f7c987ba5a9a56a2066467d20ab40ec58Dmitry Shmidt/** 17343a787e6f7c987ba5a9a56a2066467d20ab40ec58Dmitry Shmidt * scan_only_handler - Reports scan results 17353a787e6f7c987ba5a9a56a2066467d20ab40ec58Dmitry Shmidt */ 17363a787e6f7c987ba5a9a56a2066467d20ab40ec58Dmitry Shmidtvoid scan_only_handler(struct wpa_supplicant *wpa_s, 17373a787e6f7c987ba5a9a56a2066467d20ab40ec58Dmitry Shmidt struct wpa_scan_results *scan_res) 17383a787e6f7c987ba5a9a56a2066467d20ab40ec58Dmitry Shmidt{ 17394b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "Scan-only results received"); 17403a787e6f7c987ba5a9a56a2066467d20ab40ec58Dmitry Shmidt wpa_msg_ctrl(wpa_s, MSG_INFO, WPA_EVENT_SCAN_RESULTS); 17413a787e6f7c987ba5a9a56a2066467d20ab40ec58Dmitry Shmidt wpas_notify_scan_results(wpa_s); 17424b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt wpas_notify_scan_done(wpa_s, 1); 17433a787e6f7c987ba5a9a56a2066467d20ab40ec58Dmitry Shmidt} 174437d4d6a4efea4ef4f864347ac8ed8d62a9e19f90Dmitry Shmidt 174537d4d6a4efea4ef4f864347ac8ed8d62a9e19f90Dmitry Shmidt 174637d4d6a4efea4ef4f864347ac8ed8d62a9e19f90Dmitry Shmidtint wpas_scan_scheduled(struct wpa_supplicant *wpa_s) 174737d4d6a4efea4ef4f864347ac8ed8d62a9e19f90Dmitry Shmidt{ 174837d4d6a4efea4ef4f864347ac8ed8d62a9e19f90Dmitry Shmidt return eloop_is_timeout_registered(wpa_supplicant_scan, wpa_s, NULL); 174937d4d6a4efea4ef4f864347ac8ed8d62a9e19f90Dmitry Shmidt} 1750