From d48e386092ed53facfa883621d7bd499fbe4b5c0 Mon Sep 17 00:00:00 2001 From: Joel Low Date: Sun, 30 Apr 2023 08:38:44 +0800 Subject: [PATCH] policy: Attempt BSS transitions without disassociation_imminent first Signed-off-by: Joel Low --- policy.c | 38 +++++++++++++++++++++++++++++++++++--- ubus.c | 3 +++ usteer.h | 3 +++ 3 files changed, 41 insertions(+), 3 deletions(-) diff --git a/policy.c b/policy.c index 8c5d244..7073b08 100644 --- a/policy.c +++ b/policy.c @@ -321,6 +321,7 @@ usteer_roam_sm_found_better_node(struct sta_info *si, struct uevent *ev, enum ro static bool usteer_roam_trigger_sm(struct usteer_local_node *ln, struct sta_info *si) { + bool disassociation_imminent = true; struct sta_info *candidate; struct uevent ev = { .si_cur = si, @@ -344,6 +345,7 @@ usteer_roam_trigger_sm(struct usteer_local_node *ln, struct sta_info *si) if (config.roam_scan_tries && si->roam_tries >= config.roam_scan_tries) { if (!config.roam_scan_timeout) { /* Prepare to kick client */ + si->transition_request_count = 0; usteer_roam_set_state(si, ROAM_TRIGGER_SCAN_DONE, &ev); } else { /* Kick in scan timeout */ @@ -370,9 +372,39 @@ usteer_roam_trigger_sm(struct usteer_local_node *ln, struct sta_info *si) break; } - usteer_ubus_bss_transition_request(si, 1, false, false, 100, candidate->node); - si->kick_time = current_time + config.roam_kick_delay; - usteer_roam_set_state(si, ROAM_TRIGGER_IDLE, &ev); + if (!si->transition_request_count) { + si->transition_request_start = current_time; + si->transition_request_last = 0; + } + + /* If the sta acknowledged, we immediately bail */ + if (si->bss_transition_response.timestamp < si->transition_request_start || + (si->bss_transition_response.timestamp > si->transition_request_start && si->bss_transition_response.status_code)) { + /* Send gentle transitions, before setting disassociation_imminent=true. Approximately 1-5 seconds apart. */ + uint32_t delay = config.roam_kick_delay / 10; + if (delay < 1000) { + delay = 1000; + } else if (delay > 5000) { + delay = 5000; + } + if (current_time < si->transition_request_start + config.roam_kick_delay && + si->transition_request_last && current_time < si->transition_request_last + delay) { + /* Too soon to send another transition request */ + break; + } + + disassociation_imminent = si->transition_request_count > 3 && + (current_time - si->transition_request_start) > config.roam_kick_delay; + } + si->transition_request_count++; + si->transition_request_last = current_time; + + usteer_ubus_bss_transition_request(si, 1, disassociation_imminent, false, 100, candidate->node); + if (disassociation_imminent) { + si->kick_time = current_time + config.roam_kick_delay; + usteer_roam_set_state(si, ROAM_TRIGGER_IDLE, &ev); + } + return true; break; } diff --git a/ubus.c b/ubus.c index 40daf74..9b9173e 100644 --- a/ubus.c +++ b/ubus.c @@ -430,6 +430,9 @@ usteer_ubus_get_connected_clients(struct ubus_context *ctx, struct ubus_object * blobmsg_add_u64(&b, "last-kick", si->roam_kick ? current_time - si->roam_kick : 0); blobmsg_add_u64(&b, "scan_start", si->roam_scan_start ? current_time - si->roam_scan_start : 0); blobmsg_add_u64(&b, "scan_timeout_start", si->roam_scan_timeout_start ? current_time - si->roam_scan_timeout_start : 0); + blobmsg_add_u32(&b, "transition_request_count", si->transition_request_count); + blobmsg_add_u64(&b, "transition_request_start", si->transition_request_start ? current_time - si->transition_request_start : 0); + blobmsg_add_u64(&b, "transition_request_last", si->transition_request_last ? current_time - si->transition_request_last : 0); blobmsg_close_table(&b, t); t = blobmsg_open_table(&b, "bss-transition-response"); diff --git a/usteer.h b/usteer.h index f692fb8..5331200 100644 --- a/usteer.h +++ b/usteer.h @@ -267,6 +267,9 @@ struct sta_info { bool below_snr; } band_steering; + uint8_t transition_request_count; + uint64_t transition_request_start; + uint64_t transition_request_last; uint64_t kick_time; int kick_count;