All of lore.kernel.org
 help / color / mirror / Atom feed
* [gprs-provision PATCHv4 0/8] plugin API for provisioning of GPRS context settings
@ 2011-01-18  8:09 Jukka Saunamaki
  2011-01-18  8:09 ` [PATCH 1/8] gprs-provision: add driver API header Jukka Saunamaki
                   ` (7 more replies)
  0 siblings, 8 replies; 13+ messages in thread
From: Jukka Saunamaki @ 2011-01-18  8:09 UTC (permalink / raw)
  To: ofono

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

Hello

Here is a new patchset about implementing automatic provisioning of GPRS context settings. ("Internet Access Provider database" TODO item).

Compared to last one, this makes gprs-provision a "pseudo" atom similar to nettime. And possible races caused by a removed gprs-atom, while it is running asyncronous provisioning, should hopefully be fixed now.

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. 

Patches also add new functions ofono_sim_get_mcc/mnc to SIM atom API (typically needed by provisioning plugins).

--Jukka Saunamäki

Jukka Saunamaki (8):
      gprs-provision: add driver API header
      gprs-provision: add new atom type
      gprs-provision: add driver API sources
      gprs-provision: probe gprs_provision drivers
      gprs: add gprs context provisioning
      sim: getters for mcc and mnc definition
      sim: getters for mcc and mnc implementation
      gprs-provision: add example context provisioning driver

 Makefile.am              |    7 +-
 examples/provision.c     |  206 ++++++++++++++++++++++++++++++++++++++++
 include/gprs-provision.h |   80 ++++++++++++++++
 include/sim.h            |    2 +
 src/gprs-provision.c     |  236 ++++++++++++++++++++++++++++++++++++++++++++++
 src/gprs.c               |  147 ++++++++++++++++++++++++++---
 src/modem.c              |    1 +
 src/ofono.h              |    9 ++
 src/sim.c                |   50 ++++++----
 9 files changed, 703 insertions(+), 35 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/8] gprs-provision: add driver API header
  2011-01-18  8:09 [gprs-provision PATCHv4 0/8] plugin API for provisioning of GPRS context settings Jukka Saunamaki
@ 2011-01-18  8:09 ` Jukka Saunamaki
  2011-01-18 14:48   ` Marcel Holtmann
  2011-01-18  8:09 ` [PATCH 2/8] gprs-provision: add new atom type Jukka Saunamaki
                   ` (6 subsequent siblings)
  7 siblings, 1 reply; 13+ messages in thread
From: Jukka Saunamaki @ 2011-01-18  8:09 UTC (permalink / raw)
  To: ofono

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

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

diff --git a/Makefile.am b/Makefile.am
index da59be7..22ec95d 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -15,7 +15,7 @@ include_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_include_HEADERS = include/version.h
 
diff --git a/include/gprs-provision.h b/include/gprs-provision.h
new file mode 100644
index 0000000..70152b4
--- /dev/null
+++ b/include/gprs-provision.h
@@ -0,0 +1,80 @@
+/*
+ *
+ *  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.
+ * settings: list of struct ofono_gprs_provision_data
+ *
+ * It is responsibility of callback function to free settings-list
+ * settings-list elements must be freed with ofono_gprs_provision_data_free()
+ */
+typedef void (*ofono_gprs_provision_cb_t)(GSList *settings, void *userdata);
+
+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);
+};
+
+/* For provisioning drivers/plugins */
+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);
+
+/* For gprs */
+void ofono_gprs_provision_data_free(struct ofono_gprs_provision_data *data);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __OFONO_GPRS_PROVISION_H */
-- 
1.7.1


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

