summaryrefslogtreecommitdiff
path: root/package/wpa_supplicant/patches/130-scanning.patch
blob: 1f8cb4597ec4af877461bf997b52596ff5a2aa98 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
Add a scan result cache to improve roaming speed if the driver gave us a background scan before losing the connection.

--- a/wpa_supplicant/config.h
+++ b/wpa_supplicant/config.h
@@ -97,6 +97,12 @@ struct wpa_config {
 	int ap_scan;
 
 	/**
+	 * scan_cache - controls the time in seconds after the last scan results
+	 * before a new scan may be initiated
+	 */
+	int scan_cache;
+
+	/**
 	 * ctrl_interface - Parameters for the control interface
 	 *
 	 * If this is specified, %wpa_supplicant will open a control interface
--- a/wpa_supplicant/config_file.c
+++ b/wpa_supplicant/config_file.c
@@ -306,6 +306,13 @@ static int wpa_config_parse_int(const st
 	return 0;
 }
 
+static int wpa_config_process_scan_cache(struct wpa_config *config, char *pos)
+{
+	config->scan_cache = atoi(pos);
+	wpa_printf(MSG_DEBUG, "scan_cache=%d", config->scan_cache);
+	return 0;
+}
+
 
 static int wpa_config_parse_str(const struct global_parse_data *data,
 				struct wpa_config *config, int line,
@@ -433,6 +440,7 @@ static const struct global_parse_data gl
 #endif /* CONFIG_CTRL_IFACE */
 	{ INT_RANGE(eapol_version, 1, 2) },
 	{ INT(ap_scan) },
+	{ INT(scan_cache) },
 	{ INT(fast_reauth) },
 #ifdef EAP_TLS_OPENSSL
 	{ STR(opensc_engine_path) },
@@ -834,6 +842,8 @@ static void wpa_config_write_global(FILE
 		fprintf(f, "eapol_version=%d\n", config->eapol_version);
 	if (config->ap_scan != DEFAULT_AP_SCAN)
 		fprintf(f, "ap_scan=%d\n", config->ap_scan);
+	if (config->scan_cache != 0)
+		fprintf(f, "scan_cache=%d\n", config->scan_cache);
 	if (config->fast_reauth != DEFAULT_FAST_REAUTH)
 		fprintf(f, "fast_reauth=%d\n", config->fast_reauth);
 #ifdef EAP_TLS_OPENSSL
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -633,6 +633,9 @@ static void wpa_supplicant_event_scan_re
 	    wpa_s->disconnected)
 		return;
 
+	if (wpa_s->wpa_state > WPA_ASSOCIATED)
+		goto done;
+
 	while (selected == NULL) {
 		for (prio = 0; prio < wpa_s->conf->num_prio; prio++) {
 			selected = wpa_supplicant_select_bss(
@@ -645,6 +648,7 @@ static void wpa_supplicant_event_scan_re
 			wpa_printf(MSG_DEBUG, "No APs found - clear blacklist "
 				   "and try again");
 			wpa_blacklist_clear(wpa_s);
+			memset(&wpa_s->last_scan_results, 0, sizeof(wpa_s->last_scan_results));
 		} else if (selected == NULL) {
 			break;
 		}
@@ -679,10 +683,12 @@ static void wpa_supplicant_event_scan_re
 		rsn_preauth_scan_results(wpa_s->wpa, wpa_s->scan_res);
 	} else {
 		wpa_printf(MSG_DEBUG, "No suitable AP found.");
-		timeout = 5;
+		timeout = 0;
 		goto req_scan;
 	}
 
+done:
+	os_get_time(&wpa_s->last_scan_results);
 	return;
 
 req_scan:
@@ -886,6 +892,9 @@ static void wpa_supplicant_event_disasso
 	}
 	if (wpa_s->wpa_state >= WPA_ASSOCIATED)
 		wpa_supplicant_req_scan(wpa_s, 0, 100000);
+	else if (wpa_s->wpa_state == WPA_ASSOCIATING)
+		wpa_supplicant_req_auth_timeout(wpa_s, 0, 100000);
+
 	bssid = wpa_s->bssid;
 	if (is_zero_ether_addr(bssid))
 		bssid = wpa_s->pending_bssid;
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -349,6 +349,7 @@ struct wpa_supplicant {
 	struct wpa_client_mlme mlme;
 	int use_client_mlme;
 	int driver_4way_handshake;
+	struct os_time last_scan_results;
 
 	int pending_mic_error_report;
 	int pending_mic_error_pairwise;
@@ -402,6 +403,7 @@ int wpa_supplicant_scard_init(struct wpa
 
 /* scan.c */
 void wpa_supplicant_req_scan(struct wpa_supplicant *wpa_s, int sec, int usec);
+int wpa_supplicant_may_scan(struct wpa_supplicant *wpa_s);
 void wpa_supplicant_cancel_scan(struct wpa_supplicant *wpa_s);
 
 /* events.c */
--- a/wpa_supplicant/scan.c
+++ b/wpa_supplicant/scan.c
@@ -40,6 +40,18 @@ static void wpa_supplicant_gen_assoc_eve
 	wpa_supplicant_event(wpa_s, EVENT_ASSOC, &data);
 }
 
+int wpa_supplicant_may_scan(struct wpa_supplicant *wpa_s)
+{
+	struct os_time time;
+
+	if (wpa_s->conf->scan_cache > 0) {
+		os_get_time(&time);
+		time.sec -= wpa_s->conf->scan_cache;
+		if (os_time_before(&time, &wpa_s->last_scan_results))
+			return 0;
+	}
+	return 1;
+}
 
 #ifdef CONFIG_WPS
 static int wpas_wps_in_use(struct wpa_config *conf,
@@ -183,8 +195,9 @@ static void wpa_supplicant_scan(void *el
 	wps = wpas_wps_in_use(wpa_s->conf, &req_type);
 #endif /* CONFIG_WPS */
 
-	if (wpa_s->scan_res_tried == 0 && wpa_s->conf->ap_scan == 1 &&
-	    !wpa_s->use_client_mlme && wps != 2) {
+	if (!wpa_supplicant_may_scan(wpa_s) ||
+	    (wpa_s->scan_res_tried == 0 && wpa_s->conf->ap_scan == 1 &&
+	    !wpa_s->use_client_mlme && wps != 2)) {
 		wpa_s->scan_res_tried++;
 		wpa_s->scan_req = scan_req;
 		wpa_printf(MSG_DEBUG, "Trying to get current scan results "
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -1491,6 +1491,9 @@ void wpa_supplicant_rx_eapol(void *ctx, 
 {
 	struct wpa_supplicant *wpa_s = ctx;
 
+	if (wpa_s->wpa_state < WPA_ASSOCIATING)
+		return;
+
 	wpa_printf(MSG_DEBUG, "RX EAPOL from " MACSTR, MAC2STR(src_addr));
 	wpa_hexdump(MSG_MSGDUMP, "RX EAPOL", buf, len);