Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 314390
b: refs/heads/master
c: a67d7f6
h: refs/heads/master
v: v3
  • Loading branch information
Mat Martineau authored and Johan Hedberg committed Jun 5, 2012
1 parent 5c1a73f commit 92c85f2
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 37 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 18a48e76640c590a14b0286c9da5fde6ac146cc2
refs/heads/master: a67d7f6fca776317bb478c96f25196972c05d173
87 changes: 51 additions & 36 deletions trunk/net/bluetooth/l2cap_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -848,15 +848,12 @@ static inline void __pack_control(struct l2cap_chan *chan,
}
}

static inline void l2cap_send_sframe(struct l2cap_chan *chan, u32 control)
static struct sk_buff *l2cap_create_sframe_pdu(struct l2cap_chan *chan,
u32 control)
{
struct sk_buff *skb;
struct l2cap_hdr *lh;
struct l2cap_conn *conn = chan->conn;
int count, hlen;

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

if (test_bit(FLAG_EXT_CTRL, &chan->flags))
hlen = L2CAP_EXT_HDR_SIZE;
Expand All @@ -866,35 +863,65 @@ static inline void l2cap_send_sframe(struct l2cap_chan *chan, u32 control)
if (chan->fcs == L2CAP_FCS_CRC16)
hlen += L2CAP_FCS_SIZE;

BT_DBG("chan %p, control 0x%8.8x", chan, control);

count = min_t(unsigned int, conn->mtu, hlen);

control |= __set_sframe(chan);

if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state))
control |= __set_ctrl_final(chan);

if (test_and_clear_bit(CONN_SEND_PBIT, &chan->conn_state))
control |= __set_ctrl_poll(chan);
skb = bt_skb_alloc(hlen, GFP_KERNEL);

skb = bt_skb_alloc(count, GFP_ATOMIC);
if (!skb)
return;
return ERR_PTR(-ENOMEM);

lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
lh->len = cpu_to_le16(hlen - L2CAP_HDR_SIZE);
lh->cid = cpu_to_le16(chan->dcid);

__put_control(chan, control, skb_put(skb, __ctrl_size(chan)));
if (test_bit(FLAG_EXT_CTRL, &chan->flags))
put_unaligned_le32(control, skb_put(skb, L2CAP_EXT_CTRL_SIZE));
else
put_unaligned_le16(control, skb_put(skb, L2CAP_ENH_CTRL_SIZE));

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

skb->priority = HCI_PRIO_MAX;
l2cap_do_send(chan, skb);
return skb;
}

static void l2cap_send_sframe(struct l2cap_chan *chan,
struct l2cap_ctrl *control)
{
struct sk_buff *skb;
u32 control_field;

BT_DBG("chan %p, control %p", chan, control);

if (!control->sframe)
return;

if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state) &&
!control->poll)
control->final = 1;

if (control->super == L2CAP_SUPER_RR)
clear_bit(CONN_RNR_SENT, &chan->conn_state);
else if (control->super == L2CAP_SUPER_RNR)
set_bit(CONN_RNR_SENT, &chan->conn_state);

if (control->super != L2CAP_SUPER_SREJ) {
chan->last_acked_seq = control->reqseq;
__clear_ack_timer(chan);
}

BT_DBG("reqseq %d, final %d, poll %d, super %d", control->reqseq,
control->final, control->poll, control->super);

if (test_bit(FLAG_EXT_CTRL, &chan->flags))
control_field = __pack_extended_control(control);
else
control_field = __pack_enhanced_control(control);

skb = l2cap_create_sframe_pdu(chan, control_field);
if (!IS_ERR(skb))
l2cap_do_send(chan, skb);
}

static inline void l2cap_send_rr_or_rnr(struct l2cap_chan *chan, u32 control)
Expand All @@ -906,8 +933,6 @@ static inline void l2cap_send_rr_or_rnr(struct l2cap_chan *chan, u32 control)
control |= __set_ctrl_super(chan, L2CAP_SUPER_RR);

control |= __set_reqseq(chan, chan->buffer_seq);

l2cap_send_sframe(chan, control);
}

