Attach automatically when a GPRS context is activated
---
src/gprs.c | 153 ++++++++++++++++++++++++++++++++---------------------------
1 files changed, 83 insertions(+), 70 deletions(-)
diff --git a/src/gprs.c b/src/gprs.c
index 610f3b2..d4b4e24 100644
--- a/src/gprs.c
+++ b/src/gprs.c
@@ -106,6 +106,7 @@ struct context_settings {
struct pri_context {
ofono_bool_t active;
+ ofono_bool_t activation_pending;
enum ofono_gprs_context_type type;
char name[MAX_CONTEXT_NAME_LENGTH + 1];
char message_proxy[MAX_MESSAGE_PROXY_LENGTH + 1];
@@ -647,6 +648,49 @@ static DBusMessage *pri_get_properties(DBusConnection *conn,
return reply;
}
+static gboolean assign_context(struct pri_context *ctx)
+{
+ struct idmap *cidmap = ctx->gprs->cid_map;
+ unsigned int cid_min;
+ GSList *l;
+
+ if (cidmap == NULL)
+ return FALSE;
+
+ cid_min = idmap_get_min(cidmap);
+
+ ctx->context.cid = gprs_cid_alloc(ctx->gprs);
+ if (ctx->context.cid == 0)
+ return FALSE;
+
+ for (l = ctx->gprs->context_drivers; l; l = l->next) {
+ struct ofono_gprs_context *gc = l->data;
+
+ if (gc->inuse == TRUE)
+ continue;
+
+ if (gc->type == OFONO_GPRS_CONTEXT_TYPE_ANY ||
+ gc->type == ctx->type) {
+ ctx->context_driver = gc;
+ ctx->context_driver->inuse = TRUE;
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+static void free_context(struct pri_context *ctx)
+{
+ gprs_cid_release(ctx->gprs, ctx->context.cid);
+ ctx->context.cid = 0;
+ ctx->active = FALSE;
+ ctx->activation_pending = FALSE;
+ if (ctx->context_driver)
+ ctx->context_driver->inuse = FALSE;
+ ctx->context_driver = NULL;
+}
+
static void pri_activate_callback(const struct ofono_error *error,
const char *interface,
ofono_bool_t static_ip,
@@ -666,11 +710,7 @@ static void pri_activate_callback(const struct ofono_error *error,
__ofono_dbus_pending_reply(&ctx->pending,
__ofono_error_failed(ctx->pending));
- gprs_cid_release(ctx->gprs, ctx->context.cid);
- ctx->context.cid = 0;
- ctx->context_driver->inuse = FALSE;
- ctx->context_driver = NULL;
-
+ free_context(ctx);
return;
}
@@ -706,15 +746,9 @@ static void pri_deactivate_callback(const struct ofono_error *error,
void *data)
return;
}
- gprs_cid_release(ctx->gprs, ctx->context.cid);
- ctx->context.cid = 0;
- ctx->active = FALSE;
- ctx->context_driver->inuse = FALSE;
- ctx->context_driver = NULL;
-
+ free_context(ctx);
__ofono_dbus_pending_reply(&ctx->pending,
dbus_message_new_method_return(ctx->pending));
-
pri_reset_context_settings(ctx);
value = ctx->active;
@@ -957,38 +991,6 @@ static DBusMessage *pri_set_message_center(struct pri_context *ctx,
return NULL;
}
-static gboolean assign_context(struct pri_context *ctx)
-{
- struct idmap *cidmap = ctx->gprs->cid_map;
- unsigned int cid_min;
- GSList *l;
-
- if (cidmap == NULL)
- return FALSE;
-
- cid_min = idmap_get_min(cidmap);
-
- ctx->context.cid = gprs_cid_alloc(ctx->gprs);
- if (ctx->context.cid == 0)
- return FALSE;
-
- for (l = ctx->gprs->context_drivers; l; l = l->next) {
- struct ofono_gprs_context *gc = l->data;
-
- if (gc->inuse == TRUE)
- continue;
-
- if (gc->type == OFONO_GPRS_CONTEXT_TYPE_ANY ||
- gc->type == ctx->type) {
- ctx->context_driver = gc;
- ctx->context_driver->inuse = TRUE;
- return TRUE;
- }
- }
-
- return FALSE;
-}
-
static DBusMessage *pri_set_property(DBusConnection *conn,
DBusMessage *msg, void *data)
{
@@ -1030,8 +1032,19 @@ static DBusMessage *pri_set_property(DBusConnection *conn,
if (ctx->active == (ofono_bool_t) value)
return dbus_message_new_method_return(msg);
- if (value && !ctx->gprs->attached)
- return __ofono_error_not_attached(msg);
+ if (value && !ctx->gprs->attached) {
+ gprs_netreg_update(ctx->gprs);
+
+ if (!(ctx->gprs->flags & GPRS_FLAG_ATTACHING))
+ return __ofono_error_not_attached(msg);
+
+ if (!assign_context(ctx))
+ return __ofono_error_not_implemented(msg);
+
+ ctx->activation_pending = TRUE;
+ ctx->pending = dbus_message_ref(msg);
+ return NULL;
+ }
if (ctx->gprs->flags & GPRS_FLAG_ATTACHING)
return __ofono_error_attach_in_progress(msg);
@@ -1284,6 +1297,8 @@ static void gprs_attached_update(struct ofono_gprs *gprs)
const char *path;
ofono_bool_t attached;
dbus_bool_t value;
+ GSList *l;
+ struct pri_context *ctx;
attached = gprs->driver_attached &&
(gprs->status == NETWORK_REGISTRATION_STATUS_REGISTERED ||
@@ -1294,24 +1309,32 @@ static void gprs_attached_update(struct ofono_gprs *gprs)
gprs->attached = attached;
- if (gprs->attached == FALSE) {
- GSList *l;
- struct pri_context *ctx;
-
- for (l = gprs->contexts; l; l = l->next) {
- ctx = l->data;
+ for (l = gprs->contexts; l; l = l->next) {
+ struct pri_context *ctx = l->data;
+ struct ofono_gprs_context *gc = ctx->context_driver;
- if (ctx->active == FALSE)
+ if (attached) {
+ if (!ctx->activation_pending)
continue;
- gprs_cid_release(gprs, ctx->context.cid);
- ctx->context.cid = 0;
- ctx->active = FALSE;
- ctx->context_driver->inuse = FALSE;
- ctx->context_driver = NULL;
+ ctx->activation_pending = FALSE;
+ gc->driver->activate_primary(gc, &ctx->context,
+ pri_activate_callback,
+ ctx);
+ } else {
+ ofono_bool_t active = ctx->active;
+
+ if (ctx->activation_pending)
+ __ofono_dbus_pending_reply(&ctx->pending,
+ __ofono_error_failed(ctx->pending));
+
+ free_context(ctx);
pri_reset_context_settings(ctx);
+ if (!active)
+ continue;
+
value = FALSE;
ofono_dbus_signal_property_changed(conn, ctx->path,
OFONO_CONNECTION_CONTEXT_INTERFACE,
@@ -1758,12 +1781,7 @@ static void gprs_deactivate_for_all(const struct ofono_error
*error,
return;
}
- gprs_cid_release(gprs, ctx->context.cid);
- ctx->active = FALSE;
- ctx->context.cid = 0;
- ctx->context_driver->inuse = FALSE;
- ctx->context_driver = NULL;
-
+ free_context(ctx);
pri_reset_context_settings(ctx);
value = ctx->active;
@@ -1997,12 +2015,7 @@ void ofono_gprs_context_deactivated(struct ofono_gprs_context *gc,
if (ctx->context.cid != cid)
continue;
- gprs_cid_release(ctx->gprs, ctx->context.cid);
- ctx->context.cid = 0;
- ctx->active = FALSE;
- ctx->context_driver->inuse = FALSE;
- ctx->context_driver = NULL;
-
+ free_context(ctx);
pri_reset_context_settings(ctx);
value = FALSE;
--
1.7.1