Bluetooth: Add full storage support for multiple identities
Update the storage handling to take into account multiple identities. We can save a bit of code by using the new bt_id_create() API from within settings.c. Also make the treatment of addr & irk parameters to bt_id_create() consistent, in that NULL is acceptable for both of them. Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
This commit is contained in:
parent
3ed01b48b9
commit
e70c556dcc
5 changed files with 72 additions and 90 deletions
|
@ -132,10 +132,11 @@ void bt_id_get(bt_addr_le_t *addrs, size_t *count);
|
|||
* 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
|
||||
* @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.
|
||||
* 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
|
||||
|
|
|
@ -4193,20 +4193,8 @@ int bt_addr_le_create_static(bt_addr_le_t *addr)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int bt_set_static_addr(const bt_addr_le_t *addr)
|
||||
int bt_setup_id_addr(void)
|
||||
{
|
||||
if (addr->type != BT_ADDR_LE_RANDOM || !BT_ADDR_IS_STATIC(&addr->a)) {
|
||||
BT_ERR("Only static random address supported as identity");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return set_random_address(&addr->a);
|
||||
}
|
||||
|
||||
static int setup_id_addr(void)
|
||||
{
|
||||
int err;
|
||||
|
||||
#if defined(CONFIG_BT_HCI_VS_EXT)
|
||||
/* Check for VS_Read_Static_Addresses support. Only read the
|
||||
* addresses if the user has not already configured one or
|
||||
|
@ -4215,7 +4203,7 @@ static int setup_id_addr(void)
|
|||
if (!bt_dev.id_count && (bt_dev.vs_commands[1] & BIT(0))) {
|
||||
struct bt_hci_rp_vs_read_static_addrs *rp;
|
||||
struct net_buf *rsp;
|
||||
int i;
|
||||
int err, i;
|
||||
|
||||
err = bt_hci_cmd_send_sync(BT_HCI_OP_VS_READ_STATIC_ADDRS,
|
||||
NULL, &rsp);
|
||||
|
@ -4234,7 +4222,7 @@ static int setup_id_addr(void)
|
|||
net_buf_unref(rsp);
|
||||
|
||||
if (bt_dev.id_count) {
|
||||
return bt_set_static_addr(&bt_dev.id_addr[0]);
|
||||
return set_random_address(&bt_dev.id_addr[0].a);
|
||||
}
|
||||
|
||||
BT_WARN("No static addresses stored in controller");
|
||||
|
@ -4245,21 +4233,7 @@ static int setup_id_addr(void)
|
|||
generate:
|
||||
#endif
|
||||
|
||||
if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
|
||||
BT_DBG("Expecing identity addr to be handled by settings");
|
||||
return 0;
|
||||
} else {
|
||||
err = bt_addr_le_create_static(&bt_dev.id_addr[0]);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
bt_dev.id_count = 1;
|
||||
BT_WARN("Using temporary static random address %s",
|
||||
bt_addr_str(&bt_dev.id_addr[0].a));
|
||||
|
||||
return bt_set_static_addr(&bt_dev.id_addr[0]);
|
||||
}
|
||||
return bt_id_create(NULL, NULL);
|
||||
}
|
||||
|
||||
#if defined(CONFIG_BT_DEBUG)
|
||||
|
@ -4454,17 +4428,14 @@ static int hci_init(void)
|
|||
hci_vs_init();
|
||||
#endif
|
||||
|
||||
if (!bt_addr_le_cmp(&bt_dev.id_addr[0], BT_ADDR_LE_ANY) ||
|
||||
!bt_addr_le_cmp(&bt_dev.id_addr[0], BT_ADDR_LE_NONE)) {
|
||||
if (!IS_ENABLED(CONFIG_BT_SETTINGS) && !bt_dev.id_count) {
|
||||
BT_DBG("No public address. Trying to set static random.");
|
||||
err = setup_id_addr();
|
||||
err = bt_setup_id_addr();
|
||||
if (err) {
|
||||
BT_ERR("Unable to set identity address");
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
if (!IS_ENABLED(CONFIG_BT_SETTINGS)) {
|
||||
bt_dev_show_info();
|
||||
}
|
||||
|
||||
|
@ -4620,6 +4591,12 @@ static int bt_init(void)
|
|||
bt_le_scan_update(false);
|
||||
}
|
||||
|
||||
if (bt_dev.id_count > 0) {
|
||||
atomic_set_bit(bt_dev.flags, BT_DEV_PRESET_ID);
|
||||
} else if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
|
||||
BT_WARN("No ID address. Expecting one to come from storage.");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -4863,7 +4840,8 @@ 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)) {
|
||||
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;
|
||||
}
|
||||
|
@ -4877,20 +4855,22 @@ int bt_id_create(bt_addr_le_t *addr, u8_t *irk)
|
|||
}
|
||||
|
||||
new_id = bt_dev.id_count++;
|
||||
if (new_id == BT_ID_DEFAULT) {
|
||||
if (new_id == BT_ID_DEFAULT &&
|
||||
!atomic_test_bit(bt_dev.flags, BT_DEV_READY)) {
|
||||
atomic_set_bit(bt_dev.flags, BT_DEV_USER_ID_ADDR);
|
||||
}
|
||||
|
||||
if (bt_addr_le_cmp(addr, BT_ADDR_LE_ANY)) {
|
||||
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]);
|
||||
bt_addr_le_copy(addr, &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) ||
|
||||
new_id != BT_ID_DEFAULT) {
|
||||
if (atomic_test_bit(bt_dev.flags, BT_DEV_READY)) {
|
||||
u8_t zero_irk[16] = { 0 };
|
||||
|
||||
if (irk && memcmp(irk, zero_irk, 16)) {
|
||||
|
@ -4903,6 +4883,14 @@ int bt_id_create(bt_addr_le_t *addr, u8_t *irk)
|
|||
}
|
||||
}
|
||||
#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();
|
||||
}
|
||||
|
||||
return new_id;
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@ enum {
|
|||
enum {
|
||||
BT_DEV_ENABLE,
|
||||
BT_DEV_READY,
|
||||
BT_DEV_PRESET_ID,
|
||||
BT_DEV_USER_ID_ADDR,
|
||||
BT_DEV_HAS_PUB_KEY,
|
||||
BT_DEV_PUB_KEY_BUSY,
|
||||
|
@ -58,6 +59,7 @@ enum {
|
|||
|
||||
/* Flags which should not be cleared upon HCI_Reset */
|
||||
#define BT_DEV_PERSISTENT_FLAGS (BIT(BT_DEV_ENABLE) | \
|
||||
BIT(BT_DEV_PRESET_ID) | \
|
||||
BIT(BT_DEV_USER_ID_ADDR))
|
||||
|
||||
struct bt_dev_le {
|
||||
|
@ -193,6 +195,6 @@ struct bt_keys;
|
|||
int bt_id_add(struct bt_keys *keys);
|
||||
int bt_id_del(struct bt_keys *keys);
|
||||
|
||||
int bt_set_static_addr(const bt_addr_le_t *addr);
|
||||
int bt_setup_id_addr(void);
|
||||
|
||||
void bt_dev_show_info(void);
|
||||
|
|
|
@ -108,6 +108,12 @@ static int set(int argc, char **argv, char *val)
|
|||
}
|
||||
|
||||
if (!strcmp(argv[0], "id")) {
|
||||
/* Any previously provided identities supersede flash */
|
||||
if (atomic_test_bit(bt_dev.flags, BT_DEV_PRESET_ID)) {
|
||||
BT_WARN("Ignoring identities stored in flash");
|
||||
return 0;
|
||||
}
|
||||
|
||||
len = sizeof(bt_dev.id_addr);
|
||||
settings_bytes_from_str(val, &bt_dev.id_addr, &len);
|
||||
if (len < sizeof(bt_dev.id_addr[0])) {
|
||||
|
@ -156,25 +162,21 @@ static int set(int argc, char **argv, char *val)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void generate_static_addr(void)
|
||||
#if defined(CONFIG_BT_PRIVACY)
|
||||
#define ID_SIZE_MAX sizeof(bt_dev.irk)
|
||||
#else
|
||||
#define ID_SIZE_MAX sizeof(bt_dev.id_addr)
|
||||
#endif
|
||||
|
||||
#define ID_DATA_LEN(array) (bt_dev.id_count * sizeof(array[0]))
|
||||
|
||||
static void save_id(struct k_work *work)
|
||||
{
|
||||
char buf[BT_SETTINGS_SIZE(sizeof(bt_dev.id_addr))];
|
||||
char buf[BT_SETTINGS_SIZE(ID_SIZE_MAX)];
|
||||
char *str;
|
||||
|
||||
BT_DBG("Generating new static random address");
|
||||
|
||||
if (bt_addr_le_create_static(&bt_dev.id_addr[0])) {
|
||||
BT_ERR("Failed to generate static addr");
|
||||
return;
|
||||
}
|
||||
|
||||
bt_dev.id_count = 1;
|
||||
bt_set_static_addr(&bt_dev.id_addr[0]);
|
||||
|
||||
BT_DBG("New ID Addr: %s", bt_addr_le_str(&bt_dev.id_addr[0]));
|
||||
|
||||
str = settings_str_from_bytes(&bt_dev.id_addr[0],
|
||||
sizeof(bt_dev.id_addr[0]),
|
||||
str = settings_str_from_bytes(&bt_dev.id_addr,
|
||||
ID_DATA_LEN(bt_dev.id_addr),
|
||||
buf, sizeof(buf));
|
||||
if (!str) {
|
||||
BT_ERR("Unable to encode ID Addr as value");
|
||||
|
@ -183,24 +185,10 @@ static void generate_static_addr(void)
|
|||
|
||||
BT_DBG("Saving ID addr as value %s", str);
|
||||
settings_save_one("bt/id", str);
|
||||
}
|
||||
|
||||
#if defined(CONFIG_BT_PRIVACY)
|
||||
static void generate_irk(void)
|
||||
{
|
||||
char buf[BT_SETTINGS_SIZE(sizeof(bt_dev.irk))];
|
||||
char *str;
|
||||
|
||||
BT_DBG("Generating new IRK");
|
||||
|
||||
if (bt_rand(bt_dev.irk, sizeof(bt_dev.irk))) {
|
||||
BT_ERR("Failed to generate IRK");
|
||||
return;
|
||||
}
|
||||
|
||||
BT_DBG("New local IRK: %s", bt_hex(bt_dev.irk, 16));
|
||||
|
||||
str = settings_str_from_bytes(bt_dev.irk, 16, buf, sizeof(buf));
|
||||
str = settings_str_from_bytes(bt_dev.irk, ID_DATA_LEN(bt_dev.irk),
|
||||
buf, sizeof(buf));
|
||||
if (!str) {
|
||||
BT_ERR("Unable to encode IRK as value");
|
||||
return;
|
||||
|
@ -208,8 +196,15 @@ static void generate_irk(void)
|
|||
|
||||
BT_DBG("Saving IRK as value %s", str);
|
||||
settings_save_one("bt/irk", str);
|
||||
#endif
|
||||
}
|
||||
|
||||
K_WORK_DEFINE(save_id_work, save_id);
|
||||
|
||||
void bt_settings_save_id(void)
|
||||
{
|
||||
k_work_submit(&save_id_work);
|
||||
}
|
||||
#endif /* CONFIG_BT_PRIVACY */
|
||||
|
||||
static int commit(void)
|
||||
{
|
||||
|
@ -217,26 +212,20 @@ static int commit(void)
|
|||
|
||||
BT_DBG("");
|
||||
|
||||
if (!bt_addr_le_cmp(&bt_dev.id_addr[0], BT_ADDR_LE_ANY) ||
|
||||
!bt_addr_le_cmp(&bt_dev.id_addr[0], BT_ADDR_LE_NONE)) {
|
||||
generate_static_addr();
|
||||
}
|
||||
|
||||
#if defined(CONFIG_BT_DEVICE_NAME_DYNAMIC)
|
||||
if (bt_dev.name[0] == '\0') {
|
||||
bt_set_name(CONFIG_BT_DEVICE_NAME);
|
||||
}
|
||||
#endif
|
||||
if (!bt_dev.id_count) {
|
||||
int err;
|
||||
|
||||
#if defined(CONFIG_BT_PRIVACY)
|
||||
{
|
||||
u8_t zero[16] = { 0 };
|
||||
|
||||
if (!memcmp(bt_dev.irk, zero, 16)) {
|
||||
generate_irk();
|
||||
err = bt_setup_id_addr();
|
||||
if (err) {
|
||||
BT_ERR("Unable to setup an identity address");
|
||||
return err;
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_BT_PRIVACY */
|
||||
|
||||
for (h = _bt_settings_start; h < _bt_settings_end; h++) {
|
||||
if (h->commit) {
|
||||
|
|
|
@ -31,4 +31,6 @@ void bt_settings_encode_key(char *path, size_t path_size, const char *subsys,
|
|||
bt_addr_le_t *addr, const char *key);
|
||||
int bt_settings_decode_key(char *key, bt_addr_le_t *addr);
|
||||
|
||||
void bt_settings_save_id(void);
|
||||
|
||||
int bt_settings_init(void);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue