Re: [MM] [PATCH] modem: use +CEREG to determine EPS network registration status



Dan,

Will you be able to test my patch v2 on some of the modems you mentioned?

Thanks,
Ben


On Tue, Feb 12, 2013 at 4:19 PM, Dan Williams <dcbw redhat com> wrote:
On Tue, 2013-02-12 at 08:47 +0100, Aleksander Morgado wrote:
> On 02/11/2013 07:44 PM, Ben Chan wrote:
> > Aleksander and Dan,
> >
> > How do you feel about this patch?
> >
>
>
> Doesn't look bad, but I really need to read it carefully as it changed
> lots of things. The idea is that plugins can specify whether they
> require CEREG by setting MM_IFACE_MODEM_3GPP_EPS_NETWORK_SUPPORTED to
> TRUE themselves, instead of automatically trying it when LTE support is
> found, right? I now wonder how other AT-controlled LTE modems out there,
> not just the Novatel LTE, handle this. Is anyone willing to give it a
> try with other LTE modems?

ADU960S supports CEREG.  So does the UML290 with latest firmware.
There's quite a few modems that support it, which is why I was
suggesting that maybe we should use CEREG automatically on modems that
support that command.

Dan

>
> >
> >
> > On Wed, Feb 6, 2013 at 3:15 PM, Ben Chan <benchan chromium org
> > <mailto:benchan chromium org>> wrote:
> >
> >     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.
> >     ---
> >      src/mm-broadband-modem-qmi.c   |   3 +
> >      src/mm-broadband-modem.c       | 165
> >     +++++++++++++++++++++++++++++++++++------
> >      src/mm-iface-modem-3gpp.c      |  51 ++++++++++++-
> >      src/mm-iface-modem-3gpp.h      |  10 ++-
> >      src/mm-modem-helpers.c         |  82 +++++++++++++++-----
> >      src/mm-modem-helpers.h         |   1 +
> >      src/tests/test-modem-helpers.c | 121 +++++++++++++++++++++++-------
> >      7 files changed, 365 insertions(+), 68 deletions(-)
> >
> >     diff --git a/src/mm-broadband-modem-qmi.c b/src/mm-broadband-modem-qmi.c
> >     index aa82f0e..05be718 100644
> >     --- a/src/mm-broadband-modem-qmi.c
> >     +++ b/src/mm-broadband-modem-qmi.c
> >     @@ -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)
> >      {
> >     diff --git a/src/mm-broadband-modem.c b/src/mm-broadband-modem.c
> >     index 3778b56..505c42a 100644
> >     --- a/src/mm-broadband-modem.c
> >     +++ b/src/mm-broadband-modem.c
> >     @@ -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;
> >
> >     @@ -3280,6 +3282,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,
> >     @@ -3288,6 +3291,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)");
> >     @@ -3298,6 +3302,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);
> >
> >     @@ -3484,12 +3490,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
> >     @@ -3500,6 +3510,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);
> >     @@ -3526,22 +3538,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;
> >     @@ -3577,14 +3593,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;
> >     @@ -3595,6 +3614,7 @@ registration_status_check_ready
> >     (MMBroadbandModem *self,
> >                                                &cid,
> >                                                &act,
> >                                                &cgreg,
> >     +                                          &cereg,
> >                                                &error);
> >          g_match_info_free (match_info);
> >
> >     @@ -3606,8 +3626,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;
> >          }
> >     @@ -3616,10 +3638,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);
> >          }
> >
> >     @@ -3634,6 +3666,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;
> >     @@ -3661,12 +3694,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) {
> >     @@ -3684,6 +3734,7 @@ static void
> >      modem_3gpp_run_registration_checks (MMIfaceModem3gpp *self,
> >                                          gboolean cs_supported,
> >                                          gboolean ps_supported,
> >     +                                    gboolean eps_supported,
> >                                          GAsyncReadyCallback callback,
> >                                          gpointer user_data)
> >      {
> >     @@ -3697,8 +3748,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);
> >      }
> >     @@ -3712,10 +3765,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;
> >     @@ -3728,6 +3784,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);
> >     @@ -3738,6 +3796,7 @@ unsolicited_registration_events_context_new
> >     (MMBroadbandModem *self,
> >                                                   gboolean enable,
> >                                                   gboolean cs_supported,
> >                                                   gboolean ps_supported,
> >     +                                             gboolean eps_supported,
> >                                                   GAsyncReadyCallback
> >     callback,
> >                                                   gpointer user_data)
> >      {
> >     @@ -3752,6 +3811,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;
> >      }
> >     @@ -3811,6 +3871,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
> >     @@ -3823,8 +3897,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)
> >     @@ -3841,6 +3916,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 {
> >     @@ -3853,6 +3930,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 */
> >     @@ -3873,13 +3954,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 */
> >     @@ -3899,12 +3984,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 */
> >     @@ -3922,6 +4011,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) {
> >     @@ -3933,7 +4023,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;
> >     @@ -3948,16 +4038,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->ps_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) {
> >     @@ -3972,6 +4080,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)
> >      {
> >     @@ -3980,6 +4089,7 @@
> >     modem_3gpp_disable_unsolicited_registration_events (MMIfaceModem3gpp
> >     *self,
> >                                                           FALSE,
> >                                                           cs_supported,
> >                                                           ps_supported,
> >     +                                                     eps_supported,
> >                                                           callback,
> >                                                           user_data));
> >      }
> >     @@ -3988,6 +4098,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)
> >      {
> >     @@ -3996,6 +4107,7 @@
> >     modem_3gpp_enable_unsolicited_registration_events (MMIfaceModem3gpp
> >     *self,
> >                                                           TRUE,
> >                                                           cs_supported,
> >                                                           ps_supported,
> >     +                                                     eps_supported,
> >                                                           callback,
> >                                                           user_data));
> >      }
> >     @@ -8735,6 +8847,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;
> >     @@ -8821,6 +8936,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;
> >     @@ -8864,6 +8982,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;
> >     @@ -9223,6 +9342,10 @@ mm_broadband_modem_class_init
> >     (MMBroadbandModemClass *klass)
> >
> >      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);
> >
> >     diff --git a/src/mm-iface-modem-3gpp.c b/src/mm-iface-modem-3gpp.c
> >     index 7a88b2f..7117e9c 100644
> >     --- a/src/mm-iface-modem-3gpp.c
> >     +++ b/src/mm-iface-modem-3gpp.c
> >     @@ -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;
> >      }
> >
> >     diff --git a/src/mm-iface-modem-3gpp.h b/src/mm-iface-modem-3gpp.h
> >     index d706f1a..caf2575 100644
> >     --- a/src/mm-iface-modem-3gpp.h
> >     +++ b/src/mm-iface-modem-3gpp.h
> >     @@ -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,
> >     diff --git a/src/mm-modem-helpers.c b/src/mm-modem-helpers.c
> >     index e8c8f88..cedd2b7 100644
> >     --- a/src/mm-modem-helpers.c
> >     +++ b/src/mm-modem-helpers.c
> >     @@ -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;
> >     +        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 = 5;
> >     -            iact = 6;
> >     +            ici = 6;
> >     +            iact = 7;
> >              }
> >           }
> >
> >     diff --git a/src/mm-modem-helpers.h b/src/mm-modem-helpers.h
> >     index e66f259..63e53a7 100644
> >     --- a/src/mm-modem-helpers.h
> >     +++ b/src/mm-modem-helpers.h
> >     @@ -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 */
> >     diff --git a/src/tests/test-modem-helpers.c
> >     b/src/tests/test-modem-helpers.c
> >     index fdd336c..6cfac3d 100644
> >     --- a/src/tests/test-modem-helpers.c
> >     +++ b/src/tests/test-modem-helpers.c
> >     @@ -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 = "" *) 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 = "" *) 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 = "" *) 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 = "" *) 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 = "" *) 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 = "" *) 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 = "" *) 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 = "" *) 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 = "" *) 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 = "" *) 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 = "" *) 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 = "" *) 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 = "" *) 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 = "" *) 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 = "" *) 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 = "" *) 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 = "" *) 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 = "" *) 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 = "" *) 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 = "" *) 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 = "" *) 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 = "" *) 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 = "" *) 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 = "" *) 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 = "" *) 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 = "" *) 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 = "" *) 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 = "" *) 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 = "" *) 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 = "" *) 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));
> >
> >     --
> >     1.8.1
> >
> >
>
>





[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]