libnm/wwan: add GSM setting device-id, sim-id, and sim-operator-id properties
authorDan Williams <dcbw@redhat.com>
Thu, 1 Oct 2015 17:44:28 +0000 (12:44 -0500)
committerThomas Haller <thaller@redhat.com>
Wed, 18 Nov 2015 14:50:52 +0000 (15:50 +0100)
These properties limit whether the connection applies to a certain WWAN modem
based on the modem's device ID or SIM ID (as reported by the WWAN management
service), or through the MCC/MNC ID of the operator that issued the SIM card.

libnm-core/nm-setting-gsm.c
libnm-core/nm-setting-gsm.h
libnm-core/tests/test-general.c
libnm/libnm.ver
src/devices/wwan/nm-device-modem.c
src/devices/wwan/nm-modem-broadband.c
src/devices/wwan/nm-modem.c
src/devices/wwan/nm-modem.h
src/settings/plugins/keyfile/tests/keyfiles/ATT_Data_Connect_Plain
src/settings/plugins/keyfile/tests/test-keyfile.c

index 4d5d7d4..f5e60e7 100644 (file)
@@ -50,6 +50,11 @@ typedef struct {
        char *password;
        NMSettingSecretFlags password_flags;
 
+       /* Restrict connection to certain devices or SIMs */
+       char *device_id;
+       char *sim_id;
+       char *sim_operator_id;
+
        char *apn; /* NULL for dynamic */
        char *network_id; /* for manual registration or NULL for automatic */
 
@@ -70,6 +75,9 @@ enum {
        PROP_PIN,
        PROP_PIN_FLAGS,
        PROP_HOME_ONLY,
+       PROP_DEVICE_ID,
+       PROP_SIM_ID,
+       PROP_SIM_OPERATOR_ID,
 
        LAST_PROP
 };
@@ -213,6 +221,54 @@ nm_setting_gsm_get_home_only (NMSettingGsm *setting)
        return NM_SETTING_GSM_GET_PRIVATE (setting)->home_only;
 }
 
+/**
+ * nm_setting_gsm_get_device_id:
+ * @setting: the #NMSettingGsm
+ *
+ * Returns: the #NMSettingGsm:device-id property of the setting
+ *
+ * Since: 1.2
+ **/
+const char *
+nm_setting_gsm_get_device_id (NMSettingGsm *setting)
+{
+       g_return_val_if_fail (NM_IS_SETTING_GSM (setting), NULL);
+
+       return NM_SETTING_GSM_GET_PRIVATE (setting)->device_id;
+}
+
+/**
+ * nm_setting_gsm_get_sim_id:
+ * @setting: the #NMSettingGsm
+ *
+ * Returns: the #NMSettingGsm:sim-id property of the setting
+ *
+ * Since: 1.2
+ **/
+const char *
+nm_setting_gsm_get_sim_id (NMSettingGsm *setting)
+{
+       g_return_val_if_fail (NM_IS_SETTING_GSM (setting), NULL);
+
+       return NM_SETTING_GSM_GET_PRIVATE (setting)->sim_id;
+}
+
+/**
+ * nm_setting_gsm_get_sim_operator_id:
+ * @setting: the #NMSettingGsm
+ *
+ * Returns: the #NMSettingGsm:sim-operator-id property of the setting
+ *
+ * Since: 1.2
+ **/
+const char *
+nm_setting_gsm_get_sim_operator_id (NMSettingGsm *setting)
+{
+       g_return_val_if_fail (NM_IS_SETTING_GSM (setting), NULL);
+
+       return NM_SETTING_GSM_GET_PRIVATE (setting)->sim_operator_id;
+}
+
 static gboolean
 verify (NMSetting *setting, NMConnection *connection, GError **error)
 {
@@ -312,6 +368,49 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
                }
        }
 
+       if (priv->device_id && !priv->device_id[0]) {
+               g_set_error_literal (error,
+                                    NM_CONNECTION_ERROR,
+                                    NM_CONNECTION_ERROR_INVALID_PROPERTY,
+                                    _("property is empty"));
+               g_prefix_error (error, "%s.%s: ", NM_SETTING_GSM_SETTING_NAME, NM_SETTING_GSM_DEVICE_ID);
+               return FALSE;
+       }
+
+       if (priv->sim_id && !priv->sim_id[0]) {
+               g_set_error_literal (error,
+                                    NM_CONNECTION_ERROR,
+                                    NM_CONNECTION_ERROR_INVALID_PROPERTY,
+                                    _("property is empty"));
+               g_prefix_error (error, "%s.%s: ", NM_SETTING_GSM_SETTING_NAME, NM_SETTING_GSM_SIM_ID);
+               return FALSE;
+       }
+
+       if (priv->sim_operator_id) {
+               size_t len = strlen (priv->sim_operator_id);
+               const char *p = priv->sim_operator_id;
+
+               if (len == 0 || (len != 5 && len != 6)) {
+                       g_set_error_literal (error,
+                                            NM_CONNECTION_ERROR,
+                                            NM_CONNECTION_ERROR_INVALID_PROPERTY,
+                                            _("property is empty or wrong size"));
+                       g_prefix_error (error, "%s.%s: ", NM_SETTING_GSM_SETTING_NAME, NM_SETTING_GSM_SIM_OPERATOR_ID);
+                       return FALSE;
+               }
+
+               while (p && *p) {
+                       if (!g_ascii_isdigit (*p++)) {
+                               g_set_error_literal (error,
+                                                    NM_CONNECTION_ERROR,
+                                                    NM_CONNECTION_ERROR_INVALID_PROPERTY,
+                                                    _("property must contain only digits"));
+                               g_prefix_error (error, "%s.%s: ", NM_SETTING_GSM_SETTING_NAME, NM_SETTING_GSM_SIM_OPERATOR_ID);
+                               return FALSE;
+                       }
+               }
+       }
+
        return TRUE;
 }
 
@@ -401,6 +500,18 @@ set_property (GObject *object, guint prop_id,
        case PROP_HOME_ONLY:
                priv->home_only = g_value_get_boolean (value);
                break;
+       case PROP_DEVICE_ID:
+               g_free (priv->device_id);
+               priv->device_id = g_value_dup_string (value);
+               break;
+       case PROP_SIM_ID:
+               g_free (priv->sim_id);
+               priv->sim_id = g_value_dup_string (value);
+               break;
+       case PROP_SIM_OPERATOR_ID:
+               g_free (priv->sim_operator_id);
+               priv->sim_operator_id = g_value_dup_string (value);
+               break;
        default:
                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
                break;
@@ -441,6 +552,15 @@ get_property (GObject *object, guint prop_id,
        case PROP_HOME_ONLY:
                g_value_set_boolean (value, nm_setting_gsm_get_home_only (setting));
                break;
+       case PROP_DEVICE_ID:
+               g_value_set_string (value, nm_setting_gsm_get_device_id (setting));
+               break;
+       case PROP_SIM_ID:
+               g_value_set_string (value, nm_setting_gsm_get_sim_id (setting));
+               break;
+       case PROP_SIM_OPERATOR_ID:
+               g_value_set_string (value, nm_setting_gsm_get_sim_operator_id (setting));
+               break;
        default:
                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
                break;
@@ -596,6 +716,57 @@ nm_setting_gsm_class_init (NMSettingGsmClass *setting_class)
                                       G_PARAM_READWRITE |
                                       G_PARAM_STATIC_STRINGS));
 
