1 /* gatt.c - Generic Attribute Profile handling */
2
3 /*
4 * Copyright (c) 2015-2016 Intel Corporation
5 *
6 * SPDX-License-Identifier: Apache-2.0
7 */
8
9 #include <zephyr/kernel.h>
10 #include <string.h>
11 #include <errno.h>
12 #include <stdbool.h>
13 #include <stdlib.h>
14 #include <zephyr/sys/atomic.h>
15 #include <zephyr/sys/byteorder.h>
16 #include <zephyr/sys/iterable_sections.h>
17 #include <zephyr/sys/util.h>
18 #include <zephyr/sys/check.h>
19
20 #include <zephyr/settings/settings.h>
21
22 #if defined(CONFIG_BT_GATT_CACHING)
23 #include <tinycrypt/constants.h>
24 #include <tinycrypt/utils.h>
25 #include <tinycrypt/aes.h>
26 #include <tinycrypt/cmac_mode.h>
27 #include <tinycrypt/ccm_mode.h>
28 #endif /* CONFIG_BT_GATT_CACHING */
29
30 #include <zephyr/bluetooth/hci.h>
31 #include <zephyr/bluetooth/bluetooth.h>
32 #include <zephyr/bluetooth/conn.h>
33 #include <zephyr/bluetooth/uuid.h>
34 #include <zephyr/bluetooth/gatt.h>
35 #include <zephyr/drivers/bluetooth/hci_driver.h>
36
37 #include "common/bt_str.h"
38
39 #include "hci_core.h"
40 #include "conn_internal.h"
41 #include "keys.h"
42 #include "l2cap_internal.h"
43 #include "att_internal.h"
44 #include "smp.h"
45 #include "settings.h"
46 #include "gatt_internal.h"
47 #include "long_wq.h"
48
49 #define LOG_LEVEL CONFIG_BT_GATT_LOG_LEVEL
50 #include <zephyr/logging/log.h>
51 LOG_MODULE_REGISTER(bt_gatt);
52
53 #define SC_TIMEOUT K_MSEC(10)
54 #define DB_HASH_TIMEOUT K_MSEC(10)
55
56 static uint16_t last_static_handle;
57
58 /* Persistent storage format for GATT CCC */
59 struct ccc_store {
60 uint16_t handle;
61 uint16_t value;
62 };
63
64 struct gatt_sub {
65 uint8_t id;
66 bt_addr_le_t peer;
67 sys_slist_t list;
68 };
69
70 #if defined(CONFIG_BT_GATT_CLIENT)
71 #define SUB_MAX (CONFIG_BT_MAX_PAIRED + CONFIG_BT_MAX_CONN)
72 #else
73 #define SUB_MAX 0
74 #endif /* CONFIG_BT_GATT_CLIENT */
75
76 /**
77 * Entry x is free for reuse whenever (subscriptions[x].peer == BT_ADDR_LE_ANY).
78 * Invariant: (sys_slist_is_empty(subscriptions[x].list))
79 * <=> (subscriptions[x].peer == BT_ADDR_LE_ANY).
80 */
81 static struct gatt_sub subscriptions[SUB_MAX];
82 static sys_slist_t callback_list;
83
84 #if defined(CONFIG_BT_GATT_DYNAMIC_DB)
85 static sys_slist_t db;
86 #endif /* CONFIG_BT_GATT_DYNAMIC_DB */
87
88 enum gatt_global_flags {
89 GATT_INITIALIZED,
90 GATT_SERVICE_INITIALIZED,
91
92 GATT_NUM_FLAGS,
93 };
94
95 static ATOMIC_DEFINE(gatt_flags, GATT_NUM_FLAGS);
96
read_name(struct bt_conn * conn,const struct bt_gatt_attr * attr,void * buf,uint16_t len,uint16_t offset)97 static ssize_t read_name(struct bt_conn *conn, const struct bt_gatt_attr *attr,
98 void *buf, uint16_t len, uint16_t offset)
99 {
100 const char *name = bt_get_name();
101
102 return bt_gatt_attr_read(conn, attr, buf, len, offset, name,
103 strlen(name));
104 }
105
106 #if defined(CONFIG_BT_DEVICE_NAME_GATT_WRITABLE)
107
write_name(struct bt_conn * conn,const struct bt_gatt_attr * attr,const void * buf,uint16_t len,uint16_t offset,uint8_t flags)108 static ssize_t write_name(struct bt_conn *conn, const struct bt_gatt_attr *attr,
109 const void *buf, uint16_t len, uint16_t offset,
110 uint8_t flags)
111 {
112 char value[CONFIG_BT_DEVICE_NAME_MAX] = {};
113
114 if (offset >= sizeof(value)) {
115 return BT_GATT_ERR(BT_ATT_ERR_INVALID_OFFSET);
116 }
117
118 if (offset + len >= sizeof(value)) {
119 return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
120 }
121
122 memcpy(value, buf, len);
123
124 bt_set_name(value);
125
126 return len;
127 }
128
129 #endif /* CONFIG_BT_DEVICE_NAME_GATT_WRITABLE */
130
read_appearance(struct bt_conn * conn,const struct bt_gatt_attr * attr,void * buf,uint16_t len,uint16_t offset)131 static ssize_t read_appearance(struct bt_conn *conn,
132 const struct bt_gatt_attr *attr, void *buf,
133 uint16_t len, uint16_t offset)
134 {
135 uint16_t appearance = sys_cpu_to_le16(bt_get_appearance());
136
137 return bt_gatt_attr_read(conn, attr, buf, len, offset, &appearance,
138 sizeof(appearance));
139 }
140
141 #if defined(CONFIG_BT_DEVICE_APPEARANCE_GATT_WRITABLE)
write_appearance(struct bt_conn * conn,const struct bt_gatt_attr * attr,const void * buf,uint16_t len,uint16_t offset,uint8_t flags)142 static ssize_t write_appearance(struct bt_conn *conn, const struct bt_gatt_attr *attr,
143 const void *buf, uint16_t len, uint16_t offset,
144 uint8_t flags)
145 {
146 uint16_t appearance_le = sys_cpu_to_le16(bt_get_appearance());
147 char * const appearance_le_bytes = (char *)&appearance_le;
148 uint16_t appearance;
149 int err;
150
151 if (offset >= sizeof(appearance_le)) {
152 return BT_GATT_ERR(BT_ATT_ERR_INVALID_OFFSET);
153 }
154
155 if ((offset + len) > sizeof(appearance_le)) {
156 return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
157 }
158
159 memcpy(&appearance_le_bytes[offset], buf, len);
160 appearance = sys_le16_to_cpu(appearance_le);
161
162 err = bt_set_appearance(appearance);
163
164 if (err) {
165 return BT_GATT_ERR(BT_ATT_ERR_UNLIKELY);
166 }
167
168 return len;
169 }
170 #endif /* CONFIG_BT_DEVICE_APPEARANCE_GATT_WRITABLE */
171
172 #if CONFIG_BT_DEVICE_APPEARANCE_GATT_WRITABLE
173 #define GAP_APPEARANCE_PROPS (BT_GATT_CHRC_READ | BT_GATT_CHRC_WRITE)
174 #define GAP_APPEARANCE_PERMS (BT_GATT_PERM_READ | BT_GATT_PERM_WRITE_AUTHEN)
175 #define GAP_APPEARANCE_WRITE_HANDLER write_appearance
176 #else
177 #define GAP_APPEARANCE_PROPS BT_GATT_CHRC_READ
178 #define GAP_APPEARANCE_PERMS BT_GATT_PERM_READ
179 #define GAP_APPEARANCE_WRITE_HANDLER NULL
180 #endif
181
182 #if defined (CONFIG_BT_GAP_PERIPHERAL_PREF_PARAMS)
183 /* This checks if the range entered is valid */
184 BUILD_ASSERT(!(CONFIG_BT_PERIPHERAL_PREF_MIN_INT > 3200 &&
185 CONFIG_BT_PERIPHERAL_PREF_MIN_INT < 0xffff));
186 BUILD_ASSERT(!(CONFIG_BT_PERIPHERAL_PREF_MAX_INT > 3200 &&
187 CONFIG_BT_PERIPHERAL_PREF_MAX_INT < 0xffff));
188 BUILD_ASSERT(!(CONFIG_BT_PERIPHERAL_PREF_TIMEOUT > 3200 &&
189 CONFIG_BT_PERIPHERAL_PREF_TIMEOUT < 0xffff));
190 BUILD_ASSERT((CONFIG_BT_PERIPHERAL_PREF_MIN_INT == 0xffff) ||
191 (CONFIG_BT_PERIPHERAL_PREF_MIN_INT <=
192 CONFIG_BT_PERIPHERAL_PREF_MAX_INT));
193 BUILD_ASSERT((CONFIG_BT_PERIPHERAL_PREF_TIMEOUT * 4U) >
194 ((1U + CONFIG_BT_PERIPHERAL_PREF_LATENCY) *
195 CONFIG_BT_PERIPHERAL_PREF_MAX_INT));
196
read_ppcp(struct bt_conn * conn,const struct bt_gatt_attr * attr,void * buf,uint16_t len,uint16_t offset)197 static ssize_t read_ppcp(struct bt_conn *conn, const struct bt_gatt_attr *attr,
198 void *buf, uint16_t len, uint16_t offset)
199 {
200 struct __packed {
201 uint16_t min_int;
202 uint16_t max_int;
203 uint16_t latency;
204 uint16_t timeout;
205 } ppcp;
206
207 ppcp.min_int = sys_cpu_to_le16(CONFIG_BT_PERIPHERAL_PREF_MIN_INT);
208 ppcp.max_int = sys_cpu_to_le16(CONFIG_BT_PERIPHERAL_PREF_MAX_INT);
209 ppcp.latency = sys_cpu_to_le16(CONFIG_BT_PERIPHERAL_PREF_LATENCY);
210 ppcp.timeout = sys_cpu_to_le16(CONFIG_BT_PERIPHERAL_PREF_TIMEOUT);
211
212 return bt_gatt_attr_read(conn, attr, buf, len, offset, &ppcp,
213 sizeof(ppcp));
214 }
215 #endif
216
217 #if defined(CONFIG_BT_CENTRAL) && defined(CONFIG_BT_PRIVACY)
read_central_addr_res(struct bt_conn * conn,const struct bt_gatt_attr * attr,void * buf,uint16_t len,uint16_t offset)218 static ssize_t read_central_addr_res(struct bt_conn *conn,
219 const struct bt_gatt_attr *attr, void *buf,
220 uint16_t len, uint16_t offset)
221 {
222 uint8_t central_addr_res = BT_GATT_CENTRAL_ADDR_RES_SUPP;
223
224 return bt_gatt_attr_read(conn, attr, buf, len, offset,
225 ¢ral_addr_res, sizeof(central_addr_res));
226 }
227 #endif /* CONFIG_BT_CENTRAL && CONFIG_BT_PRIVACY */
228
229 BT_GATT_SERVICE_DEFINE(_2_gap_svc,
230 BT_GATT_PRIMARY_SERVICE(BT_UUID_GAP),
231 #if defined(CONFIG_BT_DEVICE_NAME_GATT_WRITABLE)
232 /* Require pairing for writes to device name */
233 BT_GATT_CHARACTERISTIC(BT_UUID_GAP_DEVICE_NAME,
234 BT_GATT_CHRC_READ | BT_GATT_CHRC_WRITE,
235 BT_GATT_PERM_READ |
236 #if defined(CONFIG_DEVICE_NAME_GATT_WRITABLE_AUTHEN)
237 BT_GATT_PERM_WRITE_AUTHEN,
238 #elif defined(CONFIG_DEVICE_NAME_GATT_WRITABLE_ENCRYPT)
239 BT_GATT_PERM_WRITE_ENCRYPT,
240 #else
241 BT_GATT_PERM_WRITE,
242 #endif
243 read_name, write_name, bt_dev.name),
244 #else
245 BT_GATT_CHARACTERISTIC(BT_UUID_GAP_DEVICE_NAME, BT_GATT_CHRC_READ,
246 BT_GATT_PERM_READ, read_name, NULL, NULL),
247 #endif /* CONFIG_BT_DEVICE_NAME_GATT_WRITABLE */
248 BT_GATT_CHARACTERISTIC(BT_UUID_GAP_APPEARANCE, GAP_APPEARANCE_PROPS,
249 GAP_APPEARANCE_PERMS, read_appearance,
250 GAP_APPEARANCE_WRITE_HANDLER, NULL),
251 #if defined(CONFIG_BT_CENTRAL) && defined(CONFIG_BT_PRIVACY)
252 BT_GATT_CHARACTERISTIC(BT_UUID_CENTRAL_ADDR_RES,
253 BT_GATT_CHRC_READ, BT_GATT_PERM_READ,
254 read_central_addr_res, NULL, NULL),
255 #endif /* CONFIG_BT_CENTRAL && CONFIG_BT_PRIVACY */
256 #if defined(CONFIG_BT_GAP_PERIPHERAL_PREF_PARAMS)
257 BT_GATT_CHARACTERISTIC(BT_UUID_GAP_PPCP, BT_GATT_CHRC_READ,
258 BT_GATT_PERM_READ, read_ppcp, NULL, NULL),
259 #endif
260 );
261
262 struct sc_data {
263 uint16_t start;
264 uint16_t end;
265 } __packed;
266
267 struct gatt_sc_cfg {
268 uint8_t id;
269 bt_addr_le_t peer;
270 struct {
271 uint16_t start;
272 uint16_t end;
273 } data;
274 };
275
276 #if defined(CONFIG_BT_GATT_SERVICE_CHANGED)
277 #define SC_CFG_MAX (CONFIG_BT_MAX_PAIRED + CONFIG_BT_MAX_CONN)
278 #else
279 #define SC_CFG_MAX 0
280 #endif
281 static struct gatt_sc_cfg sc_cfg[SC_CFG_MAX];
282 BUILD_ASSERT(sizeof(struct sc_data) == sizeof(sc_cfg[0].data));
283
284 enum {
285 SC_RANGE_CHANGED, /* SC range changed */
286 SC_INDICATE_PENDING, /* SC indicate pending */
287 SC_LOAD, /* SC has been loaded from settings */
288
289 DB_HASH_VALID, /* Database hash needs to be calculated */
290 DB_HASH_LOAD, /* Database hash loaded from settings. */
291 DB_HASH_LOAD_PROC, /* DB hash loaded from settings has been processed. */
292
293 /* Total number of flags - must be at the end of the enum */
294 SC_NUM_FLAGS,
295 };
296
297 #if defined(CONFIG_BT_GATT_SERVICE_CHANGED)
298 static struct gatt_sc {
299 struct bt_gatt_indicate_params params;
300 uint16_t start;
301 uint16_t end;
302 struct k_work_delayable work;
303
304 ATOMIC_DEFINE(flags, SC_NUM_FLAGS);
305 } gatt_sc;
306 #endif /* defined(CONFIG_BT_GATT_SERVICE_CHANGED) */
307
308 #if defined(CONFIG_BT_GATT_CACHING)
309 static struct db_hash {
310 uint8_t hash[16];
311 #if defined(CONFIG_BT_SETTINGS)
312 uint8_t stored_hash[16];
313 #endif
314 struct k_work_delayable work;
315 struct k_work_sync sync;
316 } db_hash;
317 #endif
318
find_sc_cfg(uint8_t id,const bt_addr_le_t * addr)319 static struct gatt_sc_cfg *find_sc_cfg(uint8_t id, const bt_addr_le_t *addr)
320 {
321 LOG_DBG("id: %u, addr: %s", id, bt_addr_le_str(addr));
322
323 for (size_t i = 0; i < ARRAY_SIZE(sc_cfg); i++) {
324 if (id == sc_cfg[i].id &&
325 bt_addr_le_eq(&sc_cfg[i].peer, addr)) {
326 return &sc_cfg[i];
327 }
328 }
329
330 return NULL;
331 }
332
sc_store(struct gatt_sc_cfg * cfg)333 static void sc_store(struct gatt_sc_cfg *cfg)
334 {
335 int err;
336
337 err = bt_settings_store_sc(cfg->id, &cfg->peer, &cfg->data, sizeof(cfg->data));
338 if (err) {
339 LOG_ERR("failed to store SC (err %d)", err);
340 return;
341 }
342
343 LOG_DBG("stored SC for %s (0x%04x-0x%04x)", bt_addr_le_str(&cfg->peer), cfg->data.start,
344 cfg->data.end);
345 }
346
clear_sc_cfg(struct gatt_sc_cfg * cfg)347 static void clear_sc_cfg(struct gatt_sc_cfg *cfg)
348 {
349 memset(cfg, 0, sizeof(*cfg));
350 }
351
bt_gatt_clear_sc(uint8_t id,const bt_addr_le_t * addr)352 static int bt_gatt_clear_sc(uint8_t id, const bt_addr_le_t *addr)
353 {
354
355 struct gatt_sc_cfg *cfg;
356
357 cfg = find_sc_cfg(id, (bt_addr_le_t *)addr);
358 if (!cfg) {
359 return 0;
360 }
361
362 if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
363 int err;
364
365 err = bt_settings_delete_sc(cfg->id, &cfg->peer);
366 if (err) {
367 LOG_ERR("failed to delete SC (err %d)", err);
368 } else {
369 LOG_DBG("deleted SC for %s", bt_addr_le_str(&cfg->peer));
370 }
371 }
372
373 clear_sc_cfg(cfg);
374
375 return 0;
376 }
377
sc_clear(struct bt_conn * conn)378 static void sc_clear(struct bt_conn *conn)
379 {
380 if (bt_addr_le_is_bonded(conn->id, &conn->le.dst)) {
381 int err;
382
383 err = bt_gatt_clear_sc(conn->id, &conn->le.dst);
384 if (err) {
385 LOG_ERR("Failed to clear SC %d", err);
386 }
387 } else {
388 struct gatt_sc_cfg *cfg;
389
390 cfg = find_sc_cfg(conn->id, &conn->le.dst);
391 if (cfg) {
392 clear_sc_cfg(cfg);
393 }
394 }
395 }
396
sc_reset(struct gatt_sc_cfg * cfg)397 static void sc_reset(struct gatt_sc_cfg *cfg)
398 {
399 LOG_DBG("peer %s", bt_addr_le_str(&cfg->peer));
400
401 memset(&cfg->data, 0, sizeof(cfg->data));
402
403 if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
404 sc_store(cfg);
405 }
406 }
407
update_range(uint16_t * start,uint16_t * end,uint16_t new_start,uint16_t new_end)408 static bool update_range(uint16_t *start, uint16_t *end, uint16_t new_start,
409 uint16_t new_end)
410 {
411 LOG_DBG("start 0x%04x end 0x%04x new_start 0x%04x new_end 0x%04x", *start, *end, new_start,
412 new_end);
413
414 /* Check if inside existing range */
415 if (new_start >= *start && new_end <= *end) {
416 return false;
417 }
418
419 /* Update range */
420 if (*start > new_start) {
421 *start = new_start;
422 }
423
424 if (*end < new_end) {
425 *end = new_end;
426 }
427
428 return true;
429 }
430
sc_save(uint8_t id,bt_addr_le_t * peer,uint16_t start,uint16_t end)431 static void sc_save(uint8_t id, bt_addr_le_t *peer, uint16_t start, uint16_t end)
432 {
433 struct gatt_sc_cfg *cfg;
434 bool modified = false;
435
436 LOG_DBG("peer %s start 0x%04x end 0x%04x", bt_addr_le_str(peer), start, end);
437
438 cfg = find_sc_cfg(id, peer);
439 if (!cfg) {
440 /* Find and initialize a free sc_cfg entry */
441 cfg = find_sc_cfg(BT_ID_DEFAULT, BT_ADDR_LE_ANY);
442 if (!cfg) {
443 LOG_ERR("unable to save SC: no cfg left");
444 return;
445 }
446
447 cfg->id = id;
448 bt_addr_le_copy(&cfg->peer, peer);
449 }
450
451 /* Check if there is any change stored */
452 if (!(cfg->data.start || cfg->data.end)) {
453 cfg->data.start = start;
454 cfg->data.end = end;
455 modified = true;
456 goto done;
457 }
458
459 modified = update_range(&cfg->data.start, &cfg->data.end, start, end);
460
461 done:
462 if (IS_ENABLED(CONFIG_BT_SETTINGS) &&
463 modified && bt_addr_le_is_bonded(cfg->id, &cfg->peer)) {
464 sc_store(cfg);
465 }
466 }
467
sc_ccc_cfg_write(struct bt_conn * conn,const struct bt_gatt_attr * attr,uint16_t value)468 static ssize_t sc_ccc_cfg_write(struct bt_conn *conn,
469 const struct bt_gatt_attr *attr, uint16_t value)
470 {
471 LOG_DBG("value 0x%04x", value);
472
473 if (value == BT_GATT_CCC_INDICATE) {
474 /* Create a new SC configuration entry if subscribed */
475 sc_save(conn->id, &conn->le.dst, 0, 0);
476 } else {
477 sc_clear(conn);
478 }
479
480 return sizeof(value);
481 }
482
483 static struct _bt_gatt_ccc sc_ccc = BT_GATT_CCC_INITIALIZER(NULL,
484 sc_ccc_cfg_write,
485 NULL);
486
487 /* Do not shuffle the values in this enum, they are used as bit offsets when
488 * saving the CF flags to NVS (i.e. NVS persists between FW upgrades).
489 */
490 enum {
491 CF_CHANGE_AWARE, /* Client is changed aware */
492 CF_DB_HASH_READ, /* The client has read the database hash */
493
494 /* Total number of flags - must be at the end of the enum */
495 CF_NUM_FLAGS,
496 };
497
498 #define CF_BIT_ROBUST_CACHING 0
499 #define CF_BIT_EATT 1
500 #define CF_BIT_NOTIFY_MULTI 2
501 #define CF_BIT_LAST CF_BIT_NOTIFY_MULTI
502
503 #define CF_NUM_BITS (CF_BIT_LAST + 1)
504 #define CF_NUM_BYTES ((CF_BIT_LAST / 8) + 1)
505 #define CF_FLAGS_STORE_LEN 1
506
507 #define CF_ROBUST_CACHING(_cfg) (_cfg->data[0] & BIT(CF_BIT_ROBUST_CACHING))
508 #define CF_EATT(_cfg) (_cfg->data[0] & BIT(CF_BIT_EATT))
509 #define CF_NOTIFY_MULTI(_cfg) (_cfg->data[0] & BIT(CF_BIT_NOTIFY_MULTI))
510
511 struct gatt_cf_cfg {
512 uint8_t id;
513 bt_addr_le_t peer;
514 uint8_t data[CF_NUM_BYTES];
515 ATOMIC_DEFINE(flags, CF_NUM_FLAGS);
516 };
517
518 #if defined(CONFIG_BT_GATT_CACHING)
519 #define CF_CFG_MAX (CONFIG_BT_MAX_PAIRED + CONFIG_BT_MAX_CONN)
520 #else
521 #define CF_CFG_MAX 0
522 #endif /* CONFIG_BT_GATT_CACHING */
523
524 static struct gatt_cf_cfg cf_cfg[CF_CFG_MAX] = {};
525
clear_cf_cfg(struct gatt_cf_cfg * cfg)526 static void clear_cf_cfg(struct gatt_cf_cfg *cfg)
527 {
528 bt_addr_le_copy(&cfg->peer, BT_ADDR_LE_ANY);
529 memset(cfg->data, 0, sizeof(cfg->data));
530 atomic_set(cfg->flags, 0);
531 }
532
533 enum delayed_store_flags {
534 DELAYED_STORE_CCC,
535 DELAYED_STORE_CF,
536 DELAYED_STORE_NUM_FLAGS
537 };
538
539 #if defined(CONFIG_BT_SETTINGS_DELAYED_STORE)
540 static void gatt_delayed_store_enqueue(uint8_t id, const bt_addr_le_t *peer_addr,
541 enum delayed_store_flags flag);
542 #endif
543
544 #if defined(CONFIG_BT_GATT_CACHING)
set_change_aware_no_store(struct gatt_cf_cfg * cfg,bool aware)545 static bool set_change_aware_no_store(struct gatt_cf_cfg *cfg, bool aware)
546 {
547 bool changed;
548
549 if (aware) {
550 changed = !atomic_test_and_set_bit(cfg->flags, CF_CHANGE_AWARE);
551 } else {
552 changed = atomic_test_and_clear_bit(cfg->flags, CF_CHANGE_AWARE);
553 }
554
555 LOG_DBG("peer is now change-%saware", aware ? "" : "un");
556
557 return changed;
558 }
559
set_change_aware(struct gatt_cf_cfg * cfg,bool aware)560 static void set_change_aware(struct gatt_cf_cfg *cfg, bool aware)
561 {
562 bool changed = set_change_aware_no_store(cfg, aware);
563
564 #if defined(CONFIG_BT_SETTINGS_DELAYED_STORE)
565 if (changed) {
566 gatt_delayed_store_enqueue(cfg->id, &cfg->peer, DELAYED_STORE_CF);
567 }
568 #else
569 (void)changed;
570 #endif
571 }
572
573 static int bt_gatt_store_cf(uint8_t id, const bt_addr_le_t *peer);
574
set_all_change_unaware(void)575 static void set_all_change_unaware(void)
576 {
577 #if defined(CONFIG_BT_SETTINGS)
578 /* Mark all bonded peers as change-unaware.
579 * - Can be called when not in a connection with said peers
580 * - Doesn't have any effect when no bonds are in memory. This is the
581 * case when the device has just booted and `settings_load` hasn't yet
582 * been called.
583 * - Expensive to call, as it will write the new status to settings
584 * right away.
585 */
586 for (size_t i = 0; i < ARRAY_SIZE(cf_cfg); i++) {
587 struct gatt_cf_cfg *cfg = &cf_cfg[i];
588
589 if (!bt_addr_le_eq(&cfg->peer, BT_ADDR_LE_ANY)) {
590 set_change_aware_no_store(cfg, false);
591 bt_gatt_store_cf(cfg->id, &cfg->peer);
592 }
593 }
594 #endif /* CONFIG_BT_SETTINGS */
595 }
596
find_cf_cfg(struct bt_conn * conn)597 static struct gatt_cf_cfg *find_cf_cfg(struct bt_conn *conn)
598 {
599 int i;
600
601 for (i = 0; i < ARRAY_SIZE(cf_cfg); i++) {
602 struct gatt_cf_cfg *cfg = &cf_cfg[i];
603
604 if (!conn) {
605 if (bt_addr_le_eq(&cfg->peer, BT_ADDR_LE_ANY)) {
606 return cfg;
607 }
608 } else if (bt_conn_is_peer_addr_le(conn, cfg->id, &cfg->peer)) {
609 return cfg;
610 }
611 }
612
613 return NULL;
614 }
615
cf_read(struct bt_conn * conn,const struct bt_gatt_attr * attr,void * buf,uint16_t len,uint16_t offset)616 static ssize_t cf_read(struct bt_conn *conn, const struct bt_gatt_attr *attr,
617 void *buf, uint16_t len, uint16_t offset)
618 {
619 struct gatt_cf_cfg *cfg;
620 uint8_t data[1] = {};
621
622 cfg = find_cf_cfg(conn);
623 if (cfg) {
624 memcpy(data, cfg->data, sizeof(data));
625 }
626
627 return bt_gatt_attr_read(conn, attr, buf, len, offset, data,
628 sizeof(data));
629 }
630
cf_set_value(struct gatt_cf_cfg * cfg,const uint8_t * value,uint16_t len)631 static bool cf_set_value(struct gatt_cf_cfg *cfg, const uint8_t *value, uint16_t len)
632 {
633 uint16_t i;
634
635 /* Validate the bits */
636 for (i = 0U; i <= CF_BIT_LAST && (i / 8) < len; i++) {
637 if ((cfg->data[i / 8] & BIT(i % 8)) &&
638 !(value[i / 8] & BIT(i % 8))) {
639 /* A client shall never clear a bit it has set */
640 return false;
641 }
642 }
643
644 /* Set the bits for each octect */
645 for (i = 0U; i < len && i < CF_NUM_BYTES; i++) {
646 if (i == (CF_NUM_BYTES - 1)) {
647 cfg->data[i] |= value[i] & BIT_MASK(CF_NUM_BITS % 8);
648 } else {
649 cfg->data[i] |= value[i];
650 }
651
652 LOG_DBG("byte %u: data 0x%02x value 0x%02x", i, cfg->data[i], value[i]);
653 }
654
655 return true;
656 }
657
cf_write(struct bt_conn * conn,const struct bt_gatt_attr * attr,const void * buf,uint16_t len,uint16_t offset,uint8_t flags)658 static ssize_t cf_write(struct bt_conn *conn, const struct bt_gatt_attr *attr,
659 const void *buf, uint16_t len, uint16_t offset, uint8_t flags)
660 {
661 struct gatt_cf_cfg *cfg;
662 const uint8_t *value = buf;
663
664 if (offset > sizeof(cfg->data)) {
665 return BT_GATT_ERR(BT_ATT_ERR_INVALID_OFFSET);
666 }
667
668 if (offset + len > sizeof(cfg->data)) {
669 return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
670 }
671
672 cfg = find_cf_cfg(conn);
673 if (!cfg) {
674 cfg = find_cf_cfg(NULL);
675 }
676
677 if (!cfg) {
678 LOG_WRN("No space to store Client Supported Features");
679 return BT_GATT_ERR(BT_ATT_ERR_INSUFFICIENT_RESOURCES);
680 }
681
682 LOG_DBG("handle 0x%04x len %u", attr->handle, len);
683
684 if (!cf_set_value(cfg, value, len)) {
685 return BT_GATT_ERR(BT_ATT_ERR_VALUE_NOT_ALLOWED);
686 }
687
688 bt_addr_le_copy(&cfg->peer, &conn->le.dst);
689 cfg->id = conn->id;
690 set_change_aware(cfg, true);
691
692 return len;
693 }
694
695 struct gen_hash_state {
696 struct tc_cmac_struct state;
697 int err;
698 };
699
700 union hash_attr_value {
701 /* Bluetooth Core Specification Version 5.3 | Vol 3, Part G
702 * Table 3.1: Service declaration
703 */
704 union {
705 uint16_t uuid16;
706 uint8_t uuid128[BT_UUID_SIZE_128];
707 } __packed service;
708 /* Bluetooth Core Specification Version 5.3 | Vol 3, Part G
709 * Table 3.2: Include declaration
710 */
711 struct {
712 uint16_t attribute_handle;
713 uint16_t end_group_handle;
714 uint16_t uuid16;
715 } __packed inc;
716 /* Bluetooth Core Specification Version 5.3 | Vol 3, Part G
717 * Table 3.3: Characteristic declaration
718 */
719 struct {
720 uint8_t properties;
721 uint16_t value_handle;
722 union {
723 uint16_t uuid16;
724 uint8_t uuid128[BT_UUID_SIZE_128];
725 } __packed;
726 } __packed chrc;
727 /* Bluetooth Core Specification Version 5.3 | Vol 3, Part G
728 * Table 3.5: Characteristic Properties bit field
729 */
730 struct {
731 uint16_t properties;
732 } __packed cep;
733 } __packed;
734
gen_hash_m(const struct bt_gatt_attr * attr,uint16_t handle,void * user_data)735 static uint8_t gen_hash_m(const struct bt_gatt_attr *attr, uint16_t handle,
736 void *user_data)
737 {
738 struct gen_hash_state *state = user_data;
739 struct bt_uuid_16 *u16;
740 uint8_t data[sizeof(union hash_attr_value)];
741 ssize_t len;
742 uint16_t value;
743
744 if (attr->uuid->type != BT_UUID_TYPE_16)
745 return BT_GATT_ITER_CONTINUE;
746
747 u16 = (struct bt_uuid_16 *)attr->uuid;
748
749 switch (u16->val) {
750 /* Attributes to hash: handle + UUID + value */
751 case BT_UUID_GATT_PRIMARY_VAL:
752 case BT_UUID_GATT_SECONDARY_VAL:
753 case BT_UUID_GATT_INCLUDE_VAL:
754 case BT_UUID_GATT_CHRC_VAL:
755 case BT_UUID_GATT_CEP_VAL:
756 value = sys_cpu_to_le16(handle);
757 if (tc_cmac_update(&state->state, (uint8_t *)&value,
758 sizeof(handle)) == TC_CRYPTO_FAIL) {
759 state->err = -EINVAL;
760 return BT_GATT_ITER_STOP;
761 }
762
763 value = sys_cpu_to_le16(u16->val);
764 if (tc_cmac_update(&state->state, (uint8_t *)&value,
765 sizeof(u16->val)) == TC_CRYPTO_FAIL) {
766 state->err = -EINVAL;
767 return BT_GATT_ITER_STOP;
768 }
769
770 len = attr->read(NULL, attr, data, sizeof(data), 0);
771 if (len < 0) {
772 state->err = len;
773 return BT_GATT_ITER_STOP;
774 }
775
776 if (tc_cmac_update(&state->state, data, len) ==
777 TC_CRYPTO_FAIL) {
778 state->err = -EINVAL;
779 return BT_GATT_ITER_STOP;
780 }
781
782 break;
783 /* Attributes to hash: handle + UUID */
784 case BT_UUID_GATT_CUD_VAL:
785 case BT_UUID_GATT_CCC_VAL:
786 case BT_UUID_GATT_SCC_VAL:
787 case BT_UUID_GATT_CPF_VAL:
788 case BT_UUID_GATT_CAF_VAL:
789 value = sys_cpu_to_le16(handle);
790 if (tc_cmac_update(&state->state, (uint8_t *)&value,
791 sizeof(handle)) == TC_CRYPTO_FAIL) {
792 state->err = -EINVAL;
793 return BT_GATT_ITER_STOP;
794 }
795
796 value = sys_cpu_to_le16(u16->val);
797 if (tc_cmac_update(&state->state, (uint8_t *)&value,
798 sizeof(u16->val)) == TC_CRYPTO_FAIL) {
799 state->err = -EINVAL;
800 return BT_GATT_ITER_STOP;
801 }
802 break;
803 default:
804 return BT_GATT_ITER_CONTINUE;
805 }
806
807 return BT_GATT_ITER_CONTINUE;
808 }
809
db_hash_store(void)810 static void db_hash_store(void)
811 {
812 #if defined(CONFIG_BT_SETTINGS)
813 int err;
814
815 err = bt_settings_store_hash(&db_hash.hash, sizeof(db_hash.hash));
816 if (err) {
817 LOG_ERR("Failed to save Database Hash (err %d)", err);
818 }
819
820 LOG_DBG("Database Hash stored");
821 #endif /* CONFIG_BT_SETTINGS */
822 }
823
db_hash_gen(void)824 static void db_hash_gen(void)
825 {
826 uint8_t key[16] = {};
827 struct tc_aes_key_sched_struct sched;
828 struct gen_hash_state state;
829
830 if (tc_cmac_setup(&state.state, key, &sched) == TC_CRYPTO_FAIL) {
831 LOG_ERR("Unable to setup AES CMAC");
832 return;
833 }
834
835 bt_gatt_foreach_attr(0x0001, 0xffff, gen_hash_m, &state);
836
837 if (tc_cmac_final(db_hash.hash, &state.state) == TC_CRYPTO_FAIL) {
838 LOG_ERR("Unable to calculate hash");
839 return;
840 }
841
842 /**
843 * Core 5.1 does not state the endianess of the hash.
844 * However Vol 3, Part F, 3.3.1 says that multi-octet Characteristic
845 * Values shall be LE unless otherwise defined. PTS expects hash to be
846 * in little endianess as well. bt_smp_aes_cmac calculates the hash in
847 * big endianess so we have to swap.
848 */
849 sys_mem_swap(db_hash.hash, sizeof(db_hash.hash));
850
851 LOG_HEXDUMP_DBG(db_hash.hash, sizeof(db_hash.hash), "Hash: ");
852
853 atomic_set_bit(gatt_sc.flags, DB_HASH_VALID);
854 }
855
856 #if defined(CONFIG_BT_SETTINGS)
857 static void sc_indicate(uint16_t start, uint16_t end);
858 #endif
859
do_db_hash(void)860 static void do_db_hash(void)
861 {
862 bool new_hash = !atomic_test_bit(gatt_sc.flags, DB_HASH_VALID);
863
864 if (new_hash) {
865 db_hash_gen();
866 }
867
868 #if defined(CONFIG_BT_SETTINGS)
869 bool hash_loaded_from_settings =
870 atomic_test_bit(gatt_sc.flags, DB_HASH_LOAD);
871 bool already_processed =
872 atomic_test_bit(gatt_sc.flags, DB_HASH_LOAD_PROC);
873
874 if (!hash_loaded_from_settings) {
875 /* we want to generate the hash, but not overwrite the hash
876 * stored in settings, that we haven't yet loaded.
877 */
878 return;
879 }
880
881 if (already_processed) {
882 /* hash has been loaded from settings and we have already
883 * executed the special case below once. we can now safely save
884 * the calculated hash to settings (if it has changed).
885 */
886 if (new_hash) {
887 set_all_change_unaware();
888 db_hash_store();
889 }
890 } else {
891 /* this is only supposed to run once, on bootup, after the hash
892 * has been loaded from settings.
893 */
894 atomic_set_bit(gatt_sc.flags, DB_HASH_LOAD_PROC);
895
896 /* Check if hash matches then skip SC update */
897 if (!memcmp(db_hash.stored_hash, db_hash.hash,
898 sizeof(db_hash.stored_hash))) {
899 LOG_DBG("Database Hash matches");
900 k_work_cancel_delayable(&gatt_sc.work);
901 atomic_clear_bit(gatt_sc.flags, SC_RANGE_CHANGED);
902 return;
903 }
904
905 LOG_HEXDUMP_DBG(db_hash.hash, sizeof(db_hash.hash), "New Hash: ");
906
907 /* GATT database has been modified since last boot, likely due
908 * to a firmware update or a dynamic service that was not
909 * re-registered on boot.
910 * Indicate Service Changed to all bonded devices for the full
911 * database range to invalidate client-side cache and force
912 * discovery on reconnect.
913 */
914 sc_indicate(0x0001, 0xffff);
915
916 /* Hash did not match, overwrite with current hash.
917 * Also immediately set all peers (in settings) as
918 * change-unaware.
919 */
920 set_all_change_unaware();
921 db_hash_store();
922 }
923 #endif /* defined(CONFIG_BT_SETTINGS) */
924 }
925
db_hash_process(struct k_work * work)926 static void db_hash_process(struct k_work *work)
927 {
928 do_db_hash();
929 }
930
db_hash_read(struct bt_conn * conn,const struct bt_gatt_attr * attr,void * buf,uint16_t len,uint16_t offset)931 static ssize_t db_hash_read(struct bt_conn *conn,
932 const struct bt_gatt_attr *attr,
933 void *buf, uint16_t len, uint16_t offset)
934 {
935 struct gatt_cf_cfg *cfg;
936
937 /* Check if db_hash is already pending in which case it shall be
938 * generated immediately instead of waiting for the work to complete.
939 */
940 (void)k_work_cancel_delayable_sync(&db_hash.work, &db_hash.sync);
941 if (!atomic_test_bit(gatt_sc.flags, DB_HASH_VALID)) {
942 db_hash_gen();
943 if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
944 set_all_change_unaware();
945 db_hash_store();
946 }
947 }
948
949 /* BLUETOOTH CORE SPECIFICATION Version 5.1 | Vol 3, Part G page 2347:
950 * 2.5.2.1 Robust Caching
951 * A connected client becomes change-aware when...
952 * The client reads the Database Hash characteristic and then the server
953 * receives another ATT request from the client.
954 */
955 cfg = find_cf_cfg(conn);
956 if (cfg &&
957 CF_ROBUST_CACHING(cfg) &&
958 !atomic_test_bit(cfg->flags, CF_CHANGE_AWARE)) {
959 atomic_set_bit(cfg->flags, CF_DB_HASH_READ);
960 }
961
962 return bt_gatt_attr_read(conn, attr, buf, len, offset, db_hash.hash,
963 sizeof(db_hash.hash));
964 }
965
remove_cf_cfg(struct bt_conn * conn)966 static void remove_cf_cfg(struct bt_conn *conn)
967 {
968 struct gatt_cf_cfg *cfg;
969
970 cfg = find_cf_cfg(conn);
971 if (!cfg) {
972 return;
973 }
974
975 /* BLUETOOTH CORE SPECIFICATION Version 5.1 | Vol 3, Part G page 2405:
976 * For clients with a trusted relationship, the characteristic value
977 * shall be persistent across connections. For clients without a
978 * trusted relationship the characteristic value shall be set to the
979 * default value at each connection.
980 */
981 if (!bt_addr_le_is_bonded(conn->id, &conn->le.dst)) {
982 clear_cf_cfg(cfg);
983 } else {
984 /* Update address in case it has changed */
985 bt_addr_le_copy(&cfg->peer, &conn->le.dst);
986 }
987 }
988
989 #if defined(CONFIG_BT_EATT)
990 #define SF_BIT_EATT 0
991 #define SF_BIT_LAST SF_BIT_EATT
992
sf_read(struct bt_conn * conn,const struct bt_gatt_attr * attr,void * buf,uint16_t len,uint16_t offset)993 static ssize_t sf_read(struct bt_conn *conn, const struct bt_gatt_attr *attr,
994 void *buf, uint16_t len, uint16_t offset)
995 {
996 uint8_t value = BIT(SF_BIT_EATT);
997
998 return bt_gatt_attr_read(conn, attr, buf, len, offset, &value,
999 sizeof(value));
1000 }
1001 #endif /* CONFIG_BT_EATT */
1002 #endif /* CONFIG_BT_GATT_CACHING */
1003
1004 static struct gatt_cf_cfg *find_cf_cfg_by_addr(uint8_t id,
1005 const bt_addr_le_t *addr);
1006
bt_gatt_store_cf(uint8_t id,const bt_addr_le_t * peer)1007 static int bt_gatt_store_cf(uint8_t id, const bt_addr_le_t *peer)
1008 {
1009 #if defined(CONFIG_BT_GATT_CACHING)
1010 struct gatt_cf_cfg *cfg;
1011 char dst[CF_NUM_BYTES + CF_FLAGS_STORE_LEN];
1012 char *str;
1013 size_t len;
1014 int err;
1015
1016 cfg = find_cf_cfg_by_addr(id, peer);
1017 if (!cfg) {
1018 /* No cfg found, just clear it */
1019 LOG_DBG("No config for CF");
1020 str = NULL;
1021 len = 0;
1022 } else {
1023 str = (char *)cfg->data;
1024 len = sizeof(cfg->data);
1025
1026 /* add the CF data to a temp array */
1027 memcpy(dst, str, len);
1028
1029 /* add the change-aware flag */
1030 bool is_change_aware = atomic_test_bit(cfg->flags, CF_CHANGE_AWARE);
1031
1032 dst[len] = 0;
1033 WRITE_BIT(dst[len], CF_CHANGE_AWARE, is_change_aware);
1034 len += CF_FLAGS_STORE_LEN;
1035
1036 str = dst;
1037 }
1038
1039 err = bt_settings_store_cf(id, peer, str, len);
1040 if (err) {
1041 LOG_ERR("Failed to store Client Features (err %d)", err);
1042 return err;
1043 }
1044
1045 LOG_DBG("Stored CF for %s", bt_addr_le_str(peer));
1046 LOG_HEXDUMP_DBG(str, len, "Saved data");
1047 #endif /* CONFIG_BT_GATT_CACHING */
1048 return 0;
1049
1050 }
1051
1052 #if defined(CONFIG_BT_SETTINGS) && defined(CONFIG_BT_SMP)
1053 /** Struct used to store both the id and the random address of a device when replacing
1054 * random addresses in the ccc attribute's cfg array with the device's id address after
1055 * pairing complete.
1056 */
1057 struct addr_match {
1058 const bt_addr_le_t *private_addr;
1059 const bt_addr_le_t *id_addr;
1060 };
1061
convert_to_id_on_match(const struct bt_gatt_attr * attr,uint16_t handle,void * user_data)1062 static uint8_t convert_to_id_on_match(const struct bt_gatt_attr *attr,
1063 uint16_t handle, void *user_data)
1064 {
1065 struct _bt_gatt_ccc *ccc;
1066 struct addr_match *match = user_data;
1067
1068 /* Check if attribute is a CCC */
1069 if (attr->write != bt_gatt_attr_write_ccc) {
1070 return BT_GATT_ITER_CONTINUE;
1071 }
1072
1073 ccc = attr->user_data;
1074
1075 /* Copy the device's id address to the config's address if the config's address is the
1076 * same as the device's private address
1077 */
1078 for (size_t i = 0; i < ARRAY_SIZE(ccc->cfg); i++) {
1079 if (bt_addr_le_eq(&ccc->cfg[i].peer, match->private_addr)) {
1080 bt_addr_le_copy(&ccc->cfg[i].peer, match->id_addr);
1081 }
1082 }
1083
1084 return BT_GATT_ITER_CONTINUE;
1085 }
1086
bt_gatt_identity_resolved(struct bt_conn * conn,const bt_addr_le_t * private_addr,const bt_addr_le_t * id_addr)1087 static void bt_gatt_identity_resolved(struct bt_conn *conn, const bt_addr_le_t *private_addr,
1088 const bt_addr_le_t *id_addr)
1089 {
1090 /* Update the ccc cfg addresses */
1091 struct addr_match user_data = {
1092 .private_addr = private_addr,
1093 .id_addr = id_addr
1094 };
1095 bool is_bonded = bt_addr_le_is_bonded(conn->id, &conn->le.dst);
1096
1097 bt_gatt_foreach_attr(0x0001, 0xffff, convert_to_id_on_match, &user_data);
1098
1099 /* Store the ccc */
1100 if (is_bonded) {
1101 bt_gatt_store_ccc(conn->id, &conn->le.dst);
1102 }
1103
1104 /* Update the cf addresses and store it if we get a match */
1105 struct gatt_cf_cfg *cfg = find_cf_cfg_by_addr(conn->id, private_addr);
1106
1107 if (cfg) {
1108 bt_addr_le_copy(&cfg->peer, id_addr);
1109 if (is_bonded) {
1110 bt_gatt_store_cf(conn->id, &conn->le.dst);
1111 }
1112 }
1113 }
1114
bt_gatt_pairing_complete(struct bt_conn * conn,bool bonded)1115 static void bt_gatt_pairing_complete(struct bt_conn *conn, bool bonded)
1116 {
1117 if (bonded) {
1118 /* Store the ccc and cf data */
1119 bt_gatt_store_ccc(conn->id, &(conn->le.dst));
1120 bt_gatt_store_cf(conn->id, &conn->le.dst);
1121 }
1122 }
1123 #endif /* CONFIG_BT_SETTINGS && CONFIG_BT_SMP */
1124
1125 BT_GATT_SERVICE_DEFINE(_1_gatt_svc,
1126 BT_GATT_PRIMARY_SERVICE(BT_UUID_GATT),
1127 #if defined(CONFIG_BT_GATT_SERVICE_CHANGED)
1128 /* Bluetooth 5.0, Vol3 Part G:
1129 * The Service Changed characteristic Attribute Handle on the server
1130 * shall not change if the server has a trusted relationship with any
1131 * client.
1132 */
1133 BT_GATT_CHARACTERISTIC(BT_UUID_GATT_SC, BT_GATT_CHRC_INDICATE,
1134 BT_GATT_PERM_NONE, NULL, NULL, NULL),
1135 BT_GATT_CCC_MANAGED(&sc_ccc, BT_GATT_PERM_READ | BT_GATT_PERM_WRITE),
1136 #if defined(CONFIG_BT_GATT_CACHING)
1137 BT_GATT_CHARACTERISTIC(BT_UUID_GATT_CLIENT_FEATURES,
1138 BT_GATT_CHRC_READ | BT_GATT_CHRC_WRITE,
1139 BT_GATT_PERM_READ | BT_GATT_PERM_WRITE,
1140 cf_read, cf_write, NULL),
1141 BT_GATT_CHARACTERISTIC(BT_UUID_GATT_DB_HASH,
1142 BT_GATT_CHRC_READ, BT_GATT_PERM_READ,
1143 db_hash_read, NULL, NULL),
1144 #if defined(CONFIG_BT_EATT)
1145 BT_GATT_CHARACTERISTIC(BT_UUID_GATT_SERVER_FEATURES,
1146 BT_GATT_CHRC_READ, BT_GATT_PERM_READ,
1147 sf_read, NULL, NULL),
1148 #endif /* CONFIG_BT_EATT */
1149 #endif /* CONFIG_BT_GATT_CACHING */
1150 #endif /* CONFIG_BT_GATT_SERVICE_CHANGED */
1151 );
1152
1153 #if defined(CONFIG_BT_GATT_DYNAMIC_DB)
found_attr(const struct bt_gatt_attr * attr,uint16_t handle,void * user_data)1154 static uint8_t found_attr(const struct bt_gatt_attr *attr, uint16_t handle,
1155 void *user_data)
1156 {
1157 const struct bt_gatt_attr **found = user_data;
1158
1159 *found = attr;
1160
1161 return BT_GATT_ITER_STOP;
1162 }
1163
find_attr(uint16_t handle)1164 static const struct bt_gatt_attr *find_attr(uint16_t handle)
1165 {
1166 const struct bt_gatt_attr *attr = NULL;
1167
1168 bt_gatt_foreach_attr(handle, handle, found_attr, &attr);
1169
1170 return attr;
1171 }
1172
gatt_insert(struct bt_gatt_service * svc,uint16_t last_handle)1173 static void gatt_insert(struct bt_gatt_service *svc, uint16_t last_handle)
1174 {
1175 struct bt_gatt_service *tmp, *prev = NULL;
1176
1177 if (last_handle == 0 || svc->attrs[0].handle > last_handle) {
1178 sys_slist_append(&db, &svc->node);
1179 return;
1180 }
1181
1182 /* DB shall always have its service in ascending order */
1183 SYS_SLIST_FOR_EACH_CONTAINER(&db, tmp, node) {
1184 if (tmp->attrs[0].handle > svc->attrs[0].handle) {
1185 if (prev) {
1186 sys_slist_insert(&db, &prev->node, &svc->node);
1187 } else {
1188 sys_slist_prepend(&db, &svc->node);
1189 }
1190 return;
1191 }
1192
1193 prev = tmp;
1194 }
1195 }
1196
gatt_register(struct bt_gatt_service * svc)1197 static int gatt_register(struct bt_gatt_service *svc)
1198 {
1199 struct bt_gatt_service *last;
1200 uint16_t handle, last_handle;
1201 struct bt_gatt_attr *attrs = svc->attrs;
1202 uint16_t count = svc->attr_count;
1203
1204 if (sys_slist_is_empty(&db)) {
1205 handle = last_static_handle;
1206 last_handle = 0;
1207 goto populate;
1208 }
1209
1210 last = SYS_SLIST_PEEK_TAIL_CONTAINER(&db, last, node);
1211 handle = last->attrs[last->attr_count - 1].handle;
1212 last_handle = handle;
1213
1214 populate:
1215 /* Populate the handles and append them to the list */
1216 for (; attrs && count; attrs++, count--) {
1217 if (!attrs->handle) {
1218 /* Allocate handle if not set already */
1219 attrs->handle = ++handle;
1220 } else if (attrs->handle > handle) {
1221 /* Use existing handle if valid */
1222 handle = attrs->handle;
1223 } else if (find_attr(attrs->handle)) {
1224 /* Service has conflicting handles */
1225 LOG_ERR("Unable to register handle 0x%04x", attrs->handle);
1226 return -EINVAL;
1227 }
1228
1229 LOG_DBG("attr %p handle 0x%04x uuid %s perm 0x%02x", attrs, attrs->handle,
1230 bt_uuid_str(attrs->uuid), attrs->perm);
1231 }
1232
1233 gatt_insert(svc, last_handle);
1234
1235 return 0;
1236 }
1237 #endif /* CONFIG_BT_GATT_DYNAMIC_DB */
1238
sc_work_submit(k_timeout_t timeout)1239 static inline void sc_work_submit(k_timeout_t timeout)
1240 {
1241 #if defined(CONFIG_BT_GATT_SERVICE_CHANGED)
1242 k_work_reschedule(&gatt_sc.work, timeout);
1243 #endif
1244 }
1245
1246 #if defined(CONFIG_BT_GATT_SERVICE_CHANGED)
sc_indicate_rsp(struct bt_conn * conn,struct bt_gatt_indicate_params * params,uint8_t err)1247 static void sc_indicate_rsp(struct bt_conn *conn,
1248 struct bt_gatt_indicate_params *params, uint8_t err)
1249 {
1250 #if defined(CONFIG_BT_GATT_CACHING)
1251 struct gatt_cf_cfg *cfg;
1252 #endif
1253
1254 LOG_DBG("err 0x%02x", err);
1255
1256 atomic_clear_bit(gatt_sc.flags, SC_INDICATE_PENDING);
1257
1258 /* Check if there is new change in the meantime */
1259 if (atomic_test_bit(gatt_sc.flags, SC_RANGE_CHANGED)) {
1260 /* Reschedule without any delay since it is waiting already */
1261 sc_work_submit(K_NO_WAIT);
1262 }
1263
1264 #if defined(CONFIG_BT_GATT_CACHING)
1265 /* BLUETOOTH CORE SPECIFICATION Version 5.3 | Vol 3, Part G page 1476:
1266 * 2.5.2.1 Robust Caching
1267 * ... a change-unaware connected client using exactly one ATT bearer
1268 * becomes change-aware when ...
1269 * The client receives and confirms a Handle Value Indication
1270 * for the Service Changed characteristic
1271 */
1272 if (bt_att_fixed_chan_only(conn)) {
1273 cfg = find_cf_cfg(conn);
1274 if (cfg && CF_ROBUST_CACHING(cfg)) {
1275 set_change_aware(cfg, true);
1276 }
1277 }
1278 #endif /* CONFIG_BT_GATT_CACHING */
1279 }
1280
sc_process(struct k_work * work)1281 static void sc_process(struct k_work *work)
1282 {
1283 struct k_work_delayable *dwork = k_work_delayable_from_work(work);
1284 struct gatt_sc *sc = CONTAINER_OF(dwork, struct gatt_sc, work);
1285 uint16_t sc_range[2];
1286
1287 __ASSERT(!atomic_test_bit(sc->flags, SC_INDICATE_PENDING),
1288 "Indicate already pending");
1289
1290 LOG_DBG("start 0x%04x end 0x%04x", sc->start, sc->end);
1291
1292 sc_range[0] = sys_cpu_to_le16(sc->start);
1293 sc_range[1] = sys_cpu_to_le16(sc->end);
1294
1295 atomic_clear_bit(sc->flags, SC_RANGE_CHANGED);
1296 sc->start = 0U;
1297 sc->end = 0U;
1298
1299 sc->params.attr = &_1_gatt_svc.attrs[2];
1300 sc->params.func = sc_indicate_rsp;
1301 sc->params.data = &sc_range[0];
1302 sc->params.len = sizeof(sc_range);
1303 #if defined(CONFIG_BT_EATT)
1304 sc->params.chan_opt = BT_ATT_CHAN_OPT_NONE;
1305 #endif /* CONFIG_BT_EATT */
1306
1307 if (bt_gatt_indicate(NULL, &sc->params)) {
1308 /* No connections to indicate */
1309 return;
1310 }
1311
1312 atomic_set_bit(sc->flags, SC_INDICATE_PENDING);
1313 }
1314 #endif /* defined(CONFIG_BT_GATT_SERVICE_CHANGED) */
1315
clear_ccc_cfg(struct bt_gatt_ccc_cfg * cfg)1316 static void clear_ccc_cfg(struct bt_gatt_ccc_cfg *cfg)
1317 {
1318 bt_addr_le_copy(&cfg->peer, BT_ADDR_LE_ANY);
1319 cfg->id = 0U;
1320 cfg->value = 0U;
1321 }
1322
1323 static void gatt_store_ccc_cf(uint8_t id, const bt_addr_le_t *peer_addr);
1324
1325 struct ds_peer {
1326 uint8_t id;
1327 bt_addr_le_t peer;
1328
1329 ATOMIC_DEFINE(flags, DELAYED_STORE_NUM_FLAGS);
1330 };
1331
1332 IF_ENABLED(CONFIG_BT_SETTINGS_DELAYED_STORE, (
1333 static struct gatt_delayed_store {
1334 struct ds_peer peer_list[CONFIG_BT_MAX_PAIRED + CONFIG_BT_MAX_CONN];
1335 struct k_work_delayable work;
1336 } gatt_delayed_store;
1337 ))
1338
gatt_delayed_store_find(uint8_t id,const bt_addr_le_t * peer_addr)1339 static struct ds_peer *gatt_delayed_store_find(uint8_t id,
1340 const bt_addr_le_t *peer_addr)
1341 {
1342 IF_ENABLED(CONFIG_BT_SETTINGS_DELAYED_STORE, ({
1343 struct ds_peer *el;
1344
1345 for (size_t i = 0; i < ARRAY_SIZE(gatt_delayed_store.peer_list); i++) {
1346 el = &gatt_delayed_store.peer_list[i];
1347 if (el->id == id &&
1348 bt_addr_le_eq(peer_addr, &el->peer)) {
1349 return el;
1350 }
1351 }
1352 }))
1353
1354 return NULL;
1355 }
1356
gatt_delayed_store_free(struct ds_peer * el)1357 static void gatt_delayed_store_free(struct ds_peer *el)
1358 {
1359 if (el) {
1360 el->id = 0;
1361 memset(&el->peer, 0, sizeof(el->peer));
1362 atomic_set(el->flags, 0);
1363 }
1364 }
1365
1366 #if defined(CONFIG_BT_SETTINGS_DELAYED_STORE)
gatt_delayed_store_alloc(uint8_t id,const bt_addr_le_t * peer_addr)1367 static struct ds_peer *gatt_delayed_store_alloc(uint8_t id,
1368 const bt_addr_le_t *peer_addr)
1369 {
1370 struct ds_peer *el;
1371
1372 for (size_t i = 0; i < ARRAY_SIZE(gatt_delayed_store.peer_list); i++) {
1373 el = &gatt_delayed_store.peer_list[i];
1374
1375 /* Checking for the flags is cheaper than a memcmp for the
1376 * address, so we use that to signal that a given slot is
1377 * free.
1378 */
1379 if (atomic_get(el->flags) == 0) {
1380 bt_addr_le_copy(&el->peer, peer_addr);
1381 el->id = id;
1382
1383 return el;
1384 }
1385 }
1386
1387 return NULL;
1388 }
1389
gatt_delayed_store_enqueue(uint8_t id,const bt_addr_le_t * peer_addr,enum delayed_store_flags flag)1390 static void gatt_delayed_store_enqueue(uint8_t id, const bt_addr_le_t *peer_addr,
1391 enum delayed_store_flags flag)
1392 {
1393 bool bonded = bt_addr_le_is_bonded(id, peer_addr);
1394 struct ds_peer *el = gatt_delayed_store_find(id, peer_addr);
1395
1396 if (bonded) {
1397 if (el == NULL) {
1398 el = gatt_delayed_store_alloc(id, peer_addr);
1399 __ASSERT(el != NULL, "Can't save CF / CCC to flash");
1400 }
1401
1402 atomic_set_bit(el->flags, flag);
1403
1404 k_work_reschedule(&gatt_delayed_store.work,
1405 K_MSEC(CONFIG_BT_SETTINGS_DELAYED_STORE_MS));
1406 }
1407 }
1408
delayed_store(struct k_work * work)1409 static void delayed_store(struct k_work *work)
1410 {
1411 struct ds_peer *el;
1412 struct k_work_delayable *dwork = k_work_delayable_from_work(work);
1413 struct gatt_delayed_store *store =
1414 CONTAINER_OF(dwork, struct gatt_delayed_store, work);
1415
1416 for (size_t i = 0; i < ARRAY_SIZE(gatt_delayed_store.peer_list); i++) {
1417 el = &store->peer_list[i];
1418
1419 gatt_store_ccc_cf(el->id, &el->peer);
1420 }
1421 }
1422 #endif /* CONFIG_BT_SETTINGS_DELAYED_STORE */
1423
gatt_store_ccc_cf(uint8_t id,const bt_addr_le_t * peer_addr)1424 static void gatt_store_ccc_cf(uint8_t id, const bt_addr_le_t *peer_addr)
1425 {
1426 struct ds_peer *el = gatt_delayed_store_find(id, peer_addr);
1427
1428 if (bt_addr_le_is_bonded(id, peer_addr)) {
1429 if (!IS_ENABLED(CONFIG_BT_SETTINGS_CCC_STORE_ON_WRITE) ||
1430 (IS_ENABLED(CONFIG_BT_SETTINGS_CCC_STORE_ON_WRITE) && el &&
1431 atomic_test_and_clear_bit(el->flags, DELAYED_STORE_CCC))) {
1432 bt_gatt_store_ccc(id, peer_addr);
1433 }
1434
1435 if (!IS_ENABLED(CONFIG_BT_SETTINGS_CF_STORE_ON_WRITE) ||
1436 (IS_ENABLED(CONFIG_BT_SETTINGS_CF_STORE_ON_WRITE) && el &&
1437 atomic_test_and_clear_bit(el->flags, DELAYED_STORE_CF))) {
1438 bt_gatt_store_cf(id, peer_addr);
1439 }
1440
1441 if (el && atomic_get(el->flags) == 0) {
1442 gatt_delayed_store_free(el);
1443 }
1444 }
1445 }
1446
bt_gatt_service_init(void)1447 static void bt_gatt_service_init(void)
1448 {
1449 if (atomic_test_and_set_bit(gatt_flags, GATT_SERVICE_INITIALIZED)) {
1450 return;
1451 }
1452
1453 STRUCT_SECTION_FOREACH(bt_gatt_service_static, svc) {
1454 last_static_handle += svc->attr_count;
1455 }
1456 }
1457
bt_gatt_init(void)1458 void bt_gatt_init(void)
1459 {
1460 if (atomic_test_and_set_bit(gatt_flags, GATT_INITIALIZED)) {
1461 return;
1462 }
1463
1464 bt_gatt_service_init();
1465
1466 sys_slist_init(&callback_list);
1467
1468 #if defined(CONFIG_BT_GATT_CACHING)
1469 k_work_init_delayable(&db_hash.work, db_hash_process);
1470
1471 /* Submit work to Generate initial hash as there could be static
1472 * services already in the database.
1473 */
1474 if (IS_ENABLED(CONFIG_BT_LONG_WQ)) {
1475 bt_long_wq_schedule(&db_hash.work, DB_HASH_TIMEOUT);
1476 } else {
1477 k_work_schedule(&db_hash.work, DB_HASH_TIMEOUT);
1478 }
1479 #endif /* CONFIG_BT_GATT_CACHING */
1480
1481 #if defined(CONFIG_BT_GATT_SERVICE_CHANGED)
1482 k_work_init_delayable(&gatt_sc.work, sc_process);
1483 if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
1484 /* Make sure to not send SC indications until SC
1485 * settings are loaded
1486 */
1487 atomic_set_bit(gatt_sc.flags, SC_INDICATE_PENDING);
1488 }
1489 #endif /* defined(CONFIG_BT_GATT_SERVICE_CHANGED) */
1490
1491 #if defined(CONFIG_BT_SETTINGS_DELAYED_STORE)
1492 k_work_init_delayable(&gatt_delayed_store.work, delayed_store);
1493 #endif
1494
1495 #if defined(CONFIG_BT_SETTINGS) && defined(CONFIG_BT_SMP)
1496 static struct bt_conn_auth_info_cb gatt_conn_auth_info_cb = {
1497 .pairing_complete = bt_gatt_pairing_complete,
1498 };
1499
1500 /* Register the gatt module for authentication info callbacks so it can
1501 * be notified when pairing has completed. This is used to enable CCC
1502 * and CF storage on pairing complete.
1503 */
1504 bt_conn_auth_info_cb_register(&gatt_conn_auth_info_cb);
1505
1506 static struct bt_conn_cb gatt_conn_cb = {
1507 .identity_resolved = bt_gatt_identity_resolved,
1508 };
1509
1510 /* Also update the address of CCC or CF writes that happened before the
1511 * identity resolution. Note that to increase security in the future, we
1512 * might want to explicitly not do this and treat a bonded device as a
1513 * brand-new peer.
1514 */
1515 bt_conn_cb_register(&gatt_conn_cb);
1516 #endif /* CONFIG_BT_SETTINGS && CONFIG_BT_SMP */
1517 }
1518
1519 #if defined(CONFIG_BT_GATT_DYNAMIC_DB) || \
1520 (defined(CONFIG_BT_GATT_CACHING) && defined(CONFIG_BT_SETTINGS))
sc_indicate(uint16_t start,uint16_t end)1521 static void sc_indicate(uint16_t start, uint16_t end)
1522 {
1523 LOG_DBG("start 0x%04x end 0x%04x", start, end);
1524
1525 if (!atomic_test_and_set_bit(gatt_sc.flags, SC_RANGE_CHANGED)) {
1526 gatt_sc.start = start;
1527 gatt_sc.end = end;
1528 goto submit;
1529 }
1530
1531 if (!update_range(&gatt_sc.start, &gatt_sc.end, start, end)) {
1532 return;
1533 }
1534
1535 submit:
1536 if (atomic_test_bit(gatt_sc.flags, SC_INDICATE_PENDING)) {
1537 LOG_DBG("indicate pending, waiting until complete...");
1538 return;
1539 }
1540
1541 /* Reschedule since the range has changed */
1542 sc_work_submit(SC_TIMEOUT);
1543 }
1544 #endif /* BT_GATT_DYNAMIC_DB || (BT_GATT_CACHING && BT_SETTINGS) */
1545
bt_gatt_cb_register(struct bt_gatt_cb * cb)1546 void bt_gatt_cb_register(struct bt_gatt_cb *cb)
1547 {
1548 sys_slist_append(&callback_list, &cb->node);
1549 }
1550
1551 #if defined(CONFIG_BT_GATT_DYNAMIC_DB)
db_changed(void)1552 static void db_changed(void)
1553 {
1554 #if defined(CONFIG_BT_GATT_CACHING)
1555 struct bt_conn *conn;
1556 int i;
1557
1558 atomic_clear_bit(gatt_sc.flags, DB_HASH_VALID);
1559
1560 if (IS_ENABLED(CONFIG_BT_LONG_WQ)) {
1561 bt_long_wq_reschedule(&db_hash.work, DB_HASH_TIMEOUT);
1562 } else {
1563 k_work_reschedule(&db_hash.work, DB_HASH_TIMEOUT);
1564 }
1565
1566 for (i = 0; i < ARRAY_SIZE(cf_cfg); i++) {
1567 struct gatt_cf_cfg *cfg = &cf_cfg[i];
1568
1569 if (bt_addr_le_eq(&cfg->peer, BT_ADDR_LE_ANY)) {
1570 continue;
1571 }
1572
1573 if (CF_ROBUST_CACHING(cfg)) {
1574 /* Core Spec 5.1 | Vol 3, Part G, 2.5.2.1 Robust Caching
1575 *... the database changes again before the client
1576 * becomes change-aware in which case the error response
1577 * shall be sent again.
1578 */
1579 conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cfg->peer);
1580 if (conn) {
1581 bt_att_clear_out_of_sync_sent(conn);
1582 bt_conn_unref(conn);
1583 }
1584
1585 atomic_clear_bit(cfg->flags, CF_DB_HASH_READ);
1586 set_change_aware(cfg, false);
1587 }
1588 }
1589 #endif
1590 }
1591
gatt_unregister_ccc(struct _bt_gatt_ccc * ccc)1592 static void gatt_unregister_ccc(struct _bt_gatt_ccc *ccc)
1593 {
1594 ccc->value = 0;
1595
1596 for (size_t i = 0; i < ARRAY_SIZE(ccc->cfg); i++) {
1597 struct bt_gatt_ccc_cfg *cfg = &ccc->cfg[i];
1598
1599 if (!bt_addr_le_eq(&cfg->peer, BT_ADDR_LE_ANY)) {
1600 struct bt_conn *conn;
1601 bool store = true;
1602
1603 conn = bt_conn_lookup_addr_le(cfg->id, &cfg->peer);
1604 if (conn) {
1605 if (conn->state == BT_CONN_CONNECTED) {
1606 #if defined(CONFIG_BT_SETTINGS_CCC_STORE_ON_WRITE)
1607 gatt_delayed_store_enqueue(conn->id,
1608 &conn->le.dst,
1609 DELAYED_STORE_CCC);
1610 #endif
1611 store = false;
1612 }
1613
1614 bt_conn_unref(conn);
1615 }
1616
1617 if (IS_ENABLED(CONFIG_BT_SETTINGS) && store &&
1618 bt_addr_le_is_bonded(cfg->id, &cfg->peer)) {
1619 bt_gatt_store_ccc(cfg->id, &cfg->peer);
1620 }
1621
1622 clear_ccc_cfg(cfg);
1623 }
1624 }
1625 }
1626
gatt_unregister(struct bt_gatt_service * svc)1627 static int gatt_unregister(struct bt_gatt_service *svc)
1628 {
1629 if (!sys_slist_find_and_remove(&db, &svc->node)) {
1630 return -ENOENT;
1631 }
1632
1633 for (uint16_t i = 0; i < svc->attr_count; i++) {
1634 struct bt_gatt_attr *attr = &svc->attrs[i];
1635
1636 if (attr->write == bt_gatt_attr_write_ccc) {
1637 gatt_unregister_ccc(attr->user_data);
1638 }
1639 }
1640
1641 return 0;
1642 }
1643
bt_gatt_service_register(struct bt_gatt_service * svc)1644 int bt_gatt_service_register(struct bt_gatt_service *svc)
1645 {
1646 int err;
1647
1648 __ASSERT(svc, "invalid parameters\n");
1649 __ASSERT(svc->attrs, "invalid parameters\n");
1650 __ASSERT(svc->attr_count, "invalid parameters\n");
1651
1652 if (IS_ENABLED(CONFIG_BT_SETTINGS) &&
1653 atomic_test_bit(gatt_flags, GATT_INITIALIZED) &&
1654 !atomic_test_bit(gatt_sc.flags, SC_LOAD)) {
1655 LOG_ERR("Can't register service after init and before settings are loaded.");
1656 return -EINVAL;
1657 }
1658
1659 /* Init GATT core services */
1660 bt_gatt_service_init();
1661
1662 /* Do no allow to register mandatory services twice */
1663 if (!bt_uuid_cmp(svc->attrs[0].uuid, BT_UUID_GAP) ||
1664 !bt_uuid_cmp(svc->attrs[0].uuid, BT_UUID_GATT)) {
1665 return -EALREADY;
1666 }
1667
1668 k_sched_lock();
1669
1670 err = gatt_register(svc);
1671 if (err < 0) {
1672 k_sched_unlock();
1673 return err;
1674 }
1675
1676 /* Don't submit any work until the stack is initialized */
1677 if (!atomic_test_bit(gatt_flags, GATT_INITIALIZED)) {
1678 k_sched_unlock();
1679 return 0;
1680 }
1681
1682 sc_indicate(svc->attrs[0].handle,
1683 svc->attrs[svc->attr_count - 1].handle);
1684
1685 db_changed();
1686
1687 k_sched_unlock();
1688
1689 return 0;
1690 }
1691
bt_gatt_service_unregister(struct bt_gatt_service * svc)1692 int bt_gatt_service_unregister(struct bt_gatt_service *svc)
1693 {
1694 int err;
1695
1696 __ASSERT(svc, "invalid parameters\n");
1697
1698 k_sched_lock();
1699
1700 err = gatt_unregister(svc);
1701 if (err) {
1702 k_sched_unlock();
1703 return err;
1704 }
1705
1706 /* Don't submit any work until the stack is initialized */
1707 if (!atomic_test_bit(gatt_flags, GATT_INITIALIZED)) {
1708 k_sched_unlock();
1709 return 0;
1710 }
1711
1712 sc_indicate(svc->attrs[0].handle,
1713 svc->attrs[svc->attr_count - 1].handle);
1714
1715 db_changed();
1716
1717 k_sched_unlock();
1718
1719 return 0;
1720 }
1721
bt_gatt_service_is_registered(const struct bt_gatt_service * svc)1722 bool bt_gatt_service_is_registered(const struct bt_gatt_service *svc)
1723 {
1724 bool registered = false;
1725 sys_snode_t *node;
1726
1727 k_sched_lock();
1728 SYS_SLIST_FOR_EACH_NODE(&db, node) {
1729 if (&svc->node == node) {
1730 registered = true;
1731 break;
1732 }
1733 }
1734
1735 k_sched_unlock();
1736
1737 return registered;
1738 }
1739 #endif /* CONFIG_BT_GATT_DYNAMIC_DB */
1740
bt_gatt_attr_read(struct bt_conn * conn,const struct bt_gatt_attr * attr,void * buf,uint16_t buf_len,uint16_t offset,const void * value,uint16_t value_len)1741 ssize_t bt_gatt_attr_read(struct bt_conn *conn, const struct bt_gatt_attr *attr,
1742 void *buf, uint16_t buf_len, uint16_t offset,
1743 const void *value, uint16_t value_len)
1744 {
1745 uint16_t len;
1746
1747 if (offset > value_len) {
1748 return BT_GATT_ERR(BT_ATT_ERR_INVALID_OFFSET);
1749 }
1750
1751 len = MIN(buf_len, value_len - offset);
1752
1753 LOG_DBG("handle 0x%04x offset %u length %u", attr->handle, offset, len);
1754
1755 memcpy(buf, (uint8_t *)value + offset, len);
1756
1757 return len;
1758 }
1759
bt_gatt_attr_read_service(struct bt_conn * conn,const struct bt_gatt_attr * attr,void * buf,uint16_t len,uint16_t offset)1760 ssize_t bt_gatt_attr_read_service(struct bt_conn *conn,
1761 const struct bt_gatt_attr *attr,
1762 void *buf, uint16_t len, uint16_t offset)
1763 {
1764 struct bt_uuid *uuid = attr->user_data;
1765
1766 if (uuid->type == BT_UUID_TYPE_16) {
1767 uint16_t uuid16 = sys_cpu_to_le16(BT_UUID_16(uuid)->val);
1768
1769 return bt_gatt_attr_read(conn, attr, buf, len, offset,
1770 &uuid16, 2);
1771 }
1772
1773 return bt_gatt_attr_read(conn, attr, buf, len, offset,
1774 BT_UUID_128(uuid)->val, 16);
1775 }
1776
1777 struct gatt_incl {
1778 uint16_t start_handle;
1779 uint16_t end_handle;
1780 uint16_t uuid16;
1781 } __packed;
1782
get_service_handles(const struct bt_gatt_attr * attr,uint16_t handle,void * user_data)1783 static uint8_t get_service_handles(const struct bt_gatt_attr *attr,
1784 uint16_t handle, void *user_data)
1785 {
1786 struct gatt_incl *include = user_data;
1787
1788 /* Stop if attribute is a service */
1789 if (!bt_uuid_cmp(attr->uuid, BT_UUID_GATT_PRIMARY) ||
1790 !bt_uuid_cmp(attr->uuid, BT_UUID_GATT_SECONDARY)) {
1791 return BT_GATT_ITER_STOP;
1792 }
1793
1794 include->end_handle = sys_cpu_to_le16(handle);
1795
1796 return BT_GATT_ITER_CONTINUE;
1797 }
1798
bt_gatt_attr_get_handle(const struct bt_gatt_attr * attr)1799 uint16_t bt_gatt_attr_get_handle(const struct bt_gatt_attr *attr)
1800 {
1801 uint16_t handle = 1;
1802
1803 if (!attr) {
1804 return 0;
1805 }
1806
1807 if (attr->handle) {
1808 return attr->handle;
1809 }
1810
1811 STRUCT_SECTION_FOREACH(bt_gatt_service_static, static_svc) {
1812 /* Skip ahead if start is not within service attributes array */
1813 if ((attr < &static_svc->attrs[0]) ||
1814 (attr > &static_svc->attrs[static_svc->attr_count - 1])) {
1815 handle += static_svc->attr_count;
1816 continue;
1817 }
1818
1819 for (size_t i = 0; i < static_svc->attr_count; i++, handle++) {
1820 if (attr == &static_svc->attrs[i]) {
1821 return handle;
1822 }
1823 }
1824 }
1825
1826 return 0;
1827 }
1828
bt_gatt_attr_read_included(struct bt_conn * conn,const struct bt_gatt_attr * attr,void * buf,uint16_t len,uint16_t offset)1829 ssize_t bt_gatt_attr_read_included(struct bt_conn *conn,
1830 const struct bt_gatt_attr *attr,
1831 void *buf, uint16_t len, uint16_t offset)
1832 {
1833 struct bt_gatt_attr *incl = attr->user_data;
1834 uint16_t handle = bt_gatt_attr_get_handle(incl);
1835 struct bt_uuid *uuid = incl->user_data;
1836 struct gatt_incl pdu;
1837 uint8_t value_len;
1838
1839 /* first attr points to the start handle */
1840 pdu.start_handle = sys_cpu_to_le16(handle);
1841 value_len = sizeof(pdu.start_handle) + sizeof(pdu.end_handle);
1842
1843 /*
1844 * Core 4.2, Vol 3, Part G, 3.2,
1845 * The Service UUID shall only be present when the UUID is a
1846 * 16-bit Bluetooth UUID.
1847 */
1848 if (uuid->type == BT_UUID_TYPE_16) {
1849 pdu.uuid16 = sys_cpu_to_le16(BT_UUID_16(uuid)->val);
1850 value_len += sizeof(pdu.uuid16);
1851 }
1852
1853 /* Lookup for service end handle */
1854 bt_gatt_foreach_attr(handle + 1, 0xffff, get_service_handles, &pdu);
1855
1856 return bt_gatt_attr_read(conn, attr, buf, len, offset, &pdu, value_len);
1857 }
1858
1859 struct gatt_chrc {
1860 uint8_t properties;
1861 uint16_t value_handle;
1862 union {
1863 uint16_t uuid16;
1864 uint8_t uuid[16];
1865 };
1866 } __packed;
1867
bt_gatt_attr_value_handle(const struct bt_gatt_attr * attr)1868 uint16_t bt_gatt_attr_value_handle(const struct bt_gatt_attr *attr)
1869 {
1870 uint16_t handle = 0;
1871
1872 if (attr != NULL && bt_uuid_cmp(attr->uuid, BT_UUID_GATT_CHRC) == 0) {
1873 struct bt_gatt_chrc *chrc = attr->user_data;
1874
1875 handle = chrc->value_handle;
1876 if (handle == 0) {
1877 /* Fall back to Zephyr value handle policy */
1878 handle = bt_gatt_attr_get_handle(attr) + 1U;
1879 }
1880 }
1881
1882 return handle;
1883 }
1884
bt_gatt_attr_read_chrc(struct bt_conn * conn,const struct bt_gatt_attr * attr,void * buf,uint16_t len,uint16_t offset)1885 ssize_t bt_gatt_attr_read_chrc(struct bt_conn *conn,
1886 const struct bt_gatt_attr *attr, void *buf,
1887 uint16_t len, uint16_t offset)
1888 {
1889 struct bt_gatt_chrc *chrc = attr->user_data;
1890 struct gatt_chrc pdu;
1891 uint8_t value_len;
1892
1893 pdu.properties = chrc->properties;
1894 /* BLUETOOTH SPECIFICATION Version 4.2 [Vol 3, Part G] page 534:
1895 * 3.3.2 Characteristic Value Declaration
1896 * The Characteristic Value declaration contains the value of the
1897 * characteristic. It is the first Attribute after the characteristic
1898 * declaration. All characteristic definitions shall have a
1899 * Characteristic Value declaration.
1900 */
1901 pdu.value_handle = sys_cpu_to_le16(bt_gatt_attr_value_handle(attr));
1902
1903 value_len = sizeof(pdu.properties) + sizeof(pdu.value_handle);
1904
1905 if (chrc->uuid->type == BT_UUID_TYPE_16) {
1906 pdu.uuid16 = sys_cpu_to_le16(BT_UUID_16(chrc->uuid)->val);
1907 value_len += 2U;
1908 } else {
1909 memcpy(pdu.uuid, BT_UUID_128(chrc->uuid)->val, 16);
1910 value_len += 16U;
1911 }
1912
1913 return bt_gatt_attr_read(conn, attr, buf, len, offset, &pdu, value_len);
1914 }
1915
gatt_foreach_iter(const struct bt_gatt_attr * attr,uint16_t handle,uint16_t start_handle,uint16_t end_handle,const struct bt_uuid * uuid,const void * attr_data,uint16_t * num_matches,bt_gatt_attr_func_t func,void * user_data)1916 static uint8_t gatt_foreach_iter(const struct bt_gatt_attr *attr,
1917 uint16_t handle, uint16_t start_handle,
1918 uint16_t end_handle,
1919 const struct bt_uuid *uuid,
1920 const void *attr_data, uint16_t *num_matches,
1921 bt_gatt_attr_func_t func, void *user_data)
1922 {
1923 uint8_t result;
1924
1925 /* Stop if over the requested range */
1926 if (handle > end_handle) {
1927 return BT_GATT_ITER_STOP;
1928 }
1929
1930 /* Check if attribute handle is within range */
1931 if (handle < start_handle) {
1932 return BT_GATT_ITER_CONTINUE;
1933 }
1934
1935 /* Match attribute UUID if set */
1936 if (uuid && bt_uuid_cmp(uuid, attr->uuid)) {
1937 return BT_GATT_ITER_CONTINUE;
1938 }
1939
1940 /* Match attribute user_data if set */
1941 if (attr_data && attr_data != attr->user_data) {
1942 return BT_GATT_ITER_CONTINUE;
1943 }
1944
1945 *num_matches -= 1;
1946
1947 result = func(attr, handle, user_data);
1948
1949 if (!*num_matches) {
1950 return BT_GATT_ITER_STOP;
1951 }
1952
1953 return result;
1954 }
1955
foreach_attr_type_dyndb(uint16_t start_handle,uint16_t end_handle,const struct bt_uuid * uuid,const void * attr_data,uint16_t num_matches,bt_gatt_attr_func_t func,void * user_data)1956 static void foreach_attr_type_dyndb(uint16_t start_handle, uint16_t end_handle,
1957 const struct bt_uuid *uuid,
1958 const void *attr_data, uint16_t num_matches,
1959 bt_gatt_attr_func_t func, void *user_data)
1960 {
1961 #if defined(CONFIG_BT_GATT_DYNAMIC_DB)
1962 size_t i;
1963 struct bt_gatt_service *svc;
1964
1965 SYS_SLIST_FOR_EACH_CONTAINER(&db, svc, node) {
1966 struct bt_gatt_service *next;
1967
1968 next = SYS_SLIST_PEEK_NEXT_CONTAINER(svc, node);
1969 if (next) {
1970 /* Skip ahead if start is not within service handles */
1971 if (next->attrs[0].handle <= start_handle) {
1972 continue;
1973 }
1974 }
1975
1976 for (i = 0; i < svc->attr_count; i++) {
1977 struct bt_gatt_attr *attr = &svc->attrs[i];
1978
1979 if (gatt_foreach_iter(attr, attr->handle,
1980 start_handle,
1981 end_handle,
1982 uuid, attr_data,
1983 &num_matches,
1984 func, user_data) ==
1985 BT_GATT_ITER_STOP) {
1986 return;
1987 }
1988 }
1989 }
1990 #endif /* CONFIG_BT_GATT_DYNAMIC_DB */
1991 }
1992
bt_gatt_foreach_attr_type(uint16_t start_handle,uint16_t end_handle,const struct bt_uuid * uuid,const void * attr_data,uint16_t num_matches,bt_gatt_attr_func_t func,void * user_data)1993 void bt_gatt_foreach_attr_type(uint16_t start_handle, uint16_t end_handle,
1994 const struct bt_uuid *uuid,
1995 const void *attr_data, uint16_t num_matches,
1996 bt_gatt_attr_func_t func, void *user_data)
1997 {
1998 size_t i;
1999
2000 if (!num_matches) {
2001 num_matches = UINT16_MAX;
2002 }
2003
2004 if (start_handle <= last_static_handle) {
2005 uint16_t handle = 1;
2006
2007 STRUCT_SECTION_FOREACH(bt_gatt_service_static, static_svc) {
2008 /* Skip ahead if start is not within service handles */
2009 if (handle + static_svc->attr_count < start_handle) {
2010 handle += static_svc->attr_count;
2011 continue;
2012 }
2013
2014 for (i = 0; i < static_svc->attr_count; i++, handle++) {
2015 if (gatt_foreach_iter(&static_svc->attrs[i],
2016 handle, start_handle,
2017 end_handle, uuid,
2018 attr_data, &num_matches,
2019 func, user_data) ==
2020 BT_GATT_ITER_STOP) {
2021 return;
2022 }
2023 }
2024 }
2025 }
2026
2027 /* Iterate over dynamic db */
2028 foreach_attr_type_dyndb(start_handle, end_handle, uuid, attr_data,
2029 num_matches, func, user_data);
2030 }
2031
find_next(const struct bt_gatt_attr * attr,uint16_t handle,void * user_data)2032 static uint8_t find_next(const struct bt_gatt_attr *attr, uint16_t handle,
2033 void *user_data)
2034 {
2035 struct bt_gatt_attr **next = user_data;
2036
2037 *next = (struct bt_gatt_attr *)attr;
2038
2039 return BT_GATT_ITER_STOP;
2040 }
2041
bt_gatt_attr_next(const struct bt_gatt_attr * attr)2042 struct bt_gatt_attr *bt_gatt_attr_next(const struct bt_gatt_attr *attr)
2043 {
2044 struct bt_gatt_attr *next = NULL;
2045 uint16_t handle = bt_gatt_attr_get_handle(attr);
2046
2047 bt_gatt_foreach_attr(handle + 1, handle + 1, find_next, &next);
2048
2049 return next;
2050 }
2051
find_ccc_cfg(const struct bt_conn * conn,struct _bt_gatt_ccc * ccc)2052 static struct bt_gatt_ccc_cfg *find_ccc_cfg(const struct bt_conn *conn,
2053 struct _bt_gatt_ccc *ccc)
2054 {
2055 for (size_t i = 0; i < ARRAY_SIZE(ccc->cfg); i++) {
2056 struct bt_gatt_ccc_cfg *cfg = &ccc->cfg[i];
2057
2058 if (conn) {
2059 if (bt_conn_is_peer_addr_le(conn, cfg->id,
2060 &cfg->peer)) {
2061 return cfg;
2062 }
2063 } else if (bt_addr_le_eq(&cfg->peer, BT_ADDR_LE_ANY)) {
2064 return cfg;
2065 }
2066 }
2067
2068 return NULL;
2069 }
2070
bt_gatt_attr_read_ccc(struct bt_conn * conn,const struct bt_gatt_attr * attr,void * buf,uint16_t len,uint16_t offset)2071 ssize_t bt_gatt_attr_read_ccc(struct bt_conn *conn,
2072 const struct bt_gatt_attr *attr, void *buf,
2073 uint16_t len, uint16_t offset)
2074 {
2075 struct _bt_gatt_ccc *ccc = attr->user_data;
2076 const struct bt_gatt_ccc_cfg *cfg;
2077 uint16_t value;
2078
2079 cfg = find_ccc_cfg(conn, ccc);
2080 if (cfg) {
2081 value = sys_cpu_to_le16(cfg->value);
2082 } else {
2083 /* Default to disable if there is no cfg for the peer */
2084 value = 0x0000;
2085 }
2086
2087 return bt_gatt_attr_read(conn, attr, buf, len, offset, &value,
2088 sizeof(value));
2089 }
2090
gatt_ccc_changed(const struct bt_gatt_attr * attr,struct _bt_gatt_ccc * ccc)2091 static void gatt_ccc_changed(const struct bt_gatt_attr *attr,
2092 struct _bt_gatt_ccc *ccc)
2093 {
2094 int i;
2095 uint16_t value = 0x0000;
2096
2097 for (i = 0; i < ARRAY_SIZE(ccc->cfg); i++) {
2098 if (ccc->cfg[i].value > value) {
2099 value = ccc->cfg[i].value;
2100 }
2101 }
2102
2103 LOG_DBG("ccc %p value 0x%04x", ccc, value);
2104
2105 if (value != ccc->value) {
2106 ccc->value = value;
2107 if (ccc->cfg_changed) {
2108 ccc->cfg_changed(attr, value);
2109 }
2110 }
2111 }
2112
bt_gatt_attr_write_ccc(struct bt_conn * conn,const struct bt_gatt_attr * attr,const void * buf,uint16_t len,uint16_t offset,uint8_t flags)2113 ssize_t bt_gatt_attr_write_ccc(struct bt_conn *conn,
2114 const struct bt_gatt_attr *attr, const void *buf,
2115 uint16_t len, uint16_t offset, uint8_t flags)
2116 {
2117 struct _bt_gatt_ccc *ccc = attr->user_data;
2118 struct bt_gatt_ccc_cfg *cfg;
2119 bool value_changed;
2120 uint16_t value;
2121
2122 if (offset) {
2123 return BT_GATT_ERR(BT_ATT_ERR_INVALID_OFFSET);
2124 }
2125
2126 if (!len || len > sizeof(uint16_t)) {
2127 return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
2128 }
2129
2130 if (len < sizeof(uint16_t)) {
2131 value = *(uint8_t *)buf;
2132 } else {
2133 value = sys_get_le16(buf);
2134 }
2135
2136 cfg = find_ccc_cfg(conn, ccc);
2137 if (!cfg) {
2138 /* If there's no existing entry, but the new value is zero,
2139 * we don't need to do anything, since a disabled CCC is
2140 * behaviorally the same as no written CCC.
2141 */
2142 if (!value) {
2143 return len;
2144 }
2145
2146 cfg = find_ccc_cfg(NULL, ccc);
2147 if (!cfg) {
2148 LOG_WRN("No space to store CCC cfg");
2149 return BT_GATT_ERR(BT_ATT_ERR_INSUFFICIENT_RESOURCES);
2150 }
2151
2152 bt_addr_le_copy(&cfg->peer, &conn->le.dst);
2153 cfg->id = conn->id;
2154 }
2155
2156 /* Confirm write if cfg is managed by application */
2157 if (ccc->cfg_write) {
2158 ssize_t write = ccc->cfg_write(conn, attr, value);
2159
2160 if (write < 0) {
2161 return write;
2162 }
2163
2164 /* Accept size=1 for backwards compatibility */
2165 if (write != sizeof(value) && write != 1) {
2166 return BT_GATT_ERR(BT_ATT_ERR_UNLIKELY);
2167 }
2168 }
2169
2170 value_changed = cfg->value != value;
2171 cfg->value = value;
2172
2173 LOG_DBG("handle 0x%04x value %u", attr->handle, cfg->value);
2174
2175 /* Update cfg if don't match */
2176 if (cfg->value != ccc->value) {
2177 gatt_ccc_changed(attr, ccc);
2178 }
2179
2180 if (value_changed) {
2181 #if defined(CONFIG_BT_SETTINGS_CCC_STORE_ON_WRITE)
2182 /* Enqueue CCC store if value has changed for the connection */
2183 gatt_delayed_store_enqueue(conn->id, &conn->le.dst, DELAYED_STORE_CCC);
2184 #endif
2185 }
2186
2187 /* Disabled CCC is the same as no configured CCC, so clear the entry */
2188 if (!value) {
2189 clear_ccc_cfg(cfg);
2190 }
2191
2192 return len;
2193 }
2194
bt_gatt_attr_read_cep(struct bt_conn * conn,const struct bt_gatt_attr * attr,void * buf,uint16_t len,uint16_t offset)2195 ssize_t bt_gatt_attr_read_cep(struct bt_conn *conn,
2196 const struct bt_gatt_attr *attr, void *buf,
2197 uint16_t len, uint16_t offset)
2198 {
2199 const struct bt_gatt_cep *value = attr->user_data;
2200 uint16_t props = sys_cpu_to_le16(value->properties);
2201
2202 return bt_gatt_attr_read(conn, attr, buf, len, offset, &props,
2203 sizeof(props));
2204 }
2205
bt_gatt_attr_read_cud(struct bt_conn * conn,const struct bt_gatt_attr * attr,void * buf,uint16_t len,uint16_t offset)2206 ssize_t bt_gatt_attr_read_cud(struct bt_conn *conn,
2207 const struct bt_gatt_attr *attr, void *buf,
2208 uint16_t len, uint16_t offset)
2209 {
2210 const char *value = attr->user_data;
2211
2212 return bt_gatt_attr_read(conn, attr, buf, len, offset, value,
2213 strlen(value));
2214 }
2215
2216 struct gatt_cpf {
2217 uint8_t format;
2218 int8_t exponent;
2219 uint16_t unit;
2220 uint8_t name_space;
2221 uint16_t description;
2222 } __packed;
2223
bt_gatt_attr_read_cpf(struct bt_conn * conn,const struct bt_gatt_attr * attr,void * buf,uint16_t len,uint16_t offset)2224 ssize_t bt_gatt_attr_read_cpf(struct bt_conn *conn,
2225 const struct bt_gatt_attr *attr, void *buf,
2226 uint16_t len, uint16_t offset)
2227 {
2228 const struct bt_gatt_cpf *cpf = attr->user_data;
2229 struct gatt_cpf value;
2230
2231 value.format = cpf->format;
2232 value.exponent = cpf->exponent;
2233 value.unit = sys_cpu_to_le16(cpf->unit);
2234 value.name_space = cpf->name_space;
2235 value.description = sys_cpu_to_le16(cpf->description);
2236
2237 return bt_gatt_attr_read(conn, attr, buf, len, offset, &value,
2238 sizeof(value));
2239 }
2240
2241 struct notify_data {
2242 const struct bt_gatt_attr *attr;
2243 uint16_t handle;
2244 int err;
2245 uint16_t type;
2246 union {
2247 struct bt_gatt_notify_params *nfy_params;
2248 struct bt_gatt_indicate_params *ind_params;
2249 };
2250 };
2251
2252 #if defined(CONFIG_BT_GATT_NOTIFY_MULTIPLE)
2253
2254 static struct net_buf *nfy_mult[CONFIG_BT_MAX_CONN];
2255
gatt_notify_mult_send(struct bt_conn * conn,struct net_buf * buf)2256 static int gatt_notify_mult_send(struct bt_conn *conn, struct net_buf *buf)
2257 {
2258 int ret;
2259 uint8_t *pdu = buf->data;
2260 /* PDU structure is [Opcode (1)] [Handle (2)] [Length (2)] [Value (Length)] */
2261 uint16_t first_attr_len = sys_get_le16(&pdu[3]);
2262
2263 /* Convert to ATT_HANDLE_VALUE_NTF if containing a single handle. */
2264 if (buf->len ==
2265 (1 + sizeof(struct bt_att_notify_mult) + first_attr_len)) {
2266 /* Store attr handle */
2267 uint16_t handle = sys_get_le16(&pdu[1]);
2268
2269 /* Remove the ATT_MULTIPLE_HANDLE_VALUE_NTF opcode,
2270 * attribute handle and length
2271 */
2272 (void)net_buf_pull(buf, 1 + sizeof(struct bt_att_notify_mult));
2273
2274 /* Add back an ATT_HANDLE_VALUE_NTF opcode and attr handle */
2275 /* PDU structure is now [Opcode (1)] [Handle (1)] [Value] */
2276 net_buf_push_le16(buf, handle);
2277 net_buf_push_u8(buf, BT_ATT_OP_NOTIFY);
2278 LOG_DBG("Converted BT_ATT_OP_NOTIFY_MULT with single attr to BT_ATT_OP_NOTIFY");
2279 }
2280
2281 ret = bt_att_send(conn, buf);
2282 if (ret < 0) {
2283 net_buf_unref(buf);
2284 }
2285
2286 return ret;
2287 }
2288
notify_mult_process(struct k_work * work)2289 static void notify_mult_process(struct k_work *work)
2290 {
2291 int i;
2292
2293 /* Send to any connection with an allocated buffer */
2294 for (i = 0; i < ARRAY_SIZE(nfy_mult); i++) {
2295 struct net_buf **buf = &nfy_mult[i];
2296
2297 if (*buf) {
2298 struct bt_conn *conn = bt_conn_lookup_index(i);
2299
2300 gatt_notify_mult_send(conn, *buf);
2301 *buf = NULL;
2302 bt_conn_unref(conn);
2303 }
2304 }
2305 }
2306
2307 K_WORK_DELAYABLE_DEFINE(nfy_mult_work, notify_mult_process);
2308
gatt_cf_notify_multi(struct bt_conn * conn)2309 static bool gatt_cf_notify_multi(struct bt_conn *conn)
2310 {
2311 struct gatt_cf_cfg *cfg;
2312
2313 cfg = find_cf_cfg(conn);
2314 if (!cfg) {
2315 return false;
2316 }
2317
2318 return CF_NOTIFY_MULTI(cfg);
2319 }
2320
gatt_notify_flush(struct bt_conn * conn)2321 static int gatt_notify_flush(struct bt_conn *conn)
2322 {
2323 int err = 0;
2324 struct net_buf **buf = &nfy_mult[bt_conn_index(conn)];
2325
2326 if (*buf) {
2327 err = gatt_notify_mult_send(conn, *buf);
2328 *buf = NULL;
2329 }
2330
2331 return err;
2332 }
2333
cleanup_notify(struct bt_conn * conn)2334 static void cleanup_notify(struct bt_conn *conn)
2335 {
2336 struct net_buf **buf = &nfy_mult[bt_conn_index(conn)];
2337
2338 if (*buf) {
2339 net_buf_unref(*buf);
2340 *buf = NULL;
2341 }
2342 }
2343
gatt_add_nfy_to_buf(struct net_buf * buf,uint16_t handle,struct bt_gatt_notify_params * params)2344 static void gatt_add_nfy_to_buf(struct net_buf *buf,
2345 uint16_t handle,
2346 struct bt_gatt_notify_params *params)
2347 {
2348 struct bt_att_notify_mult *nfy;
2349
2350 nfy = net_buf_add(buf, sizeof(*nfy));
2351 nfy->handle = sys_cpu_to_le16(handle);
2352 nfy->len = sys_cpu_to_le16(params->len);
2353
2354 net_buf_add(buf, params->len);
2355 (void)memcpy(nfy->value, params->data, params->len);
2356 }
2357
2358 #if (CONFIG_BT_GATT_NOTIFY_MULTIPLE_FLUSH_MS != 0)
gatt_notify_mult(struct bt_conn * conn,uint16_t handle,struct bt_gatt_notify_params * params)2359 static int gatt_notify_mult(struct bt_conn *conn, uint16_t handle,
2360 struct bt_gatt_notify_params *params)
2361 {
2362 struct net_buf **buf = &nfy_mult[bt_conn_index(conn)];
2363
2364 /* Check if we can fit more data into it, in case it doesn't fit send
2365 * the existing buffer and proceed to create a new one
2366 */
2367 if (*buf && ((net_buf_tailroom(*buf) < sizeof(struct bt_att_notify_mult) + params->len) ||
2368 !bt_att_tx_meta_data_match(*buf, params->func, params->user_data,
2369 BT_ATT_CHAN_OPT(params)))) {
2370 int ret;
2371
2372 ret = gatt_notify_mult_send(conn, *buf);
2373 *buf = NULL;
2374 if (ret < 0) {
2375 return ret;
2376 }
2377 }
2378
2379 if (!*buf) {
2380 *buf = bt_att_create_pdu(conn, BT_ATT_OP_NOTIFY_MULT,
2381 sizeof(struct bt_att_notify_mult) + params->len);
2382 if (!*buf) {
2383 return -ENOMEM;
2384 }
2385
2386 bt_att_set_tx_meta_data(*buf, params->func, params->user_data,
2387 BT_ATT_CHAN_OPT(params));
2388 } else {
2389 /* Increment the number of handles, ensuring the notify callback
2390 * gets called once for every attribute.
2391 */
2392 bt_att_increment_tx_meta_data_attr_count(*buf, 1);
2393 }
2394
2395 LOG_DBG("handle 0x%04x len %u", handle, params->len);
2396 gatt_add_nfy_to_buf(*buf, handle, params);
2397
2398 /* Use `k_work_schedule` to keep the original deadline, instead of
2399 * re-setting the timeout whenever a new notification is appended.
2400 */
2401 k_work_schedule(&nfy_mult_work,
2402 K_MSEC(CONFIG_BT_GATT_NOTIFY_MULTIPLE_FLUSH_MS));
2403
2404 return 0;
2405 }
2406 #endif /* CONFIG_BT_GATT_NOTIFY_MULTIPLE_FLUSH_MS != 0 */
2407 #endif /* CONFIG_BT_GATT_NOTIFY_MULTIPLE */
2408
gatt_notify(struct bt_conn * conn,uint16_t handle,struct bt_gatt_notify_params * params)2409 static int gatt_notify(struct bt_conn *conn, uint16_t handle,
2410 struct bt_gatt_notify_params *params)
2411 {
2412 struct net_buf *buf;
2413 struct bt_att_notify *nfy;
2414
2415 #if defined(CONFIG_BT_GATT_ENFORCE_CHANGE_UNAWARE)
2416 /* BLUETOOTH CORE SPECIFICATION Version 5.3
2417 * Vol 3, Part G 2.5.3 (page 1479):
2418 *
2419 * Except for a Handle Value indication for the Service Changed
2420 * characteristic, the server shall not send notifications and
2421 * indications to such a client until it becomes change-aware.
2422 */
2423 if (!bt_gatt_change_aware(conn, false)) {
2424 return -EAGAIN;
2425 }
2426 #endif
2427
2428 /* Confirm that the connection has the correct level of security */
2429 if (bt_gatt_check_perm(conn, params->attr, BT_GATT_PERM_READ_ENCRYPT_MASK)) {
2430 LOG_WRN("Link is not encrypted");
2431 return -EPERM;
2432 }
2433
2434 if (IS_ENABLED(CONFIG_BT_GATT_ENFORCE_SUBSCRIPTION)) {
2435 /* Check if client has subscribed before sending notifications.
2436 * This is not really required in the Bluetooth specification,
2437 * but follows its spirit.
2438 */
2439 if (!bt_gatt_is_subscribed(conn, params->attr, BT_GATT_CCC_NOTIFY)) {
2440 LOG_WRN("Device is not subscribed to characteristic");
2441 return -EINVAL;
2442 }
2443 }
2444
2445 if (IS_ENABLED(CONFIG_BT_EATT) &&
2446 !bt_att_chan_opt_valid(conn, BT_ATT_CHAN_OPT(params))) {
2447 return -EINVAL;
2448 }
2449
2450 #if defined(CONFIG_BT_GATT_NOTIFY_MULTIPLE) && (CONFIG_BT_GATT_NOTIFY_MULTIPLE_FLUSH_MS != 0)
2451 if (gatt_cf_notify_multi(conn)) {
2452 return gatt_notify_mult(conn, handle, params);
2453 }
2454 #endif /* CONFIG_BT_GATT_NOTIFY_MULTIPLE */
2455
2456 buf = bt_att_create_pdu(conn, BT_ATT_OP_NOTIFY,
2457 sizeof(*nfy) + params->len);
2458 if (!buf) {
2459 LOG_WRN("No buffer available to send notification");
2460 return -ENOMEM;
2461 }
2462
2463 LOG_DBG("conn %p handle 0x%04x", conn, handle);
2464
2465 nfy = net_buf_add(buf, sizeof(*nfy));
2466 nfy->handle = sys_cpu_to_le16(handle);
2467
2468 net_buf_add(buf, params->len);
2469 memcpy(nfy->value, params->data, params->len);
2470
2471 bt_att_set_tx_meta_data(buf, params->func, params->user_data, BT_ATT_CHAN_OPT(params));
2472 return bt_att_send(conn, buf);
2473 }
2474
gatt_indicate_rsp(struct bt_conn * conn,uint8_t err,const void * pdu,uint16_t length,void * user_data)2475 static void gatt_indicate_rsp(struct bt_conn *conn, uint8_t err,
2476 const void *pdu, uint16_t length, void *user_data)
2477 {
2478 struct bt_gatt_indicate_params *params = user_data;
2479
2480 if (params->func) {
2481 params->func(conn, params, err);
2482 }
2483
2484 params->_ref--;
2485 if (params->destroy && (params->_ref == 0)) {
2486 params->destroy(params);
2487 }
2488 }
2489
gatt_req_alloc(bt_att_func_t func,void * params,bt_att_encode_t encode,uint8_t op,size_t len)2490 static struct bt_att_req *gatt_req_alloc(bt_att_func_t func, void *params,
2491 bt_att_encode_t encode,
2492 uint8_t op,
2493 size_t len)
2494 {
2495 struct bt_att_req *req;
2496
2497 /* Allocate new request */
2498 req = bt_att_req_alloc(BT_ATT_TIMEOUT);
2499 if (!req) {
2500 return NULL;
2501 }
2502
2503 #if defined(CONFIG_BT_SMP)
2504 req->att_op = op;
2505 req->len = len;
2506 req->encode = encode;
2507 #endif
2508 req->func = func;
2509 req->user_data = params;
2510
2511 return req;
2512 }
2513
2514 #ifdef CONFIG_BT_GATT_CLIENT
gatt_req_send(struct bt_conn * conn,bt_att_func_t func,void * params,bt_att_encode_t encode,uint8_t op,size_t len,enum bt_att_chan_opt chan_opt)2515 static int gatt_req_send(struct bt_conn *conn, bt_att_func_t func, void *params,
2516 bt_att_encode_t encode, uint8_t op, size_t len,
2517 enum bt_att_chan_opt chan_opt)
2518
2519 {
2520 struct bt_att_req *req;
2521 struct net_buf *buf;
2522 int err;
2523
2524 if (IS_ENABLED(CONFIG_BT_EATT) &&
2525 !bt_att_chan_opt_valid(conn, chan_opt)) {
2526 return -EINVAL;
2527 }
2528
2529 req = gatt_req_alloc(func, params, encode, op, len);
2530 if (!req) {
2531 return -ENOMEM;
2532 }
2533
2534 buf = bt_att_create_pdu(conn, op, len);
2535 if (!buf) {
2536 bt_att_req_free(req);
2537 return -ENOMEM;
2538 }
2539
2540 bt_att_set_tx_meta_data(buf, NULL, NULL, chan_opt);
2541
2542 req->buf = buf;
2543
2544 err = encode(buf, len, params);
2545 if (err) {
2546 bt_att_req_free(req);
2547 return err;
2548 }
2549
2550 err = bt_att_req_send(conn, req);
2551 if (err) {
2552 bt_att_req_free(req);
2553 }
2554
2555 return err;
2556 }
2557 #endif
2558
gatt_indicate(struct bt_conn * conn,uint16_t handle,struct bt_gatt_indicate_params * params)2559 static int gatt_indicate(struct bt_conn *conn, uint16_t handle,
2560 struct bt_gatt_indicate_params *params)
2561 {
2562 struct net_buf *buf;
2563 struct bt_att_indicate *ind;
2564 struct bt_att_req *req;
2565 size_t len;
2566 int err;
2567
2568 #if defined(CONFIG_BT_GATT_ENFORCE_CHANGE_UNAWARE)
2569 /* BLUETOOTH CORE SPECIFICATION Version 5.1 | Vol 3, Part G page 2350:
2570 * Except for the Handle Value indication, the server shall not send
2571 * notifications and indications to such a client until it becomes
2572 * change-aware.
2573 */
2574 if (!(params->func && (params->func == sc_indicate_rsp ||
2575 params->func == sc_restore_rsp)) &&
2576 !bt_gatt_change_aware(conn, false)) {
2577 return -EAGAIN;
2578 }
2579 #endif
2580
2581 /* Confirm that the connection has the correct level of security */
2582 if (bt_gatt_check_perm(conn, params->attr, BT_GATT_PERM_READ_ENCRYPT_MASK)) {
2583 LOG_WRN("Link is not encrypted");
2584 return -EPERM;
2585 }
2586
2587 if (IS_ENABLED(CONFIG_BT_GATT_ENFORCE_SUBSCRIPTION)) {
2588 /* Check if client has subscribed before sending notifications.
2589 * This is not really required in the Bluetooth specification,
2590 * but follows its spirit.
2591 */
2592 if (!bt_gatt_is_subscribed(conn, params->attr, BT_GATT_CCC_INDICATE)) {
2593 LOG_WRN("Device is not subscribed to characteristic");
2594 return -EINVAL;
2595 }
2596 }
2597
2598 if (IS_ENABLED(CONFIG_BT_EATT) &&
2599 !bt_att_chan_opt_valid(conn, BT_ATT_CHAN_OPT(params))) {
2600 return -EINVAL;
2601 }
2602
2603 len = sizeof(*ind) + params->len;
2604
2605 req = gatt_req_alloc(gatt_indicate_rsp, params, NULL,
2606 BT_ATT_OP_INDICATE, len);
2607 if (!req) {
2608 return -ENOMEM;
2609 }
2610
2611 buf = bt_att_create_pdu(conn, BT_ATT_OP_INDICATE, len);
2612 if (!buf) {
2613 LOG_WRN("No buffer available to send indication");
2614 bt_att_req_free(req);
2615 return -ENOMEM;
2616 }
2617
2618 bt_att_set_tx_meta_data(buf, NULL, NULL, BT_ATT_CHAN_OPT(params));
2619
2620 ind = net_buf_add(buf, sizeof(*ind));
2621 ind->handle = sys_cpu_to_le16(handle);
2622
2623 net_buf_add(buf, params->len);
2624 memcpy(ind->value, params->data, params->len);
2625
2626 LOG_DBG("conn %p handle 0x%04x", conn, handle);
2627
2628 req->buf = buf;
2629
2630 err = bt_att_req_send(conn, req);
2631 if (err) {
2632 bt_att_req_free(req);
2633 }
2634
2635 return err;
2636 }
2637
notify_cb(const struct bt_gatt_attr * attr,uint16_t handle,void * user_data)2638 static uint8_t notify_cb(const struct bt_gatt_attr *attr, uint16_t handle,
2639 void *user_data)
2640 {
2641 struct notify_data *data = user_data;
2642 struct _bt_gatt_ccc *ccc;
2643 size_t i;
2644
2645 /* Check attribute user_data must be of type struct _bt_gatt_ccc */
2646 if (attr->write != bt_gatt_attr_write_ccc) {
2647 return BT_GATT_ITER_CONTINUE;
2648 }
2649
2650 ccc = attr->user_data;
2651
2652 /* Save Service Changed data if peer is not connected */
2653 if (IS_ENABLED(CONFIG_BT_GATT_SERVICE_CHANGED) && ccc == &sc_ccc) {
2654 for (i = 0; i < ARRAY_SIZE(sc_cfg); i++) {
2655 struct gatt_sc_cfg *cfg = &sc_cfg[i];
2656 struct bt_conn *conn;
2657
2658 if (bt_addr_le_eq(&cfg->peer, BT_ADDR_LE_ANY)) {
2659 continue;
2660 }
2661
2662 conn = bt_conn_lookup_state_le(cfg->id, &cfg->peer,
2663 BT_CONN_CONNECTED);
2664 if (!conn) {
2665 struct sc_data *sc;
2666
2667 sc = (struct sc_data *)data->ind_params->data;
2668 sc_save(cfg->id, &cfg->peer,
2669 sys_le16_to_cpu(sc->start),
2670 sys_le16_to_cpu(sc->end));
2671 continue;
2672 }
2673
2674 bt_conn_unref(conn);
2675 }
2676 }
2677
2678 /* Notify all peers configured */
2679 for (i = 0; i < ARRAY_SIZE(ccc->cfg); i++) {
2680 struct bt_gatt_ccc_cfg *cfg = &ccc->cfg[i];
2681 struct bt_conn *conn;
2682 int err;
2683
2684 /* Check if config value matches data type since consolidated
2685 * value may be for a different peer.
2686 */
2687 if (cfg->value != data->type) {
2688 continue;
2689 }
2690
2691 conn = bt_conn_lookup_addr_le(cfg->id, &cfg->peer);
2692 if (!conn) {
2693 continue;
2694 }
2695
2696 if (conn->state != BT_CONN_CONNECTED) {
2697 bt_conn_unref(conn);
2698 continue;
2699 }
2700
2701 /* Confirm match if cfg is managed by application */
2702 if (ccc->cfg_match && !ccc->cfg_match(conn, attr)) {
2703 bt_conn_unref(conn);
2704 continue;
2705 }
2706
2707 /* Confirm that the connection has the correct level of security */
2708 if (bt_gatt_check_perm(conn, attr, BT_GATT_PERM_READ_ENCRYPT_MASK)) {
2709 LOG_WRN("Link is not encrypted");
2710 bt_conn_unref(conn);
2711 continue;
2712 }
2713
2714 /* Use the Characteristic Value handle discovered since the
2715 * Client Characteristic Configuration descriptor may occur
2716 * in any position within the characteristic definition after
2717 * the Characteristic Value.
2718 * Only notify or indicate devices which are subscribed.
2719 */
2720 if ((data->type == BT_GATT_CCC_INDICATE) &&
2721 (cfg->value & BT_GATT_CCC_INDICATE)) {
2722 err = gatt_indicate(conn, data->handle, data->ind_params);
2723 if (err == 0) {
2724 data->ind_params->_ref++;
2725 }
2726 } else if ((data->type == BT_GATT_CCC_NOTIFY) &&
2727 (cfg->value & BT_GATT_CCC_NOTIFY)) {
2728 err = gatt_notify(conn, data->handle, data->nfy_params);
2729 } else {
2730 err = 0;
2731 }
2732
2733 bt_conn_unref(conn);
2734
2735 data->err = err;
2736
2737 if (err < 0) {
2738 return BT_GATT_ITER_STOP;
2739 }
2740 }
2741
2742 return BT_GATT_ITER_CONTINUE;
2743 }
2744
match_uuid(const struct bt_gatt_attr * attr,uint16_t handle,void * user_data)2745 static uint8_t match_uuid(const struct bt_gatt_attr *attr, uint16_t handle,
2746 void *user_data)
2747 {
2748 struct notify_data *data = user_data;
2749
2750 data->attr = attr;
2751 data->handle = handle;
2752
2753 return BT_GATT_ITER_STOP;
2754 }
2755
gatt_find_by_uuid(struct notify_data * found,const struct bt_uuid * uuid)2756 static bool gatt_find_by_uuid(struct notify_data *found,
2757 const struct bt_uuid *uuid)
2758 {
2759 found->attr = NULL;
2760
2761 bt_gatt_foreach_attr_type(found->handle, 0xffff, uuid, NULL, 1,
2762 match_uuid, found);
2763
2764 return found->attr ? true : false;
2765 }
2766
bt_gatt_find_by_uuid(const struct bt_gatt_attr * attr,uint16_t attr_count,const struct bt_uuid * uuid)2767 struct bt_gatt_attr *bt_gatt_find_by_uuid(const struct bt_gatt_attr *attr,
2768 uint16_t attr_count,
2769 const struct bt_uuid *uuid)
2770 {
2771 struct bt_gatt_attr *found = NULL;
2772 uint16_t start_handle = bt_gatt_attr_value_handle(attr);
2773 uint16_t end_handle = start_handle && attr_count ?
2774 start_handle + attr_count : 0xffff;
2775
2776 bt_gatt_foreach_attr_type(start_handle, end_handle, uuid, NULL, 1,
2777 find_next, &found);
2778
2779 return found;
2780 }
2781
bt_gatt_notify_cb(struct bt_conn * conn,struct bt_gatt_notify_params * params)2782 int bt_gatt_notify_cb(struct bt_conn *conn,
2783 struct bt_gatt_notify_params *params)
2784 {
2785 struct notify_data data;
2786
2787 __ASSERT(params, "invalid parameters\n");
2788 __ASSERT(params->attr || params->uuid, "invalid parameters\n");
2789
2790 if (!atomic_test_bit(bt_dev.flags, BT_DEV_READY)) {
2791 return -EAGAIN;
2792 }
2793
2794 if (conn && conn->state != BT_CONN_CONNECTED) {
2795 return -ENOTCONN;
2796 }
2797
2798 data.attr = params->attr;
2799 data.handle = bt_gatt_attr_get_handle(data.attr);
2800
2801 /* Lookup UUID if it was given */
2802 if (params->uuid) {
2803 if (!gatt_find_by_uuid(&data, params->uuid)) {
2804 return -ENOENT;
2805 }
2806
2807 params->attr = data.attr;
2808 } else {
2809 if (!data.handle) {
2810 return -ENOENT;
2811 }
2812 }
2813
2814 /* Check if attribute is a characteristic then adjust the handle */
2815 if (!bt_uuid_cmp(data.attr->uuid, BT_UUID_GATT_CHRC)) {
2816 struct bt_gatt_chrc *chrc = data.attr->user_data;
2817
2818 if (!(chrc->properties & BT_GATT_CHRC_NOTIFY)) {
2819 return -EINVAL;
2820 }
2821
2822 data.handle = bt_gatt_attr_value_handle(data.attr);
2823 }
2824
2825 if (conn) {
2826 return gatt_notify(conn, data.handle, params);
2827 }
2828
2829 data.err = -ENOTCONN;
2830 data.type = BT_GATT_CCC_NOTIFY;
2831 data.nfy_params = params;
2832
2833 bt_gatt_foreach_attr_type(data.handle, 0xffff, BT_UUID_GATT_CCC, NULL,
2834 1, notify_cb, &data);
2835
2836 return data.err;
2837 }
2838
2839 #if defined(CONFIG_BT_GATT_NOTIFY_MULTIPLE)
gatt_notify_multiple_verify_args(struct bt_conn * conn,struct bt_gatt_notify_params params[],uint16_t num_params)2840 static int gatt_notify_multiple_verify_args(struct bt_conn *conn,
2841 struct bt_gatt_notify_params params[],
2842 uint16_t num_params)
2843 {
2844 __ASSERT(params, "invalid parameters\n");
2845 __ASSERT(params->attr, "invalid parameters\n");
2846
2847 CHECKIF(num_params < 2) {
2848 /* Use the standard notification API when sending only one
2849 * notification.
2850 */
2851 return -EINVAL;
2852 }
2853
2854 CHECKIF(conn == NULL) {
2855 /* Use the standard notification API to send to all connected
2856 * peers.
2857 */
2858 return -EINVAL;
2859 }
2860
2861 if (!atomic_test_bit(bt_dev.flags, BT_DEV_READY)) {
2862 return -EAGAIN;
2863 }
2864
2865 if (conn->state != BT_CONN_CONNECTED) {
2866 return -ENOTCONN;
2867 }
2868
2869 #if defined(CONFIG_BT_GATT_ENFORCE_CHANGE_UNAWARE)
2870 /* BLUETOOTH CORE SPECIFICATION Version 5.3
2871 * Vol 3, Part G 2.5.3 (page 1479):
2872 *
2873 * Except for a Handle Value indication for the Service Changed
2874 * characteristic, the server shall not send notifications and
2875 * indications to such a client until it becomes change-aware.
2876 */
2877 if (!bt_gatt_change_aware(conn, false)) {
2878 return -EAGAIN;
2879 }
2880 #endif
2881
2882 /* This API guarantees an ATT_MULTIPLE_HANDLE_VALUE_NTF over the air. */
2883 if (!gatt_cf_notify_multi(conn)) {
2884 return -EOPNOTSUPP;
2885 }
2886
2887 return 0;
2888 }
2889
gatt_notify_multiple_verify_params(struct bt_conn * conn,struct bt_gatt_notify_params params[],uint16_t num_params,size_t * total_len)2890 static int gatt_notify_multiple_verify_params(struct bt_conn *conn,
2891 struct bt_gatt_notify_params params[],
2892 uint16_t num_params, size_t *total_len)
2893 {
2894 for (uint16_t i = 0; i < num_params; i++) {
2895 /* Compute the total data length. */
2896 *total_len += params[i].len;
2897
2898 /* Confirm that the connection has the correct level of security. */
2899 if (bt_gatt_check_perm(conn, params[i].attr,
2900 BT_GATT_PERM_READ_ENCRYPT |
2901 BT_GATT_PERM_READ_AUTHEN)) {
2902 LOG_WRN("Link is not encrypted");
2903 return -EPERM;
2904 }
2905
2906 /* The current implementation requires the same callbacks and
2907 * user_data.
2908 */
2909 if ((params[0].func != params[i].func) ||
2910 (params[0].user_data != params[i].user_data)) {
2911 return -EINVAL;
2912 }
2913
2914 /* This API doesn't support passing UUIDs. */
2915 if (params[i].uuid) {
2916 return -EINVAL;
2917 }
2918
2919 /* Check if the supplied handle is invalid. */
2920 if (!bt_gatt_attr_get_handle(params[i].attr)) {
2921 return -EINVAL;
2922 }
2923
2924 /* Check if the characteristic is subscribed. */
2925 if (IS_ENABLED(CONFIG_BT_GATT_ENFORCE_SUBSCRIPTION) &&
2926 !bt_gatt_is_subscribed(conn, params[i].attr,
2927 BT_GATT_CCC_NOTIFY)) {
2928 LOG_WRN("Device is not subscribed to characteristic");
2929 return -EINVAL;
2930 }
2931 }
2932
2933 /* PDU length is specified with a 16-bit value. */
2934 if (*total_len > UINT16_MAX) {
2935 return -ERANGE;
2936 }
2937
2938 /* Check there is a bearer with a high enough MTU. */
2939 if (bt_att_get_mtu(conn) <
2940 (sizeof(struct bt_att_notify_mult) + *total_len)) {
2941 return -ERANGE;
2942 }
2943
2944 return 0;
2945 }
2946
bt_gatt_notify_multiple(struct bt_conn * conn,uint16_t num_params,struct bt_gatt_notify_params params[])2947 int bt_gatt_notify_multiple(struct bt_conn *conn,
2948 uint16_t num_params,
2949 struct bt_gatt_notify_params params[])
2950 {
2951 int err;
2952 size_t total_len = 0;
2953 struct net_buf *buf;
2954
2955 /* Validate arguments, connection state and feature support. */
2956 err = gatt_notify_multiple_verify_args(conn, params, num_params);
2957 if (err) {
2958 return err;
2959 }
2960
2961 /* Validate all the attributes that we want to notify.
2962 * Also gets us the total length of the PDU as a side-effect.
2963 */
2964 err = gatt_notify_multiple_verify_params(conn, params, num_params, &total_len);
2965 if (err) {
2966 return err;
2967 }
2968
2969 /* Send any outstanding notifications.
2970 * Frees up buffer space for our PDU.
2971 */
2972 gatt_notify_flush(conn);
2973
2974 /* Build the PDU */
2975 buf = bt_att_create_pdu(conn, BT_ATT_OP_NOTIFY_MULT,
2976 sizeof(struct bt_att_notify_mult) + total_len);
2977 if (!buf) {
2978 return -ENOMEM;
2979 }
2980
2981 /* Register the callback. It will be called num_params times. */
2982 bt_att_set_tx_meta_data(buf, params->func, params->user_data, BT_ATT_CHAN_OPT(params));
2983 bt_att_increment_tx_meta_data_attr_count(buf, num_params - 1);
2984
2985 for (uint16_t i = 0; i < num_params; i++) {
2986 struct notify_data data;
2987
2988 data.attr = params[i].attr;
2989 data.handle = bt_gatt_attr_get_handle(data.attr);
2990
2991 /* Check if attribute is a characteristic then adjust the
2992 * handle
2993 */
2994 if (!bt_uuid_cmp(data.attr->uuid, BT_UUID_GATT_CHRC)) {
2995 data.handle = bt_gatt_attr_value_handle(data.attr);
2996 }
2997
2998 /* Add handle and data to the command buffer. */
2999 gatt_add_nfy_to_buf(buf, data.handle, ¶ms[i]);
3000 }
3001
3002 /* Send the buffer. */
3003 return gatt_notify_mult_send(conn, buf);
3004 }
3005 #endif /* CONFIG_BT_GATT_NOTIFY_MULTIPLE */
3006
bt_gatt_indicate(struct bt_conn * conn,struct bt_gatt_indicate_params * params)3007 int bt_gatt_indicate(struct bt_conn *conn,
3008 struct bt_gatt_indicate_params *params)
3009 {
3010 struct notify_data data;
3011
3012 __ASSERT(params, "invalid parameters\n");
3013 __ASSERT(params->attr || params->uuid, "invalid parameters\n");
3014
3015 if (!atomic_test_bit(bt_dev.flags, BT_DEV_READY)) {
3016 return -EAGAIN;
3017 }
3018
3019 if (conn && conn->state != BT_CONN_CONNECTED) {
3020 return -ENOTCONN;
3021 }
3022
3023 data.attr = params->attr;
3024 data.handle = bt_gatt_attr_get_handle(data.attr);
3025
3026 /* Lookup UUID if it was given */
3027 if (params->uuid) {
3028 if (!gatt_find_by_uuid(&data, params->uuid)) {
3029 return -ENOENT;
3030 }
3031
3032 params->attr = data.attr;
3033 } else {
3034 if (!data.handle) {
3035 return -ENOENT;
3036 }
3037 }
3038
3039 /* Check if attribute is a characteristic then adjust the handle */
3040 if (!bt_uuid_cmp(data.attr->uuid, BT_UUID_GATT_CHRC)) {
3041 struct bt_gatt_chrc *chrc = data.attr->user_data;
3042
3043 if (!(chrc->properties & BT_GATT_CHRC_INDICATE)) {
3044 return -EINVAL;
3045 }
3046
3047 data.handle = bt_gatt_attr_value_handle(data.attr);
3048 }
3049
3050 if (conn) {
3051 params->_ref = 1;
3052 return gatt_indicate(conn, data.handle, params);
3053 }
3054
3055 data.err = -ENOTCONN;
3056 data.type = BT_GATT_CCC_INDICATE;
3057 data.ind_params = params;
3058
3059 params->_ref = 0;
3060 bt_gatt_foreach_attr_type(data.handle, 0xffff, BT_UUID_GATT_CCC, NULL,
3061 1, notify_cb, &data);
3062
3063 return data.err;
3064 }
3065
bt_gatt_get_mtu(struct bt_conn * conn)3066 uint16_t bt_gatt_get_mtu(struct bt_conn *conn)
3067 {
3068 return bt_att_get_mtu(conn);
3069 }
3070
bt_gatt_check_perm(struct bt_conn * conn,const struct bt_gatt_attr * attr,uint16_t mask)3071 uint8_t bt_gatt_check_perm(struct bt_conn *conn, const struct bt_gatt_attr *attr,
3072 uint16_t mask)
3073 {
3074 if ((mask & BT_GATT_PERM_READ) &&
3075 (!(attr->perm & BT_GATT_PERM_READ_MASK) || !attr->read)) {
3076 return BT_ATT_ERR_READ_NOT_PERMITTED;
3077 }
3078
3079 if ((mask & BT_GATT_PERM_WRITE) &&
3080 (!(attr->perm & BT_GATT_PERM_WRITE_MASK) || !attr->write)) {
3081 return BT_ATT_ERR_WRITE_NOT_PERMITTED;
3082 }
3083
3084 if (IS_ENABLED(CONFIG_BT_CONN_DISABLE_SECURITY)) {
3085 return 0;
3086 }
3087
3088 mask &= attr->perm;
3089
3090 /*
3091 * Core Specification 5.4 Vol. 3 Part C 10.3.1
3092 *
3093 * If neither an LTK nor an STK is available, the service
3094 * request shall be rejected with the error code
3095 * “Insufficient Authentication”.
3096 * Note: When the link is not encrypted, the error code
3097 * “Insufficient Authentication” does not indicate that
3098 * MITM protection is required.
3099 *
3100 * If an LTK or an STK is available and encryption is
3101 * required (LE security mode 1) but encryption is not
3102 * enabled, the service request shall be rejected with
3103 * the error code “Insufficient Encryption”.
3104 */
3105
3106 if (mask & (BT_GATT_PERM_ENCRYPT_MASK | BT_GATT_PERM_AUTHEN_MASK)) {
3107 #if defined(CONFIG_BT_SMP)
3108 if (!conn->encrypt) {
3109 if (bt_conn_ltk_present(conn)) {
3110 return BT_ATT_ERR_INSUFFICIENT_ENCRYPTION;
3111 } else {
3112 return BT_ATT_ERR_AUTHENTICATION;
3113 }
3114 }
3115
3116 if (mask & BT_GATT_PERM_AUTHEN_MASK) {
3117 if (bt_conn_get_security(conn) < BT_SECURITY_L3) {
3118 return BT_ATT_ERR_AUTHENTICATION;
3119 }
3120 }
3121
3122 if (mask & BT_GATT_PERM_LESC_MASK) {
3123 const struct bt_keys *keys = conn->le.keys;
3124
3125 if (!keys || (keys->flags & BT_KEYS_SC) == 0) {
3126 return BT_ATT_ERR_AUTHENTICATION;
3127 }
3128 }
3129 #else
3130 return BT_ATT_ERR_AUTHENTICATION;
3131 #endif /* CONFIG_BT_SMP */
3132 }
3133
3134 return 0;
3135 }
3136
sc_restore_rsp(struct bt_conn * conn,struct bt_gatt_indicate_params * params,uint8_t err)3137 static void sc_restore_rsp(struct bt_conn *conn,
3138 struct bt_gatt_indicate_params *params, uint8_t err)
3139 {
3140 #if defined(CONFIG_BT_GATT_CACHING)
3141 struct gatt_cf_cfg *cfg;
3142 #endif
3143
3144 LOG_DBG("err 0x%02x", err);
3145
3146 #if defined(CONFIG_BT_GATT_CACHING)
3147 /* BLUETOOTH CORE SPECIFICATION Version 5.3 | Vol 3, Part G page 1476:
3148 * 2.5.2.1 Robust Caching
3149 * ... a change-unaware connected client using exactly one ATT bearer
3150 * becomes change-aware when ...
3151 * The client receives and confirms a Handle Value Indication
3152 * for the Service Changed characteristic
3153 */
3154
3155 if (bt_att_fixed_chan_only(conn)) {
3156 cfg = find_cf_cfg(conn);
3157 if (cfg && CF_ROBUST_CACHING(cfg)) {
3158 set_change_aware(cfg, true);
3159 }
3160 }
3161 #endif /* CONFIG_BT_GATT_CACHING */
3162
3163 if (!err && IS_ENABLED(CONFIG_BT_GATT_SERVICE_CHANGED)) {
3164 struct gatt_sc_cfg *gsc_cfg = find_sc_cfg(conn->id, &conn->le.dst);
3165
3166 if (gsc_cfg) {
3167 sc_reset(gsc_cfg);
3168 }
3169 }
3170 }
3171
3172 static struct bt_gatt_indicate_params sc_restore_params[CONFIG_BT_MAX_CONN];
3173 static uint16_t sc_range[CONFIG_BT_MAX_CONN][2];
3174
sc_restore(struct bt_conn * conn)3175 static void sc_restore(struct bt_conn *conn)
3176 {
3177 struct gatt_sc_cfg *cfg;
3178 uint8_t index;
3179
3180 cfg = find_sc_cfg(conn->id, &conn->le.dst);
3181 if (!cfg) {
3182 LOG_DBG("no SC data found");
3183 return;
3184 }
3185
3186 if (!(cfg->data.start || cfg->data.end)) {
3187 return;
3188 }
3189
3190 LOG_DBG("peer %s start 0x%04x end 0x%04x", bt_addr_le_str(&cfg->peer), cfg->data.start,
3191 cfg->data.end);
3192
3193 index = bt_conn_index(conn);
3194
3195 sc_range[index][0] = sys_cpu_to_le16(cfg->data.start);
3196 sc_range[index][1] = sys_cpu_to_le16(cfg->data.end);
3197
3198 sc_restore_params[index].attr = &_1_gatt_svc.attrs[2];
3199 sc_restore_params[index].func = sc_restore_rsp;
3200 sc_restore_params[index].data = &sc_range[index][0];
3201 sc_restore_params[index].len = sizeof(sc_range[index]);
3202
3203 if (bt_gatt_indicate(conn, &sc_restore_params[index])) {
3204 LOG_ERR("SC restore indication failed");
3205 }
3206 }
3207
3208 struct conn_data {
3209 struct bt_conn *conn;
3210 bt_security_t sec;
3211 };
3212
update_ccc(const struct bt_gatt_attr * attr,uint16_t handle,void * user_data)3213 static uint8_t update_ccc(const struct bt_gatt_attr *attr, uint16_t handle,
3214 void *user_data)
3215 {
3216 struct conn_data *data = user_data;
3217 struct bt_conn *conn = data->conn;
3218 struct _bt_gatt_ccc *ccc;
3219 size_t i;
3220 uint8_t err;
3221
3222 /* Check attribute user_data must be of type struct _bt_gatt_ccc */
3223 if (attr->write != bt_gatt_attr_write_ccc) {
3224 return BT_GATT_ITER_CONTINUE;
3225 }
3226
3227 ccc = attr->user_data;
3228
3229 for (i = 0; i < ARRAY_SIZE(ccc->cfg); i++) {
3230 struct bt_gatt_ccc_cfg *cfg = &ccc->cfg[i];
3231
3232 /* Ignore configuration for different peer or not active */
3233 if (!cfg->value ||
3234 !bt_conn_is_peer_addr_le(conn, cfg->id, &cfg->peer)) {
3235 continue;
3236 }
3237
3238 /* Check if attribute requires encryption/authentication */
3239 err = bt_gatt_check_perm(conn, attr, BT_GATT_PERM_WRITE_MASK);
3240 if (err) {
3241 bt_security_t sec;
3242
3243 if (err == BT_ATT_ERR_WRITE_NOT_PERMITTED) {
3244 LOG_WRN("CCC %p not writable", attr);
3245 continue;
3246 }
3247
3248 sec = BT_SECURITY_L2;
3249
3250 if (err == BT_ATT_ERR_AUTHENTICATION) {
3251 sec = BT_SECURITY_L3;
3252 }
3253
3254 /* Check if current security is enough */
3255 if (IS_ENABLED(CONFIG_BT_SMP) &&
3256 bt_conn_get_security(conn) < sec) {
3257 if (data->sec < sec) {
3258 data->sec = sec;
3259 }
3260 continue;
3261 }
3262 }
3263
3264 gatt_ccc_changed(attr, ccc);
3265
3266 if (IS_ENABLED(CONFIG_BT_GATT_SERVICE_CHANGED) &&
3267 ccc == &sc_ccc) {
3268 sc_restore(conn);
3269 }
3270
3271 return BT_GATT_ITER_CONTINUE;
3272 }
3273
3274 return BT_GATT_ITER_CONTINUE;
3275 }
3276
disconnected_cb(const struct bt_gatt_attr * attr,uint16_t handle,void * user_data)3277 static uint8_t disconnected_cb(const struct bt_gatt_attr *attr, uint16_t handle,
3278 void *user_data)
3279 {
3280 struct bt_conn *conn = user_data;
3281 struct _bt_gatt_ccc *ccc;
3282 bool value_used;
3283 size_t i;
3284
3285 /* Check attribute user_data must be of type struct _bt_gatt_ccc */
3286 if (attr->write != bt_gatt_attr_write_ccc) {
3287 return BT_GATT_ITER_CONTINUE;
3288 }
3289
3290 ccc = attr->user_data;
3291
3292 /* If already disabled skip */
3293 if (!ccc->value) {
3294 return BT_GATT_ITER_CONTINUE;
3295 }
3296
3297 /* Checking if all values are disabled */
3298 value_used = false;
3299
3300 for (i = 0; i < ARRAY_SIZE(ccc->cfg); i++) {
3301 struct bt_gatt_ccc_cfg *cfg = &ccc->cfg[i];
3302
3303 /* Ignore configurations with disabled value */
3304 if (!cfg->value) {
3305 continue;
3306 }
3307
3308 if (!bt_conn_is_peer_addr_le(conn, cfg->id, &cfg->peer)) {
3309 struct bt_conn *tmp;
3310
3311 /* Skip if there is another peer connected */
3312 tmp = bt_conn_lookup_addr_le(cfg->id, &cfg->peer);
3313 if (tmp) {
3314 if (tmp->state == BT_CONN_CONNECTED) {
3315 value_used = true;
3316 }
3317
3318 bt_conn_unref(tmp);
3319 }
3320 } else {
3321 /* Clear value if not paired */
3322 if (!bt_addr_le_is_bonded(conn->id, &conn->le.dst)) {
3323 if (ccc == &sc_ccc) {
3324 sc_clear(conn);
3325 }
3326
3327 clear_ccc_cfg(cfg);
3328 } else {
3329 /* Update address in case it has changed */
3330 bt_addr_le_copy(&cfg->peer, &conn->le.dst);
3331 }
3332 }
3333 }
3334
3335 /* If all values are now disabled, reset value while disconnected */
3336 if (!value_used) {
3337 ccc->value = 0U;
3338 if (ccc->cfg_changed) {
3339 ccc->cfg_changed(attr, ccc->value);
3340 }
3341
3342 LOG_DBG("ccc %p reseted", ccc);
3343 }
3344
3345 return BT_GATT_ITER_CONTINUE;
3346 }
3347
bt_gatt_is_subscribed(struct bt_conn * conn,const struct bt_gatt_attr * attr,uint16_t ccc_type)3348 bool bt_gatt_is_subscribed(struct bt_conn *conn,
3349 const struct bt_gatt_attr *attr, uint16_t ccc_type)
3350 {
3351 const struct _bt_gatt_ccc *ccc;
3352
3353 __ASSERT(conn, "invalid parameter\n");
3354 __ASSERT(attr, "invalid parameter\n");
3355
3356 if (conn->state != BT_CONN_CONNECTED) {
3357 return false;
3358 }
3359
3360 /* Check if attribute is a characteristic declaration */
3361 if (!bt_uuid_cmp(attr->uuid, BT_UUID_GATT_CHRC)) {
3362 struct bt_gatt_chrc *chrc = attr->user_data;
3363
3364 if (!(chrc->properties &
3365 (BT_GATT_CHRC_NOTIFY | BT_GATT_CHRC_INDICATE))) {
3366 /* Characteristic doesn't support subscription */
3367 return false;
3368 }
3369
3370 attr = bt_gatt_attr_next(attr);
3371 __ASSERT(attr, "No more attributes\n");
3372 }
3373
3374 /* Check if attribute is a characteristic value */
3375 if (bt_uuid_cmp(attr->uuid, BT_UUID_GATT_CCC) != 0) {
3376 attr = bt_gatt_attr_next(attr);
3377 __ASSERT(attr, "No more attributes\n");
3378 }
3379
3380 /* Find the CCC Descriptor */
3381 while (bt_uuid_cmp(attr->uuid, BT_UUID_GATT_CCC) &&
3382 /* Also stop if we leave the current characteristic definition */
3383 bt_uuid_cmp(attr->uuid, BT_UUID_GATT_CHRC) &&
3384 bt_uuid_cmp(attr->uuid, BT_UUID_GATT_PRIMARY) &&
3385 bt_uuid_cmp(attr->uuid, BT_UUID_GATT_SECONDARY)) {
3386 attr = bt_gatt_attr_next(attr);
3387 if (!attr) {
3388 return false;
3389 }
3390 }
3391
3392 if (bt_uuid_cmp(attr->uuid, BT_UUID_GATT_CCC) != 0) {
3393 return false;
3394 }
3395
3396 ccc = attr->user_data;
3397
3398 /* Check if the connection is subscribed */
3399 for (size_t i = 0; i < BT_GATT_CCC_MAX; i++) {
3400 const struct bt_gatt_ccc_cfg *cfg = &ccc->cfg[i];
3401
3402 if (bt_conn_is_peer_addr_le(conn, cfg->id, &cfg->peer) &&
3403 (ccc_type & ccc->cfg[i].value)) {
3404 return true;
3405 }
3406 }
3407
3408 return false;
3409 }
3410
gatt_sub_is_empty(struct gatt_sub * sub)3411 static bool gatt_sub_is_empty(struct gatt_sub *sub)
3412 {
3413 return sys_slist_is_empty(&sub->list);
3414 }
3415
3416 /** @brief Free sub for reuse.
3417 */
gatt_sub_free(struct gatt_sub * sub)3418 static void gatt_sub_free(struct gatt_sub *sub)
3419 {
3420 __ASSERT_NO_MSG(gatt_sub_is_empty(sub));
3421 bt_addr_le_copy(&sub->peer, BT_ADDR_LE_ANY);
3422 }
3423
gatt_sub_remove(struct bt_conn * conn,struct gatt_sub * sub,sys_snode_t * prev,struct bt_gatt_subscribe_params * params)3424 static void gatt_sub_remove(struct bt_conn *conn, struct gatt_sub *sub,
3425 sys_snode_t *prev,
3426 struct bt_gatt_subscribe_params *params)
3427 {
3428 if (params) {
3429 /* Remove subscription from the list*/
3430 sys_slist_remove(&sub->list, prev, ¶ms->node);
3431 /* Notify removal */
3432 params->notify(conn, params, NULL, 0);
3433 }
3434
3435 if (gatt_sub_is_empty(sub)) {
3436 gatt_sub_free(sub);
3437 }
3438 }
3439
3440 #if defined(CONFIG_BT_GATT_CLIENT)
gatt_sub_find(struct bt_conn * conn)3441 static struct gatt_sub *gatt_sub_find(struct bt_conn *conn)
3442 {
3443 for (int i = 0; i < ARRAY_SIZE(subscriptions); i++) {
3444 struct gatt_sub *sub = &subscriptions[i];
3445
3446 if (!conn) {
3447 if (bt_addr_le_eq(&sub->peer, BT_ADDR_LE_ANY)) {
3448 return sub;
3449 }
3450 } else if (bt_conn_is_peer_addr_le(conn, sub->id, &sub->peer)) {
3451 return sub;
3452 }
3453 }
3454
3455 return NULL;
3456 }
3457
gatt_sub_add(struct bt_conn * conn)3458 static struct gatt_sub *gatt_sub_add(struct bt_conn *conn)
3459 {
3460 struct gatt_sub *sub;
3461
3462 sub = gatt_sub_find(conn);
3463 if (!sub) {
3464 sub = gatt_sub_find(NULL);
3465 if (sub) {
3466 bt_addr_le_copy(&sub->peer, &conn->le.dst);
3467 sub->id = conn->id;
3468 }
3469 }
3470
3471 return sub;
3472 }
3473
gatt_sub_find_by_addr(uint8_t id,const bt_addr_le_t * addr)3474 static struct gatt_sub *gatt_sub_find_by_addr(uint8_t id,
3475 const bt_addr_le_t *addr)
3476 {
3477 for (int i = 0; i < ARRAY_SIZE(subscriptions); i++) {
3478 struct gatt_sub *sub = &subscriptions[i];
3479
3480 if (id == sub->id && bt_addr_le_eq(&sub->peer, addr)) {
3481 return sub;
3482 }
3483 }
3484
3485 return NULL;
3486 }
3487
gatt_sub_add_by_addr(uint8_t id,const bt_addr_le_t * addr)3488 static struct gatt_sub *gatt_sub_add_by_addr(uint8_t id,
3489 const bt_addr_le_t *addr)
3490 {
3491 struct gatt_sub *sub;
3492
3493 sub = gatt_sub_find_by_addr(id, addr);
3494 if (!sub) {
3495 sub = gatt_sub_find(NULL);
3496 if (sub) {
3497 bt_addr_le_copy(&sub->peer, addr);
3498 sub->id = id;
3499 }
3500 }
3501
3502 return sub;
3503 }
3504
check_subscribe_security_level(struct bt_conn * conn,const struct bt_gatt_subscribe_params * params)3505 static bool check_subscribe_security_level(struct bt_conn *conn,
3506 const struct bt_gatt_subscribe_params *params)
3507 {
3508 #if defined(CONFIG_BT_SMP)
3509 return conn->sec_level >= params->min_security;
3510 #endif
3511 return true;
3512 }
3513
bt_gatt_notification(struct bt_conn * conn,uint16_t handle,const void * data,uint16_t length)3514 void bt_gatt_notification(struct bt_conn *conn, uint16_t handle,
3515 const void *data, uint16_t length)
3516 {
3517 struct bt_gatt_subscribe_params *params, *tmp;
3518 struct gatt_sub *sub;
3519
3520 LOG_DBG("handle 0x%04x length %u", handle, length);
3521
3522 sub = gatt_sub_find(conn);
3523 if (!sub) {
3524 return;
3525 }
3526
3527 SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&sub->list, params, tmp, node) {
3528 if (handle != params->value_handle) {
3529 continue;
3530 }
3531
3532 if (check_subscribe_security_level(conn, params)) {
3533 if (params->notify(conn, params, data, length) ==
3534 BT_GATT_ITER_STOP) {
3535 bt_gatt_unsubscribe(conn, params);
3536 }
3537 }
3538 }
3539 }
3540
bt_gatt_mult_notification(struct bt_conn * conn,const void * data,uint16_t length)3541 void bt_gatt_mult_notification(struct bt_conn *conn, const void *data,
3542 uint16_t length)
3543 {
3544 struct bt_gatt_subscribe_params *params, *tmp;
3545 const struct bt_att_notify_mult *nfy;
3546 struct net_buf_simple buf;
3547 struct gatt_sub *sub;
3548
3549 LOG_DBG("length %u", length);
3550
3551 sub = gatt_sub_find(conn);
3552 if (!sub) {
3553 return;
3554 }
3555
3556 /* This is fine since there no write operation to the buffer. */
3557 net_buf_simple_init_with_data(&buf, (void *)data, length);
3558
3559 while (buf.len > sizeof(*nfy)) {
3560 uint16_t handle;
3561 uint16_t len;
3562
3563 nfy = net_buf_simple_pull_mem(&buf, sizeof(*nfy));
3564 handle = sys_cpu_to_le16(nfy->handle);
3565 len = sys_cpu_to_le16(nfy->len);
3566
3567 LOG_DBG("handle 0x%02x len %u", handle, len);
3568
3569 if (len > buf.len) {
3570 LOG_ERR("Invalid data len %u > %u", len, length);
3571 return;
3572 }
3573
3574 SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&sub->list, params, tmp,
3575 node) {
3576 if (handle != params->value_handle) {
3577 continue;
3578 }
3579
3580 if (check_subscribe_security_level(conn, params)) {
3581 if (params->notify(conn, params, nfy->value, len) ==
3582 BT_GATT_ITER_STOP) {
3583 bt_gatt_unsubscribe(conn, params);
3584 }
3585 }
3586 }
3587
3588 net_buf_simple_pull_mem(&buf, len);
3589 }
3590 }
3591
gatt_sub_update(struct bt_conn * conn,struct gatt_sub * sub)3592 static void gatt_sub_update(struct bt_conn *conn, struct gatt_sub *sub)
3593 {
3594 if (sub->peer.type == BT_ADDR_LE_PUBLIC) {
3595 return;
3596 }
3597
3598 /* Update address */
3599 bt_addr_le_copy(&sub->peer, &conn->le.dst);
3600 }
3601
remove_subscriptions(struct bt_conn * conn)3602 static void remove_subscriptions(struct bt_conn *conn)
3603 {
3604 struct gatt_sub *sub;
3605 struct bt_gatt_subscribe_params *params, *tmp;
3606 sys_snode_t *prev = NULL;
3607
3608 sub = gatt_sub_find(conn);
3609 if (!sub) {
3610 return;
3611 }
3612
3613 /* Lookup existing subscriptions */
3614 SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&sub->list, params, tmp, node) {
3615 atomic_clear_bit(params->flags, BT_GATT_SUBSCRIBE_FLAG_SENT);
3616
3617 if (!bt_addr_le_is_bonded(conn->id, &conn->le.dst) ||
3618 (atomic_test_bit(params->flags,
3619 BT_GATT_SUBSCRIBE_FLAG_VOLATILE))) {
3620 /* Remove subscription */
3621 params->value = 0U;
3622 gatt_sub_remove(conn, sub, prev, params);
3623 } else {
3624 gatt_sub_update(conn, sub);
3625 prev = ¶ms->node;
3626 }
3627 }
3628 }
3629
gatt_mtu_rsp(struct bt_conn * conn,uint8_t err,const void * pdu,uint16_t length,void * user_data)3630 static void gatt_mtu_rsp(struct bt_conn *conn, uint8_t err, const void *pdu,
3631 uint16_t length, void *user_data)
3632 {
3633 struct bt_gatt_exchange_params *params = user_data;
3634
3635 params->func(conn, err, params);
3636 }
3637
gatt_exchange_mtu_encode(struct net_buf * buf,size_t len,void * user_data)3638 static int gatt_exchange_mtu_encode(struct net_buf *buf, size_t len,
3639 void *user_data)
3640 {
3641 struct bt_att_exchange_mtu_req *req;
3642 uint16_t mtu;
3643
3644 mtu = BT_LOCAL_ATT_MTU_UATT;
3645
3646 LOG_DBG("Client MTU %u", mtu);
3647
3648 req = net_buf_add(buf, sizeof(*req));
3649 req->mtu = sys_cpu_to_le16(mtu);
3650
3651 return 0;
3652 }
3653
bt_gatt_exchange_mtu(struct bt_conn * conn,struct bt_gatt_exchange_params * params)3654 int bt_gatt_exchange_mtu(struct bt_conn *conn,
3655 struct bt_gatt_exchange_params *params)
3656 {
3657 int err;
3658
3659 __ASSERT(conn, "invalid parameter\n");
3660 __ASSERT(params && params->func, "invalid parameters\n");
3661
3662 if (conn->state != BT_CONN_CONNECTED) {
3663 return -ENOTCONN;
3664 }
3665
3666 /* This request shall only be sent once during a connection by the client. */
3667 if (atomic_test_and_set_bit(conn->flags, BT_CONN_ATT_MTU_EXCHANGED)) {
3668 return -EALREADY;
3669 }
3670
3671 err = gatt_req_send(conn, gatt_mtu_rsp, params,
3672 gatt_exchange_mtu_encode, BT_ATT_OP_MTU_REQ,
3673 sizeof(struct bt_att_exchange_mtu_req),
3674 BT_ATT_CHAN_OPT_UNENHANCED_ONLY);
3675 if (err) {
3676 atomic_clear_bit(conn->flags, BT_CONN_ATT_MTU_EXCHANGED);
3677 }
3678
3679 return err;
3680 }
3681
gatt_discover_next(struct bt_conn * conn,uint16_t last_handle,struct bt_gatt_discover_params * params)3682 static void gatt_discover_next(struct bt_conn *conn, uint16_t last_handle,
3683 struct bt_gatt_discover_params *params)
3684 {
3685 /* Skip if last_handle is not set */
3686 if (!last_handle)
3687 goto discover;
3688
3689 /* Continue from the last found handle */
3690 params->start_handle = last_handle;
3691 if (params->start_handle < UINT16_MAX) {
3692 params->start_handle++;
3693 } else {
3694 goto done;
3695 }
3696
3697 /* Stop if over the range or the requests */
3698 if (params->start_handle > params->end_handle) {
3699 goto done;
3700 }
3701
3702 discover:
3703 /* Discover next range */
3704 if (!bt_gatt_discover(conn, params)) {
3705 return;
3706 }
3707
3708 done:
3709 params->func(conn, NULL, params);
3710 }
3711
gatt_find_type_rsp(struct bt_conn * conn,uint8_t err,const void * pdu,uint16_t length,void * user_data)3712 static void gatt_find_type_rsp(struct bt_conn *conn, uint8_t err,
3713 const void *pdu, uint16_t length,
3714 void *user_data)
3715 {
3716 const struct bt_att_handle_group *rsp = pdu;
3717 struct bt_gatt_discover_params *params = user_data;
3718 uint8_t count;
3719 uint16_t end_handle = 0U, start_handle;
3720
3721 LOG_DBG("err 0x%02x", err);
3722
3723 if (err || (length % sizeof(struct bt_att_handle_group) != 0)) {
3724 goto done;
3725 }
3726
3727 count = length / sizeof(struct bt_att_handle_group);
3728
3729 /* Parse attributes found */
3730 for (uint8_t i = 0U; i < count; i++) {
3731 struct bt_uuid_16 uuid_svc;
3732 struct bt_gatt_attr attr;
3733 struct bt_gatt_service_val value;
3734
3735 start_handle = sys_le16_to_cpu(rsp[i].start_handle);
3736 end_handle = sys_le16_to_cpu(rsp[i].end_handle);
3737
3738 LOG_DBG("start_handle 0x%04x end_handle 0x%04x", start_handle, end_handle);
3739
3740 uuid_svc.uuid.type = BT_UUID_TYPE_16;
3741 if (params->type == BT_GATT_DISCOVER_PRIMARY) {
3742 uuid_svc.val = BT_UUID_GATT_PRIMARY_VAL;
3743 } else {
3744 uuid_svc.val = BT_UUID_GATT_SECONDARY_VAL;
3745 }
3746
3747 value.end_handle = end_handle;
3748 value.uuid = params->uuid;
3749
3750 attr = (struct bt_gatt_attr) {
3751 .uuid = &uuid_svc.uuid,
3752 .user_data = &value,
3753 .handle = start_handle,
3754 };
3755
3756 if (params->func(conn, &attr, params) == BT_GATT_ITER_STOP) {
3757 return;
3758 }
3759 }
3760
3761 gatt_discover_next(conn, end_handle, params);
3762
3763 return;
3764 done:
3765 params->func(conn, NULL, params);
3766 }
3767
gatt_find_type_encode(struct net_buf * buf,size_t len,void * user_data)3768 static int gatt_find_type_encode(struct net_buf *buf, size_t len,
3769 void *user_data)
3770 {
3771 struct bt_gatt_discover_params *params = user_data;
3772 struct bt_att_find_type_req *req;
3773 uint16_t uuid_val;
3774
3775 req = net_buf_add(buf, sizeof(*req));
3776 req->start_handle = sys_cpu_to_le16(params->start_handle);
3777 req->end_handle = sys_cpu_to_le16(params->end_handle);
3778
3779 if (params->type == BT_GATT_DISCOVER_PRIMARY) {
3780 uuid_val = BT_UUID_GATT_PRIMARY_VAL;
3781 } else {
3782 uuid_val = BT_UUID_GATT_SECONDARY_VAL;
3783 }
3784
3785 req->type = sys_cpu_to_le16(uuid_val);
3786
3787 LOG_DBG("uuid %s start_handle 0x%04x end_handle 0x%04x", bt_uuid_str(params->uuid),
3788 params->start_handle, params->end_handle);
3789
3790 switch (params->uuid->type) {
3791 case BT_UUID_TYPE_16:
3792 net_buf_add_le16(buf, BT_UUID_16(params->uuid)->val);
3793 break;
3794 case BT_UUID_TYPE_128:
3795 net_buf_add_mem(buf, BT_UUID_128(params->uuid)->val, 16);
3796 break;
3797 }
3798
3799 return 0;
3800 }
3801
gatt_find_type(struct bt_conn * conn,struct bt_gatt_discover_params * params)3802 static int gatt_find_type(struct bt_conn *conn,
3803 struct bt_gatt_discover_params *params)
3804 {
3805 size_t len;
3806
3807 len = sizeof(struct bt_att_find_type_req);
3808
3809 switch (params->uuid->type) {
3810 case BT_UUID_TYPE_16:
3811 len += BT_UUID_SIZE_16;
3812 break;
3813 case BT_UUID_TYPE_128:
3814 len += BT_UUID_SIZE_128;
3815 break;
3816 default:
3817 LOG_ERR("Unknown UUID type %u", params->uuid->type);
3818 return -EINVAL;
3819 }
3820
3821 return gatt_req_send(conn, gatt_find_type_rsp, params,
3822 gatt_find_type_encode, BT_ATT_OP_FIND_TYPE_REQ,
3823 len, BT_ATT_CHAN_OPT(params));
3824 }
3825
read_included_uuid_cb(struct bt_conn * conn,uint8_t err,const void * pdu,uint16_t length,void * user_data)3826 static void read_included_uuid_cb(struct bt_conn *conn, uint8_t err,
3827 const void *pdu, uint16_t length,
3828 void *user_data)
3829 {
3830 struct bt_gatt_discover_params *params = user_data;
3831 struct bt_gatt_include value;
3832 struct bt_gatt_attr attr;
3833 uint16_t handle;
3834 union {
3835 struct bt_uuid uuid;
3836 struct bt_uuid_128 u128;
3837 } u;
3838
3839 if (length != 16U) {
3840 LOG_ERR("Invalid data len %u", length);
3841 params->func(conn, NULL, params);
3842 return;
3843 }
3844
3845 handle = params->_included.attr_handle;
3846 value.start_handle = params->_included.start_handle;
3847 value.end_handle = params->_included.end_handle;
3848 value.uuid = &u.uuid;
3849 u.uuid.type = BT_UUID_TYPE_128;
3850 memcpy(u.u128.val, pdu, length);
3851
3852 LOG_DBG("handle 0x%04x uuid %s start_handle 0x%04x "
3853 "end_handle 0x%04x\n", params->_included.attr_handle,
3854 bt_uuid_str(&u.uuid), value.start_handle, value.end_handle);
3855
3856 /* Skip if UUID is set but doesn't match */
3857 if (params->uuid && bt_uuid_cmp(&u.uuid, params->uuid)) {
3858 goto next;
3859 }
3860
3861 attr = (struct bt_gatt_attr) {
3862 .uuid = BT_UUID_GATT_INCLUDE,
3863 .user_data = &value,
3864 .handle = handle,
3865 };
3866
3867 if (params->func(conn, &attr, params) == BT_GATT_ITER_STOP) {
3868 return;
3869 }
3870 next:
3871 gatt_discover_next(conn, params->start_handle, params);
3872
3873 return;
3874 }
3875
read_included_uuid_encode(struct net_buf * buf,size_t len,void * user_data)3876 static int read_included_uuid_encode(struct net_buf *buf, size_t len,
3877 void *user_data)
3878 {
3879 struct bt_gatt_discover_params *params = user_data;
3880 struct bt_att_read_req *req;
3881
3882 req = net_buf_add(buf, sizeof(*req));
3883 req->handle = sys_cpu_to_le16(params->_included.start_handle);
3884
3885 return 0;
3886 }
3887
read_included_uuid(struct bt_conn * conn,struct bt_gatt_discover_params * params)3888 static int read_included_uuid(struct bt_conn *conn,
3889 struct bt_gatt_discover_params *params)
3890 {
3891 LOG_DBG("handle 0x%04x", params->_included.start_handle);
3892
3893 return gatt_req_send(conn, read_included_uuid_cb, params,
3894 read_included_uuid_encode, BT_ATT_OP_READ_REQ,
3895 sizeof(struct bt_att_read_req), BT_ATT_CHAN_OPT(params));
3896 }
3897
parse_include(struct bt_conn * conn,const void * pdu,struct bt_gatt_discover_params * params,uint16_t length)3898 static uint16_t parse_include(struct bt_conn *conn, const void *pdu,
3899 struct bt_gatt_discover_params *params,
3900 uint16_t length)
3901 {
3902 const struct bt_att_read_type_rsp *rsp = pdu;
3903 uint16_t handle = 0U;
3904 struct bt_gatt_include value;
3905 union {
3906 struct bt_uuid uuid;
3907 struct bt_uuid_16 u16;
3908 struct bt_uuid_128 u128;
3909 } u;
3910
3911 /* Data can be either in UUID16 or UUID128 */
3912 switch (rsp->len) {
3913 case 8: /* UUID16 */
3914 u.uuid.type = BT_UUID_TYPE_16;
3915 break;
3916 case 6: /* UUID128 */
3917 /* BLUETOOTH SPECIFICATION Version 4.2 [Vol 3, Part G] page 550
3918 * To get the included service UUID when the included service
3919 * uses a 128-bit UUID, the Read Request is used.
3920 */
3921 u.uuid.type = BT_UUID_TYPE_128;
3922 break;
3923 default:
3924 LOG_ERR("Invalid data len %u", rsp->len);
3925 goto done;
3926 }
3927
3928 /* Parse include found */
3929 for (length--, pdu = rsp->data; length >= rsp->len;
3930 length -= rsp->len, pdu = (const uint8_t *)pdu + rsp->len) {
3931 struct bt_gatt_attr attr;
3932 const struct bt_att_data *data = pdu;
3933 struct gatt_incl *incl = (void *)data->value;
3934
3935 handle = sys_le16_to_cpu(data->handle);
3936 /* Handle 0 is invalid */
3937 if (!handle) {
3938 goto done;
3939 }
3940
3941 /* Convert include data, bt_gatt_incl and gatt_incl
3942 * have different formats so the conversion have to be done
3943 * field by field.
3944 */
3945 value.start_handle = sys_le16_to_cpu(incl->start_handle);
3946 value.end_handle = sys_le16_to_cpu(incl->end_handle);
3947
3948 switch (u.uuid.type) {
3949 case BT_UUID_TYPE_16:
3950 value.uuid = &u.uuid;
3951 u.u16.val = sys_le16_to_cpu(incl->uuid16);
3952 break;
3953 case BT_UUID_TYPE_128:
3954 params->_included.attr_handle = handle;
3955 params->_included.start_handle = value.start_handle;
3956 params->_included.end_handle = value.end_handle;
3957
3958 return read_included_uuid(conn, params);
3959 }
3960
3961 LOG_DBG("handle 0x%04x uuid %s start_handle 0x%04x "
3962 "end_handle 0x%04x\n", handle, bt_uuid_str(&u.uuid),
3963 value.start_handle, value.end_handle);
3964
3965 /* Skip if UUID is set but doesn't match */
3966 if (params->uuid && bt_uuid_cmp(&u.uuid, params->uuid)) {
3967 continue;
3968 }
3969
3970 attr = (struct bt_gatt_attr) {
3971 .uuid = BT_UUID_GATT_INCLUDE,
3972 .user_data = &value,
3973 .handle = handle,
3974 };
3975
3976 if (params->func(conn, &attr, params) == BT_GATT_ITER_STOP) {
3977 return 0;
3978 }
3979 }
3980
3981 /* Whole PDU read without error */
3982 if (length == 0U && handle) {
3983 return handle;
3984 }
3985
3986 done:
3987 params->func(conn, NULL, params);
3988 return 0;
3989 }
3990
parse_characteristic(struct bt_conn * conn,const void * pdu,struct bt_gatt_discover_params * params,uint16_t length)3991 static uint16_t parse_characteristic(struct bt_conn *conn, const void *pdu,
3992 struct bt_gatt_discover_params *params,
3993 uint16_t length)
3994 {
3995 const struct bt_att_read_type_rsp *rsp = pdu;
3996 uint16_t handle = 0U;
3997 union {
3998 struct bt_uuid uuid;
3999 struct bt_uuid_16 u16;
4000 struct bt_uuid_128 u128;
4001 } u;
4002
4003 /* Data can be either in UUID16 or UUID128 */
4004 switch (rsp->len) {
4005 case 7: /* UUID16 */
4006 u.uuid.type = BT_UUID_TYPE_16;
4007 break;
4008 case 21: /* UUID128 */
4009 u.uuid.type = BT_UUID_TYPE_128;
4010 break;
4011 default:
4012 LOG_ERR("Invalid data len %u", rsp->len);
4013 goto done;
4014 }
4015
4016 /* Parse characteristics found */
4017 for (length--, pdu = rsp->data; length >= rsp->len;
4018 length -= rsp->len, pdu = (const uint8_t *)pdu + rsp->len) {
4019 struct bt_gatt_attr attr;
4020 struct bt_gatt_chrc value;
4021 const struct bt_att_data *data = pdu;
4022 struct gatt_chrc *chrc = (void *)data->value;
4023
4024 handle = sys_le16_to_cpu(data->handle);
4025 /* Handle 0 is invalid */
4026 if (!handle) {
4027 goto done;
4028 }
4029
4030 switch (u.uuid.type) {
4031 case BT_UUID_TYPE_16:
4032 u.u16.val = sys_le16_to_cpu(chrc->uuid16);
4033 break;
4034 case BT_UUID_TYPE_128:
4035 memcpy(u.u128.val, chrc->uuid, sizeof(chrc->uuid));
4036 break;
4037 }
4038
4039 LOG_DBG("handle 0x%04x uuid %s properties 0x%02x", handle, bt_uuid_str(&u.uuid),
4040 chrc->properties);
4041
4042 /* Skip if UUID is set but doesn't match */
4043 if (params->uuid && bt_uuid_cmp(&u.uuid, params->uuid)) {
4044 continue;
4045 }
4046
4047 value = (struct bt_gatt_chrc)BT_GATT_CHRC_INIT(
4048 &u.uuid, sys_le16_to_cpu(chrc->value_handle),
4049 chrc->properties);
4050
4051 attr = (struct bt_gatt_attr) {
4052 .uuid = BT_UUID_GATT_CHRC,
4053 .user_data = &value,
4054 .handle = handle,
4055 };
4056
4057 if (params->func(conn, &attr, params) == BT_GATT_ITER_STOP) {
4058 return 0;
4059 }
4060 }
4061
4062 /* Whole PDU read without error */
4063 if (length == 0U && handle) {
4064 return handle;
4065 }
4066
4067 done:
4068 params->func(conn, NULL, params);
4069 return 0;
4070 }
4071
parse_read_std_char_desc(struct bt_conn * conn,const void * pdu,struct bt_gatt_discover_params * params,uint16_t length)4072 static uint16_t parse_read_std_char_desc(struct bt_conn *conn, const void *pdu,
4073 struct bt_gatt_discover_params *params,
4074 uint16_t length)
4075 {
4076 const struct bt_att_read_type_rsp *rsp = pdu;
4077 uint16_t handle = 0U;
4078 uint16_t uuid_val;
4079
4080 if (params->uuid->type != BT_UUID_TYPE_16) {
4081 goto done;
4082 }
4083
4084 uuid_val = BT_UUID_16(params->uuid)->val;
4085
4086 /* Parse characteristics found */
4087 for (length--, pdu = rsp->data; length >= rsp->len;
4088 length -= rsp->len, pdu = (const uint8_t *)pdu + rsp->len) {
4089 union {
4090 struct bt_gatt_ccc ccc;
4091 struct bt_gatt_cpf cpf;
4092 struct bt_gatt_cep cep;
4093 struct bt_gatt_scc scc;
4094 } value;
4095 const struct bt_att_data *data = pdu;
4096 struct bt_gatt_attr attr;
4097
4098 handle = sys_le16_to_cpu(data->handle);
4099 /* Handle 0 is invalid */
4100 if (!handle) {
4101 goto done;
4102 }
4103
4104 switch (uuid_val) {
4105 case BT_UUID_GATT_CEP_VAL:
4106 value.cep.properties = sys_get_le16(data->value);
4107 break;
4108 case BT_UUID_GATT_CCC_VAL:
4109 value.ccc.flags = sys_get_le16(data->value);
4110 break;
4111 case BT_UUID_GATT_SCC_VAL:
4112 value.scc.flags = sys_get_le16(data->value);
4113 break;
4114 case BT_UUID_GATT_CPF_VAL:
4115 {
4116 struct gatt_cpf *cpf = (struct gatt_cpf *)data->value;
4117
4118 value.cpf.format = cpf->format;
4119 value.cpf.exponent = cpf->exponent;
4120 value.cpf.unit = sys_le16_to_cpu(cpf->unit);
4121 value.cpf.name_space = cpf->name_space;
4122 value.cpf.description = sys_le16_to_cpu(cpf->description);
4123 break;
4124 }
4125 default:
4126 goto done;
4127 }
4128
4129 attr = (struct bt_gatt_attr) {
4130 .uuid = params->uuid,
4131 .user_data = &value,
4132 .handle = handle,
4133 };
4134
4135 if (params->func(conn, &attr, params) == BT_GATT_ITER_STOP) {
4136 return 0;
4137 }
4138 }
4139
4140 /* Whole PDU read without error */
4141 if (length == 0U && handle) {
4142 return handle;
4143 }
4144
4145 done:
4146 params->func(conn, NULL, params);
4147 return 0;
4148 }
4149
gatt_read_type_rsp(struct bt_conn * conn,uint8_t err,const void * pdu,uint16_t length,void * user_data)4150 static void gatt_read_type_rsp(struct bt_conn *conn, uint8_t err,
4151 const void *pdu, uint16_t length,
4152 void *user_data)
4153 {
4154 struct bt_gatt_discover_params *params = user_data;
4155 uint16_t handle;
4156
4157 LOG_DBG("err 0x%02x", err);
4158
4159 if (err) {
4160 params->func(conn, NULL, params);
4161 return;
4162 }
4163
4164 if (params->type == BT_GATT_DISCOVER_INCLUDE) {
4165 handle = parse_include(conn, pdu, params, length);
4166 } else if (params->type == BT_GATT_DISCOVER_CHARACTERISTIC) {
4167 handle = parse_characteristic(conn, pdu, params, length);
4168 } else {
4169 handle = parse_read_std_char_desc(conn, pdu, params, length);
4170 }
4171
4172 if (!handle) {
4173 return;
4174 }
4175
4176 gatt_discover_next(conn, handle, params);
4177 }
4178
gatt_read_type_encode(struct net_buf * buf,size_t len,void * user_data)4179 static int gatt_read_type_encode(struct net_buf *buf, size_t len,
4180 void *user_data)
4181 {
4182 struct bt_gatt_discover_params *params = user_data;
4183 struct bt_att_read_type_req *req;
4184
4185 req = net_buf_add(buf, sizeof(*req));
4186 req->start_handle = sys_cpu_to_le16(params->start_handle);
4187 req->end_handle = sys_cpu_to_le16(params->end_handle);
4188
4189 switch (params->type) {
4190 case BT_GATT_DISCOVER_INCLUDE:
4191 net_buf_add_le16(buf, BT_UUID_GATT_INCLUDE_VAL);
4192 break;
4193 case BT_GATT_DISCOVER_CHARACTERISTIC:
4194 net_buf_add_le16(buf, BT_UUID_GATT_CHRC_VAL);
4195 break;
4196 default:
4197 /* Only 16-bit UUIDs supported */
4198 net_buf_add_le16(buf, BT_UUID_16(params->uuid)->val);
4199 break;
4200 }
4201
4202 return 0;
4203 }
4204
gatt_read_type(struct bt_conn * conn,struct bt_gatt_discover_params * params)4205 static int gatt_read_type(struct bt_conn *conn,
4206 struct bt_gatt_discover_params *params)
4207 {
4208 LOG_DBG("start_handle 0x%04x end_handle 0x%04x", params->start_handle, params->end_handle);
4209
4210 return gatt_req_send(conn, gatt_read_type_rsp, params,
4211 gatt_read_type_encode, BT_ATT_OP_READ_TYPE_REQ,
4212 sizeof(struct bt_att_read_type_req), BT_ATT_CHAN_OPT(params));
4213 }
4214
parse_service(struct bt_conn * conn,const void * pdu,struct bt_gatt_discover_params * params,uint16_t length)4215 static uint16_t parse_service(struct bt_conn *conn, const void *pdu,
4216 struct bt_gatt_discover_params *params,
4217 uint16_t length)
4218 {
4219 const struct bt_att_read_group_rsp *rsp = pdu;
4220 uint16_t start_handle, end_handle = 0U;
4221 union {
4222 struct bt_uuid uuid;
4223 struct bt_uuid_16 u16;
4224 struct bt_uuid_128 u128;
4225 } u;
4226
4227 /* Data can be either in UUID16 or UUID128 */
4228 switch (rsp->len) {
4229 case 6: /* UUID16 */
4230 u.uuid.type = BT_UUID_TYPE_16;
4231 break;
4232 case 20: /* UUID128 */
4233 u.uuid.type = BT_UUID_TYPE_128;
4234 break;
4235 default:
4236 LOG_ERR("Invalid data len %u", rsp->len);
4237 goto done;
4238 }
4239
4240 /* Parse services found */
4241 for (length--, pdu = rsp->data; length >= rsp->len;
4242 length -= rsp->len, pdu = (const uint8_t *)pdu + rsp->len) {
4243 struct bt_uuid_16 uuid_svc;
4244 struct bt_gatt_attr attr = {};
4245 struct bt_gatt_service_val value;
4246 const struct bt_att_group_data *data = pdu;
4247
4248 start_handle = sys_le16_to_cpu(data->start_handle);
4249 if (!start_handle) {
4250 goto done;
4251 }
4252
4253 end_handle = sys_le16_to_cpu(data->end_handle);
4254 if (!end_handle || end_handle < start_handle) {
4255 goto done;
4256 }
4257
4258 switch (u.uuid.type) {
4259 case BT_UUID_TYPE_16:
4260 memcpy(&u.u16.val, data->value, sizeof(u.u16.val));
4261 u.u16.val = sys_le16_to_cpu(u.u16.val);
4262 break;
4263 case BT_UUID_TYPE_128:
4264 memcpy(u.u128.val, data->value, sizeof(u.u128.val));
4265 break;
4266 }
4267
4268 LOG_DBG("start_handle 0x%04x end_handle 0x%04x uuid %s", start_handle, end_handle,
4269 bt_uuid_str(&u.uuid));
4270
4271 uuid_svc.uuid.type = BT_UUID_TYPE_16;
4272 if (params->type == BT_GATT_DISCOVER_PRIMARY) {
4273 uuid_svc.val = BT_UUID_GATT_PRIMARY_VAL;
4274 } else {
4275 uuid_svc.val = BT_UUID_GATT_SECONDARY_VAL;
4276 }
4277
4278 value.end_handle = end_handle;
4279 value.uuid = &u.uuid;
4280
4281 attr.uuid = &uuid_svc.uuid;
4282 attr.handle = start_handle;
4283 attr.user_data = &value;
4284
4285 if (params->func(conn, &attr, params) == BT_GATT_ITER_STOP) {
4286 return 0;
4287 }
4288 }
4289
4290 /* Whole PDU read without error */
4291 if (length == 0U && end_handle) {
4292 return end_handle;
4293 }
4294
4295 done:
4296 params->func(conn, NULL, params);
4297 return 0;
4298 }
4299
gatt_read_group_rsp(struct bt_conn * conn,uint8_t err,const void * pdu,uint16_t length,void * user_data)4300 static void gatt_read_group_rsp(struct bt_conn *conn, uint8_t err,
4301 const void *pdu, uint16_t length,
4302 void *user_data)
4303 {
4304 struct bt_gatt_discover_params *params = user_data;
4305 uint16_t handle;
4306
4307 LOG_DBG("err 0x%02x", err);
4308
4309 if (err) {
4310 params->func(conn, NULL, params);
4311 return;
4312 }
4313
4314 handle = parse_service(conn, pdu, params, length);
4315 if (!handle) {
4316 return;
4317 }
4318
4319 gatt_discover_next(conn, handle, params);
4320 }
4321
gatt_read_group_encode(struct net_buf * buf,size_t len,void * user_data)4322 static int gatt_read_group_encode(struct net_buf *buf, size_t len,
4323 void *user_data)
4324 {
4325 struct bt_gatt_discover_params *params = user_data;
4326 struct bt_att_read_group_req *req;
4327
4328 req = net_buf_add(buf, sizeof(*req));
4329 req->start_handle = sys_cpu_to_le16(params->start_handle);
4330 req->end_handle = sys_cpu_to_le16(params->end_handle);
4331
4332 if (params->type == BT_GATT_DISCOVER_PRIMARY) {
4333 net_buf_add_le16(buf, BT_UUID_GATT_PRIMARY_VAL);
4334 } else {
4335 net_buf_add_le16(buf, BT_UUID_GATT_SECONDARY_VAL);
4336 }
4337
4338 return 0;
4339 }
4340
gatt_read_group(struct bt_conn * conn,struct bt_gatt_discover_params * params)4341 static int gatt_read_group(struct bt_conn *conn,
4342 struct bt_gatt_discover_params *params)
4343 {
4344 LOG_DBG("start_handle 0x%04x end_handle 0x%04x", params->start_handle, params->end_handle);
4345
4346 return gatt_req_send(conn, gatt_read_group_rsp, params,
4347 gatt_read_group_encode,
4348 BT_ATT_OP_READ_GROUP_REQ,
4349 sizeof(struct bt_att_read_group_req),
4350 BT_ATT_CHAN_OPT(params));
4351 }
4352
gatt_find_info_rsp(struct bt_conn * conn,uint8_t err,const void * pdu,uint16_t length,void * user_data)4353 static void gatt_find_info_rsp(struct bt_conn *conn, uint8_t err,
4354 const void *pdu, uint16_t length,
4355 void *user_data)
4356 {
4357 const struct bt_att_find_info_rsp *rsp = pdu;
4358 struct bt_gatt_discover_params *params = user_data;
4359 uint16_t handle = 0U;
4360 uint16_t len;
4361 union {
4362 const struct bt_att_info_16 *i16;
4363 const struct bt_att_info_128 *i128;
4364 } info;
4365 union {
4366 struct bt_uuid uuid;
4367 struct bt_uuid_16 u16;
4368 struct bt_uuid_128 u128;
4369 } u;
4370 int i;
4371 bool skip = false;
4372
4373 LOG_DBG("err 0x%02x", err);
4374
4375 if (err) {
4376 goto done;
4377 }
4378
4379 /* Data can be either in UUID16 or UUID128 */
4380 switch (rsp->format) {
4381 case BT_ATT_INFO_16:
4382 u.uuid.type = BT_UUID_TYPE_16;
4383 len = sizeof(*info.i16);
4384 break;
4385 case BT_ATT_INFO_128:
4386 u.uuid.type = BT_UUID_TYPE_128;
4387 len = sizeof(*info.i128);
4388 break;
4389 default:
4390 LOG_ERR("Invalid format %u", rsp->format);
4391 goto done;
4392 }
4393
4394 length--;
4395
4396 /* Check if there is a least one descriptor in the response */
4397 if (length < len) {
4398 goto done;
4399 }
4400
4401 /* Parse descriptors found */
4402 for (i = length / len, pdu = rsp->info; i != 0;
4403 i--, pdu = (const uint8_t *)pdu + len) {
4404 struct bt_gatt_attr attr;
4405
4406 info.i16 = pdu;
4407 handle = sys_le16_to_cpu(info.i16->handle);
4408
4409 if (skip) {
4410 skip = false;
4411 continue;
4412 }
4413
4414 switch (u.uuid.type) {
4415 case BT_UUID_TYPE_16:
4416 u.u16.val = sys_le16_to_cpu(info.i16->uuid);
4417 break;
4418 case BT_UUID_TYPE_128:
4419 memcpy(u.u128.val, info.i128->uuid, 16);
4420 break;
4421 }
4422
4423 LOG_DBG("handle 0x%04x uuid %s", handle, bt_uuid_str(&u.uuid));
4424
4425 /* Skip if UUID is set but doesn't match */
4426 if (params->uuid && bt_uuid_cmp(&u.uuid, params->uuid)) {
4427 continue;
4428 }
4429
4430 if (params->type == BT_GATT_DISCOVER_DESCRIPTOR) {
4431 /* Skip attributes that are not considered
4432 * descriptors.
4433 */
4434 if (!bt_uuid_cmp(&u.uuid, BT_UUID_GATT_PRIMARY) ||
4435 !bt_uuid_cmp(&u.uuid, BT_UUID_GATT_SECONDARY) ||
4436 !bt_uuid_cmp(&u.uuid, BT_UUID_GATT_INCLUDE)) {
4437 continue;
4438 }
4439
4440 /* If Characteristic Declaration skip ahead as the next
4441 * entry must be its value.
4442 */
4443 if (!bt_uuid_cmp(&u.uuid, BT_UUID_GATT_CHRC)) {
4444 skip = true;
4445 continue;
4446 }
4447 }
4448
4449 /* No user_data in this case */
4450 attr = (struct bt_gatt_attr) {
4451 .uuid = &u.uuid,
4452 .handle = handle,
4453 };
4454
4455 if (params->func(conn, &attr, params) == BT_GATT_ITER_STOP) {
4456 return;
4457 }
4458 }
4459
4460 gatt_discover_next(conn, handle, params);
4461
4462 return;
4463
4464 done:
4465 params->func(conn, NULL, params);
4466 }
4467
gatt_find_info_encode(struct net_buf * buf,size_t len,void * user_data)4468 static int gatt_find_info_encode(struct net_buf *buf, size_t len,
4469 void *user_data)
4470 {
4471 struct bt_gatt_discover_params *params = user_data;
4472 struct bt_att_find_info_req *req;
4473
4474 req = net_buf_add(buf, sizeof(*req));
4475 req->start_handle = sys_cpu_to_le16(params->start_handle);
4476 req->end_handle = sys_cpu_to_le16(params->end_handle);
4477
4478 return 0;
4479 }
4480
gatt_find_info(struct bt_conn * conn,struct bt_gatt_discover_params * params)4481 static int gatt_find_info(struct bt_conn *conn,
4482 struct bt_gatt_discover_params *params)
4483 {
4484 LOG_DBG("start_handle 0x%04x end_handle 0x%04x", params->start_handle, params->end_handle);
4485
4486 return gatt_req_send(conn, gatt_find_info_rsp, params,
4487 gatt_find_info_encode, BT_ATT_OP_FIND_INFO_REQ,
4488 sizeof(struct bt_att_find_info_req),
4489 BT_ATT_CHAN_OPT(params));
4490 }
4491
bt_gatt_discover(struct bt_conn * conn,struct bt_gatt_discover_params * params)4492 int bt_gatt_discover(struct bt_conn *conn,
4493 struct bt_gatt_discover_params *params)
4494 {
4495 __ASSERT(conn, "invalid parameters\n");
4496 __ASSERT(params && params->func, "invalid parameters\n");
4497 __ASSERT((params->start_handle && params->end_handle),
4498 "invalid parameters\n");
4499 __ASSERT((params->start_handle <= params->end_handle),
4500 "invalid parameters\n");
4501
4502 if (conn->state != BT_CONN_CONNECTED) {
4503 return -ENOTCONN;
4504 }
4505
4506 switch (params->type) {
4507 case BT_GATT_DISCOVER_PRIMARY:
4508 case BT_GATT_DISCOVER_SECONDARY:
4509 if (params->uuid) {
4510 return gatt_find_type(conn, params);
4511 }
4512 return gatt_read_group(conn, params);
4513
4514 case BT_GATT_DISCOVER_STD_CHAR_DESC:
4515 if (!(params->uuid && params->uuid->type == BT_UUID_TYPE_16 &&
4516 (!bt_uuid_cmp(params->uuid, BT_UUID_GATT_CEP) ||
4517 !bt_uuid_cmp(params->uuid, BT_UUID_GATT_CCC) ||
4518 !bt_uuid_cmp(params->uuid, BT_UUID_GATT_SCC) ||
4519 !bt_uuid_cmp(params->uuid, BT_UUID_GATT_CPF)))) {
4520 return -EINVAL;
4521 }
4522 __fallthrough;
4523 case BT_GATT_DISCOVER_INCLUDE:
4524 case BT_GATT_DISCOVER_CHARACTERISTIC:
4525 return gatt_read_type(conn, params);
4526 case BT_GATT_DISCOVER_DESCRIPTOR:
4527 /* Only descriptors can be filtered */
4528 if (params->uuid &&
4529 (!bt_uuid_cmp(params->uuid, BT_UUID_GATT_PRIMARY) ||
4530 !bt_uuid_cmp(params->uuid, BT_UUID_GATT_SECONDARY) ||
4531 !bt_uuid_cmp(params->uuid, BT_UUID_GATT_INCLUDE) ||
4532 !bt_uuid_cmp(params->uuid, BT_UUID_GATT_CHRC))) {
4533 return -EINVAL;
4534 }
4535 __fallthrough;
4536 case BT_GATT_DISCOVER_ATTRIBUTE:
4537 return gatt_find_info(conn, params);
4538 default:
4539 LOG_ERR("Invalid discovery type: %u", params->type);
4540 }
4541
4542 return -EINVAL;
4543 }
4544
parse_read_by_uuid(struct bt_conn * conn,struct bt_gatt_read_params * params,const void * pdu,uint16_t length)4545 static void parse_read_by_uuid(struct bt_conn *conn,
4546 struct bt_gatt_read_params *params,
4547 const void *pdu, uint16_t length)
4548 {
4549 const struct bt_att_read_type_rsp *rsp = pdu;
4550
4551 /* Parse values found */
4552 for (length--, pdu = rsp->data; length;
4553 length -= rsp->len, pdu = (const uint8_t *)pdu + rsp->len) {
4554 const struct bt_att_data *data = pdu;
4555 uint16_t handle;
4556 uint16_t len;
4557
4558 handle = sys_le16_to_cpu(data->handle);
4559
4560 /* Handle 0 is invalid */
4561 if (!handle) {
4562 LOG_ERR("Invalid handle");
4563 return;
4564 }
4565
4566 len = rsp->len > length ? length - 2 : rsp->len - 2;
4567
4568 LOG_DBG("handle 0x%04x len %u value %u", handle, rsp->len, len);
4569
4570 /* Update start_handle */
4571 params->by_uuid.start_handle = handle;
4572
4573 if (params->func(conn, 0, params, data->value, len) ==
4574 BT_GATT_ITER_STOP) {
4575 return;
4576 }
4577
4578 /* Check if long attribute */
4579 if (rsp->len > length) {
4580 break;
4581 }
4582
4583 /* Stop if it's the last handle to be read */
4584 if (params->by_uuid.start_handle == params->by_uuid.end_handle) {
4585 params->func(conn, 0, params, NULL, 0);
4586 return;
4587 }
4588
4589 params->by_uuid.start_handle++;
4590 }
4591
4592 /* Continue reading the attributes */
4593 if (bt_gatt_read(conn, params) < 0) {
4594 params->func(conn, BT_ATT_ERR_UNLIKELY, params, NULL, 0);
4595 }
4596 }
4597
gatt_read_rsp(struct bt_conn * conn,uint8_t err,const void * pdu,uint16_t length,void * user_data)4598 static void gatt_read_rsp(struct bt_conn *conn, uint8_t err, const void *pdu,
4599 uint16_t length, void *user_data)
4600 {
4601 struct bt_gatt_read_params *params = user_data;
4602
4603 LOG_DBG("err 0x%02x", err);
4604
4605 if (err || !length) {
4606 params->func(conn, err, params, NULL, 0);
4607 return;
4608 }
4609
4610 if (!params->handle_count) {
4611 parse_read_by_uuid(conn, params, pdu, length);
4612 return;
4613 }
4614
4615 if (params->func(conn, 0, params, pdu, length) == BT_GATT_ITER_STOP) {
4616 return;
4617 }
4618
4619 /*
4620 * Core Spec 4.2, Vol. 3, Part G, 4.8.1
4621 * If the Characteristic Value is greater than (ATT_MTU - 1) octets
4622 * in length, the Read Long Characteristic Value procedure may be used
4623 * if the rest of the Characteristic Value is required.
4624 */
4625 if (length < (bt_att_get_mtu(conn) - 1)) {
4626 params->func(conn, 0, params, NULL, 0);
4627 return;
4628 }
4629
4630 params->single.offset += length;
4631
4632 /* Continue reading the attribute */
4633 if (bt_gatt_read(conn, params) < 0) {
4634 params->func(conn, BT_ATT_ERR_UNLIKELY, params, NULL, 0);
4635 }
4636 }
4637
gatt_read_blob_encode(struct net_buf * buf,size_t len,void * user_data)4638 static int gatt_read_blob_encode(struct net_buf *buf, size_t len,
4639 void *user_data)
4640 {
4641 struct bt_gatt_read_params *params = user_data;
4642 struct bt_att_read_blob_req *req;
4643
4644 req = net_buf_add(buf, sizeof(*req));
4645 req->handle = sys_cpu_to_le16(params->single.handle);
4646 req->offset = sys_cpu_to_le16(params->single.offset);
4647
4648 return 0;
4649 }
4650
gatt_read_blob(struct bt_conn * conn,struct bt_gatt_read_params * params)4651 static int gatt_read_blob(struct bt_conn *conn,
4652 struct bt_gatt_read_params *params)
4653 {
4654 LOG_DBG("handle 0x%04x offset 0x%04x", params->single.handle, params->single.offset);
4655
4656 return gatt_req_send(conn, gatt_read_rsp, params,
4657 gatt_read_blob_encode, BT_ATT_OP_READ_BLOB_REQ,
4658 sizeof(struct bt_att_read_blob_req),
4659 BT_ATT_CHAN_OPT(params));
4660 }
4661
gatt_read_uuid_encode(struct net_buf * buf,size_t len,void * user_data)4662 static int gatt_read_uuid_encode(struct net_buf *buf, size_t len,
4663 void *user_data)
4664 {
4665 struct bt_gatt_read_params *params = user_data;
4666 struct bt_att_read_type_req *req;
4667
4668 req = net_buf_add(buf, sizeof(*req));
4669 req->start_handle = sys_cpu_to_le16(params->by_uuid.start_handle);
4670 req->end_handle = sys_cpu_to_le16(params->by_uuid.end_handle);
4671
4672 if (params->by_uuid.uuid->type == BT_UUID_TYPE_16) {
4673 net_buf_add_le16(buf, BT_UUID_16(params->by_uuid.uuid)->val);
4674 } else {
4675 net_buf_add_mem(buf, BT_UUID_128(params->by_uuid.uuid)->val, 16);
4676 }
4677
4678 return 0;
4679 }
4680
gatt_read_uuid(struct bt_conn * conn,struct bt_gatt_read_params * params)4681 static int gatt_read_uuid(struct bt_conn *conn,
4682 struct bt_gatt_read_params *params)
4683 {
4684 LOG_DBG("start_handle 0x%04x end_handle 0x%04x uuid %s", params->by_uuid.start_handle,
4685 params->by_uuid.end_handle, bt_uuid_str(params->by_uuid.uuid));
4686
4687 return gatt_req_send(conn, gatt_read_rsp, params,
4688 gatt_read_uuid_encode, BT_ATT_OP_READ_TYPE_REQ,
4689 sizeof(struct bt_att_read_type_req),
4690 BT_ATT_CHAN_OPT(params));
4691 }
4692
4693 #if defined(CONFIG_BT_GATT_READ_MULTIPLE)
gatt_read_mult_rsp(struct bt_conn * conn,uint8_t err,const void * pdu,uint16_t length,void * user_data)4694 static void gatt_read_mult_rsp(struct bt_conn *conn, uint8_t err, const void *pdu,
4695 uint16_t length, void *user_data)
4696 {
4697 struct bt_gatt_read_params *params = user_data;
4698
4699 LOG_DBG("err 0x%02x", err);
4700
4701 if (err || !length) {
4702 params->func(conn, err, params, NULL, 0);
4703 return;
4704 }
4705
4706 params->func(conn, 0, params, pdu, length);
4707
4708 /* mark read as complete since read multiple is single response */
4709 params->func(conn, 0, params, NULL, 0);
4710 }
4711
gatt_read_mult_encode(struct net_buf * buf,size_t len,void * user_data)4712 static int gatt_read_mult_encode(struct net_buf *buf, size_t len,
4713 void *user_data)
4714 {
4715 struct bt_gatt_read_params *params = user_data;
4716 uint8_t i;
4717
4718 for (i = 0U; i < params->handle_count; i++) {
4719 net_buf_add_le16(buf, params->multiple.handles[i]);
4720 }
4721
4722 return 0;
4723 }
4724
gatt_read_mult(struct bt_conn * conn,struct bt_gatt_read_params * params)4725 static int gatt_read_mult(struct bt_conn *conn,
4726 struct bt_gatt_read_params *params)
4727 {
4728 LOG_DBG("handle_count %zu", params->handle_count);
4729
4730 return gatt_req_send(conn, gatt_read_mult_rsp, params,
4731 gatt_read_mult_encode, BT_ATT_OP_READ_MULT_REQ,
4732 params->handle_count * sizeof(uint16_t),
4733 BT_ATT_CHAN_OPT(params));
4734 }
4735
4736 #else
gatt_read_mult(struct bt_conn * conn,struct bt_gatt_read_params * params)4737 static int gatt_read_mult(struct bt_conn *conn,
4738 struct bt_gatt_read_params *params)
4739 {
4740 return -ENOTSUP;
4741 }
4742 #endif /* CONFIG_BT_GATT_READ_MULTIPLE */
4743
4744 #if defined(CONFIG_BT_GATT_READ_MULT_VAR_LEN)
gatt_read_mult_vl_rsp(struct bt_conn * conn,uint8_t err,const void * pdu,uint16_t length,void * user_data)4745 static void gatt_read_mult_vl_rsp(struct bt_conn *conn, uint8_t err,
4746 const void *pdu, uint16_t length,
4747 void *user_data)
4748 {
4749 struct bt_gatt_read_params *params = user_data;
4750 const struct bt_att_read_mult_vl_rsp *rsp;
4751 struct net_buf_simple buf;
4752
4753 LOG_DBG("err 0x%02x", err);
4754
4755 if (err || !length) {
4756 params->func(conn, err, params, NULL, 0);
4757 return;
4758 }
4759
4760 net_buf_simple_init_with_data(&buf, (void *)pdu, length);
4761
4762 while (buf.len >= sizeof(*rsp)) {
4763 uint16_t len;
4764
4765 rsp = net_buf_simple_pull_mem(&buf, sizeof(*rsp));
4766 len = sys_le16_to_cpu(rsp->len);
4767
4768 /* If a Length Value Tuple is truncated, then the amount of
4769 * Attribute Value will be less than the value of the Value
4770 * Length field.
4771 */
4772 if (len > buf.len) {
4773 len = buf.len;
4774 }
4775
4776 params->func(conn, 0, params, rsp->value, len);
4777
4778 net_buf_simple_pull_mem(&buf, len);
4779 }
4780
4781 /* mark read as complete since read multiple is single response */
4782 params->func(conn, 0, params, NULL, 0);
4783 }
4784
gatt_read_mult_vl_encode(struct net_buf * buf,size_t len,void * user_data)4785 static int gatt_read_mult_vl_encode(struct net_buf *buf, size_t len,
4786 void *user_data)
4787 {
4788 struct bt_gatt_read_params *params = user_data;
4789 uint8_t i;
4790
4791 for (i = 0U; i < params->handle_count; i++) {
4792 net_buf_add_le16(buf, params->multiple.handles[i]);
4793 }
4794
4795 return 0;
4796 }
4797
gatt_read_mult_vl(struct bt_conn * conn,struct bt_gatt_read_params * params)4798 static int gatt_read_mult_vl(struct bt_conn *conn,
4799 struct bt_gatt_read_params *params)
4800 {
4801 LOG_DBG("handle_count %zu", params->handle_count);
4802
4803 return gatt_req_send(conn, gatt_read_mult_vl_rsp, params,
4804 gatt_read_mult_vl_encode,
4805 BT_ATT_OP_READ_MULT_VL_REQ,
4806 params->handle_count * sizeof(uint16_t),
4807 BT_ATT_CHAN_OPT(params));
4808 }
4809
4810 #else
gatt_read_mult_vl(struct bt_conn * conn,struct bt_gatt_read_params * params)4811 static int gatt_read_mult_vl(struct bt_conn *conn,
4812 struct bt_gatt_read_params *params)
4813 {
4814 return -ENOTSUP;
4815 }
4816 #endif /* CONFIG_BT_GATT_READ_MULT_VAR_LEN */
4817
gatt_read_encode(struct net_buf * buf,size_t len,void * user_data)4818 static int gatt_read_encode(struct net_buf *buf, size_t len, void *user_data)
4819 {
4820 struct bt_gatt_read_params *params = user_data;
4821 struct bt_att_read_req *req;
4822
4823 req = net_buf_add(buf, sizeof(*req));
4824 req->handle = sys_cpu_to_le16(params->single.handle);
4825
4826 return 0;
4827 }
4828
bt_gatt_read(struct bt_conn * conn,struct bt_gatt_read_params * params)4829 int bt_gatt_read(struct bt_conn *conn, struct bt_gatt_read_params *params)
4830 {
4831 __ASSERT(conn, "invalid parameters\n");
4832 __ASSERT(params && params->func, "invalid parameters\n");
4833
4834 if (conn->state != BT_CONN_CONNECTED) {
4835 return -ENOTCONN;
4836 }
4837
4838 if (params->handle_count == 0) {
4839 return gatt_read_uuid(conn, params);
4840 }
4841
4842 if (params->handle_count > 1) {
4843 if (params->multiple.variable) {
4844 return gatt_read_mult_vl(conn, params);
4845 } else {
4846 return gatt_read_mult(conn, params);
4847 }
4848 }
4849
4850 if (params->single.offset) {
4851 return gatt_read_blob(conn, params);
4852 }
4853
4854 LOG_DBG("handle 0x%04x", params->single.handle);
4855
4856 return gatt_req_send(conn, gatt_read_rsp, params, gatt_read_encode,
4857 BT_ATT_OP_READ_REQ, sizeof(struct bt_att_read_req),
4858 BT_ATT_CHAN_OPT(params));
4859 }
4860
gatt_write_rsp(struct bt_conn * conn,uint8_t err,const void * pdu,uint16_t length,void * user_data)4861 static void gatt_write_rsp(struct bt_conn *conn, uint8_t err, const void *pdu,
4862 uint16_t length, void *user_data)
4863 {
4864 struct bt_gatt_write_params *params = user_data;
4865
4866 LOG_DBG("err 0x%02x", err);
4867
4868 params->func(conn, err, params);
4869 }
4870
bt_gatt_write_without_response_cb(struct bt_conn * conn,uint16_t handle,const void * data,uint16_t length,bool sign,bt_gatt_complete_func_t func,void * user_data)4871 int bt_gatt_write_without_response_cb(struct bt_conn *conn, uint16_t handle,
4872 const void *data, uint16_t length, bool sign,
4873 bt_gatt_complete_func_t func,
4874 void *user_data)
4875 {
4876 struct net_buf *buf;
4877 struct bt_att_write_cmd *cmd;
4878 size_t write;
4879
4880 __ASSERT(conn, "invalid parameters\n");
4881 __ASSERT(handle, "invalid parameters\n");
4882
4883 if (conn->state != BT_CONN_CONNECTED) {
4884 return -ENOTCONN;
4885 }
4886
4887 #if defined(CONFIG_BT_SMP)
4888 if (conn->encrypt) {
4889 /* Don't need to sign if already encrypted */
4890 sign = false;
4891 }
4892 #endif
4893
4894 if (sign) {
4895 buf = bt_att_create_pdu(conn, BT_ATT_OP_SIGNED_WRITE_CMD,
4896 sizeof(*cmd) + length + 12);
4897 } else {
4898 buf = bt_att_create_pdu(conn, BT_ATT_OP_WRITE_CMD,
4899 sizeof(*cmd) + length);
4900 }
4901 if (!buf) {
4902 return -ENOMEM;
4903 }
4904
4905 cmd = net_buf_add(buf, sizeof(*cmd));
4906 cmd->handle = sys_cpu_to_le16(handle);
4907
4908 write = net_buf_append_bytes(buf, length, data, K_NO_WAIT, NULL, NULL);
4909 if (write != length) {
4910 LOG_WRN("Unable to allocate length %u: only %zu written", length, write);
4911 net_buf_unref(buf);
4912 return -ENOMEM;
4913 }
4914
4915 LOG_DBG("handle 0x%04x length %u", handle, length);
4916
4917 bt_att_set_tx_meta_data(buf, func, user_data, BT_ATT_CHAN_OPT_NONE);
4918
4919 return bt_att_send(conn, buf);
4920 }
4921
gatt_exec_encode(struct net_buf * buf,size_t len,void * user_data)4922 static int gatt_exec_encode(struct net_buf *buf, size_t len, void *user_data)
4923 {
4924 struct bt_att_exec_write_req *req;
4925
4926 req = net_buf_add(buf, sizeof(*req));
4927 req->flags = BT_ATT_FLAG_EXEC;
4928
4929 return 0;
4930 }
4931
gatt_exec_write(struct bt_conn * conn,struct bt_gatt_write_params * params)4932 static int gatt_exec_write(struct bt_conn *conn,
4933 struct bt_gatt_write_params *params)
4934 {
4935 LOG_DBG("");
4936
4937 return gatt_req_send(conn, gatt_write_rsp, params, gatt_exec_encode,
4938 BT_ATT_OP_EXEC_WRITE_REQ,
4939 sizeof(struct bt_att_exec_write_req),
4940 BT_ATT_CHAN_OPT(params));
4941 }
4942
gatt_cancel_encode(struct net_buf * buf,size_t len,void * user_data)4943 static int gatt_cancel_encode(struct net_buf *buf, size_t len, void *user_data)
4944 {
4945 struct bt_att_exec_write_req *req;
4946
4947 req = net_buf_add(buf, sizeof(*req));
4948 req->flags = BT_ATT_FLAG_CANCEL;
4949
4950 return 0;
4951 }
4952
gatt_cancel_all_writes(struct bt_conn * conn,struct bt_gatt_write_params * params)4953 static int gatt_cancel_all_writes(struct bt_conn *conn,
4954 struct bt_gatt_write_params *params)
4955 {
4956 LOG_DBG("");
4957
4958 return gatt_req_send(conn, gatt_write_rsp, params, gatt_cancel_encode,
4959 BT_ATT_OP_EXEC_WRITE_REQ,
4960 sizeof(struct bt_att_exec_write_req),
4961 BT_ATT_CHAN_OPT(params));
4962 }
4963
gatt_prepare_write_rsp(struct bt_conn * conn,uint8_t err,const void * pdu,uint16_t length,void * user_data)4964 static void gatt_prepare_write_rsp(struct bt_conn *conn, uint8_t err,
4965 const void *pdu, uint16_t length,
4966 void *user_data)
4967 {
4968 struct bt_gatt_write_params *params = user_data;
4969 const struct bt_att_prepare_write_rsp *rsp = pdu;
4970 size_t len;
4971 bool data_valid;
4972
4973 LOG_DBG("err 0x%02x", err);
4974
4975 /* Don't continue in case of error */
4976 if (err) {
4977 params->func(conn, err, params);
4978 return;
4979 }
4980
4981 len = length - sizeof(*rsp);
4982 if (len > params->length) {
4983 LOG_ERR("Incorrect length, canceling write");
4984 if (gatt_cancel_all_writes(conn, params)) {
4985 goto fail;
4986 }
4987
4988 return;
4989 }
4990
4991 data_valid = memcmp(params->data, rsp->value, len) == 0;
4992 if (params->offset != rsp->offset || !data_valid) {
4993 LOG_ERR("Incorrect offset or data in response, canceling write");
4994 if (gatt_cancel_all_writes(conn, params)) {
4995 goto fail;
4996 }
4997
4998 return;
4999 }
5000
5001 /* Update params */
5002 params->offset += len;
5003 params->data = (const uint8_t *)params->data + len;
5004 params->length -= len;
5005
5006 /* If there is no more data execute */
5007 if (!params->length) {
5008 if (gatt_exec_write(conn, params)) {
5009 goto fail;
5010 }
5011
5012 return;
5013 }
5014
5015 /* Write next chunk */
5016 if (!bt_gatt_write(conn, params)) {
5017 /* Success */
5018 return;
5019 }
5020
5021 fail:
5022 /* Notify application that the write operation has failed */
5023 params->func(conn, BT_ATT_ERR_UNLIKELY, params);
5024 }
5025
gatt_prepare_write_encode(struct net_buf * buf,size_t len,void * user_data)5026 static int gatt_prepare_write_encode(struct net_buf *buf, size_t len,
5027 void *user_data)
5028 {
5029 struct bt_gatt_write_params *params = user_data;
5030 struct bt_att_prepare_write_req *req;
5031 size_t write;
5032
5033 req = net_buf_add(buf, sizeof(*req));
5034 req->handle = sys_cpu_to_le16(params->handle);
5035 req->offset = sys_cpu_to_le16(params->offset);
5036
5037 write = net_buf_append_bytes(buf, len - sizeof(*req),
5038 (uint8_t *)params->data, K_NO_WAIT, NULL,
5039 NULL);
5040 if (write != (len - sizeof(*req))) {
5041 return -ENOMEM;
5042 }
5043
5044 return 0;
5045 }
5046
gatt_prepare_write(struct bt_conn * conn,struct bt_gatt_write_params * params)5047 static int gatt_prepare_write(struct bt_conn *conn,
5048 struct bt_gatt_write_params *params)
5049 {
5050 uint16_t len, req_len;
5051
5052 req_len = sizeof(struct bt_att_prepare_write_req);
5053
5054 len = bt_att_get_mtu(conn) - req_len - 1;
5055 len = MIN(params->length, len);
5056 len += req_len;
5057
5058 return gatt_req_send(conn, gatt_prepare_write_rsp, params,
5059 gatt_prepare_write_encode,
5060 BT_ATT_OP_PREPARE_WRITE_REQ, len,
5061 BT_ATT_CHAN_OPT(params));
5062 }
5063
gatt_write_encode(struct net_buf * buf,size_t len,void * user_data)5064 static int gatt_write_encode(struct net_buf *buf, size_t len, void *user_data)
5065 {
5066 struct bt_gatt_write_params *params = user_data;
5067 struct bt_att_write_req *req;
5068 size_t write;
5069
5070 req = net_buf_add(buf, sizeof(*req));
5071 req->handle = sys_cpu_to_le16(params->handle);
5072
5073 write = net_buf_append_bytes(buf, params->length, params->data,
5074 K_NO_WAIT, NULL, NULL);
5075 if (write != params->length) {
5076 return -ENOMEM;
5077 }
5078
5079 return 0;
5080 }
5081
bt_gatt_write(struct bt_conn * conn,struct bt_gatt_write_params * params)5082 int bt_gatt_write(struct bt_conn *conn, struct bt_gatt_write_params *params)
5083 {
5084 size_t len;
5085
5086 __ASSERT(conn, "invalid parameters\n");
5087 __ASSERT(params && params->func, "invalid parameters\n");
5088 __ASSERT(params->handle, "invalid parameters\n");
5089
5090 if (conn->state != BT_CONN_CONNECTED) {
5091 return -ENOTCONN;
5092 }
5093
5094 len = sizeof(struct bt_att_write_req) + params->length;
5095
5096 /* Use Prepare Write if offset is set or Long Write is required */
5097 if (params->offset || len > (bt_att_get_mtu(conn) - 1)) {
5098 return gatt_prepare_write(conn, params);
5099 }
5100
5101 LOG_DBG("handle 0x%04x length %u", params->handle, params->length);
5102
5103 return gatt_req_send(conn, gatt_write_rsp, params, gatt_write_encode,
5104 BT_ATT_OP_WRITE_REQ, len, BT_ATT_CHAN_OPT(params));
5105 }
5106
gatt_write_ccc_rsp(struct bt_conn * conn,uint8_t err,const void * pdu,uint16_t length,void * user_data)5107 static void gatt_write_ccc_rsp(struct bt_conn *conn, uint8_t err,
5108 const void *pdu, uint16_t length,
5109 void *user_data)
5110 {
5111 struct bt_gatt_subscribe_params *params = user_data;
5112
5113 LOG_DBG("err 0x%02x", err);
5114
5115 atomic_clear_bit(params->flags, BT_GATT_SUBSCRIBE_FLAG_WRITE_PENDING);
5116
5117 /* if write to CCC failed we remove subscription and notify app */
5118 if (err) {
5119 struct gatt_sub *sub;
5120 sys_snode_t *node, *tmp, *prev;
5121
5122 sub = gatt_sub_find(conn);
5123 if (!sub) {
5124 return;
5125 }
5126
5127 prev = NULL;
5128
5129 SYS_SLIST_FOR_EACH_NODE_SAFE(&sub->list, node, tmp) {
5130 if (node == ¶ms->node) {
5131 gatt_sub_remove(conn, sub, prev, params);
5132 break;
5133 }
5134 prev = node;
5135 }
5136 } else if (!params->value) {
5137 /* Notify with NULL data to complete unsubscribe */
5138 params->notify(conn, params, NULL, 0);
5139 }
5140
5141 if (params->subscribe) {
5142 params->subscribe(conn, err, params);
5143 } else if (params->write) {
5144 /* TODO: Remove after deprecation */
5145 LOG_WRN("write callback is deprecated, use subscribe cb instead");
5146 params->write(conn, err, NULL);
5147 }
5148 }
5149
5150
gatt_write_ccc_buf(struct net_buf * buf,size_t len,void * user_data)5151 static int gatt_write_ccc_buf(struct net_buf *buf, size_t len, void *user_data)
5152 {
5153 struct bt_gatt_subscribe_params *params = user_data;
5154 struct bt_att_write_req *write_req;
5155
5156 write_req = net_buf_add(buf, sizeof(*write_req));
5157 write_req->handle = sys_cpu_to_le16(params->ccc_handle);
5158 net_buf_add_le16(buf, params->value);
5159
5160 atomic_set_bit(params->flags, BT_GATT_SUBSCRIBE_FLAG_WRITE_PENDING);
5161
5162 return 0;
5163 }
5164
gatt_write_ccc(struct bt_conn * conn,struct bt_gatt_subscribe_params * params)5165 static int gatt_write_ccc(struct bt_conn *conn,
5166 struct bt_gatt_subscribe_params *params)
5167 {
5168 size_t len = sizeof(struct bt_att_write_req) + sizeof(uint16_t);
5169
5170 LOG_DBG("handle 0x%04x value 0x%04x", params->ccc_handle, params->value);
5171
5172 /* The value of the params doesn't matter, this is just so we don't
5173 * repeat CCC writes when the AUTO_RESUBSCRIBE quirk is enabled.
5174 */
5175 atomic_set_bit(params->flags, BT_GATT_SUBSCRIBE_FLAG_SENT);
5176
5177 return gatt_req_send(conn, gatt_write_ccc_rsp, params,
5178 gatt_write_ccc_buf, BT_ATT_OP_WRITE_REQ, len,
5179 BT_ATT_CHAN_OPT(params));
5180 }
5181
5182 #if defined(CONFIG_BT_GATT_AUTO_DISCOVER_CCC)
gatt_ccc_discover_cb(struct bt_conn * conn,const struct bt_gatt_attr * attr,struct bt_gatt_discover_params * params)5183 static uint8_t gatt_ccc_discover_cb(struct bt_conn *conn,
5184 const struct bt_gatt_attr *attr,
5185 struct bt_gatt_discover_params *params)
5186 {
5187 struct bt_gatt_subscribe_params *sub_params = params->sub_params;
5188
5189 if (!attr) {
5190 memset(params, 0, sizeof(*params));
5191 sub_params->notify(conn, sub_params, NULL, 0);
5192 return BT_GATT_ITER_STOP;
5193 }
5194
5195 if (params->type == BT_GATT_DISCOVER_DESCRIPTOR) {
5196 memset(params, 0, sizeof(*params));
5197 sub_params->ccc_handle = attr->handle;
5198
5199 if (bt_gatt_subscribe(conn, sub_params)) {
5200 sub_params->notify(conn, sub_params, NULL, 0);
5201 }
5202 /* else if no error occurred, then `bt_gatt_subscribe` will
5203 * call the notify function once subscribed.
5204 */
5205
5206 return BT_GATT_ITER_STOP;
5207 }
5208
5209 return BT_GATT_ITER_CONTINUE;
5210 }
5211
gatt_ccc_discover(struct bt_conn * conn,struct bt_gatt_subscribe_params * params)5212 static int gatt_ccc_discover(struct bt_conn *conn,
5213 struct bt_gatt_subscribe_params *params)
5214 {
5215 int err;
5216 static struct bt_uuid_16 ccc_uuid = BT_UUID_INIT_16(0);
5217
5218 memcpy(&ccc_uuid, BT_UUID_GATT_CCC, sizeof(ccc_uuid));
5219 memset(params->disc_params, 0, sizeof(*params->disc_params));
5220
5221 params->disc_params->sub_params = params;
5222 params->disc_params->uuid = &ccc_uuid.uuid;
5223 params->disc_params->type = BT_GATT_DISCOVER_DESCRIPTOR;
5224 params->disc_params->start_handle = params->value_handle;
5225 params->disc_params->end_handle = params->end_handle;
5226 params->disc_params->func = gatt_ccc_discover_cb;
5227 #if defined(CONFIG_BT_EATT)
5228 params->disc_params->chan_opt = params->chan_opt;
5229 #endif /* CONFIG_BT_EATT */
5230
5231 err = bt_gatt_discover(conn, params->disc_params);
5232 if (err) {
5233 LOG_DBG("CCC Discovery failed (err %d)", err);
5234 return err;
5235 }
5236 return 0;
5237
5238 }
5239 #endif /* CONFIG_BT_GATT_AUTO_DISCOVER_CCC */
5240
bt_gatt_subscribe(struct bt_conn * conn,struct bt_gatt_subscribe_params * params)5241 int bt_gatt_subscribe(struct bt_conn *conn,
5242 struct bt_gatt_subscribe_params *params)
5243 {
5244 struct gatt_sub *sub;
5245 struct bt_gatt_subscribe_params *tmp;
5246 bool has_subscription = false;
5247
5248 __ASSERT(conn, "invalid parameters\n");
5249 __ASSERT(params && params->notify, "invalid parameters\n");
5250 __ASSERT(params->value, "invalid parameters\n");
5251 #if defined(CONFIG_BT_GATT_AUTO_DISCOVER_CCC)
5252 __ASSERT(params->ccc_handle ||
5253 (params->end_handle && params->disc_params),
5254 "invalid parameters\n");
5255 #else
5256 __ASSERT(params->ccc_handle, "invalid parameters\n");
5257 #endif
5258
5259 if (conn->state != BT_CONN_CONNECTED) {
5260 return -ENOTCONN;
5261 }
5262
5263 sub = gatt_sub_add(conn);
5264 if (!sub) {
5265 return -ENOMEM;
5266 }
5267
5268 /* Lookup existing subscriptions */
5269 SYS_SLIST_FOR_EACH_CONTAINER(&sub->list, tmp, node) {
5270 /* Fail if entry already exists */
5271 if (tmp == params) {
5272 gatt_sub_remove(conn, sub, NULL, NULL);
5273 return -EALREADY;
5274 }
5275
5276 /* Check if another subscription exists */
5277 if (tmp->value_handle == params->value_handle &&
5278 tmp->value >= params->value) {
5279 has_subscription = true;
5280 }
5281 }
5282
5283 /* Skip write if already subscribed */
5284 if (!has_subscription) {
5285 int err;
5286
5287 #if defined(CONFIG_BT_GATT_AUTO_DISCOVER_CCC)
5288 if (!params->ccc_handle) {
5289 return gatt_ccc_discover(conn, params);
5290 }
5291 #endif
5292 err = gatt_write_ccc(conn, params);
5293 if (err) {
5294 gatt_sub_remove(conn, sub, NULL, NULL);
5295 return err;
5296 }
5297 }
5298
5299 /*
5300 * Add subscription before write complete as some implementation were
5301 * reported to send notification before reply to CCC write.
5302 */
5303 sys_slist_prepend(&sub->list, ¶ms->node);
5304
5305 return 0;
5306 }
5307
bt_gatt_resubscribe(uint8_t id,const bt_addr_le_t * peer,struct bt_gatt_subscribe_params * params)5308 int bt_gatt_resubscribe(uint8_t id, const bt_addr_le_t *peer,
5309 struct bt_gatt_subscribe_params *params)
5310 {
5311 struct gatt_sub *sub;
5312 struct bt_gatt_subscribe_params *tmp;
5313
5314 __ASSERT(params && params->notify, "invalid parameters\n");
5315 __ASSERT(params->value, "invalid parameters\n");
5316 __ASSERT(params->ccc_handle, "invalid parameters\n");
5317
5318 sub = gatt_sub_add_by_addr(id, peer);
5319 if (!sub) {
5320 return -ENOMEM;
5321 }
5322
5323 /* Lookup existing subscriptions */
5324 SYS_SLIST_FOR_EACH_CONTAINER(&sub->list, tmp, node) {
5325 /* Fail if entry already exists */
5326 if (tmp == params) {
5327 gatt_sub_remove(NULL, sub, NULL, NULL);
5328 return -EALREADY;
5329 }
5330 }
5331
5332 sys_slist_prepend(&sub->list, ¶ms->node);
5333 return 0;
5334 }
5335
bt_gatt_unsubscribe(struct bt_conn * conn,struct bt_gatt_subscribe_params * params)5336 int bt_gatt_unsubscribe(struct bt_conn *conn,
5337 struct bt_gatt_subscribe_params *params)
5338 {
5339 struct gatt_sub *sub;
5340 struct bt_gatt_subscribe_params *tmp;
5341 bool has_subscription = false, found = false;
5342
5343 __ASSERT(conn, "invalid parameters\n");
5344 __ASSERT(params, "invalid parameters\n");
5345
5346 if (conn->state != BT_CONN_CONNECTED) {
5347 return -ENOTCONN;
5348 }
5349
5350 sub = gatt_sub_find(conn);
5351 if (!sub) {
5352 return -EINVAL;
5353 }
5354
5355 /* Lookup existing subscriptions */
5356 SYS_SLIST_FOR_EACH_CONTAINER(&sub->list, tmp, node) {
5357 if (params == tmp) {
5358 found = true;
5359 continue;
5360 }
5361
5362 /* Check if there still remains any other subscription */
5363 if (tmp->value_handle == params->value_handle) {
5364 has_subscription = true;
5365 }
5366 }
5367
5368 if (!found) {
5369 return -EINVAL;
5370 }
5371
5372 /* Attempt to cancel if write is pending */
5373 if (atomic_test_bit(params->flags, BT_GATT_SUBSCRIBE_FLAG_WRITE_PENDING)) {
5374 bt_gatt_cancel(conn, params);
5375 }
5376
5377 if (!has_subscription) {
5378 int err;
5379
5380 params->value = 0x0000;
5381 err = gatt_write_ccc(conn, params);
5382 if (err) {
5383 return err;
5384 }
5385 }
5386
5387 sys_slist_find_and_remove(&sub->list, ¶ms->node);
5388
5389 if (gatt_sub_is_empty(sub)) {
5390 gatt_sub_free(sub);
5391 }
5392
5393 if (has_subscription) {
5394 /* Notify with NULL data to complete unsubscribe */
5395 params->notify(conn, params, NULL, 0);
5396 }
5397
5398 return 0;
5399 }
5400
bt_gatt_cancel(struct bt_conn * conn,void * params)5401 void bt_gatt_cancel(struct bt_conn *conn, void *params)
5402 {
5403 struct bt_att_req *req;
5404 bt_att_func_t func = NULL;
5405
5406 k_sched_lock();
5407
5408 req = bt_att_find_req_by_user_data(conn, params);
5409 if (req) {
5410 func = req->func;
5411 bt_att_req_cancel(conn, req);
5412 }
5413
5414 k_sched_unlock();
5415
5416 if (func) {
5417 func(conn, BT_ATT_ERR_UNLIKELY, NULL, 0, params);
5418 }
5419 }
5420
5421 #if defined(CONFIG_BT_GATT_AUTO_RESUBSCRIBE)
add_subscriptions(struct bt_conn * conn)5422 static void add_subscriptions(struct bt_conn *conn)
5423 {
5424 struct gatt_sub *sub;
5425 struct bt_gatt_subscribe_params *params;
5426
5427 if (!bt_addr_le_is_bonded(conn->id, &conn->le.dst)) {
5428 return;
5429 }
5430
5431 sub = gatt_sub_find(conn);
5432 if (!sub) {
5433 return;
5434 }
5435
5436 /* Lookup existing subscriptions */
5437 SYS_SLIST_FOR_EACH_CONTAINER(&sub->list, params, node) {
5438 if (!atomic_test_bit(params->flags,
5439 BT_GATT_SUBSCRIBE_FLAG_SENT) &&
5440 !atomic_test_bit(params->flags,
5441 BT_GATT_SUBSCRIBE_FLAG_NO_RESUB)) {
5442 /* Force write to CCC to workaround devices that don't
5443 * track it properly.
5444 */
5445 gatt_write_ccc(conn, params);
5446 }
5447 }
5448 }
5449 #endif /* CONFIG_BT_GATT_AUTO_RESUBSCRIBE */
5450
5451 #if defined(CONFIG_BT_GATT_AUTO_UPDATE_MTU)
gatt_exchange_mtu_func(struct bt_conn * conn,uint8_t err,struct bt_gatt_exchange_params * params)5452 static void gatt_exchange_mtu_func(struct bt_conn *conn, uint8_t err,
5453 struct bt_gatt_exchange_params *params)
5454 {
5455 if (err) {
5456 LOG_WRN("conn %p err 0x%02x", conn, err);
5457 }
5458 }
5459
5460 static struct bt_gatt_exchange_params gatt_exchange_params = {
5461 .func = gatt_exchange_mtu_func,
5462 };
5463 #endif /* CONFIG_BT_GATT_AUTO_UPDATE_MTU */
5464 #endif /* CONFIG_BT_GATT_CLIENT */
5465
5466 #define CCC_STORE_MAX 48
5467
ccc_find_cfg(struct _bt_gatt_ccc * ccc,const bt_addr_le_t * addr,uint8_t id)5468 static struct bt_gatt_ccc_cfg *ccc_find_cfg(struct _bt_gatt_ccc *ccc,
5469 const bt_addr_le_t *addr,
5470 uint8_t id)
5471 {
5472 for (size_t i = 0; i < ARRAY_SIZE(ccc->cfg); i++) {
5473 if (id == ccc->cfg[i].id &&
5474 bt_addr_le_eq(&ccc->cfg[i].peer, addr)) {
5475 return &ccc->cfg[i];
5476 }
5477 }
5478
5479 return NULL;
5480 }
5481
5482 struct addr_with_id {
5483 const bt_addr_le_t *addr;
5484 uint8_t id;
5485 };
5486
5487 struct ccc_load {
5488 struct addr_with_id addr_with_id;
5489 struct ccc_store *entry;
5490 size_t count;
5491 };
5492
ccc_clear(struct _bt_gatt_ccc * ccc,const bt_addr_le_t * addr,uint8_t id)5493 static void ccc_clear(struct _bt_gatt_ccc *ccc,
5494 const bt_addr_le_t *addr,
5495 uint8_t id)
5496 {
5497 struct bt_gatt_ccc_cfg *cfg;
5498
5499 cfg = ccc_find_cfg(ccc, addr, id);
5500 if (!cfg) {
5501 LOG_DBG("Unable to clear CCC: cfg not found");
5502 return;
5503 }
5504
5505 clear_ccc_cfg(cfg);
5506 }
5507
ccc_load(const struct bt_gatt_attr * attr,uint16_t handle,void * user_data)5508 static uint8_t ccc_load(const struct bt_gatt_attr *attr, uint16_t handle,
5509 void *user_data)
5510 {
5511 struct ccc_load *load = user_data;
5512 struct _bt_gatt_ccc *ccc;
5513 struct bt_gatt_ccc_cfg *cfg;
5514
5515 /* Check if attribute is a CCC */
5516 if (attr->write != bt_gatt_attr_write_ccc) {
5517 return BT_GATT_ITER_CONTINUE;
5518 }
5519
5520 ccc = attr->user_data;
5521
5522 /* Clear if value was invalidated */
5523 if (!load->entry) {
5524 ccc_clear(ccc, load->addr_with_id.addr, load->addr_with_id.id);
5525 return BT_GATT_ITER_CONTINUE;
5526 } else if (!load->count) {
5527 return BT_GATT_ITER_STOP;
5528 }
5529
5530 /* Skip if value is not for the given attribute */
5531 if (load->entry->handle != handle) {
5532 /* If attribute handle is bigger then it means
5533 * the attribute no longer exists and cannot
5534 * be restored.
5535 */
5536 if (load->entry->handle < handle) {
5537 LOG_DBG("Unable to restore CCC: handle 0x%04x cannot be"
5538 " found", load->entry->handle);
5539 goto next;
5540 }
5541 return BT_GATT_ITER_CONTINUE;
5542 }
5543
5544 LOG_DBG("Restoring CCC: handle 0x%04x value 0x%04x", load->entry->handle,
5545 load->entry->value);
5546
5547 cfg = ccc_find_cfg(ccc, load->addr_with_id.addr, load->addr_with_id.id);
5548 if (!cfg) {
5549 cfg = ccc_find_cfg(ccc, BT_ADDR_LE_ANY, 0);
5550 if (!cfg) {
5551 LOG_DBG("Unable to restore CCC: no cfg left");
5552 goto next;
5553 }
5554 bt_addr_le_copy(&cfg->peer, load->addr_with_id.addr);
5555 cfg->id = load->addr_with_id.id;
5556 }
5557
5558 cfg->value = load->entry->value;
5559
5560 next:
5561 load->entry++;
5562 load->count--;
5563
5564 return load->count ? BT_GATT_ITER_CONTINUE : BT_GATT_ITER_STOP;
5565 }
5566
ccc_set(const char * name,size_t len_rd,settings_read_cb read_cb,void * cb_arg)5567 static int ccc_set(const char *name, size_t len_rd, settings_read_cb read_cb,
5568 void *cb_arg)
5569 {
5570 if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
5571 struct ccc_store ccc_store[CCC_STORE_MAX];
5572 struct ccc_load load;
5573 bt_addr_le_t addr;
5574 ssize_t len;
5575 int err;
5576 const char *next;
5577
5578 settings_name_next(name, &next);
5579
5580 if (!name) {
5581 LOG_ERR("Insufficient number of arguments");
5582 return -EINVAL;
5583 } else if (!next) {
5584 load.addr_with_id.id = BT_ID_DEFAULT;
5585 } else {
5586 unsigned long next_id = strtoul(next, NULL, 10);
5587
5588 if (next_id >= CONFIG_BT_ID_MAX) {
5589 LOG_ERR("Invalid local identity %lu", next_id);
5590 return -EINVAL;
5591 }
5592
5593 load.addr_with_id.id = (uint8_t)next_id;
5594 }
5595
5596 err = bt_settings_decode_key(name, &addr);
5597 if (err) {
5598 LOG_ERR("Unable to decode address %s", name);
5599 return -EINVAL;
5600 }
5601
5602 load.addr_with_id.addr = &addr;
5603
5604 if (len_rd) {
5605 len = read_cb(cb_arg, ccc_store, sizeof(ccc_store));
5606
5607 if (len < 0) {
5608 LOG_ERR("Failed to decode value (err %zd)", len);
5609 return len;
5610 }
5611
5612 load.entry = ccc_store;
5613 load.count = len / sizeof(*ccc_store);
5614
5615 for (size_t i = 0; i < load.count; i++) {
5616 LOG_DBG("Read CCC: handle 0x%04x value 0x%04x", ccc_store[i].handle,
5617 ccc_store[i].value);
5618 }
5619 } else {
5620 load.entry = NULL;
5621 load.count = 0;
5622 }
5623
5624 bt_gatt_foreach_attr(0x0001, 0xffff, ccc_load, &load);
5625
5626 LOG_DBG("Restored CCC for id:%" PRIu8 " addr:%s", load.addr_with_id.id,
5627 bt_addr_le_str(load.addr_with_id.addr));
5628 }
5629
5630 return 0;
5631 }
5632
ccc_set_cb(const char * name,size_t len_rd,settings_read_cb read_cb,void * cb_arg)5633 static int ccc_set_cb(const char *name, size_t len_rd, settings_read_cb read_cb,
5634 void *cb_arg)
5635 {
5636 if (IS_ENABLED(CONFIG_BT_SETTINGS_CCC_LAZY_LOADING)) {
5637 /* Only load CCCs on demand */
5638 return 0;
5639 }
5640
5641 return ccc_set(name, len_rd, read_cb, cb_arg);
5642 }
5643
5644 BT_SETTINGS_DEFINE(ccc, "ccc", ccc_set_cb, NULL);
5645
ccc_set_direct(const char * key,size_t len,settings_read_cb read_cb,void * cb_arg,void * param)5646 static int ccc_set_direct(const char *key, size_t len, settings_read_cb read_cb,
5647 void *cb_arg, void *param)
5648 {
5649 if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
5650 const char *name;
5651
5652 LOG_DBG("key: %s", (const char *)param);
5653
5654 /* Only "bt/ccc" settings should ever come here */
5655 if (!settings_name_steq((const char *)param, "bt/ccc", &name)) {
5656 LOG_ERR("Invalid key");
5657 return -EINVAL;
5658 }
5659
5660 return ccc_set(name, len, read_cb, cb_arg);
5661 }
5662 return 0;
5663 }
5664
bt_gatt_connected(struct bt_conn * conn)5665 void bt_gatt_connected(struct bt_conn *conn)
5666 {
5667 struct conn_data data;
5668
5669 LOG_DBG("conn %p", conn);
5670
5671 data.conn = conn;
5672 data.sec = BT_SECURITY_L1;
5673
5674 /* Load CCC settings from backend if bonded */
5675 if (IS_ENABLED(CONFIG_BT_SETTINGS_CCC_LAZY_LOADING) &&
5676 bt_addr_le_is_bonded(conn->id, &conn->le.dst)) {
5677 char key[BT_SETTINGS_KEY_MAX];
5678
5679 if (conn->id) {
5680 char id_str[4];
5681
5682 u8_to_dec(id_str, sizeof(id_str), conn->id);
5683 bt_settings_encode_key(key, sizeof(key), "ccc",
5684 &conn->le.dst, id_str);
5685 } else {
5686 bt_settings_encode_key(key, sizeof(key), "ccc",
5687 &conn->le.dst, NULL);
5688 }
5689
5690 settings_load_subtree_direct(key, ccc_set_direct, (void *)key);
5691 }
5692
5693 bt_gatt_foreach_attr(0x0001, 0xffff, update_ccc, &data);
5694
5695 /* BLUETOOTH CORE SPECIFICATION Version 5.1 | Vol 3, Part C page 2192:
5696 *
5697 * 10.3.1.1 Handling of GATT indications and notifications
5698 *
5699 * A client “requests” a server to send indications and notifications
5700 * by appropriately configuring the server via a Client Characteristic
5701 * Configuration Descriptor. Since the configuration is persistent
5702 * across a disconnection and reconnection, security requirements must
5703 * be checked against the configuration upon a reconnection before
5704 * sending indications or notifications. When a server reconnects to a
5705 * client to send an indication or notification for which security is
5706 * required, the server shall initiate or request encryption with the
5707 * client prior to sending an indication or notification. If the client
5708 * does not have an LTK indicating that the client has lost the bond,
5709 * enabling encryption will fail.
5710 */
5711 if (IS_ENABLED(CONFIG_BT_SMP) &&
5712 (conn->role == BT_HCI_ROLE_CENTRAL ||
5713 IS_ENABLED(CONFIG_BT_GATT_AUTO_SEC_REQ)) &&
5714 bt_conn_get_security(conn) < data.sec) {
5715 int err = bt_conn_set_security(conn, data.sec);
5716
5717 if (err) {
5718 LOG_WRN("Failed to set security for bonded peer (%d)", err);
5719 }
5720 }
5721
5722 #if defined(CONFIG_BT_GATT_AUTO_UPDATE_MTU)
5723 int err;
5724
5725 err = bt_gatt_exchange_mtu(conn, &gatt_exchange_params);
5726 if (err) {
5727 LOG_WRN("MTU Exchange failed (err %d)", err);
5728 }
5729 #endif /* CONFIG_BT_GATT_AUTO_UPDATE_MTU */
5730 }
5731
bt_gatt_att_max_mtu_changed(struct bt_conn * conn,uint16_t tx,uint16_t rx)5732 void bt_gatt_att_max_mtu_changed(struct bt_conn *conn, uint16_t tx, uint16_t rx)
5733 {
5734 struct bt_gatt_cb *cb;
5735
5736 SYS_SLIST_FOR_EACH_CONTAINER(&callback_list, cb, node) {
5737 if (cb->att_mtu_updated) {
5738 cb->att_mtu_updated(conn, tx, rx);
5739 }
5740 }
5741 }
5742
bt_gatt_encrypt_change(struct bt_conn * conn)5743 void bt_gatt_encrypt_change(struct bt_conn *conn)
5744 {
5745 struct conn_data data;
5746
5747 LOG_DBG("conn %p", conn);
5748
5749 data.conn = conn;
5750 data.sec = BT_SECURITY_L1;
5751
5752 #if defined(CONFIG_BT_GATT_AUTO_RESUBSCRIBE)
5753 add_subscriptions(conn);
5754 #endif /* CONFIG_BT_GATT_AUTO_RESUBSCRIBE */
5755
5756 bt_gatt_foreach_attr(0x0001, 0xffff, update_ccc, &data);
5757
5758 #if defined(CONFIG_BT_SETTINGS) && defined(CONFIG_BT_GATT_SERVICE_CHANGED)
5759 if (!bt_gatt_change_aware(conn, false)) {
5760 /* Send a Service Changed indication if the current peer is
5761 * marked as change-unaware.
5762 */
5763 sc_indicate(0x0001, 0xffff);
5764 }
5765 #endif /* CONFIG_BT_SETTINGS && CONFIG_BT_GATT_SERVICE_CHANGED */
5766 }
5767
bt_gatt_change_aware(struct bt_conn * conn,bool req)5768 bool bt_gatt_change_aware(struct bt_conn *conn, bool req)
5769 {
5770 #if defined(CONFIG_BT_GATT_CACHING)
5771 struct gatt_cf_cfg *cfg;
5772
5773 cfg = find_cf_cfg(conn);
5774 if (!cfg || !CF_ROBUST_CACHING(cfg)) {
5775 return true;
5776 }
5777
5778 if (atomic_test_bit(cfg->flags, CF_CHANGE_AWARE)) {
5779 return true;
5780 }
5781
5782 /* BLUETOOTH CORE SPECIFICATION Version 5.1 | Vol 3, Part G page 2350:
5783 * If a change-unaware client sends an ATT command, the server shall
5784 * ignore it.
5785 */
5786 if (!req) {
5787 return false;
5788 }
5789
5790 /* BLUETOOTH CORE SPECIFICATION Version 5.3 | Vol 3, Part G page 1475:
5791 * 2.5.2.1 Robust Caching
5792 * A change-unaware connected client becomes change-aware when it reads
5793 * the Database Hash characteristic and then the server receives another
5794 * ATT request from the client.
5795 */
5796 if (atomic_test_and_clear_bit(cfg->flags, CF_DB_HASH_READ)) {
5797 bt_att_clear_out_of_sync_sent(conn);
5798 set_change_aware(cfg, true);
5799 return true;
5800 }
5801
5802 /* BLUETOOTH CORE SPECIFICATION Version 5.3 | Vol 3, Part G page 1476:
5803 * 2.5.2.1 Robust Caching
5804 * ... a change-unaware connected client using exactly one ATT bearer
5805 * becomes change-aware when ...
5806 * The server sends the client a response with the Error Code parameter
5807 * set to Database Out Of Sync (0x12) and then the server receives
5808 * another ATT request from the client.
5809 */
5810 if (bt_att_fixed_chan_only(conn) && bt_att_out_of_sync_sent_on_fixed(conn)) {
5811 atomic_clear_bit(cfg->flags, CF_DB_HASH_READ);
5812 bt_att_clear_out_of_sync_sent(conn);
5813 set_change_aware(cfg, true);
5814 return true;
5815 }
5816
5817 return false;
5818 #else
5819 return true;
5820 #endif
5821 }
5822
find_cf_cfg_by_addr(uint8_t id,const bt_addr_le_t * addr)5823 static struct gatt_cf_cfg *find_cf_cfg_by_addr(uint8_t id,
5824 const bt_addr_le_t *addr)
5825 {
5826 if (IS_ENABLED(CONFIG_BT_GATT_CACHING)) {
5827 int i;
5828
5829 for (i = 0; i < ARRAY_SIZE(cf_cfg); i++) {
5830 if (id == cf_cfg[i].id &&
5831 bt_addr_le_eq(addr, &cf_cfg[i].peer)) {
5832 return &cf_cfg[i];
5833 }
5834 }
5835 }
5836
5837 return NULL;
5838 }
5839
5840 #if defined(CONFIG_BT_SETTINGS)
5841
5842 struct ccc_save {
5843 struct addr_with_id addr_with_id;
5844 struct ccc_store store[CCC_STORE_MAX];
5845 size_t count;
5846 };
5847
ccc_save(const struct bt_gatt_attr * attr,uint16_t handle,void * user_data)5848 static uint8_t ccc_save(const struct bt_gatt_attr *attr, uint16_t handle,
5849 void *user_data)
5850 {
5851 struct ccc_save *save = user_data;
5852 struct _bt_gatt_ccc *ccc;
5853 struct bt_gatt_ccc_cfg *cfg;
5854
5855 /* Check if attribute is a CCC */
5856 if (attr->write != bt_gatt_attr_write_ccc) {
5857 return BT_GATT_ITER_CONTINUE;
5858 }
5859
5860 ccc = attr->user_data;
5861
5862 /* Check if there is a cfg for the peer */
5863 cfg = ccc_find_cfg(ccc, save->addr_with_id.addr, save->addr_with_id.id);
5864 if (!cfg) {
5865 return BT_GATT_ITER_CONTINUE;
5866 }
5867
5868 LOG_DBG("Storing CCCs handle 0x%04x value 0x%04x", handle, cfg->value);
5869
5870 save->store[save->count].handle = handle;
5871 save->store[save->count].value = cfg->value;
5872 save->count++;
5873
5874 return BT_GATT_ITER_CONTINUE;
5875 }
5876
bt_gatt_store_ccc(uint8_t id,const bt_addr_le_t * addr)5877 int bt_gatt_store_ccc(uint8_t id, const bt_addr_le_t *addr)
5878 {
5879 struct ccc_save save;
5880 size_t len;
5881 char *str;
5882 int err;
5883
5884 save.addr_with_id.addr = addr;
5885 save.addr_with_id.id = id;
5886 save.count = 0;
5887
5888 bt_gatt_foreach_attr(0x0001, 0xffff, ccc_save, &save);
5889
5890 if (save.count) {
5891 str = (char *)save.store;
5892 len = save.count * sizeof(*save.store);
5893 } else {
5894 /* No entries to encode, just clear */
5895 str = NULL;
5896 len = 0;
5897 }
5898
5899 err = bt_settings_store_ccc(id, addr, str, len);
5900 if (err) {
5901 LOG_ERR("Failed to store CCCs (err %d)", err);
5902 return err;
5903 }
5904
5905 LOG_DBG("Stored CCCs for %s", bt_addr_le_str(addr));
5906 if (len) {
5907 for (size_t i = 0; i < save.count; i++) {
5908 LOG_DBG(" CCC: handle 0x%04x value 0x%04x", save.store[i].handle,
5909 save.store[i].value);
5910 }
5911 } else {
5912 LOG_DBG(" CCC: NULL");
5913 }
5914
5915 return 0;
5916 }
5917
5918 #if defined(CONFIG_BT_GATT_SERVICE_CHANGED)
sc_set(const char * name,size_t len_rd,settings_read_cb read_cb,void * cb_arg)5919 static int sc_set(const char *name, size_t len_rd, settings_read_cb read_cb,
5920 void *cb_arg)
5921 {
5922 struct gatt_sc_cfg *cfg;
5923 uint8_t id;
5924 bt_addr_le_t addr;
5925 ssize_t len;
5926 int err;
5927 const char *next;
5928
5929 if (!name) {
5930 LOG_ERR("Insufficient number of arguments");
5931 return -EINVAL;
5932 }
5933
5934 err = bt_settings_decode_key(name, &addr);
5935 if (err) {
5936 LOG_ERR("Unable to decode address %s", name);
5937 return -EINVAL;
5938 }
5939
5940 settings_name_next(name, &next);
5941
5942 if (!next) {
5943 id = BT_ID_DEFAULT;
5944 } else {
5945 unsigned long next_id = strtoul(next, NULL, 10);
5946
5947 if (next_id >= CONFIG_BT_ID_MAX) {
5948 LOG_ERR("Invalid local identity %lu", next_id);
5949 return -EINVAL;
5950 }
5951
5952 id = (uint8_t)next_id;
5953 }
5954
5955 cfg = find_sc_cfg(id, &addr);
5956 if (!cfg && len_rd) {
5957 /* Find and initialize a free sc_cfg entry */
5958 cfg = find_sc_cfg(BT_ID_DEFAULT, BT_ADDR_LE_ANY);
5959 if (!cfg) {
5960 LOG_ERR("Unable to restore SC: no cfg left");
5961 return -ENOMEM;
5962 }
5963
5964 cfg->id = id;
5965 bt_addr_le_copy(&cfg->peer, &addr);
5966 }
5967
5968 if (len_rd) {
5969 len = read_cb(cb_arg, &cfg->data, sizeof(cfg->data));
5970 if (len < 0) {
5971 LOG_ERR("Failed to decode value (err %zd)", len);
5972 return len;
5973 }
5974
5975 LOG_DBG("Read SC: len %zd", len);
5976
5977 LOG_DBG("Restored SC for %s", bt_addr_le_str(&addr));
5978 } else if (cfg) {
5979 /* Clear configuration */
5980 memset(cfg, 0, sizeof(*cfg));
5981
5982 LOG_DBG("Removed SC for %s", bt_addr_le_str(&addr));
5983 }
5984
5985 return 0;
5986 }
5987
sc_commit(void)5988 static int sc_commit(void)
5989 {
5990 atomic_set_bit(gatt_sc.flags, SC_LOAD);
5991 atomic_clear_bit(gatt_sc.flags, SC_INDICATE_PENDING);
5992
5993 if (atomic_test_bit(gatt_sc.flags, SC_RANGE_CHANGED)) {
5994 /* Schedule SC indication since the range has changed */
5995 sc_work_submit(SC_TIMEOUT);
5996 }
5997
5998 return 0;
5999 }
6000
6001 BT_SETTINGS_DEFINE(sc, "sc", sc_set, sc_commit);
6002 #endif /* CONFIG_BT_GATT_SERVICE_CHANGED */
6003
6004 #if defined(CONFIG_BT_GATT_CACHING)
cf_set(const char * name,size_t len_rd,settings_read_cb read_cb,void * cb_arg)6005 static int cf_set(const char *name, size_t len_rd, settings_read_cb read_cb,
6006 void *cb_arg)
6007 {
6008 struct gatt_cf_cfg *cfg;
6009 bt_addr_le_t addr;
6010 const char *next;
6011 ssize_t len;
6012 int err;
6013 uint8_t id;
6014
6015 if (!name) {
6016 LOG_ERR("Insufficient number of arguments");
6017 return -EINVAL;
6018 }
6019
6020 err = bt_settings_decode_key(name, &addr);
6021 if (err) {
6022 LOG_ERR("Unable to decode address %s", name);
6023 return -EINVAL;
6024 }
6025
6026 settings_name_next(name, &next);
6027
6028 if (!next) {
6029 id = BT_ID_DEFAULT;
6030 } else {
6031 unsigned long next_id = strtoul(next, NULL, 10);
6032
6033 if (next_id >= CONFIG_BT_ID_MAX) {
6034 LOG_ERR("Invalid local identity %lu", next_id);
6035 return -EINVAL;
6036 }
6037
6038 id = (uint8_t)next_id;
6039 }
6040
6041 cfg = find_cf_cfg_by_addr(id, &addr);
6042 if (!cfg) {
6043 cfg = find_cf_cfg(NULL);
6044 if (!cfg) {
6045 LOG_ERR("Unable to restore CF: no cfg left");
6046 return -ENOMEM;
6047 }
6048
6049 cfg->id = id;
6050 bt_addr_le_copy(&cfg->peer, &addr);
6051 }
6052
6053 if (len_rd) {
6054 char dst[CF_NUM_BYTES + CF_FLAGS_STORE_LEN];
6055
6056 len = read_cb(cb_arg, dst, sizeof(dst));
6057 if (len < 0) {
6058 LOG_ERR("Failed to decode value (err %zd)", len);
6059 return len;
6060 }
6061
6062 memcpy(cfg->data, dst, sizeof(cfg->data));
6063 LOG_DBG("Read CF: len %zd", len);
6064
6065 if (len != sizeof(dst)) {
6066 LOG_WRN("Change-aware status not found in settings, "
6067 "defaulting peer status to change-unaware");
6068 set_change_aware(cfg, false);
6069 } else {
6070 /* change-aware byte is present in NVS */
6071 uint8_t change_aware = dst[sizeof(cfg->data)];
6072
6073 if (change_aware & ~BIT(CF_CHANGE_AWARE)) {
6074 LOG_WRN("Read back bad change-aware value: 0x%x, "
6075 "defaulting peer status to change-unaware",
6076 change_aware);
6077 set_change_aware(cfg, false);
6078 } else {
6079 set_change_aware_no_store(cfg, change_aware);
6080 }
6081 }
6082 } else {
6083 clear_cf_cfg(cfg);
6084 }
6085
6086 LOG_DBG("Restored CF for %s", bt_addr_le_str(&addr));
6087
6088 return 0;
6089 }
6090
6091 BT_SETTINGS_DEFINE(cf, "cf", cf_set, NULL);
6092
db_hash_set(const char * name,size_t len_rd,settings_read_cb read_cb,void * cb_arg)6093 static int db_hash_set(const char *name, size_t len_rd,
6094 settings_read_cb read_cb, void *cb_arg)
6095 {
6096 ssize_t len;
6097
6098 len = read_cb(cb_arg, db_hash.stored_hash, sizeof(db_hash.stored_hash));
6099 if (len < 0) {
6100 LOG_ERR("Failed to decode value (err %zd)", len);
6101 return len;
6102 }
6103
6104 LOG_HEXDUMP_DBG(db_hash.stored_hash, sizeof(db_hash.stored_hash), "Stored Hash: ");
6105
6106 return 0;
6107 }
6108
db_hash_commit(void)6109 static int db_hash_commit(void)
6110 {
6111 atomic_set_bit(gatt_sc.flags, DB_HASH_LOAD);
6112
6113 /* Calculate the hash and compare it against the value loaded from
6114 * flash. Do it from the current context to avoid any potential race
6115 * conditions.
6116 */
6117 do_db_hash();
6118
6119 return 0;
6120 }
6121
6122 BT_SETTINGS_DEFINE(hash, "hash", db_hash_set, db_hash_commit);
6123 #endif /*CONFIG_BT_GATT_CACHING */
6124 #endif /* CONFIG_BT_SETTINGS */
6125
remove_peer_from_attr(const struct bt_gatt_attr * attr,uint16_t handle,void * user_data)6126 static uint8_t remove_peer_from_attr(const struct bt_gatt_attr *attr,
6127 uint16_t handle, void *user_data)
6128 {
6129 const struct addr_with_id *addr_with_id = user_data;
6130 struct _bt_gatt_ccc *ccc;
6131 struct bt_gatt_ccc_cfg *cfg;
6132
6133 /* Check if attribute is a CCC */
6134 if (attr->write != bt_gatt_attr_write_ccc) {
6135 return BT_GATT_ITER_CONTINUE;
6136 }
6137
6138 ccc = attr->user_data;
6139
6140 /* Check if there is a cfg for the peer */
6141 cfg = ccc_find_cfg(ccc, addr_with_id->addr, addr_with_id->id);
6142 if (cfg) {
6143 memset(cfg, 0, sizeof(*cfg));
6144 }
6145
6146 return BT_GATT_ITER_CONTINUE;
6147 }
6148
bt_gatt_clear_ccc(uint8_t id,const bt_addr_le_t * addr)6149 static int bt_gatt_clear_ccc(uint8_t id, const bt_addr_le_t *addr)
6150 {
6151 struct addr_with_id addr_with_id = {
6152 .addr = addr,
6153 .id = id,
6154 };
6155
6156 bt_gatt_foreach_attr(0x0001, 0xffff, remove_peer_from_attr,
6157 &addr_with_id);
6158
6159 if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
6160 return bt_settings_delete_ccc(id, addr);
6161 }
6162
6163 return 0;
6164 }
6165
bt_gatt_clear_cf(uint8_t id,const bt_addr_le_t * addr)6166 static int bt_gatt_clear_cf(uint8_t id, const bt_addr_le_t *addr)
6167 {
6168 struct gatt_cf_cfg *cfg;
6169
6170 cfg = find_cf_cfg_by_addr(id, addr);
6171 if (cfg) {
6172 clear_cf_cfg(cfg);
6173 }
6174
6175 if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
6176 return bt_settings_delete_ccc(id, addr);
6177 }
6178
6179 return 0;
6180
6181 }
6182
6183
find_gatt_sub(uint8_t id,const bt_addr_le_t * addr)6184 static struct gatt_sub *find_gatt_sub(uint8_t id, const bt_addr_le_t *addr)
6185 {
6186 for (int i = 0; i < ARRAY_SIZE(subscriptions); i++) {
6187 struct gatt_sub *sub = &subscriptions[i];
6188
6189 if (id == sub->id &&
6190 bt_addr_le_eq(addr, &sub->peer)) {
6191 return sub;
6192 }
6193 }
6194
6195 return NULL;
6196 }
6197
bt_gatt_clear_subscriptions(uint8_t id,const bt_addr_le_t * addr)6198 static void bt_gatt_clear_subscriptions(uint8_t id, const bt_addr_le_t *addr)
6199 {
6200 struct gatt_sub *sub;
6201 struct bt_gatt_subscribe_params *params, *tmp;
6202 sys_snode_t *prev = NULL;
6203
6204 sub = find_gatt_sub(id, addr);
6205 if (!sub) {
6206 return;
6207 }
6208
6209 SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&sub->list, params, tmp,
6210 node) {
6211 params->value = 0U;
6212 gatt_sub_remove(NULL, sub, prev, params);
6213 }
6214 }
6215
bt_gatt_clear(uint8_t id,const bt_addr_le_t * addr)6216 int bt_gatt_clear(uint8_t id, const bt_addr_le_t *addr)
6217 {
6218 int err;
6219
6220 err = bt_gatt_clear_ccc(id, addr);
6221 if (err < 0) {
6222 return err;
6223 }
6224
6225 if (IS_ENABLED(CONFIG_BT_GATT_SERVICE_CHANGED)) {
6226 err = bt_gatt_clear_sc(id, addr);
6227 if (err < 0) {
6228 return err;
6229 }
6230 }
6231
6232 if (IS_ENABLED(CONFIG_BT_GATT_CACHING)) {
6233 err = bt_gatt_clear_cf(id, addr);
6234 if (err < 0) {
6235 return err;
6236 }
6237 }
6238
6239 if (IS_ENABLED(CONFIG_BT_GATT_CLIENT)) {
6240 bt_gatt_clear_subscriptions(id, addr);
6241 }
6242
6243 return 0;
6244 }
6245
bt_gatt_disconnected(struct bt_conn * conn)6246 void bt_gatt_disconnected(struct bt_conn *conn)
6247 {
6248 LOG_DBG("conn %p", conn);
6249 bt_gatt_foreach_attr(0x0001, 0xffff, disconnected_cb, conn);
6250
6251 #if defined(CONFIG_BT_GATT_NOTIFY_MULTIPLE)
6252 /* Clear pending notifications */
6253 cleanup_notify(conn);
6254 #endif /* CONFIG_BT_GATT_NOTIFY_MULTIPLE */
6255
6256 if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
6257 gatt_store_ccc_cf(conn->id, &conn->le.dst);
6258 }
6259
6260 /* Make sure to clear the CCC entry when using lazy loading */
6261 if (IS_ENABLED(CONFIG_BT_SETTINGS_CCC_LAZY_LOADING) &&
6262 bt_addr_le_is_bonded(conn->id, &conn->le.dst)) {
6263 struct addr_with_id addr_with_id = {
6264 .addr = &conn->le.dst,
6265 .id = conn->id,
6266 };
6267 bt_gatt_foreach_attr(0x0001, 0xffff,
6268 remove_peer_from_attr,
6269 &addr_with_id);
6270 }
6271
6272 #if defined(CONFIG_BT_GATT_CLIENT)
6273 remove_subscriptions(conn);
6274 #endif /* CONFIG_BT_GATT_CLIENT */
6275
6276 #if defined(CONFIG_BT_GATT_CACHING)
6277 remove_cf_cfg(conn);
6278 #endif
6279 }
6280