diff mbox series

[BlueZ,2/2] test-bap: Add Broadcast Source STR MBIS tests

Message ID 20240606102541.5395-3-iulia.tanasescu@nxp.com
State Superseded
Headers show
Series test-bap: Add Broadcast Source STR MBIS tests | expand

Commit Message

Iulia Tanasescu June 6, 2024, 10:25 a.m. UTC
4.14.3 Broadcast Audio Stream with Multiple BISes - Source

     Test Purpose:
     Verify that a Broadcast Source IUT can stream multiple
     BISes to a Broadcast Sink.

     Test Case Configuration:
     BAP/BSRC/STR/BV-18-C [BSRC, Multiple BISes, LC3 8_1]
     BAP/BSRC/STR/BV-19-C [BSRC, Multiple BISes, LC3 8_2]
     BAP/BSRC/STR/BV-20-C [BSRC, Multiple BISes, LC3 16_1]
     BAP/BSRC/STR/BV-21-C [BSRC, Multiple BISes, LC3 16_2]
     BAP/BSRC/STR/BV-22-C [BSRC, Multiple BISes, LC3 24_1]
     BAP/BSRC/STR/BV-23-C [BSRC, Multiple BISes, LC3 24_2]
     BAP/BSRC/STR/BV-24-C [BSRC, Multiple BISes, LC3 32_1]
     BAP/BSRC/STR/BV-25-C [BSRC, Multiple BISes, LC3 32_2]
     BAP/BSRC/STR/BV-26-C [BSRC, Multiple BISes, LC3 44.1_1]
     BAP/BSRC/STR/BV-27-C [BSRC, Multiple BISes, LC3 44.1_2]
     BAP/BSRC/STR/BV-28-C [BSRC, Multiple BISes, LC3 48_1]
     BAP/BSRC/STR/BV-29-C [BSRC, Multiple BISes, LC3 48_2]
     BAP/BSRC/STR/BV-30-C [BSRC, Multiple BISes, LC3 48_3]
     BAP/BSRC/STR/BV-31-C [BSRC, Multiple BISes, LC3 48_4]
     BAP/BSRC/STR/BV-32-C [BSRC, Multiple BISes, LC3 48_5]
     BAP/BSRC/STR/BV-33-C [BSRC, Multiple BISes, LC3 48_6]
     BAP/BSRC/STR/BV-34-C [BSRC, Multiple BISes, VS]

     Pass verdict:
     If the Codec ID is LC3, the IUT sends encoded LC3 audio
     data in BIS Data PDUs on each synchronized BIS.

     If the Codec ID is a vendor-specific Codec ID, the IUT
     sends BIS Data PDUs on each synchronized BIS. The parameters
     included in the Codec_Specific_Configuration data are as
     defined in TSPX_VS_Codec_Specific_Configuration.

     If the Codec ID is LC3, each parameter included in
     Codec_Specific_Configuration data is formatted in an LTV
     structure with the length, type, and value specified in
     Table 4.83.

Test Summary
------------
BAP/BSRC/STR/BV-18-C [BSRC, Multiple BISes, LC3 8_1] Passed
BAP/BSRC/STR/BV-19-C [BSRC, Multiple BISes, LC3 8_2] Passed
BAP/BSRC/STR/BV-20-C [BSRC, Multiple BISes, LC3 16_1] Passed
BAP/BSRC/STR/BV-21-C [BSRC, Multiple BISes, LC3 16_2] Passed
BAP/BSRC/STR/BV-22-C [BSRC, Multiple BISes, LC3 24_1] Passed
BAP/BSRC/STR/BV-23-C [BSRC, Multiple BISes, LC3 24_2] Passed
BAP/BSRC/STR/BV-24-C [BSRC, Multiple BISes, LC3 32_1] Passed
BAP/BSRC/STR/BV-25-C [BSRC, Multiple BISes, LC3 32_2] Passed
BAP/BSRC/STR/BV-26-C [BSRC, Multiple BISes, LC3 44.1_1] Passed
BAP/BSRC/STR/BV-27-C [BSRC, Multiple BISes, LC3 44.1_2] Passed
BAP/BSRC/STR/BV-28-C [BSRC, Multiple BISes, LC3 48_1] Passed
BAP/BSRC/STR/BV-29-C [BSRC, Multiple BISes, LC3 48_2] Passed
BAP/BSRC/STR/BV-30-C [BSRC, Multiple BISes, LC3 48_3] Passed
BAP/BSRC/STR/BV-31-C [BSRC, Multiple BISes, LC3 48_4] Passed
BAP/BSRC/STR/BV-32-C [BSRC, Multiple BISes, LC3 48_5] Passed
BAP/BSRC/STR/BV-33-C [BSRC, Multiple BISes, LC3 48_6] Passed
BAP/BSRC/STR/BV-34-C [BSRC, Multiple BISes, VS]      Passed
---
 unit/test-bap.c | 354 ++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 346 insertions(+), 8 deletions(-)

Comments

Luiz Augusto von Dentz June 6, 2024, 8:28 p.m. UTC | #1
Hi Iulia,

On Thu, Jun 6, 2024 at 6:26 AM Iulia Tanasescu <iulia.tanasescu@nxp.com> wrote:
>
> 4.14.3 Broadcast Audio Stream with Multiple BISes - Source
>
>      Test Purpose:
>      Verify that a Broadcast Source IUT can stream multiple
>      BISes to a Broadcast Sink.
>
>      Test Case Configuration:
>      BAP/BSRC/STR/BV-18-C [BSRC, Multiple BISes, LC3 8_1]
>      BAP/BSRC/STR/BV-19-C [BSRC, Multiple BISes, LC3 8_2]
>      BAP/BSRC/STR/BV-20-C [BSRC, Multiple BISes, LC3 16_1]
>      BAP/BSRC/STR/BV-21-C [BSRC, Multiple BISes, LC3 16_2]
>      BAP/BSRC/STR/BV-22-C [BSRC, Multiple BISes, LC3 24_1]
>      BAP/BSRC/STR/BV-23-C [BSRC, Multiple BISes, LC3 24_2]
>      BAP/BSRC/STR/BV-24-C [BSRC, Multiple BISes, LC3 32_1]
>      BAP/BSRC/STR/BV-25-C [BSRC, Multiple BISes, LC3 32_2]
>      BAP/BSRC/STR/BV-26-C [BSRC, Multiple BISes, LC3 44.1_1]
>      BAP/BSRC/STR/BV-27-C [BSRC, Multiple BISes, LC3 44.1_2]
>      BAP/BSRC/STR/BV-28-C [BSRC, Multiple BISes, LC3 48_1]
>      BAP/BSRC/STR/BV-29-C [BSRC, Multiple BISes, LC3 48_2]
>      BAP/BSRC/STR/BV-30-C [BSRC, Multiple BISes, LC3 48_3]
>      BAP/BSRC/STR/BV-31-C [BSRC, Multiple BISes, LC3 48_4]
>      BAP/BSRC/STR/BV-32-C [BSRC, Multiple BISes, LC3 48_5]
>      BAP/BSRC/STR/BV-33-C [BSRC, Multiple BISes, LC3 48_6]
>      BAP/BSRC/STR/BV-34-C [BSRC, Multiple BISes, VS]
>
>      Pass verdict:
>      If the Codec ID is LC3, the IUT sends encoded LC3 audio
>      data in BIS Data PDUs on each synchronized BIS.
>
>      If the Codec ID is a vendor-specific Codec ID, the IUT
>      sends BIS Data PDUs on each synchronized BIS. The parameters
>      included in the Codec_Specific_Configuration data are as
>      defined in TSPX_VS_Codec_Specific_Configuration.
>
>      If the Codec ID is LC3, each parameter included in
>      Codec_Specific_Configuration data is formatted in an LTV
>      structure with the length, type, and value specified in
>      Table 4.83.
>
> Test Summary
> ------------
> BAP/BSRC/STR/BV-18-C [BSRC, Multiple BISes, LC3 8_1] Passed
> BAP/BSRC/STR/BV-19-C [BSRC, Multiple BISes, LC3 8_2] Passed
> BAP/BSRC/STR/BV-20-C [BSRC, Multiple BISes, LC3 16_1] Passed
> BAP/BSRC/STR/BV-21-C [BSRC, Multiple BISes, LC3 16_2] Passed
> BAP/BSRC/STR/BV-22-C [BSRC, Multiple BISes, LC3 24_1] Passed
> BAP/BSRC/STR/BV-23-C [BSRC, Multiple BISes, LC3 24_2] Passed
> BAP/BSRC/STR/BV-24-C [BSRC, Multiple BISes, LC3 32_1] Passed
> BAP/BSRC/STR/BV-25-C [BSRC, Multiple BISes, LC3 32_2] Passed
> BAP/BSRC/STR/BV-26-C [BSRC, Multiple BISes, LC3 44.1_1] Passed
> BAP/BSRC/STR/BV-27-C [BSRC, Multiple BISes, LC3 44.1_2] Passed
> BAP/BSRC/STR/BV-28-C [BSRC, Multiple BISes, LC3 48_1] Passed
> BAP/BSRC/STR/BV-29-C [BSRC, Multiple BISes, LC3 48_2] Passed
> BAP/BSRC/STR/BV-30-C [BSRC, Multiple BISes, LC3 48_3] Passed
> BAP/BSRC/STR/BV-31-C [BSRC, Multiple BISes, LC3 48_4] Passed
> BAP/BSRC/STR/BV-32-C [BSRC, Multiple BISes, LC3 48_5] Passed
> BAP/BSRC/STR/BV-33-C [BSRC, Multiple BISes, LC3 48_6] Passed
> BAP/BSRC/STR/BV-34-C [BSRC, Multiple BISes, VS]      Passed
> ---
>  unit/test-bap.c | 354 ++++++++++++++++++++++++++++++++++++++++++++++--
>  1 file changed, 346 insertions(+), 8 deletions(-)
>
> diff --git a/unit/test-bap.c b/unit/test-bap.c
> index c37f7676f..30c223d16 100644
> --- a/unit/test-bap.c
> +++ b/unit/test-bap.c
> @@ -6972,27 +6972,86 @@ static void test_bsnk_str(void)
>                 NULL, test_bcast, &cfg_bsnk_str_vs_mbis, IOV_NULL);
>  }
>
> +static void stream_count_config(void *data, void *user_data)
> +{
> +       struct bt_bap_stream *stream = data;
> +       uint8_t *streams = user_data;
> +
> +       if (bt_bap_stream_get_state(stream) == BT_BAP_STREAM_STATE_CONFIG)
> +               (*streams)++;
> +}
> +
> +static void stream_count_enabling(void *data, void *user_data)
> +{
> +       struct bt_bap_stream *stream = data;
> +       uint8_t *streams = user_data;
> +
> +       if (bt_bap_stream_get_state(stream) == BT_BAP_STREAM_STATE_ENABLING)
> +               (*streams)++;
> +}
> +
> +static void stream_enable(void *data, void *user_data)
> +{
> +       struct bt_bap_stream *stream = data;
> +
> +       bt_bap_stream_enable(stream, true, NULL, NULL, NULL);
> +}
> +
> +static void stream_start(void *data, void *user_data)
> +{
> +       struct bt_bap_stream *stream = data;
> +
> +       bt_bap_stream_start(stream, NULL, NULL);
> +}
> +
>  static void bsrc_state_str(struct bt_bap_stream *stream, uint8_t old_state,
>                                 uint8_t new_state, void *user_data)
>  {
>         struct test_data *data = user_data;
> +       uint8_t streams = 0;
>
>         switch (new_state) {
>         case BT_BAP_STREAM_STATE_CONFIG:
> -               bt_bap_stream_enable(stream, true, NULL, NULL, NULL);
> +               queue_foreach(data->streams, stream_count_config, &streams);
> +
> +               if (streams == data->cfg->streams)
> +                       /* After all streams have transitioned to CONFIG
> +                        * state, enable each one.
> +                        */
> +                       queue_foreach(data->streams, stream_enable, NULL);
>                 break;
>         case BT_BAP_STREAM_STATE_ENABLING:
> -               data->base = bt_bap_stream_get_base(stream);
> +               queue_foreach(data->streams, stream_count_enabling, &streams);
>
> -               g_assert(data->base);
> -               g_assert(data->base->iov_len == data->cfg->base.iov_len);
> -               g_assert(memcmp(data->base->iov_base, data->cfg->base.iov_base,
> -                               data->base->iov_len) == 0);
> +               if (streams == 1) {
> +                       /* After the first stream has transitioned to ENABLING
> +                        * state, bt_bap_stream_get_base will generate the
> +                        * BASE from all previously configured streams.
> +                        */
> +                       data->base = bt_bap_stream_get_base(stream);
> +
> +                       g_assert(data->base);
> +                       g_assert(data->base->iov_len ==
> +                                       data->cfg->base.iov_len);
> +                       g_assert(memcmp(data->base->iov_base,
> +                                       data->cfg->base.iov_base,
> +                                       data->base->iov_len) == 0);
> +               }
>
> -               bt_bap_stream_start(stream, NULL, NULL);
> +               if (streams == data->cfg->streams)
> +                       /* After all streams have transitioned to ENABLING
> +                        * state, start each one.
> +                        */
> +                       queue_foreach(data->streams, stream_start, NULL);
>                 break;
>         case BT_BAP_STREAM_STATE_STREAMING:
> -               tester_test_passed();
> +               queue_foreach(data->streams, stream_count_streaming, &streams);
> +
> +               if (streams == data->cfg->streams)
> +                       /* Test is completed after all streams have transitioned
> +                        * to STREAMING state.
> +                        */
> +                       tester_test_passed();
>                 break;
>         }
>  }
> @@ -7225,9 +7284,288 @@ static void test_bsrc_str_1b(void)
>                 NULL, test_bcast, &cfg_bsrc_str_vs, IOV_NULL);
>  }
>
> +#define BASE_LC3_8_1_MBIS \
> +       BASE_LC3(40000, 1, 2, LC3_CFG_8_1, 0x00, 0x01, 0x00, 0x02, 0x00)

I wonder if we couldn't define these as part of lc3.h, in fact the
LC3_CFG looks awful similar to LC3_CONFIG from lc3.h, so perhaps we
could do just s/LC3_CFG/LC3_CONFIG and add something like LC3_BASE for
example then rename the existing LC3_BASE to LC3_TYPE(_id), anyway I
can probably do that myself later after merging this just wanted to
check first if you thought about that already.

