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