aboutsummaryrefslogtreecommitdiff
path: root/src/mm-iface-modem-3gpp.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mm-iface-modem-3gpp.c')
-rw-r--r--src/mm-iface-modem-3gpp.c148
1 files changed, 113 insertions, 35 deletions
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,