about summary refs log tree commit diff
path: root/src/devices/bluetooth/nm-bluez4-adapter.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/bluetooth/nm-bluez4-adapter.c')
-rw-r--r--src/devices/bluetooth/nm-bluez4-adapter.c131
1 files changed, 90 insertions, 41 deletions
diff --git a/src/devices/bluetooth/nm-bluez4-adapter.c b/src/devices/bluetooth/nm-bluez4-adapter.c
index c0c1be30..0f19f998 100644
--- a/src/devices/bluetooth/nm-bluez4-adapter.c
+++ b/src/devices/bluetooth/nm-bluez4-adapter.c
@@ -25,6 +25,7 @@
 #include <string.h>
 
 #include "nm-dbus-interface.h"
+#include "nm-utils/nm-hash-utils.h"
 #include "nm-bluez-device.h"
 #include "nm-bluez-common.h"
 #include "nm-core-internal.h"
@@ -49,6 +50,7 @@ static guint signals[LAST_SIGNAL] = { 0 };
 typedef struct {
 	char *path;
 	GDBusProxy *proxy;
+	GCancellable *proxy_cancellable;
 	gboolean initialized;
 
 	char *address;
@@ -73,6 +75,11 @@ G_DEFINE_TYPE (NMBluez4Adapter, nm_bluez4_adapter, G_TYPE_OBJECT)
 
 /*****************************************************************************/
 
+#define _NMLOG_DOMAIN      LOGD_BT
+#define _NMLOG(level, ...) __NMLOG_DEFAULT (level, _NMLOG_DOMAIN, "bluez4-adapter", __VA_ARGS__)
+
+/*****************************************************************************/
+
 static void device_do_remove (NMBluez4Adapter *self, NMBluezDevice *device);
 
 /*****************************************************************************/
@@ -119,8 +126,8 @@ nm_bluez4_adapter_get_devices (NMBluez4Adapter *self)
 static void
 emit_device_removed (NMBluez4Adapter *self, NMBluezDevice *device)
 {
-	nm_log_dbg (LOGD_BT, "(%s): bluez device now unusable",
-	            nm_bluez_device_get_path (device));
+	_LOGD ("(%s): bluez device now unusable",
+	       nm_bluez_device_get_path (device));
 	g_signal_emit (self, signals[DEVICE_REMOVED], 0, device);
 }
 
@@ -130,9 +137,9 @@ device_usable (NMBluezDevice *device, GParamSpec *pspec, gpointer user_data)
 	NMBluez4Adapter *self = NM_BLUEZ4_ADAPTER (user_data);
 
 	if (nm_bluez_device_get_usable (device)) {
-		nm_log_dbg (LOGD_BT, "(%s): bluez device now usable (device address is %s)",
-		            nm_bluez_device_get_path (device),
-		            nm_bluez_device_get_address (device));
+		_LOGD ("(%s): bluez device now usable (device address is %s)",
+		       nm_bluez_device_get_path (device),
+		       nm_bluez_device_get_address (device));
 		g_signal_emit (self, signals[DEVICE_ADDED], 0, device);
 	} else
 		emit_device_removed (self, device);
@@ -143,9 +150,9 @@ device_initialized (NMBluezDevice *device, gboolean success, gpointer user_data)
 {
 	NMBluez4Adapter *self = NM_BLUEZ4_ADAPTER (user_data);
 
-	nm_log_dbg (LOGD_BT, "(%s): bluez device %s",
-	            nm_bluez_device_get_path (device),
-	            success ? "initialized" : "failed to initialize");
+	_LOGD ("(%s): bluez device %s",
+	       nm_bluez_device_get_path (device),
+	       success ? "initialized" : "failed to initialize");
 	if (!success)
 		device_do_remove (self, device);
 }
@@ -174,11 +181,11 @@ device_created (GDBusProxy *proxy, const char *path, gpointer user_data)
 	NMBluezDevice *device;
 
 	device = nm_bluez_device_new (path, priv->address, priv->settings, 4);
-	g_signal_connect (device, "initialized", G_CALLBACK (device_initialized), self);
-	g_signal_connect (device, "notify::usable", G_CALLBACK (device_usable), self);
+	g_signal_connect (device, NM_BLUEZ_DEVICE_INITIALIZED, G_CALLBACK (device_initialized), self);
+	g_signal_connect (device, "notify::" NM_BLUEZ_DEVICE_USABLE, G_CALLBACK (device_usable), self);
 	g_hash_table_insert (priv->devices, (gpointer) nm_bluez_device_get_path (device), device);
 
-	nm_log_dbg (LOGD_BT, "(%s): new bluez device found", path);
+	_LOGD ("(%s): new bluez device found", path);
 }
 
 static void
