1 /*  Bluetooth Mesh */
2 
3 /*
4  * SPDX-FileCopyrightText: 2017 Intel Corporation
5  * SPDX-FileContributor: 2018-2021 Espressif Systems (Shanghai) CO LTD
6  *
7  * SPDX-License-Identifier: Apache-2.0
8  */
9 
10 #include <string.h>
11 #include <errno.h>
12 
13 #include "adv.h"
14 #include "scan.h"
15 #include "prov.h"
16 #include "beacon.h"
17 #include "lpn.h"
18 #include "friend.h"
19 #include "transport.h"
20 #include "access.h"
21 #include "foundation.h"
22 #include "settings.h"
23 #include "mesh.h"
24 #include "mesh_hci.h"
25 #include "mesh_common.h"
26 #include "proxy_client.h"
27 #include "proxy_server.h"
28 #include "provisioner_prov.h"
29 #include "provisioner_main.h"
30 
31 static bool mesh_init = false;
32 
bt_mesh_is_initialized(void)33 bool bt_mesh_is_initialized(void)
34 {
35     return mesh_init;
36 }
37 
bt_mesh_provision(const uint8_t net_key[16],uint16_t net_idx,uint8_t flags,uint32_t iv_index,uint16_t addr,const uint8_t dev_key[16])38 int bt_mesh_provision(const uint8_t net_key[16], uint16_t net_idx,
39                       uint8_t flags, uint32_t iv_index, uint16_t addr,
40                       const uint8_t dev_key[16])
41 {
42     bool pb_gatt_enabled = false;
43     int err = 0;
44 
45     BT_INFO("Primary Element: 0x%04x", addr);
46     BT_INFO("net_idx 0x%04x flags 0x%02x iv_index 0x%04x",
47            net_idx, flags, iv_index);
48     BT_INFO("dev_key %s", bt_hex(dev_key, 16));
49 
50     if (bt_mesh_atomic_test_and_set_bit(bt_mesh.flags, BLE_MESH_VALID)) {
51         return -EALREADY;
52     }
53 
54     if (IS_ENABLED(CONFIG_BLE_MESH_PB_GATT)) {
55         if (bt_mesh_proxy_server_prov_disable(false) == 0) {
56             pb_gatt_enabled = true;
57         } else {
58             pb_gatt_enabled = false;
59         }
60     } else {
61         pb_gatt_enabled = false;
62     }
63 
64     err = bt_mesh_net_create(net_idx, flags, net_key, iv_index);
65     if (err) {
66         bt_mesh_atomic_clear_bit(bt_mesh.flags, BLE_MESH_VALID);
67 
68         if (IS_ENABLED(CONFIG_BLE_MESH_PB_GATT) && pb_gatt_enabled) {
69             bt_mesh_proxy_server_prov_enable();
70         }
71 
72         return err;
73     }
74 
75     bt_mesh.seq = 0U;
76 
77     bt_mesh_comp_provision(addr);
78 
79     memcpy(bt_mesh.dev_key, dev_key, 16);
80 
81     if (IS_ENABLED(CONFIG_BLE_MESH_LOW_POWER) &&
82         IS_ENABLED(CONFIG_BLE_MESH_LPN_SUB_ALL_NODES_ADDR)) {
83         bt_mesh_lpn_group_add(BLE_MESH_ADDR_ALL_NODES);
84     }
85 
86     if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) {
87         BT_DBG("Storing network information persistently");
88         bt_mesh_store_net();
89         bt_mesh_store_subnet(&bt_mesh.sub[0]);
90         bt_mesh_store_iv(false);
91     }
92 
93     bt_mesh_net_start();
94 
95     return 0;
96 }
97 
bt_mesh_node_reset(void)98 void bt_mesh_node_reset(void)
99 {
100     if (!bt_mesh_is_provisioned()) {
101         BT_WARN("%s, Not provisioned", __func__);
102         return;
103     }
104 
105     if (bt_prov_active()) {
106         BT_WARN("%s, link is still active", __func__);
107         return;
108     }
109 
110     bt_mesh.iv_index = 0U;
111     bt_mesh.seq = 0U;
112 
113     bt_mesh_atomic_clear_bit(bt_mesh.flags, BLE_MESH_VALID);
114 
115     k_delayed_work_cancel(&bt_mesh.ivu_timer);
116 
117     bt_mesh_cfg_reset(true);
118 
119     bt_mesh_rx_reset(true);
120     bt_mesh_tx_reset();
121 
122     if (IS_ENABLED(CONFIG_BLE_MESH_LOW_POWER)) {
123         if (IS_ENABLED(CONFIG_BLE_MESH_LPN_SUB_ALL_NODES_ADDR)) {
124             uint16_t group = BLE_MESH_ADDR_ALL_NODES;
125 
126             bt_mesh_lpn_group_del(&group, 1);
127         }
128 
129         bt_mesh_lpn_disable(true);
130     }
131 
132     if (IS_ENABLED(CONFIG_BLE_MESH_FRIEND)) {
133         bt_mesh_friend_clear_net_idx(BLE_MESH_KEY_ANY);
134     }
135 
136     if (IS_ENABLED(CONFIG_BLE_MESH_GATT_PROXY_SERVER)) {
137         bt_mesh_proxy_server_gatt_disable();
138     }
139 
140     (void)memset(bt_mesh.dev_key, 0, sizeof(bt_mesh.dev_key));
141 
142     bt_mesh_scan_disable();
143     bt_mesh_beacon_disable();
144 
145     bt_mesh_comp_unprovision();
146 
147     if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) {
148         bt_mesh_clear_net();
149         bt_mesh_clear_seq();
150         bt_mesh_clear_role();
151     }
152 
153     memset(bt_mesh.flags, 0, sizeof(bt_mesh.flags));
154 
155     if (IS_ENABLED(CONFIG_BLE_MESH_PROV)) {
156         bt_mesh_prov_reset();
157     }
158 }
159 
bt_mesh_is_node(void)160 bool bt_mesh_is_node(void)
161 {
162     return bt_mesh_atomic_test_bit(bt_mesh.flags, BLE_MESH_NODE);
163 }
164 
bt_mesh_is_provisioned(void)165 bool bt_mesh_is_provisioned(void)
166 {
167     if (bt_mesh_is_node()) {
168         return bt_mesh_atomic_test_bit(bt_mesh.flags, BLE_MESH_VALID);
169     } else {
170         return false;
171     }
172 }
173 
bt_mesh_is_provisioner(void)174 bool bt_mesh_is_provisioner(void)
175 {
176     return bt_mesh_atomic_test_bit(bt_mesh.flags, BLE_MESH_PROVISIONER);
177 }
178 
bt_mesh_is_provisioner_en(void)179 bool bt_mesh_is_provisioner_en(void)
180 {
181     if (bt_mesh_is_provisioner()) {
182         return bt_mesh_atomic_test_bit(bt_mesh.flags, BLE_MESH_VALID_PROV);
183     } else {
184         return false;
185     }
186 }
187 
prov_bearers_valid(bt_mesh_prov_bearer_t bearers)188 static bool prov_bearers_valid(bt_mesh_prov_bearer_t bearers)
189 {
190     if ((!(bearers & (BLE_MESH_PROV_ADV | BLE_MESH_PROV_GATT))) ||
191         (IS_ENABLED(CONFIG_BLE_MESH_PB_ADV) &&
192             !IS_ENABLED(CONFIG_BLE_MESH_PB_GATT) &&
193             !(bearers & BLE_MESH_PROV_ADV)) ||
194         (!IS_ENABLED(CONFIG_BLE_MESH_PB_ADV) &&
195             IS_ENABLED(CONFIG_BLE_MESH_PB_GATT) &&
196             !(bearers & BLE_MESH_PROV_GATT))) {
197         BT_ERR("Invalid bearers 0x%02x", bearers);
198         return false;
199     }
200     return true;
201 }
202 
bt_mesh_prov_enable(bt_mesh_prov_bearer_t bearers)203 int bt_mesh_prov_enable(bt_mesh_prov_bearer_t bearers)
204 {
205     int err = 0;
206 
207     if (bt_mesh_is_provisioned()) {
208         BT_WARN("%s, Already", __func__);
209         return -EALREADY;
210     }
211 
212     if (prov_bearers_valid(bearers) == false) {
213         return -EINVAL;
214     }
215 
216     /* Add this judgement here in case the device worked as a
217      * Provisioner previously. Before the corresponding info
218      * of Provisioner is erased from flash, users try to use
219      * the device as a node, which will cause the information
220      * in NVS been handled incorrectly.
221      */
222     uint8_t role = bt_mesh_atomic_get(bt_mesh.flags) & BLE_MESH_SETTINGS_ROLE_BIT_MASK;
223     if (role != BLE_MESH_SETTINGS_ROLE_NONE &&
224         role != BLE_MESH_SETTINGS_ROLE_NODE) {
225         BT_ERR("%s, Mismatch role %u", __func__, role);
226         return -EIO;
227     }
228 
229     if (role == BLE_MESH_SETTINGS_ROLE_NONE) {
230         bt_mesh_atomic_set_bit(bt_mesh.flags, BLE_MESH_NODE);
231     }
232     if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS_BACKWARD_COMPATIBILITY) ||
233         role == BLE_MESH_SETTINGS_ROLE_NONE) {
234         if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) {
235             bt_mesh_store_role();
236         }
237     }
238 
239     if (IS_ENABLED(CONFIG_BLE_MESH_PB_ADV) &&
240             (bearers & BLE_MESH_PROV_ADV)) {
241         /* Make sure we're scanning for provisioning invitations */
242         err = bt_mesh_scan_enable();
243         if (err) {
244             return err;
245         }
246 
247         /* Enable unprovisioned beacon sending */
248         bt_mesh_beacon_enable();
249     }
250 
251     if (IS_ENABLED(CONFIG_BLE_MESH_PB_GATT) &&
252             (bearers & BLE_MESH_PROV_GATT)) {
253         bt_mesh_proxy_server_prov_enable();
254         bt_mesh_adv_update();
255     }
256 
257     return 0;
258 }
259 
bt_mesh_prov_disable(bt_mesh_prov_bearer_t bearers)260 int bt_mesh_prov_disable(bt_mesh_prov_bearer_t bearers)
261 {
262     if (bt_mesh_is_provisioned()) {
263         BT_WARN("%s, Already provisioned", __func__);
264         return -EALREADY;
265     }
266 
267     if (prov_bearers_valid(bearers) == false) {
268         return -EINVAL;
269     }
270 
271     bt_mesh_atomic_clear_bit(bt_mesh.flags, BLE_MESH_NODE);
272 
273     if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) {
274         bt_mesh_clear_role();
275     }
276 
277     if (IS_ENABLED(CONFIG_BLE_MESH_PB_ADV) &&
278             (bearers & BLE_MESH_PROV_ADV)) {
279         bt_mesh_beacon_disable();
280         bt_mesh_scan_disable();
281     }
282 
283     if (IS_ENABLED(CONFIG_BLE_MESH_PB_GATT) &&
284             (bearers & BLE_MESH_PROV_GATT)) {
285         bt_mesh_proxy_server_prov_disable(true);
286     }
287 
288     return 0;
289 }
290 
model_suspend(struct bt_mesh_model * mod,struct bt_mesh_elem * elem,bool vnd,bool primary,void * user_data)291 static void model_suspend(struct bt_mesh_model *mod, struct bt_mesh_elem *elem,
292                           bool vnd, bool primary, void *user_data)
293 {
294     if (mod->pub && mod->pub->update) {
295         mod->pub->count = 0U;
296         k_delayed_work_cancel(&mod->pub->timer);
297     }
298 }
299 
bt_mesh_suspend(void)300 int bt_mesh_suspend(void)
301 {
302     int err = 0;
303 
304     if (!bt_mesh_atomic_test_bit(bt_mesh.flags, BLE_MESH_VALID)) {
305         return -EINVAL;
306     }
307 
308     if (bt_mesh_atomic_test_and_set_bit(bt_mesh.flags, BLE_MESH_SUSPENDED)) {
309         return -EALREADY;
310     }
311 
312     err = bt_mesh_scan_disable();
313     if (err) {
314         bt_mesh_atomic_clear_bit(bt_mesh.flags, BLE_MESH_SUSPENDED);
315         BT_WARN("Disabling scanning failed (err %d)", err);
316         return err;
317     }
318 
319     bt_mesh_hb_pub_disable();
320 
321     if (bt_mesh_beacon_get() == BLE_MESH_BEACON_ENABLED) {
322         bt_mesh_beacon_disable();
323     }
324 
325     bt_mesh_model_foreach(model_suspend, NULL);
326 
327     return 0;
328 }
329 
model_resume(struct bt_mesh_model * mod,struct bt_mesh_elem * elem,bool vnd,bool primary,void * user_data)330 static void model_resume(struct bt_mesh_model *mod, struct bt_mesh_elem *elem,
331                          bool vnd, bool primary, void *user_data)
332 {
333     if (mod->pub && mod->pub->update) {
334         int32_t period_ms = bt_mesh_model_pub_period_get(mod);
335 
336         if (period_ms) {
337             k_delayed_work_submit(&mod->pub->timer, period_ms);
338         }
339     }
340 }
341 
bt_mesh_resume(void)342 int bt_mesh_resume(void)
343 {
344     int err = 0;
345 
346     if (!bt_mesh_atomic_test_bit(bt_mesh.flags, BLE_MESH_VALID)) {
347         return -EINVAL;
348     }
349 
350     if (!bt_mesh_atomic_test_and_clear_bit(bt_mesh.flags, BLE_MESH_SUSPENDED)) {
351         return -EALREADY;
352     }
353 
354     err = bt_mesh_scan_enable();
355     if (err) {
356         BT_WARN("Re-enabling scanning failed (err %d)", err);
357         bt_mesh_atomic_set_bit(bt_mesh.flags, BLE_MESH_SUSPENDED);
358         return err;
359     }
360 
361     if (bt_mesh_beacon_get() == BLE_MESH_BEACON_ENABLED) {
362         bt_mesh_beacon_enable();
363     }
364 
365     bt_mesh_model_foreach(model_resume, NULL);
366 
367     return err;
368 }
369 
bt_mesh_init(const struct bt_mesh_prov * prov,const struct bt_mesh_comp * comp)370 int bt_mesh_init(const struct bt_mesh_prov *prov,
371                  const struct bt_mesh_comp *comp)
372 {
373     int err = 0;
374 
375     if (mesh_init == true) {
376         BT_WARN("%s, Already", __func__);
377         return -EALREADY;
378     }
379 
380     bt_mesh_mutex_init();
381 
382     bt_mesh_timer_init();
383 
384     bt_mesh_hci_init();
385 
386     bt_mesh_adapt_init();
387 
388     err = bt_mesh_comp_register(comp);
389     if (err) {
390         return err;
391     }
392 
393     if (IS_ENABLED(CONFIG_BLE_MESH_PROXY)) {
394         bt_mesh_gatt_init();
395     }
396 
397     if ((IS_ENABLED(CONFIG_BLE_MESH_NODE) &&
398         IS_ENABLED(CONFIG_BLE_MESH_PB_GATT)) ||
399         IS_ENABLED(CONFIG_BLE_MESH_GATT_PROXY_SERVER)) {
400         bt_mesh_proxy_server_init();
401     }
402 
403     if ((IS_ENABLED(CONFIG_BLE_MESH_PROVISIONER) &&
404         IS_ENABLED(CONFIG_BLE_MESH_PB_GATT)) ||
405         IS_ENABLED(CONFIG_BLE_MESH_GATT_PROXY_CLIENT)) {
406         bt_mesh_proxy_client_init();
407     }
408 
409     if (IS_ENABLED(CONFIG_BLE_MESH_PROV)) {
410         if (IS_ENABLED(CONFIG_BLE_MESH_NODE)) {
411             err = bt_mesh_prov_init(prov);
412             if (err) {
413                 return err;
414             }
415         }
416         if (IS_ENABLED(CONFIG_BLE_MESH_PROVISIONER)) {
417             err = bt_mesh_provisioner_prov_init(prov);
418             if (err) {
419                 return err;
420             }
421         }
422     }
423 
424     bt_mesh_net_init();
425     bt_mesh_trans_init();
426 
427     /* Changed by Espressif, add a random delay (0 ~ 3s) */
428     if (IS_ENABLED(CONFIG_BLE_MESH_FAST_PROV)) {
429         uint32_t delay = 0;
430         bt_mesh_rand(&delay, sizeof(uint32_t));
431         vTaskDelay((delay % 3000) / portTICK_PERIOD_MS);
432     }
433 
434     bt_mesh_beacon_init();
435 
436     bt_mesh_adv_init();
437 
438     if (IS_ENABLED(CONFIG_BLE_MESH_PROVISIONER)) {
439         bt_mesh_provisioner_init();
440     }
441 
442     if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) {
443         bt_mesh_settings_init();
444     }
445 
446     mesh_init = true;
447     return 0;
448 }
449 
450 #if CONFIG_BLE_MESH_DEINIT
bt_mesh_deinit(struct bt_mesh_deinit_param * param)451 int bt_mesh_deinit(struct bt_mesh_deinit_param *param)
452 {
453     int err = 0;
454 
455     if (param == NULL) {
456         BT_ERR("%s, Invalid parameter", __func__);
457         return -EINVAL;
458     }
459 
460     if (mesh_init == false) {
461         BT_WARN("%s, Already", __func__);
462         return -EALREADY;
463     }
464 
465     bt_mesh_scan_disable();
466     bt_mesh_beacon_disable();
467 
468     if (IS_ENABLED(CONFIG_BLE_MESH_NODE) && bt_mesh_is_node()) {
469         if (IS_ENABLED(CONFIG_BLE_MESH_PB_GATT) &&
470             !bt_mesh_is_provisioned()) {
471             bt_mesh_proxy_server_prov_disable(true);
472         }
473 
474         if (IS_ENABLED(CONFIG_BLE_MESH_GATT_PROXY_SERVER) &&
475             bt_mesh_is_provisioned()) {
476             bt_mesh_proxy_server_gatt_disable();
477         }
478 
479         if (bt_mesh_is_provisioned()) {
480             /* Clear valid flag here in order to perform settings erase */
481             bt_mesh_atomic_clear_bit(bt_mesh.flags, BLE_MESH_VALID);
482 
483             bt_mesh_cfg_reset(param->erase);
484         }
485     }
486 
487     if (IS_ENABLED(CONFIG_BLE_MESH_PROVISIONER) && bt_mesh_is_provisioner_en()) {
488         if (IS_ENABLED(CONFIG_BLE_MESH_PB_GATT)) {
489             bt_mesh_proxy_client_prov_disable();
490         }
491 
492         /* Clear valid flag here in order to perform settings erase */
493         bt_mesh_atomic_clear_bit(bt_mesh.flags, BLE_MESH_VALID_PROV);
494     }
495 
496     if (IS_ENABLED(CONFIG_BLE_MESH_PROV)) {
497         if (IS_ENABLED(CONFIG_BLE_MESH_NODE)) {
498             err = bt_mesh_prov_deinit();
499             if (err) {
500                 return err;
501             }
502         }
503 
504         if (IS_ENABLED(CONFIG_BLE_MESH_PROVISIONER)) {
505             err = bt_mesh_provisioner_prov_deinit(param->erase);
506             if (err) {
507                 return err;
508             }
509 
510             err = bt_mesh_provisioner_deinit(param->erase);
511             if (err) {
512                 return err;
513             }
514         }
515     }
516 
517     bt_mesh_trans_deinit(param->erase);
518     bt_mesh_net_deinit();
519 
520     bt_mesh_beacon_deinit();
521 
522     if ((IS_ENABLED(CONFIG_BLE_MESH_NODE) &&
523         IS_ENABLED(CONFIG_BLE_MESH_PB_GATT)) ||
524         IS_ENABLED(CONFIG_BLE_MESH_GATT_PROXY_SERVER)) {
525         bt_mesh_proxy_server_deinit();
526     }
527 
528     if ((IS_ENABLED(CONFIG_BLE_MESH_PROVISIONER) &&
529         IS_ENABLED(CONFIG_BLE_MESH_PB_GATT)) ||
530         IS_ENABLED(CONFIG_BLE_MESH_GATT_PROXY_CLIENT)) {
531         bt_mesh_proxy_client_deinit();
532     }
533 
534     bt_mesh_gatt_deinit();
535 
536     if (IS_ENABLED(CONFIG_BLE_MESH_FRIEND)) {
537         bt_mesh_friend_deinit();
538     }
539 
540     if (IS_ENABLED(CONFIG_BLE_MESH_LOW_POWER)) {
541         bt_mesh_lpn_deinit();
542     }
543 
544     bt_mesh_adv_deinit();
545 
546     if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) {
547         bt_mesh_settings_deinit(param->erase);
548     }
549 
550     err = bt_mesh_comp_deregister();
551     if (err) {
552         return err;
553     }
554 
555     bt_mesh_comp_unprovision();
556 
557     memset(bt_mesh.flags, 0, sizeof(bt_mesh.flags));
558 
559     bt_mesh_timer_deinit();
560 
561     bt_mesh_mutex_deinit();
562 
563     mesh_init = false;
564     return 0;
565 }
566 #endif /* CONFIG_BLE_MESH_DEINIT */
567 
568 #if defined(CONFIG_BLE_MESH_PROVISIONER)
bt_mesh_provisioner_enable(bt_mesh_prov_bearer_t bearers)569 int bt_mesh_provisioner_enable(bt_mesh_prov_bearer_t bearers)
570 {
571     int err = 0;
572 
573     if (bt_mesh_is_provisioner_en()) {
574         BT_WARN("%s, Already", __func__);
575         return -EALREADY;
576     }
577 
578     if (prov_bearers_valid(bearers) == false) {
579         return -EINVAL;
580     }
581 
582     /* Add this judgement here in case the device worked as a
583      * node previously. Before the corresponding information
584      * of the node is erased from flash, users try to use the
585      * device as a Provisioner, which will cause the information
586      * in NVS been handled incorrectly.
587      */
588     uint8_t role = bt_mesh_atomic_get(bt_mesh.flags) & BLE_MESH_SETTINGS_ROLE_BIT_MASK;
589     if (role != BLE_MESH_SETTINGS_ROLE_NONE &&
590         role != BLE_MESH_SETTINGS_ROLE_PROV) {
591         BT_ERR("%s, Mismatch role %u", __func__, role);
592         return -EIO;
593     }
594 
595     if (role == BLE_MESH_SETTINGS_ROLE_NONE) {
596         bt_mesh_atomic_set_bit(bt_mesh.flags, BLE_MESH_PROVISIONER);
597 
598         if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) {
599             bt_mesh_store_role();
600         }
601     }
602 
603     /* Enable Provisioner here, because during the following net
604      * creation, some information needs to be stored in flash.
605      */
606     bt_mesh_atomic_set_bit(bt_mesh.flags, BLE_MESH_VALID_PROV);
607 
608     err = bt_mesh_provisioner_net_create();
609     if (err) {
610         BT_ERR("Failed to create network");
611         return err;
612     }
613 
614     err = bt_mesh_provisioner_init_prov_info();
615     if (err) {
616         BT_ERR("Failed to init prov info");
617         return err;
618     }
619 
620     bt_mesh_provisioner_set_prov_bearer(bearers, false);
621 
622     bt_mesh_comp_provision(bt_mesh_provisioner_get_primary_elem_addr());
623 
624 #if defined(CONFIG_BLE_MESH_USE_DUPLICATE_SCAN)
625     if (IS_ENABLED(CONFIG_BLE_MESH_PB_ADV) &&
626             (bearers & BLE_MESH_PROV_ADV)) {
627         bt_mesh_update_exceptional_list(BLE_MESH_EXCEP_LIST_SUB_CODE_ADD,
628                                         BLE_MESH_EXCEP_LIST_TYPE_MESH_BEACON, NULL);
629     }
630 
631     if (IS_ENABLED(CONFIG_BLE_MESH_PB_GATT) &&
632             (bearers & BLE_MESH_PROV_GATT)) {
633         bt_mesh_update_exceptional_list(BLE_MESH_EXCEP_LIST_SUB_CODE_ADD,
634                                         BLE_MESH_EXCEP_LIST_TYPE_MESH_PROV_ADV, NULL);
635     }
636 #endif
637 
638     if (IS_ENABLED(CONFIG_BLE_MESH_PB_GATT) &&
639             (bearers & BLE_MESH_PROV_GATT)) {
640         bt_mesh_proxy_client_prov_enable();
641     }
642 
643     if (IS_ENABLED(CONFIG_BLE_MESH_FRIEND)) {
644         bt_mesh_friend_init();
645     }
646 
647     if (bt_mesh_beacon_get() == BLE_MESH_BEACON_ENABLED) {
648         bt_mesh_beacon_enable();
649     }
650 
651     err = bt_mesh_scan_enable();
652     if (err) {
653         return err;
654     }
655 
656     return 0;
657 }
658 
bt_mesh_provisioner_disable(bt_mesh_prov_bearer_t bearers)659 int bt_mesh_provisioner_disable(bt_mesh_prov_bearer_t bearers)
660 {
661     bt_mesh_prov_bearer_t enable = 0U;
662 
663     if (!bt_mesh_is_provisioner_en()) {
664         BT_WARN("%s, Already", __func__);
665         return -EALREADY;
666     }
667 
668     if (prov_bearers_valid(bearers) == false) {
669         return -EINVAL;
670     }
671 
672     enable = bt_mesh_provisioner_get_prov_bearer();
673     if (!(enable & bearers)) {
674         BT_ERR("Mismatch bearers 0x%02x", bearers);
675         return -EINVAL;
676     }
677 
678     bt_mesh_provisioner_set_prov_bearer(bearers, true);
679 
680     if (IS_ENABLED(CONFIG_BLE_MESH_PB_GATT) &&
681             (enable & BLE_MESH_PROV_GATT) &&
682             (bearers & BLE_MESH_PROV_GATT)) {
683         bt_mesh_proxy_client_prov_disable();
684 #if defined(CONFIG_BLE_MESH_USE_DUPLICATE_SCAN)
685         bt_mesh_update_exceptional_list(BLE_MESH_EXCEP_LIST_SUB_CODE_REMOVE,
686                                         BLE_MESH_EXCEP_LIST_TYPE_MESH_PROV_ADV, NULL);
687 #endif
688     }
689 
690     if (!(enable & (~bearers))) {
691         /* Provisioner is disabled completely, disable scan here */
692         bt_mesh_scan_disable();
693 
694 #if defined(CONFIG_BLE_MESH_USE_DUPLICATE_SCAN)
695         if (IS_ENABLED(CONFIG_BLE_MESH_PB_ADV) &&
696                 (enable & BLE_MESH_PROV_ADV)) {
697             bt_mesh_update_exceptional_list(BLE_MESH_EXCEP_LIST_SUB_CODE_REMOVE,
698                                             BLE_MESH_EXCEP_LIST_TYPE_MESH_BEACON, NULL);
699         }
700 #endif
701 
702         /* Clear corresponding flags */
703         bt_mesh_atomic_and(bt_mesh.flags, ~(BIT(BLE_MESH_PROVISIONER) | BIT(BLE_MESH_VALID_PROV)));
704 
705         /* When Provisioner is disabled, the device role indicated by bt_mesh.flags
706          * will not be cleared, because when Provisioner is restarted after disabled,
707          * its previous information can be recovered from flash properly.
708          */
709 
710         if (bt_mesh_beacon_get() == BLE_MESH_BEACON_ENABLED) {
711             bt_mesh_beacon_disable();
712         }
713 
714         if (IS_ENABLED(CONFIG_BLE_MESH_FRIEND)) {
715             bt_mesh_friend_clear_net_idx(BLE_MESH_KEY_ANY);
716         }
717     }
718 
719     return 0;
720 }
721 #endif /* CONFIG_BLE_MESH_PROVISIONER */
722