Bluetooth: test: adding bsim basic conn test of multiple re-connects

Adding a test that confirms ability to perform 20 (re)connections
between simple peripheral and central

Signed-off-by: Erik Brockhoff <erbr@oticon.com>
This commit is contained in:
Erik Brockhoff 2023-03-24 14:05:36 +01:00 committed by Carles Cufí
parent 5582c009a4
commit 3daa01c191
3 changed files with 201 additions and 14 deletions

View File

@ -42,6 +42,9 @@ static struct bt_le_conn_param update_params = {
};
static bool encrypt_link;
static bool expect_ntf = true;
static uint8_t repeat_connect;
static uint8_t connected_signal;
/*
* Basic connection test:
@ -57,6 +60,7 @@ static bool encrypt_link;
*/
#define WAIT_TIME 6 /*seconds*/
#define WAIT_TIME_REPEAT 22 /*seconds*/
extern enum bst_result_t bst_result;
#define FAIL(...) \
@ -83,6 +87,14 @@ static void test_con_encrypted_init(void)
test_con1_init();
}
static void test_con20_init(void)
{
repeat_connect = 20;
expect_ntf = false;
bst_ticker_set_next_tick_absolute(WAIT_TIME_REPEAT*1e6);
bst_result = In_progress;
}
static void test_con1_tick(bs_time_t HW_device_time)
{
/*
@ -95,6 +107,14 @@ static void test_con1_tick(bs_time_t HW_device_time)
}
}
static void test_con20_tick(bs_time_t HW_device_time)
{
if (bst_result != Passed) {
FAIL("test_connect1 failed (not passed after %i seconds)\n",
WAIT_TIME_REPEAT);
}
}
static uint8_t notify_func(struct bt_conn *conn,
struct bt_gatt_subscribe_params *params,
const void *data, uint16_t length)
@ -260,17 +280,21 @@ static void params_updated(struct bt_conn *conn, uint16_t interval,
return;
}
memcpy(&uuid, BT_UUID_HRS, sizeof(uuid));
discover_params.uuid = &uuid.uuid;
discover_params.func = discover_func;
discover_params.start_handle = BT_ATT_FIRST_ATTRIBUTE_HANDLE;
discover_params.end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE;
discover_params.type = BT_GATT_DISCOVER_PRIMARY;
if (!expect_ntf) {
connected_signal = 1;
} else {
memcpy(&uuid, BT_UUID_HRS, sizeof(uuid));
discover_params.uuid = &uuid.uuid;
discover_params.func = discover_func;
discover_params.start_handle = BT_ATT_FIRST_ATTRIBUTE_HANDLE;
discover_params.end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE;
discover_params.type = BT_GATT_DISCOVER_PRIMARY;
err = bt_gatt_discover(conn, &discover_params);
if (err) {
FAIL("Discover failed(err %d)\n", err);
return;
err = bt_gatt_discover(conn, &discover_params);
if (err) {
FAIL("Discover failed(err %d)\n", err);
return;
}
}
}
@ -358,6 +382,8 @@ static void disconnected(struct bt_conn *conn, uint8_t reason)
if (err) {
FAIL("Scanning failed to start (err %d)\n", err);
}
printk("Scanning successfully re-started\n");
}
static struct bt_conn_cb conn_callbacks = {
@ -391,6 +417,62 @@ static void test_con1_main(void)
printk("Scanning successfully started\n");
}
static void test_con20_main(void)
{
int err;
bt_conn_cb_register(&conn_callbacks);
err = bt_enable(NULL);
if (err) {
FAIL("Bluetooth init failed (err %d)\n", err);
return;
}
printk("Bluetooth initialized\n");
err = bt_le_scan_start(BT_LE_SCAN_ACTIVE, device_found);
if (err) {
FAIL("Scanning failed to start (err %d)\n", err);
return;
}
printk("Scanning successfully started\n");
/* Implement notification. At the moment there is no suitable way
* of starting delayed work so we do it here
*/
while (1) {
k_sleep(K_MSEC(500));
if (connected_signal) {
/* Disconnect and continue */
printk("Central Disconnect\n");
connected_signal = 0;
err = bt_conn_disconnect(default_conn,
BT_HCI_ERR_REMOTE_USER_TERM_CONN);
if (err) {
FAIL("Disconnection failed (err %d)\n", err);
return;
}
if (bst_result != Failed) {
if (repeat_connect) {
printk("Disconnection OK\n");
} else {
PASS("Testcase passed\n");
}
}
if (!repeat_connect || bst_result == Failed) {
bs_trace_silent_exit(0);
}
repeat_connect--;
}
}
}
static const struct bst_test_instance test_connect[] = {
{
.test_id = "central",
@ -409,6 +491,16 @@ static const struct bst_test_instance test_connect[] = {
.test_tick_f = test_con1_tick,
.test_main_f = test_con1_main
},
{
.test_id = "central_repeat20",
.test_descr = "Multiple connections test. It expects that a "
"peripheral device can be found. The test will "
"pass if it can connect to it 20 times, in less than 22 seconds."
"Disconnect and re-connect 20 times",
.test_post_init_f = test_con20_init,
.test_tick_f = test_con20_tick,
.test_main_f = test_con20_main
},
BSTEST_END_MARKER
};

View File

@ -36,7 +36,9 @@ static struct bt_conn *default_conn;
*/
#define WAIT_TIME 5 /*seconds*/
#define WAIT_TIME_REPEAT 22 /*seconds*/
extern enum bst_result_t bst_result;
static uint8_t repeat_connect;
#define FAIL(...) \
do { \
@ -56,6 +58,12 @@ static void test_con2_init(void)
bst_result = In_progress;
}
static void test_con2_repeat_init(void)
{
bst_ticker_set_next_tick_absolute(WAIT_TIME_REPEAT*1e6);
bst_result = In_progress;
}
static void test_con2_tick(bs_time_t HW_device_time)
{
/*
@ -68,6 +76,18 @@ static void test_con2_tick(bs_time_t HW_device_time)
}
}
static void test_con2_repeat_tick(bs_time_t HW_device_time)
{
/*
* If in WAIT_TIME seconds the testcase did not already pass
* (and finish) we consider it failed
*/
if (bst_result != Passed) {
FAIL("test_connect2 failed (not passed after %i seconds)\n",
WAIT_TIME_REPEAT);
}
}
static const struct bt_data ad[] = {
BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)),
BT_DATA_BYTES(BT_DATA_UUID16_ALL,
@ -82,13 +102,19 @@ static void connected(struct bt_conn *conn, uint8_t err)
FAIL("Connection failed (err 0x%02x)\n", err);
} else {
default_conn = bt_conn_ref(conn);
printk("Connected\n");
printk("Peripheral Connected\n");
repeat_connect++;
if (repeat_connect >= 20) { /* We consider it passed */
PASS("Peripheral Repeat20 Testcase passed\n");
}
}
}
static void disconnected(struct bt_conn *conn, uint8_t reason)
{
printk("Disconnected (reason 0x%02x)\n", reason);
printk("Peripheral disconnected (reason 0x%02x)\n", reason);
if (default_conn) {
bt_conn_unref(default_conn);
@ -105,7 +131,7 @@ static void bt_ready(void)
{
int err;
printk("Bluetooth initialized\n");
printk("Peripheral Bluetooth initialized\n");
err = bt_le_adv_start(BT_LE_ADV_CONN_NAME, ad, ARRAY_SIZE(ad), NULL, 0);
if (err) {
@ -170,11 +196,30 @@ static void test_con2_main(void)
bas_notify();
if (notify_count++ == 1) { /* We consider it passed */
PASS("Testcase passed\n");
PASS("Peripheral Testcase passed\n");
}
}
}
static void test_con2_repeat_main(void)
{
int err;
bt_conn_cb_register(&conn_callbacks);
err = bt_enable(NULL);
if (err) {
FAIL("Bluetooth init failed (err %d)\n", err);
return;
}
bt_ready();
while (1) {
k_sleep(K_SECONDS(1));
}
}
static const struct bst_test_instance test_connect[] = {
{
.test_id = "peripheral",
@ -186,6 +231,15 @@ static const struct bst_test_instance test_connect[] = {
.test_tick_f = test_con2_tick,
.test_main_f = test_con2_main
},
{
.test_id = "peripheral_repeat20",
.test_descr = "Multiple connections test. It expects that a "
"central device connects 20 times. The test will "
"pass if 20 connections are succeed in less than 22 seconds",
.test_post_init_f = test_con2_repeat_init,
.test_tick_f = test_con2_repeat_tick,
.test_main_f = test_con2_repeat_main
},
BSTEST_END_MARKER
};

View File

@ -0,0 +1,41 @@
#!/usr/bin/env bash
# Copyright 2018 Oticon A/S
# SPDX-License-Identifier: Apache-2.0
# Basic connection test: a central connects to a peripheral
# using the split controller (ULL LLL) - central disconnects and reconnects 20 times
simulation_id="basic_conn20_split"
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 55 $@ & 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_bsim_bluetooth_ll_conn_prj_split_conf \
-v=${verbosity_level} -s=${simulation_id} -d=0 -RealEncryption=0 \
-testid=peripheral_repeat20 -rs=23
Execute ./bs_${BOARD}_tests_bsim_bluetooth_ll_conn_prj_split_conf\
-v=${verbosity_level} -s=${simulation_id} -d=1 -RealEncryption=0 \
-testid=central_repeat20 -rs=6
Execute ./bs_2G4_phy_v1 -v=${verbosity_level} -s=${simulation_id} \
-D=2 -sim_length=100e6 $@
for process_id in $process_ids; do
wait $process_id || let "exit_code=$?"
done
exit $exit_code #the last exit code != 0