Commit b01b5bbf authored by Marcel Holtmann's avatar Marcel Holtmann Committed by Marcel Holtmann

[Bluetooth] Check for L2CAP reliability

The L2CAP sockets can now set LM_RELIABLE flag and get notification
when a reliability problem with the ACL connection is detected. The
Bluetooth qualification tests require this functionality.
Signed-off-by: default avatarMaxim Krasnyansky <maxk@qualcomm.com>
Signed-off-by: default avatarMarcel Holtmann <marcel@holtmann.org>
parent 4227e3a8
......@@ -1100,6 +1100,22 @@ static void l2cap_conn_ready(struct l2cap_conn *conn)
read_unlock(&l->lock);
}
/* Notify sockets that we cannot guaranty reliability anymore */
static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err)
{
struct l2cap_chan_list *l = &conn->chan_list;
struct sock *sk;
BT_DBG("conn %p", conn);
read_lock(&l->lock);
for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
if (l2cap_pi(sk)->link_mode & L2CAP_LM_RELIABLE)
sk->sk_err = err;
}
read_unlock(&l->lock);
}
static void l2cap_chan_ready(struct sock *sk)
{
struct sock *parent = bt_sk(sk)->parent;
......@@ -2045,10 +2061,12 @@ static int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 fl
kfree_skb(conn->rx_skb);
conn->rx_skb = NULL;
conn->rx_len = 0;
l2cap_conn_unreliable(conn, ECOMM);
}
if (skb->len < 2) {
BT_ERR("Frame is too short (len %d)", skb->len);
l2cap_conn_unreliable(conn, ECOMM);
goto drop;
}
......@@ -2066,6 +2084,7 @@ static int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 fl
if (skb->len > len) {
BT_ERR("Frame is too long (len %d, expected len %d)",
skb->len, len);
l2cap_conn_unreliable(conn, ECOMM);
goto drop;
}
......@@ -2080,6 +2099,7 @@ static int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 fl
if (!conn->rx_len) {
BT_ERR("Unexpected continuation frame (len %d)", skb->len);
l2cap_conn_unreliable(conn, ECOMM);
goto drop;
}
......@@ -2089,6 +2109,7 @@ static int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 fl
kfree_skb(conn->rx_skb);
conn->rx_skb = NULL;
conn->rx_len = 0;
l2cap_conn_unreliable(conn, ECOMM);
goto drop;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment