Backport of https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/640 --- a/src/devices/wifi/nm-device-iwd.c +++ b/src/devices/wifi/nm-device-iwd.c @@ -1905,38 +1905,39 @@ schedule_periodic_scan (NMDeviceIwd *self, gboolean initial_scan) { NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE (self); GVariant *value; - gboolean disconnected; + gboolean disconnected = TRUE; guint interval; - if (!priv->can_scan || priv->scan_requested) - return; - - value = g_dbus_proxy_get_cached_property (priv->dbus_station_proxy, "State"); - disconnected = nm_streq0 (get_variant_state (value), "disconnected"); - g_variant_unref (value); + if (priv->can_scan) { + value = g_dbus_proxy_get_cached_property (priv->dbus_station_proxy, "State"); + disconnected = nm_streq0 (get_variant_state (value), "disconnected"); + g_variant_unref (value); + } /* Start scan immediately after a disconnect, mode change or - * device UP, otherwise wait a period dependent on the current - * state. + * device UP, otherwise wait 10 seconds. When connected, update + * AP list mainly on UI requests. * * (initial_scan && disconnected) override priv->scanning below * because of an IWD quirk where a device will often be in the * autoconnect state and scanning at the time of our initial_scan, - * but our logic will the send it a Disconnect() causeing IWD to + * but our logic will then send it a Disconnect() causing IWD to * exit autoconnect and interrupt the ongoing scan, meaning that * we still want a new scan ASAP. */ - if (initial_scan && disconnected) + if (!priv->can_scan || !disconnected || priv->scan_requested || priv->scanning) + interval = -1; + else if (initial_scan) interval = 0; - else if (!priv->periodic_scan_id && !priv->scanning) - interval = disconnected ? 10 : 20; + else if (!priv->periodic_scan_id) + interval = 10; else return; nm_clear_g_source (&priv->periodic_scan_id); - priv->periodic_scan_id = g_timeout_add_seconds (interval, - periodic_scan_timeout_cb, - self); + + if (interval != (guint) -1) + priv->periodic_scan_id = g_timeout_add_seconds (interval, periodic_scan_timeout_cb, self); } static void @@ -2331,7 +2332,6 @@ powered_changed (NMDeviceIwd *self, gboolean new_powered) update_aps (self); } else { set_can_scan (self, FALSE); - nm_clear_g_source (&priv->periodic_scan_id); priv->scanning = FALSE; priv->scan_requested = FALSE; priv->can_connect = FALSE; @@ -2537,17 +2537,7 @@ dispose (GObject *object) nm_clear_g_cancellable (&priv->cancellable); - nm_clear_g_source (&priv->periodic_scan_id); - - cleanup_association_attempt (self, TRUE); - - g_clear_object (&priv->dbus_device_proxy); - g_clear_object (&priv->dbus_station_proxy); - g_clear_object (&priv->dbus_ap_proxy); - g_clear_object (&priv->dbus_adhoc_proxy); - g_clear_object (&priv->dbus_obj); - - remove_all_aps (self); + nm_device_iwd_set_dbus_object(self, NULL); G_OBJECT_CLASS (nm_device_iwd_parent_class)->dispose (object); --- a/src/devices/wifi/nm-iwd-manager.c +++ b/src/devices/wifi/nm-iwd-manager.c @@ -622,6 +622,38 @@ interface_removed (GDBusObjectManager *object_manager, GDBusObject *object, } } +static void +object_added(GDBusObjectManager *object_manager, GDBusObject *object, gpointer user_data) +{ + GList *interfaces, *iter; + + interfaces = g_dbus_object_get_interfaces(object); + + for (iter = interfaces; iter; iter = iter->next) { + GDBusInterface *interface = G_DBUS_INTERFACE(iter->data); + + interface_added(NULL, object, interface, user_data); + } + + g_list_free_full(interfaces, g_object_unref); +} + +static void +object_removed(GDBusObjectManager *object_manager, GDBusObject *object, gpointer user_data) +{ + GList *interfaces, *iter; + + interfaces = g_dbus_object_get_interfaces(object); + + for (iter = interfaces; iter; iter = iter->next) { + GDBusInterface *interface = G_DBUS_INTERFACE(iter->data); + + interface_removed(NULL, object, interface, user_data); + } + + g_list_free_full(interfaces, g_object_unref); +} + static void connection_removed (NMSettings *settings, NMSettingsConnection *sett_conn, @@ -682,22 +714,6 @@ _om_has_name_owner (GDBusObjectManager *object_manager) return !!name_owner; } -static void -object_added (NMIwdManager *self, GDBusObject *object) -{ - GList *interfaces, *iter; - - interfaces = g_dbus_object_get_interfaces (object); - - for (iter = interfaces; iter; iter = iter->next) { - GDBusInterface *interface = G_DBUS_INTERFACE (iter->data); - - interface_added (NULL, object, interface, self); - } - - g_list_free_full (interfaces, g_object_unref); -} - static void release_object_manager (NMIwdManager *self) { @@ -836,12 +852,16 @@ got_object_manager (GObject *object, GAsyncResult *result, gpointer user_data) G_CALLBACK (interface_added), self); g_signal_connect (priv->object_manager, "interface-removed", G_CALLBACK (interface_removed), self); + g_signal_connect (priv->object_manager, "object-added", + G_CALLBACK(object_added), self); + g_signal_connect (priv->object_manager, "object-removed", + G_CALLBACK(object_removed), self); g_hash_table_remove_all (priv->known_networks); objects = g_dbus_object_manager_get_objects (object_manager); for (iter = objects; iter; iter = iter->next) - object_added (self, G_DBUS_OBJECT (iter->data)); + object_added (NULL, G_DBUS_OBJECT(iter->data), self); g_list_free_full (objects, g_object_unref);