Bluetooth: Remove bt_storage API

The same functionality is now supported by the settings-based
solution, so remove bt_storage out of the way. There were stubs in
bt_storage to handle per-peer information (e.g. pairing keys) but this
was never actually implemented in full. The next step is to add this
support to the settings-based solution.

Leave the code for generating temporary IRK and identity address in
case BT_SETTINGS is not enabled. Also leave the code for using vendor
HCI to read the identity address, in which case the settings
implementation will not touch it.

Introduce a new bt_unpair() API to replace the removed
bt_storage_clear(), since the latter was actually doing more than just
storage management: it was also handling runtime storage of pairing
information. Later, the bt_unpair() implementation will be extended to
clear settings-based pairing storage.

There is one feature that the bt shell module looses: the ability to
give a specific identity address to the "init" command as a parameter.
We might look later in the future if this is really needed, and add a
separate API for this.

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
This commit is contained in:
Johan Hedberg 2018-04-27 10:31:13 +03:00 committed by Anas Nashif
commit d22b7c9f2d
11 changed files with 106 additions and 592 deletions

View file

@ -126,12 +126,6 @@ Logical Link Control and Adaptation Protocol (L2CAP)
.. doxygengroup:: bt_l2cap .. doxygengroup:: bt_l2cap
:project: Zephyr :project: Zephyr
Persistent Storage
******************
.. doxygengroup:: bt_storage
:project: Zephyr
Serial Port Emulation (RFCOMM) Serial Port Emulation (RFCOMM)
****************************** ******************************

View file

@ -474,6 +474,15 @@ int bt_br_set_discoverable(bool enable);
*/ */
int bt_br_set_connectable(bool enable); int bt_br_set_connectable(bool enable);
/** Clear pairing information.
*
* @param addr Remote address, NULL or BT_ADDR_LE_ANY to clear all remote
* devices.
*
* @return 0 on success or negative error value on failure.
*/
int bt_unpair(const bt_addr_le_t *addr);
/** /**
* @} * @}
*/ */

View file

@ -1,146 +0,0 @@
/** @file
* @brief Bluetooth subsystem persistent storage APIs.
*/
/*
* Copyright (c) 2016 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef __BT_STORAGE_H
#define __BT_STORAGE_H
/**
* @brief Persistent Storage
* @defgroup bt_storage Persistent Storage
* @ingroup bluetooth
* @{
*/
#include <sys/types.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/hci.h>
#ifdef __cplusplus
extern "C" {
#endif
/** Well known storage keys */
enum {
/** Identity Address.
* Type: bt_addr_le_t (7 bytes)
*/
BT_STORAGE_ID_ADDR,
/** Local Identity Resolving Key.
* Type: u8_t key[16]
*/
BT_STORAGE_LOCAL_IRK,
/** List of addresses of remote devices.
* Type: bt_addr_le_t addrs[n] (length is variable).
*
* This is only used for reading. Modification of the list happens
* implicitly by writing entries for each remote device. This value
* is only used with the local storage, i.e. NULL as the target
* bt_addr_le_t passed to the read callback.
*/
BT_STORAGE_ADDRESSES,
/** Slave Long Term Key for legacy pairing.
* Type: struct bt_storage_ltk
*/
BT_STORAGE_SLAVE_LTK,
/** Long Term Key for legacy pairing.
* Type: struct bt_storage_ltk
*/
BT_STORAGE_LTK,
/** Identity Resolving Key
* Type: u8_t key[16]
*/
BT_STORAGE_IRK,
};
/** LTK key flags */
enum {
/* Key has been generated with MITM protection */
BT_STORAGE_LTK_AUTHENTICATED = BIT(0),
/* Key has been generated using the LE Secure Connection pairing */
BT_STORAGE_LTK_SC = BIT(1),
};
struct bt_storage_ltk {
u8_t flags;
/* Encryption key size used to generate key */
u8_t size;
u16_t ediv;
u8_t rand[8];
u8_t val[16];
};
struct bt_storage {
/** Read the value of a key from storage.
*
* @param addr Remote address or NULL for local storage
* @param key BT_STORAGE_* key to read
* @param data Memory location to place the data
* @param length Maximum number of bytes to read
*
* @return Number of bytes read or negative error value on
* failure.
*/
ssize_t (*read)(const bt_addr_le_t *addr, u16_t key,
void *data, size_t length);
/** Write the value of a key to storage.
*
* @param addr Remote address or NULL for local storage
* @param key BT_STORAGE_* key to write
* @param data Memory location of the data
* @param length Number of bytes to write
*
* @return Number of bytes written or negative error value on
* failure.
*/
ssize_t (*write)(const bt_addr_le_t *addr, u16_t key,
const void *data, size_t length);
/** Clear all keys for a specific address
*
* @param addr Remote address, BT_ADDR_LE_ANY for all
* remote devices, or NULL for local storage.
*
* @return 0 on success or negative error value on failure.
*/
int (*clear)(const bt_addr_le_t *addr);
};
/** Register callbacks for storage handling.
*
* @param storage Callback struct.
*/
void bt_storage_register(const struct bt_storage *storage);
/** Clear all storage keys for a specific address
*
* @param addr Remote address, NULL for local storage or
* BT_ADDR_LE_ANY to clear all remote devices.
*
* @return 0 on success or negative error value on failure.
*/
int bt_storage_clear(const bt_addr_le_t *addr);
#ifdef __cplusplus
}
#endif
/**
* @}
*/
#endif /* __BT_STORAGE_H */

