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