[PATCH] iface-modem-3gpp: add SubscriptionState property

Thieu Le thieule at chromium.org
Wed Oct 2 14:14:03 PDT 2013


Added libmm-glib methods, updated mmcli and simple status and added gtk-doc documentation.

---
 cli/mmcli-modem-simple.c                           |  15 ++-
 cli/mmcli-modem.c                                  |   3 +
 docs/reference/libmm-glib/libmm-glib-sections.txt  |   9 ++
 docs/reference/libmm-glib/libmm-glib.types         |   1 +
 include/ModemManager-enums.h                       |  17 +++
 ...g.freedesktop.ModemManager1.Modem.Modem3gpp.xml |  12 ++
 libmm-glib/mm-modem-3gpp.c                         |  19 +++
 libmm-glib/mm-modem-3gpp.h                         |   1 +
 libmm-glib/mm-simple-status.c                      |  45 +++++++
 libmm-glib/mm-simple-status.h                      |   2 +
 src/mm-broadband-modem.c                           |   4 +-
 src/mm-iface-modem-3gpp.c                          | 148 ++++++++++++++++-----
 src/mm-iface-modem-3gpp.h                          |  28 ++--
 13 files changed, 255 insertions(+), 49 deletions(-)

diff --git a/cli/mmcli-modem-simple.c b/cli/mmcli-modem-simple.c
index 22976a9..7b99792 100644
--- a/cli/mmcli-modem-simple.c
+++ b/cli/mmcli-modem-simple.c
@@ -251,13 +251,16 @@ status_process_reply (MMSimpleStatus *result,
             (mm_simple_status_get_3gpp_registration_state (result) ==
              MM_MODEM_3GPP_REGISTRATION_STATE_ROAMING)) {
             g_print ("  -------------------------\n"
-                     " 3GPP    |   registration: '%s'\n"
+                     "  3GPP   |   registration: '%s'\n"
                      "         |  operator code: '%s'\n"
-                     "         |  operator name: '%s'\n",
+                     "         |  operator name: '%s'\n"
+                     "         |   subscription: '%s'\n",
                      mm_modem_3gpp_registration_state_get_string (
                          mm_simple_status_get_3gpp_registration_state (result)),
                      VALIDATE_UNKNOWN (mm_simple_status_get_3gpp_operator_code (result)),
-                     VALIDATE_UNKNOWN (mm_simple_status_get_3gpp_operator_name (result)));
+                     VALIDATE_UNKNOWN (mm_simple_status_get_3gpp_operator_name (result)),
+                     mm_modem_3gpp_subscription_state_get_string (
+                         mm_simple_status_get_3gpp_subscription_state (result)));
         }
 
         if ((mm_simple_status_get_cdma_cdma1x_registration_state (result) !=
@@ -296,8 +299,14 @@ status_process_reply (MMSimpleStatus *result,
 
         g_free (access_tech_str);
         g_free (bands_str);
+    } else {
+        g_print ("  -------------------------\n"
+                 "  3GPP   |   subscription: '%s'\n",
+                 mm_modem_3gpp_subscription_state_get_string (
+                     mm_simple_status_get_3gpp_subscription_state (result)));
     }
 
+
     g_print ("\n");
     g_object_unref (result);
 }
diff --git a/cli/mmcli-modem.c b/cli/mmcli-modem.c
index 18e7356..dbec796 100644
--- a/cli/mmcli-modem.c
+++ b/cli/mmcli-modem.c
@@ -441,11 +441,14 @@ print_modem_info (void)
                  "           |  enabled locks: '%s'\n"
                  "           |    operator id: '%s'\n"
                  "           |  operator name: '%s'\n"
+                 "           |   subscription: '%s'\n"
                  "           |   registration: '%s'\n",
                  VALIDATE_UNKNOWN (mm_modem_3gpp_get_imei (ctx->modem_3gpp)),
                  facility_locks,
                  VALIDATE_UNKNOWN (mm_modem_3gpp_get_operator_code (ctx->modem_3gpp)),
                  VALIDATE_UNKNOWN (mm_modem_3gpp_get_operator_name (ctx->modem_3gpp)),
+                 mm_modem_3gpp_subscription_state_get_string (
+                     mm_modem_3gpp_get_subscription_state ((ctx->modem_3gpp))),
                  mm_modem_3gpp_registration_state_get_string (
                      mm_modem_3gpp_get_registration_state ((ctx->modem_3gpp))));
 
diff --git a/docs/reference/libmm-glib/libmm-glib-sections.txt b/docs/reference/libmm-glib/libmm-glib-sections.txt
index 8bbe534..302f42c 100644
--- a/docs/reference/libmm-glib/libmm-glib-sections.txt
+++ b/docs/reference/libmm-glib/libmm-glib-sections.txt
@@ -235,6 +235,7 @@ mm_modem_3gpp_get_operator_name
 mm_modem_3gpp_dup_operator_name
 mm_modem_3gpp_get_enabled_facility_locks
 mm_modem_3gpp_get_registration_state
+mm_modem_3gpp_get_subscription_state
 <SUBSECTION Methods>
 mm_modem_3gpp_register
 mm_modem_3gpp_register_finish
@@ -772,6 +773,7 @@ mm_simple_status_get_current_bands
 mm_simple_status_get_3gpp_registration_state
 mm_simple_status_get_3gpp_operator_code
 mm_simple_status_get_3gpp_operator_name
