~vanvugt/ubuntu/xenial/bluez/trunk

« back to all changes in this revision

Viewing changes to src/shared/gatt-db.c

  • Committer: Daniel van Vugt
  • Date: 2017-05-24 07:16:52 UTC
  • Revision ID: daniel.van.vugt@canonical.com-20170524071652-8fnev589l3n104m1
Initial import from xenial

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *
 
3
 *  BlueZ - Bluetooth protocol stack for Linux
 
4
 *
 
5
 *  Copyright (C) 2014  Intel Corporation. All rights reserved.
 
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 <stdbool.h>
 
29
#include <errno.h>
 
30
 
 
31
#include "lib/bluetooth.h"
 
32
#include "lib/uuid.h"
 
33
#include "src/shared/util.h"
 
34
#include "src/shared/queue.h"
 
35
#include "src/shared/timeout.h"
 
36
#include "src/shared/att.h"
 
37
#include "src/shared/gatt-db.h"
 
38
 
 
39
#ifndef MAX
 
40
#define MAX(a, b) ((a) > (b) ? (a) : (b))
 
41
#endif
 
42
 
 
43
#define MAX_CHAR_DECL_VALUE_LEN 19
 
44
#define MAX_INCLUDED_VALUE_LEN 6
 
45
#define ATTRIBUTE_TIMEOUT 5000
 
46
 
 
47
static const bt_uuid_t primary_service_uuid = { .type = BT_UUID16,
 
48
                                        .value.u16 = GATT_PRIM_SVC_UUID };
 
49
static const bt_uuid_t secondary_service_uuid = { .type = BT_UUID16,
 
50
                                        .value.u16 = GATT_SND_SVC_UUID };
 
51
static const bt_uuid_t characteristic_uuid = { .type = BT_UUID16,
 
52
                                        .value.u16 = GATT_CHARAC_UUID };
 
53
static const bt_uuid_t included_service_uuid = { .type = BT_UUID16,
 
54
                                        .value.u16 = GATT_INCLUDE_UUID };
 
55
 
 
56
struct gatt_db {
 
57
        int ref_count;
 
58
        uint16_t next_handle;
 
59
        struct queue *services;
 
60
 
 
61
        struct queue *notify_list;
 
62
        unsigned int next_notify_id;
 
63
};
 
64
 
 
65
struct notify {
 
66
        unsigned int id;
 
67
        gatt_db_attribute_cb_t service_added;
 
68
        gatt_db_attribute_cb_t service_removed;
 
69
        gatt_db_destroy_func_t destroy;
 
70
        void *user_data;
 
71
};
 
72
 
 
73
struct pending_read {
 
74
        struct gatt_db_attribute *attrib;
 
75
        unsigned int id;
 
76
        unsigned int timeout_id;
 
77
        gatt_db_attribute_read_t func;
 
78
        void *user_data;
 
79
};
 
80
 
 
81
struct pending_write {
 
82
        struct gatt_db_attribute *attrib;
 
83
        unsigned int id;
 
84
        unsigned int timeout_id;
 
85
        gatt_db_attribute_write_t func;
 
86
        void *user_data;
 
87
};
 
88
 
 
89
struct gatt_db_attribute {
 
90
        struct gatt_db_service *service;
 
91
        uint16_t handle;
 
92
        bt_uuid_t uuid;
 
93
        uint32_t permissions;
 
94
        uint16_t value_len;
 
95
        uint8_t *value;
 
96
 
 
97
        gatt_db_read_t read_func;
 
98
        gatt_db_write_t write_func;
 
99
        void *user_data;
 
100
 
 
101
        unsigned int read_id;
 
102
        struct queue *pending_reads;
 
103
 
 
104
        unsigned int write_id;
 
105
        struct queue *pending_writes;
 
106
};
 
107
 
 
108
struct gatt_db_service {
 
109
        struct gatt_db *db;
 
110
        bool active;
 
111
        bool claimed;
 
112
        uint16_t num_handles;
 
113
        struct gatt_db_attribute **attributes;
 
114
};
 
115
 
 
116
static void pending_read_result(struct pending_read *p, int err,
 
117
                                        const uint8_t *data, size_t length)
 
118
{
 
119
        if (p->timeout_id > 0)
 
120
                timeout_remove(p->timeout_id);
 
121
 
 
122
        p->func(p->attrib, err, data, length, p->user_data);
 
123
 
 
124
        free(p);
 
125
}
 
126
 
 
127
static void pending_read_free(void *data)
 
128
{
 
129
        struct pending_read *p = data;
 
130
 
 
131
        pending_read_result(p, -ECANCELED, NULL, 0);
 
132
}
 
133
 
 
134
static void pending_write_result(struct pending_write *p, int err)
 
135
{
 
136
        if (p->timeout_id > 0)
 
137
                timeout_remove(p->timeout_id);
 
138
 
 
139
        p->func(p->attrib, err, p->user_data);
 
140
 
 
141
        free(p);
 
142
}
 
143
 
 
144
static void pending_write_free(void *data)
 
145
{
 
146
        struct pending_write *p = data;
 
147
 
 
148
        pending_write_result(p, -ECANCELED);
 
149
}
 
150
 
 
151
static void attribute_destroy(struct gatt_db_attribute *attribute)
 
152
{
 
153
        /* Attribute was not initialized by user */
 
154
        if (!attribute)
 
155
                return;
 
156
 
 
157
        queue_destroy(attribute->pending_reads, pending_read_free);
 
158
        queue_destroy(attribute->pending_writes, pending_write_free);
 
159
 
 
160
        free(attribute->value);
 
161
        free(attribute);
 
162
}
 
163
 
 
164
static struct gatt_db_attribute *new_attribute(struct gatt_db_service *service,
 
165
                                                        uint16_t handle,
 
166
                                                        const bt_uuid_t *type,
 
167
                                                        const uint8_t *val,
 
168
                                                        uint16_t len)
 
169
{
 
170
        struct gatt_db_attribute *attribute;
 
171
 
 
172
        attribute = new0(struct gatt_db_attribute, 1);
 
173
 
 
174
        attribute->service = service;
 
175
        attribute->handle = handle;
 
176
        attribute->uuid = *type;
 
177
        attribute->value_len = len;
 
178
        if (len) {
 
179
                attribute->value = malloc0(len);
 
180
                if (!attribute->value)
 
181
                        goto failed;
 
182
 
 
183
                memcpy(attribute->value, val, len);
 
184
        }
 
185
 
 
186
        attribute->pending_reads = queue_new();
 
187
        attribute->pending_writes = queue_new();
 
188
 
 
189
        return attribute;
 
190
 
 
191
failed:
 
192
        attribute_destroy(attribute);
 
193
        return NULL;
 
194
}
 
195
 
 
196
struct gatt_db *gatt_db_ref(struct gatt_db *db)
 
197
{
 
198
        if (!db)
 
199
                return NULL;
 
200
 
 
201
        __sync_fetch_and_add(&db->ref_count, 1);
 
202
 
 
203
        return db;
 
204
}
 
205
 
 
206
struct gatt_db *gatt_db_new(void)
 
207
{
 
208
        struct gatt_db *db;
 
209
 
 
210
        db = new0(struct gatt_db, 1);
 
211
        db->services = queue_new();
 
212
        db->notify_list = queue_new();
 
213
        db->next_handle = 0x0001;
 
214
 
 
215
        return gatt_db_ref(db);
 
216
}
 
217
 
 
218
static void notify_destroy(void *data)
 
219
{
 
220
        struct notify *notify = data;
 
221
 
 
222
        if (notify->destroy)
 
223
                notify->destroy(notify->user_data);
 
224
 
 
225
        free(notify);
 
226
}
 
227
 
 
228
static bool match_notify_id(const void *a, const void *b)
 
229
{
 
230
        const struct notify *notify = a;
 
231
        unsigned int id = PTR_TO_UINT(b);
 
232
 
 
233
        return notify->id == id;
 
234
}
 
