From 5eb0b7ca8e04f1ada3b0920efd4fddd06894acf7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alvin=20=C5=A0ipraga?= Date: Thu, 27 May 2021 16:22:28 +0200 Subject: [PATCH] netdev: add a channel switch event If the connected BSS announces that it is switching operating channel, the kernel may emit the NL80211_CMD_CH_SWTICH_NOTIFY event when the switch is complete. Add a new netdev event NETDEV_EVENT_CHANNEL_SWITCHED to signal to interested modules that the connected BSS has changed channel. The event carries a pointer to the new channel's frequency. --- src/netdev.c | 39 +++++++++++++++++++++++++++++++++++++++ src/netdev.h | 1 + 2 files changed, 40 insertions(+) diff --git a/src/netdev.c b/src/netdev.c index 9a2afe1d..5ad57e6f 100644 --- a/src/netdev.c +++ b/src/netdev.c @@ -4536,6 +4536,42 @@ failed: } +static void netdev_channel_switch_event(struct l_genl_msg *msg, + struct netdev *netdev) +{ + struct l_genl_attr attr; + uint16_t type, len; + const void *data; + uint32_t *freq = NULL; + + l_debug(""); + + if (!l_genl_attr_init(&attr, msg)) + return; + + while (l_genl_attr_next(&attr, &type, &len, &data)) { + switch (type) { + case NL80211_ATTR_WIPHY_FREQ: + if (len != 4) + continue; + + freq = (uint32_t *) data; + break; + } + } + + if (!freq) + return; + + l_debug("Channel switch event, frequency: %u", *freq); + + if (!netdev->event_filter) + return; + + netdev->event_filter(netdev, NETDEV_EVENT_CHANNEL_SWITCHED, freq, + netdev->user_data); +} + static void netdev_mlme_notify(struct l_genl_msg *msg, void *user_data) { struct netdev *netdev = NULL; @@ -4561,6 +4597,9 @@ static void netdev_mlme_notify(struct l_genl_msg *msg, void *user_data) case NL80211_CMD_ROAM: netdev_roam_event(msg, netdev); break; + case NL80211_CMD_CH_SWITCH_NOTIFY: + netdev_channel_switch_event(msg, netdev); + break; case NL80211_CMD_CONNECT: netdev_connect_event(msg, netdev); break; diff --git a/src/netdev.h b/src/netdev.h index f625957b..ee944bce 100644 --- a/src/netdev.h +++ b/src/netdev.h @@ -43,6 +43,7 @@ enum netdev_event { NETDEV_EVENT_ASSOCIATING, NETDEV_EVENT_ROAMING, NETDEV_EVENT_ROAMED, + NETDEV_EVENT_CHANNEL_SWITCHED, NETDEV_EVENT_DISCONNECT_BY_AP, NETDEV_EVENT_DISCONNECT_BY_SME, NETDEV_EVENT_RSSI_THRESHOLD_LOW,