All of lore.kernel.org
 help / color / mirror / Atom feed
* GPRS support for Ofono
@ 2009-09-01 11:09 Ismo Puustinen
  2009-09-01 19:02 ` Jean-Christian de Rivaz
  2009-09-01 21:36 ` Denis Kenzior
  0 siblings, 2 replies; 42+ messages in thread
From: Ismo Puustinen @ 2009-09-01 11:09 UTC (permalink / raw)
  To: ofono

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

Hello List,

I started working on Ofono GPRS support.

The patch set contains:

1) Documentation describing how an Ofono GPRS D-Bus API would look like.
2) Common Ofono GPRS support.
3) Ofono GPRS ISI driver.
4) Test script for trying out the GPRS functionality.

Note that the GPRS support is in no way completed -- many things are
still TODO or have rough edges. However, I thought that it would be a
good idea to send the patches to the mailing list to gather comments
and improvement suggestions before finalizing the work.

PS. A disclaimer: I'm a Nokia engineer, even though I'm sending this
email from my personal email account (due to incompatibilities with
Nokia email servers). If you need to contact me off-the-list, please
use the email address ismo.h.puustinen(a)nokia.com .

-- 
Ismo Puustinen <ismo@iki.fi>

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-GPRS-API-documentation.patch --]
[-- Type: text/x-patch, Size: 5922 bytes --]

From 77d342e3404f5ba7374505f5a65191fa200f52cc Mon Sep 17 00:00:00 2001
From: Ismo Puustinen <ismo.h.puustinen@nokia.com>
Date: Mon, 31 Aug 2009 13:40:22 +0300
Subject: [PATCH] GPRS API documentation

---
 doc/gprs-api.txt        |   69 +++++++++++++++++++++++++++++++++++++++++++
 doc/gprsmanager-api.txt |   74 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 143 insertions(+), 0 deletions(-)
 create mode 100644 doc/gprs-api.txt
 create mode 100644 doc/gprsmanager-api.txt

diff --git a/doc/gprs-api.txt b/doc/gprs-api.txt
new file mode 100644
index 0000000..15daaae
--- /dev/null
+++ b/doc/gprs-api.txt
@@ -0,0 +1,69 @@
+GPRS context hierarchy
+======================
+
+Service     org.ofono
+Interface   org.ofono.GprsContext
+Object path [variable prefix]/{modem0,modem1,...}/{context0,context1,...}
+
+Methods     dict GetProperties()
+
+            Returns all global system properties. See the
+            properties section for available properties.
+
+Signals     PropertyChanged(string property, variant value)
+
+            Signal is emitted whenever a property has changed.
+            The new value is passed as the signal argument.
+
+        ConnectionStatistics(dict statistics)
+
+            Signal is emitted whenever a connection has ended. The
+            signal argument contains a dict with the connection
+            statistics (connection time, transferred bytes).
+
+Properties  string State [readonly]
+
+            Contains the state of the current GPRS context. The state
+            can be one of:
+                - "connecting" - The context is being connected
+                - "connected" - The context is connected
+                - "disconnected" - The context is disconnected, further
+                    use forbidden, since the context will be destroyed
+                    shortly.
+
+        string Type [readonly]
+
+            Contains the connection type ("IPv4" or "IPv6").
+
+        string Address [readonly]
+
+            Contains the IPv4 or IPv6 address of the connection.
+
+        string PrimaryDNSAddress [readonly]
+
+            Contains the primary DNS address returned by the network.
+
+        string SecondaryDNSAddress [readonly]
+
+            Contains the secondary DNS address returned by the network.
+
+        string Interface [readonly]
+
+            Contains the network interface name for the GPRS connection.
+
+        uint32 TransmittedBytes [readonly]
+
+            Contains the amount of bytes transmitted with this GPRS
+            context. This property is not sent with the PropertyChanged
+            signal.
+
+        uint32 ReceivedBytes [readonly]
+
+            Contains the amount of bytes transmitted with this GPRS
+            context. This property is not sent with the PropertyChanged
+            signal.
+
+        uint32 ConnectionTime [readonly]
+
+            Contains the duration of the connection in seconds. This
+            property is not sent with the PropertyChanged signal.
diff --git a/doc/gprsmanager-api.txt b/doc/gprsmanager-api.txt
new file mode 100644
index 0000000..12cfb27
--- /dev/null
+++ b/doc/gprsmanager-api.txt
@@ -0,0 +1,74 @@
+GPRS manager hierarchy
+======================
+
+Service     org.ofono
+Interface   org.ofono.GprsManager
+Object path [variable prefix]/{modem0,modem1,...}
+
+Methods     dict GetProperties()
+
+            Returns all global system properties. See the properties
+            section for available properties.
+
+            Possible Errors: [service].Error.InvalidArguments
+
+        void Attach
+
+            If the GPRS subsystem state is "detached", this will attempt
+            to attach it.
+
+            Possible Errors: [service].Error.AttachFailed
+
+        void Detach
+
+            If the GPRS subsystem state is "attached" or "suspended",
+            this will attempt to detach it.
+
+            Possible Errors: [service].Error.DetachFailed
+
+        object Connect(string apn, string type, string username,
+                        string password, dict optionalArguments)
+
+            Creates a new GPRS context and connects it.  The first
+            parameter is the GPRS Access point name, the second
+            parameter is the connection type ("IPv4" or "IPv6"), the
+            third parameter is the username ("" for no username), and
+            the fourth parameter is the password ("" for no password).
+
+            The last parameter is a dictionary of optional arguments to
+            the GPRS context as key/value pairs. It contains more rarely
+            used connection parameters which already have good default
+            values. An empty dict means that the default values are
+            used.
+
+            The available keys are: TBD.
+
+            Possible Errors: [service].Error.ConnectFailed
+
+        void Disconnect(object context)
+
+            Disconnects and destroys a GPRS context. The context will
+            emit the ConnectionStatistics signal, but its methods or
+            properties may not be called or queried anymore.
+
+            Possible Errors: [service].Error.DisconnectFailed
+
+Signals     PropertyChanged(string property, variant value)
+
+            Signal is emitted whenever a property has changed.  The new
+            value is passed as the signal argument.
+
+Properties  array{object} Contexts [readonly]
+
+            Returns the list of GPRS contexts present in the system. If
+            there are no GPRS contexts, the list will be empty.
+
+        string State [readonly]
+
+            Contains the state of the GPRS subsystem. The state can be
+            one of:
+                - "attached" - the GPRS subsystem is available
+                - "detached" - the GPRS subsystem is not available
+                - "suspended" - the GPRS subsystem is temporarily not
+                    available
+
-- 
1.6.0.4


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: 0002-GPRS-Atom.patch --]
[-- Type: text/x-patch, Size: 27945 bytes --]

From a5239566e9283657326177fd87fc11b127f73328 Mon Sep 17 00:00:00 2001
From: Ismo Puustinen <ismo.h.puustinen@nokia.com>
Date: Tue, 1 Sep 2009 12:05:21 +0300
Subject: [PATCH] GPRS Atom

---
 Makefile.am    |    5 +-
 include/gprs.h |  151 ++++++++++
 src/gprs.c     |  854 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/ofono.h    |    1 +
 4 files changed, 1009 insertions(+), 2 deletions(-)
 create mode 100644 include/gprs.h
 create mode 100644 src/gprs.c

diff --git a/Makefile.am b/Makefile.am
index 7ee6536..8b53e78 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -9,7 +9,8 @@ include_HEADERS = include/log.h include/plugin.h include/history.h \
 			include/call-meter.h include/call-settings.h \
 			include/phonebook.h include/ssn.h include/ussd.h \
 			include/sms.h include/sim.h include/message-waiting.h \
-			include/netreg.h include/voicecall.h include/devinfo.h
+			include/netreg.h include/voicecall.h include/devinfo.h \
+			include/gprs.h
 
 nodist_include_HEADERS = include/version.h
 
@@ -94,7 +95,7 @@ src_ofonod_SOURCES = $(gdbus_sources) $(builtin_sources) \
 			src/call-meter.c src/smsutil.h src/smsutil.c \
 			src/ssn.c src/call-barring.c src/sim.c \
 			src/phonebook.c src/history.c src/message-waiting.c \
-			src/simutil.h src/simutil.c
+			src/simutil.h src/simutil.c src/gprs.c
 
 src_ofonod_LDADD = $(builtin_libadd) \
 			@GLIB_LIBS@ @GTHREAD_LIBS@ @DBUS_LIBS@ -ldl
diff --git a/include/gprs.h b/include/gprs.h
new file mode 100644
index 0000000..aa87e38
--- /dev/null
+++ b/include/gprs.h
@@ -0,0 +1,151 @@
+/*
+ * This file is part of oFono - Open Source Telephony
+ *
+ * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * Contact: Ismo Puustinen <ismo.h.puustinen@nokia.com>
+ *
+ * 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_H
+#define __OFONO_GPRS_H
+
+#include <ofono/types.h>
+
+#define GPRS_CONTEXT_ID_INVALID 0x100
+
+#define GPRS_TYPE_IPV4 "IPv4"
+#define GPRS_TYPE_IPV6 "IPv6"
+
+/* manager */
+
+#define GPRS_PROPERTY_STATE 				"State"
+
+#define GPRS_STATE_ATTACHED					"attached"
+#define GPRS_STATE_DETACHED					"detached"
+#define GPRS_STATE_SUSPENDED				"suspended"
+
+/* contexts */
+
+#define GPRS_CONTEXT_PROPERTY_STATE 		"State"
+#define GPRS_CONTEXT_PROPERTY_TYPE 			"Type"
+#define GPRS_CONTEXT_PROPERTY_ADDRESS 		"Address"
+#define GPRS_CONTEXT_PROPERTY_PDNS_ADDRESS 	"PrimaryDNSAddress"
+#define GPRS_CONTEXT_PROPERTY_SDNS_ADDRESS 	"SecondaryDNSAddress"
+#define GPRS_CONTEXT_PROPERTY_INTERFACE		"Interface"
+#define GPRS_CONTEXT_PROPERTY_TX_BYTES		"TransmittedBytes"
+#define GPRS_CONTEXT_PROPERTY_RX_BYTES		"ReceivedBytes"
+
+#define GPRS_CONTEXT_STATE_CONNECTING		"connecting"
+#define GPRS_CONTEXT_STATE_CONNECTED		"connected"
+#define GPRS_CONTEXT_STATE_DISCONNECTED		"disconnected"
+
+struct ofono_gprs;
+
+typedef unsigned int ofono_gprs_context_id_t;
+
+/* callbacks */
+
+typedef void (*ofono_gprs_generic_cb_t)(const struct ofono_error *error,
+		void *data);
+
+typedef void (*ofono_gprs_new_context_cb_t)(const struct ofono_error *error,
+		ofono_gprs_context_id_t token,
+		void *data);
+
+typedef void (*ofono_gprs_destroy_context_cb_t)(const struct ofono_error *error,
+		ofono_gprs_context_id_t token,
+		void *data);
+
+/* TODO: add a variant property list as a parameter to the new_context
+ * call -- it will contain the rarely used or modem spesific properties
+ * (QoS, fixed IP address, forced header compression, ...) */
+
+struct ofono_gprs_driver {
+	const char *name;
+	int (*probe)(struct ofono_gprs *manager);
+	int (*remove)(struct ofono_gprs *manager);
+	void (*new_context)(struct ofono_gprs *manager,
+			const char *apn,
+			const char *type,
+			const char *username,
+			const char *password,
+			ofono_gprs_new_context_cb_t cb,
+			void *data);
+	void (*destroy_context)(struct ofono_gprs *manager,
+			ofono_gprs_context_id_t token,
+			ofono_gprs_destroy_context_cb_t cb, void *data);
+	void (*attach)(struct ofono_gprs *manager,
+			ofono_gprs_generic_cb_t cb, void *data);
+	void (*detach)(struct ofono_gprs *manager,
+			ofono_gprs_generic_cb_t cb, void *data);
+};
+
+/* manager-level notification functions */
+
+void ofono_gprs_state_notify(
+		struct ofono_gprs *manager,
+		const char *state);
+
+
+/* context-specific notification functions */
+
+void ofono_gprs_context_state_notify(struct ofono_gprs *manager,
+		ofono_gprs_context_id_t token, const char *state);
+
+void ofono_gprs_context_type_notify(struct ofono_gprs *manager,
+		ofono_gprs_context_id_t token, const char *type);
+
+void ofono_gprs_context_address_notify(struct ofono_gprs *manager,
+		ofono_gprs_context_id_t token, const char *address);
+
+void ofono_gprs_context_pdns_address_notify(struct ofono_gprs *manager,
+		ofono_gprs_context_id_t token, const char *pdns_address);
+
+void ofono_gprs_context_sdns_address_notify(struct ofono_gprs *manager,
+		ofono_gprs_context_id_t token, const char *sdns_address);
+
+void ofono_gprs_context_interface_notify(struct ofono_gprs *manager,
+		ofono_gprs_context_id_t token, const char *interface);
+
+void ofono_gprs_context_tx_bytes_notify(struct ofono_gprs *manager,
+		ofono_gprs_context_id_t token, uint32_t tx_bytes);
+
+void ofono_gprs_context_rx_bytes_notify(struct ofono_gprs *manager,
+		ofono_gprs_context_id_t token, uint32_t rx_bytes);
+
+
+/* ofono boilerplate functions */
+
+
+int ofono_gprs_driver_register(const struct ofono_gprs_driver *d);
+void ofono_gprs_driver_unregister(const struct ofono_gprs_driver *d);
+
+struct ofono_gprs *ofono_gprs_create(struct ofono_modem *modem,
+		const char *driver,
+		void *data);
+
+void ofono_gprs_register(struct ofono_gprs *manager);
+void ofono_gprs_remove(struct ofono_gprs *manager);
+
+void ofono_gprs_set_data(struct ofono_gprs *manager, void *data);
+void *ofono_gprs_get_data(struct ofono_gprs *manager);
+
+/* vim: ts=4:noexpandtab:
+*/
+
+#endif
diff --git a/src/gprs.c b/src/gprs.c
new file mode 100644
index 0000000..62fd728
--- /dev/null
+++ b/src/gprs.c
@@ -0,0 +1,854 @@
+/*
+ * This file is part of oFono - Open Source Telephony
+ *
+ * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * Contact: Ismo Puustinen <ismo.h.puustinen@nokia.com>
+ *
+ * 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
+ *
+ */
+
+/*
+ * TODO:
+ *  - GPRS Manager properties
+ *  - Caching of the property values
+ *  - GetProperties method calls for both Manager and Contexts
+ *  - ConnectionStatistics signal
+ *  - Error handling for partially completed connections
+ *  - Support for querying already active contexts during ofono startup?
+ * */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <errno.h>
+#include <ctype.h>
+
+#include <glib.h>
+#include <gdbus.h>
+
+#include "ofono.h"
+
+#include "util.h"
+
+#include "gprs.h"
+
+static GSList *g_drivers = NULL;
+
+struct ofono_gprs {
+	char *path;
+	GSList *contexts;
+	DBusMessage *pending;
+	const struct ofono_gprs_driver *driver;
+	void *driver_data;
+	struct ofono_atom *atom;
+};
+
+struct ofono_gprs_context {
+	struct ofono_gprs *manager; /* backpointer */
+	char *path;
+	int to_be_destroyed;
+	int to_be_connected;
+	ofono_gprs_context_id_t token;
+	DBusMessage *pending;
+};
+
+#define GPRS_CONTEXT_INTERFACE "org.ofono.GprsContext"
+
+static ofono_gprs_context_id_t token_from_path(struct ofono_gprs *manager,
+		const char *path)
+{
+	int len = strlen(path);
+	int digits = 0, i;
+
+	/* get the digits from the end of the context path */
+
+	for (i = len-1; i >= 0; i--) {
+		if (isdigit(path[i]))
+			digits++;
+		else
+			break;
+	}
+
+	return strtol(&path[len-digits], NULL, 10);
+}
+
+static char * path_from_token(struct ofono_gprs *manager,
+		ofono_gprs_context_id_t token)
+{
+	const char *modem_path = __ofono_atom_get_path(manager->atom);
+	static char path[256];
+
+	snprintf(path, sizeof(path), "%s/gprs%u", modem_path, token);
+
+	return path;
+}
+
+static struct ofono_gprs_context * gprs_find_context(
+		struct ofono_gprs *manager, const char *path)
+{
+	GSList *e = NULL;
+
+	if (!manager)
+		return NULL;
+
+	for (e = manager->contexts; e != NULL; e = g_slist_next(e)) {
+		struct ofono_gprs_context *context = e->data;
+		if (strcmp(path_from_token(manager, context->token), path) == 0) {
+			return context;
+		}
+	}
+
+	return NULL;
+}
+
+static DBusMessage * gprs_context_get_properties(DBusConnection *conn,
+		DBusMessage *msg, void *data)
+{
+	const char *path = dbus_message_get_path(msg);
+	struct ofono_gprs *manager = data;
+	struct ofono_gprs_context *context = gprs_find_context(manager, path);
+
+	/* TODO */
+
+	if (!context) {
+		return __ofono_error_not_found(msg);
+	}
+
+	if (context->pending || context->to_be_destroyed) {
+		return __ofono_error_busy(msg);
+	}
+
+	context->pending = dbus_message_ref(msg);
+	return NULL;
+}
+
+static GDBusMethodTable gprs_context_methods[] = {
+	{ "GetProperties",	"",			"a{sv}",	gprs_context_get_properties },
+	{ }
+};
+
+static GDBusSignalTable gprs_context_signals[] = {
+	{ "PropertyChanged",		"sv" },
+	{ "ConnectionStatistics",	"sv" },
+	{ }
+};
+
+
+static void gprs_context_destroy(gpointer data)
+{
+	ofono_debug("> gprs_context_destroy: %p", data);
+
+	return;
+}
+
+static struct ofono_gprs_context * new_context(struct ofono_gprs *manager,
+		ofono_gprs_context_id_t token)
+{
+	DBusConnection *conn = ofono_dbus_get_connection();
+	struct ofono_gprs_context *context = g_new0(struct ofono_gprs_context, 1);
+	char *path = path_from_token(manager, token);
+
+	context->token = token;
+	context->manager = manager;
+
+	if (!g_dbus_register_interface(conn, path,
+				GPRS_CONTEXT_INTERFACE,
+				gprs_context_methods,
+				gprs_context_signals,
+				NULL, context,
+				gprs_context_destroy)) {
+		ofono_error("Could not register GPRS Context interface");
+
+		gprs_context_destroy(context);
+		return NULL;
+	}
+
+	ofono_debug("GPRS Context interface for modem: %s created",
+			path);
+
+	return context;
+
+}
+/* GPRS Manager takes care of the GPRS Context objects */
+
+#define OFONO_GPRS_MANAGER_INTERFACE "org.ofono.GprsManager"
+
+static void gprs_error_disconnect(struct ofono_gprs *manager,
+		ofono_gprs_context_id_t token)
+{
+	/* something terrible has happened and we need to disconnect --
+	 * perhaps the connection could not be fully completed */
+
+	/* TODO */
+
+	return;
+}
+
+static DBusMessage * gprs_get_properties(DBusConnection *conn,
+		DBusMessage *msg, void *data)
+{
+	struct ofono_gprs *manager = data;
+
+	/* TODO */
+
+	if (manager->pending) {
+		DBusMessage *reply = __ofono_error_busy(msg);
+		g_dbus_send_message(conn, reply);
+		return NULL;
+	}
+	manager->pending = dbus_message_ref(msg);
+
+	return NULL;
+}
+
+static void gprs_error_handling_cb(const struct ofono_error *error,
+		void *data)
+{
+	struct ofono_gprs *manager = data;
+	DBusMessage *reply = NULL;
+
+	if (!manager || !manager->pending)
+		return;
+
+	if (error->type != OFONO_ERROR_TYPE_NO_ERROR) {
+		__ofono_dbus_pending_reply(&manager->pending,
+				__ofono_error_failed(manager->pending));
+		return;
+	}
+
+	/* reply to the pending call */
+	reply = dbus_message_new_method_return(manager->pending);
+
+	if (!reply) {
+		/* out of memory, can't even send a reply */
+		return;
+	}
+
+	__ofono_dbus_pending_reply(&manager->pending, reply);
+}
+
+static DBusMessage * gprs_attach(DBusConnection *conn,
+		DBusMessage *msg, void *data)
+{
+	struct ofono_gprs *manager = data;
+
+	ofono_debug("Attach called");
+
+	if (manager->pending) {
+		return __ofono_error_busy(msg);
+	}
+	manager->pending = dbus_message_ref(msg);
+
+	manager->driver->attach(manager, gprs_error_handling_cb, manager);
+
+	return NULL;
+}
+
+static DBusMessage * gprs_detach(DBusConnection *conn,
+		DBusMessage *msg, void *data)
+{
+	struct ofono_gprs *manager = data;
+
+	ofono_debug("Detach called");
+
+	if (manager->pending) {
+		return __ofono_error_busy(msg);
+	}
+	manager->pending = dbus_message_ref(msg);
+
+	manager->driver->detach(manager, gprs_error_handling_cb, manager);
+
+	return NULL;
+}
+
+#if 0
+static bool bogus_event(const struct gprs_property *property)
+{
+	/* TODO */
+
+	return false;
+}
+#endif
+
+static bool send_connection_statistics(DBusConnection *conn,
+		const char *path, struct ofono_gprs_context *context)
+{
+	/* TODO */
+
+	return true;
+}
+
+
+void ofono_gprs_context_state_notify(struct ofono_gprs *manager,
+		ofono_gprs_context_id_t token, const char *state)
+{
+	/* FIXME: check error and NULL values */
+
+	char *context_path = path_from_token(manager, token);
+	struct ofono_modem *modem = __ofono_atom_get_modem(manager->atom);
+	struct ofono_gprs_context *context = gprs_find_context(manager, context_path);
+	DBusConnection *conn = ofono_dbus_get_connection();
+
+	if (!context || !state) {
+		/* bogus event */
+		goto end;
+	}
+
+	ofono_dbus_signal_property_changed(conn, context_path,
+			GPRS_CONTEXT_INTERFACE,
+			GPRS_CONTEXT_PROPERTY_STATE,
+			DBUS_TYPE_STRING,
+			&state);
+
+	if (strcmp(state, GPRS_CONTEXT_STATE_CONNECTED) == 0) {
+
+		/* reply to the pending call */
+
+		DBusMessage *reply = dbus_message_new_method_return(manager->pending);
+
+		if (!reply) {
+			/* out of memory, can't even send a reply */
+			gprs_error_disconnect(manager, token);
+			if (g_slist_length(manager->contexts) == 1) {
+				ofono_modem_remove_interface(modem, GPRS_CONTEXT_INTERFACE);
+			}
+			goto end;
+		}
+
+		/* The connection is online and ready. Send the reply to the
+		 * D-Bus connection creation message. */
+
+		/* the context is now connected and ready */
+		context->to_be_connected = 0;
+
+		dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH,
+				&context_path,
+				DBUS_TYPE_INVALID);
+
+		__ofono_dbus_pending_reply(&manager->pending, reply);
+	}
+	else if (strcmp(state, GPRS_CONTEXT_STATE_DISCONNECTED) == 0) {
+
+		if (context->to_be_destroyed) {
+
+			/* User requested that this connection was to be
+			 * destroyed */
+
+			DBusMessage *reply = dbus_message_new_method_return(manager->pending);
+
+			if (!reply) {
+				/* out of memory, can't even send a reply */
+				return;
+			}
+
+			__ofono_dbus_pending_reply(&manager->pending, reply);
+		}
+		else if (context->to_be_connected) {
+
+			/* the context creation did not succeed, send a D-Bus
+			 * error the the user */
+
+			if (manager->pending) {
+				__ofono_dbus_pending_reply(&manager->pending,
+						__ofono_error_failed(manager->pending));
+			}
+		}
+		else {
+			/* network requested connection shutdown */
+		}
+
+		/* Send the ConnectionStatistics signal */
+
+		send_connection_statistics(conn, context_path, context);
+
+		/* Delete our representation of the context only when
+		 * everything is said and done and the ConnectionStatistics
+		 * signal has been sent */
+
+		manager->contexts = g_slist_remove(manager->contexts, context);
+		g_dbus_unregister_interface(conn, context_path, GPRS_CONTEXT_INTERFACE);
+	}
+
+end:
+
+	return;
+}
+
+void ofono_gprs_context_type_notify(struct ofono_gprs *manager,
+		ofono_gprs_context_id_t token, const char *type)
+{
+	char *context_path = path_from_token(manager, token);
+	DBusConnection *conn = ofono_dbus_get_connection();
+	struct ofono_gprs_context *context = gprs_find_context(manager, context_path);
+
+	if (!context || !type) {
+		/* bogus event */
+		return;
+	}
+
+	ofono_dbus_signal_property_changed(conn, context_path,
+			GPRS_CONTEXT_INTERFACE,
+			GPRS_CONTEXT_PROPERTY_TYPE,
+			DBUS_TYPE_STRING,
+			&type);
+
+	return;
+}
+
+void ofono_gprs_context_address_notify(struct ofono_gprs *manager,
+		ofono_gprs_context_id_t token, const char *address)
+{
+
+	char *context_path = path_from_token(manager, token);
+	DBusConnection *conn = ofono_dbus_get_connection();
+	struct ofono_gprs_context *context = gprs_find_context(manager, context_path);
+
+	if (!context || !address) {
+		/* bogus event */
+		return;
+	}
+
+	ofono_dbus_signal_property_changed(conn, context_path,
+			GPRS_CONTEXT_INTERFACE,
+			GPRS_CONTEXT_PROPERTY_ADDRESS,
+			DBUS_TYPE_STRING,
+			&address);
+
+	return;
+}
+
+void ofono_gprs_context_pdns_address_notify(struct ofono_gprs *manager,
+		ofono_gprs_context_id_t token, const char *pdns_address)
+{
+	char *context_path = path_from_token(manager, token);
+	DBusConnection *conn = ofono_dbus_get_connection();
+	struct ofono_gprs_context *context = gprs_find_context(manager, context_path);
+
+	if (!context || !pdns_address) {
+		/* bogus event */
+		return;
+	}
+
+	ofono_dbus_signal_property_changed(conn, context_path,
+			GPRS_CONTEXT_INTERFACE,
+			GPRS_CONTEXT_PROPERTY_PDNS_ADDRESS,
+			DBUS_TYPE_STRING,
+			&pdns_address);
+
+	return;
+}
+
+void ofono_gprs_context_sdns_address_notify(struct ofono_gprs *manager,
+		ofono_gprs_context_id_t token, const char *sdns_address)
+{
+	char *context_path = path_from_token(manager, token);
+	DBusConnection *conn = ofono_dbus_get_connection();
+	struct ofono_gprs_context *context = gprs_find_context(manager, context_path);
+
+	if (!context || !sdns_address) {
+		/* bogus event */
+		return;
+	}
+
+	ofono_dbus_signal_property_changed(conn, context_path,
+			GPRS_CONTEXT_INTERFACE,
+			GPRS_CONTEXT_PROPERTY_SDNS_ADDRESS,
+			DBUS_TYPE_STRING,
+			&sdns_address);
+
+	return;
+}
+
+void ofono_gprs_context_interface_notify(struct ofono_gprs *manager,
+		ofono_gprs_context_id_t token, const char *interface)
+{
+	char *context_path = path_from_token(manager, token);
+	DBusConnection *conn = ofono_dbus_get_connection();
+	struct ofono_gprs_context *context = gprs_find_context(manager, context_path);
+
+	if (!context || !interface) {
+		/* bogus event */
+		return;
+	}
+
+	ofono_dbus_signal_property_changed(conn, context_path,
+			GPRS_CONTEXT_INTERFACE,
+			GPRS_CONTEXT_PROPERTY_INTERFACE,
+			DBUS_TYPE_STRING,
+			&interface);
+
+	return;
+}
+
+void ofono_gprs_context_tx_bytes_notify(struct ofono_gprs *manager,
+		ofono_gprs_context_id_t token, uint32_t tx_bytes)
+{
+	char *context_path = path_from_token(manager, token);
+	DBusConnection *conn = ofono_dbus_get_connection();
+	struct ofono_gprs_context *context = gprs_find_context(manager, context_path);
+
+	if (!context) {
+		/* bogus event */
+		return;
+	}
+
+	ofono_dbus_signal_property_changed(conn, context_path,
+			GPRS_CONTEXT_INTERFACE,
+			GPRS_CONTEXT_PROPERTY_RX_BYTES,
+			DBUS_TYPE_UINT32,
+			&tx_bytes);
+
+	return;
+}
+
+void ofono_gprs_context_rx_bytes_notify(struct ofono_gprs *manager,
+		ofono_gprs_context_id_t token, uint32_t rx_bytes)
+{
+	char *context_path = path_from_token(manager, token);
+	DBusConnection *conn = ofono_dbus_get_connection();
+	struct ofono_gprs_context *context = gprs_find_context(manager, context_path);
+
+	if (!context) {
+		/* bogus event */
+		return;
+	}
+
+	ofono_dbus_signal_property_changed(conn, context_path,
+			GPRS_CONTEXT_INTERFACE,
+			GPRS_CONTEXT_PROPERTY_TX_BYTES,
+			DBUS_TYPE_UINT32,
+			&rx_bytes);
+
+	return;
+}
+
+static void gprs_connect_cb(const struct ofono_error *error,
+		ofono_gprs_context_id_t token,
+		void *data)
+{
+	struct ofono_gprs *manager = data;
+	struct ofono_modem *modem = __ofono_atom_get_modem(manager->atom);
+	struct ofono_gprs_context *context = NULL;
+	DBusMessage *reply = NULL;
+
+	if (error->type != OFONO_ERROR_TYPE_NO_ERROR) {
+		reply = __ofono_error_failed(manager->pending);
+		goto send_reply;
+	}
+
+	context = new_context(manager, token);
+
+	if (!context) {
+		gprs_error_disconnect(manager, token);
+		reply = __ofono_error_failed(manager->pending);
+		goto send_reply;
+	}
+
+	context->to_be_connected = 1;
+
+	if (g_slist_length(manager->contexts) == 0) {
+		ofono_modem_add_interface(modem, GPRS_CONTEXT_INTERFACE);
+	}
+
+	manager->contexts = g_slist_prepend(manager->contexts, context);
+
+	/* success case is handled when the connection gets to a connected
+	 * state, errors when they come */
+
+	return;
+
+send_reply:
+
+	__ofono_dbus_pending_reply(&manager->pending, reply);
+
+	return;
+}
+
+static DBusMessage * gprs_connect(DBusConnection *conn,
+		DBusMessage *msg, void *data)
+{
+	struct ofono_gprs *manager = data;
+	const char *apn, *type, *username, *password;
+	DBusMessageIter iter;
+
+	ofono_debug("Connect called");
+
+	if (manager->pending) {
+		DBusMessage *reply = __ofono_error_busy(msg);
+		g_dbus_send_message(conn, reply);
+		return NULL;
+	}
+
+	dbus_message_iter_init(msg, &iter);
+
+	/* get APN */
+	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) {
+		goto err;
+	}
+	dbus_message_iter_get_basic(&iter, &apn);
+	dbus_message_iter_next(&iter);
+
+	/* get type */
+	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) {
+		goto err;
+	}
+	dbus_message_iter_get_basic(&iter, &type);
+	dbus_message_iter_next(&iter);
+
+	/* get username */
+	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) {
+		goto err;
+	}
+	dbus_message_iter_get_basic(&iter, &username);
+	dbus_message_iter_next(&iter);
+
+	/* get password */
+	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) {
+		goto err;
+	}
+	dbus_message_iter_get_basic(&iter, &password);
+
+	/* skip the extra options dict for now */
+
+	manager->pending = dbus_message_ref(msg);
+
+	/* create the connection */
+
+	manager->driver->new_context(manager,
+			apn, type, username, password,
+			gprs_connect_cb,
+			manager);
+
+	return NULL;
+
+err:
+	return __ofono_error_invalid_args(msg);
+}
+
+static void gprs_destroy_cb(const struct ofono_error *error,
+		ofono_gprs_context_id_t token,
+		void *data)
+{
+	struct ofono_gprs *manager = data;
+	struct ofono_gprs_context *context = NULL;
+
+	if (error->type != OFONO_ERROR_TYPE_NO_ERROR) {
+		__ofono_dbus_pending_reply(&manager->pending,
+				__ofono_error_failed(manager->pending));
+		return;
+	}
+
+	/* Mark the interface as non-active, so that nothing can be done
+	 * with it until the ConnectionStatistics signal arrives and the
+	 * context is finally removed. */
+
+	context = gprs_find_context(manager, path_from_token(manager, token));
+
+	if (context) {
+		context->to_be_destroyed = 1;
+	}
+	else {
+		/* something fishy is going on */
+	}
+
+	return;
+}
+
+static DBusMessage * gprs_disconnect(DBusConnection *conn,
+		DBusMessage *msg, void *data)
+{
+	struct ofono_gprs *manager = data;
+	const char *path;
+	struct ofono_gprs_context *context = NULL;
+
+	ofono_debug("Disconnect called");
+
+	if (manager->pending) {
+		return __ofono_error_busy(msg);
+	}
+
+	if (!dbus_message_get_args(
+				msg, NULL, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID)) {
+		return __ofono_error_invalid_args(msg);
+	}
+
+	context = gprs_find_context(manager, path);
+
+	if (!context || context->to_be_destroyed) {
+		return __ofono_error_not_found(msg);
+	}
+
+	manager->pending = dbus_message_ref(msg);
+
+	manager->driver->destroy_context(manager, token_from_path(manager, path),
+			gprs_destroy_cb, manager);
+
+	return NULL;
+}
+
+static GDBusMethodTable gprs_manager_methods[] = {
+	{ "GetProperties",	"",			"a{sv}",	gprs_get_properties },
+	{ "Attach",			"",			"",			gprs_attach, G_DBUS_METHOD_FLAG_ASYNC  },
+	{ "Detach",			"",			"",			gprs_detach, G_DBUS_METHOD_FLAG_ASYNC  },
+	{ "Connect",		"ssssa{sv}","o",		gprs_connect, G_DBUS_METHOD_FLAG_ASYNC  },
+	{ "Disconnect",		"o",		"",			gprs_disconnect, G_DBUS_METHOD_FLAG_ASYNC  },
+	{ }
+};
+
+static GDBusSignalTable gprs_manager_signals[] = {
+	{ "PropertyChanged",	"sv" },
+	{ }
+};
+
+void ofono_gprs_state_notify(
+		struct ofono_gprs *manager,
+		const char *state)
+{
+	/* TODO */
+	return;
+}
+
+
+/* ofono boilerplate code begins */
+
+
+
+static void gprs_remove(struct ofono_atom *atom)
+{
+	struct ofono_gprs *manager = __ofono_atom_get_data(atom);
+
+	DBG("atom: %p", atom);
+
+	if (manager == NULL)
+		return;
+
+	if (manager->driver && manager->driver->remove)
+		manager->driver->remove(manager);
+
+	g_free(manager);
+}
+
+int ofono_gprs_driver_register(const struct ofono_gprs_driver *d)
+{
+	DBG("driver: %p, name: %s", d, d->name);
+
+	if (d->probe == NULL)
+		return -EINVAL;
+
+	g_drivers = g_slist_prepend(g_drivers, (void *)d);
+
+	return 0;
+}
+
+void ofono_gprs_driver_unregister(const struct ofono_gprs_driver *d)
+{
+	DBG("driver: %p, name: %s", d, d->name);
+
+	g_drivers = g_slist_remove(g_drivers, (void *)d);
+}
+
+struct ofono_gprs *ofono_gprs_create(struct ofono_modem *modem,
+		const char *driver, void *data)
+{
+	struct ofono_gprs *manager;
+	GSList *l;
+
+	if (driver == NULL)
+		return NULL;
+
+	manager = g_try_new0(struct ofono_gprs, 1);
+
+	if (manager == NULL)
+		return NULL;
+
+	manager->driver_data = data;
+	manager->pending = NULL;
+	manager->atom = __ofono_modem_add_atom(modem, OFONO_ATOM_TYPE_GPRS,
+			gprs_remove, manager);
+
+	DBG("Probing GPRS drivers");
+
+	for (l = g_drivers; l; l = l->next) {
+		const struct ofono_gprs_driver *drv = l->data;
+
+		if (g_strcmp0(drv->name, driver))
+			continue;
+
+		if (drv->probe(manager) < 0)
+			continue;
+
+		manager->driver = drv;
+		break;
+	}
+
+	return manager;
+}
+
+static void gprs_unregister(struct ofono_atom *atom)
+{
+	struct ofono_gprs *manager = __ofono_atom_get_data(atom);
+	const char *path = __ofono_atom_get_path(manager->atom);
+	DBusConnection *conn = ofono_dbus_get_connection();
+	struct ofono_modem *modem = __ofono_atom_get_modem(manager->atom);
+
+	ofono_modem_remove_interface(modem, OFONO_GPRS_MANAGER_INTERFACE);
+	g_dbus_unregister_interface(conn, path, OFONO_GPRS_MANAGER_INTERFACE);
+}
+
+void ofono_gprs_register(struct ofono_gprs *manager)
+{
+	DBusConnection *conn = ofono_dbus_get_connection();
+	const char *path = __ofono_atom_get_path(manager->atom);
+	struct ofono_modem *modem = __ofono_atom_get_modem(manager->atom);
+
+	DBG("Registering GPRS manager interface on path %s", path);
+
+	if (!g_dbus_register_interface(conn, path, OFONO_GPRS_MANAGER_INTERFACE,
+				gprs_manager_methods, gprs_manager_signals,
+				NULL, manager, NULL)) {
+		ofono_error("Could not create %s interface",
+				OFONO_GPRS_MANAGER_INTERFACE);
+
+		return;
+	}
+
+	ofono_modem_add_interface(modem, OFONO_GPRS_MANAGER_INTERFACE);
+
+	__ofono_atom_register(manager->atom, gprs_unregister);
+
+	return;
+}
+
+void ofono_gprs_set_data(struct ofono_gprs *gprs, void *data)
+{
+	gprs->driver_data = data;
+}
+
+void *ofono_gprs_get_data(struct ofono_gprs *gprs)
+{
+	return gprs->driver_data;
+}
+
+/* vim: ts=4:noexpandtab:
+*/
+
diff --git a/src/ofono.h b/src/ofono.h
index bf31531..5eda013 100644
--- a/src/ofono.h
+++ b/src/ofono.h
@@ -82,6 +82,7 @@ enum ofono_atom_type {
 	OFONO_ATOM_TYPE_HISTORY = 11,
 	OFONO_ATOM_TYPE_SSN = 12,
 	OFONO_ATOM_TYPE_MESSAGE_WAITING = 13,
+	OFONO_ATOM_TYPE_GPRS = 14,
 };
 
 enum ofono_atom_watch_condition {
-- 
1.6.0.4


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #4: 0003-GPRS-ISI-modem-driver.patch --]
[-- Type: text/x-patch, Size: 41966 bytes --]

From 38760be738440f047b28f0d274d15a0990e3c6e4 Mon Sep 17 00:00:00 2001
From: Ismo Puustinen <ismo.h.puustinen@nokia.com>
Date: Mon, 31 Aug 2009 13:49:07 +0300
Subject: [PATCH] GPRS ISI modem driver

---
 Makefile.am                 |    1 +
 drivers/isimodem/gprs.c     | 1759 +++++++++++++++++++++++++++++++++++++++++++
 drivers/isimodem/isi.h      |    4 +
 drivers/isimodem/isimodem.c |    4 +
 4 files changed, 1768 insertions(+), 0 deletions(-)
 create mode 100644 drivers/isimodem/gprs.c

diff --git a/Makefile.am b/Makefile.am
index 8b53e78..a5d8c32 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -52,6 +52,7 @@ builtin_sources += $(gisi_sources) drivers/isimodem/isi.h \
 				drivers/isimodem/sim.c \
 				drivers/isimodem/ssn.c \
 				drivers/isimodem/ussd.c \
+				drivers/isimodem/gprs.c \
 				drivers/isimodem/call-forwarding.c \
 				drivers/isimodem/call-settings.c \
 				drivers/isimodem/call-barring.c \
diff --git a/drivers/isimodem/gprs.c b/drivers/isimodem/gprs.c
new file mode 100644
index 0000000..599c298
--- /dev/null
+++ b/drivers/isimodem/gprs.c
@@ -0,0 +1,1759 @@
+/*
+ * This file is part of oFono - Open Source Telephony
+ *
+ * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * Contact: Ismo Puustinen <ismo.h.puustinen@nokia.com>
+ *
+ * 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
+ *
+ */
+
+/*
+ * TODO:
+ *  - Better error handling!
+ *  - Helper functions for creating the ISI messages in a cleaner way
+ *  - Helper functions for parsing the ISI messages
+ *  - Support for fetching the GPRS interface information
+ *  - GPRS authentication support
+ *  - Support for querying already active contexts during ofono startup?
+ * */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <net/if.h>
+
+#include <glib.h>
+#include <gisi/client.h>
+#include <gisi/pipe.h>
+#include <gisi/pep.h>
+#include <gisi/phonet.h>
+
+#include <ofono/log.h>
+#include <ofono/modem.h>
+#include <ofono/gprs.h>
+#include "util.h"
+#include "isi.h"
+
+#define PN_GPDS				0x31
+#define GPDS_TIMEOUT		60
+
+enum message_id {
+	GPDS_LL_CONFIGURE_REQ = 0x00,
+	GPDS_LL_CONFIGURE_RESP = 0x01,
+	GPDS_CONTEXT_ID_CREATE_REQ = 0x02,
+	GPDS_CONTEXT_ID_CREATE_RESP = 0x03,
+	GPDS_CONTEXT_ID_CREATE_IND = 0x04,
+	GPDS_CONTEXT_ID_DELETE_IND = 0x05,
+	GPDS_CONTEXT_CONFIGURE_REQ = 0x06,
+	GPDS_CONTEXT_CONFIGURE_RESP = 0x07,
+	GPDS_CONTEXT_ACTIVATE_REQ = 0x08,
+	GPDS_CONTEXT_ACTIVATE_RESP = 0x09,
+	GPDS_CONTEXT_ACTIVATE_IND = 0x0A,
+	GPDS_CONTEXT_DEACTIVATE_REQ = 0x0B,
+	GPDS_CONTEXT_DEACTIVATE_RESP = 0x0C,
+	GPDS_CONTEXT_DEACTIVATE_IND = 0x0D,
+	GPDS_ATTACH_REQ = 0x13,
+	GPDS_ATTACH_RESP = 0x14,
+	GPDS_ATTACH_IND = 0x15,
+	GPDS_DETACH_REQ = 0x16,
+	GPDS_DETACH_RESP = 0x17,
+	GPDS_DETACH_IND = 0x18,
+	GPDS_TRANSFER_STATUS_IND = 0x1E,
+	GPDS_CONTEXT_ACTIVATE_FAIL_IND = 0x1F,
+	GPDS_CONTEXT_STATUS_IND = 0x24,
+	GPDS_CONTEXT_ACTIVATING_IND = 0x25,
+	GPDS_CONTEXT_DEACTIVATING_IND = 0x2F,
+	GPDS_CONFIGURATION_INFO_IND = 0x32,
+	GPDS_CONTEXT_AUTH_REQ = 0x33,
+	GPDS_CONTEXT_AUTH_RESP = 0x34,
+	GPDS_RESOURCE_CONTROL_IND = 0x50,
+};
+
+enum gpds_status {
+	GPDS_ERROR = 0x00,
+	GPDS_OK = 0x01,
+	GPDS_FAIL = 0x02
+};
+
+enum gpds_pdp_type {
+	GPDS_PDP_TYPE_PPP = 0x01,
+	GPDS_PDP_TYPE_IPV4 = 0x21,
+	GPDS_PDP_TYPE_IPV6 = 0x57,
+	GPDS_PDP_TYPE_DEFAULT = 0xFF
+};
+
+enum gprs_context_state {
+	GPRS_CONTEXT_INITED,
+	GPRS_CONTEXT_ID_REQUESTED,
+	GPRS_CONTEXT_LOCAL_LINK_CONFIGURED,
+	GPRS_CONTEXT_CONFIGURED,
+	GPRS_CONTEXT_ACTIVATING,
+	GPRS_CONTEXT_ACTIVATED,
+	GPRS_CONTEXT_PIPE_CREATED,
+	GPRS_CONTEXT_PIPE_STARTED,
+	GPRS_CONTEXT_CONNECTED,
+	GPRS_CONTEXT_DEACTIVATING,
+	GPRS_CONTEXT_DEACTIVATED,
+	GPRS_CONTEXT_FINISHED
+};
+
+struct gprs_data {
+	GIsiClient *client;
+	GIsiModem *isi_modem;
+	struct isi_version version;
+	struct ofono_gprs *manager; /* manager for this modem */
+	GSList *contexts;
+};
+
+/* There are two possiblities: either we keep the driver data as an
+ * opaque structure on the user side, or we keep local track of all
+ * contexts. */
+
+struct context_data {
+
+	/* This is the callback data for the context creation request. */
+	struct isi_cb_data *cbd;
+
+	/* This is the callback data for the context disconnection request. */
+	struct isi_cb_data *destroy_cbd;
+
+	/* This is the callback data for the context property updates. */
+	struct isi_cb_data *property_cbd;
+
+	char *apn;
+	unsigned char type;
+	char *username;
+	char *password;
+
+	enum gprs_context_state prev_state;
+	enum gprs_context_state state;
+
+	ofono_gprs_context_id_t token;
+	GIsiPipe *pipe;
+	GIsiPEP *pep;
+	uint16_t gpds_object;
+
+	union {
+		struct in_addr ipv4_addr;
+		struct in6_addr ipv6_addr;
+	} pdp_addr;
+	char pdp_addr_s[INET6_ADDRSTRLEN];
+
+	union {
+		struct in_addr ipv4_addr;
+		struct in6_addr ipv6_addr;
+	} pdns_addr;
+	char pdns_addr_s[INET6_ADDRSTRLEN];
+
+	union {
+		struct in_addr ipv4_addr;
+		struct in6_addr ipv6_addr;
+	} sdns_addr;
+	char sdns_addr_s[INET6_ADDRSTRLEN];
+};
+
+static struct context_data * gprs_find_context_by_pep(
+		struct gprs_data *data,
+		GIsiPEP *pep)
+{
+	GSList *e = NULL;
+
+	for (e = data->contexts; e != NULL; e = g_slist_next(e)) {
+		struct context_data *context = e->data;
+		if (pep == context->pep) {
+			return context;
+		}
+	}
+
+	return NULL;
+}
+
+static struct context_data * gprs_find_context(
+		struct gprs_data *data, ofono_gprs_context_id_t token)
+{
+	GSList *e = NULL;
+
+	for (e = data->contexts; e != NULL; e = g_slist_next(e)) {
+		struct context_data *context = e->data;
+		if (token == context->token) {
+			return context;
+		}
+	}
+
+	return NULL;
+}
+
+static void connection_sm(struct gprs_data *data,
+		struct context_data *c_data,
+		enum gprs_context_state new_state);
+
+
+static void delete_cdata(struct context_data *c_data)
+{
+	DBG("Freeing context data structure %p", c_data);
+
+	g_free(c_data);
+
+	return;
+}
+
+static void handle_gprs_context_error(struct gprs_data *data,
+		struct context_data *c_data,
+		struct ofono_error *err)
+{
+
+	/* This function is very much TODO */
+
+	/* if the connection creation is not successful, try to remove
+	 * already initialized parts of the connection */
+
+	ofono_gprs_new_context_cb_t cb;
+
+	DBG("GPRS error handler called...");
+
+	if (!c_data)
+		return;
+
+	DBG("... state %d", c_data->state);
+
+	if (c_data->cbd) {
+
+		cb = c_data->cbd->cb;
+
+		cb(err, c_data->token, c_data->cbd->data);
+
+		switch (c_data->state) {
+			case GPRS_CONTEXT_INITED:
+				/* No need to send property update, since the context
+				 * was never created */
+				goto end;
+			case GPRS_CONTEXT_ID_REQUESTED:
+				break;
+			case GPRS_CONTEXT_LOCAL_LINK_CONFIGURED:
+				break;
+			case GPRS_CONTEXT_CONFIGURED:
+				break;
+			case GPRS_CONTEXT_ACTIVATING:
+				break;
+			case GPRS_CONTEXT_ACTIVATED:
+				break;
+			case GPRS_CONTEXT_PIPE_CREATED:
+				break;
+			case GPRS_CONTEXT_PIPE_STARTED:
+				break;
+			case GPRS_CONTEXT_CONNECTED:
+				break;
+			case GPRS_CONTEXT_DEACTIVATING:
+				break;
+			case GPRS_CONTEXT_DEACTIVATED:
+				break;
+			case GPRS_CONTEXT_FINISHED:
+				break;
+		}
+
+	}
+
+	ofono_gprs_context_state_notify(data->manager, c_data->token,
+			GPRS_CONTEXT_STATE_DISCONNECTED);
+
+end:
+
+	delete_cdata(c_data);
+	return;
+}
+
+static bool parse_msg(int header_len, unsigned char **subs, int n_subs,
+		unsigned char *msg, int msg_len)
+{
+	int i;
+	unsigned char *msg_p;
+
+	if (n_subs < 1 || msg_len <= header_len) {
+		/* no subs to find */
+		DBG("No sub blocks to parse");
+		return false;
+	}
+
+	msg_p = &msg[header_len]; /* beginning of the first sub block */
+
+	for (i = 0; i < n_subs; i++) {
+		unsigned char sub_len = *(msg_p + 1);
+		subs[i] = msg_p;
+		msg_p = msg_p + sub_len;
+	}
+
+	if (msg_p - msg > msg_len) {
+		DBG("Message parsing failed");
+		return false;
+	}
+
+	return true;
+}
+
+static bool start_interface(struct gprs_data *data, struct context_data *c_data)
+{
+	return true;
+}
+
+static bool context_activate_resp_cb(GIsiClient *client, const void *restrict data,
+		size_t len, uint16_t object, void *opaque)
+{
+	const unsigned char *msg = data;
+	struct gprs_data *gprs_data = opaque;
+	struct context_data *c_data = NULL;
+	/* char *subs[6]; */
+	int n_subs;
+
+	DBG("> context_activate_resp_cb");
+
+	/* sanity checks */
+
+	if (!msg) {
+		DBG("ISI client error: %d", g_isi_client_error(client));
+		goto error;
+	}
+
+	dump_msg(msg, len);
+
+	if (len < 7) {
+		DBG("Wrong message length");
+		goto error;
+	}
+
+	if (msg[0] != GPDS_CONTEXT_ACTIVATE_RESP) {
+		DBG("Unexpected message ID: 0x%02x", msg[0]);
+		goto error;
+	}
+
+	c_data = gprs_find_context(gprs_data, msg[1]);
+	if (!c_data) {
+		DBG("Unknown PDP context: %d", msg[1]);
+		goto error;
+	}
+
+	if (msg[2] != GPDS_OK) {
+		DBG("Context activation error");
+		goto error;
+	}
+
+	n_subs = msg[6];
+
+	if (n_subs > 6) {
+		DBG("Too many sub blocks");
+		goto error;
+	}
+
+	return true;
+
+error:
+
+	DBG("Error activating the context");
+
+	{
+		DECLARE_FAILURE(error);
+		handle_gprs_context_error(gprs_data, c_data, &error);
+	}
+	return false;
+}
+
+
+static bool context_activate_req(struct gprs_data *data, struct context_data *c_data)
+{
+	const unsigned char msg_header[] = {
+		GPDS_CONTEXT_ACTIVATE_REQ,
+		c_data->token, /* CID */
+		0x01,  /* number of sub blocks */
+	};
+	unsigned char *msg;
+	GIsiRequest *req = NULL;
+	int addr_len, pdp_block_len, filler, msg_len;
+
+	/* we can have either IPv4 or IPv6 addresses */
+
+	DBG("> context_activate_req");
+
+	if (c_data->type == GPDS_PDP_TYPE_IPV6) {
+		addr_len = sizeof(struct in6_addr);
+	}
+	else {
+		/* default case */
+		addr_len = sizeof(struct in_addr);
+	}
+
+	filler = (4 + addr_len) % 4; /* ( PDP block header + PDP address length ) modulo 4 */
+	pdp_block_len = 4 + addr_len + filler;
+	msg_len = 3 + pdp_block_len;
+	msg = malloc(msg_len);
+
+	if (!msg)
+		goto error;
+
+	/* zero (for the address and the end filler bytes) */
+	memset(msg, 0, msg_len);
+
+	memcpy(msg, msg_header, sizeof(msg_header));
+
+	msg[3] = 0x04; /* GPDS_PDP_ADDRESS_INFO */
+	msg[4] = pdp_block_len;
+	msg[5] = 0x00; /* filler */
+	msg[6] = addr_len; /* filler */
+
+	/* the address is just zeroes */
+
+	DBG("The activation request:");
+	dump_msg(msg, msg_len);
+
+	req = g_isi_request_make(data->client, msg, msg_len, GPDS_TIMEOUT,
+			context_activate_resp_cb, data);
+
+	free(msg);
+
+	if (req) {
+		return true;
+	}
+
+error:
+
+	return false;
+}
+
+static bool context_configure_resp_cb(GIsiClient *client, const void *restrict data,
+		size_t len, uint16_t object, void *opaque)
+{
+	const unsigned char *msg = data;
+	struct context_data *c_data = NULL;
+	struct gprs_data *gprs_data = opaque;
+
+	DBG("> context_configure_resp_cb");
+
+	/* sanity checks */
+
+	if (!msg) {
+		DBG("ISI client error: %d", g_isi_client_error(client));
+		goto error;
+	}
+
+	dump_msg(msg, len);
+
+	if (len != 3) {
+		DBG("Wrong message length");
+		goto error;
+	}
+
+	c_data = gprs_find_context(gprs_data, msg[1]);
+	if (!c_data) {
+		DBG("Unknown PDP context: %d", msg[1]);
+		goto error;
+	}
+
+	if (msg[0] != GPDS_CONTEXT_CONFIGURE_RESP) {
+		DBG("Unexpected message ID: 0x%02x", msg[0]);
+		goto error;
+	}
+
+	if (msg[1] != c_data->token || msg[2] != GPDS_OK) {
+		DBG("Context configuration error");
+		goto error;
+	}
+
+	/* Next phase: configure the context */
+
+	connection_sm(gprs_data, c_data, GPRS_CONTEXT_CONFIGURED);
+
+	return true;
+
+error:
+
+	{
+		DECLARE_FAILURE(error);
+		handle_gprs_context_error(gprs_data, c_data, &error);
+	}
+	return false;
+}
+
+static bool context_configure_req(struct gprs_data *data, struct context_data *c_data)
+{
+	const unsigned char msg_header[] = {
+		GPDS_CONTEXT_CONFIGURE_REQ,
+		c_data->token, /* CID */
+		c_data->type, /* IPv4 or IPv6 */
+		0x00, /* GPDS_CONT_TYPE_NORMAL */
+		c_data->token, /* primary CID */
+		0x00, /* filler */
+		0x02  /* number of sub blocks */
+	};
+	unsigned char *msg;
+	GIsiRequest *req = NULL;
+	int apn_len, apn_block_len, msg_len, filler;
+
+	DBG("> context_configure_req (apn: '%s')", c_data->apn);
+
+	/* sanity checks */
+
+	apn_len = strlen(c_data->apn);
+	if (apn_len > 100)
+		goto error;
+
+	filler = (3 + apn_len) % 4; /* ( APN block header + APN length ) modulo 4 */
+	apn_block_len = 3 + apn_len + filler;
+
+	DBG("apn_len: %d, apn_block_len: %d, filler: %d", apn_len, apn_block_len, filler);
+
+	/* header length + APN block length + DNS block length */
+	msg_len = 7 + apn_block_len + 4;
+
+	msg = malloc(msg_len);
+
+	if (!msg)
+		goto error;
+
+	/* zero (for the end filler bytes) */
+	memset(msg, 0, msg_len);
+
+	/* APN sub block */
+
+	memcpy(msg, msg_header, 7);
+	msg[7] = 0x05; /* GPDS_APN_INFO */
+	msg[8] = apn_block_len;
+	msg[9] = apn_len;
+	memcpy(&msg[10], c_data->apn, apn_len);
+
+	/* DNS sub block */
+
+	msg[7+apn_block_len] = 0x90; /* GPDS_DNS_ADDRESS_INFO */
+	msg[7+apn_block_len+1] = 0x04; /* sub block length */
+	/* the two last bytes are filler */
+
+	DBG("The configuration request:");
+	dump_msg(msg, msg_len);
+
+	req = g_isi_request_make(data->client, msg, msg_len, GPDS_TIMEOUT,
+			context_configure_resp_cb, data);
+
+	free(msg);
+
+	if (req) {
+		return true;
+	}
+
+error:
+
+	return false;
+}
+
+static bool context_configure_ll_resp_cb(GIsiClient *client, const void *restrict data,
+		size_t len, uint16_t object, void *opaque)
+{
+	const unsigned char *msg = data;
+	struct context_data *c_data = NULL;
+	struct gprs_data *gprs_data = opaque;
+
+	DBG("> context_configure_ll_resp_cb");
+
+	/* sanity checks */
+
+	if(!msg) {
+		DBG("ISI client error: %d", g_isi_client_error(client));
+		goto error;
+	}
+
+	dump_msg(msg, len);
+
+	if (len != 3) {
+		DBG("Wrong message length");
+		goto error;
+	}
+
+	c_data = gprs_find_context(gprs_data, msg[1]);
+	if (!c_data) {
+		DBG("Unknown PDP context: %d", msg[1]);
+		goto error;
+	}
+
+	if (msg[0] != GPDS_LL_CONFIGURE_RESP) {
+		DBG("Unexpected message ID: 0x%02x", msg[0]);
+		goto error;
+	}
+
+	if (msg[1] != c_data->token || msg[2] != GPDS_OK) {
+		DBG("Context  local link configuration error");
+		goto error;
+	}
+
+	connection_sm(gprs_data, c_data, GPRS_CONTEXT_LOCAL_LINK_CONFIGURED);
+
+	return true;
+
+error:
+
+	{
+		DECLARE_FAILURE(error);
+		handle_gprs_context_error(gprs_data, c_data, &error);
+	}
+	return false;
+}
+
+static bool context_configure_ll_req(struct gprs_data *data, struct context_data *c_data)
+{
+	GIsiPipe *pipe = c_data->pipe;
+	const unsigned char msg[] = {
+		GPDS_LL_CONFIGURE_REQ,
+		c_data->token, /* context identifier */
+		g_isi_pipe_get_handle(pipe), /* Phonet pipe handle */
+		0x02 /* GPDS_LL_PLAIN */
+	};
+	GIsiRequest *req = NULL;
+
+	DBG("> context_configure_ll_req");
+
+	DBG("The local link configuration request:");
+	dump_msg(msg, sizeof(msg));
+
+	req = g_isi_request_make(data->client, msg, sizeof(msg), GPDS_TIMEOUT,
+			context_configure_ll_resp_cb, data);
+
+	if (req) {
+		return true;
+	}
+
+	return false;
+}
+static bool context_id_create_resp_cb(GIsiClient *client, const void *restrict data,
+		size_t len, uint16_t object, void *opaque)
+{
+	const unsigned char *msg = data;
+	struct context_data *c_data = NULL;
+	struct gprs_data *gprs_data = opaque;
+
+	DBG("> context_id_create_resp_cb");
+
+	/* sanity checks */
+
+	if(!msg) {
+		DBG("ISI client error: %d", g_isi_client_error(client));
+		goto error;
+	}
+
+	dump_msg(msg, len);
+
+	if (len != 3) {
+		DBG("Wrong message length");
+		goto error;
+	}
+
+	if (msg[0] != GPDS_CONTEXT_ID_CREATE_RESP) {
+		DBG("Unexpected message ID: 0x%02x", msg[0]);
+		goto error;
+	}
+
+	c_data = gprs_find_context(gprs_data, GPRS_CONTEXT_ID_INVALID);
+	if (!c_data) {
+		DBG("The just-created context was not found!");
+		goto error;
+	}
+
+	c_data->token = msg[1];
+
+	if (msg[2] != GPDS_OK) {
+		DBG("Context creation error");
+		goto error;
+	}
+
+	c_data->token = msg[1];
+	c_data->gpds_object = object;
+
+	/* Next phase: configure the context */
+
+	connection_sm(gprs_data, c_data, GPRS_CONTEXT_ID_REQUESTED);
+
+	return true;
+
+error:
+
+	{
+		DECLARE_FAILURE(error);
+		handle_gprs_context_error(gprs_data, c_data, &error);
+	}
+	return false;
+}
+
+static bool context_id_create_req(struct gprs_data *data, struct context_data *c_data)
+{
+	const unsigned char msg[] = {
+		GPDS_CONTEXT_ID_CREATE_REQ
+	};
+	GIsiRequest *req = NULL;
+
+	DBG("> context_id_create_req");
+
+	req = g_isi_request_make(data->client, msg, sizeof(msg), GPDS_TIMEOUT,
+			context_id_create_resp_cb, data);
+
+	if (req) {
+		return true;
+	}
+
+	return false;
+}
+
+static bool context_start_pipe(struct gprs_data *data, struct context_data *c_data)
+{
+	int ret = g_isi_pipe_start(c_data->pipe);
+
+	DBG("> context_start_pipe");
+
+	if (ret != 0) {
+		DBG("Pipe activation failed: %d", ret);
+		return false;
+	}
+
+	c_data->state = GPRS_CONTEXT_PIPE_STARTED;
+	return true;
+}
+
+struct pipe_data {
+	struct gprs_data *gprs_data;
+	ofono_gprs_context_id_t token;
+};
+
+static void context_create_pipe_error_cb(GIsiPipe *pipe)
+{
+	struct context_data *c_data = NULL;
+	struct pipe_data *pipe_data = g_isi_pipe_get_userdata(pipe);
+
+	DBG("Pipe creation error callback called, pipe: %p", pipe);
+
+	c_data = gprs_find_context(pipe_data->gprs_data, pipe_data->token);
+
+	if (c_data) {
+		DECLARE_FAILURE(error);
+		handle_gprs_context_error(pipe_data->gprs_data, c_data, &error);
+	}
+
+	return;
+}
+
+static void context_create_pipe_cb(GIsiPipe *pipe)
+{
+	struct context_data *c_data = NULL;
+	struct pipe_data *pipe_data = g_isi_pipe_get_userdata(pipe);
+
+	DBG("Pipe creation callback called, pipe: %p", pipe);
+
+	c_data = gprs_find_context(pipe_data->gprs_data, pipe_data->token);
+
+	if (!c_data)
+		return;
+
+	c_data->pipe = pipe; /* redundant? */
+
+	if (!c_data->pipe)
+		goto error;
+
+	c_data->pipe = pipe;
+
+	connection_sm(pipe_data->gprs_data, c_data, GPRS_CONTEXT_PIPE_CREATED);
+
+	return;
+
+error:
+	{
+		DECLARE_FAILURE(error);
+		handle_gprs_context_error(pipe_data->gprs_data, c_data, &error);
+	}
+	return;
+}
+
+static void context_create_pep_cb(GIsiPEP *pep, void *opaque)
+{
+	struct gprs_data *data = opaque;
+	struct context_data *c_data = NULL;
+	char buf[IF_NAMESIZE];
+
+	/* the pipe endpoint is now ready, let's get the interface name */
+
+	DBG("Pipe endpoint creation callback called, PEP: %p", pep);
+
+	c_data = gprs_find_context_by_pep(data, pep);
+
+	if (!c_data)
+		return;
+
+	ofono_gprs_context_interface_notify(data->manager, c_data->token,
+			g_isi_pep_get_ifname(pep, buf));
+
+	return;
+}
+
+#define PN_PEP_TYPE_GPRS 0x04
+
+static bool context_create_pipe(struct gprs_data *data, struct context_data *c_data)
+{
+	uint16_t local_object;
+	struct pipe_data *pipe_data;
+
+	c_data->pep = g_isi_pep_create(data->isi_modem, context_create_pep_cb, data);
+
+	DBG("Creating the pipe: endpoint %p", c_data->pep);
+
+	if (!c_data->pep)
+		goto error;
+
+	local_object = g_isi_pep_get_object(c_data->pep);
+
+	DBG("Creating the pipe: local object 0x%04X, remote object 0x%04X",
+			local_object, c_data->gpds_object);
+
+	c_data->pipe = g_isi_pipe_create(data->isi_modem,
+			context_create_pipe_cb,
+			local_object, c_data->gpds_object,
+			PN_PEP_TYPE_GPRS, PN_PEP_TYPE_GPRS);
+
+	if (!c_data->pipe)
+		goto error;
+
+	pipe_data = g_new0(struct pipe_data, 1);
+	pipe_data->token = c_data->token;
+	pipe_data->gprs_data = data;
+
+	g_isi_pipe_set_userdata(c_data->pipe, pipe_data);
+	g_isi_pipe_set_error_handler(c_data->pipe, context_create_pipe_error_cb);
+
+	DBG("Waiting for pipe to be ready.");
+
+	return true;
+
+error:
+
+	if (c_data->pep) {
+		g_isi_pep_destroy(c_data->pep);
+	}
+
+	return false;
+}
+
+#undef PN_PEP_TYPE_GPRS
+
+static bool get_ipv4_address(int addr_len, unsigned char *msg_addr,
+		struct in_addr *addr, char *char_addr)
+{
+	if (sizeof(struct in_addr) != addr_len) {
+		DBG("Unexpected IPv4 address length");
+		return false;
+	}
+
+	memcpy(addr, msg_addr, addr_len);
+	inet_ntop(AF_INET, addr, char_addr, INET_ADDRSTRLEN);
+
+	return true;
+}
+
+static bool get_ipv6_address(int addr_len, unsigned char *msg_addr,
+		struct in6_addr *addr, char *char_addr)
+{
+	if (sizeof(struct in6_addr) != addr_len) {
+		DBG("Unexpected IPv6 address length");
+		return false;
+	}
+
+	memcpy(addr, msg_addr, addr_len);
+	inet_ntop(AF_INET6, addr, char_addr, INET6_ADDRSTRLEN);
+
+	return true;
+}
+
+static void context_id_delete_ind (GIsiClient *client,
+		const void *restrict data, size_t len,
+		uint16_t object, void *opaque)
+{
+	const unsigned char *msg = data;
+	struct context_data *c_data = NULL;
+	struct gprs_data *gprs_data = opaque;
+
+	DBG("GPDS_CONTEXT_ID_DELETE_IND:");
+	dump_msg(msg, len);
+
+	c_data = gprs_find_context(gprs_data, msg[1]);
+	if (!c_data) {
+		DBG("Unknown PDP context: %d", msg[1]);
+		goto error;
+	}
+
+	connection_sm(gprs_data, c_data, GPRS_CONTEXT_FINISHED);
+
+	return;
+
+error:
+
+	return;
+}
+
+static void deactivating_ind (GIsiClient *client,
+		const void *restrict data, size_t len,
+		uint16_t object, void *opaque)
+{
+	const unsigned char *msg = data;
+	struct context_data *c_data = NULL;
+	struct gprs_data *gprs_data = opaque;
+
+	DBG("GPDS_CONTEXT_DEACTIVATING_IND:");
+	dump_msg(msg, len);
+
+	if (len != 2) {
+		DBG("Wrong message length");
+		goto error;
+	}
+
+	c_data = gprs_find_context(gprs_data, msg[1]);
+	if (!c_data) {
+		DBG("Unknown PDP context: %d", msg[1]);
+		goto error;
+	}
+
+	connection_sm(gprs_data, c_data, GPRS_CONTEXT_DEACTIVATING);
+
+	return;
+
+error:
+
+	return;
+}
+
+static void status_ind (GIsiClient *client,
+		const void *restrict data, size_t len,
+		uint16_t object, void *opaque)
+{
+	const unsigned char *msg = data;
+	struct context_data *c_data = NULL;
+	struct gprs_data *gprs_data = opaque;
+	unsigned int rx = 0, tx = 0;
+
+	DBG("GPDS_CONTEXT_STATUS_IND:");
+	dump_msg(msg, len);
+
+	if (len != 11) {
+		DBG("Wrong message length");
+		goto error;
+	}
+
+	c_data = gprs_find_context(gprs_data, msg[2]);
+	if (!c_data) {
+		DBG("Unknown PDP context: %d", msg[1]);
+		goto error;
+	}
+
+	memcpy(&tx, &msg[3], sizeof(int));
+	memcpy(&rx, &msg[7], sizeof(int));
+
+	tx = ntohl(tx);
+	rx = ntohl(rx);
+
+#if 0
+	tx = ntohl((int) msg[3]);
+	rx = ntohl((int) msg[7]);
+#endif
+
+	DBG("TX bytes: %i, RX bytes: %i", tx, rx);
+
+	ofono_gprs_context_tx_bytes_notify(gprs_data->manager, c_data->token, tx);
+	ofono_gprs_context_rx_bytes_notify(gprs_data->manager, c_data->token, rx);
+
+	return;
+
+error:
+
+	return;
+}
+
+static void deactivate_ind (GIsiClient *client,
+		const void *restrict data, size_t len,
+		uint16_t object, void *opaque)
+{
+	const unsigned char *msg = data;
+	struct context_data *c_data = NULL;
+	struct gprs_data *gprs_data = opaque;
+
+	DBG("GPDS_CONTEXT_DEACTIVATE_IND:");
+	dump_msg(msg, len);
+
+	if (len < 3) {
+		DBG("Wrong message length");
+		goto error;
+	}
+
+	c_data = gprs_find_context(gprs_data, msg[1]);
+	if (!c_data) {
+		DBG("Unknown PDP context: %d", msg[1]);
+		goto error;
+	}
+
+	connection_sm(gprs_data, c_data, GPRS_CONTEXT_DEACTIVATED);
+
+	return;
+
+error:
+
+	return;
+}
+
+static void activating_ind (GIsiClient *client,
+		const void *restrict data, size_t len,
+		uint16_t object, void *opaque)
+{
+	const unsigned char *msg = data;
+	struct context_data *c_data = NULL;
+	struct gprs_data *gprs_data = opaque;
+
+	DBG("GPDS_CONTEXT_ACTIVATING_IND:");
+	dump_msg(msg, len);
+
+	if (len < 3) {
+		DBG("Wrong message length");
+		goto error;
+	}
+
+	c_data = gprs_find_context(gprs_data, msg[1]);
+	if (!c_data) {
+		DBG("Unknown PDP context: %d", msg[1]);
+		goto error;
+	}
+
+	connection_sm(gprs_data, c_data, GPRS_CONTEXT_ACTIVATING);
+
+	return;
+
+error:
+
+	return;
+}
+
+static void activate_fail_ind (GIsiClient *client,
+		const void *restrict data, size_t len,
+		uint16_t object, void *opaque)
+{
+	const unsigned char *msg = data;
+#if 0
+	struct context_data *c_data = NULL;
+	struct gprs_data *gprs_data = opaque;
+#endif
+
+	DBG("GPDS_CONTEXT_ACTIVATE_FAIL_IND:");
+	dump_msg(msg, len);
+
+	/* the error is handled from activate_resp_cb, so let's not do it
+	 * here */
+
+#if 0
+	c_data = gprs_find_context(gprs_data, msg[1]);
+	if (!c_data) {
+		DBG("Unknown PDP context: %d", msg[1]);
+		goto error;
+	}
+
+	connection_sm(gprs_data, c_data, GPRS_CONTEXT_DEACTIVATED);
+
+	return;
+
+error:
+#endif
+
+	return;
+}
+
+static void activate_ind (GIsiClient *client,
+		const void *restrict data, size_t len,
+		uint16_t object, void *opaque)
+{
+	const unsigned char *msg = data;
+	struct context_data *c_data = NULL;
+	struct gprs_data *gprs_data = opaque;
+	unsigned char *subs[13];
+	int n_subs;
+
+	DBG("GPDS_CONTEXT_ACTIVATE_IND:");
+
+	dump_msg(msg, len);
+
+	if (len < 3) {
+		DBG("Wrong message length");
+		goto error;
+	}
+
+	c_data = gprs_find_context(gprs_data, msg[1]);
+	if (!c_data) {
+		DBG("Unknown PDP context: %d", msg[1]);
+		goto error;
+	}
+
+	/* parse the indication */
+
+	n_subs = msg[2];
+
+	if (parse_msg(3, subs, n_subs, (unsigned char *) msg, len)) {
+		int i;
+
+		for (i = 0; i < n_subs; i++) {
+			switch (*subs[i]) {
+				case 0x04: /* GPDS_PDP_ADDRESS_INFO */
+					{
+						int addr_len = *(subs[i]+3);
+
+						if (c_data->type == GPDS_PDP_TYPE_IPV6) {
+							get_ipv6_address(addr_len, subs[i]+4,
+									&c_data->pdp_addr.ipv6_addr, c_data->pdp_addr_s);
+						}
+						else {
+							get_ipv4_address(addr_len, subs[i]+4,
+									&c_data->pdp_addr.ipv4_addr, c_data->pdp_addr_s);
+						}
+						DBG("PDP address: %s", c_data->pdp_addr_s);
+
+						ofono_gprs_context_address_notify(gprs_data->manager,
+								c_data->token, c_data->pdp_addr_s);
+
+						break;
+					}
+				case 0x0D: /* GPDS_PDNS_ADDRESS_INFO */
+					{
+						int addr_len = *(subs[i]+3);
+
+						if (c_data->type == GPDS_PDP_TYPE_IPV6) {
+							get_ipv6_address(addr_len, subs[i]+4,
+									&c_data->pdns_addr.ipv6_addr, c_data->pdns_addr_s);
+						}
+						else {
+							get_ipv4_address(addr_len, subs[i]+4,
+									&c_data->pdns_addr.ipv4_addr, c_data->pdns_addr_s);
+						}
+
+						DBG("PDNS address: %s", c_data->pdns_addr_s);
+
+						ofono_gprs_context_pdns_address_notify(gprs_data->manager,
+								c_data->token, c_data->pdns_addr_s);
+
+						break;
+					}
+				case 0x0E: /* GPDS_SDNS_ADDRESS_INFO */
+					{
+						int addr_len = *(subs[i]+3);
+
+						if (c_data->type == GPDS_PDP_TYPE_IPV6) {
+							get_ipv6_address(addr_len, subs[i]+4, &c_data->sdns_addr.ipv6_addr, c_data->sdns_addr_s);
+						}
+						else {
+							get_ipv4_address(addr_len, subs[i]+4, &c_data->sdns_addr.ipv4_addr, c_data->sdns_addr_s);
+						}
+						DBG("SDNS address: %s", c_data->sdns_addr_s);
+
+						ofono_gprs_context_sdns_address_notify(gprs_data->manager,
+								c_data->token, c_data->sdns_addr_s);
+
+						break;
+					}
+				default:
+					break;
+
+			}
+		}
+	}
+
+	connection_sm(gprs_data, c_data, GPRS_CONTEXT_ACTIVATED);
+
+	return;
+
+error:
+
+	return;
+}
+
+
+static void connection_sm(struct gprs_data *data,
+		struct context_data *c_data,
+		enum gprs_context_state new_state)
+{
+	bool ret = true;
+	bool again = false;
+	enum gprs_context_state tmp_state;
+
+	/*
+	 * 1. Create a new (primary) PDP context.
+	 * 2. Create the data pipe (deactivated)
+	 * 3. Configure the context.
+	 * 4. Configure the local link.
+	 * 5. Activate the context.
+	 * 6. Activate the data pipe.
+	 *
+	 * ... data transfer ...
+	 *
+	 * 7. Deactivate the context.
+	 */
+
+	c_data->prev_state = c_data->state;
+	c_data->state = new_state;
+
+	DBG("Entering connection state machine -- current state %d", c_data->state);
+
+	switch (c_data->state) {
+		case GPRS_CONTEXT_INITED:
+			ret = context_id_create_req(data, c_data);
+			break;
+		case GPRS_CONTEXT_ID_REQUESTED:
+			{
+				struct isi_cb_data *cbd = c_data->cbd;
+				ofono_gprs_new_context_cb_t cb = cbd->cb;
+				struct ofono_error err;
+
+				/* tell the upper level that the call actually succeeded
+				 * so far */
+
+				err.type = OFONO_ERROR_TYPE_NO_ERROR;
+				err.error = 0;
+
+				cb(&err, c_data->token, cbd->data);
+				g_free(cbd);
+				c_data->cbd = NULL;
+
+				/* Now the upper level knows we have a context running.
+				 * Set it to be in "Connecting" state. */
+
+				ofono_gprs_context_state_notify(data->manager, c_data->token,
+						GPRS_CONTEXT_STATE_CONNECTING);
+
+				ret = context_create_pipe(data, c_data);
+			}
+			break;
+		case GPRS_CONTEXT_PIPE_CREATED:
+			ret = context_configure_req(data, c_data);
+			break;
+		case GPRS_CONTEXT_CONFIGURED:
+			ret = context_configure_ll_req(data, c_data);
+			break;
+		case GPRS_CONTEXT_LOCAL_LINK_CONFIGURED:
+
+			/* subscribe to the activation indications */
+			g_isi_subscribe(data->client,
+					GPDS_CONTEXT_ACTIVATING_IND, activating_ind, data);
+
+			ret = context_activate_req(data, c_data);
+			break;
+		case GPRS_CONTEXT_PIPE_STARTED:
+			ret = start_interface(data, c_data);
+			tmp_state = GPRS_CONTEXT_CONNECTED;
+			again = true;
+			break;
+		case GPRS_CONTEXT_ACTIVATING:
+			g_isi_subscribe(data->client,
+					GPDS_CONTEXT_DEACTIVATING_IND, deactivating_ind, data);
+			g_isi_subscribe(data->client,
+					GPDS_CONTEXT_ACTIVATE_IND, activate_ind, data);
+			g_isi_subscribe(data->client,
+					GPDS_CONTEXT_ACTIVATE_FAIL_IND, activate_fail_ind, data);
+			break;
+		case GPRS_CONTEXT_ACTIVATED:
+
+			/* subscribe to the deactivation indications */
+			g_isi_subscribe(data->client,
+					GPDS_CONTEXT_DEACTIVATE_IND, deactivate_ind, data);
+
+			/* request status when the connection goes away */
+			g_isi_subscribe(data->client,
+					GPDS_CONTEXT_STATUS_IND, status_ind, data);
+
+			/* unsubscribe from the activation indications */
+			g_isi_unsubscribe(data->client, GPDS_CONTEXT_ACTIVATE_FAIL_IND);
+			g_isi_unsubscribe(data->client, GPDS_CONTEXT_ACTIVATE_IND);
+			g_isi_unsubscribe(data->client, GPDS_CONTEXT_ACTIVATING_IND);
+
+			ret = context_start_pipe(data, c_data);
+			tmp_state = GPRS_CONTEXT_PIPE_STARTED;
+			again = true;
+			break;
+		case GPRS_CONTEXT_CONNECTED:
+			ofono_gprs_context_state_notify(data->manager, c_data->token,
+					GPRS_CONTEXT_STATE_CONNECTED);
+			break;
+		case GPRS_CONTEXT_DEACTIVATING:
+
+			/* unsubscribe from the deactivating indication */
+			g_isi_unsubscribe(data->client, GPDS_CONTEXT_DEACTIVATING_IND);
+			break;
+
+		case GPRS_CONTEXT_DEACTIVATED:
+
+			/* subscribe to the context deletion indications */
+			g_isi_subscribe(data->client,
+					GPDS_CONTEXT_ID_DELETE_IND, context_id_delete_ind, data);
+
+			/* unsubscribe from the deactivation indications */
+			g_isi_unsubscribe(data->client, GPDS_CONTEXT_DEACTIVATE_IND);
+
+			if (c_data->pipe) {
+				struct pipe_data *pipe_data = g_isi_pipe_get_userdata(c_data->pipe);
+				DBG("Destroying ISI pipe %p", c_data->pipe);
+				free(pipe_data);
+				g_isi_pipe_destroy(c_data->pipe);
+			}
+
+			if (c_data->pep) {
+				DBG("Destroying ISI pipe endpoint %p", c_data->pep);
+				g_isi_pep_destroy(c_data->pep);
+			}
+
+			break;
+		case GPRS_CONTEXT_FINISHED:
+			/* unsubscribe from the context deletion indications and
+			 * status indications */
+			g_isi_unsubscribe(data->client, GPDS_CONTEXT_ID_DELETE_IND);
+			g_isi_unsubscribe(data->client, GPDS_CONTEXT_STATUS_IND);
+
+			data->contexts = g_slist_remove(data->contexts, c_data);
+
+			ofono_gprs_context_state_notify(data->manager, c_data->token,
+					GPRS_CONTEXT_STATE_DISCONNECTED);
+
+			delete_cdata(c_data);
+			c_data = NULL;
+
+			break;
+	}
+
+	if (!ret) {
+		DECLARE_FAILURE(error);
+		handle_gprs_context_error(data, c_data, &error);
+	}
+	else if (again) {
+		/* synchronous call -- continue SM processing */
+		connection_sm(data, c_data, tmp_state);
+	}
+	return;
+}
+
+static unsigned char map_pdp_type(const char *type)
+{
+	if (strcmp(type, GPRS_TYPE_IPV4) == 0) {
+		return GPDS_PDP_TYPE_IPV4;
+	}
+	else if (strcmp(type, GPRS_TYPE_IPV6) == 0) {
+		return GPDS_PDP_TYPE_IPV6;
+	}
+
+	/* error case */
+	return GPDS_PDP_TYPE_DEFAULT;
+}
+
+static void isi_gprs_new_context(struct ofono_gprs *manager,
+		const char *apn,
+		const char *type,
+		const char *username,
+		const char *password,
+		ofono_gprs_new_context_cb_t cb,
+		void *user_data)
+{
+
+	/* The PDP context creation and connection has several phases, which
+	 * are detailed in connection_sm function.
+	 */
+
+	struct gprs_data *data = ofono_gprs_get_data(manager);
+	struct context_data *c_data = g_new0(struct context_data, 1);
+
+	if (!c_data)
+		goto error;
+
+	c_data->apn = g_strdup(apn);
+	c_data->type = map_pdp_type(type);
+	c_data->username = g_strdup(username);
+	c_data->password = g_strdup(password);
+	c_data->cbd = isi_cb_data_new(NULL, cb, user_data);
+#if 0
+	c_data->property_cbd = isi_cb_data_new(NULL, property_cb, user_data);
+#endif
+	c_data->token = GPRS_CONTEXT_ID_INVALID;
+
+	if (!c_data->apn || !c_data->username || !c_data->password || !c_data->cbd)
+		goto error;
+
+	/* add the context to our internal list of active contexts */
+	data->contexts = g_slist_prepend(data->contexts, c_data);
+
+	/* start the state machine */
+	connection_sm(data, c_data, GPRS_CONTEXT_INITED);
+
+	return;
+
+error:
+	{
+		DECLARE_FAILURE(e);
+		handle_gprs_context_error(data, c_data, &e);
+	}
+	return;
+}
+
+static bool context_deactivate_resp_cb(GIsiClient *client, const void *restrict data,
+		size_t len, uint16_t object, void *opaque)
+{
+	const unsigned char *msg = data;
+	struct gprs_data *gprs_data = opaque;
+	ofono_gprs_destroy_context_cb_t cb = NULL;
+	struct ofono_error err;
+	struct context_data *c_data = NULL;
+
+	/* sanity checks */
+
+	if(!msg) {
+		DBG("ISI client error: %d", g_isi_client_error(client));
+		goto error;
+	}
+
+	dump_msg(msg, len);
+
+	if (len != 3) {
+		DBG("Wrong message length");
+		goto error;
+	}
+
+	if (msg[0] != GPDS_CONTEXT_DEACTIVATE_RESP) {
+		DBG("Unexpected message ID: 0x%02x", msg[0]);
+		goto error;
+	}
+
+	c_data = gprs_find_context(gprs_data, msg[1]);
+	if (!c_data) {
+		DBG("Unknown PDP context: %d", msg[1]);
+		goto error;
+	}
+
+	cb = c_data->destroy_cbd->cb;
+
+	if (msg[2] != GPDS_OK) {
+		DBG("Disconnect failed");
+		goto error;
+	}
+
+	err.type = OFONO_ERROR_TYPE_NO_ERROR;
+	err.error = 0;
+
+	cb(&err, c_data->token, c_data->destroy_cbd->data);
+
+	g_free(c_data->destroy_cbd);
+
+	return true;
+
+error:
+	/* what to do if disconnect fails? */
+	{
+		DECLARE_FAILURE(e);
+		if (c_data) {
+			cb(&e, c_data->token, c_data->destroy_cbd->data);
+			g_free(c_data->destroy_cbd);
+		}
+	}
+	return false;
+}
+
+static void isi_gprs_destroy_context(struct ofono_gprs *manager,
+		ofono_gprs_context_id_t token,
+		ofono_gprs_destroy_context_cb_t cb, void *user_data)
+{
+	struct gprs_data *data = ofono_gprs_get_data(manager);
+	struct context_data *c_data = NULL;
+	struct isi_cb_data *cbd = isi_cb_data_new(NULL, cb, user_data);
+	const unsigned char msg[] = {
+		GPDS_CONTEXT_DEACTIVATE_REQ,
+		token
+	};
+	GIsiRequest *req = NULL;
+
+	DBG("Destroying context %d", token);
+
+	c_data = gprs_find_context(data, msg[1]);
+	if (!c_data) {
+		DBG("Unknown PDP context: %d", msg[1]);
+		goto error;
+	}
+
+	c_data->destroy_cbd = cbd;
+
+	req = g_isi_request_make(data->client, msg, sizeof(msg), GPDS_TIMEOUT,
+			context_deactivate_resp_cb, data);
+
+	if (req) {
+		return;
+	}
+
+error:
+
+	if (cbd)
+		g_free(cbd);
+
+	{
+		DECLARE_FAILURE(error);
+		cb(&error, token, user_data);
+	}
+	return;
+}
+
+static bool attach_resp_cb(GIsiClient *client, const void *restrict data,
+		size_t len, uint16_t object, void *opaque)
+{
+	const unsigned char *msg = data;
+	struct isi_cb_data *cbd = opaque;
+	ofono_gprs_generic_cb_t cb = cbd->cb;
+	struct ofono_error err;
+
+	/* sanity checks */
+
+	if(!msg) {
+		DBG("ISI client error: %d", g_isi_client_error(client));
+		goto error;
+	}
+
+	dump_msg(msg, len);
+
+	if (len != 4) {
+		DBG("Wrong message length");
+		goto error;
+	}
+
+	if (msg[0] != GPDS_ATTACH_RESP) {
+		DBG("Unexpected message ID: 0x%02x", msg[0]);
+		goto error;
+	}
+
+	if (msg[1] != GPDS_OK) {
+		DBG("Attach failed");
+		goto error;
+	}
+
+	err.type = OFONO_ERROR_TYPE_NO_ERROR;
+	err.error = 0;
+
+	cb(&err, cbd->data);
+
+	g_free(cbd);
+
+	return true;
+
+error:
+	{
+		DECLARE_FAILURE(e);
+		cb(&e, cbd->data);
+	}
+	return false;
+}
+
+static void isi_gprs_attach(struct ofono_gprs *manager,
+		ofono_gprs_generic_cb_t cb, void *user_data)
+{
+	struct gprs_data *data = ofono_gprs_get_data(manager);
+	struct isi_cb_data *cbd = isi_cb_data_new(NULL, cb, user_data);
+	const unsigned char msg[] = {
+		GPDS_ATTACH_REQ,
+		0x00  /* GPDS_FOLLOW_OFF */
+	};
+	GIsiRequest *req = NULL;
+
+	if (!cbd)
+		goto error;
+
+	req = g_isi_request_make(data->client, msg, sizeof(msg), GPDS_TIMEOUT,
+			attach_resp_cb, cbd);
+
+	if (req) {
+		return;
+	}
+
+error:
+	if (cbd)
+		g_free(cbd);
+
+	{
+		DECLARE_FAILURE(error);
+		cb(&error, data);
+	}
+	return;
+}
+
+static bool detach_resp_cb(GIsiClient *client, const void *restrict data,
+		size_t len, uint16_t object, void *opaque)
+{
+	const unsigned char *msg = data;
+	struct isi_cb_data *cbd = opaque;
+	ofono_gprs_generic_cb_t cb = cbd->cb;
+	struct ofono_error err;
+
+	/* sanity checks */
+
+	if(!msg) {
+		DBG("ISI client error: %d", g_isi_client_error(client));
+		goto error;
+	}
+
+	dump_msg(msg, len);
+
+	if (len != 3) {
+		DBG("Wrong message length");
+		goto error;
+	}
+
+	if (msg[0] != GPDS_DETACH_RESP) {
+		DBG("Unexpected message ID: 0x%02x", msg[0]);
+		goto error;
+	}
+
+	if (msg[1] != GPDS_OK) {
+		DBG("Attach failed");
+		goto error;
+	}
+
+	err.type = OFONO_ERROR_TYPE_NO_ERROR;
+	err.error = 0;
+
+	cb(&err, cbd->data);
+
+	g_free(cbd);
+
+	return true;
+
+error:
+	{
+		DECLARE_FAILURE(e);
+		cb(&e, cbd->data);
+	}
+	return false;
+}
+
+static void isi_gprs_detach(struct ofono_gprs *manager,
+		ofono_gprs_generic_cb_t cb, void *user_data)
+{
+	struct gprs_data *data = ofono_gprs_get_data(manager);
+	struct isi_cb_data *cbd = isi_cb_data_new(NULL, cb, user_data);
+	const unsigned char msg[] = {
+		GPDS_DETACH_REQ,
+		0x00, /* filler */
+		0x00  /* number of sub blocks */
+	};
+	GIsiRequest *req = NULL;
+
+	if (!cbd)
+		goto error;
+
+	req = g_isi_request_make(data->client, msg, sizeof(msg), GPDS_TIMEOUT,
+			detach_resp_cb, cbd);
+
+	if (req) {
+		return;
+	}
+
+error:
+	if (cbd)
+		g_free(cbd);
+
+	{
+		DECLARE_FAILURE(error);
+		cb(&error, data);
+	}
+
+	return;
+}
+
+static gboolean isi_gprs_register(gpointer user)
+{
+	struct ofono_gprs *gprs = user;
+
+	DBG("> isi_gprs_register");
+
+	ofono_gprs_register(gprs);
+
+	/* run only once */
+
+	return FALSE;
+}
+
+static int isi_gprs_probe(struct ofono_gprs *gprs)
+{
+	GIsiModem *idx = ofono_gprs_get_data(gprs);
+	struct gprs_data *data = g_try_new0(struct gprs_data, 1);
+
+	DBG("> isi_gprs_probe");
+
+	if (!data) {
+		DBG("Failed to allocate GPRS data");
+		return -ENOMEM;
+	}
+
+	data->isi_modem = idx;
+	data->client = g_isi_client_create(idx, PN_GPDS);
+	if (!data->client) {
+		DBG("Failed to crate ISI client for GPRS");
+		return -ENOMEM;
+	}
+
+	/* the manager and struct gprs_data are two sides of a coin */
+	data->manager = gprs;
+
+	ofono_gprs_set_data(gprs, data);
+
+	g_idle_add(isi_gprs_register, gprs);
+
+	return 0;
+}
+
+static int isi_gprs_remove(struct ofono_gprs *gprs)
+{
+	struct gprs_data *data = ofono_gprs_get_data(gprs);
+
+	if (data) {
+		g_isi_client_destroy(data->client);
+		g_free(data);
+	}
+
+	return 0;
+}
+
+static struct ofono_gprs_driver driver = {
+	.name			        = "isi",
+	.probe			        = isi_gprs_probe,
+	.remove			        = isi_gprs_remove,
+	.new_context		    = isi_gprs_new_context,
+	.destroy_context	    = isi_gprs_destroy_context,
+	.attach				    = isi_gprs_attach,
+	.detach				    = isi_gprs_detach,
+};
+
+void isi_gprs_init()
+{
+	ofono_gprs_driver_register(&driver);
+}
+
+void isi_gprs_exit()
+{
+	ofono_gprs_driver_unregister(&driver);
+}
+
+/* vim: ts=4:noexpandtab:
+*/
+
diff --git a/drivers/isimodem/isi.h b/drivers/isimodem/isi.h
index 89ed534..bb73f12 100644
--- a/drivers/isimodem/isi.h
+++ b/drivers/isimodem/isi.h
@@ -105,3 +105,7 @@ extern void isi_call_barring_exit();
 
 extern void isi_call_meter_init();
 extern void isi_call_meter_exit();
+
+extern void isi_gprs_init();
+extern void isi_gprs_exit();
+
diff --git a/drivers/isimodem/isimodem.c b/drivers/isimodem/isimodem.c
index 3f3d179..8d032be 100644
--- a/drivers/isimodem/isimodem.c
+++ b/drivers/isimodem/isimodem.c
@@ -49,6 +49,7 @@
 #include <ofono/call-settings.h>
 #include <ofono/call-barring.h>
 #include <ofono/call-meter.h>
+#include <ofono/gprs.h>
 
 #include "isi.h"
 
@@ -161,6 +162,7 @@ static int isi_modem_populate(struct ofono_modem *modem)
 	ofono_call_settings_create(isi->modem, "isi", isi->idx);
 	ofono_call_barring_create(isi->modem, "isi", isi->idx);
 	ofono_call_meter_create(isi->modem, "isi", isi->idx);
+	ofono_gprs_create(isi->modem, "isi", isi->idx);
 
 	return 0;
 }