+mm_simple_status_get_3gpp_subscription_state
 mm_simple_status_get_cdma_cdma1x_registration_state
 mm_simple_status_get_cdma_evdo_registration_state
 mm_simple_status_get_cdma_nid
@@ -780,6 +782,7 @@ mm_simple_status_get_cdma_sid
 MM_SIMPLE_PROPERTY_3GPP_OPERATOR_CODE
 MM_SIMPLE_PROPERTY_3GPP_OPERATOR_NAME
 MM_SIMPLE_PROPERTY_3GPP_REGISTRATION_STATE
+MM_SIMPLE_PROPERTY_3GPP_SUBSCRIPTION_STATE
 MM_SIMPLE_PROPERTY_ACCESS_TECHNOLOGIES
 MM_SIMPLE_PROPERTY_CURRENT_BANDS
 MM_SIMPLE_PROPERTY_CDMA_CDMA1X_REGISTRATION_STATE
@@ -1132,6 +1135,7 @@ mm_modem_mode_build_string_from_mask
 mm_modem_band_get_string
 mm_modem_port_type_get_string
 mm_modem_3gpp_registration_state_get_string
+mm_modem_3gpp_subscription_state_get_string
 mm_modem_3gpp_facility_build_string_from_mask
 mm_modem_3gpp_network_availability_get_string
 mm_modem_3gpp_ussd_session_state_get_string
@@ -1174,6 +1178,7 @@ mm_modem_cdma_registration_state_build_string_from_mask
 mm_modem_cdma_activation_state_build_string_from_mask
 mm_modem_cdma_rm_protocol_build_string_from_mask
 mm_modem_3gpp_registration_state_build_string_from_mask
+mm_modem_3gpp_subscription_state_build_string_from_mask
 mm_modem_3gpp_facility_get_string
 mm_modem_3gpp_network_availability_build_string_from_mask
 mm_modem_3gpp_ussd_session_state_build_string_from_mask
@@ -1191,6 +1196,7 @@ MM_TYPE_FIRMWARE_IMAGE_TYPE
 MM_TYPE_MODEM_3GPP_FACILITY
 MM_TYPE_MODEM_3GPP_NETWORK_AVAILABILITY
 MM_TYPE_MODEM_3GPP_REGISTRATION_STATE
+MM_TYPE_MODEM_3GPP_SUBSCRIPTION_STATE
 MM_TYPE_MODEM_3GPP_USSD_SESSION_STATE
 MM_TYPE_MODEM_ACCESS_TECHNOLOGY
 MM_TYPE_MODEM_BAND
@@ -1223,6 +1229,7 @@ mm_firmware_image_type_get_type
 mm_modem_3gpp_facility_get_type
 mm_modem_3gpp_network_availability_get_type
 mm_modem_3gpp_registration_state_get_type
+mm_modem_3gpp_subscription_state_get_type
 mm_modem_3gpp_ussd_session_state_get_type
 mm_modem_access_technology_get_type
 mm_modem_band_get_type
@@ -1445,6 +1452,7 @@ mm_gdbus_modem3gpp_dup_operator_code
 mm_gdbus_modem3gpp_get_operator_name
 mm_gdbus_modem3gpp_dup_operator_name
 mm_gdbus_modem3gpp_get_enabled_facility_locks
+mm_gdbus_modem3gpp_get_subscription_state
 <SUBSECTION Methods>
 mm_gdbus_modem3gpp_call_register
 mm_gdbus_modem3gpp_call_register_finish
@@ -1462,6 +1470,7 @@ mm_gdbus_modem3gpp_set_imei
 mm_gdbus_modem3gpp_set_operator_code
 mm_gdbus_modem3gpp_set_operator_name
 mm_gdbus_modem3gpp_set_registration_state
+mm_gdbus_modem3gpp_set_subscription_state
 <SUBSECTION Standard>
 MM_GDBUS_IS_MODEM3GPP
 MM_GDBUS_MODEM3GPP
diff --git a/docs/reference/libmm-glib/libmm-glib.types b/docs/reference/libmm-glib/libmm-glib.types
index e59a414..1996156 100644
--- a/docs/reference/libmm-glib/libmm-glib.types
+++ b/docs/reference/libmm-glib/libmm-glib.types
@@ -71,6 +71,7 @@ mm_modem_3gpp_facility_get_type
 mm_modem_3gpp_get_type
 mm_modem_3gpp_network_availability_get_type
 mm_modem_3gpp_registration_state_get_type
+mm_modem_3gpp_subscription_state_get_type
 mm_modem_3gpp_ussd_get_type
 mm_modem_3gpp_ussd_session_state_get_type
 mm_modem_access_technology_get_type
