aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth
diff options
context:
space:
mode:
authorIdo Yariv <ido@wizery.com>2012-04-20 14:46:07 -0400
committerGustavo Padovan <gustavo@padovan.org>2012-05-09 00:40:41 -0400
commitc22876814ee9cc72f84996b78203b5530c61bee8 (patch)
tree1dca2dc1271442b9b81ae2389eb644352c2c2f95 /net/bluetooth
parentd8ce9395252fa9a264c04e7ab9949f4f7ec96f5b (diff)
Bluetooth: Search global l2cap channels by src/dst addresses
The cid or psm and the source address might not be enough to uniquely identify a global channel, especially when the source address is our own. For instance, when trying to communicate with two LE devices in master mode, data received from the both devices is sent to the same socket. Fix this by taking the destination address into account when choosing the socket. Signed-off-by: Ido Yariv <ido@wizery.com> Signed-off-by: Arik Nemtsov <arik@wizery.com> Tested-by: João Paulo Rechi Vita <jprvita@openbossa.org> Signed-off-by: Gustavo Padovan <gustavo@padovan.org>
Diffstat (limited to 'net/bluetooth')
-rw-r--r--net/bluetooth/l2cap_core.c43
1 files changed, 31 insertions, 12 deletions
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index ce93dcf0c2db..cc96e0db284d 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -1066,11 +1066,12 @@ static void l2cap_conn_start(struct l2cap_conn *conn)
1066 mutex_unlock(&conn->chan_lock); 1066 mutex_unlock(&conn->chan_lock);
1067} 1067}
1068 1068
1069/* Find socket with cid and source bdaddr. 1069/* Find socket with cid and source/destination bdaddr.
1070 * Returns closest match, locked. 1070 * Returns closest match, locked.
1071 */ 1071 */
1072static struct l2cap_chan *l2cap_global_chan_by_scid(int state, u16 cid, 1072static struct l2cap_chan *l2cap_global_chan_by_scid(int state, u16 cid,
1073 bdaddr_t *src) 1073 bdaddr_t *src,
1074 bdaddr_t *dst)
1074{ 1075{
1075 struct l2cap_chan *c, *c1 = NULL; 1076 struct l2cap_chan *c, *c1 = NULL;
1076 1077
@@ -1083,14 +1084,22 @@ static struct l2cap_chan *l2cap_global_chan_by_scid(int state, u16 cid,
1083 continue; 1084 continue;
1084 1085
1085 if (c->scid == cid) { 1086 if (c->scid == cid) {
1087 int src_match, dst_match;
1088 int src_any, dst_any;
1089
1086 /* Exact match. */ 1090 /* Exact match. */
1087 if (!bacmp(&bt_sk(sk)->src, src)) { 1091 src_match = !bacmp(&bt_sk(sk)->src, src);
1092 dst_match = !bacmp(&bt_sk(sk)->dst, dst);
1093 if (src_match && dst_match) {
1088 read_unlock(&chan_list_lock); 1094 read_unlock(&chan_list_lock);
1089 return c; 1095 return c;
1090 } 1096 }
1091 1097
1092 /* Closest match */ 1098 /* Closest match */
1093 if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) 1099 src_any = !bacmp(&bt_sk(sk)->src, BDADDR_ANY);
1100 dst_any = !bacmp(&bt_sk(sk)->dst, BDADDR_ANY);
1101 if ((src_match && dst_any) || (src_any && dst_match) ||
1102 (src_any && dst_any))
1094 c1 = c; 1103 c1 = c;
1095 } 1104 }
1096 } 1105 }
@@ -1109,7 +1118,7 @@ static void l2cap_le_conn_ready(struct l2cap_conn *conn)
1109 1118
1110 /* Check if we have socket listening on cid */ 1119 /* Check if we have socket listening on cid */
1111 pchan = l2cap_global_chan_by_scid(BT_LISTEN, L2CAP_CID_LE_DATA, 1120 pchan = l2cap_global_chan_by_scid(BT_LISTEN, L2CAP_CID_LE_DATA,
1112 conn->src); 1121 conn->src, conn->dst);
1113 if (!pchan) 1122 if (!pchan)
1114 return; 1123 return;
1115 1124
@@ -1337,10 +1346,12 @@ static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status)
1337 1346
1338/* ---- Socket interface ---- */ 1347/* ---- Socket interface ---- */
1339 1348
1340/* Find socket with psm and source bdaddr. 1349/* Find socket with psm and source / destination bdaddr.
1341 * Returns closest match. 1350 * Returns closest match.
1342 */ 1351 */
1343static struct l2cap_chan *l2cap_global_chan_by_psm(int state, __le16 psm, bdaddr_t *src) 1352static struct l2cap_chan *l2cap_global_chan_by_psm(int state, __le16 psm,
1353 bdaddr_t *src,
1354 bdaddr_t *dst)
1344{ 1355{
1345 struct l2cap_chan *c, *c1 = NULL; 1356 struct l2cap_chan *c, *c1 = NULL;
1346 1357
@@ -1353,14 +1364,22 @@ static struct l2cap_chan *l2cap_global_chan_by_psm(int state, __le16 psm, bdaddr
1353 continue; 1364 continue;
1354 1365
1355 if (c->psm == psm) { 1366 if (c->psm == psm) {
1367 int src_match, dst_match;
1368 int src_any, dst_any;
1369
1356 /* Exact match. */ 1370 /* Exact match. */
1357 if (!bacmp(&bt_sk(sk)->src, src)) { 1371 src_match = !bacmp(&bt_sk(sk)->src, src);
1372 dst_match = !bacmp(&bt_sk(sk)->dst, dst);
1373 if (src_match && dst_match) {
1358 read_unlock(&chan_list_lock); 1374 read_unlock(&chan_list_lock);
1359 return c; 1375 return c;
1360 } 1376 }
1361 1377
1362 /* Closest match */ 1378 /* Closest match */
1363 if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) 1379 src_any = !bacmp(&bt_sk(sk)->src, BDADDR_ANY);
1380 dst_any = !bacmp(&bt_sk(sk)->dst, BDADDR_ANY);
1381 if ((src_match && dst_any) || (src_any && dst_match) ||
1382 (src_any && dst_any))
1364 c1 = c; 1383 c1 = c;
1365 } 1384 }
1366 } 1385 }
@@ -2887,7 +2906,7 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd
2887 BT_DBG("psm 0x%2.2x scid 0x%4.4x", __le16_to_cpu(psm), scid); 2906 BT_DBG("psm 0x%2.2x scid 0x%4.4x", __le16_to_cpu(psm), scid);
2888 2907
2889 /* Check if we have socket listening on psm */ 2908 /* Check if we have socket listening on psm */
2890 pchan = l2cap_global_chan_by_psm(BT_LISTEN, psm, conn->src); 2909 pchan = l2cap_global_chan_by_psm(BT_LISTEN, psm, conn->src, conn->dst);
2891 if (!pchan) { 2910 if (!pchan) {
2892 result = L2CAP_CR_BAD_PSM; 2911 result = L2CAP_CR_BAD_PSM;
2893 goto sendresp; 2912 goto sendresp;
@@ -4627,7 +4646,7 @@ static inline int l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, str
4627{ 4646{
4628 struct l2cap_chan *chan; 4647 struct l2cap_chan *chan;
4629 4648
4630 chan = l2cap_global_chan_by_psm(0, psm, conn->src); 4649 chan = l2cap_global_chan_by_psm(0, psm, conn->src, conn->dst);
4631 if (!chan) 4650 if (!chan)
4632 goto drop; 4651 goto drop;
4633 4652
@@ -4653,7 +4672,7 @@ static inline int l2cap_att_channel(struct l2cap_conn *conn, u16 cid,
4653{ 4672{
4654 struct l2cap_chan *chan; 4673 struct l2cap_chan *chan;
4655 4674
4656 chan = l2cap_global_chan_by_scid(0, cid, conn->src); 4675 chan = l2cap_global_chan_by_scid(0, cid, conn->src, conn->dst);
4657 if (!chan) 4676 if (!chan)
4658 goto drop; 4677 goto drop;
4659 4678