All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH_v6 0/5]  Private network request to ConnMan
@ 2011-05-19  9:58 Guillaume Zajac
  2011-05-19  9:58 ` [PATCH_v6 1/5] gatppp: Add new contructor to use external fd Guillaume Zajac
                   ` (4 more replies)
  0 siblings, 5 replies; 13+ messages in thread
From: Guillaume Zajac @ 2011-05-19  9:58 UTC (permalink / raw)
  To: ofono

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

Hi,

With subject and blurb :)
I forgot to close fd when ppp_net_new() returns NULL.
This version include this change.

Guillaume Zajac (5):
  gatppp: Add new contructor to use external fd
  private-network: add header into include and Makefile.am
  private-network: add request/release functions and new feature to
    Makefile.am
  emulator: add request/release private network calls
  connman: add plugin in oFono to request/release private network

 Makefile.am               |   10 +-
 gatchat/gatppp.c          |   33 +++++-
 gatchat/gatppp.h          |    1 +
 gatchat/ppp.h             |    2 +-
 gatchat/ppp_net.c         |   47 +++++---
 include/private-network.h |   56 +++++++++
 plugins/connman.c         |  299 +++++++++++++++++++++++++++++++++++++++++++++
 src/emulator.c            |   75 ++++++++++--
 src/ofono.h               |    6 +
 src/private-network.c     |   91 ++++++++++++++
 10 files changed, 590 insertions(+), 30 deletions(-)
 create mode 100644 include/private-network.h
 create mode 100644 plugins/connman.c
 create mode 100644 src/private-network.c


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

* [PATCH_v6 1/5] gatppp: Add new contructor to use external fd
  2011-05-19  9:58 [PATCH_v6 0/5] Private network request to ConnMan Guillaume Zajac
@ 2011-05-19  9:58 ` Guillaume Zajac
  2011-05-25 10:36   ` Denis Kenzior
  2011-05-19  9:58 ` [PATCH_v6 2/5] private-network: add header into include and Makefile.am Guillaume Zajac
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 13+ messages in thread
From: Guillaume Zajac @ 2011-05-19  9:58 UTC (permalink / raw)
  To: ofono

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

---
 gatchat/gatppp.c  |   33 ++++++++++++++++++++++++++++++++-
 gatchat/gatppp.h  |    1 +
 gatchat/ppp.h     |    2 +-
 gatchat/ppp_net.c |   47 ++++++++++++++++++++++++++++++++---------------
 4 files changed, 66 insertions(+), 17 deletions(-)

diff --git a/gatchat/gatppp.c b/gatchat/gatppp.c
index c776811..1f2d227 100644
--- a/gatchat/gatppp.c
+++ b/gatchat/gatppp.c
@@ -78,6 +78,7 @@ struct _GAtPPP {
 	guint ppp_dead_source;
 	GAtSuspendFunc suspend_func;
 	gpointer suspend_data;
+	int fd;
 };
 
 void ppp_debug(GAtPPP *ppp, const char *str)
@@ -290,7 +291,7 @@ void ppp_auth_notify(GAtPPP *ppp, gboolean success)
 void ppp_ipcp_up_notify(GAtPPP *ppp, const char *local, const char *peer,
 					const char *dns1, const char *dns2)
 {
-	ppp->net = ppp_net_new(ppp);
+	ppp->net = ppp_net_new(ppp, ppp->fd);
 
 	if (ppp->net == NULL) {
 		ppp->disconnect_reason = G_AT_PPP_REASON_NET_FAIL;
@@ -316,6 +317,7 @@ void ppp_ipcp_down_notify(GAtPPP *ppp)
 		return;
 
 	ppp_net_free(ppp->net);
+	ppp->fd = -1;
 	ppp->net = NULL;
 }
 
@@ -522,6 +524,8 @@ void g_at_ppp_unref(GAtPPP *ppp)
 
 	if (ppp->net)
 		ppp_net_free(ppp->net);
+	else if (ppp->fd >= 0)
+		close(ppp->fd);
 
 	if (ppp->chap)
 		ppp_chap_free(ppp->chap);
@@ -565,6 +569,8 @@ static GAtPPP *ppp_init_common(GAtHDLC *hdlc, gboolean is_server, guint32 ip)
 
 	ppp->ref_count = 1;
 
+	ppp->fd = -1;
+
 	/* set options to defaults */
 	ppp->mru = DEFAULT_MRU;
 	ppp->mtu = DEFAULT_MTU;
@@ -657,3 +663,28 @@ GAtPPP *g_at_ppp_server_new_from_io(GAtIO *io, const char *local)
 
 	return ppp;
 }
+
+GAtPPP *g_at_ppp_server_new_full(GAtIO *io, const char *local, int fd)
+{
+	GAtHDLC *hdlc;
+	GAtPPP *ppp;
+	guint32 ip;
+
+	if (local == NULL)
+		ip = 0;
+	else if (inet_pton(AF_INET, local, &ip) != 1)
+		return NULL;
+
+	hdlc = g_at_hdlc_new_from_io(io);
+	if (hdlc == NULL)
+		return NULL;
+
+	ppp = ppp_init_common(hdlc, TRUE, ip);
+
+	/* Set the fd value returned by ConnMan */
+	ppp->fd = fd;
+
+	g_at_hdlc_unref(hdlc);
+
+	return ppp;
+}
diff --git a/gatchat/gatppp.h b/gatchat/gatppp.h
index 9464ffd..365123a 100644
--- a/gatchat/gatppp.h
+++ b/gatchat/gatppp.h
@@ -54,6 +54,7 @@ GAtPPP *g_at_ppp_new(GIOChannel *modem);
 GAtPPP *g_at_ppp_new_from_io(GAtIO *io);
 GAtPPP *g_at_ppp_server_new(GIOChannel *modem, const char *local);
 GAtPPP *g_at_ppp_server_new_from_io(GAtIO *io, const char *local);
+GAtPPP *g_at_ppp_server_new_full(GAtIO *io, const char *local, int fd);
 
 void g_at_ppp_open(GAtPPP *ppp);
 void g_at_ppp_set_connect_function(GAtPPP *ppp, GAtPPPConnectFunc callback,
diff --git a/gatchat/ppp.h b/gatchat/ppp.h
index 22809d8..f866944 100644
--- a/gatchat/ppp.h
+++ b/gatchat/ppp.h
@@ -102,7 +102,7 @@ void ppp_chap_free(struct ppp_chap *chap);
 void ppp_chap_process_packet(struct ppp_chap *chap, const guint8 *new_packet);
 
 /* TUN / Network related functions */
-struct ppp_net *ppp_net_new(GAtPPP *ppp);
+struct ppp_net *ppp_net_new(GAtPPP *ppp, int fd);
 const char *ppp_net_get_interface(struct ppp_net *net);
 void ppp_net_process_packet(struct ppp_net *net, const guint8 *packet);
 void ppp_net_free(struct ppp_net *net);
diff --git a/gatchat/ppp_net.c b/gatchat/ppp_net.c
index 25bcfa4..52b3554 100644
--- a/gatchat/ppp_net.c
+++ b/gatchat/ppp_net.c
@@ -123,35 +123,52 @@ const char *ppp_net_get_interface(struct ppp_net *net)
 	return net->if_name;
 }
 
-struct ppp_net *ppp_net_new(GAtPPP *ppp)
+struct ppp_net *ppp_net_new(GAtPPP *ppp, int fd)
 {
 	struct ppp_net *net;
 	GIOChannel *channel = NULL;
 	struct ifreq ifr;
-	int fd, err;
+	int err;
 
 	net = g_try_new0(struct ppp_net, 1);
-	if (net == NULL)
+	if (net == NULL) {
+		if (fd >= 0)
+			close(fd);
+
 		return NULL;
+	}
 
 	net->ppp_packet = ppp_packet_new(MAX_PACKET, PPP_IP_PROTO);
 	if (net->ppp_packet == NULL) {
+		if (fd >= 0)
+			close(fd);
+
 		g_free(net);
 		return NULL;
 	}
 
-	/* open a tun interface */
-	fd = open("/dev/net/tun", O_RDWR);
-	if (fd < 0)
-		goto error;
-
-	memset(&ifr, 0, sizeof(ifr));
-	ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
-	strcpy(ifr.ifr_name, "ppp%d");
-
-	err = ioctl(fd, TUNSETIFF, (void *) &ifr);
-	if (err < 0)
-		goto error;
+	/*
+	 * If the fd value is still the default one,
+	 * open the tun interface and configure it.
+	 */
+	if (fd < 0) {
+		/* open a tun interface */
+		fd = open("/dev/net/tun", O_RDWR);
+		if (fd < 0)
+			goto error;
+
+		memset(&ifr, 0, sizeof(ifr));
+		ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
+		strcpy(ifr.ifr_name, "ppp%d");
+
+		err = ioctl(fd, TUNSETIFF, (void *) &ifr);
+		if (err < 0)
+			goto error;
+	} else {
+		err = ioctl(fd, TUNGETIFF, (void *) &ifr);
+		if (err < 0)
+			goto error;
+	}
 
 	net->if_name = strdup(ifr.ifr_name);
 
-- 
1.7.1


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

* [PATCH_v6 2/5] private-network: add header into include and Makefile.am
  2011-05-19  9:58 [PATCH_v6 0/5] Private network request to ConnMan Guillaume Zajac
  2011-05-19  9:58 ` [PATCH_v6 1/5] gatppp: Add new contructor to use external fd Guillaume Zajac