diff --git a/include/ModemManager-enums.h b/include/ModemManager-enums.h
index 8fb0b08..a71b82e 100644
--- a/include/ModemManager-enums.h
+++ b/include/ModemManager-enums.h
@@ -772,6 +772,23 @@ typedef enum { /*< underscore_name=mm_modem_3gpp_network_availability >*/
 } MMModem3gppNetworkAvailability;
 
 /**
+ * MModem3gppSubscriptionState:
+ * @MM_MODEM_3GPP_SUBSCRIPTION_STATE_UNKNOWN: The subscription state is unknown.
+ * @MM_MODEM_3GPP_SUBSCRIPTION_STATE_UNPROVISIONED: The account is unprovisioned.
+ * @MM_MODEM_3GPP_SUBSCRIPTION_STATE_PROVISIONED: The account is provisioned and has data available.
+ * @MM_MODEM_3GPP_SUBSCRIPTION_STATE_OUT_OF_DATA: The account is provisioned but there is no data left.
+ *
+ * Describes the current subscription status of the SIM.  This value is only available after the
+ * modem attempts to register with the network.
+ */
+typedef enum { /*< underscore_name=mm_modem_3gpp_subscription_state >*/
+    MM_MODEM_3GPP_SUBSCRIPTION_STATE_UNKNOWN       = 0,
+    MM_MODEM_3GPP_SUBSCRIPTION_STATE_UNPROVISIONED = 1,
+    MM_MODEM_3GPP_SUBSCRIPTION_STATE_PROVISIONED   = 2,
+    MM_MODEM_3GPP_SUBSCRIPTION_STATE_OUT_OF_DATA   = 3,
+} MMModem3gppSubscriptionState;
+
+/**
  * MMModem3gppUssdSessionState:
  * @MM_MODEM_3GPP_USSD_SESSION_STATE_UNKNOWN: Unknown state.
  * @MM_MODEM_3GPP_USSD_SESSION_STATE_IDLE: No active session.
diff --git a/introspection/org.freedesktop.ModemManager1.Modem.Modem3gpp.xml b/introspection/org.freedesktop.ModemManager1.Modem.Modem3gpp.xml
index 3298473..ebf00ed 100644
--- a/introspection/org.freedesktop.ModemManager1.Modem.Modem3gpp.xml
+++ b/introspection/org.freedesktop.ModemManager1.Modem.Modem3gpp.xml
@@ -136,5 +136,17 @@
     -->
     <property name="EnabledFacilityLocks" type="u" access="read" />
 
+    <!--
+        SubscriptionState:
+
+        Indicates the activation status of the SIM and whether there is any
+        data remaining.  Possible values are:
+            0 - Unknown
+            1 - Account is unprovisioned
+            2 - Account is provisioned with data available
+            3 - Account is provisioned but data exhausted
+    -->
+    <property name="SubscriptionState" type="u" access="read" />
+
   </interface>
 </node>
diff --git a/libmm-glib/mm-modem-3gpp.c b/libmm-glib/mm-modem-3gpp.c
index c0a98bb..a926acc 100644
--- a/libmm-glib/mm-modem-3gpp.c
+++ b/libmm-glib/mm-modem-3gpp.c
@@ -246,6 +246,25 @@ mm_modem_3gpp_get_registration_state (MMModem3gpp *self)
 /*****************************************************************************/
 
 /**
+ * mm_modem_3gpp_get_subscription_state:
+ * @self: A #MMModem.
+ *
+ * Get the current subscription status of the account. This value is only
+ * available after the modem attempts to register with the network.
+ *
+ * Returns: A #MMModem3gppSubscriptionState value, specifying the current subscription state.
+ */
+MMModem3gppSubscriptionState
+mm_modem_3gpp_get_subscription_state (MMModem3gpp *self)
+{
+    g_return_val_if_fail (MM_IS_MODEM_3GPP (self), MM_MODEM_3GPP_SUBSCRIPTION_STATE_UNKNOWN);
+
+    return mm_gdbus_modem3gpp_get_subscription_state (MM_GDBUS_MODEM3GPP (self));
+}
+
+/*****************************************************************************/
+
+/**
  * mm_modem_3gpp_get_enabled_facility_locks:
  * @self: A #MMModem3gpp.
  *
diff --git a/libmm-glib/mm-modem-3gpp.h b/libmm-glib/mm-modem-3gpp.h
index bb055dc..7cfe011 100644
--- a/libmm-glib/mm-modem-3gpp.h
+++ b/libmm-glib/mm-modem-3gpp.h
@@ -76,6 +76,7 @@ const gchar *mm_modem_3gpp_get_operator_name (MMModem3gpp *self);
 gchar       *mm_modem_3gpp_dup_operator_name (MMModem3gpp *self);
 
 MMModem3gppRegistrationState  mm_modem_3gpp_get_registration_state     (MMModem3gpp *self);
+MMModem3gppSubscriptionState  mm_modem_3gpp_get_subscription_state     (MMModem3gpp *self);
 
 MMModem3gppFacility           mm_modem_3gpp_get_enabled_facility_locks (MMModem3gpp *self);
 
diff --git a/libmm-glib/mm-simple-status.c b/libmm-glib/mm-simple-status.c
index 10dfee3..9be9573 100644
--- a/libmm-glib/mm-simple-status.c
+++ b/libmm-glib/mm-simple-status.c
@@ -44,6 +44,7 @@ enum {
     PROP_3GPP_REGISTRATION_STATE,
     PROP_3GPP_OPERATOR_CODE,
     PROP_3GPP_OPERATOR_NAME,
+    PROP_3GPP_SUBSCRIPTION_STATE,
     PROP_CDMA_CDMA1X_REGISTRATION_STATE,
     PROP_CDMA_EVDO_REGISTRATION_STATE,
     PROP_CDMA_SID,
@@ -72,6 +73,8 @@ struct _MMSimpleStatusPrivate {
     gchar *modem_3gpp_operator_code;
     /* 3GPP operator name, given only when registered, signature 's' */
     gchar *modem_3gpp_operator_name;
+    /* 3GPP subsctiption state, signature 'u' */
+    MMModem3gppSubscriptionState modem_3gpp_subscription_state;
 
     /* <--- From the Modem CDMA interface ---> */
     /* CDMA/CDMA1x registration state, signature 'u' */
@@ -233,6 +236,25 @@ mm_simple_status_get_3gpp_operator_name (MMSimpleStatus *self)
 /*****************************************************************************/
 
 /**
+ * mm_simple_status_get_3gpp_subscription_state:
+ * @self: a #MMSimpleStatus.
+ *
+ * Gets the current subscription status of the account.
+ *
+ * Returns: a #MMModem3gppSubscriptionState.
+ */
+MMModem3gppSubscriptionState
+mm_simple_status_get_3gpp_subscription_state (MMSimpleStatus *self)
+{
+    g_return_val_if_fail (MM_IS_SIMPLE_STATUS (self), MM_MODEM_3GPP_SUBSCRIPTION_STATE_UNKNOWN);
+
+    return self->priv->modem_3gpp_subscription_state;
+}
+
+
+/*****************************************************************************/
+
+/**
  * mm_simple_status_get_cdma_cdma1x_registration_state:
  * @self: a #MMSimpleStatus.
  *
@@ -375,6 +397,12 @@ mm_simple_status_get_dictionary (MMSimpleStatus *self)
 
     }
 
+    if (self->priv->modem_3gpp_subscription_state)
+        g_variant_builder_add (&builder,
+                               "{sv}",
+                               MM_SIMPLE_PROPERTY_3GPP_SUBSCRIPTION_STATE,
+                               g_variant_new_uint32 (self->priv->modem_3gpp_subscription_state));
+
     return g_variant_ref_sink (g_variant_builder_end (&builder));
 }
 
@@ -414,6 +442,7 @@ mm_simple_status_new_from_dictionary (GVariant *dictionary,
         if (g_str_equal (key, MM_SIMPLE_PROPERTY_STATE) ||
             g_str_equal (key, MM_SIMPLE_PROPERTY_ACCESS_TECHNOLOGIES) ||
             g_str_equal (key, MM_SIMPLE_PROPERTY_3GPP_REGISTRATION_STATE) ||
+            g_str_equal (key, MM_SIMPLE_PROPERTY_3GPP_SUBSCRIPTION_STATE) ||
             g_str_equal (key, MM_SIMPLE_PROPERTY_CDMA_CDMA1X_REGISTRATION_STATE) ||
             g_str_equal (key, MM_SIMPLE_PROPERTY_CDMA_EVDO_REGISTRATION_STATE) ||
             g_str_equal (key, MM_SIMPLE_PROPERTY_CDMA_SID) ||
@@ -505,6 +534,9 @@ set_property (GObject *object,
         g_free (self->priv->modem_3gpp_operator_name);
         self->priv->modem_3gpp_operator_name = g_value_dup_string (value);
         break;
+    case PROP_3GPP_SUBSCRIPTION_STATE:
+        self->priv->modem_3gpp_subscription_state = g_value_get_enum (value);
+        break;
     case PROP_CDMA_CDMA1X_REGISTRATION_STATE:
         self->priv->modem_cdma_cdma1x_registration_state = g_value_get_enum (value);
         break;
@@ -553,6 +585,9 @@ get_property (GObject *object,
     case PROP_3GPP_OPERATOR_NAME:
         g_value_set_string (value, self->priv->modem_3gpp_operator_name);
         break;
+    case PROP_3GPP_SUBSCRIPTION_STATE:
+        g_value_set_enum (value, self->priv->modem_3gpp_subscription_state);
+        break;
     case PROP_CDMA_CDMA1X_REGISTRATION_STATE:
         g_value_set_enum (value, self->priv->modem_cdma_cdma1x_registration_state);
         break;
@@ -582,6 +617,7 @@ mm_simple_status_init (MMSimpleStatus *self)
     self->priv->state = MM_MODEM_STATE_UNKNOWN;
     self->priv->access_technologies = MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN;
     self->priv->modem_3gpp_registration_state = MM_MODEM_3GPP_REGISTRATION_STATE_UNKNOWN;
+    self->priv->modem_3gpp_subscription_state = MM_MODEM_3GPP_SUBSCRIPTION_STATE_UNKNOWN;
     self->priv->current_bands = g_variant_ref_sink (mm_common_build_bands_unknown ());
     self->priv->signal_quality = g_variant_ref_sink (g_variant_new ("(ub)", 0, 0));
     self->priv->modem_cdma_cdma1x_registration_state = MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN;
@@ -678,6 +714,15 @@ mm_simple_status_class_init (MMSimpleStatusClass *klass)
                              G_PARAM_READWRITE);
     g_object_class_install_property (object_class, PROP_3GPP_OPERATOR_NAME, properties[PROP_3GPP_OPERATOR_NAME]);
 
+    properties[PROP_3GPP_SUBSCRIPTION_STATE] =
+        g_param_spec_enum (MM_SIMPLE_PROPERTY_3GPP_SUBSCRIPTION_STATE,
+                           "3GPP subscription state",
+                           "Subscription state of the account",
+                           MM_TYPE_MODEM_3GPP_SUBSCRIPTION_STATE,
+                           MM_MODEM_3GPP_SUBSCRIPTION_STATE_UNKNOWN,
+                           G_PARAM_READWRITE);
+    g_object_class_install_property (object_class, PROP_3GPP_SUBSCRIPTION_STATE, properties[PROP_3GPP_SUBSCRIPTION_STATE]);
+
     properties[PROP_CDMA_CDMA1X_REGISTRATION_STATE] =
         g_param_spec_enum (MM_SIMPLE_PROPERTY_CDMA_CDMA1X_REGISTRATION_STATE,
                            "CDMA1x registration state",
diff --git a/libmm-glib/mm-simple-status.h b/libmm-glib/mm-simple-status.h
index 8292fdb..cbf93bc 100644
--- a/libmm-glib/mm-simple-status.h
+++ b/libmm-glib/mm-simple-status.h
@@ -67,6 +67,7 @@ MMModemAccessTechnology       mm_simple_status_get_access_technologies (MMSimple
 MMModem3gppRegistrationState  mm_simple_status_get_3gpp_registration_state (MMSimpleStatus *self);
 const gchar                  *mm_simple_status_get_3gpp_operator_code      (MMSimpleStatus *self);
 const gchar                  *mm_simple_status_get_3gpp_operator_name      (MMSimpleStatus *self);
+MMModem3gppSubscriptionState  mm_simple_status_get_3gpp_subscription_state (MMSimpleStatus *self);
 
 MMModemCdmaRegistrationState mm_simple_status_get_cdma_cdma1x_registration_state (MMSimpleStatus *self);
 MMModemCdmaRegistrationState mm_simple_status_get_cdma_evdo_registration_state   (MMSimpleStatus *self);
@@ -88,6 +89,7 @@ guint                        mm_simple_status_get_cdma_nid
 #define MM_SIMPLE_PROPERTY_3GPP_REGISTRATION_STATE "m3gpp-registration-state"
 #define MM_SIMPLE_PROPERTY_3GPP_OPERATOR_CODE      "m3gpp-operator-code"
 #define MM_SIMPLE_PROPERTY_3GPP_OPERATOR_NAME      "m3gpp-operator-name"
+#define MM_SIMPLE_PROPERTY_3GPP_SUBSCRIPTION_STATE "m3gpp-subscription-state"
 
 #define MM_SIMPLE_PROPERTY_CDMA_CDMA1X_REGISTRATION_STATE "cdma-cdma1x-registration-state"
 #define MM_SIMPLE_PROPERTY_CDMA_EVDO_REGISTRATION_STATE   "cdma-evdo-registration-state"
diff --git a/src/mm-broadband-modem.c b/src/mm-broadband-modem.c
index 1657b11..edac4cb 100644
--- a/src/mm-broadband-modem.c
+++ b/src/mm-broadband-modem.c
@@ -7412,10 +7412,10 @@ enable_location_gathering (MMIfaceModemLocation *self,
         mm_iface_modem_is_3gpp (MM_IFACE_MODEM (self))) {
         /* Reload registration to get LAC/CI */
         mm_iface_modem_3gpp_run_registration_checks (MM_IFACE_MODEM_3GPP (self), NULL, NULL);
