Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 327a895

Browse files
committedMar 20, 2025·
Bluetooth: CSIP: Add support for dynamically setting set size
The set size can now be dynamically set and notified. The rank is added as a argument in the case that changing the set size, also affects the device's rank, as ranks in a coordinated set needs to be continuous. The set coordinator implementation has been updated to support receiving the new set size, and providing this information to the upper layers. This commit adds a babblesim test for the new API, as well as a shell command. Signed-off-by: Emil Gydesen <emil.gydesen@nordicsemi.no>
1 parent 25f3de7 commit 327a895

20 files changed

+513
-63
lines changed
 

‎doc/connectivity/bluetooth/shell/audio/csip.rst

+36-15
Original file line numberDiff line numberDiff line change
@@ -144,15 +144,18 @@ Using the Set Member
144144
145145
csip_set_member --help
146146
csip_set_member - Bluetooth CSIP set member shell commands
147-
Subcommands:
148-
register :Initialize the service and register callbacks [size <int>]
149-
[rank <int>] [not-lockable] [sirk <data>]
150-
lock :Lock the set
151-
release :Release the set [force]
152-
sirk :Set the currently used SIRK <sirk>
153-
get_sirk :Get the currently used SIRK
154-
sirk_rsp :Set the response used in SIRK requests <accept, accept_enc,
155-
reject, oob>
147+
Subcommands:
148+
register : Initialize the service and register callbacks [size
149+
<int>] [rank <int>] [not-lockable] [sirk <data>]
150+
lock : Lock the set
151+
release : Release the set [force]
152+
sirk : Set the currently used SIRK <sirk>
153+
set_size_and_rank : Set the currently used size and rank <size> <rank>
154+
get_info : Get service info
155+
sirk_rsp : Set the response used in SIRK requests <accept,
156+
accept_enc, reject, oob>
157+
158+
156159
157160
Example Usage
158161
=============
@@ -179,14 +182,32 @@ clients.
179182
uart:~$ csip_set_member sirk 00112233445566778899aabbccddeeff
180183
SIRK updated
181184
182-
Getting the current SIRK
185+
Setting a new set size and rank
186+
-------------------------------
187+
188+
This command can modify the set size and rank of a service instance.
189+
This shall be done for all device in the set at the same time,
190+
and all devices shall have the same set size.
191+
The rank will be ignored if the set is not lockable, else the rank shall be <= the set size,
192+
and shall be unique for this device in the set.
193+
194+
.. code-block:: console
195+
196+
uart:~$ csip_set_member set_size_and_rank 1 1
197+
Set size and rank updated to 1 and 1
198+
199+
Getting the current info
183200
------------------------
184201

185-
This command can get the currently used SIRK.
202+
This command can get the currently used set info.
186203

187204
.. code-block:: console
188205
189-
uart:~$ csip_set_member get_sirk
190-
SIRK
191-
36 04 9a dc 66 3a a1 a1 |6...f:..
192-
1d 9a 2f 41 01 73 3e 01 |../A.s>.
206+
uart:~$ csip_set_member get_info
207+
Info for 0x2003b0c8
208+
SIRK
209+
00000000: 20 37 0a 00 95 c4 04 20 00 00 00 00 f1 79 09 00 | 7..... .....y..|
210+
Set size: 2
211+
Rank: 1
212+
Lockable: true
213+
Locked: false

‎doc/releases/release-notes-4.2.rst

+2
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,8 @@ New APIs and options
8080
* :c:macro:`BT_BAP_ADV_PARAM_BROADCAST_SLOW`
8181
* :c:macro:`BT_BAP_PER_ADV_PARAM_BROADCAST_FAST`
8282
* :c:macro:`BT_BAP_PER_ADV_PARAM_BROADCAST_SLOW`
83+
* :c:func:`bt_csip_set_member_set_size_and_rank`
84+
* :c:func:`bt_csip_set_member_get_info`
8385

8486
* Host
8587

‎include/zephyr/bluetooth/audio/csip.h

+85
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include <stdint.h>
3333

3434
#include <zephyr/autoconf.h>
35+
#include <zephyr/bluetooth/addr.h>
3536
#include <zephyr/bluetooth/bluetooth.h>
3637
#include <zephyr/bluetooth/conn.h>
3738
#include <zephyr/bluetooth/gap.h>
@@ -237,6 +238,70 @@ int bt_csip_set_member_sirk(struct bt_csip_set_member_svc_inst *svc_inst,
237238
int bt_csip_set_member_get_sirk(struct bt_csip_set_member_svc_inst *svc_inst,
238239
uint8_t sirk[BT_CSIP_SIRK_SIZE]);
239240

241+
/**
242+
* @brief Set a new size and rank for a service instance
243+
*
244+
* This function can be used to dynamically change the size and rank of a service instance.
245+
* It is important to note that a set cannot have multiple devices with the same rank in a set,
246+
* and it is up to the caller of this function to ensure that.
247+
* Similarly, it is important that the size is updated on all devices in the set at the same time.
248+
*
249+
* If @kconfig{CONFIG_BT_CSIP_SET_MEMBER_SIZE_NOTIFIABLE} is enabled, this will also send a
250+
* notification to all connected or bonded clients.
251+
*
252+
* @param svc_inst The service instance.
253+
* @param size The new set size.
254+
* @param rank The new rank. Ignored if the @p svc_inst is not lockable.
255+
*
256+
* @retval -EINVAL @p svc_inst is NULL, @p size is less than 1, @p rank is less than 1 or higher
257+
* than @p size for a lockable @p svc_inst.
258+
* @retval -EALREADY @p size and @p rank are already the provided values.
259+
* @retval 0 Success.
260+
*/
261+
int bt_csip_set_member_set_size_and_rank(struct bt_csip_set_member_svc_inst *svc_inst, uint8_t size,
262+
uint8_t rank);
263+
264+
/** Struct to hold information about a service instance */
265+
struct bt_csip_set_member_set_info {
266+
/** The 16-octet SIRK */
267+
uint8_t sirk[BT_CSIP_SIRK_SIZE];
268+
269+
/** The set size */
270+
uint8_t set_size;
271+
272+
/**
273+
* @brief The rank
274+
*
275+
* May be 0 if the set is not lockable
276+
*/
277+
uint8_t rank;
278+
279+
/** Whether the set is lockable */
280+
bool lockable: 1;
281+
282+
/** Whether the set is currently locked */
283+
bool locked: 1;
284+
285+
/**
286+
* @brief The address of the client that currently holds the lock
287+
*
288+
* Will be @ref BT_ADDR_LE_NONE if the server holds the lock
289+
*/
290+
bt_addr_le_t lock_client_addr;
291+
};
292+
293+
/**
294+
* @brief Get information about a service instances
295+
*
296+
* @param svc_inst The service instance.
297+
* @param info Pointer to a struct to store the information in.
298+
*
299+
* @retval -EINVAL @p svc_inst or @p info is NULL.
300+
* @retval 0 Success.
301+
*/
302+
int bt_csip_set_member_get_info(const struct bt_csip_set_member_svc_inst *svc_inst,
303+
struct bt_csip_set_member_set_info *info);
304+
240305
/**
241306
* @brief Generate the Resolvable Set Identifier (RSI) value.
242307
*
@@ -382,6 +447,24 @@ typedef void (*bt_csip_set_coordinator_lock_changed_cb)(
382447
typedef void (*bt_csip_set_coordinator_sirk_changed_cb)(
383448
struct bt_csip_set_coordinator_csis_inst *inst);
384449

450+
/**
451+
* @typedef bt_csip_set_coordinator_size_changed_cb
452+
* @brief Callback when the size of a set of a connected device changes.
453+
*
454+
* Since all devices in a set shall have the same set size value.
455+
* Each connected device may send the same new size set in a notification,
456+
* assuming that the remote device supports notifications of the set size.
457+
*
458+
* The rank of each device in the set may also change as part of this, so it is advisable to call
459+
* bt_csip_set_coordinator_discover() to rediscover and read the characteristic values of the sets
460+
* on each device.
461+
*
462+
* @param inst The Coordinated Set Identification Service instance that was changed.
463+
* The new size is stored in the @p inst->info.size.
464+
*/
465+
typedef void (*bt_csip_set_coordinator_size_changed_cb)(
466+
struct bt_conn *conn, const struct bt_csip_set_coordinator_csis_inst *inst);
467+
385468
/**
386469
* @typedef bt_csip_set_coordinator_ordered_access_cb_t
387470
* @brief Callback for bt_csip_set_coordinator_ordered_access()
@@ -417,6 +500,8 @@ struct bt_csip_set_coordinator_cb {
417500
bt_csip_set_coordinator_lock_changed_cb lock_changed;
418501
/** Callback when a set's SIRK has changed */
419502
bt_csip_set_coordinator_sirk_changed_cb sirk_changed;
503+
/** Callback when a set's size has changed */
504+
bt_csip_set_coordinator_size_changed_cb size_changed;
420505
/** Callback for the ordered access procedure */
421506
bt_csip_set_coordinator_ordered_access_cb_t ordered_access;
422507

‎subsys/bluetooth/audio/Kconfig.csip

+5
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,11 @@ config BT_CSIP_SET_MEMBER_SIRK_NOTIFIABLE
5353
help
5454
This option enables support for clients to be notified on SIRK changes.
5555

56+
config BT_CSIP_SET_MEMBER_SIZE_NOTIFIABLE
57+
bool "Set Size notifiable support"
58+
help
59+
This option enables support for clients to be notified on Set Size changes.
60+
5661
endif # BT_CSIP_SET_MEMBER
5762

5863
#################### Coordinated Set Identification Client ####################

‎subsys/bluetooth/audio/csip_set_coordinator.c

+16-3
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,17 @@ static void sirk_changed(struct bt_csip_set_coordinator_csis_inst *inst)
312312
}
313313
}
314314

315+
static void size_changed(struct bt_conn *conn, struct bt_csip_set_coordinator_csis_inst *inst)
316+
{
317+
struct bt_csip_set_coordinator_cb *listener;
318+
319+
SYS_SLIST_FOR_EACH_CONTAINER(&csip_set_coordinator_cbs, listener, _node) {
320+
if (listener->size_changed != NULL) {
321+
listener->size_changed(conn, inst);
322+
}
323+
}
324+
}
325+
315326
static void release_set_complete(int err)
316327
{
317328
struct bt_csip_set_coordinator_cb *listener;
@@ -468,17 +479,19 @@ static uint8_t size_notify_func(struct bt_conn *conn,
468479

469480
if (svc_inst != NULL) {
470481
if (length == sizeof(set_size)) {
471-
struct bt_csip_set_coordinator_inst *client;
472482
struct bt_csip_set_coordinator_set_info *set_info;
483+
struct bt_csip_set_coordinator_csis_inst *inst;
484+
struct bt_csip_set_coordinator_inst *client;
473485

474486
client = &client_insts[bt_conn_index(conn)];
475-
set_info = &client->set_member.insts[svc_inst->idx].info;
487+
inst = &client->set_member.insts[svc_inst->idx];
488+
set_info = &inst->info;
476489

477490
(void)memcpy(&set_size, data, length);
478491
LOG_DBG("Set size updated from %u to %u", set_info->set_size, set_size);
479492

480493
set_info->set_size = set_size;
481-
/* TODO: Notify app */
494+
size_changed(conn, inst);
482495
} else {
483496
LOG_DBG("Invalid length %u", length);
484497
}

0 commit comments

Comments
 (0)
Please sign in to comment.