From 4ff2a9985ffac9000a7a0ce46aecf4c382421bd9 Mon Sep 17 00:00:00 2001 From: Arman Uguray Date: Mon, 13 Oct 2014 14:10:01 -0700 Subject: [PATCH] shared/gatt-server: Support Exchange MTU This patch adds handling for the exchange MTU request. --- src/shared/gatt-server.c | 61 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 55 insertions(+), 6 deletions(-) diff --git a/src/shared/gatt-server.c b/src/shared/gatt-server.c index 4c492d5c0..4d9d92fa8 100644 --- a/src/shared/gatt-server.c +++ b/src/shared/gatt-server.c @@ -34,33 +34,82 @@ #define MAX(a, b) ((a) > (b) ? (a) : (b)) #endif +#ifndef MIN +#define MIN(a, b) ((a) < (b) ? (a) : (b)) +#endif + struct bt_gatt_server { struct gatt_db *db; struct bt_att *att; int ref_count; uint16_t mtu; + unsigned int mtu_id; + bt_gatt_server_debug_func_t debug_callback; bt_gatt_server_destroy_func_t debug_destroy; void *debug_data; }; -static bool gatt_server_register_att_handlers(struct bt_gatt_server *server) -{ - /* TODO */ - return true; -} - static void bt_gatt_server_free(struct bt_gatt_server *server) { if (server->debug_destroy) server->debug_destroy(server->debug_data); + bt_att_unregister(server->att, server->mtu_id); bt_att_unref(server->att); free(server); } +static void encode_error_rsp(uint8_t opcode, uint16_t handle, uint8_t ecode, + uint8_t pdu[4]) +{ + pdu[0] = opcode; + pdu[3] = ecode; + put_le16(handle, pdu + 1); +} + +static void exchange_mtu_cb(uint8_t opcode, const void *pdu, + uint16_t length, void *user_data) +{ + struct bt_gatt_server *server = user_data; + uint16_t client_rx_mtu; + uint16_t final_mtu; + uint8_t rsp_pdu[4]; + + if (length != 2) { + encode_error_rsp(opcode, 0, BT_ATT_ERROR_INVALID_PDU, rsp_pdu); + bt_att_send(server->att, BT_ATT_OP_ERROR_RSP, rsp_pdu, + sizeof(rsp_pdu), NULL, NULL, NULL); + return; + } + + client_rx_mtu = get_le16(pdu); + final_mtu = MAX(MIN(client_rx_mtu, server->mtu), BT_ATT_DEFAULT_LE_MTU); + + /* Respond with the server MTU */ + put_le16(server->mtu, rsp_pdu); + bt_att_send(server->att, BT_ATT_OP_MTU_RSP, rsp_pdu, 2, NULL, NULL, + NULL); + + /* Set MTU to be the minimum */ + server->mtu = final_mtu; + bt_att_set_mtu(server->att, final_mtu); +} + +static bool gatt_server_register_att_handlers(struct bt_gatt_server *server) +{ + /* EXCHANGE MTU request */ + server->mtu_id = bt_att_register(server->att, BT_ATT_OP_MTU_REQ, + exchange_mtu_cb, + server, NULL); + if (!server->mtu_id) + return false; + + return true; +} + struct bt_gatt_server *bt_gatt_server_new(struct gatt_db *db, struct bt_att *att, uint16_t mtu) { -- 2.47.3