From 3daa01c19126fcb40a7a251104df572162ee83a0 Mon Sep 17 00:00:00 2001 From: Erik Brockhoff Date: Fri, 24 Mar 2023 14:05:36 +0100 Subject: [PATCH] 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 --- .../bluetooth/ll/conn/src/test_connect1.c | 112 ++++++++++++++++-- .../bluetooth/ll/conn/src/test_connect2.c | 62 +++++++++- .../conn/tests_scripts/basic_conn20_split.sh | 41 +++++++ 3 files changed, 201 insertions(+), 14 deletions(-) create mode 100755 tests/bsim/bluetooth/ll/conn/tests_scripts/basic_conn20_split.sh diff --git a/tests/bsim/bluetooth/ll/conn/src/test_connect1.c b/tests/bsim/bluetooth/ll/conn/src/test_connect1.c index 765238b192b..3b469585c84 100644 --- a/tests/bsim/bluetooth/ll/conn/src/test_connect1.c +++ b/tests/bsim/bluetooth/ll/conn/src/test_connect1.c @@ -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 }; diff --git a/tests/bsim/bluetooth/ll/conn/src/test_connect2.c b/tests/bsim/bluetooth/ll/conn/src/test_connect2.c index e6dfae9563b..a0470af51a6 100644 --- a/tests/bsim/bluetooth/ll/conn/src/test_connect2.c +++ b/tests/bsim/bluetooth/ll/conn/src/test_connect2.c @@ -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 }; diff --git a/tests/bsim/bluetooth/ll/conn/tests_scripts/basic_conn20_split.sh b/tests/bsim/bluetooth/ll/conn/tests_scripts/basic_conn20_split.sh new file mode 100755 index 00000000000..e61759d7338 --- /dev/null +++ b/tests/bsim/bluetooth/ll/conn/tests_scripts/basic_conn20_split.sh @@ -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