diff options
author | Denis Kenzior <denkenz@gmail.com> | 2009-12-08 03:43:54 -0600 |
---|---|---|
committer | Denis Kenzior <denkenz@gmail.com> | 2009-12-08 03:43:54 -0600 |
commit | 07bdfc6bceb25c17d6c86377db9dc337a62954f9 (patch) | |
tree | 1ccfb38f54aacda3c270eba143c39457c64c3a1b | |
parent | 81d7cd4e1251720bc9e3fca1bebe52936d07949c (diff) | |
download | ofono-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.c | 40 |
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, |