* [PATCH_v4 1/7] android/pan: Free device after sending diconnected notification
@ 2013-12-18 14:53 Ravi kumar Veeramally
2013-12-18 14:53 ` [PATCH_v4 2/7] android/pan: Change local_role to NONE only when device list is empty Ravi kumar Veeramally
` (5 more replies)
0 siblings, 6 replies; 9+ messages in thread
From: Ravi kumar Veeramally @ 2013-12-18 14:53 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Ravi kumar Veeramally
---
android/pan.c | 9 ++-------
1 file changed, 2 insertions(+), 7 deletions(-)
diff --git a/android/pan.c b/android/pan.c
index e410f54..2bbba9e 100644
--- a/android/pan.c
+++ b/android/pan.c
@@ -103,6 +103,8 @@ 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);
}
static void bt_pan_notify_ctrl_state(struct pan_device *dev, uint8_t state)
@@ -131,7 +133,6 @@ static gboolean bnep_watchdog_cb(GIOChannel *chan, GIOCondition cond,
bnep_if_down(dev->iface);
bnep_conndel(&dev->dst);
bt_pan_notify_conn_state(dev, HAL_PAN_STATE_DISCONNECTED);
- pan_device_free(dev);
return FALSE;
}
@@ -146,7 +147,6 @@ static void bnep_conn_cb(GIOChannel *chan, char *iface, int err, void *data)
error("bnep connect req failed: %s", strerror(-err));
bnep_conndel(&dev->dst);
bt_pan_notify_conn_state(dev, HAL_PAN_STATE_DISCONNECTED);
- pan_device_free(dev);
return;
}
@@ -190,7 +190,6 @@ static void connect_cb(GIOChannel *chan, GError *err, gpointer data)
fail:
bt_pan_notify_conn_state(dev, HAL_PAN_STATE_DISCONNECTED);
- pan_device_free(dev);
}
static void bt_pan_connect(const void *buf, uint16_t len)
@@ -284,7 +283,6 @@ 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;
@@ -292,10 +290,7 @@ static void bt_pan_disconnect(const void *buf, uint16_t len)
bnep_if_down(dev->iface);
bnep_conndel(&dst);
-
bt_pan_notify_conn_state(dev, HAL_PAN_STATE_DISCONNECTED);
- pan_device_free(dev);
-
status = HAL_STATUS_SUCCESS;
failed:
--
1.8.3.2
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH_v4 2/7] android/pan: Change local_role to NONE only when device list is empty
2013-12-18 14:53 [PATCH_v4 1/7] android/pan: Free device after sending diconnected notification Ravi kumar Veeramally
@ 2013-12-18 14:53 ` Ravi kumar Veeramally
2013-12-18 14:53 ` [PATCH_v4 3/7] android/pan: shutdown io channel on disconnect call Ravi kumar Veeramally
` (4 subsequent siblings)
5 siblings, 0 replies; 9+ messages in thread
From: Ravi kumar Veeramally @ 2013-12-18 14:53 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Ravi kumar Veeramally
---
android/pan.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/android/pan.c b/android/pan.c
index 2bbba9e..b83f534 100644
--- a/android/pan.c
+++ b/android/pan.c
@@ -67,8 +67,6 @@ static int device_cmp(gconstpointer s, gconstpointer user_data)
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;
@@ -81,6 +79,9 @@ static void pan_device_free(struct pan_device *dev)
devices = g_slist_remove(devices, dev);
g_free(dev);
+
+ if (g_slist_length(devices) == 0)
+ local_role = HAL_PAN_ROLE_NONE;
}
static void bt_pan_notify_conn_state(struct pan_device *dev, uint8_t state)
--
1.8.3.2
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH_v4 3/7] android/pan: shutdown io channel on disconnect call
2013-12-18 14:53 [PATCH_v4 1/7] android/pan: Free device after sending diconnected notification Ravi kumar Veeramally
2013-12-18 14:53 ` [PATCH_v4 2/7] android/pan: Change local_role to NONE only when device list is empty Ravi kumar Veeramally
@ 2013-12-18 14:53 ` Ravi kumar Veeramally
2013-12-19 8:14 ` Johan Hedberg
2013-12-18 14:53 ` [PATCH_v4 4/7] bnep: Rename struct bnep_conn to struct bnep for better readability Ravi kumar Veeramally
` (3 subsequent siblings)
5 siblings, 1 reply; 9+ messages in thread
From: Ravi kumar Veeramally @ 2013-12-18 14:53 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 | 20 ++++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/android/pan.c b/android/pan.c
index b83f534..f64b09a 100644
--- a/android/pan.c
+++ b/android/pan.c
@@ -269,7 +269,7 @@ static void bt_pan_disconnect(const void *buf, uint16_t len)
{
const struct hal_cmd_pan_disconnect *cmd = buf;
struct pan_device *dev;
- uint8_t status;
+ uint8_t status = HAL_STATUS_FAILED;
GSList *l;
bdaddr_t dst;
@@ -278,20 +278,20 @@ static void bt_pan_disconnect(const void *buf, uint16_t len)
android2bdaddr(&cmd->bdaddr, &dst);
l = g_slist_find_custom(devices, &dst, device_cmp);
- if (!l) {
- status = HAL_STATUS_FAILED;
+ if (!l)
goto failed;
- }
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] 9+ messages in thread
* [PATCH_v4 4/7] bnep: Rename struct bnep_conn to struct bnep for better readability
2013-12-18 14:53 [PATCH_v4 1/7] android/pan: Free device after sending diconnected notification Ravi kumar Veeramally
2013-12-18 14:53 ` [PATCH_v4 2/7] android/pan: Change local_role to NONE only when device list is empty Ravi kumar Veeramally
2013-12-18 14:53 ` [PATCH_v4 3/7] android/pan: shutdown io channel on disconnect call Ravi kumar Veeramally
@ 2013-12-18 14:53 ` Ravi kumar Veeramally
2013-12-18 14:53 ` [PATCH_v4 5/7] bnep: Add bnep_new and bnep_free api's Ravi kumar Veeramally
` (2 subsequent siblings)
5 siblings, 0 replies; 9+ messages in thread
From: Ravi kumar Veeramally @ 2013-12-18 14:53 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] 9+ messages in thread
* [PATCH_v4 5/7] bnep: Add bnep_new and bnep_free api's
2013-12-18 14:53 [PATCH_v4 1/7] android/pan: Free device after sending diconnected notification Ravi kumar Veeramally
` (2 preceding siblings ...)
2013-12-18 14:53 ` [PATCH_v4 4/7] bnep: Rename struct bnep_conn to struct bnep for better readability Ravi kumar Veeramally
@ 2013-12-18 14:53 ` Ravi kumar Veeramally
2013-12-18 14:53 ` [PATCH_v4 6/7] bnep: Refactored bnep connect and disconnect calls Ravi kumar Veeramally
2013-12-18 14:53 ` [PATCH_v4 7/7] bnep: Refactored bnep server apis for bridge addition and deletion Ravi kumar Veeramally
5 siblings, 0 replies; 9+ messages in thread
From: Ravi kumar Veeramally @ 2013-12-18 14:53 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] 9+ messages in thread
* [PATCH_v4 6/7] bnep: Refactored bnep connect and disconnect calls
2013-12-18 14:53 [PATCH_v4 1/7] android/pan: Free device after sending diconnected notification Ravi kumar Veeramally
` (3 preceding siblings ...)
2013-12-18 14:53 ` [PATCH_v4 5/7] bnep: Add bnep_new and bnep_free api's Ravi kumar Veeramally
@ 2013-12-18 14:53 ` Ravi kumar Veeramally
2013-12-18 14:53 ` [PATCH_v4 7/7] bnep: Refactored bnep server apis for bridge addition and deletion Ravi kumar Veeramally
5 siblings, 0 replies; 9+ messages in thread
From: Ravi kumar Veeramally @ 2013-12-18 14:53 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 f64b09a..85b1855 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;
@@ -286,11 +291,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] 9+ messages in thread
* [PATCH_v4 7/7] bnep: Refactored bnep server apis for bridge addition and deletion
2013-12-18 14:53 [PATCH_v4 1/7] android/pan: Free device after sending diconnected notification Ravi kumar Veeramally
` (4 preceding siblings ...)
2013-12-18 14:53 ` [PATCH_v4 6/7] bnep: Refactored bnep connect and disconnect calls Ravi kumar Veeramally
@ 2013-12-18 14:53 ` Ravi kumar Veeramally
5 siblings, 0 replies; 9+ messages in thread
From: Ravi kumar Veeramally @ 2013-12-18 14:53 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] 9+ messages in thread
* Re: [PATCH_v4 3/7] android/pan: shutdown io channel on disconnect call
2013-12-18 14:53 ` [PATCH_v4 3/7] android/pan: shutdown io channel on disconnect call Ravi kumar Veeramally
@ 2013-12-19 8:14 ` Johan Hedberg
2013-12-19 8:48 ` Ravi kumar Veeramally
0 siblings, 1 reply; 9+ messages in thread
From: Johan Hedberg @ 2013-12-19 8:14 UTC (permalink / raw)
To: Ravi kumar Veeramally; +Cc: linux-bluetooth
Hi Ravi,
On Wed, Dec 18, 2013, Ravi kumar Veeramally wrote:
> Shutdown io channel and send DISCONNECTING notification and send
> DISCONNECTED notification and free the device on callback.
> ---
> android/pan.c | 20 ++++++++++----------
> 1 file changed, 10 insertions(+), 10 deletions(-)
I've applied the first two patches, but one thing with this one:
> diff --git a/android/pan.c b/android/pan.c
> index b83f534..f64b09a 100644
> --- a/android/pan.c
> +++ b/android/pan.c
> @@ -269,7 +269,7 @@ static void bt_pan_disconnect(const void *buf, uint16_t len)
> {
> const struct hal_cmd_pan_disconnect *cmd = buf;
> struct pan_device *dev;
> - uint8_t status;
> + uint8_t status = HAL_STATUS_FAILED;
> GSList *l;
> bdaddr_t dst;
>
> @@ -278,20 +278,20 @@ static void bt_pan_disconnect(const void *buf, uint16_t len)
> android2bdaddr(&cmd->bdaddr, &dst);
>
> l = g_slist_find_custom(devices, &dst, device_cmp);
> - if (!l) {
> - status = HAL_STATUS_FAILED;
> + if (!l)
> goto failed;
Since we in general try to avoid initializations upon declaration I'd
keep the status = HAL_STATUS_FAILED here. Even if it would be ok to move
it it shouldn't be in this patch since it's unrelated.
Johan
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH_v4 3/7] android/pan: shutdown io channel on disconnect call
2013-12-19 8:14 ` Johan Hedberg
@ 2013-12-19 8:48 ` Ravi kumar Veeramally
0 siblings, 0 replies; 9+ messages in thread
From: Ravi kumar Veeramally @ 2013-12-19 8:48 UTC (permalink / raw)
To: linux-bluetooth, johan.hedberg
Hi Johan,
On 19.12.2013 10:14, Johan Hedberg wrote:
> Hi Ravi,
>
> On Wed, Dec 18, 2013, Ravi kumar Veeramally wrote:
>> Shutdown io channel and send DISCONNECTING notification and send
>> DISCONNECTED notification and free the device on callback.
>> ---
>> android/pan.c | 20 ++++++++++----------
>> 1 file changed, 10 insertions(+), 10 deletions(-)
> I've applied the first two patches, but one thing with this one:
>
>> diff --git a/android/pan.c b/android/pan.c
>> index b83f534..f64b09a 100644
>> --- a/android/pan.c
>> +++ b/android/pan.c
>> @@ -269,7 +269,7 @@ static void bt_pan_disconnect(const void *buf, uint16_t len)
>> {
>> const struct hal_cmd_pan_disconnect *cmd = buf;
>> struct pan_device *dev;
>> - uint8_t status;
>> + uint8_t status = HAL_STATUS_FAILED;
>> GSList *l;
>> bdaddr_t dst;
>>
>> @@ -278,20 +278,20 @@ static void bt_pan_disconnect(const void *buf, uint16_t len)
>> android2bdaddr(&cmd->bdaddr, &dst);
>>
>> l = g_slist_find_custom(devices, &dst, device_cmp);
>> - if (!l) {
>> - status = HAL_STATUS_FAILED;
>> + if (!l)
>> goto failed;
> Since we in general try to avoid initializations upon declaration I'd
> keep the status = HAL_STATUS_FAILED here. Even if it would be ok to move
> it it shouldn't be in this patch since it's unrelated.
Ok, make sense. I'll send you updated patch set from 3-7 in a moment.
Thanks,
Ravi.
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2013-12-19 8:48 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-12-18 14:53 [PATCH_v4 1/7] android/pan: Free device after sending diconnected notification Ravi kumar Veeramally
2013-12-18 14:53 ` [PATCH_v4 2/7] android/pan: Change local_role to NONE only when device list is empty Ravi kumar Veeramally
2013-12-18 14:53 ` [PATCH_v4 3/7] android/pan: shutdown io channel on disconnect call Ravi kumar Veeramally
2013-12-19 8:14 ` Johan Hedberg
2013-12-19 8:48 ` Ravi kumar Veeramally
2013-12-18 14:53 ` [PATCH_v4 4/7] bnep: Rename struct bnep_conn to struct bnep for better readability Ravi kumar Veeramally
2013-12-18 14:53 ` [PATCH_v4 5/7] bnep: Add bnep_new and bnep_free api's Ravi kumar Veeramally
2013-12-18 14:53 ` [PATCH_v4 6/7] bnep: Refactored bnep connect and disconnect calls Ravi kumar Veeramally
2013-12-18 14:53 ` [PATCH_v4 7/7] bnep: Refactored bnep server apis for bridge addition and deletion Ravi kumar Veeramally
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.