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;