2014-07-20  Bernd Edlinger  <bernd.edlinger@hotmail.de>

	Fix WiFi connectivity problems.
	* nm-device-wifi.c (WPAS_REMOVED_TAG): Moved upwards.
	(merge_scanned_ap): Clear removed tag.
	(supplicant_iface_bss_removed_cb): Update time stamp.
	(link_timeout_cb): Only remove fake APs.

--- 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-19 22:21:08.735903297 +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)
 {
@@ -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) {
+		gint32 now = (gint32) time (NULL);
+		gint32 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);
 	}
 