@ 2011-05-19  9:58 ` Guillaume Zajac
  2011-05-25 10:38   ` Denis Kenzior
  2011-05-19  9:58 ` [PATCH_v6 3/5] private-network: add request/release functions and new feature to Makefile.am Guillaume Zajac
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 13+ messages in thread
From: Guillaume Zajac @ 2011-05-19  9:58 UTC (permalink / raw)
  To: ofono

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

---
 Makefile.am               |    4 +-
 include/private-network.h |   56 +++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 58 insertions(+), 2 deletions(-)
 create mode 100644 include/private-network.h

diff --git a/Makefile.am b/Makefile.am
index a413a47..d7e5626 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -16,8 +16,8 @@ pkginclude_HEADERS = include/log.h include/plugin.h include/history.h \
 			include/cdma-sms.h include/sim-auth.h \
 			include/gprs-provision.h include/emulator.h \
 			include/location-reporting.h \
-			include/cdma-connman.h \
-			include/gnss.h
+			include/cdma-connman.h include/gnss.h \
+			include/private-network.h
 
 nodist_pkginclude_HEADERS = include/version.h
 
diff --git a/include/private-network.h b/include/private-network.h
new file mode 100644
index 0000000..983bf5b
--- /dev/null
+++ b/include/private-network.h
@@ -0,0 +1,56 @@
+/*
+ *
+ *  oFono - Open Source Telephony
+ *
+ *  Copyright (C) 2008-2011  Intel Corporation. All rights reserved.
+ *
+ *  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_PRIVATE_NETWORK_H
+#define __OFONO_PRIVATE_NETWORK_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct ofono_private_network_settings {
+	int fd;
+	char *server_ip;
+	char *peer_ip;
+	char *primary_dns;
+	char *secondary_dns;
+};
+
+typedef void (ofono_private_network_cb_t)(
+		void *data,
+		const struct ofono_private_network_settings *settings);
+
+struct ofono_private_network_driver {
+	char *name;
+	int (*request)(ofono_private_network_cb_t cb, void *data);
+	void (*release)(int uid);
+};
+
+int ofono_private_network_driver_register(
+			const struct ofono_private_network_driver *d);
+void ofono_private_network_driver_unregister(
+			const struct ofono_private_network_driver *d);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __OFONO_PRIVATE_NETWORK_H */
-- 
1.7.1


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

* [PATCH_v6 3/5] private-network: add request/release functions and new feature to Makefile.am
  2011-05-19  9:58 [PATCH_v6 0/5] Private network request to ConnMan Guillaume Zajac
  2011-05-19  9:58 ` [PATCH_v6 1/5] gatppp: Add new contructor to use external fd Guillaume Zajac
  2011-05-19  9:58 ` [PATCH_v6 2/5] private-network: add header into include and Makefile.am Guillaume Zajac
@ 2011-05-19  9:58 ` Guillaume Zajac
  2011-05-25 10:38   ` Denis Kenzior
  2011-05-19  9:58 ` [PATCH_v6 4/5] emulator: add request/release private network calls Guillaume Zajac
  2011-05-19  9:58 ` [PATCH_v6 5/5] connman: add plugin in oFono to request/release private network Guillaume Zajac
  4 siblings, 1 reply; 13+ messages in thread
From: Guillaume Zajac @ 2011-05-19  9:58 UTC (permalink / raw)
  To: ofono

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

---
 Makefile.am           |    3 +-
 src/ofono.h           |    6 +++
 src/private-network.c |   91 +++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 99 insertions(+), 1 deletions(-)
 create mode 100644 src/private-network.c

diff --git a/Makefile.am b/Makefile.am
index d7e5626..e1eaf15 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -387,7 +387,8 @@ src_ofonod_SOURCES = $(gdbus_sources) $(builtin_sources) src/ofono.ver \
 			src/message.h src/message.c src/gprs-provision.c \
 			src/emulator.c src/location-reporting.c \
 			src/cdma-connman.c src/gnss.c \
-			src/gnssagent.c src/gnssagent.h
+			src/gnssagent.c src/gnssagent.h \
+			src/private-network.c
 
 src_ofonod_LDADD = $(builtin_libadd) @GLIB_LIBS@ @DBUS_LIBS@ @CAPNG_LIBS@ -ldl
 
diff --git a/src/ofono.h b/src/ofono.h
index 82d7e34..7353022 100644
--- a/src/ofono.h
+++ b/src/ofono.h
@@ -468,3 +468,9 @@ void __ofono_gprs_provision_free_settings(
 
 #include <ofono/emulator.h>
 #include <ofono/gnss.h>
+#include <ofono/private-network.h>
+
+void __ofono_private_network_release(int id);
+ofono_bool_t __ofono_private_network_request(ofono_private_network_cb_t cb,
+						void *data, int *id);
+
diff --git a/src/private-network.c b/src/private-network.c
new file mode 100644
index 0000000..e955656
--- /dev/null
+++ b/src/private-network.c
@@ -0,0 +1,91 @@
+/*
+ *
+ *  oFono - Open Source Telephony
+ *
+ *  Copyright (C) 2008-2011  Intel Corporation. All rights reserved.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+#include <glib.h>
+#include "ofono.h"
+
+static GSList *g_drivers = NULL;
+
+void __ofono_private_network_release(int id)
+{
+	GSList *d;
+
+	DBG("");
+
+	for (d = g_drivers; d; d = d->next) {
+		const struct ofono_private_network_driver *driver = d->data;
+
+		if (!driver->release)
+			continue;
+
+		driver->release(id);
+
+		break;
+	}
+}
+
+ofono_bool_t __ofono_private_network_request(ofono_private_network_cb_t cb,
+						void *data, int *id)
+{
+	GSList *d;
+	int uid;
+
+	DBG("");
+
+	for (d = g_drivers; d; d = d->next) {
+		const struct ofono_private_network_driver *driver = d->data;
+
+		if (!driver->request)
+			continue;
+
+		uid = driver->request(cb, data);
+		if (uid <= 0)
+			continue;
+
+		*id = uid;
+		return TRUE;
+	}
+
+	return FALSE;
+}
+
+int ofono_private_network_driver_register(
+			const struct ofono_private_network_driver *d)
+{
+	DBG("driver: %p, name: %s", d, d->name);
+
+	g_drivers = g_slist_prepend(g_drivers, (void *) d);
+
+	return 0;
+}
+
+void ofono_private_network_driver_unregister(
+			const struct ofono_private_network_driver *d)
+{
+	DBG("driver: %p, name: %s", d, d->name);
+
+	g_drivers = g_slist_remove(g_drivers, (void *) d);
+}
-- 
1.7.1


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

* [PATCH_v6 4/5] emulator: add request/release private network calls
  2011-05-19  9:58 [PATCH_v6 0/5] Private network request to ConnMan Guillaume Zajac
                   ` (2 preceding siblings ...)
  2011-05-19  9:58 ` [PATCH_v6 3/5] private-network: add request/release functions and new feature to Makefile.am Guillaume Zajac
@ 2011-05-19  9:58 ` Guillaume Zajac
  2011-05-25 10:46   ` Denis Kenzior
  2011-05-19  9:58 ` [PATCH_v6 5/5] connman: add plugin in oFono to request/release private network Guillaume Zajac
  4 siblings, 1 reply; 13+ messages in thread