@@ -190,6 +192,7 @@ static int isimodem_init(void)
 	isi_call_settings_init();
 	isi_call_barring_init();
 	isi_call_meter_init();
+	isi_gprs_init();
 
 	ofono_modem_driver_register(&driver);
 
@@ -229,6 +232,7 @@ static void isimodem_exit(void)
 	isi_call_settings_exit();
 	isi_call_barring_exit();
 	isi_call_meter_exit();
+	isi_gprs_exit();
 }
 
 OFONO_PLUGIN_DEFINE(isimodem, "PhoNet / ISI modem driver", VERSION,
-- 
1.6.0.4


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #5: 0004-Basic-tests-for-GPRS-D-Bus-API.patch --]
[-- Type: text/x-patch, Size: 1363 bytes --]

From fedc35d4e10d063351ce23025c72742d5f095a55 Mon Sep 17 00:00:00 2001
From: Ismo Puustinen <ismo.h.puustinen@nokia.com>
Date: Mon, 31 Aug 2009 14:35:07 +0300
Subject: [PATCH] Basic tests for GPRS D-Bus API

---
 test/test-gprs |   39 +++++++++++++++++++++++++++++++++++++++
 1 files changed, 39 insertions(+), 0 deletions(-)
 create mode 100755 test/test-gprs

diff --git a/test/test-gprs b/test/test-gprs
new file mode 100755
index 0000000..0e48f3c
--- /dev/null
+++ b/test/test-gprs
@@ -0,0 +1,39 @@
+#!/usr/bin/python
+
+import gobject
+
+import dbus
+
+if __name__ == "__main__":
+
+	bus = dbus.SystemBus()
+
+	manager = dbus.Interface(bus.get_object('org.ofono', '/'),
+							'org.ofono.Manager')
+
+	try:
+		modems = manager.GetProperties()['Modems']
+	except dbus.DBusException, e:
+		print "Unable to get the Modems property %s" % e
+
+	manager = dbus.Interface(bus.get_object('org.ofono', modems[0]),
+				'org.ofono.GprsManager')
+
+	# TODO: get manager properties
+
+	manager.Attach()
+
+	variants = dbus.Dictionary(signature='sv')
+
+	path = manager.Connect('internet', 'IPv4', '', '', variants, timeout=100)
+
+	print "New GPRS context created, path " + path
+	context = dbus.Interface(bus.get_object('org.ofono', path), 'org.ofono.GprsContext')
+
+	# TODO: get context properties
+
+	manager.Disconnect(path)
+
+	manager.Detach()
+
+
-- 
1.6.0.4


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

* Re: GPRS support for Ofono
  2009-09-01 11:09 GPRS support for Ofono Ismo Puustinen
@ 2009-09-01 19:02 ` Jean-Christian de Rivaz
  2009-09-01 19:25   ` =?unknown-8bit?q?R=C3=A9mi?= Denis-Courmont
  2009-09-01 19:27   ` Christensen, Mikkel
  2009-09-01 21:36 ` Denis Kenzior
  1 sibling, 2 replies; 42+ messages in thread
From: Jean-Christian de Rivaz @ 2009-09-01 19:02 UTC (permalink / raw)
  To: ofono

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

Ismo Puustinen a écrit :
> I started working on Ofono GPRS support.

Hello,

With GPRS support, Ofono become very interesting!

I failed to understand how the "isi_gprs" code in your patch communicate
with a PPP stack. For example, I currently use a project where the APN
is configured and a connection open with it. Then a pppd process is
started to establish the IP link. It seem that you make this in a other
(and certainly better) way, but I missed the big picture.

Best Regards,

Jean-Christian de Rivaz

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

* Re: GPRS support for Ofono
  2009-09-01 19:02 ` Jean-Christian de Rivaz
@ 2009-09-01 19:25   ` =?unknown-8bit?q?R=C3=A9mi?= Denis-Courmont
  2009-09-01 20:17     ` Jean-Christian de Rivaz
  2009-09-01 19:27   ` Christensen, Mikkel
  1 sibling, 1 reply; 42+ messages in thread
From: =?unknown-8bit?q?R=C3=A9mi?= Denis-Courmont @ 2009-09-01 19:25 UTC (permalink / raw)
  To: ofono

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

Le mardi 1 septembre 2009 22:02:43 Jean-Christian de Rivaz, vous avez écrit :
> With GPRS support, Ofono become very interesting!
>
> I failed to understand how the "isi_gprs" code in your patch communicate
> with a PPP stack.

That would be because it does NOT use a PPP stack.

ISI modems have their own IP path using a dedicated kernel driver 
(net/phonet/pep-gprs.c in Linux 2.6.28 amd later). There is no point in using 
the PPP line discipline.

-- 
Rémi Denis-Courmont
http://www.remlab.net/

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

* RE: GPRS support for Ofono
  2009-09-01 19:02 ` Jean-Christian de Rivaz
  2009-09-01 19:25   ` =?unknown-8bit?q?R=C3=A9mi?= Denis-Courmont
@ 2009-09-01 19:27   ` Christensen, Mikkel
  1 sibling, 0 replies; 42+ messages in thread
From: Christensen, Mikkel @ 2009-09-01 19:27 UTC (permalink / raw)
  To: ofono

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

On Tue, Sep 01, 2009 at 14:02:43, Jean-Christian de Rivaz wrote:
> I failed to understand how the "isi_gprs" code in your patch 
> communicate with a PPP stack. For example, I currently use a project 
> where the APN is configured and a connection open with it. Then a pppd 
> process is started to establish the IP link. It seem that you make 
> this in a other (and certainly
> better) way, but I missed the big picture.

The best way to do this is without PPP and this is probably what Ismo is doing. You would just create a new net_device like "eth0" and hide all the ISI and cellular messaging behind that interface providing a clean IP network device.

Best regards,
 Mikkel Christensen 

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

* Re: GPRS support for Ofono
  2009-09-01 19:25   ` =?unknown-8bit?q?R=C3=A9mi?= Denis-Courmont
@ 2009-09-01 20:17     ` Jean-Christian de Rivaz
  2009-09-01 20:26       ` =?unknown-8bit?q?R=C3=A9mi?= Denis-Courmont
  2009-09-01 20:30       ` Christensen, Mikkel
  0 siblings, 2 replies; 42+ messages in thread
From: Jean-Christian de Rivaz @ 2009-09-01 20:17 UTC (permalink / raw)
  To: ofono

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

Rémi Denis-Courmont a écrit :
> Le mardi 1 septembre 2009 22:02:43 Jean-Christian de Rivaz, vous avez écrit :
>> With GPRS support, Ofono become very interesting!
>>
>> I failed to understand how the "isi_gprs" code in your patch communicate
>> with a PPP stack.
> 
> That would be because it does NOT use a PPP stack.
> 
> ISI modems have their own IP path using a dedicated kernel driver 
> (net/phonet/pep-gprs.c in Linux 2.6.28 amd later). There is no point in using 
> the PPP line discipline.

Thanks for the explanation. I will start learning how phonet works. But
I expect there exists a PPP stack somewhere in phonet because the modem
I use don't have one. And I don't think it's possible to have a IP link
over GPRS without the PPP protocol between them.

Jean-Christian de Rivaz

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

* Re: GPRS support for Ofono
  2009-09-01 20:17     ` Jean-Christian de Rivaz
@ 2009-09-01 20:26       ` =?unknown-8bit?q?R=C3=A9mi?= Denis-Courmont
  2009-09-01 20:30       ` Christensen, Mikkel
  1 sibling, 0 replies; 42+ messages in thread
From: =?unknown-8bit?q?R=C3=A9mi?= Denis-Courmont @ 2009-09-01 20:26 UTC (permalink / raw)
  To: ofono

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

Le mardi 1 septembre 2009 23:17:36 Jean-Christian de Rivaz, vous avez écrit :
> Thanks for the explanation. I will start learning how phonet works. But
> I expect there exists a PPP stack somewhere in phonet because the modem
> I use don't have one.

ISI modems have a PPP "server-side" implementation to handle USB CDC ACM and 
BlueTooth DUN. But there is only one instance per modem, so we reserve it for 
the dumb Windows PC that we may be connected to ;)

