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



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.

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
>         > >
>         > >
>         >
>         >
>         
>         
>         
> 
> 




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