diff options
author | Thieu Le <thieule@chromium.org> | 2013-10-07 13:57:27 -0700 |
---|---|---|
committer | Aleksander Morgado <aleksander@lanedo.com> | 2013-10-09 09:59:42 +0200 |
commit | f9a4f87d5204432b52cb41b31809d43425467da5 (patch) | |
tree | b8ae31d2b84d80e376e80942ae7ca7f116dccece | |
parent | 564b3610fd6e4060bc36c2cf568b2305aaf6ea19 (diff) |
iface-modem-3gpp: add SubscriptionState property
-rw-r--r-- | cli/mmcli-modem-simple.c | 15 | ||||
-rw-r--r-- | cli/mmcli-modem.c | 3 | ||||
-rw-r--r-- | docs/reference/libmm-glib/libmm-glib-sections.txt | 9 | ||||
-rw-r--r-- | docs/reference/libmm-glib/libmm-glib.types | 1 | ||||
-rw-r--r-- | include/ModemManager-enums.h | 17 | ||||
-rw-r--r-- | introspection/org.freedesktop.ModemManager1.Modem.Modem3gpp.xml | 9 | ||||
-rw-r--r-- | libmm-glib/mm-modem-3gpp.c | 19 | ||||
-rw-r--r-- | libmm-glib/mm-modem-3gpp.h | 1 | ||||
-rw-r--r-- | libmm-glib/mm-simple-status.c | 45 | ||||
-rw-r--r-- | libmm-glib/mm-simple-status.h | 2 | ||||
-rw-r--r-- | src/mm-broadband-modem.c | 4 | ||||
-rw-r--r-- | src/mm-iface-modem-3gpp.c | 148 | ||||
-rw-r--r-- | src/mm-iface-modem-3gpp.h | 28 |
13 files changed, 252 insertions, 49 deletions
diff --git a/cli/mmcli-modem-simple.c b/cli/mmcli-modem-simple.c index 22976a97..7b997926 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 18e7356f..dbec796f 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 8bbe534a..302f42c8 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 e59a414a..19961564 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 8fb0b088..a71b82eb 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 3298473c..00c4a2e8 100644 --- a/introspection/org.freedesktop.ModemManager1.Modem.Modem3gpp.xml +++ b/introspection/org.freedesktop.ModemManager1.Modem.Modem3gpp.xml @@ -136,5 +136,14 @@ --> <property name="EnabledFacilityLocks" type="u" access="read" /> + <!-- + SubscriptionState: + + A <link linkend="MMModem3gppSubscriptionState">MMModem3gppSubscriptionState</link> + value representing the subscription status of the account and whether there + is any data remaining, given as an unsigned integer (signature <literal>"u"</literal>). + --> + <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 c0a98bb1..a926acc1 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 bb055dcd..7cfe0115 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 10dfee32..9be9573b 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 8292fdb3..cbf93bcf 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 1657b118..edac4cb3 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 53399d53..051b750d 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 f4014c40..8497d200 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, |