From c6456dd104b204a44e2964a7cf443efb87d4661d Mon Sep 17 00:00:00 2001 From: Andrew Zaborowski Date: Wed, 14 Oct 2020 02:25:45 +0200 Subject: [PATCH] platform/wifi: Read frequency from NL80211_CMD_GET_INTERFACE As an optimization, implement wifi_nl80211_get_freq() using the GET_INTERFACE nl8022 command instead of the GET_SCAN dump. The GET_SCAN dump can be over 10kB of data that the kernel has to build and we have to parse. Additionally the GET_SCAN dump is not guaranteed to contain the currently-connected BSS if there was no recent scan (30s), or if the recent scan missed the beacon from the current BSS, or if the recent scan was for a subset of channels/SSIDs/BSSIDs etc. and the last full scan was already flushed. Scan results are flushed after (I think) 30 seconds or if a new scan has the flush flag set. In IWD we do occasionally do partial scans (on a subset of channels or for a specific SSID) with the flush flag. In that case the previous wifi_nl80211_get_freq() logic would probably return 0. --- src/platform/wifi/nm-wifi-utils-nl80211.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/platform/wifi/nm-wifi-utils-nl80211.c b/src/platform/wifi/nm-wifi-utils-nl80211.c index dddfa8fafb..cad291b47a 100644 --- a/src/platform/wifi/nm-wifi-utils-nl80211.c +++ b/src/platform/wifi/nm-wifi-utils-nl80211.c @@ -163,6 +163,7 @@ dispose(GObject *object) struct nl80211_iface_info { NM80211Mode mode; + uint32_t freq; }; static int @@ -193,6 +194,9 @@ nl80211_iface_info_handler(struct nl_msg *msg, void *arg) break; } + if (tb[NL80211_ATTR_WIPHY_FREQ] != NULL) + info->freq = nla_get_u32(tb[NL80211_ATTR_WIPHY_FREQ]); + return NL_SKIP; } @@ -489,12 +493,16 @@ nl80211_get_bss_info(NMWifiUtilsNl80211 *self, struct nl80211_bss_info *bss_info static guint32 wifi_nl80211_get_freq(NMWifiUtils *data) { - NMWifiUtilsNl80211 * self = (NMWifiUtilsNl80211 *) data; - struct nl80211_bss_info bss_info; + NMWifiUtilsNl80211 * self = (NMWifiUtilsNl80211 *) data; + struct nl80211_iface_info iface_info = {}; + nm_auto_nlmsg struct nl_msg *msg = NULL; - nl80211_get_bss_info(self, &bss_info); + msg = nl80211_alloc_msg(self, NL80211_CMD_GET_INTERFACE, 0); - return bss_info.freq; + if (nl80211_send_and_recv(self, msg, nl80211_iface_info_handler, &iface_info) < 0) + return 0; + + return iface_info.freq; } static guint32