View file

@ -1,11 +1,6 @@
zephyr_library() zephyr_library()
zephyr_library_link_libraries(subsys__bluetooth) zephyr_library_link_libraries(subsys__bluetooth)
if(CONFIG_BT_INTERNAL_STORAGE)
zephyr_library_sources(storage.c)
zephyr_library_link_libraries(subsys__fs)
endif()
zephyr_library_sources_ifdef(CONFIG_BT_HCI_RAW hci_raw.c) zephyr_library_sources_ifdef(CONFIG_BT_HCI_RAW hci_raw.c)
zephyr_library_sources_ifdef(CONFIG_BT_DEBUG_MONITOR monitor.c) zephyr_library_sources_ifdef(CONFIG_BT_DEBUG_MONITOR monitor.c)
zephyr_library_sources_ifdef(CONFIG_BT_TINYCRYPT_ECC hci_ecc.c) zephyr_library_sources_ifdef(CONFIG_BT_TINYCRYPT_ECC hci_ecc.c)

View file

@ -148,15 +148,6 @@ config BT_SETTINGS
which case it's more efficient to load all settings in one go, which case it's more efficient to load all settings in one go,
instead of each subsystem doing it independently. instead of each subsystem doing it independently.
config BT_INTERNAL_STORAGE
bool "Use an internal persistent storage handler"
depends on FILE_SYSTEM
depends on PRINTK
help
When selected the application doesn't need to register its own
persistent storage handlers through the bt_storage API, rather
an internal default handler is used for this.
if BT_CONN if BT_CONN
if BT_HCI_ACL_FLOW_CONTROL if BT_HCI_ACL_FLOW_CONTROL

View file

@ -25,7 +25,6 @@
#include <bluetooth/hci.h> #include <bluetooth/hci.h>
#include <bluetooth/hci_vs.h> #include <bluetooth/hci_vs.h>
#include <bluetooth/hci_driver.h> #include <bluetooth/hci_driver.h>
#include <bluetooth/storage.h>
#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_DEBUG_HCI_CORE) #define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_DEBUG_HCI_CORE)
#include "common/log.h" #include "common/log.h"
@ -78,8 +77,6 @@ struct bt_dev bt_dev = {
static bt_ready_cb_t ready_cb; static bt_ready_cb_t ready_cb;
const struct bt_storage *bt_storage;
static bt_le_scan_cb_t *scan_dev_found_cb; static bt_le_scan_cb_t *scan_dev_found_cb;
static u8_t pub_key[64]; static u8_t pub_key[64];
@ -1272,6 +1269,53 @@ static int set_flow_control(void)
return bt_hci_cmd_send_sync(BT_HCI_OP_SET_CTL_TO_HOST_FLOW, buf, NULL); return bt_hci_cmd_send_sync(BT_HCI_OP_SET_CTL_TO_HOST_FLOW, buf, NULL);
} }
#endif /* CONFIG_BT_HCI_ACL_FLOW_CONTROL */ #endif /* CONFIG_BT_HCI_ACL_FLOW_CONTROL */
static int bt_clear_all_pairings(void)
{
bt_conn_disconnect_all();
if (IS_ENABLED(CONFIG_BT_SMP)) {
bt_keys_clear_all();
}
if (IS_ENABLED(CONFIG_BT_BREDR)) {
bt_keys_link_key_clear_addr(NULL);
}
return 0;
}
int bt_unpair(const bt_addr_le_t *addr)
{
struct bt_conn *conn;
if (!addr || !bt_addr_le_cmp(addr, BT_ADDR_LE_ANY)) {
return bt_clear_all_pairings();
}
conn = bt_conn_lookup_addr_le(addr);
if (conn) {
bt_conn_disconnect(conn, BT_HCI_ERR_REMOTE_USER_TERM_CONN);
bt_conn_unref(conn);
}
if (IS_ENABLED(CONFIG_BT_BREDR)) {
/* LE Public may indicate BR/EDR as well */
if (addr->type == BT_ADDR_LE_PUBLIC) {
bt_keys_link_key_clear_addr(&addr->a);
}
}
if (IS_ENABLED(CONFIG_BT_SMP)) {
struct bt_keys *keys = bt_keys_find_addr(addr);
if (keys) {
bt_keys_clear(keys);
}
}
return 0;
}
#endif /* CONFIG_BT_CONN */ #endif /* CONFIG_BT_CONN */
#if defined(CONFIG_BT_BREDR) #if defined(CONFIG_BT_BREDR)
@ -4050,20 +4094,30 @@ int bt_addr_le_create_static(bt_addr_le_t *addr)
return 0; return 0;
} }
static int set_static_addr(void) int bt_set_static_addr(void)
{ {
int err; int err;
if (bt_storage) { if (bt_dev.id_addr.type != BT_ADDR_LE_RANDOM ||
ssize_t ret; (bt_dev.id_addr.a.val[5] & 0xc0) != 0xc0) {
BT_ERR("Only static random address supported as identity");
ret = bt_storage->read(NULL, BT_STORAGE_ID_ADDR, return -EINVAL;
&bt_dev.id_addr, sizeof(bt_dev.id_addr));
if (ret == sizeof(bt_dev.id_addr)) {
goto set_addr;
}
} }
err = set_random_address(&bt_dev.id_addr.a);
if (err) {
return err;
}
atomic_set_bit(bt_dev.flags, BT_DEV_ID_STATIC_RANDOM);
return 0;
}
static int setup_id_addr(void)
{
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 */
if (bt_dev.vs_commands[1] & BIT(0)) { if (bt_dev.vs_commands[1] & BIT(0)) {
@ -4082,7 +4136,7 @@ static int set_static_addr(void)
bt_dev.id_addr.type = BT_ADDR_LE_RANDOM; bt_dev.id_addr.type = BT_ADDR_LE_RANDOM;
bt_addr_copy(&bt_dev.id_addr.a, &rp->a[0].bdaddr); bt_addr_copy(&bt_dev.id_addr.a, &rp->a[0].bdaddr);
net_buf_unref(rsp); net_buf_unref(rsp);
goto set_addr; return bt_set_static_addr();
} }
BT_WARN("No static addresses stored in controller"); BT_WARN("No static addresses stored in controller");
@ -4093,40 +4147,21 @@ static int set_static_addr(void)
generate: generate:
#endif #endif
BT_DBG("Generating new static random address");
err = bt_addr_le_create_static(&bt_dev.id_addr); if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
if (err) { BT_DBG("Expecing identity addr to be handled by settings");
return err; return 0;
}
if (bt_storage) {
ssize_t ret;
ret = bt_storage->write(NULL, BT_STORAGE_ID_ADDR,
&bt_dev.id_addr,
sizeof(bt_dev.id_addr));
if (ret != sizeof(bt_dev.id_addr)) {
BT_ERR("Unable to store static address");
}
} else { } else {
BT_WARN("Using temporary static random address"); err = bt_addr_le_create_static(&bt_dev.id_addr);
} if (err) {
return err;
}
set_addr: BT_WARN("Using temporary static random address %s",
if (bt_dev.id_addr.type != BT_ADDR_LE_RANDOM || bt_addr_str(&bt_dev.id_addr.a));
(bt_dev.id_addr.a.val[5] & 0xc0) != 0xc0) {
BT_ERR("Only static random address supported as identity");
return -EINVAL;
}
err = set_random_address(&bt_dev.id_addr.a); return bt_set_static_addr();
if (err) {
return err;
} }
atomic_set_bit(bt_dev.flags, BT_DEV_ID_STATIC_RANDOM);
return 0;
} }
#if defined(CONFIG_BT_DEBUG) #if defined(CONFIG_BT_DEBUG)
@ -4314,7 +4349,7 @@ static int hci_init(void)
if (!bt_addr_le_cmp(&bt_dev.id_addr, BT_ADDR_LE_ANY) || 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)) { !bt_addr_le_cmp(&bt_dev.id_addr, 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 = set_static_addr(); err = setup_id_addr();
if (err) { if (err) {
BT_ERR("Unable to set identity address"); BT_ERR("Unable to set identity address");
return err; return err;
@ -4429,30 +4464,16 @@ int bt_hci_driver_register(const struct bt_hci_driver *drv)
#if defined(CONFIG_BT_PRIVACY) #if defined(CONFIG_BT_PRIVACY)
static int irk_init(void) static int irk_init(void)
{ {
ssize_t err; if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
BT_DBG("Expecting settings to handle local IRK");
if (bt_storage) {
err = bt_storage->read(NULL, BT_STORAGE_LOCAL_IRK, &bt_dev.irk,
sizeof(bt_dev.irk));
if (err == sizeof(bt_dev.irk)) {
return 0;
}
}
BT_DBG("Generating new IRK");
err = bt_rand(bt_dev.irk, sizeof(bt_dev.irk));
if (err) {
return err;
}
if (bt_storage) {
err = bt_storage->write(NULL, BT_STORAGE_LOCAL_IRK, bt_dev.irk,
sizeof(bt_dev.irk));
if (err != sizeof(bt_dev.irk)) {
BT_ERR("Unable to store IRK");
}
} else { } else {
int err;
err = bt_rand(bt_dev.irk, sizeof(bt_dev.irk));
if (err) {
return err;
}
BT_WARN("Using temporary IRK"); BT_WARN("Using temporary IRK");
} }
@ -5133,68 +5154,6 @@ int bt_br_set_discoverable(bool enable)
} }
#endif /* CONFIG_BT_BREDR */ #endif /* CONFIG_BT_BREDR */
void bt_storage_register(const struct bt_storage *storage)
{
bt_storage = storage;
}
static int bt_storage_clear_all(void)
{
if (IS_ENABLED(CONFIG_BT_CONN)) {
bt_conn_disconnect_all();
}
if (IS_ENABLED(CONFIG_BT_SMP)) {
bt_keys_clear_all();
}
if (IS_ENABLED(CONFIG_BT_BREDR)) {
bt_keys_link_key_clear_addr(NULL);
}
if (bt_storage) {
return bt_storage->clear(NULL);
}
return 0;
}
int bt_storage_clear(const bt_addr_le_t *addr)
{
if (!addr) {
return bt_storage_clear_all();
}
if (IS_ENABLED(CONFIG_BT_CONN)) {
struct bt_conn *conn = bt_conn_lookup_addr_le(addr);
if (conn) {
bt_conn_disconnect(conn,
BT_HCI_ERR_REMOTE_USER_TERM_CONN);
bt_conn_unref(conn);
}
}
if (IS_ENABLED(CONFIG_BT_BREDR)) {
/* LE Public may indicate BR/EDR as well */
if (addr->type == BT_ADDR_LE_PUBLIC) {
bt_keys_link_key_clear_addr(&addr->a);
}
}
if (IS_ENABLED(CONFIG_BT_SMP)) {
struct bt_keys *keys = bt_keys_find_addr(addr);
if (keys) {
bt_keys_clear(keys);
}
}
if (bt_storage) {
return bt_storage->clear(addr);
}
return 0;
}
u16_t bt_hci_get_cmd_opcode(struct net_buf *buf) u16_t bt_hci_get_cmd_opcode(struct net_buf *buf)
{ {
return cmd(buf)->opcode; return cmd(buf)->opcode;

View file

@ -166,7 +166,6 @@ struct bt_dev {
}; };
extern struct bt_dev bt_dev; extern struct bt_dev bt_dev;
extern const struct bt_storage *bt_storage;
#if defined(CONFIG_BT_SMP) || defined(CONFIG_BT_BREDR) #if defined(CONFIG_BT_SMP) || defined(CONFIG_BT_BREDR)
extern const struct bt_conn_auth_cb *bt_auth; extern const struct bt_conn_auth_cb *bt_auth;
#endif /* CONFIG_BT_SMP || CONFIG_BT_BREDR */ #endif /* CONFIG_BT_SMP || CONFIG_BT_BREDR */
@ -191,4 +190,6 @@ 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);
int bt_set_static_addr(void);
void bt_dev_show_info(void); void bt_dev_show_info(void);

View file

@ -59,7 +59,7 @@ static void generate_static_addr(void)
return; return;
} }
atomic_set_bit(bt_dev.flags, BT_DEV_ID_STATIC_RANDOM); 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));

