helpers: use generic number parsing methods in CREG parser

This fixes the s8500 wave unit test, which was incorrectly parsing the
Act field reported as 'B' as "GSM" (strtol(B)=0)

Also, given that the generic parsing methods are able to parse numbers
from quoted strings, this change allows us to remove the Thuraya
specific CREG matching that just took into consideration quoted
strings. The Thuraya unit tests are also fixed up to provide proper
testing of the logic.
This commit is contained in:
Aleksander Morgado
2020-03-24 07:36:01 +01:00
parent 40b36a25ca
commit 040eb3880c
2 changed files with 28 additions and 79 deletions

View File

@@ -828,7 +828,6 @@ mm_flow_control_from_string (const gchar *str,
/* +CREG: <stat>,<lac>,<ci> (GSM 07.07 CREG=2 unsolicited) */
#define CREG3 "\\+(CREG|CGREG|CEREG):\\s*0*([0-9]),\\s*([^,\\s]*)\\s*,\\s*([^,\\s]*)"
#define CREG11 "\\+(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|CEREG):\\s*([0-9]),\\s*([0-9])\\s*,\\s*([^,]*)\\s*,\\s*([^,\\s]*)"
@@ -857,9 +856,11 @@ mm_flow_control_from_string (const gchar *str,
GPtrArray *
mm_3gpp_creg_regex_get (gboolean solicited)
{
GPtrArray *array = g_ptr_array_sized_new (13);
GPtrArray *array;
GRegex *regex;
array = g_ptr_array_sized_new (12);
/* #1 */
if (solicited)
regex = g_regex_new (CREG1 "$", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
@@ -940,14 +941,6 @@ mm_3gpp_creg_regex_get (gboolean solicited)
g_assert (regex);
g_ptr_array_add (array, regex);
/* #11 */
if (solicited)
regex = g_regex_new (CREG11 "$", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
else
regex = g_regex_new ("\\r\\n" CREG11 "\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
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);
@@ -1946,35 +1939,6 @@ mm_3gpp_parse_cgact_read_response (const gchar *reply,
/*************************************************************************/
static gulong
parse_uint (gchar *str,
gint base,
gulong nmin,
gulong nmax,
gboolean *valid)
{
gulong ret = 0;
gchar *endquote;
*valid = FALSE;
if (!str)
return 0;
/* Strip quotes */
if (str[0] == '"')
str++;
endquote = strchr (str, '"');
if (endquote)
*endquote = '\0';
if (strlen (str)) {
ret = strtol (str, NULL, base);
if ((nmin == nmax) || (ret >= nmin && ret <= nmax))
*valid = TRUE;
}
return *valid ? (guint) ret : 0;
}
static gboolean
item_is_lac_not_stat (GMatchInfo *info, guint32 item)
{
@@ -2000,9 +1964,9 @@ mm_3gpp_parse_creg_response (GMatchInfo *info,
gboolean *out_cereg,
GError **error)
{
gboolean success = FALSE, foo;
gint n_matches, act = -1;
gulong stat = 0, lac = 0, ci = 0;
guint stat = 0;
guint64 lac = 0, ci = 0;
guint istat = 0, ilac = 0, ici = 0, iact = 0;
gchar *str;
@@ -2094,10 +2058,7 @@ mm_3gpp_parse_creg_response (GMatchInfo *info,
}
/* Status */
str = g_match_info_fetch (info, istat);
stat = parse_uint (str, 10, 0, G_MAXUINT, &success);
g_free (str);
if (!success) {
if (!mm_get_uint_from_match_info (info, istat, &stat)) {
g_set_error_literal (error,
MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
"Could not parse the registration status response");
@@ -2106,43 +2067,31 @@ mm_3gpp_parse_creg_response (GMatchInfo *info,
/* 'attached RLOS' is the last valid state */
if (stat > MM_MODEM_3GPP_REGISTRATION_STATE_ATTACHED_RLOS) {
mm_obj_warn (log_object, "unknown registration state value '%lu'", stat);
mm_obj_warn (log_object, "unknown registration state value '%u'", stat);
stat = MM_MODEM_3GPP_REGISTRATION_STATE_UNKNOWN;
}
/* Location Area Code */
if (ilac) {
/* FIXME: some phones apparently swap the LAC bytes (LG, SonyEricsson,
/* Location Area Code/Tracking Area Code
* FIXME: some phones apparently swap the LAC bytes (LG, SonyEricsson,
* Sagem). Need to handle that.
*/
str = g_match_info_fetch (info, ilac);
lac = parse_uint (str, 16, 1, 0xFFFF, &foo);
g_free (str);
}
if (ilac)
mm_get_u64_from_hex_match_info (info, ilac, &lac);
/* Cell ID */
if (ici) {
str = g_match_info_fetch (info, ici);
ci = parse_uint (str, 16, 1, 0x0FFFFFFE, &foo);
g_free (str);
}
if (ici)
mm_get_u64_from_hex_match_info (info, ici, &ci);
/* Access Technology */
if (iact) {
str = g_match_info_fetch (info, iact);
act = (gint) parse_uint (str, 10, 0, 7, &foo);
g_free (str);
if (!foo)
act = -1;
}
if (iact)
mm_get_int_from_match_info (info, iact, &act);
*out_reg_state = (MMModem3gppRegistrationState) stat;
if (stat != MM_MODEM_3GPP_REGISTRATION_STATE_UNKNOWN) {
/* Don't fill in lac/ci/act if the device's state is unknown */
*out_lac = lac;
*out_ci = ci;
*out_act = get_mm_access_tech_from_etsi_access_tech (act);
*out_lac = (gulong)lac;
*out_ci = (gulong)ci;
*out_act = (act >= 0 ? get_mm_access_tech_from_etsi_access_tech (act) : MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN);
}
return TRUE;
}

View File

@@ -1435,7 +1435,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, 9, FALSE, FALSE };
const CregResult result = { 1, 0x000B, 0x2816, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, 9, FALSE, FALSE };
test_creg_match ("Samsung Wave S8500 CREG=2", FALSE, reply, data, &result);
}
@@ -1525,7 +1525,7 @@ 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, 13, FALSE, TRUE };
const CregResult result = { 1, 0x1F00, 0x79D903, MM_MODEM_ACCESS_TECHNOLOGY_LTE, 12, FALSE, TRUE };
test_creg_match ("Novatel LTE E362 CEREG=2", TRUE, reply, data, &result);
}
@@ -1535,7 +1535,7 @@ 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, 12, FALSE, TRUE };
const CregResult result = { 1, 0x1F00, 0x79D903, MM_MODEM_ACCESS_TECHNOLOGY_LTE, 11, FALSE, TRUE };
test_creg_match ("Novatel LTE E362 CEREG=2", FALSE, reply, data, &result);
}
@@ -1544,8 +1544,8 @@ static void
test_cgreg2_thuraya_solicited (void *f, gpointer d)
{
RegTestData *data = (RegTestData *) d;
const char *reply = "+CGREG: 1, \"0426\", \"F0,0F\"";
const CregResult result = { 1, 0x0426, 0x00F0, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, 11, TRUE, FALSE };
const char *reply = "+CGREG: 2, 1, \"0426\", \"F00F\"";
const CregResult result = { 1, 0x0426, 0xF00F, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, 4, TRUE, FALSE };
test_creg_match ("Thuraya solicited CREG=2", TRUE, reply, data, &result);
}
@@ -1554,8 +1554,8 @@ static void
test_cgreg2_thuraya_unsolicited (void *f, gpointer d)
{
RegTestData *data = (RegTestData *) d;
const char *reply = "\r\n+CGREG: 1, \"0426\", \"F0,0F\"\r\n";
const CregResult result = { 1, 0x0426, 0x00F0, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, 11, TRUE, FALSE };
const char *reply = "\r\n+CGREG: 1, \"0426\", \"F00F\"\r\n";
const CregResult result = { 1, 0x0426, 0xF00F, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, 3, TRUE, FALSE };
test_creg_match ("Thuraya unsolicited CREG=2", FALSE, reply, data, &result);
}