iface-modem-3gpp: update PS/CS registration states separately

But provide a consolidate state in the interface.
This commit is contained in:
Aleksander Morgado
2012-03-15 14:14:43 +01:00
parent 6abcfd54a6
commit 517d47b699
3 changed files with 135 additions and 77 deletions
+44 -68
View File
@@ -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;
}
if (cgreg)
self->priv->reg_ps = state;
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);
if (cgreg)
mm_iface_modem_3gpp_update_ps_registration_state (MM_IFACE_MODEM_3GPP (self),
state,
act);
else
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 {
if (cgreg)
self->priv->reg_ps = state;
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);
if (cgreg)
mm_iface_modem_3gpp_update_ps_registration_state (
MM_IFACE_MODEM_3GPP (self),
state,
act);
else
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;
}
+84 -4
View File
@@ -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
+7 -5
View File
@@ -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,