View file

@ -1,229 +0,0 @@
/*
* Copyright (c) 2016 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <errno.h>
#include <string.h>
#include <misc/printk.h>
#include <zephyr.h>
#include <init.h>
#include <fs.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/storage.h>
#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_DEBUG_HCI_CORE)
#include "common/log.h"
#define STORAGE_ROOT "/bt"
/* Required file name length for full storage support. If the maximum
* file name length supported by the chosen file system is less than
* this value, then only local keys are supported (/bt/abcd).
*/
#define STORAGE_FILE_NAME_LEN 13
#if MAX_FILE_NAME >= STORAGE_FILE_NAME_LEN
/* /bt/aabbccddeeff0/abcd */
#define STORAGE_PATH_MAX 23
#else
/* /bt/abcd */
#define STORAGE_PATH_MAX 9
#endif
enum storage_access {
STORAGE_READ,
STORAGE_WRITE
};
static int storage_open(const bt_addr_le_t *addr, u16_t key,
enum storage_access access, struct fs_file_t *file)
{
char path[STORAGE_PATH_MAX];
if (addr) {
#if MAX_FILE_NAME >= STORAGE_FILE_NAME_LEN
int len;
len = snprintk(path, sizeof(path),
STORAGE_ROOT "/%02X%02X%02X%02X%02X%02X%u",
addr->a.val[5], addr->a.val[4], addr->a.val[3],
addr->a.val[2], addr->a.val[1], addr->a.val[0],
addr->type);
/* Create the subdirectory if necessary */
if (access == STORAGE_WRITE) {
struct fs_dirent entry;
int err;
err = fs_stat(path, &entry);
if (err) {
err = fs_mkdir(path);
if (err) {
return err;
}
}
}
snprintk(path + len, sizeof(path) - len, "/%04x", key);
#else
return -ENAMETOOLONG;
#endif
} else {
snprintk(path, sizeof(path), STORAGE_ROOT "/%04x", key);
}
return fs_open(file, path);
}
static ssize_t storage_read(const bt_addr_le_t *addr, u16_t key, void *data,
size_t length)
{
struct fs_file_t file;
ssize_t ret;
ret = storage_open(addr, key, STORAGE_READ, &file);
if (ret) {
return ret;
}
ret = fs_read(&file, data, length);
fs_close(&file);
return ret;
}
static ssize_t storage_write(const bt_addr_le_t *addr, u16_t key,
const void *data, size_t length)
{
struct fs_file_t file;
ssize_t ret;
ret = storage_open(addr, key, STORAGE_WRITE, &file);
if (ret) {
return ret;
}
ret = fs_write(&file, data, length);
fs_close(&file);
return ret;
}
static int unlink_recursive(char path[STORAGE_PATH_MAX])
{
size_t path_len;
struct fs_dir_t dir;
int err;
err = fs_opendir(&dir, path);
if (err) {
return err;
}
/* We calculate this up-front so we can keep reusing the same
* buffer for the path when recursing.
*/
path_len = strlen(path);
while (1) {
struct fs_dirent entry;
err = fs_readdir(&dir, &entry);
if (err) {
break;
}
if (entry.name[0] == '\0') {
break;
}
snprintk(path + path_len, STORAGE_PATH_MAX - path_len, "/%s",
entry.name);
if (entry.type == FS_DIR_ENTRY_DIR) {
err = unlink_recursive(path);
} else {
err = fs_unlink(path);
}
if (err) {
break;
}
}
fs_closedir(&dir);
/* Return to the original value */
path[path_len] = '\0';
fs_unlink(path);
return err;
}
static int storage_clear(const bt_addr_le_t *addr)
{
char path[STORAGE_PATH_MAX];
int err;
if (addr) {
#if MAX_FILE_NAME >= STORAGE_FILE_NAME_LEN
snprintk(path, STORAGE_PATH_MAX,
STORAGE_ROOT "/%02X%02X%02X%02X%02X%02X%u",
addr->a.val[5], addr->a.val[4], addr->a.val[3],
addr->a.val[2], addr->a.val[1], addr->a.val[0],
addr->type);
return unlink_recursive(path);
#else
return -ENAMETOOLONG;
#endif
}
/* unlink_recursive() uses the given path as a buffer for
* constructing sub-paths, so we can't give it a string literal
* such as STORAGE_ROOT directly.
*/
strcpy(path, STORAGE_ROOT);
err = unlink_recursive(path);
if (err) {
return err;
}
return fs_mkdir(STORAGE_ROOT);
}
static int storage_init(struct device *unused)
{
static const struct bt_storage storage = {
.read = storage_read,
.write = storage_write,
.clear = storage_clear
};
struct fs_dirent entry;
int err;
err = fs_stat(STORAGE_ROOT, &entry);
if (err) {
BT_WARN("%s doesn't seem to exist (err %d). Creating it.",
STORAGE_ROOT, err);
err = fs_mkdir(STORAGE_ROOT);
if (err) {
BT_ERR("Unable to create %s (err %d)",
STORAGE_ROOT, err);
return err;
}
}
bt_storage_register(&storage);
return 0;
}
SYS_INIT(storage_init, APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT);