* [PATCH 2/8] gprs-provision: add new atom type
  2011-01-18  8:09 [gprs-provision PATCHv4 0/8] plugin API for provisioning of GPRS context settings Jukka Saunamaki
  2011-01-18  8:09 ` [PATCH 1/8] gprs-provision: add driver API header Jukka Saunamaki
@ 2011-01-18  8:09 ` Jukka Saunamaki
  2011-01-18  8:09 ` [PATCH 3/8] gprs-provision: add driver API sources Jukka Saunamaki
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 13+ messages in thread
From: Jukka Saunamaki @ 2011-01-18  8:09 UTC (permalink / raw)
  To: ofono

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

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

diff --git a/src/ofono.h b/src/ofono.h
index 77567c2..873b688 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,12 @@ 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/8] gprs-provision: add driver API sources
  2011-01-18  8:09 [gprs-provision PATCHv4 0/8] plugin API for provisioning of GPRS context settings Jukka Saunamaki
  2011-01-18  8:09 ` [PATCH 1/8] gprs-provision: add driver API header Jukka Saunamaki
  2011-01-18  8:09 ` [PATCH 2/8] gprs-provision: add new atom type Jukka Saunamaki
@ 2011-01-18  8:09 ` Jukka Saunamaki
  2011-01-18 14:55   ` Marcel Holtmann
  2011-01-18  8:09 ` [PATCH 4/8] gprs-provision: probe gprs_provision drivers Jukka Saunamaki
                   ` (4 subsequent siblings)
  7 siblings, 1 reply; 13+ messages in thread
From: Jukka Saunamaki @ 2011-01-18  8:09 UTC (permalink / raw)
  To: ofono

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

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

diff --git a/Makefile.am b/Makefile.am
index 22ec95d..e792851 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -354,7 +354,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..1690bc7
--- /dev/null
+++ b/src/gprs-provision.c
@@ -0,0 +1,236 @@
+/*
+ *
+ *  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;
+};
+
+static void settings_cb(GSList *settings, void *user_data);
+
+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);
+	}
+}
+
+void ofono_gprs_provision_data_free(struct ofono_gprs_provision_data *data)
+{
+	if (data == NULL)
+		return;
+
+	free(data->name);
+	free(data->apn);
+	free(data->username);
+	free(data->password);
+	free(data->message_proxy);
+	free(data->message_center);
+	g_free(data);
+}
+
+/*
+ * 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;
+
+	if (req->drivers == NULL)
+		return FALSE;
+
+	do {
+		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);
+
+			provision_requests = g_slist_append(provision_requests,
+								req);
+			context->driver->get_settings(context, cb, req);
+			return TRUE;
+		}
+
+	} while (req->drivers != NULL);
+
+	return FALSE;
+}
+
+static void settings_cb(GSList *settings, void *user_data)
+{
+	struct gprs_provision_request *req = user_data;
+
+	provision_requests = g_slist_remove(provision_requests, req);
+	if (settings == NULL) {
+		DBG("Provisioning plugin returned no settings");
+
+		/* No success from this driver, try next */
+		if (call_driver_get_settings(req, settings_cb) == TRUE)
+			return;
+	} else
+		DBG("Provisioning plugin returned settings for %d contexts",
+			g_slist_length(settings));
+
+	req->cb(settings, 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, 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/8] gprs-provision: probe gprs_provision drivers
  2011-01-18  8:09 [gprs-provision PATCHv4 0/8] plugin API for provisioning of GPRS context settings Jukka Saunamaki
                   ` (2 preceding siblings ...)
  2011-01-18  8:09 ` [PATCH 3/8] gprs-provision: add driver API sources Jukka Saunamaki
@ 2011-01-18  8:09 ` Jukka Saunamaki
  2011-01-18  8:09 ` [PATCH 5/8] gprs: add gprs context provisioning Jukka Saunamaki
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 13+ messages in thread
From: Jukka Saunamaki @ 2011-01-18  8:09 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 f587766..a835775 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/8] gprs: add gprs context provisioning
  2011-01-18  8:09 [gprs-provision PATCHv4 0/8] plugin API for provisioning of GPRS context settings Jukka Saunamaki
                   ` (3 preceding siblings ...)
  2011-01-18  8:09 ` [PATCH 4/8] gprs-provision: probe gprs_provision drivers Jukka Saunamaki
@ 2011-01-18  8:09 ` Jukka Saunamaki
  2011-01-18  8:09 ` [PATCH 6/8] sim: getters for mcc and mnc definition Jukka Saunamaki
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 13+ messages in thread
From: Jukka Saunamaki @ 2011-01-18  8:09 UTC (permalink / raw)
  To: ofono

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

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

diff --git a/src/gprs.c b/src/gprs.c
index 0e86bdf..b0d58f6 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
@@ -82,6 +83,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 {
@@ -122,6 +124,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);
 
@@ -2203,6 +2209,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);
 }
 
@@ -2456,13 +2465,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,
@@ -2477,18 +2488,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);
@@ -2502,6 +2501,126 @@ void ofono_gprs_register(struct ofono_gprs *gprs)
 	__ofono_atom_register(gprs->atom, gprs_unregister);
 }
 
+static void provision_context(gpointer data, gpointer user_data)
+{
+	struct ofono_gprs_provision_data *ap = data;
+	struct ofono_gprs *gprs = user_data;
+
+	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(GSList *settings, void *user_data)
+{
+	struct provision_request *req = user_data;
+	struct ofono_gprs *gprs = req->gprs;
+
+	if (gprs != NULL) {
+		gprs->provision = NULL;
+		g_slist_foreach(settings, provision_context, gprs);
+		ofono_gprs_finish_register(gprs);
+	}
+
+	g_free(req);
+	g_slist_foreach(settings, (GFunc) ofono_gprs_provision_data_free,
+			NULL);
+	g_slist_free(settings);
+}
+
+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/8] sim: getters for mcc and mnc definition
  2011-01-18  8:09 [gprs-provision PATCHv4 0/8] plugin API for provisioning of GPRS context settings Jukka Saunamaki
                   ` (4 preceding siblings ...)
  2011-01-18  8:09 ` [PATCH 5/8] gprs: add gprs context provisioning Jukka Saunamaki
@ 2011-01-18  8:09 ` Jukka Saunamaki
  2011-01-18  8:09 ` [PATCH 7/8] sim: getters for mcc and mnc implementation Jukka Saunamaki
  2011-01-18  8:09 ` [PATCH 8/8] gprs-provision: add example context provisioning driver Jukka Saunamaki
  7 siblings, 0 replies; 13+ messages in thread
