diff options
author | Dan Williams <dcbw@redhat.com> | 2015-04-06 13:37:22 -0500 |
---|---|---|
committer | Dan Williams <dcbw@redhat.com> | 2015-04-10 10:17:45 -0500 |
commit | fbf60536f925b22719499e7cd9b057812bf63f36 (patch) | |
tree | d87301860f05b14141346fb67a899f9e3d008549 | |
parent | 227de48a910f1708ba6275fa5a256824b3bb07ab (diff) | |
download | NetworkManager-fbf60536f925b22719499e7cd9b057812bf63f36.tar.gz |
wifi: fall back to band matching when frequency matching failsdcbw/supplicant-current-ap-bgo747424
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.
-rw-r--r-- | src/devices/wifi/nm-wifi-ap.c | 40 |
1 files 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; } |