1 // Copyright 2017-2018 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 <ble_os.h>
16 #include <bt_errno.h>
17 #include <atomic.h>
18 #include <misc/util.h>
19 #include <misc/byteorder.h>
20 #include <net/buf.h>
21 #include <api/mesh.h>
22 #include <bluetooth/conn.h>
23 #include <aos/ble.h>
24 
25 #ifdef CONFIG_BT_MESH_PROVISIONER
26 #ifndef CONFIG_BT_CENTRAL
27 #error "Provisioner need BT Central"
28 #endif
29 #include "mesh.h"
30 #include "api/mesh/main.h"
31 
32 #define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_MESH_DEBUG_PROV)
33 #include "common/log.h"
34 
35 #include "crypto.h"
36 #include "adv.h"
37 #include "net.h"
38 #include "access.h"
39 
40 #include "provisioner_prov.h"
41 #include "provisioner_proxy.h"
42 #include "provisioner_main.h"
43 #include <settings.h>
44 
45 #ifdef CONFIG_BT_MESH_EVENT_CALLBACK
46 #include "mesh_event_port.h"
47 #endif
48 
49 #define NODE_COMP_DATA_MIN_LEN 14
50 
51 #define BEACON_STATE BIT(0)
52 #define DEFAULT_TTL_STATE BIT(1)
53 #define GATT_PROXY_STATE BIT(2)
54 #define RELAY_STATE BIT(3)
55 #define NODE_IDENTITY_STATE BIT(4)
56 #define FRIEND_STATE BIT(5)
57 #define NET_TRANSMIT_STATE BIT(6)
58 #define HEARTBEAT_PUB_STATE BIT(7)
59 #define HEARTBEAT_SUB_STATE BIT(8)
60 
61 static const struct bt_mesh_prov *prov;
62 static const struct bt_mesh_provisioner *provisioner;
63 static const struct bt_mesh_comp *comp;
64 
65 static struct bt_mesh_node_t mesh_nodes[CONFIG_BT_MESH_MAX_STORED_NODES];
66 static bt_u32_t mesh_node_count;
67 
68 static bool prov_upper_init = false;
69 
70 extern struct net_buf_pool provisioner_buf_pool;
71 
get_u8(const u8_t ** src)72 static inline u8_t get_u8(const u8_t **src)
73 {
74     return (u8_t) * ((*src)++);
75 }
76 
get_le16(const u8_t ** src)77 static inline u16_t get_le16(const u8_t **src)
78 {
79     u16_t val = sys_get_le16(*src);
80     *src += 2;
81     return val;
82 }
83 
provisioner_index_check(int node_index)84 static int provisioner_index_check(int node_index)
85 {
86     struct bt_mesh_node_t *node = NULL;
87 
88     BT_DBG("%s", __func__);
89 
90     if (node_index < 0) {
91         BT_ERR("%s: node_index < 0", __func__);
92         return -EINVAL;
93     }
94 
95     if (node_index >= ARRAY_SIZE(mesh_nodes)) {
96         BT_ERR("%s: Too big node_index", __func__);
97         return -EINVAL;
98     }
99 
100     node = &mesh_nodes[node_index];
101 
102     if (node->node_active != true) {
103         BT_ERR("%s: node not found", __func__);
104         return -EINVAL;
105     }
106 
107     return 0;
108 }
109 
provisioner_is_node_provisioned(const u8_t * dev_addr)110 bool provisioner_is_node_provisioned(const u8_t *dev_addr)
111 {
112     int i;
113     struct bt_mesh_node_t *node = NULL;
114 
115     for (i = 0; i < ARRAY_SIZE(mesh_nodes); i++) {
116         node = &mesh_nodes[i];
117 
118         if (!node->node_active || !BT_MESH_ADDR_IS_UNICAST(node->unicast_addr)) {
119             continue;
120         }
121 
122         if (!memcmp(dev_addr, node->addr_val, 6)) {
123             return true;
124         }
125     }
126 
127     return false;
128 }
129 
provisioner_node_provision(int node_index,const u8_t uuid[16],u16_t oob_info,u16_t unicast_addr,u8_t element_num,u16_t net_idx,u8_t flags,bt_u32_t iv_index,const u8_t dev_key[16],u8_t * dev_addr)130 int provisioner_node_provision(int node_index, const u8_t uuid[16], u16_t oob_info, u16_t unicast_addr,
131                                u8_t element_num, u16_t net_idx, u8_t flags, bt_u32_t iv_index, const u8_t dev_key[16],
132                                u8_t *dev_addr)
133 {
134     struct bt_mesh_node_t *node = NULL;
135 
136     BT_DBG("%s", __func__);
137 
138     if (mesh_node_count >= ARRAY_SIZE(mesh_nodes)) {
139         BT_ERR("Provisioner mesh node queue is full");
140         return -ENOMEM;
141     }
142 
143     if (node_index >= ARRAY_SIZE(mesh_nodes) || !uuid || !dev_key) {
144         BT_ERR("Argument is invalid");
145         return -EINVAL;
146     }
147 
148 #if 0
149     node = osi_calloc(sizeof(struct bt_mesh_node_t));
150 
151     if (!node) {
152         BT_ERR("Provisioner allocate memory for node fail");
153         return -ENOMEM;
154     }
155 
156 #endif
157 
158     node = &mesh_nodes[node_index];
159 
160     BT_DBG("node_index: 0x%x, unicast_addr: 0x%x, element_num: 0x%x, net_idx: 0x%x", node_index, unicast_addr,
161            element_num, net_idx);
162     BT_DBG("dev_uuid: %s", bt_hex(uuid, 16));
163     BT_DBG("dev_key:  %s", bt_hex(dev_key, 16));
164 
165     memcpy(node->dev_uuid, uuid, 16);
166     node->oob_info = oob_info;
167     node->unicast_addr = unicast_addr;
168     node->element_num = element_num;
169     node->net_idx = net_idx;
170     node->flags = flags;
171     node->iv_index = iv_index;
172     memcpy(node->dev_key, dev_key, 16);
173     memcpy(node->addr_val, dev_addr, 6);
174     node->node_active = true;
175 
176     mesh_node_count++;
177 
178     return 0;
179 }
180 
provisioner_node_reset(int node_index)181 int provisioner_node_reset(int node_index)
182 {
183     struct bt_mesh_node_t *node = NULL;
184 
185     BT_DBG("%s: reset node %d", __func__, node_index);
186 
187     if (!mesh_node_count) {
188         BT_ERR("%s: mesh_nodes is empty", __func__);
189         return -ENODEV;
190     }
191 
192     if (provisioner_index_check(node_index)) {
193         BT_ERR("%s: check node_index fail", __func__);
194         return -EINVAL;
195     }
196 
197     node = &mesh_nodes[node_index];
198 
199     /* Reset corresponding rpl when reset the node */
200     extern void bt_mesh_rpl_clear_node(uint16_t unicast_addr, uint8_t elem_num);
201     bt_mesh_rpl_clear_node(node->unicast_addr, node->element_num);
202 
203 #if 0
204     osi_free(mesh_nodes[node_index]);
205     mesh_nodes[node_index] = NULL;
206 #endif
207 
208     node->node_active = false;
209 
210     mesh_node_count--;
211 
212 #ifdef CONFIG_BT_MESH_EVENT_CALLBACK
213     bt_mesh_model_evt_t evt_data;
214     evt_data.source_addr = mesh_nodes[node_index].unicast_addr;
215     mesh_model_evt_cb event_cb = bt_mesh_event_get_cb_func();
216     if (event_cb) {
217         event_cb(BT_MESH_MODEL_EVT_NODE_RESET_STATUS, &evt_data);
218     }
219 #endif
220 
221     if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
222         bt_mesh_clear_mesh_node(node_index);
223     }
224     return 0;
225 }
226 
provisioner_upper_reset_all_nodes(void)227 int provisioner_upper_reset_all_nodes(void)
228 {
229     int i, err;
230 
231     BT_DBG("%s", __func__);
232 
233     for (i = 0; i < ARRAY_SIZE(mesh_nodes); i++) {
234         err = provisioner_node_reset(i);
235 
236         if (err == -ENODEV) {
237             return 0;
238         }
239     }
240 
241     return 0;
242 }
243 
244 /** For Provisioner, we use the same data structure
245  *  (like, struct bt_mesh_subnet, etc.) for netkey
246  *  & appkey because if not we need to change a lot
247  *  of APIs.
248  */
provisioner_upper_init(void)249 int provisioner_upper_init(void)
250 {
251     struct bt_mesh_subnet *sub = NULL;
252     u8_t p_key[16] = { 0 };
253 
254     BT_DBG("%s", __func__);
255 
256     if (prov_upper_init) {
257         return 0;
258     }
259 
260     comp = bt_mesh_comp_get();
261 
262     if (!comp) {
263         BT_ERR("%s: Provisioner comp is NULL", __func__);
264         return -EINVAL;
265     }
266 
267     provisioner = provisioner_get_prov_info();
268 
269     if (!provisioner) {
270         BT_ERR("%s: Provisioner context is NULL", __func__);
271         return -EINVAL;
272     }
273 
274     /* If the device only acts as a Provisioner, need to initialize
275        each element's address. */
276     //bt_mesh_comp_provision(provisioner->prov_unicast_addr);
277 
278     /* Generate the primary netkey */
279     if (bt_rand(p_key, 16)) {
280         BT_ERR("%s: create primary netkey fail", __func__);
281         return -EIO;
282     }
283 
284 #if 0
285     sub = osi_calloc(sizeof(struct bt_mesh_subnet));
286 
287     if (!sub) {
288         BT_ERR("%s: allocate memory fail", __func__);
289         return -ENOMEM;
290     }
291 
292 #endif
293 
294     sub = &(bt_mesh.sub[0]);
295 
296     if (sub->subnet_active == false) {
297         sub->kr_flag = BT_MESH_KEY_REFRESH(provisioner->flags);
298 
299         if (sub->kr_flag) {
300             if (bt_mesh_net_keys_create(&sub->keys[1], p_key)) {
301                 BT_ERR("%s: create net_keys fail", __func__);
302                 //osi_free(sub);
303                 sub->subnet_active = false;
304                 return -EIO;
305             }
306 
307             sub->kr_phase = BT_MESH_KR_PHASE_2;
308         } else {
309             /* Currently provisioner only use keys[0] */
310             if (bt_mesh_net_keys_create(&sub->keys[0], p_key)) {
311                 BT_ERR("%s: create net_keys fail", __func__);
312                 //osi_free(sub);
313                 sub->subnet_active = false;
314                 return -EIO;
315             }
316 
317             sub->kr_phase = BT_MESH_KR_NORMAL;
318         }
319 
320         sub->net_idx = BT_MESH_KEY_PRIMARY;
321         sub->node_id = BT_MESH_NODE_IDENTITY_NOT_SUPPORTED;
322 
323         sub->subnet_active = true;
324 
325         if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
326             bt_mesh_store_subnet(sub, 0);
327         }
328     }
329 
330     /* Dynamically added appkey & netkey will use these key_idx */
331     bt_mesh.p_app_idx_next = 0x0000;
332     bt_mesh.p_net_idx_next = 0x0001;
333 
334     /* In this function, we use the values of struct bt_mesh_prov
335        which has been initialized in the application layer */
336     bt_mesh.iv_index = provisioner->iv_index;
337     bt_mesh.iv_update = BT_MESH_IV_UPDATE(provisioner->flags);
338 
339     /* Set initial IV Update procedure state time-stamp */
340     bt_mesh.last_update = k_uptime_get();
341 
342     prov_upper_init = true;
343 
344     BT_DBG("kr_flag: %d, kr_phase: %d, net_idx: 0x%02x, node_id %d", sub->kr_flag, sub->kr_phase, sub->net_idx,
345            sub->node_id);
346     BT_DBG("netkey:     %s, nid: 0x%x", bt_hex(sub->keys[0].net, 16), sub->keys[0].nid);
347     BT_DBG("enckey:     %s", bt_hex(sub->keys[0].enc, 16));
348     BT_DBG("network id: %s", bt_hex(sub->keys[0].net_id, 8));
349 #if defined(CONFIG_BT_MESH_GATT_PROXY)
350     BT_DBG("identity:   %s", bt_hex(sub->keys[0].identity, 16));
351 #endif
352     BT_DBG("privacy:    %s", bt_hex(sub->keys[0].privacy, 16));
353     BT_DBG("beacon:     %s", bt_hex(sub->keys[0].beacon, 16));
354 
355     return 0;
356 }
357 
358 /* The following APIs are for provisioner upper layers internal use */
359 
provisioner_net_key_get(u16_t net_idx)360 const u8_t *provisioner_net_key_get(u16_t net_idx)
361 {
362     struct bt_mesh_subnet *sub = NULL;
363     int i;
364 
365     BT_DBG("%s", __func__);
366 
367     for (i = 0; i < ARRAY_SIZE(bt_mesh.sub); i++) {
368         sub = &bt_mesh.sub[i];
369 
370         if (!sub->subnet_active || (sub->net_idx != net_idx)) {
371             BT_DBG("CONTINUE: %u, %u, %u", sub->subnet_active, sub->net_idx, net_idx);
372             continue;
373         }
374 
375         if (sub->kr_flag) {
376             BT_DBG("return kr_flag: %u", sub->kr_flag);
377             return sub->keys[1].net;
378         }
379 
380         BT_DBG("return netkey: %02x, %02x, %02x, %02x", sub->keys[0].net[0], sub->keys[0].net[1], sub->keys[0].net[2],
381                sub->keys[0].net[3]);
382         return sub->keys[0].net;
383     }
384 
385     BT_DBG("return netkey NULL");
386 
387     return NULL;
388 }
389 
provisioner_check_msg_dst_addr(u16_t dst_addr)390 bool provisioner_check_msg_dst_addr(u16_t dst_addr)
391 {
392     struct bt_mesh_node_t *node = NULL;
393     int i;
394 
395     BT_DBG("%s", __func__);
396 
397     if (!BT_MESH_ADDR_IS_UNICAST(dst_addr)) {
398         return true;
399     }
400 
401     for (i = 0; i < ARRAY_SIZE(mesh_nodes); i++) {
402         node = &mesh_nodes[i];
403 
404         if (node->node_active && dst_addr >= node->unicast_addr && dst_addr < node->unicast_addr + node->element_num) {
405             return true;
406         }
407     }
408 
409     return false;
410 }
411 
provisioner_get_device_key(u16_t dst_addr)412 const u8_t *provisioner_get_device_key(u16_t dst_addr)
413 {
414     /* Device key is only used to encrypt configuration messages.
415     *  Configuration model shall only be supported by the primary
416     *  element which uses the primary unicast address.
417     */
418     struct bt_mesh_node_t *node = NULL;
419     int i;
420 
421     BT_DBG("%s", __func__);
422 
423     if (!BT_MESH_ADDR_IS_UNICAST(dst_addr)) {
424         BT_ERR("%s: dst_addr is not unicast", __func__);
425         return NULL;
426     }
427 
428     for (i = 0; i < ARRAY_SIZE(mesh_nodes); i++) {
429         node = &mesh_nodes[i];
430 
431         if (node->node_active && node->unicast_addr == dst_addr) {
432             return node->dev_key;
433         }
434     }
435 
436     return NULL;
437 }
438 
provisioner_app_key_find(u16_t app_idx)439 struct bt_mesh_app_key *provisioner_app_key_find(u16_t app_idx)
440 {
441     struct bt_mesh_app_key *key = NULL;
442     int i;
443 
444     BT_DBG("%s", __func__);
445 
446     for (i = 0; i < ARRAY_SIZE(bt_mesh.app_keys); i++) {
447         key = &bt_mesh.app_keys[i];
448 
449         if (!key->appkey_active) {
450             continue;
451         }
452 
453         if (key->net_idx != BT_MESH_KEY_UNUSED && key->app_idx == app_idx) {
454             return key;
455         }
456     }
457 
458     return NULL;
459 }
460 
provisioner_get_prov_node_count(void)461 bt_u32_t provisioner_get_prov_node_count(void)
462 {
463     return mesh_node_count;
464 }
465 
466 /* The following APIs are for provisioner application use */
467 
468 #if 0
469 static int bt_mesh_provisioner_set_kr_flag(u16_t net_idx, bool kr_flag)
470 {
471     struct bt_mesh_subnet *sub = NULL;
472     int i;
473 
474     for (i = 0; i < ARRAY_SIZE(bt_mesh.p_sub); i++) {
475         sub = bt_mesh.p_sub[i];
476 
477         if (!sub || (sub->net_idx != net_idx)) {
478             continue;
479         }
480 
481         sub->kr_flag = kr_flag;
482         break;
483     }
484 
485     if (i == ARRAY_SIZE(bt_mesh.p_sub)) {
486         return -ENODEV;
487     }
488 
489     /* TODO: When kr_flag is changed, provisioner may need
490      *       to change the netkey of the subnet and update
491      *       corresponding appkey.
492      */
493 
494     return 0;
495 }
496 
497 static void bt_mesh_provisioner_set_iv_index(bt_u32_t iv_index)
498 {
499     bt_mesh.iv_index = iv_index;
500 
501     /* TODO: When iv_index is changed, provisioner may need to
502      *       start iv update procedure. And the ivu_initiator
503      *       & iv_update flags may also need to be set.
504      */
505 }
506 #endif
507 
bt_mesh_provisioner_store_node_info(struct bt_mesh_node_t * node_info)508 int bt_mesh_provisioner_store_node_info(struct bt_mesh_node_t *node_info)
509 {
510     struct bt_mesh_node_t *node = NULL;
511     int i;
512 
513     if (!node_info) {
514         BT_ERR("%s: node_info is NULL", __func__);
515         return -EINVAL;
516     }
517 
518     /* Check if the device uuid already exists */
519     for (i = 0; i < ARRAY_SIZE(mesh_nodes); i++) {
520         node = &mesh_nodes[i];
521 
522         if (node->node_active && !memcmp(node->dev_uuid, node_info->dev_uuid, 16)) {
523             BT_WARN("%s: node_info already exists", __func__);
524             return -EEXIST;
525         }
526     }
527 
528     /* 0 ~ (CONFIG_BT_MESH_MAX_PROV_NODES-1) are left for self-provisioned nodes */
529     for (i = CONFIG_BT_MESH_MAX_PROV_NODES; i < ARRAY_SIZE(mesh_nodes); i++) {
530         node = &mesh_nodes[i];
531 
532         if (!node->node_active) {
533 #if 0
534             node = osi_calloc(sizeof(struct bt_mesh_node_t));
535 
536             if (!node) {
537                 BT_ERR("%s: allocate memory fail", __func__);
538                 return -ENOMEM;
539             }
540 
541 #endif
542             memcpy(node, node_info, sizeof(struct bt_mesh_node_t));
543 #if 0
544             mesh_nodes[i] = node;
545 #endif
546             node->node_active = true;
547             mesh_node_count++;
548             return 0;
549         }
550     }
551 
552     BT_ERR("%s: node_info is full", __func__);
553     return -ENOMEM;
554 }
555 
bt_mesh_provisioner_get_all_node_unicast_addr(struct net_buf_simple * buf)556 int bt_mesh_provisioner_get_all_node_unicast_addr(struct net_buf_simple *buf)
557 {
558     struct bt_mesh_node_t *node = NULL;
559     int i;
560 
561     if (!buf) {
562         BT_ERR("%s: buf is NULL", __func__);
563         return -EINVAL;
564     }
565 
566     for (i = 0; i < ARRAY_SIZE(mesh_nodes); i++) {
567         node = &mesh_nodes[i];
568 
569         if (!node->node_active || !BT_MESH_ADDR_IS_UNICAST(node->unicast_addr)) {
570             continue;
571         }
572 
573         net_buf_simple_add_le16(buf, node->unicast_addr);
574     }
575 
576     return 0;
577 }
578 
bt_mesh_provisioner_set_node_name(int node_index,const char * name)579 int bt_mesh_provisioner_set_node_name(int node_index, const char *name)
580 {
581     size_t length, name_len;
582     int i;
583 
584     BT_DBG("%s", __func__);
585 
586     if (!name) {
587         BT_ERR("%s: input name is NULL", __func__);
588         return -EINVAL;
589     }
590 
591     if (provisioner_index_check(node_index)) {
592         BT_ERR("%s: check node_index fail", __func__);
593         return -EINVAL;
594     }
595 
596     BT_DBG("name len is %d, name is %s", strlen(name), name);
597 
598     length = (strlen(name) <= MESH_NAME_SIZE) ? strlen(name) : MESH_NAME_SIZE;
599 
600     for (i = 0; i < ARRAY_SIZE(mesh_nodes); i++) {
601         if (!mesh_nodes[i].node_active) {
602             continue;
603         }
604 
605         name_len = strlen(mesh_nodes[i].node_name);
606 
607         if (length != name_len) {
608             continue;
609         }
610 
611         if (!strncmp(mesh_nodes[i].node_name, name, length)) {
612             BT_WARN("%s: name already exists", __func__);
613             return -EEXIST;
614         }
615     }
616 
617     strncpy(mesh_nodes[node_index].node_name, name, length);
618 
619     return 0;
620 }
621 
bt_mesh_provisioner_get_node_name(int node_index)622 const char *bt_mesh_provisioner_get_node_name(int node_index)
623 {
624     BT_DBG("%s", __func__);
625 
626     if (provisioner_index_check(node_index)) {
627         BT_ERR("%s: check node_index fail", __func__);
628         return NULL;
629     }
630 
631     return mesh_nodes[node_index].node_name;
632 }
633 
bt_mesh_provisioner_get_node_index(const char * name)634 int bt_mesh_provisioner_get_node_index(const char *name)
635 {
636     size_t length, name_len;
637     int i;
638 
639     BT_DBG("%s", __func__);
640 
641     if (!name) {
642         return -EINVAL;
643     }
644 
645     length = (strlen(name) <= MESH_NAME_SIZE) ? strlen(name) : MESH_NAME_SIZE;
646 
647     for (i = 0; i < ARRAY_SIZE(mesh_nodes); i++) {
648         if (!mesh_nodes[i].node_active) {
649             continue;
650         }
651 
652         name_len = strlen(mesh_nodes[i].node_name);
653 
654         if (length != name_len) {
655             continue;
656         }
657 
658         if (!strncmp(mesh_nodes[i].node_name, name, length)) {
659             return i;
660         }
661     }
662 
663     return -ENODEV;
664 }
665 
bt_mesh_provisioner_get_node_info_by_id(int node_index)666 struct bt_mesh_node_t *bt_mesh_provisioner_get_node_info_by_id(int node_index)
667 {
668     if (provisioner_index_check(node_index)) {
669         BT_ERR("%s: check node_index fail", __func__);
670         return NULL;
671     }
672 
673     return &mesh_nodes[node_index];
674 }
675 
bt_mesh_provisioner_get_node_info(u16_t unicast_addr)676 struct bt_mesh_node_t *bt_mesh_provisioner_get_node_info(u16_t unicast_addr)
677 {
678     struct bt_mesh_node_t *node = NULL;
679     int i;
680 
681     BT_DBG("%s", __func__);
682 
683     if (!BT_MESH_ADDR_IS_UNICAST(unicast_addr)) {
684         BT_ERR("%s: not a unicast address", __func__);
685         return NULL;
686     }
687 
688     for (i = 0; i < ARRAY_SIZE(mesh_nodes); i++) {
689         node = &mesh_nodes[i];
690 
691         if (!node->node_active) {
692             continue;
693         }
694 
695         if (unicast_addr >= node->unicast_addr && unicast_addr < (node->unicast_addr + node->element_num)) {
696             return node;
697         }
698     }
699 
700     return NULL;
701 }
702 
bt_mesh_provisioner_get_net_key_count(void)703 bt_u32_t bt_mesh_provisioner_get_net_key_count(void)
704 {
705     return ARRAY_SIZE(bt_mesh.sub);
706 }
707 
bt_mesh_provisioner_get_app_key_count(void)708 bt_u32_t bt_mesh_provisioner_get_app_key_count(void)
709 {
710     return ARRAY_SIZE(bt_mesh.app_keys);
711 }
712 
provisioner_check_app_key(const u8_t app_key[16],u16_t * app_idx)713 static int provisioner_check_app_key(const u8_t app_key[16], u16_t *app_idx)
714 {
715     struct bt_mesh_app_key *key = NULL;
716     int i;
717 
718     if (!app_key) {
719         return 0;
720     }
721 
722     /* Check if app_key is already existed */
723     for (i = 0; i < ARRAY_SIZE(bt_mesh.app_keys); i++) {
724         key = &bt_mesh.app_keys[i];
725 
726         if (key->appkey_active && (!memcmp(key->keys[0].val, app_key, 16) || !memcmp(key->keys[1].val, app_key, 16))) {
727             *app_idx = key->app_idx;
728             return -EEXIST;
729         }
730     }
731 
732     return 0;
733 }
734 
provisioner_check_app_idx(u16_t app_idx,bool exist)735 static int provisioner_check_app_idx(u16_t app_idx, bool exist)
736 {
737     struct bt_mesh_app_key *key = NULL;
738     int i;
739 
740     if (exist) {
741         /* Check if app_idx is already existed */
742         for (i = 0; i < ARRAY_SIZE(bt_mesh.app_keys); i++) {
743             key = &bt_mesh.app_keys[i];
744 
745             if (key->appkey_active && (key->app_idx == app_idx)) {
746                 return -EEXIST;
747             }
748         }
749 
750         return 0;
751     }
752 
753     /* Check if app_idx is not existed */
754     for (i = 0; i < ARRAY_SIZE(bt_mesh.app_keys); i++) {
755         key = &bt_mesh.app_keys[i];
756 
757         if (key->appkey_active && (key->app_idx == app_idx)) {
758             return 0;
759         }
760     }
761 
762     return -ENODEV;
763 }
764 
provisioner_check_app_key_full(void)765 static int provisioner_check_app_key_full(void)
766 {
767     int i;
768 
769     for (i = 0; i < ARRAY_SIZE(bt_mesh.app_keys); i++) {
770         if (!bt_mesh.app_keys[i].appkey_active) {
771             return i;
772         }
773     }
774 
775     return -ENOMEM;
776 }
777 
provisioner_check_net_key(const u8_t net_key[16],u16_t * net_idx)778 static int provisioner_check_net_key(const u8_t net_key[16], u16_t *net_idx)
779 {
780     struct bt_mesh_subnet *sub = NULL;
781     int i;
782 
783     if (!net_key) {
784         return 0;
785     }
786 
787     /* Check if net_key is already existed */
788     for (i = 0; i < ARRAY_SIZE(bt_mesh.sub); i++) {
789         sub = &bt_mesh.sub[i];
790 
791         if (sub->subnet_active && (!memcmp(sub->keys[0].net, net_key, 16) || !memcmp(sub->keys[1].net, net_key, 16))) {
792             *net_idx = sub->net_idx;
793             return -EEXIST;
794         }
795     }
796 
797     return 0;
798 }
799 
provisioner_check_net_idx(u16_t net_idx,bool exist)800 static int provisioner_check_net_idx(u16_t net_idx, bool exist)
801 {
802     struct bt_mesh_subnet *sub = NULL;
803     int i;
804 
805     if (exist) {
806         /* Check if net_idx is already existed */
807         for (i = 0; i < ARRAY_SIZE(bt_mesh.sub); i++) {
808             sub = &bt_mesh.sub[i];
809 
810             if (sub->subnet_active && (sub->net_idx == net_idx)) {
811                 return -EEXIST;
812             }
813         }
814 
815         return 0;
816     }
817 
818     /* Check if net_idx is not existed */
819     for (i = 0; i < ARRAY_SIZE(bt_mesh.sub); i++) {
820         sub = &bt_mesh.sub[i];
821 
822         if (sub->subnet_active && (sub->net_idx == net_idx)) {
823             return 0;
824         }
825     }
826 
827     return -ENODEV;
828 }
829 
provisioner_check_net_key_full(void)830 static int provisioner_check_net_key_full(void)
831 {
832     int i;
833 
834     for (i = 0; i < ARRAY_SIZE(bt_mesh.sub); i++) {
835         if (!bt_mesh.sub[i].subnet_active) {
836             return i;
837         }
838     }
839 
840     return -ENOMEM;
841 }
842 
bt_mesh_provisioner_p_app_key_alloc()843 struct bt_mesh_app_key *bt_mesh_provisioner_p_app_key_alloc()
844 {
845     struct bt_mesh_app_key *key = NULL;
846     int add = -1;
847 
848     add = provisioner_check_app_key_full();
849 
850     if (add < 0) {
851         BT_ERR("%s: app_key full", __func__);
852         return NULL;
853     }
854 
855     key = &(bt_mesh.app_keys[add]);
856     return key;
857 }
858 
bt_mesh_provisioner_local_app_key_add(const u8_t app_key[16],u16_t net_idx,u16_t * app_idx)859 int bt_mesh_provisioner_local_app_key_add(const u8_t app_key[16], u16_t net_idx, u16_t *app_idx)
860 {
861     struct bt_mesh_app_key *key = NULL;
862     struct bt_mesh_app_keys *keys = NULL;
863     u8_t p_key[16] = { 0 };
864     int add = -1;
865 
866     if (bt_mesh.p_app_idx_next >= 0x1000) {
867         BT_ERR("%s: no app_idx available", __func__);
868         return -EIO;
869     }
870 
871     if (!app_idx || (*app_idx != 0xFFFF && *app_idx >= 0x1000)) {
872         BT_ERR("%s: invalid parameters", __func__);
873         return -EINVAL;
874     }
875 
876     /* Check if the same application key already exists */
877     if (provisioner_check_app_key(app_key, app_idx)) {
878         BT_WARN("%s: app_key already exists, app_idx updated", __func__);
879         return 0;
880     }
881 
882     /* Check if the net_idx exists */
883     if (provisioner_check_net_idx(net_idx, false)) {
884         BT_ERR("%s: net_idx does not exist", __func__);
885         return -ENODEV;
886     }
887 
888     /* Check if the same app_idx already exists */
889     if (provisioner_check_app_idx(*app_idx, true)) {
890         BT_ERR("%s: app_idx already exists", __func__);
891         return -EEXIST;
892     }
893 
894     add = provisioner_check_app_key_full();
895 
896     if (add < 0) {
897         BT_ERR("%s: app_key full", __func__);
898         return -ENOMEM;
899     }
900 
901     if (!app_key) {
902         if (bt_rand(p_key, 16)) {
903             BT_ERR("%s: generate app_key fail", __func__);
904             return -EIO;
905         }
906     } else {
907         memcpy(p_key, app_key, 16);
908     }
909 
910     key = &(bt_mesh.app_keys[add]);
911 
912     keys = &key->keys[0];
913 
914     if (bt_mesh_app_id(p_key, &keys->id)) {
915         BT_ERR("%s: generate aid fail", __func__);
916         key->appkey_active = false;
917         return -EIO;
918     }
919 
920     memcpy(keys->val, p_key, 16);
921     key->net_idx = net_idx;
922 
923     if (*app_idx != 0xFFFF) {
924         key->app_idx = *app_idx;
925     } else {
926         key->app_idx = bt_mesh.p_app_idx_next;
927 
928         while (1) {
929             if (provisioner_check_app_idx(key->app_idx, true)) {
930                 key->app_idx = (++bt_mesh.p_app_idx_next);
931 
932                 if (key->app_idx >= 0x1000) {
933                     BT_ERR("%s: no app_idx available for key", __func__);
934                     //osi_free(key);
935                     key->appkey_active = false;
936                     return -EIO;
937                 }
938             } else {
939                 break;
940             }
941         }
942 
943         *app_idx = key->app_idx;
944     }
945 
946     key->updated = false;
947     key->appkey_active = true;
948 
949     if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
950         BT_DBG("Storing AppKey persistently");
951         bt_mesh_store_app_key(key, 0);
952     }
953 
954     return 0;
955 }
956 
bt_mesh_provisioner_local_app_key_get(u16_t net_idx,u16_t app_idx)957 const u8_t *bt_mesh_provisioner_local_app_key_get(u16_t net_idx, u16_t app_idx)
958 {
959     struct bt_mesh_app_key *key = NULL;
960     int i;
961 
962     BT_DBG("%s", __func__);
963 
964     if (provisioner_check_net_idx(net_idx, false)) {
965         BT_ERR("%s: net_idx does not exist", __func__);
966         return NULL;
967     }
968 
969     if (provisioner_check_app_idx(app_idx, false)) {
970         BT_ERR("%s: app_idx does not exist", __func__);
971         return NULL;
972     }
973 
974     for (i = 0; i < ARRAY_SIZE(bt_mesh.app_keys); i++) {
975         key = &bt_mesh.app_keys[i];
976 
977         if (key->appkey_active && key->net_idx == net_idx && key->app_idx == app_idx) {
978             if (key->updated) {
979                 return key->keys[1].val;
980             }
981 
982             return key->keys[0].val;
983         }
984     }
985 
986     return NULL;
987 }
988 
bt_mesh_provisioner_local_app_key_delete(u16_t net_idx,u16_t app_idx)989 int bt_mesh_provisioner_local_app_key_delete(u16_t net_idx, u16_t app_idx)
990 {
991     struct bt_mesh_app_key *key = NULL;
992     int i;
993 
994     BT_DBG("%s", __func__);
995 
996     if (provisioner_check_net_idx(net_idx, false)) {
997         BT_ERR("%s: net_idx does not exist", __func__);
998         return -ENODEV;
999     }
1000 
1001     if (provisioner_check_app_idx(app_idx, false)) {
1002         BT_ERR("%s: app_idx does not exist", __func__);
1003         return -ENODEV;
1004     }
1005 
1006     for (i = 0; i < ARRAY_SIZE(bt_mesh.app_keys); i++) {
1007         key = &bt_mesh.app_keys[i];
1008 
1009         if (key->appkey_active && key->net_idx == net_idx && key->app_idx == app_idx) {
1010             if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
1011                 bt_mesh_clear_app_key(key, 0);
1012             }
1013 
1014             key->appkey_active = false;
1015             return 0;
1016         }
1017     }
1018 
1019     /* Shall never reach here */
1020     return -ENODEV;
1021 }
1022 
bt_mesh_provisioner_local_net_key_add(const u8_t net_key[16],u16_t * net_idx)1023 int bt_mesh_provisioner_local_net_key_add(const u8_t net_key[16], u16_t *net_idx)
1024 {
1025     struct bt_mesh_subnet *sub = NULL;
1026     u8_t p_key[16] = { 0 };
1027     int add = -1;
1028 
1029     if (bt_mesh.p_net_idx_next >= 0x1000) {
1030         BT_ERR("%s: no net_idx available", __func__);
1031         return -EIO;
1032     }
1033 
1034     if (!net_idx || (*net_idx != 0xFFFF && *net_idx >= 0x1000)) {
1035         BT_ERR("%s: invalid parameters", __func__);
1036         return -EINVAL;
1037     }
1038 
1039     /* Check if the same network key already exists */
1040     if (provisioner_check_net_key(net_key, net_idx)) {
1041         BT_WARN("%s: net_key already exists, net_idx updated", __func__);
1042         return -EEXIST;
1043     }
1044 
1045     /* Check if the same net_idx already exists */
1046     if (provisioner_check_net_idx(*net_idx, true)) {
1047         BT_ERR("%s: net_idx already exists", __func__);
1048         return -EEXIST;
1049     }
1050 
1051     add = provisioner_check_net_key_full();
1052 
1053     if (add < 0) {
1054         BT_ERR("%s: net_key full", __func__);
1055         return -ENOMEM;
1056     }
1057 
1058     if (!net_key) {
1059         if (bt_rand(p_key, 16)) {
1060             BT_ERR("%s: generate net_key fail", __func__);
1061             return -EIO;
1062         }
1063     } else {
1064         memcpy(p_key, net_key, 16);
1065     }
1066 
1067 #if 0
1068     sub = osi_calloc(sizeof(struct bt_mesh_subnet));
1069 
1070     if (!sub) {
1071         BT_ERR("%s: allocate memory for net_key fail", __func__);
1072         return -ENOMEM;
1073     }
1074 
1075 #endif
1076 
1077     sub = &bt_mesh.sub[add];
1078 
1079     if (bt_mesh_net_keys_create(&sub->keys[0], p_key)) {
1080         BT_ERR("%s: generate nid fail", __func__);
1081         //osi_free(sub);
1082         sub->subnet_active = false;
1083         return -EIO;
1084     }
1085 
1086     if (*net_idx != 0xFFFF) {
1087         sub->net_idx = *net_idx;
1088     } else {
1089         sub->net_idx = bt_mesh.p_net_idx_next;
1090 
1091         while (1) {
1092             if (provisioner_check_net_idx(sub->net_idx, true)) {
1093                 sub->net_idx = (++bt_mesh.p_net_idx_next);
1094 
1095                 if (sub->net_idx >= 0x1000) {
1096                     BT_ERR("%s: no net_idx available for sub", __func__);
1097                     //osi_free(sub);
1098                     sub->subnet_active = false;
1099                     return -EIO;
1100                 }
1101             } else {
1102                 break;
1103             }
1104         }
1105 
1106         *net_idx = sub->net_idx;
1107     }
1108 
1109     sub->kr_phase = BT_MESH_KR_NORMAL;
1110     sub->kr_flag = false;
1111     sub->node_id = BT_MESH_NODE_IDENTITY_NOT_SUPPORTED;
1112 
1113     sub->subnet_active = true;
1114 
1115     if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
1116         bt_mesh_store_subnet(sub, 0);
1117     }
1118 
1119     return 0;
1120 }
1121 
bt_mesh_provisioner_local_net_key_get(u16_t net_idx)1122 const u8_t *bt_mesh_provisioner_local_net_key_get(u16_t net_idx)
1123 {
1124     struct bt_mesh_subnet *sub = NULL;
1125     int i;
1126 
1127     BT_DBG("%s", __func__);
1128 
1129     if (provisioner_check_net_idx(net_idx, false)) {
1130         BT_ERR("%s: net_idx does not exist", __func__);
1131         return NULL;
1132     }
1133 
1134     for (i = 0; i < ARRAY_SIZE(bt_mesh.sub); i++) {
1135         sub = &bt_mesh.sub[i];
1136 
1137         if (sub->subnet_active && sub->net_idx == net_idx) {
1138             if (sub->kr_flag) {
1139                 return sub->keys[1].net;
1140             }
1141 
1142             return sub->keys[0].net;
1143         }
1144     }
1145 
1146     return NULL;
1147 }
1148 
bt_mesh_provisioner_local_net_key_delete(u16_t net_idx)1149 int bt_mesh_provisioner_local_net_key_delete(u16_t net_idx)
1150 {
1151     struct bt_mesh_subnet *sub = NULL;
1152     int i;
1153 
1154     BT_DBG("%s", __func__);
1155 
1156     if (provisioner_check_net_idx(net_idx, false)) {
1157         BT_ERR("%s: net_idx does not exist", __func__);
1158         return -ENODEV;
1159     }
1160 
1161     for (i = 0; i < ARRAY_SIZE(bt_mesh.sub); i++) {
1162         sub = &bt_mesh.sub[i];
1163 
1164         if (sub->subnet_active && sub->net_idx == net_idx) {
1165             sub->subnet_active = false;
1166 
1167             if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
1168                 bt_mesh_clear_subnet(sub, 0);
1169             }
1170 
1171             return 0;
1172         }
1173     }
1174 
1175     /* Shall never reach here */
1176     return -ENODEV;
1177 }
1178 
bt_mesh_provisioner_get_own_unicast_addr(u16_t * addr,u8_t * elem_num)1179 int bt_mesh_provisioner_get_own_unicast_addr(u16_t *addr, u8_t *elem_num)
1180 {
1181     if (!addr || !elem_num || !prov || !comp) {
1182         BT_ERR("%s: parameter is NULL", __func__);
1183         return -EINVAL;
1184     }
1185 
1186     *addr = provisioner->prov_unicast_addr;
1187     *elem_num = comp->elem_count;
1188 
1189     return 0;
1190 }
1191 
bt_mesh_provisioner_unbind_local_model_app_idx(u16_t elem_addr,u16_t mod_id,u16_t cid,u16_t app_idx)1192 int bt_mesh_provisioner_unbind_local_model_app_idx(u16_t elem_addr, u16_t mod_id, u16_t cid, u16_t app_idx)
1193 {
1194     struct bt_mesh_elem *elem = NULL;
1195     struct bt_mesh_model *model = NULL;
1196     int i;
1197 
1198     if (!comp) {
1199         BT_ERR("%s: comp is NULL", __func__);
1200         return -EINVAL;
1201     }
1202 
1203     for (i = 0; i < comp->elem_count; i++) {
1204         elem = &comp->elem[i];
1205 
1206         if (elem->addr == elem_addr) {
1207             break;
1208         }
1209     }
1210 
1211     if (i == comp->elem_count) {
1212         BT_ERR("%s: no element found", __func__);
1213         return -ENODEV;
1214     }
1215 
1216     if (cid == 0xFFFF) {
1217         model = bt_mesh_model_find(elem, mod_id);
1218     } else {
1219         model = bt_mesh_model_find_vnd(elem, cid, mod_id);
1220     }
1221 
1222     if (!model) {
1223         BT_ERR("%s: no model found", __func__);
1224         return -ENODEV;
1225     }
1226 
1227     if (provisioner_check_app_idx(app_idx, false)) {
1228         BT_ERR("%s: app_idx does not exist", __func__);
1229         return -ENODEV;
1230     }
1231 
1232     for (i = 0; i < ARRAY_SIZE(model->keys); i++) {
1233         if (model->keys[i] == app_idx) {
1234             model->keys[i] = BT_MESH_KEY_UNUSED;
1235             return 0;
1236         }
1237     }
1238 
1239     BT_DBG("%s:the appkey has not been bound to model", __func__);
1240     return 0;
1241 }
1242 
bt_mesh_provisioner_bind_local_model_app_idx(u16_t elem_addr,u16_t mod_id,u16_t cid,u16_t app_idx)1243 int bt_mesh_provisioner_bind_local_model_app_idx(u16_t elem_addr, u16_t mod_id, u16_t cid, u16_t app_idx)
1244 {
1245     struct bt_mesh_elem *elem = NULL;
1246     struct bt_mesh_model *model = NULL;
1247     int i;
1248 
1249     if (!comp) {
1250         BT_ERR("%s: comp is NULL", __func__);
1251         return -EINVAL;
1252     }
1253 
1254     for (i = 0; i < comp->elem_count; i++) {
1255         elem = &comp->elem[i];
1256 
1257         if (elem->addr == elem_addr) {
1258             break;
1259         }
1260     }
1261 
1262     if (i == comp->elem_count) {
1263         BT_ERR("%s: no element found", __func__);
1264         return -ENODEV;
1265     }
1266 
1267     if (cid == 0xFFFF) {
1268         model = bt_mesh_model_find(elem, mod_id);
1269     } else {
1270         model = bt_mesh_model_find_vnd(elem, cid, mod_id);
1271     }
1272 
1273     if (!model) {
1274         BT_ERR("%s: no model found", __func__);
1275         return -ENODEV;
1276     }
1277 
1278     if (provisioner_check_app_idx(app_idx, false)) {
1279         BT_ERR("%s: app_idx does not exist", __func__);
1280         return -ENODEV;
1281     }
1282 
1283     for (i = 0; i < ARRAY_SIZE(model->keys); i++) {
1284         if (model->keys[i] == app_idx) {
1285             BT_WARN("%s: app_idx already bind with model", __func__);
1286             return 0;
1287         }
1288     }
1289 
1290     for (i = 0; i < ARRAY_SIZE(model->keys); i++) {
1291         if (model->keys[i] == BT_MESH_KEY_UNUSED) {
1292             model->keys[i] = app_idx;
1293             return 0;
1294         }
1295     }
1296 
1297     BT_ERR("%s: model->keys is full", __func__);
1298     return -ENOMEM;
1299 }
1300 
bt_mesh_provisioner_bind_local_app_net_idx(u16_t net_idx,u16_t app_idx)1301 int bt_mesh_provisioner_bind_local_app_net_idx(u16_t net_idx, u16_t app_idx)
1302 {
1303     struct bt_mesh_app_key *key = NULL;
1304     int i;
1305 
1306     BT_DBG("%s", __func__);
1307 
1308     if (provisioner_check_net_idx(net_idx, false)) {
1309         BT_ERR("%s: net_idx does not exist", __func__);
1310         return -ENODEV;
1311     }
1312 
1313     if (provisioner_check_app_idx(app_idx, false)) {
1314         BT_ERR("%s: app_idx does not exist", __func__);
1315         return -ENODEV;
1316     }
1317 
1318     for (i = 0; i < ARRAY_SIZE(bt_mesh.app_keys); i++) {
1319         key = &bt_mesh.app_keys[i];
1320 
1321         if (!key->appkey_active || (key->app_idx != app_idx)) {
1322             continue;
1323         }
1324 
1325         key->net_idx = net_idx;
1326         return 0;
1327     }
1328 
1329     return -ENODEV;
1330 }
1331 
bt_mesh_provisioner_print_local_element_info(void)1332 int bt_mesh_provisioner_print_local_element_info(void)
1333 {
1334     struct bt_mesh_elem *elem = NULL;
1335     struct bt_mesh_model *model = NULL;
1336     int i, j;
1337 
1338     if (!comp) {
1339         BT_ERR("%s: comp is NULL", __func__);
1340         return -EINVAL;
1341     }
1342 
1343     BT_WARN("************************************************");
1344     BT_WARN("* cid: 0x%04x    pid: 0x%04x    vid: 0x%04x    *", comp->cid, comp->pid, comp->vid);
1345     BT_WARN("* Element Number: 0x%02x                         *", comp->elem_count);
1346 
1347     for (i = 0; i < comp->elem_count; i++) {
1348         elem = &comp->elem[i];
1349         BT_WARN("* Element %d: 0x%04x                            *", i, elem->addr);
1350         BT_WARN("*     Loc: 0x%04x   NumS: 0x%02x   NumV: 0x%02x    *", elem->loc, elem->model_count,
1351                 elem->vnd_model_count);
1352 
1353         for (j = 0; j < elem->model_count; j++) {
1354             model = &elem->models[j];
1355             BT_WARN("*     sig_model %d: id - 0x%04x                 *", j, model->id);
1356         }
1357 
1358         for (j = 0; j < elem->vnd_model_count; j++) {
1359             model = &elem->vnd_models[j];
1360             BT_WARN("*     vnd_model %d: id - 0x%04x, cid - 0x%04x   *", j, model->vnd.id, model->vnd.company);
1361         }
1362     }
1363 
1364     BT_WARN("************************************************");
1365     (void)model;
1366     return 0;
1367 }
1368 
bt_mesh_provisioner_print_node_info(void)1369 int bt_mesh_provisioner_print_node_info(void)
1370 {
1371     int i;
1372     BT_WARN("************************************************");
1373     BT_WARN("* Provisioned Node info                        *");
1374 
1375     for (i = 0; i < ARRAY_SIZE(mesh_nodes); i++) {
1376         struct bt_mesh_node_t *node = &mesh_nodes[i];
1377 
1378         if (!node->node_active || !BT_MESH_ADDR_IS_UNICAST(node->unicast_addr)) {
1379             continue;
1380         }
1381 
1382         BT_WARN("* Node [%d]: %s", i, node->node_name);
1383         BT_WARN("*   UUID : %s", bt_hex(node->dev_uuid, 16));
1384         BT_WARN("*   Addr: %02X:%02X:%02X:%02X:%02X:%02X (%s)", node->addr_val[5], node->addr_val[4], node->addr_val[3],
1385                 node->addr_val[2], node->addr_val[1], node->addr_val[0], node->addr_type == 0 ? "Public" : "random");
1386         BT_WARN("*   Unicast Addr: %04x  ELEM Nums: %02x  Net ID %04x", node->unicast_addr, node->element_num,
1387                 node->net_idx);
1388         BT_WARN("*   Device key: %s", bt_hex(node->dev_key, 16));
1389     }
1390 
1391     BT_WARN("************************************************");
1392     return 0;
1393 }
1394 
1395 /* The following APIs are for temporary provisioner use */
1396 
bt_mesh_temp_prov_net_idx_set(const u8_t net_key[16],u16_t * net_idx,u8_t * status)1397 int bt_mesh_temp_prov_net_idx_set(const u8_t net_key[16], u16_t *net_idx, u8_t *status)
1398 {
1399     struct bt_mesh_subnet *sub = NULL;
1400     struct bt_mesh_subnet_keys *key = NULL;
1401     const u8_t *keys = NULL;
1402     u8_t kr_flag = 0;
1403     int i, err = 0;
1404 
1405     if (!net_key || !net_idx || !status) {
1406         BT_ERR("%s: invalid parameters", __func__);
1407         return -EINVAL;
1408     }
1409 
1410     /* Check if net_key already exists in the node subnet */
1411     for (i = 0; i < ARRAY_SIZE(bt_mesh.sub); i++) {
1412         sub = &bt_mesh.sub[i];
1413 
1414         if (sub->net_idx == *net_idx) {
1415             kr_flag = BT_MESH_KEY_REFRESH(sub->kr_flag);
1416             key = kr_flag ? &sub->keys[1] : &sub->keys[0];
1417             *status = provisioner_temp_prov_set_net_idx(key->net, sub->net_idx);
1418             return 0;
1419         }
1420     }
1421 
1422     /* Check if different netkeys with the same net_idx */
1423     while (1) {
1424         for (i = 0; i < ARRAY_SIZE(bt_mesh.sub); i++) {
1425             sub = &bt_mesh.sub[i];
1426 
1427             if (sub->subnet_active && sub->net_idx == *net_idx) {
1428                 *net_idx += 1;
1429                 *net_idx &= 0xFFF; /* net_idx is 12-bit */
1430                 break;
1431             }
1432         }
1433 
1434         if (i == ARRAY_SIZE(bt_mesh.sub)) {
1435             break;
1436         }
1437     }
1438 
1439     bt_mesh.p_net_idx_next = *net_idx;
1440 
1441     /* If not exist in node subnet, will be checked with provisioner p_sub
1442        and added to p_sub if necessary */
1443     err = bt_mesh_provisioner_local_net_key_add(net_key, net_idx);
1444 
1445     if (err) {
1446         *status = 0x01; /* status: fail */
1447         return 0;
1448     };
1449 
1450     keys = bt_mesh_provisioner_local_net_key_get(*net_idx);
1451 
1452     if (!keys) {
1453         *status = 0x01; /* status: fail */
1454         return 0;
1455     }
1456 
1457     *status = provisioner_temp_prov_set_net_idx(keys, *net_idx);
1458 
1459     return 0;
1460 }
1461 
bt_mesh_temp_prov_app_idx_set(const u8_t app_key[16],u16_t net_idx,u16_t * app_idx,u8_t * status)1462 int bt_mesh_temp_prov_app_idx_set(const u8_t app_key[16], u16_t net_idx, u16_t *app_idx, u8_t *status)
1463 {
1464     struct bt_mesh_app_key *key = NULL;
1465     int i, err = 0;
1466 
1467     if (!app_key || !app_idx || !status) {
1468         BT_ERR("%s: invalid parameters", __func__);
1469         return -EINVAL;
1470     }
1471 
1472     /* Check if net_key already exists in the node subnet */
1473     for (i = 0; i < ARRAY_SIZE(bt_mesh.app_keys); i++) {
1474         key = &bt_mesh.app_keys[i];
1475 
1476         if (key->app_idx == *app_idx) {
1477             *status = 0x0;
1478             return 0;
1479         }
1480     }
1481 
1482     /* Check if different netkeys with the same net_idx */
1483     while (1) {
1484         for (i = 0; i < ARRAY_SIZE(bt_mesh.app_keys); i++) {
1485             key = &bt_mesh.app_keys[i];
1486 
1487             if (key->appkey_active && key->app_idx == *app_idx) {
1488                 *app_idx += 1;
1489                 *app_idx &= 0xFFF; /* app_idx is 12-bit */
1490                 break;
1491             }
1492         }
1493 
1494         if (i == ARRAY_SIZE(bt_mesh.app_keys)) {
1495             break;
1496         }
1497     }
1498 
1499     bt_mesh.p_app_idx_next = *app_idx;
1500 
1501     /* If not exist in node subnet, will be checked with provisioner p_app_keys
1502        and added to p_app_keys if necessary */
1503     err = bt_mesh_provisioner_local_app_key_add(app_key, net_idx, app_idx);
1504 
1505     if (err) {
1506         *status = 0x01; /* status: fail */
1507     };
1508 
1509     *status = 0x0;
1510 
1511     return 0;
1512 }
1513 
1514 #endif /* CONFIG_BT_MESH_PROVISIONER */
1515