From 844c0972427ee5f661158160aaca10b22b3dda60 Mon Sep 17 00:00:00 2001 From: "Gustavo F. Padovan" Date: Tue, 4 May 2010 23:16:01 -0300 Subject: [PATCH] Bluetooth: Fix spec error in the RemoteBusy Logic On the receipt of an RR(P=1) under RemoteBusy set to TRUE(on the RECV state table) we have to call sendIorRRorRNR(F=1) and just after set RemoteBusy to False. This leads to a freeze in the sending process since it's not allowed send data with RemoteBusy set to true and no one call SendPending-I-Frames after set RemoteBusy to false(The last action for that event). Actually sendIorRRorRNR() calls SendPending-I-Frames but at that moment RemoteBusy is still True and we cannot send any frame, after, no one calls SendPending-I-Frames again and the sending process stops. The solution here is to set RemoteBusy to false inside SendPending-I-Frames just before call SendPending-I-Frames. That will make SendPending-I-Frames able to send frames. This solution is similar to what RR(P=0)(F=0) on the RECV table and RR(P=1) on the SREJ_SENT table do. Actually doesn't make any sense call SendPending-I-Frames if we can send any frame, i. e., RemoteBusy is True. Signed-off-by: Gustavo F. Padovan Signed-off-by: Marcel Holtmann --- net/bluetooth/l2cap.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c index 9ef01c32b3a2..ba49f9a3579e 100644 --- a/net/bluetooth/l2cap.c +++ b/net/bluetooth/l2cap.c @@ -3379,6 +3379,8 @@ static inline void l2cap_send_i_or_rr_or_rnr(struct sock *sk) if (pi->conn_state & L2CAP_CONN_REMOTE_BUSY && pi->unacked_frames > 0) __mod_retrans_timer(); + pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY; + spin_lock_bh(&pi->send_lock); l2cap_ertm_send(sk); spin_unlock_bh(&pi->send_lock); @@ -3936,7 +3938,6 @@ static inline void l2cap_data_channel_rrframe(struct sock *sk, u16 rx_control) l2cap_send_srejtail(sk); } else { l2cap_send_i_or_rr_or_rnr(sk); - pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY; } } else if (rx_control & L2CAP_CTRL_FINAL) { -- 2.20.1