aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mm-broadband-modem.c108
-rw-r--r--src/mm-iface-modem-3gpp.c88
-rw-r--r--src/mm-iface-modem-3gpp.h12
3 files changed, 133 insertions, 75 deletions
diff --git a/src/mm-broadband-modem.c b/src/mm-broadband-modem.c
index 244aed09..9e5b5528 100644
--- a/src/mm-broadband-modem.c
+++ b/src/mm-broadband-modem.c
@@ -91,8 +91,6 @@ struct _MMBroadbandModemPrivate {
/* 3GPP registration helpers */
GPtrArray *reg_regex;
- MMModem3gppRegistrationState reg_cs;
- MMModem3gppRegistrationState reg_ps;
gboolean manual_reg;
GCancellable *pending_reg_cancellable;
};
@@ -100,8 +98,6 @@ struct _MMBroadbandModemPrivate {
/*****************************************************************************/
/* CREATE BEARER */
-static MMModem3gppRegistrationState get_consolidated_reg_state (MMBroadbandModem *self);
-
static MMBearer *
modem_create_bearer_finish (MMIfaceModem *self,
GAsyncResult *res,
@@ -170,8 +166,6 @@ modem_create_bearer (MMIfaceModem *self,
/*****************************************************************************/
/* CREATE SIM */
-static MMModem3gppRegistrationState get_consolidated_reg_state (MMBroadbandModem *self);
-
static MMSim *
modem_create_sim_finish (MMIfaceModem *self,
GAsyncResult *res,
@@ -1823,34 +1817,6 @@ load_operator_name (MMIfaceModem3gpp *self,
/*****************************************************************************/
/* Unsolicited registration messages handling (3GPP) */
-/* static void clear_previous_registration_request (MMBroadbandModem *self, */
-/* gboolean complete_with_cancel); */
-
-static MMModem3gppRegistrationState
-get_consolidated_reg_state (MMBroadbandModem *self)
-{
- /* Some devices (Blackberries for example) will respond to +CGREG, but
- * return ERROR for +CREG, probably because their firmware is just stupid.
- * So here we prefer the +CREG response, but if we never got a successful
- * +CREG response, we'll take +CGREG instead.
- */
- if (self->priv->reg_cs == MM_MODEM_3GPP_REGISTRATION_STATE_HOME ||
- self->priv->reg_cs == MM_MODEM_3GPP_REGISTRATION_STATE_ROAMING)
- return self->priv->reg_cs;
-
- if (self->priv->reg_ps == MM_MODEM_3GPP_REGISTRATION_STATE_HOME ||
- self->priv->reg_ps == MM_MODEM_3GPP_REGISTRATION_STATE_ROAMING)
- return self->priv->reg_ps;
-
- if (self->priv->reg_cs == MM_MODEM_3GPP_REGISTRATION_STATE_SEARCHING)
- return self->priv->reg_cs;
-
- if (self->priv->reg_ps == MM_MODEM_3GPP_REGISTRATION_STATE_SEARCHING)
- return self->priv->reg_ps;
-
- return self->priv->reg_cs;
-}
-
static gboolean
setup_unsolicited_registration_finish (MMIfaceModem3gpp *self,
GAsyncResult *res,
@@ -1883,16 +1849,15 @@ reg_state_changed (MMAtSerialPort *port,
return;
}
+ /* Report new registration state */
if (cgreg)
- self->priv->reg_ps = state;
+ mm_iface_modem_3gpp_update_ps_registration_state (MM_IFACE_MODEM_3GPP (self),
+ state,
+ act);
else
- self->priv->reg_cs = state;
-
- /* Report new registration state */
- state = get_consolidated_reg_state (self);
- mm_iface_modem_3gpp_update_registration_state (MM_IFACE_MODEM_3GPP (self),
- state,
- act);
+ mm_iface_modem_3gpp_update_cs_registration_state (MM_IFACE_MODEM_3GPP (self),
+ state,
+ act);
/* TODO: report LAC/CI location */
/* update_lac_ci (self, lac, cell_id, cgreg ? 1 : 0); */
@@ -2104,9 +2069,12 @@ run_all_registration_checks_ready (MMBroadbandModem *self,
if (error) {
mm_dbg ("Registration check failed: '%s'", error->message);
- mm_iface_modem_3gpp_update_registration_state (MM_IFACE_MODEM_3GPP (self),
- MM_MODEM_3GPP_REGISTRATION_STATE_IDLE,
- MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN);
+ mm_iface_modem_3gpp_update_ps_registration_state (MM_IFACE_MODEM_3GPP (self),
+ MM_MODEM_3GPP_REGISTRATION_STATE_IDLE,
+ MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN);
+ mm_iface_modem_3gpp_update_cs_registration_state (MM_IFACE_MODEM_3GPP (self),
+ MM_MODEM_3GPP_REGISTRATION_STATE_IDLE,
+ MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN);
g_simple_async_result_take_error (ctx->result, error);
register_in_network_context_complete_and_free (ctx);
return;
@@ -2123,9 +2091,12 @@ run_all_registration_checks_ready (MMBroadbandModem *self,
/* Don't spent too much time waiting to get registered */
if (g_timer_elapsed (ctx->timer, NULL) > MAX_REGISTRATION_CHECK_WAIT_TIME) {
mm_dbg ("Registration check timed out");
- mm_iface_modem_3gpp_update_registration_state (MM_IFACE_MODEM_3GPP (self),
- MM_MODEM_3GPP_REGISTRATION_STATE_IDLE,
- MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN);
+ mm_iface_modem_3gpp_update_cs_registration_state (MM_IFACE_MODEM_3GPP (self),
+ MM_MODEM_3GPP_REGISTRATION_STATE_IDLE,
+ MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN);
+ mm_iface_modem_3gpp_update_ps_registration_state (MM_IFACE_MODEM_3GPP (self),
+ MM_MODEM_3GPP_REGISTRATION_STATE_IDLE,
+ MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN);
g_simple_async_result_take_error (
ctx->result,
mm_mobile_equipment_error_for_code (MM_MOBILE_EQUIPMENT_ERROR_NETWORK_TIMEOUT));
@@ -2156,9 +2127,12 @@ register_in_network_ready (MMBroadbandModem *self,
if (error) {
/* Propagate error in COPS, if any */
- mm_iface_modem_3gpp_update_registration_state (MM_IFACE_MODEM_3GPP (self),
- MM_MODEM_3GPP_REGISTRATION_STATE_IDLE,
- MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN);
+ mm_iface_modem_3gpp_update_cs_registration_state (MM_IFACE_MODEM_3GPP (self),
+ MM_MODEM_3GPP_REGISTRATION_STATE_IDLE,
+ MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN);
+ mm_iface_modem_3gpp_update_ps_registration_state (MM_IFACE_MODEM_3GPP (self),
+ MM_MODEM_3GPP_REGISTRATION_STATE_IDLE,
+ MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN);
g_simple_async_result_take_error (ctx->result, error);
register_in_network_context_complete_and_free (ctx);
return;
@@ -2328,15 +2302,17 @@ registration_status_check_ready (MMBroadbandModem *self,
"Error parsing registration response: '%s'",
response);
} else {
+ /* Report new registration state */
if (cgreg)
- self->priv->reg_ps = state;
+ mm_iface_modem_3gpp_update_ps_registration_state (
+ MM_IFACE_MODEM_3GPP (self),
+ state,
+ act);
else
- self->priv->reg_cs = state;
-
- /* Report new registration state */
- mm_iface_modem_3gpp_update_registration_state (MM_IFACE_MODEM_3GPP (self),
- get_consolidated_reg_state (self),
- act);
+ mm_iface_modem_3gpp_update_cs_registration_state (
+ MM_IFACE_MODEM_3GPP (self),
+ state,
+ act);
/* TODO: report LAC/CI location */
@@ -2463,13 +2439,15 @@ cleanup_registration_sequence_ready (MMBroadbandModem *self,
/* Update registration state(s) */
if (g_str_has_prefix (ctx->command, "+CREG"))
- self->priv->reg_cs = MM_MODEM_3GPP_REGISTRATION_STATE_IDLE;
+ mm_iface_modem_3gpp_update_cs_registration_state (
+ MM_IFACE_MODEM_3GPP (self),
+ MM_MODEM_3GPP_REGISTRATION_STATE_IDLE,
+ MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN);
else
- self->priv->reg_ps = MM_MODEM_3GPP_REGISTRATION_STATE_IDLE;
-
- mm_iface_modem_3gpp_update_registration_state (MM_IFACE_MODEM_3GPP (self),
- get_consolidated_reg_state (self),
- MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN);
+ mm_iface_modem_3gpp_update_ps_registration_state (
+ MM_IFACE_MODEM_3GPP (self),
+ MM_MODEM_3GPP_REGISTRATION_STATE_IDLE,
+ MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN);
/* We're done */
g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE);
@@ -3428,8 +3406,6 @@ mm_broadband_modem_init (MMBroadbandModem *self)
self->priv->modem_current_capabilities = MM_MODEM_CAPABILITY_NONE;
self->priv->modem_3gpp_registration_state = MM_MODEM_3GPP_REGISTRATION_STATE_UNKNOWN;
self->priv->reg_regex = mm_3gpp_creg_regex_get (TRUE);
- self->priv->reg_cs = MM_MODEM_3GPP_REGISTRATION_STATE_UNKNOWN;
- self->priv->reg_ps = MM_MODEM_3GPP_REGISTRATION_STATE_UNKNOWN;
self->priv->current_charset = MM_MODEM_CHARSET_UNKNOWN;
}
diff --git a/src/mm-iface-modem-3gpp.c b/src/mm-iface-modem-3gpp.c
index 30b05935..3f1b7326 100644
--- a/src/mm-iface-modem-3gpp.c
+++ b/src/mm-iface-modem-3gpp.c
@@ -26,9 +26,11 @@
#define INDICATORS_CHECKED_TAG "indicators-checked-tag"
#define UNSOLICITED_EVENTS_SUPPORTED_TAG "unsolicited-events-supported-tag"
+#define REGISTRATION_STATE_CONTEXT_TAG "registration-state-context-tag"
static GQuark indicators_checked_quark;
static GQuark unsolicited_events_supported_quark;
+static GQuark registration_state_context_quark;
/*****************************************************************************/
@@ -603,10 +605,10 @@ bearer_3gpp_connection_forbidden (MMIfaceModem3gpp *self)
MM_MODEM_ACCESS_TECHNOLOGY_HSPA_PLUS | \
MM_MODEM_ACCESS_TECHNOLOGY_LTE)
-void
-mm_iface_modem_3gpp_update_registration_state (MMIfaceModem3gpp *self,
- MMModem3gppRegistrationState new_state,
- MMModemAccessTechnology access_tech)
+static void
+update_registration_state (MMIfaceModem3gpp *self,
+ MMModem3gppRegistrationState new_state,
+ MMModemAccessTechnology access_tech)
{
MMModem3gppRegistrationState old_state;
@@ -689,6 +691,84 @@ mm_iface_modem_3gpp_update_registration_state (MMIfaceModem3gpp *self,
}
}
+typedef struct {
+ MMModem3gppRegistrationState cs;
+ MMModem3gppRegistrationState ps;
+} RegistrationStateContext;
+
+static RegistrationStateContext *
+get_registration_state_context (MMIfaceModem3gpp *self)
+{
+ RegistrationStateContext *ctx;
+
+ if (G_UNLIKELY (!registration_state_context_quark)) {
+ registration_state_context_quark = (g_quark_from_static_string (
+ REGISTRATION_STATE_CONTEXT_TAG));
+ /* Create context and keep it as object data */
+ ctx = g_new0 (RegistrationStateContext, 1);
+ g_object_set_qdata_full (
+ G_OBJECT (self),
+ registration_state_context_quark,
+ ctx,
+ (GDestroyNotify)g_free);
+
+ ctx->cs = MM_MODEM_3GPP_REGISTRATION_STATE_UNKNOWN;
+ ctx->ps = MM_MODEM_3GPP_REGISTRATION_STATE_UNKNOWN;
+ } else
+ ctx = g_object_get_qdata (G_OBJECT (self), registration_state_context_quark);
+
+ return ctx;
+}
+
+static MMModem3gppRegistrationState
+get_consolidated_reg_state (RegistrationStateContext *ctx)
+{
+ /* Some devices (Blackberries for example) will respond to +CGREG, but
+ * return ERROR for +CREG, probably because their firmware is just stupid.
+ * So here we prefer the +CREG response, but if we never got a successful
+ * +CREG response, we'll take +CGREG instead.
+ */
+ if (ctx->cs == MM_MODEM_3GPP_REGISTRATION_STATE_HOME ||
+ ctx->cs == MM_MODEM_3GPP_REGISTRATION_STATE_ROAMING)
+ return ctx->cs;
+
+ if (ctx->ps == MM_MODEM_3GPP_REGISTRATION_STATE_HOME ||
+ ctx->ps == MM_MODEM_3GPP_REGISTRATION_STATE_ROAMING)
+ return ctx->ps;
+
+ if (ctx->cs == MM_MODEM_3GPP_REGISTRATION_STATE_SEARCHING)
+ return ctx->cs;
+
+ if (ctx->ps == MM_MODEM_3GPP_REGISTRATION_STATE_SEARCHING)
+ return ctx->ps;
+
+ return ctx->cs;
+}
+
+void
+mm_iface_modem_3gpp_update_cs_registration_state (MMIfaceModem3gpp *self,
+ MMModem3gppRegistrationState state,
+ MMModemAccessTechnology access_tech)
+{
+ RegistrationStateContext *ctx;
+
+ ctx = get_registration_state_context (self);
+ ctx->cs = state;
+ update_registration_state (self, get_consolidated_reg_state (ctx), access_tech);
+}
+
+void
+mm_iface_modem_3gpp_update_ps_registration_state (MMIfaceModem3gpp *self,
+ MMModem3gppRegistrationState state,
+ MMModemAccessTechnology access_tech)
+{
+ RegistrationStateContext *ctx;
+
+ ctx = get_registration_state_context (self);
+ ctx->ps = state;
+ update_registration_state (self, get_consolidated_reg_state (ctx), access_tech);
+}
+
/*****************************************************************************/
#define REGISTRATION_CHECK_TIMEOUT_SEC 30
diff --git a/src/mm-iface-modem-3gpp.h b/src/mm-iface-modem-3gpp.h
index 35f1194b..424b6241 100644
--- a/src/mm-iface-modem-3gpp.h
+++ b/src/mm-iface-modem-3gpp.h
@@ -207,11 +207,13 @@ void mm_iface_modem_3gpp_shutdown (MMIfaceModem3gpp *self);
/* Objects implementing this interface can report new registration states.
* This may happen when handling unsolicited registration messages, or when
- * the interface asks to run registration state checks.
- * Returns FALSE if registration process is still ongoing. */
-void mm_iface_modem_3gpp_update_registration_state (MMIfaceModem3gpp *self,
- MMModem3gppRegistrationState new_state,
- MMModemAccessTechnology access_tech);
+ * the interface asks to run registration state checks. */
+void mm_iface_modem_3gpp_update_cs_registration_state (MMIfaceModem3gpp *self,
+ MMModem3gppRegistrationState state,
+ MMModemAccessTechnology access_tech);
+void mm_iface_modem_3gpp_update_ps_registration_state (MMIfaceModem3gpp *self,
+ MMModem3gppRegistrationState state,
+ MMModemAccessTechnology access_tech);
/* Run all registration checks */
void mm_iface_modem_3gpp_run_all_registration_checks (MMIfaceModem3gpp *self,