3
0
mirror of https://git.kernel.org/pub/scm/network/wireless/iwd.git synced 2025-01-09 00:12:36 +01:00

device: Trigger roaming on beacon loss

Use beacon loss event to trigger a roam attempt in addition to the RSSI
monitoring.  Due to the how well beacons are normally received compared
to data packets, a beacon loss indicates a serious problem with the
connection so act as soon as a first beacon loss event is seen.

Avoid roaming methods that involve the current AP: preauthentication,
neighbor report request and FT-over-the-DS (not supported)
This commit is contained in:
Andrew Zaborowski 2017-08-14 14:31:18 +02:00 committed by Denis Kenzior
parent cb9c6e8ade
commit a4edbbd429

View File

@ -86,6 +86,7 @@ struct device {
bool autoconnect : 1;
bool preparing_roam : 1;
bool signal_low : 1;
bool roam_no_orig_ap : 1;
};
struct signal_agent {
@ -554,11 +555,6 @@ static void device_disassociated(struct device *device)
device_enter_state(device, DEVICE_STATE_AUTOCONNECT);
}
static void device_lost_beacon(struct device *device)
{
l_debug("%d", device->index);
}
static void device_disconnect_by_ap(struct device *device)
{
l_debug("%d", device->index);
@ -749,6 +745,7 @@ static void device_roam_failed(struct device *device)
l_debug("%d", device->index);
device->preparing_roam = false;
device->roam_no_orig_ap = false;
if (device->state == DEVICE_STATE_ROAMING)
device_disassociated(device);
@ -774,6 +771,7 @@ static void device_reassociate_cb(struct netdev *netdev,
*/
device->signal_low = false;
device->roam_min_time.tv_sec = 0;
device->roam_no_orig_ap = false;
device_enter_state(device, DEVICE_STATE_CONNECTED);
} else
@ -798,6 +796,7 @@ static void device_fast_transition_cb(struct netdev *netdev,
*/
device->signal_low = false;
device->roam_min_time.tv_sec = 0;
device->roam_no_orig_ap = false;
device_enter_state(device, DEVICE_STATE_CONNECTED);
} else
@ -943,6 +942,7 @@ static void device_transition_start(struct device *device, struct scan_bss *bss)
* the current association."
*/
if (security == SECURITY_8021X &&
!device->roam_no_orig_ap &&
scan_bss_get_rsn_info(device->connected_bss,
&cur_rsne) >= 0 &&
scan_bss_get_rsn_info(bss, &target_rsne) >= 0 &&
@ -1286,7 +1286,8 @@ static void device_roam_trigger_cb(struct l_timeout *timeout, void *user_data)
* either by choice, or due to the fact that there may be neighbor
* APs not known to the AP."
*/
if (device->connected_bss->cap_rm_neighbor_report)
if (device->connected_bss->cap_rm_neighbor_report &&
!device->roam_no_orig_ap)
if (netdev_neighbor_report_req(device->netdev,
device_neighbor_report_cb) == 0)
return;
@ -1316,6 +1317,25 @@ static void device_roam_timeout_rearm(struct device *device, int seconds)
l_timeout_create(seconds, device_roam_trigger_cb, device, NULL);
}
static void device_lost_beacon(struct device *device)
{
l_debug("%d", device->index);
if (device->preparing_roam || device->state == DEVICE_STATE_ROAMING)
return;
/*
* Tell the roam mechanism to not bother requesting Neighbor Reports,
* preauthenticating or performing other over-the-DS type of
* authentication to target AP, even while device->connected_bss is
* still non-NULL. The current connection is in a serious condition
* and we might wasting our time with those mechanisms.
*/
device->roam_no_orig_ap = true;
device_roam_trigger_cb(NULL, device);
}
static void device_connect_cb(struct netdev *netdev, enum netdev_result result,
void *user_data)
{