From: Luiz Augusto von Dentz <luiz.von.dentz@xxxxxxxxx> bt_gatt_server_set_authorize can be used to set the callback to authorize attribute operations which is required in order to send out of sync error as that has to happen even in case the handle is not valid. --- src/shared/gatt-server.c | 34 ++++++++++++++++++++++++++++++++++ src/shared/gatt-server.h | 7 +++++++ 2 files changed, 41 insertions(+) diff --git a/src/shared/gatt-server.c b/src/shared/gatt-server.c index 2c8b50065..0d9bb0762 100644 --- a/src/shared/gatt-server.c +++ b/src/shared/gatt-server.c @@ -114,6 +114,9 @@ struct bt_gatt_server { bt_gatt_server_debug_func_t debug_callback; bt_gatt_server_destroy_func_t debug_destroy; void *debug_data; + + bt_gatt_server_authorize_cb_t authorize; + void *authorize_data; }; static void bt_gatt_server_free(struct bt_gatt_server *server) @@ -785,6 +788,16 @@ static void write_complete_cb(struct gatt_db_attribute *attr, int err, async_write_op_destroy(op); } +static uint8_t authorize_req(struct bt_gatt_server *server, + uint8_t opcode, uint16_t handle) +{ + if (!server->authorize) + return 0; + + return server->authorize(server->att, opcode, handle, + server->authorize_data); +} + static void write_cb(uint8_t opcode, const void *pdu, uint16_t length, void *user_data) { @@ -799,6 +812,10 @@ static void write_cb(uint8_t opcode, const void *pdu, goto error; } + ecode = authorize_req(server, opcode, handle); + if (ecode) + goto error; + handle = get_le16(pdu); attr = gatt_db_get_attribute(server->db, handle); if (!attr) { @@ -906,6 +923,10 @@ static void handle_read_req(struct bt_gatt_server *server, uint8_t opcode, uint8_t ecode; struct async_read_op *op = NULL; + ecode = authorize_req(server, opcode, handle); + if (ecode) + goto error; + attr = gatt_db_get_attribute(server->db, handle); if (!attr) { ecode = BT_ATT_ERROR_INVALID_HANDLE; @@ -1725,3 +1746,16 @@ bool bt_gatt_server_send_indication(struct bt_gatt_server *server, return result; } + +bool bt_gatt_server_set_authorize(struct bt_gatt_server *server, + bt_gatt_server_authorize_cb_t cb, + void *user_data) +{ + if (!server) + return false; + + server->authorize = cb; + server->authorize_data = user_data; + + return true; +} diff --git a/src/shared/gatt-server.h b/src/shared/gatt-server.h index 8d88ccee8..c3d83f225 100644 --- a/src/shared/gatt-server.h +++ b/src/shared/gatt-server.h @@ -43,6 +43,13 @@ bool bt_gatt_server_set_debug(struct bt_gatt_server *server, void *user_data, bt_gatt_server_destroy_func_t destroy); +typedef uint8_t (*bt_gatt_server_authorize_cb_t)(struct bt_att *att, + uint8_t opcode, uint16_t handle, + void *user_data); +bool bt_gatt_server_set_authorize(struct bt_gatt_server *server, + bt_gatt_server_authorize_cb_t cb, + void *user_data); + bool bt_gatt_server_send_notification(struct bt_gatt_server *server, uint16_t handle, const uint8_t *value, uint16_t length); -- 2.17.2