1 /*
2 * Copyright (c) 2017 Intel Corporation
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/kernel.h>
8 #include <stdbool.h>
9 #include <errno.h>
10
11 #include <zephyr/net/buf.h>
12 #include <zephyr/bluetooth/bluetooth.h>
13 #include <zephyr/bluetooth/conn.h>
14 #include <zephyr/bluetooth/uuid.h>
15 #include <zephyr/bluetooth/mesh.h>
16
17 #include <zephyr/logging/log.h>
18 #include <common/bt_str.h>
19
20 #include "test.h"
21 #include "adv.h"
22 #include "prov.h"
23 #include "provisioner.h"
24 #include "net.h"
25 #include "subnet.h"
26 #include "app_keys.h"
27 #include "rpl.h"
28 #include "cfg.h"
29 #include "beacon.h"
30 #include "lpn.h"
31 #include "friend.h"
32 #include "transport.h"
33 #include "heartbeat.h"
34 #include "access.h"
35 #include "foundation.h"
36 #include "proxy.h"
37 #include "pb_gatt_srv.h"
38 #include "settings.h"
39 #include "mesh.h"
40 #include "solicitation.h"
41 #include "gatt_cli.h"
42 #include "crypto.h"
43
44 LOG_MODULE_REGISTER(bt_mesh_main, CONFIG_BT_MESH_LOG_LEVEL);
45
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])46 int bt_mesh_provision(const uint8_t net_key[16], uint16_t net_idx,
47 uint8_t flags, uint32_t iv_index, uint16_t addr,
48 const uint8_t dev_key[16])
49 {
50 struct bt_mesh_key mesh_dev_key;
51 struct bt_mesh_key mesh_net_key;
52 bool is_net_key_valid = false;
53 bool is_dev_key_valid = false;
54 int err = 0;
55
56 if (!atomic_test_bit(bt_mesh.flags, BT_MESH_INIT)) {
57 return -ENODEV;
58 }
59
60 struct bt_mesh_cdb_subnet *subnet = NULL;
61 struct bt_mesh_cdb_node *node = NULL;
62
63 LOG_INF("Primary Element: 0x%04x", addr);
64 LOG_DBG("net_idx 0x%04x flags 0x%02x iv_index 0x%04x", net_idx, flags, iv_index);
65
66 if (atomic_test_and_set_bit(bt_mesh.flags, BT_MESH_VALID)) {
67 return -EALREADY;
68 }
69
70 if (IS_ENABLED(CONFIG_BT_MESH_CDB) &&
71 atomic_test_bit(bt_mesh_cdb.flags, BT_MESH_CDB_VALID)) {
72 const struct bt_mesh_comp *comp;
73 const struct bt_mesh_prov *prov;
74
75 comp = bt_mesh_comp_get();
76 if (comp == NULL) {
77 LOG_ERR("Failed to get node composition");
78 atomic_clear_bit(bt_mesh.flags, BT_MESH_VALID);
79 return -EINVAL;
80 }
81
82 subnet = bt_mesh_cdb_subnet_get(net_idx);
83 if (!subnet) {
84 LOG_ERR("No subnet with idx %d", net_idx);
85 atomic_clear_bit(bt_mesh.flags, BT_MESH_VALID);
86 return -ENOENT;
87 }
88
89 prov = bt_mesh_prov_get();
90 node = bt_mesh_cdb_node_alloc(prov->uuid, addr,
91 comp->elem_count, net_idx);
92 if (node == NULL) {
93 LOG_ERR("Failed to allocate database node");
94 atomic_clear_bit(bt_mesh.flags, BT_MESH_VALID);
95 return -ENOMEM;
96 }
97
98 if (BT_MESH_KEY_REFRESH(flags)) {
99 subnet->kr_phase = BT_MESH_KR_PHASE_2;
100 } else {
101 subnet->kr_phase = BT_MESH_KR_NORMAL;
102 }
103
104 /* The primary network key has been imported during cdb creation.
105 * Importing here leaves it 'as is' if the key is the same.
106 * Otherwise, cdb replaces the old one with the new one.
107 */
108 err = bt_mesh_cdb_subnet_key_import(subnet, BT_MESH_KEY_REFRESH(flags) ? 1 : 0,
109 net_key);
110 if (err) {
111 LOG_ERR("Failed to import cdb network key");
112 goto end;
113 }
114 bt_mesh_cdb_subnet_store(subnet);
115
116 addr = node->addr;
117 bt_mesh_cdb_iv_update(iv_index, BT_MESH_IV_UPDATE(flags));
118
119 err = bt_mesh_cdb_node_key_import(node, dev_key);
120 if (err) {
121 LOG_ERR("Failed to import cdb device key");
122 goto end;
123 }
124
125 if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
126 bt_mesh_cdb_node_store(node);
127 }
128 }
129
130 err = bt_mesh_key_import(BT_MESH_KEY_TYPE_DEV, dev_key, &mesh_dev_key);
131 if (err) {
132 LOG_ERR("Failed to import device key");
133 goto end;
134 }
135 is_dev_key_valid = true;
136
137 err = bt_mesh_key_import(BT_MESH_KEY_TYPE_NET, net_key, &mesh_net_key);
138 if (err) {
139 LOG_ERR("Failed to import network key");
140 goto end;
141 }
142 is_net_key_valid = true;
143
144 err = bt_mesh_net_create(net_idx, flags, &mesh_net_key, iv_index);
145 if (err) {
146 atomic_clear_bit(bt_mesh.flags, BT_MESH_VALID);
147 goto end;
148 }
149
150 bt_mesh_net_settings_commit();
151
152 bt_mesh.seq = 0U;
153
154 bt_mesh_comp_provision(addr);
155
156 memcpy(&bt_mesh.dev_key, &mesh_dev_key, sizeof(struct bt_mesh_key));
157
158 if (IS_ENABLED(CONFIG_BT_MESH_LOW_POWER) &&
159 IS_ENABLED(CONFIG_BT_MESH_LPN_SUB_ALL_NODES_ADDR)) {
160 bt_mesh_lpn_group_add(BT_MESH_ADDR_ALL_NODES);
161 }
162
163 if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
164 bt_mesh_net_store();
165 }
166
167 bt_mesh_start();
168
169 end:
170 if (err && node != NULL && IS_ENABLED(CONFIG_BT_MESH_CDB)) {
171 bt_mesh_cdb_node_del(node, true);
172 }
173
174 if (err && is_dev_key_valid) {
175 bt_mesh_key_destroy(&mesh_dev_key);
176 }
177
178 if (err && is_net_key_valid) {
179 bt_mesh_key_destroy(&mesh_net_key);
180 }
181
182 return err;
183 }
184
185 #if defined(CONFIG_BT_MESH_RPR_SRV)
bt_mesh_reprovision(uint16_t addr)186 void bt_mesh_reprovision(uint16_t addr)
187 {
188 LOG_DBG("0x%04x devkey: %s", addr,
189 bt_hex(&bt_mesh.dev_key_cand, sizeof(struct bt_mesh_key)));
190
191 if (addr != bt_mesh_primary_addr()) {
192 bt_mesh.seq = 0U;
193
194 bt_mesh_comp_provision(addr);
195 bt_mesh_trans_reset();
196
197 if (IS_ENABLED(CONFIG_BT_MESH_FRIEND)) {
198 bt_mesh_friends_clear();
199 }
200
201 if (IS_ENABLED(CONFIG_BT_MESH_LOW_POWER)) {
202 bt_mesh_lpn_friendship_end();
203 }
204 }
205
206 if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
207 LOG_DBG("Storing network information persistently");
208 bt_mesh_net_store();
209 bt_mesh_net_seq_store(true);
210 bt_mesh_comp_data_clear();
211 }
212 }
213
bt_mesh_dev_key_cand(const uint8_t * key)214 void bt_mesh_dev_key_cand(const uint8_t *key)
215 {
216 int err;
217
218 LOG_DBG("%s", bt_hex(key, 16));
219
220 err = bt_mesh_key_import(BT_MESH_KEY_TYPE_DEV, key, &bt_mesh.dev_key_cand);
221 if (err) {
222 LOG_ERR("Failed to import device key candidate");
223 return;
224 }
225
226 atomic_set_bit(bt_mesh.flags, BT_MESH_DEVKEY_CAND);
227
228 if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
229 bt_mesh_net_dev_key_cand_store();
230 }
231 }
232
bt_mesh_dev_key_cand_remove(void)233 void bt_mesh_dev_key_cand_remove(void)
234 {
235 if (!atomic_test_and_clear_bit(bt_mesh.flags, BT_MESH_DEVKEY_CAND)) {
236 return;
237 }
238
239 LOG_DBG("");
240
241 if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
242 bt_mesh_net_dev_key_cand_store();
243 }
244 }
245
bt_mesh_dev_key_cand_activate(void)246 void bt_mesh_dev_key_cand_activate(void)
247 {
248 if (!atomic_test_and_clear_bit(bt_mesh.flags, BT_MESH_DEVKEY_CAND)) {
249 return;
250 }
251
252 bt_mesh_key_destroy(&bt_mesh.dev_key);
253 memcpy(&bt_mesh.dev_key, &bt_mesh.dev_key_cand, sizeof(struct bt_mesh_key));
254 memset(&bt_mesh.dev_key_cand, 0, sizeof(struct bt_mesh_key));
255
256 LOG_DBG("");
257
258 if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
259 bt_mesh_net_pending_net_store();
260 bt_mesh_net_dev_key_cand_store();
261 }
262 }
263 #endif
264
bt_mesh_provision_adv(const uint8_t uuid[16],uint16_t net_idx,uint16_t addr,uint8_t attention_duration)265 int bt_mesh_provision_adv(const uint8_t uuid[16], uint16_t net_idx,
266 uint16_t addr, uint8_t attention_duration)
267 {
268 if (!atomic_test_bit(bt_mesh.flags, BT_MESH_VALID)) {
269 return -EINVAL;
270 }
271
272 if (bt_mesh_subnet_get(net_idx) == NULL) {
273 return -EINVAL;
274 }
275
276 if (IS_ENABLED(CONFIG_BT_MESH_PROVISIONER) &&
277 IS_ENABLED(CONFIG_BT_MESH_PB_ADV)) {
278 return bt_mesh_pb_adv_open(uuid, net_idx, addr,
279 attention_duration);
280 }
281
282 return -ENOTSUP;
283 }
284
bt_mesh_provision_gatt(const uint8_t uuid[16],uint16_t net_idx,uint16_t addr,uint8_t attention_duration)285 int bt_mesh_provision_gatt(const uint8_t uuid[16], uint16_t net_idx, uint16_t addr,
286 uint8_t attention_duration)
287 {
288 if (!atomic_test_bit(bt_mesh.flags, BT_MESH_VALID)) {
289 return -EINVAL;
290 }
291
292 if (bt_mesh_subnet_get(net_idx) == NULL) {
293 return -EINVAL;
294 }
295
296 if (IS_ENABLED(CONFIG_BT_MESH_PB_GATT_CLIENT)) {
297 return bt_mesh_pb_gatt_open(uuid, net_idx, addr,
298 attention_duration);
299 }
300
301 return -ENOTSUP;
302 }
303
bt_mesh_provision_remote(struct bt_mesh_rpr_cli * cli,const struct bt_mesh_rpr_node * srv,const uint8_t uuid[16],uint16_t net_idx,uint16_t addr)304 int bt_mesh_provision_remote(struct bt_mesh_rpr_cli *cli,
305 const struct bt_mesh_rpr_node *srv,
306 const uint8_t uuid[16], uint16_t net_idx,
307 uint16_t addr)
308 {
309 if (!atomic_test_bit(bt_mesh.flags, BT_MESH_VALID)) {
310 return -EINVAL;
311 }
312
313 if (bt_mesh_subnet_get(net_idx) == NULL) {
314 return -EINVAL;
315 }
316
317 if (IS_ENABLED(CONFIG_BT_MESH_PROVISIONER) &&
318 IS_ENABLED(CONFIG_BT_MESH_RPR_CLI)) {
319 return bt_mesh_pb_remote_open(cli, srv, uuid, net_idx, addr);
320 }
321
322 return -ENOTSUP;
323 }
324
bt_mesh_reprovision_remote(struct bt_mesh_rpr_cli * cli,struct bt_mesh_rpr_node * srv,uint16_t addr,bool comp_change)325 int bt_mesh_reprovision_remote(struct bt_mesh_rpr_cli *cli,
326 struct bt_mesh_rpr_node *srv,
327 uint16_t addr, bool comp_change)
328 {
329 if (!atomic_test_bit(bt_mesh.flags, BT_MESH_VALID)) {
330 return -EINVAL;
331 }
332
333 if (IS_ENABLED(CONFIG_BT_MESH_PROVISIONER) &&
334 IS_ENABLED(CONFIG_BT_MESH_RPR_CLI)) {
335 return bt_mesh_pb_remote_open_node(cli, srv, addr, comp_change);
336 }
337
338 return -ENOTSUP;
339 }
340
bt_mesh_reset(void)341 void bt_mesh_reset(void)
342 {
343 if (!atomic_test_bit(bt_mesh.flags, BT_MESH_VALID) ||
344 !atomic_test_bit(bt_mesh.flags, BT_MESH_INIT)) {
345 return;
346 }
347
348 bt_mesh.iv_index = 0U;
349 bt_mesh.ivu_duration = 0;
350 bt_mesh.seq = 0U;
351
352 memset(bt_mesh.flags, 0, sizeof(bt_mesh.flags));
353 atomic_set_bit(bt_mesh.flags, BT_MESH_INIT);
354
355 bt_mesh_scan_disable();
356
357 /* If this fails, the work handler will return early on the next
358 * execution, as the device is not provisioned. If the device is
359 * reprovisioned, the timer is always restarted.
360 */
361 (void)k_work_cancel_delayable(&bt_mesh.ivu_timer);
362
363 bt_mesh_model_reset();
364 bt_mesh_cfg_default_set();
365 bt_mesh_trans_reset();
366 bt_mesh_app_keys_reset();
367 bt_mesh_net_keys_reset();
368
369 bt_mesh_net_loopback_clear(BT_MESH_KEY_ANY);
370
371 if (IS_ENABLED(CONFIG_BT_MESH_LOW_POWER)) {
372 if (IS_ENABLED(CONFIG_BT_MESH_LPN_SUB_ALL_NODES_ADDR)) {
373 uint16_t group = BT_MESH_ADDR_ALL_NODES;
374
375 bt_mesh_lpn_group_del(&group, 1);
376 }
377
378 bt_mesh_lpn_disable(true);
379 }
380
381 if (IS_ENABLED(CONFIG_BT_MESH_FRIEND)) {
382 bt_mesh_friends_clear();
383 }
384
385 if (IS_ENABLED(CONFIG_BT_MESH_GATT_PROXY)) {
386 (void)bt_mesh_proxy_gatt_disable();
387 }
388
389 if (IS_ENABLED(CONFIG_BT_MESH_GATT_CLIENT)) {
390 bt_mesh_gatt_client_deinit();
391 }
392
393 if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
394 bt_mesh_net_clear();
395 }
396
397 bt_mesh_key_destroy(&bt_mesh.dev_key);
398 memset(&bt_mesh.dev_key, 0, sizeof(bt_mesh.dev_key));
399
400 bt_mesh_beacon_disable();
401
402 bt_mesh_comp_unprovision();
403
404 if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
405 bt_mesh_settings_store_pending();
406 }
407
408 if (IS_ENABLED(CONFIG_BT_MESH_PROV)) {
409 bt_mesh_prov_reset();
410 }
411
412 if (IS_ENABLED(CONFIG_BT_MESH_PROXY_SOLICITATION)) {
413 bt_mesh_sol_reset();
414 }
415 }
416
bt_mesh_is_provisioned(void)417 bool bt_mesh_is_provisioned(void)
418 {
419 return atomic_test_bit(bt_mesh.flags, BT_MESH_VALID);
420 }
421
model_suspend(struct bt_mesh_model * mod,struct bt_mesh_elem * elem,bool vnd,bool primary,void * user_data)422 static void model_suspend(struct bt_mesh_model *mod, struct bt_mesh_elem *elem,
423 bool vnd, bool primary, void *user_data)
424 {
425 if (mod->pub && mod->pub->update) {
426 mod->pub->count = 0U;
427 /* If this fails, the work handler will check the suspend call
428 * and exit without transmitting.
429 */
430 (void)k_work_cancel_delayable(&mod->pub->timer);
431 }
432 }
433
bt_mesh_suspend(void)434 int bt_mesh_suspend(void)
435 {
436 int err;
437
438 if (!atomic_test_bit(bt_mesh.flags, BT_MESH_VALID)) {
439 return -EINVAL;
440 }
441
442 if (atomic_test_and_set_bit(bt_mesh.flags, BT_MESH_SUSPENDED)) {
443 return -EALREADY;
444 }
445
446 err = bt_mesh_scan_disable();
447 if (err) {
448 atomic_clear_bit(bt_mesh.flags, BT_MESH_SUSPENDED);
449 LOG_WRN("Disabling scanning failed (err %d)", err);
450 return err;
451 }
452
453 if (IS_ENABLED(CONFIG_BT_MESH_GATT_CLIENT)) {
454 bt_mesh_proxy_disconnect(BT_MESH_KEY_ANY);
455 }
456
457 bt_mesh_hb_suspend();
458
459 bt_mesh_beacon_disable();
460
461 bt_mesh_model_foreach(model_suspend, NULL);
462
463 return 0;
464 }
465
model_resume(struct bt_mesh_model * mod,struct bt_mesh_elem * elem,bool vnd,bool primary,void * user_data)466 static void model_resume(struct bt_mesh_model *mod, struct bt_mesh_elem *elem,
467 bool vnd, bool primary, void *user_data)
468 {
469 if (mod->pub && mod->pub->update) {
470 int32_t period_ms = bt_mesh_model_pub_period_get(mod);
471
472 if (period_ms) {
473 k_work_reschedule(&mod->pub->timer,
474 K_MSEC(period_ms));
475 }
476 }
477 }
478
bt_mesh_resume(void)479 int bt_mesh_resume(void)
480 {
481 int err;
482
483 if (!atomic_test_bit(bt_mesh.flags, BT_MESH_VALID)) {
484 return -EINVAL;
485 }
486
487 if (!atomic_test_and_clear_bit(bt_mesh.flags, BT_MESH_SUSPENDED)) {
488 return -EALREADY;
489 }
490
491 err = bt_mesh_scan_enable();
492 if (err) {
493 LOG_WRN("Re-enabling scanning failed (err %d)", err);
494 atomic_set_bit(bt_mesh.flags, BT_MESH_SUSPENDED);
495 return err;
496 }
497
498 bt_mesh_hb_resume();
499
500 if (bt_mesh_beacon_enabled() ||
501 bt_mesh_priv_beacon_get() == BT_MESH_PRIV_BEACON_ENABLED) {
502 bt_mesh_beacon_enable();
503 }
504
505 bt_mesh_model_foreach(model_resume, NULL);
506
507 return err;
508 }
509
bt_mesh_init(const struct bt_mesh_prov * prov,const struct bt_mesh_comp * comp)510 int bt_mesh_init(const struct bt_mesh_prov *prov,
511 const struct bt_mesh_comp *comp)
512 {
513 int err;
514
515 if (atomic_test_and_set_bit(bt_mesh.flags, BT_MESH_INIT)) {
516 return -EALREADY;
517 }
518
519 err = bt_mesh_test();
520 if (err) {
521 return err;
522 }
523
524 err = bt_mesh_crypto_init();
525 if (err) {
526 return err;
527 }
528
529 err = bt_mesh_comp_register(comp);
530 if (err) {
531 return err;
532 }
533
534 if (IS_ENABLED(CONFIG_BT_MESH_PROV)) {
535 err = bt_mesh_prov_init(prov);
536 if (err) {
537 return err;
538 }
539 }
540
541 bt_mesh_cfg_default_set();
542 bt_mesh_net_init();
543 bt_mesh_trans_init();
544 bt_mesh_hb_init();
545 bt_mesh_beacon_init();
546 bt_mesh_adv_init();
547
548 if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
549 bt_mesh_settings_init();
550 }
551
552 return 0;
553 }
554
model_start(struct bt_mesh_model * mod,struct bt_mesh_elem * elem,bool vnd,bool primary,void * user_data)555 static void model_start(struct bt_mesh_model *mod, struct bt_mesh_elem *elem,
556 bool vnd, bool primary, void *user_data)
557 {
558 if (mod->cb && mod->cb->start) {
559 mod->cb->start(mod);
560 }
561 }
562
bt_mesh_start(void)563 int bt_mesh_start(void)
564 {
565 int err;
566
567 err = bt_mesh_adv_enable();
568 if (err) {
569 LOG_ERR("Failed enabling advertiser");
570 return err;
571 }
572
573
574 if (bt_mesh_beacon_enabled() ||
575 bt_mesh_priv_beacon_get() == BT_MESH_PRIV_BEACON_ENABLED) {
576 bt_mesh_beacon_enable();
577 }
578
579 if (!IS_ENABLED(CONFIG_BT_MESH_PROV) || !bt_mesh_prov_active() ||
580 bt_mesh_prov_link.bearer->type == BT_MESH_PROV_ADV) {
581 if (IS_ENABLED(CONFIG_BT_MESH_PB_GATT)) {
582 (void)bt_mesh_pb_gatt_srv_disable();
583 }
584
585 if (IS_ENABLED(CONFIG_BT_MESH_GATT_PROXY)) {
586 (void)bt_mesh_proxy_gatt_enable();
587 }
588 }
589
590 if (IS_ENABLED(CONFIG_BT_MESH_GATT_CLIENT)) {
591 bt_mesh_gatt_client_init();
592 }
593
594 if (IS_ENABLED(CONFIG_BT_MESH_LOW_POWER)) {
595 bt_mesh_lpn_init();
596 } else {
597 bt_mesh_scan_enable();
598 }
599
600 if (IS_ENABLED(CONFIG_BT_MESH_FRIEND)) {
601 bt_mesh_friend_init();
602 }
603
604 if (IS_ENABLED(CONFIG_BT_MESH_PROV)) {
605 struct bt_mesh_subnet *sub = bt_mesh_subnet_next(NULL);
606 uint16_t addr = bt_mesh_primary_addr();
607
608 bt_mesh_prov_complete(sub->net_idx, addr);
609 }
610
611 bt_mesh_hb_start();
612
613 bt_mesh_model_foreach(model_start, NULL);
614
615 return 0;
616 }
617