Skip to content

Instantly share code, notes, and snippets.

@tomaskrcka
Created July 10, 2015 07:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tomaskrcka/67cac07c78ac249a79d8 to your computer and use it in GitHub Desktop.
Save tomaskrcka/67cac07c78ac249a79d8 to your computer and use it in GitHub Desktop.
Multiple gatt connection patch to kernel 3.2
--- linux-3.2.orig/net/bluetooth/l2cap_core.c 2015-05-25 15:13:25.035952220 +0200
+++ linux-3.2/net/bluetooth/l2cap_core.c 2015-07-07 13:07:02.915456939 +0200
@@ -800,11 +800,14 @@ static void l2cap_conn_start(struct l2ca
/* Find socket with cid and source bdaddr.
* Returns closest match, locked.
*/
-static struct l2cap_chan *l2cap_global_chan_by_scid(int state, __le16 cid, bdaddr_t *src)
+static struct l2cap_chan *l2cap_global_chan_by_scid(int state, __le16 cid, bdaddr_t *src, bdaddr_t *dst)
{
struct l2cap_chan *c, *c1 = NULL;
read_lock(&chan_list_lock);
+
+ BT_DBG("%s -> %s cid %d", batostr(src), batostr(dst), cid);
+
list_for_each_entry(c, &chan_list, global_l) {
struct sock *sk = c->sk;
@@ -813,14 +816,23 @@ static struct l2cap_chan *l2cap_global_c
continue;
if (c->scid == cid) {
+ int src_match, dst_match;
+ int src_any, dst_any;
+
+ src_match = !bacmp(&bt_sk(sk)->src, src);
+ dst_match = !bacmp(&bt_sk(sk)->dst, dst);
+ BT_DBG("test: src: %s dst: %s", batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst));
/* Exact match. */
- if (!bacmp(&bt_sk(sk)->src, src)) {
+ if (src_match && dst_match) {
read_unlock(&chan_list_lock);
return c;
}
/* Closest match */
- if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY))
+ src_any = !bacmp(&bt_sk(sk)->src, BDADDR_ANY);
+ dst_any = !bacmp(&bt_sk(sk)->dst, BDADDR_ANY);
+ if ((src_match && dst_any) || (src_any && dst_match) ||
+ (src_any && dst_any))
c1 = c;
}
}
@@ -839,7 +851,7 @@ static void l2cap_le_conn_ready(struct l
/* Check if we have socket listening on cid */
pchan = l2cap_global_chan_by_scid(BT_LISTEN, L2CAP_CID_LE_DATA,
- conn->src);
+ conn->src, conn->dst);
if (!pchan)
return;
@@ -3849,7 +3861,7 @@ static inline int l2cap_att_channel(stru
struct sock *sk = NULL;
struct l2cap_chan *chan;
- chan = l2cap_global_chan_by_scid(0, cid, conn->src);
+ chan = l2cap_global_chan_by_scid(0, cid, conn->src, conn->dst);
if (!chan)
goto drop;
@tomaskrcka
Copy link
Author

If you connect to more than one device via e.g. gatttool then second connection will receive responses performed from first connection.
This patch solves the problem and also it's been already solved in kernel 3.5

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment