From 2ba3c9aa1dceb0aec6a44f4f7df721823badf00b Mon Sep 17 00:00:00 2001 From: Mariusz Skamra Date: Wed, 14 Oct 2015 16:41:02 +0200 Subject: [PATCH] Bluetooth: Fix sending incorrect MTU in the Exchange MTU response According to the Core Spec 4.2 Vol 3 Part G The server shall respond with the Server Rx MTU parameter set to the maximum MTU that this server can receive. Once the messages have been exchanged, the ATT_MTU shall be set to the minimum of the Client Rx MTU and Server Rx MTU values. bt: att_mtu_req (0x0010fd04): Client MTU 672 bt: att_mtu_req (0x0010fd04): Server MTU 65 bt: att_mtu_req (0x0010fd04): Negotiated MTU 65 bt: att_mtu_req (0x0010fd04): Client MTU 42 bt: att_mtu_req (0x0010fd04): Server MTU 65 bt: att_mtu_req (0x0010fd04): Negotiated MTU 42 Change-Id: I13f2f0fc99e99d8188ed15bf7972a9b892612e11 Signed-off-by: Mariusz Skamra --- net/bluetooth/att.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/net/bluetooth/att.c b/net/bluetooth/att.c index 74fbcd98753..554b38813f7 100644 --- a/net/bluetooth/att.c +++ b/net/bluetooth/att.c @@ -134,16 +134,16 @@ static uint8_t att_mtu_req(struct bt_conn *conn, struct bt_buf *buf) struct bt_att_exchange_mtu_req *req; struct bt_att_exchange_mtu_rsp *rsp; struct bt_buf *pdu; - uint16_t mtu; + uint16_t mtu_client, mtu_server; req = (void *)buf->data; - mtu = sys_le16_to_cpu(req->mtu); + mtu_client = sys_le16_to_cpu(req->mtu); - BT_DBG("Client MTU %u\n", mtu); + BT_DBG("Client MTU %u\n", mtu_client); /* Check if MTU is valid */ - if (mtu < BT_ATT_DEFAULT_LE_MTU) { + if (mtu_client < BT_ATT_DEFAULT_LE_MTU) { return BT_ATT_ERR_INVALID_PDU; } @@ -155,17 +155,18 @@ static uint8_t att_mtu_req(struct bt_conn *conn, struct bt_buf *buf) /* Select MTU based on the amount of room we have in bt_buf including * one extra byte for ATT header. */ - mtu = min(mtu, bt_buf_tailroom(pdu) + 1); + mtu_server = bt_buf_tailroom(pdu) + 1; - BT_DBG("Server MTU %u\n", mtu); - - att->mtu = mtu; + BT_DBG("Server MTU %u\n", mtu_server); rsp = bt_buf_add(pdu, sizeof(*rsp)); - rsp->mtu = sys_cpu_to_le16(mtu); + rsp->mtu = sys_cpu_to_le16(mtu_server); bt_l2cap_send(conn, BT_L2CAP_CID_ATT, pdu); + att->mtu = min(mtu_client, mtu_server); + + BT_DBG("Negotiated MTU %u\n", att->mtu); return 0; }