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