From a1471dde503a8cc6f76949d77a85c67e093af1ea Mon Sep 17 00:00:00 2001 From: Old-Ding Date: Wed, 1 Jul 2026 10:21:06 +0800 Subject: [PATCH 1/2] nimble/audio: Bound broadcast sink subgroup count Reject sync requests whose subgroup count exceeds the broadcast sink subgroup array before copying BIS sync values into it. The previous code relied on a debug assertion in the scan delegator path, but production builds can still receive an oversized sync option. Fixes #2188 Signed-off-by: Old-Ding --- .../host/audio/src/ble_audio_broadcast_sink.c | 12 +++++- nimble/host/audio/test/src/ble_audio_test.c | 2 + .../testcases/ble_audio_broadcast_sink_test.c | 37 +++++++++++++++++++ nimble/host/audio/test/syscfg.yml | 5 +++ 4 files changed, 54 insertions(+), 2 deletions(-) create mode 100644 nimble/host/audio/test/src/testcases/ble_audio_broadcast_sink_test.c diff --git a/nimble/host/audio/src/ble_audio_broadcast_sink.c b/nimble/host/audio/src/ble_audio_broadcast_sink.c index 8c2f05451d..90dee1c499 100644 --- a/nimble/host/audio/src/ble_audio_broadcast_sink.c +++ b/nimble/host/audio/src/ble_audio_broadcast_sink.c @@ -1579,13 +1579,21 @@ ble_audio_broadcast_sink_config(uint8_t source_id, uint16_t conn_handle, const struct ble_audio_scan_delegator_sync_opt *sync_opt) { struct ble_audio_broadcast_sink *sink; + bool sync_requested; int rc; BLE_AUDIO_DBG_ASSERT(sync_opt != NULL); + sync_requested = sync_opt->pa_sync != BLE_AUDIO_SCAN_DELEGATOR_PA_SYNC_DO_NOT_SYNC; + if (sync_requested && sync_opt->num_subgroups > + MYNEWT_VAL(BLE_AUDIO_SCAN_DELEGATOR_SUBGROUP_MAX)) { + BLE_HS_LOG_ERROR("num_subgroups above the limit\n"); + return BLE_HS_EINVAL; + } + sink = broadcast_sink_get(source_id); if (sink == NULL) { - if (sync_opt->pa_sync != BLE_AUDIO_SCAN_DELEGATOR_PA_SYNC_DO_NOT_SYNC) { + if (sync_requested) { sink = broadcast_sink_new(source_id); if (sink == NULL) { return BLE_HS_ENOMEM; @@ -1596,7 +1604,7 @@ ble_audio_broadcast_sink_config(uint8_t source_id, uint16_t conn_handle, } } - if (sync_opt->pa_sync != BLE_AUDIO_SCAN_DELEGATOR_PA_SYNC_DO_NOT_SYNC) { + if (sync_requested) { /* TODO: Skip if the BIS Sync is same */ if (sink->num_subgroups != 0) { rc = big_sync_term(sink); diff --git a/nimble/host/audio/test/src/ble_audio_test.c b/nimble/host/audio/test/src/ble_audio_test.c index 91e4a91449..2f733cc439 100644 --- a/nimble/host/audio/test/src/ble_audio_test.c +++ b/nimble/host/audio/test/src/ble_audio_test.c @@ -22,11 +22,13 @@ TEST_SUITE_DECL(ble_audio_base_parse_test_suite); TEST_CASE_DECL(ble_audio_listener_register_test); +TEST_CASE_DECL(ble_audio_broadcast_sink_config_test_subgroups_bound); TEST_SUITE(ble_audio_test) { ble_audio_base_parse_test_suite(); ble_audio_listener_register_test(); + ble_audio_broadcast_sink_config_test_subgroups_bound(); } int diff --git a/nimble/host/audio/test/src/testcases/ble_audio_broadcast_sink_test.c b/nimble/host/audio/test/src/testcases/ble_audio_broadcast_sink_test.c new file mode 100644 index 0000000000..c4d7a57a2c --- /dev/null +++ b/nimble/host/audio/test/src/testcases/ble_audio_broadcast_sink_test.c @@ -0,0 +1,37 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include "testutil/testutil.h" + +#include "host/ble_hs.h" +#include "audio/ble_audio_scan_delegator.h" +#include "../../../src/ble_audio_broadcast_sink_priv.h" + +TEST_CASE_SELF(ble_audio_broadcast_sink_config_test_subgroups_bound) +{ + struct ble_audio_scan_delegator_sync_opt sync_opt = { 0 }; + int rc; + + sync_opt.pa_sync = BLE_AUDIO_SCAN_DELEGATOR_PA_SYNC_PAST_NOT_AVAILABLE; + sync_opt.num_subgroups = BLE_AUDIO_SCAN_DELEGATOR_SUBGROUP_MAX + 1; + + rc = ble_audio_broadcast_sink_config(0, BLE_HS_CONN_HANDLE_NONE, &sync_opt); + + TEST_ASSERT(rc == BLE_HS_EINVAL); +} diff --git a/nimble/host/audio/test/syscfg.yml b/nimble/host/audio/test/syscfg.yml index 7fad93f3fe..f0a8c2c830 100644 --- a/nimble/host/audio/test/syscfg.yml +++ b/nimble/host/audio/test/syscfg.yml @@ -29,3 +29,8 @@ syscfg.vals: BLE_HS_DEBUG: 1 BLE_EXT_ADV: 1 + BLE_PERIODIC_ADV: 1 + + BLE_ISO_BROADCAST_SINK: 1 + BLE_AUDIO_BROADCAST_SINK: 1 + BLE_AUDIO_BROADCAST_SINK_MAX: 1 From e93fbb98e6eec1e69680067a7dcba30f28fb9e31 Mon Sep 17 00:00:00 2001 From: Old-Ding <35417409+Old-Ding@users.noreply.github.com> Date: Fri, 10 Jul 2026 14:29:00 +0800 Subject: [PATCH 2/2] nimble/audio: enable sink test PA sync features The audio unit test now builds the broadcast sink, whose GAP handler uses PAST and BIGInfo report fields and calls ble_gap_periodic_adv_sync_receive(). Enable those periodic advertising features in the test syscfg so the corresponding host declarations are visible. Signed-off-by: Old-Ding <35417409+Old-Ding@users.noreply.github.com> --- nimble/host/audio/test/syscfg.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/nimble/host/audio/test/syscfg.yml b/nimble/host/audio/test/syscfg.yml index f0a8c2c830..cacc00c557 100644 --- a/nimble/host/audio/test/syscfg.yml +++ b/nimble/host/audio/test/syscfg.yml @@ -30,6 +30,8 @@ syscfg.vals: BLE_EXT_ADV: 1 BLE_PERIODIC_ADV: 1 + BLE_PERIODIC_ADV_SYNC_TRANSFER: 1 + BLE_PERIODIC_ADV_SYNC_BIGINFO_REPORTS: 1 BLE_ISO_BROADCAST_SINK: 1 BLE_AUDIO_BROADCAST_SINK: 1