From fbf60536f925b22719499e7cd9b057812bf63f36 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Mon, 6 Apr 2015 13:37:22 -0500 Subject: [PATCH] wifi: fall back to band matching when frequency matching fails Some dual-band access points use the same BSSID in both the 5GHz and 2.4GHz bands, so obviously frequency must be taken into account when matching. But no AP should ever use the same SSID/BSSID pair concurrently in the same band on different frequencies. Some APs also dynamically channel hop when they detect interference, or when they restart, they do so on a different channel after finding the channel with the lowest interference. To assure that we don't end up with stale scan list entries when the AP has switched to another channel in the same band, fall back to band matching when merging new scan results. --- src/devices/wifi/nm-wifi-ap.c | 40 +++++++++++++++++++++++------------ 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/src/devices/wifi/nm-wifi-ap.c b/src/devices/wifi/nm-wifi-ap.c index 91b3bcb355..0519784c12 100644 --- a/src/devices/wifi/nm-wifi-ap.c +++ b/src/devices/wifi/nm-wifi-ap.c @@ -1067,6 +1067,16 @@ nm_ap_set_last_seen (NMAccessPoint *ap, gint32 last_seen) NM_AP_GET_PRIVATE (ap)->last_seen = last_seen; } +static guint +freq_to_band (guint32 freq) +{ + if (freq >= 4915 && freq <= 5825) + return 5; + else if (freq >= 2412 && freq <= 2484) + return 2; + return 0; +} + gboolean nm_ap_check_compatible (NMAccessPoint *self, NMConnection *connection) @@ -1117,13 +1127,12 @@ nm_ap_check_compatible (NMAccessPoint *self, band = nm_setting_wireless_get_band (s_wireless); if (band) { - if (!strcmp (band, "a")) { - if (priv->freq < 4915 || priv->freq > 5825) - return FALSE; - } else if (!strcmp (band, "bg")) { - if (priv->freq < 2412 || priv->freq > 2484) - return FALSE; - } + guint ap_band = freq_to_band (priv->freq); + + if (!strcmp (band, "a") && ap_band != 5) + return FALSE; + else if (!strcmp (band, "bg") && ap_band != 2) + return FALSE; } channel = nm_setting_wireless_get_channel (s_wireless); @@ -1169,7 +1178,7 @@ NMAccessPoint * nm_ap_match_in_hash (NMAccessPoint *find_ap, GHashTable *hash) { GHashTableIter iter; - NMAccessPoint *list_ap; + NMAccessPoint *list_ap, *band_match = NULL; g_return_val_if_fail (find_ap != NULL, NULL); @@ -1177,9 +1186,11 @@ nm_ap_match_in_hash (NMAccessPoint *find_ap, GHashTable *hash) while (g_hash_table_iter_next (&iter, NULL, (gpointer) &list_ap)) { const GByteArray * list_ssid = nm_ap_get_ssid (list_ap); const char * list_addr = nm_ap_get_address (list_ap); + const guint32 list_freq = nm_ap_get_freq (list_ap); const GByteArray * find_ssid = nm_ap_get_ssid (find_ap); const char * find_addr = nm_ap_get_address (find_ap); + const guint32 find_freq = nm_ap_get_freq (find_ap); /* SSID match; if both APs are hiding their SSIDs, * let matching continue on BSSID and other properties @@ -1203,10 +1214,6 @@ nm_ap_match_in_hash (NMAccessPoint *find_ap, GHashTable *hash) if (nm_ap_get_mode (list_ap) != nm_ap_get_mode (find_ap)) continue; - /* Frequency match */ - if (nm_ap_get_freq (list_ap) != nm_ap_get_freq (find_ap)) - continue; - /* AP flags */ if (nm_ap_get_flags (list_ap) != nm_ap_get_flags (find_ap)) continue; @@ -1217,9 +1224,16 @@ nm_ap_match_in_hash (NMAccessPoint *find_ap, GHashTable *hash) if (nm_ap_get_rsn_flags (list_ap) != nm_ap_get_rsn_flags (find_ap)) continue; + if (list_freq != find_freq) { + /* Must be last check to ensure all other properties match */ + if (freq_to_band (list_freq) == freq_to_band (find_freq)) + band_match = list_ap; + continue; + } + return list_ap; } - return NULL; + return band_match; }