> +static struct test_config cfg_bsrc_str_8_1_mbis = {
> +       .cc = LC3_CONFIG_8_1,
> +       .qos = LC3_QOS_8_1_1_B,
> +       .base = UTIL_IOV_INIT(BASE_LC3_8_1_MBIS),
> +       .src = true,
> +       .state_func = bsrc_state_str,
> +       .streams = 2,
> +};
> +
> +#define BASE_LC3_8_2_MBIS \
> +       BASE_LC3(40000, 1, 2, LC3_CFG_8_2, 0x00, 0x01, 0x00, 0x02, 0x00)
> +
> +static struct test_config cfg_bsrc_str_8_2_mbis = {
> +       .cc = LC3_CONFIG_8_2,
> +       .qos = LC3_QOS_8_2_1_B,
> +       .base = UTIL_IOV_INIT(BASE_LC3_8_2_MBIS),
> +       .src = true,
> +       .state_func = bsrc_state_str,
> +       .streams = 2,
> +};
> +
> +#define BASE_LC3_16_1_MBIS \
> +       BASE_LC3(40000, 1, 2, LC3_CFG_16_1, 0x00, 0x01, 0x00, 0x02, 0x00)
> +
> +static struct test_config cfg_bsrc_str_16_1_mbis = {
> +       .cc = LC3_CONFIG_16_1,
> +       .qos = LC3_QOS_16_1_1_B,
> +       .base = UTIL_IOV_INIT(BASE_LC3_16_1_MBIS),
> +       .src = true,
> +       .state_func = bsrc_state_str,
> +       .streams = 2,
> +};
> +
> +#define BASE_LC3_16_2_MBIS \
> +       BASE_LC3(40000, 1, 2, LC3_CFG_16_2, 0x00, 0x01, 0x00, 0x02, 0x00)
> +
> +static struct test_config cfg_bsrc_str_16_2_mbis = {
> +       .cc = LC3_CONFIG_16_2,
> +       .qos = LC3_QOS_16_2_1_B,
> +       .base = UTIL_IOV_INIT(BASE_LC3_16_2_MBIS),
> +       .src = true,
> +       .state_func = bsrc_state_str,
> +       .streams = 2,
> +};
> +
> +#define BASE_LC3_24_1_MBIS \
> +       BASE_LC3(40000, 1, 2, LC3_CFG_24_1, 0x00, 0x01, 0x00, 0x02, 0x00)
> +
> +static struct test_config cfg_bsrc_str_24_1_mbis = {
> +       .cc = LC3_CONFIG_24_1,
> +       .qos = LC3_QOS_24_1_1_B,
> +       .base = UTIL_IOV_INIT(BASE_LC3_24_1_MBIS),
> +       .src = true,
> +       .state_func = bsrc_state_str,
> +       .streams = 2,
> +};
> +
> +#define BASE_LC3_24_2_MBIS \
> +       BASE_LC3(40000, 1, 2, LC3_CFG_24_2, 0x00, 0x01, 0x00, 0x02, 0x00)
> +
> +static struct test_config cfg_bsrc_str_24_2_mbis = {
> +       .cc = LC3_CONFIG_24_2,
> +       .qos = LC3_QOS_24_2_1_B,
> +       .base = UTIL_IOV_INIT(BASE_LC3_24_2_MBIS),
> +       .src = true,
> +       .state_func = bsrc_state_str,
> +       .streams = 2,
> +};
> +
> +#define BASE_LC3_32_1_MBIS \
> +       BASE_LC3(40000, 1, 2, LC3_CFG_32_1, 0x00, 0x01, 0x00, 0x02, 0x00)
> +
> +static struct test_config cfg_bsrc_str_32_1_mbis = {
> +       .cc = LC3_CONFIG_32_1,
> +       .qos = LC3_QOS_32_1_1_B,
> +       .base = UTIL_IOV_INIT(BASE_LC3_32_1_MBIS),
> +       .src = true,
> +       .state_func = bsrc_state_str,
> +       .streams = 2,
> +};
> +
> +#define BASE_LC3_32_2_MBIS \
> +       BASE_LC3(40000, 1, 2, LC3_CFG_32_2, 0x00, 0x01, 0x00, 0x02, 0x00)
> +
> +static struct test_config cfg_bsrc_str_32_2_mbis = {
> +       .cc = LC3_CONFIG_32_2,
> +       .qos = LC3_QOS_32_2_1_B,
> +       .base = UTIL_IOV_INIT(BASE_LC3_32_2_MBIS),
> +       .src = true,
> +       .state_func = bsrc_state_str,
> +       .streams = 2,
> +};
> +
> +#define BASE_LC3_44_1_MBIS \
> +       BASE_LC3(40000, 1, 2, LC3_CFG_44_1, 0x00, 0x01, 0x00, 0x02, 0x00)
> +
> +static struct test_config cfg_bsrc_str_44_1_mbis = {
> +       .cc = LC3_CONFIG_44_1,
> +       .qos = LC3_QOS_44_1_1_B,
> +       .base = UTIL_IOV_INIT(BASE_LC3_44_1_MBIS),
> +       .src = true,
> +       .state_func = bsrc_state_str,
> +       .streams = 2,
> +};
> +
> +#define BASE_LC3_44_2_MBIS \
> +       BASE_LC3(40000, 1, 2, LC3_CFG_44_2, 0x00, 0x01, 0x00, 0x02, 0x00)
> +
> +static struct test_config cfg_bsrc_str_44_2_mbis = {
> +       .cc = LC3_CONFIG_44_2,
> +       .qos = LC3_QOS_44_2_1_B,
> +       .base = UTIL_IOV_INIT(BASE_LC3_44_2_MBIS),
> +       .src = true,
> +       .state_func = bsrc_state_str,
> +       .streams = 2,
> +};
> +
> +#define BASE_LC3_48_1_MBIS \
> +       BASE_LC3(40000, 1, 2, LC3_CFG_48_1, 0x00, 0x01, 0x00, 0x02, 0x00)
> +
> +static struct test_config cfg_bsrc_str_48_1_mbis = {
> +       .cc = LC3_CONFIG_48_1,
> +       .qos = LC3_QOS_48_1_1_B,
> +       .base = UTIL_IOV_INIT(BASE_LC3_48_1_MBIS),
> +       .src = true,
> +       .state_func = bsrc_state_str,
> +       .streams = 2,
> +};
> +
> +#define BASE_LC3_48_2_MBIS \
> +       BASE_LC3(40000, 1, 2, LC3_CFG_48_2, 0x00, 0x01, 0x00, 0x02, 0x00)
> +
> +static struct test_config cfg_bsrc_str_48_2_mbis = {
> +       .cc = LC3_CONFIG_48_2,
> +       .qos = LC3_QOS_48_2_1_B,
> +       .base = UTIL_IOV_INIT(BASE_LC3_48_2_MBIS),
> +       .src = true,
> +       .state_func = bsrc_state_str,
> +       .streams = 2,
> +};
> +
> +#define BASE_LC3_48_3_MBIS \
> +       BASE_LC3(40000, 1, 2, LC3_CFG_48_3, 0x00, 0x01, 0x00, 0x02, 0x00)
> +
> +static struct test_config cfg_bsrc_str_48_3_mbis = {
> +       .cc = LC3_CONFIG_48_3,
> +       .qos = LC3_QOS_48_3_1_B,
> +       .base = UTIL_IOV_INIT(BASE_LC3_48_3_MBIS),
> +       .src = true,
> +       .state_func = bsrc_state_str,
> +       .streams = 2,
> +};
> +
> +#define BASE_LC3_48_4_MBIS \
> +       BASE_LC3(40000, 1, 2, LC3_CFG_48_4, 0x00, 0x01, 0x00, 0x02, 0x00)
> +
> +static struct test_config cfg_bsrc_str_48_4_mbis = {
> +       .cc = LC3_CONFIG_48_4,
> +       .qos = LC3_QOS_48_4_1_B,
> +       .base = UTIL_IOV_INIT(BASE_LC3_48_4_MBIS),
> +       .src = true,
> +       .state_func = bsrc_state_str,
> +       .streams = 2,
> +};
> +
> +#define BASE_LC3_48_5_MBIS \
> +       BASE_LC3(40000, 1, 2, LC3_CFG_48_5, 0x00, 0x01, 0x00, 0x02, 0x00)
> +
> +static struct test_config cfg_bsrc_str_48_5_mbis = {
> +       .cc = LC3_CONFIG_48_5,
> +       .qos = LC3_QOS_48_5_1_B,
> +       .base = UTIL_IOV_INIT(BASE_LC3_48_5_MBIS),
> +       .src = true,
> +       .state_func = bsrc_state_str,
> +       .streams = 2,
> +};
> +
> +#define BASE_LC3_48_6_MBIS \
> +       BASE_LC3(40000, 1, 2, LC3_CFG_48_6, 0x00, 0x01, 0x00, 0x02, 0x00)
> +
> +static struct test_config cfg_bsrc_str_48_6_mbis = {
> +       .cc = LC3_CONFIG_48_6,
> +       .qos = LC3_QOS_48_6_1_B,
> +       .base = UTIL_IOV_INIT(BASE_LC3_48_6_MBIS),
> +       .src = true,
> +       .state_func = bsrc_state_str,
> +       .streams = 2,
> +};
> +
> +#define BASE_VS_MBIS \
> +       BASE(40000, 1, 2, 0xFF, 0x00, 0x00, 0x00, 0x00, \
> +       VS_CFG, 0x00, 0x01, 0x00, 0x02, 0x00)
> +
> +static struct test_config cfg_bsrc_str_vs_mbis = {
> +       .cc = UTIL_IOV_INIT(VS_CC),
> +       .qos = QOS_BCAST,
> +       .base = UTIL_IOV_INIT(BASE_VS_MBIS),
> +       .src = true,
> +       .state_func = bsrc_state_str,
> +       .vs = true,
> +       .streams = 2,
> +};
> +
> +/* Test Purpose:
> + * Verify that a Broadcast Source IUT can stream multiple BISes to
> + * a Broadcast Sink. The verification is performed for each set of
> + * parameters in turn, as specified in Table 4.82.
> + *
> + * Pass verdict:
> + * If the Codec ID is LC3, the IUT sends encoded LC3 audio data in
> + * BIS Data PDUs on each synchronized BIS.
> + *
> + * If the Codec ID is a vendor-specific Codec ID, the IUT sends BIS
> + * Data PDUs on each synchronized BIS. The parameters included in the
> + * Codec_Specific_Configuration data are as defined in
> + * TSPX_VS_Codec_Specific_Configuration.
> + *
> + * If the Codec ID is LC3, each parameter included in
> + * Codec_Specific_Configuration data is formatted in an LTV structure
> + * with the length, type, and value specified in Table 4.83.
> + */
> +static void test_bsrc_str_2b(void)
> +{
> +       define_test("BAP/BSRC/STR/BV-18-C [BSRC, Multiple BISes, LC3 8_1]",
> +               NULL, test_bcast, &cfg_bsrc_str_8_1_mbis, IOV_NULL);
> +
> +       define_test("BAP/BSRC/STR/BV-19-C [BSRC, Multiple BISes, LC3 8_2]",
> +               NULL, test_bcast, &cfg_bsrc_str_8_2_mbis, IOV_NULL);
> +
> +       define_test("BAP/BSRC/STR/BV-20-C [BSRC, Multiple BISes, LC3 16_1]",
> +               NULL, test_bcast, &cfg_bsrc_str_16_1_mbis, IOV_NULL);
> +
> +       define_test("BAP/BSRC/STR/BV-21-C [BSRC, Multiple BISes, LC3 16_2]",
> +               NULL, test_bcast, &cfg_bsrc_str_16_2_mbis, IOV_NULL);
> +
> +       define_test("BAP/BSRC/STR/BV-22-C [BSRC, Multiple BISes, LC3 24_1]",
> +               NULL, test_bcast, &cfg_bsrc_str_24_1_mbis, IOV_NULL);
> +
> +       define_test("BAP/BSRC/STR/BV-23-C [BSRC, Multiple BISes, LC3 24_2]",
> +               NULL, test_bcast, &cfg_bsrc_str_24_2_mbis, IOV_NULL);
> +
> +       define_test("BAP/BSRC/STR/BV-24-C [BSRC, Multiple BISes, LC3 32_1]",
> +               NULL, test_bcast, &cfg_bsrc_str_32_1_mbis, IOV_NULL);
> +
> +       define_test("BAP/BSRC/STR/BV-25-C [BSRC, Multiple BISes, LC3 32_2]",
> +               NULL, test_bcast, &cfg_bsrc_str_32_2_mbis, IOV_NULL);
> +
> +       define_test("BAP/BSRC/STR/BV-26-C [BSRC, Multiple BISes, LC3 44.1_1]",
> +               NULL, test_bcast, &cfg_bsrc_str_44_1_mbis, IOV_NULL);
> +
> +       define_test("BAP/BSRC/STR/BV-27-C [BSRC, Multiple BISes, LC3 44.1_2]",
> +               NULL, test_bcast, &cfg_bsrc_str_44_2_mbis, IOV_NULL);
> +
> +       define_test("BAP/BSRC/STR/BV-28-C [BSRC, Multiple BISes, LC3 48_1]",
> +               NULL, test_bcast, &cfg_bsrc_str_48_1_mbis, IOV_NULL);
> +
> +       define_test("BAP/BSRC/STR/BV-29-C [BSRC, Multiple BISes, LC3 48_2]",
> +               NULL, test_bcast, &cfg_bsrc_str_48_2_mbis, IOV_NULL);
> +
> +       define_test("BAP/BSRC/STR/BV-30-C [BSRC, Multiple BISes, LC3 48_3]",
> +               NULL, test_bcast, &cfg_bsrc_str_48_3_mbis, IOV_NULL);
> +
> +       define_test("BAP/BSRC/STR/BV-31-C [BSRC, Multiple BISes, LC3 48_4]",
> +               NULL, test_bcast, &cfg_bsrc_str_48_4_mbis, IOV_NULL);
> +
> +       define_test("BAP/BSRC/STR/BV-32-C [BSRC, Multiple BISes, LC3 48_5]",
> +               NULL, test_bcast, &cfg_bsrc_str_48_5_mbis, IOV_NULL);
> +
> +       define_test("BAP/BSRC/STR/BV-33-C [BSRC, Multiple BISes, LC3 48_6]",
> +               NULL, test_bcast, &cfg_bsrc_str_48_6_mbis, IOV_NULL);
> +
> +       define_test("BAP/BSRC/STR/BV-34-C [BSRC, Multiple BISes, VS]",
> +               NULL, test_bcast, &cfg_bsrc_str_vs_mbis, IOV_NULL);
> +}
> +
>  static void test_bsrc_str(void)
>  {
>         test_bsrc_str_1b();
> +       test_bsrc_str_2b();
>  }
>
>  int main(int argc, char *argv[])
> --
> 2.39.2
>
Iulia Tanasescu June 10, 2024, 7:23 a.m. UTC | #2
Hi Luiz,

