tests: Bluetooth: Add some more tests for bt_le_create_conn()
Adds coverage for attempting to connect while already connecting or connecting to a device that already exists. Signed-off-by: Rubin Gerritsen <rubin.gerritsen@nordicsemi.no>
This commit is contained in:
parent
c394234305
commit
f6712c43d4
5 changed files with 238 additions and 11 deletions
|
@ -1,3 +1,4 @@
|
|||
CONFIG_ASSERT=y
|
||||
CONFIG_BT=y
|
||||
CONFIG_BT_CENTRAL=y
|
||||
CONFIG_BT_PERIPHERAL=y
|
||||
|
|
66
tests/bsim/bluetooth/host/central/src/dummy_peripheral.c
Normal file
66
tests/bsim/bluetooth/host/central/src/dummy_peripheral.c
Normal file
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* Copyright (c) 2024 Nordic Semiconductor
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "bstests.h"
|
||||
#include "babblekit/testcase.h"
|
||||
#include <zephyr/bluetooth/conn.h>
|
||||
|
||||
static K_SEM_DEFINE(sem_connected, 0, 1);
|
||||
|
||||
static void connected_cb(struct bt_conn *conn, uint8_t err)
|
||||
{
|
||||
TEST_ASSERT(conn);
|
||||
TEST_ASSERT(err == 0, "Expected success");
|
||||
|
||||
k_sem_give(&sem_connected);
|
||||
bt_conn_unref(conn);
|
||||
}
|
||||
|
||||
static struct bt_conn_cb conn_cb = {
|
||||
.connected = connected_cb,
|
||||
};
|
||||
|
||||
static void test_peripheral_dummy(void)
|
||||
{
|
||||
int err;
|
||||
const struct bt_data ad[] = {
|
||||
BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR))};
|
||||
|
||||
bt_conn_cb_register(&conn_cb);
|
||||
|
||||
bt_addr_le_t addr = {.type = BT_ADDR_LE_RANDOM,
|
||||
.a.val = {0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0}};
|
||||
|
||||
err = bt_id_create(&addr, NULL);
|
||||
TEST_ASSERT(err == 0, "Failed to create iD (err %d)", err);
|
||||
|
||||
/* Initialize Bluetooth */
|
||||
err = bt_enable(NULL);
|
||||
TEST_ASSERT(err == 0, "Can't enable Bluetooth (err %d)", err);
|
||||
|
||||
err = bt_le_adv_start(BT_LE_ADV_CONN_ONE_TIME, ad, ARRAY_SIZE(ad), NULL, 0);
|
||||
TEST_ASSERT(err == 0, "Advertising failed to start (err %d)", err);
|
||||
|
||||
err = k_sem_take(&sem_connected, K_FOREVER);
|
||||
TEST_ASSERT(err == 0, "Failed getting connected timeout", err);
|
||||
|
||||
TEST_PASS("Passed");
|
||||
}
|
||||
|
||||
static const struct bst_test_instance test_def[] = {
|
||||
{
|
||||
.test_id = "peripheral_dummy",
|
||||
.test_descr = "Connectable peripheral",
|
||||
.test_tick_f = bst_tick,
|
||||
.test_main_f = test_peripheral_dummy,
|
||||
},
|
||||
BSTEST_END_MARKER,
|
||||
};
|
||||
|
||||
struct bst_test_list *test_peripheral_install(struct bst_test_list *tests)
|
||||
{
|
||||
return bst_add_tests(tests, test_def);
|
||||
}
|
|
@ -8,17 +8,36 @@
|
|||
#include "babblekit/testcase.h"
|
||||
#include <zephyr/bluetooth/conn.h>
|
||||
|
||||
/* Include conn_internal for the purpose of checking reference counts. */
|
||||
#include "host/conn_internal.h"
|
||||
|
||||
struct bst_test_list *test_peripheral_install(struct bst_test_list *tests);
|
||||
|
||||
static K_SEM_DEFINE(sem_failed_to_connect, 0, 1);
|
||||
static K_SEM_DEFINE(sem_connected, 0, 1);
|
||||
|
||||
static void connected_cb(struct bt_conn *conn, uint8_t err)
|
||||
static void connected_cb_expect_fail(struct bt_conn *conn, uint8_t err)
|
||||
{
|
||||
TEST_ASSERT(conn);
|
||||
TEST_ASSERT(err == BT_HCI_ERR_UNKNOWN_CONN_ID, "Expected connection timeout");
|
||||
|
||||
k_sem_give(&sem_failed_to_connect);
|
||||
bt_conn_unref(conn);
|
||||
}
|
||||
|
||||
static void connected_cb(struct bt_conn *conn, uint8_t err)
|
||||
{
|
||||
TEST_ASSERT(conn);
|
||||
TEST_ASSERT(err == BT_HCI_ERR_SUCCESS, "Expected connection establishment");
|
||||
|
||||
k_sem_give(&sem_connected);
|
||||
bt_conn_unref(conn);
|
||||
}
|
||||
|
||||
static struct bt_conn_cb conn_cb_expect_fail = {
|
||||
.connected = connected_cb_expect_fail,
|
||||
};
|
||||
|
||||
static struct bt_conn_cb conn_cb = {
|
||||
.connected = connected_cb,
|
||||
};
|
||||
|
@ -44,14 +63,14 @@ static void test_central_connect_timeout_with_timeout(uint32_t timeout_ms)
|
|||
.timeout = timeout_ms / 10,
|
||||
};
|
||||
|
||||
k_sem_reset(&sem_connected);
|
||||
k_sem_reset(&sem_failed_to_connect);
|
||||
|
||||
const uint64_t conn_create_start = k_uptime_get();
|
||||
|
||||
err = bt_conn_le_create(&peer, &create_param, BT_LE_CONN_PARAM_DEFAULT, &conn);
|
||||
TEST_ASSERT(err == 0, "Failed starting initiator (err %d)", err);
|
||||
|
||||
err = k_sem_take(&sem_connected, K_MSEC(2 * expected_conn_timeout_ms));
|
||||
err = k_sem_take(&sem_failed_to_connect, K_MSEC(2 * expected_conn_timeout_ms));
|
||||
TEST_ASSERT(err == 0, "Failed getting connected timeout within %d s (err %d)",
|
||||
2 * expected_conn_timeout_ms, err);
|
||||
|
||||
|
@ -63,14 +82,15 @@ static void test_central_connect_timeout_with_timeout(uint32_t timeout_ms)
|
|||
TEST_PRINT("Connection timeout after %d ms", time_diff_ms);
|
||||
TEST_ASSERT(diff_to_expected_ms < 0.1 * expected_conn_timeout_ms,
|
||||
"Connection timeout not within 10%% of expected timeout. "
|
||||
"Actual timeout: %d", time_diff_ms);
|
||||
"Actual timeout: %d",
|
||||
time_diff_ms);
|
||||
}
|
||||
|
||||
static void test_central_connect_timeout(void)
|
||||
{
|
||||
int err;
|
||||
|
||||
bt_conn_cb_register(&conn_cb);
|
||||
bt_conn_cb_register(&conn_cb_expect_fail);
|
||||
|
||||
/* Initialize Bluetooth */
|
||||
err = bt_enable(NULL);
|
||||
|
@ -82,14 +102,118 @@ static void test_central_connect_timeout(void)
|
|||
TEST_PASS("Correct timeout");
|
||||
}
|
||||
|
||||
static void test_central_connect_when_connecting(void)
|
||||
{
|
||||
int err;
|
||||
|
||||
bt_conn_cb_register(&conn_cb_expect_fail);
|
||||
|
||||
/* Initialize Bluetooth */
|
||||
err = bt_enable(NULL);
|
||||
TEST_ASSERT(err == 0, "Can't enable Bluetooth (err %d)", err);
|
||||
|
||||
struct bt_conn *conn;
|
||||
|
||||
bt_addr_le_t peer = {.a.val = {0x01}};
|
||||
|
||||
const struct bt_conn_le_create_param create_param = {
|
||||
.options = BT_CONN_LE_OPT_NONE,
|
||||
.interval = BT_GAP_SCAN_FAST_INTERVAL,
|
||||
.window = BT_GAP_SCAN_FAST_WINDOW,
|
||||
};
|
||||
|
||||
k_sem_reset(&sem_failed_to_connect);
|
||||
|
||||
err = bt_conn_le_create(&peer, &create_param, BT_LE_CONN_PARAM_DEFAULT, &conn);
|
||||
TEST_ASSERT(err == 0, "Failed starting initiator (err %d)", err);
|
||||
|
||||
/* Now we have a valid connection reference */
|
||||
atomic_val_t initial_refs = atomic_get(&conn->ref);
|
||||
|
||||
TEST_ASSERT(initial_refs >= 1, "Expect to have at least once reference");
|
||||
|
||||
err = bt_conn_le_create(&peer, &create_param, BT_LE_CONN_PARAM_DEFAULT, &conn);
|
||||
TEST_ASSERT(err == -EALREADY, "Expected to fail to create connection (err %d)", err);
|
||||
|
||||
/* Expect the number of refs to be unchanged. */
|
||||
TEST_ASSERT(atomic_get(&conn->ref) == initial_refs,
|
||||
"Expect number of references to be unchanged");
|
||||
|
||||
err = k_sem_take(&sem_failed_to_connect, K_FOREVER);
|
||||
TEST_ASSERT(err == 0, "Failed getting connected timeout", err);
|
||||
|
||||
TEST_ASSERT(atomic_get(&conn->ref) == 0, "Expect no more references");
|
||||
|
||||
TEST_PASS("Passed");
|
||||
}
|
||||
|
||||
static void test_central_connect_to_existing(void)
|
||||
{
|
||||
int err;
|
||||
|
||||
bt_conn_cb_register(&conn_cb);
|
||||
|
||||
/* Initialize Bluetooth */
|
||||
err = bt_enable(NULL);
|
||||
TEST_ASSERT(err == 0, "Can't enable Bluetooth (err %d)", err);
|
||||
|
||||
struct bt_conn *conn;
|
||||
|
||||
bt_addr_le_t peer = {.type = BT_ADDR_LE_RANDOM,
|
||||
.a.val = {0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0}};
|
||||
|
||||
const struct bt_conn_le_create_param create_param = {
|
||||
.options = BT_CONN_LE_OPT_NONE,
|
||||
.interval = BT_GAP_SCAN_FAST_INTERVAL,
|
||||
.window = BT_GAP_SCAN_FAST_WINDOW,
|
||||
};
|
||||
|
||||
k_sem_reset(&sem_connected);
|
||||
|
||||
err = bt_conn_le_create(&peer, &create_param, BT_LE_CONN_PARAM_DEFAULT, &conn);
|
||||
TEST_ASSERT(err == 0, "Failed starting initiator (err %d)", err);
|
||||
|
||||
err = k_sem_take(&sem_connected, K_FOREVER);
|
||||
TEST_ASSERT(err == 0, "Failed establishing connection", err);
|
||||
|
||||
/* Now we have a valid connection reference */
|
||||
atomic_val_t initial_refs = atomic_get(&conn->ref);
|
||||
|
||||
TEST_ASSERT(initial_refs >= 1, "Expect to have at least once reference");
|
||||
|
||||
err = bt_conn_le_create(&peer, &create_param, BT_LE_CONN_PARAM_DEFAULT, &conn);
|
||||
TEST_ASSERT(err == -EINVAL, "Expected to fail to create a connection (err %d)", err);
|
||||
|
||||
/* Expect the number of refs to be unchanged. */
|
||||
TEST_ASSERT(atomic_get(&conn->ref) == initial_refs,
|
||||
"Expect number of references to be unchanged");
|
||||
|
||||
TEST_PASS("Passed");
|
||||
}
|
||||
|
||||
static const struct bst_test_instance test_def[] = {
|
||||
{
|
||||
.test_id = "central_connect_timeout",
|
||||
.test_descr = "Verifies that the default connection timeout is used correctly",
|
||||
.test_tick_f = bst_tick,
|
||||
.test_main_f = test_central_connect_timeout
|
||||
.test_main_f = test_central_connect_timeout,
|
||||
},
|
||||
BSTEST_END_MARKER
|
||||
{
|
||||
.test_id = "central_connect_when_connecting",
|
||||
.test_descr = "Verifies that the stack returns an error code when trying to connect"
|
||||
" while already connecting",
|
||||
.test_tick_f = bst_tick,
|
||||
.test_main_f = test_central_connect_when_connecting,
|
||||
},
|
||||
{
|
||||
.test_id = "central_connect_to_existing",
|
||||
.test_descr =
|
||||
"Verifies that the stack returns an error code when trying to connect"
|
||||
" to an existing device and does not unref the existing connection object.",
|
||||
.test_tick_f = bst_tick,
|
||||
.test_main_f = test_central_connect_to_existing,
|
||||
},
|
||||
BSTEST_END_MARKER,
|
||||
};
|
||||
|
||||
static struct bst_test_list *test_central_install(struct bst_test_list *tests)
|
||||
|
@ -97,10 +221,7 @@ static struct bst_test_list *test_central_install(struct bst_test_list *tests)
|
|||
return bst_add_tests(tests, test_def);
|
||||
}
|
||||
|
||||
bst_test_install_t test_installers[] = {
|
||||
test_central_install,
|
||||
NULL
|
||||
};
|
||||
bst_test_install_t test_installers[] = {test_central_install, test_peripheral_install, NULL};
|
||||
|
||||
int main(void)
|
||||
{
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
#!/usr/bin/env bash
|
||||
# Copyright (c) 2024 Nordic Semiconductor
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
source ${ZEPHYR_BASE}/tests/bsim/sh_common.source
|
||||
|
||||
simulation_id="central_connect_timeout_to_existing"
|
||||
verbosity_level=2
|
||||
|
||||
cd ${BSIM_OUT_PATH}/bin
|
||||
|
||||
Execute ./bs_${BOARD_TS}_tests_bsim_bluetooth_host_central_prj_conf \
|
||||
-v=${verbosity_level} -s=${simulation_id} -d=0 -testid=central_connect_to_existing
|
||||
|
||||
Execute ./bs_${BOARD_TS}_tests_bsim_bluetooth_host_central_prj_conf \
|
||||
-v=${verbosity_level} -s=${simulation_id} -d=1 -testid=peripheral_dummy
|
||||
|
||||
Execute ./bs_2G4_phy_v1 -v=${verbosity_level} -s=${simulation_id} \
|
||||
-D=2 -sim_length=60e6 $@
|
||||
|
||||
wait_for_background_jobs
|
|
@ -0,0 +1,18 @@
|
|||
#!/usr/bin/env bash
|
||||
# Copyright (c) 2024 Nordic Semiconductor
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
source ${ZEPHYR_BASE}/tests/bsim/sh_common.source
|
||||
|
||||
simulation_id="central_connect_when_connecting"
|
||||
verbosity_level=2
|
||||
|
||||
cd ${BSIM_OUT_PATH}/bin
|
||||
|
||||
Execute ./bs_${BOARD_TS}_tests_bsim_bluetooth_host_central_prj_conf \
|
||||
-v=${verbosity_level} -s=${simulation_id} -d=0 -testid=central_connect_when_connecting
|
||||
|
||||
Execute ./bs_2G4_phy_v1 -v=${verbosity_level} -s=${simulation_id} \
|
||||
-D=1 -sim_length=60e6 $@
|
||||
|
||||
wait_for_background_jobs
|
Loading…
Add table
Add a link
Reference in a new issue