Bluetooth: Add code to handle BT_ATT_OP_MTU_REQ
Add code to respond to BT_ATT_OP_MTU_REQ with BT_ATT_OP_MTU_RSP selecting the MTU based on the amount of room bt_buf has: < ACL Data RX: Handle 39 flags 0x02 dlen 7 ATT: Exchange MTU Response (0x03) len 2 Server RX MTU: 65 Change-Id: I47b8179fcee0d6adff5761abc37cfcb1ed636d65 Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This commit is contained in:
parent
7cbb4e6f4b
commit
028edd59ba
2 changed files with 52 additions and 0 deletions
|
@ -35,6 +35,7 @@
|
|||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <misc/byteorder.h>
|
||||
#include <misc/util.h>
|
||||
|
||||
#include <bluetooth/hci.h>
|
||||
#include <bluetooth/bluetooth.h>
|
||||
|
@ -63,6 +64,51 @@ static void send_err_rsp(struct bt_conn *conn, uint8_t req, uint16_t handle,
|
|||
bt_conn_send(conn, buf);
|
||||
}
|
||||
|
||||
static void att_mtu_req(struct bt_conn *conn, struct bt_buf *data)
|
||||
{
|
||||
struct bt_att_exchange_mtu_req *req;
|
||||
struct bt_att_exchange_mtu_rsp *rsp;
|
||||
struct bt_buf *buf;
|
||||
uint16_t mtu;
|
||||
|
||||
if (data->len != sizeof(*req)) {
|
||||
send_err_rsp(conn, BT_ATT_OP_MTU_REQ, 0,
|
||||
BT_ATT_ERR_INVALID_PDU);
|
||||
return;
|
||||
}
|
||||
|
||||
req = (void *)data->data;
|
||||
|
||||
mtu = sys_le16_to_cpu(req->mtu);
|
||||
|
||||
BT_DBG("Client MTU %u\n", mtu);
|
||||
|
||||
if (mtu > BT_ATT_MAX_LE_MTU || mtu < BT_ATT_DEFAULT_LE_MTU) {
|
||||
send_err_rsp(conn, BT_ATT_OP_MTU_REQ, 0,
|
||||
BT_ATT_ERR_INVALID_PDU);
|
||||
return;
|
||||
}
|
||||
|
||||
buf = bt_att_create_pdu(conn, BT_ATT_OP_MTU_RSP, sizeof(*rsp));
|
||||
if (!buf) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* 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(buf) + 1);
|
||||
|
||||
BT_DBG("Server MTU %u\n", mtu);
|
||||
|
||||
/* TODO: Store the MTU negotiated */
|
||||
|
||||
rsp = (void *)bt_buf_add(buf, sizeof(*rsp));
|
||||
rsp->mtu = sys_cpu_to_le16(mtu);
|
||||
|
||||
bt_conn_send(conn, buf);
|
||||
}
|
||||
|
||||
void bt_att_recv(struct bt_conn *conn, struct bt_buf *buf)
|
||||
{
|
||||
struct bt_att_hdr *hdr = (void *)buf->data;
|
||||
|
@ -77,6 +123,9 @@ void bt_att_recv(struct bt_conn *conn, struct bt_buf *buf)
|
|||
bt_buf_pull(buf, sizeof(*hdr));
|
||||
|
||||
switch (hdr->code) {
|
||||
case BT_ATT_OP_MTU_REQ:
|
||||
att_mtu_req(conn, buf);
|
||||
break;
|
||||
default:
|
||||
BT_DBG("Unhandled ATT code %u\n", hdr->code);
|
||||
send_err_rsp(conn, hdr->code, 0, BT_ATT_ERR_NOT_SUPPORTED);
|
||||
|
|
|
@ -30,6 +30,9 @@
|
|||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#define BT_ATT_DEFAULT_LE_MTU 23
|
||||
#define BT_ATT_MAX_LE_MTU 517
|
||||
|
||||
struct bt_att_hdr {
|
||||
uint8_t code;
|
||||
} PACK_STRUCT;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue