• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * WPA Supplicant - Scanning
3  * Copyright (c) 2003-2019, Jouni Malinen <j@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 "common/wpa_ctrl.h"
15 #include "config.h"
16 #include "wpa_supplicant_i.h"
17 #include "driver_i.h"
18 #include "wps_supplicant.h"
19 #include "p2p_supplicant.h"
20 #include "p2p/p2p.h"
21 #include "hs20_supplicant.h"
22 #include "notify.h"
23 #include "bss.h"
24 #include "scan.h"
25 #include "mesh.h"
26 
27 
wpa_supplicant_gen_assoc_event(struct wpa_supplicant * wpa_s)28 static void wpa_supplicant_gen_assoc_event(struct wpa_supplicant *wpa_s)
29 {
30 	struct wpa_ssid *ssid;
31 	union wpa_event_data data;
32 
33 	ssid = wpa_supplicant_get_ssid(wpa_s);
34 	if (ssid == NULL)
35 		return;
36 
37 	if (wpa_s->current_ssid == NULL) {
38 		wpa_s->current_ssid = ssid;
39 		wpas_notify_network_changed(wpa_s);
40 	}
41 	wpa_supplicant_initiate_eapol(wpa_s);
42 	wpa_dbg(wpa_s, MSG_DEBUG, "Already associated with a configured "
43 		"network - generating associated event");
44 	os_memset(&data, 0, sizeof(data));
45 	wpa_supplicant_event(wpa_s, EVENT_ASSOC, &data);
46 }
47 
48 
49 #ifdef CONFIG_WPS
wpas_wps_in_use(struct wpa_supplicant * wpa_s,enum wps_request_type * req_type)50 static int wpas_wps_in_use(struct wpa_supplicant *wpa_s,
51 			   enum wps_request_type *req_type)
52 {
53 	struct wpa_ssid *ssid;
54 	int wps = 0;
55 
56 	for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
57 		if (!(ssid->key_mgmt & WPA_KEY_MGMT_WPS))
58 			continue;
59 
60 		wps = 1;
61 		*req_type = wpas_wps_get_req_type(ssid);
62 		if (ssid->eap.phase1 && os_strstr(ssid->eap.phase1, "pbc=1"))
63 			return 2;
64 	}
65 
66 #ifdef CONFIG_P2P
67 	if (!wpa_s->global->p2p_disabled && wpa_s->global->p2p &&
68 	    !wpa_s->conf->p2p_disabled) {
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 
wpa_setup_mac_addr_rand_params(struct wpa_driver_scan_params * params,const u8 * mac_addr)82 static int wpa_setup_mac_addr_rand_params(struct wpa_driver_scan_params *params,
83 					  const u8 *mac_addr)
84 {
85 	u8 *tmp;
86 
87 	if (params->mac_addr) {
88 		params->mac_addr_mask = NULL;
89 		os_free(params->mac_addr);
90 		params->mac_addr = NULL;
91 	}
92 
93 	params->mac_addr_rand = 1;
94 
95 	if (!mac_addr)
96 		return 0;
97 
98 	tmp = os_malloc(2 * ETH_ALEN);
99 	if (!tmp)
100 		return -1;
101 
102 	os_memcpy(tmp, mac_addr, 2 * ETH_ALEN);
103 	params->mac_addr = tmp;
104 	params->mac_addr_mask = tmp + ETH_ALEN;
105 	return 0;
106 }
107 
108 
109 /**
110  * wpa_supplicant_enabled_networks - Check whether there are enabled networks
111  * @wpa_s: Pointer to wpa_supplicant data
112  * Returns: 0 if no networks are enabled, >0 if networks are enabled
113  *
114  * This function is used to figure out whether any networks (or Interworking
115  * with enabled credentials and auto_interworking) are present in the current
116  * configuration.
117  */
wpa_supplicant_enabled_networks(struct wpa_supplicant * wpa_s)118 int wpa_supplicant_enabled_networks(struct wpa_supplicant *wpa_s)
119 {
120 	struct wpa_ssid *ssid = wpa_s->conf->ssid;
121 	int count = 0, disabled = 0;
122 
123 	if (wpa_s->p2p_mgmt)
124 		return 0; /* no normal network profiles on p2p_mgmt interface */
125 
126 	while (ssid) {
127 		if (!wpas_network_disabled(wpa_s, ssid))
128 			count++;
129 		else
130 			disabled++;
131 		ssid = ssid->next;
132 	}
133 	if (wpa_s->conf->cred && wpa_s->conf->interworking &&
134 	    wpa_s->conf->auto_interworking)
135 		count++;
136 	if (count == 0 && disabled > 0) {
137 		wpa_dbg(wpa_s, MSG_DEBUG, "No enabled networks (%d disabled "
138 			"networks)", disabled);
139 	}
140 	return count;
141 }
142 
143 
wpa_supplicant_assoc_try(struct wpa_supplicant * wpa_s,struct wpa_ssid * ssid)144 static void wpa_supplicant_assoc_try(struct wpa_supplicant *wpa_s,
145 				     struct wpa_ssid *ssid)
146 {
147 	int min_temp_disabled = 0;
148 
149 	while (ssid) {
150 		if (!wpas_network_disabled(wpa_s, ssid)) {
151 			int temp_disabled = wpas_temp_disabled(wpa_s, ssid);
152 
153 			if (temp_disabled <= 0)
154 				break;
155 
156 			if (!min_temp_disabled ||
157 			    temp_disabled < min_temp_disabled)
158 				min_temp_disabled = temp_disabled;
159 		}
160 		ssid = ssid->next;
161 	}
162 
163 	/* ap_scan=2 mode - try to associate with each SSID. */
164 	if (ssid == NULL) {
165 		wpa_dbg(wpa_s, MSG_DEBUG, "wpa_supplicant_assoc_try: Reached "
166 			"end of scan list - go back to beginning");
167 		wpa_s->prev_scan_ssid = WILDCARD_SSID_SCAN;
168 		wpa_supplicant_req_scan(wpa_s, min_temp_disabled, 0);
169 		return;
170 	}
171 	if (ssid->next) {
172 		/* Continue from the next SSID on the next attempt. */
173 		wpa_s->prev_scan_ssid = ssid;
174 	} else {
175 		/* Start from the beginning of the SSID list. */
176 		wpa_s->prev_scan_ssid = WILDCARD_SSID_SCAN;
177 	}
178 	wpa_supplicant_associate(wpa_s, NULL, ssid);
179 }
180 
181 
wpas_trigger_scan_cb(struct wpa_radio_work * work,int deinit)182 static void wpas_trigger_scan_cb(struct wpa_radio_work *work, int deinit)
183 {
184 	struct wpa_supplicant *wpa_s = work->wpa_s;
185 	struct wpa_driver_scan_params *params = work->ctx;
186 	int ret;
187 
188 	if (deinit) {
189 		if (!work->started) {
190 			wpa_scan_free_params(params);
191 			return;
192 		}
193 		wpa_supplicant_notify_scanning(wpa_s, 0);
194 		wpas_notify_scan_done(wpa_s, 0);
195 		wpa_s->scan_work = NULL;
196 		return;
197 	}
198 
199 	if ((wpa_s->mac_addr_rand_enable & MAC_ADDR_RAND_SCAN) &&
200 	    wpa_s->wpa_state <= WPA_SCANNING)
201 		wpa_setup_mac_addr_rand_params(params, wpa_s->mac_addr_scan);
202 
203 	if (wpas_update_random_addr_disassoc(wpa_s) < 0) {
204 		wpa_msg(wpa_s, MSG_INFO,
205 			"Failed to assign random MAC address for a scan");
206 		wpa_scan_free_params(params);
207 		wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_SCAN_FAILED "ret=-1");
208 		radio_work_done(work);
209 		return;
210 	}
211 
212 	wpa_supplicant_notify_scanning(wpa_s, 1);
213 
214 	if (wpa_s->clear_driver_scan_cache) {
215 		wpa_printf(MSG_DEBUG,
216 			   "Request driver to clear scan cache due to local BSS flush");
217 		params->only_new_results = 1;
218 	}
219 	ret = wpa_drv_scan(wpa_s, params);
220 	/*
221 	 * Store the obtained vendor scan cookie (if any) in wpa_s context.
222 	 * The current design is to allow only one scan request on each
223 	 * interface, hence having this scan cookie stored in wpa_s context is
224 	 * fine for now.
225 	 *
226 	 * Revisit this logic if concurrent scan operations per interface
227 	 * is supported.
228 	 */
229 	if (ret == 0)
230 		wpa_s->curr_scan_cookie = params->scan_cookie;
231 	wpa_scan_free_params(params);
232 	work->ctx = NULL;
233 	if (ret) {
234 		int retry = wpa_s->last_scan_req != MANUAL_SCAN_REQ &&
235 			!wpa_s->beacon_rep_data.token;
236 
237 		if (wpa_s->disconnected)
238 			retry = 0;
239 
240 		wpa_supplicant_notify_scanning(wpa_s, 0);
241 		wpas_notify_scan_done(wpa_s, 0);
242 		if (wpa_s->wpa_state == WPA_SCANNING)
243 			wpa_supplicant_set_state(wpa_s,
244 						 wpa_s->scan_prev_wpa_state);
245 		wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_SCAN_FAILED "ret=%d%s",
246 			ret, retry ? " retry=1" : "");
247 		radio_work_done(work);
248 
249 		if (retry) {
250 			/* Restore scan_req since we will try to scan again */
251 			wpa_s->scan_req = wpa_s->last_scan_req;
252 			wpa_supplicant_req_scan(wpa_s, 1, 0);
253 		} else if (wpa_s->scan_res_handler) {
254 			/* Clear the scan_res_handler */
255 			wpa_s->scan_res_handler = NULL;
256 		}
257 
258 		if (wpa_s->beacon_rep_data.token)
259 			wpas_rrm_refuse_request(wpa_s);
260 
261 		return;
262 	}
263 
264 	os_get_reltime(&wpa_s->scan_trigger_time);
265 	wpa_s->scan_runs++;
266 	wpa_s->normal_scans++;
267 	wpa_s->own_scan_requested = 1;
268 	wpa_s->clear_driver_scan_cache = 0;
269 	wpa_s->scan_work = work;
270 }
271 
272 
273 /**
274  * wpa_supplicant_trigger_scan - Request driver to start a scan
275  * @wpa_s: Pointer to wpa_supplicant data
276  * @params: Scan parameters
277  * Returns: 0 on success, -1 on failure
278  */
wpa_supplicant_trigger_scan(struct wpa_supplicant * wpa_s,struct wpa_driver_scan_params * params)279 int wpa_supplicant_trigger_scan(struct wpa_supplicant *wpa_s,
280 				struct wpa_driver_scan_params *params)
281 {
282 	struct wpa_driver_scan_params *ctx;
283 
284 	if (wpa_s->scan_work) {
285 		wpa_dbg(wpa_s, MSG_INFO, "Reject scan trigger since one is already pending");
286 		return -1;
287 	}
288 
289 	ctx = wpa_scan_clone_params(params);
290 	if (!ctx ||
291 	    radio_add_work(wpa_s, 0, "scan", 0, wpas_trigger_scan_cb, ctx) < 0)
292 	{
293 		wpa_scan_free_params(ctx);
294 		wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_SCAN_FAILED "ret=-1");
295 		return -1;
296 	}
297 
298 	return 0;
299 }
300 
301 
302 static void
wpa_supplicant_delayed_sched_scan_timeout(void * eloop_ctx,void * timeout_ctx)303 wpa_supplicant_delayed_sched_scan_timeout(void *eloop_ctx, void *timeout_ctx)
304 {
305 	struct wpa_supplicant *wpa_s = eloop_ctx;
306 
307 	wpa_dbg(wpa_s, MSG_DEBUG, "Starting delayed sched scan");
308 
309 	if (wpa_supplicant_req_sched_scan(wpa_s))
310 		wpa_supplicant_req_scan(wpa_s, 0, 0);
311 }
312 
313 
314 static void
wpa_supplicant_sched_scan_timeout(void * eloop_ctx,void * timeout_ctx)315 wpa_supplicant_sched_scan_timeout(void *eloop_ctx, void *timeout_ctx)
316 {
317 	struct wpa_supplicant *wpa_s = eloop_ctx;
318 
319 	wpa_dbg(wpa_s, MSG_DEBUG, "Sched scan timeout - stopping it");
320 
321 	wpa_s->sched_scan_timed_out = 1;
322 	wpa_supplicant_cancel_sched_scan(wpa_s);
323 }
324 
325 
326 static int
wpa_supplicant_start_sched_scan(struct wpa_supplicant * wpa_s,struct wpa_driver_scan_params * params)327 wpa_supplicant_start_sched_scan(struct wpa_supplicant *wpa_s,
328 				struct wpa_driver_scan_params *params)
329 {
330 	int ret;
331 
332 	wpa_supplicant_notify_scanning(wpa_s, 1);
333 	ret = wpa_drv_sched_scan(wpa_s, params);
334 	if (ret)
335 		wpa_supplicant_notify_scanning(wpa_s, 0);
336 	else
337 		wpa_s->sched_scanning = 1;
338 
339 	return ret;
340 }
341 
342 
wpa_supplicant_stop_sched_scan(struct wpa_supplicant * wpa_s)343 static int wpa_supplicant_stop_sched_scan(struct wpa_supplicant *wpa_s)
344 {
345 	int ret;
346 
347 	ret = wpa_drv_stop_sched_scan(wpa_s);
348 	if (ret) {
349 		wpa_dbg(wpa_s, MSG_DEBUG, "stopping sched_scan failed!");
350 		/* TODO: what to do if stopping fails? */
351 		return -1;
352 	}
353 
354 	return ret;
355 }
356 
357 
358 static struct wpa_driver_scan_filter *
wpa_supplicant_build_filter_ssids(struct wpa_config * conf,size_t * num_ssids)359 wpa_supplicant_build_filter_ssids(struct wpa_config *conf, size_t *num_ssids)
360 {
361 	struct wpa_driver_scan_filter *ssids;
362 	struct wpa_ssid *ssid;
363 	size_t count;
364 
365 	*num_ssids = 0;
366 	if (!conf->filter_ssids)
367 		return NULL;
368 
369 	for (count = 0, ssid = conf->ssid; ssid; ssid = ssid->next) {
370 		if (ssid->ssid && ssid->ssid_len)
371 			count++;
372 	}
373 	if (count == 0)
374 		return NULL;
375 	ssids = os_calloc(count, sizeof(struct wpa_driver_scan_filter));
376 	if (ssids == NULL)
377 		return NULL;
378 
379 	for (ssid = conf->ssid; ssid; ssid = ssid->next) {
380 		if (!ssid->ssid || !ssid->ssid_len)
381 			continue;
382 		os_memcpy(ssids[*num_ssids].ssid, ssid->ssid, ssid->ssid_len);
383 		ssids[*num_ssids].ssid_len = ssid->ssid_len;
384 		(*num_ssids)++;
385 	}
386 
387 	return ssids;
388 }
389 
390 
wpa_supplicant_optimize_freqs(struct wpa_supplicant * wpa_s,struct wpa_driver_scan_params * params)391 static void wpa_supplicant_optimize_freqs(
392 	struct wpa_supplicant *wpa_s, struct wpa_driver_scan_params *params)
393 {
394 #ifdef CONFIG_P2P
395 	if (params->freqs == NULL && wpa_s->p2p_in_provisioning &&
396 	    wpa_s->go_params) {
397 		/* Optimize provisioning state scan based on GO information */
398 		if (wpa_s->p2p_in_provisioning < 5 &&
399 		    wpa_s->go_params->freq > 0) {
400 			wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Scan only GO "
401 				"preferred frequency %d MHz",
402 				wpa_s->go_params->freq);
403 			params->freqs = os_calloc(2, sizeof(int));
404 			if (params->freqs)
405 				params->freqs[0] = wpa_s->go_params->freq;
406 		} else if (wpa_s->p2p_in_provisioning < 8 &&
407 			   wpa_s->go_params->freq_list[0]) {
408 			wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Scan only common "
409 				"channels");
410 			int_array_concat(&params->freqs,
411 					 wpa_s->go_params->freq_list);
412 			if (params->freqs)
413 				int_array_sort_unique(params->freqs);
414 		}
415 		wpa_s->p2p_in_provisioning++;
416 	}
417 
418 	if (params->freqs == NULL && wpa_s->p2p_in_invitation) {
419 		/*
420 		 * Optimize scan based on GO information during persistent
421 		 * group reinvocation
422 		 */
423 		if (wpa_s->p2p_in_invitation < 5 &&
424 		    wpa_s->p2p_invite_go_freq > 0) {
425 			wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Scan only GO preferred frequency %d MHz during invitation",
426 				wpa_s->p2p_invite_go_freq);
427 			params->freqs = os_calloc(2, sizeof(int));
428 			if (params->freqs)
429 				params->freqs[0] = wpa_s->p2p_invite_go_freq;
430 		}
431 		wpa_s->p2p_in_invitation++;
432 		if (wpa_s->p2p_in_invitation > 20) {
433 			/*
434 			 * This should not really happen since the variable is
435 			 * cleared on group removal, but if it does happen, make
436 			 * sure we do not get stuck in special invitation scan
437 			 * mode.
438 			 */
439 			wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Clear p2p_in_invitation");
440 			wpa_s->p2p_in_invitation = 0;
441 		}
442 	}
443 #endif /* CONFIG_P2P */
444 
445 #ifdef CONFIG_WPS
446 	if (params->freqs == NULL && wpa_s->after_wps && wpa_s->wps_freq) {
447 		/*
448 		 * Optimize post-provisioning scan based on channel used
449 		 * during provisioning.
450 		 */
451 		wpa_dbg(wpa_s, MSG_DEBUG, "WPS: Scan only frequency %u MHz "
452 			"that was used during provisioning", wpa_s->wps_freq);
453 		params->freqs = os_calloc(2, sizeof(int));
454 		if (params->freqs)
455 			params->freqs[0] = wpa_s->wps_freq;
456 		wpa_s->after_wps--;
457 	} else if (wpa_s->after_wps)
458 		wpa_s->after_wps--;
459 
460 	if (params->freqs == NULL && wpa_s->known_wps_freq && wpa_s->wps_freq)
461 	{
462 		/* Optimize provisioning scan based on already known channel */
463 		wpa_dbg(wpa_s, MSG_DEBUG, "WPS: Scan only frequency %u MHz",
464 			wpa_s->wps_freq);
465 		params->freqs = os_calloc(2, sizeof(int));
466 		if (params->freqs)
467 			params->freqs[0] = wpa_s->wps_freq;
468 		wpa_s->known_wps_freq = 0; /* only do this once */
469 	}
470 #endif /* CONFIG_WPS */
471 }
472 
473 
474 #ifdef CONFIG_INTERWORKING
wpas_add_interworking_elements(struct wpa_supplicant * wpa_s,struct wpabuf * buf)475 static void wpas_add_interworking_elements(struct wpa_supplicant *wpa_s,
476 					   struct wpabuf *buf)
477 {
478 	wpabuf_put_u8(buf, WLAN_EID_INTERWORKING);
479 	wpabuf_put_u8(buf, is_zero_ether_addr(wpa_s->conf->hessid) ? 1 :
480 		      1 + ETH_ALEN);
481 	wpabuf_put_u8(buf, wpa_s->conf->access_network_type);
482 	/* No Venue Info */
483 	if (!is_zero_ether_addr(wpa_s->conf->hessid))
484 		wpabuf_put_data(buf, wpa_s->conf->hessid, ETH_ALEN);
485 }
486 #endif /* CONFIG_INTERWORKING */
487 
488 
489 #ifdef CONFIG_MBO
wpas_fils_req_param_add_max_channel(struct wpa_supplicant * wpa_s,struct wpabuf ** ie)490 static void wpas_fils_req_param_add_max_channel(struct wpa_supplicant *wpa_s,
491 						struct wpabuf **ie)
492 {
493 	if (wpabuf_resize(ie, 5)) {
494 		wpa_printf(MSG_DEBUG,
495 			   "Failed to allocate space for FILS Request Parameters element");
496 		return;
497 	}
498 
499 	/* FILS Request Parameters element */
500 	wpabuf_put_u8(*ie, WLAN_EID_EXTENSION);
501 	wpabuf_put_u8(*ie, 3); /* FILS Request attribute length */
502 	wpabuf_put_u8(*ie, WLAN_EID_EXT_FILS_REQ_PARAMS);
503 	/* Parameter control bitmap */
504 	wpabuf_put_u8(*ie, 0);
505 	/* Max Channel Time field - contains the value of MaxChannelTime
506 	 * parameter of the MLME-SCAN.request primitive represented in units of
507 	 * TUs, as an unsigned integer. A Max Channel Time field value of 255
508 	 * is used to indicate any duration of more than 254 TUs, or an
509 	 * unspecified or unknown duration. (IEEE Std 802.11ai-2016, 9.4.2.178)
510 	 */
511 	wpabuf_put_u8(*ie, 255);
512 }
513 #endif /* CONFIG_MBO */
514 
515 
wpa_supplicant_set_default_scan_ies(struct wpa_supplicant * wpa_s)516 void wpa_supplicant_set_default_scan_ies(struct wpa_supplicant *wpa_s)
517 {
518 	struct wpabuf *default_ies = NULL;
519 	u8 ext_capab[18];
520 	int ext_capab_len;
521 	enum wpa_driver_if_type type = WPA_IF_STATION;
522 
523 #ifdef CONFIG_P2P
524 	if (wpa_s->p2p_group_interface == P2P_GROUP_INTERFACE_CLIENT)
525 		type = WPA_IF_P2P_CLIENT;
526 #endif /* CONFIG_P2P */
527 
528 	wpa_drv_get_ext_capa(wpa_s, type);
529 
530 	ext_capab_len = wpas_build_ext_capab(wpa_s, ext_capab,
531 					     sizeof(ext_capab));
532 	if (ext_capab_len > 0 &&
533 	    wpabuf_resize(&default_ies, ext_capab_len) == 0)
534 		wpabuf_put_data(default_ies, ext_capab, ext_capab_len);
535 
536 #ifdef CONFIG_MBO
537 	if (wpa_s->enable_oce & OCE_STA)
538 		wpas_fils_req_param_add_max_channel(wpa_s, &default_ies);
539 	/* Send MBO and OCE capabilities */
540 	if (wpabuf_resize(&default_ies, 12) == 0)
541 		wpas_mbo_scan_ie(wpa_s, default_ies);
542 #endif /* CONFIG_MBO */
543 
544 	if (default_ies)
545 		wpa_drv_set_default_scan_ies(wpa_s, wpabuf_head(default_ies),
546 					     wpabuf_len(default_ies));
547 	wpabuf_free(default_ies);
548 }
549 
550 
wpa_supplicant_extra_ies(struct wpa_supplicant * wpa_s)551 static struct wpabuf * wpa_supplicant_extra_ies(struct wpa_supplicant *wpa_s)
552 {
553 	struct wpabuf *extra_ie = NULL;
554 	u8 ext_capab[18];
555 	int ext_capab_len;
556 #ifdef CONFIG_WPS
557 	int wps = 0;
558 	enum wps_request_type req_type = WPS_REQ_ENROLLEE_INFO;
559 #endif /* CONFIG_WPS */
560 
561 #ifdef CONFIG_P2P
562 	if (wpa_s->p2p_group_interface == P2P_GROUP_INTERFACE_CLIENT)
563 		wpa_drv_get_ext_capa(wpa_s, WPA_IF_P2P_CLIENT);
564 	else
565 #endif /* CONFIG_P2P */
566 		wpa_drv_get_ext_capa(wpa_s, WPA_IF_STATION);
567 
568 	ext_capab_len = wpas_build_ext_capab(wpa_s, ext_capab,
569 					     sizeof(ext_capab));
570 	if (ext_capab_len > 0 &&
571 	    wpabuf_resize(&extra_ie, ext_capab_len) == 0)
572 		wpabuf_put_data(extra_ie, ext_capab, ext_capab_len);
573 
574 #ifdef CONFIG_INTERWORKING
575 	if (wpa_s->conf->interworking &&
576 	    wpabuf_resize(&extra_ie, 100) == 0)
577 		wpas_add_interworking_elements(wpa_s, extra_ie);
578 #endif /* CONFIG_INTERWORKING */
579 
580 #ifdef CONFIG_MBO
581 	if (wpa_s->enable_oce & OCE_STA)
582 		wpas_fils_req_param_add_max_channel(wpa_s, &extra_ie);
583 #endif /* CONFIG_MBO */
584 
585 #ifdef CONFIG_WPS
586 	wps = wpas_wps_in_use(wpa_s, &req_type);
587 
588 	if (wps) {
589 		struct wpabuf *wps_ie;
590 		wps_ie = wps_build_probe_req_ie(wps == 2 ? DEV_PW_PUSHBUTTON :
591 						DEV_PW_DEFAULT,
592 						&wpa_s->wps->dev,
593 						wpa_s->wps->uuid, req_type,
594 						0, NULL);
595 		if (wps_ie) {
596 			if (wpabuf_resize(&extra_ie, wpabuf_len(wps_ie)) == 0)
597 				wpabuf_put_buf(extra_ie, wps_ie);
598 			wpabuf_free(wps_ie);
599 		}
600 	}
601 
602 #ifdef CONFIG_P2P
603 	if (wps) {
604 		size_t ielen = p2p_scan_ie_buf_len(wpa_s->global->p2p);
605 		if (wpabuf_resize(&extra_ie, ielen) == 0)
606 			wpas_p2p_scan_ie(wpa_s, extra_ie);
607 	}
608 #endif /* CONFIG_P2P */
609 
610 	wpa_supplicant_mesh_add_scan_ie(wpa_s, &extra_ie);
611 
612 #endif /* CONFIG_WPS */
613 
614 #ifdef CONFIG_HS20
615 	if (wpa_s->conf->hs20 && wpabuf_resize(&extra_ie, 9) == 0)
616 		wpas_hs20_add_indication(extra_ie, -1, 0);
617 #endif /* CONFIG_HS20 */
618 
619 #ifdef CONFIG_FST
620 	if (wpa_s->fst_ies &&
621 	    wpabuf_resize(&extra_ie, wpabuf_len(wpa_s->fst_ies)) == 0)
622 		wpabuf_put_buf(extra_ie, wpa_s->fst_ies);
623 #endif /* CONFIG_FST */
624 
625 #ifdef CONFIG_MBO
626 	/* Send MBO and OCE capabilities */
627 	if (wpabuf_resize(&extra_ie, 12) == 0)
628 		wpas_mbo_scan_ie(wpa_s, extra_ie);
629 #endif /* CONFIG_MBO */
630 
631 	if (wpa_s->vendor_elem[VENDOR_ELEM_PROBE_REQ]) {
632 		struct wpabuf *buf = wpa_s->vendor_elem[VENDOR_ELEM_PROBE_REQ];
633 
634 		if (wpabuf_resize(&extra_ie, wpabuf_len(buf)) == 0)
635 			wpabuf_put_buf(extra_ie, buf);
636 	}
637 
638 	return extra_ie;
639 }
640 
641 
642 #ifdef CONFIG_P2P
643 
644 /*
645  * Check whether there are any enabled networks or credentials that could be
646  * used for a non-P2P connection.
647  */
non_p2p_network_enabled(struct wpa_supplicant * wpa_s)648 static int non_p2p_network_enabled(struct wpa_supplicant *wpa_s)
649 {
650 	struct wpa_ssid *ssid;
651 
652 	for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
653 		if (wpas_network_disabled(wpa_s, ssid))
654 			continue;
655 		if (!ssid->p2p_group)
656 			return 1;
657 	}
658 
659 	if (wpa_s->conf->cred && wpa_s->conf->interworking &&
660 	    wpa_s->conf->auto_interworking)
661 		return 1;
662 
663 	return 0;
664 }
665 
666 #endif /* CONFIG_P2P */
667 
668 
wpa_setband_scan_freqs_list(struct wpa_supplicant * wpa_s,enum hostapd_hw_mode band,struct wpa_driver_scan_params * params,int is_6ghz)669 static void wpa_setband_scan_freqs_list(struct wpa_supplicant *wpa_s,
670 					enum hostapd_hw_mode band,
671 					struct wpa_driver_scan_params *params,
672 					int is_6ghz)
673 {
674 	/* Include only supported channels for the specified band */
675 	struct hostapd_hw_modes *mode;
676 	int count, i;
677 
678 	mode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes, band, is_6ghz);
679 	if (mode == NULL) {
680 		/* No channels supported in this band - use empty list */
681 		params->freqs = os_zalloc(sizeof(int));
682 		return;
683 	}
684 
685 	params->freqs = os_calloc(mode->num_channels + 1, sizeof(int));
686 	if (params->freqs == NULL)
687 		return;
688 	for (count = 0, i = 0; i < mode->num_channels; i++) {
689 		if (mode->channels[i].flag & HOSTAPD_CHAN_DISABLED)
690 			continue;
691 		params->freqs[count++] = mode->channels[i].freq;
692 	}
693 }
694 
695 
wpa_setband_scan_freqs(struct wpa_supplicant * wpa_s,struct wpa_driver_scan_params * params)696 static void wpa_setband_scan_freqs(struct wpa_supplicant *wpa_s,
697 				   struct wpa_driver_scan_params *params)
698 {
699 	if (wpa_s->hw.modes == NULL)
700 		return; /* unknown what channels the driver supports */
701 	if (params->freqs)
702 		return; /* already using a limited channel set */
703 	if (wpa_s->setband == WPA_SETBAND_5G)
704 		wpa_setband_scan_freqs_list(wpa_s, HOSTAPD_MODE_IEEE80211A,
705 					    params, 0);
706 	else if (wpa_s->setband == WPA_SETBAND_2G)
707 		wpa_setband_scan_freqs_list(wpa_s, HOSTAPD_MODE_IEEE80211G,
708 					    params, 0);
709 }
710 
711 
wpa_add_scan_ssid(struct wpa_supplicant * wpa_s,struct wpa_driver_scan_params * params,size_t max_ssids,const u8 * ssid,size_t ssid_len)712 static void wpa_add_scan_ssid(struct wpa_supplicant *wpa_s,
713 			      struct wpa_driver_scan_params *params,
714 			      size_t max_ssids, const u8 *ssid, size_t ssid_len)
715 {
716 	unsigned int j;
717 
718 	for (j = 0; j < params->num_ssids; j++) {
719 		if (params->ssids[j].ssid_len == ssid_len &&
720 		    params->ssids[j].ssid &&
721 		    os_memcmp(params->ssids[j].ssid, ssid, ssid_len) == 0)
722 			return; /* already in the list */
723 	}
724 
725 	if (params->num_ssids + 1 > max_ssids) {
726 		wpa_printf(MSG_DEBUG, "Over max scan SSIDs for manual request");
727 		return;
728 	}
729 
730 	wpa_printf(MSG_DEBUG, "Scan SSID (manual request): %s",
731 		   wpa_ssid_txt(ssid, ssid_len));
732 
733 	params->ssids[params->num_ssids].ssid = ssid;
734 	params->ssids[params->num_ssids].ssid_len = ssid_len;
735 	params->num_ssids++;
736 }
737 
738 
wpa_add_owe_scan_ssid(struct wpa_supplicant * wpa_s,struct wpa_driver_scan_params * params,struct wpa_ssid * ssid,size_t max_ssids)739 static void wpa_add_owe_scan_ssid(struct wpa_supplicant *wpa_s,
740 				  struct wpa_driver_scan_params *params,
741 				  struct wpa_ssid *ssid, size_t max_ssids)
742 {
743 #ifdef CONFIG_OWE
744 	struct wpa_bss *bss;
745 
746 	if (!(ssid->key_mgmt & WPA_KEY_MGMT_OWE))
747 		return;
748 
749 	wpa_printf(MSG_DEBUG, "OWE: Look for transition mode AP. ssid=%s",
750 		   wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
751 
752 	dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
753 		const u8 *owe, *pos, *end;
754 		const u8 *owe_ssid;
755 		size_t owe_ssid_len;
756 
757 		if (bss->ssid_len != ssid->ssid_len ||
758 		    os_memcmp(bss->ssid, ssid->ssid, ssid->ssid_len) != 0)
759 			continue;
760 
761 		owe = wpa_bss_get_vendor_ie(bss, OWE_IE_VENDOR_TYPE);
762 		if (!owe || owe[1] < 4)
763 			continue;
764 
765 		pos = owe + 6;
766 		end = owe + 2 + owe[1];
767 
768 		/* Must include BSSID and ssid_len */
769 		if (end - pos < ETH_ALEN + 1)
770 			return;
771 
772 		/* Skip BSSID */
773 		pos += ETH_ALEN;
774 		owe_ssid_len = *pos++;
775 		owe_ssid = pos;
776 
777 		if ((size_t) (end - pos) < owe_ssid_len ||
778 		    owe_ssid_len > SSID_MAX_LEN)
779 			return;
780 
781 		wpa_printf(MSG_DEBUG,
782 			   "OWE: scan_ssids: transition mode OWE ssid=%s",
783 			   wpa_ssid_txt(owe_ssid, owe_ssid_len));
784 
785 		wpa_add_scan_ssid(wpa_s, params, max_ssids,
786 				  owe_ssid, owe_ssid_len);
787 		return;
788 	}
789 #endif /* CONFIG_OWE */
790 }
791 
792 
wpa_set_scan_ssids(struct wpa_supplicant * wpa_s,struct wpa_driver_scan_params * params,size_t max_ssids)793 static void wpa_set_scan_ssids(struct wpa_supplicant *wpa_s,
794 			       struct wpa_driver_scan_params *params,
795 			       size_t max_ssids)
796 {
797 	unsigned int i;
798 	struct wpa_ssid *ssid;
799 
800 	/*
801 	 * For devices with max_ssids greater than 1, leave the last slot empty
802 	 * for adding the wildcard scan entry.
803 	 */
804 	max_ssids = max_ssids > 1 ? max_ssids - 1 : max_ssids;
805 
806 	for (i = 0; i < wpa_s->scan_id_count; i++) {
807 		ssid = wpa_config_get_network(wpa_s->conf, wpa_s->scan_id[i]);
808 		if (!ssid)
809 			continue;
810 		if (ssid->scan_ssid)
811 			wpa_add_scan_ssid(wpa_s, params, max_ssids,
812 					  ssid->ssid, ssid->ssid_len);
813 		/*
814 		 * Also add the SSID of the OWE BSS, to allow discovery of
815 		 * transition mode APs more quickly.
816 		 */
817 		wpa_add_owe_scan_ssid(wpa_s, params, ssid, max_ssids);
818 	}
819 
820 	wpa_s->scan_id_count = 0;
821 }
822 
823 
wpa_set_ssids_from_scan_req(struct wpa_supplicant * wpa_s,struct wpa_driver_scan_params * params,size_t max_ssids)824 static int wpa_set_ssids_from_scan_req(struct wpa_supplicant *wpa_s,
825 				       struct wpa_driver_scan_params *params,
826 				       size_t max_ssids)
827 {
828 	unsigned int i;
829 
830 	if (wpa_s->ssids_from_scan_req == NULL ||
831 	    wpa_s->num_ssids_from_scan_req == 0)
832 		return 0;
833 
834 	if (wpa_s->num_ssids_from_scan_req > max_ssids) {
835 		wpa_s->num_ssids_from_scan_req = max_ssids;
836 		wpa_printf(MSG_DEBUG, "Over max scan SSIDs from scan req: %u",
837 			   (unsigned int) max_ssids);
838 	}
839 
840 	for (i = 0; i < wpa_s->num_ssids_from_scan_req; i++) {
841 		params->ssids[i].ssid = wpa_s->ssids_from_scan_req[i].ssid;
842 		params->ssids[i].ssid_len =
843 			wpa_s->ssids_from_scan_req[i].ssid_len;
844 		wpa_hexdump_ascii(MSG_DEBUG, "specific SSID",
845 				  params->ssids[i].ssid,
846 				  params->ssids[i].ssid_len);
847 	}
848 
849 	params->num_ssids = wpa_s->num_ssids_from_scan_req;
850 	wpa_s->num_ssids_from_scan_req = 0;
851 	return 1;
852 }
853 
854 
wpa_supplicant_scan(void * eloop_ctx,void * timeout_ctx)855 static void wpa_supplicant_scan(void *eloop_ctx, void *timeout_ctx)
856 {
857 	struct wpa_supplicant *wpa_s = eloop_ctx;
858 	struct wpa_ssid *ssid;
859 	int ret, p2p_in_prog;
860 	struct wpabuf *extra_ie = NULL;
861 	struct wpa_driver_scan_params params;
862 	struct wpa_driver_scan_params *scan_params;
863 	size_t max_ssids;
864 	int connect_without_scan = 0;
865 
866 	wpa_s->ignore_post_flush_scan_res = 0;
867 
868 	if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
869 		wpa_dbg(wpa_s, MSG_DEBUG, "Skip scan - interface disabled");
870 		return;
871 	}
872 
873 	if (wpa_s->disconnected && wpa_s->scan_req == NORMAL_SCAN_REQ) {
874 		wpa_dbg(wpa_s, MSG_DEBUG, "Disconnected - do not scan");
875 		wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
876 		return;
877 	}
878 
879 	if (wpa_s->scanning) {
880 		/*
881 		 * If we are already in scanning state, we shall reschedule the
882 		 * the incoming scan request.
883 		 */
884 		wpa_dbg(wpa_s, MSG_DEBUG, "Already scanning - Reschedule the incoming scan req");
885 		wpa_supplicant_req_scan(wpa_s, 1, 0);
886 		return;
887 	}
888 
889 	if (!wpa_supplicant_enabled_networks(wpa_s) &&
890 	    wpa_s->scan_req == NORMAL_SCAN_REQ) {
891 		wpa_dbg(wpa_s, MSG_DEBUG, "No enabled networks - do not scan");
892 		wpa_supplicant_set_state(wpa_s, WPA_INACTIVE);
893 		return;
894 	}
895 
896 	if (wpa_s->conf->ap_scan != 0 &&
897 	    (wpa_s->drv_flags & WPA_DRIVER_FLAGS_WIRED)) {
898 		wpa_dbg(wpa_s, MSG_DEBUG, "Using wired authentication - "
899 			"overriding ap_scan configuration");
900 		wpa_s->conf->ap_scan = 0;
901 		wpas_notify_ap_scan_changed(wpa_s);
902 	}
903 
904 	if (wpa_s->conf->ap_scan == 0) {
905 		wpa_supplicant_gen_assoc_event(wpa_s);
906 		return;
907 	}
908 
909 	ssid = NULL;
910 	if (wpa_s->scan_req != MANUAL_SCAN_REQ &&
911 	    wpa_s->connect_without_scan) {
912 		connect_without_scan = 1;
913 		for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
914 			if (ssid == wpa_s->connect_without_scan)
915 				break;
916 		}
917 	}
918 
919 	p2p_in_prog = wpas_p2p_in_progress(wpa_s);
920 	if (p2p_in_prog && p2p_in_prog != 2 &&
921 	    (!ssid ||
922 	     (ssid->mode != WPAS_MODE_AP && ssid->mode != WPAS_MODE_P2P_GO))) {
923 		wpa_dbg(wpa_s, MSG_DEBUG, "Delay station mode scan while P2P operation is in progress");
924 		wpa_supplicant_req_scan(wpa_s, 5, 0);
925 		return;
926 	}
927 
928 	/*
929 	 * Don't cancel the scan based on ongoing PNO; defer it. Some scans are
930 	 * used for changing modes inside wpa_supplicant (roaming,
931 	 * auto-reconnect, etc). Discarding the scan might hurt these processes.
932 	 * The normal use case for PNO is to suspend the host immediately after
933 	 * starting PNO, so the periodic 100 ms attempts to run the scan do not
934 	 * normally happen in practice multiple times, i.e., this is simply
935 	 * restarting scanning once the host is woken up and PNO stopped.
936 	 */
937 	if (wpa_s->pno || wpa_s->pno_sched_pending) {
938 		wpa_dbg(wpa_s, MSG_DEBUG, "Defer scan - PNO is in progress");
939 		wpa_supplicant_req_scan(wpa_s, 0, 100000);
940 		return;
941 	}
942 
943 	if (wpa_s->conf->ap_scan == 2)
944 		max_ssids = 1;
945 	else {
946 		max_ssids = wpa_s->max_scan_ssids;
947 		if (max_ssids > WPAS_MAX_SCAN_SSIDS)
948 			max_ssids = WPAS_MAX_SCAN_SSIDS;
949 	}
950 
951 	wpa_s->last_scan_req = wpa_s->scan_req;
952 	wpa_s->scan_req = NORMAL_SCAN_REQ;
953 
954 	if (connect_without_scan) {
955 		wpa_s->connect_without_scan = NULL;
956 		if (ssid) {
957 			wpa_printf(MSG_DEBUG, "Start a pre-selected network "
958 				   "without scan step");
959 			wpa_supplicant_associate(wpa_s, NULL, ssid);
960 			return;
961 		}
962 	}
963 
964 	os_memset(&params, 0, sizeof(params));
965 
966 	wpa_s->scan_prev_wpa_state = wpa_s->wpa_state;
967 	if (wpa_s->wpa_state == WPA_DISCONNECTED ||
968 	    wpa_s->wpa_state == WPA_INACTIVE)
969 		wpa_supplicant_set_state(wpa_s, WPA_SCANNING);
970 
971 	/*
972 	 * If autoscan has set its own scanning parameters
973 	 */
974 	if (wpa_s->autoscan_params != NULL) {
975 		scan_params = wpa_s->autoscan_params;
976 		goto scan;
977 	}
978 
979 	if (wpa_s->last_scan_req == MANUAL_SCAN_REQ &&
980 	    wpa_set_ssids_from_scan_req(wpa_s, &params, max_ssids)) {
981 		wpa_printf(MSG_DEBUG, "Use specific SSIDs from SCAN command");
982 		goto ssid_list_set;
983 	}
984 
985 #ifdef CONFIG_P2P
986 	if ((wpa_s->p2p_in_provisioning || wpa_s->show_group_started) &&
987 	    wpa_s->go_params && !wpa_s->conf->passive_scan) {
988 		wpa_printf(MSG_DEBUG, "P2P: Use specific SSID for scan during P2P group formation (p2p_in_provisioning=%d show_group_started=%d)",
989 			   wpa_s->p2p_in_provisioning,
990 			   wpa_s->show_group_started);
991 		params.ssids[0].ssid = wpa_s->go_params->ssid;
992 		params.ssids[0].ssid_len = wpa_s->go_params->ssid_len;
993 		params.num_ssids = 1;
994 		goto ssid_list_set;
995 	}
996 
997 	if (wpa_s->p2p_in_invitation) {
998 		if (wpa_s->current_ssid) {
999 			wpa_printf(MSG_DEBUG, "P2P: Use specific SSID for scan during invitation");
1000 			params.ssids[0].ssid = wpa_s->current_ssid->ssid;
1001 			params.ssids[0].ssid_len =
1002 				wpa_s->current_ssid->ssid_len;
1003 			params.num_ssids = 1;
1004 		} else {
1005 			wpa_printf(MSG_DEBUG, "P2P: No specific SSID known for scan during invitation");
1006 		}
1007 		goto ssid_list_set;
1008 	}
1009 #endif /* CONFIG_P2P */
1010 
1011 	/* Find the starting point from which to continue scanning */
1012 	ssid = wpa_s->conf->ssid;
1013 	if (wpa_s->prev_scan_ssid != WILDCARD_SSID_SCAN) {
1014 		while (ssid) {
1015 			if (ssid == wpa_s->prev_scan_ssid) {
1016 				ssid = ssid->next;
1017 				break;
1018 			}
1019 			ssid = ssid->next;
1020 		}
1021 	}
1022 
1023 	if (wpa_s->last_scan_req != MANUAL_SCAN_REQ &&
1024 #ifdef CONFIG_AP
1025 	    !wpa_s->ap_iface &&
1026 #endif /* CONFIG_AP */
1027 	    wpa_s->conf->ap_scan == 2) {
1028 		wpa_s->connect_without_scan = NULL;
1029 		wpa_s->prev_scan_wildcard = 0;
1030 		wpa_supplicant_assoc_try(wpa_s, ssid);
1031 		return;
1032 	} else if (wpa_s->conf->ap_scan == 2) {
1033 		/*
1034 		 * User-initiated scan request in ap_scan == 2; scan with
1035 		 * wildcard SSID.
1036 		 */
1037 		ssid = NULL;
1038 	} else if (wpa_s->reattach && wpa_s->current_ssid != NULL) {
1039 		/*
1040 		 * Perform single-channel single-SSID scan for
1041 		 * reassociate-to-same-BSS operation.
1042 		 */
1043 		/* Setup SSID */
1044 		ssid = wpa_s->current_ssid;
1045 		wpa_hexdump_ascii(MSG_DEBUG, "Scan SSID",
1046 				  ssid->ssid, ssid->ssid_len);
1047 		params.ssids[0].ssid = ssid->ssid;
1048 		params.ssids[0].ssid_len = ssid->ssid_len;
1049 		params.num_ssids = 1;
1050 
1051 		/*
1052 		 * Allocate memory for frequency array, allocate one extra
1053 		 * slot for the zero-terminator.
1054 		 */
1055 		params.freqs = os_malloc(sizeof(int) * 2);
1056 		if (params.freqs) {
1057 			params.freqs[0] = wpa_s->assoc_freq;
1058 			params.freqs[1] = 0;
1059 		}
1060 
1061 		/*
1062 		 * Reset the reattach flag so that we fall back to full scan if
1063 		 * this scan fails.
1064 		 */
1065 		wpa_s->reattach = 0;
1066 	} else {
1067 		struct wpa_ssid *start = ssid, *tssid;
1068 		int freqs_set = 0;
1069 		if (ssid == NULL && max_ssids > 1)
1070 			ssid = wpa_s->conf->ssid;
1071 		while (ssid) {
1072 			if (!wpas_network_disabled(wpa_s, ssid) &&
1073 			    ssid->scan_ssid) {
1074 				wpa_hexdump_ascii(MSG_DEBUG, "Scan SSID",
1075 						  ssid->ssid, ssid->ssid_len);
1076 				params.ssids[params.num_ssids].ssid =
1077 					ssid->ssid;
1078 				params.ssids[params.num_ssids].ssid_len =
1079 					ssid->ssid_len;
1080 				params.num_ssids++;
1081 				if (params.num_ssids + 1 >= max_ssids)
1082 					break;
1083 			}
1084 
1085 			if (!wpas_network_disabled(wpa_s, ssid)) {
1086 				/*
1087 				 * Also add the SSID of the OWE BSS, to allow
1088 				 * discovery of transition mode APs more
1089 				 * quickly.
1090 				 */
1091 				wpa_add_owe_scan_ssid(wpa_s, &params, ssid,
1092 						      max_ssids);
1093 			}
1094 
1095 			ssid = ssid->next;
1096 			if (ssid == start)
1097 				break;
1098 			if (ssid == NULL && max_ssids > 1 &&
1099 			    start != wpa_s->conf->ssid)
1100 				ssid = wpa_s->conf->ssid;
1101 		}
1102 
1103 		if (wpa_s->scan_id_count &&
1104 		    wpa_s->last_scan_req == MANUAL_SCAN_REQ)
1105 			wpa_set_scan_ssids(wpa_s, &params, max_ssids);
1106 
1107 		for (tssid = wpa_s->conf->ssid;
1108 		     wpa_s->last_scan_req != MANUAL_SCAN_REQ && tssid;
1109 		     tssid = tssid->next) {
1110 			if (wpas_network_disabled(wpa_s, tssid))
1111 				continue;
1112 			if (((params.freqs || !freqs_set) &&
1113 			     tssid->scan_freq) &&
1114 			    int_array_len(params.freqs) < 100) {
1115 				int_array_concat(&params.freqs,
1116 						 tssid->scan_freq);
1117 			} else {
1118 				os_free(params.freqs);
1119 				params.freqs = NULL;
1120 			}
1121 			freqs_set = 1;
1122 		}
1123 		int_array_sort_unique(params.freqs);
1124 	}
1125 
1126 	if (ssid && max_ssids == 1) {
1127 		/*
1128 		 * If the driver is limited to 1 SSID at a time interleave
1129 		 * wildcard SSID scans with specific SSID scans to avoid
1130 		 * waiting a long time for a wildcard scan.
1131 		 */
1132 		if (!wpa_s->prev_scan_wildcard) {
1133 			params.ssids[0].ssid = NULL;
1134 			params.ssids[0].ssid_len = 0;
1135 			wpa_s->prev_scan_wildcard = 1;
1136 			wpa_dbg(wpa_s, MSG_DEBUG, "Starting AP scan for "
1137 				"wildcard SSID (Interleave with specific)");
1138 		} else {
1139 			wpa_s->prev_scan_ssid = ssid;
1140 			wpa_s->prev_scan_wildcard = 0;
1141 			wpa_dbg(wpa_s, MSG_DEBUG,
1142 				"Starting AP scan for specific SSID: %s",
1143 				wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
1144 		}
1145 	} else if (ssid) {
1146 		/* max_ssids > 1 */
1147 
1148 		wpa_s->prev_scan_ssid = ssid;
1149 		wpa_dbg(wpa_s, MSG_DEBUG, "Include wildcard SSID in "
1150 			"the scan request");
1151 		params.num_ssids++;
1152 	} else if (wpa_s->last_scan_req == MANUAL_SCAN_REQ &&
1153 		   wpa_s->manual_scan_passive && params.num_ssids == 0) {
1154 		wpa_dbg(wpa_s, MSG_DEBUG, "Use passive scan based on manual request");
1155 	} else if (wpa_s->conf->passive_scan) {
1156 		wpa_dbg(wpa_s, MSG_DEBUG,
1157 			"Use passive scan based on configuration");
1158 	} else {
1159 		wpa_s->prev_scan_ssid = WILDCARD_SSID_SCAN;
1160 		params.num_ssids++;
1161 		wpa_dbg(wpa_s, MSG_DEBUG, "Starting AP scan for wildcard "
1162 			"SSID");
1163 	}
1164 
1165 ssid_list_set:
1166 	wpa_supplicant_optimize_freqs(wpa_s, &params);
1167 	extra_ie = wpa_supplicant_extra_ies(wpa_s);
1168 
1169 	if (wpa_s->last_scan_req == MANUAL_SCAN_REQ &&
1170 	    wpa_s->manual_scan_only_new) {
1171 		wpa_printf(MSG_DEBUG,
1172 			   "Request driver to clear scan cache due to manual only_new=1 scan");
1173 		params.only_new_results = 1;
1174 	}
1175 
1176 	if (wpa_s->last_scan_req == MANUAL_SCAN_REQ && params.freqs == NULL &&
1177 	    wpa_s->manual_scan_freqs) {
1178 		wpa_dbg(wpa_s, MSG_DEBUG, "Limit manual scan to specified channels");
1179 		params.freqs = wpa_s->manual_scan_freqs;
1180 		wpa_s->manual_scan_freqs = NULL;
1181 	}
1182 
1183 	if (params.freqs == NULL && wpa_s->select_network_scan_freqs) {
1184 		wpa_dbg(wpa_s, MSG_DEBUG,
1185 			"Limit select_network scan to specified channels");
1186 		params.freqs = wpa_s->select_network_scan_freqs;
1187 		wpa_s->select_network_scan_freqs = NULL;
1188 	}
1189 
1190 	if (params.freqs == NULL && wpa_s->next_scan_freqs) {
1191 		wpa_dbg(wpa_s, MSG_DEBUG, "Optimize scan based on previously "
1192 			"generated frequency list");
1193 		params.freqs = wpa_s->next_scan_freqs;
1194 	} else
1195 		os_free(wpa_s->next_scan_freqs);
1196 	wpa_s->next_scan_freqs = NULL;
1197 	wpa_setband_scan_freqs(wpa_s, &params);
1198 
1199 	/* See if user specified frequencies. If so, scan only those. */
1200 	if (wpa_s->conf->freq_list && !params.freqs) {
1201 		wpa_dbg(wpa_s, MSG_DEBUG,
1202 			"Optimize scan based on conf->freq_list");
1203 		int_array_concat(&params.freqs, wpa_s->conf->freq_list);
1204 	}
1205 
1206 	/* Use current associated channel? */
1207 	if (wpa_s->conf->scan_cur_freq && !params.freqs) {
1208 		unsigned int num = wpa_s->num_multichan_concurrent;
1209 
1210 		params.freqs = os_calloc(num + 1, sizeof(int));
1211 		if (params.freqs) {
1212 			num = get_shared_radio_freqs(wpa_s, params.freqs, num);
1213 			if (num > 0) {
1214 				wpa_dbg(wpa_s, MSG_DEBUG, "Scan only the "
1215 					"current operating channels since "
1216 					"scan_cur_freq is enabled");
1217 			} else {
1218 				os_free(params.freqs);
1219 				params.freqs = NULL;
1220 			}
1221 		}
1222 	}
1223 
1224 #ifdef CONFIG_MBO
1225 	if (wpa_s->enable_oce & OCE_STA)
1226 		params.oce_scan = 1;
1227 #endif /* CONFIG_MBO */
1228 
1229 	params.filter_ssids = wpa_supplicant_build_filter_ssids(
1230 		wpa_s->conf, &params.num_filter_ssids);
1231 	if (extra_ie) {
1232 		params.extra_ies = wpabuf_head(extra_ie);
1233 		params.extra_ies_len = wpabuf_len(extra_ie);
1234 	}
1235 
1236 #ifdef CONFIG_P2P
1237 	if (wpa_s->p2p_in_provisioning || wpa_s->p2p_in_invitation ||
1238 	    (wpa_s->show_group_started && wpa_s->go_params)) {
1239 		/*
1240 		 * The interface may not yet be in P2P mode, so we have to
1241 		 * explicitly request P2P probe to disable CCK rates.
1242 		 */
1243 		params.p2p_probe = 1;
1244 	}
1245 #endif /* CONFIG_P2P */
1246 
1247 	if ((wpa_s->mac_addr_rand_enable & MAC_ADDR_RAND_SCAN) &&
1248 	    wpa_s->wpa_state <= WPA_SCANNING)
1249 		wpa_setup_mac_addr_rand_params(&params, wpa_s->mac_addr_scan);
1250 
1251 	if (!is_zero_ether_addr(wpa_s->next_scan_bssid)) {
1252 		struct wpa_bss *bss;
1253 
1254 		params.bssid = wpa_s->next_scan_bssid;
1255 		bss = wpa_bss_get_bssid_latest(wpa_s, params.bssid);
1256 		if (!wpa_s->next_scan_bssid_wildcard_ssid &&
1257 		    bss && bss->ssid_len && params.num_ssids == 1 &&
1258 		    params.ssids[0].ssid_len == 0) {
1259 			params.ssids[0].ssid = bss->ssid;
1260 			params.ssids[0].ssid_len = bss->ssid_len;
1261 			wpa_dbg(wpa_s, MSG_DEBUG,
1262 				"Scan a previously specified BSSID " MACSTR
1263 				" and SSID %s",
1264 				MAC2STR(params.bssid),
1265 				wpa_ssid_txt(bss->ssid, bss->ssid_len));
1266 		} else {
1267 			wpa_dbg(wpa_s, MSG_DEBUG,
1268 				"Scan a previously specified BSSID " MACSTR,
1269 				MAC2STR(params.bssid));
1270 		}
1271 	}
1272 
1273 	scan_params = &params;
1274 
1275 scan:
1276 #ifdef CONFIG_P2P
1277 	/*
1278 	 * If the driver does not support multi-channel concurrency and a
1279 	 * virtual interface that shares the same radio with the wpa_s interface
1280 	 * is operating there may not be need to scan other channels apart from
1281 	 * the current operating channel on the other virtual interface. Filter
1282 	 * out other channels in case we are trying to find a connection for a
1283 	 * station interface when we are not configured to prefer station
1284 	 * connection and a concurrent operation is already in process.
1285 	 */
1286 	if (wpa_s->scan_for_connection &&
1287 	    wpa_s->last_scan_req == NORMAL_SCAN_REQ &&
1288 	    !scan_params->freqs && !params.freqs &&
1289 	    wpas_is_p2p_prioritized(wpa_s) &&
1290 	    wpa_s->p2p_group_interface == NOT_P2P_GROUP_INTERFACE &&
1291 	    non_p2p_network_enabled(wpa_s)) {
1292 		unsigned int num = wpa_s->num_multichan_concurrent;
1293 
1294 		params.freqs = os_calloc(num + 1, sizeof(int));
1295 		if (params.freqs) {
1296 			num = get_shared_radio_freqs(wpa_s, params.freqs, num);
1297 			if (num > 0 && num == wpa_s->num_multichan_concurrent) {
1298 				wpa_dbg(wpa_s, MSG_DEBUG, "Scan only the current operating channels since all channels are already used");
1299 			} else {
1300 				os_free(params.freqs);
1301 				params.freqs = NULL;
1302 			}
1303 		}
1304 	}
1305 #endif /* CONFIG_P2P */
1306 
1307 	ret = wpa_supplicant_trigger_scan(wpa_s, scan_params);
1308 
1309 	if (ret && wpa_s->last_scan_req == MANUAL_SCAN_REQ && params.freqs &&
1310 	    !wpa_s->manual_scan_freqs) {
1311 		/* Restore manual_scan_freqs for the next attempt */
1312 		wpa_s->manual_scan_freqs = params.freqs;
1313 		params.freqs = NULL;
1314 	}
1315 
1316 	wpabuf_free(extra_ie);
1317 	os_free(params.freqs);
1318 	os_free(params.filter_ssids);
1319 	os_free(params.mac_addr);
1320 
1321 	if (ret) {
1322 		wpa_msg(wpa_s, MSG_WARNING, "Failed to initiate AP scan");
1323 		if (wpa_s->scan_prev_wpa_state != wpa_s->wpa_state)
1324 			wpa_supplicant_set_state(wpa_s,
1325 						 wpa_s->scan_prev_wpa_state);
1326 		/* Restore scan_req since we will try to scan again */
1327 		wpa_s->scan_req = wpa_s->last_scan_req;
1328 		wpa_supplicant_req_scan(wpa_s, 1, 0);
1329 	} else {
1330 		wpa_s->scan_for_connection = 0;
1331 #ifdef CONFIG_INTERWORKING
1332 		wpa_s->interworking_fast_assoc_tried = 0;
1333 #endif /* CONFIG_INTERWORKING */
1334 		wpa_s->next_scan_bssid_wildcard_ssid = 0;
1335 		if (params.bssid)
1336 			os_memset(wpa_s->next_scan_bssid, 0, ETH_ALEN);
1337 	}
1338 }
1339 
1340 
wpa_supplicant_update_scan_int(struct wpa_supplicant * wpa_s,int sec)1341 void wpa_supplicant_update_scan_int(struct wpa_supplicant *wpa_s, int sec)
1342 {
1343 	struct os_reltime remaining, new_int;
1344 	int cancelled;
1345 
1346 	cancelled = eloop_cancel_timeout_one(wpa_supplicant_scan, wpa_s, NULL,
1347 					     &remaining);
1348 
1349 	new_int.sec = sec;
1350 	new_int.usec = 0;
1351 	if (cancelled && os_reltime_before(&remaining, &new_int)) {
1352 		new_int.sec = remaining.sec;
1353 		new_int.usec = remaining.usec;
1354 	}
1355 
1356 	if (cancelled) {
1357 		eloop_register_timeout(new_int.sec, new_int.usec,
1358 				       wpa_supplicant_scan, wpa_s, NULL);
1359 	}
1360 	wpa_s->scan_interval = sec;
1361 }
1362 
1363 
1364 /**
1365  * wpa_supplicant_req_scan - Schedule a scan for neighboring access points
1366  * @wpa_s: Pointer to wpa_supplicant data
1367  * @sec: Number of seconds after which to scan
1368  * @usec: Number of microseconds after which to scan
1369  *
1370  * This function is used to schedule a scan for neighboring access points after
1371  * the specified time.
1372  */
wpa_supplicant_req_scan(struct wpa_supplicant * wpa_s,int sec,int usec)1373 void wpa_supplicant_req_scan(struct wpa_supplicant *wpa_s, int sec, int usec)
1374 {
1375 	int res;
1376 
1377 	if (wpa_s->p2p_mgmt) {
1378 		wpa_dbg(wpa_s, MSG_DEBUG,
1379 			"Ignore scan request (%d.%06d sec) on p2p_mgmt interface",
1380 			sec, usec);
1381 		return;
1382 	}
1383 
1384 	res = eloop_deplete_timeout(sec, usec, wpa_supplicant_scan, wpa_s,
1385 				    NULL);
1386 	if (res == 1) {
1387 		wpa_dbg(wpa_s, MSG_DEBUG, "Rescheduling scan request: %d.%06d sec",
1388 			sec, usec);
1389 	} else if (res == 0) {
1390 		wpa_dbg(wpa_s, MSG_DEBUG, "Ignore new scan request for %d.%06d sec since an earlier request is scheduled to trigger sooner",
1391 			sec, usec);
1392 	} else {
1393 		wpa_dbg(wpa_s, MSG_DEBUG, "Setting scan request: %d.%06d sec",
1394 			sec, usec);
1395 		eloop_register_timeout(sec, usec, wpa_supplicant_scan, wpa_s, NULL);
1396 	}
1397 }
1398 
1399 
1400 /**
1401  * wpa_supplicant_delayed_sched_scan - Request a delayed scheduled scan
1402  * @wpa_s: Pointer to wpa_supplicant data
1403  * @sec: Number of seconds after which to scan
1404  * @usec: Number of microseconds after which to scan
1405  * Returns: 0 on success or -1 otherwise
1406  *
1407  * This function is used to schedule periodic scans for neighboring
1408  * access points after the specified time.
1409  */
wpa_supplicant_delayed_sched_scan(struct wpa_supplicant * wpa_s,int sec,int usec)1410 int wpa_supplicant_delayed_sched_scan(struct wpa_supplicant *wpa_s,
1411 				      int sec, int usec)
1412 {
1413 	if (!wpa_s->sched_scan_supported)
1414 		return -1;
1415 
1416 	eloop_register_timeout(sec, usec,
1417 			       wpa_supplicant_delayed_sched_scan_timeout,
1418 			       wpa_s, NULL);
1419 
1420 	return 0;
1421 }
1422 
1423 
1424 static void
wpa_scan_set_relative_rssi_params(struct wpa_supplicant * wpa_s,struct wpa_driver_scan_params * params)1425 wpa_scan_set_relative_rssi_params(struct wpa_supplicant *wpa_s,
1426 				  struct wpa_driver_scan_params *params)
1427 {
1428 	if (wpa_s->wpa_state != WPA_COMPLETED ||
1429 	    !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_SCHED_SCAN_RELATIVE_RSSI) ||
1430 	    wpa_s->srp.relative_rssi_set == 0)
1431 		return;
1432 
1433 	params->relative_rssi_set = 1;
1434 	params->relative_rssi = wpa_s->srp.relative_rssi;
1435 
1436 	if (wpa_s->srp.relative_adjust_rssi == 0)
1437 		return;
1438 
1439 	params->relative_adjust_band = wpa_s->srp.relative_adjust_band;
1440 	params->relative_adjust_rssi = wpa_s->srp.relative_adjust_rssi;
1441 }
1442 
1443 
1444 /**
1445  * wpa_supplicant_req_sched_scan - Start a periodic scheduled scan
1446  * @wpa_s: Pointer to wpa_supplicant data
1447  * Returns: 0 is sched_scan was started or -1 otherwise
1448  *
1449  * This function is used to schedule periodic scans for neighboring
1450  * access points repeating the scan continuously.
1451  */
wpa_supplicant_req_sched_scan(struct wpa_supplicant * wpa_s)1452 int wpa_supplicant_req_sched_scan(struct wpa_supplicant *wpa_s)
1453 {
1454 	struct wpa_driver_scan_params params;
1455 	struct wpa_driver_scan_params *scan_params;
1456 	enum wpa_states prev_state;
1457 	struct wpa_ssid *ssid = NULL;
1458 	struct wpabuf *extra_ie = NULL;
1459 	int ret;
1460 	unsigned int max_sched_scan_ssids;
1461 	int wildcard = 0;
1462 	int need_ssids;
1463 	struct sched_scan_plan scan_plan;
1464 
1465 	if (!wpa_s->sched_scan_supported)
1466 		return -1;
1467 
1468 	if (wpa_s->max_sched_scan_ssids > WPAS_MAX_SCAN_SSIDS)
1469 		max_sched_scan_ssids = WPAS_MAX_SCAN_SSIDS;
1470 	else
1471 		max_sched_scan_ssids = wpa_s->max_sched_scan_ssids;
1472 	if (max_sched_scan_ssids < 1 || wpa_s->conf->disable_scan_offload)
1473 		return -1;
1474 
1475 	wpa_s->sched_scan_stop_req = 0;
1476 
1477 	if (wpa_s->sched_scanning) {
1478 		wpa_dbg(wpa_s, MSG_DEBUG, "Already sched scanning");
1479 		return 0;
1480 	}
1481 
1482 	need_ssids = 0;
1483 	for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
1484 		if (!wpas_network_disabled(wpa_s, ssid) && !ssid->scan_ssid) {
1485 			/* Use wildcard SSID to find this network */
1486 			wildcard = 1;
1487 		} else if (!wpas_network_disabled(wpa_s, ssid) &&
1488 			   ssid->ssid_len)
1489 			need_ssids++;
1490 
1491 #ifdef CONFIG_WPS
1492 		if (!wpas_network_disabled(wpa_s, ssid) &&
1493 		    ssid->key_mgmt == WPA_KEY_MGMT_WPS) {
1494 			/*
1495 			 * Normal scan is more reliable and faster for WPS
1496 			 * operations and since these are for short periods of
1497 			 * time, the benefit of trying to use sched_scan would
1498 			 * be limited.
1499 			 */
1500 			wpa_dbg(wpa_s, MSG_DEBUG, "Use normal scan instead of "
1501 				"sched_scan for WPS");
1502 			return -1;
1503 		}
1504 #endif /* CONFIG_WPS */
1505 	}
1506 	if (wildcard)
1507 		need_ssids++;
1508 
1509 	if (wpa_s->normal_scans < 3 &&
1510 	    (need_ssids <= wpa_s->max_scan_ssids ||
1511 	     wpa_s->max_scan_ssids >= (int) max_sched_scan_ssids)) {
1512 		/*
1513 		 * When normal scan can speed up operations, use that for the
1514 		 * first operations before starting the sched_scan to allow
1515 		 * user space sleep more. We do this only if the normal scan
1516 		 * has functionality that is suitable for this or if the
1517 		 * sched_scan does not have better support for multiple SSIDs.
1518 		 */
1519 		wpa_dbg(wpa_s, MSG_DEBUG, "Use normal scan instead of "
1520 			"sched_scan for initial scans (normal_scans=%d)",
1521 			wpa_s->normal_scans);
1522 		return -1;
1523 	}
1524 
1525 	os_memset(&params, 0, sizeof(params));
1526 
1527 	/* If we can't allocate space for the filters, we just don't filter */
1528 	params.filter_ssids = os_calloc(wpa_s->max_match_sets,
1529 					sizeof(struct wpa_driver_scan_filter));
1530 
1531 	prev_state = wpa_s->wpa_state;
1532 	if (wpa_s->wpa_state == WPA_DISCONNECTED ||
1533 	    wpa_s->wpa_state == WPA_INACTIVE)
1534 		wpa_supplicant_set_state(wpa_s, WPA_SCANNING);
1535 
1536 	if (wpa_s->autoscan_params != NULL) {
1537 		scan_params = wpa_s->autoscan_params;
1538 		goto scan;
1539 	}
1540 
1541 	/* Find the starting point from which to continue scanning */
1542 	ssid = wpa_s->conf->ssid;
1543 	if (wpa_s->prev_sched_ssid) {
1544 		while (ssid) {
1545 			if (ssid == wpa_s->prev_sched_ssid) {
1546 				ssid = ssid->next;
1547 				break;
1548 			}
1549 			ssid = ssid->next;
1550 		}
1551 	}
1552 
1553 	if (!ssid || !wpa_s->prev_sched_ssid) {
1554 		wpa_dbg(wpa_s, MSG_DEBUG, "Beginning of SSID list");
1555 		wpa_s->sched_scan_timeout = max_sched_scan_ssids * 2;
1556 		wpa_s->first_sched_scan = 1;
1557 		ssid = wpa_s->conf->ssid;
1558 		wpa_s->prev_sched_ssid = ssid;
1559 	}
1560 
1561 	if (wildcard) {
1562 		wpa_dbg(wpa_s, MSG_DEBUG, "Add wildcard SSID to sched_scan");
1563 		params.num_ssids++;
1564 	}
1565 
1566 	while (ssid) {
1567 		if (wpas_network_disabled(wpa_s, ssid))
1568 			goto next;
1569 
1570 		if (params.num_filter_ssids < wpa_s->max_match_sets &&
1571 		    params.filter_ssids && ssid->ssid && ssid->ssid_len) {
1572 			wpa_dbg(wpa_s, MSG_DEBUG, "add to filter ssid: %s",
1573 				wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
1574 			os_memcpy(params.filter_ssids[params.num_filter_ssids].ssid,
1575 				  ssid->ssid, ssid->ssid_len);
1576 			params.filter_ssids[params.num_filter_ssids].ssid_len =
1577 				ssid->ssid_len;
1578 			params.num_filter_ssids++;
1579 		} else if (params.filter_ssids && ssid->ssid && ssid->ssid_len)
1580 		{
1581 			wpa_dbg(wpa_s, MSG_DEBUG, "Not enough room for SSID "
1582 				"filter for sched_scan - drop filter");
1583 			os_free(params.filter_ssids);
1584 			params.filter_ssids = NULL;
1585 			params.num_filter_ssids = 0;
1586 		}
1587 
1588 		if (ssid->scan_ssid && ssid->ssid && ssid->ssid_len) {
1589 			if (params.num_ssids == max_sched_scan_ssids)
1590 				break; /* only room for broadcast SSID */
1591 			wpa_dbg(wpa_s, MSG_DEBUG,
1592 				"add to active scan ssid: %s",
1593 				wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
1594 			params.ssids[params.num_ssids].ssid =
1595 				ssid->ssid;
1596 			params.ssids[params.num_ssids].ssid_len =
1597 				ssid->ssid_len;
1598 			params.num_ssids++;
1599 			if (params.num_ssids >= max_sched_scan_ssids) {
1600 				wpa_s->prev_sched_ssid = ssid;
1601 				do {
1602 					ssid = ssid->next;
1603 				} while (ssid &&
1604 					 (wpas_network_disabled(wpa_s, ssid) ||
1605 					  !ssid->scan_ssid));
1606 				break;
1607 			}
1608 		}
1609 
1610 	next:
1611 		wpa_s->prev_sched_ssid = ssid;
1612 		ssid = ssid->next;
1613 	}
1614 
1615 	if (params.num_filter_ssids == 0) {
1616 		os_free(params.filter_ssids);
1617 		params.filter_ssids = NULL;
1618 	}
1619 
1620 	extra_ie = wpa_supplicant_extra_ies(wpa_s);
1621 	if (extra_ie) {
1622 		params.extra_ies = wpabuf_head(extra_ie);
1623 		params.extra_ies_len = wpabuf_len(extra_ie);
1624 	}
1625 
1626 	if (wpa_s->conf->filter_rssi)
1627 		params.filter_rssi = wpa_s->conf->filter_rssi;
1628 
1629 	/* See if user specified frequencies. If so, scan only those. */
1630 	if (wpa_s->conf->freq_list && !params.freqs) {
1631 		wpa_dbg(wpa_s, MSG_DEBUG,
1632 			"Optimize scan based on conf->freq_list");
1633 		int_array_concat(&params.freqs, wpa_s->conf->freq_list);
1634 	}
1635 
1636 #ifdef CONFIG_MBO
1637 	if (wpa_s->enable_oce & OCE_STA)
1638 		params.oce_scan = 1;
1639 #endif /* CONFIG_MBO */
1640 
1641 	scan_params = &params;
1642 
1643 scan:
1644 	wpa_s->sched_scan_timed_out = 0;
1645 
1646 	/*
1647 	 * We cannot support multiple scan plans if the scan request includes
1648 	 * too many SSID's, so in this case use only the last scan plan and make
1649 	 * it run infinitely. It will be stopped by the timeout.
1650 	 */
1651 	if (wpa_s->sched_scan_plans_num == 1 ||
1652 	    (wpa_s->sched_scan_plans_num && !ssid && wpa_s->first_sched_scan)) {
1653 		params.sched_scan_plans = wpa_s->sched_scan_plans;
1654 		params.sched_scan_plans_num = wpa_s->sched_scan_plans_num;
1655 	} else if (wpa_s->sched_scan_plans_num > 1) {
1656 		wpa_dbg(wpa_s, MSG_DEBUG,
1657 			"Too many SSIDs. Default to using single scheduled_scan plan");
1658 		params.sched_scan_plans =
1659 			&wpa_s->sched_scan_plans[wpa_s->sched_scan_plans_num -
1660 						 1];
1661 		params.sched_scan_plans_num = 1;
1662 	} else {
1663 		if (wpa_s->conf->sched_scan_interval)
1664 			scan_plan.interval = wpa_s->conf->sched_scan_interval;
1665 		else
1666 			scan_plan.interval = 10;
1667 
1668 		if (scan_plan.interval > wpa_s->max_sched_scan_plan_interval) {
1669 			wpa_printf(MSG_WARNING,
1670 				   "Scan interval too long(%u), use the maximum allowed(%u)",
1671 				   scan_plan.interval,
1672 				   wpa_s->max_sched_scan_plan_interval);
1673 			scan_plan.interval =
1674 				wpa_s->max_sched_scan_plan_interval;
1675 		}
1676 
1677 		scan_plan.iterations = 0;
1678 		params.sched_scan_plans = &scan_plan;
1679 		params.sched_scan_plans_num = 1;
1680 	}
1681 
1682 	params.sched_scan_start_delay = wpa_s->conf->sched_scan_start_delay;
1683 
1684 	if (ssid || !wpa_s->first_sched_scan) {
1685 		wpa_dbg(wpa_s, MSG_DEBUG,
1686 			"Starting sched scan after %u seconds: interval %u timeout %d",
1687 			params.sched_scan_start_delay,
1688 			params.sched_scan_plans[0].interval,
1689 			wpa_s->sched_scan_timeout);
1690 	} else {
1691 		wpa_dbg(wpa_s, MSG_DEBUG,
1692 			"Starting sched scan after %u seconds (no timeout)",
1693 			params.sched_scan_start_delay);
1694 	}
1695 
1696 	wpa_setband_scan_freqs(wpa_s, scan_params);
1697 
1698 	if ((wpa_s->mac_addr_rand_enable & MAC_ADDR_RAND_SCHED_SCAN) &&
1699 	    wpa_s->wpa_state <= WPA_SCANNING)
1700 		wpa_setup_mac_addr_rand_params(&params,
1701 					       wpa_s->mac_addr_sched_scan);
1702 
1703 	wpa_scan_set_relative_rssi_params(wpa_s, scan_params);
1704 
1705 	ret = wpa_supplicant_start_sched_scan(wpa_s, scan_params);
1706 	wpabuf_free(extra_ie);
1707 	os_free(params.filter_ssids);
1708 	os_free(params.mac_addr);
1709 	if (ret) {
1710 		wpa_msg(wpa_s, MSG_WARNING, "Failed to initiate sched scan");
1711 		if (prev_state != wpa_s->wpa_state)
1712 			wpa_supplicant_set_state(wpa_s, prev_state);
1713 		return ret;
1714 	}
1715 
1716 	/* If we have more SSIDs to scan, add a timeout so we scan them too */
1717 	if (ssid || !wpa_s->first_sched_scan) {
1718 		wpa_s->sched_scan_timed_out = 0;
1719 		eloop_register_timeout(wpa_s->sched_scan_timeout, 0,
1720 				       wpa_supplicant_sched_scan_timeout,
1721 				       wpa_s, NULL);
1722 		wpa_s->first_sched_scan = 0;
1723 		wpa_s->sched_scan_timeout /= 2;
1724 		params.sched_scan_plans[0].interval *= 2;
1725 		if ((unsigned int) wpa_s->sched_scan_timeout <
1726 		    params.sched_scan_plans[0].interval ||
1727 		    params.sched_scan_plans[0].interval >
1728 		    wpa_s->max_sched_scan_plan_interval) {
1729 			params.sched_scan_plans[0].interval = 10;
1730 			wpa_s->sched_scan_timeout = max_sched_scan_ssids * 2;
1731 		}
1732 	}
1733 
1734 	/* If there is no more ssids, start next time from the beginning */
1735 	if (!ssid)
1736 		wpa_s->prev_sched_ssid = NULL;
1737 
1738 	return 0;
1739 }
1740 
1741 
1742 /**
1743  * wpa_supplicant_cancel_scan - Cancel a scheduled scan request
1744  * @wpa_s: Pointer to wpa_supplicant data
1745  *
1746  * This function is used to cancel a scan request scheduled with
1747  * wpa_supplicant_req_scan().
1748  */
wpa_supplicant_cancel_scan(struct wpa_supplicant * wpa_s)1749 void wpa_supplicant_cancel_scan(struct wpa_supplicant *wpa_s)
1750 {
1751 	wpa_dbg(wpa_s, MSG_DEBUG, "Cancelling scan request");
1752 	eloop_cancel_timeout(wpa_supplicant_scan, wpa_s, NULL);
1753 }
1754 
1755 
1756 /**
1757  * wpa_supplicant_cancel_delayed_sched_scan - Stop a delayed scheduled scan
1758  * @wpa_s: Pointer to wpa_supplicant data
1759  *
1760  * This function is used to stop a delayed scheduled scan.
1761  */
wpa_supplicant_cancel_delayed_sched_scan(struct wpa_supplicant * wpa_s)1762 void wpa_supplicant_cancel_delayed_sched_scan(struct wpa_supplicant *wpa_s)
1763 {
1764 	if (!wpa_s->sched_scan_supported)
1765 		return;
1766 
1767 	wpa_dbg(wpa_s, MSG_DEBUG, "Cancelling delayed sched scan");
1768 	eloop_cancel_timeout(wpa_supplicant_delayed_sched_scan_timeout,
1769 			     wpa_s, NULL);
1770 }
1771 
1772 
1773 /**
1774  * wpa_supplicant_cancel_sched_scan - Stop running scheduled scans
1775  * @wpa_s: Pointer to wpa_supplicant data
1776  *
1777  * This function is used to stop a periodic scheduled scan.
1778  */
wpa_supplicant_cancel_sched_scan(struct wpa_supplicant * wpa_s)1779 void wpa_supplicant_cancel_sched_scan(struct wpa_supplicant *wpa_s)
1780 {
1781 	if (!wpa_s->sched_scanning)
1782 		return;
1783 
1784 	if (wpa_s->sched_scanning)
1785 		wpa_s->sched_scan_stop_req = 1;
1786 
1787 	wpa_dbg(wpa_s, MSG_DEBUG, "Cancelling sched scan");
1788 	eloop_cancel_timeout(wpa_supplicant_sched_scan_timeout, wpa_s, NULL);
1789 	wpa_supplicant_stop_sched_scan(wpa_s);
1790 }
1791 
1792 
1793 /**
1794  * wpa_supplicant_notify_scanning - Indicate possible scan state change
1795  * @wpa_s: Pointer to wpa_supplicant data
1796  * @scanning: Whether scanning is currently in progress
1797  *
1798  * This function is to generate scanning notifycations. It is called whenever
1799  * there may have been a change in scanning (scan started, completed, stopped).
1800  * wpas_notify_scanning() is called whenever the scanning state changed from the
1801  * previously notified state.
1802  */
wpa_supplicant_notify_scanning(struct wpa_supplicant * wpa_s,int scanning)1803 void wpa_supplicant_notify_scanning(struct wpa_supplicant *wpa_s,
1804 				    int scanning)
1805 {
1806 	if (wpa_s->scanning != scanning) {
1807 		wpa_s->scanning = scanning;
1808 		wpas_notify_scanning(wpa_s);
1809 	}
1810 }
1811 
1812 
wpa_scan_get_max_rate(const struct wpa_scan_res * res)1813 static int wpa_scan_get_max_rate(const struct wpa_scan_res *res)
1814 {
1815 	int rate = 0;
1816 	const u8 *ie;
1817 	int i;
1818 
1819 	ie = wpa_scan_get_ie(res, WLAN_EID_SUPP_RATES);
1820 	for (i = 0; ie && i < ie[1]; i++) {
1821 		if ((ie[i + 2] & 0x7f) > rate)
1822 			rate = ie[i + 2] & 0x7f;
1823 	}
1824 
1825 	ie = wpa_scan_get_ie(res, WLAN_EID_EXT_SUPP_RATES);
1826 	for (i = 0; ie && i < ie[1]; i++) {
1827 		if ((ie[i + 2] & 0x7f) > rate)
1828 			rate = ie[i + 2] & 0x7f;
1829 	}
1830 
1831 	return rate;
1832 }
1833 
1834 
1835 /**
1836  * wpa_scan_get_ie - Fetch a specified information element from a scan result
1837  * @res: Scan result entry
1838  * @ie: Information element identitifier (WLAN_EID_*)
1839  * Returns: Pointer to the information element (id field) or %NULL if not found
1840  *
1841  * This function returns the first matching information element in the scan
1842  * result.
1843  */
wpa_scan_get_ie(const struct wpa_scan_res * res,u8 ie)1844 const u8 * wpa_scan_get_ie(const struct wpa_scan_res *res, u8 ie)
1845 {
1846 	size_t ie_len = res->ie_len;
1847 
1848 	/* Use the Beacon frame IEs if res->ie_len is not available */
1849 	if (!ie_len)
1850 		ie_len = res->beacon_ie_len;
1851 
1852 	return get_ie((const u8 *) (res + 1), ie_len, ie);
1853 }
1854 
1855 
1856 /**
1857  * wpa_scan_get_vendor_ie - Fetch vendor information element from a scan result
1858  * @res: Scan result entry
1859  * @vendor_type: Vendor type (four octets starting the IE payload)
1860  * Returns: Pointer to the information element (id field) or %NULL if not found
1861  *
1862  * This function returns the first matching information element in the scan
1863  * result.
1864  */
wpa_scan_get_vendor_ie(const struct wpa_scan_res * res,u32 vendor_type)1865 const u8 * wpa_scan_get_vendor_ie(const struct wpa_scan_res *res,
1866 				  u32 vendor_type)
1867 {
1868 	const u8 *end, *pos;
1869 
1870 	pos = (const u8 *) (res + 1);
1871 	end = pos + res->ie_len;
1872 
1873 	while (end - pos > 1) {
1874 		if (2 + pos[1] > end - pos)
1875 			break;
1876 		if (pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 &&
1877 		    vendor_type == WPA_GET_BE32(&pos[2]))
1878 			return pos;
1879 		pos += 2 + pos[1];
1880 	}
1881 
1882 	return NULL;
1883 }
1884 
1885 
1886 /**
1887  * wpa_scan_get_vendor_ie_beacon - Fetch vendor information from a scan result
1888  * @res: Scan result entry
1889  * @vendor_type: Vendor type (four octets starting the IE payload)
1890  * Returns: Pointer to the information element (id field) or %NULL if not found
1891  *
1892  * This function returns the first matching information element in the scan
1893  * result.
1894  *
1895  * This function is like wpa_scan_get_vendor_ie(), but uses IE buffer only
1896  * from Beacon frames instead of either Beacon or Probe Response frames.
1897  */
wpa_scan_get_vendor_ie_beacon(const struct wpa_scan_res * res,u32 vendor_type)1898 const u8 * wpa_scan_get_vendor_ie_beacon(const struct wpa_scan_res *res,
1899 					 u32 vendor_type)
1900 {
1901 	const u8 *end, *pos;
1902 
1903 	if (res->beacon_ie_len == 0)
1904 		return NULL;
1905 
1906 	pos = (const u8 *) (res + 1);
1907 	pos += res->ie_len;
1908 	end = pos + res->beacon_ie_len;
1909 
1910 	while (end - pos > 1) {
1911 		if (2 + pos[1] > end - pos)
1912 			break;
1913 		if (pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 &&
1914 		    vendor_type == WPA_GET_BE32(&pos[2]))
1915 			return pos;
1916 		pos += 2 + pos[1];
1917 	}
1918 
1919 	return NULL;
1920 }
1921 
1922 
1923 /**
1924  * wpa_scan_get_vendor_ie_multi - Fetch vendor IE data from a scan result
1925  * @res: Scan result entry
1926  * @vendor_type: Vendor type (four octets starting the IE payload)
1927  * Returns: Pointer to the information element payload or %NULL if not found
1928  *
1929  * This function returns concatenated payload of possibly fragmented vendor
1930  * specific information elements in the scan result. The caller is responsible
1931  * for freeing the returned buffer.
1932  */
wpa_scan_get_vendor_ie_multi(const struct wpa_scan_res * res,u32 vendor_type)1933 struct wpabuf * wpa_scan_get_vendor_ie_multi(const struct wpa_scan_res *res,
1934 					     u32 vendor_type)
1935 {
1936 	struct wpabuf *buf;
1937 	const u8 *end, *pos;
1938 
1939 	buf = wpabuf_alloc(res->ie_len);
1940 	if (buf == NULL)
1941 		return NULL;
1942 
1943 	pos = (const u8 *) (res + 1);
1944 	end = pos + res->ie_len;
1945 
1946 	while (end - pos > 1) {
1947 		if (2 + pos[1] > end - pos)
1948 			break;
1949 		if (pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 &&
1950 		    vendor_type == WPA_GET_BE32(&pos[2]))
1951 			wpabuf_put_data(buf, pos + 2 + 4, pos[1] - 4);
1952 		pos += 2 + pos[1];
1953 	}
1954 
1955 	if (wpabuf_len(buf) == 0) {
1956 		wpabuf_free(buf);
1957 		buf = NULL;
1958 	}
1959 
1960 	return buf;
1961 }
1962 
1963 
1964 /* Compare function for sorting scan results. Return >0 if @b is considered
1965  * better. */
wpa_scan_result_compar(const void * a,const void * b)1966 static int wpa_scan_result_compar(const void *a, const void *b)
1967 {
1968 #define MIN(a,b) a < b ? a : b
1969 	struct wpa_scan_res **_wa = (void *) a;
1970 	struct wpa_scan_res **_wb = (void *) b;
1971 	struct wpa_scan_res *wa = *_wa;
1972 	struct wpa_scan_res *wb = *_wb;
1973 	int wpa_a, wpa_b;
1974 	int snr_a, snr_b, snr_a_full, snr_b_full;
1975 
1976 	/* WPA/WPA2 support preferred */
1977 	wpa_a = wpa_scan_get_vendor_ie(wa, WPA_IE_VENDOR_TYPE) != NULL ||
1978 		wpa_scan_get_ie(wa, WLAN_EID_RSN) != NULL;
1979 	wpa_b = wpa_scan_get_vendor_ie(wb, WPA_IE_VENDOR_TYPE) != NULL ||
1980 		wpa_scan_get_ie(wb, WLAN_EID_RSN) != NULL;
1981 
1982 	if (wpa_b && !wpa_a)
1983 		return 1;
1984 	if (!wpa_b && wpa_a)
1985 		return -1;
1986 
1987 	/* privacy support preferred */
1988 	if ((wa->caps & IEEE80211_CAP_PRIVACY) == 0 &&
1989 	    (wb->caps & IEEE80211_CAP_PRIVACY))
1990 		return 1;
1991 	if ((wa->caps & IEEE80211_CAP_PRIVACY) &&
1992 	    (wb->caps & IEEE80211_CAP_PRIVACY) == 0)
1993 		return -1;
1994 
1995 	if (wa->flags & wb->flags & WPA_SCAN_LEVEL_DBM) {
1996 		snr_a_full = wa->snr;
1997 		snr_a = MIN(wa->snr, GREAT_SNR);
1998 		snr_b_full = wb->snr;
1999 		snr_b = MIN(wb->snr, GREAT_SNR);
2000 	} else {
2001 		/* Level is not in dBm, so we can't calculate
2002 		 * SNR. Just use raw level (units unknown). */
2003 		snr_a = snr_a_full = wa->level;
2004 		snr_b = snr_b_full = wb->level;
2005 	}
2006 
2007 	/* if SNR is close, decide by max rate or frequency band */
2008 	if (snr_a && snr_b && abs(snr_b - snr_a) < 7) {
2009 		if (wa->est_throughput != wb->est_throughput)
2010 			return (int) wb->est_throughput -
2011 				(int) wa->est_throughput;
2012 	}
2013 	if ((snr_a && snr_b && abs(snr_b - snr_a) < 5) ||
2014 	    (wa->qual && wb->qual && abs(wb->qual - wa->qual) < 10)) {
2015 		if (IS_5GHZ(wa->freq) ^ IS_5GHZ(wb->freq))
2016 			return IS_5GHZ(wa->freq) ? -1 : 1;
2017 	}
2018 
2019 	/* all things being equal, use SNR; if SNRs are
2020 	 * identical, use quality values since some drivers may only report
2021 	 * that value and leave the signal level zero */
2022 	if (snr_b_full == snr_a_full)
2023 		return wb->qual - wa->qual;
2024 	return snr_b_full - snr_a_full;
2025 #undef MIN
2026 }
2027 
2028 
2029 #ifdef CONFIG_WPS
2030 /* Compare function for sorting scan results when searching a WPS AP for
2031  * provisioning. Return >0 if @b is considered better. */
wpa_scan_result_wps_compar(const void * a,const void * b)2032 static int wpa_scan_result_wps_compar(const void *a, const void *b)
2033 {
2034 	struct wpa_scan_res **_wa = (void *) a;
2035 	struct wpa_scan_res **_wb = (void *) b;
2036 	struct wpa_scan_res *wa = *_wa;
2037 	struct wpa_scan_res *wb = *_wb;
2038 	int uses_wps_a, uses_wps_b;
2039 	struct wpabuf *wps_a, *wps_b;
2040 	int res;
2041 
2042 	/* Optimization - check WPS IE existence before allocated memory and
2043 	 * doing full reassembly. */
2044 	uses_wps_a = wpa_scan_get_vendor_ie(wa, WPS_IE_VENDOR_TYPE) != NULL;
2045 	uses_wps_b = wpa_scan_get_vendor_ie(wb, WPS_IE_VENDOR_TYPE) != NULL;
2046 	if (uses_wps_a && !uses_wps_b)
2047 		return -1;
2048 	if (!uses_wps_a && uses_wps_b)
2049 		return 1;
2050 
2051 	if (uses_wps_a && uses_wps_b) {
2052 		wps_a = wpa_scan_get_vendor_ie_multi(wa, WPS_IE_VENDOR_TYPE);
2053 		wps_b = wpa_scan_get_vendor_ie_multi(wb, WPS_IE_VENDOR_TYPE);
2054 		res = wps_ap_priority_compar(wps_a, wps_b);
2055 		wpabuf_free(wps_a);
2056 		wpabuf_free(wps_b);
2057 		if (res)
2058 			return res;
2059 	}
2060 
2061 	/*
2062 	 * Do not use current AP security policy as a sorting criteria during
2063 	 * WPS provisioning step since the AP may get reconfigured at the
2064 	 * completion of provisioning.
2065 	 */
2066 
2067 	/* all things being equal, use signal level; if signal levels are
2068 	 * identical, use quality values since some drivers may only report
2069 	 * that value and leave the signal level zero */
2070 	if (wb->level == wa->level)
2071 		return wb->qual - wa->qual;
2072 	return wb->level - wa->level;
2073 }
2074 #endif /* CONFIG_WPS */
2075 
2076 
dump_scan_res(struct wpa_scan_results * scan_res)2077 static void dump_scan_res(struct wpa_scan_results *scan_res)
2078 {
2079 #ifndef CONFIG_NO_STDOUT_DEBUG
2080 	size_t i;
2081 
2082 	if (scan_res->res == NULL || scan_res->num == 0)
2083 		return;
2084 
2085 	wpa_printf(MSG_EXCESSIVE, "Sorted scan results");
2086 
2087 	for (i = 0; i < scan_res->num; i++) {
2088 		struct wpa_scan_res *r = scan_res->res[i];
2089 		u8 *pos;
2090 		if (r->flags & WPA_SCAN_LEVEL_DBM) {
2091 			int noise_valid = !(r->flags & WPA_SCAN_NOISE_INVALID);
2092 
2093 			wpa_printf(MSG_EXCESSIVE, MACSTR " freq=%d qual=%d "
2094 				   "noise=%d%s level=%d snr=%d%s flags=0x%x age=%u est=%u",
2095 				   MAC2STR(r->bssid), r->freq, r->qual,
2096 				   r->noise, noise_valid ? "" : "~", r->level,
2097 				   r->snr, r->snr >= GREAT_SNR ? "*" : "",
2098 				   r->flags,
2099 				   r->age, r->est_throughput);
2100 		} else {
2101 			wpa_printf(MSG_EXCESSIVE, MACSTR " freq=%d qual=%d "
2102 				   "noise=%d level=%d flags=0x%x age=%u est=%u",
2103 				   MAC2STR(r->bssid), r->freq, r->qual,
2104 				   r->noise, r->level, r->flags, r->age,
2105 				   r->est_throughput);
2106 		}
2107 		pos = (u8 *) (r + 1);
2108 		if (r->ie_len)
2109 			wpa_hexdump(MSG_EXCESSIVE, "IEs", pos, r->ie_len);
2110 		pos += r->ie_len;
2111 		if (r->beacon_ie_len)
2112 			wpa_hexdump(MSG_EXCESSIVE, "Beacon IEs",
2113 				    pos, r->beacon_ie_len);
2114 	}
2115 #endif /* CONFIG_NO_STDOUT_DEBUG */
2116 }
2117 
2118 
2119 /**
2120  * wpa_supplicant_filter_bssid_match - Is the specified BSSID allowed
2121  * @wpa_s: Pointer to wpa_supplicant data
2122  * @bssid: BSSID to check
2123  * Returns: 0 if the BSSID is filtered or 1 if not
2124  *
2125  * This function is used to filter out specific BSSIDs from scan reslts mainly
2126  * for testing purposes (SET bssid_filter ctrl_iface command).
2127  */
wpa_supplicant_filter_bssid_match(struct wpa_supplicant * wpa_s,const u8 * bssid)2128 int wpa_supplicant_filter_bssid_match(struct wpa_supplicant *wpa_s,
2129 				      const u8 *bssid)
2130 {
2131 	size_t i;
2132 
2133 	if (wpa_s->bssid_filter == NULL)
2134 		return 1;
2135 
2136 	for (i = 0; i < wpa_s->bssid_filter_count; i++) {
2137 		if (os_memcmp(wpa_s->bssid_filter + i * ETH_ALEN, bssid,
2138 			      ETH_ALEN) == 0)
2139 			return 1;
2140 	}
2141 
2142 	return 0;
2143 }
2144 
2145 
filter_scan_res(struct wpa_supplicant * wpa_s,struct wpa_scan_results * res)2146 void filter_scan_res(struct wpa_supplicant *wpa_s,
2147 		     struct wpa_scan_results *res)
2148 {
2149 	size_t i, j;
2150 
2151 	if (wpa_s->bssid_filter == NULL)
2152 		return;
2153 
2154 	for (i = 0, j = 0; i < res->num; i++) {
2155 		if (wpa_supplicant_filter_bssid_match(wpa_s,
2156 						      res->res[i]->bssid)) {
2157 			res->res[j++] = res->res[i];
2158 		} else {
2159 			os_free(res->res[i]);
2160 			res->res[i] = NULL;
2161 		}
2162 	}
2163 
2164 	if (res->num != j) {
2165 		wpa_printf(MSG_DEBUG, "Filtered out %d scan results",
2166 			   (int) (res->num - j));
2167 		res->num = j;
2168 	}
2169 }
2170 
2171 
scan_snr(struct wpa_scan_res * res)2172 void scan_snr(struct wpa_scan_res *res)
2173 {
2174 	if (res->flags & WPA_SCAN_NOISE_INVALID) {
2175 		res->noise = IS_5GHZ(res->freq) ?
2176 			DEFAULT_NOISE_FLOOR_5GHZ :
2177 			DEFAULT_NOISE_FLOOR_2GHZ;
2178 	}
2179 
2180 	if (res->flags & WPA_SCAN_LEVEL_DBM) {
2181 		res->snr = res->level - res->noise;
2182 	} else {
2183 		/* Level is not in dBm, so we can't calculate
2184 		 * SNR. Just use raw level (units unknown). */
2185 		res->snr = res->level;
2186 	}
2187 }
2188 
2189 
interpolate_rate(int snr,int snr0,int snr1,int rate0,int rate1)2190 static unsigned int interpolate_rate(int snr, int snr0, int snr1,
2191 				     int rate0, int rate1)
2192 {
2193 	return rate0 + (snr - snr0) * (rate1 - rate0) / (snr1 - snr0);
2194 }
2195 
2196 
2197 #define INTERPOLATE_RATE(snr0, snr1, rate0, rate1) \
2198 	if (snr < (snr1)) \
2199 		return interpolate_rate(snr, (snr0), (snr1), (rate0), (rate1))
2200 
max_ht20_rate(int snr,int vht)2201 static unsigned int max_ht20_rate(int snr, int vht)
2202 {
2203 	if (snr < 0)
2204 		return 0;
2205 	INTERPOLATE_RATE(0, 2, 0, 6500); /* HT20 MCS0 */
2206 	INTERPOLATE_RATE(2, 5, 6500, 13000); /* HT20 MCS1 */
2207 	INTERPOLATE_RATE(5, 9, 13000, 19500); /* HT20 MCS2 */
2208 	INTERPOLATE_RATE(9, 11, 19500, 26000); /* HT20 MCS3 */
2209 	INTERPOLATE_RATE(11, 15, 26000, 39000); /* HT20 MCS4 */
2210 	INTERPOLATE_RATE(15, 18, 39000, 52000); /* HT20 MCS5 */
2211 	INTERPOLATE_RATE(18, 20, 52000, 58500); /* HT20 MCS6 */
2212 	INTERPOLATE_RATE(20, 25, 58500, 65000); /* HT20 MCS7 */
2213 	if (!vht)
2214 		return 65000;
2215 	INTERPOLATE_RATE(25, 29, 65000, 78000); /* VHT20 MCS8 */
2216 	return 78000;
2217 }
2218 
2219 
max_ht40_rate(int snr,int vht)2220 static unsigned int max_ht40_rate(int snr, int vht)
2221 {
2222 	if (snr < 0)
2223 		return 0;
2224 	INTERPOLATE_RATE(0, 5, 0, 13500); /* HT40 MCS0 */
2225 	INTERPOLATE_RATE(5, 8, 13500, 27000); /* HT40 MCS1 */
2226 	INTERPOLATE_RATE(8, 12, 27000, 40500); /* HT40 MCS2 */
2227 	INTERPOLATE_RATE(12, 14, 40500, 54000); /* HT40 MCS3 */
2228 	INTERPOLATE_RATE(14, 18, 54000, 81000); /* HT40 MCS4 */
2229 	INTERPOLATE_RATE(18, 21, 81000, 108000); /* HT40 MCS5 */
2230 	INTERPOLATE_RATE(21, 23, 108000, 121500); /* HT40 MCS6 */
2231 	INTERPOLATE_RATE(23, 28, 121500, 135000); /* HT40 MCS7 */
2232 	if (!vht)
2233 		return 135000;
2234 	INTERPOLATE_RATE(28, 32, 135000, 162000); /* VHT40 MCS8 */
2235 	INTERPOLATE_RATE(32, 34, 162000, 180000); /* VHT40 MCS9 */
2236 	return 180000;
2237 }
2238 
2239 
max_vht80_rate(int snr)2240 static unsigned int max_vht80_rate(int snr)
2241 {
2242 	if (snr < 0)
2243 		return 0;
2244 	INTERPOLATE_RATE(0, 8, 0, 29300); /* VHT80 MCS0 */
2245 	INTERPOLATE_RATE(8, 11, 29300, 58500); /* VHT80 MCS1 */
2246 	INTERPOLATE_RATE(11, 15, 58500, 87800); /* VHT80 MCS2 */
2247 	INTERPOLATE_RATE(15, 17, 87800, 117000); /* VHT80 MCS3 */
2248 	INTERPOLATE_RATE(17, 21, 117000, 175500); /* VHT80 MCS4 */
2249 	INTERPOLATE_RATE(21, 24, 175500, 234000); /* VHT80 MCS5 */
2250 	INTERPOLATE_RATE(24, 26, 234000, 263300); /* VHT80 MCS6 */
2251 	INTERPOLATE_RATE(26, 31, 263300, 292500); /* VHT80 MCS7 */
2252 	INTERPOLATE_RATE(31, 35, 292500, 351000); /* VHT80 MCS8 */
2253 	INTERPOLATE_RATE(35, 37, 351000, 390000); /* VHT80 MCS9 */
2254 	return 390000;
2255 }
2256 
2257 #undef INTERPOLATE_RATE
2258 
2259 
wpas_get_est_tpt(const struct wpa_supplicant * wpa_s,const u8 * ies,size_t ies_len,int rate,int snr)2260 unsigned int wpas_get_est_tpt(const struct wpa_supplicant *wpa_s,
2261 			      const u8 *ies, size_t ies_len, int rate,
2262 			      int snr)
2263 {
2264 	enum local_hw_capab capab = wpa_s->hw_capab;
2265 	unsigned int est, tmp;
2266 	const u8 *ie;
2267 
2268 	/* Limit based on estimated SNR */
2269 	if (rate > 1 * 2 && snr < 1)
2270 		rate = 1 * 2;
2271 	else if (rate > 2 * 2 && snr < 4)
2272 		rate = 2 * 2;
2273 	else if (rate > 6 * 2 && snr < 5)
2274 		rate = 6 * 2;
2275 	else if (rate > 9 * 2 && snr < 6)
2276 		rate = 9 * 2;
2277 	else if (rate > 12 * 2 && snr < 7)
2278 		rate = 12 * 2;
2279 	else if (rate > 12 * 2 && snr < 8)
2280 		rate = 14 * 2;
2281 	else if (rate > 12 * 2 && snr < 9)
2282 		rate = 16 * 2;
2283 	else if (rate > 18 * 2 && snr < 10)
2284 		rate = 18 * 2;
2285 	else if (rate > 24 * 2 && snr < 11)
2286 		rate = 24 * 2;
2287 	else if (rate > 24 * 2 && snr < 12)
2288 		rate = 27 * 2;
2289 	else if (rate > 24 * 2 && snr < 13)
2290 		rate = 30 * 2;
2291 	else if (rate > 24 * 2 && snr < 14)
2292 		rate = 33 * 2;
2293 	else if (rate > 36 * 2 && snr < 15)
2294 		rate = 36 * 2;
2295 	else if (rate > 36 * 2 && snr < 16)
2296 		rate = 39 * 2;
2297 	else if (rate > 36 * 2 && snr < 17)
2298 		rate = 42 * 2;
2299 	else if (rate > 36 * 2 && snr < 18)
2300 		rate = 45 * 2;
2301 	else if (rate > 48 * 2 && snr < 19)
2302 		rate = 48 * 2;
2303 	else if (rate > 48 * 2 && snr < 20)
2304 		rate = 51 * 2;
2305 	else if (rate > 54 * 2 && snr < 21)
2306 		rate = 54 * 2;
2307 	est = rate * 500;
2308 
2309 	if (capab == CAPAB_HT || capab == CAPAB_HT40 || capab == CAPAB_VHT) {
2310 		ie = get_ie(ies, ies_len, WLAN_EID_HT_CAP);
2311 		if (ie) {
2312 			tmp = max_ht20_rate(snr, 0);
2313 			if (tmp > est)
2314 				est = tmp;
2315 		}
2316 	}
2317 
2318 	if (capab == CAPAB_HT40 || capab == CAPAB_VHT) {
2319 		ie = get_ie(ies, ies_len, WLAN_EID_HT_OPERATION);
2320 		if (ie && ie[1] >= 2 &&
2321 		    (ie[3] & HT_INFO_HT_PARAM_SECONDARY_CHNL_OFF_MASK)) {
2322 			tmp = max_ht40_rate(snr, 0);
2323 			if (tmp > est)
2324 				est = tmp;
2325 		}
2326 	}
2327 
2328 	if (capab == CAPAB_VHT) {
2329 		/* Use +1 to assume VHT is always faster than HT */
2330 		ie = get_ie(ies, ies_len, WLAN_EID_VHT_CAP);
2331 		if (ie) {
2332 			tmp = max_ht20_rate(snr, 1) + 1;
2333 			if (tmp > est)
2334 				est = tmp;
2335 
2336 			ie = get_ie(ies, ies_len, WLAN_EID_HT_OPERATION);
2337 			if (ie && ie[1] >= 2 &&
2338 			    (ie[3] &
2339 			     HT_INFO_HT_PARAM_SECONDARY_CHNL_OFF_MASK)) {
2340 				tmp = max_ht40_rate(snr, 1) + 1;
2341 				if (tmp > est)
2342 					est = tmp;
2343 			}
2344 
2345 			ie = get_ie(ies, ies_len, WLAN_EID_VHT_OPERATION);
2346 			if (ie && ie[1] >= 1 &&
2347 			    (ie[2] & VHT_OPMODE_CHANNEL_WIDTH_MASK)) {
2348 				tmp = max_vht80_rate(snr) + 1;
2349 				if (tmp > est)
2350 					est = tmp;
2351 			}
2352 		}
2353 	}
2354 
2355 	return est;
2356 }
2357 
2358 
scan_est_throughput(struct wpa_supplicant * wpa_s,struct wpa_scan_res * res)2359 void scan_est_throughput(struct wpa_supplicant *wpa_s,
2360 			 struct wpa_scan_res *res)
2361 {
2362 	int rate; /* max legacy rate in 500 kb/s units */
2363 	int snr = res->snr;
2364 	const u8 *ies = (const void *) (res + 1);
2365 	size_t ie_len = res->ie_len;
2366 
2367 	if (res->est_throughput)
2368 		return;
2369 
2370 	/* Get maximum legacy rate */
2371 	rate = wpa_scan_get_max_rate(res);
2372 
2373 	if (!ie_len)
2374 		ie_len = res->beacon_ie_len;
2375 	res->est_throughput =
2376 		wpas_get_est_tpt(wpa_s, ies, ie_len, rate, snr);
2377 
2378 	/* TODO: channel utilization and AP load (e.g., from AP Beacon) */
2379 }
2380 
2381 
2382 /**
2383  * wpa_supplicant_get_scan_results - Get scan results
2384  * @wpa_s: Pointer to wpa_supplicant data
2385  * @info: Information about what was scanned or %NULL if not available
2386  * @new_scan: Whether a new scan was performed
2387  * Returns: Scan results, %NULL on failure
2388  *
2389  * This function request the current scan results from the driver and updates
2390  * the local BSS list wpa_s->bss. The caller is responsible for freeing the
2391  * results with wpa_scan_results_free().
2392  */
2393 struct wpa_scan_results *
wpa_supplicant_get_scan_results(struct wpa_supplicant * wpa_s,struct scan_info * info,int new_scan)2394 wpa_supplicant_get_scan_results(struct wpa_supplicant *wpa_s,
2395 				struct scan_info *info, int new_scan)
2396 {
2397 	struct wpa_scan_results *scan_res;
2398 	size_t i;
2399 	int (*compar)(const void *, const void *) = wpa_scan_result_compar;
2400 
2401 	scan_res = wpa_drv_get_scan_results2(wpa_s);
2402 	if (scan_res == NULL) {
2403 		wpa_dbg(wpa_s, MSG_DEBUG, "Failed to get scan results");
2404 		return NULL;
2405 	}
2406 	if (scan_res->fetch_time.sec == 0) {
2407 		/*
2408 		 * Make sure we have a valid timestamp if the driver wrapper
2409 		 * does not set this.
2410 		 */
2411 		os_get_reltime(&scan_res->fetch_time);
2412 	}
2413 	filter_scan_res(wpa_s, scan_res);
2414 
2415 	for (i = 0; i < scan_res->num; i++) {
2416 		struct wpa_scan_res *scan_res_item = scan_res->res[i];
2417 
2418 		scan_snr(scan_res_item);
2419 		scan_est_throughput(wpa_s, scan_res_item);
2420 	}
2421 
2422 #ifdef CONFIG_WPS
2423 	if (wpas_wps_searching(wpa_s)) {
2424 		wpa_dbg(wpa_s, MSG_DEBUG, "WPS: Order scan results with WPS "
2425 			"provisioning rules");
2426 		compar = wpa_scan_result_wps_compar;
2427 	}
2428 #endif /* CONFIG_WPS */
2429 
2430 	if (scan_res->res) {
2431 		qsort(scan_res->res, scan_res->num,
2432 		      sizeof(struct wpa_scan_res *), compar);
2433 	}
2434 	dump_scan_res(scan_res);
2435 
2436 	if (wpa_s->ignore_post_flush_scan_res) {
2437 		/* FLUSH command aborted an ongoing scan and these are the
2438 		 * results from the aborted scan. Do not process the results to
2439 		 * maintain flushed state. */
2440 		wpa_dbg(wpa_s, MSG_DEBUG,
2441 			"Do not update BSS table based on pending post-FLUSH scan results");
2442 		wpa_s->ignore_post_flush_scan_res = 0;
2443 		return scan_res;
2444 	}
2445 
2446 	wpa_bss_update_start(wpa_s);
2447 	for (i = 0; i < scan_res->num; i++)
2448 		wpa_bss_update_scan_res(wpa_s, scan_res->res[i],
2449 					&scan_res->fetch_time);
2450 	wpa_bss_update_end(wpa_s, info, new_scan);
2451 
2452 	return scan_res;
2453 }
2454 
2455 
2456 /**
2457  * wpa_supplicant_update_scan_results - Update scan results from the driver
2458  * @wpa_s: Pointer to wpa_supplicant data
2459  * Returns: 0 on success, -1 on failure
2460  *
2461  * This function updates the BSS table within wpa_supplicant based on the
2462  * currently available scan results from the driver without requesting a new
2463  * scan. This is used in cases where the driver indicates an association
2464  * (including roaming within ESS) and wpa_supplicant does not yet have the
2465  * needed information to complete the connection (e.g., to perform validation
2466  * steps in 4-way handshake).
2467  */
wpa_supplicant_update_scan_results(struct wpa_supplicant * wpa_s)2468 int wpa_supplicant_update_scan_results(struct wpa_supplicant *wpa_s)
2469 {
2470 	struct wpa_scan_results *scan_res;
2471 	scan_res = wpa_supplicant_get_scan_results(wpa_s, NULL, 0);
2472 	if (scan_res == NULL)
2473 		return -1;
2474 	wpa_scan_results_free(scan_res);
2475 
2476 	return 0;
2477 }
2478 
2479 
2480 /**
2481  * scan_only_handler - Reports scan results
2482  */
scan_only_handler(struct wpa_supplicant * wpa_s,struct wpa_scan_results * scan_res)2483 void scan_only_handler(struct wpa_supplicant *wpa_s,
2484 		       struct wpa_scan_results *scan_res)
2485 {
2486 	wpa_dbg(wpa_s, MSG_DEBUG, "Scan-only results received");
2487 	if (wpa_s->last_scan_req == MANUAL_SCAN_REQ &&
2488 	    wpa_s->manual_scan_use_id && wpa_s->own_scan_running) {
2489 		wpa_msg_ctrl(wpa_s, MSG_INFO, WPA_EVENT_SCAN_RESULTS "id=%u",
2490 			     wpa_s->manual_scan_id);
2491 		wpa_s->manual_scan_use_id = 0;
2492 	} else {
2493 		wpa_msg_ctrl(wpa_s, MSG_INFO, WPA_EVENT_SCAN_RESULTS);
2494 	}
2495 	wpas_notify_scan_results(wpa_s);
2496 	wpas_notify_scan_done(wpa_s, 1);
2497 	if (wpa_s->scan_work) {
2498 		struct wpa_radio_work *work = wpa_s->scan_work;
2499 		wpa_s->scan_work = NULL;
2500 		radio_work_done(work);
2501 	}
2502 
2503 	if (wpa_s->wpa_state == WPA_SCANNING)
2504 		wpa_supplicant_set_state(wpa_s, wpa_s->scan_prev_wpa_state);
2505 }
2506 
2507 
wpas_scan_scheduled(struct wpa_supplicant * wpa_s)2508 int wpas_scan_scheduled(struct wpa_supplicant *wpa_s)
2509 {
2510 	return eloop_is_timeout_registered(wpa_supplicant_scan, wpa_s, NULL);
2511 }
2512 
2513 
2514 struct wpa_driver_scan_params *
wpa_scan_clone_params(const struct wpa_driver_scan_params * src)2515 wpa_scan_clone_params(const struct wpa_driver_scan_params *src)
2516 {
2517 	struct wpa_driver_scan_params *params;
2518 	size_t i;
2519 	u8 *n;
2520 
2521 	params = os_zalloc(sizeof(*params));
2522 	if (params == NULL)
2523 		return NULL;
2524 
2525 	for (i = 0; i < src->num_ssids; i++) {
2526 		if (src->ssids[i].ssid) {
2527 			n = os_memdup(src->ssids[i].ssid,
2528 				      src->ssids[i].ssid_len);
2529 			if (n == NULL)
2530 				goto failed;
2531 			params->ssids[i].ssid = n;
2532 			params->ssids[i].ssid_len = src->ssids[i].ssid_len;
2533 		}
2534 	}
2535 	params->num_ssids = src->num_ssids;
2536 
2537 	if (src->extra_ies) {
2538 		n = os_memdup(src->extra_ies, src->extra_ies_len);
2539 		if (n == NULL)
2540 			goto failed;
2541 		params->extra_ies = n;
2542 		params->extra_ies_len = src->extra_ies_len;
2543 	}
2544 
2545 	if (src->freqs) {
2546 		int len = int_array_len(src->freqs);
2547 		params->freqs = os_memdup(src->freqs, (len + 1) * sizeof(int));
2548 		if (params->freqs == NULL)
2549 			goto failed;
2550 	}
2551 
2552 	if (src->filter_ssids) {
2553 		params->filter_ssids = os_memdup(src->filter_ssids,
2554 						 sizeof(*params->filter_ssids) *
2555 						 src->num_filter_ssids);
2556 		if (params->filter_ssids == NULL)
2557 			goto failed;
2558 		params->num_filter_ssids = src->num_filter_ssids;
2559 	}
2560 
2561 	params->filter_rssi = src->filter_rssi;
2562 	params->p2p_probe = src->p2p_probe;
2563 	params->only_new_results = src->only_new_results;
2564 	params->low_priority = src->low_priority;
2565 	params->duration = src->duration;
2566 	params->duration_mandatory = src->duration_mandatory;
2567 	params->oce_scan = src->oce_scan;
2568 
2569 	if (src->sched_scan_plans_num > 0) {
2570 		params->sched_scan_plans =
2571 			os_memdup(src->sched_scan_plans,
2572 				  sizeof(*src->sched_scan_plans) *
2573 				  src->sched_scan_plans_num);
2574 		if (!params->sched_scan_plans)
2575 			goto failed;
2576 
2577 		params->sched_scan_plans_num = src->sched_scan_plans_num;
2578 	}
2579 
2580 	if (src->mac_addr_rand &&
2581 	    wpa_setup_mac_addr_rand_params(params, src->mac_addr))
2582 		goto failed;
2583 
2584 	if (src->bssid) {
2585 		u8 *bssid;
2586 
2587 		bssid = os_memdup(src->bssid, ETH_ALEN);
2588 		if (!bssid)
2589 			goto failed;
2590 		params->bssid = bssid;
2591 	}
2592 
2593 	params->relative_rssi_set = src->relative_rssi_set;
2594 	params->relative_rssi = src->relative_rssi;
2595 	params->relative_adjust_band = src->relative_adjust_band;
2596 	params->relative_adjust_rssi = src->relative_adjust_rssi;
2597 	return params;
2598 
2599 failed:
2600 	wpa_scan_free_params(params);
2601 	return NULL;
2602 }
2603 
2604 
wpa_scan_free_params(struct wpa_driver_scan_params * params)2605 void wpa_scan_free_params(struct wpa_driver_scan_params *params)
2606 {
2607 	size_t i;
2608 
2609 	if (params == NULL)
2610 		return;
2611 
2612 	for (i = 0; i < params->num_ssids; i++)
2613 		os_free((u8 *) params->ssids[i].ssid);
2614 	os_free((u8 *) params->extra_ies);
2615 	os_free(params->freqs);
2616 	os_free(params->filter_ssids);
2617 	os_free(params->sched_scan_plans);
2618 
2619 	/*
2620 	 * Note: params->mac_addr_mask points to same memory allocation and
2621 	 * must not be freed separately.
2622 	 */
2623 	os_free((u8 *) params->mac_addr);
2624 
2625 	os_free((u8 *) params->bssid);
2626 
2627 	os_free(params);
2628 }
2629 
2630 
wpas_start_pno(struct wpa_supplicant * wpa_s)2631 int wpas_start_pno(struct wpa_supplicant *wpa_s)
2632 {
2633 	int ret;
2634 	size_t prio, i, num_ssid, num_match_ssid;
2635 	struct wpa_ssid *ssid;
2636 	struct wpa_driver_scan_params params;
2637 	struct sched_scan_plan scan_plan;
2638 	unsigned int max_sched_scan_ssids;
2639 
2640 	if (!wpa_s->sched_scan_supported)
2641 		return -1;
2642 
2643 	if (wpa_s->max_sched_scan_ssids > WPAS_MAX_SCAN_SSIDS)
2644 		max_sched_scan_ssids = WPAS_MAX_SCAN_SSIDS;
2645 	else
2646 		max_sched_scan_ssids = wpa_s->max_sched_scan_ssids;
2647 	if (max_sched_scan_ssids < 1)
2648 		return -1;
2649 
2650 	if (wpa_s->pno || wpa_s->pno_sched_pending)
2651 		return 0;
2652 
2653 	if ((wpa_s->wpa_state > WPA_SCANNING) &&
2654 	    (wpa_s->wpa_state < WPA_COMPLETED)) {
2655 		wpa_printf(MSG_ERROR, "PNO: In assoc process");
2656 		return -EAGAIN;
2657 	}
2658 
2659 	if (wpa_s->wpa_state == WPA_SCANNING) {
2660 		wpa_supplicant_cancel_scan(wpa_s);
2661 		if (wpa_s->sched_scanning) {
2662 			wpa_printf(MSG_DEBUG, "Schedule PNO on completion of "
2663 				   "ongoing sched scan");
2664 			wpa_supplicant_cancel_sched_scan(wpa_s);
2665 			wpa_s->pno_sched_pending = 1;
2666 			return 0;
2667 		}
2668 	}
2669 
2670 	if (wpa_s->sched_scan_stop_req) {
2671 		wpa_printf(MSG_DEBUG,
2672 			   "Schedule PNO after previous sched scan has stopped");
2673 		wpa_s->pno_sched_pending = 1;
2674 		return 0;
2675 	}
2676 
2677 	os_memset(&params, 0, sizeof(params));
2678 
2679 	num_ssid = num_match_ssid = 0;
2680 	ssid = wpa_s->conf->ssid;
2681 	while (ssid) {
2682 		if (!wpas_network_disabled(wpa_s, ssid)) {
2683 			num_match_ssid++;
2684 			if (ssid->scan_ssid)
2685 				num_ssid++;
2686 		}
2687 		ssid = ssid->next;
2688 	}
2689 
2690 	if (num_match_ssid == 0) {
2691 		wpa_printf(MSG_DEBUG, "PNO: No configured SSIDs");
2692 		return -1;
2693 	}
2694 
2695 	if (num_match_ssid > num_ssid) {
2696 		params.num_ssids++; /* wildcard */
2697 		num_ssid++;
2698 	}
2699 
2700 	if (num_ssid > max_sched_scan_ssids) {
2701 		wpa_printf(MSG_DEBUG, "PNO: Use only the first %u SSIDs from "
2702 			   "%u", max_sched_scan_ssids, (unsigned int) num_ssid);
2703 		num_ssid = max_sched_scan_ssids;
2704 	}
2705 
2706 	if (num_match_ssid > wpa_s->max_match_sets) {
2707 		num_match_ssid = wpa_s->max_match_sets;
2708 		wpa_dbg(wpa_s, MSG_DEBUG, "PNO: Too many SSIDs to match");
2709 	}
2710 	params.filter_ssids = os_calloc(num_match_ssid,
2711 					sizeof(struct wpa_driver_scan_filter));
2712 	if (params.filter_ssids == NULL)
2713 		return -1;
2714 
2715 	i = 0;
2716 	prio = 0;
2717 	ssid = wpa_s->conf->pssid[prio];
2718 	while (ssid) {
2719 		if (!wpas_network_disabled(wpa_s, ssid)) {
2720 			if (ssid->scan_ssid && params.num_ssids < num_ssid) {
2721 				params.ssids[params.num_ssids].ssid =
2722 					ssid->ssid;
2723 				params.ssids[params.num_ssids].ssid_len =
2724 					 ssid->ssid_len;
2725 				params.num_ssids++;
2726 			}
2727 			os_memcpy(params.filter_ssids[i].ssid, ssid->ssid,
2728 				  ssid->ssid_len);
2729 			params.filter_ssids[i].ssid_len = ssid->ssid_len;
2730 			params.num_filter_ssids++;
2731 			i++;
2732 			if (i == num_match_ssid)
2733 				break;
2734 		}
2735 		if (ssid->pnext)
2736 			ssid = ssid->pnext;
2737 		else if (prio + 1 == wpa_s->conf->num_prio)
2738 			break;
2739 		else
2740 			ssid = wpa_s->conf->pssid[++prio];
2741 	}
2742 
2743 	if (wpa_s->conf->filter_rssi)
2744 		params.filter_rssi = wpa_s->conf->filter_rssi;
2745 
2746 	if (wpa_s->sched_scan_plans_num) {
2747 		params.sched_scan_plans = wpa_s->sched_scan_plans;
2748 		params.sched_scan_plans_num = wpa_s->sched_scan_plans_num;
2749 	} else {
2750 		/* Set one scan plan that will run infinitely */
2751 		if (wpa_s->conf->sched_scan_interval)
2752 			scan_plan.interval = wpa_s->conf->sched_scan_interval;
2753 		else
2754 			scan_plan.interval = 10;
2755 
2756 		scan_plan.iterations = 0;
2757 		params.sched_scan_plans = &scan_plan;
2758 		params.sched_scan_plans_num = 1;
2759 	}
2760 
2761 	params.sched_scan_start_delay = wpa_s->conf->sched_scan_start_delay;
2762 
2763 	if (params.freqs == NULL && wpa_s->manual_sched_scan_freqs) {
2764 		wpa_dbg(wpa_s, MSG_DEBUG, "Limit sched scan to specified channels");
2765 		params.freqs = wpa_s->manual_sched_scan_freqs;
2766 	}
2767 
2768 	if ((wpa_s->mac_addr_rand_enable & MAC_ADDR_RAND_PNO) &&
2769 	    wpa_s->wpa_state <= WPA_SCANNING)
2770 		wpa_setup_mac_addr_rand_params(&params, wpa_s->mac_addr_pno);
2771 
2772 	wpa_scan_set_relative_rssi_params(wpa_s, &params);
2773 
2774 	ret = wpa_supplicant_start_sched_scan(wpa_s, &params);
2775 	os_free(params.filter_ssids);
2776 	os_free(params.mac_addr);
2777 	if (ret == 0)
2778 		wpa_s->pno = 1;
2779 	else
2780 		wpa_msg(wpa_s, MSG_ERROR, "Failed to schedule PNO");
2781 	return ret;
2782 }
2783 
2784 
wpas_stop_pno(struct wpa_supplicant * wpa_s)2785 int wpas_stop_pno(struct wpa_supplicant *wpa_s)
2786 {
2787 	int ret = 0;
2788 
2789 	if (!wpa_s->pno)
2790 		return 0;
2791 
2792 	ret = wpa_supplicant_stop_sched_scan(wpa_s);
2793 	wpa_s->sched_scan_stop_req = 1;
2794 
2795 	wpa_s->pno = 0;
2796 	wpa_s->pno_sched_pending = 0;
2797 
2798 	if (wpa_s->wpa_state == WPA_SCANNING)
2799 		wpa_supplicant_req_scan(wpa_s, 0, 0);
2800 
2801 	return ret;
2802 }
2803 
2804 
wpas_mac_addr_rand_scan_clear(struct wpa_supplicant * wpa_s,unsigned int type)2805 void wpas_mac_addr_rand_scan_clear(struct wpa_supplicant *wpa_s,
2806 				    unsigned int type)
2807 {
2808 	type &= MAC_ADDR_RAND_ALL;
2809 	wpa_s->mac_addr_rand_enable &= ~type;
2810 
2811 	if (type & MAC_ADDR_RAND_SCAN) {
2812 		os_free(wpa_s->mac_addr_scan);
2813 		wpa_s->mac_addr_scan = NULL;
2814 	}
2815 
2816 	if (type & MAC_ADDR_RAND_SCHED_SCAN) {
2817 		os_free(wpa_s->mac_addr_sched_scan);
2818 		wpa_s->mac_addr_sched_scan = NULL;
2819 	}
2820 
2821 	if (type & MAC_ADDR_RAND_PNO) {
2822 		os_free(wpa_s->mac_addr_pno);
2823 		wpa_s->mac_addr_pno = NULL;
2824 	}
2825 }
2826 
2827 
wpas_mac_addr_rand_scan_set(struct wpa_supplicant * wpa_s,unsigned int type,const u8 * addr,const u8 * mask)2828 int wpas_mac_addr_rand_scan_set(struct wpa_supplicant *wpa_s,
2829 				unsigned int type, const u8 *addr,
2830 				const u8 *mask)
2831 {
2832 	u8 *tmp = NULL;
2833 
2834 	if ((wpa_s->mac_addr_rand_supported & type) != type ) {
2835 		wpa_printf(MSG_INFO,
2836 			   "scan: MAC randomization type %u != supported=%u",
2837 			   type, wpa_s->mac_addr_rand_supported);
2838 		return -1;
2839 	}
2840 
2841 	wpas_mac_addr_rand_scan_clear(wpa_s, type);
2842 
2843 	if (addr) {
2844 		tmp = os_malloc(2 * ETH_ALEN);
2845 		if (!tmp)
2846 			return -1;
2847 		os_memcpy(tmp, addr, ETH_ALEN);
2848 		os_memcpy(tmp + ETH_ALEN, mask, ETH_ALEN);
2849 	}
2850 
2851 	if (type == MAC_ADDR_RAND_SCAN) {
2852 		wpa_s->mac_addr_scan = tmp;
2853 	} else if (type == MAC_ADDR_RAND_SCHED_SCAN) {
2854 		wpa_s->mac_addr_sched_scan = tmp;
2855 	} else if (type == MAC_ADDR_RAND_PNO) {
2856 		wpa_s->mac_addr_pno = tmp;
2857 	} else {
2858 		wpa_printf(MSG_INFO,
2859 			   "scan: Invalid MAC randomization type=0x%x",
2860 			   type);
2861 		os_free(tmp);
2862 		return -1;
2863 	}
2864 
2865 	wpa_s->mac_addr_rand_enable |= type;
2866 	return 0;
2867 }
2868 
2869 
wpas_mac_addr_rand_scan_get_mask(struct wpa_supplicant * wpa_s,unsigned int type,u8 * mask)2870 int wpas_mac_addr_rand_scan_get_mask(struct wpa_supplicant *wpa_s,
2871 				     unsigned int type, u8 *mask)
2872 {
2873 	const u8 *to_copy;
2874 
2875 	if ((wpa_s->mac_addr_rand_enable & type) != type)
2876 		return -1;
2877 
2878 	if (type == MAC_ADDR_RAND_SCAN) {
2879 		to_copy = wpa_s->mac_addr_scan;
2880 	} else if (type == MAC_ADDR_RAND_SCHED_SCAN) {
2881 		to_copy = wpa_s->mac_addr_sched_scan;
2882 	} else if (type == MAC_ADDR_RAND_PNO) {
2883 		to_copy = wpa_s->mac_addr_pno;
2884 	} else {
2885 		wpa_printf(MSG_DEBUG,
2886 			   "scan: Invalid MAC randomization type=0x%x",
2887 			   type);
2888 		return -1;
2889 	}
2890 
2891 	os_memcpy(mask, to_copy + ETH_ALEN, ETH_ALEN);
2892 	return 0;
2893 }
2894 
2895 
wpas_abort_ongoing_scan(struct wpa_supplicant * wpa_s)2896 int wpas_abort_ongoing_scan(struct wpa_supplicant *wpa_s)
2897 {
2898 	struct wpa_radio_work *work;
2899 	struct wpa_radio *radio = wpa_s->radio;
2900 
2901 	dl_list_for_each(work, &radio->work, struct wpa_radio_work, list) {
2902 		if (work->wpa_s != wpa_s || !work->started ||
2903 		    (os_strcmp(work->type, "scan") != 0 &&
2904 		     os_strcmp(work->type, "p2p-scan") != 0))
2905 			continue;
2906 		wpa_dbg(wpa_s, MSG_DEBUG, "Abort an ongoing scan");
2907 		return wpa_drv_abort_scan(wpa_s, wpa_s->curr_scan_cookie);
2908 	}
2909 
2910 	wpa_dbg(wpa_s, MSG_DEBUG, "No ongoing scan/p2p-scan found to abort");
2911 	return -1;
2912 }
2913 
2914 
wpas_sched_scan_plans_set(struct wpa_supplicant * wpa_s,const char * cmd)2915 int wpas_sched_scan_plans_set(struct wpa_supplicant *wpa_s, const char *cmd)
2916 {
2917 	struct sched_scan_plan *scan_plans = NULL;
2918 	const char *token, *context = NULL;
2919 	unsigned int num = 0;
2920 
2921 	if (!cmd)
2922 		return -1;
2923 
2924 	if (!cmd[0]) {
2925 		wpa_printf(MSG_DEBUG, "Clear sched scan plans");
2926 		os_free(wpa_s->sched_scan_plans);
2927 		wpa_s->sched_scan_plans = NULL;
2928 		wpa_s->sched_scan_plans_num = 0;
2929 		return 0;
2930 	}
2931 
2932 	while ((token = cstr_token(cmd, " ", &context))) {
2933 		int ret;
2934 		struct sched_scan_plan *scan_plan, *n;
2935 
2936 		n = os_realloc_array(scan_plans, num + 1, sizeof(*scan_plans));
2937 		if (!n)
2938 			goto fail;
2939 
2940 		scan_plans = n;
2941 		scan_plan = &scan_plans[num];
2942 		num++;
2943 
2944 		ret = sscanf(token, "%u:%u", &scan_plan->interval,
2945 			     &scan_plan->iterations);
2946 		if (ret <= 0 || ret > 2 || !scan_plan->interval) {
2947 			wpa_printf(MSG_ERROR,
2948 				   "Invalid sched scan plan input: %s", token);
2949 			goto fail;
2950 		}
2951 
2952 		if (scan_plan->interval > wpa_s->max_sched_scan_plan_interval) {
2953 			wpa_printf(MSG_WARNING,
2954 				   "scan plan %u: Scan interval too long(%u), use the maximum allowed(%u)",
2955 				   num, scan_plan->interval,
2956 				   wpa_s->max_sched_scan_plan_interval);
2957 			scan_plan->interval =
2958 				wpa_s->max_sched_scan_plan_interval;
2959 		}
2960 
2961 		if (ret == 1) {
2962 			scan_plan->iterations = 0;
2963 			break;
2964 		}
2965 
2966 		if (!scan_plan->iterations) {
2967 			wpa_printf(MSG_ERROR,
2968 				   "scan plan %u: Number of iterations cannot be zero",
2969 				   num);
2970 			goto fail;
2971 		}
2972 
2973 		if (scan_plan->iterations >
2974 		    wpa_s->max_sched_scan_plan_iterations) {
2975 			wpa_printf(MSG_WARNING,
2976 				   "scan plan %u: Too many iterations(%u), use the maximum allowed(%u)",
2977 				   num, scan_plan->iterations,
2978 				   wpa_s->max_sched_scan_plan_iterations);
2979 			scan_plan->iterations =
2980 				wpa_s->max_sched_scan_plan_iterations;
2981 		}
2982 
2983 		wpa_printf(MSG_DEBUG,
2984 			   "scan plan %u: interval=%u iterations=%u",
2985 			   num, scan_plan->interval, scan_plan->iterations);
2986 	}
2987 
2988 	if (!scan_plans) {
2989 		wpa_printf(MSG_ERROR, "Invalid scan plans entry");
2990 		goto fail;
2991 	}
2992 
2993 	if (cstr_token(cmd, " ", &context) || scan_plans[num - 1].iterations) {
2994 		wpa_printf(MSG_ERROR,
2995 			   "All scan plans but the last must specify a number of iterations");
2996 		goto fail;
2997 	}
2998 
2999 	wpa_printf(MSG_DEBUG, "scan plan %u (last plan): interval=%u",
3000 		   num, scan_plans[num - 1].interval);
3001 
3002 	if (num > wpa_s->max_sched_scan_plans) {
3003 		wpa_printf(MSG_WARNING,
3004 			   "Too many scheduled scan plans (only %u supported)",
3005 			   wpa_s->max_sched_scan_plans);
3006 		wpa_printf(MSG_WARNING,
3007 			   "Use only the first %u scan plans, and the last one (in infinite loop)",
3008 			   wpa_s->max_sched_scan_plans - 1);
3009 		os_memcpy(&scan_plans[wpa_s->max_sched_scan_plans - 1],
3010 			  &scan_plans[num - 1], sizeof(*scan_plans));
3011 		num = wpa_s->max_sched_scan_plans;
3012 	}
3013 
3014 	os_free(wpa_s->sched_scan_plans);
3015 	wpa_s->sched_scan_plans = scan_plans;
3016 	wpa_s->sched_scan_plans_num = num;
3017 
3018 	return 0;
3019 
3020 fail:
3021 	os_free(scan_plans);
3022 	wpa_printf(MSG_ERROR, "invalid scan plans list");
3023 	return -1;
3024 }
3025 
3026 
3027 /**
3028  * wpas_scan_reset_sched_scan - Reset sched_scan state
3029  * @wpa_s: Pointer to wpa_supplicant data
3030  *
3031  * This function is used to cancel a running scheduled scan and to reset an
3032  * internal scan state to continue with a regular scan on the following
3033  * wpa_supplicant_req_scan() calls.
3034  */
wpas_scan_reset_sched_scan(struct wpa_supplicant * wpa_s)3035 void wpas_scan_reset_sched_scan(struct wpa_supplicant *wpa_s)
3036 {
3037 	wpa_s->normal_scans = 0;
3038 	if (wpa_s->sched_scanning) {
3039 		wpa_s->sched_scan_timed_out = 0;
3040 		wpa_s->prev_sched_ssid = NULL;
3041 		wpa_supplicant_cancel_sched_scan(wpa_s);
3042 	}
3043 }
3044 
3045 
wpas_scan_restart_sched_scan(struct wpa_supplicant * wpa_s)3046 void wpas_scan_restart_sched_scan(struct wpa_supplicant *wpa_s)
3047 {
3048 	/* simulate timeout to restart the sched scan */
3049 	wpa_s->sched_scan_timed_out = 1;
3050 	wpa_s->prev_sched_ssid = NULL;
3051 	wpa_supplicant_cancel_sched_scan(wpa_s);
3052 }
3053