tizen 2.3 release
[framework/connectivity/bluez.git] / src / attrib-server.c
1 /*
2  *
3  *  BlueZ - Bluetooth protocol stack for Linux
4  *
5  *  Copyright (C) 2010  Nokia Corporation
6  *  Copyright (C) 2010  Marcel Holtmann <marcel@holtmann.org>
7  *
8  *
9  *  This program is free software; you can redistribute it and/or modify
10  *  it under the terms of the GNU General Public License as published by
11  *  the Free Software Foundation; either version 2 of the License, or
12  *  (at your option) any later version.
13  *
14  *  This program is distributed in the hope that it will be useful,
15  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  *  GNU General Public License for more details.
18  *
19  *  You should have received a copy of the GNU General Public License
20  *  along with this program; if not, write to the Free Software
21  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
22  *
23  */
24
25 #ifdef HAVE_CONFIG_H
26 #include <config.h>
27 #endif
28
29 #include <errno.h>
30 #include <stdint.h>
31 #include <stdbool.h>
32 #include <string.h>
33 #include <unistd.h>
34 #include <glib.h>
35 #include <sys/stat.h>
36
37 #include <bluetooth/bluetooth.h>
38 #include <bluetooth/sdp.h>
39 #include <bluetooth/sdp_lib.h>
40
41 #include <gdbus/gdbus.h>
42
43 #include "lib/uuid.h"
44 #include "btio/btio.h"
45 #include "log.h"
46 #include "sdpd.h"
47 #include "hcid.h"
48 #include "adapter.h"
49 #include "device.h"
50 #include "attrib/gattrib.h"
51 #include "attrib/att.h"
52 #include "attrib/gatt.h"
53 #include "attrib/att-database.h"
54 #include "textfile.h"
55 #include "storage.h"
56 #ifdef __TIZEN_PATCH__
57 #include "src/shared/util.h"
58 #endif
59
60 #include "attrib-server.h"
61
62 static GSList *servers = NULL;
63
64 struct gatt_server {
65         struct btd_adapter *adapter;
66         GIOChannel *l2cap_io;
67         GIOChannel *le_io;
68         uint32_t gatt_sdp_handle;
69         uint32_t gap_sdp_handle;
70         GList *database;
71         GSList *clients;
72         uint16_t name_handle;
73         uint16_t appearance_handle;
74 };
75
76 struct gatt_channel {
77         GAttrib *attrib;
78         guint mtu;
79         gboolean le;
80         guint id;
81         gboolean encrypted;
82         struct gatt_server *server;
83         guint cleanup_id;
84         struct btd_device *device;
85 };
86
87 struct group_elem {
88         uint16_t handle;
89         uint16_t end;
90         uint8_t *data;
91         uint16_t len;
92 };
93
94 #ifdef __TIZEN_PATCH__
95 static bt_uuid_t prim_uuid32 = {
96                         .type = BT_UUID32,
97                         .value.u32 = GATT_PRIM_SVC_UUID
98 };
99
100 static bt_uuid_t snd_uuid32 = {
101                         .type = BT_UUID32,
102                         .value.u32 = GATT_SND_SVC_UUID
103 };
104 #endif
105
106
107 static bt_uuid_t prim_uuid = {
108                         .type = BT_UUID16,
109                         .value.u16 = GATT_PRIM_SVC_UUID
110 };
111 static bt_uuid_t snd_uuid = {
112                         .type = BT_UUID16,
113                         .value.u16 = GATT_SND_SVC_UUID
114 };
115 static bt_uuid_t ccc_uuid = {
116                         .type = BT_UUID16,
117                         .value.u16 = GATT_CLIENT_CHARAC_CFG_UUID
118 };
119
120 static void attrib_free(void *data)
121 {
122         struct attribute *a = data;
123
124         g_free(a->data);
125         g_free(a);
126 }
127
128 static void channel_free(struct gatt_channel *channel)
129 {
130         if (channel->cleanup_id)
131                 g_source_remove(channel->cleanup_id);
132
133         if (channel->device) {
134                 device_unset_attrib(channel->device);
135                 btd_device_unref(channel->device);
136         }
137
138         g_attrib_unref(channel->attrib);
139         g_free(channel);
140 }
141
142 static void gatt_server_free(struct gatt_server *server)
143 {
144         g_list_free_full(server->database, attrib_free);
145
146         if (server->l2cap_io != NULL) {
147                 g_io_channel_shutdown(server->l2cap_io, FALSE, NULL);
148                 g_io_channel_unref(server->l2cap_io);
149         }
150
151         if (server->le_io != NULL) {
152                 g_io_channel_shutdown(server->le_io, FALSE, NULL);
153                 g_io_channel_unref(server->le_io);
154         }
155
156         g_slist_free_full(server->clients, (GDestroyNotify) channel_free);
157
158         if (server->gatt_sdp_handle > 0)
159                 adapter_service_remove(server->adapter,
160                                         server->gatt_sdp_handle);
161
162         if (server->gap_sdp_handle > 0)
163                 adapter_service_remove(server->adapter, server->gap_sdp_handle);
164
165         if (server->adapter != NULL)
166                 btd_adapter_unref(server->adapter);
167
168         g_free(server);
169 }
170
171 static int adapter_cmp_addr(gconstpointer a, gconstpointer b)
172 {
173         const struct gatt_server *server = a;
174         const bdaddr_t *bdaddr = b;
175
176         return bacmp(btd_adapter_get_address(server->adapter), bdaddr);
177 }
178
179 static int adapter_cmp(gconstpointer a, gconstpointer b)
180 {
181         const struct gatt_server *server = a;
182         const struct btd_adapter *adapter = b;
183
184         if (server->adapter == adapter)
185                 return 0;
186
187         return -1;
188 }
189
190 static struct gatt_server *find_gatt_server(const bdaddr_t *bdaddr)
191 {
192         GSList *l;
193
194         l = g_slist_find_custom(servers, bdaddr, adapter_cmp_addr);
195         if (l == NULL) {
196                 char addr[18];
197
198                 ba2str(bdaddr, addr);
199                 error("No GATT server found in %s", addr);
200                 return NULL;
201         }
202
203         return l->data;
204 }
205
206 static sdp_record_t *server_record_new(uuid_t *uuid, uint16_t start, uint16_t end)
207 {
208         sdp_list_t *svclass_id, *apseq, *proto[2], *root, *aproto;
209         uuid_t root_uuid, proto_uuid, l2cap;
210         sdp_record_t *record;
211         sdp_data_t *psm, *sh, *eh;
212         uint16_t lp = ATT_PSM;
213
214         if (uuid == NULL)
215                 return NULL;
216
217         if (start > end)
218                 return NULL;
219
220         record = sdp_record_alloc();
221         if (record == NULL)
222                 return NULL;
223
224         sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
225         root = sdp_list_append(NULL, &root_uuid);
226         sdp_set_browse_groups(record, root);
227         sdp_list_free(root, NULL);
228
229         svclass_id = sdp_list_append(NULL, uuid);
230         sdp_set_service_classes(record, svclass_id);
231         sdp_list_free(svclass_id, NULL);
232
233         sdp_uuid16_create(&l2cap, L2CAP_UUID);
234         proto[0] = sdp_list_append(NULL, &l2cap);
235         psm = sdp_data_alloc(SDP_UINT16, &lp);
236         proto[0] = sdp_list_append(proto[0], psm);
237         apseq = sdp_list_append(NULL, proto[0]);
238
239         sdp_uuid16_create(&proto_uuid, ATT_UUID);
240         proto[1] = sdp_list_append(NULL, &proto_uuid);
241         sh = sdp_data_alloc(SDP_UINT16, &start);
242         proto[1] = sdp_list_append(proto[1], sh);
243         eh = sdp_data_alloc(SDP_UINT16, &end);
244         proto[1] = sdp_list_append(proto[1], eh);
245         apseq = sdp_list_append(apseq, proto[1]);
246
247         aproto = sdp_list_append(NULL, apseq);
248         sdp_set_access_protos(record, aproto);
249
250         sdp_data_free(psm);
251         sdp_data_free(sh);
252         sdp_data_free(eh);
253         sdp_list_free(proto[0], NULL);
254         sdp_list_free(proto[1], NULL);
255         sdp_list_free(apseq, NULL);
256         sdp_list_free(aproto, NULL);
257
258         return record;
259 }
260
261 static int handle_cmp(gconstpointer a, gconstpointer b)
262 {
263         const struct attribute *attrib = a;
264         uint16_t handle = GPOINTER_TO_UINT(b);
265
266         return attrib->handle - handle;
267 }
268
269 static int attribute_cmp(gconstpointer a1, gconstpointer a2)
270 {
271         const struct attribute *attrib1 = a1;
272         const struct attribute *attrib2 = a2;
273
274         return attrib1->handle - attrib2->handle;
275 }
276
277
278 #ifdef __TIZEN_PATCH__
279 static inline void put_uuid_le(const bt_uuid_t *src, void *dst)
280 {
281         if (src->type == BT_UUID16) {
282                 put_le16(src->value.u16, dst);
283         }
284         else if (src->type == BT_UUID32) {
285                 put_le32(src->value.u32, dst);
286         } else {
287                 /* Convert from 128-bit BE to LE */
288                 bswap_128(&src->value.u128, dst);
289         }
290 }
291
292 static int attribute_uuid_cmp(gconstpointer a, gconstpointer b)
293 {
294         const struct attribute *attrib1 = a;
295         const bt_uuid_t *uuid = b;
296
297         return bt_uuid_cmp(&attrib1->uuid, uuid);
298 }
299
300 struct attribute *attribute_find(struct btd_adapter *adapter, bt_uuid_t *uuid)
301 {
302         GList *l;
303         bt_uuid_t cmp_uuid;
304         struct gatt_server *server;
305
306         /* Find the attrib server database for the given adapter */
307         l = g_slist_find_custom(servers, adapter, adapter_cmp);
308         if (!l)
309                 return NULL;
310
311         server = l->data;
312
313         l = g_list_find_custom(server->database, GUINT_TO_POINTER(uuid),
314                                                         attribute_uuid_cmp);
315         if (!l)
316                 return NULL;
317
318         return l->data;
319 }
320 #endif
321
322 static struct attribute *find_svc_range(struct gatt_server *server,
323                                         uint16_t start, uint16_t *end)
324 {
325         struct attribute *attrib;
326         guint h = start;
327         GList *l;
328
329         if (end == NULL)
330                 return NULL;
331
332         l = g_list_find_custom(server->database, GUINT_TO_POINTER(h),
333                                                                 handle_cmp);
334         if (!l)
335                 return NULL;
336
337         attrib = l->data;
338
339 #ifdef __TIZEN_PATCH__
340         if (attrib->uuid.type == BT_UUID16) {
341 #endif
342         if (bt_uuid_cmp(&attrib->uuid, &prim_uuid) != 0 &&
343                         bt_uuid_cmp(&attrib->uuid, &snd_uuid) != 0)
344                 return NULL;
345
346 #ifdef __TIZEN_PATCH__
347         }
348         else if (attrib->uuid.type == BT_UUID32) {
349                 if (bt_uuid_cmp(&attrib->uuid, &prim_uuid32) != 0 &&
350                         bt_uuid_cmp(&attrib->uuid, &snd_uuid32) != 0)
351                         return NULL;
352         }
353 #endif
354
355         *end = start;
356
357         for (l = l->next; l; l = l->next) {
358                 struct attribute *a = l->data;
359
360 #ifdef __TIZEN_PATCH__
361         if (attrib->uuid.type == BT_UUID16) {
362 #endif
363                 if (bt_uuid_cmp(&a->uuid, &prim_uuid) == 0 ||
364                                 bt_uuid_cmp(&a->uuid, &snd_uuid) == 0)
365                         break;
366
367 #ifdef __TIZEN_PATCH__
368                 }
369                 else if (attrib->uuid.type == BT_UUID32) {
370                         if (bt_uuid_cmp(&attrib->uuid, &prim_uuid32) != 0 &&
371                                 bt_uuid_cmp(&attrib->uuid, &snd_uuid32) != 0)
372                                 break;
373                 }
374                 else
375                         break;
376 #endif
377
378                 *end = a->handle;
379         }
380
381         return attrib;
382 }
383
384 static uint32_t attrib_create_sdp_new(struct gatt_server *server,
385                                         uint16_t handle, const char *name)
386 {
387         sdp_record_t *record;
388         struct attribute *a;
389         uint16_t end = 0;
390         uuid_t svc, gap_uuid;
391
392         a = find_svc_range(server, handle, &end);
393
394         if (a == NULL)
395                 return 0;
396
397         if (a->len == 2)
398                 sdp_uuid16_create(&svc, att_get_u16(a->data));
399 #ifdef __TIZEN_PATCH__
400         else if (a->len == 4) {
401                 sdp_uuid32_create(&svc, att_get_u32(a->data));
402         }
403 #endif
404         else if (a->len == 16)
405                 sdp_uuid128_create(&svc, a->data);
406         else
407                 return 0;
408
409         record = server_record_new(&svc, handle, end);
410         if (record == NULL)
411                 return 0;
412
413         if (name != NULL)
414                 sdp_set_info_attr(record, name, "BlueZ", NULL);
415
416         sdp_uuid16_create(&gap_uuid, GENERIC_ACCESS_PROFILE_ID);
417         if (sdp_uuid_cmp(&svc, &gap_uuid) == 0) {
418                 sdp_set_url_attr(record, "http://www.bluez.org/",
419                                 "http://www.bluez.org/",
420                                 "http://www.bluez.org/");
421         }
422
423         if (adapter_service_add(server->adapter, record) == 0)
424                 return record->handle;
425
426         sdp_record_free(record);
427         return 0;
428 }
429
430 static struct attribute *attrib_db_add_new(struct gatt_server *server,
431                                 uint16_t handle, bt_uuid_t *uuid,
432                                 int read_req, int write_req,
433                                 const uint8_t *value, size_t len)
434 {
435         struct attribute *a;
436         guint h = handle;
437
438         DBG("handle=0x%04x", handle);
439
440         if (g_list_find_custom(server->database, GUINT_TO_POINTER(h),
441                                                                 handle_cmp))
442                 return NULL;
443
444         a = g_new0(struct attribute, 1);
445         a->len = len;
446         a->data = g_memdup(value, len);
447         a->handle = handle;
448         a->uuid = *uuid;
449         a->read_req = read_req;
450         a->write_req = write_req;
451
452         server->database = g_list_insert_sorted(server->database, a,
453                                                                 attribute_cmp);
454
455         return a;
456 }
457
458 static uint8_t att_check_reqs(struct gatt_channel *channel, uint8_t opcode,
459                                                                 int reqs)
460 {
461         /* FIXME: currently, it is assumed an encrypted link is enough for
462          * authentication. This will allow to enable the SMP negotiation once
463          * it is on upstream kernel. High security level should be mapped
464          * to authentication and medium to encryption permission. */
465         if (!channel->encrypted)
466                 channel->encrypted = g_attrib_is_encrypted(channel->attrib);
467         if (reqs == ATT_AUTHENTICATION && !channel->encrypted)
468                 return ATT_ECODE_AUTHENTICATION;
469         else if (reqs == ATT_AUTHORIZATION)
470                 return ATT_ECODE_AUTHORIZATION;
471
472         switch (opcode) {
473         case ATT_OP_READ_BY_GROUP_REQ:
474         case ATT_OP_READ_BY_TYPE_REQ:
475         case ATT_OP_READ_REQ:
476         case ATT_OP_READ_BLOB_REQ:
477         case ATT_OP_READ_MULTI_REQ:
478                 if (reqs == ATT_NOT_PERMITTED)
479                         return ATT_ECODE_READ_NOT_PERM;
480                 break;
481         case ATT_OP_PREP_WRITE_REQ:
482         case ATT_OP_WRITE_REQ:
483         case ATT_OP_WRITE_CMD:
484                 if (reqs == ATT_NOT_PERMITTED)
485                         return ATT_ECODE_WRITE_NOT_PERM;
486                 break;
487         }
488
489         return 0;
490 }
491
492 static uint16_t read_by_group(struct gatt_channel *channel, uint16_t start,
493                                                 uint16_t end, bt_uuid_t *uuid,
494                                                 uint8_t *pdu, size_t len)
495 {
496         struct att_data_list *adl;
497         struct attribute *a;
498         struct group_elem *cur, *old = NULL;
499         GSList *l, *groups;
500         GList *dl, *database;
501         uint16_t length, last_handle, last_size = 0;
502         uint8_t status;
503         int i;
504
505         if (start > end || start == 0x0000)
506                 return enc_error_resp(ATT_OP_READ_BY_GROUP_REQ, start,
507                                         ATT_ECODE_INVALID_HANDLE, pdu, len);
508
509         /*
510          * Only <<Primary Service>> and <<Secondary Service>> grouping
511          * types may be used in the Read By Group Type Request.
512          */
513
514 #ifdef __TIZEN_PATCH__
515         if (uuid->type == BT_UUID16) {
516 #endif
517         if (bt_uuid_cmp(uuid, &prim_uuid) != 0 &&
518                 bt_uuid_cmp(uuid, &snd_uuid) != 0)
519                 return enc_error_resp(ATT_OP_READ_BY_GROUP_REQ, 0x0000,
520                                         ATT_ECODE_UNSUPP_GRP_TYPE, pdu, len);
521
522 #ifdef __TIZEN_PATCH__
523         }
524         else if (uuid->type == BT_UUID32) {
525                 if (bt_uuid_cmp(uuid, &prim_uuid32) != 0 &&
526                         bt_uuid_cmp(uuid, &snd_uuid32) != 0)
527                         return enc_error_resp(ATT_OP_READ_BY_GROUP_REQ, 0x0000,
528                                                 ATT_ECODE_UNSUPP_GRP_TYPE, pdu, len);
529         }
530         else
531                 return enc_error_resp(ATT_OP_READ_BY_GROUP_REQ, 0x0000,
532                                                 ATT_ECODE_UNSUPP_GRP_TYPE, pdu, len);
533 #endif
534
535         last_handle = end;
536         database = channel->server->database;
537         for (dl = database, groups = NULL, cur = NULL; dl; dl = dl->next) {
538
539                 a = dl->data;
540
541                 if (a->handle < start)
542                         continue;
543
544                 if (a->handle >= end)
545                         break;
546
547 #ifdef __TIZEN_PATCH__
548                 if (uuid->type == BT_UUID16) {
549 #endif
550                 /* The old group ends when a new one starts */
551                 if (old && (bt_uuid_cmp(&a->uuid, &prim_uuid) == 0 ||
552                                 bt_uuid_cmp(&a->uuid, &snd_uuid) == 0)) {
553                         old->end = last_handle;
554                         old = NULL;
555                 }
556
557 #ifdef __TIZEN_PATCH__
558                 }
559                 if (uuid->type == BT_UUID32) {
560                         if (old && (bt_uuid_cmp(&a->uuid, &prim_uuid32) == 0 ||
561                                         bt_uuid_cmp(&a->uuid, &snd_uuid32) == 0)) {
562                                 old->end = last_handle;
563                                 old = NULL;
564                         }
565                 }
566 #endif
567
568                 if (bt_uuid_cmp(&a->uuid, uuid) != 0) {
569                         /* Still inside a service, update its last handle */
570                         if (old)
571                                 last_handle = a->handle;
572                         continue;
573                 }
574
575                 if (last_size && (last_size != a->len))
576                         break;
577
578                 status = att_check_reqs(channel, ATT_OP_READ_BY_GROUP_REQ,
579                                                                 a->read_req);
580
581                 if (status == 0x00 && a->read_cb)
582                         status = a->read_cb(a, channel->device,
583                                                         a->cb_user_data);
584
585                 if (status) {
586                         g_slist_free_full(groups, g_free);
587                         return enc_error_resp(ATT_OP_READ_BY_GROUP_REQ,
588                                                 a->handle, status, pdu, len);
589                 }
590
591                 cur = g_new0(struct group_elem, 1);
592                 cur->handle = a->handle;
593                 cur->data = a->data;
594                 cur->len = a->len;
595
596                 /* Attribute Grouping Type found */
597                 groups = g_slist_append(groups, cur);
598
599                 last_size = a->len;
600                 old = cur;
601                 last_handle = cur->handle;
602         }
603
604         if (groups == NULL)
605                 return enc_error_resp(ATT_OP_READ_BY_GROUP_REQ, start,
606                                         ATT_ECODE_ATTR_NOT_FOUND, pdu, len);
607
608         if (dl == NULL)
609                 cur->end = a->handle;
610         else
611                 cur->end = last_handle;
612
613         length = g_slist_length(groups);
614
615         adl = att_data_list_alloc(length, last_size + 4);
616         if (adl == NULL) {
617                 g_slist_free_full(groups, g_free);
618                 return enc_error_resp(ATT_OP_READ_BY_GROUP_REQ, start,
619                                         ATT_ECODE_UNLIKELY, pdu, len);
620         }
621
622         for (i = 0, l = groups; l; l = l->next, i++) {
623                 uint8_t *value;
624
625                 cur = l->data;
626
627                 value = (void *) adl->data[i];
628
629                 att_put_u16(cur->handle, value);
630                 att_put_u16(cur->end, &value[2]);
631                 /* Attribute Value */
632                 memcpy(&value[4], cur->data, cur->len);
633         }
634
635         length = enc_read_by_grp_resp(adl, pdu, len);
636
637         att_data_list_free(adl);
638         g_slist_free_full(groups, g_free);
639
640         return length;
641 }
642
643 static uint16_t read_by_type(struct gatt_channel *channel, uint16_t start,
644                                                 uint16_t end, bt_uuid_t *uuid,
645                                                 uint8_t *pdu, size_t len)
646 {
647         struct att_data_list *adl;
648         GSList *l, *types;
649         GList *dl, *database;
650         struct attribute *a;
651         uint16_t num, length;
652         uint8_t status;
653         int i;
654
655         if (start > end || start == 0x0000)
656                 return enc_error_resp(ATT_OP_READ_BY_TYPE_REQ, start,
657                                         ATT_ECODE_INVALID_HANDLE, pdu, len);
658
659         database = channel->server->database;
660         for (dl = database, length = 0, types = NULL; dl; dl = dl->next) {
661
662                 a = dl->data;
663
664                 if (a->handle < start)
665                         continue;
666
667                 if (a->handle > end)
668                         break;
669
670                 if (bt_uuid_cmp(&a->uuid, uuid)  != 0)
671                         continue;
672
673                 status = att_check_reqs(channel, ATT_OP_READ_BY_TYPE_REQ,
674                                                                 a->read_req);
675
676                 if (status == 0x00 && a->read_cb)
677                         status = a->read_cb(a, channel->device,
678                                                         a->cb_user_data);
679
680                 if (status) {
681                         g_slist_free(types);
682                         return enc_error_resp(ATT_OP_READ_BY_TYPE_REQ,
683                                                 a->handle, status, pdu, len);
684                 }
685
686                 /* All elements must have the same length */
687                 if (length == 0)
688                         length = a->len;
689                 else if (a->len != length)
690                         break;
691
692                 types = g_slist_append(types, a);
693         }
694
695         if (types == NULL)
696                 return enc_error_resp(ATT_OP_READ_BY_TYPE_REQ, start,
697                                         ATT_ECODE_ATTR_NOT_FOUND, pdu, len);
698
699         num = g_slist_length(types);
700
701         /* Handle length plus attribute value length */
702         length += 2;
703
704         adl = att_data_list_alloc(num, length);
705         if (adl == NULL) {
706                 g_slist_free(types);
707                 return enc_error_resp(ATT_OP_READ_BY_TYPE_REQ, start,
708                                         ATT_ECODE_UNLIKELY, pdu, len);
709         }
710
711         for (i = 0, l = types; l; i++, l = l->next) {
712                 uint8_t *value;
713
714                 a = l->data;
715
716                 value = (void *) adl->data[i];
717
718                 att_put_u16(a->handle, value);
719
720                 /* Attribute Value */
721                 memcpy(&value[2], a->data, a->len);
722         }
723
724         length = enc_read_by_type_resp(adl, pdu, len);
725
726         att_data_list_free(adl);
727         g_slist_free(types);
728
729         return length;
730 }
731
732 static uint16_t find_info(struct gatt_channel *channel, uint16_t start,
733                                 uint16_t end, uint8_t *pdu, size_t len)
734 {
735         struct attribute *a;
736         struct att_data_list *adl;
737         GSList *l, *info;
738         GList *dl, *database;
739         uint8_t format, last_type = BT_UUID_UNSPEC;
740         uint16_t length, num;
741         int i;
742
743         if (start > end || start == 0x0000)
744                 return enc_error_resp(ATT_OP_FIND_INFO_REQ, start,
745                                         ATT_ECODE_INVALID_HANDLE, pdu, len);
746
747         database = channel->server->database;
748         for (dl = database, info = NULL, num = 0; dl; dl = dl->next) {
749                 a = dl->data;
750
751                 if (a->handle < start)
752                         continue;
753
754                 if (a->handle > end)
755                         break;
756
757                 if (last_type == BT_UUID_UNSPEC)
758                         last_type = a->uuid.type;
759
760                 if (a->uuid.type != last_type)
761                         break;
762
763                 info = g_slist_append(info, a);
764                 num++;
765
766                 last_type = a->uuid.type;
767         }
768
769         if (info == NULL)
770                 return enc_error_resp(ATT_OP_FIND_INFO_REQ, start,
771                                         ATT_ECODE_ATTR_NOT_FOUND, pdu, len);
772
773         if (last_type == BT_UUID16) {
774                 length = 2;
775                 format = 0x01;
776         } else if (last_type == BT_UUID128) {
777                 length = 16;
778                 format = 0x02;
779         } else {
780                 g_slist_free(info);
781                 return 0;
782         }
783
784         adl = att_data_list_alloc(num, length + 2);
785         if (adl == NULL) {
786                 g_slist_free(info);
787                 return enc_error_resp(ATT_OP_FIND_INFO_REQ, start,
788                                         ATT_ECODE_UNLIKELY, pdu, len);
789         }
790
791         for (i = 0, l = info; l; i++, l = l->next) {
792                 uint8_t *value;
793
794                 a = l->data;
795
796                 value = (void *) adl->data[i];
797
798                 att_put_u16(a->handle, value);
799
800                 /* Attribute Value */
801                 att_put_uuid(a->uuid, &value[2]);
802         }
803
804         length = enc_find_info_resp(format, adl, pdu, len);
805
806         att_data_list_free(adl);
807         g_slist_free(info);
808
809         return length;
810 }
811
812 static uint16_t find_by_type(struct gatt_channel *channel, uint16_t start,
813                                 uint16_t end, bt_uuid_t *uuid,
814                                 const uint8_t *value, size_t vlen,
815                                 uint8_t *opdu, size_t mtu)
816 {
817         struct attribute *a;
818         struct att_range *range;
819         GSList *matches;
820         GList *dl, *database;
821         uint16_t len;
822
823         if (start > end || start == 0x0000)
824                 return enc_error_resp(ATT_OP_FIND_BY_TYPE_REQ, start,
825                                         ATT_ECODE_INVALID_HANDLE, opdu, mtu);
826
827         /* Searching first requested handle number */
828         database = channel->server->database;
829         for (dl = database, matches = NULL, range = NULL; dl; dl = dl->next) {
830                 a = dl->data;
831
832                 if (a->handle < start)
833                         continue;
834
835                 if (a->handle > end)
836                         break;
837
838                 /* Primary service? Attribute value matches? */
839                 if ((bt_uuid_cmp(&a->uuid, uuid) == 0) && (a->len == vlen) &&
840                                         (memcmp(a->data, value, vlen) == 0)) {
841
842                         range = g_new0(struct att_range, 1);
843                         range->start = a->handle;
844                         /* It is allowed to have end group handle the same as
845                          * start handle, for groups with only one attribute. */
846                         range->end = a->handle;
847
848                         matches = g_slist_append(matches, range);
849                 } else if (range) {
850                         /* Update the last found handle or reset the pointer
851                          * to track that a new group started: Primary or
852                          * Secondary service. */
853 #ifndef __TIZEN_PATCH__
854                         if (bt_uuid_cmp(&a->uuid, &prim_uuid) == 0 ||
855                                         bt_uuid_cmp(&a->uuid, &snd_uuid) == 0)
856                                 range = NULL;
857 #else
858                         if (a->uuid.type == BT_UUID32) {
859                                 if (bt_uuid_cmp(&a->uuid, &prim_uuid32) == 0 ||
860                                                 bt_uuid_cmp(&a->uuid, &snd_uuid32) == 0)
861                                         range = NULL;
862                         }
863 #endif
864
865                         else
866                                 range->end = a->handle;
867                 }
868         }
869
870         if (matches == NULL)
871                 return enc_error_resp(ATT_OP_FIND_BY_TYPE_REQ, start,
872                                 ATT_ECODE_ATTR_NOT_FOUND, opdu, mtu);
873
874         len = enc_find_by_type_resp(matches, opdu, mtu);
875
876         g_slist_free_full(matches, g_free);
877
878         return len;
879 }
880
881 static int read_device_ccc(struct btd_device *device, uint16_t handle,
882                                 uint16_t *value)
883 {
884         char *filename;
885         GKeyFile *key_file;
886         char group[6];
887         char *str;
888         unsigned int config;
889         int err = 0;
890
891         filename = btd_device_get_storage_path(device, "ccc");
892         if (!filename) {
893                 warn("Unable to get ccc storage path for device");
894                 return -ENOENT;
895         }
896
897         key_file = g_key_file_new();
898         g_key_file_load_from_file(key_file, filename, 0, NULL);
899
900         sprintf(group, "%hu", handle);
901
902         str = g_key_file_get_string(key_file, group, "Value", NULL);
903         if (!str || sscanf(str, "%04X", &config) != 1)
904                 err = -ENOENT;
905         else
906                 *value = config;
907
908         g_free(str);
909         g_free(filename);
910         g_key_file_free(key_file);
911
912         return err;
913 }
914
915 static uint16_t read_value(struct gatt_channel *channel, uint16_t handle,
916                                                 uint8_t *pdu, size_t len)
917 {
918         struct attribute *a;
919         uint8_t status;
920         GList *l;
921         uint16_t cccval;
922         guint h = handle;
923
924         l = g_list_find_custom(channel->server->database,
925                                         GUINT_TO_POINTER(h), handle_cmp);
926         if (!l)
927                 return enc_error_resp(ATT_OP_READ_REQ, handle,
928                                         ATT_ECODE_INVALID_HANDLE, pdu, len);
929
930         a = l->data;
931
932         if (bt_uuid_cmp(&ccc_uuid, &a->uuid) == 0 &&
933                 read_device_ccc(channel->device, handle, &cccval) == 0) {
934                 uint8_t config[2];
935
936                 att_put_u16(cccval, config);
937                 return enc_read_resp(config, sizeof(config), pdu, len);
938         }
939
940         status = att_check_reqs(channel, ATT_OP_READ_REQ, a->read_req);
941
942         if (status == 0x00 && a->read_cb)
943                 status = a->read_cb(a, channel->device, a->cb_user_data);
944
945         if (status)
946                 return enc_error_resp(ATT_OP_READ_REQ, handle, status, pdu,
947                                                                         len);
948
949         return enc_read_resp(a->data, a->len, pdu, len);
950 }
951
952 static uint16_t read_blob(struct gatt_channel *channel, uint16_t handle,
953                                 uint16_t offset, uint8_t *pdu, size_t len)
954 {
955         struct attribute *a;
956         uint8_t status;
957         GList *l;
958         uint16_t cccval;
959         guint h = handle;
960
961         l = g_list_find_custom(channel->server->database,
962                                         GUINT_TO_POINTER(h), handle_cmp);
963         if (!l)
964                 return enc_error_resp(ATT_OP_READ_BLOB_REQ, handle,
965                                         ATT_ECODE_INVALID_HANDLE, pdu, len);
966
967         a = l->data;
968
969         if (a->len <= offset)
970                 return enc_error_resp(ATT_OP_READ_BLOB_REQ, handle,
971                                         ATT_ECODE_INVALID_OFFSET, pdu, len);
972
973         if (bt_uuid_cmp(&ccc_uuid, &a->uuid) == 0 &&
974                 read_device_ccc(channel->device, handle, &cccval) == 0) {
975                 uint8_t config[2];
976
977                 att_put_u16(cccval, config);
978                 return enc_read_blob_resp(config, sizeof(config), offset,
979                                                                 pdu, len);
980         }
981
982         status = att_check_reqs(channel, ATT_OP_READ_BLOB_REQ, a->read_req);
983
984         if (status == 0x00 && a->read_cb)
985                 status = a->read_cb(a, channel->device, a->cb_user_data);
986
987         if (status)
988                 return enc_error_resp(ATT_OP_READ_BLOB_REQ, handle, status,
989                                                                 pdu, len);
990
991         return enc_read_blob_resp(a->data, a->len, offset, pdu, len);
992 }
993
994 static uint16_t write_value(struct gatt_channel *channel, uint16_t handle,
995                                         const uint8_t *value, size_t vlen,
996                                         uint8_t *pdu, size_t len)
997 {
998         struct attribute *a;
999         uint8_t status;
1000         GList *l;
1001         guint h = handle;
1002
1003         l = g_list_find_custom(channel->server->database,
1004                                         GUINT_TO_POINTER(h), handle_cmp);
1005         if (!l)
1006                 return enc_error_resp(ATT_OP_WRITE_REQ, handle,
1007                                 ATT_ECODE_INVALID_HANDLE, pdu, len);
1008
1009         a = l->data;
1010
1011         status = att_check_reqs(channel, ATT_OP_WRITE_REQ, a->write_req);
1012         if (status)
1013                 return enc_error_resp(ATT_OP_WRITE_REQ, handle, status, pdu,
1014                                                                         len);
1015
1016         if (bt_uuid_cmp(&ccc_uuid, &a->uuid) != 0) {
1017
1018                 attrib_db_update(channel->server->adapter, handle, NULL,
1019                                                         value, vlen, NULL);
1020
1021                 if (a->write_cb) {
1022                         status = a->write_cb(a, channel->device,
1023                                                         a->cb_user_data);
1024                         if (status)
1025                                 return enc_error_resp(ATT_OP_WRITE_REQ, handle,
1026                                                         status, pdu, len);
1027                 }
1028         } else {
1029                 uint16_t cccval = att_get_u16(value);
1030                 char *filename;
1031                 GKeyFile *key_file;
1032                 char group[6], value[5];
1033                 char *data;
1034                 gsize length = 0;
1035
1036                 filename = btd_device_get_storage_path(channel->device, "ccc");
1037                 if (!filename) {
1038                         warn("Unable to get ccc storage path for device");
1039                         return enc_error_resp(ATT_OP_WRITE_REQ, handle,
1040                                                 ATT_ECODE_WRITE_NOT_PERM,
1041                                                 pdu, len);
1042                 }
1043
1044                 key_file = g_key_file_new();
1045                 g_key_file_load_from_file(key_file, filename, 0, NULL);
1046
1047                 sprintf(group, "%hu", handle);
1048                 sprintf(value, "%hX", cccval);
1049                 g_key_file_set_string(key_file, group, "Value", value);
1050
1051                 data = g_key_file_to_data(key_file, &length, NULL);
1052                 if (length > 0) {
1053                         create_file(filename, S_IRUSR | S_IWUSR);
1054                         g_file_set_contents(filename, data, length, NULL);
1055                 }
1056
1057 #ifdef __TIZEN_PATCH__
1058                 g_free(filename);
1059                 filename = btd_device_get_storage_path(channel->device, "ccc_sc");
1060                 if (!filename) {
1061                         warn("Unable to get ccc storage path for device");
1062                         return enc_error_resp(ATT_OP_WRITE_REQ, handle,
1063                                                 ATT_ECODE_WRITE_NOT_PERM,
1064                                                 pdu, len);
1065                 }
1066
1067                 g_key_file_free(key_file);
1068                 key_file = g_key_file_new();
1069                 g_key_file_load_from_file(key_file, filename, 0, NULL);
1070
1071                 memset(&group, 0x00, 6);
1072                 memset(&value, 0x00, 5);
1073                 sprintf(group, "%hu", handle);
1074                 sprintf(value, "%hX", cccval);
1075                 g_key_file_set_string(key_file, group, "Value", value);
1076
1077                 g_free(data);
1078                 data = g_key_file_to_data(key_file, &length, NULL);
1079                 if (length > 0) {
1080                         create_file(filename, S_IRUSR | S_IWUSR);
1081                         g_file_set_contents(filename, data, length, NULL);
1082                 }
1083 #endif
1084
1085                 g_free(data);
1086                 g_free(filename);
1087                 g_key_file_free(key_file);
1088         }
1089
1090         return enc_write_resp(pdu);
1091 }
1092
1093 static uint16_t mtu_exchange(struct gatt_channel *channel, uint16_t mtu,
1094                                                 uint8_t *pdu, size_t len)
1095 {
1096         GError *gerr = NULL;
1097         GIOChannel *io;
1098         uint16_t imtu;
1099
1100         if (mtu < ATT_DEFAULT_LE_MTU)
1101                 return enc_error_resp(ATT_OP_MTU_REQ, 0,
1102                                         ATT_ECODE_REQ_NOT_SUPP, pdu, len);
1103
1104         io = g_attrib_get_channel(channel->attrib);
1105
1106         bt_io_get(io, &gerr, BT_IO_OPT_IMTU, &imtu, BT_IO_OPT_INVALID);
1107         if (gerr) {
1108                 error("bt_io_get: %s", gerr->message);
1109                 g_error_free(gerr);
1110                 return enc_error_resp(ATT_OP_MTU_REQ, 0, ATT_ECODE_UNLIKELY,
1111                                                                 pdu, len);
1112         }
1113
1114         channel->mtu = MIN(mtu, imtu);
1115         g_attrib_set_mtu(channel->attrib, channel->mtu);
1116
1117         return enc_mtu_resp(imtu, pdu, len);
1118 }
1119
1120 static void channel_remove(struct gatt_channel *channel)
1121 {
1122         channel->server->clients = g_slist_remove(channel->server->clients,
1123                                                                 channel);
1124 #ifdef __TIZEN_PATCH__
1125         if (channel->server->clients == NULL) {
1126                 device_set_gatt_connected(channel->device, FALSE);
1127         }
1128 #endif
1129         channel_free(channel);
1130 }
1131
1132 static gboolean channel_watch_cb(GIOChannel *io, GIOCondition cond,
1133                                                 gpointer user_data)
1134 {
1135         channel_remove(user_data);
1136
1137         return FALSE;
1138 }
1139
1140 static void channel_handler(const uint8_t *ipdu, uint16_t len,
1141                                                         gpointer user_data)
1142 {
1143         struct gatt_channel *channel = user_data;
1144         uint8_t opdu[channel->mtu];
1145         uint16_t length, start, end, mtu, offset;
1146         bt_uuid_t uuid;
1147         uint8_t status = 0;
1148         size_t vlen;
1149         uint8_t *value = g_attrib_get_buffer(channel->attrib, &vlen);
1150
1151         DBG("op 0x%02x", ipdu[0]);
1152
1153         if (len > vlen) {
1154                 error("Too much data on ATT socket");
1155                 status = ATT_ECODE_INVALID_PDU;
1156                 goto done;
1157         }
1158
1159         switch (ipdu[0]) {
1160         case ATT_OP_READ_BY_GROUP_REQ:
1161                 length = dec_read_by_grp_req(ipdu, len, &start, &end, &uuid);
1162                 if (length == 0) {
1163                         status = ATT_ECODE_INVALID_PDU;
1164                         goto done;
1165                 }
1166
1167                 length = read_by_group(channel, start, end, &uuid, opdu,
1168                                                                 channel->mtu);
1169                 break;
1170         case ATT_OP_READ_BY_TYPE_REQ:
1171                 length = dec_read_by_type_req(ipdu, len, &start, &end, &uuid);
1172                 if (length == 0) {
1173                         status = ATT_ECODE_INVALID_PDU;
1174                         goto done;
1175                 }
1176
1177                 length = read_by_type(channel, start, end, &uuid, opdu,
1178                                                                 channel->mtu);
1179                 break;
1180         case ATT_OP_READ_REQ:
1181                 length = dec_read_req(ipdu, len, &start);
1182                 if (length == 0) {
1183                         status = ATT_ECODE_INVALID_PDU;
1184                         goto done;
1185                 }
1186
1187                 length = read_value(channel, start, opdu, channel->mtu);
1188                 break;
1189         case ATT_OP_READ_BLOB_REQ:
1190                 length = dec_read_blob_req(ipdu, len, &start, &offset);
1191                 if (length == 0) {
1192                         status = ATT_ECODE_INVALID_PDU;
1193                         goto done;
1194                 }
1195
1196                 length = read_blob(channel, start, offset, opdu, channel->mtu);
1197                 break;
1198         case ATT_OP_MTU_REQ:
1199                 if (!channel->le) {
1200                         status = ATT_ECODE_REQ_NOT_SUPP;
1201                         goto done;
1202                 }
1203
1204                 length = dec_mtu_req(ipdu, len, &mtu);
1205                 if (length == 0) {
1206                         status = ATT_ECODE_INVALID_PDU;
1207                         goto done;
1208                 }
1209
1210                 length = mtu_exchange(channel, mtu, opdu, channel->mtu);
1211                 break;
1212         case ATT_OP_FIND_INFO_REQ:
1213                 length = dec_find_info_req(ipdu, len, &start, &end);
1214                 if (length == 0) {
1215                         status = ATT_ECODE_INVALID_PDU;
1216                         goto done;
1217                 }
1218
1219                 length = find_info(channel, start, end, opdu, channel->mtu);
1220                 break;
1221         case ATT_OP_WRITE_REQ:
1222                 length = dec_write_req(ipdu, len, &start, value, &vlen);
1223                 if (length == 0) {
1224                         status = ATT_ECODE_INVALID_PDU;
1225                         goto done;
1226                 }
1227
1228                 length = write_value(channel, start, value, vlen, opdu,
1229                                                                 channel->mtu);
1230                 break;
1231         case ATT_OP_WRITE_CMD:
1232                 length = dec_write_cmd(ipdu, len, &start, value, &vlen);
1233                 if (length > 0)
1234                         write_value(channel, start, value, vlen, opdu,
1235                                                                 channel->mtu);
1236                 return;
1237         case ATT_OP_FIND_BY_TYPE_REQ:
1238                 length = dec_find_by_type_req(ipdu, len, &start, &end,
1239                                                         &uuid, value, &vlen);
1240                 if (length == 0) {
1241                         status = ATT_ECODE_INVALID_PDU;
1242                         goto done;
1243                 }
1244
1245                 length = find_by_type(channel, start, end, &uuid, value, vlen,
1246                                                         opdu, channel->mtu);
1247                 break;
1248         case ATT_OP_HANDLE_CNF:
1249                 return;
1250         case ATT_OP_HANDLE_IND:
1251         case ATT_OP_HANDLE_NOTIFY:
1252                 /* The attribute client is already handling these */
1253                 return;
1254         case ATT_OP_READ_MULTI_REQ:
1255         case ATT_OP_PREP_WRITE_REQ:
1256         case ATT_OP_EXEC_WRITE_REQ:
1257         default:
1258                 DBG("Unsupported request 0x%02x", ipdu[0]);
1259                 status = ATT_ECODE_REQ_NOT_SUPP;
1260                 goto done;
1261         }
1262
1263         if (length == 0)
1264                 status = ATT_ECODE_IO;
1265
1266 done:
1267         if (status)
1268                 length = enc_error_resp(ipdu[0], 0x0000, status, opdu,
1269                                                                 channel->mtu);
1270
1271         g_attrib_send(channel->attrib, 0, opdu, length, NULL, NULL, NULL);
1272 }
1273
1274 GAttrib *attrib_from_device(struct btd_device *device)
1275 {
1276         struct btd_adapter *adapter = device_get_adapter(device);
1277         struct gatt_server *server;
1278         GSList *l;
1279
1280         l = g_slist_find_custom(servers, adapter, adapter_cmp);
1281         if (!l)
1282                 return NULL;
1283
1284         server = l->data;
1285
1286         for (l = server->clients; l; l = l->next) {
1287                 struct gatt_channel *channel = l->data;
1288
1289                 if (channel->device == device)
1290                         return g_attrib_ref(channel->attrib);
1291         }
1292
1293         return NULL;
1294 }
1295
1296 guint attrib_channel_attach(GAttrib *attrib)
1297 {
1298         struct gatt_server *server;
1299         struct btd_device *device;
1300         struct gatt_channel *channel;
1301         bdaddr_t src, dst;
1302         GIOChannel *io;
1303         GError *gerr = NULL;
1304         uint8_t bdaddr_type;
1305         uint16_t cid;
1306         guint mtu = 0;
1307
1308         io = g_attrib_get_channel(attrib);
1309
1310         bt_io_get(io, &gerr,
1311                         BT_IO_OPT_SOURCE_BDADDR, &src,
1312                         BT_IO_OPT_DEST_BDADDR, &dst,
1313                         BT_IO_OPT_DEST_TYPE, &bdaddr_type,
1314                         BT_IO_OPT_CID, &cid,
1315                         BT_IO_OPT_IMTU, &mtu,
1316                         BT_IO_OPT_INVALID);
1317         if (gerr) {
1318                 error("bt_io_get: %s", gerr->message);
1319                 g_error_free(gerr);
1320                 return 0;
1321         }
1322
1323         server = find_gatt_server(&src);
1324         if (server == NULL)
1325                 return 0;
1326
1327         channel = g_new0(struct gatt_channel, 1);
1328         channel->server = server;
1329
1330         device = btd_adapter_find_device(server->adapter, &dst);
1331         if (device == NULL) {
1332                 error("Device object not found for attrib server");
1333                 g_free(channel);
1334                 return 0;
1335         }
1336
1337 #ifdef __TIZEN_PATCH__
1338         device_set_gatt_connected(device, TRUE);
1339 #endif
1340
1341         if (!device_is_bonded(device, bdaddr_type)) {
1342                 char *filename;
1343
1344                 filename = btd_device_get_storage_path(device, "ccc");
1345                 if (filename) {
1346                         unlink(filename);
1347                         g_free(filename);
1348                 }
1349         }
1350
1351         if (cid != ATT_CID) {
1352                 channel->le = FALSE;
1353                 channel->mtu = mtu;
1354         } else {
1355                 channel->le = TRUE;
1356                 channel->mtu = ATT_DEFAULT_LE_MTU;
1357         }
1358
1359         channel->attrib = g_attrib_ref(attrib);
1360         channel->id = g_attrib_register(channel->attrib, GATTRIB_ALL_REQS,
1361                         GATTRIB_ALL_HANDLES, channel_handler, channel, NULL);
1362
1363         channel->cleanup_id = g_io_add_watch(io, G_IO_HUP, channel_watch_cb,
1364                                                                 channel);
1365 #ifdef __TIZEN_PATCH__
1366         device_set_attrib(device, channel->id, channel->attrib);
1367 #endif
1368         channel->device = btd_device_ref(device);
1369
1370         server->clients = g_slist_append(server->clients, channel);
1371
1372         return channel->id;
1373 }
1374
1375 static int channel_id_cmp(gconstpointer data, gconstpointer user_data)
1376 {
1377         const struct gatt_channel *channel = data;
1378         guint id = GPOINTER_TO_UINT(user_data);
1379
1380         return channel->id - id;
1381 }
1382
1383 gboolean attrib_channel_detach(GAttrib *attrib, guint id)
1384 {
1385         struct gatt_server *server;
1386         struct gatt_channel *channel;
1387         GError *gerr = NULL;
1388         GIOChannel *io;
1389         bdaddr_t src;
1390         GSList *l;
1391
1392         io = g_attrib_get_channel(attrib);
1393
1394         bt_io_get(io, &gerr, BT_IO_OPT_SOURCE_BDADDR, &src, BT_IO_OPT_INVALID);
1395
1396         if (gerr != NULL) {
1397                 error("bt_io_get: %s", gerr->message);
1398                 g_error_free(gerr);
1399                 return FALSE;
1400         }
1401
1402         server = find_gatt_server(&src);
1403         if (server == NULL)
1404                 return FALSE;
1405
1406         l = g_slist_find_custom(server->clients, GUINT_TO_POINTER(id),
1407                                                                 channel_id_cmp);
1408         if (!l)
1409                 return FALSE;
1410
1411         channel = l->data;
1412
1413         g_attrib_unregister(channel->attrib, channel->id);
1414         channel_remove(channel);
1415
1416         return TRUE;
1417 }
1418
1419 static void connect_event(GIOChannel *io, GError *gerr, void *user_data)
1420 {
1421         GAttrib *attrib;
1422
1423         DBG("");
1424
1425         if (gerr) {
1426                 error("%s", gerr->message);
1427                 return;
1428         }
1429
1430         attrib = g_attrib_new(io);
1431         if (!attrib)
1432                 return;
1433
1434         attrib_channel_attach(attrib);
1435         g_attrib_unref(attrib);
1436 }
1437
1438 static gboolean register_core_services(struct gatt_server *server)
1439 {
1440         uint8_t atval[256];
1441         bt_uuid_t uuid;
1442         uint16_t appearance = 0x0000;
1443         struct gatt_info *info;
1444
1445         /* GAP service: primary service definition */
1446         bt_uuid16_create(&uuid, GATT_PRIM_SVC_UUID);
1447         att_put_u16(GENERIC_ACCESS_PROFILE_ID, &atval[0]);
1448         attrib_db_add_new(server, 0x0001, &uuid, ATT_NONE, ATT_NOT_PERMITTED,
1449                                                                 atval, 2);
1450
1451         /* GAP service: device name characteristic */
1452         server->name_handle = 0x0006;
1453         bt_uuid16_create(&uuid, GATT_CHARAC_UUID);
1454         atval[0] = ATT_CHAR_PROPER_READ;
1455         att_put_u16(server->name_handle, &atval[1]);
1456         att_put_u16(GATT_CHARAC_DEVICE_NAME, &atval[3]);
1457         attrib_db_add_new(server, 0x0004, &uuid, ATT_NONE, ATT_NOT_PERMITTED,
1458                                                                 atval, 5);
1459
1460         /* GAP service: device name attribute */
1461         bt_uuid16_create(&uuid, GATT_CHARAC_DEVICE_NAME);
1462         attrib_db_add_new(server, server->name_handle, &uuid, ATT_NONE,
1463                                                 ATT_NOT_PERMITTED, NULL, 0);
1464
1465         /* GAP service: device appearance characteristic */
1466         server->appearance_handle = 0x0008;
1467         bt_uuid16_create(&uuid, GATT_CHARAC_UUID);
1468         atval[0] = ATT_CHAR_PROPER_READ;
1469         att_put_u16(server->appearance_handle, &atval[1]);
1470         att_put_u16(GATT_CHARAC_APPEARANCE, &atval[3]);
1471         attrib_db_add_new(server, 0x0007, &uuid, ATT_NONE, ATT_NOT_PERMITTED,
1472                                                                 atval, 5);
1473
1474         /* GAP service: device appearance attribute */
1475         bt_uuid16_create(&uuid, GATT_CHARAC_APPEARANCE);
1476         att_put_u16(appearance, &atval[0]);
1477         attrib_db_add_new(server, server->appearance_handle, &uuid, ATT_NONE,
1478                                                 ATT_NOT_PERMITTED, atval, 2);
1479         server->gap_sdp_handle = attrib_create_sdp_new(server, 0x0001,
1480                                                 "Generic Access Profile");
1481         if (server->gap_sdp_handle == 0) {
1482                 error("Failed to register GAP service record");
1483                 return FALSE;
1484         }
1485
1486         /* GATT service: primary service definition */
1487         bt_uuid16_create(&uuid, GATT_PRIM_SVC_UUID);
1488         att_put_u16(GENERIC_ATTRIB_PROFILE_ID, &atval[0]);
1489         attrib_db_add_new(server, 0x0010, &uuid, ATT_NONE, ATT_NOT_PERMITTED,
1490                                                                 atval, 2);
1491
1492 #ifdef __TIZEN_PATCH__
1493         /* GATT service: service changed characteristic */
1494         server->name_handle = 0x0012;
1495         bt_uuid16_create(&uuid, GATT_CLIENT_CHARAC_CFG_UUID);
1496
1497         atval[0] = ATT_CHAR_PROPER_READ;
1498         att_put_u16(server->name_handle, &atval[1]);
1499         att_put_u16(GATT_CHARAC_SERVICE_CHANGED, &atval[3]);
1500         att_put_u16(GATT_CLIENT_CHARAC_CFG_IND_BIT, atval);
1501         attrib_db_add_new(server, 0x0011, &uuid, ATT_NONE, ATT_NOT_PERMITTED,
1502                                                                 atval, 4);
1503
1504         /* GATT service: service changed attribute */
1505         bt_uuid16_create(&uuid, GATT_CHARAC_SERVICE_CHANGED);
1506         attrib_db_add_new(server, server->name_handle, &uuid, ATT_NONE,
1507                                                 ATT_NOT_PERMITTED, NULL, 0);
1508 #endif
1509
1510         server->gatt_sdp_handle = attrib_create_sdp_new(server, 0x0010,
1511                                                 "Generic Attribute Profile");
1512         if (server->gatt_sdp_handle == 0) {
1513                 error("Failed to register GATT service record");
1514                 return FALSE;
1515         }
1516
1517         return TRUE;
1518 }
1519
1520 int btd_adapter_gatt_server_start(struct btd_adapter *adapter)
1521 {
1522         struct gatt_server *server;
1523         GError *gerr = NULL;
1524         const bdaddr_t *addr;
1525
1526         DBG("Start GATT server in hci%d", btd_adapter_get_index(adapter));
1527
1528         server = g_new0(struct gatt_server, 1);
1529         server->adapter = btd_adapter_ref(adapter);
1530
1531         addr = btd_adapter_get_address(server->adapter);
1532
1533         /* BR/EDR socket */
1534         server->l2cap_io = bt_io_listen(connect_event, NULL, NULL, NULL, &gerr,
1535                                         BT_IO_OPT_SOURCE_BDADDR, addr,
1536                                         BT_IO_OPT_PSM, ATT_PSM,
1537                                         BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
1538                                         BT_IO_OPT_INVALID);
1539
1540         if (server->l2cap_io == NULL) {
1541                 error("%s", gerr->message);
1542                 g_error_free(gerr);
1543                 gatt_server_free(server);
1544                 return -1;
1545         }
1546
1547         if (!register_core_services(server)) {
1548                 gatt_server_free(server);
1549                 return -1;
1550         }
1551
1552         /* LE socket */
1553         server->le_io = bt_io_listen(connect_event, NULL,
1554                                         &server->le_io, NULL, &gerr,
1555                                         BT_IO_OPT_SOURCE_BDADDR, addr,
1556                                         BT_IO_OPT_SOURCE_TYPE, BDADDR_LE_PUBLIC,
1557                                         BT_IO_OPT_CID, ATT_CID,
1558                                         BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
1559                                         BT_IO_OPT_INVALID);
1560
1561         if (server->le_io == NULL) {
1562                 error("%s", gerr->message);
1563                 g_error_free(gerr);
1564                 /* Doesn't have LE support, continue */
1565         }
1566
1567         servers = g_slist_prepend(servers, server);
1568         return 0;
1569 }
1570
1571 void btd_adapter_gatt_server_stop(struct btd_adapter *adapter)
1572 {
1573         struct gatt_server *server;
1574         GSList *l;
1575
1576         l = g_slist_find_custom(servers, adapter, adapter_cmp);
1577         if (l == NULL)
1578                 return;
1579
1580         DBG("Stop GATT server in hci%d", btd_adapter_get_index(adapter));
1581
1582         server = l->data;
1583         servers = g_slist_remove(servers, server);
1584         gatt_server_free(server);
1585 }
1586
1587 uint32_t attrib_create_sdp(struct btd_adapter *adapter, uint16_t handle,
1588                                                         const char *name)
1589 {
1590         GSList *l;
1591
1592         l = g_slist_find_custom(servers, adapter, adapter_cmp);
1593         if (l == NULL)
1594                 return 0;
1595
1596         return attrib_create_sdp_new(l->data, handle, name);
1597 }
1598
1599 void attrib_free_sdp(struct btd_adapter *adapter, uint32_t sdp_handle)
1600 {
1601         adapter_service_remove(adapter, sdp_handle);
1602 }
1603
1604 static uint16_t find_uuid16_avail(struct btd_adapter *adapter, uint16_t nitems)
1605 {
1606         struct gatt_server *server;
1607         uint16_t handle;
1608         GSList *l;
1609         GList *dl;
1610
1611         l = g_slist_find_custom(servers, adapter, adapter_cmp);
1612         if (l == NULL)
1613                 return 0;
1614
1615         server = l->data;
1616         if (server->database == NULL)
1617                 return 0x0001;
1618
1619         for (dl = server->database, handle = 0x0001; dl; dl = dl->next) {
1620                 struct attribute *a = dl->data;
1621
1622                 if ((bt_uuid_cmp(&a->uuid, &prim_uuid) == 0 ||
1623                                 bt_uuid_cmp(&a->uuid, &snd_uuid) == 0) &&
1624                                 a->handle - handle >= nitems)
1625                         /* Note: the range above excludes the current handle */
1626                         return handle;
1627
1628 #ifdef __TIZEN_PATCH__
1629                 if (a->len == 4) {
1630                         /* 32 bit UUID service definition */
1631                         return 0;
1632                 }
1633 #endif
1634                 if (a->len == 16 && (bt_uuid_cmp(&a->uuid, &prim_uuid) == 0 ||
1635                                 bt_uuid_cmp(&a->uuid, &snd_uuid) == 0)) {
1636                         /* 128 bit UUID service definition */
1637                         return 0;
1638                 }
1639
1640                 if (a->handle == 0xffff)
1641                         return 0;
1642
1643                 handle = a->handle + 1;
1644         }
1645
1646         if (0xffff - handle + 1 >= nitems)
1647                 return handle;
1648
1649         return 0;
1650 }
1651
1652 #ifdef __TIZEN_PATCH__
1653 static uint16_t find_uuid32_avail(struct btd_adapter *adapter, uint16_t nitems)
1654 {
1655         struct gatt_server *server;
1656         uint16_t handle;
1657         GSList *l;
1658         GList *dl;
1659
1660         l = g_slist_find_custom(servers, adapter, adapter_cmp);
1661         if (l == NULL)
1662                 return 0;
1663
1664         server = l->data;
1665         if (server->database == NULL)
1666                 return 0x0001;
1667
1668         for (dl = server->database, handle = 0x0001; dl; dl = dl->next) {
1669                 struct attribute *a = dl->data;
1670
1671                 if ((bt_uuid_cmp(&a->uuid, &prim_uuid32) == 0 ||
1672                                 bt_uuid_cmp(&a->uuid, &snd_uuid32) == 0) &&
1673                                 a->handle - handle >= nitems) {
1674                         /* Note: the range above excludes the current handle */
1675                         return handle;
1676                         }
1677
1678                 if (a->len == 2 || a->len == 16) {
1679                         /* 16 bit UUID or 128 bit UUID service definition */
1680                         return 0;
1681                 }
1682
1683                 if (a->handle == 0xffff)
1684                         return 0;
1685
1686                 handle = a->handle + 1;
1687         }
1688
1689         if (0xffff - handle + 1 >= nitems)
1690                 return handle;
1691
1692         return 0;
1693 }
1694 #endif
1695
1696 static uint16_t find_uuid128_avail(struct btd_adapter *adapter, uint16_t nitems)
1697 {
1698         uint16_t handle = 0, end = 0xffff;
1699         struct gatt_server *server;
1700         GList *dl;
1701         GSList *l;
1702
1703         l = g_slist_find_custom(servers, adapter, adapter_cmp);
1704         if (l == NULL)
1705                 return 0;
1706
1707         server = l->data;
1708         if (server->database == NULL)
1709                 return 0xffff - nitems + 1;
1710
1711         for (dl = g_list_last(server->database); dl; dl = dl->prev) {
1712                 struct attribute *a = dl->data;
1713
1714                 if (handle == 0)
1715                         handle = a->handle;
1716
1717                 if (bt_uuid_cmp(&a->uuid, &prim_uuid) != 0 &&
1718                                 bt_uuid_cmp(&a->uuid, &snd_uuid) != 0)
1719                         continue;
1720
1721                 if (end - handle >= nitems)
1722                         return end - nitems + 1;
1723
1724                 if (a->len == 2) {
1725                         /* 16 bit UUID service definition */
1726                         return 0;
1727                 }
1728
1729 #ifdef __TIZEN_PATCH__
1730                 if (a->len == 4) {
1731                         /* 32 bit UUID service definition */
1732                         return 0;
1733                 }
1734 #endif
1735
1736                 if (a->handle == 0x0001)
1737                         return 0;
1738
1739                 end = a->handle - 1;
1740                 handle = 0;
1741         }
1742
1743         if (end - 0x0001 >= nitems)
1744                 return end - nitems + 1;
1745
1746         return 0;
1747 }
1748
1749 uint16_t attrib_db_find_avail(struct btd_adapter *adapter, bt_uuid_t *svc_uuid,
1750                                                                 uint16_t nitems)
1751 {
1752         g_assert(nitems > 0);
1753
1754         if (svc_uuid->type == BT_UUID16)
1755                 return find_uuid16_avail(adapter, nitems);
1756 #ifdef __TIZEN_PATCH__
1757         else if (svc_uuid->type == BT_UUID32)
1758                 return find_uuid32_avail(adapter, nitems);
1759 #endif
1760         else if (svc_uuid->type == BT_UUID128)
1761                 return find_uuid128_avail(adapter, nitems);
1762         else {
1763                 char uuidstr[MAX_LEN_UUID_STR];
1764
1765                 bt_uuid_to_string(svc_uuid, uuidstr, MAX_LEN_UUID_STR);
1766                 error("Service uuid: %s is neither a 16-bit nor a 128-bit uuid",
1767                                                                 uuidstr);
1768                 return 0;
1769         }
1770 }
1771
1772 struct attribute *attrib_db_add(struct btd_adapter *adapter, uint16_t handle,
1773                                         bt_uuid_t *uuid, int read_req,
1774                                         int write_req, const uint8_t *value,
1775                                         size_t len)
1776 {
1777         GSList *l;
1778
1779         l = g_slist_find_custom(servers, adapter, adapter_cmp);
1780         if (l == NULL)
1781                 return NULL;
1782
1783         return attrib_db_add_new(l->data, handle, uuid, read_req, write_req,
1784                                                                 value, len);
1785 }
1786
1787 int attrib_db_update(struct btd_adapter *adapter, uint16_t handle,
1788                                         bt_uuid_t *uuid, const uint8_t *value,
1789                                         size_t len, struct attribute **attr)
1790 {
1791         struct gatt_server *server;
1792         struct attribute *a;
1793         GSList *l;
1794         GList *dl;
1795         guint h = handle;
1796
1797         l = g_slist_find_custom(servers, adapter, adapter_cmp);
1798         if (l == NULL)
1799                 return -ENOENT;
1800
1801         server = l->data;
1802
1803         DBG("handle=0x%04x", handle);
1804
1805         dl = g_list_find_custom(server->database, GUINT_TO_POINTER(h),
1806                                                                 handle_cmp);
1807         if (dl == NULL)
1808                 return -ENOENT;
1809
1810         a = dl->data;
1811
1812         a->data = g_try_realloc(a->data, len);
1813         if (len && a->data == NULL)
1814                 return -ENOMEM;
1815
1816         a->len = len;
1817         memcpy(a->data, value, len);
1818
1819         if (uuid != NULL)
1820                 a->uuid = *uuid;
1821
1822         if (attr)
1823                 *attr = a;
1824
1825         return 0;
1826 }
1827
1828 int attrib_db_del(struct btd_adapter *adapter, uint16_t handle)
1829 {
1830         struct gatt_server *server;
1831         struct attribute *a;
1832         GSList *l;
1833         GList *dl;
1834         guint h = handle;
1835
1836         l = g_slist_find_custom(servers, adapter, adapter_cmp);
1837         if (l == NULL)
1838                 return -ENOENT;
1839
1840         server = l->data;
1841
1842         DBG("handle=0x%04x", handle);
1843
1844         dl = g_list_find_custom(server->database, GUINT_TO_POINTER(h),
1845                                                                 handle_cmp);
1846         if (dl == NULL)
1847                 return -ENOENT;
1848
1849         a = dl->data;
1850         server->database = g_list_remove(server->database, a);
1851         g_free(a->data);
1852         g_free(a);
1853
1854         return 0;
1855 }
1856
1857 #ifdef __TIZEN_PATCH__
1858 static uint8_t attrib_get_ccc_info(struct btd_device *device, uint16_t handle)
1859 {
1860         uint16_t cccval = 0;
1861         char *filename;
1862         GKeyFile *key_file;
1863         char group[6];
1864         char *value;
1865
1866         filename = btd_device_get_storage_path(device, "ccc");
1867         if (!filename) {
1868                 warn("Unable to get ccc storage path for device");
1869                 return 0;
1870         }
1871
1872         key_file = g_key_file_new();
1873         g_key_file_load_from_file(key_file, filename, 0, NULL);
1874         sprintf(group, "%hu", handle);
1875
1876         /* Get the CCC value */
1877         value = g_key_file_get_string(key_file, group, "Value", NULL);
1878         if (!value)
1879                 return 0;
1880
1881         sscanf(value, "%hX", &cccval);
1882
1883         g_free(filename);
1884         g_key_file_free(key_file);
1885
1886         return cccval;
1887 }
1888
1889 static uint8_t attrib_get_sc_ccc_info(struct btd_device *device, uint16_t handle)
1890 {
1891         uint16_t cccval = 0;
1892         char *filename;
1893         GKeyFile *key_file;
1894         char group[6];
1895         char *value;
1896
1897         filename = btd_device_get_storage_path(device, "ccc_sc");
1898         if (!filename) {
1899                 warn("Unable to get ccc_sc storage path for device");
1900                 return 0;
1901         }
1902
1903         key_file = g_key_file_new();
1904         g_key_file_load_from_file(key_file, filename, 0, NULL);
1905         sprintf(group, "%hu", handle);
1906
1907         /* Get the CCC value */
1908         value = g_key_file_get_string(key_file, group, "Value", NULL);
1909         if (!value)
1910                 return 0;
1911
1912         sscanf(value, "%hX", &cccval);
1913
1914         g_free(filename);
1915         g_key_file_free(key_file);
1916
1917         return cccval;
1918 }
1919
1920 void attrib_send_sc_ind(struct btd_device *device, GAttrib *attrib,
1921                                 uint16_t start_handle, uint16_t end_handle,
1922                                 size_t vlen)
1923 {
1924         size_t length = 0;
1925         uint8_t *pdu;
1926         size_t mtu;
1927
1928         pdu = g_attrib_get_buffer(attrib, &mtu);
1929         length = send_sc_indication(start_handle, end_handle, vlen, pdu, mtu);
1930         g_attrib_send(attrib, 0, pdu, length, NULL, NULL, NULL);
1931 }
1932
1933 void attrib_send_noty_ind(struct btd_device *device, GAttrib *attrib,
1934                                 uint16_t handle, uint16_t desc_handle,
1935                                 uint8_t *value, size_t vlen)
1936 {
1937         size_t length = 0;
1938         uint16_t cccval;
1939         uint8_t *pdu;
1940         size_t mtu;
1941
1942         cccval = attrib_get_ccc_info(device, desc_handle);
1943         if (!cccval)
1944                 return;
1945
1946         pdu = g_attrib_get_buffer(attrib, &mtu);
1947         if (cccval == GATT_CLIENT_CHARAC_CFG_NOTIF_BIT) {
1948                 length = enc_notification(handle, value, vlen, pdu, mtu);
1949                 g_attrib_send(attrib, 0, pdu, length, NULL, NULL, NULL);
1950         } else if (cccval == GATT_CLIENT_CHARAC_CFG_IND_BIT) {
1951                 length = enc_indication(handle, value, vlen, pdu, mtu);
1952                 g_attrib_send(attrib, 0, pdu, length, NULL, NULL, NULL);
1953         }
1954 }
1955 #endif
1956
1957 int attrib_gap_set(struct btd_adapter *adapter, uint16_t uuid,
1958                                         const uint8_t *value, size_t len)
1959 {
1960         struct gatt_server *server;
1961         uint16_t handle;
1962         GSList *l;
1963
1964         l = g_slist_find_custom(servers, adapter, adapter_cmp);
1965         if (l == NULL)
1966                 return -ENOENT;
1967
1968         server = l->data;
1969
1970         /* FIXME: Missing Privacy and Reconnection Address */
1971
1972         switch (uuid) {
1973         case GATT_CHARAC_DEVICE_NAME:
1974                 handle = server->name_handle;
1975                 break;
1976         case GATT_CHARAC_APPEARANCE:
1977                 handle = server->appearance_handle;
1978                 break;
1979         default:
1980                 return -ENOSYS;
1981         }
1982
1983         return attrib_db_update(adapter, handle, NULL, value, len, NULL);
1984 }