static void
interface_get_cb (GDBusProxy *proxy, GAsyncResult *result, gpointer user_data)
{
	NMSupplicantInterface *self;
	NMSupplicantInterfacePrivate *priv;
	gs_unref_variant GVariant *variant = NULL;
	gs_free_error GError *error = NULL;
	const char *path;

	variant = _nm_dbus_proxy_call_finish (proxy, result,
	                                      G_VARIANT_TYPE ("(o)"),
	                                      &error);
	if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
		return;

	self = NM_SUPPLICANT_INTERFACE (user_data);
	priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);

	if (variant) {
		g_variant_get (variant, "(&o)", &path);
		interface_add_done (self, path);
	} else {
		g_dbus_error_strip_remote_error (error);
		nm_log_err (LOGD_SUPPLICANT, "(%s): error getting interface: %s", priv->dev, error->message);
		set_state (self, NM_SUPPLICANT_INTERFACE_STATE_DOWN);
	}
}
static void
interface_add_cb (GDBusProxy *proxy, GAsyncResult *result, gpointer user_data)
{
	NMSupplicantInterface *self;
	NMSupplicantInterfacePrivate *priv;
	gs_free_error GError *error = NULL;
	gs_unref_variant GVariant *variant = NULL;
	const char *path;

	variant = _nm_dbus_proxy_call_finish (proxy, result,
	                                      G_VARIANT_TYPE ("(o)"),
	                                      &error);
	if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
		return;

	self = NM_SUPPLICANT_INTERFACE (user_data);
	priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);

	if (variant) {
		g_variant_get (variant, "(&o)", &path);
		interface_add_done (self, path);
	} else if (_nm_dbus_error_has_name (error, WPAS_ERROR_EXISTS_ERROR)) {
		/* Interface already added, just get its object path */
		g_dbus_proxy_call (priv->wpas_proxy,
		                   "GetInterface",
		                   g_variant_new ("(s)", priv->dev),
		                   G_DBUS_CALL_FLAGS_NONE,
		                   -1,
		                   priv->init_cancellable,
		                   (GAsyncReadyCallback) interface_get_cb,
		                   self);
	} else if (   g_error_matches (error, G_DBUS_ERROR, G_DBUS_ERROR_SERVICE_UNKNOWN)
	           || g_error_matches (error, G_DBUS_ERROR, G_DBUS_ERROR_SPAWN_EXEC_FAILED)
	           || g_error_matches (error, G_DBUS_ERROR, G_DBUS_ERROR_SPAWN_FORK_FAILED)
	           || g_error_matches (error, G_DBUS_ERROR, G_DBUS_ERROR_SPAWN_FAILED)
	           || g_error_matches (error, G_DBUS_ERROR, G_DBUS_ERROR_TIMEOUT)
	           || g_error_matches (error, G_DBUS_ERROR, G_DBUS_ERROR_NO_REPLY)
	           || g_error_matches (error, G_DBUS_ERROR, G_DBUS_ERROR_TIMED_OUT)
	           || g_error_matches (error, G_DBUS_ERROR, G_DBUS_ERROR_SPAWN_SERVICE_NOT_FOUND)) {
		/* Supplicant wasn't running and could not be launched via service
		 * activation.  Wait for it to start by moving back to the INIT
		 * state.
		 */
		g_dbus_error_strip_remote_error (error);
		nm_log_dbg (LOGD_SUPPLICANT, "(%s): failed to activate supplicant: %s",
		            priv->dev, error->message);
		set_state (self, NM_SUPPLICANT_INTERFACE_STATE_INIT);
	} else {
		g_dbus_error_strip_remote_error (error);
		nm_log_err (LOGD_SUPPLICANT, "(%s): error adding interface: %s", priv->dev, error->message);
		set_state (self, NM_SUPPLICANT_INTERFACE_STATE_DOWN);
	}
}
static void
interface_get_cb (DBusGProxy *proxy,
                  DBusGProxyCall *call_id,
                  gpointer user_data)
{
	NMSupplicantInfo *info = (NMSupplicantInfo *) user_data;
	NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (info->interface);
	GError *error = NULL;
	char *path = NULL;

	if (dbus_g_proxy_end_call (proxy, call_id, &error,
	                           DBUS_TYPE_G_OBJECT_PATH, &path,
	                           G_TYPE_INVALID)) {
		interface_add_done (info->interface, path);
	} else {
		nm_log_err (LOGD_SUPPLICANT, "(%s): error getting interface: %s",
		            priv->dev, error->message);
		g_clear_error (&error);
		set_state (info->interface, NM_SUPPLICANT_INTERFACE_STATE_DOWN);
	}
}
static void
interface_add_cb (DBusGProxy *proxy,
                  DBusGProxyCall *call_id,
                  gpointer user_data)
{
	NMSupplicantInfo *info = (NMSupplicantInfo *) user_data;
	NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (info->interface);
	GError *error = NULL;
	char *path = NULL;

	if (dbus_g_proxy_end_call (proxy, call_id, &error,
	                           DBUS_TYPE_G_OBJECT_PATH, &path,
	                           G_TYPE_INVALID)) {
		interface_add_done (info->interface, path);
	} else {
		if (dbus_g_error_has_name (error, WPAS_ERROR_EXISTS_ERROR)) {
			/* Interface already added, just get its object path */
			interface_get (info->interface);
		} else if (   g_error_matches (error, DBUS_GERROR, DBUS_GERROR_SERVICE_UNKNOWN)
		           || g_error_matches (error, DBUS_GERROR, DBUS_GERROR_SPAWN_EXEC_FAILED)
		           || g_error_matches (error, DBUS_GERROR, DBUS_GERROR_SPAWN_FORK_FAILED)
		           || g_error_matches (error, DBUS_GERROR, DBUS_GERROR_SPAWN_FAILED)
		           || dbus_g_error_has_name (error, DBUS_ERROR_SPAWN_SERVICE_NOT_FOUND)) {
			/* Supplicant wasn't running and could be launched via service
			 * activation.  Wait for it to start by moving back to the INIT
			 * state.
			 */
			nm_log_dbg (LOGD_SUPPLICANT, "(%s): failed to activate supplicant: %s",
			            priv->dev, error->message);
			set_state (info->interface, NM_SUPPLICANT_INTERFACE_STATE_INIT);
		} else {
			nm_log_err (LOGD_SUPPLICANT, "(%s): error adding interface: %s",
			            priv->dev, error->message);
			set_state (info->interface, NM_SUPPLICANT_INTERFACE_STATE_DOWN);
		}
		g_clear_error (&error);
	}
}