mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-02-15 09:10:32 +01:00
bluetooth: move device logic to bluez manager
To simplify NMManager and to make use of the new connection provider functionality, move the logic for when a paired Bluetooth device is actually usable for network connections or not into the bluez manager and out of NMManager. The general direction should be towards moving this sort of logic out of the manager and into the device specific stuff, like we did with the WiMAX bits, so we can make stuff into plugins.
This commit is contained in:
parent
4dc5e6c92a
commit
201096b209
7 changed files with 313 additions and 255 deletions
|
|
@ -15,7 +15,7 @@
|
|||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Copyright (C) 2009 - 2010 Red Hat, Inc.
|
||||
* Copyright (C) 2009 - 2012 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#include <glib.h>
|
||||
|
|
@ -41,6 +41,9 @@ typedef struct {
|
|||
|
||||
char *address;
|
||||
GHashTable *devices;
|
||||
|
||||
/* Cached for devices */
|
||||
NMConnectionProvider *provider;
|
||||
} NMBluezAdapterPrivate;
|
||||
|
||||
|
||||
|
|
@ -85,23 +88,18 @@ nm_bluez_adapter_get_initialized (NMBluezAdapter *self)
|
|||
return NM_BLUEZ_ADAPTER_GET_PRIVATE (self)->initialized;
|
||||
}
|
||||
|
||||
static void
|
||||
devices_to_list (gpointer key, gpointer data, gpointer user_data)
|
||||
{
|
||||
NMBluezDevice *device = NM_BLUEZ_DEVICE (data);
|
||||
GSList **list = user_data;
|
||||
|
||||
if (nm_bluez_device_get_usable (device))
|
||||
*list = g_slist_append (*list, data);
|
||||
}
|
||||
|
||||
GSList *
|
||||
nm_bluez_adapter_get_devices (NMBluezAdapter *self)
|
||||
{
|
||||
NMBluezAdapterPrivate *priv = NM_BLUEZ_ADAPTER_GET_PRIVATE (self);
|
||||
GSList *devices = NULL;
|
||||
GHashTableIter iter;
|
||||
NMBluezDevice *device;
|
||||
|
||||
g_hash_table_foreach (priv->devices, devices_to_list, &devices);
|
||||
g_hash_table_iter_init (&iter, NM_BLUEZ_ADAPTER_GET_PRIVATE (self)->devices);
|
||||
while (g_hash_table_iter_next (&iter, NULL, (gpointer) &device)) {
|
||||
if (nm_bluez_device_get_usable (device))
|
||||
devices = g_slist_append (devices, device);
|
||||
}
|
||||
return devices;
|
||||
}
|
||||
|
||||
|
|
@ -109,16 +107,19 @@ static void
|
|||
device_usable (NMBluezDevice *device, GParamSpec *pspec, gpointer user_data)
|
||||
{
|
||||
NMBluezAdapter *self = NM_BLUEZ_ADAPTER (user_data);
|
||||
NMBluezAdapterPrivate *priv = NM_BLUEZ_ADAPTER_GET_PRIVATE (self);
|
||||
gboolean usable = nm_bluez_device_get_usable (device);
|
||||
|
||||
if (nm_bluez_device_get_usable (device))
|
||||
nm_log_dbg (LOGD_BT, "(%s): bluez device now %s",
|
||||
nm_bluez_device_get_path (device),
|
||||
usable ? "usable" : "unusable");
|
||||
|
||||
if (usable) {
|
||||
nm_log_dbg (LOGD_BT, "(%s): bluez device address %s",
|
||||
nm_bluez_device_get_path (device),
|
||||
nm_bluez_device_get_address (device));
|
||||
g_signal_emit (self, signals[DEVICE_ADDED], 0, device);
|
||||
else {
|
||||
g_object_ref (device);
|
||||
g_hash_table_remove (priv->devices, nm_bluez_device_get_path (device));
|
||||
} else
|
||||
g_signal_emit (self, signals[DEVICE_REMOVED], 0, device);
|
||||
g_object_unref (device);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -127,6 +128,9 @@ device_initialized (NMBluezDevice *device, gboolean success, gpointer user_data)
|
|||
NMBluezAdapter *self = NM_BLUEZ_ADAPTER (user_data);
|
||||
NMBluezAdapterPrivate *priv = NM_BLUEZ_ADAPTER_GET_PRIVATE (self);
|
||||
|
||||
nm_log_dbg (LOGD_BT, "(%s): bluez device %s",
|
||||
nm_bluez_device_get_path (device),
|
||||
success ? "initialized" : "failed to initialize");
|
||||
if (!success)
|
||||
g_hash_table_remove (priv->devices, nm_bluez_device_get_path (device));
|
||||
}
|
||||
|
|
@ -138,10 +142,12 @@ device_created (DBusGProxy *proxy, const char *path, gpointer user_data)
|
|||
NMBluezAdapterPrivate *priv = NM_BLUEZ_ADAPTER_GET_PRIVATE (self);
|
||||
NMBluezDevice *device;
|
||||
|
||||
device = nm_bluez_device_new (path);
|
||||
device = nm_bluez_device_new (path, priv->provider);
|
||||
g_signal_connect (device, "initialized", G_CALLBACK (device_initialized), self);
|
||||
g_signal_connect (device, "notify::usable", G_CALLBACK (device_usable), self);
|
||||
g_hash_table_insert (priv->devices, g_strdup (path), device);
|
||||
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);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -151,10 +157,12 @@ device_removed (DBusGProxy *proxy, const char *path, gpointer user_data)
|
|||
NMBluezAdapterPrivate *priv = NM_BLUEZ_ADAPTER_GET_PRIVATE (self);
|
||||
NMBluezDevice *device;
|
||||
|
||||
nm_log_dbg (LOGD_BT, "(%s): bluez device removed", path);
|
||||
|
||||
device = g_hash_table_lookup (priv->devices, path);
|
||||
if (device) {
|
||||
g_object_ref (device);
|
||||
g_hash_table_remove (priv->devices, path);
|
||||
g_hash_table_remove (priv->devices, nm_bluez_device_get_path (device));
|
||||
g_signal_emit (self, signals[DEVICE_REMOVED], 0, device);
|
||||
g_object_unref (device);
|
||||
}
|
||||
|
|
@ -214,8 +222,10 @@ query_properties (NMBluezAdapter *self)
|
|||
}
|
||||
}
|
||||
|
||||
/***********************************************************/
|
||||
|
||||
NMBluezAdapter *
|
||||
nm_bluez_adapter_new (const char *path)
|
||||
nm_bluez_adapter_new (const char *path, NMConnectionProvider *provider)
|
||||
{
|
||||
NMBluezAdapter *self;
|
||||
NMBluezAdapterPrivate *priv;
|
||||
|
|
@ -229,6 +239,9 @@ nm_bluez_adapter_new (const char *path)
|
|||
return NULL;
|
||||
|
||||
priv = NM_BLUEZ_ADAPTER_GET_PRIVATE (self);
|
||||
|
||||
priv->provider = provider;
|
||||
|
||||
dbus_mgr = nm_dbus_manager_get ();
|
||||
connection = nm_dbus_manager_get_connection (dbus_mgr);
|
||||
|
||||
|
|
@ -258,7 +271,23 @@ nm_bluez_adapter_init (NMBluezAdapter *self)
|
|||
NMBluezAdapterPrivate *priv = NM_BLUEZ_ADAPTER_GET_PRIVATE (self);
|
||||
|
||||
priv->devices = g_hash_table_new_full (g_str_hash, g_str_equal,
|
||||
g_free, g_object_unref);
|
||||
NULL, g_object_unref);
|
||||
}
|
||||
|
||||
static void
|
||||
dispose (GObject *object)
|
||||
{
|
||||
NMBluezAdapter *self = NM_BLUEZ_ADAPTER (object);
|
||||
NMBluezAdapterPrivate *priv = NM_BLUEZ_ADAPTER_GET_PRIVATE (self);
|
||||
GHashTableIter iter;
|
||||
NMBluezDevice *device;
|
||||
|
||||
g_hash_table_iter_init (&iter, priv->devices);
|
||||
while (g_hash_table_iter_next (&iter, NULL, (gpointer) &device))
|
||||
g_signal_emit (self, signals[DEVICE_REMOVED], 0, device);
|
||||
g_hash_table_remove_all (priv->devices);
|
||||
|
||||
G_OBJECT_CLASS (nm_bluez_adapter_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -320,6 +349,7 @@ nm_bluez_adapter_class_init (NMBluezAdapterClass *config_class)
|
|||
/* virtual methods */
|
||||
object_class->get_property = get_property;
|
||||
object_class->set_property = set_property;
|
||||
object_class->dispose = dispose;
|
||||
object_class->finalize = finalize;
|
||||
|
||||
/* Properties */
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Copyright (C) 2009 Red Hat, Inc.
|
||||
* Copyright (C) 2009 - 2012 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#ifndef NM_BLUEZ_ADAPTER_H
|
||||
|
|
@ -25,6 +25,7 @@
|
|||
#include <glib-object.h>
|
||||
|
||||
#include "nm-bluez-device.h"
|
||||
#include "nm-connection-provider.h"
|
||||
|
||||
#define NM_TYPE_BLUEZ_ADAPTER (nm_bluez_adapter_get_type ())
|
||||
#define NM_BLUEZ_ADAPTER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_BLUEZ_ADAPTER, NMBluezAdapter))
|
||||
|
|
@ -53,7 +54,8 @@ typedef struct {
|
|||
|
||||
GType nm_bluez_adapter_get_type (void);
|
||||
|
||||
NMBluezAdapter *nm_bluez_adapter_new (const char *path);
|
||||
NMBluezAdapter *nm_bluez_adapter_new (const char *path,
|
||||
NMConnectionProvider *provider);
|
||||
|
||||
const char *nm_bluez_adapter_get_path (NMBluezAdapter *self);
|
||||
|
||||
|
|
|
|||
|
|
@ -15,13 +15,17 @@
|
|||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Copyright (C) 2009 - 2010 Red Hat, Inc.
|
||||
* Copyright (C) 2009 - 2012 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#include <glib.h>
|
||||
#include <string.h>
|
||||
#include <net/ethernet.h>
|
||||
#include <netinet/ether.h>
|
||||
|
||||
#include "NetworkManager.h"
|
||||
#include "nm-setting-bluetooth.h"
|
||||
|
||||
#include "nm-dbus-manager.h"
|
||||
#include "nm-bluez-device.h"
|
||||
#include "nm-bluez-common.h"
|
||||
|
|
@ -41,9 +45,13 @@ typedef struct {
|
|||
gboolean usable;
|
||||
|
||||
char *address;
|
||||
guint8 bin_address[ETH_ALEN];
|
||||
char *name;
|
||||
guint32 capabilities;
|
||||
gint rssi;
|
||||
|
||||
NMConnectionProvider *provider;
|
||||
GSList *connections;
|
||||
} NMBluezDevicePrivate;
|
||||
|
||||
|
||||
|
|
@ -66,6 +74,8 @@ enum {
|
|||
};
|
||||
static guint signals[LAST_SIGNAL] = { 0 };
|
||||
|
||||
/***********************************************************/
|
||||
|
||||
const char *
|
||||
nm_bluez_device_get_path (NMBluezDevice *self)
|
||||
{
|
||||
|
|
@ -122,6 +132,111 @@ nm_bluez_device_get_rssi (NMBluezDevice *self)
|
|||
return NM_BLUEZ_DEVICE_GET_PRIVATE (self)->rssi;
|
||||
}
|
||||
|
||||
static void
|
||||
check_emit_usable (NMBluezDevice *self)
|
||||
{
|
||||
NMBluezDevicePrivate *priv = NM_BLUEZ_DEVICE_GET_PRIVATE (self);
|
||||
gboolean new_usable;
|
||||
|
||||
new_usable = (priv->initialized && priv->capabilities && priv->name && priv->address && priv->connections);
|
||||
if (new_usable != priv->usable) {
|
||||
priv->usable = new_usable;
|
||||
g_object_notify (G_OBJECT (self), NM_BLUEZ_DEVICE_USABLE);
|
||||
}
|
||||
}
|
||||
|
||||
/********************************************************************/
|
||||
|
||||
static gboolean
|
||||
connection_compatible (NMBluezDevice *self, NMConnection *connection)
|
||||
{
|
||||
NMBluezDevicePrivate *priv = NM_BLUEZ_DEVICE_GET_PRIVATE (self);
|
||||
NMSettingBluetooth *s_bt;
|
||||
const char *bt_type;
|
||||
const GByteArray *bdaddr;
|
||||
|
||||
if (!nm_connection_is_type (connection, NM_SETTING_BLUETOOTH_SETTING_NAME))
|
||||
return FALSE;
|
||||
|
||||
s_bt = nm_connection_get_setting_bluetooth (connection);
|
||||
if (!s_bt)
|
||||
return FALSE;
|
||||
|
||||
bdaddr = nm_setting_bluetooth_get_bdaddr (s_bt);
|
||||
if (!bdaddr || bdaddr->len != ETH_ALEN)
|
||||
return FALSE;
|
||||
if (memcmp (bdaddr->data, priv->bin_address, ETH_ALEN) != 0)
|
||||
return FALSE;
|
||||
|
||||
bt_type = nm_setting_bluetooth_get_connection_type (s_bt);
|
||||
if ( g_str_equal (bt_type, NM_SETTING_BLUETOOTH_TYPE_DUN)
|
||||
&& !(priv->capabilities & NM_BT_CAPABILITY_DUN))
|
||||
return FALSE;
|
||||
|
||||
if ( g_str_equal (bt_type, NM_SETTING_BLUETOOTH_TYPE_PANU)
|
||||
&& !(priv->capabilities & NM_BT_CAPABILITY_NAP))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
_internal_add_connection (NMBluezDevice *self, NMConnection *connection)
|
||||
{
|
||||
NMBluezDevicePrivate *priv = NM_BLUEZ_DEVICE_GET_PRIVATE (self);
|
||||
|
||||
if (!g_slist_find (priv->connections, connection)) {
|
||||
priv->connections = g_slist_prepend (priv->connections, g_object_ref (connection));
|
||||
check_emit_usable (self);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
cp_connection_added (NMConnectionProvider *provider,
|
||||
NMConnection *connection,
|
||||
NMBluezDevice *self)
|
||||
{
|
||||
if (connection_compatible (self, connection))
|
||||
_internal_add_connection (self, connection);
|
||||
}
|
||||
|
||||
static void
|
||||
cp_connection_removed (NMConnectionProvider *provider,
|
||||
NMConnection *connection,
|
||||
NMBluezDevice *self)
|
||||
{
|
||||
NMBluezDevicePrivate *priv = NM_BLUEZ_DEVICE_GET_PRIVATE (self);
|
||||
|
||||
if (g_slist_find (priv->connections, connection)) {
|
||||
priv->connections = g_slist_remove (priv->connections, connection);
|
||||
g_object_unref (connection);
|
||||
check_emit_usable (self);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
cp_connection_updated (NMConnectionProvider *provider,
|
||||
NMConnection *connection,
|
||||
NMBluezDevice *self)
|
||||
{
|
||||
if (connection_compatible (self, connection))
|
||||
_internal_add_connection (self, connection);
|
||||
else
|
||||
cp_connection_removed (provider, connection, self);
|
||||
}
|
||||
|
||||
static void
|
||||
cp_connections_loaded (NMConnectionProvider *provider, NMBluezDevice *self)
|
||||
{
|
||||
const GSList *connections, *iter;
|
||||
|
||||
connections = nm_connection_provider_get_connections (provider);
|
||||
for (iter = connections; iter; iter = g_slist_next (iter))
|
||||
cp_connection_added (provider, NM_CONNECTION (iter->data), self);
|
||||
}
|
||||
|
||||
/***********************************************************/
|
||||
|
||||
static guint32
|
||||
convert_uuids_to_capabilities (const char **strings)
|
||||
{
|
||||
|
|
@ -130,53 +245,26 @@ convert_uuids_to_capabilities (const char **strings)
|
|||
|
||||
for (iter = strings; iter && *iter; iter++) {
|
||||
char **parts;
|
||||
guint uuid16;
|
||||
|
||||
parts = g_strsplit (*iter, "-", -1);
|
||||
if (parts == NULL || parts[0] == NULL) {
|
||||
g_strfreev (parts);
|
||||
continue;
|
||||
if (parts && parts[0]) {
|
||||
switch (g_ascii_strtoull (parts[0], NULL, 16)) {
|
||||
case 0x1103:
|
||||
capabilities |= NM_BT_CAPABILITY_DUN;
|
||||
break;
|
||||
case 0x1116:
|
||||
capabilities |= NM_BT_CAPABILITY_NAP;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uuid16 = g_ascii_strtoull (parts[0], NULL, 16);
|
||||
g_strfreev (parts);
|
||||
|
||||
switch (uuid16) {
|
||||
case 0x1103:
|
||||
capabilities |= NM_BT_CAPABILITY_DUN;
|
||||
break;
|
||||
case 0x1116:
|
||||
capabilities |= NM_BT_CAPABILITY_NAP;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return capabilities;
|
||||
}
|
||||
|
||||
static void
|
||||
check_emit_usable (NMBluezDevice *self)
|
||||
{
|
||||
NMBluezDevicePrivate *priv = NM_BLUEZ_DEVICE_GET_PRIVATE (self);
|
||||
|
||||
if ( priv->initialized
|
||||
&& priv->capabilities
|
||||
&& priv->name
|
||||
&& priv->address) {
|
||||
if (!priv->usable) {
|
||||
priv->usable = TRUE;
|
||||
g_object_notify (G_OBJECT (self), NM_BLUEZ_DEVICE_USABLE);
|
||||
}
|
||||
} else {
|
||||
if (priv->usable) {
|
||||
priv->usable = FALSE;
|
||||
g_object_notify (G_OBJECT (self), NM_BLUEZ_DEVICE_USABLE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
property_changed (DBusGProxy *proxy,
|
||||
const char *property,
|
||||
|
|
@ -224,6 +312,7 @@ get_properties_cb (DBusGProxy *proxy, DBusGProxyCall *call, gpointer user_data)
|
|||
GError *err = NULL;
|
||||
GValue *value;
|
||||
const char **uuids;
|
||||
struct ether_addr *tmp;
|
||||
|
||||
if (!dbus_g_proxy_end_call (proxy, call, &err,
|
||||
DBUS_TYPE_G_MAP_OF_VARIANT, &properties,
|
||||
|
|
@ -237,6 +326,11 @@ get_properties_cb (DBusGProxy *proxy, DBusGProxyCall *call, gpointer user_data)
|
|||
|
||||
value = g_hash_table_lookup (properties, "Address");
|
||||
priv->address = value ? g_value_dup_string (value) : NULL;
|
||||
if (priv->address) {
|
||||
tmp = ether_aton (priv->address);
|
||||
g_assert (tmp);
|
||||
memcpy (priv->bin_address, tmp->ether_addr_octet, ETH_ALEN);
|
||||
}
|
||||
|
||||
value = g_hash_table_lookup (properties, "Name");
|
||||
priv->name = value ? g_value_dup_string (value) : NULL;
|
||||
|
|
@ -253,6 +347,9 @@ get_properties_cb (DBusGProxy *proxy, DBusGProxyCall *call, gpointer user_data)
|
|||
|
||||
g_hash_table_unref (properties);
|
||||
|
||||
/* Check if any connections match this device */
|
||||
cp_connections_loaded (priv->provider, self);
|
||||
|
||||
priv->initialized = TRUE;
|
||||
g_signal_emit (self, signals[INITIALIZED], 0, TRUE);
|
||||
|
||||
|
|
@ -275,14 +372,18 @@ query_properties (NMBluezDevice *self)
|
|||
}
|
||||
}
|
||||
|
||||
/********************************************************************/
|
||||
|
||||
NMBluezDevice *
|
||||
nm_bluez_device_new (const char *path)
|
||||
nm_bluez_device_new (const char *path, NMConnectionProvider *provider)
|
||||
{
|
||||
NMBluezDevice *self;
|
||||
NMBluezDevicePrivate *priv;
|
||||
NMDBusManager *dbus_mgr;
|
||||
DBusGConnection *connection;
|
||||
|
||||
g_return_val_if_fail (path != NULL, NULL);
|
||||
g_return_val_if_fail (provider != NULL, NULL);
|
||||
|
||||
self = (NMBluezDevice *) g_object_new (NM_TYPE_BLUEZ_DEVICE,
|
||||
NM_BLUEZ_DEVICE_PATH, path,
|
||||
|
|
@ -291,6 +392,29 @@ nm_bluez_device_new (const char *path)
|
|||
return NULL;
|
||||
|
||||
priv = NM_BLUEZ_DEVICE_GET_PRIVATE (self);
|
||||
|
||||
priv->provider = provider;
|
||||
|
||||
g_signal_connect (priv->provider,
|
||||
NM_CP_SIGNAL_CONNECTION_ADDED,
|
||||
G_CALLBACK (cp_connection_added),
|
||||
self);
|
||||
|
||||
g_signal_connect (priv->provider,
|
||||
NM_CP_SIGNAL_CONNECTION_REMOVED,
|
||||
G_CALLBACK (cp_connection_removed),
|
||||
self);
|
||||
|
||||
g_signal_connect (priv->provider,
|
||||
NM_CP_SIGNAL_CONNECTION_UPDATED,
|
||||
G_CALLBACK (cp_connection_updated),
|
||||
self);
|
||||
|
||||
g_signal_connect (priv->provider,
|
||||
NM_CP_SIGNAL_CONNECTIONS_LOADED,
|
||||
G_CALLBACK (cp_connections_loaded),
|
||||
self);
|
||||
|
||||
dbus_mgr = nm_dbus_manager_get ();
|
||||
connection = nm_dbus_manager_get_connection (dbus_mgr);
|
||||
|
||||
|
|
@ -318,6 +442,24 @@ nm_bluez_device_init (NMBluezDevice *self)
|
|||
{
|
||||
}
|
||||
|
||||
static void
|
||||
dispose (GObject *object)
|
||||
{
|
||||
NMBluezDevice *self = NM_BLUEZ_DEVICE (object);
|
||||
NMBluezDevicePrivate *priv = NM_BLUEZ_DEVICE_GET_PRIVATE (self);
|
||||
|
||||
g_slist_foreach (priv->connections, (GFunc) g_object_unref, NULL);
|
||||
g_slist_free (priv->connections);
|
||||
priv->connections = NULL;
|
||||
|
||||
g_signal_handlers_disconnect_by_func (priv->provider, cp_connection_added, self);
|
||||
g_signal_handlers_disconnect_by_func (priv->provider, cp_connection_removed, self);
|
||||
g_signal_handlers_disconnect_by_func (priv->provider, cp_connection_updated, self);
|
||||
g_signal_handlers_disconnect_by_func (priv->provider, cp_connections_loaded, self);
|
||||
|
||||
G_OBJECT_CLASS (nm_bluez_device_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
finalize (GObject *object)
|
||||
{
|
||||
|
|
@ -389,6 +531,7 @@ nm_bluez_device_class_init (NMBluezDeviceClass *config_class)
|
|||
/* virtual methods */
|
||||
object_class->get_property = get_property;
|
||||
object_class->set_property = set_property;
|
||||
object_class->dispose = dispose;
|
||||
object_class->finalize = finalize;
|
||||
|
||||
/* Properties */
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Copyright (C) 2009 Red Hat, Inc.
|
||||
* Copyright (C) 2009 - 2012 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#ifndef NM_BLUEZ_DEVICE_H
|
||||
|
|
@ -24,6 +24,9 @@
|
|||
#include <glib.h>
|
||||
#include <glib-object.h>
|
||||
|
||||
#include "nm-connection.h"
|
||||
#include "nm-connection-provider.h"
|
||||
|
||||
#define NM_TYPE_BLUEZ_DEVICE (nm_bluez_device_get_type ())
|
||||
#define NM_BLUEZ_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_BLUEZ_DEVICE, NMBluezDevice))
|
||||
#define NM_BLUEZ_DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_BLUEZ_DEVICE, NMBluezDeviceClass))
|
||||
|
|
@ -53,7 +56,7 @@ typedef struct {
|
|||
|
||||
GType nm_bluez_device_get_type (void);
|
||||
|
||||
NMBluezDevice *nm_bluez_device_new (const char *path);
|
||||
NMBluezDevice *nm_bluez_device_new (const char *path, NMConnectionProvider *provider);
|
||||
|
||||
const char *nm_bluez_device_get_path (NMBluezDevice *self);
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Copyright (C) 2007 - 2008 Novell, Inc.
|
||||
* Copyright (C) 2007 - 2010 Red Hat, Inc.
|
||||
* Copyright (C) 2007 - 2012 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#include <signal.h>
|
||||
|
|
@ -37,6 +37,8 @@ typedef struct {
|
|||
NMDBusManager *dbus_mgr;
|
||||
gulong name_owner_changed_id;
|
||||
|
||||
NMConnectionProvider *provider;
|
||||
|
||||
DBusGProxy *proxy;
|
||||
|
||||
NMBluezAdapter *adapter;
|
||||
|
|
@ -165,7 +167,7 @@ default_adapter_changed (DBusGProxy *proxy, const char *path, NMBluezManager *se
|
|||
|
||||
/* Add the new default adapter */
|
||||
if (path) {
|
||||
priv->adapter = nm_bluez_adapter_new (path);
|
||||
priv->adapter = nm_bluez_adapter_new (path, priv->provider);
|
||||
g_signal_connect (priv->adapter, "initialized", G_CALLBACK (adapter_initialized), self);
|
||||
}
|
||||
}
|
||||
|
|
@ -237,12 +239,6 @@ bluez_connect (NMBluezManager *self)
|
|||
query_default_adapter (self);
|
||||
}
|
||||
|
||||
static void
|
||||
remove_all_devices (NMBluezManager *self, gboolean do_signal)
|
||||
{
|
||||
/* FIXME: do something */
|
||||
}
|
||||
|
||||
static void
|
||||
name_owner_changed_cb (NMDBusManager *dbus_mgr,
|
||||
const char *name,
|
||||
|
|
@ -251,6 +247,7 @@ name_owner_changed_cb (NMDBusManager *dbus_mgr,
|
|||
gpointer user_data)
|
||||
{
|
||||
NMBluezManager *self = NM_BLUEZ_MANAGER (user_data);
|
||||
NMBluezManagerPrivate *priv = NM_BLUEZ_MANAGER_GET_PRIVATE (self);
|
||||
gboolean old_owner_good = (old_owner && strlen (old_owner));
|
||||
gboolean new_owner_good = (new_owner && strlen (new_owner));
|
||||
|
||||
|
|
@ -260,8 +257,13 @@ name_owner_changed_cb (NMDBusManager *dbus_mgr,
|
|||
|
||||
if (!old_owner_good && new_owner_good)
|
||||
query_default_adapter (self);
|
||||
else if (old_owner_good && !new_owner_good)
|
||||
remove_all_devices (self, TRUE);
|
||||
else if (old_owner_good && !new_owner_good) {
|
||||
/* Throwing away the adapter removes all devices too */
|
||||
if (priv->adapter) {
|
||||
g_object_unref (priv->adapter);
|
||||
priv->adapter = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -274,7 +276,10 @@ bluez_cleanup (NMBluezManager *self, gboolean do_signal)
|
|||
priv->proxy = NULL;
|
||||
}
|
||||
|
||||
remove_all_devices (self, do_signal);
|
||||
if (priv->adapter) {
|
||||
g_object_unref (priv->adapter);
|
||||
priv->adapter = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -290,24 +295,22 @@ dbus_connection_changed_cb (NMDBusManager *dbus_mgr,
|
|||
bluez_connect (self);
|
||||
}
|
||||
|
||||
/****************************************************************/
|
||||
|
||||
NMBluezManager *
|
||||
nm_bluez_manager_new (void)
|
||||
{
|
||||
return NM_BLUEZ_MANAGER (g_object_new (NM_TYPE_BLUEZ_MANAGER, NULL));
|
||||
}
|
||||
|
||||
NMBluezManager *
|
||||
nm_bluez_manager_get (void)
|
||||
nm_bluez_manager_get (NMConnectionProvider *provider)
|
||||
{
|
||||
static NMBluezManager *singleton = NULL;
|
||||
|
||||
if (!singleton)
|
||||
singleton = nm_bluez_manager_new ();
|
||||
else
|
||||
g_object_ref (singleton);
|
||||
if (singleton)
|
||||
return g_object_ref (singleton);
|
||||
|
||||
singleton = (NMBluezManager *) g_object_new (NM_TYPE_BLUEZ_MANAGER, NULL);
|
||||
g_assert (singleton);
|
||||
|
||||
/* Cache the connection provider for NMBluezAdapter objects */
|
||||
NM_BLUEZ_MANAGER_GET_PRIVATE (singleton)->provider = provider;
|
||||
|
||||
return singleton;
|
||||
}
|
||||
|
||||
|
|
@ -333,13 +336,20 @@ nm_bluez_manager_init (NMBluezManager *self)
|
|||
}
|
||||
|
||||
static void
|
||||
finalize (GObject *object)
|
||||
dispose (GObject *object)
|
||||
{
|
||||
NMBluezManager *self = NM_BLUEZ_MANAGER (object);
|
||||
NMBluezManagerPrivate *priv = NM_BLUEZ_MANAGER_GET_PRIVATE (self);
|
||||
|
||||
bluez_cleanup (self, FALSE);
|
||||
|
||||
G_OBJECT_CLASS (nm_bluez_manager_parent_class)->finalize (object);
|
||||
if (priv->dbus_mgr) {
|
||||
g_signal_handlers_disconnect_by_func (priv->dbus_mgr, name_owner_changed_cb, self);
|
||||
g_signal_handlers_disconnect_by_func (priv->dbus_mgr, dbus_connection_changed_cb, self);
|
||||
g_object_unref (priv->dbus_mgr);
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (nm_bluez_manager_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -350,11 +360,11 @@ nm_bluez_manager_class_init (NMBluezManagerClass *klass)
|
|||
g_type_class_add_private (klass, sizeof (NMBluezManagerPrivate));
|
||||
|
||||
/* virtual methods */
|
||||
object_class->finalize = finalize;
|
||||
object_class->dispose = dispose;
|
||||
|
||||
/* Signals */
|
||||
signals[BDADDR_ADDED] =
|
||||
g_signal_new ("bdaddr-added",
|
||||
g_signal_new (NM_BLUEZ_MANAGER_BDADDR_ADDED,
|
||||
G_OBJECT_CLASS_TYPE (object_class),
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
G_STRUCT_OFFSET (NMBluezManagerClass, bdaddr_added),
|
||||
|
|
@ -363,7 +373,7 @@ nm_bluez_manager_class_init (NMBluezManagerClass *klass)
|
|||
G_TYPE_NONE, 4, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_UINT);
|
||||
|
||||
signals[BDADDR_REMOVED] =
|
||||
g_signal_new ("bdaddr-removed",
|
||||
g_signal_new (NM_BLUEZ_MANAGER_BDADDR_REMOVED,
|
||||
G_OBJECT_CLASS_TYPE (object_class),
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
G_STRUCT_OFFSET (NMBluezManagerClass, bdaddr_removed),
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Copyright (C) 2007 - 2008 Novell, Inc.
|
||||
* Copyright (C) 2007 - 2009 Red Hat, Inc.
|
||||
* Copyright (C) 2007 - 2012 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#ifndef NM_BLUEZ_MANAGER_H
|
||||
|
|
@ -25,6 +25,8 @@
|
|||
#include <glib.h>
|
||||
#include <glib-object.h>
|
||||
|
||||
#include "nm-connection-provider.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define NM_TYPE_BLUEZ_MANAGER (nm_bluez_manager_get_type ())
|
||||
|
|
@ -34,6 +36,9 @@ G_BEGIN_DECLS
|
|||
#define NM_IS_BLUEZ_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_BLUEZ_MANAGER))
|
||||
#define NM_BLUEZ_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_BLUEZ_MANAGER, NMBluezManagerClass))
|
||||
|
||||
#define NM_BLUEZ_MANAGER_BDADDR_ADDED "bdaddr-added"
|
||||
#define NM_BLUEZ_MANAGER_BDADDR_REMOVED "bdaddr-removed"
|
||||
|
||||
typedef struct {
|
||||
GObject parent;
|
||||
} NMBluezManager;
|
||||
|
|
@ -55,8 +60,8 @@ typedef struct {
|
|||
|
||||
GType nm_bluez_manager_get_type (void);
|
||||
|
||||
NMBluezManager *nm_bluez_manager_new (void);
|
||||
NMBluezManager *nm_bluez_manager_get (void);
|
||||
NMBluezManager *nm_bluez_manager_get (NMConnectionProvider *provider);
|
||||
|
||||
void nm_bluez_manager_query_devices (NMBluezManager *manager);
|
||||
|
||||
#endif /* NM_BLUEZ_MANAGER_H */
|
||||
|
|
|
|||
177
src/nm-manager.c
177
src/nm-manager.c
|
|
@ -127,18 +127,16 @@ static gboolean impl_manager_set_logging (NMManager *manager,
|
|||
#include "nm-manager-glue.h"
|
||||
|
||||
static void bluez_manager_bdaddr_added_cb (NMBluezManager *bluez_mgr,
|
||||
const char *bdaddr,
|
||||
const char *name,
|
||||
const char *object_path,
|
||||
guint32 uuids,
|
||||
NMManager *manager);
|
||||
const char *bdaddr,
|
||||
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 bluez_manager_resync_devices (NMManager *self);
|
||||
const char *bdaddr,
|
||||
const char *object_path,
|
||||
gpointer user_data);
|
||||
|
||||
static void add_device (NMManager *self, NMDevice *device);
|
||||
|
||||
|
|
@ -1160,8 +1158,6 @@ connection_added (NMSettings *settings,
|
|||
NMSettingsConnection *connection,
|
||||
NMManager *manager)
|
||||
{
|
||||
bluez_manager_resync_devices (manager);
|
||||
|
||||
if (connection_needs_virtual_device (NM_CONNECTION (connection)))
|
||||
system_create_virtual_device (manager, NM_CONNECTION (connection));
|
||||
}
|
||||
|
|
@ -1171,8 +1167,6 @@ connection_changed (NMSettings *settings,
|
|||
NMSettingsConnection *connection,
|
||||
NMManager *manager)
|
||||
{
|
||||
bluez_manager_resync_devices (manager);
|
||||
|
||||
/* FIXME: Some virtual devices may need to be updated in the future. */
|
||||
}
|
||||
|
||||
|
|
@ -1181,8 +1175,6 @@ connection_removed (NMSettings *settings,
|
|||
NMSettingsConnection *connection,
|
||||
NMManager *manager)
|
||||
{
|
||||
bluez_manager_resync_devices (manager);
|
||||
|
||||
/*
|
||||
* Do not delete existing virtual devices to keep connectivity up.
|
||||
* Virtual devices are reused when NetworkManager is restarted.
|
||||
|
|
@ -1793,120 +1785,6 @@ add_device (NMManager *self, NMDevice *device)
|
|||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
bdaddr_matches_connection (NMSettingBluetooth *s_bt, const char *bdaddr)
|
||||
{
|
||||
const GByteArray *arr;
|
||||
gboolean ret = FALSE;
|
||||
|
||||
arr = nm_setting_bluetooth_get_bdaddr (s_bt);
|
||||
|
||||
if ( arr != NULL
|
||||
&& arr->len == ETH_ALEN) {
|
||||
char *str;
|
||||
|
||||
str = g_strdup_printf ("%02X:%02X:%02X:%02X:%02X:%02X",
|
||||
arr->data[0],
|
||||
arr->data[1],
|
||||
arr->data[2],
|
||||
arr->data[3],
|
||||
arr->data[4],
|
||||
arr->data[5]);
|
||||
ret = g_str_equal (str, bdaddr);
|
||||
g_free (str);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static NMConnection *
|
||||
bluez_manager_find_connection (NMManager *manager,
|
||||
const char *bdaddr,
|
||||
guint32 capabilities)
|
||||
{
|
||||
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
|
||||
NMConnection *found = NULL;
|
||||
GSList *connections, *l;
|
||||
|
||||
connections = nm_settings_get_connections (priv->settings);
|
||||
|
||||
for (l = connections; l != NULL; l = l->next) {
|
||||
NMConnection *candidate = NM_CONNECTION (l->data);
|
||||
NMSettingConnection *s_con;
|
||||
NMSettingBluetooth *s_bt;
|
||||
const char *con_type;
|
||||
const char *bt_type;
|
||||
|
||||
s_con = nm_connection_get_setting_connection (candidate);
|
||||
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 = nm_connection_get_setting_bluetooth (candidate);
|
||||
if (!s_bt)
|
||||
continue;
|
||||
|
||||
if (!bdaddr_matches_connection (s_bt, bdaddr))
|
||||
continue;
|
||||
|
||||
bt_type = nm_setting_bluetooth_get_connection_type (s_bt);
|
||||
if ( g_str_equal (bt_type, NM_SETTING_BLUETOOTH_TYPE_DUN)
|
||||
&& !(capabilities & NM_BT_CAPABILITY_DUN))
|
||||
continue;
|
||||
if ( g_str_equal (bt_type, NM_SETTING_BLUETOOTH_TYPE_PANU)
|
||||
&& !(capabilities & NM_BT_CAPABILITY_NAP))
|
||||
continue;
|
||||
|
||||
found = candidate;
|
||||
break;
|
||||
}
|
||||
|
||||
g_slist_free (connections);
|
||||
return found;
|
||||
}
|
||||
|
||||
static void
|
||||
bluez_manager_resync_devices (NMManager *self)
|
||||
{
|
||||
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
||||
GSList *iter, *gone = NULL, *keep = NULL;
|
||||
|
||||
/* Remove devices from the device list that don't have a corresponding connection */
|
||||
for (iter = priv->devices; iter; iter = g_slist_next (iter)) {
|
||||
NMDevice *candidate = NM_DEVICE (iter->data);
|
||||
guint32 uuids;
|
||||
const char *bdaddr;
|
||||
|
||||
if (nm_device_get_device_type (candidate) == NM_DEVICE_TYPE_BT) {
|
||||
uuids = nm_device_bt_get_capabilities (NM_DEVICE_BT (candidate));
|
||||
bdaddr = nm_device_bt_get_hw_address (NM_DEVICE_BT (candidate));
|
||||
|
||||
if (bluez_manager_find_connection (self, bdaddr, uuids))
|
||||
keep = g_slist_prepend (keep, candidate);
|
||||
else
|
||||
gone = g_slist_prepend (gone, candidate);
|
||||
} else
|
||||
keep = g_slist_prepend (keep, candidate);
|
||||
}
|
||||
|
||||
/* Only touch the device list if anything actually changed */
|
||||
if (g_slist_length (gone)) {
|
||||
g_slist_free (priv->devices);
|
||||
priv->devices = keep;
|
||||
|
||||
while (g_slist_length (gone))
|
||||
gone = remove_one_device (self, gone, NM_DEVICE (gone->data), FALSE);
|
||||
} else {
|
||||
g_slist_free (keep);
|
||||
g_slist_free (gone);
|
||||
}
|
||||
|
||||
/* Now look for devices without connections */
|
||||
nm_bluez_manager_query_devices (priv->bluez_mgr);
|
||||
}
|
||||
|
||||
static void
|
||||
bluez_manager_bdaddr_added_cb (NMBluezManager *bluez_mgr,
|
||||
const char *bdaddr,
|
||||
|
|
@ -1928,12 +1806,6 @@ bluez_manager_bdaddr_added_cb (NMBluezManager *bluez_mgr,
|
|||
if (nm_manager_get_device_by_udi (manager, object_path))
|
||||
return;
|
||||
|
||||
if (has_dun == FALSE && has_nap == FALSE)
|
||||
return;
|
||||
|
||||
if (!bluez_manager_find_connection (manager, bdaddr, capabilities))
|
||||
return;
|
||||
|
||||
device = nm_device_bt_new (object_path, bdaddr, name, capabilities, FALSE);
|
||||
if (device) {
|
||||
nm_log_info (LOGD_HW, "BT device %s (%s) added (%s%s%s)",
|
||||
|
|
@ -1955,19 +1827,15 @@ bluez_manager_bdaddr_removed_cb (NMBluezManager *bluez_mgr,
|
|||
{
|
||||
NMManager *self = NM_MANAGER (user_data);
|
||||
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
||||
GSList *iter;
|
||||
NMDevice *device;
|
||||
|
||||
g_return_if_fail (bdaddr != NULL);
|
||||
g_return_if_fail (object_path != NULL);
|
||||
|
||||
for (iter = priv->devices; iter; iter = iter->next) {
|
||||
NMDevice *device = NM_DEVICE (iter->data);
|
||||
|
||||
if (!strcmp (nm_device_get_udi (device), object_path)) {
|
||||
nm_log_info (LOGD_HW, "BT device %s removed", bdaddr);
|
||||
priv->devices = remove_one_device (self, priv->devices, device, FALSE);
|
||||
break;
|
||||
}
|
||||
device = nm_manager_get_device_by_udi (self, object_path);
|
||||
if (device) {
|
||||
nm_log_info (LOGD_HW, "BT device %s removed", bdaddr);
|
||||
priv->devices = remove_one_device (self, priv->devices, device, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3254,9 +3122,6 @@ do_sleep_wake (NMManager *self)
|
|||
else
|
||||
nm_device_set_managed (device, TRUE, NM_DEVICE_STATE_REASON_NOW_MANAGED);
|
||||
}
|
||||
|
||||
/* Ask for new bluetooth devices */
|
||||
bluez_manager_resync_devices (self);
|
||||
}
|
||||
|
||||
nm_manager_update_state (self);
|
||||
|
|
@ -3673,7 +3538,7 @@ nm_manager_start (NMManager *self)
|
|||
system_hostname_changed_cb (priv->settings, NULL, self);
|
||||
|
||||
nm_udev_manager_query_devices (priv->udev_mgr);
|
||||
bluez_manager_resync_devices (self);
|
||||
nm_bluez_manager_query_devices (priv->bluez_mgr);
|
||||
|
||||
/* Query devices again to ensure that we catch all virtual interfaces (like
|
||||
* VLANs) that require a parent. If during the first pass the VLAN
|
||||
|
|
@ -4015,17 +3880,17 @@ nm_manager_new (NMSettings *settings,
|
|||
G_CALLBACK (udev_manager_rfkill_changed_cb),
|
||||
singleton);
|
||||
|
||||
priv->bluez_mgr = nm_bluez_manager_get ();
|
||||
priv->bluez_mgr = nm_bluez_manager_get (NM_CONNECTION_PROVIDER (priv->settings));
|
||||
|
||||
g_signal_connect (priv->bluez_mgr,
|
||||
"bdaddr-added",
|
||||
G_CALLBACK (bluez_manager_bdaddr_added_cb),
|
||||
singleton);
|
||||
NM_BLUEZ_MANAGER_BDADDR_ADDED,
|
||||
G_CALLBACK (bluez_manager_bdaddr_added_cb),
|
||||
singleton);
|
||||
|
||||
g_signal_connect (priv->bluez_mgr,
|
||||
"bdaddr-removed",
|
||||
G_CALLBACK (bluez_manager_bdaddr_removed_cb),
|
||||
singleton);
|
||||
NM_BLUEZ_MANAGER_BDADDR_REMOVED,
|
||||
G_CALLBACK (bluez_manager_bdaddr_removed_cb),
|
||||
singleton);
|
||||
|
||||
return singleton;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue