Skip to content

Commit efe3d3e

Browse files
Thalleykoffes
authored andcommitted
[nrf fromtree] 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 <[email protected]> (cherry picked from commit d19abff)
1 parent bca63b6 commit efe3d3e

File tree

20 files changed

+513
-63
lines changed

20 files changed

+513
-63
lines changed

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

Lines changed: 36 additions & 15 deletions
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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@ New APIs and options
7676
* :c:macro:`BT_BAP_ADV_PARAM_BROADCAST_SLOW`
7777
* :c:macro:`BT_BAP_PER_ADV_PARAM_BROADCAST_FAST`
7878
* :c:macro:`BT_BAP_PER_ADV_PARAM_BROADCAST_SLOW`
79+
* :c:func:`bt_csip_set_member_set_size_and_rank`
80+
* :c:func:`bt_csip_set_member_get_info`
7981

8082
* Host
8183

include/zephyr/bluetooth/audio/csip.h

Lines changed: 85 additions & 0 deletions
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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,11 @@ config BT_CSIP_SET_MEMBER_SIRK_NOTIFIABLE
5151
help
5252
This option enables support for clients to be notified on SIRK changes.
5353

54+
config BT_CSIP_SET_MEMBER_SIZE_NOTIFIABLE
55+
bool "Set Size notifiable support"
56+
help
57+
This option enables support for clients to be notified on Set Size changes.
58+
5459
endif # BT_CSIP_SET_MEMBER
5560

5661
#################### Coordinated Set Identification Client ####################

subsys/bluetooth/audio/csip_set_coordinator.c

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,17 @@ static void sirk_changed(struct bt_csip_set_coordinator_csis_inst *inst)
317317
}
318318
}
319319

320+
static void size_changed(struct bt_conn *conn, struct bt_csip_set_coordinator_csis_inst *inst)
321+
{
322+
struct bt_csip_set_coordinator_cb *listener;
323+
324+
SYS_SLIST_FOR_EACH_CONTAINER(&csip_set_coordinator_cbs, listener, _node) {
325+
if (listener->size_changed != NULL) {
326+
listener->size_changed(conn, inst);
327+
}
328+
}
329+
}
330+
320331
static void release_set_complete(int err)
321332
{
322333
struct bt_csip_set_coordinator_cb *listener;
@@ -473,17 +484,19 @@ static uint8_t size_notify_func(struct bt_conn *conn,
473484

474485
if (svc_inst != NULL) {
475486
if (length == sizeof(set_size)) {
476-
struct bt_csip_set_coordinator_inst *client;
477487
struct bt_csip_set_coordinator_set_info *set_info;
488+
struct bt_csip_set_coordinator_csis_inst *inst;
489+
struct bt_csip_set_coordinator_inst *client;
478490

479491
client = &client_insts[bt_conn_index(conn)];
480-
set_info = &client->set_member.insts[svc_inst->idx].info;
492+
inst = &client->set_member.insts[svc_inst->idx];
493+
set_info = &inst->info;
481494

482495
(void)memcpy(&set_size, data, length);
483496
LOG_DBG("Set size updated from %u to %u", set_info->set_size, set_size);
484497

485498
set_info->set_size = set_size;
486-
/* TODO: Notify app */
499+
size_changed(conn, inst);
487500
} else {
488501
LOG_DBG("Invalid length %u", length);
489502
}

0 commit comments

Comments
 (0)