Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3733937d authored by Mat Martineau's avatar Mat Martineau Committed by Johan Hedberg
Browse files

Bluetooth: Refactor l2cap_streaming_send



This new implementation uses struct l2cap_ctrl to compose the
streaming mode headers.

Signed-off-by: default avatarMat Martineau <mathewm@codeaurora.org>
Signed-off-by: default avatarGustavo Padovan <gustavo.padovan@collabora.co.uk>
parent 608bcc6d
Loading
Loading
Loading
Loading
+31 −17
Original line number Diff line number Diff line
@@ -1650,29 +1650,45 @@ static void l2cap_drop_acked_frames(struct l2cap_chan *chan)
		__clear_retrans_timer(chan);
}

static void l2cap_streaming_send(struct l2cap_chan *chan)
static int l2cap_streaming_send(struct l2cap_chan *chan,
				struct sk_buff_head *skbs)
{
	struct sk_buff *skb;
	u32 control;
	u16 fcs;
	struct l2cap_ctrl *control;

	while ((skb = skb_dequeue(&chan->tx_q))) {
		control = __get_control(chan, skb->data + L2CAP_HDR_SIZE);
		control |= __set_txseq(chan, chan->next_tx_seq);
		control |= __set_ctrl_sar(chan, bt_cb(skb)->control.sar);
		__put_control(chan, control, skb->data + L2CAP_HDR_SIZE);
	BT_DBG("chan %p, skbs %p", chan, skbs);

	if (chan->state != BT_CONNECTED)
		return -ENOTCONN;

	skb_queue_splice_tail_init(skbs, &chan->tx_q);

	while (!skb_queue_empty(&chan->tx_q)) {

		skb = skb_dequeue(&chan->tx_q);

		bt_cb(skb)->control.retries = 1;
		control = &bt_cb(skb)->control;

		control->reqseq = 0;
		control->txseq = chan->next_tx_seq;

		__pack_control(chan, control, skb);

		if (chan->fcs == L2CAP_FCS_CRC16) {
			fcs = crc16(0, (u8 *)skb->data,
						skb->len - L2CAP_FCS_SIZE);
			put_unaligned_le16(fcs,
					skb->data + skb->len - L2CAP_FCS_SIZE);
			u16 fcs = crc16(0, (u8 *) skb->data, skb->len);
			put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
		}

		l2cap_do_send(chan, skb);

		BT_DBG("Sent txseq %d", (int)control->txseq);

		chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq);
		chan->frames_sent++;
	}

	return 0;
}

static void l2cap_retransmit_one_frame(struct l2cap_chan *chan, u16 tx_seq)
@@ -2136,13 +2152,11 @@ int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len,
		if (err)
			break;

		if (chan->mode == L2CAP_MODE_ERTM) {
		if (chan->mode == L2CAP_MODE_ERTM)
			err = l2cap_tx(chan, 0, &seg_queue,
				       L2CAP_EV_DATA_REQUEST);
		} else {
			skb_queue_splice_tail_init(&seg_queue, &chan->tx_q);
			l2cap_streaming_send(chan);
		}
		else
			err = l2cap_streaming_send(chan, &seg_queue);

		if (!err)
			err = len;