tests: Bluetooth: CAP: Initiator unicast start unittests

Adds unittests for the CAP Initiator start procedure, simply
verifying that the procedure works as well as
testing invalid parameters.
This also allows us to remove the invalid behavior checks
from the babblesim test implementation.

Signed-off-by: Emil Gydesen <emil.gydesen@nordicsemi.no>
This commit is contained in:
Emil Gydesen 2024-06-03 09:27:50 +02:00 committed by Anas Nashif
commit eaf92a1494
9 changed files with 497 additions and 129 deletions

View file

@ -14,7 +14,7 @@ target_include_directories(testbinary PRIVATE include)
target_sources(testbinary
PRIVATE
${ZEPHYR_BASE}/subsys/bluetooth/host/uuid.c
src/main.c
src/test_common.c
src/test_unicast_start.c
)

View file

@ -3,7 +3,6 @@ CONFIG_LOG=y
CONFIG_BT=y
CONFIG_BT_CENTRAL=y
CONFIG_BT_MAX_CONN=2
CONFIG_BT_AUDIO=y
# Dependencies for CAP initiator unicast
@ -13,6 +12,13 @@ CONFIG_BT_CSIP_SET_COORDINATOR=y
CONFIG_BT_CAP_INITIATOR=y
CONFIG_BT_CAP_INITIATOR_LOG_LEVEL_DBG=y
# Support setting up a sink and source stream on 2 acceptors
CONFIG_BT_MAX_CONN=2
CONFIG_BT_ISO_MAX_CHAN=4
CONFIG_BT_BAP_UNICAST_CLIENT_GROUP_STREAM_COUNT=4
CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SNK_COUNT=2
CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SRC_COUNT=2
CONFIG_ASSERT=y
CONFIG_ASSERT_LEVEL=2
CONFIG_ASSERT_VERBOSE=y

View file

