summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAlfonso Sanchez-Beato <alfonso.sanchez-beato@canonical.com>2015-05-18 08:47:06 +0200
committerDenis Kenzior <denkenz@gmail.com>2015-05-18 09:08:13 -0500
commit444611c086d3c333546e2645feba96020a4c030e (patch)
tree1f574d0c8cf8ef6b08d0c007e02ebabe176667b2 /src
parentf8d9485dc28f976ed5665cbe75ef4a55d5f84ee1 (diff)
downloadofono-444611c086d3c333546e2645feba96020a4c030e.tar.bz2
gprs: Add DBus method to reset contexts
Add DBus method that removes the current contexts and re-provisions using the APN database.
Diffstat (limited to 'src')
-rw-r--r--src/gprs.c142
1 files changed, 118 insertions, 24 deletions
diff --git a/src/gprs.c b/src/gprs.c
index 05ab4994..64fa6f10 100644
--- a/src/gprs.c
+++ b/src/gprs.c
@@ -149,6 +149,8 @@ struct pri_context {
static void gprs_netreg_update(struct ofono_gprs *gprs);
static void gprs_deactivate_next(struct ofono_gprs *gprs);
+static void provision_contexts(struct ofono_gprs *gprs, const char *mcc,
+ const char *mnc, const char *spn);
static GSList *g_drivers = NULL;
static GSList *g_context_drivers = NULL;
@@ -1885,6 +1887,36 @@ static struct pri_context *add_context(struct ofono_gprs *gprs,
return context;
}
+static void send_context_added_signal(struct ofono_gprs *gprs,
+ struct pri_context *context,
+ DBusConnection *conn)
+{
+ const char *path;
+ DBusMessage *signal;
+ DBusMessageIter iter;
+ DBusMessageIter dict;
+
+ path = __ofono_atom_get_path(gprs->atom);
+ signal = dbus_message_new_signal(path,
+ OFONO_CONNECTION_MANAGER_INTERFACE,
+ "ContextAdded");
+ if (!signal)
+ return;
+
+ dbus_message_iter_init_append(signal, &iter);
+
+ path = context->path;
+ dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH, &path);
+
+ dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
+ OFONO_PROPERTIES_ARRAY_SIGNATURE,
+ &dict);
+ append_context_properties(context, &dict);
+ dbus_message_iter_close_container(&iter, &dict);
+
+ g_dbus_send_message(conn, signal);
+}
+
static DBusMessage *gprs_add_context(DBusConnection *conn,
DBusMessage *msg, void *data)
{
@@ -1894,7 +1926,6 @@ static DBusMessage *gprs_add_context(DBusConnection *conn,
const char *name;
const char *path;
enum ofono_gprs_context_type type;
- DBusMessage *signal;
if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &typestr,
DBUS_TYPE_INVALID))
@@ -1916,29 +1947,7 @@ static DBusMessage *gprs_add_context(DBusConnection *conn,
g_dbus_send_reply(conn, msg, DBUS_TYPE_OBJECT_PATH, &path,
DBUS_TYPE_INVALID);
- path = __ofono_atom_get_path(gprs->atom);
- signal = dbus_message_new_signal(path,
- OFONO_CONNECTION_MANAGER_INTERFACE,
- "ContextAdded");
-
- if (signal) {
- DBusMessageIter iter;
- DBusMessageIter dict;
-
- dbus_message_iter_init_append(signal, &iter);
-
- path = context->path;
- dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
- &path);
-
- dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
- OFONO_PROPERTIES_ARRAY_SIGNATURE,
- &dict);
- append_context_properties(context, &dict);
- dbus_message_iter_close_container(&iter, &dict);
-
- g_dbus_send_message(conn, signal);
- }
+ send_context_added_signal(gprs, context, conn);
return NULL;
}
@@ -2173,6 +2182,89 @@ static DBusMessage *gprs_get_contexts(DBusConnection *conn,
return reply;
}
+static void remove_non_active_context(struct ofono_gprs *gprs,
+ struct pri_context *ctx, DBusConnection *conn)
+{
+ char *path;
+ const char *atompath;
+
+ if (gprs->settings) {
+ g_key_file_remove_group(gprs->settings, ctx->key, NULL);
+ storage_sync(gprs->imsi, SETTINGS_STORE, gprs->settings);
+ }
+
+ /* Make a backup copy of path for signal emission below */
+ path = g_strdup(ctx->path);
+
+ context_dbus_unregister(ctx);
+ gprs->contexts = g_slist_remove(gprs->contexts, ctx);
+
+ atompath = __ofono_atom_get_path(gprs->atom);
+ g_dbus_emit_signal(conn, atompath, OFONO_CONNECTION_MANAGER_INTERFACE,
+ "ContextRemoved", DBUS_TYPE_OBJECT_PATH, &path,
+ DBUS_TYPE_INVALID);
+ g_free(path);
+}
+
+static DBusMessage *gprs_reset_contexts(DBusConnection *conn,
+ DBusMessage *msg, void *data)
+{
+ struct ofono_gprs *gprs = data;
+ struct ofono_modem *modem = __ofono_atom_get_modem(gprs->atom);
+ struct ofono_sim *sim = __ofono_atom_find(OFONO_ATOM_TYPE_SIM, modem);
+ DBusMessage *reply;
+ GSList *l;
+
+ if (gprs->pending)
+ return __ofono_error_busy(msg);
+
+ for (l = gprs->contexts; l; l = l->next) {
+ struct pri_context *ctx = l->data;
+
+ if (ctx->pending)
+ return __ofono_error_busy(msg);
+ }
+
+ if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_INVALID))
+ return __ofono_error_invalid_args(msg);
+
+ if (gprs->powered)
+ return __ofono_error_not_allowed(msg);
+
+ for (l = gprs->contexts; l; l = l->next) {
+ struct pri_context *ctx = l->data;
+
+ if (ctx->active)
+ return __ofono_error_not_allowed(msg);
+ }
+
+ reply = dbus_message_new_method_return(msg);
+ if (reply == NULL)
+ return NULL;
+
+ /* Remove first the current contexts, re-provision after */
+
+ while (gprs->contexts != NULL) {
+ struct pri_context *ctx = gprs->contexts->data;
+ remove_non_active_context(gprs, ctx, conn);
+ }
+
+ gprs->last_context_id = 0;
+
+ provision_contexts(gprs, ofono_sim_get_mcc(sim),
+ ofono_sim_get_mnc(sim), ofono_sim_get_spn(sim));
+
+ if (gprs->contexts == NULL) /* Automatic provisioning failed */
+ add_context(gprs, NULL, OFONO_GPRS_CONTEXT_TYPE_INTERNET);
+
+ for (l = gprs->contexts; l; l = l->next) {
+ struct pri_context *ctx = l->data;
+ send_context_added_signal(gprs, ctx, conn);
+ }
+
+ return reply;
+}
+
static const GDBusMethodTable manager_methods[] = {
{ GDBUS_METHOD("GetProperties",
NULL, GDBUS_ARGS({ "properties", "a{sv}" }),
@@ -2192,6 +2284,8 @@ static const GDBusMethodTable manager_methods[] = {
{ GDBUS_METHOD("GetContexts", NULL,
GDBUS_ARGS({ "contexts_with_properties", "a(oa{sv})" }),
gprs_get_contexts) },
+ { GDBUS_ASYNC_METHOD("ResetContexts", NULL, NULL,
+ gprs_reset_contexts) },
{ }
};