From 21f148afe98c082a99e7083cd3d6abd020c503e7 Mon Sep 17 00:00:00 2001 From: Lars Poeschel Date: Tue, 1 Sep 2020 11:21:11 +0200 Subject: [PATCH] atmodem: Detect usage of AT+CGEREP Currently AT+CGEREP=2,1 is sent in case we don't know what the modem needs. (default case) Not all modems understand this. So, we first query what the modem supports with AT+CGEREP=? and then use this information to be nice to the modem. This way modems, like the Quectel M95 that do only understand AT+CGEREP=1 do also work nicely. --- drivers/atmodem/gprs.c | 64 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 62 insertions(+), 2 deletions(-) diff --git a/drivers/atmodem/gprs.c b/drivers/atmodem/gprs.c index 68470f11..c208f6e6 100644 --- a/drivers/atmodem/gprs.c +++ b/drivers/atmodem/gprs.c @@ -45,6 +45,7 @@ #define MAX_CONTEXTS 255 static const char *cgreg_prefix[] = { "+CGREG:", NULL }; +static const char *cgerep_prefix[] = { "+CGEREP:", NULL }; static const char *cgdcont_prefix[] = { "+CGDCONT:", NULL }; static const char *cgact_prefix[] = { "+CGACT:", NULL }; static const char *none_prefix[] = { NULL }; @@ -648,6 +649,65 @@ static void gprs_initialized(gboolean ok, GAtResult *result, gpointer user_data) ofono_gprs_register(gprs); } +static void at_cgerep_test_cb(gboolean ok, GAtResult *result, + gpointer user_data) +{ + struct ofono_gprs *gprs = user_data; + struct gprs_data *gd = ofono_gprs_get_data(gprs); + GAtResultIter iter; + int min, max, arg1 = 0, arg2 = 0; + gboolean two_arguments = true; + char buf[20]; + + if (!ok) { + ofono_error("Error querying AT+CGEREP=? Failing..."); + ofono_gprs_remove(gprs); + return; + } + + g_at_result_iter_init(&iter, result); + + g_at_result_iter_next(&iter, "+CGEREP:"); + + if (!g_at_result_iter_open_list(&iter)) { + ofono_error("Malformed reply from AT+CGEREP=? Failing..."); + ofono_gprs_remove(gprs); + return; + } + + while (g_at_result_iter_next_range(&iter, &min, &max)) { + if ((min <= 1) && (max >= 1)) + arg1 = 1; + + if ((min <= 2) && (max >= 2)) + arg1 = 2; + } + + if (!g_at_result_iter_close_list(&iter)) + goto out; + + if (!g_at_result_iter_open_list(&iter)) { + two_arguments = false; + goto out; + } + + while (g_at_result_iter_next_range(&iter, &min, &max)) { + if ((min <= 1) && (max >= 1)) + arg2 = 1; + } + + g_at_result_iter_close_list(&iter); + +out: + if (two_arguments) + sprintf(buf, "AT+CGEREP=%u,%u", arg1, arg2); + else + sprintf(buf, "AT+CGEREP=%u", arg1); + + g_at_chat_send(gd->chat, buf, none_prefix, gprs_initialized, gprs, + NULL); +} + static void at_cgreg_test_cb(gboolean ok, GAtResult *result, gpointer user_data) { @@ -702,8 +762,8 @@ retry: gprs_initialized, gprs, NULL); break; default: - g_at_chat_send(gd->chat, "AT+CGEREP=2,1", none_prefix, - gprs_initialized, gprs, NULL); + g_at_chat_send(gd->chat, "AT+CGEREP=?", cgerep_prefix, + at_cgerep_test_cb, gprs, NULL); break; }