Bluetooth: Introduce skeleton for settings-based storage
Introduce a basic skeleton for peristent storage based on the settings subsystem. Also enable support for this to the peripheral sample application, so the new code gets exersized by CI. For now, the implementation provides the same level support as the bt_storage API ever did, i.e. for the identity address and the IRK. Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
This commit is contained in:
parent
f4dcb4593d
commit
b997a283f7
8 changed files with 216 additions and 3 deletions
|
@ -1,3 +1,6 @@
|
||||||
|
# Incresed stack due to settings API usage
|
||||||
|
CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2048
|
||||||
|
|
||||||
CONFIG_BT=y
|
CONFIG_BT=y
|
||||||
CONFIG_BT_DEBUG_LOG=y
|
CONFIG_BT_DEBUG_LOG=y
|
||||||
CONFIG_BT_SMP=y
|
CONFIG_BT_SMP=y
|
||||||
|
@ -7,3 +10,11 @@ CONFIG_BT_ATT_PREPARE_COUNT=2
|
||||||
CONFIG_BT_PRIVACY=y
|
CONFIG_BT_PRIVACY=y
|
||||||
CONFIG_BT_DEVICE_NAME="Test peripheral"
|
CONFIG_BT_DEVICE_NAME="Test peripheral"
|
||||||
CONFIG_BT_DEVICE_APPEARANCE=833
|
CONFIG_BT_DEVICE_APPEARANCE=833
|
||||||
|
|
||||||
|
CONFIG_BT_SETTINGS=y
|
||||||
|
CONFIG_FLASH=y
|
||||||
|
CONFIG_FLASH_PAGE_LAYOUT=y
|
||||||
|
CONFIG_FLASH_MAP=y
|
||||||
|
CONFIG_FCB=y
|
||||||
|
CONFIG_SETTINGS=y
|
||||||
|
CONFIG_SETTINGS_FCB=y
|
||||||
|
|
|
@ -14,6 +14,8 @@
|
||||||
#include <misc/byteorder.h>
|
#include <misc/byteorder.h>
|
||||||
#include <zephyr.h>
|
#include <zephyr.h>
|
||||||
|
|
||||||
|
#include <settings/settings.h>
|
||||||
|
|
||||||
#include <bluetooth/bluetooth.h>
|
#include <bluetooth/bluetooth.h>
|
||||||
#include <bluetooth/hci.h>
|
#include <bluetooth/hci.h>
|
||||||
#include <bluetooth/conn.h>
|
#include <bluetooth/conn.h>
|
||||||
|
@ -242,6 +244,10 @@ static void bt_ready(int err)
|
||||||
dis_init(CONFIG_SOC, "Manufacturer");
|
dis_init(CONFIG_SOC, "Manufacturer");
|
||||||
bt_gatt_service_register(&vnd_svc);
|
bt_gatt_service_register(&vnd_svc);
|
||||||
|
|
||||||
|
if (IS_ENABLED(CONFIG_SETTINGS)) {
|
||||||
|
settings_load();
|
||||||
|
}
|
||||||
|
|
||||||
err = bt_le_adv_start(BT_LE_ADV_CONN, ad, ARRAY_SIZE(ad),
|
err = bt_le_adv_start(BT_LE_ADV_CONN, ad, ARRAY_SIZE(ad),
|
||||||
sd, ARRAY_SIZE(sd));
|
sd, ARRAY_SIZE(sd));
|
||||||
if (err) {
|
if (err) {
|
||||||
|
|
|
@ -13,6 +13,7 @@ zephyr_library_sources_ifdef(CONFIG_BT_A2DP a2dp.c)
|
||||||
zephyr_library_sources_ifdef(CONFIG_BT_AVDTP avdtp.c)
|
zephyr_library_sources_ifdef(CONFIG_BT_AVDTP avdtp.c)
|
||||||
zephyr_library_sources_ifdef(CONFIG_BT_RFCOMM rfcomm.c)
|
zephyr_library_sources_ifdef(CONFIG_BT_RFCOMM rfcomm.c)
|
||||||
zephyr_library_sources_ifdef(CONFIG_BT_TESTING testing.c)
|
zephyr_library_sources_ifdef(CONFIG_BT_TESTING testing.c)
|
||||||
|
zephyr_library_sources_ifdef(CONFIG_BT_SETTINGS settings.c)
|
||||||
|
|
||||||
zephyr_library_sources_ifdef(
|
zephyr_library_sources_ifdef(
|
||||||
CONFIG_BT_BREDR
|
CONFIG_BT_BREDR
|
||||||
|
|
|
@ -95,6 +95,7 @@ config BT_RX_STACK_SIZE
|
||||||
int "Size of the receiving thread stack"
|
int "Size of the receiving thread stack"
|
||||||
depends on BT_HCI_HOST || BT_RECV_IS_RX_THREAD
|
depends on BT_HCI_HOST || BT_RECV_IS_RX_THREAD
|
||||||
default 1024
|
default 1024
|
||||||
|
default 2048 if BT_SETTINGS
|
||||||
default 2048 if BT_MESH
|
default 2048 if BT_MESH
|
||||||
default 512 if BT_HCI_RAW
|
default 512 if BT_HCI_RAW
|
||||||
range 512 65536 if BT_HCI_RAW
|
range 512 65536 if BT_HCI_RAW
|
||||||
|
@ -130,6 +131,23 @@ config BT_HOST_CRYPTO
|
||||||
select TINYCRYPT_SHA256_HMAC
|
select TINYCRYPT_SHA256_HMAC
|
||||||
select TINYCRYPT_SHA256_HMAC_PRNG
|
select TINYCRYPT_SHA256_HMAC_PRNG
|
||||||
|
|
||||||
|
config BT_SETTINGS
|
||||||
|
bool "Store Bluetooth state and configuration persistently"
|
||||||
|
depends on SETTINGS
|
||||||
|
select MPU_ALLOW_FLASH_WRITE if ARM_MPU
|
||||||
|
help
|
||||||
|
When selected, the Bluetooth stack will take care of storing
|
||||||
|
(and restoring) the Bluetooth state (e.g. pairing keys) and
|
||||||
|
configuration persistently in flash.
|
||||||
|
|
||||||
|
When this option has been enabled, it's important that the
|
||||||
|
application makes a call to settings_load() after having done
|
||||||
|
all necessary initialization (e.g. calling bt_enable). The
|
||||||
|
reason settings_load() is handled externally to the stack, is
|
||||||
|
that there may be other subsystems using the settings API, in
|
||||||
|
which case it's more efficient to load all settings in one go,
|
||||||
|
instead of each subsystem doing it independently.
|
||||||
|
|
||||||
config BT_INTERNAL_STORAGE
|
config BT_INTERNAL_STORAGE
|
||||||
bool "Use an internal persistent storage handler"
|
bool "Use an internal persistent storage handler"
|
||||||
depends on FILE_SYSTEM
|
depends on FILE_SYSTEM
|
||||||
|
@ -350,6 +368,12 @@ config BT_TINYCRYPT_ECC
|
||||||
Connections so that Hosts can make use of those.
|
Connections so that Hosts can make use of those.
|
||||||
|
|
||||||
if BT_DEBUG
|
if BT_DEBUG
|
||||||
|
config BT_DEBUG_SETTINGS
|
||||||
|
bool "Bluetooth storage debug"
|
||||||
|
depends on BT_SETTINGS
|
||||||
|
help
|
||||||
|
This option enables debug support for Bluetooth storage.
|
||||||
|
|
||||||
config BT_DEBUG_HCI_CORE
|
config BT_DEBUG_HCI_CORE
|
||||||
bool "Bluetooth HCI core debug"
|
bool "Bluetooth HCI core debug"
|
||||||
help
|
help
|
||||||
|
|
|
@ -41,6 +41,7 @@
|
||||||
#include "l2cap_internal.h"
|
#include "l2cap_internal.h"
|
||||||
#include "smp.h"
|
#include "smp.h"
|
||||||
#include "crypto.h"
|
#include "crypto.h"
|
||||||
|
#include "settings.h"
|
||||||
|
|
||||||
/* Peripheral timeout to initialize Connection Parameter Update procedure */
|
/* Peripheral timeout to initialize Connection Parameter Update procedure */
|
||||||
#define CONN_UPDATE_TIMEOUT K_SECONDS(5)
|
#define CONN_UPDATE_TIMEOUT K_SECONDS(5)
|
||||||
|
@ -4143,7 +4144,7 @@ static const char *ver_str(u8_t ver)
|
||||||
return "unknown";
|
return "unknown";
|
||||||
}
|
}
|
||||||
|
|
||||||
static void show_dev_info(void)
|
void bt_dev_show_info(void)
|
||||||
{
|
{
|
||||||
BT_INFO("Identity: %s", bt_addr_le_str(&bt_dev.id_addr));
|
BT_INFO("Identity: %s", bt_addr_le_str(&bt_dev.id_addr));
|
||||||
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",
|
||||||
|
@ -4154,7 +4155,7 @@ static void show_dev_info(void)
|
||||||
bt_dev.lmp_subversion);
|
bt_dev.lmp_subversion);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
static inline void show_dev_info(void)
|
void bt_dev_show_info(void)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_BT_DEBUG */
|
#endif /* CONFIG_BT_DEBUG */
|
||||||
|
@ -4320,7 +4321,9 @@ static int hci_init(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
show_dev_info();
|
if (!IS_ENABLED(CONFIG_BT_SETTINGS)) {
|
||||||
|
bt_dev_show_info();
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -4549,6 +4552,13 @@ int bt_enable(bt_ready_cb_t cb)
|
||||||
return -EALREADY;
|
return -EALREADY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
|
||||||
|
err = bt_settings_init();
|
||||||
|
if (err) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ready_cb = cb;
|
ready_cb = cb;
|
||||||
|
|
||||||
/* TX thread */
|
/* TX thread */
|
||||||
|
|
|
@ -190,3 +190,5 @@ u16_t bt_hci_get_cmd_opcode(struct net_buf *buf);
|
||||||
struct bt_keys;
|
struct bt_keys;
|
||||||
int bt_id_add(struct bt_keys *keys);
|
int bt_id_add(struct bt_keys *keys);
|
||||||
int bt_id_del(struct bt_keys *keys);
|
int bt_id_del(struct bt_keys *keys);
|
||||||
|
|
||||||
|
void bt_dev_show_info(void);
|
||||||
|
|
152
subsys/bluetooth/host/settings.c
Normal file
152
subsys/bluetooth/host/settings.c
Normal file
|
@ -0,0 +1,152 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018 Intel Corporation
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include <zephyr.h>
|
||||||
|
#include <settings/settings.h>
|
||||||
|
|
||||||
|
#include <bluetooth/bluetooth.h>
|
||||||
|
#include <bluetooth/conn.h>
|
||||||
|
|
||||||
|
#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_DEBUG_SETTINGS)
|
||||||
|
#include "common/log.h"
|
||||||
|
|
||||||
|
#include "hci_core.h"
|
||||||
|
#include "settings.h"
|
||||||
|
|
||||||
|
static int set(int argc, char **argv, char *val)
|
||||||
|
{
|
||||||
|
int len;
|
||||||
|
|
||||||
|
BT_DBG("argc %d argv[0] %s val %s", argc, argv[0], val);
|
||||||
|
|
||||||
|
if (argc != 1) {
|
||||||
|
return -ENOENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strcmp(argv[0], "id")) {
|
||||||
|
len = sizeof(bt_dev.id_addr);
|
||||||
|
settings_bytes_from_str(val, &bt_dev.id_addr, &len);
|
||||||
|
BT_DBG("ID Addr set to %s", bt_addr_le_str(&bt_dev.id_addr));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(CONFIG_BT_PRIVACY)
|
||||||
|
if (!strcmp(argv[0], "irk")) {
|
||||||
|
len = sizeof(bt_dev.irk);
|
||||||
|
settings_bytes_from_str(val, bt_dev.irk, &len);
|
||||||
|
BT_DBG("IRK set to %s", bt_hex(bt_dev.irk, 16));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_BT_PRIVACY */
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void generate_static_addr(void)
|
||||||
|
{
|
||||||
|
char buf[13];
|
||||||
|
char *str;
|
||||||
|
|
||||||
|
BT_DBG("Generating new static random address");
|
||||||
|
|
||||||
|
if (bt_addr_le_create_static(&bt_dev.id_addr)) {
|
||||||
|
BT_ERR("Failed to generate static addr");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
atomic_set_bit(bt_dev.flags, BT_DEV_ID_STATIC_RANDOM);
|
||||||
|
|
||||||
|
BT_DBG("New ID Addr: %s", bt_addr_le_str(&bt_dev.id_addr));
|
||||||
|
|
||||||
|
str = settings_str_from_bytes(&bt_dev.id_addr, sizeof(bt_dev.id_addr),
|
||||||
|
buf, sizeof(buf));
|
||||||
|
if (!str) {
|
||||||
|
BT_ERR("Unable to encode ID Addr as value");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
BT_DBG("Saving ID addr as value %s", str);
|
||||||
|
settings_save_one("bt/id", str);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(CONFIG_BT_PRIVACY)
|
||||||
|
static void generate_irk(void)
|
||||||
|
{
|
||||||
|
char buf[25];
|
||||||
|
char *str;
|
||||||
|
|
||||||
|
BT_DBG("Generating new IRK");
|
||||||
|
|
||||||
|
if (bt_rand(bt_dev.irk, sizeof(bt_dev.irk))) {
|
||||||
|
BT_ERR("Failed to generate IRK");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
BT_DBG("New local IRK: %s", bt_hex(bt_dev.irk, 16));
|
||||||
|
|
||||||
|
str = settings_str_from_bytes(bt_dev.irk, 16, buf, sizeof(buf));
|
||||||
|
if (!str) {
|
||||||
|
BT_ERR("Unable to encode IRK as value");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
BT_DBG("Saving IRK as value %s", str);
|
||||||
|
settings_save_one("bt/irk", str);
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_BT_PRIVACY */
|
||||||
|
|
||||||
|
static int commit(void)
|
||||||
|
{
|
||||||
|
BT_DBG("");
|
||||||
|
|
||||||
|
if (!bt_addr_le_cmp(&bt_dev.id_addr, BT_ADDR_LE_ANY) ||
|
||||||
|
!bt_addr_le_cmp(&bt_dev.id_addr, BT_ADDR_LE_NONE)) {
|
||||||
|
generate_static_addr();
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(CONFIG_BT_PRIVACY)
|
||||||
|
{
|
||||||
|
u8_t zero[16] = { 0 };
|
||||||
|
|
||||||
|
if (!memcmp(bt_dev.irk, zero, 16)) {
|
||||||
|
generate_irk();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_BT_PRIVACY */
|
||||||
|
|
||||||
|
bt_dev_show_info();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct settings_handler bt_settings = {
|
||||||
|
.name = "bt",
|
||||||
|
.h_set = set,
|
||||||
|
.h_commit = commit,
|
||||||
|
};
|
||||||
|
|
||||||
|
int bt_settings_init(void)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
|
||||||
|
BT_DBG("");
|
||||||
|
|
||||||
|
err = settings_subsys_init();
|
||||||
|
if (err) {
|
||||||
|
BT_ERR("settings_subsys_init failed (err %d)", err);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = settings_register(&bt_settings);
|
||||||
|
if (err) {
|
||||||
|
BT_ERR("settings_register failed (err %d)", err);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
7
subsys/bluetooth/host/settings.h
Normal file
7
subsys/bluetooth/host/settings.h
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018 Intel Corporation
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
int bt_settings_init(void);
|
Loading…
Add table
Add a link
Reference in a new issue