235
 
 
236
struct notify_data {
 
237
        struct gatt_db_attribute *attr;
 
238
        bool added;
 
239
};
 
240
 
 
241
static void handle_notify(void *data, void *user_data)
 
242
{
 
243
        struct notify *notify = data;
 
244
        struct notify_data *notify_data = user_data;
 
245
 
 
246
        if (notify_data->added)
 
247
                notify->service_added(notify_data->attr, notify->user_data);
 
248
        else
 
249
                notify->service_removed(notify_data->attr, notify->user_data);
 
250
}
 
251
 
 
252
static void notify_service_changed(struct gatt_db *db,
 
253
                                                struct gatt_db_service *service,
 
254
                                                bool added)
 
255
{
 
256
        struct notify_data data;
 
257
 
 
258
        if (queue_isempty(db->notify_list))
 
259
                return;
 
260
 
 
261
        data.attr = service->attributes[0];
 
262
        data.added = added;
 
263
 
 
264
        gatt_db_ref(db);
 
265
 
 
266
        queue_foreach(db->notify_list, handle_notify, &data);
 
267
 
 
268
        gatt_db_unref(db);
 
269
}
 
270
 
 
271
static void gatt_db_service_destroy(void *data)
 
272
{
 
273
        struct gatt_db_service *service = data;
 
274
        int i;
 
275
 
 
276
        if (service->active)
 
277
                notify_service_changed(service->db, service, false);
 
278
 
 
279
        for (i = 0; i < service->num_handles; i++)
 
280
                attribute_destroy(service->attributes[i]);
 
281
 
 
282
        free(service->attributes);
 
283
        free(service);
 
284
}
 
285
 
 
286
static void gatt_db_destroy(struct gatt_db *db)
 
287
{
 
288
        if (!db)
 
289
                return;
 
290
 
 
291
        /*
 
292
         * Clear the notify list before clearing the services to prevent the
 
293
         * latter from sending service_removed events.
 
294
         */
 
295
        queue_destroy(db->notify_list, notify_destroy);
 
296
        db->notify_list = NULL;
 
297
 
 
298
        queue_destroy(db->services, gatt_db_service_destroy);
 
299
        free(db);
 
300
}
 
301
 
 
302
void gatt_db_unref(struct gatt_db *db)
 
303
{
 
304
        if (!db)
 
305
                return;
 
306
 
 
307
        if (__sync_sub_and_fetch(&db->ref_count, 1))
 
308
                return;
 
309
 
 
310
        gatt_db_destroy(db);
 
311
}
 
312
 
 
313
bool gatt_db_isempty(struct gatt_db *db)
 
314
{
 
315
        if (!db)
 
316
                return true;
 
317
 
 
318
        return queue_isempty(db->services);
 
319
}
 
320
 
 
321
static int uuid_to_le(const bt_uuid_t *uuid, uint8_t *dst)
 
322
{
 
323
        bt_uuid_t uuid128;
 
324
 
 
325
        if (uuid->type == BT_UUID16) {
 
326
                put_le16(uuid->value.u16, dst);
 
327
                return bt_uuid_len(uuid);
 
328
        }
 
329
 
 
330
        bt_uuid_to_uuid128(uuid, &uuid128);
 
331
        bswap_128(&uuid128.value.u128, dst);
 
332
        return bt_uuid_len(&uuid128);
 
333
}
 
334
 
 
335
static bool le_to_uuid(const uint8_t *src, size_t len, bt_uuid_t *uuid)
 
336
{
 
337
        uint128_t u128;
 
338
 
 
339
        if (len == 2) {
 
340
                bt_uuid16_create(uuid, get_le16(src));
 
341
                return true;
 
342
        }
 
343
 
 
344
        if (len == 4) {
 
345
                bt_uuid32_create(uuid, get_le32(src));
 
346
                return true;
 
347
        }
 
348
 
 
349
        if (len != 16)
 
350
                return false;
 
351
 
 
352
        bswap_128(src, &u128);
 
353
        bt_uuid128_create(uuid, u128);
 
354
 
 
355
        return true;
 
356
}
 
357
 
 
358
static struct gatt_db_service *gatt_db_service_create(const bt_uuid_t *uuid,
 
359
                                                        uint16_t handle,
 
360
                                                        bool primary,
 
361
                                                        uint16_t num_handles)
 
362
{
 
363
        struct gatt_db_service *service;
 
364
        const bt_uuid_t *type;
 
365
        uint8_t value[16];
 
366
        uint16_t len;
 
367
 
 
368
        if (num_handles < 1)
 
369
                return NULL;
 
370
 
 
371
        service = new0(struct gatt_db_service, 1);
 
372
        service->attributes = new0(struct gatt_db_attribute *, num_handles);
 
373
 
 
374
        if (primary)
 
375
                type = &primary_service_uuid;
 
376
        else
 
377
                type = &secondary_service_uuid;
 
378
 
 
379
        len = uuid_to_le(uuid, value);
 
380
 
 
381
        service->attributes[0] = new_attribute(service, handle, type, value,
 
382
                                                                        len);
 
383
        if (!service->attributes[0]) {
 
384
                gatt_db_service_destroy(service);
 
385
                return NULL;
 
386
        }
 
387
 
 
388
        return service;
 
389
}
 
390
 
 
391
 
 
392
bool gatt_db_remove_service(struct gatt_db *db,
 
393
                                        struct gatt_db_attribute *attrib)
 
394
{
 
395
        struct gatt_db_service *service;
 
396
 
 
397
        if (!db || !attrib)
 
398
                return false;
 
399
 
 
400
        service = attrib->service;
 
401
 
 
402
        queue_remove(db->services, service);
 
403
 
 
404
        gatt_db_service_destroy(service);
 
405
 
 
406
        return true;
 
407
}
 
408
 
 
409
bool gatt_db_clear(struct gatt_db *db)
 
410
{
 
411
        if (!db)
 
412
                return false;
 
413
 
 
414
        queue_remove_all(db->services, NULL, NULL, gatt_db_service_destroy);
 
415
 
 
416
        db->next_handle = 0;
 
417
 
 
418
        return true;
 
419
}
 
420
 
 
421
static void gatt_db_service_get_handles(const struct gatt_db_service *service,
 
422
                                                        uint16_t *start_handle,
 
423
                                                        uint16_t *end_handle)
 
424
{
 
425
        if (start_handle)
 
426
                *start_handle = service->attributes[0]->handle;
 
427
 
 
428
        if (end_handle)
 
429
                *end_handle = service->attributes[0]->handle +
 
430
                                                service->num_handles - 1;
 
431
}
 
432
 
 
433
struct clear_range {
 
434
        uint16_t start, end;
 
435
};
 
436
 
 
437
static bool match_range(const void *a, const void *b)
 
438
{
 
439
        const struct gatt_db_service *service = a;
 
440
        const struct clear_range *range = b;
 
441
        uint16_t svc_start, svc_end;
 
442
 
 
443
        gatt_db_service_get_handles(service, &svc_start, &svc_end);
 
444
 
 
445
        return svc_start <= range->end && svc_end >= range->start;
 
446
}
 
447
 
 
448
bool gatt_db_clear_range(struct gatt_db *db, uint16_t start_handle,
 
449
                                                        uint16_t end_handle)
 
450
{
 
451
        struct clear_range range;
 
452
 
 
453
        if (!db || start_handle > end_handle)
 
454
                return false;
 
455
 
 
456
        range.start = start_handle;
 
457
        range.end = end_handle;
 
458
 
 
459
        queue_remove_all(db->services, match_range, &range,
 
460
                                                gatt_db_service_destroy);
 
461
 
 
462
        return true;
 
463
}
 
464
 
 
465
static struct gatt_db_service *find_insert_loc(struct gatt_db *db,
 
466
                                                uint16_t start, uint16_t end,
 
467
                                                struct gatt_db_service **after)
 
468
{
 
469
        const struct queue_entry *services_entry;
 
470
        struct gatt_db_service *service;
 
471
        uint16_t cur_start, cur_end;
 
472
 
 
473
        *after = NULL;
 
474
 
 
475
        services_entry = queue_get_entries(db->services);
 
476
 
 
477
        while (services_entry) {
 
478
                service = services_entry->data;
 
479
 
 
480
                gatt_db_service_get_handles(service, &cur_start, &cur_end);
 
481
 
 
482
                if (start >= cur_start && start <= cur_end)
 
483
                        return service;
 
484
 
 
485
                if (end >= cur_start && end <= cur_end)
 
486
                        return service;
 
487
 
 
488
                if (end < cur_start)
 
489
                        return NULL;
 
490
 
 
491
                *after = service;
 
492
                services_entry = services_entry->next;
 
493
        }
 
494
 
 
495
        return NULL;
 
496
}
 
497
 
 
498
struct gatt_db_attribute *gatt_db_insert_service(struct gatt_db *db,
 
499
                                                        uint16_t handle,
 
500
                                                        const bt_uuid_t *uuid,
 
501
                                                        bool primary,
 
502
                                                        uint16_t num_handles)
 
503
{
 
504
        struct gatt_db_service *service, *after;
 
505
 
 
506
        after = NULL;
 
507
 
 
508
        if (!db || handle < 1)
 
509
                return NULL;
 
510
 
 
511
        if (num_handles < 1 || (handle + num_handles - 1) > UINT16_MAX)
 
512
                return NULL;
 
513
 
 
514
        service = find_insert_loc(db, handle, handle + num_handles - 1, &after);
 
515
        if (service) {
 
516
                const bt_uuid_t *type;
 
517
                bt_uuid_t value;
 
518
 
 
519
                if (primary)
 
520
                        type = &primary_service_uuid;
 
521
                else
 
522
                        type = &secondary_service_uuid;
 
523
 
 
524
                gatt_db_attribute_get_service_uuid(service->attributes[0],
 
525
                                                                        &value);
 
526
 
 
527
                /* Check if service match */
 
528
                if (!bt_uuid_cmp(&service->attributes[0]->uuid, type) &&
 
529
                                !bt_uuid_cmp(&value, uuid) &&
 
530
                                service->num_handles == num_handles &&
 
531
                                service->attributes[0]->handle == handle)
 
532
                        return service->attributes[0];
 
533
 
 
534
                return NULL;
 
535
        }
 
536
 
 
537
        service = gatt_db_service_create(uuid, handle, primary, num_handles);
 
538
 
 
539
        if (!service)
 
540
                return NULL;
 
541
 
 
542
        if (after) {
 
543
                if (!queue_push_after(db->services, after, service))
 
544
                        goto fail;
 
545
        } else if (!queue_push_head(db->services, service)) {
 
546
                goto fail;
 
547
        }
 
548
 
 
549
        service->db = db;
 
550
        service->attributes[0]->handle = handle;
 
551
        service->num_handles = num_handles;
 
552
 
 
553
        /* Fast-forward next_handle if the new service was added to the end */
 
554
        db->next_handle = MAX(handle + num_handles, db->next_handle);
 
555
 
 
556
        return service->attributes[0];
 
557
 
 
558
fail:
 
559
        gatt_db_service_destroy(service);
 
560
        return NULL;
 
561
}
 
562
 
 
563
struct gatt_db_attribute *gatt_db_add_service(struct gatt_db *db,
 
564
                                                const bt_uuid_t *uuid,
 
565
                                                bool primary,
 
566
                                                uint16_t num_handles)
 
567
{
 
568
        return gatt_db_insert_service(db, db->next_handle, uuid, primary,
 
569
                                                                num_handles);
 
570
}
 
571
 
 
572
unsigned int gatt_db_register(struct gatt_db *db,
 
573
                                        gatt_db_attribute_cb_t service_added,
 
574
                                        gatt_db_attribute_cb_t service_removed,
 
575
                                        void *user_data,
 
576
                                        gatt_db_destroy_func_t destroy)
 
577
{
 
578
        struct notify *notify;
 
579
 
 
580
        if (!db || !(service_added || service_removed))
 
581
                return 0;
 
582
 
 
583
        notify = new0(struct notify, 1);
 
584
        notify->service_added = service_added;
 
585
        notify->service_removed = service_removed;
 
586
        notify->destroy = destroy;
 
587
        notify->user_data = user_data;
 
588
 
 
589
        if (db->next_notify_id < 1)
 
590
                db->next_notify_id = 1;
 
591
 
 
592
        notify->id = db->next_notify_id++;
 
593
 
 
594
        if (!queue_push_tail(db->notify_list, notify)) {
 
595
                free(notify);
 
596
                return 0;
 
597
        }
 
598
 
 
599
        return notify->id;
 
600
}
 
601
 
 
602
bool gatt_db_unregister(struct gatt_db *db, unsigned int id)
 
603
{
 
604
        struct notify *notify;
 
605
 
 
606
        if (!db || !id)
 
607
                return false;
 
608
 
 
609
        notify = queue_find(db->notify_list, match_notify_id, UINT_TO_PTR(id));
 
610
        if (!notify)
 
611
                return false;
 
612
 
 
613
        queue_remove(db->notify_list, notify);
 
614
        notify_destroy(notify);
 
615
 
 
616
        return true;
 
617
}
 
618
 
 
619
static uint16_t get_attribute_index(struct gatt_db_service *service,
 
620
                                                        int end_offset)
 
621
{
 
622
        int i = 0;
 
623
 
 
624
        /* Here we look for first free attribute index with given offset */
 
625
        while (i < (service->num_handles - end_offset) &&
 
626
                                                service->attributes[i])
 
627
                i++;
 
628
 
 
629
        return i == (service->num_handles - end_offset) ? 0 : i;
 
630
}
 
631
 
 
632
static uint16_t get_handle_at_index(struct gatt_db_service *service,
 
633
                                                                int index)
 
634
{
 
635
        return service->attributes[index]->handle;
 
636
}
 
637
 
 
638
static struct gatt_db_attribute *
 
639
attribute_update(struct gatt_db_service *service, int index)
 
640
{
 
641
        uint16_t previous_handle;
 
642
 
 
643
        /* We call this function with index > 0, because index 0 is reserved
 
644
         * for service declaration, and is set in add_service()
 
645
         */
 
646
        previous_handle = service->attributes[index - 1]->handle;
 
647
        service->attributes[index]->handle = previous_handle + 1;
 
648
 
 
649
        return service->attributes[index];
 
650
}
 
651
 
 
652
static void set_attribute_data(struct gatt_db_attribute *attribute,
 
653
                                                gatt_db_read_t read_func,
 
654
                                                gatt_db_write_t write_func,
 
655
                                                uint32_t permissions,
 
656
                                                void *user_data)
 
657
{
 
658
        attribute->permissions = permissions;
 
659
        attribute->read_func = read_func;
 
660
        attribute->write_func = write_func;
 
661
        attribute->user_data = user_data;
 
662
}
 
663
 
 
664
static struct gatt_db_attribute *
 
665
service_insert_characteristic(struct gatt_db_service *service,
 
666
                                        uint16_t handle,
 
667
                                        const bt_uuid_t *uuid,
 
668
                                        uint32_t permissions,
 
669
                                        uint8_t properties,
 
670
                                        gatt_db_read_t read_func,
 
671
                                        gatt_db_write_t write_func,
 
672
                                        void *user_data)
 
