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 "common/ieee802_11_defs.h"
13 #include "wpa_supplicant_i.h"
14 #include "drivers/driver.h"
15 #include "common/ieee802_11_common.h"
16 #include "bss.h"
17 #include "scan.h"
18 
19 /**
20  * wpa_supplicant_req_scan - Schedule a scan for neighboring access points
21  * @wpa_s: Pointer to wpa_supplicant data
22  * @sec: Number of seconds after which to scan
23  * @usec: Number of microseconds after which to scan
24  *
25  * This function is used to schedule a scan for neighboring access points after
26  * the specified time.
27  */
wpa_supplicant_req_scan(struct wpa_supplicant * wpa_s,int sec,int usec)28 void wpa_supplicant_req_scan(struct wpa_supplicant *wpa_s, int sec, int usec)
29 {
30 	int ret;
31 	struct wpa_driver_scan_params *params;
32 
33 	os_sleep(sec, usec);
34 
35 	if (wpa_s->scanning) {
36 		wpa_dbg(wpa_s, MSG_DEBUG, "Already scanning - Return");
37 		return;
38 	}
39 	if (!wpa_s->current_bss) {
40 		wpa_dbg(wpa_s, MSG_INFO, "Current BSS is null - Return");
41 		return;
42 	}
43 	params = os_zalloc(sizeof(*params));
44 
45 	if (!params) {
46 		wpa_printf(MSG_ERROR, "Memory allocation failed");
47 		return;
48 	}
49 #ifdef CONFIG_WNM
50 	if (wpa_s->wnm_mode) {
51 		/* Use the same memory */
52 		params->ssids[0].ssid = wpa_s->current_bss->ssid;
53 		params->ssids[0].ssid_len = wpa_s->current_bss->ssid_len;
54 		params->num_ssids = 1;
55 	}
56 #endif
57 	if (!is_zero_ether_addr(wpa_s->next_scan_bssid)) {
58 		/* Use the same memory */
59 		params->bssid = wpa_s->next_scan_bssid;
60 	}
61 
62 	if (wpa_s->next_scan_chan)
63 		params->channel = wpa_s->next_scan_chan;
64 
65 	wpa_s->scan_reason = REASON_WNM_BSS_TRANS_REQ;
66 	ret = wpa_supplicant_trigger_scan(wpa_s, params);
67 
68 	os_free(params);
69 
70 	if (ret < 0) {
71 		wpa_printf(MSG_ERROR, "Failed to issue scan - Return");
72 		return;
73 	}
74 }
75 
76 /**
77  * wpa_scan_get_ie - Fetch a specified information element from a scan result
78  * @res: Scan result entry
79  * @ie: Information element identitifier (WLAN_EID_*)
80  * Returns: Pointer to the information element (id field) or %NULL if not found
81  *
82  * This function returns the first matching information element in the scan
83  * result.
84  */
wpa_scan_get_ie(const struct wpa_scan_res * res,u8 ie)85 const u8 * wpa_scan_get_ie(const struct wpa_scan_res *res, u8 ie)
86 {
87 	size_t ie_len = res->ie_len;
88 
89 	/* Use the Beacon frame IEs if res->ie_len is not available */
90 	if (!ie_len)
91 		ie_len = res->beacon_ie_len;
92 
93 	return get_ie((const u8 *) (res + 1), ie_len, ie);
94 }
95 
wpa_scan_free_params(struct wpa_driver_scan_params * params)96 void wpa_scan_free_params(struct wpa_driver_scan_params *params)
97 {
98 	if (params == NULL)
99 		return;
100 
101 	os_free((u8 *) params->bssid);
102 
103 	os_free(params);
104 }
105