All of lore.kernel.org
 help / color / mirror / Atom feed
* [gprs-provision PATCHv5 0/6] Plugin API for provisioning of GPRS context setting
@ 2011-01-20 13:11 Jukka Saunamaki
  2011-01-20 13:11 ` [PATCH 1/6] gprs-provision: add driver API header Jukka Saunamaki
                   ` (5 more replies)
  0 siblings, 6 replies; 13+ messages in thread
From: Jukka Saunamaki @ 2011-01-20 13:11 UTC (permalink / raw)
  To: ofono

[-- Attachment #1: Type: text/plain, Size: 2302 bytes --]

Hello

And again, here is a new patchset about implementing automatic provisioning of GPRS context settings.

Since last time, driver API should be cleaner now. Some whitespace issues fixed, and probably some new ones introduced :)

Example driver patch requires ofono_sim_get_mcc/mnc in SIM atom API patches, that I mailed earlier.

[copy from earlier mail]
Provisioning data for gprs contexts is returned by gprs-provisioning plugins/drivers. Different kind of provisioning modules may be created for different platforms or use cases.
It is up to the module what settings database it uses, and how many, and what type of contexts (with settings) it returns.
Several plugins may be loaded in oFono, and they will be called in priority order until first plugin returns non-empty result.

Provisioning modules are called in case there are no previously configured contexts found during gprs atom registration.
 
These patches add new gprs-provision.[hc] API for provisioning plugins to register into, and __ofono_gprs_provision_get_settings for gprs.c to call when needed.
gprs.c is modified to use provisioning if reading existing context settings fails.

A dummy example provisioning plugin is included. In case it is called when using phonesim with default.xml configuration, the plugin returns dummy settings for two contexts, one type Internet and one type MMS. 

--Jukka Saunamäki


Jukka Saunamaki (6):
      gprs-provision: add driver API header
      ofono.h: add new atom type for gprs-provision
      gprs-provision: add driver API sources
      modem: probe gprs_provision drivers
      gprs: add gprs context provisioning
      gprs-provision: add example context provisioning driver

 Makefile.am              |    7 +-
 examples/provision.c     |  221 ++++++++++++++++++++++++++++++++++++++++++++++
 include/gprs-provision.h |   74 +++++++++++++++
 src/gprs-provision.c     |  219 +++++++++++++++++++++++++++++++++++++++++++++
 src/gprs.c               |  147 ++++++++++++++++++++++++++++---
 src/modem.c              |    1 +
 src/ofono.h              |    8 ++
 7 files changed, 661 insertions(+), 16 deletions(-)
 create mode 100644 examples/provision.c
 create mode 100644 include/gprs-provision.h
 create mode 100644 src/gprs-provision.c


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH 1/6] gprs-provision: add driver API header
  2011-01-20 13:11 [gprs-provision PATCHv5 0/6] Plugin API for provisioning of GPRS context setting Jukka Saunamaki
@ 2011-01-20 13:11 ` Jukka Saunamaki
  2011-01-20 21:51   ` Denis Kenzior
  2011-01-20 13:11 ` [PATCH 2/6] ofono.h: add new atom type for gprs-provision Jukka Saunamaki
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 13+ messages in thread
From: Jukka Saunamaki @ 2011-01-20 13:11 UTC (permalink / raw)
  To: ofono

[-- Attachment #1: Type: text/plain, Size: 3056 bytes --]

---
 Makefile.am              |    2 +-
 include/gprs-provision.h |   74 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 75 insertions(+), 1 deletions(-)
 create mode 100644 include/gprs-provision.h

diff --git a/Makefile.am b/Makefile.am
index c1c34ca..7a03f08 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -13,7 +13,7 @@ pkginclude_HEADERS = include/log.h include/plugin.h include/history.h \
 			include/radio-settings.h include/stk.h \
 			include/audio-settings.h include/nettime.h \
 			include/ctm.h include/cdma-voicecall.h \
-			include/cdma-sms.h
+			include/cdma-sms.h include/gprs-provision.h
 
 nodist_pkginclude_HEADERS = include/version.h
 
diff --git a/include/gprs-provision.h b/include/gprs-provision.h
new file mode 100644
index 0000000..cc751d2
--- /dev/null
+++ b/include/gprs-provision.h
@@ -0,0 +1,74 @@
+/*
+ *
+ *  oFono - Open Telephony stack for Linux
+ *
+ *  Copyright (C) 2011  Nokia Corporation and/or its subsidiary(-ies).
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#ifndef __OFONO_GPRS_PROVISION_H
+#define __OFONO_GPRS_PROVISION_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "gprs-context.h"
+
+struct ofono_gprs_provision_context {
+	struct ofono_gprs_provision_driver *driver;
+	struct ofono_modem *modem;
+	void *data;
+};
+
+struct ofono_gprs_provision_data {
+	enum ofono_gprs_context_type type;
+	enum ofono_gprs_proto proto;
+	char *name;
+	char *apn;
+	char *username;
+	char *password;
+	char *message_proxy;
+	char *message_center;
+};
+
+/*
+ * Callback from provisioning plugin.
+ */
+typedef void (*ofono_gprs_provision_cb_t)(
+			const struct ofono_gprs_provision_data settings[],
+			int count, void *user_data);
+
+struct ofono_gprs_provision_driver {
+	const char *name;
+	int priority;
+	int (*probe)(struct ofono_gprs_provision_context *context);
+	void (*remove)(struct ofono_gprs_provision_context *context);
+	void (*get_settings)(struct ofono_gprs_provision_context *context,
+				ofono_gprs_provision_cb_t cb,
+				void *user_data);
+};
+
+int ofono_gprs_provision_driver_register(
+			const struct ofono_gprs_provision_driver *driver);
+void ofono_gprs_provision_driver_unregister(
+			const struct ofono_gprs_provision_driver *driver);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __OFONO_GPRS_PROVISION_H */
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 2/6] ofono.h: add new atom type for gprs-provision
  2011-01-20 13:11 [gprs-provision PATCHv5 0/6] Plugin API for provisioning of GPRS context setting Jukka Saunamaki
  2011-01-20 13:11 ` [PATCH 1/6] gprs-provision: add driver API header Jukka Saunamaki