From: Jukka Saunamaki @ 2011-01-18  8:09 UTC (permalink / raw)
  To: ofono

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

---
 include/sim.h |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/include/sim.h b/include/sim.h
index 830322a..81df60e 100644
--- a/include/sim.h
+++ b/include/sim.h
@@ -178,6 +178,8 @@ void ofono_sim_set_data(struct ofono_sim *sim, void *data);
 void *ofono_sim_get_data(struct ofono_sim *sim);
 
 const char *ofono_sim_get_imsi(struct ofono_sim *sim);
+const char *ofono_sim_get_mcc(struct ofono_sim *sim);
+const char *ofono_sim_get_mnc(struct ofono_sim *sim);
 enum ofono_sim_phase ofono_sim_get_phase(struct ofono_sim *sim);
 
 enum ofono_sim_cphs_phase ofono_sim_get_cphs_phase(struct ofono_sim *sim);
-- 
1.7.1


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

* [PATCH 7/8] sim: getters for mcc and mnc implementation
  2011-01-18  8:09 [gprs-provision PATCHv4 0/8] plugin API for provisioning of GPRS context settings Jukka Saunamaki
                   ` (5 preceding siblings ...)
  2011-01-18  8:09 ` [PATCH 6/8] sim: getters for mcc and mnc definition Jukka Saunamaki