From: Guillaume Zajac @ 2011-05-19  9:58 UTC (permalink / raw)
  To: ofono

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

---
 src/emulator.c |   75 ++++++++++++++++++++++++++++++++++++++++++++++++-------
 1 files changed, 65 insertions(+), 10 deletions(-)

diff --git a/src/emulator.c b/src/emulator.c
index c17b901..0a83403 100644
--- a/src/emulator.c
+++ b/src/emulator.c
@@ -25,6 +25,7 @@
 
 #include <stdio.h>
 #include <string.h>
+#include <unistd.h>
 
 #include <glib.h>
 
@@ -32,11 +33,7 @@
 #include "common.h"
 #include "gatserver.h"
 #include "gatppp.h"
-
-#define DUN_SERVER_ADDRESS     "192.168.1.1"
-#define DUN_PEER_ADDRESS       "192.168.1.2"
-#define DUN_DNS_SERVER_1       "10.10.10.10"
-#define DUN_DNS_SERVER_2       "10.10.10.11"
+#include "private-network.h"
 
 #define RING_TIMEOUT 3
 
@@ -56,6 +53,8 @@ struct ofono_emulator {
 	guint callsetup_source;
 	gboolean clip;
 	gboolean ccwa;
+	int pns_id;
+	struct ofono_private_network_settings *local_pns;
 };
 
 struct indicator {
@@ -91,6 +90,18 @@ static void ppp_connect(const char *iface, const char *local,
 	DBG("Secondary DNS Server: %s\n", dns2);
 }
 
+static void release_pns(struct ofono_emulator *em)
+{
+	g_free(em->local_pns->server_ip);
+	g_free(em->local_pns->peer_ip);
+	g_free(em->local_pns->primary_dns);
+	g_free(em->local_pns->secondary_dns);
+	g_free(em->local_pns);
+
+	__ofono_private_network_release(em->pns_id);
+	em->pns_id = 0;
+}
+
 static void ppp_disconnect(GAtPPPDisconnectReason reason, gpointer user_data)
 {
 	struct ofono_emulator *em = user_data;
@@ -100,6 +111,9 @@ static void ppp_disconnect(GAtPPPDisconnectReason reason, gpointer user_data)
 	g_at_ppp_unref(em->ppp);
 	em->ppp = NULL;
 
+	if (em->pns_id > 0)
+		release_pns(em);
+
 	if (em->server == NULL)
 		return;
 
@@ -128,14 +142,21 @@ static gboolean setup_ppp(gpointer user_data)
 
 	g_at_server_suspend(em->server);
 
-	em->ppp = g_at_ppp_server_new_from_io(io, DUN_SERVER_ADDRESS);
+	em->ppp = g_at_ppp_server_new_full(io, em->local_pns->server_ip,
+						em->local_pns->fd);
 	if (em->ppp == NULL) {
+		/* PPP stack hasn't closed fd */
+		close(em->local_pns->fd);
+		if (em->pns_id > 0)
+			release_pns(em);
+
 		g_at_server_resume(em->server);
 		return FALSE;
 	}
 
-	g_at_ppp_set_server_info(em->ppp, DUN_PEER_ADDRESS,
-					DUN_DNS_SERVER_1, DUN_DNS_SERVER_2);
+	g_at_ppp_set_server_info(em->ppp, em->local_pns->peer_ip,
+					em->local_pns->primary_dns,
+					em->local_pns->secondary_dns);
 
 	g_at_ppp_set_credentials(em->ppp, "", "");
 	g_at_ppp_set_debug(em->ppp, emulator_debug, "PPP");
@@ -147,6 +168,39 @@ static gboolean setup_ppp(gpointer user_data)
 	return FALSE;
 }
 
+static void request_private_network_cb(void *data,
+			const struct ofono_private_network_settings *pns)
+{
+	struct ofono_emulator *em = data;
+
+	if (pns == NULL) {
+		__ofono_private_network_release(em->pns_id);
+		em->pns_id = 0;
+		g_at_server_send_final(em->server, G_AT_SERVER_RESULT_ERROR);
+		return;
+	}
+
+	em->local_pns = g_try_new0(struct ofono_private_network_settings, 1);
+	if (em->local_pns == NULL) {
+		close(pns->fd);
+		__ofono_private_network_release(em->pns_id);
+		em->pns_id = 0;
+		g_at_server_send_final(em->server, G_AT_SERVER_RESULT_ERROR);
+		return;
+	}
+
+	em->local_pns->fd = pns->fd;
+	em->local_pns->server_ip = g_strdup(pns->server_ip);
+	em->local_pns->peer_ip = g_strdup(pns->peer_ip);
+	em->local_pns->primary_dns = g_strdup(pns->primary_dns);
+	em->local_pns->secondary_dns = g_strdup(pns->secondary_dns);
+
+	g_at_server_send_intermediate(em->server, "CONNECT");
+	em->source = g_idle_add(setup_ppp, em);
+
+	return;
+}
+
 static gboolean dial_call(struct ofono_emulator *em, const char *dial_str)
 {
 	char c = *dial_str;
@@ -154,8 +208,9 @@ static gboolean dial_call(struct ofono_emulator *em, const char *dial_str)
 	DBG("dial call %s", dial_str);
 
 	if (c == '*' || c == '#' || c == 'T' || c == 't') {
-		g_at_server_send_intermediate(em->server, "CONNECT");
-		em->source = g_idle_add(setup_ppp, em);
+		if (__ofono_private_network_request(request_private_network_cb,
+						em, &em->pns_id) == FALSE)
+			return FALSE;
 	}
 
 	return TRUE;
-- 
1.7.1


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

* [PATCH_v6 5/5] connman: add plugin in oFono to request/release private network
  2011-05-19  9:58 [PATCH_v6 0/5] Private network request to ConnMan Guillaume Zajac
                   ` (3 preceding siblings ...)
  2011-05-19  9:58 ` [PATCH_v6 4/5] emulator: add request/release private network calls Guillaume Zajac
@ 2011-05-19  9:58 ` Guillaume Zajac
  2011-06-02  2:53   ` Denis Kenzior
  4 siblings, 1 reply; 13+ messages in thread
From: Guillaume Zajac @ 2011-05-19  9:58 UTC (permalink / raw)
  To: ofono

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

---
 Makefile.am       |    3 +
 plugins/connman.c |  299 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 302 insertions(+), 0 deletions(-)
 create mode 100644 plugins/connman.c

diff --git a/Makefile.am b/Makefile.am
index e1eaf15..ffb85ae 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -339,6 +339,9 @@ builtin_sources += plugins/hfp_ag.c plugins/bluetooth.h
 builtin_modules += dun_gw
 builtin_sources += plugins/dun_gw.c plugins/bluetooth.h
 
+builtin_modules += connman
+builtin_sources += plugins/connman.c
+
 builtin_sources += $(btio_sources)
 builtin_cflags += @BLUEZ_CFLAGS@
 builtin_libadd += @BLUEZ_LIBS@
diff --git a/plugins/connman.c b/plugins/connman.c
new file mode 100644
index 0000000..5f0ad8a
--- /dev/null
+++ b/plugins/connman.c
@@ -0,0 +1,299 @@
+/*
+ *
+ *  oFono - Open Source Telephony
+ *
+ *  Copyright (C) 2008-2011  Intel Corporation. All rights reserved.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <errno.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <gdbus.h>
+#include <string.h>
+
+#include <ofono.h>
+#include <private-network.h>
+
+#define CONNMAN_SERVICE			"net.connman"
+#define CONNMAN_PATH			"/net/connman"
+
+#define CONNMAN_DEBUG_INTERFACE		CONNMAN_SERVICE ".Debug"
+#define CONNMAN_ERROR_INTERFACE		CONNMAN_SERVICE ".Error"
+#define CONNMAN_AGENT_INTERFACE		CONNMAN_SERVICE ".Agent"
+#define CONNMAN_COUNTER_INTERFACE	CONNMAN_SERVICE ".Counter"
+
+#define CONNMAN_MANAGER_INTERFACE	CONNMAN_SERVICE ".Manager"
+#define CONNMAN_MANAGER_PATH		"/"
+
+#define CONNMAN_TASK_INTERFACE		CONNMAN_SERVICE ".Task"
+#define CONNMAN_PROFILE_INTERFACE	CONNMAN_SERVICE ".Profile"
+#define CONNMAN_SERVICE_INTERFACE	CONNMAN_SERVICE ".Service"
+#define CONNMAN_PROVIDER_INTERFACE	CONNMAN_SERVICE ".Provider"
+#define CONNMAN_TECHNOLOGY_INTERFACE	CONNMAN_SERVICE ".Technology"
+#define CONNMAN_SESSION_INTERFACE	CONNMAN_SERVICE ".Session"
+#define CONNMAN_NOTIFICATION_INTERFACE	CONNMAN_SERVICE ".Notification"
+
+static DBusConnection *connection;
+static GHashTable *requests;
+static unsigned int id;
+
+struct pns_req {
+	int uid;
+	DBusPendingCall *pending;
+	ofono_private_network_cb_t *cb;
+	void *data;
+	gboolean redundant;
+	gboolean error;
+};
+
+static void request_reply(DBusPendingCall *call, void *user_data)
+{
+	struct pns_req *req = user_data;
+	struct ofono_private_network_settings pns;
+	DBusMessageIter array, dict, entry;
+	DBusMessage *reply;
+
+	DBG("");
+
+	pns.fd = -1;
+	pns.server_ip = NULL;
+	pns.peer_ip = NULL;
+	pns.primary_dns = NULL;
+	pns.secondary_dns = NULL;
+
+	/* request is no more pending */
+	req->pending = NULL;
+
+	reply = dbus_pending_call_steal_reply(call);
+	if (!reply)
+		goto error;
+
+	if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR)
+		goto error;
+
+	if (dbus_message_iter_init(reply, &array) == FALSE)
+		goto error;
+
+	if (dbus_message_iter_get_arg_type(&array) != DBUS_TYPE_UNIX_FD)
+		goto error;
+
+	dbus_message_iter_get_basic(&array, &pns.fd);
+	DBG("Fildescriptor = %d\n", pns.fd);
+
+	dbus_message_iter_next(&array);
+
+	if (dbus_message_iter_get_arg_type(&array) != DBUS_TYPE_ARRAY)
+		goto error;
+
+	dbus_message_iter_recurse(&array, &dict);
+
+	while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) {
+		DBusMessageIter iter;
+		const char *key;
+		int type;
+
+		dbus_message_iter_recurse(&dict, &entry);
+
+		dbus_message_iter_get_basic(&entry, &key);
+
+		dbus_message_iter_next(&entry);
+		dbus_message_iter_recurse(&entry, &iter);
+
+		type = dbus_message_iter_get_arg_type(&iter);
+		if (type != DBUS_TYPE_STRING)
+			break;
+
+		if (g_str_equal(key, "ServerIPv4")
+				&& type == DBUS_TYPE_STRING)
+			dbus_message_iter_get_basic(&iter, &pns.server_ip);
+		else if (g_str_equal(key, "PeerIPv4")
+				&& type == DBUS_TYPE_STRING)
+			dbus_message_iter_get_basic(&iter, &pns.peer_ip);
+		else if (g_str_equal(key, "PrimaryDNS")
+				&& type == DBUS_TYPE_STRING)
+			dbus_message_iter_get_basic(&iter, &pns.primary_dns);
+		else if (g_str_equal(key, "SecondaryDNS")
+				&& type == DBUS_TYPE_STRING)
+			dbus_message_iter_get_basic(&iter, &pns.secondary_dns);
+
+		dbus_message_iter_next(&dict);
+	}
+
+	if (req->redundant == TRUE)
+		goto done;
+
+	if (pns.server_ip == NULL || pns.peer_ip == NULL ||
+			pns.primary_dns == NULL || pns.secondary_dns == NULL ||
+			pns.fd < 0) {
+		ofono_error("Error while reading dictionnary...\n");
+		goto done;
+	}
+
+	req->cb(req->data, &pns);
+
+	dbus_message_unref(reply);
+	dbus_pending_call_unref(call);
+
+	return;
+
+error:
+	req->error = TRUE;
+done:
+	if (pns.fd >= 0)
+		close(pns.fd);
+
+	req->cb(req->data, NULL);
+
+	if (reply)
+		dbus_message_unref(reply);
+
+	dbus_pending_call_unref(call);
+}
+
+static int pns_request(ofono_private_network_cb_t cb, void *data)
+{
+	DBusMessage *message;
+	DBusPendingCall *call;
+	struct pns_req *req;
+
+	DBG("");
+
+	req = g_try_new(struct pns_req, 1);
+
+	if (req == NULL)
+		return -ENOMEM;
+
+	message = dbus_message_new_method_call(CONNMAN_SERVICE,
+				     CONNMAN_MANAGER_PATH,
+				     CONNMAN_MANAGER_INTERFACE,
+				     "RequestPrivateNetwork");
+
+	if (message == NULL) {
+		g_free(req);
+		return -ENOMEM;
+	}
+
+	if (dbus_connection_send_with_reply(connection,
+				message, &call, 5000) == FALSE) {
+		g_free(req);
+		dbus_message_unref(message);
+		return -EIO;
+	}
+
+	id++;
+	req->pending = call;
+	req->cb = cb;
+	req->data = data;
+	req->uid = id;
+	req->redundant = FALSE;
+	req->error = FALSE;
+
+	dbus_pending_call_set_notify(call, request_reply,
+							req, NULL);
+	g_hash_table_insert(requests, &req->uid, req);
+	dbus_message_unref(message);
+
+	return req->uid;
+}
+
+static void pns_release(int uid)
+{
+	DBusMessage *message = NULL;
+	struct pns_req *req;
+
+	DBG("");
+
+	req = g_hash_table_lookup(requests, &uid);
+	if (!req)
+		return;
+
+	if (req->pending) {
+		if (dbus_pending_call_get_completed(req->pending) == FALSE) {
+			/*
+			 * We want to cancel the request but we have to wait
+			 * the response of ConnMan. So we mark request as
+			 * redundant until we get the response, then we remove
+			 * it from hash table.
+			 */
+			req->redundant = TRUE;
+			return;
+		}
+	}
+
+	/*
+	 * There was an error while reading response or transmitted by response
+	 * so we don't need to call release DBus method.
+	 */
+	if (req->error)
+		goto error;
+
+	message = dbus_message_new_method_call(CONNMAN_SERVICE,
+				     CONNMAN_MANAGER_PATH,
+				     CONNMAN_MANAGER_INTERFACE,
+				     "ReleasePrivateNetwork");
+
+	if (message == NULL)
+		goto error;
+
+	dbus_message_set_no_reply(message, TRUE);
+	dbus_connection_send(connection, message, NULL);
+
+error:
+	if (message)
+		dbus_message_unref(message);
+
+	g_hash_table_remove(requests, &req->uid);
+}
+
+static struct ofono_private_network_driver pn_driver = {
+	.name		= "ConnMan Private Network",
+	.request	= pns_request,
+	.release	= pns_release,
+};
+
+static void remove_requests(gpointer user_data)
+{
+	struct pns_req *req = user_data;
+
+	g_free(req);
+}
+
+static int connman_init(void)
+{
+	DBG("");
+
+	id = 0;
+	connection = ofono_dbus_get_connection();
+	requests = g_hash_table_new_full(g_int_hash, g_int_equal, NULL,
+						remove_requests);
+
+	return ofono_private_network_driver_register(&pn_driver);
+}
+
+static void connman_exit(void)
+{
+	g_hash_table_destroy(requests);
+	ofono_private_network_driver_unregister(&pn_driver);
+}
+
+OFONO_PLUGIN_DEFINE(connman, "ConnMan plugin", VERSION,
+		OFONO_PLUGIN_PRIORITY_DEFAULT, connman_init, connman_exit)
-- 
1.7.1


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

