Bluetooth: Audio: Add TBS server and client BSIM tests
Add babblesim tests for the TBS server and client. Signed-off-by: Emil Gydesen <emil.gydesen@nordicsemi.no>
This commit is contained in:
parent
b32491df11
commit
7eef8d705f
|
@ -55,6 +55,10 @@ CONFIG_BT_CSIS_TEST_SAMPLE_DATA=y
|
|||
CONFIG_BT_CSIS_CLIENT=y
|
||||
CONFIG_BT_CSIS_CLIENT_TEST_SAMPLE_DATA=y
|
||||
|
||||
# Telephone bearer service
|
||||
CONFIG_BT_TBS=y
|
||||
CONFIG_BT_TBS_CLIENT=y
|
||||
|
||||
# Media control
|
||||
CONFIG_MCTL=y
|
||||
CONFIG_MCTL_LOCAL_PLAYER_CONTROL=y
|
||||
|
@ -96,6 +100,8 @@ CONFIG_BT_DEBUG_VOCS_CLIENT=y
|
|||
CONFIG_BT_DEBUG_MICS=y
|
||||
CONFIG_BT_DEBUG_MICS_CLIENT=y
|
||||
CONFIG_BT_DEBUG_MPL=y
|
||||
CONFIG_BT_DEBUG_TBS=y
|
||||
CONFIG_BT_DEBUG_TBS_CLIENT=y
|
||||
CONFIG_BT_DEBUG_MCS=y
|
||||
CONFIG_BT_DEBUG_MCC=y
|
||||
CONFIG_BT_OTS_LOG_LEVEL_DBG=y
|
||||
|
|
|
@ -12,6 +12,8 @@ extern struct bst_test_list *test_mics_install(struct bst_test_list *tests);
|
|||
extern struct bst_test_list *test_mics_client_install(struct bst_test_list *tests);
|
||||
extern struct bst_test_list *test_csis_install(struct bst_test_list *tests);
|
||||
extern struct bst_test_list *test_csis_client_install(struct bst_test_list *tests);
|
||||
extern struct bst_test_list *test_tbs_install(struct bst_test_list *tests);
|
||||
extern struct bst_test_list *test_tbs_client_install(struct bst_test_list *tests);
|
||||
extern struct bst_test_list *test_mcs_install(struct bst_test_list *tests);
|
||||
extern struct bst_test_list *test_mcc_install(struct bst_test_list *tests);
|
||||
extern struct bst_test_list *test_media_controller_install(struct bst_test_list *tests);
|
||||
|
@ -30,6 +32,8 @@ bst_test_install_t test_installers[] = {
|
|||
test_mics_client_install,
|
||||
test_csis_install,
|
||||
test_csis_client_install,
|
||||
test_tbs_install,
|
||||
test_tbs_client_install,
|
||||
test_mcs_install,
|
||||
test_mcc_install,
|
||||
test_media_controller_install,
|
||||
|
|
232
tests/bluetooth/bsim_bt/bsim_test_audio/src/tbs_client_test.c
Normal file
232
tests/bluetooth/bsim_bt/bsim_test_audio/src/tbs_client_test.c
Normal file
|
@ -0,0 +1,232 @@
|
|||
/*
|
||||
* Copyright (c) 2019 Bose Corporation
|
||||
* Copyright (c) 2021 Nordic Semiconductor ASA
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_BT_TBS_CLIENT
|
||||
|
||||
#include <bluetooth/audio/tbs.h>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
static struct bt_conn_cb conn_callbacks;
|
||||
extern enum bst_result_t bst_result;
|
||||
static volatile bool bt_init;
|
||||
static volatile bool is_connected;
|
||||
static volatile bool discovery_complete;
|
||||
static volatile bool is_gtbs_found;
|
||||
static volatile bool read_complete;
|
||||
static volatile bool call_placed;
|
||||
static volatile uint8_t call_state;
|
||||
static volatile uint8_t call_index;
|
||||
|
||||
static void tbs_client_call_states_cb(struct bt_conn *conn, int err,
|
||||
uint8_t index, uint8_t call_count,
|
||||
const struct bt_tbs_client_call_state *call_states)
|
||||
{
|
||||
if (index != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
printk("%s\n", __func__);
|
||||
printk("Index %u\n", index);
|
||||
if (err != 0) {
|
||||
FAIL("Call could not read call states (%d)\n", err);
|
||||
return;
|
||||
}
|
||||
|
||||
call_index = call_states[0].index;
|
||||
call_state = call_states[0].state;
|
||||
printk("call index %u - state %u\n", call_index, call_state);
|
||||
}
|
||||
|
||||
static void tbs_client_read_bearer_provider_name(struct bt_conn *conn, int err,
|
||||
uint8_t index,
|
||||
const char *value)
|
||||
{
|
||||
if (err != 0) {
|
||||
FAIL("Call could not read bearer name (%d)\n", err);
|
||||
return;
|
||||
}
|
||||
|
||||
printk("Index %u\n", index);
|
||||
printk("Bearer name pointer: %p\n", value);
|
||||
printk("Bearer name: %s\n", value);
|
||||
read_complete = true;
|
||||
}
|
||||
|
||||
static void tbs_client_discover_cb(struct bt_conn *conn, int err,
|
||||
uint8_t tbs_count, bool gtbs_found)
|
||||
{
|
||||
printk("%s\n", __func__);
|
||||
if (err != 0) {
|
||||
FAIL("TBS_CLIENT could not be discovered (%d)\n", err);
|
||||
return;
|
||||
}
|
||||
|
||||
is_gtbs_found = true;
|
||||
discovery_complete = true;
|
||||
}
|
||||
|
||||
static struct bt_tbs_client_cb tbs_client_cbs = {
|
||||
.discover = tbs_client_discover_cb,
|
||||
.originate_call = NULL,
|
||||
.terminate_call = NULL,
|
||||
.hold_call = NULL,
|
||||
.accept_call = NULL,
|
||||
.retrieve_call = NULL,
|
||||
.join_calls = NULL,
|
||||
.bearer_provider_name = tbs_client_read_bearer_provider_name,
|
||||
.bearer_uci = NULL,
|
||||
.technology = NULL,
|
||||
.uri_list = NULL,
|
||||
.signal_strength = NULL,
|
||||
.signal_interval = NULL,
|
||||
.current_calls = NULL,
|
||||
.ccid = NULL,
|
||||
.status_flags = NULL,
|
||||
.call_uri = NULL,
|
||||
.call_state = tbs_client_call_states_cb,
|
||||
.termination_reason = NULL
|
||||
};
|
||||
|
||||
static void connected(struct bt_conn *conn, uint8_t err)
|
||||
{
|
||||
char addr[BT_ADDR_LE_STR_LEN];
|
||||
|
||||
bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
|
||||
|
||||
if (err != 0) {
|
||||
bt_conn_unref(default_conn);
|
||||
FAIL("Failed to connect to %s (%u)\n", addr, err);
|
||||
return;
|
||||
}
|
||||
|
||||
printk("Connected to %s\n", addr);
|
||||
is_connected = true;
|
||||
}
|
||||
|
||||
static void bt_ready(int err)
|
||||
{
|
||||
if (err != 0) {
|
||||
FAIL("Bluetooth discover failed (err %d)\n", err);
|
||||
return;
|
||||
}
|
||||
|
||||
bt_init = true;
|
||||
}
|
||||
|
||||
static struct bt_conn_cb conn_callbacks = {
|
||||
.connected = connected,
|
||||
.disconnected = disconnected,
|
||||
};
|
||||
|
||||
static void test_main(void)
|
||||
{
|
||||
int err;
|
||||
int index = 0;
|
||||
int tbs_client_err;
|
||||
|
||||
err = bt_enable(bt_ready);
|
||||
|
||||
if (err != 0) {
|
||||
FAIL("Bluetooth discover failed (err %d)\n", err);
|
||||
return;
|
||||
}
|
||||
|
||||
bt_conn_cb_register(&conn_callbacks);
|
||||
bt_tbs_client_register_cb(&tbs_client_cbs);
|
||||
|
||||
WAIT_FOR(bt_init);
|
||||
|
||||
printk("Audio Server: Bluetooth discovered\n");
|
||||
|
||||
err = bt_le_adv_start(BT_LE_ADV_CONN_NAME, ad, AD_SIZE, NULL, 0);
|
||||
if (err != 0) {
|
||||
FAIL("Advertising failed to start (err %d)\n", err);
|
||||
return;
|
||||
}
|
||||
|
||||
printk("Advertising successfully started\n");
|
||||
|
||||
WAIT_FOR(is_connected);
|
||||
|
||||
tbs_client_err = bt_tbs_client_discover(default_conn, true);
|
||||
if (tbs_client_err) {
|
||||
FAIL("Failed to discover TBS_CLIENT for connection %d", tbs_client_err);
|
||||
}
|
||||
|
||||
WAIT_FOR(discovery_complete);
|
||||
|
||||
printk("GTBS %sfound\n", is_gtbs_found ? "" : "not ");
|
||||
|
||||
printk("Placing call\n");
|
||||
err = bt_tbs_client_originate_call(default_conn, 0, "tel:123456789012");
|
||||
if (err != 0) {
|
||||
FAIL("Originate call failed (%d)\n", err);
|
||||
}
|
||||
|
||||
/* Call transitions:
|
||||
* 1) Dialing
|
||||
* 2) Alerting
|
||||
* 3) Active
|
||||
* 4) Remotely Held
|
||||
*/
|
||||
printk("Waiting for remotely held\n");
|
||||
WAIT_FOR(call_state == BT_TBS_CALL_STATE_REMOTELY_HELD);
|
||||
|
||||
printk("Holding call\n");
|
||||
err = bt_tbs_client_hold_call(default_conn, index, call_index);
|
||||
if (err != 0) {
|
||||
FAIL("Hold call failed (%d)\n", err);
|
||||
}
|
||||
|
||||
/* Call transitions:
|
||||
* 1) Locally and remotely held
|
||||
* 2) Locally held
|
||||
*/
|
||||
WAIT_FOR(call_state == BT_TBS_CALL_STATE_LOCALLY_HELD);
|
||||
|
||||
printk("Retrieving call\n");
|
||||
err = bt_tbs_client_retrieve_call(default_conn, index, call_index);
|
||||
if (err != 0) {
|
||||
FAIL("Retrieve call failed (%d)\n", err);
|
||||
}
|
||||
|
||||
WAIT_FOR(call_state == BT_TBS_CALL_STATE_ACTIVE);
|
||||
|
||||
printk("Reading bearer provider name\n");
|
||||
err = bt_tbs_client_read_bearer_provider_name(default_conn, index);
|
||||
if (err != 0) {
|
||||
FAIL("Read bearer provider name failed (%d)\n", err);
|
||||
}
|
||||
|
||||
WAIT_FOR(read_complete);
|
||||
PASS("TBS_CLIENT Passed\n");
|
||||
}
|
||||
|
||||
static const struct bst_test_instance test_tbs_client[] = {
|
||||
{
|
||||
.test_id = "tbs_client",
|
||||
.test_post_init_f = test_init,
|
||||
.test_tick_f = test_tick,
|
||||
.test_main_f = test_main
|
||||
},
|
||||
BSTEST_END_MARKER
|
||||
};
|
||||
|
||||
struct bst_test_list *test_tbs_client_install(struct bst_test_list *tests)
|
||||
{
|
||||
return bst_add_tests(tests, test_tbs_client);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
struct bst_test_list *test_tbs_client_install(struct bst_test_list *tests)
|
||||
{
|
||||
return tests;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_BT_TBS_CLIENT */
|
144
tests/bluetooth/bsim_bt/bsim_test_audio/src/tbs_test.c
Normal file
144
tests/bluetooth/bsim_bt/bsim_test_audio/src/tbs_test.c
Normal file
|
@ -0,0 +1,144 @@
|
|||
/*
|
||||
* Copyright (c) 2019 Bose Corporation
|
||||
* Copyright (c) 2021 Nordic Semiconductor ASA
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_BT_TBS
|
||||
#include <bluetooth/audio/tbs.h>
|
||||
#include "common.h"
|
||||
|
||||
extern enum bst_result_t bst_result;
|
||||
static volatile bool is_connected;
|
||||
static volatile bool call_placed;
|
||||
static volatile bool call_held;
|
||||
static volatile bool call_id;
|
||||
|
||||
static void tbs_hold_call_cb(struct bt_conn *conn, uint8_t call_index)
|
||||
{
|
||||
if (call_index == call_id) {
|
||||
call_held = true;
|
||||
}
|
||||
}
|
||||
|
||||
static bool tbs_originate_call_cb(struct bt_conn *conn, uint8_t call_index,
|
||||
const char *caller_id)
|
||||
{
|
||||
printk("Placing call to remote with id %u to %s\n",
|
||||
call_index, caller_id);
|
||||
call_id = call_index;
|
||||
call_placed = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool tbs_authorize_cb(struct bt_conn *conn)
|
||||
{
|
||||
return conn == default_conn;
|
||||
}
|
||||
|
||||
static struct bt_tbs_cb tbs_cbs = {
|
||||
.originate_call = tbs_originate_call_cb,
|
||||
.terminate_call = NULL,
|
||||
.hold_call = tbs_hold_call_cb,
|
||||
.accept_call = NULL,
|
||||
.retrieve_call = NULL,
|
||||
.join_calls = NULL,
|
||||
.authorize = tbs_authorize_cb,
|
||||
};
|
||||
|
||||
static void connected(struct bt_conn *conn, uint8_t err)
|
||||
{
|
||||
char addr[BT_ADDR_LE_STR_LEN];
|
||||
|
||||
bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
|
||||
|
||||
if (err != 0) {
|
||||
FAIL("Failed to connect to %s (%u)\n", addr, err);
|
||||
return;
|
||||
}
|
||||
|
||||
printk("Connected to %s\n", addr);
|
||||
|
||||
default_conn = bt_conn_ref(conn);
|
||||
is_connected = true;
|
||||
}
|
||||
|
||||
static struct bt_conn_cb conn_callbacks = {
|
||||
.connected = connected,
|
||||
.disconnected = disconnected,
|
||||
};
|
||||
|
||||
static void test_main(void)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = bt_enable(NULL);
|
||||
if (err != 0) {
|
||||
printk("Bluetooth init failed (err %d)\n", err);
|
||||
return;
|
||||
}
|
||||
|
||||
printk("Audio Client: Bluetooth initialized\n");
|
||||
|
||||
bt_conn_cb_register(&conn_callbacks);
|
||||
bt_tbs_register_cb(&tbs_cbs);
|
||||
|
||||
err = bt_le_scan_start(BT_LE_SCAN_PASSIVE, device_found);
|
||||
if (err != 0) {
|
||||
FAIL("Scanning failed to start (err %d)\n", err);
|
||||
return;
|
||||
}
|
||||
|
||||
printk("Scanning successfully started\n");
|
||||
|
||||
WAIT_FOR(is_connected);
|
||||
|
||||
WAIT_FOR(call_placed);
|
||||
|
||||
err = bt_tbs_remote_answer(call_id);
|
||||
if (err != BT_TBS_RESULT_CODE_SUCCESS) {
|
||||
FAIL("Remote could not answer call: %d\n", err);
|
||||
return;
|
||||
}
|
||||
printk("Remote answered %u\n", call_id);
|
||||
|
||||
err = bt_tbs_remote_hold(call_id);
|
||||
if (err != BT_TBS_RESULT_CODE_SUCCESS) {
|
||||
FAIL("Remote could not hold call: %d\n", err);
|
||||
}
|
||||
printk("Remote held %u\n", call_id);
|
||||
|
||||
WAIT_FOR(call_held);
|
||||
|
||||
err = bt_tbs_remote_retrieve(call_id);
|
||||
if (err != BT_TBS_RESULT_CODE_SUCCESS) {
|
||||
FAIL("Remote could not answer call: %d\n", err);
|
||||
return;
|
||||
}
|
||||
printk("Remote retrieved %u\n", call_id);
|
||||
|
||||
PASS("TBS passed\n");
|
||||
}
|
||||
|
||||
static const struct bst_test_instance test_tbs[] = {
|
||||
{
|
||||
.test_id = "tbs",
|
||||
.test_post_init_f = test_init,
|
||||
.test_tick_f = test_tick,
|
||||
.test_main_f = test_main
|
||||
},
|
||||
BSTEST_END_MARKER
|
||||
};
|
||||
|
||||
struct bst_test_list *test_tbs_install(struct bst_test_list *tests)
|
||||
{
|
||||
return bst_add_tests(tests, test_tbs);
|
||||
}
|
||||
#else
|
||||
struct bst_test_list *test_tbs_install(struct bst_test_list *tests)
|
||||
{
|
||||
return tests;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_BT_TBS */
|
40
tests/bluetooth/bsim_bt/bsim_test_audio/test_scripts/tbs.sh
Executable file
40
tests/bluetooth/bsim_bt/bsim_test_audio/test_scripts/tbs.sh
Executable file
|
@ -0,0 +1,40 @@
|
|||
#!/usr/bin/env bash
|
||||
#
|
||||
# Copyright (c) 2019 Bose Corporation
|
||||
# Copyright (c) 2021 Nordic Semiconductor ASA
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
SIMULATION_ID="tbs_ccp"
|
||||
VERBOSITY_LEVEL=2
|
||||
PROCESS_IDS=""; EXIT_CODE=0
|
||||
|
||||
function Execute(){
|
||||
if [ ! -f $1 ]; then
|
||||
echo -e " \e[91m`pwd`/`basename $1` cannot be found (did you forget to\
|
||||
compile it?)\e[39m"
|
||||
exit 1
|
||||
fi
|
||||
timeout 20 $@ & PROCESS_IDS="$PROCESS_IDS $!"
|
||||
}
|
||||
|
||||
: "${BSIM_OUT_PATH:?BSIM_OUT_PATH must be defined}"
|
||||
|
||||
#Give a default value to BOARD if it does not have one yet:
|
||||
BOARD="${BOARD:-nrf52_bsim}"
|
||||
|
||||
cd ${BSIM_OUT_PATH}/bin
|
||||
|
||||
Execute ./bs_${BOARD}_tests_bluetooth_bsim_bt_bsim_test_audio_prj_conf \
|
||||
-v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=0 -testid=tbs -rs=23
|
||||
|
||||
Execute ./bs_${BOARD}_tests_bluetooth_bsim_bt_bsim_test_audio_prj_conf \
|
||||
-v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=1 -testid=tbs_client -rs=6
|
||||
|
||||
Execute ./bs_2G4_phy_v1 -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} \
|
||||
-D=2 -sim_length=20e6 $@
|
||||
|
||||
for PROCESS_ID in $PROCESS_IDS; do
|
||||
wait $PROCESS_ID || let "EXIT_CODE=$?"
|
||||
done
|
||||
exit $EXIT_CODE #the last exit code != 0
|
Loading…
Reference in a new issue