Hi,

Here is a log showing why this is needed, no CREG for more than 30 minutes
when changing tech from UTRAN to E-UTRAN.

This happens on a L210, but as I understood Jonas, and comments
in the code, the L4xx suffers from similar issues, so I added this for both
L4
and L2.


Sep 23 21:45:37 info : Aux: < \r\n+CIEV: 2,3\r\n
Sep 23 21:59:29 info : Aux: < \r\n+CGREG: 4\r\n
Sep 23 21:59:29 debug : ../git/src/gprs.c:ofono_gprs_status_notify()
/ublox_0 status unknown (4)
Sep 23 21:59:29 debug : ../git/src/gprs.c:ofono_gprs_detached_notify()
/ublox_0
Sep 23 21:59:29 info : Aux: < \r\n+UREG: 0\r\n
Sep 23 21:59:29 info : Aux: < \r\n+CIEV: 9,1\r\n

We get an UREG URC indicating E-UTRAN,.

Sep 23 21:59:29 info : Aux: < \r\n+UREG: 7\r\n
Sep 23 21:59:29 info : Aux: < \r\n+CIEV: 9,2\r\n
Sep 23 21:59:29 info : Aux: < \r\n+CGEV: NW MODIFY 1,0,0\r\n
Sep 23 21:59:31 info : Aux: < \r\n+CIEV: 2,2\r\n
Sep 23 21:59:39 info : Aux: < \r\n+CIEV: 2,3\r\n
Sep 23 21:59:44 info : Aux: < \r\n+CIEV: 2,2\r\n
Sep 23 22:01:38 info : Aux: < \r\n+CIEV: 2,3\r\n
Sep 23 22:01:43 info : Aux: < \r\n+CIEV: 2,2\r\n

CREG After 30+ minutes!! Indicating UTRAN (which is incorrect, but worked
around in another commit)

Sep 23 22:29:39 info : Aux: < \r\n+CREG: 5,"0000","00000000",6\r\n

BR
Richard

Den sön 29 sep. 2019 kl 21:40 skrev <[email protected]>:

> From: Richard Röjfors <[email protected]>
>
> It turns out that both L2xx and L4xx modems are a bit
> buggy when it comes to send CREG URC's when the tech changes.
> Try to overcome this by subscribing to both UREG and CREG,
> and poll the other when any of the URC's are received.
> Protect from doing simultanious polls though.
> ---
>  drivers/ubloxmodem/network-registration.c | 198 ++++++++++++++++------
>  1 file changed, 148 insertions(+), 50 deletions(-)
>
> diff --git a/drivers/ubloxmodem/network-registration.c
> b/drivers/ubloxmodem/network-registration.c
> index 69af4644..ad905fb3 100644
> --- a/drivers/ubloxmodem/network-registration.c
> +++ b/drivers/ubloxmodem/network-registration.c
> @@ -47,11 +47,15 @@
>  static const char *none_prefix[] = { NULL };
>  static const char *cmer_prefix[] = { "+CMER:", NULL };
>  static const char *ureg_prefix[] = { "+UREG:", NULL };
> +static const char *creg_prefix[] = { "+CREG:", NULL };
> +
> +#define UBLOX_UPDATING_STATUS 0x01
>
>  struct netreg_data {
>         struct at_netreg_data at_data;
>
>         const struct ublox_model *model;
> +       int flags;
>  };
>
>  struct tech_query {
> @@ -213,13 +217,72 @@ static void ctze_notify(GAtResult *result, gpointer
> user_data)
>         ofono_netreg_time_notify(netreg, &nd->time);
>  }
>
> -static void ublox_query_tech_cb(gboolean ok, GAtResult *result,
> +static int ublox_ureg_state_to_tech(int state)
> +{
> +       switch (state) {
> +       case 1:
> +               return ACCESS_TECHNOLOGY_GSM;
> +       case 2:
> +               return ACCESS_TECHNOLOGY_GSM_EGPRS;
> +       case 3:
> +               return ACCESS_TECHNOLOGY_UTRAN;
> +       case 4:
> +               return ACCESS_TECHNOLOGY_UTRAN_HSDPA;
> +       case 5:
> +               return ACCESS_TECHNOLOGY_UTRAN_HSUPA;
> +       case 6:
> +               return ACCESS_TECHNOLOGY_UTRAN_HSDPA_HSUPA;
> +       case 7:
> +               return ACCESS_TECHNOLOGY_EUTRAN;
> +       case 8:
> +               return ACCESS_TECHNOLOGY_GSM;
> +       case 9:
> +               return ACCESS_TECHNOLOGY_GSM_EGPRS;
> +       default:
> +               /* Not registered for PS (0) or something unknown (>9)...
> */
> +               return -1;
> +       }
> +}
> +
> +static gboolean is_registered(int status)
> +{
> +       return status == NETWORK_REGISTRATION_STATUS_REGISTERED ||
> +               status == NETWORK_REGISTRATION_STATUS_ROAMING;
> +}
> +
> +static void ublox_creg_cb(gboolean ok, GAtResult *result,
> +                               gpointer user_data)
> +{
> +       struct tech_query *tq = user_data;
> +       struct netreg_data *nd = ofono_netreg_get_data(tq->netreg);
> +       int status, lac, ci, tech;
> +
> +       nd->flags &= ~UBLOX_UPDATING_STATUS;
> +
> +       if (!ok)
> +               return;
> +
> +       if (at_util_parse_reg(result, "+CREG:", NULL, &status,
> +                               &lac, &ci, &tech, OFONO_VENDOR_GENERIC) ==
> FALSE)
> +               return;
> +
> +       /* The query provided a tech, use that */
> +       if (is_registered(status) && tq->tech != -1)
> +               tech = tq->tech;
> +
> +       ofono_netreg_status_notify(tq->netreg, status, lac, ci, tech);
> +}
> +
> +static void ublox_ureg_cb(gboolean ok, GAtResult *result,
>                                                         gpointer user_data)
>  {
>         struct tech_query *tq = user_data;
> +       struct netreg_data *nd = ofono_netreg_get_data(tq->netreg);
>         GAtResultIter iter;
>         gint enabled, state;
> -       int tech = -1;
> +       int tech = tq->tech;
> +
> +       nd->flags &= ~UBLOX_UPDATING_STATUS;
>
>         if (!ok)
>                 goto error;
> @@ -235,48 +298,49 @@ static void ublox_query_tech_cb(gboolean ok,
> GAtResult *result,
>         if (!g_at_result_iter_next_number(&iter, &state))
>                 return;
>
> -       switch (state) {
> -       case 0:
> -               /* Not registered for PS, then we have to trust CREG... */
> -               tech = tq->tech;
> -               break;
> -       case 1:
> -               tech = ACCESS_TECHNOLOGY_GSM;
> -               break;
> -       case 2:
> -               tech = ACCESS_TECHNOLOGY_GSM_EGPRS;
> -               break;
> -       case 3:
> -               tech = ACCESS_TECHNOLOGY_UTRAN;
> -               break;
> -       case 4:
> -               tech = ACCESS_TECHNOLOGY_UTRAN_HSDPA;
> -               break;
> -       case 5:
> -               tech = ACCESS_TECHNOLOGY_UTRAN_HSUPA;
> -               break;
> -       case 6:
> -               tech = ACCESS_TECHNOLOGY_UTRAN_HSDPA_HSUPA;
> -               break;
> -       case 7:
> -               tech = ACCESS_TECHNOLOGY_EUTRAN;
> -               break;
> -       case 8:
> -               tech = ACCESS_TECHNOLOGY_GSM;
> -               break;
> -       case 9:
> -               tech = ACCESS_TECHNOLOGY_GSM_EGPRS;
> -               break;
> -       default:
> -               /* Not registered for PS or something unknown, trust
> CREG... */
> +       tech = ublox_ureg_state_to_tech(state);
> +       if (tech < 0)
> +               /* No valid UREG status, we have to trust CREG... */
>                 tech = tq->tech;
> -       }
>
>  error:
>         ofono_netreg_status_notify(tq->netreg,
>                         tq->status, tq->lac, tq->ci, tech);
>  }
>
> +static void ureg_notify(GAtResult *result, gpointer user_data)
> +{
> +       struct ofono_netreg *netreg = user_data;
> +       int state;
> +       struct netreg_data *nd = ofono_netreg_get_data(netreg);
> +       struct tech_query *tq;
> +       GAtResultIter iter;
> +
> +       if (nd->flags & UBLOX_UPDATING_STATUS)
> +               return;
> +
> +       g_at_result_iter_init(&iter, result);
> +
> +       if (!g_at_result_iter_next(&iter, "+UREG:"))
> +               return;
> +
> +       if (!g_at_result_iter_next_number(&iter, &state))
> +               return;
> +
> +       tq = g_new0(struct tech_query, 1);
> +
> +       tq->tech = ublox_ureg_state_to_tech(state);
> +       tq->netreg = netreg;
> +
> +       if (g_at_chat_send(nd->at_data.chat, "AT+CREG?", creg_prefix,
> +                       ublox_creg_cb, tq, g_free) > 0) {
> +               nd->flags |= UBLOX_UPDATING_STATUS;
> +               return;
> +       }
> +
> +       g_free(tq);
> +}
> +
>  static void creg_notify(GAtResult *result, gpointer user_data)
>  {
>         struct ofono_netreg *netreg = user_data;
> @@ -284,11 +348,14 @@ static void creg_notify(GAtResult *result, gpointer
> user_data)
>         struct netreg_data *nd = ofono_netreg_get_data(netreg);
>         struct tech_query *tq;
>
> +       if (nd->flags & UBLOX_UPDATING_STATUS)
> +               return;
> +
>         if (at_util_parse_reg_unsolicited(result, "+CREG:", &status,
>                         &lac, &ci, &tech, OFONO_VENDOR_GENERIC) == FALSE)
>                 return;
>
> -       if (status != 1 && status != 5)
> +       if (!is_registered(status))
>                 goto notify;
>
>         if (ublox_is_toby_l4(nd->model) || ublox_is_toby_l2(nd->model)) {
> @@ -301,13 +368,15 @@ static void creg_notify(GAtResult *result, gpointer
> user_data)
>                 tq->netreg = netreg;
>
>                 if (g_at_chat_send(nd->at_data.chat, "AT+UREG?",
> ureg_prefix,
> -                               ublox_query_tech_cb, tq, g_free) > 0)
> +                               ublox_ureg_cb, tq, g_free) > 0) {
> +                       nd->flags |= UBLOX_UPDATING_STATUS;
>                         return;
> +               }
>
>                 g_free(tq);
>         }
>
> -       if ((status == 1 || status == 5) && tech == -1)
> +       if (tech == -1)
>                 tech = nd->at_data.tech;
>
>  notify:
> @@ -322,24 +391,56 @@ static void at_cmer_not_supported(struct
> ofono_netreg *netreg)
>         ofono_netreg_remove(netreg);
>  }
>
> +static void ublox_finish_registration(struct ofono_netreg *netreg)
> +{
> +       struct netreg_data *nd = ofono_netreg_get_data(netreg);
> +
> +       if (ublox_is_toby_l4(nd->model) || ublox_is_toby_l2(nd->model))
> +               g_at_chat_register(nd->at_data.chat, "+UREG:",
> +                                       ureg_notify, FALSE, netreg, NULL);
> +
> +       g_at_chat_register(nd->at_data.chat, "+CIEV:",
> +                       ciev_notify, FALSE, netreg, NULL);
> +
> +       g_at_chat_register(nd->at_data.chat, "+CREG:",
> +                               creg_notify, FALSE, netreg, NULL);
> +
> +       ofono_netreg_register(netreg);
> +}
> +
> +static void ublox_ureg_set_cb(gboolean ok,
> +                               GAtResult *result, gpointer user_data)
> +{
> +       struct ofono_netreg *netreg = user_data;
> +
> +       if (!ok) {
> +               ofono_error("Unable to initialize Network Registration");
> +               ofono_netreg_remove(netreg);
> +               return;
> +       }
> +
> +       ublox_finish_registration(netreg);
> +}
> +
>  static void ublox_cmer_set_cb(gboolean ok,
>                                 GAtResult *result, gpointer user_data)
>  {
>         struct ofono_netreg *netreg = user_data;
> -       struct at_netreg_data *nd = ofono_netreg_get_data(netreg);
> +       struct netreg_data *nd = ofono_netreg_get_data(netreg);
>
>         if (!ok) {
>                 at_cmer_not_supported(netreg);
>                 return;
>         }
>
> -       g_at_chat_register(nd->chat, "+CIEV:",
> -                       ciev_notify, FALSE, netreg, NULL);
> +       if (ublox_is_toby_l4(nd->model) || ublox_is_toby_l2(nd->model)) {
> +               g_at_chat_send(nd->at_data.chat, "AT+UREG=1", none_prefix,
> +                       ublox_ureg_set_cb, netreg, NULL);
>
> -       g_at_chat_register(nd->chat, "+CREG:",
> -                               creg_notify, FALSE, netreg, NULL);
> +               return;
> +       }
>
> -       ofono_netreg_register(netreg);
> +       ublox_finish_registration(netreg);
>  }
>
>  static void ublox_creg_set_cb(gboolean ok,
> @@ -354,12 +455,9 @@ static void ublox_creg_set_cb(gboolean ok,
>                 return;
>         }
>
> -       if (ublox_is_toby_l4(nd->model)) {
> +       if (ublox_is_toby_l4(nd->model))
>                 /* FIXME */
>                 ofono_error("TOBY L4 requires polling of ECSQ");
> -               ofono_error("TOBY L4 wants UREG notifications for"
> -                               " tech updates");
> -       }
>
>         /* Register for network time update reports */
>         if (ublox_is_toby_l2(nd->model)) {
> --
> 2.20.1
>
>
_______________________________________________
ofono mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to