summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDenis Kenzior <denkenz@gmail.com>2009-12-08 03:43:54 -0600
committerDenis Kenzior <denkenz@gmail.com>2009-12-08 03:43:54 -0600
commit07bdfc6bceb25c17d6c86377db9dc337a62954f9 (patch)
tree1ccfb38f54aacda3c270eba143c39457c64c3a1b
parent81d7cd4e1251720bc9e3fca1bebe52936d07949c (diff)
downloadofono-07bdfc6bceb25c17d6c86377db9dc337a62954f9.tar.bz2
Harden the CGREG parsing function
Sometimes the CGREG query and CGREG unsolicited notification get intermixed. Since they have the same prefix, GAtChat clumps them together. Make sure the parser skips the unsolicited notification.
-rw-r--r--drivers/atmodem/gprs.c40
1 files changed, 21 insertions, 19 deletions
diff --git a/drivers/atmodem/gprs.c b/drivers/atmodem/gprs.c
index 7aaa51a8..7af66f12 100644
--- a/drivers/atmodem/gprs.c
+++ b/drivers/atmodem/gprs.c
@@ -89,6 +89,7 @@ static void at_cgreg_cb(gboolean ok, GAtResult *result, gpointer user_data)
ofono_gprs_status_cb_t cb = cbd->cb;
int status;
const char *str;
+ int mode;
int lac = -1, ci = -1, tech = -1;
struct ofono_error error;
@@ -102,32 +103,33 @@ static void at_cgreg_cb(gboolean ok, GAtResult *result, gpointer user_data)
g_at_result_iter_init(&iter, result);
- if (!g_at_result_iter_next(&iter, "+CGREG:")) {
- CALLBACK_WITH_FAILURE(cb, -1, -1, -1, -1, cbd->data);
- return;
- }
+ while (g_at_result_iter_next(&iter, "+CGREG:")) {
+ g_at_result_iter_next_number(&iter, &mode);
- /* Skip <n> the unsolicited result code */
- g_at_result_iter_skip_next(&iter);
+ /* Sometimes we get an unsolicited CGREG here, skip it */
+ if (g_at_result_iter_next_number(&iter, &status) == FALSE)
+ continue;
- g_at_result_iter_next_number(&iter, &status);
+ if (g_at_result_iter_next_string(&iter, &str) == TRUE)
+ lac = strtol(str, NULL, 16);
+ else
+ goto out;
- if (g_at_result_iter_next_string(&iter, &str) == TRUE)
- lac = strtol(str, NULL, 16);
- else
- goto out;
+ if (g_at_result_iter_next_string(&iter, &str) == TRUE)
+ ci = strtol(str, NULL, 16);
+ else
+ goto out;
- if (g_at_result_iter_next_string(&iter, &str) == TRUE)
- ci = strtol(str, NULL, 16);
- else
- goto out;
-
- g_at_result_iter_next_number(&iter, &tech);
+ g_at_result_iter_next_number(&iter, &tech);
out:
- ofono_debug("cgreg_cb: %d, %d, %d, %d", status, lac, ci, tech);
+ ofono_debug("cgreg_cb: %d, %d, %d, %d", status, lac, ci, tech);
+
+ cb(&error, status, lac, ci, tech, cbd->data);
+ return;
+ }
- cb(&error, status, lac, ci, tech, cbd->data);
+ CALLBACK_WITH_FAILURE(cb, -1, -1, -1, -1, cbd->data);
}
static void at_gprs_registration_status(struct ofono_gprs *gprs,