diff --git a/include/zephyr/bluetooth/bluetooth.h b/include/zephyr/bluetooth/bluetooth.h index 59689974b87..72c386ae4d6 100644 --- a/include/zephyr/bluetooth/bluetooth.h +++ b/include/zephyr/bluetooth/bluetooth.h @@ -231,6 +231,10 @@ int bt_enable(bt_ready_cb_t cb); * * Disable Bluetooth. Can't be called before bt_enable has completed. * + * This API will clear all configured identities and keys that are not persistently + * stored with @kconfig{CONFIG_BT_SETTINGS}. These can be restored + * with settings_load() before reenabling the stack. + * * Close and release HCI resources. Result is architecture dependent. * * @return Zero on success or (negative) error code otherwise. diff --git a/subsys/bluetooth/host/hci_core.c b/subsys/bluetooth/host/hci_core.c index 1c4a5ca67e1..3f0a32dd094 100644 --- a/subsys/bluetooth/host/hci_core.c +++ b/subsys/bluetooth/host/hci_core.c @@ -4233,6 +4233,13 @@ int bt_disable(void) /* Some functions rely on checking this bitfield */ memset(bt_dev.supported_commands, 0x00, sizeof(bt_dev.supported_commands)); + /* Reset IDs and corresponding keys. */ + bt_dev.id_count = 0; +#if defined(CONFIG_BT_SMP) + bt_dev.le.rl_entries = 0; + bt_keys_reset(); +#endif + /* If random address was set up - clear it */ bt_addr_le_copy(&bt_dev.random_addr, BT_ADDR_LE_ANY); diff --git a/subsys/bluetooth/host/keys.c b/subsys/bluetooth/host/keys.c index c8184d7cbb4..6740d43b1cd 100644 --- a/subsys/bluetooth/host/keys.c +++ b/subsys/bluetooth/host/keys.c @@ -80,6 +80,11 @@ static bool key_is_in_use(uint8_t id) } #endif /* CONFIG_BT_KEYS_OVERWRITE_OLDEST */ +void bt_keys_reset(void) +{ + memset(key_pool, 0, sizeof(key_pool)); +} + struct bt_keys *bt_keys_get_addr(uint8_t id, const bt_addr_le_t *addr) { struct bt_keys *keys; diff --git a/subsys/bluetooth/host/keys.h b/subsys/bluetooth/host/keys.h index 198b6991ca9..76508e0cf39 100644 --- a/subsys/bluetooth/host/keys.h +++ b/subsys/bluetooth/host/keys.h @@ -82,6 +82,12 @@ struct bt_keys { #define BT_KEYS_STORAGE_LEN (sizeof(struct bt_keys) - \ offsetof(struct bt_keys, storage_start)) +/** Clears all keys. + * + * Keys stored in settings are not cleared. + */ +void bt_keys_reset(void); + /** * @brief Get a call through the callback for each key with the same type * diff --git a/tests/bsim/bluetooth/host/iso/cis/prj.conf b/tests/bsim/bluetooth/host/iso/cis/prj.conf index 134cd4beed5..8637b14f004 100644 --- a/tests/bsim/bluetooth/host/iso/cis/prj.conf +++ b/tests/bsim/bluetooth/host/iso/cis/prj.conf @@ -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" diff --git a/tests/bsim/bluetooth/host/misc/disable/src/main_disable.c b/tests/bsim/bluetooth/host/misc/disable/src/main_disable.c index d4a6f6d904a..43f9b00af8b 100644 --- a/tests/bsim/bluetooth/host/misc/disable/src/main_disable.c +++ b/tests/bsim/bluetooth/host/misc/disable/src/main_disable.c @@ -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 }; diff --git a/tests/bsim/bluetooth/host/misc/disable/tests_scripts/disable_set_default_id.sh b/tests/bsim/bluetooth/host/misc/disable/tests_scripts/disable_set_default_id.sh new file mode 100755 index 00000000000..437dcdff139 --- /dev/null +++ b/tests/bsim/bluetooth/host/misc/disable/tests_scripts/disable_set_default_id.sh @@ -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