1 /*
2 * SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <string.h>
8 #include <errno.h>
9
10 #include "mesh.h"
11 #include "crypto.h"
12 #include "adv.h"
13 #include "access.h"
14 #include "settings.h"
15 #include "friend.h"
16 #include "transport.h"
17 #include "foundation.h"
18 #include "mesh_common.h"
19 #include "proxy_client.h"
20 #include "provisioner_prov.h"
21 #include "provisioner_main.h"
22
23 #if CONFIG_BLE_MESH_PROVISIONER
24
25 static struct bt_mesh_node *mesh_nodes[CONFIG_BLE_MESH_MAX_PROV_NODES];
26 static bt_mesh_mutex_t provisioner_lock;
27 static uint16_t node_count;
28
29 static int provisioner_remove_node(uint16_t index, bool erase);
30
bt_mesh_provisioner_mutex_new(void)31 static inline void bt_mesh_provisioner_mutex_new(void)
32 {
33 if (!provisioner_lock.mutex) {
34 bt_mesh_mutex_create(&provisioner_lock);
35 }
36 }
37
38 #if CONFIG_BLE_MESH_DEINIT
bt_mesh_provisioner_mutex_free(void)39 static inline void bt_mesh_provisioner_mutex_free(void)
40 {
41 bt_mesh_mutex_free(&provisioner_lock);
42 }
43 #endif /* CONFIG_BLE_MESH_DEINIT */
44
bt_mesh_provisioner_lock(void)45 static inline void bt_mesh_provisioner_lock(void)
46 {
47 bt_mesh_mutex_lock(&provisioner_lock);
48 }
49
bt_mesh_provisioner_unlock(void)50 static inline void bt_mesh_provisioner_unlock(void)
51 {
52 bt_mesh_mutex_unlock(&provisioner_lock);
53 }
54
bt_mesh_provisioner_init(void)55 int bt_mesh_provisioner_init(void)
56 {
57 bt_mesh_provisioner_mutex_new();
58
59 return 0;
60 }
61
62 /**
63 * When a Provisioner tries to create a network, it will check the
64 * status of the restored network keys firstly, and try to create
65 * one if they are not existed.
66 */
bt_mesh_provisioner_net_create(void)67 int bt_mesh_provisioner_net_create(void)
68 {
69 const struct bt_mesh_prov *prov = NULL;
70 struct bt_mesh_subnet *sub = NULL;
71 uint8_t p_key[16] = {0};
72
73 BT_DBG("%s", __func__);
74
75 prov = bt_mesh_provisioner_get_prov_info();
76 if (!prov) {
77 BT_ERR("No provisioning context provided");
78 return -EINVAL;
79 }
80
81 if (bt_mesh.p_sub[0]) {
82 /* Provisioner is already enabled (enable -> disable -> enable),
83 * or Provisioner is restored from flash.
84 */
85 BT_INFO("Provisioner already created network");
86 sub = bt_mesh.p_sub[0];
87 goto done;
88 }
89
90 /* Generate the primary netkey */
91 if (bt_mesh_rand(p_key, 16)) {
92 BT_ERR("Failed to generate Primary NetKey");
93 return -EIO;
94 }
95
96 sub = bt_mesh_calloc(sizeof(struct bt_mesh_subnet));
97 if (!sub) {
98 BT_ERR("%s, Out of memory", __func__);
99 return -ENOMEM;
100 }
101
102 sub->kr_flag = BLE_MESH_KEY_REFRESH(prov->flags);
103 if (sub->kr_flag) {
104 if (bt_mesh_net_keys_create(&sub->keys[1], p_key)) {
105 BT_ERR("Failed to generate net-related keys");
106 bt_mesh_free(sub);
107 return -EIO;
108 }
109 sub->kr_phase = BLE_MESH_KR_PHASE_2;
110 } else {
111 /* Currently provisioner only use keys[0] */
112 if (bt_mesh_net_keys_create(&sub->keys[0], p_key)) {
113 BT_ERR("Failed to create net-related keys");
114 bt_mesh_free(sub);
115 return -EIO;
116 }
117 sub->kr_phase = BLE_MESH_KR_NORMAL;
118 }
119 sub->net_idx = BLE_MESH_KEY_PRIMARY;
120 sub->node_id = BLE_MESH_NODE_IDENTITY_NOT_SUPPORTED;
121
122 bt_mesh.p_sub[0] = sub;
123
124 /* Dynamically added appkey & netkey will use these key_idx */
125 bt_mesh.p_app_idx_next = 0x0000;
126 bt_mesh.p_net_idx_next = 0x0001;
127
128 if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) {
129 bt_mesh_store_p_net_idx();
130 bt_mesh_store_p_app_idx();
131 bt_mesh_store_p_subnet(bt_mesh.p_sub[0]);
132 }
133
134 bt_mesh.iv_index = prov->iv_index;
135 bt_mesh_atomic_set_bit_to(bt_mesh.flags, BLE_MESH_IVU_IN_PROGRESS,
136 BLE_MESH_IV_UPDATE(prov->flags));
137
138 /* Set minimum required hours, since the 96-hour minimum requirement
139 * doesn't apply straight after provisioning (since we can't know how
140 * long has actually passed since the network changed its state).
141 * This operation is the same with node initialization.
142 */
143 bt_mesh.ivu_duration = BLE_MESH_IVU_MIN_HOURS;
144
145 if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) {
146 bt_mesh_store_iv(true);
147 }
148
149 done:
150 BT_INFO("NetKeyIndex 0x%03x, NID 0x%02x", sub->net_idx, sub->keys[0].nid);
151 BT_INFO("NetKey %s", bt_hex(sub->keys[0].net, 16));
152
153 return 0;
154 }
155
bt_mesh_provisioner_main_reset(bool erase)156 void bt_mesh_provisioner_main_reset(bool erase)
157 {
158 int i;
159
160 for (i = 0; i < ARRAY_SIZE(bt_mesh.p_sub); i++) {
161 if (bt_mesh.p_sub[i]) {
162 bt_mesh_provisioner_local_net_key_del(bt_mesh.p_sub[i]->net_idx, erase);
163 }
164 }
165
166 /* Clear model state that isn't otherwise cleared. E.g. AppKey
167 * binding and model publication is cleared as a consequence
168 * of removing all app keys, however model subscription clearing
169 * must be taken care of here.
170 */
171 bt_mesh_mod_sub_reset(erase);
172
173 bt_mesh.p_net_idx_next = 0U;
174 bt_mesh.p_app_idx_next = 0U;
175
176 if (erase && IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) {
177 bt_mesh_clear_p_net_idx();
178 bt_mesh_clear_p_app_idx();
179 }
180
181 for (i = 0; i < CONFIG_BLE_MESH_MAX_PROV_NODES; i++) {
182 provisioner_remove_node(i, erase);
183 }
184
185 node_count = 0U;
186 }
187
188 #if CONFIG_BLE_MESH_DEINIT
bt_mesh_provisioner_deinit(bool erase)189 int bt_mesh_provisioner_deinit(bool erase)
190 {
191 bt_mesh_provisioner_main_reset(erase);
192 bt_mesh_provisioner_mutex_free();
193 return 0;
194 }
195 #endif /* CONFIG_BLE_MESH_DEINIT */
196
bt_mesh_provisioner_check_is_addr_dup(uint16_t addr,uint8_t elem_num,bool comp_with_own)197 bool bt_mesh_provisioner_check_is_addr_dup(uint16_t addr, uint8_t elem_num, bool comp_with_own)
198 {
199 const struct bt_mesh_comp *comp = NULL;
200 struct bt_mesh_node *node = NULL;
201 uint16_t primary_addr = BLE_MESH_ADDR_UNASSIGNED;
202 uint16_t comp_addr = BLE_MESH_ADDR_UNASSIGNED;
203 int i;
204
205 if (comp_with_own) {
206 comp = bt_mesh_comp_get();
207 if (!comp) {
208 BT_ERR("Invalid composition data");
209 return true;
210 }
211
212 primary_addr = bt_mesh_provisioner_get_primary_elem_addr();
213 if (!BLE_MESH_ADDR_IS_UNICAST(primary_addr)) {
214 BT_ERR("Invalid unicast address 0x%04x", primary_addr);
215 return true;
216 }
217 }
218
219 for (comp_addr = addr; comp_addr < addr + elem_num; comp_addr++) {
220 for (i = 0; i < ARRAY_SIZE(mesh_nodes); i++) {
221 node = mesh_nodes[i];
222 if (node && comp_addr >= node->unicast_addr &&
223 comp_addr < node->unicast_addr + node->element_num) {
224 BT_ERR("Duplicate with node address 0x%04x", comp_addr);
225 return true;
226 }
227
228 if (comp_with_own && comp_addr >= primary_addr &&
229 comp_addr < primary_addr + comp->elem_count) {
230 BT_ERR("Duplicate with Provisioner address 0x%04x", comp_addr);
231 return true;
232 }
233 }
234 }
235
236 return false;
237 }
238
provisioner_node_count_inc(void)239 static void provisioner_node_count_inc(void)
240 {
241 node_count++;
242 }
243
provisioner_node_count_dec(void)244 static void provisioner_node_count_dec(void)
245 {
246 if (node_count) {
247 node_count--;
248 }
249 }
250
bt_mesh_provisioner_get_node_count(void)251 uint16_t bt_mesh_provisioner_get_node_count(void)
252 {
253 return node_count;
254 }
255
provisioner_store_node(struct bt_mesh_node * node,bool store,uint16_t * index)256 static int provisioner_store_node(struct bt_mesh_node *node, bool store, uint16_t *index)
257 {
258 int i;
259
260 bt_mesh_provisioner_lock();
261
262 /* Check if the node already exists */
263 for (i = 0; i < ARRAY_SIZE(mesh_nodes); i++) {
264 if (mesh_nodes[i] && !memcmp(mesh_nodes[i]->dev_uuid, node->dev_uuid, 16)) {
265 BT_WARN("Node already exists, uuid %s", bt_hex(node->dev_uuid, 16));
266 bt_mesh_provisioner_unlock();
267 return -EEXIST;
268 }
269 }
270
271 for (i = 0; i < ARRAY_SIZE(mesh_nodes); i++) {
272 if (mesh_nodes[i] == NULL) {
273 mesh_nodes[i] = bt_mesh_calloc(sizeof(struct bt_mesh_node));
274 if (!mesh_nodes[i]) {
275 BT_ERR("%s, Out of memory", __func__);
276 bt_mesh_provisioner_unlock();
277 return -ENOMEM;
278 }
279
280 memcpy(mesh_nodes[i], node, sizeof(struct bt_mesh_node));
281 provisioner_node_count_inc();
282 if (index) {
283 *index = i;
284 }
285
286 if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS) && store) {
287 bt_mesh_store_node_info(mesh_nodes[i]);
288 }
289
290 bt_mesh_provisioner_unlock();
291 return 0;
292 }
293 }
294
295 BT_ERR("Node is full!");
296 bt_mesh_provisioner_unlock();
297 return -ENOMEM;
298 }
299
bt_mesh_provisioner_restore_node_info(struct bt_mesh_node * node)300 int bt_mesh_provisioner_restore_node_info(struct bt_mesh_node *node)
301 {
302 if (!node) {
303 BT_ERR("%s, Invalid parameter", __func__);
304 return -EINVAL;
305 }
306
307 return provisioner_store_node(node, false, NULL);
308 }
309
bt_mesh_provisioner_provision(const bt_mesh_addr_t * addr,const uint8_t uuid[16],uint16_t oob_info,uint16_t unicast_addr,uint8_t element_num,uint16_t net_idx,uint8_t flags,uint32_t iv_index,const uint8_t dev_key[16],uint16_t * index)310 int bt_mesh_provisioner_provision(const bt_mesh_addr_t *addr, const uint8_t uuid[16],
311 uint16_t oob_info, uint16_t unicast_addr,
312 uint8_t element_num, uint16_t net_idx,
313 uint8_t flags, uint32_t iv_index,
314 const uint8_t dev_key[16], uint16_t *index)
315 {
316 struct bt_mesh_node node = {0};
317
318 BT_DBG("%s", __func__);
319
320 if (!addr || !uuid || !dev_key || !index) {
321 BT_ERR("%s, Invalid parameter", __func__);
322 return -EINVAL;
323 }
324
325 BT_INFO("Unicast addr 0x%04x, element num %d, NetKeyIndex 0x%04x",
326 unicast_addr, element_num, net_idx);
327 BT_INFO("UUID %s", bt_hex(uuid, 16));
328 BT_INFO("DevKey %s", bt_hex(dev_key, 16));
329
330 memcpy(node.addr, addr->val, BLE_MESH_ADDR_LEN);
331 node.addr_type = addr->type;
332 memcpy(node.dev_uuid, uuid, 16);
333 node.oob_info = oob_info;
334 node.unicast_addr = unicast_addr;
335 node.element_num = element_num;
336 node.net_idx = net_idx;
337 node.flags = flags;
338 node.iv_index = iv_index;
339 memcpy(node.dev_key, dev_key, 16);
340
341 return provisioner_store_node(&node, true, index);
342 }
343
provisioner_remove_node(uint16_t index,bool erase)344 static int provisioner_remove_node(uint16_t index, bool erase)
345 {
346 struct bt_mesh_node *node = NULL;
347 int i;
348
349 BT_DBG("Remove node %d", index);
350
351 bt_mesh_provisioner_lock();
352
353 if (mesh_nodes[index] == NULL) {
354 bt_mesh_provisioner_unlock();
355 return 0;
356 }
357
358 node = mesh_nodes[index];
359
360 /* Reset corresponding network cache when reset the node */
361 bt_mesh_msg_cache_clear(node->unicast_addr, node->element_num);
362
363 /* Reset corresponding transport info when removing the node */
364 for (i = 0; i < node->element_num; i++) {
365 bt_mesh_rx_reset_single(node->unicast_addr + i);
366 }
367 for (i = 0; i < node->element_num; i++) {
368 bt_mesh_tx_reset_single(node->unicast_addr + i);
369 }
370
371 if (IS_ENABLED(CONFIG_BLE_MESH_FRIEND)) {
372 bt_mesh_friend_remove_lpn(node->unicast_addr);
373 }
374
375 if (erase && IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) {
376 bt_mesh_clear_node_info(node->unicast_addr);
377 }
378
379 if (mesh_nodes[index]->comp_data) {
380 bt_mesh_free(mesh_nodes[index]->comp_data);
381 }
382 bt_mesh_free(mesh_nodes[index]);
383 mesh_nodes[index] = NULL;
384
385 provisioner_node_count_dec();
386
387 bt_mesh_provisioner_unlock();
388 return 0;
389 }
390
provisioner_find_node_with_uuid(const uint8_t uuid[16],uint16_t * index)391 static struct bt_mesh_node *provisioner_find_node_with_uuid(const uint8_t uuid[16], uint16_t *index)
392 {
393 int i;
394
395 BT_DBG("%s", __func__);
396
397 if (uuid == NULL) {
398 BT_ERR("Invalid device uuid");
399 return NULL;
400 }
401
402 bt_mesh_provisioner_lock();
403
404 for (i = 0; i < ARRAY_SIZE(mesh_nodes); i++) {
405 if (mesh_nodes[i] && !memcmp(mesh_nodes[i]->dev_uuid, uuid, 16)) {
406 if (index) {
407 *index = i;
408 }
409 bt_mesh_provisioner_unlock();
410 return mesh_nodes[i];
411 }
412 }
413
414 bt_mesh_provisioner_unlock();
415 return NULL;
416 }
417
bt_mesh_provisioner_remove_node(const uint8_t uuid[16])418 int bt_mesh_provisioner_remove_node(const uint8_t uuid[16])
419 {
420 struct bt_mesh_node *node = NULL;
421 uint16_t index = 0U;
422 int i;
423
424 if (uuid == NULL) {
425 for (i = 0; i < ARRAY_SIZE(mesh_nodes); i++) {
426 if (mesh_nodes[i]) {
427 provisioner_remove_node(i, true);
428 }
429 }
430 return 0;
431 }
432
433 node = provisioner_find_node_with_uuid(uuid, &index);
434 if (!node) {
435 BT_WARN("Node not found, uuid %s", bt_hex(uuid, 16));
436 return -ENODEV;
437 }
438
439 provisioner_remove_node(index, true);
440 return 0;
441 }
442
provisioner_find_node_with_addr(uint16_t addr,uint16_t * index)443 static struct bt_mesh_node *provisioner_find_node_with_addr(uint16_t addr, uint16_t *index)
444 {
445 struct bt_mesh_node *node = NULL;
446 int i;
447
448 BT_DBG("%s", __func__);
449
450 if (!BLE_MESH_ADDR_IS_UNICAST(addr)) {
451 BT_ERR("Invalid unicast address 0x%04x", addr);
452 return NULL;
453 }
454
455 bt_mesh_provisioner_lock();
456
457 for (i = 0; i < ARRAY_SIZE(mesh_nodes); i++) {
458 node = mesh_nodes[i];
459 if (node && addr >= node->unicast_addr &&
460 addr < (node->unicast_addr + node->element_num)) {
461 if (index) {
462 *index = i;
463 }
464 bt_mesh_provisioner_unlock();
465 return node;
466 }
467 }
468
469 bt_mesh_provisioner_unlock();
470 return NULL;
471 }
472
bt_mesh_provisioner_restore_node_name(uint16_t addr,const char * name)473 int bt_mesh_provisioner_restore_node_name(uint16_t addr, const char *name)
474 {
475 struct bt_mesh_node *node = NULL;
476
477 node = provisioner_find_node_with_addr(addr, NULL);
478 if (node == NULL) {
479 BT_ERR("Node not found, addr 0x%04x", addr);
480 return -ENODEV;
481 }
482
483 strncpy(node->name, name, BLE_MESH_NODE_NAME_SIZE);
484 node->name[BLE_MESH_NODE_NAME_SIZE] = 0;
485
486 return 0;
487 }
488
bt_mesh_provisioner_get_node_with_uuid(const uint8_t uuid[16])489 struct bt_mesh_node *bt_mesh_provisioner_get_node_with_uuid(const uint8_t uuid[16])
490 {
491 return provisioner_find_node_with_uuid(uuid, NULL);
492 }
493
bt_mesh_provisioner_get_node_with_addr(uint16_t unicast_addr)494 struct bt_mesh_node *bt_mesh_provisioner_get_node_with_addr(uint16_t unicast_addr)
495 {
496 return provisioner_find_node_with_addr(unicast_addr, NULL);
497 }
498
bt_mesh_provisioner_delete_node_with_uuid(const uint8_t uuid[16])499 int bt_mesh_provisioner_delete_node_with_uuid(const uint8_t uuid[16])
500 {
501 struct bt_mesh_node *node = NULL;
502 uint16_t index = 0U;
503
504 node = provisioner_find_node_with_uuid(uuid, &index);
505 if (!node) {
506 BT_WARN("Node not found, uuid %s", bt_hex(uuid, 16));
507 return -ENODEV;
508 }
509
510 provisioner_remove_node(index, true);
511 return 0;
512 }
513
bt_mesh_provisioner_delete_node_with_node_addr(uint16_t unicast_addr)514 int bt_mesh_provisioner_delete_node_with_node_addr(uint16_t unicast_addr)
515 {
516 struct bt_mesh_node *node = NULL;
517 uint16_t index = 0U;
518
519 node = provisioner_find_node_with_addr(unicast_addr, &index);
520 if (!node) {
521 BT_WARN("Node not found, addr 0x%04x", unicast_addr);
522 return -ENODEV;
523 }
524
525 provisioner_remove_node(index, true);
526 return 0;
527 }
528
bt_mesh_provisioner_delete_node_with_dev_addr(const bt_mesh_addr_t * addr)529 int bt_mesh_provisioner_delete_node_with_dev_addr(const bt_mesh_addr_t *addr)
530 {
531 int i;
532
533 for (i = 0; i < ARRAY_SIZE(mesh_nodes); i++) {
534 if (mesh_nodes[i] && mesh_nodes[i]->addr_type == addr->type &&
535 !memcmp(mesh_nodes[i]->addr, addr->val, BLE_MESH_ADDR_LEN)) {
536 return provisioner_remove_node(i, true);
537 }
538 }
539
540 BT_WARN("Node not exist, device address %s", bt_hex(addr->val, BLE_MESH_ADDR_LEN));
541 return -ENODEV;
542 }
543
provisioner_find_node_with_name(const char * name)544 static struct bt_mesh_node **provisioner_find_node_with_name(const char *name)
545 {
546 size_t length = 0U;
547 int i;
548
549 BT_DBG("node name %s", name);
550
551 length = MIN(strlen(name), BLE_MESH_NODE_NAME_SIZE);
552
553 bt_mesh_provisioner_lock();
554
555 for (i = 0; i < ARRAY_SIZE(mesh_nodes); i++) {
556 if (mesh_nodes[i]) {
557 if (strlen(mesh_nodes[i]->name) != length) {
558 continue;
559 }
560 if (!strncmp(mesh_nodes[i]->name, name, length)) {
561 bt_mesh_provisioner_unlock();
562 return &mesh_nodes[i];
563 }
564 }
565 }
566
567 bt_mesh_provisioner_unlock();
568 return NULL;
569 }
570
bt_mesh_provisioner_set_node_name(uint16_t index,const char * name)571 int bt_mesh_provisioner_set_node_name(uint16_t index, const char *name)
572 {
573 if (index >= ARRAY_SIZE(mesh_nodes)) {
574 BT_ERR("Invalid node index %d", index);
575 return -EINVAL;
576 }
577
578 if (mesh_nodes[index] == NULL) {
579 BT_ERR("Node not exists, index %d", index);
580 return -EINVAL;
581 }
582
583 if (name == NULL) {
584 BT_ERR("Invalid node name");
585 return -EINVAL;
586 }
587
588 if (provisioner_find_node_with_name(name)) {
589 BT_WARN("Node name \"%s\" already exists", name);
590 return -EEXIST;
591 }
592
593 memset(mesh_nodes[index]->name, 0, sizeof(mesh_nodes[index]->name));
594 strncpy(mesh_nodes[index]->name, name, BLE_MESH_NODE_NAME_SIZE);
595
596 if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) {
597 bt_mesh_store_node_name(mesh_nodes[index]);
598 }
599
600 return 0;
601 }
602
bt_mesh_provisioner_get_node_name(uint16_t index)603 const char *bt_mesh_provisioner_get_node_name(uint16_t index)
604 {
605 if (index >= ARRAY_SIZE(mesh_nodes)) {
606 BT_ERR("Invalid node index %d", index);
607 return NULL;
608 }
609
610 if (mesh_nodes[index] == NULL) {
611 BT_ERR("Node not exists, index %d", index);
612 return NULL;
613 }
614
615 return mesh_nodes[index]->name;
616 }
617
bt_mesh_provisioner_get_node_index(const char * name)618 uint16_t bt_mesh_provisioner_get_node_index(const char *name)
619 {
620 struct bt_mesh_node **node = NULL;
621
622 if (name == NULL) {
623 BT_ERR("Invalid node name");
624 return BLE_MESH_INVALID_NODE_INDEX;
625 }
626
627 node = provisioner_find_node_with_name(name);
628 if (node == NULL) {
629 BT_ERR("Node name \"%s\" not exists", name);
630 return BLE_MESH_INVALID_NODE_INDEX;
631 }
632
633 return (node - mesh_nodes);
634 }
635
bt_mesh_provisioner_get_node_with_name(const char * name)636 struct bt_mesh_node *bt_mesh_provisioner_get_node_with_name(const char *name)
637 {
638 struct bt_mesh_node **node = NULL;
639
640 if (name == NULL) {
641 BT_ERR("Invalid node name");
642 return NULL;
643 }
644
645 node = provisioner_find_node_with_name(name);
646 if (node == NULL) {
647 BT_ERR("Node name \"%s\" not exists", name);
648 return NULL;
649 }
650
651 return *node;
652 }
653
bt_mesh_provisioner_get_node_table_entry(void)654 const struct bt_mesh_node **bt_mesh_provisioner_get_node_table_entry(void)
655 {
656 return (const struct bt_mesh_node **)mesh_nodes;
657 }
658
659 #define COMP_DATA_PAGE_0_MIN_LEN 16
660
store_node_comp_data(uint16_t addr,const uint8_t * data,uint16_t length,bool store)661 static int store_node_comp_data(uint16_t addr, const uint8_t *data, uint16_t length, bool store)
662 {
663 struct bt_mesh_node *node = NULL;
664
665 if (!BLE_MESH_ADDR_IS_UNICAST(addr)) {
666 BT_ERR("Invalid unicast address 0x%04x", addr);
667 return -EINVAL;
668 }
669
670 if (data == NULL || (length % 2) || length < COMP_DATA_PAGE_0_MIN_LEN) {
671 BT_ERR("Invalid composition data");
672 return -EINVAL;
673 }
674
675 node = provisioner_find_node_with_addr(addr, NULL);
676 if (node == NULL) {
677 BT_ERR("Node not found, addr 0x%04x", addr);
678 return -ENODEV;
679 }
680
681 node->comp_data = bt_mesh_calloc(length);
682 if (node->comp_data == NULL) {
683 BT_ERR("%s, Out of memory", __func__);
684 return -ENOMEM;
685 }
686
687 memcpy(node->comp_data, data, length);
688 node->comp_length = length;
689
690 if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS) && store) {
691 bt_mesh_store_node_comp_data(node);
692 }
693
694 return 0;
695 }
696
bt_mesh_provisioner_store_node_comp_data(uint16_t addr,const uint8_t * data,uint16_t length)697 int bt_mesh_provisioner_store_node_comp_data(uint16_t addr, const uint8_t *data, uint16_t length)
698 {
699 return store_node_comp_data(addr, data, length, true);
700 }
701
bt_mesh_provisioner_restore_node_comp_data(uint16_t addr,const uint8_t * data,uint16_t length)702 int bt_mesh_provisioner_restore_node_comp_data(uint16_t addr, const uint8_t *data, uint16_t length)
703 {
704 return store_node_comp_data(addr, data, length, false);
705 }
706
707 /* Provisioner DevKey, NetKey and AppKey related functions */
708
bt_mesh_provisioner_net_key_get(uint16_t net_idx)709 const uint8_t *bt_mesh_provisioner_net_key_get(uint16_t net_idx)
710 {
711 struct bt_mesh_subnet *sub = NULL;
712 int i;
713
714 BT_DBG("%s", __func__);
715
716 for (i = 0; i < ARRAY_SIZE(bt_mesh.p_sub); i++) {
717 sub = bt_mesh.p_sub[i];
718 if (sub && sub->net_idx == net_idx) {
719 if (sub->kr_flag) {
720 return sub->keys[1].net;
721 } else {
722 return sub->keys[0].net;
723 }
724 }
725 }
726
727 return NULL;
728 }
729
bt_mesh_provisioner_subnet_get(uint16_t net_idx)730 struct bt_mesh_subnet *bt_mesh_provisioner_subnet_get(uint16_t net_idx)
731 {
732 struct bt_mesh_subnet *sub = NULL;
733 int i;
734
735 BT_DBG("%s", __func__);
736
737 if (net_idx == BLE_MESH_KEY_ANY) {
738 return bt_mesh.p_sub[0];
739 }
740
741 for (i = 0; i < ARRAY_SIZE(bt_mesh.p_sub); i++) {
742 sub = bt_mesh.p_sub[i];
743 if (sub && sub->net_idx == net_idx) {
744 return sub;
745 }
746 }
747
748 return NULL;
749 }
750
bt_mesh_provisioner_check_msg_dst(uint16_t dst)751 bool bt_mesh_provisioner_check_msg_dst(uint16_t dst)
752 {
753 struct bt_mesh_node *node = NULL;
754 int i;
755
756 BT_DBG("%s", __func__);
757
758 if (!BLE_MESH_ADDR_IS_UNICAST(dst)) {
759 return true;
760 }
761
762 for (i = 0; i < ARRAY_SIZE(mesh_nodes); i++) {
763 node = mesh_nodes[i];
764 if (node && dst >= node->unicast_addr &&
765 dst < node->unicast_addr + node->element_num) {
766 return true;
767 }
768 }
769
770 return false;
771 }
772
bt_mesh_provisioner_dev_key_get(uint16_t dst)773 const uint8_t *bt_mesh_provisioner_dev_key_get(uint16_t dst)
774 {
775 /* Device key is only used to encrypt configuration messages.
776 * Configuration model shall only be supported by the primary
777 * element which uses the primary unicast address.
778 */
779 struct bt_mesh_node *node = NULL;
780 int i;
781
782 BT_DBG("%s", __func__);
783
784 if (!BLE_MESH_ADDR_IS_UNICAST(dst)) {
785 BT_ERR("Invalid unicast address 0x%04x", dst);
786 return NULL;
787 }
788
789 for (i = 0; i < ARRAY_SIZE(mesh_nodes); i++) {
790 node = mesh_nodes[i];
791 if (node && node->unicast_addr == dst) {
792 return node->dev_key;
793 }
794 }
795
796 return NULL;
797 }
798
bt_mesh_provisioner_app_key_find(uint16_t app_idx)799 struct bt_mesh_app_key *bt_mesh_provisioner_app_key_find(uint16_t app_idx)
800 {
801 struct bt_mesh_app_key *key = NULL;
802 int i;
803
804 BT_DBG("%s", __func__);
805
806 for (i = 0; i < ARRAY_SIZE(bt_mesh.p_app_keys); i++) {
807 key = bt_mesh.p_app_keys[i];
808 if (key && key->net_idx != BLE_MESH_KEY_UNUSED &&
809 key->app_idx == app_idx) {
810 return key;
811 }
812 }
813
814 return NULL;
815 }
816
provisioner_check_app_key(const uint8_t app_key[16],uint16_t * app_idx)817 static int provisioner_check_app_key(const uint8_t app_key[16], uint16_t *app_idx)
818 {
819 struct bt_mesh_app_key *key = NULL;
820 int i;
821
822 if (!app_key) {
823 return 0;
824 }
825
826 /* Check if app_key is already existed */
827 for (i = 0; i < ARRAY_SIZE(bt_mesh.p_app_keys); i++) {
828 key = bt_mesh.p_app_keys[i];
829 if (key && (!memcmp(key->keys[0].val, app_key, 16) ||
830 !memcmp(key->keys[1].val, app_key, 16))) {
831 *app_idx = key->app_idx;
832 return -EEXIST;
833 }
834 }
835
836 return 0;
837 }
838
provisioner_check_app_idx(uint16_t app_idx,bool exist)839 static int provisioner_check_app_idx(uint16_t app_idx, bool exist)
840 {
841 struct bt_mesh_app_key *key = NULL;
842 int i;
843
844 if (exist) {
845 /* Check if app_idx is already existed */
846 for (i = 0; i < ARRAY_SIZE(bt_mesh.p_app_keys); i++) {
847 key = bt_mesh.p_app_keys[i];
848 if (key && (key->app_idx == app_idx)) {
849 return -EEXIST;
850 }
851 }
852 return 0;
853 }
854
855 /* Check if app_idx is not existed */
856 for (i = 0; i < ARRAY_SIZE(bt_mesh.p_app_keys); i++) {
857 key = bt_mesh.p_app_keys[i];
858 if (key && (key->app_idx == app_idx)) {
859 return 0;
860 }
861 }
862
863 return -ENODEV;
864 }
865
provisioner_check_app_key_full(void)866 static int provisioner_check_app_key_full(void)
867 {
868 int i;
869
870 for (i = 0; i < ARRAY_SIZE(bt_mesh.p_app_keys); i++) {
871 if (!bt_mesh.p_app_keys[i]) {
872 return i;
873 }
874 }
875
876 return -ENOMEM;
877 }
878
provisioner_check_net_key(const uint8_t net_key[16],uint16_t * net_idx)879 static int provisioner_check_net_key(const uint8_t net_key[16], uint16_t *net_idx)
880 {
881 struct bt_mesh_subnet *sub = NULL;
882 int i;
883
884 if (!net_key) {
885 return 0;
886 }
887
888 /* Check if net_key is already existed */
889 for (i = 0; i < ARRAY_SIZE(bt_mesh.p_sub); i++) {
890 sub = bt_mesh.p_sub[i];
891 if (sub && (!memcmp(sub->keys[0].net, net_key, 16) ||
892 !memcmp(sub->keys[1].net, net_key, 16))) {
893 *net_idx = sub->net_idx;
894 return -EEXIST;
895 }
896 }
897
898 return 0;
899 }
900
provisioner_check_net_idx(uint16_t net_idx,bool exist)901 static int provisioner_check_net_idx(uint16_t net_idx, bool exist)
902 {
903 struct bt_mesh_subnet *sub = NULL;
904 int i;
905
906 if (exist) {
907 /* Check if net_idx is already existed */
908 for (i = 0; i < ARRAY_SIZE(bt_mesh.p_sub); i++) {
909 sub = bt_mesh.p_sub[i];
910 if (sub && (sub->net_idx == net_idx)) {
911 return -EEXIST;
912 }
913 }
914 return 0;
915 }
916
917 /* Check if net_idx is not existed */
918 for (i = 0; i < ARRAY_SIZE(bt_mesh.p_sub); i++) {
919 sub = bt_mesh.p_sub[i];
920 if (sub && (sub->net_idx == net_idx)) {
921 return 0;
922 }
923 }
924
925 return -ENODEV;
926 }
927
provisioner_check_net_key_full(void)928 static int provisioner_check_net_key_full(void)
929 {
930 int i;
931
932 for (i = 0; i < ARRAY_SIZE(bt_mesh.p_sub); i++) {
933 if (!bt_mesh.p_sub[i]) {
934 return i;
935 }
936 }
937
938 return -ENOMEM;
939 }
940
bt_mesh_provisioner_local_app_key_add(const uint8_t app_key[16],uint16_t net_idx,uint16_t * app_idx)941 int bt_mesh_provisioner_local_app_key_add(const uint8_t app_key[16],
942 uint16_t net_idx, uint16_t *app_idx)
943 {
944 struct bt_mesh_app_keys *keys = NULL;
945 struct bt_mesh_app_key *key = NULL;
946 uint8_t p_key[16] = {0};
947 int add = -1;
948
949 if (bt_mesh.p_app_idx_next >= 0x1000) {
950 BT_ERR("No AppKeyIndex available");
951 return -EIO;
952 }
953
954 if (!app_idx || (*app_idx != 0xFFFF && *app_idx >= 0x1000)) {
955 BT_ERR("%s, Invalid parameter", __func__);
956 return -EINVAL;
957 }
958
959 /* Check if the same application key already exists */
960 if (provisioner_check_app_key(app_key, app_idx)) {
961 BT_WARN("AppKey exists, AppKeyIndex updated");
962 return 0;
963 }
964
965 /* Check if the net_idx exists */
966 if (provisioner_check_net_idx(net_idx, false)) {
967 BT_ERR("Invalid NetKeyIndex 0x%04x", net_idx);
968 return -ENODEV;
969 }
970
971 /* Check if the same app_idx already exists */
972 if (provisioner_check_app_idx(*app_idx, true)) {
973 BT_ERR("Invalid AppKeyIndex 0x%04x", *app_idx);
974 return -EEXIST;
975 }
976
977 add = provisioner_check_app_key_full();
978 if (add < 0) {
979 BT_ERR("AppKey is full!");
980 return -ENOMEM;
981 }
982
983 if (!app_key) {
984 if (bt_mesh_rand(p_key, 16)) {
985 BT_ERR("Failed to generate AppKey");
986 return -EIO;
987 }
988 } else {
989 memcpy(p_key, app_key, 16);
990 }
991
992 key = bt_mesh_calloc(sizeof(struct bt_mesh_app_key));
993 if (!key) {
994 BT_ERR("%s, Out of memory", __func__);
995 return -ENOMEM;
996 }
997
998 keys = &key->keys[0];
999 if (bt_mesh_app_id(p_key, &keys->id)) {
1000 BT_ERR("Failed to generate AID");
1001 bt_mesh_free(key);
1002 return -EIO;
1003 }
1004
1005 memcpy(keys->val, p_key, 16);
1006 key->net_idx = net_idx;
1007 if (*app_idx != 0xFFFF) {
1008 key->app_idx = *app_idx;
1009 } else {
1010 key->app_idx = bt_mesh.p_app_idx_next;
1011 while (1) {
1012 if (provisioner_check_app_idx(key->app_idx, true)) {
1013 key->app_idx = (++bt_mesh.p_app_idx_next);
1014 if (key->app_idx >= 0x1000) {
1015 BT_ERR("No AppKeyIndex available");
1016 bt_mesh_free(key);
1017 return -EIO;
1018 }
1019 } else {
1020 break;
1021 }
1022 }
1023 *app_idx = key->app_idx;
1024 bt_mesh.p_app_idx_next++;
1025 }
1026 key->updated = false;
1027
1028 bt_mesh.p_app_keys[add] = key;
1029
1030 if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) {
1031 bt_mesh_store_p_app_idx();
1032 bt_mesh_store_p_app_key(key);
1033 }
1034
1035 return 0;
1036 }
1037
bt_mesh_provisioner_local_app_key_update(const uint8_t app_key[16],uint16_t net_idx,uint16_t app_idx)1038 int bt_mesh_provisioner_local_app_key_update(const uint8_t app_key[16],
1039 uint16_t net_idx, uint16_t app_idx)
1040 {
1041 struct bt_mesh_app_keys *keys = NULL;
1042 struct bt_mesh_app_key *key = NULL;
1043
1044 if (app_key == NULL) {
1045 BT_ERR("Invalid AppKey");
1046 return -EINVAL;
1047 }
1048
1049 BT_INFO("AppKey %s, net_idx 0x%03x, app_idx 0x%03x", bt_hex(app_key, 16), net_idx, app_idx);
1050
1051 /* Check if the net_idx exists */
1052 if (provisioner_check_net_idx(net_idx, false)) {
1053 BT_ERR("Invalid NetKeyIndex 0x%04x", net_idx);
1054 return -ENODEV;
1055 }
1056
1057 key = bt_mesh_provisioner_app_key_find(app_idx);
1058 if (key == NULL) {
1059 BT_ERR("Invalid AppKeyIndex 0x%04x", app_idx);
1060 return -ENODEV;
1061 }
1062
1063 keys = &key->keys[0];
1064 if (bt_mesh_app_id(app_key, &keys->id)) {
1065 BT_ERR("Failed to generate AID");
1066 return -EIO;
1067 }
1068
1069 memset(keys->val, 0, 16);
1070 memcpy(keys->val, app_key, 16);
1071
1072 key->updated = false;
1073
1074 if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) {
1075 bt_mesh_store_p_app_idx();
1076 bt_mesh_store_p_app_key(key);
1077 }
1078
1079 return 0;
1080 }
1081
bt_mesh_provisioner_local_app_key_get(uint16_t net_idx,uint16_t app_idx)1082 const uint8_t *bt_mesh_provisioner_local_app_key_get(uint16_t net_idx, uint16_t app_idx)
1083 {
1084 struct bt_mesh_app_key *key = NULL;
1085 int i;
1086
1087 BT_DBG("%s", __func__);
1088
1089 if (provisioner_check_net_idx(net_idx, false)) {
1090 BT_ERR("Invalid NetKeyIndex 0x%04x", net_idx);
1091 return NULL;
1092 }
1093
1094 if (provisioner_check_app_idx(app_idx, false)) {
1095 BT_ERR("Invalid AppKeyIndex 0x%04x", app_idx);
1096 return NULL;
1097 }
1098
1099 for (i = 0; i < ARRAY_SIZE(bt_mesh.p_app_keys); i++) {
1100 key = bt_mesh.p_app_keys[i];
1101 if (key && key->net_idx == net_idx &&
1102 key->app_idx == app_idx) {
1103 if (key->updated) {
1104 return key->keys[1].val;
1105 }
1106 return key->keys[0].val;
1107 }
1108 }
1109
1110 return NULL;
1111 }
1112
model_pub_clear(struct bt_mesh_model * model,bool store)1113 static void model_pub_clear(struct bt_mesh_model *model, bool store)
1114 {
1115 if (!model->pub) {
1116 return;
1117 }
1118
1119 if (model->pub->addr == BLE_MESH_ADDR_UNASSIGNED) {
1120 return;
1121 }
1122
1123 model->pub->addr = BLE_MESH_ADDR_UNASSIGNED;
1124 model->pub->key = 0U;
1125 model->pub->cred = 0U;
1126 model->pub->ttl = 0U;
1127 model->pub->period = 0U;
1128 model->pub->retransmit = 0U;
1129 model->pub->count = 0U;
1130
1131 if (model->pub->update) {
1132 k_delayed_work_cancel(&model->pub->timer);
1133 }
1134
1135 if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS) && store) {
1136 bt_mesh_store_mod_pub(model);
1137 }
1138
1139 return;
1140 }
1141
model_unbind(struct bt_mesh_model * model,uint16_t app_idx,bool store)1142 static void model_unbind(struct bt_mesh_model *model, uint16_t app_idx, bool store)
1143 {
1144 int i;
1145
1146 BT_DBG("model %p app_idx 0x%03x", model, app_idx);
1147
1148 for (i = 0; i < ARRAY_SIZE(model->keys); i++) {
1149 if (model->keys[i] != app_idx) {
1150 continue;
1151 }
1152
1153 model->keys[i] = BLE_MESH_KEY_UNUSED;
1154
1155 if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS) && store) {
1156 bt_mesh_store_mod_bind(model);
1157 }
1158
1159 model_pub_clear(model, store);
1160 }
1161 }
1162
1163 struct unbind_data {
1164 uint16_t app_idx;
1165 bool store;
1166 };
1167
_model_unbind(struct bt_mesh_model * mod,struct bt_mesh_elem * elem,bool vnd,bool primary,void * user_data)1168 static void _model_unbind(struct bt_mesh_model *mod, struct bt_mesh_elem *elem,
1169 bool vnd, bool primary, void *user_data)
1170 {
1171 struct unbind_data *data = user_data;
1172
1173 model_unbind(mod, data->app_idx, data->store);
1174 }
1175
bt_mesh_provisioner_local_app_key_del(uint16_t net_idx,uint16_t app_idx,bool store)1176 int bt_mesh_provisioner_local_app_key_del(uint16_t net_idx, uint16_t app_idx, bool store)
1177 {
1178 struct unbind_data data = { .app_idx = app_idx, .store = store };
1179 struct bt_mesh_app_key *key = NULL;
1180 int i;
1181
1182 BT_DBG("%s", __func__);
1183
1184 if (provisioner_check_net_idx(net_idx, false)) {
1185 BT_ERR("Invalid NetKeyIndex 0x%04x", net_idx);
1186 return -ENODEV;
1187 }
1188
1189 if (provisioner_check_app_idx(app_idx, false)) {
1190 BT_ERR("Invalid AppKeyIndex 0x%04x", app_idx);
1191 return -ENODEV;
1192 }
1193
1194 for (i = 0; i < ARRAY_SIZE(bt_mesh.p_app_keys); i++) {
1195 key = bt_mesh.p_app_keys[i];
1196 if (key && key->net_idx == net_idx &&
1197 key->app_idx == app_idx) {
1198 /* Remove the AppKey from the models if they are bound with it */
1199 bt_mesh_model_foreach(_model_unbind, &data);
1200
1201 if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS) && store) {
1202 bt_mesh_clear_p_app_key(app_idx);
1203 }
1204
1205 bt_mesh_free(bt_mesh.p_app_keys[i]);
1206 bt_mesh.p_app_keys[i] = NULL;
1207 return 0;
1208 }
1209 }
1210
1211 /* Shall never reach here */
1212 return -ENODEV;
1213 }
1214
bt_mesh_provisioner_local_net_key_add(const uint8_t net_key[16],uint16_t * net_idx)1215 int bt_mesh_provisioner_local_net_key_add(const uint8_t net_key[16], uint16_t *net_idx)
1216 {
1217 struct bt_mesh_subnet *sub = NULL;
1218 uint8_t p_key[16] = {0};
1219 int add = -1;
1220
1221 if (bt_mesh.p_net_idx_next >= 0x1000) {
1222 BT_ERR("No NetKeyIndex available");
1223 return -EIO;
1224 }
1225
1226 if (!net_idx || (*net_idx != 0xFFFF && *net_idx >= 0x1000)) {
1227 BT_ERR("%s, Invalid parameter", __func__);
1228 return -EINVAL;
1229 }
1230
1231 /* Check if the same network key already exists */
1232 if (provisioner_check_net_key(net_key, net_idx)) {
1233 BT_WARN("NetKey exists, NetKeyIndex updated");
1234 return 0;
1235 }
1236
1237 /* Check if the same net_idx already exists */
1238 if (provisioner_check_net_idx(*net_idx, true)) {
1239 BT_ERR("Invalid NetKeyIndex 0x%04x", *net_idx);
1240 return -EEXIST;
1241 }
1242
1243 add = provisioner_check_net_key_full();
1244 if (add < 0) {
1245 BT_ERR("NetKey is full!");
1246 return -ENOMEM;
1247 }
1248
1249 if (!net_key) {
1250 if (bt_mesh_rand(p_key, 16)) {
1251 BT_ERR("Failed to generate NetKey");
1252 return -EIO;
1253 }
1254 } else {
1255 memcpy(p_key, net_key, 16);
1256 }
1257
1258 sub = bt_mesh_calloc(sizeof(struct bt_mesh_subnet));
1259 if (!sub) {
1260 BT_ERR("%s, Out of memory", __func__);
1261 return -ENOMEM;
1262 }
1263
1264 if (bt_mesh_net_keys_create(&sub->keys[0], p_key)) {
1265 BT_ERR("Failed to generate NID");
1266 bt_mesh_free(sub);
1267 return -EIO;
1268 }
1269
1270 if (*net_idx != 0xFFFF) {
1271 sub->net_idx = *net_idx;
1272 } else {
1273 sub->net_idx = bt_mesh.p_net_idx_next;
1274 while (1) {
1275 if (provisioner_check_net_idx(sub->net_idx, true)) {
1276 sub->net_idx = (++bt_mesh.p_net_idx_next);
1277 if (sub->net_idx >= 0x1000) {
1278 BT_ERR("No NetKeyIndex available");
1279 bt_mesh_free(sub);
1280 return -EIO;
1281 }
1282 } else {
1283 break;
1284 }
1285 }
1286 *net_idx = sub->net_idx;
1287 bt_mesh.p_net_idx_next++;
1288 }
1289 sub->kr_phase = BLE_MESH_KR_NORMAL;
1290 sub->kr_flag = false;
1291 sub->node_id = BLE_MESH_NODE_IDENTITY_NOT_SUPPORTED;
1292
1293 bt_mesh.p_sub[add] = sub;
1294
1295 if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) {
1296 bt_mesh_store_p_net_idx();
1297 bt_mesh_store_p_subnet(sub);
1298 }
1299
1300 return 0;
1301 }
1302
bt_mesh_provisioner_local_net_key_update(const uint8_t net_key[16],uint16_t net_idx)1303 int bt_mesh_provisioner_local_net_key_update(const uint8_t net_key[16], uint16_t net_idx)
1304 {
1305 struct bt_mesh_subnet *sub = NULL;
1306 int err = 0;
1307
1308 if (net_key == NULL) {
1309 BT_ERR("Invalid NetKey");
1310 return -EINVAL;
1311 }
1312
1313 BT_INFO("NetKey %s, net_idx 0x%03x", bt_hex(net_key, 16), net_idx);
1314
1315 sub = bt_mesh_provisioner_subnet_get(net_idx);
1316 if (sub == NULL) {
1317 BT_ERR("Invalid NetKeyIndex 0x%04x", net_idx);
1318 return -ENODEV;
1319 }
1320
1321 err = bt_mesh_net_keys_create(&sub->keys[0], net_key);
1322 if (err) {
1323 BT_ERR("Failed to generate NID");
1324 return -EIO;
1325 }
1326
1327 memset(sub->keys[0].net, 0, 16);
1328 memcpy(sub->keys[0].net, net_key, 16);
1329
1330 sub->kr_phase = BLE_MESH_KR_NORMAL;
1331 sub->kr_flag = false;
1332 sub->node_id = BLE_MESH_NODE_IDENTITY_NOT_SUPPORTED;
1333
1334 err = bt_mesh_net_beacon_update(sub);
1335 if (err) {
1336 BT_ERR("Failed to update secure beacon");
1337 return -EIO;
1338 }
1339
1340 if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) {
1341 bt_mesh_store_p_subnet(sub);
1342 }
1343
1344 return 0;
1345 }
1346
bt_mesh_provisioner_local_net_key_get(uint16_t net_idx)1347 const uint8_t *bt_mesh_provisioner_local_net_key_get(uint16_t net_idx)
1348 {
1349 struct bt_mesh_subnet *sub = NULL;
1350 int i;
1351
1352 BT_DBG("%s", __func__);
1353
1354 if (provisioner_check_net_idx(net_idx, false)) {
1355 BT_ERR("Invalid NetKeyIndex 0x%04x", net_idx);
1356 return NULL;
1357 }
1358
1359 for (i = 0; i < ARRAY_SIZE(bt_mesh.p_sub); i++) {
1360 sub = bt_mesh.p_sub[i];
1361 if (sub && sub->net_idx == net_idx) {
1362 if (sub->kr_flag) {
1363 return sub->keys[1].net;
1364 }
1365 return sub->keys[0].net;
1366 }
1367 }
1368
1369 return NULL;
1370 }
1371
bt_mesh_provisioner_local_net_key_del(uint16_t net_idx,bool store)1372 int bt_mesh_provisioner_local_net_key_del(uint16_t net_idx, bool store)
1373 {
1374 struct bt_mesh_subnet *sub = NULL;
1375 int i, j;
1376
1377 BT_DBG("%s", __func__);
1378
1379 if (provisioner_check_net_idx(net_idx, false)) {
1380 BT_ERR("Invalid NetKeyIndex 0x%04x", net_idx);
1381 return -ENODEV;
1382 }
1383
1384 for (i = 0; i < ARRAY_SIZE(bt_mesh.p_sub); i++) {
1385 sub = bt_mesh.p_sub[i];
1386 if (sub && sub->net_idx == net_idx) {
1387 /* Delete any app keys bound to this NetKey index */
1388 for (j = 0; j < ARRAY_SIZE(bt_mesh.p_app_keys); j++) {
1389 struct bt_mesh_app_key *key = bt_mesh.p_app_keys[j];
1390
1391 if (key && key->net_idx == sub->net_idx) {
1392 bt_mesh_provisioner_local_app_key_del(key->net_idx, key->app_idx, store);
1393 }
1394 }
1395
1396 if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS) && store) {
1397 bt_mesh_clear_p_subnet(net_idx);
1398 }
1399
1400 bt_mesh_free(bt_mesh.p_sub[i]);
1401 bt_mesh.p_sub[i] = NULL;
1402 return 0;
1403 }
1404 }
1405
1406 /* Shall never reach here */
1407 return -ENODEV;
1408 }
1409
bt_mesh_provisioner_bind_local_model_app_idx(uint16_t elem_addr,uint16_t mod_id,uint16_t cid,uint16_t app_idx)1410 int bt_mesh_provisioner_bind_local_model_app_idx(uint16_t elem_addr, uint16_t mod_id,
1411 uint16_t cid, uint16_t app_idx)
1412 {
1413 struct bt_mesh_model *model = NULL;
1414 struct bt_mesh_elem *elem = NULL;
1415 int i;
1416
1417 elem = bt_mesh_elem_find(elem_addr);
1418 if (!elem) {
1419 BT_ERR("No element found, addr 0x%04x", elem_addr);
1420 return -ENODEV;
1421 }
1422
1423 if (cid == 0xFFFF) {
1424 model = bt_mesh_model_find(elem, mod_id);
1425 } else {
1426 model = bt_mesh_model_find_vnd(elem, cid, mod_id);
1427 }
1428 if (!model) {
1429 BT_ERR("No model found, model id 0x%04x, cid 0x%04x", mod_id, cid);
1430 return -ENODEV;
1431 }
1432
1433 if (provisioner_check_app_idx(app_idx, false)) {
1434 BT_ERR("Invalid AppKeyIndex 0x%04x", app_idx);
1435 return -ENODEV;
1436 }
1437
1438 for (i = 0; i < ARRAY_SIZE(model->keys); i++) {
1439 if (model->keys[i] == app_idx) {
1440 BT_INFO("AppKey 0x%03x already bound to model", app_idx);
1441 return 0;
1442 }
1443 }
1444
1445 for (i = 0; i < ARRAY_SIZE(model->keys); i++) {
1446 if (model->keys[i] == BLE_MESH_KEY_UNUSED) {
1447 model->keys[i] = app_idx;
1448
1449 if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) {
1450 bt_mesh_store_mod_bind(model);
1451 }
1452 return 0;
1453 }
1454 }
1455
1456 BT_ERR("Model bound is full!");
1457 return -ENOMEM;
1458 }
1459
bt_mesh_print_local_composition_data(void)1460 int bt_mesh_print_local_composition_data(void)
1461 {
1462 const struct bt_mesh_comp *comp = NULL;
1463 struct bt_mesh_model *model = NULL;
1464 struct bt_mesh_elem *elem = NULL;
1465 int i, j;
1466
1467 comp = bt_mesh_comp_get();
1468 if (!comp) {
1469 BT_ERR("Invalid composition data");
1470 return -EINVAL;
1471 }
1472
1473 BT_INFO("************************************************");
1474 BT_INFO("* cid: 0x%04x pid: 0x%04x vid: 0x%04x *", comp->cid, comp->pid, comp->vid);
1475 BT_INFO("* Element Number: 0x%02x *", comp->elem_count);
1476 for (i = 0; i < comp->elem_count; i++) {
1477 elem = &comp->elem[i];
1478 BT_INFO("* Element %d: 0x%04x *", i, elem->addr);
1479 BT_INFO("* Loc: 0x%04x NumS: 0x%02x NumV: 0x%02x *", elem->loc, elem->model_count, elem->vnd_model_count);
1480 for (j = 0; j < elem->model_count; j++) {
1481 model = &elem->models[j];
1482 BT_INFO("* sig_model %d: id - 0x%04x *", j, model->id);
1483 }
1484 for (j = 0; j < elem->vnd_model_count; j++) {
1485 model = &elem->vnd_models[j];
1486 BT_INFO("* vnd_model %d: id - 0x%04x, cid - 0x%04x *", j, model->vnd.id, model->vnd.company);
1487 }
1488 }
1489 BT_INFO("************************************************");
1490
1491 ((void) model);
1492
1493 return 0;
1494 }
1495
1496 #if CONFIG_BLE_MESH_TEST_AUTO_ENTER_NETWORK
bt_mesh_provisioner_store_node_info(struct bt_mesh_node * node)1497 int bt_mesh_provisioner_store_node_info(struct bt_mesh_node *node)
1498 {
1499 int err = 0;
1500
1501 if (!node) {
1502 BT_ERR("%s, Invalid parameter", __func__);
1503 return -EINVAL;
1504 }
1505
1506 if (!BLE_MESH_ADDR_IS_UNICAST(node->unicast_addr)) {
1507 BT_ERR("Invalid unicast address 0x%04x", node->unicast_addr);
1508 return -EINVAL;
1509 }
1510
1511 if (node->element_num == 0) {
1512 BT_ERR("Invalid element count %d", node->element_num);
1513 return -EINVAL;
1514 }
1515
1516 if (bt_mesh_provisioner_check_is_addr_dup(node->unicast_addr, node->element_num, true)) {
1517 BT_ERR("Duplicate unicast address 0x%04x", node->unicast_addr);
1518 return -EINVAL;
1519 }
1520
1521 if (node->unicast_addr + node->element_num - 1 > 0x7FFF) {
1522 BT_ERR("Not enough unicast address for the node");
1523 return -EIO;
1524 }
1525
1526 if (bt_mesh_provisioner_net_key_get(node->net_idx) == NULL) {
1527 BT_ERR("Invalid NetKeyIndex 0x%04x", node->net_idx);
1528 return -EINVAL;
1529 }
1530
1531 err = provisioner_store_node(node, true, NULL);
1532 if (err) {
1533 BT_ERR("Failed to store node info");
1534 return err;
1535 }
1536
1537 bt_mesh_test_provisioner_update_alloc_addr(node->unicast_addr, node->element_num);
1538 return 0;
1539 }
1540 #endif /* CONFIG_BLE_MESH_TEST_AUTO_ENTER_NETWORK */
1541
1542 #if CONFIG_BLE_MESH_PROVISIONER_RECV_HB
1543
1544 #define HEARTBEAT_FILTER_ACCEPTLIST 0x00
1545 #define HEARTBEAT_FILTER_REJECTLIST 0x01
1546
1547 #define HEARTBEAT_FILTER_ADD 0x00
1548 #define HEARTBEAT_FILTER_REMOVE 0x01
1549
1550 #define HEARTBEAT_FILTER_WITH_SRC BIT(0)
1551 #define HEARTBEAT_FILTER_WITH_DST BIT(1)
1552 #define HEARTBEAT_FILTER_WITH_BOTH (BIT(1) | BIT(0))
1553
1554 static struct heartbeat_recv {
1555 struct heartbeat_filter {
1556 uint8_t type; /* Indicate if using src or dst or both to filter heartbeat messages */
1557 uint16_t src; /* Heartbeat source address (unicast address) */
1558 uint16_t dst; /* Heartbeat destination address (unicast address or group address) */
1559 } filter[CONFIG_BLE_MESH_PROVISIONER_RECV_HB_FILTER_SIZE];
1560 uint8_t type; /* Heartbeat filter type */
1561 bt_mesh_heartbeat_recv_cb_t cb; /* Heartbeat receive callback */
1562 } hb_rx;
1563
bt_mesh_provisioner_recv_heartbeat(bt_mesh_heartbeat_recv_cb_t cb)1564 int bt_mesh_provisioner_recv_heartbeat(bt_mesh_heartbeat_recv_cb_t cb)
1565 {
1566 memset(&hb_rx, 0, sizeof(hb_rx));
1567
1568 /* Start with an empty rejectlist, which means all heartbeat messages will be reported */
1569 hb_rx.type = HEARTBEAT_FILTER_REJECTLIST;
1570 hb_rx.cb = cb;
1571
1572 return 0;
1573 }
1574
bt_mesh_provisioner_set_heartbeat_filter_type(uint8_t type)1575 int bt_mesh_provisioner_set_heartbeat_filter_type(uint8_t type)
1576 {
1577 if (type > HEARTBEAT_FILTER_REJECTLIST) {
1578 BT_ERR("Invalid heartbeat filter type 0x%02x", type);
1579 return -EINVAL;
1580 }
1581
1582 /* If the heartbeat filter type is different with previous one,
1583 * clear the existing filter entries.
1584 */
1585 if (hb_rx.type != type) {
1586 memset(&hb_rx, 0, offsetof(struct heartbeat_recv, cb));
1587 hb_rx.type = type;
1588 }
1589
1590 return 0;
1591 }
1592
get_filter_addr_type(uint16_t src,uint16_t dst)1593 static inline uint8_t get_filter_addr_type(uint16_t src, uint16_t dst)
1594 {
1595 if (BLE_MESH_ADDR_IS_UNICAST(src)) {
1596 if (BLE_MESH_ADDR_IS_UNICAST(dst) || BLE_MESH_ADDR_IS_GROUP(dst)) {
1597 return HEARTBEAT_FILTER_WITH_BOTH;
1598 } else {
1599 return HEARTBEAT_FILTER_WITH_SRC;
1600 }
1601 } else {
1602 return HEARTBEAT_FILTER_WITH_DST;
1603 }
1604 }
1605
hb_filter_alloc(uint16_t src,uint16_t dst)1606 static int hb_filter_alloc(uint16_t src, uint16_t dst)
1607 {
1608 int i;
1609
1610 for (i = 0; i < ARRAY_SIZE(hb_rx.filter); i++) {
1611 struct heartbeat_filter *filter = &hb_rx.filter[i];
1612
1613 if (filter->src == BLE_MESH_ADDR_UNASSIGNED &&
1614 filter->dst == BLE_MESH_ADDR_UNASSIGNED) {
1615 filter->type = get_filter_addr_type(src, dst);
1616 filter->src = src;
1617 filter->dst = dst;
1618 return 0;
1619 }
1620 }
1621
1622 BT_ERR("Heartbeat filter is full!");
1623 return -ENOMEM;
1624 }
1625
hb_filter_add(uint16_t src,uint16_t dst)1626 static int hb_filter_add(uint16_t src, uint16_t dst)
1627 {
1628 int i;
1629
1630 if (!BLE_MESH_ADDR_IS_UNICAST(src) &&
1631 !BLE_MESH_ADDR_IS_UNICAST(dst) && !BLE_MESH_ADDR_IS_GROUP(dst)) {
1632 BT_ERR("Invalid filter address, src 0x%04x, dst 0x%04x", src, dst);
1633 return -EINVAL;
1634 }
1635
1636 /* Check if filter entries with the same src or dst exist. */
1637 for (i = 0; i < ARRAY_SIZE(hb_rx.filter); i++) {
1638 struct heartbeat_filter *filter = &hb_rx.filter[i];
1639
1640 if ((BLE_MESH_ADDR_IS_UNICAST(src) && filter->src == src) ||
1641 ((BLE_MESH_ADDR_IS_UNICAST(dst) || BLE_MESH_ADDR_IS_GROUP(dst)) &&
1642 filter->dst == dst)) {
1643 memset(filter, 0, sizeof(struct heartbeat_filter));
1644 }
1645 }
1646
1647 return hb_filter_alloc(src, dst);
1648 }
1649
hb_filter_remove(uint16_t src,uint16_t dst)1650 static int hb_filter_remove(uint16_t src, uint16_t dst)
1651 {
1652 int i;
1653
1654 if (!BLE_MESH_ADDR_IS_UNICAST(src) &&
1655 !BLE_MESH_ADDR_IS_UNICAST(dst) && !BLE_MESH_ADDR_IS_GROUP(dst)) {
1656 BT_ERR("Invalid filter address, src 0x%04x, dst 0x%04x", src, dst);
1657 return -EINVAL;
1658 }
1659
1660 for (i = 0; i < ARRAY_SIZE(hb_rx.filter); i++) {
1661 struct heartbeat_filter *filter = &hb_rx.filter[i];
1662
1663 if ((BLE_MESH_ADDR_IS_UNICAST(src) && filter->src == src) ||
1664 ((BLE_MESH_ADDR_IS_UNICAST(dst) || BLE_MESH_ADDR_IS_GROUP(dst)) &&
1665 filter->dst == dst)) {
1666 memset(filter, 0, sizeof(struct heartbeat_filter));
1667 }
1668 }
1669
1670 return 0;
1671 }
1672
bt_mesh_provisioner_set_heartbeat_filter_info(uint8_t op,uint16_t src,uint16_t dst)1673 int bt_mesh_provisioner_set_heartbeat_filter_info(uint8_t op, uint16_t src, uint16_t dst)
1674 {
1675 switch (op) {
1676 case HEARTBEAT_FILTER_ADD:
1677 return hb_filter_add(src, dst);
1678 case HEARTBEAT_FILTER_REMOVE:
1679 return hb_filter_remove(src, dst);
1680 default:
1681 BT_ERR("Invalid heartbeat filter opcode 0x%02x", op);
1682 return -EINVAL;
1683 }
1684 }
1685
filter_with_rejectlist(uint16_t hb_src,uint16_t hb_dst)1686 static bool filter_with_rejectlist(uint16_t hb_src, uint16_t hb_dst)
1687 {
1688 int i;
1689
1690 for (i = 0; i < ARRAY_SIZE(hb_rx.filter); i++) {
1691 struct heartbeat_filter *filter = &hb_rx.filter[i];
1692
1693 switch (filter->type) {
1694 case HEARTBEAT_FILTER_WITH_SRC:
1695 if (hb_src == filter->src) {
1696 return true;
1697 }
1698 break;
1699 case HEARTBEAT_FILTER_WITH_DST:
1700 if (hb_dst == filter->dst) {
1701 return true;
1702 }
1703 break;
1704 case HEARTBEAT_FILTER_WITH_BOTH:
1705 if (hb_src == filter->src && hb_dst == filter->dst) {
1706 return true;
1707 }
1708 break;
1709 default:
1710 BT_DBG("Unknown filter addr type 0x%02x", filter->type);
1711 break;
1712 }
1713 }
1714
1715 return false;
1716 }
1717
filter_with_acceptlist(uint16_t hb_src,uint16_t hb_dst)1718 static bool filter_with_acceptlist(uint16_t hb_src, uint16_t hb_dst)
1719 {
1720 int i;
1721
1722 for (i = 0; i < ARRAY_SIZE(hb_rx.filter); i++) {
1723 struct heartbeat_filter *filter = &hb_rx.filter[i];
1724
1725 switch (filter->type) {
1726 case HEARTBEAT_FILTER_WITH_SRC:
1727 if (hb_src == filter->src) {
1728 return false;
1729 }
1730 break;
1731 case HEARTBEAT_FILTER_WITH_DST:
1732 if (hb_dst == filter->dst) {
1733 return false;
1734 }
1735 break;
1736 case HEARTBEAT_FILTER_WITH_BOTH:
1737 if (hb_src == filter->src && hb_dst == filter->dst) {
1738 return false;
1739 }
1740 break;
1741 default:
1742 BT_DBG("Unknown filter addr type 0x%02x", filter->type);
1743 break;
1744 }
1745 }
1746
1747 return true;
1748 }
1749
bt_mesh_provisioner_heartbeat(uint16_t hb_src,uint16_t hb_dst,uint8_t init_ttl,uint8_t rx_ttl,uint8_t hops,uint16_t feat,int8_t rssi)1750 void bt_mesh_provisioner_heartbeat(uint16_t hb_src, uint16_t hb_dst,
1751 uint8_t init_ttl, uint8_t rx_ttl,
1752 uint8_t hops, uint16_t feat, int8_t rssi)
1753 {
1754 if (hb_rx.cb == NULL) {
1755 BT_DBG("Receiving heartbeat is not enabled");
1756 return;
1757 }
1758
1759 if (hb_rx.type == HEARTBEAT_FILTER_REJECTLIST) {
1760 if (filter_with_rejectlist(hb_src, hb_dst)) {
1761 BT_INFO("Filtered by rejectlist, src 0x%04x, dst 0x%04x", hb_src, hb_dst);
1762 return;
1763 }
1764 } else {
1765 if (filter_with_acceptlist(hb_src, hb_dst)) {
1766 BT_INFO("Filtered by acceptlist, src 0x%04x, dst 0x%04x", hb_src, hb_dst);
1767 return;
1768 }
1769 }
1770
1771 if (hb_rx.cb) {
1772 hb_rx.cb(hb_src, hb_dst, init_ttl, rx_ttl, hops, feat, rssi);
1773 }
1774 }
1775 #endif /* CONFIG_BLE_MESH_PROVISIONER_RECV_HB */
1776
1777 #endif /* CONFIG_BLE_MESH_PROVISIONER */
1778