From 9f69bda6aa8b365169b4a6fd35432ee40574d661 Mon Sep 17 00:00:00 2001 From: "Gustavo F. Padovan" Date: Thu, 7 Apr 2011 16:40:25 -0300 Subject: [PATCH] Bluetooth: Add proper handling of received LE data Despite it works, handling through l2cap_data_channel() is wrongs. That function should handle only connection oriented data. Signed-off-by: Gustavo F. Padovan --- net/bluetooth/l2cap_core.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 97827506dc94..c9c1f9257a91 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -3728,6 +3728,36 @@ static inline int l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, str return 0; } +static inline int l2cap_att_channel(struct l2cap_conn *conn, __le16 cid, struct sk_buff *skb) +{ + struct sock *sk; + + sk = l2cap_get_sock_by_scid(0, cid, conn->src); + if (!sk) + goto drop; + + bh_lock_sock(sk); + + BT_DBG("sk %p, len %d", sk, skb->len); + + if (sk->sk_state != BT_BOUND && sk->sk_state != BT_CONNECTED) + goto drop; + + if (l2cap_pi(sk)->imtu < skb->len) + goto drop; + + if (!sock_queue_rcv_skb(sk, skb)) + goto done; + +drop: + kfree_skb(skb); + +done: + if (sk) + bh_unlock_sock(sk); + return 0; +} + static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb) { struct l2cap_hdr *lh = (void *) skb->data; @@ -3757,6 +3787,10 @@ static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb) l2cap_conless_channel(conn, psm, skb); break; + case L2CAP_CID_LE_DATA: + l2cap_att_channel(conn, cid, skb); + break; + default: l2cap_data_channel(conn, cid, skb); break; -- GitLab