modem: use +CEREG to determine EPS network registration status
This patch adds the support for solicited/unsolicited EPS network registration status via AT+CEREG, which is configurable via the 'iface-modem-3gpp-eps-network-supported' property of the MMIfaceModem3gpp interface and is disabled by default.
This commit is contained in:

committed by
Aleksander Morgado

parent
7144b673e2
commit
85b67ed8d9
@@ -3984,6 +3984,7 @@ static void
|
||||
modem_3gpp_run_registration_checks (MMIfaceModem3gpp *self,
|
||||
gboolean cs_supported,
|
||||
gboolean ps_supported,
|
||||
gboolean eps_supported,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
@@ -4138,6 +4139,7 @@ static void
|
||||
modem_3gpp_disable_unsolicited_registration_events (MMIfaceModem3gpp *self,
|
||||
gboolean cs_supported,
|
||||
gboolean ps_supported,
|
||||
gboolean eps_supported,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
@@ -4183,6 +4185,7 @@ static void
|
||||
modem_3gpp_enable_unsolicited_registration_events (MMIfaceModem3gpp *self,
|
||||
gboolean cs_supported,
|
||||
gboolean ps_supported,
|
||||
gboolean eps_supported,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
|
@@ -86,6 +86,7 @@ enum {
|
||||
PROP_MODEM_3GPP_REGISTRATION_STATE,
|
||||
PROP_MODEM_3GPP_CS_NETWORK_SUPPORTED,
|
||||
PROP_MODEM_3GPP_PS_NETWORK_SUPPORTED,
|
||||
PROP_MODEM_3GPP_EPS_NETWORK_SUPPORTED,
|
||||
PROP_MODEM_CDMA_CDMA1X_REGISTRATION_STATE,
|
||||
PROP_MODEM_CDMA_EVDO_REGISTRATION_STATE,
|
||||
PROP_MODEM_CDMA_CDMA1X_NETWORK_SUPPORTED,
|
||||
@@ -129,6 +130,7 @@ struct _MMBroadbandModemPrivate {
|
||||
MMModem3gppRegistrationState modem_3gpp_registration_state;
|
||||
gboolean modem_3gpp_cs_network_supported;
|
||||
gboolean modem_3gpp_ps_network_supported;
|
||||
gboolean modem_3gpp_eps_network_supported;
|
||||
/* Implementation helpers */
|
||||
GPtrArray *modem_3gpp_registration_regex;
|
||||
|
||||
@@ -3285,6 +3287,7 @@ registration_state_changed (MMAtSerialPort *port,
|
||||
gulong lac = 0, cell_id = 0;
|
||||
MMModemAccessTechnology act = MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN;
|
||||
gboolean cgreg = FALSE;
|
||||
gboolean cereg = FALSE;
|
||||
GError *error = NULL;
|
||||
|
||||
if (!mm_3gpp_parse_creg_response (match_info,
|
||||
@@ -3293,6 +3296,7 @@ registration_state_changed (MMAtSerialPort *port,
|
||||
&cell_id,
|
||||
&act,
|
||||
&cgreg,
|
||||
&cereg,
|
||||
&error)) {
|
||||
mm_warn ("error parsing unsolicited registration: %s",
|
||||
error && error->message ? error->message : "(unknown)");
|
||||
@@ -3303,6 +3307,8 @@ registration_state_changed (MMAtSerialPort *port,
|
||||
/* Report new registration state */
|
||||
if (cgreg)
|
||||
mm_iface_modem_3gpp_update_ps_registration_state (MM_IFACE_MODEM_3GPP (self), state);
|
||||
else if (cereg)
|
||||
mm_iface_modem_3gpp_update_eps_registration_state (MM_IFACE_MODEM_3GPP (self), state);
|
||||
else
|
||||
mm_iface_modem_3gpp_update_cs_registration_state (MM_IFACE_MODEM_3GPP (self), state);
|
||||
|
||||
@@ -3489,12 +3495,16 @@ typedef struct {
|
||||
GSimpleAsyncResult *result;
|
||||
gboolean cs_supported;
|
||||
gboolean ps_supported;
|
||||
gboolean eps_supported;
|
||||
gboolean run_cs;
|
||||
gboolean run_ps;
|
||||
gboolean run_eps;
|
||||
gboolean running_cs;
|
||||
gboolean running_ps;
|
||||
gboolean running_eps;
|
||||
GError *cs_error;
|
||||
GError *ps_error;
|
||||
GError *eps_error;
|
||||
} RunRegistrationChecksContext;
|
||||
|
||||
static void
|
||||
@@ -3505,6 +3515,8 @@ run_registration_checks_context_complete_and_free (RunRegistrationChecksContext
|
||||
g_error_free (ctx->cs_error);
|
||||
if (ctx->ps_error)
|
||||
g_error_free (ctx->ps_error);
|
||||
if (ctx->eps_error)
|
||||
g_error_free (ctx->eps_error);
|
||||
g_object_unref (ctx->result);
|
||||
g_object_unref (ctx->self);
|
||||
g_free (ctx);
|
||||
@@ -3531,22 +3543,26 @@ registration_status_check_ready (MMBroadbandModem *self,
|
||||
guint i;
|
||||
gboolean parsed;
|
||||
gboolean cgreg;
|
||||
gboolean cereg;
|
||||
MMModem3gppRegistrationState state;
|
||||
MMModemAccessTechnology act;
|
||||
gulong lac;
|
||||
gulong cid;
|
||||
|
||||
/* Only one must be running */
|
||||
g_assert (!(ctx->running_ps && ctx->running_cs) &&
|
||||
(ctx->running_cs || ctx->running_ps));
|
||||
g_assert ((ctx->running_cs ? 1 : 0) +
|
||||
(ctx->running_ps ? 1 : 0) +
|
||||
(ctx->running_eps ? 1 : 0) == 1);
|
||||
|
||||
response = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error);
|
||||
if (!response) {
|
||||
g_assert (error != NULL);
|
||||
if (ctx->running_cs)
|
||||
ctx->cs_error = error;
|
||||
else
|
||||
else if (ctx->running_ps)
|
||||
ctx->ps_error = error;
|
||||
else
|
||||
ctx->eps_error = error;
|
||||
|
||||
run_registration_checks_context_step (ctx);
|
||||
return;
|
||||
@@ -3582,14 +3598,17 @@ registration_status_check_ready (MMBroadbandModem *self,
|
||||
response);
|
||||
if (ctx->running_cs)
|
||||
ctx->cs_error = error;
|
||||
else
|
||||
else if (ctx->running_ps)
|
||||
ctx->ps_error = error;
|
||||
else
|
||||
ctx->eps_error = error;
|
||||
|
||||
run_registration_checks_context_step (ctx);
|
||||
return;
|
||||
}
|
||||
|
||||
cgreg = FALSE;
|
||||
cereg = FALSE;
|
||||
state = MM_MODEM_3GPP_REGISTRATION_STATE_UNKNOWN;
|
||||
act = MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN;
|
||||
lac = 0;
|
||||
@@ -3600,6 +3619,7 @@ registration_status_check_ready (MMBroadbandModem *self,
|
||||
&cid,
|
||||
&act,
|
||||
&cgreg,
|
||||
&cereg,
|
||||
&error);
|
||||
g_match_info_free (match_info);
|
||||
|
||||
@@ -3611,8 +3631,10 @@ registration_status_check_ready (MMBroadbandModem *self,
|
||||
response);
|
||||
if (ctx->running_cs)
|
||||
ctx->cs_error = error;
|
||||
else
|
||||
else if (ctx->running_ps)
|
||||
ctx->ps_error = error;
|
||||
else
|
||||
ctx->eps_error = error;
|
||||
run_registration_checks_context_step (ctx);
|
||||
return;
|
||||
}
|
||||
@@ -3621,10 +3643,20 @@ registration_status_check_ready (MMBroadbandModem *self,
|
||||
if (cgreg) {
|
||||
if (ctx->running_cs)
|
||||
mm_dbg ("Got PS registration state when checking CS registration state");
|
||||
else if (ctx->running_eps)
|
||||
mm_dbg ("Got PS registration state when checking EPS registration state");
|
||||
mm_iface_modem_3gpp_update_ps_registration_state (MM_IFACE_MODEM_3GPP (self), state);
|
||||
} else if (cereg) {
|
||||
if (ctx->running_cs)
|
||||
mm_dbg ("Got EPS registration state when checking CS registration state");
|
||||
else if (ctx->running_ps)
|
||||
mm_dbg ("Got EPS registration state when checking PS registration state");
|
||||
mm_iface_modem_3gpp_update_eps_registration_state (MM_IFACE_MODEM_3GPP (self), state);
|
||||
} else {
|
||||
if (ctx->running_ps)
|
||||
mm_dbg ("Got CS registration state when checking PS registration state");
|
||||
else if (ctx->running_eps)
|
||||
mm_dbg ("Got CS registration state when checking EPS registration state");
|
||||
mm_iface_modem_3gpp_update_cs_registration_state (MM_IFACE_MODEM_3GPP (self), state);
|
||||
}
|
||||
|
||||
@@ -3639,6 +3671,7 @@ run_registration_checks_context_step (RunRegistrationChecksContext *ctx)
|
||||
{
|
||||
ctx->running_cs = FALSE;
|
||||
ctx->running_ps = FALSE;
|
||||
ctx->running_eps = FALSE;
|
||||
|
||||
if (ctx->run_cs) {
|
||||
ctx->running_cs = TRUE;
|
||||
@@ -3666,12 +3699,29 @@ run_registration_checks_context_step (RunRegistrationChecksContext *ctx)
|
||||
return;
|
||||
}
|
||||
|
||||
if (ctx->run_eps) {
|
||||
ctx->running_eps = TRUE;
|
||||
ctx->run_eps = FALSE;
|
||||
/* Check current EPS-registration state. */
|
||||
mm_base_modem_at_command (MM_BASE_MODEM (ctx->self),
|
||||
"+CEREG?",
|
||||
10,
|
||||
FALSE,
|
||||
(GAsyncReadyCallback)registration_status_check_ready,
|
||||
ctx);
|
||||
return;
|
||||
}
|
||||
|
||||
/* If all run checks returned errors we fail */
|
||||
if ((ctx->ps_supported && ctx->ps_error && ctx->cs_supported && ctx->cs_error) ||
|
||||
(ctx->ps_supported && ctx->ps_error && !ctx->cs_supported) ||
|
||||
(ctx->cs_supported && ctx->cs_error && !ctx->ps_supported)) {
|
||||
/* Prefer the PS error if any */
|
||||
if (ctx->ps_error) {
|
||||
if ((ctx->cs_supported || ctx->ps_supported || ctx->eps_supported) &&
|
||||
(!ctx->cs_supported || ctx->cs_error) &&
|
||||
(!ctx->ps_supported || ctx->ps_error) &&
|
||||
(!ctx->eps_supported || ctx->eps_error)) {
|
||||
/* Prefer the EPS, and then PS error if any */
|
||||
if (ctx->eps_error) {
|
||||
g_simple_async_result_set_from_error (ctx->result, ctx->eps_error);
|
||||
ctx->eps_error = NULL;
|
||||
} else if (ctx->ps_error) {
|
||||
g_simple_async_result_set_from_error (ctx->result, ctx->ps_error);
|
||||
ctx->ps_error = NULL;
|
||||
} else if (ctx->cs_error) {
|
||||
@@ -3689,6 +3739,7 @@ static void
|
||||
modem_3gpp_run_registration_checks (MMIfaceModem3gpp *self,
|
||||
gboolean cs_supported,
|
||||
gboolean ps_supported,
|
||||
gboolean eps_supported,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
@@ -3702,8 +3753,10 @@ modem_3gpp_run_registration_checks (MMIfaceModem3gpp *self,
|
||||
modem_3gpp_run_registration_checks);
|
||||
ctx->cs_supported = cs_supported;
|
||||
ctx->ps_supported = ps_supported;
|
||||
ctx->eps_supported = eps_supported;
|
||||
ctx->run_cs = cs_supported;
|
||||
ctx->run_ps = ps_supported;
|
||||
ctx->run_eps = eps_supported;
|
||||
|
||||
run_registration_checks_context_step (ctx);
|
||||
}
|
||||
@@ -3717,10 +3770,13 @@ typedef struct {
|
||||
gboolean enable; /* TRUE for enabling, FALSE for disabling */
|
||||
gboolean run_cs;
|
||||
gboolean run_ps;
|
||||
gboolean run_eps;
|
||||
gboolean running_cs;
|
||||
gboolean running_ps;
|
||||
gboolean running_eps;
|
||||
GError *cs_error;
|
||||
GError *ps_error;
|
||||
GError *eps_error;
|
||||
gboolean secondary_sequence;
|
||||
gboolean secondary_done;
|
||||
} UnsolicitedRegistrationEventsContext;
|
||||
@@ -3733,6 +3789,8 @@ unsolicited_registration_events_context_complete_and_free (UnsolicitedRegistrati
|
||||
g_error_free (ctx->cs_error);
|
||||
if (ctx->ps_error)
|
||||
g_error_free (ctx->ps_error);
|
||||
if (ctx->eps_error)
|
||||
g_error_free (ctx->eps_error);
|
||||
g_object_unref (ctx->result);
|
||||
g_object_unref (ctx->self);
|
||||
g_free (ctx);
|
||||
@@ -3743,6 +3801,7 @@ unsolicited_registration_events_context_new (MMBroadbandModem *self,
|
||||
gboolean enable,
|
||||
gboolean cs_supported,
|
||||
gboolean ps_supported,
|
||||
gboolean eps_supported,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
@@ -3757,6 +3816,7 @@ unsolicited_registration_events_context_new (MMBroadbandModem *self,
|
||||
ctx->enable = FALSE;
|
||||
ctx->run_cs = cs_supported;
|
||||
ctx->run_ps = ps_supported;
|
||||
ctx->run_eps = eps_supported;
|
||||
|
||||
return ctx;
|
||||
}
|
||||
@@ -3816,6 +3876,20 @@ static const MMBaseModemAtCommand ps_unregistration_sequence[] = {
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
static const MMBaseModemAtCommand eps_registration_sequence[] = {
|
||||
/* Enable unsolicited registration notifications in EPS network, with location */
|
||||
{ "+CEREG=2", 3, FALSE, parse_registration_setup_reply },
|
||||
/* Enable unsolicited registration notifications in EPS network, without location */
|
||||
{ "+CEREG=1", 3, FALSE, parse_registration_setup_reply },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
static const MMBaseModemAtCommand eps_unregistration_sequence[] = {
|
||||
/* Disable unsolicited registration notifications in PS network */
|
||||
{ "+CEREG=0", 3, FALSE, parse_registration_setup_reply },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
static void unsolicited_registration_events_context_step (UnsolicitedRegistrationEventsContext *ctx);
|
||||
|
||||
static void
|
||||
@@ -3828,8 +3902,9 @@ unsolicited_registration_events_sequence_ready (MMBroadbandModem *self,
|
||||
MMAtSerialPort *secondary;
|
||||
|
||||
/* Only one must be running */
|
||||
g_assert (!(ctx->running_ps && ctx->running_cs) &&
|
||||
(ctx->running_cs || ctx->running_ps));
|
||||
g_assert ((ctx->running_cs ? 1 : 0) +
|
||||
(ctx->running_ps ? 1 : 0) +
|
||||
(ctx->running_eps ? 1 : 0) == 1);
|
||||
|
||||
if (ctx->secondary_done) {
|
||||
if (ctx->secondary_sequence)
|
||||
@@ -3846,6 +3921,8 @@ unsolicited_registration_events_sequence_ready (MMBroadbandModem *self,
|
||||
ctx->cs_error = error;
|
||||
else if (ctx->running_ps && !ctx->ps_error)
|
||||
ctx->ps_error = error;
|
||||
else if (ctx->running_eps && !ctx->eps_error)
|
||||
ctx->eps_error = error;
|
||||
else
|
||||
g_error_free (error);
|
||||
} else {
|
||||
@@ -3858,6 +3935,10 @@ unsolicited_registration_events_sequence_ready (MMBroadbandModem *self,
|
||||
g_error_free (ctx->ps_error);
|
||||
ctx->ps_error = NULL;
|
||||
}
|
||||
else if (ctx->running_eps && ctx->eps_error) {
|
||||
g_error_free (ctx->eps_error);
|
||||
ctx->eps_error = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Done with primary and secondary, keep on */
|
||||
@@ -3878,13 +3959,17 @@ unsolicited_registration_events_sequence_ready (MMBroadbandModem *self,
|
||||
/* Keep errors reported */
|
||||
if (ctx->running_cs)
|
||||
ctx->cs_error = error;
|
||||
else
|
||||
else if (ctx->running_ps)
|
||||
ctx->ps_error = error;
|
||||
else
|
||||
ctx->eps_error = error;
|
||||
/* Even if primary failed, go on and try to enable in secondary port */
|
||||
}
|
||||
|
||||
secondary = mm_base_modem_peek_port_secondary (MM_BASE_MODEM (self));
|
||||
if (secondary) {
|
||||
const MMBaseModemAtCommand *registration_sequence = NULL;
|
||||
|
||||
ctx->secondary_done = TRUE;
|
||||
|
||||
/* Now use the same registration setup in secondary port, if any */
|
||||
@@ -3904,12 +3989,16 @@ unsolicited_registration_events_sequence_ready (MMBroadbandModem *self,
|
||||
|
||||
/* If primary failed, run the whole sequence in secondary */
|
||||
ctx->secondary_sequence = TRUE;
|
||||
if (ctx->running_cs)
|
||||
registration_sequence = ctx->enable ? cs_registration_sequence : cs_unregistration_sequence;
|
||||
else if (ctx->running_ps)
|
||||
registration_sequence = ctx->enable ? ps_registration_sequence : ps_unregistration_sequence;
|
||||
else
|
||||
registration_sequence = ctx->enable ? eps_registration_sequence : eps_unregistration_sequence;
|
||||
mm_base_modem_at_sequence_full (
|
||||
MM_BASE_MODEM (self),
|
||||
secondary,
|
||||
(ctx->running_cs ?
|
||||
(ctx->enable ? cs_registration_sequence : cs_unregistration_sequence) :
|
||||
(ctx->enable ? ps_registration_sequence : ps_unregistration_sequence)),
|
||||
registration_sequence,
|
||||
NULL, /* response processor context */
|
||||
NULL, /* response processor context free */
|
||||
NULL, /* cancellable */
|
||||
@@ -3927,6 +4016,7 @@ unsolicited_registration_events_context_step (UnsolicitedRegistrationEventsConte
|
||||
{
|
||||
ctx->running_cs = FALSE;
|
||||
ctx->running_ps = FALSE;
|
||||
ctx->running_eps = FALSE;
|
||||
ctx->secondary_done = FALSE;
|
||||
|
||||
if (ctx->run_cs) {
|
||||
@@ -3938,7 +4028,7 @@ unsolicited_registration_events_context_step (UnsolicitedRegistrationEventsConte
|
||||
cs_registration_sequence,
|
||||
NULL, /* response processor context */
|
||||
NULL, /* response processor context free */
|
||||
NULL, /* cancellable */
|
||||
NULL, /* cancellable */
|
||||
(GAsyncReadyCallback)unsolicited_registration_events_sequence_ready,
|
||||
ctx);
|
||||
return;
|
||||
@@ -3953,16 +4043,34 @@ unsolicited_registration_events_context_step (UnsolicitedRegistrationEventsConte
|
||||
ps_registration_sequence,
|
||||
NULL, /* response processor context */
|
||||
NULL, /* response processor context free */
|
||||
NULL, /* cancellable */
|
||||
NULL, /* cancellable */
|
||||
(GAsyncReadyCallback)unsolicited_registration_events_sequence_ready,
|
||||
ctx);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ctx->run_eps) {
|
||||
ctx->running_eps = TRUE;
|
||||
ctx->run_eps = FALSE;
|
||||
mm_base_modem_at_sequence_full (
|
||||
MM_BASE_MODEM (ctx->self),
|
||||
mm_base_modem_peek_port_primary (MM_BASE_MODEM (ctx->self)),
|
||||
eps_registration_sequence,
|
||||
NULL, /* response processor context */
|
||||
NULL, /* response processor context free */
|
||||
NULL, /* cancellable */
|
||||
(GAsyncReadyCallback)unsolicited_registration_events_sequence_ready,
|
||||
ctx);
|
||||
return;
|
||||
}
|
||||
|
||||
/* All done!
|
||||
* If we have any error reported, we'll propagate it. PS errors take
|
||||
* precendence over CS errors. */
|
||||
if (ctx->ps_error) {
|
||||
* If we have any error reported, we'll propagate it. EPS errors take
|
||||
* precendence over PS errors and PS errors take precendence over CS errors. */
|
||||
if (ctx->eps_error) {
|
||||
g_simple_async_result_take_error (ctx->result, ctx->eps_error);
|
||||
ctx->eps_error = NULL;
|
||||
} else if (ctx->ps_error) {
|
||||
g_simple_async_result_take_error (ctx->result, ctx->ps_error);
|
||||
ctx->ps_error = NULL;
|
||||
} else if (ctx->cs_error) {
|
||||
@@ -3977,6 +4085,7 @@ static void
|
||||
modem_3gpp_disable_unsolicited_registration_events (MMIfaceModem3gpp *self,
|
||||
gboolean cs_supported,
|
||||
gboolean ps_supported,
|
||||
gboolean eps_supported,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
@@ -3985,6 +4094,7 @@ modem_3gpp_disable_unsolicited_registration_events (MMIfaceModem3gpp *self,
|
||||
FALSE,
|
||||
cs_supported,
|
||||
ps_supported,
|
||||
eps_supported,
|
||||
callback,
|
||||
user_data));
|
||||
}
|
||||
@@ -3993,6 +4103,7 @@ static void
|
||||
modem_3gpp_enable_unsolicited_registration_events (MMIfaceModem3gpp *self,
|
||||
gboolean cs_supported,
|
||||
gboolean ps_supported,
|
||||
gboolean eps_supported,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
@@ -4001,6 +4112,7 @@ modem_3gpp_enable_unsolicited_registration_events (MMIfaceModem3gpp *self,
|
||||
TRUE,
|
||||
cs_supported,
|
||||
ps_supported,
|
||||
eps_supported,
|
||||
callback,
|
||||
user_data));
|
||||
}
|
||||
@@ -8740,6 +8852,9 @@ set_property (GObject *object,
|
||||
case PROP_MODEM_3GPP_PS_NETWORK_SUPPORTED:
|
||||
self->priv->modem_3gpp_ps_network_supported = g_value_get_boolean (value);
|
||||
break;
|
||||
case PROP_MODEM_3GPP_EPS_NETWORK_SUPPORTED:
|
||||
self->priv->modem_3gpp_eps_network_supported = g_value_get_boolean (value);
|
||||
break;
|
||||
case PROP_MODEM_CDMA_CDMA1X_REGISTRATION_STATE:
|
||||
self->priv->modem_cdma_cdma1x_registration_state = g_value_get_enum (value);
|
||||
break;
|
||||
@@ -8826,6 +8941,9 @@ get_property (GObject *object,
|
||||
case PROP_MODEM_3GPP_PS_NETWORK_SUPPORTED:
|
||||
g_value_set_boolean (value, self->priv->modem_3gpp_ps_network_supported);
|
||||
break;
|
||||
case PROP_MODEM_3GPP_EPS_NETWORK_SUPPORTED:
|
||||
g_value_set_boolean (value, self->priv->modem_3gpp_eps_network_supported);
|
||||
break;
|
||||
case PROP_MODEM_CDMA_CDMA1X_REGISTRATION_STATE:
|
||||
g_value_set_enum (value, self->priv->modem_cdma_cdma1x_registration_state);
|
||||
break;
|
||||
@@ -8869,6 +8987,7 @@ mm_broadband_modem_init (MMBroadbandModem *self)
|
||||
self->priv->modem_3gpp_registration_state = MM_MODEM_3GPP_REGISTRATION_STATE_UNKNOWN;
|
||||
self->priv->modem_3gpp_cs_network_supported = TRUE;
|
||||
self->priv->modem_3gpp_ps_network_supported = TRUE;
|
||||
self->priv->modem_3gpp_eps_network_supported = FALSE;
|
||||
self->priv->modem_cdma_cdma1x_registration_state = MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN;
|
||||
self->priv->modem_cdma_evdo_registration_state = MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN;
|
||||
self->priv->modem_cdma_cdma1x_network_supported = TRUE;
|
||||
@@ -9227,6 +9346,10 @@ mm_broadband_modem_class_init (MMBroadbandModemClass *klass)
|
||||
PROP_MODEM_3GPP_PS_NETWORK_SUPPORTED,
|
||||
MM_IFACE_MODEM_3GPP_PS_NETWORK_SUPPORTED);
|
||||
|
||||
g_object_class_override_property (object_class,
|
||||
PROP_MODEM_3GPP_EPS_NETWORK_SUPPORTED,
|
||||
MM_IFACE_MODEM_3GPP_EPS_NETWORK_SUPPORTED);
|
||||
|
||||
g_object_class_override_property (object_class,
|
||||
PROP_MODEM_CDMA_CDMA1X_REGISTRATION_STATE,
|
||||
MM_IFACE_MODEM_CDMA_CDMA1X_REGISTRATION_STATE);
|
||||
|
@@ -72,6 +72,7 @@ mm_iface_modem_3gpp_bind_simple_status (MMIfaceModem3gpp *self,
|
||||
typedef struct {
|
||||
MMModem3gppRegistrationState cs;
|
||||
MMModem3gppRegistrationState ps;
|
||||
MMModem3gppRegistrationState eps;
|
||||
gboolean manual_registration;
|
||||
GCancellable *pending_registration_cancellable;
|
||||
gboolean reloading_operator;
|
||||
@@ -102,6 +103,7 @@ get_registration_state_context (MMIfaceModem3gpp *self)
|
||||
ctx = g_slice_new0 (RegistrationStateContext);
|
||||
ctx->cs = MM_MODEM_3GPP_REGISTRATION_STATE_UNKNOWN;
|
||||
ctx->ps = MM_MODEM_3GPP_REGISTRATION_STATE_UNKNOWN;
|
||||
ctx->eps = MM_MODEM_3GPP_REGISTRATION_STATE_UNKNOWN;
|
||||
|
||||
g_object_set_qdata_full (
|
||||
G_OBJECT (self),
|
||||
@@ -129,12 +131,19 @@ get_consolidated_reg_state (RegistrationStateContext *ctx)
|
||||
ctx->ps == MM_MODEM_3GPP_REGISTRATION_STATE_ROAMING)
|
||||
return ctx->ps;
|
||||
|
||||
if (ctx->eps == MM_MODEM_3GPP_REGISTRATION_STATE_HOME ||
|
||||
ctx->eps == MM_MODEM_3GPP_REGISTRATION_STATE_ROAMING)
|
||||
return ctx->eps;
|
||||
|
||||
if (ctx->cs == MM_MODEM_3GPP_REGISTRATION_STATE_SEARCHING)
|
||||
return ctx->cs;
|
||||
|
||||
if (ctx->ps == MM_MODEM_3GPP_REGISTRATION_STATE_SEARCHING)
|
||||
return ctx->ps;
|
||||
|
||||
if (ctx->eps == MM_MODEM_3GPP_REGISTRATION_STATE_SEARCHING)
|
||||
return ctx->eps;
|
||||
|
||||
return ctx->cs;
|
||||
}
|
||||
|
||||
@@ -183,6 +192,7 @@ register_in_network_context_failed (RegisterInNetworkContext *ctx,
|
||||
{
|
||||
mm_iface_modem_3gpp_update_cs_registration_state (ctx->self, MM_MODEM_3GPP_REGISTRATION_STATE_IDLE);
|
||||
mm_iface_modem_3gpp_update_ps_registration_state (ctx->self, MM_MODEM_3GPP_REGISTRATION_STATE_IDLE);
|
||||
mm_iface_modem_3gpp_update_eps_registration_state (ctx->self, MM_MODEM_3GPP_REGISTRATION_STATE_IDLE);
|
||||
mm_iface_modem_3gpp_update_access_technologies (ctx->self, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN);
|
||||
mm_iface_modem_3gpp_update_location (ctx->self, 0, 0);
|
||||
|
||||
@@ -719,21 +729,25 @@ mm_iface_modem_3gpp_run_registration_checks (MMIfaceModem3gpp *self,
|
||||
{
|
||||
gboolean cs_supported = FALSE;
|
||||
gboolean ps_supported = FALSE;
|
||||
gboolean eps_supported = FALSE;
|
||||
|
||||
g_assert (MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->run_registration_checks != NULL);
|
||||
|
||||
g_object_get (self,
|
||||
MM_IFACE_MODEM_3GPP_CS_NETWORK_SUPPORTED, &cs_supported,
|
||||
MM_IFACE_MODEM_3GPP_PS_NETWORK_SUPPORTED, &ps_supported,
|
||||
MM_IFACE_MODEM_3GPP_EPS_NETWORK_SUPPORTED, &eps_supported,
|
||||
NULL);
|
||||
|
||||
mm_dbg ("Running registration checks (CS: '%s', PS: '%s')",
|
||||
mm_dbg ("Running registration checks (CS: '%s', PS: '%s', EPS: '%s')",
|
||||
cs_supported ? "yes" : "no",
|
||||
ps_supported ? "yes" : "no");
|
||||
ps_supported ? "yes" : "no",
|
||||
eps_supported ? "yes" : "no");
|
||||
|
||||
MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->run_registration_checks (self,
|
||||
cs_supported,
|
||||
ps_supported,
|
||||
eps_supported,
|
||||
callback,
|
||||
user_data);
|
||||
}
|
||||
@@ -1117,6 +1131,25 @@ mm_iface_modem_3gpp_update_ps_registration_state (MMIfaceModem3gpp *self,
|
||||
update_registration_state (self, get_consolidated_reg_state (ctx));
|
||||
}
|
||||
|
||||
void
|
||||
mm_iface_modem_3gpp_update_eps_registration_state (MMIfaceModem3gpp *self,
|
||||
MMModem3gppRegistrationState state)
|
||||
{
|
||||
RegistrationStateContext *ctx;
|
||||
gboolean supported = FALSE;
|
||||
|
||||
g_object_get (self,
|
||||
MM_IFACE_MODEM_3GPP_EPS_NETWORK_SUPPORTED, &supported,
|
||||
NULL);
|
||||
|
||||
if (!supported)
|
||||
return;
|
||||
|
||||
ctx = get_registration_state_context (self);
|
||||
ctx->eps = state;
|
||||
update_registration_state (self, get_consolidated_reg_state (ctx));
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
typedef struct {
|
||||
@@ -1297,10 +1330,12 @@ interface_disabling_step (DisablingContext *ctx)
|
||||
case DISABLING_STEP_DISABLE_UNSOLICITED_REGISTRATION_EVENTS: {
|
||||
gboolean cs_supported = FALSE;
|
||||
gboolean ps_supported = FALSE;
|
||||
gboolean eps_supported = FALSE;
|
||||
|
||||
g_object_get (ctx->self,
|
||||
MM_IFACE_MODEM_3GPP_CS_NETWORK_SUPPORTED, &cs_supported,
|
||||
MM_IFACE_MODEM_3GPP_PS_NETWORK_SUPPORTED, &ps_supported,
|
||||
MM_IFACE_MODEM_3GPP_EPS_NETWORK_SUPPORTED, &eps_supported,
|
||||
NULL);
|
||||
|
||||
if (MM_IFACE_MODEM_3GPP_GET_INTERFACE (ctx->self)->disable_unsolicited_registration_events &&
|
||||
@@ -1309,6 +1344,7 @@ interface_disabling_step (DisablingContext *ctx)
|
||||
ctx->self,
|
||||
cs_supported,
|
||||
ps_supported,
|
||||
eps_supported,
|
||||
(GAsyncReadyCallback)disable_unsolicited_registration_events_ready,
|
||||
ctx);
|
||||
return;
|
||||
@@ -1618,10 +1654,12 @@ interface_enabling_step (EnablingContext *ctx)
|
||||
case ENABLING_STEP_ENABLE_UNSOLICITED_REGISTRATION_EVENTS: {
|
||||
gboolean cs_supported = FALSE;
|
||||
gboolean ps_supported = FALSE;
|
||||
gboolean eps_supported = FALSE;
|
||||
|
||||
g_object_get (ctx->self,
|
||||
MM_IFACE_MODEM_3GPP_CS_NETWORK_SUPPORTED, &cs_supported,
|
||||
MM_IFACE_MODEM_3GPP_PS_NETWORK_SUPPORTED, &ps_supported,
|
||||
MM_IFACE_MODEM_3GPP_EPS_NETWORK_SUPPORTED, &eps_supported,
|
||||
NULL);
|
||||
|
||||
if (MM_IFACE_MODEM_3GPP_GET_INTERFACE (ctx->self)->enable_unsolicited_registration_events &&
|
||||
@@ -1630,6 +1668,7 @@ interface_enabling_step (EnablingContext *ctx)
|
||||
ctx->self,
|
||||
cs_supported,
|
||||
ps_supported,
|
||||
eps_supported,
|
||||
(GAsyncReadyCallback)enable_unsolicited_registration_events_ready,
|
||||
ctx);
|
||||
return;
|
||||
@@ -1996,6 +2035,14 @@ iface_modem_3gpp_init (gpointer g_iface)
|
||||
TRUE,
|
||||
G_PARAM_READWRITE));
|
||||
|
||||
g_object_interface_install_property
|
||||
(g_iface,
|
||||
g_param_spec_boolean (MM_IFACE_MODEM_3GPP_EPS_NETWORK_SUPPORTED,
|
||||
"EPS network supported",
|
||||
"Whether the modem works in the EPS network",
|
||||
FALSE,
|
||||
G_PARAM_READWRITE));
|
||||
|
||||
initialized = TRUE;
|
||||
}
|
||||
|
||||
|
@@ -30,8 +30,9 @@
|
||||
|
||||
#define MM_IFACE_MODEM_3GPP_DBUS_SKELETON "iface-modem-3gpp-dbus-skeleton"
|
||||
#define MM_IFACE_MODEM_3GPP_REGISTRATION_STATE "iface-modem-3gpp-registration-state"
|
||||
#define MM_IFACE_MODEM_3GPP_PS_NETWORK_SUPPORTED "iface-modem-3gpp-ps-network-supported"
|
||||
#define MM_IFACE_MODEM_3GPP_CS_NETWORK_SUPPORTED "iface-modem-3gpp-cs-network-supported"
|
||||
#define MM_IFACE_MODEM_3GPP_PS_NETWORK_SUPPORTED "iface-modem-3gpp-ps-network-supported"
|
||||
#define MM_IFACE_MODEM_3GPP_EPS_NETWORK_SUPPORTED "iface-modem-3gpp-eps-network-supported"
|
||||
|
||||
#define MM_IFACE_MODEM_3GPP_ALL_ACCESS_TECHNOLOGIES_MASK \
|
||||
(MM_MODEM_ACCESS_TECHNOLOGY_GSM | \
|
||||
@@ -110,6 +111,7 @@ struct _MMIfaceModem3gpp {
|
||||
void (*enable_unsolicited_registration_events) (MMIfaceModem3gpp *self,
|
||||
gboolean cs_supported,
|
||||
gboolean ps_supported,
|
||||
gboolean eps_supported,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
gboolean (*enable_unsolicited_registration_events_finish) (MMIfaceModem3gpp *self,
|
||||
@@ -127,18 +129,20 @@ struct _MMIfaceModem3gpp {
|
||||
void (*disable_unsolicited_registration_events) (MMIfaceModem3gpp *self,
|
||||
gboolean cs_supported,
|
||||
gboolean ps_supported,
|
||||
gboolean eps_supported,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
gboolean (*disable_unsolicited_registration_events_finish) (MMIfaceModem3gpp *self,
|
||||
GAsyncResult *res,
|
||||
GError **error);
|
||||
|
||||
/* Run CS/PS registration state checks..
|
||||
/* Run CS/PS/EPS registration state checks..
|
||||
* Note that no registration state is returned, implementations should call
|
||||
* mm_iface_modem_3gpp_update_registration_state(). */
|
||||
void (* run_registration_checks) (MMIfaceModem3gpp *self,
|
||||
gboolean cs_supported,
|
||||
gboolean ps_supported,
|
||||
gboolean eps_supported,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
gboolean (*run_registration_checks_finish) (MMIfaceModem3gpp *self,
|
||||
@@ -219,6 +223,8 @@ void mm_iface_modem_3gpp_update_cs_registration_state (MMIfaceModem3gpp *self,
|
||||
MMModem3gppRegistrationState state);
|
||||
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_access_technologies (MMIfaceModem3gpp *self,
|
||||
MMModemAccessTechnology access_tech);
|
||||
void mm_iface_modem_3gpp_update_location (MMIfaceModem3gpp *self,
|
||||
|
@@ -216,22 +216,22 @@ mm_filter_current_bands (const GArray *supported_bands,
|
||||
/*****************************************************************************/
|
||||
|
||||
/* +CREG: <stat> (GSM 07.07 CREG=1 unsolicited) */
|
||||
#define CREG1 "\\+(CREG|CGREG):\\s*0*([0-9])"
|
||||
#define CREG1 "\\+(CREG|CGREG|CEREG):\\s*0*([0-9])"
|
||||
|
||||
/* +CREG: <n>,<stat> (GSM 07.07 CREG=1 solicited) */
|
||||
#define CREG2 "\\+(CREG|CGREG):\\s*0*([0-9]),\\s*0*([0-9])"
|
||||
#define CREG2 "\\+(CREG|CGREG|CEREG):\\s*0*([0-9]),\\s*0*([0-9])"
|
||||
|
||||
/* +CREG: <stat>,<lac>,<ci> (GSM 07.07 CREG=2 unsolicited) */
|
||||
#define CREG3 "\\+(CREG|CGREG):\\s*0*([0-9]),\\s*([^,\\s]*)\\s*,\\s*([^,\\s]*)"
|
||||
#define CREG3 "\\+(CREG|CGREG|CEREG):\\s*0*([0-9]),\\s*([^,\\s]*)\\s*,\\s*([^,\\s]*)"
|
||||
|
||||
/* +CREG: <n>,<stat>,<lac>,<ci> (GSM 07.07 solicited and some CREG=2 unsolicited) */
|
||||
#define CREG4 "\\+(CREG|CGREG):\\s*0*([0-9]),\\s*0*([0-9])\\s*,\\s*([^,]*)\\s*,\\s*([^,\\s]*)"
|
||||
#define CREG4 "\\+(CREG|CGREG|CEREG):\\s*0*([0-9]),\\s*0*([0-9])\\s*,\\s*([^,]*)\\s*,\\s*([^,\\s]*)"
|
||||
|
||||
/* +CREG: <stat>,<lac>,<ci>,<AcT> (ETSI 27.007 CREG=2 unsolicited) */
|
||||
#define CREG5 "\\+(CREG|CGREG):\\s*0*([0-9])\\s*,\\s*([^,\\s]*)\\s*,\\s*([^,\\s]*)\\s*,\\s*0*([0-9])"
|
||||
#define CREG5 "\\+(CREG|CGREG|CEREG):\\s*0*([0-9])\\s*,\\s*([^,\\s]*)\\s*,\\s*([^,\\s]*)\\s*,\\s*0*([0-9])"
|
||||
|
||||
/* +CREG: <n>,<stat>,<lac>,<ci>,<AcT> (ETSI 27.007 solicited and some CREG=2 unsolicited) */
|
||||
#define CREG6 "\\+(CREG|CGREG):\\s*0*([0-9]),\\s*0*([0-9])\\s*,\\s*([^,\\s]*)\\s*,\\s*([^,\\s]*)\\s*,\\s*0*([0-9])"
|
||||
#define CREG6 "\\+(CREG|CGREG|CEREG):\\s*0*([0-9]),\\s*0*([0-9])\\s*,\\s*([^,\\s]*)\\s*,\\s*([^,\\s]*)\\s*,\\s*0*([0-9])"
|
||||
|
||||
/* +CREG: <n>,<stat>,<lac>,<ci>,<AcT?>,<something> (Samsung Wave S8500) */
|
||||
/* '<CR><LF>+CREG: 2,1,000B,2816, B, C2816<CR><LF><CR><LF>OK<CR><LF>' */
|
||||
@@ -240,10 +240,16 @@ mm_filter_current_bands (const GArray *supported_bands,
|
||||
/* +CREG: <stat>,<lac>,<ci>,<AcT>,<RAC> (ETSI 27.007 v9.20 CREG=2 unsolicited with RAC) */
|
||||
#define CREG8 "\\+(CREG|CGREG):\\s*0*([0-9])\\s*,\\s*([^,\\s]*)\\s*,\\s*([^,\\s]*)\\s*,\\s*0*([0-9])\\s*,\\s*([^,\\s]*)"
|
||||
|
||||
/* +CEREG: <stat>,<lac>,<rac>,<ci>,<AcT> (ETSI 27.007 v8.6 CREG=2 unsolicited with RAC) */
|
||||
#define CEREG1 "\\+(CEREG):\\s*0*([0-9])\\s*,\\s*([^,\\s]*)\\s*,\\s*([^,\\s]*)\\s*,\\s*([^,\\s]*)\\s*,\\s*0*([0-9])"
|
||||
|
||||
/* +CEREG: <n>,<stat>,<lac>,<rac>,<ci>,<AcT> (ETSI 27.007 v8.6 CREG=2 solicited with RAC) */
|
||||
#define CEREG2 "\\+(CEREG):\\s*0*([0-9]),\\s*0*([0-9])\\s*,\\s*([^,\\s]*)\\s*,\\s*([^,\\s]*)\\s*,\\s*([^,\\s]*)\\s*,\\s*0*([0-9])"
|
||||
|
||||
GPtrArray *
|
||||
mm_3gpp_creg_regex_get (gboolean solicited)
|
||||
{
|
||||
GPtrArray *array = g_ptr_array_sized_new (7);
|
||||
GPtrArray *array = g_ptr_array_sized_new (10);
|
||||
GRegex *regex;
|
||||
|
||||
/* #1 */
|
||||
@@ -310,6 +316,22 @@ mm_3gpp_creg_regex_get (gboolean solicited)
|
||||
g_assert (regex);
|
||||
g_ptr_array_add (array, regex);
|
||||
|
||||
/* CEREG #1 */
|
||||
if (solicited)
|
||||
regex = g_regex_new (CEREG1 "$", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
|
||||
else
|
||||
regex = g_regex_new ("\\r\\n" CEREG1 "\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
|
||||
g_assert (regex);
|
||||
g_ptr_array_add (array, regex);
|
||||
|
||||
/* CEREG #2 */
|
||||
if (solicited)
|
||||
regex = g_regex_new (CEREG2 "$", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
|
||||
else
|
||||
regex = g_regex_new ("\\r\\n" CEREG2 "\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
|
||||
g_assert (regex);
|
||||
g_ptr_array_add (array, regex);
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
@@ -723,6 +745,7 @@ mm_3gpp_parse_creg_response (GMatchInfo *info,
|
||||
gulong *out_ci,
|
||||
MMModemAccessTechnology *out_act,
|
||||
gboolean *out_cgreg,
|
||||
gboolean *out_cereg,
|
||||
GError **error)
|
||||
{
|
||||
gboolean success = FALSE, foo;
|
||||
@@ -737,10 +760,11 @@ mm_3gpp_parse_creg_response (GMatchInfo *info,
|
||||
g_return_val_if_fail (out_ci != NULL, FALSE);
|
||||
g_return_val_if_fail (out_act != NULL, FALSE);
|
||||
g_return_val_if_fail (out_cgreg != NULL, FALSE);
|
||||
g_return_val_if_fail (out_cereg != NULL, FALSE);
|
||||
|
||||
str = g_match_info_fetch (info, 1);
|
||||
if (str && strstr (str, "CGREG"))
|
||||
*out_cgreg = TRUE;
|
||||
*out_cgreg = (str && strstr (str, "CGREG")) ? TRUE : FALSE;
|
||||
*out_cereg = (str && strstr (str, "CEREG")) ? TRUE : FALSE;
|
||||
g_free (str);
|
||||
|
||||
/* Normally the number of matches could be used to determine what each
|
||||
@@ -777,19 +801,43 @@ mm_3gpp_parse_creg_response (GMatchInfo *info,
|
||||
} else if (n_matches == 7) {
|
||||
/* CREG=2 (solicited): +CREG: <n>,<stat>,<lac>,<ci>,<AcT>
|
||||
* CREG=2 (unsolicited with RAC): +CREG: <stat>,<lac>,<ci>,<AcT>,<RAC>
|
||||
* CEREG=2 (solicited): +CEREG: <n>,<stat>,<lac>,<ci>,<AcT>
|
||||
* CEREG=2 (unsolicited with RAC): +CEREG: <stat>,<lac>,<rac>,<ci>,<AcT>
|
||||
*/
|
||||
|
||||
/* Check if the third item is the LAC to distinguish the two cases */
|
||||
if (item_is_lac_not_stat (info, 3)) {
|
||||
istat = 2;
|
||||
ilac = 3;
|
||||
ici = 4;
|
||||
iact = 5;
|
||||
} else {
|
||||
istat = 3;
|
||||
ilac = 4;
|
||||
if (*out_cereg) {
|
||||
/* Check if the third item is the LAC to distinguish the two cases */
|
||||
if (item_is_lac_not_stat (info, 3)) {
|
||||
istat = 2;
|
||||
ilac = 3;
|
||||
} else {
|
||||
istat = 3;
|
||||
ilac = 4;
|
||||
}
|
||||
ici = 5;
|
||||
iact = 6;
|
||||
} else {
|
||||
/* Check if the third item is the LAC to distinguish the two cases */
|
||||
if (item_is_lac_not_stat (info, 3)) {
|
||||
istat = 2;
|
||||
ilac = 3;
|
||||
ici = 4;
|
||||
iact = 5;
|
||||
} else {
|
||||
istat = 3;
|
||||
ilac = 4;
|
||||
ici = 5;
|
||||
iact = 6;
|
||||
}
|
||||
}
|
||||
} else if (n_matches == 8) {
|
||||
/* CEREG=2 (solicited with RAC): +CEREG: <n>,<stat>,<lac>,<rac>,<ci>,<AcT>
|
||||
*/
|
||||
if (*out_cereg) {
|
||||
istat = 3;
|
||||
ilac = 4;
|
||||
ici = 6;
|
||||
iact = 7;
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -106,6 +106,7 @@ gboolean mm_3gpp_parse_creg_response (GMatchInfo *info,
|
||||
gulong *out_ci,
|
||||
MMModemAccessTechnology *out_act,
|
||||
gboolean *out_cgreg,
|
||||
gboolean *out_cereg,
|
||||
GError **error);
|
||||
|
||||
/* AT+CMGF=? (SMS message format) response parser */
|
||||
|
@@ -473,6 +473,7 @@ typedef struct {
|
||||
|
||||
guint regex_num;
|
||||
gboolean cgreg;
|
||||
gboolean cereg;
|
||||
} CregResult;
|
||||
|
||||
static void
|
||||
@@ -488,7 +489,7 @@ test_creg_match (const char *test,
|
||||
MMModemAccessTechnology access_tech = MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN;
|
||||
gulong lac = 0, ci = 0;
|
||||
GError *error = NULL;
|
||||
gboolean success, cgreg = FALSE;
|
||||
gboolean success, cgreg = FALSE, cereg = FALSE;
|
||||
guint regex_num = 0;
|
||||
GPtrArray *array;
|
||||
|
||||
@@ -522,7 +523,7 @@ test_creg_match (const char *test,
|
||||
g_assert (info != NULL);
|
||||
g_assert_cmpuint (regex_num, ==, result->regex_num);
|
||||
|
||||
success = mm_3gpp_parse_creg_response (info, &state, &lac, &ci, &access_tech, &cgreg, &error);
|
||||
success = mm_3gpp_parse_creg_response (info, &state, &lac, &ci, &access_tech, &cgreg, &cereg, &error);
|
||||
g_assert (success);
|
||||
g_assert_no_error (error);
|
||||
g_assert_cmpuint (state, ==, result->state);
|
||||
@@ -533,6 +534,7 @@ test_creg_match (const char *test,
|
||||
access_tech, result->act);
|
||||
g_assert_cmpuint (access_tech, ==, result->act);
|
||||
g_assert_cmpuint (cgreg, ==, result->cgreg);
|
||||
g_assert_cmpuint (cereg, ==, result->cereg);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -540,7 +542,7 @@ test_creg1_solicited (void *f, gpointer d)
|
||||
{
|
||||
RegTestData *data = (RegTestData *) d;
|
||||
const char *reply = "+CREG: 1,3";
|
||||
const CregResult result = { 3, 0, 0, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN , 2, FALSE};
|
||||
const CregResult result = { 3, 0, 0, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN , 2, FALSE, FALSE };
|
||||
|
||||
test_creg_match ("CREG=1", TRUE, reply, data, &result);
|
||||
}
|
||||
@@ -550,7 +552,7 @@ test_creg1_unsolicited (void *f, gpointer d)
|
||||
{
|
||||
RegTestData *data = (RegTestData *) d;
|
||||
const char *reply = "\r\n+CREG: 3\r\n";
|
||||
const CregResult result = { 3, 0, 0, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN , 1, FALSE};
|
||||
const CregResult result = { 3, 0, 0, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN , 1, FALSE, FALSE };
|
||||
|
||||
test_creg_match ("CREG=1", FALSE, reply, data, &result);
|
||||
}
|
||||
@@ -560,7 +562,7 @@ test_creg2_mercury_solicited (void *f, gpointer d)
|
||||
{
|
||||
RegTestData *data = (RegTestData *) d;
|
||||
const char *reply = "+CREG: 0,1,84CD,00D30173";
|
||||
const CregResult result = { 1, 0x84cd, 0xd30173, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN , 4, FALSE};
|
||||
const CregResult result = { 1, 0x84cd, 0xd30173, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN , 4, FALSE, FALSE };
|
||||
|
||||
test_creg_match ("Sierra Mercury CREG=2", TRUE, reply, data, &result);
|
||||
}
|
||||
@@ -570,7 +572,7 @@ test_creg2_mercury_unsolicited (void *f, gpointer d)
|
||||
{
|
||||
RegTestData *data = (RegTestData *) d;
|
||||
const char *reply = "\r\n+CREG: 1,84CD,00D30156\r\n";
|
||||
const CregResult result = { 1, 0x84cd, 0xd30156, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN , 3, FALSE};
|
||||
const CregResult result = { 1, 0x84cd, 0xd30156, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN , 3, FALSE, FALSE };
|
||||
|
||||
test_creg_match ("Sierra Mercury CREG=2", FALSE, reply, data, &result);
|
||||
}
|
||||
@@ -580,7 +582,7 @@ test_creg2_sek850i_solicited (void *f, gpointer d)
|
||||
{
|
||||
RegTestData *data = (RegTestData *) d;
|
||||
const char *reply = "+CREG: 2,1,\"CE00\",\"01CEAD8F\"";
|
||||
const CregResult result = { 1, 0xce00, 0x01cead8f, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN , 4, FALSE};
|
||||
const CregResult result = { 1, 0xce00, 0x01cead8f, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN , 4, FALSE, FALSE };
|
||||
|
||||
test_creg_match ("Sony Ericsson K850i CREG=2", TRUE, reply, data, &result);
|
||||
}
|
||||
@@ -590,7 +592,7 @@ test_creg2_sek850i_unsolicited (void *f, gpointer d)
|
||||
{
|
||||
RegTestData *data = (RegTestData *) d;
|
||||
const char *reply = "\r\n+CREG: 1,\"CE00\",\"00005449\"\r\n";
|
||||
const CregResult result = { 1, 0xce00, 0x5449, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN , 3, FALSE};
|
||||
const CregResult result = { 1, 0xce00, 0x5449, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN , 3, FALSE, FALSE };
|
||||
|
||||
test_creg_match ("Sony Ericsson K850i CREG=2", FALSE, reply, data, &result);
|
||||
}
|
||||
@@ -600,7 +602,7 @@ test_creg2_e160g_solicited_unregistered (void *f, gpointer d)
|
||||
{
|
||||
RegTestData *data = (RegTestData *) d;
|
||||
const char *reply = "+CREG: 2,0,00,0";
|
||||
const CregResult result = { 0, 0, 0, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN , 4, FALSE};
|
||||
const CregResult result = { 0, 0, 0, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN , 4, FALSE, FALSE };
|
||||
|
||||
test_creg_match ("Huawei E160G unregistered CREG=2", TRUE, reply, data, &result);
|
||||
}
|
||||
@@ -610,7 +612,7 @@ test_creg2_e160g_solicited (void *f, gpointer d)
|
||||
{
|
||||
RegTestData *data = (RegTestData *) d;
|
||||
const char *reply = "+CREG: 2,1,8BE3,2BAF";
|
||||
const CregResult result = { 1, 0x8be3, 0x2baf, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN , 4, FALSE};
|
||||
const CregResult result = { 1, 0x8be3, 0x2baf, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN , 4, FALSE, FALSE };
|
||||
|
||||
test_creg_match ("Huawei E160G CREG=2", TRUE, reply, data, &result);
|
||||
}
|
||||
@@ -620,7 +622,7 @@ test_creg2_e160g_unsolicited (void *f, gpointer d)
|
||||
{
|
||||
RegTestData *data = (RegTestData *) d;
|
||||
const char *reply = "\r\n+CREG: 2,8BE3,2BAF\r\n";
|
||||
const CregResult result = { 2, 0x8be3, 0x2baf, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN , 3, FALSE};
|
||||
const CregResult result = { 2, 0x8be3, 0x2baf, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN , 3, FALSE, FALSE };
|
||||
|
||||
test_creg_match ("Huawei E160G CREG=2", FALSE, reply, data, &result);
|
||||
}
|
||||
@@ -630,7 +632,7 @@ test_creg2_tm506_solicited (void *f, gpointer d)
|
||||
{
|
||||
RegTestData *data = (RegTestData *) d;
|
||||
const char *reply = "+CREG: 2,1,\"8BE3\",\"00002BAF\"";
|
||||
const CregResult result = { 1, 0x8BE3, 0x2BAF, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN , 4, FALSE};
|
||||
const CregResult result = { 1, 0x8BE3, 0x2BAF, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN , 4, FALSE, FALSE };
|
||||
|
||||
/* Test leading zeros in the CI */
|
||||
test_creg_match ("Sony Ericsson TM-506 CREG=2", TRUE, reply, data, &result);
|
||||
@@ -641,7 +643,7 @@ test_creg2_xu870_unsolicited_unregistered (void *f, gpointer d)
|
||||
{
|
||||
RegTestData *data = (RegTestData *) d;
|
||||
const char *reply = "\r\n+CREG: 2,,\r\n";
|
||||
const CregResult result = { 2, 0, 0, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN , 3, FALSE};
|
||||
const CregResult result = { 2, 0, 0, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN , 3, FALSE, FALSE };
|
||||
|
||||
test_creg_match ("Novatel XU870 unregistered CREG=2", FALSE, reply, data, &result);
|
||||
}
|
||||
@@ -651,7 +653,7 @@ test_creg2_iridium_solicited (void *f, gpointer d)
|
||||
{
|
||||
RegTestData *data = (RegTestData *) d;
|
||||
const char *reply = "+CREG:002,001,\"18d8\",\"ffff\"";
|
||||
const CregResult result = { 1, 0x18D8, 0xFFFF, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, 4, FALSE};
|
||||
const CregResult result = { 1, 0x18D8, 0xFFFF, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, 4, FALSE, FALSE };
|
||||
|
||||
test_creg_match ("Iridium, CREG=2", TRUE, reply, data, &result);
|
||||
}
|
||||
@@ -661,7 +663,7 @@ test_cgreg1_solicited (void *f, gpointer d)
|
||||
{
|
||||
RegTestData *data = (RegTestData *) d;
|
||||
const char *reply = "+CGREG: 1,3";
|
||||
const CregResult result = { 3, 0, 0, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN , 2, TRUE};
|
||||
const CregResult result = { 3, 0, 0, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN , 2, TRUE, FALSE };
|
||||
|
||||
test_creg_match ("CGREG=1", TRUE, reply, data, &result);
|
||||
}
|
||||
@@ -671,7 +673,7 @@ test_cgreg1_unsolicited (void *f, gpointer d)
|
||||
{
|
||||
RegTestData *data = (RegTestData *) d;
|
||||
const char *reply = "\r\n+CGREG: 3\r\n";
|
||||
const CregResult result = { 3, 0, 0, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN , 1, TRUE};
|
||||
const CregResult result = { 3, 0, 0, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN , 1, TRUE, FALSE };
|
||||
|
||||
test_creg_match ("CGREG=1", FALSE, reply, data, &result);
|
||||
}
|
||||
@@ -681,7 +683,7 @@ test_cgreg2_f3607gw_solicited (void *f, gpointer d)
|
||||
{
|
||||
RegTestData *data = (RegTestData *) d;
|
||||
const char *reply = "+CGREG: 2,1,\"8BE3\",\"00002B5D\",3";
|
||||
const CregResult result = { 1, 0x8BE3, 0x2B5D, MM_MODEM_ACCESS_TECHNOLOGY_EDGE , 6, TRUE};
|
||||
const CregResult result = { 1, 0x8BE3, 0x2B5D, MM_MODEM_ACCESS_TECHNOLOGY_EDGE , 6, TRUE, FALSE };
|
||||
|
||||
test_creg_match ("Ericsson F3607gw CGREG=2", TRUE, reply, data, &result);
|
||||
}
|
||||
@@ -691,7 +693,7 @@ test_cgreg2_f3607gw_unsolicited (void *f, gpointer d)
|
||||
{
|
||||
RegTestData *data = (RegTestData *) d;
|
||||
const char *reply = "\r\n+CGREG: 1,\"8BE3\",\"00002B5D\",3\r\n";
|
||||
const CregResult result = { 1, 0x8BE3, 0x2B5D, MM_MODEM_ACCESS_TECHNOLOGY_EDGE , 5, TRUE};
|
||||
const CregResult result = { 1, 0x8BE3, 0x2B5D, MM_MODEM_ACCESS_TECHNOLOGY_EDGE , 5, TRUE, FALSE };
|
||||
|
||||
test_creg_match ("Ericsson F3607gw CGREG=2", FALSE, reply, data, &result);
|
||||
}
|
||||
@@ -701,7 +703,7 @@ test_creg2_md400_unsolicited (void *f, gpointer d)
|
||||
{
|
||||
RegTestData *data = (RegTestData *) d;
|
||||
const char *reply = "\r\n+CREG: 2,5,\"0502\",\"0404736D\"\r\n";
|
||||
const CregResult result = { 5, 0x0502, 0x0404736D, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN , 4, FALSE};
|
||||
const CregResult result = { 5, 0x0502, 0x0404736D, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN , 4, FALSE, FALSE };
|
||||
|
||||
test_creg_match ("Sony-Ericsson MD400 CREG=2", FALSE, reply, data, &result);
|
||||
}
|
||||
@@ -711,7 +713,7 @@ test_cgreg2_md400_unsolicited (void *f, gpointer d)
|
||||
{
|
||||
RegTestData *data = (RegTestData *) d;
|
||||
const char *reply = "\r\n+CGREG: 5,\"0502\",\"0404736D\",2\r\n";
|
||||
const CregResult result = { 5, 0x0502, 0x0404736D, MM_MODEM_ACCESS_TECHNOLOGY_UMTS, 5, TRUE};
|
||||
const CregResult result = { 5, 0x0502, 0x0404736D, MM_MODEM_ACCESS_TECHNOLOGY_UMTS, 5, TRUE, FALSE };
|
||||
|
||||
test_creg_match ("Sony-Ericsson MD400 CGREG=2", FALSE, reply, data, &result);
|
||||
}
|
||||
@@ -721,7 +723,7 @@ test_creg_cgreg_multi_unsolicited (void *f, gpointer d)
|
||||
{
|
||||
RegTestData *data = (RegTestData *) d;
|
||||
const char *reply = "\r\n+CREG: 5\r\n\r\n+CGREG: 0\r\n";
|
||||
const CregResult result = { 5, 0, 0, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, 1, FALSE};
|
||||
const CregResult result = { 5, 0, 0, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, 1, FALSE, FALSE };
|
||||
|
||||
test_creg_match ("Multi CREG/CGREG", FALSE, reply, data, &result);
|
||||
}
|
||||
@@ -731,7 +733,7 @@ test_creg_cgreg_multi2_unsolicited (void *f, gpointer d)
|
||||
{
|
||||
RegTestData *data = (RegTestData *) d;
|
||||
const char *reply = "\r\n+CGREG: 0\r\n\r\n+CREG: 5\r\n";
|
||||
const CregResult result = { 0, 0, 0, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, 1, TRUE};
|
||||
const CregResult result = { 0, 0, 0, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, 1, TRUE, FALSE };
|
||||
|
||||
test_creg_match ("Multi CREG/CGREG #2", FALSE, reply, data, &result);
|
||||
}
|
||||
@@ -741,7 +743,7 @@ test_cgreg2_x220_unsolicited (void *f, gpointer d)
|
||||
{
|
||||
RegTestData *data = (RegTestData *) d;
|
||||
const char *reply = "\r\n+CGREG: 2,1, 81ED, 1A9CEB\r\n";
|
||||
const CregResult result = { 1, 0x81ED, 0x1A9CEB, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, 4, TRUE};
|
||||
const CregResult result = { 1, 0x81ED, 0x1A9CEB, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, 4, TRUE, FALSE };
|
||||
|
||||
/* Tests random spaces in response */
|
||||
test_creg_match ("Alcatel One-Touch X220D CGREG=2", FALSE, reply, data, &result);
|
||||
@@ -752,7 +754,7 @@ test_creg2_s8500_wave_unsolicited (void *f, gpointer d)
|
||||
{
|
||||
RegTestData *data = (RegTestData *) d;
|
||||
const char *reply = "\r\n+CREG: 2,1,000B,2816, B, C2816\r\n";
|
||||
const CregResult result = { 1, 0x000B, 0x2816, MM_MODEM_ACCESS_TECHNOLOGY_GSM, 7, FALSE};
|
||||
const CregResult result = { 1, 0x000B, 0x2816, MM_MODEM_ACCESS_TECHNOLOGY_GSM, 7, FALSE, FALSE };
|
||||
|
||||
test_creg_match ("Samsung Wave S8500 CREG=2", FALSE, reply, data, &result);
|
||||
}
|
||||
@@ -762,7 +764,7 @@ test_creg2_gobi_weird_solicited (void *f, gpointer d)
|
||||
{
|
||||
RegTestData *data = (RegTestData *) d;
|
||||
const char *reply = "\r\n+CREG: 2,1, 0 5, 2715\r\n";
|
||||
const CregResult result = { 1, 0x0000, 0x2715, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, 4, FALSE};
|
||||
const CregResult result = { 1, 0x0000, 0x2715, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, 4, FALSE, FALSE };
|
||||
|
||||
test_creg_match ("Qualcomm Gobi 1000 CREG=2", TRUE, reply, data, &result);
|
||||
}
|
||||
@@ -772,11 +774,71 @@ test_cgreg2_unsolicited_with_rac (void *f, gpointer d)
|
||||
{
|
||||
RegTestData *data = (RegTestData *) d;
|
||||
const char *reply = "\r\n+CGREG: 1,\"1422\",\"00000142\",3,\"00\"\r\n";
|
||||
const CregResult result = { 1, 0x1422, 0x0142, MM_MODEM_ACCESS_TECHNOLOGY_EDGE, 8, TRUE };
|
||||
const CregResult result = { 1, 0x1422, 0x0142, MM_MODEM_ACCESS_TECHNOLOGY_EDGE, 8, TRUE, FALSE };
|
||||
|
||||
test_creg_match ("CGREG=2 with RAC", FALSE, reply, data, &result);
|
||||
}
|
||||
|
||||
static void
|
||||
test_cereg1_solicited (void *f, gpointer d)
|
||||
{
|
||||
RegTestData *data = (RegTestData *) d;
|
||||
const char *reply = "+CEREG: 1,3";
|
||||
const CregResult result = { 3, 0, 0, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN , 2, FALSE, TRUE };
|
||||
|
||||
test_creg_match ("CEREG=1", TRUE, reply, data, &result);
|
||||
}
|
||||
|
||||
static void
|
||||
test_cereg1_unsolicited (void *f, gpointer d)
|
||||
{
|
||||
RegTestData *data = (RegTestData *) d;
|
||||
const char *reply = "\r\n+CEREG: 3\r\n";
|
||||
const CregResult result = { 3, 0, 0, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN , 1, FALSE, TRUE };
|
||||
|
||||
test_creg_match ("CEREG=1", FALSE, reply, data, &result);
|
||||
}
|
||||
|
||||
static void
|
||||
test_cereg2_solicited (void *f, gpointer d)
|
||||
{
|
||||
RegTestData *data = (RegTestData *) d;
|
||||
const char *reply = "\r\n+CEREG: 2,1, 1F00, 79D903 ,7\r\n";
|
||||
const CregResult result = { 1, 0x1F00, 0x79D903, MM_MODEM_ACCESS_TECHNOLOGY_LTE, 6, FALSE, TRUE };
|
||||
|
||||
test_creg_match ("CEREG=2", TRUE, reply, data, &result);
|
||||
}
|
||||
|
||||
static void
|
||||
test_cereg2_unsolicited (void *f, gpointer d)
|
||||
{
|
||||
RegTestData *data = (RegTestData *) d;
|
||||
const char *reply = "\r\n+CEREG: 1, 1F00, 79D903 ,7\r\n";
|
||||
const CregResult result = { 1, 0x1F00, 0x79D903, MM_MODEM_ACCESS_TECHNOLOGY_LTE, 5, FALSE, TRUE };
|
||||
|
||||
test_creg_match ("CEREG=2", FALSE, reply, data, &result);
|
||||
}
|
||||
|
||||
static void
|
||||
test_cereg2_novatel_lte_solicited (void *f, gpointer d)
|
||||
{
|
||||
RegTestData *data = (RegTestData *) d;
|
||||
const char *reply = "\r\n+CEREG: 2,1, 1F00, 20 ,79D903 ,7\r\n";
|
||||
const CregResult result = { 1, 0x1F00, 0x79D903, MM_MODEM_ACCESS_TECHNOLOGY_LTE, 10, FALSE, TRUE };
|
||||
|
||||
test_creg_match ("Novatel LTE E362 CEREG=2", TRUE, reply, data, &result);
|
||||
}
|
||||
|
||||
static void
|
||||
test_cereg2_novatel_lte_unsolicited (void *f, gpointer d)
|
||||
{
|
||||
RegTestData *data = (RegTestData *) d;
|
||||
const char *reply = "\r\n+CEREG: 1, 1F00, 20 ,79D903 ,7\r\n";
|
||||
const CregResult result = { 1, 0x1F00, 0x79D903, MM_MODEM_ACCESS_TECHNOLOGY_LTE, 9, FALSE, TRUE };
|
||||
|
||||
test_creg_match ("Novatel LTE E362 CEREG=2", FALSE, reply, data, &result);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Test CSCS responses */
|
||||
|
||||
@@ -1617,6 +1679,13 @@ int main (int argc, char **argv)
|
||||
g_test_suite_add (suite, TESTCASE (test_cgreg2_x220_unsolicited, reg_data));
|
||||
g_test_suite_add (suite, TESTCASE (test_cgreg2_unsolicited_with_rac, reg_data));
|
||||
|
||||
g_test_suite_add (suite, TESTCASE (test_cereg1_solicited, reg_data));
|
||||
g_test_suite_add (suite, TESTCASE (test_cereg1_unsolicited, reg_data));
|
||||
g_test_suite_add (suite, TESTCASE (test_cereg2_solicited, reg_data));
|
||||
g_test_suite_add (suite, TESTCASE (test_cereg2_unsolicited, reg_data));
|
||||
g_test_suite_add (suite, TESTCASE (test_cereg2_novatel_lte_solicited, reg_data));
|
||||
g_test_suite_add (suite, TESTCASE (test_cereg2_novatel_lte_unsolicited, reg_data));
|
||||
|
||||
g_test_suite_add (suite, TESTCASE (test_creg_cgreg_multi_unsolicited, reg_data));
|
||||
g_test_suite_add (suite, TESTCASE (test_creg_cgreg_multi2_unsolicited, reg_data));
|
||||
|
||||
|
Reference in New Issue
Block a user