From 45dffa281cddbeab00870c0bcb119fab7ed339e7 Mon Sep 17 00:00:00 2001 From: Mat Martineau Date: Thu, 17 May 2012 20:53:44 -0700 Subject: [PATCH] --- yaml --- r: 314399 b: refs/heads/master c: bed68bde7ebdb591cc67921261307626c8f37936 h: refs/heads/master i: 314397: 06c245debcb712532fc38d7b68b58d9adce2f4b8 314395: 3e020ce83e84913412d3c09244af6f7ee5908327 314391: 86ba0c66477a1941d310de1ee666278be19ee3bc 314383: a7f760fcb107993002413c1196b85cc079524bd3 314367: 6de25810a3e400c22694f8f42a9e4472cca98f4b v: v3 --- [refs] | 2 +- trunk/net/bluetooth/l2cap_core.c | 56 ++++++++++++++++++++++++++++++-- 2 files changed, 54 insertions(+), 4 deletions(-) diff --git a/[refs] b/[refs] index 32049ede145d..8f1079cd7aca 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: e1fbd4c19a5c4d4f490d70e73745cf2cf0dc1955 +refs/heads/master: bed68bde7ebdb591cc67921261307626c8f37936 diff --git a/trunk/net/bluetooth/l2cap_core.c b/trunk/net/bluetooth/l2cap_core.c index 26963a5e3f58..5823697cf9de 100644 --- a/trunk/net/bluetooth/l2cap_core.c +++ b/trunk/net/bluetooth/l2cap_core.c @@ -2239,17 +2239,67 @@ int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len, static void l2cap_send_srej(struct l2cap_chan *chan, u16 txseq) { - /* Placeholder */ + struct l2cap_ctrl control; + u16 seq; + + BT_DBG("chan %p, txseq %d", chan, txseq); + + memset(&control, 0, sizeof(control)); + control.sframe = 1; + control.super = L2CAP_SUPER_SREJ; + + for (seq = chan->expected_tx_seq; seq != txseq; + seq = __next_seq(chan, seq)) { + if (!l2cap_ertm_seq_in_queue(&chan->srej_q, seq)) { + control.reqseq = seq; + l2cap_send_sframe(chan, &control); + l2cap_seq_list_append(&chan->srej_list, seq); + } + } + + chan->expected_tx_seq = __next_seq(chan, txseq); } static void l2cap_send_srej_tail(struct l2cap_chan *chan) { - /* Placeholder */ + struct l2cap_ctrl control; + + BT_DBG("chan %p", chan); + + if (chan->srej_list.tail == L2CAP_SEQ_LIST_CLEAR) + return; + + memset(&control, 0, sizeof(control)); + control.sframe = 1; + control.super = L2CAP_SUPER_SREJ; + control.reqseq = chan->srej_list.tail; + l2cap_send_sframe(chan, &control); } static void l2cap_send_srej_list(struct l2cap_chan *chan, u16 txseq) { - /* Placeholder */ + struct l2cap_ctrl control; + u16 initial_head; + u16 seq; + + BT_DBG("chan %p, txseq %d", chan, txseq); + + memset(&control, 0, sizeof(control)); + control.sframe = 1; + control.super = L2CAP_SUPER_SREJ; + + /* Capture initial list head to allow only one pass through the list. */ + initial_head = chan->srej_list.head; + + do { + seq = l2cap_seq_list_pop(&chan->srej_list); + if (seq == txseq || seq == L2CAP_SEQ_LIST_CLEAR) + break; + + control.reqseq = seq; + l2cap_send_sframe(chan, &control); + l2cap_seq_list_append(&chan->srej_list, seq); + } while (chan->srej_list.head != initial_head); } static void l2cap_process_reqseq(struct l2cap_chan *chan, u16 reqseq)