* Re: [PATCH_v6 1/5] gatppp: Add new contructor to use external fd
  2011-05-19  9:58 ` [PATCH_v6 1/5] gatppp: Add new contructor to use external fd Guillaume Zajac
@ 2011-05-25 10:36   ` Denis Kenzior
  0 siblings, 0 replies; 13+ messages in thread
From: Denis Kenzior @ 2011-05-25 10:36 UTC (permalink / raw)
  To: ofono

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

Hi Guillaume,

On 05/19/2011 04:58 AM, Guillaume Zajac wrote:
> ---
>  gatchat/gatppp.c  |   33 ++++++++++++++++++++++++++++++++-
>  gatchat/gatppp.h  |    1 +
>  gatchat/ppp.h     |    2 +-
>  gatchat/ppp_net.c |   47 ++++++++++++++++++++++++++++++++---------------
>  4 files changed, 66 insertions(+), 17 deletions(-)
> 

I applied this patch, but did have a few minor fixes afterward.

Regards,
-Denis

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

* Re: [PATCH_v6 2/5] private-network: add header into include and Makefile.am
  2011-05-19  9:58 ` [PATCH_v6 2/5] private-network: add header into include and Makefile.am Guillaume Zajac
@ 2011-05-25 10:38   ` Denis Kenzior
  0 siblings, 0 replies; 13+ messages in thread