@ 2011-01-18  8:09 ` Jukka Saunamaki
  2011-01-18 14:44   ` Marcel Holtmann
  2011-01-18  8:09 ` [PATCH 8/8] gprs-provision: add example context provisioning driver Jukka Saunamaki
  7 siblings, 1 reply; 13+ messages in thread
From: Jukka Saunamaki @ 2011-01-18  8:09 UTC (permalink / raw)
  To: ofono

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

---
 src/sim.c |   50 +++++++++++++++++++++++++++++++-------------------
 1 files changed, 31 insertions(+), 19 deletions(-)

diff --git a/src/sim.c b/src/sim.c
index d627647..86c3f13 100644
--- a/src/sim.c
+++ b/src/sim.c
@@ -78,6 +78,8 @@ struct ofono_sim {
 	gboolean barred_dialing;
 
 	char *imsi;
+	char mcc[OFONO_MAX_MCC_LENGTH + 1];
+	char mnc[OFONO_MAX_MNC_LENGTH + 1];
 
 	GSList *own_numbers;
 	GSList *new_numbers;
@@ -348,21 +350,13 @@ static DBusMessage *sim_get_properties(DBusConnection *conn,
 	bdn = sim->barred_dialing;
 	ofono_dbus_dict_append(&dict, "BarredDialing", DBUS_TYPE_BOOLEAN, &bdn);
 
-	if (sim->mnc_length && sim->imsi) {
-		char mcc[OFONO_MAX_MCC_LENGTH + 1];
-		char mnc[OFONO_MAX_MNC_LENGTH + 1];
+	if (sim->mcc[0] != '\0' && sim->mnc[0] != '\0') {
 		const char *str;
-
-		strncpy(mcc, sim->imsi, OFONO_MAX_MCC_LENGTH);
-		mcc[OFONO_MAX_MCC_LENGTH] = '\0';
-		strncpy(mnc, sim->imsi + OFONO_MAX_MCC_LENGTH, sim->mnc_length);
-		mnc[sim->mnc_length] = '\0';
-
-		str = mcc;
+		str = sim->mcc;
 		ofono_dbus_dict_append(&dict, "MobileCountryCode",
 					DBUS_TYPE_STRING, &str);
 
-		str = mnc;
+		str = sim->mnc;
 		ofono_dbus_dict_append(&dict, "MobileNetworkCode",
 					DBUS_TYPE_STRING, &str);
 	}
@@ -1299,22 +1293,21 @@ static void sim_imsi_cb(const struct ofono_error *error, const char *imsi,
 						DBUS_TYPE_STRING, &sim->imsi);
 
 	if (sim->mnc_length) {
-		char mcc[OFONO_MAX_MCC_LENGTH + 1];
-		char mnc[OFONO_MAX_MNC_LENGTH + 1];
 		const char *str;
 
-		strncpy(mcc, sim->imsi, OFONO_MAX_MCC_LENGTH);
-		mcc[OFONO_MAX_MCC_LENGTH] = '\0';
-		strncpy(mnc, sim->imsi + OFONO_MAX_MCC_LENGTH, sim->mnc_length);
-		mnc[sim->mnc_length] = '\0';
+		strncpy(sim->mcc, sim->imsi, OFONO_MAX_MCC_LENGTH);
+		sim->mcc[OFONO_MAX_MCC_LENGTH] = '\0';
+		strncpy(sim->mnc, sim->imsi + OFONO_MAX_MCC_LENGTH,
+			sim->mnc_length);
+		sim->mnc[sim->mnc_length] = '\0';
 
-		str = mcc;
+		str = sim->mcc;
 		ofono_dbus_signal_property_changed(conn, path,
 						OFONO_SIM_MANAGER_INTERFACE,
 						"MobileCountryCode",
 						DBUS_TYPE_STRING, &str);
 
-		str = mnc;
+		str = sim->mnc;
 		ofono_dbus_signal_property_changed(conn, path,
 						OFONO_SIM_MANAGER_INTERFACE,
 						"MobileNetworkCode",
@@ -1997,6 +1990,22 @@ const char *ofono_sim_get_imsi(struct ofono_sim *sim)
 	return sim->imsi;
 }
 
+const char *ofono_sim_get_mcc(struct ofono_sim *sim)
+{
+	if (sim == NULL)
+		return NULL;
+
+	return sim->mcc;
+}
+
+const char *ofono_sim_get_mnc(struct ofono_sim *sim)
+{
+	if (sim == NULL)
+		return NULL;
+
+	return sim->mnc;
+}
+
 enum ofono_sim_phase ofono_sim_get_phase(struct ofono_sim *sim)
 {
 	if (sim == NULL)
@@ -2060,6 +2069,9 @@ static void sim_free_state(struct ofono_sim *sim)
 		sim->imsi = NULL;
 	}
 
+	sim->mcc[0] = '\0';
+	sim->mnc[0] = '\0';
+
 	if (sim->own_numbers) {
 		g_slist_foreach(sim->own_numbers, (GFunc)g_free, NULL);
 		g_slist_free(sim->own_numbers);
-- 
1.7.1


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

* [PATCH 8/8] gprs-provision: add example context provisioning driver
  2011-01-18  8:09 [gprs-provision PATCHv4 0/8] plugin API for provisioning of GPRS context settings Jukka Saunamaki
                   ` (6 preceding siblings ...)
  2011-01-18  8:09 ` [PATCH 7/8] sim: getters for mcc and mnc implementation Jukka Saunamaki
@ 2011-01-18  8:09 ` Jukka Saunamaki
  7 siblings, 0 replies; 13+ messages in thread
