Bluetooth: Host: Fix not clearing IDs and keys upon bt_disable()

Expectation: After calling `bt_disable()` it is possible to
use the Bluetooth APIs as if `bt_enable()` was never called.

This was not the case for `bt_id_create()`, it was not possible
to set the default identity. This prevented an application
developer to restart the stack as a different identity.

Keys also need to be cleared to avoid the following pattern:
1. Pair two devices
2. Central calls `bt_disable()` and `bt_enable()`.
   The central will now generate a new identity address.
3. Connect the two devices.
4. Re-establish encryption. Now the central will try to use
   the previously used keys. The procedure will fail
   because the peripheral does not have any keys associated
   with the new central address.

The API documentation is updated accordingly.

Signed-off-by: Rubin Gerritsen <rubin.gerritsen@nordicsemi.no>
This commit is contained in:
Rubin Gerritsen 2024-05-13 13:51:57 +02:00 committed by Carles Cufí
commit 3ce106c620
7 changed files with 106 additions and 0 deletions

View file

@ -2,6 +2,7 @@ CONFIG_BT=y
CONFIG_LOG=y
CONFIG_ASSERT=y
CONFIG_BT_SMP=y
CONFIG_BT_MAX_PAIRED=2
CONFIG_BT_DEVICE_NAME="CIS test"

View file

@ -35,6 +35,62 @@ static void test_disable_main(void)
PASS("Disable test passed\n");
}
static void test_disable_set_default_id(void)
{
/* FIXME: Temporary workaround to get around a bug in the controller.
* The controller gets stuck in the POWER_CLOCK ISR without this.
* See open PR: https://github.com/zephyrproject-rtos/zephyr/pull/73342
* for more details.
*/
k_sleep(K_MSEC(1));
for (int i = 0; i < NUM_ITERATIONS; i++) {
int err;
size_t id_count;
bt_addr_le_t stored_id;
bt_addr_le_t addr = {.type = BT_ADDR_LE_RANDOM,
.a = {.val = {i, 2, 3, 4, 5, 0xc0}}};
err = bt_id_create(&addr, NULL);
if (err != 0) {
FAIL("Creating ID failed (err %d)\n", err);
}
err = bt_enable(NULL);
if (err != 0) {
FAIL("Enable failed (err %d)\n", err);
}
bt_id_get(NULL, &id_count);
if (id_count != 1) {
FAIL("Expected only one ID, but got: %u\n", id_count);
}
id_count = 1;
bt_id_get(&stored_id, &id_count);
if (id_count != 1) {
FAIL("Expected only one ID, but got: %u\n", id_count);
}
if (!bt_addr_le_eq(&stored_id, &addr)) {
uint8_t addr_set_str[BT_ADDR_LE_STR_LEN];
uint8_t addr_stored_str[BT_ADDR_LE_STR_LEN];
bt_addr_le_to_str(&addr, addr_set_str, BT_ADDR_LE_STR_LEN);
bt_addr_le_to_str(&stored_id, addr_stored_str, BT_ADDR_LE_STR_LEN);
FAIL("Expected stored ID to be equal to set ID: %s, %s\n",
addr_set_str, addr_stored_str);
}
err = bt_disable();
if (err) {
FAIL("Enable failed (err %d)\n", err);
}
}
PASS("Disable set default ID test passed\n");
}
static const struct bst_test_instance test_def[] = {
{
.test_id = "disable",
@ -43,6 +99,13 @@ static const struct bst_test_instance test_def[] = {
.test_tick_f = test_tick,
.test_main_f = test_disable_main
},
{
.test_id = "disable_set_default_id",
.test_descr = "disable_test where each iteration sets the default ID",
.test_pre_init_f = test_init,
.test_tick_f = test_tick,
.test_main_f = test_disable_set_default_id
},
BSTEST_END_MARKER
};

View file

@ -0,0 +1,20 @@
#!/usr/bin/env bash
# Copyright (c) 2022 Nordic Semiconductor
# SPDX-License-Identifier: Apache-2.0
source ${ZEPHYR_BASE}/tests/bsim/sh_common.source
# Disable test: bt_enable and bt_disable are called in a loop.
# Each iteration the default ID is updated
simulation_id="disable_test_set_default_id"
verbosity_level=2
cd ${BSIM_OUT_PATH}/bin
Execute ./bs_${BOARD_TS}_tests_bsim_bluetooth_host_misc_disable_prj_conf \
-v=${verbosity_level} -s=${simulation_id} -d=0 -testid=disable_set_default_id
Execute ./bs_2G4_phy_v1 -v=${verbosity_level} -s=${simulation_id} \
-D=1 -sim_length=10e6 $@
wait_for_background_jobs