From 5a87917f903623aae242f3ac495c32ef8d213bcf Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Thu, 14 May 2009 13:59:03 -0400 Subject: [PATCH] bluetooth: create NMDeviceBt objects for configured Bluez devices Create a new exported Bluetooth device object for any usable Bluez device that has at least one corresponding NMConnection somewhere. Clean up UUID/Capability confusion too. --- marshallers/nm-marshal.list | 1 + src/bluez-manager/nm-bluez-device.c | 47 +++++++----- src/bluez-manager/nm-bluez-device.h | 14 ++-- src/bluez-manager/nm-bluez-manager.c | 49 ++++++------ src/bluez-manager/nm-bluez-manager.h | 10 ++- src/nm-manager.c | 110 +++++++++++++++++++++++++-- 6 files changed, 169 insertions(+), 62 deletions(-) diff --git a/marshallers/nm-marshal.list b/marshallers/nm-marshal.list index 419716c614..62c9ed08ef 100644 --- a/marshallers/nm-marshal.list +++ b/marshallers/nm-marshal.list @@ -12,6 +12,7 @@ VOID:STRING,STRING VOID:STRING,UCHAR VOID:STRING,OBJECT VOID:STRING,STRING,POINTER,POINTER +VOID:STRING,STRING,STRING,UINT VOID:OBJECT,UINT,UINT VOID:STRING,INT VOID:STRING,UINT diff --git a/src/bluez-manager/nm-bluez-device.c b/src/bluez-manager/nm-bluez-device.c index 3505b30fe0..6ecd6b43c0 100644 --- a/src/bluez-manager/nm-bluez-device.c +++ b/src/bluez-manager/nm-bluez-device.c @@ -42,7 +42,7 @@ typedef struct { char *address; char *name; - guint32 uuids; + guint32 capabilities; gint rssi; } NMBluezDevicePrivate; @@ -52,7 +52,7 @@ enum { PROP_PATH, PROP_ADDRESS, PROP_NAME, - PROP_UUIDS, + PROP_CAPABILITIES, PROP_RSSI, PROP_USABLE, @@ -107,11 +107,11 @@ nm_bluez_device_get_name (NMBluezDevice *self) } guint32 -nm_bluez_device_get_uuids (NMBluezDevice *self) +nm_bluez_device_get_capabilities (NMBluezDevice *self) { g_return_val_if_fail (NM_IS_BLUEZ_DEVICE (self), 0); - return NM_BLUEZ_DEVICE_GET_PRIVATE (self)->uuids; + return NM_BLUEZ_DEVICE_GET_PRIVATE (self)->capabilities; } gint @@ -123,10 +123,10 @@ nm_bluez_device_get_rssi (NMBluezDevice *self) } static guint32 -convert_uuids (const char **strings) +convert_uuids_to_capabilities (const char **strings) { const char **iter; - guint32 uuids = 0; + guint32 capabilities = 0; for (iter = strings; iter && *iter; iter++) { char **parts; @@ -143,17 +143,17 @@ convert_uuids (const char **strings) switch (uuid16) { case 0x1103: - uuids |= NM_BT_CAPABILITY_DUN; + capabilities |= NM_BT_CAPABILITY_DUN; break; case 0x1116: - uuids |= NM_BT_CAPABILITY_NAP; + capabilities |= NM_BT_CAPABILITY_NAP; break; default: break; } } - return uuids; + return capabilities; } static void @@ -162,7 +162,7 @@ check_emit_usable (NMBluezDevice *self) NMBluezDevicePrivate *priv = NM_BLUEZ_DEVICE_GET_PRIVATE (self); if ( priv->initialized - && priv->uuids + && priv->capabilities && priv->name && priv->address) { if (!priv->usable) { @@ -205,10 +205,10 @@ property_changed (DBusGProxy *proxy, g_object_notify (G_OBJECT (self), NM_BLUEZ_DEVICE_RSSI); } } else if (!strcmp (property, "UUIDs")) { - uint_val = convert_uuids ((const char **) g_value_get_boxed (value)); - if (priv->uuids != uint_val) { - priv->uuids = uint_val; - g_object_notify (G_OBJECT (self), NM_BLUEZ_DEVICE_UUIDS); + uint_val = convert_uuids_to_capabilities ((const char **) g_value_get_boxed (value)); + if (priv->capabilities != uint_val) { + priv->capabilities = uint_val; + g_object_notify (G_OBJECT (self), NM_BLUEZ_DEVICE_CAPABILITIES); } } @@ -223,6 +223,7 @@ get_properties_cb (DBusGProxy *proxy, DBusGProxyCall *call, gpointer user_data) GHashTable *properties = NULL; GError *err = NULL; GValue *value; + const char **uuids; if (!dbus_g_proxy_end_call (proxy, call, &err, DBUS_TYPE_G_MAP_OF_VARIANT, &properties, @@ -244,7 +245,11 @@ get_properties_cb (DBusGProxy *proxy, DBusGProxyCall *call, gpointer user_data) priv->rssi = value ? g_value_get_int (value) : 0; value = g_hash_table_lookup (properties, "UUIDs"); - priv->uuids = value ? convert_uuids ((const char **) g_value_get_boxed (value)) : 0; + if (value) { + uuids = (const char **) g_value_get_boxed (value); + priv->capabilities = convert_uuids_to_capabilities (uuids); + } else + priv->capabilities = NM_BT_CAPABILITY_NONE; g_hash_table_unref (properties); @@ -342,8 +347,8 @@ get_property (GObject *object, guint prop_id, case PROP_NAME: g_value_set_string (value, priv->name); break; - case PROP_UUIDS: - g_value_set_uint (value, priv->uuids); + case PROP_CAPABILITIES: + g_value_set_uint (value, priv->capabilities); break; case PROP_RSSI: g_value_set_int (value, priv->rssi); @@ -412,10 +417,10 @@ nm_bluez_device_class_init (NMBluezDeviceClass *config_class) G_PARAM_READABLE)); g_object_class_install_property - (object_class, PROP_UUIDS, - g_param_spec_uint (NM_BLUEZ_DEVICE_UUIDS, - "UUIDs", - "UUIDs", + (object_class, PROP_CAPABILITIES, + g_param_spec_uint (NM_BLUEZ_DEVICE_CAPABILITIES, + "Capabilities", + "Capabilities", 0, G_MAXUINT, 0, G_PARAM_READABLE)); diff --git a/src/bluez-manager/nm-bluez-device.h b/src/bluez-manager/nm-bluez-device.h index 7996393c42..8a6b3597ad 100644 --- a/src/bluez-manager/nm-bluez-device.h +++ b/src/bluez-manager/nm-bluez-device.h @@ -31,12 +31,12 @@ #define NM_IS_BLUEZ_DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_BLUEZ_DEVICE)) #define NM_BLUEZ_DEVICE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_BLUEZ_DEVICE, NMBluezDeviceClass)) -#define NM_BLUEZ_DEVICE_PATH "path" -#define NM_BLUEZ_DEVICE_ADDRESS "address" -#define NM_BLUEZ_DEVICE_NAME "name" -#define NM_BLUEZ_DEVICE_UUIDS "uuids" -#define NM_BLUEZ_DEVICE_RSSI "rssi" -#define NM_BLUEZ_DEVICE_USABLE "usable" +#define NM_BLUEZ_DEVICE_PATH "path" +#define NM_BLUEZ_DEVICE_ADDRESS "address" +#define NM_BLUEZ_DEVICE_NAME "name" +#define NM_BLUEZ_DEVICE_CAPABILITIES "capabilities" +#define NM_BLUEZ_DEVICE_RSSI "rssi" +#define NM_BLUEZ_DEVICE_USABLE "usable" typedef struct { GObject parent; @@ -67,7 +67,7 @@ const char *nm_bluez_device_get_name (NMBluezDevice *self); guint32 nm_bluez_device_get_class (NMBluezDevice *self); -guint32 nm_bluez_device_get_uuids (NMBluezDevice *self); +guint32 nm_bluez_device_get_capabilities (NMBluezDevice *self); gint nm_bluez_device_get_rssi (NMBluezDevice *self); diff --git a/src/bluez-manager/nm-bluez-manager.c b/src/bluez-manager/nm-bluez-manager.c index 20c6b358a5..96cb3e725e 100644 --- a/src/bluez-manager/nm-bluez-manager.c +++ b/src/bluez-manager/nm-bluez-manager.c @@ -55,6 +55,17 @@ enum { static guint signals[LAST_SIGNAL] = { 0 }; +static void + +emit_bdaddr_added (NMBluezManager *self, NMBluezDevice *device) +{ + g_signal_emit (self, signals[BDADDR_ADDED], 0, + nm_bluez_device_get_address (device), + nm_bluez_device_get_name (device), + nm_bluez_device_get_path (device), + nm_bluez_device_get_capabilities (device)); +} + void nm_bluez_manager_query_devices (NMBluezManager *self) { @@ -65,24 +76,15 @@ nm_bluez_manager_query_devices (NMBluezManager *self) return; devices = nm_bluez_adapter_get_devices (priv->adapter); - for (iter = devices; iter; iter = g_slist_next (iter)) { - NMBluezDevice *device = NM_BLUEZ_DEVICE (iter->data); - - g_signal_emit (self, signals[BDADDR_ADDED], 0, - nm_bluez_device_get_address (device), - nm_bluez_device_get_uuids (device)); - } + for (iter = devices; iter; iter = g_slist_next (iter)) + emit_bdaddr_added (self, NM_BLUEZ_DEVICE (iter->data)); g_slist_free (devices); } static void device_added (NMBluezAdapter *adapter, NMBluezDevice *device, gpointer user_data) { - NMBluezManager *self = NM_BLUEZ_MANAGER (user_data); - - g_signal_emit (self, signals[BDADDR_ADDED], 0, - nm_bluez_device_get_address (device), - nm_bluez_device_get_uuids (device)); + emit_bdaddr_added (NM_BLUEZ_MANAGER (user_data), device); } static void @@ -91,7 +93,8 @@ device_removed (NMBluezAdapter *adapter, NMBluezDevice *device, gpointer user_da NMBluezManager *self = NM_BLUEZ_MANAGER (user_data); g_signal_emit (self, signals[BDADDR_REMOVED], 0, - nm_bluez_device_get_address (device)); + nm_bluez_device_get_address (device), + nm_bluez_device_get_path (device)); } static void @@ -104,13 +107,8 @@ adapter_initialized (NMBluezAdapter *adapter, gboolean success, gpointer user_da GSList *devices, *iter; devices = nm_bluez_adapter_get_devices (adapter); - for (iter = devices; iter; iter = g_slist_next (iter)) { - NMBluezDevice *device = NM_BLUEZ_DEVICE (iter->data); - - g_signal_emit (self, signals[BDADDR_ADDED], 0, - nm_bluez_device_get_address (device), - nm_bluez_device_get_uuids (device)); - } + for (iter = devices; iter; iter = g_slist_next (iter)) + emit_bdaddr_added (self, NM_BLUEZ_DEVICE (iter->data)); g_slist_free (devices); g_signal_connect (adapter, "device-added", G_CALLBACK (device_added), self); @@ -135,7 +133,8 @@ adapter_removed (DBusGProxy *proxy, const char *path, NMBluezManager *self) NMBluezDevice *device = NM_BLUEZ_DEVICE (iter->data); g_signal_emit (self, signals[BDADDR_REMOVED], 0, - nm_bluez_device_get_address (device)); + nm_bluez_device_get_address (device), + nm_bluez_device_get_path (device)); } g_slist_free (devices); } @@ -355,8 +354,8 @@ nm_bluez_manager_class_init (NMBluezManagerClass *klass) G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (NMBluezManagerClass, bdaddr_added), NULL, NULL, - _nm_marshal_VOID__STRING_UINT, - G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_UINT); + _nm_marshal_VOID__STRING_STRING_STRING_UINT, + G_TYPE_NONE, 4, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_UINT); signals[BDADDR_REMOVED] = g_signal_new ("bdaddr-removed", @@ -364,7 +363,7 @@ nm_bluez_manager_class_init (NMBluezManagerClass *klass) G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (NMBluezManagerClass, bdaddr_removed), NULL, NULL, - g_cclosure_marshal_VOID__STRING, - G_TYPE_NONE, 1, G_TYPE_STRING); + _nm_marshal_VOID__STRING_STRING, + G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_STRING); } diff --git a/src/bluez-manager/nm-bluez-manager.h b/src/bluez-manager/nm-bluez-manager.h index d7513fa300..9cfab1b7e7 100644 --- a/src/bluez-manager/nm-bluez-manager.h +++ b/src/bluez-manager/nm-bluez-manager.h @@ -42,9 +42,15 @@ typedef struct { GObjectClass parent; /* Virtual functions */ - void (*bdaddr_added) (NMBluezManager *manager, const char *bdaddr, guint uuids); + void (*bdaddr_added) (NMBluezManager *manager, + const char *bdaddr, + const char *name, + const char *object_path, + guint uuids); - void (*bdaddr_removed) (NMBluezManager *manager, const char *bdaddr); + void (*bdaddr_removed) (NMBluezManager *manager, + const char *bdaddr, + const char *object_path); } NMBluezManagerClass; GType nm_bluez_manager_get_type (void); diff --git a/src/nm-manager.c b/src/nm-manager.c index 9652360fd6..7afd4871d7 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -30,12 +30,14 @@ #include "nm-dbus-manager.h" #include "nm-vpn-manager.h" #include "nm-modem-manager.h" +#include "nm-device-bt.h" #include "nm-device-interface.h" #include "nm-device-private.h" #include "nm-device-ethernet.h" #include "nm-device-wifi.h" #include "NetworkManagerSystem.h" #include "nm-properties-changed-signal.h" +#include "nm-setting-bluetooth.h" #include "nm-setting-connection.h" #include "nm-setting-wireless.h" #include "nm-setting-vpn.h" @@ -100,11 +102,14 @@ static void hal_manager_hal_reappeared_cb (NMHalManager *hal_mgr, static void bluez_manager_bdaddr_added_cb (NMBluezManager *bluez_mgr, const char *bdaddr, - guint type, - gpointer user_data); + const char *name, + const char *object_path, + guint32 uuids, + NMManager *manager); static void bluez_manager_bdaddr_removed_cb (NMBluezManager *bluez_mgr, const char *bdaddr, + const char *object_path, gpointer user_data); static void system_settings_properties_changed_cb (DBusGProxy *proxy, @@ -1796,14 +1801,70 @@ add_device (NMManager *self, NMDevice *device) g_signal_emit (self, signals[DEVICE_ADDED], 0, device); } +static gboolean +bluez_manager_bdaddr_has_connection (NMManager *manager, + const char *bdaddr, + guint32 uuids, + NMConnectionScope scope) +{ + GSList *connections, *l; + gboolean found = FALSE; + + connections = nm_manager_get_connections (manager, scope); + for (l = connections; l != NULL; l = l->next) { + NMConnection *connection = NM_CONNECTION (l->data); + NMSettingConnection *s_con; + NMSettingBluetooth *s_bt; + const char *con_type; + const char *bt_type; + + s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + g_assert (s_con); + con_type = nm_setting_connection_get_connection_type (s_con); + g_assert (con_type); + if (!g_str_equal (con_type, NM_SETTING_BLUETOOTH_SETTING_NAME)) + continue; + + s_bt = (NMSettingBluetooth *) nm_connection_get_setting (connection, NM_TYPE_SETTING_BLUETOOTH); + if (!s_bt) + continue; + + if (g_str_equal (nm_setting_bluetooth_get_bdaddr (s_bt), bdaddr) == FALSE) + continue; + + bt_type = nm_setting_bluetooth_get_connection_type (s_bt); + if ( g_str_equal (bt_type, NM_SETTING_BLUETOOTH_TYPE_DUN) + && !(uuids & NM_BT_CAPABILITY_DUN)) + continue; + if ( g_str_equal (bt_type, NM_SETTING_BLUETOOTH_TYPE_PANU) + && !(uuids & NM_BT_CAPABILITY_NAP)) + continue; + + found = TRUE; + break; + } + + g_slist_free (connections); + + return found; +} + static void bluez_manager_bdaddr_added_cb (NMBluezManager *bluez_mgr, const char *bdaddr, - guint32 uuids, - gpointer user_data) + const char *name, + const char *object_path, + guint32 capabilities, + NMManager *manager) { - gboolean has_dun = (uuids & NM_BT_CAPABILITY_DUN); - gboolean has_nap = (uuids & NM_BT_CAPABILITY_NAP); + NMDeviceBt *device; + gboolean has_dun = (capabilities & NM_BT_CAPABILITY_DUN); + gboolean has_nap = (capabilities & NM_BT_CAPABILITY_NAP); + + g_return_if_fail (bdaddr != NULL); + g_return_if_fail (name != NULL); + g_return_if_fail (object_path != NULL); + g_return_if_fail (capabilities != NM_BT_CAPABILITY_NONE); g_message ("%s: BT device %s added (%s%s%s)", __func__, @@ -1811,14 +1872,49 @@ bluez_manager_bdaddr_added_cb (NMBluezManager *bluez_mgr, has_dun ? "DUN" : "", has_dun && has_nap ? " " : "", has_nap ? "NAP" : ""); + + /* Make sure the device is not already in the device list */ + if (nm_manager_get_device_by_udi (manager, object_path)) + return; + + if (has_dun == FALSE && has_nap == FALSE) + return; + + if ( !bluez_manager_bdaddr_has_connection (manager, bdaddr, capabilities, NM_CONNECTION_SCOPE_SYSTEM) + && !bluez_manager_bdaddr_has_connection (manager, bdaddr, capabilities, NM_CONNECTION_SCOPE_USER)) + return; + + device = nm_device_bt_new (object_path, bdaddr, name, capabilities, TRUE); + if (!device) + return; + + add_device (manager, NM_DEVICE (device)); } static void bluez_manager_bdaddr_removed_cb (NMBluezManager *bluez_mgr, - const char *bdaddr, + const char *bdaddr, + const char *object_path, gpointer user_data) { + NMManager *self = NM_MANAGER (user_data); + NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); + GSList *iter; + + g_return_if_fail (bdaddr != NULL); + g_return_if_fail (object_path != NULL); + g_message ("%s: BT device %s removed", __func__, bdaddr); + + for (iter = priv->devices; iter; iter = iter->next) { + NMDevice *device = NM_DEVICE (iter->data); + + if (!strcmp (nm_device_get_udi (device), object_path)) { + priv->devices = g_slist_delete_link (priv->devices, iter); + remove_one_device (self, device); + break; + } + } } static void