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.
This commit is contained in:
Alvin Šipraga 2021-01-22 13:37:00 +00:00 committed by Denis Kenzior
parent 9ac59700d1
commit f456501b9e
1 changed files with 8 additions and 6 deletions

View File

@ -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,