Merge request !1480 from 'creg_urc'
modem-helpers: fix multiple C*REG events in single URC https://gitlab.freedesktop.org/mobile-broadband/ModemManager/-/merge_requests/1480 Closes #1087
This commit is contained in:
+13
-34
@@ -218,7 +218,7 @@ struct _MMBroadbandModemPrivate {
|
||||
gboolean modem_3gpp_eps_network_supported;
|
||||
gboolean modem_3gpp_5gs_network_supported;
|
||||
/* Implementation helpers */
|
||||
GPtrArray *modem_3gpp_registration_regex;
|
||||
GRegex *modem_3gpp_registration_regex;
|
||||
MMModem3gppFacility modem_3gpp_ignored_facility_locks;
|
||||
MMBaseBearer *modem_3gpp_initial_eps_bearer;
|
||||
MMModem3gppPacketServiceState modem_3gpp_packet_service_state;
|
||||
@@ -5267,32 +5267,28 @@ modem_3gpp_setup_unsolicited_registration_events (MMIfaceModem3gpp *self,
|
||||
gpointer user_data)
|
||||
{
|
||||
MMPortSerialAt *ports[2];
|
||||
GPtrArray *array;
|
||||
g_autoptr(GRegex) regex = NULL;
|
||||
guint i;
|
||||
guint j;
|
||||
GTask *task;
|
||||
|
||||
ports[0] = mm_base_modem_peek_port_primary (MM_BASE_MODEM (self));
|
||||
ports[1] = mm_base_modem_peek_port_secondary (MM_BASE_MODEM (self));
|
||||
|
||||
/* Set up CREG unsolicited message handlers in both ports */
|
||||
array = mm_3gpp_creg_regex_get (FALSE);
|
||||
regex = mm_3gpp_creg_regex_get (FALSE);
|
||||
for (i = 0; i < 2; i++) {
|
||||
if (!ports[i])
|
||||
continue;
|
||||
|
||||
mm_obj_dbg (self, "setting up 3GPP unsolicited registration messages handlers in %s",
|
||||
mm_port_get_device (MM_PORT (ports[i])));
|
||||
for (j = 0; j < array->len; j++) {
|
||||
mm_port_serial_at_add_unsolicited_msg_handler (
|
||||
MM_PORT_SERIAL_AT (ports[i]),
|
||||
(GRegex *) g_ptr_array_index (array, j),
|
||||
regex,
|
||||
(MMPortSerialAtUnsolicitedMsgFn)registration_state_changed,
|
||||
self,
|
||||
NULL);
|
||||
}
|
||||
}
|
||||
mm_3gpp_creg_regex_destroy (array);
|
||||
|
||||
task = g_task_new (self, NULL, callback, user_data);
|
||||
g_task_return_boolean (task, TRUE);
|
||||
@@ -5316,32 +5312,28 @@ modem_3gpp_cleanup_unsolicited_registration_events (MMIfaceModem3gpp *self,
|
||||
gpointer user_data)
|
||||
{
|
||||
MMPortSerialAt *ports[2];
|
||||
GPtrArray *array;
|
||||
g_autoptr(GRegex) regex = NULL;
|
||||
guint i;
|
||||
guint j;
|
||||
GTask *task;
|
||||
|
||||
ports[0] = mm_base_modem_peek_port_primary (MM_BASE_MODEM (self));
|
||||
ports[1] = mm_base_modem_peek_port_secondary (MM_BASE_MODEM (self));
|
||||
|
||||
/* Set up CREG unsolicited message handlers in both ports */
|
||||
array = mm_3gpp_creg_regex_get (FALSE);
|
||||
regex = mm_3gpp_creg_regex_get (FALSE);
|
||||
for (i = 0; i < 2; i++) {
|
||||
if (!ports[i])
|
||||
continue;
|
||||
|
||||
mm_obj_dbg (self, "cleaning up unsolicited registration messages handlers in %s",
|
||||
mm_port_get_device (MM_PORT (ports[i])));
|
||||
for (j = 0; j < array->len; j++) {
|
||||
mm_port_serial_at_add_unsolicited_msg_handler (
|
||||
MM_PORT_SERIAL_AT (ports[i]),
|
||||
(GRegex *) g_ptr_array_index (array, j),
|
||||
regex,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
}
|
||||
}
|
||||
mm_3gpp_creg_regex_destroy (array);
|
||||
|
||||
task = g_task_new (self, NULL, callback, user_data);
|
||||
g_task_return_boolean (task, TRUE);
|
||||
@@ -5608,7 +5600,6 @@ registration_status_check_ready (MMBroadbandModem *self,
|
||||
RunRegistrationChecksContext *ctx;
|
||||
const gchar *response;
|
||||
GError *error = NULL;
|
||||
guint i;
|
||||
gboolean parsed;
|
||||
gboolean cgreg = FALSE;
|
||||
gboolean cereg = FALSE;
|
||||
@@ -5641,18 +5632,10 @@ registration_status_check_ready (MMBroadbandModem *self,
|
||||
}
|
||||
|
||||
/* Try to match the response */
|
||||
for (i = 0;
|
||||
i < self->priv->modem_3gpp_registration_regex->len;
|
||||
i++) {
|
||||
if (g_regex_match ((GRegex *)g_ptr_array_index (self->priv->modem_3gpp_registration_regex, i),
|
||||
if (!g_regex_match (self->priv->modem_3gpp_registration_regex,
|
||||
response,
|
||||
0,
|
||||
&match_info))
|
||||
break;
|
||||
g_clear_pointer (&match_info, g_match_info_free);
|
||||
}
|
||||
|
||||
if (!match_info) {
|
||||
&match_info)) {
|
||||
error = g_error_new (MM_CORE_ERROR,
|
||||
MM_CORE_ERROR_FAILED,
|
||||
"Unknown registration status response: '%s'",
|
||||
@@ -11704,9 +11687,8 @@ setup_ports (MMBroadbandModem *self)
|
||||
g_autoptr(GRegex) ciev_regex = NULL;
|
||||
g_autoptr(GRegex) cmti_regex = NULL;
|
||||
g_autoptr(GRegex) cusd_regex = NULL;
|
||||
GPtrArray *array;
|
||||
g_autoptr(GRegex) creg_regex = NULL;
|
||||
guint i;
|
||||
guint j;
|
||||
|
||||
ports[0] = mm_base_modem_peek_port_primary (MM_BASE_MODEM (self));
|
||||
ports[1] = mm_base_modem_peek_port_secondary (MM_BASE_MODEM (self));
|
||||
@@ -11722,7 +11704,7 @@ setup_ports (MMBroadbandModem *self)
|
||||
NULL);
|
||||
|
||||
/* Cleanup all unsolicited message handlers in all AT ports */
|
||||
array = mm_3gpp_creg_regex_get (FALSE);
|
||||
creg_regex = mm_3gpp_creg_regex_get (FALSE);
|
||||
ciev_regex = mm_3gpp_ciev_regex_get ();
|
||||
cmti_regex = mm_3gpp_cmti_regex_get ();
|
||||
cusd_regex = mm_3gpp_cusd_regex_get ();
|
||||
@@ -11731,14 +11713,11 @@ setup_ports (MMBroadbandModem *self)
|
||||
if (!ports[i])
|
||||
continue;
|
||||
|
||||
for (j = 0; j < array->len; j++)
|
||||
mm_port_serial_at_add_unsolicited_msg_handler (MM_PORT_SERIAL_AT (ports[i]), (GRegex *)g_ptr_array_index (array, j), NULL, NULL, NULL);
|
||||
mm_port_serial_at_add_unsolicited_msg_handler (MM_PORT_SERIAL_AT (ports[i]), creg_regex, NULL, NULL, NULL);
|
||||
mm_port_serial_at_add_unsolicited_msg_handler (MM_PORT_SERIAL_AT (ports[i]), ciev_regex, NULL, NULL, NULL);
|
||||
mm_port_serial_at_add_unsolicited_msg_handler (MM_PORT_SERIAL_AT (ports[i]), cmti_regex, NULL, NULL, NULL);
|
||||
mm_port_serial_at_add_unsolicited_msg_handler (MM_PORT_SERIAL_AT (ports[i]), cusd_regex, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
mm_3gpp_creg_regex_destroy (array);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
@@ -14284,7 +14263,7 @@ finalize (GObject *object)
|
||||
ports_context_unref (self->priv->in_call_ports_ctx);
|
||||
|
||||
if (self->priv->modem_3gpp_registration_regex)
|
||||
mm_3gpp_creg_regex_destroy (self->priv->modem_3gpp_registration_regex);
|
||||
g_regex_unref (self->priv->modem_3gpp_registration_regex);
|
||||
|
||||
g_free (self->priv->carrier_config_mapping);
|
||||
|
||||
|
||||
+129
-122
@@ -900,35 +900,24 @@ static const gchar *creg_regex[] = {
|
||||
[13] = "\\+(C5GREG):\\s*([0-9]+)\\s*,\\s*([0-9+])\\s*,\\s*([^,\\s]*)\\s*,\\s*([^,\\s]*)\\s*,\\s*([0-9]+)\\s*,\\s*([^,\\s]*)\\s*,\\s*([^,\\s]*)",
|
||||
};
|
||||
|
||||
GPtrArray *
|
||||
GRegex *
|
||||
mm_3gpp_creg_regex_get (gboolean solicited)
|
||||
{
|
||||
GPtrArray *array;
|
||||
g_autoptr(GString) pattern = NULL;
|
||||
guint i;
|
||||
|
||||
array = g_ptr_array_sized_new (G_N_ELEMENTS (creg_regex));
|
||||
pattern = g_string_sized_new(4096);
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (creg_regex); i++) {
|
||||
GRegex *regex;
|
||||
g_autofree gchar *pattern = NULL;
|
||||
|
||||
if (solicited) {
|
||||
pattern = g_strdup_printf ("%s$", creg_regex[i]);
|
||||
regex = g_regex_new (pattern, G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
|
||||
g_string_append_printf (pattern, "%s$|", creg_regex[i]);
|
||||
} else {
|
||||
pattern = g_strdup_printf ("\\r\\n%s\\r\\n", creg_regex[i]);
|
||||
regex = g_regex_new (pattern, G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
|
||||
g_string_append_printf (pattern, "\\r\\n%s\\r\\n|", creg_regex[i]);
|
||||
}
|
||||
g_assert (regex);
|
||||
g_ptr_array_add (array, regex);
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
void
|
||||
mm_3gpp_creg_regex_destroy (GPtrArray *array)
|
||||
{
|
||||
g_ptr_array_foreach (array, (GFunc) g_regex_unref, NULL);
|
||||
g_ptr_array_free (array, TRUE);
|
||||
/* truncate last | char */
|
||||
g_string_truncate (pattern, pattern->len - 1);
|
||||
return g_regex_new (pattern->str, G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
@@ -2013,20 +2002,6 @@ mm_3gpp_parse_cgact_read_response (const gchar *reply,
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
static gboolean
|
||||
item_is_lac_not_stat (GMatchInfo *info, guint32 item)
|
||||
{
|
||||
gchar *str;
|
||||
gboolean is_lac = FALSE;
|
||||
|
||||
/* A <stat> will always be a digit < 100, without quotes */
|
||||
str = g_match_info_fetch (info, item);
|
||||
g_assert (str);
|
||||
is_lac = (strchr (str, '"') || strlen (str) > 2);
|
||||
g_free (str);
|
||||
return is_lac;
|
||||
}
|
||||
|
||||
gboolean
|
||||
mm_3gpp_parse_creg_response (GMatchInfo *info,
|
||||
gpointer log_object,
|
||||
@@ -2042,7 +2017,7 @@ mm_3gpp_parse_creg_response (GMatchInfo *info,
|
||||
gint n_matches, act = -1;
|
||||
guint stat = 0;
|
||||
guint64 lac = 0, ci = 0;
|
||||
guint istat = 0, ilac = 0, ici = 0, iact = 0;
|
||||
guint ireg = 0, istat = 0, ilac = 0, ici = 0, iact = 0;
|
||||
gchar *str;
|
||||
|
||||
g_assert (info != NULL);
|
||||
@@ -2054,98 +2029,130 @@ mm_3gpp_parse_creg_response (GMatchInfo *info,
|
||||
g_assert (out_cereg != NULL);
|
||||
g_assert (out_c5greg != NULL);
|
||||
|
||||
str = g_match_info_fetch (info, 1);
|
||||
/* Each regex in the array adds to the number of matches (e.g. first regex
|
||||
* will match in indices 1 and 2, but second regex will use indices 3/4/5
|
||||
* etc), so we "just" need to process each regex in order */
|
||||
n_matches = g_match_info_get_match_count (info);
|
||||
switch (n_matches) {
|
||||
case 3:
|
||||
/* +CREG: <stat> (GSM 07.07 CREG=1 unsolicited) */
|
||||
/* [0] = "\\+(CREG|CGREG|CEREG|C5GREG):\\s*0*([0-9])", */
|
||||
ireg = n_matches - 2;
|
||||
istat = n_matches - 1;
|
||||
break;
|
||||
case 6:
|
||||
/* +CREG: <n>,<stat> (GSM 07.07 CREG=1 solicited) */
|
||||
/* [1] = "\\+(CREG|CGREG|CEREG|C5GREG):\\s*0*([0-9]),\\s*0*([0-9])", */
|
||||
ireg = n_matches - 3;
|
||||
istat = n_matches - 1;
|
||||
break;
|
||||
case 10:
|
||||
/* +CREG: <stat>,<lac>,<ci> (GSM 07.07 CREG=2 unsolicited) */
|
||||
/* [2] = "\\+(CREG|CGREG|CEREG):\\s*0*([0-9]),\\s*([^,\\s]*)\\s*,\\s*([^,\\s]*)", */
|
||||
ireg = n_matches - 4;
|
||||
istat = n_matches - 3;
|
||||
ilac = n_matches - 2;
|
||||
ici = n_matches - 1;
|
||||
break;
|
||||
case 15:
|
||||
case 20:
|
||||
/* +CREG: <n>,<stat>,<lac>,<ci> (GSM 07.07 solicited and some CREG=2 unsolicited) */
|
||||
/* [3] = "\\+(CREG|CGREG|CEREG):\\s*([0-9]),\\s*([0-9])\\s*,\\s*([^,]*)\\s*,\\s*([^,\\s]*)", */
|
||||
/* [4] = "\\+(CREG|CGREG|CEREG):\\s*0*([0-9]),\\s*0*([0-9])\\s*,\\s*(\"[^,]*\")\\s*,\\s*(\"[^,\\s]*\")", */
|
||||
ireg = n_matches - 5;
|
||||
istat = n_matches - 3;
|
||||
ilac = n_matches - 2;
|
||||
ici = n_matches - 1;
|
||||
break;
|
||||
case 25:
|
||||
case 30:
|
||||
/* +CREG: <stat>,<lac>,<ci>,<AcT> (ETSI 27.007 CREG=2 unsolicited) */
|
||||
/* [5] = "\\+(CREG|CGREG|CEREG):\\s*([0-9])\\s*,\\s*([^,\\s]*)\\s*,\\s*([^,\\s]*)\\s*,\\s*([0-9])", */
|
||||
/* [6] = "\\+(CREG|CGREG|CEREG):\\s*0*([0-9])\\s*,\\s*(\"[^,\\s]*\")\\s*,\\s*(\"[^,\\s]*\")\\s*,\\s*0*([0-9])", */
|
||||
ireg = n_matches - 5;
|
||||
istat = n_matches - 4;
|
||||
ilac = n_matches - 3;
|
||||
ici = n_matches - 2;
|
||||
iact = n_matches - 1;
|
||||
break;
|
||||
case 36:
|
||||
/* +CREG: <n>,<stat>,<lac>,<ci>,<AcT> (ETSI 27.007 solicited and some CREG=2 unsolicited) */
|
||||
/* [7] = "\\+(CREG|CGREG|CEREG):\\s*0*([0-9]),\\s*0*([0-9])\\s*,\\s*([^,\\s]*)\\s*,\\s*([^,\\s]*)\\s*,\\s*0*([0-9])", */
|
||||
ireg = n_matches - 6;
|
||||
istat = n_matches - 4;
|
||||
ilac = n_matches - 3;
|
||||
ici = n_matches - 2;
|
||||
iact = n_matches - 1;
|
||||
break;
|
||||
case 42:
|
||||
/* +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>' */
|
||||
/* [8] = "\\+(CREG|CGREG):\\s*0*([0-9]),\\s*0*([0-9])\\s*,\\s*([^,\\s]*)\\s*,\\s*([^,\\s]*)\\s*,\\s*([^,\\s]*)\\s*,\\s*[^,\\s]*", */
|
||||
ireg = n_matches - 6;
|
||||
istat = n_matches - 4;
|
||||
ilac = n_matches - 3;
|
||||
ici = n_matches - 2;
|
||||
iact = n_matches - 1;
|
||||
break;
|
||||
case 48:
|
||||
/* +CREG: <stat>,<lac>,<ci>,<AcT>,<RAC> (ETSI 27.007 v9.20 CREG=2 unsolicited with RAC) */
|
||||
/* [9] = "\\+(CREG|CGREG):\\s*0*([0-9])\\s*,\\s*([^,\\s]*)\\s*,\\s*([^,\\s]*)\\s*,\\s*0*([0-9])\\s*,\\s*([^,\\s]*)", */
|
||||
ireg = n_matches - 6;
|
||||
istat = n_matches - 5;
|
||||
ilac = n_matches - 4;
|
||||
ici = n_matches - 3;
|
||||
iact = n_matches - 2;
|
||||
break;
|
||||
case 54:
|
||||
/* +CEREG: <stat>,<lac>,<rac>,<ci>,<AcT> (ETSI 27.007 v8.6 CREG=2 unsolicited with RAC) */
|
||||
/* [10] = "\\+(CEREG):\\s*0*([0-9])\\s*,\\s*([^,\\s]*)\\s*,\\s*([^,\\s]*)\\s*,\\s*([^,\\s]*)\\s*,\\s*0*([0-9])", */
|
||||
ireg = n_matches - 6;
|
||||
istat = n_matches - 5;
|
||||
ilac = n_matches - 4;
|
||||
ici = n_matches - 2;
|
||||
iact = n_matches - 1;
|
||||
break;
|
||||
case 61:
|
||||
/* +CEREG: <n>,<stat>,<lac>,<rac>,<ci>,<AcT> (ETSI 27.007 v8.6 CREG=2 solicited with RAC) */
|
||||
/* [11] = "\\+(CEREG):\\s*0*([0-9]),\\s*0*([0-9])\\s*,\\s*([^,\\s]*)\\s*,\\s*([^,\\s]*)\\s*,\\s*([^,\\s]*)\\s*,\\s*0*([0-9])", */
|
||||
ireg = n_matches - 7;
|
||||
istat = n_matches - 5;
|
||||
ilac = n_matches - 4;
|
||||
ici = n_matches - 2;
|
||||
iact = n_matches - 1;
|
||||
break;
|
||||
case 68:
|
||||
/* +C5GREG: <stat>,<lac>,<ci>,<AcT>,<Allowed_NSSAI_length>,<Allowed_NSSAI> (ETSI 27.007 CREG=2 unsolicited) */
|
||||
/* [12] = "\\+(C5GREG):\\s*([0-9]+)\\s*,\\s*([^,\\s]*)\\s*,\\s*([^,\\s]*)\\s*,\\s*([0-9]+)\\s*,\\s*([^,\\s]*)\\s*,\\s*([^,\\s]*)", */
|
||||
ireg = n_matches - 7;
|
||||
istat = n_matches - 6;
|
||||
ilac = n_matches - 5;
|
||||
ici = n_matches - 4;
|
||||
iact = n_matches - 3;
|
||||
break;
|
||||
case 76:
|
||||
/* +C5GREG: <n>,<stat>,<lac>,<ci>,<AcT>,<Allowed_NSSAI_length>,<Allowed_NSSAI> (ETSI 27.007 solicited) */
|
||||
/* [13] = "\\+(C5GREG):\\s*([0-9]+)\\s*,\\s*([0-9+])\\s*,\\s*([^,\\s]*)\\s*,\\s*([^,\\s]*)\\s*,\\s*([0-9]+)\\s*,\\s*([^,\\s]*)\\s*,\\s*([^,\\s]*)", */
|
||||
ireg = n_matches - 8;
|
||||
istat = n_matches - 6;
|
||||
ilac = n_matches - 5;
|
||||
ici = n_matches - 4;
|
||||
iact = n_matches - 3;
|
||||
break;
|
||||
default:
|
||||
g_set_error_literal (error,
|
||||
MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
|
||||
"Could not parse the registration status response (invalid match count)");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Reg type */
|
||||
str = g_match_info_fetch (info, ireg);
|
||||
*out_cgreg = (str && strstr (str, "CGREG")) ? TRUE : FALSE;
|
||||
*out_cereg = (str && strstr (str, "CEREG")) ? TRUE : FALSE;
|
||||
*out_c5greg = (str && strstr (str, "C5GREG")) ? TRUE : FALSE;
|
||||
g_free (str);
|
||||
|
||||
/* Normally the number of matches could be used to determine what each
|
||||
* item is, but we have overlap in one case.
|
||||
*/
|
||||
n_matches = g_match_info_get_match_count (info);
|
||||
if (n_matches == 3) {
|
||||
/* CREG=1: +CREG: <stat> */
|
||||
istat = 2;
|
||||
} else if (n_matches == 4) {
|
||||
/* Solicited response: +CREG: <n>,<stat> */
|
||||
istat = 3;
|
||||
} else if (n_matches == 5) {
|
||||
/* CREG=2 (GSM 07.07): +CREG: <stat>,<lac>,<ci> */
|
||||
istat = 2;
|
||||
ilac = 3;
|
||||
ici = 4;
|
||||
} else if (n_matches == 6) {
|
||||
/* CREG=2 (ETSI 27.007): +CREG: <stat>,<lac>,<ci>,<AcT>
|
||||
* CREG=2 (non-standard): +CREG: <n>,<stat>,<lac>,<ci>
|
||||
*/
|
||||
|
||||
/* 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;
|
||||
}
|
||||
} 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>
|
||||
*/
|
||||
|
||||
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>
|
||||
* C5GREG=2 (unsolicited): +C5GREG: <stat>,<tac>,<ci>,<AcT>,<Allowed_NSSAI_length>,<Allowed_NSSAI>
|
||||
*/
|
||||
if (*out_cereg) {
|
||||
istat = 3;
|
||||
ilac = 4;
|
||||
ici = 6;
|
||||
iact = 7;
|
||||
} else if (*out_c5greg) {
|
||||
istat = 2;
|
||||
ilac = 3;
|
||||
ici = 4;
|
||||
iact = 5;
|
||||
}
|
||||
} else if (n_matches == 9) {
|
||||
/* C5GREG=2 (solicited): +C5GREG: <n>,<stat>,<tac>,<ci>,<AcT>,<Allowed_NSSAI_length>,<Allowed_NSSAI> */
|
||||
istat = 3;
|
||||
ilac = 4;
|
||||
ici = 5;
|
||||
iact = 6;
|
||||
}
|
||||
|
||||
/* Status */
|
||||
if (!mm_get_uint_from_match_info (info, istat, &stat)) {
|
||||
g_set_error_literal (error,
|
||||
|
||||
@@ -141,8 +141,7 @@ MMFlowControl mm_flow_control_from_string (const gchar *str,
|
||||
gboolean mm_modem_3gpp_registration_state_is_registered (MMModem3gppRegistrationState state);
|
||||
|
||||
/* Common Regex getters */
|
||||
GPtrArray *mm_3gpp_creg_regex_get (gboolean solicited);
|
||||
void mm_3gpp_creg_regex_destroy (GPtrArray *array);
|
||||
GRegex *mm_3gpp_creg_regex_get (gboolean solicited);
|
||||
GRegex *mm_3gpp_ciev_regex_get (void);
|
||||
GRegex *mm_3gpp_cgev_regex_get (void);
|
||||
GRegex *mm_3gpp_cusd_regex_get (void);
|
||||
|
||||
@@ -1088,8 +1088,8 @@ test_normalize_operator (void)
|
||||
/* Test CREG/CGREG responses and unsolicited messages */
|
||||
|
||||
typedef struct {
|
||||
GPtrArray *solicited_creg;
|
||||
GPtrArray *unsolicited_creg;
|
||||
GRegex *solicited_creg;
|
||||
GRegex *unsolicited_creg;
|
||||
} RegTestData;
|
||||
|
||||
static RegTestData *
|
||||
@@ -1106,8 +1106,8 @@ reg_test_data_new (void)
|
||||
static void
|
||||
reg_test_data_free (RegTestData *data)
|
||||
{
|
||||
mm_3gpp_creg_regex_destroy (data->solicited_creg);
|
||||
mm_3gpp_creg_regex_destroy (data->unsolicited_creg);
|
||||
g_regex_unref (data->solicited_creg);
|
||||
g_regex_unref (data->unsolicited_creg);
|
||||
g_free (data);
|
||||
}
|
||||
|
||||
@@ -1131,52 +1131,42 @@ test_creg_match (const char *test,
|
||||
const CregResult *result)
|
||||
{
|
||||
g_autoptr(GMatchInfo) info = NULL;
|
||||
guint i;
|
||||
MMModem3gppRegistrationState state = MM_MODEM_3GPP_REGISTRATION_STATE_UNKNOWN;
|
||||
MMModemAccessTechnology access_tech = MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN;
|
||||
gulong lac = 0;
|
||||
gulong ci = 0;
|
||||
GError *error = NULL;
|
||||
gboolean success;
|
||||
gboolean matched;
|
||||
gboolean cgreg = FALSE;
|
||||
gboolean cereg = FALSE;
|
||||
gboolean c5greg = FALSE;
|
||||
guint regex_num = 0;
|
||||
GPtrArray *array;
|
||||
GRegex *regex;
|
||||
|
||||
g_assert (reply);
|
||||
g_assert (test);
|
||||
g_assert (data);
|
||||
g_assert (result);
|
||||
|
||||
g_debug ("Testing '%s' +C%sREG %s response...",
|
||||
g_debug ("Testing '%s' +C%sREG %s response '%s'...",
|
||||
test,
|
||||
result->cgreg ? "G" : "",
|
||||
solicited ? "solicited" : "unsolicited");
|
||||
solicited ? "solicited" : "unsolicited",
|
||||
reply);
|
||||
|
||||
array = solicited ? data->solicited_creg : data->unsolicited_creg;
|
||||
for (i = 0; i < array->len; i++) {
|
||||
GRegex *r = g_ptr_array_index (array, i);
|
||||
|
||||
if (g_regex_match (r, reply, 0, &info)) {
|
||||
g_debug (" matched with %d", i);
|
||||
regex_num = i;
|
||||
break;
|
||||
}
|
||||
g_clear_pointer (&info, g_match_info_free);
|
||||
}
|
||||
|
||||
g_debug (" regex_num (%u) == result->regex_num (%u)",
|
||||
regex_num,
|
||||
result->regex_num);
|
||||
|
||||
g_assert (info != NULL);
|
||||
g_assert_cmpuint (regex_num, ==, result->regex_num);
|
||||
regex = solicited ? data->solicited_creg : data->unsolicited_creg;
|
||||
g_regex_match (regex, reply, 0, &info);
|
||||
|
||||
while (g_match_info_matches (info)) {
|
||||
matched = TRUE;
|
||||
success = mm_3gpp_parse_creg_response (info, NULL, &state, &lac, &ci, &access_tech, &cgreg, &cereg, &c5greg, &error);
|
||||
|
||||
g_assert (success);
|
||||
g_assert_no_error (error);
|
||||
g_match_info_next (info, NULL);
|
||||
}
|
||||
|
||||
g_assert (matched);
|
||||
g_assert_cmpuint (state, ==, result->state);
|
||||
g_assert_cmpuint (lac, ==, result->lac);
|
||||
g_assert_cmpuint (ci, ==, result->ci);
|
||||
@@ -1472,7 +1462,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 = { MM_MODEM_3GPP_REGISTRATION_STATE_ROAMING, 0, 0, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, 0, FALSE, FALSE, FALSE };
|
||||
const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_IDLE, 0, 0, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, 0, TRUE, FALSE, FALSE };
|
||||
|
||||
test_creg_match ("Multi CREG/CGREG", FALSE, reply, data, &result);
|
||||
}
|
||||
@@ -1482,11 +1472,21 @@ 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 = { MM_MODEM_3GPP_REGISTRATION_STATE_IDLE, 0, 0, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, 0, TRUE, FALSE, FALSE };
|
||||
const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_ROAMING, 0, 0, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, 0, FALSE, FALSE, FALSE };
|
||||
|
||||
test_creg_match ("Multi CREG/CGREG #2", FALSE, reply, data, &result);
|
||||
}
|
||||
|
||||
static void
|
||||
test_cereg_multi_unsolicited (void *f, gpointer d)
|
||||
{
|
||||
RegTestData *data = (RegTestData *) d;
|
||||
const char *reply = "\r\n+CEREG: 2\r\n\r\n+CNSMOD: 8\r\n\r\n+CEREG: 1,AAAA,01234567,7\r\n";
|
||||
const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_HOME, 0xAAAA, 0x1234567, MM_MODEM_ACCESS_TECHNOLOGY_LTE, 5, FALSE, TRUE, FALSE };
|
||||
|
||||
test_creg_match ("Multi CEREG", FALSE, reply, data, &result);
|
||||
}
|
||||
|
||||
static void
|
||||
test_cgreg2_x220_unsolicited (void *f, gpointer d)
|
||||
{
|
||||
@@ -1518,6 +1518,16 @@ test_creg2_s8500_wave_multidigit_stat_unsolicited (void *f, gpointer d)
|
||||
test_creg_match ("Samsung Wave S8500 CREG=2 with multidigit \"stat\" value", FALSE, reply, data, &result);
|
||||
}
|
||||
|
||||
static void
|
||||
test_creg2_s8500_wave_act_unsolicited (void *f, gpointer d)
|
||||
{
|
||||
RegTestData *data = (RegTestData *) d;
|
||||
const char *reply = "\r\n+CGREG: 2,11,003F,8FE3, 10, C2816\r\n";
|
||||
const CregResult result = { MM_MODEM_3GPP_REGISTRATION_STATE_ATTACHED_RLOS, 0x003F, 0x8FE3, MM_MODEM_ACCESS_TECHNOLOGY_LTE, 8, TRUE, FALSE, FALSE };
|
||||
|
||||
test_creg_match ("Samsung Wave S8500 CREG=2 with act value", FALSE, reply, data, &result);
|
||||
}
|
||||
|
||||
static void
|
||||
test_creg2_gobi_weird_solicited (void *f, gpointer d)
|
||||
{
|
||||
@@ -5362,6 +5372,7 @@ int main (int argc, char **argv)
|
||||
g_test_suite_add (suite, TESTCASE (test_creg2_md400_unsolicited, reg_data));
|
||||
g_test_suite_add (suite, TESTCASE (test_creg2_s8500_wave_unsolicited, reg_data));
|
||||
g_test_suite_add (suite, TESTCASE (test_creg2_s8500_wave_multidigit_stat_unsolicited, reg_data));
|
||||
g_test_suite_add (suite, TESTCASE (test_creg2_s8500_wave_act_unsolicited, reg_data));
|
||||
g_test_suite_add (suite, TESTCASE (test_creg2_gobi_weird_solicited, reg_data));
|
||||
g_test_suite_add (suite, TESTCASE (test_creg2_iridium_solicited, reg_data));
|
||||
g_test_suite_add (suite, TESTCASE (test_creg2_no_leading_zeros_solicited, reg_data));
|
||||
@@ -5406,6 +5417,7 @@ int main (int argc, char **argv)
|
||||
|
||||
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));
|
||||
g_test_suite_add (suite, TESTCASE (test_cereg_multi_unsolicited, reg_data));
|
||||
|
||||
g_test_suite_add (suite, TESTCASE (test_cscs_icon225_support_response, NULL));
|
||||
g_test_suite_add (suite, TESTCASE (test_cscs_sierra_mercury_support_response, NULL));
|
||||
|
||||
Reference in New Issue
Block a user