From: Jukka Saunamaki @ 2011-01-18  8:09 UTC (permalink / raw)
  To: ofono

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

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

diff --git a/Makefile.am b/Makefile.am
index e792851..a74f75e 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -328,6 +328,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..d39fc3c
--- /dev/null
+++ b/examples/provision.c
@@ -0,0 +1,206 @@
+/*
+ *
+ *  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 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;
+	char *spn = NULL;
+
+	struct ofono_atom *sim_atom;
+	struct ofono_sim *sim;
+	const char *mcc;
+	const char *mnc;
+
+	GSList *settings = NULL;
+	struct ofono_gprs_provision_data *entry;
+
+	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);
+	if (mcc == NULL) {
+		ofono_debug("No MCC available");
+		goto finish;
+	}
+
+	mnc = ofono_sim_get_mnc(sim);
+	if (mnc == NULL) {
+		ofono_debug("No MNC available");
+		goto finish;
+	}
+
+	if (ok)
+		spn = sim_string_to_utf8(data + 1, length - 1);
+
+	ofono_debug("Finding settings for MCC %s, MNC %s, SPN '%s'",
+			mcc, mnc, spn);
+
+	/* Example settings for phonesim */
+	if (strcmp(mcc, "246") != 0 || strcmp(mnc, "81") != 0 ||
+			spn == NULL || strcmp(spn, "oFono") != 0)
+		goto finish;
+
+	ofono_debug("Creating example settings for phonesim");
+
+	/* MMS context settings */
+	entry = g_try_new0(struct ofono_gprs_provision_data, 1);
+	if (entry == NULL)
+		goto finish;
+
+	entry->proto = OFONO_GPRS_PROTO_IP;
+	entry->type = OFONO_GPRS_CONTEXT_TYPE_MMS;
+	entry->name = strdup("Phonesim MMS");
+	entry->apn = strdup("mmsapn");
+	entry->username = strdup("mmsuser");
+	entry->password = strdup("mmspass");
+	entry->message_proxy = strdup("10.11.12.13:8080");
+	entry->message_center = strdup("http://mms.example.com:8000");
+	settings = g_slist_prepend(settings, entry);
+
+	/* Internet context settings */
+	entry = g_try_new0(struct ofono_gprs_provision_data, 1);
+	if (entry == NULL)
+		goto finish;
+
+	entry->proto = OFONO_GPRS_PROTO_IP;
+	entry->type = OFONO_GPRS_CONTEXT_TYPE_INTERNET;
+	entry->name = strdup("Phonesim Internet");
+	entry->apn = strdup("internetapn");
+	settings = g_slist_prepend(settings, entry);
+
+finish:
+	g_free(spn);
+
+	if (req->cb != NULL)
+		req->cb(settings, req->user_data);
+
+	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;
+
+	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:
+	if (cb != NULL)
+		cb(NULL, user_data);
+}
+
+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 7/8] sim: getters for mcc and mnc implementation
  2011-01-18  8:09 ` [PATCH 7/8] sim: getters for mcc and mnc implementation Jukka Saunamaki
@ 2011-01-18 14:44   ` Marcel Holtmann
  0 siblings, 0 replies; 13+ messages in thread
