tests: Bluetooth: Audio: Remove uses of K_FOREVER in syswg for TX
Several tests were using K_FOREVER when allocating the buffer for TX in the system workqueue, which is illegal behavior. The solution chosen was to create a TX thread to handle TX, similar to the solution used in the audio shell and some sample applications. This way we can continue to use K_FOREVER when allocting buffers and it will always be done in a round-robin fashion while TXing as much as possible, by always enqueuing all the buffers with mock data. Since this works for all streams (both broadcast and unicast), it was obvious to use the same implementation for all tests, and thus cleaning up the tests a bit and more them more similar. Signed-off-by: Emil Gydesen <emil.gydesen@nordicsemi.no>
This commit is contained in:
parent
f6490bf33d
commit
778a9afae3
11 changed files with 434 additions and 396 deletions
|
@ -26,6 +26,7 @@
|
|||
#include <zephyr/toolchain.h>
|
||||
|
||||
#include "bap_common.h"
|
||||
#include "bap_stream_tx.h"
|
||||
#include "bstests.h"
|
||||
#include "common.h"
|
||||
|
||||
|
@ -37,22 +38,6 @@
|
|||
#if defined(CONFIG_BT_BAP_BROADCAST_SOURCE)
|
||||
CREATE_FLAG(flag_source_started);
|
||||
|
||||
/* When BROADCAST_ENQUEUE_COUNT > 1 we can enqueue enough buffers to ensure that
|
||||
* the controller is never idle
|
||||
*/
|
||||
#define BROADCAST_ENQUEUE_COUNT 2U
|
||||
#define TOTAL_BUF_NEEDED (BROADCAST_ENQUEUE_COUNT * CONFIG_BT_BAP_BROADCAST_SRC_STREAM_COUNT)
|
||||
|
||||
BUILD_ASSERT(CONFIG_BT_ISO_TX_BUF_COUNT >= TOTAL_BUF_NEEDED,
|
||||
"CONFIG_BT_ISO_TX_BUF_COUNT should be at least "
|
||||
"BROADCAST_ENQUEUE_COUNT * CONFIG_BT_BAP_BROADCAST_SRC_STREAM_COUNT");
|
||||
|
||||
NET_BUF_POOL_FIXED_DEFINE(tx_pool,
|
||||
TOTAL_BUF_NEEDED,
|
||||
BT_ISO_SDU_BUF_SIZE(CONFIG_BT_ISO_TX_MTU),
|
||||
CONFIG_BT_CONN_TX_USER_DATA_SIZE, NULL);
|
||||
|
||||
extern enum bst_result_t bst_result;
|
||||
static struct audio_test_stream broadcast_source_streams[CONFIG_BT_BAP_BROADCAST_SRC_STREAM_COUNT];
|
||||
static struct bt_bap_lc3_preset preset_16_2_1 = BT_BAP_LC3_BROADCAST_PRESET_16_2_1(
|
||||
BT_AUDIO_LOCATION_FRONT_LEFT, BT_AUDIO_CONTEXT_TYPE_UNSPECIFIED);
|
||||
|
@ -216,6 +201,12 @@ static void stream_started_cb(struct bt_bap_stream *stream)
|
|||
return;
|
||||
}
|
||||
|
||||
err = bap_stream_tx_register(stream);
|
||||
if (err != 0) {
|
||||
FAIL("Failed to register stream %p for TX: %d\n", stream, err);
|
||||
return;
|
||||
}
|
||||
|
||||
printk("Stream %p started\n", stream);
|
||||
validate_stream_codec_cfg(stream);
|
||||
k_sem_give(&sem_stream_started);
|
||||
|
@ -223,53 +214,23 @@ static void stream_started_cb(struct bt_bap_stream *stream)
|
|||
|
||||
static void steam_stopped_cb(struct bt_bap_stream *stream, uint8_t reason)
|
||||
{
|
||||
int err;
|
||||
|
||||
printk("Stream %p stopped with reason 0x%02X\n", stream, reason);
|
||||
|
||||
err = bap_stream_tx_unregister(stream);
|
||||
if (err != 0) {
|
||||
FAIL("Failed to unregister stream %p for TX: %d\n", stream, err);
|
||||
return;
|
||||
}
|
||||
|
||||
k_sem_give(&sem_stream_stopped);
|
||||
}
|
||||
|
||||
static void stream_sent_cb(struct bt_bap_stream *stream)
|
||||
{
|
||||
struct audio_test_stream *test_stream = audio_test_stream_from_bap_stream(stream);
|
||||
struct net_buf *buf;
|
||||
int ret;
|
||||
|
||||
if (!test_stream->tx_active) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ((test_stream->tx_cnt % 100U) == 0U) {
|
||||
printk("Sent with seq_num %u\n", test_stream->seq_num);
|
||||
}
|
||||
|
||||
buf = net_buf_alloc(&tx_pool, K_FOREVER);
|
||||
if (buf == NULL) {
|
||||
printk("Could not allocate buffer when sending on %p\n",
|
||||
stream);
|
||||
return;
|
||||
}
|
||||
|
||||
net_buf_reserve(buf, BT_ISO_CHAN_SEND_RESERVE);
|
||||
net_buf_add_mem(buf, mock_iso_data, test_stream->tx_sdu_size);
|
||||
ret = bt_bap_stream_send(stream, buf, test_stream->seq_num++);
|
||||
if (ret < 0) {
|
||||
/* This will end broadcasting on this stream. */
|
||||
net_buf_unref(buf);
|
||||
|
||||
/* Only fail if tx is active (may fail if we are disabling the stream) */
|
||||
if (test_stream->tx_active) {
|
||||
FAIL("Unable to broadcast data on %p: %d\n", stream, ret);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
test_stream->tx_cnt++;
|
||||
}
|
||||
|
||||
static struct bt_bap_stream_ops stream_ops = {
|
||||
.started = stream_started_cb,
|
||||
.stopped = steam_stopped_cb,
|
||||
.sent = stream_sent_cb,
|
||||
.sent = bap_stream_tx_sent_cb,
|
||||
};
|
||||
|
||||
static void source_started_cb(struct bt_bap_broadcast_source *source)
|
||||
|
@ -525,10 +486,6 @@ static void test_broadcast_source_stop(struct bt_bap_broadcast_source *source)
|
|||
|
||||
printk("Stopping broadcast source\n");
|
||||
|
||||
for (size_t i = 0U; i < ARRAY_SIZE(broadcast_source_streams); i++) {
|
||||
broadcast_source_streams[i].tx_active = false;
|
||||
}
|
||||
|
||||
err = bt_bap_broadcast_source_stop(source);
|
||||
if (err != 0) {
|
||||
FAIL("Unable to stop broadcast source: %d\n", err);
|
||||
|
@ -597,6 +554,7 @@ static void init(void)
|
|||
}
|
||||
|
||||
printk("Bluetooth initialized\n");
|
||||
bap_stream_tx_init();
|
||||
|
||||
err = bt_bap_broadcast_source_register_cb(&broadcast_source_cb);
|
||||
if (err != 0) {
|
||||
|
@ -629,17 +587,6 @@ static void test_main(void)
|
|||
|
||||
test_broadcast_source_start(source, adv);
|
||||
|
||||
/* Initialize sending */
|
||||
printk("Sending data\n");
|
||||
for (size_t i = 0U; i < ARRAY_SIZE(broadcast_source_streams); i++) {
|
||||
for (unsigned int j = 0U; j < BROADCAST_ENQUEUE_COUNT; j++) {
|
||||
struct audio_test_stream *test_stream = &broadcast_source_streams[i];
|
||||
|
||||
test_stream->tx_active = true;
|
||||
stream_sent_cb(&test_stream->stream.bap_stream);
|
||||
}
|
||||
}
|
||||
|
||||
/* Wait for other devices to have received what they wanted */
|
||||
backchannel_sync_wait_any();
|
||||
|
||||
|
@ -701,17 +648,6 @@ static void test_main_encrypted(void)
|
|||
|
||||
test_broadcast_source_start(source, adv);
|
||||
|
||||
/* Initialize sending */
|
||||
printk("Sending data\n");
|
||||
for (size_t i = 0U; i < ARRAY_SIZE(broadcast_source_streams); i++) {
|
||||
for (unsigned int j = 0U; j < BROADCAST_ENQUEUE_COUNT; j++) {
|
||||
struct audio_test_stream *test_stream = &broadcast_source_streams[i];
|
||||
|
||||
test_stream->tx_active = true;
|
||||
stream_sent_cb(&test_stream->stream.bap_stream);
|
||||
}
|
||||
}
|
||||
|
||||
/* Wait for other devices to have received data */
|
||||
backchannel_sync_wait_any();
|
||||
|
||||
|
|
|
@ -13,14 +13,14 @@
|
|||
#include "common.h"
|
||||
#include <string.h>
|
||||
|
||||
LOG_MODULE_REGISTER(stream_tx, LOG_LEVEL_INF);
|
||||
LOG_MODULE_REGISTER(bap_stream_rx, LOG_LEVEL_INF);
|
||||
|
||||
static void log_stream_rx(struct bt_bap_stream *stream, const struct bt_iso_recv_info *info,
|
||||
struct net_buf *buf)
|
||||
{
|
||||
struct audio_test_stream *test_stream = audio_test_stream_from_bap_stream(stream);
|
||||
|
||||
LOG_INF("[%zu]: Incoming audio on stream %p len %u, flags 0x%02X, seq_num %u and ts %u\n",
|
||||
LOG_INF("[%zu]: Incoming audio on stream %p len %u, flags 0x%02X, seq_num %u and ts %u",
|
||||
test_stream->rx_cnt, stream, buf->len, info->flags, info->seq_num, info->ts);
|
||||
}
|
||||
|
||||
|
|
221
tests/bsim/bluetooth/audio/src/bap_stream_tx.c
Normal file
221
tests/bsim/bluetooth/audio/src/bap_stream_tx.c
Normal file
|
@ -0,0 +1,221 @@
|
|||
/*
|
||||
* Copyright (c) 2024 Nordic Semiconductor ASA
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <autoconf.h>
|
||||
#include <errno.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <zephyr/bluetooth/audio/cap.h>
|
||||
#include <zephyr/bluetooth/audio/bap.h>
|
||||
#include <zephyr/bluetooth/bluetooth.h>
|
||||
#include <zephyr/bluetooth/hci_types.h>
|
||||
#include <zephyr/bluetooth/iso.h>
|
||||
#include <zephyr/kernel.h>
|
||||
#include <zephyr/kernel/thread_stack.h>
|
||||
#include <zephyr/logging/log.h>
|
||||
#include <zephyr/logging/log_core.h>
|
||||
#include <zephyr/net_buf.h>
|
||||
#include <zephyr/sys/atomic.h>
|
||||
#include <zephyr/sys/atomic_types.h>
|
||||
#include <zephyr/sys/byteorder.h>
|
||||
#include <zephyr/sys/util.h>
|
||||
#include <zephyr/sys/util_macro.h>
|
||||
#include <zephyr/types.h>
|
||||
|
||||
#include "bap_stream_tx.h"
|
||||
#include "common.h"
|
||||
|
||||
/** Enqueue at least 2 per stream, but otherwise equal distribution based on the buf count */
|
||||
#define ENQUEUE_CNT MAX(2, (CONFIG_BT_ISO_TX_BUF_COUNT / CONFIG_BT_ISO_MAX_CHAN))
|
||||
|
||||
LOG_MODULE_REGISTER(bap_stream_tx, LOG_LEVEL_INF);
|
||||
|
||||
struct tx_stream {
|
||||
struct bt_bap_stream *bap_stream;
|
||||
uint16_t seq_num;
|
||||
atomic_t enqueued;
|
||||
};
|
||||
|
||||
static struct tx_stream tx_streams[CONFIG_BT_ISO_MAX_CHAN];
|
||||
|
||||
static bool stream_is_streaming(const struct bt_bap_stream *bap_stream)
|
||||
{
|
||||
struct bt_bap_ep_info ep_info;
|
||||
int err;
|
||||
|
||||
if (bap_stream == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* No-op if stream is not configured */
|
||||
if (bap_stream->ep == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
err = bt_bap_ep_get_info(bap_stream->ep, &ep_info);
|
||||
if (err != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ep_info.iso_chan == NULL || ep_info.iso_chan->state != BT_ISO_STATE_CONNECTED) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return ep_info.state == BT_BAP_EP_STATE_STREAMING;
|
||||
}
|
||||
|
||||
static void tx_thread_func(void *arg1, void *arg2, void *arg3)
|
||||
{
|
||||
NET_BUF_POOL_FIXED_DEFINE(tx_pool, CONFIG_BT_ISO_TX_BUF_COUNT,
|
||||
BT_ISO_SDU_BUF_SIZE(CONFIG_BT_ISO_TX_MTU),
|
||||
CONFIG_BT_CONN_TX_USER_DATA_SIZE, NULL);
|
||||
|
||||
/* This loop will attempt to send on all streams in the streaming state in a round robin
|
||||
* fashion.
|
||||
* The TX is controlled by the number of buffers configured, and increasing
|
||||
* CONFIG_BT_ISO_TX_BUF_COUNT will allow for more streams in parallel, or to submit more
|
||||
* buffers per stream.
|
||||
* Once a buffer has been freed by the stack, it triggers the next TX.
|
||||
*/
|
||||
while (true) {
|
||||
int err = -ENOEXEC;
|
||||
|
||||
for (size_t i = 0U; i < ARRAY_SIZE(tx_streams); i++) {
|
||||
struct bt_bap_stream *bap_stream = tx_streams[i].bap_stream;
|
||||
|
||||
if (stream_is_streaming(bap_stream) &&
|
||||
atomic_get(&tx_streams[i].enqueued) < ENQUEUE_CNT) {
|
||||
struct net_buf *buf;
|
||||
|
||||
buf = net_buf_alloc(&tx_pool, K_FOREVER);
|
||||
net_buf_reserve(buf, BT_ISO_CHAN_SEND_RESERVE);
|
||||
|
||||
net_buf_add_mem(buf, mock_iso_data, bap_stream->qos->sdu);
|
||||
|
||||
err = bt_bap_stream_send(bap_stream, buf, tx_streams[i].seq_num);
|
||||
if (err == 0) {
|
||||
tx_streams[i].seq_num++;
|
||||
atomic_inc(&tx_streams[i].enqueued);
|
||||
} else {
|
||||
if (!stream_is_streaming(bap_stream)) {
|
||||
/* Can happen if we disconnected while waiting for a
|
||||
* buffer - Ignore
|
||||
*/
|
||||
} else {
|
||||
FAIL("Unable to send: %d", err);
|
||||
}
|
||||
|
||||
net_buf_unref(buf);
|
||||
}
|
||||
} /* No-op if stream is not streaming */
|
||||
}
|
||||
|
||||
if (err != 0) {
|
||||
/* In case of any errors, retry with a delay */
|
||||
k_sleep(K_MSEC(10));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int bap_stream_tx_register(struct bt_bap_stream *bap_stream)
|
||||
{
|
||||
if (bap_stream == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!bap_stream_tx_can_send(bap_stream)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
for (size_t i = 0U; i < ARRAY_SIZE(tx_streams); i++) {
|
||||
if (tx_streams[i].bap_stream == NULL) {
|
||||
tx_streams[i].bap_stream = bap_stream;
|
||||
tx_streams[i].seq_num = 0U;
|
||||
|
||||
LOG_INF("Registered %p for TX", bap_stream);
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
int bap_stream_tx_unregister(struct bt_bap_stream *bap_stream)
|
||||
{
|
||||
if (bap_stream == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
for (size_t i = 0U; i < ARRAY_SIZE(tx_streams); i++) {
|
||||
if (tx_streams[i].bap_stream == bap_stream) {
|
||||
tx_streams[i].bap_stream = NULL;
|
||||
atomic_set(&tx_streams[i].enqueued, 0);
|
||||
|
||||
LOG_INF("Unregistered %p for TX", bap_stream);
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return -ENODATA;
|
||||
}
|
||||
|
||||
void bap_stream_tx_init(void)
|
||||
{
|
||||
static bool thread_started;
|
||||
|
||||
if (!thread_started) {
|
||||
static K_KERNEL_STACK_DEFINE(tx_thread_stack, 1024U);
|
||||
const int tx_thread_prio = K_PRIO_PREEMPT(5);
|
||||
static struct k_thread tx_thread;
|
||||
|
||||
k_thread_create(&tx_thread, tx_thread_stack, K_KERNEL_STACK_SIZEOF(tx_thread_stack),
|
||||
tx_thread_func, NULL, NULL, NULL, tx_thread_prio, 0, K_NO_WAIT);
|
||||
k_thread_name_set(&tx_thread, "TX thread");
|
||||
thread_started = true;
|
||||
}
|
||||
}
|
||||
|
||||
bool bap_stream_tx_can_send(const struct bt_bap_stream *stream)
|
||||
{
|
||||
struct bt_bap_ep_info info;
|
||||
int err;
|
||||
|
||||
if (stream == NULL || stream->ep == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
err = bt_bap_ep_get_info(stream->ep, &info);
|
||||
if (err != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return info.can_send;
|
||||
}
|
||||
|
||||
void bap_stream_tx_sent_cb(struct bt_bap_stream *stream)
|
||||
{
|
||||
struct audio_test_stream *test_stream = audio_test_stream_from_bap_stream(stream);
|
||||
|
||||
if ((test_stream->tx_cnt % 100U) == 0U) {
|
||||
LOG_INF("Stream %p sent %zu SDUs", stream, test_stream->tx_cnt);
|
||||
}
|
||||
|
||||
test_stream->tx_cnt++;
|
||||
|
||||
for (size_t i = 0U; i < ARRAY_SIZE(tx_streams); i++) {
|
||||
if (tx_streams[i].bap_stream == stream) {
|
||||
const atomic_val_t old = atomic_dec(&tx_streams[i].enqueued);
|
||||
|
||||
if (old == 0) {
|
||||
FAIL("Old enqueue count was 0");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
69
tests/bsim/bluetooth/audio/src/bap_stream_tx.h
Normal file
69
tests/bsim/bluetooth/audio/src/bap_stream_tx.h
Normal file
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* Copyright (c) 2024 Nordic Semiconductor ASA
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef STREAM_TX_H
|
||||
#define STREAM_TX_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <zephyr/bluetooth/conn.h>
|
||||
#include <zephyr/bluetooth/audio/bap.h>
|
||||
#include <zephyr/bluetooth/audio/cap.h>
|
||||
#include <zephyr/types.h>
|
||||
|
||||
/**
|
||||
* @brief Initialize TX
|
||||
*
|
||||
* This will initialize TX if not already initialized. This creates and starts a thread that
|
||||
* will attempt to send data on all streams registered with bap_stream_tx_register().
|
||||
*/
|
||||
void bap_stream_tx_init(void);
|
||||
|
||||
/**
|
||||
* @brief Register a stream for TX
|
||||
*
|
||||
* This will add it to the list of streams the TX thread will attempt to send on.
|
||||
*
|
||||
* @param bap_stream The stream to register
|
||||
*
|
||||
* @retval 0 on success
|
||||
* @retval -EINVAL @p bap_stream is NULL
|
||||
* @retval -EINVAL @p bap_stream is not configured for TX
|
||||
* @retval -EINVAL @p bap_stream.codec_cfg contains invalid values
|
||||
* @retval -ENOMEM if not more streams can be registered
|
||||
*/
|
||||
int bap_stream_tx_register(struct bt_bap_stream *bap_stream);
|
||||
|
||||
/**
|
||||
* @brief Unregister a stream for TX
|
||||
*
|
||||
* This will remove it to the list of streams the TX thread will attempt to send on.
|
||||
*
|
||||
* @param bap_stream The stream to unregister
|
||||
*
|
||||
* @retval 0 on success
|
||||
* @retval -EINVAL @p bap_stream is NULL
|
||||
* @retval -EINVAL @p bap_stream is not configured for TX
|
||||
* @retval -EALREADY @p bap_stream is currently not registered
|
||||
*/
|
||||
int bap_stream_tx_unregister(struct bt_bap_stream *bap_stream);
|
||||
|
||||
/**
|
||||
* @brief Test if the provided stream has been configured for TX
|
||||
*
|
||||
* @param bap_stream The stream to test for TX support
|
||||
*
|
||||
* @retval true if it has been configured for TX, and false if not
|
||||
*/
|
||||
bool bap_stream_tx_can_send(const struct bt_bap_stream *stream);
|
||||
|
||||
/**
|
||||
* @brief Callback to indicate a TX complete
|
||||
*
|
||||
* @param stream The stream that completed TX
|
||||
*/
|
||||
void bap_stream_tx_sent_cb(struct bt_bap_stream *stream);
|
||||
#endif /* STREAM_TX_H */
|
|
@ -30,6 +30,7 @@
|
|||
#include <zephyr/sys/util.h>
|
||||
|
||||
#include "bap_stream_rx.h"
|
||||
#include "bap_stream_tx.h"
|
||||
#include "bstests.h"
|
||||
#include "common.h"
|
||||
#include "bap_common.h"
|
||||
|
@ -38,11 +39,6 @@
|
|||
|
||||
#define BAP_STREAM_RETRY_WAIT K_MSEC(100)
|
||||
|
||||
#define ENQUEUE_COUNT 2U
|
||||
#define TOTAL_BUF_NEEDED (ENQUEUE_COUNT * CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SNK_COUNT)
|
||||
NET_BUF_POOL_FIXED_DEFINE(tx_pool, TOTAL_BUF_NEEDED, BT_ISO_SDU_BUF_SIZE(CONFIG_BT_ISO_TX_MTU),
|
||||
CONFIG_BT_CONN_TX_USER_DATA_SIZE, NULL);
|
||||
|
||||
extern enum bst_result_t bst_result;
|
||||
|
||||
static struct audio_test_stream test_streams[CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SNK_COUNT];
|
||||
|
@ -106,6 +102,16 @@ static void stream_started(struct bt_bap_stream *stream)
|
|||
{
|
||||
printk("Started stream %p\n", stream);
|
||||
|
||||
if (bap_stream_tx_can_send(stream)) {
|
||||
int err;
|
||||
|
||||
err = bap_stream_tx_register(stream);
|
||||
if (err != 0) {
|
||||
FAIL("Failed to register stream %p for TX: %d\n", stream, err);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
SET_FLAG(flag_stream_started);
|
||||
}
|
||||
|
||||
|
@ -132,10 +138,6 @@ static void stream_metadata_updated(struct bt_bap_stream *stream)
|
|||
|
||||
static void stream_disabled(struct bt_bap_stream *stream)
|
||||
{
|
||||
struct audio_test_stream *test_stream = audio_test_stream_from_bap_stream(stream);
|
||||
|
||||
test_stream->tx_active = false;
|
||||
|
||||
printk("Disabled stream %p\n", stream);
|
||||
|
||||
SET_FLAG(flag_stream_disabled);
|
||||
|
@ -145,6 +147,16 @@ static void stream_stopped(struct bt_bap_stream *stream, uint8_t reason)
|
|||
{
|
||||
printk("Stopped stream %p with reason 0x%02X\n", stream, reason);
|
||||
|
||||
if (bap_stream_tx_can_send(stream)) {
|
||||
int err;
|
||||
|
||||
err = bap_stream_tx_unregister(stream);
|
||||
if (err != 0) {
|
||||
FAIL("Failed to unregister stream %p for TX: %d\n", stream, err);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
SET_FLAG(flag_stream_stopped);
|
||||
}
|
||||
|
||||
|
@ -155,40 +167,6 @@ static void stream_released(struct bt_bap_stream *stream)
|
|||
SET_FLAG(flag_stream_released);
|
||||
}
|
||||
|
||||
static void stream_sent_cb(struct bt_bap_stream *stream)
|
||||
{
|
||||
struct audio_test_stream *test_stream = audio_test_stream_from_bap_stream(stream);
|
||||
struct net_buf *buf;
|
||||
int ret;
|
||||
|
||||
if (!test_stream->tx_active) {
|
||||
return;
|
||||
}
|
||||
|
||||
buf = net_buf_alloc(&tx_pool, K_FOREVER);
|
||||
if (buf == NULL) {
|
||||
printk("Could not allocate buffer when sending on %p\n", stream);
|
||||
return;
|
||||
}
|
||||
|
||||
net_buf_reserve(buf, BT_ISO_CHAN_SEND_RESERVE);
|
||||
net_buf_add_mem(buf, mock_iso_data, test_stream->tx_sdu_size);
|
||||
ret = bt_bap_stream_send(stream, buf, test_stream->seq_num++);
|
||||
if (ret < 0) {
|
||||
/* This will end broadcasting on this stream. */
|
||||
net_buf_unref(buf);
|
||||
|
||||
/* Only fail if tx is active (may fail if we are disabling the stream) */
|
||||
if (test_stream->tx_active) {
|
||||
FAIL("Unable to send data on %p: %d\n", stream, ret);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
test_stream->tx_cnt++;
|
||||
}
|
||||
|
||||
static struct bt_bap_stream_ops stream_ops = {
|
||||
.configured = stream_configured,
|
||||
.qos_set = stream_qos_set,
|
||||
|
@ -199,7 +177,7 @@ static struct bt_bap_stream_ops stream_ops = {
|
|||
.stopped = stream_stopped,
|
||||
.released = stream_released,
|
||||
.recv = bap_stream_rx_recv_cb,
|
||||
.sent = stream_sent_cb,
|
||||
.sent = bap_stream_tx_sent_cb,
|
||||
.connected = stream_connected,
|
||||
.disconnected = stream_disconnected,
|
||||
};
|
||||
|
@ -496,6 +474,9 @@ static void init(void)
|
|||
return;
|
||||
}
|
||||
|
||||
printk("Bluetooth initialized\n");
|
||||
bap_stream_tx_init();
|
||||
|
||||
for (size_t i = 0; i < ARRAY_SIZE(test_streams); i++) {
|
||||
struct bt_bap_stream *bap_stream =
|
||||
bap_stream_from_audio_test_stream(&test_streams[i]);
|
||||
|
@ -846,11 +827,6 @@ static void transceive_streams(void)
|
|||
struct audio_test_stream *test_stream =
|
||||
audio_test_stream_from_bap_stream(sink_stream);
|
||||
|
||||
test_stream->tx_active = true;
|
||||
for (unsigned int i = 0U; i < ENQUEUE_COUNT; i++) {
|
||||
stream_sent_cb(sink_stream);
|
||||
}
|
||||
|
||||
/* Keep sending until we reach the minimum expected */
|
||||
while (test_stream->tx_cnt < MIN_SEND_COUNT) {
|
||||
k_sleep(K_MSEC(100));
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
|
||||
#include "bap_common.h"
|
||||
#include "bap_stream_rx.h"
|
||||
#include "bap_stream_tx.h"
|
||||
#include "bstests.h"
|
||||
#include "common.h"
|
||||
|
||||
|
@ -39,11 +40,6 @@ extern enum bst_result_t bst_result;
|
|||
|
||||
#define PREF_CONTEXT (BT_AUDIO_CONTEXT_TYPE_CONVERSATIONAL | BT_AUDIO_CONTEXT_TYPE_MEDIA)
|
||||
|
||||
#define ENQUEUE_COUNT 2U
|
||||
#define TOTAL_BUF_NEEDED (ENQUEUE_COUNT * CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SNK_COUNT)
|
||||
NET_BUF_POOL_FIXED_DEFINE(tx_pool, TOTAL_BUF_NEEDED, BT_ISO_SDU_BUF_SIZE(CONFIG_BT_ISO_TX_MTU),
|
||||
CONFIG_BT_CONN_TX_USER_DATA_SIZE, NULL);
|
||||
|
||||
static const struct bt_audio_codec_cap lc3_codec_cap = {
|
||||
.path_id = BT_ISO_DATA_PATH_HCI,
|
||||
.id = BT_HCI_CODING_FORMAT_LC3,
|
||||
|
@ -203,12 +199,8 @@ static int lc3_metadata(struct bt_bap_stream *stream, const uint8_t meta[], size
|
|||
|
||||
static int lc3_disable(struct bt_bap_stream *stream, struct bt_bap_ascs_rsp *rsp)
|
||||
{
|
||||
struct audio_test_stream *test_stream = audio_test_stream_from_bap_stream(stream);
|
||||
|
||||
printk("Disable: stream %p\n", stream);
|
||||
|
||||
test_stream->tx_active = false;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -271,48 +263,40 @@ static void stream_started_cb(struct bt_bap_stream *stream)
|
|||
{
|
||||
printk("Started: stream %p\n", stream);
|
||||
|
||||
if (bap_stream_tx_can_send(stream)) {
|
||||
int err;
|
||||
|
||||
err = bap_stream_tx_register(stream);
|
||||
if (err != 0) {
|
||||
FAIL("Failed to register stream %p for TX: %d\n", stream, err);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
SET_FLAG(flag_stream_started);
|
||||
}
|
||||
|
||||
static void stream_sent_cb(struct bt_bap_stream *stream)
|
||||
static void stream_stopped_cb(struct bt_bap_stream *stream, uint8_t reason)
|
||||
{
|
||||
struct audio_test_stream *test_stream = audio_test_stream_from_bap_stream(stream);
|
||||
struct net_buf *buf;
|
||||
int ret;
|
||||
printk("Stopped stream %p with reason 0x%02X\n", stream, reason);
|
||||
|
||||
if (!test_stream->tx_active) {
|
||||
return;
|
||||
}
|
||||
if (bap_stream_tx_can_send(stream)) {
|
||||
int err;
|
||||
|
||||
buf = net_buf_alloc(&tx_pool, K_FOREVER);
|
||||
if (buf == NULL) {
|
||||
printk("Could not allocate buffer when sending on %p\n", stream);
|
||||
return;
|
||||
}
|
||||
|
||||
net_buf_reserve(buf, BT_ISO_CHAN_SEND_RESERVE);
|
||||
net_buf_add_mem(buf, mock_iso_data, test_stream->tx_sdu_size);
|
||||
ret = bt_bap_stream_send(stream, buf, test_stream->seq_num++);
|
||||
if (ret < 0) {
|
||||
/* This will end broadcasting on this stream. */
|
||||
net_buf_unref(buf);
|
||||
|
||||
/* Only fail if tx is active (may fail if we are disabling the stream) */
|
||||
if (test_stream->tx_active) {
|
||||
FAIL("Unable to send data on %p: %d\n", stream, ret);
|
||||
err = bap_stream_tx_unregister(stream);
|
||||
if (err != 0) {
|
||||
FAIL("Failed to unregister stream %p for TX: %d\n", stream, err);
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
test_stream->tx_cnt++;
|
||||
}
|
||||
|
||||
static struct bt_bap_stream_ops stream_ops = {
|
||||
.enabled = stream_enabled_cb,
|
||||
.started = stream_started_cb,
|
||||
.stopped = stream_stopped_cb,
|
||||
.recv = bap_stream_rx_recv_cb,
|
||||
.sent = stream_sent_cb,
|
||||
.sent = bap_stream_tx_sent_cb,
|
||||
};
|
||||
|
||||
static void transceive_test_streams(void)
|
||||
|
@ -358,11 +342,6 @@ static void transceive_test_streams(void)
|
|||
struct audio_test_stream *test_stream =
|
||||
audio_test_stream_from_bap_stream(source_stream);
|
||||
|
||||
test_stream->tx_active = true;
|
||||
for (unsigned int i = 0U; i < ENQUEUE_COUNT; i++) {
|
||||
stream_sent_cb(source_stream);
|
||||
}
|
||||
|
||||
/* Keep sending until we reach the minimum expected */
|
||||
while (test_stream->tx_cnt < MIN_SEND_COUNT) {
|
||||
k_sleep(K_MSEC(100));
|
||||
|
@ -450,6 +429,7 @@ static void init(void)
|
|||
}
|
||||
|
||||
printk("Bluetooth initialized\n");
|
||||
bap_stream_tx_init();
|
||||
|
||||
err = bt_bap_unicast_server_register(¶m);
|
||||
if (err != 0) {
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include <zephyr/toolchain.h>
|
||||
|
||||
#include "bap_common.h"
|
||||
#include "bap_stream_tx.h"
|
||||
#include "bstests.h"
|
||||
#include "common.h"
|
||||
|
||||
|
@ -49,19 +50,10 @@ CREATE_FLAG(flag_source_started);
|
|||
BT_GAP_MS_TO_PER_ADV_INTERVAL(150), BT_LE_PER_ADV_OPT_NONE)
|
||||
|
||||
#define BROADCAST_STREMT_CNT CONFIG_BT_BAP_BROADCAST_SRC_STREAM_COUNT
|
||||
#define BROADCAST_ENQUEUE_COUNT 18U
|
||||
#define TOTAL_BUF_NEEDED (BROADCAST_ENQUEUE_COUNT * BROADCAST_STREMT_CNT)
|
||||
#define CAP_AC_MAX_STREAM 2
|
||||
#define LOCATION (BT_AUDIO_LOCATION_FRONT_LEFT | BT_AUDIO_LOCATION_FRONT_RIGHT)
|
||||
#define CONTEXT (BT_AUDIO_CONTEXT_TYPE_MEDIA)
|
||||
|
||||
BUILD_ASSERT(CONFIG_BT_ISO_TX_BUF_COUNT >= TOTAL_BUF_NEEDED,
|
||||
"CONFIG_BT_ISO_TX_BUF_COUNT should be at least "
|
||||
"BROADCAST_ENQUEUE_COUNT * BROADCAST_STREMT_CNT");
|
||||
|
||||
NET_BUF_POOL_FIXED_DEFINE(tx_pool, TOTAL_BUF_NEEDED, BT_ISO_SDU_BUF_SIZE(CONFIG_BT_ISO_TX_MTU),
|
||||
CONFIG_BT_CONN_TX_USER_DATA_SIZE, NULL);
|
||||
|
||||
struct cap_initiator_ac_param {
|
||||
char *name;
|
||||
size_t stream_cnt;
|
||||
|
@ -119,70 +111,41 @@ static const struct named_lc3_preset lc3_broadcast_presets[] = {
|
|||
static void broadcast_stream_started_cb(struct bt_bap_stream *stream)
|
||||
{
|
||||
struct audio_test_stream *test_stream = audio_test_stream_from_bap_stream(stream);
|
||||
int err;
|
||||
|
||||
test_stream->seq_num = 0U;
|
||||
test_stream->tx_cnt = 0U;
|
||||
|
||||
printk("Stream %p started\n", stream);
|
||||
|
||||
err = bap_stream_tx_register(stream);
|
||||
if (err != 0) {
|
||||
FAIL("Failed to register stream %p for TX: %d\n", stream, err);
|
||||
return;
|
||||
}
|
||||
|
||||
k_sem_give(&sem_broadcast_stream_started);
|
||||
}
|
||||
|
||||
static void broadcast_stream_stopped_cb(struct bt_bap_stream *stream, uint8_t reason)
|
||||
{
|
||||
int err;
|
||||
|
||||
printk("Stream %p stopped with reason 0x%02X\n", stream, reason);
|
||||
|
||||
err = bap_stream_tx_unregister(stream);
|
||||
if (err != 0) {
|
||||
FAIL("Failed to unregister stream %p for TX: %d\n", stream, err);
|
||||
return;
|
||||
}
|
||||
|
||||
k_sem_give(&sem_broadcast_stream_stopped);
|
||||
}
|
||||
|
||||
static void broadcast_stream_sent_cb(struct bt_bap_stream *bap_stream)
|
||||
{
|
||||
struct audio_test_stream *test_stream = audio_test_stream_from_bap_stream(bap_stream);
|
||||
struct bt_cap_stream *cap_stream = cap_stream_from_audio_test_stream(test_stream);
|
||||
struct net_buf *buf;
|
||||
int ret;
|
||||
|
||||
if (!test_stream->tx_active) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ((test_stream->tx_cnt % 100U) == 0U) {
|
||||
printk("[%zu]: Stream %p sent with seq_num %u\n", test_stream->tx_cnt, cap_stream,
|
||||
test_stream->seq_num);
|
||||
}
|
||||
|
||||
if (test_stream->tx_sdu_size > CONFIG_BT_ISO_TX_MTU) {
|
||||
FAIL("Invalid SDU %u for the MTU: %d", test_stream->tx_sdu_size,
|
||||
CONFIG_BT_ISO_TX_MTU);
|
||||
return;
|
||||
}
|
||||
|
||||
buf = net_buf_alloc(&tx_pool, K_FOREVER);
|
||||
if (buf == NULL) {
|
||||
printk("Could not allocate buffer when sending on %p\n", bap_stream);
|
||||
return;
|
||||
}
|
||||
|
||||
net_buf_reserve(buf, BT_ISO_CHAN_SEND_RESERVE);
|
||||
net_buf_add_mem(buf, mock_iso_data, test_stream->tx_sdu_size);
|
||||
ret = bt_cap_stream_send(cap_stream, buf, test_stream->seq_num++);
|
||||
if (ret < 0) {
|
||||
/* This will end broadcasting on this stream. */
|
||||
net_buf_unref(buf);
|
||||
|
||||
/* Only fail if tx is active (may fail if we are disabling the stream) */
|
||||
if (test_stream->tx_active) {
|
||||
FAIL("Unable to broadcast data on %p: %d\n", cap_stream, ret);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
test_stream->tx_cnt++;
|
||||
}
|
||||
|
||||
static struct bt_bap_stream_ops broadcast_stream_ops = {
|
||||
.started = broadcast_stream_started_cb,
|
||||
.stopped = broadcast_stream_stopped_cb,
|
||||
.sent = broadcast_stream_sent_cb,
|
||||
.sent = bap_stream_tx_sent_cb,
|
||||
};
|
||||
|
||||
static void broadcast_source_started_cb(struct bt_cap_broadcast_source *broadcast_source)
|
||||
|
@ -212,6 +175,9 @@ static void init(void)
|
|||
return;
|
||||
}
|
||||
|
||||
printk("Bluetooth initialized\n");
|
||||
bap_stream_tx_init();
|
||||
|
||||
(void)memset(broadcast_source_streams, 0, sizeof(broadcast_source_streams));
|
||||
|
||||
for (size_t i = 0; i < ARRAY_SIZE(broadcast_streams); i++) {
|
||||
|
@ -617,10 +583,6 @@ static void test_broadcast_audio_stop(struct bt_cap_broadcast_source *broadcast_
|
|||
|
||||
printk("Stopping broadcast source\n");
|
||||
|
||||
for (size_t i = 0U; i < ARRAY_SIZE(broadcast_source_streams); i++) {
|
||||
broadcast_source_streams[i].tx_active = false;
|
||||
}
|
||||
|
||||
err = bt_cap_initiator_broadcast_audio_stop(broadcast_source);
|
||||
if (err != 0) {
|
||||
FAIL("Failed to stop broadcast source: %d\n", err);
|
||||
|
@ -711,17 +673,6 @@ static void test_main_cap_initiator_broadcast(void)
|
|||
|
||||
WAIT_FOR_FLAG(flag_source_started);
|
||||
|
||||
/* Initialize sending */
|
||||
for (size_t i = 0U; i < stream_count; i++) {
|
||||
struct audio_test_stream *test_stream = &broadcast_source_streams[i];
|
||||
|
||||
test_stream->tx_active = true;
|
||||
|
||||
for (unsigned int j = 0U; j < BROADCAST_ENQUEUE_COUNT; j++) {
|
||||
broadcast_stream_sent_cb(bap_stream_from_audio_test_stream(test_stream));
|
||||
}
|
||||
}
|
||||
|
||||
/* Wait for other devices to have received what they wanted */
|
||||
backchannel_sync_wait_any();
|
||||
|
||||
|
@ -819,17 +770,6 @@ static int test_cap_initiator_ac(const struct cap_initiator_ac_param *param)
|
|||
|
||||
WAIT_FOR_FLAG(flag_source_started);
|
||||
|
||||
/* Initialize sending */
|
||||
for (size_t i = 0U; i < stream_count; i++) {
|
||||
struct audio_test_stream *test_stream = &broadcast_source_streams[i];
|
||||
|
||||
test_stream->tx_active = true;
|
||||
|
||||
for (unsigned int j = 0U; j < BROADCAST_ENQUEUE_COUNT; j++) {
|
||||
broadcast_stream_sent_cb(bap_stream_from_audio_test_stream(test_stream));
|
||||
}
|
||||
}
|
||||
|
||||
/* Wait for other devices to have received what they wanted */
|
||||
backchannel_sync_wait_any();
|
||||
|
||||
|
|
|
@ -107,7 +107,7 @@ extern enum bst_result_t bst_result;
|
|||
#define PA_SYNC_INTERVAL_TO_TIMEOUT_RATIO 20 /* Set the timeout relative to interval */
|
||||
#define PA_SYNC_SKIP 5
|
||||
|
||||
#define PBP_STREAMS_TO_SEND 2
|
||||
#define PBP_STREAMS_TO_SEND 2
|
||||
|
||||
extern struct bt_le_scan_cb common_scan_cb;
|
||||
extern const struct bt_data ad[AD_SIZE];
|
||||
|
@ -135,7 +135,6 @@ struct audio_test_stream {
|
|||
struct bt_cap_stream stream;
|
||||
|
||||
uint16_t seq_num;
|
||||
bool tx_active;
|
||||
size_t tx_cnt;
|
||||
uint16_t tx_sdu_size;
|
||||
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include <zephyr/sys/util_macro.h>
|
||||
#include <zephyr/toolchain.h>
|
||||
|
||||
#include "bap_stream_tx.h"
|
||||
#include "bstests.h"
|
||||
#include "common.h"
|
||||
#include "bap_common.h"
|
||||
|
@ -65,17 +66,6 @@
|
|||
#define GMAP_UNICAST_AC_MAX_PAIR MAX(GMAP_UNICAST_AC_MAX_SNK, GMAP_UNICAST_AC_MAX_SRC)
|
||||
#define GMAP_UNICAST_AC_MAX_STREAM (GMAP_UNICAST_AC_MAX_SNK + GMAP_UNICAST_AC_MAX_SRC)
|
||||
|
||||
#define MAX_ISO_CHAN_COUNT 2U
|
||||
#define ISO_ENQUEUE_COUNT 2U
|
||||
#define TOTAL_BUF_NEEDED (ISO_ENQUEUE_COUNT * MAX_ISO_CHAN_COUNT)
|
||||
|
||||
BUILD_ASSERT(
|
||||
CONFIG_BT_ISO_TX_BUF_COUNT >= TOTAL_BUF_NEEDED,
|
||||
"CONFIG_BT_ISO_TX_BUF_COUNT should be at least ISO_ENQUEUE_COUNT * MAX_ISO_CHAN_COUNT");
|
||||
|
||||
NET_BUF_POOL_FIXED_DEFINE(tx_pool, TOTAL_BUF_NEEDED, BT_ISO_SDU_BUF_SIZE(CONFIG_BT_ISO_TX_MTU),
|
||||
CONFIG_BT_CONN_TX_USER_DATA_SIZE, NULL);
|
||||
|
||||
extern enum bst_result_t bst_result;
|
||||
static const struct named_lc3_preset *snk_named_preset;
|
||||
static const struct named_lc3_preset *src_named_preset;
|
||||
|
@ -178,52 +168,6 @@ const struct named_lc3_preset *gmap_get_named_preset(bool is_unicast, enum bt_au
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static void stream_sent_cb(struct bt_bap_stream *bap_stream)
|
||||
{
|
||||
struct audio_test_stream *test_stream = audio_test_stream_from_bap_stream(bap_stream);
|
||||
struct bt_cap_stream *cap_stream = cap_stream_from_audio_test_stream(test_stream);
|
||||
struct net_buf *buf;
|
||||
int ret;
|
||||
|
||||
if (!test_stream->tx_active) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ((test_stream->tx_cnt % 100U) == 0U) {
|
||||
printk("[%zu]: Stream %p sent with seq_num %u\n", test_stream->tx_cnt, cap_stream,
|
||||
test_stream->seq_num);
|
||||
}
|
||||
|
||||
if (test_stream->tx_sdu_size > CONFIG_BT_ISO_TX_MTU) {
|
||||
FAIL("Invalid SDU %u for the MTU: %d", test_stream->tx_sdu_size,
|
||||
CONFIG_BT_ISO_TX_MTU);
|
||||
return;
|
||||
}
|
||||
|
||||
buf = net_buf_alloc(&tx_pool, K_FOREVER);
|
||||
if (buf == NULL) {
|
||||
printk("Could not allocate buffer when sending on %p\n", bap_stream);
|
||||
return;
|
||||
}
|
||||
|
||||
net_buf_reserve(buf, BT_ISO_CHAN_SEND_RESERVE);
|
||||
net_buf_add_mem(buf, mock_iso_data, test_stream->tx_sdu_size);
|
||||
ret = bt_cap_stream_send(cap_stream, buf, test_stream->seq_num++);
|
||||
if (ret < 0) {
|
||||
/* This will end broadcasting on this stream. */
|
||||
net_buf_unref(buf);
|
||||
|
||||
/* Only fail if tx is active (may fail if we are disabling the stream) */
|
||||
if (test_stream->tx_active) {
|
||||
FAIL("Unable to broadcast data on %p: %d\n", cap_stream, ret);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
test_stream->tx_cnt++;
|
||||
}
|
||||
|
||||
static void stream_configured_cb(struct bt_bap_stream *stream,
|
||||
const struct bt_bap_qos_cfg_pref *pref)
|
||||
{
|
||||
|
@ -247,6 +191,17 @@ static void stream_enabled_cb(struct bt_bap_stream *stream)
|
|||
static void stream_started_cb(struct bt_bap_stream *stream)
|
||||
{
|
||||
printk("Started stream %p\n", stream);
|
||||
|
||||
if (bap_stream_tx_can_send(stream)) {
|
||||
int err;
|
||||
|
||||
err = bap_stream_tx_register(stream);
|
||||
if (err != 0) {
|
||||
FAIL("Failed to register stream %p for TX: %d\n", stream, err);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
k_sem_give(&sem_stream_started);
|
||||
}
|
||||
|
||||
|
@ -263,6 +218,17 @@ static void stream_disabled_cb(struct bt_bap_stream *stream)
|
|||
static void stream_stopped_cb(struct bt_bap_stream *stream, uint8_t reason)
|
||||
{
|
||||
printk("Stream %p stopped with reason 0x%02X\n", stream, reason);
|
||||
|
||||
if (bap_stream_tx_can_send(stream)) {
|
||||
int err;
|
||||
|
||||
err = bap_stream_tx_unregister(stream);
|
||||
if (err != 0) {
|
||||
FAIL("Failed to unregister stream %p for TX: %d\n", stream, err);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
k_sem_give(&sem_stream_stopped);
|
||||
}
|
||||
|
||||
|
@ -280,7 +246,7 @@ static struct bt_bap_stream_ops stream_ops = {
|
|||
.disabled = stream_disabled_cb,
|
||||
.stopped = stream_stopped_cb,
|
||||
.released = stream_released_cb,
|
||||
.sent = stream_sent_cb,
|
||||
.sent = bap_stream_tx_sent_cb,
|
||||
};
|
||||
|
||||
static void cap_discovery_complete_cb(struct bt_conn *conn, int err,
|
||||
|
@ -473,6 +439,9 @@ static void init(void)
|
|||
return;
|
||||
}
|
||||
|
||||
printk("Bluetooth initialized\n");
|
||||
bap_stream_tx_init();
|
||||
|
||||
bt_gatt_cb_register(&gatt_callbacks);
|
||||
|
||||
err = bt_bap_unicast_client_register_cb(&unicast_client_cbs);
|
||||
|
@ -1153,10 +1122,6 @@ static void broadcast_audio_stop(struct bt_cap_broadcast_source *broadcast_sourc
|
|||
|
||||
printk("Stopping broadcast source\n");
|
||||
|
||||
for (size_t i = 0U; i < ARRAY_SIZE(broadcast_streams); i++) {
|
||||
broadcast_streams[i].tx_active = false;
|
||||
}
|
||||
|
||||
err = bt_cap_initiator_broadcast_audio_stop(broadcast_source);
|
||||
if (err != 0) {
|
||||
FAIL("Failed to stop broadcast source: %d\n", err);
|
||||
|
@ -1257,18 +1222,6 @@ static int test_gmap_ugg_broadcast_ac(const struct gmap_broadcast_ac_param *para
|
|||
k_sem_take(&sem_stream_started, K_FOREVER);
|
||||
}
|
||||
|
||||
/* Initialize sending */
|
||||
printk("Starting sending\n");
|
||||
for (size_t i = 0U; i < param->stream_cnt; i++) {
|
||||
struct audio_test_stream *test_stream = &broadcast_streams[i];
|
||||
|
||||
test_stream->tx_active = true;
|
||||
|
||||
for (unsigned int j = 0U; j < ISO_ENQUEUE_COUNT; j++) {
|
||||
stream_sent_cb(bap_stream_from_audio_test_stream(test_stream));
|
||||
}
|
||||
}
|
||||
|
||||
/* Wait for other devices to have received what they wanted */
|
||||
backchannel_sync_wait_any();
|
||||
|
||||
|
|
|
@ -26,30 +26,17 @@
|
|||
#include <zephyr/sys/util.h>
|
||||
#include <zephyr/toolchain.h>
|
||||
|
||||
#include "bap_stream_tx.h"
|
||||
#include "bstests.h"
|
||||
#include "common.h"
|
||||
|
||||
#if defined(CONFIG_BT_PBP)
|
||||
/* When BROADCAST_ENQUEUE_COUNT > 1 we can enqueue enough buffers to ensure that
|
||||
* the controller is never idle
|
||||
*/
|
||||
#define BROADCAST_ENQUEUE_COUNT 2U
|
||||
#define BUF_NEEDED (BROADCAST_ENQUEUE_COUNT * CONFIG_BT_BAP_BROADCAST_SRC_STREAM_COUNT)
|
||||
/* PBS ASCII text */
|
||||
#define PBS_DEMO 'P', 'B', 'P'
|
||||
#define SEM_TIMEOUT K_SECONDS(2)
|
||||
|
||||
extern enum bst_result_t bst_result;
|
||||
|
||||
BUILD_ASSERT(CONFIG_BT_ISO_TX_BUF_COUNT >= BUF_NEEDED,
|
||||
"CONFIG_BT_ISO_TX_BUF_COUNT should be at least "
|
||||
"BROADCAST_ENQUEUE_COUNT * CONFIG_BT_BAP_BROADCAST_SRC_STREAM_COUNT");
|
||||
|
||||
NET_BUF_POOL_FIXED_DEFINE(tx_pool,
|
||||
BUF_NEEDED,
|
||||
BT_ISO_SDU_BUF_SIZE(CONFIG_BT_ISO_TX_MTU),
|
||||
CONFIG_BT_CONN_TX_USER_DATA_SIZE, NULL);
|
||||
|
||||
static const uint8_t pba_metadata[] = {
|
||||
BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_PROGRAM_INFO, PBS_DEMO)};
|
||||
|
||||
|
@ -58,6 +45,7 @@ static uint8_t bis_codec_data[] = {
|
|||
BT_BYTES_LIST_LE16(BT_AUDIO_CODEC_CFG_FREQ_48KHZ))};
|
||||
|
||||
static struct audio_test_stream broadcast_source_stream;
|
||||
static struct bt_cap_stream *broadcast_stream;
|
||||
|
||||
static struct bt_cap_initiator_broadcast_stream_param stream_params;
|
||||
static struct bt_cap_initiator_broadcast_subgroup_param subgroup_param;
|
||||
|
@ -76,57 +64,37 @@ static struct bt_le_ext_adv *adv;
|
|||
static void started_cb(struct bt_bap_stream *stream)
|
||||
{
|
||||
struct audio_test_stream *test_stream = audio_test_stream_from_bap_stream(stream);
|
||||
int err;
|
||||
|
||||
test_stream->seq_num = 0U;
|
||||
test_stream->tx_cnt = 0U;
|
||||
|
||||
printk("Stream %p started\n", stream);
|
||||
|
||||
err = bap_stream_tx_register(stream);
|
||||
if (err != 0) {
|
||||
FAIL("Failed to register stream %p for TX: %d\n", stream, err);
|
||||
return;
|
||||
}
|
||||
|
||||
k_sem_give(&sem_started);
|
||||
}
|
||||
|
||||
static void stopped_cb(struct bt_bap_stream *stream, uint8_t reason)
|
||||
{
|
||||
int err;
|
||||
|
||||
printk("Stream %p stopped with reason 0x%02X\n", stream, reason);
|
||||
|
||||
err = bap_stream_tx_unregister(stream);
|
||||
if (err != 0) {
|
||||
FAIL("Failed to unregister stream %p for TX: %d\n", stream, err);
|
||||
return;
|
||||
}
|
||||
|
||||
k_sem_give(&sem_stopped);
|
||||
}
|
||||
|
||||
static void sent_cb(struct bt_bap_stream *stream)
|
||||
{
|
||||
struct audio_test_stream *test_stream = audio_test_stream_from_bap_stream(stream);
|
||||
struct net_buf *buf;
|
||||
int ret;
|
||||
|
||||
if (!test_stream->tx_active) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (broadcast_preset_48_2_1.qos.sdu > CONFIG_BT_ISO_TX_MTU) {
|
||||
printk("Invalid SDU %u for the MTU: %d",
|
||||
broadcast_preset_48_2_1.qos.sdu, CONFIG_BT_ISO_TX_MTU);
|
||||
return;
|
||||
}
|
||||
|
||||
buf = net_buf_alloc(&tx_pool, K_FOREVER);
|
||||
if (buf == NULL) {
|
||||
printk("Could not allocate buffer when sending on %p\n", stream);
|
||||
return;
|
||||
}
|
||||
|
||||
net_buf_reserve(buf, BT_ISO_CHAN_SEND_RESERVE);
|
||||
net_buf_add_mem(buf, mock_iso_data, broadcast_preset_48_2_1.qos.sdu);
|
||||
ret = bt_bap_stream_send(stream, buf, test_stream->seq_num++);
|
||||
if (ret < 0) {
|
||||
/* This will end broadcasting on this stream. */
|
||||
net_buf_unref(buf);
|
||||
|
||||
/* Only fail if tx is active (may fail if we are disabling the stream) */
|
||||
if (test_stream->tx_active) {
|
||||
FAIL("Unable to broadcast data on %p: %d\n", stream, ret);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static int setup_extended_adv_data(struct bt_cap_broadcast_source *source,
|
||||
struct bt_le_ext_adv *adv)
|
||||
{
|
||||
|
@ -283,7 +251,7 @@ static int stop_extended_adv(struct bt_le_ext_adv *adv)
|
|||
static struct bt_bap_stream_ops broadcast_stream_ops = {
|
||||
.started = started_cb,
|
||||
.stopped = stopped_cb,
|
||||
.sent = sent_cb
|
||||
.sent = bap_stream_tx_sent_cb,
|
||||
};
|
||||
|
||||
static void test_main(void)
|
||||
|
@ -298,6 +266,10 @@ static void test_main(void)
|
|||
return;
|
||||
}
|
||||
|
||||
printk("Bluetooth initialized\n");
|
||||
bap_stream_tx_init();
|
||||
|
||||
broadcast_stream = &broadcast_source_stream.stream;
|
||||
bt_bap_stream_cb_register(&broadcast_source_stream.stream.bap_stream,
|
||||
&broadcast_stream_ops);
|
||||
|
||||
|
@ -351,19 +323,11 @@ static void test_main(void)
|
|||
|
||||
k_sem_take(&sem_started, SEM_TIMEOUT);
|
||||
|
||||
/* Initialize sending */
|
||||
broadcast_source_stream.tx_active = true;
|
||||
for (unsigned int j = 0U; j < BROADCAST_ENQUEUE_COUNT; j++) {
|
||||
sent_cb(&broadcast_source_stream.stream.bap_stream);
|
||||
}
|
||||
|
||||
/* Wait for other devices to let us know when we can stop the source */
|
||||
printk("Waiting for signal from receiver to stop\n");
|
||||
backchannel_sync_wait_any();
|
||||
|
||||
printk("Stopping broadcast source\n");
|
||||
broadcast_source_stream.tx_active = false;
|
||||
|
||||
err = bt_cap_initiator_broadcast_audio_stop(broadcast_source);
|
||||
if (err != 0) {
|
||||
printk("Failed to stop broadcast source: %d\n", err);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue