Skip unsolicied CREG/CGREG correctly while checking GPRS attach status
PATCH v2 1/1 Skip unsolicied CREG/CGREG correctly while checking GPRS attach status
This patch is to skip unsolicited CGREG while checking the GPRS attach status, especially for Huawei modem which sends lac and ci strings in unquoted format, and casues at_util_parse_reg() return lac value as status.
--- drivers/atmodem/atutil.c | 12 ++++++++---- gatchat/gatresult.c | 5 +++++ gatchat/gatresult.h | 1 + 3 files changed, 14 insertions(+), 4 deletions(-)
drivers/atmodem/atutil.c +0 -0
@@ -243,13 +243,11 @@ gboolean at_util_parse_reg(GAtResult *result,
const char *prefix,
if (g_at_result_iter_next_number(&iter, &s) == FALSE)
continue;
- /* Some firmware will report bogus lac/ci when unregistered */
- if (s != 1 && s != 5)
- goto out;
-
switch (vendor) {
case OFONO_VENDOR_HUAWEI:
case OFONO_VENDOR_NOVATEL:
+ if (g_at_result_iter_eol(&iter))
+ continue;
r = g_at_result_iter_next_unquoted_string(&iter, &str);
if (r == TRUE)
@@ -257,6 +255,8 @@ gboolean at_util_parse_reg(GAtResult *result, const char *prefix,
else
goto out;
+ if (g_at_result_iter_eol(&iter))
+ continue;
r = g_at_result_iter_next_unquoted_string(&iter, &str);
if (r == TRUE)
@@ -266,11 +266,15 @@ gboolean at_util_parse_reg(GAtResult *result, const char *prefix,
break;
default:
+ if (g_at_result_iter_eol(&iter))
+ continue;
if (g_at_result_iter_next_string(&iter, &str) == TRUE)
l = strtol(str, NULL, 16);
else
goto out;
+ if (g_at_result_iter_eol(&iter))
+ continue;
if (g_at_result_iter_next_string(&iter, &str) == TRUE)
c = strtol(str, NULL, 16);
else
gatchat/gatresult.c +0 -0
@@ -39,6 +39,11 @@ void g_at_result_iter_init(GAtResultIter *iter,
GAtResult *result)
iter->line_pos = 0;
}
+gboolean g_at_result_iter_eol(GAtResultIter *iter)
+{
+ return iter->line_pos >= strlen(iter->l->data);
+}
+
gboolean g_at_result_iter_next(GAtResultIter *iter, const char *prefix) {
char *line;
gatchat/gatresult.h +1 -0
@@ -46,6 +46,7 @@ struct _GAtResultIter {typedef struct _GAtResultIter GAtResultIter ;void g_at_result_iter_init (GAtResultIter *iter,GAtResult *result); +gboolean g_at_result_iter_eol (GAtResultIter *iter); gboolean g_at_result_iter_next(GAtResultIter *iter, const char
*prefix);
gboolean g_at_result_iter_open_list(GAtResultIter *iter);
Signature · 1 line
1.7.2.2
Quoted 9 lines · Tonny Tzeng
This patch is to skip unsolicited CGREG while checking the GPRS attach status, especially for Huawei modem which sends lac and ci strings in unquoted format, and casues
at_util_parse_reg()return lac value as status.--- drivers/atmodem/atutil.c | 12 ++++++++---- gatchat/gatresult.c | 5 +++++ gatchat/gatresult.h | 1 +
We like to see patches split on a top level directory boundary. Please see the 'Submitting patches' section in the HACKING document.
Quoted 7 lines
3 files changed, 14 insertions(+), 4 deletions(-)drivers/atmodem/atutil.c +0
-0
drivers/atmodem/atutil.c gboolean at_util_parse_reg(GAtResult *result, · line 250
Quoted 8 lines
drivers/atmodem/atutil.c +0
-4@@ -243,13 +243,11 @@ gboolean at_util_parse_reg(GAtResult *result, const char *prefix, if (g_at_result_iter_next_number(&iter, &s) == FALSE) continue; -/* Some firmware will report bogus lac/ci when unregistered */ -if (s !=1 && s !=5 ) - goto out; -
Skipping this check is still a bad idea.
drivers/atmodem/atutil.c gboolean at_util_parse_reg(GAtResult *result, · line 251
Quoted 5 lines
drivers/atmodem/atutil.c +2
-0switch (vendor) {case OFONO_VENDOR_HUAWEI :case OFONO_VENDOR_NOVATEL : +if (g_at_result_iter_eol (&iter)) +continue ;
Coding style item M1.
drivers/atmodem/atutil.c gboolean at_util_parse_reg(GAtResult *result, const · line 260
Quoted 10 lines
drivers/atmodem/atutil.c +0
-0r =g_at_result_iter_next_unquoted_string (&iter, &str);drivers/atmodem/atutil.c +2
-0if (r == TRUE)@@ -257,6 +255,8 @@ gboolean at_util_parse_reg(GAtResult *result, constchar *prefix, else goto out; +if (g_at_result_iter_eol (&iter)) +continue ;
Coding style item M1.
drivers/atmodem/atutil.c gboolean at_util_parse_reg(GAtResult *result, · line 271
Quoted 10 lines
drivers/atmodem/atutil.c +0
-0r =g_at_result_iter_next_unquoted_string (&iter, &str);drivers/atmodem/atutil.c +2
-0if (r == TRUE)@@ -266,11 +266,15 @@ gboolean at_util_parse_reg(GAtResult *result,const char *prefix, break;default : +if (g_at_result_iter_eol (&iter)) +continue ;
Coding style item M1. And continuing is not the right thing to do here
drivers/atmodem/atutil.c gboolean at_util_parse_reg(GAtResult *result, · line 278
Quoted 7 lines
drivers/atmodem/atutil.c +2
-0if (g_at_result_iter_next_string (&iter, &str) == TRUE) l =strtol (str,NULL ,16 );else goto out; +if (g_at_result_iter_eol (&iter)) +continue ;
Ditto
Quoted 8 lines
drivers/atmodem/atutil.c +0
-0if (g_at_result_iter_next_string (&iter, &str) == TRUE) c =strtol (str,NULL ,16 );drivers/atmodem/atutil.c +0
-0else gatchat/gatresult.c +0
-0
gatchat/gatresult.c void g_at_result_iter_init(GAtResultIter *iter, · line 47
Quoted 9 lines
gatchat/gatresult.c +5
-0@@ -39,6 +39,11 @@ void g_at_result_iter_init(GAtResultIter *iter, GAtResult *result) iter->line_pos = 0; } +gboolean g_at_result_iter_eol (GAtResultIter *iter) +{ +return iter->line_pos >=strlen (iter->l->data); +} +
And I pretty much don't see the need for this. It doesn't really help you here.
Quoted 15 lines
gatchat/gatresult.c +0
-0gboolean g_at_result_iter_next (GAtResultIter *iter,const char *prefix) {gatchat/gatresult.c +0
-0char *line;gatchat/gatresult.h +1
-0@@ -46,6 +46,7 @@ struct _GAtResultIter {typedef struct _GAtResultIter GAtResultIter ;void g_at_result_iter_init (GAtResultIter *iter,GAtResult *result); +gboolean g_at_result_iter_eol (GAtResultIter *iter);gboolean g_at_result_iter_next (GAtResultIter *iter,const char *prefix);
Quoted 1 line
gboolean
g_at_result_iter_open_list(GAtResultIter *iter);
Anyhow, can you please try the attached patch and see if it solves your problems.
Regards,
-Denis
Quoted 1 line
From
f5473c398a2e29a98c74ad4c98a427564e25d9d0Mon Sep 17 00:00:00 2001
From: Denis Kenzior <[email protected]>
Date: Mon, 6 Dec 2010 21:36:54 -0600
Subject: [PATCH] atutil: Fix parsing of un-quoted CREG / CGREG
On broken hardware like the Huawei, it is possible to receive both an unsolicited and a solicited version of the CREG / CGREG within within the same response set. Skipping of the unsolicited version was not handled correctly. This attempts to fix this issue.
--- drivers/atmodem/atutil.c | 19 +++++++++++++++++-- 1 files changed, 17 insertions(+), 2 deletions(-)
drivers/atmodem/atutil.c +17 -2
@@ -240,8 +240,23 @@ gboolean at_util_parse_reg(GAtResult *result, const char *prefix,g_at_result_iter_next_number (&iter, &m);/* Sometimes we get an unsolicited CREG/CGREG here, skip it */ -if (g_at_result_iter_next_number (&iter, &s) == FALSE) -continue ; +switch (vendor) { +case OFONO_VENDOR_HUAWEI : +case OFONO_VENDOR_NOVATEL : + r =g_at_result_iter_next_unquoted_string (&iter, &str); + +if (r == FALSE ||strlen (str) !=1 ) +continue ; + + s =strtol (str,NULL ,10 ); + +break ; +default : +if (g_at_result_iter_next_number (&iter, &s) == FALSE) +continue ; + +break ; + }/* Some firmware will report bogus lac/ci when unregistered */ if (s !=1 && s !=5 )
Signature · 1 line
1.7.0.4
Quoted 10 lines
Quoted 10 lines
gatchat/gatresult.c +0
-0@@ -39,6 +39,11 @@ void g_at_result_iter_init(GAtResultIter *iter, GAtResult *result) iter->line_pos = 0; }
Quoted 8 lines
gatchat/gatresult.c void g_at_result_iter_init(GAtResultIter *iter, · line 47
Quoted 5 lines
gatchat/gatresult.c +5
-0+gboolean g_at_result_iter_eol (GAtResultIter *iter) +{ +return iter->line_pos >=strlen (iter->l->data); +} +And I pretty much don't see the need for this. It doesn't really help you here.
No, this function can help to ignore unsolicited response properly. I think the difference between solicited and unsolicited CGREG is the number of parameters after +CGREG:, so it would be nice if we have a utility function to know we are at the end of AT return string.
This is what we want to parse the state info from the solicited response:
+CGREG: <n>, <state>, <lac>, <ci>
but in a race condition, we received this unsolicited response from Huawei modem:
+CGREG: <state>, <lac>, <ci>
In your proposed patch, it bypass the unsolicited response only if the 2nd number after +CGREG: is not single digit, however if the lac is single digit, we will still get the wrong state number.
So I still believe we should check whether we are at the end of the return string before parsing the unquoted lac and ci. If we are at the end of the string, then this is a unsolicited code and we should ignore it. How do you think?
Quoted 23 lines
Quoted 15 lines
gatchat/gatresult.c +0
-0gboolean g_at_result_iter_next (GAtResultIter *iter,const char *prefix) {char *line;gatchat/gatresult.h +1
-0@@ -46,6 +46,7 @@ struct _GAtResultIter {typedef struct _GAtResultIter GAtResultIter ;void g_at_result_iter_init (GAtResultIter *iter,GAtResult *result); +gboolean g_at_result_iter_eol (GAtResultIter *iter);gboolean g_at_result_iter_next (GAtResultIter *iter,const char *prefix);Quoted 1 line
gboolean
g_at_result_iter_open_list(GAtResultIter *iter);Anyhow, can you please try the attached patch and see if it solves your problems.
Regards,
-Denis
Hi Tonny,
Quoted 3 lines
In your proposed patch, it bypass the unsolicited response only if the 2nd number after +CGREG: is not single digit, however if the lac is single digit, we will still get the wrong state number.
The lac is given as a 2 byte number and should always be printed as four hexadecimal letters. If this is not the case, then you should have a serious talk with your vendor.
Quoted 6 lines
So I still believe we should check whether we are at the end of the return string before parsing the unquoted lac and ci. If we are at the end of the string, then this is a unsolicited code and we should ignore it. How do you think?
I'm against this, if you really want to guard against this, then use the approach similar to comprehension_tlv_iter_copy in src/simutil.[ch]. You can use that to 'peek' ahead and figure out whether the response contains 3 or 4 elements.
But again, you would not be having this issue in the first place if your vendor followed standards ;)
Regards,
-Denis
Hi Denis,
Quoted 10 lines · Denis Kenzior
Hi Tonny,
Quoted 3 lines
In your proposed patch, it bypass the unsolicited response only if the 2nd number after +CGREG: is not single digit, however if the lac is single digit, we will still get the wrong state number.
The lac is given as a 2 byte number and should always be printed as four hexadecimal letters. If this is not the case, then you should have a serious talk with your vendor.
Well, if this (i.e. lac are 4 hex-digits) is the case, then I totally agree with you that it could ignore unsolicited response properly in at_util_parse_reg() for my case. Thank you so much for the coach :)
Best Regards,
Tonny