@ -6,6 +6,9 @@
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/bluetooth/conn.h>
#include <zephyr/bluetooth/hci_types.h>
#include "cap_initiator.h"
#include "conn.h"
#include "test_common.h"
@ -24,7 +27,7 @@ void test_conn_init(struct bt_conn *conn)
{
conn->index = 0;
conn->info.type = BT_CONN_TYPE_LE;
conn->info.role = BT_CONN_ROLE_PERIPHERAL;
conn->info.role = BT_CONN_ROLE_CENTRAL;
conn->info.state = BT_CONN_STATE_CONNECTED;
conn->info.security.level = BT_SECURITY_L2;
conn->info.security.enc_key_size = BT_ENC_KEY_SIZE_MAX;

View file

@ -0,0 +1,386 @@
/* test_unicast_start.c - unit test for unicast start procedure */
/*
* Copyright (c) 2024 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <errno.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <zephyr/autoconf.h>
#include <zephyr/bluetooth/audio/audio.h>
#include <zephyr/bluetooth/audio/bap.h>
#include <zephyr/bluetooth/audio/bap_lc3_preset.h>
#include <zephyr/bluetooth/audio/cap.h>
#include <zephyr/bluetooth/hci_types.h>
#include <zephyr/fff.h>
#include <zephyr/sys/slist.h>
#include <zephyr/sys/util.h>
#include <sys/errno.h>
#include "bap_endpoint.h"
#include "cap_initiator.h"
#include "conn.h"
#include "expects_util.h"
#include "test_common.h"
#include "ztest_assert.h"
#include "ztest_test.h"
#define FFF_GLOBALS
struct cap_initiator_test_unicast_start_fixture {
struct bt_cap_stream cap_streams[CONFIG_BT_BAP_UNICAST_CLIENT_GROUP_STREAM_COUNT];
struct bt_bap_ep eps[CONFIG_BT_BAP_UNICAST_CLIENT_GROUP_STREAM_COUNT];
struct bt_bap_unicast_group unicast_group;
struct bt_conn conns[CONFIG_BT_MAX_CONN];
struct bt_bap_lc3_preset preset;
};
static void cap_initiator_test_unicast_start_fixture_init(
struct cap_initiator_test_unicast_start_fixture *fixture)
{
fixture->preset = (struct bt_bap_lc3_preset)BT_BAP_LC3_UNICAST_PRESET_16_2_1(
BT_AUDIO_LOCATION_MONO_AUDIO, BT_AUDIO_CONTEXT_TYPE_UNSPECIFIED);
for (size_t i = 0U; i < ARRAY_SIZE(fixture->conns); i++) {
test_conn_init(&fixture->conns[i]);
}
for (size_t i = 0U; i < ARRAY_SIZE(fixture->cap_streams); i++) {
struct bt_bap_stream *bap_stream = &fixture->cap_streams[i].bap_stream;
sys_slist_append(&fixture->unicast_group.streams, &bap_stream->_node);
bap_stream->group = &fixture->unicast_group;
}
for (size_t i = 0U; i < ARRAY_SIZE(fixture->eps); i++) {
fixture->eps[i].dir = (i & 1) + 1; /* Makes it either 1 or 2 (sink or source)*/
}
}
static void *cap_initiator_test_unicast_start_setup(void)
{
struct cap_initiator_test_unicast_start_fixture *fixture;
fixture = malloc(sizeof(*fixture));
zassert_not_null(fixture);
return fixture;
}
static void cap_initiator_test_unicast_start_before(void *f)
{
int err;
memset(f, 0, sizeof(struct cap_initiator_test_unicast_start_fixture));
cap_initiator_test_unicast_start_fixture_init(f);
err = bt_cap_initiator_register_cb(&mock_cap_initiator_cb);
zassert_equal(0, err, "Unexpected return value %d", err);
}
static void cap_initiator_test_unicast_start_after(void *f)
{
struct cap_initiator_test_unicast_start_fixture *fixture = f;
bt_cap_initiator_unregister_cb(&mock_cap_initiator_cb);
for (size_t i = 0; i < ARRAY_SIZE(fixture->conns); i++) {
mock_bt_conn_disconnected(&fixture->conns[i], BT_HCI_ERR_REMOTE_USER_TERM_CONN);
}
}
static void cap_initiator_test_unicast_start_teardown(void *f)
{
free(f);
}
ZTEST_SUITE(cap_initiator_test_unicast_start, NULL, cap_initiator_test_unicast_start_setup,
cap_initiator_test_unicast_start_before, cap_initiator_test_unicast_start_after,
cap_initiator_test_unicast_start_teardown);
static ZTEST_F(cap_initiator_test_unicast_start, test_initiator_unicast_start)
{
struct bt_cap_unicast_audio_start_stream_param
stream_params[CONFIG_BT_BAP_UNICAST_CLIENT_GROUP_STREAM_COUNT] = {0};
const struct bt_cap_unicast_audio_start_param param = {
.type = BT_CAP_SET_TYPE_AD_HOC,
.count = ARRAY_SIZE(stream_params),
.stream_params = stream_params,
};
int err;
for (size_t i = 0U; i < ARRAY_SIZE(stream_params); i++) {
stream_params[i].stream = &fixture->cap_streams[i];
stream_params[i].codec_cfg = &fixture->preset.codec_cfg;
stream_params[i].member.member = &fixture->conns[i % ARRAY_SIZE(fixture->conns)];
stream_params[i].ep = &fixture->eps[i];
}
err = bt_cap_initiator_unicast_audio_start(&param);
zassert_equal(err, 0, "Unexpected return value %d", err);
zexpect_call_count("bt_cap_initiator_cb.unicast_start_complete_cb", 1,
mock_cap_initiator_unicast_start_complete_cb_fake.call_count);
for (size_t i = 0U; i < ARRAY_SIZE(stream_params); i++) {
const enum bt_bap_ep_state state =
fixture->cap_streams[i].bap_stream.ep->status.state;
zassert_equal(state, BT_BAP_EP_STATE_STREAMING, "[%zu] Unexpected state: %d", i,
state);
}
}
static ZTEST_F(cap_initiator_test_unicast_start, test_initiator_unicast_start_inval_param_null)
{
int err;
err = bt_cap_initiator_unicast_audio_start(NULL);
zassert_equal(err, -EINVAL, "Unexpected return value %d", err);
zexpect_call_count("bt_cap_initiator_cb.unicast_start_complete_cb", 0,
mock_cap_initiator_unicast_start_complete_cb_fake.call_count);
}
static ZTEST_F(cap_initiator_test_unicast_start,
test_initiator_unicast_start_inval_param_null_param)
{
const struct bt_cap_unicast_audio_start_param param = {
.type = BT_CAP_SET_TYPE_AD_HOC,
.count = CONFIG_BT_BAP_UNICAST_CLIENT_GROUP_STREAM_COUNT,
.stream_params = NULL,
};
int err;
err = bt_cap_initiator_unicast_audio_start(&param);
zassert_equal(err, -EINVAL, "Unexpected return value %d", err);
zexpect_call_count("bt_cap_initiator_cb.unicast_start_complete_cb", 0,
mock_cap_initiator_unicast_start_complete_cb_fake.call_count);
}
static ZTEST_F(cap_initiator_test_unicast_start,
test_initiator_unicast_start_inval_param_null_member)
{
struct bt_cap_unicast_audio_start_stream_param
stream_params[CONFIG_BT_BAP_UNICAST_CLIENT_GROUP_STREAM_COUNT] = {0};
const struct bt_cap_unicast_audio_start_param param = {
.type = BT_CAP_SET_TYPE_AD_HOC,
.count = ARRAY_SIZE(stream_params),
.stream_params = stream_params,
};
int err;
for (size_t i = 0U; i < ARRAY_SIZE(stream_params); i++) {
stream_params[i].stream = &fixture->cap_streams[i];
stream_params[i].codec_cfg = &fixture->preset.codec_cfg;
stream_params[i].ep = &fixture->eps[i];
}
err = bt_cap_initiator_unicast_audio_start(&param);
zassert_equal(err, -EINVAL, "Unexpected return value %d", err);
zexpect_call_count("bt_cap_initiator_cb.unicast_start_complete_cb", 0,
mock_cap_initiator_unicast_start_complete_cb_fake.call_count);
}
static ZTEST_F(cap_initiator_test_unicast_start, test_initiator_unicast_start_inval_missing_cas)
{
struct bt_cap_unicast_audio_start_stream_param
stream_params[CONFIG_BT_BAP_UNICAST_CLIENT_GROUP_STREAM_COUNT] = {0};
const struct bt_cap_unicast_audio_start_param param = {
.type = BT_CAP_SET_TYPE_CSIP, /* CSIP requires CAS */
.count = ARRAY_SIZE(stream_params),
.stream_params = stream_params,
};
int err;
for (size_t i = 0U; i < ARRAY_SIZE(stream_params); i++) {
stream_params[i].stream = &fixture->cap_streams[i];
stream_params[i].codec_cfg = &fixture->preset.codec_cfg;
stream_params[i].member.member = &fixture->conns[i % ARRAY_SIZE(fixture->conns)];
stream_params[i].ep = &fixture->eps[i];
}
err = bt_cap_initiator_unicast_audio_start(&param);
zassert_equal(err, -EINVAL, "Unexpected return value %d", err);
zexpect_call_count("bt_cap_initiator_cb.unicast_start_complete_cb", 0,
mock_cap_initiator_unicast_start_complete_cb_fake.call_count);
}
static ZTEST_F(cap_initiator_test_unicast_start,
test_initiator_unicast_start_inval_param_zero_count)
{
struct bt_cap_unicast_audio_start_stream_param
stream_params[CONFIG_BT_BAP_UNICAST_CLIENT_GROUP_STREAM_COUNT] = {0};
const struct bt_cap_unicast_audio_start_param param = {
.type = BT_CAP_SET_TYPE_AD_HOC,
.count = 0U,
.stream_params = stream_params,
};
int err;
for (size_t i = 0U; i < ARRAY_SIZE(stream_params); i++) {
stream_params[i].stream = &fixture->cap_streams[i];
stream_params[i].codec_cfg = &fixture->preset.codec_cfg;
stream_params[i].member.member = &fixture->conns[i % ARRAY_SIZE(fixture->conns)];
stream_params[i].ep = &fixture->eps[i];
}
err = bt_cap_initiator_unicast_audio_start(&param);
zassert_equal(err, -EINVAL, "Unexpected return value %d", err);
zexpect_call_count("bt_cap_initiator_cb.unicast_start_complete_cb", 0,
mock_cap_initiator_unicast_start_complete_cb_fake.call_count);
}
static ZTEST_F(cap_initiator_test_unicast_start,
test_initiator_unicast_start_inval_param_inval_count)
{
struct bt_cap_unicast_audio_start_stream_param
stream_params[CONFIG_BT_BAP_UNICAST_CLIENT_GROUP_STREAM_COUNT] = {0};
const struct bt_cap_unicast_audio_start_param param = {
.type = BT_CAP_SET_TYPE_AD_HOC,
.count = CONFIG_BT_BAP_UNICAST_CLIENT_GROUP_STREAM_COUNT + 1U,
.stream_params = stream_params,
};
int err;
for (size_t i = 0U; i < ARRAY_SIZE(stream_params); i++) {
stream_params[i].stream = &fixture->cap_streams[i];
stream_params[i].codec_cfg = &fixture->preset.codec_cfg;
stream_params[i].member.member = &fixture->conns[i % ARRAY_SIZE(fixture->conns)];
stream_params[i].ep = &fixture->eps[i];
}
err = bt_cap_initiator_unicast_audio_start(&param);
zassert_equal(err, -EINVAL, "Unexpected return value %d", err);
zexpect_call_count("bt_cap_initiator_cb.unicast_start_complete_cb", 0,
mock_cap_initiator_unicast_start_complete_cb_fake.call_count);
}
static ZTEST_F(cap_initiator_test_unicast_start,
test_initiator_unicast_start_inval_param_inval_stream_param_null_stream)
{
struct bt_cap_unicast_audio_start_stream_param stream_param = {0};
const struct bt_cap_unicast_audio_start_param param = {
.type = BT_CAP_SET_TYPE_AD_HOC,
.count = 1,
.stream_params = &stream_param,
};
int err;
stream_param.stream = NULL;
stream_param.codec_cfg = &fixture->preset.codec_cfg;
stream_param.member.member = &fixture->conns[0];
stream_param.ep = &fixture->eps[0];
err = bt_cap_initiator_unicast_audio_start(&param);
zassert_equal(err, -EINVAL, "Unexpected return value %d", err);
zexpect_call_count("bt_cap_initiator_cb.unicast_start_complete_cb", 0,
mock_cap_initiator_unicast_start_complete_cb_fake.call_count);
}
static ZTEST_F(cap_initiator_test_unicast_start,
test_initiator_unicast_start_inval_param_inval_stream_param_null_codec_cfg)
{
struct bt_cap_unicast_audio_start_stream_param stream_param = {0};
const struct bt_cap_unicast_audio_start_param param = {
.type = BT_CAP_SET_TYPE_AD_HOC,
.count = 1,
.stream_params = &stream_param,
};
int err;
stream_param.stream = &fixture->cap_streams[0];
stream_param.codec_cfg = NULL;
stream_param.member.member = &fixture->conns[0];
stream_param.ep = &fixture->eps[0];
err = bt_cap_initiator_unicast_audio_start(&param);
zassert_equal(err, -EINVAL, "Unexpected return value %d", err);
zexpect_call_count("bt_cap_initiator_cb.unicast_start_complete_cb", 0,
mock_cap_initiator_unicast_start_complete_cb_fake.call_count);
}
static ZTEST_F(cap_initiator_test_unicast_start,
test_initiator_unicast_start_inval_param_inval_stream_param_null_member)
{
struct bt_cap_unicast_audio_start_stream_param stream_param = {0};
const struct bt_cap_unicast_audio_start_param param = {
.type = BT_CAP_SET_TYPE_AD_HOC,
.count = 1,
.stream_params = &stream_param,
};
int err;
stream_param.stream = &fixture->cap_streams[0];
stream_param.codec_cfg = &fixture->preset.codec_cfg;
stream_param.member.member = NULL;
stream_param.ep = &fixture->eps[0];
err = bt_cap_initiator_unicast_audio_start(&param);
zassert_equal(err, -EINVAL, "Unexpected return value %d", err);
zexpect_call_count("bt_cap_initiator_cb.unicast_start_complete_cb", 0,
mock_cap_initiator_unicast_start_complete_cb_fake.call_count);
}
static ZTEST_F(cap_initiator_test_unicast_start,
test_initiator_unicast_start_inval_param_inval_stream_param_null_ep)
{
struct bt_cap_unicast_audio_start_stream_param stream_param = {0};
const struct bt_cap_unicast_audio_start_param param = {
.type = BT_CAP_SET_TYPE_AD_HOC,
.count = 1,
.stream_params = &stream_param,
};
int err;
stream_param.stream = &fixture->cap_streams[0];
stream_param.codec_cfg = &fixture->preset.codec_cfg;
stream_param.member.member = &fixture->conns[0];
stream_param.ep = NULL;
err = bt_cap_initiator_unicast_audio_start(&param);
zassert_equal(err, -EINVAL, "Unexpected return value %d", err);
zexpect_call_count("bt_cap_initiator_cb.unicast_start_complete_cb", 0,
mock_cap_initiator_unicast_start_complete_cb_fake.call_count);
}
static ZTEST_F(cap_initiator_test_unicast_start,
test_initiator_unicast_start_inval_param_inval_stream_param_invalid_meta)
{
struct bt_cap_unicast_audio_start_stream_param stream_param = {0};
const struct bt_cap_unicast_audio_start_param param = {
.type = BT_CAP_SET_TYPE_AD_HOC,
.count = 1,
.stream_params = &stream_param,
};
int err;
stream_param.stream = &fixture->cap_streams[0];
stream_param.codec_cfg = &fixture->preset.codec_cfg;
stream_param.member.member = &fixture->conns[0];
stream_param.ep = &fixture->eps[0];
/* CAP requires stream context - Let's remove it */
memset(stream_param.codec_cfg->meta, 0, sizeof(stream_param.codec_cfg->meta));
stream_param.codec_cfg->meta_len = 0U;
err = bt_cap_initiator_unicast_audio_start(&param);
zassert_equal(err, -EINVAL, "Unexpected return value %d", err);
zexpect_call_count("bt_cap_initiator_cb.unicast_start_complete_cb", 0,
mock_cap_initiator_unicast_start_complete_cb_fake.call_count);
}

