diff --git a/tests/bsim/bluetooth/host/compile.sh b/tests/bsim/bluetooth/host/compile.sh index dfb637078c1..c78c7a735a3 100755 --- a/tests/bsim/bluetooth/host/compile.sh +++ b/tests/bsim/bluetooth/host/compile.sh @@ -31,6 +31,7 @@ run_in_background ${ZEPHYR_BASE}/tests/bsim/bluetooth/host/misc/hfc/compile.sh run_in_background ${ZEPHYR_BASE}/tests/bsim/bluetooth/host/misc/hfc_multilink/compile.sh app=tests/bsim/bluetooth/host/misc/unregister_conn_cb compile run_in_background ${ZEPHYR_BASE}/tests/bsim/bluetooth/host/misc/sample_test/compile.sh +run_in_background ${ZEPHYR_BASE}/tests/bsim/bluetooth/host/misc/acl_tx_frag/compile.sh run_in_background ${ZEPHYR_BASE}/tests/bsim/bluetooth/host/privacy/central/compile.sh run_in_background ${ZEPHYR_BASE}/tests/bsim/bluetooth/host/privacy/peripheral/compile.sh diff --git a/tests/bsim/bluetooth/host/misc/acl_tx_frag/CMakeLists.txt b/tests/bsim/bluetooth/host/misc/acl_tx_frag/CMakeLists.txt new file mode 100644 index 00000000000..cab9cacea3c --- /dev/null +++ b/tests/bsim/bluetooth/host/misc/acl_tx_frag/CMakeLists.txt @@ -0,0 +1,24 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) + +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) + +project(acl_tx_frag) + +add_subdirectory(${ZEPHYR_BASE}/tests/bluetooth/common/testlib testlib) +target_link_libraries(app PRIVATE testlib) + +add_subdirectory(${ZEPHYR_BASE}/tests/bsim/babblekit babblekit) +target_link_libraries(app PRIVATE babblekit) + +zephyr_include_directories( + ${BSIM_COMPONENTS_PATH}/libUtilv1/src/ + ${BSIM_COMPONENTS_PATH}/libPhyComv1/src/ +) + +target_sources(app PRIVATE + src/main.c + src/dut.c + src/peer.c +) diff --git a/tests/bsim/bluetooth/host/misc/acl_tx_frag/compile.sh b/tests/bsim/bluetooth/host/misc/acl_tx_frag/compile.sh new file mode 100755 index 00000000000..e717a4b2bbe --- /dev/null +++ b/tests/bsim/bluetooth/host/misc/acl_tx_frag/compile.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash +# Copyright 2023 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 +set -eu +: "${ZEPHYR_BASE:?ZEPHYR_BASE must be defined}" + +INCR_BUILD=1 + +source ${ZEPHYR_BASE}/tests/bsim/compile.source + +app="$(guess_test_relpath)" compile + +wait_for_background_jobs diff --git a/tests/bsim/bluetooth/host/misc/acl_tx_frag/prj.conf b/tests/bsim/bluetooth/host/misc/acl_tx_frag/prj.conf new file mode 100644 index 00000000000..6bd02c8b645 --- /dev/null +++ b/tests/bsim/bluetooth/host/misc/acl_tx_frag/prj.conf @@ -0,0 +1,50 @@ +CONFIG_BT=y +CONFIG_BT_DEVICE_NAME="acl_tx_frag" +CONFIG_BT_PERIPHERAL=y +CONFIG_BT_CENTRAL=y + +# Dependency of testlib/adv and testlib/scan. +CONFIG_BT_EXT_ADV=y + +CONFIG_BT_GATT_CLIENT=y +CONFIG_BT_GATT_AUTO_DISCOVER_CCC=y + +CONFIG_BT_GATT_ENFORCE_SUBSCRIPTION=n + +CONFIG_ASSERT=y +CONFIG_LOG=y +CONFIG_LOG_RUNTIME_FILTERING=y +CONFIG_THREAD_NAME=y +CONFIG_LOG_THREAD_ID_PREFIX=y +CONFIG_ARCH_POSIX_TRAP_ON_FATAL=y + +# Disable auto-initiated procedures so they don't +# mess with the test's execution. +CONFIG_BT_AUTO_PHY_UPDATE=n +CONFIG_BT_AUTO_DATA_LEN_UPDATE=n +CONFIG_BT_GAP_AUTO_UPDATE_CONN_PARAMS=n + +CONFIG_BT_MAX_CONN=1 + +# We don't want to be constrained on the number of TX +# contexts, rather on the number of LL TX buffers. +CONFIG_BT_CONN_TX_MAX=10 + +# Outgoing ATT buffers +CONFIG_BT_ATT_TX_COUNT=1 + +# Allow big ATT MTU +CONFIG_BT_BUF_ACL_RX_SIZE=100 +CONFIG_BT_L2CAP_TX_MTU=100 + +# Controller buffers +CONFIG_BT_BUF_ACL_TX_COUNT=1 +CONFIG_BT_BUF_ACL_TX_SIZE=27 + +# If we don't define this, it will inherit +# CONFIG_BT_BUF_ACL_TX_COUNT and fail a build assert that +# expects >= 3. +CONFIG_BT_L2CAP_TX_BUF_COUNT=3 + +# For indication param structs. It's fine, we run on native. +CONFIG_HEAP_MEM_POOL_SIZE=1024 diff --git a/tests/bsim/bluetooth/host/misc/acl_tx_frag/src/data.h b/tests/bsim/bluetooth/host/misc/acl_tx_frag/src/data.h new file mode 100644 index 00000000000..59912b25eef --- /dev/null +++ b/tests/bsim/bluetooth/host/misc/acl_tx_frag/src/data.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_TESTS_BSIM_BLUETOOTH_HOST_MISC_ACL_TX_FRAG_SRC_DATA_H_ +#define ZEPHYR_TESTS_BSIM_BLUETOOTH_HOST_MISC_ACL_TX_FRAG_SRC_DATA_H_ + +#include + +#define TEST_ITERATIONS 3 + +/* overhead: opcode + ATT handle + L2CAP PDU header */ +#define GATT_PAYLOAD_SIZE (CONFIG_BT_L2CAP_TX_MTU - 1 - 2 - 4) + +#define test_service_uuid \ + BT_UUID_DECLARE_128(BT_UUID_128_ENCODE(0xf0debc9a, 0x7856, 0x3412, 0x7856, 0x341278563412)) +#define test_characteristic_uuid \ + BT_UUID_DECLARE_128(BT_UUID_128_ENCODE(0xf2debc9a, 0x7856, 0x3412, 0x7856, 0x341278563412)) + +#endif /* ZEPHYR_TESTS_BSIM_BLUETOOTH_HOST_MISC_ACL_TX_FRAG_SRC_DATA_H_ */ diff --git a/tests/bsim/bluetooth/host/misc/acl_tx_frag/src/dut.c b/tests/bsim/bluetooth/host/misc/acl_tx_frag/src/dut.c new file mode 100644 index 00000000000..6fe11230201 --- /dev/null +++ b/tests/bsim/bluetooth/host/misc/acl_tx_frag/src/dut.c @@ -0,0 +1,272 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "testlib/conn.h" +#include "testlib/scan.h" +#include "testlib/log_utils.h" + +#include "babblekit/flags.h" +#include "babblekit/testcase.h" + +/* For the radio shenanigans */ +#include "hw_testcheat_if.h" + +/* local includes */ +#include "data.h" + +LOG_MODULE_REGISTER(dut, LOG_LEVEL_DBG); + +static DEFINE_FLAG(is_subscribed); +static DEFINE_FLAG(mtu_has_been_exchanged); +static DEFINE_FLAG(conn_recycled); +static DEFINE_FLAG(conn_param_updated); +static DEFINE_FLAG(indicated); + +extern unsigned long runtime_log_level; + +static void recycled(void) +{ + LOG_DBG(""); + SET_FLAG(conn_recycled); +} + +static void params_updated(struct bt_conn *conn, uint16_t interval, uint16_t latency, + uint16_t timeout) +{ + LOG_DBG(""); + SET_FLAG(conn_param_updated); +} + +static struct bt_conn_cb conn_cbs = { + .recycled = recycled, + .le_param_updated = params_updated, +}; + +static void ccc_changed(const struct bt_gatt_attr *attr, uint16_t value) +{ + /* assume we only get it for the `test_gatt_service` */ + if (value != 0) { + SET_FLAG(is_subscribed); + } else { + UNSET_FLAG(is_subscribed); + } +} + +BT_GATT_SERVICE_DEFINE(test_gatt_service, BT_GATT_PRIMARY_SERVICE(test_service_uuid), + BT_GATT_CHARACTERISTIC(test_characteristic_uuid, + (BT_GATT_CHRC_READ | BT_GATT_CHRC_WRITE | + BT_GATT_CHRC_NOTIFY | BT_GATT_CHRC_INDICATE), + BT_GATT_PERM_READ | BT_GATT_PERM_WRITE, NULL, NULL, + NULL), + BT_GATT_CCC(ccc_changed, BT_GATT_PERM_READ | BT_GATT_PERM_WRITE)); + +static void _mtu_exchanged(struct bt_conn *conn, uint8_t err, + struct bt_gatt_exchange_params *params) +{ + LOG_DBG("MTU exchanged"); + SET_FLAG(mtu_has_been_exchanged); +} + +static void exchange_mtu(struct bt_conn *conn) +{ + int err; + struct bt_gatt_exchange_params params = { + .func = _mtu_exchanged, + }; + + UNSET_FLAG(mtu_has_been_exchanged); + + err = bt_gatt_exchange_mtu(conn, ¶ms); + TEST_ASSERT(!err, "Failed MTU exchange (err %d)", err); + + WAIT_FOR_FLAG(mtu_has_been_exchanged); +} + +#define UPDATE_PARAM_INTERVAL_MIN 500 +#define UPDATE_PARAM_INTERVAL_MAX 500 +#define UPDATE_PARAM_LATENCY 1 +#define UPDATE_PARAM_TIMEOUT 1000 + +static struct bt_le_conn_param update_params = { + .interval_min = UPDATE_PARAM_INTERVAL_MIN, + .interval_max = UPDATE_PARAM_INTERVAL_MAX, + .latency = UPDATE_PARAM_LATENCY, + .timeout = UPDATE_PARAM_TIMEOUT, +}; + +void slow_down_conn(struct bt_conn *conn) +{ + int err; + + UNSET_FLAG(conn_param_updated); + err = bt_conn_le_param_update(conn, &update_params); + TEST_ASSERT(!err, "Parameter update failed (err %d)", err); + WAIT_FOR_FLAG(conn_param_updated); +} + +static void make_peer_go_out_of_range(void) +{ + hw_radio_testcheat_set_tx_power_gain(-300); + hw_radio_testcheat_set_rx_power_gain(-300); +} + +static void make_peer_go_back_in_range(void) +{ + hw_radio_testcheat_set_tx_power_gain(+300); + hw_radio_testcheat_set_rx_power_gain(+300); +} + +void indicated_cb(struct bt_conn *conn, struct bt_gatt_indicate_params *params, uint8_t err) +{ + SET_FLAG(indicated); +} + +static void params_struct_freed_cb(struct bt_gatt_indicate_params *params) +{ + k_free(params); +} + +static int send_indication(struct bt_conn *conn, const struct bt_gatt_attr *attr, const void *data, + uint16_t len) +{ + struct bt_gatt_indicate_params *params = k_malloc(sizeof(struct bt_gatt_indicate_params)); + + params->attr = attr; + params->func = indicated_cb; + params->destroy = params_struct_freed_cb; + params->data = data; + params->len = len; + + return bt_gatt_indicate(conn, params); +} + +static const uint8_t notification_data[GATT_PAYLOAD_SIZE]; + +static void test_iteration(bt_addr_le_t *peer) +{ + int err; + struct bt_conn *conn = NULL; + const struct bt_gatt_attr *attr; + + /* Create a connection using that address */ + err = bt_testlib_connect(peer, &conn); + TEST_ASSERT(!err, "Failed to initiate connection (err %d)", err); + + LOG_DBG("Connected"); + + LOG_INF("Wait until peer subscribes"); + UNSET_FLAG(is_subscribed); + WAIT_FOR_FLAG(is_subscribed); + + /* Prepare data for notifications + * attrs[0] is our service declaration + * attrs[1] is our characteristic declaration + * attrs[2] is our characteristic value + * + * We store a pointer for the characteristic value as that is the + * value we want to notify later. + * + * We could alternatively use `bt_gatt_notify_uuid()`. + */ + attr = &test_gatt_service.attrs[2]; + + exchange_mtu(conn); + + slow_down_conn(conn); + LOG_DBG("Updated params"); + + LOG_INF("Send indication #1"); + UNSET_FLAG(indicated); + err = send_indication(conn, attr, notification_data, sizeof(notification_data)); + TEST_ASSERT(!err, "Failed to send notification: err %d", err); + LOG_DBG("Wait until peer confirms our first indication"); + WAIT_FOR_FLAG(indicated); + + LOG_INF("Send indication #2"); + UNSET_FLAG(indicated); + err = send_indication(conn, attr, notification_data, sizeof(notification_data)); + TEST_ASSERT(!err, "Failed to send notification: err %d", err); + + LOG_DBG("Simulate RF connection loss"); + UNSET_FLAG(conn_recycled); + make_peer_go_out_of_range(); + + /* We will not access conn after this: give back our initial ref. */ + bt_testlib_conn_unref(&conn); + WAIT_FOR_FLAG(conn_recycled); + + LOG_DBG("Connection object has been destroyed as expected"); + make_peer_go_back_in_range(); +} + +void entrypoint_dut(void) +{ + /* Test purpose: + * + * Verifies that we don't leak resources or mess up host state when a + * disconnection happens whilst the host is transmitting ACL fragments. + * + * To achieve that, we use the BabbleSim magic modem (see run.sh) to cut + * the RF link before we have sent all the ACL fragments the peer. We do + * want to send multiple fragments to the controller though, the + * important part is that the peer does not acknowledge them, so that + * the disconnection happens while the controller has its TX buffers + * full. + * + * Two devices: + * - `dut`: the device whose host we are testing + * - `peer`: anime side-character. not important. + * + * Procedure (for n iterations): + * - [dut] establish connection to `peer` + * - [peer] discover GATT and subscribe to the test characteristic + * - [dut] send long indication + * - [peer] wait for confirmation of indication + * - [dut] send another long indication + * - [dut] disconnect + * + * [verdict] + * - All test cycles complete + */ + int err; + bt_addr_le_t peer = {}; + + /* Mark test as in progress. */ + TEST_START("dut"); + + /* Set the log level given by the `log_level` CLI argument */ + bt_testlib_log_level_set("dut", runtime_log_level); + + /* Initialize Bluetooth */ + bt_conn_cb_register(&conn_cbs); + err = bt_enable(NULL); + TEST_ASSERT(err == 0, "Can't enable Bluetooth (err %d)", err); + + LOG_DBG("Bluetooth initialized"); + + /* Find the address of the peer. In our case, both devices are actually + * the same executable (with the same config) but executed with + * different arguments. We can then just use CONFIG_BT_DEVICE_NAME which + * contains our device name in string form. + */ + err = bt_testlib_scan_find_name(&peer, CONFIG_BT_DEVICE_NAME); + TEST_ASSERT(!err, "Failed to start scan (err %d)", err); + + for (int i = 0; i < TEST_ITERATIONS; i++) { + LOG_INF("## Iteration %d", i); + test_iteration(&peer); + } + + TEST_PASS("dut"); +} diff --git a/tests/bsim/bluetooth/host/misc/acl_tx_frag/src/main.c b/tests/bsim/bluetooth/host/misc/acl_tx_frag/src/main.c new file mode 100644 index 00000000000..9afd99d7355 --- /dev/null +++ b/tests/bsim/bluetooth/host/misc/acl_tx_frag/src/main.c @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#include "bs_tracing.h" +#include "bstests.h" +#include "babblekit/testcase.h" +#include "testlib/log_utils.h" + +extern void entrypoint_dut(void); +extern void entrypoint_peer(void); +extern enum bst_result_t bst_result; + +unsigned long runtime_log_level = LOG_LEVEL_INF; + +static void test_args(int argc, char *argv[]) +{ + size_t argn = 0; + const char *arg = argv[argn]; + + if (strcmp(arg, "log_level") == 0) { + + runtime_log_level = strtoul(argv[++argn], NULL, 10); + + if (runtime_log_level >= LOG_LEVEL_NONE && runtime_log_level <= LOG_LEVEL_DBG) { + TEST_PRINT("Runtime log level configuration: %d", runtime_log_level); + } else { + TEST_FAIL("Invalid arguments to set log level: %d", runtime_log_level); + } + } else { + TEST_PRINT("Default runtime log level configuration: INFO"); + } +} + +static void test_end_cb(void) +{ + if (bst_result != Passed) { + TEST_FAIL("Test has not passed."); + } +} + +static const struct bst_test_instance entrypoints[] = { + { + .test_id = "dut", + .test_delete_f = test_end_cb, + .test_main_f = entrypoint_dut, + .test_args_f = test_args, + }, + { + .test_id = "peer", + .test_delete_f = test_end_cb, + .test_main_f = entrypoint_peer, + .test_args_f = test_args, + }, + BSTEST_END_MARKER, +}; + +static struct bst_test_list *install(struct bst_test_list *tests) +{ + return bst_add_tests(tests, entrypoints); +}; + +bst_test_install_t test_installers[] = {install, NULL}; + +int main(void) +{ + bst_main(); + + return 0; +} diff --git a/tests/bsim/bluetooth/host/misc/acl_tx_frag/src/peer.c b/tests/bsim/bluetooth/host/misc/acl_tx_frag/src/peer.c new file mode 100644 index 00000000000..7b40d995b9d --- /dev/null +++ b/tests/bsim/bluetooth/host/misc/acl_tx_frag/src/peer.c @@ -0,0 +1,175 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include + +#include "testlib/adv.h" +#include "testlib/att_read.h" +#include "testlib/att_write.h" +#include "testlib/conn.h" +#include "testlib/log_utils.h" + +#include "babblekit/flags.h" +#include "babblekit/testcase.h" + +/* local includes */ +#include "data.h" + +LOG_MODULE_REGISTER(peer, LOG_LEVEL_DBG); + +static DEFINE_FLAG(is_subscribed); +static DEFINE_FLAG(got_notification_1); + +extern unsigned long runtime_log_level; + +int find_characteristic(struct bt_conn *conn, const struct bt_uuid *svc, const struct bt_uuid *chrc, + uint16_t *chrc_value_handle) +{ + uint16_t svc_handle; + uint16_t svc_end_handle; + uint16_t chrc_end_handle; + int err; + + LOG_DBG(""); + + err = bt_testlib_gatt_discover_primary(&svc_handle, &svc_end_handle, conn, svc, + BT_ATT_FIRST_ATTRIBUTE_HANDLE, + BT_ATT_LAST_ATTRIBUTE_HANDLE); + if (err != 0) { + LOG_ERR("Failed to discover service: %d", err); + + return err; + } + + LOG_DBG("svc_handle: %u, svc_end_handle: %u", svc_handle, svc_end_handle); + + err = bt_testlib_gatt_discover_characteristic(chrc_value_handle, &chrc_end_handle, NULL, + conn, chrc, (svc_handle + 1), svc_end_handle); + if (err != 0) { + LOG_ERR("Failed to get value handle: %d", err); + + return err; + } + + LOG_DBG("chrc_value_handle: %u, chrc_end_handle: %u", *chrc_value_handle, chrc_end_handle); + + return err; +} + +static uint8_t received_notification(struct bt_conn *conn, struct bt_gatt_subscribe_params *params, + const void *data, uint16_t length) +{ + if (length) { + LOG_INF("RX notification"); + LOG_HEXDUMP_DBG(data, length, "payload"); + SET_FLAG(got_notification_1); + + TEST_ASSERT(length == GATT_PAYLOAD_SIZE, "Unexpected length: %d", length); + } + + return BT_GATT_ITER_CONTINUE; +} + +static void sub_cb(struct bt_conn *conn, uint8_t err, struct bt_gatt_subscribe_params *params) +{ + TEST_ASSERT(!err, "Subscribe failed (err %d)", err); + + TEST_ASSERT(params, "params is NULL"); + TEST_ASSERT(params->value, "Host shouldn't know we have unsubscribed"); + + LOG_DBG("Subscribed to handle 0x%04x", params->value_handle); + SET_FLAG(is_subscribed); +} + +/* Subscription parameters have the same lifetime as a subscription. + * That is the backing struct should stay valid until a call to + * `bt_gatt_unsubscribe()` is made. Hence the `static`. + */ +static struct bt_gatt_subscribe_params sub_params; + +/* This is "working memory" used by the `CONFIG_BT_GATT_AUTO_DISCOVER_CCC` + * feature. It also has to stay valid until the end of the async call. + */ +static struct bt_gatt_discover_params ccc_disc_params; + +static void subscribe(struct bt_conn *conn, uint16_t handle, bt_gatt_notify_func_t cb) +{ + int err; + + /* Subscribe to notifications */ + sub_params.notify = cb; + sub_params.subscribe = sub_cb; + sub_params.value = BT_GATT_CCC_INDICATE; + sub_params.value_handle = handle; + + /* Set-up auto-discovery of the CCC handle */ + sub_params.ccc_handle = 0; + sub_params.disc_params = &ccc_disc_params; + sub_params.end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE; + + err = bt_gatt_subscribe(conn, &sub_params); + TEST_ASSERT(!err, "Subscribe failed (err %d)", err); + + WAIT_FOR_FLAG(is_subscribed); +} + +static uint16_t g_handle; + +static void test_iteration(void) +{ + struct bt_conn *conn; + int err; + + err = bt_testlib_adv_conn(&conn, BT_ID_DEFAULT, bt_get_name()); + TEST_ASSERT(!err, "Failed to start connectable advertising (err %d)", err); + + if (g_handle) { + LOG_DBG("Re-use cached characteristic"); + } else { + LOG_DBG("Discover test characteristic"); + err = find_characteristic(conn, test_service_uuid, test_characteristic_uuid, + &g_handle); + TEST_ASSERT(!err, "Failed to find characteristic: %d", err); + } + + LOG_DBG("Subscribe to test characteristic: handle 0x%04x", g_handle); + subscribe(conn, g_handle, received_notification); + + WAIT_FOR_FLAG(got_notification_1); + + bt_testlib_wait_disconnected(conn); + bt_testlib_conn_unref(&conn); +} + +/* Read the comments on `entrypoint_dut()` first. */ +void entrypoint_peer(void) +{ + int err; + + /* Mark test as in progress. */ + TEST_START("peer"); + + /* Set the log level given by the `log_level` CLI argument */ + bt_testlib_log_level_set("peer", runtime_log_level); + + /* Initialize Bluetooth */ + err = bt_enable(NULL); + TEST_ASSERT(err == 0, "Can't enable Bluetooth (err %d)", err); + + LOG_DBG("Bluetooth initialized"); + + for (int i = 0; i < TEST_ITERATIONS; i++) { + LOG_INF("## Iteration %d", i); + test_iteration(); + } + + TEST_PASS_AND_EXIT("peer"); +} diff --git a/tests/bsim/bluetooth/host/misc/acl_tx_frag/test_scripts/run.sh b/tests/bsim/bluetooth/host/misc/acl_tx_frag/test_scripts/run.sh new file mode 100755 index 00000000000..91eee9a078e --- /dev/null +++ b/tests/bsim/bluetooth/host/misc/acl_tx_frag/test_scripts/run.sh @@ -0,0 +1,29 @@ +#!/usr/bin/env bash +# Copyright (c) 2024 Nordic Semiconductor +# SPDX-License-Identifier: Apache-2.0 + +set -eu + +source ${ZEPHYR_BASE}/tests/bsim/sh_common.source + +test_name="$(guess_test_long_name)" +simulation_id=${test_name} +verbosity_level=2 + +# sixty-second (maximum) sim time. +# The test will exit simulation as soon as it has passed. +SIM_LEN_US=$((60 * 1000 * 1000)) + +test_exe="${BSIM_OUT_PATH}/bin/bs_${BOARD_TS}_${test_name}_prj_conf" + +cd ${BSIM_OUT_PATH}/bin + +Execute "${test_exe}" -v=${verbosity_level} -s=${simulation_id} -d=0 -rs=420 -testid=dut \ + -argstest log_level 3 +Execute "${test_exe}" -v=${verbosity_level} -s=${simulation_id} -d=1 -rs=69 -testid=peer \ + -argstest log_level 3 >/dev/null + +Execute ./bs_2G4_phy_v1 -defmodem=BLE_simple \ + -v=${verbosity_level} -s=${simulation_id} -D=2 -sim_length=${SIM_LEN_US} $@ + +wait_for_background_jobs