Skip to content

Commit

Permalink
Bluetooth: Fix sending ReqSeq on I-frames
Browse files Browse the repository at this point in the history
As specified by ERTM spec an ERTM channel can acknowledge received
I-frames(the data frames) by sending an I-frame with the proper ReqSeq
value (i.e. ReqSeq is set to BufferSeq).  Until now we aren't setting the
ReqSeq value on I-frame control bits. That way we can save sending
S-frames(Supervise frames) only to acknowledge receipt of I-frames. It
is very helpful to the full-duplex channel.
ReqSeq is the packet sequence number sent in an acknowledgement frame to
acknowledge receipt of frames up to (ReqSeq - 1).
BufferSeq controls the receiver buffer, it is used to delay
acknowledgement of new frames to not cause buffer overflow. BufferSeq
value is not increased until frames are pulled by reassembly function.

Signed-off-by: Gustavo F. Padovan <gustavo@las.ic.unicamp.br>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
  • Loading branch information
Gustavo F. Padovan authored and Marcel Holtmann committed Dec 3, 2009
1 parent 889a3ca commit 9f121a5
Show file tree
Hide file tree
Showing 2 changed files with 6 additions and 3 deletions.
1 change: 0 additions & 1 deletion include/net/bluetooth/l2cap.h
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,6 @@ struct l2cap_pinfo {

__u8 next_tx_seq;
__u8 expected_ack_seq;
__u8 req_seq;
__u8 expected_tx_seq;
__u8 buffer_seq;
__u8 buffer_seq_srej;
Expand Down
8 changes: 6 additions & 2 deletions net/bluetooth/l2cap.c
Original file line number Diff line number Diff line change
Expand Up @@ -1333,7 +1333,7 @@ static int l2cap_retransmit_frame(struct sock *sk, u8 tx_seq)
tx_skb = skb_clone(skb, GFP_ATOMIC);
bt_cb(skb)->retries++;
control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
control |= (pi->req_seq << L2CAP_CTRL_REQSEQ_SHIFT)
control |= (pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT)
| (tx_seq << L2CAP_CTRL_TXSEQ_SHIFT);
put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);

Expand Down Expand Up @@ -1375,7 +1375,7 @@ static int l2cap_ertm_send(struct sock *sk)
bt_cb(skb)->retries++;

control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
control |= (pi->req_seq << L2CAP_CTRL_REQSEQ_SHIFT)
control |= (pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT)
| (pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT);
put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);

Expand Down Expand Up @@ -3298,12 +3298,16 @@ static inline int l2cap_data_channel_iframe(struct sock *sk, u16 rx_control, str
{
struct l2cap_pinfo *pi = l2cap_pi(sk);
u8 tx_seq = __get_txseq(rx_control);
u8 req_seq = __get_reqseq(rx_control);
u16 tx_control = 0;
u8 sar = rx_control >> L2CAP_CTRL_SAR_SHIFT;
int err = 0;

BT_DBG("sk %p rx_control 0x%4.4x len %d", sk, rx_control, skb->len);

pi->expected_ack_seq = req_seq;
l2cap_drop_acked_frames(sk);

if (tx_seq == pi->expected_tx_seq)
goto expected;

Expand Down

0 comments on commit 9f121a5

Please sign in to comment.