aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Stewart <pstew@chromium.org>2012-02-05 16:43:06 (GMT)
committerJouni Malinen <j@w1.fi>2012-02-05 16:43:06 (GMT)
commit87343c2017dd543098d06ced597860bb8a963141 (patch)
treeb9cf102647f8ec34bc2c288afee285cea3aa1d65
parent0f4668ceac37e2c98ce6068bd255d0915974a706 (diff)
downloadhostap-87343c2017dd543098d06ced597860bb8a963141.zip
hostap-87343c2017dd543098d06ced597860bb8a963141.tar.gz
hostap-87343c2017dd543098d06ced597860bb8a963141.tar.bz2
bgscan_simple: Refinements to fast-scan backoff
These changes account for situations where the CQM threshold might be approximately the same as the currently received signal, and thus CQM events are triggered often due to measurement error/small fluctuations. This results in scanning occurring too frequently. Firstly, inhibit the immediate scan when the short-scan count is at the maximum. This keeps bursts of CQM toggling from causing a torrent of back-to-back scans. This does not inhibit immediate scans if the CQM triggers a second time (if the signal falls lower past the hysteresis). This reduces the scan rate in the worst case (fast-rate toggling high/low CQM events) to the short scan interval. Secondly, change the behavior of the short scan count so it acts like a "leaky bucket". As we perform short-scans, the bucket fills until it reaches a maximal short-scan count, at which we back-off and revert to a long scan interval. The short scan count decreases by one (emptying the bucket) every time we complete a long scan interval without a low-RSSI CQM event. This reduces the impact of medium-rate toggling of high/low CQM events, reducing the number of short-interval scans that occur before returning to a long-interval if the system was recently doing short scans.
-rw-r--r--wpa_supplicant/bgscan_simple.c23
1 files changed, 19 insertions, 4 deletions
diff --git a/wpa_supplicant/bgscan_simple.c b/wpa_supplicant/bgscan_simple.c
index eedc961..a622ce6 100644
--- a/wpa_supplicant/bgscan_simple.c
+++ b/wpa_supplicant/bgscan_simple.c
@@ -29,6 +29,7 @@ struct bgscan_simple_data {
int scan_interval;
int signal_threshold;
int short_scan_count; /* counter for scans using short scan interval */
+ int max_short_scans; /* maximum times we short-scan before back-off */
int short_interval; /* use if signal < threshold */
int long_interval; /* use if signal > threshold */
struct os_time last_bgscan;
@@ -66,12 +67,19 @@ static void bgscan_simple_timeout(void *eloop_ctx, void *timeout_ctx)
* scanning at the short scan interval. After that,
* revert to the long scan interval.
*/
- if (data->short_scan_count >
- data->long_interval / data->short_interval + 1) {
+ if (data->short_scan_count > data->max_short_scans) {
data->scan_interval = data->long_interval;
wpa_printf(MSG_DEBUG, "bgscan simple: Backing "
"off to long scan interval");
}
+ } else if (data->short_scan_count > 0) {
+ /*
+ * If we lasted a long scan interval without any
+ * CQM triggers, decrease the short-scan count,
+ * which allows 1 more short-scan interval to
+ * occur in the future when CQM triggers.
+ */
+ data->short_scan_count--;
}
os_get_time(&data->last_bgscan);
}
@@ -138,6 +146,7 @@ static void * bgscan_simple_init(struct wpa_supplicant *wpa_s,
}
data->scan_interval = data->short_interval;
+ data->max_short_scans = data->long_interval / data->short_interval + 1;
if (data->signal_threshold) {
/* Poll for signal info to set initial scan interval */
struct wpa_signal_info siginfo;
@@ -222,9 +231,15 @@ static void bgscan_simple_notify_signal_change(void *priv, int above,
wpa_printf(MSG_DEBUG, "bgscan simple: Start using short "
"bgscan interval");
data->scan_interval = data->short_interval;
- data->short_scan_count = 0;
os_get_time(&now);
- if (now.sec > data->last_bgscan.sec + 1)
+ if (now.sec > data->last_bgscan.sec + 1 &&
+ data->short_scan_count <= data->max_short_scans)
+ /*
+ * If we haven't just previously (<1 second ago)
+ * performed a scan, and we haven't depleted our
+ * budget for short-scans, perform a scan
+ * immediately.
+ */
scan = 1;
else if (data->last_bgscan.sec + data->long_interval >
now.sec + data->scan_interval) {