aboutsummaryrefslogtreecommitdiff
path: root/src/mm-modem-helpers.c
diff options
context:
space:
mode:
authorBen Chan <benchan@chromium.org>2013-07-31 23:07:52 -0700
committerDan Williams <dcbw@redhat.com>2013-08-06 16:14:35 -0500
commitffac6f17b5912dfa4d2e55eaf078796680871ea7 (patch)
tree4b08910ca479095e00ffa417d8bca1de18f0e776 /src/mm-modem-helpers.c
parent755c61a2ffad6d54fc3116dd29d91b4325cf6b18 (diff)
modem-helpers: fix parsing of CREG/CGREG/CEREG responses
The format of CREG/CGREG/CEREG responses is not very precisely defined in or strictly enforced by the 3GPP specifications. That leads to the fact that some modems put leading zeros in integer type fields (e.g. <n>, <stat>, <AcT>), and not all modems put double quotes around string type fields (e.g. <lac>, <ci>) in those C*REG responses. For example, 0001 can be a valid value for both <stat> and <lac>. The original C*REG parsing code in ModemManager could potentially interpret '+CREG: <stat>,<lac>,<ci>,<AcT>' as '+CREG: <n>,<stat>,<lac>,<ci>'. This patch addresses this issue by refining the regular expressions returned by mm_3gpp_creg_regex_get() with the following assumptions: 1. If a modem puts leading zeros in integer type fields, it puts double quotes around string type fields. 2. If a modem omits double quotes around string type fields, it does not put leading zeros in integer type fields.
Diffstat (limited to 'src/mm-modem-helpers.c')
-rw-r--r--src/mm-modem-helpers.c30
1 files changed, 24 insertions, 6 deletions
diff --git a/src/mm-modem-helpers.c b/src/mm-modem-helpers.c
index cd4ef763..95d74dc1 100644
--- a/src/mm-modem-helpers.c
+++ b/src/mm-modem-helpers.c
@@ -333,20 +333,22 @@ mm_filter_supported_capabilities (MMModemCapability all,
#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|CEREG):\\s*0*([0-9]),\\s*0*([0-9])\\s*,\\s*([^,]*)\\s*,\\s*([^,\\s]*)"
+#define CREG4 "\\+(CREG|CGREG|CEREG):\\s*([0-9]),\\s*([0-9])\\s*,\\s*([^,]*)\\s*,\\s*([^,\\s]*)"
+#define CREG5 "\\+(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|CEREG):\\s*0*([0-9])\\s*,\\s*([^,\\s]*)\\s*,\\s*([^,\\s]*)\\s*,\\s*0*([0-9])"
+#define CREG6 "\\+(CREG|CGREG|CEREG):\\s*([0-9])\\s*,\\s*([^,\\s]*)\\s*,\\s*([^,\\s]*)\\s*,\\s*([0-9])"
+#define CREG7 "\\+(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|CEREG):\\s*0*([0-9]),\\s*0*([0-9])\\s*,\\s*([^,\\s]*)\\s*,\\s*([^,\\s]*)\\s*,\\s*0*([0-9])"
+#define CREG8 "\\+(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>' */
-#define CREG7 "\\+(CREG|CGREG):\\s*0*([0-9]),\\s*0*([0-9])\\s*,\\s*([^,\\s]*)\\s*,\\s*([^,\\s]*)\\s*,\\s*([^,\\s]*)\\s*,\\s*[^,\\s]*"
+#define CREG9 "\\+(CREG|CGREG):\\s*0*([0-9]),\\s*0*([0-9])\\s*,\\s*([^,\\s]*)\\s*,\\s*([^,\\s]*)\\s*,\\s*([^,\\s]*)\\s*,\\s*[^,\\s]*"
/* +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]*)"
+#define CREG10 "\\+(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])"
@@ -357,7 +359,7 @@ mm_filter_supported_capabilities (MMModemCapability all,
GPtrArray *
mm_3gpp_creg_regex_get (gboolean solicited)
{
- GPtrArray *array = g_ptr_array_sized_new (10);
+ GPtrArray *array = g_ptr_array_sized_new (12);
GRegex *regex;
/* #1 */
@@ -424,6 +426,22 @@ mm_3gpp_creg_regex_get (gboolean solicited)
g_assert (regex);
g_ptr_array_add (array, regex);
+ /* #9 */
+ if (solicited)
+ regex = g_regex_new (CREG9 "$", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
+ else
+ regex = g_regex_new ("\\r\\n" CREG9 "\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
+ g_assert (regex);
+ g_ptr_array_add (array, regex);
+
+ /* #10 */
+ if (solicited)
+ regex = g_regex_new (CREG10 "$", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
+ else
+ regex = g_regex_new ("\\r\\n" CREG10 "\\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);