-
Notifications
You must be signed in to change notification settings - Fork 6.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
bluetooth: tests: Add bsim test for setting bondable flag per-conn
Added test for the bt_conn_set_bondable API function. Check if we can pair without setting the bonding flag on the per-connection basis if the device was already bonded on the other identity. Signed-off-by: Mateusz Kapala <mateusz.kapala@nordicsemi.no>
- Loading branch information
1 parent
5b44ebe
commit 8e5673c
Showing
11 changed files
with
556 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
18 changes: 18 additions & 0 deletions
18
tests/bsim/bluetooth/host/security/bond_per_connection/CMakeLists.txt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
# SPDX-License-Identifier: Apache-2.0 | ||
|
||
cmake_minimum_required(VERSION 3.20.0) | ||
|
||
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) | ||
project(bsim_test_multi_id_bond_per_connection) | ||
|
||
target_sources(app PRIVATE | ||
src/bs_bt_utils.c | ||
src/central.c | ||
src/main.c | ||
src/peripheral.c | ||
) | ||
|
||
zephyr_include_directories( | ||
${BSIM_COMPONENTS_PATH}/libUtilv1/src/ | ||
${BSIM_COMPONENTS_PATH}/libPhyComv1/src/ | ||
) |
17 changes: 17 additions & 0 deletions
17
tests/bsim/bluetooth/host/security/bond_per_connection/prj.conf
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
CONFIG_BT=y | ||
CONFIG_BT_PERIPHERAL=y | ||
CONFIG_BT_CENTRAL=y | ||
|
||
CONFIG_BT_SMP=y | ||
|
||
CONFIG_ASSERT=y | ||
CONFIG_BT_TESTING=y | ||
CONFIG_LOG=y | ||
|
||
CONFIG_BT_ID_MAX=3 | ||
CONFIG_BT_MAX_PAIRED=2 | ||
CONFIG_BT_MAX_CONN=1 | ||
|
||
CONFIG_BT_PRIVACY=y | ||
|
||
CONFIG_BT_BONDABLE_PER_CONNECTION=y |
209 changes: 209 additions & 0 deletions
209
tests/bsim/bluetooth/host/security/bond_per_connection/src/bs_bt_utils.c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,209 @@ | ||
/* | ||
* Copyright (c) 2023 Nordic Semiconductor ASA | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
#include "bs_bt_utils.h" | ||
|
||
BUILD_ASSERT(CONFIG_BT_MAX_PAIRED >= 2, "CONFIG_BT_MAX_PAIRED is too small."); | ||
BUILD_ASSERT(CONFIG_BT_ID_MAX >= 3, "CONFIG_BT_ID_MAX is too small."); | ||
|
||
#define BS_SECONDS(dur_sec) ((bs_time_t)dur_sec * 1000000) | ||
#define TEST_TIMEOUT_SIMULATED BS_SECONDS(60) | ||
|
||
void test_tick(bs_time_t HW_device_time) | ||
{ | ||
bs_trace_debug_time(0, "Simulation ends now.\n"); | ||
if (bst_result != Passed) { | ||
bst_result = Failed; | ||
bs_trace_error("Test did not pass before simulation ended.\n"); | ||
} | ||
} | ||
|
||
void test_init(void) | ||
{ | ||
bst_ticker_set_next_tick_absolute(TEST_TIMEOUT_SIMULATED); | ||
bst_result = In_progress; | ||
} | ||
|
||
DEFINE_FLAG(flag_is_connected); | ||
struct bt_conn *g_conn; | ||
DEFINE_FLAG(bondable); | ||
DEFINE_FLAG(call_bt_conn_set_bondable); | ||
|
||
void wait_connected(void) | ||
{ | ||
WAIT_FOR_FLAG(flag_is_connected); | ||
} | ||
|
||
void wait_disconnected(void) | ||
{ | ||
WAIT_FOR_FLAG_UNSET(flag_is_connected); | ||
} | ||
|
||
static void disconnected(struct bt_conn *conn, uint8_t reason) | ||
{ | ||
UNSET_FLAG(flag_is_connected); | ||
} | ||
|
||
BUILD_ASSERT(CONFIG_BT_MAX_CONN == 1, "This test assumes a single link."); | ||
static void connected(struct bt_conn *conn, uint8_t err) | ||
{ | ||
ASSERT((!g_conn || (conn == g_conn)), "Unexpected new connection."); | ||
|
||
if (!g_conn) { | ||
g_conn = bt_conn_ref(conn); | ||
} | ||
|
||
if (err != 0) { | ||
clear_g_conn(); | ||
return; | ||
} | ||
|
||
SET_FLAG(flag_is_connected); | ||
|
||
if (GET_FLAG(call_bt_conn_set_bondable) && bt_conn_set_bondable(conn, GET_FLAG(bondable))) { | ||
ASSERT(0, "Fail during setting bondable flag for given connection."); | ||
} | ||
} | ||
|
||
BT_CONN_CB_DEFINE(conn_callbacks) = { | ||
.connected = connected, | ||
.disconnected = disconnected, | ||
}; | ||
|
||
void clear_g_conn(void) | ||
{ | ||
struct bt_conn *conn; | ||
|
||
conn = g_conn; | ||
g_conn = NULL; | ||
ASSERT(conn, "Test error: No g_conn!\n"); | ||
bt_conn_unref(conn); | ||
} | ||
|
||
/* The following flags are raised by events and lowered by test code. */ | ||
DEFINE_FLAG(flag_pairing_complete); | ||
DEFINE_FLAG(flag_bonded); | ||
DEFINE_FLAG(flag_not_bonded); | ||
|
||
static void pairing_complete(struct bt_conn *conn, bool bonded) | ||
{ | ||
SET_FLAG(flag_pairing_complete); | ||
|
||
if (bonded) { | ||
SET_FLAG(flag_bonded); | ||
} else { | ||
SET_FLAG(flag_not_bonded); | ||
} | ||
} | ||
|
||
static struct bt_conn_auth_info_cb bt_conn_auth_info_cb = { | ||
.pairing_complete = pairing_complete, | ||
}; | ||
|
||
void bs_bt_utils_setup(void) | ||
{ | ||
int err; | ||
|
||
err = bt_enable(NULL); | ||
ASSERT(!err, "bt_enable failed.\n"); | ||
err = bt_conn_auth_info_cb_register(&bt_conn_auth_info_cb); | ||
ASSERT(!err, "bt_conn_auth_info_cb_register failed.\n"); | ||
} | ||
|
||
static void scan_connect_to_first_result__device_found(const bt_addr_le_t *addr, int8_t rssi, | ||
uint8_t type, struct net_buf_simple *ad) | ||
{ | ||
char addr_str[BT_ADDR_LE_STR_LEN]; | ||
int err; | ||
|
||
if (g_conn != NULL) { | ||
return; | ||
} | ||
|
||
/* We're only interested in connectable events */ | ||
if (type != BT_HCI_ADV_IND && type != BT_HCI_ADV_DIRECT_IND) { | ||
FAIL("Unexpected advertisement type."); | ||
} | ||
|
||
bt_addr_le_to_str(addr, addr_str, sizeof(addr_str)); | ||
printk("Got scan result, connecting.. dst %s, RSSI %d\n", addr_str, rssi); | ||
|
||
err = bt_le_scan_stop(); | ||
ASSERT(!err, "Err bt_le_scan_stop %d", err); | ||
|
||
err = bt_conn_le_create(addr, BT_CONN_LE_CREATE_CONN, BT_LE_CONN_PARAM_DEFAULT, &g_conn); | ||
ASSERT(!err, "Err bt_conn_le_create %d", err); | ||
} | ||
|
||
void scan_connect_to_first_result(void) | ||
{ | ||
int err; | ||
|
||
err = bt_le_scan_start(BT_LE_SCAN_PASSIVE, scan_connect_to_first_result__device_found); | ||
ASSERT(!err, "Err bt_le_scan_start %d", err); | ||
} | ||
|
||
void disconnect(void) | ||
{ | ||
int err; | ||
|
||
err = bt_conn_disconnect(g_conn, BT_HCI_ERR_REMOTE_USER_TERM_CONN); | ||
ASSERT(!err, "Err bt_conn_disconnect %d", err); | ||
} | ||
|
||
void unpair(int id) | ||
{ | ||
int err; | ||
|
||
err = bt_unpair(id, BT_ADDR_LE_ANY); | ||
ASSERT(!err, "Err bt_unpair %d", err); | ||
} | ||
|
||
void set_security(bt_security_t sec) | ||
{ | ||
int err; | ||
|
||
err = bt_conn_set_security(g_conn, sec); | ||
ASSERT(!err, "Err bt_conn_set_security %d", err); | ||
} | ||
|
||
void advertise_connectable(int id, bt_addr_le_t *directed_dst) | ||
{ | ||
int err; | ||
struct bt_le_adv_param param = {}; | ||
|
||
param.id = id; | ||
param.interval_min = 0x0020; | ||
param.interval_max = 0x4000; | ||
param.options |= BT_LE_ADV_OPT_ONE_TIME; | ||
param.options |= BT_LE_ADV_OPT_CONNECTABLE; | ||
|
||
if (directed_dst) { | ||
param.options |= BT_LE_ADV_OPT_DIR_ADDR_RPA; | ||
param.peer = directed_dst; | ||
} | ||
|
||
err = bt_le_adv_start(¶m, NULL, 0, NULL, 0); | ||
ASSERT(err == 0, "Advertising failed to start (err %d)\n", err); | ||
} | ||
|
||
void set_bondable(bool enable) | ||
{ | ||
if (enable) { | ||
SET_FLAG(bondable); | ||
} else { | ||
UNSET_FLAG(bondable); | ||
} | ||
} | ||
|
||
void enable_bt_conn_set_bondable(bool enable) | ||
{ | ||
if (enable) { | ||
SET_FLAG(call_bt_conn_set_bondable); | ||
} else { | ||
UNSET_FLAG(call_bt_conn_set_bondable); | ||
} | ||
} |
85 changes: 85 additions & 0 deletions
85
tests/bsim/bluetooth/host/security/bond_per_connection/src/bs_bt_utils.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
/** | ||
* Common functions and helpers for BSIM GATT tests | ||
* | ||
* Copyright (c) 2023 Nordic Semiconductor ASA | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
#include "bs_tracing.h" | ||
#include "bs_types.h" | ||
#include "bstests.h" | ||
#include "time_machine.h" | ||
#include "zephyr/sys/__assert.h" | ||
|
||
#include <errno.h> | ||
#include <stddef.h> | ||
#include <stdint.h> | ||
|
||
#include <zephyr/bluetooth/bluetooth.h> | ||
#include <zephyr/bluetooth/conn.h> | ||
#include <zephyr/bluetooth/gatt.h> | ||
#include <zephyr/bluetooth/hci.h> | ||
#include <zephyr/bluetooth/uuid.h> | ||
#include <zephyr/kernel.h> | ||
#include <zephyr/types.h> | ||
|
||
extern enum bst_result_t bst_result; | ||
|
||
#define DECLARE_FLAG(flag) extern atomic_t flag | ||
#define DEFINE_FLAG(flag) atomic_t flag = (atomic_t) false | ||
#define SET_FLAG(flag) (void)atomic_set(&flag, (atomic_t) true) | ||
#define UNSET_FLAG(flag) (void)atomic_set(&flag, (atomic_t) false) | ||
#define WAIT_FOR_FLAG(flag) \ | ||
while (!(bool)atomic_get(&flag)) { \ | ||
(void)k_sleep(K_MSEC(1)); \ | ||
} | ||
#define WAIT_FOR_FLAG_UNSET(flag) \ | ||
while ((bool)atomic_get(&flag)) { \ | ||
(void)k_sleep(K_MSEC(1)); \ | ||
} | ||
#define TAKE_FLAG(flag) \ | ||
while (!(bool)atomic_cas(&flag, true, false)) { \ | ||
(void)k_sleep(K_MSEC(1)); \ | ||
} | ||
#define GET_FLAG(flag) \ | ||
(bool)atomic_get(&flag) | ||
|
||
#define ASSERT(expr, ...) \ | ||
do { \ | ||
if (!(expr)) { \ | ||
FAIL(__VA_ARGS__); \ | ||
} \ | ||
} while (0) | ||
|
||
#define FAIL(...) \ | ||
do { \ | ||
bst_result = Failed; \ | ||
bs_trace_error_time_line(__VA_ARGS__); \ | ||
} while (0) | ||
|
||
#define PASS(...) \ | ||
do { \ | ||
bst_result = Passed; \ | ||
bs_trace_info_time(1, __VA_ARGS__); \ | ||
} while (0) | ||
|
||
void test_tick(bs_time_t HW_device_time); | ||
void test_init(void); | ||
|
||
DECLARE_FLAG(flag_pairing_complete); | ||
DECLARE_FLAG(flag_bonded); | ||
DECLARE_FLAG(flag_not_bonded); | ||
|
||
extern struct bt_conn *g_conn; | ||
void wait_connected(void); | ||
void wait_disconnected(void); | ||
void clear_g_conn(void); | ||
void bs_bt_utils_setup(void); | ||
void scan_connect_to_first_result(void); | ||
void disconnect(void); | ||
void unpair(int id); | ||
void set_security(bt_security_t sec); | ||
void advertise_connectable(int id, bt_addr_le_t *directed_dst); | ||
void set_bondable(bool enable); | ||
void enable_bt_conn_set_bondable(bool enable); |
55 changes: 55 additions & 0 deletions
55
tests/bsim/bluetooth/host/security/bond_per_connection/src/central.c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
/* | ||
* Copyright (c) 2023 Nordic Semiconductor ASA | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
#include "bs_bt_utils.h" | ||
#include "zephyr/bluetooth/addr.h" | ||
#include "zephyr/bluetooth/conn.h" | ||
|
||
#include <stdint.h> | ||
|
||
#include <zephyr/bluetooth/bluetooth.h> | ||
|
||
void central(void) | ||
{ | ||
bs_bt_utils_setup(); | ||
|
||
printk("== Bonding id a - global bondable mode ==\n"); | ||
BUILD_ASSERT(CONFIG_BT_BONDABLE, "CONFIG_BT_BONDABLE must be enabled by default."); | ||
enable_bt_conn_set_bondable(false); | ||
scan_connect_to_first_result(); | ||
wait_connected(); | ||
set_security(BT_SECURITY_L2); | ||
TAKE_FLAG(flag_pairing_complete); | ||
TAKE_FLAG(flag_bonded); | ||
disconnect(); | ||
wait_disconnected(); | ||
unpair(BT_ID_DEFAULT); | ||
clear_g_conn(); | ||
|
||
printk("== Bonding id a - bond per-connection ==\n"); | ||
enable_bt_conn_set_bondable(true); | ||
set_bondable(true); | ||
scan_connect_to_first_result(); | ||
wait_connected(); | ||
set_security(BT_SECURITY_L2); | ||
TAKE_FLAG(flag_pairing_complete); | ||
TAKE_FLAG(flag_bonded); | ||
disconnect(); | ||
wait_disconnected(); | ||
clear_g_conn(); | ||
|
||
printk("== Bonding id b - bond per-connection ==\n"); | ||
scan_connect_to_first_result(); | ||
wait_connected(); | ||
set_security(BT_SECURITY_L2); | ||
TAKE_FLAG(flag_pairing_complete); | ||
TAKE_FLAG(flag_not_bonded); | ||
disconnect(); | ||
wait_disconnected(); | ||
clear_g_conn(); | ||
|
||
PASS("PASS\n"); | ||
} |
Oops, something went wrong.