@@ -188,7 +195,7 @@ device_removed (GDBusProxy *proxy, const char *path, gpointer user_data)
 	NMBluez4AdapterPrivate *priv = NM_BLUEZ4_ADAPTER_GET_PRIVATE (self);
 	NMBluezDevice *device;
 
-	nm_log_dbg (LOGD_BT, "(%s): bluez device removed", path);
+	_LOGD ("(%s): bluez device removed", path);
 
 	device = g_hash_table_lookup (priv->devices, path);
 	if (device)
@@ -198,19 +205,28 @@ device_removed (GDBusProxy *proxy, const char *path, gpointer user_data)
 static void
 get_properties_cb (GObject *proxy, GAsyncResult *result, gpointer user_data)
 {
-	NMBluez4Adapter *self = NM_BLUEZ4_ADAPTER (user_data);
-	NMBluez4AdapterPrivate *priv = NM_BLUEZ4_ADAPTER_GET_PRIVATE (self);
-	GError *err = NULL;
+	NMBluez4Adapter *self;
+	NMBluez4AdapterPrivate *priv;
+	gs_free_error GError *error = NULL;
 	GVariant *ret, *properties;
 	char **devices;
 	int i;
 
 	ret = _nm_dbus_proxy_call_finish (G_DBUS_PROXY (proxy), result,
-	                                  G_VARIANT_TYPE ("(a{sv})"), &err);
+	                                  G_VARIANT_TYPE ("(a{sv})"), &error);
+
+	if (   !ret
+	    && g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+		return;
+
+	self = NM_BLUEZ4_ADAPTER (user_data);
+	priv = NM_BLUEZ4_ADAPTER_GET_PRIVATE (self);
+
+	g_clear_object (&priv->proxy_cancellable);
+
 	if (!ret) {
-		g_dbus_error_strip_remote_error (err);
-		nm_log_warn (LOGD_BT, "bluez error getting adapter properties: %s", err->message);
-		g_error_free (err);
+		g_dbus_error_strip_remote_error (error);
+		_LOGW ("bluez error getting adapter properties: %s", error->message);
 		goto done;
 	}
 
@@ -233,15 +249,43 @@ done:
 }
 
 static void
-query_properties (NMBluez4Adapter *self)
+_proxy_new_cb (GObject *source_object,
+               GAsyncResult *result,
+               gpointer user_data)
 {
-	NMBluez4AdapterPrivate *priv = NM_BLUEZ4_ADAPTER_GET_PRIVATE (self);
+	NMBluez4Adapter *self;
+	NMBluez4AdapterPrivate *priv;
+	gs_free_error GError *error = NULL;
+	GDBusProxy *proxy;
+
+	proxy = g_dbus_proxy_new_for_bus_finish (result, &error);
+	if (   !proxy
+	    && g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+		return;
+
+	self = user_data;
+	priv = NM_BLUEZ4_ADAPTER_GET_PRIVATE (self);
+
+	if (!proxy) {
+		_LOGW ("bluez error creating D-Bus proxy: %s", error->message);
+		g_clear_object (&priv->proxy_cancellable);
+		g_signal_emit (self, signals[INITIALIZED], 0, priv->initialized);
+		return;
+	}
+
+	priv->proxy = proxy;
+
+	_nm_dbus_signal_connect (priv->proxy, "DeviceCreated", G_VARIANT_TYPE ("(o)"),
+	                         G_CALLBACK (device_created), self);
+	_nm_dbus_signal_connect (priv->proxy, "DeviceRemoved", G_VARIANT_TYPE ("(o)"),
+	                         G_CALLBACK (device_removed), self);
 
 	g_dbus_proxy_call (priv->proxy, "GetProperties",
 	                   NULL,
 	                   G_DBUS_CALL_FLAGS_NONE, -1,
-	                   NULL,
-	                   get_properties_cb, self);
+	                   priv->proxy_cancellable,
+	                   get_properties_cb,
+	                   self);
 }
 
 /*****************************************************************************/
