diff options
Diffstat (limited to 'libnm-core/nm-setting-bluetooth.c')
| -rw-r--r-- | libnm-core/nm-setting-bluetooth.c | 95 |
1 files changed, 71 insertions, 24 deletions
diff --git a/libnm-core/nm-setting-bluetooth.c b/libnm-core/nm-setting-bluetooth.c index 837b06c0..5b6ef3eb 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, NM_SETTING_PRIORITY_HW_NON_BASE)) 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) @@ -112,17 +113,10 @@ static gboolean verify (NMSetting *setting, NMConnection *connection, GError **error) { NMSettingBluetoothPrivate *priv = NM_SETTING_BLUETOOTH_GET_PRIVATE (setting); + const char *type; + gboolean missing_nap_bridge = FALSE; - 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, @@ -131,27 +125,38 @@ verify (NMSetting *setting, NMConnection *connection, GError **error) return FALSE; } - if (!priv->type) { - 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_TYPE); - return FALSE; - } else if (!g_str_equal (priv->type, NM_SETTING_BLUETOOTH_TYPE_DUN) && - !g_str_equal (priv->type, NM_SETTING_BLUETOOTH_TYPE_PANU)) { + type = priv->type; + if (!type) { + if (connection) { + /* We may infer the type from the (non-)existence of gsm/cdma/bridge settings. */ + type = _nm_connection_detect_bluetooth_type (connection); + } + if (!type) { + 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_TYPE); + return FALSE; + } + } + + if (!NM_IN_STRSET (type, NM_SETTING_BLUETOOTH_TYPE_DUN, + NM_SETTING_BLUETOOTH_TYPE_NAP, + NM_SETTING_BLUETOOTH_TYPE_PANU)) { + nm_assert (priv->type == type); g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY, _("'%s' is not a valid value for the property"), - priv->type); + type); g_prefix_error (error, "%s.%s: ", NM_SETTING_BLUETOOTH_SETTING_NAME, NM_SETTING_BLUETOOTH_TYPE); return FALSE; } /* Make sure the corresponding 'type' setting is present */ if ( connection - && !strcmp (priv->type, NM_SETTING_BLUETOOTH_TYPE_DUN)) { + && nm_streq (type, NM_SETTING_BLUETOOTH_TYPE_DUN)) { gboolean gsm = FALSE, cdma = FALSE; gsm = !!nm_connection_get_setting_gsm (connection); @@ -176,6 +181,48 @@ 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 (nm_streq (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)) + missing_nap_bridge = TRUE; + } 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; + } + } + + /* errors form here are normalizable. */ + + if (!priv->type) { + /* as determined above, we can detect the bluetooth type. */ + nm_assert (!missing_nap_bridge); + 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_TYPE); + return NM_SETTING_VERIFY_NORMALIZABLE; + } + + if (missing_nap_bridge) { + 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; + } + return TRUE; } |