View file

@ -1,5 +1,5 @@
#
# Copyright (c) 2023 Nordic Semiconductor ASA
# Copyright (c) 2023-2024 Nordic Semiconductor ASA
#
# SPDX-License-Identifier: Apache-2.0
#
@ -14,6 +14,7 @@ add_library(uut STATIC
${ZEPHYR_BASE}/subsys/bluetooth/audio/cap_common.c
${ZEPHYR_BASE}/subsys/bluetooth/audio/cap_stream.c
${ZEPHYR_BASE}/subsys/bluetooth/common/bt_str.c
${ZEPHYR_BASE}/subsys/bluetooth/host/uuid.c
${ZEPHYR_BASE}/subsys/logging/log_minimal.c
${ZEPHYR_BASE}/subsys/net/buf_simple.c
bap_unicast_client.c

View file

@ -1,10 +1,21 @@
/*
* Copyright (c) 2023 Codecoup
* Copyright (c) 2024 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <errno.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <zephyr/bluetooth/audio/audio.h>
#include <zephyr/bluetooth/audio/bap.h>
#include <zephyr/sys/slist.h>
#include "bap_endpoint.h"
#include "ztest_assert.h"
bool bt_bap_ep_is_unicast_client(const struct bt_bap_ep *ep)
{
@ -14,43 +25,111 @@ bool bt_bap_ep_is_unicast_client(const struct bt_bap_ep *ep)
int bt_bap_unicast_client_config(struct bt_bap_stream *stream,
const struct bt_audio_codec_cfg *codec_cfg)
{
zassert_unreachable("Unexpected call to '%s()' occurred", __func__);
if (stream == NULL || stream->ep == NULL || codec_cfg == NULL) {
return -EINVAL;
}
stream->ep->status.state = BT_BAP_EP_STATE_CODEC_CONFIGURED;
if (stream->ops != NULL && stream->ops->configured != NULL) {
const struct bt_audio_codec_qos_pref pref = {0};
stream->ops->configured(stream, &pref);
}
return 0;
}
int bt_bap_unicast_client_qos(struct bt_conn *conn, struct bt_bap_unicast_group *group)
{
zassert_unreachable("Unexpected call to '%s()' occurred", __func__);
struct bt_bap_stream *stream;
if (conn == NULL || group == NULL) {
return -EINVAL;
}
SYS_SLIST_FOR_EACH_CONTAINER(&group->streams, stream, _node) {
if (stream->conn == conn) {
stream->ep->status.state = BT_BAP_EP_STATE_QOS_CONFIGURED;
if (stream->ops != NULL && stream->ops->qos_set != NULL) {
stream->ops->qos_set(stream);
}
}
}
return 0;
}
int bt_bap_unicast_client_enable(struct bt_bap_stream *stream, uint8_t meta[],
int bt_bap_unicast_client_enable(struct bt_bap_stream *stream, const uint8_t meta[],
size_t meta_len)
{
zassert_unreachable("Unexpected call to '%s()' occurred", __func__);
if (stream == NULL) {
return -EINVAL;
}
stream->ep->status.state = BT_BAP_EP_STATE_ENABLING;
if (stream->ops != NULL && stream->ops->enabled != NULL) {
stream->ops->enabled(stream);
}
return 0;
}
int bt_bap_unicast_client_metadata(struct bt_bap_stream *stream, uint8_t meta[],
int bt_bap_unicast_client_metadata(struct bt_bap_stream *stream, const uint8_t meta[],
size_t meta_len)
{
zassert_unreachable("Unexpected call to '%s()' occurred", __func__);
return 0;
}
if (stream == NULL) {
return -EINVAL;
}
if (stream->ops != NULL && stream->ops->metadata_updated != NULL) {
stream->ops->metadata_updated(stream);
}
int bt_bap_unicast_client_disable(struct bt_bap_stream *stream)
{
zassert_unreachable("Unexpected call to '%s()' occurred", __func__);
return 0;
}
int bt_bap_unicast_client_connect(struct bt_bap_stream *stream)
{
zassert_unreachable("Unexpected call to '%s()' occurred", __func__);
if (stream == NULL) {
return -EINVAL;
}
if (stream->ops != NULL && stream->ops->connected != NULL) {
stream->ops->connected(stream);
}
if (stream->ep != NULL && stream->ep->dir == BT_AUDIO_DIR_SINK) {
/* Mocking that the unicast server automatically starts the stream */
stream->ep->status.state = BT_BAP_EP_STATE_STREAMING;
if (stream->ops != NULL && stream->ops->started != NULL) {
stream->ops->started(stream);
}
}
return 0;
}
int bt_bap_unicast_client_start(struct bt_bap_stream *stream)
{
/* As per the ASCS spec, only source streams can be started by the client */
if (stream == NULL || stream->ep == NULL || stream->ep->dir == BT_AUDIO_DIR_SINK) {
return -EINVAL;
}
stream->ep->status.state = BT_BAP_EP_STATE_STREAMING;
if (stream->ops != NULL && stream->ops->started != NULL) {
stream->ops->started(stream);
}
return 0;
}
int bt_bap_unicast_client_disable(struct bt_bap_stream *stream)
{
zassert_unreachable("Unexpected call to '%s()' occurred", __func__);
return 0;

View file

@ -9,6 +9,10 @@
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <zephyr/bluetooth/audio/csip.h>
#include <zephyr/bluetooth/conn.h>

View file

@ -510,12 +510,6 @@ static void discover_cas_inval(struct bt_conn *conn)
{
int err;
err = bt_cap_initiator_unicast_discover(NULL);
if (err == 0) {
FAIL("bt_cap_initiator_unicast_discover with NULL conn did not fail\n");
return;
}
/* Test if it handles concurrent request for same connection */
UNSET_FLAG(flag_discovered);
@ -576,111 +570,6 @@ static void unicast_group_create(struct bt_bap_unicast_group **out_unicast_group
}
}
static void unicast_audio_start_inval(struct bt_bap_unicast_group *unicast_group)
{
struct bt_audio_codec_cfg invalid_codec = BT_AUDIO_CODEC_LC3_CONFIG(
BT_AUDIO_CODEC_CFG_FREQ_16KHZ, BT_AUDIO_CODEC_CFG_DURATION_10,
BT_AUDIO_LOCATION_FRONT_LEFT, 40U, 1, BT_AUDIO_CONTEXT_TYPE_MEDIA);
struct bt_cap_unicast_audio_start_stream_param invalid_stream_param;
struct bt_cap_unicast_audio_start_stream_param valid_stream_param;
struct bt_cap_unicast_audio_start_param invalid_start_param;
struct bt_cap_unicast_audio_start_param valid_start_param;
int err;
valid_start_param.type = BT_CAP_SET_TYPE_AD_HOC;
valid_start_param.count = 1u;
valid_start_param.stream_params = &valid_stream_param;
valid_stream_param.member.member = default_conn;
valid_stream_param.stream = &unicast_client_sink_streams[0];
valid_stream_param.ep = unicast_sink_eps[bt_conn_index(default_conn)][0];
valid_stream_param.codec_cfg = &unicast_preset_16_2_1.codec_cfg;
/* Test NULL parameters */
err = bt_cap_initiator_unicast_audio_start(NULL);
if (err == 0) {
FAIL("bt_cap_initiator_unicast_audio_start with NULL param did not fail\n");
return;
}
/* Test invalid parameters */
memcpy(&invalid_stream_param, &valid_stream_param, sizeof(valid_stream_param));
memcpy(&invalid_start_param, &valid_start_param, sizeof(valid_start_param));
invalid_start_param.stream_params = &invalid_stream_param;
/* Test invalid stream_start parameters */
invalid_start_param.count = 0U;
err = bt_cap_initiator_unicast_audio_start(&invalid_start_param);
if (err == 0) {
FAIL("bt_cap_initiator_unicast_audio_start with 0 count did not fail\n");
return;
}
memcpy(&invalid_start_param, &valid_start_param, sizeof(valid_start_param));
invalid_start_param.stream_params = &invalid_stream_param;
invalid_start_param.stream_params = NULL;
err = bt_cap_initiator_unicast_audio_start(&invalid_start_param);
if (err == 0) {
FAIL("bt_cap_initiator_unicast_audio_start with NULL stream params did not fail\n");
return;
}
memcpy(&invalid_start_param, &valid_start_param, sizeof(valid_start_param));
invalid_start_param.stream_params = &invalid_stream_param;
/* Test invalid stream_param parameters */
invalid_stream_param.member.member = NULL;
err = bt_cap_initiator_unicast_audio_start(&invalid_start_param);
if (err == 0) {
FAIL("bt_cap_initiator_unicast_audio_start with NULL stream params member did not "
"fail\n");
return;
}
memcpy(&invalid_stream_param, &valid_stream_param, sizeof(valid_stream_param));
invalid_stream_param.stream = NULL;
err = bt_cap_initiator_unicast_audio_start(&invalid_start_param);
if (err == 0) {
FAIL("bt_cap_initiator_unicast_audio_start with NULL stream params stream did not "
"fail\n");
return;
}
memcpy(&invalid_stream_param, &valid_stream_param, sizeof(valid_stream_param));
invalid_stream_param.ep = NULL;
err = bt_cap_initiator_unicast_audio_start(&invalid_start_param);
if (err == 0) {
FAIL("bt_cap_initiator_unicast_audio_start with NULL stream params ep did not "
"fail\n");
return;
}
memcpy(&invalid_stream_param, &valid_stream_param, sizeof(valid_stream_param));
invalid_stream_param.codec_cfg = NULL;
err = bt_cap_initiator_unicast_audio_start(&invalid_start_param);
if (err == 0) {
FAIL("bt_cap_initiator_unicast_audio_start with NULL stream params codec did not "
"fail\n");
return;
}
/* Clear metadata so that it does not contain the mandatory stream context */
memcpy(&invalid_stream_param, &valid_stream_param, sizeof(valid_stream_param));
memset(&invalid_codec.meta, 0, sizeof(invalid_codec.meta));
invalid_stream_param.codec_cfg = &invalid_codec;
err = bt_cap_initiator_unicast_audio_start(&invalid_start_param);
if (err == 0) {
FAIL("bt_cap_initiator_unicast_audio_start with invalid Codec metadata did not "
"fail\n");
return;
}
}
static void unicast_audio_start(struct bt_bap_unicast_group *unicast_group, bool wait)
{
struct bt_cap_unicast_audio_start_stream_param stream_param[2];
@ -926,7 +815,6 @@ static void test_main_cap_initiator_unicast_inval(void)
unicast_group_create(&unicast_group);
unicast_audio_start_inval(unicast_group);
unicast_audio_start(unicast_group, true);
unicast_audio_update_inval();