Bluetooth: Add initial APIs for identity manipulation

Add APIs for getting current identities as well as for creating new
ones.

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
This commit is contained in:
Johan Hedberg 2018-07-13 12:04:39 +03:00 committed by Johan Hedberg
commit 1d8dab811e
2 changed files with 108 additions and 4 deletions

View file

@ -97,6 +97,58 @@ const char *bt_get_name(void);
*/
int bt_set_id_addr(const bt_addr_le_t *addr);
/** @brief Get the currently configured identities.
*
* Returns an array of the currently configured identity addresses. To
* make sure all available identities can be retrieved, the number of
* elements in the @a addrs array should be CONFIG_BT_ID_MAX. The identity
* identifier that some APIs expect (such as advertising parameters) is
* simply the index of the identity in the @a addrs array.
*
* @param addrs Array where to store the configured identities.
* @param count Should be initialized to the array size. Once the function
* returns it will contain the number of returned identies.
*/
void bt_id_get(bt_addr_le_t *addrs, size_t *count);
/** @brief Create a new identity.
*
* Create a new identity using the given address and IRK. This function
* can be called before calling bt_enable(), in which case it can be used
* to override the controller's public address (in case it has one). However,
* the new identity will only be stored persistently in flash when this API
* is used after bt_enable(). The reason is that the persistent settings
* are loaded after bt_enable() and would therefore cause potential conflicts
* with the stack blindly overwriting what's stored in flash. The identity
* will also not be written to flash in case a pre-defined address is
* provided, since in such a situation the app clearly has some place it got
* the address from and will be able to repeat the procedure on every power
* cycle, i.e. it would be redundant to also store the information in flash.
*
* If the application wants to have the stack randomly generate identities
* and store them in flash for later recovery, the way to do it would be
* to first initialize the stack (using bt_enable), then call settings_load(),
* and after that check with bt_id_get() how many identities were recovered.
* If an insufficient amount of identities were recovered the app may then
* call bt_id_create() to create new ones.
*
* @param addr Address to use for the new identity. If 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.
* @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_create(bt_addr_le_t *addr, u8_t *irk);
/* Advertising API */
/** Description of different data types that can be encoded into

View file

@ -4847,21 +4847,73 @@ const char *bt_get_name(void)
int bt_set_id_addr(const bt_addr_le_t *addr)
{
bt_addr_le_t non_const_addr;
if (atomic_test_bit(bt_dev.flags, BT_DEV_READY)) {
BT_ERR("Setting identity not allowed after bt_enable()");
return -EBUSY;
}
bt_addr_le_copy(&non_const_addr, addr);
return bt_id_create(&non_const_addr, NULL);
}
void bt_id_get(bt_addr_le_t *addrs, size_t *count)
{
size_t to_copy = min(*count, bt_dev.id_count);
memcpy(addrs, bt_dev.id_addr, to_copy * sizeof(bt_addr_le_t));
*count = to_copy;
}
int bt_id_create(bt_addr_le_t *addr, u8_t *irk)
{
int new_id;
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[0], addr);
atomic_set_bit(bt_dev.flags, BT_DEV_USER_ID_ADDR);
atomic_set_bit(bt_dev.flags, BT_DEV_ID_STATIC_RANDOM);
if (!IS_ENABLED(CONFIG_BT_PRIVACY) && irk) {
return -EINVAL;
}
return 0;
if (bt_dev.id_count == ARRAY_SIZE(bt_dev.id_addr)) {
return -ENOMEM;
}
new_id = bt_dev.id_count++;
if (new_id == BT_ID_DEFAULT) {
atomic_set_bit(bt_dev.flags, BT_DEV_USER_ID_ADDR);
atomic_set_bit(bt_dev.flags, BT_DEV_ID_STATIC_RANDOM);
}
if (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]);
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) ||
new_id != BT_ID_DEFAULT) {
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
return new_id;
}
bool bt_addr_le_is_bonded(u8_t id, const bt_addr_le_t *addr)