From 9a78412ac5afadd27a8a949e82d7a5d3591534c9 Mon Sep 17 00:00:00 2001 From: David Bauer Date: Tue, 21 Dec 2021 15:30:14 +0100 Subject: [PATCH] policy: add roam-scan timeout Add an optional timeout when a better roaming candidate is not found after the scan-retry limit. The roam state-machine will not retry scanning before this timeout has expired. If the timeout is set to 0, the client is kicked instead, which resembles the behavior prior this commit. This is added, as without this patch, if a forced disconnect is not desired before roam_scan_trigger is exceeded the client will repeatedly be asked to return active beacon-reports. For battery powered clients this can result in a noticeable battery drain. Signed-off-by: David Bauer --- main.c | 1 + openwrt/usteer/files/etc/config/usteer | 4 +++ openwrt/usteer/files/etc/init.d/usteer | 2 +- policy.c | 38 ++++++++++++++++++++++---- ubus.c | 1 + usteer.h | 2 ++ 6 files changed, 41 insertions(+), 7 deletions(-) diff --git a/main.c b/main.c index 4e9ffa4..901a133 100644 --- a/main.c +++ b/main.c @@ -99,6 +99,7 @@ void usteer_init_defaults(void) config.roam_kick_delay = 100; config.roam_process_timeout = 5 * 1000; config.roam_scan_tries = 3; + config.roam_scan_timeout = 0; config.roam_scan_interval = 10 * 1000; config.roam_trigger_interval = 60 * 1000; diff --git a/openwrt/usteer/files/etc/config/usteer b/openwrt/usteer/files/etc/config/usteer index f0b8867..cedb881 100644 --- a/openwrt/usteer/files/etc/config/usteer +++ b/openwrt/usteer/files/etc/config/usteer @@ -67,6 +67,10 @@ config usteer # Maximum number of client roaming scan trigger attempts #option roam_scan_tries 3 + # Retry scanning when roam_scan_tries is exceeded after this timeout (in ms) + # In case this option is set to 0, the client is kicked instead + #option roam_scan_timeout 0 + # Minimum time (ms) between client roaming scan trigger attempts #option roam_scan_interval 10000 diff --git a/openwrt/usteer/files/etc/init.d/usteer b/openwrt/usteer/files/etc/init.d/usteer index d3579e7..f05d8c4 100755 --- a/openwrt/usteer/files/etc/init.d/usteer +++ b/openwrt/usteer/files/etc/init.d/usteer @@ -80,7 +80,7 @@ uci_usteer() { remote_update_interval remote_node_timeout\ min_connect_snr min_snr signal_diff_threshold \ initial_connect_delay roam_process_timeout\ - roam_kick_delay roam_scan_tries \ + roam_kick_delay roam_scan_tries roam_scan_timeout \ roam_scan_snr roam_scan_interval \ roam_trigger_snr roam_trigger_interval \ load_kick_threshold load_kick_delay load_kick_min_clients \ diff --git a/policy.c b/policy.c index 445abde..47a720f 100644 --- a/policy.c +++ b/policy.c @@ -272,6 +272,26 @@ usteer_roam_set_state(struct sta_info *si, enum roam_trigger_state state, usteer_event(ev); } +static void +usteer_roam_sm_start_scan(struct sta_info *si, struct uevent *ev) +{ + /* Start scanning in case we are not timeout-constrained or timeout has expired */ + if (config.roam_scan_timeout && + current_time > si->roam_scan_timeout_start + config.roam_scan_timeout) { + usteer_roam_set_state(si, ROAM_TRIGGER_SCAN, ev); + return; + } + + /* We are currently in scan timeout / cooldown. + * Check if we are in ROAM_TRIGGER_IDLE state and enter this stateif not. + */ + if (si->roam_state == ROAM_TRIGGER_IDLE) + return; + + /* Enter idle state */ + usteer_roam_set_state(si, ROAM_TRIGGER_IDLE, ev); +} + static bool usteer_roam_trigger_sm(struct sta_info *si) { @@ -293,14 +313,20 @@ usteer_roam_trigger_sm(struct sta_info *si) break; } - if (config.roam_scan_tries && - si->roam_tries >= config.roam_scan_tries) { - usteer_roam_set_state(si, ROAM_TRIGGER_WAIT_KICK, &ev); + if (config.roam_scan_tries && si->roam_tries >= config.roam_scan_tries) { + if (!config.roam_scan_timeout) { + /* Prepare to kick client */ + usteer_roam_set_state(si, ROAM_TRIGGER_WAIT_KICK, &ev); + } else { + /* Kick in scan timeout */ + si->roam_scan_timeout_start = current_time; + usteer_roam_set_state(si, ROAM_TRIGGER_IDLE, &ev); + } break; } usteer_ubus_trigger_client_scan(si); - usteer_roam_set_state(si, ROAM_TRIGGER_SCAN, &ev); + usteer_roam_sm_start_scan(si, &ev); break; case ROAM_TRIGGER_IDLE: @@ -309,13 +335,13 @@ usteer_roam_trigger_sm(struct sta_info *si) break; } - usteer_roam_set_state(si, ROAM_TRIGGER_SCAN, &ev); + usteer_roam_sm_start_scan(si, &ev); break; case ROAM_TRIGGER_SCAN_DONE: /* Check for stale scan results, kick back to SCAN state if necessary */ if (current_time - si->roam_scan_done > 2 * config.roam_scan_interval) { - usteer_roam_set_state(si, ROAM_TRIGGER_SCAN, &ev); + usteer_roam_sm_start_scan(si, &ev); break; } diff --git a/ubus.c b/ubus.c index 52f2415..4ff52bc 100644 --- a/ubus.c +++ b/ubus.c @@ -159,6 +159,7 @@ struct cfg_item { _cfg(U32, roam_process_timeout), \ _cfg(I32, roam_scan_snr), \ _cfg(U32, roam_scan_tries), \ + _cfg(U32, roam_scan_timeout), \ _cfg(U32, roam_scan_interval), \ _cfg(I32, roam_trigger_snr), \ _cfg(U32, roam_trigger_interval), \ diff --git a/usteer.h b/usteer.h index 7bf6aa3..280fdb2 100644 --- a/usteer.h +++ b/usteer.h @@ -172,6 +172,7 @@ struct usteer_config { uint32_t roam_process_timeout; uint32_t roam_scan_tries; + uint32_t roam_scan_timeout; uint32_t roam_scan_interval; int32_t roam_trigger_snr; @@ -229,6 +230,7 @@ struct sta_info { uint64_t roam_event; uint64_t roam_kick; uint64_t roam_scan_done; + uint64_t roam_scan_timeout_start; int kick_count; -- 2.30.2