@@ -297,7 +341,7 @@ nm_bluez4_adapter_init (NMBluez4Adapter *self)
 {
 	NMBluez4AdapterPrivate *priv = NM_BLUEZ4_ADAPTER_GET_PRIVATE (self);
 
-	priv->devices = g_hash_table_new_full (g_str_hash, g_str_equal,
+	priv->devices = g_hash_table_new_full (nm_str_hash, g_str_equal,
 	                                       NULL, NULL);
 }
 
@@ -316,19 +360,17 @@ nm_bluez4_adapter_new (const char *path, NMSettings *settings)
 
 	priv->settings = g_object_ref (settings);
 
-	priv->proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
-	                                             G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES,
-	                                             NULL,
-	                                             BLUEZ_SERVICE,
-	                                             priv->path,
-	                                             BLUEZ4_ADAPTER_INTERFACE,
-	                                             NULL, NULL);
-	_nm_dbus_signal_connect (priv->proxy, "DeviceCreated", G_VARIANT_TYPE ("(o)"),
-	                         G_CALLBACK (device_created), self);
-	_nm_dbus_signal_connect (priv->proxy, "DeviceRemoved", G_VARIANT_TYPE ("(o)"),
-	                         G_CALLBACK (device_removed), self);
+	priv->proxy_cancellable = g_cancellable_new ();
 
-	query_properties (self);
+	g_dbus_proxy_new_for_bus (G_BUS_TYPE_SYSTEM,
+	                          G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES,
+	                          NULL,
+	                          NM_BLUEZ_SERVICE,
+	                          priv->path,
+	                          NM_BLUEZ4_ADAPTER_INTERFACE,
+	                          priv->proxy_cancellable,
+	                          _proxy_new_cb,
+	                          self);
 	return self;
 }
 
@@ -339,21 +381,28 @@ dispose (GObject *object)
 	NMBluez4AdapterPrivate *priv = NM_BLUEZ4_ADAPTER_GET_PRIVATE (self);
 	NMBluezDevice *device;
 
+	nm_clear_g_cancellable (&priv->proxy_cancellable);
+
 	while ((device = g_hash_table_find (priv->devices, _find_all, NULL)))
 		device_do_remove (self, device);
 
+	if (priv->proxy) {
+		g_signal_handlers_disconnect_by_data (priv->proxy, self);
+		g_clear_object (&priv->proxy);
+	}
+
 	G_OBJECT_CLASS (nm_bluez4_adapter_parent_class)->dispose (object);
 }
 
 static void
 finalize (GObject *object)
 {
-	NMBluez4AdapterPrivate *priv = NM_BLUEZ4_ADAPTER_GET_PRIVATE ((NMBluez4Adapter *) object);
+	NMBluez4Adapter *self = NM_BLUEZ4_ADAPTER (object);
+	NMBluez4AdapterPrivate *priv = NM_BLUEZ4_ADAPTER_GET_PRIVATE (self);
 
 	g_hash_table_destroy (priv->devices);
 	g_free (priv->address);
 	g_free (priv->path);
-	g_object_unref (priv->proxy);
 
 	G_OBJECT_CLASS (nm_bluez4_adapter_parent_class)->finalize (object);
 
@@ -384,7 +433,7 @@ nm_bluez4_adapter_class_init (NMBluez4AdapterClass *config_class)
 
 	g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties);
 
-	signals[INITIALIZED] = g_signal_new ("initialized",
+	signals[INITIALIZED] = g_signal_new (NM_BLUEZ4_ADAPTER_INITIALIZED,
 	                                     G_OBJECT_CLASS_TYPE (object_class),
 	                                     G_SIGNAL_RUN_LAST,
 	                                     0,
@@ -392,7 +441,7 @@ nm_bluez4_adapter_class_init (NMBluez4AdapterClass *config_class)
 	                                     g_cclosure_marshal_VOID__BOOLEAN,
 	                                     G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
 
-	signals[DEVICE_ADDED] = g_signal_new ("device-added",
+	signals[DEVICE_ADDED] = g_signal_new (NM_BLUEZ4_ADAPTER_DEVICE_ADDED,
 	                                      G_OBJECT_CLASS_TYPE (object_class),
 	                                      G_SIGNAL_RUN_LAST,
 	                                      0,
@@ -400,7 +449,7 @@ nm_bluez4_adapter_class_init (NMBluez4AdapterClass *config_class)
 	                                      g_cclosure_marshal_VOID__OBJECT,
 	                                      G_TYPE_NONE, 1, G_TYPE_OBJECT);
 
-	signals[DEVICE_REMOVED] = g_signal_new ("device-removed",
+	signals[DEVICE_REMOVED] = g_signal_new (NM_BLUEZ4_ADAPTER_DEVICE_REMOVED,
 	                                        G_OBJECT_CLASS_TYPE (object_class),
 	                                        G_SIGNAL_RUN_LAST,
 	                                        0,