Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions doc/releases/migration-guide-4.3.rst
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,12 @@ Bluetooth Audio
* Setting the BGS role for GMAP now requires also supporting and implementing the
:kconfig:option:`CONFIG_BT_BAP_BROADCAST_ASSISTANT`.
See the :zephyr:code-sample:`bluetooth_bap_broadcast_assistant` sample as a reference.
* The BAP Scan Delegator will no longer automatically update the PA sync state, and
:c:func:`bt_bap_scan_delegator_set_pa_state` must be used to update the state. If the
BAP Scan Delegator is used together with the BAP Broadcast Sink, then the PA state of the
receive state of a :c:struct:`bt_bap_broadcast_sink` will still be automatically updated when the
PA state changes. (:github:`95453``)


.. zephyr-keep-sorted-stop

Expand Down
10 changes: 8 additions & 2 deletions include/zephyr/bluetooth/audio/bap.h
Original file line number Diff line number Diff line change
Expand Up @@ -2661,8 +2661,6 @@ int bt_bap_scan_delegator_unregister(void);
*
* @param src_id The source id used to identify the receive state.
* @param pa_state The Periodic Advertising sync state to set.
* BT_BAP_PA_STATE_NOT_SYNCED and BT_BAP_PA_STATE_SYNCED is
* not necessary to provide, as they are handled internally.
*
* @return int Error value. 0 on success, errno on fail.
*/
Expand All @@ -2688,6 +2686,14 @@ struct bt_bap_scan_delegator_add_src_param {
/** Advertiser SID */
uint8_t sid;

/**
* @brief Periodic Advertising sync state
*
* This will typically be either @ref BT_BAP_PA_STATE_NOT_SYNCED or
* @ref BT_BAP_PA_STATE_SYNCED.
*/
enum bt_bap_pa_state pa_state;

/** The broadcast isochronous group encryption state */
enum bt_bap_big_enc_state encrypt_state;

Expand Down
69 changes: 51 additions & 18 deletions subsys/bluetooth/audio/bap_broadcast_sink.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,8 @@ static struct bt_bap_scan_delegator_mod_src_param mod_src_param;

static void broadcast_sink_cleanup(struct bt_bap_broadcast_sink *sink);

static bool find_recv_state_by_sink_cb(const struct bt_bap_scan_delegator_recv_state *recv_state,
void *user_data)
static bool find_recv_state_by_src_id_cb(const struct bt_bap_scan_delegator_recv_state *recv_state,
void *user_data)
{
const struct bt_bap_broadcast_sink *sink = user_data;

Expand All @@ -83,34 +83,35 @@ static bool find_recv_state_by_sink_cb(const struct bt_bap_scan_delegator_recv_s
return false;
}

static bool find_recv_state_by_pa_sync_cb(const struct bt_bap_scan_delegator_recv_state *recv_state,
void *user_data)
static bool
find_recv_state_by_sink_fields_cb(const struct bt_bap_scan_delegator_recv_state *recv_state,
void *user_data)
{
struct bt_le_per_adv_sync *sync = user_data;
const struct bt_bap_broadcast_sink *sink = user_data;
struct bt_le_per_adv_sync_info sync_info;
int err;

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

return false;
}

if (bt_addr_le_eq(&recv_state->addr, &sync_info.addr) &&
recv_state->adv_sid == sync_info.sid) {
return true;
}

return false;
/* BAP 6.5.4 states that the combined Source_Address_Type, Source_Adv_SID, and Broadcast_ID
* fields are what makes a receive state unique.
*/
return recv_state->addr.type == sync_info.addr.type &&
recv_state->adv_sid == sync_info.sid &&
recv_state->broadcast_id == sink->broadcast_id;
};

static void update_recv_state_big_synced(const struct bt_bap_broadcast_sink *sink)
{
const struct bt_bap_scan_delegator_recv_state *recv_state;
int err;

recv_state = bt_bap_scan_delegator_find_state(find_recv_state_by_sink_cb, (void *)sink);
recv_state = bt_bap_scan_delegator_find_state(find_recv_state_by_src_id_cb, (void *)sink);
if (recv_state == NULL) {
LOG_WRN("Failed to find receive state for sink %p", sink);

Expand Down Expand Up @@ -156,7 +157,7 @@ static void update_recv_state_big_cleared(const struct bt_bap_broadcast_sink *si
bool sink_is_streaming = false;
int err;

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

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

recv_state = bt_bap_scan_delegator_find_state(find_recv_state_by_sink_cb, (void *)sink);
recv_state = bt_bap_scan_delegator_find_state(find_recv_state_by_src_id_cb, (void *)sink);
if (recv_state == NULL) {
LOG_WRN("Failed to find receive state for sink %p", sink);

Expand Down Expand Up @@ -745,12 +748,23 @@ static void pa_recv(struct bt_le_per_adv_sync *sync,
bt_data_parse(buf, pa_decode_base, (void *)sink);
}

static void pa_synced_cb(struct bt_le_per_adv_sync *sync,
struct bt_le_per_adv_sync_synced_info *info)
{
struct bt_bap_broadcast_sink *sink = broadcast_sink_get_by_pa(sync);

if (sink != NULL) {
bt_bap_scan_delegator_set_pa_state(sink->bass_src_id, BT_BAP_PA_STATE_SYNCED);
}
}

static void pa_term_cb(struct bt_le_per_adv_sync *sync,
const struct bt_le_per_adv_sync_term_info *info)
{
struct bt_bap_broadcast_sink *sink = broadcast_sink_get_by_pa(sync);

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

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

recv_state = bt_bap_scan_delegator_find_state(find_recv_state_by_sink_cb, (void *)sink);
recv_state = bt_bap_scan_delegator_find_state(find_recv_state_by_src_id_cb, (void *)sink);
if (recv_state == NULL) {
LOG_WRN("Failed to find receive state for sink %p", sink);

Expand Down Expand Up @@ -1073,8 +1087,8 @@ int bt_bap_broadcast_sink_create(struct bt_le_per_adv_sync *pa_sync, uint32_t br
sink->broadcast_id = broadcast_id;
sink->pa_sync = pa_sync;

recv_state = bt_bap_scan_delegator_find_state(find_recv_state_by_pa_sync_cb,
(void *)pa_sync);
recv_state =
bt_bap_scan_delegator_find_state(find_recv_state_by_sink_fields_cb, (void *)sink);
if (recv_state == NULL) {
broadcast_sink_add_src(sink);
} else {
Expand All @@ -1088,8 +1102,26 @@ int bt_bap_broadcast_sink_create(struct bt_le_per_adv_sync *pa_sync, uint32_t br
}

sink->bass_src_id = recv_state->src_id;
if (recv_state->pa_sync_state != BT_BAP_PA_STATE_SYNCED) {
int err;

/* When a broadcast sink is created we always assume the PA sync provided is
* synced
*/
err = bt_bap_scan_delegator_set_pa_state(sink->bass_src_id,
BT_BAP_PA_STATE_SYNCED);
if (err != 0) {
LOG_DBG("Failed to set PA state: %d", err);

broadcast_sink_cleanup(sink);

return err;
}
}

atomic_set_bit(sink->flags, BT_BAP_BROADCAST_SINK_FLAG_SRC_ID_VALID);
}

atomic_set_bit(sink->flags, BT_BAP_BROADCAST_SINK_FLAG_INITIALIZED);

*out_sink = sink;
Expand Down Expand Up @@ -1416,6 +1448,7 @@ int bt_bap_broadcast_sink_delete(struct bt_bap_broadcast_sink *sink)
static int broadcast_sink_init(void)
{
static struct bt_le_per_adv_sync_cb cb = {
.synced = pa_synced_cb,
.recv = pa_recv,
.biginfo = biginfo_recv,
.term = pa_term_cb,
Expand Down
Loading
Loading