673
{
 
674
        uint8_t value[MAX_CHAR_DECL_VALUE_LEN];
 
675
        uint16_t len = 0;
 
676
        int i;
 
677
 
 
678
        /* Check if handle is in within service range */
 
679
        if (handle && handle <= service->attributes[0]->handle)
 
680
                return NULL;
 
681
 
 
682
        /*
 
683
         * It is not possible to allocate last handle for a Characteristic
 
684
         * since it would not have space for its value:
 
685
         * 3.3.2 Characteristic Value Declaration
 
686
         * The Characteristic Value declaration contains the value of the
 
687
         * characteristic. It is the first Attribute after the characteristic
 
688
         * declaration. All characteristic definitions shall have a
 
689
         * Characteristic Value declaration.
 
690
         */
 
691
        if (handle == UINT16_MAX)
 
692
                return NULL;
 
693
 
 
694
        i = get_attribute_index(service, 1);
 
695
        if (!i)
 
696
                return NULL;
 
697
 
 
698
        if (!handle)
 
699
                handle = get_handle_at_index(service, i - 1) + 2;
 
700
 
 
701
        value[0] = properties;
 
702
        len += sizeof(properties);
 
703
 
 
704
        /* We set handle of characteristic value, which will be added next */
 
705
        put_le16(handle, &value[1]);
 
706
        len += sizeof(uint16_t);
 
707
        len += uuid_to_le(uuid, &value[3]);
 
708
 
 
709
        service->attributes[i] = new_attribute(service, handle - 1,
 
710
                                                        &characteristic_uuid,
 
711
                                                        value, len);
 
712
        if (!service->attributes[i])
 
713
                return NULL;
 
714
 
 
715
        i++;
 
716
 
 
717
        service->attributes[i] = new_attribute(service, handle, uuid, NULL, 0);
 
718
        if (!service->attributes[i]) {
 
719
                free(service->attributes[i - 1]);
 
720
                return NULL;
 
721
        }
 
722
 
 
723
        set_attribute_data(service->attributes[i], read_func, write_func,
 
724
                                                        permissions, user_data);
 
725
 
 
726
        return service->attributes[i];
 
727
}
 
728
 
 
729
struct gatt_db_attribute *
 
730
gatt_db_service_insert_characteristic(struct gatt_db_attribute *attrib,
 
731
                                        uint16_t handle,
 
732
                                        const bt_uuid_t *uuid,
 
733
                                        uint32_t permissions,
 
734
                                        uint8_t properties,
 
735
                                        gatt_db_read_t read_func,
 
736
                                        gatt_db_write_t write_func,
 
737
                                        void *user_data)
 
738
{
 
739
        if (!attrib || !handle)
 
740
                return NULL;
 
741
 
 
742
        return service_insert_characteristic(attrib->service, handle, uuid,
 
743
                                                permissions, properties,
 
744
                                                read_func, write_func,
 
745
                                                user_data);
 
746
}
 
747
 
 
748
struct gatt_db_attribute *
 
749
gatt_db_service_add_characteristic(struct gatt_db_attribute *attrib,
 
750
                                        const bt_uuid_t *uuid,
 
751
                                        uint32_t permissions,
 
752
                                        uint8_t properties,
 
753
                                        gatt_db_read_t read_func,
 
754
                                        gatt_db_write_t write_func,
 
755
                                        void *user_data)
 
756
{
 
757
        if (!attrib)
 
758
                return NULL;
 
759
 
 
760
        return service_insert_characteristic(attrib->service, 0, uuid,
 
761
                                                permissions, properties,
 
762
                                                read_func, write_func,
 
763
                                                user_data);
 
764
}
 
765
 
 
766
static struct gatt_db_attribute *
 
767
service_insert_descriptor(struct gatt_db_service *service,
 
768
                                        uint16_t handle,
 
769
                                        const bt_uuid_t *uuid,
 
770
                                        uint32_t permissions,
 
771
                                        gatt_db_read_t read_func,
 
772
                                        gatt_db_write_t write_func,
 
773
                                        void *user_data)
 
774
{
 
775
        int i;
 
776
 
 
777
        i = get_attribute_index(service, 0);
 
778
        if (!i)
 
779
                return NULL;
 
780
 
 
781
        /* Check if handle is in within service range */
 
782
        if (handle && handle <= service->attributes[0]->handle)
 
783
                return NULL;
 
784
 
 
785
        if (!handle)
 
786
                handle = get_handle_at_index(service, i - 1) + 1;
 
787
 
 
788
        service->attributes[i] = new_attribute(service, handle, uuid, NULL, 0);
 
789
        if (!service->attributes[i])
 
790
                return NULL;
 
791
 
 
792
        set_attribute_data(service->attributes[i], read_func, write_func,
 
793
                                                        permissions, user_data);
 
794
 
 
795
        return service->attributes[i];
 
796
}
 
797
 
 
798
struct gatt_db_attribute *
 
799
gatt_db_service_insert_descriptor(struct gatt_db_attribute *attrib,
 
800
                                        uint16_t handle,
 
801
                                        const bt_uuid_t *uuid,
 
802
                                        uint32_t permissions,
 
803
                                        gatt_db_read_t read_func,
 
804
                                        gatt_db_write_t write_func,
 
805
                                        void *user_data)
 
806
{
 
807
        if (!attrib || !handle)
 
808
                return NULL;
 
809
 
 
810
        return service_insert_descriptor(attrib->service, handle, uuid,
 
811
                                        permissions, read_func, write_func,
 
812
                                        user_data);
 
813
}
 
814
 
 
815
struct gatt_db_attribute *
 
816
gatt_db_service_add_descriptor(struct gatt_db_attribute *attrib,
 
817
                                        const bt_uuid_t *uuid,
 
818
                                        uint32_t permissions,
 
819
                                        gatt_db_read_t read_func,
 
820
                                        gatt_db_write_t write_func,
 
821
                                        void *user_data)
 
822
{
 
823
        if (!attrib)
 
824
                return NULL;
 
825
 
 
826
        return service_insert_descriptor(attrib->service, 0, uuid,
 
827
                                        permissions, read_func, write_func,
 
828
                                        user_data);
 
829
}
 
830
 
 
831
struct gatt_db_attribute *
 
832
gatt_db_service_add_included(struct gatt_db_attribute *attrib,
 
833
                                        struct gatt_db_attribute *include)
 
834
{
 
835
        struct gatt_db_service *service, *included;
 
836
        uint8_t value[MAX_INCLUDED_VALUE_LEN];
 
837
        uint16_t included_handle, len = 0;
 
838
        int index;
 
839
 
 
840
        if (!attrib || !include)
 
841
                return NULL;
 
842
 
 
843
        service = attrib->service;
 
844
        included = include->service;
 
845
 
 
846
        /* Adjust include to point to the first attribute */
 
847
        if (include != included->attributes[0])
 
848
                include = included->attributes[0];
 
849
 
 
850
        included_handle = include->handle;
 
851
 
 
852
        put_le16(included_handle, &value[len]);
 
853
        len += sizeof(uint16_t);
 
854
 
 
855
        put_le16(included_handle + included->num_handles - 1, &value[len]);
 
856
        len += sizeof(uint16_t);
 
857
 
 
858
        /* The Service UUID shall only be present when the UUID is a 16-bit
 
859
         * Bluetooth UUID. Vol 2. Part G. 3.2
 
860
         */
 
861
        if (include->value_len == sizeof(uint16_t)) {
 
862
                memcpy(&value[len], include->value, include->value_len);
 
863
                len += include->value_len;
 
864
        }
 
865
 
 
866
        index = get_attribute_index(service, 0);
 
867
        if (!index)
 
868
                return NULL;
 
869
 
 
870
        service->attributes[index] = new_attribute(service, 0,
 
871
                                                        &included_service_uuid,
 
872
                                                        value, len);
 
873
        if (!service->attributes[index])
 
874
                return NULL;
 
875
 
 
876
        /* The Attribute Permissions shall be read only and not require
 
877
         * authentication or authorization. Vol 2. Part G. 3.2
 
878
         *
 
879
         * TODO handle permissions
 
880
         */
 
881
        set_attribute_data(service->attributes[index], NULL, NULL, 0, NULL);
 
882
 
 
883
        return attribute_update(service, index);
 
884
}
 
885
 
 
886
bool gatt_db_service_set_active(struct gatt_db_attribute *attrib, bool active)
 
