Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 315680
b: refs/heads/master
c: c20f8e3
h: refs/heads/master
v: v3
  • Loading branch information
Mat Martineau authored and Gustavo Padovan committed Jul 15, 2012
1 parent da70f77 commit 2c5d3e0
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 26 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: a0dfe0ab6bf194805ce9d6a2dc81efab7a4a7fda
refs/heads/master: c20f8e35ca8b0583323d310ec63a0f0d17cfdcf5
1 change: 1 addition & 0 deletions trunk/include/net/bluetooth/l2cap.h
Original file line number Diff line number Diff line change
Expand Up @@ -464,6 +464,7 @@ struct l2cap_chan {

__u16 tx_win;
__u16 tx_win_max;
__u16 ack_win;
__u8 max_tx;
__u16 retrans_timeout;
__u16 monitor_timeout;
Expand Down
59 changes: 34 additions & 25 deletions trunk/net/bluetooth/l2cap_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -431,6 +431,7 @@ void l2cap_chan_set_defaults(struct l2cap_chan *chan)
chan->max_tx = L2CAP_DEFAULT_MAX_TX;
chan->tx_win = L2CAP_DEFAULT_TX_WINDOW;
chan->tx_win_max = L2CAP_DEFAULT_TX_WINDOW;
chan->ack_win = L2CAP_DEFAULT_TX_WINDOW;
chan->sec_level = BT_SECURITY_LOW;

set_bit(FLAG_FORCE_ACTIVE, &chan->flags);
Expand Down Expand Up @@ -1877,10 +1878,10 @@ static void l2cap_send_ack(struct l2cap_chan *chan)
frames_to_ack = 0;
}

/* Ack now if the tx window is 3/4ths full.
/* Ack now if the window is 3/4ths full.
* Calculate without mul or div
*/
threshold = chan->tx_win;
threshold = chan->ack_win;
threshold += threshold << 1;
threshold >>= 2;

Expand Down Expand Up @@ -2786,6 +2787,7 @@ static inline void l2cap_txwin_setup(struct l2cap_chan *chan)
L2CAP_DEFAULT_TX_WINDOW);
chan->tx_win_max = L2CAP_DEFAULT_TX_WINDOW;
}
chan->ack_win = chan->tx_win;
}

static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data)
Expand Down Expand Up @@ -3175,10 +3177,9 @@ static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len, voi
break;

case L2CAP_CONF_EWS:
chan->tx_win = min_t(u16, val,
L2CAP_DEFAULT_EXT_WINDOW);
chan->ack_win = min_t(u16, val, chan->ack_win);
l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
chan->tx_win);
chan->tx_win);
break;

case L2CAP_CONF_EFS:
Expand Down Expand Up @@ -3207,6 +3208,9 @@ static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len, voi
chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
chan->mps = le16_to_cpu(rfc.max_pdu_size);
if (!test_bit(FLAG_EXT_CTRL, &chan->flags))
chan->ack_win = min_t(u16, chan->ack_win,
rfc.txwin_size);

if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
chan->local_msdu = le16_to_cpu(efs.msdu);
Expand Down Expand Up @@ -3268,7 +3272,17 @@ static void l2cap_conf_rfc_get(struct l2cap_chan *chan, void *rsp, int len)
{
int type, olen;
unsigned long val;
struct l2cap_conf_rfc rfc;
/* Use sane default values in case a misbehaving remote device
* did not send an RFC or extended window size option.
*/
u16 txwin_ext = chan->ack_win;
struct l2cap_conf_rfc rfc = {
.mode = chan->mode,
.retrans_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO),
.monitor_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO),
.max_pdu_size = cpu_to_le16(chan->imtu),
.txwin_size = min_t(u16, chan->ack_win, L2CAP_DEFAULT_TX_WINDOW),
};

BT_DBG("chan %p, rsp %p, len %d", chan, rsp, len);

Expand All @@ -3278,32 +3292,27 @@ static void l2cap_conf_rfc_get(struct l2cap_chan *chan, void *rsp, int len)
while (len >= L2CAP_CONF_OPT_SIZE) {
len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);

if (type != L2CAP_CONF_RFC)
continue;

if (olen != sizeof(rfc))
switch (type) {
case L2CAP_CONF_RFC:
if (olen == sizeof(rfc))
memcpy(&rfc, (void *)val, olen);
break;

memcpy(&rfc, (void *)val, olen);
goto done;
case L2CAP_CONF_EWS:
txwin_ext = val;
break;
}
}

/* Use sane default values in case a misbehaving remote device
* did not send an RFC option.
*/
rfc.mode = chan->mode;
rfc.retrans_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO);
rfc.monitor_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO);
rfc.max_pdu_size = cpu_to_le16(chan->imtu);

BT_ERR("Expected RFC option was not found, using defaults");

done:
switch (rfc.mode) {
case L2CAP_MODE_ERTM:
chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
chan->mps = le16_to_cpu(rfc.max_pdu_size);
chan->mps = le16_to_cpu(rfc.max_pdu_size);
if (test_bit(FLAG_EXT_CTRL, &chan->flags))
chan->ack_win = min_t(u16, chan->ack_win, txwin_ext);
else
chan->ack_win = min_t(u16, chan->ack_win,
rfc.txwin_size);
break;
case L2CAP_MODE_STREAMING:
chan->mps = le16_to_cpu(rfc.max_pdu_size);
Expand Down

0 comments on commit 2c5d3e0

Please sign in to comment.