3 * BlueZ - Bluetooth protocol stack for Linux
5 * Copyright (C) 2014 Google Inc.
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
32 #include "src/shared/io.h"
33 #include "src/shared/queue.h"
34 #include "src/shared/util.h"
35 #include "src/shared/timeout.h"
37 #include "src/shared/att.h"
38 #include "src/shared/att-types.h"
40 #define ATT_MIN_PDU_LEN 1 /* At least 1 byte for the opcode. */
41 #define ATT_OP_CMD_MASK 0x40
42 #define ATT_OP_SIGNED_MASK 0x80
43 #define ATT_TIMEOUT_INTERVAL 30000 /* 30000 ms */
52 struct queue *req_queue; /* Queued ATT protocol requests */
53 struct att_send_op *pending_req;
54 struct queue *ind_queue; /* Queued ATT protocol indications */
55 struct att_send_op *pending_ind;
56 struct queue *write_queue; /* Queue of PDUs ready to send */
59 struct queue *notify_list; /* List of registered callbacks */
61 bool need_notify_cleanup;
63 struct queue *disconn_list; /* List of disconnect handlers */
65 bool need_disconn_cleanup;
70 unsigned int next_send_id; /* IDs for "send" ops */
71 unsigned int next_reg_id; /* IDs for registered callbacks */
73 bt_att_timeout_func_t timeout_callback;
74 bt_att_destroy_func_t timeout_destroy;
77 bt_att_debug_func_t debug_callback;
78 bt_att_destroy_func_t debug_destroy;
94 enum att_op_type type;
95 } att_opcode_type_table[] = {
96 { BT_ATT_OP_ERROR_RSP, ATT_OP_TYPE_RSP },
97 { BT_ATT_OP_MTU_REQ, ATT_OP_TYPE_REQ },
98 { BT_ATT_OP_MTU_RSP, ATT_OP_TYPE_RSP },
99 { BT_ATT_OP_FIND_INFO_REQ, ATT_OP_TYPE_REQ },
100 { BT_ATT_OP_FIND_INFO_RSP, ATT_OP_TYPE_RSP },
101 { BT_ATT_OP_FIND_BY_TYPE_VAL_REQ, ATT_OP_TYPE_REQ },
102 { BT_ATT_OP_FIND_BY_TYPE_VAL_RSP, ATT_OP_TYPE_RSP },
103 { BT_ATT_OP_READ_BY_TYPE_REQ, ATT_OP_TYPE_REQ },
104 { BT_ATT_OP_READ_BY_TYPE_RSP, ATT_OP_TYPE_RSP },
105 { BT_ATT_OP_READ_REQ, ATT_OP_TYPE_REQ },
106 { BT_ATT_OP_READ_RSP, ATT_OP_TYPE_RSP },
107 { BT_ATT_OP_READ_BLOB_REQ, ATT_OP_TYPE_REQ },
108 { BT_ATT_OP_READ_BLOB_RSP, ATT_OP_TYPE_RSP },
109 { BT_ATT_OP_READ_MULT_REQ, ATT_OP_TYPE_REQ },
110 { BT_ATT_OP_READ_MULT_RSP, ATT_OP_TYPE_RSP },
111 { BT_ATT_OP_READ_BY_GRP_TYPE_REQ, ATT_OP_TYPE_REQ },
112 { BT_ATT_OP_READ_BY_GRP_TYPE_RSP, ATT_OP_TYPE_RSP },
113 { BT_ATT_OP_WRITE_REQ, ATT_OP_TYPE_REQ },
114 { BT_ATT_OP_WRITE_RSP, ATT_OP_TYPE_RSP },
115 { BT_ATT_OP_WRITE_CMD, ATT_OP_TYPE_CMD },
116 { BT_ATT_OP_SIGNED_WRITE_CMD, ATT_OP_TYPE_CMD },
117 { BT_ATT_OP_PREP_WRITE_REQ, ATT_OP_TYPE_REQ },
118 { BT_ATT_OP_PREP_WRITE_RSP, ATT_OP_TYPE_RSP },
119 { BT_ATT_OP_EXEC_WRITE_REQ, ATT_OP_TYPE_REQ },
120 { BT_ATT_OP_EXEC_WRITE_RSP, ATT_OP_TYPE_RSP },
121 { BT_ATT_OP_HANDLE_VAL_NOT, ATT_OP_TYPE_NOT },
122 { BT_ATT_OP_HANDLE_VAL_IND, ATT_OP_TYPE_IND },
123 { BT_ATT_OP_HANDLE_VAL_CONF, ATT_OP_TYPE_CONF },
127 static enum att_op_type get_op_type(uint8_t opcode)
131 for (i = 0; att_opcode_type_table[i].opcode; i++) {
132 if (att_opcode_type_table[i].opcode == opcode)
133 return att_opcode_type_table[i].type;
136 return ATT_OP_TYPE_UNKNOWN;
139 static const struct {
142 } att_req_rsp_mapping_table[] = {
143 { BT_ATT_OP_MTU_REQ, BT_ATT_OP_MTU_RSP },
144 { BT_ATT_OP_FIND_INFO_REQ, BT_ATT_OP_FIND_INFO_RSP},
145 { BT_ATT_OP_FIND_BY_TYPE_VAL_REQ, BT_ATT_OP_FIND_BY_TYPE_VAL_RSP },
146 { BT_ATT_OP_READ_BY_TYPE_REQ, BT_ATT_OP_READ_BY_TYPE_RSP },
147 { BT_ATT_OP_READ_REQ, BT_ATT_OP_READ_RSP },
148 { BT_ATT_OP_READ_BLOB_REQ, BT_ATT_OP_READ_BLOB_RSP },
149 { BT_ATT_OP_READ_MULT_REQ, BT_ATT_OP_READ_MULT_RSP },
150 { BT_ATT_OP_READ_BY_GRP_TYPE_REQ, BT_ATT_OP_READ_BY_GRP_TYPE_RSP },
151 { BT_ATT_OP_WRITE_REQ, BT_ATT_OP_WRITE_RSP },
152 { BT_ATT_OP_PREP_WRITE_REQ, BT_ATT_OP_PREP_WRITE_RSP },
153 { BT_ATT_OP_EXEC_WRITE_REQ, BT_ATT_OP_EXEC_WRITE_RSP },
157 static uint8_t get_req_opcode(uint8_t rsp_opcode)
161 for (i = 0; att_req_rsp_mapping_table[i].rsp_opcode; i++) {
162 if (att_req_rsp_mapping_table[i].rsp_opcode == rsp_opcode)
163 return att_req_rsp_mapping_table[i].req_opcode;
171 unsigned int timeout_id;
172 enum att_op_type type;
176 bt_att_response_func_t callback;
177 bt_att_destroy_func_t destroy;
181 static void destroy_att_send_op(void *data)
183 struct att_send_op *op = data;
186 timeout_remove(op->timeout_id);
189 op->destroy(op->user_data);
190 #endif /* To avoid crash */
200 bt_att_notify_func_t callback;
201 bt_att_destroy_func_t destroy;
205 static void destroy_att_notify(void *data)
207 struct att_notify *notify = data;
210 notify->destroy(notify->user_data);
215 static bool match_notify_id(const void *a, const void *b)
217 const struct att_notify *notify = a;
218 unsigned int id = PTR_TO_UINT(b);
220 return notify->id == id;
223 static bool match_notify_removed(const void *a, const void *b)
225 const struct att_notify *notify = a;
227 return notify->removed;
230 static void mark_notify_removed(void *data, void *user_data)
232 struct att_notify *notify = data;
234 notify->removed = true;
240 bt_att_disconnect_func_t callback;
241 bt_att_destroy_func_t destroy;
245 static void destroy_att_disconn(void *data)
247 struct att_disconn *disconn = data;
249 if (disconn->destroy)
250 disconn->destroy(disconn->user_data);
255 static bool match_disconn_id(const void *a, const void *b)
257 const struct att_disconn *disconn = a;
258 unsigned int id = PTR_TO_UINT(b);
260 return disconn->id == id;
263 static bool match_disconn_removed(const void *a, const void *b)
265 const struct att_disconn *disconn = a;
267 return disconn->removed;
270 static void mark_disconn_removed(void *data, void *user_data)
272 struct att_disconn *disconn = data;
274 disconn->removed = true;
277 static bool encode_pdu(struct att_send_op *op, const void *pdu,
278 uint16_t length, uint16_t mtu)
280 uint16_t pdu_len = 1;
289 op->pdu = malloc(op->len);
293 ((uint8_t *) op->pdu)[0] = op->opcode;
295 memcpy(op->pdu + 1, pdu, length);
300 static struct att_send_op *create_att_send_op(uint8_t opcode, const void *pdu,
301 uint16_t length, uint16_t mtu,
302 bt_att_response_func_t callback,
304 bt_att_destroy_func_t destroy)
306 struct att_send_op *op;
307 enum att_op_type op_type;
312 op_type = get_op_type(opcode);
313 if (op_type == ATT_OP_TYPE_UNKNOWN)
316 /* If the opcode corresponds to an operation type that does not elicit a
317 * response from the remote end, then no callback should have been
318 * provided, since it will never be called.
320 if (callback && op_type != ATT_OP_TYPE_REQ && op_type != ATT_OP_TYPE_IND)
323 /* Similarly, if the operation does elicit a response then a callback
326 if (!callback && (op_type == ATT_OP_TYPE_REQ || op_type == ATT_OP_TYPE_IND))
329 op = new0(struct att_send_op, 1);
335 op->callback = callback;
336 op->destroy = destroy;
337 op->user_data = user_data;
339 if (!encode_pdu(op, pdu, length, mtu)) {
347 static struct att_send_op *pick_next_send_op(struct bt_att *att)
349 struct att_send_op *op;
351 /* See if any operations are already in the write queue */
352 op = queue_pop_head(att->write_queue);
356 /* If there is no pending request, pick an operation from the
359 if (!att->pending_req) {
360 op = queue_pop_head(att->req_queue);
365 /* There is either a request pending or no requests queued. If there is
366 * no pending indication, pick an operation from the indication queue.
368 if (!att->pending_ind) {
369 op = queue_pop_head(att->ind_queue);
377 struct timeout_data {
382 static bool timeout_cb(void *user_data)
384 struct timeout_data *timeout = user_data;
385 struct bt_att *att = timeout->att;
386 struct att_send_op *op = NULL;
388 if (att->pending_req && att->pending_req->id == timeout->id) {
389 op = att->pending_req;
390 att->pending_req = NULL;
391 } else if (att->pending_ind && att->pending_ind->id == timeout->id) {
392 op = att->pending_ind;
393 att->pending_ind = NULL;
402 util_debug(att->debug_callback, att->debug_data,
403 "Operation timed out: 0x%02x", op->opcode);
405 if (att->timeout_callback)
406 att->timeout_callback(op->id, op->opcode, att->timeout_data);
409 destroy_att_send_op(op);
414 static void write_watch_destroy(void *user_data)
416 struct bt_att *att = user_data;
418 att->writer_active = false;
421 static bool can_write_data(struct io *io, void *user_data)
423 struct bt_att *att = user_data;
424 struct att_send_op *op;
425 struct timeout_data *timeout;
426 ssize_t bytes_written;
428 op = pick_next_send_op(att);
432 bytes_written = write(att->fd, op->pdu, op->len);
433 if (bytes_written < 0) {
434 util_debug(att->debug_callback, att->debug_data,
435 "write failed: %s", strerror(errno));
437 op->callback(BT_ATT_OP_ERROR_RSP, NULL, 0,
440 destroy_att_send_op(op);
444 util_debug(att->debug_callback, att->debug_data,
445 "ATT op 0x%02x", op->opcode);
447 util_hexdump('<', op->pdu, bytes_written,
448 att->debug_callback, att->debug_data);
450 /* Based on the operation type, set either the pending request or the
451 * pending indication. If it came from the write queue, then there is
452 * no need to keep it around.
455 case ATT_OP_TYPE_REQ:
456 att->pending_req = op;
458 case ATT_OP_TYPE_IND:
459 att->pending_ind = op;
462 destroy_att_send_op(op);
466 timeout = new0(struct timeout_data, 1);
471 timeout->id = op->id;
472 op->timeout_id = timeout_add(ATT_TIMEOUT_INTERVAL, timeout_cb,
475 /* Return true as there may be more operations ready to write. */
479 static void wakeup_writer(struct bt_att *att)
481 if (att->writer_active)
484 /* Set the write handler only if there is anything that can be sent
487 if (queue_isempty(att->write_queue)) {
488 if ((att->pending_req || queue_isempty(att->req_queue)) &&
489 (att->pending_ind || queue_isempty(att->ind_queue)))
493 if (!io_set_write_handler(att->io, can_write_data, att,
494 write_watch_destroy))
497 att->writer_active = true;
500 static void handle_rsp(struct bt_att *att, uint8_t opcode, uint8_t *pdu,
503 struct att_send_op *op = att->pending_req;
506 uint8_t *rsp_pdu = NULL;
507 uint16_t rsp_pdu_len = 0;
509 /* If no request is pending, then the response is unexpected. */
515 /* If the received response doesn't match the pending request, or if
516 * the request is malformed, end the current request with failure.
518 if (opcode == BT_ATT_OP_ERROR_RSP) {
523 } else if (!(req_opcode = get_req_opcode(opcode)))
526 if (req_opcode != op->opcode)
533 rsp_pdu_len = pdu_len;
539 util_debug(att->debug_callback, att->debug_data,
540 "Failed to handle response PDU; opcode: 0x%02x", opcode);
541 rsp_opcode = BT_ATT_OP_ERROR_RSP;
545 op->callback(rsp_opcode, rsp_pdu, rsp_pdu_len, op->user_data);
547 destroy_att_send_op(op);
548 att->pending_req = NULL;
559 static void notify_handler(void *data, void *user_data)
561 struct att_notify *notify = data;
562 struct notify_data *not_data = user_data;
567 if (notify->opcode != not_data->opcode)
570 if (notify->callback)
571 notify->callback(not_data->opcode, not_data->pdu,
572 not_data->pdu_len, notify->user_data);
575 static void handle_notify(struct bt_att *att, uint8_t opcode, uint8_t *pdu,
578 struct notify_data data;
581 att->in_notify = true;
583 memset(&data, 0, sizeof(data));
584 data.opcode = opcode;
588 data.pdu_len = pdu_len;
591 queue_foreach(att->notify_list, notify_handler, &data);
593 att->in_notify = false;
595 if (att->need_notify_cleanup) {
596 queue_remove_all(att->notify_list, match_notify_removed, NULL,
598 att->need_notify_cleanup = false;
604 static bool can_read_data(struct io *io, void *user_data)
606 struct bt_att *att = user_data;
611 bytes_read = read(att->fd, att->buf, att->mtu);
615 util_hexdump('>', att->buf, bytes_read,
616 att->debug_callback, att->debug_data);
618 if (bytes_read < ATT_MIN_PDU_LEN)
624 /* Act on the received PDU based on the opcode type */
625 switch (get_op_type(opcode)) {
626 case ATT_OP_TYPE_RSP:
627 util_debug(att->debug_callback, att->debug_data,
628 "ATT response received: 0x%02x", opcode);
629 handle_rsp(att, opcode, pdu + 1, bytes_read - 1);
631 case ATT_OP_TYPE_CONF:
632 util_debug(att->debug_callback, att->debug_data,
633 "ATT opcode cannot be handled: 0x%02x", opcode);
636 /* For all other opcodes notify the upper layer of the PDU and
637 * let them act on it.
639 util_debug(att->debug_callback, att->debug_data,
640 "ATT PDU received: 0x%02x", opcode);
641 handle_notify(att, opcode, pdu + 1, bytes_read - 1);
648 static void disconn_handler(void *data, void *user_data)
650 struct att_disconn *disconn = data;
652 if (disconn->removed)
655 if (disconn->callback)
656 disconn->callback(disconn->user_data);
659 static bool disconnect_cb(struct io *io, void *user_data)
661 struct bt_att *att = user_data;
666 util_debug(att->debug_callback, att->debug_data,
667 "Physical link disconnected");
670 att->in_disconn = true;
671 queue_foreach(att->disconn_list, disconn_handler, NULL);
672 att->in_disconn = false;
674 if (att->need_disconn_cleanup) {
675 queue_remove_all(att->disconn_list, match_disconn_removed, NULL,
676 destroy_att_disconn);
677 att->need_disconn_cleanup = false;
680 bt_att_cancel_all(att);
681 bt_att_unregister_all(att);
688 struct bt_att *bt_att_new(int fd)
695 att = new0(struct bt_att, 1);
701 att->mtu = BT_ATT_DEFAULT_LE_MTU;
702 att->buf = malloc(att->mtu);
706 att->io = io_new(fd);
710 att->req_queue = queue_new();
714 att->ind_queue = queue_new();
718 att->write_queue = queue_new();
719 if (!att->write_queue)
722 att->notify_list = queue_new();
723 if (!att->notify_list)
726 att->disconn_list = queue_new();
727 if (!att->disconn_list)
730 if (!io_set_read_handler(att->io, can_read_data, att, NULL))
733 if (!io_set_disconnect_handler(att->io, disconnect_cb, att, NULL))
736 return bt_att_ref(att);
739 queue_destroy(att->req_queue, NULL);
740 queue_destroy(att->ind_queue, NULL);
741 queue_destroy(att->write_queue, NULL);
742 queue_destroy(att->notify_list, NULL);
743 queue_destroy(att->disconn_list, NULL);
751 struct bt_att *bt_att_ref(struct bt_att *att)
756 __sync_fetch_and_add(&att->ref_count, 1);
761 void bt_att_unref(struct bt_att *att)
766 if (__sync_sub_and_fetch(&att->ref_count, 1))
769 bt_att_unregister_all(att);
770 bt_att_cancel_all(att);
775 queue_destroy(att->req_queue, NULL);
776 queue_destroy(att->ind_queue, NULL);
777 queue_destroy(att->write_queue, NULL);
778 queue_destroy(att->notify_list, NULL);
779 queue_destroy(att->disconn_list, NULL);
780 att->req_queue = NULL;
781 att->ind_queue = NULL;
782 att->write_queue = NULL;
783 att->notify_list = NULL;
785 if (att->timeout_destroy)
786 att->timeout_destroy(att->timeout_data);
788 if (att->debug_destroy)
789 att->debug_destroy(att->debug_data);
797 bool bt_att_set_close_on_unref(struct bt_att *att, bool do_close)
799 if (!att || !att->io)
802 return io_set_close_on_destroy(att->io, do_close);
805 bool bt_att_set_debug(struct bt_att *att, bt_att_debug_func_t callback,
806 void *user_data, bt_att_destroy_func_t destroy)
811 if (att->debug_destroy)
812 att->debug_destroy(att->debug_data);
814 att->debug_callback = callback;
815 att->debug_destroy = destroy;
816 att->debug_data = user_data;
821 uint16_t bt_att_get_mtu(struct bt_att *att)
829 bool bt_att_set_mtu(struct bt_att *att, uint16_t mtu)
836 if (mtu < BT_ATT_DEFAULT_LE_MTU)
851 bool bt_att_set_timeout_cb(struct bt_att *att, bt_att_timeout_func_t callback,
853 bt_att_destroy_func_t destroy)
858 if (att->timeout_destroy)
859 att->timeout_destroy(att->timeout_data);
861 att->timeout_callback = callback;
862 att->timeout_destroy = destroy;
863 att->timeout_data = user_data;
868 unsigned int bt_att_register_disconnect(struct bt_att *att,
869 bt_att_disconnect_func_t callback,
871 bt_att_destroy_func_t destroy)
873 struct att_disconn *disconn;
875 if (!att || !att->io)
878 disconn = new0(struct att_disconn, 1);
882 disconn->callback = callback;
883 disconn->destroy = destroy;
884 disconn->user_data = user_data;
886 if (att->next_reg_id < 1)
887 att->next_reg_id = 1;
889 disconn->id = att->next_reg_id++;
891 if (!queue_push_tail(att->disconn_list, disconn)) {
899 bool bt_att_unregister_disconnect(struct bt_att *att, unsigned int id)
901 struct att_disconn *disconn;
906 disconn = queue_find(att->disconn_list, match_disconn_id,
911 if (!att->in_disconn) {
912 queue_remove(att->disconn_list, disconn);
913 destroy_att_disconn(disconn);
917 disconn->removed = true;
918 att->need_disconn_cleanup = true;
923 unsigned int bt_att_send(struct bt_att *att, uint8_t opcode,
924 const void *pdu, uint16_t length,
925 bt_att_response_func_t callback, void *user_data,
926 bt_att_destroy_func_t destroy)
928 struct att_send_op *op;
931 if (!att || !att->io)
934 op = create_att_send_op(opcode, pdu, length, att->mtu, callback,
939 if (att->next_send_id < 1)
940 att->next_send_id = 1;
942 op->id = att->next_send_id++;
944 /* Add the op to the correct queue based on its type */
946 case ATT_OP_TYPE_REQ:
947 result = queue_push_tail(att->req_queue, op);
949 case ATT_OP_TYPE_IND:
950 result = queue_push_tail(att->ind_queue, op);
953 result = queue_push_tail(att->write_queue, op);
968 static bool match_op_id(const void *a, const void *b)
970 const struct att_send_op *op = a;
971 unsigned int id = PTR_TO_UINT(b);
976 bool bt_att_cancel(struct bt_att *att, unsigned int id)
978 struct att_send_op *op;
983 if (att->pending_req && att->pending_req->id == id) {
984 op = att->pending_req;
985 att->pending_req = NULL;
989 if (att->pending_ind && att->pending_ind->id == id) {
990 op = att->pending_ind;
991 att->pending_ind = NULL;
995 op = queue_remove_if(att->req_queue, match_op_id, UINT_TO_PTR(id));
999 op = queue_remove_if(att->ind_queue, match_op_id, UINT_TO_PTR(id));
1003 op = queue_remove_if(att->write_queue, match_op_id, UINT_TO_PTR(id));
1011 destroy_att_send_op(op);
1018 bool bt_att_cancel_all(struct bt_att *att)
1023 queue_remove_all(att->req_queue, NULL, NULL, destroy_att_send_op);
1024 queue_remove_all(att->ind_queue, NULL, NULL, destroy_att_send_op);
1025 queue_remove_all(att->write_queue, NULL, NULL, destroy_att_send_op);
1027 if (att->pending_req) {
1028 destroy_att_send_op(att->pending_req);
1029 att->pending_req = NULL;
1032 if (att->pending_ind) {
1033 destroy_att_send_op(att->pending_ind);
1034 att->pending_ind = NULL;
1040 unsigned int bt_att_register(struct bt_att *att, uint8_t opcode,
1041 bt_att_notify_func_t callback,
1043 bt_att_destroy_func_t destroy)
1045 struct att_notify *notify;
1047 if (!att || !opcode || !callback || !att->io)
1050 notify = new0(struct att_notify, 1);
1054 notify->opcode = opcode;
1055 notify->callback = callback;
1056 notify->destroy = destroy;
1057 notify->user_data = user_data;
1059 if (att->next_reg_id < 1)
1060 att->next_reg_id = 1;
1062 notify->id = att->next_reg_id++;
1064 if (!queue_push_tail(att->notify_list, notify)) {
1072 bool bt_att_unregister(struct bt_att *att, unsigned int id)
1074 struct att_notify *notify;
1079 notify = queue_find(att->notify_list, match_notify_id,
1084 if (!att->in_notify) {
1085 queue_remove(att->notify_list, notify);
1086 destroy_att_notify(notify);
1090 notify->removed = true;
1091 att->need_notify_cleanup = true;
1096 bool bt_att_unregister_all(struct bt_att *att)
1101 if (att->in_notify) {
1102 queue_foreach(att->notify_list, mark_notify_removed, NULL);
1103 att->need_notify_cleanup = true;
1105 queue_remove_all(att->notify_list, NULL, NULL,
1106 destroy_att_notify);
1109 if (att->in_disconn) {
1110 queue_foreach(att->disconn_list, mark_disconn_removed, NULL);
1111 att->need_disconn_cleanup = true;
1113 queue_remove_all(att->disconn_list, NULL, NULL,
1114 destroy_att_disconn);