From: Denis Kenzior @ 2011-05-25 10:38 UTC (permalink / raw)
  To: ofono

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

Hi Guillaume,

On 05/19/2011 04:58 AM, Guillaume Zajac wrote:
> ---
>  Makefile.am               |    4 +-
>  include/private-network.h |   56 +++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 58 insertions(+), 2 deletions(-)
>  create mode 100644 include/private-network.h

I applied this patch, however I did fix up a few things afterwards:

> +typedef void (ofono_private_network_cb_t)(

Please make sure that this is a pointer, e.g. typedef void (*foo)(...);

> +		void *data,
> +		const struct ofono_private_network_settings *settings);

It is customary to have the userdata pointer as the last argument

Regards,
-Denis

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

* Re: [PATCH_v6 3/5] private-network: add request/release functions and new feature to Makefile.am
  2011-05-19  9:58 ` [PATCH_v6 3/5] private-network: add request/release functions and new feature to Makefile.am Guillaume Zajac
@ 2011-05-25 10:38   ` Denis Kenzior
  0 siblings, 0 replies; 13+ messages in thread
From: Denis Kenzior @ 2011-05-25 10:38 UTC (permalink / raw)
  To: ofono

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

Hi Guillaume,

On 05/19/2011 04:58 AM, Guillaume Zajac wrote:
> ---
>  Makefile.am           |    3 +-
>  src/ofono.h           |    6 +++
>  src/private-network.c |   91 +++++++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 99 insertions(+), 1 deletions(-)
>  create mode 100644 src/private-network.c
> 

Patch has been applied, thanks.

Regards,
-Denis

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

* Re: [PATCH_v6 4/5] emulator: add request/release private network calls
  2011-05-19  9:58 ` [PATCH_v6 4/5] emulator: add request/release private network calls Guillaume Zajac
@ 2011-05-25 10:46   ` Denis Kenzior
  2011-05-30 13:25     ` Guillaume Zajac
  0 siblings, 1 reply; 13+ messages in thread
From: Denis Kenzior @ 2011-05-25 10:46 UTC (permalink / raw)
  To: ofono

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

Hi Guillaume,

On 05/19/2011 04:58 AM, Guillaume Zajac wrote:
> ---
>  src/emulator.c |   75 ++++++++++++++++++++++++++++++++++++++++++++++++-------
>  1 files changed, 65 insertions(+), 10 deletions(-)
> 

I applied this patch, but have done heavy refactoring afterwards.
Please review all my changes (~20 or so patches intermixed with yours)
and make sure everything makes sense.  I lightly tested this
functionality with gsmdial and everything seems to be performing well.

However, please test it really well yourself, use valgrind and try every
exceptional condition you can think of.

Regards,
-Denis

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

* Re: [PATCH_v6 4/5] emulator: add request/release private network calls
  2011-05-25 10:46   ` Denis Kenzior
