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,OBJECT
VOID:STRING,STRING,POINTER,POINTER
VOID:STRING,STRING,STRING,UINT
VOID:OBJECT,UINT,UINT
VOID:STRING,INT
VOID:STRING,UINT

View file

@ -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));

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_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);

View file

@ -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);
}

View file

@ -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);

View file

@ -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