1 /*
2 * Copyright (c) 2018 Intel Corporation
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <errno.h>
8 #include <stddef.h>
9 #include <stdint.h>
10 #include <string.h>
11
12 #include <zephyr/autoconf.h>
13 #include <zephyr/bluetooth/addr.h>
14 #include <zephyr/bluetooth/bluetooth.h>
15 #include <zephyr/bluetooth/conn.h>
16 #include <zephyr/bluetooth/hci.h>
17 #include <zephyr/settings/settings.h>
18 #include <zephyr/kernel.h>
19 #include <zephyr/sys/atomic.h>
20 #include <zephyr/sys/printk.h>
21 #include <zephyr/sys/util.h>
22 #include <zephyr/sys/util_macro.h>
23 #include <zephyr/toolchain.h>
24
25 #include "common/bt_settings_commit.h"
26 #include "common/bt_str.h"
27 #include "hci_core.h"
28 #include "settings.h"
29 #include "sys/types.h"
30
31 #define LOG_LEVEL CONFIG_BT_SETTINGS_LOG_LEVEL
32 #include <zephyr/logging/log.h>
33 LOG_MODULE_REGISTER(bt_settings);
34
35 #if defined(CONFIG_BT_SETTINGS_USE_PRINTK)
bt_settings_encode_key(char * path,size_t path_size,const char * subsys,const bt_addr_le_t * addr,const char * key)36 void bt_settings_encode_key(char *path, size_t path_size, const char *subsys,
37 const bt_addr_le_t *addr, const char *key)
38 {
39 if (key) {
40 snprintk(path, path_size,
41 "bt/%s/%02x%02x%02x%02x%02x%02x%u/%s", subsys,
42 addr->a.val[5], addr->a.val[4], addr->a.val[3],
43 addr->a.val[2], addr->a.val[1], addr->a.val[0],
44 addr->type, key);
45 } else {
46 snprintk(path, path_size,
47 "bt/%s/%02x%02x%02x%02x%02x%02x%u", subsys,
48 addr->a.val[5], addr->a.val[4], addr->a.val[3],
49 addr->a.val[2], addr->a.val[1], addr->a.val[0],
50 addr->type);
51 }
52
53 LOG_DBG("Encoded path %s", path);
54 }
55 #else
bt_settings_encode_key(char * path,size_t path_size,const char * subsys,const bt_addr_le_t * addr,const char * key)56 void bt_settings_encode_key(char *path, size_t path_size, const char *subsys,
57 const bt_addr_le_t *addr, const char *key)
58 {
59 size_t len = 3;
60
61 /* Skip if path_size is less than 3; strlen("bt/") */
62 if (len < path_size) {
63 /* Key format:
64 * "bt/<subsys>/<addr><type>/<key>", "/<key>" is optional
65 */
66 strcpy(path, "bt/");
67 strncpy(&path[len], subsys, path_size - len);
68 len = strlen(path);
69 if (len < path_size) {
70 path[len] = '/';
71 len++;
72 }
73
74 for (int8_t i = 5; i >= 0 && len < path_size; i--) {
75 len += bin2hex(&addr->a.val[i], 1, &path[len],
76 path_size - len);
77 }
78
79 if (len < path_size) {
80 /* Type can be either BT_ADDR_LE_PUBLIC or
81 * BT_ADDR_LE_RANDOM (value 0 or 1)
82 */
83 path[len] = '0' + addr->type;
84 len++;
85 }
86
87 if (key && len < path_size) {
88 path[len] = '/';
89 len++;
90 strncpy(&path[len], key, path_size - len);
91 len += strlen(&path[len]);
92 }
93
94 if (len >= path_size) {
95 /* Truncate string */
96 path[path_size - 1] = '\0';
97 }
98 } else if (path_size > 0) {
99 *path = '\0';
100 }
101
102 LOG_DBG("Encoded path %s", path);
103 }
104 #endif
105
bt_settings_decode_key(const char * key,bt_addr_le_t * addr)106 int bt_settings_decode_key(const char *key, bt_addr_le_t *addr)
107 {
108 if (settings_name_next(key, NULL) != 13) {
109 return -EINVAL;
110 }
111
112 if (key[12] == '0') {
113 addr->type = BT_ADDR_LE_PUBLIC;
114 } else if (key[12] == '1') {
115 addr->type = BT_ADDR_LE_RANDOM;
116 } else {
117 return -EINVAL;
118 }
119
120 for (uint8_t i = 0; i < 6; i++) {
121 hex2bin(&key[i * 2], 2, &addr->a.val[5 - i], 1);
122 }
123
124 LOG_DBG("Decoded %s as %s", key, bt_addr_le_str(addr));
125
126 return 0;
127 }
128
set_setting(const char * name,size_t len_rd,settings_read_cb read_cb,void * cb_arg)129 static int set_setting(const char *name, size_t len_rd, settings_read_cb read_cb,
130 void *cb_arg)
131 {
132 ssize_t len;
133 const char *next;
134
135 if (!atomic_test_bit(bt_dev.flags, BT_DEV_ENABLE)) {
136 /* The Bluetooth settings loader needs to communicate with the Bluetooth
137 * controller to setup identities. This will not work before
138 * bt_enable(). The doc on @ref bt_enable requires the "bt/" settings
139 * tree to be loaded after @ref bt_enable is completed, so this handler
140 * will be called again later.
141 */
142 return 0;
143 }
144
145 if (!name) {
146 LOG_ERR("Insufficient number of arguments");
147 return -ENOENT;
148 }
149
150 len = settings_name_next(name, &next);
151
152 if (!strncmp(name, "id", len)) {
153 /* Any previously provided identities supersede flash */
154 if (atomic_test_bit(bt_dev.flags, BT_DEV_PRESET_ID)) {
155 LOG_WRN("Ignoring identities stored in flash");
156 return 0;
157 }
158
159 len = read_cb(cb_arg, &bt_dev.id_addr, sizeof(bt_dev.id_addr));
160 if (len < sizeof(bt_dev.id_addr[0])) {
161 if (len < 0) {
162 LOG_ERR("Failed to read ID address from storage"
163 " (err %zd)", len);
164 } else {
165 LOG_ERR("Invalid length ID address in storage");
166 LOG_HEXDUMP_DBG(&bt_dev.id_addr, len, "data read");
167 }
168 (void)memset(bt_dev.id_addr, 0,
169 sizeof(bt_dev.id_addr));
170 bt_dev.id_count = 0U;
171 } else {
172 int i;
173
174 bt_dev.id_count = len / sizeof(bt_dev.id_addr[0]);
175 for (i = 0; i < bt_dev.id_count; i++) {
176 LOG_DBG("ID[%d] %s", i, bt_addr_le_str(&bt_dev.id_addr[i]));
177 }
178 }
179
180 return 0;
181 }
182
183 #if defined(CONFIG_BT_DEVICE_NAME_DYNAMIC)
184 if (!strncmp(name, "name", len)) {
185 len = read_cb(cb_arg, &bt_dev.name, sizeof(bt_dev.name) - 1);
186 if (len < 0) {
187 LOG_ERR("Failed to read device name from storage"
188 " (err %zd)", len);
189 } else {
190 bt_dev.name[len] = '\0';
191
192 LOG_DBG("Name set to %s", bt_dev.name);
193 }
194 return 0;
195 }
196 #endif
197
198 #if defined(CONFIG_BT_DEVICE_APPEARANCE_DYNAMIC)
199 if (!strncmp(name, "appearance", len)) {
200 if (len_rd != sizeof(bt_dev.appearance)) {
201 LOG_ERR("Ignoring settings entry 'bt/appearance'. Wrong length.");
202 return -EINVAL;
203 }
204
205 len = read_cb(cb_arg, &bt_dev.appearance, sizeof(bt_dev.appearance));
206 if (len < 0) {
207 return len;
208 }
209
210 return 0;
211 }
212 #endif
213
214 #if defined(CONFIG_BT_PRIVACY)
215 if (!strncmp(name, "irk", len)) {
216 len = read_cb(cb_arg, bt_dev.irk, sizeof(bt_dev.irk));
217 if (len < sizeof(bt_dev.irk[0])) {
218 if (len < 0) {
219 LOG_ERR("Failed to read IRK from storage"
220 " (err %zd)", len);
221 } else {
222 LOG_ERR("Invalid length IRK in storage");
223 (void)memset(bt_dev.irk, 0, sizeof(bt_dev.irk));
224 }
225 } else {
226 int i, count;
227
228 count = len / sizeof(bt_dev.irk[0]);
229 for (i = 0; i < count; i++) {
230 LOG_DBG("IRK[%d] %s", i, bt_hex(bt_dev.irk[i], 16));
231 }
232 }
233
234 return 0;
235 }
236 #endif /* CONFIG_BT_PRIVACY */
237
238 return -ENOENT;
239 }
240
commit_settings(void)241 static int commit_settings(void)
242 {
243 int err;
244
245 LOG_DBG("");
246
247 if (!atomic_test_bit(bt_dev.flags, BT_DEV_ENABLE)) {
248 /* The Bluetooth settings loader needs to communicate with the Bluetooth
249 * controller to setup identities. This will not work before
250 * bt_enable(). The doc on @ref bt_enable requires the "bt/" settings
251 * tree to be loaded after @ref bt_enable is completed, so this handler
252 * will be called again later.
253 */
254 return 0;
255 }
256
257 #if defined(CONFIG_BT_DEVICE_NAME_DYNAMIC)
258 if (bt_dev.name[0] == '\0') {
259 bt_set_name(CONFIG_BT_DEVICE_NAME);
260 }
261 #endif
262 if (!bt_dev.id_count) {
263 err = bt_setup_public_id_addr();
264 if (err) {
265 LOG_ERR("Unable to setup an identity address");
266 return err;
267 }
268 }
269
270 if (!bt_dev.id_count) {
271 err = bt_setup_random_id_addr();
272 if (err) {
273 LOG_ERR("Unable to setup an identity address");
274 return err;
275 }
276 }
277
278 if (!atomic_test_bit(bt_dev.flags, BT_DEV_READY)) {
279 bt_finalize_init();
280 }
281
282 /* If any part of the Identity Information of the device has been
283 * generated this Identity needs to be saved persistently.
284 */
285 if (atomic_test_and_clear_bit(bt_dev.flags, BT_DEV_STORE_ID)) {
286 LOG_DBG("Storing Identity Information");
287 bt_settings_store_id();
288 bt_settings_store_irk();
289 }
290
291 return 0;
292 }
293
294 SETTINGS_STATIC_HANDLER_DEFINE_WITH_CPRIO(bt, "bt", NULL, set_setting, commit_settings, NULL,
295 BT_SETTINGS_CPRIO_0);
296
bt_settings_init(void)297 int bt_settings_init(void)
298 {
299 int err;
300
301 LOG_DBG("");
302
303 err = settings_subsys_init();
304 if (err) {
305 LOG_ERR("settings_subsys_init failed (err %d)", err);
306 return err;
307 }
308
309 return 0;
310 }
311
bt_testing_settings_store_hook(const char * key,const void * value,size_t val_len)312 __weak void bt_testing_settings_store_hook(const char *key, const void *value, size_t val_len)
313 {
314 ARG_UNUSED(key);
315 ARG_UNUSED(value);
316 ARG_UNUSED(val_len);
317 }
318
bt_testing_settings_delete_hook(const char * key)319 __weak void bt_testing_settings_delete_hook(const char *key)
320 {
321 ARG_UNUSED(key);
322 }
323
bt_settings_store(const char * key,uint8_t id,const bt_addr_le_t * addr,const void * value,size_t val_len)324 int bt_settings_store(const char *key, uint8_t id, const bt_addr_le_t *addr, const void *value,
325 size_t val_len)
326 {
327 int err;
328 char id_str[4];
329 char key_str[BT_SETTINGS_KEY_MAX];
330
331 if (addr) {
332 if (id) {
333 u8_to_dec(id_str, sizeof(id_str), id);
334 }
335
336 bt_settings_encode_key(key_str, sizeof(key_str), key, addr, (id ? id_str : NULL));
337 } else {
338 err = snprintk(key_str, sizeof(key_str), "bt/%s", key);
339 if (err < 0) {
340 return -EINVAL;
341 }
342 }
343
344 if (IS_ENABLED(CONFIG_BT_TESTING)) {
345 bt_testing_settings_store_hook(key_str, value, val_len);
346 }
347
348 return settings_save_one(key_str, value, val_len);
349 }
350
bt_settings_delete(const char * key,uint8_t id,const bt_addr_le_t * addr)351 int bt_settings_delete(const char *key, uint8_t id, const bt_addr_le_t *addr)
352 {
353 int err;
354 char id_str[4];
355 char key_str[BT_SETTINGS_KEY_MAX];
356
357 if (addr) {
358 if (id) {
359 u8_to_dec(id_str, sizeof(id_str), id);
360 }
361
362 bt_settings_encode_key(key_str, sizeof(key_str), key, addr, (id ? id_str : NULL));
363 } else {
364 err = snprintk(key_str, sizeof(key_str), "bt/%s", key);
365 if (err < 0) {
366 return -EINVAL;
367 }
368 }
369
370 if (IS_ENABLED(CONFIG_BT_TESTING)) {
371 bt_testing_settings_delete_hook(key_str);
372 }
373
374 return settings_delete(key_str);
375 }
376
bt_settings_store_sc(uint8_t id,const bt_addr_le_t * addr,const void * value,size_t val_len)377 int bt_settings_store_sc(uint8_t id, const bt_addr_le_t *addr, const void *value, size_t val_len)
378 {
379 return bt_settings_store("sc", id, addr, value, val_len);
380 }
381
bt_settings_delete_sc(uint8_t id,const bt_addr_le_t * addr)382 int bt_settings_delete_sc(uint8_t id, const bt_addr_le_t *addr)
383 {
384 return bt_settings_delete("sc", id, addr);
385 }
386
bt_settings_store_cf(uint8_t id,const bt_addr_le_t * addr,const void * value,size_t val_len)387 int bt_settings_store_cf(uint8_t id, const bt_addr_le_t *addr, const void *value, size_t val_len)
388 {
389 return bt_settings_store("cf", id, addr, value, val_len);
390 }
391
bt_settings_delete_cf(uint8_t id,const bt_addr_le_t * addr)392 int bt_settings_delete_cf(uint8_t id, const bt_addr_le_t *addr)
393 {
394 return bt_settings_delete("cf", id, addr);
395 }
396
bt_settings_store_ccc(uint8_t id,const bt_addr_le_t * addr,const void * value,size_t val_len)397 int bt_settings_store_ccc(uint8_t id, const bt_addr_le_t *addr, const void *value, size_t val_len)
398 {
399 return bt_settings_store("ccc", id, addr, value, val_len);
400 }
401
bt_settings_delete_ccc(uint8_t id,const bt_addr_le_t * addr)402 int bt_settings_delete_ccc(uint8_t id, const bt_addr_le_t *addr)
403 {
404 return bt_settings_delete("ccc", id, addr);
405 }
406
bt_settings_store_hash(const void * value,size_t val_len)407 int bt_settings_store_hash(const void *value, size_t val_len)
408 {
409 return bt_settings_store("hash", 0, NULL, value, val_len);
410 }
411
bt_settings_delete_hash(void)412 int bt_settings_delete_hash(void)
413 {
414 return bt_settings_delete("hash", 0, NULL);
415 }
416
bt_settings_store_name(const void * value,size_t val_len)417 int bt_settings_store_name(const void *value, size_t val_len)
418 {
419 return bt_settings_store("name", 0, NULL, value, val_len);
420 }
421
bt_settings_delete_name(void)422 int bt_settings_delete_name(void)
423 {
424 return bt_settings_delete("name", 0, NULL);
425 }
426
bt_settings_store_appearance(const void * value,size_t val_len)427 int bt_settings_store_appearance(const void *value, size_t val_len)
428 {
429 return bt_settings_store("appearance", 0, NULL, value, val_len);
430 }
431
bt_settings_delete_appearance(void)432 int bt_settings_delete_appearance(void)
433 {
434 return bt_settings_delete("appearance", 0, NULL);
435 }
436
do_store_id(struct k_work * work)437 static void do_store_id(struct k_work *work)
438 {
439 int err = bt_settings_store("id", 0, NULL, &bt_dev.id_addr, ID_DATA_LEN(bt_dev.id_addr));
440
441 if (err) {
442 LOG_ERR("Failed to save ID (err %d)", err);
443 }
444 }
445
446 K_WORK_DEFINE(store_id_work, do_store_id);
447
bt_settings_store_id(void)448 int bt_settings_store_id(void)
449 {
450 k_work_submit(&store_id_work);
451
452 return 0;
453 }
454
bt_settings_delete_id(void)455 int bt_settings_delete_id(void)
456 {
457 return bt_settings_delete("id", 0, NULL);
458 }
459
do_store_irk(struct k_work * work)460 static void do_store_irk(struct k_work *work)
461 {
462 #if defined(CONFIG_BT_PRIVACY)
463 int err = bt_settings_store("irk", 0, NULL, bt_dev.irk, ID_DATA_LEN(bt_dev.irk));
464
465 if (err) {
466 LOG_ERR("Failed to save IRK (err %d)", err);
467 }
468 #endif
469 }
470
471 K_WORK_DEFINE(store_irk_work, do_store_irk);
472
bt_settings_store_irk(void)473 int bt_settings_store_irk(void)
474 {
475 #if defined(CONFIG_BT_PRIVACY)
476 k_work_submit(&store_irk_work);
477 #endif /* defined(CONFIG_BT_PRIVACY) */
478 return 0;
479 }
480
bt_settings_delete_irk(void)481 int bt_settings_delete_irk(void)
482 {
483 return bt_settings_delete("irk", 0, NULL);
484 }
485
bt_settings_store_link_key(const bt_addr_le_t * addr,const void * value,size_t val_len)486 int bt_settings_store_link_key(const bt_addr_le_t *addr, const void *value, size_t val_len)
487 {
488 return bt_settings_store("link_key", 0, addr, value, val_len);
489 }
490
bt_settings_delete_link_key(const bt_addr_le_t * addr)491 int bt_settings_delete_link_key(const bt_addr_le_t *addr)
492 {
493 return bt_settings_delete("link_key", 0, addr);
494 }
495
bt_settings_store_keys(uint8_t id,const bt_addr_le_t * addr,const void * value,size_t val_len)496 int bt_settings_store_keys(uint8_t id, const bt_addr_le_t *addr, const void *value, size_t val_len)
497 {
498 return bt_settings_store("keys", id, addr, value, val_len);
499 }
500
bt_settings_delete_keys(uint8_t id,const bt_addr_le_t * addr)501 int bt_settings_delete_keys(uint8_t id, const bt_addr_le_t *addr)
502 {
503 return bt_settings_delete("keys", id, addr);
504 }
505