Bluetooth: Introduce new bt_set_id_addr() API

There are certain use cases where the application needs to be able to
explicitly set a specific identity address. This was previously
possible using the bt_storage API, however now that it's gone another
solution is needed.

This patch adds a ne bt_set_id_addr() API which the application can
use to set a specific identity address before calling bt_enable().

Fixes #7434

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
This commit is contained in:
Johan Hedberg 2018-05-10 17:25:25 +03:00 committed by Carles Cufí
commit 5b01cb1a46
3 changed files with 52 additions and 8 deletions

View file

@ -56,6 +56,21 @@ typedef void (*bt_ready_cb_t)(int err);
*/
int bt_enable(bt_ready_cb_t cb);
/** @brief Set the local Identity Address
*
* Allows setting the local Identity Address from the application.
* This API must be called before calling bt_enable(). Calling it at any
* other time will cause it to fail. In most cases the application doesn't
* need to use this API, however there are a few valid cases where
* it can be useful (such as for testing).
*
* At the moment, the given address must be a static random address. In the
* future support for public addresses may be added.
*
* @return Zero on success or (negative) error code otherwise.
*/
int bt_set_id_addr(const bt_addr_le_t *addr);
/* Advertising API */
/** Description of different data types that can be encoded into

View file

@ -2895,6 +2895,7 @@ static void le_dhkey_complete(struct net_buf *buf)
static void hci_reset_complete(struct net_buf *buf)
{
u8_t status = buf->data[0];
atomic_t flags;
BT_DBG("status %u", status);
@ -2910,8 +2911,8 @@ static void hci_reset_complete(struct net_buf *buf)
discovery_results_count = 0;
#endif /* CONFIG_BT_BREDR */
/* we only allow to enable once so this bit must be keep set */
atomic_set(bt_dev.flags, BIT(BT_DEV_ENABLE));
flags = (atomic_get(bt_dev.flags) & BT_DEV_PERSISTENT_FLAGS);
atomic_set(bt_dev.flags, flags);
}
static void hci_cmd_done(u16_t opcode, u8_t status, struct net_buf *buf)
@ -3572,12 +3573,14 @@ static int common_init(void)
net_buf_unref(rsp);
/* Read Bluetooth Address */
err = bt_hci_cmd_send_sync(BT_HCI_OP_READ_BD_ADDR, NULL, &rsp);
if (err) {
return err;
if (!atomic_test_bit(bt_dev.flags, BT_DEV_USER_ID_ADDR)) {
err = bt_hci_cmd_send_sync(BT_HCI_OP_READ_BD_ADDR, NULL, &rsp);
if (err) {
return err;
}
read_bdaddr_complete(rsp);
net_buf_unref(rsp);
}
read_bdaddr_complete(rsp);
net_buf_unref(rsp);
/* Read Local Supported Commands */
err = bt_hci_cmd_send_sync(BT_HCI_OP_READ_SUPPORTED_COMMANDS, NULL,
@ -4257,7 +4260,8 @@ static void hci_vs_init(void)
*/
if (IS_ENABLED(CONFIG_BT_HCI_VS_EXT_DETECT) &&
(bt_dev.hci_version < BT_HCI_VERSION_5_0 ||
bt_addr_le_cmp(&bt_dev.id_addr, BT_ADDR_LE_ANY))) {
(!atomic_test_bit(bt_dev.flags, BT_DEV_USER_ID_ADDR) &&
bt_addr_le_cmp(&bt_dev.id_addr, BT_ADDR_LE_ANY)))) {
BT_WARN("Controller doesn't seem to support Zephyr vendor HCI");
return;
}
@ -4612,6 +4616,25 @@ int bt_enable(bt_ready_cb_t cb)
return 0;
}
int bt_set_id_addr(const bt_addr_le_t *addr)
{
if (atomic_test_bit(bt_dev.flags, BT_DEV_READY)) {
BT_ERR("Setting identity not allowed after bt_enable()");
return -EBUSY;
}
if (addr->type != BT_ADDR_LE_RANDOM || !BT_ADDR_IS_STATIC(&addr->a)) {
BT_ERR("Only static random identity address supported");
return -EINVAL;
}
bt_addr_le_copy(&bt_dev.id_addr, addr);
atomic_set_bit(bt_dev.flags, BT_DEV_USER_ID_ADDR);
atomic_set_bit(bt_dev.flags, BT_DEV_ID_STATIC_RANDOM);
return 0;
}
bool bt_addr_le_is_bonded(const bt_addr_le_t *addr)
{
if (IS_ENABLED(CONFIG_BT_SMP)) {

View file

@ -31,6 +31,7 @@ enum {
BT_DEV_ENABLE,
BT_DEV_READY,
BT_DEV_ID_STATIC_RANDOM,
BT_DEV_USER_ID_ADDR,
BT_DEV_HAS_PUB_KEY,
BT_DEV_PUB_KEY_BUSY,
@ -55,6 +56,11 @@ enum {
BT_DEV_NUM_FLAGS,
};
/* Flags which should not be cleared upon HCI_Reset */
#define BT_DEV_PERSISTENT_FLAGS (BIT(BT_DEV_ENABLE) | \
BIT(BT_DEV_USER_ID_ADDR) | \
BIT(BT_DEV_ID_STATIC_RANDOM))
struct bt_dev_le {
/* LE features */
u8_t features[8];