> -----Original Message-----
> From: Luiz Augusto von Dentz <luiz.dentz@gmail.com>
> Sent: Thursday, June 6, 2024 11:29 PM
> To: Iulia Tanasescu <iulia.tanasescu@nxp.com>
> Cc: linux-bluetooth@vger.kernel.org; Claudia Cristina Draghicescu
> <claudia.rosu@nxp.com>; Mihai-Octavian Urzica <mihai-
> octavian.urzica@nxp.com>; Vlad Pruteanu <vlad.pruteanu@nxp.com>;
> Andrei Istodorescu <andrei.istodorescu@nxp.com>
> Subject: Re: [PATCH BlueZ 2/2] test-bap: Add Broadcast Source STR
> MBIS tests
> 
> Hi Iulia,
> 
> On Thu, Jun 6, 2024 at 6:26 AM Iulia Tanasescu <iulia.tanasescu@nxp.com>
> wrote:
> >
> > 4.14.3 Broadcast Audio Stream with Multiple BISes - Source
> >
> >      Test Purpose:
> >      Verify that a Broadcast Source IUT can stream multiple
> >      BISes to a Broadcast Sink.
> >
> >      Test Case Configuration:
> >      BAP/BSRC/STR/BV-18-C [BSRC, Multiple BISes, LC3 8_1]
> >      BAP/BSRC/STR/BV-19-C [BSRC, Multiple BISes, LC3 8_2]
> >      BAP/BSRC/STR/BV-20-C [BSRC, Multiple BISes, LC3 16_1]
> >      BAP/BSRC/STR/BV-21-C [BSRC, Multiple BISes, LC3 16_2]
> >      BAP/BSRC/STR/BV-22-C [BSRC, Multiple BISes, LC3 24_1]
> >      BAP/BSRC/STR/BV-23-C [BSRC, Multiple BISes, LC3 24_2]
> >      BAP/BSRC/STR/BV-24-C [BSRC, Multiple BISes, LC3 32_1]
> >      BAP/BSRC/STR/BV-25-C [BSRC, Multiple BISes, LC3 32_2]
> >      BAP/BSRC/STR/BV-26-C [BSRC, Multiple BISes, LC3 44.1_1]
> >      BAP/BSRC/STR/BV-27-C [BSRC, Multiple BISes, LC3 44.1_2]
> >      BAP/BSRC/STR/BV-28-C [BSRC, Multiple BISes, LC3 48_1]
> >      BAP/BSRC/STR/BV-29-C [BSRC, Multiple BISes, LC3 48_2]
> >      BAP/BSRC/STR/BV-30-C [BSRC, Multiple BISes, LC3 48_3]
> >      BAP/BSRC/STR/BV-31-C [BSRC, Multiple BISes, LC3 48_4]
> >      BAP/BSRC/STR/BV-32-C [BSRC, Multiple BISes, LC3 48_5]
> >      BAP/BSRC/STR/BV-33-C [BSRC, Multiple BISes, LC3 48_6]
> >      BAP/BSRC/STR/BV-34-C [BSRC, Multiple BISes, VS]
> >
> >      Pass verdict:
> >      If the Codec ID is LC3, the IUT sends encoded LC3 audio
> >      data in BIS Data PDUs on each synchronized BIS.
> >
> >      If the Codec ID is a vendor-specific Codec ID, the IUT
> >      sends BIS Data PDUs on each synchronized BIS. The parameters
> >      included in the Codec_Specific_Configuration data are as
> >      defined in TSPX_VS_Codec_Specific_Configuration.
> >
> >      If the Codec ID is LC3, each parameter included in
> >      Codec_Specific_Configuration data is formatted in an LTV
> >      structure with the length, type, and value specified in
> >      Table 4.83.
> >
> > Test Summary
> > ------------
> > BAP/BSRC/STR/BV-18-C [BSRC, Multiple BISes, LC3 8_1] Passed
> > BAP/BSRC/STR/BV-19-C [BSRC, Multiple BISes, LC3 8_2] Passed
> > BAP/BSRC/STR/BV-20-C [BSRC, Multiple BISes, LC3 16_1] Passed
> > BAP/BSRC/STR/BV-21-C [BSRC, Multiple BISes, LC3 16_2] Passed
> > BAP/BSRC/STR/BV-22-C [BSRC, Multiple BISes, LC3 24_1] Passed
> > BAP/BSRC/STR/BV-23-C [BSRC, Multiple BISes, LC3 24_2] Passed
> > BAP/BSRC/STR/BV-24-C [BSRC, Multiple BISes, LC3 32_1] Passed
> > BAP/BSRC/STR/BV-25-C [BSRC, Multiple BISes, LC3 32_2] Passed
> > BAP/BSRC/STR/BV-26-C [BSRC, Multiple BISes, LC3 44.1_1] Passed
> > BAP/BSRC/STR/BV-27-C [BSRC, Multiple BISes, LC3 44.1_2] Passed
> > BAP/BSRC/STR/BV-28-C [BSRC, Multiple BISes, LC3 48_1] Passed
> > BAP/BSRC/STR/BV-29-C [BSRC, Multiple BISes, LC3 48_2] Passed
> > BAP/BSRC/STR/BV-30-C [BSRC, Multiple BISes, LC3 48_3] Passed
> > BAP/BSRC/STR/BV-31-C [BSRC, Multiple BISes, LC3 48_4] Passed
> > BAP/BSRC/STR/BV-32-C [BSRC, Multiple BISes, LC3 48_5] Passed
> > BAP/BSRC/STR/BV-33-C [BSRC, Multiple BISes, LC3 48_6] Passed
> > BAP/BSRC/STR/BV-34-C [BSRC, Multiple BISes, VS]      Passed
> > ---
> >  unit/test-bap.c | 354
> > ++++++++++++++++++++++++++++++++++++++++++++++--
> >  1 file changed, 346 insertions(+), 8 deletions(-)
> >
> > diff --git a/unit/test-bap.c b/unit/test-bap.c index
> > c37f7676f..30c223d16 100644
> > --- a/unit/test-bap.c
> > +++ b/unit/test-bap.c
> > @@ -6972,27 +6972,86 @@ static void test_bsnk_str(void)
> >                 NULL, test_bcast, &cfg_bsnk_str_vs_mbis, IOV_NULL);  }
> >
> > +static void stream_count_config(void *data, void *user_data) {
> > +       struct bt_bap_stream *stream = data;
> > +       uint8_t *streams = user_data;
> > +
> > +       if (bt_bap_stream_get_state(stream) ==
> BT_BAP_STREAM_STATE_CONFIG)
> > +               (*streams)++;
> > +}
> > +
> > +static void stream_count_enabling(void *data, void *user_data) {
> > +       struct bt_bap_stream *stream = data;
> > +       uint8_t *streams = user_data;
> > +
> > +       if (bt_bap_stream_get_state(stream) ==
> BT_BAP_STREAM_STATE_ENABLING)
> > +               (*streams)++;
> > +}
> > +
> > +static void stream_enable(void *data, void *user_data) {
> > +       struct bt_bap_stream *stream = data;
> > +
> > +       bt_bap_stream_enable(stream, true, NULL, NULL, NULL); }
> > +
> > +static void stream_start(void *data, void *user_data) {
> > +       struct bt_bap_stream *stream = data;
> > +
> > +       bt_bap_stream_start(stream, NULL, NULL); }
> > +
> >  static void bsrc_state_str(struct bt_bap_stream *stream, uint8_t old_state,
> >                                 uint8_t new_state, void *user_data)  {
> >         struct test_data *data = user_data;
> > +       uint8_t streams = 0;
> >
> >         switch (new_state) {
> >         case BT_BAP_STREAM_STATE_CONFIG:
> > -               bt_bap_stream_enable(stream, true, NULL, NULL, NULL);
> > +               queue_foreach(data->streams, stream_count_config, &streams);
> > +
> > +               if (streams == data->cfg->streams)
> > +                       /* After all streams have transitioned to CONFIG
> > +                        * state, enable each one.
> > +                        */
> > +                       queue_foreach(data->streams, stream_enable, NULL);
> >                 break;
> >         case BT_BAP_STREAM_STATE_ENABLING:
> > -               data->base = bt_bap_stream_get_base(stream);
> > +               queue_foreach(data->streams, stream_count_enabling,
> &streams);
> >
> > -               g_assert(data->base);
> > -               g_assert(data->base->iov_len == data->cfg->base.iov_len);
> > -               g_assert(memcmp(data->base->iov_base, data->cfg-
> >base.iov_base,
> > -                               data->base->iov_len) == 0);
> > +               if (streams == 1) {
> > +                       /* After the first stream has transitioned to ENABLING
> > +                        * state, bt_bap_stream_get_base will generate the
> > +                        * BASE from all previously configured streams.
> > +                        */
> > +                       data->base = bt_bap_stream_get_base(stream);
> > +
> > +                       g_assert(data->base);
> > +                       g_assert(data->base->iov_len ==
> > +                                       data->cfg->base.iov_len);
> > +                       g_assert(memcmp(data->base->iov_base,
> > +                                       data->cfg->base.iov_base,
> > +                                       data->base->iov_len) == 0);
> > +               }
> >
> > -               bt_bap_stream_start(stream, NULL, NULL);
> > +               if (streams == data->cfg->streams)
> > +                       /* After all streams have transitioned to ENABLING
> > +                        * state, start each one.
> > +                        */
> > +                       queue_foreach(data->streams, stream_start, NULL);
> >                 break;
> >         case BT_BAP_STREAM_STATE_STREAMING:
> > -               tester_test_passed();
> > +               queue_foreach(data->streams, stream_count_streaming,
> &streams);
> > +
> > +               if (streams == data->cfg->streams)
> > +                       /* Test is completed after all streams have transitioned
> > +                        * to STREAMING state.
> > +                        */
> > +                       tester_test_passed();
> >                 break;
> >         }
> >  }
> > @@ -7225,9 +7284,288 @@ static void test_bsrc_str_1b(void)
> >                 NULL, test_bcast, &cfg_bsrc_str_vs, IOV_NULL);
> >  }
> >
> > +#define BASE_LC3_8_1_MBIS \
> > +       BASE_LC3(40000, 1, 2, LC3_CFG_8_1, 0x00, 0x01, 0x00, 0x02, 0x00)
> 
> I wonder if we couldn't define these as part of lc3.h, in fact the
> LC3_CFG looks awful similar to LC3_CONFIG from lc3.h, so perhaps we
> could do just s/LC3_CFG/LC3_CONFIG and add something like LC3_BASE for
> example then rename the existing LC3_BASE to LC3_TYPE(_id), anyway I
> can probably do that myself later after merging this just wanted to
> check first if you thought about that already.

I added LC3_CFG because LC3_CONFIG from lc3.h defines a iovec struct,
while I needed some byte array to include in BASE_LC3. But I do think
it would be useful to add the BASE defines to lc3.h, and they could be
used for iso-tester as well.

> 
> > +static struct test_config cfg_bsrc_str_8_1_mbis = {
> > +       .cc = LC3_CONFIG_8_1,
> > +       .qos = LC3_QOS_8_1_1_B,
> > +       .base = UTIL_IOV_INIT(BASE_LC3_8_1_MBIS),
> > +       .src = true,
> > +       .state_func = bsrc_state_str,
> > +       .streams = 2,
> > +};
> > +
> > +#define BASE_LC3_8_2_MBIS \
> > +       BASE_LC3(40000, 1, 2, LC3_CFG_8_2, 0x00, 0x01, 0x00, 0x02, 0x00)
> > +
> > +static struct test_config cfg_bsrc_str_8_2_mbis = {
> > +       .cc = LC3_CONFIG_8_2,
> > +       .qos = LC3_QOS_8_2_1_B,
> > +       .base = UTIL_IOV_INIT(BASE_LC3_8_2_MBIS),
> > +       .src = true,
> > +       .state_func = bsrc_state_str,
> > +       .streams = 2,
> > +};
> > +
> > +#define BASE_LC3_16_1_MBIS \
> > +       BASE_LC3(40000, 1, 2, LC3_CFG_16_1, 0x00, 0x01, 0x00, 0x02, 0x00)
> > +
> > +static struct test_config cfg_bsrc_str_16_1_mbis = {
> > +       .cc = LC3_CONFIG_16_1,
> > +       .qos = LC3_QOS_16_1_1_B,
> > +       .base = UTIL_IOV_INIT(BASE_LC3_16_1_MBIS),
> > +       .src = true,
> > +       .state_func = bsrc_state_str,
> > +       .streams = 2,
> > +};
> > +
> > +#define BASE_LC3_16_2_MBIS \
> > +       BASE_LC3(40000, 1, 2, LC3_CFG_16_2, 0x00, 0x01, 0x00, 0x02, 0x00)
> > +
> > +static struct test_config cfg_bsrc_str_16_2_mbis = {
> > +       .cc = LC3_CONFIG_16_2,
> > +       .qos = LC3_QOS_16_2_1_B,
> > +       .base = UTIL_IOV_INIT(BASE_LC3_16_2_MBIS),
> > +       .src = true,
> > +       .state_func = bsrc_state_str,
> > +       .streams = 2,
> > +};
> > +
> > +#define BASE_LC3_24_1_MBIS \
> > +       BASE_LC3(40000, 1, 2, LC3_CFG_24_1, 0x00, 0x01, 0x00, 0x02, 0x00)
> > +
> > +static struct test_config cfg_bsrc_str_24_1_mbis = {
> > +       .cc = LC3_CONFIG_24_1,
> > +       .qos = LC3_QOS_24_1_1_B,
> > +       .base = UTIL_IOV_INIT(BASE_LC3_24_1_MBIS),
> > +       .src = true,
> > +       .state_func = bsrc_state_str,
> > +       .streams = 2,
> > +};
> > +
> > +#define BASE_LC3_24_2_MBIS \
> > +       BASE_LC3(40000, 1, 2, LC3_CFG_24_2, 0x00, 0x01, 0x00, 0x02, 0x00)
> > +
> > +static struct test_config cfg_bsrc_str_24_2_mbis = {
> > +       .cc = LC3_CONFIG_24_2,
> > +       .qos = LC3_QOS_24_2_1_B,
> > +       .base = UTIL_IOV_INIT(BASE_LC3_24_2_MBIS),
> > +       .src = true,
> > +       .state_func = bsrc_state_str,
> > +       .streams = 2,
> > +};
> > +
> > +#define BASE_LC3_32_1_MBIS \
> > +       BASE_LC3(40000, 1, 2, LC3_CFG_32_1, 0x00, 0x01, 0x00, 0x02, 0x00)
> > +
> > +static struct test_config cfg_bsrc_str_32_1_mbis = {
> > +       .cc = LC3_CONFIG_32_1,
> > +       .qos = LC3_QOS_32_1_1_B,
> > +       .base = UTIL_IOV_INIT(BASE_LC3_32_1_MBIS),
> > +       .src = true,
> > +       .state_func = bsrc_state_str,
> > +       .streams = 2,
> > +};
> > +
> > +#define BASE_LC3_32_2_MBIS \
> > +       BASE_LC3(40000, 1, 2, LC3_CFG_32_2, 0x00, 0x01, 0x00, 0x02, 0x00)
> > +
> > +static struct test_config cfg_bsrc_str_32_2_mbis = {
> > +       .cc = LC3_CONFIG_32_2,
> > +       .qos = LC3_QOS_32_2_1_B,
> > +       .base = UTIL_IOV_INIT(BASE_LC3_32_2_MBIS),
> > +       .src = true,
> > +       .state_func = bsrc_state_str,
> > +       .streams = 2,
> > +};
> > +
> > +#define BASE_LC3_44_1_MBIS \
> > +       BASE_LC3(40000, 1, 2, LC3_CFG_44_1, 0x00, 0x01, 0x00, 0x02, 0x00)
> > +
> > +static struct test_config cfg_bsrc_str_44_1_mbis = {
> > +       .cc = LC3_CONFIG_44_1,
> > +       .qos = LC3_QOS_44_1_1_B,
> > +       .base = UTIL_IOV_INIT(BASE_LC3_44_1_MBIS),
> > +       .src = true,
> > +       .state_func = bsrc_state_str,
> > +       .streams = 2,
> > +};
> > +
> > +#define BASE_LC3_44_2_MBIS \
> > +       BASE_LC3(40000, 1, 2, LC3_CFG_44_2, 0x00, 0x01, 0x00, 0x02, 0x00)
> > +
> > +static struct test_config cfg_bsrc_str_44_2_mbis = {
> > +       .cc = LC3_CONFIG_44_2,
> > +       .qos = LC3_QOS_44_2_1_B,
> > +       .base = UTIL_IOV_INIT(BASE_LC3_44_2_MBIS),
> > +       .src = true,
> > +       .state_func = bsrc_state_str,
> > +       .streams = 2,
> > +};
> > +
> > +#define BASE_LC3_48_1_MBIS \
> > +       BASE_LC3(40000, 1, 2, LC3_CFG_48_1, 0x00, 0x01, 0x00, 0x02, 0x00)
> > +
> > +static struct test_config cfg_bsrc_str_48_1_mbis = {
> > +       .cc = LC3_CONFIG_48_1,
> > +       .qos = LC3_QOS_48_1_1_B,
> > +       .base = UTIL_IOV_INIT(BASE_LC3_48_1_MBIS),
> > +       .src = true,
> > +       .state_func = bsrc_state_str,
> > +       .streams = 2,
> > +};
> > +
> > +#define BASE_LC3_48_2_MBIS \
> > +       BASE_LC3(40000, 1, 2, LC3_CFG_48_2, 0x00, 0x01, 0x00, 0x02, 0x00)
> > +
> > +static struct test_config cfg_bsrc_str_48_2_mbis = {
> > +       .cc = LC3_CONFIG_48_2,
> > +       .qos = LC3_QOS_48_2_1_B,
> > +       .base = UTIL_IOV_INIT(BASE_LC3_48_2_MBIS),
> > +       .src = true,
> > +       .state_func = bsrc_state_str,
> > +       .streams = 2,
> > +};
> > +
> > +#define BASE_LC3_48_3_MBIS \
> > +       BASE_LC3(40000, 1, 2, LC3_CFG_48_3, 0x00, 0x01, 0x00, 0x02, 0x00)
> > +
> > +static struct test_config cfg_bsrc_str_48_3_mbis = {
> > +       .cc = LC3_CONFIG_48_3,
> > +       .qos = LC3_QOS_48_3_1_B,
> > +       .base = UTIL_IOV_INIT(BASE_LC3_48_3_MBIS),
> > +       .src = true,
> > +       .state_func = bsrc_state_str,
> > +       .streams = 2,
> > +};
> > +
> > +#define BASE_LC3_48_4_MBIS \
> > +       BASE_LC3(40000, 1, 2, LC3_CFG_48_4, 0x00, 0x01, 0x00, 0x02, 0x00)
> > +
> > +static struct test_config cfg_bsrc_str_48_4_mbis = {
> > +       .cc = LC3_CONFIG_48_4,
> > +       .qos = LC3_QOS_48_4_1_B,
> > +       .base = UTIL_IOV_INIT(BASE_LC3_48_4_MBIS),
> > +       .src = true,
> > +       .state_func = bsrc_state_str,
> > +       .streams = 2,
> > +};
> > +
> > +#define BASE_LC3_48_5_MBIS \
> > +       BASE_LC3(40000, 1, 2, LC3_CFG_48_5, 0x00, 0x01, 0x00, 0x02, 0x00)
> > +
> > +static struct test_config cfg_bsrc_str_48_5_mbis = {
> > +       .cc = LC3_CONFIG_48_5,
> > +       .qos = LC3_QOS_48_5_1_B,
> > +       .base = UTIL_IOV_INIT(BASE_LC3_48_5_MBIS),
> > +       .src = true,
> > +       .state_func = bsrc_state_str,
> > +       .streams = 2,
> > +};
> > +
> > +#define BASE_LC3_48_6_MBIS \
> > +       BASE_LC3(40000, 1, 2, LC3_CFG_48_6, 0x00, 0x01, 0x00, 0x02, 0x00)
> > +
> > +static struct test_config cfg_bsrc_str_48_6_mbis = {
> > +       .cc = LC3_CONFIG_48_6,
> > +       .qos = LC3_QOS_48_6_1_B,
> > +       .base = UTIL_IOV_INIT(BASE_LC3_48_6_MBIS),
> > +       .src = true,
> > +       .state_func = bsrc_state_str,
> > +       .streams = 2,
> > +};
> > +
> > +#define BASE_VS_MBIS \
> > +       BASE(40000, 1, 2, 0xFF, 0x00, 0x00, 0x00, 0x00, \
> > +       VS_CFG, 0x00, 0x01, 0x00, 0x02, 0x00)
> > +
> > +static struct test_config cfg_bsrc_str_vs_mbis = {
> > +       .cc = UTIL_IOV_INIT(VS_CC),
> > +       .qos = QOS_BCAST,
> > +       .base = UTIL_IOV_INIT(BASE_VS_MBIS),
> > +       .src = true,
> > +       .state_func = bsrc_state_str,
> > +       .vs = true,
> > +       .streams = 2,
> > +};
> > +
> > +/* Test Purpose:
> > + * Verify that a Broadcast Source IUT can stream multiple BISes to
> > + * a Broadcast Sink. The verification is performed for each set of
> > + * parameters in turn, as specified in Table 4.82.
> > + *
> > + * Pass verdict:
> > + * If the Codec ID is LC3, the IUT sends encoded LC3 audio data in
> > + * BIS Data PDUs on each synchronized BIS.
> > + *
> > + * If the Codec ID is a vendor-specific Codec ID, the IUT sends BIS
> > + * Data PDUs on each synchronized BIS. The parameters included in the
> > + * Codec_Specific_Configuration data are as defined in
> > + * TSPX_VS_Codec_Specific_Configuration.
> > + *
> > + * If the Codec ID is LC3, each parameter included in
> > + * Codec_Specific_Configuration data is formatted in an LTV structure
> > + * with the length, type, and value specified in Table 4.83.
> > + */
> > +static void test_bsrc_str_2b(void)
> > +{
> > +       define_test("BAP/BSRC/STR/BV-18-C [BSRC, Multiple BISes, LC3 8_1]",
> > +               NULL, test_bcast, &cfg_bsrc_str_8_1_mbis, IOV_NULL);
> > +
> > +       define_test("BAP/BSRC/STR/BV-19-C [BSRC, Multiple BISes, LC3 8_2]",
> > +               NULL, test_bcast, &cfg_bsrc_str_8_2_mbis, IOV_NULL);
> > +
> > +       define_test("BAP/BSRC/STR/BV-20-C [BSRC, Multiple BISes, LC3
> 16_1]",
> > +               NULL, test_bcast, &cfg_bsrc_str_16_1_mbis, IOV_NULL);
> > +
> > +       define_test("BAP/BSRC/STR/BV-21-C [BSRC, Multiple BISes, LC3
> 16_2]",
> > +               NULL, test_bcast, &cfg_bsrc_str_16_2_mbis, IOV_NULL);
> > +
> > +       define_test("BAP/BSRC/STR/BV-22-C [BSRC, Multiple BISes, LC3
> 24_1]",
> > +               NULL, test_bcast, &cfg_bsrc_str_24_1_mbis, IOV_NULL);
> > +
> > +       define_test("BAP/BSRC/STR/BV-23-C [BSRC, Multiple BISes, LC3
> 24_2]",
> > +               NULL, test_bcast, &cfg_bsrc_str_24_2_mbis, IOV_NULL);
> > +
> > +       define_test("BAP/BSRC/STR/BV-24-C [BSRC, Multiple BISes, LC3
> 32_1]",
> > +               NULL, test_bcast, &cfg_bsrc_str_32_1_mbis, IOV_NULL);
> > +
> > +       define_test("BAP/BSRC/STR/BV-25-C [BSRC, Multiple BISes, LC3
> 32_2]",
> > +               NULL, test_bcast, &cfg_bsrc_str_32_2_mbis, IOV_NULL);
> > +
> > +       define_test("BAP/BSRC/STR/BV-26-C [BSRC, Multiple BISes, LC3
> 44.1_1]",
> > +               NULL, test_bcast, &cfg_bsrc_str_44_1_mbis, IOV_NULL);
> > +
> > +       define_test("BAP/BSRC/STR/BV-27-C [BSRC, Multiple BISes, LC3
> 44.1_2]",
> > +               NULL, test_bcast, &cfg_bsrc_str_44_2_mbis, IOV_NULL);
> > +
> > +       define_test("BAP/BSRC/STR/BV-28-C [BSRC, Multiple BISes, LC3
> 48_1]",
> > +               NULL, test_bcast, &cfg_bsrc_str_48_1_mbis, IOV_NULL);
> > +
> > +       define_test("BAP/BSRC/STR/BV-29-C [BSRC, Multiple BISes, LC3
> 48_2]",
> > +               NULL, test_bcast, &cfg_bsrc_str_48_2_mbis, IOV_NULL);
> > +
> > +       define_test("BAP/BSRC/STR/BV-30-C [BSRC, Multiple BISes, LC3
> 48_3]",
> > +               NULL, test_bcast, &cfg_bsrc_str_48_3_mbis, IOV_NULL);
> > +
> > +       define_test("BAP/BSRC/STR/BV-31-C [BSRC, Multiple BISes, LC3
> 48_4]",
> > +               NULL, test_bcast, &cfg_bsrc_str_48_4_mbis, IOV_NULL);
> > +
> > +       define_test("BAP/BSRC/STR/BV-32-C [BSRC, Multiple BISes, LC3
> 48_5]",
> > +               NULL, test_bcast, &cfg_bsrc_str_48_5_mbis, IOV_NULL);
> > +
> > +       define_test("BAP/BSRC/STR/BV-33-C [BSRC, Multiple BISes, LC3
> 48_6]",
> > +               NULL, test_bcast, &cfg_bsrc_str_48_6_mbis, IOV_NULL);
> > +
> > +       define_test("BAP/BSRC/STR/BV-34-C [BSRC, Multiple BISes, VS]",
> > +               NULL, test_bcast, &cfg_bsrc_str_vs_mbis, IOV_NULL);
> > +}
> > +
> >  static void test_bsrc_str(void)
> >  {
> >         test_bsrc_str_1b();
> > +       test_bsrc_str_2b();
> >  }
> >
> >  int main(int argc, char *argv[])
> > --
> > 2.39.2
> >
> 
> 
> --
> Luiz Augusto von Dentz


