diff --git NetworkManager/src/nm-device-ethernet.c NetworkManager/src/nm-device-ethernet.c index d1df23e..b5232e4 100644 --- NetworkManager/src/nm-device-ethernet.c +++ NetworkManager/src/nm-device-ethernet.c @@ -697,7 +697,7 @@ supplicant_interface_clean (NMDeviceEthernet *self) } if (priv->supplicant.iface) { - nm_supplicant_interface_disconnect (priv->supplicant.iface); + nm_supplicant_interface_disconnect_sync (priv->supplicant.iface); nm_supplicant_manager_release_iface (priv->supplicant.mgr, priv->supplicant.iface); priv->supplicant.iface = NULL; } diff --git NetworkManager/src/nm-device-wifi.c NetworkManager/src/nm-device-wifi.c index 413fe33..24a0ce9 100644 --- NetworkManager/src/nm-device-wifi.c +++ NetworkManager/src/nm-device-wifi.c @@ -630,7 +630,7 @@ supplicant_interface_release (NMDeviceWifi *self) if (priv->supplicant.iface) { /* Tell the supplicant to disconnect from the current AP */ - nm_supplicant_interface_disconnect (priv->supplicant.iface); + nm_supplicant_interface_disconnect_sync (priv->supplicant.iface); nm_supplicant_manager_release_iface (priv->supplicant.mgr, priv->supplicant.iface); priv->supplicant.iface = NULL; @@ -1967,7 +1967,7 @@ cleanup_association_attempt (NMDeviceWifi *self, gboolean disconnect) remove_supplicant_interface_connection_error_handler (self); remove_supplicant_timeouts (self); if (disconnect && priv->supplicant.iface) - nm_supplicant_interface_disconnect (priv->supplicant.iface); + nm_supplicant_interface_disconnect_sync (priv->supplicant.iface); } diff --git NetworkManager/src/supplicant-manager/nm-supplicant-interface.c NetworkManager/src/supplicant-manager/nm-supplicant-interface.c index 43cd167..c66ca42 100644 --- NetworkManager/src/supplicant-manager/nm-supplicant-interface.c +++ NetworkManager/src/supplicant-manager/nm-supplicant-interface.c @@ -968,6 +968,70 @@ nm_supplicant_interface_disconnect (NMSupplicantInterface * self) nm_supplicant_info_set_call (info, call); } +void +nm_supplicant_interface_disconnect_sync (NMSupplicantInterface * self) +{ + NMSupplicantInterfacePrivate *priv; + GError *err = NULL; + guint tmp; + + g_return_if_fail (NM_IS_SUPPLICANT_INTERFACE (self)); + + priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self); + + /* Clear and cancel all pending calls related to a prior + * connection attempt. + */ + cancel_all_callbacks (priv->assoc_pcalls); + + /* Don't do anything if there is no connection to the supplicant yet. */ + if (!priv->iface_proxy) + return; + + /* Don't try to disconnect if the supplicant interface is already + * disconnected. + */ + if (priv->con_state == NM_SUPPLICANT_INTERFACE_CON_STATE_DISCONNECTED + || priv->con_state == NM_SUPPLICANT_INTERFACE_CON_STATE_INACTIVE) { + if (priv->net_proxy) { + g_object_unref (priv->net_proxy); + priv->net_proxy = NULL; + } + + return; + } + + /* Remove any network that was added by NetworkManager */ + if (priv->net_proxy) + { + if (!dbus_g_proxy_call (priv->iface_proxy, "removeNetwork", + &err, + DBUS_TYPE_G_OBJECT_PATH, dbus_g_proxy_get_path (priv->net_proxy), + G_TYPE_INVALID, + G_TYPE_UINT, &tmp, + G_TYPE_INVALID)) + { + nm_warning ("Couldn't remove network from supplicant interface: %s.", err->message); + g_error_free (err); + err = NULL; + } + + g_object_unref (priv->net_proxy); + priv->net_proxy = NULL; + } + + if (!dbus_g_proxy_call (priv->iface_proxy, "disconnect", + &err, + G_TYPE_INVALID, + G_TYPE_UINT, &tmp, + G_TYPE_INVALID)) + { + nm_warning ("Couldn't disconnect supplicant interface: %s.", err->message); + g_error_free (err); + err = NULL; + } +} + static void select_network_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) { diff --git NetworkManager/src/supplicant-manager/nm-supplicant-interface.h NetworkManager/src/supplicant-manager/nm-supplicant-interface.h index f68c238..94cda7c 100644 --- NetworkManager/src/supplicant-manager/nm-supplicant-interface.h +++ NetworkManager/src/supplicant-manager/nm-supplicant-interface.h @@ -115,6 +115,7 @@ gboolean nm_supplicant_interface_set_config (NMSupplicantInterface * iface, NMSupplicantConfig * cfg); void nm_supplicant_interface_disconnect (NMSupplicantInterface * iface); +void nm_supplicant_interface_disconnect_sync (NMSupplicantInterface * iface); const char * nm_supplicant_interface_get_device (NMSupplicantInterface * iface);