From: Marcel Holtmann @ 2011-01-18 14:44 UTC (permalink / raw)
  To: ofono

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

Hi Jukka,

>  src/sim.c |   50 +++++++++++++++++++++++++++++++-------------------
>  1 files changed, 31 insertions(+), 19 deletions(-)
> 
> diff --git a/src/sim.c b/src/sim.c
> index d627647..86c3f13 100644
> --- a/src/sim.c
> +++ b/src/sim.c
> @@ -78,6 +78,8 @@ struct ofono_sim {
>  	gboolean barred_dialing;
>  
>  	char *imsi;
> +	char mcc[OFONO_MAX_MCC_LENGTH + 1];
> +	char mnc[OFONO_MAX_MNC_LENGTH + 1];

so I would split this a little bit.

1) refactor src/sim.c to store mcc and mnc.
2) add header definitions
3) add getters implementation.

And send these separately. No need to make them part of the provision
patch set. I know that you need them for that, but they are not really
required and could be reviewed and applied quicker.

Regards

Marcel



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

* Re: [PATCH 1/8] gprs-provision: add driver API header
  2011-01-18  8:09 ` [PATCH 1/8] gprs-provision: add driver API header Jukka Saunamaki
@ 2011-01-18 14:48   ` Marcel Holtmann
  2011-01-19  5:58     ` Jukka Saunamaki
  0 siblings, 1 reply; 13+ messages in thread
From: Marcel Holtmann @ 2011-01-18 14:48 UTC (permalink / raw)
  To: ofono

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

Hi Jukka,

<snip>

> +/*
> + * Callback from provisioning plugin.
> + * settings: list of struct ofono_gprs_provision_data
> + *
> + * It is responsibility of callback function to free settings-list
> + * settings-list elements must be freed with ofono_gprs_provision_data_free()
> + */
> +typedef void (*ofono_gprs_provision_cb_t)(GSList *settings, void *userdata);

so our general rule is no GLib types in oFono public APIs.

> +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,

No space between (get_settings) and (struct please.

> +				ofono_gprs_provision_cb_t cb,
> +				void *user_data);
> +};
> +
> +/* For provisioning drivers/plugins */
> +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);
> +
> +/* For gprs */
> +void ofono_gprs_provision_data_free(struct ofono_gprs_provision_data *data);

This sounds more like an __ofono_* internal API kind of thing.

Regards

Marcel



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

* Re: [PATCH 3/8] gprs-provision: add driver API sources
  2011-01-18  8:09 ` [PATCH 3/8] gprs-provision: add driver API sources Jukka Saunamaki