@ 2011-01-20 13:11 ` Jukka Saunamaki
  2011-01-20 13:11 ` [PATCH 3/6] gprs-provision: add driver API sources Jukka Saunamaki
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 13+ messages in thread
From: Jukka Saunamaki @ 2011-01-20 13:11 UTC (permalink / raw)
  To: ofono

[-- Attachment #1: Type: text/plain, Size: 926 bytes --]

---
 src/ofono.h |    8 ++++++++
 1 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/src/ofono.h b/src/ofono.h
index 77567c2..43a703f 100644
--- a/src/ofono.h
+++ b/src/ofono.h
@@ -127,6 +127,7 @@ enum ofono_atom_type {
 	OFONO_ATOM_TYPE_NETTIME = 21,
 	OFONO_ATOM_TYPE_CTM = 22,
 	OFONO_ATOM_TYPE_CDMA_VOICECALL_MANAGER = 23,
+	OFONO_ATOM_TYPE_GPRS_PROVISION = 24,
 };
 
 enum ofono_atom_watch_condition {
@@ -417,4 +418,11 @@ void __ofono_nettime_probe_drivers(struct ofono_modem *modem);
 void __ofono_nettime_info_received(struct ofono_modem *modem,
 					struct ofono_network_time *info);
 
+#include <ofono/gprs-provision.h>
+
+void __ofono_gprs_provision_probe_drivers(struct ofono_modem *modem);
+
+void __ofono_gprs_provision_get_settings(struct ofono_modem *modem,
+						ofono_gprs_provision_cb_t cb,
+						void *user_data);
 #include <ofono/cdma-voicecall.h>
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 3/6] gprs-provision: add driver API sources
  2011-01-20 13:11 [gprs-provision PATCHv5 0/6] Plugin API for provisioning of GPRS context setting Jukka Saunamaki
  2011-01-20 13:11 ` [PATCH 1/6] gprs-provision: add driver API header Jukka Saunamaki
  2011-01-20 13:11 ` [PATCH 2/6] ofono.h: add new atom type for gprs-provision Jukka Saunamaki
@ 2011-01-20 13:11 ` Jukka Saunamaki
  2011-01-20 13:11 ` [PATCH 4/6] modem: probe gprs_provision drivers Jukka Saunamaki
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 13+ messages in thread
From: Jukka Saunamaki @ 2011-01-20 13:11 UTC (permalink / raw)
  To: ofono

[-- Attachment #1: Type: text/plain, Size: 6889 bytes --]

---
 Makefile.am          |    2 +-
 src/gprs-provision.c |  219 ++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 220 insertions(+), 1 deletions(-)
 create mode 100644 src/gprs-provision.c

diff --git a/Makefile.am b/Makefile.am
index 7a03f08..97480d5 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -353,7 +353,7 @@ src_ofonod_SOURCES = $(gdbus_sources) $(builtin_sources) src/ofono.ver \
 			src/nettime.c src/stkagent.c src/stkagent.h \
 			src/simfs.c src/simfs.h src/audio-settings.c \
 			src/smsagent.c src/smsagent.h src/ctm.c \
-			src/cdma-voicecall.c
+			src/cdma-voicecall.c src/gprs-provision.c
 
 src_ofonod_LDADD = $(builtin_libadd) @GLIB_LIBS@ @DBUS_LIBS@ @CAPNG_LIBS@ -ldl
 
diff --git a/src/gprs-provision.c b/src/gprs-provision.c
new file mode 100644
index 0000000..380d126
--- /dev/null
+++ b/src/gprs-provision.c
@@ -0,0 +1,219 @@
+/*
+ *
+ *  oFono - Open Source Telephony
+ *
+ *  Copyright (C) 2011  Nokia Corporation and/or its subsidiary(-ies).
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <glib.h>
+
+#include "ofono.h"
+#include "gprs-provision.h"
+
+static GSList *g_drivers = NULL;
+static GSList *provision_requests = NULL;
+
+struct gprs_provision_request {
+	GSList *drivers; /* Provisioning drivers to be called */
+	struct ofono_modem *modem;
+	ofono_gprs_provision_cb_t cb;
+	void *user_data;
+	const char *current_name;
+};
+
+static struct ofono_gprs_provision_context *gprs_provision_context_create(
+			struct ofono_modem *modem,
+			struct ofono_gprs_provision_driver *driver)
+{
+	struct ofono_gprs_provision_context *context;
+
+	if (driver->probe == NULL)
+		return NULL;
+
+	context = g_try_new0(struct ofono_gprs_provision_context, 1);
+	if (context == NULL)
+		return NULL;
+
+	context->driver = driver;
+	context->modem = modem;
+
+	if (driver->probe(context) < 0) {
+		g_free(context);
+		return NULL;
+	}
+
+	return context;
+}
+
+static void clean_active_requests(gpointer data, gpointer user_data)
+{
+	struct gprs_provision_request *req = data;
+	struct ofono_gprs_provision_context *context = user_data;
+
+	req->drivers = g_slist_remove(req->drivers, context);
+}
+
+static void context_remove(struct ofono_atom *atom)
+{
+	struct ofono_gprs_provision_context *context =
+		__ofono_atom_get_data(atom);
+
+	g_slist_foreach(provision_requests, clean_active_requests, context);
+
+	if (context->driver->remove)
+		context->driver->remove(context);
+
+	g_free(context);
+}
+
+void __ofono_gprs_provision_probe_drivers(struct ofono_modem *modem)
+{
+	struct ofono_gprs_provision_driver *driver;
+	struct ofono_gprs_provision_context *context;
+	GSList *l;
+
+	for (l = g_drivers; l; l = l->next) {
+		driver = l->data;
+		context = gprs_provision_context_create(modem, driver);
+		if (context == NULL)
+			continue;
+
+		__ofono_modem_add_atom(modem, OFONO_ATOM_TYPE_GPRS_PROVISION,
+						context_remove, context);
+	}
+}
+
+/*
+ * Calls next driver that has callable get_settings()
+ * Returns TRUE if a driver was called.
+ */
+static gboolean call_driver_get_settings(struct gprs_provision_request *req,
+						ofono_gprs_provision_cb_t cb)
+{
+	struct ofono_gprs_provision_context *context;
+
+	while (req->drivers != NULL) {
+		context = req->drivers->data;
+		req->drivers = g_slist_delete_link(req->drivers, req->drivers);
+
+		if (context->driver->get_settings != NULL) {
+			DBG("Calling provisioning plugin '%s'",
+				context->driver->name);
+
+			req->current_name = context->driver->name;
+			provision_requests = g_slist_append(provision_requests,
+								req);
+			context->driver->get_settings(context, cb, req);
+			return TRUE;
+		}
+	}
+
+	return FALSE;
+}
+
+static void settings_cb(const struct ofono_gprs_provision_data settings[],
+			int count, void *user_data)
+{
+	struct gprs_provision_request *req = user_data;
+
+	provision_requests = g_slist_remove(provision_requests, req);
+
+	if (count == 0) {
+		ofono_warn("Provisioning plugin '%s' returned no settings",
+			req->current_name);
+
+		/* No success from this driver, try next */
+		if (call_driver_get_settings(req, settings_cb) == TRUE)
+			return;
+	} else
+		DBG("Plugin '%s' returned settings for %d contexts",
+			req->current_name, count);
+
+	req->cb(settings, count, req->user_data);
+	g_slist_free(req->drivers);
+	g_free(req);
+}
+
+static void prepend_provision_driver(struct ofono_atom *atom, void *data)
+{
+	struct ofono_gprs_provision_context *context =
+		__ofono_atom_get_data(atom);
+	GSList **drivers = data;
+
+	*drivers = g_slist_prepend(*drivers, context);
+}
+
+void __ofono_gprs_provision_get_settings(struct ofono_modem *modem,
+						ofono_gprs_provision_cb_t cb,
+						void *user_data)
+{
+	struct gprs_provision_request *req;
+
+	req = g_try_new0(struct gprs_provision_request, 1);
+	if (req == NULL)
+		goto error;
+
+	req->modem = modem;
+	req->cb = cb;
+	req->user_data = user_data;
+
+	__ofono_modem_foreach_atom(modem, OFONO_ATOM_TYPE_GPRS_PROVISION,
+					prepend_provision_driver,
+					&req->drivers);
+
+	if (call_driver_get_settings(req, settings_cb) == TRUE)
+		return;
+
+	DBG("No callable GPRS provision drivers");
+
+	g_slist_free(req->drivers);
+
+error:
+	g_free(req);
+	cb(NULL, 0, user_data);
+}
+
+static gint compare_priority(gconstpointer a, gconstpointer b)
+{
+	const struct ofono_gprs_provision_driver *plugin1 = a;
+	const struct ofono_gprs_provision_driver *plugin2 = b;
+
+	return plugin2->priority - plugin1->priority;
+}
+
+int ofono_gprs_provision_driver_register(
+			const struct ofono_gprs_provision_driver *driver)
+{
+	DBG("driver: %p name: %s", driver, driver->name);
+
+	g_drivers = g_slist_insert_sorted(g_drivers, (void *) driver,
+						compare_priority);
+	return 0;
+}
+
+void ofono_gprs_provision_driver_unregister(
+			const struct ofono_gprs_provision_driver *driver)
+{
+	DBG("driver: %p name: %s", driver, driver->name);
+
+	g_drivers = g_slist_remove(g_drivers, driver);
+}
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 4/6] modem: probe gprs_provision drivers
  2011-01-20 13:11 [gprs-provision PATCHv5 0/6] Plugin API for provisioning of GPRS context setting Jukka Saunamaki
                   ` (2 preceding siblings ...)
  2011-01-20 13:11 ` [PATCH 3/6] gprs-provision: add driver API sources Jukka Saunamaki
