tizen 2.3 release
[framework/connectivity/bluez.git] / src / shared / att.c
1 /*
2  *
3  *  BlueZ - Bluetooth protocol stack for Linux
4  *
5  *  Copyright (C) 2014  Google Inc.
6  *
7  *
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.
12  *
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.
17  *
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
21  *
22  */
23
24 #ifdef HAVE_CONFIG_H
25 #include <config.h>
26 #endif
27
28 #include <stdlib.h>
29 #include <unistd.h>
30 #include <errno.h>
31
32 #include "src/shared/io.h"
33 #include "src/shared/queue.h"
34 #include "src/shared/util.h"
35 #include "src/shared/timeout.h"
36 #include "lib/uuid.h"
37 #include "src/shared/att.h"
38 #include "src/shared/att-types.h"
39
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 */
44
45 struct att_send_op;
46
47 struct bt_att {
48         int ref_count;
49         int fd;
50         struct io *io;
51
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 */
57         bool writer_active;
58
59         struct queue *notify_list;      /* List of registered callbacks */
60         bool in_notify;
61         bool need_notify_cleanup;
62
63         struct queue *disconn_list;     /* List of disconnect handlers */
64         bool in_disconn;
65         bool need_disconn_cleanup;
66
67         uint8_t *buf;
68         uint16_t mtu;
69
70         unsigned int next_send_id;      /* IDs for "send" ops */
71         unsigned int next_reg_id;       /* IDs for registered callbacks */
72
73         bt_att_timeout_func_t timeout_callback;
74         bt_att_destroy_func_t timeout_destroy;
75         void *timeout_data;
76
77         bt_att_debug_func_t debug_callback;
78         bt_att_destroy_func_t debug_destroy;
79         void *debug_data;
80 };
81
82 enum att_op_type {
83         ATT_OP_TYPE_REQ,
84         ATT_OP_TYPE_RSP,
85         ATT_OP_TYPE_CMD,
86         ATT_OP_TYPE_IND,
87         ATT_OP_TYPE_NOT,
88         ATT_OP_TYPE_CONF,
89         ATT_OP_TYPE_UNKNOWN,
90 };
91
92 static const struct {
93         uint8_t opcode;
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 },
124         { }
125 };
126
127 static enum att_op_type get_op_type(uint8_t opcode)
128 {
129         int i;
130
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;
134         }
135
136         return ATT_OP_TYPE_UNKNOWN;
137 }
138
139 static const struct {
140         uint8_t req_opcode;
141         uint8_t rsp_opcode;
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 },
154         { }
155 };
156
157 static uint8_t get_req_opcode(uint8_t rsp_opcode)
158 {
159         int i;
160
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;
164         }
165
166         return 0;
167 }
168
169 struct att_send_op {
170         unsigned int id;
171         unsigned int timeout_id;
172         enum att_op_type type;
173         uint16_t opcode;
174         void *pdu;
175         uint16_t len;
176         bt_att_response_func_t callback;
177         bt_att_destroy_func_t destroy;
178         void *user_data;
179 };
180
181 static void destroy_att_send_op(void *data)
182 {
183         struct att_send_op *op = data;
184 #if 0
185         if (op->timeout_id)
186                 timeout_remove(op->timeout_id);
187
188         if (op->destroy)
189                 op->destroy(op->user_data);
190 #endif /* To avoid crash */
191         free(op->pdu);
192         free(op);
193
194 }
195
196 struct att_notify {
197         unsigned int id;
198         uint16_t opcode;
199         bool removed;
200         bt_att_notify_func_t callback;
201         bt_att_destroy_func_t destroy;
202         void *user_data;
203 };
204
205 static void destroy_att_notify(void *data)
206 {
207         struct att_notify *notify = data;
208
209         if (notify->destroy)
210                 notify->destroy(notify->user_data);
211
212         free(notify);
213 }
214
215 static bool match_notify_id(const void *a, const void *b)
216 {
217         const struct att_notify *notify = a;
218         unsigned int id = PTR_TO_UINT(b);
219
220         return notify->id == id;
221 }
222
223 static bool match_notify_removed(const void *a, const void *b)
224 {
225         const struct att_notify *notify = a;
226
227         return notify->removed;
228 }
229
230 static void mark_notify_removed(void *data, void *user_data)
231 {
232         struct att_notify *notify = data;
233
234         notify->removed = true;
235 }
236
237 struct att_disconn {
238         unsigned int id;
239         bool removed;
240         bt_att_disconnect_func_t callback;
241         bt_att_destroy_func_t destroy;
242         void *user_data;
243 };
244
245 static void destroy_att_disconn(void *data)
246 {
247         struct att_disconn *disconn = data;
248
249         if (disconn->destroy)
250                 disconn->destroy(disconn->user_data);
251
252         free(disconn);
253 }
254
255 static bool match_disconn_id(const void *a, const void *b)
256 {
257         const struct att_disconn *disconn = a;
258         unsigned int id = PTR_TO_UINT(b);
259
260         return disconn->id == id;
261 }
262
263 static bool match_disconn_removed(const void *a, const void *b)
264 {
265         const struct att_disconn *disconn = a;
266
267         return disconn->removed;
268 }
269
270 static void mark_disconn_removed(void *data, void *user_data)
271 {
272         struct att_disconn *disconn = data;
273
274         disconn->removed = true;
275 }
276
277 static bool encode_pdu(struct att_send_op *op, const void *pdu,
278                                                 uint16_t length, uint16_t mtu)
279 {
280         uint16_t pdu_len = 1;
281
282         if (length && pdu)
283                 pdu_len += length;
284
285         if (pdu_len > mtu)
286                 return false;
287
288         op->len = pdu_len;
289         op->pdu = malloc(op->len);
290         if (!op->pdu)
291                 return false;
292
293         ((uint8_t *) op->pdu)[0] = op->opcode;
294         if (pdu_len > 1)
295                 memcpy(op->pdu + 1, pdu, length);
296
297         return true;
298 }
299
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,
303                                                 void *user_data,
304                                                 bt_att_destroy_func_t destroy)
305 {
306         struct att_send_op *op;
307         enum att_op_type op_type;
308
309         if (length && !pdu)
310                 return NULL;
311
312         op_type = get_op_type(opcode);
313         if (op_type == ATT_OP_TYPE_UNKNOWN)
314                 return NULL;
315
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.
319          */
320         if (callback && op_type != ATT_OP_TYPE_REQ && op_type != ATT_OP_TYPE_IND)
321                 return NULL;
322
323         /* Similarly, if the operation does elicit a response then a callback
324          * must be provided.
325          */
326         if (!callback && (op_type == ATT_OP_TYPE_REQ || op_type == ATT_OP_TYPE_IND))
327                 return NULL;
328
329         op = new0(struct att_send_op, 1);
330         if (!op)
331                 return NULL;
332
333         op->type = op_type;
334         op->opcode = opcode;
335         op->callback = callback;
336         op->destroy = destroy;
337         op->user_data = user_data;
338
339         if (!encode_pdu(op, pdu, length, mtu)) {
340                 free(op);
341                 return NULL;
342         }
343
344         return op;
345 }
346
347 static struct att_send_op *pick_next_send_op(struct bt_att *att)
348 {
349         struct att_send_op *op;
350
351         /* See if any operations are already in the write queue */
352         op = queue_pop_head(att->write_queue);
353         if (op)
354                 return op;
355
356         /* If there is no pending request, pick an operation from the
357          * request queue.
358          */
359         if (!att->pending_req) {
360                 op = queue_pop_head(att->req_queue);
361                 if (op)
362                         return op;
363         }
364
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.
367          */
368         if (!att->pending_ind) {
369                 op = queue_pop_head(att->ind_queue);
370                 if (op)
371                         return op;
372         }
373
374         return NULL;
375 }
376
377 struct timeout_data {
378         struct bt_att *att;
379         unsigned int id;
380 };
381
382 static bool timeout_cb(void *user_data)
383 {
384         struct timeout_data *timeout = user_data;
385         struct bt_att *att = timeout->att;
386         struct att_send_op *op = NULL;
387
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;
394         }
395
396         if (!op)
397                 return false;
398
399         io_destroy(att->io);
400         att->io = NULL;
401
402         util_debug(att->debug_callback, att->debug_data,
403                                 "Operation timed out: 0x%02x", op->opcode);
404
405         if (att->timeout_callback)
406                 att->timeout_callback(op->id, op->opcode, att->timeout_data);
407
408         op->timeout_id = 0;
409         destroy_att_send_op(op);
410
411         return false;
412 }
413
414 static void write_watch_destroy(void *user_data)
415 {
416         struct bt_att *att = user_data;
417
418         att->writer_active = false;
419 }
420
421 static bool can_write_data(struct io *io, void *user_data)
422 {
423         struct bt_att *att = user_data;
424         struct att_send_op *op;
425         struct timeout_data *timeout;
426         ssize_t bytes_written;
427
428         op = pick_next_send_op(att);
429         if (!op)
430                 return false;
431
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));
436                 if (op->callback)
437                         op->callback(BT_ATT_OP_ERROR_RSP, NULL, 0,
438                                                         op->user_data);
439
440                 destroy_att_send_op(op);
441                 return true;
442         }
443
444         util_debug(att->debug_callback, att->debug_data,
445                                         "ATT op 0x%02x", op->opcode);
446
447         util_hexdump('<', op->pdu, bytes_written,
448                                         att->debug_callback, att->debug_data);
449
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.
453          */
454         switch (op->type) {
455         case ATT_OP_TYPE_REQ:
456                 att->pending_req = op;
457                 break;
458         case ATT_OP_TYPE_IND:
459                 att->pending_ind = op;
460                 break;
461         default:
462                 destroy_att_send_op(op);
463                 return true;
464         }
465
466         timeout = new0(struct timeout_data, 1);
467         if (!timeout)
468                 return true;
469
470         timeout->att = att;
471         timeout->id = op->id;
472         op->timeout_id = timeout_add(ATT_TIMEOUT_INTERVAL, timeout_cb,
473                                                                 timeout, free);
474
475         /* Return true as there may be more operations ready to write. */
476         return true;
477 }
478
479 static void wakeup_writer(struct bt_att *att)
480 {
481         if (att->writer_active)
482                 return;
483
484         /* Set the write handler only if there is anything that can be sent
485          * at all.
486          */
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)))
490                         return;
491         }
492
493         if (!io_set_write_handler(att->io, can_write_data, att,
494                                                         write_watch_destroy))
495                 return;
496
497         att->writer_active = true;
498 }
499
500 static void handle_rsp(struct bt_att *att, uint8_t opcode, uint8_t *pdu,
501                                                                 ssize_t pdu_len)
502 {
503         struct att_send_op *op = att->pending_req;
504         uint8_t req_opcode;
505         uint8_t rsp_opcode;
506         uint8_t *rsp_pdu = NULL;
507         uint16_t rsp_pdu_len = 0;
508
509         /* If no request is pending, then the response is unexpected. */
510         if (!op) {
511                 wakeup_writer(att);
512                 return;
513         }
514
515         /* If the received response doesn't match the pending request, or if
516          * the request is malformed, end the current request with failure.
517          */
518         if (opcode == BT_ATT_OP_ERROR_RSP) {
519                 if (pdu_len != 4)
520                         goto fail;
521
522                 req_opcode = pdu[0];
523         } else if (!(req_opcode = get_req_opcode(opcode)))
524                 goto fail;
525
526         if (req_opcode != op->opcode)
527                 goto fail;
528
529         rsp_opcode = opcode;
530
531         if (pdu_len > 0) {
532                 rsp_pdu = pdu;
533                 rsp_pdu_len = pdu_len;
534         }
535
536         goto done;
537
538 fail:
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;
542
543 done:
544         if (op->callback)
545                 op->callback(rsp_opcode, rsp_pdu, rsp_pdu_len, op->user_data);
546
547         destroy_att_send_op(op);
548         att->pending_req = NULL;
549
550         wakeup_writer(att);
551 }
552
553 struct notify_data {
554         uint8_t opcode;
555         uint8_t *pdu;
556         ssize_t pdu_len;
557 };
558
559 static void notify_handler(void *data, void *user_data)
560 {
561         struct att_notify *notify = data;
562         struct notify_data *not_data = user_data;
563
564         if (notify->removed)
565                 return;
566
567         if (notify->opcode != not_data->opcode)
568                 return;
569
570         if (notify->callback)
571                 notify->callback(not_data->opcode, not_data->pdu,
572                                         not_data->pdu_len, notify->user_data);
573 }
574
575 static void handle_notify(struct bt_att *att, uint8_t opcode, uint8_t *pdu,
576                                                                 ssize_t pdu_len)
577 {
578         struct notify_data data;
579
580         bt_att_ref(att);
581         att->in_notify = true;
582
583         memset(&data, 0, sizeof(data));
584         data.opcode = opcode;
585
586         if (pdu_len > 0) {
587                 data.pdu = pdu;
588                 data.pdu_len = pdu_len;
589         }
590
591         queue_foreach(att->notify_list, notify_handler, &data);
592
593         att->in_notify = false;
594
595         if (att->need_notify_cleanup) {
596                 queue_remove_all(att->notify_list, match_notify_removed, NULL,
597                                                         destroy_att_notify);
598                 att->need_notify_cleanup = false;
599         }
600
601         bt_att_unref(att);
602 }
603
604 static bool can_read_data(struct io *io, void *user_data)
605 {
606         struct bt_att *att = user_data;
607         uint8_t opcode;
608         uint8_t *pdu;
609         ssize_t bytes_read;
610
611         bytes_read = read(att->fd, att->buf, att->mtu);
612         if (bytes_read < 0)
613                 return false;
614
615         util_hexdump('>', att->buf, bytes_read,
616                                         att->debug_callback, att->debug_data);
617
618         if (bytes_read < ATT_MIN_PDU_LEN)
619                 return true;
620
621         pdu = att->buf;
622         opcode = pdu[0];
623
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);
630                 break;
631         case ATT_OP_TYPE_CONF:
632                 util_debug(att->debug_callback, att->debug_data,
633                                 "ATT opcode cannot be handled: 0x%02x", opcode);
634                 break;
635         default:
636                 /* For all other opcodes notify the upper layer of the PDU and
637                  * let them act on it.
638                  */
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);
642                 break;
643         }
644
645         return true;
646 }
647
648 static void disconn_handler(void *data, void *user_data)
649 {
650         struct att_disconn *disconn = data;
651
652         if (disconn->removed)
653                 return;
654
655         if (disconn->callback)
656                 disconn->callback(disconn->user_data);
657 }
658
659 static bool disconnect_cb(struct io *io, void *user_data)
660 {
661         struct bt_att *att = user_data;
662
663         io_destroy(att->io);
664         att->io = NULL;
665
666         util_debug(att->debug_callback, att->debug_data,
667                                                 "Physical link disconnected");
668
669         bt_att_ref(att);
670         att->in_disconn = true;
671         queue_foreach(att->disconn_list, disconn_handler, NULL);
672         att->in_disconn = false;
673
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;
678         }
679
680         bt_att_cancel_all(att);
681         bt_att_unregister_all(att);
682
683         bt_att_unref(att);
684
685         return false;
686 }
687
688 struct bt_att *bt_att_new(int fd)
689 {
690         struct bt_att *att;
691
692         if (fd < 0)
693                 return NULL;
694
695         att = new0(struct bt_att, 1);
696         if (!att)
697                 return NULL;
698
699         att->fd = fd;
700
701         att->mtu = BT_ATT_DEFAULT_LE_MTU;
702         att->buf = malloc(att->mtu);
703         if (!att->buf)
704                 goto fail;
705
706         att->io = io_new(fd);
707         if (!att->io)
708                 goto fail;
709
710         att->req_queue = queue_new();
711         if (!att->req_queue)
712                 goto fail;
713
714         att->ind_queue = queue_new();
715         if (!att->ind_queue)
716                 goto fail;
717
718         att->write_queue = queue_new();
719         if (!att->write_queue)
720                 goto fail;
721
722         att->notify_list = queue_new();
723         if (!att->notify_list)
724                 goto fail;
725
726         att->disconn_list = queue_new();
727         if (!att->disconn_list)
728                 goto fail;
729
730         if (!io_set_read_handler(att->io, can_read_data, att, NULL))
731                 goto fail;
732
733         if (!io_set_disconnect_handler(att->io, disconnect_cb, att, NULL))
734                 goto fail;
735
736         return bt_att_ref(att);
737
738 fail:
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);
744         io_destroy(att->io);
745         free(att->buf);
746         free(att);
747
748         return NULL;
749 }
750
751 struct bt_att *bt_att_ref(struct bt_att *att)
752 {
753         if (!att)
754                 return NULL;
755
756         __sync_fetch_and_add(&att->ref_count, 1);
757
758         return att;
759 }
760
761 void bt_att_unref(struct bt_att *att)
762 {
763         if (!att)
764                 return;
765
766         if (__sync_sub_and_fetch(&att->ref_count, 1))
767                 return;
768
769         bt_att_unregister_all(att);
770         bt_att_cancel_all(att);
771
772         io_destroy(att->io);
773         att->io = NULL;
774
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;
784
785         if (att->timeout_destroy)
786                 att->timeout_destroy(att->timeout_data);
787
788         if (att->debug_destroy)
789                 att->debug_destroy(att->debug_data);
790
791         free(att->buf);
792         att->buf = NULL;
793
794         free(att);
795 }
796
797 bool bt_att_set_close_on_unref(struct bt_att *att, bool do_close)
798 {
799         if (!att || !att->io)
800                 return false;
801
802         return io_set_close_on_destroy(att->io, do_close);
803 }
804
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)
807 {
808         if (!att)
809                 return false;
810
811         if (att->debug_destroy)
812                 att->debug_destroy(att->debug_data);
813
814         att->debug_callback = callback;
815         att->debug_destroy = destroy;
816         att->debug_data = user_data;
817
818         return true;
819 }
820
821 uint16_t bt_att_get_mtu(struct bt_att *att)
822 {
823         if (!att)
824                 return 0;
825
826         return att->mtu;
827 }
828
829 bool bt_att_set_mtu(struct bt_att *att, uint16_t mtu)
830 {
831         void *buf;
832
833         if (!att)
834                 return false;
835
836         if (mtu < BT_ATT_DEFAULT_LE_MTU)
837                 return false;
838
839         buf = malloc(mtu);
840         if (!buf)
841                 return false;
842
843         free(att->buf);
844
845         att->mtu = mtu;
846         att->buf = buf;
847
848         return true;
849 }
850
851 bool bt_att_set_timeout_cb(struct bt_att *att, bt_att_timeout_func_t callback,
852                                                 void *user_data,
853                                                 bt_att_destroy_func_t destroy)
854 {
855         if (!att)
856                 return false;
857
858         if (att->timeout_destroy)
859                 att->timeout_destroy(att->timeout_data);
860
861         att->timeout_callback = callback;
862         att->timeout_destroy = destroy;
863         att->timeout_data = user_data;
864
865         return true;
866 }
867
868 unsigned int bt_att_register_disconnect(struct bt_att *att,
869                                         bt_att_disconnect_func_t callback,
870                                         void *user_data,
871                                         bt_att_destroy_func_t destroy)
872 {
873         struct att_disconn *disconn;
874
875         if (!att || !att->io)
876                 return 0;
877
878         disconn = new0(struct att_disconn, 1);
879         if (!disconn)
880                 return 0;
881
882         disconn->callback = callback;
883         disconn->destroy = destroy;
884         disconn->user_data = user_data;
885
886         if (att->next_reg_id < 1)
887                 att->next_reg_id = 1;
888
889         disconn->id = att->next_reg_id++;
890
891         if (!queue_push_tail(att->disconn_list, disconn)) {
892                 free(disconn);
893                 return 0;
894         }
895
896         return disconn->id;
897 }
898
899 bool bt_att_unregister_disconnect(struct bt_att *att, unsigned int id)
900 {
901         struct att_disconn *disconn;
902
903         if (!att || !id)
904                 return false;
905
906         disconn = queue_find(att->disconn_list, match_disconn_id,
907                                                         UINT_TO_PTR(id));
908         if (!disconn)
909                 return false;
910
911         if (!att->in_disconn) {
912                 queue_remove(att->disconn_list, disconn);
913                 destroy_att_disconn(disconn);
914                 return true;
915         }
916
917         disconn->removed = true;
918         att->need_disconn_cleanup = true;
919
920         return true;
921 }
922
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)
927 {
928         struct att_send_op *op;
929         bool result;
930
931         if (!att || !att->io)
932                 return 0;
933
934         op = create_att_send_op(opcode, pdu, length, att->mtu, callback,
935                                                         user_data, destroy);
936         if (!op)
937                 return 0;
938
939         if (att->next_send_id < 1)
940                 att->next_send_id = 1;
941
942         op->id = att->next_send_id++;
943
944         /* Add the op to the correct queue based on its type */
945         switch (op->type) {
946         case ATT_OP_TYPE_REQ:
947                 result = queue_push_tail(att->req_queue, op);
948                 break;
949         case ATT_OP_TYPE_IND:
950                 result = queue_push_tail(att->ind_queue, op);
951                 break;
952         default:
953                 result = queue_push_tail(att->write_queue, op);
954                 break;
955         }
956
957         if (!result) {
958                 free(op->pdu);
959                 free(op);
960                 return 0;
961         }
962
963         wakeup_writer(att);
964
965         return op->id;
966 }
967
968 static bool match_op_id(const void *a, const void *b)
969 {
970         const struct att_send_op *op = a;
971         unsigned int id = PTR_TO_UINT(b);
972
973         return op->id == id;
974 }
975
976 bool bt_att_cancel(struct bt_att *att, unsigned int id)
977 {
978         struct att_send_op *op;
979
980         if (!att || !id)
981                 return false;
982
983         if (att->pending_req && att->pending_req->id == id) {
984                 op = att->pending_req;
985                 att->pending_req = NULL;
986                 goto done;
987         }
988
989         if (att->pending_ind && att->pending_ind->id == id) {
990                 op = att->pending_ind;
991                 att->pending_ind = NULL;
992                 goto done;
993         }
994
995         op = queue_remove_if(att->req_queue, match_op_id, UINT_TO_PTR(id));
996         if (op)
997                 goto done;
998
999         op = queue_remove_if(att->ind_queue, match_op_id, UINT_TO_PTR(id));
1000         if (op)
1001                 goto done;
1002
1003         op = queue_remove_if(att->write_queue, match_op_id, UINT_TO_PTR(id));
1004         if (op)
1005                 goto done;
1006
1007         if (!op)
1008                 return false;
1009
1010 done:
1011         destroy_att_send_op(op);
1012
1013         wakeup_writer(att);
1014
1015         return true;
1016 }
1017
1018 bool bt_att_cancel_all(struct bt_att *att)
1019 {
1020         if (!att)
1021                 return false;
1022
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);
1026
1027         if (att->pending_req) {
1028                 destroy_att_send_op(att->pending_req);
1029                 att->pending_req = NULL;
1030         }
1031
1032         if (att->pending_ind) {
1033                 destroy_att_send_op(att->pending_ind);
1034                 att->pending_ind = NULL;
1035         }
1036
1037         return true;
1038 }
1039
1040 unsigned int bt_att_register(struct bt_att *att, uint8_t opcode,
1041                                                 bt_att_notify_func_t callback,
1042                                                 void *user_data,
1043                                                 bt_att_destroy_func_t destroy)
1044 {
1045         struct att_notify *notify;
1046
1047         if (!att || !opcode || !callback || !att->io)
1048                 return 0;
1049
1050         notify = new0(struct att_notify, 1);
1051         if (!notify)
1052                 return 0;
1053
1054         notify->opcode = opcode;
1055         notify->callback = callback;
1056         notify->destroy = destroy;
1057         notify->user_data = user_data;
1058
1059         if (att->next_reg_id < 1)
1060                 att->next_reg_id = 1;
1061
1062         notify->id = att->next_reg_id++;
1063
1064         if (!queue_push_tail(att->notify_list, notify)) {
1065                 free(notify);
1066                 return 0;
1067         }
1068
1069         return notify->id;
1070 }
1071
1072 bool bt_att_unregister(struct bt_att *att, unsigned int id)
1073 {
1074         struct att_notify *notify;
1075
1076         if (!att || !id)
1077                 return false;
1078
1079         notify = queue_find(att->notify_list, match_notify_id,
1080                                                         UINT_TO_PTR(id));
1081         if (!notify)
1082                 return false;
1083
1084         if (!att->in_notify) {
1085                 queue_remove(att->notify_list, notify);
1086                 destroy_att_notify(notify);
1087                 return true;
1088         }
1089
1090         notify->removed = true;
1091         att->need_notify_cleanup = true;
1092
1093         return true;
1094 }
1095
1096 bool bt_att_unregister_all(struct bt_att *att)
1097 {
1098         if (!att)
1099                 return false;
1100
1101         if (att->in_notify) {
1102                 queue_foreach(att->notify_list, mark_notify_removed, NULL);
1103                 att->need_notify_cleanup = true;
1104         } else {
1105                 queue_remove_all(att->notify_list, NULL, NULL,
1106                                                         destroy_att_notify);
1107         }
1108
1109         if (att->in_disconn) {
1110                 queue_foreach(att->disconn_list, mark_disconn_removed, NULL);
1111                 att->need_disconn_cleanup = true;
1112         } else {
1113                 queue_remove_all(att->disconn_list, NULL, NULL,
1114                                                         destroy_att_disconn);
1115         }
1116
1117         return true;
1118 }