+       /**
+        * NMSettingGsm:device-id:
+        *
+        * The device unique identifier (as given by the WWAN management service)
+        * which this connection applies to.  If given, the connection will only
+        * apply to the specified device.
+        *
+        * Since: 1.2
+        **/
+       g_object_class_install_property
+               (object_class, PROP_DEVICE_ID,
+                g_param_spec_string (NM_SETTING_GSM_DEVICE_ID, "", "",
+                                     NULL,
+                                     G_PARAM_READWRITE |
+                                     G_PARAM_STATIC_STRINGS));
+
+       /**
+        * NMSettingGsm:sim-id:
+        *
+        * The SIM card unique identifier (as given by the WWAN management service)
+        * which this connection applies to.  If given, the connection will apply
+        * to any device also allowed by #NMSettingGsm:device-id which contains a
+        * SIM card matching the given identifier.
+        *
+        * Since: 1.2
+        **/
+       g_object_class_install_property
+               (object_class, PROP_SIM_ID,
+                g_param_spec_string (NM_SETTING_GSM_SIM_ID, "", "",
+                                     NULL,
+                                     G_PARAM_READWRITE |
+                                     G_PARAM_STATIC_STRINGS));
+
+       /**
+        * NMSettingGsm:sim-operator-id:
+        *
+        * A MCC/MNC string like "310260" or "21601" identifying the specific
+        * mobile network operator which this connection applies to.  If given,
+        * the connection will apply to any device also allowed by
+        * #NMSettingGsm:device-id and #NMSettingGsm:sim-id which contains a SIM
+        * card provisioined by the given operator.
+        *
+        * Since: 1.2
+        **/
+       g_object_class_install_property
+               (object_class, PROP_SIM_OPERATOR_ID,
+                g_param_spec_string (NM_SETTING_GSM_SIM_OPERATOR_ID, "", "",
+                                     NULL,
+                                     G_PARAM_READWRITE |
+                                     G_PARAM_STATIC_STRINGS));
+
        /* Ignore incoming deprecated properties */
        _nm_setting_class_add_dbus_only_property (parent_class, "allowed-bands",
                                                  G_VARIANT_TYPE_UINT32,
index 9075673..2dfe73f 100644 (file)
@@ -40,15 +40,18 @@ G_BEGIN_DECLS
 
 #define NM_SETTING_GSM_SETTING_NAME "gsm"
 
-#define NM_SETTING_GSM_NUMBER         "number"
-#define NM_SETTING_GSM_USERNAME       "username"
-#define NM_SETTING_GSM_PASSWORD       "password"
-#define NM_SETTING_GSM_PASSWORD_FLAGS "password-flags"
-#define NM_SETTING_GSM_APN            "apn"
-#define NM_SETTING_GSM_NETWORK_ID     "network-id"
-#define NM_SETTING_GSM_PIN            "pin"
-#define NM_SETTING_GSM_PIN_FLAGS      "pin-flags"
-#define NM_SETTING_GSM_HOME_ONLY      "home-only"
+#define NM_SETTING_GSM_NUMBER          "number"
+#define NM_SETTING_GSM_USERNAME        "username"
+#define NM_SETTING_GSM_PASSWORD        "password"
+#define NM_SETTING_GSM_PASSWORD_FLAGS  "password-flags"
+#define NM_SETTING_GSM_APN             "apn"
+#define NM_SETTING_GSM_NETWORK_ID      "network-id"
+#define NM_SETTING_GSM_PIN             "pin"
+#define NM_SETTING_GSM_PIN_FLAGS       "pin-flags"
+#define NM_SETTING_GSM_HOME_ONLY       "home-only"
+#define NM_SETTING_GSM_DEVICE_ID       "device-id"
+#define NM_SETTING_GSM_SIM_ID          "sim-id"
+#define NM_SETTING_GSM_SIM_OPERATOR_ID "sim-operator-id"
 
 struct _NMSettingGsm {
        NMSetting parent;
@@ -63,14 +66,21 @@ typedef struct {
 
 GType nm_setting_gsm_get_type (void);
 
-NMSetting *nm_setting_gsm_new                (void);
-const char *nm_setting_gsm_get_number        (NMSettingGsm *setting);
-const char *nm_setting_gsm_get_username      (NMSettingGsm *setting);
-const char *nm_setting_gsm_get_password      (NMSettingGsm *setting);
-const char *nm_setting_gsm_get_apn           (NMSettingGsm *setting);
-const char *nm_setting_gsm_get_network_id    (NMSettingGsm *setting);
-const char *nm_setting_gsm_get_pin           (NMSettingGsm *setting);
-gboolean    nm_setting_gsm_get_home_only     (NMSettingGsm *setting);
+NMSetting *nm_setting_gsm_new                  (void);
+const char *nm_setting_gsm_get_number          (NMSettingGsm *setting);
+const char *nm_setting_gsm_get_username        (NMSettingGsm *setting);
+const char *nm_setting_gsm_get_password        (NMSettingGsm *setting);
+const char *nm_setting_gsm_get_apn             (NMSettingGsm *setting);
+const char *nm_setting_gsm_get_network_id      (NMSettingGsm *setting);
+const char *nm_setting_gsm_get_pin             (NMSettingGsm *setting);
+gboolean    nm_setting_gsm_get_home_only       (NMSettingGsm *setting);
+
+NM_AVAILABLE_IN_1_2
+const char *nm_setting_gsm_get_device_id       (NMSettingGsm *setting);
+NM_AVAILABLE_IN_1_2
+const char *nm_setting_gsm_get_sim_id          (NMSettingGsm *setting);
+NM_AVAILABLE_IN_1_2
+const char *nm_setting_gsm_get_sim_operator_id (NMSettingGsm *setting);
 
 NMSettingSecretFlags nm_setting_gsm_get_pin_flags      (NMSettingGsm *setting);
 NMSettingSecretFlags nm_setting_gsm_get_password_flags (NMSettingGsm *setting);
index 5d95f26..2111e59 100644 (file)
@@ -756,6 +756,35 @@ test_setting_gsm_without_number (void)
                                           NM_CONNECTION_ERROR_INVALID_PROPERTY);
 }
 
+static void
+test_setting_gsm_sim_operator_id (void)
+{
+       gs_unref_object NMSettingGsm *s_gsm = NULL;
+
+       s_gsm = (NMSettingGsm *) nm_setting_gsm_new ();
+       g_assert (s_gsm);
+
+       /* Valid */
+       g_object_set (s_gsm, NM_SETTING_GSM_SIM_OPERATOR_ID, "12345", NULL);
+       nmtst_assert_setting_verifies (NM_SETTING (s_gsm));
+
+       g_object_set (s_gsm, NM_SETTING_GSM_SIM_OPERATOR_ID, "123456", NULL);
+       nmtst_assert_setting_verifies (NM_SETTING (s_gsm));
+
+       /* Invalid */
+       g_object_set (s_gsm, NM_SETTING_GSM_SIM_OPERATOR_ID, "", NULL);
+       nmtst_assert_setting_verify_fails (NM_SETTING (s_gsm), NM_CONNECTION_ERROR,
+                                          NM_CONNECTION_ERROR_INVALID_PROPERTY);
+
+       g_object_set (s_gsm, NM_SETTING_GSM_SIM_OPERATOR_ID, "     ", NULL);
+       nmtst_assert_setting_verify_fails (NM_SETTING (s_gsm), NM_CONNECTION_ERROR,
+                                          NM_CONNECTION_ERROR_INVALID_PROPERTY);
+
+       g_object_set (s_gsm, NM_SETTING_GSM_SIM_OPERATOR_ID, "abcdef", NULL);
+       nmtst_assert_setting_verify_fails (NM_SETTING (s_gsm), NM_CONNECTION_ERROR,
+                                          NM_CONNECTION_ERROR_INVALID_PROPERTY);
+}
+
 static NMSettingWirelessSecurity *
 make_test_wsec_setting (const char *detail)
 {
@@ -4861,6 +4890,7 @@ int main (int argc, char **argv)
        g_test_add_func ("/core/general/test_setting_gsm_apn_bad_chars", test_setting_gsm_apn_bad_chars);
        g_test_add_func ("/core/general/test_setting_gsm_apn_underscore", test_setting_gsm_apn_underscore);
        g_test_add_func ("/core/general/test_setting_gsm_without_number", test_setting_gsm_without_number);
+       g_test_add_func ("/core/general/test_setting_gsm_sim_operator_id", test_setting_gsm_sim_operator_id);
        g_test_add_func ("/core/general/test_setting_to_dbus_all", test_setting_to_dbus_all);
        g_test_add_func ("/core/general/test_setting_to_dbus_no_secrets", test_setting_to_dbus_no_secrets);
        g_test_add_func ("/core/general/test_setting_to_dbus_only_secrets", test_setting_to_dbus_only_secrets);
index eff17b3..0a73b27 100644 (file)
@@ -881,6 +881,9 @@ global:
        nm_setting_connection_get_lldp;
        nm_setting_connection_get_metered;
        nm_setting_connection_lldp_get_type;
+       nm_setting_gsm_get_device_id;
+       nm_setting_gsm_get_sim_id;
+       nm_setting_gsm_get_sim_operator_id;
        nm_setting_ip4_config_get_dhcp_timeout;
        nm_setting_ip6_config_addr_gen_mode_get_type;
        nm_setting_ip6_config_get_addr_gen_mode;
index 3a85d58..04d8690 100644 (file)
@@ -253,6 +253,12 @@ data_port_changed_cb (NMModem *modem, GParamSpec *pspec, gpointer user_data)
                nm_device_ipv6_sysctl_set (self, "disable_ipv6", "1");
 }
 
+static void
+ids_changed_cb (NMModem *modem, GParamSpec *pspec, gpointer user_data)
+{
+       nm_device_recheck_available_connections (NM_DEVICE (user_data));
+}
+
 static void
 modem_state_cb (NMModem *modem,
                 NMModemState new_state,
@@ -677,6 +683,10 @@ set_modem (NMDeviceModem *self, NMModem *modem)
         * while in the new ModemManager the data port is set afterwards when the bearer gets
         * created */
        g_signal_connect (modem, "notify::" NM_MODEM_DATA_PORT, G_CALLBACK (data_port_changed_cb), self);
+
+       g_signal_connect (modem, "notify::" NM_MODEM_DEVICE_ID, G_CALLBACK (ids_changed_cb), self);
+       g_signal_connect (modem, "notify::" NM_MODEM_SIM_ID, G_CALLBACK (ids_changed_cb), self);
+       g_signal_connect (modem, "notify::" NM_MODEM_SIM_OPERATOR_ID, G_CALLBACK (ids_changed_cb), self);
 }
 
 static void
index 2236559..51e3965 100644 (file)
@@ -1126,6 +1126,7 @@ get_sim_ready (MMModem *modem,
        if (new_sim) {
                g_object_set (G_OBJECT (self),
                              NM_MODEM_SIM_ID, mm_sim_get_identifier (new_sim),
+                             NM_MODEM_SIM_OPERATOR_ID, mm_sim_get_operator_identifier (new_sim),
                              NULL);
                g_object_unref (new_sim);
        } else {
@@ -1150,7 +1151,10 @@ sim_changed (MMModem *modem, GParamSpec *pspec, gpointer user_data)
                                  (GAsyncReadyCallback) get_sim_ready,
                                  g_object_ref (self));
        } else
-               g_object_set (G_OBJECT (self), NM_MODEM_SIM_ID, NULL, NULL);
+               g_object_set (G_OBJECT (self),
+                             NM_MODEM_SIM_ID, NULL,
+                             NM_MODEM_SIM_OPERATOR_ID, NULL,
+                             NULL);
 }
 
 static void