-        /* Reload operator to get MCC/MNC */
+        /* Reload registration information to get MCC/MNC */
         if (MM_BROADBAND_MODEM (self)->priv->modem_3gpp_registration_state == MM_MODEM_3GPP_REGISTRATION_STATE_HOME ||
             MM_BROADBAND_MODEM (self)->priv->modem_3gpp_registration_state == MM_MODEM_3GPP_REGISTRATION_STATE_ROAMING)
-            mm_iface_modem_3gpp_reload_current_operator (MM_IFACE_MODEM_3GPP (self), NULL, NULL);
+            mm_iface_modem_3gpp_reload_current_registration_info (MM_IFACE_MODEM_3GPP (self), NULL, NULL);
     }
 
     /* Done we are */
diff --git a/src/mm-iface-modem-3gpp.c b/src/mm-iface-modem-3gpp.c
index 53399d5..196d0ef 100644
--- a/src/mm-iface-modem-3gpp.c
+++ b/src/mm-iface-modem-3gpp.c
@@ -64,6 +64,10 @@ mm_iface_modem_3gpp_bind_simple_status (MMIfaceModem3gpp *self,
                             status, MM_SIMPLE_PROPERTY_3GPP_OPERATOR_NAME,
                             G_BINDING_DEFAULT | G_BINDING_SYNC_CREATE);
 
+    g_object_bind_property (skeleton, "subscription-state",
+                            status, MM_SIMPLE_PROPERTY_3GPP_SUBSCRIPTION_STATE,
+                            G_BINDING_DEFAULT | G_BINDING_SYNC_CREATE);
+
     g_object_unref (skeleton);
 }
 
@@ -75,7 +79,7 @@ typedef struct {
     MMModem3gppRegistrationState eps;
     gboolean manual_registration;
     GCancellable *pending_registration_cancellable;
-    gboolean reloading_operator;
+    gboolean reloading_registration_info;
 } RegistrationStateContext;
 
 static void
@@ -760,33 +764,34 @@ typedef struct {
     GSimpleAsyncResult *result;
     gboolean operator_code_loaded;
     gboolean operator_name_loaded;
-} ReloadCurrentOperatorContext;
+    gboolean subscription_state_loaded;
+} ReloadCurrentRegistrationInfoContext;
 
 static void
