MYNEWT-743 BLE Host - Persist bonds to sys/config

X-Original-Commit: 858e59595311423deb674959841c3d3b8eb9e100
This commit is contained in:
Christopher Collins
2017-06-28 15:22:38 -07:00
parent f33e83bace
commit 1983ab5f90
14 changed files with 986 additions and 24 deletions
+1
View File
@@ -72,6 +72,7 @@ struct os_event;
#define BLE_HS_EENCRYPT 25
#define BLE_HS_EENCRYPT_KEY_SZ 26
#define BLE_HS_ESTORE_CAP 27
#define BLE_HS_ESTORE_FAIL 28
#define BLE_HS_ERR_ATT_BASE 0x100 /* 256 */
#define BLE_HS_ATT_ERR(x) ((x) ? BLE_HS_ERR_ATT_BASE + (x) : 0)
@@ -0,0 +1,39 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#ifndef H_BLE_STORE_CONFIG_
#define H_BLE_STORE_CONFIG_
#ifdef __cplusplus
extern "C" {
#endif
union ble_store_key;
union ble_store_value;
int ble_store_config_read(int obj_type, const union ble_store_key *key,
union ble_store_value *value);
int ble_store_config_write(int obj_type, const union ble_store_value *val);
int ble_store_config_delete(int obj_type, const union ble_store_key *key);
#ifdef __cplusplus
}
#endif
#endif
+38
View File
@@ -0,0 +1,38 @@
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
#
pkg.name: net/nimble/host/store/config
pkg.description: sys/config-based persistence layer for the NimBLE host.
pkg.author: "Apache Mynewt <[email protected]>"
pkg.homepage: "http://mynewt.apache.org/"
pkg.keywords:
- ble
- bluetooth
- nimble
- persistence
pkg.deps:
- encoding/base64
- net/nimble/host
pkg.deps.BLE_STORE_CONFIG_PERSIST:
- sys/config
pkg.init:
ble_store_config_init: 500
@@ -0,0 +1,533 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#include <inttypes.h>
#include <string.h>
#include "sysinit/sysinit.h"
#include "syscfg/syscfg.h"
#include "host/ble_hs.h"
#include "config/config.h"
#include "base64/base64.h"
#include "store/config/ble_store_config.h"
#include "ble_store_config_priv.h"
struct ble_store_value_sec
ble_store_config_our_secs[MYNEWT_VAL(BLE_STORE_MAX_BONDS)];
int ble_store_config_num_our_secs;
struct ble_store_value_sec
ble_store_config_peer_secs[MYNEWT_VAL(BLE_STORE_MAX_BONDS)];
int ble_store_config_num_peer_secs;
struct ble_store_value_cccd
ble_store_config_cccds[MYNEWT_VAL(BLE_STORE_MAX_CCCDS)];
int ble_store_config_num_cccds;
/*****************************************************************************
* $sec *
*****************************************************************************/
static void
ble_store_config_print_value_sec(const struct ble_store_value_sec *sec)
{
if (sec->ltk_present) {
BLE_HS_LOG(DEBUG, "ediv=%u rand=%llu authenticated=%d ltk=",
sec->ediv, sec->rand_num, sec->authenticated);
ble_hs_log_flat_buf(sec->ltk, 16);
BLE_HS_LOG(DEBUG, " ");
}
if (sec->irk_present) {
BLE_HS_LOG(DEBUG, "irk=");
ble_hs_log_flat_buf(sec->irk, 16);
BLE_HS_LOG(DEBUG, " ");
}
if (sec->csrk_present) {
BLE_HS_LOG(DEBUG, "csrk=");
ble_hs_log_flat_buf(sec->csrk, 16);
BLE_HS_LOG(DEBUG, " ");
}
BLE_HS_LOG(DEBUG, "\n");
}
static void
ble_store_config_print_key_sec(const struct ble_store_key_sec *key_sec)
{
if (ble_addr_cmp(&key_sec->peer_addr, BLE_ADDR_ANY)) {
BLE_HS_LOG(DEBUG, "peer_addr_type=%d peer_addr=",
key_sec->peer_addr.type);
ble_hs_log_flat_buf(key_sec->peer_addr.val, 6);
BLE_HS_LOG(DEBUG, " ");
}
if (key_sec->ediv_rand_present) {
BLE_HS_LOG(DEBUG, "ediv=0x%02x rand=0x%llx ",
key_sec->ediv, key_sec->rand_num);
}
}
static int
ble_store_config_find_sec(const struct ble_store_key_sec *key_sec,
const struct ble_store_value_sec *value_secs,
int num_value_secs)
{
const struct ble_store_value_sec *cur;
int skipped;
int i;
skipped = 0;
for (i = 0; i < num_value_secs; i++) {
cur = value_secs + i;
if (ble_addr_cmp(&key_sec->peer_addr, BLE_ADDR_ANY)) {
if (ble_addr_cmp(&cur->peer_addr, &key_sec->peer_addr)) {
continue;
}
}
if (key_sec->ediv_rand_present) {
if (cur->ediv != key_sec->ediv) {
continue;
}
if (cur->rand_num != key_sec->rand_num) {
continue;
}
}
if (key_sec->idx > skipped) {
skipped++;
continue;
}
return i;
}
return -1;
}
static int
ble_store_config_read_our_sec(const struct ble_store_key_sec *key_sec,
struct ble_store_value_sec *value_sec)
{
int idx;
idx = ble_store_config_find_sec(key_sec, ble_store_config_our_secs,
ble_store_config_num_our_secs);
if (idx == -1) {
return BLE_HS_ENOENT;
}
*value_sec = ble_store_config_our_secs[idx];
return 0;
}
static int
ble_store_config_write_our_sec(const struct ble_store_value_sec *value_sec)
{
struct ble_store_key_sec key_sec;
int idx;
int rc;
BLE_HS_LOG(DEBUG, "persisting our sec; ");
ble_store_config_print_value_sec(value_sec);
ble_store_key_from_value_sec(&key_sec, value_sec);
idx = ble_store_config_find_sec(&key_sec, ble_store_config_our_secs,
ble_store_config_num_our_secs);
if (idx == -1) {
if (ble_store_config_num_our_secs >= MYNEWT_VAL(BLE_STORE_MAX_BONDS)) {
BLE_HS_LOG(DEBUG, "error persisting our sec; too many entries "
"(%d)\n", ble_store_config_num_our_secs);
return BLE_HS_ESTORE_CAP;
}
idx = ble_store_config_num_our_secs;
ble_store_config_num_our_secs++;
}
ble_store_config_our_secs[idx] = *value_sec;
rc = ble_store_config_persist_our_secs();
if (rc != 0) {
return rc;
}
return 0;
}
static int
ble_store_config_delete_obj(void *values, int value_size, int idx,
int *num_values)
{
uint8_t *dst;
uint8_t *src;
int move_count;
(*num_values)--;
if (idx < *num_values) {
dst = values;
dst += idx * value_size;
src = dst + value_size;
move_count = *num_values - idx;
memmove(dst, src, move_count * value_size);
}
return 0;
}
static int
ble_store_config_delete_sec(const struct ble_store_key_sec *key_sec,
struct ble_store_value_sec *value_secs,
int *num_value_secs)
{
int idx;
int rc;
idx = ble_store_config_find_sec(key_sec, value_secs, *num_value_secs);
if (idx == -1) {
return BLE_HS_ENOENT;
}
rc = ble_store_config_delete_obj(value_secs, sizeof *value_secs, idx,
num_value_secs);
if (rc != 0) {
return rc;
}
return 0;
}
static int
ble_store_config_delete_our_sec(const struct ble_store_key_sec *key_sec)
{
int rc;
rc = ble_store_config_delete_sec(key_sec, ble_store_config_our_secs,
&ble_store_config_num_our_secs);
if (rc != 0) {
return rc;
}
rc = ble_store_config_persist_our_secs();
if (rc != 0) {
return rc;
}
return 0;
}
static int
ble_store_config_delete_peer_sec(const struct ble_store_key_sec *key_sec)
{
int rc;
rc = ble_store_config_delete_sec(key_sec, ble_store_config_peer_secs,
&ble_store_config_num_peer_secs);
if (rc != 0) {
return rc;
}
rc = ble_store_config_persist_peer_secs();
if (rc != 0) {
return rc;
}
return 0;
}
static int
ble_store_config_read_peer_sec(const struct ble_store_key_sec *key_sec,
struct ble_store_value_sec *value_sec)
{
int idx;
idx = ble_store_config_find_sec(key_sec, ble_store_config_peer_secs,
ble_store_config_num_peer_secs);
if (idx == -1) {
return BLE_HS_ENOENT;
}
*value_sec = ble_store_config_peer_secs[idx];
return 0;
}
static int
ble_store_config_write_peer_sec(const struct ble_store_value_sec *value_sec)
{
struct ble_store_key_sec key_sec;
int idx;
int rc;
BLE_HS_LOG(DEBUG, "persisting peer sec; ");
ble_store_config_print_value_sec(value_sec);
ble_store_key_from_value_sec(&key_sec, value_sec);
idx = ble_store_config_find_sec(&key_sec, ble_store_config_peer_secs,
ble_store_config_num_peer_secs);
if (idx == -1) {
if (ble_store_config_num_peer_secs >= MYNEWT_VAL(BLE_STORE_MAX_BONDS)) {
BLE_HS_LOG(DEBUG, "error persisting peer sec; too many entries "
"(%d)\n", ble_store_config_num_peer_secs);
return BLE_HS_ESTORE_CAP;
}
idx = ble_store_config_num_peer_secs;
ble_store_config_num_peer_secs++;
}
ble_store_config_peer_secs[idx] = *value_sec;
rc = ble_store_config_persist_peer_secs();
if (rc != 0) {
return rc;
}
return 0;
}
/*****************************************************************************
* $cccd *
*****************************************************************************/
static int
ble_store_config_find_cccd(const struct ble_store_key_cccd *key)
{
struct ble_store_value_cccd *cccd;
int skipped;
int i;
skipped = 0;
for (i = 0; i < ble_store_config_num_cccds; i++) {
cccd = ble_store_config_cccds + i;
if (ble_addr_cmp(&key->peer_addr, BLE_ADDR_ANY)) {
if (ble_addr_cmp(&cccd->peer_addr, &key->peer_addr)) {
continue;
}
}
if (key->chr_val_handle != 0) {
if (cccd->chr_val_handle != key->chr_val_handle) {
continue;
}
}
if (key->idx > skipped) {
skipped++;
continue;
}
return i;
}
return -1;
}
static int
ble_store_config_delete_cccd(const struct ble_store_key_cccd *key_cccd)
{
int idx;
int rc;
idx = ble_store_config_find_cccd(key_cccd);
if (idx == -1) {
return BLE_HS_ENOENT;
}
rc = ble_store_config_delete_obj(ble_store_config_cccds,
sizeof *ble_store_config_cccds,
idx,
&ble_store_config_num_cccds);
if (rc != 0) {
return rc;
}
rc = ble_store_config_persist_cccds();
if (rc != 0) {
return rc;
}
return 0;
}
static int
ble_store_config_read_cccd(const struct ble_store_key_cccd *key_cccd,
struct ble_store_value_cccd *value_cccd)
{
int idx;
idx = ble_store_config_find_cccd(key_cccd);
if (idx == -1) {
return BLE_HS_ENOENT;
}
*value_cccd = ble_store_config_cccds[idx];
return 0;
}
static int
ble_store_config_write_cccd(const struct ble_store_value_cccd *value_cccd)
{
struct ble_store_key_cccd key_cccd;
int idx;
int rc;
ble_store_key_from_value_cccd(&key_cccd, value_cccd);
idx = ble_store_config_find_cccd(&key_cccd);
if (idx == -1) {
if (ble_store_config_num_cccds >= MYNEWT_VAL(BLE_STORE_MAX_CCCDS)) {
BLE_HS_LOG(DEBUG, "error persisting cccd; too many entries (%d)\n",
ble_store_config_num_cccds);
return BLE_HS_ESTORE_CAP;
}
idx = ble_store_config_num_cccds;
ble_store_config_num_cccds++;
}
ble_store_config_cccds[idx] = *value_cccd;
rc = ble_store_config_persist_cccds();
if (rc != 0) {
return rc;
}
return 0;
}
/*****************************************************************************
* $api *
*****************************************************************************/
/**
* Searches the database for an object matching the specified criteria.
*
* @return 0 if a key was found; else BLE_HS_ENOENT.
*/
int
ble_store_config_read(int obj_type, const union ble_store_key *key,
union ble_store_value *value)
{
int rc;
switch (obj_type) {
case BLE_STORE_OBJ_TYPE_PEER_SEC:
/* An encryption procedure (bonding) is being attempted. The nimble
* stack is asking us to look in our key database for a long-term key
* corresponding to the specified ediv and random number.
*
* Perform a key lookup and populate the context object with the
* result. The nimble stack will use this key if this function returns
* success.
*/
BLE_HS_LOG(DEBUG, "looking up peer sec; ");
ble_store_config_print_key_sec(&key->sec);
BLE_HS_LOG(DEBUG, "\n");
rc = ble_store_config_read_peer_sec(&key->sec, &value->sec);
return rc;
case BLE_STORE_OBJ_TYPE_OUR_SEC:
BLE_HS_LOG(DEBUG, "looking up our sec; ");
ble_store_config_print_key_sec(&key->sec);
BLE_HS_LOG(DEBUG, "\n");
rc = ble_store_config_read_our_sec(&key->sec, &value->sec);
return rc;
case BLE_STORE_OBJ_TYPE_CCCD:
rc = ble_store_config_read_cccd(&key->cccd, &value->cccd);
return rc;
default:
return BLE_HS_ENOTSUP;
}
}
/**
* Adds the specified object to the database.
*
* @return 0 on success;
* BLE_HS_ESTORE_CAP if the database is full.
*/
int
ble_store_config_write(int obj_type, const union ble_store_value *val)
{
int rc;
switch (obj_type) {
case BLE_STORE_OBJ_TYPE_PEER_SEC:
rc = ble_store_config_write_peer_sec(&val->sec);
return rc;
case BLE_STORE_OBJ_TYPE_OUR_SEC:
rc = ble_store_config_write_our_sec(&val->sec);
return rc;
case BLE_STORE_OBJ_TYPE_CCCD:
rc = ble_store_config_write_cccd(&val->cccd);
return rc;
default:
return BLE_HS_ENOTSUP;
}
}
int
ble_store_config_delete(int obj_type, const union ble_store_key *key)
{
int rc;
switch (obj_type) {
case BLE_STORE_OBJ_TYPE_PEER_SEC:
rc = ble_store_config_delete_peer_sec(&key->sec);
return rc;
case BLE_STORE_OBJ_TYPE_OUR_SEC:
rc = ble_store_config_delete_our_sec(&key->sec);
return rc;
case BLE_STORE_OBJ_TYPE_CCCD:
rc = ble_store_config_delete_cccd(&key->cccd);
return rc;
default:
return BLE_HS_ENOTSUP;
}
}
void
ble_store_config_init(void)
{
/* Ensure this function only gets called by sysinit. */
SYSINIT_ASSERT_ACTIVE();
ble_hs_cfg.store_read_cb = ble_store_config_read;
ble_hs_cfg.store_write_cb = ble_store_config_write;
ble_hs_cfg.store_delete_cb = ble_store_config_delete;
/* Re-initialize BSS values in case of unit tests. */
ble_store_config_num_our_secs = 0;
ble_store_config_num_peer_secs = 0;
ble_store_config_num_cccds = 0;
ble_store_config_conf_init();
}
@@ -0,0 +1,231 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#include "syscfg/syscfg.h"
#if MYNEWT_VAL(BLE_STORE_CONFIG_PERSIST)
#include <inttypes.h>
#include <string.h>
#include "sysinit/sysinit.h"
#include "host/ble_hs.h"
#include "config/config.h"
#include "base64/base64.h"
#include "store/config/ble_store_config.h"
#include "ble_store_config_priv.h"
static int
ble_store_config_conf_set(int argc, char **argv, char *val);
static int
ble_store_config_conf_export(void (*func)(char *name, char *val),
enum conf_export_tgt tgt);
static struct conf_handler ble_store_config_conf_handler = {
.ch_name = "ble_hs",
.ch_get = NULL,
.ch_set = ble_store_config_conf_set,
.ch_commit = NULL,
.ch_export = ble_store_config_conf_export
};
#define BLE_STORE_CONFIG_SEC_ENCODE_SZ \
BASE64_ENCODE_SIZE(sizeof (struct ble_store_value_sec))
#define BLE_STORE_CONFIG_SEC_SET_ENCODE_SZ \
(MYNEWT_VAL(BLE_STORE_MAX_BONDS) * BLE_STORE_CONFIG_SEC_ENCODE_SZ + 1)
#define BLE_STORE_CONFIG_CCCD_ENCODE_SZ \
BASE64_ENCODE_SIZE(sizeof (struct ble_store_value_cccd))
#define BLE_STORE_CONFIG_CCCD_SET_ENCODE_SZ \
(MYNEWT_VAL(BLE_STORE_MAX_CCCDS) * BLE_STORE_CONFIG_CCCD_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)
{
int arr_size;
arr_size = obj_sz * num_objs;
assert(arr_size <= buf_sz);
base64_encode(arr, arr_size, out_buf, 1);
}
static int
ble_store_config_deserialize_arr(const char *enc,
void *out_arr,
int obj_sz,
int *out_num_objs)
{
int len;
len = base64_decode(enc, out_arr);
if (len < 0) {
return OS_EINVAL;
}
*out_num_objs = len / obj_sz;
return 0;
}
static int
ble_store_config_conf_set(int argc, char **argv, char *val)
{
int rc;
if (argc == 1) {
if (strcmp(argv[0], "our_sec") == 0) {
rc = ble_store_config_deserialize_arr(
val,
ble_store_config_our_secs,
sizeof *ble_store_config_our_secs,
&ble_store_config_num_our_secs);
return rc;
} else if (strcmp(argv[0], "peer_sec") == 0) {
rc = ble_store_config_deserialize_arr(
val,
ble_store_config_peer_secs,
sizeof *ble_store_config_peer_secs,
&ble_store_config_num_peer_secs);
return rc;
} else if (strcmp(argv[0], "cccd") == 0) {
rc = ble_store_config_deserialize_arr(
val,
ble_store_config_cccds,
sizeof *ble_store_config_cccds,
&ble_store_config_num_cccds);
return rc;
}
}
return OS_ENOENT;
}
static int
ble_store_config_conf_export(void (*func)(char *name, char *val),
enum conf_export_tgt tgt)
{
union {
char sec[BLE_STORE_CONFIG_SEC_SET_ENCODE_SZ];
char cccd[BLE_STORE_CONFIG_CCCD_SET_ENCODE_SZ];
} buf;
ble_store_config_serialize_arr(ble_store_config_our_secs,
sizeof *ble_store_config_our_secs,
ble_store_config_num_our_secs,
buf.sec,
sizeof buf.sec);
func("ble_hs/our_sec", buf.sec);
ble_store_config_serialize_arr(ble_store_config_peer_secs,
sizeof *ble_store_config_peer_secs,
ble_store_config_num_peer_secs,
buf.sec,
sizeof buf.sec);
func("ble_hs/peer_sec", buf.sec);
ble_store_config_serialize_arr(ble_store_config_cccds,
sizeof *ble_store_config_cccds,
ble_store_config_num_cccds,
buf.cccd,
sizeof buf.cccd);
func("ble_hs/cccd", buf.cccd);
return 0;
}
static int
ble_store_config_persist_sec_set(const char *setting_name,
const struct ble_store_value_sec *secs,
int num_secs)
{
char buf[BLE_STORE_CONFIG_SEC_SET_ENCODE_SZ];
int rc;
ble_store_config_serialize_arr(secs, sizeof *secs, num_secs,
buf, sizeof buf);
rc = conf_save_one(setting_name, buf);
if (rc != 0) {
return BLE_HS_ESTORE_FAIL;
}
return 0;
}
int
ble_store_config_persist_our_secs(void)
{
int rc;
rc = ble_store_config_persist_sec_set("ble_hs/our_sec",
ble_store_config_our_secs,
ble_store_config_num_our_secs);
if (rc != 0) {
return rc;
}
return 0;
}
int
ble_store_config_persist_peer_secs(void)
{
int rc;
rc = ble_store_config_persist_sec_set("ble_hs/peer_sec",
ble_store_config_peer_secs,
ble_store_config_num_peer_secs);
if (rc != 0) {
return rc;
}
return 0;
}
int
ble_store_config_persist_cccds(void)
{
char buf[BLE_STORE_CONFIG_CCCD_SET_ENCODE_SZ];
int rc;
ble_store_config_serialize_arr(ble_store_config_cccds,
sizeof *ble_store_config_cccds,
ble_store_config_num_cccds,
buf,
sizeof buf);
rc = conf_save_one("ble_hs/cccd", buf);
if (rc != 0) {
return BLE_HS_ESTORE_FAIL;
}
return 0;
}
void
ble_store_config_conf_init(void)
{
int rc;
rc = conf_register(&ble_store_config_conf_handler);
SYSINIT_PANIC_ASSERT_MSG(rc == 0,
"Failed to register ble_store_config conf");
}
#endif /* MYNEWT_VAL(BLE_STORE_CONFIG_PERSIST) */
@@ -0,0 +1,59 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#ifndef H_BLE_STORE_CONFIG_PRIV_
#define H_BLE_STORE_CONFIG_PRIV_
#ifdef __cplusplus
extern "C" {
#endif
extern struct ble_store_value_sec
ble_store_config_our_secs[MYNEWT_VAL(BLE_STORE_MAX_BONDS)];
extern int ble_store_config_num_our_secs;
extern struct ble_store_value_sec
ble_store_config_peer_secs[MYNEWT_VAL(BLE_STORE_MAX_BONDS)];
extern int ble_store_config_num_peer_secs;
extern struct ble_store_value_cccd
ble_store_config_cccds[MYNEWT_VAL(BLE_STORE_MAX_CCCDS)];
extern int ble_store_config_num_cccds;
#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);
void ble_store_config_conf_init(void);
#else
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 void ble_store_config_conf_init(void) { }
#endif /* MYNEWT_VAL(BLE_STORE_CONFIG_PERSIST) */
#ifdef __cplusplus
}
#endif
#endif
+25
View File
@@ -0,0 +1,25 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
#
# Package: net/nimble/host
syscfg.defs:
BLE_STORE_CONFIG_PERSIST:
description: >
Whether to save data to sys/config, or just keep it in RAM.
value: 1
+4 -1
View File
@@ -18,7 +18,10 @@
#
pkg.name: net/nimble/host/store/ram
pkg.description: RAM-based persistence layer for the NimBLE host.
pkg.description: >
DEPRECATED; for a RAM-only BLE store, use store/config and set
BLE_STORE_CONFIG_PERSIST to 0. RAM-based persistence layer for the NimBLE
host.
pkg.author: "Apache Mynewt <[email protected]>"
pkg.homepage: "http://mynewt.apache.org/"
pkg.keywords:
+10 -5
View File
@@ -322,10 +322,15 @@ syscfg.defs:
# Store settings.
BLE_STORE_MAX_BONDS:
description: >
Number of bonds to persist before recycling old ones.
value: 4
Maximum number of bonds that can be persisted. Note: increasing
this value may also require increasing the capacity of the
underlying storage mechanism.
value: 3
BLE_STORE_MAX_CCCDS:
description: >
Number of client characteristic configuration descriptors to
persist before recycling old ones.
value: 16
Maximum number of client characteristic configuration descriptors
that can be persisted. Note: increasing this value may also
require increasing the capacity of the underlying storage
mechanism.
value: 8
+1 -1
View File
@@ -25,7 +25,7 @@ pkg.keywords:
pkg.deps:
- test/testutil
- net/nimble/host
- net/nimble/host/store/ram
- net/nimble/host/store/config
pkg.deps.SELFTEST:
- sys/console/stub
+4 -4
View File
@@ -26,7 +26,7 @@
#include "nimble/ble_hci_trans.h"
#include "host/ble_hs_adv.h"
#include "host/ble_hs_id.h"
#include "store/ram/ble_store_ram.h"
#include "store/config/ble_store_config.h"
#include "transport/ram/ble_hci_ram.h"
#include "ble_hs_test_util.h"
@@ -2328,7 +2328,7 @@ ble_hs_test_util_store_read(int obj_type, const union ble_store_key *key,
ble_sm_test_store_obj_type = obj_type;
ble_sm_test_store_key = *key;
rc = ble_store_ram_read(obj_type, key, value);
rc = ble_store_config_read(obj_type, key, value);
ble_sm_test_store_value = *value;
return rc;
@@ -2341,7 +2341,7 @@ ble_hs_test_util_store_write(int obj_type, const union ble_store_value *value)
ble_sm_test_store_obj_type = obj_type;
rc = ble_store_ram_write(obj_type, value);
rc = ble_store_config_write(obj_type, value);
ble_sm_test_store_value = *value;
return rc;
@@ -2355,7 +2355,7 @@ ble_hs_test_util_store_delete(int obj_type, const union ble_store_key *key)
ble_sm_test_store_obj_type = obj_type;
ble_sm_test_store_key = *key;
rc = ble_store_ram_delete(obj_type, key);
rc = ble_store_config_delete(obj_type, key);
return rc;
}
-1
View File
@@ -26,7 +26,6 @@
#include "host/ble_sm.h"
#include "host/ble_hs_test.h"
#include "host/ble_hs_id.h"
#include "store/ram/ble_store_ram.h"
#include "ble_hs_test_util.h"
#include "ble_sm_test_util.h"
+40 -12
View File
@@ -115,7 +115,7 @@ ble_store_test_util_overflow_sec(int is_our_sec)
TEST_CASE(ble_store_test_peers)
{
struct ble_store_value_sec secs[4] = {
struct ble_store_value_sec secs[3] = {
{
.peer_addr = { BLE_ADDR_PUBLIC, { 1, 2, 3, 4, 5, 6 } },
.ltk_present = 1,
@@ -129,12 +129,8 @@ TEST_CASE(ble_store_test_peers)
.peer_addr = { BLE_ADDR_PUBLIC, { 2, 3, 4, 5, 6, 7 } },
.ltk_present = 1,
},
{
.peer_addr = { BLE_ADDR_RANDOM, { 3, 4, 5, 6, 7, 8 } },
.ltk_present = 1,
},
};
ble_addr_t peer_addrs[4];
ble_addr_t peer_addrs[3];
int num_addrs;
int rc;
int i;
@@ -188,6 +184,9 @@ TEST_CASE(ble_store_test_delete_peer)
.chr_val_handle = 5,
},
};
union ble_store_value value;
union ble_store_key key;
int count;
int rc;
int i;
@@ -212,6 +211,35 @@ TEST_CASE(ble_store_test_delete_peer)
/* Ensure all traces of first peer have been removed. */
ble_store_test_util_verify_peer_deleted(&secs[0].peer_addr);
/* Ensure second peer data is still intact. */
ble_store_key_from_value_sec(&key.sec, secs + 1);
rc = ble_store_util_count(BLE_STORE_OBJ_TYPE_OUR_SEC, &count);
TEST_ASSERT_FATAL(rc == 0);
TEST_ASSERT(count == 1);
rc = ble_store_read_our_sec(&key.sec, &value.sec);
TEST_ASSERT_FATAL(rc == 0);
TEST_ASSERT(memcmp(&value.sec, secs + 1, sizeof value.sec) == 0);
rc = ble_store_util_count(BLE_STORE_OBJ_TYPE_PEER_SEC, &count);
TEST_ASSERT_FATAL(rc == 0);
TEST_ASSERT(count == 1);
rc = ble_store_read_peer_sec(&key.sec, &value.sec);
TEST_ASSERT_FATAL(rc == 0);
TEST_ASSERT(memcmp(&value.sec, secs + 1, sizeof value.sec) == 0);
ble_store_key_from_value_cccd(&key.cccd, cccds + 2);
rc = ble_store_util_count(BLE_STORE_OBJ_TYPE_CCCD, &count);
TEST_ASSERT_FATAL(rc == 0);
TEST_ASSERT(count == 1);
rc = ble_store_read_cccd(&key.cccd, &value.cccd);
TEST_ASSERT_FATAL(rc == 0);
TEST_ASSERT(memcmp(&value.cccd, cccds + 2, sizeof value.cccd) == 0);
/* Delete second peer. */
rc = ble_store_util_delete_peer(&secs[1].peer_addr);
TEST_ASSERT_FATAL(rc == 0);
@@ -272,15 +300,15 @@ TEST_CASE(ble_store_test_count)
/* Write some test data. */
for (i = 0; i < 4; i++) {
for (i = 0; i < 3; i++) {
rc = ble_store_write_our_sec(secs + i);
TEST_ASSERT_FATAL(rc == 0);
}
for (i = 0; i < 3; i++) {
for (i = 0; i < 2; i++) {
rc = ble_store_write_peer_sec(secs + i);
TEST_ASSERT_FATAL(rc == 0);
}
for (i = 0; i < 2; i++) {
for (i = 0; i < 1; i++) {
rc = ble_store_write_cccd(cccds + i);
TEST_ASSERT_FATAL(rc == 0);
}
@@ -288,15 +316,15 @@ TEST_CASE(ble_store_test_count)
/*** Verify counts after populating store. */
rc = ble_store_util_count(BLE_STORE_OBJ_TYPE_OUR_SEC, &count);
TEST_ASSERT_FATAL(rc == 0);
TEST_ASSERT(count == 4);
TEST_ASSERT(count == 3);
rc = ble_store_util_count(BLE_STORE_OBJ_TYPE_PEER_SEC, &count);
TEST_ASSERT_FATAL(rc == 0);
TEST_ASSERT(count == 3);
TEST_ASSERT(count == 2);
rc = ble_store_util_count(BLE_STORE_OBJ_TYPE_CCCD, &count);
TEST_ASSERT_FATAL(rc == 0);
TEST_ASSERT(count == 2);
TEST_ASSERT(count == 1);
}
TEST_CASE(ble_store_test_overflow)
+1
View File
@@ -28,3 +28,4 @@ syscfg.vals:
BLE_SM_SC: 1
MSYS_1_BLOCK_COUNT: 100
BLE_L2CAP_COC_MAX_NUM: 1
CONFIG_FCB: 1