Regards,
Iulia
Iulia Tanasescu June 20, 2024, 2:22 p.m. UTC | #3
Hi Luiz,

> -----Original Message-----
> From: Iulia Tanasescu
> Sent: Monday, June 10, 2024 10:24 AM
> To: luiz.dentz@gmail.com
> Cc: Andrei Istodorescu <andrei.istodorescu@nxp.com>; Claudia Cristina
> Draghicescu <claudia.rosu@nxp.com>; Iulia Tanasescu
> <iulia.tanasescu@nxp.com>; linux-bluetooth@vger.kernel.org; Mihai-
> Octavian Urzica <mihai-octavian.urzica@nxp.com>; Vlad Pruteanu
> <vlad.pruteanu@nxp.com>
> Subject: Re: [PATCH BlueZ 2/2] test-bap: Add Broadcast Source STR MBIS
> tests
> 
> Hi Luiz,
> 
> > -----Original Message-----
> > From: Luiz Augusto von Dentz <luiz.dentz@gmail.com>
> > Sent: Thursday, June 6, 2024 11:29 PM
> > To: Iulia Tanasescu <iulia.tanasescu@nxp.com>
> > Cc: linux-bluetooth@vger.kernel.org; Claudia Cristina Draghicescu
> > <claudia.rosu@nxp.com>; Mihai-Octavian Urzica <mihai-
> > octavian.urzica@nxp.com>; Vlad Pruteanu <vlad.pruteanu@nxp.com>;
> > Andrei Istodorescu <andrei.istodorescu@nxp.com>
> > Subject: Re: [PATCH BlueZ 2/2] test-bap: Add Broadcast Source STR MBIS
> > tests
> >
> > Hi Iulia,
> >
> > On Thu, Jun 6, 2024 at 6:26 AM Iulia Tanasescu
> > <iulia.tanasescu@nxp.com>
> > wrote:
> > >
> > > 4.14.3 Broadcast Audio Stream with Multiple BISes - Source
> > >
> > >      Test Purpose:
> > >      Verify that a Broadcast Source IUT can stream multiple
> > >      BISes to a Broadcast Sink.
> > >
> > >      Test Case Configuration:
> > >      BAP/BSRC/STR/BV-18-C [BSRC, Multiple BISes, LC3 8_1]
> > >      BAP/BSRC/STR/BV-19-C [BSRC, Multiple BISes, LC3 8_2]
> > >      BAP/BSRC/STR/BV-20-C [BSRC, Multiple BISes, LC3 16_1]
> > >      BAP/BSRC/STR/BV-21-C [BSRC, Multiple BISes, LC3 16_2]
> > >      BAP/BSRC/STR/BV-22-C [BSRC, Multiple BISes, LC3 24_1]
> > >      BAP/BSRC/STR/BV-23-C [BSRC, Multiple BISes, LC3 24_2]
> > >      BAP/BSRC/STR/BV-24-C [BSRC, Multiple BISes, LC3 32_1]
> > >      BAP/BSRC/STR/BV-25-C [BSRC, Multiple BISes, LC3 32_2]
> > >      BAP/BSRC/STR/BV-26-C [BSRC, Multiple BISes, LC3 44.1_1]
> > >      BAP/BSRC/STR/BV-27-C [BSRC, Multiple BISes, LC3 44.1_2]
> > >      BAP/BSRC/STR/BV-28-C [BSRC, Multiple BISes, LC3 48_1]
> > >      BAP/BSRC/STR/BV-29-C [BSRC, Multiple BISes, LC3 48_2]
> > >      BAP/BSRC/STR/BV-30-C [BSRC, Multiple BISes, LC3 48_3]
> > >      BAP/BSRC/STR/BV-31-C [BSRC, Multiple BISes, LC3 48_4]
> > >      BAP/BSRC/STR/BV-32-C [BSRC, Multiple BISes, LC3 48_5]
> > >      BAP/BSRC/STR/BV-33-C [BSRC, Multiple BISes, LC3 48_6]
> > >      BAP/BSRC/STR/BV-34-C [BSRC, Multiple BISes, VS]
> > >
> > >      Pass verdict:
> > >      If the Codec ID is LC3, the IUT sends encoded LC3 audio
> > >      data in BIS Data PDUs on each synchronized BIS.
> > >
> > >      If the Codec ID is a vendor-specific Codec ID, the IUT
> > >      sends BIS Data PDUs on each synchronized BIS. The parameters
> > >      included in the Codec_Specific_Configuration data are as
> > >      defined in TSPX_VS_Codec_Specific_Configuration.
> > >
> > >      If the Codec ID is LC3, each parameter included in
> > >      Codec_Specific_Configuration data is formatted in an LTV
> > >      structure with the length, type, and value specified in
> > >      Table 4.83.
> > >
> > > Test Summary
> > > ------------
> > > BAP/BSRC/STR/BV-18-C [BSRC, Multiple BISes, LC3 8_1] Passed
> > > BAP/BSRC/STR/BV-19-C [BSRC, Multiple BISes, LC3 8_2] Passed
> > > BAP/BSRC/STR/BV-20-C [BSRC, Multiple BISes, LC3 16_1] Passed
> > > BAP/BSRC/STR/BV-21-C [BSRC, Multiple BISes, LC3 16_2] Passed
> > > BAP/BSRC/STR/BV-22-C [BSRC, Multiple BISes, LC3 24_1] Passed
> > > BAP/BSRC/STR/BV-23-C [BSRC, Multiple BISes, LC3 24_2] Passed
> > > BAP/BSRC/STR/BV-24-C [BSRC, Multiple BISes, LC3 32_1] Passed
> > > BAP/BSRC/STR/BV-25-C [BSRC, Multiple BISes, LC3 32_2] Passed
> > > BAP/BSRC/STR/BV-26-C [BSRC, Multiple BISes, LC3 44.1_1] Passed
> > > BAP/BSRC/STR/BV-27-C [BSRC, Multiple BISes, LC3 44.1_2] Passed
> > > BAP/BSRC/STR/BV-28-C [BSRC, Multiple BISes, LC3 48_1] Passed
> > > BAP/BSRC/STR/BV-29-C [BSRC, Multiple BISes, LC3 48_2] Passed
> > > BAP/BSRC/STR/BV-30-C [BSRC, Multiple BISes, LC3 48_3] Passed
> > > BAP/BSRC/STR/BV-31-C [BSRC, Multiple BISes, LC3 48_4] Passed
> > > BAP/BSRC/STR/BV-32-C [BSRC, Multiple BISes, LC3 48_5] Passed
> > > BAP/BSRC/STR/BV-33-C [BSRC, Multiple BISes, LC3 48_6] Passed
> > > BAP/BSRC/STR/BV-34-C [BSRC, Multiple BISes, VS]      Passed
> > > ---
> > >  unit/test-bap.c | 354
> > > ++++++++++++++++++++++++++++++++++++++++++++++--
> > >  1 file changed, 346 insertions(+), 8 deletions(-)
> > >
> > > diff --git a/unit/test-bap.c b/unit/test-bap.c index
> > > c37f7676f..30c223d16 100644
> > > --- a/unit/test-bap.c
> > > +++ b/unit/test-bap.c
> > > @@ -6972,27 +6972,86 @@ static void test_bsnk_str(void)
> > >                 NULL, test_bcast, &cfg_bsnk_str_vs_mbis, IOV_NULL);
> > > }
> > >
> > > +static void stream_count_config(void *data, void *user_data) {
> > > +       struct bt_bap_stream *stream = data;
> > > +       uint8_t *streams = user_data;
> > > +
> > > +       if (bt_bap_stream_get_state(stream) ==
> > BT_BAP_STREAM_STATE_CONFIG)
> > > +               (*streams)++;
> > > +}
> > > +
> > > +static void stream_count_enabling(void *data, void *user_data) {
> > > +       struct bt_bap_stream *stream = data;
> > > +       uint8_t *streams = user_data;
> > > +
> > > +       if (bt_bap_stream_get_state(stream) ==
> > BT_BAP_STREAM_STATE_ENABLING)
> > > +               (*streams)++;
> > > +}
> > > +
> > > +static void stream_enable(void *data, void *user_data) {
> > > +       struct bt_bap_stream *stream = data;
> > > +
> > > +       bt_bap_stream_enable(stream, true, NULL, NULL, NULL); }
> > > +
> > > +static void stream_start(void *data, void *user_data) {
> > > +       struct bt_bap_stream *stream = data;
> > > +
> > > +       bt_bap_stream_start(stream, NULL, NULL); }
> > > +
> > >  static void bsrc_state_str(struct bt_bap_stream *stream, uint8_t
> old_state,
> > >                                 uint8_t new_state, void *user_data)  {
> > >         struct test_data *data = user_data;
> > > +       uint8_t streams = 0;
> > >
> > >         switch (new_state) {
> > >         case BT_BAP_STREAM_STATE_CONFIG:
> > > -               bt_bap_stream_enable(stream, true, NULL, NULL, NULL);
> > > +               queue_foreach(data->streams, stream_count_config,
> > > + &streams);
> > > +
> > > +               if (streams == data->cfg->streams)
> > > +                       /* After all streams have transitioned to CONFIG
> > > +                        * state, enable each one.
> > > +                        */
> > > +                       queue_foreach(data->streams, stream_enable,
> > > + NULL);
> > >                 break;
> > >         case BT_BAP_STREAM_STATE_ENABLING:
> > > -               data->base = bt_bap_stream_get_base(stream);
> > > +               queue_foreach(data->streams, stream_count_enabling,
> > &streams);
> > >
> > > -               g_assert(data->base);
> > > -               g_assert(data->base->iov_len == data->cfg->base.iov_len);
> > > -               g_assert(memcmp(data->base->iov_base, data->cfg-
> > >base.iov_base,
> > > -                               data->base->iov_len) == 0);
> > > +               if (streams == 1) {
> > > +                       /* After the first stream has transitioned to ENABLING
> > > +                        * state, bt_bap_stream_get_base will generate the
> > > +                        * BASE from all previously configured streams.
> > > +                        */
> > > +                       data->base = bt_bap_stream_get_base(stream);
> > > +
> > > +                       g_assert(data->base);
> > > +                       g_assert(data->base->iov_len ==
> > > +                                       data->cfg->base.iov_len);
> > > +                       g_assert(memcmp(data->base->iov_base,
> > > +                                       data->cfg->base.iov_base,
> > > +                                       data->base->iov_len) == 0);
> > > +               }
> > >
> > > -               bt_bap_stream_start(stream, NULL, NULL);
> > > +               if (streams == data->cfg->streams)
> > > +                       /* After all streams have transitioned to ENABLING
> > > +                        * state, start each one.
> > > +                        */
> > > +                       queue_foreach(data->streams, stream_start,
> > > + NULL);
> > >                 break;
> > >         case BT_BAP_STREAM_STATE_STREAMING:
> > > -               tester_test_passed();
> > > +               queue_foreach(data->streams, stream_count_streaming,
> > &streams);
> > > +
> > > +               if (streams == data->cfg->streams)
> > > +                       /* Test is completed after all streams have transitioned
> > > +                        * to STREAMING state.
> > > +                        */
> > > +                       tester_test_passed();
> > >                 break;
> > >         }
> > >  }
> > > @@ -7225,9 +7284,288 @@ static void test_bsrc_str_1b(void)
> > >                 NULL, test_bcast, &cfg_bsrc_str_vs, IOV_NULL);  }
> > >
> > > +#define BASE_LC3_8_1_MBIS \
> > > +       BASE_LC3(40000, 1, 2, LC3_CFG_8_1, 0x00, 0x01, 0x00, 0x02,
> > > +0x00)
> >
> > I wonder if we couldn't define these as part of lc3.h, in fact the
> > LC3_CFG looks awful similar to LC3_CONFIG from lc3.h, so perhaps we
> > could do just s/LC3_CFG/LC3_CONFIG and add something like LC3_BASE
> for
> > example then rename the existing LC3_BASE to LC3_TYPE(_id), anyway I
> > can probably do that myself later after merging this just wanted to
> > check first if you thought about that already.
> 
> I added LC3_CFG because LC3_CONFIG from lc3.h defines a iovec struct,
> while I needed some byte array to include in BASE_LC3. But I do think it
> would be useful to add the BASE defines to lc3.h, and they could be used
> for iso-tester as well.
>

