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