diff options
author | Lubomir Rintel <lkundrak@v3.sk> | 2017-06-01 12:37:02 +0200 |
---|---|---|
committer | Lubomir Rintel <lkundrak@v3.sk> | 2017-06-01 12:37:02 +0200 |
commit | f9b1bc16e9e691ab89caf883f33d94be72364671 (patch) | |
tree | 3eb5fa946ce3a7f4993f22c1f9206f78559e84c1 | |
parent | 0d71c0569f2eacacd02b0148c6d94f59bace5c65 (diff) | |
parent | bf7e86128c85141b6e30af1b671b023bfac0998d (diff) | |
download | NetworkManager-f9b1bc16e9e691ab89caf883f33d94be72364671.tar.gz |
merge: branch 'lr/bluetooth-nap'
https://bugzilla.gnome.org/show_bug.cgi?id=783013
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__ */ |