Upgrade bluez5_37 :Merge the code from private
[platform/upstream/bluez.git] / src / shared / gatt-server.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 <sys/uio.h>
29 #include <errno.h>
30
31 #include "src/shared/att.h"
32 #include "lib/bluetooth.h"
33 #include "lib/uuid.h"
34 #include "src/shared/queue.h"
35 #include "src/shared/gatt-db.h"
36 #include "src/shared/gatt-server.h"
37 #include "src/shared/gatt-helpers.h"
38 #include "src/shared/util.h"
39
40 #ifndef MAX
41 #define MAX(a, b) ((a) > (b) ? (a) : (b))
42 #endif
43
44 #ifndef MIN
45 #define MIN(a, b) ((a) < (b) ? (a) : (b))
46 #endif
47
48 /*
49  * TODO: This is an arbitrary limit. Come up with something reasonable or
50  * perhaps an API to set this value if there is a use case for it.
51  */
52 #define DEFAULT_MAX_PREP_QUEUE_LEN 30
53
54 struct async_read_op {
55         struct bt_gatt_server *server;
56         uint8_t opcode;
57         bool done;
58         uint8_t *pdu;
59         size_t pdu_len;
60         size_t value_len;
61         struct queue *db_data;
62 };
63
64 struct async_write_op {
65         struct bt_gatt_server *server;
66         uint8_t opcode;
67 };
68
69 struct prep_write_data {
70         struct bt_gatt_server *server;
71         uint8_t *value;
72         uint16_t handle;
73         uint16_t offset;
74         uint16_t length;
75 };
76
77 static void prep_write_data_destroy(void *user_data)
78 {
79         struct prep_write_data *data = user_data;
80
81         free(data->value);
82         free(data);
83 }
84
85 struct bt_gatt_server {
86         struct gatt_db *db;
87         struct bt_att *att;
88         int ref_count;
89         uint16_t mtu;
90
91         unsigned int mtu_id;
92         unsigned int read_by_grp_type_id;
93         unsigned int read_by_type_id;
94         unsigned int find_info_id;
95         unsigned int find_by_type_value_id;
96         unsigned int write_id;
97         unsigned int write_cmd_id;
98         unsigned int read_id;
99         unsigned int read_blob_id;
100         unsigned int read_multiple_id;
101         unsigned int prep_write_id;
102         unsigned int exec_write_id;
103
104         struct queue *prep_queue;
105         unsigned int max_prep_queue_len;
106
107         struct async_read_op *pending_read_op;
108         struct async_write_op *pending_write_op;
109
110         bt_gatt_server_debug_func_t debug_callback;
111         bt_gatt_server_destroy_func_t debug_destroy;
112         void *debug_data;
113 };
114
115 static void bt_gatt_server_free(struct bt_gatt_server *server)
116 {
117         if (server->debug_destroy)
118                 server->debug_destroy(server->debug_data);
119
120         bt_att_unregister(server->att, server->mtu_id);
121         bt_att_unregister(server->att, server->read_by_grp_type_id);
122         bt_att_unregister(server->att, server->read_by_type_id);
123         bt_att_unregister(server->att, server->find_info_id);
124         bt_att_unregister(server->att, server->find_by_type_value_id);
125         bt_att_unregister(server->att, server->write_id);
126         bt_att_unregister(server->att, server->write_cmd_id);
127         bt_att_unregister(server->att, server->read_id);
128         bt_att_unregister(server->att, server->read_blob_id);
129         bt_att_unregister(server->att, server->read_multiple_id);
130         bt_att_unregister(server->att, server->prep_write_id);
131         bt_att_unregister(server->att, server->exec_write_id);
132
133         if (server->pending_read_op)
134                 server->pending_read_op->server = NULL;
135
136         if (server->pending_write_op)
137                 server->pending_write_op->server = NULL;
138
139         queue_destroy(server->prep_queue, prep_write_data_destroy);
140
141         gatt_db_unref(server->db);
142         bt_att_unref(server->att);
143         free(server);
144 }
145
146 static bool get_uuid_le(const uint8_t *uuid, size_t len, bt_uuid_t *out_uuid)
147 {
148         uint128_t u128;
149
150         switch (len) {
151         case 2:
152                 bt_uuid16_create(out_uuid, get_le16(uuid));
153                 return true;
154         case 16:
155                 bswap_128(uuid, &u128.data);
156                 bt_uuid128_create(out_uuid, u128);
157                 return true;
158         default:
159                 return false;
160         }
161
162         return false;
163 }
164
165 static void attribute_read_cb(struct gatt_db_attribute *attrib, int err,
166                                         const uint8_t *value, size_t length,
167                                         void *user_data)
168 {
169         struct iovec *iov = user_data;
170
171         iov->iov_base = (void *) value;
172         iov->iov_len = length;
173 }
174
175 static bool encode_read_by_grp_type_rsp(struct gatt_db *db, struct queue *q,
176                                                 struct bt_att *att,
177                                                 uint16_t mtu, uint8_t *pdu,
178                                                 uint16_t *len)
179 {
180         int iter = 0;
181         uint16_t start_handle, end_handle;
182         struct iovec value;
183         uint8_t data_val_len;
184
185         *len = 0;
186
187         while (queue_peek_head(q)) {
188                 struct gatt_db_attribute *attrib = queue_pop_head(q);
189
190                 value.iov_base = NULL;
191                 value.iov_len = 0;
192
193                 /*
194                  * This should never be deferred to the read callback for
195                  * primary/secondary service declarations.
196                  */
197                 if (!gatt_db_attribute_read(attrib, 0,
198                                                 BT_ATT_OP_READ_BY_GRP_TYPE_REQ,
199                                                 att, attribute_read_cb,
200                                                 &value) || !value.iov_len)
201                         return false;
202
203                 /*
204                  * Use the first attribute to determine the length of each
205                  * attribute data unit. Stop the list when a different attribute
206                  * value is seen.
207                  */
208                 if (iter == 0) {
209                         data_val_len = MIN(MIN((unsigned)mtu - 6, 251),
210                                                                 value.iov_len);
211                         pdu[0] = data_val_len + 4;
212                         iter++;
213                 } else if (value.iov_len != data_val_len)
214                         break;
215
216                 /* Stop if this unit would surpass the MTU */
217                 if (iter + data_val_len + 4 > mtu - 1)
218                         break;
219
220                 gatt_db_attribute_get_service_handles(attrib, &start_handle,
221                                                                 &end_handle);
222
223                 put_le16(start_handle, pdu + iter);
224                 put_le16(end_handle, pdu + iter + 2);
225                 memcpy(pdu + iter + 4, value.iov_base, data_val_len);
226
227                 iter += data_val_len + 4;
228         }
229
230         *len = iter;
231
232         return true;
233 }
234
235 static void read_by_grp_type_cb(uint8_t opcode, const void *pdu,
236                                         uint16_t length, void *user_data)
237 {
238         struct bt_gatt_server *server = user_data;
239         uint16_t start, end;
240         bt_uuid_t type;
241         bt_uuid_t prim, snd;
242         uint16_t mtu = bt_att_get_mtu(server->att);
243         uint8_t rsp_pdu[mtu];
244         uint16_t rsp_len;
245         uint8_t ecode = 0;
246         uint16_t ehandle = 0;
247         struct queue *q = NULL;
248
249         if (length != 6 && length != 20) {
250                 ecode = BT_ATT_ERROR_INVALID_PDU;
251                 goto error;
252         }
253
254         q = queue_new();
255
256         start = get_le16(pdu);
257         end = get_le16(pdu + 2);
258         get_uuid_le(pdu + 4, length - 4, &type);
259
260         util_debug(server->debug_callback, server->debug_data,
261                                 "Read By Grp Type - start: 0x%04x end: 0x%04x",
262                                 start, end);
263
264         if (!start || !end) {
265                 ecode = BT_ATT_ERROR_INVALID_HANDLE;
266                 goto error;
267         }
268
269         ehandle = start;
270
271         if (start > end) {
272                 ecode = BT_ATT_ERROR_INVALID_HANDLE;
273                 goto error;
274         }
275
276         /*
277          * GATT defines that only the <<Primary Service>> and
278          * <<Secondary Service>> group types can be used for the
279          * "Read By Group Type" request (Core v4.1, Vol 3, sec 2.5.3). Return an
280          * error if any other group type is given.
281          */
282         bt_uuid16_create(&prim, GATT_PRIM_SVC_UUID);
283         bt_uuid16_create(&snd, GATT_SND_SVC_UUID);
284         if (bt_uuid_cmp(&type, &prim) && bt_uuid_cmp(&type, &snd)) {
285                 ecode = BT_ATT_ERROR_UNSUPPORTED_GROUP_TYPE;
286                 goto error;
287         }
288
289         gatt_db_read_by_group_type(server->db, start, end, type, q);
290
291         if (queue_isempty(q)) {
292                 ecode = BT_ATT_ERROR_ATTRIBUTE_NOT_FOUND;
293                 goto error;
294         }
295
296         if (!encode_read_by_grp_type_rsp(server->db, q, server->att, mtu,
297                                                         rsp_pdu, &rsp_len)) {
298                 ecode = BT_ATT_ERROR_UNLIKELY;
299                 goto error;
300         }
301
302         queue_destroy(q, NULL);
303
304         bt_att_send(server->att, BT_ATT_OP_READ_BY_GRP_TYPE_RSP,
305                                                         rsp_pdu, rsp_len,
306                                                         NULL, NULL, NULL);
307
308         return;
309
310 error:
311         queue_destroy(q, NULL);
312         bt_att_send_error_rsp(server->att, opcode, ehandle, ecode);
313 }
314
315 static void async_read_op_destroy(struct async_read_op *op)
316 {
317         if (op->server)
318                 op->server->pending_read_op = NULL;
319
320         queue_destroy(op->db_data, NULL);
321         free(op->pdu);
322         free(op);
323 }
324
325 static void process_read_by_type(struct async_read_op *op);
326
327 static void read_by_type_read_complete_cb(struct gatt_db_attribute *attr,
328                                                 int err, const uint8_t *value,
329                                                 size_t len, void *user_data)
330 {
331         struct async_read_op *op = user_data;
332         struct bt_gatt_server *server = op->server;
333         uint16_t mtu;
334         uint16_t handle;
335
336         if (!server) {
337                 async_read_op_destroy(op);
338                 return;
339         }
340
341         mtu = bt_att_get_mtu(server->att);
342         handle = gatt_db_attribute_get_handle(attr);
343
344         /* Terminate the operation if there was an error */
345         if (err) {
346                 bt_att_send_error_rsp(server->att, BT_ATT_OP_READ_BY_TYPE_REQ,
347                                                                 handle, err);
348                 async_read_op_destroy(op);
349                 return;
350         }
351
352         if (op->pdu_len == 0) {
353                 op->value_len = MIN(MIN((unsigned) mtu - 4, 253), len);
354                 op->pdu[0] = op->value_len + 2;
355                 op->pdu_len++;
356         } else if (len != op->value_len) {
357                 op->done = true;
358                 goto done;
359         }
360
361         /* Stop if this would surpass the MTU */
362         if (op->pdu_len + op->value_len + 2 > (unsigned) mtu - 1) {
363                 op->done = true;
364                 goto done;
365         }
366
367         /* Encode the current value */
368         put_le16(handle, op->pdu + op->pdu_len);
369         memcpy(op->pdu + op->pdu_len + 2, value, op->value_len);
370
371         op->pdu_len += op->value_len + 2;
372
373         if (op->pdu_len == (unsigned) mtu - 1)
374                 op->done = true;
375
376 done:
377         process_read_by_type(op);
378 }
379
380 static uint8_t check_permissions(struct bt_gatt_server *server,
381                                 struct gatt_db_attribute *attr, uint32_t mask)
382 {
383         uint32_t perm;
384         int security;
385
386         perm = gatt_db_attribute_get_permissions(attr);
387
388         if (perm && mask & BT_ATT_PERM_READ && !(perm & BT_ATT_PERM_READ))
389                 return BT_ATT_ERROR_READ_NOT_PERMITTED;
390
391         if (perm && mask & BT_ATT_PERM_WRITE && !(perm & BT_ATT_PERM_WRITE))
392                 return BT_ATT_ERROR_WRITE_NOT_PERMITTED;
393
394         perm &= mask;
395         if (!perm)
396                 return 0;
397
398         security = bt_att_get_security(server->att);
399         if (perm & BT_ATT_PERM_AUTHEN && security < BT_ATT_SECURITY_HIGH)
400                 return BT_ATT_ERROR_AUTHENTICATION;
401
402         if (perm & BT_ATT_PERM_ENCRYPT && security < BT_ATT_SECURITY_MEDIUM)
403                 return BT_ATT_ERROR_INSUFFICIENT_ENCRYPTION;
404
405         return 0;
406 }
407
408 static void process_read_by_type(struct async_read_op *op)
409 {
410         struct bt_gatt_server *server = op->server;
411         uint8_t ecode;
412         struct gatt_db_attribute *attr;
413
414         attr = queue_pop_head(op->db_data);
415
416         if (op->done || !attr) {
417                 bt_att_send(server->att, BT_ATT_OP_READ_BY_TYPE_RSP, op->pdu,
418                                                                 op->pdu_len,
419                                                                 NULL, NULL,
420                                                                 NULL);
421                 async_read_op_destroy(op);
422                 return;
423         }
424
425         ecode = check_permissions(server, attr, BT_ATT_PERM_READ |
426                                                 BT_ATT_PERM_READ_AUTHEN |
427                                                 BT_ATT_PERM_READ_ENCRYPT);
428         if (ecode)
429                 goto error;
430
431         if (gatt_db_attribute_read(attr, 0, op->opcode, server->att,
432                                         read_by_type_read_complete_cb, op))
433                 return;
434
435         ecode = BT_ATT_ERROR_UNLIKELY;
436
437 error:
438         bt_att_send_error_rsp(server->att, BT_ATT_OP_READ_BY_TYPE_REQ,
439                                 gatt_db_attribute_get_handle(attr), ecode);
440         async_read_op_destroy(op);
441 }
442
443 static void read_by_type_cb(uint8_t opcode, const void *pdu,
444                                         uint16_t length, void *user_data)
445 {
446         struct bt_gatt_server *server = user_data;
447         uint16_t start, end;
448         bt_uuid_t type;
449         uint16_t ehandle = 0;
450         uint8_t ecode;
451         struct queue *q = NULL;
452         struct async_read_op *op;
453
454         if (length != 6 && length != 20) {
455                 ecode = BT_ATT_ERROR_INVALID_PDU;
456                 goto error;
457         }
458
459         q = queue_new();
460
461         start = get_le16(pdu);
462         end = get_le16(pdu + 2);
463         get_uuid_le(pdu + 4, length - 4, &type);
464
465         util_debug(server->debug_callback, server->debug_data,
466                                 "Read By Type - start: 0x%04x end: 0x%04x",
467                                 start, end);
468
469         if (!start || !end) {
470                 ecode = BT_ATT_ERROR_INVALID_HANDLE;
471                 goto error;
472         }
473
474         ehandle = start;
475
476         if (start > end) {
477                 ecode = BT_ATT_ERROR_INVALID_HANDLE;
478                 goto error;
479         }
480
481         gatt_db_read_by_type(server->db, start, end, type, q);
482
483         if (queue_isempty(q)) {
484                 ecode = BT_ATT_ERROR_ATTRIBUTE_NOT_FOUND;
485                 goto error;
486         }
487
488         if (server->pending_read_op) {
489                 ecode = BT_ATT_ERROR_UNLIKELY;
490                 goto error;
491         }
492
493         op = new0(struct async_read_op, 1);
494         op->pdu = malloc(bt_att_get_mtu(server->att));
495         if (!op->pdu) {
496                 free(op);
497                 ecode = BT_ATT_ERROR_INSUFFICIENT_RESOURCES;
498                 goto error;
499         }
500
501         op->opcode = opcode;
502         op->server = server;
503         op->db_data = q;
504         server->pending_read_op = op;
505
506         process_read_by_type(op);
507
508         return;
509
510 error:
511         bt_att_send_error_rsp(server->att, opcode, ehandle, ecode);
512         queue_destroy(q, NULL);
513 }
514
515 static bool encode_find_info_rsp(struct gatt_db *db, struct queue *q,
516                                                 uint16_t mtu,
517                                                 uint8_t *pdu, uint16_t *len)
518 {
519         uint16_t handle;
520         struct gatt_db_attribute *attr;
521         const bt_uuid_t *type;
522         int uuid_len, cur_uuid_len;
523         int iter = 0;
524
525         *len = 0;
526
527         while (queue_peek_head(q)) {
528                 attr = queue_pop_head(q);
529                 handle = gatt_db_attribute_get_handle(attr);
530                 type = gatt_db_attribute_get_type(attr);
531                 if (!handle || !type)
532                         return false;
533
534                 cur_uuid_len = bt_uuid_len(type);
535
536                 if (iter == 0) {
537                         switch (cur_uuid_len) {
538                         case 2:
539                                 uuid_len = 2;
540                                 pdu[0] = 0x01;
541                                 break;
542                         case 4:
543                         case 16:
544                                 uuid_len = 16;
545                                 pdu[0] = 0x02;
546                                 break;
547                         default:
548                                 return false;
549                         }
550
551                         iter++;
552                 } else if (cur_uuid_len != uuid_len)
553                         break;
554
555                 if (iter + uuid_len + 2 > mtu - 1)
556                         break;
557
558                 put_le16(handle, pdu + iter);
559                 bt_uuid_to_le(type, pdu + iter + 2);
560
561                 iter += uuid_len + 2;
562         }
563
564         *len = iter;
565
566         return true;
567 }
568
569 static void find_info_cb(uint8_t opcode, const void *pdu,
570                                         uint16_t length, void *user_data)
571 {
572         struct bt_gatt_server *server = user_data;
573         uint16_t start, end;
574         uint16_t mtu = bt_att_get_mtu(server->att);
575         uint8_t rsp_pdu[mtu];
576         uint16_t rsp_len;
577         uint8_t ecode = 0;
578         uint16_t ehandle = 0;
579         struct queue *q = NULL;
580
581         if (length != 4) {
582                 ecode = BT_ATT_ERROR_INVALID_PDU;
583                 goto error;
584         }
585
586         q = queue_new();
587
588         start = get_le16(pdu);
589         end = get_le16(pdu + 2);
590
591         util_debug(server->debug_callback, server->debug_data,
592                                         "Find Info - start: 0x%04x end: 0x%04x",
593                                         start, end);
594
595         if (!start || !end) {
596                 ecode = BT_ATT_ERROR_INVALID_HANDLE;
597                 goto error;
598         }
599
600         ehandle = start;
601
602         if (start > end) {
603                 ecode = BT_ATT_ERROR_INVALID_HANDLE;
604                 goto error;
605         }
606
607         gatt_db_find_information(server->db, start, end, q);
608
609         if (queue_isempty(q)) {
610                 ecode = BT_ATT_ERROR_ATTRIBUTE_NOT_FOUND;
611                 goto error;
612         }
613
614         if (!encode_find_info_rsp(server->db, q, mtu, rsp_pdu, &rsp_len)) {
615                 ecode = BT_ATT_ERROR_UNLIKELY;
616                 goto error;
617         }
618
619         bt_att_send(server->att, BT_ATT_OP_FIND_INFO_RSP, rsp_pdu, rsp_len,
620                                                         NULL, NULL, NULL);
621         queue_destroy(q, NULL);
622
623         return;
624
625 error:
626         bt_att_send_error_rsp(server->att, opcode, ehandle, ecode);
627         queue_destroy(q, NULL);
628
629 }
630
631 struct find_by_type_val_data {
632         uint8_t *pdu;
633         uint16_t len;
634         uint16_t mtu;
635         uint8_t ecode;
636 };
637
638 static void find_by_type_val_att_cb(struct gatt_db_attribute *attrib,
639                                                                 void *user_data)
640 {
641         uint16_t handle, end_handle;
642         struct find_by_type_val_data *data = user_data;
643
644         if (data->ecode)
645                 return;
646
647         if (data->len + 4 > data->mtu - 1)
648                 return;
649
650         /*
651          * This OP is only valid for Primary Service per the spec
652          * page 562, so this should work.
653          */
654         gatt_db_attribute_get_service_data(attrib, &handle, &end_handle, NULL,
655                                                                         NULL);
656
657         if (!handle || !end_handle) {
658                 data->ecode = BT_ATT_ERROR_UNLIKELY;
659                 return;
660         }
661
662         put_le16(handle, data->pdu + data->len);
663         put_le16(end_handle, data->pdu + data->len + 2);
664
665         data->len += 4;
666 }
667
668 static void find_by_type_val_cb(uint8_t opcode, const void *pdu,
669                                         uint16_t length, void *user_data)
670 {
671         struct bt_gatt_server *server = user_data;
672         uint16_t start, end, uuid16;
673         struct find_by_type_val_data data;
674         uint16_t mtu = bt_att_get_mtu(server->att);
675         uint8_t rsp_pdu[mtu];
676         uint16_t ehandle = 0;
677         bt_uuid_t uuid;
678
679         if (length < 6) {
680                 data.ecode = BT_ATT_ERROR_INVALID_PDU;
681                 goto error;
682         }
683
684         data.pdu = rsp_pdu;
685         data.len = 0;
686         data.mtu = mtu;
687         data.ecode = 0;
688
689         start = get_le16(pdu);
690         end = get_le16(pdu + 2);
691         uuid16 = get_le16(pdu + 4);
692
693         util_debug(server->debug_callback, server->debug_data,
694                         "Find By Type Value - start: 0x%04x end: 0x%04x uuid: 0x%04x",
695                         start, end, uuid16);
696         ehandle = start;
697         if (start > end) {
698                 data.ecode = BT_ATT_ERROR_INVALID_HANDLE;
699                 goto error;
700         }
701
702         bt_uuid16_create(&uuid, uuid16);
703         gatt_db_find_by_type_value(server->db, start, end, &uuid, pdu + 6,
704                                                         length - 6,
705                                                         find_by_type_val_att_cb,
706                                                         &data);
707
708         if (!data.len)
709                 data.ecode = BT_ATT_ERROR_ATTRIBUTE_NOT_FOUND;
710
711         if (data.ecode)
712                 goto error;
713
714         bt_att_send(server->att, BT_ATT_OP_FIND_BY_TYPE_RSP, data.pdu,
715                                                 data.len, NULL, NULL, NULL);
716
717         return;
718
719 error:
720         bt_att_send_error_rsp(server->att, opcode, ehandle, data.ecode);
721 }
722
723 static void async_write_op_destroy(struct async_write_op *op)
724 {
725         if (op->server)
726                 op->server->pending_write_op = NULL;
727
728         free(op);
729 }
730
731 static void write_complete_cb(struct gatt_db_attribute *attr, int err,
732                                                                 void *user_data)
733 {
734         struct async_write_op *op = user_data;
735         struct bt_gatt_server *server = op->server;
736         uint16_t handle;
737
738         if (!server || op->opcode == BT_ATT_OP_WRITE_CMD) {
739                 async_write_op_destroy(op);
740                 return;
741         }
742
743         handle = gatt_db_attribute_get_handle(attr);
744
745         if (err)
746                 bt_att_send_error_rsp(server->att, op->opcode, handle, err);
747         else
748                 bt_att_send(server->att, BT_ATT_OP_WRITE_RSP, NULL, 0,
749                                                         NULL, NULL, NULL);
750
751         async_write_op_destroy(op);
752 }
753
754 static void write_cb(uint8_t opcode, const void *pdu,
755                                         uint16_t length, void *user_data)
756 {
757         struct bt_gatt_server *server = user_data;
758         struct gatt_db_attribute *attr;
759         uint16_t handle = 0;
760         struct async_write_op *op = NULL;
761         uint8_t ecode;
762
763         if (length < 2) {
764                 ecode = BT_ATT_ERROR_INVALID_PDU;
765                 goto error;
766         }
767
768         handle = get_le16(pdu);
769         attr = gatt_db_get_attribute(server->db, handle);
770         if (!attr) {
771                 ecode = BT_ATT_ERROR_INVALID_HANDLE;
772                 goto error;
773         }
774
775         util_debug(server->debug_callback, server->debug_data,
776                                 "Write %s - handle: 0x%04x",
777                                 (opcode == BT_ATT_OP_WRITE_REQ) ? "Req" : "Cmd",
778                                 handle);
779
780         ecode = check_permissions(server, attr, BT_ATT_PERM_WRITE |
781                                                 BT_ATT_PERM_WRITE_AUTHEN |
782                                                 BT_ATT_PERM_WRITE_ENCRYPT);
783         if (ecode)
784                 goto error;
785
786         if (server->pending_write_op) {
787 #ifdef __TIZEN_PATCH__
788                 if (opcode != BT_ATT_OP_WRITE_CMD) {
789 #endif
790                 ecode = BT_ATT_ERROR_UNLIKELY;
791                 goto error;
792 #ifdef __TIZEN_PATCH__
793                 }
794 #endif
795         }
796
797         op = new0(struct async_write_op, 1);
798         op->server = server;
799         op->opcode = opcode;
800
801 #ifdef __TIZEN_PATCH__
802         if (opcode != BT_ATT_OP_WRITE_CMD)
803                 server->pending_write_op = op;
804 #else
805         server->pending_write_op = op;
806 #endif
807
808         if (gatt_db_attribute_write(attr, 0, pdu + 2, length - 2, opcode,
809                                                         server->att,
810                                                         write_complete_cb, op))
811                 return;
812
813         if (op)
814                 async_write_op_destroy(op);
815
816         ecode = BT_ATT_ERROR_UNLIKELY;
817
818 error:
819 #ifdef __TIZEN_PATCH__
820         util_debug(server->debug_callback, server->debug_data,
821                                 "Handling \"Write %s\" is failed : %d",
822                                 (opcode == BT_ATT_OP_WRITE_REQ) ? "Req" : "Cmd",
823                                 ecode);
824 #endif
825
826         if (opcode == BT_ATT_OP_WRITE_CMD)
827                 return;
828
829         bt_att_send_error_rsp(server->att, opcode, handle, ecode);
830 }
831
832 static uint8_t get_read_rsp_opcode(uint8_t opcode)
833 {
834
835         switch (opcode) {
836         case BT_ATT_OP_READ_REQ:
837                 return BT_ATT_OP_READ_RSP;
838         case BT_ATT_OP_READ_BLOB_REQ:
839                 return BT_ATT_OP_READ_BLOB_RSP;
840         default:
841                 /*
842                  * Should never happen
843                  *
844                  * TODO: It would be nice to have a debug-mode assert macro
845                  * for development builds. This way bugs could be easily catched
846                  * during development and there would be self documenting code
847                  * that wouldn't be crash release builds.
848                  */
849                 return 0;
850         }
851
852         return 0;
853 }
854
855 static void read_complete_cb(struct gatt_db_attribute *attr, int err,
856                                         const uint8_t *value, size_t len,
857                                         void *user_data)
858 {
859         struct async_read_op *op = user_data;
860         struct bt_gatt_server *server = op->server;
861         uint8_t rsp_opcode;
862         uint16_t mtu;
863         uint16_t handle;
864
865         if (!server) {
866                 async_read_op_destroy(op);
867                 return;
868         }
869
870         mtu = bt_att_get_mtu(server->att);
871         handle = gatt_db_attribute_get_handle(attr);
872
873         if (err) {
874                 bt_att_send_error_rsp(server->att, op->opcode, handle, err);
875                 async_read_op_destroy(op);
876                 return;
877         }
878
879         rsp_opcode = get_read_rsp_opcode(op->opcode);
880
881         bt_att_send(server->att, rsp_opcode, len ? value : NULL,
882                                                 MIN((unsigned) mtu - 1, len),
883                                                 NULL, NULL, NULL);
884         async_read_op_destroy(op);
885 }
886
887 static void handle_read_req(struct bt_gatt_server *server, uint8_t opcode,
888                                                                 uint16_t handle,
889                                                                 uint16_t offset)
890 {
891         struct gatt_db_attribute *attr;
892         uint8_t ecode;
893         struct async_read_op *op = NULL;
894
895         attr = gatt_db_get_attribute(server->db, handle);
896         if (!attr) {
897                 ecode = BT_ATT_ERROR_INVALID_HANDLE;
898                 goto error;
899         }
900
901         util_debug(server->debug_callback, server->debug_data,
902                         "Read %sReq - handle: 0x%04x",
903                         opcode == BT_ATT_OP_READ_BLOB_REQ ? "Blob " : "",
904                         handle);
905
906         ecode = check_permissions(server, attr, BT_ATT_PERM_READ |
907                                                 BT_ATT_PERM_READ_AUTHEN |
908                                                 BT_ATT_PERM_READ_ENCRYPT);
909         if (ecode)
910                 goto error;
911
912         if (server->pending_read_op) {
913                 ecode = BT_ATT_ERROR_UNLIKELY;
914                 goto error;
915         }
916
917         op = new0(struct async_read_op, 1);
918         op->opcode = opcode;
919         op->server = server;
920         server->pending_read_op = op;
921
922         if (gatt_db_attribute_read(attr, offset, opcode, server->att,
923                                                         read_complete_cb, op))
924                 return;
925
926         ecode = BT_ATT_ERROR_UNLIKELY;
927
928 error:
929         if (op)
930                 async_read_op_destroy(op);
931
932         bt_att_send_error_rsp(server->att, opcode, handle, ecode);
933 }
934
935 static void read_cb(uint8_t opcode, const void *pdu,
936                                         uint16_t length, void *user_data)
937 {
938         struct bt_gatt_server *server = user_data;
939         uint16_t handle;
940
941         if (length != 2) {
942                 bt_att_send_error_rsp(server->att, opcode, 0,
943                                                 BT_ATT_ERROR_INVALID_PDU);
944                 return;
945         }
946
947         handle = get_le16(pdu);
948
949         handle_read_req(server, opcode, handle, 0);
950 }
951
952 static void read_blob_cb(uint8_t opcode, const void *pdu,
953                                         uint16_t length, void *user_data)
954 {
955         struct bt_gatt_server *server = user_data;
956         uint16_t handle, offset;
957
958         if (length != 4) {
959                 bt_att_send_error_rsp(server->att, opcode, 0,
960                                                 BT_ATT_ERROR_INVALID_PDU);
961                 return;
962         }
963
964         handle = get_le16(pdu);
965         offset = get_le16(pdu + 2);
966
967         handle_read_req(server, opcode, handle, offset);
968 }
969
970 struct read_multiple_resp_data {
971         struct bt_gatt_server *server;
972         uint16_t *handles;
973         size_t cur_handle;
974         size_t num_handles;
975         uint8_t *rsp_data;
976         size_t length;
977         size_t mtu;
978 };
979
980 static void read_multiple_resp_data_free(struct read_multiple_resp_data *data)
981 {
982         free(data->handles);
983         data->handles = NULL;
984
985         free(data->rsp_data);
986         data->rsp_data = NULL;
987 }
988
989 static void read_multiple_complete_cb(struct gatt_db_attribute *attr, int err,
990                                         const uint8_t *value, size_t len,
991                                         void *user_data)
992 {
993         struct read_multiple_resp_data *data = user_data;
994         struct gatt_db_attribute *next_attr;
995         uint16_t handle = gatt_db_attribute_get_handle(attr);
996         uint8_t ecode;
997
998         if (err != 0) {
999                 bt_att_send_error_rsp(data->server->att,
1000                                         BT_ATT_OP_READ_MULT_REQ, handle, err);
1001                 read_multiple_resp_data_free(data);
1002                 return;
1003         }
1004
1005         ecode = check_permissions(data->server, attr, BT_ATT_PERM_READ |
1006                                                 BT_ATT_PERM_READ_AUTHEN |
1007                                                 BT_ATT_PERM_READ_ENCRYPT);
1008         if (ecode) {
1009                 bt_att_send_error_rsp(data->server->att,
1010                                         BT_ATT_OP_READ_MULT_REQ, handle, ecode);
1011                 read_multiple_resp_data_free(data);
1012                 return;
1013         }
1014
1015         len = MIN(len, data->mtu - data->length - 1);
1016
1017         memcpy(data->rsp_data + data->length, value, len);
1018         data->length += len;
1019
1020         data->cur_handle++;
1021
1022         if ((data->length >= data->mtu - 1) ||
1023                                 (data->cur_handle == data->num_handles)) {
1024                 bt_att_send(data->server->att, BT_ATT_OP_READ_MULT_RSP,
1025                                 data->rsp_data, data->length, NULL, NULL, NULL);
1026                 read_multiple_resp_data_free(data);
1027                 return;
1028         }
1029
1030         util_debug(data->server->debug_callback, data->server->debug_data,
1031                                 "Read Multiple Req - #%zu of %zu: 0x%04x",
1032                                 data->cur_handle + 1, data->num_handles,
1033                                 data->handles[data->cur_handle]);
1034
1035         next_attr = gatt_db_get_attribute(data->server->db,
1036                                         data->handles[data->cur_handle]);
1037
1038         if (!next_attr) {
1039                 bt_att_send_error_rsp(data->server->att,
1040                                         BT_ATT_OP_READ_MULT_REQ,
1041                                         data->handles[data->cur_handle],
1042                                         BT_ATT_ERROR_INVALID_HANDLE);
1043                 read_multiple_resp_data_free(data);
1044                 return;
1045         }
1046
1047         if (!gatt_db_attribute_read(next_attr, 0, BT_ATT_OP_READ_MULT_REQ,
1048                                         data->server->att,
1049                                         read_multiple_complete_cb, data)) {
1050                 bt_att_send_error_rsp(data->server->att,
1051                                                 BT_ATT_OP_READ_MULT_REQ,
1052                                                 data->handles[data->cur_handle],
1053                                                 BT_ATT_ERROR_UNLIKELY);
1054                 read_multiple_resp_data_free(data);
1055         }
1056 }
1057
1058 static void read_multiple_cb(uint8_t opcode, const void *pdu,
1059                                         uint16_t length, void *user_data)
1060 {
1061         struct bt_gatt_server *server = user_data;
1062         struct gatt_db_attribute *attr;
1063         struct read_multiple_resp_data data;
1064         uint8_t ecode = BT_ATT_ERROR_UNLIKELY;
1065         size_t i = 0;
1066
1067         data.handles = NULL;
1068         data.rsp_data = NULL;
1069
1070         if (length < 4) {
1071                 ecode = BT_ATT_ERROR_INVALID_PDU;
1072                 goto error;
1073         }
1074
1075         data.server = server;
1076         data.num_handles = length / 2;
1077         data.cur_handle = 0;
1078         data.mtu = bt_att_get_mtu(server->att);
1079         data.length = 0;
1080         data.rsp_data = malloc(data.mtu - 1);
1081
1082         if (!data.rsp_data)
1083                 goto error;
1084
1085         data.handles = new0(uint16_t, data.num_handles);
1086
1087         for (i = 0; i < data.num_handles; i++)
1088                 data.handles[i] = get_le16(pdu + i * 2);
1089
1090         util_debug(server->debug_callback, server->debug_data,
1091                         "Read Multiple Req - %zu handles, 1st: 0x%04x",
1092                         data.num_handles, data.handles[0]);
1093
1094         attr = gatt_db_get_attribute(server->db, data.handles[0]);
1095
1096         if (!attr) {
1097                 ecode = BT_ATT_ERROR_INVALID_HANDLE;
1098                 goto error;
1099         }
1100
1101         if (gatt_db_attribute_read(attr, 0, opcode, server->att,
1102                                         read_multiple_complete_cb, &data))
1103                 return;
1104
1105 error:
1106         read_multiple_resp_data_free(&data);
1107         bt_att_send_error_rsp(server->att, opcode, 0, ecode);
1108 }
1109
1110 static void prep_write_cb(uint8_t opcode, const void *pdu,
1111                                         uint16_t length, void *user_data)
1112 {
1113         struct bt_gatt_server *server = user_data;
1114         struct prep_write_data *prep_data = NULL;
1115         uint16_t handle = 0;
1116         uint16_t offset;
1117         struct gatt_db_attribute *attr;
1118         uint8_t ecode;
1119
1120         if (length < 4) {
1121                 ecode = BT_ATT_ERROR_INVALID_PDU;
1122                 goto error;
1123         }
1124
1125         if (queue_length(server->prep_queue) >= server->max_prep_queue_len) {
1126                 ecode = BT_ATT_ERROR_PREPARE_QUEUE_FULL;
1127                 goto error;
1128         }
1129
1130         handle = get_le16(pdu);
1131         offset = get_le16(pdu + 2);
1132
1133         attr = gatt_db_get_attribute(server->db, handle);
1134         if (!attr) {
1135                 ecode = BT_ATT_ERROR_INVALID_HANDLE;
1136                 goto error;
1137         }
1138
1139         util_debug(server->debug_callback, server->debug_data,
1140                                 "Prep Write Req - handle: 0x%04x", handle);
1141
1142         ecode = check_permissions(server, attr, BT_ATT_PERM_WRITE |
1143                                                 BT_ATT_PERM_WRITE_AUTHEN |
1144                                                 BT_ATT_PERM_WRITE_ENCRYPT);
1145         if (ecode)
1146                 goto error;
1147
1148         prep_data = new0(struct prep_write_data, 1);
1149         prep_data->length = length - 4;
1150         if (prep_data->length) {
1151                 prep_data->value = malloc(prep_data->length);
1152                 if (!prep_data->value) {
1153                         ecode = BT_ATT_ERROR_INSUFFICIENT_RESOURCES;
1154                         goto error;
1155                 }
1156         }
1157
1158         prep_data->server = server;
1159         prep_data->handle = handle;
1160         prep_data->offset = offset;
1161         memcpy(prep_data->value, pdu + 4, prep_data->length);
1162
1163         queue_push_tail(server->prep_queue, prep_data);
1164
1165         bt_att_send(server->att, BT_ATT_OP_PREP_WRITE_RSP, pdu, length, NULL,
1166                                                                 NULL, NULL);
1167         return;
1168
1169 error:
1170         if (prep_data)
1171                 prep_write_data_destroy(prep_data);
1172
1173         bt_att_send_error_rsp(server->att, opcode, handle, ecode);
1174
1175 }
1176
1177 static void exec_next_prep_write(struct bt_gatt_server *server,
1178                                                 uint16_t ehandle, int err);
1179
1180 static void exec_write_complete_cb(struct gatt_db_attribute *attr, int err,
1181                                                                 void *user_data)
1182 {
1183         struct bt_gatt_server *server = user_data;
1184         uint16_t handle = gatt_db_attribute_get_handle(attr);
1185
1186         exec_next_prep_write(server, handle, err);
1187 }
1188
1189 static void exec_next_prep_write(struct bt_gatt_server *server,
1190                                                 uint16_t ehandle, int err)
1191 {
1192         struct prep_write_data *next = NULL;
1193         struct gatt_db_attribute *attr;
1194         bool status;
1195
1196         if (err)
1197                 goto error;
1198
1199         next = queue_pop_head(server->prep_queue);
1200         if (!next) {
1201                 bt_att_send(server->att, BT_ATT_OP_EXEC_WRITE_RSP, NULL, 0,
1202                                                         NULL, NULL, NULL);
1203                 return;
1204         }
1205
1206         attr = gatt_db_get_attribute(server->db, next->handle);
1207         if (!attr) {
1208                 err = BT_ATT_ERROR_UNLIKELY;
1209                 goto error;
1210         }
1211
1212         status = gatt_db_attribute_write(attr, next->offset,
1213                                                 next->value, next->length,
1214                                                 BT_ATT_OP_EXEC_WRITE_REQ,
1215                                                 server->att,
1216                                                 exec_write_complete_cb, server);
1217
1218         prep_write_data_destroy(next);
1219
1220         if (status)
1221                 return;
1222
1223         err = BT_ATT_ERROR_UNLIKELY;
1224
1225 error:
1226         bt_att_send_error_rsp(server->att, BT_ATT_OP_EXEC_WRITE_REQ,
1227                                                                 ehandle, err);
1228 }
1229
1230 static void exec_write_cb(uint8_t opcode, const void *pdu,
1231                                         uint16_t length, void *user_data)
1232 {
1233         struct bt_gatt_server *server = user_data;
1234         uint8_t flags;
1235         uint8_t ecode;
1236         bool write;
1237
1238         if (length != 1) {
1239                 ecode = BT_ATT_ERROR_INVALID_PDU;
1240                 goto error;
1241         }
1242
1243         flags = ((uint8_t *) pdu)[0];
1244
1245         util_debug(server->debug_callback, server->debug_data,
1246                                 "Exec Write Req - flags: 0x%02x", flags);
1247
1248         if (flags == 0x00)
1249                 write = false;
1250         else if (flags == 0x01)
1251                 write = true;
1252         else {
1253                 ecode = BT_ATT_ERROR_INVALID_PDU;
1254                 goto error;
1255         }
1256
1257         if (!write) {
1258                 queue_remove_all(server->prep_queue, NULL, NULL,
1259                                                 prep_write_data_destroy);
1260                 bt_att_send(server->att, BT_ATT_OP_EXEC_WRITE_RSP, NULL, 0,
1261                                                         NULL, NULL, NULL);
1262                 return;
1263         }
1264
1265         exec_next_prep_write(server, 0, 0);
1266
1267         return;
1268
1269 error:
1270         bt_att_send_error_rsp(server->att, opcode, 0, ecode);
1271 }
1272
1273 static void exchange_mtu_cb(uint8_t opcode, const void *pdu,
1274                                         uint16_t length, void *user_data)
1275 {
1276         struct bt_gatt_server *server = user_data;
1277         uint16_t client_rx_mtu;
1278         uint16_t final_mtu;
1279         uint8_t rsp_pdu[2];
1280
1281         if (length != 2) {
1282                 bt_att_send_error_rsp(server->att, opcode, 0,
1283                                                 BT_ATT_ERROR_INVALID_PDU);
1284                 return;
1285         }
1286
1287         client_rx_mtu = get_le16(pdu);
1288 #ifndef __TIZEN_PACTH__
1289         final_mtu = MAX(MIN(client_rx_mtu, server->mtu), BT_ATT_DEFAULT_LE_MTU);
1290
1291         /* Respond with the server MTU */
1292         put_le16(server->mtu, rsp_pdu);
1293         bt_att_send(server->att, BT_ATT_OP_MTU_RSP, rsp_pdu, 2, NULL, NULL,
1294                                                                         NULL);
1295
1296         /* Set MTU to be the minimum */
1297         server->mtu = final_mtu;
1298         bt_att_set_mtu(server->att, final_mtu);
1299 #else
1300         final_mtu = MAX(MIN(client_rx_mtu, BT_ATT_MAX_LE_MTU), BT_ATT_DEFAULT_LE_MTU);
1301
1302         /* Set MTU to be the minimum */
1303         server->mtu = final_mtu;
1304         bt_att_set_mtu(server->att, final_mtu);
1305
1306         /* Respond with the server MTU */
1307         put_le16(server->mtu, rsp_pdu);
1308         bt_att_send(server->att, BT_ATT_OP_MTU_RSP, rsp_pdu, 2, NULL, NULL,
1309                                                                         NULL);
1310 #endif
1311
1312         util_debug(server->debug_callback, server->debug_data,
1313                         "MTU exchange complete, with MTU: %u", final_mtu);
1314 }
1315
1316 static bool gatt_server_register_att_handlers(struct bt_gatt_server *server)
1317 {
1318         /* Exchange MTU */
1319         server->mtu_id = bt_att_register(server->att, BT_ATT_OP_MTU_REQ,
1320                                                                 exchange_mtu_cb,
1321                                                                 server, NULL);
1322         if (!server->mtu_id)
1323                 return false;
1324
1325         /* Read By Group Type */
1326         server->read_by_grp_type_id = bt_att_register(server->att,
1327                                                 BT_ATT_OP_READ_BY_GRP_TYPE_REQ,
1328                                                 read_by_grp_type_cb,
1329                                                 server, NULL);
1330         if (!server->read_by_grp_type_id)
1331                 return false;
1332
1333         /* Read By Type */
1334         server->read_by_type_id = bt_att_register(server->att,
1335                                                 BT_ATT_OP_READ_BY_TYPE_REQ,
1336                                                 read_by_type_cb,
1337                                                 server, NULL);
1338         if (!server->read_by_type_id)
1339                 return false;
1340
1341         /* Find Information */
1342         server->find_info_id = bt_att_register(server->att,
1343                                                         BT_ATT_OP_FIND_INFO_REQ,
1344                                                         find_info_cb,
1345                                                         server, NULL);
1346         if (!server->find_info_id)
1347                 return false;
1348
1349         /* Find By Type Value */
1350         server->find_by_type_value_id = bt_att_register(server->att,
1351                                                 BT_ATT_OP_FIND_BY_TYPE_REQ,
1352                                                 find_by_type_val_cb,
1353                                                 server, NULL);
1354
1355         if (!server->find_by_type_value_id)
1356                 return false;
1357
1358         /* Write Request */
1359         server->write_id = bt_att_register(server->att, BT_ATT_OP_WRITE_REQ,
1360                                                                 write_cb,
1361                                                                 server, NULL);
1362         if (!server->write_id)
1363                 return false;
1364
1365         /* Write Command */
1366         server->write_cmd_id = bt_att_register(server->att, BT_ATT_OP_WRITE_CMD,
1367                                                                 write_cb,
1368                                                                 server, NULL);
1369         if (!server->write_cmd_id)
1370                 return false;
1371
1372         /* Read Request */
1373         server->read_id = bt_att_register(server->att, BT_ATT_OP_READ_REQ,
1374                                                                 read_cb,
1375                                                                 server, NULL);
1376         if (!server->read_id)
1377                 return false;
1378
1379         /* Read Blob Request */
1380         server->read_blob_id = bt_att_register(server->att,
1381                                                         BT_ATT_OP_READ_BLOB_REQ,
1382                                                         read_blob_cb,
1383                                                         server, NULL);
1384         if (!server->read_blob_id)
1385                 return false;
1386
1387         /* Read Multiple Request */
1388         server->read_multiple_id = bt_att_register(server->att,
1389                                                         BT_ATT_OP_READ_MULT_REQ,
1390                                                         read_multiple_cb,
1391                                                         server, NULL);
1392
1393         if (!server->read_multiple_id)
1394                 return false;
1395
1396         /* Prepare Write Request */
1397         server->prep_write_id = bt_att_register(server->att,
1398                                                 BT_ATT_OP_PREP_WRITE_REQ,
1399                                                 prep_write_cb, server, NULL);
1400         if (!server->prep_write_id)
1401                 return false;
1402
1403         /* Execute Write Request */
1404         server->exec_write_id = bt_att_register(server->att,
1405                                                 BT_ATT_OP_EXEC_WRITE_REQ,
1406                                                 exec_write_cb, server, NULL);
1407         if (!server->exec_write_id)
1408                 return NULL;
1409
1410         return true;
1411 }
1412
1413 struct bt_gatt_server *bt_gatt_server_new(struct gatt_db *db,
1414                                         struct bt_att *att, uint16_t mtu)
1415 {
1416         struct bt_gatt_server *server;
1417
1418         if (!att || !db)
1419                 return NULL;
1420
1421         server = new0(struct bt_gatt_server, 1);
1422         server->db = gatt_db_ref(db);
1423         server->att = bt_att_ref(att);
1424         server->mtu = MAX(mtu, BT_ATT_DEFAULT_LE_MTU);
1425         server->max_prep_queue_len = DEFAULT_MAX_PREP_QUEUE_LEN;
1426         server->prep_queue = queue_new();
1427
1428         if (!gatt_server_register_att_handlers(server)) {
1429                 bt_gatt_server_free(server);
1430                 return NULL;
1431         }
1432
1433         return bt_gatt_server_ref(server);
1434 }
1435
1436 struct bt_gatt_server *bt_gatt_server_ref(struct bt_gatt_server *server)
1437 {
1438         if (!server)
1439                 return NULL;
1440
1441         __sync_fetch_and_add(&server->ref_count, 1);
1442
1443         return server;
1444 }
1445
1446 void bt_gatt_server_unref(struct bt_gatt_server *server)
1447 {
1448         if (!server)
1449                 return;
1450
1451         if (__sync_sub_and_fetch(&server->ref_count, 1))
1452                 return;
1453
1454         bt_gatt_server_free(server);
1455 }
1456
1457 bool bt_gatt_server_set_debug(struct bt_gatt_server *server,
1458                                         bt_gatt_server_debug_func_t callback,
1459                                         void *user_data,
1460                                         bt_gatt_server_destroy_func_t destroy)
1461 {
1462         if (!server)
1463                 return false;
1464
1465         if (server->debug_destroy)
1466                 server->debug_destroy(server->debug_data);
1467
1468         server->debug_callback = callback;
1469         server->debug_destroy = destroy;
1470         server->debug_data = user_data;
1471
1472         return true;
1473 }
1474
1475 bool bt_gatt_server_send_notification(struct bt_gatt_server *server,
1476                                         uint16_t handle, const uint8_t *value,
1477                                         uint16_t length)
1478 {
1479         uint16_t pdu_len;
1480         uint8_t *pdu;
1481         bool result;
1482
1483         if (!server || (length && !value))
1484                 return false;
1485
1486         pdu_len = MIN(bt_att_get_mtu(server->att) - 1, length + 2);
1487         pdu = malloc(pdu_len);
1488         if (!pdu)
1489                 return false;
1490
1491         put_le16(handle, pdu);
1492         memcpy(pdu + 2, value, pdu_len - 2);
1493
1494         result = !!bt_att_send(server->att, BT_ATT_OP_HANDLE_VAL_NOT, pdu,
1495                                                 pdu_len, NULL, NULL, NULL);
1496         free(pdu);
1497
1498         return result;
1499 }
1500
1501 struct ind_data {
1502         bt_gatt_server_conf_func_t callback;
1503         bt_gatt_server_destroy_func_t destroy;
1504         void *user_data;
1505 };
1506
1507 static void destroy_ind_data(void *user_data)
1508 {
1509         struct ind_data *data = user_data;
1510
1511         if (data->destroy)
1512                 data->destroy(data->user_data);
1513
1514         free(data);
1515 }
1516
1517 static void conf_cb(uint8_t opcode, const void *pdu,
1518                                         uint16_t length, void *user_data)
1519 {
1520         struct ind_data *data = user_data;
1521
1522         if (data->callback)
1523                 data->callback(data->user_data);
1524 }
1525
1526 bool bt_gatt_server_send_indication(struct bt_gatt_server *server,
1527                                         uint16_t handle, const uint8_t *value,
1528                                         uint16_t length,
1529                                         bt_gatt_server_conf_func_t callback,
1530                                         void *user_data,
1531                                         bt_gatt_server_destroy_func_t destroy)
1532 {
1533         uint16_t pdu_len;
1534         uint8_t *pdu;
1535         struct ind_data *data;
1536         bool result;
1537
1538         if (!server || (length && !value))
1539                 return false;
1540
1541         pdu_len = MIN(bt_att_get_mtu(server->att) - 1, length + 2);
1542         pdu = malloc(pdu_len);
1543         if (!pdu)
1544                 return false;
1545
1546         data = new0(struct ind_data, 1);
1547
1548         data->callback = callback;
1549         data->destroy = destroy;
1550         data->user_data = user_data;
1551
1552         put_le16(handle, pdu);
1553         memcpy(pdu + 2, value, pdu_len - 2);
1554
1555         result = !!bt_att_send(server->att, BT_ATT_OP_HANDLE_VAL_IND, pdu,
1556                                                         pdu_len, conf_cb,
1557                                                         data, destroy_ind_data);
1558         if (!result)
1559                 destroy_ind_data(data);
1560
1561         free(pdu);
1562
1563         return result;
1564 }