887
{
 
888
        struct gatt_db_service *service;
 
889
 
 
890
        if (!attrib)
 
891
                return false;
 
892
 
 
893
        service = attrib->service;
 
894
 
 
895
        if (service->active == active)
 
896
                return true;
 
897
 
 
898
        service->active = active;
 
899
 
 
900
        notify_service_changed(service->db, service, active);
 
901
 
 
902
        return true;
 
903
}
 
904
 
 
905
bool gatt_db_service_get_active(struct gatt_db_attribute *attrib)
 
906
{
 
907
        if (!attrib)
 
908
                return false;
 
909
 
 
910
        return attrib->service->active;
 
911
}
 
912
 
 
913
bool gatt_db_service_set_claimed(struct gatt_db_attribute *attrib,
 
914
                                                                bool claimed)
 
915
{
 
916
        if (!attrib)
 
917
                return false;
 
918
 
 
919
        attrib->service->claimed = claimed;
 
920
 
 
921
        return true;
 
922
}
 
923
 
 
924
bool gatt_db_service_get_claimed(struct gatt_db_attribute *attrib)
 
925
{
 
926
        if (!attrib)
 
927
                return false;
 
928
 
 
929
        return attrib->service->claimed;
 
930
}
 
931
 
 
932
void gatt_db_read_by_group_type(struct gatt_db *db, uint16_t start_handle,
 
933
                                                        uint16_t end_handle,
 
934
                                                        const bt_uuid_t type,
 
935
                                                        struct queue *queue)
 
936
{
 
937
        const struct queue_entry *services_entry;
 
938
        struct gatt_db_service *service;
 
939
        uint16_t grp_start, grp_end, uuid_size;
 
940
 
 
941
        uuid_size = 0;
 
942
 
 
943
        services_entry = queue_get_entries(db->services);
 
944
 
 
945
        while (services_entry) {
 
946
                service = services_entry->data;
 
947
 
 
948
                if (!service->active)
 
949
                        goto next_service;
 
950
 
 
951
                if (bt_uuid_cmp(&type, &service->attributes[0]->uuid))
 
952
                        goto next_service;
 
953
 
 
954
                grp_start = service->attributes[0]->handle;
 
955
                grp_end = grp_start + service->num_handles - 1;
 
956
 
 
957
                if (grp_end < start_handle || grp_start > end_handle)
 
958
                        goto next_service;
 
959
 
 
960
                if (grp_start < start_handle || grp_start > end_handle)
 
961
                        goto next_service;
 
962
 
 
963
                if (!uuid_size)
 
964
                        uuid_size = service->attributes[0]->value_len;
 
965
                else if (uuid_size != service->attributes[0]->value_len)
 
966
                        return;
 
967
 
 
968
                queue_push_tail(queue, service->attributes[0]);
 
969
 
 
970
next_service:
 
971
                services_entry = services_entry->next;
 
972
        }
 
973
}
 
974
 
 
975
struct find_by_type_value_data {
 
976
        bt_uuid_t uuid;
 
977
        uint16_t start_handle;
 
978
        uint16_t end_handle;
 
979
        gatt_db_attribute_cb_t func;
 
980
        void *user_data;
 
981
        const void *value;
 
982
        size_t value_len;
 
983
        unsigned int num_of_res;
 
984
};
 
985
 
 
986
static void find_by_type(void *data, void *user_data)
 
987
{
 
988
        struct find_by_type_value_data *search_data = user_data;
 
989
        struct gatt_db_service *service = data;
 
990
        struct gatt_db_attribute *attribute;
 
991
        int i;
 
992
 
 
993
        if (!service->active)
 
994
                return;
 
995
 
 
996
        for (i = 0; i < service->num_handles; i++) {
 
997
                attribute = service->attributes[i];
 
998
 
 
999
                if (!attribute)
 
1000
                        continue;
 
1001
 
 
1002
                if ((attribute->handle < search_data->start_handle) ||
 
1003
                                (attribute->handle > search_data->end_handle))
 
1004
                        continue;
 
1005
 
 
1006
                if (bt_uuid_cmp(&search_data->uuid, &attribute->uuid))
 
1007
                        continue;
 
1008
 
 
1009
                /* TODO: fix for read-callback based attributes */
 
1010
                if (search_data->value && memcmp(attribute->value,
 
1011
                                                        search_data->value,
 
1012
                                                        search_data->value_len))
 
1013
                        continue;
 
1014
 
 
1015
                search_data->num_of_res++;
 
1016
                search_data->func(attribute, search_data->user_data);
 
1017
        }
 
1018
}
 
1019
 
 
1020
unsigned int gatt_db_find_by_type(struct gatt_db *db, uint16_t start_handle,
 
1021
                                                uint16_t end_handle,
 
1022
                                                const bt_uuid_t *type,
 
1023
                                                gatt_db_attribute_cb_t func,
 
1024
                                                void *user_data)
 
1025
{
 
1026
        struct find_by_type_value_data data;
 
1027
 
 
1028
        memset(&data, 0, sizeof(data));
 
1029
 
 
1030
        data.uuid = *type;
 
1031
        data.start_handle = start_handle;
 
1032
        data.end_handle = end_handle;
 
1033
        data.func = func;
 
1034
        data.user_data = user_data;
 
1035
 
 
1036
        queue_foreach(db->services, find_by_type, &data);
 
1037
 
 
1038
        return data.num_of_res;
 
1039
}
 
1040
 
 
1041
unsigned int gatt_db_find_by_type_value(struct gatt_db *db,
 
1042
                                                uint16_t start_handle,
 
1043
                                                uint16_t end_handle,
 
1044
                                                const bt_uuid_t *type,
 
1045
                                                const void *value,
 
1046
                                                size_t value_len,
 
1047
                                                gatt_db_attribute_cb_t func,
 
1048
                                                void *user_data)
 
1049
{
 
1050
        struct find_by_type_value_data data;
 
1051
 
 
1052
        data.uuid = *type;
 
1053
        data.start_handle = start_handle;
 
1054
        data.end_handle = end_handle;
 
1055
        data.func = func;
 
1056
        data.user_data = user_data;
 
1057
        data.value = value;
 
1058
        data.value_len = value_len;
 
1059
 
 
1060
        queue_foreach(db->services, find_by_type, &data);
 
1061
 
 
1062
        return data.num_of_res;
 
1063
}
 
1064
 
 
1065
struct read_by_type_data {
 
1066
        struct queue *queue;
 
1067
        bt_uuid_t uuid;
 
1068
        uint16_t start_handle;
 
1069
        uint16_t end_handle;
 
1070
};
 
1071
 
 
1072
static void read_by_type(void *data, void *user_data)
 
1073
{
 
1074
        struct read_by_type_data *search_data = user_data;
 
1075
        struct gatt_db_service *service = data;
 
1076
        struct gatt_db_attribute *attribute;
 
1077
        int i;
 
1078
 
 
1079
        if (!service->active)
 
1080
                return;
 
1081
 
 
1082
        for (i = 0; i < service->num_handles; i++) {
 
1083
                attribute = service->attributes[i];
 
1084
                if (!attribute)
 
1085
                        continue;
 
1086
 
 
1087
                if (attribute->handle < search_data->start_handle)
 
1088
                        continue;
 
1089
 
 
1090
                if (attribute->handle > search_data->end_handle)
 
1091
                        return;
 
1092
 
 
1093
                if (bt_uuid_cmp(&search_data->uuid, &attribute->uuid))
 
1094
                        continue;
 
1095
 
 
1096
                queue_push_tail(search_data->queue, attribute);
 
1097
        }
 
1098
}
 
1099
 
 
1100
void gatt_db_read_by_type(struct gatt_db *db, uint16_t start_handle,
 
1101
                                                uint16_t end_handle,
 
1102
                                                const bt_uuid_t type,
 
1103
                                                struct queue *queue)
 
