linux-bluetooth.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH_v5 1/5] android/pan: shutdown io channel on disconnect call
@ 2013-12-19  8:48 Ravi kumar Veeramally
  2013-12-19  8:48 ` [PATCH_v5 2/5] bnep: Rename struct bnep_conn to struct bnep for better readability Ravi kumar Veeramally
                   ` (3 more replies)
  0 siblings, 4 replies; 6+ messages in thread
From: Ravi kumar Veeramally @ 2013-12-19  8:48 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Ravi kumar Veeramally

Shutdown io channel and send DISCONNECTING notification and send
DISCONNECTED notification and free the device on callback.
---
 android/pan.c | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/android/pan.c b/android/pan.c
index b83f534..187953b 100644
--- a/android/pan.c
+++ b/android/pan.c
@@ -284,14 +284,16 @@ static void bt_pan_disconnect(const void *buf, uint16_t len)
 	}
 
 	dev = l->data;
-	if (dev->watch) {
-		g_source_remove(dev->watch);
-		dev->watch = 0;
+
+	if (dev->io)
+		g_io_channel_shutdown(dev->io, TRUE, NULL);
+
+	if (dev->conn_state == HAL_PAN_STATE_CONNECTED) {
+		bnep_if_down(dev->iface);
+		bnep_conndel(&dst);
 	}
 
-	bnep_if_down(dev->iface);
-	bnep_conndel(&dst);
-	bt_pan_notify_conn_state(dev, HAL_PAN_STATE_DISCONNECTED);
+	bt_pan_notify_conn_state(dev, HAL_PAN_STATE_DISCONNECTING);
 	status = HAL_STATUS_SUCCESS;
 
 failed:
-- 
1.8.3.2


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

* [PATCH_v5 2/5] bnep: Rename struct bnep_conn to struct bnep for better readability
  2013-12-19  8:48 [PATCH_v5 1/5] android/pan: shutdown io channel on disconnect call Ravi kumar Veeramally
@ 2013-12-19  8:48 ` Ravi kumar Veeramally
  2013-12-19  8:48 ` [PATCH_v5 3/5] bnep: Add bnep_new and bnep_free api's Ravi kumar Veeramally
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 6+ messages in thread
From: Ravi kumar Veeramally @ 2013-12-19  8:48 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Ravi kumar Veeramally

---
 profiles/network/bnep.c | 80 ++++++++++++++++++++++++-------------------------
 1 file changed, 40 insertions(+), 40 deletions(-)

diff --git a/profiles/network/bnep.c b/profiles/network/bnep.c
index 08037e6..02e2647 100644
--- a/profiles/network/bnep.c
+++ b/profiles/network/bnep.c
@@ -67,7 +67,7 @@ struct __service_16 {
 	uint16_t src;
 } __attribute__ ((packed));
 
-struct bnep_conn {
+struct bnep {
 	GIOChannel	*io;
 	uint16_t	src;
 	uint16_t	dst;
@@ -77,17 +77,17 @@ struct bnep_conn {
 	bnep_connect_cb	conn_cb;
 };
 
-static void free_bnep_connect(struct bnep_conn *bc)
+static void free_bnep_connect(struct bnep *b)
 {
-	if (!bc)
+	if (!b)
 		return;
 
-	if (bc->io) {
-		g_io_channel_unref(bc->io);
-		bc->io = NULL;
+	if (b->io) {
+		g_io_channel_unref(b->io);
+		b->io = NULL;
 	}
 
-	g_free(bc);
+	g_free(b);
 }
 
 uint16_t bnep_service_id(const char *svc)
@@ -249,7 +249,7 @@ int bnep_if_down(const char *devname)
 static gboolean bnep_setup_cb(GIOChannel *chan, GIOCondition cond,
 								gpointer data)
 {
-	struct bnep_conn *bc = data;
+	struct bnep *b = data;
 	struct bnep_control_rsp *rsp;
 	struct timeval timeo;
 	char pkt[BNEP_MTU];
@@ -260,9 +260,9 @@ static gboolean bnep_setup_cb(GIOChannel *chan, GIOCondition cond,
 	if (cond & G_IO_NVAL)
 		goto failed;
 
-	if (bc->setup_to > 0) {
-		g_source_remove(bc->setup_to);
-		bc->setup_to = 0;
+	if (b->setup_to > 0) {
+		g_source_remove(b->setup_to);
+		b->setup_to = 0;
 	}
 
 	if (cond & (G_IO_HUP | G_IO_ERR)) {
@@ -309,8 +309,8 @@ static gboolean bnep_setup_cb(GIOChannel *chan, GIOCondition cond,
 	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)) {
+	sk = g_io_channel_unix_get_fd(b->io);
+	if (bnep_connadd(sk, b->src, iface)) {
 		error("bnep conn could not be added");
 		goto failed;
 	}
@@ -320,19 +320,19 @@ static gboolean bnep_setup_cb(GIOChannel *chan, GIOCondition cond,
 		goto failed;
 	}
 
-	bc->conn_cb(chan, iface, 0, bc->data);
-	free_bnep_connect(bc);
+	b->conn_cb(chan, iface, 0, b->data);
+	free_bnep_connect(b);
 
 	return FALSE;
 
 failed:
-	bc->conn_cb(NULL, NULL, -EIO, bc->data);
-	free_bnep_connect(bc);
+	b->conn_cb(NULL, NULL, -EIO, b->data);
+	free_bnep_connect(b);
 
 	return FALSE;
 }
 
-static int bnep_setup_conn_req(struct bnep_conn *bc)
+static int bnep_setup_conn_req(struct bnep *b)
 {
 	struct bnep_setup_conn_req *req;
 	struct __service_16 *s;
@@ -345,34 +345,34 @@ static int bnep_setup_conn_req(struct bnep_conn *bc)
 	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);
+	s->src = htons(b->src);
+	s->dst = htons(b->dst);
 
-	fd = g_io_channel_unix_get_fd(bc->io);
+	fd = g_io_channel_unix_get_fd(b->io);
 	if (write(fd, pkt, sizeof(*req) + sizeof(*s)) < 0) {
 		error("bnep connection req send failed: %s", strerror(errno));
 		return -errno;
 	}
 
-	bc->attempts++;
+	b->attempts++;
 
 	return 0;
 }
 
 static gboolean bnep_conn_req_to(gpointer user_data)
 {
-	struct bnep_conn *bc = user_data;
+	struct bnep *b = user_data;
 
-	if (bc->attempts == CON_SETUP_RETRIES) {
+	if (b->attempts == CON_SETUP_RETRIES) {
 		error("Too many bnep connection attempts");
 	} else {
 		error("bnep connection setup TO, retrying...");
-		if (bnep_setup_conn_req(bc) == 0)
+		if (bnep_setup_conn_req(b) == 0)
 			return TRUE;
 	}
 
-	bc->conn_cb(NULL, NULL, -ETIMEDOUT, bc->data);
-	free_bnep_connect(bc);
+	b->conn_cb(NULL, NULL, -ETIMEDOUT, b->data);
+	free_bnep_connect(b);
 
 	return FALSE;
 }
@@ -380,28 +380,28 @@ static gboolean bnep_conn_req_to(gpointer user_data)
 int bnep_connect(int sk, uint16_t src, uint16_t dst, bnep_connect_cb conn_cb,
 								void *data)
 {
-	struct bnep_conn *bc;
+	struct bnep *b;
 	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;
+	b = g_new0(struct bnep, 1);
+	b->io = g_io_channel_unix_new(sk);
+	b->attempts = 0;
+	b->src = src;
+	b->dst = dst;
+	b->conn_cb = conn_cb;
+	b->data = data;
 
-	err = bnep_setup_conn_req(bc);
+	err = bnep_setup_conn_req(b);
 	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);
+	b->setup_to = g_timeout_add_seconds(CON_SETUP_TO,
+							bnep_conn_req_to, b);
+	g_io_add_watch(b->io, G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
+							bnep_setup_cb, b);
 	return 0;
 }
 
-- 
1.8.3.2


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

* [PATCH_v5 3/5] bnep: Add bnep_new and bnep_free api's
  2013-12-19  8:48 [PATCH_v5 1/5] android/pan: shutdown io channel on disconnect call Ravi kumar Veeramally
  2013-12-19  8:48 ` [PATCH_v5 2/5] bnep: Rename struct bnep_conn to struct bnep for better readability Ravi kumar Veeramally
@ 2013-12-19  8:48 ` Ravi kumar Veeramally
  2013-12-19  8:48 ` [PATCH_v5 4/5] bnep: Refactored bnep connect and disconnect calls Ravi kumar Veeramally
  2013-12-19  8:48 ` [PATCH_v5 5/5] bnep: Refactored bnep server apis for bridge addition and deletion Ravi kumar Veeramally
  3 siblings, 0 replies; 6+ messages in thread
From: Ravi kumar Veeramally @ 2013-12-19  8:48 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Ravi kumar Veeramally

Refacoring connect and disconnect mechanisms. It would be more
convinient for caller to maintain just bnep connection reference
and delete whenever it is not required.
---
 profiles/network/bnep.c | 25 +++++++++++++++++++++++++
 profiles/network/bnep.h |  4 ++++
 2 files changed, 29 insertions(+)

diff --git a/profiles/network/bnep.c b/profiles/network/bnep.c
index 02e2647..f3ed63b 100644
--- a/profiles/network/bnep.c
+++ b/profiles/network/bnep.c
@@ -246,6 +246,31 @@ int bnep_if_down(const char *devname)
 	return 0;
 }
 
+struct bnep *bnep_new(int sk, uint16_t local_role, uint16_t remote_role)
+{
+	struct bnep *b;
+
+	b = g_new0(struct bnep, 1);
+	b->io = g_io_channel_unix_new(sk);
+	b->src = local_role;
+	b->dst = remote_role;
+
+	return b;
+}
+
+void bnep_free(struct bnep *b)
+{
+	if (!b)
+		return;
+
+	if (b->io) {
+		g_io_channel_unref(b->io);
+		b->io = NULL;
+	}
+
+	g_free(b);
+}
+
 static gboolean bnep_setup_cb(GIOChannel *chan, GIOCondition cond,
 								gpointer data)
 {
diff --git a/profiles/network/bnep.h b/profiles/network/bnep.h
index dd22c40..091a7f2 100644
--- a/profiles/network/bnep.h
+++ b/profiles/network/bnep.h
@@ -21,6 +21,8 @@
  *
  */
 
+struct bnep;
+
 int bnep_init(void);
 int bnep_cleanup(void);
 
@@ -28,6 +30,8 @@ uint16_t bnep_service_id(const char *svc);
 const char *bnep_uuid(uint16_t id);
 const char *bnep_name(uint16_t id);
 
+struct bnep *bnep_new(int sk, uint16_t local_role, uint16_t remote_role);
+void bnep_free(struct bnep *b);
 int bnep_connadd(int sk, uint16_t role, char *dev);
 int bnep_conndel(const bdaddr_t *dst);
 int bnep_if_up(const char *devname);
-- 
1.8.3.2


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

* [PATCH_v5 4/5] bnep: Refactored bnep connect and disconnect calls
  2013-12-19  8:48 [PATCH_v5 1/5] android/pan: shutdown io channel on disconnect call Ravi kumar Veeramally
  2013-12-19  8:48 ` [PATCH_v5 2/5] bnep: Rename struct bnep_conn to struct bnep for better readability Ravi kumar Veeramally
  2013-12-19  8:48 ` [PATCH_v5 3/5] bnep: Add bnep_new and bnep_free api's Ravi kumar Veeramally
@ 2013-12-19  8:48 ` Ravi kumar Veeramally
  2013-12-19  8:48 ` [PATCH_v5 5/5] bnep: Refactored bnep server apis for bridge addition and deletion Ravi kumar Veeramally
  3 siblings, 0 replies; 6+ messages in thread
From: Ravi kumar Veeramally @ 2013-12-19  8:48 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Ravi kumar Veeramally

Refactored bnep connect and disconnect calls to simplify and
keeping bnep related functionality behind curtains.
Provided bnep struct globally. bnep_connect calls takes
care of bnep_setup until interface up then connect callback
will be called. Provided bnep_set_watchdog. When interface is
up then only set watchdog. bnep_disconnect should be called
only when iface is up/connected.
---
 android/pan.c                 | 50 ++++++++++++------------
 profiles/network/bnep.c       | 91 +++++++++++++++++++++++++++----------------
 profiles/network/bnep.h       |  8 ++--
 profiles/network/connection.c | 42 +++++++++++++-------
 4 files changed, 114 insertions(+), 77 deletions(-)

diff --git a/android/pan.c b/android/pan.c
index 187953b..2537114 100644
--- a/android/pan.c
+++ b/android/pan.c
@@ -55,6 +55,7 @@ struct pan_device {
 	uint8_t		role;
 	GIOChannel	*io;
 	guint		watch;
+	struct bnep	*bnep_conn;
 };
 
 static int device_cmp(gconstpointer s, gconstpointer user_data)
@@ -67,6 +68,8 @@ static int device_cmp(gconstpointer s, gconstpointer user_data)
 
 static void pan_device_free(struct pan_device *dev)
 {
+	DBG("");
+
 	if (dev->watch > 0) {
 		g_source_remove(dev->watch);
 		dev->watch = 0;
@@ -77,6 +80,7 @@ static void pan_device_free(struct pan_device *dev)
 		dev->io = NULL;
 	}
 
+	bnep_free(dev->bnep_conn);
 	devices = g_slist_remove(devices, dev);
 	g_free(dev);
 
@@ -92,7 +96,6 @@ static void bt_pan_notify_conn_state(struct pan_device *dev, uint8_t state)
 	if (dev->conn_state == state)
 		return;
 
-	dev->conn_state = state;
 	ba2str(&dev->dst, addr);
 	DBG("device %s state %u", addr, state);
 
@@ -104,8 +107,16 @@ static void bt_pan_notify_conn_state(struct pan_device *dev, uint8_t state)
 
 	ipc_send_notif(HAL_SERVICE_ID_PAN, HAL_EV_PAN_CONN_STATE, sizeof(ev),
 									&ev);
-	if (dev->conn_state == HAL_PAN_STATE_DISCONNECTED)
-		pan_device_free(dev);
+
+	if (dev->conn_state == HAL_PAN_STATE_CONNECTED)
+		bnep_disconnect(dev->bnep_conn);
+
+	dev->conn_state = state;
+
+	if (state != HAL_PAN_STATE_DISCONNECTED)
+		return;
+
+	pan_device_free(dev);
 }
 
 static void bt_pan_notify_ctrl_state(struct pan_device *dev, uint8_t state)
@@ -131,14 +142,12 @@ static gboolean bnep_watchdog_cb(GIOChannel *chan, GIOCondition cond,
 
 	DBG("%s disconnected", dev->iface);
 
-	bnep_if_down(dev->iface);
-	bnep_conndel(&dev->dst);
 	bt_pan_notify_conn_state(dev, HAL_PAN_STATE_DISCONNECTED);
 
 	return FALSE;
 }
 
-static void bnep_conn_cb(GIOChannel *chan, char *iface, int err, void *data)
+static void bnep_conn_cb(char *iface, int err, void *data)
 {
 	struct pan_device *dev = data;
 
@@ -146,28 +155,22 @@ static void bnep_conn_cb(GIOChannel *chan, char *iface, int err, void *data)
 
 	if (err < 0) {
 		error("bnep connect req failed: %s", strerror(-err));
-		bnep_conndel(&dev->dst);
 		bt_pan_notify_conn_state(dev, HAL_PAN_STATE_DISCONNECTED);
 		return;
 	}
 
-	memcpy(dev->iface, iface, sizeof(dev->iface));
-
-	DBG("%s connected", dev->iface);
+	DBG("%s connected", iface);
 
+	memcpy(dev->iface, iface, sizeof(dev->iface));
 	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;
+	dev->watch = bnep_set_watchdog(dev->bnep_conn, bnep_watchdog_cb, dev);
 }
 
 static void connect_cb(GIOChannel *chan, GError *err, gpointer data)
 {
 	struct pan_device *dev = data;
-	uint16_t src, dst;
+	uint16_t l_role, r_role;
 	int perr, sk;
 
 	DBG("");
@@ -177,11 +180,13 @@ static void connect_cb(GIOChannel *chan, GError *err, gpointer data)
 		goto fail;
 	}
 
-	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);
+	l_role = (local_role == HAL_PAN_ROLE_NAP) ? BNEP_SVC_NAP :
+								BNEP_SVC_PANU;
+	r_role = (dev->role == HAL_PAN_ROLE_NAP) ? BNEP_SVC_NAP : BNEP_SVC_PANU;
 
-	perr = bnep_connect(sk, src, dst, bnep_conn_cb, dev);
+	sk = g_io_channel_unix_get_fd(dev->io);
+	dev->bnep_conn = bnep_new(sk, l_role, r_role);
+	perr = bnep_connect(dev->bnep_conn, bnep_conn_cb, dev);
 	if (perr < 0) {
 		error("bnep connect req failed: %s", strerror(-perr));
 		goto fail;
@@ -288,11 +293,6 @@ static void bt_pan_disconnect(const void *buf, uint16_t len)
 	if (dev->io)
 		g_io_channel_shutdown(dev->io, TRUE, NULL);
 
-	if (dev->conn_state == HAL_PAN_STATE_CONNECTED) {
-		bnep_if_down(dev->iface);
-		bnep_conndel(&dst);
-	}
-
 	bt_pan_notify_conn_state(dev, HAL_PAN_STATE_DISCONNECTING);
 	status = HAL_STATUS_SUCCESS;
 
diff --git a/profiles/network/bnep.c b/profiles/network/bnep.c
index f3ed63b..b7c3835 100644
--- a/profiles/network/bnep.c
+++ b/profiles/network/bnep.c
@@ -39,6 +39,7 @@
 #include <bluetooth/bluetooth.h>
 #include <bluetooth/l2cap.h>
 #include <bluetooth/bnep.h>
+#include <btio/btio.h>
 
 #include <glib.h>
 
@@ -71,25 +72,15 @@ struct bnep {
 	GIOChannel	*io;
 	uint16_t	src;
 	uint16_t	dst;
+	bdaddr_t	dst_addr;
+	char	iface[16];
 	guint	attempts;
 	guint	setup_to;
 	void	*data;
 	bnep_connect_cb	conn_cb;
+	guint watch;
 };
 
-static void free_bnep_connect(struct bnep *b)
-{
-	if (!b)
-		return;
-
-	if (b->io) {
-		g_io_channel_unref(b->io);
-		b->io = NULL;
-	}
-
-	g_free(b);
-}
-
 uint16_t bnep_service_id(const char *svc)
 {
 	int i;
@@ -278,12 +269,11 @@ static gboolean bnep_setup_cb(GIOChannel *chan, GIOCondition cond,
 	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;
+		return FALSE;
 
 	if (b->setup_to > 0) {
 		g_source_remove(b->setup_to);
@@ -335,24 +325,23 @@ static gboolean bnep_setup_cb(GIOChannel *chan, GIOCondition cond,
 	setsockopt(sk, SOL_SOCKET, SO_RCVTIMEO, &timeo, sizeof(timeo));
 
 	sk = g_io_channel_unix_get_fd(b->io);
-	if (bnep_connadd(sk, b->src, iface)) {
+	if (bnep_connadd(sk, b->src, b->iface)) {
 		error("bnep conn could not be added");
 		goto failed;
 	}
 
-	if (bnep_if_up(iface)) {
-		error("could not up %s", iface);
+	if (bnep_if_up(b->iface)) {
+		error("could not up %s", b->iface);
+		bnep_conndel(&b->dst_addr);
 		goto failed;
 	}
 
-	b->conn_cb(chan, iface, 0, b->data);
-	free_bnep_connect(b);
+	b->conn_cb(b->iface, 0, b->data);
 
 	return FALSE;
 
 failed:
-	b->conn_cb(NULL, NULL, -EIO, b->data);
-	free_bnep_connect(b);
+	b->conn_cb(NULL, -EIO, b->data);
 
 	return FALSE;
 }
@@ -396,40 +385,76 @@ static gboolean bnep_conn_req_to(gpointer user_data)
 			return TRUE;
 	}
 
-	b->conn_cb(NULL, NULL, -ETIMEDOUT, b->data);
-	free_bnep_connect(b);
+	b->conn_cb(NULL, -ETIMEDOUT, b->data);
 
 	return FALSE;
 }
 
-int bnep_connect(int sk, uint16_t src, uint16_t dst, bnep_connect_cb conn_cb,
-								void *data)
+int bnep_connect(struct bnep *b, bnep_connect_cb conn_cb, void *data)
 {
-	struct bnep *b;
+	GError *gerr = NULL;
 	int err;
 
-	if (!conn_cb)
+	if (!b || !conn_cb)
 		return -EINVAL;
 
-	b = g_new0(struct bnep, 1);
-	b->io = g_io_channel_unix_new(sk);
 	b->attempts = 0;
-	b->src = src;
-	b->dst = dst;
 	b->conn_cb = conn_cb;
 	b->data = data;
 
+	bt_io_get(b->io, &gerr, BT_IO_OPT_DEST_BDADDR, &b->dst_addr,
+							BT_IO_OPT_INVALID);
+	if (gerr) {
+		error("%s", gerr->message);
+		g_error_free(gerr);
+		return -EINVAL;
+	}
+
 	err = bnep_setup_conn_req(b);
 	if (err < 0)
 		return err;
 
 	b->setup_to = g_timeout_add_seconds(CON_SETUP_TO,
 							bnep_conn_req_to, b);
-	g_io_add_watch(b->io, G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
+	b->watch = g_io_add_watch(b->io,
+				G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
 							bnep_setup_cb, b);
 	return 0;
 }
 
+void bnep_disconnect(struct bnep *b)
+{
+	if (!b)
+		return;
+
+	if (b->io) {
+		g_io_channel_unref(b->io);
+		b->io = NULL;
+	}
+
+	if (b->watch) {
+		g_source_remove(b->watch);
+		b->watch = 0;
+	}
+
+	bnep_if_down(b->iface);
+	bnep_conndel(&b->dst_addr);
+}
+
+guint bnep_set_watchdog(struct bnep *b, GIOFunc watchdog, void *data)
+{
+	guint ret = 0;
+
+	if (!b)
+		return ret;
+
+	if (b->io)
+		ret = g_io_add_watch(b->io, G_IO_ERR | G_IO_HUP | G_IO_NVAL,
+								watchdog, data);
+
+	return ret;
+}
+
 int bnep_add_to_bridge(const char *devname, const char *bridge)
 {
 	int ifindex;
diff --git a/profiles/network/bnep.h b/profiles/network/bnep.h
index 091a7f2..46199df 100644
--- a/profiles/network/bnep.h
+++ b/profiles/network/bnep.h
@@ -39,10 +39,10 @@ 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);
+typedef void (*bnep_connect_cb) (char *iface, int err, void *data);
+int bnep_connect(struct bnep *b, bnep_connect_cb conn_cb, void *data);
+guint bnep_set_watchdog(struct bnep *b, GIOFunc watchdog, void *data);
+void bnep_disconnect(struct bnep *b);
 
 ssize_t bnep_send_ctrl_rsp(int sk, uint8_t type, uint8_t ctrl, uint16_t resp);
 uint16_t bnep_setup_chk(uint16_t dst_role, uint16_t src_role);
diff --git a/profiles/network/connection.c b/profiles/network/connection.c
index fb3e1ce..f1a44e9 100644
--- a/profiles/network/connection.c
+++ b/profiles/network/connection.c
@@ -72,6 +72,8 @@ struct network_conn {
 	guint		dc_id;
 	struct network_peer *peer;
 	DBusMessage	*connect;
+	struct bnep	*bnep_conn;
+	guint		watch;
 };
 
 static GSList *peers = NULL;
@@ -126,11 +128,19 @@ static gboolean bnep_watchdog_cb(GIOChannel *chan, GIOCondition cond,
 
 	info("%s disconnected", nc->dev);
 
-	bnep_if_down(nc->dev);
 	nc->state = DISCONNECTED;
 	memset(nc->dev, 0, sizeof(nc->dev));
 	strcpy(nc->dev, "bnep%d");
 
+	bnep_free(nc->bnep_conn);
+	nc->bnep_conn = NULL;
+
+	if (nc->io) {
+		g_io_channel_shutdown(nc->io, TRUE, NULL);
+		g_io_channel_unref(nc->io);
+		nc->io = NULL;
+	}
+
 	return FALSE;
 }
 
@@ -158,9 +168,17 @@ static void cancel_connection(struct network_conn *nc, int err)
 	if (nc->connect)
 		local_connect_cb(nc, err);
 
-	g_io_channel_shutdown(nc->io, TRUE, NULL);
-	g_io_channel_unref(nc->io);
-	nc->io = NULL;
+	if (nc->io) {
+		g_io_channel_shutdown(nc->io, TRUE, NULL);
+		g_io_channel_unref(nc->io);
+		nc->io = NULL;
+	}
+
+	if (nc->state == CONNECTED)
+		bnep_disconnect(nc->bnep_conn);
+
+	bnep_free(nc->bnep_conn);
+	nc->bnep_conn = NULL;
 
 	nc->state = DISCONNECTED;
 }
@@ -169,11 +187,7 @@ static void connection_destroy(DBusConnection *conn, void *user_data)
 {
 	struct network_conn *nc = user_data;
 
-	if (nc->state == CONNECTED) {
-		bnep_if_down(nc->dev);
-		bnep_conndel(device_get_address(nc->peer->device));
-	} else if (nc->io)
-		cancel_connection(nc, -EIO);
+	cancel_connection(nc, -EIO);
 }
 
 static void disconnect_cb(struct btd_device *device, gboolean removal,
@@ -186,7 +200,7 @@ static void disconnect_cb(struct btd_device *device, gboolean removal,
 	connection_destroy(NULL, user_data);
 }
 
-static void bnep_conn_cb(GIOChannel *chan, char *iface, int err, void *data)
+static void bnep_conn_cb(char *iface, int err, void *data)
 {
 	struct network_conn *nc = data;
 	const char *path;
@@ -220,10 +234,7 @@ static void bnep_conn_cb(GIOChannel *chan, char *iface, int err, void *data)
 	nc->state = CONNECTED;
 	nc->dc_id = device_add_disconnect_watch(nc->peer->device, disconnect_cb,
 								nc, NULL);
-	g_io_add_watch(chan, G_IO_ERR | G_IO_HUP | G_IO_NVAL,
-							bnep_watchdog_cb, nc);
-	g_io_channel_unref(nc->io);
-	nc->io = NULL;
+	nc->watch = bnep_set_watchdog(nc->bnep_conn, bnep_watchdog_cb, nc);
 
 	return;
 
@@ -242,7 +253,8 @@ static void connect_cb(GIOChannel *chan, GError *err, gpointer data)
 	}
 
 	sk = g_io_channel_unix_get_fd(nc->io);
-	perr = bnep_connect(sk, BNEP_SVC_PANU, nc->id, bnep_conn_cb, nc);
+	nc->bnep_conn = bnep_new(sk, BNEP_SVC_PANU, nc->id);
+	perr = bnep_connect(nc->bnep_conn, bnep_conn_cb, nc);
 	if (perr < 0) {
 		error("bnep connect(): %s (%d)", strerror(-perr), -perr);
 		goto failed;
-- 
1.8.3.2


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

* [PATCH_v5 5/5] bnep: Refactored bnep server apis for bridge addition and deletion
  2013-12-19  8:48 [PATCH_v5 1/5] android/pan: shutdown io channel on disconnect call Ravi kumar Veeramally
                   ` (2 preceding siblings ...)
  2013-12-19  8:48 ` [PATCH_v5 4/5] bnep: Refactored bnep connect and disconnect calls Ravi kumar Veeramally
@ 2013-12-19  8:48 ` Ravi kumar Veeramally
  3 siblings, 0 replies; 6+ messages in thread
From: Ravi kumar Veeramally @ 2013-12-19  8:48 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Ravi kumar Veeramally

To simplify bnep server realted bridge creation and deletion calls
provided extra apis and moved existing apis to static.
---
 profiles/network/bnep.c   | 50 +++++++++++++++++++++++++++++++++++++++++------
 profiles/network/bnep.h   |  9 +++------
 profiles/network/server.c | 37 +++--------------------------------
 3 files changed, 50 insertions(+), 46 deletions(-)

diff --git a/profiles/network/bnep.c b/profiles/network/bnep.c
index b7c3835..90728d3 100644
--- a/profiles/network/bnep.c
+++ b/profiles/network/bnep.c
@@ -151,7 +151,7 @@ int bnep_cleanup(void)
 	return 0;
 }
 
-int bnep_conndel(const bdaddr_t *dst)
+static int bnep_conndel(const bdaddr_t *dst)
 {
 	struct bnep_conndel_req req;
 
@@ -167,7 +167,7 @@ int bnep_conndel(const bdaddr_t *dst)
 	return 0;
 }
 
-int bnep_connadd(int sk, uint16_t role, char *dev)
+static int bnep_connadd(int sk, uint16_t role, char *dev)
 {
 	struct bnep_connadd_req req;
 
@@ -187,7 +187,7 @@ int bnep_connadd(int sk, uint16_t role, char *dev)
 	return 0;
 }
 
-int bnep_if_up(const char *devname)
+static int bnep_if_up(const char *devname)
 {
 	struct ifreq ifr;
 	int sk, err;
@@ -212,7 +212,7 @@ int bnep_if_up(const char *devname)
 	return 0;
 }
 
-int bnep_if_down(const char *devname)
+static int bnep_if_down(const char *devname)
 {
 	struct ifreq ifr;
 	int sk, err;
@@ -455,7 +455,7 @@ guint bnep_set_watchdog(struct bnep *b, GIOFunc watchdog, void *data)
 	return ret;
 }
 
-int bnep_add_to_bridge(const char *devname, const char *bridge)
+static int bnep_add_to_bridge(const char *devname, const char *bridge)
 {
 	int ifindex;
 	struct ifreq ifr;
@@ -486,7 +486,7 @@ int bnep_add_to_bridge(const char *devname, const char *bridge)
 	return 0;
 }
 
-int bnep_del_from_bridge(const char *devname, const char *bridge)
+static int bnep_del_from_bridge(const char *devname, const char *bridge)
 {
 	int ifindex = if_nametoindex(devname);
 	struct ifreq ifr;
@@ -592,3 +592,41 @@ uint16_t bnep_setup_decode(struct bnep_setup_conn_req *req, uint16_t *dst,
 
 	return BNEP_SUCCESS;
 }
+
+int bnep_server_add(int sk, uint16_t dst, char *bridge, char *iface,
+						const bdaddr_t *addr)
+{
+	if (!bridge || !bridge || !iface || !addr)
+		return -EINVAL;
+
+	if (bnep_connadd(sk, dst, iface) < 0) {
+		error("Can't add connection to the bridge %s: %s(%d)",
+						bridge, strerror(errno), errno);
+		return -errno;
+	}
+
+	if (bnep_add_to_bridge(iface, bridge) < 0) {
+		error("Can't add %s to the bridge %s: %s(%d)",
+					iface, bridge, strerror(errno), errno);
+		bnep_conndel(addr);
+		return -errno;
+	}
+
+	if (bnep_if_up(iface) < 0) {
+		error("Can't up the interface %s: %s(%d)",
+						iface, strerror(errno), errno);
+		return -errno;
+	}
+
+	return 0;
+}
+
+void bnep_server_delete(char *bridge, char *iface, const bdaddr_t *addr)
+{
+	if (!bridge || !iface || !addr)
+		return;
+
+	bnep_del_from_bridge(iface, bridge);
+	bnep_if_down(iface);
+	bnep_conndel(addr);
+}
diff --git a/profiles/network/bnep.h b/profiles/network/bnep.h
index 46199df..3447f6e 100644
--- a/profiles/network/bnep.h
+++ b/profiles/network/bnep.h
@@ -32,12 +32,6 @@ const char *bnep_name(uint16_t id);
 
 struct bnep *bnep_new(int sk, uint16_t local_role, uint16_t remote_role);
 void bnep_free(struct bnep *b);
-int bnep_connadd(int sk, uint16_t role, char *dev);
-int bnep_conndel(const bdaddr_t *dst);
-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) (char *iface, int err, void *data);
 int bnep_connect(struct bnep *b, bnep_connect_cb conn_cb, void *data);
@@ -48,3 +42,6 @@ ssize_t bnep_send_ctrl_rsp(int sk, uint8_t type, uint8_t ctrl, uint16_t resp);
 uint16_t bnep_setup_chk(uint16_t dst_role, uint16_t src_role);
 uint16_t bnep_setup_decode(struct bnep_setup_conn_req *req, uint16_t *dst,
 								uint16_t *src);
+int bnep_server_add(int sk, uint16_t dst, char *bridge, char *iface,
+							const bdaddr_t *addr);
+void bnep_server_delete(char *bridge, char *iface, const bdaddr_t *addr);
diff --git a/profiles/network/server.c b/profiles/network/server.c
index 73741ec..7cb5a1e 100644
--- a/profiles/network/server.c
+++ b/profiles/network/server.c
@@ -251,35 +251,6 @@ static sdp_record_t *server_record_new(const char *name, uint16_t id)
 	return record;
 }
 
-static int server_connadd(struct network_server *ns,
-				struct network_session *session,
-				uint16_t dst_role)
-{
-	char devname[16];
-	int err, nsk;
-
-	nsk = g_io_channel_unix_get_fd(session->io);
-	err = bnep_connadd(nsk, dst_role, devname);
-	if (err < 0)
-		return err;
-
-	info("Added new connection: %s", devname);
-
-	if (bnep_add_to_bridge(devname, ns->bridge) < 0) {
-		error("Can't add %s to the bridge %s: %s(%d)",
-				devname, ns->bridge, strerror(errno), errno);
-		return -EPERM;
-	}
-
-	bnep_if_up(devname);
-
-	strncpy(session->dev, devname, sizeof(devname));
-
-	ns->sessions = g_slist_append(ns->sessions, session);
-
-	return 0;
-}
-
 static void session_free(void *data)
 {
 	struct network_session *session = data;
@@ -377,7 +348,8 @@ static gboolean bnep_setup(GIOChannel *chan,
 		goto reply;
 	}
 
-	if (server_connadd(ns, na->setup, dst_role) < 0)
+	if (bnep_server_add(sk, dst_role, ns->bridge, na->setup->dev,
+							&na->setup->dst) < 0)
 		goto reply;
 
 	na->setup = NULL;
@@ -524,10 +496,7 @@ static void server_remove_sessions(struct network_server *ns)
 		if (*session->dev == '\0')
 			continue;
 
-		bnep_del_from_bridge(session->dev, ns->bridge);
-		bnep_if_down(session->dev);
-
-		bnep_conndel(&session->dst);
+		bnep_server_delete(ns->bridge, session->dev, &session->dst);
 	}
 
 	g_slist_free_full(ns->sessions, session_free);
-- 
1.8.3.2


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

* [PATCH_v5 1/5] android/pan: shutdown io channel on disconnect call
@ 2013-12-19  9:15 Ravi kumar Veeramally
  0 siblings, 0 replies; 6+ messages in thread
From: Ravi kumar Veeramally @ 2013-12-19  9:15 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Ravi kumar Veeramally

Shutdown io channel and send DISCONNECTING notification and send
DISCONNECTED notification and free the device on callback.
---
 android/pan.c | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/android/pan.c b/android/pan.c
index b83f534..187953b 100644
--- a/android/pan.c
+++ b/android/pan.c
@@ -284,14 +284,16 @@ static void bt_pan_disconnect(const void *buf, uint16_t len)
 	}
 
 	dev = l->data;
-	if (dev->watch) {
-		g_source_remove(dev->watch);
-		dev->watch = 0;
+
+	if (dev->io)
+		g_io_channel_shutdown(dev->io, TRUE, NULL);
+
+	if (dev->conn_state == HAL_PAN_STATE_CONNECTED) {
+		bnep_if_down(dev->iface);
+		bnep_conndel(&dst);
 	}
 
-	bnep_if_down(dev->iface);
-	bnep_conndel(&dst);
-	bt_pan_notify_conn_state(dev, HAL_PAN_STATE_DISCONNECTED);
+	bt_pan_notify_conn_state(dev, HAL_PAN_STATE_DISCONNECTING);
 	status = HAL_STATUS_SUCCESS;
 
 failed:
-- 
1.8.3.2


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

end of thread, other threads:[~2013-12-19  9:15 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-12-19  8:48 [PATCH_v5 1/5] android/pan: shutdown io channel on disconnect call Ravi kumar Veeramally
2013-12-19  8:48 ` [PATCH_v5 2/5] bnep: Rename struct bnep_conn to struct bnep for better readability Ravi kumar Veeramally
2013-12-19  8:48 ` [PATCH_v5 3/5] bnep: Add bnep_new and bnep_free api's Ravi kumar Veeramally
2013-12-19  8:48 ` [PATCH_v5 4/5] bnep: Refactored bnep connect and disconnect calls Ravi kumar Veeramally
2013-12-19  8:48 ` [PATCH_v5 5/5] bnep: Refactored bnep server apis for bridge addition and deletion Ravi kumar Veeramally
  -- strict thread matches above, loose matches on Subject: below --
2013-12-19  9:15 [PATCH_v5 1/5] android/pan: shutdown io channel on disconnect call Ravi kumar Veeramally

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).