Should I update this patch to move the BASE defines in lc3.h? Or should
it be done in a separate patch?

> >
> > > +static struct test_config cfg_bsrc_str_8_1_mbis = {
> > > +       .cc = LC3_CONFIG_8_1,
> > > +       .qos = LC3_QOS_8_1_1_B,
> > > +       .base = UTIL_IOV_INIT(BASE_LC3_8_1_MBIS),
> > > +       .src = true,
> > > +       .state_func = bsrc_state_str,
> > > +       .streams = 2,
> > > +};
> > > +
> > > +#define BASE_LC3_8_2_MBIS \
> > > +       BASE_LC3(40000, 1, 2, LC3_CFG_8_2, 0x00, 0x01, 0x00, 0x02,
> > > +0x00)
> > > +
> > > +static struct test_config cfg_bsrc_str_8_2_mbis = {
> > > +       .cc = LC3_CONFIG_8_2,
> > > +       .qos = LC3_QOS_8_2_1_B,
> > > +       .base = UTIL_IOV_INIT(BASE_LC3_8_2_MBIS),
> > > +       .src = true,
> > > +       .state_func = bsrc_state_str,
> > > +       .streams = 2,
> > > +};
> > > +
> > > +#define BASE_LC3_16_1_MBIS \
> > > +       BASE_LC3(40000, 1, 2, LC3_CFG_16_1, 0x00, 0x01, 0x00, 0x02,
> > > +0x00)
> > > +
> > > +static struct test_config cfg_bsrc_str_16_1_mbis = {
> > > +       .cc = LC3_CONFIG_16_1,
> > > +       .qos = LC3_QOS_16_1_1_B,
> > > +       .base = UTIL_IOV_INIT(BASE_LC3_16_1_MBIS),
> > > +       .src = true,
> > > +       .state_func = bsrc_state_str,
> > > +       .streams = 2,
> > > +};
> > > +
> > > +#define BASE_LC3_16_2_MBIS \
> > > +       BASE_LC3(40000, 1, 2, LC3_CFG_16_2, 0x00, 0x01, 0x00, 0x02,
> > > +0x00)
> > > +
> > > +static struct test_config cfg_bsrc_str_16_2_mbis = {
> > > +       .cc = LC3_CONFIG_16_2,
> > > +       .qos = LC3_QOS_16_2_1_B,
> > > +       .base = UTIL_IOV_INIT(BASE_LC3_16_2_MBIS),
> > > +       .src = true,
> > > +       .state_func = bsrc_state_str,
> > > +       .streams = 2,
> > > +};
> > > +
> > > +#define BASE_LC3_24_1_MBIS \
> > > +       BASE_LC3(40000, 1, 2, LC3_CFG_24_1, 0x00, 0x01, 0x00, 0x02,
> > > +0x00)
> > > +
> > > +static struct test_config cfg_bsrc_str_24_1_mbis = {
> > > +       .cc = LC3_CONFIG_24_1,
> > > +       .qos = LC3_QOS_24_1_1_B,
> > > +       .base = UTIL_IOV_INIT(BASE_LC3_24_1_MBIS),
> > > +       .src = true,
> > > +       .state_func = bsrc_state_str,
> > > +       .streams = 2,
> > > +};
> > > +
> > > +#define BASE_LC3_24_2_MBIS \
> > > +       BASE_LC3(40000, 1, 2, LC3_CFG_24_2, 0x00, 0x01, 0x00, 0x02,
> > > +0x00)
> > > +
> > > +static struct test_config cfg_bsrc_str_24_2_mbis = {
> > > +       .cc = LC3_CONFIG_24_2,
> > > +       .qos = LC3_QOS_24_2_1_B,
> > > +       .base = UTIL_IOV_INIT(BASE_LC3_24_2_MBIS),
> > > +       .src = true,
> > > +       .state_func = bsrc_state_str,
> > > +       .streams = 2,
> > > +};
> > > +
> > > +#define BASE_LC3_32_1_MBIS \
> > > +       BASE_LC3(40000, 1, 2, LC3_CFG_32_1, 0x00, 0x01, 0x00, 0x02,
> > > +0x00)
> > > +
> > > +static struct test_config cfg_bsrc_str_32_1_mbis = {
> > > +       .cc = LC3_CONFIG_32_1,
> > > +       .qos = LC3_QOS_32_1_1_B,
> > > +       .base = UTIL_IOV_INIT(BASE_LC3_32_1_MBIS),
> > > +       .src = true,
> > > +       .state_func = bsrc_state_str,
> > > +       .streams = 2,
> > > +};
> > > +
> > > +#define BASE_LC3_32_2_MBIS \
> > > +       BASE_LC3(40000, 1, 2, LC3_CFG_32_2, 0x00, 0x01, 0x00, 0x02,
> > > +0x00)
> > > +
> > > +static struct test_config cfg_bsrc_str_32_2_mbis = {
> > > +       .cc = LC3_CONFIG_32_2,
> > > +       .qos = LC3_QOS_32_2_1_B,
> > > +       .base = UTIL_IOV_INIT(BASE_LC3_32_2_MBIS),
> > > +       .src = true,
> > > +       .state_func = bsrc_state_str,
> > > +       .streams = 2,
> > > +};
> > > +
> > > +#define BASE_LC3_44_1_MBIS \
> > > +       BASE_LC3(40000, 1, 2, LC3_CFG_44_1, 0x00, 0x01, 0x00, 0x02,
> > > +0x00)
> > > +
> > > +static struct test_config cfg_bsrc_str_44_1_mbis = {
> > > +       .cc = LC3_CONFIG_44_1,
> > > +       .qos = LC3_QOS_44_1_1_B,
> > > +       .base = UTIL_IOV_INIT(BASE_LC3_44_1_MBIS),
> > > +       .src = true,
> > > +       .state_func = bsrc_state_str,
> > > +       .streams = 2,
> > > +};
> > > +
> > > +#define BASE_LC3_44_2_MBIS \
> > > +       BASE_LC3(40000, 1, 2, LC3_CFG_44_2, 0x00, 0x01, 0x00, 0x02,
> > > +0x00)
> > > +
> > > +static struct test_config cfg_bsrc_str_44_2_mbis = {
> > > +       .cc = LC3_CONFIG_44_2,
> > > +       .qos = LC3_QOS_44_2_1_B,
> > > +       .base = UTIL_IOV_INIT(BASE_LC3_44_2_MBIS),
> > > +       .src = true,
> > > +       .state_func = bsrc_state_str,
> > > +       .streams = 2,
> > > +};
> > > +
> > > +#define BASE_LC3_48_1_MBIS \
> > > +       BASE_LC3(40000, 1, 2, LC3_CFG_48_1, 0x00, 0x01, 0x00, 0x02,
> > > +0x00)
> > > +
> > > +static struct test_config cfg_bsrc_str_48_1_mbis = {
> > > +       .cc = LC3_CONFIG_48_1,
> > > +       .qos = LC3_QOS_48_1_1_B,
> > > +       .base = UTIL_IOV_INIT(BASE_LC3_48_1_MBIS),
> > > +       .src = true,
> > > +       .state_func = bsrc_state_str,
> > > +       .streams = 2,
> > > +};
> > > +
> > > +#define BASE_LC3_48_2_MBIS \
> > > +       BASE_LC3(40000, 1, 2, LC3_CFG_48_2, 0x00, 0x01, 0x00, 0x02,
> > > +0x00)
> > > +
> > > +static struct test_config cfg_bsrc_str_48_2_mbis = {
> > > +       .cc = LC3_CONFIG_48_2,
> > > +       .qos = LC3_QOS_48_2_1_B,
> > > +       .base = UTIL_IOV_INIT(BASE_LC3_48_2_MBIS),
> > > +       .src = true,
> > > +       .state_func = bsrc_state_str,
> > > +       .streams = 2,
> > > +};
> > > +
> > > +#define BASE_LC3_48_3_MBIS \
> > > +       BASE_LC3(40000, 1, 2, LC3_CFG_48_3, 0x00, 0x01, 0x00, 0x02,
> > > +0x00)
> > > +
> > > +static struct test_config cfg_bsrc_str_48_3_mbis = {
> > > +       .cc = LC3_CONFIG_48_3,
> > > +       .qos = LC3_QOS_48_3_1_B,
> > > +       .base = UTIL_IOV_INIT(BASE_LC3_48_3_MBIS),
> > > +       .src = true,
> > > +       .state_func = bsrc_state_str,
> > > +       .streams = 2,
> > > +};
> > > +
> > > +#define BASE_LC3_48_4_MBIS \
> > > +       BASE_LC3(40000, 1, 2, LC3_CFG_48_4, 0x00, 0x01, 0x00, 0x02,
> > > +0x00)
> > > +
> > > +static struct test_config cfg_bsrc_str_48_4_mbis = {
> > > +       .cc = LC3_CONFIG_48_4,
> > > +       .qos = LC3_QOS_48_4_1_B,
> > > +       .base = UTIL_IOV_INIT(BASE_LC3_48_4_MBIS),
> > > +       .src = true,
> > > +       .state_func = bsrc_state_str,
> > > +       .streams = 2,
> > > +};
> > > +
> > > +#define BASE_LC3_48_5_MBIS \
> > > +       BASE_LC3(40000, 1, 2, LC3_CFG_48_5, 0x00, 0x01, 0x00, 0x02,
> > > +0x00)
> > > +
> > > +static struct test_config cfg_bsrc_str_48_5_mbis = {
> > > +       .cc = LC3_CONFIG_48_5,
> > > +       .qos = LC3_QOS_48_5_1_B,
> > > +       .base = UTIL_IOV_INIT(BASE_LC3_48_5_MBIS),
> > > +       .src = true,
> > > +       .state_func = bsrc_state_str,
> > > +       .streams = 2,
> > > +};
> > > +
> > > +#define BASE_LC3_48_6_MBIS \
> > > +       BASE_LC3(40000, 1, 2, LC3_CFG_48_6, 0x00, 0x01, 0x00, 0x02,
> > > +0x00)
> > > +
> > > +static struct test_config cfg_bsrc_str_48_6_mbis = {
> > > +       .cc = LC3_CONFIG_48_6,
> > > +       .qos = LC3_QOS_48_6_1_B,
> > > +       .base = UTIL_IOV_INIT(BASE_LC3_48_6_MBIS),
> > > +       .src = true,
> > > +       .state_func = bsrc_state_str,
> > > +       .streams = 2,
> > > +};
> > > +
> > > +#define BASE_VS_MBIS \
> > > +       BASE(40000, 1, 2, 0xFF, 0x00, 0x00, 0x00, 0x00, \
> > > +       VS_CFG, 0x00, 0x01, 0x00, 0x02, 0x00)
> > > +
> > > +static struct test_config cfg_bsrc_str_vs_mbis = {
> > > +       .cc = UTIL_IOV_INIT(VS_CC),
> > > +       .qos = QOS_BCAST,
> > > +       .base = UTIL_IOV_INIT(BASE_VS_MBIS),
> > > +       .src = true,
> > > +       .state_func = bsrc_state_str,
> > > +       .vs = true,
> > > +       .streams = 2,
> > > +};
> > > +
> > > +/* Test Purpose:
> > > + * Verify that a Broadcast Source IUT can stream multiple BISes to
> > > + * a Broadcast Sink. The verification is performed for each set of
> > > + * parameters in turn, as specified in Table 4.82.
> > > + *
> > > + * Pass verdict:
> > > + * If the Codec ID is LC3, the IUT sends encoded LC3 audio data in
> > > + * BIS Data PDUs on each synchronized BIS.
> > > + *
> > > + * If the Codec ID is a vendor-specific Codec ID, the IUT sends BIS
> > > + * Data PDUs on each synchronized BIS. The parameters included in
> > > +the
> > > + * Codec_Specific_Configuration data are as defined in
> > > + * TSPX_VS_Codec_Specific_Configuration.
> > > + *
> > > + * If the Codec ID is LC3, each parameter included in
> > > + * Codec_Specific_Configuration data is formatted in an LTV
> > > +structure
> > > + * with the length, type, and value specified in Table 4.83.
> > > + */
> > > +static void test_bsrc_str_2b(void)
> > > +{
> > > +       define_test("BAP/BSRC/STR/BV-18-C [BSRC, Multiple BISes, LC3
> 8_1]",
> > > +               NULL, test_bcast, &cfg_bsrc_str_8_1_mbis, IOV_NULL);
> > > +
> > > +       define_test("BAP/BSRC/STR/BV-19-C [BSRC, Multiple BISes, LC3
> 8_2]",
> > > +               NULL, test_bcast, &cfg_bsrc_str_8_2_mbis, IOV_NULL);
> > > +
> > > +       define_test("BAP/BSRC/STR/BV-20-C [BSRC, Multiple BISes, LC3
> > 16_1]",
> > > +               NULL, test_bcast, &cfg_bsrc_str_16_1_mbis,
> > > + IOV_NULL);
> > > +
> > > +       define_test("BAP/BSRC/STR/BV-21-C [BSRC, Multiple BISes, LC3
> > 16_2]",
> > > +               NULL, test_bcast, &cfg_bsrc_str_16_2_mbis,
> > > + IOV_NULL);
> > > +
> > > +       define_test("BAP/BSRC/STR/BV-22-C [BSRC, Multiple BISes, LC3
> > 24_1]",
> > > +               NULL, test_bcast, &cfg_bsrc_str_24_1_mbis,
> > > + IOV_NULL);
> > > +
> > > +       define_test("BAP/BSRC/STR/BV-23-C [BSRC, Multiple BISes, LC3
> > 24_2]",
> > > +               NULL, test_bcast, &cfg_bsrc_str_24_2_mbis,
> > > + IOV_NULL);
> > > +
> > > +       define_test("BAP/BSRC/STR/BV-24-C [BSRC, Multiple BISes, LC3
> > 32_1]",
> > > +               NULL, test_bcast, &cfg_bsrc_str_32_1_mbis,
> > > + IOV_NULL);
> > > +
> > > +       define_test("BAP/BSRC/STR/BV-25-C [BSRC, Multiple BISes, LC3
> > 32_2]",
> > > +               NULL, test_bcast, &cfg_bsrc_str_32_2_mbis,
> > > + IOV_NULL);
> > > +
> > > +       define_test("BAP/BSRC/STR/BV-26-C [BSRC, Multiple BISes, LC3
> > 44.1_1]",
> > > +               NULL, test_bcast, &cfg_bsrc_str_44_1_mbis,
> > > + IOV_NULL);
> > > +
> > > +       define_test("BAP/BSRC/STR/BV-27-C [BSRC, Multiple BISes, LC3
> > 44.1_2]",
> > > +               NULL, test_bcast, &cfg_bsrc_str_44_2_mbis,
> > > + IOV_NULL);
> > > +
> > > +       define_test("BAP/BSRC/STR/BV-28-C [BSRC, Multiple BISes, LC3
> > 48_1]",
> > > +               NULL, test_bcast, &cfg_bsrc_str_48_1_mbis,
> > > + IOV_NULL);
> > > +
> > > +       define_test("BAP/BSRC/STR/BV-29-C [BSRC, Multiple BISes, LC3
> > 48_2]",
> > > +               NULL, test_bcast, &cfg_bsrc_str_48_2_mbis,
> > > + IOV_NULL);
> > > +
> > > +       define_test("BAP/BSRC/STR/BV-30-C [BSRC, Multiple BISes, LC3
> > 48_3]",
> > > +               NULL, test_bcast, &cfg_bsrc_str_48_3_mbis,
> > > + IOV_NULL);
> > > +
> > > +       define_test("BAP/BSRC/STR/BV-31-C [BSRC, Multiple BISes, LC3
> > 48_4]",
> > > +               NULL, test_bcast, &cfg_bsrc_str_48_4_mbis,
> > > + IOV_NULL);
> > > +
> > > +       define_test("BAP/BSRC/STR/BV-32-C [BSRC, Multiple BISes, LC3
> > 48_5]",
> > > +               NULL, test_bcast, &cfg_bsrc_str_48_5_mbis,
> > > + IOV_NULL);
> > > +
> > > +       define_test("BAP/BSRC/STR/BV-33-C [BSRC, Multiple BISes, LC3
> > 48_6]",
> > > +               NULL, test_bcast, &cfg_bsrc_str_48_6_mbis,
> > > + IOV_NULL);
> > > +
> > > +       define_test("BAP/BSRC/STR/BV-34-C [BSRC, Multiple BISes, VS]",
> > > +               NULL, test_bcast, &cfg_bsrc_str_vs_mbis, IOV_NULL);
> > > +}
> > > +
> > >  static void test_bsrc_str(void)
> > >  {
> > >         test_bsrc_str_1b();
> > > +       test_bsrc_str_2b();
> > >  }
> > >
> > >  int main(int argc, char *argv[])
> > > --
> > > 2.39.2
> > >
> >
> >
> > --
> > Luiz Augusto von Dentz
> 
> 
> Regards,
> Iulia

Regards,
Iulia
Luiz Augusto von Dentz June 20, 2024, 2:27 p.m. UTC | #4
Hi Iulia,

On Thu, Jun 20, 2024 at 10:22 AM Iulia Tanasescu
<iulia.tanasescu@nxp.com> wrote:
>
> Hi Luiz,
>
> > -----Original Message-----
> > From: Iulia Tanasescu
> > Sent: Monday, June 10, 2024 10:24 AM
> > To: luiz.dentz@gmail.com
> > Cc: Andrei Istodorescu <andrei.istodorescu@nxp.com>; Claudia Cristina
> > Draghicescu <claudia.rosu@nxp.com>; Iulia Tanasescu
> > <iulia.tanasescu@nxp.com>; linux-bluetooth@vger.kernel.org; Mihai-
> > Octavian Urzica <mihai-octavian.urzica@nxp.com>; Vlad Pruteanu
> > <vlad.pruteanu@nxp.com>
> > Subject: Re: [PATCH BlueZ 2/2] test-bap: Add Broadcast Source STR MBIS
> > tests
> >
> > Hi Luiz,
> >
> > > -----Original Message-----
> > > From: Luiz Augusto von Dentz <luiz.dentz@gmail.com>
> > > Sent: Thursday, June 6, 2024 11:29 PM
> > > To: Iulia Tanasescu <iulia.tanasescu@nxp.com>
> > > Cc: linux-bluetooth@vger.kernel.org; Claudia Cristina Draghicescu
> > > <claudia.rosu@nxp.com>; Mihai-Octavian Urzica <mihai-
> > > octavian.urzica@nxp.com>; Vlad Pruteanu <vlad.pruteanu@nxp.com>;
> > > Andrei Istodorescu <andrei.istodorescu@nxp.com>
> > > Subject: Re: [PATCH BlueZ 2/2] test-bap: Add Broadcast Source STR MBIS
> > > tests
> > >
> > > Hi Iulia,
> > >
> > > On Thu, Jun 6, 2024 at 6:26 AM Iulia Tanasescu
> > > <iulia.tanasescu@nxp.com>
> > > wrote:
> > > >
> > > > 4.14.3 Broadcast Audio Stream with Multiple BISes - Source
> > > >
> > > >      Test Purpose:
> > > >      Verify that a Broadcast Source IUT can stream multiple
> > > >      BISes to a Broadcast Sink.
> > > >
> > > >      Test Case Configuration:
> > > >      BAP/BSRC/STR/BV-18-C [BSRC, Multiple BISes, LC3 8_1]
> > > >      BAP/BSRC/STR/BV-19-C [BSRC, Multiple BISes, LC3 8_2]
> > > >      BAP/BSRC/STR/BV-20-C [BSRC, Multiple BISes, LC3 16_1]
> > > >      BAP/BSRC/STR/BV-21-C [BSRC, Multiple BISes, LC3 16_2]
> > > >      BAP/BSRC/STR/BV-22-C [BSRC, Multiple BISes, LC3 24_1]
> > > >      BAP/BSRC/STR/BV-23-C [BSRC, Multiple BISes, LC3 24_2]
> > > >      BAP/BSRC/STR/BV-24-C [BSRC, Multiple BISes, LC3 32_1]
> > > >      BAP/BSRC/STR/BV-25-C [BSRC, Multiple BISes, LC3 32_2]
> > > >      BAP/BSRC/STR/BV-26-C [BSRC, Multiple BISes, LC3 44.1_1]
> > > >      BAP/BSRC/STR/BV-27-C [BSRC, Multiple BISes, LC3 44.1_2]
> > > >      BAP/BSRC/STR/BV-28-C [BSRC, Multiple BISes, LC3 48_1]
> > > >      BAP/BSRC/STR/BV-29-C [BSRC, Multiple BISes, LC3 48_2]
> > > >      BAP/BSRC/STR/BV-30-C [BSRC, Multiple BISes, LC3 48_3]
> > > >      BAP/BSRC/STR/BV-31-C [BSRC, Multiple BISes, LC3 48_4]
> > > >      BAP/BSRC/STR/BV-32-C [BSRC, Multiple BISes, LC3 48_5]
> > > >      BAP/BSRC/STR/BV-33-C [BSRC, Multiple BISes, LC3 48_6]
> > > >      BAP/BSRC/STR/BV-34-C [BSRC, Multiple BISes, VS]
> > > >
> > > >      Pass verdict:
> > > >      If the Codec ID is LC3, the IUT sends encoded LC3 audio
> > > >      data in BIS Data PDUs on each synchronized BIS.
> > > >
> > > >      If the Codec ID is a vendor-specific Codec ID, the IUT
> > > >      sends BIS Data PDUs on each synchronized BIS. The parameters
> > > >      included in the Codec_Specific_Configuration data are as
> > > >      defined in TSPX_VS_Codec_Specific_Configuration.
> > > >
> > > >      If the Codec ID is LC3, each parameter included in
> > > >      Codec_Specific_Configuration data is formatted in an LTV
> > > >      structure with the length, type, and value specified in
> > > >      Table 4.83.
> > > >
> > > > Test Summary
> > > > ------------
> > > > BAP/BSRC/STR/BV-18-C [BSRC, Multiple BISes, LC3 8_1] Passed
> > > > BAP/BSRC/STR/BV-19-C [BSRC, Multiple BISes, LC3 8_2] Passed
> > > > BAP/BSRC/STR/BV-20-C [BSRC, Multiple BISes, LC3 16_1] Passed
> > > > BAP/BSRC/STR/BV-21-C [BSRC, Multiple BISes, LC3 16_2] Passed
> > > > BAP/BSRC/STR/BV-22-C [BSRC, Multiple BISes, LC3 24_1] Passed
> > > > BAP/BSRC/STR/BV-23-C [BSRC, Multiple BISes, LC3 24_2] Passed
> > > > BAP/BSRC/STR/BV-24-C [BSRC, Multiple BISes, LC3 32_1] Passed
> > > > BAP/BSRC/STR/BV-25-C [BSRC, Multiple BISes, LC3 32_2] Passed
> > > > BAP/BSRC/STR/BV-26-C [BSRC, Multiple BISes, LC3 44.1_1] Passed
> > > > BAP/BSRC/STR/BV-27-C [BSRC, Multiple BISes, LC3 44.1_2] Passed
> > > > BAP/BSRC/STR/BV-28-C [BSRC, Multiple BISes, LC3 48_1] Passed
> > > > BAP/BSRC/STR/BV-29-C [BSRC, Multiple BISes, LC3 48_2] Passed
> > > > BAP/BSRC/STR/BV-30-C [BSRC, Multiple BISes, LC3 48_3] Passed
> > > > BAP/BSRC/STR/BV-31-C [BSRC, Multiple BISes, LC3 48_4] Passed
> > > > BAP/BSRC/STR/BV-32-C [BSRC, Multiple BISes, LC3 48_5] Passed
> > > > BAP/BSRC/STR/BV-33-C [BSRC, Multiple BISes, LC3 48_6] Passed
> > > > BAP/BSRC/STR/BV-34-C [BSRC, Multiple BISes, VS]      Passed
> > > > ---
> > > >  unit/test-bap.c | 354
> > > > ++++++++++++++++++++++++++++++++++++++++++++++--
> > > >  1 file changed, 346 insertions(+), 8 deletions(-)
> > > >
> > > > diff --git a/unit/test-bap.c b/unit/test-bap.c index
> > > > c37f7676f..30c223d16 100644
> > > > --- a/unit/test-bap.c
> > > > +++ b/unit/test-bap.c
> > > > @@ -6972,27 +6972,86 @@ static void test_bsnk_str(void)
> > > >                 NULL, test_bcast, &cfg_bsnk_str_vs_mbis, IOV_NULL);
> > > > }
> > > >
> > > > +static void stream_count_config(void *data, void *user_data) {
> > > > +       struct bt_bap_stream *stream = data;
> > > > +       uint8_t *streams = user_data;
> > > > +
> > > > +       if (bt_bap_stream_get_state(stream) ==
> > > BT_BAP_STREAM_STATE_CONFIG)
> > > > +               (*streams)++;
> > > > +}
> > > > +
> > > > +static void stream_count_enabling(void *data, void *user_data) {
> > > > +       struct bt_bap_stream *stream = data;
> > > > +       uint8_t *streams = user_data;
> > > > +
> > > > +       if (bt_bap_stream_get_state(stream) ==
> > > BT_BAP_STREAM_STATE_ENABLING)
> > > > +               (*streams)++;
> > > > +}
> > > > +
> > > > +static void stream_enable(void *data, void *user_data) {
> > > > +       struct bt_bap_stream *stream = data;
> > > > +
> > > > +       bt_bap_stream_enable(stream, true, NULL, NULL, NULL); }
> > > > +
> > > > +static void stream_start(void *data, void *user_data) {
> > > > +       struct bt_bap_stream *stream = data;
> > > > +
> > > > +       bt_bap_stream_start(stream, NULL, NULL); }
> > > > +
> > > >  static void bsrc_state_str(struct bt_bap_stream *stream, uint8_t
> > old_state,
> > > >                                 uint8_t new_state, void *user_data)  {
> > > >         struct test_data *data = user_data;
> > > > +       uint8_t streams = 0;
> > > >
> > > >         switch (new_state) {
> > > >         case BT_BAP_STREAM_STATE_CONFIG:
> > > > -               bt_bap_stream_enable(stream, true, NULL, NULL, NULL);
> > > > +               queue_foreach(data->streams, stream_count_config,
> > > > + &streams);
> > > > +
> > > > +               if (streams == data->cfg->streams)
> > > > +                       /* After all streams have transitioned to CONFIG
> > > > +                        * state, enable each one.
> > > > +                        */
> > > > +                       queue_foreach(data->streams, stream_enable,
> > > > + NULL);
> > > >                 break;
> > > >         case BT_BAP_STREAM_STATE_ENABLING:
> > > > -               data->base = bt_bap_stream_get_base(stream);
> > > > +               queue_foreach(data->streams, stream_count_enabling,
> > > &streams);
> > > >
> > > > -               g_assert(data->base);
> > > > -               g_assert(data->base->iov_len == data->cfg->base.iov_len);
> > > > -               g_assert(memcmp(data->base->iov_base, data->cfg-
> > > >base.iov_base,
> > > > -                               data->base->iov_len) == 0);
> > > > +               if (streams == 1) {
> > > > +                       /* After the first stream has transitioned to ENABLING
> > > > +                        * state, bt_bap_stream_get_base will generate the
> > > > +                        * BASE from all previously configured streams.
> > > > +                        */
> > > > +                       data->base = bt_bap_stream_get_base(stream);
> > > > +
> > > > +                       g_assert(data->base);
> > > > +                       g_assert(data->base->iov_len ==
> > > > +                                       data->cfg->base.iov_len);
> > > > +                       g_assert(memcmp(data->base->iov_base,
> > > > +                                       data->cfg->base.iov_base,
> > > > +                                       data->base->iov_len) == 0);
> > > > +               }
> > > >
> > > > -               bt_bap_stream_start(stream, NULL, NULL);
> > > > +               if (streams == data->cfg->streams)
> > > > +                       /* After all streams have transitioned to ENABLING
> > > > +                        * state, start each one.
> > > > +                        */
> > > > +                       queue_foreach(data->streams, stream_start,
> > > > + NULL);
> > > >                 break;
> > > >         case BT_BAP_STREAM_STATE_STREAMING:
> > > > -               tester_test_passed();
> > > > +               queue_foreach(data->streams, stream_count_streaming,
> > > &streams);
> > > > +
> > > > +               if (streams == data->cfg->streams)
> > > > +                       /* Test is completed after all streams have transitioned
> > > > +                        * to STREAMING state.
> > > > +                        */
> > > > +                       tester_test_passed();
> > > >                 break;
> > > >         }
> > > >  }
> > > > @@ -7225,9 +7284,288 @@ static void test_bsrc_str_1b(void)
> > > >                 NULL, test_bcast, &cfg_bsrc_str_vs, IOV_NULL);  }
> > > >
> > > > +#define BASE_LC3_8_1_MBIS \
> > > > +       BASE_LC3(40000, 1, 2, LC3_CFG_8_1, 0x00, 0x01, 0x00, 0x02,
> > > > +0x00)
> > >
> > > I wonder if we couldn't define these as part of lc3.h, in fact the
> > > LC3_CFG looks awful similar to LC3_CONFIG from lc3.h, so perhaps we
> > > could do just s/LC3_CFG/LC3_CONFIG and add something like LC3_BASE
> > for
> > > example then rename the existing LC3_BASE to LC3_TYPE(_id), anyway I
> > > can probably do that myself later after merging this just wanted to
> > > check first if you thought about that already.
> >
> > I added LC3_CFG because LC3_CONFIG from lc3.h defines a iovec struct,
> > while I needed some byte array to include in BASE_LC3. But I do think it
> > would be useful to add the BASE defines to lc3.h, and they could be used
> > for iso-tester as well.
> >
>
> Should I update this patch to move the BASE defines in lc3.h? Or should
> it be done in a separate patch?

Yes, please move the BASE defines to lc3.h.