-reload_current_operator_context_complete_and_free (ReloadCurrentOperatorContext *ctx)
+reload_current_registration_info_context_complete_and_free (ReloadCurrentRegistrationInfoContext *ctx)
 {
     g_simple_async_result_complete_in_idle (ctx->result);
     g_object_unref (ctx->result);
     if (ctx->skeleton)
         g_object_unref (ctx->skeleton);
     g_object_unref (ctx->self);
-    g_slice_free (ReloadCurrentOperatorContext, ctx);
+    g_slice_free (ReloadCurrentRegistrationInfoContext, ctx);
 }
 
 gboolean
-mm_iface_modem_3gpp_reload_current_operator_finish (MMIfaceModem3gpp *self,
-                                                    GAsyncResult *res,
-                                                    GError **error)
+mm_iface_modem_3gpp_reload_current_registration_info_finish (MMIfaceModem3gpp *self,
+                                                             GAsyncResult *res,
+                                                             GError **error)
 {
     return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error);
 }
 
-static void reload_current_operator_context_step (ReloadCurrentOperatorContext *ctx);
+static void reload_current_registration_info_context_step (ReloadCurrentRegistrationInfoContext *ctx);
 
 static void
 load_operator_name_ready (MMIfaceModem3gpp *self,
                           GAsyncResult *res,
-                          ReloadCurrentOperatorContext *ctx)
+                          ReloadCurrentRegistrationInfoContext *ctx)
 {
     GError *error = NULL;
     gchar *str;
@@ -802,7 +807,7 @@ load_operator_name_ready (MMIfaceModem3gpp *self,
     g_free (str);
 
     ctx->operator_name_loaded = TRUE;
-    reload_current_operator_context_step (ctx);
+    reload_current_registration_info_context_step (ctx);
 }
 
 static gboolean
@@ -836,7 +841,7 @@ parse_mcc_mnc (const gchar *mccmnc,
 static void
 load_operator_code_ready (MMIfaceModem3gpp *self,
                           GAsyncResult *res,
-                          ReloadCurrentOperatorContext *ctx)
+                          ReloadCurrentRegistrationInfoContext *ctx)
 {
     GError *error = NULL;
     gchar *str;
@@ -861,11 +866,33 @@ load_operator_code_ready (MMIfaceModem3gpp *self,
     g_free (str);
 
     ctx->operator_code_loaded = TRUE;
-    reload_current_operator_context_step (ctx);
+    reload_current_registration_info_context_step (ctx);
+}
+
+static void
+load_subscription_state_ready (MMIfaceModem3gpp *self,
+                               GAsyncResult *res,
+                               ReloadCurrentRegistrationInfoContext *ctx)
+{
+    GError *error = NULL;
+    MMModem3gppSubscriptionState subscription_state = MM_MODEM_3GPP_SUBSCRIPTION_STATE_UNKNOWN;
+
+    subscription_state = MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->load_subscription_state_finish (self, res, &error);
+    if (error) {
+        mm_warn ("Couldn't load Subscription State: '%s'", error->message);
+        g_error_free (error);
+    }
+
+    if (ctx->skeleton)
+        mm_gdbus_modem3gpp_set_subscription_state (ctx->skeleton, subscription_state);
+
+    ctx->subscription_state_loaded = TRUE;
+    reload_current_registration_info_context_step (ctx);
 }
 
+
 static void
-reload_current_operator_context_step (ReloadCurrentOperatorContext *ctx)
+reload_current_registration_info_context_step (ReloadCurrentRegistrationInfoContext *ctx)
 {
     if (!ctx->operator_code_loaded) {
         /* Launch operator code update */
@@ -885,24 +912,33 @@ reload_current_operator_context_step (ReloadCurrentOperatorContext *ctx)
         return;
     }
 
-    /* If both loaded, all done */
+    if (!ctx->subscription_state_loaded) {
+        /* Launch subscription state update */
+        MM_IFACE_MODEM_3GPP_GET_INTERFACE (ctx->self)->load_subscription_state (
+            ctx->self,
+            (GAsyncReadyCallback)load_subscription_state_ready,
+            ctx);
+        return;
+    }
+
+    /* If all are loaded, all done */
     g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE);
-    reload_current_operator_context_complete_and_free (ctx);
+    reload_current_registration_info_context_complete_and_free (ctx);
 }
 
 void
-mm_iface_modem_3gpp_reload_current_operator (MMIfaceModem3gpp *self,
-                                             GAsyncReadyCallback callback,
-                                             gpointer user_data)
+mm_iface_modem_3gpp_reload_current_registration_info (MMIfaceModem3gpp *self,
+                                                      GAsyncReadyCallback callback,
+                                                      gpointer user_data)
 {
-    ReloadCurrentOperatorContext *ctx;
+    ReloadCurrentRegistrationInfoContext *ctx;
 
-    ctx = g_slice_new0 (ReloadCurrentOperatorContext);
+    ctx = g_slice_new0 (ReloadCurrentRegistrationInfoContext);
     ctx->self = g_object_ref (self);
     ctx->result = g_simple_async_result_new (G_OBJECT (self),
                                              callback,
                                              user_data,
-                                             mm_iface_modem_3gpp_reload_current_operator);
+                                             mm_iface_modem_3gpp_reload_current_registration_info);
 
     g_object_get (self,
                   MM_IFACE_MODEM_3GPP_DBUS_SKELETON, &ctx->skeleton,
@@ -912,7 +948,7 @@ mm_iface_modem_3gpp_reload_current_operator (MMIfaceModem3gpp *self,
                                          MM_CORE_ERROR,
                                          MM_CORE_ERROR_FAILED,
                                          "Couldn't get interface skeleton");
-        reload_current_operator_context_complete_and_free (ctx);
+        reload_current_registration_info_context_complete_and_free (ctx);
         return;
     }
 
@@ -929,7 +965,12 @@ mm_iface_modem_3gpp_reload_current_operator (MMIfaceModem3gpp *self,
     if (ctx->operator_name_loaded)
         mm_gdbus_modem3gpp_set_operator_name (ctx->skeleton, NULL);
 
-    reload_current_operator_context_step (ctx);
+    ctx->subscription_state_loaded = !(MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->load_subscription_state &&
+                                       MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->load_subscription_state_finish);
+    if (ctx->subscription_state_loaded)
+      mm_gdbus_modem3gpp_set_subscription_state (ctx->skeleton, MM_MODEM_3GPP_SUBSCRIPTION_STATE_UNKNOWN);
+
+    reload_current_registration_info_context_step (ctx);
 }
 
 void
@@ -949,6 +990,19 @@ mm_iface_modem_3gpp_clear_current_operator (MMIfaceModem3gpp *self)
         mm_iface_modem_location_3gpp_update_mcc_mnc (MM_IFACE_MODEM_LOCATION (self), 0, 0);
 }
 
