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