From c22672b3834a92f16edb13aa3106873ed3aee91d Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Wed, 31 May 2017 19:08:12 +0200 Subject: [PATCH 01/21] libnm-core: fix verify() implementations to allow connection=NULL --- libnm-core/nm-connection.c | 3 +++ libnm-core/nm-setting-bond.c | 2 +- libnm-core/nm-setting-infiniband.c | 5 +++-- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/libnm-core/nm-connection.c b/libnm-core/nm-connection.c index ecfb9780be..ce0200ba54 100644 --- a/libnm-core/nm-connection.c +++ b/libnm-core/nm-connection.c @@ -1787,6 +1787,9 @@ _nm_connection_verify_required_interface_name (NMConnection *connection, { const char *interface_name; + if (!connection) + return TRUE; + interface_name = nm_connection_get_interface_name (connection); if (interface_name) return TRUE; diff --git a/libnm-core/nm-setting-bond.c b/libnm-core/nm-setting-bond.c index 9a8bdc3702..18b274ac19 100644 --- a/libnm-core/nm-setting-bond.c +++ b/libnm-core/nm-setting-bond.c @@ -645,7 +645,7 @@ verify (NMSetting *setting, NMConnection *connection, GError **error) } } - if (nm_connection_get_setting_infiniband (connection)) { + if (connection && nm_connection_get_setting_infiniband (connection)) { if (strcmp (mode_new, "active-backup") != 0) { g_set_error (error, NM_CONNECTION_ERROR, diff --git a/libnm-core/nm-setting-infiniband.c b/libnm-core/nm-setting-infiniband.c index 1bbe2b3fb5..6ab6ac11b5 100644 --- a/libnm-core/nm-setting-infiniband.c +++ b/libnm-core/nm-setting-infiniband.c @@ -181,7 +181,7 @@ nm_setting_infiniband_get_virtual_interface_name (NMSettingInfiniband *setting) static gboolean verify (NMSetting *setting, NMConnection *connection, GError **error) { - NMSettingConnection *s_con; + NMSettingConnection *s_con = NULL; NMSettingInfinibandPrivate *priv = NM_SETTING_INFINIBAND_GET_PRIVATE (setting); guint32 normerr_max_mtu = 0; @@ -241,7 +241,8 @@ verify (NMSetting *setting, NMConnection *connection, GError **error) } } - s_con = nm_connection_get_setting_connection (connection); + if (connection) + s_con = nm_connection_get_setting_connection (connection); if (s_con) { const char *interface_name = nm_setting_connection_get_interface_name (s_con); GError *tmp_error = NULL; From 43c43d5e3a01b3d33d386b7472c58f1a0cce2a46 Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Thu, 25 May 2017 18:38:10 +0200 Subject: [PATCH 02/21] bluetooth: streamline NMBluez5Manager teardown a bit --- src/devices/bluetooth/nm-bluez5-manager.c | 24 +++++++---------------- 1 file changed, 7 insertions(+), 17 deletions(-) diff --git a/src/devices/bluetooth/nm-bluez5-manager.c b/src/devices/bluetooth/nm-bluez5-manager.c index 88759301d5..27d4989b46 100644 --- a/src/devices/bluetooth/nm-bluez5-manager.c +++ b/src/devices/bluetooth/nm-bluez5-manager.c @@ -306,22 +306,6 @@ name_owner_changed_cb (GObject *object, } } -static void -bluez_cleanup (NMBluez5Manager *self, gboolean do_signal) -{ - NMBluez5ManagerPrivate *priv = NM_BLUEZ5_MANAGER_GET_PRIVATE (self); - - if (priv->proxy) { - g_signal_handlers_disconnect_by_func (priv->proxy, G_CALLBACK (name_owner_changed_cb), self); - g_clear_object (&priv->proxy); - } - - if (do_signal) - remove_all_devices (self); - else - g_hash_table_remove_all (priv->devices); -} - /*****************************************************************************/ static void @@ -351,8 +335,14 @@ static void dispose (GObject *object) { NMBluez5Manager *self = NM_BLUEZ5_MANAGER (object); + NMBluez5ManagerPrivate *priv = NM_BLUEZ5_MANAGER_GET_PRIVATE (self); - bluez_cleanup (self, FALSE); + 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); } From 1a20611f6616701e7d40aec1b9057ad372d9844a Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Wed, 31 May 2017 19:24:24 +0200 Subject: [PATCH 03/21] bluetooth/trivial: rename the defines --- src/devices/bluetooth/nm-bluez-common.h | 22 +++++++++---------- src/devices/bluetooth/nm-bluez-device.c | 26 +++++++++++------------ src/devices/bluetooth/nm-bluez-manager.c | 6 +++--- src/devices/bluetooth/nm-bluez4-adapter.c | 4 ++-- src/devices/bluetooth/nm-bluez4-manager.c | 6 +++--- src/devices/bluetooth/nm-bluez5-manager.c | 12 +++++------ 6 files changed, 38 insertions(+), 38 deletions(-) diff --git a/src/devices/bluetooth/nm-bluez-common.h b/src/devices/bluetooth/nm-bluez-common.h index 6e97c3f512..7abc0ddabc 100644 --- a/src/devices/bluetooth/nm-bluez-common.h +++ b/src/devices/bluetooth/nm-bluez-common.h @@ -24,20 +24,20 @@ #define BLUETOOTH_CONNECT_DUN "dun" #define BLUETOOTH_CONNECT_NAP "nap" -#define BLUEZ_SERVICE "org.bluez" +#define NM_BLUEZ_SERVICE "org.bluez" -#define BLUEZ_MANAGER_PATH "/" -#define OBJECT_MANAGER_INTERFACE "org.freedesktop.DBus.ObjectManager" +#define NM_BLUEZ_MANAGER_PATH "/" +#define NM_OBJECT_MANAGER_INTERFACE "org.freedesktop.DBus.ObjectManager" -#define BLUEZ5_ADAPTER_INTERFACE "org.bluez.Adapter1" -#define BLUEZ5_DEVICE_INTERFACE "org.bluez.Device1" -#define BLUEZ5_NETWORK_INTERFACE "org.bluez.Network1" +#define NM_BLUEZ5_ADAPTER_INTERFACE "org.bluez.Adapter1" +#define NM_BLUEZ5_DEVICE_INTERFACE "org.bluez.Device1" +#define NM_BLUEZ5_NETWORK_INTERFACE "org.bluez.Network1" -#define BLUEZ4_MANAGER_INTERFACE "org.bluez.Manager" -#define BLUEZ4_ADAPTER_INTERFACE "org.bluez.Adapter" -#define BLUEZ4_DEVICE_INTERFACE "org.bluez.Device" -#define BLUEZ4_SERIAL_INTERFACE "org.bluez.Serial" -#define BLUEZ4_NETWORK_INTERFACE "org.bluez.Network" +#define NM_BLUEZ4_MANAGER_INTERFACE "org.bluez.Manager" +#define NM_BLUEZ4_ADAPTER_INTERFACE "org.bluez.Adapter" +#define NM_BLUEZ4_DEVICE_INTERFACE "org.bluez.Device" +#define NM_BLUEZ4_SERIAL_INTERFACE "org.bluez.Serial" +#define NM_BLUEZ4_NETWORK_INTERFACE "org.bluez.Network" #define NM_BLUEZ_MANAGER_BDADDR_ADDED "bdaddr-added" diff --git a/src/devices/bluetooth/nm-bluez-device.c b/src/devices/bluetooth/nm-bluez-device.c index 41ef74cae7..e42f6533da 100644 --- a/src/devices/bluetooth/nm-bluez-device.c +++ b/src/devices/bluetooth/nm-bluez-device.c @@ -465,7 +465,7 @@ nm_bluez_device_disconnect (NMBluezDevice *self) if (!priv->b4_iface) goto out; args = g_variant_new ("(s)", priv->b4_iface), - dbus_iface = BLUEZ4_SERIAL_INTERFACE; + dbus_iface = NM_BLUEZ4_SERIAL_INTERFACE; } else if (priv->bluez_version == 5) { #if WITH_BLUEZ5_DUN nm_bluez5_dun_cleanup (priv->b5_dun_context); @@ -475,16 +475,16 @@ nm_bluez_device_disconnect (NMBluezDevice *self) } } else if (priv->connection_bt_type == NM_BT_CAPABILITY_NAP) { if (priv->bluez_version == 4) - dbus_iface = BLUEZ4_NETWORK_INTERFACE; + dbus_iface = NM_BLUEZ4_NETWORK_INTERFACE; else if (priv->bluez_version == 5) - dbus_iface = BLUEZ5_NETWORK_INTERFACE; + dbus_iface = NM_BLUEZ5_NETWORK_INTERFACE; else g_assert_not_reached (); } else g_assert_not_reached (); g_dbus_connection_call (priv->dbus_connection, - BLUEZ_SERVICE, + NM_BLUEZ_SERVICE, priv->path, dbus_iface, "Disconnect", @@ -577,13 +577,13 @@ nm_bluez_device_connect_async (NMBluezDevice *self, if (connection_bt_type == NM_BT_CAPABILITY_NAP) { connect_type = BLUETOOTH_CONNECT_NAP; if (priv->bluez_version == 4) - dbus_iface = BLUEZ4_NETWORK_INTERFACE; + dbus_iface = NM_BLUEZ4_NETWORK_INTERFACE; else if (priv->bluez_version == 5) - dbus_iface = BLUEZ5_NETWORK_INTERFACE; + dbus_iface = NM_BLUEZ5_NETWORK_INTERFACE; } else if (connection_bt_type == NM_BT_CAPABILITY_DUN) { connect_type = BLUETOOTH_CONNECT_DUN; if (priv->bluez_version == 4) - dbus_iface = BLUEZ4_SERIAL_INTERFACE; + dbus_iface = NM_BLUEZ4_SERIAL_INTERFACE; else if (priv->bluez_version == 5) { #if WITH_BLUEZ5_DUN if (priv->b5_dun_context == NULL) @@ -602,7 +602,7 @@ nm_bluez_device_connect_async (NMBluezDevice *self, g_assert_not_reached (); g_dbus_connection_call (priv->dbus_connection, - BLUEZ_SERVICE, + NM_BLUEZ_SERVICE, priv->path, dbus_iface, "Connect", @@ -972,9 +972,9 @@ query_properties (NMBluezDevice *self) g_dbus_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, NULL, - BLUEZ_SERVICE, + NM_BLUEZ_SERVICE, g_variant_get_string (v, NULL), - BLUEZ5_ADAPTER_INTERFACE, + NM_BLUEZ5_ADAPTER_INTERFACE, NULL, (GAsyncReadyCallback) adapter5_on_acquired, g_object_ref (self)); @@ -1134,17 +1134,17 @@ nm_bluez_device_new (const char *path, switch (priv->bluez_version) { case 4: - interface_name = BLUEZ4_DEVICE_INTERFACE; + interface_name = NM_BLUEZ4_DEVICE_INTERFACE; break; case 5: - interface_name = BLUEZ5_DEVICE_INTERFACE; + interface_name = NM_BLUEZ5_DEVICE_INTERFACE; break; } g_dbus_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, NULL, - BLUEZ_SERVICE, + NM_BLUEZ_SERVICE, priv->path, interface_name, NULL, diff --git a/src/devices/bluetooth/nm-bluez-manager.c b/src/devices/bluetooth/nm-bluez-manager.c index 2f0afa1684..e290173220 100644 --- a/src/devices/bluetooth/nm-bluez-manager.c +++ b/src/devices/bluetooth/nm-bluez-manager.c @@ -264,7 +264,7 @@ check_bluez_and_try_setup_final_step (NMBluezManager *self, int bluez_version, c cleanup_checking (self, FALSE); if (!priv->watch_name_id) { priv->watch_name_id = g_bus_watch_name (G_BUS_TYPE_SYSTEM, - BLUEZ_SERVICE, + NM_BLUEZ_SERVICE, G_BUS_NAME_WATCHER_FLAGS_NONE, watch_name_on_appeared, NULL, @@ -317,7 +317,7 @@ check_bluez_and_try_setup_do_introspect (GObject *source_object, /* might not be the best approach to detect the version, but it's good enough in practice. */ if (strstr (xml_data, "org.freedesktop.DBus.ObjectManager")) bluez_version = 5; - else if (strstr (xml_data, BLUEZ4_MANAGER_INTERFACE)) + else if (strstr (xml_data, NM_BLUEZ4_MANAGER_INTERFACE)) bluez_version = 4; else reason = "unexpected introspect result"; @@ -380,7 +380,7 @@ check_bluez_and_try_setup (NMBluezManager *self) g_dbus_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, NULL, - BLUEZ_SERVICE, + NM_BLUEZ_SERVICE, "/", DBUS_INTERFACE_INTROSPECTABLE, priv->async_cancellable, diff --git a/src/devices/bluetooth/nm-bluez4-adapter.c b/src/devices/bluetooth/nm-bluez4-adapter.c index cd9eaed34a..57aaf142f0 100644 --- a/src/devices/bluetooth/nm-bluez4-adapter.c +++ b/src/devices/bluetooth/nm-bluez4-adapter.c @@ -364,9 +364,9 @@ nm_bluez4_adapter_new (const char *path, NMSettings *settings) g_dbus_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, NULL, - BLUEZ_SERVICE, + NM_BLUEZ_SERVICE, priv->path, - BLUEZ4_ADAPTER_INTERFACE, + NM_BLUEZ4_ADAPTER_INTERFACE, priv->proxy_cancellable, _proxy_new_cb, self); diff --git a/src/devices/bluetooth/nm-bluez4-manager.c b/src/devices/bluetooth/nm-bluez4-manager.c index 66ef83104d..f86c9b7bb5 100644 --- a/src/devices/bluetooth/nm-bluez4-manager.c +++ b/src/devices/bluetooth/nm-bluez4-manager.c @@ -296,9 +296,9 @@ nm_bluez4_manager_init (NMBluez4Manager *self) g_dbus_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, NULL, - BLUEZ_SERVICE, - BLUEZ_MANAGER_PATH, - BLUEZ4_MANAGER_INTERFACE, + NM_BLUEZ_SERVICE, + NM_BLUEZ_MANAGER_PATH, + NM_BLUEZ4_MANAGER_INTERFACE, priv->proxy_cancellable, _proxy_new_cb, self); diff --git a/src/devices/bluetooth/nm-bluez5-manager.c b/src/devices/bluetooth/nm-bluez5-manager.c index 27d4989b46..47b8ed204e 100644 --- a/src/devices/bluetooth/nm-bluez5-manager.c +++ b/src/devices/bluetooth/nm-bluez5-manager.c @@ -186,7 +186,7 @@ object_manager_interfaces_added (GDBusProxy *proxy, GVariant *dict, NMBluez5Manager *self) { - if (g_variant_lookup (dict, BLUEZ5_DEVICE_INTERFACE, "a{sv}", NULL)) + if (g_variant_lookup (dict, NM_BLUEZ5_DEVICE_INTERFACE, "a{sv}", NULL)) device_added (proxy, path, self); } @@ -196,7 +196,7 @@ object_manager_interfaces_removed (GDBusProxy *proxy, const char **ifaces, NMBluez5Manager *self) { - if (ifaces && g_strv_contains (ifaces, BLUEZ5_DEVICE_INTERFACE)) + if (ifaces && g_strv_contains (ifaces, NM_BLUEZ5_DEVICE_INTERFACE)) device_removed (proxy, path, self); } @@ -225,7 +225,7 @@ get_managed_objects_cb (GDBusProxy *proxy, } g_variant_iter_init (&i, g_variant_get_child_value (variant, 0)); while ((g_variant_iter_next (&i, "{&o*}", &path, &ifaces))) { - if (g_variant_lookup_value (ifaces, BLUEZ5_DEVICE_INTERFACE, + if (g_variant_lookup_value (ifaces, NM_BLUEZ5_DEVICE_INTERFACE, G_VARIANT_TYPE_DICTIONARY)) { device_added (proxy, path, self); } @@ -281,9 +281,9 @@ bluez_connect (NMBluez5Manager *self) g_dbus_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, NULL, - BLUEZ_SERVICE, - BLUEZ_MANAGER_PATH, - OBJECT_MANAGER_INTERFACE, + NM_BLUEZ_SERVICE, + NM_BLUEZ_MANAGER_PATH, + NM_OBJECT_MANAGER_INTERFACE, NULL, (GAsyncReadyCallback) on_proxy_acquired, self); From 28505ae92bc763dc9f05253ed615071695df071f Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Tue, 23 May 2017 20:45:39 +0200 Subject: [PATCH 04/21] build: don't drop the test suite log on failure Fixes: 2198f73b0ec810b6b9084c0e00dcf07d4a6ee8e3 --- Makefile.am | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile.am b/Makefile.am index c6583c6817..35ac2a368d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -4509,5 +4509,6 @@ cscope: ############################################################################### +.PRECIOUS: test-suite.log .DELETE_ON_ERROR: .PHONY: cscope dist-configure-check $(check_local) $(dist_hook) From 1bb751b9d13522ea1de2f6b85ce6ae1de6ec3e07 Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Wed, 31 May 2017 20:04:13 +0200 Subject: [PATCH 05/21] bluez5: use _NMLOG --- src/devices/bluetooth/nm-bluez5-manager.c | 33 +++++++++++++---------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/src/devices/bluetooth/nm-bluez5-manager.c b/src/devices/bluetooth/nm-bluez5-manager.c index 47b8ed204e..7052956090 100644 --- a/src/devices/bluetooth/nm-bluez5-manager.c +++ b/src/devices/bluetooth/nm-bluez5-manager.c @@ -66,6 +66,11 @@ G_DEFINE_TYPE (NMBluez5Manager, nm_bluez5_manager, G_TYPE_OBJECT) /*****************************************************************************/ +#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); @@ -125,14 +130,14 @@ device_usable (NMBluezDevice *device, GParamSpec *pspec, NMBluez5Manager *self) { gboolean usable = nm_bluez_device_get_usable (device); - nm_log_dbg (LOGD_BT, "(%s): bluez device now %s", - nm_bluez_device_get_path (device), - usable ? "usable" : "unusable"); + _LOGD ("(%s): bluez device now %s", + nm_bluez_device_get_path (device), + usable ? "usable" : "unusable"); if (usable) { - nm_log_dbg (LOGD_BT, "(%s): bluez device address %s", - nm_bluez_device_get_path (device), - nm_bluez_device_get_address (device)); + _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); @@ -143,9 +148,9 @@ device_initialized (NMBluezDevice *device, gboolean success, NMBluez5Manager *se { NMBluez5ManagerPrivate *priv = NM_BLUEZ5_MANAGER_GET_PRIVATE (self); - nm_log_dbg (LOGD_BT, "(%s): bluez device %s", - nm_bluez_device_get_path (device), - success ? "initialized" : "failed to initialize"); + _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)); } @@ -161,7 +166,7 @@ device_added (GDBusProxy *proxy, const gchar *path, NMBluez5Manager *self) g_signal_connect (device, "notify::usable", G_CALLBACK (device_usable), self); g_hash_table_insert (priv->devices, (gpointer) nm_bluez_device_get_path (device), device); - nm_log_dbg (LOGD_BT, "(%s): new bluez device found", path); + _LOGD ("(%s): new bluez device found", path); } static void @@ -170,7 +175,7 @@ device_removed (GDBusProxy *proxy, const gchar *path, NMBluez5Manager *self) NMBluez5ManagerPrivate *priv = NM_BLUEZ5_MANAGER_GET_PRIVATE (self); NMBluezDevice *device; - nm_log_dbg (LOGD_BT, "(%s): bluez device removed", path); + _LOGD ("(%s): bluez device removed", path); device = g_hash_table_lookup (priv->devices, path); if (device) { @@ -215,10 +220,10 @@ get_managed_objects_cb (GDBusProxy *proxy, &error); if (!variant) { if (g_error_matches (error, G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_METHOD)) - nm_log_warn (LOGD_BT, "Couldn't get managed objects: not running Bluez5?"); + _LOGW ("Couldn't get managed objects: not running Bluez5?"); else { g_dbus_error_strip_remote_error (error); - nm_log_warn (LOGD_BT, "Couldn't get managed objects: %s", error->message); + _LOGW ("Couldn't get managed objects: %s", error->message); } g_clear_error (&error); return; @@ -248,7 +253,7 @@ on_proxy_acquired (GObject *object, priv->proxy = g_dbus_proxy_new_for_bus_finish (res, &error); if (!priv->proxy) { - nm_log_warn (LOGD_BT, "Couldn't acquire object manager proxy: %s", error->message); + _LOGW ("Couldn't acquire object manager proxy: %s", error->message); g_clear_error (&error); return; } From 15daf29220ed4d9a5fddf6fe87fc9b790f996211 Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Tue, 23 May 2017 13:19:22 +0200 Subject: [PATCH 06/21] bluez5: avoid leaking the interface dictionary --- src/devices/bluetooth/nm-bluez5-manager.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/devices/bluetooth/nm-bluez5-manager.c b/src/devices/bluetooth/nm-bluez5-manager.c index 7052956090..1d3abb2905 100644 --- a/src/devices/bluetooth/nm-bluez5-manager.c +++ b/src/devices/bluetooth/nm-bluez5-manager.c @@ -230,10 +230,7 @@ get_managed_objects_cb (GDBusProxy *proxy, } g_variant_iter_init (&i, g_variant_get_child_value (variant, 0)); while ((g_variant_iter_next (&i, "{&o*}", &path, &ifaces))) { - if (g_variant_lookup_value (ifaces, NM_BLUEZ5_DEVICE_INTERFACE, - G_VARIANT_TYPE_DICTIONARY)) { - device_added (proxy, path, self); - } + object_manager_interfaces_added (proxy, path, ifaces, self); g_variant_unref (ifaces); } From 02e527f644799cfbc155b6773e16df9df9da6efd Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Mon, 22 May 2017 20:11:40 +0200 Subject: [PATCH 07/21] core/connections: pick base setting from settings the connection actually has We will need multiple base settings for Bluetooth NAP servers: bluetooth and bridge. We want to identify the device as "bluetooth" to the user, but leave the Bridge factory handle it. The "connection.type" is somewhat redundant -- let's keep it for what the user sees. And identify the actual base setting to pick the right factory by the actually present setting. --- libnm-core/nm-connection.c | 37 ++++++++++++++------------------- libnm-core/tests/test-general.c | 2 +- 2 files changed, 17 insertions(+), 22 deletions(-) diff --git a/libnm-core/nm-connection.c b/libnm-core/nm-connection.c index ce0200ba54..f000d0c4d9 100644 --- a/libnm-core/nm-connection.c +++ b/libnm-core/nm-connection.c @@ -592,10 +592,12 @@ _nm_connection_find_base_type_setting (NMConnection *connection) continue; if (setting) { - /* FIXME: currently, if there is more than one matching base type, - * we cannot detect the base setting. - * See: https://bugzilla.gnome.org/show_bug.cgi?id=696936#c8 */ - return NULL; + NMSettingConnection *s_con = nm_connection_get_setting_connection (connection); + + if (!s_con) + return NULL; + return nm_connection_get_setting_by_name (connection, + nm_setting_connection_get_connection_type (s_con)); } setting = s_iter; } @@ -1609,19 +1611,16 @@ nm_connection_to_dbus (NMConnection *connection, gboolean nm_connection_is_type (NMConnection *connection, const char *type) { - NMSettingConnection *s_con; - const char *type2; + NMSetting *setting; g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE); g_return_val_if_fail (type != NULL, FALSE); - s_con = nm_connection_get_setting_connection (connection); - if (!s_con) + setting = nm_connection_get_setting_by_name (connection, type); + if (!setting) return FALSE; - type2 = nm_setting_connection_get_connection_type (s_con); - - return (g_strcmp0 (type2, type) == 0); + return _nm_setting_is_base_type (setting); } static int @@ -1850,22 +1849,19 @@ nm_connection_get_id (NMConnection *connection) * nm_connection_get_connection_type: * @connection: the #NMConnection * - * A shortcut to return the type from the connection's #NMSettingConnection. - * - * Returns: the type from the connection's 'connection' setting + * Returns: the connection's base type. **/ const char * nm_connection_get_connection_type (NMConnection *connection) { - NMSettingConnection *s_con; + NMSetting *setting; g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); - s_con = nm_connection_get_setting_connection (connection); - if (!s_con) + setting = _nm_connection_find_base_type_setting (connection); + if (!setting) return NULL; - - return nm_setting_connection_get_connection_type (s_con); + return nm_setting_get_name (setting); } /** @@ -1880,9 +1876,8 @@ nm_connection_get_connection_type (NMConnection *connection) gboolean nm_connection_is_virtual (NMConnection *connection) { - const char *type; + const char *type = nm_connection_get_connection_type (connection); - type = nm_connection_get_connection_type (connection); g_return_val_if_fail (type != NULL, FALSE); if ( !strcmp (type, NM_SETTING_BOND_SETTING_NAME) diff --git a/libnm-core/tests/test-general.c b/libnm-core/tests/test-general.c index f80f013dc9..435088eb91 100644 --- a/libnm-core/tests/test-general.c +++ b/libnm-core/tests/test-general.c @@ -3558,7 +3558,7 @@ _test_connection_normalize_type_normalizable_type (const char *type, nm_connection_add_setting (con, s_base); } - g_assert (!nm_connection_get_connection_type (con)); + g_assert (!nm_setting_connection_get_connection_type (s_con)); g_assert (nm_connection_get_setting_by_name (con, type) == s_base); nmtst_assert_connection_verifies_after_normalization (con, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_MISSING_PROPERTY); From 7b5712acd25577ed61da5d10c26f724116f03cee Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Mon, 22 May 2017 20:18:17 +0200 Subject: [PATCH 08/21] core: allow two priorities of base settings We'll need two "base" settings for Bluetooth NAP connections: bridge to set up the actual link and bluetooth to identify the HCI to register the network server with. Let's use two priorities for base setting, with "1" marking one of higher priority and "2" of lower priority when both are present. --- libnm-core/nm-setting-8021x.c | 2 +- libnm-core/nm-setting-bluetooth.c | 2 +- libnm-core/nm-setting-bridge-port.c | 2 +- libnm-core/nm-setting-dcb.c | 2 +- libnm-core/nm-setting-ip4-config.c | 2 +- libnm-core/nm-setting-ip6-config.c | 2 +- libnm-core/nm-setting-ppp.c | 2 +- libnm-core/nm-setting-pppoe.c | 2 +- libnm-core/nm-setting-proxy.c | 2 +- libnm-core/nm-setting-serial.c | 2 +- libnm-core/nm-setting-team-port.c | 2 +- libnm-core/nm-setting-wireless-security.c | 2 +- libnm-core/nm-setting.c | 13 ++++++++----- 13 files changed, 20 insertions(+), 17 deletions(-) diff --git a/libnm-core/nm-setting-8021x.c b/libnm-core/nm-setting-8021x.c index 1995a5ba3e..c791cf1fa3 100644 --- a/libnm-core/nm-setting-8021x.c +++ b/libnm-core/nm-setting-8021x.c @@ -61,7 +61,7 @@ **/ G_DEFINE_TYPE_WITH_CODE (NMSetting8021x, nm_setting_802_1x, NM_TYPE_SETTING, - _nm_register_setting (802_1X, 2)) + _nm_register_setting (802_1X, 3)) NM_SETTING_REGISTER_TYPE (NM_TYPE_SETTING_802_1X) #define NM_SETTING_802_1X_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_802_1X, NMSetting8021xPrivate)) diff --git a/libnm-core/nm-setting-bluetooth.c b/libnm-core/nm-setting-bluetooth.c index 837b06c04d..669c1be3b9 100644 --- a/libnm-core/nm-setting-bluetooth.c +++ b/libnm-core/nm-setting-bluetooth.c @@ -43,7 +43,7 @@ **/ G_DEFINE_TYPE_WITH_CODE (NMSettingBluetooth, nm_setting_bluetooth, NM_TYPE_SETTING, - _nm_register_setting (BLUETOOTH, 1)) + _nm_register_setting (BLUETOOTH, 2)) NM_SETTING_REGISTER_TYPE (NM_TYPE_SETTING_BLUETOOTH) #define NM_SETTING_BLUETOOTH_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_BLUETOOTH, NMSettingBluetoothPrivate)) diff --git a/libnm-core/nm-setting-bridge-port.c b/libnm-core/nm-setting-bridge-port.c index 0116a8364c..ba297b70d4 100644 --- a/libnm-core/nm-setting-bridge-port.c +++ b/libnm-core/nm-setting-bridge-port.c @@ -41,7 +41,7 @@ **/ G_DEFINE_TYPE_WITH_CODE (NMSettingBridgePort, nm_setting_bridge_port, NM_TYPE_SETTING, - _nm_register_setting (BRIDGE_PORT, 3)) + _nm_register_setting (BRIDGE_PORT, 4)) NM_SETTING_REGISTER_TYPE (NM_TYPE_SETTING_BRIDGE_PORT) #define NM_SETTING_BRIDGE_PORT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_BRIDGE_PORT, NMSettingBridgePortPrivate)) diff --git a/libnm-core/nm-setting-dcb.c b/libnm-core/nm-setting-dcb.c index 140dc02102..93f82199a2 100644 --- a/libnm-core/nm-setting-dcb.c +++ b/libnm-core/nm-setting-dcb.c @@ -41,7 +41,7 @@ **/ G_DEFINE_TYPE_WITH_CODE (NMSettingDcb, nm_setting_dcb, NM_TYPE_SETTING, - _nm_register_setting (DCB, 2)) + _nm_register_setting (DCB, 3)) NM_SETTING_REGISTER_TYPE (NM_TYPE_SETTING_DCB) #define NM_SETTING_DCB_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_DCB, NMSettingDcbPrivate)) diff --git a/libnm-core/nm-setting-ip4-config.c b/libnm-core/nm-setting-ip4-config.c index 3a3661613f..3c54dfa96f 100644 --- a/libnm-core/nm-setting-ip4-config.c +++ b/libnm-core/nm-setting-ip4-config.c @@ -51,7 +51,7 @@ **/ G_DEFINE_TYPE_WITH_CODE (NMSettingIP4Config, nm_setting_ip4_config, NM_TYPE_SETTING_IP_CONFIG, - _nm_register_setting (IP4_CONFIG, 4)) + _nm_register_setting (IP4_CONFIG, 5)) NM_SETTING_REGISTER_TYPE (NM_TYPE_SETTING_IP4_CONFIG) #define NM_SETTING_IP4_CONFIG_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_IP4_CONFIG, NMSettingIP4ConfigPrivate)) diff --git a/libnm-core/nm-setting-ip6-config.c b/libnm-core/nm-setting-ip6-config.c index fbeffe7e0b..93301d20cd 100644 --- a/libnm-core/nm-setting-ip6-config.c +++ b/libnm-core/nm-setting-ip6-config.c @@ -52,7 +52,7 @@ **/ G_DEFINE_TYPE_WITH_CODE (NMSettingIP6Config, nm_setting_ip6_config, NM_TYPE_SETTING_IP_CONFIG, - _nm_register_setting (IP6_CONFIG, 4)) + _nm_register_setting (IP6_CONFIG, 5)) NM_SETTING_REGISTER_TYPE (NM_TYPE_SETTING_IP6_CONFIG) #define NM_SETTING_IP6_CONFIG_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_IP6_CONFIG, NMSettingIP6ConfigPrivate)) diff --git a/libnm-core/nm-setting-ppp.c b/libnm-core/nm-setting-ppp.c index 1db41e44d4..05b5233031 100644 --- a/libnm-core/nm-setting-ppp.c +++ b/libnm-core/nm-setting-ppp.c @@ -36,7 +36,7 @@ **/ G_DEFINE_TYPE_WITH_CODE (NMSettingPpp, nm_setting_ppp, NM_TYPE_SETTING, - _nm_register_setting (PPP, 3)) + _nm_register_setting (PPP, 4)) NM_SETTING_REGISTER_TYPE (NM_TYPE_SETTING_PPP) #define NM_SETTING_PPP_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_PPP, NMSettingPppPrivate)) diff --git a/libnm-core/nm-setting-pppoe.c b/libnm-core/nm-setting-pppoe.c index c7fbd56d21..5dcc708ec1 100644 --- a/libnm-core/nm-setting-pppoe.c +++ b/libnm-core/nm-setting-pppoe.c @@ -39,7 +39,7 @@ **/ G_DEFINE_TYPE_WITH_CODE (NMSettingPppoe, nm_setting_pppoe, NM_TYPE_SETTING, - _nm_register_setting (PPPOE, 3)) + _nm_register_setting (PPPOE, 4)) NM_SETTING_REGISTER_TYPE (NM_TYPE_SETTING_PPPOE) #define NM_SETTING_PPPOE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_PPPOE, NMSettingPppoePrivate)) diff --git a/libnm-core/nm-setting-proxy.c b/libnm-core/nm-setting-proxy.c index 1492892cc4..ad417f7721 100644 --- a/libnm-core/nm-setting-proxy.c +++ b/libnm-core/nm-setting-proxy.c @@ -40,7 +40,7 @@ **/ G_DEFINE_TYPE_WITH_CODE (NMSettingProxy, nm_setting_proxy, NM_TYPE_SETTING, - _nm_register_setting (PROXY, 4)) + _nm_register_setting (PROXY, 5)) NM_SETTING_REGISTER_TYPE (NM_TYPE_SETTING_PROXY) #define NM_SETTING_PROXY_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_PROXY, NMSettingProxyPrivate)) diff --git a/libnm-core/nm-setting-serial.c b/libnm-core/nm-setting-serial.c index fd251b7d24..bb592c080a 100644 --- a/libnm-core/nm-setting-serial.c +++ b/libnm-core/nm-setting-serial.c @@ -38,7 +38,7 @@ **/ G_DEFINE_TYPE_WITH_CODE (NMSettingSerial, nm_setting_serial, NM_TYPE_SETTING, - _nm_register_setting (SERIAL, 2)) + _nm_register_setting (SERIAL, 3)) NM_SETTING_REGISTER_TYPE (NM_TYPE_SETTING_SERIAL) #define NM_SETTING_SERIAL_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_SERIAL, NMSettingSerialPrivate)) diff --git a/libnm-core/nm-setting-team-port.c b/libnm-core/nm-setting-team-port.c index f64aa5f947..8dd3da097c 100644 --- a/libnm-core/nm-setting-team-port.c +++ b/libnm-core/nm-setting-team-port.c @@ -40,7 +40,7 @@ **/ G_DEFINE_TYPE_WITH_CODE (NMSettingTeamPort, nm_setting_team_port, NM_TYPE_SETTING, - _nm_register_setting (TEAM_PORT, 3)) + _nm_register_setting (TEAM_PORT, 4)) NM_SETTING_REGISTER_TYPE (NM_TYPE_SETTING_TEAM_PORT) #define NM_SETTING_TEAM_PORT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_TEAM_PORT, NMSettingTeamPortPrivate)) diff --git a/libnm-core/nm-setting-wireless-security.c b/libnm-core/nm-setting-wireless-security.c index 48a04fc5a8..ef840322b2 100644 --- a/libnm-core/nm-setting-wireless-security.c +++ b/libnm-core/nm-setting-wireless-security.c @@ -54,7 +54,7 @@ **/ G_DEFINE_TYPE_WITH_CODE (NMSettingWirelessSecurity, nm_setting_wireless_security, NM_TYPE_SETTING, - _nm_register_setting (WIRELESS_SECURITY, 2)) + _nm_register_setting (WIRELESS_SECURITY, 3)) NM_SETTING_REGISTER_TYPE (NM_TYPE_SETTING_WIRELESS_SECURITY) #define NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_WIRELESS_SECURITY, NMSettingWirelessSecurityPrivate)) diff --git a/libnm-core/nm-setting.c b/libnm-core/nm-setting.c index e4be8706dd..258cedc0eb 100644 --- a/libnm-core/nm-setting.c +++ b/libnm-core/nm-setting.c @@ -135,18 +135,18 @@ _ensure_registered_constructor (void) * * 0: reserved for the Connection setting * - * 1: hardware-related settings like Ethernet, Wi-Fi, InfiniBand, Bridge, etc. + * 1,2: hardware-related settings like Ethernet, Wi-Fi, InfiniBand, Bridge, etc. * These priority 1 settings are also "base types", which means that at least * one of them is required for the connection to be valid, and their name is * valid in the 'type' property of the Connection setting. * - * 2: hardware-related auxiliary settings that require a base setting to be + * 3: hardware-related auxiliary settings that require a base setting to be * successful first, like Wi-Fi security, 802.1x, etc. * - * 3: hardware-independent settings that are required before IP connectivity + * 4: hardware-independent settings that are required before IP connectivity * can be established, like PPP, PPPoE, etc. * - * 4: IP-level stuff + * 5: IP-level stuff * * 10: NMSettingUser */ @@ -214,12 +214,15 @@ _nm_setting_get_setting_priority (NMSetting *setting) gboolean _nm_setting_type_is_base_type (GType type) { + guint32 priority; + /* Historical oddity: PPPoE is a base-type even though it's not * priority 1. It needs to be sorted *after* lower-level stuff like * Wi-Fi security or 802.1x for secrets, but it's still allowed as a * base type. */ - return _get_setting_type_priority (type) == 1 || (type == NM_TYPE_SETTING_PPPOE); + priority = _get_setting_type_priority (type); + return (priority == 1 || priority == 2 || (type == NM_TYPE_SETTING_PPPOE)); } gboolean From 2c1a178f5bd815146a3079c3a188fae3b0491377 Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Mon, 22 May 2017 20:31:00 +0200 Subject: [PATCH 09/21] core: negotiate the best base setting When the two base settings are present, use one of higher priority. This will pick the "bridge" setting when both "bridge" and "bluetooth" are present for a Bluetooth NAP connection. --- libnm-core/nm-connection.c | 21 ++++++++++++++------- libnm-core/nm-setting-connection.c | 2 +- libnm-core/nm-setting-private.h | 4 ++-- libnm-core/nm-setting.c | 15 +++++++++------ libnm-core/nm-utils.c | 4 ++-- libnm-core/tests/test-general.c | 6 +++--- 6 files changed, 31 insertions(+), 21 deletions(-) diff --git a/libnm-core/nm-connection.c b/libnm-core/nm-connection.c index f000d0c4d9..858f5aab88 100644 --- a/libnm-core/nm-connection.c +++ b/libnm-core/nm-connection.c @@ -585,21 +585,28 @@ _nm_connection_find_base_type_setting (NMConnection *connection) NMConnectionPrivate *priv = NM_CONNECTION_GET_PRIVATE (connection); GHashTableIter iter; NMSetting *setting = NULL, *s_iter; + guint32 setting_prio, s_iter_prio; g_hash_table_iter_init (&iter, priv->settings); while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &s_iter)) { - if (!_nm_setting_is_base_type (s_iter)) + s_iter_prio = _nm_setting_get_base_type_priority (s_iter); + if (!s_iter_prio) continue; if (setting) { - NMSettingConnection *s_con = nm_connection_get_setting_connection (connection); + if (s_iter_prio > setting_prio) { + continue; + } else if (s_iter_prio == setting_prio) { + NMSettingConnection *s_con = nm_connection_get_setting_connection (connection); - if (!s_con) - return NULL; - return nm_connection_get_setting_by_name (connection, - nm_setting_connection_get_connection_type (s_con)); + if (!s_con) + return NULL; + return nm_connection_get_setting_by_name (connection, + nm_setting_connection_get_connection_type (s_con)); + } } setting = s_iter; + setting_prio = s_iter_prio; } return setting; } @@ -1620,7 +1627,7 @@ nm_connection_is_type (NMConnection *connection, const char *type) if (!setting) return FALSE; - return _nm_setting_is_base_type (setting); + return !!_nm_setting_get_base_type_priority (setting); } static int diff --git a/libnm-core/nm-setting-connection.c b/libnm-core/nm-setting-connection.c index 2d2247fe4c..257d6621af 100644 --- a/libnm-core/nm-setting-connection.c +++ b/libnm-core/nm-setting-connection.c @@ -926,7 +926,7 @@ verify (NMSetting *setting, NMConnection *connection, GError **error) } base_type = nm_setting_lookup_type (priv->type); - if (base_type == G_TYPE_INVALID || !_nm_setting_type_is_base_type (base_type)) { + if (base_type == G_TYPE_INVALID || !_nm_setting_type_get_base_type_priority (base_type)) { g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY, diff --git a/libnm-core/nm-setting-private.h b/libnm-core/nm-setting-private.h index 79b6ac8712..3d6e2d4d86 100644 --- a/libnm-core/nm-setting-private.h +++ b/libnm-core/nm-setting-private.h @@ -36,8 +36,8 @@ void _nm_register_setting (const char *name, _nm_register_setting (NM_SETTING_ ## name ## _SETTING_NAME "", g_define_type_id, priority); \ } G_STMT_END -gboolean _nm_setting_is_base_type (NMSetting *setting); -gboolean _nm_setting_type_is_base_type (GType type); +guint32 _nm_setting_get_base_type_priority (NMSetting *setting); +guint32 _nm_setting_type_get_base_type_priority (GType type); gint _nm_setting_compare_priority (gconstpointer a, gconstpointer b); typedef enum NMSettingUpdateSecretResult { diff --git a/libnm-core/nm-setting.c b/libnm-core/nm-setting.c index 258cedc0eb..530dd0147a 100644 --- a/libnm-core/nm-setting.c +++ b/libnm-core/nm-setting.c @@ -211,8 +211,8 @@ _nm_setting_get_setting_priority (NMSetting *setting) return priv->info->priority; } -gboolean -_nm_setting_type_is_base_type (GType type) +guint32 +_nm_setting_type_get_base_type_priority (GType type) { guint32 priority; @@ -222,13 +222,16 @@ _nm_setting_type_is_base_type (GType type) * base type. */ priority = _get_setting_type_priority (type); - return (priority == 1 || priority == 2 || (type == NM_TYPE_SETTING_PPPOE)); + if (priority == 1 || priority == 2 || (type == NM_TYPE_SETTING_PPPOE)) + return priority; + else + return 0; } -gboolean -_nm_setting_is_base_type (NMSetting *setting) +guint32 +_nm_setting_get_base_type_priority (NMSetting *setting) { - return _nm_setting_type_is_base_type (G_OBJECT_TYPE (setting)); + return _nm_setting_type_get_base_type_priority (G_OBJECT_TYPE (setting)); } /** diff --git a/libnm-core/nm-utils.c b/libnm-core/nm-utils.c index 441a2dfd4e..dedad241ad 100644 --- a/libnm-core/nm-utils.c +++ b/libnm-core/nm-utils.c @@ -3896,8 +3896,8 @@ _nm_utils_inet6_is_token (const struct in6_addr *in6addr) gboolean nm_utils_check_virtual_device_compatibility (GType virtual_type, GType other_type) { - g_return_val_if_fail (_nm_setting_type_is_base_type (virtual_type), FALSE); - g_return_val_if_fail (_nm_setting_type_is_base_type (other_type), FALSE); + g_return_val_if_fail (_nm_setting_type_get_base_type_priority (virtual_type), FALSE); + g_return_val_if_fail (_nm_setting_type_get_base_type_priority (other_type), FALSE); if (virtual_type == NM_TYPE_SETTING_BOND) { return ( other_type == NM_TYPE_SETTING_INFINIBAND diff --git a/libnm-core/tests/test-general.c b/libnm-core/tests/test-general.c index 435088eb91..cc8c6bd7f7 100644 --- a/libnm-core/tests/test-general.c +++ b/libnm-core/tests/test-general.c @@ -3492,7 +3492,7 @@ _test_connection_normalize_type_normalizable_setting (const char *type, base_type = nm_setting_lookup_type (type); g_assert (base_type != G_TYPE_INVALID); - g_assert (_nm_setting_type_is_base_type (base_type)); + g_assert (_nm_setting_type_get_base_type_priority (base_type)); con = nmtst_create_minimal_connection (id, NULL, NULL, &s_con); @@ -3522,7 +3522,7 @@ _test_connection_normalize_type_unnormalizable_setting (const char *type) base_type = nm_setting_lookup_type (type); g_assert (base_type != G_TYPE_INVALID); - g_assert (_nm_setting_type_is_base_type (base_type)); + g_assert (_nm_setting_type_get_base_type_priority (base_type)); con = nmtst_create_minimal_connection (id, NULL, NULL, &s_con); @@ -3545,7 +3545,7 @@ _test_connection_normalize_type_normalizable_type (const char *type, base_type = nm_setting_lookup_type (type); g_assert (base_type != G_TYPE_INVALID); - g_assert (_nm_setting_type_is_base_type (base_type)); + g_assert (_nm_setting_type_get_base_type_priority (base_type)); con = nmtst_create_minimal_connection (id, NULL, NULL, &s_con); From 7c5a2be96618787bfa94ad1179c101796b4f986d Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Mon, 22 May 2017 18:47:42 +0200 Subject: [PATCH 10/21] core/bluetooth: add NAP type --- libnm-core/nm-setting-bluetooth.c | 5 +++-- libnm-core/nm-setting-bluetooth.h | 12 ++++++++++-- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/libnm-core/nm-setting-bluetooth.c b/libnm-core/nm-setting-bluetooth.c index 669c1be3b9..d25d4db269 100644 --- a/libnm-core/nm-setting-bluetooth.c +++ b/libnm-core/nm-setting-bluetooth.c @@ -80,8 +80,8 @@ NMSetting *nm_setting_bluetooth_new (void) * Returns the connection method for communicating with the remote device (i.e. * either DUN to a DUN-capable device or PANU to a NAP-capable device). * - * Returns: the type, either %NM_SETTING_BLUETOOTH_TYPE_PANU or - * %NM_SETTING_BLUETOOTH_TYPE_DUN + * Returns: the type, either %NM_SETTING_BLUETOOTH_TYPE_PANU, + * %NM_SETTING_BLUETOOTH_TYPE_NAP or %NM_SETTING_BLUETOOTH_TYPE_DUN **/ const char * nm_setting_bluetooth_get_connection_type (NMSettingBluetooth *setting) @@ -139,6 +139,7 @@ verify (NMSetting *setting, NMConnection *connection, GError **error) g_prefix_error (error, "%s.%s: ", NM_SETTING_BLUETOOTH_SETTING_NAME, NM_SETTING_BLUETOOTH_TYPE); return FALSE; } else if (!g_str_equal (priv->type, NM_SETTING_BLUETOOTH_TYPE_DUN) && + !g_str_equal (priv->type, NM_SETTING_BLUETOOTH_TYPE_NAP) && !g_str_equal (priv->type, NM_SETTING_BLUETOOTH_TYPE_PANU)) { g_set_error (error, NM_CONNECTION_ERROR, diff --git a/libnm-core/nm-setting-bluetooth.h b/libnm-core/nm-setting-bluetooth.h index 312aab1440..58326702ce 100644 --- a/libnm-core/nm-setting-bluetooth.h +++ b/libnm-core/nm-setting-bluetooth.h @@ -54,11 +54,19 @@ G_BEGIN_DECLS /** * NM_SETTING_BLUETOOTH_TYPE_PANU: * - * Connection type describing a connection to devices that support the Bluetooth - * NAP (Network Access Point) protocol, which accepts connections via PANU. + * Connection type describing PANU connection to a Bluetooth NAP (Network + * Access Point). */ #define NM_SETTING_BLUETOOTH_TYPE_PANU "panu" +/** + * NM_SETTING_BLUETOOTH_TYPE_NAP: + * + * Connection type describing a Bluetooth NAP (Network Access Point), + * which accepts PANU clients. + */ +#define NM_SETTING_BLUETOOTH_TYPE_NAP "nap" + /** * NMSettingBluetooth: * From 63292b5c4112e247d6e016c481c4cb5c2c444a3b Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Mon, 22 May 2017 19:31:43 +0200 Subject: [PATCH 11/21] core/connection: normalize bridge settings into bluetooth NAP connections For the Bluetooth NAP we need a Bridge link for the BlueZ to assign the BNEP links for PANU client connections into. Let's disable STP by default -- it adds extra delay for the Bridge when the BNEP link is assigned and is likely not useful for a typical client. --- libnm-core/nm-connection.c | 16 +++++++++++-- libnm-core/nm-setting-bluetooth.c | 37 ++++++++++++++++++++++--------- 2 files changed, 41 insertions(+), 12 deletions(-) diff --git a/libnm-core/nm-connection.c b/libnm-core/nm-connection.c index 858f5aab88..2be9007682 100644 --- a/libnm-core/nm-connection.c +++ b/libnm-core/nm-connection.c @@ -1002,13 +1002,25 @@ _normalize_team_port_config (NMConnection *self, GHashTable *parameters) static gboolean _normalize_required_settings (NMConnection *self, GHashTable *parameters) { + NMSettingBluetooth *s_bt = nm_connection_get_setting_bluetooth (self); + NMSetting *s_bridge; + gboolean changed = FALSE; + if (nm_connection_get_setting_vlan (self)) { if (!nm_connection_get_setting_wired (self)) { nm_connection_add_setting (self, nm_setting_wired_new ()); - return TRUE; + changed = TRUE; } } - return FALSE; + if (s_bt && nm_streq0 (nm_setting_bluetooth_get_connection_type (s_bt), NM_SETTING_BLUETOOTH_TYPE_NAP)) { + if (!nm_connection_get_setting_bridge (self)) { + s_bridge = nm_setting_bridge_new (); + g_object_set (s_bridge, NM_SETTING_BRIDGE_STP, FALSE, NULL); + nm_connection_add_setting (self, s_bridge); + changed = TRUE; + } + } + return changed; } static gboolean diff --git a/libnm-core/nm-setting-bluetooth.c b/libnm-core/nm-setting-bluetooth.c index d25d4db269..26f41d62ce 100644 --- a/libnm-core/nm-setting-bluetooth.c +++ b/libnm-core/nm-setting-bluetooth.c @@ -25,6 +25,7 @@ #include #include +#include "nm-connection-private.h" #include "nm-setting-bluetooth.h" #include "nm-setting-cdma.h" #include "nm-setting-gsm.h" @@ -113,16 +114,7 @@ verify (NMSetting *setting, NMConnection *connection, GError **error) { NMSettingBluetoothPrivate *priv = NM_SETTING_BLUETOOTH_GET_PRIVATE (setting); - if (!priv->bdaddr) { - g_set_error_literal (error, - NM_CONNECTION_ERROR, - NM_CONNECTION_ERROR_MISSING_PROPERTY, - _("property is missing")); - g_prefix_error (error, "%s.%s: ", NM_SETTING_BLUETOOTH_SETTING_NAME, NM_SETTING_BLUETOOTH_BDADDR); - return FALSE; - } - - if (!nm_utils_hwaddr_valid (priv->bdaddr, ETH_ALEN)) { + if (priv->bdaddr && !nm_utils_hwaddr_valid (priv->bdaddr, ETH_ALEN)) { g_set_error_literal (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY, @@ -177,6 +169,31 @@ verify (NMSetting *setting, NMConnection *connection, GError **error) * is required at the interface level. */ + /* NAP mode needs a bridge setting, and a bridge needs a name. */ + if (!strcmp (priv->type, NM_SETTING_BLUETOOTH_TYPE_NAP)) { + if (!_nm_connection_verify_required_interface_name (connection, error)) + return FALSE; + if (connection && !nm_connection_get_setting_bridge (connection)) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_SETTING, + _("'%s' connection requires '%s' setting"), + NM_SETTING_BLUETOOTH_TYPE_NAP, + NM_SETTING_BRIDGE_SETTING_NAME); + g_prefix_error (error, "%s: ", NM_SETTING_BLUETOOTH_SETTING_NAME); + return NM_SETTING_VERIFY_NORMALIZABLE_ERROR; + } + } else { + if (!priv->bdaddr) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_PROPERTY, + _("property is missing")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_BLUETOOTH_SETTING_NAME, NM_SETTING_BLUETOOTH_BDADDR); + return FALSE; + } + } + return TRUE; } From ab46c9c70c41b14db2c216983bfa96194f272b5a Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Mon, 22 May 2017 18:12:29 +0200 Subject: [PATCH 12/21] clients: allow bridge settings for Bluetooth devices Will be useful for Bluetooth NAP. --- clients/common/nm-meta-setting-desc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/clients/common/nm-meta-setting-desc.c b/clients/common/nm-meta-setting-desc.c index 1eef126dad..3862e17fee 100644 --- a/clients/common/nm-meta-setting-desc.c +++ b/clients/common/nm-meta-setting-desc.c @@ -6778,6 +6778,7 @@ const NMMetaSettingInfoEditor nm_meta_setting_infos_editor[] = { .valid_parts = NM_META_SETTING_VALID_PARTS ( NM_META_SETTING_VALID_PART_ITEM (CONNECTION, TRUE), NM_META_SETTING_VALID_PART_ITEM (BLUETOOTH, TRUE), + NM_META_SETTING_VALID_PART_ITEM (BRIDGE, FALSE), ), .setting_init_fcn = _setting_init_fcn_bluetooth, ), From aedeb3cbf4fa5857d7784b10d8b20cba798cc7ce Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Mon, 22 May 2017 20:33:29 +0200 Subject: [PATCH 13/21] clients: add support for Bluetooth NAP type --- clients/cli/connections.c | 13 +++++++------ clients/common/nm-meta-setting-desc.c | 4 ++-- clients/common/nm-meta-setting-desc.h | 3 ++- man/nmcli.xml | 8 ++++---- 4 files changed, 15 insertions(+), 13 deletions(-) diff --git a/clients/cli/connections.c b/clients/cli/connections.c index 983a9587dd..f2f4adecf7 100644 --- a/clients/cli/connections.c +++ b/clients/cli/connections.c @@ -301,7 +301,7 @@ usage_connection_add (void) " [parent ]\n" " [p-key ]\n\n" " bluetooth: [addr ]\n" - " [bt-type panu|dun-gsm|dun-cdma]\n\n" + " [bt-type panu|nap|dun-gsm|dun-cdma]\n\n" " vlan: dev \n" " id \n" " [flags ]\n" @@ -3769,7 +3769,7 @@ gen_func_bool_values_l10n (const char *text, int state) static char * gen_func_bt_type (const char *text, int state) { - const char *words[] = { "panu", "dun-gsm", "dun-cdma", NULL }; + const char *words[] = { "panu", "nap", "dun-gsm", "dun-cdma", NULL }; return nmc_rl_gen_func_basic (text, state, words); } @@ -3991,13 +3991,14 @@ set_bluetooth_type (NmCli *nmc, NMConnection *con, const OptionInfo *option, con value = NM_SETTING_BLUETOOTH_TYPE_DUN; setting = nm_setting_cdma_new (); nm_connection_add_setting (con, setting); - } else if (!strcmp (value, NM_SETTING_BLUETOOTH_TYPE_PANU)) { + } else if (!strcmp (value, NM_SETTING_BLUETOOTH_TYPE_PANU) || !strcmp (value, NM_SETTING_BLUETOOTH_TYPE_NAP)) { /* no op */ } else { g_set_error (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT, - _("Error: 'bt-type': '%s' not valid; use [%s, %s (%s), %s]."), - value, NM_SETTING_BLUETOOTH_TYPE_PANU, NM_SETTING_BLUETOOTH_TYPE_DUN, - NM_SETTING_BLUETOOTH_TYPE_DUN"-gsm", NM_SETTING_BLUETOOTH_TYPE_DUN"-cdma"); + _("Error: 'bt-type': '%s' not valid; use [%s, %s, %s (%s), %s]."), + value, NM_SETTING_BLUETOOTH_TYPE_PANU, NM_SETTING_BLUETOOTH_TYPE_NAP, + NM_SETTING_BLUETOOTH_TYPE_DUN, NM_SETTING_BLUETOOTH_TYPE_DUN"-gsm", + NM_SETTING_BLUETOOTH_TYPE_DUN"-cdma"); return FALSE; } diff --git a/clients/common/nm-meta-setting-desc.c b/clients/common/nm-meta-setting-desc.c index 3862e17fee..39d958c9f5 100644 --- a/clients/common/nm-meta-setting-desc.c +++ b/clients/common/nm-meta-setting-desc.c @@ -4817,7 +4817,6 @@ static const NMMetaPropertyInfo *const property_infos_BLUETOOTH[] = { PROPERTY_INFO_WITH_DESC (NM_SETTING_BLUETOOTH_BDADDR, .is_cli_option = TRUE, .property_alias = "addr", - .inf_flags = NM_META_PROPERTY_INF_FLAG_REQD, .prompt = N_("Bluetooth device address"), .property_type = &_pt_gobject_mac, ), @@ -4829,7 +4828,8 @@ static const NMMetaPropertyInfo *const property_infos_BLUETOOTH[] = { .property_type = &_pt_gobject_string, .property_typ_data = DEFINE_PROPERTY_TYP_DATA ( .values_static = VALUES_STATIC (NM_SETTING_BLUETOOTH_TYPE_DUN, - NM_SETTING_BLUETOOTH_TYPE_PANU), + NM_SETTING_BLUETOOTH_TYPE_PANU, + NM_SETTING_BLUETOOTH_TYPE_NAP), ), ), NULL diff --git a/clients/common/nm-meta-setting-desc.h b/clients/common/nm-meta-setting-desc.h index e21c9f3971..5d6cfbbc8d 100644 --- a/clients/common/nm-meta-setting-desc.h +++ b/clients/common/nm-meta-setting-desc.h @@ -44,9 +44,10 @@ struct _NMDevice; #define NM_META_TEXT_PROMPT_BT_TYPE N_("Bluetooth type") #define NM_META_TEXT_WORD_PANU "panu" +#define NM_META_TEXT_WORD_NAP "nap" #define NM_META_TEXT_WORD_DUN_GSM "dun-gsm" #define NM_META_TEXT_WORD_DUN_CDMA "dun-cdma" -#define NM_META_TEXT_PROMPT_BT_TYPE_CHOICES "(" NM_META_TEXT_WORD_PANU "/" NM_META_TEXT_WORD_DUN_GSM "/" NM_META_TEXT_WORD_DUN_CDMA ") [" NM_META_TEXT_WORD_PANU "]" +#define NM_META_TEXT_PROMPT_BT_TYPE_CHOICES "(" NM_META_TEXT_WORD_PANU "/" NM_META_TEXT_WORD_NAP "/" NM_META_TEXT_WORD_DUN_GSM "/" NM_META_TEXT_WORD_DUN_CDMA ") [" NM_META_TEXT_WORD_PANU "]" #define NM_META_TEXT_PROMPT_BOND_MODE N_("Bonding mode") diff --git a/man/nmcli.xml b/man/nmcli.xml index 8ee7914b15..58a7004f07 100644 --- a/man/nmcli.xml +++ b/man/nmcli.xml @@ -1804,10 +1804,10 @@ property as well. bt-type bluetooth.type - Apart from the usual dun and -panu options, the values of dun-gsm -and dun-cdma can be used for compatibility with older -versions. They are equivalent to using dun and setting + Apart from the usual panu, +nap and dun options, the values of +dun-gsm and dun-cdma can be used for compatibility +with older versions. They are equivalent to using dun and setting appropriate gsm.* or cdma.* properties. From 805d3240f9363f5ea5d57000f2920234bf6cd152 Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Wed, 24 May 2017 16:35:03 +0200 Subject: [PATCH 14/21] devices/factory: allow announcing a NULL component We'll use this to let the devices know they can retry autoactivation because some component became available without actually having any data that would be useful for that device. Adjust the comment. --- src/devices/nm-device-factory.c | 1 - src/devices/nm-device-factory.h | 14 +++++++++----- src/devices/nm-device.h | 8 ++++---- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/src/devices/nm-device-factory.c b/src/devices/nm-device-factory.c index f512b8b25d..a2447ad66d 100644 --- a/src/devices/nm-device-factory.c +++ b/src/devices/nm-device-factory.c @@ -55,7 +55,6 @@ nm_device_factory_emit_component_added (NMDeviceFactory *factory, GObject *compo gboolean consumed = FALSE; g_return_val_if_fail (NM_IS_DEVICE_FACTORY (factory), FALSE); - g_return_val_if_fail (G_IS_OBJECT (component), FALSE); g_signal_emit (factory, signals[COMPONENT_ADDED], 0, component, &consumed); return consumed; diff --git a/src/devices/nm-device-factory.h b/src/devices/nm-device-factory.h index 7f8175e455..836af5f522 100644 --- a/src/devices/nm-device-factory.h +++ b/src/devices/nm-device-factory.h @@ -140,11 +140,15 @@ typedef struct { * @factory: the #NMDeviceFactory * @component: a new component which existing devices may wish to claim * - * The factory emits this signal when it finds a new component. For example, - * the WWAN factory may indicate that a new modem is available, which an - * existing Bluetooth device may wish to claim. 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. + * 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 */ diff --git a/src/devices/nm-device.h b/src/devices/nm-device.h index c91ec2d5ec..cc1510ed7b 100644 --- a/src/devices/nm-device.h +++ b/src/devices/nm-device.h @@ -375,10 +375,10 @@ typedef struct { * @self: the #NMDevice * @component: the component (device, modem, etc) which was added * - * Notifies @self that a new component was added to the Manager. This - * may include any kind of %GObject subclass, and the device is expected - * to match only specific components they care about, like %NMModem objects - * or %NMDevice objects. + * 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 From b866a12667224bbed3029897a873126f499807bb Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Thu, 25 May 2017 18:22:44 +0200 Subject: [PATCH 15/21] device: retry autoactivation upon a component addition It might have changed circumstances that were blocking the autoactivation. --- src/devices/bluetooth/nm-device-bt.c | 2 +- src/devices/nm-device.c | 14 +++++++++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/devices/bluetooth/nm-device-bt.c b/src/devices/bluetooth/nm-device-bt.c index 3402532fca..16630996a7 100644 --- a/src/devices/bluetooth/nm-device-bt.c +++ b/src/devices/bluetooth/nm-device-bt.c @@ -647,7 +647,7 @@ component_added (NMDevice *device, GObject *component) NMDeviceState state; NMDeviceStateReason failure_reason = NM_DEVICE_STATE_REASON_NONE; - if (!NM_IS_MODEM (component)) + if (!component || !NM_IS_MODEM (component)) return FALSE; modem = NM_MODEM (component); diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index ca816ec1e4..e11b7158fb 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -3291,13 +3291,25 @@ gboolean nm_device_notify_component_added (NMDevice *self, GObject *component) { NMDeviceClass *klass; + NMDevicePrivate *priv; g_return_val_if_fail (NM_IS_DEVICE (self), FALSE); - g_return_val_if_fail (G_IS_OBJECT (component), FALSE); + 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 (klass->component_added) return klass->component_added (self, component); + return FALSE; } From 53482c38e20c213cf48d58ce2b9e2a27f46848d6 Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Tue, 23 May 2017 13:06:50 +0200 Subject: [PATCH 16/21] device: register a bridge for Bluetooth NAP with Bluez Bluez needs to know about then so that it can eventually enslave the BNEP links for PANU client connections to it. --- src/devices/bluetooth/nm-bluez-common.h | 2 +- src/devices/nm-device.c | 76 +++++++++++++++++++++++++ src/devices/nm-device.h | 12 ++++ 3 files changed, 89 insertions(+), 1 deletion(-) diff --git a/src/devices/bluetooth/nm-bluez-common.h b/src/devices/bluetooth/nm-bluez-common.h index 7abc0ddabc..19344d36c4 100644 --- a/src/devices/bluetooth/nm-bluez-common.h +++ b/src/devices/bluetooth/nm-bluez-common.h @@ -15,7 +15,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2009 Red Hat, Inc. + * Copyright (C) 2017 Red Hat, Inc. */ #ifndef __NETWORKMANAGER_BLUEZ_COMMON_H__ diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index e11b7158fb..252402fb96 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -70,6 +70,7 @@ #include "nm-arping-manager.h" #include "nm-connectivity.h" #include "nm-dbus-interface.h" +#include "bluetooth/nm-bluez-common.h" #include "nm-device-logging.h" _LOG_DECLARE_SELF (NMDevice); @@ -4364,6 +4365,70 @@ dnsmasq_state_changed_cb (NMDnsMasqManager *manager, guint32 status, gpointer us /*****************************************************************************/ +const NMBtVTableNetworkServer *nm_bt_vtable_network_server = NULL; + +static NMSettingBluetooth * +_setting_bluetooth_for_bt_nap (NMConnection *connection) +{ + NMSettingBluetooth *s_bt = nm_connection_get_setting_bluetooth (connection); + + if (!s_bt) + return NULL; + if (!nm_streq0 (nm_setting_bluetooth_get_connection_type (s_bt), NM_SETTING_BLUETOOTH_TYPE_NAP)) + return NULL; + + return s_bt; +} + +static gboolean +bt_network_server_available (NMConnection *connection) +{ + NMSettingBluetooth *s_bt = _setting_bluetooth_for_bt_nap (connection); + + if (!s_bt) + return TRUE; + if (!nm_bt_vtable_network_server) + return FALSE; + return nm_bt_vtable_network_server->is_available (nm_bt_vtable_network_server, + nm_setting_bluetooth_get_bdaddr (s_bt)); +} + +static gboolean +bt_network_server_register (NMDevice *self) +{ + NMConnection *connection = nm_device_get_applied_connection (self); + NMSettingBluetooth *s_bt = _setting_bluetooth_for_bt_nap (connection); + + if (!s_bt) + return TRUE; + if (!nm_bt_vtable_network_server) + return FALSE; + return nm_bt_vtable_network_server->register_bridge (nm_bt_vtable_network_server, + nm_setting_bluetooth_get_bdaddr (s_bt), + BLUETOOTH_CONNECT_NAP, + self); +} + +static void +bt_network_server_unregister (NMDevice *self) +{ + NMConnection *connection = nm_device_get_applied_connection (self); + NMSettingBluetooth *s_bt; + + if (!connection) + return; + s_bt = _setting_bluetooth_for_bt_nap (connection); + if (!s_bt) + return; + + if (!nm_bt_vtable_network_server) + return; + nm_bt_vtable_network_server->unregister_bridge (nm_bt_vtable_network_server, + self); +} + +/*****************************************************************************/ + static gboolean activation_source_handle_cb4 (gpointer user_data) { @@ -4749,6 +4814,12 @@ activate_stage2_device_config (NMDevice *self) nm_device_queue_recheck_assume (info->slave); } + if (!bt_network_server_register (self)) { + /* The HCI we could use is no longer present. */ + nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_REMOVED); + return; + } + lldp_init (self, TRUE); nm_device_activate_schedule_stage3_ip_config_start (self); } @@ -11438,6 +11509,9 @@ _nm_device_check_connection_available (NMDevice *self, { NMDeviceState state; + if (!bt_network_server_available (connection)) + return FALSE; + /* an unrealized software device is always available, hardware devices never. */ if (!nm_device_is_real (self)) { if (nm_device_is_software (self)) @@ -11879,6 +11953,8 @@ _cleanup_generic_pre (NMDevice *self, CleanupType cleanup_type) queued_state_clear (self); + bt_network_server_unregister (self); + _cleanup_ip4_pre (self, cleanup_type); _cleanup_ip6_pre (self, cleanup_type); } diff --git a/src/devices/nm-device.h b/src/devices/nm-device.h index cc1510ed7b..271810d293 100644 --- a/src/devices/nm-device.h +++ b/src/devices/nm-device.h @@ -705,4 +705,16 @@ void nm_device_check_connectivity (NMDevice *self, gpointer user_data); NMConnectivityState nm_device_get_connectivity_state (NMDevice *self); +typedef struct _NMBtVTableNetworkServer NMBtVTableNetworkServer; +struct _NMBtVTableNetworkServer { + gboolean (*is_available) (const NMBtVTableNetworkServer *vtable, + const char *addr); + gboolean (*register_bridge) (const NMBtVTableNetworkServer *vtable, + const char *addr, const char *uuid, NMDevice *device); + gboolean (*unregister_bridge) (const NMBtVTableNetworkServer *vtable, + NMDevice *device); +}; + +extern const NMBtVTableNetworkServer *nm_bt_vtable_network_server; + #endif /* __NETWORKMANAGER_DEVICE_H__ */ From d6f2a2e73c1a98da6f1959a2360810ac258260ad Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Tue, 23 May 2017 18:14:19 +0200 Subject: [PATCH 17/21] bluetooth: expose known HCI adapters to devices They may register the Bluetooth NAP enabled bridges for Bluez to enslave their BNEP links to. --- src/devices/bluetooth/nm-bluez-common.h | 2 + src/devices/bluetooth/nm-bluez5-manager.c | 213 +++++++++++++++++++++- 2 files changed, 213 insertions(+), 2 deletions(-) diff --git a/src/devices/bluetooth/nm-bluez-common.h b/src/devices/bluetooth/nm-bluez-common.h index 19344d36c4..d72bea8131 100644 --- a/src/devices/bluetooth/nm-bluez-common.h +++ b/src/devices/bluetooth/nm-bluez-common.h @@ -32,6 +32,7 @@ #define NM_BLUEZ5_ADAPTER_INTERFACE "org.bluez.Adapter1" #define NM_BLUEZ5_DEVICE_INTERFACE "org.bluez.Device1" #define NM_BLUEZ5_NETWORK_INTERFACE "org.bluez.Network1" +#define NM_BLUEZ5_NETWORK_SERVER_INTERFACE "org.bluez.NetworkServer1" #define NM_BLUEZ4_MANAGER_INTERFACE "org.bluez.Manager" #define NM_BLUEZ4_ADAPTER_INTERFACE "org.bluez.Adapter" @@ -40,5 +41,6 @@ #define NM_BLUEZ4_NETWORK_INTERFACE "org.bluez.Network" #define NM_BLUEZ_MANAGER_BDADDR_ADDED "bdaddr-added" +#define NM_BLUEZ_MANAGER_NETWORK_SERVER_ADDED "network-server-added" #endif /* NM_BLUEZ_COMMON_H */ diff --git a/src/devices/bluetooth/nm-bluez5-manager.c b/src/devices/bluetooth/nm-bluez5-manager.c index 1d3abb2905..2dfc521bc6 100644 --- a/src/devices/bluetooth/nm-bluez5-manager.c +++ b/src/devices/bluetooth/nm-bluez5-manager.c @@ -16,7 +16,7 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Copyright (C) 2007 - 2008 Novell, Inc. - * Copyright (C) 2007 - 2013 Red Hat, Inc. + * Copyright (C) 2007 - 2017 Red Hat, Inc. * Copyright (C) 2013 Intel Corporation. */ @@ -30,14 +30,17 @@ #include "nm-core-internal.h" +#include "nm-utils/c-list.h" #include "nm-bluez-device.h" #include "nm-bluez-common.h" +#include "devices/nm-device.h" #include "settings/nm-settings.h" /*****************************************************************************/ enum { BDADDR_ADDED, + NETWORK_SERVER_ADDED, LAST_SIGNAL, }; @@ -49,10 +52,13 @@ typedef struct { GDBusProxy *proxy; GHashTable *devices; + + CList network_servers; } NMBluez5ManagerPrivate; struct _NMBluez5Manager { GObject parent; + NMBtVTableNetworkServer network_server_vtable; NMBluez5ManagerPrivate _priv; }; @@ -64,6 +70,10 @@ 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 @@ -76,6 +86,174 @@ static void device_usable (NMBluezDevice *device, GParamSpec *pspec, NMBluez5Man /*****************************************************************************/ +typedef struct { + char *path; + char *addr; + char *uuid; + NMDevice *device; + CList network_servers; +} NetworkServer; + +static NetworkServer* +_find_network_server (NMBluez5Manager *self, + const gchar *path, const gchar *addr, NMDevice *device) +{ + NMBluez5ManagerPrivate *priv = NM_BLUEZ5_MANAGER_GET_PRIVATE (self); + NetworkServer *network_server; + CList *iter; + + c_list_for_each (iter, &priv->network_servers) { + network_server = c_list_entry (iter, NetworkServer, network_servers); + + /* Device and path matches are exact. */ + if ( (path && !strcmp (network_server->path, path)) + || (device && network_server->device == device)) + return network_server; + + /* The address lookups need a server not assigned to a device + * and tolerate an empty address as a wildcard for "any". */ + if ( (!path && !device) + && !network_server->device + && (!addr || !strcmp (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->uuid) { + /* 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)", network_server->uuid), + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, NULL, NULL, NULL); + + g_clear_pointer (&network_server->uuid, g_free); + 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 (&network_server->network_servers); + 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 (self, NULL, addr, NULL); +} + +static gboolean +network_server_register_bridge (const NMBtVTableNetworkServer *vtable, + const char *addr, const char *uuid, 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 (self, NULL, addr, NULL); + + 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)", uuid, nm_device_get_iface (device)), + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, NULL, NULL, NULL); + + network_server->device = g_object_ref (device); + network_server->uuid = g_strdup (uuid); + + 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, NULL, device); + + if (network_server) + _network_server_unregister (self, network_server); + + return TRUE; +} + +static void +network_server_removed (GDBusProxy *proxy, const gchar *path, NMBluez5Manager *self) +{ + NetworkServer *network_server; + + network_server = _find_network_server (self, path, NULL, 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 gchar *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->network_servers); + + _LOGI ("NAP: added interface %s", addr); + + g_signal_emit (self, signals[NETWORK_SERVER_ADDED], 0); +} + +/*****************************************************************************/ + static void emit_bdaddr_added (NMBluez5Manager *self, NMBluezDevice *device) { @@ -193,6 +371,14 @@ object_manager_interfaces_added (GDBusProxy *proxy, { 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)) { + GVariant *adapter = g_variant_lookup_value (dict, NM_BLUEZ5_ADAPTER_INTERFACE, G_VARIANT_TYPE_DICTIONARY); + const char *address; + + g_variant_lookup (adapter, "Address", "&s", &address); + network_server_added (proxy, path, address, self); + g_variant_unref (adapter); + } } static void @@ -203,6 +389,8 @@ object_manager_interfaces_removed (GDBusProxy *proxy, { 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 @@ -314,11 +502,20 @@ 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 (g_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 * @@ -338,6 +535,10 @@ 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, network_servers)); if (priv->proxy) { g_signal_handlers_disconnect_by_func (priv->proxy, G_CALLBACK (name_owner_changed_cb), self); @@ -352,7 +553,8 @@ dispose (GObject *object) static void finalize (GObject *object) { - NMBluez5ManagerPrivate *priv = NM_BLUEZ5_MANAGER_GET_PRIVATE ((NMBluez5Manager *) object); + NMBluez5Manager *self = NM_BLUEZ5_MANAGER (object); + NMBluez5ManagerPrivate *priv = NM_BLUEZ5_MANAGER_GET_PRIVATE (self); g_hash_table_destroy (priv->devices); @@ -376,4 +578,11 @@ nm_bluez5_manager_class_init (NMBluez5ManagerClass *klass) 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); } From 29a0876db6205f7a017c335df22d4a115fe04fe5 Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Thu, 25 May 2017 18:23:35 +0200 Subject: [PATCH 18/21] bluetooth: emit component-added when a network server is added --- src/devices/bluetooth/nm-bluez-manager.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/devices/bluetooth/nm-bluez-manager.c b/src/devices/bluetooth/nm-bluez-manager.c index e290173220..33bea4e27c 100644 --- a/src/devices/bluetooth/nm-bluez-manager.c +++ b/src/devices/bluetooth/nm-bluez-manager.c @@ -146,7 +146,7 @@ cleanup_checking (NMBluezManager *self, gboolean do_unwatch_name) static void -manager_bdaddr_added_cb (NMBluez4Manager *bluez_mgr, +manager_bdaddr_added_cb (GObject *manager, NMBluezDevice *bt_device, const char *bdaddr, const char *name, @@ -179,6 +179,13 @@ manager_bdaddr_added_cb (NMBluez4Manager *bluez_mgr, g_object_unref (device); } +static void +manager_network_server_added_cb (GObject *manager, + gpointer user_data) +{ + nm_device_factory_emit_component_added (NM_DEVICE_FACTORY (user_data), NULL); +} + static void setup_version_number (NMBluezManager *self, int bluez_version) { @@ -228,6 +235,10 @@ setup_bluez5 (NMBluezManager *self) NM_BLUEZ_MANAGER_BDADDR_ADDED, G_CALLBACK (manager_bdaddr_added_cb), self); + g_signal_connect (manager, + NM_BLUEZ_MANAGER_NETWORK_SERVER_ADDED, + G_CALLBACK (manager_network_server_added_cb), + self); nm_bluez5_manager_query_devices (manager); } @@ -427,7 +438,7 @@ dispose (GObject *object) g_clear_object (&priv->manager4); } if (priv->manager5) { - g_signal_handlers_disconnect_by_func (priv->manager5, manager_bdaddr_added_cb, self); + g_signal_handlers_disconnect_by_data (priv->manager5, self); g_clear_object (&priv->manager5); } From 1be01bd51f3e27d82335999586e8efff40b92b87 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 31 May 2017 22:55:03 +0200 Subject: [PATCH 19/21] device: don't include header of bluetooth plugin in nm-device.h The plugins may use stuff from core, but not the other way around. Including "bluetooth/nm-bluez-common.h" is wrong. The UUID argument is always "nap" in the NAP case. We don't need the flexibility that it might be anything else. Just drop it. As far as NMDevice is concerned, it anyway wouldn't (or shouldn't know what the uuid is. It says register, and NMBluez5Manager should figure out the details. --- src/devices/bluetooth/nm-bluez5-manager.c | 12 +++++------- src/devices/nm-device.c | 2 -- src/devices/nm-device.h | 3 ++- 3 files changed, 7 insertions(+), 10 deletions(-) diff --git a/src/devices/bluetooth/nm-bluez5-manager.c b/src/devices/bluetooth/nm-bluez5-manager.c index 2dfc521bc6..a2d1a4c214 100644 --- a/src/devices/bluetooth/nm-bluez5-manager.c +++ b/src/devices/bluetooth/nm-bluez5-manager.c @@ -89,7 +89,6 @@ static void device_usable (NMBluezDevice *device, GParamSpec *pspec, NMBluez5Man typedef struct { char *path; char *addr; - char *uuid; NMDevice *device; CList network_servers; } NetworkServer; @@ -126,7 +125,7 @@ _network_server_unregister (NMBluez5Manager *self, NetworkServer *network_server { NMBluez5ManagerPrivate *priv = NM_BLUEZ5_MANAGER_GET_PRIVATE (self); - if (!network_server->uuid) { + if (!network_server->device) { /* Not connected. */ return; } @@ -140,12 +139,11 @@ _network_server_unregister (NMBluez5Manager *self, NetworkServer *network_server network_server->path, NM_BLUEZ5_NETWORK_SERVER_INTERFACE, "Unregister", - g_variant_new ("(s)", network_server->uuid), + g_variant_new ("(s)", BLUETOOTH_CONNECT_NAP), NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL); - g_clear_pointer (&network_server->uuid, g_free); g_clear_object (&network_server->device); } @@ -170,7 +168,8 @@ network_server_is_available (const NMBtVTableNetworkServer *vtable, static gboolean network_server_register_bridge (const NMBtVTableNetworkServer *vtable, - const char *addr, const char *uuid, NMDevice *device) + const char *addr, + NMDevice *device) { NMBluez5Manager *self = NETWORK_SERVER_VTABLE_GET_NM_BLUEZ5_MANAGER (vtable); NMBluez5ManagerPrivate *priv = NM_BLUEZ5_MANAGER_GET_PRIVATE (self); @@ -191,13 +190,12 @@ network_server_register_bridge (const NMBtVTableNetworkServer *vtable, network_server->path, NM_BLUEZ5_NETWORK_SERVER_INTERFACE, "Register", - g_variant_new ("(ss)", uuid, nm_device_get_iface (device)), + 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); - network_server->uuid = g_strdup (uuid); return TRUE; } diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index 252402fb96..8be901b297 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -70,7 +70,6 @@ #include "nm-arping-manager.h" #include "nm-connectivity.h" #include "nm-dbus-interface.h" -#include "bluetooth/nm-bluez-common.h" #include "nm-device-logging.h" _LOG_DECLARE_SELF (NMDevice); @@ -4405,7 +4404,6 @@ bt_network_server_register (NMDevice *self) return FALSE; return nm_bt_vtable_network_server->register_bridge (nm_bt_vtable_network_server, nm_setting_bluetooth_get_bdaddr (s_bt), - BLUETOOTH_CONNECT_NAP, self); } diff --git a/src/devices/nm-device.h b/src/devices/nm-device.h index 271810d293..00685ee29b 100644 --- a/src/devices/nm-device.h +++ b/src/devices/nm-device.h @@ -710,7 +710,8 @@ struct _NMBtVTableNetworkServer { gboolean (*is_available) (const NMBtVTableNetworkServer *vtable, const char *addr); gboolean (*register_bridge) (const NMBtVTableNetworkServer *vtable, - const char *addr, const char *uuid, NMDevice *device); + const char *addr, + NMDevice *device); gboolean (*unregister_bridge) (const NMBtVTableNetworkServer *vtable, NMDevice *device); }; From b0f9571d3d6c5dff53c677ae2841126cd482e363 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 31 May 2017 22:37:49 +0200 Subject: [PATCH 20/21] libnm: add _nm_connection_get_setting_bluetooth_for_nap() If there is value in such a helper function (there is), then it should go alongside the other nm_connection_get_setting*() helpers. NMDevice is already large enough. --- libnm-core/nm-connection.c | 11 +++++++++++ libnm-core/nm-core-internal.h | 4 ++++ src/devices/nm-device.c | 19 +++---------------- 3 files changed, 18 insertions(+), 16 deletions(-) diff --git a/libnm-core/nm-connection.c b/libnm-core/nm-connection.c index 2be9007682..2b9a05ca19 100644 --- a/libnm-core/nm-connection.c +++ b/libnm-core/nm-connection.c @@ -2518,6 +2518,17 @@ nm_connection_get_setting_vlan (NMConnection *connection) return (NMSettingVlan *) nm_connection_get_setting (connection, NM_TYPE_SETTING_VLAN); } +NMSettingBluetooth * +_nm_connection_get_setting_bluetooth_for_nap (NMConnection *connection) +{ + NMSettingBluetooth *s_bt = nm_connection_get_setting_bluetooth (connection); + + if ( s_bt + && nm_streq0 (nm_setting_bluetooth_get_connection_type (s_bt), NM_SETTING_BLUETOOTH_TYPE_NAP)) + return s_bt; + return NULL; +} + /*****************************************************************************/ static void diff --git a/libnm-core/nm-core-internal.h b/libnm-core/nm-core-internal.h index 9bc54df387..102cd6575f 100644 --- a/libnm-core/nm-core-internal.h +++ b/libnm-core/nm-core-internal.h @@ -352,6 +352,10 @@ gboolean _nm_setting_bond_option_supported (const char *option, NMBondMode mode) /*****************************************************************************/ +NMSettingBluetooth *_nm_connection_get_setting_bluetooth_for_nap (NMConnection *connection); + +/*****************************************************************************/ + gboolean _nm_utils_inet6_is_token (const struct in6_addr *in6addr); /*****************************************************************************/ diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index 8be901b297..65621006ad 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -4366,23 +4366,10 @@ dnsmasq_state_changed_cb (NMDnsMasqManager *manager, guint32 status, gpointer us const NMBtVTableNetworkServer *nm_bt_vtable_network_server = NULL; -static NMSettingBluetooth * -_setting_bluetooth_for_bt_nap (NMConnection *connection) -{ - NMSettingBluetooth *s_bt = nm_connection_get_setting_bluetooth (connection); - - if (!s_bt) - return NULL; - if (!nm_streq0 (nm_setting_bluetooth_get_connection_type (s_bt), NM_SETTING_BLUETOOTH_TYPE_NAP)) - return NULL; - - return s_bt; -} - static gboolean bt_network_server_available (NMConnection *connection) { - NMSettingBluetooth *s_bt = _setting_bluetooth_for_bt_nap (connection); + NMSettingBluetooth *s_bt = _nm_connection_get_setting_bluetooth_for_nap (connection); if (!s_bt) return TRUE; @@ -4396,7 +4383,7 @@ static gboolean bt_network_server_register (NMDevice *self) { NMConnection *connection = nm_device_get_applied_connection (self); - NMSettingBluetooth *s_bt = _setting_bluetooth_for_bt_nap (connection); + NMSettingBluetooth *s_bt = _nm_connection_get_setting_bluetooth_for_nap (connection); if (!s_bt) return TRUE; @@ -4415,7 +4402,7 @@ bt_network_server_unregister (NMDevice *self) if (!connection) return; - s_bt = _setting_bluetooth_for_bt_nap (connection); + s_bt = _nm_connection_get_setting_bluetooth_for_nap (connection); if (!s_bt) return; From bf7e86128c85141b6e30af1b671b023bfac0998d Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Thu, 1 Jun 2017 11:57:42 +0200 Subject: [PATCH 21/21] bridge: move the Bluetooth NAP logic to bridge device The Bluetooth NAP functionality seems only useful for the bridges. Move it away from NMDevice. --- src/devices/bluetooth/nm-bluez5-manager.c | 2 +- src/devices/nm-device-bridge.c | 73 +++++++++++++++++++++++ src/devices/nm-device-bridge.h | 2 + src/devices/nm-device.c | 61 ------------------- src/devices/nm-device.h | 2 - 5 files changed, 76 insertions(+), 64 deletions(-) diff --git a/src/devices/bluetooth/nm-bluez5-manager.c b/src/devices/bluetooth/nm-bluez5-manager.c index a2d1a4c214..83028a2c85 100644 --- a/src/devices/bluetooth/nm-bluez5-manager.c +++ b/src/devices/bluetooth/nm-bluez5-manager.c @@ -33,7 +33,7 @@ #include "nm-utils/c-list.h" #include "nm-bluez-device.h" #include "nm-bluez-common.h" -#include "devices/nm-device.h" +#include "devices/nm-device-bridge.h" #include "settings/nm-settings.h" /*****************************************************************************/ diff --git a/src/devices/nm-device-bridge.c b/src/devices/nm-device-bridge.c index 01c4eb224b..c281dbad0c 100644 --- a/src/devices/nm-device-bridge.c +++ b/src/devices/nm-device-bridge.c @@ -49,6 +49,56 @@ G_DEFINE_TYPE (NMDeviceBridge, nm_device_bridge, NM_TYPE_DEVICE) /*****************************************************************************/ +const NMBtVTableNetworkServer *nm_bt_vtable_network_server = NULL; + +static gboolean +bt_network_server_available (NMConnection *connection) +{ + NMSettingBluetooth *s_bt = _nm_connection_get_setting_bluetooth_for_nap (connection); + + if (!s_bt) + return TRUE; + if (!nm_bt_vtable_network_server) + return FALSE; + return nm_bt_vtable_network_server->is_available (nm_bt_vtable_network_server, + nm_setting_bluetooth_get_bdaddr (s_bt)); +} + +static gboolean +bt_network_server_register (NMDevice *self) +{ + NMConnection *connection = nm_device_get_applied_connection (self); + NMSettingBluetooth *s_bt = _nm_connection_get_setting_bluetooth_for_nap (connection); + + if (!s_bt) + return TRUE; + if (!nm_bt_vtable_network_server) + return FALSE; + return nm_bt_vtable_network_server->register_bridge (nm_bt_vtable_network_server, + nm_setting_bluetooth_get_bdaddr (s_bt), + self); +} + +static void +bt_network_server_unregister (NMDevice *self) +{ + NMConnection *connection = nm_device_get_applied_connection (self); + NMSettingBluetooth *s_bt; + + if (!connection) + return; + s_bt = _nm_connection_get_setting_bluetooth_for_nap (connection); + if (!s_bt) + return; + + if (!nm_bt_vtable_network_server) + return; + nm_bt_vtable_network_server->unregister_bridge (nm_bt_vtable_network_server, + self); +} + +/*****************************************************************************/ + static NMDeviceCapabilities get_generic_capabilities (NMDevice *dev) { @@ -67,6 +117,9 @@ check_connection_available (NMDevice *device, NMDeviceCheckConAvailableFlags flags, const char *specific_object) { + if (!bt_network_server_available (connection)) + return FALSE; + /* Connections are always available because the carrier state is determined * by the bridge port carrier states, not the bridge's state. */ @@ -324,6 +377,24 @@ act_stage1_prepare (NMDevice *device, NMDeviceStateReason *out_failure_reason) return NM_ACT_STAGE_RETURN_SUCCESS; } +static NMActStageReturn +act_stage2_config (NMDevice *device, NMDeviceStateReason *out_failure_reason) +{ + if (!bt_network_server_register (device)) { + /* The HCI we could use is no longer present. */ + *out_failure_reason = NM_DEVICE_STATE_REASON_REMOVED; + return NM_ACT_STAGE_RETURN_FAILURE; + } + + return NM_ACT_STAGE_RETURN_SUCCESS; +} + +static void +deactivate (NMDevice *device) +{ + bt_network_server_unregister (device); +} + static gboolean enslave_slave (NMDevice *device, NMDevice *slave, @@ -443,6 +514,8 @@ nm_device_bridge_class_init (NMDeviceBridgeClass *klass) parent_class->create_and_realize = create_and_realize; parent_class->act_stage1_prepare = act_stage1_prepare; + parent_class->act_stage2_config = act_stage2_config; + parent_class->deactivate = deactivate; parent_class->enslave_slave = enslave_slave; parent_class->release_slave = release_slave; parent_class->get_configured_mtu = nm_device_get_configured_mtu_for_wired; diff --git a/src/devices/nm-device-bridge.h b/src/devices/nm-device-bridge.h index f0fa1f4b64..44b4ed729a 100644 --- a/src/devices/nm-device-bridge.h +++ b/src/devices/nm-device-bridge.h @@ -35,4 +35,6 @@ typedef struct _NMDeviceBridgeClass NMDeviceBridgeClass; GType nm_device_bridge_get_type (void); +extern const NMBtVTableNetworkServer *nm_bt_vtable_network_server; + #endif /* __NETWORKMANAGER_DEVICE_BRIDGE_H__ */ diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index 65621006ad..e11b7158fb 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -4364,56 +4364,6 @@ dnsmasq_state_changed_cb (NMDnsMasqManager *manager, guint32 status, gpointer us /*****************************************************************************/ -const NMBtVTableNetworkServer *nm_bt_vtable_network_server = NULL; - -static gboolean -bt_network_server_available (NMConnection *connection) -{ - NMSettingBluetooth *s_bt = _nm_connection_get_setting_bluetooth_for_nap (connection); - - if (!s_bt) - return TRUE; - if (!nm_bt_vtable_network_server) - return FALSE; - return nm_bt_vtable_network_server->is_available (nm_bt_vtable_network_server, - nm_setting_bluetooth_get_bdaddr (s_bt)); -} - -static gboolean -bt_network_server_register (NMDevice *self) -{ - NMConnection *connection = nm_device_get_applied_connection (self); - NMSettingBluetooth *s_bt = _nm_connection_get_setting_bluetooth_for_nap (connection); - - if (!s_bt) - return TRUE; - if (!nm_bt_vtable_network_server) - return FALSE; - return nm_bt_vtable_network_server->register_bridge (nm_bt_vtable_network_server, - nm_setting_bluetooth_get_bdaddr (s_bt), - self); -} - -static void -bt_network_server_unregister (NMDevice *self) -{ - NMConnection *connection = nm_device_get_applied_connection (self); - NMSettingBluetooth *s_bt; - - if (!connection) - return; - s_bt = _nm_connection_get_setting_bluetooth_for_nap (connection); - if (!s_bt) - return; - - if (!nm_bt_vtable_network_server) - return; - nm_bt_vtable_network_server->unregister_bridge (nm_bt_vtable_network_server, - self); -} - -/*****************************************************************************/ - static gboolean activation_source_handle_cb4 (gpointer user_data) { @@ -4799,12 +4749,6 @@ activate_stage2_device_config (NMDevice *self) nm_device_queue_recheck_assume (info->slave); } - if (!bt_network_server_register (self)) { - /* The HCI we could use is no longer present. */ - nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_REMOVED); - return; - } - lldp_init (self, TRUE); nm_device_activate_schedule_stage3_ip_config_start (self); } @@ -11494,9 +11438,6 @@ _nm_device_check_connection_available (NMDevice *self, { NMDeviceState state; - if (!bt_network_server_available (connection)) - return FALSE; - /* an unrealized software device is always available, hardware devices never. */ if (!nm_device_is_real (self)) { if (nm_device_is_software (self)) @@ -11938,8 +11879,6 @@ _cleanup_generic_pre (NMDevice *self, CleanupType cleanup_type) queued_state_clear (self); - bt_network_server_unregister (self); - _cleanup_ip4_pre (self, cleanup_type); _cleanup_ip6_pre (self, cleanup_type); } diff --git a/src/devices/nm-device.h b/src/devices/nm-device.h index 00685ee29b..e7d79947cc 100644 --- a/src/devices/nm-device.h +++ b/src/devices/nm-device.h @@ -716,6 +716,4 @@ struct _NMBtVTableNetworkServer { NMDevice *device); }; -extern const NMBtVTableNetworkServer *nm_bt_vtable_network_server; - #endif /* __NETWORKMANAGER_DEVICE_H__ */