@ 2011-05-30 13:25     ` Guillaume Zajac
  0 siblings, 0 replies; 13+ messages in thread
From: Guillaume Zajac @ 2011-05-30 13:25 UTC (permalink / raw)
  To: ofono

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

Hi Denis,

> I applied this patch, but have done heavy refactoring afterwards.
> Please review all my changes (~20 or so patches intermixed with yours)
> and make sure everything makes sense.  I lightly tested this
> functionality with gsmdial and everything seems to be performing well.
>
> However, please test it really well yourself, use valgrind and try every
> exceptional condition you can think of.
>

I see you have changed the way PPP packets exchange start, that was what 
was missing me.
Now we don't need anymore to copy into emulator structure the PN 
settings as we can directly
pass the values to the PPP stack.
I also forgot to use set_write_done to trigger the resume GAtPPP/suspend 
GAtChat.
It sounds ok to me.

I have tested it with Windows 7 DUN client and everything seems to work.
I have also found a way to test escape sequence from Windows 7 DUN client,
you just have to turn off your bluetooth adapter while you are connected 
to oFono DUN server.
It will send +++ --> ATH0 and turn the adapter off.

Kind regards,
Guillaume


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

* Re: [PATCH_v6 5/5] connman: add plugin in oFono to request/release private network
  2011-05-19  9:58 ` [PATCH_v6 5/5] connman: add plugin in oFono to request/release private network Guillaume Zajac