> And I don't think it's possible to have a IP link
> over GPRS without the PPP protocol between them.

It might be possible in the standard, but I have not found any network 
offering such a PP over GPRS data service.

-- 
Rémi Denis-Courmont
http://www.remlab.net/

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

* RE: GPRS support for Ofono
  2009-09-01 20:17     ` Jean-Christian de Rivaz
  2009-09-01 20:26       ` =?unknown-8bit?q?R=C3=A9mi?= Denis-Courmont
@ 2009-09-01 20:30       ` Christensen, Mikkel
  1 sibling, 0 replies; 42+ messages in thread
From: Christensen, Mikkel @ 2009-09-01 20:30 UTC (permalink / raw)
  To: ofono

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

On Tue, Sep 01, 2009 at 15:17:36, Jean-Christian de Rivaz wrote:
> Thanks for the explanation. I will start learning how phonet works. 
> But I expect there exists a PPP stack somewhere in phonet because the 
> modem I use don't have one. And I don't think it's possible to have a 
> IP link over GPRS without the PPP protocol between them.

On most modern modems there is no need to have a PPP link between the Application Processor (AP) and the modem. They will often be able to transmit IP traffic directly to the AP.

Hence there is no PPP stack in phonet. If your modem does not support raw IP messaging (or any other datagram service) to the AP you will probably be stuck with good old PPP.




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

* Re: GPRS support for Ofono
  2009-09-01 11:09 GPRS support for Ofono Ismo Puustinen
  2009-09-01 19:02 ` Jean-Christian de Rivaz