index 5889aa7..86a0281 100644 (file)
@@ -22,7 +22,9 @@
 #include "config.h"
 
 #include <string.h>
+
 #include "nm-modem.h"
+#include "nm-core-internal.h"
 #include "nm-platform.h"
 #include "nm-setting-connection.h"
 #include "nm-default.h"
@@ -50,6 +52,7 @@ enum {
        PROP_DEVICE_ID,
        PROP_SIM_ID,
        PROP_IP_TYPES,
+       PROP_SIM_OPERATOR_ID,
 
        LAST_PROP
 };
@@ -69,6 +72,7 @@ typedef struct {
        char *device_id;
        char *sim_id;
        NMModemIPType ip_types;
+       char *sim_operator_id;
 
        NMPPPManager *ppp_manager;
 
@@ -348,6 +352,24 @@ nm_modem_get_connection_ip_type (NMModem *self,
        return NULL;
 }
 
+const char *
+nm_modem_get_device_id (NMModem *self)
+{
+       return NM_MODEM_GET_PRIVATE (self)->device_id;
+}
+
+const char *
+nm_modem_get_sim_id (NMModem *self)
+{
+       return NM_MODEM_GET_PRIVATE (self)->sim_id;
+}
+
+const char *
+nm_modem_get_sim_operator_id (NMModem *self)
+{
+       return NM_MODEM_GET_PRIVATE (self)->sim_operator_id;
+}
+
 /*****************************************************************************/
 /* IP method PPP */
 
@@ -844,6 +866,67 @@ nm_modem_act_stage2_config (NMModem *self,
 gboolean
 nm_modem_check_connection_compatible (NMModem *self, NMConnection *connection)
 {
+       NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self);
+       NMSettingConnection *s_con;
+
+       s_con = nm_connection_get_setting_connection (connection);
+       g_assert (s_con);
+
+       if (g_str_equal (nm_setting_connection_get_connection_type (s_con),
+                        NM_SETTING_GSM_SETTING_NAME)) {
+               NMSettingGsm *s_gsm;
+               const char *str;
+
+               s_gsm = nm_connection_get_setting_gsm (connection);
+               if (!s_gsm)
+                       return FALSE;
+
+               str = nm_setting_gsm_get_device_id (s_gsm);
+               if (str) {
+                       if (!priv->device_id) {
+                               nm_log_dbg (LOGD_MB, "(%s): %s/%s has device-id, device does not",
+                                           priv->uid,
+                                           nm_connection_get_uuid (connection),
+                                           nm_connection_get_id (connection));
+                               return FALSE;
+                       }
+                       if (strcmp (str, priv->device_id)) {
+                               nm_log_dbg (LOGD_MB, "(%s): %s/%s device-id mismatch",
+                                           priv->uid,
+                                           nm_connection_get_uuid (connection),
+                                           nm_connection_get_id (connection));
+                               return FALSE;
+                       }
+               }
+
+               /* SIM properties may not be available before the SIM is unlocked, so
+                * to ensure that autoconnect works, the connection's SIM properties
+                * are only compared if present on the device.
+                */
+
+               str = nm_setting_gsm_get_sim_id (s_gsm);
+               if (str && priv->sim_id) {
+                       if (strcmp (str, priv->sim_id)) {
+                               nm_log_dbg (LOGD_MB, "(%s): %s/%s sim-id mismatch",
+                                           priv->uid,
+                                           nm_connection_get_uuid (connection),
+                                           nm_connection_get_id (connection));
+                               return FALSE;
+                       }
+               }
+
+               str = nm_setting_gsm_get_sim_operator_id (s_gsm);
+               if (str && priv->sim_operator_id) {
+                       if (strcmp (str, priv->sim_operator_id)) {
+                               nm_log_dbg (LOGD_MB, "(%s): %s/%s sim-operator-id mismatch",
+                                           priv->uid,
+                                           nm_connection_get_uuid (connection),
+                                           nm_connection_get_id (connection));
+                               return FALSE;
+                       }
+               }
+       }
+
        if (NM_MODEM_GET_CLASS (self)->check_connection_compatible)
                return NM_MODEM_GET_CLASS (self)->check_connection_compatible (self, connection);
        return FALSE;
@@ -1297,6 +1380,9 @@ get_property (GObject *object, guint prop_id,
        case PROP_IP_TYPES:
                g_value_set_uint (value, priv->ip_types);
                break;
+       case PROP_SIM_OPERATOR_ID:
+               g_value_set_string (value, priv->sim_operator_id);
+               break;
        default:
                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
                break;
@@ -1308,6 +1394,7 @@ set_property (GObject *object, guint prop_id,
               const GValue *value, GParamSpec *pspec)
 {
        NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (object);
+       const char *s;
 
        switch (prop_id) {
        case PROP_PATH:
@@ -1351,6 +1438,12 @@ set_property (GObject *object, guint prop_id,
        case PROP_IP_TYPES:
                priv->ip_types = g_value_get_uint (value);
                break;
+       case PROP_SIM_OPERATOR_ID:
+               g_clear_pointer (&priv->sim_operator_id, g_free);
+               s = g_value_get_string (value);
+               if (s && s[0])
+                       priv->sim_operator_id = g_strdup (s);
+               break;
        default:
                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
                break;
@@ -1382,6 +1475,7 @@ finalize (GObject *object)
        g_free (priv->data_port);
        g_free (priv->device_id);
        g_free (priv->sim_id);
+       g_free (priv->sim_operator_id);
 
        G_OBJECT_CLASS (nm_modem_parent_class)->finalize (object);
 }
@@ -1496,6 +1590,13 @@ nm_modem_class_init (NMModemClass *klass)
                                    0, G_MAXUINT32, NM_MODEM_IP_TYPE_IPV4,
                                    G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
 
+       g_object_class_install_property
+               (object_class, PROP_SIM_OPERATOR_ID,
+                g_param_spec_string (NM_MODEM_SIM_OPERATOR_ID, "", "",
+                                     NULL,
+                                     G_PARAM_READWRITE | G_PARAM_CONSTRUCT |
+                                     G_PARAM_STATIC_STRINGS));
+
        /* Signals */
 
        signals[PPP_STATS] =
index fffbeb3..60e5589 100644 (file)
@@ -36,18 +36,19 @@ G_BEGIN_DECLS
 #define NM_MODEM_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj),  NM_TYPE_MODEM, NMModemClass))
 
 /* Properties */
-#define NM_MODEM_UID          "uid"
-#define NM_MODEM_PATH         "path"
-#define NM_MODEM_DRIVER       "driver"
-#define NM_MODEM_CONTROL_PORT "control-port"
-#define NM_MODEM_DATA_PORT    "data-port"
-#define NM_MODEM_IP4_METHOD   "ip4-method"
-#define NM_MODEM_IP6_METHOD   "ip6-method"
-#define NM_MODEM_IP_TIMEOUT   "ip-timeout"
-#define NM_MODEM_STATE        "state"
-#define NM_MODEM_DEVICE_ID    "device-id"
-#define NM_MODEM_SIM_ID       "sim-id"
-#define NM_MODEM_IP_TYPES     "ip-types"   /* Supported IP types */
+#define NM_MODEM_UID             "uid"
+#define NM_MODEM_PATH            "path"
+#define NM_MODEM_DRIVER          "driver"
+#define NM_MODEM_CONTROL_PORT    "control-port"
+#define NM_MODEM_DATA_PORT       "data-port"
+#define NM_MODEM_IP4_METHOD      "ip4-method"
+#define NM_MODEM_IP6_METHOD      "ip6-method"
+#define NM_MODEM_IP_TIMEOUT      "ip-timeout"
+#define NM_MODEM_STATE           "state"
+#define NM_MODEM_DEVICE_ID       "device-id"
+#define NM_MODEM_SIM_ID          "sim-id"
+#define NM_MODEM_IP_TYPES        "ip-types"   /* Supported IP types */
+#define NM_MODEM_SIM_OPERATOR_ID "sim-operator-id"
 
 /* Signals */
 #define NM_MODEM_PPP_STATS         "ppp-stats"
@@ -179,12 +180,15 @@ typedef struct {
 
 GType nm_modem_get_type (void);
 
-const char *nm_modem_get_path         (NMModem *modem);
-const char *nm_modem_get_uid          (NMModem *modem);
-const char *nm_modem_get_control_port (NMModem *modem);
-const char *nm_modem_get_data_port    (NMModem *modem);
-const char *nm_modem_get_driver       (NMModem *modem);
-gboolean    nm_modem_get_iid          (NMModem *modem, NMUtilsIPv6IfaceId *out_iid);
+const char *nm_modem_get_path            (NMModem *modem);
+const char *nm_modem_get_uid             (NMModem *modem);
+const char *nm_modem_get_control_port    (NMModem *modem);
+const char *nm_modem_get_data_port       (NMModem *modem);
+const char *nm_modem_get_driver          (NMModem *modem);
+const char *nm_modem_get_device_id       (NMModem *modem);
+const char *nm_modem_get_sim_id          (NMModem *modem);
+const char *nm_modem_get_sim_operator_id (NMModem *modem);
+gboolean    nm_modem_get_iid             (NMModem *modem, NMUtilsIPv6IfaceId *out_iid);
 
 gboolean    nm_modem_owns_port        (NMModem *modem, const char *iface);
 
index 902b842..11e1ec6 100644 (file)
@@ -15,6 +15,9 @@ password=CINGULAR1
 apn=ISP.CINGULAR
 network-id=24005
 pin=2345
+device-id=da812de91eec16620b06cd0ca5cbc7ea25245222
+sim-id=89148000000060671234
+sim-operator-id=310260
 
 [serial]
 baud=115200
index ede40ee..250bad3 100644 (file)
@@ -1882,153 +1882,43 @@ test_read_gsm_connection (void)
        NMSettingConnection *s_con;
        NMSettingSerial *s_serial;
        NMSettingGsm *s_gsm;
-       NMSettingBluetooth *s_bluetooth;
        GError *error = NULL;
-       const char *tmp;
-       NMSettingSerialParity parity;
-       const char *expected_id = "AT&T Data Connect";
-       const char *expected_apn = "ISP.CINGULAR";
-       const char *expected_username = "ISP@CINGULARGPRS.COM";
-       const char *expected_password = "CINGULAR1";
-       const char *expected_network_id = "24005";
-       const char *expected_pin = "2345";
+       gboolean success;
 
-       connection = nm_keyfile_plugin_connection_from_file (TEST_GSM_FILE, NULL);
-       ASSERT (connection != NULL,
-                       "connection-read", "failed to read %s", TEST_GSM_FILE);
+       connection = nm_keyfile_plugin_connection_from_file (TEST_GSM_FILE, &error);
+       g_assert_no_error (error);
+       g_assert (connection);
 
-       ASSERT (nm_connection_verify (connection, &error),
-               "connection-verify", "failed to verify %s: %s", TEST_GSM_FILE, error->message);
+       success = nm_connection_verify (connection, &error);
+       g_assert_no_error (error);
+       g_assert (success);
 
        /* ===== CONNECTION SETTING ===== */
-
        s_con = nm_connection_get_setting_connection (connection);
-       ASSERT (s_con != NULL,
-               "connection-verify-connection", "failed to verify %s: missing %s setting",
-               TEST_GSM_FILE,
-               NM_SETTING_CONNECTION_SETTING_NAME);
-
-       /* ID */
-       tmp = nm_setting_connection_get_id (s_con);
-       ASSERT (tmp != NULL,
-               "connection-verify-connection", "failed to verify %s: missing %s / %s key",
-               TEST_GSM_FILE,
-               NM_SETTING_CONNECTION_SETTING_NAME,
-               NM_SETTING_CONNECTION_ID);
-       ASSERT (strcmp (tmp, expected_id) == 0,
-               "connection-verify-connection", "failed to verify %s: unexpected %s / %s key value",
-               TEST_GSM_FILE,
-               NM_SETTING_CONNECTION_SETTING_NAME,
-               NM_SETTING_CONNECTION_ID);
-
-       tmp = nm_setting_connection_get_connection_type (s_con);
-       ASSERT (tmp != NULL,
-               "connection-verify-connection", "failed to verify %s: missing %s / %s key",
-               TEST_GSM_FILE,
-               NM_SETTING_CONNECTION_SETTING_NAME,
-               NM_SETTING_CONNECTION_ID);
-       ASSERT (strcmp (tmp, NM_SETTING_GSM_SETTING_NAME) == 0,
-               "connection-verify-connection", "failed to verify %s: unexpected %s / %s key value",
-               TEST_GSM_FILE,
-               NM_SETTING_CONNECTION_SETTING_NAME,
-               NM_SETTING_CONNECTION_TYPE);
+       g_assert (s_con);
+       g_assert_cmpstr (nm_setting_connection_get_id (s_con), ==, "AT&T Data Connect");
+       g_assert_cmpstr (nm_setting_connection_get_connection_type (s_con), ==, NM_SETTING_GSM_SETTING_NAME);
 
        /* ===== BLUETOOTH SETTING ===== */
-
        /* Plain GSM, so no BT setting expected */
-       s_bluetooth = nm_connection_get_setting_bluetooth (connection);
-       ASSERT (s_bluetooth == NULL,
-               "connection-verify-bt", "unexpected %s setting",
-               TEST_GSM_FILE,
-               NM_SETTING_BLUETOOTH_SETTING_NAME);
+       g_assert (nm_connection_get_setting_bluetooth (connection) == NULL);
 
        /* ===== GSM SETTING ===== */
-
        s_gsm = nm_connection_get_setting_gsm (connection);
-       ASSERT (s_gsm != NULL,
-               "connection-verify-gsm", "failed to verify %s: missing %s setting",
-               TEST_GSM_FILE,
-               NM_SETTING_GSM_SETTING_NAME);
-
-       /* APN */
-       tmp = nm_setting_gsm_get_apn (s_gsm);
-       ASSERT (tmp != NULL,
-               "connection-verify-gsm", "failed to verify %s: missing %s / %s key",
-               TEST_GSM_FILE,
-               NM_SETTING_GSM_SETTING_NAME,
-               NM_SETTING_GSM_APN);
-       ASSERT (strcmp (tmp, expected_apn) == 0,
-               "connection-verify-gsm", "failed to verify %s: unexpected %s / %s key value",
-               TEST_GSM_FILE,
-               NM_SETTING_GSM_SETTING_NAME,
-               NM_SETTING_GSM_APN);
-
-       /* Username */
-       tmp = nm_setting_gsm_get_username (s_gsm);
-       ASSERT (tmp != NULL,
-               "connection-verify-gsm", "failed to verify %s: missing %s / %s key",
-               TEST_GSM_FILE,
-               NM_SETTING_GSM_SETTING_NAME,
-               NM_SETTING_GSM_USERNAME);
-       ASSERT (strcmp (tmp, expected_username) == 0,
-               "connection-verify-gsm", "failed to verify %s: unexpected %s / %s key value",
-               TEST_GSM_FILE,
-               NM_SETTING_GSM_SETTING_NAME,
-               NM_SETTING_GSM_USERNAME);
-
-       /* Password */
-       tmp = nm_setting_gsm_get_password (s_gsm);
-       ASSERT (tmp != NULL,
-               "connection-verify-gsm", "failed to verify %s: missing %s / %s key",
-               TEST_GSM_FILE,
-               NM_SETTING_GSM_SETTING_NAME,
-               NM_SETTING_GSM_PASSWORD);
-       ASSERT (strcmp (tmp, expected_password) == 0,
-               "connection-verify-gsm", "failed to verify %s: unexpected %s / %s key value",
-               TEST_GSM_FILE,
-               NM_SETTING_GSM_SETTING_NAME,
-               NM_SETTING_GSM_PASSWORD);
-
-       /* Network ID */
-       tmp = nm_setting_gsm_get_network_id (s_gsm);
-       ASSERT (tmp != NULL,
-               "connection-verify-gsm", "failed to verify %s: missing %s / %s key",
-               TEST_GSM_FILE,
-               NM_SETTING_GSM_SETTING_NAME,
-               NM_SETTING_GSM_NETWORK_ID);
-       ASSERT (strcmp (tmp, expected_network_id) == 0,
-               "connection-verify-gsm", "failed to verify %s: unexpected %s / %s key value",
-               TEST_GSM_FILE,
-               NM_SETTING_GSM_SETTING_NAME,
-               NM_SETTING_GSM_NETWORK_ID);
-
-       /* PIN */
-       tmp = nm_setting_gsm_get_pin (s_gsm);
-       ASSERT (tmp != NULL,
-               "connection-verify-gsm", "failed to verify %s: missing %s / %s key",
-               TEST_GSM_FILE,
-               NM_SETTING_GSM_SETTING_NAME,
-               NM_SETTING_GSM_PIN);
-       ASSERT (strcmp (tmp, expected_pin) == 0,
-               "connection-verify-gsm", "failed to verify %s: unexpected %s / %s key value",
-               TEST_GSM_FILE,
-               NM_SETTING_GSM_SETTING_NAME,
-               NM_SETTING_GSM_PIN);
+       g_assert (s_gsm);
+       g_assert_cmpstr (nm_setting_gsm_get_apn (s_gsm), ==, "ISP.CINGULAR");
+       g_assert_cmpstr (nm_setting_gsm_get_username (s_gsm), ==, "ISP@CINGULARGPRS.COM");
+       g_assert_cmpstr (nm_setting_gsm_get_password (s_gsm), ==, "CINGULAR1");
+       g_assert_cmpstr (nm_setting_gsm_get_network_id (s_gsm), ==, "24005");
+       g_assert_cmpstr (nm_setting_gsm_get_pin (s_gsm), ==, "2345");
+       g_assert_cmpstr (nm_setting_gsm_get_device_id (s_gsm), ==, "da812de91eec16620b06cd0ca5cbc7ea25245222");
+       g_assert_cmpstr (nm_setting_gsm_get_sim_id (s_gsm), ==, "89148000000060671234");
+       g_assert_cmpstr (nm_setting_gsm_get_sim_operator_id (s_gsm), ==, "310260");
 
        /* ===== SERIAL SETTING ===== */
-
        s_serial = nm_connection_get_setting_serial (connection);
-       ASSERT (s_serial != NULL,
-               "connection-verify-serial", "failed to verify %s: missing %s setting",
-               TEST_GSM_FILE,
-               NM_SETTING_SERIAL_SETTING_NAME);
-
-       parity = nm_setting_serial_get_parity (s_serial);
-       ASSERT (parity == NM_SETTING_SERIAL_PARITY_ODD,
-               "connection-verify-serial", "failed to verify %s: unexpected %s / %s key value",
-               TEST_GSM_FILE,
-               NM_SETTING_SERIAL_SETTING_NAME,
-               NM_SETTING_SERIAL_PARITY);
+       g_assert (s_serial);
+       g_assert_cmpint (nm_setting_serial_get_parity (s_serial), ==, NM_SETTING_SERIAL_PARITY_ODD);
 
        g_object_unref (connection);
 }
@@ -2087,22 +1977,23 @@ test_write_gsm_connection (void)
                      NM_SETTING_GSM_PIN, "123456",
                      NM_SETTING_GSM_NETWORK_ID, "254098",
                      NM_SETTING_GSM_HOME_ONLY, TRUE,
+                     NM_SETTING_GSM_DEVICE_ID, "da812de91eec16620b06cd0ca5cbc7ea25245222",
+                     NM_SETTING_GSM_SIM_ID, "89148000000060671234",
+                     NM_SETTING_GSM_SIM_OPERATOR_ID, "310260",
                      NULL);
 
        /* Write out the connection */
        owner_uid = geteuid ();
        owner_grp = getegid ();
        success = nm_keyfile_plugin_write_test_connection (connection, TEST_SCRATCH_DIR, owner_uid, owner_grp, &testfile, &error);
-       ASSERT (success == TRUE,
-                       "connection-write", "failed to write keyfile: %s",
-                       error ? error->message : "(none)");
-
-       ASSERT (testfile != NULL,
-                       "connection-write", "didn't get keyfile name back after writing connection");
+       g_assert_no_error (error);
+       g_assert (success);
+       g_assert (testfile != NULL);
 
        /* Read the connection back in and compare it to the one we just wrote out */
-       reread = nm_keyfile_plugin_connection_from_file (testfile, NULL);
-       ASSERT (reread != NULL, "connection-write", "failed to re-read test connection");
+       reread = nm_keyfile_plugin_connection_from_file (testfile, &error);
+       g_assert_no_error (error);
+       g_assert (reread);
 
        nmtst_assert_connection_equals (connection, TRUE, reread, FALSE);