From d6b86996b2257f9ef0ba74e7e55a2139a97a922e Mon Sep 17 00:00:00 2001 From: Ben Greear Date: Wed, 2 Feb 2011 22:42:54 -0800 Subject: [PATCH 15/17] wpa_supplicant: Support minimum interval between scan attempts. 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 --- :100644 100644 f6d3f88... b0f4c81... M wpa_supplicant/config.c :100644 100644 ac0b329... 643283e... M wpa_supplicant/config.h :100644 100644 9905cc0... 7750116... M wpa_supplicant/events.c :100644 100644 7f4aa14... e487551... M wpa_supplicant/scan.c :100644 100644 c1a8808... be4ad5f... 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 f6d3f88..b0f4c81 100644 --- a/wpa_supplicant/config.c +++ b/wpa_supplicant/config.c @@ -2174,6 +2174,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); @@ -2413,6 +2414,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 ac0b329..643283e 100644 --- a/wpa_supplicant/config.h +++ b/wpa_supplicant/config.h @@ -29,6 +29,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" @@ -433,6 +434,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 9905cc0..7750116 100644 --- a/wpa_supplicant/events.c +++ b/wpa_supplicant/events.c @@ -934,6 +934,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 7f4aa14..e487551 100644 --- a/wpa_supplicant/scan.c +++ b/wpa_supplicant/scan.c @@ -504,6 +504,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 @@ -526,6 +528,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 c1a8808..be4ad5f 100644 --- a/wpa_supplicant/wpa_supplicant_i.h +++ b/wpa_supplicant/wpa_supplicant_i.h @@ -367,6 +367,7 @@ struct wpa_supplicant { int group_cipher; int key_mgmt; 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