Commit 836f7d17 authored by Dan Williams's avatar Dan Williams
Browse files

wifi: fix removal of APs from the scan list when it doesn't change

Due to an omission in the port to the new supplicant D-Bus API
during the 0.9 cycle, if the scan list didn't change, APs may
not have been removed properly from the scan list.
parent 4f166d71
...@@ -141,6 +141,7 @@ struct _NMDeviceWifiPrivate { ...@@ -141,6 +141,7 @@ struct _NMDeviceWifiPrivate {
glong scheduled_scan_time; glong scheduled_scan_time;
guint8 scan_interval; /* seconds */ guint8 scan_interval; /* seconds */
guint pending_scan_id; guint pending_scan_id;
guint scanlist_cull_id;
Supplicant supplicant; Supplicant supplicant;
WifiData * wifi_data; WifiData * wifi_data;
...@@ -180,7 +181,7 @@ static void supplicant_iface_notify_scanning_cb (NMSupplicantInterface * iface, ...@@ -180,7 +181,7 @@ static void supplicant_iface_notify_scanning_cb (NMSupplicantInterface * iface,
GParamSpec * pspec, GParamSpec * pspec,
NMDeviceWifi * self); NMDeviceWifi * self);
static void cull_scan_list (NMDeviceWifi *self); static void schedule_scanlist_cull (NMDeviceWifi *self);
/*****************************************************************/ /*****************************************************************/
...@@ -418,6 +419,11 @@ supplicant_interface_release (NMDeviceWifi *self) ...@@ -418,6 +419,11 @@ supplicant_interface_release (NMDeviceWifi *self)
} }
memset (priv->supplicant.sig_ids, 0, sizeof (priv->supplicant.sig_ids)); memset (priv->supplicant.sig_ids, 0, sizeof (priv->supplicant.sig_ids));
if (priv->scanlist_cull_id) {
g_source_remove (priv->scanlist_cull_id);
priv->scanlist_cull_id = 0;
}
if (priv->supplicant.iface) { if (priv->supplicant.iface) {
/* Tell the supplicant to disconnect from the current AP */ /* Tell the supplicant to disconnect from the current AP */
nm_supplicant_interface_disconnect (priv->supplicant.iface); nm_supplicant_interface_disconnect (priv->supplicant.iface);
...@@ -1555,15 +1561,10 @@ supplicant_iface_scan_done_cb (NMSupplicantInterface *iface, ...@@ -1555,15 +1561,10 @@ supplicant_iface_scan_done_cb (NMSupplicantInterface *iface,
if (check_scanning_allowed (self)) if (check_scanning_allowed (self))
schedule_scan (self, TRUE); schedule_scan (self, TRUE);
#if 0 /* Ensure that old APs get removed, which otherwise only
if (num_results == 0) { * happens when there are new BSSes.
/* ensure that old APs get culled, which otherwise only */
* happens when there are actual scan results to process. schedule_scanlist_cull (self);
*/
cull_scan_list (self);
ap_list_dump (self);
}
#endif
} }
...@@ -1670,25 +1671,16 @@ merge_scanned_ap (NMDeviceWifi *self, ...@@ -1670,25 +1671,16 @@ merge_scanned_ap (NMDeviceWifi *self,
} }
} }
static void static gboolean
cull_scan_list (NMDeviceWifi *self) cull_scan_list (NMDeviceWifi *self)
{ {
NMDeviceWifiPrivate *priv; NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
GTimeVal cur_time; GTimeVal now;
GSList *outdated_list = NULL; GSList *outdated_list = NULL;
GSList *elt; GSList *elt;
NMActRequest *req;
const char *cur_ap_path = NULL;
guint32 removed = 0, total = 0; guint32 removed = 0, total = 0;
g_return_if_fail (self != NULL); priv->scanlist_cull_id = 0;
priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
g_get_current_time (&cur_time);
req = nm_device_get_act_request (NM_DEVICE (self));
if (req)
cur_ap_path = nm_active_connection_get_specific_object (NM_ACTIVE_CONNECTION (req));
nm_log_dbg (LOGD_WIFI_SCAN, "(%s): checking scan list for outdated APs", nm_log_dbg (LOGD_WIFI_SCAN, "(%s): checking scan list for outdated APs",
nm_device_get_iface (NM_DEVICE (self))); nm_device_get_iface (NM_DEVICE (self)));
...@@ -1696,19 +1688,16 @@ cull_scan_list (NMDeviceWifi *self) ...@@ -1696,19 +1688,16 @@ cull_scan_list (NMDeviceWifi *self)
/* Walk the access point list and remove any access points older than /* Walk the access point list and remove any access points older than
* three times the inactive scan interval. * three times the inactive scan interval.
*/ */
g_get_current_time (&now);
for (elt = priv->ap_list; elt; elt = g_slist_next (elt), total++) { for (elt = priv->ap_list; elt; elt = g_slist_next (elt), total++) {
NMAccessPoint * ap = NM_AP (elt->data); NMAccessPoint *ap = elt->data;
const glong ap_time = nm_ap_get_last_seen (ap); const guint prune_interval_s = SCAN_INTERVAL_MAX * 3;
gboolean keep = FALSE;
const guint prune_interval_s = SCAN_INTERVAL_MAX * 3;
/* Don't ever prune the AP we're currently associated with */ /* Don't cull the associated AP or manually created APs */
if (cur_ap_path && !strcmp (cur_ap_path, nm_ap_get_dbus_path (ap))) if (ap == priv->current_ap || nm_ap_get_fake (ap))
keep = TRUE; continue;
if (nm_ap_get_fake (ap))
keep = TRUE;
if (!keep && (ap_time + prune_interval_s < cur_time.tv_sec)) if (nm_ap_get_last_seen (ap) + prune_interval_s < now.tv_sec)
outdated_list = g_slist_append (outdated_list, ap); outdated_list = g_slist_append (outdated_list, ap);
} }
...@@ -1739,6 +1728,21 @@ cull_scan_list (NMDeviceWifi *self) ...@@ -1739,6 +1728,21 @@ cull_scan_list (NMDeviceWifi *self)
nm_log_dbg (LOGD_WIFI_SCAN, "(%s): removed %d APs (of %d)", nm_log_dbg (LOGD_WIFI_SCAN, "(%s): removed %d APs (of %d)",
nm_device_get_iface (NM_DEVICE (self)), nm_device_get_iface (NM_DEVICE (self)),
removed, total); removed, total);
ap_list_dump (self);
return FALSE;
}
static void
schedule_scanlist_cull (NMDeviceWifi *self)
{
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
/* Cull the scan list after the last request for it has come in */
if (priv->scanlist_cull_id)
g_source_remove (priv->scanlist_cull_id);
priv->scanlist_cull_id = g_timeout_add_seconds (4, (GSourceFunc) cull_scan_list, self);
} }
static void static void
...@@ -1765,15 +1769,13 @@ supplicant_iface_new_bss_cb (NMSupplicantInterface *iface, ...@@ -1765,15 +1769,13 @@ supplicant_iface_new_bss_cb (NMSupplicantInterface *iface,
/* Add the AP to the device's AP list */ /* Add the AP to the device's AP list */
merge_scanned_ap (self, ap); merge_scanned_ap (self, ap);
g_object_unref (ap); g_object_unref (ap);
/* Remove outdated access points */
cull_scan_list (self);
ap_list_dump (self);
} else { } else {
nm_log_warn (LOGD_WIFI_SCAN, "(%s): invalid AP properties received", nm_log_warn (LOGD_WIFI_SCAN, "(%s): invalid AP properties received",
nm_device_get_iface (NM_DEVICE (self))); nm_device_get_iface (NM_DEVICE (self)));
} }
/* Remove outdated access points */
schedule_scanlist_cull (self);
} }
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment