mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2025-12-26 18:10:08 +01:00
bluez: merge branch 'th/bluez-rework-2'
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/merge_requests/251
This commit is contained in:
commit
e79f1b623d
54 changed files with 4939 additions and 2917 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -206,6 +206,7 @@ test-*.trs
|
|||
|
||||
/src/NetworkManager
|
||||
/src/NetworkManager.ver
|
||||
/src/devices/bluetooth/tests/nm-bt-test
|
||||
/src/devices/tests/test-acd
|
||||
/src/devices/tests/test-lldp
|
||||
/src/devices/wifi/tests/test-devices-wifi
|
||||
|
|
|
|||
67
Makefile.am
67
Makefile.am
|
|
@ -3408,18 +3408,41 @@ EXTRA_DIST += \
|
|||
|
||||
if WITH_MODEM_MANAGER_1
|
||||
|
||||
noinst_LTLIBRARIES += src/devices/bluetooth/libnm-bluetooth-utils.la
|
||||
|
||||
src_devices_bluetooth_libnm_bluetooth_utils_la_SOURCES = \
|
||||
src/devices/bluetooth/nm-bluez-common.h \
|
||||
src/devices/bluetooth/nm-bt-error.c \
|
||||
src/devices/bluetooth/nm-bt-error.h \
|
||||
$(NULL)
|
||||
|
||||
src_devices_bluetooth_libnm_bluetooth_utils_la_CPPFLAGS = \
|
||||
$(src_cppflags_base) \
|
||||
$(NULL)
|
||||
|
||||
src_devices_bluetooth_libnm_bluetooth_utils_la_LIBADD = \
|
||||
$(GLIB_LIBS) \
|
||||
$(NULL)
|
||||
|
||||
if WITH_BLUEZ5_DUN
|
||||
src_devices_bluetooth_libnm_bluetooth_utils_la_SOURCES += \
|
||||
src/devices/bluetooth/nm-bluez5-dun.c \
|
||||
src/devices/bluetooth/nm-bluez5-dun.h \
|
||||
$(NULL)
|
||||
|
||||
src_devices_bluetooth_libnm_bluetooth_utils_la_CPPFLAGS += $(BLUEZ5_CFLAGS)
|
||||
src_devices_bluetooth_libnm_bluetooth_utils_la_LIBADD += $(BLUEZ5_LIBS)
|
||||
endif
|
||||
|
||||
$(src_devices_bluetooth_libnm_bluetooth_utils_la_OBJECTS): $(libnm_core_lib_h_pub_mkenums)
|
||||
|
||||
###############################################################################
|
||||
|
||||
core_plugins += src/devices/bluetooth/libnm-device-plugin-bluetooth.la
|
||||
|
||||
src_devices_bluetooth_libnm_device_plugin_bluetooth_la_SOURCES = \
|
||||
src/devices/bluetooth/nm-bluez-manager.c \
|
||||
src/devices/bluetooth/nm-bluez-common.h \
|
||||
src/devices/bluetooth/nm-bluez-device.c \
|
||||
src/devices/bluetooth/nm-bluez-device.h \
|
||||
src/devices/bluetooth/nm-bluez5-manager.c \
|
||||
src/devices/bluetooth/nm-bluez5-manager.h \
|
||||
src/devices/bluetooth/nm-bt-error.h \
|
||||
src/devices/bluetooth/nm-bt-error.c \
|
||||
\
|
||||
src/devices/bluetooth/nm-bluez-manager.h \
|
||||
src/devices/bluetooth/nm-device-bt.c \
|
||||
src/devices/bluetooth/nm-device-bt.h \
|
||||
$(NULL)
|
||||
|
|
@ -3431,18 +3454,30 @@ src_devices_bluetooth_libnm_device_plugin_bluetooth_la_LDFLAGS = \
|
|||
-Wl,--version-script="$(srcdir)/linker-script-devices.ver"
|
||||
|
||||
src_devices_bluetooth_libnm_device_plugin_bluetooth_la_LIBADD = \
|
||||
src/devices/bluetooth/libnm-bluetooth-utils.la \
|
||||
src/devices/wwan/libnm-wwan.la \
|
||||
$(GLIB_LIBS)
|
||||
$(GLIB_LIBS) \
|
||||
$(NULL)
|
||||
|
||||
if WITH_BLUEZ5_DUN
|
||||
src_devices_bluetooth_libnm_device_plugin_bluetooth_la_CPPFLAGS += $(BLUEZ5_CFLAGS)
|
||||
$(src_devices_bluetooth_libnm_device_plugin_bluetooth_la_OBJECTS): $(libnm_core_lib_h_pub_mkenums)
|
||||
|
||||
src_devices_bluetooth_libnm_device_plugin_bluetooth_la_SOURCES += \
|
||||
src/devices/bluetooth/nm-bluez5-dun.c \
|
||||
src/devices/bluetooth/nm-bluez5-dun.h
|
||||
###############################################################################
|
||||
|
||||
src_devices_bluetooth_libnm_device_plugin_bluetooth_la_LIBADD += $(BLUEZ5_LIBS)
|
||||
endif
|
||||
check_programs_norun += \
|
||||
src/devices/bluetooth/tests/nm-bt-test
|
||||
|
||||
src_devices_bluetooth_tests_nm_bt_test_CPPFLAGS = \
|
||||
$(src_cppflags_test) \
|
||||
$(NULL)
|
||||
src_devices_bluetooth_tests_nm_bt_test_LDADD = \
|
||||
src/devices/bluetooth/libnm-bluetooth-utils.la \
|
||||
src/libNetworkManager.la \
|
||||
$(GLIB_LIBS) \
|
||||
$(NULL)
|
||||
|
||||
$(src_devices_bluetooth_tests_nm_bt_test_OBJECTS): $(libnm_core_lib_h_pub_mkenums)
|
||||
|
||||
###############################################################################
|
||||
|
||||
check-local-devices-bluetooth: src/devices/bluetooth/libnm-device-plugin-bluetooth.la
|
||||
$(srcdir)/tools/check-exports.sh $(builddir)/src/devices/bluetooth/.libs/libnm-device-plugin-bluetooth.so "$(srcdir)/linker-script-devices.ver"
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -587,6 +587,28 @@ Connection 'ethernet-4' (de89cdeb-a3e1-4d53-8fa0-c22546c775f4) successfully
|
|||
</para>
|
||||
</example>
|
||||
|
||||
<example><title>Bluetooth connection profiles</title>
|
||||
<para>NetworkManger supports both connecting to NAP and DUN devices as a client. It also
|
||||
supports sharing the network via a NAP server.
|
||||
</para>
|
||||
<para>For NAP client connections, NetworkManager automatically creates a suitable in-memory profile
|
||||
for paired devices if none is available. You may use that generated profile directly, but you may also modify
|
||||
and persist it, which will prevent to automatically re-create it. You may also create a profile from scratch.
|
||||
For example, the following uses DHCP and IPv6 autoconf for address configuration:
|
||||
</para>
|
||||
<screen><prompt>$ </prompt><userinput>nmcli connection add type bluetooth con-name "Profile for My Bluetooth Device (NAP)" autoconnect no bluetooth.type panu bluetooth.bdaddr "$BDADDR"</userinput></screen>
|
||||
<para>For DUN connections, the user needs to configure modem settings and hence no profile
|
||||
gets created automatically. The modem settings depend on your device and you either need
|
||||
a "gsm" or a "csma" section. For example,
|
||||
</para>
|
||||
<screen><prompt>$ </prompt><userinput>nmcli connection add type bluetooth con-name "Profile for My Bluetooth Device (DUN)" autoconnect no bluetooth.type dun bluetooth.bdaddr "$BDADDR" gsm.apn apn.com</userinput></screen>
|
||||
<para>Finally, you can create a bluetooth hotspot. BlueZ implements those as a bridge device,
|
||||
so such profiles also have a bridge section. Also, you probably want to set IP methods as "shared",
|
||||
so that clients get automatic IP addressing. Note that the "shared" IPv4 method requires dnsmasq to be available.
|
||||
</para>
|
||||
<screen><prompt>$ </prompt><userinput>nmcli connection add type bluetooth con-name "My Bluetooth Hotspot" autoconnect no ifname btnap0 bluetooth.type nap ipv4.method shared ipv6.method shared</userinput></screen>
|
||||
</example>
|
||||
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -53,3 +53,195 @@ nm_dbus_connection_call_get_name_owner (GDBusConnection *dbus_connection,
|
|||
_nm_dbus_connection_call_get_name_owner_cb,
|
||||
nm_utils_user_data_pack (user_data, callback));
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
_nm_dbus_connection_call_get_all_cb (GObject *source,
|
||||
GAsyncResult *res,
|
||||
gpointer user_data)
|
||||
{
|
||||
gs_unref_variant GVariant *ret = NULL;
|
||||
gs_free_error GError *error = NULL;
|
||||
gpointer orig_user_data;
|
||||
NMDBusConnectionCallDefaultCb callback;
|
||||
|
||||
nm_utils_user_data_unpack (user_data, &orig_user_data, &callback);
|
||||
|
||||
ret = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source), res, &error);
|
||||
|
||||
nm_assert ((!!ret) != (!!error));
|
||||
|
||||
callback (ret, error, orig_user_data);
|
||||
}
|
||||
|
||||
void
|
||||
nm_dbus_connection_call_get_all (GDBusConnection *dbus_connection,
|
||||
const char *bus_name,
|
||||
const char *object_path,
|
||||
const char *interface_name,
|
||||
int timeout_msec,
|
||||
GCancellable *cancellable,
|
||||
NMDBusConnectionCallDefaultCb callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
nm_assert (callback);
|
||||
|
||||
g_dbus_connection_call (dbus_connection,
|
||||
bus_name,
|
||||
object_path,
|
||||
DBUS_INTERFACE_PROPERTIES,
|
||||
"GetAll",
|
||||
g_variant_new ("(s)", interface_name),
|
||||
G_VARIANT_TYPE ("(a{sv})"),
|
||||
G_DBUS_CALL_FLAGS_NONE,
|
||||
timeout_msec,
|
||||
cancellable,
|
||||
_nm_dbus_connection_call_get_all_cb,
|
||||
nm_utils_user_data_pack (user_data, callback));
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
typedef struct {
|
||||
NMDBusConnectionSignalObjectMangerCb callback;
|
||||
gpointer user_data;
|
||||
GDestroyNotify user_data_free_func;
|
||||
} SubscribeObjectManagerData;
|
||||
|
||||
static void
|
||||
_subscribe_object_manager_cb (GDBusConnection *connection,
|
||||
const char *sender_name,
|
||||
const char *arg_object_path,
|
||||
const char *interface_name,
|
||||
const char *signal_name,
|
||||
GVariant *parameters,
|
||||
gpointer user_data)
|
||||
{
|
||||
const SubscribeObjectManagerData *d = user_data;
|
||||
|
||||
nm_assert (nm_streq0 (interface_name, DBUS_INTERFACE_OBJECT_MANAGER));
|
||||
|
||||
if (nm_streq (signal_name, "InterfacesAdded")) {
|
||||
gs_unref_variant GVariant *interfaces_and_properties = NULL;
|
||||
const char *object_path;
|
||||
|
||||
if (!g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(oa{sa{sv}})")))
|
||||
return;
|
||||
|
||||
g_variant_get (parameters,
|
||||
"(&o@a{sa{sv}})",
|
||||
&object_path,
|
||||
&interfaces_and_properties);
|
||||
|
||||
d->callback (object_path, interfaces_and_properties, NULL, d->user_data);
|
||||
return;
|
||||
}
|
||||
|
||||
if (nm_streq (signal_name, "InterfacesRemoved")) {
|
||||
gs_free const char **interfaces = NULL;
|
||||
const char *object_path;
|
||||
|
||||
if (!g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(oas)")))
|
||||
return;
|
||||
|
||||
g_variant_get (parameters,
|
||||
"(&o^a&s)",
|
||||
&object_path,
|
||||
&interfaces);
|
||||
|
||||
d->callback (object_path, NULL, interfaces, d->user_data);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_subscribe_object_manager_data_free (gpointer ptr)
|
||||
{
|
||||
SubscribeObjectManagerData *d = ptr;
|
||||
|
||||
if (d->user_data_free_func)
|
||||
d->user_data_free_func (d->user_data);
|
||||
nm_g_slice_free (d);
|
||||
}
|
||||
|
||||
guint
|
||||
nm_dbus_connection_signal_subscribe_object_manager (GDBusConnection *dbus_connection,
|
||||
const char *service_name,
|
||||
const char *object_path,
|
||||
NMDBusConnectionSignalObjectMangerCb callback,
|
||||
gpointer user_data,
|
||||
GDestroyNotify user_data_free_func)
|
||||
{
|
||||
SubscribeObjectManagerData *d;
|
||||
|
||||
g_return_val_if_fail (callback, 0);
|
||||
|
||||
d = g_slice_new (SubscribeObjectManagerData);
|
||||
*d = (SubscribeObjectManagerData) {
|
||||
.callback = callback,
|
||||
.user_data = user_data,
|
||||
.user_data_free_func = user_data_free_func,
|
||||
};
|
||||
|
||||
return nm_dbus_connection_signal_subscribe_object_manager_plain (dbus_connection,
|
||||
service_name,
|
||||
object_path,
|
||||
NULL,
|
||||
_subscribe_object_manager_cb,
|
||||
d,
|
||||
_subscribe_object_manager_data_free);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
_nm_dbus_connection_call_get_managed_objects_cb (GObject *source,
|
||||
GAsyncResult *res,
|
||||
gpointer user_data)
|
||||
{
|
||||
gs_unref_variant GVariant *ret = NULL;
|
||||
gs_unref_variant GVariant *arg = NULL;
|
||||
gs_free_error GError *error = NULL;
|
||||
gpointer orig_user_data;
|
||||
NMDBusConnectionCallDefaultCb callback;
|
||||
|
||||
nm_utils_user_data_unpack (user_data, &orig_user_data, &callback);
|
||||
|
||||
ret = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source), res, &error);
|
||||
|
||||
nm_assert ((!!ret) != (!!error));
|
||||
|
||||
if (ret) {
|
||||
nm_assert (g_variant_is_of_type (ret, G_VARIANT_TYPE ("(a{oa{sa{sv}}})")));
|
||||
arg = g_variant_get_child_value (ret, 0);
|
||||
}
|
||||
|
||||
callback (arg, error, orig_user_data);
|
||||
}
|
||||
|
||||
void
|
||||
nm_dbus_connection_call_get_managed_objects (GDBusConnection *dbus_connection,
|
||||
const char *bus_name,
|
||||
const char *object_path,
|
||||
GDBusCallFlags flags,
|
||||
int timeout_msec,
|
||||
GCancellable *cancellable,
|
||||
NMDBusConnectionCallDefaultCb callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
nm_assert (callback);
|
||||
|
||||
g_dbus_connection_call (dbus_connection,
|
||||
bus_name,
|
||||
object_path,
|
||||
DBUS_INTERFACE_OBJECT_MANAGER,
|
||||
"GetManagedObjects",
|
||||
NULL,
|
||||
G_VARIANT_TYPE ("(a{oa{sa{sv}}})"),
|
||||
flags,
|
||||
timeout_msec,
|
||||
cancellable,
|
||||
_nm_dbus_connection_call_get_managed_objects_cb,
|
||||
nm_utils_user_data_pack (user_data, callback));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,6 +28,12 @@ nm_clear_g_dbus_connection_signal (GDBusConnection *dbus_connection,
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
typedef void (*NMDBusConnectionCallDefaultCb) (GVariant *result,
|
||||
GError *error,
|
||||
gpointer user_data);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static inline void
|
||||
nm_dbus_connection_call_start_service_by_name (GDBusConnection *dbus_connection,
|
||||
const char *name,
|
||||
|
|
@ -77,11 +83,95 @@ typedef void (*NMDBusConnectionCallGetNameOwnerCb) (const char *name_owner,
|
|||
gpointer user_data);
|
||||
|
||||
void nm_dbus_connection_call_get_name_owner (GDBusConnection *dbus_connection,
|
||||
const char *service_name,
|
||||
int timeout_msec,
|
||||
GCancellable *cancellable,
|
||||
NMDBusConnectionCallGetNameOwnerCb callback,
|
||||
gpointer user_data);
|
||||
const char *service_name,
|
||||
int timeout_msec,
|
||||
GCancellable *cancellable,
|
||||
NMDBusConnectionCallGetNameOwnerCb callback,
|
||||
gpointer user_data);
|
||||
|
||||
static inline guint
|
||||
nm_dbus_connection_signal_subscribe_properties_changed (GDBusConnection *dbus_connection,
|
||||
const char *bus_name,
|
||||
const char *object_path,
|
||||
const char *interface_name,
|
||||
GDBusSignalCallback callback,
|
||||
gpointer user_data,
|
||||
GDestroyNotify user_data_free_func)
|
||||
|
||||
{
|
||||
nm_assert (bus_name);
|
||||
|
||||
/* it seems that using a non-unique name causes problems that we get signals
|
||||
* also from unrelated senders. Usually, you are anyway monitoring the name-owner,
|
||||
* so you should have the unique name at hand.
|
||||
*
|
||||
* If not, investigate this, ensure that it works, and lift this restriction. */
|
||||
nm_assert (g_dbus_is_unique_name (bus_name));
|
||||
|
||||
return g_dbus_connection_signal_subscribe (dbus_connection,
|
||||
bus_name,
|
||||
DBUS_INTERFACE_PROPERTIES,
|
||||
"PropertiesChanged",
|
||||
object_path,
|
||||
interface_name,
|
||||
G_DBUS_SIGNAL_FLAGS_NONE,
|
||||
callback,
|
||||
user_data,
|
||||
user_data_free_func);
|
||||
}
|
||||
|
||||
void nm_dbus_connection_call_get_all (GDBusConnection *dbus_connection,
|
||||
const char *bus_name,
|
||||
const char *object_path,
|
||||
const char *interface_name,
|
||||
int timeout_msec,
|
||||
GCancellable *cancellable,
|
||||
NMDBusConnectionCallDefaultCb callback,
|
||||
gpointer user_data);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static inline guint
|
||||
nm_dbus_connection_signal_subscribe_object_manager_plain (GDBusConnection *dbus_connection,
|
||||
const char *service_name,
|
||||
const char *object_path,
|
||||
const char *signal_name,
|
||||
GDBusSignalCallback callback,
|
||||
gpointer user_data,
|
||||
GDestroyNotify user_data_free_func)
|
||||
{
|
||||
return g_dbus_connection_signal_subscribe (dbus_connection,
|
||||
service_name,
|
||||
DBUS_INTERFACE_OBJECT_MANAGER,
|
||||
signal_name,
|
||||
object_path,
|
||||
NULL,
|
||||
G_DBUS_SIGNAL_FLAGS_NONE,
|
||||
callback,
|
||||
user_data,
|
||||
user_data_free_func);
|
||||
}
|
||||
|
||||
typedef void (*NMDBusConnectionSignalObjectMangerCb) (const char *object_path,
|
||||
GVariant *added_interfaces_and_properties,
|
||||
const char *const*removed_interfaces,
|
||||
gpointer user_data);
|
||||
|
||||
guint nm_dbus_connection_signal_subscribe_object_manager (GDBusConnection *dbus_connection,
|
||||
const char *service_name,
|
||||
const char *object_path,
|
||||
NMDBusConnectionSignalObjectMangerCb callback,
|
||||
gpointer user_data,
|
||||
GDestroyNotify user_data_free_func);
|
||||
|
||||
void nm_dbus_connection_call_get_managed_objects (GDBusConnection *dbus_connection,
|
||||
const char *bus_name,
|
||||
const char *object_path,
|
||||
GDBusCallFlags flags,
|
||||
int timeout_msec,
|
||||
GCancellable *cancellable,
|
||||
NMDBusConnectionCallDefaultCb callback,
|
||||
gpointer user_data);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
|
|
|
|||
|
|
@ -310,6 +310,12 @@ _nm_auto_protect_errno (int *p_saved_errno)
|
|||
NM_AUTO_DEFINE_FCN0 (GSource *, _nm_auto_unref_gsource, g_source_unref);
|
||||
#define nm_auto_unref_gsource nm_auto(_nm_auto_unref_gsource)
|
||||
|
||||
NM_AUTO_DEFINE_FCN0 (guint, _nm_auto_remove_source, g_source_remove);
|
||||
#define nm_auto_remove_source nm_auto(_nm_auto_remove_source)
|
||||
|
||||
NM_AUTO_DEFINE_FCN0 (GIOChannel *, _nm_auto_unref_io_channel, g_io_channel_unref)
|
||||
#define nm_auto_unref_io_channel nm_auto(_nm_auto_unref_io_channel)
|
||||
|
||||
NM_AUTO_DEFINE_FCN0 (GMainLoop *, _nm_auto_unref_gmainloop, g_main_loop_unref);
|
||||
#define nm_auto_unref_gmainloop nm_auto(_nm_auto_unref_gmainloop)
|
||||
|
||||
|
|
|
|||
|
|
@ -2288,6 +2288,44 @@ nm_utils_hash_keys_to_array (GHashTable *hash,
|
|||
return keys;
|
||||
}
|
||||
|
||||
gpointer *
|
||||
nm_utils_hash_values_to_array (GHashTable *hash,
|
||||
GCompareDataFunc compare_func,
|
||||
gpointer user_data,
|
||||
guint *out_len)
|
||||
{
|
||||
GHashTableIter iter;
|
||||
gpointer value;
|
||||
gpointer *arr;
|
||||
guint i, len;
|
||||
|
||||
if ( !hash
|
||||
|| (len = g_hash_table_size (hash)) == 0u) {
|
||||
NM_SET_OUT (out_len, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
arr = g_new (gpointer, ((gsize) len) + 1);
|
||||
i = 0;
|
||||
g_hash_table_iter_init (&iter, hash);
|
||||
while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &value))
|
||||
arr[i++] = value;
|
||||
|
||||
nm_assert (i == len);
|
||||
arr[len] = NULL;
|
||||
|
||||
if ( len > 1
|
||||
&& compare_func) {
|
||||
g_qsort_with_data (arr,
|
||||
len,
|
||||
sizeof (gpointer),
|
||||
compare_func,
|
||||
user_data);
|
||||
}
|
||||
|
||||
return arr;
|
||||
}
|
||||
|
||||
gboolean
|
||||
nm_utils_hashtable_same_keys (const GHashTable *a,
|
||||
const GHashTable *b)
|
||||
|
|
|
|||
|
|
@ -638,6 +638,7 @@ _nm_g_slice_free_fcn_define (8)
|
|||
_nm_g_slice_free_fcn_define (10)
|
||||
_nm_g_slice_free_fcn_define (12)
|
||||
_nm_g_slice_free_fcn_define (16)
|
||||
_nm_g_slice_free_fcn_define (32)
|
||||
|
||||
#define _nm_g_slice_free_fcn1(mem_size) \
|
||||
({ \
|
||||
|
|
@ -652,7 +653,8 @@ _nm_g_slice_free_fcn_define (16)
|
|||
|| ((mem_size) == 8) \
|
||||
|| ((mem_size) == 10) \
|
||||
|| ((mem_size) == 12) \
|
||||
|| ((mem_size) == 16)); \
|
||||
|| ((mem_size) == 16) \
|
||||
|| ((mem_size) == 32)); \
|
||||
switch ((mem_size)) { \
|
||||
case 1: _fcn = _nm_g_slice_free_fcn_1; break; \
|
||||
case 2: _fcn = _nm_g_slice_free_fcn_2; break; \
|
||||
|
|
@ -661,6 +663,7 @@ _nm_g_slice_free_fcn_define (16)
|
|||
case 10: _fcn = _nm_g_slice_free_fcn_10; break; \
|
||||
case 12: _fcn = _nm_g_slice_free_fcn_12; break; \
|
||||
case 16: _fcn = _nm_g_slice_free_fcn_16; break; \
|
||||
case 32: _fcn = _nm_g_slice_free_fcn_32; break; \
|
||||
default: g_assert_not_reached (); _fcn = NULL; break; \
|
||||
} \
|
||||
_fcn; \
|
||||
|
|
@ -952,6 +955,11 @@ gpointer *nm_utils_hash_keys_to_array (GHashTable *hash,
|
|||
gpointer user_data,
|
||||
guint *out_len);
|
||||
|
||||
gpointer *nm_utils_hash_values_to_array (GHashTable *hash,
|
||||
GCompareDataFunc compare_func,
|
||||
gpointer user_data,
|
||||
guint *out_len);
|
||||
|
||||
static inline const char **
|
||||
nm_utils_strdict_get_keys (const GHashTable *hash,
|
||||
gboolean sorted,
|
||||
|
|
|
|||
|
|
@ -31,6 +31,8 @@
|
|||
/** The interface supported by most dbus peers */
|
||||
#define DBUS_INTERFACE_PEER "org.freedesktop.DBus.Peer"
|
||||
|
||||
#define DBUS_INTERFACE_OBJECT_MANAGER "org.freedesktop.DBus.ObjectManager"
|
||||
|
||||
/** This is a special interface whose methods can only be invoked
|
||||
* by the local implementation (messages from remote apps aren't
|
||||
* allowed to specify this interface).
|
||||
|
|
|
|||
|
|
@ -946,9 +946,10 @@ nm_ip_routing_rule_to_platform (const NMIPRoutingRule *rule,
|
|||
|
||||
struct _NMShutdownWaitObjHandle {
|
||||
CList lst;
|
||||
GObject *watched_obj;
|
||||
gpointer watched_obj;
|
||||
char *msg_reason;
|
||||
bool free_msg_reason:1;
|
||||
bool is_cancellable:1;
|
||||
};
|
||||
|
||||
static CList _shutdown_waitobj_lst_head;
|
||||
|
|
@ -967,7 +968,7 @@ _shutdown_waitobj_unregister (NMShutdownWaitObjHandle *handle)
|
|||
|
||||
static void
|
||||
_shutdown_waitobj_cb (gpointer user_data,
|
||||
GObject *where_the_object_was)
|
||||
GObject *where_the_object_was)
|
||||
{
|
||||
NMShutdownWaitObjHandle *handle = user_data;
|
||||
|
||||
|
|
@ -980,6 +981,8 @@ _shutdown_waitobj_cb (gpointer user_data,
|
|||
* nm_shutdown_wait_obj_register_full:
|
||||
* @watched_obj: the object to watch. Takes a weak reference on the object
|
||||
* to be notified when it gets destroyed.
|
||||
* @wait_type: whether @watched_obj is just a plain GObject or a GCancellable
|
||||
* that should be cancelled.
|
||||
* @msg_reason: a reason message, for debugging and logging purposes.
|
||||
* @free_msg_reason: if %TRUE, then ownership of @msg_reason will be taken
|
||||
* and the string will be freed with g_free() afterwards. If %FALSE,
|
||||
|
|
@ -993,21 +996,41 @@ _shutdown_waitobj_cb (gpointer user_data,
|
|||
* the reference-counter of @watched_obj as signal, that the object
|
||||
* is still used.
|
||||
*
|
||||
* If @wait_type is %NM_SHUTDOWN_WAIT_TYPE_CANCELLABLE, then during shutdown
|
||||
* (after %NM_SHUTDOWN_TIMEOUT_MS), the cancellable will be cancelled to notify
|
||||
* the source of the shutdown. Note that otherwise, in this mode also @watched_obj
|
||||
* is only tracked with a weak-pointer. Especially, it does not register to the
|
||||
* "cancelled" signal to automatically unregister (otherwise, you would never
|
||||
* know whether the returned NMShutdownWaitObjHandle is still valid.
|
||||
*
|
||||
* FIXME(shutdown): proper shutdown is not yet implemented, and registering
|
||||
* an object (currently) has no effect.
|
||||
*
|
||||
* FIXME(shutdown): during shutdown, after %NM_SHUTDOWN_TIMEOUT_MS timeout, cancel
|
||||
* all remaining %NM_SHUTDOWN_WAIT_TYPE_CANCELLABLE instances. Also, when somebody
|
||||
* enqueues a cancellable after that point, cancel it right away on an idle handler.
|
||||
*
|
||||
* Returns: a handle to unregister the object. The caller may choose to ignore
|
||||
* the handle, in which case, the object will be automatically unregistered,
|
||||
* once it gets destroyed.
|
||||
* Note that the handle is only valid as long as @watched_obj exists. If
|
||||
* you plan to use it, ensure that you take care of not using it after
|
||||
* destroying @watched_obj.
|
||||
*/
|
||||
NMShutdownWaitObjHandle *
|
||||
nm_shutdown_wait_obj_register_full (GObject *watched_obj,
|
||||
nm_shutdown_wait_obj_register_full (gpointer watched_obj,
|
||||
NMShutdownWaitType wait_type,
|
||||
char *msg_reason,
|
||||
gboolean free_msg_reason)
|
||||
{
|
||||
NMShutdownWaitObjHandle *handle;
|
||||
|
||||
g_return_val_if_fail (G_IS_OBJECT (watched_obj), NULL);
|
||||
if (wait_type == NM_SHUTDOWN_WAIT_TYPE_OBJECT)
|
||||
g_return_val_if_fail (G_IS_OBJECT (watched_obj), NULL);
|
||||
else if (wait_type == NM_SHUTDOWN_WAIT_TYPE_CANCELLABLE)
|
||||
g_return_val_if_fail (G_IS_CANCELLABLE (watched_obj), NULL);
|
||||
else
|
||||
g_return_val_if_reached (NULL);
|
||||
|
||||
if (G_UNLIKELY (!_shutdown_waitobj_lst_head.next))
|
||||
c_list_init (&_shutdown_waitobj_lst_head);
|
||||
|
|
@ -1020,6 +1043,7 @@ nm_shutdown_wait_obj_register_full (GObject *watched_obj,
|
|||
.watched_obj = watched_obj,
|
||||
.msg_reason = msg_reason,
|
||||
.free_msg_reason = free_msg_reason,
|
||||
.is_cancellable = (wait_type == NM_SHUTDOWN_WAIT_TYPE_CANCELLABLE),
|
||||
};
|
||||
c_list_link_tail (&_shutdown_waitobj_lst_head, &handle->lst);
|
||||
g_object_weak_ref (watched_obj, _shutdown_waitobj_cb, handle);
|
||||
|
|
|
|||
|
|
@ -74,13 +74,43 @@ NMPlatformRoutingRule *nm_ip_routing_rule_to_platform (const NMIPRoutingRule *ru
|
|||
#define NM_SHUTDOWN_TIMEOUT_MS 1500
|
||||
#define NM_SHUTDOWN_TIMEOUT_MS_WATCHDOG 500
|
||||
|
||||
typedef enum {
|
||||
/* The watched_obj argument is a GObject, and shutdown is delayed until the object
|
||||
* gets destroyed (or unregistered). */
|
||||
NM_SHUTDOWN_WAIT_TYPE_OBJECT,
|
||||
|
||||
/* The watched_obj argument is a GCancellable, and shutdown is delayed until the object
|
||||
* gets destroyed (or unregistered). Note that after NM_SHUTDOWN_TIMEOUT_MS, the
|
||||
* cancellable will be cancelled to notify listeners about the shutdown. */
|
||||
NM_SHUTDOWN_WAIT_TYPE_CANCELLABLE,
|
||||
} NMShutdownWaitType;
|
||||
|
||||
typedef struct _NMShutdownWaitObjHandle NMShutdownWaitObjHandle;
|
||||
|
||||
NMShutdownWaitObjHandle *nm_shutdown_wait_obj_register_full (GObject *watched_obj,
|
||||
NMShutdownWaitObjHandle *nm_shutdown_wait_obj_register_full (gpointer watched_obj,
|
||||
NMShutdownWaitType wait_type,
|
||||
char *msg_reason,
|
||||
gboolean free_msg_reason);
|
||||
|
||||
#define nm_shutdown_wait_obj_register(watched_obj, msg_reason) nm_shutdown_wait_obj_register_full((watched_obj), (""msg_reason""), FALSE)
|
||||
static inline NMShutdownWaitObjHandle *
|
||||
nm_shutdown_wait_obj_register_object_full (gpointer watched_obj,
|
||||
char *msg_reason,
|
||||
gboolean free_msg_reason)
|
||||
{
|
||||
return nm_shutdown_wait_obj_register_full (watched_obj, NM_SHUTDOWN_WAIT_TYPE_OBJECT, msg_reason, free_msg_reason);
|
||||
}
|
||||
|
||||
#define nm_shutdown_wait_obj_register_object(watched_obj, msg_reason) nm_shutdown_wait_obj_register_object_full((watched_obj), (""msg_reason""), FALSE)
|
||||
|
||||
static inline NMShutdownWaitObjHandle *
|
||||
nm_shutdown_wait_obj_register_cancellable_full (GCancellable *watched_obj,
|
||||
char *msg_reason,
|
||||
gboolean free_msg_reason)
|
||||
{
|
||||
return nm_shutdown_wait_obj_register_full (watched_obj, NM_SHUTDOWN_WAIT_TYPE_CANCELLABLE, msg_reason, free_msg_reason);
|
||||
}
|
||||
|
||||
#define nm_shutdown_wait_obj_register_cancellable(watched_obj, msg_reason) nm_shutdown_wait_obj_register_cancellable_full((watched_obj), (""msg_reason""), FALSE)
|
||||
|
||||
void nm_shutdown_wait_obj_unregister (NMShutdownWaitObjHandle *handle);
|
||||
|
||||
|
|
|
|||
|
|
@ -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',
|
||||
)
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@
|
|||
#define NM_BLUEZ_SERVICE "org.bluez"
|
||||
|
||||
#define NM_BLUEZ_MANAGER_PATH "/"
|
||||
#define NM_OBJECT_MANAGER_INTERFACE "org.freedesktop.DBus.ObjectManager"
|
||||
|
||||
#define NM_BLUEZ5_ADAPTER_INTERFACE "org.bluez.Adapter1"
|
||||
#define NM_BLUEZ5_DEVICE_INTERFACE "org.bluez.Device1"
|
||||
|
|
|
|||
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,584 +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 "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,
|
||||
NM_OBJECT_MANAGER_INTERFACE,
|
||||
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__ */
|
||||
|
|
|
|||
220
src/devices/bluetooth/tests/nm-bt-test.c
Normal file
220
src/devices/bluetooth/tests/nm-bt-test.c
Normal file
|
|
@ -0,0 +1,220 @@
|
|||
// SPDX-License-Identifier: LGPL-2.1+
|
||||
|
||||
#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)
|
||||
{
|
||||
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_logging_init (NULL, TRUE);
|
||||
|
||||
gl.argv = (const char *const*) argv;
|
||||
gl.argc = argc;
|
||||
gl.loop = g_main_loop_new (NULL, FALSE);
|
||||
|
||||
_LOGI ("bluetooth test util start");
|
||||
|
||||
gl.argv_cmd = argc >= 2 ? argv[1] : NULL;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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(...) \
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ ppp_ifindex_set (NMPPPManager *ppp_manager,
|
|||
}
|
||||
|
||||
if (old_name)
|
||||
nm_manager_remove_device (nm_manager_get (), old_name, NM_DEVICE_TYPE_PPP);
|
||||
nm_manager_remove_device (NM_MANAGER_GET, old_name, NM_DEVICE_TYPE_PPP);
|
||||
|
||||
nm_device_activate_schedule_stage3_ip_config_start (device);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -145,7 +145,7 @@ act_stage1_prepare (NMDevice *device, NMDeviceStateReason *out_failure_reason)
|
|||
hwaddr_len);
|
||||
if ( lowpan_plink
|
||||
&& NM_FLAGS_HAS (lowpan_plink->n_ifi_flags, IFF_UP)) {
|
||||
lowpan_device = nm_manager_get_device_by_ifindex (nm_manager_get (),
|
||||
lowpan_device = nm_manager_get_device_by_ifindex (NM_MANAGER_GET,
|
||||
lowpan_plink->ifindex);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1717,7 +1717,7 @@ _parent_set_ifindex (NMDevice *self,
|
|||
}
|
||||
|
||||
if (parent_ifindex > 0) {
|
||||
parent_device = nm_manager_get_device_by_ifindex (nm_manager_get (), parent_ifindex);
|
||||
parent_device = nm_manager_get_device_by_ifindex (NM_MANAGER_GET, parent_ifindex);
|
||||
if (parent_device == self)
|
||||
parent_device = NULL;
|
||||
} else
|
||||
|
|
@ -2210,7 +2210,7 @@ nm_device_get_route_metric (NMDevice *self,
|
|||
if (route_metric >= 0)
|
||||
goto out;
|
||||
|
||||
route_metric = nm_manager_device_route_metric_reserve (nm_manager_get (),
|
||||
route_metric = nm_manager_device_route_metric_reserve (NM_MANAGER_GET,
|
||||
nm_device_get_ip_ifindex (self),
|
||||
nm_device_get_device_type (self));
|
||||
out:
|
||||
|
|
@ -3676,7 +3676,7 @@ device_recheck_slave_status (NMDevice *self, const NMPlatformLink *plink)
|
|||
if (plink->master <= 0)
|
||||
return;
|
||||
|
||||
master = nm_manager_get_device_by_ifindex (nm_manager_get (), plink->master);
|
||||
master = nm_manager_get_device_by_ifindex (NM_MANAGER_GET, plink->master);
|
||||
plink_master = nm_platform_link_get (nm_device_get_platform (self), plink->master);
|
||||
plink_master_keep_alive = nmp_object_ref (NMP_OBJECT_UP_CAST (plink_master));
|
||||
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -5895,7 +5877,7 @@ check_connection_compatible (NMDevice *self, NMConnection *connection, GError **
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
conn_iface = nm_manager_get_connection_iface (nm_manager_get (),
|
||||
conn_iface = nm_manager_get_connection_iface (NM_MANAGER_GET,
|
||||
connection,
|
||||
NULL,
|
||||
&local);
|
||||
|
|
@ -10658,7 +10640,7 @@ start_sharing (NMDevice *self, NMIP4Config *config, GError **error)
|
|||
* the announced setting without restarting dnsmasq. That means, if the default
|
||||
* route changes w.r.t. being metered, then the shared connection does not get
|
||||
* updated before reactivating. */
|
||||
announce_android_metered = NM_IN_SET (nm_manager_get_metered (nm_manager_get ()),
|
||||
announce_android_metered = NM_IN_SET (nm_manager_get_metered (NM_MANAGER_GET),
|
||||
NM_METERED_YES,
|
||||
NM_METERED_GUESS_YES);
|
||||
break;
|
||||
|
|
@ -14668,7 +14650,7 @@ _cleanup_generic_pre (NMDevice *self, CleanupType cleanup_type)
|
|||
priv->stage1_sriov_state = NM_DEVICE_STAGE_STATE_INIT;
|
||||
|
||||
if (cleanup_type != CLEANUP_TYPE_KEEP) {
|
||||
nm_manager_device_route_metric_clear (nm_manager_get (),
|
||||
nm_manager_device_route_metric_clear (NM_MANAGER_GET,
|
||||
nm_device_get_ip_ifindex (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);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ new_device_from_type (const char *name, NMDeviceType device_type)
|
|||
const char *type_desc;
|
||||
NMLinkType link_type = NM_LINK_TYPE_NONE;
|
||||
|
||||
if (nm_manager_get_device (nm_manager_get (), name, device_type))
|
||||
if (nm_manager_get_device (NM_MANAGER_GET, name, device_type))
|
||||
return NULL;
|
||||
|
||||
if (device_type == NM_DEVICE_TYPE_OVS_INTERFACE) {
|
||||
|
|
@ -117,7 +117,7 @@ ovsdb_device_removed (NMOvsdb *ovsdb, const char *name, NMDeviceType device_type
|
|||
NMDevice *device;
|
||||
NMDeviceState device_state;
|
||||
|
||||
device = nm_manager_get_device (nm_manager_get (), name, device_type);
|
||||
device = nm_manager_get_device (NM_MANAGER_GET, name, device_type);
|
||||
if (!device)
|
||||
return;
|
||||
|
||||
|
|
@ -145,7 +145,7 @@ ovsdb_interface_failed (NMOvsdb *ovsdb,
|
|||
|
||||
_LOGI (name, connection_uuid, "ovs interface \"%s\" (%s) failed: %s", name, connection_uuid, error);
|
||||
|
||||
device = nm_manager_get_device (nm_manager_get (), name, NM_DEVICE_TYPE_OVS_INTERFACE);
|
||||
device = nm_manager_get_device (NM_MANAGER_GET, name, NM_DEVICE_TYPE_OVS_INTERFACE);
|
||||
if (!device)
|
||||
return;
|
||||
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ NM_DEVICE_FACTORY_DECLARE_TYPES (
|
|||
G_MODULE_EXPORT NMDeviceFactory *
|
||||
nm_device_factory_create (GError **error)
|
||||
{
|
||||
nm_manager_set_capability (nm_manager_get (), NM_CAPABILITY_TEAM);
|
||||
nm_manager_set_capability (NM_MANAGER_GET, NM_CAPABILITY_TEAM);
|
||||
return (NMDeviceFactory *) g_object_new (NM_TYPE_TEAM_FACTORY, NULL);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -451,7 +451,7 @@ constructed (GObject *object)
|
|||
|
||||
G_OBJECT_CLASS (nm_device_olpc_mesh_parent_class)->constructed (object);
|
||||
|
||||
priv->manager = g_object_ref (nm_manager_get ());
|
||||
priv->manager = g_object_ref (NM_MANAGER_GET);
|
||||
|
||||
g_signal_connect (priv->manager, NM_MANAGER_DEVICE_ADDED, G_CALLBACK (device_added_cb), self);
|
||||
g_signal_connect (priv->manager, NM_MANAGER_DEVICE_REMOVED, G_CALLBACK (device_removed_cb), self);
|
||||
|
|
|
|||
|
|
@ -881,7 +881,7 @@ nm_iwd_manager_init (NMIwdManager *self)
|
|||
{
|
||||
NMIwdManagerPrivate *priv = NM_IWD_MANAGER_GET_PRIVATE (self);
|
||||
|
||||
priv->manager = g_object_ref (nm_manager_get ());
|
||||
priv->manager = g_object_ref (NM_MANAGER_GET);
|
||||
g_signal_connect (priv->manager, NM_MANAGER_DEVICE_ADDED,
|
||||
G_CALLBACK (device_added), self);
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ global:
|
|||
nm_modem_act_stage1_prepare;
|
||||
nm_modem_act_stage2_config;
|
||||
nm_modem_check_connection_compatible;
|
||||
nm_modem_claim;
|
||||
nm_modem_complete_connection;
|
||||
nm_modem_deactivate;
|
||||
nm_modem_deactivate_async;
|
||||
|
|
@ -14,15 +15,17 @@ global:
|
|||
nm_modem_get_device_id;
|
||||
nm_modem_get_driver;
|
||||
nm_modem_get_iid;
|
||||
nm_modem_get_path;
|
||||
nm_modem_get_ip_ifindex;
|
||||
nm_modem_get_operator_code;
|
||||
nm_modem_get_path;
|
||||
nm_modem_get_secrets;
|
||||
nm_modem_get_state;
|
||||
nm_modem_get_type;
|
||||
nm_modem_get_uid;
|
||||
nm_modem_ip4_pre_commit;
|
||||
nm_modem_is_claimed;
|
||||
nm_modem_manager_get;
|
||||
nm_modem_manager_get_modems;
|
||||
nm_modem_manager_get_type;
|
||||
nm_modem_manager_name_owner_get;
|
||||
nm_modem_manager_name_owner_ref;
|
||||
|
|
@ -32,6 +35,7 @@ global:
|
|||
nm_modem_stage3_ip4_config_start;
|
||||
nm_modem_stage3_ip6_config_start;
|
||||
nm_modem_state_to_string;
|
||||
nm_modem_unclaim;
|
||||
local:
|
||||
*;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -605,12 +605,9 @@ act_stage1_prepare (NMDevice *device, NMDeviceStateReason *out_failure_reason)
|
|||
static NMActStageReturn
|
||||
act_stage2_config (NMDevice *device, NMDeviceStateReason *out_failure_reason)
|
||||
{
|
||||
NMActRequest *req;
|
||||
nm_modem_act_stage2_config (NM_DEVICE_MODEM_GET_PRIVATE (device)->modem);
|
||||
|
||||
req = nm_device_get_act_request (device);
|
||||
g_return_val_if_fail (req, NM_ACT_STAGE_RETURN_FAILURE);
|
||||
|
||||
return nm_modem_act_stage2_config (NM_DEVICE_MODEM_GET_PRIVATE (device)->modem, req, out_failure_reason);
|
||||
return NM_ACT_STAGE_RETURN_SUCCESS;
|
||||
}
|
||||
|
||||
static NMActStageReturn
|
||||
|
|
@ -716,7 +713,7 @@ set_modem (NMDeviceModem *self, NMModem *modem)
|
|||
|
||||
g_return_if_fail (modem != NULL);
|
||||
|
||||
priv->modem = g_object_ref (modem);
|
||||
priv->modem = nm_modem_claim (modem);
|
||||
|
||||
g_signal_connect (modem, NM_MODEM_PPP_FAILED, G_CALLBACK (ppp_failed), self);
|
||||
g_signal_connect (modem, NM_MODEM_PREPARE_RESULT, G_CALLBACK (modem_prepare_result), self);
|
||||
|
|
@ -844,7 +841,7 @@ dispose (GObject *object)
|
|||
|
||||
if (priv->modem) {
|
||||
g_signal_handlers_disconnect_by_data (priv->modem, NM_DEVICE_MODEM (object));
|
||||
g_clear_object (&priv->modem);
|
||||
nm_clear_pointer (&priv->modem, nm_modem_unclaim);
|
||||
}
|
||||
|
||||
g_clear_pointer (&priv->device_id, g_free);
|
||||
|
|
|
|||
|
|
@ -136,6 +136,20 @@ remove_one_modem (gpointer key, gpointer value, gpointer user_data)
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
NMModem **
|
||||
nm_modem_manager_get_modems (NMModemManager *self,
|
||||
guint *out_len)
|
||||
{
|
||||
g_return_val_if_fail (NM_IS_MODEM_MANAGER (self), NULL);
|
||||
|
||||
return (NMModem **) nm_utils_hash_values_to_array (NM_MODEM_MANAGER_GET_PRIVATE (self)->modems,
|
||||
NULL,
|
||||
NULL,
|
||||
out_len);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
modm_clear_manager (NMModemManager *self)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -38,4 +38,7 @@ void nm_modem_manager_name_owner_unref (NMModemManager *self);
|
|||
|
||||
const char *nm_modem_manager_name_owner_get (NMModemManager *self);
|
||||
|
||||
NMModem **nm_modem_manager_get_modems (NMModemManager *self,
|
||||
guint *out_len);
|
||||
|
||||
#endif /* __NETWORKMANAGER_MODEM_MANAGER_H__ */
|
||||
|
|
|
|||
|
|
@ -97,6 +97,8 @@ typedef struct _NMModemPrivate {
|
|||
/* PPP stats */
|
||||
guint32 in_bytes;
|
||||
guint32 out_bytes;
|
||||
|
||||
bool claimed:1;
|
||||
} NMModemPrivate;
|
||||
|
||||
G_DEFINE_TYPE (NMModem, nm_modem, G_TYPE_OBJECT)
|
||||
|
|
@ -174,6 +176,53 @@ nm_modem_state_to_string (NMModemState state)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
gboolean
|
||||
nm_modem_is_claimed (NMModem *self)
|
||||
{
|
||||
g_return_val_if_fail (NM_IS_MODEM (self), FALSE);
|
||||
|
||||
return NM_MODEM_GET_PRIVATE (self)->claimed;
|
||||
}
|
||||
|
||||
NMModem *
|
||||
nm_modem_claim (NMModem *self)
|
||||
{
|
||||
NMModemPrivate *priv;
|
||||
|
||||
g_return_val_if_fail (NM_IS_MODEM (self), NULL);
|
||||
|
||||
priv = NM_MODEM_GET_PRIVATE (self);
|
||||
|
||||
g_return_val_if_fail (!priv->claimed, NULL);
|
||||
|
||||
priv->claimed = TRUE;
|
||||
return g_object_ref (self);
|
||||
}
|
||||
|
||||
void
|
||||
nm_modem_unclaim (NMModem *self)
|
||||
{
|
||||
NMModemPrivate *priv;
|
||||
|
||||
g_return_if_fail (NM_IS_MODEM (self));
|
||||
|
||||
priv = NM_MODEM_GET_PRIVATE (self);
|
||||
|
||||
g_return_if_fail (priv->claimed);
|
||||
|
||||
/* we don't actually unclaim the instance. This instance should not be re-used
|
||||
* by another owner, that is because we only claim modems as we receive them.
|
||||
* There is no mechanism that somebody else would later re-use them again.
|
||||
*
|
||||
* // priv->claimed = FALSE; */
|
||||
|
||||
g_object_unref (self);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
NMModemState
|
||||
nm_modem_get_state (NMModem *self)
|
||||
{
|
||||
|
|
@ -980,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);
|
||||
|
|
@ -1014,19 +1065,18 @@ nm_modem_act_stage1_prepare (NMModem *self,
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
NMActStageReturn
|
||||
nm_modem_act_stage2_config (NMModem *self,
|
||||
NMActRequest *req,
|
||||
NMDeviceStateReason *out_failure_reason)
|
||||
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.
|
||||
*/
|
||||
priv->secrets_tries = 0;
|
||||
|
||||
return NM_ACT_STAGE_RETURN_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
|
|||
|
|
@ -154,6 +154,10 @@ typedef struct {
|
|||
|
||||
GType nm_modem_get_type (void);
|
||||
|
||||
gboolean nm_modem_is_claimed (NMModem *modem);
|
||||
NMModem *nm_modem_claim (NMModem *modem);
|
||||
void nm_modem_unclaim (NMModem *modem);
|
||||
|
||||
const char *nm_modem_get_path (NMModem *modem);
|
||||
const char *nm_modem_get_uid (NMModem *modem);
|
||||
const char *nm_modem_get_control_port (NMModem *modem);
|
||||
|
|
@ -209,9 +213,7 @@ NMActStageReturn nm_modem_act_stage1_prepare (NMModem *modem,
|
|||
NMActRequest *req,
|
||||
NMDeviceStateReason *out_failure_reason);
|
||||
|
||||
NMActStageReturn nm_modem_act_stage2_config (NMModem *modem,
|
||||
NMActRequest *req,
|
||||
NMDeviceStateReason *out_failure_reason);
|
||||
void nm_modem_act_stage2_config (NMModem *modem);
|
||||
|
||||
NMActStageReturn nm_modem_stage3_ip4_config_start (NMModem *modem,
|
||||
NMDevice *device,
|
||||
|
|
|
|||
|
|
@ -64,11 +64,10 @@ modem_added_cb (NMModemManager *manager,
|
|||
gpointer user_data)
|
||||
{
|
||||
NMWwanFactory *self = NM_WWAN_FACTORY (user_data);
|
||||
NMDevice *device;
|
||||
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)))
|
||||
if (nm_modem_is_claimed (modem))
|
||||
return;
|
||||
|
||||
driver = nm_modem_get_driver (modem);
|
||||
|
|
@ -77,17 +76,16 @@ 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;
|
||||
}
|
||||
|
||||
/* Make the new modem device */
|
||||
device = nm_device_modem_new (modem);
|
||||
g_assert (device);
|
||||
g_signal_emit_by_name (self, NM_DEVICE_FACTORY_DEVICE_ADDED, device);
|
||||
g_object_unref (device);
|
||||
}
|
||||
|
||||
static NMDevice *
|
||||
|
|
|
|||
|
|
@ -1449,7 +1449,7 @@ static const GDBusSignalInfo signal_info_objmgr_interfaces_removed = NM_DEFINE_G
|
|||
);
|
||||
|
||||
static const GDBusInterfaceInfo interface_info_objmgr = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT (
|
||||
"org.freedesktop.DBus.ObjectManager",
|
||||
DBUS_INTERFACE_OBJECT_MANAGER,
|
||||
.methods = NM_DEFINE_GDBUS_METHOD_INFOS (
|
||||
NM_DEFINE_GDBUS_METHOD_INFO (
|
||||
"GetManagedObjects",
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
|
|||
|
|
@ -64,6 +64,7 @@ GType nm_manager_get_type (void);
|
|||
NMManager * nm_manager_setup (void);
|
||||
|
||||
NMManager * nm_manager_get (void);
|
||||
#define NM_MANAGER_GET (nm_manager_get ())
|
||||
|
||||
gboolean nm_manager_start (NMManager *manager,
|
||||
GError **error);
|
||||
|
|
@ -190,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__ */
|
||||
|
|
|
|||
|
|
@ -166,7 +166,7 @@ static void
|
|||
_clear_ip6_subnet (gpointer key, gpointer value, gpointer user_data)
|
||||
{
|
||||
NMPlatformIP6Address *subnet = value;
|
||||
NMDevice *device = nm_manager_get_device_by_ifindex (nm_manager_get (),
|
||||
NMDevice *device = nm_manager_get_device_by_ifindex (NM_MANAGER_GET,
|
||||
GPOINTER_TO_INT (key));
|
||||
|
||||
if (device) {
|
||||
|
|
|
|||
|
|
@ -1213,7 +1213,7 @@ _ppp_manager_stop (NMPPPManager *self,
|
|||
/* No PID. There is nothing to kill, however, invoke the callback in
|
||||
* an idle handler.
|
||||
*
|
||||
* Note that we don't register nm_shutdown_wait_obj_register().
|
||||
* Note that we don't register nm_shutdown_wait_obj_register_object().
|
||||
* In order for shutdown to work properly, the caller must always
|
||||
* explicitly cancel the action to go down. With the idle-handler,
|
||||
* cancelling the handle completes the request. */
|
||||
|
|
@ -1225,7 +1225,7 @@ _ppp_manager_stop (NMPPPManager *self,
|
|||
* until the process terminated. We do that, by registering an object
|
||||
* that delays shutdown. */
|
||||
handle->shutdown_waitobj = g_object_new (G_TYPE_OBJECT, NULL);
|
||||
nm_shutdown_wait_obj_register (handle->shutdown_waitobj, "ppp-manager-wait-kill-pppd");
|
||||
nm_shutdown_wait_obj_register_object (handle->shutdown_waitobj, "ppp-manager-wait-kill-pppd");
|
||||
nm_utils_kill_child_async (nm_steal_int (&priv->pid),
|
||||
SIGTERM, LOGD_PPP, "pppd",
|
||||
NM_SHUTDOWN_TIMEOUT_MS,
|
||||
|
|
|
|||
|
|
@ -160,7 +160,7 @@ _call_id_new (NMSecretAgent *self,
|
|||
/* self has async requests (that keep self alive). As long as
|
||||
* we have pending requests, shutdown is blocked. */
|
||||
priv->shutdown_wait_obj_registered = TRUE;
|
||||
nm_shutdown_wait_obj_register (G_OBJECT (self), "secret-agent");
|
||||
nm_shutdown_wait_obj_register_object (G_OBJECT (self), "secret-agent");
|
||||
}
|
||||
|
||||
return call_id;
|
||||
|
|
|
|||
|
|
@ -3116,9 +3116,9 @@ add_plugin (NMSettings *self,
|
|||
|
||||
priv->plugins = g_slist_append (priv->plugins, g_object_ref (plugin));
|
||||
|
||||
nm_shutdown_wait_obj_register_full (G_OBJECT (plugin),
|
||||
g_strdup_printf ("%s-settings-plugin", pname),
|
||||
TRUE);
|
||||
nm_shutdown_wait_obj_register_object_full (plugin,
|
||||
g_strdup_printf ("%s-settings-plugin", pname),
|
||||
TRUE);
|
||||
|
||||
_LOGI ("Loaded settings plugin: %s (%s%s%s)",
|
||||
pname,
|
||||
|
|
|
|||
|
|
@ -1925,7 +1925,7 @@ write_connection_setting (NMSettingConnection *s_con, shvarFile *ifcfg)
|
|||
* it into an interface name, so that legacy tooling is not confused. */
|
||||
if (!nm_utils_get_testing ()) {
|
||||
/* This is conditional for easier testing. */
|
||||
master_iface = nm_manager_iface_for_uuid (nm_manager_get (), master);
|
||||
master_iface = nm_manager_iface_for_uuid (NM_MANAGER_GET, master);
|
||||
}
|
||||
if (!master_iface) {
|
||||
master_iface = master;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue