Skip to content

Commit c0cfe49

Browse files
babrsnnashif
authored andcommitted
Bluetooth: BASS: Add support for dynamic registration of BASS
Added support for dynamic registration and unregistration of the Broadcast Audio Scan Service (BASS) within the scan delegator. This enables both scan delegator and BASS to be registered or unregistered dynamically at runtime. Signed-off-by: Babak Arisian <[email protected]>
1 parent 38fb12f commit c0cfe49

File tree

11 files changed

+174
-23
lines changed

11 files changed

+174
-23
lines changed

doc/releases/migration-guide-4.0.rst

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,17 @@ Bluetooth Audio
288288
is enabled and that all members are bonded, to comply with the requirements from the CSIP spec.
289289
(:github:`78877`)
290290

291+
* The Broadcast Audio Scan Service (BASS) shall now be registered and unregistered dynamically
292+
at runtime within the scan delegator. Two new APIs, :c:func:`bt_bap_scan_delegator_register()`
293+
and :c:func:`bt_bap_scan_delegator_unregister()`, have been introduced to manage both BASS and
294+
scan delegator registration and initialization dynamically. It should also be mentioned that
295+
the previous callback registration function, :c:func:`bt_bap_scan_delegator_register_cb()` has
296+
now been removed and merged with :c:func:`bt_bap_scan_delegator_register()`.
297+
This change allows more flexibility when registering or unregistering scan delegator and BASS
298+
related functionality without requiring build-time configuration. Existing need to be updated
299+
to use these new APIs.
300+
(:github:`78751`)
301+
291302
Bluetooth Classic
292303
=================
293304

