mirror of
https://github.com/espressif/esp-nimble.git
synced 2026-08-20 08:50:02 +00:00
fix(nimble): Handled IRK/LTK deletion based on key availability.
This commit is contained in:
@@ -31,7 +31,8 @@ extern "C" {
|
||||
#define BLE_STORE_OBJ_TYPE_PEER_SEC 2
|
||||
#define BLE_STORE_OBJ_TYPE_CCCD 3
|
||||
#define BLE_STORE_OBJ_TYPE_PEER_DEV_REC 4
|
||||
|
||||
#define BLE_STORE_OBJ_TYPE_PEER_ADDR 6
|
||||
#define BLE_STORE_OBJ_TYPE_LOCAL_IRK 7
|
||||
/** Failed to persist record; insufficient storage capacity. */
|
||||
#define BLE_STORE_EVENT_OVERFLOW 1
|
||||
|
||||
@@ -120,6 +121,26 @@ struct ble_store_value_cccd {
|
||||
uint16_t flags;
|
||||
unsigned value_changed:1;
|
||||
};
|
||||
struct ble_store_key_rpa_rec{
|
||||
ble_addr_t peer_rpa_addr;
|
||||
uint8_t idx;
|
||||
};
|
||||
struct ble_store_value_rpa_rec{
|
||||
ble_addr_t peer_rpa_addr;
|
||||
ble_addr_t peer_addr;
|
||||
};
|
||||
|
||||
struct ble_store_key_local_irk {
|
||||
ble_addr_t addr;
|
||||
|
||||
uint8_t idx;
|
||||
};
|
||||
struct ble_store_value_local_irk {
|
||||
ble_addr_t addr;
|
||||
|
||||
uint8_t irk[16];
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Used as a key for store lookups. This union must be accompanied by an
|
||||
@@ -128,6 +149,8 @@ struct ble_store_value_cccd {
|
||||
union ble_store_key {
|
||||
struct ble_store_key_sec sec;
|
||||
struct ble_store_key_cccd cccd;
|
||||
struct ble_store_key_rpa_rec rpa_rec;
|
||||
struct ble_store_key_local_irk local_irk;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -137,6 +160,8 @@ union ble_store_key {
|
||||
union ble_store_value {
|
||||
struct ble_store_value_sec sec;
|
||||
struct ble_store_value_cccd cccd;
|
||||
struct ble_store_value_rpa_rec rpa_rec;
|
||||
struct ble_store_value_local_irk local_irk;
|
||||
};
|
||||
|
||||
struct ble_store_status_event {
|
||||
@@ -272,6 +297,21 @@ void ble_store_key_from_value_sec(struct ble_store_key_sec *out_key,
|
||||
void ble_store_key_from_value_cccd(struct ble_store_key_cccd *out_key,
|
||||
const struct ble_store_value_cccd *value);
|
||||
|
||||
int ble_store_read_rpa_rec(const struct ble_store_key_rpa_rec *key,
|
||||
struct ble_store_value_rpa_rec *out_value);
|
||||
int ble_store_write_rpa_rec(const struct ble_store_value_rpa_rec *value);
|
||||
int ble_store_delete_rpa_rec(const struct ble_store_key_rpa_rec *key);
|
||||
void ble_store_key_from_value_rpa_rec(struct ble_store_key_rpa_rec *out_key,
|
||||
const struct ble_store_value_rpa_rec *value);
|
||||
|
||||
int ble_store_read_local_irk(const struct ble_store_key_local_irk *key,
|
||||
struct ble_store_value_local_irk *out_value);
|
||||
int ble_store_write_local_irk(const struct ble_store_value_local_irk *value);
|
||||
int ble_store_delete_local_irk(const struct ble_store_key_local_irk *key);
|
||||
void ble_store_key_from_value_local_irk(struct ble_store_key_local_irk *out_key,
|
||||
const struct ble_store_value_local_irk *value);
|
||||
|
||||
|
||||
void ble_store_key_from_value(int obj_type,
|
||||
union ble_store_key *out_key,
|
||||
const union ble_store_value *value);
|
||||
|
||||
@@ -5937,8 +5937,14 @@ ble_gap_encryption_initiate(uint16_t conn_handle,
|
||||
int
|
||||
ble_gap_unpair(const ble_addr_t *peer_addr)
|
||||
{
|
||||
#if NIMBLE_BLE_SM
|
||||
int rc;
|
||||
int ltk_rc = 0;
|
||||
int irk_rc = 0;
|
||||
struct ble_hs_conn *conn;
|
||||
|
||||
union ble_store_value value;
|
||||
union ble_store_key key;
|
||||
ble_addr_t *new_addr = (ble_addr_t *) peer_addr;
|
||||
if (!ble_hs_is_enabled()) {
|
||||
return BLE_HS_EDISABLED;
|
||||
}
|
||||
@@ -5956,10 +5962,54 @@ ble_gap_unpair(const ble_addr_t *peer_addr)
|
||||
|
||||
ble_hs_unlock();
|
||||
|
||||
ble_hs_pvcy_remove_entry(peer_addr->type,
|
||||
peer_addr->val);
|
||||
memset(&key,0,sizeof(key));
|
||||
key.rpa_rec.peer_rpa_addr = *peer_addr;
|
||||
|
||||
return ble_store_util_delete_peer(peer_addr);
|
||||
rc = ble_store_read(BLE_STORE_OBJ_TYPE_PEER_ADDR, &key, &value);
|
||||
|
||||
if (!rc) {
|
||||
new_addr = &(value.rpa_rec.peer_addr);
|
||||
}
|
||||
|
||||
memset(&key, 0, sizeof(key));
|
||||
key.sec.peer_addr = *new_addr;
|
||||
|
||||
rc = ble_store_read(BLE_STORE_OBJ_TYPE_PEER_SEC, &key, &value);
|
||||
|
||||
// Checking if the device is in ble_store
|
||||
if (!rc) {
|
||||
if (value.sec.irk_present) {
|
||||
// Delete the IRK as it is Distributed
|
||||
irk_rc = ble_hs_pvcy_remove_entry(key.sec.peer_addr.type,
|
||||
key.sec.peer_addr.val);
|
||||
if (irk_rc != 0) {
|
||||
BLE_HS_LOG(ERROR, "Error while removing IRK\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (value.sec.ltk_present || value.sec.irk_present) {
|
||||
// Delete the Peer record from store as LTK is present
|
||||
ltk_rc = ble_store_util_delete_peer(&key.sec.peer_addr);
|
||||
if (ltk_rc != 0) {
|
||||
BLE_HS_LOG(ERROR, "Error while removing LTK\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
rc = ble_store_read(BLE_STORE_OBJ_TYPE_OUR_SEC, &key, &value);
|
||||
if (!rc) {
|
||||
ble_store_util_delete_peer(&key.sec.peer_addr);
|
||||
}
|
||||
else {
|
||||
BLE_HS_LOG(ERROR,"No record found for the given address in ble store");
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
#else
|
||||
return BLE_HS_ENOTSUP;
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
|
||||
@@ -525,6 +525,7 @@ static void
|
||||
ble_sm_persist_keys(struct ble_sm_proc *proc)
|
||||
{
|
||||
struct ble_store_value_sec value_sec;
|
||||
struct ble_store_value_rpa_rec value_rpa_rec;
|
||||
struct ble_hs_conn *conn;
|
||||
ble_addr_t peer_addr;
|
||||
int authenticated;
|
||||
@@ -611,6 +612,9 @@ ble_sm_persist_keys(struct ble_sm_proc *proc)
|
||||
ble_sm_fill_store_value(&peer_addr, authenticated, sc, &proc->peer_keys,
|
||||
&value_sec);
|
||||
ble_store_write_peer_sec(&value_sec);
|
||||
value_rpa_rec.peer_addr=peer_addr;
|
||||
value_rpa_rec.peer_rpa_addr=conn->bhc_peer_rpa_addr;
|
||||
ble_store_write_rpa_rec(&value_rpa_rec);
|
||||
}
|
||||
|
||||
static int
|
||||
|
||||
@@ -306,6 +306,93 @@ ble_store_key_from_value_sec(struct ble_store_key_sec *out_key,
|
||||
out_key->idx = 0;
|
||||
}
|
||||
|
||||
int
|
||||
ble_store_read_rpa_rec(const struct ble_store_key_rpa_rec *key,
|
||||
struct ble_store_value_rpa_rec *out_value)
|
||||
{
|
||||
union ble_store_value *store_value;
|
||||
union ble_store_key *store_key;
|
||||
int rc;
|
||||
|
||||
store_key = (void *)key;
|
||||
store_value = (void *)out_value;
|
||||
rc = ble_store_read(BLE_STORE_OBJ_TYPE_PEER_ADDR, store_key, store_value);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
ble_store_write_rpa_rec(const struct ble_store_value_rpa_rec *value)
|
||||
{
|
||||
union ble_store_value *store_value;
|
||||
int rc;
|
||||
|
||||
store_value = (void *)value;
|
||||
rc = ble_store_write(BLE_STORE_OBJ_TYPE_PEER_ADDR, store_value);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
ble_store_delete_rpa_rec(const struct ble_store_key_rpa_rec *key)
|
||||
{
|
||||
union ble_store_key *store_key;
|
||||
int rc;
|
||||
|
||||
store_key = (void *)key;
|
||||
rc = ble_store_delete(BLE_STORE_OBJ_TYPE_PEER_ADDR, store_key);
|
||||
return rc;
|
||||
}
|
||||
void
|
||||
ble_store_key_from_value_rpa_rec(struct ble_store_key_rpa_rec *out_key,
|
||||
const struct ble_store_value_rpa_rec *value)
|
||||
{
|
||||
out_key->peer_rpa_addr = value->peer_rpa_addr;
|
||||
out_key->idx = 0;
|
||||
}
|
||||
|
||||
int
|
||||
ble_store_read_local_irk(const struct ble_store_key_local_irk *key,
|
||||
struct ble_store_value_local_irk *out_value)
|
||||
{
|
||||
union ble_store_value *store_value;
|
||||
union ble_store_key *store_key;
|
||||
int rc;
|
||||
|
||||
store_key = (void *)key;
|
||||
store_value = (void *)out_value;
|
||||
rc = ble_store_read(BLE_STORE_OBJ_TYPE_LOCAL_IRK, store_key, store_value);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
ble_store_write_local_irk(const struct ble_store_value_local_irk *value)
|
||||
{
|
||||
union ble_store_value *store_value;
|
||||
int rc;
|
||||
|
||||
store_value = (void *)value;
|
||||
rc = ble_store_write(BLE_STORE_OBJ_TYPE_LOCAL_IRK, store_value);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
ble_store_delete_local_irk(const struct ble_store_key_local_irk *key)
|
||||
{
|
||||
union ble_store_key *store_key;
|
||||
int rc;
|
||||
|
||||
store_key = (void *)key;
|
||||
rc = ble_store_delete(BLE_STORE_OBJ_TYPE_LOCAL_IRK, store_key);
|
||||
return rc;
|
||||
}
|
||||
|
||||
void
|
||||
ble_store_key_from_value_local_irk(struct ble_store_key_local_irk *out_key,
|
||||
const struct ble_store_value_local_irk *value)
|
||||
{
|
||||
out_key->addr = value->addr;
|
||||
out_key->idx = 0;
|
||||
}
|
||||
|
||||
void
|
||||
ble_store_key_from_value(int obj_type,
|
||||
union ble_store_key *out_key,
|
||||
@@ -321,6 +408,12 @@ ble_store_key_from_value(int obj_type,
|
||||
ble_store_key_from_value_cccd(&out_key->cccd, &value->cccd);
|
||||
break;
|
||||
|
||||
case BLE_STORE_OBJ_TYPE_PEER_ADDR:
|
||||
ble_store_key_from_value_rpa_rec(&out_key->rpa_rec, &value->rpa_rec);
|
||||
break;
|
||||
case BLE_STORE_OBJ_TYPE_LOCAL_IRK:
|
||||
ble_store_key_from_value_local_irk(&out_key->local_irk, &value->local_irk);
|
||||
break;
|
||||
default:
|
||||
BLE_HS_DBG_ASSERT(0);
|
||||
break;
|
||||
@@ -350,6 +443,14 @@ ble_store_iterate(int obj_type,
|
||||
key.cccd.peer_addr = *BLE_ADDR_ANY;
|
||||
pidx = &key.cccd.idx;
|
||||
break;
|
||||
case BLE_STORE_OBJ_TYPE_PEER_ADDR:
|
||||
key.rpa_rec.peer_rpa_addr = *BLE_ADDR_ANY;
|
||||
pidx = &key.rpa_rec.idx;
|
||||
break;
|
||||
case BLE_STORE_OBJ_TYPE_LOCAL_IRK:
|
||||
key.local_irk.addr = *BLE_ADDR_ANY;
|
||||
pidx = &key.local_irk.idx;
|
||||
break;
|
||||
default:
|
||||
BLE_HS_DBG_ASSERT(0);
|
||||
return BLE_HS_EINVAL;
|
||||
@@ -394,6 +495,8 @@ ble_store_clear(void)
|
||||
BLE_STORE_OBJ_TYPE_OUR_SEC,
|
||||
BLE_STORE_OBJ_TYPE_PEER_SEC,
|
||||
BLE_STORE_OBJ_TYPE_CCCD,
|
||||
BLE_STORE_OBJ_TYPE_PEER_ADDR,
|
||||
BLE_STORE_OBJ_TYPE_LOCAL_IRK
|
||||
};
|
||||
union ble_store_key key;
|
||||
int obj_type;
|
||||
|
||||
@@ -136,6 +136,14 @@ ble_store_util_delete_peer(const ble_addr_t *peer_id_addr)
|
||||
return rc;
|
||||
}
|
||||
|
||||
memset(&key, 0, sizeof key);
|
||||
key.rpa_rec.peer_rpa_addr = *peer_id_addr;
|
||||
|
||||
rc = ble_store_util_delete_all(BLE_STORE_OBJ_TYPE_PEER_ADDR, &key);
|
||||
if (rc != 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
#if MYNEWT_VAL(BLE_HOST_BASED_PRIVACY)
|
||||
struct ble_hs_dev_records *peer_rec =
|
||||
ble_rpa_find_peer_dev_rec(key.sec.peer_addr.val);
|
||||
@@ -255,6 +263,7 @@ ble_store_util_status_rr(struct ble_store_status_event *event, void *arg)
|
||||
switch (event->overflow.obj_type) {
|
||||
case BLE_STORE_OBJ_TYPE_OUR_SEC:
|
||||
case BLE_STORE_OBJ_TYPE_PEER_SEC:
|
||||
case BLE_STORE_OBJ_TYPE_PEER_ADDR:
|
||||
return ble_gap_unpair_oldest_peer();
|
||||
case BLE_STORE_OBJ_TYPE_CCCD:
|
||||
/* Try unpairing oldest peer except current peer */
|
||||
|
||||
@@ -38,6 +38,14 @@ struct ble_store_value_cccd
|
||||
ble_store_config_cccds[MYNEWT_VAL(BLE_STORE_MAX_CCCDS)];
|
||||
int ble_store_config_num_cccds;
|
||||
|
||||
struct ble_store_value_rpa_rec
|
||||
ble_store_config_rpa_recs[MYNEWT_VAL(BLE_STORE_MAX_BONDS)];
|
||||
int ble_store_config_num_rpa_recs;
|
||||
|
||||
struct ble_store_value_local_irk
|
||||
ble_store_config_local_irks[MYNEWT_VAL(BLE_STORE_MAX_BONDS)];
|
||||
int ble_store_config_num_local_irks;
|
||||
|
||||
/*****************************************************************************
|
||||
* $sec *
|
||||
*****************************************************************************/
|
||||
@@ -413,6 +421,213 @@ ble_store_config_write_cccd(const struct ble_store_value_cccd *value_cccd)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* $rpa-map *
|
||||
*****************************************************************************/
|
||||
#if MYNEWT_VAL(BLE_STORE_MAX_BONDS)
|
||||
static int
|
||||
ble_store_config_find_rpa_rec(const struct ble_store_key_rpa_rec *key){
|
||||
struct ble_store_value_rpa_rec *rpa_rec;
|
||||
int skipped = 0;
|
||||
int i = 0;
|
||||
|
||||
for(i = 0; i < ble_store_config_num_rpa_recs; i++){
|
||||
rpa_rec = ble_store_config_rpa_recs + i;
|
||||
|
||||
if (ble_addr_cmp(&rpa_rec->peer_rpa_addr, &key->peer_rpa_addr) && ble_addr_cmp(&rpa_rec->peer_addr, &key->peer_rpa_addr)) {
|
||||
continue;
|
||||
}
|
||||
if (key->idx > skipped) {
|
||||
skipped++;
|
||||
continue;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int
|
||||
ble_store_config_read_rpa_rec(const struct ble_store_key_rpa_rec *key_rpa_rec,struct ble_store_value_rpa_rec *value_rpa_rec)
|
||||
{
|
||||
#if MYNEWT_VAL(BLE_STORE_MAX_BONDS)
|
||||
int idx;
|
||||
|
||||
idx = ble_store_config_find_rpa_rec(key_rpa_rec);
|
||||
if (idx == -1) {
|
||||
return BLE_HS_ENOENT;
|
||||
}
|
||||
*value_rpa_rec = ble_store_config_rpa_recs[idx];
|
||||
return 0;
|
||||
#else
|
||||
return BLE_HS_ENOENT;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int
|
||||
ble_store_config_write_rpa_rec(const struct ble_store_value_rpa_rec *value_rpa_rec){
|
||||
|
||||
#if MYNEWT_VAL(BLE_STORE_MAX_BONDS)
|
||||
struct ble_store_key_rpa_rec key_rpa_rec;
|
||||
int idx;
|
||||
int rc;
|
||||
ble_store_key_from_value_rpa_rec(&key_rpa_rec, value_rpa_rec);
|
||||
idx = ble_store_config_find_rpa_rec(&key_rpa_rec);
|
||||
|
||||
if (idx == -1) {
|
||||
if (ble_store_config_num_rpa_recs >= MYNEWT_VAL(BLE_STORE_MAX_BONDS)) {
|
||||
BLE_HS_LOG(DEBUG, "error persisting peer addrr; too many entries (%d)\n",
|
||||
ble_store_config_num_rpa_recs);
|
||||
return BLE_HS_ESTORE_CAP;
|
||||
}
|
||||
|
||||
idx = ble_store_config_num_rpa_recs;
|
||||
ble_store_config_num_rpa_recs++;
|
||||
}
|
||||
ble_store_config_rpa_recs[idx] = *value_rpa_rec;
|
||||
|
||||
rc = ble_store_config_persist_rpa_recs();
|
||||
if (rc != 0) {
|
||||
return rc;
|
||||
}
|
||||
return 0;
|
||||
#else
|
||||
return BLE_HS_ENOENT;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int
|
||||
ble_store_config_delete_rpa_rec(const struct ble_store_key_rpa_rec *key_rpa_rec)
|
||||
{
|
||||
int idx;
|
||||
int rc;
|
||||
|
||||
idx = ble_store_config_find_rpa_rec(key_rpa_rec);
|
||||
if (idx == -1) {
|
||||
return BLE_HS_ENOENT;
|
||||
}
|
||||
|
||||
rc = ble_store_config_delete_obj(ble_store_config_rpa_recs,
|
||||
sizeof *ble_store_config_rpa_recs,
|
||||
idx,
|
||||
&ble_store_config_num_rpa_recs);
|
||||
if (rc != 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = ble_store_config_persist_rpa_recs();
|
||||
if (rc != 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* $local_irk *
|
||||
*****************************************************************************/
|
||||
static int
|
||||
ble_store_config_find_local_irk(const struct ble_store_key_local_irk *key)
|
||||
{
|
||||
struct ble_store_value_local_irk *local_irk;
|
||||
int skipped;
|
||||
int i;
|
||||
|
||||
skipped = 0;
|
||||
for (i = 0; i < ble_store_config_num_local_irks; i++) {
|
||||
local_irk = ble_store_config_local_irks + i;
|
||||
|
||||
if (ble_addr_cmp(&key->addr, BLE_ADDR_ANY)) {
|
||||
if (ble_addr_cmp(&local_irk->addr, &key->addr)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (key->idx > skipped) {
|
||||
skipped++;
|
||||
continue;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
ble_store_config_delete_local_irk(const struct ble_store_key_local_irk *key_irk)
|
||||
{
|
||||
int idx;
|
||||
int rc;
|
||||
|
||||
idx = ble_store_config_find_local_irk(key_irk);
|
||||
if (idx == -1) {
|
||||
return BLE_HS_ENOENT;
|
||||
}
|
||||
|
||||
rc = ble_store_config_delete_obj(ble_store_config_local_irks,
|
||||
sizeof *ble_store_config_local_irks,
|
||||
idx,
|
||||
&ble_store_config_num_local_irks);
|
||||
if (rc != 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = ble_store_config_persist_local_irk();
|
||||
if (rc != 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
ble_store_config_read_local_irk(const struct ble_store_key_local_irk *key_irk,
|
||||
struct ble_store_value_local_irk *value_irk)
|
||||
{
|
||||
int idx;
|
||||
|
||||
idx = ble_store_config_find_local_irk(key_irk);
|
||||
if (idx == -1) {
|
||||
return BLE_HS_ENOENT;
|
||||
}
|
||||
|
||||
*value_irk = ble_store_config_local_irks[idx];
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
ble_store_config_write_local_irk(const struct ble_store_value_local_irk *value_irk)
|
||||
{
|
||||
struct ble_store_key_local_irk key_irk;
|
||||
int idx;
|
||||
int rc;
|
||||
|
||||
ble_store_key_from_value_local_irk(&key_irk, value_irk);
|
||||
idx = ble_store_config_find_local_irk(&key_irk);
|
||||
|
||||
if (idx == -1) {
|
||||
if (ble_store_config_num_local_irks >= 1) {
|
||||
BLE_HS_LOG(DEBUG, "error persisting ead; too many entries (%d)\n",
|
||||
ble_store_config_num_local_irks);
|
||||
return BLE_HS_ESTORE_CAP;
|
||||
}
|
||||
|
||||
idx = ble_store_config_num_local_irks;
|
||||
ble_store_config_num_local_irks++;
|
||||
}
|
||||
|
||||
ble_store_config_local_irks[idx] = *value_irk;
|
||||
|
||||
rc = ble_store_config_persist_local_irk();
|
||||
if (rc != 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* $api *
|
||||
*****************************************************************************/
|
||||
@@ -455,6 +670,14 @@ ble_store_config_read(int obj_type, const union ble_store_key *key,
|
||||
rc = ble_store_config_read_cccd(&key->cccd, &value->cccd);
|
||||
return rc;
|
||||
|
||||
case BLE_STORE_OBJ_TYPE_PEER_ADDR:
|
||||
rc = ble_store_config_read_rpa_rec(&key->rpa_rec, &value->rpa_rec);
|
||||
return rc;
|
||||
|
||||
case BLE_STORE_OBJ_TYPE_LOCAL_IRK:
|
||||
rc = ble_store_config_read_local_irk(&key->local_irk, &value->local_irk);
|
||||
return rc;
|
||||
|
||||
default:
|
||||
return BLE_HS_ENOTSUP;
|
||||
}
|
||||
@@ -484,6 +707,14 @@ ble_store_config_write(int obj_type, const union ble_store_value *val)
|
||||
rc = ble_store_config_write_cccd(&val->cccd);
|
||||
return rc;
|
||||
|
||||
case BLE_STORE_OBJ_TYPE_PEER_ADDR:
|
||||
rc = ble_store_config_write_rpa_rec(&val->rpa_rec);
|
||||
return rc;
|
||||
|
||||
case BLE_STORE_OBJ_TYPE_LOCAL_IRK:
|
||||
rc = ble_store_config_write_local_irk(&val->local_irk);
|
||||
return rc;
|
||||
|
||||
default:
|
||||
return BLE_HS_ENOTSUP;
|
||||
}
|
||||
@@ -507,6 +738,14 @@ ble_store_config_delete(int obj_type, const union ble_store_key *key)
|
||||
rc = ble_store_config_delete_cccd(&key->cccd);
|
||||
return rc;
|
||||
|
||||
case BLE_STORE_OBJ_TYPE_PEER_ADDR:
|
||||
rc = ble_store_config_delete_rpa_rec(&key->rpa_rec);
|
||||
return rc;
|
||||
|
||||
case BLE_STORE_OBJ_TYPE_LOCAL_IRK:
|
||||
rc = ble_store_config_delete_local_irk(&key->local_irk);
|
||||
return rc;
|
||||
|
||||
default:
|
||||
return BLE_HS_ENOTSUP;
|
||||
}
|
||||
@@ -526,6 +765,7 @@ ble_store_config_init(void)
|
||||
ble_store_config_num_our_secs = 0;
|
||||
ble_store_config_num_peer_secs = 0;
|
||||
ble_store_config_num_cccds = 0;
|
||||
|
||||
ble_store_config_num_rpa_recs = 0;
|
||||
ble_store_config_num_local_irks=0;
|
||||
ble_store_config_conf_init();
|
||||
}
|
||||
|
||||
@@ -57,6 +57,12 @@ static struct conf_handler ble_store_config_conf_handler = {
|
||||
#define BLE_STORE_CONFIG_CCCD_SET_ENCODE_SZ \
|
||||
(MYNEWT_VAL(BLE_STORE_MAX_CCCDS) * BLE_STORE_CONFIG_CCCD_ENCODE_SZ + 1)
|
||||
|
||||
#define BLE_STORE_CONFIG_RPA_REC_ENCODE_SZ \
|
||||
BASE64_ENCODE_SIZE(sizeof (struct ble_store_value_rpa_rec))
|
||||
|
||||
#define BLE_STORE_CONFIG_RPA_REC_SET_ENCODE_SZ \
|
||||
(MYNEWT_VAL(BLE_STORE_MAX_BONDS) * BLE_STORE_CONFIG_RPA_REC_ENCODE_SZ + 1)
|
||||
|
||||
static void
|
||||
ble_store_config_serialize_arr(const void *arr, int obj_sz, int num_objs,
|
||||
char *out_buf, int buf_sz)
|
||||
@@ -114,6 +120,14 @@ ble_store_config_conf_set(int argc, char **argv, char *val)
|
||||
&ble_store_config_num_cccds);
|
||||
return rc;
|
||||
}
|
||||
else if (strcmp(argv[0],"rpa_rec") == 0){
|
||||
rc = ble_store_config_deserialize_arr(
|
||||
val,
|
||||
ble_store_config_rpa_recs,
|
||||
sizeof *ble_store_config_rpa_recs,
|
||||
&ble_store_config_num_rpa_recs);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
return OS_ENOENT;
|
||||
}
|
||||
@@ -125,6 +139,7 @@ ble_store_config_conf_export(void (*func)(char *name, char *val),
|
||||
union {
|
||||
char sec[BLE_STORE_CONFIG_SEC_SET_ENCODE_SZ];
|
||||
char cccd[BLE_STORE_CONFIG_CCCD_SET_ENCODE_SZ];
|
||||
char rpa_rec[BLE_STORE_CONFIG_RPA_REC_SET_ENCODE_SZ];
|
||||
} buf;
|
||||
|
||||
ble_store_config_serialize_arr(ble_store_config_our_secs,
|
||||
@@ -148,6 +163,12 @@ ble_store_config_conf_export(void (*func)(char *name, char *val),
|
||||
sizeof buf.cccd);
|
||||
func("ble_hs/cccd", buf.cccd);
|
||||
|
||||
ble_store_config_serialize_arr(ble_store_config_rpa_recs,
|
||||
sizeof *ble_store_config_rpa_recs,
|
||||
ble_store_config_num_rpa_recs,
|
||||
buf.rpa_rec,
|
||||
sizeof buf.rpa_rec);
|
||||
func("ble_hs/rpa_rec", buf.rpa_rec);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -218,6 +239,22 @@ ble_store_config_persist_cccds(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ble_store_config_persist_rpa_recs(void)
|
||||
{
|
||||
char buf[BLE_STORE_CONFIG_RPA_REC_SET_ENCODE_SZ];
|
||||
int rc;
|
||||
ble_store_config_serialize_arr(ble_store_config_rpa_recs,
|
||||
sizeof *ble_store_config_rpa_recs,
|
||||
ble_store_config_num_rpa_recs,
|
||||
buf,
|
||||
sizeof buf);
|
||||
rc = conf_save_one("ble_hs/rpa_rec", buf);
|
||||
if (rc != 0) {
|
||||
return BLE_HS_ESTORE_FAIL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
void
|
||||
ble_store_config_conf_init(void)
|
||||
{
|
||||
|
||||
@@ -36,11 +36,22 @@ extern struct ble_store_value_cccd
|
||||
ble_store_config_cccds[MYNEWT_VAL(BLE_STORE_MAX_CCCDS)];
|
||||
extern int ble_store_config_num_cccds;
|
||||
|
||||
extern struct ble_store_value_rpa_rec
|
||||
ble_store_config_rpa_recs[MYNEWT_VAL(BLE_STORE_MAX_BONDS)];
|
||||
extern int ble_store_config_num_rpa_recs;
|
||||
|
||||
extern struct ble_store_value_local_irk
|
||||
ble_store_config_local_irks[MYNEWT_VAL(BLE_STORE_MAX_BONDS)];
|
||||
extern int ble_store_config_num_local_irks;
|
||||
|
||||
|
||||
#if MYNEWT_VAL(BLE_STORE_CONFIG_PERSIST)
|
||||
|
||||
int ble_store_config_persist_our_secs(void);
|
||||
int ble_store_config_persist_peer_secs(void);
|
||||
int ble_store_config_persist_cccds(void);
|
||||
int ble_store_config_persist_rpa_recs(void);
|
||||
int ble_store_config_persist_local_irk(void);
|
||||
void ble_store_config_conf_init(void);
|
||||
|
||||
#else
|
||||
@@ -48,6 +59,8 @@ void ble_store_config_conf_init(void);
|
||||
static inline int ble_store_config_persist_our_secs(void) { return 0; }
|
||||
static inline int ble_store_config_persist_peer_secs(void) { return 0; }
|
||||
static inline int ble_store_config_persist_cccds(void) { return 0; }
|
||||
static inline int ble_store_config_persist_rpa_recs(void) { return 0; }
|
||||
static inline int ble_store_config_persist_local_irk(void) { return 0; }
|
||||
static inline void ble_store_config_conf_init(void) { }
|
||||
|
||||
#if MYNEWT_VAL(BLE_HOST_BASED_PRIVACY)
|
||||
|
||||
@@ -41,7 +41,8 @@
|
||||
#define NIMBLE_NVS_CCCD_SEC_KEY "cccd_sec"
|
||||
#define NIMBLE_NVS_PEER_RECORDS_KEY "p_dev_rec"
|
||||
#define NIMBLE_NVS_NAMESPACE "nimble_bond"
|
||||
|
||||
#define NIMBLE_NVS_RPA_RECORDS_KEY "rpa_rec"
|
||||
#define NIMBLE_NVS_LOCAL_IRK_KEY "local_irk"
|
||||
static const char *TAG = "NIMBLE_NVS";
|
||||
|
||||
/*****************************************************************************
|
||||
@@ -58,7 +59,11 @@ get_nvs_key_string(int obj_type, int index, char *key_string)
|
||||
sprintf(key_string, "%s_%d", NIMBLE_NVS_PEER_SEC_KEY, index);
|
||||
} else if (obj_type == BLE_STORE_OBJ_TYPE_OUR_SEC) {
|
||||
sprintf(key_string, "%s_%d", NIMBLE_NVS_OUR_SEC_KEY, index);
|
||||
} else {
|
||||
} else if (obj_type == BLE_STORE_OBJ_TYPE_PEER_ADDR){
|
||||
sprintf(key_string, "%s_%d", NIMBLE_NVS_RPA_RECORDS_KEY, index);
|
||||
} else if (obj_type == BLE_STORE_OBJ_TYPE_LOCAL_IRK) {
|
||||
sprintf(key_string, "%s_%d", NIMBLE_NVS_LOCAL_IRK_KEY, index);
|
||||
} else {
|
||||
sprintf(key_string, "%s_%d", NIMBLE_NVS_CCCD_SEC_KEY, index);
|
||||
}
|
||||
}
|
||||
@@ -156,6 +161,14 @@ get_nvs_db_value(int obj_type, char *key_string, union ble_store_value *val)
|
||||
if (obj_type == BLE_STORE_OBJ_TYPE_CCCD) {
|
||||
err = nvs_get_blob(nimble_handle, key_string, &val->cccd,
|
||||
&required_size);
|
||||
|
||||
} else if (obj_type == BLE_STORE_OBJ_TYPE_PEER_ADDR) {
|
||||
err = nvs_get_blob(nimble_handle, key_string, &val->rpa_rec,
|
||||
&required_size);
|
||||
|
||||
} else if (obj_type == BLE_STORE_OBJ_TYPE_LOCAL_IRK) {
|
||||
err = nvs_get_blob (nimble_handle, key_string, &val->local_irk,
|
||||
&required_size);
|
||||
} else {
|
||||
err = nvs_get_blob(nimble_handle, key_string, &val->sec,
|
||||
&required_size);
|
||||
@@ -222,6 +235,15 @@ get_nvs_db_attribute(int obj_type, bool empty, void *value, int num_value)
|
||||
if (obj_type != BLE_STORE_OBJ_TYPE_CCCD) {
|
||||
err = get_nvs_matching_index(&cur.sec, value, num_value,
|
||||
sizeof(struct ble_store_value_sec));
|
||||
|
||||
} else if (obj_type == BLE_STORE_OBJ_TYPE_PEER_ADDR){
|
||||
err = get_nvs_matching_index(&cur.rpa_rec,value,num_value,
|
||||
sizeof(struct ble_store_value_rpa_rec));
|
||||
|
||||
} else if (obj_type == BLE_STORE_OBJ_TYPE_LOCAL_IRK) {
|
||||
err = get_nvs_matching_index(&cur.local_irk, value, num_value,
|
||||
sizeof(struct ble_store_value_local_irk));
|
||||
|
||||
} else {
|
||||
err = get_nvs_matching_index(&cur.cccd, value, num_value,
|
||||
sizeof(struct ble_store_value_cccd));
|
||||
@@ -347,6 +369,14 @@ ble_store_nvs_write(int obj_type, const union ble_store_value *val)
|
||||
if (obj_type == BLE_STORE_OBJ_TYPE_CCCD) {
|
||||
return ble_nvs_write_key_value(key_string, &val->cccd, sizeof(struct
|
||||
ble_store_value_cccd));
|
||||
} else if (obj_type == BLE_STORE_OBJ_TYPE_PEER_ADDR) {
|
||||
return ble_nvs_write_key_value(key_string, &val->rpa_rec, sizeof(struct
|
||||
ble_store_value_rpa_rec));
|
||||
|
||||
} else if (obj_type == BLE_STORE_OBJ_TYPE_LOCAL_IRK) {
|
||||
return ble_nvs_write_key_value(key_string, &val->local_irk, sizeof(struct
|
||||
ble_store_value_local_irk));
|
||||
|
||||
} else {
|
||||
return ble_nvs_write_key_value(key_string, &val->sec, sizeof(struct
|
||||
ble_store_value_sec));
|
||||
@@ -431,6 +461,19 @@ populate_db_from_nvs(int obj_type, void *dst, int *db_num)
|
||||
memcpy(db_item, &cur.cccd, sizeof(struct ble_store_value_cccd));
|
||||
db_item += sizeof(struct ble_store_value_cccd);
|
||||
(*db_num)++;
|
||||
|
||||
} else if (obj_type == BLE_STORE_OBJ_TYPE_PEER_ADDR) {
|
||||
ESP_LOGD(TAG, "RPA_REC in RAM is filled up from NVS index = %d", i);
|
||||
memcpy(db_item, &cur.rpa_rec, sizeof(struct ble_store_value_rpa_rec));
|
||||
db_item += sizeof(struct ble_store_value_rpa_rec);
|
||||
(*db_num)++;
|
||||
|
||||
} else if (obj_type == BLE_STORE_OBJ_TYPE_LOCAL_IRK) {
|
||||
ESP_LOGD(TAG, "Local IRK in RAM is filled up from NVS index = %d", i);
|
||||
memcpy(db_item, &cur.local_irk, sizeof(struct ble_store_value_local_irk));
|
||||
db_item += sizeof(struct ble_store_value_local_irk);
|
||||
(*db_num)++;
|
||||
|
||||
} else {
|
||||
ESP_LOGD(TAG, "KEY in RAM is filled up from NVS index = %d", i);
|
||||
memcpy(db_item, &cur.sec, sizeof(struct ble_store_value_sec));
|
||||
@@ -476,6 +519,24 @@ ble_nvs_restore_sec_keys(void)
|
||||
ESP_LOGD(TAG, "ble_store_config_cccds restored %d bonds",
|
||||
ble_store_config_num_cccds);
|
||||
|
||||
err = populate_db_from_nvs(BLE_STORE_OBJ_TYPE_PEER_ADDR, ble_store_config_rpa_recs,
|
||||
&ble_store_config_num_rpa_recs);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "NVS operation failed for 'RPA_REC'");
|
||||
return err;
|
||||
}
|
||||
ESP_LOGD(TAG, "ble_store_config_rpa_recs restored %d bonds",
|
||||
ble_store_config_num_rpa_recs);
|
||||
|
||||
err = populate_db_from_nvs(BLE_STORE_OBJ_TYPE_LOCAL_IRK, ble_store_config_local_irks,
|
||||
&ble_store_config_num_local_irks);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "NVS operation failed for 'Local IRK'");
|
||||
return err;
|
||||
}
|
||||
ESP_LOGD(TAG, "ble_store_config_local_irks restored %d irks",
|
||||
ble_store_config_num_local_irks);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -532,6 +593,64 @@ int ble_store_config_persist_cccds(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ble_store_config_persist_rpa_recs(void)
|
||||
{
|
||||
int nvs_count, nvs_idx;
|
||||
union ble_store_value val;
|
||||
nvs_count = get_nvs_db_attribute(BLE_STORE_OBJ_TYPE_PEER_ADDR, 0, NULL, 0);
|
||||
if (nvs_count == -1) {
|
||||
ESP_LOGE(TAG, "NVS operation failed while persisting RPA_RECS");
|
||||
return BLE_HS_ESTORE_FAIL;
|
||||
}
|
||||
if (nvs_count < ble_store_config_num_rpa_recs) {
|
||||
/* NVS db count less than RAM count, write operation */
|
||||
ESP_LOGD(TAG, "Persisting RPA_RECS value in NVS...");
|
||||
val.rpa_rec = ble_store_config_rpa_recs[ble_store_config_num_rpa_recs - 1];
|
||||
return ble_store_nvs_write(BLE_STORE_OBJ_TYPE_PEER_ADDR, &val);
|
||||
} else if (nvs_count > ble_store_config_num_rpa_recs) {
|
||||
/* NVS db count more than RAM count, delete operation */
|
||||
nvs_idx = get_nvs_db_attribute(BLE_STORE_OBJ_TYPE_PEER_ADDR, 0,
|
||||
ble_store_config_rpa_recs, ble_store_config_num_rpa_recs);
|
||||
if (nvs_idx == -1) {
|
||||
ESP_LOGE(TAG, "NVS delete operation failed for RPA_REC");
|
||||
return BLE_HS_ESTORE_FAIL;
|
||||
}
|
||||
ESP_LOGD(TAG, "Deleting RPA_REC, nvs idx = %d", nvs_idx);
|
||||
return ble_nvs_delete_value(BLE_STORE_OBJ_TYPE_PEER_ADDR, nvs_idx);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ble_store_config_persist_local_irk(void)
|
||||
{
|
||||
int nvs_count, nvs_idx;
|
||||
union ble_store_value val;
|
||||
|
||||
nvs_count = get_nvs_db_attribute(BLE_STORE_OBJ_TYPE_LOCAL_IRK, 0, NULL, 0);
|
||||
if (nvs_count == -1) {
|
||||
ESP_LOGE(TAG, "NVS operation failed while persisting EAD");
|
||||
return BLE_HS_ESTORE_FAIL;
|
||||
}
|
||||
|
||||
if (nvs_count < ble_store_config_num_local_irks) {
|
||||
/* NVS db count less than RAM count, write operation */
|
||||
ESP_LOGD(TAG, "Persisting Local IRK value in NVS...");
|
||||
val.local_irk = ble_store_config_local_irks[ble_store_config_num_local_irks-1];
|
||||
return ble_store_nvs_write(BLE_STORE_OBJ_TYPE_LOCAL_IRK, &val);
|
||||
} else if (nvs_count > ble_store_config_num_local_irks) {
|
||||
/* NVS db count more than RAM count, delete operation */
|
||||
nvs_idx = get_nvs_db_attribute(BLE_STORE_OBJ_TYPE_LOCAL_IRK, 0,
|
||||
ble_store_config_local_irks, ble_store_config_num_local_irks);
|
||||
if (nvs_idx == -1) {
|
||||
ESP_LOGE(TAG, "NVS delete operation failed for Local IRK");
|
||||
return BLE_HS_ESTORE_FAIL;
|
||||
}
|
||||
ESP_LOGD(TAG, "Deleting Local IRK, nvs idx = %d", nvs_idx);
|
||||
return ble_nvs_delete_value(BLE_STORE_OBJ_TYPE_LOCAL_IRK, nvs_idx);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ble_store_config_persist_peer_secs(void)
|
||||
{
|
||||
int nvs_count, nvs_idx;
|
||||
|
||||
Reference in New Issue
Block a user