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