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

_______________________________________________
ofono mailing list
[email protected]
http://lists.ofono.org/listinfo/ofono

Reply via email to