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