From f456501b9eb1e699316e9cc0466fd1d97ddcf153 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alvin=20=C5=A0ipraga?= Date: Fri, 22 Jan 2021 13:37:00 +0000 Subject: [PATCH] station: retry roaming unless notified of a high RSSI Following a successful roaming sequence, schedule another attempt unless the driver has sent a high RSSI notification. This makes the behaviour analogous to a failed roaming attempt where we remained connected to the same BSS. This makes iwd compatible with wireless drivers which do not necessarily send out a duplicate low RSSI notification upon reassociation. Without this change, iwd risks getting indefinitely stuck to a BSS with low signal strength, even though a better BSS might later become available. In the case of a high RSSI notification, the minimum roam time will also be reset to zero. This preserves the original behaviour in the case where a high RSSI notification is processed after station_roamed(). Doing so also gives a chance for faster roaming action in the following example scenario: 1. RSSI LOW 2. schedule roam in 5 seconds (5 seconds pass) 3. try roaming 4. roaming fails, same BSS 5. schedule roam in 60 seconds (20 seconds pass) 6. RSSI HIGH 7. cancel scheduled roam (20 seconds pass) 8. RSSI LOW 9. schedule roam in 5 seconds or 20 seconds? By resetting the minimum roam time, we can avoid waiting 20 seconds when the station may have moved considerably. And since the high/low RSSI notifications are configured with a hysteresis, we should still be protected against too frequent spurious roaming attempts. --- src/station.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/station.c b/src/station.c index c65fc0cc..2e886a73 100644 --- a/src/station.c +++ b/src/station.c @@ -1362,14 +1362,15 @@ static int station_roam_scan(struct station *station, static void station_roamed(struct station *station) { - /* - * New signal high/low notification should occur on the next - * beacon from new AP. - */ - station->signal_low = false; - station->roam_min_time.tv_sec = 0; station->roam_scan_full = false; + /* + * Schedule another roaming attempt in case the signal continues to + * remain low. A subsequent high signal notification will cancel it. + */ + if (station->signal_low) + station_roam_timeout_rearm(station, 60); + if (station->netconfig) netconfig_reconfigure(station->netconfig); @@ -2227,6 +2228,7 @@ static void station_ok_rssi(struct station *station) station->roam_trigger_timeout = NULL; station->signal_low = false; + station->roam_min_time.tv_sec = 0; } static void station_rssi_level_changed(struct station *station,