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