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:
@@ -828,7 +828,6 @@ mm_flow_control_from_string (const gchar *str,
|
|||||||
|
|
||||||
/* +CREG: <stat>,<lac>,<ci> (GSM 07.07 CREG=2 unsolicited) */
|
/* +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 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) */
|
/* +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]*)"
|
#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 *
|
GPtrArray *
|
||||||
mm_3gpp_creg_regex_get (gboolean solicited)
|
mm_3gpp_creg_regex_get (gboolean solicited)
|
||||||
{
|
{
|
||||||
GPtrArray *array = g_ptr_array_sized_new (13);
|
GPtrArray *array;
|
||||||
GRegex *regex;
|
GRegex *regex;
|
||||||
|
|
||||||
|
array = g_ptr_array_sized_new (12);
|
||||||
|
|
||||||
/* #1 */
|
/* #1 */
|
||||||
if (solicited)
|
if (solicited)
|
||||||
regex = g_regex_new (CREG1 "$", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
|
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_assert (regex);
|
||||||
g_ptr_array_add (array, 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 */
|
/* CEREG #1 */
|
||||||
if (solicited)
|
if (solicited)
|
||||||
regex = g_regex_new (CEREG1 "$", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
|
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
|
static gboolean
|
||||||
item_is_lac_not_stat (GMatchInfo *info, guint32 item)
|
item_is_lac_not_stat (GMatchInfo *info, guint32 item)
|
||||||
{
|
{
|
||||||
@@ -2000,9 +1964,9 @@ mm_3gpp_parse_creg_response (GMatchInfo *info,
|
|||||||
gboolean *out_cereg,
|
gboolean *out_cereg,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
gboolean success = FALSE, foo;
|
|
||||||
gint n_matches, act = -1;
|
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;
|
guint istat = 0, ilac = 0, ici = 0, iact = 0;
|
||||||
gchar *str;
|
gchar *str;
|
||||||
|
|
||||||
@@ -2094,10 +2058,7 @@ mm_3gpp_parse_creg_response (GMatchInfo *info,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Status */
|
/* Status */
|
||||||
str = g_match_info_fetch (info, istat);
|
if (!mm_get_uint_from_match_info (info, istat, &stat)) {
|
||||||
stat = parse_uint (str, 10, 0, G_MAXUINT, &success);
|
|
||||||
g_free (str);
|
|
||||||
if (!success) {
|
|
||||||
g_set_error_literal (error,
|
g_set_error_literal (error,
|
||||||
MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
|
MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
|
||||||
"Could not parse the registration status response");
|
"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 */
|
/* 'attached RLOS' is the last valid state */
|
||||||
if (stat > MM_MODEM_3GPP_REGISTRATION_STATE_ATTACHED_RLOS) {
|
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;
|
stat = MM_MODEM_3GPP_REGISTRATION_STATE_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Location Area Code */
|
/* Location Area Code/Tracking Area Code
|
||||||
if (ilac) {
|
* FIXME: some phones apparently swap the LAC bytes (LG, SonyEricsson,
|
||||||
/* FIXME: some phones apparently swap the LAC bytes (LG, SonyEricsson,
|
|
||||||
* Sagem). Need to handle that.
|
* Sagem). Need to handle that.
|
||||||
*/
|
*/
|
||||||
str = g_match_info_fetch (info, ilac);
|
if (ilac)
|
||||||
lac = parse_uint (str, 16, 1, 0xFFFF, &foo);
|
mm_get_u64_from_hex_match_info (info, ilac, &lac);
|
||||||
g_free (str);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Cell ID */
|
/* Cell ID */
|
||||||
if (ici) {
|
if (ici)
|
||||||
str = g_match_info_fetch (info, ici);
|
mm_get_u64_from_hex_match_info (info, ici, &ci);
|
||||||
ci = parse_uint (str, 16, 1, 0x0FFFFFFE, &foo);
|
|
||||||
g_free (str);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Access Technology */
|
/* Access Technology */
|
||||||
if (iact) {
|
if (iact)
|
||||||
str = g_match_info_fetch (info, iact);
|
mm_get_int_from_match_info (info, iact, &act);
|
||||||
act = (gint) parse_uint (str, 10, 0, 7, &foo);
|
|
||||||
g_free (str);
|
|
||||||
if (!foo)
|
|
||||||
act = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
*out_reg_state = (MMModem3gppRegistrationState) stat;
|
*out_reg_state = (MMModem3gppRegistrationState) stat;
|
||||||
if (stat != MM_MODEM_3GPP_REGISTRATION_STATE_UNKNOWN) {
|
if (stat != MM_MODEM_3GPP_REGISTRATION_STATE_UNKNOWN) {
|
||||||
/* Don't fill in lac/ci/act if the device's state is unknown */
|
/* Don't fill in lac/ci/act if the device's state is unknown */
|
||||||
*out_lac = lac;
|
*out_lac = (gulong)lac;
|
||||||
*out_ci = ci;
|
*out_ci = (gulong)ci;
|
||||||
|
*out_act = (act >= 0 ? get_mm_access_tech_from_etsi_access_tech (act) : MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN);
|
||||||
*out_act = get_mm_access_tech_from_etsi_access_tech (act);
|
|
||||||
}
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@@ -1435,7 +1435,7 @@ test_creg2_s8500_wave_unsolicited (void *f, gpointer d)
|
|||||||
{
|
{
|
||||||
RegTestData *data = (RegTestData *) d;
|
RegTestData *data = (RegTestData *) d;
|
||||||
const char *reply = "\r\n+CREG: 2,1,000B,2816, B, C2816\r\n";
|
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);
|
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;
|
RegTestData *data = (RegTestData *) d;
|
||||||
const char *reply = "\r\n+CEREG: 2,1, 1F00, 20 ,79D903 ,7\r\n";
|
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);
|
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;
|
RegTestData *data = (RegTestData *) d;
|
||||||
const char *reply = "\r\n+CEREG: 1, 1F00, 20 ,79D903 ,7\r\n";
|
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);
|
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)
|
test_cgreg2_thuraya_solicited (void *f, gpointer d)
|
||||||
{
|
{
|
||||||
RegTestData *data = (RegTestData *) d;
|
RegTestData *data = (RegTestData *) d;
|
||||||
const char *reply = "+CGREG: 1, \"0426\", \"F0,0F\"";
|
const char *reply = "+CGREG: 2, 1, \"0426\", \"F00F\"";
|
||||||
const CregResult result = { 1, 0x0426, 0x00F0, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, 11, TRUE, FALSE };
|
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);
|
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)
|
test_cgreg2_thuraya_unsolicited (void *f, gpointer d)
|
||||||
{
|
{
|
||||||
RegTestData *data = (RegTestData *) d;
|
RegTestData *data = (RegTestData *) d;
|
||||||
const char *reply = "\r\n+CGREG: 1, \"0426\", \"F0,0F\"\r\n";
|
const char *reply = "\r\n+CGREG: 1, \"0426\", \"F00F\"\r\n";
|
||||||
const CregResult result = { 1, 0x0426, 0x00F0, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, 11, TRUE, FALSE };
|
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);
|
test_creg_match ("Thuraya unsolicited CREG=2", FALSE, reply, data, &result);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user