* [PATCH 1/5] idmap: add api for finding a certain id in map
2016-03-18 11:58 [PATCH v4 0/5] allow automatic context activation Dragos Tatulea
@ 2016-03-18 11:58 ` Dragos Tatulea
2016-03-18 15:03 ` Denis Kenzior
2016-03-18 11:58 ` [PATCH 2/5] gprs-context.h: add op for reading context config Dragos Tatulea
` (3 subsequent siblings)
4 siblings, 1 reply; 13+ messages in thread
From: Dragos Tatulea @ 2016-03-18 11:58 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 1381 bytes --]
---
src/idmap.c | 12 ++++++++++++
src/idmap.h | 1 +
2 files changed, 13 insertions(+)
diff --git a/src/idmap.c b/src/idmap.c
index c097eb4..da32d96 100644
--- a/src/idmap.c
+++ b/src/idmap.c
@@ -166,6 +166,18 @@ void idmap_take(struct idmap *idmap, unsigned int id)
idmap->bits[offset] |= 1UL << (bit % BITS_PER_LONG);
}
+int idmap_find(struct idmap *idmap, unsigned int id)
+{
+ unsigned int bit = id - idmap->min;
+ unsigned int offset;
+
+ if (bit >= idmap->size)
+ return 0;
+
+ offset = bit / BITS_PER_LONG;
+ return (idmap->bits[offset] & (1UL << (bit % BITS_PER_LONG))) != 0;
+}
+
/*
* Allocate the next bit skipping the ids up to and including last. If there
* is no free ids until the max id is encountered, the counter is wrapped back
diff --git a/src/idmap.h b/src/idmap.h
index ebda177..97a6f04 100644
--- a/src/idmap.h
+++ b/src/idmap.h
@@ -25,6 +25,7 @@ struct idmap *idmap_new(unsigned int size);
void idmap_free(struct idmap *idmap);
void idmap_put(struct idmap *idmap, unsigned int id);
void idmap_take(struct idmap *idmap, unsigned int id);
+int idmap_find(struct idmap *idmap, unsigned int id);
unsigned int idmap_alloc(struct idmap *idmap);
unsigned int idmap_alloc_next(struct idmap *idmap, unsigned int last);
struct idmap *idmap_new_from_range(unsigned int min, unsigned int max);
--
2.5.0
^ permalink raw reply related [flat|nested] 13+ messages in thread* [PATCH 2/5] gprs-context.h: add op for reading context config
2016-03-18 11:58 [PATCH v4 0/5] allow automatic context activation Dragos Tatulea
2016-03-18 11:58 ` [PATCH 1/5] idmap: add api for finding a certain id in map Dragos Tatulea
@ 2016-03-18 11:58 ` Dragos Tatulea
2016-03-18 15:04 ` Denis Kenzior
2016-03-18 11:58 ` [PATCH 3/5] gprs: implement ofono_gprs_cid_activated Dragos Tatulea
` (2 subsequent siblings)
4 siblings, 1 reply; 13+ messages in thread
From: Dragos Tatulea @ 2016-03-18 11:58 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 820 bytes --]
This will be implemented by a gprs-context driver to support
automatic context activation. The gprs atom will call the driver
to read the ip configuration without activating the context.
---
include/gprs-context.h | 3 +++
1 file changed, 3 insertions(+)
diff --git a/include/gprs-context.h b/include/gprs-context.h
index 0090cc4..c4910f2 100644
--- a/include/gprs-context.h
+++ b/include/gprs-context.h
@@ -79,6 +79,9 @@ struct ofono_gprs_context_driver {
ofono_gprs_context_cb_t cb, void *data);
void (*detach_shutdown)(struct ofono_gprs_context *gc,
unsigned int id);
+ void (*read_settings)(struct ofono_gprs_context *gc,
+ unsigned int cid,
+ ofono_gprs_context_cb_t cb, void *data);
};
void ofono_gprs_context_deactivated(struct ofono_gprs_context *gc,
--
2.5.0
^ permalink raw reply related [flat|nested] 13+ messages in thread* [PATCH 3/5] gprs: implement ofono_gprs_cid_activated
2016-03-18 11:58 [PATCH v4 0/5] allow automatic context activation Dragos Tatulea
2016-03-18 11:58 ` [PATCH 1/5] idmap: add api for finding a certain id in map Dragos Tatulea
2016-03-18 11:58 ` [PATCH 2/5] gprs-context.h: add op for reading context config Dragos Tatulea
@ 2016-03-18 11:58 ` Dragos Tatulea
2016-03-18 15:10 ` Denis Kenzior
2016-03-18 11:58 ` [PATCH 4/5] atmodem: gprs: handle automatic context activation Dragos Tatulea
2016-03-18 11:58 ` [PATCH 5/5] ubloxmodem: support automatic ctx activation Dragos Tatulea
4 siblings, 1 reply; 13+ messages in thread
From: Dragos Tatulea @ 2016-03-18 11:58 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 4455 bytes --]
It works by looking for a context with the same APN and tries to use
that. Otherwise it will create it's own.
Then it assigns a gprs context driver and calls it's read_settings if
it exists.
---
src/gprs.c | 114 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 114 insertions(+)
diff --git a/src/gprs.c b/src/gprs.c
index e956a23..9a85121 100644
--- a/src/gprs.c
+++ b/src/gprs.c
@@ -293,6 +293,11 @@ static void gprs_cid_release(struct ofono_gprs *gprs, unsigned int id)
idmap_put(gprs->cid_map, id);
}
+static gboolean gprs_cid_taken(struct ofono_gprs *gprs, unsigned int id)
+{
+ return idmap_find(gprs->cid_map, id) != 0;
+}
+
static gboolean assign_context(struct pri_context *ctx, int use_cid)
{
struct idmap *cidmap = ctx->gprs->cid_map;
@@ -943,6 +948,39 @@ static void pri_deactivate_callback(const struct ofono_error *error, void *data)
"Active", DBUS_TYPE_BOOLEAN, &value);
}
+static void pri_read_settings_callback(const struct ofono_error *error,
+ void *data)
+{
+ struct pri_context *pri_ctx = data;
+ struct ofono_gprs_context *gc = pri_ctx->context_driver;
+ DBusConnection *conn = ofono_dbus_get_connection();
+ dbus_bool_t value;
+
+ DBG("%p", pri_ctx);
+
+ if (error->type != OFONO_ERROR_TYPE_NO_ERROR) {
+ DBG("Reading context settings failed with error: %s",
+ telephony_error_to_str(error));
+ context_settings_free(pri_ctx->context_driver->settings);
+ release_context(pri_ctx);
+ return;
+ }
+
+ pri_ctx->active = TRUE;
+
+ if (gc->settings->interface != NULL) {
+ pri_ifupdown(gc->settings->interface, TRUE);
+
+ pri_context_signal_settings(pri_ctx, gc->settings->ipv4 != NULL,
+ gc->settings->ipv6 != NULL);
+ }
+
+ value = pri_ctx->active;
+ ofono_dbus_signal_property_changed(conn, pri_ctx->path,
+ OFONO_CONNECTION_CONTEXT_INTERFACE,
+ "Active", DBUS_TYPE_BOOLEAN, &value);
+}
+
static DBusMessage *pri_set_apn(struct pri_context *ctx, DBusConnection *conn,
DBusMessage *msg, const char *apn)
{
@@ -1840,6 +1878,35 @@ static void write_context_settings(struct ofono_gprs *gprs,
}
}
+static struct pri_context *find_usable_context(struct ofono_gprs *gprs,
+ const char *apn)
+{
+ GSList *l;
+ struct pri_context *pri_ctx;
+
+ /* Look for matching APN: */
+ for (l = gprs->contexts; l; l = l->next) {
+ pri_ctx = l->data;
+
+ /* Looking only at prefix for the LTE case when a user APN is
+ * web.provider.com but it apepars as
+ * web.provider.com.mncX.mccY.gprs .
+ */
+ if (g_str_has_prefix(apn, pri_ctx->context.apn))
+ return pri_ctx;
+ }
+
+ /* Look for a provision failed pri context: */
+ for (l = gprs->contexts; l; l = l->next) {
+ pri_ctx = l->data;
+
+ if (pri_ctx->context.apn == NULL)
+ return pri_ctx;
+ }
+
+ return NULL;
+}
+
static struct pri_context *add_context(struct ofono_gprs *gprs,
const char *name,
enum ofono_gprs_context_type type)
@@ -1883,6 +1950,53 @@ static struct pri_context *add_context(struct ofono_gprs *gprs,
return context;
}
+void ofono_gprs_cid_activated(struct ofono_gprs *gprs, unsigned int cid,
+ const char *apn)
+{
+ struct pri_context *pri_ctx;
+ struct ofono_gprs_context *gc;
+
+ DBG("");
+
+ if (gprs_cid_taken(gprs, cid)) {
+ DBG("cid %u already activated", cid);
+ return;
+ }
+
+ pri_ctx = find_usable_context(gprs, apn);
+
+ if (!pri_ctx) {
+ pri_ctx = add_context(gprs, apn,
+ OFONO_GPRS_CONTEXT_TYPE_INTERNET);
+ if (!pri_ctx) {
+ ofono_error("Can't find/create automatic context %d "
+ "with APN %s.", cid, apn);
+ return;
+ }
+ }
+
+ if (assign_context(pri_ctx, cid) == FALSE) {
+ ofono_warn("Can't assign context to driver for APN.");
+ release_context(pri_ctx);
+ return;
+ }
+
+ gc = pri_ctx->context_driver;
+
+ if (gc->driver->read_settings == NULL) {
+ ofono_warn("Context activated for driver that doesn't support "
+ "automatic context activation.");
+ release_context(pri_ctx);
+ }
+
+ if (strlen(pri_ctx->context.apn) == 0) {
+ DBusConnection *conn = ofono_dbus_get_connection();
+ pri_set_apn(pri_ctx, conn, NULL, apn);
+ }
+
+ gc->driver->read_settings(gc, cid, pri_read_settings_callback, pri_ctx);
+}
+
static void send_context_added_signal(struct ofono_gprs *gprs,
struct pri_context *context,
DBusConnection *conn)
--
2.5.0
^ permalink raw reply related [flat|nested] 13+ messages in thread* [PATCH 4/5] atmodem: gprs: handle automatic context activation
2016-03-18 11:58 [PATCH v4 0/5] allow automatic context activation Dragos Tatulea
` (2 preceding siblings ...)
2016-03-18 11:58 ` [PATCH 3/5] gprs: implement ofono_gprs_cid_activated Dragos Tatulea
@ 2016-03-18 11:58 ` Dragos Tatulea
2016-03-18 15:11 ` Denis Kenzior
2016-03-18 11:58 ` [PATCH 5/5] ubloxmodem: support automatic ctx activation Dragos Tatulea
4 siblings, 1 reply; 13+ messages in thread
From: Dragos Tatulea @ 2016-03-18 11:58 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 2577 bytes --]
When the event comes, trigger CGCONT? to read the APN for the
activated cid and then call ogono_gprs_cid_activated to handle
the event.
---
drivers/atmodem/gprs.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 50 insertions(+)
diff --git a/drivers/atmodem/gprs.c b/drivers/atmodem/gprs.c
index 4505477..bc3c633 100644
--- a/drivers/atmodem/gprs.c
+++ b/drivers/atmodem/gprs.c
@@ -49,6 +49,7 @@ static const char *none_prefix[] = { NULL };
struct gprs_data {
GAtChat *chat;
unsigned int vendor;
+ unsigned int last_auto_context_id;
};
static void at_cgatt_cb(gboolean ok, GAtResult *result, gpointer user_data)
@@ -141,6 +142,49 @@ 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)
+{
+ 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;
+ }
+
+ g_at_result_iter_init(&iter, result);
+
+ while (g_at_result_iter_next(&iter, "+CGDCONT:")) {
+ int read_cid;
+
+ if (!g_at_result_iter_next_number(&iter, &read_cid))
+ break;
+
+ if (read_cid != activated_cid)
+ continue;
+
+ /* ignore protocol */
+ g_at_result_iter_skip_next(&iter);
+
+ g_at_result_iter_next_string(&iter, &apn);
+
+ break;
+ }
+
+ if (apn)
+ ofono_gprs_cid_activated(gprs, activated_cid, apn);
+ else
+ ofono_warn("cid %u: Received activated but no apn present",
+ activated_cid);
+}
+
+
static void cgreg_notify(GAtResult *result, gpointer user_data)
{
struct ofono_gprs *gprs = user_data;
@@ -157,6 +201,7 @@ static void cgreg_notify(GAtResult *result, gpointer user_data)
static void cgev_notify(GAtResult *result, gpointer user_data)
{
struct ofono_gprs *gprs = user_data;
+ struct gprs_data *gd = ofono_gprs_get_data(gprs);
GAtResultIter iter;
const char *event;
@@ -172,6 +217,11 @@ static void cgev_notify(GAtResult *result, gpointer user_data)
g_str_equal(event, "ME DETACH")) {
ofono_gprs_detached_notify(gprs);
return;
+ } else if (g_str_has_prefix(event, "ME PDN ACT")) {
+ sscanf(event, "%*s %*s %*s %u", &gd->last_auto_context_id);
+
+ g_at_chat_send(gd->chat, "AT+CGDCONT?", cgdcont_prefix,
+ at_cgdcont_read_cb, gprs, NULL);
}
}
--
2.5.0
^ permalink raw reply related [flat|nested] 13+ messages in thread* Re: [PATCH 4/5] atmodem: gprs: handle automatic context activation
2016-03-18 11:58 ` [PATCH 4/5] atmodem: gprs: handle automatic context activation Dragos Tatulea
@ 2016-03-18 15:11 ` Denis Kenzior
0 siblings, 0 replies; 13+ messages in thread
From: Denis Kenzior @ 2016-03-18 15:11 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 2906 bytes --]
Hi Dragos,
On 03/18/2016 06:58 AM, Dragos Tatulea wrote:
> When the event comes, trigger CGCONT? to read the APN for the
> activated cid and then call ogono_gprs_cid_activated to handle
> the event.
> ---
> drivers/atmodem/gprs.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 50 insertions(+)
>
Applied, but...
> diff --git a/drivers/atmodem/gprs.c b/drivers/atmodem/gprs.c
> index 4505477..bc3c633 100644
> --- a/drivers/atmodem/gprs.c
> +++ b/drivers/atmodem/gprs.c
> @@ -49,6 +49,7 @@ static const char *none_prefix[] = { NULL };
> struct gprs_data {
> GAtChat *chat;
> unsigned int vendor;
> + unsigned int last_auto_context_id;
> };
>
> static void at_cgatt_cb(gboolean ok, GAtResult *result, gpointer user_data)
> @@ -141,6 +142,49 @@ 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)
> +{
> + 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;
> + }
> +
> + g_at_result_iter_init(&iter, result);
> +
> + while (g_at_result_iter_next(&iter, "+CGDCONT:")) {
> + int read_cid;
> +
> + if (!g_at_result_iter_next_number(&iter, &read_cid))
> + break;
> +
> + if (read_cid != activated_cid)
> + continue;
> +
> + /* ignore protocol */
> + g_at_result_iter_skip_next(&iter);
> +
> + g_at_result_iter_next_string(&iter, &apn);
> +
> + break;
> + }
> +
> + if (apn)
> + ofono_gprs_cid_activated(gprs, activated_cid, apn);
> + else
> + ofono_warn("cid %u: Received activated but no apn present",
> + activated_cid);
> +}
> +
> +
Silently squashed this double-empty line.
> static void cgreg_notify(GAtResult *result, gpointer user_data)
> {
> struct ofono_gprs *gprs = user_data;
> @@ -157,6 +201,7 @@ static void cgreg_notify(GAtResult *result, gpointer user_data)
> static void cgev_notify(GAtResult *result, gpointer user_data)
> {
> struct ofono_gprs *gprs = user_data;
> + struct gprs_data *gd = ofono_gprs_get_data(gprs);
> GAtResultIter iter;
> const char *event;
>
> @@ -172,6 +217,11 @@ static void cgev_notify(GAtResult *result, gpointer user_data)
> g_str_equal(event, "ME DETACH")) {
> ofono_gprs_detached_notify(gprs);
> return;
> + } else if (g_str_has_prefix(event, "ME PDN ACT")) {
> + sscanf(event, "%*s %*s %*s %u", &gd->last_auto_context_id);
> +
> + g_at_chat_send(gd->chat, "AT+CGDCONT?", cgdcont_prefix,
> + at_cgdcont_read_cb, gprs, NULL);
> }
> }
>
>
Regards,
-Denis
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 5/5] ubloxmodem: support automatic ctx activation
2016-03-18 11:58 [PATCH v4 0/5] allow automatic context activation Dragos Tatulea
` (3 preceding siblings ...)
2016-03-18 11:58 ` [PATCH 4/5] atmodem: gprs: handle automatic context activation Dragos Tatulea
@ 2016-03-18 11:58 ` Dragos Tatulea
2016-03-18 15:13 ` Denis Kenzior
4 siblings, 1 reply; 13+ messages in thread
From: Dragos Tatulea @ 2016-03-18 11:58 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 2180 bytes --]
... by imlementing read_settings.
---
drivers/ubloxmodem/gprs-context.c | 32 ++++++++++++++++++++++----------
1 file changed, 22 insertions(+), 10 deletions(-)
diff --git a/drivers/ubloxmodem/gprs-context.c b/drivers/ubloxmodem/gprs-context.c
index 63f6ac2..23c27aa 100644
--- a/drivers/ubloxmodem/gprs-context.c
+++ b/drivers/ubloxmodem/gprs-context.c
@@ -35,6 +35,7 @@
#include <ofono/log.h>
#include <ofono/modem.h>
#include <ofono/gprs-context.h>
+#include <ofono/gprs.h>
#include "gatchat.h"
#include "gatresult.h"
@@ -181,6 +182,21 @@ static void ublox_read_settings(struct ofono_gprs_context *gc)
CALLBACK_WITH_FAILURE(gcd->cb, gcd->cb_data);
}
+static void ublox_gprs_read_settings(struct ofono_gprs_context *gc,
+ unsigned int cid,
+ ofono_gprs_context_cb_t cb, void *data)
+{
+ struct gprs_context_data *gcd = ofono_gprs_context_get_data(gc);
+
+ DBG("cid %u", cid);
+
+ gcd->active_context = cid;
+ gcd->cb = cb;
+ gcd->cb_data = data;
+
+ ublox_read_settings(gc);
+}
+
static void cgact_enable_cb(gboolean ok, GAtResult *result, gpointer user_data)
{
struct ofono_gprs_context *gc = user_data;
@@ -379,16 +395,11 @@ static void cgev_notify(GAtResult *result, gpointer user_data)
if (!g_at_result_iter_next_unquoted_string(&iter, &event))
return;
- if (g_str_has_prefix(event, "NW PDN DEACT")) {
- if (!g_at_result_iter_skip_next(&iter))
- return;
- } else if (g_str_has_prefix(event, "NW DEACT") == FALSE)
- return;
-
- if (!g_at_result_iter_skip_next(&iter))
- return;
-
- if (!g_at_result_iter_next_number(&iter, &cid))
+ if (g_str_has_prefix(event, "NW PDN DEACT"))
+ sscanf(event, "%*s %*s %*s %u", &cid);
+ else if (g_str_has_prefix(event, "NW DEACT"))
+ sscanf(event, "%*s %*s %u", &cid);
+ else
return;
DBG("cid %d", cid);
@@ -440,6 +451,7 @@ static struct ofono_gprs_context_driver driver = {
.remove = ublox_gprs_context_remove,
.activate_primary = ublox_gprs_activate_primary,
.deactivate_primary = ublox_gprs_deactivate_primary,
+ .read_settings = ublox_gprs_read_settings,
};
void ublox_gprs_context_init(void)
--
2.5.0
^ permalink raw reply related [flat|nested] 13+ messages in thread