1 /* gatt.c - Bluetooth GATT Server Tester */
2
3 /*
4 * Copyright (c) 2015-2016 Intel Corporation
5 *
6 * SPDX-License-Identifier: Apache-2.0
7 */
8
9 #include <zephyr/types.h>
10 #include <string.h>
11 #include <errno.h>
12 #include <stdlib.h>
13
14 #include <zephyr/toolchain.h>
15 #include <zephyr/bluetooth/att.h>
16 #include <zephyr/bluetooth/bluetooth.h>
17 #include <zephyr/bluetooth/conn.h>
18 #include <zephyr/bluetooth/gatt.h>
19 #include <zephyr/bluetooth/uuid.h>
20 #include <zephyr/bluetooth/l2cap.h>
21 #include <zephyr/sys/byteorder.h>
22 #include <zephyr/sys/printk.h>
23 #include <zephyr/sys/__assert.h>
24 #include <zephyr/net_buf.h>
25
26 #include <zephyr/logging/log.h>
27 #define LOG_MODULE_NAME bttester_gatt
28 LOG_MODULE_REGISTER(LOG_MODULE_NAME, CONFIG_BTTESTER_LOG_LEVEL);
29
30 #include "btp/btp.h"
31
32 #define MAX_BUFFER_SIZE 2048
33 #define MAX_UUID_LEN 16
34
35 #define MAX_SUBSCRIPTIONS 2
36
37 #define UNUSED_SUBSCRIBE_CCC_HANDLE 0x0000
38
39 /* This masks Permission bits from GATT API */
40 #define GATT_PERM_MASK (BT_GATT_PERM_READ | \
41 BT_GATT_PERM_READ_AUTHEN | \
42 BT_GATT_PERM_READ_ENCRYPT | \
43 BT_GATT_PERM_WRITE | \
44 BT_GATT_PERM_WRITE_AUTHEN | \
45 BT_GATT_PERM_WRITE_ENCRYPT | \
46 BT_GATT_PERM_PREPARE_WRITE)
47 #define GATT_PERM_ENC_READ_MASK (BT_GATT_PERM_READ_ENCRYPT | \
48 BT_GATT_PERM_READ_AUTHEN)
49 #define GATT_PERM_ENC_WRITE_MASK (BT_GATT_PERM_WRITE_ENCRYPT | \
50 BT_GATT_PERM_WRITE_AUTHEN)
51 #define GATT_PERM_READ_AUTHORIZATION 0x40
52 #define GATT_PERM_WRITE_AUTHORIZATION 0x80
53
54 /* GATT server context */
55 #define SERVER_MAX_SERVICES 10
56 #define SERVER_MAX_ATTRIBUTES 50
57 #define SERVER_BUF_SIZE 2048
58 #define MAX_CCC_COUNT 2
59
60 /* bt_gatt_attr_next cannot be used on non-registered services */
61 #define NEXT_DB_ATTR(attr) (attr + 1)
62 #define LAST_DB_ATTR (server_db + (attr_count - 1))
63
64 #define server_buf_push(_len) net_buf_push(server_buf, ROUND_UP(_len, 4))
65 #define server_buf_pull(_len) net_buf_pull(server_buf, ROUND_UP(_len, 4))
66
67 static struct bt_gatt_service server_svcs[SERVER_MAX_SERVICES];
68 static struct bt_gatt_attr server_db[SERVER_MAX_ATTRIBUTES];
69 static struct net_buf *server_buf;
70 NET_BUF_POOL_DEFINE(server_pool, 1, SERVER_BUF_SIZE, 0, NULL);
71
72 static uint8_t attr_count;
73 static uint8_t svc_attr_count;
74 static uint8_t svc_count;
75 static bool ccc_added;
76
77 /*
78 * gatt_buf - cache used by a gatt client (to cache data read/discovered)
79 * and gatt server (to store attribute user_data).
80 * It is not intended to be used by client and server at the same time.
81 */
82 static struct {
83 uint16_t len;
84 uint8_t buf[MAX_BUFFER_SIZE];
85 } gatt_buf;
86
87 struct get_attr_data {
88 struct net_buf_simple *buf;
89 struct bt_conn *conn;
90 };
91
92 struct ccc_value {
93 struct bt_gatt_attr *attr;
94 struct bt_gatt_attr *ccc;
95 uint8_t value;
96 };
97
98 static struct ccc_value ccc_values[MAX_CCC_COUNT];
99
ccc_find_by_attr(uint16_t handle)100 static int ccc_find_by_attr(uint16_t handle)
101 {
102 for (int i = 0; i < MAX_CCC_COUNT; i++) {
103 if ((ccc_values[i].attr != NULL) && (handle == ccc_values[i].attr->handle)) {
104 return i;
105 }
106 }
107
108 return -ENOENT;
109 }
110
ccc_find_by_ccc(const struct bt_gatt_attr * attr)111 static int ccc_find_by_ccc(const struct bt_gatt_attr *attr)
112 {
113 for (int i = 0; i < MAX_CCC_COUNT; i++) {
114 if (attr == ccc_values[i].ccc) {
115 return i;
116 }
117 }
118
119 return -ENOENT;
120 }
121
gatt_buf_add(const void * data,size_t len)122 static void *gatt_buf_add(const void *data, size_t len)
123 {
124 void *ptr = gatt_buf.buf + gatt_buf.len;
125
126 if ((len + gatt_buf.len) > MAX_BUFFER_SIZE) {
127 return NULL;
128 }
129
130 if (data) {
131 memcpy(ptr, data, len);
132 } else {
133 (void)memset(ptr, 0, len);
134 }
135
136 gatt_buf.len += len;
137
138 LOG_DBG("%d/%d used", gatt_buf.len, MAX_BUFFER_SIZE);
139
140 return ptr;
141 }
142
gatt_buf_reserve(size_t len)143 static void *gatt_buf_reserve(size_t len)
144 {
145 return gatt_buf_add(NULL, len);
146 }
147
gatt_buf_clear(void)148 static void gatt_buf_clear(void)
149 {
150 (void)memset(&gatt_buf, 0, sizeof(gatt_buf));
151 }
152
153 union uuid {
154 struct bt_uuid uuid;
155 struct bt_uuid_16 u16;
156 struct bt_uuid_128 u128;
157 };
158
gatt_db_add(const struct bt_gatt_attr * pattern,size_t user_data_len)159 static struct bt_gatt_attr *gatt_db_add(const struct bt_gatt_attr *pattern,
160 size_t user_data_len)
161 {
162 static struct bt_gatt_attr *attr = server_db;
163 const union uuid *u = CONTAINER_OF(pattern->uuid, union uuid, uuid);
164 size_t uuid_size = u->uuid.type == BT_UUID_TYPE_16 ? sizeof(u->u16) :
165 sizeof(u->u128);
166
167 /* Return NULL if database is full */
168 if (attr == &server_db[SERVER_MAX_ATTRIBUTES - 1]) {
169 return NULL;
170 }
171
172 /* First attribute in db must be service */
173 if (!svc_count) {
174 return NULL;
175 }
176
177 memcpy(attr, pattern, sizeof(*attr));
178
179 /* Store the UUID. */
180 attr->uuid = server_buf_push(uuid_size);
181 memcpy((void *) attr->uuid, &u->uuid, uuid_size);
182
183 /* Copy user_data to the buffer. */
184 if (user_data_len) {
185 attr->user_data = server_buf_push(user_data_len);
186 memcpy(attr->user_data, pattern->user_data, user_data_len);
187 }
188
189 LOG_DBG("handle 0x%04x", attr->handle);
190
191 attr_count++;
192 svc_attr_count++;
193
194 return attr++;
195 }
196
197 /* Convert UUID from BTP command to bt_uuid */
btp2bt_uuid(const uint8_t * uuid,uint8_t len,struct bt_uuid * bt_uuid)198 static uint8_t btp2bt_uuid(const uint8_t *uuid, uint8_t len,
199 struct bt_uuid *bt_uuid)
200 {
201 uint16_t le16;
202
203 switch (len) {
204 case 0x02: /* UUID 16 */
205 bt_uuid->type = BT_UUID_TYPE_16;
206 memcpy(&le16, uuid, sizeof(le16));
207 BT_UUID_16(bt_uuid)->val = sys_le16_to_cpu(le16);
208 break;
209 case 0x10: /* UUID 128*/
210 bt_uuid->type = BT_UUID_TYPE_128;
211 memcpy(BT_UUID_128(bt_uuid)->val, uuid, 16);
212 break;
213 default:
214 return BTP_STATUS_FAILED;
215 }
216
217 return BTP_STATUS_SUCCESS;
218 }
219
supported_commands(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)220 static uint8_t supported_commands(const void *cmd, uint16_t cmd_len,
221 void *rsp, uint16_t *rsp_len)
222 {
223 struct btp_gatt_read_supported_commands_rp *rp = rsp;
224
225 /* octet 0 */
226 tester_set_bit(rp->data, BTP_GATT_READ_SUPPORTED_COMMANDS);
227 tester_set_bit(rp->data, BTP_GATT_ADD_SERVICE);
228 tester_set_bit(rp->data, BTP_GATT_ADD_CHARACTERISTIC);
229 tester_set_bit(rp->data, BTP_GATT_ADD_DESCRIPTOR);
230 tester_set_bit(rp->data, BTP_GATT_ADD_INCLUDED_SERVICE);
231 tester_set_bit(rp->data, BTP_GATT_SET_VALUE);
232 tester_set_bit(rp->data, BTP_GATT_START_SERVER);
233
234 /* octet 1 */
235 tester_set_bit(rp->data, BTP_GATT_SET_ENC_KEY_SIZE);
236 tester_set_bit(rp->data, BTP_GATT_EXCHANGE_MTU);
237 tester_set_bit(rp->data, BTP_GATT_DISC_ALL_PRIM);
238 tester_set_bit(rp->data, BTP_GATT_DISC_PRIM_UUID);
239 tester_set_bit(rp->data, BTP_GATT_FIND_INCLUDED);
240 tester_set_bit(rp->data, BTP_GATT_DISC_ALL_CHRC);
241 tester_set_bit(rp->data, BTP_GATT_DISC_CHRC_UUID);
242
243 /* octet 2 */
244 tester_set_bit(rp->data, BTP_GATT_DISC_ALL_DESC);
245 tester_set_bit(rp->data, BTP_GATT_READ);
246 tester_set_bit(rp->data, BTP_GATT_READ_LONG);
247 tester_set_bit(rp->data, BTP_GATT_READ_MULTIPLE);
248 tester_set_bit(rp->data, BTP_GATT_WRITE_WITHOUT_RSP);
249 tester_set_bit(rp->data, BTP_GATT_SIGNED_WRITE_WITHOUT_RSP);
250 tester_set_bit(rp->data, BTP_GATT_WRITE);
251
252 /* octet 3 */
253 tester_set_bit(rp->data, BTP_GATT_WRITE_LONG);
254 tester_set_bit(rp->data, BTP_GATT_CFG_NOTIFY);
255 tester_set_bit(rp->data, BTP_GATT_CFG_INDICATE);
256 tester_set_bit(rp->data, BTP_GATT_GET_ATTRIBUTES);
257 tester_set_bit(rp->data, BTP_GATT_GET_ATTRIBUTE_VALUE);
258 tester_set_bit(rp->data, BTP_GATT_CHANGE_DB);
259 tester_set_bit(rp->data, BTP_GATT_EATT_CONNECT);
260
261 /* octet 4 */
262 tester_set_bit(rp->data, BTP_GATT_READ_MULTIPLE_VAR);
263 tester_set_bit(rp->data, BTP_GATT_NOTIFY_MULTIPLE);
264
265
266 *rsp_len = sizeof(*rp) + 5;
267
268 return BTP_STATUS_SUCCESS;
269 }
270
register_service(void)271 static int register_service(void)
272 {
273 int err;
274
275 server_svcs[svc_count].attrs = server_db +
276 (attr_count - svc_attr_count);
277 server_svcs[svc_count].attr_count = svc_attr_count;
278
279 err = bt_gatt_service_register(&server_svcs[svc_count]);
280 if (!err) {
281 /* Service registered, reset the counter */
282 svc_attr_count = 0U;
283 }
284
285 return err;
286 }
287
add_service(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)288 static uint8_t add_service(const void *cmd, uint16_t cmd_len,
289 void *rsp, uint16_t *rsp_len)
290 {
291 const struct btp_gatt_add_service_cmd *cp = cmd;
292 struct btp_gatt_add_service_rp *rp = rsp;
293 struct bt_gatt_attr *attr_svc = NULL;
294 union uuid uuid;
295 size_t uuid_size;
296
297 if ((cmd_len < sizeof(*cp)) ||
298 (cmd_len != sizeof(*cp) + cp->uuid_length)) {
299 return BTP_STATUS_FAILED;
300 }
301
302 if (btp2bt_uuid(cp->uuid, cp->uuid_length, &uuid.uuid)) {
303 return BTP_STATUS_FAILED;
304 }
305
306 uuid_size = uuid.uuid.type == BT_UUID_TYPE_16 ? sizeof(uuid.u16) :
307 sizeof(uuid.u128);
308
309 /* Register last defined service */
310 if (svc_attr_count) {
311 if (register_service()) {
312 return BTP_STATUS_FAILED;
313 }
314 }
315
316 svc_count++;
317
318 switch (cp->type) {
319 case BTP_GATT_SERVICE_PRIMARY:
320 attr_svc = gatt_db_add(&(struct bt_gatt_attr)
321 BT_GATT_PRIMARY_SERVICE(&uuid.uuid),
322 uuid_size);
323 break;
324 case BTP_GATT_SERVICE_SECONDARY:
325 attr_svc = gatt_db_add(&(struct bt_gatt_attr)
326 BT_GATT_SECONDARY_SERVICE(&uuid.uuid),
327 uuid_size);
328 break;
329 }
330
331 if (!attr_svc) {
332 svc_count--;
333 return BTP_STATUS_FAILED;
334 }
335
336 rp->svc_id = sys_cpu_to_le16(attr_svc->handle);
337 *rsp_len = sizeof(*rp);
338
339 return BTP_STATUS_SUCCESS;
340 }
341
342 struct gatt_value {
343 uint16_t len;
344 uint8_t *data;
345 uint8_t enc_key_size;
346 uint8_t flags[1];
347 };
348
349 enum {
350 GATT_VALUE_CCC_FLAG,
351 GATT_VALUE_READ_AUTHOR_FLAG,
352 GATT_VALUE_WRITE_AUTHOR_FLAG,
353 };
354
read_value(struct bt_conn * conn,const struct bt_gatt_attr * attr,void * buf,uint16_t len,uint16_t offset)355 static ssize_t read_value(struct bt_conn *conn, const struct bt_gatt_attr *attr,
356 void *buf, uint16_t len, uint16_t offset)
357 {
358 const struct gatt_value *value = attr->user_data;
359
360 if (tester_test_bit(value->flags, GATT_VALUE_READ_AUTHOR_FLAG)) {
361 return BT_GATT_ERR(BT_ATT_ERR_AUTHORIZATION);
362 }
363
364 if ((attr->perm & GATT_PERM_ENC_READ_MASK) && (conn != NULL) &&
365 (value->enc_key_size > bt_conn_enc_key_size(conn))) {
366 return BT_GATT_ERR(BT_ATT_ERR_ENCRYPTION_KEY_SIZE);
367 }
368
369 return bt_gatt_attr_read(conn, attr, buf, len, offset, value->data,
370 value->len);
371 }
372
attr_value_changed_ev(uint16_t handle,const uint8_t * value,uint16_t len)373 static void attr_value_changed_ev(uint16_t handle, const uint8_t *value, uint16_t len)
374 {
375 uint8_t buf[len + sizeof(struct btp_gatt_attr_value_changed_ev)];
376 struct btp_gatt_attr_value_changed_ev *ev = (void *) buf;
377
378 ev->handle = sys_cpu_to_le16(handle);
379 ev->data_length = sys_cpu_to_le16(len);
380 memcpy(ev->data, value, len);
381
382 tester_event(BTP_SERVICE_ID_GATT, BTP_GATT_EV_ATTR_VALUE_CHANGED,
383 buf, sizeof(buf));
384 }
385
write_value(struct bt_conn * conn,const struct bt_gatt_attr * attr,const void * buf,uint16_t len,uint16_t offset,uint8_t flags)386 static ssize_t write_value(struct bt_conn *conn,
387 const struct bt_gatt_attr *attr, const void *buf,
388 uint16_t len, uint16_t offset, uint8_t flags)
389 {
390 struct gatt_value *value = attr->user_data;
391
392 if (tester_test_bit(value->flags, GATT_VALUE_WRITE_AUTHOR_FLAG)) {
393 return BT_GATT_ERR(BT_ATT_ERR_AUTHORIZATION);
394 }
395
396 if ((attr->perm & GATT_PERM_ENC_WRITE_MASK) &&
397 (value->enc_key_size > bt_conn_enc_key_size(conn))) {
398 return BT_GATT_ERR(BT_ATT_ERR_ENCRYPTION_KEY_SIZE);
399 }
400
401 /* Don't write anything if prepare flag is set */
402 if (flags & BT_GATT_WRITE_FLAG_PREPARE) {
403 return 0;
404 }
405
406 if (offset > value->len) {
407 return BT_GATT_ERR(BT_ATT_ERR_INVALID_OFFSET);
408 }
409
410 if (offset + len > value->len) {
411 return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
412 }
413
414 memcpy(value->data + offset, buf, len);
415 value->len = len;
416
417 /* Maximum attribute value size is 512 bytes */
418 __ASSERT_NO_MSG(value->len <= 512);
419
420 attr_value_changed_ev(attr->handle, value->data, value->len);
421
422 return len;
423 }
424
425 struct add_characteristic {
426 uint16_t char_id;
427 uint8_t properties;
428 uint8_t permissions;
429 const struct bt_uuid *uuid;
430 };
431
alloc_characteristic(struct add_characteristic * ch)432 static int alloc_characteristic(struct add_characteristic *ch)
433 {
434 struct bt_gatt_attr *attr_chrc, *attr_value;
435 struct bt_gatt_chrc *chrc_data;
436 struct gatt_value value;
437
438 /* Add Characteristic Declaration */
439 attr_chrc = gatt_db_add(&(struct bt_gatt_attr)
440 BT_GATT_ATTRIBUTE(BT_UUID_GATT_CHRC,
441 BT_GATT_PERM_READ,
442 bt_gatt_attr_read_chrc, NULL,
443 (&(struct bt_gatt_chrc){})),
444 sizeof(*chrc_data));
445 if (!attr_chrc) {
446 return -EINVAL;
447 }
448
449 (void)memset(&value, 0, sizeof(value));
450
451 if (ch->permissions & GATT_PERM_READ_AUTHORIZATION) {
452 tester_set_bit(value.flags, GATT_VALUE_READ_AUTHOR_FLAG);
453
454 /* To maintain backward compatibility, set Read Permission */
455 if (!(ch->permissions & GATT_PERM_ENC_READ_MASK)) {
456 ch->permissions |= BT_GATT_PERM_READ;
457 }
458 }
459
460 if (ch->permissions & GATT_PERM_WRITE_AUTHORIZATION) {
461 tester_set_bit(value.flags, GATT_VALUE_WRITE_AUTHOR_FLAG);
462
463 /* To maintain backward compatibility, set Write Permission */
464 if (!(ch->permissions & GATT_PERM_ENC_WRITE_MASK)) {
465 ch->permissions |= BT_GATT_PERM_WRITE;
466 }
467 }
468
469 /* Allow prepare writes */
470 ch->permissions |= BT_GATT_PERM_PREPARE_WRITE;
471
472 /* Add Characteristic Value */
473 attr_value = gatt_db_add(&(struct bt_gatt_attr)
474 BT_GATT_ATTRIBUTE(ch->uuid,
475 ch->permissions & GATT_PERM_MASK,
476 read_value, write_value, &value),
477 sizeof(value));
478 if (!attr_value) {
479 server_buf_pull(sizeof(*chrc_data));
480 /* Characteristic attribute uuid has constant length */
481 server_buf_pull(sizeof(uint16_t));
482 return -EINVAL;
483 }
484
485 chrc_data = attr_chrc->user_data;
486 chrc_data->properties = ch->properties;
487 chrc_data->uuid = attr_value->uuid;
488
489 ch->char_id = attr_chrc->handle;
490 return 0;
491 }
492
add_characteristic(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)493 static uint8_t add_characteristic(const void *cmd, uint16_t cmd_len,
494 void *rsp, uint16_t *rsp_len)
495 {
496 const struct btp_gatt_add_characteristic_cmd *cp = cmd;
497 struct btp_gatt_add_characteristic_rp *rp = rsp;
498 struct add_characteristic cmd_data;
499 union uuid uuid;
500
501 if ((cmd_len < sizeof(*cp)) ||
502 (cmd_len != sizeof(*cp) + cp->uuid_length)) {
503 return BTP_STATUS_FAILED;
504 }
505
506 /* Pre-set char_id */
507 cmd_data.char_id = 0U;
508 cmd_data.permissions = cp->permissions;
509 cmd_data.properties = cp->properties;
510 cmd_data.uuid = &uuid.uuid;
511
512 if (btp2bt_uuid(cp->uuid, cp->uuid_length, &uuid.uuid)) {
513 return BTP_STATUS_FAILED;
514 }
515
516 /* characteristic must be added only sequential */
517 if (cp->svc_id) {
518 return BTP_STATUS_FAILED;
519 }
520
521 if (alloc_characteristic(&cmd_data)) {
522 return BTP_STATUS_FAILED;
523 }
524
525 ccc_added = false;
526
527 rp->char_id = sys_cpu_to_le16(cmd_data.char_id);
528 *rsp_len = sizeof(*rp);
529
530 return BTP_STATUS_SUCCESS;
531 }
532
ccc_cfg_changed(const struct bt_gatt_attr * attr,uint16_t value)533 static void ccc_cfg_changed(const struct bt_gatt_attr *attr, uint16_t value)
534 {
535 int i = ccc_find_by_ccc(attr);
536
537 if (i >= 0) {
538 ccc_values[i].value = value;
539 }
540 }
541
542 static struct bt_gatt_attr ccc = BT_GATT_CCC(ccc_cfg_changed,
543 BT_GATT_PERM_READ |
544 BT_GATT_PERM_WRITE);
545
add_ccc(struct bt_gatt_attr * attr)546 static struct bt_gatt_attr *add_ccc(struct bt_gatt_attr *attr)
547 {
548 struct bt_gatt_attr *attr_desc;
549 struct bt_gatt_chrc *chrc = attr->user_data;
550 struct gatt_value *value = NEXT_DB_ATTR(attr)->user_data;
551 int i;
552
553 /* Fail if another CCC already exist for this characteristic */
554 if (ccc_added) {
555 return NULL;
556 }
557
558 /* Check characteristic properties */
559 if (!(chrc->properties &
560 (BT_GATT_CHRC_NOTIFY | BT_GATT_CHRC_INDICATE))) {
561 return NULL;
562 }
563
564 /* Add CCC descriptor to GATT database */
565 attr_desc = gatt_db_add(&ccc, 0);
566 if (!attr_desc) {
567 return NULL;
568 }
569
570 i = ccc_find_by_ccc(NULL);
571 if (i >= 0) {
572 ccc_values[i].attr = attr;
573 ccc_values[i].ccc = attr_desc;
574 ccc_values[i].value = 0;
575 }
576
577 tester_set_bit(value->flags, GATT_VALUE_CCC_FLAG);
578 ccc_added = true;
579
580 return attr_desc;
581 }
582
add_cep(const struct bt_gatt_attr * attr_chrc)583 static struct bt_gatt_attr *add_cep(const struct bt_gatt_attr *attr_chrc)
584 {
585 struct bt_gatt_chrc *chrc = attr_chrc->user_data;
586 struct bt_gatt_cep cep_value;
587
588 /* Extended Properties bit shall be set */
589 if (!(chrc->properties & BT_GATT_CHRC_EXT_PROP)) {
590 return NULL;
591 }
592
593 cep_value.properties = 0x0000;
594
595 /* Add CEP descriptor to GATT database */
596 return gatt_db_add(&(struct bt_gatt_attr) BT_GATT_CEP(&cep_value),
597 sizeof(cep_value));
598 }
599
600 struct add_descriptor {
601 uint16_t desc_id;
602 uint8_t permissions;
603 const struct bt_uuid *uuid;
604 };
605
alloc_descriptor(struct bt_gatt_attr * attr,struct add_descriptor * d)606 static int alloc_descriptor(struct bt_gatt_attr *attr,
607 struct add_descriptor *d)
608 {
609 struct bt_gatt_attr *attr_desc;
610 struct gatt_value value;
611
612 if (!bt_uuid_cmp(d->uuid, BT_UUID_GATT_CEP)) {
613 attr_desc = add_cep(attr);
614 } else if (!bt_uuid_cmp(d->uuid, BT_UUID_GATT_CCC)) {
615 attr_desc = add_ccc(attr);
616 } else {
617 (void)memset(&value, 0, sizeof(value));
618
619 if (d->permissions & GATT_PERM_READ_AUTHORIZATION) {
620 tester_set_bit(value.flags,
621 GATT_VALUE_READ_AUTHOR_FLAG);
622
623 /*
624 * To maintain backward compatibility,
625 * set Read Permission
626 */
627 if (!(d->permissions & GATT_PERM_ENC_READ_MASK)) {
628 d->permissions |= BT_GATT_PERM_READ;
629 }
630 }
631
632 if (d->permissions & GATT_PERM_WRITE_AUTHORIZATION) {
633 tester_set_bit(value.flags,
634 GATT_VALUE_WRITE_AUTHOR_FLAG);
635
636 /*
637 * To maintain backward compatibility,
638 * set Write Permission
639 */
640 if (!(d->permissions & GATT_PERM_ENC_WRITE_MASK)) {
641 d->permissions |= BT_GATT_PERM_WRITE;
642 }
643 }
644
645 /* Allow prepare writes */
646 d->permissions |= BT_GATT_PERM_PREPARE_WRITE;
647
648 attr_desc = gatt_db_add(&(struct bt_gatt_attr)
649 BT_GATT_DESCRIPTOR(d->uuid,
650 d->permissions & GATT_PERM_MASK,
651 read_value, write_value,
652 &value), sizeof(value));
653 }
654
655 if (!attr_desc) {
656 return -EINVAL;
657 }
658
659 d->desc_id = attr_desc->handle;
660 return 0;
661 }
662
get_base_chrc(struct bt_gatt_attr * attr)663 static struct bt_gatt_attr *get_base_chrc(struct bt_gatt_attr *attr)
664 {
665 struct bt_gatt_attr *tmp;
666
667 for (tmp = attr; tmp > server_db; tmp--) {
668 /* Service Declaration cannot precede Descriptor declaration */
669 if (!bt_uuid_cmp(tmp->uuid, BT_UUID_GATT_PRIMARY) ||
670 !bt_uuid_cmp(tmp->uuid, BT_UUID_GATT_SECONDARY)) {
671 break;
672 }
673
674 if (!bt_uuid_cmp(tmp->uuid, BT_UUID_GATT_CHRC)) {
675 return tmp;
676 }
677 }
678
679 return NULL;
680 }
681
add_descriptor(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)682 static uint8_t add_descriptor(const void *cmd, uint16_t cmd_len,
683 void *rsp, uint16_t *rsp_len)
684 {
685 const struct btp_gatt_add_descriptor_cmd *cp = cmd;
686 struct btp_gatt_add_descriptor_rp *rp = rsp;
687 struct add_descriptor cmd_data;
688 struct bt_gatt_attr *chrc;
689 union uuid uuid;
690
691 if ((cmd_len < sizeof(*cp)) ||
692 (cmd_len != sizeof(*cp) + cp->uuid_length)) {
693 return BTP_STATUS_FAILED;
694 }
695
696 /* Must be declared first svc or at least 3 attrs (svc+char+char val) */
697 if (!svc_count || attr_count < 3) {
698 return BTP_STATUS_FAILED;
699 }
700
701 /* Pre-set desc_id */
702 cmd_data.desc_id = 0U;
703 cmd_data.permissions = cp->permissions;
704 cmd_data.uuid = &uuid.uuid;
705
706 if (btp2bt_uuid(cp->uuid, cp->uuid_length, &uuid.uuid)) {
707 return BTP_STATUS_FAILED;
708 }
709
710 /* descriptor can be added only sequential */
711 if (cp->char_id) {
712 return BTP_STATUS_FAILED;
713 }
714
715 /* Lookup preceding Characteristic Declaration here */
716 chrc = get_base_chrc(LAST_DB_ATTR);
717 if (!chrc) {
718 return BTP_STATUS_FAILED;
719 }
720
721 if (alloc_descriptor(chrc, &cmd_data)) {
722 return BTP_STATUS_FAILED;
723 }
724
725 rp->desc_id = sys_cpu_to_le16(cmd_data.desc_id);
726 *rsp_len = sizeof(*rp);
727
728 return BTP_STATUS_SUCCESS;
729 }
730
alloc_included(struct bt_gatt_attr * attr,uint16_t * included_service_id,uint16_t svc_handle)731 static int alloc_included(struct bt_gatt_attr *attr,
732 uint16_t *included_service_id, uint16_t svc_handle)
733 {
734 struct bt_gatt_attr *attr_incl;
735
736 /*
737 * user_data_len is set to 0 to NOT allocate memory in server_buf for
738 * user_data, just to assign to it attr pointer.
739 */
740 attr_incl = gatt_db_add(&(struct bt_gatt_attr)
741 BT_GATT_INCLUDE_SERVICE(attr), 0);
742
743 if (!attr_incl) {
744 return -EINVAL;
745 }
746
747 attr_incl->user_data = attr;
748
749 *included_service_id = attr_incl->handle;
750 return 0;
751 }
752
add_included(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)753 static uint8_t add_included(const void *cmd, uint16_t cmd_len,
754 void *rsp, uint16_t *rsp_len)
755 {
756 const struct btp_gatt_add_included_service_cmd *cp = cmd;
757 struct btp_gatt_add_included_service_rp *rp = rsp;
758 struct bt_gatt_attr *svc;
759 uint16_t svc_id;
760 uint16_t included_service_id = 0U;
761
762 if (!svc_count) {
763 return BTP_STATUS_FAILED;
764 }
765
766 svc_id = sys_le16_to_cpu(cp->svc_id);
767
768 if (svc_id == 0 || svc_id > SERVER_MAX_ATTRIBUTES) {
769 return BTP_STATUS_FAILED;
770 }
771
772 svc = &server_db[svc_id - 1];
773
774 /* Fail if attribute stored under requested handle is not a service */
775 if (bt_uuid_cmp(svc->uuid, BT_UUID_GATT_PRIMARY) &&
776 bt_uuid_cmp(svc->uuid, BT_UUID_GATT_SECONDARY)) {
777 return BTP_STATUS_FAILED;
778 }
779
780 if (alloc_included(svc, &included_service_id, svc_id)) {
781 return BTP_STATUS_FAILED;
782 }
783
784 rp->included_service_id = sys_cpu_to_le16(included_service_id);
785 *rsp_len = sizeof(*rp);
786
787 return BTP_STATUS_SUCCESS;
788 }
789
set_cep_value(struct bt_gatt_attr * attr,const void * value,const uint16_t len)790 static uint8_t set_cep_value(struct bt_gatt_attr *attr, const void *value,
791 const uint16_t len)
792 {
793 struct bt_gatt_cep *cep_value = attr->user_data;
794 uint16_t properties;
795
796 if (len != sizeof(properties)) {
797 return BTP_STATUS_FAILED;
798 }
799
800 memcpy(&properties, value, len);
801 cep_value->properties = sys_le16_to_cpu(properties);
802
803 return BTP_STATUS_SUCCESS;
804 }
805
806 struct set_value {
807 const uint8_t *value;
808 uint16_t len;
809 };
810
811 struct bt_gatt_indicate_params indicate_params;
812
indicate_cb(struct bt_conn * conn,struct bt_gatt_indicate_params * params,uint8_t err)813 static void indicate_cb(struct bt_conn *conn,
814 struct bt_gatt_indicate_params *params, uint8_t err)
815 {
816 if (err != 0U) {
817 LOG_ERR("Indication fail");
818 } else {
819 LOG_DBG("Indication success");
820 }
821 }
822
alloc_value(struct bt_gatt_attr * attr,struct set_value * data)823 static uint8_t alloc_value(struct bt_gatt_attr *attr, struct set_value *data)
824 {
825 struct gatt_value *value;
826 uint8_t ccc_value;
827 int i;
828
829 /* Value has been already set while adding CCC to the gatt_db */
830 if (!bt_uuid_cmp(attr->uuid, BT_UUID_GATT_CCC)) {
831 return BTP_STATUS_SUCCESS;
832 }
833
834 /* Set CEP value */
835 if (!bt_uuid_cmp(attr->uuid, BT_UUID_GATT_CEP)) {
836 return set_cep_value(attr, data->value, data->len);
837 }
838
839 value = attr->user_data;
840
841 /* Check if attribute value has been already set */
842 if (!value->len) {
843 value->data = server_buf_push(data->len);
844 value->len = data->len;
845 }
846
847 /* Fail if value length doesn't match */
848 if (value->len != data->len) {
849 return BTP_STATUS_FAILED;
850 }
851
852 memcpy(value->data, data->value, value->len);
853
854 /** Handle of attribute is 1 less that handle to its value */
855 i = ccc_find_by_attr(attr->handle - 1);
856
857 if (i < 0) {
858 ccc_value = 0;
859 } else {
860 ccc_value = ccc_values[i].value;
861 }
862
863 if (tester_test_bit(value->flags, GATT_VALUE_CCC_FLAG) && ccc_value) {
864 if (ccc_value == BT_GATT_CCC_NOTIFY) {
865 bt_gatt_notify(NULL, attr, value->data, value->len);
866 } else {
867 indicate_params.attr = attr;
868 indicate_params.data = value->data;
869 indicate_params.len = value->len;
870 indicate_params.func = indicate_cb;
871 indicate_params.destroy = NULL;
872 indicate_params.chan_opt = BT_ATT_CHAN_OPT_NONE;
873
874 bt_gatt_indicate(NULL, &indicate_params);
875 }
876 }
877
878 return BTP_STATUS_SUCCESS;
879 }
880
set_value(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)881 static uint8_t set_value(const void *cmd, uint16_t cmd_len,
882 void *rsp, uint16_t *rsp_len)
883 {
884 const struct btp_gatt_set_value_cmd *cp = cmd;
885 struct set_value cmd_data;
886 uint16_t attr_id;
887 uint8_t status;
888
889 if ((cmd_len < sizeof(*cp)) ||
890 (cmd_len != sizeof(*cp) + sys_le16_to_cpu(cp->len))) {
891 return BTP_STATUS_FAILED;
892 }
893
894 attr_id = sys_le16_to_cpu(cp->attr_id);
895 if (attr_id > SERVER_MAX_ATTRIBUTES) {
896 return BTP_STATUS_FAILED;
897 }
898
899 /* Pre-set btp_status */
900 cmd_data.value = cp->value;
901 cmd_data.len = sys_le16_to_cpu(cp->len);
902
903 if (attr_id == 0) {
904 status = alloc_value(LAST_DB_ATTR, &cmd_data);
905 } else {
906 /* set value of local attr, corrected by pre set attr handles */
907 status = alloc_value(&server_db[attr_id - server_db[0].handle],
908 &cmd_data);
909 }
910
911 return BTP_STATUS_SUCCESS;
912 }
913
start_server(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)914 static uint8_t start_server(const void *cmd, uint16_t cmd_len,
915 void *rsp, uint16_t *rsp_len)
916 {
917 struct btp_gatt_start_server_rp *rp = rsp;
918
919 /* Register last defined service */
920 if (svc_attr_count) {
921 if (register_service()) {
922 return BTP_STATUS_FAILED;
923 }
924 }
925
926 rp->db_attr_off = sys_cpu_to_le16(0); /* TODO*/
927 rp->db_attr_cnt = svc_attr_count;
928 *rsp_len = sizeof(*rp);
929
930 return BTP_STATUS_SUCCESS;
931 }
932
set_attr_enc_key_size(const struct bt_gatt_attr * attr,uint8_t key_size)933 static int set_attr_enc_key_size(const struct bt_gatt_attr *attr,
934 uint8_t key_size)
935 {
936 struct gatt_value *value;
937
938 /* Fail if requested attribute is a service */
939 if (!bt_uuid_cmp(attr->uuid, BT_UUID_GATT_PRIMARY) ||
940 !bt_uuid_cmp(attr->uuid, BT_UUID_GATT_SECONDARY) ||
941 !bt_uuid_cmp(attr->uuid, BT_UUID_GATT_INCLUDE)) {
942 return -EINVAL;
943 }
944
945 /* Fail if permissions are not set */
946 if (!(attr->perm & (GATT_PERM_ENC_READ_MASK |
947 GATT_PERM_ENC_WRITE_MASK))) {
948 return -EINVAL;
949 }
950
951 value = attr->user_data;
952 value->enc_key_size = key_size;
953
954 return 0;
955 }
956
set_enc_key_size(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)957 static uint8_t set_enc_key_size(const void *cmd, uint16_t cmd_len,
958 void *rsp, uint16_t *rsp_len)
959 {
960 const struct btp_gatt_set_enc_key_size_cmd *cp = cmd;
961 uint16_t attr_id;
962 int ret;
963
964 /* Fail if requested key size is invalid */
965 if (cp->key_size < 0x07 || cp->key_size > 0x0f) {
966 return BTP_STATUS_FAILED;
967 }
968
969 attr_id = sys_le16_to_cpu(cp->attr_id);
970
971 if (!attr_id) {
972 ret = set_attr_enc_key_size(LAST_DB_ATTR, cp->key_size);
973 } else {
974 /* set value of local attr, corrected by pre set attr handles */
975 ret = set_attr_enc_key_size(&server_db[attr_id -
976 server_db[0].handle], cp->key_size);
977 }
978
979 if (ret) {
980 return BTP_STATUS_FAILED;
981 }
982
983 return BTP_STATUS_SUCCESS;
984 }
985
exchange_func(struct bt_conn * conn,uint8_t err,struct bt_gatt_exchange_params * params)986 static void exchange_func(struct bt_conn *conn, uint8_t err,
987 struct bt_gatt_exchange_params *params)
988 {
989 if (err != 0U) {
990 LOG_ERR("MTU exchange failed");
991 } else {
992 LOG_DBG("MTU exchange succeed");
993 }
994 }
995
996 static struct bt_gatt_exchange_params exchange_params;
997
exchange_mtu(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)998 static uint8_t exchange_mtu(const void *cmd, uint16_t cmd_len,
999 void *rsp, uint16_t *rsp_len)
1000 {
1001 const struct btp_gatt_exchange_mtu_cmd *cp = cmd;
1002 struct bt_conn *conn;
1003
1004 conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address);
1005 if (!conn) {
1006 return BTP_STATUS_FAILED;
1007 }
1008
1009 exchange_params.func = exchange_func;
1010
1011 if (bt_gatt_exchange_mtu(conn, &exchange_params) < 0) {
1012 bt_conn_unref(conn);
1013 return BTP_STATUS_FAILED;
1014 }
1015
1016 bt_conn_unref(conn);
1017
1018 /* this BTP command is about initiating MTU exchange, no need to wait
1019 * for procedure to complete.
1020 */
1021 return BTP_STATUS_SUCCESS;
1022 }
1023
1024 static struct bt_gatt_discover_params discover_params;
1025 static union uuid uuid;
1026 static uint8_t btp_opcode;
1027
discover_destroy(struct bt_gatt_discover_params * params)1028 static void discover_destroy(struct bt_gatt_discover_params *params)
1029 {
1030 (void)memset(params, 0, sizeof(*params));
1031 gatt_buf_clear();
1032 }
1033
disc_prim_cb(struct bt_conn * conn,const struct bt_gatt_attr * attr,struct bt_gatt_discover_params * params)1034 static uint8_t disc_prim_cb(struct bt_conn *conn,
1035 const struct bt_gatt_attr *attr,
1036 struct bt_gatt_discover_params *params)
1037 {
1038 struct bt_gatt_service_val *data;
1039 struct btp_gatt_disc_prim_rp *rp = (void *) gatt_buf.buf;
1040 struct btp_gatt_service *service;
1041 uint8_t uuid_length;
1042
1043 if (!attr) {
1044 tester_rsp_full(BTP_SERVICE_ID_GATT, btp_opcode,
1045 gatt_buf.buf, gatt_buf.len);
1046 discover_destroy(params);
1047 return BT_GATT_ITER_STOP;
1048 }
1049
1050 data = attr->user_data;
1051
1052 uuid_length = data->uuid->type == BT_UUID_TYPE_16 ? 2 : 16;
1053
1054 service = gatt_buf_reserve(sizeof(*service) + uuid_length);
1055 if (!service) {
1056 tester_rsp(BTP_SERVICE_ID_GATT, btp_opcode, BTP_STATUS_FAILED);
1057 discover_destroy(params);
1058 return BT_GATT_ITER_STOP;
1059 }
1060
1061 service->start_handle = sys_cpu_to_le16(attr->handle);
1062 service->end_handle = sys_cpu_to_le16(data->end_handle);
1063 service->uuid_length = uuid_length;
1064
1065 if (data->uuid->type == BT_UUID_TYPE_16) {
1066 uint16_t u16 = sys_cpu_to_le16(BT_UUID_16(data->uuid)->val);
1067
1068 memcpy(service->uuid, &u16, uuid_length);
1069 } else {
1070 memcpy(service->uuid, BT_UUID_128(data->uuid)->val,
1071 uuid_length);
1072 }
1073
1074 rp->services_count++;
1075
1076 return BT_GATT_ITER_CONTINUE;
1077 }
1078
disc_all_prim(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1079 static uint8_t disc_all_prim(const void *cmd, uint16_t cmd_len,
1080 void *rsp, uint16_t *rsp_len)
1081 {
1082 const struct btp_gatt_disc_all_prim_cmd *cp = cmd;
1083 struct bt_conn *conn;
1084
1085 conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address);
1086 if (!conn) {
1087 return BTP_STATUS_FAILED;
1088 }
1089
1090 if (!gatt_buf_reserve(sizeof(struct btp_gatt_disc_prim_rp))) {
1091 bt_conn_unref(conn);
1092 return BTP_STATUS_FAILED;
1093 }
1094
1095 discover_params.uuid = NULL;
1096 discover_params.start_handle = BT_ATT_FIRST_ATTRIBUTE_HANDLE;
1097 discover_params.end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE;
1098 discover_params.type = BT_GATT_DISCOVER_PRIMARY;
1099 discover_params.func = disc_prim_cb;
1100 discover_params.chan_opt = BT_ATT_CHAN_OPT_NONE;
1101
1102 btp_opcode = BTP_GATT_DISC_ALL_PRIM;
1103
1104 if (bt_gatt_discover(conn, &discover_params) < 0) {
1105 discover_destroy(&discover_params);
1106 bt_conn_unref(conn);
1107 return BTP_STATUS_FAILED;
1108 }
1109
1110 bt_conn_unref(conn);
1111
1112 return BTP_STATUS_DELAY_REPLY;
1113 }
1114
disc_prim_uuid(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1115 static uint8_t disc_prim_uuid(const void *cmd, uint16_t cmd_len,
1116 void *rsp, uint16_t *rsp_len)
1117 {
1118 const struct btp_gatt_disc_prim_uuid_cmd *cp = cmd;
1119 struct bt_conn *conn;
1120
1121 if ((cmd_len < sizeof(*cp)) ||
1122 (cmd_len != sizeof(*cp) + cp->uuid_length)) {
1123 return BTP_STATUS_FAILED;
1124 }
1125
1126 conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address);
1127 if (!conn) {
1128 return BTP_STATUS_FAILED;
1129 }
1130
1131 if (btp2bt_uuid(cp->uuid, cp->uuid_length, &uuid.uuid)) {
1132 bt_conn_unref(conn);
1133 return BTP_STATUS_FAILED;
1134 }
1135
1136 if (!gatt_buf_reserve(sizeof(struct btp_gatt_disc_prim_rp))) {
1137 bt_conn_unref(conn);
1138 return BTP_STATUS_FAILED;
1139 }
1140
1141 discover_params.uuid = &uuid.uuid;
1142 discover_params.start_handle = BT_ATT_FIRST_ATTRIBUTE_HANDLE;
1143 discover_params.end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE;
1144 discover_params.type = BT_GATT_DISCOVER_PRIMARY;
1145 discover_params.func = disc_prim_cb;
1146 discover_params.chan_opt = BT_ATT_CHAN_OPT_NONE;
1147
1148 btp_opcode = BTP_GATT_DISC_PRIM_UUID;
1149
1150 if (bt_gatt_discover(conn, &discover_params) < 0) {
1151 discover_destroy(&discover_params);
1152 bt_conn_unref(conn);
1153 return BTP_STATUS_FAILED;
1154 }
1155
1156 bt_conn_unref(conn);
1157
1158 return BTP_STATUS_DELAY_REPLY;
1159 }
1160
find_included_cb(struct bt_conn * conn,const struct bt_gatt_attr * attr,struct bt_gatt_discover_params * params)1161 static uint8_t find_included_cb(struct bt_conn *conn,
1162 const struct bt_gatt_attr *attr,
1163 struct bt_gatt_discover_params *params)
1164 {
1165 struct bt_gatt_include *data;
1166 struct btp_gatt_find_included_rp *rp = (void *) gatt_buf.buf;
1167 struct btp_gatt_included *included;
1168 uint8_t uuid_length;
1169
1170 if (!attr) {
1171 tester_rsp_full(BTP_SERVICE_ID_GATT, BTP_GATT_FIND_INCLUDED,
1172 gatt_buf.buf, gatt_buf.len);
1173 discover_destroy(params);
1174 return BT_GATT_ITER_STOP;
1175 }
1176
1177 data = attr->user_data;
1178
1179 uuid_length = data->uuid->type == BT_UUID_TYPE_16 ? 2 : 16;
1180
1181 included = gatt_buf_reserve(sizeof(*included) + uuid_length);
1182 if (!included) {
1183 tester_rsp(BTP_SERVICE_ID_GATT, BTP_GATT_FIND_INCLUDED, BTP_STATUS_FAILED);
1184 discover_destroy(params);
1185 return BT_GATT_ITER_STOP;
1186 }
1187
1188 included->included_handle = attr->handle;
1189 included->service.start_handle = sys_cpu_to_le16(data->start_handle);
1190 included->service.end_handle = sys_cpu_to_le16(data->end_handle);
1191 included->service.uuid_length = uuid_length;
1192
1193 if (data->uuid->type == BT_UUID_TYPE_16) {
1194 uint16_t u16 = sys_cpu_to_le16(BT_UUID_16(data->uuid)->val);
1195
1196 memcpy(included->service.uuid, &u16, uuid_length);
1197 } else {
1198 memcpy(included->service.uuid, BT_UUID_128(data->uuid)->val,
1199 uuid_length);
1200 }
1201
1202 rp->services_count++;
1203
1204 return BT_GATT_ITER_CONTINUE;
1205 }
1206
find_included(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1207 static uint8_t find_included(const void *cmd, uint16_t cmd_len,
1208 void *rsp, uint16_t *rsp_len)
1209 {
1210 const struct btp_gatt_find_included_cmd *cp = cmd;
1211 struct bt_conn *conn;
1212
1213 conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address);
1214 if (!conn) {
1215 return BTP_STATUS_FAILED;
1216 }
1217
1218 if (!gatt_buf_reserve(sizeof(struct btp_gatt_find_included_rp))) {
1219 bt_conn_unref(conn);
1220 return BTP_STATUS_FAILED;
1221 }
1222
1223 discover_params.start_handle = sys_le16_to_cpu(cp->start_handle);
1224 discover_params.end_handle = sys_le16_to_cpu(cp->end_handle);
1225 discover_params.type = BT_GATT_DISCOVER_INCLUDE;
1226 discover_params.func = find_included_cb;
1227 discover_params.chan_opt = BT_ATT_CHAN_OPT_NONE;
1228
1229 if (bt_gatt_discover(conn, &discover_params) < 0) {
1230 discover_destroy(&discover_params);
1231 bt_conn_unref(conn);
1232 return BTP_STATUS_FAILED;
1233 }
1234
1235 bt_conn_unref(conn);
1236
1237 return BTP_STATUS_DELAY_REPLY;
1238 }
1239
disc_chrc_cb(struct bt_conn * conn,const struct bt_gatt_attr * attr,struct bt_gatt_discover_params * params)1240 static uint8_t disc_chrc_cb(struct bt_conn *conn,
1241 const struct bt_gatt_attr *attr,
1242 struct bt_gatt_discover_params *params)
1243 {
1244 struct bt_gatt_chrc *data;
1245 struct btp_gatt_disc_chrc_rp *rp = (void *) gatt_buf.buf;
1246 struct btp_gatt_characteristic *chrc;
1247 uint8_t uuid_length;
1248
1249 if (!attr) {
1250 tester_rsp_full(BTP_SERVICE_ID_GATT, btp_opcode,
1251 gatt_buf.buf, gatt_buf.len);
1252 discover_destroy(params);
1253 return BT_GATT_ITER_STOP;
1254 }
1255
1256 data = attr->user_data;
1257
1258 uuid_length = data->uuid->type == BT_UUID_TYPE_16 ? 2 : 16;
1259
1260 chrc = gatt_buf_reserve(sizeof(*chrc) + uuid_length);
1261 if (!chrc) {
1262 tester_rsp(BTP_SERVICE_ID_GATT, btp_opcode, BTP_STATUS_FAILED);
1263 discover_destroy(params);
1264 return BT_GATT_ITER_STOP;
1265 }
1266
1267 chrc->characteristic_handle = sys_cpu_to_le16(attr->handle);
1268 chrc->properties = data->properties;
1269 chrc->value_handle = sys_cpu_to_le16(attr->handle + 1);
1270 chrc->uuid_length = uuid_length;
1271
1272 if (data->uuid->type == BT_UUID_TYPE_16) {
1273 uint16_t u16 = sys_cpu_to_le16(BT_UUID_16(data->uuid)->val);
1274
1275 memcpy(chrc->uuid, &u16, uuid_length);
1276 } else {
1277 memcpy(chrc->uuid, BT_UUID_128(data->uuid)->val, uuid_length);
1278 }
1279
1280 rp->characteristics_count++;
1281
1282 return BT_GATT_ITER_CONTINUE;
1283 }
1284
disc_all_chrc(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1285 static uint8_t disc_all_chrc(const void *cmd, uint16_t cmd_len,
1286 void *rsp, uint16_t *rsp_len)
1287 {
1288 const struct btp_gatt_disc_all_chrc_cmd *cp = cmd;
1289 struct bt_conn *conn;
1290
1291 conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address);
1292 if (!conn) {
1293 return BTP_STATUS_FAILED;
1294 }
1295
1296 if (!gatt_buf_reserve(sizeof(struct btp_gatt_disc_chrc_rp))) {
1297 bt_conn_unref(conn);
1298 return BTP_STATUS_FAILED;
1299 }
1300
1301 discover_params.start_handle = sys_le16_to_cpu(cp->start_handle);
1302 discover_params.end_handle = sys_le16_to_cpu(cp->end_handle);
1303 discover_params.type = BT_GATT_DISCOVER_CHARACTERISTIC;
1304 discover_params.func = disc_chrc_cb;
1305 discover_params.chan_opt = BT_ATT_CHAN_OPT_NONE;
1306
1307 /* TODO should be handled as user_data via CONTAINER_OF macro */
1308 btp_opcode = BTP_GATT_DISC_ALL_CHRC;
1309
1310 if (bt_gatt_discover(conn, &discover_params) < 0) {
1311 discover_destroy(&discover_params);
1312 bt_conn_unref(conn);
1313 return BTP_STATUS_FAILED;
1314 }
1315
1316 bt_conn_unref(conn);
1317
1318 return BTP_STATUS_DELAY_REPLY;
1319 }
1320
disc_chrc_uuid(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1321 static uint8_t disc_chrc_uuid(const void *cmd, uint16_t cmd_len,
1322 void *rsp, uint16_t *rsp_len)
1323 {
1324 const struct btp_gatt_disc_chrc_uuid_cmd *cp = cmd;
1325 struct bt_conn *conn;
1326
1327 if ((cmd_len < sizeof(*cp)) ||
1328 (cmd_len != sizeof(*cp) + cp->uuid_length)) {
1329 return BTP_STATUS_FAILED;
1330 }
1331
1332 conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address);
1333 if (!conn) {
1334 return BTP_STATUS_FAILED;
1335 }
1336
1337 if (btp2bt_uuid(cp->uuid, cp->uuid_length, &uuid.uuid)) {
1338 bt_conn_unref(conn);
1339 return BTP_STATUS_FAILED;
1340 }
1341
1342 if (!gatt_buf_reserve(sizeof(struct btp_gatt_disc_chrc_rp))) {
1343 bt_conn_unref(conn);
1344 return BTP_STATUS_FAILED;
1345 }
1346
1347 discover_params.uuid = &uuid.uuid;
1348 discover_params.start_handle = sys_le16_to_cpu(cp->start_handle);
1349 discover_params.end_handle = sys_le16_to_cpu(cp->end_handle);
1350 discover_params.type = BT_GATT_DISCOVER_CHARACTERISTIC;
1351 discover_params.func = disc_chrc_cb;
1352 discover_params.chan_opt = BT_ATT_CHAN_OPT_NONE;
1353
1354 /* TODO should be handled as user_data via CONTAINER_OF macro */
1355 btp_opcode = BTP_GATT_DISC_CHRC_UUID;
1356
1357 if (bt_gatt_discover(conn, &discover_params) < 0) {
1358 discover_destroy(&discover_params);
1359 bt_conn_unref(conn);
1360 return BTP_STATUS_FAILED;
1361 }
1362
1363 bt_conn_unref(conn);
1364
1365 return BTP_STATUS_DELAY_REPLY;
1366 }
1367
disc_all_desc_cb(struct bt_conn * conn,const struct bt_gatt_attr * attr,struct bt_gatt_discover_params * params)1368 static uint8_t disc_all_desc_cb(struct bt_conn *conn,
1369 const struct bt_gatt_attr *attr,
1370 struct bt_gatt_discover_params *params)
1371 {
1372 struct btp_gatt_disc_all_desc_rp *rp = (void *) gatt_buf.buf;
1373 struct btp_gatt_descriptor *descriptor;
1374 uint8_t uuid_length;
1375
1376 if (!attr) {
1377 tester_rsp_full(BTP_SERVICE_ID_GATT, BTP_GATT_DISC_ALL_DESC,
1378 gatt_buf.buf, gatt_buf.len);
1379 discover_destroy(params);
1380 return BT_GATT_ITER_STOP;
1381 }
1382
1383 uuid_length = attr->uuid->type == BT_UUID_TYPE_16 ? 2 : 16;
1384
1385 descriptor = gatt_buf_reserve(sizeof(*descriptor) + uuid_length);
1386 if (!descriptor) {
1387 tester_rsp(BTP_SERVICE_ID_GATT, BTP_GATT_DISC_ALL_DESC, BTP_STATUS_FAILED);
1388 discover_destroy(params);
1389 return BT_GATT_ITER_STOP;
1390 }
1391
1392 descriptor->descriptor_handle = sys_cpu_to_le16(attr->handle);
1393 descriptor->uuid_length = uuid_length;
1394
1395 if (attr->uuid->type == BT_UUID_TYPE_16) {
1396 uint16_t u16 = sys_cpu_to_le16(BT_UUID_16(attr->uuid)->val);
1397
1398 memcpy(descriptor->uuid, &u16, uuid_length);
1399 } else {
1400 memcpy(descriptor->uuid, BT_UUID_128(attr->uuid)->val,
1401 uuid_length);
1402 }
1403
1404 rp->descriptors_count++;
1405
1406 return BT_GATT_ITER_CONTINUE;
1407 }
1408
disc_all_desc(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1409 static uint8_t disc_all_desc(const void *cmd, uint16_t cmd_len,
1410 void *rsp, uint16_t *rsp_len)
1411 {
1412 const struct btp_gatt_disc_all_desc_cmd *cp = cmd;
1413 struct bt_conn *conn;
1414
1415 conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address);
1416 if (!conn) {
1417 return BTP_STATUS_FAILED;
1418 }
1419
1420 if (!gatt_buf_reserve(sizeof(struct btp_gatt_disc_all_desc_rp))) {
1421 bt_conn_unref(conn);
1422 return BTP_STATUS_FAILED;
1423 }
1424
1425 discover_params.start_handle = sys_le16_to_cpu(cp->start_handle);
1426 discover_params.end_handle = sys_le16_to_cpu(cp->end_handle);
1427 discover_params.type = BT_GATT_DISCOVER_DESCRIPTOR;
1428 discover_params.func = disc_all_desc_cb;
1429 discover_params.chan_opt = BT_ATT_CHAN_OPT_NONE;
1430
1431 if (bt_gatt_discover(conn, &discover_params) < 0) {
1432 discover_destroy(&discover_params);
1433 bt_conn_unref(conn);
1434 return BTP_STATUS_FAILED;
1435 }
1436
1437 bt_conn_unref(conn);
1438
1439 return BTP_STATUS_DELAY_REPLY;
1440 }
1441
1442 static struct bt_gatt_read_params read_params;
1443
read_destroy(struct bt_gatt_read_params * params)1444 static void read_destroy(struct bt_gatt_read_params *params)
1445 {
1446 (void)memset(params, 0, sizeof(*params));
1447 gatt_buf_clear();
1448 }
1449
read_cb(struct bt_conn * conn,uint8_t err,struct bt_gatt_read_params * params,const void * data,uint16_t length)1450 static uint8_t read_cb(struct bt_conn *conn, uint8_t err,
1451 struct bt_gatt_read_params *params, const void *data,
1452 uint16_t length)
1453 {
1454 struct btp_gatt_read_rp *rp = (void *) gatt_buf.buf;
1455
1456 /* Respond to the Lower Tester with ATT Error received */
1457 if (err) {
1458 rp->att_response = err;
1459 }
1460
1461 /* read complete */
1462 if (!data) {
1463 tester_rsp_full(BTP_SERVICE_ID_GATT, btp_opcode,
1464 gatt_buf.buf, gatt_buf.len);
1465 read_destroy(params);
1466 return BT_GATT_ITER_STOP;
1467 }
1468
1469 if (!gatt_buf_add(data, length)) {
1470 tester_rsp(BTP_SERVICE_ID_GATT, btp_opcode, BTP_STATUS_FAILED);
1471 read_destroy(params);
1472 return BT_GATT_ITER_STOP;
1473 }
1474
1475 rp->data_length += length;
1476
1477 return BT_GATT_ITER_CONTINUE;
1478 }
1479
read_uuid_cb(struct bt_conn * conn,uint8_t err,struct bt_gatt_read_params * params,const void * data,uint16_t length)1480 static uint8_t read_uuid_cb(struct bt_conn *conn, uint8_t err,
1481 struct bt_gatt_read_params *params, const void *data,
1482 uint16_t length)
1483 {
1484 struct btp_gatt_read_uuid_rp *rp = (void *)gatt_buf.buf;
1485 struct btp_gatt_char_value value;
1486
1487 /* Respond to the Lower Tester with ATT Error received */
1488 if (err) {
1489 rp->att_response = err;
1490 }
1491
1492 /* read complete */
1493 if (!data) {
1494 tester_rsp_full(BTP_SERVICE_ID_GATT, btp_opcode,
1495 gatt_buf.buf, gatt_buf.len);
1496 read_destroy(params);
1497
1498 return BT_GATT_ITER_STOP;
1499 }
1500
1501 value.handle = params->by_uuid.start_handle;
1502 value.data_len = length;
1503
1504 if (!gatt_buf_add(&value, sizeof(struct btp_gatt_char_value))) {
1505 tester_rsp(BTP_SERVICE_ID_GATT, btp_opcode, BTP_STATUS_FAILED);
1506 read_destroy(params);
1507
1508 return BT_GATT_ITER_STOP;
1509 }
1510
1511 if (!gatt_buf_add(data, length)) {
1512 tester_rsp(BTP_SERVICE_ID_GATT, btp_opcode, BTP_STATUS_FAILED);
1513 read_destroy(params);
1514
1515 return BT_GATT_ITER_STOP;
1516 }
1517
1518 rp->values_count++;
1519
1520 return BT_GATT_ITER_CONTINUE;
1521 }
1522
read_data(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1523 static uint8_t read_data(const void *cmd, uint16_t cmd_len,
1524 void *rsp, uint16_t *rsp_len)
1525 {
1526 const struct btp_gatt_read_cmd *cp = cmd;
1527 struct bt_conn *conn;
1528
1529 conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address);
1530 if (!conn) {
1531 return BTP_STATUS_FAILED;
1532 }
1533
1534 if (!gatt_buf_reserve(sizeof(struct btp_gatt_read_rp))) {
1535 bt_conn_unref(conn);
1536 return BTP_STATUS_FAILED;
1537 }
1538
1539 read_params.handle_count = 1;
1540 read_params.single.handle = sys_le16_to_cpu(cp->handle);
1541 read_params.single.offset = 0x0000;
1542 read_params.func = read_cb;
1543 read_params.chan_opt = BT_ATT_CHAN_OPT_NONE;
1544
1545 /* TODO should be handled as user_data via CONTAINER_OF macro */
1546 btp_opcode = BTP_GATT_READ;
1547
1548 if (bt_gatt_read(conn, &read_params) < 0) {
1549 read_destroy(&read_params);
1550 bt_conn_unref(conn);
1551 return BTP_STATUS_FAILED;
1552 }
1553
1554 bt_conn_unref(conn);
1555
1556 return BTP_STATUS_DELAY_REPLY;
1557 }
1558
read_uuid(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1559 static uint8_t read_uuid(const void *cmd, uint16_t cmd_len,
1560 void *rsp, uint16_t *rsp_len)
1561 {
1562 const struct btp_gatt_read_uuid_cmd *cp = cmd;
1563 struct bt_conn *conn;
1564
1565 if ((cmd_len < sizeof(*cp)) ||
1566 (cmd_len != sizeof(*cp) + cp->uuid_length)) {
1567 return BTP_STATUS_FAILED;
1568 }
1569
1570 conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address);
1571 if (!conn) {
1572 return BTP_STATUS_FAILED;
1573 }
1574
1575 if (btp2bt_uuid(cp->uuid, cp->uuid_length, &uuid.uuid)) {
1576 bt_conn_unref(conn);
1577 return BTP_STATUS_FAILED;
1578 }
1579
1580 if (!gatt_buf_reserve(sizeof(struct btp_gatt_read_uuid_rp))) {
1581 bt_conn_unref(conn);
1582 return BTP_STATUS_FAILED;
1583 }
1584
1585 read_params.by_uuid.uuid = &uuid.uuid;
1586 read_params.handle_count = 0;
1587 read_params.by_uuid.start_handle = sys_le16_to_cpu(cp->start_handle);
1588 read_params.by_uuid.end_handle = sys_le16_to_cpu(cp->end_handle);
1589 read_params.func = read_uuid_cb;
1590 read_params.chan_opt = BT_ATT_CHAN_OPT_NONE;
1591
1592 btp_opcode = BTP_GATT_READ_UUID;
1593
1594 if (bt_gatt_read(conn, &read_params) < 0) {
1595 read_destroy(&read_params);
1596 bt_conn_unref(conn);
1597 return BTP_STATUS_FAILED;
1598 }
1599
1600 bt_conn_unref(conn);
1601
1602 return BTP_STATUS_DELAY_REPLY;
1603 }
1604
read_long(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1605 static uint8_t read_long(const void *cmd, uint16_t cmd_len,
1606 void *rsp, uint16_t *rsp_len)
1607 {
1608 const struct btp_gatt_read_long_cmd *cp = cmd;
1609 struct bt_conn *conn;
1610
1611 conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address);
1612 if (!conn) {
1613 return BTP_STATUS_FAILED;
1614 }
1615
1616 if (!gatt_buf_reserve(sizeof(struct btp_gatt_read_rp))) {
1617 bt_conn_unref(conn);
1618 return BTP_STATUS_FAILED;
1619 }
1620
1621 read_params.handle_count = 1;
1622 read_params.single.handle = sys_le16_to_cpu(cp->handle);
1623 read_params.single.offset = sys_le16_to_cpu(cp->offset);
1624 read_params.func = read_cb;
1625 read_params.chan_opt = BT_ATT_CHAN_OPT_NONE;
1626
1627 /* TODO should be handled as user_data via CONTAINER_OF macro */
1628 btp_opcode = BTP_GATT_READ_LONG;
1629
1630 if (bt_gatt_read(conn, &read_params) < 0) {
1631 read_destroy(&read_params);
1632 bt_conn_unref(conn);
1633 return BTP_STATUS_FAILED;
1634 }
1635
1636 bt_conn_unref(conn);
1637
1638 return BTP_STATUS_DELAY_REPLY;
1639 }
1640
read_multiple(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1641 static uint8_t read_multiple(const void *cmd, uint16_t cmd_len,
1642 void *rsp, uint16_t *rsp_len)
1643 {
1644 const struct btp_gatt_read_multiple_cmd *cp = cmd;
1645 uint16_t handles[5];
1646 struct bt_conn *conn;
1647 int i;
1648
1649 if ((cmd_len < sizeof(*cp)) ||
1650 (cmd_len != sizeof(*cp) + (cp->handles_count * sizeof(cp->handles[0])))) {
1651 return BTP_STATUS_FAILED;
1652 }
1653
1654 if (cp->handles_count == 0 || cp->handles_count > ARRAY_SIZE(handles)) {
1655 return BTP_STATUS_FAILED;
1656 }
1657
1658 for (i = 0; i < cp->handles_count; i++) {
1659 handles[i] = sys_le16_to_cpu(cp->handles[i]);
1660 }
1661
1662 conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address);
1663 if (!conn) {
1664 return BTP_STATUS_FAILED;
1665 }
1666
1667 if (!gatt_buf_reserve(sizeof(struct btp_gatt_read_rp))) {
1668 bt_conn_unref(conn);
1669 return BTP_STATUS_FAILED;
1670 }
1671
1672 read_params.func = read_cb;
1673 read_params.handle_count = cp->handles_count;
1674 read_params.multiple.handles = handles; /* not used in read func */
1675 read_params.multiple.variable = false;
1676 read_params.chan_opt = BT_ATT_CHAN_OPT_NONE;
1677
1678 /* TODO should be handled as user_data via CONTAINER_OF macro */
1679 btp_opcode = BTP_GATT_READ_MULTIPLE;
1680
1681 if (bt_gatt_read(conn, &read_params) < 0) {
1682 gatt_buf_clear();
1683 bt_conn_unref(conn);
1684 return BTP_STATUS_FAILED;
1685 }
1686
1687 bt_conn_unref(conn);
1688
1689 return BTP_STATUS_DELAY_REPLY;
1690 }
1691
read_multiple_var(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1692 static uint8_t read_multiple_var(const void *cmd, uint16_t cmd_len,
1693 void *rsp, uint16_t *rsp_len)
1694 {
1695 const struct btp_gatt_read_multiple_var_cmd *cp = cmd;
1696 uint16_t handles[5];
1697 struct bt_conn *conn;
1698 int i;
1699
1700 if ((cmd_len < sizeof(*cp)) ||
1701 (cmd_len != sizeof(*cp) + (cp->handles_count * sizeof(cp->handles[0])))) {
1702 return BTP_STATUS_FAILED;
1703 }
1704
1705 if (cp->handles_count > ARRAY_SIZE(handles)) {
1706 return BTP_STATUS_FAILED;
1707 }
1708
1709 for (i = 0; i < ARRAY_SIZE(handles); i++) {
1710 handles[i] = sys_le16_to_cpu(cp->handles[i]);
1711 }
1712
1713 conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address);
1714 if (!conn) {
1715 return BTP_STATUS_FAILED;
1716 }
1717
1718 if (!gatt_buf_reserve(sizeof(struct btp_gatt_read_rp))) {
1719 bt_conn_unref(conn);
1720 return BTP_STATUS_FAILED;
1721 }
1722
1723 read_params.func = read_cb;
1724 read_params.handle_count = i;
1725 read_params.multiple.handles = handles; /* not used in read func */
1726 read_params.multiple.variable = true;
1727 read_params.chan_opt = BT_ATT_CHAN_OPT_NONE;
1728
1729 /* TODO should be handled as user_data via CONTAINER_OF macro */
1730 btp_opcode = BTP_GATT_READ_MULTIPLE_VAR;
1731
1732 if (bt_gatt_read(conn, &read_params) < 0) {
1733 gatt_buf_clear();
1734 bt_conn_unref(conn);
1735 return BTP_STATUS_FAILED;
1736 }
1737
1738 bt_conn_unref(conn);
1739
1740 return BTP_STATUS_DELAY_REPLY;
1741 }
1742
write_without_rsp(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1743 static uint8_t write_without_rsp(const void *cmd, uint16_t cmd_len,
1744 void *rsp, uint16_t *rsp_len)
1745 {
1746 const struct btp_gatt_write_without_rsp_cmd *cp = cmd;
1747 struct bt_conn *conn;
1748
1749 if (cmd_len < sizeof(*cp) ||
1750 cmd_len != sizeof(*cp) + sys_le16_to_cpu(cp->data_length)) {
1751 return BTP_STATUS_FAILED;
1752 }
1753
1754 conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address);
1755 if (!conn) {
1756 return BTP_STATUS_FAILED;
1757 }
1758
1759 if (bt_gatt_write_without_response(conn, sys_le16_to_cpu(cp->handle),
1760 cp->data,
1761 sys_le16_to_cpu(cp->data_length),
1762 false) < 0) {
1763 bt_conn_unref(conn);
1764 return BTP_STATUS_FAILED;
1765 }
1766
1767 bt_conn_unref(conn);
1768 return BTP_STATUS_SUCCESS;
1769 }
1770
write_signed_without_rsp(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1771 static uint8_t write_signed_without_rsp(const void *cmd, uint16_t cmd_len,
1772 void *rsp, uint16_t *rsp_len)
1773 {
1774 const struct btp_gatt_signed_write_without_rsp_cmd *cp = cmd;
1775 struct bt_conn *conn;
1776
1777 if (cmd_len < sizeof(*cp) ||
1778 cmd_len != sizeof(*cp) + sys_le16_to_cpu(cp->data_length)) {
1779 return BTP_STATUS_FAILED;
1780 }
1781
1782 conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address);
1783 if (!conn) {
1784 return BTP_STATUS_FAILED;
1785 }
1786
1787 if (bt_gatt_write_without_response(conn, sys_le16_to_cpu(cp->handle),
1788 cp->data,
1789 sys_le16_to_cpu(cp->data_length),
1790 true) < 0) {
1791 bt_conn_unref(conn);
1792 return BTP_STATUS_FAILED;
1793 }
1794
1795 bt_conn_unref(conn);
1796 return BTP_STATUS_SUCCESS;
1797 }
1798
write_rsp(struct bt_conn * conn,uint8_t err,struct bt_gatt_write_params * params)1799 static void write_rsp(struct bt_conn *conn, uint8_t err,
1800 struct bt_gatt_write_params *params)
1801 {
1802 tester_rsp_full(BTP_SERVICE_ID_GATT, BTP_GATT_WRITE, &err, sizeof(err));
1803 }
1804
1805 static struct bt_gatt_write_params write_params;
1806
write_data(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1807 static uint8_t write_data(const void *cmd, uint16_t cmd_len,
1808 void *rsp, uint16_t *rsp_len)
1809 {
1810 const struct btp_gatt_write_cmd *cp = cmd;
1811 struct bt_conn *conn;
1812
1813 if (cmd_len < sizeof(*cp) ||
1814 cmd_len != sizeof(*cp) + sys_le16_to_cpu(cp->data_length)) {
1815 return BTP_STATUS_FAILED;
1816 }
1817
1818 conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address);
1819 if (!conn) {
1820 return BTP_STATUS_FAILED;
1821 }
1822
1823 write_params.handle = sys_le16_to_cpu(cp->handle);
1824 write_params.func = write_rsp;
1825 write_params.offset = 0U;
1826 write_params.data = cp->data;
1827 write_params.length = sys_le16_to_cpu(cp->data_length);
1828 write_params.chan_opt = BT_ATT_CHAN_OPT_NONE;
1829
1830 if (bt_gatt_write(conn, &write_params) < 0) {
1831 bt_conn_unref(conn);
1832 return BTP_STATUS_FAILED;
1833 }
1834
1835 bt_conn_unref(conn);
1836 return BTP_STATUS_DELAY_REPLY;
1837 }
1838
write_long_rsp(struct bt_conn * conn,uint8_t err,struct bt_gatt_write_params * params)1839 static void write_long_rsp(struct bt_conn *conn, uint8_t err,
1840 struct bt_gatt_write_params *params)
1841 {
1842 tester_rsp_full(BTP_SERVICE_ID_GATT, BTP_GATT_WRITE_LONG, &err, sizeof(err));
1843 }
1844
write_long(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1845 static uint8_t write_long(const void *cmd, uint16_t cmd_len,
1846 void *rsp, uint16_t *rsp_len)
1847 {
1848 const struct btp_gatt_write_long_cmd *cp = cmd;
1849 struct bt_conn *conn;
1850
1851 if (cmd_len < sizeof(*cp) ||
1852 cmd_len != sizeof(*cp) + sys_le16_to_cpu(cp->data_length)) {
1853 return BTP_STATUS_FAILED;
1854 }
1855
1856 conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address);
1857 if (!conn) {
1858 return BTP_STATUS_FAILED;
1859 }
1860
1861 write_params.handle = sys_le16_to_cpu(cp->handle);
1862 write_params.func = write_long_rsp;
1863 write_params.offset = sys_le16_to_cpu(cp->offset);
1864 write_params.data = cp->data;
1865 write_params.length = sys_le16_to_cpu(cp->data_length);
1866 write_params.chan_opt = BT_ATT_CHAN_OPT_NONE;
1867
1868 if (bt_gatt_write(conn, &write_params) < 0) {
1869 bt_conn_unref(conn);
1870 return BTP_STATUS_FAILED;
1871 }
1872
1873 bt_conn_unref(conn);
1874 return BTP_STATUS_DELAY_REPLY;
1875 }
1876
1877 static struct bt_gatt_subscribe_params subscriptions[MAX_SUBSCRIPTIONS];
1878
find_subscription(uint16_t ccc_handle)1879 static struct bt_gatt_subscribe_params *find_subscription(uint16_t ccc_handle)
1880 {
1881 for (int i = 0; i < MAX_SUBSCRIPTIONS; i++) {
1882 if (subscriptions[i].ccc_handle == ccc_handle) {
1883 return &subscriptions[i];
1884 }
1885 }
1886
1887 return NULL;
1888 }
1889
1890 /* TODO there should be better way of determining max supported MTU */
1891 #define MAX_NOTIF_DATA (MIN(BT_L2CAP_RX_MTU, BT_L2CAP_TX_MTU) - 3)
1892
1893 static uint8_t ev_buf[sizeof(struct btp_gatt_notification_ev) + MAX_NOTIF_DATA];
1894
notify_func(struct bt_conn * conn,struct bt_gatt_subscribe_params * params,const void * data,uint16_t length)1895 static uint8_t notify_func(struct bt_conn *conn,
1896 struct bt_gatt_subscribe_params *params,
1897 const void *data, uint16_t length)
1898 {
1899 struct btp_gatt_notification_ev *ev = (void *) ev_buf;
1900
1901 if (!conn || !data) {
1902 LOG_DBG("Unsubscribed");
1903 (void)memset(params, 0, sizeof(*params));
1904 return BT_GATT_ITER_STOP;
1905 }
1906 ev->type = (uint8_t)params->value;
1907 ev->handle = sys_cpu_to_le16(params->value_handle);
1908
1909 length = MIN(length, MAX_NOTIF_DATA);
1910
1911 ev->data_length = sys_cpu_to_le16(length);
1912 memcpy(ev->data, data, length);
1913 bt_addr_le_copy(&ev->address, bt_conn_get_dst(conn));
1914
1915 tester_event(BTP_SERVICE_ID_GATT, BTP_GATT_EV_NOTIFICATION,
1916 ev, sizeof(*ev) + length);
1917
1918 return BT_GATT_ITER_CONTINUE;
1919 }
1920
discover_complete(struct bt_conn * conn,struct bt_gatt_discover_params * params)1921 static void discover_complete(struct bt_conn *conn,
1922 struct bt_gatt_discover_params *params)
1923 {
1924 struct bt_gatt_subscribe_params *subscription;
1925 uint8_t op, status;
1926
1927 subscription = find_subscription(discover_params.end_handle);
1928 __ASSERT_NO_MSG(subscription);
1929
1930 /* If no value handle it means that chrc has not been found */
1931 if (!subscription->value_handle) {
1932 status = BTP_STATUS_FAILED;
1933 goto fail;
1934 }
1935
1936 subscription->chan_opt = BT_ATT_CHAN_OPT_NONE;
1937 if (bt_gatt_subscribe(conn, subscription) < 0) {
1938 status = BTP_STATUS_FAILED;
1939 goto fail;
1940 }
1941
1942 status = BTP_STATUS_SUCCESS;
1943 fail:
1944 op = subscription->value == BT_GATT_CCC_NOTIFY ? BTP_GATT_CFG_NOTIFY :
1945 BTP_GATT_CFG_INDICATE;
1946
1947 if (status == BTP_STATUS_FAILED) {
1948 (void)memset(subscription, 0, sizeof(*subscription));
1949 }
1950
1951 tester_rsp(BTP_SERVICE_ID_GATT, op, status);
1952
1953 (void)memset(params, 0, sizeof(*params));
1954 }
1955
discover_func(struct bt_conn * conn,const struct bt_gatt_attr * attr,struct bt_gatt_discover_params * params)1956 static uint8_t discover_func(struct bt_conn *conn,
1957 const struct bt_gatt_attr *attr,
1958 struct bt_gatt_discover_params *params)
1959 {
1960 struct bt_gatt_subscribe_params *subscription;
1961
1962 if (!attr) {
1963 discover_complete(conn, params);
1964 return BT_GATT_ITER_STOP;
1965 }
1966
1967 subscription = find_subscription(discover_params.end_handle);
1968 __ASSERT_NO_MSG(subscription);
1969
1970 /* Characteristic Value Handle is the next handle beyond declaration */
1971 subscription->value_handle = attr->handle + 1;
1972
1973 /*
1974 * Continue characteristic discovery to get last characteristic
1975 * preceding this CCC descriptor
1976 */
1977 return BT_GATT_ITER_CONTINUE;
1978 }
1979
enable_subscription(struct bt_conn * conn,uint16_t ccc_handle,uint16_t value)1980 static int enable_subscription(struct bt_conn *conn, uint16_t ccc_handle,
1981 uint16_t value)
1982 {
1983 struct bt_gatt_subscribe_params *subscription;
1984
1985 /* find unused subscription */
1986 subscription = find_subscription(UNUSED_SUBSCRIBE_CCC_HANDLE);
1987 if (!subscription) {
1988 return -ENOMEM;
1989 }
1990
1991 /* if discovery is busy fail */
1992 if (discover_params.start_handle) {
1993 return -EBUSY;
1994 }
1995
1996 /* Discover Characteristic Value this CCC Descriptor refers to */
1997 discover_params.start_handle = BT_ATT_FIRST_ATTRIBUTE_HANDLE;
1998 discover_params.end_handle = ccc_handle;
1999 discover_params.type = BT_GATT_DISCOVER_CHARACTERISTIC;
2000 discover_params.func = discover_func;
2001 discover_params.chan_opt = BT_ATT_CHAN_OPT_NONE;
2002
2003 subscription->ccc_handle = ccc_handle;
2004 subscription->value = value;
2005 subscription->notify = notify_func;
2006
2007 /* require security level from time of subscription */
2008 subscription->min_security = bt_conn_get_security(conn);
2009
2010 return bt_gatt_discover(conn, &discover_params);
2011 }
2012
disable_subscription(struct bt_conn * conn,uint16_t ccc_handle)2013 static int disable_subscription(struct bt_conn *conn, uint16_t ccc_handle)
2014 {
2015 struct bt_gatt_subscribe_params *subscription;
2016
2017 /* Fail if CCC handle doesn't match */
2018 subscription = find_subscription(ccc_handle);
2019 if (!subscription) {
2020 LOG_ERR("CCC handle doesn't match");
2021 return -EINVAL;
2022 }
2023
2024 if (bt_gatt_unsubscribe(conn, subscription) < 0) {
2025 return -EBUSY;
2026 }
2027
2028 (void)memset(subscription, 0, sizeof(*subscription));
2029
2030 return 0;
2031 }
2032
config_subscription_notif(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)2033 static uint8_t config_subscription_notif(const void *cmd, uint16_t cmd_len,
2034 void *rsp, uint16_t *rsp_len)
2035 {
2036 const struct btp_gatt_cfg_notify_cmd *cp = cmd;
2037 struct bt_conn *conn;
2038 uint16_t ccc_handle = sys_le16_to_cpu(cp->ccc_handle);
2039 uint8_t status;
2040
2041 conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address);
2042 if (!conn) {
2043 return BTP_STATUS_FAILED;
2044 }
2045
2046 if (cp->enable) {
2047 /* on success response will be sent from callback */
2048 if (enable_subscription(conn, ccc_handle, BT_GATT_CCC_NOTIFY) == 0) {
2049 bt_conn_unref(conn);
2050 return BTP_STATUS_DELAY_REPLY;
2051 }
2052
2053 status = BTP_STATUS_FAILED;
2054 } else {
2055 if (disable_subscription(conn, ccc_handle) < 0) {
2056 status = BTP_STATUS_FAILED;
2057 } else {
2058 status = BTP_STATUS_SUCCESS;
2059 }
2060 }
2061
2062 LOG_DBG("Config notification subscription status %u", status);
2063
2064 bt_conn_unref(conn);
2065 return status;
2066 }
2067
config_subscription_ind(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)2068 static uint8_t config_subscription_ind(const void *cmd, uint16_t cmd_len,
2069 void *rsp, uint16_t *rsp_len)
2070 {
2071 const struct btp_gatt_cfg_notify_cmd *cp = cmd;
2072 struct bt_conn *conn;
2073 uint16_t ccc_handle = sys_le16_to_cpu(cp->ccc_handle);
2074 uint8_t status;
2075
2076 conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address);
2077 if (!conn) {
2078 return BTP_STATUS_FAILED;
2079 }
2080
2081 if (cp->enable) {
2082 /* on success response will be sent from callback */
2083 if (enable_subscription(conn, ccc_handle, BT_GATT_CCC_INDICATE) == 0) {
2084 bt_conn_unref(conn);
2085 return BTP_STATUS_DELAY_REPLY;
2086 }
2087
2088 status = BTP_STATUS_FAILED;
2089 } else {
2090 if (disable_subscription(conn, ccc_handle) < 0) {
2091 status = BTP_STATUS_FAILED;
2092 } else {
2093 status = BTP_STATUS_SUCCESS;
2094 }
2095 }
2096
2097 LOG_DBG("Config indication subscription status %u", status);
2098
2099 bt_conn_unref(conn);
2100 return status;
2101 }
2102
2103 #if defined(CONFIG_BT_GATT_NOTIFY_MULTIPLE)
notify_cb(struct bt_conn * conn,void * user_data)2104 static void notify_cb(struct bt_conn *conn, void *user_data)
2105 {
2106 LOG_DBG("Nofication sent");
2107 }
2108
notify_mult(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)2109 static uint8_t notify_mult(const void *cmd, uint16_t cmd_len,
2110 void *rsp, uint16_t *rsp_len)
2111 {
2112 const struct btp_gatt_cfg_notify_mult_cmd *cp = cmd;
2113 const size_t max_cnt = CONFIG_BT_L2CAP_TX_BUF_COUNT;
2114 struct bt_gatt_notify_params params[max_cnt];
2115 struct bt_conn *conn;
2116 const size_t min_cnt = 1U;
2117 int err = 0;
2118 uint16_t attr_data_len = 0;
2119
2120 if ((cmd_len < sizeof(*cp)) ||
2121 (cmd_len != sizeof(*cp) + (cp->cnt * sizeof(cp->attr_id[0])))) {
2122 return BTP_STATUS_FAILED;
2123 }
2124
2125 if (!IN_RANGE(cp->cnt, min_cnt, max_cnt)) {
2126 LOG_ERR("Invalid count value %d (range %zu to %zu)",
2127 cp->cnt, min_cnt, max_cnt);
2128
2129 return BTP_STATUS_FAILED;
2130 }
2131
2132 conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address);
2133 if (!conn) {
2134 return BTP_STATUS_FAILED;
2135 }
2136
2137 (void)memset(params, 0, sizeof(params));
2138
2139 for (uint16_t i = 0U; i < cp->cnt; i++) {
2140 struct bt_gatt_attr attr = server_db[cp->attr_id[i] -
2141 server_db[0].handle];
2142
2143 attr_data_len = strtoul(attr.user_data, NULL, 16);
2144 params[i].uuid = 0;
2145 params[i].attr = &attr;
2146 params[i].data = &attr.user_data;
2147 params[i].len = attr_data_len;
2148 params[i].func = notify_cb;
2149 params[i].user_data = NULL;
2150 }
2151
2152 err = bt_gatt_notify_multiple(conn, cp->cnt, params);
2153 if (err != 0) {
2154 LOG_ERR("bt_gatt_notify_multiple failed: %d", err);
2155 bt_conn_unref(conn);
2156 return BTP_STATUS_FAILED;
2157 }
2158
2159 LOG_DBG("Send %u notifications", cp->cnt);
2160 bt_conn_unref(conn);
2161 return BTP_STATUS_SUCCESS;
2162 }
2163 #endif /* CONFIG_BT_GATT_NOTIFY_MULTIPLE */
2164
2165 struct get_attrs_foreach_data {
2166 struct net_buf_simple *buf;
2167 const struct bt_uuid *uuid;
2168 uint8_t count;
2169 };
2170
get_attrs_rp(const struct bt_gatt_attr * attr,uint16_t handle,void * user_data)2171 static uint8_t get_attrs_rp(const struct bt_gatt_attr *attr, uint16_t handle,
2172 void *user_data)
2173 {
2174 struct get_attrs_foreach_data *foreach = user_data;
2175 struct btp_gatt_attr *gatt_attr;
2176
2177 if (foreach->uuid && bt_uuid_cmp(foreach->uuid, attr->uuid)) {
2178
2179 return BT_GATT_ITER_CONTINUE;
2180 }
2181
2182 gatt_attr = net_buf_simple_add(foreach->buf, sizeof(*gatt_attr));
2183 gatt_attr->handle = sys_cpu_to_le16(handle);
2184 gatt_attr->permission = attr->perm;
2185
2186 if (attr->uuid->type == BT_UUID_TYPE_16) {
2187 gatt_attr->type_length = 2U;
2188 net_buf_simple_add_le16(foreach->buf,
2189 BT_UUID_16(attr->uuid)->val);
2190 } else {
2191 gatt_attr->type_length = 16U;
2192 net_buf_simple_add_mem(foreach->buf,
2193 BT_UUID_128(attr->uuid)->val,
2194 gatt_attr->type_length);
2195 }
2196
2197 foreach->count++;
2198
2199 return BT_GATT_ITER_CONTINUE;
2200 }
2201
get_attrs(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)2202 static uint8_t get_attrs(const void *cmd, uint16_t cmd_len,
2203 void *rsp, uint16_t *rsp_len)
2204 {
2205 const struct btp_gatt_get_attributes_cmd *cp = cmd;
2206 struct btp_gatt_get_attributes_rp *rp = rsp;
2207 struct net_buf_simple *buf = NET_BUF_SIMPLE(BTP_DATA_MAX_SIZE - sizeof(*rp));
2208 struct get_attrs_foreach_data foreach;
2209 uint16_t start_handle, end_handle;
2210 union uuid search_uuid;
2211
2212 if ((cmd_len < sizeof(*cp)) ||
2213 (cmd_len != sizeof(*cp) + cp->type_length)) {
2214 return BTP_STATUS_FAILED;
2215 }
2216
2217 start_handle = sys_le16_to_cpu(cp->start_handle);
2218 end_handle = sys_le16_to_cpu(cp->end_handle);
2219
2220 if (cp->type_length) {
2221 char uuid_str[BT_UUID_STR_LEN];
2222
2223 if (btp2bt_uuid(cp->type, cp->type_length, &search_uuid.uuid)) {
2224 return BTP_STATUS_FAILED;
2225 }
2226
2227 bt_uuid_to_str(&search_uuid.uuid, uuid_str, sizeof(uuid_str));
2228 LOG_DBG("start 0x%04x end 0x%04x, uuid %s", start_handle,
2229 end_handle, uuid_str);
2230
2231 foreach.uuid = &search_uuid.uuid;
2232 } else {
2233 LOG_DBG("start 0x%04x end 0x%04x", start_handle, end_handle);
2234
2235 foreach.uuid = NULL;
2236 }
2237
2238 net_buf_simple_init(buf, 0);
2239
2240 foreach.buf = buf;
2241 foreach.count = 0U;
2242
2243 bt_gatt_foreach_attr(start_handle, end_handle, get_attrs_rp, &foreach);
2244
2245 (void)memcpy(rp->attrs, buf->data, buf->len);
2246 rp->attrs_count = foreach.count;
2247
2248 *rsp_len = sizeof(*rp) + buf->len;
2249
2250 return BTP_STATUS_SUCCESS;
2251 }
2252
err_to_att(int err)2253 static uint8_t err_to_att(int err)
2254 {
2255 if (err < 0 && err >= -0xff) {
2256 return -err;
2257 }
2258
2259 return BT_ATT_ERR_UNLIKELY;
2260 }
2261
get_attr_val_rp(const struct bt_gatt_attr * attr,uint16_t handle,void * user_data)2262 static uint8_t get_attr_val_rp(const struct bt_gatt_attr *attr, uint16_t handle,
2263 void *user_data)
2264 {
2265 struct get_attr_data *u_data = user_data;
2266 struct net_buf_simple *buf = u_data->buf;
2267 struct bt_conn *conn = u_data->conn;
2268 struct btp_gatt_get_attribute_value_rp *rp;
2269 ssize_t read, to_read;
2270
2271 rp = net_buf_simple_add(buf, sizeof(*rp));
2272 rp->value_length = 0x0000;
2273 rp->att_response = BT_ATT_ERR_SUCCESS;
2274
2275 do {
2276 to_read = net_buf_simple_tailroom(buf);
2277
2278 if (!attr->read) {
2279 rp->att_response = BT_ATT_ERR_READ_NOT_PERMITTED;
2280 break;
2281 }
2282
2283 read = attr->read(conn, attr, buf->data + buf->len, to_read,
2284 rp->value_length);
2285 if (read < 0) {
2286 rp->att_response = err_to_att(read);
2287 break;
2288 }
2289
2290 rp->value_length += read;
2291
2292 net_buf_simple_add(buf, read);
2293 } while (read == to_read);
2294
2295 /* use userdata only for tester own attributes */
2296 if (IS_ARRAY_ELEMENT(server_db, attr)) {
2297 const struct gatt_value *value = attr->user_data;
2298
2299 if ((rp->att_response == BT_ATT_ERR_SUCCESS) && (value->enc_key_size > 0)) {
2300 /*
2301 * If attribute has enc_key_size set to non-zero value
2302 * it means that it is used for testing encryption key size
2303 * error on GATT database access and we need to report it
2304 * when local database is read.
2305 *
2306 * It is min key size and is used to trigger error on GATT operation
2307 * when PTS pairs with small key size (typically it is set it to 16
2308 * for specified test characteristics, while PTS pairs with keysize
2309 * set to <16, but is can be of any 7-16 value)
2310 *
2311 * Depending on test, PTS may ask about handle during connection or
2312 * prior to connection. If former we validate keysize against
2313 * current connection, if latter we just report error status.
2314 *
2315 * Note that we report expected error and data as this is used for
2316 * PTS validation and not actual GATT operation.
2317 */
2318 if (conn) {
2319 if (value->enc_key_size > bt_conn_enc_key_size(conn)) {
2320 rp->att_response = BT_ATT_ERR_ENCRYPTION_KEY_SIZE;
2321 }
2322 } else {
2323 rp->att_response = BT_ATT_ERR_ENCRYPTION_KEY_SIZE;
2324 }
2325 }
2326 }
2327
2328 return BT_GATT_ITER_STOP;
2329 }
2330
get_attr_val(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)2331 static uint8_t get_attr_val(const void *cmd, uint16_t cmd_len,
2332 void *rsp, uint16_t *rsp_len)
2333 {
2334 const struct btp_gatt_get_attribute_value_cmd *cp = cmd;
2335 struct net_buf_simple *buf = NET_BUF_SIMPLE(BTP_DATA_MAX_SIZE);
2336 uint16_t handle = sys_le16_to_cpu(cp->handle);
2337 struct bt_conn *conn;
2338
2339 conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address);
2340
2341 net_buf_simple_init(buf, 0);
2342
2343 struct get_attr_data cb_data = { .buf = buf, .conn = conn };
2344
2345 bt_gatt_foreach_attr(handle, handle, get_attr_val_rp, &cb_data);
2346
2347 if (buf->len) {
2348 (void)memcpy(rsp, buf->data, buf->len);
2349 *rsp_len = buf->len;
2350 return BTP_STATUS_SUCCESS;
2351 }
2352
2353 return BTP_STATUS_FAILED;
2354 }
2355
2356 static const struct bt_uuid_128 test_uuid = BT_UUID_INIT_128(
2357 0x94, 0x99, 0xb6, 0xa9, 0xcd, 0x1c, 0x42, 0x95,
2358 0xb2, 0x07, 0x2f, 0x7f, 0xec, 0xc0, 0xc7, 0x5b);
2359
2360 static struct bt_gatt_attr test_attrs[] = {
2361 BT_GATT_PRIMARY_SERVICE(&test_uuid),
2362 };
2363
2364 static struct bt_gatt_service test_service = BT_GATT_SERVICE(test_attrs);
2365
change_database(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)2366 static uint8_t change_database(const void *cmd, uint16_t cmd_len,
2367 void *rsp, uint16_t *rsp_len)
2368 {
2369 const struct btp_gatt_change_db_cmd *cp = cmd;
2370 static bool test_service_registered;
2371 int err;
2372
2373 /* currently support only "any" handles */
2374 if (cp->start_handle > 0 || cp->end_handle > 0) {
2375 return BTP_STATUS_FAILED;
2376 }
2377
2378 switch (cp->operation) {
2379 case BTP_GATT_CHANGE_DB_ADD:
2380 if (test_service_registered) {
2381 return BTP_STATUS_FAILED;
2382 }
2383
2384 err = bt_gatt_service_register(&test_service);
2385 break;
2386 case BTP_GATT_CHANGE_DB_REMOVE:
2387 if (!test_service_registered) {
2388 return BTP_STATUS_FAILED;
2389 }
2390
2391 err = bt_gatt_service_unregister(&test_service);
2392 break;
2393 case BTP_GATT_CHANGE_DB_ANY:
2394 if (test_service_registered) {
2395 err = bt_gatt_service_unregister(&test_service);
2396 } else {
2397 err = bt_gatt_service_register(&test_service);
2398 }
2399 break;
2400 default:
2401 return BTP_STATUS_FAILED;
2402 }
2403
2404 if (err) {
2405 return BTP_STATUS_FAILED;
2406 }
2407
2408 test_service_registered = !test_service_registered;
2409
2410 return BTP_STATUS_SUCCESS;
2411 }
2412
eatt_connect(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)2413 static uint8_t eatt_connect(const void *cmd, uint16_t cmd_len,
2414 void *rsp, uint16_t *rsp_len)
2415 {
2416 const struct btp_gatt_eatt_connect_cmd *cp = cmd;
2417 struct bt_conn *conn;
2418 int err;
2419
2420 conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address);
2421 if (!conn) {
2422 return BTP_STATUS_FAILED;
2423 }
2424
2425 err = bt_eatt_connect(conn, cp->num_channels);
2426 if (err) {
2427 bt_conn_unref(conn);
2428 return BTP_STATUS_FAILED;
2429 }
2430
2431 bt_conn_unref(conn);
2432 return BTP_STATUS_SUCCESS;
2433 }
2434
2435 static const struct btp_handler handlers[] = {
2436 {
2437 .opcode = BTP_GATT_READ_SUPPORTED_COMMANDS,
2438 .index = BTP_INDEX_NONE,
2439 .expect_len = 0,
2440 .func = supported_commands,
2441 },
2442 {
2443 .opcode = BTP_GATT_ADD_SERVICE,
2444 .expect_len = BTP_HANDLER_LENGTH_VARIABLE,
2445 .func = add_service,
2446 },
2447 {
2448 .opcode = BTP_GATT_ADD_CHARACTERISTIC,
2449 .expect_len = BTP_HANDLER_LENGTH_VARIABLE,
2450 .func = add_characteristic,
2451 },
2452 {
2453 .opcode = BTP_GATT_ADD_DESCRIPTOR,
2454 .expect_len = BTP_HANDLER_LENGTH_VARIABLE,
2455 .func = add_descriptor,
2456 },
2457 {
2458 .opcode = BTP_GATT_ADD_INCLUDED_SERVICE,
2459 .expect_len = sizeof(struct btp_gatt_add_included_service_cmd),
2460 .func = add_included,
2461 },
2462 {
2463 .opcode = BTP_GATT_SET_VALUE,
2464 .expect_len = BTP_HANDLER_LENGTH_VARIABLE,
2465 .func = set_value,
2466 },
2467 {
2468 .opcode = BTP_GATT_START_SERVER,
2469 .expect_len = 0,
2470 .func = start_server,
2471 },
2472 {
2473 .opcode = BTP_GATT_SET_ENC_KEY_SIZE,
2474 .expect_len = sizeof(struct btp_gatt_set_enc_key_size_cmd),
2475 .func = set_enc_key_size,
2476 },
2477 {
2478 .opcode = BTP_GATT_EXCHANGE_MTU,
2479 .expect_len = sizeof(struct btp_gatt_exchange_mtu_cmd),
2480 .func = exchange_mtu,
2481 },
2482 {
2483 .opcode = BTP_GATT_DISC_ALL_PRIM,
2484 .expect_len = sizeof(struct btp_gatt_disc_all_prim_cmd),
2485 .func = disc_all_prim,
2486 },
2487 {
2488 .opcode = BTP_GATT_DISC_PRIM_UUID,
2489 .expect_len = BTP_HANDLER_LENGTH_VARIABLE,
2490 .func = disc_prim_uuid,
2491 },
2492 {
2493 .opcode = BTP_GATT_FIND_INCLUDED,
2494 .expect_len = sizeof(struct btp_gatt_find_included_cmd),
2495 .func = find_included,
2496 },
2497 {
2498 .opcode = BTP_GATT_DISC_ALL_CHRC,
2499 .expect_len = sizeof(struct btp_gatt_disc_all_chrc_cmd),
2500 .func = disc_all_chrc,
2501 },
2502 {
2503 .opcode = BTP_GATT_DISC_CHRC_UUID,
2504 .expect_len = BTP_HANDLER_LENGTH_VARIABLE,
2505 .func = disc_chrc_uuid,
2506 },
2507 {
2508 .opcode = BTP_GATT_DISC_ALL_DESC,
2509 .expect_len = sizeof(struct btp_gatt_disc_all_desc_cmd),
2510 .func = disc_all_desc,
2511 },
2512 {
2513 .opcode = BTP_GATT_READ,
2514 .expect_len = sizeof(struct btp_gatt_read_cmd),
2515 .func = read_data,
2516 },
2517 {
2518 .opcode = BTP_GATT_READ_UUID,
2519 .expect_len = BTP_HANDLER_LENGTH_VARIABLE,
2520 .func = read_uuid,
2521 },
2522 {
2523 .opcode = BTP_GATT_READ_LONG,
2524 .expect_len = sizeof(struct btp_gatt_read_long_cmd),
2525 .func = read_long,
2526 },
2527 {
2528 .opcode = BTP_GATT_READ_MULTIPLE,
2529 .expect_len = BTP_HANDLER_LENGTH_VARIABLE,
2530 .func = read_multiple,
2531 },
2532 {
2533 .opcode = BTP_GATT_WRITE_WITHOUT_RSP,
2534 .expect_len = BTP_HANDLER_LENGTH_VARIABLE,
2535 .func = write_without_rsp,
2536 },
2537 {
2538 .opcode = BTP_GATT_SIGNED_WRITE_WITHOUT_RSP,
2539 .expect_len = BTP_HANDLER_LENGTH_VARIABLE,
2540 .func = write_signed_without_rsp,
2541 },
2542 {
2543 .opcode = BTP_GATT_WRITE,
2544 .expect_len = BTP_HANDLER_LENGTH_VARIABLE,
2545 .func = write_data,
2546 },
2547 {
2548 .opcode = BTP_GATT_WRITE_LONG,
2549 .expect_len = BTP_HANDLER_LENGTH_VARIABLE,
2550 .func = write_long,
2551 },
2552 {
2553 .opcode = BTP_GATT_CFG_NOTIFY,
2554 .expect_len = sizeof(struct btp_gatt_cfg_notify_cmd),
2555 .func = config_subscription_notif,
2556 },
2557 {
2558 .opcode = BTP_GATT_CFG_INDICATE,
2559 .expect_len = sizeof(struct btp_gatt_cfg_notify_cmd),
2560 .func = config_subscription_ind,
2561 },
2562 {
2563 .opcode = BTP_GATT_GET_ATTRIBUTES,
2564 .expect_len = BTP_HANDLER_LENGTH_VARIABLE,
2565 .func = get_attrs,
2566 },
2567 {
2568 .opcode = BTP_GATT_GET_ATTRIBUTE_VALUE,
2569 .expect_len = sizeof(struct btp_gatt_get_attribute_value_cmd),
2570 .func = get_attr_val,
2571 },
2572 {
2573 .opcode = BTP_GATT_CHANGE_DB,
2574 .expect_len = sizeof(struct btp_gatt_change_db_cmd),
2575 .func = change_database,
2576 },
2577 {
2578 .opcode = BTP_GATT_EATT_CONNECT,
2579 .expect_len = sizeof(struct btp_gatt_eatt_connect_cmd),
2580 .func = eatt_connect,
2581 },
2582 {
2583 .opcode = BTP_GATT_READ_MULTIPLE_VAR,
2584 .expect_len = BTP_HANDLER_LENGTH_VARIABLE,
2585 .func = read_multiple_var,
2586 },
2587 {
2588 .opcode = BTP_GATT_NOTIFY_MULTIPLE,
2589 .expect_len = BTP_HANDLER_LENGTH_VARIABLE,
2590 .func = notify_mult,
2591 },
2592 };
2593
tester_init_gatt(void)2594 uint8_t tester_init_gatt(void)
2595 {
2596 server_buf = net_buf_alloc(&server_pool, K_NO_WAIT);
2597 if (!server_buf) {
2598 return BTP_STATUS_FAILED;
2599 }
2600
2601 net_buf_reserve(server_buf, SERVER_BUF_SIZE);
2602
2603 tester_register_command_handlers(BTP_SERVICE_ID_GATT, handlers,
2604 ARRAY_SIZE(handlers));
2605
2606 return BTP_STATUS_SUCCESS;
2607 }
2608
tester_unregister_gatt(void)2609 uint8_t tester_unregister_gatt(void)
2610 {
2611 return BTP_STATUS_SUCCESS;
2612 }
2613