Upgrade bluez5_37 :Merge the code from private
[platform/upstream/bluez.git] / src / shared / gatt-helpers.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
25 #ifdef HAVE_CONFIG_H
26 #include <config.h>
27 #endif
28
29 #include "src/shared/queue.h"
30 #include "src/shared/att.h"
31 #include "lib/bluetooth.h"
32 #include "lib/uuid.h"
33 #include "src/shared/gatt-helpers.h"
34 #include "src/shared/util.h"
35
36 #ifndef MIN
37 #define MIN(a, b) ((a) < (b) ? (a) : (b))
38 #endif
39
40 struct bt_gatt_result {
41         uint8_t opcode;
42         void *pdu;
43         uint16_t pdu_len;
44         uint16_t data_len;
45
46         void *op;  /* Discovery operation data */
47
48         struct bt_gatt_result *next;
49 };
50
51 static struct bt_gatt_result *result_create(uint8_t opcode, const void *pdu,
52                                                         uint16_t pdu_len,
53                                                         uint16_t data_len,
54                                                         void *op)
55 {
56         struct bt_gatt_result *result;
57
58         result = new0(struct bt_gatt_result, 1);
59         result->pdu = malloc(pdu_len);
60         if (!result->pdu) {
61                 free(result);
62                 return NULL;
63         }
64
65         result->opcode = opcode;
66         result->pdu_len = pdu_len;
67         result->data_len = data_len;
68         result->op = op;
69
70         memcpy(result->pdu, pdu, pdu_len);
71
72         return result;
73 }
74
75 static void result_destroy(struct bt_gatt_result *result)
76 {
77         struct bt_gatt_result *next;
78
79         while (result) {
80                 next = result->next;
81
82                 free(result->pdu);
83                 free(result);
84
85                 result = next;
86         }
87 }
88
89 static unsigned int result_element_count(struct bt_gatt_result *result)
90 {
91         unsigned int count = 0;
92         struct bt_gatt_result *cur;
93
94         cur = result;
95
96         while (cur) {
97                 count += cur->pdu_len / cur->data_len;
98                 cur = cur->next;
99         }
100
101         return count;
102 }
103
104 unsigned int bt_gatt_result_service_count(struct bt_gatt_result *result)
105 {
106         if (!result)
107                 return 0;
108
109         if (result->opcode != BT_ATT_OP_READ_BY_GRP_TYPE_RSP &&
110                         result->opcode != BT_ATT_OP_FIND_BY_TYPE_RSP)
111                 return 0;
112
113         return result_element_count(result);
114 }
115
116 unsigned int bt_gatt_result_characteristic_count(struct bt_gatt_result *result)
117 {
118         if (!result)
119                 return 0;
120
121         if (result->opcode != BT_ATT_OP_READ_BY_TYPE_RSP)
122                 return 0;
123
124         /*
125          * Data length contains 7 or 21 octets:
126          * 2 octets: Attribute handle
127          * 1 octet: Characteristic properties
128          * 2 octets: Characteristic value handle
129          * 2 or 16 octets: characteristic UUID
130          */
131         if (result->data_len != 21 && result->data_len != 7)
132                 return 0;
133
134         return result_element_count(result);
135 }
136
137 unsigned int bt_gatt_result_descriptor_count(struct bt_gatt_result *result)
138 {
139         if (!result)
140                 return 0;
141
142         if (result->opcode != BT_ATT_OP_FIND_INFO_RSP)
143                 return 0;
144
145         return result_element_count(result);
146 }
147
148 unsigned int bt_gatt_result_included_count(struct bt_gatt_result *result)
149 {
150         struct bt_gatt_result *cur;
151         unsigned int count = 0;
152
153         if (!result)
154                 return 0;
155
156         if (result->opcode != BT_ATT_OP_READ_BY_TYPE_RSP)
157                 return 0;
158
159         /*
160          * Data length can be of length 6 or 8 octets:
161          * 2 octets - include service handle
162          * 2 octets - start handle of included service
163          * 2 octets - end handle of included service
164          * 2 octets (optionally) - 16 bit Bluetooth UUID
165          */
166         if (result->data_len != 6 && result->data_len != 8)
167                 return 0;
168
169         for (cur = result; cur; cur = cur->next)
170                 if (cur->opcode == BT_ATT_OP_READ_BY_TYPE_RSP)
171                         count += cur->pdu_len / cur->data_len;
172
173         return count;
174 }
175
176 bool bt_gatt_iter_init(struct bt_gatt_iter *iter, struct bt_gatt_result *result)
177 {
178         if (!iter || !result)
179                 return false;
180
181         iter->result = result;
182         iter->pos = 0;
183
184         return true;
185 }
186
187 static const uint8_t bt_base_uuid[16] = {
188         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
189         0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB
190 };
191
192 static bool convert_uuid_le(const uint8_t *src, size_t len, uint8_t dst[16])
193 {
194         if (len == 16) {
195                 bswap_128(src, dst);
196                 return true;
197         }
198
199         if (len != 2)
200                 return false;
201
202         memcpy(dst, bt_base_uuid, sizeof(bt_base_uuid));
203         dst[2] = src[1];
204         dst[3] = src[0];
205
206         return true;
207 }
208
209 struct bt_gatt_request {
210         struct bt_att *att;
211         unsigned int id;
212         uint16_t start_handle;
213         uint16_t end_handle;
214         int ref_count;
215         bt_uuid_t uuid;
216         uint16_t service_type;
217         struct bt_gatt_result *result_head;
218         struct bt_gatt_result *result_tail;
219         bt_gatt_request_callback_t callback;
220         void *user_data;
221         bt_gatt_destroy_func_t destroy;
222 };
223
224 static struct bt_gatt_result *result_append(uint8_t opcode, const void *pdu,
225                                                 uint16_t pdu_len,
226                                                 uint16_t data_len,
227                                                 struct bt_gatt_request *op)
228 {
229         struct bt_gatt_result *result;
230
231         result = result_create(opcode, pdu, pdu_len, data_len, op);
232         if (!result)
233                 return NULL;
234
235         if (!op->result_head)
236                 op->result_head = op->result_tail = result;
237         else {
238                 op->result_tail->next = result;
239                 op->result_tail = result;
240         }
241
242         return result;
243 }
244
245 bool bt_gatt_iter_next_included_service(struct bt_gatt_iter *iter,
246                                 uint16_t *handle, uint16_t *start_handle,
247                                 uint16_t *end_handle, uint8_t uuid[16])
248 {
249         struct bt_gatt_result *read_result;
250         struct bt_gatt_request *op;
251         const void *pdu_ptr;
252         int i = 0;
253
254         if (!iter || !iter->result || !handle || !start_handle || !end_handle
255                                                                 || !uuid)
256                 return false;
257
258
259         if (iter->result->opcode != BT_ATT_OP_READ_BY_TYPE_RSP)
260                 return false;
261
262         /* UUID in discovery_op is set in read_by_type and service_discovery */
263         op = iter->result->op;
264         if (op->uuid.type != BT_UUID_UNSPEC)
265                 return false;
266         /*
267          * iter->result points to READ_BY_TYPE_RSP with data length containing:
268          * 2 octets - include service handle
269          * 2 octets - start handle of included service
270          * 2 octets - end handle of included service
271          * optional 2  octets - Bluetooth UUID
272          */
273         if (iter->result->data_len != 8 && iter->result->data_len != 6)
274                 return false;
275
276         pdu_ptr = iter->result->pdu + iter->pos;
277
278         /* This result contains 16 bit UUID */
279         if (iter->result->data_len == 8) {
280                 *handle = get_le16(pdu_ptr);
281                 *start_handle = get_le16(pdu_ptr + 2);
282                 *end_handle = get_le16(pdu_ptr + 4);
283                 convert_uuid_le(pdu_ptr + 6, 2, uuid);
284
285                 iter->pos += iter->result->data_len;
286
287                 if (iter->pos == iter->result->pdu_len) {
288                         iter->result = iter->result->next;
289                         iter->pos = 0;
290                 }
291
292                 return true;
293         }
294
295         *handle = get_le16(pdu_ptr);
296         *start_handle = get_le16(pdu_ptr + 2);
297         *end_handle = get_le16(pdu_ptr + 4);
298         read_result = iter->result;
299
300         /*
301          * Find READ_RSP with include service UUID.
302          * If number of current data set in READ_BY_TYPE_RSP is n, then we must
303          * go to n'th PDU next to current item->result
304          */
305         for (read_result = read_result->next; read_result; i++) {
306                 if (i >= (iter->pos / iter->result->data_len))
307                         break;
308
309                 read_result = read_result->next;
310         }
311
312         if (!read_result)
313                 return false;
314
315         convert_uuid_le(read_result->pdu, read_result->data_len, uuid);
316         iter->pos += iter->result->data_len;
317         if (iter->pos == iter->result->pdu_len) {
318                 iter->result = read_result->next;
319                 iter->pos = 0;
320         }
321
322         return true;
323 }
324
325 bool bt_gatt_iter_next_service(struct bt_gatt_iter *iter,
326                                 uint16_t *start_handle, uint16_t *end_handle,
327                                 uint8_t uuid[16])
328 {
329         struct bt_gatt_request *op;
330         const void *pdu_ptr;
331         bt_uuid_t tmp;
332
333         if (!iter || !iter->result || !start_handle || !end_handle || !uuid)
334                 return false;
335
336         op = iter->result->op;
337         pdu_ptr = iter->result->pdu + iter->pos;
338
339         switch (iter->result->opcode) {
340         case BT_ATT_OP_READ_BY_GRP_TYPE_RSP:
341                 *start_handle = get_le16(pdu_ptr);
342                 *end_handle = get_le16(pdu_ptr + 2);
343                 convert_uuid_le(pdu_ptr + 4, iter->result->data_len - 4, uuid);
344                 break;
345         case BT_ATT_OP_FIND_BY_TYPE_RSP:
346                 *start_handle = get_le16(pdu_ptr);
347                 *end_handle = get_le16(pdu_ptr + 2);
348
349                 bt_uuid_to_uuid128(&op->uuid, &tmp);
350                 memcpy(uuid, tmp.value.u128.data, 16);
351                 break;
352         default:
353                 return false;
354         }
355
356
357         iter->pos += iter->result->data_len;
358         if (iter->pos == iter->result->pdu_len) {
359                 iter->result = iter->result->next;
360                 iter->pos = 0;
361         }
362
363         return true;
364 }
365
366 bool bt_gatt_iter_next_characteristic(struct bt_gatt_iter *iter,
367                                 uint16_t *start_handle, uint16_t *end_handle,
368                                 uint16_t *value_handle, uint8_t *properties,
369                                 uint8_t uuid[16])
370 {
371         struct bt_gatt_request *op;
372         const void *pdu_ptr;
373
374         if (!iter || !iter->result || !start_handle || !end_handle ||
375                                         !value_handle || !properties || !uuid)
376                 return false;
377
378         if (iter->result->opcode != BT_ATT_OP_READ_BY_TYPE_RSP)
379                 return false;
380
381         /* UUID in discovery_op is set in read_by_type and service_discovery */
382         op = iter->result->op;
383         if (op->uuid.type != BT_UUID_UNSPEC)
384                 return false;
385         /*
386          * Data length contains 7 or 21 octets:
387          * 2 octets: Attribute handle
388          * 1 octet: Characteristic properties
389          * 2 octets: Characteristic value handle
390          * 2 or 16 octets: characteristic UUID
391          */
392         if (iter->result->data_len != 21 && iter->result->data_len != 7)
393                 return false;
394
395         pdu_ptr = iter->result->pdu + iter->pos;
396
397         *start_handle = get_le16(pdu_ptr);
398         *properties = ((uint8_t *) pdu_ptr)[2];
399         *value_handle = get_le16(pdu_ptr + 3);
400         convert_uuid_le(pdu_ptr + 5, iter->result->data_len - 5, uuid);
401
402         iter->pos += iter->result->data_len;
403         if (iter->pos == iter->result->pdu_len) {
404                 iter->result = iter->result->next;
405                 iter->pos = 0;
406         }
407
408         if (!iter->result) {
409                 *end_handle = op->end_handle;
410                 return true;
411         }
412
413         *end_handle = get_le16(iter->result->pdu + iter->pos) - 1;
414
415         return true;
416 }
417
418 bool bt_gatt_iter_next_descriptor(struct bt_gatt_iter *iter, uint16_t *handle,
419                                                         uint8_t uuid[16])
420 {
421         const void *pdu_ptr;
422
423         if (!iter || !iter->result || !handle || !uuid)
424                 return false;
425
426         if (iter->result->opcode != BT_ATT_OP_FIND_INFO_RSP)
427                 return false;
428
429         pdu_ptr = iter->result->pdu + iter->pos;
430
431         *handle = get_le16(pdu_ptr);
432         convert_uuid_le(pdu_ptr + 2, iter->result->data_len - 2, uuid);
433
434         iter->pos += iter->result->data_len;
435         if (iter->pos == iter->result->pdu_len) {
436                 iter->result = iter->result->next;
437                 iter->pos = 0;
438         }
439
440         return true;
441 }
442
443 bool bt_gatt_iter_next_read_by_type(struct bt_gatt_iter *iter,
444                                 uint16_t *handle, uint16_t *length,
445                                 const uint8_t **value)
446 {
447         struct bt_gatt_request *op;
448         const void *pdu_ptr;
449
450         if (!iter || !iter->result || !handle || !length || !value)
451                 return false;
452
453         if (iter->result->opcode != BT_ATT_OP_READ_BY_TYPE_RSP)
454                 return false;
455
456         /*
457          * Check if UUID is set, otherwise results can contain characteristic
458          * discovery service or included service discovery results
459          */
460         op = iter->result->op;
461         if (op->uuid.type == BT_UUID_UNSPEC)
462                 return false;
463
464         pdu_ptr = iter->result->pdu + iter->pos;
465
466         *handle = get_le16(pdu_ptr);
467         *length = iter->result->data_len - 2;
468         *value = pdu_ptr + 2;
469
470         iter->pos += iter->result->data_len;
471         if (iter->pos == iter->result->pdu_len) {
472                 iter->result = iter->result->next;
473                 iter->pos = 0;
474         }
475
476         return true;
477 }
478
479 struct mtu_op {
480         struct bt_att *att;
481         uint16_t client_rx_mtu;
482         bt_gatt_result_callback_t callback;
483         void *user_data;
484         bt_gatt_destroy_func_t destroy;
485 };
486
487 static void destroy_mtu_op(void *user_data)
488 {
489         struct mtu_op *op = user_data;
490
491         if (op->destroy)
492                 op->destroy(op->user_data);
493
494         free(op);
495 }
496
497 static uint8_t process_error(const void *pdu, uint16_t length)
498 {
499         const struct bt_att_pdu_error_rsp *error_pdu;
500
501         if (!pdu || length != sizeof(struct bt_att_pdu_error_rsp))
502                 return 0;
503
504         error_pdu = pdu;
505
506         return error_pdu->ecode;
507 }
508
509 static void mtu_cb(uint8_t opcode, const void *pdu, uint16_t length,
510                                                                 void *user_data)
511 {
512         struct mtu_op *op = user_data;
513         bool success = true;
514         uint8_t att_ecode = 0;
515         uint16_t server_rx_mtu;
516
517         if (opcode == BT_ATT_OP_ERROR_RSP) {
518                 success = false;
519                 att_ecode = process_error(pdu, length);
520                 goto done;
521         }
522
523         if (opcode != BT_ATT_OP_MTU_RSP || !pdu || length != 2) {
524                 success = false;
525                 goto done;
526         }
527
528         server_rx_mtu = get_le16(pdu);
529         bt_att_set_mtu(op->att, MIN(op->client_rx_mtu, server_rx_mtu));
530
531 done:
532         if (op->callback)
533                 op->callback(success, att_ecode, op->user_data);
534 }
535
536 unsigned int bt_gatt_exchange_mtu(struct bt_att *att, uint16_t client_rx_mtu,
537                                         bt_gatt_result_callback_t callback,
538                                         void *user_data,
539                                         bt_gatt_destroy_func_t destroy)
540 {
541         struct mtu_op *op;
542         uint8_t pdu[2];
543         unsigned int id;
544
545         if (!att || !client_rx_mtu)
546                 return false;
547
548         op = new0(struct mtu_op, 1);
549         op->att = att;
550         op->client_rx_mtu = client_rx_mtu;
551         op->callback = callback;
552         op->user_data = user_data;
553         op->destroy = destroy;
554
555         put_le16(client_rx_mtu, pdu);
556
557         id = bt_att_send(att, BT_ATT_OP_MTU_REQ, pdu, sizeof(pdu), mtu_cb, op,
558                                                                 destroy_mtu_op);
559         if (!id)
560                 free(op);
561
562         return id;
563 }
564
565 static inline int get_uuid_len(const bt_uuid_t *uuid)
566 {
567         if (!uuid)
568                 return 0;
569
570         return (uuid->type == BT_UUID16) ? 2 : 16;
571 }
572
573 struct bt_gatt_request *bt_gatt_request_ref(struct bt_gatt_request *req)
574 {
575         if (!req)
576                 return NULL;
577
578         __sync_fetch_and_add(&req->ref_count, 1);
579
580         return req;
581 }
582
583 void bt_gatt_request_unref(struct bt_gatt_request *req)
584 {
585         if (!req)
586                 return;
587
588         if (__sync_sub_and_fetch(&req->ref_count, 1))
589                 return;
590
591         bt_gatt_request_cancel(req);
592
593         if (req->destroy)
594                 req->destroy(req->user_data);
595
596         result_destroy(req->result_head);
597
598         free(req);
599 }
600
601 void bt_gatt_request_cancel(struct bt_gatt_request *req)
602 {
603         if (!req)
604                 return;
605
606         if (!req->id)
607                 return;
608
609         bt_att_cancel(req->att, req->id);
610         req->id = 0;
611 }
612
613 static void async_req_unref(void *data)
614 {
615         struct bt_gatt_request *req = data;
616
617         bt_gatt_request_unref(req);
618 }
619
620 static void discovery_op_complete(struct bt_gatt_request *op, bool success,
621                                                                 uint8_t ecode)
622 {
623         /* Reset success if there is some result to report */
624         if (ecode == BT_ATT_ERROR_ATTRIBUTE_NOT_FOUND && op->result_head)
625                 success = true;
626
627         if (op->callback)
628                 op->callback(success, ecode, success ? op->result_head : NULL,
629                                                                 op->user_data);
630
631         if (!op->id)
632                 async_req_unref(op);
633         else
634                 op->id = 0;
635
636 }
637
638 static void read_by_grp_type_cb(uint8_t opcode, const void *pdu,
639                                         uint16_t length, void *user_data)
640 {
641         struct bt_gatt_request *op = user_data;
642         bool success;
643         uint8_t att_ecode = 0;
644         struct bt_gatt_result *cur_result;
645         size_t data_length;
646         size_t list_length;
647         uint16_t last_end;
648
649         if (opcode == BT_ATT_OP_ERROR_RSP) {
650                 success = false;
651                 att_ecode = process_error(pdu, length);
652                 goto done;
653         }
654
655         /* PDU must contain at least the following (sans opcode):
656          * - Attr Data Length (1 octet)
657          * - Attr Data List (at least 6 octets):
658          *   -- 2 octets: Attribute handle
659          *   -- 2 octets: End group handle
660          *   -- 2 or 16 octets: service UUID
661          */
662         if (opcode != BT_ATT_OP_READ_BY_GRP_TYPE_RSP || !pdu || length < 7) {
663                 success = false;
664                 goto done;
665         }
666
667         data_length = ((uint8_t *) pdu)[0];
668         list_length = length - 1;
669
670         if ((data_length != 6 && data_length != 20) ||
671                                         (list_length % data_length)) {
672                 success = false;
673                 goto done;
674         }
675
676         /* PDU is correctly formatted. Get the last end handle to process the
677          * next request and store the PDU.
678          */
679         cur_result = result_append(opcode, pdu + 1, list_length, data_length,
680                                                                         op);
681         if (!cur_result) {
682                 success = false;
683                 goto done;
684         }
685
686         last_end = get_le16(pdu + length - data_length + 2);
687
688         /*
689          * If last handle is lower from previous start handle then it is smth
690          * wrong. Let's stop search, otherwise we might enter infinite loop.
691          */
692         if (last_end < op->start_handle) {
693                 success = false;
694                 goto done;
695         }
696
697         op->start_handle = last_end + 1;
698
699         if (last_end < op->end_handle) {
700                 uint8_t pdu[6];
701
702                 put_le16(op->start_handle, pdu);
703                 put_le16(op->end_handle, pdu + 2);
704                 put_le16(op->service_type, pdu + 4);
705
706                 op->id = bt_att_send(op->att, BT_ATT_OP_READ_BY_GRP_TYPE_REQ,
707                                                 pdu, sizeof(pdu),
708                                                 read_by_grp_type_cb,
709                                                 bt_gatt_request_ref(op),
710                                                 async_req_unref);
711                 if (op->id)
712                         return;
713
714                 success = false;
715                 goto done;
716         }
717
718         /* Some devices incorrectly return 0xffff as the end group handle when
719          * the read-by-group-type request is performed within a smaller range.
720          * Manually set the end group handle that we report in the result to the
721          * end handle in the original request.
722          */
723         if (last_end == 0xffff && last_end != op->end_handle)
724                 put_le16(op->end_handle,
725                                 cur_result->pdu + length - data_length + 1);
726
727         success = true;
728
729 done:
730         discovery_op_complete(op, success, att_ecode);
731 }
732
733 static void find_by_type_val_cb(uint8_t opcode, const void *pdu,
734                                         uint16_t length, void *user_data)
735 {
736         struct bt_gatt_request *op = user_data;
737         bool success;
738         uint8_t att_ecode = 0;
739         uint16_t last_end;
740
741         if (opcode == BT_ATT_OP_ERROR_RSP) {
742                 success = false;
743                 att_ecode = process_error(pdu, length);
744                 goto done;
745         }
746
747         /* PDU must contain 4 bytes and it must be a multiple of 4, where each
748          * 4 bytes contain the 16-bit attribute and group end handles.
749          */
750         if (opcode != BT_ATT_OP_FIND_BY_TYPE_RSP || !pdu || !length ||
751                                                                 length % 4) {
752                 success = false;
753                 goto done;
754         }
755
756         if (!result_append(opcode, pdu, length, 4, op)) {
757                 success = false;
758                 goto done;
759         }
760
761         /*
762          * Each data set contains:
763          * 2 octets with start handle
764          * 2 octets with end handle
765          * last_end is end handle of last data set
766          */
767         last_end = get_le16(pdu + length - 2);
768
769         /*
770         * If last handle is lower from previous start handle then it is smth
771         * wrong. Let's stop search, otherwise we might enter infinite loop.
772         */
773         if (last_end < op->start_handle) {
774                 success = false;
775                 goto done;
776         }
777
778         op->start_handle = last_end + 1;
779
780         if (last_end < op->end_handle) {
781                 uint8_t pdu[6 + get_uuid_len(&op->uuid)];
782
783                 put_le16(op->start_handle, pdu);
784                 put_le16(op->end_handle, pdu + 2);
785                 put_le16(op->service_type, pdu + 4);
786                 bt_uuid_to_le(&op->uuid, pdu + 6);
787
788                 op->id = bt_att_send(op->att, BT_ATT_OP_FIND_BY_TYPE_REQ,
789                                                 pdu, sizeof(pdu),
790                                                 find_by_type_val_cb,
791                                                 bt_gatt_request_ref(op),
792                                                 async_req_unref);
793                 if (op->id)
794                         return;
795
796                 success = false;
797                 goto done;
798         }
799
800         success = false;
801
802 done:
803         discovery_op_complete(op, success, att_ecode);
804 }
805
806 static struct bt_gatt_request *discover_services(struct bt_att *att,
807                                         bt_uuid_t *uuid,
808                                         uint16_t start, uint16_t end,
809                                         bt_gatt_request_callback_t callback,
810                                         void *user_data,
811                                         bt_gatt_destroy_func_t destroy,
812                                         bool primary)
813 {
814         struct bt_gatt_request *op;
815
816         if (!att)
817                 return NULL;
818
819         op = new0(struct bt_gatt_request, 1);
820         op->att = att;
821         op->start_handle = start;
822         op->end_handle = end;
823         op->callback = callback;
824         op->user_data = user_data;
825         op->destroy = destroy;
826         /* set service uuid to primary or secondary */
827         op->service_type = primary ? GATT_PRIM_SVC_UUID : GATT_SND_SVC_UUID;
828
829         /* If UUID is NULL, then discover all primary services */
830         if (!uuid) {
831                 uint8_t pdu[6];
832
833                 put_le16(start, pdu);
834                 put_le16(end, pdu + 2);
835                 put_le16(op->service_type, pdu + 4);
836
837                 op->id = bt_att_send(att, BT_ATT_OP_READ_BY_GRP_TYPE_REQ,
838                                                 pdu, sizeof(pdu),
839                                                 read_by_grp_type_cb,
840                                                 bt_gatt_request_ref(op),
841                                                 async_req_unref);
842         } else {
843                 uint8_t pdu[6 + get_uuid_len(uuid)];
844
845                 if (uuid->type == BT_UUID_UNSPEC) {
846                         free(op);
847                         return NULL;
848                 }
849
850                 /* Discover by UUID */
851                 op->uuid = *uuid;
852
853                 put_le16(start, pdu);
854                 put_le16(end, pdu + 2);
855                 put_le16(op->service_type, pdu + 4);
856                 bt_uuid_to_le(&op->uuid, pdu + 6);
857
858                 op->id = bt_att_send(att, BT_ATT_OP_FIND_BY_TYPE_REQ,
859                                                 pdu, sizeof(pdu),
860                                                 find_by_type_val_cb,
861                                                 bt_gatt_request_ref(op),
862                                                 async_req_unref);
863         }
864
865         if (!op->id) {
866                 free(op);
867                 return NULL;
868         }
869
870         return bt_gatt_request_ref(op);
871 }
872
873 struct bt_gatt_request *bt_gatt_discover_all_primary_services(
874                                         struct bt_att *att, bt_uuid_t *uuid,
875                                         bt_gatt_request_callback_t callback,
876                                         void *user_data,
877                                         bt_gatt_destroy_func_t destroy)
878 {
879         return bt_gatt_discover_primary_services(att, uuid, 0x0001, 0xffff,
880                                                         callback, user_data,
881                                                         destroy);
882 }
883
884 struct bt_gatt_request *bt_gatt_discover_primary_services(
885                                         struct bt_att *att, bt_uuid_t *uuid,
886                                         uint16_t start, uint16_t end,
887                                         bt_gatt_request_callback_t callback,
888                                         void *user_data,
889                                         bt_gatt_destroy_func_t destroy)
890 {
891         return discover_services(att, uuid, start, end, callback, user_data,
892                                                                 destroy, true);
893 }
894
895 struct bt_gatt_request *bt_gatt_discover_secondary_services(
896                                         struct bt_att *att, bt_uuid_t *uuid,
897                                         uint16_t start, uint16_t end,
898                                         bt_gatt_request_callback_t callback,
899                                         void *user_data,
900                                         bt_gatt_destroy_func_t destroy)
901 {
902         return discover_services(att, uuid, start, end, callback, user_data,
903                                                                 destroy, false);
904 }
905
906 struct read_incl_data {
907         struct bt_gatt_request *op;
908         struct bt_gatt_result *result;
909         int pos;
910         int ref_count;
911 };
912
913 static struct read_incl_data *new_read_included(struct bt_gatt_result *res)
914 {
915         struct read_incl_data *data;
916
917         data = new0(struct read_incl_data, 1);
918         data->op = bt_gatt_request_ref(res->op);
919         data->result = res;
920
921         return data;
922 };
923
924 static struct read_incl_data *read_included_ref(struct read_incl_data *data)
925 {
926         __sync_fetch_and_add(&data->ref_count, 1);
927
928         return data;
929 }
930
931 static void read_included_unref(void *data)
932 {
933         struct read_incl_data *read_data = data;
934
935         if (__sync_sub_and_fetch(&read_data->ref_count, 1))
936                 return;
937
938         async_req_unref(read_data->op);
939
940         free(read_data);
941 }
942
943 static void discover_included_cb(uint8_t opcode, const void *pdu,
944                                         uint16_t length, void *user_data);
945
946 static void read_included_cb(uint8_t opcode, const void *pdu,
947                                         uint16_t length, void *user_data)
948 {
949         struct read_incl_data *data = user_data;
950         struct bt_gatt_request *op = data->op;
951         uint8_t att_ecode = 0;
952         uint8_t read_pdu[2];
953         bool success;
954
955         if (opcode == BT_ATT_OP_ERROR_RSP) {
956                 success = false;
957                 att_ecode = process_error(pdu, length);
958                 goto done;
959         }
960
961         if (opcode != BT_ATT_OP_READ_RSP || (!pdu && length)) {
962                 success = false;
963                 goto done;
964         }
965
966         /*
967          * UUID should be in 128 bit format, as it couldn't be read in
968          * READ_BY_TYPE request
969          */
970         if (length != 16) {
971                 success = false;
972                 goto done;
973         }
974
975         if (!result_append(opcode, pdu, length, length, op)) {
976                 success = false;
977                 goto done;
978         }
979
980         if (data->pos == data->result->pdu_len) {
981                 uint16_t last_handle;
982                 uint8_t pdu[6];
983
984                 last_handle = get_le16(data->result->pdu + data->pos -
985                                                         data->result->data_len);
986                 if (last_handle == op->end_handle) {
987                         success = true;
988                         goto done;
989                 }
990
991                 put_le16(last_handle + 1, pdu);
992                 put_le16(op->end_handle, pdu + 2);
993                 put_le16(GATT_INCLUDE_UUID, pdu + 4);
994
995                 op->id = bt_att_send(op->att, BT_ATT_OP_READ_BY_TYPE_REQ,
996                                                 pdu, sizeof(pdu),
997                                                 discover_included_cb,
998                                                 bt_gatt_request_ref(op),
999                                                 async_req_unref);
1000                 if (op->id)
1001                         return;
1002
1003                 success = false;
1004                 goto done;
1005         }
1006
1007         memcpy(read_pdu, data->result->pdu + data->pos + 2, sizeof(uint16_t));
1008
1009         data->pos += data->result->data_len;
1010
1011         if (bt_att_send(op->att, BT_ATT_OP_READ_REQ, read_pdu, sizeof(read_pdu),
1012                                 read_included_cb, read_included_ref(data),
1013                                 read_included_unref))
1014                 return;
1015
1016         read_included_unref(data);
1017         success = false;
1018
1019 done:
1020         discovery_op_complete(op, success, att_ecode);
1021 }
1022
1023 static void read_included(struct read_incl_data *data)
1024 {
1025         struct bt_gatt_request *op = data->op;
1026         uint8_t pdu[2];
1027
1028         memcpy(pdu, data->result->pdu + 2, sizeof(uint16_t));
1029
1030         data->pos += data->result->data_len;
1031
1032         if (bt_att_send(op->att, BT_ATT_OP_READ_REQ, pdu, sizeof(pdu),
1033                                                         read_included_cb,
1034                                                         read_included_ref(data),
1035                                                         read_included_unref))
1036                 return;
1037
1038         if (op->callback)
1039                 op->callback(false, 0, NULL, data->op->user_data);
1040
1041         read_included_unref(data);
1042 }
1043
1044 static void discover_included_cb(uint8_t opcode, const void *pdu,
1045                                         uint16_t length, void *user_data)
1046 {
1047         struct bt_gatt_request *op = user_data;
1048         struct bt_gatt_result *cur_result;
1049         uint8_t att_ecode = 0;
1050         uint16_t last_handle;
1051         size_t data_length;
1052         bool success;
1053
1054         if (opcode == BT_ATT_OP_ERROR_RSP) {
1055                 att_ecode = process_error(pdu, length);
1056                 success = false;
1057                 goto failed;
1058         }
1059
1060         if (opcode != BT_ATT_OP_READ_BY_TYPE_RSP || !pdu || length < 6) {
1061                 success = false;
1062                 goto failed;
1063         }
1064
1065         data_length = ((const uint8_t *) pdu)[0];
1066
1067         /*
1068          * Check if PDU contains data sets with length declared in the beginning
1069          * of frame and if this length is correct.
1070          * Data set length may be 6 or 8 octets:
1071          * 2 octets - include service handle
1072          * 2 octets - start handle of included service
1073          * 2 octets - end handle of included service
1074          * optional 2 octets - Bluetooth UUID of included service
1075          */
1076         if ((data_length != 8 && data_length != 6) ||
1077                                                 (length - 1) % data_length) {
1078                 success = false;
1079                 goto failed;
1080         }
1081
1082         cur_result = result_append(opcode, pdu + 1, length - 1, data_length,
1083                                                                         op);
1084         if (!cur_result) {
1085                 success = false;
1086                 goto failed;
1087         }
1088
1089         if (data_length == 6) {
1090                 struct read_incl_data *data;
1091
1092                 data = new_read_included(cur_result);
1093                 if (!data) {
1094                         success = false;
1095                         goto failed;
1096                 }
1097
1098                 read_included(data);
1099                 return;
1100         }
1101
1102         last_handle = get_le16(pdu + length - data_length);
1103
1104         /*
1105          * If last handle is lower from previous start handle then it is smth
1106          * wrong. Let's stop search, otherwise we might enter infinite loop.
1107          */
1108         if (last_handle < op->start_handle) {
1109                 success = false;
1110                 goto failed;
1111         }
1112
1113         op->start_handle = last_handle + 1;
1114         if (last_handle != op->end_handle) {
1115                 uint8_t pdu[6];
1116
1117                 put_le16(op->start_handle, pdu);
1118                 put_le16(op->end_handle, pdu + 2);
1119                 put_le16(GATT_INCLUDE_UUID, pdu + 4);
1120
1121                 op->id = bt_att_send(op->att, BT_ATT_OP_READ_BY_TYPE_REQ,
1122                                                 pdu, sizeof(pdu),
1123                                                 discover_included_cb,
1124                                                 bt_gatt_request_ref(op),
1125                                                 async_req_unref);
1126                 if (op->id)
1127                         return;
1128
1129                 success = false;
1130                 goto failed;
1131         }
1132
1133         success = true;
1134
1135 failed:
1136         discovery_op_complete(op, success, att_ecode);
1137 }
1138
1139 struct bt_gatt_request *bt_gatt_discover_included_services(struct bt_att *att,
1140                                         uint16_t start, uint16_t end,
1141                                         bt_gatt_request_callback_t callback,
1142                                         void *user_data,
1143                                         bt_gatt_destroy_func_t destroy)
1144 {
1145         struct bt_gatt_request *op;
1146         uint8_t pdu[6];
1147
1148         if (!att)
1149                 return false;
1150
1151         op = new0(struct bt_gatt_request, 1);
1152         op->att = att;
1153         op->callback = callback;
1154         op->user_data = user_data;
1155         op->destroy = destroy;
1156         op->start_handle = start;
1157         op->end_handle = end;
1158
1159         put_le16(start, pdu);
1160         put_le16(end, pdu + 2);
1161         put_le16(GATT_INCLUDE_UUID, pdu + 4);
1162
1163         op->id = bt_att_send(att, BT_ATT_OP_READ_BY_TYPE_REQ, pdu, sizeof(pdu),
1164                                 discover_included_cb, bt_gatt_request_ref(op),
1165                                 async_req_unref);
1166         if (!op->id) {
1167                 free(op);
1168                 return NULL;
1169         }
1170
1171         return bt_gatt_request_ref(op);
1172 }
1173
1174 static void discover_chrcs_cb(uint8_t opcode, const void *pdu,
1175                                         uint16_t length, void *user_data)
1176 {
1177         struct bt_gatt_request *op = user_data;
1178         bool success;
1179         uint8_t att_ecode = 0;
1180         size_t data_length;
1181         uint16_t last_handle;
1182
1183         if (opcode == BT_ATT_OP_ERROR_RSP) {
1184                 success = false;
1185                 att_ecode = process_error(pdu, length);
1186                 goto done;
1187         }
1188
1189         /* PDU must contain at least the following (sans opcode):
1190          * - Attr Data Length (1 octet)
1191          * - Attr Data List (at least 7 octets):
1192          *   -- 2 octets: Attribute handle
1193          *   -- 1 octet: Characteristic properties
1194          *   -- 2 octets: Characteristic value handle
1195          *   -- 2 or 16 octets: characteristic UUID
1196          */
1197         if (opcode != BT_ATT_OP_READ_BY_TYPE_RSP || !pdu || length < 8) {
1198                 success = false;
1199                 goto done;
1200         }
1201
1202         data_length = ((uint8_t *) pdu)[0];
1203
1204         if ((data_length != 7 && data_length != 21) ||
1205                                         ((length - 1) % data_length)) {
1206                 success = false;
1207                 goto done;
1208         }
1209
1210         if (!result_append(opcode, pdu + 1, length - 1,
1211                                                         data_length, op)) {
1212                 success = false;
1213                 goto done;
1214         }
1215         last_handle = get_le16(pdu + length - data_length);
1216
1217         /*
1218          * If last handle is lower from previous start handle then it is smth
1219          * wrong. Let's stop search, otherwise we might enter infinite loop.
1220          */
1221         if (last_handle < op->start_handle) {
1222                 success = false;
1223                 goto done;
1224         }
1225
1226         op->start_handle = last_handle + 1;
1227
1228         if (last_handle != op->end_handle) {
1229                 uint8_t pdu[6];
1230
1231                 put_le16(op->start_handle, pdu);
1232                 put_le16(op->end_handle, pdu + 2);
1233                 put_le16(GATT_CHARAC_UUID, pdu + 4);
1234
1235                 op->id = bt_att_send(op->att, BT_ATT_OP_READ_BY_TYPE_REQ,
1236                                                 pdu, sizeof(pdu),
1237                                                 discover_chrcs_cb,
1238                                                 bt_gatt_request_ref(op),
1239                                                 async_req_unref);
1240                 if (op->id)
1241                         return;
1242
1243                 success = false;
1244                 goto done;
1245         }
1246
1247         success = true;
1248
1249 done:
1250         discovery_op_complete(op, success, att_ecode);
1251 }
1252
1253 struct bt_gatt_request *bt_gatt_discover_characteristics(struct bt_att *att,
1254                                         uint16_t start, uint16_t end,
1255                                         bt_gatt_request_callback_t callback,
1256                                         void *user_data,
1257                                         bt_gatt_destroy_func_t destroy)
1258 {
1259         struct bt_gatt_request *op;
1260         uint8_t pdu[6];
1261
1262         if (!att)
1263                 return false;
1264
1265         op = new0(struct bt_gatt_request, 1);
1266         op->att = att;
1267         op->callback = callback;
1268         op->user_data = user_data;
1269         op->destroy = destroy;
1270         op->start_handle = start;
1271         op->end_handle = end;
1272
1273         put_le16(start, pdu);
1274         put_le16(end, pdu + 2);
1275         put_le16(GATT_CHARAC_UUID, pdu + 4);
1276
1277         op->id = bt_att_send(att, BT_ATT_OP_READ_BY_TYPE_REQ, pdu, sizeof(pdu),
1278                                 discover_chrcs_cb, bt_gatt_request_ref(op),
1279                                 async_req_unref);
1280         if (!op->id) {
1281                 free(op);
1282                 return NULL;
1283         }
1284
1285         return bt_gatt_request_ref(op);
1286 }
1287
1288 static void read_by_type_cb(uint8_t opcode, const void *pdu,
1289                                         uint16_t length, void *user_data)
1290 {
1291         struct bt_gatt_request *op = user_data;
1292         bool success;
1293         uint8_t att_ecode = 0;
1294         size_t data_length;
1295         uint16_t last_handle;
1296
1297         if (opcode == BT_ATT_OP_ERROR_RSP) {
1298                 att_ecode = process_error(pdu, length);
1299                 success = false;
1300                 goto done;
1301         }
1302
1303         if (opcode != BT_ATT_OP_READ_BY_TYPE_RSP || !pdu) {
1304                 success = false;
1305                 att_ecode = 0;
1306                 goto done;
1307         }
1308
1309         data_length = ((uint8_t *) pdu)[0];
1310         if (((length - 1) % data_length)) {
1311                 success = false;
1312                 att_ecode = 0;
1313                 goto done;
1314         }
1315
1316         if (!result_append(opcode, pdu + 1, length - 1, data_length, op)) {
1317                 success = false;
1318                 att_ecode = 0;
1319                 goto done;
1320         }
1321
1322         last_handle = get_le16(pdu + length - data_length);
1323
1324         /*
1325          * If last handle is lower from previous start handle then it is smth
1326          * wrong. Let's stop search, otherwise we might enter infinite loop.
1327          */
1328         if (last_handle < op->start_handle) {
1329                 success = false;
1330                 goto done;
1331         }
1332
1333         op->start_handle = last_handle + 1;
1334
1335         if (last_handle != op->end_handle) {
1336                 uint8_t pdu[4 + get_uuid_len(&op->uuid)];
1337
1338                 put_le16(op->start_handle, pdu);
1339                 put_le16(op->end_handle, pdu + 2);
1340                 bt_uuid_to_le(&op->uuid, pdu + 4);
1341
1342                 op->id = bt_att_send(op->att, BT_ATT_OP_READ_BY_TYPE_REQ,
1343                                                 pdu, sizeof(pdu),
1344                                                 read_by_type_cb,
1345                                                 bt_gatt_request_ref(op),
1346                                                 async_req_unref);
1347                 if (op->id)
1348                         return;
1349
1350                 success = false;
1351                 goto done;
1352         }
1353
1354         success = true;
1355
1356 done:
1357         discovery_op_complete(op, success, att_ecode);
1358 }
1359
1360 bool bt_gatt_read_by_type(struct bt_att *att, uint16_t start, uint16_t end,
1361                                         const bt_uuid_t *uuid,
1362                                         bt_gatt_request_callback_t callback,
1363                                         void *user_data,
1364                                         bt_gatt_destroy_func_t destroy)
1365 {
1366         struct bt_gatt_request *op;
1367         uint8_t pdu[4 + get_uuid_len(uuid)];
1368
1369         if (!att || !uuid || uuid->type == BT_UUID_UNSPEC)
1370                 return false;
1371
1372         op = new0(struct bt_gatt_request, 1);
1373         op->att = att;
1374         op->callback = callback;
1375         op->user_data = user_data;
1376         op->destroy = destroy;
1377         op->start_handle = start;
1378         op->end_handle = end;
1379         op->uuid = *uuid;
1380
1381         put_le16(start, pdu);
1382         put_le16(end, pdu + 2);
1383         bt_uuid_to_le(uuid, pdu + 4);
1384
1385         op->id = bt_att_send(att, BT_ATT_OP_READ_BY_TYPE_REQ, pdu, sizeof(pdu),
1386                                                 read_by_type_cb,
1387                                                 bt_gatt_request_ref(op),
1388                                                 async_req_unref);
1389         if (op->id)
1390                 return true;
1391
1392         free(op);
1393         return false;
1394 }
1395
1396 static void discover_descs_cb(uint8_t opcode, const void *pdu,
1397                                         uint16_t length, void *user_data)
1398 {
1399         struct bt_gatt_request *op = user_data;
1400         bool success;
1401         uint8_t att_ecode = 0;
1402         uint8_t format;
1403         uint16_t last_handle;
1404         size_t data_length;
1405
1406         if (opcode == BT_ATT_OP_ERROR_RSP) {
1407                 success = false;
1408                 att_ecode = process_error(pdu, length);
1409                 goto done;
1410         }
1411
1412         /* The PDU should contain the following data (sans opcode):
1413          * - Format (1 octet)
1414          * - Attr Data List (at least 4 octets):
1415          *   -- 2 octets: Attribute handle
1416          *   -- 2 or 16 octets: UUID.
1417          */
1418         if (opcode != BT_ATT_OP_FIND_INFO_RSP || !pdu || length < 5) {
1419                 success = false;
1420                 goto done;
1421         }
1422
1423         format = ((uint8_t *) pdu)[0];
1424
1425         if (format == 0x01)
1426                 data_length = 4;
1427         else if (format == 0x02)
1428                 data_length = 18;
1429         else {
1430                 success = false;
1431                 goto done;
1432         }
1433
1434         if ((length - 1) % data_length) {
1435                 success = false;
1436                 goto done;
1437         }
1438
1439         if (!result_append(opcode, pdu + 1, length - 1, data_length, op)) {
1440                 success = false;
1441                 goto done;
1442         }
1443
1444         last_handle = get_le16(pdu + length - data_length);
1445
1446         /*
1447          * If last handle is lower from previous start handle then it is smth
1448          * wrong. Let's stop search, otherwise we might enter infinite loop.
1449          */
1450         if (last_handle < op->start_handle) {
1451                 success = false;
1452                 goto done;
1453         }
1454
1455         op->start_handle = last_handle + 1;
1456
1457         if (last_handle != op->end_handle) {
1458                 uint8_t pdu[4];
1459
1460                 put_le16(op->start_handle, pdu);
1461                 put_le16(op->end_handle, pdu + 2);
1462
1463                 op->id = bt_att_send(op->att, BT_ATT_OP_FIND_INFO_REQ,
1464                                                 pdu, sizeof(pdu),
1465                                                 discover_descs_cb,
1466                                                 bt_gatt_request_ref(op),
1467                                                 async_req_unref);
1468                 if (op->id)
1469                         return;
1470
1471                 success = false;
1472                 goto done;
1473         }
1474
1475         success = true;
1476
1477 done:
1478         discovery_op_complete(op, success, att_ecode);
1479 }
1480
1481 struct bt_gatt_request *bt_gatt_discover_descriptors(struct bt_att *att,
1482                                         uint16_t start, uint16_t end,
1483                                         bt_gatt_request_callback_t callback,
1484                                         void *user_data,
1485                                         bt_gatt_destroy_func_t destroy)
1486 {
1487         struct bt_gatt_request *op;
1488         uint8_t pdu[4];
1489
1490         if (!att)
1491                 return false;
1492
1493         op = new0(struct bt_gatt_request, 1);
1494         op->att = att;
1495         op->callback = callback;
1496         op->user_data = user_data;
1497         op->destroy = destroy;
1498         op->start_handle = start;
1499         op->end_handle = end;
1500
1501         put_le16(start, pdu);
1502         put_le16(end, pdu + 2);
1503
1504         op->id = bt_att_send(att, BT_ATT_OP_FIND_INFO_REQ, pdu, sizeof(pdu),
1505                                                 discover_descs_cb,
1506                                                 bt_gatt_request_ref(op),
1507                                                 async_req_unref);
1508         if (!op->id) {
1509                 free(op);
1510                 return NULL;
1511         }
1512
1513         return bt_gatt_request_ref(op);
1514 }