Bluetooth: Fix ATT Indicate/Confirm handling
If due to timing issues out of our control, an outbound ATT Indicate
is delayed to the point that user space code does not receive
confirmation within it time-out period, both Client and Server
sockets must be torn down. We also must always respond to incoming
ATT Indicate pkt with a Confirmation, as the Error Response is an
illegal response for Indicate.
CRs-Fixed: 363355
Change-Id: I4003a59e1a731a08818f18d5b79db537e2aa2619
Signed-off-by: Brian Gix <bgix@codeaurora.org>
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index 4829e6b..3fa4a02 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -1174,7 +1174,7 @@
static int l2cap_sock_release(struct socket *sock)
{
struct sock *sk = sock->sk;
- struct sock *srv_sk = NULL;
+ struct sock *sk2 = NULL;
int err;
BT_DBG("sock %p, sk %p", sock, sk);
@@ -1182,15 +1182,16 @@
if (!sk)
return 0;
- /* If this is an ATT Client socket, find the matching Server */
- if (l2cap_pi(sk)->scid == L2CAP_CID_LE_DATA && !l2cap_pi(sk)->incoming)
- srv_sk = l2cap_find_sock_by_fixed_cid_and_dir(L2CAP_CID_LE_DATA,
- &bt_sk(sk)->src, &bt_sk(sk)->dst, 1);
+ /* If this is an ATT socket, find it's matching server/client */
+ if (l2cap_pi(sk)->scid == L2CAP_CID_LE_DATA)
+ sk2 = l2cap_find_sock_by_fixed_cid_and_dir(L2CAP_CID_LE_DATA,
+ &bt_sk(sk)->src, &bt_sk(sk)->dst,
+ l2cap_pi(sk)->incoming ? 0 : 1);
- /* If server socket found, request tear down */
- BT_DBG("client:%p server:%p", sk, srv_sk);
- if (srv_sk)
- l2cap_sock_set_timer(srv_sk, 1);
+ /* If matching socket found, request tear down */
+ BT_DBG("sock:%p companion:%p", sk, sk2);
+ if (sk2)
+ l2cap_sock_set_timer(sk2, 1);
err = l2cap_sock_shutdown(sock, 2);