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_settings_store(const char * key,uint8_t id,const bt_addr_le_t * addr,const void * value,size_t val_len)301 int bt_settings_store(const char *key, uint8_t id, const bt_addr_le_t *addr, const void *value,
302 		      size_t val_len)
303 {
304 	int err;
305 	char id_str[4];
306 	char key_str[BT_SETTINGS_KEY_MAX];
307 
308 	if (addr) {
309 		if (id) {
310 			u8_to_dec(id_str, sizeof(id_str), id);
311 		}
312 
313 		bt_settings_encode_key(key_str, sizeof(key_str), key, addr, (id ? id_str : NULL));
314 	} else {
315 		err = snprintk(key_str, sizeof(key_str), "bt/%s", key);
316 		if (err < 0) {
317 			return -EINVAL;
318 		}
319 	}
320 
321 	return settings_save_one(key_str, value, val_len);
322 }
323 
bt_settings_delete(const char * key,uint8_t id,const bt_addr_le_t * addr)324 int bt_settings_delete(const char *key, uint8_t id, const bt_addr_le_t *addr)
325 {
326 	int err;
327 	char id_str[4];
328 	char key_str[BT_SETTINGS_KEY_MAX];
329 
330 	if (addr) {
331 		if (id) {
332 			u8_to_dec(id_str, sizeof(id_str), id);
333 		}
334 
335 		bt_settings_encode_key(key_str, sizeof(key_str), key, addr, (id ? id_str : NULL));
336 	} else {
337 		err = snprintk(key_str, sizeof(key_str), "bt/%s", key);
338 		if (err < 0) {
339 			return -EINVAL;
340 		}
341 	}
342 
343 	return settings_delete(key_str);
344 }
345 
bt_settings_store_sc(uint8_t id,const bt_addr_le_t * addr,const void * value,size_t val_len)346 int bt_settings_store_sc(uint8_t id, const bt_addr_le_t *addr, const void *value, size_t val_len)
347 {
348 	return bt_settings_store("sc", id, addr, value, val_len);
349 }
350 
bt_settings_delete_sc(uint8_t id,const bt_addr_le_t * addr)351 int bt_settings_delete_sc(uint8_t id, const bt_addr_le_t *addr)
352 {
353 	return bt_settings_delete("sc", id, addr);
354 }
355 
bt_settings_store_cf(uint8_t id,const bt_addr_le_t * addr,const void * value,size_t val_len)356 int bt_settings_store_cf(uint8_t id, const bt_addr_le_t *addr, const void *value, size_t val_len)
357 {
358 	return bt_settings_store("cf", id, addr, value, val_len);
359 }
360 
bt_settings_delete_cf(uint8_t id,const bt_addr_le_t * addr)361 int bt_settings_delete_cf(uint8_t id, const bt_addr_le_t *addr)
362 {
363 	return bt_settings_delete("cf", id, addr);
364 }
365 
bt_settings_store_ccc(uint8_t id,const bt_addr_le_t * addr,const void * value,size_t val_len)366 int bt_settings_store_ccc(uint8_t id, const bt_addr_le_t *addr, const void *value, size_t val_len)
367 {
368 	return bt_settings_store("ccc", id, addr, value, val_len);
369 }
370 
bt_settings_delete_ccc(uint8_t id,const bt_addr_le_t * addr)371 int bt_settings_delete_ccc(uint8_t id, const bt_addr_le_t *addr)
372 {
373 	return bt_settings_delete("ccc", id, addr);
374 }
375 
bt_settings_store_hash(const void * value,size_t val_len)376 int bt_settings_store_hash(const void *value, size_t val_len)
377 {
378 	return bt_settings_store("hash", 0, NULL, value, val_len);
379 }
380 
bt_settings_delete_hash(void)381 int bt_settings_delete_hash(void)
382 {
383 	return bt_settings_delete("hash", 0, NULL);
384 }
385 
bt_settings_store_name(const void * value,size_t val_len)386 int bt_settings_store_name(const void *value, size_t val_len)
387 {
388 	return bt_settings_store("name", 0, NULL, value, val_len);
389 }
390 
bt_settings_delete_name(void)391 int bt_settings_delete_name(void)
392 {
393 	return bt_settings_delete("name", 0, NULL);
394 }
395 
bt_settings_store_appearance(const void * value,size_t val_len)396 int bt_settings_store_appearance(const void *value, size_t val_len)
397 {
398 	return bt_settings_store("appearance", 0, NULL, value, val_len);
399 }
400 
bt_settings_delete_appearance(void)401 int bt_settings_delete_appearance(void)
402 {
403 	return bt_settings_delete("appearance", 0, NULL);
404 }
405 
do_store_id(struct k_work * work)406 static void do_store_id(struct k_work *work)
407 {
408 	int err = bt_settings_store("id", 0, NULL, &bt_dev.id_addr, ID_DATA_LEN(bt_dev.id_addr));
409 
410 	if (err) {
411 		LOG_ERR("Failed to save ID (err %d)", err);
412 	}
413 }
414 
415 K_WORK_DEFINE(store_id_work, do_store_id);
416 
bt_settings_store_id(void)417 int bt_settings_store_id(void)
418 {
419 	k_work_submit(&store_id_work);
420 
421 	return 0;
422 }
423 
bt_settings_delete_id(void)424 int bt_settings_delete_id(void)
425 {
426 	return bt_settings_delete("id", 0, NULL);
427 }
428 
do_store_irk(struct k_work * work)429 static void do_store_irk(struct k_work *work)
430 {
431 #if defined(CONFIG_BT_PRIVACY)
432 	int err = bt_settings_store("irk", 0, NULL, bt_dev.irk, ID_DATA_LEN(bt_dev.irk));
433 
434 	if (err) {
435 		LOG_ERR("Failed to save IRK (err %d)", err);
436 	}
437 #endif
438 }
439 
440 K_WORK_DEFINE(store_irk_work, do_store_irk);
441 
bt_settings_store_irk(void)442 int bt_settings_store_irk(void)
443 {
444 #if defined(CONFIG_BT_PRIVACY)
445 	k_work_submit(&store_irk_work);
446 #endif /* defined(CONFIG_BT_PRIVACY) */
447 	return 0;
448 }
449 
bt_settings_delete_irk(void)450 int bt_settings_delete_irk(void)
451 {
452 	return bt_settings_delete("irk", 0, NULL);
453 }
454 
bt_settings_store_link_key(const bt_addr_le_t * addr,const void * value,size_t val_len)455 int bt_settings_store_link_key(const bt_addr_le_t *addr, const void *value, size_t val_len)
456 {
457 	return bt_settings_store("link_key", 0, addr, value, val_len);
458 }
459 
bt_settings_delete_link_key(const bt_addr_le_t * addr)460 int bt_settings_delete_link_key(const bt_addr_le_t *addr)
461 {
462 	return bt_settings_delete("link_key", 0, addr);
463 }
464 
bt_settings_store_keys(uint8_t id,const bt_addr_le_t * addr,const void * value,size_t val_len)465 int bt_settings_store_keys(uint8_t id, const bt_addr_le_t *addr, const void *value, size_t val_len)
466 {
467 	return bt_settings_store("keys", id, addr, value, val_len);
468 }
469 
bt_settings_delete_keys(uint8_t id,const bt_addr_le_t * addr)470 int bt_settings_delete_keys(uint8_t id, const bt_addr_le_t *addr)
471 {
472 	return bt_settings_delete("keys", id, addr);
473 }
474