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_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