From 103eeb2cc6c398b60bec2263c7e98bde550714df Mon Sep 17 00:00:00 2001 From: James Prestwood Date: Tue, 9 Aug 2022 16:04:25 -0700 Subject: [PATCH] station: react to (new) netdev packet loss event This adds a new netdev event for packet loss notifications from the kernel. Depending on the scenario a station may see packet loss events without any other indications like low RSSI. In these cases IWD should still roam since there is no data flowing. --- src/netdev.h | 1 + src/station.c | 39 +++++++++++++++++++++++++++++++++------ 2 files changed, 34 insertions(+), 6 deletions(-) diff --git a/src/netdev.h b/src/netdev.h index f093c499..d13bc5e6 100644 --- a/src/netdev.h +++ b/src/netdev.h @@ -49,6 +49,7 @@ enum netdev_event { NETDEV_EVENT_RSSI_THRESHOLD_LOW, NETDEV_EVENT_RSSI_THRESHOLD_HIGH, NETDEV_EVENT_RSSI_LEVEL_NOTIFY, + NETDEV_EVENT_PACKET_LOSS_NOTIFY, }; enum netdev_watch_event { diff --git a/src/station.c b/src/station.c index 38909c98..66b296b8 100644 --- a/src/station.c +++ b/src/station.c @@ -2535,15 +2535,10 @@ static void station_neighbor_report_cb(struct netdev *netdev, int err, station_roam_failed(station); } -static void station_roam_trigger_cb(struct l_timeout *timeout, void *user_data) +static void station_start_roam(struct station *station) { - struct station *station = user_data; int r; - l_debug("%u", netdev_get_ifindex(station->netdev)); - - l_timeout_remove(station->roam_trigger_timeout); - station->roam_trigger_timeout = NULL; station->preparing_roam = true; /* @@ -2577,6 +2572,18 @@ static void station_roam_trigger_cb(struct l_timeout *timeout, void *user_data) station_roam_failed(station); } +static void station_roam_trigger_cb(struct l_timeout *timeout, void *user_data) +{ + struct station *station = user_data; + + l_debug("%u", netdev_get_ifindex(station->netdev)); + + l_timeout_remove(station->roam_trigger_timeout); + station->roam_trigger_timeout = NULL; + + station_start_roam(station); +} + static void station_roam_timeout_rearm(struct station *station, int seconds) { struct timespec now, min_timeout; @@ -3057,6 +3064,23 @@ static void station_disconnect_event(struct station *station, void *event_data) l_warn("Unexpected disconnect event"); } +#define STATION_PKT_LOSS_THRESHOLD 10 + +static void station_packets_lost(struct station *station, uint32_t num_pkts) +{ + l_debug("Packets lost event: %u", num_pkts); + + if (num_pkts < STATION_PKT_LOSS_THRESHOLD) + return; + + if (station_cannot_roam(station)) + return; + + station_debug_event(station, "packet-loss-roam"); + + station_start_roam(station); +} + static void station_netdev_event(struct netdev *netdev, enum netdev_event event, void *event_data, void *user_data) { @@ -3092,6 +3116,9 @@ static void station_netdev_event(struct netdev *netdev, enum netdev_event event, case NETDEV_EVENT_CHANNEL_SWITCHED: station_event_channel_switched(station, l_get_u32(event_data)); break; + case NETDEV_EVENT_PACKET_LOSS_NOTIFY: + station_packets_lost(station, l_get_u32(event_data)); + break; } }