policy: add roam-scan timeout
authorDavid Bauer <mail@david-bauer.net>
Tue, 21 Dec 2021 14:30:14 +0000 (15:30 +0100)
committerDavid Bauer <mail@david-bauer.net>
Sun, 9 Jan 2022 23:45:19 +0000 (00:45 +0100)
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 <mail@david-bauer.net>
main.c
openwrt/usteer/files/etc/config/usteer
openwrt/usteer/files/etc/init.d/usteer
policy.c
ubus.c
usteer.h

diff --git a/main.c b/main.c
index 4e9ffa4084abb685c4df0f0d3bc43643e7aa33d5..901a133e1c40ec9a2a993acddecaadde4f470adb 100644 (file)
--- 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;
 
index f0b8867407271f0d200ec23725b8f82228b98f44..cedb8816fe31648a00f0a556cc61a89601c85871 100644 (file)
@@ -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
 
index d3579e75840a9bac3f0402a626c05e5e222f5ef6..f05d8c4ab47a6c8a05bd0daee709c3b678b11b1c 100755 (executable)
@@ -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 \
index 445abdefe8d9d57d3420bf01b387b557c67756b3..47a720f8299b1c549b29dbf34cd4edf34eeed519 100644 (file)
--- 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 52f2415bc6cff6f8f2568ed74910d9556f4f0456..4ff52bc25c76cbc9dadfbbdce4b1750add541fea 100644 (file)
--- 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), \
index 7bf6aa32cfd46328f7c9f4d76e682b68002f246d..280fdb2e4fa1e658bf008ebdea417ac7e3c35e41 100644 (file)
--- 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;