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