+static void
+clear_subscription_state (MMIfaceModem3gpp *self)
+{
+    MmGdbusModem3gpp *skeleton = NULL;
+
+    g_object_get (self,
+                  MM_IFACE_MODEM_3GPP_DBUS_SKELETON, &skeleton,
+                  NULL);
+    if (!skeleton)
+        return;
+    mm_gdbus_modem3gpp_set_subscription_state (skeleton, MM_MODEM_3GPP_SUBSCRIPTION_STATE_UNKNOWN);
+}
+
 /*****************************************************************************/
 
 void
@@ -969,7 +1023,7 @@ mm_iface_modem_3gpp_update_access_technologies (MMIfaceModem3gpp *self,
      * but only if something valid to report */
     if (state == MM_MODEM_3GPP_REGISTRATION_STATE_HOME ||
         state == MM_MODEM_3GPP_REGISTRATION_STATE_ROAMING ||
-        ctx->reloading_operator) {
+        ctx->reloading_registration_info) {
         if (access_tech != MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN)
             mm_iface_modem_update_access_technologies (MM_IFACE_MODEM (self),
                                                        access_tech,
@@ -1009,9 +1063,9 @@ mm_iface_modem_3gpp_update_location (MMIfaceModem3gpp *self,
 /*****************************************************************************/
 
 static void
-update_registration_reload_current_operator_ready (MMIfaceModem3gpp *self,
-                                                   GAsyncResult *res,
-                                                   gpointer user_data)
+update_registration_reload_current_registration_info_ready (MMIfaceModem3gpp *self,
+                                                            GAsyncResult *res,
+                                                            gpointer user_data)
 {
     MMModem3gppRegistrationState new_state;
     RegistrationStateContext *ctx;
@@ -1034,7 +1088,7 @@ update_registration_reload_current_operator_ready (MMIfaceModem3gpp *self,
                                            MM_MODEM_STATE_CHANGE_REASON_UNKNOWN);
 
     ctx = get_registration_state_context (self);
-    ctx->reloading_operator = FALSE;
+    ctx->reloading_registration_info = FALSE;
 }
 
 static void
@@ -1045,6 +1099,14 @@ update_non_registered_state (MMIfaceModem3gpp *self,
     /* Not registered neither in home nor roaming network */
     mm_iface_modem_3gpp_clear_current_operator (self);
 
+    /* The subscription state can be computed in two ways: a) via PCO which is
+     * sent by the carrier during registration or b) by looking at the
+     * registration reject error code.  If b), we want to make sure we
+     * preserve the subscription state */
+    if (old_state == MM_MODEM_3GPP_REGISTRATION_STATE_HOME ||
+        old_state == MM_MODEM_3GPP_REGISTRATION_STATE_ROAMING)
+        clear_subscription_state (self);
+
     /* The property in the interface is bound to the property
      * in the skeleton, so just updating here is enough */
     g_object_set (self,
@@ -1081,20 +1143,20 @@ update_registration_state (MMIfaceModem3gpp *self,
 
     if (new_state == MM_MODEM_3GPP_REGISTRATION_STATE_HOME ||
         new_state == MM_MODEM_3GPP_REGISTRATION_STATE_ROAMING) {
-        /* If already reloading operator, skip it */
-        if (ctx->reloading_operator)
+        /* If already reloading registration info, skip it */
+        if (ctx->reloading_registration_info)
             return;
 
         mm_info ("Modem %s: 3GPP Registration state changed (%s -> registering)",
                  g_dbus_object_get_object_path (G_DBUS_OBJECT (self)),
                  mm_modem_3gpp_registration_state_get_string (old_state));
 
-        /* Reload current operator. ONLY update the state to REGISTERED after
-         * having loaded operator code/name */
-        ctx->reloading_operator = TRUE;
-        mm_iface_modem_3gpp_reload_current_operator (
+        /* Reload current registration info. ONLY update the state to REGISTERED
+         * after having loaded operator code/name/subscription state */
+        ctx->reloading_registration_info = TRUE;
+        mm_iface_modem_3gpp_reload_current_registration_info (
             self,
-            (GAsyncReadyCallback)update_registration_reload_current_operator_ready,
+            (GAsyncReadyCallback)update_registration_reload_current_registration_info_ready,
             GUINT_TO_POINTER (new_state));
         return;
     }
@@ -1164,6 +1226,21 @@ mm_iface_modem_3gpp_update_eps_registration_state (MMIfaceModem3gpp *self,
     update_registration_state (self, get_consolidated_reg_state (ctx), TRUE);
 }
 
+void
+mm_iface_modem_3gpp_update_subscription_state (MMIfaceModem3gpp *self,
+                                               MMModem3gppSubscriptionState state)
+{
+    MmGdbusModem3gpp *skeleton = NULL;
+
+    g_object_get (self,
+                  MM_IFACE_MODEM_3GPP_DBUS_SKELETON, &skeleton,
+                  NULL);
+    if (skeleton) {
+        mm_gdbus_modem3gpp_set_subscription_state (skeleton, state);
+        g_object_unref (skeleton);
+    }
+}
+
 /*****************************************************************************/
 
 typedef struct {
@@ -1954,6 +2031,7 @@ mm_iface_modem_3gpp_initialize (MMIfaceModem3gpp *self,
         mm_gdbus_modem3gpp_set_operator_code (skeleton, NULL);
         mm_gdbus_modem3gpp_set_operator_name (skeleton, NULL);
         mm_gdbus_modem3gpp_set_enabled_facility_locks (skeleton, MM_MODEM_3GPP_FACILITY_NONE);
+        mm_gdbus_modem3gpp_set_subscription_state (skeleton, MM_MODEM_3GPP_SUBSCRIPTION_STATE_UNKNOWN);
 
         /* Bind our RegistrationState property */
         g_object_bind_property (self, MM_IFACE_MODEM_3GPP_REGISTRATION_STATE,
diff --git a/src/mm-iface-modem-3gpp.h b/src/mm-iface-modem-3gpp.h
index f4014c4..8497d20 100644
--- a/src/mm-iface-modem-3gpp.h
+++ b/src/mm-iface-modem-3gpp.h
@@ -176,6 +176,14 @@ struct _MMIfaceModem3gpp {
                                           GAsyncResult *res,
                                           GError **error);
 
+    /* Loading of the subscription state property */
+    void (*load_subscription_state) (MMIfaceModem3gpp *self,
+                                     GAsyncReadyCallback callback,
+                                     gpointer user_data);
+    MMModem3gppSubscriptionState (*load_subscription_state_finish) (MMIfaceModem3gpp *self,
+                                                                    GAsyncResult *res,
+                                                                    GError **error);
+
     /* Scan current networks, expect a GList of MMModem3gppNetworkInfo */
     void (* scan_networks) (MMIfaceModem3gpp *self,
                             GAsyncReadyCallback callback,
@@ -216,7 +224,7 @@ gboolean mm_iface_modem_3gpp_disable_finish (MMIfaceModem3gpp *self,
 /* Shutdown Modem 3GPP interface */
 void mm_iface_modem_3gpp_shutdown (MMIfaceModem3gpp *self);
 
-/* Objects implementing this interface can report new registration states,
+/* Objects implementing this interface can report new registration info,
  * access technologies and location.
  * This may happen when handling unsolicited registration messages, or when
  * the interface asks to run registration state checks. */
@@ -226,6 +234,8 @@ void mm_iface_modem_3gpp_update_ps_registration_state (MMIfaceModem3gpp *self,
                                                        MMModem3gppRegistrationState state);
 void mm_iface_modem_3gpp_update_eps_registration_state (MMIfaceModem3gpp *self,
                                                         MMModem3gppRegistrationState state);
+void mm_iface_modem_3gpp_update_subscription_state (MMIfaceModem3gpp *self,
+                                                    MMModem3gppSubscriptionState state);
 void mm_iface_modem_3gpp_update_access_technologies (MMIfaceModem3gpp *self,
                                                      MMModemAccessTechnology access_tech);
 void mm_iface_modem_3gpp_update_location            (MMIfaceModem3gpp *self,
@@ -240,14 +250,14 @@ gboolean mm_iface_modem_3gpp_run_registration_checks_finish (MMIfaceModem3gpp *s
                                                              GAsyncResult *res,
                                                              GError **error);
 
-/* Request to reload current operator */
-void     mm_iface_modem_3gpp_reload_current_operator        (MMIfaceModem3gpp *self,
-                                                             GAsyncReadyCallback callback,
-                                                             gpointer user_data);
-gboolean mm_iface_modem_3gpp_reload_current_operator_finish (MMIfaceModem3gpp *self,
-                                                             GAsyncResult *res,
-                                                             GError **error);
-void     mm_iface_modem_3gpp_clear_current_operator         (MMIfaceModem3gpp *self);
+/* Request to reload current registration information */
+void     mm_iface_modem_3gpp_reload_current_registration_info        (MMIfaceModem3gpp *self,
+                                                                      GAsyncReadyCallback callback,
+                                                                      gpointer user_data);
+gboolean mm_iface_modem_3gpp_reload_current_registration_info_finish (MMIfaceModem3gpp *self,
+                                                                      GAsyncResult *res,
+                                                                      GError **error);
+void     mm_iface_modem_3gpp_clear_current_operator                  (MMIfaceModem3gpp *self);
 
 /* Allow registering in the network */
 gboolean mm_iface_modem_3gpp_register_in_network_finish (MMIfaceModem3gpp *self,
-- 
1.7.12.4



More information about the ModemManager-devel mailing list