linux-bluetooth.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH_v5 0/6] Refactor bnep code and implement pan methods
@ 2013-11-29 14:20 Ravi kumar Veeramally
  2013-11-29 14:20 ` [PATCH_v5 1/6] profiles/network: Refactor bnep connection setup functionality Ravi kumar Veeramally
                   ` (6 more replies)
  0 siblings, 7 replies; 8+ messages in thread
From: Ravi kumar Veeramally @ 2013-11-29 14:20 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Ravi kumar Veeramally

v5: Renamed strcut network_peer to pan_device as per Luiz comments.

v4: Fixed Luiz comments (discussed in irc). Merge patch 1 and 2.
    Pass fd in bnep_connect instead of GIOChannel.

v3: Fixed Anderson and Luiz comments and solved rebased conflicts.

v2: Refactored profiles/network/common.* as per Johan's comments
    (renaming common.c|h to bnep.c|h and moving bnep related code to
     bnep.c ro reduce redundancy in profiles/netowrk/connection.c and
     android/pan.c)

v1: This patch set supports PANU role with a minor fix in android. Added
    CAP_NET_RAW capability for bnep services. Creates bnep connection and
    up the inreface on connect call and free the device on disconnect call.
    Interface name(bnepX) will be notified on control state cb. Android
    environment will create IP address with dhcp calls.

Ravi kumar Veeramally (6):
  profiles/network: Refactor bnep connection setup functionality
  profiles/network: Rename common.c|h to bnep.c|h
  android/pan: Implement pan connect method in daemon
  android/pan: Implement pan disconnect method in daemon
  android/pan: Implement the get local role method in daemon
  android: Add reasons for adding capabilites to process

 Makefile.plugins                      |   2 +-
 android/Android.mk                    |   2 +
 android/Makefile.am                   |   3 +-
 android/main.c                        |   3 +
 android/pan.c                         | 253 ++++++++++++++++++++++++++++++++--
 profiles/network/{common.c => bnep.c} | 197 +++++++++++++++++++++++++-
 profiles/network/{common.h => bnep.h} |   5 +
 profiles/network/connection.c         | 174 ++---------------------
 profiles/network/manager.c            |   2 +-
 profiles/network/server.c             |   5 +-
 10 files changed, 468 insertions(+), 178 deletions(-)
 rename profiles/network/{common.c => bnep.c} (58%)
 rename profiles/network/{common.h => bnep.h} (87%)

-- 
1.8.3.2


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

* [PATCH_v5 1/6] profiles/network: Refactor bnep connection setup functionality
  2013-11-29 14:20 [PATCH_v5 0/6] Refactor bnep code and implement pan methods Ravi kumar Veeramally
@ 2013-11-29 14:20 ` Ravi kumar Veeramally
  2013-11-29 14:20 ` [PATCH_v5 2/6] profiles/network: Rename common.c|h to bnep.c|h Ravi kumar Veeramally
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Ravi kumar Veeramally @ 2013-11-29 14:20 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Ravi kumar Veeramally

Moving bnep connection setup related functionality to common.c.
Provided bnep_connect call with bnep_connect_cb for status and
bnep interface name. It will be simple if someone want to utilize
this call otherwise they have to reimplement similar functionality
with minimal changes (e.g. android/pan).
---
 profiles/network/common.c     | 195 +++++++++++++++++++++++++++++++++++++++++-
 profiles/network/common.h     |   5 ++
 profiles/network/connection.c | 172 +++----------------------------------
 profiles/network/server.c     |   3 -
 4 files changed, 211 insertions(+), 164 deletions(-)

diff --git a/profiles/network/common.c b/profiles/network/common.c
index 0b291bd..71154c8 100644
--- a/profiles/network/common.c
+++ b/profiles/network/common.c
@@ -46,6 +46,9 @@
 #include "common.h"
 #include "lib/uuid.h"
 
