From: Richard Röjfors <[email protected]>
The callback calls cgact and cgdcont to get information
regarding any auto activated context.
---
drivers/atmodem/gprs.c | 115 +++++++++++++++++++++++++++++++----------
1 file changed, 88 insertions(+), 27 deletions(-)
diff --git a/drivers/atmodem/gprs.c b/drivers/atmodem/gprs.c
index 10108281..f08dc00c 100644
--- a/drivers/atmodem/gprs.c
+++ b/drivers/atmodem/gprs.c
@@ -146,27 +146,11 @@ static void at_gprs_registration_status(struct ofono_gprs
*gprs,
CALLBACK_WITH_FAILURE(cb, -1, data);
}
-static void at_cgdcont_read_cb(gboolean ok, GAtResult *result,
- gpointer user_data)
+static const char *at_cgdcont_parse(GAtResult *result, int cid)
{
- struct ofono_gprs *gprs = user_data;
- struct gprs_data *gd = ofono_gprs_get_data(gprs);
- int activated_cid = gd->last_auto_context_id;
const char *apn = NULL;
GAtResultIter iter;
- DBG("ok %d", ok);
-
- if (!ok) {
- ofono_warn("Can't read CGDCONT contexts.");
- return;
- }
-
- if (gd->last_auto_context_id == -1) {
- DBG("Context got deactivated while calling CGDCONT");
- return;
- }
-
g_at_result_iter_init(&iter, result);
while (g_at_result_iter_next(&iter, "+CGDCONT:")) {
@@ -175,7 +159,7 @@ static void at_cgdcont_read_cb(gboolean ok, GAtResult
*result,
if (!g_at_result_iter_next_number(&iter, &read_cid))
break;
- if (read_cid != activated_cid)
+ if (read_cid != cid)
continue;
/* ignore protocol */
@@ -186,6 +170,31 @@ static void at_cgdcont_read_cb(gboolean ok, GAtResult
*result,
break;
}
+ return apn;
+}
+
+static void at_cgdcont_read_cb(gboolean ok, GAtResult *result,
+ gpointer user_data)
+{
+ struct ofono_gprs *gprs = user_data;
+ struct gprs_data *gd = ofono_gprs_get_data(gprs);
+ int activated_cid = gd->last_auto_context_id;
+ const char *apn = NULL;
+
+ DBG("ok %d", ok);
+
+ if (!ok) {
+ ofono_warn("Can't read CGDCONT contexts.");
+ return;
+ }
+
+ if (activated_cid == -1) {
+ DBG("Context got deactivated while calling CGDCONT");
+ return;
+ }
+
+ apn = at_cgdcont_parse(result, activated_cid);
+
if (apn)
ofono_gprs_cid_activated(gprs, activated_cid, apn);
else
@@ -193,16 +202,46 @@ static void at_cgdcont_read_cb(gboolean ok, GAtResult
*result,
activated_cid);
}
+static void at_cgdcont_act_read_cb(gboolean ok, GAtResult *result,
+ gpointer user_data)
+{
+ struct cb_data *cbd = user_data;
+ struct gprs_data *gd = cbd->user;
+ ofono_gprs_active_context_cb_t cb = cbd->cb;
+ struct ofono_error error;
+ int activated_cid = gd->last_auto_context_id;
+ const char *apn = NULL;
+
+ decode_at_error(&error, g_at_result_final_response(result));
+
+ if (!ok) {
+ ofono_warn("Can't read CGDCONT contexts.");
+
+ activated_cid = -1;
+ } else if (activated_cid != -1) {
+ apn = at_cgdcont_parse(result, activated_cid);
+ }
+
+ cb(&error, activated_cid, apn, cbd->data);
+}
+
static void at_cgact_cb(gboolean ok, GAtResult *result, gpointer user_data)
{
- struct ofono_gprs *gprs = user_data;
- struct gprs_data *gd = ofono_gprs_get_data(gprs);
+ struct cb_data *cbd = user_data;
+ struct gprs_data *gd = cbd->user;
+ ofono_gprs_active_context_cb_t cb = cbd->cb;
+ struct ofono_error error;
GAtResultIter iter;
- DBG("ok %d", ok);
+ decode_at_error(&error, g_at_result_final_response(result));
if (!ok) {
ofono_warn("Can't read CGACT contexts.");
+
+ cb(&error, -1, NULL, cbd->data);
+
+ g_free(cbd);
+
return;
}
@@ -222,17 +261,42 @@ static void at_cgact_cb(gboolean ok, GAtResult *result,
gpointer user_data)
continue;
/* Flag this as auto context as it was obviously active */
- if (gd->last_auto_context_id == 0)
+ if (gd->last_auto_context_id == -1)
gd->last_auto_context_id = read_cid;
if (read_cid != gd->last_auto_context_id)
continue;
g_at_chat_send(gd->chat, "AT+CGDCONT?", cgdcont_prefix,
- at_cgdcont_read_cb, gprs, NULL);
+ at_cgdcont_act_read_cb, cbd, g_free);
break;
}
+
+ if (gd->last_auto_context_id == -1) {
+ /* No error, but no auto activated contexts... */
+ cb(&error, -1, NULL, cbd->data);
+
+ g_free(cbd);
+ }
+}
+
+static void at_gprs_get_active_auto_context(struct ofono_gprs *gprs,
+ ofono_gprs_active_context_cb_t cb,
+ void *data)
+{
+ struct gprs_data *gd = ofono_gprs_get_data(gprs);
+ struct cb_data *cbd = cb_data_new(cb, data);
+
+ cbd->user = gd;
+
+ if (g_at_chat_send(gd->chat, "AT+CGACT?", cgact_prefix,
+ at_cgact_cb, cbd, NULL))
+ return;
+
+ g_free(cbd);
+
+ CALLBACK_WITH_FAILURE(cb, -1, NULL, data);
}
static void cgreg_notify(GAtResult *result, gpointer user_data)
@@ -538,10 +602,6 @@ static void gprs_initialized(gboolean ok, GAtResult
*result, gpointer user_data)
break;
}
- /* Check if there is any already activated contexts at init */
- g_at_chat_send(gd->chat, "AT+CGACT?", cgact_prefix,
- at_cgact_cb, gprs, NULL);
-
ofono_gprs_register(gprs);
}
@@ -705,6 +765,7 @@ static const struct ofono_gprs_driver driver = {
.remove = at_gprs_remove,
.set_attached = at_gprs_set_attached,
.attached_status = at_gprs_registration_status,
+ .get_active_auto_context= at_gprs_get_active_auto_context,
};
void at_gprs_init(void)
--
2.20.1
_______________________________________________
ofono mailing list
[email protected]
https://lists.ofono.org/mailman/listinfo/ofono