diff options
author | Gustavo F. Padovan <padovan@profusion.mobi> | 2010-05-04 22:16:01 -0400 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2010-05-10 03:28:53 -0400 |
commit | 844c0972427ee5f661158160aaca10b22b3dda60 (patch) | |
tree | b4e7694efc8dbfbc88ecfcca97a2381f0144c046 /net/bluetooth | |
parent | 4178ba462a3e8ab5094e69606f01d9e95f2d5ea6 (diff) |
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 <padovan@profusion.mobi>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net/bluetooth')
-rw-r--r-- | net/bluetooth/l2cap.c | 3 |
1 files changed, 2 insertions, 1 deletions
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) | |||
3379 | if (pi->conn_state & L2CAP_CONN_REMOTE_BUSY && pi->unacked_frames > 0) | 3379 | if (pi->conn_state & L2CAP_CONN_REMOTE_BUSY && pi->unacked_frames > 0) |
3380 | __mod_retrans_timer(); | 3380 | __mod_retrans_timer(); |
3381 | 3381 | ||
3382 | pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY; | ||
3383 | |||
3382 | spin_lock_bh(&pi->send_lock); | 3384 | spin_lock_bh(&pi->send_lock); |
3383 | l2cap_ertm_send(sk); | 3385 | l2cap_ertm_send(sk); |
3384 | spin_unlock_bh(&pi->send_lock); | 3386 | spin_unlock_bh(&pi->send_lock); |
@@ -3936,7 +3938,6 @@ static inline void l2cap_data_channel_rrframe(struct sock *sk, u16 rx_control) | |||
3936 | l2cap_send_srejtail(sk); | 3938 | l2cap_send_srejtail(sk); |
3937 | } else { | 3939 | } else { |
3938 | l2cap_send_i_or_rr_or_rnr(sk); | 3940 | l2cap_send_i_or_rr_or_rnr(sk); |
3939 | pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY; | ||
3940 | } | 3941 | } |
3941 | 3942 | ||
3942 | } else if (rx_control & L2CAP_CTRL_FINAL) { | 3943 | } else if (rx_control & L2CAP_CTRL_FINAL) { |