Skip to content

Commit ff67879

Browse files
committed
settings: add settings_zblue module.
Change-Id: Ia21bdfc4abe18136e4f5c828dce94a9ee94851f2 Signed-off-by: liuxiang18 <[email protected]>
1 parent 17f15b8 commit ff67879

File tree

3 files changed

+355
-0
lines changed

3 files changed

+355
-0
lines changed

subsys/settings/Kconfig

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ choice SETTINGS_BACKEND
3535
default SETTINGS_NVS if NVS
3636
default SETTINGS_FCB if FCB
3737
default SETTINGS_FILE if FILE_SYSTEM
38+
default SETTINGS_VELA if BLUETOOTH_STORAGE_PROPERTY_SUPPORT
3839
default SETTINGS_NONE
3940
help
4041
Storage back-end to be used by the settings subsystem.
@@ -45,6 +46,12 @@ config SETTINGS_FCB
4546
help
4647
Use FCB as a settings storage back-end.
4748

49+
config SETTINGS_VELA
50+
bool "VELA"
51+
depends on BLUETOOTH_STORAGE_PROPERTY_SUPPORT
52+
help
53+
Use VELA as a settings storage back-end.
54+
4855
config SETTINGS_FILE
4956
bool "File"
5057
depends on FILE_SYSTEM
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
/*
2+
* Copyright (c) 2025 liuxiang
3+
* Copyright (c) 2019 Xiaomi Corporation.
4+
*
5+
* SPDX-License-Identifier: Apache-2.0
6+
*/
7+
8+
#ifndef __SETTINGS_NVS_H_
9+
#define __SETTINGS_NVS_H_
10+
11+
#include <zephyr/settings/settings.h>
12+
#include <zephyr/bluetooth/addr.h>
13+
14+
#ifdef __cplusplus
15+
extern "C" {
16+
#endif
17+
18+
/* In the NVS backend, each setting is stored in two NVS entries:
19+
* 1. setting's name
20+
* 2. setting's value
21+
*
22+
* The NVS entry ID for the setting's value is determined implicitly based on
23+
* the ID of the NVS entry for the setting's name, once that is found. The
24+
* difference between name and value ID is constant and equal to
25+
* NVS_NAME_ID_OFFSET.
26+
*
27+
* Setting's name entries start from NVS_NAMECNT_ID + 1. The entry at
28+
* NVS_NAMECNT_ID is used to store the largest name ID in use.
29+
*
30+
* Deleted records will not be found, only the last record will be
31+
* read.
32+
*/
33+
34+
struct settings_vela {
35+
struct settings_store cf_store;
36+
};
37+
38+
struct settings_vela_save_fn_arg {
39+
bt_addr_le_t addr;
40+
const char* value;
41+
};
42+
43+
struct bt_settings_vela_cb {
44+
#if defined(CONFIG_BT_CLASSIC)
45+
/** @brief notify that bredr pairing link key generated.
46+
*
47+
* The callback notifies the application that the link key has been
48+
* generated during the pairing procedure.
49+
*
50+
* @param conn Connection object.
51+
* @param key Link key.
52+
* @param key_type Link key type.
53+
*/
54+
int (*linkkey_notify)(uint8_t dev_id, bt_addr_le_t* addr, const char* key_value, uint8_t value_len);
55+
56+
int (*linkkey_load)(bt_addr_le_t* addr, uint8_t* key_value, uint8_t value_len);
57+
#endif
58+
int (*ltk_notify)(uint8_t dev_id, uint8_t id, bt_addr_le_t* addr, const char* key_value, uint8_t value_len);
59+
60+
int (*ltk_load)(bt_addr_le_t* addr, uint8_t* key_value, uint8_t value_len);
61+
62+
/** @internal Internally used field for list handling */
63+
sys_snode_t _node;
64+
};
65+
66+
/** @brief Register connection callbacks.
67+
*
68+
* Register callbacks to monitor the state of connections.
69+
*
70+
* @param cb Callback struct. Must point to memory that remains valid.
71+
*
72+
* @retval 0 Success.
73+
* @retval -EEXIST if @p cb was already registered.
74+
*/
75+
int bt_setting_cb_register(struct bt_settings_vela_cb *cb);
76+
77+
78+
/* register nvs to be a source of settings */
79+
int settings_vela_src(struct settings_vela *cf);
80+
81+
/* register nvs to be the destination of settings */
82+
int settings_vela_dst(struct settings_vela *cf);
83+
84+
/**
85+
* @brief Enable Bluetooth
86+
*
87+
* Enable Bluetooth. Must be the called before any calls that
88+
* require communication with the local Bluetooth hardware.
89+
*
90+
* When @kconfig{CONFIG_BT_SETTINGS} is enabled, the application must load the
91+
* Bluetooth settings after this API call successfully completes before
92+
* Bluetooth APIs can be used. Loading the settings before calling this function
93+
* is insufficient. Bluetooth settings can be loaded with settings_load() or
94+
* settings_load_subtree() with argument "bt". The latter selectively loads only
95+
* Bluetooth settings and is recommended if settings_load() has been called
96+
* earlier.
97+
*
98+
* @param cb Callback to notify completion or NULL to perform the
99+
* enabling synchronously. The callback is called from the system workqueue.
100+
*
101+
* @return Zero on success or (negative) error code otherwise.
102+
*/
103+
int bt_settings_load(uint8_t dev_id, uint8_t id, const char* key, bt_addr_le_t* addr);
104+
105+
/* Initialize a nvs backend. */
106+
int settings_vela_backend_init(struct settings_vela *cf);
107+
108+
struct settings_zblue_cb_arg {
109+
uint8_t dev_id;
110+
void* param;
111+
};
112+
113+
114+
#ifdef __cplusplus
115+
}
116+
#endif
117+
118+
#endif /* __SETTINGS_VELA_H_ */
119+
Lines changed: 229 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,229 @@
1+
/*
2+
* Copyright (c) 2025 Liuxiang
3+
* Copyright (c) 2019 Xiaomi Corporation.
4+
*
5+
* SPDX-License-Identifier: Apache-2.0
6+
*/
7+
8+
#include <errno.h>
9+
#include <string.h>
10+
11+
#include <zephyr/settings/settings.h>
12+
13+
#include "settings/settings_vela.h"
14+
#include <conn_internal.h>
15+
#include <iso_internal.h>
16+
17+
#include <hci_core.h>
18+
#include <zephyr/bluetooth/bluetooth.h>
19+
#include <zephyr/logging/log.h>
20+
21+
#include "settings.h"
22+
23+
// #include "hci_core.h"
24+
LOG_MODULE_DECLARE(settings, CONFIG_SETTINGS_LOG_LEVEL);
25+
26+
static int settings_vela_load(struct settings_store* cs,
27+
const struct settings_load_arg* arg);
28+
static int settings_vela_save(struct settings_store* cs, const char* name,
29+
const char* value, size_t val_len);
30+
31+
sys_slist_t bt_settings_cbs;
32+
33+
static struct settings_store_itf settings_vela_itf = {
34+
.csi_load = settings_vela_load,
35+
.csi_save = settings_vela_save,
36+
};
37+
38+
static struct settings_vela default_settings_vela;
39+
40+
int settings_vela_src(struct settings_vela* cf)
41+
{
42+
cf->cf_store.cs_itf = &settings_vela_itf;
43+
settings_src_register(&cf->cf_store);
44+
45+
return 0;
46+
}
47+
48+
int settings_vela_dst(struct settings_vela* cf)
49+
{
50+
cf->cf_store.cs_itf = &settings_vela_itf;
51+
settings_dst_register(&cf->cf_store);
52+
53+
return 0;
54+
}
55+
56+
static ssize_t settings_vela_read(void* back_end, void* data, size_t len)
57+
{
58+
struct bt_settings_vela_cb *listener, *next;
59+
char* name = (char*)back_end;
60+
bt_addr_le_t addr;
61+
int res = 0;
62+
63+
if (!strncmp(name, "bt/keys/", strlen("bt/keys/"))) {
64+
bt_settings_decode_key(name + strlen("bt/keys/"), &addr);
65+
SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&bt_settings_cbs, listener,
66+
next, _node)
67+
{
68+
if (listener->ltk_load) {
69+
res = listener->ltk_load(&addr, data, len);
70+
}
71+
}
72+
} else if (!strncmp(name, "bt/linkkey/", strlen("bt/linkkey/"))) {
73+
bt_settings_decode_key(name + strlen("bt/linkkey/"), &addr);
74+
SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&bt_settings_cbs, listener,
75+
next, _node)
76+
{
77+
if (listener->linkkey_load) {
78+
res = listener->linkkey_load(&addr, data, len);
79+
}
80+
}
81+
}
82+
83+
return res;
84+
}
85+
86+
static int settings_vela_load(struct settings_store* cs,
87+
const struct settings_load_arg* arg)
88+
{
89+
LOG_ERR("%s", __func__);
90+
return 0;
91+
92+
char* name = "bt/keys/5c40713b3aa80";
93+
// char* name = "bt/keys/473f6b6396fb1";
94+
// implement the logic to load current key_name from sal.
95+
int rc2 = 16, ret;
96+
int cnt = 0;
97+
98+
// SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&hdev->bt_auth_info_cbs, listener,
99+
// next, _node) {
100+
// if (listener->key_load) {
101+
// listener->key_load(&cnt);
102+
// }
103+
// //typedef ssize_t (*settings_read_cb)(void *cb_arg, void *data, size_t len);
104+
105+
// // read_cb
106+
// ret = settings_call_set_handler(
107+
// name, rc2,
108+
// settings_vela_read/* read_cb */, name/* read_cb_arg */,
109+
// (void *)arg);
110+
// }
111+
ret = settings_call_set_handler(
112+
name, rc2,
113+
settings_vela_read /* read_cb */, name /* read_cb_arg */,
114+
(void*)arg);
115+
116+
return 0;
117+
}
118+
119+
int bt_settings_load(uint8_t dev_id, uint8_t id, const char* key, bt_addr_le_t* addr)
120+
{
121+
// char* name = "bt/keys/5c40713b3aa80";
122+
// // implement the logic to load current key_name from sal.
123+
// int len = 0;
124+
125+
int err, len = 0;
126+
char id_str[4];
127+
char dev_id_str[4];
128+
char key_str[BT_SETTINGS_KEY_MAX];
129+
130+
if (addr) {
131+
if (id) {
132+
u8_to_dec(id_str, sizeof(id_str), id);
133+
}
134+
135+
u8_to_dec(dev_id_str, sizeof(dev_id_str), dev_id);
136+
bt_settings_encode_key(key_str, sizeof(key_str), key, addr, (id ? id_str : NULL), dev_id_str);
137+
} else {
138+
err = snprintk(key_str, sizeof(key_str), "bt/%s/%d", key, dev_id);
139+
if (err < 0) {
140+
return -EINVAL;
141+
}
142+
}
143+
144+
settings_call_set_handler(
145+
key_str, len /* unused */,
146+
settings_vela_read /* read_cb */, key_str /* read_cb_arg */,
147+
NULL);
148+
149+
return 0;
150+
}
151+
152+
static void parse_settings_key(const char* name, uint8_t* dev_id, uint8_t* id, bt_addr_le_t* addr)
153+
{
154+
const char *id_next, *dev_next;
155+
156+
/* parse addr */
157+
bt_settings_decode_key(name, addr);
158+
159+
/* parse dev_id(multi-controller) */
160+
settings_name_next(name, &dev_next);
161+
*dev_id = strtoul(dev_next, NULL, 10);
162+
163+
/* parse id(optional) */
164+
settings_name_next(dev_next, &id_next);
165+
if (id_next)
166+
*id = strtoul(id_next, NULL, 10);
167+
else
168+
*id = BT_ID_DEFAULT;
169+
}
170+
171+
static int settings_vela_save(struct settings_store* cs, const char* name,
172+
const char* value, size_t val_len)
173+
{
174+
struct bt_settings_vela_cb *listener, *next;
175+
bt_addr_le_t addr;
176+
uint8_t dev_id, id;
177+
int err = 0;
178+
179+
LOG_ERR("%s", __func__);
180+
181+
if (!strncmp(name, "bt/keys/", strlen("bt/keys/"))) {
182+
parse_settings_key(name + strlen("bt/keys/"), &dev_id, &id, &addr);
183+
SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&bt_settings_cbs, listener,
184+
next, _node)
185+
{
186+
if (listener->ltk_notify) {
187+
err = listener->ltk_notify(dev_id, id, &addr, value, val_len);
188+
}
189+
190+
if (err) {
191+
return err;
192+
}
193+
}
194+
} else if (!strncmp(name, "bt/linkkey/", strlen("bt/linkkey/"))) {
195+
parse_settings_key(name + strlen("bt/linkkey/"), &dev_id, &id, &addr);
196+
SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&bt_settings_cbs, listener,
197+
next, _node)
198+
{
199+
if (listener->linkkey_notify) {
200+
listener->linkkey_notify(dev_id, &addr, value, val_len);
201+
}
202+
203+
if (err) {
204+
return err;
205+
}
206+
}
207+
}
208+
209+
return err;
210+
}
211+
212+
int bt_setting_cb_register(struct bt_settings_vela_cb* cb)
213+
{
214+
215+
if (sys_slist_find(&bt_settings_cbs, &cb->_node, NULL)) {
216+
return -EEXIST;
217+
}
218+
219+
sys_slist_append(&bt_settings_cbs, &cb->_node);
220+
221+
return 0;
222+
}
223+
224+
int settings_backend_init(void)
225+
{
226+
settings_vela_src(&default_settings_vela);
227+
settings_vela_dst(&default_settings_vela);
228+
return 0;
229+
}

0 commit comments

Comments
 (0)