mirror of
https://git.kernel.org/pub/scm/network/wireless/iwd.git
synced 2025-01-09 16:42:33 +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:
parent
cb9c6e8ade
commit
a4edbbd429
32
src/device.c
32
src/device.c
@ -86,6 +86,7 @@ struct device {
|
|||||||
bool autoconnect : 1;
|
bool autoconnect : 1;
|
||||||
bool preparing_roam : 1;
|
bool preparing_roam : 1;
|
||||||
bool signal_low : 1;
|
bool signal_low : 1;
|
||||||
|
bool roam_no_orig_ap : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct signal_agent {
|
struct signal_agent {
|
||||||
@ -554,11 +555,6 @@ static void device_disassociated(struct device *device)
|
|||||||
device_enter_state(device, DEVICE_STATE_AUTOCONNECT);
|
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)
|
static void device_disconnect_by_ap(struct device *device)
|
||||||
{
|
{
|
||||||
l_debug("%d", device->index);
|
l_debug("%d", device->index);
|
||||||
@ -749,6 +745,7 @@ static void device_roam_failed(struct device *device)
|
|||||||
l_debug("%d", device->index);
|
l_debug("%d", device->index);
|
||||||
|
|
||||||
device->preparing_roam = false;
|
device->preparing_roam = false;
|
||||||
|
device->roam_no_orig_ap = false;
|
||||||
|
|
||||||
if (device->state == DEVICE_STATE_ROAMING)
|
if (device->state == DEVICE_STATE_ROAMING)
|
||||||
device_disassociated(device);
|
device_disassociated(device);
|
||||||
@ -774,6 +771,7 @@ static void device_reassociate_cb(struct netdev *netdev,
|
|||||||
*/
|
*/
|
||||||
device->signal_low = false;
|
device->signal_low = false;
|
||||||
device->roam_min_time.tv_sec = 0;
|
device->roam_min_time.tv_sec = 0;
|
||||||
|
device->roam_no_orig_ap = false;
|
||||||
|
|
||||||
device_enter_state(device, DEVICE_STATE_CONNECTED);
|
device_enter_state(device, DEVICE_STATE_CONNECTED);
|
||||||
} else
|
} else
|
||||||
@ -798,6 +796,7 @@ static void device_fast_transition_cb(struct netdev *netdev,
|
|||||||
*/
|
*/
|
||||||
device->signal_low = false;
|
device->signal_low = false;
|
||||||
device->roam_min_time.tv_sec = 0;
|
device->roam_min_time.tv_sec = 0;
|
||||||
|
device->roam_no_orig_ap = false;
|
||||||
|
|
||||||
device_enter_state(device, DEVICE_STATE_CONNECTED);
|
device_enter_state(device, DEVICE_STATE_CONNECTED);
|
||||||
} else
|
} else
|
||||||
@ -943,6 +942,7 @@ static void device_transition_start(struct device *device, struct scan_bss *bss)
|
|||||||
* the current association."
|
* the current association."
|
||||||
*/
|
*/
|
||||||
if (security == SECURITY_8021X &&
|
if (security == SECURITY_8021X &&
|
||||||
|
!device->roam_no_orig_ap &&
|
||||||
scan_bss_get_rsn_info(device->connected_bss,
|
scan_bss_get_rsn_info(device->connected_bss,
|
||||||
&cur_rsne) >= 0 &&
|
&cur_rsne) >= 0 &&
|
||||||
scan_bss_get_rsn_info(bss, &target_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
|
* either by choice, or due to the fact that there may be neighbor
|
||||||
* APs not known to the AP."
|
* 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,
|
if (netdev_neighbor_report_req(device->netdev,
|
||||||
device_neighbor_report_cb) == 0)
|
device_neighbor_report_cb) == 0)
|
||||||
return;
|
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);
|
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,
|
static void device_connect_cb(struct netdev *netdev, enum netdev_result result,
|
||||||
void *user_data)
|
void *user_data)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user