Skip to content

Commit 9fb3ea3

Browse files
committed
Bluetooth: BAP: SD: Remove address lookups
Remove lookups in the Scan Delegator that relates to the advertiser address. The reason for this, is that the address is not considered a unique value for receive states, since the address may change over time in the case of (N)RPAs. Instead we shall rely exclusively on the address type, the sid and the broadcast ID. The implementation of the Scan Delegator and Broadcast Sink has been updated to not use addresses for lookups anymore, and there has been a minor API modification to set the PA sync state as part of bt_bap_scan_delegator_add_src as the higher layers are better suited to handle the PA Sync state. Signed-off-by: Emil Gydesen <[email protected]>
1 parent 3022bd1 commit 9fb3ea3

File tree

3 files changed

+138
-199
lines changed

3 files changed

+138
-199
lines changed

include/zephyr/bluetooth/audio/bap.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2661,8 +2661,6 @@ int bt_bap_scan_delegator_unregister(void);
26612661
*
26622662
* @param src_id The source id used to identify the receive state.
26632663
* @param pa_state The Periodic Advertising sync state to set.
2664-
* BT_BAP_PA_STATE_NOT_SYNCED and BT_BAP_PA_STATE_SYNCED is
2665-
* not necessary to provide, as they are handled internally.
26662664
*
26672665
* @return int Error value. 0 on success, errno on fail.
26682666
*/
@@ -2688,6 +2686,14 @@ struct bt_bap_scan_delegator_add_src_param {
26882686
/** Advertiser SID */
26892687
uint8_t sid;
26902688

2689+
/**
2690+
* @brief Periodic Advertising sync state
2691+
*
2692+
* This will typically be either @ref BT_BAP_PA_STATE_NOT_SYNCED or
2693+
* @ref BT_BAP_PA_STATE_SYNCED.
2694+
*/
2695+
enum bt_bap_pa_state pa_state;
2696+
26912697
/** The broadcast isochronous group encryption state */
26922698
enum bt_bap_big_enc_state encrypt_state;
26932699

subsys/bluetooth/audio/bap_broadcast_sink.c

Lines changed: 50 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,8 @@ static struct bt_bap_scan_delegator_mod_src_param mod_src_param;
7070

7171
static void broadcast_sink_cleanup(struct bt_bap_broadcast_sink *sink);
7272

73-
static bool find_recv_state_by_sink_cb(const struct bt_bap_scan_delegator_recv_state *recv_state,
74-
void *user_data)
73+
static bool find_recv_state_by_src_id_cb(const struct bt_bap_scan_delegator_recv_state *recv_state,
74+
void *user_data)
7575
{
7676
const struct bt_bap_broadcast_sink *sink = user_data;
7777

@@ -83,34 +83,35 @@ static bool find_recv_state_by_sink_cb(const struct bt_bap_scan_delegator_recv_s
8383
return false;
8484
}
8585

86-
static bool find_recv_state_by_pa_sync_cb(const struct bt_bap_scan_delegator_recv_state *recv_state,
87-
void *user_data)
86+
static bool
87+
find_recv_state_by_sink_fields_cb(const struct bt_bap_scan_delegator_recv_state *recv_state,
88+
void *user_data)
8889
{
89-
struct bt_le_per_adv_sync *sync = user_data;
90+
const struct bt_bap_broadcast_sink *sink = user_data;
9091
struct bt_le_per_adv_sync_info sync_info;
9192
int err;
9293

93-
err = bt_le_per_adv_sync_get_info(sync, &sync_info);
94+
err = bt_le_per_adv_sync_get_info(sink->pa_sync, &sync_info);
9495
if (err != 0) {
9596
LOG_DBG("Failed to get sync info: %d", err);
9697

9798
return false;
9899
}
99100

100-
if (bt_addr_le_eq(&recv_state->addr, &sync_info.addr) &&
101-
recv_state->adv_sid == sync_info.sid) {
102-
return true;
103-
}
104-
105-
return false;
101+
/* BAP 6.5.4 states that the combined Source_Address_Type, Source_Adv_SID, and Broadcast_ID
102+
* fields are what makes a receive state unique.
103+
*/
104+
return recv_state->addr.type == sync_info.addr.type &&
105+
recv_state->adv_sid == sync_info.sid &&
106+
recv_state->broadcast_id == sink->broadcast_id;
106107
};
107108

108109
static void update_recv_state_big_synced(const struct bt_bap_broadcast_sink *sink)
109110
{
110111
const struct bt_bap_scan_delegator_recv_state *recv_state;
111112
int err;
112113

113-
recv_state = bt_bap_scan_delegator_find_state(find_recv_state_by_sink_cb, (void *)sink);
114+
recv_state = bt_bap_scan_delegator_find_state(find_recv_state_by_src_id_cb, (void *)sink);
114115
if (recv_state == NULL) {
115116
LOG_WRN("Failed to find receive state for sink %p", sink);
116117

@@ -156,7 +157,7 @@ static void update_recv_state_big_cleared(const struct bt_bap_broadcast_sink *si
156157
bool sink_is_streaming = false;
157158
int err;
158159

159-
recv_state = bt_bap_scan_delegator_find_state(find_recv_state_by_sink_cb, (void *)sink);
160+
recv_state = bt_bap_scan_delegator_find_state(find_recv_state_by_src_id_cb, (void *)sink);
160161
if (recv_state == NULL) {
161162
/* This is likely due to the receive state being removed while we are BIG synced */
162163
LOG_DBG("Could not find receive state for sink %p", sink);
@@ -489,6 +490,8 @@ static void broadcast_sink_add_src(struct bt_bap_broadcast_sink *sink)
489490

490491
bt_addr_le_copy(&add_src_param.addr, &sync_info.addr);
491492
add_src_param.sid = sync_info.sid;
493+
/* When a broadcast sink is created we always assume the PA sync provided is synced */
494+
add_src_param.pa_state = BT_BAP_PA_STATE_SYNCED;
492495
add_src_param.broadcast_id = sink->broadcast_id;
493496
/* Will be updated when we receive the BASE */
494497
add_src_param.encrypt_state = BT_BAP_BIG_ENC_STATE_NO_ENC;
@@ -542,7 +545,7 @@ static void update_recv_state_base(const struct bt_bap_broadcast_sink *sink,
542545
const struct bt_bap_scan_delegator_recv_state *recv_state;
543546
int err;
544547

545-
recv_state = bt_bap_scan_delegator_find_state(find_recv_state_by_sink_cb, (void *)sink);
548+
recv_state = bt_bap_scan_delegator_find_state(find_recv_state_by_src_id_cb, (void *)sink);
546549
if (recv_state == NULL) {
547550
LOG_WRN("Failed to find receive state for sink %p", sink);
548551

@@ -745,12 +748,23 @@ static void pa_recv(struct bt_le_per_adv_sync *sync,
745748
bt_data_parse(buf, pa_decode_base, (void *)sink);
746749
}
747750

751+
static void pa_synced_cb(struct bt_le_per_adv_sync *sync,
752+
struct bt_le_per_adv_sync_synced_info *info)
753+
{
754+
struct bt_bap_broadcast_sink *sink = broadcast_sink_get_by_pa(sync);
755+
756+
if (sink != NULL) {
757+
bt_bap_scan_delegator_set_pa_state(sink->bass_src_id, BT_BAP_PA_STATE_SYNCED);
758+
}
759+
}
760+
748761
static void pa_term_cb(struct bt_le_per_adv_sync *sync,
749762
const struct bt_le_per_adv_sync_term_info *info)
750763
{
751764
struct bt_bap_broadcast_sink *sink = broadcast_sink_get_by_pa(sync);
752765

753766
if (sink != NULL) {
767+
bt_bap_scan_delegator_set_pa_state(sink->bass_src_id, BT_BAP_PA_STATE_NOT_SYNCED);
754768
sink->pa_sync = NULL;
755769
sink->base_size = 0U;
756770
}
@@ -763,7 +777,7 @@ static void update_recv_state_encryption(const struct bt_bap_broadcast_sink *sin
763777

764778
__ASSERT(sink->big == NULL, "Encryption state shall not be updated while synced");
765779

766-
recv_state = bt_bap_scan_delegator_find_state(find_recv_state_by_sink_cb, (void *)sink);
780+
recv_state = bt_bap_scan_delegator_find_state(find_recv_state_by_src_id_cb, (void *)sink);
767781
if (recv_state == NULL) {
768782
LOG_WRN("Failed to find receive state for sink %p", sink);
769783

@@ -1044,6 +1058,7 @@ int bt_bap_broadcast_sink_create(struct bt_le_per_adv_sync *pa_sync, uint32_t br
10441058
{
10451059
const struct bt_bap_scan_delegator_recv_state *recv_state;
10461060
struct bt_bap_broadcast_sink *sink;
1061+
int err;
10471062

10481063
CHECKIF(pa_sync == NULL) {
10491064
LOG_DBG("pa_sync is NULL");
@@ -1073,8 +1088,8 @@ int bt_bap_broadcast_sink_create(struct bt_le_per_adv_sync *pa_sync, uint32_t br
10731088
sink->broadcast_id = broadcast_id;
10741089
sink->pa_sync = pa_sync;
10751090

1076-
recv_state = bt_bap_scan_delegator_find_state(find_recv_state_by_pa_sync_cb,
1077-
(void *)pa_sync);
1091+
recv_state =
1092+
bt_bap_scan_delegator_find_state(find_recv_state_by_sink_fields_cb, (void *)sink);
10781093
if (recv_state == NULL) {
10791094
broadcast_sink_add_src(sink);
10801095
} else {
@@ -1088,8 +1103,24 @@ int bt_bap_broadcast_sink_create(struct bt_le_per_adv_sync *pa_sync, uint32_t br
10881103
}
10891104

10901105
sink->bass_src_id = recv_state->src_id;
1106+
if (recv_state->pa_sync_state != BT_BAP_PA_STATE_SYNCED) {
1107+
/* When a broadcast sink is created we always assume the PA sync provided is
1108+
* synced
1109+
*/
1110+
err = bt_bap_scan_delegator_set_pa_state(sink->bass_src_id,
1111+
BT_BAP_PA_STATE_SYNCED);
1112+
if (err != 0) {
1113+
LOG_DBG("Failed to set PA state: %d", err);
1114+
1115+
broadcast_sink_cleanup(sink);
1116+
1117+
return err;
1118+
}
1119+
}
1120+
10911121
atomic_set_bit(sink->flags, BT_BAP_BROADCAST_SINK_FLAG_SRC_ID_VALID);
10921122
}
1123+
10931124
atomic_set_bit(sink->flags, BT_BAP_BROADCAST_SINK_FLAG_INITIALIZED);
10941125

10951126
*out_sink = sink;
@@ -1432,6 +1463,7 @@ int bt_bap_broadcast_sink_delete(struct bt_bap_broadcast_sink *sink)
14321463
static int broadcast_sink_init(void)
14331464
{
14341465
static struct bt_le_per_adv_sync_cb cb = {
1466+
.synced = pa_synced_cb,
14351467
.recv = pa_recv,
14361468
.biginfo = biginfo_recv,
14371469
.term = pa_term_cb,

0 commit comments

Comments
 (0)