mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2025-12-30 09:40:11 +01:00
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:
parent
3af7068a87
commit
5a87917f90
6 changed files with 169 additions and 62 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
110
src/nm-manager.c
110
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
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue