Bluetooth: Add infrastructure to handle multiple identities
Make it possible to have multiple identity addresses as an LE peripheral. For central role only the default identity is supported for now. This also extends the flash storage in a backward compatible way. Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
This commit is contained in:
parent
6b8af4f0b2
commit
5708f1e8b1
22 changed files with 340 additions and 168 deletions
|
@ -29,6 +29,14 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/** @def BT_ID_DEFAULT
|
||||||
|
*
|
||||||
|
* Convenience macro for specifying the default identity. This helps
|
||||||
|
* make the code more readable, especially when only one identity is
|
||||||
|
* supported.
|
||||||
|
*/
|
||||||
|
#define BT_ID_DEFAULT 0
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Generic Access Profile
|
* @brief Generic Access Profile
|
||||||
* @defgroup bt_gap Generic Access Profile
|
* @defgroup bt_gap Generic Access Profile
|
||||||
|
@ -161,6 +169,9 @@ enum {
|
||||||
|
|
||||||
/** LE Advertising Parameters. */
|
/** LE Advertising Parameters. */
|
||||||
struct bt_le_adv_param {
|
struct bt_le_adv_param {
|
||||||
|
/** Local identity */
|
||||||
|
u8_t id;
|
||||||
|
|
||||||
/** Bit-field of advertising options */
|
/** Bit-field of advertising options */
|
||||||
u8_t options;
|
u8_t options;
|
||||||
|
|
||||||
|
@ -343,9 +354,10 @@ struct bt_le_oob {
|
||||||
* Address that is valid for CONFIG_BT_RPA_TIMEOUT seconds. This address
|
* Address that is valid for CONFIG_BT_RPA_TIMEOUT seconds. This address
|
||||||
* will be used for advertising, active scanning and connection creation.
|
* will be used for advertising, active scanning and connection creation.
|
||||||
*
|
*
|
||||||
|
* @param id Local identity, in most cases BT_ID_DEFAULT.
|
||||||
* @param oob LE related information
|
* @param oob LE related information
|
||||||
*/
|
*/
|
||||||
int bt_le_oob_get_local(struct bt_le_oob *oob);
|
int bt_le_oob_get_local(u8_t id, struct bt_le_oob *oob);
|
||||||
|
|
||||||
/** @brief BR/EDR discovery result structure */
|
/** @brief BR/EDR discovery result structure */
|
||||||
struct bt_br_discovery_result {
|
struct bt_br_discovery_result {
|
||||||
|
@ -538,12 +550,13 @@ int bt_br_set_connectable(bool enable);
|
||||||
|
|
||||||
/** Clear pairing information.
|
/** Clear pairing information.
|
||||||
*
|
*
|
||||||
|
* @param id Local identity (mostly just BT_ID_DEFAULT).
|
||||||
* @param addr Remote address, NULL or BT_ADDR_LE_ANY to clear all remote
|
* @param addr Remote address, NULL or BT_ADDR_LE_ANY to clear all remote
|
||||||
* devices.
|
* devices.
|
||||||
*
|
*
|
||||||
* @return 0 on success or negative error value on failure.
|
* @return 0 on success or negative error value on failure.
|
||||||
*/
|
*/
|
||||||
int bt_unpair(const bt_addr_le_t *addr);
|
int bt_unpair(u8_t id, const bt_addr_le_t *addr);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
|
|
|
@ -83,13 +83,14 @@ void bt_conn_unref(struct bt_conn *conn);
|
||||||
*
|
*
|
||||||
* Look up an existing connection based on the remote address.
|
* Look up an existing connection based on the remote address.
|
||||||
*
|
*
|
||||||
|
* @param id Local identity (in most cases BT_ID_DEFAULT).
|
||||||
* @param peer Remote address.
|
* @param peer Remote address.
|
||||||
*
|
*
|
||||||
* @return Connection object or NULL if not found. The caller gets a
|
* @return Connection object or NULL if not found. The caller gets a
|
||||||
* new reference to the connection object which must be released with
|
* new reference to the connection object which must be released with
|
||||||
* bt_conn_unref() once done using the object.
|
* bt_conn_unref() once done using the object.
|
||||||
*/
|
*/
|
||||||
struct bt_conn *bt_conn_lookup_addr_le(const bt_addr_le_t *peer);
|
struct bt_conn *bt_conn_lookup_addr_le(u8_t id, const bt_addr_le_t *peer);
|
||||||
|
|
||||||
/** @brief Get destination (peer) address of a connection.
|
/** @brief Get destination (peer) address of a connection.
|
||||||
*
|
*
|
||||||
|
@ -134,6 +135,7 @@ enum {
|
||||||
*
|
*
|
||||||
* @param type Connection Type
|
* @param type Connection Type
|
||||||
* @param role Connection Role
|
* @param role Connection Role
|
||||||
|
* @param id Which local identity the connection was created with
|
||||||
* @param le LE Connection specific Info
|
* @param le LE Connection specific Info
|
||||||
* @param br BR/EDR Connection specific Info
|
* @param br BR/EDR Connection specific Info
|
||||||
*/
|
*/
|
||||||
|
@ -142,6 +144,8 @@ struct bt_conn_info {
|
||||||
|
|
||||||
u8_t role;
|
u8_t role;
|
||||||
|
|
||||||
|
u8_t id;
|
||||||
|
|
||||||
union {
|
union {
|
||||||
struct bt_conn_le_info le;
|
struct bt_conn_le_info le;
|
||||||
|
|
||||||
|
|
|
@ -479,11 +479,13 @@ ssize_t bt_gatt_attr_read_chrc(struct bt_conn *conn,
|
||||||
#define BT_GATT_CCC_MAX (CONFIG_BT_MAX_PAIRED + CONFIG_BT_MAX_CONN)
|
#define BT_GATT_CCC_MAX (CONFIG_BT_MAX_PAIRED + CONFIG_BT_MAX_CONN)
|
||||||
|
|
||||||
/** @brief GATT CCC configuration entry.
|
/** @brief GATT CCC configuration entry.
|
||||||
|
* @param id Local identity, BT_ID_DEFAULT in most cases.
|
||||||
* @param peer Remote peer address
|
* @param peer Remote peer address
|
||||||
* @param value Configuration value.
|
* @param value Configuration value.
|
||||||
* @param data Configuration pointer data.
|
* @param data Configuration pointer data.
|
||||||
*/
|
*/
|
||||||
struct bt_gatt_ccc_cfg {
|
struct bt_gatt_ccc_cfg {
|
||||||
|
u8_t id;
|
||||||
bt_addr_le_t peer;
|
bt_addr_le_t peer;
|
||||||
u16_t value;
|
u16_t value;
|
||||||
u8_t data[4] __aligned(4);
|
u8_t data[4] __aligned(4);
|
||||||
|
|
|
@ -40,6 +40,8 @@ typedef struct {
|
||||||
} bt_addr_le_t;
|
} bt_addr_le_t;
|
||||||
|
|
||||||
#define BT_ADDR_ANY (&(bt_addr_t) { { 0, 0, 0, 0, 0, 0 } })
|
#define BT_ADDR_ANY (&(bt_addr_t) { { 0, 0, 0, 0, 0, 0 } })
|
||||||
|
#define BT_ADDR_NONE (&(bt_addr_t) { \
|
||||||
|
{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff } })
|
||||||
#define BT_ADDR_LE_ANY (&(bt_addr_le_t) { 0, { { 0, 0, 0, 0, 0, 0 } } })
|
#define BT_ADDR_LE_ANY (&(bt_addr_le_t) { 0, { { 0, 0, 0, 0, 0, 0 } } })
|
||||||
#define BT_ADDR_LE_NONE (&(bt_addr_le_t) { 0, \
|
#define BT_ADDR_LE_NONE (&(bt_addr_le_t) { 0, \
|
||||||
{ { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff } } })
|
{ { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff } } })
|
||||||
|
|
|
@ -579,7 +579,7 @@ static void bt_ready(int err)
|
||||||
SYS_LOG_INF("Bluetooth initialized");
|
SYS_LOG_INF("Bluetooth initialized");
|
||||||
|
|
||||||
/* Use identity address as device UUID */
|
/* Use identity address as device UUID */
|
||||||
if (bt_le_oob_get_local(&oob)) {
|
if (bt_le_oob_get_local(BT_ID_DEFAULT, &oob)) {
|
||||||
SYS_LOG_ERR("Identity Address unavailable");
|
SYS_LOG_ERR("Identity Address unavailable");
|
||||||
} else {
|
} else {
|
||||||
memcpy(dev_uuid, oob.addr.a.val, 6);
|
memcpy(dev_uuid, oob.addr.a.val, 6);
|
||||||
|
|
|
@ -63,7 +63,7 @@ void bt_ready(int err)
|
||||||
printk("Bluetooth initialized\n");
|
printk("Bluetooth initialized\n");
|
||||||
|
|
||||||
/* Use identity address as device UUID */
|
/* Use identity address as device UUID */
|
||||||
if (bt_le_oob_get_local(&oob)) {
|
if (bt_le_oob_get_local(BT_ID_DEFAULT, &oob)) {
|
||||||
printk("Identity Address unavailable\n");
|
printk("Identity Address unavailable\n");
|
||||||
} else {
|
} else {
|
||||||
memcpy(dev_uuid, oob.addr.a.val, 6);
|
memcpy(dev_uuid, oob.addr.a.val, 6);
|
||||||
|
|
|
@ -382,6 +382,14 @@ config BT_DEVICE_APPEARANCE
|
||||||
consult the following link:
|
consult the following link:
|
||||||
https://www.bluetooth.com/specifications/assigned-numbers
|
https://www.bluetooth.com/specifications/assigned-numbers
|
||||||
|
|
||||||
|
config BT_ID_MAX
|
||||||
|
int "Maximum number of local identities"
|
||||||
|
range 1 10
|
||||||
|
default 1
|
||||||
|
help
|
||||||
|
Maximum number of supported local identity addresses. For most
|
||||||
|
products this is safe to leave as the default value (1).
|
||||||
|
|
||||||
endif # BT_HCI_HOST
|
endif # BT_HCI_HOST
|
||||||
|
|
||||||
config BT_TINYCRYPT_ECC
|
config BT_TINYCRYPT_ECC
|
||||||
|
|
|
@ -893,9 +893,10 @@ static int start_security(struct bt_conn *conn)
|
||||||
{
|
{
|
||||||
if (!conn->le.keys) {
|
if (!conn->le.keys) {
|
||||||
conn->le.keys = bt_keys_find(BT_KEYS_LTK_P256,
|
conn->le.keys = bt_keys_find(BT_KEYS_LTK_P256,
|
||||||
&conn->le.dst);
|
conn->id, &conn->le.dst);
|
||||||
if (!conn->le.keys) {
|
if (!conn->le.keys) {
|
||||||
conn->le.keys = bt_keys_find(BT_KEYS_LTK,
|
conn->le.keys = bt_keys_find(BT_KEYS_LTK,
|
||||||
|
conn->id,
|
||||||
&conn->le.dst);
|
&conn->le.dst);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1577,7 +1578,7 @@ int bt_conn_addr_le_cmp(const struct bt_conn *conn, const bt_addr_le_t *peer)
|
||||||
return bt_addr_le_cmp(peer, &conn->le.init_addr);
|
return bt_addr_le_cmp(peer, &conn->le.init_addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct bt_conn *bt_conn_lookup_addr_le(const bt_addr_le_t *peer)
|
struct bt_conn *bt_conn_lookup_addr_le(u8_t id, const bt_addr_le_t *peer)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
@ -1590,7 +1591,8 @@ struct bt_conn *bt_conn_lookup_addr_le(const bt_addr_le_t *peer)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!bt_conn_addr_le_cmp(&conns[i], peer)) {
|
if (conns[i].id == id &&
|
||||||
|
!bt_conn_addr_le_cmp(&conns[i], peer)) {
|
||||||
return bt_conn_ref(&conns[i]);
|
return bt_conn_ref(&conns[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1667,6 +1669,7 @@ int bt_conn_get_info(const struct bt_conn *conn, struct bt_conn_info *info)
|
||||||
{
|
{
|
||||||
info->type = conn->type;
|
info->type = conn->type;
|
||||||
info->role = conn->role;
|
info->role = conn->role;
|
||||||
|
info->id = conn->id;
|
||||||
|
|
||||||
switch (conn->type) {
|
switch (conn->type) {
|
||||||
case BT_CONN_TYPE_LE:
|
case BT_CONN_TYPE_LE:
|
||||||
|
@ -1815,7 +1818,7 @@ struct bt_conn *bt_conn_create_le(const bt_addr_le_t *peer,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
conn = bt_conn_lookup_addr_le(peer);
|
conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, peer);
|
||||||
if (conn) {
|
if (conn) {
|
||||||
switch (conn->state) {
|
switch (conn->state) {
|
||||||
case BT_CONN_CONNECT_SCAN:
|
case BT_CONN_CONNECT_SCAN:
|
||||||
|
@ -1835,6 +1838,9 @@ struct bt_conn *bt_conn_create_le(const bt_addr_le_t *peer,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Only default identity supported for now */
|
||||||
|
conn->id = BT_ID_DEFAULT;
|
||||||
|
|
||||||
/* Set initial address - will be updated later if necessary. */
|
/* Set initial address - will be updated later if necessary. */
|
||||||
bt_addr_le_copy(&conn->le.resp_addr, peer);
|
bt_addr_le_copy(&conn->le.resp_addr, peer);
|
||||||
|
|
||||||
|
@ -1856,7 +1862,7 @@ int bt_le_set_auto_conn(bt_addr_le_t *addr,
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
conn = bt_conn_lookup_addr_le(addr);
|
conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, addr);
|
||||||
if (!conn) {
|
if (!conn) {
|
||||||
conn = bt_conn_add_le(addr);
|
conn = bt_conn_add_le(addr);
|
||||||
if (!conn) {
|
if (!conn) {
|
||||||
|
@ -1865,6 +1871,9 @@ int bt_le_set_auto_conn(bt_addr_le_t *addr,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (param) {
|
if (param) {
|
||||||
|
/* Only default identity is supported */
|
||||||
|
conn->id = BT_ID_DEFAULT;
|
||||||
|
|
||||||
bt_conn_set_param_le(conn, param);
|
bt_conn_set_param_le(conn, param);
|
||||||
|
|
||||||
if (!atomic_test_and_set_bit(conn->flags,
|
if (!atomic_test_and_set_bit(conn->flags,
|
||||||
|
@ -2131,6 +2140,8 @@ int bt_conn_init(void)
|
||||||
|
|
||||||
if (atomic_test_bit(conn->flags,
|
if (atomic_test_bit(conn->flags,
|
||||||
BT_CONN_AUTO_CONNECT)) {
|
BT_CONN_AUTO_CONNECT)) {
|
||||||
|
/* Only the default identity is supported */
|
||||||
|
conn->id = BT_ID_DEFAULT;
|
||||||
bt_conn_set_state(conn, BT_CONN_CONNECT_SCAN);
|
bt_conn_set_state(conn, BT_CONN_CONNECT_SCAN);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,6 +88,9 @@ struct bt_conn {
|
||||||
|
|
||||||
ATOMIC_DEFINE(flags, BT_CONN_NUM_FLAGS);
|
ATOMIC_DEFINE(flags, BT_CONN_NUM_FLAGS);
|
||||||
|
|
||||||
|
/* Which local identity address this connection uses */
|
||||||
|
u8_t id;
|
||||||
|
|
||||||
#if defined(CONFIG_BT_SMP) || defined(CONFIG_BT_BREDR)
|
#if defined(CONFIG_BT_SMP) || defined(CONFIG_BT_BREDR)
|
||||||
bt_security_t sec_level;
|
bt_security_t sec_level;
|
||||||
bt_security_t required_sec_level;
|
bt_security_t required_sec_level;
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include <atomic.h>
|
#include <atomic.h>
|
||||||
#include <misc/byteorder.h>
|
#include <misc/byteorder.h>
|
||||||
#include <misc/util.h>
|
#include <misc/util.h>
|
||||||
|
@ -810,20 +811,21 @@ static u8_t notify_cb(const struct bt_gatt_attr *attr, void *user_data)
|
||||||
|
|
||||||
/* Notify all peers configured */
|
/* Notify all peers configured */
|
||||||
for (i = 0; i < ccc->cfg_len; i++) {
|
for (i = 0; i < ccc->cfg_len; i++) {
|
||||||
|
struct bt_gatt_ccc_cfg *cfg = &ccc->cfg[i];
|
||||||
struct bt_conn *conn;
|
struct bt_conn *conn;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
/* Check if config value matches data type since consolidated
|
/* Check if config value matches data type since consolidated
|
||||||
* value may be for a different peer.
|
* value may be for a different peer.
|
||||||
*/
|
*/
|
||||||
if (ccc->cfg[i].value != data->type) {
|
if (cfg->value != data->type) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
conn = bt_conn_lookup_addr_le(&ccc->cfg[i].peer);
|
conn = bt_conn_lookup_addr_le(cfg->id, &cfg->peer);
|
||||||
if (!conn) {
|
if (!conn) {
|
||||||
if (ccc->cfg == sc_ccc_cfg) {
|
if (ccc->cfg == sc_ccc_cfg) {
|
||||||
sc_save(&ccc->cfg[i], data->params);
|
sc_save(cfg, data->params);
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -978,16 +980,19 @@ static u8_t disconnected_cb(const struct bt_gatt_attr *attr, void *user_data)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < ccc->cfg_len; i++) {
|
for (i = 0; i < ccc->cfg_len; i++) {
|
||||||
|
struct bt_gatt_ccc_cfg *cfg = &ccc->cfg[i];
|
||||||
|
|
||||||
/* Ignore configurations with disabled value */
|
/* Ignore configurations with disabled value */
|
||||||
if (!ccc->cfg[i].value) {
|
if (!cfg->value) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bt_conn_addr_le_cmp(conn, &ccc->cfg[i].peer)) {
|
if (conn->id != cfg->id ||
|
||||||
|
bt_conn_addr_le_cmp(conn, &cfg->peer)) {
|
||||||
struct bt_conn *tmp;
|
struct bt_conn *tmp;
|
||||||
|
|
||||||
/* Skip if there is another peer connected */
|
/* Skip if there is another peer connected */
|
||||||
tmp = bt_conn_lookup_addr_le(&ccc->cfg[i].peer);
|
tmp = bt_conn_lookup_addr_le(cfg->id, &cfg->peer);
|
||||||
if (tmp) {
|
if (tmp) {
|
||||||
if (tmp->state == BT_CONN_CONNECTED) {
|
if (tmp->state == BT_CONN_CONNECTED) {
|
||||||
bt_conn_unref(tmp);
|
bt_conn_unref(tmp);
|
||||||
|
@ -998,14 +1003,12 @@ static u8_t disconnected_cb(const struct bt_gatt_attr *attr, void *user_data)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Clear value if not paired */
|
/* Clear value if not paired */
|
||||||
if (!bt_addr_le_is_bonded(&conn->le.dst)) {
|
if (!bt_addr_le_is_bonded(conn->id, &conn->le.dst)) {
|
||||||
bt_addr_le_copy(&ccc->cfg[i].peer,
|
bt_addr_le_copy(&cfg->peer, BT_ADDR_LE_ANY);
|
||||||
BT_ADDR_LE_ANY);
|
cfg->value = 0;
|
||||||
ccc->cfg[i].value = 0;
|
|
||||||
} else {
|
} else {
|
||||||
/* Update address in case it has changed */
|
/* Update address in case it has changed */
|
||||||
bt_addr_le_copy(&ccc->cfg[i].peer,
|
bt_addr_le_copy(&cfg->peer, &conn->le.dst);
|
||||||
&conn->le.dst);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1074,7 +1077,7 @@ static void remove_subscriptions(struct bt_conn *conn)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!bt_addr_le_is_bonded(&conn->le.dst) ||
|
if (!bt_addr_le_is_bonded(conn->id, &conn->le.dst) ||
|
||||||
(params->flags & BT_GATT_SUBSCRIBE_FLAG_VOLATILE)) {
|
(params->flags & BT_GATT_SUBSCRIBE_FLAG_VOLATILE)) {
|
||||||
/* Remove subscription */
|
/* Remove subscription */
|
||||||
params->value = 0;
|
params->value = 0;
|
||||||
|
@ -2172,8 +2175,8 @@ void bt_gatt_disconnected(struct bt_conn *conn)
|
||||||
bt_gatt_foreach_attr(0x0001, 0xffff, disconnected_cb, conn);
|
bt_gatt_foreach_attr(0x0001, 0xffff, disconnected_cb, conn);
|
||||||
|
|
||||||
if (IS_ENABLED(CONFIG_BT_SETTINGS) &&
|
if (IS_ENABLED(CONFIG_BT_SETTINGS) &&
|
||||||
bt_addr_le_is_bonded(&conn->le.dst)) {
|
bt_addr_le_is_bonded(conn->id, &conn->le.dst)) {
|
||||||
bt_gatt_store_ccc(&conn->le.dst);
|
bt_gatt_store_ccc(conn->id, &conn->le.dst);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(CONFIG_BT_GATT_CLIENT)
|
#if defined(CONFIG_BT_GATT_CLIENT)
|
||||||
|
@ -2234,7 +2237,7 @@ static u8_t ccc_save(const struct bt_gatt_attr *attr, void *user_data)
|
||||||
return BT_GATT_ITER_CONTINUE;
|
return BT_GATT_ITER_CONTINUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
int bt_gatt_store_ccc(const bt_addr_le_t *addr)
|
int bt_gatt_store_ccc(u8_t id, const bt_addr_le_t *addr)
|
||||||
{
|
{
|
||||||
struct ccc_save save;
|
struct ccc_save save;
|
||||||
char val[BT_SETTINGS_SIZE(sizeof(save.store))];
|
char val[BT_SETTINGS_SIZE(sizeof(save.store))];
|
||||||
|
@ -2255,8 +2258,16 @@ int bt_gatt_store_ccc(const bt_addr_le_t *addr)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (id) {
|
||||||
|
char id_str[4];
|
||||||
|
|
||||||
|
snprintk(id_str, sizeof(id_str), "%u", id);
|
||||||
|
bt_settings_encode_key(key, sizeof(key), "ccc",
|
||||||
|
(bt_addr_le_t *)addr, id_str);
|
||||||
|
} else {
|
||||||
bt_settings_encode_key(key, sizeof(key), "ccc",
|
bt_settings_encode_key(key, sizeof(key), "ccc",
|
||||||
(bt_addr_le_t *)addr, NULL);
|
(bt_addr_le_t *)addr, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
err = settings_save_one(key, str);
|
err = settings_save_one(key, str);
|
||||||
if (err) {
|
if (err) {
|
||||||
|
@ -2270,12 +2281,20 @@ int bt_gatt_store_ccc(const bt_addr_le_t *addr)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int bt_gatt_clear_ccc(const bt_addr_le_t *addr)
|
int bt_gatt_clear_ccc(u8_t id, const bt_addr_le_t *addr)
|
||||||
{
|
{
|
||||||
char key[BT_SETTINGS_KEY_MAX];
|
char key[BT_SETTINGS_KEY_MAX];
|
||||||
|
|
||||||
|
if (id) {
|
||||||
|
char id_str[4];
|
||||||
|
|
||||||
|
snprintk(id_str, sizeof(id_str), "%u", id);
|
||||||
|
bt_settings_encode_key(key, sizeof(key), "ccc",
|
||||||
|
(bt_addr_le_t *)addr, id_str);
|
||||||
|
} else {
|
||||||
bt_settings_encode_key(key, sizeof(key), "ccc",
|
bt_settings_encode_key(key, sizeof(key), "ccc",
|
||||||
(bt_addr_le_t *)addr, NULL);
|
(bt_addr_le_t *)addr, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
return settings_save_one(key, NULL);
|
return settings_save_one(key, NULL);
|
||||||
}
|
}
|
||||||
|
@ -2295,6 +2314,7 @@ static void ccc_clear(struct _bt_gatt_ccc *ccc, bt_addr_le_t *addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ccc_load {
|
struct ccc_load {
|
||||||
|
u8_t id;
|
||||||
bt_addr_le_t addr;
|
bt_addr_le_t addr;
|
||||||
struct ccc_store *entry;
|
struct ccc_store *entry;
|
||||||
size_t count;
|
size_t count;
|
||||||
|
@ -2363,6 +2383,10 @@ static int ccc_set(int argc, char **argv, char *val)
|
||||||
if (argc < 1) {
|
if (argc < 1) {
|
||||||
BT_ERR("Insufficient number of arguments");
|
BT_ERR("Insufficient number of arguments");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
} else if (argc == 1) {
|
||||||
|
load.id = BT_ID_DEFAULT;
|
||||||
|
} else {
|
||||||
|
load.id = strtol(argv[1], NULL, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
BT_DBG("argv[0] %s val %s", argv[0], val ? val : "(null)");
|
BT_DBG("argv[0] %s val %s", argv[0], val ? val : "(null)");
|
||||||
|
@ -2380,8 +2404,12 @@ static int ccc_set(int argc, char **argv, char *val)
|
||||||
BT_ERR("Failed to decode value (err %d)", err);
|
BT_ERR("Failed to decode value (err %d)", err);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
load.entry = ccc_store;
|
load.entry = ccc_store;
|
||||||
load.count = len / sizeof(*ccc_store);
|
load.count = len / sizeof(*ccc_store);
|
||||||
|
} else {
|
||||||
|
load.entry = NULL;
|
||||||
|
load.count = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bt_gatt_foreach_attr(0x0001, 0xffff, ccc_load, &load);
|
bt_gatt_foreach_attr(0x0001, 0xffff, ccc_load, &load);
|
||||||
|
|
|
@ -12,8 +12,8 @@ void bt_gatt_init(void);
|
||||||
void bt_gatt_connected(struct bt_conn *conn);
|
void bt_gatt_connected(struct bt_conn *conn);
|
||||||
void bt_gatt_disconnected(struct bt_conn *conn);
|
void bt_gatt_disconnected(struct bt_conn *conn);
|
||||||
|
|
||||||
int bt_gatt_store_ccc(const bt_addr_le_t *addr);
|
int bt_gatt_store_ccc(u8_t id, const bt_addr_le_t *addr);
|
||||||
int bt_gatt_clear_ccc(const bt_addr_le_t *addr);
|
int bt_gatt_clear_ccc(u8_t id, const bt_addr_le_t *addr);
|
||||||
|
|
||||||
#if defined(CONFIG_BT_GATT_CLIENT)
|
#if defined(CONFIG_BT_GATT_CLIENT)
|
||||||
void bt_gatt_notification(struct bt_conn *conn, u16_t handle,
|
void bt_gatt_notification(struct bt_conn *conn, u16_t handle,
|
||||||
|
|
|
@ -286,12 +286,12 @@ int bt_hci_cmd_send_sync(u16_t opcode, struct net_buf *buf,
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(CONFIG_BT_OBSERVER) || defined(CONFIG_BT_CONN)
|
#if defined(CONFIG_BT_OBSERVER) || defined(CONFIG_BT_CONN)
|
||||||
static const bt_addr_le_t *find_id_addr(const bt_addr_le_t *addr)
|
static const bt_addr_le_t *find_id_addr(u8_t id, const bt_addr_le_t *addr)
|
||||||
{
|
{
|
||||||
if (IS_ENABLED(CONFIG_BT_SMP)) {
|
if (IS_ENABLED(CONFIG_BT_SMP)) {
|
||||||
struct bt_keys *keys;
|
struct bt_keys *keys;
|
||||||
|
|
||||||
keys = bt_keys_find_irk(addr);
|
keys = bt_keys_find_irk(id, addr);
|
||||||
if (keys) {
|
if (keys) {
|
||||||
BT_DBG("Identity %s matched RPA %s",
|
BT_DBG("Identity %s matched RPA %s",
|
||||||
bt_addr_le_str(&keys->addr),
|
bt_addr_le_str(&keys->addr),
|
||||||
|
@ -365,7 +365,7 @@ static int set_random_address(const bt_addr_t *addr)
|
||||||
|
|
||||||
#if defined(CONFIG_BT_PRIVACY)
|
#if defined(CONFIG_BT_PRIVACY)
|
||||||
/* this function sets new RPA only if current one is no longer valid */
|
/* this function sets new RPA only if current one is no longer valid */
|
||||||
static int le_set_private_addr(void)
|
static int le_set_private_addr(u8_t id)
|
||||||
{
|
{
|
||||||
bt_addr_t rpa;
|
bt_addr_t rpa;
|
||||||
int err;
|
int err;
|
||||||
|
@ -375,7 +375,7 @@ static int le_set_private_addr(void)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = bt_rpa_create(bt_dev.irk, &rpa);
|
err = bt_rpa_create(bt_dev.irk[0], &rpa);
|
||||||
if (!err) {
|
if (!err) {
|
||||||
err = set_random_address(&rpa);
|
err = set_random_address(&rpa);
|
||||||
if (!err) {
|
if (!err) {
|
||||||
|
@ -403,17 +403,17 @@ static void rpa_timeout(struct k_work *work)
|
||||||
if (atomic_test_bit(bt_dev.flags, BT_DEV_ADVERTISING)) {
|
if (atomic_test_bit(bt_dev.flags, BT_DEV_ADVERTISING)) {
|
||||||
/* make sure new address is used */
|
/* make sure new address is used */
|
||||||
set_advertise_enable(false);
|
set_advertise_enable(false);
|
||||||
le_set_private_addr();
|
le_set_private_addr(bt_dev.adv_id);
|
||||||
set_advertise_enable(true);
|
set_advertise_enable(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (atomic_test_bit(bt_dev.flags, BT_DEV_ACTIVE_SCAN)) {
|
if (atomic_test_bit(bt_dev.flags, BT_DEV_ACTIVE_SCAN)) {
|
||||||
/* TODO do we need to toggle scan? */
|
/* TODO do we need to toggle scan? */
|
||||||
le_set_private_addr();
|
le_set_private_addr(BT_ID_DEFAULT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
static int le_set_private_addr(void)
|
static int le_set_private_addr(u8_t id)
|
||||||
{
|
{
|
||||||
bt_addr_t nrpa;
|
bt_addr_t nrpa;
|
||||||
int err;
|
int err;
|
||||||
|
@ -655,7 +655,7 @@ advertise:
|
||||||
!atomic_test_bit(bt_dev.flags, BT_DEV_ADVERTISING)) {
|
!atomic_test_bit(bt_dev.flags, BT_DEV_ADVERTISING)) {
|
||||||
if (IS_ENABLED(CONFIG_BT_PRIVACY) &&
|
if (IS_ENABLED(CONFIG_BT_PRIVACY) &&
|
||||||
!BT_FEAT_LE_PRIVACY(bt_dev.le.features)) {
|
!BT_FEAT_LE_PRIVACY(bt_dev.le.features)) {
|
||||||
le_set_private_addr();
|
le_set_private_addr(bt_dev.adv_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
set_advertise_enable(true);
|
set_advertise_enable(true);
|
||||||
|
@ -856,13 +856,15 @@ static void le_enh_conn_complete(struct bt_hci_evt_le_enh_conn_complete *evt)
|
||||||
* was set during outgoing connection creation.
|
* was set during outgoing connection creation.
|
||||||
*/
|
*/
|
||||||
if (conn->role == BT_HCI_ROLE_SLAVE) {
|
if (conn->role == BT_HCI_ROLE_SLAVE) {
|
||||||
|
conn->id = bt_dev.adv_id;
|
||||||
bt_addr_le_copy(&conn->le.init_addr, &peer_addr);
|
bt_addr_le_copy(&conn->le.init_addr, &peer_addr);
|
||||||
|
|
||||||
if (IS_ENABLED(CONFIG_BT_PRIVACY)) {
|
if (IS_ENABLED(CONFIG_BT_PRIVACY)) {
|
||||||
bt_addr_copy(&conn->le.resp_addr.a, &evt->local_rpa);
|
bt_addr_copy(&conn->le.resp_addr.a, &evt->local_rpa);
|
||||||
conn->le.resp_addr.type = BT_ADDR_LE_RANDOM;
|
conn->le.resp_addr.type = BT_ADDR_LE_RANDOM;
|
||||||
} else {
|
} else {
|
||||||
bt_addr_le_copy(&conn->le.resp_addr, &bt_dev.id_addr);
|
bt_addr_le_copy(&conn->le.resp_addr,
|
||||||
|
&bt_dev.id_addr[conn->id]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if the controller supports, lets advertise for another
|
/* if the controller supports, lets advertise for another
|
||||||
|
@ -873,7 +875,7 @@ static void le_enh_conn_complete(struct bt_hci_evt_le_enh_conn_complete *evt)
|
||||||
if (atomic_test_bit(bt_dev.flags, BT_DEV_KEEP_ADVERTISING) &&
|
if (atomic_test_bit(bt_dev.flags, BT_DEV_KEEP_ADVERTISING) &&
|
||||||
BT_LE_STATES_SLAVE_CONN_ADV(bt_dev.le.states)) {
|
BT_LE_STATES_SLAVE_CONN_ADV(bt_dev.le.states)) {
|
||||||
if (IS_ENABLED(CONFIG_BT_PRIVACY)) {
|
if (IS_ENABLED(CONFIG_BT_PRIVACY)) {
|
||||||
le_set_private_addr();
|
le_set_private_addr(bt_dev.adv_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
set_advertise_enable(true);
|
set_advertise_enable(true);
|
||||||
|
@ -949,7 +951,12 @@ static void le_legacy_conn_complete(struct net_buf *buf)
|
||||||
bt_addr_copy(&enh.local_rpa, BT_ADDR_ANY);
|
bt_addr_copy(&enh.local_rpa, BT_ADDR_ANY);
|
||||||
}
|
}
|
||||||
|
|
||||||
id_addr = find_id_addr(&enh.peer_addr);
|
if (evt->role == BT_HCI_ROLE_SLAVE) {
|
||||||
|
id_addr = find_id_addr(bt_dev.adv_id, &enh.peer_addr);
|
||||||
|
} else {
|
||||||
|
id_addr = find_id_addr(BT_ID_DEFAULT, &enh.peer_addr);
|
||||||
|
}
|
||||||
|
|
||||||
if (id_addr != &enh.peer_addr) {
|
if (id_addr != &enh.peer_addr) {
|
||||||
bt_addr_copy(&enh.peer_rpa, &enh.peer_addr.a);
|
bt_addr_copy(&enh.peer_rpa, &enh.peer_addr.a);
|
||||||
bt_addr_le_copy(&enh.peer_addr, id_addr);
|
bt_addr_le_copy(&enh.peer_addr, id_addr);
|
||||||
|
@ -1219,7 +1226,7 @@ static void check_pending_conn(const bt_addr_le_t *id_addr,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IS_ENABLED(CONFIG_BT_PRIVACY)) {
|
if (IS_ENABLED(CONFIG_BT_PRIVACY)) {
|
||||||
if (le_set_private_addr()) {
|
if (le_set_private_addr(BT_ID_DEFAULT)) {
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1230,10 +1237,10 @@ static void check_pending_conn(const bt_addr_le_t *id_addr,
|
||||||
* NRPA used for active scan could be used for connection.
|
* NRPA used for active scan could be used for connection.
|
||||||
*/
|
*/
|
||||||
if (atomic_test_bit(bt_dev.flags, BT_DEV_ID_STATIC_RANDOM)) {
|
if (atomic_test_bit(bt_dev.flags, BT_DEV_ID_STATIC_RANDOM)) {
|
||||||
set_random_address(&bt_dev.id_addr.a);
|
set_random_address(&bt_dev.id_addr[conn->id].a);
|
||||||
}
|
}
|
||||||
|
|
||||||
bt_addr_le_copy(&conn->le.init_addr, &bt_dev.id_addr);
|
bt_addr_le_copy(&conn->le.init_addr, &bt_dev.id_addr[conn->id]);
|
||||||
}
|
}
|
||||||
|
|
||||||
bt_addr_le_copy(&conn->le.resp_addr, addr);
|
bt_addr_le_copy(&conn->le.resp_addr, addr);
|
||||||
|
@ -1309,15 +1316,19 @@ static int bt_clear_all_pairings(void)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int bt_unpair(const bt_addr_le_t *addr)
|
int bt_unpair(u8_t id, const bt_addr_le_t *addr)
|
||||||
{
|
{
|
||||||
struct bt_conn *conn;
|
struct bt_conn *conn;
|
||||||
|
|
||||||
|
if (id >= CONFIG_BT_ID_MAX) {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
if (!addr || !bt_addr_le_cmp(addr, BT_ADDR_LE_ANY)) {
|
if (!addr || !bt_addr_le_cmp(addr, BT_ADDR_LE_ANY)) {
|
||||||
return bt_clear_all_pairings();
|
return bt_clear_all_pairings();
|
||||||
}
|
}
|
||||||
|
|
||||||
conn = bt_conn_lookup_addr_le(addr);
|
conn = bt_conn_lookup_addr_le(id, addr);
|
||||||
if (conn) {
|
if (conn) {
|
||||||
bt_conn_disconnect(conn, BT_HCI_ERR_REMOTE_USER_TERM_CONN);
|
bt_conn_disconnect(conn, BT_HCI_ERR_REMOTE_USER_TERM_CONN);
|
||||||
bt_conn_unref(conn);
|
bt_conn_unref(conn);
|
||||||
|
@ -1331,14 +1342,14 @@ int bt_unpair(const bt_addr_le_t *addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IS_ENABLED(CONFIG_BT_SMP)) {
|
if (IS_ENABLED(CONFIG_BT_SMP)) {
|
||||||
struct bt_keys *keys = bt_keys_find_addr(addr);
|
struct bt_keys *keys = bt_keys_find_addr(id, addr);
|
||||||
if (keys) {
|
if (keys) {
|
||||||
bt_keys_clear(keys);
|
bt_keys_clear(keys);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
|
if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
|
||||||
bt_gatt_clear_ccc(addr);
|
bt_gatt_clear_ccc(id, addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -2836,10 +2847,11 @@ static void le_ltk_request(struct net_buf *buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!conn->le.keys) {
|
if (!conn->le.keys) {
|
||||||
conn->le.keys = bt_keys_find(BT_KEYS_LTK_P256, &conn->le.dst);
|
conn->le.keys = bt_keys_find(BT_KEYS_LTK_P256, conn->id,
|
||||||
|
&conn->le.dst);
|
||||||
if (!conn->le.keys) {
|
if (!conn->le.keys) {
|
||||||
conn->le.keys = bt_keys_find(BT_KEYS_SLAVE_LTK,
|
conn->le.keys = bt_keys_find(BT_KEYS_SLAVE_LTK,
|
||||||
&conn->le.dst);
|
conn->id, &conn->le.dst);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3038,7 +3050,7 @@ static int start_le_scan(u8_t scan_type, u16_t interval, u16_t window)
|
||||||
set_param.filter_policy = 0x00;
|
set_param.filter_policy = 0x00;
|
||||||
|
|
||||||
if (IS_ENABLED(CONFIG_BT_PRIVACY)) {
|
if (IS_ENABLED(CONFIG_BT_PRIVACY)) {
|
||||||
err = le_set_private_addr();
|
err = le_set_private_addr(BT_ID_DEFAULT);
|
||||||
if (err) {
|
if (err) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
@ -3049,7 +3061,7 @@ static int start_le_scan(u8_t scan_type, u16_t interval, u16_t window)
|
||||||
set_param.addr_type = BT_ADDR_LE_RANDOM;
|
set_param.addr_type = BT_ADDR_LE_RANDOM;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
set_param.addr_type = bt_dev.id_addr.type;
|
set_param.addr_type = bt_dev.id_addr[0].type;
|
||||||
|
|
||||||
/* Use NRPA unless identity has been explicitly requested
|
/* Use NRPA unless identity has been explicitly requested
|
||||||
* (through Kconfig), or if there is no advertising ongoing.
|
* (through Kconfig), or if there is no advertising ongoing.
|
||||||
|
@ -3057,7 +3069,7 @@ static int start_le_scan(u8_t scan_type, u16_t interval, u16_t window)
|
||||||
if (!IS_ENABLED(CONFIG_BT_SCAN_WITH_IDENTITY) &&
|
if (!IS_ENABLED(CONFIG_BT_SCAN_WITH_IDENTITY) &&
|
||||||
scan_type == BT_HCI_LE_SCAN_ACTIVE &&
|
scan_type == BT_HCI_LE_SCAN_ACTIVE &&
|
||||||
!atomic_test_bit(bt_dev.flags, BT_DEV_ADVERTISING)) {
|
!atomic_test_bit(bt_dev.flags, BT_DEV_ADVERTISING)) {
|
||||||
err = le_set_private_addr();
|
err = le_set_private_addr(BT_ID_DEFAULT);
|
||||||
if (err) {
|
if (err) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
@ -3188,7 +3200,9 @@ static void le_adv_report(struct net_buf *buf)
|
||||||
bt_addr_le_copy(&id_addr, &info->addr);
|
bt_addr_le_copy(&id_addr, &info->addr);
|
||||||
id_addr.type -= BT_ADDR_LE_PUBLIC_ID;
|
id_addr.type -= BT_ADDR_LE_PUBLIC_ID;
|
||||||
} else {
|
} else {
|
||||||
bt_addr_le_copy(&id_addr, find_id_addr(&info->addr));
|
bt_addr_le_copy(&id_addr,
|
||||||
|
find_id_addr(bt_dev.adv_id,
|
||||||
|
&info->addr));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (scan_dev_found_cb) {
|
if (scan_dev_found_cb) {
|
||||||
|
@ -3508,8 +3522,15 @@ static void read_bdaddr_complete(struct net_buf *buf)
|
||||||
|
|
||||||
BT_DBG("status %u", rp->status);
|
BT_DBG("status %u", rp->status);
|
||||||
|
|
||||||
bt_addr_copy(&bt_dev.id_addr.a, &rp->bdaddr);
|
if (!bt_addr_cmp(&rp->bdaddr, BT_ADDR_ANY) ||
|
||||||
bt_dev.id_addr.type = BT_ADDR_LE_PUBLIC;
|
!bt_addr_cmp(&rp->bdaddr, BT_ADDR_NONE)) {
|
||||||
|
BT_DBG("Controller has no public address");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bt_addr_copy(&bt_dev.id_addr[0].a, &rp->bdaddr);
|
||||||
|
bt_dev.id_addr[0].type = BT_ADDR_LE_PUBLIC;
|
||||||
|
bt_dev.id_count = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void read_le_features_complete(struct net_buf *buf)
|
static void read_le_features_complete(struct net_buf *buf)
|
||||||
|
@ -4174,13 +4195,13 @@ int bt_set_static_addr(void)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
if (bt_dev.id_addr.type != BT_ADDR_LE_RANDOM ||
|
if (bt_dev.id_addr[0].type != BT_ADDR_LE_RANDOM ||
|
||||||
(bt_dev.id_addr.a.val[5] & 0xc0) != 0xc0) {
|
(bt_dev.id_addr[0].a.val[5] & 0xc0) != 0xc0) {
|
||||||
BT_ERR("Only static random address supported as identity");
|
BT_ERR("Only static random address supported as identity");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = set_random_address(&bt_dev.id_addr.a);
|
err = set_random_address(&bt_dev.id_addr[0].a);
|
||||||
if (err) {
|
if (err) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
@ -4195,10 +4216,14 @@ static int setup_id_addr(void)
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
#if defined(CONFIG_BT_HCI_VS_EXT)
|
#if defined(CONFIG_BT_HCI_VS_EXT)
|
||||||
/* Check for VS_Read_Static_Addresses support */
|
/* Check for VS_Read_Static_Addresses support. Only read the
|
||||||
if (bt_dev.vs_commands[1] & BIT(0)) {
|
* addresses if the user has not already configured one or
|
||||||
|
* more identities (!bt_dev.id_count).
|
||||||
|
*/
|
||||||
|
if (!bt_dev.id_count && (bt_dev.vs_commands[1] & BIT(0))) {
|
||||||
struct bt_hci_rp_vs_read_static_addrs *rp;
|
struct bt_hci_rp_vs_read_static_addrs *rp;
|
||||||
struct net_buf *rsp;
|
struct net_buf *rsp;
|
||||||
|
int i;
|
||||||
|
|
||||||
err = bt_hci_cmd_send_sync(BT_HCI_OP_VS_READ_STATIC_ADDRS,
|
err = bt_hci_cmd_send_sync(BT_HCI_OP_VS_READ_STATIC_ADDRS,
|
||||||
NULL, &rsp);
|
NULL, &rsp);
|
||||||
|
@ -4208,15 +4233,19 @@ static int setup_id_addr(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
rp = (void *)rsp->data;
|
rp = (void *)rsp->data;
|
||||||
if (rp->num_addrs) {
|
bt_dev.id_count = min(rp->num_addrs, CONFIG_BT_ID_MAX);
|
||||||
bt_dev.id_addr.type = BT_ADDR_LE_RANDOM;
|
for (i = 0; i < bt_dev.id_count; i++) {
|
||||||
bt_addr_copy(&bt_dev.id_addr.a, &rp->a[0].bdaddr);
|
bt_dev.id_addr[i].type = BT_ADDR_LE_RANDOM;
|
||||||
|
bt_addr_copy(&bt_dev.id_addr[i].a, &rp->a[i].bdaddr);
|
||||||
|
}
|
||||||
|
|
||||||
net_buf_unref(rsp);
|
net_buf_unref(rsp);
|
||||||
|
|
||||||
|
if (bt_dev.id_count) {
|
||||||
return bt_set_static_addr();
|
return bt_set_static_addr();
|
||||||
}
|
}
|
||||||
|
|
||||||
BT_WARN("No static addresses stored in controller");
|
BT_WARN("No static addresses stored in controller");
|
||||||
net_buf_unref(rsp);
|
|
||||||
} else {
|
} else {
|
||||||
BT_WARN("Read Static Addresses command not available");
|
BT_WARN("Read Static Addresses command not available");
|
||||||
}
|
}
|
||||||
|
@ -4228,13 +4257,14 @@ generate:
|
||||||
BT_DBG("Expecing identity addr to be handled by settings");
|
BT_DBG("Expecing identity addr to be handled by settings");
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
err = bt_addr_le_create_static(&bt_dev.id_addr);
|
err = bt_addr_le_create_static(&bt_dev.id_addr[0]);
|
||||||
if (err) {
|
if (err) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bt_dev.id_count = 1;
|
||||||
BT_WARN("Using temporary static random address %s",
|
BT_WARN("Using temporary static random address %s",
|
||||||
bt_addr_str(&bt_dev.id_addr.a));
|
bt_addr_str(&bt_dev.id_addr[0].a));
|
||||||
|
|
||||||
return bt_set_static_addr();
|
return bt_set_static_addr();
|
||||||
}
|
}
|
||||||
|
@ -4257,7 +4287,16 @@ static const char *ver_str(u8_t ver)
|
||||||
|
|
||||||
void bt_dev_show_info(void)
|
void bt_dev_show_info(void)
|
||||||
{
|
{
|
||||||
BT_INFO("Identity: %s", bt_addr_le_str(&bt_dev.id_addr));
|
int i;
|
||||||
|
|
||||||
|
BT_INFO("Identity%s: %s", bt_dev.id_count > 1 ? "[0]" : "",
|
||||||
|
bt_addr_le_str(&bt_dev.id_addr[0]));
|
||||||
|
|
||||||
|
for (i = 1; i < bt_dev.id_count; i++) {
|
||||||
|
BT_INFO("Identity[%d]: %s",
|
||||||
|
i, bt_addr_le_str(&bt_dev.id_addr[i]));
|
||||||
|
}
|
||||||
|
|
||||||
BT_INFO("HCI: version %s (0x%02x) revision 0x%04x, manufacturer 0x%04x",
|
BT_INFO("HCI: version %s (0x%02x) revision 0x%04x, manufacturer 0x%04x",
|
||||||
ver_str(bt_dev.hci_version), bt_dev.hci_version,
|
ver_str(bt_dev.hci_version), bt_dev.hci_version,
|
||||||
bt_dev.hci_revision, bt_dev.manufacturer);
|
bt_dev.hci_revision, bt_dev.manufacturer);
|
||||||
|
@ -4338,7 +4377,7 @@ static void hci_vs_init(void)
|
||||||
if (IS_ENABLED(CONFIG_BT_HCI_VS_EXT_DETECT) &&
|
if (IS_ENABLED(CONFIG_BT_HCI_VS_EXT_DETECT) &&
|
||||||
(bt_dev.hci_version < BT_HCI_VERSION_5_0 ||
|
(bt_dev.hci_version < BT_HCI_VERSION_5_0 ||
|
||||||
(!atomic_test_bit(bt_dev.flags, BT_DEV_USER_ID_ADDR) &&
|
(!atomic_test_bit(bt_dev.flags, BT_DEV_USER_ID_ADDR) &&
|
||||||
bt_addr_le_cmp(&bt_dev.id_addr, BT_ADDR_LE_ANY)))) {
|
bt_addr_le_cmp(&bt_dev.id_addr[0], BT_ADDR_LE_ANY)))) {
|
||||||
BT_WARN("Controller doesn't seem to support Zephyr vendor HCI");
|
BT_WARN("Controller doesn't seem to support Zephyr vendor HCI");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -4423,8 +4462,8 @@ static int hci_init(void)
|
||||||
hci_vs_init();
|
hci_vs_init();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!bt_addr_le_cmp(&bt_dev.id_addr, BT_ADDR_LE_ANY) ||
|
if (!bt_addr_le_cmp(&bt_dev.id_addr[0], BT_ADDR_LE_ANY) ||
|
||||||
!bt_addr_le_cmp(&bt_dev.id_addr, BT_ADDR_LE_NONE)) {
|
!bt_addr_le_cmp(&bt_dev.id_addr[0], BT_ADDR_LE_NONE)) {
|
||||||
BT_DBG("No public address. Trying to set static random.");
|
BT_DBG("No public address. Trying to set static random.");
|
||||||
err = setup_id_addr();
|
err = setup_id_addr();
|
||||||
if (err) {
|
if (err) {
|
||||||
|
@ -4546,7 +4585,7 @@ static int irk_init(void)
|
||||||
} else {
|
} else {
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
err = bt_rand(bt_dev.irk, sizeof(bt_dev.irk));
|
err = bt_rand(&bt_dev.irk[0], 16);
|
||||||
if (err) {
|
if (err) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
@ -4818,17 +4857,17 @@ int bt_set_id_addr(const bt_addr_le_t *addr)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
bt_addr_le_copy(&bt_dev.id_addr, addr);
|
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_USER_ID_ADDR);
|
||||||
atomic_set_bit(bt_dev.flags, BT_DEV_ID_STATIC_RANDOM);
|
atomic_set_bit(bt_dev.flags, BT_DEV_ID_STATIC_RANDOM);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool bt_addr_le_is_bonded(const bt_addr_le_t *addr)
|
bool bt_addr_le_is_bonded(u8_t id, const bt_addr_le_t *addr)
|
||||||
{
|
{
|
||||||
if (IS_ENABLED(CONFIG_BT_SMP)) {
|
if (IS_ENABLED(CONFIG_BT_SMP)) {
|
||||||
struct bt_keys *keys = bt_keys_find_addr(addr);
|
struct bt_keys *keys = bt_keys_find_addr(id, addr);
|
||||||
|
|
||||||
/* if there are any keys stored then device is bonded */
|
/* if there are any keys stored then device is bonded */
|
||||||
return keys && keys->keys;
|
return keys && keys->keys;
|
||||||
|
@ -4839,6 +4878,10 @@ bool bt_addr_le_is_bonded(const bt_addr_le_t *addr)
|
||||||
|
|
||||||
static bool valid_adv_param(const struct bt_le_adv_param *param)
|
static bool valid_adv_param(const struct bt_le_adv_param *param)
|
||||||
{
|
{
|
||||||
|
if (param->id >= bt_dev.id_count) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (!(param->options & BT_LE_ADV_OPT_CONNECTABLE)) {
|
if (!(param->options & BT_LE_ADV_OPT_CONNECTABLE)) {
|
||||||
/*
|
/*
|
||||||
* BT Core 4.2 [Vol 2, Part E, 7.8.5]
|
* BT Core 4.2 [Vol 2, Part E, 7.8.5]
|
||||||
|
@ -4865,6 +4908,7 @@ int bt_le_adv_start(const struct bt_le_adv_param *param,
|
||||||
const struct bt_data *sd, size_t sd_len)
|
const struct bt_data *sd, size_t sd_len)
|
||||||
{
|
{
|
||||||
struct bt_hci_cp_le_set_adv_param set_param;
|
struct bt_hci_cp_le_set_adv_param set_param;
|
||||||
|
const bt_addr_le_t *id_addr;
|
||||||
struct net_buf *buf;
|
struct net_buf *buf;
|
||||||
struct bt_ad d[2] = {};
|
struct bt_ad d[2] = {};
|
||||||
int err;
|
int err;
|
||||||
|
@ -4933,10 +4977,14 @@ int bt_le_adv_start(const struct bt_le_adv_param *param,
|
||||||
set_param.max_interval = sys_cpu_to_le16(param->interval_max);
|
set_param.max_interval = sys_cpu_to_le16(param->interval_max);
|
||||||
set_param.channel_map = 0x07;
|
set_param.channel_map = 0x07;
|
||||||
|
|
||||||
|
/* Set which local identity address we're advertising with */
|
||||||
|
bt_dev.adv_id = param->id;
|
||||||
|
id_addr = &bt_dev.id_addr[param->id];
|
||||||
|
|
||||||
if (param->options & BT_LE_ADV_OPT_CONNECTABLE) {
|
if (param->options & BT_LE_ADV_OPT_CONNECTABLE) {
|
||||||
if (IS_ENABLED(CONFIG_BT_PRIVACY) &&
|
if (IS_ENABLED(CONFIG_BT_PRIVACY) &&
|
||||||
!(param->options & BT_LE_ADV_OPT_USE_IDENTITY)) {
|
!(param->options & BT_LE_ADV_OPT_USE_IDENTITY)) {
|
||||||
err = le_set_private_addr();
|
err = le_set_private_addr(param->id);
|
||||||
if (err) {
|
if (err) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
@ -4956,10 +5004,10 @@ int bt_le_adv_start(const struct bt_le_adv_param *param,
|
||||||
*/
|
*/
|
||||||
if (atomic_test_bit(bt_dev.flags,
|
if (atomic_test_bit(bt_dev.flags,
|
||||||
BT_DEV_ID_STATIC_RANDOM)) {
|
BT_DEV_ID_STATIC_RANDOM)) {
|
||||||
set_random_address(&bt_dev.id_addr.a);
|
set_random_address(&id_addr->a);
|
||||||
}
|
}
|
||||||
|
|
||||||
set_param.own_addr_type = bt_dev.id_addr.type;
|
set_param.own_addr_type = id_addr->type;
|
||||||
}
|
}
|
||||||
|
|
||||||
set_param.type = BT_LE_ADV_IND;
|
set_param.type = BT_LE_ADV_IND;
|
||||||
|
@ -4967,12 +5015,12 @@ int bt_le_adv_start(const struct bt_le_adv_param *param,
|
||||||
if (param->options & BT_LE_ADV_OPT_USE_IDENTITY) {
|
if (param->options & BT_LE_ADV_OPT_USE_IDENTITY) {
|
||||||
if (atomic_test_bit(bt_dev.flags,
|
if (atomic_test_bit(bt_dev.flags,
|
||||||
BT_DEV_ID_STATIC_RANDOM)) {
|
BT_DEV_ID_STATIC_RANDOM)) {
|
||||||
err = set_random_address(&bt_dev.id_addr.a);
|
err = set_random_address(&id_addr->a);
|
||||||
}
|
}
|
||||||
|
|
||||||
set_param.own_addr_type = bt_dev.id_addr.type;
|
set_param.own_addr_type = id_addr->type;
|
||||||
} else {
|
} else {
|
||||||
err = le_set_private_addr();
|
err = le_set_private_addr(param->id);
|
||||||
set_param.own_addr_type = BT_ADDR_LE_RANDOM;
|
set_param.own_addr_type = BT_ADDR_LE_RANDOM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5037,7 +5085,7 @@ int bt_le_adv_stop(void)
|
||||||
/* If active scan is ongoing set NRPA */
|
/* If active scan is ongoing set NRPA */
|
||||||
if (atomic_test_bit(bt_dev.flags, BT_DEV_SCANNING) &&
|
if (atomic_test_bit(bt_dev.flags, BT_DEV_SCANNING) &&
|
||||||
atomic_test_bit(bt_dev.flags, BT_DEV_ACTIVE_SCAN)) {
|
atomic_test_bit(bt_dev.flags, BT_DEV_ACTIVE_SCAN)) {
|
||||||
le_set_private_addr();
|
le_set_private_addr(bt_dev.adv_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5460,28 +5508,32 @@ int bt_dh_key_gen(const u8_t remote_pk[64], bt_dh_key_cb_t cb)
|
||||||
#if defined(CONFIG_BT_BREDR)
|
#if defined(CONFIG_BT_BREDR)
|
||||||
int bt_br_oob_get_local(struct bt_br_oob *oob)
|
int bt_br_oob_get_local(struct bt_br_oob *oob)
|
||||||
{
|
{
|
||||||
bt_addr_copy(&oob->addr, &bt_dev.id_addr.a);
|
bt_addr_copy(&oob->addr, &bt_dev.id_addr[0].a);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_BT_BREDR */
|
#endif /* CONFIG_BT_BREDR */
|
||||||
|
|
||||||
int bt_le_oob_get_local(struct bt_le_oob *oob)
|
int bt_le_oob_get_local(u8_t id, struct bt_le_oob *oob)
|
||||||
{
|
{
|
||||||
|
if (id >= CONFIG_BT_ID_MAX) {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
if (IS_ENABLED(CONFIG_BT_PRIVACY)) {
|
if (IS_ENABLED(CONFIG_BT_PRIVACY)) {
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
/* Invalidate RPA so a new one is generated */
|
/* Invalidate RPA so a new one is generated */
|
||||||
atomic_clear_bit(bt_dev.flags, BT_DEV_RPA_VALID);
|
atomic_clear_bit(bt_dev.flags, BT_DEV_RPA_VALID);
|
||||||
|
|
||||||
err = le_set_private_addr();
|
err = le_set_private_addr(id);
|
||||||
if (err) {
|
if (err) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
bt_addr_le_copy(&oob->addr, &bt_dev.random_addr);
|
bt_addr_le_copy(&oob->addr, &bt_dev.random_addr);
|
||||||
} else {
|
} else {
|
||||||
bt_addr_le_copy(&oob->addr, &bt_dev.id_addr);
|
bt_addr_le_copy(&oob->addr, &bt_dev.id_addr[id]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -103,8 +103,12 @@ struct bt_dev_br {
|
||||||
|
|
||||||
/* State tracking for the local Bluetooth controller */
|
/* State tracking for the local Bluetooth controller */
|
||||||
struct bt_dev {
|
struct bt_dev {
|
||||||
/* Local Identity Address */
|
/* Local Identity Address(es) */
|
||||||
bt_addr_le_t id_addr;
|
bt_addr_le_t id_addr[CONFIG_BT_ID_MAX];
|
||||||
|
u8_t id_count;
|
||||||
|
|
||||||
|
/* ID Address used for advertising */
|
||||||
|
u8_t adv_id;
|
||||||
|
|
||||||
/* Current local Random Address */
|
/* Current local Random Address */
|
||||||
bt_addr_le_t random_addr;
|
bt_addr_le_t random_addr;
|
||||||
|
@ -159,7 +163,7 @@ struct bt_dev {
|
||||||
|
|
||||||
#if defined(CONFIG_BT_PRIVACY)
|
#if defined(CONFIG_BT_PRIVACY)
|
||||||
/* Local Identity Resolving Key */
|
/* Local Identity Resolving Key */
|
||||||
u8_t irk[16];
|
u8_t irk[CONFIG_BT_ID_MAX][16];
|
||||||
|
|
||||||
/* Work used for RPA rotation */
|
/* Work used for RPA rotation */
|
||||||
struct k_delayed_work rpa_update;
|
struct k_delayed_work rpa_update;
|
||||||
|
@ -180,7 +184,7 @@ bool bt_le_conn_params_valid(const struct bt_le_conn_param *param);
|
||||||
|
|
||||||
int bt_le_scan_update(bool fast_scan);
|
int bt_le_scan_update(bool fast_scan);
|
||||||
|
|
||||||
bool bt_addr_le_is_bonded(const bt_addr_le_t *addr);
|
bool bt_addr_le_is_bonded(u8_t id, const bt_addr_le_t *addr);
|
||||||
|
|
||||||
int bt_send(struct net_buf *buf);
|
int bt_send(struct net_buf *buf);
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
#include <zephyr.h>
|
#include <zephyr.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include <atomic.h>
|
#include <atomic.h>
|
||||||
#include <misc/util.h>
|
#include <misc/util.h>
|
||||||
|
|
||||||
|
@ -28,7 +29,7 @@
|
||||||
|
|
||||||
static struct bt_keys key_pool[CONFIG_BT_MAX_PAIRED];
|
static struct bt_keys key_pool[CONFIG_BT_MAX_PAIRED];
|
||||||
|
|
||||||
struct bt_keys *bt_keys_get_addr(const bt_addr_le_t *addr)
|
struct bt_keys *bt_keys_get_addr(u8_t id, const bt_addr_le_t *addr)
|
||||||
{
|
{
|
||||||
struct bt_keys *keys;
|
struct bt_keys *keys;
|
||||||
int i;
|
int i;
|
||||||
|
@ -38,11 +39,12 @@ struct bt_keys *bt_keys_get_addr(const bt_addr_le_t *addr)
|
||||||
for (i = 0; i < ARRAY_SIZE(key_pool); i++) {
|
for (i = 0; i < ARRAY_SIZE(key_pool); i++) {
|
||||||
keys = &key_pool[i];
|
keys = &key_pool[i];
|
||||||
|
|
||||||
if (!bt_addr_le_cmp(&keys->addr, addr)) {
|
if (keys->id == id && !bt_addr_le_cmp(&keys->addr, addr)) {
|
||||||
return keys;
|
return keys;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!bt_addr_le_cmp(&keys->addr, BT_ADDR_LE_ANY)) {
|
if (!bt_addr_le_cmp(&keys->addr, BT_ADDR_LE_ANY)) {
|
||||||
|
keys->id = id;
|
||||||
bt_addr_le_copy(&keys->addr, addr);
|
bt_addr_le_copy(&keys->addr, addr);
|
||||||
BT_DBG("created %p for %s", keys, bt_addr_le_str(addr));
|
BT_DBG("created %p for %s", keys, bt_addr_le_str(addr));
|
||||||
return keys;
|
return keys;
|
||||||
|
@ -65,14 +67,14 @@ void bt_keys_foreach(int type, void (*func)(struct bt_keys *keys))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct bt_keys *bt_keys_find(int type, const bt_addr_le_t *addr)
|
struct bt_keys *bt_keys_find(int type, u8_t id, const bt_addr_le_t *addr)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
BT_DBG("type %d %s", type, bt_addr_le_str(addr));
|
BT_DBG("type %d %s", type, bt_addr_le_str(addr));
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(key_pool); i++) {
|
for (i = 0; i < ARRAY_SIZE(key_pool); i++) {
|
||||||
if ((key_pool[i].keys & type) &&
|
if ((key_pool[i].keys & type) && key_pool[i].id == id &&
|
||||||
!bt_addr_le_cmp(&key_pool[i].addr, addr)) {
|
!bt_addr_le_cmp(&key_pool[i].addr, addr)) {
|
||||||
return &key_pool[i];
|
return &key_pool[i];
|
||||||
}
|
}
|
||||||
|
@ -81,18 +83,18 @@ struct bt_keys *bt_keys_find(int type, const bt_addr_le_t *addr)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct bt_keys *bt_keys_get_type(int type, const bt_addr_le_t *addr)
|
struct bt_keys *bt_keys_get_type(int type, u8_t id, const bt_addr_le_t *addr)
|
||||||
{
|
{
|
||||||
struct bt_keys *keys;
|
struct bt_keys *keys;
|
||||||
|
|
||||||
BT_DBG("type %d %s", type, bt_addr_le_str(addr));
|
BT_DBG("type %d %s", type, bt_addr_le_str(addr));
|
||||||
|
|
||||||
keys = bt_keys_find(type, addr);
|
keys = bt_keys_find(type, id, addr);
|
||||||
if (keys) {
|
if (keys) {
|
||||||
return keys;
|
return keys;
|
||||||
}
|
}
|
||||||
|
|
||||||
keys = bt_keys_get_addr(addr);
|
keys = bt_keys_get_addr(id, addr);
|
||||||
if (!keys) {
|
if (!keys) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -102,7 +104,7 @@ struct bt_keys *bt_keys_get_type(int type, const bt_addr_le_t *addr)
|
||||||
return keys;
|
return keys;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct bt_keys *bt_keys_find_irk(const bt_addr_le_t *addr)
|
struct bt_keys *bt_keys_find_irk(u8_t id, const bt_addr_le_t *addr)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
@ -117,7 +119,8 @@ struct bt_keys *bt_keys_find_irk(const bt_addr_le_t *addr)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!bt_addr_cmp(&addr->a, &key_pool[i].irk.rpa)) {
|
if (key_pool[i].id == id &&
|
||||||
|
!bt_addr_cmp(&addr->a, &key_pool[i].irk.rpa)) {
|
||||||
BT_DBG("cached RPA %s for %s",
|
BT_DBG("cached RPA %s for %s",
|
||||||
bt_addr_str(&key_pool[i].irk.rpa),
|
bt_addr_str(&key_pool[i].irk.rpa),
|
||||||
bt_addr_le_str(&key_pool[i].addr));
|
bt_addr_le_str(&key_pool[i].addr));
|
||||||
|
@ -130,6 +133,10 @@ struct bt_keys *bt_keys_find_irk(const bt_addr_le_t *addr)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (key_pool[i].id != id) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (bt_rpa_irk_matches(key_pool[i].irk.val, &addr->a)) {
|
if (bt_rpa_irk_matches(key_pool[i].irk.val, &addr->a)) {
|
||||||
BT_DBG("RPA %s matches %s",
|
BT_DBG("RPA %s matches %s",
|
||||||
bt_addr_str(&key_pool[i].irk.rpa),
|
bt_addr_str(&key_pool[i].irk.rpa),
|
||||||
|
@ -146,14 +153,15 @@ struct bt_keys *bt_keys_find_irk(const bt_addr_le_t *addr)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct bt_keys *bt_keys_find_addr(const bt_addr_le_t *addr)
|
struct bt_keys *bt_keys_find_addr(u8_t id, const bt_addr_le_t *addr)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
BT_DBG("%s", bt_addr_le_str(addr));
|
BT_DBG("%s", bt_addr_le_str(addr));
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(key_pool); i++) {
|
for (i = 0; i < ARRAY_SIZE(key_pool); i++) {
|
||||||
if (!bt_addr_le_cmp(&key_pool[i].addr, addr)) {
|
if (key_pool[i].id == id &&
|
||||||
|
!bt_addr_le_cmp(&key_pool[i].addr, addr)) {
|
||||||
return &key_pool[i];
|
return &key_pool[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -178,8 +186,17 @@ void bt_keys_clear(struct bt_keys *keys)
|
||||||
char key[BT_SETTINGS_KEY_MAX];
|
char key[BT_SETTINGS_KEY_MAX];
|
||||||
|
|
||||||
/* Delete stored keys from flash */
|
/* Delete stored keys from flash */
|
||||||
bt_settings_encode_key(key, sizeof(key), "keys", &keys->addr,
|
if (keys->id) {
|
||||||
NULL);
|
char id[4];
|
||||||
|
|
||||||
|
snprintk(id, sizeof(id), "%u", keys->id);
|
||||||
|
bt_settings_encode_key(key, sizeof(key), "keys",
|
||||||
|
&keys->addr, id);
|
||||||
|
} else {
|
||||||
|
bt_settings_encode_key(key, sizeof(key), "keys",
|
||||||
|
&keys->addr, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
BT_DBG("Deleting key %s", key);
|
BT_DBG("Deleting key %s", key);
|
||||||
settings_save_one(key, NULL);
|
settings_save_one(key, NULL);
|
||||||
}
|
}
|
||||||
|
@ -207,7 +224,16 @@ int bt_keys_store(struct bt_keys *keys)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
bt_settings_encode_key(key, sizeof(key), "keys", &keys->addr, NULL);
|
if (keys->id) {
|
||||||
|
char id[4];
|
||||||
|
|
||||||
|
snprintk(id, sizeof(id), "%u", keys->id);
|
||||||
|
bt_settings_encode_key(key, sizeof(key), "keys", &keys->addr,
|
||||||
|
id);
|
||||||
|
} else {
|
||||||
|
bt_settings_encode_key(key, sizeof(key), "keys", &keys->addr,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
|
||||||
err = settings_save_one(key, val);
|
err = settings_save_one(key, val);
|
||||||
if (err) {
|
if (err) {
|
||||||
|
@ -224,6 +250,7 @@ static int keys_set(int argc, char **argv, char *val)
|
||||||
{
|
{
|
||||||
struct bt_keys *keys;
|
struct bt_keys *keys;
|
||||||
bt_addr_le_t addr;
|
bt_addr_le_t addr;
|
||||||
|
u8_t id;
|
||||||
int len, err;
|
int len, err;
|
||||||
|
|
||||||
if (argc < 1) {
|
if (argc < 1) {
|
||||||
|
@ -239,8 +266,14 @@ static int keys_set(int argc, char **argv, char *val)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (argc == 1) {
|
||||||
|
id = BT_ID_DEFAULT;
|
||||||
|
} else {
|
||||||
|
id = strtol(argv[1], NULL, 10);
|
||||||
|
}
|
||||||
|
|
||||||
if (!val) {
|
if (!val) {
|
||||||
keys = bt_keys_find(BT_KEYS_ALL, &addr);
|
keys = bt_keys_find(BT_KEYS_ALL, id, &addr);
|
||||||
if (keys) {
|
if (keys) {
|
||||||
memset(keys, 0, sizeof(*keys));
|
memset(keys, 0, sizeof(*keys));
|
||||||
BT_DBG("Cleared keys for %s", bt_addr_le_str(&addr));
|
BT_DBG("Cleared keys for %s", bt_addr_le_str(&addr));
|
||||||
|
@ -252,7 +285,7 @@ static int keys_set(int argc, char **argv, char *val)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
keys = bt_keys_get_addr(&addr);
|
keys = bt_keys_get_addr(id, &addr);
|
||||||
if (!keys) {
|
if (!keys) {
|
||||||
BT_ERR("Failed to allocate keys for %s", bt_addr_le_str(&addr));
|
BT_ERR("Failed to allocate keys for %s", bt_addr_le_str(&addr));
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
|
@ -43,6 +43,7 @@ struct bt_csrk {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct bt_keys {
|
struct bt_keys {
|
||||||
|
u8_t id;
|
||||||
bt_addr_le_t addr;
|
bt_addr_le_t addr;
|
||||||
u8_t storage_start[0];
|
u8_t storage_start[0];
|
||||||
u8_t enc_size;
|
u8_t enc_size;
|
||||||
|
@ -65,11 +66,11 @@ struct bt_keys {
|
||||||
typedef void (*bt_keys_func_t)(struct bt_keys *keys);
|
typedef void (*bt_keys_func_t)(struct bt_keys *keys);
|
||||||
void bt_keys_foreach(int type, bt_keys_func_t func);
|
void bt_keys_foreach(int type, bt_keys_func_t func);
|
||||||
|
|
||||||
struct bt_keys *bt_keys_get_addr(const bt_addr_le_t *addr);
|
struct bt_keys *bt_keys_get_addr(u8_t id, const bt_addr_le_t *addr);
|
||||||
struct bt_keys *bt_keys_get_type(int type, const bt_addr_le_t *addr);
|
struct bt_keys *bt_keys_get_type(int type, u8_t id, const bt_addr_le_t *addr);
|
||||||
struct bt_keys *bt_keys_find(int type, const bt_addr_le_t *addr);
|
struct bt_keys *bt_keys_find(int type, u8_t id, const bt_addr_le_t *addr);
|
||||||
struct bt_keys *bt_keys_find_irk(const bt_addr_le_t *addr);
|
struct bt_keys *bt_keys_find_irk(u8_t id, const bt_addr_le_t *addr);
|
||||||
struct bt_keys *bt_keys_find_addr(const bt_addr_le_t *addr);
|
struct bt_keys *bt_keys_find_addr(u8_t id, const bt_addr_le_t *addr);
|
||||||
|
|
||||||
void bt_keys_add_type(struct bt_keys *keys, int type);
|
void bt_keys_add_type(struct bt_keys *keys, int type);
|
||||||
void bt_keys_clear(struct bt_keys *keys);
|
void bt_keys_clear(struct bt_keys *keys);
|
||||||
|
|
|
@ -124,6 +124,7 @@ static inline void adv_send(struct net_buf *buf)
|
||||||
param.options = 0;
|
param.options = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
param.id = BT_ID_DEFAULT;
|
||||||
param.interval_min = ADV_SCAN_UNIT(adv_int);
|
param.interval_min = ADV_SCAN_UNIT(adv_int);
|
||||||
param.interval_max = param.interval_min;
|
param.interval_max = param.interval_min;
|
||||||
|
|
||||||
|
|
|
@ -110,12 +110,18 @@ static int set(int argc, char **argv, char *val)
|
||||||
if (!strcmp(argv[0], "id")) {
|
if (!strcmp(argv[0], "id")) {
|
||||||
len = sizeof(bt_dev.id_addr);
|
len = sizeof(bt_dev.id_addr);
|
||||||
settings_bytes_from_str(val, &bt_dev.id_addr, &len);
|
settings_bytes_from_str(val, &bt_dev.id_addr, &len);
|
||||||
if (len != sizeof(bt_dev.id_addr)) {
|
if (len < sizeof(bt_dev.id_addr[0])) {
|
||||||
BT_ERR("Invalid length ID address in storage");
|
BT_ERR("Invalid length ID address in storage");
|
||||||
bt_addr_le_copy(&bt_dev.id_addr, BT_ADDR_LE_ANY);
|
memset(bt_dev.id_addr, 0, sizeof(bt_dev.id_addr));
|
||||||
|
bt_dev.id_count = 0;
|
||||||
} else {
|
} else {
|
||||||
BT_DBG("ID Addr set to %s",
|
int i;
|
||||||
bt_addr_le_str(&bt_dev.id_addr));
|
|
||||||
|
bt_dev.id_count = len / sizeof(bt_dev.id_addr[0]);
|
||||||
|
for (i = 0; i < bt_dev.id_count; i++) {
|
||||||
|
BT_DBG("ID Addr %d %s", i,
|
||||||
|
bt_addr_le_str(&bt_dev.id_addr[i]));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -136,11 +142,11 @@ static int set(int argc, char **argv, char *val)
|
||||||
if (!strcmp(argv[0], "irk")) {
|
if (!strcmp(argv[0], "irk")) {
|
||||||
len = sizeof(bt_dev.irk);
|
len = sizeof(bt_dev.irk);
|
||||||
settings_bytes_from_str(val, bt_dev.irk, &len);
|
settings_bytes_from_str(val, bt_dev.irk, &len);
|
||||||
if (len != sizeof(bt_dev.irk)) {
|
if (len < sizeof(bt_dev.irk[0])) {
|
||||||
BT_ERR("Invalid length IRK in storage");
|
BT_ERR("Invalid length IRK in storage");
|
||||||
memset(bt_dev.irk, 0, sizeof(bt_dev.irk));
|
memset(bt_dev.irk, 0, sizeof(bt_dev.irk));
|
||||||
} else {
|
} else {
|
||||||
BT_DBG("IRK set to %s", bt_hex(bt_dev.irk, 16));
|
BT_DBG("IRK set to %s", bt_hex(bt_dev.irk[0], 16));
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -157,16 +163,18 @@ static void generate_static_addr(void)
|
||||||
|
|
||||||
BT_DBG("Generating new static random address");
|
BT_DBG("Generating new static random address");
|
||||||
|
|
||||||
if (bt_addr_le_create_static(&bt_dev.id_addr)) {
|
if (bt_addr_le_create_static(&bt_dev.id_addr[0])) {
|
||||||
BT_ERR("Failed to generate static addr");
|
BT_ERR("Failed to generate static addr");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bt_dev.id_count = 1;
|
||||||
bt_set_static_addr();
|
bt_set_static_addr();
|
||||||
|
|
||||||
BT_DBG("New ID Addr: %s", bt_addr_le_str(&bt_dev.id_addr));
|
BT_DBG("New ID Addr: %s", bt_addr_le_str(&bt_dev.id_addr[0]));
|
||||||
|
|
||||||
str = settings_str_from_bytes(&bt_dev.id_addr, sizeof(bt_dev.id_addr),
|
str = settings_str_from_bytes(&bt_dev.id_addr[0],
|
||||||
|
sizeof(bt_dev.id_addr[0]),
|
||||||
buf, sizeof(buf));
|
buf, sizeof(buf));
|
||||||
if (!str) {
|
if (!str) {
|
||||||
BT_ERR("Unable to encode ID Addr as value");
|
BT_ERR("Unable to encode ID Addr as value");
|
||||||
|
@ -209,8 +217,8 @@ static int commit(void)
|
||||||
|
|
||||||
BT_DBG("");
|
BT_DBG("");
|
||||||
|
|
||||||
if (!bt_addr_le_cmp(&bt_dev.id_addr, BT_ADDR_LE_ANY) ||
|
if (!bt_addr_le_cmp(&bt_dev.id_addr[0], BT_ADDR_LE_ANY) ||
|
||||||
!bt_addr_le_cmp(&bt_dev.id_addr, BT_ADDR_LE_NONE)) {
|
!bt_addr_le_cmp(&bt_dev.id_addr[0], BT_ADDR_LE_NONE)) {
|
||||||
generate_static_addr();
|
generate_static_addr();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -723,7 +723,7 @@ static void smp_pairing_br_complete(struct bt_smp_br *smp, u8_t status)
|
||||||
*/
|
*/
|
||||||
bt_addr_copy(&addr.a, &conn->br.dst);
|
bt_addr_copy(&addr.a, &conn->br.dst);
|
||||||
addr.type = BT_ADDR_LE_PUBLIC;
|
addr.type = BT_ADDR_LE_PUBLIC;
|
||||||
keys = bt_keys_find_addr(&addr);
|
keys = bt_keys_find_addr(conn->id, &addr);
|
||||||
|
|
||||||
if (status) {
|
if (status) {
|
||||||
if (keys) {
|
if (keys) {
|
||||||
|
@ -832,7 +832,7 @@ static void smp_br_derive_ltk(struct bt_smp_br *smp)
|
||||||
bt_addr_copy(&addr.a, &conn->br.dst);
|
bt_addr_copy(&addr.a, &conn->br.dst);
|
||||||
addr.type = BT_ADDR_LE_PUBLIC;
|
addr.type = BT_ADDR_LE_PUBLIC;
|
||||||
|
|
||||||
keys = bt_keys_get_type(BT_KEYS_LTK_P256, &addr);
|
keys = bt_keys_get_type(BT_KEYS_LTK_P256, conn->id, &addr);
|
||||||
if (!keys) {
|
if (!keys) {
|
||||||
BT_ERR("No keys space for %s", bt_addr_le_str(&addr));
|
BT_ERR("No keys space for %s", bt_addr_le_str(&addr));
|
||||||
return;
|
return;
|
||||||
|
@ -890,7 +890,7 @@ static void smp_br_distribute_keys(struct bt_smp_br *smp)
|
||||||
bt_addr_copy(&addr.a, &conn->br.dst);
|
bt_addr_copy(&addr.a, &conn->br.dst);
|
||||||
addr.type = BT_ADDR_LE_PUBLIC;
|
addr.type = BT_ADDR_LE_PUBLIC;
|
||||||
|
|
||||||
keys = bt_keys_get_addr(&addr);
|
keys = bt_keys_get_addr(conn->id, &addr);
|
||||||
if (!keys) {
|
if (!keys) {
|
||||||
BT_ERR("No keys space for %s", bt_addr_le_str(&addr));
|
BT_ERR("No keys space for %s", bt_addr_le_str(&addr));
|
||||||
return;
|
return;
|
||||||
|
@ -924,7 +924,7 @@ static void smp_br_distribute_keys(struct bt_smp_br *smp)
|
||||||
}
|
}
|
||||||
|
|
||||||
id_addr_info = net_buf_add(buf, sizeof(*id_addr_info));
|
id_addr_info = net_buf_add(buf, sizeof(*id_addr_info));
|
||||||
bt_addr_le_copy(&id_addr_info->addr, &bt_dev.id_addr);
|
bt_addr_le_copy(&id_addr_info->addr, &bt_dev.id_addr[conn->id]);
|
||||||
|
|
||||||
smp_br_send(smp, buf, id_sent);
|
smp_br_send(smp, buf, id_sent);
|
||||||
}
|
}
|
||||||
|
@ -1144,7 +1144,7 @@ static u8_t smp_br_ident_info(struct bt_smp_br *smp, struct net_buf *buf)
|
||||||
bt_addr_copy(&addr.a, &conn->br.dst);
|
bt_addr_copy(&addr.a, &conn->br.dst);
|
||||||
addr.type = BT_ADDR_LE_PUBLIC;
|
addr.type = BT_ADDR_LE_PUBLIC;
|
||||||
|
|
||||||
keys = bt_keys_get_type(BT_KEYS_IRK, &addr);
|
keys = bt_keys_get_type(BT_KEYS_IRK, conn->id, &addr);
|
||||||
if (!keys) {
|
if (!keys) {
|
||||||
BT_ERR("Unable to get keys for %s", bt_addr_le_str(&addr));
|
BT_ERR("Unable to get keys for %s", bt_addr_le_str(&addr));
|
||||||
return BT_SMP_ERR_UNSPECIFIED;
|
return BT_SMP_ERR_UNSPECIFIED;
|
||||||
|
@ -1214,7 +1214,7 @@ static u8_t smp_br_signing_info(struct bt_smp_br *smp, struct net_buf *buf)
|
||||||
bt_addr_copy(&addr.a, &conn->br.dst);
|
bt_addr_copy(&addr.a, &conn->br.dst);
|
||||||
addr.type = BT_ADDR_LE_PUBLIC;
|
addr.type = BT_ADDR_LE_PUBLIC;
|
||||||
|
|
||||||
keys = bt_keys_get_type(BT_KEYS_REMOTE_CSRK, &addr);
|
keys = bt_keys_get_type(BT_KEYS_REMOTE_CSRK, conn->id, &addr);
|
||||||
if (!keys) {
|
if (!keys) {
|
||||||
BT_ERR("Unable to get keys for %s", bt_addr_le_str(&addr));
|
BT_ERR("Unable to get keys for %s", bt_addr_le_str(&addr));
|
||||||
return BT_SMP_ERR_UNSPECIFIED;
|
return BT_SMP_ERR_UNSPECIFIED;
|
||||||
|
@ -1808,7 +1808,7 @@ static void bt_smp_distribute_keys(struct bt_smp *smp)
|
||||||
}
|
}
|
||||||
|
|
||||||
id_addr_info = net_buf_add(buf, sizeof(*id_addr_info));
|
id_addr_info = net_buf_add(buf, sizeof(*id_addr_info));
|
||||||
bt_addr_le_copy(&id_addr_info->addr, &bt_dev.id_addr);
|
bt_addr_le_copy(&id_addr_info->addr, &bt_dev.id_addr[conn->id]);
|
||||||
|
|
||||||
smp_send(smp, buf, id_sent);
|
smp_send(smp, buf, id_sent);
|
||||||
}
|
}
|
||||||
|
@ -1924,7 +1924,7 @@ static u8_t legacy_request_tk(struct bt_smp *smp)
|
||||||
* distributed in new pairing. This is to avoid replacing authenticated
|
* distributed in new pairing. This is to avoid replacing authenticated
|
||||||
* keys with unauthenticated ones.
|
* keys with unauthenticated ones.
|
||||||
*/
|
*/
|
||||||
keys = bt_keys_find_addr(&conn->le.dst);
|
keys = bt_keys_find_addr(conn->id, &conn->le.dst);
|
||||||
if (keys && (keys->flags & BT_KEYS_AUTHENTICATED) &&
|
if (keys && (keys->flags & BT_KEYS_AUTHENTICATED) &&
|
||||||
smp->method == JUST_WORKS) {
|
smp->method == JUST_WORKS) {
|
||||||
BT_ERR("JustWorks failed, authenticated keys present");
|
BT_ERR("JustWorks failed, authenticated keys present");
|
||||||
|
@ -2141,7 +2141,7 @@ static u8_t smp_encrypt_info(struct bt_smp *smp, struct net_buf *buf)
|
||||||
struct bt_conn *conn = smp->chan.chan.conn;
|
struct bt_conn *conn = smp->chan.chan.conn;
|
||||||
struct bt_keys *keys;
|
struct bt_keys *keys;
|
||||||
|
|
||||||
keys = bt_keys_get_type(BT_KEYS_LTK, &conn->le.dst);
|
keys = bt_keys_get_type(BT_KEYS_LTK, conn->id, &conn->le.dst);
|
||||||
if (!keys) {
|
if (!keys) {
|
||||||
BT_ERR("Unable to get keys for %s",
|
BT_ERR("Unable to get keys for %s",
|
||||||
bt_addr_le_str(&conn->le.dst));
|
bt_addr_le_str(&conn->le.dst));
|
||||||
|
@ -2166,7 +2166,7 @@ static u8_t smp_master_ident(struct bt_smp *smp, struct net_buf *buf)
|
||||||
struct bt_smp_master_ident *req = (void *)buf->data;
|
struct bt_smp_master_ident *req = (void *)buf->data;
|
||||||
struct bt_keys *keys;
|
struct bt_keys *keys;
|
||||||
|
|
||||||
keys = bt_keys_get_type(BT_KEYS_LTK, &conn->le.dst);
|
keys = bt_keys_get_type(BT_KEYS_LTK, conn->id, &conn->le.dst);
|
||||||
if (!keys) {
|
if (!keys) {
|
||||||
BT_ERR("Unable to get keys for %s",
|
BT_ERR("Unable to get keys for %s",
|
||||||
bt_addr_le_str(&conn->le.dst));
|
bt_addr_le_str(&conn->le.dst));
|
||||||
|
@ -3028,7 +3028,7 @@ static u8_t smp_ident_info(struct bt_smp *smp, struct net_buf *buf)
|
||||||
struct bt_conn *conn = smp->chan.chan.conn;
|
struct bt_conn *conn = smp->chan.chan.conn;
|
||||||
struct bt_keys *keys;
|
struct bt_keys *keys;
|
||||||
|
|
||||||
keys = bt_keys_get_type(BT_KEYS_IRK, &conn->le.dst);
|
keys = bt_keys_get_type(BT_KEYS_IRK, conn->id, &conn->le.dst);
|
||||||
if (!keys) {
|
if (!keys) {
|
||||||
BT_ERR("Unable to get keys for %s",
|
BT_ERR("Unable to get keys for %s",
|
||||||
bt_addr_le_str(&conn->le.dst));
|
bt_addr_le_str(&conn->le.dst));
|
||||||
|
@ -3060,7 +3060,7 @@ static u8_t smp_ident_addr_info(struct bt_smp *smp, struct net_buf *buf)
|
||||||
const bt_addr_le_t *dst;
|
const bt_addr_le_t *dst;
|
||||||
struct bt_keys *keys;
|
struct bt_keys *keys;
|
||||||
|
|
||||||
keys = bt_keys_get_type(BT_KEYS_IRK, &conn->le.dst);
|
keys = bt_keys_get_type(BT_KEYS_IRK, conn->id, &conn->le.dst);
|
||||||
if (!keys) {
|
if (!keys) {
|
||||||
BT_ERR("Unable to get keys for %s",
|
BT_ERR("Unable to get keys for %s",
|
||||||
bt_addr_le_str(&conn->le.dst));
|
bt_addr_le_str(&conn->le.dst));
|
||||||
|
@ -3130,7 +3130,8 @@ static u8_t smp_signing_info(struct bt_smp *smp, struct net_buf *buf)
|
||||||
struct bt_smp_signing_info *req = (void *)buf->data;
|
struct bt_smp_signing_info *req = (void *)buf->data;
|
||||||
struct bt_keys *keys;
|
struct bt_keys *keys;
|
||||||
|
|
||||||
keys = bt_keys_get_type(BT_KEYS_REMOTE_CSRK, &conn->le.dst);
|
keys = bt_keys_get_type(BT_KEYS_REMOTE_CSRK, conn->id,
|
||||||
|
&conn->le.dst);
|
||||||
if (!keys) {
|
if (!keys) {
|
||||||
BT_ERR("Unable to get keys for %s",
|
BT_ERR("Unable to get keys for %s",
|
||||||
bt_addr_le_str(&conn->le.dst));
|
bt_addr_le_str(&conn->le.dst));
|
||||||
|
@ -3183,9 +3184,10 @@ static u8_t smp_security_request(struct bt_smp *smp, struct net_buf *buf)
|
||||||
goto pair;
|
goto pair;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
conn->le.keys = bt_keys_find(BT_KEYS_LTK_P256, &conn->le.dst);
|
conn->le.keys = bt_keys_find(BT_KEYS_LTK_P256, conn->id,
|
||||||
|
&conn->le.dst);
|
||||||
if (!conn->le.keys) {
|
if (!conn->le.keys) {
|
||||||
conn->le.keys = bt_keys_find(BT_KEYS_LTK,
|
conn->le.keys = bt_keys_find(BT_KEYS_LTK, conn->id,
|
||||||
&conn->le.dst);
|
&conn->le.dst);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3725,7 +3727,7 @@ int bt_smp_sign_verify(struct bt_conn *conn, struct net_buf *buf)
|
||||||
/* Store signature incl. count */
|
/* Store signature incl. count */
|
||||||
memcpy(sig, net_buf_tail(buf) - sizeof(sig), sizeof(sig));
|
memcpy(sig, net_buf_tail(buf) - sizeof(sig), sizeof(sig));
|
||||||
|
|
||||||
keys = bt_keys_find(BT_KEYS_REMOTE_CSRK, &conn->le.dst);
|
keys = bt_keys_find(BT_KEYS_REMOTE_CSRK, conn->id, &conn->le.dst);
|
||||||
if (!keys) {
|
if (!keys) {
|
||||||
BT_ERR("Unable to find Remote CSRK for %s",
|
BT_ERR("Unable to find Remote CSRK for %s",
|
||||||
bt_addr_le_str(&conn->le.dst));
|
bt_addr_le_str(&conn->le.dst));
|
||||||
|
@ -3764,7 +3766,7 @@ int bt_smp_sign(struct bt_conn *conn, struct net_buf *buf)
|
||||||
u32_t cnt;
|
u32_t cnt;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
keys = bt_keys_find(BT_KEYS_LOCAL_CSRK, &conn->le.dst);
|
keys = bt_keys_find(BT_KEYS_LOCAL_CSRK, conn->id, &conn->le.dst);
|
||||||
if (!keys) {
|
if (!keys) {
|
||||||
BT_ERR("Unable to find local CSRK for %s",
|
BT_ERR("Unable to find local CSRK for %s",
|
||||||
bt_addr_le_str(&conn->le.dst));
|
bt_addr_le_str(&conn->le.dst));
|
||||||
|
@ -4420,7 +4422,7 @@ void bt_smp_update_keys(struct bt_conn *conn)
|
||||||
bt_keys_clear(conn->le.keys);
|
bt_keys_clear(conn->le.keys);
|
||||||
}
|
}
|
||||||
|
|
||||||
conn->le.keys = bt_keys_get_addr(&conn->le.dst);
|
conn->le.keys = bt_keys_get_addr(conn->id, &conn->le.dst);
|
||||||
if (!conn->le.keys) {
|
if (!conn->le.keys) {
|
||||||
BT_ERR("Unable to get keys for %s",
|
BT_ERR("Unable to get keys for %s",
|
||||||
bt_addr_le_str(&conn->le.dst));
|
bt_addr_le_str(&conn->le.dst));
|
||||||
|
|
|
@ -823,7 +823,7 @@ static int cmd_disconnect(int argc, char *argv[])
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
conn = bt_conn_lookup_addr_le(&addr);
|
conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!conn) {
|
if (!conn) {
|
||||||
|
@ -885,7 +885,7 @@ static int cmd_select(int argc, char *argv[])
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
conn = bt_conn_lookup_addr_le(&addr);
|
conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &addr);
|
||||||
if (!conn) {
|
if (!conn) {
|
||||||
printk("No matching connection found\n");
|
printk("No matching connection found\n");
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -930,7 +930,7 @@ static int cmd_oob(int argc, char *argv[])
|
||||||
struct bt_le_oob oob;
|
struct bt_le_oob oob;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
err = bt_le_oob_get_local(&oob);
|
err = bt_le_oob_get_local(BT_ID_DEFAULT, &oob);
|
||||||
if (err) {
|
if (err) {
|
||||||
printk("OOB data failed\n");
|
printk("OOB data failed\n");
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -955,7 +955,7 @@ static int cmd_clear(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(argv[1], "all") == 0) {
|
if (strcmp(argv[1], "all") == 0) {
|
||||||
err = bt_unpair(NULL);
|
err = bt_unpair(BT_ID_DEFAULT, NULL);
|
||||||
if (err) {
|
if (err) {
|
||||||
printk("Failed to clear pairings (err %d)\n", err);
|
printk("Failed to clear pairings (err %d)\n", err);
|
||||||
} else {
|
} else {
|
||||||
|
@ -982,7 +982,7 @@ static int cmd_clear(int argc, char *argv[])
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = bt_unpair(&addr);
|
err = bt_unpair(BT_ID_DEFAULT, &addr);
|
||||||
if (err) {
|
if (err) {
|
||||||
printk("Failed to clear pairing (err %d)\n", err);
|
printk("Failed to clear pairing (err %d)\n", err);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -126,7 +126,7 @@ static void controller_info(u8_t *data, u16_t len)
|
||||||
|
|
||||||
memset(&rp, 0, sizeof(rp));
|
memset(&rp, 0, sizeof(rp));
|
||||||
|
|
||||||
bt_le_oob_get_local(&oob);
|
bt_le_oob_get_local(BT_ID_DEFAULT, &oob);
|
||||||
memcpy(rp.address, &oob.addr.a, sizeof(bt_addr_t));
|
memcpy(rp.address, &oob.addr.a, sizeof(bt_addr_t));
|
||||||
/*
|
/*
|
||||||
* If privacy is used, the device uses random type address, otherwise
|
* If privacy is used, the device uses random type address, otherwise
|
||||||
|
@ -465,7 +465,7 @@ static void disconnect(const u8_t *data, u16_t len)
|
||||||
struct bt_conn *conn;
|
struct bt_conn *conn;
|
||||||
u8_t status;
|
u8_t status;
|
||||||
|
|
||||||
conn = bt_conn_lookup_addr_le((bt_addr_le_t *) data);
|
conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, (bt_addr_le_t *)data);
|
||||||
if (!conn) {
|
if (!conn) {
|
||||||
status = BTP_STATUS_FAILED;
|
status = BTP_STATUS_FAILED;
|
||||||
goto rsp;
|
goto rsp;
|
||||||
|
@ -563,7 +563,7 @@ static void pair(const u8_t *data, u16_t len)
|
||||||
struct bt_conn *conn;
|
struct bt_conn *conn;
|
||||||
u8_t status;
|
u8_t status;
|
||||||
|
|
||||||
conn = bt_conn_lookup_addr_le((bt_addr_le_t *) data);
|
conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, (bt_addr_le_t *)data);
|
||||||
if (!conn) {
|
if (!conn) {
|
||||||
status = BTP_STATUS_FAILED;
|
status = BTP_STATUS_FAILED;
|
||||||
goto rsp;
|
goto rsp;
|
||||||
|
@ -593,7 +593,7 @@ static void unpair(const u8_t *data, u16_t len)
|
||||||
addr.type = cmd->address_type;
|
addr.type = cmd->address_type;
|
||||||
memcpy(addr.a.val, cmd->address, sizeof(addr.a.val));
|
memcpy(addr.a.val, cmd->address, sizeof(addr.a.val));
|
||||||
|
|
||||||
conn = bt_conn_lookup_addr_le(&addr);
|
conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &addr);
|
||||||
if (!conn) {
|
if (!conn) {
|
||||||
goto keys;
|
goto keys;
|
||||||
}
|
}
|
||||||
|
@ -620,7 +620,7 @@ static void passkey_entry(const u8_t *data, u16_t len)
|
||||||
struct bt_conn *conn;
|
struct bt_conn *conn;
|
||||||
u8_t status;
|
u8_t status;
|
||||||
|
|
||||||
conn = bt_conn_lookup_addr_le((bt_addr_le_t *) data);
|
conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, (bt_addr_le_t *)data);
|
||||||
if (!conn) {
|
if (!conn) {
|
||||||
status = BTP_STATUS_FAILED;
|
status = BTP_STATUS_FAILED;
|
||||||
goto rsp;
|
goto rsp;
|
||||||
|
|
|
@ -884,7 +884,7 @@ static void exchange_mtu(u8_t *data, u16_t len)
|
||||||
{
|
{
|
||||||
struct bt_conn *conn;
|
struct bt_conn *conn;
|
||||||
|
|
||||||
conn = bt_conn_lookup_addr_le((bt_addr_le_t *) data);
|
conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, (bt_addr_le_t *)data);
|
||||||
if (!conn) {
|
if (!conn) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
@ -966,7 +966,7 @@ static void disc_prim_uuid(u8_t *data, u16_t len)
|
||||||
const struct gatt_disc_prim_uuid_cmd *cmd = (void *) data;
|
const struct gatt_disc_prim_uuid_cmd *cmd = (void *) data;
|
||||||
struct bt_conn *conn;
|
struct bt_conn *conn;
|
||||||
|
|
||||||
conn = bt_conn_lookup_addr_le((bt_addr_le_t *) data);
|
conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, (bt_addr_le_t *)data);
|
||||||
if (!conn) {
|
if (!conn) {
|
||||||
goto fail_conn;
|
goto fail_conn;
|
||||||
}
|
}
|
||||||
|
@ -1054,7 +1054,7 @@ static void find_included(u8_t *data, u16_t len)
|
||||||
const struct gatt_find_included_cmd *cmd = (void *) data;
|
const struct gatt_find_included_cmd *cmd = (void *) data;
|
||||||
struct bt_conn *conn;
|
struct bt_conn *conn;
|
||||||
|
|
||||||
conn = bt_conn_lookup_addr_le((bt_addr_le_t *) data);
|
conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, (bt_addr_le_t *)data);
|
||||||
if (!conn) {
|
if (!conn) {
|
||||||
goto fail_conn;
|
goto fail_conn;
|
||||||
}
|
}
|
||||||
|
@ -1136,7 +1136,7 @@ static void disc_all_chrc(u8_t *data, u16_t len)
|
||||||
const struct gatt_disc_all_chrc_cmd *cmd = (void *) data;
|
const struct gatt_disc_all_chrc_cmd *cmd = (void *) data;
|
||||||
struct bt_conn *conn;
|
struct bt_conn *conn;
|
||||||
|
|
||||||
conn = bt_conn_lookup_addr_le((bt_addr_le_t *) data);
|
conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, (bt_addr_le_t *)data);
|
||||||
if (!conn) {
|
if (!conn) {
|
||||||
goto fail_conn;
|
goto fail_conn;
|
||||||
}
|
}
|
||||||
|
@ -1175,7 +1175,7 @@ static void disc_chrc_uuid(u8_t *data, u16_t len)
|
||||||
const struct gatt_disc_chrc_uuid_cmd *cmd = (void *) data;
|
const struct gatt_disc_chrc_uuid_cmd *cmd = (void *) data;
|
||||||
struct bt_conn *conn;
|
struct bt_conn *conn;
|
||||||
|
|
||||||
conn = bt_conn_lookup_addr_le((bt_addr_le_t *) data);
|
conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, (bt_addr_le_t *)data);
|
||||||
if (!conn) {
|
if (!conn) {
|
||||||
goto fail_conn;
|
goto fail_conn;
|
||||||
}
|
}
|
||||||
|
@ -1261,7 +1261,7 @@ static void disc_all_desc(u8_t *data, u16_t len)
|
||||||
const struct gatt_disc_all_desc_cmd *cmd = (void *) data;
|
const struct gatt_disc_all_desc_cmd *cmd = (void *) data;
|
||||||
struct bt_conn *conn;
|
struct bt_conn *conn;
|
||||||
|
|
||||||
conn = bt_conn_lookup_addr_le((bt_addr_le_t *) data);
|
conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, (bt_addr_le_t *)data);
|
||||||
if (!conn) {
|
if (!conn) {
|
||||||
goto fail_conn;
|
goto fail_conn;
|
||||||
}
|
}
|
||||||
|
@ -1336,7 +1336,7 @@ static void read(u8_t *data, u16_t len)
|
||||||
const struct gatt_read_cmd *cmd = (void *) data;
|
const struct gatt_read_cmd *cmd = (void *) data;
|
||||||
struct bt_conn *conn;
|
struct bt_conn *conn;
|
||||||
|
|
||||||
conn = bt_conn_lookup_addr_le((bt_addr_le_t *) data);
|
conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, (bt_addr_le_t *)data);
|
||||||
if (!conn) {
|
if (!conn) {
|
||||||
goto fail_conn;
|
goto fail_conn;
|
||||||
}
|
}
|
||||||
|
@ -1375,7 +1375,7 @@ static void read_long(u8_t *data, u16_t len)
|
||||||
const struct gatt_read_long_cmd *cmd = (void *) data;
|
const struct gatt_read_long_cmd *cmd = (void *) data;
|
||||||
struct bt_conn *conn;
|
struct bt_conn *conn;
|
||||||
|
|
||||||
conn = bt_conn_lookup_addr_le((bt_addr_le_t *) data);
|
conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, (bt_addr_le_t *)data);
|
||||||
if (!conn) {
|
if (!conn) {
|
||||||
goto fail_conn;
|
goto fail_conn;
|
||||||
}
|
}
|
||||||
|
@ -1420,7 +1420,7 @@ static void read_multiple(u8_t *data, u16_t len)
|
||||||
handles[i] = sys_le16_to_cpu(cmd->handles[i]);
|
handles[i] = sys_le16_to_cpu(cmd->handles[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
conn = bt_conn_lookup_addr_le((bt_addr_le_t *) data);
|
conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, (bt_addr_le_t *)data);
|
||||||
if (!conn) {
|
if (!conn) {
|
||||||
goto fail_conn;
|
goto fail_conn;
|
||||||
}
|
}
|
||||||
|
@ -1459,7 +1459,7 @@ static void write_without_rsp(u8_t *data, u16_t len, u8_t op,
|
||||||
struct bt_conn *conn;
|
struct bt_conn *conn;
|
||||||
u8_t status = BTP_STATUS_SUCCESS;
|
u8_t status = BTP_STATUS_SUCCESS;
|
||||||
|
|
||||||
conn = bt_conn_lookup_addr_le((bt_addr_le_t *) data);
|
conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, (bt_addr_le_t *)data);
|
||||||
if (!conn) {
|
if (!conn) {
|
||||||
status = BTP_STATUS_FAILED;
|
status = BTP_STATUS_FAILED;
|
||||||
goto rsp;
|
goto rsp;
|
||||||
|
@ -1491,7 +1491,7 @@ static void write(u8_t *data, u16_t len)
|
||||||
const struct gatt_write_cmd *cmd = (void *) data;
|
const struct gatt_write_cmd *cmd = (void *) data;
|
||||||
struct bt_conn *conn;
|
struct bt_conn *conn;
|
||||||
|
|
||||||
conn = bt_conn_lookup_addr_le((bt_addr_le_t *) data);
|
conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, (bt_addr_le_t *)data);
|
||||||
if (!conn) {
|
if (!conn) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
@ -1527,7 +1527,7 @@ static void write_long(u8_t *data, u16_t len)
|
||||||
const struct gatt_write_long_cmd *cmd = (void *) data;
|
const struct gatt_write_long_cmd *cmd = (void *) data;
|
||||||
struct bt_conn *conn;
|
struct bt_conn *conn;
|
||||||
|
|
||||||
conn = bt_conn_lookup_addr_le((bt_addr_le_t *) data);
|
conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, (bt_addr_le_t *)data);
|
||||||
if (!conn) {
|
if (!conn) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
@ -1675,7 +1675,7 @@ static void config_subscription(u8_t *data, u16_t len, u16_t op)
|
||||||
u16_t ccc_handle = sys_le16_to_cpu(cmd->ccc_handle);
|
u16_t ccc_handle = sys_le16_to_cpu(cmd->ccc_handle);
|
||||||
u8_t status;
|
u8_t status;
|
||||||
|
|
||||||
conn = bt_conn_lookup_addr_le((bt_addr_le_t *) data);
|
conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, (bt_addr_le_t *)data);
|
||||||
if (!conn) {
|
if (!conn) {
|
||||||
tester_rsp(BTP_SERVICE_ID_GATT, op, CONTROLLER_INDEX,
|
tester_rsp(BTP_SERVICE_ID_GATT, op, CONTROLLER_INDEX,
|
||||||
BTP_STATUS_FAILED);
|
BTP_STATUS_FAILED);
|
||||||
|
|
|
@ -137,7 +137,7 @@ static void connect(u8_t *data, u16_t len)
|
||||||
struct channel *chan;
|
struct channel *chan;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
conn = bt_conn_lookup_addr_le((bt_addr_le_t *) data);
|
conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, (bt_addr_le_t *)data);
|
||||||
if (!conn) {
|
if (!conn) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue