mirror of
https://git.kernel.org/pub/scm/network/wireless/iwd.git
synced 2024-12-21 11:52:34 +01:00
station: Re-attempt roam with a full scan
When roaming, iwd tries to scan a limited number of frequencies to keep the roaming latency down. Ideally the frequency list would come in from a neighbor report, but if neighbor reports are not supported, we fall back to our internal database for known frequencies of this network. iwd tries to keep the number of scans down to a bare minimum, which means that we might miss APs that are in range. This could happen because the user might have moved physically and our frequency list is no longer up to date, or if the AP frequencies have been reconfigured. If a limited scan fails to find any good roaming candidates, re-attempt a full scan right away.
This commit is contained in:
parent
b026e6740b
commit
a1b41f786e
@ -96,6 +96,7 @@ struct station {
|
|||||||
struct netconfig *netconfig;
|
struct netconfig *netconfig;
|
||||||
|
|
||||||
bool preparing_roam : 1;
|
bool preparing_roam : 1;
|
||||||
|
bool roam_scan_full : 1;
|
||||||
bool signal_low : 1;
|
bool signal_low : 1;
|
||||||
bool roam_no_orig_ap : 1;
|
bool roam_no_orig_ap : 1;
|
||||||
bool ap_directed_roaming : 1;
|
bool ap_directed_roaming : 1;
|
||||||
@ -1282,6 +1283,7 @@ static void station_roam_state_clear(struct station *station)
|
|||||||
l_timeout_remove(station->roam_trigger_timeout);
|
l_timeout_remove(station->roam_trigger_timeout);
|
||||||
station->roam_trigger_timeout = NULL;
|
station->roam_trigger_timeout = NULL;
|
||||||
station->preparing_roam = false;
|
station->preparing_roam = false;
|
||||||
|
station->roam_scan_full = false;
|
||||||
station->signal_low = false;
|
station->signal_low = false;
|
||||||
station->roam_min_time.tv_sec = 0;
|
station->roam_min_time.tv_sec = 0;
|
||||||
|
|
||||||
@ -1345,6 +1347,8 @@ static void station_disconnect_event(struct station *station, void *event_data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void station_roam_timeout_rearm(struct station *station, int seconds);
|
static void station_roam_timeout_rearm(struct station *station, int seconds);
|
||||||
|
static int station_roam_scan(struct station *station,
|
||||||
|
struct scan_freq_set *freq_set);
|
||||||
|
|
||||||
static void station_roamed(struct station *station)
|
static void station_roamed(struct station *station)
|
||||||
{
|
{
|
||||||
@ -1355,6 +1359,7 @@ static void station_roamed(struct station *station)
|
|||||||
station->signal_low = false;
|
station->signal_low = false;
|
||||||
station->roam_min_time.tv_sec = 0;
|
station->roam_min_time.tv_sec = 0;
|
||||||
station->roam_no_orig_ap = false;
|
station->roam_no_orig_ap = false;
|
||||||
|
station->roam_scan_full = false;
|
||||||
|
|
||||||
if (station->netconfig)
|
if (station->netconfig)
|
||||||
netconfig_reconfigure(station->netconfig);
|
netconfig_reconfigure(station->netconfig);
|
||||||
@ -1375,12 +1380,29 @@ static void station_roam_failed(struct station *station)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We were told by the AP to roam, but failed. Try ourselves or
|
||||||
|
* wait for the AP to tell us to roam again
|
||||||
|
*/
|
||||||
|
if (station->ap_directed_roaming)
|
||||||
|
goto delayed_retry;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If we tried a limited scan, failed and the signal is still low,
|
||||||
|
* repeat with a full scan right away
|
||||||
|
*/
|
||||||
|
if (station->signal_low && !station->roam_scan_full &&
|
||||||
|
!station_roam_scan(station, NULL))
|
||||||
|
return;
|
||||||
|
|
||||||
|
delayed_retry:
|
||||||
/*
|
/*
|
||||||
* If we're still connected to the old BSS, only clear preparing_roam
|
* If we're still connected to the old BSS, only clear preparing_roam
|
||||||
* and reattempt in 60 seconds if signal level is still low at that
|
* and reattempt in 60 seconds if signal level is still low at that
|
||||||
* time.
|
* time.
|
||||||
*/
|
*/
|
||||||
station->preparing_roam = false;
|
station->preparing_roam = false;
|
||||||
|
station->roam_scan_full = false;
|
||||||
station->ap_directed_roaming = false;
|
station->ap_directed_roaming = false;
|
||||||
|
|
||||||
if (station->signal_low)
|
if (station->signal_low)
|
||||||
@ -1784,6 +1806,9 @@ static int station_roam_scan(struct station *station,
|
|||||||
/* Use direct probe request */
|
/* Use direct probe request */
|
||||||
params.ssid = network_get_ssid(station->connected_network);
|
params.ssid = network_get_ssid(station->connected_network);
|
||||||
|
|
||||||
|
if (!freq_set)
|
||||||
|
station->roam_scan_full = true;
|
||||||
|
|
||||||
station->roam_scan_id =
|
station->roam_scan_id =
|
||||||
scan_active_full(netdev_get_wdev_id(station->netdev), ¶ms,
|
scan_active_full(netdev_get_wdev_id(station->netdev), ¶ms,
|
||||||
station_roam_scan_triggered,
|
station_roam_scan_triggered,
|
||||||
|
Loading…
Reference in New Issue
Block a user