@ 2011-01-20 13:11 ` Jukka Saunamaki
  2011-01-20 13:11 ` [PATCH 5/6] gprs: add gprs context provisioning Jukka Saunamaki
  2011-01-20 13:11 ` [PATCH 6/6] gprs-provision: add example context provisioning driver Jukka Saunamaki
  5 siblings, 0 replies; 13+ messages in thread
From: Jukka Saunamaki @ 2011-01-20 13:11 UTC (permalink / raw)
  To: ofono

[-- Attachment #1: Type: text/plain, Size: 499 bytes --]

---
 src/modem.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/src/modem.c b/src/modem.c
index e966a6e..a302590 100644
--- a/src/modem.c
+++ b/src/modem.c
@@ -424,6 +424,7 @@ static void modem_change_state(struct ofono_modem *modem,
 				driver->post_sim(modem);
 			__ofono_history_probe_drivers(modem);
 			__ofono_nettime_probe_drivers(modem);
+			__ofono_gprs_provision_probe_drivers(modem);
 		} else
 			notify_online_watches(modem);
 
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 5/6] gprs: add gprs context provisioning
  2011-01-20 13:11 [gprs-provision PATCHv5 0/6] Plugin API for provisioning of GPRS context setting Jukka Saunamaki
                   ` (3 preceding siblings ...)
  2011-01-20 13:11 ` [PATCH 4/6] modem: probe gprs_provision drivers Jukka Saunamaki
@ 2011-01-20 13:11 ` Jukka Saunamaki
  2011-01-20 13:11 ` [PATCH 6/6] gprs-provision: add example context provisioning driver Jukka Saunamaki
  5 siblings, 0 replies; 13+ messages in thread
From: Jukka Saunamaki @ 2011-01-20 13:11 UTC (permalink / raw)
  To: ofono

[-- Attachment #1: Type: text/plain, Size: 5918 bytes --]

---
 src/gprs.c |  147 ++++++++++++++++++++++++++++++++++++++++++++++++++++++------
 1 files changed, 133 insertions(+), 14 deletions(-)

diff --git a/src/gprs.c b/src/gprs.c
index 7ef81d5..06f6555 100644
--- a/src/gprs.c
+++ b/src/gprs.c
@@ -43,6 +43,7 @@
 #include "common.h"
 #include "storage.h"
 #include "idmap.h"
+#include "gprs-provision.h"
 
 #define GPRS_FLAG_ATTACHING 0x1
 #define GPRS_FLAG_RECHECK 0x2
@@ -83,6 +84,7 @@ struct ofono_gprs {
 	const struct ofono_gprs_driver *driver;
 	void *driver_data;
 	struct ofono_atom *atom;
+	struct provision_request *provision;
 };
 
 struct ofono_gprs_context {
@@ -123,6 +125,10 @@ struct pri_context {
 	struct ofono_gprs *gprs;
 };
 
+struct provision_request {
+	struct ofono_gprs *gprs;
+};
+
 static void gprs_netreg_update(struct ofono_gprs *gprs);
 static void gprs_deactivate_next(struct ofono_gprs *gprs);
 
@@ -2230,6 +2236,9 @@ static void gprs_remove(struct ofono_atom *atom)
 	if (gprs->driver && gprs->driver->remove)
 		gprs->driver->remove(gprs);
 
+	if (gprs->provision != NULL)
+		gprs->provision->gprs = NULL;
+
 	g_free(gprs);
 }
 
@@ -2483,13 +2492,15 @@ remove:
 		storage_sync(imsi, SETTINGS_STORE, gprs->settings);
 }
 
-void ofono_gprs_register(struct ofono_gprs *gprs)
+static void ofono_gprs_finish_register(struct ofono_gprs *gprs)
 {
 	DBusConnection *conn = ofono_dbus_get_connection();
 	struct ofono_modem *modem = __ofono_atom_get_modem(gprs->atom);
 	const char *path = __ofono_atom_get_path(gprs->atom);
 	struct ofono_atom *netreg_atom;
-	struct ofono_atom *sim_atom;
+
+	if (gprs->contexts == NULL) /* Automatic provisioning failed */
+		add_context(gprs, NULL, OFONO_GPRS_CONTEXT_TYPE_INTERNET);
 
 	if (!g_dbus_register_interface(conn, path,
 					OFONO_CONNECTION_MANAGER_INTERFACE,
@@ -2504,18 +2515,6 @@ void ofono_gprs_register(struct ofono_gprs *gprs)
 	ofono_modem_add_interface(modem,
 				OFONO_CONNECTION_MANAGER_INTERFACE);
 
-	sim_atom = __ofono_modem_find_atom(modem, OFONO_ATOM_TYPE_SIM);
-
-	if (sim_atom) {
-		struct ofono_sim *sim = __ofono_atom_get_data(sim_atom);
-		const char *imsi = ofono_sim_get_imsi(sim);
-
-		gprs_load_settings(gprs, imsi);
-	}
-
-	if (gprs->contexts == NULL)
-		add_context(gprs, NULL, OFONO_GPRS_CONTEXT_TYPE_INTERNET);
-
 	gprs->netreg_watch = __ofono_modem_add_atom_watch(modem,
 					OFONO_ATOM_TYPE_NETREG,
 					netreg_watch, gprs, NULL);
@@ -2529,6 +2528,126 @@ void ofono_gprs_register(struct ofono_gprs *gprs)
 	__ofono_atom_register(gprs->atom, gprs_unregister);
 }
 
+static void provision_context(const struct ofono_gprs_provision_data *ap,
+				struct ofono_gprs *gprs)
+{
+	unsigned int id;
+	struct pri_context *context = NULL;
+
+	/* Sanity check */
+	if (ap == NULL || ap->name == NULL)
+		return;
+
+	if (gprs->last_context_id)
+		id = idmap_alloc_next(gprs->pid_map, gprs->last_context_id);
+	else
+		id = idmap_alloc(gprs->pid_map);
+
+	if (id > idmap_get_max(gprs->pid_map))
+		return;
+
+	context = pri_context_create(gprs, ap->name, ap->type);
+	DBG("%s context%d '%s' %s", gprs_context_default_name(ap->type),
+		id, ap->name, context ? "created" : "creation failed");
+
+	if (context == NULL)
+		return;
+
+	context->id = id;
+
+	if (ap->username != NULL)
+		strncpy(context->context.username, ap->username,
+			OFONO_GPRS_MAX_USERNAME_LENGTH);
+
+	if (ap->password != NULL)
+		strncpy(context->context.password, ap->password,
+			OFONO_GPRS_MAX_PASSWORD_LENGTH);
+
+	if (ap->apn != NULL)
+		strncpy(context->context.apn, ap->apn,
+			OFONO_GPRS_MAX_APN_LENGTH);
+
+	context->context.proto = ap->proto;
+
+	if (ap->type == OFONO_GPRS_CONTEXT_TYPE_MMS &&
+			ap->message_proxy != NULL)
+		strncpy(context->message_proxy, ap->message_proxy,
+			MAX_MESSAGE_PROXY_LENGTH);
+
+	if (ap->type == OFONO_GPRS_CONTEXT_TYPE_MMS &&
+			ap->message_center != NULL)
+		strncpy(context->message_center, ap->message_center,
+			MAX_MESSAGE_CENTER_LENGTH);
+
+	if (context_dbus_register(context) == TRUE) {
+		gprs->last_context_id = id;
+		gprs->contexts = g_slist_append(gprs->contexts, context);
+		write_context_settings(gprs, context);
+
+		if (context->type == OFONO_GPRS_CONTEXT_TYPE_MMS) {
+			g_key_file_set_string(gprs->settings, context->key,
+						"MessageProxy",
+						context->message_proxy);
+			g_key_file_set_string(gprs->settings, context->key,
+						"MessageCenter",
+						context->message_center);
+		}
+
+		storage_sync(gprs->imsi, SETTINGS_STORE, gprs->settings);
+	}
+}
+
+
+static void provision_cb(const struct ofono_gprs_provision_data settings[],
+				int count, void *user_data)
+{
+	struct provision_request *req = user_data;
+	struct ofono_gprs *gprs = req->gprs;
+
+	if (gprs != NULL) {
+		int i;
+		gprs->provision = NULL;
+
+		for (i = 0; i < count; i++)
+			provision_context(&settings[i], gprs);
+
+		ofono_gprs_finish_register(gprs);
+	}
+
+	g_free(req);
+}
+
+void ofono_gprs_register(struct ofono_gprs *gprs)
+{
+	struct ofono_modem *modem = __ofono_atom_get_modem(gprs->atom);
+	struct ofono_atom *sim_atom;
+
+	sim_atom = __ofono_modem_find_atom(modem, OFONO_ATOM_TYPE_SIM);
+
+	if (sim_atom != NULL) {
+		struct ofono_sim *sim = __ofono_atom_get_data(sim_atom);
+		const char *imsi = ofono_sim_get_imsi(sim);
+
+		gprs_load_settings(gprs, imsi);
+	}
+
+	if (gprs->contexts == NULL) {
+		/* Start settings provisioning */
+		struct provision_request *req;
+
+		req = g_try_new0(struct provision_request, 1);
+		if (req != NULL) {
+			req->gprs = gprs;
+			gprs->provision = req;
+			__ofono_gprs_provision_get_settings(modem, provision_cb,
+								req);
+			return;
+		}
+	}
+
+	ofono_gprs_finish_register(gprs);
+}
+
 void ofono_gprs_remove(struct ofono_gprs *gprs)
 {
 	__ofono_atom_free(gprs->atom);
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 6/6] gprs-provision: add example context provisioning driver
  2011-01-20 13:11 [gprs-provision PATCHv5 0/6] Plugin API for provisioning of GPRS context setting Jukka Saunamaki
                   ` (4 preceding siblings ...)
  2011-01-20 13:11 ` [PATCH 5/6] gprs: add gprs context provisioning Jukka Saunamaki
@ 2011-01-20 13:11 ` Jukka Saunamaki
  5 siblings, 0 replies; 13+ messages in thread
