1 /* Bluetooth CSIP - Coordinated Set Identification Profile */
2
3 /*
4 * Copyright (c) 2019 Bose Corporation
5 * Copyright (c) 2020-2022 Nordic Semiconductor ASA
6 *
7 * SPDX-License-Identifier: Apache-2.0
8 */
9 #include <sys/types.h>
10 #include <errno.h>
11 #include <stdbool.h>
12 #include <stddef.h>
13 #include <stdint.h>
14 #include <stdlib.h>
15 #include <string.h>
16
17 #include <zephyr/autoconf.h>
18 #include <zephyr/bluetooth/addr.h>
19 #include <zephyr/bluetooth/att.h>
20 #include <zephyr/bluetooth/audio/csip.h>
21 #include <zephyr/bluetooth/bluetooth.h>
22 #include <zephyr/bluetooth/conn.h>
23 #include <zephyr/bluetooth/crypto.h>
24 #include <zephyr/bluetooth/gatt.h>
25 #include <zephyr/bluetooth/buf.h>
26 #include <zephyr/bluetooth/uuid.h>
27 #include <zephyr/device.h>
28 #include <zephyr/init.h>
29 #include <zephyr/kernel.h>
30 #include <zephyr/logging/log.h>
31 #include <zephyr/sys/__assert.h>
32 #include <zephyr/sys/atomic.h>
33 #include <zephyr/sys/util.h>
34 #include <zephyr/sys/util_macro.h>
35 #include <zephyr/sys_clock.h>
36 #include <zephyr/types.h>
37 #include <zephyr/sys/byteorder.h>
38 #include <zephyr/sys/check.h>
39
40 #include "../host/conn_internal.h"
41 #include "../host/keys.h"
42
43 #include "common/bt_str.h"
44 #include "audio_internal.h"
45 #include "csip_internal.h"
46 #include "csip_crypto.h"
47
48 #define CSIP_SET_LOCK_TIMER_VALUE K_SECONDS(60)
49
50 #define CSIS_CHAR_ATTR_COUNT 3 /* declaration + value + cccd */
51 #define CSIS_RANK_CHAR_ATTR_COUNT 2 /* declaration + value */
52
53 LOG_MODULE_REGISTER(bt_csip_set_member, CONFIG_BT_CSIP_SET_MEMBER_LOG_LEVEL);
54
55 enum csip_flag {
56 FLAG_ACTIVE,
57 FLAG_NOTIFY_LOCK,
58 FLAG_NOTIFY_SIRK,
59 FLAG_NUM,
60 };
61
62 struct csip_client {
63 bt_addr_le_t addr;
64
65 /* Pending notification flags */
66 ATOMIC_DEFINE(flags, FLAG_NUM);
67 };
68
69 struct bt_csip_set_member_svc_inst {
70 struct bt_csip_sirk sirk;
71 uint8_t set_size;
72 uint8_t set_lock;
73 uint8_t rank;
74 struct bt_csip_set_member_cb *cb;
75 struct k_work_delayable set_lock_timer;
76 bt_addr_le_t lock_client_addr;
77 struct bt_gatt_service *service_p;
78 struct csip_client clients[CONFIG_BT_MAX_PAIRED];
79 };
80
81 static struct bt_csip_set_member_svc_inst svc_insts[CONFIG_BT_CSIP_SET_MEMBER_MAX_INSTANCE_COUNT];
82 static bt_addr_le_t server_dummy_addr; /* 0'ed address */
83
84 static void deferred_nfy_work_handler(struct k_work *work);
85
86 static K_WORK_DELAYABLE_DEFINE(deferred_nfy_work, deferred_nfy_work_handler);
87
is_last_client_to_write(const struct bt_csip_set_member_svc_inst * svc_inst,const struct bt_conn * conn)88 static bool is_last_client_to_write(const struct bt_csip_set_member_svc_inst *svc_inst,
89 const struct bt_conn *conn)
90 {
91 if (conn != NULL) {
92 return bt_addr_le_eq(bt_conn_get_dst(conn),
93 &svc_inst->lock_client_addr);
94 } else {
95 return bt_addr_le_eq(&server_dummy_addr,
96 &svc_inst->lock_client_addr);
97 }
98 }
99
notify_work_reschedule(k_timeout_t delay)100 static void notify_work_reschedule(k_timeout_t delay)
101 {
102 int err;
103
104 /* If it is already scheduled, don't reschedule */
105 if (k_work_delayable_remaining_get(&deferred_nfy_work) > 0) {
106 return;
107 }
108
109 err = k_work_reschedule(&deferred_nfy_work, delay);
110 if (err < 0) {
111 LOG_ERR("Failed to reschedule notification work err %d", err);
112 }
113 }
114
notify_clients(struct bt_csip_set_member_svc_inst * svc_inst,struct bt_conn * excluded_client,enum csip_flag flag)115 static void notify_clients(struct bt_csip_set_member_svc_inst *svc_inst,
116 struct bt_conn *excluded_client, enum csip_flag flag)
117 {
118 bool submit_work = false;
119
120 /* Mark all bonded devices (except the excluded one) as pending notifications */
121 for (size_t i = 0U; i < ARRAY_SIZE(svc_inst->clients); i++) {
122 struct csip_client *client;
123
124 client = &svc_inst->clients[i];
125
126 if (atomic_test_bit(client->flags, FLAG_ACTIVE)) {
127 if (excluded_client != NULL &&
128 bt_addr_le_eq(bt_conn_get_dst(excluded_client), &client->addr)) {
129 continue;
130 }
131
132 atomic_set_bit(client->flags, flag);
133 submit_work = true;
134 }
135 }
136
137 /* Reschedule work for notifying */
138 if (submit_work) {
139 notify_work_reschedule(K_NO_WAIT);
140 }
141 }
142
sirk_encrypt(struct bt_conn * conn,const struct bt_csip_sirk * sirk,struct bt_csip_sirk * enc_sirk)143 static int sirk_encrypt(struct bt_conn *conn, const struct bt_csip_sirk *sirk,
144 struct bt_csip_sirk *enc_sirk)
145 {
146 int err;
147 const uint8_t *k;
148
149 if (IS_ENABLED(CONFIG_BT_CSIP_SET_MEMBER_TEST_SAMPLE_DATA)) {
150 /* test_k is from the sample data from A.2 in the CSIS spec */
151 static const uint8_t test_k[] = {
152 /* Sample data is in big-endian, we need it in little-endian. */
153 + REVERSE_ARGS(0x67, 0x6e, 0x1b, 0x9b,
154 0xd4, 0x48, 0x69, 0x6f,
155 0x06, 0x1e, 0xc6, 0x22,
156 0x3c, 0xe5, 0xce, 0xd9) };
157 LOG_DBG("Encrypting test SIRK");
158 k = test_k;
159 } else {
160 if (conn == NULL) {
161 return -EINVAL;
162 }
163
164 k = conn->le.keys->ltk.val;
165 }
166
167 err = bt_csip_sef(k, sirk->value, enc_sirk->value);
168
169 if (err != 0) {
170 return err;
171 }
172
173 enc_sirk->type = BT_CSIP_SIRK_TYPE_ENCRYPTED;
174
175 return 0;
176 }
177
generate_prand(uint8_t dest[BT_CSIP_CRYPTO_PRAND_SIZE])178 static int generate_prand(uint8_t dest[BT_CSIP_CRYPTO_PRAND_SIZE])
179 {
180 bool valid = false;
181
182 do {
183 int res;
184 uint32_t prand;
185
186 *dest = 0;
187 res = bt_rand(dest, BT_CSIP_CRYPTO_PRAND_SIZE);
188 if (res != 0) {
189 return res;
190 }
191
192 /* Validate Prand: Must contain both a 1 and a 0 */
193 prand = sys_get_le24(dest);
194 if (prand != 0 && prand != 0x3FFFFF) {
195 valid = true;
196 }
197 } while (!valid);
198
199 dest[BT_CSIP_CRYPTO_PRAND_SIZE - 1] &= 0x3F;
200 dest[BT_CSIP_CRYPTO_PRAND_SIZE - 1] |= BIT(6);
201
202 return 0;
203 }
204
bt_csip_set_member_generate_rsi(const struct bt_csip_set_member_svc_inst * svc_inst,uint8_t rsi[BT_CSIP_RSI_SIZE])205 int bt_csip_set_member_generate_rsi(const struct bt_csip_set_member_svc_inst *svc_inst,
206 uint8_t rsi[BT_CSIP_RSI_SIZE])
207 {
208 int res = 0;
209 uint8_t prand[BT_CSIP_CRYPTO_PRAND_SIZE];
210 uint8_t hash[BT_CSIP_CRYPTO_HASH_SIZE];
211
212 if (IS_ENABLED(CONFIG_BT_CSIP_SET_MEMBER_TEST_SAMPLE_DATA)) {
213 /* prand is from the sample data from A.2 in the CSIS spec */
214 sys_put_le24(0x69f563, prand);
215 } else {
216 res = generate_prand(prand);
217
218 if (res != 0) {
219 LOG_WRN("Could not generate new prand");
220 return res;
221 }
222 }
223
224 res = bt_csip_sih(svc_inst->sirk.value, prand, hash);
225 if (res != 0) {
226 LOG_WRN("Could not generate new RSI");
227 return res;
228 }
229
230 (void)memcpy(rsi, hash, BT_CSIP_CRYPTO_HASH_SIZE);
231 (void)memcpy(rsi + BT_CSIP_CRYPTO_HASH_SIZE, prand, BT_CSIP_CRYPTO_PRAND_SIZE);
232
233 return res;
234 }
235
read_sirk(struct bt_conn * conn,const struct bt_gatt_attr * attr,void * buf,uint16_t len,uint16_t offset)236 static ssize_t read_sirk(struct bt_conn *conn, const struct bt_gatt_attr *attr, void *buf,
237 uint16_t len, uint16_t offset)
238 {
239 struct bt_csip_sirk enc_sirk;
240 struct bt_csip_sirk *sirk;
241 struct bt_csip_set_member_svc_inst *svc_inst = BT_AUDIO_CHRC_USER_DATA(attr);
242
243 if (svc_inst->cb != NULL && svc_inst->cb->sirk_read_req != NULL) {
244 ssize_t gatt_err = BT_GATT_ERR(BT_ATT_ERR_SUCCESS);
245 uint8_t cb_rsp;
246
247 /* Ask higher layer for what SIRK to return, if any */
248 cb_rsp = svc_inst->cb->sirk_read_req(conn, &svc_insts[0]);
249
250 if (cb_rsp == BT_CSIP_READ_SIRK_REQ_RSP_ACCEPT) {
251 sirk = &svc_inst->sirk;
252 } else if (IS_ENABLED(CONFIG_BT_CSIP_SET_MEMBER_ENC_SIRK_SUPPORT) &&
253 cb_rsp == BT_CSIP_READ_SIRK_REQ_RSP_ACCEPT_ENC) {
254 int err;
255
256 err = sirk_encrypt(conn, &svc_inst->sirk, &enc_sirk);
257 if (err != 0) {
258 LOG_ERR("Could not encrypt SIRK: %d",
259 err);
260 gatt_err = BT_GATT_ERR(BT_ATT_ERR_UNLIKELY);
261 } else {
262 sirk = &enc_sirk;
263 LOG_HEXDUMP_DBG(enc_sirk.value, sizeof(enc_sirk.value),
264 "Encrypted SIRK");
265 }
266 } else if (cb_rsp == BT_CSIP_READ_SIRK_REQ_RSP_REJECT) {
267 gatt_err = BT_GATT_ERR(BT_ATT_ERR_AUTHORIZATION);
268 } else if (cb_rsp == BT_CSIP_READ_SIRK_REQ_RSP_OOB_ONLY) {
269 gatt_err = BT_GATT_ERR(BT_CSIP_ERROR_SIRK_OOB_ONLY);
270 } else {
271 LOG_ERR("Invalid callback response: %u", cb_rsp);
272 gatt_err = BT_GATT_ERR(BT_ATT_ERR_UNLIKELY);
273 }
274
275 if (gatt_err != BT_GATT_ERR(BT_ATT_ERR_SUCCESS)) {
276 return gatt_err;
277 }
278 } else {
279 sirk = &svc_inst->sirk;
280 }
281
282 LOG_DBG("SIRK %sencrypted", sirk->type == BT_CSIP_SIRK_TYPE_PLAIN ? "not " : "");
283 LOG_HEXDUMP_DBG(svc_inst->sirk.value, sizeof(svc_inst->sirk.value), "SIRK");
284 return bt_gatt_attr_read(conn, attr, buf, len, offset,
285 sirk, sizeof(*sirk));
286 }
287
288 #if defined(CONFIG_BT_CSIP_SET_MEMBER_SIRK_NOTIFIABLE)
sirk_cfg_changed(const struct bt_gatt_attr * attr,uint16_t value)289 static void sirk_cfg_changed(const struct bt_gatt_attr *attr, uint16_t value)
290 {
291 LOG_DBG("value 0x%04x", value);
292 }
293 #endif /* CONFIG_BT_CSIP_SET_MEMBER_SIRK_NOTIFIABLE */
294
read_set_size(struct bt_conn * conn,const struct bt_gatt_attr * attr,void * buf,uint16_t len,uint16_t offset)295 static ssize_t read_set_size(struct bt_conn *conn,
296 const struct bt_gatt_attr *attr,
297 void *buf, uint16_t len, uint16_t offset)
298 {
299 struct bt_csip_set_member_svc_inst *svc_inst = BT_AUDIO_CHRC_USER_DATA(attr);
300
301 LOG_DBG("%u", svc_inst->set_size);
302
303 return bt_gatt_attr_read(conn, attr, buf, len, offset,
304 &svc_inst->set_size,
305 sizeof(svc_inst->set_size));
306 }
307
set_size_cfg_changed(const struct bt_gatt_attr * attr,uint16_t value)308 static void set_size_cfg_changed(const struct bt_gatt_attr *attr,
309 uint16_t value)
310 {
311 LOG_DBG("value 0x%04x", value);
312 }
313
read_set_lock(struct bt_conn * conn,const struct bt_gatt_attr * attr,void * buf,uint16_t len,uint16_t offset)314 static ssize_t read_set_lock(struct bt_conn *conn,
315 const struct bt_gatt_attr *attr,
316 void *buf, uint16_t len, uint16_t offset)
317 {
318 struct bt_csip_set_member_svc_inst *svc_inst = BT_AUDIO_CHRC_USER_DATA(attr);
319
320 LOG_DBG("%u", svc_inst->set_lock);
321
322 return bt_gatt_attr_read(conn, attr, buf, len, offset,
323 &svc_inst->set_lock,
324 sizeof(svc_inst->set_lock));
325 }
326
327 /**
328 * @brief Set the lock value of a CSIP instance.
329 *
330 * @param conn The connection locking the instance.
331 * Will be NULL if the server locally sets the lock.
332 * @param svc_inst The CSIP instance to change the lock value of
333 * @param val The lock value (BT_CSIP_LOCK_VALUE or BT_CSIP_RELEASE_VALUE)
334 *
335 * @return BT_CSIP_ERROR_* on failure or 0 if success
336 */
set_lock(struct bt_conn * conn,struct bt_csip_set_member_svc_inst * svc_inst,uint8_t val)337 static uint8_t set_lock(struct bt_conn *conn,
338 struct bt_csip_set_member_svc_inst *svc_inst,
339 uint8_t val)
340 {
341 bool notify;
342
343 if (val != BT_CSIP_RELEASE_VALUE && val != BT_CSIP_LOCK_VALUE) {
344 return BT_CSIP_ERROR_LOCK_INVAL_VALUE;
345 }
346
347 if (svc_inst->set_lock == BT_CSIP_LOCK_VALUE) {
348 if (val == BT_CSIP_LOCK_VALUE) {
349 if (is_last_client_to_write(svc_inst, conn)) {
350 return BT_CSIP_ERROR_LOCK_ALREADY_GRANTED;
351 } else {
352 return BT_CSIP_ERROR_LOCK_DENIED;
353 }
354 } else if (!is_last_client_to_write(svc_inst, conn)) {
355 return BT_CSIP_ERROR_LOCK_RELEASE_DENIED;
356 }
357 }
358
359 notify = svc_inst->set_lock != val;
360
361 svc_inst->set_lock = val;
362 if (svc_inst->set_lock == BT_CSIP_LOCK_VALUE) {
363 if (conn != NULL) {
364 bt_addr_le_copy(&svc_inst->lock_client_addr,
365 bt_conn_get_dst(conn));
366 }
367 (void)k_work_reschedule(&svc_inst->set_lock_timer,
368 CSIP_SET_LOCK_TIMER_VALUE);
369 } else {
370 (void)memset(&svc_inst->lock_client_addr, 0,
371 sizeof(svc_inst->lock_client_addr));
372 (void)k_work_cancel_delayable(&svc_inst->set_lock_timer);
373 }
374
375 LOG_DBG("%u", svc_inst->set_lock);
376
377 if (notify) {
378 /*
379 * The Spec states that all clients, except for the
380 * client writing the value, shall be notified
381 * (if subscribed)
382 */
383 notify_clients(svc_inst, conn, FLAG_NOTIFY_LOCK);
384
385 if (svc_inst->cb != NULL && svc_inst->cb->lock_changed != NULL) {
386 bool locked = svc_inst->set_lock == BT_CSIP_LOCK_VALUE;
387
388 svc_inst->cb->lock_changed(conn, svc_inst, locked);
389 }
390 }
391
392 return 0;
393 }
394
write_set_lock(struct bt_conn * conn,const struct bt_gatt_attr * attr,const void * buf,uint16_t len,uint16_t offset,uint8_t flags)395 static ssize_t write_set_lock(struct bt_conn *conn,
396 const struct bt_gatt_attr *attr,
397 const void *buf, uint16_t len,
398 uint16_t offset, uint8_t flags)
399 {
400 ssize_t res;
401 uint8_t val;
402 struct bt_csip_set_member_svc_inst *svc_inst = BT_AUDIO_CHRC_USER_DATA(attr);
403
404 if (offset != 0) {
405 return BT_GATT_ERR(BT_ATT_ERR_INVALID_OFFSET);
406 } else if (len != sizeof(val)) {
407 return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
408 }
409
410 (void)memcpy(&val, buf, len);
411
412 res = set_lock(conn, svc_inst, val);
413 if (res != BT_ATT_ERR_SUCCESS) {
414 return BT_GATT_ERR(res);
415 }
416
417 return len;
418 }
419
set_lock_cfg_changed(const struct bt_gatt_attr * attr,uint16_t value)420 static void set_lock_cfg_changed(const struct bt_gatt_attr *attr,
421 uint16_t value)
422 {
423 LOG_DBG("value 0x%04x", value);
424 }
425
read_rank(struct bt_conn * conn,const struct bt_gatt_attr * attr,void * buf,uint16_t len,uint16_t offset)426 static ssize_t read_rank(struct bt_conn *conn, const struct bt_gatt_attr *attr,
427 void *buf, uint16_t len, uint16_t offset)
428 {
429 struct bt_csip_set_member_svc_inst *svc_inst = BT_AUDIO_CHRC_USER_DATA(attr);
430
431 LOG_DBG("%u", svc_inst->rank);
432
433 return bt_gatt_attr_read(conn, attr, buf, len, offset,
434 &svc_inst->rank,
435 sizeof(svc_inst->rank));
436
437 }
438
set_lock_timer_handler(struct k_work * work)439 static void set_lock_timer_handler(struct k_work *work)
440 {
441 struct k_work_delayable *delayable;
442 struct bt_csip_set_member_svc_inst *svc_inst;
443
444 delayable = k_work_delayable_from_work(work);
445 svc_inst = CONTAINER_OF(delayable, struct bt_csip_set_member_svc_inst,
446 set_lock_timer);
447
448 LOG_DBG("Lock timeout, releasing");
449 svc_inst->set_lock = BT_CSIP_RELEASE_VALUE;
450 notify_clients(svc_inst, NULL, FLAG_NOTIFY_LOCK);
451
452 if (svc_inst->cb != NULL && svc_inst->cb->lock_changed != NULL) {
453 bool locked = svc_inst->set_lock == BT_CSIP_LOCK_VALUE;
454
455 svc_inst->cb->lock_changed(NULL, svc_inst, locked);
456 }
457 }
458
csip_security_changed(struct bt_conn * conn,bt_security_t level,enum bt_security_err err)459 static void csip_security_changed(struct bt_conn *conn, bt_security_t level,
460 enum bt_security_err err)
461 {
462 if (err != 0 || conn->encrypt == 0) {
463 return;
464 }
465
466 if (!bt_le_bond_exists(conn->id, &conn->le.dst)) {
467 return;
468 }
469
470 for (size_t i = 0U; i < ARRAY_SIZE(svc_insts); i++) {
471 struct bt_csip_set_member_svc_inst *svc_inst = &svc_insts[i];
472
473 for (size_t j = 0U; j < ARRAY_SIZE(svc_inst->clients); j++) {
474 struct csip_client *client;
475
476 client = &svc_inst->clients[i];
477
478 if (atomic_test_bit(client->flags, FLAG_NOTIFY_LOCK) &&
479 bt_addr_le_eq(bt_conn_get_dst(conn), &client->addr)) {
480 notify_work_reschedule(K_NO_WAIT);
481 break;
482 }
483 }
484 }
485 }
486
handle_csip_disconnect(struct bt_csip_set_member_svc_inst * svc_inst,struct bt_conn * conn)487 static void handle_csip_disconnect(struct bt_csip_set_member_svc_inst *svc_inst,
488 struct bt_conn *conn)
489 {
490 LOG_DBG("Non-bonded device");
491 if (is_last_client_to_write(svc_inst, conn)) {
492 (void)memset(&svc_inst->lock_client_addr, 0,
493 sizeof(svc_inst->lock_client_addr));
494 svc_inst->set_lock = BT_CSIP_RELEASE_VALUE;
495 notify_clients(svc_inst, NULL, FLAG_NOTIFY_LOCK);
496
497 if (svc_inst->cb != NULL && svc_inst->cb->lock_changed != NULL) {
498 bool locked = svc_inst->set_lock == BT_CSIP_LOCK_VALUE;
499
500 svc_inst->cb->lock_changed(conn, svc_inst, locked);
501 }
502 }
503
504 /* Check if the disconnected device once was bonded and stored
505 * here as a bonded device
506 */
507 for (size_t i = 0U; i < ARRAY_SIZE(svc_inst->clients); i++) {
508 struct csip_client *client;
509
510 client = &svc_inst->clients[i];
511
512 if (bt_addr_le_eq(bt_conn_get_dst(conn), &client->addr)) {
513 (void)memset(client, 0, sizeof(*client));
514 break;
515 }
516 }
517 }
518
csip_disconnected(struct bt_conn * conn,uint8_t reason)519 static void csip_disconnected(struct bt_conn *conn, uint8_t reason)
520 {
521 LOG_DBG("Disconnected: %s (reason %u)", bt_addr_le_str(bt_conn_get_dst(conn)), reason);
522
523 if (!bt_le_bond_exists(conn->id, &conn->le.dst)) {
524 for (size_t i = 0U; i < ARRAY_SIZE(svc_insts); i++) {
525 handle_csip_disconnect(&svc_insts[i], conn);
526 }
527 }
528 }
529
handle_csip_auth_complete(struct bt_csip_set_member_svc_inst * svc_inst,struct bt_conn * conn)530 static void handle_csip_auth_complete(struct bt_csip_set_member_svc_inst *svc_inst,
531 struct bt_conn *conn)
532 {
533 /* Check if already in list, and do nothing if it is */
534 for (size_t i = 0U; i < ARRAY_SIZE(svc_inst->clients); i++) {
535 struct csip_client *client;
536
537 client = &svc_inst->clients[i];
538
539 if (atomic_test_bit(client->flags, FLAG_ACTIVE) &&
540 bt_addr_le_eq(bt_conn_get_dst(conn), &client->addr)) {
541 return;
542 }
543 }
544
545 /* Else add the device */
546 for (size_t i = 0U; i < ARRAY_SIZE(svc_inst->clients); i++) {
547 struct csip_client *client;
548
549 client = &svc_inst->clients[i];
550
551 if (!atomic_test_bit(client->flags, FLAG_ACTIVE)) {
552 atomic_set_bit(client->flags, FLAG_ACTIVE);
553 memcpy(&client->addr, bt_conn_get_dst(conn), sizeof(bt_addr_le_t));
554
555 /* Send out all pending notifications */
556 notify_work_reschedule(K_NO_WAIT);
557 return;
558 }
559 }
560
561 LOG_WRN("Could not add device to pending notification list");
562 }
563
auth_pairing_complete(struct bt_conn * conn,bool bonded)564 static void auth_pairing_complete(struct bt_conn *conn, bool bonded)
565 {
566 /**
567 * If a pairing is complete for a bonded device, then we
568 * 1) Store the connection pointer to later validate SIRK encryption
569 * 2) Check if the device is already in the `clients`, and if it is
570 * not, then we
571 * 3) Check if there's room for another device in the `clients`
572 * array. If there are no more room for a new device, then
573 * 4) Either we ignore this new device (bad luck), or we overwrite
574 * the oldest entry, following the behavior of the key storage.
575 */
576
577 LOG_DBG("%s paired (%sbonded)", bt_addr_le_str(bt_conn_get_dst(conn)),
578 bonded ? "" : "not ");
579
580 if (!bonded) {
581 return;
582 }
583
584 for (size_t i = 0U; i < ARRAY_SIZE(svc_insts); i++) {
585 handle_csip_auth_complete(&svc_insts[i], conn);
586 }
587 }
588
csip_bond_deleted(uint8_t id,const bt_addr_le_t * peer)589 static void csip_bond_deleted(uint8_t id, const bt_addr_le_t *peer)
590 {
591 for (size_t i = 0U; i < ARRAY_SIZE(svc_insts); i++) {
592 struct bt_csip_set_member_svc_inst *svc_inst = &svc_insts[i];
593
594 for (size_t j = 0U; j < ARRAY_SIZE(svc_inst->clients); j++) {
595
596 /* Check if match, and if active, if so, reset */
597 if (atomic_test_bit(svc_inst->clients[i].flags, FLAG_ACTIVE) &&
598 bt_addr_le_eq(peer, &svc_inst->clients[i].addr)) {
599 atomic_clear(svc_inst->clients[i].flags);
600 (void)memset(&svc_inst->clients[i].addr, 0, sizeof(bt_addr_le_t));
601 break;
602 }
603 }
604 }
605 }
606
607 static struct bt_conn_cb conn_callbacks = {
608 .disconnected = csip_disconnected,
609 .security_changed = csip_security_changed,
610 };
611
612 static struct bt_conn_auth_info_cb auth_callbacks = {
613 .pairing_complete = auth_pairing_complete,
614 .bond_deleted = csip_bond_deleted
615 };
616
617 #if defined(CONFIG_BT_CSIP_SET_MEMBER_SIRK_NOTIFIABLE)
618 #define BT_CSIS_CHR_SIRK(_csip) \
619 BT_AUDIO_CHRC(BT_UUID_CSIS_SIRK, BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, \
620 BT_GATT_PERM_READ_ENCRYPT, read_sirk, NULL, &_csip), \
621 BT_AUDIO_CCC(sirk_cfg_changed)
622 #else
623 #define BT_CSIS_CHR_SIRK(_csip) \
624 BT_AUDIO_CHRC(BT_UUID_CSIS_SIRK, BT_GATT_CHRC_READ, BT_GATT_PERM_READ_ENCRYPT, read_sirk, \
625 NULL, &_csip)
626 #endif /* CONFIG_BT_CSIP_SET_MEMBER_SIRK_NOTIFIABLE */
627
628 #define BT_CSIP_SERVICE_DEFINITION(_csip) {\
629 BT_GATT_PRIMARY_SERVICE(BT_UUID_CSIS), \
630 BT_CSIS_CHR_SIRK(_csip), \
631 BT_AUDIO_CHRC(BT_UUID_CSIS_SET_SIZE, \
632 BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY, \
633 BT_GATT_PERM_READ_ENCRYPT, \
634 read_set_size, NULL, &_csip), \
635 BT_AUDIO_CCC(set_size_cfg_changed), \
636 BT_AUDIO_CHRC(BT_UUID_CSIS_SET_LOCK, \
637 BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY | BT_GATT_CHRC_WRITE, \
638 BT_GATT_PERM_READ_ENCRYPT | BT_GATT_PERM_WRITE_ENCRYPT, \
639 read_set_lock, write_set_lock, &_csip), \
640 BT_AUDIO_CCC(set_lock_cfg_changed), \
641 BT_AUDIO_CHRC(BT_UUID_CSIS_RANK, \
642 BT_GATT_CHRC_READ, \
643 BT_GATT_PERM_READ_ENCRYPT, \
644 read_rank, NULL, &_csip) \
645 }
646
647 BT_GATT_SERVICE_INSTANCE_DEFINE(csip_set_member_service_list, svc_insts,
648 CONFIG_BT_CSIP_SET_MEMBER_MAX_INSTANCE_COUNT,
649 BT_CSIP_SERVICE_DEFINITION);
650
651 /****************************** Public API ******************************/
bt_csip_set_member_svc_decl_get(const struct bt_csip_set_member_svc_inst * svc_inst)652 void *bt_csip_set_member_svc_decl_get(const struct bt_csip_set_member_svc_inst *svc_inst)
653 {
654 if (svc_inst == NULL || svc_inst->service_p == NULL) {
655 return NULL;
656 }
657
658 return svc_inst->service_p->attrs;
659 }
660
valid_register_param(const struct bt_csip_set_member_register_param * param)661 static bool valid_register_param(const struct bt_csip_set_member_register_param *param)
662 {
663 if (param->lockable && param->rank == 0) {
664 LOG_DBG("Rank cannot be 0 if service is lockable");
665 return false;
666 }
667
668 if (param->rank > 0 && param->set_size > 0 && param->rank > param->set_size) {
669 LOG_DBG("Invalid rank: %u (shall be less than or equal to set_size: %u)",
670 param->rank, param->set_size);
671 return false;
672 }
673
674 #if CONFIG_BT_CSIP_SET_MEMBER_MAX_INSTANCE_COUNT > 1
675 if (param->parent == NULL) {
676 LOG_DBG("Parent service not provided");
677 return false;
678 }
679 #endif /* CONFIG_BT_CSIP_SET_MEMBER_MAX_INSTANCE_COUNT > 1 */
680
681 return true;
682 }
683
remove_csis_char(const struct bt_uuid * uuid,struct bt_gatt_service * svc)684 static void remove_csis_char(const struct bt_uuid *uuid, struct bt_gatt_service *svc)
685 {
686 size_t attrs_to_rem;
687
688 /* Rank does not have any CCCD */
689 if (bt_uuid_cmp(uuid, BT_UUID_CSIS_RANK) == 0) {
690 attrs_to_rem = CSIS_RANK_CHAR_ATTR_COUNT;
691 } else {
692 attrs_to_rem = CSIS_CHAR_ATTR_COUNT;
693 }
694
695 /* Start at index 4 as the first 4 attributes are mandatory */
696 for (size_t i = 4U; i < svc->attr_count; i++) {
697 if (bt_uuid_cmp(svc->attrs[i].uuid, uuid) == 0) {
698 /* Remove the characteristic declaration, the characteristic value and
699 * potentially the CCCD. The value declaration will be a i - 1, the
700 * characteristic value at i and the CCCD is potentially at i + 1
701 */
702
703 /* We use attrs_to_rem to determine whether there is a CCCD after the
704 * characteristic value or not, which then determines if this is the last
705 * characteristic or not
706 */
707 if (i == (svc->attr_count - (attrs_to_rem - 1))) {
708 /* This is the last characteristic in the service: just decrement
709 * the attr_count by number of attributes to remove
710 * (CSIS_CHAR_ATTR_COUNT)
711 */
712 } else {
713 /* Move all following attributes attrs_to_rem locations "up" */
714 for (size_t j = i - 1U; j < svc->attr_count - attrs_to_rem; j++) {
715 svc->attrs[j] = svc->attrs[j + attrs_to_rem];
716 }
717 }
718
719 svc->attr_count -= attrs_to_rem;
720
721 return;
722 }
723 }
724
725 __ASSERT(false, "Failed to remove CSIS char %s", bt_uuid_str(uuid));
726 }
727
notify(struct bt_csip_set_member_svc_inst * svc_inst,struct bt_conn * conn,const struct bt_uuid * uuid,const void * data,uint16_t len)728 static void notify(struct bt_csip_set_member_svc_inst *svc_inst, struct bt_conn *conn,
729 const struct bt_uuid *uuid, const void *data, uint16_t len)
730 {
731 int err;
732
733 if (svc_inst->service_p == NULL) {
734 return;
735 }
736
737 err = bt_gatt_notify_uuid(conn, uuid, svc_inst->service_p->attrs, data, len);
738 if (err) {
739 if (err == -ENOTCONN) {
740 LOG_DBG("Notification error: ENOTCONN (%d)", err);
741 } else {
742 LOG_ERR("Notification error: %d", err);
743 }
744 }
745 }
746
notify_cb(struct bt_conn * conn,void * data)747 static void notify_cb(struct bt_conn *conn, void *data)
748 {
749 struct bt_conn_info info;
750 int err = 0;
751
752 err = bt_conn_get_info(conn, &info);
753 if (err != 0) {
754 return;
755 }
756
757 if (info.state != BT_CONN_STATE_CONNECTED) {
758 /* Not connected */
759 LOG_DBG("Not connected: %u", info.state);
760 return;
761 }
762
763 for (size_t i = 0U; i < ARRAY_SIZE(svc_insts); i++) {
764 struct bt_csip_set_member_svc_inst *svc_inst = &svc_insts[i];
765 struct csip_client *client = &svc_inst->clients[bt_conn_index(conn)];
766
767 if (atomic_test_and_clear_bit(client->flags, FLAG_NOTIFY_LOCK)) {
768 notify(svc_inst, conn, BT_UUID_CSIS_SET_LOCK, &svc_inst->set_lock,
769 sizeof(svc_inst->set_lock));
770 }
771
772 if (IS_ENABLED(CONFIG_BT_CSIP_SET_MEMBER_SIRK_NOTIFIABLE) &&
773 atomic_test_and_clear_bit(client->flags, FLAG_NOTIFY_SIRK)) {
774 notify(svc_inst, conn, BT_UUID_CSIS_SIRK, &svc_inst->sirk,
775 sizeof(svc_inst->sirk));
776 }
777 }
778 }
779
deferred_nfy_work_handler(struct k_work * work)780 static void deferred_nfy_work_handler(struct k_work *work)
781 {
782 bt_conn_foreach(BT_CONN_TYPE_LE, notify_cb, NULL);
783 }
784
add_bonded_addr_to_client_list(const struct bt_bond_info * info,void * data)785 static void add_bonded_addr_to_client_list(const struct bt_bond_info *info, void *data)
786 {
787
788 for (size_t i = 0U; i < ARRAY_SIZE(svc_insts); i++) {
789 struct bt_csip_set_member_svc_inst *svc_inst = &svc_insts[i];
790
791 for (size_t j = 1U; j < ARRAY_SIZE(svc_inst->clients); i++) {
792 /* Check if device is registered, it not, add it */
793 if (!atomic_test_bit(svc_inst->clients[j].flags, FLAG_ACTIVE)) {
794 char addr_str[BT_ADDR_LE_STR_LEN];
795
796 atomic_set_bit(svc_inst->clients[j].flags, FLAG_ACTIVE);
797 memcpy(&svc_inst->clients[j].addr, &info->addr,
798 sizeof(bt_addr_le_t));
799 bt_addr_le_to_str(&svc_inst->clients[j].addr, addr_str,
800 sizeof(addr_str));
801 LOG_DBG("Added %s to bonded list\n", addr_str);
802 return;
803 }
804 }
805 }
806 }
807
bt_csip_set_member_register(const struct bt_csip_set_member_register_param * param,struct bt_csip_set_member_svc_inst ** svc_inst)808 int bt_csip_set_member_register(const struct bt_csip_set_member_register_param *param,
809 struct bt_csip_set_member_svc_inst **svc_inst)
810 {
811 static bool first_register;
812 static uint8_t instance_cnt;
813 struct bt_csip_set_member_svc_inst *inst;
814 int err;
815
816 if (instance_cnt == ARRAY_SIZE(svc_insts)) {
817 LOG_DBG("Too many set member registrations");
818 return -ENOMEM;
819 }
820
821 CHECKIF(param == NULL) {
822 LOG_DBG("NULL param");
823 return -EINVAL;
824 }
825
826 CHECKIF(!valid_register_param(param)) {
827 LOG_DBG("Invalid parameters");
828 return -EINVAL;
829 }
830
831 inst = &svc_insts[instance_cnt];
832 inst->service_p = &csip_set_member_service_list[instance_cnt];
833 instance_cnt++;
834
835 if (!first_register) {
836 bt_conn_cb_register(&conn_callbacks);
837 bt_conn_auth_info_cb_register(&auth_callbacks);
838
839 /* Restore bonding list */
840 bt_foreach_bond(BT_ID_DEFAULT, add_bonded_addr_to_client_list, NULL);
841
842 first_register = true;
843 }
844
845 /* The removal of the optional characteristics should be done in reverse order of the order
846 * in BT_CSIP_SERVICE_DEFINITION, as that improves the performance of remove_csis_char,
847 * since it's easier to remove the last characteristic
848 */
849 if (param->rank == 0U) {
850 remove_csis_char(BT_UUID_CSIS_RANK, inst->service_p);
851 }
852
853 if (param->set_size == 0U) {
854 remove_csis_char(BT_UUID_CSIS_SET_SIZE, inst->service_p);
855 }
856
857 if (!param->lockable) {
858 remove_csis_char(BT_UUID_CSIS_SET_LOCK, inst->service_p);
859 }
860
861 err = bt_gatt_service_register(inst->service_p);
862 if (err != 0) {
863 LOG_DBG("CSIS service register failed: %d", err);
864 return err;
865 }
866
867 k_work_init_delayable(&inst->set_lock_timer,
868 set_lock_timer_handler);
869 inst->rank = param->rank;
870 inst->set_size = param->set_size;
871 inst->set_lock = BT_CSIP_RELEASE_VALUE;
872 inst->sirk.type = BT_CSIP_SIRK_TYPE_PLAIN;
873 inst->cb = param->cb;
874
875 if (IS_ENABLED(CONFIG_BT_CSIP_SET_MEMBER_TEST_SAMPLE_DATA)) {
876 uint8_t test_sirk[] = {
877 0xcd, 0xcc, 0x72, 0xdd, 0x86, 0x8c, 0xcd, 0xce,
878 0x22, 0xfd, 0xa1, 0x21, 0x09, 0x7d, 0x7d, 0x45,
879 };
880
881 (void)memcpy(inst->sirk.value, test_sirk, sizeof(test_sirk));
882 LOG_DBG("CSIP SIRK was overwritten by sample data SIRK");
883 } else {
884 (void)memcpy(inst->sirk.value, param->sirk, sizeof(inst->sirk.value));
885 }
886
887 *svc_inst = inst;
888 return 0;
889 }
890
bt_csip_set_member_unregister(struct bt_csip_set_member_svc_inst * svc_inst)891 int bt_csip_set_member_unregister(struct bt_csip_set_member_svc_inst *svc_inst)
892 {
893 int err;
894
895 CHECKIF(svc_inst == NULL) {
896 LOG_DBG("NULL svc_inst");
897 return -EINVAL;
898 }
899
900 err = bt_gatt_service_unregister(svc_inst->service_p);
901 if (err != 0) {
902 LOG_DBG("CSIS service unregister failed: %d", err);
903 return err;
904 }
905
906 (void)k_work_cancel_delayable(&svc_inst->set_lock_timer);
907 memset(svc_inst, 0, sizeof(*svc_inst));
908
909 return 0;
910 }
911
bt_csip_set_member_sirk(struct bt_csip_set_member_svc_inst * svc_inst,const uint8_t sirk[BT_CSIP_SIRK_SIZE])912 int bt_csip_set_member_sirk(struct bt_csip_set_member_svc_inst *svc_inst,
913 const uint8_t sirk[BT_CSIP_SIRK_SIZE])
914 {
915 CHECKIF(svc_inst == NULL) {
916 LOG_DBG("NULL svc_inst");
917 return -EINVAL;
918 }
919
920 CHECKIF(sirk == NULL) {
921 LOG_DBG("NULL SIRK");
922 return -EINVAL;
923 }
924
925 memcpy(svc_inst->sirk.value, sirk, BT_CSIP_SIRK_SIZE);
926
927 notify_clients(svc_inst, NULL, FLAG_NOTIFY_SIRK);
928
929 return 0;
930 }
931
bt_csip_set_member_get_sirk(struct bt_csip_set_member_svc_inst * svc_inst,uint8_t sirk[BT_CSIP_SIRK_SIZE])932 int bt_csip_set_member_get_sirk(struct bt_csip_set_member_svc_inst *svc_inst,
933 uint8_t sirk[BT_CSIP_SIRK_SIZE])
934 {
935 CHECKIF(svc_inst == NULL) {
936 LOG_DBG("NULL svc_inst");
937 return -EINVAL;
938 }
939
940 CHECKIF(sirk == NULL) {
941 LOG_DBG("NULL SIRK");
942 return -EINVAL;
943 }
944
945 memcpy(sirk, svc_inst->sirk.value, BT_CSIP_SIRK_SIZE);
946
947 return 0;
948 }
949
bt_csip_set_member_lock(struct bt_csip_set_member_svc_inst * svc_inst,bool lock,bool force)950 int bt_csip_set_member_lock(struct bt_csip_set_member_svc_inst *svc_inst,
951 bool lock, bool force)
952 {
953 uint8_t lock_val;
954 int err = 0;
955
956 if (lock) {
957 lock_val = BT_CSIP_LOCK_VALUE;
958 } else {
959 lock_val = BT_CSIP_RELEASE_VALUE;
960 }
961
962 if (!lock && force) {
963 svc_inst->set_lock = BT_CSIP_RELEASE_VALUE;
964 notify_clients(svc_inst, NULL, FLAG_NOTIFY_LOCK);
965
966 if (svc_inst->cb != NULL && svc_inst->cb->lock_changed != NULL) {
967 svc_inst->cb->lock_changed(NULL, &svc_insts[0], false);
968 }
969 } else {
970 err = set_lock(NULL, svc_inst, lock_val);
971 }
972
973 if (err < 0) {
974 return BT_GATT_ERR(err);
975 } else {
976 return 0;
977 }
978 }
979