static inline int __l2cap_no_conn_pending(struct l2cap_chan *chan)
Expand Down Expand Up @@ -1826,15 +1851,13 @@ static void __l2cap_send_ack(struct l2cap_chan *chan)
if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
control |= __set_ctrl_super(chan, L2CAP_SUPER_RNR);
set_bit(CONN_RNR_SENT, &chan->conn_state);
l2cap_send_sframe(chan, control);
return;
}

if (l2cap_ertm_send(chan) > 0)
return;

control |= __set_ctrl_super(chan, L2CAP_SUPER_RR);
l2cap_send_sframe(chan, control);
}

static void l2cap_send_ack(struct l2cap_chan *chan)
Expand All @@ -1853,8 +1876,6 @@ static void l2cap_send_srejtail(struct l2cap_chan *chan)

tail = list_entry((&chan->srej_l)->prev, struct srej_list, list);
control |= __set_reqseq(chan, tail->tx_seq);

l2cap_send_sframe(chan, control);
}

static inline int l2cap_skbuff_fromiovec(struct l2cap_chan *chan,
Expand Down Expand Up @@ -2259,7 +2280,7 @@ static int l2cap_tx_state_xmit(struct l2cap_chan *chan,
local_control.super = L2CAP_SUPER_RR;
local_control.poll = 1;
local_control.reqseq = chan->buffer_seq;
l2cap_send_sframe(chan, 0);
l2cap_send_sframe(chan, &local_control);

chan->retry_count = 1;
__set_monitor_timer(chan);
Expand Down Expand Up @@ -2333,7 +2354,7 @@ static int l2cap_tx_state_wait_f(struct l2cap_chan *chan,
local_control.super = L2CAP_SUPER_RR;
local_control.poll = 1;
local_control.reqseq = chan->buffer_seq;
l2cap_send_sframe(chan, 0);
l2cap_send_sframe(chan, &local_control);

chan->retry_count = 1;
__set_monitor_timer(chan);
Expand Down Expand Up @@ -4233,7 +4254,6 @@ static inline void l2cap_send_i_or_rr_or_rnr(struct l2cap_chan *chan)

if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) {
control |= __set_ctrl_super(chan, L2CAP_SUPER_RNR);
l2cap_send_sframe(chan, control);
set_bit(CONN_RNR_SENT, &chan->conn_state);
}

Expand All @@ -4245,7 +4265,6 @@ static inline void l2cap_send_i_or_rr_or_rnr(struct l2cap_chan *chan)
if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state) &&
chan->frames_sent == 0) {
control |= __set_ctrl_super(chan, L2CAP_SUPER_RR);
l2cap_send_sframe(chan, control);
}
}

Expand Down Expand Up @@ -4404,7 +4423,6 @@ static void l2cap_ertm_exit_local_busy(struct l2cap_chan *chan)
control = __set_reqseq(chan, chan->buffer_seq);
control |= __set_ctrl_poll(chan);
control |= __set_ctrl_super(chan, L2CAP_SUPER_RR);
l2cap_send_sframe(chan, control);
chan->retry_count = 1;

__clear_retrans_timer(chan);
Expand Down Expand Up @@ -4468,7 +4486,6 @@ static void l2cap_resend_srejframe(struct l2cap_chan *chan, u16 tx_seq)
}
control = __set_ctrl_super(chan, L2CAP_SUPER_SREJ);
control |= __set_reqseq(chan, l->tx_seq);
l2cap_send_sframe(chan, control);
list_del(&l->list);
list_add_tail(&l->list, &chan->srej_l);
}
Expand All @@ -4483,7 +4500,6 @@ static int l2cap_send_srejframe(struct l2cap_chan *chan, u16 tx_seq)
control = __set_ctrl_super(chan, L2CAP_SUPER_SREJ);
control |= __set_reqseq(chan, chan->expected_tx_seq);
l2cap_seq_list_append(&chan->srej_list, chan->expected_tx_seq);
l2cap_send_sframe(chan, control);

new = kzalloc(sizeof(struct srej_list), GFP_ATOMIC);
if (!new)
Expand Down Expand Up @@ -4767,7 +4783,6 @@ static inline void l2cap_data_channel_rnrframe(struct l2cap_chan *chan, u32 rx_c
l2cap_send_srejtail(chan);
} else {
rx_control = __set_ctrl_super(chan, L2CAP_SUPER_RR);
l2cap_send_sframe(chan, rx_control);
}
}

Expand Down

0 comments on commit 92c85f2

Please sign in to comment.