[RFC 13/13] wpa_supplicant: Support minimum interval between scan attempts.

greearb at candelatech.com greearb at candelatech.com
Fri Oct 14 18:34:37 EDT 2011


From: Ben Greear <greearb at candelatech.com>

When running lots of vifs, they can all end up wanting to
scan right after the other.  This leaves too little time for
useful work to happen.  Allow users to configure a minimum
timer interval (in seconds) between scans.  Default is zero,
which is current behaviour.

Signed-off-by: Ben Greear <greearb at candelatech.com>
---
:100644 100644 7ec4531... a4936a7... M	wpa_supplicant/config.c
:100644 100644 2bc05da... 453b1c3... M	wpa_supplicant/config.h
:100644 100644 7d886e7... 436d942... M	wpa_supplicant/events.c
:100644 100644 9159d31... fdbad91... M	wpa_supplicant/scan.c
:100644 100644 866649b... f195978... M	wpa_supplicant/wpa_supplicant_i.h
 wpa_supplicant/config.c           |    2 ++
 wpa_supplicant/config.h           |    4 ++++
 wpa_supplicant/events.c           |    1 +
 wpa_supplicant/scan.c             |   19 +++++++++++++++++++
 wpa_supplicant/wpa_supplicant_i.h |    1 +
 5 files changed, 27 insertions(+), 0 deletions(-)

diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c
index 7ec4531..a4936a7 100644
--- a/wpa_supplicant/config.c
+++ b/wpa_supplicant/config.c
@@ -2173,6 +2173,7 @@ struct wpa_config * wpa_config_alloc_empty(const char *ctrl_interface,
 	config->bss_expiration_age = DEFAULT_BSS_EXPIRATION_AGE;
 	config->bss_expiration_scan_count = DEFAULT_BSS_EXPIRATION_SCAN_COUNT;
 	config->max_num_sta = DEFAULT_MAX_NUM_STA;
+	config->min_scan_gap = DEFAULT_MIN_SCAN_GAP;
 
 	if (ctrl_interface)
 		config->ctrl_interface = os_strdup(ctrl_interface);
@@ -2411,6 +2412,7 @@ static const struct global_parse_data global_fields[] = {
 	{ INT(dot11RSNAConfigPMKLifetime), 0 },
 	{ INT(dot11RSNAConfigPMKReauthThreshold), 0 },
 	{ INT(dot11RSNAConfigSATimeout), 0 },
+	{ INT(min_scan_gap), 0 },
 #ifndef CONFIG_NO_CONFIG_WRITE
 	{ INT(update_config), 0 },
 #endif /* CONFIG_NO_CONFIG_WRITE */
diff --git a/wpa_supplicant/config.h b/wpa_supplicant/config.h
index 2bc05da..453b1c3 100644
--- a/wpa_supplicant/config.h
+++ b/wpa_supplicant/config.h
@@ -28,6 +28,7 @@
 #define DEFAULT_BSS_EXPIRATION_AGE 180
 #define DEFAULT_BSS_EXPIRATION_SCAN_COUNT 2
 #define DEFAULT_MAX_NUM_STA 128
+#define DEFAULT_MIN_SCAN_GAP 0
 
 #include "config_ssid.h"
 #include "wps/wps.h"
@@ -426,6 +427,9 @@ struct wpa_config {
 	 * disassoc_low_ack - Disassocicate stations with massive packet loss
 	 */
 	int disassoc_low_ack;
+
+	/* Minimum interval between scan requests, in seconds */
+	int min_scan_gap;
 };
 
 
diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
index 7d886e7..436d942 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -943,6 +943,7 @@ static int _wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s,
 		return 0;
 	}
 
+	wpa_s->last_scan_rx_sec = time(NULL);
 	wpa_dbg(wpa_s, MSG_DEBUG, "New scan results available");
 	wpa_msg_ctrl(wpa_s, MSG_INFO, WPA_EVENT_SCAN_RESULTS);
 	wpas_notify_scan_results(wpa_s);
diff --git a/wpa_supplicant/scan.c b/wpa_supplicant/scan.c
index 9159d31..fdbad91 100644
--- a/wpa_supplicant/scan.c
+++ b/wpa_supplicant/scan.c
@@ -517,6 +517,8 @@ static void wpa_supplicant_scan(void *eloop_ctx, void *timeout_ctx)
  */
 void wpa_supplicant_req_scan(struct wpa_supplicant *wpa_s, int sec, int usec)
 {
+	int n;
+
 	/* If there's at least one network that should be specifically scanned
 	 * then don't cancel the scan and reschedule.  Some drivers do
 	 * background scanning which generates frequent scan results, and that
@@ -539,6 +541,23 @@ void wpa_supplicant_req_scan(struct wpa_supplicant *wpa_s, int sec, int usec)
 		}
 	}
 
+	/* With lots of VIFS, we can end up trying to scan very often.
+	 * This can cause us to not be able to associate due to missing
+	 * EAPOL key messages and such.  So, allow a minimum time between
+	 * scans.
+	 */
+	if (wpa_s->conf->min_scan_gap) {
+		int mingap;
+		n = time(NULL);
+		if (n >= wpa_s->last_scan_rx_sec)
+			wpa_s->last_scan_rx_sec = n;
+
+		mingap = wpa_s->conf->min_scan_gap
+			- (n - wpa_s->last_scan_rx_sec);
+		if (sec < mingap)
+			sec = mingap;
+	}
+
 	wpa_dbg(wpa_s, MSG_DEBUG, "Setting scan request: %d sec %d usec",
 		sec, usec);
 	eloop_cancel_timeout(wpa_supplicant_scan, wpa_s, NULL);
diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
index 866649b..f195978 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -375,6 +375,7 @@ struct wpa_supplicant {
 	int key_mgmt;
 	int wpa_proto;
 	int mgmt_group_cipher;
+	int last_scan_rx_sec;
 
 	void *drv_priv; /* private data used by driver_ops */
 	void *global_drv_priv;
-- 
1.7.3.4



More information about the HostAP mailing list