@ 2011-06-02  2:53   ` Denis Kenzior
  0 siblings, 0 replies; 13+ messages in thread
From: Denis Kenzior @ 2011-06-02  2:53 UTC (permalink / raw)
  To: ofono

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

Hi Guillaume,

On 05/19/2011 04:58 AM, Guillaume Zajac wrote:
> ---
>  Makefile.am       |    3 +
>  plugins/connman.c |  299 +++++++++++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 302 insertions(+), 0 deletions(-)
>  create mode 100644 plugins/connman.c
> 
> diff --git a/Makefile.am b/Makefile.am
> index e1eaf15..ffb85ae 100644
> --- a/Makefile.am
> +++ b/Makefile.am
> @@ -339,6 +339,9 @@ builtin_sources += plugins/hfp_ag.c plugins/bluetooth.h
>  builtin_modules += dun_gw
>  builtin_sources += plugins/dun_gw.c plugins/bluetooth.h
>  
> +builtin_modules += connman
> +builtin_sources += plugins/connman.c
> +
>  builtin_sources += $(btio_sources)
>  builtin_cflags += @BLUEZ_CFLAGS@
>  builtin_libadd += @BLUEZ_LIBS@
> diff --git a/plugins/connman.c b/plugins/connman.c
> new file mode 100644
> index 0000000..5f0ad8a
> --- /dev/null
> +++ b/plugins/connman.c
> @@ -0,0 +1,299 @@
> +/*
> + *
> + *  oFono - Open Source Telephony
> + *
> + *  Copyright (C) 2008-2011  Intel Corporation. All rights reserved.
> + *
> + *  This program is free software; you can redistribute it and/or modify
> + *  it under the terms of the GNU General Public License version 2 as
> + *  published by the Free Software Foundation.
> + *
> + *  This program is distributed in the hope that it will be useful,
> + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
> + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + *  GNU General Public License for more details.
> + *
> + *  You should have received a copy of the GNU General Public License
> + *  along with this program; if not, write to the Free Software
> + *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
> + *
> + */
> +
> +#ifdef HAVE_CONFIG_H
> +#include <config.h>
> +#endif
> +
> +#include <errno.h>
> +#include <stdlib.h>
> +#include <unistd.h>
> +
> +#include <gdbus.h>
> +#include <string.h>
> +
> +#include <ofono.h>
> +#include <private-network.h>
> +
> +#define CONNMAN_SERVICE			"net.connman"
> +#define CONNMAN_PATH			"/net/connman"
> +
> +#define CONNMAN_DEBUG_INTERFACE		CONNMAN_SERVICE ".Debug"
> +#define CONNMAN_ERROR_INTERFACE		CONNMAN_SERVICE ".Error"
> +#define CONNMAN_AGENT_INTERFACE		CONNMAN_SERVICE ".Agent"
> +#define CONNMAN_COUNTER_INTERFACE	CONNMAN_SERVICE ".Counter"
> +
> +#define CONNMAN_MANAGER_INTERFACE	CONNMAN_SERVICE ".Manager"
> +#define CONNMAN_MANAGER_PATH		"/"
> +
> +#define CONNMAN_TASK_INTERFACE		CONNMAN_SERVICE ".Task"
> +#define CONNMAN_PROFILE_INTERFACE	CONNMAN_SERVICE ".Profile"
> +#define CONNMAN_SERVICE_INTERFACE	CONNMAN_SERVICE ".Service"
> +#define CONNMAN_PROVIDER_INTERFACE	CONNMAN_SERVICE ".Provider"
> +#define CONNMAN_TECHNOLOGY_INTERFACE	CONNMAN_SERVICE ".Technology"
> +#define CONNMAN_SESSION_INTERFACE	CONNMAN_SERVICE ".Session"
> +#define CONNMAN_NOTIFICATION_INTERFACE	CONNMAN_SERVICE ".Notification"
> +

Why do you bother defining all these interfaces when you only ever use
the MANAGER one?  Please remove the ones you don't need.

> +static DBusConnection *connection;
> +static GHashTable *requests;
> +static unsigned int id;
> +
> +struct pns_req {
> +	int uid;
> +	DBusPendingCall *pending;
> +	ofono_private_network_cb_t *cb;
> +	void *data;
> +	gboolean redundant;
> +	gboolean error;
> +};
> +
> +static void request_reply(DBusPendingCall *call, void *user_data)
> +{
> +	struct pns_req *req = user_data;
> +	struct ofono_private_network_settings pns;
> +	DBusMessageIter array, dict, entry;
> +	DBusMessage *reply;
> +
> +	DBG("");
> +
> +	pns.fd = -1;
> +	pns.server_ip = NULL;
> +	pns.peer_ip = NULL;
> +	pns.primary_dns = NULL;
> +	pns.secondary_dns = NULL;
> +
> +	/* request is no more pending */
> +	req->pending = NULL;
> +
> +	reply = dbus_pending_call_steal_reply(call);
> +	if (!reply)
> +		goto error;
> +
> +	if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR)
> +		goto error;
> +
> +	if (dbus_message_iter_init(reply, &array) == FALSE)
> +		goto error;
> +
> +	if (dbus_message_iter_get_arg_type(&array) != DBUS_TYPE_UNIX_FD)
> +		goto error;
> +
> +	dbus_message_iter_get_basic(&array, &pns.fd);
> +	DBG("Fildescriptor = %d\n", pns.fd);
> +
> +	dbus_message_iter_next(&array);
> +
> +	if (dbus_message_iter_get_arg_type(&array) != DBUS_TYPE_ARRAY)
> +		goto error;
> +
> +	dbus_message_iter_recurse(&array, &dict);
> +
> +	while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) {
> +		DBusMessageIter iter;
> +		const char *key;
> +		int type;
> +
> +		dbus_message_iter_recurse(&dict, &entry);
> +
> +		dbus_message_iter_get_basic(&entry, &key);
> +
> +		dbus_message_iter_next(&entry);
> +		dbus_message_iter_recurse(&entry, &iter);
> +
> +		type = dbus_message_iter_get_arg_type(&iter);
> +		if (type != DBUS_TYPE_STRING)
> +			break;
> +
> +		if (g_str_equal(key, "ServerIPv4")
> +				&& type == DBUS_TYPE_STRING)
> +			dbus_message_iter_get_basic(&iter, &pns.server_ip);
> +		else if (g_str_equal(key, "PeerIPv4")
> +				&& type == DBUS_TYPE_STRING)
> +			dbus_message_iter_get_basic(&iter, &pns.peer_ip);
> +		else if (g_str_equal(key, "PrimaryDNS")
> +				&& type == DBUS_TYPE_STRING)
> +			dbus_message_iter_get_basic(&iter, &pns.primary_dns);
> +		else if (g_str_equal(key, "SecondaryDNS")
> +				&& type == DBUS_TYPE_STRING)
> +			dbus_message_iter_get_basic(&iter, &pns.secondary_dns);
> +
> +		dbus_message_iter_next(&dict);
> +	}
> +
> +	if (req->redundant == TRUE)
> +		goto done;

We should be checking this much earlier, before doing all the work of
parsing the returned arguments.  You should also be sending a
ReleasePrivateNetwork call to ConnMan in this case.

> +
> +	if (pns.server_ip == NULL || pns.peer_ip == NULL ||
> +			pns.primary_dns == NULL || pns.secondary_dns == NULL ||
> +			pns.fd < 0) {
> +		ofono_error("Error while reading dictionnary...\n");
> +		goto done;
> +	}
> +
> +	req->cb(req->data, &pns);
> +
> +	dbus_message_unref(reply);
> +	dbus_pending_call_unref(call);
> +
> +	return;
> +
> +error:
> +	req->error = TRUE;
> +done:

Calling this label 'done' is a bit misleading.

> +	if (pns.fd >= 0)
> +		close(pns.fd);
> +
> +	req->cb(req->data, NULL);
> +
> +	if (reply)
> +		dbus_message_unref(reply);
> +
> +	dbus_pending_call_unref(call);
> +}
> +
> +static int pns_request(ofono_private_network_cb_t cb, void *data)
> +{
> +	DBusMessage *message;
> +	DBusPendingCall *call;
> +	struct pns_req *req;
> +
> +	DBG("");
> +
> +	req = g_try_new(struct pns_req, 1);
> +
> +	if (req == NULL)
> +		return -ENOMEM;
> +
> +	message = dbus_message_new_method_call(CONNMAN_SERVICE,
> +				     CONNMAN_MANAGER_PATH,
> +				     CONNMAN_MANAGER_INTERFACE,
> +				     "RequestPrivateNetwork");

Mixing tabs and spaces here, please fix this.

> +
> +	if (message == NULL) {
> +		g_free(req);
> +		return -ENOMEM;
> +	}
> +
> +	if (dbus_connection_send_with_reply(connection,
> +				message, &call, 5000) == FALSE) {
> +		g_free(req);
> +		dbus_message_unref(message);
> +		return -EIO;
> +	}
> +
> +	id++;
> +	req->pending = call;
> +	req->cb = cb;
> +	req->data = data;
> +	req->uid = id;
> +	req->redundant = FALSE;
> +	req->error = FALSE;
> +
> +	dbus_pending_call_set_notify(call, request_reply,
> +							req, NULL);
> +	g_hash_table_insert(requests, &req->uid, req);
> +	dbus_message_unref(message);
> +
> +	return req->uid;
> +}
> +
> +static void pns_release(int uid)
> +{
> +	DBusMessage *message = NULL;
> +	struct pns_req *req;
> +
> +	DBG("");
> +
> +	req = g_hash_table_lookup(requests, &uid);
> +	if (!req)
> +		return;
> +
> +	if (req->pending) {
> +		if (dbus_pending_call_get_completed(req->pending) == FALSE) {
> +			/*
> +			 * We want to cancel the request but we have to wait
> +			 * the response of ConnMan. So we mark request as
> +			 * redundant until we get the response, then we remove
> +			 * it from hash table.
> +			 */
> +			req->redundant = TRUE;
> +			return;
> +		}
> +	}
> +
> +	/*
> +	 * There was an error while reading response or transmitted by response
> +	 * so we don't need to call release DBus method.
> +	 */
> +	if (req->error)
> +		goto error;

Actually I don't think you need this.  We should not call release in
case Request() returned an error.  I fixed this in commit 9ff1b9f.

> +
> +	message = dbus_message_new_method_call(CONNMAN_SERVICE,
> +				     CONNMAN_MANAGER_PATH,
> +				     CONNMAN_MANAGER_INTERFACE,
> +				     "ReleasePrivateNetwork");

Mixing tabs and spaces here, please fix this

> +
> +	if (message == NULL)
> +		goto error;
> +
> +	dbus_message_set_no_reply(message, TRUE);
> +	dbus_connection_send(connection, message, NULL);
> +
> +error:
> +	if (message)
> +		dbus_message_unref(message);
> +
> +	g_hash_table_remove(requests, &req->uid);
> +}
> +
> +static struct ofono_private_network_driver pn_driver = {
> +	.name		= "ConnMan Private Network",
> +	.request	= pns_request,
> +	.release	= pns_release,
> +};
> +
> +static void remove_requests(gpointer user_data)
> +{
> +	struct pns_req *req = user_data;
> +
> +	g_free(req);
> +}
> +
> +static int connman_init(void)
> +{
> +	DBG("");
> +
> +	id = 0;
> +	connection = ofono_dbus_get_connection();
> +	requests = g_hash_table_new_full(g_int_hash, g_int_equal, NULL,
> +						remove_requests);
> +
> +	return ofono_private_network_driver_register(&pn_driver);
> +}
> +
> +static void connman_exit(void)
> +{
> +	g_hash_table_destroy(requests);
> +	ofono_private_network_driver_unregister(&pn_driver);
> +}
> +
> +OFONO_PLUGIN_DEFINE(connman, "ConnMan plugin", VERSION,
> +		OFONO_PLUGIN_PRIORITY_DEFAULT, connman_init, connman_exit)

Regards,
-Denis

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

* [PATCH_v6 1/5] gatppp: Add new contructor to use external fd
  2011-05-19  9:55 [PATCH_v6 0/5] *** SUBJECT HERE *** Guillaume Zajac
@ 2011-05-19  9:55 ` Guillaume Zajac
  0 siblings, 0 replies; 13+ messages in thread
From: Guillaume Zajac @ 2011-05-19  9:55 UTC (permalink / raw)
  To: ofono

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

---
 gatchat/gatppp.c  |   33 ++++++++++++++++++++++++++++++++-
 gatchat/gatppp.h  |    1 +
 gatchat/ppp.h     |    2 +-
 gatchat/ppp_net.c |   47 ++++++++++++++++++++++++++++++++---------------
 4 files changed, 66 insertions(+), 17 deletions(-)

diff --git a/gatchat/gatppp.c b/gatchat/gatppp.c
index c776811..1f2d227 100644
--- a/gatchat/gatppp.c
+++ b/gatchat/gatppp.c
@@ -78,6 +78,7 @@ struct _GAtPPP {
 	guint ppp_dead_source;
 	GAtSuspendFunc suspend_func;
 	gpointer suspend_data;
+	int fd;
 };
 
 void ppp_debug(GAtPPP *ppp, const char *str)
