3
* BlueZ - Bluetooth protocol stack for Linux
5
* Copyright (C) 2010 Nokia Corporation
6
* Copyright (C) 2010 Marcel Holtmann <marcel@holtmann.org>
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.
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.
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
35
#include <bluetooth/bluetooth.h>
36
#include <bluetooth/sdp.h>
37
#include <bluetooth/sdp_lib.h>
40
#include "glib-helper.h"
47
#include "attrib-server.h"
52
static GSList *database = NULL;
69
static GIOChannel *l2cap_io = NULL;
70
static GIOChannel *le_io = NULL;
71
static GSList *clients = NULL;
72
static uint32_t sdp_handle = 0;
74
static uuid_t prim_uuid = { .type = SDP_UUID16, .value.uuid16 = GATT_PRIM_SVC_UUID };
75
static uuid_t snd_uuid = { .type = SDP_UUID16, .value.uuid16 = GATT_SND_SVC_UUID };
77
static sdp_record_t *server_record_new(void)
79
sdp_list_t *svclass_id, *apseq, *proto[2], *profiles, *root, *aproto;
80
uuid_t root_uuid, proto_uuid, gatt_uuid, l2cap;
81
sdp_profile_desc_t profile;
83
sdp_data_t *psm, *sh, *eh;
84
uint16_t lp = GATT_PSM, start = 0x0001, end = 0xffff;
86
record = sdp_record_alloc();
90
sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
91
root = sdp_list_append(NULL, &root_uuid);
92
sdp_set_browse_groups(record, root);
93
sdp_list_free(root, NULL);
95
sdp_uuid16_create(&gatt_uuid, GENERIC_ATTRIB_SVCLASS_ID);
96
svclass_id = sdp_list_append(NULL, &gatt_uuid);
97
sdp_set_service_classes(record, svclass_id);
98
sdp_list_free(svclass_id, NULL);
100
sdp_uuid16_create(&profile.uuid, GENERIC_ATTRIB_PROFILE_ID);
101
profile.version = 0x0100;
102
profiles = sdp_list_append(NULL, &profile);
103
sdp_set_profile_descs(record, profiles);
104
sdp_list_free(profiles, NULL);
106
sdp_uuid16_create(&l2cap, L2CAP_UUID);
107
proto[0] = sdp_list_append(NULL, &l2cap);
108
psm = sdp_data_alloc(SDP_UINT16, &lp);
109
proto[0] = sdp_list_append(proto[0], psm);
110
apseq = sdp_list_append(NULL, proto[0]);
112
sdp_uuid16_create(&proto_uuid, ATT_UUID);
113
proto[1] = sdp_list_append(NULL, &proto_uuid);
114
sh = sdp_data_alloc(SDP_UINT16, &start);
115
proto[1] = sdp_list_append(proto[1], sh);
116
eh = sdp_data_alloc(SDP_UINT16, &end);
117
proto[1] = sdp_list_append(proto[1], eh);
118
apseq = sdp_list_append(apseq, proto[1]);
120
aproto = sdp_list_append(NULL, apseq);
121
sdp_set_access_protos(record, aproto);
123
sdp_set_info_attr(record, "Generic Attribute Profile", "BlueZ", NULL);
125
sdp_set_url_attr(record, "http://www.bluez.org/",
126
"http://www.bluez.org/", "http://www.bluez.org/");
128
sdp_set_service_id(record, gatt_uuid);
133
sdp_list_free(proto[0], NULL);
134
sdp_list_free(proto[1], NULL);
135
sdp_list_free(apseq, NULL);
136
sdp_list_free(aproto, NULL);
141
static uint16_t read_by_group(uint16_t start, uint16_t end, uuid_t *uuid,
142
uint8_t *pdu, int len)
144
struct att_data_list *adl;
146
struct group_elem *cur, *old = NULL;
148
uint16_t length, last_handle, last_size = 0;
151
if (start > end || start == 0x0000)
152
return enc_error_resp(ATT_OP_READ_BY_GROUP_REQ, start,
153
ATT_ECODE_INVALID_HANDLE, pdu, len);
156
* Only <<Primary Service>> and <<Secondary Service>> grouping
157
* types may be used in the Read By Group Type Request.
160
if (sdp_uuid_cmp(uuid, &prim_uuid) != 0 &&
161
sdp_uuid_cmp(uuid, &snd_uuid) != 0)
162
return enc_error_resp(ATT_OP_READ_BY_GROUP_REQ, 0x0000,
163
ATT_ECODE_UNSUPP_GRP_TYPE, pdu, len);
166
for (l = database, groups = NULL; l; l = l->next) {
169
if (a->handle < start)
172
if (a->handle >= end)
175
/* The old group ends when a new one starts */
176
if (old && (sdp_uuid_cmp(&a->uuid, &prim_uuid) == 0 ||
177
sdp_uuid_cmp(&a->uuid, &snd_uuid) == 0)) {
178
old->end = last_handle;
182
if (sdp_uuid_cmp(&a->uuid, uuid) != 0) {
183
/* Still inside a service, update its last handle */
185
last_handle = a->handle;
189
if (last_size && (last_size != a->len))
192
cur = g_new0(struct group_elem, 1);
193
cur->handle = a->handle;
197
/* Attribute Grouping Type found */
198
groups = g_slist_append(groups, cur);
205
return enc_error_resp(ATT_OP_READ_BY_GROUP_REQ, start,
206
ATT_ECODE_ATTR_NOT_FOUND, pdu, len);
209
cur->end = a->handle;
211
cur->end = last_handle;
213
length = g_slist_length(groups);
215
adl = g_new0(struct att_data_list, 1);
216
adl->len = last_size + 4; /* Length of each element */
217
adl->num = length; /* Number of primary or secondary services */
218
adl->data = g_malloc(length * sizeof(uint8_t *));
220
for (i = 0, l = groups; l; l = l->next, i++) {
225
adl->data[i] = g_malloc(adl->len);
226
value = (void *) adl->data[i];
228
att_put_u16(cur->handle, value);
229
att_put_u16(cur->end, &value[2]);
230
/* Attribute Value */
231
memcpy(&value[4], cur->data, cur->len);
234
length = enc_read_by_grp_resp(adl, pdu, len);
236
att_data_list_free(adl);
237
g_slist_foreach(groups, (GFunc) g_free, NULL);
238
g_slist_free(groups);
243
static uint16_t read_by_type(uint16_t start, uint16_t end, uuid_t *uuid,
244
uint8_t *pdu, int len)
246
struct att_data_list *adl;
249
uint16_t num, length;
252
if (start > end || start == 0x0000)
253
return enc_error_resp(ATT_OP_READ_BY_TYPE_REQ, start,
254
ATT_ECODE_INVALID_HANDLE, pdu, len);
256
for (l = database, length = 0, types = NULL; l; l = l->next) {
259
if (a->handle < start)
262
if (a->handle >= end)
265
if (sdp_uuid_cmp(&a->uuid, uuid) != 0)
268
/* All elements must have the same length */
271
else if (a->len != length)
274
types = g_slist_append(types, a);
278
return enc_error_resp(ATT_OP_READ_BY_TYPE_REQ, start,
279
ATT_ECODE_ATTR_NOT_FOUND, pdu, len);
281
num = g_slist_length(types);
283
/* Handle length plus attribute value length */
286
adl = g_new0(struct att_data_list, 1);
287
adl->len = length; /* Length of each element */
288
adl->num = num; /* Number of primary or secondary services */
289
adl->data = g_malloc(num * sizeof(uint8_t *));
291
for (i = 0, l = types; l; i++, l = l->next) {
295
adl->data[i] = g_malloc(length);
297
value = (void *) adl->data[i];
299
att_put_u16(a->handle, value);
301
/* Attribute Value */
302
memcpy(&value[2], a->data, a->len);
305
length = enc_read_by_type_resp(adl, pdu, len);
307
att_data_list_free(adl);
313
static int find_info(uint16_t start, uint16_t end, uint8_t *pdu, int len)
316
struct att_data_list *adl;
318
uint8_t format, last_type = SDP_UUID_UNSPEC;
319
uint16_t length, num;
322
if (start > end || start == 0x0000)
323
return enc_error_resp(ATT_OP_FIND_INFO_REQ, start,
324
ATT_ECODE_INVALID_HANDLE, pdu, len);
326
for (l = database, info = NULL, num = 0; l; l = l->next) {
329
if (a->handle < start)
335
if (last_type == SDP_UUID_UNSPEC)
336
last_type = a->uuid.type;
338
if (a->uuid.type != last_type)
341
info = g_slist_append(info, a);
344
last_type = a->uuid.type;
348
return enc_error_resp(ATT_OP_FIND_INFO_REQ, start,
349
ATT_ECODE_ATTR_NOT_FOUND, pdu, len);
351
if (last_type == SDP_UUID16) {
354
} else if (last_type == SDP_UUID128) {
359
adl = g_new0(struct att_data_list, 1);
360
adl->len = length + 2; /* Length of each element */
361
adl->num = num; /* Number of primary or secondary services */
362
adl->data = g_malloc(num * sizeof(uint8_t *));
364
for (i = 0, l = info; l; i++, l = l->next) {
368
adl->data[i] = g_malloc(adl->len);
370
value = (void *) adl->data[i];
372
att_put_u16(a->handle, value);
374
/* Attribute Value */
375
memcpy(&value[2], &a->uuid.value, length);
378
length = enc_find_info_resp(format, adl, pdu, len);
380
att_data_list_free(adl);
386
static int find_by_type(uint16_t start, uint16_t end, uuid_t *uuid,
387
const uint8_t *value, int vlen, uint8_t *opdu, int mtu)
390
struct att_range *range;
394
if (start > end || start == 0x0000)
395
return enc_error_resp(ATT_OP_FIND_BY_TYPE_REQ, start,
396
ATT_ECODE_INVALID_HANDLE, opdu, mtu);
398
/* Searching first requested handle number */
399
for (l = database, matches = NULL, range = NULL; l; l = l->next) {
402
if (a->handle < start)
408
/* Primary service? Attribute value matches? */
409
if ((sdp_uuid_cmp(&a->uuid, uuid) == 0) && (a->len == vlen) &&
410
(memcmp(a->data, value, vlen) == 0)) {
412
range = g_new0(struct att_range, 1);
413
range->start = a->handle;
415
matches = g_slist_append(matches, range);
418
* Update the last found handle or reset the pointer
419
* to track that a new group started: Primary or
422
if (sdp_uuid_cmp(&a->uuid, &prim_uuid) == 0 ||
423
sdp_uuid_cmp(&a->uuid, &snd_uuid) == 0)
426
range->end = a->handle;
432
/* Avoids another iteration */
434
} else if (range->end == 0) {
436
* Broken requests: requested End Handle is not 0xFFFF.
437
* Given handle is in the middle of a service definition.
439
matches = g_slist_remove(matches, range);
445
return enc_error_resp(ATT_OP_FIND_BY_TYPE_REQ, start,
446
ATT_ECODE_ATTR_NOT_FOUND, opdu, mtu);
448
len = enc_find_by_type_resp(matches, opdu, mtu);
450
g_slist_foreach(matches, (GFunc) g_free, NULL);
451
g_slist_free(matches);
456
static int handle_cmp(gconstpointer a, gconstpointer b)
458
const struct attribute *attrib = a;
459
uint16_t handle = GPOINTER_TO_UINT(b);
461
return attrib->handle - handle;
464
static int attribute_cmp(gconstpointer a1, gconstpointer a2)
466
const struct attribute *attrib1 = a1;
467
const struct attribute *attrib2 = a2;
469
return attrib1->handle - attrib2->handle;
472
static uint16_t read_value(uint16_t handle, uint8_t *pdu, int len)
478
l = g_slist_find_custom(database, GUINT_TO_POINTER(h), handle_cmp);
480
return enc_error_resp(ATT_OP_READ_REQ, handle,
481
ATT_ECODE_INVALID_HANDLE, pdu, len);
485
return enc_read_resp(a->data, a->len, pdu, len);
488
static void write_value(uint16_t handle, const uint8_t *value, int vlen)
495
l = g_slist_find_custom(database, GUINT_TO_POINTER(h), handle_cmp);
500
memcpy(&uuid, &a->uuid, sizeof(uuid_t));
501
attrib_db_update(handle, &uuid, value, vlen);
504
static uint16_t mtu_exchange(struct gatt_channel *channel, uint16_t mtu,
505
uint8_t *pdu, int len)
507
channel->mtu = MIN(mtu, ATT_MAX_MTU);
509
return enc_mtu_resp(channel->mtu, pdu, len);
512
static void channel_disconnect(void *user_data)
514
struct gatt_channel *channel = user_data;
516
g_attrib_unref(channel->attrib);
517
clients = g_slist_remove(clients, channel);
522
static void channel_handler(const uint8_t *ipdu, uint16_t len,
525
struct gatt_channel *channel = user_data;
526
uint8_t opdu[ATT_MAX_MTU], value[ATT_MAX_MTU];
527
uint16_t length, start, end, mtu;
533
case ATT_OP_READ_BY_GROUP_REQ:
534
length = dec_read_by_grp_req(ipdu, len, &start, &end, &uuid);
536
status = ATT_ECODE_INVALID_PDU;
540
length = read_by_group(start, end, &uuid, opdu, channel->mtu);
542
case ATT_OP_READ_BY_TYPE_REQ:
543
length = dec_read_by_type_req(ipdu, len, &start, &end, &uuid);
545
status = ATT_ECODE_INVALID_PDU;
549
length = read_by_type(start, end, &uuid, opdu, channel->mtu);
551
case ATT_OP_READ_REQ:
552
length = dec_read_req(ipdu, len, &start);
554
status = ATT_ECODE_INVALID_PDU;
558
length = read_value(start, opdu, channel->mtu);
561
length = dec_mtu_req(ipdu, len, &mtu);
563
status = ATT_ECODE_INVALID_PDU;
567
length = mtu_exchange(channel, mtu, opdu, channel->mtu);
569
case ATT_OP_FIND_INFO_REQ:
570
length = dec_find_info_req(ipdu, len, &start, &end);
572
status = ATT_ECODE_INVALID_PDU;
576
length = find_info(start, end, opdu, channel->mtu);
578
case ATT_OP_WRITE_REQ:
579
length = dec_write_req(ipdu, len, &start, value, &vlen);
581
status = ATT_ECODE_INVALID_PDU;
585
write_value(start, value, vlen);
586
opdu[0] = ATT_OP_WRITE_RESP;
587
length = sizeof(opdu[0]);
589
case ATT_OP_WRITE_CMD:
590
length = dec_write_cmd(ipdu, len, &start, value, &vlen);
592
write_value(start, value, vlen);
594
case ATT_OP_FIND_BY_TYPE_REQ:
595
length = dec_find_by_type_req(ipdu, len, &start, &end,
596
&uuid, value, &vlen);
598
status = ATT_ECODE_INVALID_PDU;
602
length = find_by_type(start, end, &uuid, value, vlen,
605
case ATT_OP_READ_BLOB_REQ:
606
case ATT_OP_READ_MULTI_REQ:
607
case ATT_OP_PREP_WRITE_REQ:
608
case ATT_OP_EXEC_WRITE_REQ:
610
status = ATT_ECODE_REQ_NOT_SUPP;
615
status = ATT_ECODE_IO;
619
length = enc_error_resp(ipdu[0], 0x0000, status, opdu, channel->mtu);
621
g_attrib_send(channel->attrib, opdu[0], opdu, length,
625
static void connect_event(GIOChannel *io, GError *err, void *user_data)
627
struct gatt_channel *channel;
631
error("%s", err->message);
635
channel = g_new0(struct gatt_channel, 1);
637
bt_io_get(io, BT_IO_L2CAP, &gerr,
638
BT_IO_OPT_SOURCE_BDADDR, &channel->src,
639
BT_IO_OPT_DEST_BDADDR, &channel->dst,
642
error("bt_io_get: %s", gerr->message);
645
g_io_channel_shutdown(io, TRUE, NULL);
649
channel->attrib = g_attrib_new(io);
650
channel->mtu = ATT_DEFAULT_MTU;
652
channel->id = g_attrib_register(channel->attrib, GATTRIB_ALL_EVENTS,
653
channel_handler, channel, NULL);
655
g_attrib_set_disconnect_function(channel->attrib, channel_disconnect,
658
clients = g_slist_append(clients, channel);
661
static void confirm_event(GIOChannel *io, void *user_data)
665
if (bt_io_accept(io, connect_event, NULL, NULL, &gerr) == FALSE) {
666
error("bt_io_accept: %s", gerr->message);
668
g_io_channel_unref(io);
674
int attrib_server_init(void)
677
sdp_record_t *record;
680
l2cap_io = bt_io_listen(BT_IO_L2CAP, NULL, confirm_event,
682
BT_IO_OPT_SOURCE_BDADDR, BDADDR_ANY,
683
BT_IO_OPT_PSM, GATT_PSM,
684
BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
687
if (l2cap_io == NULL) {
688
error("%s", gerr->message);
693
record = server_record_new();
694
if (record == NULL) {
695
error("Unable to create GATT service record");
699
if (add_record_to_server(BDADDR_ANY, record) < 0) {
700
error("Failed to register GATT service record");
701
sdp_record_free(record);
705
sdp_handle = record->handle;
711
le_io = bt_io_listen(BT_IO_L2CAP, NULL, confirm_event,
713
BT_IO_OPT_SOURCE_BDADDR, BDADDR_ANY,
714
BT_IO_OPT_CID, GATT_CID,
715
BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
719
error("%s", gerr->message);
721
/* Doesn't have LE support, continue */
727
g_io_channel_unref(l2cap_io);
733
void attrib_server_exit(void)
737
g_slist_foreach(database, (GFunc) g_free, NULL);
738
g_slist_free(database);
741
g_io_channel_unref(l2cap_io);
742
g_io_channel_shutdown(l2cap_io, FALSE, NULL);
746
g_io_channel_unref(le_io);
747
g_io_channel_shutdown(le_io, FALSE, NULL);
750
for (l = clients; l; l = l->next) {
751
struct gatt_channel *channel = l->data;
753
g_attrib_unref(channel->attrib);
757
g_slist_free(clients);
760
remove_record_from_server(sdp_handle);
763
int attrib_db_add(uint16_t handle, uuid_t *uuid, const uint8_t *value, int len)
767
/* FIXME: handle conflicts */
769
a = g_malloc0(sizeof(struct attribute) + len);
771
memcpy(&a->uuid, uuid, sizeof(uuid_t));
773
memcpy(a->data, value, len);
775
database = g_slist_insert_sorted(database, a, attribute_cmp);
780
int attrib_db_update(uint16_t handle, uuid_t *uuid, const uint8_t *value,
787
l = g_slist_find_custom(database, GUINT_TO_POINTER(h), handle_cmp);
791
a = g_try_realloc(l->data, sizeof(struct attribute) + len);
797
memcpy(&a->uuid, uuid, sizeof(uuid_t));
799
memcpy(a->data, value, len);
802
* <<Client/Server Characteristic Configuration>> descriptors are
803
* not supported yet. If a given attribute changes, the attribute
804
* server shall report the new values using the mechanism selected
805
* by the client. Notification/Indication shall not be automatically
806
* sent if the client didn't request them.
812
int attrib_db_del(uint16_t handle)
818
l = g_slist_find_custom(database, GUINT_TO_POINTER(h), handle_cmp);
823
database = g_slist_remove(database, a);