summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLubomir Rintel <lkundrak@v3.sk>2017-06-01 12:37:02 +0200
committerLubomir Rintel <lkundrak@v3.sk>2017-06-01 12:37:02 +0200
commitf9b1bc16e9e691ab89caf883f33d94be72364671 (patch)
tree3eb5fa946ce3a7f4993f22c1f9206f78559e84c1
parent0d71c0569f2eacacd02b0148c6d94f59bace5c65 (diff)
parentbf7e86128c85141b6e30af1b671b023bfac0998d (diff)
downloadNetworkManager-f9b1bc16e9e691ab89caf883f33d94be72364671.tar.gz
merge: branch 'lr/bluetooth-nap'
https://bugzilla.gnome.org/show_bug.cgi?id=783013
-rw-r--r--Makefile.am1
-rw-r--r--clients/cli/connections.c13
-rw-r--r--clients/common/nm-meta-setting-desc.c5
-rw-r--r--clients/common/nm-meta-setting-desc.h3
-rw-r--r--libnm-core/nm-connection.c76
-rw-r--r--libnm-core/nm-core-internal.h4
-rw-r--r--libnm-core/nm-setting-8021x.c2
-rw-r--r--libnm-core/nm-setting-bluetooth.c44
-rw-r--r--libnm-core/nm-setting-bluetooth.h12
-rw-r--r--libnm-core/nm-setting-bond.c2
-rw-r--r--libnm-core/nm-setting-bridge-port.c2
-rw-r--r--libnm-core/nm-setting-connection.c2
-rw-r--r--libnm-core/nm-setting-dcb.c2
-rw-r--r--libnm-core/nm-setting-infiniband.c5
-rw-r--r--libnm-core/nm-setting-ip4-config.c2
-rw-r--r--libnm-core/nm-setting-ip6-config.c2
-rw-r--r--libnm-core/nm-setting-ppp.c2
-rw-r--r--libnm-core/nm-setting-pppoe.c2
-rw-r--r--libnm-core/nm-setting-private.h4
-rw-r--r--libnm-core/nm-setting-proxy.c2
-rw-r--r--libnm-core/nm-setting-serial.c2
-rw-r--r--libnm-core/nm-setting-team-port.c2
-rw-r--r--libnm-core/nm-setting-wireless-security.c2
-rw-r--r--libnm-core/nm-setting.c26
-rw-r--r--libnm-core/nm-utils.c4
-rw-r--r--libnm-core/tests/test-general.c8
-rw-r--r--man/nmcli.xml8
-rw-r--r--src/devices/bluetooth/nm-bluez-common.h26
-rw-r--r--src/devices/bluetooth/nm-bluez-device.c26
-rw-r--r--src/devices/bluetooth/nm-bluez-manager.c21
-rw-r--r--src/devices/bluetooth/nm-bluez4-adapter.c4
-rw-r--r--src/devices/bluetooth/nm-bluez4-manager.c6
-rw-r--r--src/devices/bluetooth/nm-bluez5-manager.c283
-rw-r--r--src/devices/bluetooth/nm-device-bt.c2
-rw-r--r--src/devices/nm-device-bridge.c73
-rw-r--r--src/devices/nm-device-bridge.h2
-rw-r--r--src/devices/nm-device-factory.c1
-rw-r--r--src/devices/nm-device-factory.h14
-rw-r--r--src/devices/nm-device.c14
-rw-r--r--src/devices/nm-device.h19
40 files changed, 556 insertions, 174 deletions
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)
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 <ifname>]\n"
" [p-key <IPoIB P_Key>]\n\n"
" bluetooth: [addr <bluetooth address>]\n"
- " [bt-type panu|dun-gsm|dun-cdma]\n\n"
+ " [bt-type panu|nap|dun-gsm|dun-cdma]\n\n"
" vlan: dev <parent device (connection UUID, ifname, or MAC)>\n"
" id <VLAN ID>\n"
" [flags <VLAN 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 1eef126dad..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
@@ -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,
),
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/libnm-core/nm-connection.c b/libnm-core/nm-connection.c
index ecfb9780be..2b9a05ca19 100644
--- a/libnm-core/nm-connection.c
+++ b/libnm-core/nm-connection.c
@@ -585,19 +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) {
- /* 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;
+ 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));
+ }
}
setting = s_iter;
+ setting_prio = s_iter_prio;
}
return setting;
}
@@ -993,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
@@ -1609,19 +1630,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_get_base_type_priority (setting);
}
static int
@@ -1787,6 +1805,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;
@@ -1847,22 +1868,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);
}
/**
@@ -1877,9 +1895,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)
@@ -2501,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/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..26f41d62ce 100644
--- a/libnm-core/nm-setting-bluetooth.c
+++ b/libnm-core/nm-setting-bluetooth.c
@@ -25,6 +25,7 @@
#include <string.h>
#include <net/ethernet.h>
+#include "nm-connection-private.h"
#include "nm-setting-bluetooth.h"
#include "nm-setting-cdma.h"
#include "nm-setting-gsm.h"
@@ -43,7 +44,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))
@@ -80,8 +81,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)
@@ -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,
@@ -139,6 +131,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,
@@ -176,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;
}
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,12 +54,20 @@ 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:
*
* Bluetooth Settings
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-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-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-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-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;
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-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-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..530dd0147a 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
*/
@@ -211,21 +211,27 @@ _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;
+
/* 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);
+ 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 f80f013dc9..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);
@@ -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);
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.
<row>
<entry align="left">bt-type</entry>
<entry align="left"><link linkend="nm-settings.property.bluetooth.type">bluetooth.type</link></entry>
- <entry align="left" valign="top">Apart from the usual <literal>dun</literal> and
-<literal>panu</literal> options, the values of <literal>dun-gsm</literal>
-and <literal>dun-cdma</literal> can be used for compatibility with older
-versions. They are equivalent to using <literal>dun</literal> and setting
+ <entry align="left" valign="top">Apart from the usual <literal>panu</literal>,
+<literal>nap</literal> and <literal>dun</literal> options, the values of
+<literal>dun-gsm</literal> and <literal>dun-cdma</literal> can be used for compatibility
+with older versions. They are equivalent to using <literal>dun</literal> and setting
appropriate <literal>gsm.*</literal> or <literal>cdma.*</literal> properties.</entry>
</row>
</tbody>
diff --git a/src/devices/bluetooth/nm-bluez-common.h b/src/devices/bluetooth/nm-bluez-common.h
index 6e97c3f512..d72bea8131 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__
@@ -24,21 +24,23 @@
#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 NM_BLUEZ5_NETWORK_SERVER_INTERFACE "org.bluez.NetworkServer1"
-#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"
+#define NM_BLUEZ_MANAGER_NETWORK_SERVER_ADDED "network-server-added"
#endif /* NM_BLUEZ_COMMON_H */
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..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,
@@ -180,6 +180,13 @@ manager_bdaddr_added_cb (NMBluez4Manager *bluez_mgr,
}
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)
{
NMBluezManagerPrivate *priv = NM_BLUEZ_MANAGER_GET_PRIVATE (self);
@@ -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);
}
@@ -264,7 +275,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 +328,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 +391,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,
@@ -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);
}
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 88759301d5..83028a2c85 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-bridge.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,15 @@ 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);
@@ -71,6 +86,172 @@ static void device_usable (NMBluezDevice *device, GParamSpec *pspec, NMBluez5Man
/*****************************************************************************/
+typedef struct {
+ char *path;
+ char *addr;
+ 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->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 (&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,
+ 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)", 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, 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)
{
@@ -125,14 +306,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 +324,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 +342,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 +351,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) {
@@ -186,8 +367,16 @@ 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);
+ 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
@@ -196,8 +385,10 @@ 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);
+ if (ifaces && g_strv_contains (ifaces, NM_BLUEZ5_NETWORK_SERVER_INTERFACE))
+ network_server_removed (proxy, path, self);
}
static void
@@ -215,20 +406,17 @@ 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;
}
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,
- G_VARIANT_TYPE_DICTIONARY)) {
- device_added (proxy, path, self);
- }
+ object_manager_interfaces_added (proxy, path, ifaces, self);
g_variant_unref (ifaces);
}
@@ -248,7 +436,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;
}
@@ -281,9 +469,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);
@@ -306,33 +494,26 @@ 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
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 *
@@ -351,8 +532,18 @@ 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, network_servers));
- 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);
}
@@ -360,7 +551,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);
@@ -384,4 +576,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);
}
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-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-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.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;
}
diff --git a/src/devices/nm-device.h b/src/devices/nm-device.h
index c91ec2d5ec..e7d79947cc 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
@@ -705,4 +705,15 @@ 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,
+ NMDevice *device);
+ gboolean (*unregister_bridge) (const NMBtVTableNetworkServer *vtable,
+ NMDevice *device);
+};
+
#endif /* __NETWORKMANAGER_DEVICE_H__ */