Bluetooth: Audio: Scan Delegator: Guard for duplication in add_source
Added a check for duplication of add source operation in the Scan Delagator. BAP 6.5.4 states that an assistant may not perform add source operation if it results in a duplication of a source. While this is not mentioned for the Scan Delegator, the spirit of the spec. must be that no duplications can exists in the recv_state, which is what this commit fixes. Signed-off-by: Fredrik Danebjer <frdn@demant.com>
This commit is contained in:
parent
d73b6e50b9
commit
0fe8ddd75e
@ -279,7 +279,7 @@ static void scan_delegator_security_changed(struct bt_conn *conn,
|
||||
}
|
||||
|
||||
/* Notify all receive states after a bonded device reconnects */
|
||||
for (int i = 0; i < ARRAY_SIZE(scan_delegator.recv_states); i++) {
|
||||
for (size_t i = 0; i < ARRAY_SIZE(scan_delegator.recv_states); i++) {
|
||||
struct bass_recv_state_internal *internal_state = &scan_delegator.recv_states[i];
|
||||
int gatt_err;
|
||||
|
||||
@ -318,7 +318,7 @@ static struct broadcast_assistant *get_bap_broadcast_assistant(struct bt_conn *c
|
||||
{
|
||||
struct broadcast_assistant *new = NULL;
|
||||
|
||||
for (int i = 0; i < ARRAY_SIZE(scan_delegator.assistant_configs); i++) {
|
||||
for (size_t i = 0; i < ARRAY_SIZE(scan_delegator.assistant_configs); i++) {
|
||||
if (scan_delegator.assistant_configs[i].conn == conn) {
|
||||
return &scan_delegator.assistant_configs[i];
|
||||
} else if (new == NULL &&
|
||||
@ -344,7 +344,7 @@ static uint8_t next_src_id(void)
|
||||
while (!unique) {
|
||||
next_src_id = scan_delegator.next_src_id++;
|
||||
unique = true;
|
||||
for (int i = 0; i < ARRAY_SIZE(scan_delegator.recv_states); i++) {
|
||||
for (size_t i = 0; i < ARRAY_SIZE(scan_delegator.recv_states); i++) {
|
||||
if (scan_delegator.recv_states[i].active &&
|
||||
scan_delegator.recv_states[i].state.src_id == next_src_id) {
|
||||
unique = false;
|
||||
@ -358,7 +358,7 @@ static uint8_t next_src_id(void)
|
||||
|
||||
static struct bass_recv_state_internal *bass_lookup_src_id(uint8_t src_id)
|
||||
{
|
||||
for (int i = 0; i < ARRAY_SIZE(scan_delegator.recv_states); i++) {
|
||||
for (size_t i = 0; i < ARRAY_SIZE(scan_delegator.recv_states); i++) {
|
||||
if (scan_delegator.recv_states[i].active &&
|
||||
scan_delegator.recv_states[i].state.src_id == src_id) {
|
||||
return &scan_delegator.recv_states[i];
|
||||
@ -370,7 +370,7 @@ static struct bass_recv_state_internal *bass_lookup_src_id(uint8_t src_id)
|
||||
|
||||
static struct bass_recv_state_internal *bass_lookup_pa_sync(struct bt_le_per_adv_sync *sync)
|
||||
{
|
||||
for (int i = 0; i < ARRAY_SIZE(scan_delegator.recv_states); i++) {
|
||||
for (size_t i = 0; i < ARRAY_SIZE(scan_delegator.recv_states); i++) {
|
||||
if (scan_delegator.recv_states[i].pa_sync == sync) {
|
||||
return &scan_delegator.recv_states[i];
|
||||
}
|
||||
@ -381,7 +381,7 @@ static struct bass_recv_state_internal *bass_lookup_pa_sync(struct bt_le_per_adv
|
||||
|
||||
static struct bass_recv_state_internal *bass_lookup_addr(const bt_addr_le_t *addr)
|
||||
{
|
||||
for (int i = 0; i < ARRAY_SIZE(scan_delegator.recv_states); i++) {
|
||||
for (size_t i = 0; i < ARRAY_SIZE(scan_delegator.recv_states); i++) {
|
||||
if (bt_addr_le_eq(&scan_delegator.recv_states[i].state.addr,
|
||||
addr)) {
|
||||
return &scan_delegator.recv_states[i];
|
||||
@ -493,6 +493,24 @@ static int pa_sync_term_request(struct bt_conn *conn,
|
||||
return err;
|
||||
}
|
||||
|
||||
static bool bass_source_is_duplicate(uint32_t broadcast_id, uint8_t adv_sid, bt_addr_le_t addr)
|
||||
{
|
||||
struct bass_recv_state_internal *state;
|
||||
|
||||
for (size_t i = 0; i < ARRAY_SIZE(scan_delegator.recv_states); i++) {
|
||||
state = &scan_delegator.recv_states[i];
|
||||
|
||||
if (state != NULL && state->state.broadcast_id == broadcast_id
|
||||
&& state->state.adv_sid == adv_sid && state->state.addr.type == addr.type) {
|
||||
LOG_DBG("recv_state already exists at src_id=0x%02X", state->state.src_id);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static int scan_delegator_add_source(struct bt_conn *conn,
|
||||
struct net_buf_simple *buf)
|
||||
{
|
||||
@ -502,6 +520,7 @@ static int scan_delegator_add_source(struct bt_conn *conn,
|
||||
uint8_t pa_sync;
|
||||
uint16_t pa_interval;
|
||||
uint32_t aggregated_bis_syncs = 0;
|
||||
uint32_t broadcast_id;
|
||||
bool bis_sync_requested;
|
||||
|
||||
/* subtract 1 as the opcode has already been pulled */
|
||||
@ -535,7 +554,17 @@ static int scan_delegator_add_source(struct bt_conn *conn,
|
||||
return BT_GATT_ERR(BT_ATT_ERR_VALUE_NOT_ALLOWED);
|
||||
}
|
||||
|
||||
state->broadcast_id = net_buf_simple_pull_le24(buf);
|
||||
broadcast_id = net_buf_simple_pull_le24(buf);
|
||||
|
||||
if (bass_source_is_duplicate(broadcast_id, state->adv_sid, state->addr)) {
|
||||
LOG_DBG("Adding broadcast_id=0x%06X, adv_sid=0x%02X, and addr.type=0x%02X would "
|
||||
"result in duplication", state->broadcast_id, state->adv_sid,
|
||||
state->addr.type);
|
||||
|
||||
return BT_GATT_ERR(BT_ATT_ERR_WRITE_REQ_REJECTED);
|
||||
}
|
||||
|
||||
state->broadcast_id = broadcast_id;
|
||||
|
||||
pa_sync = net_buf_simple_pull_u8(buf);
|
||||
if (pa_sync > BT_BAP_BASS_PA_REQ_SYNC) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user