[PATCH 17/21] gprs: Add DUN server GPRS connect support

2011-01-12 Thread Frédéric Dalleau
From: Zhenhua Zhang 

Implement dial up networking in GPRS atom.
---
 src/gprs.c |  229 +++-
 1 files changed, 227 insertions(+), 2 deletions(-)

diff --git a/src/gprs.c b/src/gprs.c
index 0feb344..e90f043 100644
--- a/src/gprs.c
+++ b/src/gprs.c
@@ -57,6 +57,10 @@
 #define MAX_CONTEXTS 256
 #define SUSPEND_TIMEOUT 8
 
+#define DUN_LOCAL "192.168.1.1"
+#define DUN_PEER "192.168.1.2"
+#define DUN_CONNECT_TIMEOUT 20
+
 static GSList *g_drivers = NULL;
 static GSList *g_context_drivers = NULL;
 
@@ -95,6 +99,9 @@ struct ofono_gprs {
unsigned int dun_watch;
unsigned int dun_status_watch;
struct gprs_dun_data dun_data;
+   int attach_source;
+   int context_source;
+   int timeout_source;
 };
 
 struct ofono_gprs_context {
@@ -136,6 +143,7 @@ struct pri_context {
 };
 
 static void gprs_netreg_update(struct ofono_gprs *gprs);
+static gboolean dun_connect_remove(gpointer user_data);
 static void gprs_deactivate_next(struct ofono_gprs *gprs);
 
 static const char *gprs_context_default_name(enum ofono_gprs_context_type type)
@@ -676,7 +684,9 @@ static void pri_activate_callback(const struct ofono_error 
*error,
if (error->type != OFONO_ERROR_TYPE_NO_ERROR) {
DBG("Activating context failed with error: %s",
telephony_error_to_str(error));
-   __ofono_dbus_pending_reply(&ctx->pending,
+
+   if (ctx->pending)
+   __ofono_dbus_pending_reply(&ctx->pending,
__ofono_error_failed(ctx->pending));
 
gprs_cid_release(ctx->gprs, ctx->context.cid);
@@ -684,11 +694,15 @@ static void pri_activate_callback(const struct 
ofono_error *error,
ctx->context_driver->inuse = FALSE;
ctx->context_driver = NULL;
 
+   if (ctx->gprs->dun)
+   dun_connect_remove(ctx->gprs);
+
return;
}
 
ctx->active = TRUE;
-   __ofono_dbus_pending_reply(&ctx->pending,
+   if (ctx->pending)
+   __ofono_dbus_pending_reply(&ctx->pending,
dbus_message_new_method_return(ctx->pending));
 
/*
@@ -1967,6 +1981,27 @@ void ofono_gprs_set_cid_range(struct ofono_gprs *gprs,
gprs->cid_map = idmap_new_from_range(min, max);
 }
 
+static void ofono_gprs_remove_sources(struct ofono_gprs *gprs)
+{
+   if (gprs == NULL)
+   return;
+
+   if (gprs->timeout_source) {
+   g_source_remove(gprs->timeout_source);
+   gprs->timeout_source = 0;
+   }
+
+   if (gprs->attach_source) {
+   g_source_remove(gprs->attach_source);
+   gprs->attach_source = 0;
+   }
+
+   if (gprs->context_source) {
+   g_source_remove(gprs->context_source);
+   gprs->context_source = 0;
+   }
+}
+
 static void gprs_context_unregister(struct ofono_atom *atom)
 {
struct ofono_gprs_context *gc = __ofono_atom_get_data(atom);
@@ -1974,6 +2009,8 @@ static void gprs_context_unregister(struct ofono_atom 
*atom)
if (gc->gprs == NULL)
return;
 
+   ofono_gprs_remove_sources(gc->gprs);
+
gc->gprs->context_drivers = g_slist_remove(gc->gprs->context_drivers,
gc);
gc->gprs = NULL;
@@ -2026,6 +2063,183 @@ void ofono_gprs_context_deactivated(struct 
ofono_gprs_context *gc,
}
 }
 
+static ofono_bool_t set_primary_context_powered(struct pri_context *ctx,
+   ofono_bool_t value)
+{
+   struct ofono_gprs_context *gc = ctx->context_driver;
+
+   if (gc == NULL || gc->driver->activate_primary == NULL ||
+   gc->driver->deactivate_primary == NULL ||
+   ctx->gprs->cid_map == NULL)
+   return FALSE;
+
+   if (ctx->pending)
+   return FALSE;
+
+   if (ctx->active == value)
+   return FALSE;
+
+   if (value && !ctx->gprs->attached)
+   return FALSE;
+
+   if (ctx->gprs->flags & GPRS_FLAG_ATTACHING)
+   return FALSE;
+
+   if (value) {
+   ctx->context.cid = gprs_cid_alloc(ctx->gprs);
+
+   if (ctx->context.cid == 0)
+   return FALSE;
+
+   if (ctx->context.cid !=
+   idmap_get_min(ctx->gprs->cid_map)) {
+   ofono_error("Multiple active contexts are"
+   " not yet supported");
+
+   gprs_cid_release(ctx->gprs, ctx->context.cid);
+   ctx->context.cid = 0;
+
+   return FALSE;
+   }
+   }
+
+   if (value)
+   gc->driver->activate_primary(gc, &ctx->context,
+   pri_activate_callb

[PATCH 17/21] gprs: Add DUN server GPRS connect support

2010-09-29 Thread Zhenhua Zhang
Implement dial up networking in GPRS atom.
---
 src/gprs.c |  232 +++-
 1 files changed, 229 insertions(+), 3 deletions(-)

diff --git a/src/gprs.c b/src/gprs.c
index 617ed05..eabc825 100644
--- a/src/gprs.c
+++ b/src/gprs.c
@@ -51,6 +51,10 @@
 #define MAX_CONTEXTS 256
 #define SUSPEND_TIMEOUT 8
 
+#define DUN_LOCAL "192.168.1.1"
+#define DUN_PEER "192.168.1.2"
+#define DUN_CONNECT_TIMEOUT 20
+
 static GSList *g_drivers = NULL;
 static GSList *g_context_drivers = NULL;
 
@@ -96,6 +100,9 @@ struct ofono_gprs {
unsigned int dun_watch;
unsigned int dun_status_watch;
struct gprs_dun_data dun_data;
+   int attach_source;
+   int context_source;
+   int timeout_source;
 };
 
 struct ofono_gprs_context {
@@ -128,6 +135,7 @@ struct pri_context {
 };
 
 static void gprs_netreg_update(struct ofono_gprs *gprs);
+static gboolean dun_connect_remove(gpointer user_data);
 
 static const char *gprs_context_type_to_string(int type)
 {
@@ -464,17 +472,24 @@ static void pri_activate_callback(const struct 
ofono_error *error,
if (error->type != OFONO_ERROR_TYPE_NO_ERROR) {
DBG("Activating context failed with error: %s",
telephony_error_to_str(error));
-   __ofono_dbus_pending_reply(&gc->pending,
+
+   if (gc->pending)
+   __ofono_dbus_pending_reply(&gc->pending,
__ofono_error_failed(gc->pending));
 
gprs_cid_release(ctx->gprs, ctx->context.cid);
ctx->context.cid = 0;
 
+   if (ctx->gprs->dun)
+   dun_connect_remove(ctx->gprs);
+
return;
}
 
ctx->active = TRUE;
-   __ofono_dbus_pending_reply(&gc->pending,
+
+   if (gc->pending)
+   __ofono_dbus_pending_reply(&gc->pending,
dbus_message_new_method_return(gc->pending));
 
/*
@@ -1564,12 +1579,35 @@ void ofono_gprs_set_cid_range(struct ofono_gprs *gprs,
gprs->cid_map = idmap_new_from_range(min, max);
 }
 
+static void ofono_gprs_remove_sources(struct ofono_gprs *gprs)
+{
+   if (gprs == NULL)
+   return;
+
+   if (gprs->timeout_source) {
+   g_source_remove(gprs->timeout_source);
+   gprs->timeout_source = 0;
+   }
+
+   if (gprs->attach_source) {
+   g_source_remove(gprs->attach_source);
+   gprs->attach_source = 0;
+   }
+
+   if (gprs->context_source) {
+   g_source_remove(gprs->context_source);
+   gprs->context_source = 0;
+   }
+}
+
 static void gprs_context_unregister(struct ofono_atom *atom)
 {
struct ofono_gprs_context *gc = __ofono_atom_get_data(atom);
 
-   if (gc->gprs)
+   if (gc->gprs) {
gc->gprs->context_driver = NULL;
+   ofono_gprs_remove_sources(gc->gprs);
+   }
 
gc->gprs = NULL;
 }
@@ -1613,6 +1651,183 @@ void ofono_gprs_context_deactivated(struct 
ofono_gprs_context *gc,
}
 }
 
+static ofono_bool_t set_primary_context_powered(struct pri_context *ctx,
+   ofono_bool_t value)
+{
+   struct ofono_gprs_context *gc = ctx->gprs->context_driver;
+
+   if (gc == NULL || gc->driver->activate_primary == NULL ||
+   gc->driver->deactivate_primary == NULL ||
+   ctx->gprs->cid_map == NULL)
+   return FALSE;
+
+   if (gc->pending)
+   return FALSE;
+
+   if (ctx->active == value)
+   return FALSE;
+
+   if (value && !ctx->gprs->attached)
+   return FALSE;
+
+   if (ctx->gprs->flags & GPRS_FLAG_ATTACHING)
+   return FALSE;
+
+   if (value) {
+   ctx->context.cid = gprs_cid_alloc(ctx->gprs);
+
+   if (ctx->context.cid == 0)
+   return FALSE;
+
+   if (ctx->context.cid !=
+   idmap_get_min(ctx->gprs->cid_map)) {
+   ofono_error("Multiple active contexts are"
+   " not yet supported");
+
+   gprs_cid_release(ctx->gprs, ctx->context.cid);
+   ctx->context.cid = 0;
+
+   return FALSE;
+   }
+   }
+
+   if (value)
+   gc->driver->activate_primary(gc, &ctx->context,
+   pri_activate_callback, ctx);
+   else
+   gc->driver->deactivate_primary(gc, ctx->context.cid,
+   pri_deactivate_callback, ctx);
+
+   return TRUE;
+}
+
+static void ofono_gprs_dun_disconnect(struct ofono_gprs *gprs,
+   struct ofono_emulator_req *req)
+{
+   struct pri_context *context = gprs->dun_data.context;
+
+   ofono_gprs_re