Bluetooth: Introduce bt_id_reset() API

Add a new API which can be used to reclaim an identity slot for a new
identity. When called, any previous pairings, connections, or other
data will be cleared, and then a new identity will be generated in the
place of the old one.

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
This commit is contained in:
Johan Hedberg 2018-07-18 13:47:04 +03:00 committed by Johan Hedberg
commit 7dba2512e3
2 changed files with 102 additions and 31 deletions

View file

@ -150,6 +150,39 @@ void bt_id_get(bt_addr_le_t *addrs, size_t *count);
*/
int bt_id_create(bt_addr_le_t *addr, u8_t *irk);
/** @brief Reset/reclaim an identity for reuse.
*
* The semantics of the @a addr and @a irk parameters of this function
* are the same as with bt_id_create(). The difference is the first
* @a id parameter that needs to be an existing identity (if it doesn't
* exist this function will return an error). When given an existing
* identity this function will disconnect any connections created using it,
* remove any pairing keys or other data associated with it, and then create
* a new identity in the same slot, based on the @a addr and @a irk
* parameters.
*
* Note: the default identity (BT_ID_DEFAULT) cannot be reset, i.e. this
* API will return an error if asked to do that.
*
* @param id Existing identity identifier.
* @param addr Address to use for the new identity. If NULL or initialized
* to BT_ADDR_LE_ANY the stack will generate a new static
* random address for the identity and copy it to the given
* parameter upon return from this function (in case the
* parameter was non-NULL).
* @param irk Identity Resolving Key (16 bytes) to be used with this
* identity. If set to all zeroes or NULL, the stack will
* generate a random IRK for the identity and copy it back
* to the parameter upon return from this function (in case
* the parameter was non-NULL). If privacy support
* (CONFIG_BT_PRIVACY) is not enabled this parameter must
* be NULL.
*
* @return Identity identifier (>= 0) in case of success, or a negative
* error code on failure.
*/
int bt_id_reset(u8_t id, bt_addr_le_t *addr, u8_t *irk);
/* Advertising API */
/** Description of different data types that can be encoded into

View file

@ -4831,6 +4831,41 @@ void bt_id_get(bt_addr_le_t *addrs, size_t *count)
*count = to_copy;
}
static void id_create(u8_t id, bt_addr_le_t *addr, u8_t *irk)
{
if (addr && bt_addr_le_cmp(addr, BT_ADDR_LE_ANY)) {
bt_addr_le_copy(&bt_dev.id_addr[id], addr);
} else {
bt_addr_le_create_static(&bt_dev.id_addr[id]);
if (addr) {
bt_addr_le_copy(addr, &bt_dev.id_addr[id]);
}
}
#if defined(CONFIG_BT_PRIVACY)
if (atomic_test_bit(bt_dev.flags, BT_DEV_READY)) {
u8_t zero_irk[16] = { 0 };
if (irk && memcmp(irk, zero_irk, 16)) {
memcpy(&bt_dev.irk[id], irk, 16);
} else {
bt_rand(&bt_dev.irk[id], 16);
if (irk) {
memcpy(irk, &bt_dev.irk[id], 16);
}
}
}
#endif
/* Only store if stack was already initialized. Before initialization
* we don't know the flash content, so it's potentially harmful to
* try to write anything there.
*/
if (IS_ENABLED(CONFIG_BT_SETTINGS) &&
atomic_test_bit(bt_dev.flags, BT_DEV_READY)) {
bt_settings_save_id();
}
}
int bt_id_create(bt_addr_le_t *addr, u8_t *irk)
{
int new_id;
@ -4855,41 +4890,44 @@ int bt_id_create(bt_addr_le_t *addr, u8_t *irk)
atomic_set_bit(bt_dev.flags, BT_DEV_USER_ID_ADDR);
}
if (addr && bt_addr_le_cmp(addr, BT_ADDR_LE_ANY)) {
bt_addr_le_copy(&bt_dev.id_addr[new_id], addr);
} else {
bt_addr_le_create_static(&bt_dev.id_addr[new_id]);
if (addr) {
bt_addr_le_copy(addr, &bt_dev.id_addr[new_id]);
}
}
#if defined(CONFIG_BT_PRIVACY)
if (atomic_test_bit(bt_dev.flags, BT_DEV_READY)) {
u8_t zero_irk[16] = { 0 };
if (irk && memcmp(irk, zero_irk, 16)) {
memcpy(&bt_dev.irk[new_id], irk, 16);
} else {
bt_rand(&bt_dev.irk[new_id], 16);
if (irk) {
memcpy(irk, &bt_dev.irk[new_id], 16);
}
}
}
#endif
/* Only store if stack was already initialized. Before initialization
* we don't know the flash content, so it's potentially harmful to
* try to write anything there.
*/
if (IS_ENABLED(CONFIG_BT_SETTINGS) &&
atomic_test_bit(bt_dev.flags, BT_DEV_READY);
bt_settings_save_id();
}
id_create(new_id, addr, irk);
return new_id;
}
int bt_id_reset(u8_t id, bt_addr_le_t *addr, u8_t *irk)
{
int err;
if (addr && bt_addr_le_cmp(addr, BT_ADDR_LE_ANY) &&
(addr->type != BT_ADDR_LE_RANDOM || !BT_ADDR_IS_STATIC(&addr->a))) {
BT_ERR("Only static random identity address supported");
return -EINVAL;
}
if (!IS_ENABLED(CONFIG_BT_PRIVACY) && irk) {
return -EINVAL;
}
if (id == BT_ID_DEFAULT || id >= bt_dev.id_count) {
return -EINVAL;
}
if (id == bt_dev.adv_id && atomic_test_bit(bt_dev.flags,
BT_DEV_ADVERTISING)) {
return -EBUSY;
}
err = bt_unpair(id, NULL);
if (err) {
return err;
}
id_create(id, addr, irk);
return id;
}
bool bt_addr_le_is_bonded(u8_t id, const bt_addr_le_t *addr)
{
if (IS_ENABLED(CONFIG_BT_SMP)) {