mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager
synced 2024-07-22 10:46:59 +00:00
bluetooth: refactor BlueZ handling and let NMBluezManager cache ObjectManager data
This is a complete refactoring of the bluetooth code. Now that BlueZ 4 support was dropped, the separation of NMBluezManager and NMBluez5Manager makes no sense. They should be merged. At that point, notice that BlueZ 5's D-Bus API is fully centered around D-Bus's ObjectManager interface. Using that interface, we basically only call GetManagedObjects() once and register to InterfacesAdded, InterfacesRemoved and PropertiesChanged signals. There is no need to fetch individual properties ever. Note how NMBluezDevice used to query the D-Bus properties itself by creating a GDBusProxy. This is redundant, because when using the ObjectManager interfaces, we have all information already. Instead, let NMBluezManager basically become the client-side cache of all of BlueZ's ObjectManager interface. NMBluezDevice was mostly concerned about caching the D-Bus interface's state, tracking suitable profiles (pan_connection), and moderate between bluez and NMDeviceBt. These tasks don't get simpler by moving them to a seprate file. Let them also be handled by NMBluezManager. I mean, just look how it was previously: NMBluez5Manager registers to ObjectManager interface and sees a device appearing. It creates a NMBluezDevice object and registers to its "initialized" and "notify:usable" signal. In the meantime, NMBluezDevice fetches the relevant information from D-Bus (although it was already present in the data provided by the ObjectManager) and eventually emits these usable and initialized signals. Then, NMBlue5Manager emits a "bdaddr-added" signal, for which NMBluezManager creates the NMDeviceBt instance. NMBluezManager, NMBluez5Manager and NMBluezDevice are strongly cooperating to the point that it is simpler to merge them. This is not mere refactoring. This patch aims to make everything asynchronously and always cancellable. Also, it aims to fix races and inconsistencies of the state. - Registering to a NAP server now waits for the response and delays activation of the NMDeviceBridge accordingly. - For NAP connections we now watch the bnep0 interface in platform, and tear down the device when it goes away. Bluez doesn't send us a notification on D-Bus in that case. - Rework establishing a DUN connection. It no longer uses blocking connect() and does not block until rfcomm device appears. It's all async now. It also watches the rfcomm file descriptor for POLLERR/POLLHUP to notice disconnect. - drop nm_device_factory_emit_component_added() and instead let NMDeviceBt directly register to the WWan factory's "added" signal.
This commit is contained in:
parent
878d4963ed
commit
4154d9618c
|
@ -3441,11 +3441,8 @@ $(src_devices_bluetooth_libnm_bluetooth_utils_la_OBJECTS): $(libnm_core_lib_h_pu
|
|||
core_plugins += src/devices/bluetooth/libnm-device-plugin-bluetooth.la
|
||||
|
||||
src_devices_bluetooth_libnm_device_plugin_bluetooth_la_SOURCES = \
|
||||
src/devices/bluetooth/nm-bluez-device.c \
|
||||
src/devices/bluetooth/nm-bluez-device.h \
|
||||
src/devices/bluetooth/nm-bluez-manager.c \
|
||||
src/devices/bluetooth/nm-bluez5-manager.c \
|
||||
src/devices/bluetooth/nm-bluez5-manager.h \
|
||||
src/devices/bluetooth/nm-bluez-manager.h \
|
||||
src/devices/bluetooth/nm-device-bt.c \
|
||||
src/devices/bluetooth/nm-device-bt.h \
|
||||
$(NULL)
|
||||
|
|
|
@ -131,6 +131,10 @@ _nm_setting_secret_flags_valid (NMSettingSecretFlags flags)
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
const char *nm_bluetooth_capability_to_string (NMBluetoothCapabilities capabilities, char *buf, gsize len);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
typedef enum { /*< skip >*/
|
||||
NM_SETTING_PARSE_FLAGS_NONE = 0,
|
||||
NM_SETTING_PARSE_FLAGS_STRICT = 1LL << 0,
|
||||
|
|
|
@ -5812,6 +5812,14 @@ nm_utils_version (void)
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
NM_UTILS_FLAGS2STR_DEFINE (nm_bluetooth_capability_to_string, NMBluetoothCapabilities,
|
||||
NM_UTILS_FLAGS2STR (NM_BT_CAPABILITY_NONE, "NONE"),
|
||||
NM_UTILS_FLAGS2STR (NM_BT_CAPABILITY_DUN, "DUN"),
|
||||
NM_UTILS_FLAGS2STR (NM_BT_CAPABILITY_NAP, "NAP"),
|
||||
)
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/**
|
||||
* nm_utils_base64secret_decode:
|
||||
* @base64_key: the (possibly invalid) base64 encode key.
|
||||
|
|
|
@ -148,7 +148,7 @@ src/dhcp/nm-dhcp-dhclient-utils.c
|
|||
src/dhcp/nm-dhcp-manager.c
|
||||
src/dns/nm-dns-manager.c
|
||||
src/devices/adsl/nm-device-adsl.c
|
||||
src/devices/bluetooth/nm-bluez-device.c
|
||||
src/devices/bluetooth/nm-bluez-manager.c
|
||||
src/devices/bluetooth/nm-device-bt.c
|
||||
src/devices/nm-device-6lowpan.c
|
||||
src/devices/nm-device-bond.c
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
sources = files(
|
||||
'nm-bluez-device.c',
|
||||
'nm-bluez-manager.c',
|
||||
'nm-bluez5-manager.c',
|
||||
'nm-bt-error.c',
|
||||
'nm-device-bt.c',
|
||||
)
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,70 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/* NetworkManager -- Network link manager
|
||||
*
|
||||
* Copyright (C) 2009 - 2014 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#ifndef __NETWORKMANAGER_BLUEZ_DEVICE_H__
|
||||
#define __NETWORKMANAGER_BLUEZ_DEVICE_H__
|
||||
|
||||
#include "nm-connection.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))
|
||||
#define NM_IS_BLUEZ_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_BLUEZ_DEVICE))
|
||||
#define NM_IS_BLUEZ_DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_BLUEZ_DEVICE))
|
||||
#define NM_BLUEZ_DEVICE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_BLUEZ_DEVICE, NMBluezDeviceClass))
|
||||
|
||||
/* Properties */
|
||||
#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_USABLE "usable"
|
||||
#define NM_BLUEZ_DEVICE_CONNECTED "connected"
|
||||
|
||||
/* Signals */
|
||||
#define NM_BLUEZ_DEVICE_INITIALIZED "initialized"
|
||||
#define NM_BLUEZ_DEVICE_REMOVED "removed"
|
||||
|
||||
typedef struct _NMBluezDevice NMBluezDevice;
|
||||
typedef struct _NMBluezDeviceClass NMBluezDeviceClass;
|
||||
|
||||
GType nm_bluez_device_get_type (void);
|
||||
|
||||
NMBluezDevice *nm_bluez_device_new (GDBusConnection *dbus_connection,
|
||||
const char *path,
|
||||
NMSettings *settings);
|
||||
|
||||
const char *nm_bluez_device_get_path (NMBluezDevice *self);
|
||||
|
||||
gboolean nm_bluez_device_get_initialized (NMBluezDevice *self);
|
||||
|
||||
gboolean nm_bluez_device_get_usable (NMBluezDevice *self);
|
||||
|
||||
const char *nm_bluez_device_get_address (NMBluezDevice *self);
|
||||
|
||||
const char *nm_bluez_device_get_name (NMBluezDevice *self);
|
||||
|
||||
guint32 nm_bluez_device_get_capabilities (NMBluezDevice *self);
|
||||
|
||||
gboolean nm_bluez_device_get_connected (NMBluezDevice *self);
|
||||
|
||||
typedef void (*NMBluezDeviceConnectCallback) (NMBluezDevice *self,
|
||||
const char *device,
|
||||
GError *error,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
nm_bluez_device_connect_async (NMBluezDevice *self,
|
||||
NMBluetoothCapabilities connection_bt_type,
|
||||
GCancellable *cancellable,
|
||||
NMBluezDeviceConnectCallback callback,
|
||||
gpointer callback_user_data);
|
||||
|
||||
void
|
||||
nm_bluez_device_disconnect (NMBluezDevice *self);
|
||||
|
||||
#endif /* __NETWORKMANAGER_BLUEZ_DEVICE_H__ */
|
||||
|
File diff suppressed because it is too large
Load diff
39
src/devices/bluetooth/nm-bluez-manager.h
Normal file
39
src/devices/bluetooth/nm-bluez-manager.h
Normal file
|
@ -0,0 +1,39 @@
|
|||
// SPDX-License-Identifier: LGPL-2.1+
|
||||
/*
|
||||
* Copyright (C) 2009 - 2019 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#ifndef __NM_BLUEZ_MANAGER_H__
|
||||
#define __NM_BLUEZ_MANAGER_H__
|
||||
|
||||
#define NM_TYPE_BLUEZ_MANAGER (nm_bluez_manager_get_type ())
|
||||
#define NM_BLUEZ_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_BLUEZ_MANAGER, NMBluezManager))
|
||||
#define NM_BLUEZ_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_BLUEZ_MANAGER, NMBluezManagerClass))
|
||||
#define NM_IS_BLUEZ_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_BLUEZ_MANAGER))
|
||||
#define NM_IS_BLUEZ_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_BLUEZ_MANAGER))
|
||||
#define NM_BLUEZ_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_BLUEZ_MANAGER, NMBluezManagerClass))
|
||||
|
||||
typedef struct _NMBluezManager NMBluezManager;
|
||||
typedef struct _NMBluezManagerClass NMBluezManagerClass;
|
||||
|
||||
GType nm_bluez_manager_get_type (void);
|
||||
|
||||
typedef void (*NMBluezManagerConnectCb) (NMBluezManager *self,
|
||||
gboolean is_completed /* or else is early notification with DUN path */,
|
||||
const char *device_name,
|
||||
GError *error,
|
||||
gpointer user_data);
|
||||
|
||||
gboolean nm_bluez_manager_connect (NMBluezManager *self,
|
||||
const char *object_path,
|
||||
NMBluetoothCapabilities connection_bt_type,
|
||||
int timeout_msec,
|
||||
GCancellable *cancellable,
|
||||
NMBluezManagerConnectCb callback,
|
||||
gpointer callback_user_data,
|
||||
GError **error);
|
||||
|
||||
void nm_bluez_manager_disconnect (NMBluezManager *self,
|
||||
const char *object_path);
|
||||
|
||||
#endif /* __NM_BLUEZ_MANAGER_H__ */
|
File diff suppressed because it is too large
Load diff
|
@ -4,27 +4,36 @@
|
|||
* Copyright (C) 2014 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#ifndef _NM_BLUEZ5_UTILS_H_
|
||||
#define _NM_BLUEZ5_UTILS_H_
|
||||
#ifndef __NM_BLUEZ5_DUN_H__
|
||||
#define __NM_BLUEZ5_DUN_H__
|
||||
|
||||
typedef struct _NMBluez5DunContext NMBluez5DunContext;
|
||||
|
||||
typedef void (*NMBluez5DunFunc) (NMBluez5DunContext *context,
|
||||
const char *rfcomm_dev,
|
||||
GError *error,
|
||||
gpointer user_data);
|
||||
#if WITH_BLUEZ5_DUN
|
||||
|
||||
NMBluez5DunContext *nm_bluez5_dun_new (const char *adapter,
|
||||
const char *remote);
|
||||
typedef void (*NMBluez5DunConnectCb) (NMBluez5DunContext *context,
|
||||
const char *rfcomm_dev,
|
||||
GError *error,
|
||||
gpointer user_data);
|
||||
|
||||
void nm_bluez5_dun_connect (NMBluez5DunContext *context,
|
||||
NMBluez5DunFunc callback,
|
||||
gpointer user_data);
|
||||
typedef void (*NMBluez5DunNotifyTtyHangupCb) (NMBluez5DunContext *context,
|
||||
gpointer user_data);
|
||||
|
||||
/* Clean up connection resources */
|
||||
void nm_bluez5_dun_cleanup (NMBluez5DunContext *context);
|
||||
gboolean nm_bluez5_dun_connect (const char *adapter,
|
||||
const char *remote,
|
||||
GCancellable *cancellable,
|
||||
NMBluez5DunConnectCb callback,
|
||||
gpointer callback_user_data,
|
||||
NMBluez5DunNotifyTtyHangupCb notify_tty_hangup_cb,
|
||||
gpointer notify_tty_hangup_user_data,
|
||||
GError **error);
|
||||
|
||||
/* Clean up and dispose all resources */
|
||||
void nm_bluez5_dun_free (NMBluez5DunContext *context);
|
||||
void nm_bluez5_dun_disconnect (NMBluez5DunContext *context);
|
||||
|
||||
#endif /* _NM_BLUEZ5_UTILS_H_ */
|
||||
const char *nm_bluez5_dun_context_get_adapter (const NMBluez5DunContext *context);
|
||||
const char *nm_bluez5_dun_context_get_remote (const NMBluez5DunContext *context);
|
||||
const char *nm_bluez5_dun_context_get_rfcomm_dev (const NMBluez5DunContext *context);
|
||||
|
||||
#endif /* WITH_BLUEZ5_DUN */
|
||||
|
||||
#endif /* __NM_BLUEZ5_DUN_H__ */
|
||||
|
|
|
@ -1,585 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/* NetworkManager -- Network link manager
|
||||
*
|
||||
* Copyright (C) 2007 - 2008 Novell, Inc.
|
||||
* Copyright (C) 2007 - 2017 Red Hat, Inc.
|
||||
* Copyright (C) 2013 Intel Corporation.
|
||||
*/
|
||||
|
||||
#include "nm-default.h"
|
||||
|
||||
#include "nm-bluez5-manager.h"
|
||||
|
||||
#include <signal.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "nm-core-internal.h"
|
||||
|
||||
#include "nm-std-aux/nm-dbus-compat.h"
|
||||
#include "c-list/src/c-list.h"
|
||||
#include "nm-bluez-device.h"
|
||||
#include "nm-bluez-common.h"
|
||||
#include "devices/nm-device-bridge.h"
|
||||
#include "settings/nm-settings.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
enum {
|
||||
BDADDR_ADDED,
|
||||
NETWORK_SERVER_ADDED,
|
||||
LAST_SIGNAL,
|
||||
};
|
||||
|
||||
static guint signals[LAST_SIGNAL] = { 0 };
|
||||
|
||||
typedef struct {
|
||||
NMSettings *settings;
|
||||
|
||||
GDBusProxy *proxy;
|
||||
|
||||
GHashTable *devices;
|
||||
|
||||
CList network_servers;
|
||||
} NMBluez5ManagerPrivate;
|
||||
|
||||
struct _NMBluez5Manager {
|
||||
GObject parent;
|
||||
NMBtVTableNetworkServer network_server_vtable;
|
||||
NMBluez5ManagerPrivate _priv;
|
||||
};
|
||||
|
||||
struct _NMBluez5ManagerClass {
|
||||
GObjectClass parent;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (NMBluez5Manager, nm_bluez5_manager, G_TYPE_OBJECT)
|
||||
|
||||
#define NM_BLUEZ5_MANAGER_GET_PRIVATE(self) _NM_GET_PRIVATE (self, NMBluez5Manager, NM_IS_BLUEZ5_MANAGER)
|
||||
|
||||
#define NM_BLUEZ5_MANAGER_GET_NETWORK_SERVER_VTABLE(self) (&(self)->network_server_vtable)
|
||||
|
||||
#define NETWORK_SERVER_VTABLE_GET_NM_BLUEZ5_MANAGER(vtable) \
|
||||
NM_BLUEZ5_MANAGER(((char *)(vtable)) - offsetof (struct _NMBluez5Manager, network_server_vtable))
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#define _NMLOG_DOMAIN LOGD_BT
|
||||
#define _NMLOG(level, ...) __NMLOG_DEFAULT (level, _NMLOG_DOMAIN, "bluez5", __VA_ARGS__)
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void device_initialized (NMBluezDevice *device, gboolean success, NMBluez5Manager *self);
|
||||
static void device_usable (NMBluezDevice *device, GParamSpec *pspec, NMBluez5Manager *self);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
typedef struct {
|
||||
char *path;
|
||||
char *addr;
|
||||
NMDevice *device;
|
||||
CList lst_ns;
|
||||
} NetworkServer;
|
||||
|
||||
static NetworkServer *
|
||||
_find_network_server (NMBluez5Manager *self, const char *path, NMDevice *device)
|
||||
{
|
||||
NMBluez5ManagerPrivate *priv = NM_BLUEZ5_MANAGER_GET_PRIVATE (self);
|
||||
NetworkServer *network_server;
|
||||
|
||||
nm_assert (path || NM_IS_DEVICE (device));
|
||||
|
||||
c_list_for_each_entry (network_server, &priv->network_servers, lst_ns) {
|
||||
if (path && !nm_streq (network_server->path, path))
|
||||
continue;
|
||||
if (device && network_server->device != device)
|
||||
continue;
|
||||
return network_server;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static NetworkServer *
|
||||
_find_network_server_for_addr (NMBluez5Manager *self, const char *addr)
|
||||
{
|
||||
NMBluez5ManagerPrivate *priv = NM_BLUEZ5_MANAGER_GET_PRIVATE (self);
|
||||
NetworkServer *network_server;
|
||||
|
||||
c_list_for_each_entry (network_server, &priv->network_servers, lst_ns) {
|
||||
/* The address lookups need a server not assigned to a device
|
||||
* and tolerate an empty address as a wildcard for "any". */
|
||||
if ( !network_server->device
|
||||
&& (!addr || nm_streq (network_server->addr, addr)))
|
||||
return network_server;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
_network_server_unregister (NMBluez5Manager *self, NetworkServer *network_server)
|
||||
{
|
||||
NMBluez5ManagerPrivate *priv = NM_BLUEZ5_MANAGER_GET_PRIVATE (self);
|
||||
|
||||
if (!network_server->device) {
|
||||
/* Not connected. */
|
||||
return;
|
||||
}
|
||||
|
||||
_LOGI ("NAP: unregistering %s from %s",
|
||||
nm_device_get_iface (network_server->device),
|
||||
network_server->addr);
|
||||
|
||||
g_dbus_connection_call (g_dbus_proxy_get_connection (priv->proxy),
|
||||
NM_BLUEZ_SERVICE,
|
||||
network_server->path,
|
||||
NM_BLUEZ5_NETWORK_SERVER_INTERFACE,
|
||||
"Unregister",
|
||||
g_variant_new ("(s)", BLUETOOTH_CONNECT_NAP),
|
||||
NULL,
|
||||
G_DBUS_CALL_FLAGS_NONE,
|
||||
-1, NULL, NULL, NULL);
|
||||
|
||||
g_clear_object (&network_server->device);
|
||||
}
|
||||
|
||||
static void
|
||||
_network_server_free (NMBluez5Manager *self, NetworkServer *network_server)
|
||||
{
|
||||
_network_server_unregister (self, network_server);
|
||||
c_list_unlink_stale (&network_server->lst_ns);
|
||||
g_free (network_server->path);
|
||||
g_free (network_server->addr);
|
||||
g_slice_free (NetworkServer, network_server);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
network_server_is_available (const NMBtVTableNetworkServer *vtable,
|
||||
const char *addr)
|
||||
{
|
||||
NMBluez5Manager *self = NETWORK_SERVER_VTABLE_GET_NM_BLUEZ5_MANAGER (vtable);
|
||||
|
||||
return !!_find_network_server_for_addr (self, addr);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
network_server_register_bridge (const NMBtVTableNetworkServer *vtable,
|
||||
const char *addr,
|
||||
NMDevice *device)
|
||||
{
|
||||
NMBluez5Manager *self = NETWORK_SERVER_VTABLE_GET_NM_BLUEZ5_MANAGER (vtable);
|
||||
NMBluez5ManagerPrivate *priv = NM_BLUEZ5_MANAGER_GET_PRIVATE (self);
|
||||
NetworkServer *network_server = _find_network_server_for_addr (self, addr);
|
||||
|
||||
nm_assert (NM_IS_DEVICE (device));
|
||||
nm_assert (!_find_network_server (self, NULL, device));
|
||||
|
||||
if (!network_server) {
|
||||
/* The device checked that a network server is available, before
|
||||
* starting the activation, but for some reason it no longer is.
|
||||
* Indicate that the activation should not proceed. */
|
||||
_LOGI ("NAP: %s is not available for %s", addr, nm_device_get_iface (device));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
_LOGI ("NAP: registering %s on %s", nm_device_get_iface (device), network_server->addr);
|
||||
|
||||
g_dbus_connection_call (g_dbus_proxy_get_connection (priv->proxy),
|
||||
NM_BLUEZ_SERVICE,
|
||||
network_server->path,
|
||||
NM_BLUEZ5_NETWORK_SERVER_INTERFACE,
|
||||
"Register",
|
||||
g_variant_new ("(ss)", BLUETOOTH_CONNECT_NAP, nm_device_get_iface (device)),
|
||||
NULL,
|
||||
G_DBUS_CALL_FLAGS_NONE,
|
||||
-1, NULL, NULL, NULL);
|
||||
|
||||
network_server->device = g_object_ref (device);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
network_server_unregister_bridge (const NMBtVTableNetworkServer *vtable,
|
||||
NMDevice *device)
|
||||
{
|
||||
NMBluez5Manager *self = NETWORK_SERVER_VTABLE_GET_NM_BLUEZ5_MANAGER (vtable);
|
||||
NetworkServer *network_server = _find_network_server (self, NULL, device);
|
||||
|
||||
if (network_server)
|
||||
_network_server_unregister (self, network_server);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
network_server_removed (GDBusProxy *proxy, const char *path, NMBluez5Manager *self)
|
||||
{
|
||||
NetworkServer *network_server;
|
||||
|
||||
network_server = _find_network_server (self, path, NULL);
|
||||
if (!network_server)
|
||||
return;
|
||||
|
||||
if (network_server->device) {
|
||||
nm_device_queue_state (network_server->device, NM_DEVICE_STATE_DISCONNECTED,
|
||||
NM_DEVICE_STATE_REASON_BT_FAILED);
|
||||
}
|
||||
_LOGI ("NAP: removed interface %s", network_server->addr);
|
||||
_network_server_free (self, network_server);
|
||||
}
|
||||
|
||||
static void
|
||||
network_server_added (GDBusProxy *proxy, const char *path, const char *addr, NMBluez5Manager *self)
|
||||
{
|
||||
NMBluez5ManagerPrivate *priv = NM_BLUEZ5_MANAGER_GET_PRIVATE (self);
|
||||
NetworkServer *network_server;
|
||||
|
||||
/* If BlueZ messes up and announces a single network server twice,
|
||||
* make sure we get rid of the older instance first. */
|
||||
network_server_removed (proxy, path, self);
|
||||
|
||||
network_server = g_slice_new0 (NetworkServer);
|
||||
network_server->path = g_strdup (path);
|
||||
network_server->addr = g_strdup (addr);
|
||||
c_list_link_before (&priv->network_servers, &network_server->lst_ns);
|
||||
|
||||
_LOGI ("NAP: added interface %s", addr);
|
||||
|
||||
g_signal_emit (self, signals[NETWORK_SERVER_ADDED], 0);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
emit_bdaddr_added (NMBluez5Manager *self, NMBluezDevice *device)
|
||||
{
|
||||
g_signal_emit (self, signals[BDADDR_ADDED], 0,
|
||||
device,
|
||||
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_bluez5_manager_query_devices (NMBluez5Manager *self)
|
||||
{
|
||||
NMBluez5ManagerPrivate *priv = NM_BLUEZ5_MANAGER_GET_PRIVATE (self);
|
||||
NMBluezDevice *device;
|
||||
GHashTableIter iter;
|
||||
|
||||
g_hash_table_iter_init (&iter, priv->devices);
|
||||
while (g_hash_table_iter_next (&iter, NULL, (gpointer) &device)) {
|
||||
if (nm_bluez_device_get_usable (device))
|
||||
emit_bdaddr_added (self, device);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
remove_device (NMBluez5Manager *self, NMBluezDevice *device)
|
||||
{
|
||||
g_signal_handlers_disconnect_by_func (device, G_CALLBACK (device_initialized), self);
|
||||
g_signal_handlers_disconnect_by_func (device, G_CALLBACK (device_usable), self);
|
||||
if (nm_bluez_device_get_usable (device))
|
||||
g_signal_emit_by_name (device, NM_BLUEZ_DEVICE_REMOVED);
|
||||
}
|
||||
|
||||
static void
|
||||
remove_all_devices (NMBluez5Manager *self)
|
||||
{
|
||||
GHashTableIter iter;
|
||||
NMBluezDevice *device;
|
||||
NMBluez5ManagerPrivate *priv = NM_BLUEZ5_MANAGER_GET_PRIVATE (self);
|
||||
|
||||
g_hash_table_iter_init (&iter, priv->devices);
|
||||
while (g_hash_table_iter_next (&iter, NULL, (gpointer) &device)) {
|
||||
g_hash_table_iter_steal (&iter);
|
||||
remove_device (self, device);
|
||||
g_object_unref (device);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
device_usable (NMBluezDevice *device, GParamSpec *pspec, NMBluez5Manager *self)
|
||||
{
|
||||
gboolean usable = nm_bluez_device_get_usable (device);
|
||||
|
||||
_LOGD ("(%s): bluez device now %s",
|
||||
nm_bluez_device_get_path (device),
|
||||
usable ? "usable" : "unusable");
|
||||
|
||||
if (usable) {
|
||||
_LOGD ("(%s): bluez device address %s",
|
||||
nm_bluez_device_get_path (device),
|
||||
nm_bluez_device_get_address (device));
|
||||
emit_bdaddr_added (self, device);
|
||||
} else
|
||||
g_signal_emit_by_name (device, NM_BLUEZ_DEVICE_REMOVED);
|
||||
}
|
||||
|
||||
static void
|
||||
device_initialized (NMBluezDevice *device, gboolean success, NMBluez5Manager *self)
|
||||
{
|
||||
NMBluez5ManagerPrivate *priv = NM_BLUEZ5_MANAGER_GET_PRIVATE (self);
|
||||
|
||||
_LOGD ("(%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));
|
||||
}
|
||||
|
||||
static void
|
||||
device_added (GDBusProxy *proxy, const char *path, NMBluez5Manager *self)
|
||||
{
|
||||
NMBluez5ManagerPrivate *priv = NM_BLUEZ5_MANAGER_GET_PRIVATE (self);
|
||||
NMBluezDevice *device;
|
||||
|
||||
device = nm_bluez_device_new (g_dbus_proxy_get_connection (proxy), path, priv->settings);
|
||||
g_signal_connect (device, NM_BLUEZ_DEVICE_INITIALIZED, G_CALLBACK (device_initialized), self);
|
||||
g_signal_connect (device, "notify::" NM_BLUEZ_DEVICE_USABLE, G_CALLBACK (device_usable), self);
|
||||
g_hash_table_insert (priv->devices, (gpointer) nm_bluez_device_get_path (device), device);
|
||||
|
||||
_LOGD ("(%s): new bluez device found", path);
|
||||
}
|
||||
|
||||
static void
|
||||
device_removed (GDBusProxy *proxy, const char *path, NMBluez5Manager *self)
|
||||
{
|
||||
NMBluez5ManagerPrivate *priv = NM_BLUEZ5_MANAGER_GET_PRIVATE (self);
|
||||
NMBluezDevice *device;
|
||||
|
||||
_LOGD ("(%s): bluez device removed", path);
|
||||
|
||||
device = g_hash_table_lookup (priv->devices, path);
|
||||
if (device) {
|
||||
g_hash_table_steal (priv->devices, nm_bluez_device_get_path (device));
|
||||
remove_device (NM_BLUEZ5_MANAGER (self), device);
|
||||
g_object_unref (device);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
object_manager_interfaces_added (GDBusProxy *proxy,
|
||||
const char *path,
|
||||
GVariant *dict,
|
||||
NMBluez5Manager *self)
|
||||
{
|
||||
if (g_variant_lookup (dict, NM_BLUEZ5_DEVICE_INTERFACE, "a{sv}", NULL))
|
||||
device_added (proxy, path, self);
|
||||
if (g_variant_lookup (dict, NM_BLUEZ5_NETWORK_SERVER_INTERFACE, "a{sv}", NULL)) {
|
||||
gs_unref_variant GVariant *adapter = g_variant_lookup_value (dict, NM_BLUEZ5_ADAPTER_INTERFACE, G_VARIANT_TYPE_DICTIONARY);
|
||||
const char *address;
|
||||
|
||||
if ( adapter
|
||||
&& g_variant_lookup (adapter, "Address", "&s", &address))
|
||||
network_server_added (proxy, path, address, self);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
object_manager_interfaces_removed (GDBusProxy *proxy,
|
||||
const char *path,
|
||||
const char **ifaces,
|
||||
NMBluez5Manager *self)
|
||||
{
|
||||
if (ifaces && g_strv_contains (ifaces, NM_BLUEZ5_DEVICE_INTERFACE))
|
||||
device_removed (proxy, path, self);
|
||||
if (ifaces && g_strv_contains (ifaces, NM_BLUEZ5_NETWORK_SERVER_INTERFACE))
|
||||
network_server_removed (proxy, path, self);
|
||||
}
|
||||
|
||||
static void
|
||||
get_managed_objects_cb (GDBusProxy *proxy,
|
||||
GAsyncResult *res,
|
||||
NMBluez5Manager *self)
|
||||
{
|
||||
gs_unref_variant GVariant *variant0 = NULL;
|
||||
GVariant *variant, *ifaces;
|
||||
GVariantIter i;
|
||||
GError *error = NULL;
|
||||
const char *path;
|
||||
|
||||
variant = _nm_dbus_proxy_call_finish (proxy, res,
|
||||
G_VARIANT_TYPE ("(a{oa{sa{sv}}})"),
|
||||
&error);
|
||||
if (!variant) {
|
||||
if (g_error_matches (error, G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_METHOD))
|
||||
_LOGW ("Couldn't get managed objects: not running Bluez5?");
|
||||
else {
|
||||
g_dbus_error_strip_remote_error (error);
|
||||
_LOGW ("Couldn't get managed objects: %s", error->message);
|
||||
}
|
||||
g_clear_error (&error);
|
||||
return;
|
||||
}
|
||||
variant0 = g_variant_get_child_value (variant, 0);
|
||||
g_variant_iter_init (&i, variant0);
|
||||
while ((g_variant_iter_next (&i, "{&o*}", &path, &ifaces))) {
|
||||
object_manager_interfaces_added (proxy, path, ifaces, self);
|
||||
g_variant_unref (ifaces);
|
||||
}
|
||||
|
||||
g_variant_unref (variant);
|
||||
}
|
||||
|
||||
static void name_owner_changed_cb (GObject *object, GParamSpec *pspec, gpointer user_data);
|
||||
|
||||
static void
|
||||
on_proxy_acquired (GObject *object,
|
||||
GAsyncResult *res,
|
||||
NMBluez5Manager *self)
|
||||
{
|
||||
NMBluez5ManagerPrivate *priv = NM_BLUEZ5_MANAGER_GET_PRIVATE (self);
|
||||
GError *error = NULL;
|
||||
|
||||
priv->proxy = g_dbus_proxy_new_for_bus_finish (res, &error);
|
||||
|
||||
if (!priv->proxy) {
|
||||
_LOGW ("Couldn't acquire object manager proxy: %s", error->message);
|
||||
g_clear_error (&error);
|
||||
return;
|
||||
}
|
||||
|
||||
g_signal_connect (priv->proxy, "notify::g-name-owner",
|
||||
G_CALLBACK (name_owner_changed_cb), self);
|
||||
|
||||
/* Get already managed devices. */
|
||||
g_dbus_proxy_call (priv->proxy, "GetManagedObjects",
|
||||
NULL,
|
||||
G_DBUS_CALL_FLAGS_NONE,
|
||||
-1,
|
||||
NULL,
|
||||
(GAsyncReadyCallback) get_managed_objects_cb,
|
||||
self);
|
||||
|
||||
_nm_dbus_signal_connect (priv->proxy, "InterfacesAdded", G_VARIANT_TYPE ("(oa{sa{sv}})"),
|
||||
G_CALLBACK (object_manager_interfaces_added), self);
|
||||
_nm_dbus_signal_connect (priv->proxy, "InterfacesRemoved", G_VARIANT_TYPE ("(oas)"),
|
||||
G_CALLBACK (object_manager_interfaces_removed), self);
|
||||
}
|
||||
|
||||
static void
|
||||
bluez_connect (NMBluez5Manager *self)
|
||||
{
|
||||
NMBluez5ManagerPrivate *priv = NM_BLUEZ5_MANAGER_GET_PRIVATE (self);
|
||||
|
||||
g_return_if_fail (priv->proxy == NULL);
|
||||
|
||||
g_dbus_proxy_new_for_bus (G_BUS_TYPE_SYSTEM,
|
||||
G_DBUS_PROXY_FLAGS_NONE,
|
||||
NULL,
|
||||
NM_BLUEZ_SERVICE,
|
||||
NM_BLUEZ_MANAGER_PATH,
|
||||
DBUS_INTERFACE_OBJECT_MANAGER,
|
||||
NULL,
|
||||
(GAsyncReadyCallback) on_proxy_acquired,
|
||||
self);
|
||||
}
|
||||
|
||||
static void
|
||||
name_owner_changed_cb (GObject *object,
|
||||
GParamSpec *pspec,
|
||||
gpointer user_data)
|
||||
{
|
||||
NMBluez5Manager *self = NM_BLUEZ5_MANAGER (user_data);
|
||||
NMBluez5ManagerPrivate *priv = NM_BLUEZ5_MANAGER_GET_PRIVATE (self);
|
||||
char *owner;
|
||||
|
||||
if (priv->devices) {
|
||||
owner = g_dbus_proxy_get_name_owner (priv->proxy);
|
||||
if (!owner)
|
||||
remove_all_devices (self);
|
||||
g_free (owner);
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
nm_bluez5_manager_init (NMBluez5Manager *self)
|
||||
{
|
||||
NMBluez5ManagerPrivate *priv = NM_BLUEZ5_MANAGER_GET_PRIVATE (self);
|
||||
NMBtVTableNetworkServer *network_server_vtable = NM_BLUEZ5_MANAGER_GET_NETWORK_SERVER_VTABLE (self);
|
||||
|
||||
bluez_connect (self);
|
||||
|
||||
priv->devices = g_hash_table_new_full (nm_str_hash, g_str_equal,
|
||||
NULL, g_object_unref);
|
||||
|
||||
c_list_init (&priv->network_servers);
|
||||
|
||||
nm_assert (!nm_bt_vtable_network_server);
|
||||
network_server_vtable->is_available = network_server_is_available;
|
||||
network_server_vtable->register_bridge = network_server_register_bridge;
|
||||
network_server_vtable->unregister_bridge = network_server_unregister_bridge;
|
||||
nm_bt_vtable_network_server = network_server_vtable;
|
||||
}
|
||||
|
||||
NMBluez5Manager *
|
||||
nm_bluez5_manager_new (NMSettings *settings)
|
||||
{
|
||||
NMBluez5Manager *instance = NULL;
|
||||
|
||||
g_return_val_if_fail (NM_IS_SETTINGS (settings), NULL);
|
||||
|
||||
instance = g_object_new (NM_TYPE_BLUEZ5_MANAGER, NULL);
|
||||
NM_BLUEZ5_MANAGER_GET_PRIVATE (instance)->settings = g_object_ref (settings);
|
||||
return instance;
|
||||
}
|
||||
|
||||
static void
|
||||
dispose (GObject *object)
|
||||
{
|
||||
NMBluez5Manager *self = NM_BLUEZ5_MANAGER (object);
|
||||
NMBluez5ManagerPrivate *priv = NM_BLUEZ5_MANAGER_GET_PRIVATE (self);
|
||||
CList *iter, *safe;
|
||||
|
||||
c_list_for_each_safe (iter, safe, &priv->network_servers)
|
||||
_network_server_free (self, c_list_entry (iter, NetworkServer, lst_ns));
|
||||
|
||||
if (priv->proxy) {
|
||||
g_signal_handlers_disconnect_by_func (priv->proxy, G_CALLBACK (name_owner_changed_cb), self);
|
||||
g_clear_object (&priv->proxy);
|
||||
}
|
||||
|
||||
g_hash_table_remove_all (priv->devices);
|
||||
|
||||
G_OBJECT_CLASS (nm_bluez5_manager_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
finalize (GObject *object)
|
||||
{
|
||||
NMBluez5Manager *self = NM_BLUEZ5_MANAGER (object);
|
||||
NMBluez5ManagerPrivate *priv = NM_BLUEZ5_MANAGER_GET_PRIVATE (self);
|
||||
|
||||
g_hash_table_destroy (priv->devices);
|
||||
|
||||
G_OBJECT_CLASS (nm_bluez5_manager_parent_class)->finalize (object);
|
||||
|
||||
g_object_unref (priv->settings);
|
||||
}
|
||||
|
||||
static void
|
||||
nm_bluez5_manager_class_init (NMBluez5ManagerClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->dispose = dispose;
|
||||
object_class->finalize = finalize;
|
||||
|
||||
signals[BDADDR_ADDED] =
|
||||
g_signal_new (NM_BLUEZ_MANAGER_BDADDR_ADDED,
|
||||
G_OBJECT_CLASS_TYPE (object_class),
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
0, NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 5, G_TYPE_OBJECT, G_TYPE_STRING,
|
||||
G_TYPE_STRING, G_TYPE_STRING, G_TYPE_UINT);
|
||||
|
||||
signals[NETWORK_SERVER_ADDED] =
|
||||
g_signal_new (NM_BLUEZ_MANAGER_NETWORK_SERVER_ADDED,
|
||||
G_OBJECT_CLASS_TYPE (object_class),
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
0, NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 0);
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/* NetworkManager -- Network link manager
|
||||
*
|
||||
* Copyright (C) 2007 - 2008 Novell, Inc.
|
||||
* Copyright (C) 2007 - 2013 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#ifndef __NETWORKMANAGER_BLUEZ5_MANAGER_H__
|
||||
#define __NETWORKMANAGER_BLUEZ5_MANAGER_H__
|
||||
|
||||
#define NM_TYPE_BLUEZ5_MANAGER (nm_bluez5_manager_get_type ())
|
||||
#define NM_BLUEZ5_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_BLUEZ5_MANAGER, NMBluez5Manager))
|
||||
#define NM_BLUEZ5_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_BLUEZ5_MANAGER, NMBluez5ManagerClass))
|
||||
#define NM_IS_BLUEZ5_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_BLUEZ5_MANAGER))
|
||||
#define NM_IS_BLUEZ5_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_BLUEZ5_MANAGER))
|
||||
#define NM_BLUEZ5_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_BLUEZ5_MANAGER, NMBluez5ManagerClass))
|
||||
|
||||
typedef struct _NMBluez5Manager NMBluez5Manager;
|
||||
typedef struct _NMBluez5ManagerClass NMBluez5ManagerClass;
|
||||
|
||||
GType nm_bluez5_manager_get_type (void);
|
||||
|
||||
NMBluez5Manager *nm_bluez5_manager_new (NMSettings *settings);
|
||||
|
||||
void nm_bluez5_manager_query_devices (NMBluez5Manager *manager);
|
||||
|
||||
#endif /* __NETWORKMANAGER_BLUEZ5_MANAGER_H__ */
|
File diff suppressed because it is too large
Load diff
|
@ -8,7 +8,6 @@
|
|||
#define __NETWORKMANAGER_DEVICE_BT_H__
|
||||
|
||||
#include "devices/nm-device.h"
|
||||
#include "nm-bluez-device.h"
|
||||
|
||||
#define NM_TYPE_DEVICE_BT (nm_device_bt_get_type ())
|
||||
#define NM_DEVICE_BT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_BT, NMDeviceBt))
|
||||
|
@ -17,9 +16,11 @@
|
|||
#define NM_IS_DEVICE_BT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_BT))
|
||||
#define NM_DEVICE_BT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_BT, NMDeviceBtClass))
|
||||
|
||||
#define NM_DEVICE_BT_NAME "name"
|
||||
#define NM_DEVICE_BT_BDADDR "bt-bdaddr"
|
||||
#define NM_DEVICE_BT_BZ_MGR "bt-bz-mgr"
|
||||
#define NM_DEVICE_BT_CAPABILITIES "bt-capabilities"
|
||||
#define NM_DEVICE_BT_DEVICE "bt-device"
|
||||
#define NM_DEVICE_BT_DBUS_PATH "bt-dbus-path"
|
||||
#define NM_DEVICE_BT_NAME "bt-name"
|
||||
|
||||
#define NM_DEVICE_BT_PPP_STATS "ppp-stats"
|
||||
|
||||
|
@ -28,13 +29,21 @@ typedef struct _NMDeviceBtClass NMDeviceBtClass;
|
|||
|
||||
GType nm_device_bt_get_type (void);
|
||||
|
||||
NMDevice *nm_device_bt_new (NMBluezDevice *bt_device,
|
||||
const char *udi,
|
||||
const char *bdaddr,
|
||||
const char *name,
|
||||
guint32 capabilities);
|
||||
struct _NMBluezManager;
|
||||
|
||||
guint32 nm_device_bt_get_capabilities (NMDeviceBt *device);
|
||||
NMDeviceBt *nm_device_bt_new (struct _NMBluezManager *bz_mgr,
|
||||
const char *dbus_path,
|
||||
const char *bdaddr,
|
||||
const char *name,
|
||||
NMBluetoothCapabilities capabilities);
|
||||
|
||||
gboolean _nm_device_bt_for_same_device (NMDeviceBt *device,
|
||||
const char *dbus_path,
|
||||
const char *bdaddr,
|
||||
const char *name,
|
||||
NMBluetoothCapabilities capabilities);
|
||||
|
||||
NMBluetoothCapabilities nm_device_bt_get_capabilities (NMDeviceBt *device);
|
||||
|
||||
struct _NMModem;
|
||||
|
||||
|
@ -42,4 +51,11 @@ gboolean nm_device_bt_modem_added (NMDeviceBt *device,
|
|||
struct _NMModem *modem,
|
||||
const char *driver);
|
||||
|
||||
void _nm_device_bt_notify_removed (NMDeviceBt *self);
|
||||
|
||||
void _nm_device_bt_notify_set_name (NMDeviceBt *self, const char *name);
|
||||
|
||||
void _nm_device_bt_notify_set_connected (NMDeviceBt *self,
|
||||
gboolean connected);
|
||||
|
||||
#endif /* __NETWORKMANAGER_DEVICE_BT_H__ */
|
||||
|
|
|
@ -2,35 +2,219 @@
|
|||
|
||||
#include "nm-default.h"
|
||||
|
||||
#include <glib-unix.h>
|
||||
|
||||
#include "devices/bluetooth/nm-bluez5-dun.h"
|
||||
|
||||
#include "nm-test-utils-core.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#define _NMLOG_DOMAIN LOGD_BT
|
||||
#define _NMLOG(level, ...) \
|
||||
nm_log ((level), _NMLOG_DOMAIN, \
|
||||
NULL, NULL, \
|
||||
"bt%s%s%s: " _NM_UTILS_MACRO_FIRST (__VA_ARGS__), \
|
||||
NM_PRINT_FMT_QUOTED (gl.argv_cmd, "[", gl.argv_cmd, "]", "") \
|
||||
_NM_UTILS_MACRO_REST (__VA_ARGS__))
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
struct {
|
||||
int argc;
|
||||
const char *const*argv;
|
||||
const char *argv_cmd;
|
||||
GMainLoop *loop;
|
||||
} gl;
|
||||
|
||||
typedef struct _MainCmdInfo {
|
||||
const char *name;
|
||||
int (*main_func) (const struct _MainCmdInfo *main_cmd_info);
|
||||
} MainCmdInfo;
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#if WITH_BLUEZ5_DUN
|
||||
|
||||
typedef struct {
|
||||
NMBluez5DunContext *dun_context;
|
||||
GCancellable *cancellable;
|
||||
guint timeout_id;
|
||||
guint sig_term_id;
|
||||
guint sig_int_id;
|
||||
} DunConnectData;
|
||||
|
||||
static void
|
||||
_dun_connect_cb (NMBluez5DunContext *context,
|
||||
const char *rfcomm_dev,
|
||||
GError *error,
|
||||
gpointer user_data)
|
||||
{
|
||||
DunConnectData *dun_connect_data = user_data;
|
||||
|
||||
g_assert (dun_connect_data);
|
||||
g_assert (!dun_connect_data->dun_context);
|
||||
g_assert ((!!error) != (!!rfcomm_dev));
|
||||
|
||||
if (rfcomm_dev && !context) {
|
||||
_LOGI ("dun-connect notifies path \"%s\". Wait longer...", rfcomm_dev);
|
||||
return;
|
||||
}
|
||||
|
||||
if (rfcomm_dev) {
|
||||
g_assert (context);
|
||||
_LOGI ("dun-connect completed with path \"%s\"", rfcomm_dev);
|
||||
} else {
|
||||
g_assert (!context);
|
||||
_LOGI ("dun-connect failed with error: %s", error->message);
|
||||
}
|
||||
|
||||
dun_connect_data->dun_context = context;
|
||||
|
||||
g_main_loop_quit (gl.loop);
|
||||
}
|
||||
|
||||
static void
|
||||
_dun_notify_tty_hangup_cb (NMBluez5DunContext *context,
|
||||
gpointer user_data)
|
||||
{
|
||||
_LOGI ("dun-connect: notified TTY hangup");
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_timeout_cb (gpointer user_data)
|
||||
{
|
||||
DunConnectData *dun_connect_data = user_data;
|
||||
|
||||
_LOGI ("timeout");
|
||||
dun_connect_data->timeout_id = 0;
|
||||
if (dun_connect_data->cancellable)
|
||||
g_cancellable_cancel (dun_connect_data->cancellable);
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_sig_xxx_cb (DunConnectData *dun_connect_data, int sigid)
|
||||
{
|
||||
_LOGI ("signal %s received", sigid == SIGTERM ? "SIGTERM" : "SIGINT");
|
||||
g_main_loop_quit (gl.loop);
|
||||
return G_SOURCE_CONTINUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_sig_term_cb (gpointer user_data)
|
||||
{
|
||||
return _sig_xxx_cb (user_data, SIGTERM);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_sig_int_cb (gpointer user_data)
|
||||
{
|
||||
return _sig_xxx_cb (user_data, SIGINT);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int
|
||||
do_dun_connect (const MainCmdInfo *main_cmd_info)
|
||||
{
|
||||
#if WITH_BLUEZ5_DUN
|
||||
gs_unref_object GCancellable *cancellable = NULL;
|
||||
gs_free_error GError *error = NULL;
|
||||
const char *adapter;
|
||||
const char *remote;
|
||||
DunConnectData dun_connect_data = { };
|
||||
|
||||
if (gl.argc < 4) {
|
||||
_LOGE ("missing arguments \"adapter\" and \"remote\"");
|
||||
return -1;
|
||||
}
|
||||
|
||||
adapter = gl.argv[2];
|
||||
remote = gl.argv[3];
|
||||
|
||||
cancellable = g_cancellable_new ();
|
||||
dun_connect_data.cancellable = cancellable;
|
||||
|
||||
if (!nm_bluez5_dun_connect (adapter,
|
||||
remote,
|
||||
cancellable,
|
||||
_dun_connect_cb,
|
||||
&dun_connect_data,
|
||||
_dun_notify_tty_hangup_cb,
|
||||
&dun_connect_data,
|
||||
&error)) {
|
||||
_LOGE ("connect failed to start: %s", error->message);
|
||||
return -1;
|
||||
}
|
||||
|
||||
dun_connect_data.timeout_id = g_timeout_add (60000, _timeout_cb, &dun_connect_data);
|
||||
|
||||
g_main_loop_run (gl.loop);
|
||||
|
||||
nm_clear_g_source (&dun_connect_data.timeout_id);
|
||||
|
||||
if (dun_connect_data.dun_context) {
|
||||
|
||||
dun_connect_data.sig_term_id = g_unix_signal_add (SIGTERM, _sig_term_cb, &dun_connect_data);
|
||||
dun_connect_data.sig_int_id = g_unix_signal_add (SIGINT, _sig_int_cb, &dun_connect_data);
|
||||
|
||||
g_main_loop_run (gl.loop);
|
||||
|
||||
nm_clear_g_source (&dun_connect_data.sig_term_id);
|
||||
nm_clear_g_source (&dun_connect_data.sig_int_id);
|
||||
|
||||
nm_bluez5_dun_disconnect (g_steal_pointer (&dun_connect_data.dun_context));
|
||||
}
|
||||
|
||||
return 0;
|
||||
#else
|
||||
_LOGE ("compiled without bluetooth DUN support");
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
NMTST_DEFINE ();
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
NMBluez5DunContext *dun_context;
|
||||
GMainLoop *loop;
|
||||
static const MainCmdInfo main_cmd_infos[] = {
|
||||
{ .name = "dun-connect", .main_func = do_dun_connect, },
|
||||
};
|
||||
int exit_code = 0;
|
||||
guint i;
|
||||
|
||||
if (!g_getenv ("G_MESSAGES_DEBUG"))
|
||||
g_setenv ("G_MESSAGES_DEBUG", "all", TRUE);
|
||||
|
||||
nmtst_init_with_logging (&argc, &argv, "DEBUG", "ALL");
|
||||
|
||||
nm_log_info (LOGD_BT, "bluetooth test util start");
|
||||
nm_logging_init (NULL, TRUE);
|
||||
|
||||
dun_context = nm_bluez5_dun_new ("aa:bb:cc:dd:ee:ff",
|
||||
"aa:bb:cc:dd:ee:fa");
|
||||
gl.argv = (const char *const*) argv;
|
||||
gl.argc = argc;
|
||||
gl.loop = g_main_loop_new (NULL, FALSE);
|
||||
|
||||
loop = g_main_loop_new (NULL, FALSE);
|
||||
_LOGI ("bluetooth test util start");
|
||||
|
||||
g_main_loop_unref (loop);
|
||||
gl.argv_cmd = argc >= 2 ? argv[1] : NULL;
|
||||
|
||||
nm_bluez5_dun_free (dun_context);
|
||||
for (i = 0; i < G_N_ELEMENTS (main_cmd_infos); i++) {
|
||||
if (nm_streq0 (main_cmd_infos[i].name, gl.argv_cmd)) {
|
||||
_LOGD ("start \"%s\"", gl.argv_cmd);
|
||||
exit_code = main_cmd_infos[i].main_func (&main_cmd_infos[i]);
|
||||
_LOGD ("completed with %d", exit_code);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (gl.argv_cmd && i >= G_N_ELEMENTS (main_cmd_infos)) {
|
||||
nm_log_err (LOGD_BT, "invalid command \"%s\"", gl.argv_cmd);
|
||||
exit_code = -1;
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
nm_clear_pointer (&gl.loop, g_main_loop_unref);
|
||||
|
||||
return exit_code;
|
||||
}
|
||||
|
|
|
@ -23,7 +23,9 @@ _LOG_DECLARE_SELF(NMDeviceBridge);
|
|||
|
||||
struct _NMDeviceBridge {
|
||||
NMDevice parent;
|
||||
GCancellable *bt_cancellable;
|
||||
bool vlan_configured:1;
|
||||
bool bt_registered:1;
|
||||
};
|
||||
|
||||
struct _NMDeviceBridgeClass {
|
||||
|
@ -51,6 +53,7 @@ check_connection_available (NMDevice *device,
|
|||
const char *specific_object,
|
||||
GError **error)
|
||||
{
|
||||
NMDeviceBridge *self = NM_DEVICE_BRIDGE (device);
|
||||
NMSettingBluetooth *s_bt;
|
||||
|
||||
if (!NM_DEVICE_CLASS (nm_device_bridge_parent_class)->check_connection_available (device, connection, flags, specific_object, error))
|
||||
|
@ -67,13 +70,18 @@ check_connection_available (NMDevice *device,
|
|||
}
|
||||
|
||||
bdaddr = nm_setting_bluetooth_get_bdaddr (s_bt);
|
||||
if (!nm_bt_vtable_network_server->is_available (nm_bt_vtable_network_server, bdaddr)) {
|
||||
if (!nm_bt_vtable_network_server->is_available (nm_bt_vtable_network_server,
|
||||
bdaddr,
|
||||
( self->bt_cancellable
|
||||
|| self->bt_registered)
|
||||
? device
|
||||
: NULL)) {
|
||||
if (bdaddr)
|
||||
nm_utils_error_set (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY,
|
||||
"not suitable NAP device \"%s\" available", bdaddr);
|
||||
"no suitable NAP device \"%s\" available", bdaddr);
|
||||
else
|
||||
nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY,
|
||||
"not suitable NAP device available");
|
||||
"no suitable NAP device available");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
@ -505,9 +513,53 @@ act_stage1_prepare (NMDevice *device, NMDeviceStateReason *out_failure_reason)
|
|||
return NM_ACT_STAGE_RETURN_SUCCESS;
|
||||
}
|
||||
|
||||
static void
|
||||
_bt_register_bridge_cb (GError *error,
|
||||
gpointer user_data)
|
||||
{
|
||||
NMDeviceBridge *self;
|
||||
|
||||
if (nm_utils_error_is_cancelled (error, FALSE))
|
||||
return;
|
||||
|
||||
self = user_data;
|
||||
|
||||
g_clear_object (&self->bt_cancellable);
|
||||
|
||||
if (error) {
|
||||
_LOGD (LOGD_DEVICE, "bluetooth NAP server failed to register bridge: %s", error->message);
|
||||
nm_device_state_changed (NM_DEVICE (self), NM_DEVICE_STATE_FAILED,
|
||||
NM_DEVICE_STATE_REASON_BT_FAILED);
|
||||
return;
|
||||
}
|
||||
|
||||
nm_device_activate_schedule_stage3_ip_config_start (NM_DEVICE (self));
|
||||
}
|
||||
|
||||
void
|
||||
_nm_device_bridge_notify_unregister_bt_nap (NMDevice *device,
|
||||
const char *reason)
|
||||
{
|
||||
NMDeviceBridge *self = NM_DEVICE_BRIDGE (device);
|
||||
|
||||
_LOGD (LOGD_DEVICE, "bluetooth NAP server unregistered from bridge: %s%s",
|
||||
reason,
|
||||
self->bt_registered ? "" : " (was no longer registered)");
|
||||
|
||||
nm_clear_g_cancellable (&self->bt_cancellable);
|
||||
|
||||
if (self->bt_registered) {
|
||||
self->bt_registered = FALSE;
|
||||
nm_device_state_changed (device,
|
||||
NM_DEVICE_STATE_FAILED,
|
||||
NM_DEVICE_STATE_REASON_BT_FAILED);
|
||||
}
|
||||
}
|
||||
|
||||
static NMActStageReturn
|
||||
act_stage2_config (NMDevice *device, NMDeviceStateReason *out_failure_reason)
|
||||
{
|
||||
NMDeviceBridge *self = NM_DEVICE_BRIDGE (device);
|
||||
NMConnection *connection;
|
||||
NMSettingBluetooth *s_bt;
|
||||
|
||||
|
@ -515,14 +567,32 @@ act_stage2_config (NMDevice *device, NMDeviceStateReason *out_failure_reason)
|
|||
|
||||
s_bt = _nm_connection_get_setting_bluetooth_for_nap (connection);
|
||||
if (s_bt) {
|
||||
if ( !nm_bt_vtable_network_server
|
||||
|| !nm_bt_vtable_network_server->register_bridge (nm_bt_vtable_network_server,
|
||||
nm_setting_bluetooth_get_bdaddr (s_bt),
|
||||
device)) {
|
||||
/* The HCI we could use is no longer present. */
|
||||
*out_failure_reason = NM_DEVICE_STATE_REASON_REMOVED;
|
||||
gs_free_error GError *error = NULL;
|
||||
|
||||
if (!nm_bt_vtable_network_server) {
|
||||
_LOGD (LOGD_DEVICE, "bluetooth NAP server failed because bluetooth plugin not available");
|
||||
*out_failure_reason = NM_DEVICE_STATE_REASON_BT_FAILED;
|
||||
return NM_ACT_STAGE_RETURN_FAILURE;
|
||||
}
|
||||
|
||||
if (self->bt_cancellable)
|
||||
return NM_ACT_STAGE_RETURN_POSTPONE;
|
||||
|
||||
self->bt_cancellable = g_cancellable_new ();
|
||||
if (!nm_bt_vtable_network_server->register_bridge (nm_bt_vtable_network_server,
|
||||
nm_setting_bluetooth_get_bdaddr (s_bt),
|
||||
device,
|
||||
self->bt_cancellable,
|
||||
_bt_register_bridge_cb,
|
||||
device,
|
||||
&error)) {
|
||||
_LOGD (LOGD_DEVICE, "bluetooth NAP server failed to register bridge: %s", error->message);
|
||||
*out_failure_reason = NM_DEVICE_STATE_REASON_BT_FAILED;
|
||||
return NM_ACT_STAGE_RETURN_FAILURE;
|
||||
}
|
||||
|
||||
self->bt_registered = TRUE;
|
||||
return NM_ACT_STAGE_RETURN_POSTPONE;
|
||||
}
|
||||
|
||||
return NM_ACT_STAGE_RETURN_SUCCESS;
|
||||
|
@ -533,11 +603,15 @@ deactivate (NMDevice *device)
|
|||
{
|
||||
NMDeviceBridge *self = NM_DEVICE_BRIDGE (device);
|
||||
|
||||
_LOGD (LOGD_DEVICE, "deactivate bridge%s",
|
||||
self->bt_registered ? " (registered as NAP bluetooth device)" : "");
|
||||
|
||||
self->vlan_configured = FALSE;
|
||||
|
||||
if (nm_bt_vtable_network_server) {
|
||||
/* always call unregister. It does nothing if the device
|
||||
* isn't registered as a hotspot bridge. */
|
||||
nm_clear_g_cancellable (&self->bt_cancellable);
|
||||
|
||||
if (self->bt_registered) {
|
||||
self->bt_registered = FALSE;
|
||||
nm_bt_vtable_network_server->unregister_bridge (nm_bt_vtable_network_server,
|
||||
device);
|
||||
}
|
||||
|
|
|
@ -23,4 +23,7 @@ GType nm_device_bridge_get_type (void);
|
|||
|
||||
extern const NMBtVTableNetworkServer *nm_bt_vtable_network_server;
|
||||
|
||||
void _nm_device_bridge_notify_unregister_bt_nap (NMDevice *device,
|
||||
const char *reason);
|
||||
|
||||
#endif /* __NETWORKMANAGER_DEVICE_BRIDGE_H__ */
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
|
||||
enum {
|
||||
DEVICE_ADDED,
|
||||
COMPONENT_ADDED,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
|
@ -33,17 +32,6 @@ G_DEFINE_ABSTRACT_TYPE (NMDeviceFactory, nm_device_factory, G_TYPE_OBJECT)
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
gboolean
|
||||
nm_device_factory_emit_component_added (NMDeviceFactory *factory, GObject *component)
|
||||
{
|
||||
gboolean consumed = FALSE;
|
||||
|
||||
g_return_val_if_fail (NM_IS_DEVICE_FACTORY (factory), FALSE);
|
||||
|
||||
g_signal_emit (factory, signals[COMPONENT_ADDED], 0, component, &consumed);
|
||||
return consumed;
|
||||
}
|
||||
|
||||
static void
|
||||
nm_device_factory_get_supported_types (NMDeviceFactory *factory,
|
||||
const NMLinkType **out_link_types,
|
||||
|
@ -182,16 +170,8 @@ nm_device_factory_class_init (NMDeviceFactoryClass *klass)
|
|||
signals[DEVICE_ADDED] = g_signal_new (NM_DEVICE_FACTORY_DEVICE_ADDED,
|
||||
G_OBJECT_CLASS_TYPE (object_class),
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
G_STRUCT_OFFSET (NMDeviceFactoryClass, device_added),
|
||||
NULL, NULL, NULL,
|
||||
0, NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 1, NM_TYPE_DEVICE);
|
||||
|
||||
signals[COMPONENT_ADDED] = g_signal_new (NM_DEVICE_FACTORY_COMPONENT_ADDED,
|
||||
G_OBJECT_CLASS_TYPE (object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (NMDeviceFactoryClass, component_added),
|
||||
g_signal_accumulator_true_handled, NULL, NULL,
|
||||
G_TYPE_BOOLEAN, 1, G_TYPE_OBJECT);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
#define NM_IS_DEVICE_FACTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_FACTORY))
|
||||
#define NM_DEVICE_FACTORY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_FACTORY, NMDeviceFactoryClass))
|
||||
|
||||
#define NM_DEVICE_FACTORY_COMPONENT_ADDED "component-added"
|
||||
#define NM_DEVICE_FACTORY_DEVICE_ADDED "device-added"
|
||||
|
||||
typedef struct {
|
||||
|
@ -118,36 +117,6 @@ typedef struct {
|
|||
NMConnection *connection,
|
||||
gboolean *out_ignore);
|
||||
|
||||
/* Signals */
|
||||
|
||||
/**
|
||||
* device_added:
|
||||
* @factory: the #NMDeviceFactory
|
||||
* @device: the new #NMDevice subclass
|
||||
*
|
||||
* The factory emits this signal if it finds a new device by itself.
|
||||
*/
|
||||
void (*device_added) (NMDeviceFactory *factory, NMDevice *device);
|
||||
|
||||
/**
|
||||
* component_added:
|
||||
* @factory: the #NMDeviceFactory
|
||||
* @component: a new component which existing devices may wish to claim
|
||||
*
|
||||
* The factory emits this signal when an appearance of some component
|
||||
* native to it could be interesting to some of the already existing devices.
|
||||
* The devices then indicate if they took interest in claiming the component.
|
||||
*
|
||||
* For example, the WWAN factory may indicate that a new modem is available,
|
||||
* which an existing Bluetooth device may wish to claim. It emits a signal
|
||||
* passing the modem instance around to see if any device claims it.
|
||||
* If no device claims the component, the plugin is allowed to create a new
|
||||
* #NMDevice instance for that component and emit the "device-added" signal.
|
||||
*
|
||||
* Returns: %TRUE if the component was claimed by a device, %FALSE if not
|
||||
*/
|
||||
gboolean (*component_added) (NMDeviceFactory *factory, GObject *component);
|
||||
|
||||
} NMDeviceFactoryClass;
|
||||
|
||||
GType nm_device_factory_get_type (void);
|
||||
|
@ -189,10 +158,6 @@ NMDevice * nm_device_factory_create_device (NMDeviceFactory *factory,
|
|||
gboolean *out_ignore,
|
||||
GError **error);
|
||||
|
||||
/* For use by implementations */
|
||||
gboolean nm_device_factory_emit_component_added (NMDeviceFactory *factory,
|
||||
GObject *component);
|
||||
|
||||
#define NM_DEVICE_FACTORY_DECLARE_LINK_TYPES(...) \
|
||||
{ static NMLinkType const _link_types_declared[] = { __VA_ARGS__, NM_LINK_TYPE_NONE }; _link_types = _link_types_declared; }
|
||||
#define NM_DEVICE_FACTORY_DECLARE_SETTING_TYPES(...) \
|
||||
|
|
|
@ -4785,42 +4785,24 @@ nm_device_unrealize (NMDevice *self, gboolean remove_resources, GError **error)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_device_notify_component_added():
|
||||
* @self: the #NMDevice
|
||||
* @component: the component being added by a plugin
|
||||
*
|
||||
* Called by the manager to notify the device that a new component has
|
||||
* been found. The device implementation should return %TRUE if it
|
||||
* wishes to claim the component, or %FALSE if it cannot.
|
||||
*
|
||||
* Returns: %TRUE to claim the component, %FALSE if the component cannot be
|
||||
* claimed.
|
||||
*/
|
||||
gboolean
|
||||
nm_device_notify_component_added (NMDevice *self, GObject *component)
|
||||
void
|
||||
nm_device_notify_availability_maybe_changed (NMDevice *self)
|
||||
{
|
||||
NMDeviceClass *klass;
|
||||
NMDevicePrivate *priv;
|
||||
|
||||
g_return_val_if_fail (NM_IS_DEVICE (self), FALSE);
|
||||
g_return_if_fail (NM_IS_DEVICE (self));
|
||||
|
||||
priv = NM_DEVICE_GET_PRIVATE (self);
|
||||
klass = NM_DEVICE_GET_CLASS (self);
|
||||
|
||||
if (priv->state == NM_DEVICE_STATE_DISCONNECTED) {
|
||||
/* A device could have stayed disconnected because it would
|
||||
* want to register with a network server that now become
|
||||
* available. */
|
||||
nm_device_recheck_available_connections (self);
|
||||
if (g_hash_table_size (priv->available_connections) > 0)
|
||||
nm_device_emit_recheck_auto_activate (self);
|
||||
}
|
||||
if (priv->state != NM_DEVICE_STATE_DISCONNECTED)
|
||||
return;
|
||||
|
||||
if (klass->component_added)
|
||||
return klass->component_added (self, component);
|
||||
|
||||
return FALSE;
|
||||
/* A device could have stayed disconnected because it would
|
||||
* want to register with a network server that now become
|
||||
* available. */
|
||||
nm_device_recheck_available_connections (self);
|
||||
if (g_hash_table_size (priv->available_connections) > 0)
|
||||
nm_device_emit_recheck_auto_activate (self);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -416,23 +416,6 @@ typedef struct _NMDeviceClass {
|
|||
int new_ifindex,
|
||||
NMDevice *new_parent);
|
||||
|
||||
/**
|
||||
* component_added:
|
||||
* @self: the #NMDevice
|
||||
* @component: the component (device, modem, etc) which was added
|
||||
*
|
||||
* Notifies @self that a new component that a device might be interested
|
||||
* in was detected by some device factory. It may include an object of
|
||||
* %GObject subclass to help the devices decide whether it claims that
|
||||
* particular object itself and the emitting factory should not.
|
||||
*
|
||||
* Returns: %TRUE if the component was claimed exclusively and no further
|
||||
* devices should be notified of the new component. %FALSE to indicate
|
||||
* that the component was not exclusively claimed and other devices should
|
||||
* be notified.
|
||||
*/
|
||||
gboolean (* component_added) (NMDevice *self, GObject *component);
|
||||
|
||||
gboolean (* owns_iface) (NMDevice *self, const char *iface);
|
||||
|
||||
NMConnection * (* new_default_connection) (NMDevice *self);
|
||||
|
@ -809,7 +792,7 @@ gboolean nm_device_check_connection_available (NMDevice *device,
|
|||
const char *specific_object,
|
||||
GError **error);
|
||||
|
||||
gboolean nm_device_notify_component_added (NMDevice *device, GObject *component);
|
||||
void nm_device_notify_availability_maybe_changed (NMDevice *self);
|
||||
|
||||
gboolean nm_device_owns_iface (NMDevice *device, const char *iface);
|
||||
|
||||
|
@ -869,12 +852,22 @@ void nm_device_check_connectivity_cancel (NMDeviceConnectivityHandle *handle);
|
|||
NMConnectivityState nm_device_get_connectivity_state (NMDevice *self, int addr_family);
|
||||
|
||||
typedef struct _NMBtVTableNetworkServer NMBtVTableNetworkServer;
|
||||
|
||||
typedef void (*NMBtVTableRegisterCallback) (GError *error,
|
||||
gpointer user_data);
|
||||
|
||||
struct _NMBtVTableNetworkServer {
|
||||
gboolean (*is_available) (const NMBtVTableNetworkServer *vtable,
|
||||
const char *addr);
|
||||
const char *addr,
|
||||
NMDevice *device_accept_busy);
|
||||
|
||||
gboolean (*register_bridge) (const NMBtVTableNetworkServer *vtable,
|
||||
const char *addr,
|
||||
NMDevice *device);
|
||||
NMDevice *device,
|
||||
GCancellable *cancellable,
|
||||
NMBtVTableRegisterCallback callback,
|
||||
gpointer callback_user_data,
|
||||
GError **error);
|
||||
gboolean (*unregister_bridge) (const NMBtVTableNetworkServer *vtable,
|
||||
NMDevice *device);
|
||||
};
|
||||
|
|
|
@ -1029,6 +1029,8 @@ nm_modem_act_stage1_prepare (NMModem *self,
|
|||
NMSecretAgentGetSecretsFlags flags = NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION;
|
||||
NMConnection *connection;
|
||||
|
||||
g_return_val_if_fail (NM_IS_ACT_REQUEST (req), NM_ACT_STAGE_RETURN_FAILURE);
|
||||
|
||||
if (priv->act_request)
|
||||
g_object_unref (priv->act_request);
|
||||
priv->act_request = g_object_ref (req);
|
||||
|
@ -1066,8 +1068,11 @@ nm_modem_act_stage1_prepare (NMModem *self,
|
|||
void
|
||||
nm_modem_act_stage2_config (NMModem *self)
|
||||
{
|
||||
NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self);
|
||||
NMModemPrivate *priv;
|
||||
|
||||
g_return_if_fail (NM_IS_MODEM (self));
|
||||
|
||||
priv = NM_MODEM_GET_PRIVATE (self);
|
||||
/* Clear secrets tries counter since secrets were successfully used
|
||||
* already if we get here.
|
||||
*/
|
||||
|
|
|
@ -67,10 +67,6 @@ modem_added_cb (NMModemManager *manager,
|
|||
gs_unref_object NMDevice *device = NULL;
|
||||
const char *driver;
|
||||
|
||||
/* Do nothing if the modem was consumed by some other plugin */
|
||||
if (nm_device_factory_emit_component_added (NM_DEVICE_FACTORY (self), G_OBJECT (modem)))
|
||||
return;
|
||||
|
||||
if (nm_modem_is_claimed (modem))
|
||||
return;
|
||||
|
||||
|
@ -80,9 +76,10 @@ modem_added_cb (NMModemManager *manager,
|
|||
* it. The rfcomm port (and thus the modem) gets created automatically
|
||||
* by the Bluetooth code during the connection process.
|
||||
*/
|
||||
if (driver && strstr (driver, "bluetooth")) {
|
||||
nm_log_info (LOGD_MB, "ignoring modem '%s' (no associated Bluetooth device)",
|
||||
nm_modem_get_control_port (modem));
|
||||
if ( driver
|
||||
&& strstr (driver, "bluetooth")) {
|
||||
nm_log_dbg (LOGD_MB, "WWAN factory ignores bluetooth modem '%s' which should be handled by bluetooth plugin",
|
||||
nm_modem_get_control_port (modem));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -3188,22 +3188,6 @@ factory_device_added_cb (NMDeviceFactory *factory,
|
|||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
factory_component_added_cb (NMDeviceFactory *factory,
|
||||
GObject *component,
|
||||
gpointer user_data)
|
||||
{
|
||||
NMManager *self = user_data;
|
||||
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
||||
NMDevice *device;
|
||||
|
||||
c_list_for_each_entry (device, &priv->devices_lst_head, devices_lst) {
|
||||
if (nm_device_notify_component_added (device, component))
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
_register_device_factory (NMDeviceFactory *factory, gpointer user_data)
|
||||
{
|
||||
|
@ -3213,10 +3197,18 @@ _register_device_factory (NMDeviceFactory *factory, gpointer user_data)
|
|||
NM_DEVICE_FACTORY_DEVICE_ADDED,
|
||||
G_CALLBACK (factory_device_added_cb),
|
||||
self);
|
||||
g_signal_connect (factory,
|
||||
NM_DEVICE_FACTORY_COMPONENT_ADDED,
|
||||
G_CALLBACK (factory_component_added_cb),
|
||||
self);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
void
|
||||
nm_manager_notify_device_availibility_maybe_changed (NMManager *self)
|
||||
{
|
||||
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
||||
NMDevice *device;
|
||||
|
||||
c_list_for_each_entry (device, &priv->devices_lst_head, devices_lst)
|
||||
nm_device_notify_availability_maybe_changed (device);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
|
@ -191,4 +191,6 @@ void nm_manager_dbus_set_property_handle (NMDBusObject *obj,
|
|||
|
||||
NMMetered nm_manager_get_metered (NMManager *self);
|
||||
|
||||
void nm_manager_notify_device_availibility_maybe_changed (NMManager *self);
|
||||
|
||||
#endif /* __NETWORKMANAGER_MANAGER_H__ */
|
||||
|
|
Loading…
Reference in a new issue