1 // Copyright 2017-2019 Espressif Systems (Shanghai) PTE LTD
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include <string.h>
16 #include <errno.h>
17
18 #include "mesh_common.h"
19 #include "settings_uid.h"
20 #include "settings.h"
21
22 #if CONFIG_BLE_MESH_SETTINGS
23
24 enum settings_type {
25 SETTINGS_CORE,
26 #if CONFIG_BLE_MESH_USE_MULTIPLE_NAMESPACE
27 SETTINGS_UID,
28 #endif
29 };
30
31 struct settings_context {
32 char *nvs_name;
33 bt_mesh_nvs_handle_t handle;
34
35 int (*settings_init)(void);
36 int (*settings_load)(void);
37 int (*settings_commit)(void);
38 #if CONFIG_BLE_MESH_DEINIT
39 int (*settings_deinit)(void);
40 int (*settings_erase)(void);
41 #endif /* CONFIG_BLE_MESH_DEINIT */
42 };
43
44 static struct settings_context settings_ctx[] = {
45 [SETTINGS_CORE] = {
46 .nvs_name = "mesh_core",
47 .settings_init = settings_core_init,
48 .settings_load = settings_core_load,
49 .settings_commit = settings_core_commit,
50 #if CONFIG_BLE_MESH_DEINIT
51 .settings_deinit = settings_core_deinit,
52 .settings_erase = settings_core_erase,
53 #endif /* CONFIG_BLE_MESH_DEINIT */
54 },
55 #if CONFIG_BLE_MESH_USE_MULTIPLE_NAMESPACE
56 [SETTINGS_UID] = {
57 .nvs_name = "mesh_user_id",
58 .settings_init = settings_uid_init,
59 .settings_load = settings_uid_load,
60 .settings_commit = NULL,
61 #if CONFIG_BLE_MESH_DEINIT
62 .settings_deinit = settings_uid_deinit,
63 .settings_erase = settings_uid_erase,
64 #endif /* CONFIG_BLE_MESH_DEINIT */
65 },
66 #endif /* CONFIG_BLE_MESH_USE_MULTIPLE_NAMESPACE */
67 };
68
69 /* API used to initialize, load and commit BLE Mesh related settings */
70
bt_mesh_settings_nvs_open(const char * name,bt_mesh_nvs_handle_t * handle)71 int bt_mesh_settings_nvs_open(const char* name, bt_mesh_nvs_handle_t *handle)
72 {
73 #if CONFIG_BLE_MESH_SPECIFIC_PARTITION
74 return nvs_open_from_partition(CONFIG_BLE_MESH_PARTITION_NAME, name, NVS_READWRITE, handle);
75 #else
76 return nvs_open(name, NVS_READWRITE, handle);
77 #endif
78 }
79
bt_mesh_settings_nvs_close(bt_mesh_nvs_handle_t handle)80 void bt_mesh_settings_nvs_close(bt_mesh_nvs_handle_t handle)
81 {
82 nvs_close(handle);
83 }
84
bt_mesh_settings_init_foreach(void)85 void bt_mesh_settings_init_foreach(void)
86 {
87 int err = 0;
88 int i;
89
90 #if CONFIG_BLE_MESH_SPECIFIC_PARTITION
91 err = nvs_flash_init_partition(CONFIG_BLE_MESH_PARTITION_NAME);
92 if (err != ESP_OK) {
93 BT_ERR("Init mesh partition failed, name %s, err %d", CONFIG_BLE_MESH_PARTITION_NAME, err);
94 return;
95 }
96 #endif /* CONFIG_BLE_MESH_SPECIFIC_PARTITION */
97
98 for (i = 0; i < ARRAY_SIZE(settings_ctx); i++) {
99 struct settings_context *ctx = &settings_ctx[i];
100
101 /* Settings initialization is always needed. */
102 if (ctx->settings_init && ctx->settings_init()) {
103 BT_ERR("Init settings failed, name %s", ctx->nvs_name);
104 return;
105 }
106
107 #if CONFIG_BLE_MESH_USE_MULTIPLE_NAMESPACE
108 /* If multiple nvs namespace functionality is enabled,
109 * no need to perform the following operations during
110 * initialization. And they will be performed when the
111 * application layer tries to open settings.
112 */
113 if (i != SETTINGS_UID) {
114 continue;
115 }
116 #endif /* CONFIG_BLE_MESH_USE_MULTIPLE_NAMESPACE */
117
118 err = bt_mesh_settings_nvs_open(ctx->nvs_name, &ctx->handle);
119 if (err) {
120 BT_ERR("Open nvs failed, name %s, err %d", ctx->nvs_name, err);
121 return;
122 }
123
124 if (ctx->settings_load && ctx->settings_load()) {
125 BT_ERR("Load settings failed, name %s", ctx->nvs_name);
126 return;
127 }
128
129 /* If not using multiple nvs namespaces, we will follow the normal
130 * procedure, i.e. restoring all the mesh information.
131 * If using multiple nvs namespaces, we will only restore user_id.
132 */
133 if (ctx->settings_commit && ctx->settings_commit()) {
134 BT_ERR("Commit settings failed, name %s", ctx->nvs_name);
135 return;
136 }
137 }
138 }
139
140 #if CONFIG_BLE_MESH_DEINIT
bt_mesh_settings_deinit_foreach(bool erase)141 void bt_mesh_settings_deinit_foreach(bool erase)
142 {
143 int i;
144
145 for (i = 0; i < ARRAY_SIZE(settings_ctx); i++) {
146 struct settings_context *ctx = &settings_ctx[i];
147
148 if (ctx->settings_deinit && ctx->settings_deinit()) {
149 BT_ERR("Deinit settings failed, name %s", ctx->nvs_name);
150 continue;
151 }
152
153 if (erase && ctx->settings_erase && ctx->settings_erase()) {
154 BT_ERR("Erase settings failed, name %s", ctx->nvs_name);
155 continue;
156 }
157
158 bt_mesh_settings_nvs_close(ctx->handle);
159 }
160
161 #if CONFIG_BLE_MESH_SPECIFIC_PARTITION
162 nvs_flash_deinit_partition(CONFIG_BLE_MESH_PARTITION_NAME);
163 #endif
164 }
165 #endif /* CONFIG_BLE_MESH_DEINIT */
166
bt_mesh_settings_direct_open(bt_mesh_nvs_handle_t * handle)167 int bt_mesh_settings_direct_open(bt_mesh_nvs_handle_t *handle)
168 {
169 int err = 0;
170 int i;
171
172 #if CONFIG_BLE_MESH_SPECIFIC_PARTITION
173 err = nvs_flash_init_partition(CONFIG_BLE_MESH_PARTITION_NAME);
174 if (err != ESP_OK) {
175 BT_ERR("Init mesh partition failed, name %s, err %d", CONFIG_BLE_MESH_PARTITION_NAME, err);
176 return -EIO;
177 }
178 #endif /* CONFIG_BLE_MESH_SPECIFIC_PARTITION */
179
180 for (i = 0; i < ARRAY_SIZE(settings_ctx); i++) {
181 struct settings_context *ctx = &settings_ctx[i];
182
183 err = bt_mesh_settings_nvs_open(ctx->nvs_name, &ctx->handle);
184 if (err) {
185 BT_ERR("Open nvs failed, name %s, err %d", ctx->nvs_name, err);
186 return -EIO;
187 }
188
189 if (i == SETTINGS_CORE && handle) {
190 *handle = ctx->handle;
191 }
192 }
193
194 return 0;
195 }
196
bt_mesh_settings_direct_close(void)197 void bt_mesh_settings_direct_close(void)
198 {
199 int i;
200
201 for (i = 0; i < ARRAY_SIZE(settings_ctx); i++) {
202 bt_mesh_settings_nvs_close(settings_ctx[i].handle);
203 }
204
205 #if CONFIG_BLE_MESH_SPECIFIC_PARTITION
206 nvs_flash_deinit_partition(CONFIG_BLE_MESH_PARTITION_NAME);
207 #endif
208 }
209
210 /* API used to get BLE Mesh related nvs handle */
211
settings_get_nvs_handle(enum settings_type type)212 static inline bt_mesh_nvs_handle_t settings_get_nvs_handle(enum settings_type type)
213 {
214 #if CONFIG_BLE_MESH_USE_MULTIPLE_NAMESPACE
215 if (type == SETTINGS_CORE) {
216 extern bt_mesh_nvs_handle_t get_core_settings_handle(void);
217 return get_core_settings_handle();
218 }
219 #endif
220 return settings_ctx[type].handle;
221 }
222
223 /* API used to store/erase BLE Mesh related settings */
224
settings_save(bt_mesh_nvs_handle_t handle,const char * key,const uint8_t * val,size_t len)225 static int settings_save(bt_mesh_nvs_handle_t handle, const char *key, const uint8_t *val, size_t len)
226 {
227 int err = 0;
228
229 if (key == NULL) {
230 BT_ERR("%s, Invalid parameter", __func__);
231 return -EINVAL;
232 }
233
234 BT_DBG("nvs %s, key %s", val ? "set" : "erase", key);
235
236 if (val) {
237 err = nvs_set_blob(handle, key, val, len);
238 } else {
239 err = nvs_erase_key(handle, key);
240 if (err == ESP_ERR_NVS_NOT_FOUND) {
241 BT_DBG("%s not exists", key);
242 return 0;
243 }
244 }
245 if (err != ESP_OK) {
246 BT_ERR("Failed to %s %s data (err %d)",
247 val ? "set" : "erase", key, err);
248 return -EIO;
249 }
250
251 err = nvs_commit(handle);
252 if (err != ESP_OK) {
253 BT_ERR("Failed to commit settings (err %d)", err);
254 return -EIO;
255 }
256
257 return 0;
258 }
259
bt_mesh_save_settings(bt_mesh_nvs_handle_t handle,const char * key,const uint8_t * val,size_t len)260 int bt_mesh_save_settings(bt_mesh_nvs_handle_t handle, const char *key,
261 const uint8_t *val, size_t len)
262 {
263 int err = 0;
264 bt_mesh_settings_lock();
265 err = settings_save(handle, key, val, len);
266 bt_mesh_settings_unlock();
267 return err;
268 }
269
bt_mesh_save_core_settings(const char * key,const uint8_t * val,size_t len)270 int bt_mesh_save_core_settings(const char *key, const uint8_t *val, size_t len)
271 {
272 bt_mesh_nvs_handle_t handle = settings_get_nvs_handle(SETTINGS_CORE);
273 return bt_mesh_save_settings(handle, key, val, len);
274 }
275
276 #if CONFIG_BLE_MESH_USE_MULTIPLE_NAMESPACE
bt_mesh_save_uid_settings(const char * key,const uint8_t * val,size_t len)277 int bt_mesh_save_uid_settings(const char *key, const uint8_t *val, size_t len)
278 {
279 bt_mesh_nvs_handle_t handle = settings_get_nvs_handle(SETTINGS_UID);
280 return bt_mesh_save_settings(handle, key, val, len);
281 }
282 #endif
283
bt_mesh_erase_settings(bt_mesh_nvs_handle_t handle,const char * key)284 int bt_mesh_erase_settings(bt_mesh_nvs_handle_t handle, const char *key)
285 {
286 return bt_mesh_save_settings(handle, key, NULL, 0);
287 }
288
bt_mesh_erase_core_settings(const char * key)289 int bt_mesh_erase_core_settings(const char *key)
290 {
291 return bt_mesh_save_core_settings(key, NULL, 0);
292 }
293
294 #if CONFIG_BLE_MESH_USE_MULTIPLE_NAMESPACE
bt_mesh_erase_uid_settings(const char * name)295 int bt_mesh_erase_uid_settings(const char *name)
296 {
297 return bt_mesh_save_uid_settings(name, NULL, 0);
298 }
299 #endif
300
301 /* API used to load BLE Mesh related settings */
302
settings_load(bt_mesh_nvs_handle_t handle,const char * key,uint8_t * buf,size_t buf_len,bool * exist)303 static int settings_load(bt_mesh_nvs_handle_t handle, const char *key,
304 uint8_t *buf, size_t buf_len, bool *exist)
305 {
306 int err = 0;
307
308 if (key == NULL || buf == NULL || exist == NULL) {
309 BT_ERR("%s, Invalid parameter", __func__);
310 return -EINVAL;
311 }
312
313 err = nvs_get_blob(handle, key, buf, &buf_len);
314 if (err != ESP_OK) {
315 if (err == ESP_ERR_NVS_NOT_FOUND) {
316 BT_DBG("Settings %s not found", key);
317 *exist = false;
318 return 0;
319 }
320
321 BT_ERR("Failed to get %s data (err %d)", key, err);
322 return -EIO;
323 }
324
325 *exist = true;
326 return 0;
327 }
328
bt_mesh_load_settings(bt_mesh_nvs_handle_t handle,const char * key,uint8_t * buf,size_t buf_len,bool * exist)329 int bt_mesh_load_settings(bt_mesh_nvs_handle_t handle, const char *key,
330 uint8_t *buf, size_t buf_len, bool *exist)
331 {
332 int err = 0;
333 bt_mesh_settings_lock();
334 err = settings_load(handle, key, buf, buf_len, exist);
335 bt_mesh_settings_unlock();
336 return err;
337 }
338
bt_mesh_load_core_settings(const char * key,uint8_t * buf,size_t buf_len,bool * exist)339 int bt_mesh_load_core_settings(const char *key, uint8_t *buf, size_t buf_len, bool *exist)
340 {
341 bt_mesh_nvs_handle_t handle = settings_get_nvs_handle(SETTINGS_CORE);
342 return bt_mesh_load_settings(handle, key, buf, buf_len, exist);
343 }
344
345 #if CONFIG_BLE_MESH_USE_MULTIPLE_NAMESPACE
bt_mesh_load_uid_settings(const char * key,uint8_t * buf,size_t buf_len,bool * exist)346 int bt_mesh_load_uid_settings(const char *key, uint8_t *buf, size_t buf_len, bool *exist)
347 {
348 bt_mesh_nvs_handle_t handle = settings_get_nvs_handle(SETTINGS_UID);
349 return bt_mesh_load_settings(handle, key, buf, buf_len, exist);
350 }
351 #endif
352
353 /* API used to get length of BLE Mesh related settings */
354
settings_get_length(bt_mesh_nvs_handle_t handle,const char * key)355 static size_t settings_get_length(bt_mesh_nvs_handle_t handle, const char *key)
356 {
357 size_t len = 0U;
358 int err = 0;
359
360 if (key == NULL) {
361 BT_ERR("%s, Invalid parameter", __func__);
362 return 0;
363 }
364
365 err = nvs_get_blob(handle, key, NULL, &len);
366 if (err != ESP_OK) {
367 if (err != ESP_ERR_NVS_NOT_FOUND) {
368 BT_ERR("Failed to get %s length (err %d)", key, err);
369 }
370 return 0;
371 }
372
373 return len;
374 }
375
376 /* API used to get BLE Mesh related items. Here items mean model key, NetKey/AppKey
377 * Index, etc. which are going to be used as the prefix of the nvs keys of the BLE
378 * Mesh settings.
379 */
380
settings_get_item(bt_mesh_nvs_handle_t handle,const char * key)381 static struct net_buf_simple *settings_get_item(bt_mesh_nvs_handle_t handle, const char *key)
382 {
383 struct net_buf_simple *buf = NULL;
384 size_t length = 0U;
385 bool exist = false;
386 int err = 0;
387
388 length = settings_get_length(handle, key);
389 if (!length) {
390 BT_DBG("Empty %s", key);
391 return NULL;
392 }
393
394 buf = bt_mesh_alloc_buf(length);
395 if (!buf) {
396 BT_ERR("%s, Out of memory", __func__);
397 /* TODO: in this case, erase all related settings? */
398 return NULL;
399 }
400
401 err = settings_load(handle, key, buf->data, length, &exist);
402 if (err) {
403 BT_ERR("Failed to load %s", key);
404 /* TODO: in this case, erase all related settings? */
405 bt_mesh_free_buf(buf);
406 return NULL;
407 }
408
409 if (exist == false) {
410 bt_mesh_free_buf(buf);
411 return NULL;
412 }
413
414 buf->len = length;
415 return buf;
416 }
417
bt_mesh_get_settings_item(bt_mesh_nvs_handle_t handle,const char * key)418 struct net_buf_simple *bt_mesh_get_settings_item(bt_mesh_nvs_handle_t handle, const char *key)
419 {
420 struct net_buf_simple *buf = NULL;
421 bt_mesh_settings_lock();
422 buf = settings_get_item(handle, key);
423 bt_mesh_settings_unlock();
424 return buf;
425 }
426
bt_mesh_get_core_settings_item(const char * key)427 struct net_buf_simple *bt_mesh_get_core_settings_item(const char *key)
428 {
429 bt_mesh_nvs_handle_t handle = settings_get_nvs_handle(SETTINGS_CORE);
430 return bt_mesh_get_settings_item(handle, key);
431 }
432
433 #if CONFIG_BLE_MESH_USE_MULTIPLE_NAMESPACE
bt_mesh_get_uid_settings_item(const char * key)434 struct net_buf_simple *bt_mesh_get_uid_settings_item(const char *key)
435 {
436 bt_mesh_nvs_handle_t handle = settings_get_nvs_handle(SETTINGS_UID);
437 return bt_mesh_get_settings_item(handle, key);
438 }
439 #endif
440
441 /* API used to check if the settings item exists */
442
is_settings_item_exist(struct net_buf_simple * buf,const uint16_t val)443 static bool is_settings_item_exist(struct net_buf_simple *buf, const uint16_t val)
444 {
445 struct net_buf_simple_state state = {0};
446 size_t length = 0U;
447 int i;
448
449 if (!buf) {
450 return false;
451 }
452
453 net_buf_simple_save(buf, &state);
454
455 length = buf->len;
456 for (i = 0; i < length / SETTINGS_ITEM_SIZE; i++) {
457 uint16_t item = net_buf_simple_pull_le16(buf);
458 if (item == val) {
459 net_buf_simple_restore(buf, &state);
460 return true;
461 }
462 }
463
464 net_buf_simple_restore(buf, &state);
465 return false;
466 }
467
468 /* API used to add the settings item */
469
settings_add_item(bt_mesh_nvs_handle_t handle,const char * key,const uint16_t val)470 static int settings_add_item(bt_mesh_nvs_handle_t handle, const char *key, const uint16_t val)
471 {
472 struct net_buf_simple *store = NULL;
473 struct net_buf_simple *buf = NULL;
474 size_t length = 0U;
475 int err = 0;
476
477 buf = settings_get_item(handle, key);
478
479 /* Check if val already exists */
480 if (is_settings_item_exist(buf, val) == true) {
481 BT_DBG("0x%04x already exists", val);
482 bt_mesh_free_buf(buf);
483 return 0;
484 }
485
486 length = (buf ? buf->len : 0) + sizeof(val);
487
488 store = bt_mesh_alloc_buf(length);
489 if (!store) {
490 BT_ERR("%s, Out of memory", __func__);
491 bt_mesh_free_buf(buf);
492 return -ENOMEM;
493 }
494
495 if (buf) {
496 net_buf_simple_add_mem(store, buf->data, buf->len);
497 }
498 net_buf_simple_add_mem(store, &val, sizeof(val));
499
500 err = settings_save(handle, key, store->data, store->len);
501
502 bt_mesh_free_buf(store);
503 bt_mesh_free_buf(buf);
504 return err;
505 }
506
bt_mesh_add_settings_item(bt_mesh_nvs_handle_t handle,const char * key,const uint16_t val)507 int bt_mesh_add_settings_item(bt_mesh_nvs_handle_t handle, const char *key, const uint16_t val)
508 {
509 int err = 0;
510 bt_mesh_settings_lock();
511 err = settings_add_item(handle, key, val);
512 bt_mesh_settings_unlock();
513 return err;
514 }
515
bt_mesh_add_core_settings_item(const char * key,const uint16_t val)516 int bt_mesh_add_core_settings_item(const char *key, const uint16_t val)
517 {
518 bt_mesh_nvs_handle_t handle = settings_get_nvs_handle(SETTINGS_CORE);
519 return bt_mesh_add_settings_item(handle, key, val);
520 }
521
522 #if CONFIG_BLE_MESH_USE_MULTIPLE_NAMESPACE
bt_mesh_add_uid_settings_item(const char * key,const uint16_t val)523 int bt_mesh_add_uid_settings_item(const char *key, const uint16_t val)
524 {
525 bt_mesh_nvs_handle_t handle = settings_get_nvs_handle(SETTINGS_UID);
526 return bt_mesh_add_settings_item(handle, key, val);
527 }
528 #endif
529
530 /* API used to remove the settings item */
531
settings_remove_item(bt_mesh_nvs_handle_t handle,const char * key,const uint16_t val)532 static int settings_remove_item(bt_mesh_nvs_handle_t handle, const char *key, const uint16_t val)
533 {
534 struct net_buf_simple *store = NULL;
535 struct net_buf_simple *buf = NULL;
536 size_t length = 0U;
537 size_t buf_len = 0U;
538 int err = 0;
539 int i;
540
541 buf = settings_get_item(handle, key);
542
543 /* Check if val does exist */
544 if (is_settings_item_exist(buf, val) == false) {
545 BT_DBG("0x%04x not exists", val);
546 bt_mesh_free_buf(buf);
547 return 0;
548 }
549
550 length = buf->len - sizeof(val);
551 if (!length) {
552 settings_save(handle, key, NULL, 0);
553 bt_mesh_free_buf(buf);
554 return 0;
555 }
556
557 store = bt_mesh_alloc_buf(length);
558 if (!store) {
559 BT_ERR("%s, Out of memory", __func__);
560 bt_mesh_free_buf(buf);
561 return -ENOMEM;
562 }
563
564 buf_len = buf->len;
565 for (i = 0; i < buf_len / SETTINGS_ITEM_SIZE; i++) {
566 uint16_t item = net_buf_simple_pull_le16(buf);
567 if (item != val) {
568 net_buf_simple_add_le16(store, item);
569 }
570 }
571
572 err = settings_save(handle, key, store->data, store->len);
573
574 bt_mesh_free_buf(store);
575 bt_mesh_free_buf(buf);
576 return err;
577 }
578
bt_mesh_remove_settings_item(bt_mesh_nvs_handle_t handle,const char * key,const uint16_t val)579 int bt_mesh_remove_settings_item(bt_mesh_nvs_handle_t handle, const char *key, const uint16_t val)
580 {
581 int err = 0;
582 bt_mesh_settings_lock();
583 err = settings_remove_item(handle, key, val);
584 bt_mesh_settings_unlock();
585 return err;
586 }
587
bt_mesh_remove_core_settings_item(const char * key,const uint16_t val)588 int bt_mesh_remove_core_settings_item(const char *key, const uint16_t val)
589 {
590 bt_mesh_nvs_handle_t handle = settings_get_nvs_handle(SETTINGS_CORE);
591 return bt_mesh_remove_settings_item(handle, key, val);
592 }
593
594 #if CONFIG_BLE_MESH_USE_MULTIPLE_NAMESPACE
bt_mesh_remove_uid_settings_item(const char * key,const uint16_t val)595 int bt_mesh_remove_uid_settings_item(const char *key, const uint16_t val)
596 {
597 bt_mesh_nvs_handle_t handle = settings_get_nvs_handle(SETTINGS_UID);
598 return bt_mesh_remove_settings_item(handle, key, val);
599 }
600 #endif
601
bt_mesh_settings_erase_key(bt_mesh_nvs_handle_t handle,const char * key)602 int bt_mesh_settings_erase_key(bt_mesh_nvs_handle_t handle, const char *key)
603 {
604 int err = 0;
605
606 err = nvs_erase_key(handle, key);
607 if (err != ESP_OK) {
608 if (err == ESP_ERR_NVS_NOT_FOUND) {
609 return 0;
610 }
611
612 BT_ERR("Failed to erase %s (err %d)", key, err);
613 return -EIO;
614 }
615
616 err = nvs_commit(handle);
617 if (err != ESP_OK) {
618 BT_ERR("Failed to commit nvs (err %d)", err);
619 return -EIO;
620 }
621
622 return 0;
623 }
624
bt_mesh_settings_erase_all(bt_mesh_nvs_handle_t handle)625 int bt_mesh_settings_erase_all(bt_mesh_nvs_handle_t handle)
626 {
627 int err = 0;
628
629 err = nvs_erase_all(handle);
630 if (err != ESP_OK) {
631 BT_ERR("Failed to erase all (err %d)", err);
632 return -EIO;
633 }
634
635 err = nvs_commit(handle);
636 if (err != ESP_OK) {
637 BT_ERR("Failed to commit nvs (err %d)", err);
638 return -EIO;
639 }
640
641 return 0;
642 }
643 #endif /* CONFIG_BLE_MESH_SETTINGS */
644