OSDN Git Service

core: gatt-database: Remove unnecessary typecast
[android-x86/external-bluetooth-bluez.git] / src / gatt-database.c
1 /*
2  *
3  *  BlueZ - Bluetooth protocol stack for Linux
4  *
5  *  Copyright (C) 2015  Google Inc.
6  *
7  *
8  *  This program is free software; you can redistribute it and/or modify
9  *  it under the terms of the GNU General Public License as published by
10  *  the Free Software Foundation; either version 2 of the License, or
11  *  (at your option) any later version.
12  *
13  *  This program 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
16  *  GNU General Public License for more details.
17  *
18  */
19
20 #ifdef HAVE_CONFIG_H
21 #include <config.h>
22 #endif
23
24 #include <stdint.h>
25 #include <stdlib.h>
26 #include <errno.h>
27
28 #include "lib/bluetooth.h"
29 #include "lib/sdp.h"
30 #include "lib/sdp_lib.h"
31 #include "lib/uuid.h"
32 #include "btio/btio.h"
33 #include "gdbus/gdbus.h"
34 #include "src/shared/util.h"
35 #include "src/shared/queue.h"
36 #include "src/shared/att.h"
37 #include "src/shared/gatt-db.h"
38 #include "src/shared/gatt-server.h"
39 #include "log.h"
40 #include "error.h"
41 #include "adapter.h"
42 #include "device.h"
43 #include "gatt-database.h"
44 #include "dbus-common.h"
45 #include "profile.h"
46
47 #ifndef ATT_CID
48 #define ATT_CID 4
49 #endif
50
51 #ifndef ATT_PSM
52 #define ATT_PSM 31
53 #endif
54
55 #define GATT_MANAGER_IFACE      "org.bluez.GattManager1"
56 #define GATT_SERVICE_IFACE      "org.bluez.GattService1"
57 #define GATT_CHRC_IFACE         "org.bluez.GattCharacteristic1"
58 #define GATT_DESC_IFACE         "org.bluez.GattDescriptor1"
59
60 #define UUID_GAP        0x1800
61 #define UUID_GATT       0x1801
62
63 #ifndef MIN
64 #define MIN(a, b) ((a) < (b) ? (a) : (b))
65 #endif
66
67 struct btd_gatt_database {
68         struct btd_adapter *adapter;
69         struct gatt_db *db;
70         unsigned int db_id;
71         GIOChannel *le_io;
72         GIOChannel *l2cap_io;
73         uint32_t gap_handle;
74         uint32_t gatt_handle;
75         struct queue *device_states;
76         struct queue *ccc_callbacks;
77         struct gatt_db_attribute *svc_chngd;
78         struct gatt_db_attribute *svc_chngd_ccc;
79         struct queue *services;
80         struct queue *profiles;
81 };
82
83 struct external_service {
84         struct btd_gatt_database *database;
85         bool failed;
86         char *owner;
87         char *path;     /* Path to GattService1 */
88         DBusMessage *reg;
89         GDBusClient *client;
90         GDBusProxy *proxy;
91         struct gatt_db_attribute *attrib;
92         uint16_t attr_cnt;
93         struct queue *chrcs;
94         struct queue *descs;
95 };
96
97 struct external_profile {
98         struct btd_gatt_database *database;
99         char *owner;
100         char *path;     /* Path to GattProfile1 */
101         unsigned int id;
102         struct queue *profiles; /* btd_profile list */
103 };
104
105 struct external_chrc {
106         struct external_service *service;
107         char *path;
108         GDBusProxy *proxy;
109         uint8_t props;
110         uint8_t ext_props;
111         struct gatt_db_attribute *attrib;
112         struct gatt_db_attribute *ccc;
113         struct queue *pending_reads;
114         struct queue *pending_writes;
115         unsigned int ntfy_cnt;
116 };
117
118 struct external_desc {
119         struct external_service *service;
120         char *chrc_path;
121         GDBusProxy *proxy;
122         uint32_t perm;
123         struct gatt_db_attribute *attrib;
124         bool handled;
125         struct queue *pending_reads;
126         struct queue *pending_writes;
127 };
128
129 struct pending_op {
130         unsigned int id;
131         struct gatt_db_attribute *attrib;
132         struct queue *owner_queue;
133         struct iovec data;
134 };
135
136 struct device_state {
137         bdaddr_t bdaddr;
138         uint8_t bdaddr_type;
139         struct queue *ccc_states;
140 };
141
142 struct ccc_state {
143         uint16_t handle;
144         uint8_t value[2];
145 };
146
147 struct ccc_cb_data {
148         uint16_t handle;
149         btd_gatt_database_ccc_write_t callback;
150         btd_gatt_database_destroy_t destroy;
151         void *user_data;
152 };
153
154 struct device_info {
155         bdaddr_t bdaddr;
156         uint8_t bdaddr_type;
157 };
158
159 static void ccc_cb_free(void *data)
160 {
161         struct ccc_cb_data *ccc_cb = data;
162
163         if (ccc_cb->destroy)
164                 ccc_cb->destroy(ccc_cb->user_data);
165
166         free(ccc_cb);
167 }
168
169 static bool ccc_cb_match_service(const void *data, const void *match_data)
170 {
171         const struct ccc_cb_data *ccc_cb = data;
172         const struct gatt_db_attribute *attrib = match_data;
173         uint16_t start, end;
174
175         if (!gatt_db_attribute_get_service_handles(attrib, &start, &end))
176                 return false;
177
178         return ccc_cb->handle >= start && ccc_cb->handle <= end;
179 }
180
181 static bool ccc_cb_match_handle(const void *data, const void *match_data)
182 {
183         const struct ccc_cb_data *ccc_cb = data;
184         uint16_t handle = PTR_TO_UINT(match_data);
185
186         return ccc_cb->handle == handle;
187 }
188
189 static bool dev_state_match(const void *a, const void *b)
190 {
191         const struct device_state *dev_state = a;
192         const struct device_info *dev_info = b;
193
194         return bacmp(&dev_state->bdaddr, &dev_info->bdaddr) == 0 &&
195                                 dev_state->bdaddr_type == dev_info->bdaddr_type;
196 }
197
198 static struct device_state *
199 find_device_state(struct btd_gatt_database *database, bdaddr_t *bdaddr,
200                                                         uint8_t bdaddr_type)
201 {
202         struct device_info dev_info;
203
204         memset(&dev_info, 0, sizeof(dev_info));
205
206         bacpy(&dev_info.bdaddr, bdaddr);
207         dev_info.bdaddr_type = bdaddr_type;
208
209         return queue_find(database->device_states, dev_state_match, &dev_info);
210 }
211
212 static bool ccc_state_match(const void *a, const void *b)
213 {
214         const struct ccc_state *ccc = a;
215         uint16_t handle = PTR_TO_UINT(b);
216
217         return ccc->handle == handle;
218 }
219
220 static struct ccc_state *find_ccc_state(struct device_state *dev_state,
221                                                                 uint16_t handle)
222 {
223         return queue_find(dev_state->ccc_states, ccc_state_match,
224                                                         UINT_TO_PTR(handle));
225 }
226
227 static struct device_state *device_state_create(bdaddr_t *bdaddr,
228                                                         uint8_t bdaddr_type)
229 {
230         struct device_state *dev_state;
231
232         dev_state = new0(struct device_state, 1);
233         if (!dev_state)
234                 return NULL;
235
236         dev_state->ccc_states = queue_new();
237         if (!dev_state->ccc_states) {
238                 free(dev_state);
239                 return NULL;
240         }
241
242         bacpy(&dev_state->bdaddr, bdaddr);
243         dev_state->bdaddr_type = bdaddr_type;
244
245         return dev_state;
246 }
247
248 static struct device_state *get_device_state(struct btd_gatt_database *database,
249                                                         bdaddr_t *bdaddr,
250                                                         uint8_t bdaddr_type)
251 {
252         struct device_state *dev_state;
253
254         /*
255          * Find and return a device state. If a matching state doesn't exist,
256          * then create a new one.
257          */
258         dev_state = find_device_state(database, bdaddr, bdaddr_type);
259         if (dev_state)
260                 return dev_state;
261
262         dev_state = device_state_create(bdaddr, bdaddr_type);
263         if (!dev_state)
264                 return NULL;
265
266         queue_push_tail(database->device_states, dev_state);
267
268         return dev_state;
269 }
270
271 static struct ccc_state *get_ccc_state(struct btd_gatt_database *database,
272                                                         bdaddr_t *bdaddr,
273                                                         uint8_t bdaddr_type,
274                                                         uint16_t handle)
275 {
276         struct device_state *dev_state;
277         struct ccc_state *ccc;
278
279         dev_state = get_device_state(database, bdaddr, bdaddr_type);
280         if (!dev_state)
281                 return NULL;
282
283         ccc = find_ccc_state(dev_state, handle);
284         if (ccc)
285                 return ccc;
286
287         ccc = new0(struct ccc_state, 1);
288         if (!ccc)
289                 return NULL;
290
291         ccc->handle = handle;
292         queue_push_tail(dev_state->ccc_states, ccc);
293
294         return ccc;
295 }
296
297 static void device_state_free(void *data)
298 {
299         struct device_state *state = data;
300
301         queue_destroy(state->ccc_states, free);
302         free(state);
303 }
304
305 static void cancel_pending_read(void *data)
306 {
307         struct pending_op *op = data;
308
309         gatt_db_attribute_read_result(op->attrib, op->id,
310                                         BT_ATT_ERROR_REQUEST_NOT_SUPPORTED,
311                                         NULL, 0);
312         op->owner_queue = NULL;
313 }
314
315 static void cancel_pending_write(void *data)
316 {
317         struct pending_op *op = data;
318
319         gatt_db_attribute_write_result(op->attrib, op->id,
320                                         BT_ATT_ERROR_REQUEST_NOT_SUPPORTED);
321         op->owner_queue = NULL;
322 }
323
324 static void chrc_free(void *data)
325 {
326         struct external_chrc *chrc = data;
327
328         queue_destroy(chrc->pending_reads, cancel_pending_read);
329         queue_destroy(chrc->pending_writes, cancel_pending_write);
330
331         g_free(chrc->path);
332
333         g_dbus_proxy_set_property_watch(chrc->proxy, NULL, NULL);
334         g_dbus_proxy_unref(chrc->proxy);
335
336         free(chrc);
337 }
338
339 static void desc_free(void *data)
340 {
341         struct external_desc *desc = data;
342
343         queue_destroy(desc->pending_reads, cancel_pending_read);
344         queue_destroy(desc->pending_writes, cancel_pending_write);
345
346         g_dbus_proxy_unref(desc->proxy);
347         g_free(desc->chrc_path);
348
349         free(desc);
350 }
351
352 static void service_free(void *data)
353 {
354         struct external_service *service = data;
355
356         queue_destroy(service->chrcs, chrc_free);
357         queue_destroy(service->descs, desc_free);
358
359         gatt_db_remove_service(service->database->db, service->attrib);
360
361         if (service->client) {
362                 g_dbus_client_set_disconnect_watch(service->client, NULL, NULL);
363                 g_dbus_client_set_proxy_handlers(service->client, NULL, NULL,
364                                                                 NULL, NULL);
365                 g_dbus_client_set_ready_watch(service->client, NULL, NULL);
366                 g_dbus_proxy_unref(service->proxy);
367                 g_dbus_client_unref(service->client);
368         }
369
370         if (service->reg)
371                 dbus_message_unref(service->reg);
372
373         g_free(service->owner);
374         g_free(service->path);
375
376         free(service);
377 }
378
379 static void profile_remove(void *data)
380 {
381         struct btd_profile *p = data;
382
383         DBG("Removed \"%s\"", p->name);
384
385         adapter_foreach(adapter_remove_profile, p);
386
387         g_free((void *) p->name);
388         g_free((void *) p->remote_uuid);
389
390         free(p);
391 }
392
393 static void profile_release(struct external_profile *profile)
394 {
395         DBusMessage *msg;
396
397         if (!profile->id)
398                 return;
399
400         DBG("Releasing \"%s\"", profile->owner);
401
402         g_dbus_remove_watch(btd_get_dbus_connection(), profile->id);
403
404         msg = dbus_message_new_method_call(profile->owner, profile->path,
405                                                 "org.bluez.GattProfile1",
406                                                 "Release");
407         if (msg)
408                 g_dbus_send_message(btd_get_dbus_connection(), msg);
409 }
410
411 static void profile_free(void *data)
412 {
413         struct external_profile *profile = data;
414
415         queue_destroy(profile->profiles, profile_remove);
416
417         profile_release(profile);
418
419         g_free(profile->owner);
420         g_free(profile->path);
421
422         free(profile);
423 }
424
425 static void gatt_database_free(void *data)
426 {
427         struct btd_gatt_database *database = data;
428
429         if (database->le_io) {
430                 g_io_channel_shutdown(database->le_io, FALSE, NULL);
431                 g_io_channel_unref(database->le_io);
432         }
433
434         if (database->l2cap_io) {
435                 g_io_channel_shutdown(database->l2cap_io, FALSE, NULL);
436                 g_io_channel_unref(database->l2cap_io);
437         }
438
439         if (database->gatt_handle)
440                 adapter_service_remove(database->adapter,
441                                                         database->gatt_handle);
442
443         if (database->gap_handle)
444                 adapter_service_remove(database->adapter, database->gap_handle);
445
446         /* TODO: Persistently store CCC states before freeing them */
447         gatt_db_unregister(database->db, database->db_id);
448
449         queue_destroy(database->device_states, device_state_free);
450         queue_destroy(database->services, service_free);
451         queue_destroy(database->profiles, profile_free);
452         queue_destroy(database->ccc_callbacks, ccc_cb_free);
453         database->device_states = NULL;
454         database->ccc_callbacks = NULL;
455
456         gatt_db_unref(database->db);
457
458         btd_adapter_unref(database->adapter);
459         free(database);
460 }
461
462 static void connect_cb(GIOChannel *io, GError *gerr, gpointer user_data)
463 {
464         struct btd_adapter *adapter;
465         struct btd_device *device;
466         uint8_t dst_type;
467         bdaddr_t src, dst;
468
469         DBG("New incoming LE ATT connection");
470
471         if (gerr) {
472                 error("%s", gerr->message);
473                 return;
474         }
475
476         bt_io_get(io, &gerr, BT_IO_OPT_SOURCE_BDADDR, &src,
477                                                 BT_IO_OPT_DEST_BDADDR, &dst,
478                                                 BT_IO_OPT_DEST_TYPE, &dst_type,
479                                                 BT_IO_OPT_INVALID);
480         if (gerr) {
481                 error("bt_io_get: %s", gerr->message);
482                 g_error_free(gerr);
483                 return;
484         }
485
486         adapter = adapter_find(&src);
487         if (!adapter)
488                 return;
489
490         device = btd_adapter_get_device(adapter, &dst, dst_type);
491         if (!device)
492                 return;
493
494         device_attach_att(device, io);
495 }
496
497 static void gap_device_name_read_cb(struct gatt_db_attribute *attrib,
498                                         unsigned int id, uint16_t offset,
499                                         uint8_t opcode, struct bt_att *att,
500                                         void *user_data)
501 {
502         struct btd_gatt_database *database = user_data;
503         uint8_t error = 0;
504         size_t len = 0;
505         const uint8_t *value = NULL;
506         const char *device_name;
507
508         DBG("GAP Device Name read request\n");
509
510         device_name = btd_adapter_get_name(database->adapter);
511         len = strlen(device_name);
512
513         if (offset > len) {
514                 error = BT_ATT_ERROR_INVALID_OFFSET;
515                 goto done;
516         }
517
518         len -= offset;
519         value = len ? (const uint8_t *) &device_name[offset] : NULL;
520
521 done:
522         gatt_db_attribute_read_result(attrib, id, error, value, len);
523 }
524
525 static void gap_appearance_read_cb(struct gatt_db_attribute *attrib,
526                                         unsigned int id, uint16_t offset,
527                                         uint8_t opcode, struct bt_att *att,
528                                         void *user_data)
529 {
530         struct btd_gatt_database *database = user_data;
531         uint8_t error = 0;
532         size_t len = 2;
533         const uint8_t *value = NULL;
534         uint8_t appearance[2];
535         uint32_t dev_class;
536
537         DBG("GAP Appearance read request\n");
538
539         dev_class = btd_adapter_get_class(database->adapter);
540
541         if (offset > 2) {
542                 error = BT_ATT_ERROR_INVALID_OFFSET;
543                 goto done;
544         }
545
546         appearance[0] = dev_class & 0x00ff;
547         appearance[1] = (dev_class >> 8) & 0x001f;
548
549         len -= offset;
550         value = len ? &appearance[offset] : NULL;
551
552 done:
553         gatt_db_attribute_read_result(attrib, id, error, value, len);
554 }
555
556 static sdp_record_t *record_new(uuid_t *uuid, uint16_t start, uint16_t end)
557 {
558         sdp_list_t *svclass_id, *apseq, *proto[2], *root, *aproto;
559         uuid_t root_uuid, proto_uuid, l2cap;
560         sdp_record_t *record;
561         sdp_data_t *psm, *sh, *eh;
562         uint16_t lp = ATT_PSM;
563
564         if (uuid == NULL)
565                 return NULL;
566
567         if (start > end)
568                 return NULL;
569
570         record = sdp_record_alloc();
571         if (record == NULL)
572                 return NULL;
573
574         sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
575         root = sdp_list_append(NULL, &root_uuid);
576         sdp_set_browse_groups(record, root);
577         sdp_list_free(root, NULL);
578
579         svclass_id = sdp_list_append(NULL, uuid);
580         sdp_set_service_classes(record, svclass_id);
581         sdp_list_free(svclass_id, NULL);
582
583         sdp_uuid16_create(&l2cap, L2CAP_UUID);
584         proto[0] = sdp_list_append(NULL, &l2cap);
585         psm = sdp_data_alloc(SDP_UINT16, &lp);
586         proto[0] = sdp_list_append(proto[0], psm);
587         apseq = sdp_list_append(NULL, proto[0]);
588
589         sdp_uuid16_create(&proto_uuid, ATT_UUID);
590         proto[1] = sdp_list_append(NULL, &proto_uuid);
591         sh = sdp_data_alloc(SDP_UINT16, &start);
592         proto[1] = sdp_list_append(proto[1], sh);
593         eh = sdp_data_alloc(SDP_UINT16, &end);
594         proto[1] = sdp_list_append(proto[1], eh);
595         apseq = sdp_list_append(apseq, proto[1]);
596
597         aproto = sdp_list_append(NULL, apseq);
598         sdp_set_access_protos(record, aproto);
599
600         sdp_data_free(psm);
601         sdp_data_free(sh);
602         sdp_data_free(eh);
603         sdp_list_free(proto[0], NULL);
604         sdp_list_free(proto[1], NULL);
605         sdp_list_free(apseq, NULL);
606         sdp_list_free(aproto, NULL);
607
608         return record;
609 }
610
611 static uint32_t database_add_record(struct btd_gatt_database *database,
612                                         uint16_t uuid,
613                                         struct gatt_db_attribute *attr,
614                                         const char *name)
615 {
616         sdp_record_t *record;
617         uint16_t start, end;
618         uuid_t svc, gap_uuid;
619
620         sdp_uuid16_create(&svc, uuid);
621         gatt_db_attribute_get_service_handles(attr, &start, &end);
622
623         record = record_new(&svc, start, end);
624         if (!record)
625                 return 0;
626
627         if (name != NULL)
628                 sdp_set_info_attr(record, name, "BlueZ", NULL);
629
630         sdp_uuid16_create(&gap_uuid, UUID_GAP);
631         if (sdp_uuid_cmp(&svc, &gap_uuid) == 0) {
632                 sdp_set_url_attr(record, "http://www.bluez.org/",
633                                 "http://www.bluez.org/",
634                                 "http://www.bluez.org/");
635         }
636
637         if (adapter_service_add(database->adapter, record) == 0)
638                 return record->handle;
639
640         sdp_record_free(record);
641         return 0;
642 }
643
644 static void populate_gap_service(struct btd_gatt_database *database)
645 {
646         bt_uuid_t uuid;
647         struct gatt_db_attribute *service;
648
649         /* Add the GAP service */
650         bt_uuid16_create(&uuid, UUID_GAP);
651         service = gatt_db_add_service(database->db, &uuid, true, 5);
652         database->gap_handle = database_add_record(database, UUID_GAP, service,
653                                                 "Generic Access Profile");
654
655         /*
656          * Device Name characteristic.
657          */
658         bt_uuid16_create(&uuid, GATT_CHARAC_DEVICE_NAME);
659         gatt_db_service_add_characteristic(service, &uuid, BT_ATT_PERM_READ,
660                                                         BT_GATT_CHRC_PROP_READ,
661                                                         gap_device_name_read_cb,
662                                                         NULL, database);
663
664         /*
665          * Device Appearance characteristic.
666          */
667         bt_uuid16_create(&uuid, GATT_CHARAC_APPEARANCE);
668         gatt_db_service_add_characteristic(service, &uuid, BT_ATT_PERM_READ,
669                                                         BT_GATT_CHRC_PROP_READ,
670                                                         gap_appearance_read_cb,
671                                                         NULL, database);
672
673         gatt_db_service_set_active(service, true);
674 }
675
676 static bool get_dst_info(struct bt_att *att, bdaddr_t *dst, uint8_t *dst_type)
677 {
678         GIOChannel *io = NULL;
679         GError *gerr = NULL;
680
681         io = g_io_channel_unix_new(bt_att_get_fd(att));
682         if (!io)
683                 return false;
684
685         bt_io_get(io, &gerr, BT_IO_OPT_DEST_BDADDR, dst,
686                                                 BT_IO_OPT_DEST_TYPE, dst_type,
687                                                 BT_IO_OPT_INVALID);
688         if (gerr) {
689                 error("gatt: bt_io_get: %s", gerr->message);
690                 g_error_free(gerr);
691                 g_io_channel_unref(io);
692                 return false;
693         }
694
695         g_io_channel_unref(io);
696         return true;
697 }
698
699 static void gatt_ccc_read_cb(struct gatt_db_attribute *attrib,
700                                         unsigned int id, uint16_t offset,
701                                         uint8_t opcode, struct bt_att *att,
702                                         void *user_data)
703 {
704         struct btd_gatt_database *database = user_data;
705         struct ccc_state *ccc;
706         uint16_t handle;
707         uint8_t ecode = 0;
708         const uint8_t *value = NULL;
709         size_t len = 0;
710         bdaddr_t bdaddr;
711         uint8_t bdaddr_type;
712
713         handle = gatt_db_attribute_get_handle(attrib);
714
715         DBG("CCC read called for handle: 0x%04x", handle);
716
717         if (offset > 2) {
718                 ecode = BT_ATT_ERROR_INVALID_OFFSET;
719                 goto done;
720         }
721
722         if (!get_dst_info(att, &bdaddr, &bdaddr_type)) {
723                 ecode = BT_ATT_ERROR_UNLIKELY;
724                 goto done;
725         }
726
727         ccc = get_ccc_state(database, &bdaddr, bdaddr_type, handle);
728         if (!ccc) {
729                 ecode = BT_ATT_ERROR_UNLIKELY;
730                 goto done;
731         }
732
733         len = 2 - offset;
734         value = len ? &ccc->value[offset] : NULL;
735
736 done:
737         gatt_db_attribute_read_result(attrib, id, ecode, value, len);
738 }
739
740 static void gatt_ccc_write_cb(struct gatt_db_attribute *attrib,
741                                         unsigned int id, uint16_t offset,
742                                         const uint8_t *value, size_t len,
743                                         uint8_t opcode, struct bt_att *att,
744                                         void *user_data)
745 {
746         struct btd_gatt_database *database = user_data;
747         struct ccc_state *ccc;
748         struct ccc_cb_data *ccc_cb;
749         uint16_t handle;
750         uint8_t ecode = 0;
751         bdaddr_t bdaddr;
752         uint8_t bdaddr_type;
753
754         handle = gatt_db_attribute_get_handle(attrib);
755
756         DBG("CCC write called for handle: 0x%04x", handle);
757
758         if (!value || len != 2) {
759                 ecode = BT_ATT_ERROR_INVALID_ATTRIBUTE_VALUE_LEN;
760                 goto done;
761         }
762
763         if (offset > 2) {
764                 ecode = BT_ATT_ERROR_INVALID_OFFSET;
765                 goto done;
766         }
767
768         if (!get_dst_info(att, &bdaddr, &bdaddr_type)) {
769                 ecode = BT_ATT_ERROR_UNLIKELY;
770                 goto done;
771         }
772
773         ccc = get_ccc_state(database, &bdaddr, bdaddr_type, handle);
774         if (!ccc) {
775                 ecode = BT_ATT_ERROR_UNLIKELY;
776                 goto done;
777         }
778
779         ccc_cb = queue_find(database->ccc_callbacks, ccc_cb_match_handle,
780                         UINT_TO_PTR(gatt_db_attribute_get_handle(attrib)));
781         if (!ccc_cb) {
782                 ecode = BT_ATT_ERROR_UNLIKELY;
783                 goto done;
784         }
785
786         /* If value is identical, then just succeed */
787         if (ccc->value[0] == value[0] && ccc->value[1] == value[1])
788                 goto done;
789
790         if (ccc_cb->callback)
791                 ecode = ccc_cb->callback(get_le16(value), ccc_cb->user_data);
792
793         if (!ecode) {
794                 ccc->value[0] = value[0];
795                 ccc->value[1] = value[1];
796         }
797
798 done:
799         gatt_db_attribute_write_result(attrib, id, ecode);
800 }
801
802 static struct gatt_db_attribute *
803 service_add_ccc(struct gatt_db_attribute *service,
804                                 struct btd_gatt_database *database,
805                                 btd_gatt_database_ccc_write_t write_callback,
806                                 void *user_data,
807                                 btd_gatt_database_destroy_t destroy)
808 {
809         struct gatt_db_attribute *ccc;
810         struct ccc_cb_data *ccc_cb;
811         bt_uuid_t uuid;
812
813         ccc_cb = new0(struct ccc_cb_data, 1);
814         if (!ccc_cb) {
815                 error("Could not allocate memory for callback data");
816                 return NULL;
817         }
818
819         bt_uuid16_create(&uuid, GATT_CLIENT_CHARAC_CFG_UUID);
820         ccc = gatt_db_service_add_descriptor(service, &uuid,
821                                 BT_ATT_PERM_READ | BT_ATT_PERM_WRITE,
822                                 gatt_ccc_read_cb, gatt_ccc_write_cb, database);
823         if (!ccc) {
824                 error("Failed to create CCC entry in database");
825                 free(ccc_cb);
826                 return NULL;
827         }
828
829         ccc_cb->handle = gatt_db_attribute_get_handle(ccc);
830         ccc_cb->callback = write_callback;
831         ccc_cb->destroy = destroy;
832         ccc_cb->user_data = user_data;
833
834         queue_push_tail(database->ccc_callbacks, ccc_cb);
835
836         return ccc;
837 }
838
839 struct gatt_db_attribute *
840 btd_gatt_database_add_ccc(struct btd_gatt_database *database,
841                                 uint16_t service_handle,
842                                 btd_gatt_database_ccc_write_t write_callback,
843                                 void *user_data,
844                                 btd_gatt_database_destroy_t destroy)
845 {
846         struct gatt_db_attribute *service;
847
848         if (!database || !service_handle)
849                 return NULL;
850
851         service = gatt_db_get_attribute(database->db, service_handle);
852         if (!service) {
853                 error("No service exists with handle: 0x%04x", service_handle);
854                 return NULL;
855         }
856
857         return service_add_ccc(service, database, write_callback, user_data,
858                                                                 destroy);
859 }
860
861 static void populate_gatt_service(struct btd_gatt_database *database)
862 {
863         bt_uuid_t uuid;
864         struct gatt_db_attribute *service;
865
866         /* Add the GATT service */
867         bt_uuid16_create(&uuid, UUID_GATT);
868         service = gatt_db_add_service(database->db, &uuid, true, 4);
869         database->gatt_handle = database_add_record(database, UUID_GATT,
870                                                 service,
871                                                 "Generic Attribute Profile");
872
873         bt_uuid16_create(&uuid, GATT_CHARAC_SERVICE_CHANGED);
874         database->svc_chngd = gatt_db_service_add_characteristic(service, &uuid,
875                                 BT_ATT_PERM_READ, BT_GATT_CHRC_PROP_INDICATE,
876                                 NULL, NULL, database);
877
878         database->svc_chngd_ccc = service_add_ccc(service, database, NULL, NULL,
879                                                                         NULL);
880
881         gatt_db_service_set_active(service, true);
882 }
883
884 static void register_core_services(struct btd_gatt_database *database)
885 {
886         populate_gap_service(database);
887         populate_gatt_service(database);
888 }
889
890 struct notify {
891         struct btd_gatt_database *database;
892         uint16_t handle, ccc_handle;
893         const uint8_t *value;
894         uint16_t len;
895         bool indicate;
896 };
897
898 static void conf_cb(void *user_data)
899 {
900         DBG("GATT server received confirmation");
901 }
902
903 static void send_notification_to_device(void *data, void *user_data)
904 {
905         struct device_state *device_state = data;
906         struct notify *notify = user_data;
907         struct ccc_state *ccc;
908         struct btd_device *device;
909
910         ccc = find_ccc_state(device_state, notify->ccc_handle);
911         if (!ccc)
912                 return;
913
914         if (!ccc->value[0] || (notify->indicate && !(ccc->value[0] & 0x02)))
915                 return;
916
917         device = btd_adapter_get_device(notify->database->adapter,
918                                                 &device_state->bdaddr,
919                                                 device_state->bdaddr_type);
920         if (!device)
921                 return;
922
923         /*
924          * TODO: If the device is not connected but bonded, send the
925          * notification/indication when it becomes connected.
926          */
927         if (!notify->indicate) {
928                 DBG("GATT server sending notification");
929                 bt_gatt_server_send_notification(
930                                         btd_device_get_gatt_server(device),
931                                         notify->handle, notify->value,
932                                         notify->len);
933                 return;
934         }
935
936         DBG("GATT server sending indication");
937         bt_gatt_server_send_indication(btd_device_get_gatt_server(device),
938                                                         notify->handle,
939                                                         notify->value,
940                                                         notify->len, conf_cb,
941                                                         NULL, NULL);
942 }
943
944 static void send_notification_to_devices(struct btd_gatt_database *database,
945                                         uint16_t handle, const uint8_t *value,
946                                         uint16_t len, uint16_t ccc_handle,
947                                         bool indicate)
948 {
949         struct notify notify;
950
951         memset(&notify, 0, sizeof(notify));
952
953         notify.database = database;
954         notify.handle = handle;
955         notify.ccc_handle = ccc_handle;
956         notify.value = value;
957         notify.len = len;
958         notify.indicate = indicate;
959
960         queue_foreach(database->device_states, send_notification_to_device,
961                                                                 &notify);
962 }
963
964 static void send_service_changed(struct btd_gatt_database *database,
965                                         struct gatt_db_attribute *attrib)
966 {
967         uint16_t start, end;
968         uint8_t value[4];
969         uint16_t handle, ccc_handle;
970
971         if (!gatt_db_attribute_get_service_handles(attrib, &start, &end)) {
972                 error("Failed to obtain changed service handles");
973                 return;
974         }
975
976         handle = gatt_db_attribute_get_handle(database->svc_chngd);
977         ccc_handle = gatt_db_attribute_get_handle(database->svc_chngd_ccc);
978
979         if (!handle || !ccc_handle) {
980                 error("Failed to obtain handles for \"Service Changed\""
981                                                         " characteristic");
982                 return;
983         }
984
985         put_le16(start, value);
986         put_le16(end, value + 2);
987
988         send_notification_to_devices(database, handle, value, sizeof(value),
989                                                         ccc_handle, true);
990 }
991
992 static void gatt_db_service_added(struct gatt_db_attribute *attrib,
993                                                                 void *user_data)
994 {
995         struct btd_gatt_database *database = user_data;
996
997         DBG("GATT Service added to local database");
998
999         send_service_changed(database, attrib);
1000 }
1001
1002 static bool ccc_match_service(const void *data, const void *match_data)
1003 {
1004         const struct ccc_state *ccc = data;
1005         const struct gatt_db_attribute *attrib = match_data;
1006         uint16_t start, end;
1007
1008         if (!gatt_db_attribute_get_service_handles(attrib, &start, &end))
1009                 return false;
1010
1011         return ccc->handle >= start && ccc->handle <= end;
1012 }
1013
1014 static void remove_device_ccc(void *data, void *user_data)
1015 {
1016         struct device_state *state = data;
1017
1018         queue_remove_all(state->ccc_states, ccc_match_service, user_data, free);
1019 }
1020
1021 static void gatt_db_service_removed(struct gatt_db_attribute *attrib,
1022                                                                 void *user_data)
1023 {
1024         struct btd_gatt_database *database = user_data;
1025
1026         DBG("Local GATT service removed");
1027
1028         send_service_changed(database, attrib);
1029
1030         queue_foreach(database->device_states, remove_device_ccc, attrib);
1031         queue_remove_all(database->ccc_callbacks, ccc_cb_match_service, attrib,
1032                                                                 ccc_cb_free);
1033 }
1034
1035 struct svc_match_data {
1036         const char *path;
1037         const char *sender;
1038 };
1039
1040 static bool match_service(const void *a, const void *b)
1041 {
1042         const struct external_service *service = a;
1043         const struct svc_match_data *data = b;
1044
1045         return g_strcmp0(service->path, data->path) == 0 &&
1046                                 g_strcmp0(service->owner, data->sender) == 0;
1047 }
1048
1049 static gboolean service_free_idle_cb(void *data)
1050 {
1051         service_free(data);
1052
1053         return FALSE;
1054 }
1055
1056 static void service_remove_helper(void *data)
1057 {
1058         struct external_service *service = data;
1059
1060         queue_remove(service->database->services, service);
1061
1062         /*
1063          * Do not run in the same loop, this may be a disconnect
1064          * watch call and GDBusClient should not be destroyed.
1065          */
1066         g_idle_add(service_free_idle_cb, service);
1067 }
1068
1069 static void client_disconnect_cb(DBusConnection *conn, void *user_data)
1070 {
1071         DBG("Client disconnected");
1072
1073         service_remove_helper(user_data);
1074 }
1075
1076 static void service_remove(void *data)
1077 {
1078         struct external_service *service = data;
1079
1080         /*
1081          * Set callback to NULL to avoid potential race condition
1082          * when calling remove_service and GDBusClient unref.
1083          */
1084         g_dbus_client_set_disconnect_watch(service->client, NULL, NULL);
1085
1086         /*
1087          * Set proxy handlers to NULL, so that this gets called only once when
1088          * the first proxy that belongs to this service gets removed.
1089          */
1090         g_dbus_client_set_proxy_handlers(service->client, NULL, NULL,
1091                                                                 NULL, NULL);
1092
1093         service_remove_helper(service);
1094 }
1095
1096 static struct external_chrc *chrc_create(struct external_service *service,
1097                                                         GDBusProxy *proxy,
1098                                                         const char *path)
1099 {
1100         struct external_chrc *chrc;
1101
1102         chrc = new0(struct external_chrc, 1);
1103         if (!chrc)
1104                 return NULL;
1105
1106         chrc->pending_reads = queue_new();
1107         if (!chrc->pending_reads) {
1108                 free(chrc);
1109                 return NULL;
1110         }
1111
1112         chrc->pending_writes = queue_new();
1113         if (!chrc->pending_writes) {
1114                 queue_destroy(chrc->pending_reads, NULL);
1115                 free(chrc);
1116                 return NULL;
1117         }
1118
1119         chrc->path = g_strdup(path);
1120         if (!chrc->path) {
1121                 queue_destroy(chrc->pending_reads, NULL);
1122                 queue_destroy(chrc->pending_writes, NULL);
1123                 free(chrc);
1124                 return NULL;
1125         }
1126
1127         chrc->service = service;
1128         chrc->proxy = g_dbus_proxy_ref(proxy);
1129
1130         return chrc;
1131 }
1132
1133 static struct external_desc *desc_create(struct external_service *service,
1134                                                         GDBusProxy *proxy,
1135                                                         const char *chrc_path)
1136 {
1137         struct external_desc *desc;
1138
1139         desc = new0(struct external_desc, 1);
1140         if (!desc)
1141                 return NULL;
1142
1143         desc->pending_reads = queue_new();
1144         if (!desc->pending_reads) {
1145                 free(desc);
1146                 return NULL;
1147         }
1148
1149         desc->pending_writes = queue_new();
1150         if (!desc->pending_writes) {
1151                 queue_destroy(desc->pending_reads, NULL);
1152                 free(desc);
1153                 return NULL;
1154         }
1155
1156         desc->chrc_path = g_strdup(chrc_path);
1157         if (!desc->chrc_path) {
1158                 queue_destroy(desc->pending_reads, NULL);
1159                 queue_destroy(desc->pending_writes, NULL);
1160                 free(desc);
1161                 return NULL;
1162         }
1163
1164         desc->service = service;
1165         desc->proxy = g_dbus_proxy_ref(proxy);
1166
1167         return desc;
1168 }
1169
1170 static bool incr_attr_count(struct external_service *service, uint16_t incr)
1171 {
1172         if (service->attr_cnt > UINT16_MAX - incr)
1173                 return false;
1174
1175         service->attr_cnt += incr;
1176
1177         return true;
1178 }
1179
1180 static bool parse_path(GDBusProxy *proxy, const char *name, const char **path)
1181 {
1182         DBusMessageIter iter;
1183
1184         if (!g_dbus_proxy_get_property(proxy, name, &iter))
1185                 return false;
1186
1187         if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_OBJECT_PATH)
1188                 return false;
1189
1190         dbus_message_iter_get_basic(&iter, path);
1191
1192         return true;
1193 }
1194
1195 static bool check_service_path(GDBusProxy *proxy,
1196                                         struct external_service *service)
1197 {
1198         const char *service_path;
1199
1200         if (!parse_path(proxy, "Service", &service_path))
1201                 return false;
1202
1203         return g_strcmp0(service_path, service->path) == 0;
1204 }
1205
1206 static bool parse_chrc_flags(DBusMessageIter *array, uint8_t *props,
1207                                                         uint8_t *ext_props)
1208 {
1209         const char *flag;
1210
1211         *props = *ext_props = 0;
1212
1213         do {
1214                 if (dbus_message_iter_get_arg_type(array) != DBUS_TYPE_STRING)
1215                         return false;
1216
1217                 dbus_message_iter_get_basic(array, &flag);
1218
1219                 if (!strcmp("broadcast", flag))
1220                         *props |= BT_GATT_CHRC_PROP_BROADCAST;
1221                 else if (!strcmp("read", flag))
1222                         *props |= BT_GATT_CHRC_PROP_READ;
1223                 else if (!strcmp("write-without-response", flag))
1224                         *props |= BT_GATT_CHRC_PROP_WRITE_WITHOUT_RESP;
1225                 else if (!strcmp("write", flag))
1226                         *props |= BT_GATT_CHRC_PROP_WRITE;
1227                 else if (!strcmp("notify", flag))
1228                         *props |= BT_GATT_CHRC_PROP_NOTIFY;
1229                 else if (!strcmp("indicate", flag))
1230                         *props |= BT_GATT_CHRC_PROP_INDICATE;
1231                 else if (!strcmp("authenticated-signed-writes", flag))
1232                         *props |= BT_GATT_CHRC_PROP_AUTH;
1233                 else if (!strcmp("reliable-write", flag))
1234                         *ext_props |= BT_GATT_CHRC_EXT_PROP_RELIABLE_WRITE;
1235                 else if (!strcmp("writable-auxiliaries", flag))
1236                         *ext_props |= BT_GATT_CHRC_EXT_PROP_WRITABLE_AUX;
1237                 else if (!strcmp("encrypt-read", flag)) {
1238                         *props |= BT_GATT_CHRC_PROP_READ;
1239                         *ext_props |= BT_GATT_CHRC_EXT_PROP_ENC_READ;
1240                 } else if (!strcmp("encrypt-write", flag)) {
1241                         *props |= BT_GATT_CHRC_PROP_WRITE;
1242                         *ext_props |= BT_GATT_CHRC_EXT_PROP_ENC_WRITE;
1243                 } else if (!strcmp("encrypt-authenticated-read", flag)) {
1244                         *props |= BT_GATT_CHRC_PROP_READ;
1245                         *ext_props |= BT_GATT_CHRC_EXT_PROP_AUTH_READ;
1246                 } else if (!strcmp("encrypt-authenticated-write", flag)) {
1247                         *props |= BT_GATT_CHRC_PROP_WRITE;
1248                         *ext_props |= BT_GATT_CHRC_EXT_PROP_AUTH_WRITE;
1249                 } else {
1250                         error("Invalid characteristic flag: %s", flag);
1251                         return false;
1252                 }
1253         } while (dbus_message_iter_next(array));
1254
1255         if (*ext_props)
1256                 *props |= BT_GATT_CHRC_PROP_EXT_PROP;
1257
1258         return true;
1259 }
1260
1261 static bool parse_desc_flags(DBusMessageIter *array, uint32_t *perm)
1262 {
1263         const char *flag;
1264
1265         *perm = 0;
1266
1267         do {
1268                 if (dbus_message_iter_get_arg_type(array) != DBUS_TYPE_STRING)
1269                         return false;
1270
1271                 dbus_message_iter_get_basic(array, &flag);
1272
1273                 if (!strcmp("read", flag))
1274                         *perm |= BT_ATT_PERM_READ;
1275                 else if (!strcmp("write", flag))
1276                         *perm |= BT_ATT_PERM_WRITE;
1277                 else if (!strcmp("encrypt-read", flag))
1278                         *perm |= BT_ATT_PERM_READ | BT_ATT_PERM_READ_ENCRYPT;
1279                 else if (!strcmp("encrypt-write", flag))
1280                         *perm |= BT_ATT_PERM_WRITE | BT_ATT_PERM_WRITE_ENCRYPT;
1281                 else if (!strcmp("encrypt-authenticated-read", flag))
1282                         *perm |= BT_ATT_PERM_READ | BT_ATT_PERM_READ_AUTHEN;
1283                 else if (!strcmp("encrypt-authenticated-write", flag))
1284                         *perm |= BT_ATT_PERM_WRITE | BT_ATT_PERM_WRITE_AUTHEN;
1285                 else {
1286                         error("Invalid descriptor flag: %s", flag);
1287                         return false;
1288                 }
1289         } while (dbus_message_iter_next(array));
1290
1291         return true;
1292 }
1293
1294 static bool parse_flags(GDBusProxy *proxy, uint8_t *props, uint8_t *ext_props,
1295                                                                 uint32_t *perm)
1296 {
1297         DBusMessageIter iter, array;
1298
1299         if (!g_dbus_proxy_get_property(proxy, "Flags", &iter))
1300                 return false;
1301
1302         if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY)
1303                 return false;
1304
1305         dbus_message_iter_recurse(&iter, &array);
1306
1307         if (perm)
1308                 return parse_desc_flags(&array, perm);
1309
1310         return parse_chrc_flags(&array, props, ext_props);
1311 }
1312
1313 static void proxy_added_cb(GDBusProxy *proxy, void *user_data)
1314 {
1315         struct external_service *service = user_data;
1316         const char *iface, *path;
1317
1318         if (service->failed || service->attrib)
1319                 return;
1320
1321         iface = g_dbus_proxy_get_interface(proxy);
1322         path = g_dbus_proxy_get_path(proxy);
1323
1324         if (!g_str_has_prefix(path, service->path))
1325                 return;
1326
1327         if (g_strcmp0(iface, GATT_SERVICE_IFACE) == 0) {
1328                 if (service->proxy)
1329                         return;
1330
1331                 /*
1332                  * TODO: We may want to support adding included services in a
1333                  * single hierarchy.
1334                  */
1335                 if (g_strcmp0(path, service->path) != 0) {
1336                         error("Multiple services added within hierarchy");
1337                         service->failed = true;
1338                         return;
1339                 }
1340
1341                 /* Add 1 for the service declaration */
1342                 if (!incr_attr_count(service, 1)) {
1343                         error("Failed to increment attribute count");
1344                         service->failed = true;
1345                         return;
1346                 }
1347
1348                 service->proxy = g_dbus_proxy_ref(proxy);
1349         } else if (g_strcmp0(iface, GATT_CHRC_IFACE) == 0) {
1350                 struct external_chrc *chrc;
1351
1352                 if (g_strcmp0(path, service->path) == 0) {
1353                         error("Characteristic path same as service path");
1354                         service->failed = true;
1355                         return;
1356                 }
1357
1358                 chrc = chrc_create(service, proxy, path);
1359                 if (!chrc) {
1360                         service->failed = true;
1361                         return;
1362                 }
1363
1364                 /*
1365                  * Add 2 for the characteristic declaration and the value
1366                  * attribute.
1367                  */
1368                 if (!incr_attr_count(service, 2)) {
1369                         error("Failed to increment attribute count");
1370                         service->failed = true;
1371                         return;
1372                 }
1373
1374                 /*
1375                  * Parse characteristic flags (i.e. properties) here since they
1376                  * are used to determine if any special descriptors should be
1377                  * created.
1378                  */
1379                 if (!parse_flags(proxy, &chrc->props, &chrc->ext_props, NULL)) {
1380                         error("Failed to parse characteristic properties");
1381                         service->failed = true;
1382                         return;
1383                 }
1384
1385                 if ((chrc->props & BT_GATT_CHRC_PROP_NOTIFY ||
1386                                 chrc->props & BT_GATT_CHRC_PROP_INDICATE) &&
1387                                 !incr_attr_count(service, 1)) {
1388                         error("Failed to increment attribute count for CCC");
1389                         service->failed = true;
1390                         return;
1391                 }
1392
1393                 if (chrc->ext_props && !incr_attr_count(service, 1)) {
1394                         error("Failed to increment attribute count for CEP");
1395                         service->failed = true;
1396                         return;
1397                 }
1398
1399                 queue_push_tail(service->chrcs, chrc);
1400         } else if (g_strcmp0(iface, GATT_DESC_IFACE) == 0) {
1401                 struct external_desc *desc;
1402                 const char *chrc_path;
1403
1404                 if (!parse_path(proxy, "Characteristic", &chrc_path)) {
1405                         error("Failed to obtain characteristic path for "
1406                                                                 "descriptor");
1407                         service->failed = true;
1408                         return;
1409                 }
1410
1411                 desc = desc_create(service, proxy, chrc_path);
1412                 if (!desc) {
1413                         service->failed = true;
1414                         return;
1415                 }
1416
1417                 /* Add 1 for the descriptor attribute */
1418                 if (!incr_attr_count(service, 1)) {
1419                         error("Failed to increment attribute count");
1420                         service->failed = true;
1421                         return;
1422                 }
1423
1424                 /*
1425                  * Parse descriptors flags here since they are used to
1426                  * determine the permission the descriptor should have
1427                  */
1428                 if (!parse_flags(proxy, NULL, NULL, &desc->perm)) {
1429                         error("Failed to parse characteristic properties");
1430                         service->failed = true;
1431                         return;
1432                 }
1433
1434                 queue_push_tail(service->descs, desc);
1435         } else {
1436                 DBG("Ignoring unrelated interface: %s", iface);
1437                 return;
1438         }
1439
1440         DBG("Object added to service - path: %s, iface: %s", path, iface);
1441 }
1442
1443 static void proxy_removed_cb(GDBusProxy *proxy, void *user_data)
1444 {
1445         struct external_service *service = user_data;
1446         const char *path;
1447
1448         path = g_dbus_proxy_get_path(proxy);
1449
1450         if (!g_str_has_prefix(path, service->path))
1451                 return;
1452
1453         DBG("Proxy removed - removing service: %s", service->path);
1454
1455         service_remove(service);
1456 }
1457
1458 static bool parse_uuid(GDBusProxy *proxy, bt_uuid_t *uuid)
1459 {
1460         DBusMessageIter iter;
1461         bt_uuid_t tmp;
1462         const char *uuidstr;
1463
1464         if (!g_dbus_proxy_get_property(proxy, "UUID", &iter))
1465                 return false;
1466
1467         if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
1468                 return false;
1469
1470         dbus_message_iter_get_basic(&iter, &uuidstr);
1471
1472         if (bt_string_to_uuid(uuid, uuidstr) < 0)
1473                 return false;
1474
1475         /* GAP & GATT services are created and managed by BlueZ */
1476         bt_uuid16_create(&tmp, UUID_GAP);
1477         if (!bt_uuid_cmp(&tmp, uuid)) {
1478                 error("GAP service must be handled by BlueZ");
1479                 return false;
1480         }
1481
1482         bt_uuid16_create(&tmp, UUID_GATT);
1483         if (!bt_uuid_cmp(&tmp, uuid)) {
1484                 error("GATT service must be handled by BlueZ");
1485                 return false;
1486         }
1487
1488         return true;
1489 }
1490
1491 static bool parse_primary(GDBusProxy *proxy, bool *primary)
1492 {
1493         DBusMessageIter iter;
1494         dbus_bool_t val;
1495
1496         if (!g_dbus_proxy_get_property(proxy, "Primary", &iter))
1497                 return false;
1498
1499         if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_BOOLEAN)
1500                 return false;
1501
1502         dbus_message_iter_get_basic(&iter, &val);
1503
1504         *primary = val;
1505
1506         return true;
1507 }
1508
1509 static uint8_t dbus_error_to_att_ecode(const char *error_name)
1510 {
1511
1512         if (strcmp(error_name, "org.bluez.Error.Failed") == 0)
1513                 return 0x80;  /* For now return this "application error" */
1514
1515         if (strcmp(error_name, "org.bluez.Error.NotSupported") == 0)
1516                 return BT_ATT_ERROR_REQUEST_NOT_SUPPORTED;
1517
1518         if (strcmp(error_name, "org.bluez.Error.NotAuthorized") == 0)
1519                 return BT_ATT_ERROR_AUTHORIZATION;
1520
1521         if (strcmp(error_name, "org.bluez.Error.InvalidValueLength") == 0)
1522                 return BT_ATT_ERROR_INVALID_ATTRIBUTE_VALUE_LEN;
1523
1524         if (strcmp(error_name, "org.bluez.Error.InProgress") == 0)
1525                 return BT_ERROR_ALREADY_IN_PROGRESS;
1526
1527         return 0;
1528 }
1529
1530 static void read_reply_cb(DBusMessage *message, void *user_data)
1531 {
1532         struct pending_op *op = user_data;
1533         DBusError err;
1534         DBusMessageIter iter, array;
1535         uint8_t ecode = 0;
1536         uint8_t *value = NULL;
1537         int len = 0;
1538
1539         if (!op->owner_queue) {
1540                 DBG("Pending read was canceled when object got removed");
1541                 return;
1542         }
1543
1544         dbus_error_init(&err);
1545
1546         if (dbus_set_error_from_message(&err, message) == TRUE) {
1547                 DBG("Failed to read value: %s: %s", err.name, err.message);
1548                 ecode = dbus_error_to_att_ecode(err.name);
1549                 ecode = ecode ? ecode : BT_ATT_ERROR_READ_NOT_PERMITTED;
1550                 dbus_error_free(&err);
1551                 goto done;
1552         }
1553
1554         dbus_message_iter_init(message, &iter);
1555
1556         if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) {
1557                 /*
1558                  * Return not supported for this, as the external app basically
1559                  * doesn't properly support reading from this characteristic.
1560                  */
1561                 ecode = BT_ATT_ERROR_REQUEST_NOT_SUPPORTED;
1562                 error("Invalid return value received for \"ReadValue\"");
1563                 goto done;
1564         }
1565
1566         dbus_message_iter_recurse(&iter, &array);
1567         dbus_message_iter_get_fixed_array(&array, &value, &len);
1568
1569         if (len < 0) {
1570                 ecode = BT_ATT_ERROR_REQUEST_NOT_SUPPORTED;
1571                 value = NULL;
1572                 len = 0;
1573                 goto done;
1574         }
1575
1576         /* Truncate the value if it's too large */
1577         len = MIN(BT_ATT_MAX_VALUE_LEN, len);
1578         value = len ? value : NULL;
1579
1580 done:
1581         gatt_db_attribute_read_result(op->attrib, op->id, ecode, value, len);
1582 }
1583
1584 static void pending_op_free(void *data)
1585 {
1586         struct pending_op *op = data;
1587
1588         if (op->owner_queue)
1589                 queue_remove(op->owner_queue, op);
1590
1591         free(op);
1592 }
1593
1594 static struct pending_op *pending_read_new(struct queue *owner_queue,
1595                                         struct gatt_db_attribute *attrib,
1596                                         unsigned int id)
1597 {
1598         struct pending_op *op;
1599
1600         op = new0(struct pending_op, 1);
1601         if (!op)
1602                 return NULL;
1603
1604         op->owner_queue = owner_queue;
1605         op->attrib = attrib;
1606         op->id = id;
1607         queue_push_tail(owner_queue, op);
1608
1609         return op;
1610 }
1611
1612 static void send_read(struct gatt_db_attribute *attrib, GDBusProxy *proxy,
1613                                                 struct queue *owner_queue,
1614                                                 unsigned int id)
1615 {
1616         struct pending_op *op;
1617         uint8_t ecode = BT_ATT_ERROR_UNLIKELY;
1618
1619         op = pending_read_new(owner_queue, attrib, id);
1620         if (!op) {
1621                 error("Failed to allocate memory for pending read call");
1622                 ecode = BT_ATT_ERROR_INSUFFICIENT_RESOURCES;
1623                 goto error;
1624         }
1625
1626         if (g_dbus_proxy_method_call(proxy, "ReadValue", NULL, read_reply_cb,
1627                                                 op, pending_op_free) == TRUE)
1628                 return;
1629
1630         pending_op_free(op);
1631
1632 error:
1633         gatt_db_attribute_read_result(attrib, id, ecode, NULL, 0);
1634 }
1635
1636 static void write_setup_cb(DBusMessageIter *iter, void *user_data)
1637 {
1638         struct pending_op *op = user_data;
1639         DBusMessageIter array;
1640
1641         dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY, "y", &array);
1642         dbus_message_iter_append_fixed_array(&array, DBUS_TYPE_BYTE,
1643                                         &op->data.iov_base, op->data.iov_len);
1644         dbus_message_iter_close_container(iter, &array);
1645 }
1646
1647 static void write_reply_cb(DBusMessage *message, void *user_data)
1648 {
1649         struct pending_op *op = user_data;
1650         DBusError err;
1651         DBusMessageIter iter;
1652         uint8_t ecode = 0;
1653
1654         if (!op->owner_queue) {
1655                 DBG("Pending write was canceled when object got removed");
1656                 return;
1657         }
1658
1659         dbus_error_init(&err);
1660
1661         if (dbus_set_error_from_message(&err, message) == TRUE) {
1662                 DBG("Failed to write value: %s: %s", err.name, err.message);
1663                 ecode = dbus_error_to_att_ecode(err.name);
1664                 ecode = ecode ? ecode : BT_ATT_ERROR_WRITE_NOT_PERMITTED;
1665                 dbus_error_free(&err);
1666                 goto done;
1667         }
1668
1669         dbus_message_iter_init(message, &iter);
1670         if (dbus_message_iter_has_next(&iter)) {
1671                 /*
1672                  * Return not supported for this, as the external app basically
1673                  * doesn't properly support the "WriteValue" API.
1674                  */
1675                 ecode = BT_ATT_ERROR_REQUEST_NOT_SUPPORTED;
1676                 error("Invalid return value received for \"WriteValue\"");
1677         }
1678
1679 done:
1680         gatt_db_attribute_write_result(op->attrib, op->id, ecode);
1681 }
1682
1683 static struct pending_op *pending_write_new(struct queue *owner_queue,
1684                                         struct gatt_db_attribute *attrib,
1685                                         unsigned int id,
1686                                         const uint8_t *value,
1687                                         size_t len)
1688 {
1689         struct pending_op *op;
1690
1691         op = new0(struct pending_op, 1);
1692         if (!op)
1693                 return NULL;
1694
1695         op->data.iov_base = (uint8_t *) value;
1696         op->data.iov_len = len;
1697
1698         op->owner_queue = owner_queue;
1699         op->attrib = attrib;
1700         op->id = id;
1701         queue_push_tail(owner_queue, op);
1702
1703         return op;
1704 }
1705
1706 static void send_write(struct gatt_db_attribute *attrib, GDBusProxy *proxy,
1707                                         struct queue *owner_queue,
1708                                         unsigned int id,
1709                                         const uint8_t *value, size_t len)
1710 {
1711         struct pending_op *op;
1712         uint8_t ecode = BT_ATT_ERROR_UNLIKELY;
1713
1714         op = pending_write_new(owner_queue, attrib, id, value, len);
1715         if (!op) {
1716                 error("Failed to allocate memory for pending read call");
1717                 ecode = BT_ATT_ERROR_INSUFFICIENT_RESOURCES;
1718                 goto error;
1719         }
1720
1721         if (g_dbus_proxy_method_call(proxy, "WriteValue", write_setup_cb,
1722                                                 write_reply_cb, op,
1723                                                 pending_op_free) == TRUE)
1724                 return;
1725
1726         pending_op_free(op);
1727
1728 error:
1729         gatt_db_attribute_write_result(attrib, id, ecode);
1730 }
1731
1732 static uint32_t permissions_from_props(uint8_t props, uint8_t ext_props)
1733 {
1734         uint32_t perm = 0;
1735
1736         if (props & BT_GATT_CHRC_PROP_WRITE ||
1737                         props & BT_GATT_CHRC_PROP_WRITE_WITHOUT_RESP ||
1738                         ext_props & BT_GATT_CHRC_EXT_PROP_RELIABLE_WRITE ||
1739                         ext_props & BT_GATT_CHRC_EXT_PROP_ENC_WRITE ||
1740                         ext_props & BT_GATT_CHRC_EXT_PROP_AUTH_WRITE)
1741                 perm |= BT_ATT_PERM_WRITE;
1742
1743         if (props & BT_GATT_CHRC_PROP_READ ||
1744                         ext_props & BT_GATT_CHRC_EXT_PROP_ENC_READ ||
1745                         ext_props & BT_GATT_CHRC_EXT_PROP_AUTH_READ)
1746                 perm |= BT_ATT_PERM_READ;
1747
1748         if (ext_props & BT_GATT_CHRC_EXT_PROP_ENC_READ)
1749                 perm |= BT_ATT_PERM_READ_ENCRYPT;
1750
1751         if (ext_props & BT_GATT_CHRC_EXT_PROP_ENC_WRITE)
1752                 perm |= BT_ATT_PERM_WRITE_ENCRYPT;
1753
1754         if (ext_props & BT_GATT_CHRC_EXT_PROP_AUTH_READ)
1755                 perm |= BT_ATT_PERM_READ_AUTHEN;
1756
1757         if (ext_props & BT_GATT_CHRC_EXT_PROP_AUTH_WRITE)
1758                 perm |= BT_ATT_PERM_WRITE_AUTHEN;
1759
1760         return perm;
1761 }
1762
1763 static uint8_t ccc_write_cb(uint16_t value, void *user_data)
1764 {
1765         struct external_chrc *chrc = user_data;
1766
1767         DBG("External CCC write received with value: 0x%04x", value);
1768
1769         /* Notifications/indications disabled */
1770         if (!value) {
1771                 if (!chrc->ntfy_cnt)
1772                         return 0;
1773
1774                 if (__sync_sub_and_fetch(&chrc->ntfy_cnt, 1))
1775                         return 0;
1776
1777                 /*
1778                  * Send request to stop notifying. This is best-effort
1779                  * operation, so simply ignore the return the value.
1780                  */
1781                 g_dbus_proxy_method_call(chrc->proxy, "StopNotify", NULL,
1782                                                         NULL, NULL, NULL);
1783                 return 0;
1784         }
1785
1786         /*
1787          * TODO: All of the errors below should fall into the so called
1788          * "Application Error" range. Since there is no well defined error for
1789          * these, we return a generic ATT protocol error for now.
1790          */
1791
1792         if (chrc->ntfy_cnt == UINT_MAX) {
1793                 /* Maximum number of per-device CCC descriptors configured */
1794                 return BT_ATT_ERROR_REQUEST_NOT_SUPPORTED;
1795         }
1796
1797         /* Don't support undefined CCC values yet */
1798         if (value > 2 ||
1799                 (value == 1 && !(chrc->props & BT_GATT_CHRC_PROP_NOTIFY)) ||
1800                 (value == 2 && !(chrc->props & BT_GATT_CHRC_PROP_INDICATE)))
1801                 return BT_ATT_ERROR_REQUEST_NOT_SUPPORTED;
1802
1803         /*
1804          * Always call StartNotify for an incoming enable and ignore the return
1805          * value for now.
1806          */
1807         if (g_dbus_proxy_method_call(chrc->proxy,
1808                                                 "StartNotify", NULL, NULL,
1809                                                 NULL, NULL) == FALSE)
1810                 return BT_ATT_ERROR_REQUEST_NOT_SUPPORTED;
1811
1812         __sync_fetch_and_add(&chrc->ntfy_cnt, 1);
1813
1814         return 0;
1815 }
1816
1817 static void property_changed_cb(GDBusProxy *proxy, const char *name,
1818                                         DBusMessageIter *iter, void *user_data)
1819 {
1820         struct external_chrc *chrc = user_data;
1821         DBusMessageIter array;
1822         uint8_t *value = NULL;
1823         int len = 0;
1824
1825         if (strcmp(name, "Value"))
1826                 return;
1827
1828         if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY) {
1829                 DBG("Malformed \"Value\" property received");
1830                 return;
1831         }
1832
1833         dbus_message_iter_recurse(iter, &array);
1834         dbus_message_iter_get_fixed_array(&array, &value, &len);
1835
1836         if (len < 0) {
1837                 DBG("Malformed \"Value\" property received");
1838                 return;
1839         }
1840
1841         /* Truncate the value if it's too large */
1842         len = MIN(BT_ATT_MAX_VALUE_LEN, len);
1843         value = len ? value : NULL;
1844
1845         send_notification_to_devices(chrc->service->database,
1846                                 gatt_db_attribute_get_handle(chrc->attrib),
1847                                 value, len,
1848                                 gatt_db_attribute_get_handle(chrc->ccc),
1849                                 chrc->props & BT_GATT_CHRC_PROP_INDICATE);
1850 }
1851
1852 static bool database_add_ccc(struct external_service *service,
1853                                                 struct external_chrc *chrc)
1854 {
1855         if (!(chrc->props & BT_GATT_CHRC_PROP_NOTIFY) &&
1856                                 !(chrc->props & BT_GATT_CHRC_PROP_INDICATE))
1857                 return true;
1858
1859         chrc->ccc = service_add_ccc(service->attrib, service->database,
1860                                                 ccc_write_cb, chrc, NULL);
1861         if (!chrc->ccc) {
1862                 error("Failed to create CCC entry for characteristic");
1863                 return false;
1864         }
1865
1866         if (g_dbus_proxy_set_property_watch(chrc->proxy, property_changed_cb,
1867                                                         chrc) == FALSE) {
1868                 error("Failed to set up property watch for characteristic");
1869                 return false;
1870         }
1871
1872         DBG("Created CCC entry for characteristic");
1873
1874         return true;
1875 }
1876
1877 static void cep_write_cb(struct gatt_db_attribute *attrib, int err,
1878                                                                 void *user_data)
1879 {
1880         if (err)
1881                 DBG("Failed to store CEP value in the database");
1882         else
1883                 DBG("Stored CEP value in the database");
1884 }
1885
1886 static bool database_add_cep(struct external_service *service,
1887                                                 struct external_chrc *chrc)
1888 {
1889         struct gatt_db_attribute *cep;
1890         bt_uuid_t uuid;
1891         uint8_t value[2];
1892
1893         if (!chrc->ext_props)
1894                 return true;
1895
1896         bt_uuid16_create(&uuid, GATT_CHARAC_EXT_PROPER_UUID);
1897         cep = gatt_db_service_add_descriptor(service->attrib, &uuid,
1898                                                         BT_ATT_PERM_READ,
1899                                                         NULL, NULL, NULL);
1900         if (!cep) {
1901                 error("Failed to create CEP entry for characteristic");
1902                 return false;
1903         }
1904
1905         memset(value, 0, sizeof(value));
1906         value[0] = chrc->ext_props;
1907
1908         if (!gatt_db_attribute_write(cep, 0, value, sizeof(value), 0, NULL,
1909                                                         cep_write_cb, NULL)) {
1910                 DBG("Failed to store CEP value in the database");
1911                 return false;
1912         }
1913
1914         DBG("Created CEP entry for characteristic");
1915
1916         return true;
1917 }
1918
1919 static void desc_read_cb(struct gatt_db_attribute *attrib,
1920                                         unsigned int id, uint16_t offset,
1921                                         uint8_t opcode, struct bt_att *att,
1922                                         void *user_data)
1923 {
1924         struct external_desc *desc = user_data;
1925
1926         if (desc->attrib != attrib) {
1927                 error("Read callback called with incorrect attribute");
1928                 return;
1929         }
1930
1931         send_read(attrib, desc->proxy, desc->pending_reads, id);
1932 }
1933
1934 static void desc_write_cb(struct gatt_db_attribute *attrib,
1935                                         unsigned int id, uint16_t offset,
1936                                         const uint8_t *value, size_t len,
1937                                         uint8_t opcode, struct bt_att *att,
1938                                         void *user_data)
1939 {
1940         struct external_desc *desc = user_data;
1941
1942         if (desc->attrib != attrib) {
1943                 error("Read callback called with incorrect attribute");
1944                 return;
1945         }
1946
1947         send_write(attrib, desc->proxy, desc->pending_writes, id, value, len);
1948 }
1949
1950 static bool database_add_desc(struct external_service *service,
1951                                                 struct external_desc *desc)
1952 {
1953         bt_uuid_t uuid;
1954
1955         if (!parse_uuid(desc->proxy, &uuid)) {
1956                 error("Failed to read \"UUID\" property of descriptor");
1957                 return false;
1958         }
1959
1960         desc->attrib = gatt_db_service_add_descriptor(service->attrib, &uuid,
1961                                                         desc->perm,
1962                                                         desc_read_cb,
1963                                                         desc_write_cb, desc);
1964         if (!desc->attrib) {
1965                 error("Failed to create descriptor entry in database");
1966                 return false;
1967         }
1968
1969         desc->handled = true;
1970
1971         return true;
1972 }
1973
1974 static void chrc_read_cb(struct gatt_db_attribute *attrib,
1975                                         unsigned int id, uint16_t offset,
1976                                         uint8_t opcode, struct bt_att *att,
1977                                         void *user_data)
1978 {
1979         struct external_chrc *chrc = user_data;
1980
1981         if (chrc->attrib != attrib) {
1982                 error("Read callback called with incorrect attribute");
1983                 return;
1984         }
1985
1986         send_read(attrib, chrc->proxy, chrc->pending_reads, id);
1987 }
1988
1989 static void chrc_write_cb(struct gatt_db_attribute *attrib,
1990                                         unsigned int id, uint16_t offset,
1991                                         const uint8_t *value, size_t len,
1992                                         uint8_t opcode, struct bt_att *att,
1993                                         void *user_data)
1994 {
1995         struct external_chrc *chrc = user_data;
1996
1997         if (chrc->attrib != attrib) {
1998                 error("Write callback called with incorrect attribute");
1999                 return;
2000         }
2001
2002         send_write(attrib, chrc->proxy, chrc->pending_writes, id, value, len);
2003 }
2004
2005 static bool database_add_chrc(struct external_service *service,
2006                                                 struct external_chrc *chrc)
2007 {
2008         bt_uuid_t uuid;
2009         uint32_t perm;
2010         const struct queue_entry *entry;
2011
2012         if (!parse_uuid(chrc->proxy, &uuid)) {
2013                 error("Failed to read \"UUID\" property of characteristic");
2014                 return false;
2015         }
2016
2017         if (!check_service_path(chrc->proxy, service)) {
2018                 error("Invalid service path for characteristic");
2019                 return false;
2020         }
2021
2022         /*
2023          * TODO: Once shared/gatt-server properly supports permission checks,
2024          * set the permissions based on a D-Bus property of the external
2025          * characteristic.
2026          */
2027         perm = permissions_from_props(chrc->props, chrc->ext_props);
2028         chrc->attrib = gatt_db_service_add_characteristic(service->attrib,
2029                                                 &uuid, perm,
2030                                                 chrc->props, chrc_read_cb,
2031                                                 chrc_write_cb, chrc);
2032         if (!chrc->attrib) {
2033                 error("Failed to create characteristic entry in database");
2034                 return false;
2035         }
2036
2037         if (!database_add_ccc(service, chrc))
2038                 return false;
2039
2040         if (!database_add_cep(service, chrc))
2041                 return false;
2042
2043         /* Handle the descriptors that belong to this characteristic. */
2044         for (entry = queue_get_entries(service->descs); entry;
2045                                                         entry = entry->next) {
2046                 struct external_desc *desc = entry->data;
2047
2048                 if (desc->handled || g_strcmp0(desc->chrc_path, chrc->path))
2049                         continue;
2050
2051                 if (!database_add_desc(service, desc)) {
2052                         chrc->attrib = NULL;
2053                         error("Failed to create descriptor entry");
2054                         return false;
2055                 }
2056         }
2057
2058         return true;
2059 }
2060
2061 static bool match_desc_unhandled(const void *a, const void *b)
2062 {
2063         const struct external_desc *desc = a;
2064
2065         return !desc->handled;
2066 }
2067
2068 static bool create_service_entry(struct external_service *service)
2069 {
2070         bt_uuid_t uuid;
2071         bool primary;
2072         const struct queue_entry *entry;
2073
2074         if (!parse_uuid(service->proxy, &uuid)) {
2075                 error("Failed to read \"UUID\" property of service");
2076                 return false;
2077         }
2078
2079         if (!parse_primary(service->proxy, &primary)) {
2080                 error("Failed to read \"Primary\" property of service");
2081                 return false;
2082         }
2083
2084         service->attrib = gatt_db_add_service(service->database->db, &uuid,
2085                                                 primary, service->attr_cnt);
2086         if (!service->attrib)
2087                 return false;
2088
2089         entry = queue_get_entries(service->chrcs);
2090         while (entry) {
2091                 struct external_chrc *chrc = entry->data;
2092
2093                 if (!database_add_chrc(service, chrc)) {
2094                         error("Failed to add characteristic");
2095                         goto fail;
2096                 }
2097
2098                 entry = entry->next;
2099         }
2100
2101         /* If there are any unhandled descriptors, return an error */
2102         if (queue_find(service->descs, match_desc_unhandled, NULL)) {
2103                 error("Found descriptor with no matching characteristic!");
2104                 goto fail;
2105         }
2106
2107         gatt_db_service_set_active(service->attrib, true);
2108
2109         return true;
2110
2111 fail:
2112         gatt_db_remove_service(service->database->db, service->attrib);
2113         service->attrib = NULL;
2114
2115         return false;
2116 }
2117
2118 static void client_ready_cb(GDBusClient *client, void *user_data)
2119 {
2120         struct external_service *service = user_data;
2121         DBusMessage *reply;
2122         bool fail = false;
2123
2124         if (!service->proxy || service->failed) {
2125                 error("No valid external GATT objects found");
2126                 fail = true;
2127                 reply = btd_error_failed(service->reg,
2128                                         "No valid service object found");
2129                 goto reply;
2130         }
2131
2132         if (!create_service_entry(service)) {
2133                 error("Failed to create GATT service entry in local database");
2134                 fail = true;
2135                 reply = btd_error_failed(service->reg,
2136                                         "Failed to create entry in database");
2137                 goto reply;
2138         }
2139
2140         DBG("GATT service registered: %s", service->path);
2141
2142         reply = dbus_message_new_method_return(service->reg);
2143
2144 reply:
2145         g_dbus_send_message(btd_get_dbus_connection(), reply);
2146         dbus_message_unref(service->reg);
2147         service->reg = NULL;
2148
2149         if (fail)
2150                 service_remove(service);
2151 }
2152
2153 static struct external_service *service_create(DBusConnection *conn,
2154                                         DBusMessage *msg, const char *path)
2155 {
2156         struct external_service *service;
2157         const char *sender = dbus_message_get_sender(msg);
2158
2159         if (!path || !g_str_has_prefix(path, "/"))
2160                 return NULL;
2161
2162         service = new0(struct external_service, 1);
2163         if (!service)
2164                 return NULL;
2165
2166         service->client = g_dbus_client_new_full(conn, sender, path, path);
2167         if (!service->client)
2168                 goto fail;
2169
2170         service->owner = g_strdup(sender);
2171         if (!service->owner)
2172                 goto fail;
2173
2174         service->path = g_strdup(path);
2175         if (!service->path)
2176                 goto fail;
2177
2178         service->chrcs = queue_new();
2179         if (!service->chrcs)
2180                 goto fail;
2181
2182         service->descs = queue_new();
2183         if (!service->descs)
2184                 goto fail;
2185
2186         service->reg = dbus_message_ref(msg);
2187
2188         g_dbus_client_set_disconnect_watch(service->client,
2189                                                 client_disconnect_cb, service);
2190         g_dbus_client_set_proxy_handlers(service->client, proxy_added_cb,
2191                                                         proxy_removed_cb, NULL,
2192                                                         service);
2193         g_dbus_client_set_ready_watch(service->client, client_ready_cb,
2194                                                                 service);
2195
2196         return service;
2197
2198 fail:
2199         service_free(service);
2200         return NULL;
2201 }
2202
2203 static DBusMessage *manager_register_service(DBusConnection *conn,
2204                                         DBusMessage *msg, void *user_data)
2205 {
2206         struct btd_gatt_database *database = user_data;
2207         const char *sender = dbus_message_get_sender(msg);
2208         DBusMessageIter args;
2209         const char *path;
2210         struct external_service *service;
2211         struct svc_match_data match_data;
2212
2213         if (!dbus_message_iter_init(msg, &args))
2214                 return btd_error_invalid_args(msg);
2215
2216         if (dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_OBJECT_PATH)
2217                 return btd_error_invalid_args(msg);
2218
2219         dbus_message_iter_get_basic(&args, &path);
2220
2221         match_data.path = path;
2222         match_data.sender = sender;
2223
2224         if (queue_find(database->services, match_service, &match_data))
2225                 return btd_error_already_exists(msg);
2226
2227         dbus_message_iter_next(&args);
2228         if (dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_ARRAY)
2229                 return btd_error_invalid_args(msg);
2230
2231         service = service_create(conn, msg, path);
2232         if (!service)
2233                 return btd_error_failed(msg, "Failed to register service");
2234
2235         DBG("Registering service - path: %s", path);
2236
2237         service->database = database;
2238         queue_push_tail(database->services, service);
2239
2240         return NULL;
2241 }
2242
2243 static DBusMessage *manager_unregister_service(DBusConnection *conn,
2244                                         DBusMessage *msg, void *user_data)
2245 {
2246         struct btd_gatt_database *database = user_data;
2247         const char *sender = dbus_message_get_sender(msg);
2248         const char *path;
2249         DBusMessageIter args;
2250         struct external_service *service;
2251         struct svc_match_data match_data;
2252
2253         if (!dbus_message_iter_init(msg, &args))
2254                 return btd_error_invalid_args(msg);
2255
2256         if (dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_OBJECT_PATH)
2257                 return btd_error_invalid_args(msg);
2258
2259         dbus_message_iter_get_basic(&args, &path);
2260
2261         match_data.path = path;
2262         match_data.sender = sender;
2263
2264         service = queue_remove_if(database->services, match_service,
2265                                                                 &match_data);
2266         if (!service)
2267                 return btd_error_does_not_exist(msg);
2268
2269         service_free(service);
2270
2271         return dbus_message_new_method_return(msg);
2272 }
2273
2274 static void profile_exited(DBusConnection *conn, void *user_data)
2275 {
2276         struct external_profile *profile = user_data;
2277
2278         DBG("\"%s\" exited", profile->owner);
2279
2280         profile->id = 0;
2281
2282         queue_remove(profile->database->profiles, profile);
2283
2284         profile_free(profile);
2285 }
2286
2287 static int profile_add(struct external_profile *profile, const char *uuid)
2288 {
2289         struct btd_profile *p;
2290
2291         p = new0(struct btd_profile, 1);
2292         if (!p)
2293                 return -ENOMEM;
2294
2295         /* Assign directly to avoid having extra fields */
2296         p->name = (const void *) g_strdup_printf("%s%s/%s", profile->owner,
2297                                                         profile->path, uuid);
2298         if (!p->name) {
2299                 free(p);
2300                 return -ENOMEM;
2301         }
2302
2303         p->remote_uuid = (const void *) g_strdup(uuid);
2304         if (!p->remote_uuid) {
2305                 g_free((void *) p->name);
2306                 free(p);
2307                 return -ENOMEM;
2308         }
2309
2310         p->auto_connect = true;
2311
2312         queue_push_tail(profile->profiles, p);
2313
2314         DBG("Added \"%s\"", p->name);
2315
2316         return 0;
2317 }
2318
2319 static void add_profile(void *data, void *user_data)
2320 {
2321         struct btd_adapter *adapter = user_data;
2322
2323         adapter_add_profile(adapter, data);
2324 }
2325
2326 static int profile_create(DBusConnection *conn,
2327                                 struct btd_gatt_database *database,
2328                                 const char *sender, const char *path,
2329                                 DBusMessageIter *iter)
2330 {
2331         struct external_profile *profile;
2332         DBusMessageIter uuids;
2333
2334         if (!path || !g_str_has_prefix(path, "/"))
2335                 return -EINVAL;
2336
2337         profile = new0(struct external_profile, 1);
2338         if (!profile)
2339                 return -ENOMEM;
2340
2341         profile->owner = g_strdup(sender);
2342         if (!profile->owner)
2343                 goto fail;
2344
2345         profile->path = g_strdup(path);
2346         if (!profile->path)
2347                 goto fail;
2348
2349         profile->profiles = queue_new();
2350         if (!profile->profiles)
2351                 goto fail;
2352
2353         profile->database = database;
2354         profile->id = g_dbus_add_disconnect_watch(conn, sender, profile_exited,
2355                                                                 profile, NULL);
2356
2357         dbus_message_iter_recurse(iter, &uuids);
2358
2359         while (dbus_message_iter_get_arg_type(&uuids) == DBUS_TYPE_STRING) {
2360                 const char *uuid;
2361
2362                 dbus_message_iter_get_basic(&uuids, &uuid);
2363
2364                 if (profile_add(profile, uuid) < 0)
2365                         goto fail;
2366
2367                 dbus_message_iter_next(&uuids);
2368         }
2369
2370         if (queue_isempty(profile->profiles))
2371                 goto fail;
2372
2373         queue_foreach(profile->profiles, add_profile, database->adapter);
2374         queue_push_tail(database->profiles, profile);
2375
2376         return 0;
2377
2378 fail:
2379         profile_free(profile);
2380         return -EINVAL;
2381 }
2382
2383 static bool match_profile(const void *a, const void *b)
2384 {
2385         const struct external_profile *profile = a;
2386         const struct svc_match_data *data = b;
2387
2388         return g_strcmp0(profile->path, data->path) == 0 &&
2389                                 g_strcmp0(profile->owner, data->sender) == 0;
2390 }
2391
2392 static DBusMessage *manager_register_profile(DBusConnection *conn,
2393                                         DBusMessage *msg, void *user_data)
2394 {
2395         struct btd_gatt_database *database = user_data;
2396         const char *sender = dbus_message_get_sender(msg);
2397         DBusMessageIter args;
2398         const char *path;
2399         struct svc_match_data match_data;
2400
2401         DBG("sender %s", sender);
2402
2403         if (!dbus_message_iter_init(msg, &args))
2404                 return btd_error_invalid_args(msg);
2405
2406         if (dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_OBJECT_PATH)
2407                 return btd_error_invalid_args(msg);
2408
2409         dbus_message_iter_get_basic(&args, &path);
2410
2411         match_data.path = path;
2412         match_data.sender = sender;
2413
2414         if (queue_find(database->profiles, match_profile, &match_data))
2415                 return btd_error_already_exists(msg);
2416
2417         dbus_message_iter_next(&args);
2418         if (dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_ARRAY)
2419                 return btd_error_invalid_args(msg);
2420
2421         if (profile_create(conn, database, sender, path, &args) < 0)
2422                 return btd_error_failed(msg, "Failed to register profile");
2423
2424         return dbus_message_new_method_return(msg);
2425 }
2426
2427 static DBusMessage *manager_unregister_profile(DBusConnection *conn,
2428                                         DBusMessage *msg, void *user_data)
2429 {
2430         struct btd_gatt_database *database = user_data;
2431         const char *sender = dbus_message_get_sender(msg);
2432         const char *path;
2433         DBusMessageIter args;
2434         struct external_profile *profile;
2435         struct svc_match_data match_data;
2436
2437         if (!dbus_message_iter_init(msg, &args))
2438                 return btd_error_invalid_args(msg);
2439
2440         if (dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_OBJECT_PATH)
2441                 return btd_error_invalid_args(msg);
2442
2443         dbus_message_iter_get_basic(&args, &path);
2444
2445         match_data.path = path;
2446         match_data.sender = sender;
2447
2448         profile = queue_remove_if(database->profiles, match_profile,
2449                                                                 &match_data);
2450         if (!profile)
2451                 return btd_error_does_not_exist(msg);
2452
2453         profile_free(profile);
2454
2455         return dbus_message_new_method_return(msg);
2456 }
2457
2458 static const GDBusMethodTable manager_methods[] = {
2459         { GDBUS_EXPERIMENTAL_ASYNC_METHOD("RegisterService",
2460                         GDBUS_ARGS({ "service", "o" }, { "options", "a{sv}" }),
2461                         NULL, manager_register_service) },
2462         { GDBUS_EXPERIMENTAL_ASYNC_METHOD("UnregisterService",
2463                                         GDBUS_ARGS({ "service", "o" }),
2464                                         NULL, manager_unregister_service) },
2465         { GDBUS_EXPERIMENTAL_ASYNC_METHOD("RegisterProfile",
2466                         GDBUS_ARGS({ "profile", "o" }, { "UUIDs", "as" },
2467                         { "options", "a{sv}" }), NULL,
2468                         manager_register_profile) },
2469         { GDBUS_EXPERIMENTAL_ASYNC_METHOD("UnregisterProfile",
2470                                         GDBUS_ARGS({ "profile", "o" }),
2471                                         NULL, manager_unregister_profile) },
2472         { }
2473 };
2474
2475 struct btd_gatt_database *btd_gatt_database_new(struct btd_adapter *adapter)
2476 {
2477         struct btd_gatt_database *database;
2478         GError *gerr = NULL;
2479         const bdaddr_t *addr;
2480
2481         if (!adapter)
2482                 return NULL;
2483
2484         database = new0(struct btd_gatt_database, 1);
2485         if (!database)
2486                 return NULL;
2487
2488         database->adapter = btd_adapter_ref(adapter);
2489         database->db = gatt_db_new();
2490         if (!database->db)
2491                 goto fail;
2492
2493         database->device_states = queue_new();
2494         if (!database->device_states)
2495                 goto fail;
2496
2497         database->services = queue_new();
2498         if (!database->services)
2499                 goto fail;
2500
2501         database->profiles = queue_new();
2502         if (!database->profiles)
2503                 goto fail;
2504
2505         database->ccc_callbacks = queue_new();
2506         if (!database->ccc_callbacks)
2507                 goto fail;
2508
2509         database->db_id = gatt_db_register(database->db, gatt_db_service_added,
2510                                                         gatt_db_service_removed,
2511                                                         database, NULL);
2512         if (!database->db_id)
2513                 goto fail;
2514
2515         addr = btd_adapter_get_address(adapter);
2516         database->le_io = bt_io_listen(connect_cb, NULL, NULL, NULL, &gerr,
2517                                         BT_IO_OPT_SOURCE_BDADDR, addr,
2518                                         BT_IO_OPT_SOURCE_TYPE, BDADDR_LE_PUBLIC,
2519                                         BT_IO_OPT_CID, ATT_CID,
2520                                         BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
2521                                         BT_IO_OPT_INVALID);
2522         if (!database->le_io) {
2523                 error("Failed to start listening: %s", gerr->message);
2524                 g_error_free(gerr);
2525                 goto fail;
2526         }
2527
2528         /* BR/EDR socket */
2529         database->l2cap_io = bt_io_listen(connect_cb, NULL, NULL, NULL, &gerr,
2530                                         BT_IO_OPT_SOURCE_BDADDR, addr,
2531                                         BT_IO_OPT_PSM, ATT_PSM,
2532                                         BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
2533                                         BT_IO_OPT_INVALID);
2534         if (database->l2cap_io == NULL) {
2535                 error("Failed to start listening: %s", gerr->message);
2536                 g_error_free(gerr);
2537                 goto fail;
2538         }
2539
2540         if (g_dbus_register_interface(btd_get_dbus_connection(),
2541                                                 adapter_get_path(adapter),
2542                                                 GATT_MANAGER_IFACE,
2543                                                 manager_methods, NULL, NULL,
2544                                                 database, NULL))
2545                 DBG("GATT Manager registered for adapter: %s",
2546                                                 adapter_get_path(adapter));
2547
2548         register_core_services(database);
2549
2550         return database;
2551
2552 fail:
2553         gatt_database_free(database);
2554
2555         return NULL;
2556 }
2557
2558 void btd_gatt_database_destroy(struct btd_gatt_database *database)
2559 {
2560         if (!database)
2561                 return;
2562
2563         g_dbus_unregister_interface(btd_get_dbus_connection(),
2564                                         adapter_get_path(database->adapter),
2565                                         GATT_MANAGER_IFACE);
2566
2567         gatt_database_free(database);
2568 }
2569
2570 struct gatt_db *btd_gatt_database_get_db(struct btd_gatt_database *database)
2571 {
2572         if (!database)
2573                 return NULL;
2574
2575         return database->db;
2576 }