1104
{
 
1105
        struct read_by_type_data data;
 
1106
        data.uuid = type;
 
1107
        data.start_handle = start_handle;
 
1108
        data.end_handle = end_handle;
 
1109
        data.queue = queue;
 
1110
 
 
1111
        queue_foreach(db->services, read_by_type, &data);
 
1112
}
 
1113
 
 
1114
 
 
1115
struct find_information_data {
 
1116
        struct queue *queue;
 
1117
        uint16_t start_handle;
 
1118
        uint16_t end_handle;
 
1119
};
 
1120
 
 
1121
static void find_information(void *data, void *user_data)
 
1122
{
 
1123
        struct find_information_data *search_data = user_data;
 
1124
        struct gatt_db_service *service = data;
 
1125
        struct gatt_db_attribute *attribute;
 
1126
        int i;
 
1127
 
 
1128
        if (!service->active)
 
1129
                return;
 
1130
 
 
1131
        /* Check if service is in range */
 
1132
        if ((service->attributes[0]->handle + service->num_handles - 1) <
 
1133
                                                search_data->start_handle)
 
1134
                return;
 
1135
 
 
1136
        for (i = 0; i < service->num_handles; i++) {
 
1137
                attribute = service->attributes[i];
 
1138
                if (!attribute)
 
1139
                        continue;
 
1140
 
 
1141
                if (attribute->handle < search_data->start_handle)
 
1142
                        continue;
 
1143
 
 
1144
                if (attribute->handle > search_data->end_handle)
 
1145
                        return;
 
1146
 
 
1147
                queue_push_tail(search_data->queue, attribute);
 
1148
        }
 
1149
}
 
1150
 
 
1151
void gatt_db_find_information(struct gatt_db *db, uint16_t start_handle,
 
1152
                                                        uint16_t end_handle,
 
1153
                                                        struct queue *queue)
 
1154
{
 
1155
        struct find_information_data data;
 
1156
 
 
1157
        data.start_handle = start_handle;
 
1158
        data.end_handle = end_handle;
 
1159
        data.queue = queue;
 
1160
 
 
1161
        queue_foreach(db->services, find_information, &data);
 
1162
}
 
1163
 
 
1164
void gatt_db_foreach_service(struct gatt_db *db, const bt_uuid_t *uuid,
 
1165
                                                gatt_db_attribute_cb_t func,
 
1166
                                                void *user_data)
 
1167
{
 
1168
        gatt_db_foreach_service_in_range(db, uuid, func, user_data, 0x0001,
 
1169
                                                                        0xffff);
 
1170
}
 
1171
 
 
1172
struct foreach_data {
 
1173
        gatt_db_attribute_cb_t func;
 
1174
        const bt_uuid_t *uuid;
 
1175
        void *user_data;
 
1176
        uint16_t start, end;
 
1177
};
 
1178
 
 
1179
static void foreach_service_in_range(void *data, void *user_data)
 
1180
{
 
1181
        struct gatt_db_service *service = data;
 
1182
        struct foreach_data *foreach_data = user_data;
 
1183
        uint16_t svc_start;
 
1184
        bt_uuid_t uuid;
 
1185
 
 
1186
        svc_start = get_handle_at_index(service, 0);
 
1187
 
 
1188
        if (svc_start > foreach_data->end || svc_start < foreach_data->start)
 
1189
                return;
 
1190
 
 
1191
        if (foreach_data->uuid) {
 
1192
                gatt_db_attribute_get_service_uuid(service->attributes[0],
 
1193
                                                                        &uuid);
 
1194
                if (bt_uuid_cmp(&uuid, foreach_data->uuid))
 
1195
                        return;
 
1196
        }
 
1197
 
 
1198
        foreach_data->func(service->attributes[0], foreach_data->user_data);
 
1199
}
 
1200
 
 
1201
void gatt_db_foreach_service_in_range(struct gatt_db *db,
 
1202
                                                const bt_uuid_t *uuid,
 
1203
                                                gatt_db_attribute_cb_t func,
 
1204
                                                void *user_data,
 
1205
                                                uint16_t start_handle,
 
1206
                                                uint16_t end_handle)
 
1207
{
 
1208
        struct foreach_data data;
 
1209
 
 
1210
        if (!db || !func || start_handle > end_handle)
 
1211
                return;
 
1212
 
 
1213
        data.func = func;
 
1214
        data.uuid = uuid;
 
1215
        data.user_data = user_data;
 
1216
        data.start = start_handle;
 
1217
        data.end = end_handle;
 
1218
 
 
1219
        queue_foreach(db->services, foreach_service_in_range, &data);
 
1220
}
 
1221
 
 
1222
void gatt_db_service_foreach(struct gatt_db_attribute *attrib,
 
1223
                                                const bt_uuid_t *uuid,
 
1224
                                                gatt_db_attribute_cb_t func,
 
1225
                                                void *user_data)
 
1226
{
 
1227
        struct gatt_db_service *service;
 
1228
        struct gatt_db_attribute *attr;
 
1229
        uint16_t i;
 
1230
 
 
1231
        if (!attrib || !func)
 
1232
                return;
 
1233
 
 
1234
        service = attrib->service;
 
1235
 
 
1236
        for (i = 0; i < service->num_handles; i++) {
 
1237
                attr = service->attributes[i];
 
1238
                if (!attr)
 
1239
                        continue;
 
1240
 
 
1241
                if (uuid && bt_uuid_cmp(uuid, &attr->uuid))
 
1242
                        continue;
 
1243
 
 
1244
                func(attr, user_data);
 
1245
        }
 
1246
}
 
1247
 
 
1248
void gatt_db_service_foreach_char(struct gatt_db_attribute *attrib,
 
1249
                                                gatt_db_attribute_cb_t func,
 
1250
                                                void *user_data)
 
1251
{
 
1252
        gatt_db_service_foreach(attrib, &characteristic_uuid, func, user_data);
 
1253
}
 
1254
 
 
1255
void gatt_db_service_foreach_desc(struct gatt_db_attribute *attrib,
 
1256
                                                gatt_db_attribute_cb_t func,
 
1257
                                                void *user_data)
 
1258
{
 
1259
        struct gatt_db_service *service;
 
1260
        struct gatt_db_attribute *attr;
 
1261
        uint16_t i;
 
1262
 
 
1263
        if (!attrib || !func)
 
1264
                return;
 
1265
 
 
1266
        /* Return if this attribute is not a characteristic declaration */
 
1267
        if (bt_uuid_cmp(&characteristic_uuid, &attrib->uuid))
 
1268
                return;
 
1269
 
 
1270
        service = attrib->service;
 
1271
 
 
1272
        /* Start from the attribute following the value handle */
 
1273
        for (i = 0; i < service->num_handles; i++) {
 
1274
                if (service->attributes[i] == attrib) {
 
1275
                        i += 2;
 
1276
                        break;
 
1277
                }
 
1278
        }
 
1279
 
 
1280
        for (; i < service->num_handles; i++) {
 
1281
                attr = service->attributes[i];
 
1282
                if (!attr)
 
1283
                        continue;
 
1284
 
 
1285
                /* Return if we reached the end of this characteristic */
 
1286
                if (!bt_uuid_cmp(&characteristic_uuid, &attr->uuid) ||
 
1287
                        !bt_uuid_cmp(&included_service_uuid, &attr->uuid))
 
1288
                        return;
 
1289
 
 
1290
                func(attr, user_data);
 
1291
        }
 
1292
}
 
1293
 
 
1294
void gatt_db_service_foreach_incl(struct gatt_db_attribute *attrib,
 
1295
                                                gatt_db_attribute_cb_t func,
 
1296
                                                void *user_data)
 
1297
{
 
1298
        gatt_db_service_foreach(attrib, &included_service_uuid, func,
 
1299
                                                                user_data);
 
1300
}
 
1301
 
 
1302
static bool find_service_for_handle(const void *data, const void *user_data)
 
1303
{
 
1304
        const struct gatt_db_service *service = data;
 
1305
        uint16_t handle = PTR_TO_UINT(user_data);
 
1306
        uint16_t start, end;
 
1307
 
 
1308
        gatt_db_service_get_handles(service, &start, &end);
 
1309
 
 
1310
        return (start <= handle) && (handle <= end);
 
1311
}
 