@ 2009-09-01 21:36 ` Denis Kenzior
  2009-09-01 22:42   ` Marcel Holtmann
  2009-09-02 11:30   ` Ismo Puustinen
  1 sibling, 2 replies; 42+ messages in thread
From: Denis Kenzior @ 2009-09-01 21:36 UTC (permalink / raw)
  To: ofono

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

Everyone,

So as it happens I had also been brainstorming a GPRS API for the last several 
days.  And somewhat spontaneously a GPRS api discussion happened on IRC 
between myself, Marcel and Ismo.  The following GPRS API proposal is a result 
of this discussion.  I'd like all interested to comment.  What needs 
improvement? What is missing?  What should be removed?

Please note that Secondary PDP contexts, Traffic Filters and Network Activated 
(Incoming) PDP contexts are not covered in this proposal.  These features are 
not commonly used and none of us have real experience with them yet.  However, 
we considered these features and have left room in the APIs for further 
expansion.

Data Connection Manager hierarchy
=================

Service		org.ofono
Interface	org.ofono.DataConnectionManager
Object path	[variable]

Methods		dict GetProperties()

			Returns all global system properties. See the
			properties section for available properties.

			Possible Errors: [service].Error.InvalidArguments

		void SetProperty(string property, variant value)

			Sets the property to a desired value

			Possible Errors: [service].Error.InvalidArguments
					 [service].Error.InvalidFormat
					 [service].Error.Failed

		void DeactivateAll()

			Deactivates all active contexts.

		object CreateContext()

			Creates a new Primary context.  Returns the object
			path of the created context.

		object RemoveContext()

			Removes a primary context.  All secondary contexts, if
			any, associated with the primary context are also
			removed.

Signals		PropertyChanged(string property, variant value)

			This signal indicates a changed value of the given
			property.

Properties	array{object} PrimaryContexts [readonly]

			List of all primary contexts objects.

		boolean Attached [readonly]

			Contains whether the Packet Radio Service is attached.
			The attach state might change dynamically based on
			availability of network resources.  If this value
			changes to false, the user can assume that all
			contexts have been deactivated.

			If the modem is detached, certain features will not
			be available, e.g. receiving SMS over packet radio
			or network initiated PDP activation.

		boolean RoamingAllowed [readwrite]

			Contains whether data roaming is allowed.  In the off
			setting, if the packet radio registration state
			indicates that the modem is roaming, oFono will
			automatically detach and no further connection
			establishment will be possible.

		boolean Powered [readwrite]

			Controls whether packet radio use is allowed. Setting
			this value to off detaches the modem from the
			Packet Domain network.
			
		string Status [readonly]

			The current packet radio registration status of a modem.

			The possible values are: 
				"unregistered"  Not registered to any network
				"registered"    Registered to home network
				"searching"     Not registered, but searching
				"denied"        Registration has been denied
				"unknown"       Status is unknown
				"roaming"       Registered, but roaming

		uint16 LocationAreaCode [readonly, optional]

			Contains the current location area code.

		uint32 CellId [readonly, optional]

			Contains the current network cell id.

		string Technology [readonly, optional]

			Contains the technology of the current network.

			The possible values are: "GSM", "GSMCompact", "UTRAN",
						 "GSM+EGPS", "UTRAN+HSDPA",
						 "UTRAN+HSUPA",
						 "UTRAN+HSDPA+HSUPA",
						 "E-UTRAN"

Primary Data Context hierarchy
=================

Service		org.ofono
Interface	org.ofono.PrimaryDataContext
Object path	[variable]

Methods		dict GetProperties()
			Returns all properties for the context object.

			Possible Errors: [service].Error.InvalidArguments

		void SetProperty(string property, variant value)

			Sets the property to a desired value

			Possible Errors: [service].Error.InvalidArguments
					 [service].Error.InvalidFormat
					 [service].Error.Failed

Signals		PropertyChanged(string property, variant value)

			This signal indicates a changed value of the given
			property.

Properties	boolean Activated [readwrite]

			Holds whether the context is activated.  This value
			can be set to activate / deactivate the context.

		string AccessPointName [readwrite]

			Holds the name of the access point.  This is
			abbreviated as APN.  This value cannot be changed when
			the context is active.

		string Username [readwrite]

			Holds the username to be used for authentication
			purposes.  This value cannot be changed when the
			context is active.

		string Password [readwrite]

			Holds the password to be used for authentication
			purposes.  This value cannot be changed when the
			context is active.

		string Interface [readonly, optional]

			Holds the interface of the network interface created
			by this context (e.g. "ppp0")

		array{string} DomainNameServers [readonly, optional]

			Holds the list of domain name servers for this
			context.


Regards,
-Denis

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

* Re: GPRS support for Ofono
  2009-09-01 21:36 ` Denis Kenzior
@ 2009-09-01 22:42   ` Marcel Holtmann
  2009-09-01 22:50     ` Denis Kenzior
  2009-09-02  6:39     ` =?unknown-8bit?q?R=C3=A9mi?= Denis-Courmont
  2009-09-02 11:30   ` Ismo Puustinen
  1 sibling, 2 replies; 42+ messages in thread
From: Marcel Holtmann @ 2009-09-01 22:42 UTC (permalink / raw)
  To: ofono

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

Hi Denis,

> So as it happens I had also been brainstorming a GPRS API for the last several 
> days.  And somewhat spontaneously a GPRS api discussion happened on IRC 
> between myself, Marcel and Ismo.  The following GPRS API proposal is a result 
> of this discussion.  I'd like all interested to comment.  What needs 
> improvement? What is missing?  What should be removed?
> 
> Please note that Secondary PDP contexts, Traffic Filters and Network Activated 
> (Incoming) PDP contexts are not covered in this proposal.  These features are 
> not commonly used and none of us have real experience with them yet.  However, 
> we considered these features and have left room in the APIs for further 
> expansion.
> 
> Data Connection Manager hierarchy
> =================
> 
> Service		org.ofono
> Interface	org.ofono.DataConnectionManager

I think this should be GPRSManager or something to clearly separate
between GRPS connections and actual data connection,

> Object path	[variable]
> 
> Methods		dict GetProperties()
> 
> 			Returns all global system properties. See the
> 			properties section for available properties.
> 
> 			Possible Errors: [service].Error.InvalidArguments
> 
> 		void SetProperty(string property, variant value)
> 
> 			Sets the property to a desired value
> 
> 			Possible Errors: [service].Error.InvalidArguments
> 					 [service].Error.InvalidFormat
> 					 [service].Error.Failed
> 
> 		void DeactivateAll()
> 
> 			Deactivates all active contexts.
> 
> 		object CreateContext()
> 
> 			Creates a new Primary context.  Returns the object
> 			path of the created context.
> 
> 		object RemoveContext()
> 
> 			Removes a primary context.  All secondary contexts, if
> 			any, associated with the primary context are also
> 			removed.

I assume this is void RemoveContext(object context)

> Signals		PropertyChanged(string property, variant value)
> 
> 			This signal indicates a changed value of the given
> 			property.
> 
> Properties	array{object} PrimaryContexts [readonly]
> 
> 			List of all primary contexts objects.

Calling this just Contexts seems to more reasonable. See comment about
interface name below.

> 		boolean Attached [readonly]
> 
> 			Contains whether the Packet Radio Service is attached.
> 			The attach state might change dynamically based on
> 			availability of network resources.  If this value
> 			changes to false, the user can assume that all
> 			contexts have been deactivated.
> 
> 			If the modem is detached, certain features will not
> 			be available, e.g. receiving SMS over packet radio
> 			or network initiated PDP activation.
> 
> 		boolean RoamingAllowed [readwrite]
> 
> 			Contains whether data roaming is allowed.  In the off
> 			setting, if the packet radio registration state
> 			indicates that the modem is roaming, oFono will
> 			automatically detach and no further connection
> 			establishment will be possible.
> 
> 		boolean Powered [readwrite]
> 
> 			Controls whether packet radio use is allowed. Setting
> 			this value to off detaches the modem from the
> 			Packet Domain network.
> 			
> 		string Status [readonly]
> 
> 			The current packet radio registration status of a modem.
> 
> 			The possible values are: 
> 				"unregistered"  Not registered to any network
> 				"registered"    Registered to home network
> 				"searching"     Not registered, but searching
> 				"denied"        Registration has been denied
> 				"unknown"       Status is unknown
> 				"roaming"       Registered, but roaming
> 
> 		uint16 LocationAreaCode [readonly, optional]
> 
> 			Contains the current location area code.
> 
> 		uint32 CellId [readonly, optional]
> 
> 			Contains the current network cell id.
> 
> 		string Technology [readonly, optional]
> 
> 			Contains the technology of the current network.
> 
> 			The possible values are: "GSM", "GSMCompact", "UTRAN",
> 						 "GSM+EGPS", "UTRAN+HSDPA",
> 						 "UTRAN+HSUPA",
> 						 "UTRAN+HSDPA+HSUPA",
> 						 "E-UTRAN"
> 
> Primary Data Context hierarchy
> =================
> 
> Service		org.ofono
> Interface	org.ofono.PrimaryDataContext

I would prefer if we just call this GRPSContext and explain that this is
for the primary context. The confusion between primary context and
secondary context is some GSM specific non-sense.

> Object path	[variable]
> 
> Methods		dict GetProperties()
> 			Returns all properties for the context object.
> 
> 			Possible Errors: [service].Error.InvalidArguments
> 
> 		void SetProperty(string property, variant value)
> 
> 			Sets the property to a desired value
> 
> 			Possible Errors: [service].Error.InvalidArguments
> 					 [service].Error.InvalidFormat
> 					 [service].Error.Failed
> 
> Signals		PropertyChanged(string property, variant value)
> 
> 			This signal indicates a changed value of the given
> 			property.
> 
> Properties	boolean Activated [readwrite]
> 
> 			Holds whether the context is activated.  This value
> 			can be set to activate / deactivate the context.
> 
> 		string AccessPointName [readwrite]
> 
> 			Holds the name of the access point.  This is
> 			abbreviated as APN.  This value cannot be changed when
> 			the context is active.
> 
> 		string Username [readwrite]
> 
> 			Holds the username to be used for authentication
> 			purposes.  This value cannot be changed when the
> 			context is active.
> 
> 		string Password [readwrite]
> 
> 			Holds the password to be used for authentication
> 			purposes.  This value cannot be changed when the
> 			context is active.
> 
> 		string Interface [readonly, optional]
> 
> 			Holds the interface of the network interface created
> 			by this context (e.g. "ppp0")

Our current assumption is that the basic setup of IP address, netmask
and broadcast are done by oFono. Only routing and DNS are up to other
programs like ConnMan for example.

> 		array{string} DomainNameServers [readonly, optional]
> 
> 			Holds the list of domain name servers for this
> 			context.

What about the gateway value. In theory we can just route it to the
interface, but if the device fakes a real Ethernet interface and the
gateway is in a different subnet we need a proper host route first.

Regards

Marcel



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

* Re: GPRS support for Ofono
  2009-09-01 22:42   ` Marcel Holtmann
@ 2009-09-01 22:50     ` Denis Kenzior
  2009-09-02  6:39     ` =?unknown-8bit?q?R=C3=A9mi?= Denis-Courmont
  1 sibling, 0 replies; 42+ messages in thread
From: Denis Kenzior @ 2009-09-01 22:50 UTC (permalink / raw)
  To: ofono

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

Hi Marcel,

> > Service		org.ofono
> > Interface	org.ofono.DataConnectionManager
>
> I think this should be GPRSManager or something to clearly separate
> between GRPS connections and actual data connection,

Two reasons for this:
	- Purpose of DataConnectionManager is easier to understand for people new to 
GSM.  Whereas GPRSManager really doesn't tell them anything.  Everywhere else 
we tend to use more easily understood terminology than what is used in the 
specifications.

	- GPRS is not easily Carmel-cased.  E.g. we'd have to name it GprsManager.

> > 		object RemoveContext()
> >
> > 			Removes a primary context.  All secondary contexts, if
> > 			any, associated with the primary context are also
> > 			removed.
>
> I assume this is void RemoveContext(object context)

You're absolutely correct.

> > Properties	array{object} PrimaryContexts [readonly]
> >
> > 			List of all primary contexts objects.
>
> Calling this just Contexts seems to more reasonable. See comment about
> interface name below.

That sounds fine to me.

> > Primary Data Context hierarchy
> > =================
> >
> > Service		org.ofono
> > Interface	org.ofono.PrimaryDataContext
>
> I would prefer if we just call this GRPSContext and explain that this is
> for the primary context. The confusion between primary context and
> secondary context is some GSM specific non-sense.

Should we just simply name this 'Context' and name the secondary pdp context 
'SubContext'?

> > 		array{string} DomainNameServers [readonly, optional]
> >
> > 			Holds the list of domain name servers for this
> > 			context.
>
> What about the gateway value. In theory we can just route it to the
> interface, but if the device fakes a real Ethernet interface and the
> gateway is in a different subnet we need a proper host route first.

Yes, this one needs to be added.  Good catch.

Regards,
-Denis

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

* Re: GPRS support for Ofono
  2009-09-01 22:42   ` Marcel Holtmann
  2009-09-01 22:50     ` Denis Kenzior
@ 2009-09-02  6:39     ` =?unknown-8bit?q?R=C3=A9mi?= Denis-Courmont
  2009-09-02  9:16       ` Marcel Holtmann
  1 sibling, 1 reply; 42+ messages in thread
From: =?unknown-8bit?q?R=C3=A9mi?= Denis-Courmont @ 2009-09-02  6:39 UTC (permalink / raw)
  To: ofono

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


On Tue, 01 Sep 2009 15:42:40 -0700, Marcel Holtmann <marcel@holtmann.org>
wrote:

> Our current assumption is that the basic setup of IP address, netmask
> and broadcast are done by oFono. Only routing and DNS are up to other
> programs like ConnMan for example.

WHAAAAAAAAAAT? No way. There is just no way.

We need to support letting the calling program configure the routing
parameters manually. For instance, if we want to connect to multiple
primary access points, it simply won't work if Ofono configures everything.
Instead, we need to either setup source routing or separate network
name-spaces. Ofono does not know what the caller intends to do with the APN
(and should not need to), so it cannot configure IP parameters. Besides, it
makes very little if any sense to configure IP parameters but not DNS.

-- 
Rémi Denis-Courmont


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

* Re: GPRS support for Ofono
  2009-09-02  6:39     ` =?unknown-8bit?q?R=C3=A9mi?= Denis-Courmont
@ 2009-09-02  9:16       ` Marcel Holtmann
  2009-09-02  9:22         ` =?unknown-8bit?q?R=C3=A9mi?= Denis-Courmont
  0 siblings, 1 reply; 42+ messages in thread
From: Marcel Holtmann @ 2009-09-02  9:16 UTC (permalink / raw)
  To: ofono

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

Hi Remi,

> > Our current assumption is that the basic setup of IP address, netmask
> > and broadcast are done by oFono. Only routing and DNS are up to other
> > programs like ConnMan for example.
> 
> WHAAAAAAAAAAT? No way. There is just no way.
> 
> We need to support letting the calling program configure the routing
> parameters manually. For instance, if we want to connect to multiple
> primary access points, it simply won't work if Ofono configures everything.
> Instead, we need to either setup source routing or separate network
> name-spaces. Ofono does not know what the caller intends to do with the APN
> (and should not need to), so it cannot configure IP parameters. Besides, it
> makes very little if any sense to configure IP parameters but not DNS.

personally I don't care who finally sets the IP for the interface. It
really just makes no difference. What problem do you see if oFono would
set the IP address on that newly created interface that is up and
running now?

My point is that gateway and DNS is out of the question for oFono.

Regards

Marcel



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

* Re: GPRS support for Ofono
  2009-09-02  9:16       ` Marcel Holtmann
@ 2009-09-02  9:22         ` =?unknown-8bit?q?R=C3=A9mi?= Denis-Courmont
  2009-09-02 10:43           ` Aki Niemi
  0 siblings, 1 reply; 42+ messages in thread
From: =?unknown-8bit?q?R=C3=A9mi?= Denis-Courmont @ 2009-09-02  9:22 UTC (permalink / raw)
  To: ofono

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




On Wed, 02 Sep 2009 02:16:40 -0700, Marcel Holtmann <marcel@holtmann.org>
wrote:
> Hi Remi,
> 
>> > Our current assumption is that the basic setup of IP address, netmask
>> > and broadcast are done by oFono. Only routing and DNS are up to other
>> > programs like ConnMan for example.
>>
>> WHAAAAAAAAAAT? No way. There is just no way.
>>
>> We need to support letting the calling program configure the routing
>> parameters manually. For instance, if we want to connect to multiple
>> primary access points, it simply won't work if Ofono configures
> everything.
>> Instead, we need to either setup source routing or separate network
>> name-spaces. Ofono does not know what the caller intends to do with the
> APN
>> (and should not need to), so it cannot configure IP parameters. Besides,
> it
>> makes very little if any sense to configure IP parameters but not DNS.
> 
> personally I don't care who finally sets the IP for the interface. It
> really just makes no difference. What problem do you see if oFono would
> set the IP address on that newly created interface that is up and
> running now?

Then the application cannot influence the way it's done. That's the whole
point. Maybe I want to migrate the interface in a new namespace. For that,
it must (1) create the interface, (2) migrate it, (3) configure it, in that
order. So Ofono cannot do (3) if it cannot do (2), and it certainly should
not do (2) by itself. So it has to stick to (1).

-- 
Rémi Denis-Courmont


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

* Re: GPRS support for Ofono
  2009-09-02  9:22         ` =?unknown-8bit?q?R=C3=A9mi?= Denis-Courmont
@ 2009-09-02 10:43           ` Aki Niemi
  2009-09-02 11:03             ` Marcel Holtmann
  0 siblings, 1 reply; 42+ messages in thread
From: Aki Niemi @ 2009-09-02 10:43 UTC (permalink / raw)
  To: ofono

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

2009/9/2 Rémi Denis-Courmont <remi@remlab.net>:
>> personally I don't care who finally sets the IP for the interface. It
>> really just makes no difference. What problem do you see if oFono would
>> set the IP address on that newly created interface that is up and
>> running now?
>
> Then the application cannot influence the way it's done. That's the whole
> point. Maybe I want to migrate the interface in a new namespace. For that,
> it must (1) create the interface, (2) migrate it, (3) configure it, in that
> order. So Ofono cannot do (3) if it cannot do (2), and it certainly should
> not do (2) by itself. So it has to stick to (1).

And this generally applies to services that operators have decided to
run behind a dedicated APN, such as WAP, MMS, Push over Cellular (PoC)
and others. For example, Elisa in Finland seems to be running their
MMSC behind an "mms" APN, with public IP address space, but firewalled
from the rest of the Internet. oFono should isolate such an access
from the rest of the system, since only the MMS client would know how
to work with it properly.

Cheers,
Aki

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

* Re: GPRS support for Ofono
  2009-09-02 10:43           ` Aki Niemi
@ 2009-09-02 11:03             ` Marcel Holtmann
  2009-09-02 11:19               ` =?unknown-8bit?q?R=C3=A9mi?= Denis-Courmont
  0 siblings, 1 reply; 42+ messages in thread
From: Marcel Holtmann @ 2009-09-02 11:03 UTC (permalink / raw)
  To: ofono

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

Hi Aki,

> >> personally I don't care who finally sets the IP for the interface. It
> >> really just makes no difference. What problem do you see if oFono would
> >> set the IP address on that newly created interface that is up and
> >> running now?
> >
> > Then the application cannot influence the way it's done. That's the whole
> > point. Maybe I want to migrate the interface in a new namespace. For that,
> > it must (1) create the interface, (2) migrate it, (3) configure it, in that
> > order. So Ofono cannot do (3) if it cannot do (2), and it certainly should
> > not do (2) by itself. So it has to stick to (1).
> 
> And this generally applies to services that operators have decided to
> run behind a dedicated APN, such as WAP, MMS, Push over Cellular (PoC)
> and others. For example, Elisa in Finland seems to be running their
> MMSC behind an "mms" APN, with public IP address space, but firewalled
> from the rest of the Internet. oFono should isolate such an access
> from the rest of the system, since only the MMS client would know how
> to work with it properly.

if they are doing something nasty like that, then the only real solution
is network namespaces. This means we can just bring the interface up and
then have to give all networking details via D-Bus properties. Actually
we might should not even bring the network interface up, but it might be
tricky with PPP or the HSO point-to-point stuff.

Regards

Marcel



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

* Re: GPRS support for Ofono
  2009-09-02 11:03             ` Marcel Holtmann
@ 2009-09-02 11:19               ` =?unknown-8bit?q?R=C3=A9mi?= Denis-Courmont
  0 siblings, 0 replies; 42+ messages in thread
From: =?unknown-8bit?q?R=C3=A9mi?= Denis-Courmont @ 2009-09-02 11:19 UTC (permalink / raw)
  To: ofono

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


On Wed, 02 Sep 2009 04:03:05 -0700, Marcel Holtmann <marcel@holtmann.org>
wrote:
>> And this generally applies to services that operators have decided to
>> run behind a dedicated APN, such as WAP, MMS, Push over Cellular (PoC)
>> and others. For example, Elisa in Finland seems to be running their
>> MMSC behind an "mms" APN, with public IP address space, but firewalled
>> from the rest of the Internet. oFono should isolate such an access
>> from the rest of the system, since only the MMS client would know how
>> to work with it properly.
> 
> if they are doing something nasty like that, then the only real solution
> is network namespaces. This means we can just bring the interface up and
> then have to give all networking details via D-Bus properties.

Yes. That's what I was saying, or at least trying to say.

-- 
Rémi Denis-Courmont


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

* Re: GPRS support for Ofono
  2009-09-01 21:36 ` Denis Kenzior
  2009-09-01 22:42   ` Marcel Holtmann
@ 2009-09-02 11:30   ` Ismo Puustinen
  2009-09-02 12:02     ` Marcel Holtmann
  2009-09-02 15:00     ` Denis Kenzior
  1 sibling, 2 replies; 42+ messages in thread
From: Ismo Puustinen @ 2009-09-02 11:30 UTC (permalink / raw)
  To: ofono

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

On Wed, Sep 2, 2009 at 12:36 AM, Denis Kenzior<denkenz@gmail.com> wrote:

> of this discussion.  I'd like all interested to comment.  What needs
> improvement? What is missing?  What should be removed?

Here are some comments. Some of the comments were already present in
the IRC discussion, but I'll repeat them here anyway. First of all,
the both Denis's proposal and mine look quite much the same -- the
basic objects are the GPRS manager and the PDP contexts, and they
offer quite the same functionality. Please correct me if I understood
some parts of Denis's proposal incorrectly. The big differences
between the API proposals are the creation and connecting of the
contexts and the handling of the attached/detached state. I'll try to
address the both issues below.

In this proposal the contexts PDP contexts are persistent on the
device, meaning that they stay there also when Ofono is shut down. The
idea is that the contexts are made to Ofono by the GPRS provisioning
programs or by the UI, and then ConnMan or another upper layer needs
just to activate the context to actually do the connection. In my
proposal I thought that the higher layer components would keep track
of the access points and call the Connect() method with the suitable
connection parameters.

