aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth
diff options
context:
space:
mode:
authorGustavo F. Padovan <padovan@profusion.mobi>2010-05-29 01:24:35 -0400
committerMarcel Holtmann <marcel@holtmann.org>2010-07-21 13:39:06 -0400
commit3cb123d1c03a0510d3c325bfaa971ce4df1e050d (patch)
treed8287b65d2f01ebb352fce02e1046c8377582398 /net/bluetooth
parent2ece3684b4037ad2394de795d67abbe412ab5e2f (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.c14
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)