diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/mm-broadband-modem.c | 108 | ||||
-rw-r--r-- | src/mm-iface-modem-3gpp.c | 88 | ||||
-rw-r--r-- | src/mm-iface-modem-3gpp.h | 12 |
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, |