77
82
static uint16_t name_handle = 0x0000;
78
83
static uint16_t appearance_handle = 0x0000;
80
static uuid_t prim_uuid = {
82
.value.uuid16 = GATT_PRIM_SVC_UUID
85
static bt_uuid_t prim_uuid = {
87
.value.u16 = GATT_PRIM_SVC_UUID
84
static uuid_t snd_uuid = {
86
.value.uuid16 = GATT_SND_SVC_UUID
89
static bt_uuid_t snd_uuid = {
91
.value.u16 = GATT_SND_SVC_UUID
89
94
static sdp_record_t *server_record_new(uuid_t *uuid, uint16_t start, uint16_t end)
91
96
sdp_list_t *svclass_id, *apseq, *proto[2], *root, *aproto;
92
uuid_t root_uuid, proto_uuid, gatt_uuid, l2cap;
97
uuid_t root_uuid, proto_uuid, l2cap;
93
98
sdp_record_t *record;
94
99
sdp_data_t *psm, *sh, *eh;
95
100
uint16_t lp = GATT_PSM;
196
static uint8_t client_set_notifications(struct attribute *attr,
199
struct gatt_channel *channel = user_data;
200
struct attribute *last_chr_val = NULL;
206
cfg_val = att_get_u16(attr->data);
208
bt_uuid16_create(&uuid, GATT_CHARAC_UUID);
209
for (l = database, props = 0; l != NULL; l = l->next) {
210
struct attribute *a = l->data;
211
static uint16_t handle = 0;
213
if (a->handle >= attr->handle)
216
if (bt_uuid_cmp(&a->uuid, &uuid) == 0) {
217
props = att_get_u8(&a->data[0]);
218
handle = att_get_u16(&a->data[1]);
222
if (handle && a->handle == handle)
226
if (last_chr_val == NULL)
229
if ((cfg_val & 0x0001) && !(props & ATT_CHAR_PROPER_NOTIFY))
230
return ATT_ECODE_WRITE_NOT_PERM;
232
if ((cfg_val & 0x0002) && !(props & ATT_CHAR_PROPER_INDICATE))
233
return ATT_ECODE_WRITE_NOT_PERM;
235
if (cfg_val & 0x0001)
236
channel->notify = g_slist_append(channel->notify, last_chr_val);
238
channel->notify = g_slist_remove(channel->notify, last_chr_val);
240
if (cfg_val & 0x0002)
241
channel->indicate = g_slist_append(channel->indicate,
244
channel->indicate = g_slist_remove(channel->indicate,
250
static struct attribute *client_cfg_attribute(struct gatt_channel *channel,
251
struct attribute *orig_attr,
252
const uint8_t *value, int vlen)
254
guint handle = orig_attr->handle;
258
bt_uuid16_create(&uuid, GATT_CLIENT_CHARAC_CFG_UUID);
259
if (bt_uuid_cmp(&orig_attr->uuid, &uuid) != 0)
262
/* Value is unchanged, not need to create a private copy yet */
263
if (vlen == orig_attr->len && memcmp(orig_attr->data, value, vlen) == 0)
266
l = g_slist_find_custom(channel->configs, GUINT_TO_POINTER(handle),
271
/* Create a private copy of the Client Characteristic
272
* Configuration attribute */
273
a = g_malloc0(sizeof(*a) + vlen);
274
memcpy(a, orig_attr, sizeof(*a));
275
memcpy(a->data, value, vlen);
276
a->write_cb = client_set_notifications;
277
a->cb_user_data = channel;
279
channel->configs = g_slist_insert_sorted(channel->configs, a,
177
288
static uint16_t read_by_group(struct gatt_channel *channel, uint16_t start,
178
uint16_t end, uuid_t *uuid,
289
uint16_t end, bt_uuid_t *uuid,
179
290
uint8_t *pdu, int len)
181
292
struct att_data_list *adl;
406
529
return enc_error_resp(ATT_OP_FIND_INFO_REQ, start,
407
530
ATT_ECODE_ATTR_NOT_FOUND, pdu, len);
409
if (last_type == SDP_UUID16) {
532
if (last_type == BT_UUID16) {
412
} else if (last_type == SDP_UUID128) {
535
} else if (last_type == BT_UUID128) {
417
adl = g_new0(struct att_data_list, 1);
418
adl->len = length + 2; /* Length of each element */
419
adl->num = num; /* Number of primary or secondary services */
420
adl->data = g_malloc(num * sizeof(uint8_t *));
540
adl = att_data_list_alloc(num, length + 2);
422
542
for (i = 0, l = info; l; i++, l = l->next) {
426
adl->data[i] = g_malloc(adl->len);
428
547
value = (void *) adl->data[i];
430
549
att_put_u16(a->handle, value);
432
551
/* Attribute Value */
433
memcpy(&value[2], &a->uuid.value, length);
552
att_put_uuid(a->uuid, &value[2]);
436
555
length = enc_find_info_resp(format, adl, pdu, len);
466
585
/* Primary service? Attribute value matches? */
467
if ((sdp_uuid_cmp(&a->uuid, uuid) == 0) && (a->len == vlen) &&
586
if ((bt_uuid_cmp(&a->uuid, uuid) == 0) && (a->len == vlen) &&
468
587
(memcmp(a->data, value, vlen) == 0)) {
470
589
range = g_new0(struct att_range, 1);
471
590
range->start = a->handle;
591
/* It is allowed to have end group handle the same as
592
* start handle, for groups with only one attribute. */
593
range->end = a->handle;
473
595
matches = g_slist_append(matches, range);
474
596
} else if (range) {
475
597
/* Update the last found handle or reset the pointer
476
598
* to track that a new group started: Primary or
477
599
* Secondary service. */
478
if (sdp_uuid_cmp(&a->uuid, &prim_uuid) == 0 ||
479
sdp_uuid_cmp(&a->uuid, &snd_uuid) == 0)
600
if (bt_uuid_cmp(&a->uuid, &prim_uuid) == 0 ||
601
bt_uuid_cmp(&a->uuid, &snd_uuid) == 0)
482
604
range->end = a->handle;
488
/* Avoids another iteration */
490
} else if (range->end == 0) {
491
/* Broken requests: requested End Handle is not
492
* 0xFFFF. Given handle is in the middle of a
493
* service definition. */
494
matches = g_slist_remove(matches, range);
499
608
if (matches == NULL)
500
609
return enc_error_resp(ATT_OP_FIND_BY_TYPE_REQ, start,
501
610
ATT_ECODE_ATTR_NOT_FOUND, opdu, mtu);
630
737
return enc_error_resp(ATT_OP_WRITE_REQ, handle, status, pdu,
633
memcpy(&uuid, &a->uuid, sizeof(uuid_t));
634
attrib_db_update(handle, &uuid, value, vlen);
740
client_attr = client_cfg_attribute(channel, a, value, vlen);
744
attrib_db_update(a->handle, &a->uuid, value, vlen);
747
status = a->write_cb(a, a->cb_user_data);
749
return enc_error_resp(ATT_OP_WRITE_REQ, handle, status,
753
DBG("Notifications: %d, indications: %d",
754
g_slist_length(channel->notify),
755
g_slist_length(channel->indicate));
636
757
return enc_write_resp(pdu, len);
639
760
static uint16_t mtu_exchange(struct gatt_channel *channel, uint16_t mtu,
640
761
uint8_t *pdu, int len)
642
channel->mtu = MIN(mtu, channel->mtu);
644
return enc_mtu_resp(channel->mtu, pdu, len);
763
guint old_mtu = channel->mtu;
765
if (mtu < ATT_DEFAULT_LE_MTU)
766
channel->mtu = ATT_DEFAULT_LE_MTU;
768
channel->mtu = MIN(mtu, channel->mtu);
770
bt_io_set(le_io, BT_IO_L2CAP, NULL,
771
BT_IO_OPT_OMTU, channel->mtu,
774
return enc_mtu_resp(old_mtu, pdu, len);
647
777
static void channel_disconnect(void *user_data)
976
static void attrib_notify_clients(struct attribute *attr)
978
guint handle = attr->handle;
981
for (l = clients; l; l = l->next) {
982
struct gatt_channel *channel = l->data;
985
if (g_slist_find_custom(channel->notify,
986
GUINT_TO_POINTER(handle), handle_cmp)) {
987
uint8_t pdu[ATT_MAX_MTU];
990
len = enc_notification(attr, pdu, channel->mtu);
994
g_attrib_send(channel->attrib, 0, pdu[0], pdu, len,
999
if (g_slist_find_custom(channel->indicate,
1000
GUINT_TO_POINTER(handle), handle_cmp)) {
1001
uint8_t pdu[ATT_MAX_MTU];
1004
len = enc_indication(attr, pdu, channel->mtu);
1008
g_attrib_send(channel->attrib, 0, pdu[0], pdu, len,
829
1014
static gboolean register_core_services(void)
831
1016
uint8_t atval[256];
833
1018
uint16_t appearance = 0x0000;
835
1020
/* GAP service: primary service definition */
836
sdp_uuid16_create(&uuid, GATT_PRIM_SVC_UUID);
1021
bt_uuid16_create(&uuid, GATT_PRIM_SVC_UUID);
837
1022
att_put_u16(GENERIC_ACCESS_PROFILE_ID, &atval[0]);
838
1023
attrib_db_add(0x0001, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 2);
840
1025
/* GAP service: device name characteristic */
841
1026
name_handle = 0x0006;
842
sdp_uuid16_create(&uuid, GATT_CHARAC_UUID);
1027
bt_uuid16_create(&uuid, GATT_CHARAC_UUID);
843
1028
atval[0] = ATT_CHAR_PROPER_READ;
844
1029
att_put_u16(name_handle, &atval[1]);
845
1030
att_put_u16(GATT_CHARAC_DEVICE_NAME, &atval[3]);
846
1031
attrib_db_add(0x0004, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 5);
848
1033
/* GAP service: device name attribute */
849
sdp_uuid16_create(&uuid, GATT_CHARAC_DEVICE_NAME);
1034
bt_uuid16_create(&uuid, GATT_CHARAC_DEVICE_NAME);
850
1035
attrib_db_add(name_handle, &uuid, ATT_NONE, ATT_NOT_PERMITTED,
853
1038
/* GAP service: device appearance characteristic */
854
1039
appearance_handle = 0x0008;
855
sdp_uuid16_create(&uuid, GATT_CHARAC_UUID);
1040
bt_uuid16_create(&uuid, GATT_CHARAC_UUID);
856
1041
atval[0] = ATT_CHAR_PROPER_READ;
857
1042
att_put_u16(appearance_handle, &atval[1]);
858
1043
att_put_u16(GATT_CHARAC_APPEARANCE, &atval[3]);
859
1044
attrib_db_add(0x0007, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 5);
861
1046
/* GAP service: device appearance attribute */
862
sdp_uuid16_create(&uuid, GATT_CHARAC_APPEARANCE);
1047
bt_uuid16_create(&uuid, GATT_CHARAC_APPEARANCE);
863
1048
att_put_u16(appearance, &atval[0]);
864
1049
attrib_db_add(appearance_handle, &uuid, ATT_NONE, ATT_NOT_PERMITTED,
866
1051
gap_sdp_handle = attrib_create_sdp(0x0001, "Generic Access Profile");
868
1052
if (gap_sdp_handle == 0) {
869
1053
error("Failed to register GAP service record");
873
1057
/* GATT service: primary service definition */
874
sdp_uuid16_create(&uuid, GATT_PRIM_SVC_UUID);
1058
bt_uuid16_create(&uuid, GATT_PRIM_SVC_UUID);
875
1059
att_put_u16(GENERIC_ATTRIB_PROFILE_ID, &atval[0]);
876
1060
attrib_db_add(0x0010, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 2);