@ 2011-01-18 14:55   ` Marcel Holtmann
  0 siblings, 0 replies; 13+ messages in thread
From: Marcel Holtmann @ 2011-01-18 14:55 UTC (permalink / raw)
  To: ofono

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

Hi Jukka,

I am just making some minor style comments right now.

<snip>

> +struct gprs_provision_request {
> +	GSList *drivers; /* Provisioning drivers to be called */
> +	struct ofono_modem *modem;
> +	ofono_gprs_provision_cb_t cb;
> +	void *user_data;
> +};
> +
> +static void settings_cb(GSList *settings, void *user_data);
> +
> +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);
> +

No empty line here please. Checking for a memory allocation result
should be done right away.

We might have some leftover cases from the earlier days. So bonus points
if you find them and fix them ;)

> +	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);
> +	}
> +}
> +
> +void ofono_gprs_provision_data_free(struct ofono_gprs_provision_data *data)
> +{
> +	if (data == NULL)
> +		return;
> +
> +	free(data->name);
> +	free(data->apn);
> +	free(data->username);
> +	free(data->password);
> +	free(data->message_proxy);
> +	free(data->message_center);

Use g_free for all of them please.

> +	g_free(data);
> +}

As mentioned in the other reply. This sounds more like an internal API
detail to me.

> + * 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;
> +
> +	if (req->drivers == NULL)
> +		return FALSE;

What is this check for? Wouldn't a 

	while (req->drivers != NULL) {

	}

	return FALSE;

just work fine as well.

> +
> +	do {
> +		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);
> +
> +			provision_requests = g_slist_append(provision_requests,
> +								req);
> +			context->driver->get_settings(context, cb, req);
> +			return TRUE;
> +		}
> +
> +	} while (req->drivers != NULL);
> +
> +	return FALSE;
> +}
> +
> +static void settings_cb(GSList *settings, void *user_data)
> +{
> +	struct gprs_provision_request *req = user_data;
> +
> +	provision_requests = g_slist_remove(provision_requests, req);
> +	if (settings == NULL) {
> +		DBG("Provisioning plugin returned no settings");

This sounds more like an ofono_warn message. Especially if you can also
print out the settings driver name.

> +		/* No success from this driver, try next */
> +		if (call_driver_get_settings(req, settings_cb) == TRUE)
> +			return;
> +	} else
> +		DBG("Provisioning plugin returned settings for %d contexts",
> +			g_slist_length(settings));
> +
> +	req->cb(settings, 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, 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);
> +}

Regards

Marcel



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

* Re: [PATCH 1/8] gprs-provision: add driver API header
  2011-01-18 14:48   ` Marcel Holtmann
@ 2011-01-19  5:58     ` Jukka Saunamaki
  0 siblings, 0 replies; 13+ messages in thread
From: Jukka Saunamaki @ 2011-01-19  5:58 UTC (permalink / raw)
  To: ofono

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

Hi Marcel,

> > +/*
> > + * Callback from provisioning plugin.
> > + * settings: list of struct ofono_gprs_provision_data
> > + *
> > + * It is responsibility of callback function to free settings-list
> > + * settings-list elements must be freed with ofono_gprs_provision_data_free()
> > + */
> > +typedef void (*ofono_gprs_provision_cb_t)(GSList *settings, void *userdata);
> 
> so our general rule is no GLib types in oFono public APIs.

OK. Do you have any preferences for the best type here? Linked list of
'struct ofono_gprs_provision_data's, array of structs + count, array of
pointers (+count)?

--Jukka



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

end of thread, other threads:[~2011-01-19  5:58 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-01-18  8:09 [gprs-provision PATCHv4 0/8] plugin API for provisioning of GPRS context settings Jukka Saunamaki
2011-01-18  8:09 ` [PATCH 1/8] gprs-provision: add driver API header Jukka Saunamaki
2011-01-18 14:48   ` Marcel Holtmann
2011-01-19  5:58     ` Jukka Saunamaki
2011-01-18  8:09 ` [PATCH 2/8] gprs-provision: add new atom type Jukka Saunamaki
2011-01-18  8:09 ` [PATCH 3/8] gprs-provision: add driver API sources Jukka Saunamaki
2011-01-18 14:55   ` Marcel Holtmann
2011-01-18  8:09 ` [PATCH 4/8] gprs-provision: probe gprs_provision drivers Jukka Saunamaki
2011-01-18  8:09 ` [PATCH 5/8] gprs: add gprs context provisioning Jukka Saunamaki
2011-01-18  8:09 ` [PATCH 6/8] sim: getters for mcc and mnc definition Jukka Saunamaki
2011-01-18  8:09 ` [PATCH 7/8] sim: getters for mcc and mnc implementation Jukka Saunamaki
2011-01-18 14:44   ` Marcel Holtmann
2011-01-18  8:09 ` [PATCH 8/8] 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.