1312
 
 
1313
struct gatt_db_attribute *gatt_db_get_attribute(struct gatt_db *db,
 
1314
                                                        uint16_t handle)
 
1315
{
 
1316
        struct gatt_db_service *service;
 
1317
        int i;
 
1318
 
 
1319
        if (!db || !handle)
 
1320
                return NULL;
 
1321
 
 
1322
        service = queue_find(db->services, find_service_for_handle,
 
1323
                                                        UINT_TO_PTR(handle));
 
1324
        if (!service)
 
1325
                return NULL;
 
1326
 
 
1327
        for (i = 0; i < service->num_handles; i++) {
 
1328
                if (!service->attributes[i])
 
1329
                        continue;
 
1330
 
 
1331
                if (service->attributes[i]->handle == handle)
 
1332
                        return service->attributes[i];
 
1333
        }
 
1334
 
 
1335
        return NULL;
 
1336
}
 
1337
 
 
1338
static bool find_service_with_uuid(const void *data, const void *user_data)
 
1339
{
 
1340
        const struct gatt_db_service *service = data;
 
1341
        const bt_uuid_t *uuid = user_data;
 
1342
        bt_uuid_t svc_uuid;
 
1343
 
 
1344
        gatt_db_attribute_get_service_uuid(service->attributes[0], &svc_uuid);
 
1345
 
 
1346
        return bt_uuid_cmp(uuid, &svc_uuid) == 0;
 
1347
}
 
1348
 
 
1349
struct gatt_db_attribute *gatt_db_get_service_with_uuid(struct gatt_db *db,
 
1350
                                                        const bt_uuid_t *uuid)
 
1351
{
 
1352
        struct gatt_db_service *service;
 
1353
 
 
1354
        if (!db || !uuid)
 
1355
                return NULL;
 
1356
 
 
1357
        service = queue_find(db->services, find_service_with_uuid, uuid);
 
1358
        if (!service)
 
1359
                return NULL;
 
1360
 
 
1361
        return service->attributes[0];
 
1362
}
 
1363
 
 
1364
const bt_uuid_t *gatt_db_attribute_get_type(
 
1365
                                        const struct gatt_db_attribute *attrib)
 
1366
{
 
1367
        if (!attrib)
 
1368
                return NULL;
 
1369
 
 
1370
        return &attrib->uuid;
 
1371
}
 
1372
 
 
1373
uint16_t gatt_db_attribute_get_handle(const struct gatt_db_attribute *attrib)
 
1374
{
 
1375
        if (!attrib)
 
1376
                return 0;
 
1377
 
 
1378
        return attrib->handle;
 
1379
}
 
1380
 
 
1381
bool gatt_db_attribute_get_service_uuid(const struct gatt_db_attribute *attrib,
 
1382
                                                        bt_uuid_t *uuid)
 
1383
{
 
1384
        struct gatt_db_service *service;
 
1385
 
 
1386
        if (!attrib || !uuid)
 
1387
                return false;
 
1388
 
 
1389
        service = attrib->service;
 
1390
 
 
1391
        if (service->attributes[0]->value_len == sizeof(uint16_t)) {
 
1392
                uint16_t value;
 
1393
 
 
1394
                value = get_le16(service->attributes[0]->value);
 
1395
                bt_uuid16_create(uuid, value);
 
1396
 
 
1397
                return true;
 
1398
        }
 
1399
 
 
1400
        if (service->attributes[0]->value_len == sizeof(uint128_t)) {
 
1401
                uint128_t value;
 
1402
 
 
1403
                bswap_128(service->attributes[0]->value, &value);
 
1404
                bt_uuid128_create(uuid, value);
 
1405
 
 
1406
                return true;
 
1407
        }
 
1408
 
 
1409
        return false;
 
1410
}
 
1411
 
 
1412
bool gatt_db_attribute_get_service_handles(
 
1413
                                        const struct gatt_db_attribute *attrib,
 
1414
                                        uint16_t *start_handle,
 
1415
                                        uint16_t *end_handle)
 
1416
{
 
1417
        struct gatt_db_service *service;
 
1418
 
 
1419
        if (!attrib)
 
1420
                return false;
 
1421
 
 
1422
        service = attrib->service;
 
1423
 
 
1424
        gatt_db_service_get_handles(service, start_handle, end_handle);
 
1425
 
 
1426
        return true;
 
1427
}
 
1428
 
 
1429
bool gatt_db_attribute_get_service_data(const struct gatt_db_attribute *attrib,
 
1430
                                                        uint16_t *start_handle,
 
1431
                                                        uint16_t *end_handle,
 
1432
                                                        bool *primary,
 
1433
                                                        bt_uuid_t *uuid)
 
1434
{
 
1435
        struct gatt_db_service *service;
 
1436
        struct gatt_db_attribute *decl;
 
1437
 
 
1438
        if (!attrib)
 
1439
                return false;
 
1440
 
 
1441
        service = attrib->service;
 
1442
        decl = service->attributes[0];
 
1443
 
 
1444
        gatt_db_service_get_handles(service, start_handle, end_handle);
 
1445
 
 
1446
        if (primary)
 
1447
                *primary = bt_uuid_cmp(&decl->uuid, &secondary_service_uuid);
 
1448
 
 
1449
        if (!uuid)
 
1450
                return true;
 
1451
 
 
1452
        /*
 
1453
         * The service declaration attribute value is the 16 or 128 bit service
 
1454
         * UUID.
 
1455
         */
 
1456
        return le_to_uuid(decl->value, decl->value_len, uuid);
 
1457
}
 
1458
 
 
1459
bool gatt_db_attribute_get_char_data(const struct gatt_db_attribute *attrib,
 
1460
                                                        uint16_t *handle,
 
1461
                                                        uint16_t *value_handle,
 
1462
                                                        uint8_t *properties,
 
1463
                                                        bt_uuid_t *uuid)
 
1464
{
 
1465
        if (!attrib)
 
1466
                return false;
 
1467
 
 
1468
        if (bt_uuid_cmp(&characteristic_uuid, &attrib->uuid))
 
1469
                return false;
 
1470
 
 
1471
        /*
 
1472
         * Characteristic declaration value:
 
1473
         * 1 octet: Characteristic properties
 
1474
         * 2 octets: Characteristic value handle
 
1475
         * 2 or 16 octets: characteristic UUID
 
1476
         */
 
1477
        if (!attrib->value || (attrib->value_len != 5 &&
 
1478
                                                attrib->value_len != 19))
 
1479
                return false;
 
1480
 
 
1481
        if (handle)
 
1482
                *handle = attrib->handle;
 
1483
 
 
1484
        if (properties)
 
1485
                *properties = attrib->value[0];
 
1486
 
 
1487
        if (value_handle)
 
1488
                *value_handle = get_le16(attrib->value + 1);
 
1489
 
 
1490
        if (!uuid)
 
1491
                return true;
 
1492
 
 
1493
        return le_to_uuid(attrib->value + 3, attrib->value_len - 3, uuid);
 
1494
}
 
1495
 
 
1496
bool gatt_db_attribute_get_incl_data(const struct gatt_db_attribute *attrib,
 
1497
                                                        uint16_t *handle,
 
1498
                                                        uint16_t *start_handle,
 
1499
                                                        uint16_t *end_handle)
 
