Skip to content

Commit 52f089a

Browse files
Thalleykartben
authored andcommitted
Bluetooth: CSIP: Set member: Fix issue with re-registration
The bt_csip_set_member_register kept a counter that was not decreased when bt_csip_set_member_unregister was called. This meant that we could register and unregister CSIS, but we could not re-register once it had been unregistered. This commit fixes this by removing the counter and instead rely on the service instance state, which also requires restoring the original service definition, as well as adding a test that would have failed with the previous version. Signed-off-by: Emil Gydesen <[email protected]>
1 parent 287984f commit 52f089a

File tree

3 files changed

+101
-15
lines changed

3 files changed

+101
-15
lines changed

subsys/bluetooth/audio/csip_set_member.c

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
/*
44
* Copyright (c) 2019 Bose Corporation
5-
* Copyright (c) 2020-2022 Nordic Semiconductor ASA
5+
* Copyright (c) 2020-2025 Nordic Semiconductor ASA
66
*
77
* SPDX-License-Identifier: Apache-2.0
88
*/
@@ -909,15 +909,9 @@ int bt_csip_set_member_register(const struct bt_csip_set_member_register_param *
909909
struct bt_csip_set_member_svc_inst **svc_inst)
910910
{
911911
static bool first_register;
912-
static uint8_t instance_cnt;
913912
struct bt_csip_set_member_svc_inst *inst;
914913
int err;
915914

916-
if (instance_cnt == ARRAY_SIZE(svc_insts)) {
917-
LOG_DBG("Too many set member registrations");
918-
return -ENOMEM;
919-
}
920-
921915
CHECKIF(param == NULL) {
922916
LOG_DBG("NULL param");
923917
return -EINVAL;
@@ -937,15 +931,26 @@ int bt_csip_set_member_register(const struct bt_csip_set_member_register_param *
937931
first_register = true;
938932
}
939933

940-
inst = &svc_insts[instance_cnt];
934+
inst = NULL;
935+
ARRAY_FOR_EACH(svc_insts, i) {
936+
if (svc_insts[i].service_p == NULL) {
937+
inst = &svc_insts[i];
941938

942-
err = k_mutex_lock(&inst->mutex, K_NO_WAIT);
943-
if (err != 0) {
944-
LOG_DBG("Failed to lock mutex: %d", err);
945-
return -EBUSY;
939+
err = k_mutex_lock(&inst->mutex, K_NO_WAIT);
940+
if (err != 0) {
941+
/* Try the next */
942+
continue;
943+
}
944+
945+
inst->service_p = &csip_set_member_service_list[i];
946+
break;
947+
}
946948
}
947949

948-
inst->service_p = &csip_set_member_service_list[instance_cnt];
950+
if (inst == NULL) {
951+
LOG_DBG("Too many set member registrations");
952+
return -ENOMEM;
953+
}
949954

950955
/* The removal of the optional characteristics should be done in reverse order of the order
951956
* in BT_CSIP_SERVICE_DEFINITION, as that improves the performance of remove_csis_char,
@@ -973,7 +978,6 @@ int bt_csip_set_member_register(const struct bt_csip_set_member_register_param *
973978
return err;
974979
}
975980

976-
instance_cnt++;
977981
k_work_init_delayable(&inst->set_lock_timer,
978982
set_lock_timer_handler);
979983
inst->rank = param->rank;
@@ -1030,6 +1034,16 @@ int bt_csip_set_member_unregister(struct bt_csip_set_member_svc_inst *svc_inst)
10301034
return err;
10311035
}
10321036

1037+
/* Restore original declaration */
1038+
1039+
/* attrs_0 is an array of the original attributes, and while the actual number of attributes
1040+
* may change, the size of the array stays the same, so we can use that to restore the
1041+
* original attribute count
1042+
*/
1043+
(void)memcpy(svc_inst->service_p->attrs,
1044+
(struct bt_gatt_attr[])BT_CSIP_SERVICE_DEFINITION(svc_inst), sizeof(attrs_0));
1045+
svc_inst->service_p->attr_count = ARRAY_SIZE(attrs_0);
1046+
10331047
(void)k_work_cancel_delayable(&svc_inst->set_lock_timer);
10341048

10351049
memset(svc_inst, 0, offsetof(struct bt_csip_set_member_svc_inst, mutex));

tests/bsim/bluetooth/audio/src/csip_set_member_test.c

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
22
* Copyright (c) 2019 Bose Corporation
3-
* Copyright (c) 2020-2024 Nordic Semiconductor ASA
3+
* Copyright (c) 2020-2025 Nordic Semiconductor ASA
44
*
55
* SPDX-License-Identifier: Apache-2.0
66
*/
@@ -16,6 +16,7 @@
1616
#include <zephyr/sys/printk.h>
1717
#include <zephyr/sys/util.h>
1818

19+
#include "bs_tracing.h"
1920
#include "bstests.h"
2021
#include "common.h"
2122
#ifdef CONFIG_BT_CSIP_SET_MEMBER
@@ -288,6 +289,46 @@ static void test_new_set_size_and_rank(void)
288289
PASS("CSIP Set member passed: Client successfully disconnected\n");
289290
}
290291

292+
static void test_register(void)
293+
{
294+
for (size_t iteration = 1; iteration <= 5; iteration++) {
295+
struct bt_csip_set_member_svc_inst
296+
*svc_insts[CONFIG_BT_CSIP_SET_MEMBER_MAX_INSTANCE_COUNT];
297+
int err;
298+
299+
printk("Running iteration %zu\n", iteration);
300+
301+
ARRAY_FOR_EACH(svc_insts, i) {
302+
err = bt_csip_set_member_register(&param, &svc_insts[i]);
303+
if (err != 0) {
304+
FAIL("[%zu]: Could not register CSIS (err %d)\n", i, err);
305+
return;
306+
}
307+
}
308+
309+
err = bt_csip_set_member_register(&param, &svc_inst);
310+
if (err == 0) {
311+
FAIL("Registered more CSIS than expected\n");
312+
return;
313+
}
314+
315+
ARRAY_FOR_EACH(svc_insts, i) {
316+
err = bt_csip_set_member_unregister(svc_insts[i]);
317+
if (err != 0) {
318+
FAIL("[%zu]: Could not unregister CSIS (err %d)\n", i, err);
319+
return;
320+
}
321+
svc_insts[i] = NULL;
322+
}
323+
}
324+
325+
PASS("CSIP Set member register passed\n");
326+
/* We can terminate the test immediately here as there is no peer devices we keep
327+
* communicating with.
328+
*/
329+
bs_trace_silent_exit(0);
330+
}
331+
291332
static void test_args(int argc, char *argv[])
292333
{
293334
for (size_t argn = 0; argn < argc; argn++) {
@@ -352,6 +393,13 @@ static const struct bst_test_instance test_connect[] = {
352393
.test_main_f = test_new_set_size_and_rank,
353394
.test_args_f = test_args,
354395
},
396+
{
397+
.test_id = "csip_set_member_register",
398+
.test_pre_init_f = test_init,
399+
.test_tick_f = test_tick,
400+
.test_main_f = test_register,
401+
.test_args_f = test_args,
402+
},
355403
BSTEST_END_MARKER,
356404
};
357405

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#!/usr/bin/env bash
2+
#
3+
# Copyright (c) 2025 Nordic Semiconductor ASA
4+
#
5+
# SPDX-License-Identifier: Apache-2.0
6+
7+
source ${ZEPHYR_BASE}/tests/bsim/sh_common.source
8+
9+
VERBOSITY_LEVEL=2
10+
EXECUTE_TIMEOUT=30
11+
12+
cd ${BSIM_OUT_PATH}/bin
13+
14+
SIMULATION_ID="csip_register"
15+
16+
Execute ./bs_${BOARD_TS}_tests_bsim_bluetooth_audio_prj_conf \
17+
-v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=0 -testid=csip_set_member_register \
18+
-RealEncryption=1 -rs=20 -D=1 -argstest rank 1 size 2
19+
20+
# Simulation time should be larger than the WAIT_TIME in common.h
21+
Execute ./bs_2G4_phy_v1 -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} \
22+
-D=1 -sim_length=1e6 $@
23+
24+
wait_for_background_jobs

0 commit comments

Comments
 (0)