2014-07-20 Bernd Edlinger Fix WiFi connectivity problems. * nm-device-wifi.c (WPAS_REMOVED_TAG): Moved upwards. (merge_scanned_ap): Clear removed tag. (supplicant_iface_bss_updated_cb): Remove type cast. (supplicant_iface_bss_removed_cb): Update time stamp. (link_timeout_cb): Only remove fake APs. * nm-wifi-ap.c (nm_ap_new_from_properties): Remove type cast. --- network-manager-0.9.8.8.orig/src/nm-device-wifi.c 2014-07-18 20:14:41.000000000 +0200 +++ network-manager-0.9.8.8/src/nm-device-wifi.c 2014-07-20 16:17:49.625331209 +0200 @@ -1825,6 +1825,7 @@ supplicant_iface_scan_done_cb (NMSupplic #define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x" #define MAC_ARG(x) ((guint8*)(x))[0],((guint8*)(x))[1],((guint8*)(x))[2],((guint8*)(x))[3],((guint8*)(x))[4],((guint8*)(x))[5] +#define WPAS_REMOVED_TAG "supplicant-removed" /* * merge_scanned_ap @@ -1907,6 +1908,7 @@ merge_scanned_ap (NMDeviceWifi *self, * fake, since it clearly exists somewhere. */ nm_ap_set_fake (found_ap, FALSE); + g_object_set_data (G_OBJECT (found_ap), WPAS_REMOVED_TAG, NULL); } else { /* New entry in the list */ nm_log_dbg (LOGD_WIFI_SCAN, "(%s): adding new AP '%s' " MAC_FMT " (%p)", @@ -1923,8 +1925,6 @@ merge_scanned_ap (NMDeviceWifi *self, } } -#define WPAS_REMOVED_TAG "supplicant-removed" - static gboolean cull_scan_list (NMDeviceWifi *self) { @@ -2067,7 +2067,7 @@ supplicant_iface_bss_updated_cb (NMSuppl /* Update the AP's last-seen property */ ap = get_ap_by_supplicant_path (self, object_path); if (ap) - nm_ap_set_last_seen (ap, (guint32) time (NULL)); + nm_ap_set_last_seen (ap, time (NULL)); /* Remove outdated access points */ schedule_scanlist_cull (self); @@ -2084,8 +2084,22 @@ supplicant_iface_bss_removed_cb (NMSuppl g_return_if_fail (object_path != NULL); ap = get_ap_by_supplicant_path (self, object_path); - if (ap) + if (ap) { + glong now = time (NULL); + glong last_seen = nm_ap_get_last_seen (ap); + + /* We don't know when the supplicant last saw the AP's beacons, + * it could be two minutes or it could be 2 seconds. Because the + * supplicant doesn't send property change notifications if the + * AP's other properties don't change, our last-seen time may be + * much older the supplicant's, and the AP would be immediately + * removed from the list on the next cleanup. So update the + * last-seen time to ensure the AP sticks around for at least + * one more periodic scan. + */ + nm_ap_set_last_seen (ap, MAX (last_seen, now - SCAN_INTERVAL_MAX)); g_object_set_data (G_OBJECT (ap), WPAS_REMOVED_TAG, GUINT_TO_POINTER (TRUE)); + } } @@ -2174,7 +2188,7 @@ link_timeout_cb (gpointer user_data) } else ap = nm_device_wifi_get_activation_ap (self); - if (ap) + if (ap && nm_ap_get_fake (ap)) remove_access_point (self, ap); } --- network-manager-0.9.8.8.orig/src/nm-wifi-ap.c 2014-07-18 20:14:41.000000000 +0200 +++ network-manager-0.9.8.8/src/nm-wifi-ap.c 2014-07-25 09:22:06.999779676 +0200 @@ -531,7 +531,7 @@ nm_ap_new_from_properties (const char *s return NULL; } - nm_ap_set_last_seen (ap, (guint32) time (NULL)); + nm_ap_set_last_seen (ap, time (NULL)); if (!nm_ap_get_ssid (ap)) nm_ap_set_broadcast (ap, FALSE);