> > >
> > > > +static struct test_config cfg_bsrc_str_8_1_mbis = {
> > > > +       .cc = LC3_CONFIG_8_1,
> > > > +       .qos = LC3_QOS_8_1_1_B,
> > > > +       .base = UTIL_IOV_INIT(BASE_LC3_8_1_MBIS),
> > > > +       .src = true,
> > > > +       .state_func = bsrc_state_str,
> > > > +       .streams = 2,
> > > > +};
> > > > +
> > > > +#define BASE_LC3_8_2_MBIS \
> > > > +       BASE_LC3(40000, 1, 2, LC3_CFG_8_2, 0x00, 0x01, 0x00, 0x02,
> > > > +0x00)
> > > > +
> > > > +static struct test_config cfg_bsrc_str_8_2_mbis = {
> > > > +       .cc = LC3_CONFIG_8_2,
> > > > +       .qos = LC3_QOS_8_2_1_B,
> > > > +       .base = UTIL_IOV_INIT(BASE_LC3_8_2_MBIS),
> > > > +       .src = true,
> > > > +       .state_func = bsrc_state_str,
> > > > +       .streams = 2,
> > > > +};
> > > > +
> > > > +#define BASE_LC3_16_1_MBIS \
> > > > +       BASE_LC3(40000, 1, 2, LC3_CFG_16_1, 0x00, 0x01, 0x00, 0x02,
> > > > +0x00)
> > > > +
> > > > +static struct test_config cfg_bsrc_str_16_1_mbis = {
> > > > +       .cc = LC3_CONFIG_16_1,
> > > > +       .qos = LC3_QOS_16_1_1_B,
> > > > +       .base = UTIL_IOV_INIT(BASE_LC3_16_1_MBIS),
> > > > +       .src = true,
> > > > +       .state_func = bsrc_state_str,
> > > > +       .streams = 2,
> > > > +};
> > > > +
> > > > +#define BASE_LC3_16_2_MBIS \
> > > > +       BASE_LC3(40000, 1, 2, LC3_CFG_16_2, 0x00, 0x01, 0x00, 0x02,
> > > > +0x00)
> > > > +
> > > > +static struct test_config cfg_bsrc_str_16_2_mbis = {
> > > > +       .cc = LC3_CONFIG_16_2,
> > > > +       .qos = LC3_QOS_16_2_1_B,
> > > > +       .base = UTIL_IOV_INIT(BASE_LC3_16_2_MBIS),
> > > > +       .src = true,
> > > > +       .state_func = bsrc_state_str,
> > > > +       .streams = 2,
> > > > +};
> > > > +
> > > > +#define BASE_LC3_24_1_MBIS \
> > > > +       BASE_LC3(40000, 1, 2, LC3_CFG_24_1, 0x00, 0x01, 0x00, 0x02,
> > > > +0x00)
> > > > +
> > > > +static struct test_config cfg_bsrc_str_24_1_mbis = {
> > > > +       .cc = LC3_CONFIG_24_1,
> > > > +       .qos = LC3_QOS_24_1_1_B,
> > > > +       .base = UTIL_IOV_INIT(BASE_LC3_24_1_MBIS),
> > > > +       .src = true,
> > > > +       .state_func = bsrc_state_str,
> > > > +       .streams = 2,
> > > > +};
> > > > +
> > > > +#define BASE_LC3_24_2_MBIS \
> > > > +       BASE_LC3(40000, 1, 2, LC3_CFG_24_2, 0x00, 0x01, 0x00, 0x02,
> > > > +0x00)
> > > > +
> > > > +static struct test_config cfg_bsrc_str_24_2_mbis = {
> > > > +       .cc = LC3_CONFIG_24_2,
> > > > +       .qos = LC3_QOS_24_2_1_B,
> > > > +       .base = UTIL_IOV_INIT(BASE_LC3_24_2_MBIS),
> > > > +       .src = true,
> > > > +       .state_func = bsrc_state_str,
> > > > +       .streams = 2,
> > > > +};
> > > > +
> > > > +#define BASE_LC3_32_1_MBIS \
> > > > +       BASE_LC3(40000, 1, 2, LC3_CFG_32_1, 0x00, 0x01, 0x00, 0x02,
> > > > +0x00)
> > > > +
> > > > +static struct test_config cfg_bsrc_str_32_1_mbis = {
> > > > +       .cc = LC3_CONFIG_32_1,
> > > > +       .qos = LC3_QOS_32_1_1_B,
> > > > +       .base = UTIL_IOV_INIT(BASE_LC3_32_1_MBIS),
> > > > +       .src = true,
> > > > +       .state_func = bsrc_state_str,
> > > > +       .streams = 2,
> > > > +};
> > > > +
> > > > +#define BASE_LC3_32_2_MBIS \
> > > > +       BASE_LC3(40000, 1, 2, LC3_CFG_32_2, 0x00, 0x01, 0x00, 0x02,
> > > > +0x00)
> > > > +
> > > > +static struct test_config cfg_bsrc_str_32_2_mbis = {
> > > > +       .cc = LC3_CONFIG_32_2,
> > > > +       .qos = LC3_QOS_32_2_1_B,
> > > > +       .base = UTIL_IOV_INIT(BASE_LC3_32_2_MBIS),
> > > > +       .src = true,
> > > > +       .state_func = bsrc_state_str,
> > > > +       .streams = 2,
> > > > +};
> > > > +
> > > > +#define BASE_LC3_44_1_MBIS \
> > > > +       BASE_LC3(40000, 1, 2, LC3_CFG_44_1, 0x00, 0x01, 0x00, 0x02,
> > > > +0x00)
> > > > +
> > > > +static struct test_config cfg_bsrc_str_44_1_mbis = {
> > > > +       .cc = LC3_CONFIG_44_1,
> > > > +       .qos = LC3_QOS_44_1_1_B,
> > > > +       .base = UTIL_IOV_INIT(BASE_LC3_44_1_MBIS),
> > > > +       .src = true,
> > > > +       .state_func = bsrc_state_str,
> > > > +       .streams = 2,
> > > > +};
> > > > +
> > > > +#define BASE_LC3_44_2_MBIS \
> > > > +       BASE_LC3(40000, 1, 2, LC3_CFG_44_2, 0x00, 0x01, 0x00, 0x02,
> > > > +0x00)
> > > > +
> > > > +static struct test_config cfg_bsrc_str_44_2_mbis = {
> > > > +       .cc = LC3_CONFIG_44_2,
> > > > +       .qos = LC3_QOS_44_2_1_B,
> > > > +       .base = UTIL_IOV_INIT(BASE_LC3_44_2_MBIS),
> > > > +       .src = true,
> > > > +       .state_func = bsrc_state_str,
> > > > +       .streams = 2,
> > > > +};
> > > > +
> > > > +#define BASE_LC3_48_1_MBIS \
> > > > +       BASE_LC3(40000, 1, 2, LC3_CFG_48_1, 0x00, 0x01, 0x00, 0x02,
> > > > +0x00)
> > > > +
> > > > +static struct test_config cfg_bsrc_str_48_1_mbis = {
> > > > +       .cc = LC3_CONFIG_48_1,
> > > > +       .qos = LC3_QOS_48_1_1_B,
> > > > +       .base = UTIL_IOV_INIT(BASE_LC3_48_1_MBIS),
> > > > +       .src = true,
> > > > +       .state_func = bsrc_state_str,
> > > > +       .streams = 2,
> > > > +};
> > > > +
> > > > +#define BASE_LC3_48_2_MBIS \
> > > > +       BASE_LC3(40000, 1, 2, LC3_CFG_48_2, 0x00, 0x01, 0x00, 0x02,
> > > > +0x00)
> > > > +
> > > > +static struct test_config cfg_bsrc_str_48_2_mbis = {
> > > > +       .cc = LC3_CONFIG_48_2,
> > > > +       .qos = LC3_QOS_48_2_1_B,
> > > > +       .base = UTIL_IOV_INIT(BASE_LC3_48_2_MBIS),
> > > > +       .src = true,
> > > > +       .state_func = bsrc_state_str,
> > > > +       .streams = 2,
> > > > +};
> > > > +
> > > > +#define BASE_LC3_48_3_MBIS \
> > > > +       BASE_LC3(40000, 1, 2, LC3_CFG_48_3, 0x00, 0x01, 0x00, 0x02,
> > > > +0x00)
> > > > +
> > > > +static struct test_config cfg_bsrc_str_48_3_mbis = {
> > > > +       .cc = LC3_CONFIG_48_3,
> > > > +       .qos = LC3_QOS_48_3_1_B,
> > > > +       .base = UTIL_IOV_INIT(BASE_LC3_48_3_MBIS),
> > > > +       .src = true,
> > > > +       .state_func = bsrc_state_str,
> > > > +       .streams = 2,
> > > > +};
> > > > +
> > > > +#define BASE_LC3_48_4_MBIS \
> > > > +       BASE_LC3(40000, 1, 2, LC3_CFG_48_4, 0x00, 0x01, 0x00, 0x02,
> > > > +0x00)
> > > > +
> > > > +static struct test_config cfg_bsrc_str_48_4_mbis = {
> > > > +       .cc = LC3_CONFIG_48_4,
> > > > +       .qos = LC3_QOS_48_4_1_B,
> > > > +       .base = UTIL_IOV_INIT(BASE_LC3_48_4_MBIS),
> > > > +       .src = true,
> > > > +       .state_func = bsrc_state_str,
> > > > +       .streams = 2,
> > > > +};
> > > > +
> > > > +#define BASE_LC3_48_5_MBIS \
> > > > +       BASE_LC3(40000, 1, 2, LC3_CFG_48_5, 0x00, 0x01, 0x00, 0x02,
> > > > +0x00)
> > > > +
> > > > +static struct test_config cfg_bsrc_str_48_5_mbis = {
> > > > +       .cc = LC3_CONFIG_48_5,
> > > > +       .qos = LC3_QOS_48_5_1_B,
> > > > +       .base = UTIL_IOV_INIT(BASE_LC3_48_5_MBIS),
> > > > +       .src = true,
> > > > +       .state_func = bsrc_state_str,
> > > > +       .streams = 2,
> > > > +};
> > > > +
> > > > +#define BASE_LC3_48_6_MBIS \
> > > > +       BASE_LC3(40000, 1, 2, LC3_CFG_48_6, 0x00, 0x01, 0x00, 0x02,
> > > > +0x00)
> > > > +
> > > > +static struct test_config cfg_bsrc_str_48_6_mbis = {
> > > > +       .cc = LC3_CONFIG_48_6,
> > > > +       .qos = LC3_QOS_48_6_1_B,
> > > > +       .base = UTIL_IOV_INIT(BASE_LC3_48_6_MBIS),
> > > > +       .src = true,
> > > > +       .state_func = bsrc_state_str,
> > > > +       .streams = 2,
> > > > +};
> > > > +
> > > > +#define BASE_VS_MBIS \
> > > > +       BASE(40000, 1, 2, 0xFF, 0x00, 0x00, 0x00, 0x00, \
> > > > +       VS_CFG, 0x00, 0x01, 0x00, 0x02, 0x00)
> > > > +
> > > > +static struct test_config cfg_bsrc_str_vs_mbis = {
> > > > +       .cc = UTIL_IOV_INIT(VS_CC),
> > > > +       .qos = QOS_BCAST,
> > > > +       .base = UTIL_IOV_INIT(BASE_VS_MBIS),
> > > > +       .src = true,
> > > > +       .state_func = bsrc_state_str,
> > > > +       .vs = true,
> > > > +       .streams = 2,
> > > > +};
> > > > +
> > > > +/* Test Purpose:
> > > > + * Verify that a Broadcast Source IUT can stream multiple BISes to
> > > > + * a Broadcast Sink. The verification is performed for each set of
> > > > + * parameters in turn, as specified in Table 4.82.
> > > > + *
> > > > + * Pass verdict:
> > > > + * If the Codec ID is LC3, the IUT sends encoded LC3 audio data in
> > > > + * BIS Data PDUs on each synchronized BIS.
> > > > + *
> > > > + * If the Codec ID is a vendor-specific Codec ID, the IUT sends BIS
> > > > + * Data PDUs on each synchronized BIS. The parameters included in
> > > > +the
> > > > + * Codec_Specific_Configuration data are as defined in
> > > > + * TSPX_VS_Codec_Specific_Configuration.
> > > > + *
> > > > + * If the Codec ID is LC3, each parameter included in
> > > > + * Codec_Specific_Configuration data is formatted in an LTV
> > > > +structure
> > > > + * with the length, type, and value specified in Table 4.83.
> > > > + */
> > > > +static void test_bsrc_str_2b(void)
> > > > +{
> > > > +       define_test("BAP/BSRC/STR/BV-18-C [BSRC, Multiple BISes, LC3
> > 8_1]",
> > > > +               NULL, test_bcast, &cfg_bsrc_str_8_1_mbis, IOV_NULL);
> > > > +
> > > > +       define_test("BAP/BSRC/STR/BV-19-C [BSRC, Multiple BISes, LC3
> > 8_2]",
> > > > +               NULL, test_bcast, &cfg_bsrc_str_8_2_mbis, IOV_NULL);
> > > > +
> > > > +       define_test("BAP/BSRC/STR/BV-20-C [BSRC, Multiple BISes, LC3
> > > 16_1]",
> > > > +               NULL, test_bcast, &cfg_bsrc_str_16_1_mbis,
> > > > + IOV_NULL);
> > > > +
> > > > +       define_test("BAP/BSRC/STR/BV-21-C [BSRC, Multiple BISes, LC3
> > > 16_2]",
> > > > +               NULL, test_bcast, &cfg_bsrc_str_16_2_mbis,
> > > > + IOV_NULL);
> > > > +
> > > > +       define_test("BAP/BSRC/STR/BV-22-C [BSRC, Multiple BISes, LC3
> > > 24_1]",
> > > > +               NULL, test_bcast, &cfg_bsrc_str_24_1_mbis,
> > > > + IOV_NULL);
> > > > +
> > > > +       define_test("BAP/BSRC/STR/BV-23-C [BSRC, Multiple BISes, LC3
> > > 24_2]",
> > > > +               NULL, test_bcast, &cfg_bsrc_str_24_2_mbis,
> > > > + IOV_NULL);
> > > > +
> > > > +       define_test("BAP/BSRC/STR/BV-24-C [BSRC, Multiple BISes, LC3
> > > 32_1]",
> > > > +               NULL, test_bcast, &cfg_bsrc_str_32_1_mbis,
> > > > + IOV_NULL);
> > > > +
> > > > +       define_test("BAP/BSRC/STR/BV-25-C [BSRC, Multiple BISes, LC3
> > > 32_2]",
> > > > +               NULL, test_bcast, &cfg_bsrc_str_32_2_mbis,
> > > > + IOV_NULL);
> > > > +
> > > > +       define_test("BAP/BSRC/STR/BV-26-C [BSRC, Multiple BISes, LC3
> > > 44.1_1]",
> > > > +               NULL, test_bcast, &cfg_bsrc_str_44_1_mbis,
> > > > + IOV_NULL);
> > > > +
> > > > +       define_test("BAP/BSRC/STR/BV-27-C [BSRC, Multiple BISes, LC3
> > > 44.1_2]",
> > > > +               NULL, test_bcast, &cfg_bsrc_str_44_2_mbis,
> > > > + IOV_NULL);
> > > > +
> > > > +       define_test("BAP/BSRC/STR/BV-28-C [BSRC, Multiple BISes, LC3
> > > 48_1]",
> > > > +               NULL, test_bcast, &cfg_bsrc_str_48_1_mbis,
> > > > + IOV_NULL);
> > > > +
> > > > +       define_test("BAP/BSRC/STR/BV-29-C [BSRC, Multiple BISes, LC3
> > > 48_2]",
> > > > +               NULL, test_bcast, &cfg_bsrc_str_48_2_mbis,
> > > > + IOV_NULL);
> > > > +
> > > > +       define_test("BAP/BSRC/STR/BV-30-C [BSRC, Multiple BISes, LC3
> > > 48_3]",
> > > > +               NULL, test_bcast, &cfg_bsrc_str_48_3_mbis,
> > > > + IOV_NULL);
> > > > +
> > > > +       define_test("BAP/BSRC/STR/BV-31-C [BSRC, Multiple BISes, LC3
> > > 48_4]",
> > > > +               NULL, test_bcast, &cfg_bsrc_str_48_4_mbis,
> > > > + IOV_NULL);
> > > > +
> > > > +       define_test("BAP/BSRC/STR/BV-32-C [BSRC, Multiple BISes, LC3
> > > 48_5]",
> > > > +               NULL, test_bcast, &cfg_bsrc_str_48_5_mbis,
> > > > + IOV_NULL);
> > > > +
> > > > +       define_test("BAP/BSRC/STR/BV-33-C [BSRC, Multiple BISes, LC3
> > > 48_6]",
> > > > +               NULL, test_bcast, &cfg_bsrc_str_48_6_mbis,
> > > > + IOV_NULL);
> > > > +
> > > > +       define_test("BAP/BSRC/STR/BV-34-C [BSRC, Multiple BISes, VS]",
> > > > +               NULL, test_bcast, &cfg_bsrc_str_vs_mbis, IOV_NULL);
> > > > +}
> > > > +
> > > >  static void test_bsrc_str(void)
> > > >  {
> > > >         test_bsrc_str_1b();
> > > > +       test_bsrc_str_2b();
> > > >  }
> > > >
> > > >  int main(int argc, char *argv[])
> > > > --
> > > > 2.39.2
> > > >
> > >
> > >
> > > --
> > > Luiz Augusto von Dentz
> >
> >
> > Regards,
> > Iulia
>
> Regards,
> Iulia
diff mbox series

Patch

diff --git a/unit/test-bap.c b/unit/test-bap.c
index c37f7676f..30c223d16 100644
--- a/unit/test-bap.c
+++ b/unit/test-bap.c
@@ -6972,27 +6972,86 @@  static void test_bsnk_str(void)
 		NULL, test_bcast, &cfg_bsnk_str_vs_mbis, IOV_NULL);
 }
 
+static void stream_count_config(void *data, void *user_data)
+{
+	struct bt_bap_stream *stream = data;
+	uint8_t *streams = user_data;
+
+	if (bt_bap_stream_get_state(stream) == BT_BAP_STREAM_STATE_CONFIG)
+		(*streams)++;
+}
+
+static void stream_count_enabling(void *data, void *user_data)
+{
+	struct bt_bap_stream *stream = data;
+	uint8_t *streams = user_data;
+
+	if (bt_bap_stream_get_state(stream) == BT_BAP_STREAM_STATE_ENABLING)
+		(*streams)++;
+}
+
+static void stream_enable(void *data, void *user_data)
+{
+	struct bt_bap_stream *stream = data;
+
+	bt_bap_stream_enable(stream, true, NULL, NULL, NULL);
+}
+
+static void stream_start(void *data, void *user_data)
+{
+	struct bt_bap_stream *stream = data;
+
+	bt_bap_stream_start(stream, NULL, NULL);
+}
+
 static void bsrc_state_str(struct bt_bap_stream *stream, uint8_t old_state,
 				uint8_t new_state, void *user_data)
 {
 	struct test_data *data = user_data;
+	uint8_t streams = 0;
 
 	switch (new_state) {
 	case BT_BAP_STREAM_STATE_CONFIG:
-		bt_bap_stream_enable(stream, true, NULL, NULL, NULL);
+		queue_foreach(data->streams, stream_count_config, &streams);
+
+		if (streams == data->cfg->streams)
+			/* After all streams have transitioned to CONFIG
+			 * state, enable each one.
+			 */
+			queue_foreach(data->streams, stream_enable, NULL);
 		break;
 	case BT_BAP_STREAM_STATE_ENABLING:
-		data->base = bt_bap_stream_get_base(stream);
+		queue_foreach(data->streams, stream_count_enabling, &streams);
 
-		g_assert(data->base);
-		g_assert(data->base->iov_len == data->cfg->base.iov_len);
-		g_assert(memcmp(data->base->iov_base, data->cfg->base.iov_base,
-				data->base->iov_len) == 0);
+		if (streams == 1) {
+			/* After the first stream has transitioned to ENABLING
+			 * state, bt_bap_stream_get_base will generate the
+			 * BASE from all previously configured streams.
+			 */
+			data->base = bt_bap_stream_get_base(stream);
+
+			g_assert(data->base);
+			g_assert(data->base->iov_len ==
+					data->cfg->base.iov_len);
+			g_assert(memcmp(data->base->iov_base,
+					data->cfg->base.iov_base,
+					data->base->iov_len) == 0);
+		}
 
-		bt_bap_stream_start(stream, NULL, NULL);
+		if (streams == data->cfg->streams)
+			/* After all streams have transitioned to ENABLING
+			 * state, start each one.
+			 */
+			queue_foreach(data->streams, stream_start, NULL);
 		break;
 	case BT_BAP_STREAM_STATE_STREAMING:
-		tester_test_passed();
+		queue_foreach(data->streams, stream_count_streaming, &streams);
+
+		if (streams == data->cfg->streams)
+			/* Test is completed after all streams have transitioned
+			 * to STREAMING state.
+			 */
+			tester_test_passed();
 		break;
 	}
 }
@@ -7225,9 +7284,288 @@  static void test_bsrc_str_1b(void)
 		NULL, test_bcast, &cfg_bsrc_str_vs, IOV_NULL);
 }
 
+#define BASE_LC3_8_1_MBIS \
+	BASE_LC3(40000, 1, 2, LC3_CFG_8_1, 0x00, 0x01, 0x00, 0x02, 0x00)
+
+static struct test_config cfg_bsrc_str_8_1_mbis = {
+	.cc = LC3_CONFIG_8_1,
+	.qos = LC3_QOS_8_1_1_B,
+	.base = UTIL_IOV_INIT(BASE_LC3_8_1_MBIS),
+	.src = true,
+	.state_func = bsrc_state_str,
+	.streams = 2,
+};
+
+#define BASE_LC3_8_2_MBIS \
+	BASE_LC3(40000, 1, 2, LC3_CFG_8_2, 0x00, 0x01, 0x00, 0x02, 0x00)
+
+static struct test_config cfg_bsrc_str_8_2_mbis = {
+	.cc = LC3_CONFIG_8_2,
+	.qos = LC3_QOS_8_2_1_B,
+	.base = UTIL_IOV_INIT(BASE_LC3_8_2_MBIS),
+	.src = true,
+	.state_func = bsrc_state_str,
+	.streams = 2,
+};
+
+#define BASE_LC3_16_1_MBIS \
+	BASE_LC3(40000, 1, 2, LC3_CFG_16_1, 0x00, 0x01, 0x00, 0x02, 0x00)
+
+static struct test_config cfg_bsrc_str_16_1_mbis = {
+	.cc = LC3_CONFIG_16_1,
+	.qos = LC3_QOS_16_1_1_B,
+	.base = UTIL_IOV_INIT(BASE_LC3_16_1_MBIS),
+	.src = true,
+	.state_func = bsrc_state_str,
+	.streams = 2,
+};
+
+#define BASE_LC3_16_2_MBIS \
+	BASE_LC3(40000, 1, 2, LC3_CFG_16_2, 0x00, 0x01, 0x00, 0x02, 0x00)
+
+static struct test_config cfg_bsrc_str_16_2_mbis = {
+	.cc = LC3_CONFIG_16_2,
+	.qos = LC3_QOS_16_2_1_B,
+	.base = UTIL_IOV_INIT(BASE_LC3_16_2_MBIS),
+	.src = true,
+	.state_func = bsrc_state_str,
+	.streams = 2,
+};
+
+#define BASE_LC3_24_1_MBIS \
+	BASE_LC3(40000, 1, 2, LC3_CFG_24_1, 0x00, 0x01, 0x00, 0x02, 0x00)
+
+static struct test_config cfg_bsrc_str_24_1_mbis = {
+	.cc = LC3_CONFIG_24_1,
+	.qos = LC3_QOS_24_1_1_B,
+	.base = UTIL_IOV_INIT(BASE_LC3_24_1_MBIS),
+	.src = true,
+	.state_func = bsrc_state_str,
+	.streams = 2,
+};
+
+#define BASE_LC3_24_2_MBIS \
+	BASE_LC3(40000, 1, 2, LC3_CFG_24_2, 0x00, 0x01, 0x00, 0x02, 0x00)
+
+static struct test_config cfg_bsrc_str_24_2_mbis = {
+	.cc = LC3_CONFIG_24_2,
+	.qos = LC3_QOS_24_2_1_B,
+	.base = UTIL_IOV_INIT(BASE_LC3_24_2_MBIS),
+	.src = true,
+	.state_func = bsrc_state_str,
+	.streams = 2,
+};
+
+#define BASE_LC3_32_1_MBIS \
+	BASE_LC3(40000, 1, 2, LC3_CFG_32_1, 0x00, 0x01, 0x00, 0x02, 0x00)
+
+static struct test_config cfg_bsrc_str_32_1_mbis = {
+	.cc = LC3_CONFIG_32_1,
+	.qos = LC3_QOS_32_1_1_B,
+	.base = UTIL_IOV_INIT(BASE_LC3_32_1_MBIS),
+	.src = true,
+	.state_func = bsrc_state_str,
+	.streams = 2,
+};
+
+#define BASE_LC3_32_2_MBIS \
+	BASE_LC3(40000, 1, 2, LC3_CFG_32_2, 0x00, 0x01, 0x00, 0x02, 0x00)
+
+static struct test_config cfg_bsrc_str_32_2_mbis = {
+	.cc = LC3_CONFIG_32_2,
+	.qos = LC3_QOS_32_2_1_B,
+	.base = UTIL_IOV_INIT(BASE_LC3_32_2_MBIS),
+	.src = true,
+	.state_func = bsrc_state_str,
+	.streams = 2,
+};
+
+#define BASE_LC3_44_1_MBIS \
+	BASE_LC3(40000, 1, 2, LC3_CFG_44_1, 0x00, 0x01, 0x00, 0x02, 0x00)
+
+static struct test_config cfg_bsrc_str_44_1_mbis = {
+	.cc = LC3_CONFIG_44_1,
+	.qos = LC3_QOS_44_1_1_B,
+	.base = UTIL_IOV_INIT(BASE_LC3_44_1_MBIS),
+	.src = true,
+	.state_func = bsrc_state_str,
+	.streams = 2,
+};
+
+#define BASE_LC3_44_2_MBIS \
+	BASE_LC3(40000, 1, 2, LC3_CFG_44_2, 0x00, 0x01, 0x00, 0x02, 0x00)
+
+static struct test_config cfg_bsrc_str_44_2_mbis = {
+	.cc = LC3_CONFIG_44_2,
+	.qos = LC3_QOS_44_2_1_B,
+	.base = UTIL_IOV_INIT(BASE_LC3_44_2_MBIS),
+	.src = true,
+	.state_func = bsrc_state_str,
+	.streams = 2,
+};
+
+#define BASE_LC3_48_1_MBIS \
+	BASE_LC3(40000, 1, 2, LC3_CFG_48_1, 0x00, 0x01, 0x00, 0x02, 0x00)
+
+static struct test_config cfg_bsrc_str_48_1_mbis = {
+	.cc = LC3_CONFIG_48_1,
+	.qos = LC3_QOS_48_1_1_B,
+	.base = UTIL_IOV_INIT(BASE_LC3_48_1_MBIS),
+	.src = true,
+	.state_func = bsrc_state_str,
+	.streams = 2,
+};
+
+#define BASE_LC3_48_2_MBIS \
+	BASE_LC3(40000, 1, 2, LC3_CFG_48_2, 0x00, 0x01, 0x00, 0x02, 0x00)
+
+static struct test_config cfg_bsrc_str_48_2_mbis = {
+	.cc = LC3_CONFIG_48_2,
+	.qos = LC3_QOS_48_2_1_B,
+	.base = UTIL_IOV_INIT(BASE_LC3_48_2_MBIS),
+	.src = true,
+	.state_func = bsrc_state_str,
+	.streams = 2,
+};
+
+#define BASE_LC3_48_3_MBIS \
+	BASE_LC3(40000, 1, 2, LC3_CFG_48_3, 0x00, 0x01, 0x00, 0x02, 0x00)
+
+static struct test_config cfg_bsrc_str_48_3_mbis = {
+	.cc = LC3_CONFIG_48_3,
+	.qos = LC3_QOS_48_3_1_B,
+	.base = UTIL_IOV_INIT(BASE_LC3_48_3_MBIS),
+	.src = true,
+	.state_func = bsrc_state_str,
+	.streams = 2,
+};
+
+#define BASE_LC3_48_4_MBIS \
+	BASE_LC3(40000, 1, 2, LC3_CFG_48_4, 0x00, 0x01, 0x00, 0x02, 0x00)
+
+static struct test_config cfg_bsrc_str_48_4_mbis = {
+	.cc = LC3_CONFIG_48_4,
+	.qos = LC3_QOS_48_4_1_B,
+	.base = UTIL_IOV_INIT(BASE_LC3_48_4_MBIS),
+	.src = true,
+	.state_func = bsrc_state_str,
+	.streams = 2,
+};
+
+#define BASE_LC3_48_5_MBIS \
+	BASE_LC3(40000, 1, 2, LC3_CFG_48_5, 0x00, 0x01, 0x00, 0x02, 0x00)
+
+static struct test_config cfg_bsrc_str_48_5_mbis = {
+	.cc = LC3_CONFIG_48_5,
+	.qos = LC3_QOS_48_5_1_B,
+	.base = UTIL_IOV_INIT(BASE_LC3_48_5_MBIS),
+	.src = true,
+	.state_func = bsrc_state_str,
+	.streams = 2,
+};
+
+#define BASE_LC3_48_6_MBIS \
+	BASE_LC3(40000, 1, 2, LC3_CFG_48_6, 0x00, 0x01, 0x00, 0x02, 0x00)
+
+static struct test_config cfg_bsrc_str_48_6_mbis = {
+	.cc = LC3_CONFIG_48_6,
+	.qos = LC3_QOS_48_6_1_B,
+	.base = UTIL_IOV_INIT(BASE_LC3_48_6_MBIS),
+	.src = true,
+	.state_func = bsrc_state_str,
+	.streams = 2,
+};
+
+#define BASE_VS_MBIS \
+	BASE(40000, 1, 2, 0xFF, 0x00, 0x00, 0x00, 0x00, \
+	VS_CFG, 0x00, 0x01, 0x00, 0x02, 0x00)
+
+static struct test_config cfg_bsrc_str_vs_mbis = {
+	.cc = UTIL_IOV_INIT(VS_CC),
+	.qos = QOS_BCAST,
+	.base = UTIL_IOV_INIT(BASE_VS_MBIS),
+	.src = true,
+	.state_func = bsrc_state_str,
+	.vs = true,
+	.streams = 2,
+};
+
+/* Test Purpose:
+ * Verify that a Broadcast Source IUT can stream multiple BISes to
+ * a Broadcast Sink. The verification is performed for each set of
+ * parameters in turn, as specified in Table 4.82.
+ *
+ * Pass verdict:
+ * If the Codec ID is LC3, the IUT sends encoded LC3 audio data in
+ * BIS Data PDUs on each synchronized BIS.
+ *
+ * If the Codec ID is a vendor-specific Codec ID, the IUT sends BIS
+ * Data PDUs on each synchronized BIS. The parameters included in the
+ * Codec_Specific_Configuration data are as defined in
+ * TSPX_VS_Codec_Specific_Configuration.
+ *
+ * If the Codec ID is LC3, each parameter included in
+ * Codec_Specific_Configuration data is formatted in an LTV structure
+ * with the length, type, and value specified in Table 4.83.
+ */
+static void test_bsrc_str_2b(void)
+{
+	define_test("BAP/BSRC/STR/BV-18-C [BSRC, Multiple BISes, LC3 8_1]",
+		NULL, test_bcast, &cfg_bsrc_str_8_1_mbis, IOV_NULL);
+
+	define_test("BAP/BSRC/STR/BV-19-C [BSRC, Multiple BISes, LC3 8_2]",
+		NULL, test_bcast, &cfg_bsrc_str_8_2_mbis, IOV_NULL);
+
+	define_test("BAP/BSRC/STR/BV-20-C [BSRC, Multiple BISes, LC3 16_1]",
+		NULL, test_bcast, &cfg_bsrc_str_16_1_mbis, IOV_NULL);
+
+	define_test("BAP/BSRC/STR/BV-21-C [BSRC, Multiple BISes, LC3 16_2]",
+		NULL, test_bcast, &cfg_bsrc_str_16_2_mbis, IOV_NULL);
+
+	define_test("BAP/BSRC/STR/BV-22-C [BSRC, Multiple BISes, LC3 24_1]",
+		NULL, test_bcast, &cfg_bsrc_str_24_1_mbis, IOV_NULL);
+
+	define_test("BAP/BSRC/STR/BV-23-C [BSRC, Multiple BISes, LC3 24_2]",
+		NULL, test_bcast, &cfg_bsrc_str_24_2_mbis, IOV_NULL);
+
+	define_test("BAP/BSRC/STR/BV-24-C [BSRC, Multiple BISes, LC3 32_1]",
+		NULL, test_bcast, &cfg_bsrc_str_32_1_mbis, IOV_NULL);
+
+	define_test("BAP/BSRC/STR/BV-25-C [BSRC, Multiple BISes, LC3 32_2]",
+		NULL, test_bcast, &cfg_bsrc_str_32_2_mbis, IOV_NULL);
+
+	define_test("BAP/BSRC/STR/BV-26-C [BSRC, Multiple BISes, LC3 44.1_1]",
+		NULL, test_bcast, &cfg_bsrc_str_44_1_mbis, IOV_NULL);
+
+	define_test("BAP/BSRC/STR/BV-27-C [BSRC, Multiple BISes, LC3 44.1_2]",
+		NULL, test_bcast, &cfg_bsrc_str_44_2_mbis, IOV_NULL);
+
+	define_test("BAP/BSRC/STR/BV-28-C [BSRC, Multiple BISes, LC3 48_1]",
+		NULL, test_bcast, &cfg_bsrc_str_48_1_mbis, IOV_NULL);
+
+	define_test("BAP/BSRC/STR/BV-29-C [BSRC, Multiple BISes, LC3 48_2]",
+		NULL, test_bcast, &cfg_bsrc_str_48_2_mbis, IOV_NULL);
+
+	define_test("BAP/BSRC/STR/BV-30-C [BSRC, Multiple BISes, LC3 48_3]",
+		NULL, test_bcast, &cfg_bsrc_str_48_3_mbis, IOV_NULL);
+
+	define_test("BAP/BSRC/STR/BV-31-C [BSRC, Multiple BISes, LC3 48_4]",
+		NULL, test_bcast, &cfg_bsrc_str_48_4_mbis, IOV_NULL);
+
+	define_test("BAP/BSRC/STR/BV-32-C [BSRC, Multiple BISes, LC3 48_5]",
+		NULL, test_bcast, &cfg_bsrc_str_48_5_mbis, IOV_NULL);
+
+	define_test("BAP/BSRC/STR/BV-33-C [BSRC, Multiple BISes, LC3 48_6]",
+		NULL, test_bcast, &cfg_bsrc_str_48_6_mbis, IOV_NULL);
+
+	define_test("BAP/BSRC/STR/BV-34-C [BSRC, Multiple BISes, VS]",
+		NULL, test_bcast, &cfg_bsrc_str_vs_mbis, IOV_NULL);
+}
+
 static void test_bsrc_str(void)
 {
 	test_bsrc_str_1b();
+	test_bsrc_str_2b();
 }
 
 int main(int argc, char *argv[])