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