This is a philosophical difference from the provisioning point of
view. An operator will likely support multiple configured access
points, and the provisioning program should know their purpose from
the configuration file (internet/MMS/WAP/...). This metadata is not
there in the Ofono context, meaning that the provisioning program
needs to store somewhere else the mapping between Ofono context object
paths and the neccessary metadata. This begs the question: why not
store all connection data (APN, authentication data, other metadata)
to this external store in the first place?

The attachment to the GPRS network in this proposal is bit vague. To
my understanding, to attach the GPRS you need to set "Powered"
property on and "RoamingAllowed" on. To detach you need to set the
"Powered" property off. Since attaching can take a long time (or
fail), does this mean that the attach errors are handled in the
"Powered" property setter callback?  Or what happens when (during
roaming) the "Powered" is already on and the user puts the
"RoamingAllowed" on -- where are the attach errors handled? I kind of
think that it might be a better idea to just expose the GPRS
registration status and the attach status, and let a higher level
component explicitly set the attach/detach with either a readwrite
property or Attach() and Detach() methods.

In my proposal the "Status" variable was a three-state variable,
having the states "attached", "detached" and "suspended". "Suspended"
was specified to mean that the GPRS was attached, but temporarily not
available (for instance because of a 2G phone call or temporary loss
of cellular connectivity). In the IRC discussion someone said that
this property would not be part of Denis's API because the tri-state
variables were bad and the "suspended" status was not supported by
spec 27.007. However, the problem is that Maemo 5 already has UI
support for indicating that the connection is suspended, and that
makes it harder to drop the feature. Could the "suspended" status enum
still be left there, and just have the modems that don't support the
feature to never go to "suspended" mode?

Still one difference to my proposal was the dropping of the TX and RX
byte counts, and the explanation that those statistics would be
handled by the upper layers by reading the values from the network
interface. I mentioned the problem where the connection was terminated
by the network and the network interface was brought down before the
upper layer had a chance to read the values. After giving the matter
some thought, I still feel that for this reason the modem driver would
need to get the TX/RX data and send it to the upper levels, if at all
possible. Since many operators charge by the amount of data
transferred, not losing the TX/RX data is quite crucial. At least
Nokia phones have a GPRS data counter feature, that is supposed to
show the transferred data. This said, I know that not all modem
drivers can get the data from a connection that has been terminated by
the network, but that does not mean that the modem drivers that can
get the data should just discard it.

Btw, is the context API missing the PDP type (IPv4 or IPv6)?

As I said, I think that the differences between this proposal and mine
are mostly philosophical -- should the context data be stored in Ofono
or in the upper layers of the stack? And should Ofono set the policies
(for instance the roaming case) or just act as a low-level interface
to the GPRS functionality?

By looking at Denis's proposal it is easy to see that my proposal
wasn't perfect either. ;-) At least the GPRS registration state and
possibly other properties need to be added to the D-Bus interface, and
the API also needs to be made more future-proof by thinking how the
network-initiated connections and the secondary contexts would be
made.

-- 
Ismo Puustinen <ismo@iki.fi>

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

* Re: GPRS support for Ofono
  2009-09-02 11:30   ` Ismo Puustinen
@ 2009-09-02 12:02     ` Marcel Holtmann
  2009-09-02 12:34       ` Aki Niemi
  2009-09-02 12:46       ` =?unknown-8bit?q?R=C3=A9mi?= Denis-Courmont
  2009-09-02 15:00     ` Denis Kenzior
  1 sibling, 2 replies; 42+ messages in thread
From: Marcel Holtmann @ 2009-09-02 12:02 UTC (permalink / raw)
  To: ofono

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

Hi Ismo,

> > of this discussion.  I'd like all interested to comment.  What needs
> > improvement? What is missing?  What should be removed?
> 
> Here are some comments. Some of the comments were already present in
> the IRC discussion, but I'll repeat them here anyway. First of all,
> the both Denis's proposal and mine look quite much the same -- the
> basic objects are the GPRS manager and the PDP contexts, and they
> offer quite the same functionality. Please correct me if I understood
> some parts of Denis's proposal incorrectly. The big differences
> between the API proposals are the creation and connecting of the
> contexts and the handling of the attached/detached state. I'll try to
> address the both issues below.
> 
> In this proposal the contexts PDP contexts are persistent on the
> device, meaning that they stay there also when Ofono is shut down. The
> idea is that the contexts are made to Ofono by the GPRS provisioning
> programs or by the UI, and then ConnMan or another upper layer needs
> just to activate the context to actually do the connection. In my
> proposal I thought that the higher layer components would keep track
> of the access points and call the Connect() method with the suitable
> connection parameters.
> 
> This is a philosophical difference from the provisioning point of
> view. An operator will likely support multiple configured access
> points, and the provisioning program should know their purpose from
> the configuration file (internet/MMS/WAP/...). This metadata is not
> there in the Ofono context, meaning that the provisioning program
> needs to store somewhere else the mapping between Ofono context object
> paths and the neccessary metadata. This begs the question: why not
> store all connection data (APN, authentication data, other metadata)
> to this external store in the first place?

I mentioned that already. We do wanna store something like Type that
says internet, mms, wap etc. The only comment here was that for network
initiated context we have no idea of its intent.

> The attachment to the GPRS network in this proposal is bit vague. To
> my understanding, to attach the GPRS you need to set "Powered"
> property on and "RoamingAllowed" on. To detach you need to set the
> "Powered" property off. Since attaching can take a long time (or
> fail), does this mean that the attach errors are handled in the
> "Powered" property setter callback?  Or what happens when (during
> roaming) the "Powered" is already on and the user puts the
> "RoamingAllowed" on -- where are the attach errors handled? I kind of
> think that it might be a better idea to just expose the GPRS
> registration status and the attach status, and let a higher level
> component explicitly set the attach/detach with either a readwrite
> property or Attach() and Detach() methods.

Powered = on and RoamingAllowed = yes and Roaming = true will lead to
auto-attach.

Powered = on and RoamingAllowed = no and Roaming = true will lead to
detach.

Powered = on and Roaming = false will lead to auto-attach.

Powered = off will lead to detach.

We are not going to expose Attach() or Detach() method. As explained
there are global anyway and so pointless to expose. This can be handled
in the background without bothering the higher level application with
these details.

> In my proposal the "Status" variable was a three-state variable,
> having the states "attached", "detached" and "suspended". "Suspended"
> was specified to mean that the GPRS was attached, but temporarily not
> available (for instance because of a 2G phone call or temporary loss
> of cellular connectivity). In the IRC discussion someone said that
> this property would not be part of Denis's API because the tri-state
> variables were bad and the "suspended" status was not supported by
> spec 27.007. However, the problem is that Maemo 5 already has UI
> support for indicating that the connection is suspended, and that
> makes it harder to drop the feature. Could the "suspended" status enum
> still be left there, and just have the modems that don't support the
> feature to never go to "suspended" mode?

I am still not seeing the point in what suspended will do for us and the
UI. And that Maemo 5 exposed such a state in the UI is not an argument
to keep doing it. I asked this before, what are we suppose to be doing
when we get signaled suspended?

> Still one difference to my proposal was the dropping of the TX and RX
> byte counts, and the explanation that those statistics would be
> handled by the upper layers by reading the values from the network
> interface. I mentioned the problem where the connection was terminated
> by the network and the network interface was brought down before the
> upper layer had a chance to read the values. After giving the matter
> some thought, I still feel that for this reason the modem driver would
> need to get the TX/RX data and send it to the upper levels, if at all
> possible. Since many operators charge by the amount of data
> transferred, not losing the TX/RX data is quite crucial. At least
> Nokia phones have a GPRS data counter feature, that is supposed to
> show the transferred data. This said, I know that not all modem
> drivers can get the data from a connection that has been terminated by
> the network, but that does not mean that the modem drivers that can
> get the data should just discard it.

This is for ConnMan or similar to figure out. And we can always count
via netfilter or some other facility. Counting inside oFono makes no
sense. However we could send out a statistics signal before taking the
interface down if it would be really needed. Making it part of the
properties and having to poll for it is wrong.

> Btw, is the context API missing the PDP type (IPv4 or IPv6)?

I keep forgetting these since so far I haven't seen any provider giving
me IPv6, but you are correct, we need to be able to handle this.

> As I said, I think that the differences between this proposal and mine
> are mostly philosophical -- should the context data be stored in Ofono
> or in the upper layers of the stack? And should Ofono set the policies
> (for instance the roaming case) or just act as a low-level interface
> to the GPRS functionality?

While oFono is sort of low-level, it is not that low-level. If it would
we could expose the native AT commands. So in summary the PDP context
are stored persistently in oFono. Like BlueZ remember paired devices.

And for data roaming, we make it as simple as allowed = yes/no. This is
all the upper layer need to configure.

Not exposing method for attach/detach is a logical consequence as
explained above. It is a global per modem detail and thus there is not
point in exposing it. Also there is not point in having ConnMan and some
other potential application fighting for it. We do auto-attach if
available and tell the applications the status. If Attached = yes, then
the application can connect/disconnect contexts. As simple as that.

> By looking at Denis's proposal it is easy to see that my proposal
> wasn't perfect either. ;-) At least the GPRS registration state and
> possibly other properties need to be added to the D-Bus interface, and
> the API also needs to be made more future-proof by thinking how the
> network-initiated connections and the secondary contexts would be
> made.

I prefer start simple and add more details later. Removing details is
more complicated than adding them.

Regards

Marcel



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

* Re: GPRS support for Ofono
  2009-09-02 12:02     ` Marcel Holtmann
@ 2009-09-02 12:34       ` Aki Niemi
  2009-09-02 12:46         ` Marcel Holtmann
  2009-09-02 15:28         ` Denis Kenzior
  2009-09-02 12:46       ` =?unknown-8bit?q?R=C3=A9mi?= Denis-Courmont
  1 sibling, 2 replies; 42+ messages in thread
From: Aki Niemi @ 2009-09-02 12:34 UTC (permalink / raw)
  To: ofono

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

2009/9/2 Marcel Holtmann <marcel@holtmann.org>:
> Powered = on and RoamingAllowed = yes and Roaming = true will lead to
> auto-attach.
>
> Powered = on and RoamingAllowed = no and Roaming = true will lead to
> detach.
>
> Powered = on and Roaming = false will lead to auto-attach.
>
> Powered = off will lead to detach.

Why is auto-attach dependent on roaming?

> We are not going to expose Attach() or Detach() method. As explained
> there are global anyway and so pointless to expose. This can be handled
> in the background without bothering the higher level application with
> these details.

AFAIK, attach status of GPRS has both regulatory aspects to consider
(some operators require always attached vs. some prohibit it) as well
as power consumption issues (auto-attach might draw more power than
on-demand, although there's an inverse effect on latency). These are
issues you need to take into account, and higher layers in the stack
definitely *need* to be aware of as well. Also, I don' t think oFono
is the correct place for these decisions -> better expose a necessary
API and let upper layers deal with it.


In general, I appreciate the attempt to hide ugly details from
applications, but unfortunately some things can't well be hidden.
Another unrelated, but similar issue is network scanning. It just
isn't going to work without us exposing it in the D-Bus API
explicitly.

The reason is simple, Nokia modems suspend GPRS when scanning (or
registering), simply because the operation will take roughly three
times as long with GPRS attached. You will find this feature in
current phones, too.

Now, there is no way we can have GPRS suspend without warning just
because the stack deems it necessary to scan for networks. Again the
intention is good, but the end result not so good. I don't want to
start patching oFono to support this type of basic stuff.

>> In my proposal the "Status" variable was a three-state variable,
>> having the states "attached", "detached" and "suspended". "Suspended"
>> was specified to mean that the GPRS was attached, but temporarily not
>> available (for instance because of a 2G phone call or temporary loss
>> of cellular connectivity). In the IRC discussion someone said that
>> this property would not be part of Denis's API because the tri-state
>> variables were bad and the "suspended" status was not supported by
>> spec 27.007. However, the problem is that Maemo 5 already has UI
>> support for indicating that the connection is suspended, and that
>> makes it harder to drop the feature. Could the "suspended" status enum
>> still be left there, and just have the modems that don't support the
>> feature to never go to "suspended" mode?
>
> I am still not seeing the point in what suspended will do for us and the
> UI. And that Maemo 5 exposed such a state in the UI is not an argument
> to keep doing it. I asked this before, what are we suppose to be doing
> when we get signaled suspended?

You will find that practically every Nokia phone behaves this way,
i.e., you make a call in 2G, and the UI will inform you that GPRS is
suspended while on call.

>> Still one difference to my proposal was the dropping of the TX and RX
>> byte counts, and the explanation that those statistics would be
>> handled by the upper layers by reading the values from the network
>> interface. I mentioned the problem where the connection was terminated
>> by the network and the network interface was brought down before the
>> upper layer had a chance to read the values. After giving the matter
>> some thought, I still feel that for this reason the modem driver would
>> need to get the TX/RX data and send it to the upper levels, if at all
>> possible. Since many operators charge by the amount of data
>> transferred, not losing the TX/RX data is quite crucial. At least
>> Nokia phones have a GPRS data counter feature, that is supposed to
>> show the transferred data. This said, I know that not all modem
>> drivers can get the data from a connection that has been terminated by
>> the network, but that does not mean that the modem drivers that can
>> get the data should just discard it.
>
> This is for ConnMan or similar to figure out. And we can always count
> via netfilter or some other facility. Counting inside oFono makes no
> sense. However we could send out a statistics signal before taking the
> interface down if it would be really needed. Making it part of the
> properties and having to poll for it is wrong.

I believe emitting a signal was Ismo's original proposal.

> While oFono is sort of low-level, it is not that low-level. If it would
> we could expose the native AT commands. So in summary the PDP context
> are stored persistently in oFono. Like BlueZ remember paired devices.
>
> And for data roaming, we make it as simple as allowed = yes/no. This is
> all the upper layer need to configure.
>
> Not exposing method for attach/detach is a logical consequence as
> explained above. It is a global per modem detail and thus there is not
> point in exposing it. Also there is not point in having ConnMan and some
> other potential application fighting for it. We do auto-attach if
> available and tell the applications the status. If Attached = yes, then
> the application can connect/disconnect contexts. As simple as that.

Then expose an AutoAttach = true/false property. That would work.

>> By looking at Denis's proposal it is easy to see that my proposal
>> wasn't perfect either. ;-) At least the GPRS registration state and
>> possibly other properties need to be added to the D-Bus interface, and
>> the API also needs to be made more future-proof by thinking how the
>> network-initiated connections and the secondary contexts would be
>> made.
>
> I prefer start simple and add more details later. Removing details is
> more complicated than adding them.

For some of these features, there is no question whether or not we
need them. I think you should be listening closely for the
requirements we post, because this isn't something we *think* might be
needed some day -- this is stuff that we've implemented and will ship,
and expect to ship in the future.

Cheers,
Aki

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

* Re: GPRS support for Ofono
  2009-09-02 12:34       ` Aki Niemi
@ 2009-09-02 12:46         ` Marcel Holtmann
  2009-09-02 12:51           ` =?unknown-8bit?q?R=C3=A9mi?= Denis-Courmont
  2009-09-02 15:28         ` Denis Kenzior
  1 sibling, 1 reply; 42+ messages in thread
From: Marcel Holtmann @ 2009-09-02 12:46 UTC (permalink / raw)
  To: ofono

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

Hi Aki,

> > Powered = on and RoamingAllowed = yes and Roaming = true will lead to
> > auto-attach.
> >
> > Powered = on and RoamingAllowed = no and Roaming = true will lead to
> > detach.
> >
> > Powered = on and Roaming = false will lead to auto-attach.
> >
> > Powered = off will lead to detach.
> 
> Why is auto-attach dependent on roaming?

power consumption. No need to attach if you don't wanna allow data
roaming.

> > We are not going to expose Attach() or Detach() method. As explained
> > there are global anyway and so pointless to expose. This can be handled
> > in the background without bothering the higher level application with
> > these details.
> 
> AFAIK, attach status of GPRS has both regulatory aspects to consider
> (some operators require always attached vs. some prohibit it) as well
> as power consumption issues (auto-attach might draw more power than
> on-demand, although there's an inverse effect on latency). These are
> issues you need to take into account, and higher layers in the stack
> definitely *need* to be aware of as well. Also, I don' t think oFono
> is the correct place for these decisions -> better expose a necessary
> API and let upper layers deal with it.

I disagree. We can have a config option that always attaches or attached
on demand, but this should not be exposed to any higher level
applications.

> In general, I appreciate the attempt to hide ugly details from
> applications, but unfortunately some things can't well be hidden.
> Another unrelated, but similar issue is network scanning. It just
> isn't going to work without us exposing it in the D-Bus API
> explicitly.
> 
> The reason is simple, Nokia modems suspend GPRS when scanning (or
> registering), simply because the operation will take roughly three
> times as long with GPRS attached. You will find this feature in
> current phones, too.
> 
> Now, there is no way we can have GPRS suspend without warning just
> because the stack deems it necessary to scan for networks. Again the
> intention is good, but the end result not so good. I don't want to
> start patching oFono to support this type of basic stuff.

I mentioned this before. We might need to add a config option to allow
integrators choose different behavior.

> >> In my proposal the "Status" variable was a three-state variable,
> >> having the states "attached", "detached" and "suspended". "Suspended"
> >> was specified to mean that the GPRS was attached, but temporarily not
> >> available (for instance because of a 2G phone call or temporary loss
> >> of cellular connectivity). In the IRC discussion someone said that
> >> this property would not be part of Denis's API because the tri-state
> >> variables were bad and the "suspended" status was not supported by
> >> spec 27.007. However, the problem is that Maemo 5 already has UI
> >> support for indicating that the connection is suspended, and that
> >> makes it harder to drop the feature. Could the "suspended" status enum
> >> still be left there, and just have the modems that don't support the
> >> feature to never go to "suspended" mode?
> >
> > I am still not seeing the point in what suspended will do for us and the
> > UI. And that Maemo 5 exposed such a state in the UI is not an argument
> > to keep doing it. I asked this before, what are we suppose to be doing
> > when we get signaled suspended?
> 
> You will find that practically every Nokia phone behaves this way,
> i.e., you make a call in 2G, and the UI will inform you that GPRS is
> suspended while on call.

So what is the difference signaling a disconnect and re-connect to the
application?

> >> Still one difference to my proposal was the dropping of the TX and RX
> >> byte counts, and the explanation that those statistics would be
> >> handled by the upper layers by reading the values from the network
> >> interface. I mentioned the problem where the connection was terminated
> >> by the network and the network interface was brought down before the
> >> upper layer had a chance to read the values. After giving the matter
> >> some thought, I still feel that for this reason the modem driver would
> >> need to get the TX/RX data and send it to the upper levels, if at all
> >> possible. Since many operators charge by the amount of data
> >> transferred, not losing the TX/RX data is quite crucial. At least
> >> Nokia phones have a GPRS data counter feature, that is supposed to
> >> show the transferred data. This said, I know that not all modem
> >> drivers can get the data from a connection that has been terminated by
> >> the network, but that does not mean that the modem drivers that can
> >> get the data should just discard it.
> >
> > This is for ConnMan or similar to figure out. And we can always count
> > via netfilter or some other facility. Counting inside oFono makes no
> > sense. However we could send out a statistics signal before taking the
> > interface down if it would be really needed. Making it part of the
> > properties and having to poll for it is wrong.
> 
> I believe emitting a signal was Ismo's original proposal.

I will talk with Stephen and David about this and what it a proper way
to collect statistics even if the interface goes away. They might have
some ideas. Changing the kernel and adding proper support for statistics
collection is not out the question here.

> > While oFono is sort of low-level, it is not that low-level. If it would
> > we could expose the native AT commands. So in summary the PDP context
> > are stored persistently in oFono. Like BlueZ remember paired devices.
> >
> > And for data roaming, we make it as simple as allowed = yes/no. This is
> > all the upper layer need to configure.
> >
> > Not exposing method for attach/detach is a logical consequence as
> > explained above. It is a global per modem detail and thus there is not
> > point in exposing it. Also there is not point in having ConnMan and some
> > other potential application fighting for it. We do auto-attach if
> > available and tell the applications the status. If Attached = yes, then
> > the application can connect/disconnect contexts. As simple as that.
> 
> Then expose an AutoAttach = true/false property. That would work.

I prefer these details as configuration option that integrators set when
building the actual device. No need to have higher application change
it.

> >> By looking at Denis's proposal it is easy to see that my proposal
> >> wasn't perfect either. ;-) At least the GPRS registration state and
> >> possibly other properties need to be added to the D-Bus interface, and
> >> the API also needs to be made more future-proof by thinking how the
> >> network-initiated connections and the secondary contexts would be
> >> made.
> >
> > I prefer start simple and add more details later. Removing details is
> > more complicated than adding them.
> 
> For some of these features, there is no question whether or not we
> need them. I think you should be listening closely for the
> requirements we post, because this isn't something we *think* might be
> needed some day -- this is stuff that we've implemented and will ship,
> and expect to ship in the future.

Then please give examples. I asked this on IRC. I have never used
Secondary PDP Context before. Same goes for network initiated contexts.
I would really like to know which networks use what. And I think we need
to start collecting these information somewhere. It is important to know
what is used in production.

Regards

Marcel



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

* Re: GPRS support for Ofono
  2009-09-02 12:02     ` Marcel Holtmann
  2009-09-02 12:34       ` Aki Niemi
@ 2009-09-02 12:46       ` =?unknown-8bit?q?R=C3=A9mi?= Denis-Courmont
  2009-09-02 13:01         ` Marcel Holtmann
  1 sibling, 1 reply; 42+ messages in thread
From: =?unknown-8bit?q?R=C3=A9mi?= Denis-Courmont @ 2009-09-02 12:46 UTC (permalink / raw)
  To: ofono

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


On Wed, 02 Sep 2009 05:02:46 -0700, Marcel Holtmann <marcel@holtmann.org>
wrote:
> I mentioned that already. We do wanna store something like Type that
> says internet, mms, wap etc. The only comment here was that for network
> initiated context we have no idea of its intent.

And we do not want to.

>> The attachment to the GPRS network in this proposal is bit vague. To
>> my understanding, to attach the GPRS you need to set "Powered"
>> property on and "RoamingAllowed" on. To detach you need to set the
>> "Powered" property off. Since attaching can take a long time (or
>> fail), does this mean that the attach errors are handled in the
>> "Powered" property setter callback?  Or what happens when (during
>> roaming) the "Powered" is already on and the user puts the
>> "RoamingAllowed" on -- where are the attach errors handled? I kind of
>> think that it might be a better idea to just expose the GPRS
>> registration status and the attach status, and let a higher level
>> component explicitly set the attach/detach with either a readwrite
>> property or Attach() and Detach() methods.
> 
> Powered = on and RoamingAllowed = yes and Roaming = true will lead to
> auto-attach.

That's just _idiotic_ from the naming perspective.

A modem can have radio on or off. Whether this is done by completely
powering the modem off, or by going into some kind of flight mode, is
driver-specific. Hence the "powered" name is semantically wrong. When
possible, it's actually best to keep the modem in flight mode, so that e.g.
the SIM is still usable.

The story is basically the same with roaming. Roaming means you are outside
your home network. It does not mean that you want to auto-attach or not.
Some people _never_ want to auto-attach, and some people _always_ want to
auto-attach. In fact, different operators have different requirements with
that regard. Sure, some people want to auto-attach if and only if not
roaming. Given that roaming is not just about GPRS, the name is wrong and
confusing. But more importantly, we need t support turning the radio on
while in the home network yet _not_ attach automatically. This has operator
requirements as well as power saving implications.

> We are not going to expose Attach() or Detach() method.

And we are going to expose it.

> I am still not seeing the point in what suspended will do for us and the
> UI. And that Maemo 5 exposed such a state in the UI is not an argument
> to keep doing it. I asked this before, what are we suppose to be doing
> when we get signaled suspended?

User, as well as intelligent (connectivity-aware) applications, need to
know about this so that they understand why "Internet" is momentarily
broken. It's as simple as that.

Oh we could also use the network device carrier flag, and then use Netlink
(and we probably should do that too), but we all know how horrible Netlink
is from userland.

(...)
> This is for ConnMan or similar to figure out. And we can always count
> via netfilter or some other facility. Counting inside oFono makes no
> sense. However we could send out a statistics signal before taking the
> interface down if it would be really needed. Making it part of the
> properties and having to poll for it is wrong.

This has legal(ish) implications related to charging. Skipping this is not
exactly an option (for a device vendor). I actually agree that this is ugly
in some ways. In theory, I don't really care if Ofono or the over-lying
connection manager takes care of it. *But* we even need to collect
statistics for contexts not handled in Ofono (e.g. Windows PC tethering).
And I doubt that Connman would be able to do that properly.

It's ugly and annoying, but we have to suck it up.

>> As I said, I think that the differences between this proposal and mine
>> are mostly philosophical -- should the context data be stored in Ofono
>> or in the upper layers of the stack? And should Ofono set the policies
>> (for instance the roaming case) or just act as a low-level interface
>> to the GPRS functionality?
> 
> While oFono is sort of low-level, it is not that low-level. If it would
> we could expose the native AT commands. So in summary the PDP context
> are stored persistently in oFono. Like BlueZ remember paired devices.

I fail to see how providing a direct low-level interface would prevent us
from providing _also_ a higher-level interface. The later can handle
provisioning and data persistence.

-- 
Rémi Denis-Courmont


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

* Re: GPRS support for Ofono
  2009-09-02 12:46         ` Marcel Holtmann
@ 2009-09-02 12:51           ` =?unknown-8bit?q?R=C3=A9mi?= Denis-Courmont
  0 siblings, 0 replies; 42+ messages in thread
From: =?unknown-8bit?q?R=C3=A9mi?= Denis-Courmont @ 2009-09-02 12:51 UTC (permalink / raw)
  To: ofono

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


On Wed, 02 Sep 2009 05:46:31 -0700, Marcel Holtmann <marcel@holtmann.org>
wrote:
>> You will find that practically every Nokia phone behaves this way,
>> i.e., you make a call in 2G, and the UI will inform you that GPRS is
>> suspended while on call.
> 
> So what is the difference signaling a disconnect and re-connect to the
> application?

It's like pausing or stopping your media player.

>> For some of these features, there is no question whether or not we
>> need them. I think you should be listening closely for the
>> requirements we post, because this isn't something we *think* might be
>> needed some day -- this is stuff that we've implemented and will ship,
>> and expect to ship in the future.
> 
> Then please give examples. I asked this on IRC. I have never used
> Secondary PDP Context before. Same goes for network initiated contexts.

Neither did I.

OTOH, I did see annoying data counter requirements, and I did see suspended
mode.

-- 
Rémi Denis-Courmont


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

* Re: GPRS support for Ofono
  2009-09-02 12:46       ` =?unknown-8bit?q?R=C3=A9mi?= Denis-Courmont
@ 2009-09-02 13:01         ` Marcel Holtmann
  2009-09-02 17:51           ` Bastian, Waldo
  0 siblings, 1 reply; 42+ messages in thread
From: Marcel Holtmann @ 2009-09-02 13:01 UTC (permalink / raw)
  To: ofono

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

Hi Remi,

> > I mentioned that already. We do wanna store something like Type that
> > says internet, mms, wap etc. The only comment here was that for network
> > initiated context we have no idea of its intent.
> 
> And we do not want to.
> 
> >> The attachment to the GPRS network in this proposal is bit vague. To
> >> my understanding, to attach the GPRS you need to set "Powered"
> >> property on and "RoamingAllowed" on. To detach you need to set the
> >> "Powered" property off. Since attaching can take a long time (or
> >> fail), does this mean that the attach errors are handled in the
> >> "Powered" property setter callback?  Or what happens when (during
> >> roaming) the "Powered" is already on and the user puts the
> >> "RoamingAllowed" on -- where are the attach errors handled? I kind of
> >> think that it might be a better idea to just expose the GPRS
> >> registration status and the attach status, and let a higher level
> >> component explicitly set the attach/detach with either a readwrite
> >> property or Attach() and Detach() methods.
> > 
> > Powered = on and RoamingAllowed = yes and Roaming = true will lead to
> > auto-attach.
> 
> That's just _idiotic_ from the naming perspective.
> 
> A modem can have radio on or off. Whether this is done by completely
> powering the modem off, or by going into some kind of flight mode, is
> driver-specific. Hence the "powered" name is semantically wrong. When
> possible, it's actually best to keep the modem in flight mode, so that e.g.
> the SIM is still usable.
> 
> The story is basically the same with roaming. Roaming means you are outside
> your home network. It does not mean that you want to auto-attach or not.
> Some people _never_ want to auto-attach, and some people _always_ want to
> auto-attach. In fact, different operators have different requirements with
> that regard. Sure, some people want to auto-attach if and only if not
> roaming. Given that roaming is not just about GPRS, the name is wrong and
> confusing. But more importantly, we need t support turning the radio on
> while in the home network yet _not_ attach automatically. This has operator
> requirements as well as power saving implications.

you did read the API docs Denis send around? These are not global
Powered and RoamingAllowed properties. They are specific to the GPRS
Manager and thus have specific meaning in that context. It has nothing
to do with flight mode or radio off.

And for the different operator policy/behavior, that should be
configured via config option and not via D-Bus. The integrator should
make a choice. It it is a list of mappings of operator = attach policy,
then that is also fine.

> > We are not going to expose Attach() or Detach() method.
> 
> And we are going to expose it.

And for what good is this. So we have two applications fighting about
Attach and Detach and some weird policy somewhere upper in the stack
with no real sense on what is happening. Sorry but I am not buying this
at all.

If the only argument is that different providers require different
auto-attach policies then we have that as described via a config option
and be done with it.

Otherwise I like to see real examples where something like ConnMan, an
MMS application or any other application need control over the attach
status.

> > I am still not seeing the point in what suspended will do for us and the
> > UI. And that Maemo 5 exposed such a state in the UI is not an argument
> > to keep doing it. I asked this before, what are we suppose to be doing
> > when we get signaled suspended?
> 
> User, as well as intelligent (connectivity-aware) applications, need to
> know about this so that they understand why "Internet" is momentarily
> broken. It's as simple as that.
> 
> Oh we could also use the network device carrier flag, and then use Netlink
> (and we probably should do that too), but we all know how horrible Netlink
> is from userland.

Using IFF_RUNNING and IFF_LOWER_UP sounds more reasonable then some
suspended state.

> (...)
> > This is for ConnMan or similar to figure out. And we can always count
> > via netfilter or some other facility. Counting inside oFono makes no
> > sense. However we could send out a statistics signal before taking the
> > interface down if it would be really needed. Making it part of the
> > properties and having to poll for it is wrong.
> 
> This has legal(ish) implications related to charging. Skipping this is not
> exactly an option (for a device vendor). I actually agree that this is ugly
> in some ways. In theory, I don't really care if Ofono or the over-lying
> connection manager takes care of it. *But* we even need to collect
> statistics for contexts not handled in Ofono (e.g. Windows PC tethering).
> And I doubt that Connman would be able to do that properly.
> 
> It's ugly and annoying, but we have to suck it up.

As I mentioned it before. We figure something out. We do have the same
problem for all hotplug network devices. Especially with hotplug 3G
dongles, we need to do something better than counting by ourself. The
kernel should do it for us. If you yank the dongle, then oFono is even
lost and the accounting is not accurate.

> >> As I said, I think that the differences between this proposal and mine
> >> are mostly philosophical -- should the context data be stored in Ofono
> >> or in the upper layers of the stack? And should Ofono set the policies
> >> (for instance the roaming case) or just act as a low-level interface
> >> to the GPRS functionality?
> > 
> > While oFono is sort of low-level, it is not that low-level. If it would
> > we could expose the native AT commands. So in summary the PDP context
> > are stored persistently in oFono. Like BlueZ remember paired devices.
> 
> I fail to see how providing a direct low-level interface would prevent us
> from providing _also_ a higher-level interface. The later can handle
> provisioning and data persistence.

I don't see the need for the low-level interface in this context. What
do you expect it to do? I might be missing something here, but where do
we actually use dynamic one-time PDP contexts. These all look like
configured or provisioned settings to me.

Regards

Marcel



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

* Re: GPRS support for Ofono
  2009-09-02 11:30   ` Ismo Puustinen
  2009-09-02 12:02     ` Marcel Holtmann
@ 2009-09-02 15:00     ` Denis Kenzior
  2009-09-02 15:32       ` Aki Niemi
  2009-09-02 15:38       ` =?unknown-8bit?q?R=C3=A9mi?= Denis-Courmont
  1 sibling, 2 replies; 42+ messages in thread
From: Denis Kenzior @ 2009-09-02 15:00 UTC (permalink / raw)
  To: ofono

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

Hi Ismo,

> This is a philosophical difference from the provisioning point of
> view. An operator will likely support multiple configured access
> points, and the provisioning program should know their purpose from
> the configuration file (internet/MMS/WAP/...). This metadata is not
> there in the Ofono context, meaning that the provisioning program
> needs to store somewhere else the mapping between Ofono context object
> paths and the neccessary metadata. This begs the question: why not
> store all connection data (APN, authentication data, other metadata)
> to this external store in the first place?

Actually this one is missing from the API proposal.  Marcel already wanted the 
context type (internet, mms, wap, etc) information.  I've updated the proposed 
API in git.

As discussed previously, we want oFono to manage this data, since it can do 
this by using the IMSI.  So if you insert a different operator SIM your APN 
settings are magically updated for that operator.  

> In my proposal the "Status" variable was a three-state variable,
> having the states "attached", "detached" and "suspended". "Suspended"
> was specified to mean that the GPRS was attached, but temporarily not
> available (for instance because of a 2G phone call or temporary loss
> of cellular connectivity). In the IRC discussion someone said that
> this property would not be part of Denis's API because the tri-state
> variables were bad and the "suspended" status was not supported by

So the general rule is that if a feature isn't explicitly allowed in 27.007, 
we do not support it.  There are exceptions to this of course.  27.007 only 
supports two states for context: activated and deactivated.

> spec 27.007. However, the problem is that Maemo 5 already has UI
> support for indicating that the connection is suspended, and that
> makes it harder to drop the feature. Could the "suspended" status enum
> still be left there, and just have the modems that don't support the
> feature to never go to "suspended" mode?

I'd rather not.

If this feature is really required, then some sort of heuristic can be 
applied.  (e.g. Powered on, Attached on, but context is deactivated most 
likely means temporary unavailability of resources)

>
> Still one difference to my proposal was the dropping of the TX and RX
> byte counts, and the explanation that those statistics would be
> handled by the upper layers by reading the values from the network
> interface. I mentioned the problem where the connection was terminated
> by the network and the network interface was brought down before the
> upper layer had a chance to read the values. After giving the matter
> some thought, I still feel that for this reason the modem driver would
> need to get the TX/RX data and send it to the upper levels, if at all
> possible. Since many operators charge by the amount of data
> transferred, not losing the TX/RX data is quite crucial. At least
> Nokia phones have a GPRS data counter feature, that is supposed to
> show the transferred data. This said, I know that not all modem
> drivers can get the data from a connection that has been terminated by
> the network, but that does not mean that the modem drivers that can
> get the data should just discard it.

This really belong in the kernel.  Only the kernel can reliably know when a 
network interface has been brought down and notify the interested applications 
with the statistics.  Nokia hardware supports this explicitly, but many others 
don't.  I don't want nasty kludges inside oFono to enable this.

>
> Btw, is the context API missing the PDP type (IPv4 or IPv6)?

I left this out explicitly since I've never seen anything besides "IP" being 
used.  But we can add this easily enough if there's need.

Regards,
-Denis

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

* Re: GPRS support for Ofono
  2009-09-02 12:34       ` Aki Niemi
  2009-09-02 12:46         ` Marcel Holtmann
@ 2009-09-02 15:28         ` Denis Kenzior
  2009-09-02 15:42           ` Aki Niemi
  1 sibling, 1 reply; 42+ messages in thread
From: Denis Kenzior @ 2009-09-02 15:28 UTC (permalink / raw)
  To: ofono

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

Hi Aki,

> > We are not going to expose Attach() or Detach() method. As explained
> > there are global anyway and so pointless to expose. This can be handled
> > in the background without bothering the higher level application with
> > these details.
>
> AFAIK, attach status of GPRS has both regulatory aspects to consider
> (some operators require always attached vs. some prohibit it) as well
> as power consumption issues (auto-attach might draw more power than
> on-demand, although there's an inverse effect on latency). These are
> issues you need to take into account, and higher layers in the stack
> definitely *need* to be aware of as well. Also, I don' t think oFono
> is the correct place for these decisions -> better expose a necessary
> API and let upper layers deal with it.

I know you guys are coming from mobile phone perspective, but that one isn't 
the only scenario.  We have netbooks/laptops with gprs data cards to consider 
as well.  Hardcoding operator requirements is also not an option, since SIM 
cards can be changed.

I fundamentally disagree that the logic should be in the higher layers.  oFono 
has all the information to handle this, and can be hinted on what is 
appropriate behavior easily enough.  oFono should simply store the auto-attach 
preferences in its IMSI-indexed preference store.  The operator can bootstrap 
these preferences if required.

>
> In general, I appreciate the attempt to hide ugly details from
> applications, but unfortunately some things can't well be hidden.
> Another unrelated, but similar issue is network scanning. It just
> isn't going to work without us exposing it in the D-Bus API
> explicitly.
>

Modem drivers will have some control over whether the scan is performed 
automatically, but denying the capability for everyone is not the right thing 
to do either.

> The reason is simple, Nokia modems suspend GPRS when scanning (or
> registering), simply because the operation will take roughly three
> times as long with GPRS attached. You will find this feature in
> current phones, too.

Then ideally you should have two scan modes, periodic and user initiated.  For 
periodic mode we don't care how long it takes. 

Regards,
-Denis

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

* Re: GPRS support for Ofono
  2009-09-02 15:00     ` Denis Kenzior
@ 2009-09-02 15:32       ` Aki Niemi
  2009-09-02 15:36         ` Denis Kenzior
  2009-09-02 15:38       ` =?unknown-8bit?q?R=C3=A9mi?= Denis-Courmont
  1 sibling, 1 reply; 42+ messages in thread
From: Aki Niemi @ 2009-09-02 15:32 UTC (permalink / raw)
  To: ofono

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

Hi Denis,

2009/9/2 Denis Kenzior <denkenz@gmail.com>:
> So the general rule is that if a feature isn't explicitly allowed in 27.007,
> we do not support it.  There are exceptions to this of course.  27.007 only
> supports two states for context: activated and deactivated.

Ahem. Just like access selection mode is not in 27.007, yet Nokia has
it, and most AT modems have proprietary commands to query and set it
[1]. Maybe you call that the necessary exception to the rule, but I
think we might as well change the rule to:

"If a feature is explicitly requested by users of oFono, and can be
reasonably provided by modems that have it without braking those that
don't have it, it will be supported. And 27.007 can go fsck itself."
;-)

>> spec 27.007. However, the problem is that Maemo 5 already has UI
>> support for indicating that the connection is suspended, and that
>> makes it harder to drop the feature. Could the "suspended" status enum
>> still be left there, and just have the modems that don't support the
>> feature to never go to "suspended" mode?
>
> I'd rather not.
>
> If this feature is really required, then some sort of heuristic can be
> applied.  (e.g. Powered on, Attached on, but context is deactivated most
> likely means temporary unavailability of resources)

You want the UI to implement this heuristic, when the modem plugin has
explicit knowledge of that state, but isn't telling? Please explain
how that makes the UI simpler?

Cheers,
Aki

[1] http://blogs.gnome.org/dcbw/2009/03/20/thats-when-i-reach-for-my-revolver/

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

* Re: GPRS support for Ofono
  2009-09-02 15:32       ` Aki Niemi
@ 2009-09-02 15:36         ` Denis Kenzior
  0 siblings, 0 replies; 42+ messages in thread
From: Denis Kenzior @ 2009-09-02 15:36 UTC (permalink / raw)
  To: ofono

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

Hi Aki,

> Hi Denis,
>
> 2009/9/2 Denis Kenzior <denkenz@gmail.com>:
> > So the general rule is that if a feature isn't explicitly allowed in
> > 27.007, we do not support it.  There are exceptions to this of course.
> >  27.007 only supports two states for context: activated and deactivated.
>
> Ahem. Just like access selection mode is not in 27.007, yet Nokia has
> it, and most AT modems have proprietary commands to query and set it
> [1]. Maybe you call that the necessary exception to the rule, but I
> think we might as well change the rule to:

So my stance on BandSelection is that we want a standard interface _if and 
only if_ we can support it reliably across the majority of modems.  You might 
still find me telling every modem manufacturer to simply implement their own 
BandSelection interface if this cannot be done.

The same goes for Neighbor Cell Info or any other stuff that isn't mandated by 
27.007.

>
> >> spec 27.007. However, the problem is that Maemo 5 already has UI
> >> support for indicating that the connection is suspended, and that
> >> makes it harder to drop the feature. Could the "suspended" status enum
> >> still be left there, and just have the modems that don't support the
> >> feature to never go to "suspended" mode?
> >
> > I'd rather not.
> >
> > If this feature is really required, then some sort of heuristic can be
> > applied.  (e.g. Powered on, Attached on, but context is deactivated most
> > likely means temporary unavailability of resources)
>
> You want the UI to implement this heuristic, when the modem plugin has
> explicit knowledge of that state, but isn't telling? Please explain
> how that makes the UI simpler?

Then expose this signal on Nokia-only interface and be done with it.  Why does 
everything have to be part of the oFono official APIs?

Regards,
-Denis

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

* Re: GPRS support for Ofono
  2009-09-02 15:00     ` Denis Kenzior
  2009-09-02 15:32       ` Aki Niemi
@ 2009-09-02 15:38       ` =?unknown-8bit?q?R=C3=A9mi?= Denis-Courmont
  2009-09-02 16:26         ` Denis Kenzior
  2009-09-02 20:53         ` Marcel Holtmann
  1 sibling, 2 replies; 42+ messages in thread
From: =?unknown-8bit?q?R=C3=A9mi?= Denis-Courmont @ 2009-09-02 15:38 UTC (permalink / raw)
  To: ofono

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

Le mercredi 2 septembre 2009 18:00:22 Denis Kenzior, vous avez écrit :
> Actually this one is missing from the API proposal.  Marcel already wanted
> the context type (internet, mms, wap, etc) information.  I've updated the
> proposed API in git.

This is not going to work.

Depending on the operator, you may have more than one "type" for a single 
context (e.g. WAP+MMS), or worse, multiple contexts of the same type (e.g. 
Internet with only Web and Internet with full IP).

> As discussed previously, we want oFono to manage this data, since it can do
> this by using the IMSI.  So if you insert a different operator SIM your APN
> settings are magically updated for that operator.

I have a feeling this does not work either. If I upgrade my subscription, the 
APN may change while not the IMSI, no?

> > In my proposal the "Status" variable was a three-state variable,
> > having the states "attached", "detached" and "suspended". "Suspended"
> > was specified to mean that the GPRS was attached, but temporarily not
> > available (for instance because of a 2G phone call or temporary loss
> > of cellular connectivity). In the IRC discussion someone said that
> > this property would not be part of Denis's API because the tri-state
> > variables were bad and the "suspended" status was not supported by
>
> So the general rule is that if a feature isn't explicitly allowed in
> 27.007, we do not support it.  There are exceptions to this of course. 
> 27.007 only supports two states for context: activated and deactivated.

Our general rule is that if we have a UI requirement, or better an actual use 
case for it, we support it. Suspended GPRS fits both.

> > spec 27.007. However, the problem is that Maemo 5 already has UI
> > support for indicating that the connection is suspended, and that
> > makes it harder to drop the feature. Could the "suspended" status enum
> > still be left there, and just have the modems that don't support the
> > feature to never go to "suspended" mode?
>
> I'd rather not.
>
> If this feature is really required, then some sort of heuristic can be
> applied.  (e.g. Powered on, Attached on, but context is deactivated most
> likely means temporary unavailability of resources)

Is this some kind of joke? Don't you know the difference between pause and 
stop on your MP3 player and between suspend to memory and power off on your 
computer?

Second guessing does not fit in my definition of "easy to use self-
documenting" for an API.

> This really belong in the kernel.  Only the kernel can reliably know when a
> network interface has been brought down and notify the interested
> applications with the statistics.

You're missing the point.

Yes, any body can extract the statistics for a running context. But data 
counters are cumulating. To compute the sum properly, there are but two 
options:
# Either the GPRS middleware requests kernel per-interface statistics right 
before destroying the interface, and sums with the earlier total.
# Or the modem does it internally.

There is no way some random userland interface application can do it just by 
requesting the kernel, since it cannot know when to request those statistics.

> Nokia hardware supports this explicitly, but many others don't.

That's irrelevant. Hardware support helps in the sense that it can include 
statistics for contexts external to Ofono. If the hardware does not support 
it, then it needs to be done manually in the GPRS middleware.

That won't make the requirement go away.

-- 
Rémi Denis-Courmont
http://www.remlab.net/

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

* Re: GPRS support for Ofono
  2009-09-02 15:28         ` Denis Kenzior
@ 2009-09-02 15:42           ` Aki Niemi
  2009-09-02 20:37             ` Marcel Holtmann
  0 siblings, 1 reply; 42+ messages in thread
From: Aki Niemi @ 2009-09-02 15:42 UTC (permalink / raw)
  To: ofono

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

2009/9/2 Denis Kenzior <denkenz@gmail.com>:
>> AFAIK, attach status of GPRS has both regulatory aspects to consider
>> (some operators require always attached vs. some prohibit it) as well
>> as power consumption issues (auto-attach might draw more power than
>> on-demand, although there's an inverse effect on latency). These are
>> issues you need to take into account, and higher layers in the stack
>> definitely *need* to be aware of as well. Also, I don' t think oFono
>> is the correct place for these decisions -> better expose a necessary
>> API and let upper layers deal with it.
>
> I know you guys are coming from mobile phone perspective, but that one isn't
> the only scenario.  We have netbooks/laptops with gprs data cards to consider
> as well.  Hardcoding operator requirements is also not an option, since SIM
> cards can be changed.
>
> I fundamentally disagree that the logic should be in the higher layers.  oFono
> has all the information to handle this, and can be hinted on what is
> appropriate behavior easily enough.  oFono should simply store the auto-attach
> preferences in its IMSI-indexed preference store.  The operator can bootstrap
> these preferences if required.

Operator requirements were only half of the story. You need to be able
to disable auto-attach in low power conditions, and this logic
definitely doesn't belong in oFono. This applies equally well to
mobile phones as it does to laptops/netbooks.

>> In general, I appreciate the attempt to hide ugly details from
>> applications, but unfortunately some things can't well be hidden.
>> Another unrelated, but similar issue is network scanning. It just
>> isn't going to work without us exposing it in the D-Bus API
>> explicitly.
>>
>
> Modem drivers will have some control over whether the scan is performed
> automatically, but denying the capability for everyone is not the right thing
> to do either.

Agree, and I don't think that was what I was suggesting either.

>> The reason is simple, Nokia modems suspend GPRS when scanning (or
>> registering), simply because the operation will take roughly three
>> times as long with GPRS attached. You will find this feature in
>> current phones, too.
>
> Then ideally you should have two scan modes, periodic and user initiated.  For
> periodic mode we don't care how long it takes.

+1

Cheers,
Aki

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

* Re: GPRS support for Ofono
  2009-09-02 15:38       ` =?unknown-8bit?q?R=C3=A9mi?= Denis-Courmont
@ 2009-09-02 16:26         ` Denis Kenzior
  2009-09-02 17:39           ` Bastian, Waldo
  2009-09-02 20:53         ` Marcel Holtmann
  1 sibling, 1 reply; 42+ messages in thread
From: Denis Kenzior @ 2009-09-02 16:26 UTC (permalink / raw)
  To: ofono

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

Hi Remi,

> Le mercredi 2 septembre 2009 18:00:22 Denis Kenzior, vous avez écrit :
> > Actually this one is missing from the API proposal.  Marcel already
> > wanted the context type (internet, mms, wap, etc) information.  I've
> > updated the proposed API in git.
>
> This is not going to work.
>
> Depending on the operator, you may have more than one "type" for a single
> context (e.g. WAP+MMS), or worse, multiple contexts of the same type (e.g.
> Internet with only Web and Internet with full IP).

Worst case we make the field completely freeform.  Right now we really only 
care about "internet" type for connman.

>
> > As discussed previously, we want oFono to manage this data, since it can
> > do this by using the IMSI.  So if you insert a different operator SIM
> > your APN settings are magically updated for that operator.
>
> I have a feeling this does not work either. If I upgrade my subscription,
> the APN may change while not the IMSI, no?

Yes, but then you will probably receive an SMS/OTA message with new connection 
details.  Which either oFono or some external application will apply to your 
GPRS settings.

> > This really belong in the kernel.  Only the kernel can reliably know when
> > a network interface has been brought down and notify the interested
> > applications with the statistics.
>
> You're missing the point.
>
> Yes, any body can extract the statistics for a running context. But data
> counters are cumulating. To compute the sum properly, there are but two
> options:
> # Either the GPRS middleware requests kernel per-interface statistics right
> before destroying the interface, and sums with the earlier total.
> # Or the modem does it internally.

I know why you want this, but I'm still against the counter being an oFono 
driver API.  There needs to be a proper kernel interface that signals the 
application when an interface has gone away with the rx/tx details.  This way 
we handle this generically for all modems without relying on some intrinsic 
hardware capabilities.

The rx/tx counter not being reported via PropertyChanged is also a bad idea 
since it breaks our API conventions.  I can deal with a one-time signal being 
emitted when the interface has gone away though.

Regards,
-Denis

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

* RE: GPRS support for Ofono
  2009-09-02 16:26         ` Denis Kenzior
@ 2009-09-02 17:39           ` Bastian, Waldo
  2009-09-02 17:46             ` Denis Kenzior
  0 siblings, 1 reply; 42+ messages in thread
From: Bastian, Waldo @ 2009-09-02 17:39 UTC (permalink / raw)
  To: ofono

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

> > > This really belong in the kernel.  Only the kernel can reliably know
> > > when a network interface has been brought down and notify the 
> > > interested applications with the statistics.
> >
> > You're missing the point.
> >
> > Yes, any body can extract the statistics for a running context. But data
> > counters are cumulating. To compute the sum properly, there are but two
> > options:
> > # Either the GPRS middleware requests kernel per-interface statistics
> > right before destroying the interface, and sums with the earlier total.
> > # Or the modem does it internally.
> 
> I know why you want this, but I'm still against the counter being an oFono
> driver API.  There needs to be a proper kernel interface that signals the
> application when an interface has gone away with the rx/tx details.  This
> way we handle this generically for all modems without relying on some
> intrinsic hardware capabilities.

This still doesn't solve the case where the modem is accessed from a PC client and forwards PPP data as that data will not go through any network interface, e.g. BT DUN or USB tethering.

The modem is really in the best position to provide the most reliable information on data usage. You can still use statistics from the network interfaces as a fall-back in case the modem can not provide this information.

Cheers,
Waldo

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

* Re: GPRS support for Ofono
  2009-09-02 17:39           ` Bastian, Waldo
@ 2009-09-02 17:46             ` Denis Kenzior
  2009-09-02 18:41               ` Bastian, Waldo
  0 siblings, 1 reply; 42+ messages in thread
From: Denis Kenzior @ 2009-09-02 17:46 UTC (permalink / raw)
  To: ofono

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

Hi Waldo,

> > I know why you want this, but I'm still against the counter being an
> > oFono driver API.  There needs to be a proper kernel interface that
> > signals the application when an interface has gone away with the rx/tx
> > details.  This way we handle this generically for all modems without
> > relying on some intrinsic hardware capabilities.
>
> This still doesn't solve the case where the modem is accessed from a PC
> client and forwards PPP data as that data will not go through any network
> interface, e.g. BT DUN or USB tethering.

The cases you describe imply that oFono is not even in control of the gprs 
context.  How would we track/report the tx/rx statistics in that case?

>
> The modem is really in the best position to provide the most reliable
> information on data usage. You can still use statistics from the network
> interfaces as a fall-back in case the modem can not provide this
> information.

I don't disagree, but not every modem can track these statistics and this 
isn't described by 27.007.  I suggest the initial support should be enabled by 
the modem driver implementing a custom D-Bus interface and expose these 
details however it wishes.

Regards,
-Denis

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

* RE: GPRS support for Ofono
  2009-09-02 13:01         ` Marcel Holtmann
@ 2009-09-02 17:51           ` Bastian, Waldo
  2009-09-02 20:40             ` Marcel Holtmann
  0 siblings, 1 reply; 42+ messages in thread
From: Bastian, Waldo @ 2009-09-02 17:51 UTC (permalink / raw)
  To: ofono

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

> > > I am still not seeing the point in what suspended will do for us and
> > > the UI. And that Maemo 5 exposed such a state in the UI is not an 
> > > argument to keep doing it. I asked this before, what are we suppose to 
> > > be doing when we get signaled suspended?
> >
> > User, as well as intelligent (connectivity-aware) applications, need to
> > know about this so that they understand why "Internet" is momentarily
> > broken. It's as simple as that.

+1

> > Oh we could also use the network device carrier flag, and then use
> > Netlink (and we probably should do that too), but we all know how 
> > horrible Netlink is from userland.
> 
> Using IFF_RUNNING and IFF_LOWER_UP sounds more reasonable then some
> suspended state.

IF_OPER_DORMANT seems a more accurate reflection of the state.

Cheers,
Waldo

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

* RE: GPRS support for Ofono
  2009-09-02 17:46             ` Denis Kenzior
@ 2009-09-02 18:41               ` Bastian, Waldo
  2009-09-02 21:01                 ` Marcel Holtmann
  0 siblings, 1 reply; 42+ messages in thread
From: Bastian, Waldo @ 2009-09-02 18:41 UTC (permalink / raw)
  To: ofono

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

> > > I know why you want this, but I'm still against the counter being an
> > > oFono driver API.  There needs to be a proper kernel interface that
> > > signals the application when an interface has gone away with the rx/tx
> > > details.  This way we handle this generically for all modems without
> > > relying on some intrinsic hardware capabilities.
> >
> > This still doesn't solve the case where the modem is accessed from a PC
> > client and forwards PPP data as that data will not go through any
> > network interface, e.g. BT DUN or USB tethering.
> 
> The cases you describe imply that oFono is not even in control of the gprs
> context.  How would we track/report the tx/rx statistics in that case?

It's probably difficult if the PC client is allowed to redefine GPRS contexts, but otherwise oFono should at least be able to report the total tx/rx for the context's it has defined. The BT DUN / USB bridge could call into oFono and trigger a poll of all the stats to update them, e.g. when a BT DUN connection is disconnected.

> > The modem is really in the best position to provide the most reliable
> > information on data usage. You can still use statistics from the network
> > interfaces as a fall-back in case the modem can not provide this
> > information.
> 
> I don't disagree, but not every modem can track these statistics and this
> isn't described by 27.007.  I suggest the initial support should be
> enabled by the modem driver implementing a custom D-Bus interface and 
> expose these details however it wishes.

The modem driver has no desires of its own :-) It really comes down to what the UI needs and I doubt that the UI wants to deal with this on a modem by modem basis, but sure it's a possibility.

Cheers,
Waldo

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

* Re: GPRS support for Ofono
  2009-09-02 20:37             ` Marcel Holtmann
@ 2009-09-02 20:36               ` Denis Kenzior
  2009-09-02 21:09                 ` Marcel Holtmann
  0 siblings, 1 reply; 42+ messages in thread
From: Denis Kenzior @ 2009-09-02 20:36 UTC (permalink / raw)
  To: ofono

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

Hi Marcel,
> > >> The reason is simple, Nokia modems suspend GPRS when scanning (or
> > >> registering), simply because the operation will take roughly three
> > >> times as long with GPRS attached. You will find this feature in
> > >> current phones, too.
> > >
> > > Then ideally you should have two scan modes, periodic and user
> > > initiated.  For periodic mode we don't care how long it takes.
> >
> > +1
>
> Sounds like a plan. So we do need an /etc/ofono/main.conf :)

So my current thinking is to introduce a method to NetworkRegistration 
property called 'ProposeOperatorScan' and a new property called 
'OperatorScanInterval'.  The driver api can then support a (non-standard 
*gasp*) option to say whether this scan was initiated actively or not.

Maybe the Nokia modems can use this information not to drop the GPRS link if 
it isn't an active scan being performed.

Regards,
-Denis

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

* Re: GPRS support for Ofono
  2009-09-02 15:42           ` Aki Niemi
@ 2009-09-02 20:37             ` Marcel Holtmann
  2009-09-02 20:36               ` Denis Kenzior
  0 siblings, 1 reply; 42+ messages in thread
From: Marcel Holtmann @ 2009-09-02 20:37 UTC (permalink / raw)
  To: ofono

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

Hi Aki,

> >> AFAIK, attach status of GPRS has both regulatory aspects to consider
> >> (some operators require always attached vs. some prohibit it) as well
> >> as power consumption issues (auto-attach might draw more power than
> >> on-demand, although there's an inverse effect on latency). These are
> >> issues you need to take into account, and higher layers in the stack
> >> definitely *need* to be aware of as well. Also, I don' t think oFono
> >> is the correct place for these decisions -> better expose a necessary
> >> API and let upper layers deal with it.
> >
> > I know you guys are coming from mobile phone perspective, but that one isn't
> > the only scenario.  We have netbooks/laptops with gprs data cards to consider
> > as well.  Hardcoding operator requirements is also not an option, since SIM
> > cards can be changed.
> >
> > I fundamentally disagree that the logic should be in the higher layers.  oFono
> > has all the information to handle this, and can be hinted on what is
> > appropriate behavior easily enough.  oFono should simply store the auto-attach
> > preferences in its IMSI-indexed preference store.  The operator can bootstrap
> > these preferences if required.
> 
> Operator requirements were only half of the story. You need to be able
> to disable auto-attach in low power conditions, and this logic
> definitely doesn't belong in oFono. This applies equally well to
> mobile phones as it does to laptops/netbooks.

this a different requirement. Where do you get your low power
information from? I would prefer that we add a plugin that gets informed
of this low power situation and then is able to adjust such things.

I am against exposing this in user application/UI API. I am with you
that such requirements have to be met, but not via the D-Bus API. So
these kind of policy details are device/manufacturer specific and having
a custom plugins that can be enabled by the integrator sounds best to me
if a config file is not flexible enough.

> >> In general, I appreciate the attempt to hide ugly details from
> >> applications, but unfortunately some things can't well be hidden.
> >> Another unrelated, but similar issue is network scanning. It just
> >> isn't going to work without us exposing it in the D-Bus API
> >> explicitly.
> >>
> >
> > Modem drivers will have some control over whether the scan is performed
> > automatically, but denying the capability for everyone is not the right thing
> > to do either.
> 
> Agree, and I don't think that was what I was suggesting either.
> 
> >> The reason is simple, Nokia modems suspend GPRS when scanning (or
> >> registering), simply because the operation will take roughly three
> >> times as long with GPRS attached. You will find this feature in
> >> current phones, too.
> >
> > Then ideally you should have two scan modes, periodic and user initiated.  For
> > periodic mode we don't care how long it takes.
> 
> +1

Sounds like a plan. So we do need an /etc/ofono/main.conf :)

Regards

Marcel



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

* RE: GPRS support for Ofono
  2009-09-02 17:51           ` Bastian, Waldo
@ 2009-09-02 20:40             ` Marcel Holtmann
  0 siblings, 0 replies; 42+ messages in thread
From: Marcel Holtmann @ 2009-09-02 20:40 UTC (permalink / raw)
  To: ofono

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

Hi Waldo,

> > > > I am still not seeing the point in what suspended will do for us and
> > > > the UI. And that Maemo 5 exposed such a state in the UI is not an 
> > > > argument to keep doing it. I asked this before, what are we suppose to 
> > > > be doing when we get signaled suspended?
> > >
> > > User, as well as intelligent (connectivity-aware) applications, need to
> > > know about this so that they understand why "Internet" is momentarily
> > > broken. It's as simple as that.
> 
> +1

they need to know if they can do something useful with this information.
If not, then this state is just pointless. However the D-Bus API is the
wrong location for this detail.

> > > Oh we could also use the network device carrier flag, and then use
> > > Netlink (and we probably should do that too), but we all know how 
> > > horrible Netlink is from userland.
> > 
> > Using IFF_RUNNING and IFF_LOWER_UP sounds more reasonable then some
> > suspended state.
> 
> IF_OPER_DORMANT seems a more accurate reflection of the state.

Yep. That sounds good. We don't use that in ConnMan right now, but that
can be fixed of course. I still need to figure out what we are suppose
to do when this gets signaled to us.

Regards

Marcel



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

* Re: GPRS support for Ofono
  2009-09-02 15:38       ` =?unknown-8bit?q?R=C3=A9mi?= Denis-Courmont
  2009-09-02 16:26         ` Denis Kenzior
@ 2009-09-02 20:53         ` Marcel Holtmann
  1 sibling, 0 replies; 42+ messages in thread
From: Marcel Holtmann @ 2009-09-02 20:53 UTC (permalink / raw)
  To: ofono

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

Hi Remi,

> > Actually this one is missing from the API proposal.  Marcel already wanted
> > the context type (internet, mms, wap, etc) information.  I've updated the
> > proposed API in git.
> 
> This is not going to work.
> 
> Depending on the operator, you may have more than one "type" for a single 
> context (e.g. WAP+MMS), or worse, multiple contexts of the same type (e.g. 
> Internet with only Web and Internet with full IP).

we might need some extra work here and define what we want. I am
confident that we can break this down to something useful. Worst case we
something free form.

> > As discussed previously, we want oFono to manage this data, since it can do
> > this by using the IMSI.  So if you insert a different operator SIM your APN
> > settings are magically updated for that operator.
> 
> I have a feeling this does not work either. If I upgrade my subscription, the 
> APN may change while not the IMSI, no?

We can update these details at any time. Storing them on a per ISMI
basis is a good idea and something new that oFono does (as far as what I
have seen). So if you switch SIM cards, then you don't have to worry
about anything when traveling. It does the right thing you configured.

Especially with the devices like the Nokia netbook and the iPhone where
you can easily switch SIM cards without power on/off this will come in
handy.

If an upgrade of the subscription needs manual interaction from the user
or an operator message to update the settings, then that is fine. Since
the user did something to begin with. So they are aware of that
something changed (hope the operator told them). While just switching a
SIM card and by accident using a wrong APN and causing expensive roaming
would be a worse thing. Especially since there is an expectation from
the user when switching SIM cards.

> > > In my proposal the "Status" variable was a three-state variable,
> > > having the states "attached", "detached" and "suspended". "Suspended"
> > > was specified to mean that the GPRS was attached, but temporarily not
> > > available (for instance because of a 2G phone call or temporary loss
> > > of cellular connectivity). In the IRC discussion someone said that
> > > this property would not be part of Denis's API because the tri-state
> > > variables were bad and the "suspended" status was not supported by
> >
> > So the general rule is that if a feature isn't explicitly allowed in
> > 27.007, we do not support it.  There are exceptions to this of course. 
> > 27.007 only supports two states for context: activated and deactivated.
> 
> Our general rule is that if we have a UI requirement, or better an actual use 
> case for it, we support it. Suspended GPRS fits both.

Can you share these UI requirements with us.

> > > spec 27.007. However, the problem is that Maemo 5 already has UI
> > > support for indicating that the connection is suspended, and that
> > > makes it harder to drop the feature. Could the "suspended" status enum
> > > still be left there, and just have the modems that don't support the
> > > feature to never go to "suspended" mode?
> >
> > I'd rather not.
> >
> > If this feature is really required, then some sort of heuristic can be
> > applied.  (e.g. Powered on, Attached on, but context is deactivated most
> > likely means temporary unavailability of resources)
> 
> Is this some kind of joke? Don't you know the difference between pause and 
> stop on your MP3 player and between suspend to memory and power off on your 
> computer?
> 
> Second guessing does not fit in my definition of "easy to use self-
> documenting" for an API.
> 
> > This really belong in the kernel.  Only the kernel can reliably know when a
> > network interface has been brought down and notify the interested
> > applications with the statistics.
> 
> You're missing the point.
> 
> Yes, any body can extract the statistics for a running context. But data 
> counters are cumulating. To compute the sum properly, there are but two 
> options:
> # Either the GPRS middleware requests kernel per-interface statistics right 
> before destroying the interface, and sums with the earlier total.
> # Or the modem does it internally.
> 
> There is no way some random userland interface application can do it just by 
> requesting the kernel, since it cannot know when to request those statistics.

So my 2 cents here are that whatever so modem does for statistics it
should match the details its exports via the networking interface.

And on the kernel part and destroyed interface, as I mentioned, we need
to discuss this with the kernel guys. I wanna get an answer what can be
done to help us. We have most kernel guys at netconf in Portland in
three weeks and I gonna check with them.

> > Nokia hardware supports this explicitly, but many others don't.
> 
> That's irrelevant. Hardware support helps in the sense that it can include 
> statistics for contexts external to Ofono. If the hardware does not support 
> it, then it needs to be done manually in the GPRS middleware.
> 
> That won't make the requirement go away.

What do you expect middleware to do exactly. Our problem is that we
loose the latest state of statistics when interface destroyed. If that
can be fixed inside the kernel, why work around in user space. In case
it can not be fixed and solved to what we need then we revisit this
proposal. Until then we should put this on hold.

Regards

Marcel



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

* RE: GPRS support for Ofono
  2009-09-02 18:41               ` Bastian, Waldo
@ 2009-09-02 21:01                 ` Marcel Holtmann
  2009-09-02 21:10                   ` =?unknown-8bit?q?R=C3=A9mi?= Denis-Courmont
  0 siblings, 1 reply; 42+ messages in thread
From: Marcel Holtmann @ 2009-09-02 21:01 UTC (permalink / raw)
  To: ofono

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

Hi Waldo,

> > > > I know why you want this, but I'm still against the counter being an
> > > > oFono driver API.  There needs to be a proper kernel interface that
> > > > signals the application when an interface has gone away with the rx/tx
> > > > details.  This way we handle this generically for all modems without
> > > > relying on some intrinsic hardware capabilities.
> > >
> > > This still doesn't solve the case where the modem is accessed from a PC
> > > client and forwards PPP data as that data will not go through any
> > > network interface, e.g. BT DUN or USB tethering.
> > 
> > The cases you describe imply that oFono is not even in control of the gprs
> > context.  How would we track/report the tx/rx statistics in that case?
> 
> It's probably difficult if the PC client is allowed to redefine GPRS contexts, but otherwise oFono should at least be able to report the total tx/rx for the context's it has defined. The BT DUN / USB bridge could call into oFono and trigger a poll of all the stats to update them, e.g. when a BT DUN connection is disconnected.

how should it do this if oFono is not in the mix. If you are using
Bluetooth DUN and point it to a virtual TTY, then you are out of look.
If using USB CDC ACM then same applies.

The real solution here is Bluetooth PAN and USB CDC Ether which do
properly interact with the networking stack.

> > > The modem is really in the best position to provide the most reliable
> > > information on data usage. You can still use statistics from the network
> > > interfaces as a fall-back in case the modem can not provide this
> > > information.
> > 
> > I don't disagree, but not every modem can track these statistics and this
> > isn't described by 27.007.  I suggest the initial support should be
> > enabled by the modem driver implementing a custom D-Bus interface and 
> > expose these details however it wishes.
> 
> The modem driver has no desires of its own :-) It really comes down to what the UI needs and I doubt that the UI wants to deal with this on a modem by modem basis, but sure it's a possibility.

The current consent is that we might send a one time signal with all
statistics details once the interface goes away. Or we can make the
kernel help us here.

However I prefer that we sit this out a little and play with what is
possible before knocking down an API. I am not even sure what different
hardware would give us and how things need to work. I don't see us
having enough information to understand what is needed from a hardware,
driver or oFono core point of view.

Regards

Marcel



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

* Re: GPRS support for Ofono
  2009-09-02 20:36               ` Denis Kenzior
@ 2009-09-02 21:09                 ` Marcel Holtmann
  0 siblings, 0 replies; 42+ messages in thread
From: Marcel Holtmann @ 2009-09-02 21:09 UTC (permalink / raw)
  To: ofono

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

Hi Denis,

> > > >> The reason is simple, Nokia modems suspend GPRS when scanning (or
> > > >> registering), simply because the operation will take roughly three
> > > >> times as long with GPRS attached. You will find this feature in
> > > >> current phones, too.
> > > >
> > > > Then ideally you should have two scan modes, periodic and user
> > > > initiated.  For periodic mode we don't care how long it takes.
> > >
> > > +1
> >
> > Sounds like a plan. So we do need an /etc/ofono/main.conf :)
> 
> So my current thinking is to introduce a method to NetworkRegistration 
> property called 'ProposeOperatorScan' and a new property called 
> 'OperatorScanInterval'.  The driver api can then support a (non-standard 
> *gasp*) option to say whether this scan was initiated actively or not.
> 
> Maybe the Nokia modems can use this information not to drop the GPRS link if 
> it isn't an active scan being performed.

I really prefer if we put this into /etc/ofono/main.conf since the UI
should not configure this at all. It is more a one time setting based on
what the integrator expects as a behavior.

Regards

Marcel



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

* Re: GPRS support for Ofono
  2009-09-02 21:01                 ` Marcel Holtmann
@ 2009-09-02 21:10                   ` =?unknown-8bit?q?R=C3=A9mi?= Denis-Courmont
  2009-09-02 21:18                     ` Marcel Holtmann
  0 siblings, 1 reply; 42+ messages in thread
From: =?unknown-8bit?q?R=C3=A9mi?= Denis-Courmont @ 2009-09-02 21:10 UTC (permalink / raw)
  To: ofono

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

Le jeudi 3 septembre 2009 00:01:03 Marcel Holtmann, vous avez écrit :
> > It's probably difficult if the PC client is allowed to redefine GPRS
> > contexts, but otherwise oFono should at least be able to report the total
> > tx/rx for the context's it has defined. The BT DUN / USB bridge could
> > call into oFono and trigger a poll of all the stats to update them, e.g.
> > when a BT DUN connection is disconnected.
>
> how should it do this if oFono is not in the mix. If you are using
> Bluetooth DUN and point it to a virtual TTY, then you are out of look.
> If using USB CDC ACM then same applies.
>
> The real solution here is Bluetooth PAN and USB CDC Ether which do
> properly interact with the networking stack.

When we have patched all the Windows PC of the world, we can consider it.

In the mean time, AT+PPP emulation is required. Some modems do provide data 
counters including that. I've seen it as a requirement that I would rather 
have avoided but could not. It's ugly and arguably stupid, but required 
anyway. In fact, if Ofono won't do it, ConnMan will have to, which is probably 
by all means worse.

You can argue that it should be a driver-specific feature, but it has to be 
there. Hence, I would guess that more than one driver will support eventually, 
at which point it should probably be in the common API.

-- 
Rémi Denis-Courmont
http://www.remlab.net/

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

* Re: GPRS support for Ofono
  2009-09-02 21:10                   ` =?unknown-8bit?q?R=C3=A9mi?= Denis-Courmont
@ 2009-09-02 21:18                     ` Marcel Holtmann
  0 siblings, 0 replies; 42+ messages in thread
From: Marcel Holtmann @ 2009-09-02 21:18 UTC (permalink / raw)
  To: ofono

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

Hi Remi,

> > > It's probably difficult if the PC client is allowed to redefine GPRS
> > > contexts, but otherwise oFono should at least be able to report the total
> > > tx/rx for the context's it has defined. The BT DUN / USB bridge could
> > > call into oFono and trigger a poll of all the stats to update them, e.g.
> > > when a BT DUN connection is disconnected.
> >
> > how should it do this if oFono is not in the mix. If you are using
> > Bluetooth DUN and point it to a virtual TTY, then you are out of look.
> > If using USB CDC ACM then same applies.
> >
> > The real solution here is Bluetooth PAN and USB CDC Ether which do
> > properly interact with the networking stack.
> 
> When we have patched all the Windows PC of the world, we can consider it.

my approach would be to try and see how far we get this pushing towards
PAN and CDC Ether :)

> In the mean time, AT+PPP emulation is required. Some modems do provide data 
> counters including that. I've seen it as a requirement that I would rather 
> have avoided but could not. It's ugly and arguably stupid, but required 
> anyway. In fact, if Ofono won't do it, ConnMan will have to, which is probably 
> by all means worse.

Actually it is worth for high-speed modems with a network interface and
no internal PPP emulation, we would have to do that emulation somewhere
in the host stack. And now my brain hurts :(

> You can argue that it should be a driver-specific feature, but it has to be 
> there. Hence, I would guess that more than one driver will support eventually, 
> at which point it should probably be in the common API.

We have to figure something out, but right I would prefer if we GPRS up
and running and after that tackle the statistics part. Since without
GPRS, we don't need the statistics ;)

Regards

Marcel



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

end of thread, other threads:[~2009-09-02 21:18 UTC | newest]

Thread overview: 42+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-09-01 11:09 GPRS support for Ofono Ismo Puustinen
2009-09-01 19:02 ` Jean-Christian de Rivaz
2009-09-01 19:25   ` =?unknown-8bit?q?R=C3=A9mi?= Denis-Courmont
2009-09-01 20:17     ` Jean-Christian de Rivaz
2009-09-01 20:26       ` =?unknown-8bit?q?R=C3=A9mi?= Denis-Courmont
2009-09-01 20:30       ` Christensen, Mikkel
2009-09-01 19:27   ` Christensen, Mikkel
2009-09-01 21:36 ` Denis Kenzior
2009-09-01 22:42   ` Marcel Holtmann
2009-09-01 22:50     ` Denis Kenzior
2009-09-02  6:39     ` =?unknown-8bit?q?R=C3=A9mi?= Denis-Courmont
2009-09-02  9:16       ` Marcel Holtmann
2009-09-02  9:22         ` =?unknown-8bit?q?R=C3=A9mi?= Denis-Courmont
2009-09-02 10:43           ` Aki Niemi
2009-09-02 11:03             ` Marcel Holtmann
2009-09-02 11:19               ` =?unknown-8bit?q?R=C3=A9mi?= Denis-Courmont
2009-09-02 11:30   ` Ismo Puustinen
2009-09-02 12:02     ` Marcel Holtmann
2009-09-02 12:34       ` Aki Niemi
2009-09-02 12:46         ` Marcel Holtmann
2009-09-02 12:51           ` =?unknown-8bit?q?R=C3=A9mi?= Denis-Courmont
2009-09-02 15:28         ` Denis Kenzior
2009-09-02 15:42           ` Aki Niemi
2009-09-02 20:37             ` Marcel Holtmann
2009-09-02 20:36               ` Denis Kenzior
2009-09-02 21:09                 ` Marcel Holtmann
2009-09-02 12:46       ` =?unknown-8bit?q?R=C3=A9mi?= Denis-Courmont
2009-09-02 13:01         ` Marcel Holtmann
2009-09-02 17:51           ` Bastian, Waldo
2009-09-02 20:40             ` Marcel Holtmann
2009-09-02 15:00     ` Denis Kenzior
2009-09-02 15:32       ` Aki Niemi
2009-09-02 15:36         ` Denis Kenzior
2009-09-02 15:38       ` =?unknown-8bit?q?R=C3=A9mi?= Denis-Courmont
2009-09-02 16:26         ` Denis Kenzior
2009-09-02 17:39           ` Bastian, Waldo
2009-09-02 17:46             ` Denis Kenzior
2009-09-02 18:41               ` Bastian, Waldo
2009-09-02 21:01                 ` Marcel Holtmann
2009-09-02 21:10                   ` =?unknown-8bit?q?R=C3=A9mi?= Denis-Courmont
2009-09-02 21:18                     ` Marcel Holtmann
2009-09-02 20:53         ` Marcel Holtmann

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.