diff --git a/[refs] b/[refs] index 70e7fe5592cb..107a98d57f5a 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 0733119c0bed37eda4bb832d049939a0dc53a233 +refs/heads/master: 9f69bda6aa8b365169b4a6fd35432ee40574d661 diff --git a/trunk/net/bluetooth/l2cap_core.c b/trunk/net/bluetooth/l2cap_core.c index 97827506dc94..c9c1f9257a91 100644 --- a/trunk/net/bluetooth/l2cap_core.c +++ b/trunk/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;