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