View file

@ -23,7 +23,6 @@
#include <bluetooth/conn.h> #include <bluetooth/conn.h>
#include <bluetooth/l2cap.h> #include <bluetooth/l2cap.h>
#include <bluetooth/rfcomm.h> #include <bluetooth/rfcomm.h>
#include <bluetooth/storage.h>
#include <bluetooth/sdp.h> #include <bluetooth/sdp.h>
#include <shell/shell.h> #include <shell/shell.h>
@ -39,7 +38,6 @@
#define DATA_BREDR_MTU 48 #define DATA_BREDR_MTU 48
#define BT_SHELL_MODULE "bt" #define BT_SHELL_MODULE "bt"
static bt_addr_le_t id_addr;
#if defined(CONFIG_BT_CONN) #if defined(CONFIG_BT_CONN)
struct bt_conn *default_conn; struct bt_conn *default_conn;
@ -506,42 +504,6 @@ static int str2bt_addr_le(const char *str, const char *type, bt_addr_le_t *addr)
return 0; return 0;
} }
static ssize_t storage_read(const bt_addr_le_t *addr, u16_t key, void *data,
size_t length)
{
if (addr) {
return -ENOENT;
}
if (key == BT_STORAGE_ID_ADDR && length == sizeof(id_addr) &&
bt_addr_le_cmp(&id_addr, BT_ADDR_LE_ANY)) {
bt_addr_le_copy(data, &id_addr);
return sizeof(id_addr);
}
return -EIO;
}
static ssize_t storage_write(const bt_addr_le_t *addr, u16_t key,
const void *data, size_t length)
{
if (addr) {
return -ENOENT;
}
if (key == BT_STORAGE_ID_ADDR && length == sizeof(id_addr)) {
bt_addr_le_copy(&id_addr, data);
return sizeof(id_addr);
}
return -EIO;
}
static int storage_clear(const bt_addr_le_t *addr)
{
return -ENOSYS;
}
static void bt_ready(int err) static void bt_ready(int err)
{ {
if (err) { if (err) {
@ -560,29 +522,8 @@ static void bt_ready(int err)
static int cmd_init(int argc, char *argv[]) static int cmd_init(int argc, char *argv[])
{ {
static const struct bt_storage storage = {
.read = storage_read,
.write = storage_write,
.clear = storage_clear,
};
int err; int err;
if (argc > 1) {
if (argc < 3) {
printk("Invalid address\n");
return -EINVAL;
}
err = str2bt_addr_le(argv[1], argv[2], &id_addr);
if (err) {
printk("Invalid address (err %d)\n", err);
bt_addr_le_cmp(&id_addr, BT_ADDR_LE_ANY);
return -EINVAL;
}
bt_storage_register(&storage);
}
err = bt_enable(bt_ready); err = bt_enable(bt_ready);
if (err) { if (err) {
printk("Bluetooth init failed (err %d)\n", err); printk("Bluetooth init failed (err %d)\n", err);
@ -944,11 +885,11 @@ static int cmd_clear(int argc, char *argv[])
} }
if (strcmp(argv[1], "all") == 0) { if (strcmp(argv[1], "all") == 0) {
err = bt_storage_clear(NULL); err = bt_unpair(NULL);
if (err) { if (err) {
printk("Failed to clear storage (err %d)\n", err); printk("Failed to clear pairings (err %d)\n", err);
} else { } else {
printk("Storage successfully cleared\n"); printk("Pairings successfully cleared\n");
} }
return 0; return 0;
@ -971,11 +912,11 @@ static int cmd_clear(int argc, char *argv[])
return 0; return 0;
} }
err = bt_storage_clear(&addr); err = bt_unpair(&addr);
if (err) { if (err) {
printk("Failed to clear storage (err %d)\n", err); printk("Failed to clear pairing (err %d)\n", err);
} else { } else {
printk("Storage successfully cleared\n"); printk("Pairing successfully cleared\n");
} }
return 0; return 0;

View file

@ -13,7 +13,6 @@
#include <toolchain.h> #include <toolchain.h>
#include <bluetooth/bluetooth.h> #include <bluetooth/bluetooth.h>
#include <bluetooth/conn.h> #include <bluetooth/conn.h>
#include <bluetooth/storage.h>
#include <misc/byteorder.h> #include <misc/byteorder.h>
#include <net/buf.h> #include <net/buf.h>
@ -608,7 +607,7 @@ static void unpair(const u8_t *data, u16_t len)
goto rsp; goto rsp;
} }
keys: keys:
err = bt_storage_clear(&addr); err = bt_unpair(&addr);
status = err < 0 ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS; status = err < 0 ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS;
rsp: rsp: