From: Gustavo F. Padovan Date: Thu, 7 Apr 2011 19:40:25 +0000 (-0300) Subject: Bluetooth: Add proper handling of received LE data X-Git-Url: http://drtracing.org/?a=commitdiff_plain;h=9f69bda6aa8b365169b4a6fd35432ee40574d661;p=deliverable%2Flinux.git 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 --- 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 @@ done: 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;