diff options
author | Gustavo F. Padovan <padovan@profusion.mobi> | 2010-05-29 01:24:35 -0400 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2010-07-21 13:39:06 -0400 |
commit | 3cb123d1c03a0510d3c325bfaa971ce4df1e050d (patch) | |
tree | d8287b65d2f01ebb352fce02e1046c8377582398 /net/bluetooth | |
parent | 2ece3684b4037ad2394de795d67abbe412ab5e2f (diff) |
Bluetooth: Fix handle of received P-bit
ERTM spec mandates that after receive a P-bit we shall send an F-bit in
response. This patch fixes this for retransmitted packets, on
retransmitting we were missing to check for a pending F-bit to be sent.
Also we were missing some annotation to send a F-bit.
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
Reviewed-by: João Paulo Rechi Vita <jprvita@profusion.mobi>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net/bluetooth')
-rw-r--r-- | net/bluetooth/l2cap.c | 14 |
1 files changed, 12 insertions, 2 deletions
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c index ecf3e3dcefe3..f0441b0b0335 100644 --- a/net/bluetooth/l2cap.c +++ b/net/bluetooth/l2cap.c | |||
@@ -1430,10 +1430,15 @@ static void l2cap_retransmit_one_frame(struct sock *sk, u8 tx_seq) | |||
1430 | tx_skb = skb_clone(skb, GFP_ATOMIC); | 1430 | tx_skb = skb_clone(skb, GFP_ATOMIC); |
1431 | bt_cb(skb)->retries++; | 1431 | bt_cb(skb)->retries++; |
1432 | control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE); | 1432 | control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE); |
1433 | control &= L2CAP_CTRL_SAR; | 1433 | |
1434 | if (pi->conn_state & L2CAP_CONN_SEND_FBIT) { | ||
1435 | control |= L2CAP_CTRL_FINAL; | ||
1436 | pi->conn_state &= ~L2CAP_CONN_SEND_FBIT; | ||
1437 | } | ||
1434 | 1438 | ||
1435 | control |= (pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT) | 1439 | control |= (pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT) |
1436 | | (tx_seq << L2CAP_CTRL_TXSEQ_SHIFT); | 1440 | | (tx_seq << L2CAP_CTRL_TXSEQ_SHIFT); |
1441 | |||
1437 | put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE); | 1442 | put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE); |
1438 | 1443 | ||
1439 | if (pi->fcs == L2CAP_FCS_CRC16) { | 1444 | if (pi->fcs == L2CAP_FCS_CRC16) { |
@@ -3385,7 +3390,6 @@ static inline void l2cap_send_i_or_rr_or_rnr(struct sock *sk) | |||
3385 | u16 control = 0; | 3390 | u16 control = 0; |
3386 | 3391 | ||
3387 | pi->frames_sent = 0; | 3392 | pi->frames_sent = 0; |
3388 | pi->conn_state |= L2CAP_CONN_SEND_FBIT; | ||
3389 | 3393 | ||
3390 | control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT; | 3394 | control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT; |
3391 | 3395 | ||
@@ -3963,6 +3967,7 @@ static inline void l2cap_data_channel_rrframe(struct sock *sk, u16 rx_control) | |||
3963 | l2cap_drop_acked_frames(sk); | 3967 | l2cap_drop_acked_frames(sk); |
3964 | 3968 | ||
3965 | if (rx_control & L2CAP_CTRL_POLL) { | 3969 | if (rx_control & L2CAP_CTRL_POLL) { |
3970 | pi->conn_state |= L2CAP_CONN_SEND_FBIT; | ||
3966 | if (pi->conn_state & L2CAP_CONN_SREJ_SENT) { | 3971 | if (pi->conn_state & L2CAP_CONN_SREJ_SENT) { |
3967 | if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) && | 3972 | if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) && |
3968 | (pi->unacked_frames > 0)) | 3973 | (pi->unacked_frames > 0)) |
@@ -4030,6 +4035,8 @@ static inline void l2cap_data_channel_srejframe(struct sock *sk, u16 rx_control) | |||
4030 | if (rx_control & L2CAP_CTRL_POLL) { | 4035 | if (rx_control & L2CAP_CTRL_POLL) { |
4031 | pi->expected_ack_seq = tx_seq; | 4036 | pi->expected_ack_seq = tx_seq; |
4032 | l2cap_drop_acked_frames(sk); | 4037 | l2cap_drop_acked_frames(sk); |
4038 | |||
4039 | pi->conn_state |= L2CAP_CONN_SEND_FBIT; | ||
4033 | l2cap_retransmit_one_frame(sk, tx_seq); | 4040 | l2cap_retransmit_one_frame(sk, tx_seq); |
4034 | 4041 | ||
4035 | spin_lock_bh(&pi->send_lock); | 4042 | spin_lock_bh(&pi->send_lock); |
@@ -4064,6 +4071,9 @@ static inline void l2cap_data_channel_rnrframe(struct sock *sk, u16 rx_control) | |||
4064 | pi->expected_ack_seq = tx_seq; | 4071 | pi->expected_ack_seq = tx_seq; |
4065 | l2cap_drop_acked_frames(sk); | 4072 | l2cap_drop_acked_frames(sk); |
4066 | 4073 | ||
4074 | if (rx_control & L2CAP_CTRL_POLL) | ||
4075 | pi->conn_state |= L2CAP_CONN_SEND_FBIT; | ||
4076 | |||
4067 | if (!(pi->conn_state & L2CAP_CONN_SREJ_SENT)) { | 4077 | if (!(pi->conn_state & L2CAP_CONN_SREJ_SENT)) { |
4068 | del_timer(&pi->retrans_timer); | 4078 | del_timer(&pi->retrans_timer); |
4069 | if (rx_control & L2CAP_CTRL_POLL) | 4079 | if (rx_control & L2CAP_CTRL_POLL) |