Skip to content

Commit b866b8b

Browse files
alexsvenrlubos
authored andcommitted
[nrf fromtree] bluetooth: audio: scan_delegator: Reject remove when PA synced
- BASS mandates that a remove_source operation is not done if we are synced to PA or BIS. This PR fixes that - Update BabbleSim tests to reflect this behavior - Fixes BASS/SR/SPE/BI-05-C Signed-off-by: Alexander Svensen <[email protected]> (cherry picked from commit 87997af)
1 parent 91d4f78 commit b866b8b

File tree

3 files changed

+102
-60
lines changed

3 files changed

+102
-60
lines changed

subsys/bluetooth/audio/bap_scan_delegator.c

Lines changed: 29 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1051,7 +1051,6 @@ static int scan_delegator_rem_src(struct bt_conn *conn,
10511051
{
10521052
struct bass_recv_state_internal *internal_state;
10531053
struct bt_bap_scan_delegator_recv_state *state;
1054-
bool bis_sync_was_requested = false;
10551054
uint8_t src_id;
10561055
int err;
10571056

@@ -1078,38 +1077,40 @@ static int scan_delegator_rem_src(struct bt_conn *conn,
10781077

10791078
state = &internal_state->state;
10801079

1081-
/* If conn == NULL then it's a local operation and we do not need to ask the application */
1082-
if (conn != NULL) {
1083-
1084-
if (scan_delegator_cbs != NULL && scan_delegator_cbs->remove_source != NULL) {
1085-
err = scan_delegator_cbs->remove_source(conn, src_id);
1086-
if (err != 0) {
1087-
LOG_DBG("Remove Source rejected with reason 0x%02x", err);
1088-
err = k_mutex_unlock(&internal_state->mutex);
1089-
__ASSERT(err == 0, "Failed to unlock mutex: %d", err);
1090-
return BT_GATT_ERR(BT_ATT_ERR_WRITE_REQ_REJECTED);
1091-
}
1092-
}
1093-
1094-
if (state->pa_sync_state == BT_BAP_PA_STATE_INFO_REQ ||
1095-
state->pa_sync_state == BT_BAP_PA_STATE_SYNCED) {
1096-
/* Terminate PA sync */
1097-
err = pa_sync_term_request(conn, &internal_state->state);
1098-
if (err != 0) {
1099-
LOG_DBG("PA sync term from %p was rejected with reason %d",
1100-
(void *)conn, err);
1101-
err = k_mutex_unlock(&internal_state->mutex);
1102-
__ASSERT(err == 0, "Failed to unlock mutex: %d", err);
1103-
return BT_GATT_ERR(BT_ATT_ERR_WRITE_REQ_REJECTED);
1104-
}
1105-
}
1080+
if (state->pa_sync_state == BT_BAP_PA_STATE_SYNCED) {
1081+
LOG_DBG("Cannot remove source ID 0x%02x while PA is synced", state->src_id);
1082+
err = k_mutex_unlock(&internal_state->mutex);
1083+
__ASSERT(err == 0, "Failed to unlock mutex: %d", err);
1084+
/* We shouldn't return a success here, but the Test Spec requires it at the moment,
1085+
* Errata to fix this: https://bluetooth.atlassian.net/browse/ES-28445
1086+
*/
1087+
return BT_GATT_ERR(BT_ATT_ERR_SUCCESS);
11061088
}
11071089

11081090
for (uint8_t i = 0U; i < state->num_subgroups; i++) {
11091091
if (internal_state->requested_bis_sync[i] != 0U &&
11101092
internal_state->state.subgroups[i].bis_sync != 0U) {
1111-
bis_sync_was_requested = true;
1112-
break;
1093+
LOG_DBG("Cannot remove source ID 0x%02x while BIS is synced",
1094+
state->src_id);
1095+
err = k_mutex_unlock(&internal_state->mutex);
1096+
__ASSERT(err == 0, "Failed to unlock mutex: %d", err);
1097+
/* We shouldn't return a success here, but the Test Spec requires it at the
1098+
* moment, Errata to fix this:
1099+
* https://bluetooth.atlassian.net/browse/ES-28445
1100+
*/
1101+
return BT_GATT_ERR(BT_ATT_ERR_SUCCESS);
1102+
}
1103+
}
1104+
1105+
/* If conn == NULL then it's a local operation and we do not need to ask the application */
1106+
if (conn != NULL && scan_delegator_cbs != NULL &&
1107+
scan_delegator_cbs->remove_source != NULL) {
1108+
err = scan_delegator_cbs->remove_source(conn, src_id);
1109+
if (err != 0) {
1110+
LOG_DBG("Remove Source rejected with reason 0x%02x", err);
1111+
err = k_mutex_unlock(&internal_state->mutex);
1112+
__ASSERT(err == 0, "Failed to unlock mutex: %d", err);
1113+
return BT_GATT_ERR(BT_ATT_ERR_WRITE_REQ_REJECTED);
11131114
}
11141115
}
11151116

@@ -1128,10 +1129,6 @@ static int scan_delegator_rem_src(struct bt_conn *conn,
11281129
err = k_mutex_unlock(&internal_state->mutex);
11291130
__ASSERT(err == 0, "Failed to unlock mutex: %d", err);
11301131

1131-
if (bis_sync_was_requested) {
1132-
bis_sync_request_updated(conn, internal_state);
1133-
}
1134-
11351132
/* app callback */
11361133
receive_state_updated(conn, internal_state);
11371134

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

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -502,7 +502,7 @@ static void test_bass_add_source(void)
502502
printk("Source added\n");
503503
}
504504

505-
static void test_bass_mod_source(uint32_t bis_sync)
505+
static void test_bass_mod_source(bool pa_sync, uint32_t bis_sync)
506506
{
507507
int err;
508508
struct bt_bap_broadcast_assistant_mod_src_param mod_src_param = { 0 };
@@ -515,7 +515,7 @@ static void test_bass_mod_source(uint32_t bis_sync)
515515
UNSET_FLAG(flag_recv_state_updated);
516516
mod_src_param.src_id = recv_state.src_id;
517517
mod_src_param.num_subgroups = 1;
518-
mod_src_param.pa_sync = true;
518+
mod_src_param.pa_sync = pa_sync;
519519
mod_src_param.subgroups = &subgroup;
520520
mod_src_param.pa_interval = g_broadcaster_info.interval;
521521
subgroup.bis_sync = bis_sync;
@@ -542,14 +542,16 @@ static void test_bass_mod_source(uint32_t bis_sync)
542542
WAIT_FOR_AND_CLEAR_FLAG(flag_recv_state_updated);
543543
}
544544

545-
if (recv_state.pa_sync_state != BT_BAP_PA_STATE_SYNCED) {
546-
FAIL("Unexpected PA sync state: %d\n", recv_state.pa_sync_state);
547-
return;
548-
}
545+
if (pa_sync) {
546+
if (recv_state.pa_sync_state != BT_BAP_PA_STATE_SYNCED) {
547+
FAIL("Unexpected PA sync state: %d\n", recv_state.pa_sync_state);
548+
return;
549+
}
549550

550-
if (recv_state.encrypt_state != BT_BAP_BIG_ENC_STATE_NO_ENC) {
551-
FAIL("Unexpected BIG encryption state: %d\n", recv_state.pa_sync_state);
552-
return;
551+
if (recv_state.encrypt_state != BT_BAP_BIG_ENC_STATE_NO_ENC) {
552+
FAIL("Unexpected BIG encryption state: %d\n", recv_state.pa_sync_state);
553+
return;
554+
}
553555
}
554556

555557
if (recv_state.num_subgroups != mod_src_param.num_subgroups) {
@@ -563,19 +565,15 @@ static void test_bass_mod_source(uint32_t bis_sync)
563565
WAIT_FOR_AND_CLEAR_FLAG(flag_recv_state_updated);
564566
}
565567

566-
remote_bis_sync = recv_state.subgroups[0].bis_sync;
567-
if (subgroup.bis_sync == 0) {
568-
if (remote_bis_sync != 0U) {
569-
FAIL("Unexpected BIS sync value: %u\n", remote_bis_sync);
570-
return;
571-
}
572-
} else {
568+
if (bis_sync != 0) {
569+
remote_bis_sync = recv_state.subgroups[0].bis_sync;
573570
printk("Waiting for BIS sync\n");
574571

575572
if (remote_bis_sync == 0U &&
576573
recv_state.encrypt_state == BT_BAP_BIG_ENC_STATE_NO_ENC) {
577-
/* Wait for another notification, which will either request a broadcast code
578-
* for encrypted broadcasts, or have the BIS sync values set
574+
/* Wait for another notification, which will either request a
575+
* broadcast code for encrypted broadcasts, or have the BIS sync
576+
* values set
579577
*/
580578
printk("Waiting for another receive state update with BIS sync\n");
581579
WAIT_FOR_AND_CLEAR_FLAG(flag_recv_state_updated);
@@ -770,14 +768,15 @@ static void test_main_client_sync(void)
770768
test_bass_scan_stop();
771769
test_bass_create_pa_sync();
772770
test_bass_add_source();
773-
test_bass_mod_source(0);
771+
test_bass_mod_source(true, 0);
774772
test_bass_mod_source_long_meta();
775-
test_bass_mod_source(BT_ISO_BIS_INDEX_BIT(1) | BT_ISO_BIS_INDEX_BIT(2));
773+
test_bass_mod_source(true, BT_ISO_BIS_INDEX_BIT(1) | BT_ISO_BIS_INDEX_BIT(2));
776774
test_bass_broadcast_code(BROADCAST_CODE);
777775

778776
printk("Waiting for receive state with BIS sync\n");
779777
WAIT_FOR_FLAG(flag_recv_state_updated_with_bis_sync);
780778

779+
test_bass_mod_source(false, 0);
781780
test_bass_remove_source();
782781

783782
PASS("BAP Broadcast Assistant Client Sync Passed\n");
@@ -797,11 +796,12 @@ static void test_main_client_sync_incorrect_code(void)
797796
test_bass_scan_stop();
798797
test_bass_create_pa_sync();
799798
test_bass_add_source();
800-
test_bass_mod_source(BT_ISO_BIS_INDEX_BIT(1));
799+
test_bass_mod_source(true, BT_ISO_BIS_INDEX_BIT(1));
801800
WAIT_FOR_FLAG(flag_broadcast_code_requested);
802801
test_bass_broadcast_code(INCORRECT_BROADCAST_CODE);
803802
WAIT_FOR_FLAG(flag_incorrect_broadcast_code);
804803

804+
test_bass_mod_source(false, 0);
805805
test_bass_remove_source();
806806

807807
PASS("BAP Broadcast Assistant Client Sync Passed\n");
@@ -825,6 +825,7 @@ static void test_main_server_sync_client_rem(void)
825825
WAIT_FOR_FLAG(flag_recv_state_updated_with_bis_sync);
826826

827827
printk("Attempting to remove source for the first time\n");
828+
test_bass_mod_source(false, 0);
828829
test_bass_remove_source();
829830

830831
WAIT_FOR_FLAG(flag_remove_source_rejected);

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

Lines changed: 51 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,8 @@ static int pa_sync_term(struct sync_state *state)
213213

214214
printk("Deleting PA sync\n");
215215

216+
UNSET_FLAG(flag_pa_terminated);
217+
216218
err = bt_le_per_adv_sync_delete(state->pa_sync);
217219
if (err != 0) {
218220
FAIL("Could not delete per adv sync: %d\n", err);
@@ -221,6 +223,8 @@ static int pa_sync_term(struct sync_state *state)
221223
state->pa_sync = NULL;
222224
}
223225

226+
WAIT_FOR_FLAG(flag_pa_terminated);
227+
224228
return err;
225229
}
226230

@@ -708,13 +712,48 @@ static void remove_all_sources(void)
708712

709713
printk("[%zu]: Source removed with id %u\n",
710714
i, state->src_id);
715+
}
716+
}
717+
}
711718

712-
printk("Terminating PA sync\n");
713-
err = pa_sync_term(state);
714-
if (err) {
715-
FAIL("[%zu]: PA sync term failed (err %d)\n", err);
716-
return;
717-
}
719+
static void terminate_all_pa(void)
720+
{
721+
for (size_t i = 0U; i < ARRAY_SIZE(sync_states); i++) {
722+
int err;
723+
struct sync_state *state = &sync_states[i];
724+
725+
if (state->pa_sync == NULL) {
726+
continue;
727+
}
728+
729+
err = pa_sync_term(state);
730+
if (err != 0) {
731+
FAIL("[%zu]: PA sync term failed (err %d)\n", i, err);
732+
return;
733+
}
734+
}
735+
}
736+
737+
static void set_bis_sync_state(struct sync_state *state,
738+
uint32_t bis_sync_req[CONFIG_BT_BAP_BASS_MAX_SUBGROUPS])
739+
{
740+
int err;
741+
742+
err = bt_bap_scan_delegator_set_bis_sync_state(state->src_id, bis_sync_req);
743+
if (err != 0) {
744+
FAIL("Could not set BIS sync state: %d\n", err);
745+
return;
746+
}
747+
}
748+
749+
static void set_all_bis_sync_states(uint32_t bis_sync_req[CONFIG_BT_BAP_BASS_MAX_SUBGROUPS])
750+
{
751+
for (size_t i = 0U; i < ARRAY_SIZE(sync_states); i++) {
752+
struct sync_state *state = &sync_states[i];
753+
754+
if (state->recv_state != NULL) {
755+
printk("[%zu]: Setting BIS sync state\n", i);
756+
set_bis_sync_state(state, bis_sync_req);
718757
}
719758
}
720759
}
@@ -914,7 +953,12 @@ static void test_main_server_sync_server_rem(void)
914953
/* Set the BIS sync state */
915954
sync_all_broadcasts();
916955

917-
/* Remote all sources, causing PA sync term request to trigger */
956+
uint32_t bis_sync_req[CONFIG_BT_BAP_BASS_MAX_SUBGROUPS] = {0};
957+
958+
set_all_bis_sync_states(bis_sync_req);
959+
terminate_all_pa();
960+
961+
/* Remove all sources, causing PA sync term request to trigger */
918962
remove_all_sources();
919963

920964
/* Wait for PA sync to be terminated */

0 commit comments

Comments
 (0)