@@ -290,7 +291,7 @@ void ppp_auth_notify(GAtPPP *ppp, gboolean success)
 void ppp_ipcp_up_notify(GAtPPP *ppp, const char *local, const char *peer,
 					const char *dns1, const char *dns2)
 {
-	ppp->net = ppp_net_new(ppp);
+	ppp->net = ppp_net_new(ppp, ppp->fd);
 
 	if (ppp->net == NULL) {
 		ppp->disconnect_reason = G_AT_PPP_REASON_NET_FAIL;
@@ -316,6 +317,7 @@ void ppp_ipcp_down_notify(GAtPPP *ppp)
 		return;
 
 	ppp_net_free(ppp->net);
+	ppp->fd = -1;
 	ppp->net = NULL;
 }
 
@@ -522,6 +524,8 @@ void g_at_ppp_unref(GAtPPP *ppp)
 
 	if (ppp->net)
 		ppp_net_free(ppp->net);
+	else if (ppp->fd >= 0)
+		close(ppp->fd);
 
 	if (ppp->chap)
 		ppp_chap_free(ppp->chap);
@@ -565,6 +569,8 @@ static GAtPPP *ppp_init_common(GAtHDLC *hdlc, gboolean is_server, guint32 ip)
 
 	ppp->ref_count = 1;
 
+	ppp->fd = -1;
+
 	/* set options to defaults */
 	ppp->mru = DEFAULT_MRU;
 	ppp->mtu = DEFAULT_MTU;
@@ -657,3 +663,28 @@ GAtPPP *g_at_ppp_server_new_from_io(GAtIO *io, const char *local)
 
 	return ppp;
 }
+
+GAtPPP *g_at_ppp_server_new_full(GAtIO *io, const char *local, int fd)
+{
+	GAtHDLC *hdlc;
+	GAtPPP *ppp;
+	guint32 ip;
+
+	if (local == NULL)
+		ip = 0;
+	else if (inet_pton(AF_INET, local, &ip) != 1)
+		return NULL;
+
+	hdlc = g_at_hdlc_new_from_io(io);
+	if (hdlc == NULL)
+		return NULL;
+
+	ppp = ppp_init_common(hdlc, TRUE, ip);
+
+	/* Set the fd value returned by ConnMan */
+	ppp->fd = fd;
+
+	g_at_hdlc_unref(hdlc);
+
+	return ppp;
+}
diff --git a/gatchat/gatppp.h b/gatchat/gatppp.h
index 9464ffd..365123a 100644
--- a/gatchat/gatppp.h
+++ b/gatchat/gatppp.h
@@ -54,6 +54,7 @@ GAtPPP *g_at_ppp_new(GIOChannel *modem);
 GAtPPP *g_at_ppp_new_from_io(GAtIO *io);
 GAtPPP *g_at_ppp_server_new(GIOChannel *modem, const char *local);
 GAtPPP *g_at_ppp_server_new_from_io(GAtIO *io, const char *local);
+GAtPPP *g_at_ppp_server_new_full(GAtIO *io, const char *local, int fd);
 
 void g_at_ppp_open(GAtPPP *ppp);
 void g_at_ppp_set_connect_function(GAtPPP *ppp, GAtPPPConnectFunc callback,
diff --git a/gatchat/ppp.h b/gatchat/ppp.h
index 22809d8..f866944 100644
--- a/gatchat/ppp.h
+++ b/gatchat/ppp.h
@@ -102,7 +102,7 @@ void ppp_chap_free(struct ppp_chap *chap);
 void ppp_chap_process_packet(struct ppp_chap *chap, const guint8 *new_packet);
 
 /* TUN / Network related functions */
-struct ppp_net *ppp_net_new(GAtPPP *ppp);
+struct ppp_net *ppp_net_new(GAtPPP *ppp, int fd);
 const char *ppp_net_get_interface(struct ppp_net *net);
 void ppp_net_process_packet(struct ppp_net *net, const guint8 *packet);
 void ppp_net_free(struct ppp_net *net);
diff --git a/gatchat/ppp_net.c b/gatchat/ppp_net.c
index 25bcfa4..52b3554 100644
--- a/gatchat/ppp_net.c
+++ b/gatchat/ppp_net.c
@@ -123,35 +123,52 @@ const char *ppp_net_get_interface(struct ppp_net *net)
 	return net->if_name;
 }
 
-struct ppp_net *ppp_net_new(GAtPPP *ppp)
+struct ppp_net *ppp_net_new(GAtPPP *ppp, int fd)
 {
 	struct ppp_net *net;
 	GIOChannel *channel = NULL;
 	struct ifreq ifr;
-	int fd, err;
+	int err;
 
 	net = g_try_new0(struct ppp_net, 1);
-	if (net == NULL)
+	if (net == NULL) {
+		if (fd >= 0)
+			close(fd);
+
 		return NULL;
+	}
 
 	net->ppp_packet = ppp_packet_new(MAX_PACKET, PPP_IP_PROTO);
 	if (net->ppp_packet == NULL) {
+		if (fd >= 0)
+			close(fd);
+
 		g_free(net);
 		return NULL;
 	}
 
-	/* open a tun interface */
-	fd = open("/dev/net/tun", O_RDWR);
-	if (fd < 0)
-		goto error;
-
-	memset(&ifr, 0, sizeof(ifr));
-	ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
-	strcpy(ifr.ifr_name, "ppp%d");
-
-	err = ioctl(fd, TUNSETIFF, (void *) &ifr);
-	if (err < 0)
-		goto error;
+	/*
+	 * If the fd value is still the default one,
+	 * open the tun interface and configure it.
+	 */
+	if (fd < 0) {
+		/* open a tun interface */
+		fd = open("/dev/net/tun", O_RDWR);
+		if (fd < 0)
+			goto error;
+
+		memset(&ifr, 0, sizeof(ifr));
+		ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
+		strcpy(ifr.ifr_name, "ppp%d");
+
+		err = ioctl(fd, TUNSETIFF, (void *) &ifr);
+		if (err < 0)
+			goto error;
+	} else {
+		err = ioctl(fd, TUNGETIFF, (void *) &ifr);
+		if (err < 0)
+			goto error;
+	}
 
 	net->if_name = strdup(ifr.ifr_name);
 
-- 
1.7.1


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

end of thread, other threads:[~2011-06-02  2:53 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-05-19  9:58 [PATCH_v6 0/5] Private network request to ConnMan Guillaume Zajac
2011-05-19  9:58 ` [PATCH_v6 1/5] gatppp: Add new contructor to use external fd Guillaume Zajac
2011-05-25 10:36   ` Denis Kenzior
2011-05-19  9:58 ` [PATCH_v6 2/5] private-network: add header into include and Makefile.am Guillaume Zajac
2011-05-25 10:38   ` Denis Kenzior
2011-05-19  9:58 ` [PATCH_v6 3/5] private-network: add request/release functions and new feature to Makefile.am Guillaume Zajac
2011-05-25 10:38   ` Denis Kenzior
2011-05-19  9:58 ` [PATCH_v6 4/5] emulator: add request/release private network calls Guillaume Zajac
2011-05-25 10:46   ` Denis Kenzior
2011-05-30 13:25     ` Guillaume Zajac
2011-05-19  9:58 ` [PATCH_v6 5/5] connman: add plugin in oFono to request/release private network Guillaume Zajac
2011-06-02  2:53   ` Denis Kenzior
  -- strict thread matches above, loose matches on Subject: below --
2011-05-19  9:55 [PATCH_v6 0/5] *** SUBJECT HERE *** Guillaume Zajac
2011-05-19  9:55 ` [PATCH_v6 1/5] gatppp: Add new contructor to use external fd Guillaume Zajac

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.