bluetooth: add HCI driver parameter to set controller's public address
This allows HCI drivers to expose vendor-specific functions to set the public address. Signed-off-by: Armin Brauns <armin.brauns@embedded-solutions.at>
This commit is contained in:
parent
1e91453005
commit
5b1b260f80
12 changed files with 122 additions and 13 deletions
|
@ -52,6 +52,11 @@ Device Drivers and Device Tree
|
||||||
drdy-pin = <2>;
|
drdy-pin = <2>;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
* The optional :c:func:`setup()` function in the Bluetooth HCI driver API (enabled through
|
||||||
|
:kconfig:option:`CONFIG_BT_HCI_SETUP`) has gained a function parameter of type
|
||||||
|
:c:struct:`bt_hci_setup_params`. By default, the struct is empty, but drivers can opt-in to
|
||||||
|
:kconfig:option:`CONFIG_BT_HCI_SET_PUBLIC_ADDR` if they support setting the controller's public
|
||||||
|
identity address, which will then be passed in the ``public_addr`` field.
|
||||||
|
|
||||||
(:github:`62994`)
|
(:github:`62994`)
|
||||||
|
|
||||||
|
|
|
@ -164,6 +164,16 @@ config BT_DRIVER_QUIRK_NO_AUTO_DLE
|
||||||
This has to be enabled when the BLE controller connected is Zephyr
|
This has to be enabled when the BLE controller connected is Zephyr
|
||||||
open source controller.
|
open source controller.
|
||||||
|
|
||||||
|
config BT_HCI_SET_PUBLIC_ADDR
|
||||||
|
bool
|
||||||
|
select BT_HCI_SETUP
|
||||||
|
help
|
||||||
|
Pass the controller's public address to the HCI driver in setup()
|
||||||
|
|
||||||
|
This option should be enabled by drivers for controllers that support setting the
|
||||||
|
public identity through vendor-specific commands. They can then implement the
|
||||||
|
setup() HCI driver API function and get the address to set from the public_addr field.
|
||||||
|
|
||||||
config BT_HCI_SETUP
|
config BT_HCI_SETUP
|
||||||
bool
|
bool
|
||||||
help
|
help
|
||||||
|
|
|
@ -529,8 +529,10 @@ static int h4_open(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(CONFIG_BT_HCI_SETUP)
|
#if defined(CONFIG_BT_HCI_SETUP)
|
||||||
static int h4_setup(void)
|
static int h4_setup(const struct bt_hci_setup_params *params)
|
||||||
{
|
{
|
||||||
|
ARG_UNUSED(params);
|
||||||
|
|
||||||
/* Extern bt_h4_vnd_setup function.
|
/* Extern bt_h4_vnd_setup function.
|
||||||
* This function executes vendor-specific commands sequence to
|
* This function executes vendor-specific commands sequence to
|
||||||
* initialize BT Controller before BT Host executes Reset sequence.
|
* initialize BT Controller before BT Host executes Reset sequence.
|
||||||
|
|
|
@ -196,8 +196,9 @@ static int psoc6_bless_send(struct net_buf *buf)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int psoc6_bless_setup(void)
|
static int psoc6_bless_setup(const struct bt_hci_setup_params *params)
|
||||||
{
|
{
|
||||||
|
ARG_UNUSED(params);
|
||||||
struct net_buf *buf;
|
struct net_buf *buf;
|
||||||
int err;
|
int err;
|
||||||
uint8_t *addr = (uint8_t *)&SFLASH_BLE_DEVICE_ADDRESS[0];
|
uint8_t *addr = (uint8_t *)&SFLASH_BLE_DEVICE_ADDRESS[0];
|
||||||
|
|
|
@ -340,6 +340,12 @@ void bt_id_get(bt_addr_le_t *addrs, size_t *count);
|
||||||
* If an insufficient amount of identities were recovered the app may then
|
* If an insufficient amount of identities were recovered the app may then
|
||||||
* call bt_id_create() to create new ones.
|
* call bt_id_create() to create new ones.
|
||||||
*
|
*
|
||||||
|
* If supported by the HCI driver (indicated by setting
|
||||||
|
* @kconfig{CONFIG_BT_HCI_SET_PUBLIC_ADDR}), the first call to this function can be
|
||||||
|
* used to set the controller's public identity address. This call must happen
|
||||||
|
* before calling bt_enable(). Subsequent calls always add/generate random
|
||||||
|
* static addresses.
|
||||||
|
*
|
||||||
* @param addr Address to use for the new identity. If NULL or initialized
|
* @param addr Address to use for the new identity. If NULL or initialized
|
||||||
* to BT_ADDR_LE_ANY the stack will generate a new random
|
* to BT_ADDR_LE_ANY the stack will generate a new random
|
||||||
* static address for the identity and copy it to the given
|
* static address for the identity and copy it to the given
|
||||||
|
|
|
@ -139,6 +139,16 @@ enum bt_hci_driver_bus {
|
||||||
BT_HCI_DRIVER_BUS_IPM = 9,
|
BT_HCI_DRIVER_BUS_IPM = 9,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if defined(CONFIG_BT_HCI_SETUP) || defined(__DOXYGEN__)
|
||||||
|
struct bt_hci_setup_params {
|
||||||
|
/** The public identity address to give to the controller. This field is used when the
|
||||||
|
* driver selects @kconfig{CONFIG_BT_HCI_SET_PUBLIC_ADDR} to indicate that it supports
|
||||||
|
* setting the controller's public address.
|
||||||
|
*/
|
||||||
|
bt_addr_t public_addr;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Abstraction which represents the HCI transport to the controller.
|
* @brief Abstraction which represents the HCI transport to the controller.
|
||||||
*
|
*
|
||||||
|
@ -213,7 +223,7 @@ struct bt_hci_driver {
|
||||||
*
|
*
|
||||||
* @return 0 on success or negative error number on failure.
|
* @return 0 on success or negative error number on failure.
|
||||||
*/
|
*/
|
||||||
int (*setup)(void);
|
int (*setup)(const struct bt_hci_setup_params *params);
|
||||||
#endif /* defined(CONFIG_BT_HCI_SETUP) || defined(__DOXYGEN__)*/
|
#endif /* defined(CONFIG_BT_HCI_SETUP) || defined(__DOXYGEN__)*/
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -3668,9 +3668,19 @@ static void hci_vs_init(void)
|
||||||
static int hci_init(void)
|
static int hci_init(void)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
#if defined(CONFIG_BT_HCI_SETUP)
|
#if defined(CONFIG_BT_HCI_SETUP)
|
||||||
|
struct bt_hci_setup_params setup_params = { 0 };
|
||||||
|
|
||||||
|
bt_addr_copy(&setup_params.public_addr, BT_ADDR_ANY);
|
||||||
|
#if defined(CONFIG_BT_HCI_SET_PUBLIC_ADDR)
|
||||||
|
if (bt_dev.id_count > 0 && bt_dev.id_addr[BT_ID_DEFAULT].type == BT_ADDR_LE_PUBLIC) {
|
||||||
|
bt_addr_copy(&setup_params.public_addr, &bt_dev.id_addr[BT_ID_DEFAULT].a);
|
||||||
|
}
|
||||||
|
#endif /* defined(CONFIG_BT_HCI_SET_PUBLIC_ADDR) */
|
||||||
|
|
||||||
if (bt_dev.drv->setup) {
|
if (bt_dev.drv->setup) {
|
||||||
err = bt_dev.drv->setup();
|
err = bt_dev.drv->setup(&setup_params);
|
||||||
if (err) {
|
if (err) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1281,20 +1281,27 @@ int bt_id_create(bt_addr_le_t *addr, uint8_t *irk)
|
||||||
{
|
{
|
||||||
int new_id, err;
|
int new_id, err;
|
||||||
|
|
||||||
if (addr && !bt_addr_le_eq(addr, BT_ADDR_LE_ANY)) {
|
if (!IS_ENABLED(CONFIG_BT_PRIVACY) && irk) {
|
||||||
if (addr->type != BT_ADDR_LE_RANDOM ||
|
return -EINVAL;
|
||||||
!BT_ADDR_IS_STATIC(&addr->a)) {
|
}
|
||||||
LOG_ERR("Only static random identity address supported");
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (addr && !bt_addr_le_eq(addr, BT_ADDR_LE_ANY)) {
|
||||||
if (id_find(addr) >= 0) {
|
if (id_find(addr) >= 0) {
|
||||||
return -EALREADY;
|
return -EALREADY;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (!IS_ENABLED(CONFIG_BT_PRIVACY) && irk) {
|
if (addr->type == BT_ADDR_LE_PUBLIC && IS_ENABLED(CONFIG_BT_HCI_SET_PUBLIC_ADDR)) {
|
||||||
return -EINVAL;
|
/* set the single public address */
|
||||||
|
if (bt_dev.id_count != 0) {
|
||||||
|
return -EALREADY;
|
||||||
|
}
|
||||||
|
bt_addr_le_copy(&bt_dev.id_addr[BT_ID_DEFAULT], addr);
|
||||||
|
bt_dev.id_count++;
|
||||||
|
return BT_ID_DEFAULT;
|
||||||
|
} else if (addr->type != BT_ADDR_LE_RANDOM || !BT_ADDR_IS_STATIC(&addr->a)) {
|
||||||
|
LOG_ERR("Only random static identity address supported");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bt_dev.id_count == ARRAY_SIZE(bt_dev.id_addr)) {
|
if (bt_dev.id_count == ARRAY_SIZE(bt_dev.id_addr)) {
|
||||||
|
|
11
tests/bluetooth/host/id/bt_id_create/Kconfig
Normal file
11
tests/bluetooth/host/id/bt_id_create/Kconfig
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
# Copyright (c) 2023 Nordic Semiconductor ASA
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
config SELECT_BT_HCI_SET_PUBLIC_ADDR
|
||||||
|
bool "dummy kconfig"
|
||||||
|
select BT_HCI_SET_PUBLIC_ADDR
|
||||||
|
help
|
||||||
|
dummy kconfig
|
||||||
|
|
||||||
|
source "Kconfig.zephyr"
|
|
@ -215,3 +215,40 @@ ZTEST(bt_id_create, test_create_id_valid_input_address)
|
||||||
zassert_mem_equal(&bt_dev.id_addr[new_id], BT_STATIC_RANDOM_LE_ADDR_1, sizeof(bt_addr_le_t),
|
zassert_mem_equal(&bt_dev.id_addr[new_id], BT_STATIC_RANDOM_LE_ADDR_1, sizeof(bt_addr_le_t),
|
||||||
"Incorrect address was set");
|
"Incorrect address was set");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Test creating a new public identity.
|
||||||
|
*
|
||||||
|
* Constraints:
|
||||||
|
* - A valid address of type public is used
|
||||||
|
* - Input IRK is NULL
|
||||||
|
* - 'BT_DEV_ENABLE' flag is set in bt_dev.flags
|
||||||
|
*
|
||||||
|
* Expected behaviour:
|
||||||
|
* - The public address is loaded to bt_dev.id_addr[BT_ID_DEFAULT]
|
||||||
|
* - bt_dev.id_count is incremented
|
||||||
|
*/
|
||||||
|
ZTEST(bt_id_create, test_public_address)
|
||||||
|
{
|
||||||
|
int id_count, new_id;
|
||||||
|
bt_addr_le_t addr = *BT_LE_ADDR;
|
||||||
|
|
||||||
|
if (!IS_ENABLED(CONFIG_BT_HCI_SET_PUBLIC_ADDR)) {
|
||||||
|
ztest_test_skip();
|
||||||
|
}
|
||||||
|
|
||||||
|
id_count = bt_dev.id_count;
|
||||||
|
atomic_set_bit(bt_dev.flags, BT_DEV_ENABLE);
|
||||||
|
/* Calling bt_addr_le_create_static() isn't expected */
|
||||||
|
bt_addr_le_create_static_fake.return_val = -1;
|
||||||
|
|
||||||
|
new_id = bt_id_create(&addr, NULL);
|
||||||
|
|
||||||
|
expect_not_called_bt_addr_le_create_static();
|
||||||
|
|
||||||
|
zassert_true(new_id == BT_ID_DEFAULT, "Unexpected error code '%d' was returned", new_id);
|
||||||
|
zassert_true(bt_dev.id_count == (id_count + 1), "Incorrect ID count %d was set",
|
||||||
|
bt_dev.id_count);
|
||||||
|
zassert_mem_equal(&bt_dev.id_addr[new_id], BT_LE_ADDR, sizeof(bt_addr_le_t),
|
||||||
|
"Incorrect address was set");
|
||||||
|
}
|
||||||
|
|
|
@ -93,6 +93,10 @@ ZTEST(bt_id_create_invalid_inputs, test_public_address)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
if (IS_ENABLED(CONFIG_BT_HCI_SET_PUBLIC_ADDR)) {
|
||||||
|
ztest_test_skip();
|
||||||
|
}
|
||||||
|
|
||||||
err = bt_id_create(BT_LE_ADDR, NULL);
|
err = bt_id_create(BT_LE_ADDR, NULL);
|
||||||
|
|
||||||
zassert_true(err == -EINVAL, "Unexpected error code '%d' was returned", err);
|
zassert_true(err == -EINVAL, "Unexpected error code '%d' was returned", err);
|
||||||
|
|
|
@ -5,6 +5,12 @@ common:
|
||||||
tests:
|
tests:
|
||||||
bluetooth.host.bt_id_create.default:
|
bluetooth.host.bt_id_create.default:
|
||||||
type: unit
|
type: unit
|
||||||
|
bluetooth.host.bt_id_create.bt_set_public_addr:
|
||||||
|
type: unit
|
||||||
|
extra_configs:
|
||||||
|
- CONFIG_BT_SMP=y
|
||||||
|
- CONFIG_BT_PRIVACY=y
|
||||||
|
- CONFIG_SELECT_BT_HCI_SET_PUBLIC_ADDR=y
|
||||||
bluetooth.host.bt_id_create.bt_privacy_enabled:
|
bluetooth.host.bt_id_create.bt_privacy_enabled:
|
||||||
type: unit
|
type: unit
|
||||||
extra_configs:
|
extra_configs:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue