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



On Wed, 2013-02-13 at 08:06 -0600, Dan Williams wrote:
On Tue, 2013-02-12 at 18:42 -0800, Ben Chan wrote:
Dan,


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

Sure, can do.

The V2 patch doesn't seem to cause problems with the ADU960, but then
again, I don't have access to the LTE networks it can use (AT&T and
Lightsquared).  After patching the code to unconditionally enable CEREG,
the device responds correctly to CEREG requests:

AT+CEREG=2
OK
AT+CEREG?
+CEREG: 2,1
OK

when I'm registered on T-Mobile's GSM network.  So while I'd really like
to have us try CEREG unconditionally if we can, I'm fine with the V2
patch as it is.

Dan

Dan



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 = (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));
        > >
        > >     --
        > >     1.8.1
        > >
        > >
        >
        >
        
        
        




_______________________________________________
networkmanager-list mailing list
networkmanager-list gnome org
https://mail.gnome.org/mailman/listinfo/networkmanager-list




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