From 080ff41db96df4a04dfc9f4fbf62fa4b3ef385e3 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 29 Oct 2010 13:39:27 +0200 Subject: [PATCH] atmodem: Add support for IFX specific GPRS suspend notification The Infineon modem informs about GPRS suspend cases. For example when GPRS is active and a call is made. If the status changes, inform the core about this change. This uses GPRS_SUSPENDED_UNKNOWN_CAUSE reason since the modem does not give a clear reason why GPRS was suspended. With this reason there is a delay before the status change gets send out as D-Bus signal. --- drivers/atmodem/gprs.c | 43 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/drivers/atmodem/gprs.c b/drivers/atmodem/gprs.c index 85c76954..94247eca 100644 --- a/drivers/atmodem/gprs.c +++ b/drivers/atmodem/gprs.c @@ -28,6 +28,7 @@ #include #include #include +#include #include @@ -174,6 +175,31 @@ static void cgev_notify(GAtResult *result, gpointer user_data) } } +static void xdatastat_notify(GAtResult *result, gpointer user_data) +{ + struct ofono_gprs *gprs = user_data; + GAtResultIter iter; + int stat; + + g_at_result_iter_init(&iter, result); + + if (!g_at_result_iter_next(&iter, "+XDATASTAT:")) + return; + + if (!g_at_result_iter_next_number(&iter, &stat)) + + DBG("stat %d", stat); + + switch (stat) { + case 0: + ofono_gprs_suspend_notify(gprs, GPRS_SUSPENDED_UNKNOWN_CAUSE); + break; + case 1: + ofono_gprs_resume_notify(gprs); + break; + } +} + static void gprs_initialized(gboolean ok, GAtResult *result, gpointer user_data) { struct ofono_gprs *gprs = user_data; @@ -181,7 +207,17 @@ static void gprs_initialized(gboolean ok, GAtResult *result, gpointer user_data) g_at_chat_register(gd->chat, "+CGEV:", cgev_notify, FALSE, gprs, NULL); g_at_chat_register(gd->chat, "+CGREG:", cgreg_notify, - FALSE, gprs, NULL); + FALSE, gprs, NULL); + + switch (gd->vendor) { + case OFONO_VENDOR_IFX: + /* Register for GPRS suspend notifications */ + g_at_chat_register(gd->chat, "+XDATASTAT:", xdatastat_notify, + FALSE, gprs, NULL); + g_at_chat_send(gd->chat, "AT+XDATASTAT=1", none_prefix, + NULL, NULL, NULL); + break; + } ofono_gprs_register(gprs); } @@ -313,7 +349,10 @@ static int at_gprs_probe(struct ofono_gprs *gprs, GAtChat *chat = data; struct gprs_data *gd; - gd = g_new0(struct gprs_data, 1); + gd = g_try_new0(struct gprs_data, 1); + if (!gd) + return -ENOMEM; + gd->chat = g_at_chat_clone(chat); gd->vendor = vendor;