From: Jukka Saunamaki @ 2011-01-20 13:11 UTC (permalink / raw)
  To: ofono

[-- Attachment #1: Type: text/plain, Size: 6938 bytes --]

---
 Makefile.am          |    3 +
 examples/provision.c |  221 ++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 224 insertions(+), 0 deletions(-)
 create mode 100644 examples/provision.c

diff --git a/Makefile.am b/Makefile.am
index 97480d5..7a87aee 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -327,6 +327,9 @@ builtin_sources += examples/history.c
 
 builtin_modules += example_nettime
 builtin_sources += examples/nettime.c
+
+builtin_modules += example_provision
+builtin_sources += examples/provision.c
 endif
 
 builtin_modules += smart_messaging
diff --git a/examples/provision.c b/examples/provision.c
new file mode 100644
index 0000000..d84c4ba
--- /dev/null
+++ b/examples/provision.c
@@ -0,0 +1,221 @@
+/*
+ *
+ *  oFono - Open Source Telephony
+ *
+ *  Copyright (C) 2011  Nokia Corporation and/or its subsidiary(-ies).
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+#include <glib.h>
+
+#define OFONO_API_SUBJECT_TO_CHANGE
+
+#include <ofono/modem.h>
+#include <ofono/plugin.h>
+#include <ofono/log.h>
+#include <ofono/gprs-provision.h>
+#include <ofono/types.h>
+
+#include "ofono.h"
+#include "common.h"
+#include "sim.h"
+#include "simutil.h"
+#include "util.h"
+
+struct provisioning_request {
+	struct ofono_modem *modem;
+	ofono_gprs_provision_cb_t cb;
+	void *user_data;
+};
+
+static int example_provision_probe(struct ofono_gprs_provision_context *context)
+{
+	ofono_debug("Example GPRS context provisioning Probe for modem: %p",
+			context->modem);
+	return 0;
+}
+
+static void example_provision_remove(
+		struct ofono_gprs_provision_context *context)
+{
+	ofono_debug("Example GPRS context provisioning Remove for modem: %p",
+			context->modem);
+}
+
+static void provision_settings_free(struct ofono_gprs_provision_data *settings,
+					int count)
+{
+	int i;
+
+	for (i = 0; i < count; i++) {
+		g_free(settings[i].name);
+		g_free(settings[i].apn);
+		g_free(settings[i].username);
+		g_free(settings[i].password);
+		g_free(settings[i].message_proxy);
+		g_free(settings[i].message_center);
+	}
+
+	g_free(settings);
+}
+
+/* Example settings for phonesim */
+static void example_settings(const char *mcc, const char *mnc, const char *spn,
+				struct ofono_gprs_provision_data **settings,
+				int *count)
+{
+	*count = 0;
+	*settings = NULL;
+
+	ofono_debug("Finding settings for MCC %s, MNC %s, SPN '%s'",
+			mcc, mnc, spn);
+
+	if (strcmp(mcc, "246") != 0 || strcmp(mnc, "81") != 0 ||
+			spn == NULL || strcmp(spn, "oFono") != 0)
+		return;
+
+	ofono_debug("Creating example settings for phonesim");
+
+	*settings = g_try_new0(struct ofono_gprs_provision_data, 2);
+	if (*settings == NULL)
+		return;
+
+	*count = 2;
+
+	/* Internet context settings */
+	(*settings)[0].proto = OFONO_GPRS_PROTO_IP;
+	(*settings)[0].type = OFONO_GPRS_CONTEXT_TYPE_INTERNET;
+	(*settings)[0].name = g_strdup("Phonesim Internet");
+	(*settings)[0].apn = g_strdup("internetapn");
+
+	/* MMS context settings */
+	(*settings)[1].proto = OFONO_GPRS_PROTO_IP;
+	(*settings)[1].type = OFONO_GPRS_CONTEXT_TYPE_MMS;
+	(*settings)[1].name = g_strdup("Phonesim MMS");
+	(*settings)[1].apn = g_strdup("mmsapn");
+	(*settings)[1].username = g_strdup("mmsuser");
+	(*settings)[1].password = g_strdup("mmspass");
+	(*settings)[1].message_proxy = g_strdup("10.11.12.13:8080");
+	(*settings)[1].message_center = g_strdup("http://mms.example.com:8000");
+}
+
+static void sim_spn_read_cb(int ok, int length, int record,
+				const unsigned char *data,
+				int record_length, void *user_data)
+{
+	struct provisioning_request *req = user_data;
+
+	struct ofono_atom *sim_atom;
+	struct ofono_sim *sim;
+	const char *mcc;
+	const char *mnc;
+	char *spn = NULL;
+	struct ofono_gprs_provision_data *settings = NULL;
+	int count = 0;
+
+	sim_atom = __ofono_modem_find_atom(req->modem, OFONO_ATOM_TYPE_SIM);
+	if (sim_atom == NULL) {
+		ofono_debug("No SIM atom");
+		goto finish;
+	}
+
+	sim = __ofono_atom_get_data(sim_atom);
+	mcc = ofono_sim_get_mcc(sim);
+	mnc = ofono_sim_get_mnc(sim);
+	if (mcc == NULL || strlen(mcc) == 0 ||
+			mnc == NULL || strlen(mnc) == 0) {
+		ofono_debug("No MCC/MNC available");
+		goto finish;
+	}
+
+	if (ok)
+		spn = sim_string_to_utf8(data + 1, length - 1);
+
+	example_settings(mcc, mnc, spn, &settings, &count);
+
+finish:
+	g_free(spn);
+	req->cb(settings, count, req->user_data);
+	provision_settings_free(settings, count);
+	g_free(req);
+}
+
+static void example_provision_get_settings(
+		struct ofono_gprs_provision_context *driver_context,
+		ofono_gprs_provision_cb_t cb,
+		void *user_data)
+{
+	struct provisioning_request *req;
+	struct ofono_atom *sim_atom;
+	struct ofono_sim *sim = NULL;
+
+	if (cb == NULL)
+		return;
+
+	ofono_debug("Provisioning...");
+
+	req = g_try_new0(struct provisioning_request, 1);
+	if (req == NULL)
+		goto error;
+
+	req->modem = driver_context->modem;
+	req->cb = cb;
+	req->user_data = user_data;
+
+	/* Start SPN query from SIM */
+	sim_atom = __ofono_modem_find_atom(req->modem, OFONO_ATOM_TYPE_SIM);
+	if (sim_atom != NULL)
+		sim = __ofono_atom_get_data(sim_atom);
+
+	if (sim != NULL) {
+		ofono_sim_read(sim, SIM_EFSPN_FILEID,
+				OFONO_SIM_FILE_STRUCTURE_TRANSPARENT,
+				sim_spn_read_cb, req);
+		return;
+	}
+
+error:
+	cb(NULL, 0, user_data);
+	g_free(req);
+}
+
+static struct ofono_gprs_provision_driver example_driver = {
+	.name		= "Example GPRS context provisioning",
+	.priority       = OFONO_PLUGIN_PRIORITY_LOW,
+	.probe		= example_provision_probe,
+	.remove		= example_provision_remove,
+	.get_settings	= example_provision_get_settings,
+};
+
+static int example_provision_init(void)
+{
+	return ofono_gprs_provision_driver_register(&example_driver);
+}
+
+static void example_provision_exit(void)
+{
+	ofono_gprs_provision_driver_unregister(&example_driver);
+}
+
+OFONO_PLUGIN_DEFINE(example_provision, "Example Provisioning Plugin",
+			VERSION, OFONO_PLUGIN_PRIORITY_DEFAULT,
+			example_provision_init,
+			example_provision_exit)
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [PATCH 1/6] gprs-provision: add driver API header
  2011-01-20 13:11 ` [PATCH 1/6] gprs-provision: add driver API header Jukka Saunamaki
@ 2011-01-20 21:51   ` Denis Kenzior
  2011-01-21  7:39     ` Jukka Saunamaki
  0 siblings, 1 reply; 13+ messages in thread
From: Denis Kenzior @ 2011-01-20 21:51 UTC (permalink / raw)
  To: ofono

[-- Attachment #1: Type: text/plain, Size: 1306 bytes --]

Hi Jukka,

> +/*
> + * Callback from provisioning plugin.
> + */
> +typedef void (*ofono_gprs_provision_cb_t)(
> +			const struct ofono_gprs_provision_data settings[],
> +			int count, void *user_data);
> +
> +struct ofono_gprs_provision_driver {
> +	const char *name;
> +	int priority;
> +	int (*probe)(struct ofono_gprs_provision_context *context);
> +	void (*remove)(struct ofono_gprs_provision_context *context);
> +	void (*get_settings)(struct ofono_gprs_provision_context *context,
> +				ofono_gprs_provision_cb_t cb,
> +				void *user_data);
> +};

So I don't really see the point in an asynchronous provisioning driver.
 If you want to do this over D-Bus or something then you might as well
provision via the ConnectionManager interface.  The other problem with
being async is that is nearly impossible to support multiple
provisioning plugins properly.  I'd rather not deal with the race
conditions.

If we can't make the lookup fast enough to be done synchronously, then I
think we should give up.

I also don't see the point of instantiating these per modem.  The API
already has all the information it needs in the get_settings call.  So
having the plugin allocate its data in the plugin init function and free
it there seems enough to me.

Regards,
-Denis

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 1/6] gprs-provision: add driver API header
  2011-01-20 21:51   ` Denis Kenzior
@ 2011-01-21  7:39     ` Jukka Saunamaki
  2011-01-21 17:44       ` Denis Kenzior
  0 siblings, 1 reply; 13+ messages in thread
From: Jukka Saunamaki @ 2011-01-21  7:39 UTC (permalink / raw)
  To: ofono

[-- Attachment #1: Type: text/plain, Size: 1690 bytes --]

Hi

On Thu, 2011-01-20 at 15:51 -0600, Denis Kenzior wrote:
> So I don't really see the point in an asynchronous provisioning driver.
>  If you want to do this over D-Bus or something then you might as well
> provision via the ConnectionManager interface.  The other problem with
> being async is that is nearly impossible to support multiple
> provisioning plugins properly.  I'd rather not deal with the race
> conditions.
> 
> If we can't make the lookup fast enough to be done synchronously, then I
> think we should give up.

The reason for asyncronous API is still that SPN value reading from SIM.
Is there any way to make sure it is available synchronously when
provisioning is run?
And what do you mean with it being impossible to support multiple
provisioning plugins properly? Plugins are run one after another until
first returns something.
Race conditions I tried to address in gprs, so if gprs atom goes away
while provisioning is running nothing bad should happen. But sure, there
might something else, and hopefully someone could point them.

Of cause there is always the possibility to do all this provisioning
stuff outside of oFono, especially if we add SPN property to SIM API.

> I also don't see the point of instantiating these per modem.  The API
> already has all the information it needs in the get_settings call.  So
> having the plugin allocate its data in the plugin init function and free
> it there seems enough to me.

This I agree, earlier patches did it that way. I only changed this since
Marcel wished that all this kind of driver interfaces (like nettime)
would look similar. Or did I misunderstand that?

--Jukka



^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 1/6] gprs-provision: add driver API header
  2011-01-21  7:39     ` Jukka Saunamaki
@ 2011-01-21 17:44       ` Denis Kenzior
  2011-01-24  7:10         ` Jukka Saunamaki
  2011-01-24 10:38         ` Aki Niemi
  0 siblings, 2 replies; 13+ messages in thread
From: Denis Kenzior @ 2011-01-21 17:44 UTC (permalink / raw)
  To: ofono

[-- Attachment #1: Type: text/plain, Size: 1632 bytes --]

Hi Jukka,

On 01/21/2011 01:39 AM, Jukka Saunamaki wrote:
> Hi
> 
> On Thu, 2011-01-20 at 15:51 -0600, Denis Kenzior wrote:
>> So I don't really see the point in an asynchronous provisioning driver.
>>  If you want to do this over D-Bus or something then you might as well
>> provision via the ConnectionManager interface.  The other problem with
>> being async is that is nearly impossible to support multiple
>> provisioning plugins properly.  I'd rather not deal with the race
>> conditions.
>>
>> If we can't make the lookup fast enough to be done synchronously, then I
>> think we should give up.
> 
> The reason for asyncronous API is still that SPN value reading from SIM.
> Is there any way to make sure it is available synchronously when
> provisioning is run?

Not really. So you're introducing a boatload of extra complexity just
because of the need for EFspn?  Are you 100% sure that you really need
this?  Can some of these corner cases be covered differently?

> And what do you mean with it being impossible to support multiple
> provisioning plugins properly? Plugins are run one after another until
> first returns something.
> Race conditions I tried to address in gprs, so if gprs atom goes away
> while provisioning is running nothing bad should happen. But sure, there
> might something else, and hopefully someone could point them.

How exactly are you guaranteeing that 'nothing bad should happen'?
There is no cancellation mechanism that I see.  Not to mention that the
current ofono_sim_read API is not even safe either.  For exactly the
same reasons.

Regards,
-Denis

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 1/6] gprs-provision: add driver API header
  2011-01-21 17:44       ` Denis Kenzior
@ 2011-01-24  7:10         ` Jukka Saunamaki
  2011-01-24 10:16           ` Aki Niemi
  2011-01-24 10:38         ` Aki Niemi
  1 sibling, 1 reply; 13+ messages in thread
From: Jukka Saunamaki @ 2011-01-24  7:10 UTC (permalink / raw)
  To: ofono

[-- Attachment #1: Type: text/plain, Size: 1970 bytes --]

Hi Denis,

On Fri, 2011-01-21 at 11:44 -0600, Denis Kenzior wrote:
> > The reason for asyncronous API is still that SPN value reading from SIM.
> > Is there any way to make sure it is available synchronously when
> > provisioning is run?
> 
> Not really. So you're introducing a boatload of extra complexity just
> because of the need for EFspn?  Are you 100% sure that you really need
> this?  Can some of these corner cases be covered differently?

As I have said, there are MVNOs (I checked, all of them do not have
their own MNC) and operator brand names that use different APN settings
from their host operator. To tell these cases apart in provisioning, we
need SPN. 

> > And what do you mean with it being impossible to support multiple
> > provisioning plugins properly? Plugins are run one after another until
> > first returns something.
> > Race conditions I tried to address in gprs, so if gprs atom goes away
> > while provisioning is running nothing bad should happen. But sure, there
> > might something else, and hopefully someone could point them.
> 
> How exactly are you guaranteeing that 'nothing bad should happen'?
> There is no cancellation mechanism that I see.  Not to mention that the
> current ofono_sim_read API is not even safe either.  For exactly the
> same reasons.

No, I am not so familiar with the whole code that I could guarantee
that. So, I am asking for help there.

You say ofono_sim_read is not safe, but in what sense? Is it possible
that it never calls the callback?

Then how about something like this: Lets make provisioning API
synchronous (so that plugins do not need to care about SIM or other
safety).
In stead, if in gprs atom ofono_gprs_register() we notice the need for
provisioning,  ofono_sim_read(SPN) is called there. All issues would be
localised there. Provisioning modules would be called with MCC,MNC,SPN
as parameters. 

Any other solutions, anyone?

--Jukka



^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 1/6] gprs-provision: add driver API header
  2011-01-24  7:10         ` Jukka Saunamaki
@ 2011-01-24 10:16           ` Aki Niemi
  0 siblings, 0 replies; 13+ messages in thread
From: Aki Niemi @ 2011-01-24 10:16 UTC (permalink / raw)
  To: ofono

[-- Attachment #1: Type: text/plain, Size: 757 bytes --]

Hi Jukka,

2011/1/24 Jukka Saunamaki <jukka.saunamaki@nokia.com>:
> Then how about something like this: Lets make provisioning API
> synchronous (so that plugins do not need to care about SIM or other
> safety).
> In stead, if in gprs atom ofono_gprs_register() we notice the need for
> provisioning,  ofono_sim_read(SPN) is called there. All issues would be
> localised there. Provisioning modules would be called with MCC,MNC,SPN
> as parameters.

I think this is a better approach. It would reduce the role of the
provisioning plugins to database abstraction only, which is
essentially what they are.

I think the provisioning atom/plugins also should not be modem
specific, but just created once for all modems to use.

Cheers,
Aki

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 1/6] gprs-provision: add driver API header
  2011-01-21 17:44       ` Denis Kenzior
  2011-01-24  7:10         ` Jukka Saunamaki
@ 2011-01-24 10:38         ` Aki Niemi
  1 sibling, 0 replies; 13+ messages in thread
From: Aki Niemi @ 2011-01-24 10:38 UTC (permalink / raw)
  To: ofono

[-- Attachment #1: Type: text/plain, Size: 805 bytes --]

Hi Denis,

2011/1/21 Denis Kenzior <denkenz@gmail.com>:
> How exactly are you guaranteeing that 'nothing bad should happen'?
> There is no cancellation mechanism that I see.  Not to mention that the
> current ofono_sim_read API is not even safe either.  For exactly the
> same reasons.

This is a problem with all users of ofono_sim_read() at the moment. I
suppose if the atoms get removed at different times, it may happen
that after the gprs atom is gone, the SIM atom is still calling its
read callback.

Seems like we need some sort of cancellation API to ofono_sim_read(),
or use Jukka's approach of a request object, perhaps with a
GDestroyNotify parameter, or simply change the way atoms are created
and removed so that this could be handled inside the SIM atom.

Cheers,
Aki

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2011-01-24 10:38 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-01-20 13:11 [gprs-provision PATCHv5 0/6] Plugin API for provisioning of GPRS context setting Jukka Saunamaki
2011-01-20 13:11 ` [PATCH 1/6] gprs-provision: add driver API header Jukka Saunamaki
2011-01-20 21:51   ` Denis Kenzior
2011-01-21  7:39     ` Jukka Saunamaki
2011-01-21 17:44       ` Denis Kenzior
2011-01-24  7:10         ` Jukka Saunamaki
2011-01-24 10:16           ` Aki Niemi
2011-01-24 10:38         ` Aki Niemi
2011-01-20 13:11 ` [PATCH 2/6] ofono.h: add new atom type for gprs-provision Jukka Saunamaki
2011-01-20 13:11 ` [PATCH 3/6] gprs-provision: add driver API sources Jukka Saunamaki
2011-01-20 13:11 ` [PATCH 4/6] modem: probe gprs_provision drivers Jukka Saunamaki
2011-01-20 13:11 ` [PATCH 5/6] gprs: add gprs context provisioning Jukka Saunamaki
2011-01-20 13:11 ` [PATCH 6/6] gprs-provision: add example context provisioning driver Jukka Saunamaki

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.