1500
{
 
1501
        if (!attrib)
 
1502
                return false;
 
1503
 
 
1504
        if (bt_uuid_cmp(&included_service_uuid, &attrib->uuid))
 
1505
                return false;
 
1506
 
 
1507
        /*
 
1508
         * Include definition value:
 
1509
         * 2 octets: start handle of included service
 
1510
         * 2 octets: end handle of included service
 
1511
         * optional 2 octets: 16-bit Bluetooth UUID
 
1512
         */
 
1513
        if (!attrib->value || attrib->value_len < 4 || attrib->value_len > 6)
 
1514
                return false;
 
1515
 
 
1516
        /*
 
1517
         * We only return the handles since the UUID can be easily obtained
 
1518
         * from the corresponding attribute.
 
1519
         */
 
1520
        if (handle)
 
1521
                *handle = attrib->handle;
 
1522
 
 
1523
        if (start_handle)
 
1524
                *start_handle = get_le16(attrib->value);
 
1525
 
 
1526
        if (end_handle)
 
1527
                *end_handle = get_le16(attrib->value + 2);
 
1528
 
 
1529
        return true;
 
1530
}
 
1531
 
 
1532
uint32_t
 
1533
gatt_db_attribute_get_permissions(const struct gatt_db_attribute *attrib)
 
1534
{
 
1535
        if (!attrib)
 
1536
                return 0;
 
1537
 
 
1538
        return attrib->permissions;
 
1539
}
 
1540
 
 
1541
static bool read_timeout(void *user_data)
 
1542
{
 
1543
        struct pending_read *p = user_data;
 
1544
 
 
1545
        p->timeout_id = 0;
 
1546
 
 
1547
        queue_remove(p->attrib->pending_reads, p);
 
1548
 
 
1549
        pending_read_result(p, -ETIMEDOUT, NULL, 0);
 
1550
 
 
1551
        return false;
 
1552
}
 
1553
 
 
1554
bool gatt_db_attribute_read(struct gatt_db_attribute *attrib, uint16_t offset,
 
1555
                                uint8_t opcode, struct bt_att *att,
 
1556
                                gatt_db_attribute_read_t func, void *user_data)
 
1557
{
 
1558
        uint8_t *value;
 
1559
 
 
1560
        if (!attrib || !func)
 
1561
                return false;
 
1562
 
 
1563
        if (attrib->read_func) {
 
1564
                struct pending_read *p;
 
1565
 
 
1566
                p = new0(struct pending_read, 1);
 
1567
                p->attrib = attrib;
 
1568
                p->id = ++attrib->read_id;
 
1569
                p->timeout_id = timeout_add(ATTRIBUTE_TIMEOUT, read_timeout,
 
1570
                                                                p, NULL);
 
1571
                p->func = func;
 
1572
                p->user_data = user_data;
 
1573
 
 
1574
                queue_push_tail(attrib->pending_reads, p);
 
1575
 
 
1576
                attrib->read_func(attrib, p->id, offset, opcode, att,
 
1577
                                                        attrib->user_data);
 
1578
                return true;
 
1579
        }
 
1580
 
 
1581
        /* Check boundary if value is stored in the db */
 
1582
        if (offset > attrib->value_len) {
 
1583
                func(attrib, BT_ATT_ERROR_INVALID_OFFSET, NULL, 0, user_data);
 
1584
                return true;
 
1585
        }
 
1586
 
 
1587
        /* Guard against invalid access if offset equals to value length */
 
1588
        value = offset == attrib->value_len ? NULL : &attrib->value[offset];
 
1589
 
 
1590
        func(attrib, 0, value, attrib->value_len - offset, user_data);
 
1591
 
 
1592
        return true;
 
1593
}
 
1594
 
 
1595
static bool find_pending(const void *a, const void *b)
 
1596
{
 
1597
        const struct pending_read *p = a;
 
1598
        unsigned int id = PTR_TO_UINT(b);
 
1599
 
 
1600
        return p->id == id;
 
1601
}
 
1602
 
 
1603
bool gatt_db_attribute_read_result(struct gatt_db_attribute *attrib,
 
1604
                                        unsigned int id, int err,
 
1605
                                        const uint8_t *value, size_t length)
 
1606
{
 
1607
        struct pending_read *p;
 
1608
 
 
1609
        if (!attrib || !id)
 
1610
                return false;
 
1611
 
 
1612
        p = queue_remove_if(attrib->pending_reads, find_pending,
 
1613
                                                        UINT_TO_PTR(id));
 
1614
        if (!p)
 
1615
                return false;
 
1616
 
 
1617
        pending_read_result(p, err, value, length);
 
1618
 
 
1619
        return true;
 
1620
}
 
1621
 
 
1622
static bool write_timeout(void *user_data)
 
1623
{
 
1624
        struct pending_write *p = user_data;
 
1625
 
 
1626
        p->timeout_id = 0;
 
1627
 
 
1628
        queue_remove(p->attrib->pending_writes, p);
 
1629
 
 
1630
        pending_write_result(p, -ETIMEDOUT);
 
1631
 
 
1632
        return false;
 
1633
}
 
1634
 
 
1635
bool gatt_db_attribute_write(struct gatt_db_attribute *attrib, uint16_t offset,
 
1636
                                        const uint8_t *value, size_t len,
 
1637
                                        uint8_t opcode, struct bt_att *att,
 
1638
                                        gatt_db_attribute_write_t func,
 
1639
                                        void *user_data)
 
1640
{
 
1641
        if (!attrib || !func)
 
1642
                return false;
 
1643
 
 
1644
        if (attrib->write_func) {
 
1645
                struct pending_write *p;
 
1646
 
 
1647
                p = new0(struct pending_write, 1);
 
1648
                p->attrib = attrib;
 
1649
                p->id = ++attrib->write_id;
 
1650
                p->timeout_id = timeout_add(ATTRIBUTE_TIMEOUT, write_timeout,
 
1651
                                                                p, NULL);
 
1652
                p->func = func;
 
1653
                p->user_data = user_data;
 
1654
 
 
1655
                queue_push_tail(attrib->pending_writes, p);
 
1656
 
 
1657
                attrib->write_func(attrib, p->id, offset, value, len, opcode,
 
1658
                                                        att, attrib->user_data);
 
1659
                return true;
 
1660
        }
 
1661
 
 
1662
        /* Nothing to write just skip */
 
1663
        if (len == 0)
 
1664
                goto done;
 
1665
 
 
1666
        /* For values stored in db allocate on demand */
 
1667
        if (!attrib->value || offset >= attrib->value_len ||
 
1668
                                len > (unsigned) (attrib->value_len - offset)) {
 
1669
                void *buf;
 
1670
 
 
1671
                buf = realloc(attrib->value, len + offset);
 
1672
                if (!buf)
 
1673
                        return false;
 
1674
 
 
1675
                attrib->value = buf;
 
1676
 
 
1677
                /* Init data in the first allocation */
 
1678
                if (!attrib->value_len)
 
1679
                        memset(attrib->value, 0, offset);
 
1680
 
 
1681
                attrib->value_len = len + offset;
 
1682
        }
 
1683
 
 
1684
        memcpy(&attrib->value[offset], value, len);
 
1685
 
 
1686
done:
 
1687
        func(attrib, 0, user_data);
 
1688
 
 
1689
        return true;
 
1690
}
 
1691
 
 
1692
bool gatt_db_attribute_write_result(struct gatt_db_attribute *attrib,
 
1693
                                                unsigned int id, int err)
 
1694
{
 
1695
        struct pending_write *p;
 
1696
 
 
1697
        if (!attrib || !id)
 
1698
                return false;
 
1699
 
 
1700
        p = queue_remove_if(attrib->pending_writes, find_pending,
 
1701
                                                        UINT_TO_PTR(id));
 
1702
        if (!p)
 
1703
                return false;
 
1704
 
 
1705
        pending_write_result(p, err);
 
1706
 
 
1707
        return true;
 
1708
}
 
1709
 
 
1710
bool gatt_db_attribute_reset(struct gatt_db_attribute *attrib)
 
1711
{
 
1712
        if (!attrib)
 
1713
                return false;
 
1714
 
 
1715
        if (!attrib->value || !attrib->value_len)
 
1716
                return true;
 
1717
 
 
1718
        free(attrib->value);
 
1719
        attrib->value = NULL;
 
1720
        attrib->value_len = 0;
 
1721
 
 
1722
        return true;
 
1723
}