include/zephyr/bluetooth/audio/bap.h

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -318,7 +318,7 @@ struct bt_bap_scan_delegator_recv_state {
318318
/**
319319
* @brief Struct to hold the Basic Audio Profile Scan Delegator callbacks
320320
*
321-
* These can be registered for usage with bt_bap_scan_delegator_register_cb().
321+
* These can be registered for usage with bt_bap_scan_delegator_register().
322322
*/
323323
struct bt_bap_scan_delegator_cb {
324324
/**
@@ -2048,14 +2048,29 @@ int bt_bap_broadcast_sink_delete(struct bt_bap_broadcast_sink *sink);
20482048
/** @} */ /* End of group bt_bap_broadcast_sink */
20492049

20502050
/**
2051-
* @brief Register the callbacks for the Basic Audio Profile Scan Delegator
2051+
* @brief Register the Basic Audio Profile Scan Delegator and BASS.
2052+
*
2053+
* Register the scan deligator and Broadcast Audio Scan Service (BASS)
2054+
* dynamically at runtime.
20522055
*
20532056
* Only one set of callbacks can be registered at any one time, and calling this function multiple
20542057
* times will override any previously registered callbacks.
20552058
*
20562059
* @param cb Pointer to the callback struct
2060+
*
2061+
* @return 0 in case of success or negative value in case of error.
2062+
*/
2063+
int bt_bap_scan_delegator_register(struct bt_bap_scan_delegator_cb *cb);
2064+
2065+
/**
2066+
* @brief unregister the Basic Audio Profile Scan Delegator and BASS.
2067+
*
2068+
* Unregister the scan deligator and Broadcast Audio Scan Service (BASS)
2069+
* dynamically at runtime.
2070+
*
2071+
* @return 0 in case of success or negative value in case of error.
20572072
*/
2058-
void bt_bap_scan_delegator_register_cb(struct bt_bap_scan_delegator_cb *cb);
2073+
int bt_bap_scan_delegator_unregister(void);
20592074

20602075
/**
20612076
* @brief Set the periodic advertising sync state to syncing

samples/bluetooth/bap_broadcast_sink/src/main.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1308,8 +1308,13 @@ static int init(void)
13081308
return err;
13091309
}
13101310

1311+
err = bt_bap_scan_delegator_register(&scan_delegator_cbs);
1312+
if (err) {
1313+
printk("Scan delegator register failed (err %d)\n", err);
1314+
return err;
1315+
}
1316+
13111317
bt_bap_broadcast_sink_register_cb(&broadcast_sink_cbs);
1312-
bt_bap_scan_delegator_register_cb(&scan_delegator_cbs);
13131318
bt_le_per_adv_sync_cb_register(&bap_pa_sync_cb);
13141319
bt_le_scan_cb_register(&bap_scan_cb);
13151320

samples/bluetooth/cap_acceptor/src/cap_acceptor_broadcast.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -731,6 +731,13 @@ int init_cap_acceptor_broadcast(void)
731731
.recv = broadcast_scan_recv,
732732
};
733733

734+
err = bt_bap_scan_delegator_register(&scan_delegator_cbs);
735+
if (err != 0) {
736+
LOG_ERR("Scan delegator register failed (err %d)", err);
737+
738+
return err;
739+
}
740+
734741
err = bt_bap_broadcast_sink_register_cb(&broadcast_sink_cbs);
735742
if (err != 0) {
736743
LOG_ERR("Failed to register BAP broadcast sink callbacks: %d", err);
@@ -739,7 +746,6 @@ int init_cap_acceptor_broadcast(void)
739746
}
740747

741748
bt_cap_stream_ops_register(&broadcast_sink.broadcast_stream, &broadcast_stream_ops);
742-
bt_bap_scan_delegator_register_cb(&scan_delegator_cbs);
743749
bt_le_per_adv_sync_cb_register(&bap_pa_sync_cb);
744750

745751
if (IS_ENABLED(CONFIG_SAMPLE_SCAN_SELF)) {

subsys/bluetooth/audio/Kconfig.bap

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,7 @@ config BT_BAP_SCAN_DELEGATOR
211211
select BT_EXT_ADV
212212
select BT_PER_ADV_SYNC
213213
select BT_ISO_SYNC_RECEIVER
214+
select BT_GATT_DYNAMIC_DB
214215
depends on BT_BONDABLE
215216
help
216217
This option enables support for the Scan Delegator role and the

subsys/bluetooth/audio/bap_scan_delegator.c

Lines changed: 95 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,16 @@ struct bt_bap_scan_delegator_inst {
8787
[CONFIG_BT_BAP_SCAN_DELEGATOR_RECV_STATE_COUNT];
8888
};
8989

90-
static bool conn_cb_registered;
90+
enum scan_delegator_flag {
91+
SCAN_DELEGATOR_FLAG_REGISTERED_CONN_CB,
92+
SCAN_DELEGATOR_FLAG_REGISTERED_SCAN_DELIGATOR,
93+
SCAN_DELEGATOR_FLAG_REGISTERED_PA_SYNC_CB,
94+
95+
SCAN_DELEGATOR_FLAG_NUM,
96+
};
97+
98+
static ATOMIC_DEFINE(scan_delegator_flags, SCAN_DELEGATOR_FLAG_NUM);
99+
91100
static struct bt_bap_scan_delegator_inst scan_delegator;
92101
static struct bt_bap_scan_delegator_cb *scan_delegator_cbs;
93102

@@ -325,9 +334,9 @@ static struct broadcast_assistant *get_bap_broadcast_assistant(struct bt_conn *c
325334
}
326335
}
327336

328-
if (!conn_cb_registered) {
337+
if (!atomic_test_and_set_bit(scan_delegator_flags,
338+
SCAN_DELEGATOR_FLAG_REGISTERED_CONN_CB)) {
329339
bt_conn_cb_register(&conn_cb);
330-
conn_cb_registered = true;
331340
}
332341

333342
return new;
@@ -1157,7 +1166,7 @@ static ssize_t read_recv_state(struct bt_conn *conn,
11571166
read_recv_state, NULL, UINT_TO_POINTER(idx)), \
11581167
BT_AUDIO_CCC(recv_state_cfg_changed)
11591168

1160-
BT_GATT_SERVICE_DEFINE(bass_svc,
1169+
static struct bt_gatt_attr attr_bass_svc[] = {
11611170
BT_GATT_PRIMARY_SERVICE(BT_UUID_BASS),
11621171
BT_AUDIO_CHRC(BT_UUID_BASS_CONTROL_POINT,
11631172
BT_GATT_CHRC_WRITE_WITHOUT_RESP | BT_GATT_CHRC_WRITE,
@@ -1170,10 +1179,58 @@ BT_GATT_SERVICE_DEFINE(bass_svc,
11701179
RECEIVE_STATE_CHARACTERISTIC(2)
11711180
#endif /* CONFIG_BT_BAP_SCAN_DELEGATOR_RECV_STATE_COUNT > 2 */
11721181
#endif /* CONFIG_BT_BAP_SCAN_DELEGATOR_RECV_STATE_COUNT > 1 */
1173-
);
1182+
};
1183+
1184+
static struct bt_gatt_service bass_svc = BT_GATT_SERVICE(attr_bass_svc);
1185+
1186+
static int bass_register(void)
1187+
{
1188+
int err;
1189+
1190+
err = bt_gatt_service_register(&bass_svc);
1191+
if (err) {
1192+
LOG_DBG("Failed to register BASS service (err %d)", err);
1193+
return err;
1194+
}
1195+
1196+
LOG_DBG("BASS service registered");
11741197

1175-
static int bt_bap_scan_delegator_init(void)
1198+
return 0;
1199+
}
1200+
1201+
static int bass_unregister(void)
11761202
{
1203+
int err;
1204+
1205+
err = bt_gatt_service_unregister(&bass_svc);
1206+
if (err) {
1207+
LOG_DBG("Failed to unregister BASS service (err %d)", err);
1208+
return err;
1209+
}
1210+
1211+
LOG_DBG("BASS service unregistered");
1212+
1213+
return 0;
1214+
}
1215+
1216+
/****************************** PUBLIC API ******************************/
1217+
int bt_bap_scan_delegator_register(struct bt_bap_scan_delegator_cb *cb)
1218+
{
1219+
int err;
1220+
1221+
if (atomic_test_and_set_bit(scan_delegator_flags,
1222+
SCAN_DELEGATOR_FLAG_REGISTERED_SCAN_DELIGATOR)) {
1223+
LOG_DBG("Scan delegator already registered");
1224+
return -EALREADY;
1225+
}
1226+
1227+
err = bass_register();
1228+
if (err) {
1229+
atomic_clear_bit(scan_delegator_flags,
1230+
SCAN_DELEGATOR_FLAG_REGISTERED_SCAN_DELIGATOR);
1231+
return err;
1232+
}
1233+
11771234
/* Store the pointer to the first characteristic in each receive state */
11781235
scan_delegator.recv_states[0].attr = &bass_svc.attrs[3];
11791236
scan_delegator.recv_states[0].index = 0;
@@ -1186,17 +1243,43 @@ static int bt_bap_scan_delegator_init(void)
11861243
#endif /* CONFIG_BT_BAP_SCAN_DELEGATOR_RECV_STATE_COUNT > 2 */
11871244
#endif /* CONFIG_BT_BAP_SCAN_DELEGATOR_RECV_STATE_COUNT > 1 */
11881245

1189-
bt_le_per_adv_sync_cb_register(&pa_sync_cb);
1246+
if (!atomic_test_and_set_bit(scan_delegator_flags,
1247+
SCAN_DELEGATOR_FLAG_REGISTERED_PA_SYNC_CB)) {
1248+
err = bt_le_per_adv_sync_cb_register(&pa_sync_cb);
1249+
if (err) {
1250+
atomic_clear_bit(scan_delegator_flags,
1251+
SCAN_DELEGATOR_FLAG_REGISTERED_PA_SYNC_CB);
1252+
atomic_clear_bit(scan_delegator_flags,
1253+
SCAN_DELEGATOR_FLAG_REGISTERED_SCAN_DELIGATOR);
1254+
return err;
1255+
}
1256+
}
1257+
1258+
scan_delegator_cbs = cb;
11901259

11911260
return 0;
11921261
}
11931262

1194-
SYS_INIT(bt_bap_scan_delegator_init, APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEVICE);
1195-
1196-
/****************************** PUBLIC API ******************************/
1197-
void bt_bap_scan_delegator_register_cb(struct bt_bap_scan_delegator_cb *cb)
1263+
int bt_bap_scan_delegator_unregister(void)
11981264
{
1199-
scan_delegator_cbs = cb;
1265+
int err;
1266+
1267+
if (!atomic_test_and_clear_bit(scan_delegator_flags,
1268+
SCAN_DELEGATOR_FLAG_REGISTERED_SCAN_DELIGATOR)) {
1269+
LOG_DBG("Scan delegator not yet registered");
1270+
return -EALREADY;
1271+
}
1272+
1273+
err = bass_unregister();
1274+
if (err) {
1275+
atomic_set_bit(scan_delegator_flags,
1276+
SCAN_DELEGATOR_FLAG_REGISTERED_SCAN_DELIGATOR);
1277+
return err;
1278+
}
1279+
1280+
scan_delegator_cbs = NULL;
1281+
1282+
return 0;
12001283
}
12011284

12021285
int bt_bap_scan_delegator_set_pa_state(uint8_t src_id,

subsys/bluetooth/audio/shell/bap_scan_delegator.c

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -436,8 +436,19 @@ static int cmd_bap_scan_delegator_init(const struct shell *sh, size_t argc,
436436
static bool registered;
437437

438438
if (!registered) {
439-
bt_le_per_adv_sync_cb_register(&pa_sync_cb);
440-
bt_bap_scan_delegator_register_cb(&scan_delegator_cb);
439+
int err;
440+
441+
err = bt_bap_scan_delegator_register(&scan_delegator_cb);
442+
if (err) {
443+
shell_error(sh, "Failed to register scan delegator (err: %d)", err);
444+
return -ENOEXEC;
445+
}
446+
447+
err = bt_le_per_adv_sync_cb_register(&pa_sync_cb);
448+
if (err) {
449+
shell_error(sh, "Failed to register PA sync callbacks (err: %d)", err);
450+
return -ENOEXEC;
451+
}
441452

442453
registered = true;
443454
}

tests/bluetooth/tester/src/audio/btp_bap_broadcast.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1033,7 +1033,10 @@ uint8_t btp_bap_broadcast_sink_setup(const void *cmd, uint16_t cmd_len,
10331033
}
10341034

10351035
/* For Scan Delegator role */
1036-
bt_bap_scan_delegator_register_cb(&scan_delegator_cbs);
1036+
err = bt_bap_scan_delegator_register(&scan_delegator_cbs);
1037+
if (err != 0) {
1038+
return BTP_STATUS_FAILED;
1039+
}
10371040

10381041
/* For Broadcast Sink role */
10391042
bt_bap_broadcast_sink_register_cb(&broadcast_sink_cbs);

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -642,6 +642,12 @@ static int init(void)
642642
return err;
643643
}
644644

645+
err = bt_bap_scan_delegator_register(&scan_delegator_cbs);
646+
if (err) {
647+
FAIL("Scan delegator register failed (err %d)\n", err);
648+
return err;
649+
}
650+
645651
/* Test invalid input */
646652
err = bt_bap_broadcast_sink_register_cb(NULL);
647653
if (err == 0) {
@@ -655,7 +661,6 @@ static int init(void)
655661
return err;
656662
}
657663

658-
bt_bap_scan_delegator_register_cb(&scan_delegator_cbs);
659664
bt_le_per_adv_sync_cb_register(&bap_pa_sync_cb);
660665
bt_le_scan_cb_register(&bap_scan_cb);
661666

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -685,7 +685,12 @@ static int common_init(void)
685685

686686
printk("Bluetooth initialized\n");
687687

688-
bt_bap_scan_delegator_register_cb(&scan_delegator_cb);
688+
err = bt_bap_scan_delegator_register(&scan_delegator_cb);
689+
if (err) {
690+
FAIL("Scan delegator register failed (err %d)\n", err);
691+
return err;
692+
}
693+
689694
bt_le_per_adv_sync_cb_register(&pa_sync_cb);
690695

691696
err = bt_le_adv_start(BT_LE_ADV_CONN_ONE_TIME, ad, AD_SIZE, NULL, 0);

0 commit comments

Comments
 (0)