merge: branch 'lr/bluetooth-nap'

https://bugzilla.gnome.org/show_bug.cgi?id=783013
This commit is contained in:
Lubomir Rintel 2017-06-01 12:37:02 +02:00
commit f9b1bc16e9
40 changed files with 556 additions and 174 deletions

View file

@ -4509,5 +4509,6 @@ cscope:
###############################################################################
.PRECIOUS: test-suite.log
.DELETE_ON_ERROR:
.PHONY: cscope dist-configure-check $(check_local) $(dist_hook)

View file

@ -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;
}

View file

@ -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,
),

View file

@ -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")

View file

@ -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

View file

@ -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);
/*****************************************************************************/

View file

@ -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))

View file

@ -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;
}

View file

@ -54,11 +54,19 @@ G_BEGIN_DECLS
/**
* NM_SETTING_BLUETOOTH_TYPE_PANU:
*
* Connection type describing a connection to devices that support the Bluetooth
* NAP (Network Access Point) protocol, which accepts connections via PANU.
* Connection type describing PANU connection to a Bluetooth NAP (Network
* Access Point).
*/
#define NM_SETTING_BLUETOOTH_TYPE_PANU "panu"
/**
* NM_SETTING_BLUETOOTH_TYPE_NAP:
*
* Connection type describing a Bluetooth NAP (Network Access Point),
* which accepts PANU clients.
*/
#define NM_SETTING_BLUETOOTH_TYPE_NAP "nap"
/**
* NMSettingBluetooth:
*

View file

@ -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,

View file

@ -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))

View file

@ -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,

View file

@ -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))

View file

@ -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;

View file

@ -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))

View file

@ -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))

View file

@ -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))

View file

@ -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))

View file

@ -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 {

View file

@ -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))

View file

@ -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))

View file

@ -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))

View file

@ -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))

View file

@ -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));
}
/**

View file

@ -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

View file

@ -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);

View file

@ -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>

View file

@ -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 */

View file

@ -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,

View file

@ -146,7 +146,7 @@ cleanup_checking (NMBluezManager *self, gboolean do_unwatch_name)
static void
manager_bdaddr_added_cb (NMBluez4Manager *bluez_mgr,
manager_bdaddr_added_cb (GObject *manager,
NMBluezDevice *bt_device,
const char *bdaddr,
const char *name,
@ -179,6 +179,13 @@ manager_bdaddr_added_cb (NMBluez4Manager *bluez_mgr,
g_object_unref (device);
}
static void
manager_network_server_added_cb (GObject *manager,
gpointer user_data)
{
nm_device_factory_emit_component_added (NM_DEVICE_FACTORY (user_data), NULL);
}
static void
setup_version_number (NMBluezManager *self, int bluez_version)
{
@ -228,6 +235,10 @@ setup_bluez5 (NMBluezManager *self)
NM_BLUEZ_MANAGER_BDADDR_ADDED,
G_CALLBACK (manager_bdaddr_added_cb),
self);
g_signal_connect (manager,
NM_BLUEZ_MANAGER_NETWORK_SERVER_ADDED,
G_CALLBACK (manager_network_server_added_cb),
self);
nm_bluez5_manager_query_devices (manager);
}
@ -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);
}

View file

@ -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);

View file

@ -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);

View file

@ -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;
bluez_cleanup (self, FALSE);
c_list_for_each_safe (iter, safe, &priv->network_servers)
_network_server_free (self, c_list_entry (iter, NetworkServer, network_servers));
if (priv->proxy) {
g_signal_handlers_disconnect_by_func (priv->proxy, G_CALLBACK (name_owner_changed_cb), self);
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);
}

View file

@ -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);

View file

@ -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;

View file

@ -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__ */

View file

@ -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;

View file

@ -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
*/

View file

@ -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;
}

View file

@ -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__ */