[PATCH 17/21] gprs: Add DUN server GPRS connect support
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
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