Skip to content

Commit

Permalink
Bluetooth: Auto tune if input MTU is set to 0
Browse files Browse the repository at this point in the history
This enables the code to set the input MTU using the underline link
packet types when set to 0, previously this would likely be rejected by
the remote peer since it would be bellow the minimal of 48 for BR/EDR
or 23 for LE, that way it shall be safe to use 0 without causing any
side effects.

This is convenient for the likes of A2DP transport, see:

https://habr.com/en/post/456182/

Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
  • Loading branch information
Luiz Augusto von Dentz authored and Marcel Holtmann committed Jan 4, 2020
1 parent 1efd927 commit 4b6e228
Showing 1 changed file with 52 additions and 2 deletions.
54 changes: 52 additions & 2 deletions net/bluetooth/l2cap_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -1289,6 +1289,9 @@ static void l2cap_le_connect(struct l2cap_chan *chan)
if (test_and_set_bit(FLAG_LE_CONN_REQ_SENT, &chan->flags))
return;

if (!chan->imtu)
chan->imtu = chan->conn->mtu;

l2cap_le_flowctl_init(chan, 0);

req.psm = chan->psm;
Expand Down Expand Up @@ -3226,6 +3229,49 @@ static inline void l2cap_txwin_setup(struct l2cap_chan *chan)
chan->ack_win = chan->tx_win;
}

static void l2cap_mtu_auto(struct l2cap_chan *chan)
{
struct hci_conn *conn = chan->conn->hcon;

chan->imtu = L2CAP_DEFAULT_MIN_MTU;

/* The 2-DH1 packet has between 2 and 56 information bytes
* (including the 2-byte payload header)
*/
if (!(conn->pkt_type & HCI_2DH1))
chan->imtu = 54;

/* The 3-DH1 packet has between 2 and 85 information bytes
* (including the 2-byte payload header)
*/
if (!(conn->pkt_type & HCI_3DH1))
chan->imtu = 83;

/* The 2-DH3 packet has between 2 and 369 information bytes
* (including the 2-byte payload header)
*/
if (!(conn->pkt_type & HCI_2DH3))
chan->imtu = 367;

/* The 3-DH3 packet has between 2 and 554 information bytes
* (including the 2-byte payload header)
*/
if (!(conn->pkt_type & HCI_3DH3))
chan->imtu = 552;

/* The 2-DH5 packet has between 2 and 681 information bytes
* (including the 2-byte payload header)
*/
if (!(conn->pkt_type & HCI_2DH5))
chan->imtu = 679;

/* The 3-DH5 packet has between 2 and 1023 information bytes
* (including the 2-byte payload header)
*/
if (!(conn->pkt_type & HCI_3DH5))
chan->imtu = 1021;
}

static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data, size_t data_size)
{
struct l2cap_conf_req *req = data;
Expand Down Expand Up @@ -3255,8 +3301,12 @@ static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data, size_t data
}

done:
if (chan->imtu != L2CAP_DEFAULT_MTU)
l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu, endptr - ptr);
if (chan->imtu != L2CAP_DEFAULT_MTU) {
if (!chan->imtu)
l2cap_mtu_auto(chan);
l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu,
endptr - ptr);
}

switch (chan->mode) {
case L2CAP_MODE_BASIC:
Expand Down

0 comments on commit 4b6e228

Please sign in to comment.