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.
This commit is contained in:
Bastien Nocera 2009-05-14 13:59:03 -04:00 committed by Dan Williams
parent 3af7068a87
commit 5a87917f90
6 changed files with 169 additions and 62 deletions

View file

@ -12,6 +12,7 @@ VOID:STRING,STRING
VOID:STRING,UCHAR VOID:STRING,UCHAR
VOID:STRING,OBJECT VOID:STRING,OBJECT
VOID:STRING,STRING,POINTER,POINTER VOID:STRING,STRING,POINTER,POINTER
VOID:STRING,STRING,STRING,UINT
VOID:OBJECT,UINT,UINT VOID:OBJECT,UINT,UINT
VOID:STRING,INT VOID:STRING,INT
VOID:STRING,UINT VOID:STRING,UINT

View file

@ -42,7 +42,7 @@ typedef struct {
char *address; char *address;
char *name; char *name;
guint32 uuids; guint32 capabilities;
gint rssi; gint rssi;
} NMBluezDevicePrivate; } NMBluezDevicePrivate;
@ -52,7 +52,7 @@ enum {
PROP_PATH, PROP_PATH,
PROP_ADDRESS, PROP_ADDRESS,
PROP_NAME, PROP_NAME,
PROP_UUIDS, PROP_CAPABILITIES,
PROP_RSSI, PROP_RSSI,
PROP_USABLE, PROP_USABLE,
@ -107,11 +107,11 @@ nm_bluez_device_get_name (NMBluezDevice *self)
} }
guint32 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); 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 gint
@ -123,10 +123,10 @@ nm_bluez_device_get_rssi (NMBluezDevice *self)
} }
static guint32 static guint32
convert_uuids (const char **strings) convert_uuids_to_capabilities (const char **strings)
{ {
const char **iter; const char **iter;
guint32 uuids = 0; guint32 capabilities = 0;
for (iter = strings; iter && *iter; iter++) { for (iter = strings; iter && *iter; iter++) {
char **parts; char **parts;
@ -143,17 +143,17 @@ convert_uuids (const char **strings)
switch (uuid16) { switch (uuid16) {
case 0x1103: case 0x1103:
uuids |= NM_BT_CAPABILITY_DUN; capabilities |= NM_BT_CAPABILITY_DUN;
break; break;
case 0x1116: case 0x1116:
uuids |= NM_BT_CAPABILITY_NAP; capabilities |= NM_BT_CAPABILITY_NAP;
break; break;
default: default:
break; break;
} }
} }
return uuids; return capabilities;
} }
static void static void
@ -162,7 +162,7 @@ check_emit_usable (NMBluezDevice *self)
NMBluezDevicePrivate *priv = NM_BLUEZ_DEVICE_GET_PRIVATE (self); NMBluezDevicePrivate *priv = NM_BLUEZ_DEVICE_GET_PRIVATE (self);
if ( priv->initialized if ( priv->initialized
&& priv->uuids && priv->capabilities
&& priv->name && priv->name
&& priv->address) { && priv->address) {
if (!priv->usable) { if (!priv->usable) {
@ -205,10 +205,10 @@ property_changed (DBusGProxy *proxy,
g_object_notify (G_OBJECT (self), NM_BLUEZ_DEVICE_RSSI); g_object_notify (G_OBJECT (self), NM_BLUEZ_DEVICE_RSSI);
} }
} else if (!strcmp (property, "UUIDs")) { } else if (!strcmp (property, "UUIDs")) {
uint_val = convert_uuids ((const char **) g_value_get_boxed (value)); uint_val = convert_uuids_to_capabilities ((const char **) g_value_get_boxed (value));
if (priv->uuids != uint_val) { if (priv->capabilities != uint_val) {
priv->uuids = uint_val; priv->capabilities = uint_val;
g_object_notify (G_OBJECT (self), NM_BLUEZ_DEVICE_UUIDS); 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; GHashTable *properties = NULL;
GError *err = NULL; GError *err = NULL;
GValue *value; GValue *value;
const char **uuids;
if (!dbus_g_proxy_end_call (proxy, call, &err, if (!dbus_g_proxy_end_call (proxy, call, &err,
DBUS_TYPE_G_MAP_OF_VARIANT, &properties, 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; priv->rssi = value ? g_value_get_int (value) : 0;
value = g_hash_table_lookup (properties, "UUIDs"); 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); g_hash_table_unref (properties);
@ -342,8 +347,8 @@ get_property (GObject *object, guint prop_id,
case PROP_NAME: case PROP_NAME:
g_value_set_string (value, priv->name); g_value_set_string (value, priv->name);
break; break;
case PROP_UUIDS: case PROP_CAPABILITIES:
g_value_set_uint (value, priv->uuids); g_value_set_uint (value, priv->capabilities);
break; break;
case PROP_RSSI: case PROP_RSSI:
g_value_set_int (value, priv->rssi); g_value_set_int (value, priv->rssi);
@ -412,10 +417,10 @@ nm_bluez_device_class_init (NMBluezDeviceClass *config_class)
G_PARAM_READABLE)); G_PARAM_READABLE));
g_object_class_install_property g_object_class_install_property
(object_class, PROP_UUIDS, (object_class, PROP_CAPABILITIES,
g_param_spec_uint (NM_BLUEZ_DEVICE_UUIDS, g_param_spec_uint (NM_BLUEZ_DEVICE_CAPABILITIES,
"UUIDs", "Capabilities",
"UUIDs", "Capabilities",
0, G_MAXUINT, 0, 0, G_MAXUINT, 0,
G_PARAM_READABLE)); G_PARAM_READABLE));

View file

@ -31,12 +31,12 @@
#define NM_IS_BLUEZ_DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_BLUEZ_DEVICE)) #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_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_BLUEZ_DEVICE, NMBluezDeviceClass))
#define NM_BLUEZ_DEVICE_PATH "path" #define NM_BLUEZ_DEVICE_PATH "path"
#define NM_BLUEZ_DEVICE_ADDRESS "address" #define NM_BLUEZ_DEVICE_ADDRESS "address"
#define NM_BLUEZ_DEVICE_NAME "name" #define NM_BLUEZ_DEVICE_NAME "name"
#define NM_BLUEZ_DEVICE_UUIDS "uuids" #define NM_BLUEZ_DEVICE_CAPABILITIES "capabilities"
#define NM_BLUEZ_DEVICE_RSSI "rssi" #define NM_BLUEZ_DEVICE_RSSI "rssi"
#define NM_BLUEZ_DEVICE_USABLE "usable" #define NM_BLUEZ_DEVICE_USABLE "usable"
typedef struct { typedef struct {
GObject parent; 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_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); gint nm_bluez_device_get_rssi (NMBluezDevice *self);

View file

@ -55,6 +55,17 @@ enum {
static guint signals[LAST_SIGNAL] = { 0 }; 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 void
nm_bluez_manager_query_devices (NMBluezManager *self) nm_bluez_manager_query_devices (NMBluezManager *self)
{ {
@ -65,24 +76,15 @@ nm_bluez_manager_query_devices (NMBluezManager *self)
return; return;
devices = nm_bluez_adapter_get_devices (priv->adapter); devices = nm_bluez_adapter_get_devices (priv->adapter);
for (iter = devices; iter; iter = g_slist_next (iter)) { for (iter = devices; iter; iter = g_slist_next (iter))
NMBluezDevice *device = NM_BLUEZ_DEVICE (iter->data); emit_bdaddr_added (self, 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));
}
g_slist_free (devices); g_slist_free (devices);
} }
static void static void
device_added (NMBluezAdapter *adapter, NMBluezDevice *device, gpointer user_data) device_added (NMBluezAdapter *adapter, NMBluezDevice *device, gpointer user_data)
{ {
NMBluezManager *self = NM_BLUEZ_MANAGER (user_data); emit_bdaddr_added (NM_BLUEZ_MANAGER (user_data), device);
g_signal_emit (self, signals[BDADDR_ADDED], 0,
nm_bluez_device_get_address (device),
nm_bluez_device_get_uuids (device));
} }
static void static void
@ -91,7 +93,8 @@ device_removed (NMBluezAdapter *adapter, NMBluezDevice *device, gpointer user_da
NMBluezManager *self = NM_BLUEZ_MANAGER (user_data); NMBluezManager *self = NM_BLUEZ_MANAGER (user_data);
g_signal_emit (self, signals[BDADDR_REMOVED], 0, 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 static void
@ -104,13 +107,8 @@ adapter_initialized (NMBluezAdapter *adapter, gboolean success, gpointer user_da
GSList *devices, *iter; GSList *devices, *iter;
devices = nm_bluez_adapter_get_devices (adapter); devices = nm_bluez_adapter_get_devices (adapter);
for (iter = devices; iter; iter = g_slist_next (iter)) { for (iter = devices; iter; iter = g_slist_next (iter))
NMBluezDevice *device = NM_BLUEZ_DEVICE (iter->data); emit_bdaddr_added (self, 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));
}
g_slist_free (devices); g_slist_free (devices);
g_signal_connect (adapter, "device-added", G_CALLBACK (device_added), self); 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); NMBluezDevice *device = NM_BLUEZ_DEVICE (iter->data);
g_signal_emit (self, signals[BDADDR_REMOVED], 0, 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); g_slist_free (devices);
} }
@ -355,8 +354,8 @@ nm_bluez_manager_class_init (NMBluezManagerClass *klass)
G_SIGNAL_RUN_FIRST, G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (NMBluezManagerClass, bdaddr_added), G_STRUCT_OFFSET (NMBluezManagerClass, bdaddr_added),
NULL, NULL, NULL, NULL,
_nm_marshal_VOID__STRING_UINT, _nm_marshal_VOID__STRING_STRING_STRING_UINT,
G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_UINT); G_TYPE_NONE, 4, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_UINT);
signals[BDADDR_REMOVED] = signals[BDADDR_REMOVED] =
g_signal_new ("bdaddr-removed", g_signal_new ("bdaddr-removed",
@ -364,7 +363,7 @@ nm_bluez_manager_class_init (NMBluezManagerClass *klass)
G_SIGNAL_RUN_FIRST, G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (NMBluezManagerClass, bdaddr_removed), G_STRUCT_OFFSET (NMBluezManagerClass, bdaddr_removed),
NULL, NULL, NULL, NULL,
g_cclosure_marshal_VOID__STRING, _nm_marshal_VOID__STRING_STRING,
G_TYPE_NONE, 1, G_TYPE_STRING); G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_STRING);
} }

View file

@ -42,9 +42,15 @@ typedef struct {
GObjectClass parent; GObjectClass parent;
/* Virtual functions */ /* 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; } NMBluezManagerClass;
GType nm_bluez_manager_get_type (void); GType nm_bluez_manager_get_type (void);

View file

@ -30,12 +30,14 @@
#include "nm-dbus-manager.h" #include "nm-dbus-manager.h"
#include "nm-vpn-manager.h" #include "nm-vpn-manager.h"
#include "nm-modem-manager.h" #include "nm-modem-manager.h"
#include "nm-device-bt.h"
#include "nm-device-interface.h" #include "nm-device-interface.h"
#include "nm-device-private.h" #include "nm-device-private.h"
#include "nm-device-ethernet.h" #include "nm-device-ethernet.h"
#include "nm-device-wifi.h" #include "nm-device-wifi.h"
#include "NetworkManagerSystem.h" #include "NetworkManagerSystem.h"
#include "nm-properties-changed-signal.h" #include "nm-properties-changed-signal.h"
#include "nm-setting-bluetooth.h"
#include "nm-setting-connection.h" #include "nm-setting-connection.h"
#include "nm-setting-wireless.h" #include "nm-setting-wireless.h"
#include "nm-setting-vpn.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, static void bluez_manager_bdaddr_added_cb (NMBluezManager *bluez_mgr,
const char *bdaddr, const char *bdaddr,
guint type, const char *name,
gpointer user_data); const char *object_path,
guint32 uuids,
NMManager *manager);
static void bluez_manager_bdaddr_removed_cb (NMBluezManager *bluez_mgr, static void bluez_manager_bdaddr_removed_cb (NMBluezManager *bluez_mgr,
const char *bdaddr, const char *bdaddr,
const char *object_path,
gpointer user_data); gpointer user_data);
static void system_settings_properties_changed_cb (DBusGProxy *proxy, 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); 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 static void
bluez_manager_bdaddr_added_cb (NMBluezManager *bluez_mgr, bluez_manager_bdaddr_added_cb (NMBluezManager *bluez_mgr,
const char *bdaddr, const char *bdaddr,
guint32 uuids, const char *name,
gpointer user_data) const char *object_path,
guint32 capabilities,
NMManager *manager)
{ {
gboolean has_dun = (uuids & NM_BT_CAPABILITY_DUN); NMDeviceBt *device;
gboolean has_nap = (uuids & NM_BT_CAPABILITY_NAP); 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)", g_message ("%s: BT device %s added (%s%s%s)",
__func__, __func__,
@ -1811,14 +1872,49 @@ bluez_manager_bdaddr_added_cb (NMBluezManager *bluez_mgr,
has_dun ? "DUN" : "", has_dun ? "DUN" : "",
has_dun && has_nap ? " " : "", has_dun && has_nap ? " " : "",
has_nap ? "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 static void
bluez_manager_bdaddr_removed_cb (NMBluezManager *bluez_mgr, bluez_manager_bdaddr_removed_cb (NMBluezManager *bluez_mgr,
const char *bdaddr, const char *bdaddr,
const char *object_path,
gpointer user_data) 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); 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 static void