+#define CON_SETUP_RETRIES      3
+#define CON_SETUP_TO           9
+
 static int ctl;
 
 static struct {
@@ -59,6 +62,35 @@ static struct {
 	{ NULL }
 };
 
+struct __service_16 {
+	uint16_t dst;
+	uint16_t src;
+} __attribute__ ((packed));
+
+struct bnep_conn {
+	GIOChannel	*io;
+	uint16_t	src;
+	uint16_t	dst;
+	guint	attempts;
+	guint	setup_to;
+	void	*data;
+	bnep_connect_cb	conn_cb;
+};
+
+static void free_bnep_connect(struct bnep_conn *bc)
+{
+	if (!bc)
+		return;
+
+	if (bc->io) {
+		g_io_channel_unref(bc->io);
+		bc->io = NULL;
+	}
+
+	g_free(bc);
+	bc = NULL;
+}
+
 uint16_t bnep_service_id(const char *svc)
 {
 	int i;
@@ -149,9 +181,9 @@ int bnep_connadd(int sk, uint16_t role, char *dev)
 {
 	struct bnep_connadd_req req;
 
+	memset(dev, 0, 16);
 	memset(&req, 0, sizeof(req));
-	strncpy(req.device, dev, 16);
-	req.device[15] = '\0';
+	strcpy(req.device, "bnep%d");
 	req.sock = sk;
 	req.role = role;
 	if (ioctl(ctl, BNEPCONNADD, &req) < 0) {
@@ -215,6 +247,165 @@ int bnep_if_down(const char *devname)
 	return 0;
 }
 
+static gboolean bnep_setup_cb(GIOChannel *chan, GIOCondition cond,
+								gpointer data)
+{
+	struct bnep_conn *bc = data;
+	struct bnep_control_rsp *rsp;
+	struct timeval timeo;
+	char pkt[BNEP_MTU];
+	char iface[16];
+	ssize_t r;
+	int sk;
+
+	if (cond & G_IO_NVAL)
+		goto failed;
+
+	if (bc->setup_to > 0) {
+		g_source_remove(bc->setup_to);
+		bc->setup_to = 0;
+	}
+
+	if (cond & (G_IO_HUP | G_IO_ERR)) {
+		error("Hangup or error on l2cap server socket");
+		goto failed;
+	}
+
+	sk = g_io_channel_unix_get_fd(chan);
+	memset(pkt, 0, BNEP_MTU);
+	r = read(sk, pkt, sizeof(pkt) - 1);
+	if (r < 0) {
+		error("IO Channel read error");
+		goto failed;
+	}
+
+	if (r == 0) {
+		error("No packet received on l2cap socket");
+		goto failed;
+	}
+
+	errno = EPROTO;
+
+	if ((size_t) r < sizeof(*rsp)) {
+		error("Packet received is not bnep type");
+		goto failed;
+	}
+
+	rsp = (void *) pkt;
+	if (rsp->type != BNEP_CONTROL) {
+		error("Packet received is not bnep type");
+		goto failed;
+	}
+
+	if (rsp->ctrl != BNEP_SETUP_CONN_RSP)
+		return TRUE;
+
+	r = ntohs(rsp->resp);
+	if (r != BNEP_SUCCESS) {
+		error("bnep failed");
+		goto failed;
+	}
+
+	memset(&timeo, 0, sizeof(timeo));
+	timeo.tv_sec = 0;
+	setsockopt(sk, SOL_SOCKET, SO_RCVTIMEO, &timeo, sizeof(timeo));
+
+	sk = g_io_channel_unix_get_fd(bc->io);
+	if (bnep_connadd(sk, bc->src, iface)) {
+		error("bnep conn could not be added");
+		goto failed;
+	}
+
+	if (bnep_if_up(iface)) {
+		error("could not up %s", iface);
+		goto failed;
+	}
+
+	bc->conn_cb(chan, iface, 0, bc->data);
+	free_bnep_connect(bc);
+
+	return FALSE;
+
+failed:
+	bc->conn_cb(NULL, NULL, -EIO, bc->data);
+	free_bnep_connect(bc);
+
+	return FALSE;
+}
+
+static int bnep_setup_conn_req(struct bnep_conn *bc)
+{
+	struct bnep_setup_conn_req *req;
+	struct __service_16 *s;
+	unsigned char pkt[BNEP_MTU];
+	int fd;
+
+	/* Send request */
+	req = (void *) pkt;
+	req->type = BNEP_CONTROL;
+	req->ctrl = BNEP_SETUP_CONN_REQ;
+	req->uuid_size = 2;     /* 16bit UUID */
+	s = (void *) req->service;
+	s->src = htons(bc->src);
+	s->dst = htons(bc->dst);
+
+	fd = g_io_channel_unix_get_fd(bc->io);
+	if (write(fd, pkt, sizeof(*req) + sizeof(*s)) < 0) {
+		error("bnep connection req send failed: %s", strerror(errno));
+		return -errno;
+	}
+
+	bc->attempts++;
+
+	return 0;
+}
+
+static gboolean bnep_conn_req_to(gpointer user_data)
+{
+	struct bnep_conn *bc = user_data;
+
+	if (bc->attempts == CON_SETUP_RETRIES) {
+		error("Too many bnep connection attempts");
+	} else {
+		error("bnep connection setup TO, retrying...");
+		if (bnep_setup_conn_req(bc) == 0)
+			return TRUE;
+	}
+
+	bc->conn_cb(NULL, NULL, -ETIMEDOUT, bc->data);
+	free_bnep_connect(bc);
+
+	return FALSE;
+}
+
+int bnep_connect(int sk, uint16_t src, uint16_t dst, bnep_connect_cb conn_cb,
+								void *data)
+{
+	struct bnep_conn *bc;
+	int err;
+
+	if (!conn_cb)
+		return -EINVAL;
+
+	bc = g_new0(struct bnep_conn, 1);
+	bc->io = g_io_channel_unix_new(sk);
+	bc->attempts = 0;
+	bc->src = src;
+	bc->dst = dst;
+	bc->conn_cb = conn_cb;
+	bc->data = data;
+
+	err = bnep_setup_conn_req(bc);
+	if (err < 0)
+		return err;
+
+	bc->setup_to = g_timeout_add_seconds(CON_SETUP_TO,
+							bnep_conn_req_to, bc);
+	g_io_add_watch(bc->io, G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
+							bnep_setup_cb, bc);
+	return 0;
+}
+
 int bnep_add_to_bridge(const char *devname, const char *bridge)
 {
 	int ifindex;
diff --git a/profiles/network/common.h b/profiles/network/common.h
index 9a8caac..9043e46 100644
--- a/profiles/network/common.h
+++ b/profiles/network/common.h
@@ -35,3 +35,8 @@ int bnep_if_up(const char *devname);
 int bnep_if_down(const char *devname);
 int bnep_add_to_bridge(const char *devname, const char *bridge);
 int bnep_del_from_bridge(const char *devname, const char *bridge);
+
+typedef void (*bnep_connect_cb) (GIOChannel *chan, char *iface, int err,
+								void *data);
+int bnep_connect(int sk, uint16_t src, uint16_t dst, bnep_connect_cb conn_cb,
+								void *data);
diff --git a/profiles/network/connection.c b/profiles/network/connection.c
index 5966268..d100580 100644
--- a/profiles/network/connection.c
+++ b/profiles/network/connection.c
@@ -51,8 +51,6 @@
 #include "connection.h"
 
 #define NETWORK_PEER_INTERFACE "org.bluez.Network1"
-#define CON_SETUP_RETRIES      3
-#define CON_SETUP_TO           9
 
 typedef enum {
 	CONNECTED,
@@ -73,16 +71,9 @@ struct network_conn {
 	GIOChannel	*io;
 	guint		dc_id;
 	struct network_peer *peer;
-	guint		attempt_cnt;
-	guint		timeout_source;
 	DBusMessage	*connect;
 };
 
-struct __service_16 {
-	uint16_t dst;
-	uint16_t src;
-} __attribute__ ((packed));
-
 static GSList *peers = NULL;
 
 static uint16_t get_service_id(struct btd_service *service)
@@ -163,11 +154,6 @@ static void local_connect_cb(struct network_conn *nc, int err)
 
 static void cancel_connection(struct network_conn *nc, int err)
 {
-	if (nc->timeout_source > 0) {
-		g_source_remove(nc->timeout_source);
-		nc->timeout_source = 0;
-	}
-
 	btd_service_connecting_complete(nc->service, err);
 	if (nc->connect)
 		local_connect_cb(nc, err);
@@ -200,83 +186,24 @@ static void disconnect_cb(struct btd_device *device, gboolean removal,
 	connection_destroy(NULL, user_data);
 }
 
-static gboolean bnep_setup_cb(GIOChannel *chan, GIOCondition cond,
-							gpointer data)
+static void bnep_conn_cb(GIOChannel *chan, char *iface, int err, void *data)
 {
 	struct network_conn *nc = data;
-	struct bnep_control_rsp *rsp;
-	struct timeval timeo;
-	char pkt[BNEP_MTU];
-	ssize_t r;
-	int sk;
 	const char *path;
 	DBusConnection *conn;
 
-	DBG("cond %u", cond);
-
-	if (cond & G_IO_NVAL)
-		return FALSE;
-
-	if (nc->timeout_source > 0) {
-		g_source_remove(nc->timeout_source);
-		nc->timeout_source = 0;
-	}
-
-	if (cond & (G_IO_HUP | G_IO_ERR)) {
-		error("Hangup or error on l2cap server socket");
-		goto failed;
-	}
-
-	sk = g_io_channel_unix_get_fd(chan);
-
-	memset(pkt, 0, BNEP_MTU);
-	r = read(sk, pkt, sizeof(pkt) -1);
-	if (r < 0) {
-		error("IO Channel read error");
-		goto failed;
-	}
-
-	if (r == 0) {
-		error("No packet received on l2cap socket");
-		goto failed;
-	}
-
-	errno = EPROTO;
-
-	if ((size_t) r < sizeof(*rsp)) {
-		error("Packet received is not bnep type");
-		goto failed;
-	}
-
-	rsp = (void *) pkt;
-	if (rsp->type != BNEP_CONTROL) {
-		error("Packet received is not bnep type");
-		goto failed;
-	}
-
-	if (rsp->ctrl != BNEP_SETUP_CONN_RSP)
-		return TRUE;
-
-	r = ntohs(rsp->resp);
-
-	if (r != BNEP_SUCCESS) {
-		error("bnep failed");
-		goto failed;
-	}
-
-	memset(&timeo, 0, sizeof(timeo));
-	timeo.tv_sec = 0;
-
-	setsockopt(sk, SOL_SOCKET, SO_RCVTIMEO, &timeo, sizeof(timeo));
+	DBG("");
 
-	if (bnep_connadd(sk, BNEP_SVC_PANU, nc->dev)) {
-		error("%s could not be added", nc->dev);
+	if (err < 0) {
+		error("connect failed %s", strerror(-err));
 		goto failed;
 	}
 
-	bnep_if_up(nc->dev);
+	info("%s connected", nc->dev);
 
+	memcpy(nc->dev, iface, sizeof(nc->dev));
 	btd_service_connecting_complete(nc->service, 0);
+
 	if (nc->connect)
 		local_connect_cb(nc, 0);
 
@@ -292,101 +219,30 @@ static gboolean bnep_setup_cb(GIOChannel *chan, GIOCondition cond,
 
 	nc->state = CONNECTED;
 	nc->dc_id = device_add_disconnect_watch(nc->peer->device, disconnect_cb,
-						nc, NULL);
-
-	info("%s connected", nc->dev);
-	/* Start watchdog */
+								nc, NULL);
 	g_io_add_watch(chan, G_IO_ERR | G_IO_HUP | G_IO_NVAL,
-			(GIOFunc) bnep_watchdog_cb, nc);
+							bnep_watchdog_cb, nc);
 	g_io_channel_unref(nc->io);
 	nc->io = NULL;
 
-	return FALSE;
+	return;
 
 failed:
 	cancel_connection(nc, -EIO);
-
-	return FALSE;
-}
-
-static int bnep_send_conn_req(struct network_conn *nc)
-{
-	struct bnep_setup_conn_req *req;
-	struct __service_16 *s;
-	unsigned char pkt[BNEP_MTU];
-	int fd;
-
-	DBG("");
-
-	/* Send request */
-	req = (void *) pkt;
-	req->type = BNEP_CONTROL;
-	req->ctrl = BNEP_SETUP_CONN_REQ;
-	req->uuid_size = 2;	/* 16bit UUID */
-	s = (void *) req->service;
-	s->dst = htons(nc->id);
-	s->src = htons(BNEP_SVC_PANU);
-
-	fd = g_io_channel_unix_get_fd(nc->io);
-	if (write(fd, pkt, sizeof(*req) + sizeof(*s)) < 0) {
-		int err = -errno;
-		error("bnep connection req send failed: %s", strerror(errno));
-		return err;
-	}
-
-	nc->attempt_cnt++;
-
-	return 0;
-}
-
-static gboolean bnep_conn_req_to(gpointer user_data)
-{
-	struct network_conn *nc;
-
-	nc = user_data;
-	if (nc->attempt_cnt == CON_SETUP_RETRIES) {
-		error("Too many bnep connection attempts");
-	} else {
-		error("bnep connection setup TO, retrying...");
-		if (bnep_send_conn_req(nc) == 0)
-			return TRUE;
-	}
-
-	cancel_connection(nc, -ETIMEDOUT);
-
-	return FALSE;
-}
-
-static int bnep_connect(struct network_conn *nc)
-{
-	int err;
-
-	nc->attempt_cnt = 0;
-
-	err = bnep_send_conn_req(nc);
-	if (err < 0)
-		return err;
-
-	nc->timeout_source = g_timeout_add_seconds(CON_SETUP_TO,
-							bnep_conn_req_to, nc);
-
-	g_io_add_watch(nc->io, G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
-							bnep_setup_cb, nc);
-
-	return 0;
 }
 
 static void connect_cb(GIOChannel *chan, GError *err, gpointer data)
 {
 	struct network_conn *nc = data;
-	int perr;
+	int sk, perr;
 
 	if (err) {
 		error("%s", err->message);
 		goto failed;
 	}
 
-	perr = bnep_connect(nc);
+	sk = g_io_channel_unix_get_fd(nc->io);
+	perr = bnep_connect(sk, BNEP_SVC_PANU, nc->id, bnep_conn_cb, nc);
 	if (perr < 0) {
 		error("bnep connect(): %s (%d)", strerror(-perr), -perr);
 		goto failed;
@@ -692,8 +548,6 @@ int connection_register(struct btd_service *service)
 
 	nc = g_new0(struct network_conn, 1);
 	nc->id = id;
-	memset(nc->dev, 0, sizeof(nc->dev));
-	strcpy(nc->dev, "bnep%d");
 	nc->service = btd_service_ref(service);
 	nc->state = DISCONNECTED;
 	nc->peer = peer;
diff --git a/profiles/network/server.c b/profiles/network/server.c
index 0050b30..3a7e52a 100644
--- a/profiles/network/server.c
+++ b/profiles/network/server.c
@@ -269,9 +269,6 @@ static int server_connadd(struct network_server *ns,
 	char devname[16];
 	int err, nsk;
 
-	memset(devname, 0, sizeof(devname));
-	strcpy(devname, "bnep%d");
-
 	nsk = g_io_channel_unix_get_fd(session->io);
 	err = bnep_connadd(nsk, dst_role, devname);
 	if (err < 0)
-- 
1.8.3.2


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

* [PATCH_v5 2/6] profiles/network: Rename common.c|h to bnep.c|h
  2013-11-29 14:20 [PATCH_v5 0/6] Refactor bnep code and implement pan methods Ravi kumar Veeramally
  2013-11-29 14:20 ` [PATCH_v5 1/6] profiles/network: Refactor bnep connection setup functionality Ravi kumar Veeramally
@ 2013-11-29 14:20 ` Ravi kumar Veeramally
  2013-11-29 14:20 ` [PATCH_v5 3/6] android/pan: Implement pan connect method in daemon Ravi kumar Veeramally
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Ravi kumar Veeramally @ 2013-11-29 14:20 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Ravi kumar Veeramally

Files common.c|h contains only bnep related code, it makes
more sence with bnep.c|h.
---
 Makefile.plugins                      | 2 +-
 profiles/network/{common.c => bnep.c} | 2 +-
 profiles/network/{common.h => bnep.h} | 0
 profiles/network/connection.c         | 2 +-
 profiles/network/manager.c            | 2 +-
 profiles/network/server.c             | 2 +-
 6 files changed, 5 insertions(+), 5 deletions(-)
 rename profiles/network/{common.c => bnep.c} (99%)
 rename profiles/network/{common.h => bnep.h} (100%)

diff --git a/Makefile.plugins b/Makefile.plugins
index f5025e9..6a1ddbf 100644
--- a/Makefile.plugins
+++ b/Makefile.plugins
@@ -47,7 +47,7 @@ builtin_sources += profiles/audio/control.h profiles/audio/control.c \
 
 builtin_modules += network
 builtin_sources += profiles/network/manager.c \
-			profiles/network/common.h profiles/network/common.c \
+			profiles/network/bnep.h profiles/network/bnep.c \
 			profiles/network/server.h profiles/network/server.c \
 			profiles/network/connection.h \
 			profiles/network/connection.c
diff --git a/profiles/network/common.c b/profiles/network/bnep.c
similarity index 99%
rename from profiles/network/common.c
rename to profiles/network/bnep.c
index 71154c8..0a719a2 100644
--- a/profiles/network/common.c
+++ b/profiles/network/bnep.c
@@ -43,7 +43,7 @@
 #include <glib.h>
 
 #include "log.h"
-#include "common.h"
+#include "bnep.h"
 #include "lib/uuid.h"
 
 #define CON_SETUP_RETRIES      3
diff --git a/profiles/network/common.h b/profiles/network/bnep.h
similarity index 100%
rename from profiles/network/common.h
rename to profiles/network/bnep.h
diff --git a/profiles/network/connection.c b/profiles/network/connection.c
index d100580..9aff319 100644
--- a/profiles/network/connection.c
+++ b/profiles/network/connection.c
@@ -47,7 +47,7 @@
 #include "service.h"
 
 #include "error.h"
-#include "common.h"
+#include "bnep.h"
 #include "connection.h"
 
 #define NETWORK_PEER_INTERFACE "org.bluez.Network1"
diff --git a/profiles/network/manager.c b/profiles/network/manager.c
index ab4224d..8ac2dec 100644
--- a/profiles/network/manager.c
+++ b/profiles/network/manager.c
@@ -43,7 +43,7 @@
 #include "device.h"
 #include "profile.h"
 #include "service.h"
-#include "common.h"
+#include "bnep.h"
 #include "connection.h"
 #include "server.h"
 
diff --git a/profiles/network/server.c b/profiles/network/server.c
index 3a7e52a..b3aab11 100644
--- a/profiles/network/server.c
+++ b/profiles/network/server.c
@@ -48,7 +48,7 @@
 #include "error.h"
 #include "sdpd.h"
 
-#include "common.h"
+#include "bnep.h"
 #include "server.h"
 
 #define NETWORK_SERVER_INTERFACE "org.bluez.NetworkServer1"
-- 
1.8.3.2


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

* [PATCH_v5 3/6] android/pan: Implement pan connect method in daemon
  2013-11-29 14:20 [PATCH_v5 0/6] Refactor bnep code and implement pan methods Ravi kumar Veeramally
  2013-11-29 14:20 ` [PATCH_v5 1/6] profiles/network: Refactor bnep connection setup functionality Ravi kumar Veeramally
  2013-11-29 14:20 ` [PATCH_v5 2/6] profiles/network: Rename common.c|h to bnep.c|h Ravi kumar Veeramally
@ 2013-11-29 14:20 ` Ravi kumar Veeramally
  2013-11-29 14:20 ` [PATCH_v5 4/6] android/pan: Implement pan disconnect " Ravi kumar Veeramally
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Ravi kumar Veeramally @ 2013-11-29 14:20 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Ravi kumar Veeramally

Implements the PAN connect method in android daemon with PANU role
only. Setting up the bnep environment, adds connection and makes
bnep interface up are part of bnep_connect call. Notifies bnep
interface on control state call back and connection status on
connection state call back.
---
 android/Android.mk  |   2 +
 android/Makefile.am |   3 +-
 android/pan.c       | 219 ++++++++++++++++++++++++++++++++++++++++++++++++++--
 3 files changed, 216 insertions(+), 8 deletions(-)

diff --git a/android/Android.mk b/android/Android.mk
index c4d722d..549613c 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -42,6 +42,7 @@ LOCAL_SRC_FILES := \
 	../lib/hci.c \
 	../btio/btio.c \
 	../src/sdp-client.c \
+	../profiles/network/bnep.c \
 
 LOCAL_C_INCLUDES := \
 	$(call include-path-for, glib) \
@@ -66,6 +67,7 @@ lib_headers := \
 	sdp.h \
 	rfcomm.h \
 	sco.h \
+	bnep.h \
 
 $(shell mkdir -p $(LOCAL_PATH)/../lib/bluetooth)
 
diff --git a/android/Makefile.am b/android/Makefile.am
index 15ecf35..df04762 100644
--- a/android/Makefile.am
+++ b/android/Makefile.am
@@ -24,7 +24,8 @@ android_bluetoothd_SOURCES = android/main.c \
 				android/socket.h android/socket.c \
 				android/pan.h android/pan.c \
 				btio/btio.h btio/btio.c \
-				src/sdp-client.h src/sdp-client.c
+				src/sdp-client.h src/sdp-client.c \
+				profiles/network/bnep.h profiles/network/bnep.c
 
 android_bluetoothd_LDADD = lib/libbluetooth-internal.la @GLIB_LIBS@
 
diff --git a/android/pan.c b/android/pan.c
index ea15637..031dfff 100644
--- a/android/pan.c
+++ b/android/pan.c
@@ -29,35 +29,228 @@
 #include <fcntl.h>
 #include <glib.h>
 
+#include "btio/btio.h"
 #include "lib/bluetooth.h"
+#include "lib/bnep.h"
+#include "lib/sdp.h"
+#include "lib/sdp_lib.h"
+#include "src/glib-helper.h"
+#include "profiles/network/bnep.h"
+
 #include "log.h"
 #include "pan.h"
 #include "hal-msg.h"
 #include "ipc.h"
+#include "utils.h"
+#include "bluetooth.h"
 
-static uint8_t bt_pan_enable(struct hal_cmd_pan_enable *cmd, uint16_t len)
+static bdaddr_t adapter_addr;
+GSList *peers = NULL;
+uint8_t local_role = HAL_PAN_ROLE_NONE;
+
+struct pan_device {
+	char		dev[16];
+	bdaddr_t	dst;
+	uint8_t		conn_state;
+	uint8_t		role;
+	GIOChannel	*io;
+	guint		watch;
+};
+
+static int peer_cmp(gconstpointer s, gconstpointer user_data)
 {
-	DBG("Not Implemented");
+	const struct pan_device *dev = s;
+	const bdaddr_t *dst = user_data;
 
-	return HAL_STATUS_FAILED;
+	return bacmp(&dev->dst, dst);
 }
 
-static uint8_t bt_pan_get_role(void *cmd, uint16_t len)
+static void pan_device_free(struct pan_device *dev)
+{
+	local_role = HAL_PAN_ROLE_NONE;
+
+	if (dev->watch > 0) {
+		g_source_remove(dev->watch);
+		dev->watch = 0;
+	}
+
+	if (dev->io) {
+		g_io_channel_unref(dev->io);
+		dev->io = NULL;
+	}
+
+	peers = g_slist_remove(peers, dev);
+	g_free(dev);
+	dev = NULL;
+}
+
+static void bt_pan_notify_conn_state(struct pan_device *dev, uint8_t state)
+{
+	struct hal_ev_pan_conn_state ev;
+	char addr[18];
+
+	if (dev->conn_state == state)
+		return;
+
+	dev->conn_state = state;
+	ba2str(&dev->dst, addr);
+	DBG("device %s state %u", addr, state);
+
+	bdaddr2android(&dev->dst, ev.bdaddr);
+	ev.state = state;
+	ev.local_role = local_role;
+	ev.remote_role = dev->role;
+	ev.status = HAL_STATUS_SUCCESS;
+
+	ipc_send_notif(HAL_SERVICE_ID_PAN, HAL_EV_PAN_CONN_STATE, sizeof(ev),
+									&ev);
+}
+
+static void bt_pan_notify_ctrl_state(struct pan_device *dev, uint8_t state)
+{
+	struct hal_ev_pan_ctrl_state ev;
+
+	DBG("");
+
+	ev.state = state;
+	ev.local_role = local_role;
+	ev.status = HAL_STATUS_SUCCESS;
+	memcpy(ev.name, dev->dev, sizeof(dev->dev));
+
+	ipc_send_notif(HAL_SERVICE_ID_PAN, HAL_EV_PAN_CTRL_STATE, sizeof(ev),
+									&ev);
+}
+
+static gboolean bnep_watchdog_cb(GIOChannel *chan, GIOCondition cond,
+								gpointer data)
+{
+	struct pan_device *dev = data;
+
+	DBG("%s disconnected", dev->dev);
+
+	bt_pan_notify_conn_state(dev, HAL_PAN_STATE_DISCONNECTED);
+	pan_device_free(dev);
+
+	return FALSE;
+}
+
+static void bnep_conn_cb(GIOChannel *chan, char *iface, int err, void *data)
+{
+	struct pan_device *dev = data;
+
+	DBG("");
+
+	if (err < 0) {
+		error("bnep connect req failed: %s", strerror(-err));
+		bt_pan_notify_conn_state(dev, HAL_PAN_STATE_DISCONNECTED);
+		pan_device_free(dev);
+		return;
+	}
+
+	memcpy(dev->dev, iface, sizeof(dev->dev));
+
+	DBG("%s connected", dev->dev);
+
+	bt_pan_notify_ctrl_state(dev, HAL_PAN_CTRL_ENABLED);
+	bt_pan_notify_conn_state(dev, HAL_PAN_STATE_CONNECTED);
+
+	dev->watch = g_io_add_watch(chan, G_IO_ERR | G_IO_HUP | G_IO_NVAL,
+							bnep_watchdog_cb, dev);
+	g_io_channel_unref(dev->io);
+	dev->io = NULL;
+}
+
+static void connect_cb(GIOChannel *chan, GError *err, gpointer data)
+{
+	struct pan_device *dev = data;
+	uint16_t src, dst;
+	int perr, sk;
+
+	DBG("");
+
+	if (err) {
+		error("%s", err->message);
+		bt_pan_notify_conn_state(dev, HAL_PAN_STATE_DISCONNECTED);
+		pan_device_free(dev);
+	}
+
+	src = (local_role == HAL_PAN_ROLE_NAP) ? BNEP_SVC_NAP : BNEP_SVC_PANU;
+	dst = (dev->role == HAL_PAN_ROLE_NAP) ? BNEP_SVC_NAP : BNEP_SVC_PANU;
+	sk = g_io_channel_unix_get_fd(dev->io);
+
+	perr = bnep_connect(sk, src, dst, bnep_conn_cb, dev);
+	if (perr < 0) {
+		error("bnep connect req failed: %s", strerror(-perr));
+		bt_pan_notify_conn_state(dev, HAL_PAN_STATE_DISCONNECTED);
+		pan_device_free(dev);
+		return;
+	}
+}
+
+static uint8_t bt_pan_connect(struct hal_cmd_pan_connect *cmd, uint16_t len)
+{
+	struct pan_device *dev;
+	bdaddr_t dst;
+	char addr[18];
+	GSList *l;
+	GError *gerr = NULL;
+
+	DBG("");
+
+	if (len < sizeof(*cmd))
+		return HAL_STATUS_INVALID;
+
+	android2bdaddr(&cmd->bdaddr, &dst);
+
+	l = g_slist_find_custom(peers, &dst, peer_cmp);
+	if (l)
+		return HAL_STATUS_FAILED;
+
+	dev = g_new0(struct pan_device, 1);
+	bacpy(&dev->dst, &dst);
+	local_role = cmd->local_role;
+	dev->role = cmd->remote_role;
+
+	ba2str(&dev->dst, addr);
+	DBG("connecting to %s %s", addr, dev->dev);
+
+	dev->io = bt_io_connect(connect_cb, dev, NULL, &gerr,
+					BT_IO_OPT_SOURCE_BDADDR, &adapter_addr,
+					BT_IO_OPT_DEST_BDADDR, &dev->dst,
+					BT_IO_OPT_PSM, BNEP_PSM,
+					BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
+					BT_IO_OPT_OMTU, BNEP_MTU,
+					BT_IO_OPT_IMTU, BNEP_MTU,
+					BT_IO_OPT_INVALID);
+	if (!dev->io) {
+		error("%s", gerr->message);
+		g_error_free(gerr);
+		g_free(dev);
+		return HAL_STATUS_FAILED;
+	}
+
+	peers = g_slist_append(peers, dev);
+	bt_pan_notify_conn_state(dev, HAL_PAN_STATE_CONNECTING);
+
+	return HAL_STATUS_SUCCESS;
+}
+
+static uint8_t bt_pan_disconnect(struct hal_cmd_pan_disconnect *cmd,
+								uint16_t len)
 {
 	DBG("Not Implemented");
 
 	return HAL_STATUS_FAILED;
 }
 
-static uint8_t bt_pan_connect(struct hal_cmd_pan_connect *cmd, uint16_t len)
+static uint8_t bt_pan_enable(struct hal_cmd_pan_enable *cmd, uint16_t len)
 {
 	DBG("Not Implemented");
 
 	return HAL_STATUS_FAILED;
 }
 
-static uint8_t bt_pan_disconnect(struct hal_cmd_pan_disconnect *cmd,
-								uint16_t len)
+static uint8_t bt_pan_get_role(void *cmd, uint16_t len)
 {
 	DBG("Not Implemented");
 
@@ -91,12 +284,24 @@ void bt_pan_handle_cmd(int sk, uint8_t opcode, void *buf, uint16_t len)
 
 bool bt_pan_register(const bdaddr_t *addr)
 {
+	int err;
+
 	DBG("");
 
+	bacpy(&adapter_addr, addr);
+
+	err = bnep_init();
+	if (err) {
+		error("bnep init failed");
+		return false;
+	}
+
 	return true;
 }
 
 void bt_pan_unregister(void)
 {
 	DBG("");
+
+	bnep_cleanup();
 }
-- 
1.8.3.2


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

* [PATCH_v5 4/6] android/pan: Implement pan disconnect method in daemon
  2013-11-29 14:20 [PATCH_v5 0/6] Refactor bnep code and implement pan methods Ravi kumar Veeramally
                   ` (2 preceding siblings ...)
  2013-11-29 14:20 ` [PATCH_v5 3/6] android/pan: Implement pan connect method in daemon Ravi kumar Veeramally
@ 2013-11-29 14:20 ` Ravi kumar Veeramally
  2013-11-29 14:20 ` [PATCH_v5 5/6] android/pan: Implement the get local role " Ravi kumar Veeramally
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Ravi kumar Veeramally @ 2013-11-29 14:20 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Ravi kumar Veeramally

Disconnect ongoing PANU role connection betweek devices, free
the device and notify the connection state.
---
 android/pan.c | 30 ++++++++++++++++++++++++++++--
 1 file changed, 28 insertions(+), 2 deletions(-)

diff --git a/android/pan.c b/android/pan.c
index 031dfff..7093e4c 100644
--- a/android/pan.c
+++ b/android/pan.c
@@ -238,9 +238,35 @@ static uint8_t bt_pan_connect(struct hal_cmd_pan_connect *cmd, uint16_t len)
 static uint8_t bt_pan_disconnect(struct hal_cmd_pan_disconnect *cmd,
 								uint16_t len)
 {
-	DBG("Not Implemented");
+	struct pan_device *dev;
+	GSList *l;
+	bdaddr_t dst;
 
-	return HAL_STATUS_FAILED;
+	DBG("");
+
+	if (len < sizeof(*cmd))
+		return HAL_STATUS_INVALID;
+
+	android2bdaddr(&cmd->bdaddr, &dst);
+
+	l = g_slist_find_custom(peers, &dst, peer_cmp);
+	if (!l)
+		return HAL_STATUS_FAILED;
+
+	dev = l->data;
+
+	if (dev->watch) {
+		g_source_remove(dev->watch);
+		dev->watch = 0;
+	}
+
+	bnep_if_down(dev->dev);
+	bnep_kill_connection(&dst);
+
+	bt_pan_notify_conn_state(dev, HAL_PAN_STATE_DISCONNECTED);
+	pan_device_free(dev);
+
+	return HAL_STATUS_SUCCESS;
 }
 
 static uint8_t bt_pan_enable(struct hal_cmd_pan_enable *cmd, uint16_t len)
-- 
1.8.3.2


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

* [PATCH_v5 5/6] android/pan: Implement the get local role method in daemon
  2013-11-29 14:20 [PATCH_v5 0/6] Refactor bnep code and implement pan methods Ravi kumar Veeramally
                   ` (3 preceding siblings ...)
  2013-11-29 14:20 ` [PATCH_v5 4/6] android/pan: Implement pan disconnect " Ravi kumar Veeramally
@ 2013-11-29 14:20 ` Ravi kumar Veeramally
  2013-11-29 14:20 ` [PATCH_v5 6/6] android: Add reasons for adding capabilites to process Ravi kumar Veeramally
  2013-11-29 15:16 ` [PATCH_v5 0/6] Refactor bnep code and implement pan methods Luiz Augusto von Dentz
  6 siblings, 0 replies; 8+ messages in thread
From: Ravi kumar Veeramally @ 2013-11-29 14:20 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Ravi kumar Veeramally

Returns local role of the device (NONE, PANU or NAP).
---
 android/pan.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/android/pan.c b/android/pan.c
index 7093e4c..9ff14f3 100644
--- a/android/pan.c
+++ b/android/pan.c
@@ -278,9 +278,15 @@ static uint8_t bt_pan_enable(struct hal_cmd_pan_enable *cmd, uint16_t len)
 
 static uint8_t bt_pan_get_role(void *cmd, uint16_t len)
 {
-	DBG("Not Implemented");
+	struct hal_rsp_pan_get_role rsp;
 
-	return HAL_STATUS_FAILED;
+	DBG("");
+
+	rsp.local_role = local_role;
+	ipc_send_rsp_full(HAL_SERVICE_ID_PAN, HAL_OP_PAN_GET_ROLE, sizeof(rsp),
+								&rsp, -1);
+
+	return HAL_STATUS_SUCCESS;
 }
 
 void bt_pan_handle_cmd(int sk, uint8_t opcode, void *buf, uint16_t len)
-- 
1.8.3.2


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

* [PATCH_v5 6/6] android: Add reasons for adding capabilites to process
  2013-11-29 14:20 [PATCH_v5 0/6] Refactor bnep code and implement pan methods Ravi kumar Veeramally
                   ` (4 preceding siblings ...)
  2013-11-29 14:20 ` [PATCH_v5 5/6] android/pan: Implement the get local role " Ravi kumar Veeramally
@ 2013-11-29 14:20 ` Ravi kumar Veeramally
  2013-11-29 15:16 ` [PATCH_v5 0/6] Refactor bnep code and implement pan methods Luiz Augusto von Dentz
  6 siblings, 0 replies; 8+ messages in thread
From: Ravi kumar Veeramally @ 2013-11-29 14:20 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Ravi kumar Veeramally

CAP_NET_ADMIN: Allow use of MGMT interface
CAP_NET_BIND_SERVICE: Allow use of privileged PSM
CAP_NET_RAW: Allow use of bnep ioctl calls
---
 android/main.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/android/main.c b/android/main.c
index 3a14af5..eedca58 100644
--- a/android/main.c
+++ b/android/main.c
@@ -534,6 +534,9 @@ static bool set_capabilities(void)
 	header.version = _LINUX_CAPABILITY_VERSION;
 	header.pid = 0;
 
+	/* CAP_NET_ADMIN: Allow use of MGMT interface
+	 * CAP_NET_BIND_SERVICE: Allow use of privileged PSM
+	 * CAP_NET_RAW: Allow use of bnep ioctl calls */
 	cap.effective = cap.permitted =
 		CAP_TO_MASK(CAP_NET_RAW) |
 		CAP_TO_MASK(CAP_NET_ADMIN) |
-- 
1.8.3.2


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

* Re: [PATCH_v5 0/6] Refactor bnep code and implement pan methods
  2013-11-29 14:20 [PATCH_v5 0/6] Refactor bnep code and implement pan methods Ravi kumar Veeramally
                   ` (5 preceding siblings ...)
  2013-11-29 14:20 ` [PATCH_v5 6/6] android: Add reasons for adding capabilites to process Ravi kumar Veeramally
@ 2013-11-29 15:16 ` Luiz Augusto von Dentz
  6 siblings, 0 replies; 8+ messages in thread
From: Luiz Augusto von Dentz @ 2013-11-29 15:16 UTC (permalink / raw)
  To: Ravi kumar Veeramally; +Cc: linux-bluetooth@vger.kernel.org

Hi Ravi,

On Fri, Nov 29, 2013 at 4:20 PM, Ravi kumar Veeramally
<ravikumar.veeramally@linux.intel.com> wrote:
> v5: Renamed strcut network_peer to pan_device as per Luiz comments.
>
> v4: Fixed Luiz comments (discussed in irc). Merge patch 1 and 2.
>     Pass fd in bnep_connect instead of GIOChannel.
>
> v3: Fixed Anderson and Luiz comments and solved rebased conflicts.
>
> v2: Refactored profiles/network/common.* as per Johan's comments
>     (renaming common.c|h to bnep.c|h and moving bnep related code to
>      bnep.c ro reduce redundancy in profiles/netowrk/connection.c and
>      android/pan.c)
>
> v1: This patch set supports PANU role with a minor fix in android. Added
>     CAP_NET_RAW capability for bnep services. Creates bnep connection and
>     up the inreface on connect call and free the device on disconnect call.
>     Interface name(bnepX) will be notified on control state cb. Android
>     environment will create IP address with dhcp calls.
>
> Ravi kumar Veeramally (6):
>   profiles/network: Refactor bnep connection setup functionality
>   profiles/network: Rename common.c|h to bnep.c|h
>   android/pan: Implement pan connect method in daemon
>   android/pan: Implement pan disconnect method in daemon
>   android/pan: Implement the get local role method in daemon
>   android: Add reasons for adding capabilites to process
>
>  Makefile.plugins                      |   2 +-
>  android/Android.mk                    |   2 +
>  android/Makefile.am                   |   3 +-
>  android/main.c                        |   3 +
>  android/pan.c                         | 253 ++++++++++++++++++++++++++++++++--
>  profiles/network/{common.c => bnep.c} | 197 +++++++++++++++++++++++++-
>  profiles/network/{common.h => bnep.h} |   5 +
>  profiles/network/connection.c         | 174 ++---------------------
>  profiles/network/manager.c            |   2 +-
>  profiles/network/server.c             |   5 +-
>  10 files changed, 468 insertions(+), 178 deletions(-)
>  rename profiles/network/{common.c => bnep.c} (58%)
>  rename profiles/network/{common.h => bnep.h} (87%)
>
> --
> 1.8.3.2

Applied, please have a look as I renamed a few other things and I
found that we were sending uninitialized data while testing.


-- 
Luiz Augusto von Dentz

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

end of thread, other threads:[~2013-11-29 15:16 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-11-29 14:20 [PATCH_v5 0/6] Refactor bnep code and implement pan methods Ravi kumar Veeramally
2013-11-29 14:20 ` [PATCH_v5 1/6] profiles/network: Refactor bnep connection setup functionality Ravi kumar Veeramally
2013-11-29 14:20 ` [PATCH_v5 2/6] profiles/network: Rename common.c|h to bnep.c|h Ravi kumar Veeramally
2013-11-29 14:20 ` [PATCH_v5 3/6] android/pan: Implement pan connect method in daemon Ravi kumar Veeramally
2013-11-29 14:20 ` [PATCH_v5 4/6] android/pan: Implement pan disconnect " Ravi kumar Veeramally
2013-11-29 14:20 ` [PATCH_v5 5/6] android/pan: Implement the get local role " Ravi kumar Veeramally
2013-11-29 14:20 ` [PATCH_v5 6/6] android: Add reasons for adding capabilites to process Ravi kumar Veeramally
2013-11-29 15:16 ` [PATCH_v5 0/6] Refactor bnep code and implement pan methods Luiz Augusto von Dentz

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).