Bluetooth: Fix L2CAP control bit field corruption
authorGustavo F. Padovan <padovan@profusion.mobi>
Fri, 18 Jun 2010 23:37:33 +0000 (20:37 -0300)
committerMarcel Holtmann <marcel@holtmann.org>
Wed, 21 Jul 2010 17:39:05 +0000 (10:39 -0700)
When resending an I-frame, ERTM was reusing the control bits from the last
time it was sent, that was causing a corruption in the new control field
due to it dirty fields.

This patches extracts only the SAR bits from the old field and reuse it to
resend the packet, the others bits should be reset and receive the
updated value.

Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
net/bluetooth/l2cap.c

index 4415eb48c6aeede5f25d8f0af347d7e3696fbb25..c2fb26d9286cad2f779fede33cc9bee4a57d9217 100644 (file)
@@ -1430,6 +1430,8 @@ static void l2cap_retransmit_one_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 &= L2CAP_CTRL_SAR;
+
        control |= (pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT)
                        | (tx_seq << L2CAP_CTRL_TXSEQ_SHIFT);
        put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
@@ -1465,6 +1467,8 @@ static int l2cap_ertm_send(struct sock *sk)
                bt_cb(skb)->retries++;
 
                control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
+               control &= L2CAP_CTRL_SAR;
+
                if (pi->conn_state & L2CAP_CONN_SEND_FBIT) {
                        control |= L2CAP_CTRL_FINAL;
                        pi->conn_state &= ~L2CAP_CONN_SEND_FBIT;