Bluetooth: Refactor l2cap_streaming_send
This new implementation uses struct l2cap_ctrl to compose the streaming mode headers. Signed-off-by: Mat Martineau <mathewm@codeaurora.org> Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
This commit is contained in:
committed by
Johan Hedberg
parent
608bcc6d70
commit
3733937d96
+31
-17
@@ -1650,29 +1650,45 @@ static void l2cap_drop_acked_frames(struct l2cap_chan *chan)
|
|||||||
__clear_retrans_timer(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;
|
struct sk_buff *skb;
|
||||||
u32 control;
|
struct l2cap_ctrl *control;
|
||||||
u16 fcs;
|
|
||||||
|
|
||||||
while ((skb = skb_dequeue(&chan->tx_q))) {
|
BT_DBG("chan %p, skbs %p", chan, skbs);
|
||||||
control = __get_control(chan, skb->data + L2CAP_HDR_SIZE);
|
|
||||||
control |= __set_txseq(chan, chan->next_tx_seq);
|
if (chan->state != BT_CONNECTED)
|
||||||
control |= __set_ctrl_sar(chan, bt_cb(skb)->control.sar);
|
return -ENOTCONN;
|
||||||
__put_control(chan, control, skb->data + L2CAP_HDR_SIZE);
|
|
||||||
|
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) {
|
if (chan->fcs == L2CAP_FCS_CRC16) {
|
||||||
fcs = crc16(0, (u8 *)skb->data,
|
u16 fcs = crc16(0, (u8 *) skb->data, skb->len);
|
||||||
skb->len - L2CAP_FCS_SIZE);
|
put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE));
|
||||||
put_unaligned_le16(fcs,
|
|
||||||
skb->data + skb->len - L2CAP_FCS_SIZE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
l2cap_do_send(chan, skb);
|
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->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)
|
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)
|
if (err)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (chan->mode == L2CAP_MODE_ERTM) {
|
if (chan->mode == L2CAP_MODE_ERTM)
|
||||||
err = l2cap_tx(chan, 0, &seg_queue,
|
err = l2cap_tx(chan, 0, &seg_queue,
|
||||||
L2CAP_EV_DATA_REQUEST);
|
L2CAP_EV_DATA_REQUEST);
|
||||||
} else {
|
else
|
||||||
skb_queue_splice_tail_init(&seg_queue, &chan->tx_q);
|
err = l2cap_streaming_send(chan, &seg_queue);
|
||||||
l2cap_streaming_send(chan);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!err)
|
if (!err)
|
||||||
err = len;
|
err = len;
|
||||||
|
|||||||
Reference in New Issue
Block a user