1 /*
2  * Copyright (C) 2019-2020 Alibaba Group Holding Limited
3  */
4 
5 #include <stdio.h>
6 #include <stdlib.h>
7 
8 #include <api/mesh.h>
9 #include <aos/debug.h>
10 #include <aos/kernel.h>
11 #include <aos/kv.h>
12 #include <aos/ble.h>
13 #include <bt_errno.h>
14 #include <mesh.h>
15 #include "mesh_node.h"
16 #include "mesh_model/mesh_model.h"
17 
18 #ifdef CONFIG_BT_MESH_PROVISIONER
19 #include "provisioner_prov.h"
20 #include "provisioner_main.h"
21 #include "provisioner_proxy.h"
22 #endif
23 
24 #define COMMON_SUB_ADDR 0xF000
25 #define COMMON_PUB_ADDR 0xF001
26 #define TIMEOUT 402
27 
28 static uint8_t dev_uuid[16];
29 static uint8_t g_static_data[16] = { 0 };
30 
31 #define TAG "BT_MESH_NODE"
32 
33 #ifdef BT_MESH_BEACON_RSSI_REPORT
34 typedef struct {
35     uint8_t mac[6];
36     uint8_t rssi;
37     uint8_t rssi_calibration;
38 } beacon_rssi_data;
39 
40 typedef struct {
41     uint8_t front;
42     uint8_t rear;
43     uint8_t length;
44     beacon_rssi_data data[16];
45 } rssi_data_queue;
46 #endif
47 typedef void (*node_event_cb)(uint16_t event, void *p_arg);
48 
49 typedef struct _mesh_node {
50     const struct bt_mesh_comp *comp;
51     model_event_cb user_model_cb;
52     uint8_t init_flag;
53 #ifdef CONFIG_BT_MESH_PROVISIONER
54     provisioner_cb user_provisioner_cb;
55     k_timer_t add_appkey_timer;
56     uint32_t add_appkey_timeout;
57     uint8_t app_key_add_retry;
58     uint16_t auto_add_appkey_idx;
59 #else
60     prov_event_cb user_prov_cb;
61     k_timer_t auto_config_timer;
62     uint32_t auto_config_timeout;
63     uint8_t app_key_add_flag:1;
64     uint8_t auto_config_retry;
65     uint8_t auto_config_ack_flag;
66     uint8_t auto_config_status;
67     uint16_t prov_addr;
68     bt_mesh_input_action_t input_act;
69     uint8_t input_size;
70 #endif
71 
72 #ifdef BT_MESH_BEACON_RSSI_REPORT
73     uint8_t rssi_report_enable:1;
74     k_timer_t beacon_rssi_timer;
75     rssi_data_queue rssi_queue;
76 #endif
77     uint8_t node_provisioned;
78     health_srv_cb health_cb;
79 } mesh_node;
80 
81 mesh_node g_mesh_node;
82 
83 #ifdef BT_MESH_BEACON_RSSI_REPORT
84 static int init_rssi_report();
85 #endif
86 
87 extern void bt_mesh_store_mod_bind(struct bt_mesh_model *mod);
88 extern void bt_mesh_store_mod_sub(struct bt_mesh_model *mod);
89 extern void bt_mesh_store_mod_pub(struct bt_mesh_model *mod);
90 extern u16_t *bt_mesh_model_find_group(struct bt_mesh_model *mod, u16_t addr);
91 extern int bt_mesh_store_mod_pending_check();
92 
93 #ifndef CONFIG_BT_MESH_PROVISIONER
94 
report_auto_config_status(uint16_t dst_addr,uint8_t status)95 static int report_auto_config_status(uint16_t dst_addr, uint8_t status)
96 {
97 #ifdef CONFIG_BT_MESH_MODEL_VENDOR_SRV
98     static uint8_t tid = 0;
99     struct bt_mesh_model *vnd_model = ble_mesh_model_find(0, BT_MESH_MODEL_VND_MODEL_SRV, CONFIG_CID_TAOBAO);
100 
101     if (!vnd_model) {
102         return -1;
103     }
104 
105     vnd_model_msg vnd_msg = { 0 };
106     vnd_msg.netkey_idx = 0;
107     vnd_msg.appkey_idx = 0;
108     vnd_msg.dst_addr = dst_addr;
109     vnd_msg.tid = tid++;
110     vnd_msg.model = vnd_model;
111     vnd_msg.opid = VENDOR_OP_ATTR_MESH_AUTOCONFIG_STATUS;
112     vnd_msg.len = 1;
113     vnd_msg.data = (uint8_t *)&status;
114     return ble_mesh_vendor_srv_model_msg_send(&vnd_msg);
115 #else
116     return 0;
117 #endif
118 }
auto_config_timeout_cb(void * timer,void * arg)119 static void auto_config_timeout_cb(void *timer, void *arg)
120 {
121     int16_t ret;
122 
123     k_timer_stop(&g_mesh_node.auto_config_timer);
124 
125     if (!bt_mesh_store_mod_pending_check()) {
126         g_mesh_node.auto_config_status = BT_MESH_AUTO_CONFIG_SUCCEED;
127         g_mesh_node.node_provisioned = 1;
128 
129         if (g_mesh_node.auto_config_ack_flag) {
130             ret = report_auto_config_status(g_mesh_node.prov_addr, g_mesh_node.auto_config_status);
131 
132             if (ret) {
133                 LOGE(TAG, "report auto config status faild");
134             }
135         }
136 
137         ret = aos_kv_setint("AUTO_CONFIG", BT_MESH_AUTO_CONFIG_SUCCEED);
138 
139         if (ret) {
140             LOGE(TAG, "save auto config status faild");
141         }
142 
143 #ifdef BT_MESH_BEACON_RSSI_REPORT
144 
145         if (g_mesh_node.rssi_report_enable) {
146             init_rssi_report();
147         }
148 
149 #endif
150     } else {
151         LOGI(TAG, "store is pending");
152 
153         if (g_mesh_node.auto_config_retry) {
154             k_timer_start(&g_mesh_node.auto_config_timer, g_mesh_node.auto_config_timeout);
155             g_mesh_node.auto_config_retry--;
156         }
157     }
158 }
159 #endif
160 
161 #ifdef CONFIG_BT_MESH_PROVISIONER
162 
163 static uint16_t last_addr;
164 
165 static struct bt_mesh_prov node_prov = {
166     .uuid = dev_uuid,
167     .link_open = NULL,
168     .link_close = NULL,
169     .complete = NULL,
170     .reset = NULL,
171     .static_val = g_static_data,
172     .static_val_len = 0,
173     .input_size = 0,
174     .input_actions = 0,
175     .input = NULL,
176     .output_size = 0,
177     .output_actions = 0,
178     .output_number = NULL,
179     .output_string = NULL,
180 };
181 #else
182 static void link_open(bt_mesh_prov_bearer_t bearer);
183 static void link_close(bt_mesh_prov_bearer_t bearer);
184 static void prov_complete(uint16_t net_idx, uint16_t addr);
185 static void prov_reset(void);
186 static int output_number(bt_mesh_output_action_t action, bt_u32_t number);
187 static int output_string(const char *str);
188 static int node_input(bt_mesh_input_action_t act, u8_t size);
189 
190 static struct bt_mesh_prov node_prov = {
191     .uuid = dev_uuid,
192     .link_open = link_open,
193     .link_close = link_close,
194     .complete = prov_complete,
195     .reset = prov_reset,
196     .static_val = g_static_data,
197     .static_val_len = 0,
198     .input_size = 0,
199     .input_actions = 0,
200     .input = node_input,
201     .output_size = 0,
202     .output_actions = 0,
203     .output_number = output_number,
204     .output_string = output_string,
205 };
206 #endif
207 
208 typedef struct auto_config_t {
209     uint16_t mod_id;
210     uint16_t cid;
211     uint16_t appkey_idx;
212     uint16_t sub_addr;
213     uint16_t pub_addr;
214 } auto_config_t;
215 
node_config(struct bt_mesh_model * mod,struct bt_mesh_elem * elem,bool vnd,bool primary,void * user_data)216 static void node_config(struct bt_mesh_model *mod, struct bt_mesh_elem *elem, bool vnd, bool primary, void *user_data)
217 {
218     auto_config_t *config = user_data;
219 
220     if (!config) {
221         return;
222     }
223 
224     if (!vnd && (mod->id == BT_MESH_MODEL_ID_CFG_SRV || mod->id == BT_MESH_MODEL_ID_CFG_CLI ||
225                  mod->id == BT_MESH_MODEL_ID_HEALTH_SRV || mod->id == BT_MESH_MODEL_ID_HEALTH_CLI)) {
226         return;
227     }
228 
229     if (!vnd) {
230         if (config->mod_id != 0xffff && config->mod_id != mod->id) {
231             return;
232         }
233     } else {
234         if ((config->mod_id != 0xffff && config->cid != 0xffff) &&
235             (config->mod_id != mod->vnd.id || config->cid != mod->vnd.company)) {
236             return;
237         }
238     }
239 
240     bt_mesh_mod_bind(mod, config->appkey_idx);
241 
242     bt_mesh_mod_sub_add(mod, config->sub_addr);
243 
244     bt_mesh_mod_pub_set(mod, config->pub_addr);
245 }
246 
auto_config(auto_config_t * config)247 static int16_t auto_config(auto_config_t *config)
248 {
249     if (!config) {
250         return -EINVAL;
251     }
252 
253     LOGD(TAG, "bind appkey:%04x sub addr:%04x pub addr:%04x", config->appkey_idx, config->sub_addr, config->pub_addr);
254     extern void bt_mesh_model_foreach(void (*func)(struct bt_mesh_model *mod, struct bt_mesh_elem *elem, bool vnd,
255                                                    bool primary, void *user_data),
256                                       void *user_data);
257     bt_mesh_model_foreach(node_config, config);
258 
259     return 0;
260 }
261 
262 #ifdef CONFIG_BT_MESH_PROVISIONER
ble_mesh_node_appkey_add(uint16_t netkey_idx,uint16_t appkey_idx,uint16_t unicast_addr)263 int ble_mesh_node_appkey_add(uint16_t netkey_idx, uint16_t appkey_idx, uint16_t unicast_addr)
264 {
265     const uint8_t *app_key;
266     int16_t ret;
267 
268     app_key = bt_mesh_provisioner_local_app_key_get(netkey_idx, appkey_idx);
269 
270     if (NULL == app_key) {
271         return -1;
272     }
273 
274     ret = bt_mesh_cfg_app_key_add(0, unicast_addr, netkey_idx, appkey_idx, app_key, NULL);
275 
276     if (ret && TIMEOUT != ret) {
277         LOGE(TAG, "mesh appkey add set status send fail %d", ret);
278         return ret;
279     }
280 
281     return 0;
282 }
283 
ble_mesh_node_model_autoconfig(uint16_t netkey_idx,uint16_t appkey_idx,uint16_t addr,model_auto_config_t auto_conf)284 int ble_mesh_node_model_autoconfig(uint16_t netkey_idx, uint16_t appkey_idx, uint16_t addr,
285                                    model_auto_config_t auto_conf)
286 {
287 #ifdef CONFIG_BT_MESH_MODEL_VENDOR_SRV
288     static uint8_t tid = 0;
289     struct bt_mesh_model *vendor_model;
290     vnd_model_msg vnd_msg = { 0 };
291     int16_t ret;
292     uint16_t send_data;
293     vendor_model = ble_mesh_model_find(0, BT_MESH_MODEL_VND_MODEL_CLI, BT_MESH_MODEL_VND_COMPANY_ID);
294 
295     if (!vendor_model) {
296         return -1;
297     }
298 
299     send_data = auto_conf.sub_addr;
300     vnd_msg.netkey_idx = netkey_idx;
301     vnd_msg.appkey_idx = appkey_idx;
302     vnd_msg.dst_addr = addr;
303     vnd_msg.tid = tid++;
304     vnd_msg.model = vendor_model;
305     vnd_msg.len = 2;
306     vnd_msg.opid = VENDOR_OP_ATTR_MESH_AUTOCONFIG;
307     vnd_msg.data = (uint8_t *)&send_data;
308 
309     ret = ble_mesh_vendor_cli_model_msg_send(&vnd_msg);
310 
311     if (ret) {
312         return -1;
313     }
314 #endif
315     return 0;
316 }
317 
add_appkey_timeout_cb(void * timer,void * arg)318 static void add_appkey_timeout_cb(void *timer, void *arg)
319 {
320     int16_t ret;
321     k_timer_stop(&g_mesh_node.add_appkey_timer);
322 
323     if (g_mesh_node.app_key_add_retry) {
324         ret = ble_mesh_node_appkey_add(0, g_mesh_node.auto_add_appkey_idx, last_addr);
325 
326         if (ret) {
327             LOGE(TAG, "add appkey send faild");
328         } else {
329             g_mesh_node.app_key_add_retry--;
330             k_timer_start(&g_mesh_node.add_appkey_timer, g_mesh_node.add_appkey_timeout);
331         }
332 
333     } else {
334         LOGE(TAG, "add appkey faild");
335     }
336 }
337 
provisioner_node_cb(mesh_provisioner_event_en event,void * p_arg)338 static void provisioner_node_cb(mesh_provisioner_event_en event, void *p_arg)
339 {
340     switch (event) {
341         // provisioner message
342 
343     case BT_MESH_EVENT_PROV_COMP: {
344         if (p_arg) {
345             mesh_node_t *node = (mesh_node_t *)p_arg;
346             uint8_t auto_add_appkey = 0;
347             extern int ble_mesh_provisioner_get_add_appkey_flag(u16_t unicast_addr);
348             auto_add_appkey = ble_mesh_provisioner_get_add_appkey_flag(node->prim_unicast);
349 
350             if (auto_add_appkey) {
351                 g_mesh_node.app_key_add_retry = DEF_ADD_APPKEY_RETRY;
352                 g_mesh_node.add_appkey_timeout = DEF_ADD_APPKEY_TIMEOUT;
353                 g_mesh_node.auto_add_appkey_idx = 0;
354                 last_addr = node->prim_unicast;
355                 k_timer_start(&g_mesh_node.add_appkey_timer, DEF_ADD_APPKEY_DELAY);
356             }
357         }
358     } break;
359 
360     default:
361         break;
362     }
363 
364     if (g_mesh_node.user_provisioner_cb) {
365         g_mesh_node.user_provisioner_cb(event, p_arg);
366     }
367 }
368 
369 #else
370 
371 // __attribute__((unused)) static const char *bearer2str(int bearer)
bearer2str(int bearer)372 static const char *bearer2str(int bearer)
373 {
374     switch (bearer) {
375     case BT_MESH_PROV_ADV:
376         return "PB-ADV";
377 
378     case BT_MESH_PROV_GATT:
379         return "PB-GATT";
380 
381     default:
382         return "unknown";
383     }
384 }
385 
link_open(bt_mesh_prov_bearer_t bearer)386 static void link_open(bt_mesh_prov_bearer_t bearer)
387 {
388     LOGI(TAG, "Provisioning link opened on %s\n", bearer2str(bearer));
389 }
390 
link_close(bt_mesh_prov_bearer_t bearer)391 static void link_close(bt_mesh_prov_bearer_t bearer)
392 {
393     LOGI(TAG, "Provisioning link closed on %s\n", bearer2str(bearer));
394 }
395 
prov_complete(uint16_t net_idx,uint16_t addr)396 static void prov_complete(uint16_t net_idx, uint16_t addr)
397 {
398     LOGI(TAG, "provisioning complete netid %d, primary element address 0x%x", net_idx, addr);
399     mesh_node_local_t node_info;
400     node_info.prim_unicast = addr;
401     g_mesh_node.auto_config_status = BT_MESH_AUTO_CONFIG_NOT_START;
402     g_mesh_node.app_key_add_flag = 0;
403 
404     if (g_mesh_node.user_prov_cb) {
405         g_mesh_node.user_prov_cb(BT_MESH_EVENT_NODE_PROV_COMP, &node_info);
406     }
407 }
408 
prov_reset(void)409 static void prov_reset(void)
410 {
411     LOGD(TAG, "Node Reset");
412     bt_mesh_prov_enable(BT_MESH_PROV_ADV | BT_MESH_PROV_GATT);
413 
414     if (g_mesh_node.user_prov_cb) {
415         g_mesh_node.user_prov_cb(BT_MESH_EVENT_NODE_REST, NULL);
416     }
417 }
418 
output_number(bt_mesh_output_action_t action,bt_u32_t number)419 static int output_number(bt_mesh_output_action_t action, bt_u32_t number)
420 {
421     LOGI(TAG, "OOB Number: %u\n", number);
422     return 0;
423 }
424 
output_string(const char * str)425 static int output_string(const char *str)
426 {
427     LOGI(TAG, "OOB String: %s\n", str);
428     return 0;
429 }
430 
node_input(bt_mesh_input_action_t act,u8_t size)431 static int node_input(bt_mesh_input_action_t act, u8_t size)
432 {
433     switch (act) {
434     case BT_MESH_ENTER_NUMBER: {
435         LOGI(TAG, "Enter a number (max %u digits) with: input-num <num>\n", size);
436 
437         if (g_mesh_node.user_prov_cb) {
438             g_mesh_node.user_prov_cb(BT_MESH_EVENT_NODE_OOB_INPUT_NUM, &size);
439         }
440     } break;
441 
442     case BT_MESH_ENTER_STRING: {
443         LOGI(TAG, "Enter a string (max %u chars) with: input-str <str>\n", size);
444 
445         if (g_mesh_node.user_prov_cb) {
446             g_mesh_node.user_prov_cb(BT_MESH_EVENT_NODE_OOB_INPUT_STRING, &size);
447         }
448     } break;
449 
450     default: {
451         LOGI(TAG, "Unknown input action %u (size %u) requested!\n", act, size);
452         return -EINVAL;
453     } break;
454     }
455 
456     g_mesh_node.input_act = act;
457     g_mesh_node.input_size = size;
458     return 0;
459 }
460 
461 #ifdef BT_MESH_BEACON_RSSI_REPORT
is_rssi_data_queue_empty(rssi_data_queue * queue)462 static bool is_rssi_data_queue_empty(rssi_data_queue *queue)
463 {
464     return queue->front == queue->rear;
465 }
466 
is_rssi_data_queue_full(rssi_data_queue * queue)467 static bool is_rssi_data_queue_full(rssi_data_queue *queue)
468 {
469     if ((queue->rear + 1) % 16 == queue->front) {
470         return true;
471     } else {
472         return false;
473     }
474 }
475 
get_rssi_data(rssi_data_queue * queue)476 static beacon_rssi_data *get_rssi_data(rssi_data_queue *queue)
477 {
478     if (is_rssi_data_queue_empty(queue)) {
479         return NULL;
480     } else {
481         beacon_rssi_data *data = &queue->data[queue->front];
482         queue->front = (queue->front + 1) % 16;
483         return data;
484     }
485 }
486 
put_rssi_data(rssi_data_queue * queue,const uint8_t * mac,int8_t rssi,int8_t rssi_calibration)487 static int put_rssi_data(rssi_data_queue *queue, const uint8_t *mac, int8_t rssi, int8_t rssi_calibration)
488 {
489     if (is_rssi_data_queue_full(queue)) {
490         return -1;
491     }
492 
493     memcpy(queue->data[queue->rear].mac, mac, 6);
494     queue->data[queue->rear].rssi = rssi;
495     queue->data[queue->rear].rssi_calibration = rssi_calibration;
496     queue->rear = (queue->rear + 1) % 16;
497     return 0;
498 }
499 
data_complent_u8(int8_t data)500 static uint8_t data_complent_u8(int8_t data)
501 {
502     uint8_t out;
503 
504     if (data <= 0) {
505         out = data;
506     } else {
507         uint8_t in = -data;
508         out = ~in + 1;
509     }
510 
511     return out;
512 }
513 
beacon_rssi_cb(const struct adv_addr_t * addr,s8_t rssi,u8_t adv_type,void * user_data,uint16_t len)514 static void beacon_rssi_cb(const struct adv_addr_t *addr, s8_t rssi, u8_t adv_type, void *user_data, uint16_t len)
515 {
516     if (!g_mesh_node.node_provisioned) {
517         return;
518     }
519 
520     if (!user_data || !len) {
521         return;
522     }
523 
524     struct net_buf_simple *buf = (struct net_buf_simple *)user_data;
525 
526     uint8_t data_len = net_buf_simple_pull_u8(buf);
527 
528     if (!data_len) {
529         return;
530     }
531 
532     uint8_t opid = net_buf_simple_pull_u8(buf);
533 
534     if (0x02 != opid) {
535         return;
536     }
537 
538     int8_t rssi_calibration = net_buf_simple_pull_u8(buf);
539 
540     put_rssi_data(&g_mesh_node.rssi_queue, addr->val, data_complent_u8(rssi), data_complent_u8(rssi_calibration));
541 }
542 
rssi_repot_timeout(void * timer,void * args)543 void rssi_repot_timeout(void *timer, void *args)
544 {
545     beacon_rssi_data *data = NULL;
546     k_timer_start(&g_mesh_node.beacon_rssi_timer, RSSI_BEACON_REPORT_PERIOD);
547     data = get_rssi_data(&g_mesh_node.rssi_queue);
548 
549     if (!data) {
550         return;
551     }
552 
553     struct bt_mesh_model *vendor_model;
554 
555     vendor_model = ble_mesh_model_find(0, BT_MESH_MODEL_VND_MODEL_SRV, CONFIG_CID_TAOBAO);
556 
557     if (!vendor_model || !vendor_model->pub || BT_MESH_ADDR_UNASSIGNED == vendor_model->pub->addr) {
558         return;
559     }
560 
561     vnd_model_msg vnd_data = { 0 };
562     uint8_t rssi_data[60];
563     snprintf((char *)rssi_data, sizeof(rssi_data), "rssi%02x,%02x,%02x%02x%02x%02x%02x%02x", data->rssi,
564              data->rssi_calibration, data->mac[5], data->mac[4], data->mac[3], data->mac[2], data->mac[1],
565              data->mac[0]);
566     vnd_data.netkey_idx = 0;
567     vnd_data.appkey_idx = 0;
568     vnd_data.dst_addr = vendor_model->pub->addr;
569     vnd_data.model = vendor_model;
570     vnd_data.opid = VENDOR_OP_ATTR_TRANS_MSG;
571     vnd_data.data = rssi_data;
572     vnd_data.retry = 0;
573     vnd_data.len = strlen((char *)rssi_data);
574     ble_mesh_vendor_srv_model_msg_send(&vnd_data);
575 }
576 
init_rssi_report()577 static int init_rssi_report()
578 {
579     int16_t ret;
580     ret = bt_mesh_vnd_adv_set_cb(beacon_rssi_cb);
581 
582     if (ret) {
583         return ret;
584     }
585 
586     g_mesh_node.rssi_queue.front = 0;
587     g_mesh_node.rssi_queue.rear = 0;
588     g_mesh_node.rssi_queue.length = 16;
589     k_timer_init(&g_mesh_node.beacon_rssi_timer, rssi_repot_timeout, NULL);
590     k_timer_start(&g_mesh_node.beacon_rssi_timer, RSSI_BEACON_REPORT_PERIOD);
591     return 0;
592 }
593 #endif
594 
ble_mesh_node_OOB_input_string(const char * str)595 int ble_mesh_node_OOB_input_string(const char *str)
596 {
597     if (!g_mesh_node.init_flag) {
598         return -1;
599     }
600 
601     int16_t ret;
602 
603     if (g_mesh_node.input_act != BT_MESH_ENTER_STRING) {
604         LOGE(TAG, "A string hasn't been requested!\n");
605         return -1;
606     }
607 
608     if (strlen(str) < g_mesh_node.input_size) {
609         LOGE(TAG, "Too short input (%u characters required)\n", g_mesh_node.input_size);
610         return -1;
611     }
612 
613     ret = bt_mesh_input_string(str);
614 
615     if (ret) {
616         LOGE(TAG, "String input failed (err %d)\n", ret);
617         return -1;
618     }
619 
620     g_mesh_node.input_act = BT_MESH_NO_INPUT;
621 
622     return 0;
623 }
624 
ble_mesh_node_OOB_input_num(uint32_t num)625 int ble_mesh_node_OOB_input_num(uint32_t num)
626 {
627     if (!g_mesh_node.init_flag) {
628         return -1;
629     }
630 
631     int16_t ret;
632 
633     if (g_mesh_node.input_act != BT_MESH_ENTER_STRING) {
634         LOGE(TAG, "A num hasn't been requested!\n");
635         return -1;
636     }
637 
638     ret = bt_mesh_input_number(num);
639 
640     if (ret) {
641         LOGE(TAG, "num input failed (err %d)\n", ret);
642         return -1;
643     }
644 
645     g_mesh_node.input_act = BT_MESH_NO_INPUT;
646 
647     return 0;
648 }
649 
650 #endif
651 
node_model_message_cb(mesh_model_event_en event,void * p_arg)652 static void node_model_message_cb(mesh_model_event_en event, void *p_arg)
653 {
654     int ret;
655 
656     switch (event) {
657 #ifdef CONFIG_BT_MESH_PROVISIONER
658 
659     case BT_MESH_MODEL_CFG_APPKEY_STATUS: {
660         if (p_arg) {
661             model_message message = *(model_message *)p_arg;
662             uint8_t status = message.status_data->data[0];
663 
664             k_timer_stop(&g_mesh_node.add_appkey_timer);
665 
666             if (status) {
667                 if (g_mesh_node.app_key_add_retry) {
668                     ret = ble_mesh_node_appkey_add(0, g_mesh_node.auto_add_appkey_idx, last_addr);
669 
670                     if (ret) {
671                         LOGE(TAG, "add appkey faild");
672                     } else {
673                         g_mesh_node.app_key_add_retry--;
674                     }
675 
676                 } else {
677                     LOGE(TAG, "add appkey faild");
678                 }
679             }
680         }
681     } break;
682 #else
683 
684     case BT_MESH_MODEL_CFG_APP_KEY_ADD: {
685 #if defined(CONFIG_BT_MESH_MODEL_VENDOR_SRV)
686         if (p_arg) {
687             appkey_status *add_status = (appkey_status *)p_arg;
688 
689             if (!add_status->status) {
690                 if (g_mesh_node.app_key_add_flag) {
691                     break;
692                 }
693 
694                 g_mesh_node.app_key_add_flag = 1;
695                 auto_config_t config = {
696                     .appkey_idx = add_status->appkey_idx,
697                     .sub_addr = COMMON_SUB_ADDR,
698                     .pub_addr = COMMON_PUB_ADDR,
699                     .mod_id = BT_MESH_MODEL_VND_MODEL_SRV,
700                     .cid = BT_MESH_MODEL_VND_COMPANY_ID,
701                 };
702 
703                 auto_config(&config);
704             }
705         }
706 #endif
707     } break;
708 
709     case BT_MESH_MODEL_VENDOR_MESH_AUTOCONFIG: {
710         if (p_arg && BT_MESH_AUTO_CONFIG_START != g_mesh_node.auto_config_status) {
711             // uint8_t tid;
712             int16_t ret;
713             model_message *msg = (model_message *)p_arg;
714 
715             if (!g_mesh_node.app_key_add_flag) {
716                 g_mesh_node.auto_config_status = BT_MESH_AUTO_CONFIG_FAILD;
717 
718                 if (BT_MESH_ADDR_IS_UNICAST(msg->dst_addr)) {
719                     ret = report_auto_config_status(msg->source_addr, g_mesh_node.auto_config_status);
720 
721                     if (ret) {
722                         LOGE(TAG, "report auto config status faild");
723                     }
724                 }
725 
726                 return;
727             }
728 
729             if (BT_MESH_ADDR_IS_UNICAST(msg->dst_addr)) {
730                 g_mesh_node.auto_config_ack_flag = 1;
731             } else {
732                 g_mesh_node.auto_config_ack_flag = 0;
733             }
734 
735             if (BT_MESH_AUTO_CONFIG_SUCCEED == g_mesh_node.auto_config_status) {
736                 if (g_mesh_node.auto_config_ack_flag) {
737                     ret = report_auto_config_status(msg->source_addr, g_mesh_node.auto_config_status);
738 
739                     if (ret) {
740                         LOGE(TAG, "report auto config status faild");
741                     }
742 
743                     return;
744                 } else {
745                     return;
746                 }
747             }
748 
749             g_mesh_node.auto_config_status = BT_MESH_AUTO_CONFIG_START;
750 
751             net_buf_simple_pull_u8(msg->ven_data.user_data);
752             auto_config_t config = { 0 };
753             config.appkey_idx = 0;
754             config.sub_addr = net_buf_simple_pull_le16(msg->ven_data.user_data);
755             config.pub_addr = 0; // net_buf_simple_pull_le16(msg->ven_data.user_data);
756             config.mod_id = 0xffff;
757             config.cid = 0xffff;
758             ret = auto_config(&config);
759 
760             if (ret) {
761                 g_mesh_node.auto_config_status = BT_MESH_AUTO_CONFIG_FAILD;
762                 ret = aos_kv_setint("AUTO_CONFIG", BT_MESH_AUTO_CONFIG_FAILD);
763 
764                 if (ret) {
765                     LOGE(TAG, "save auto config status faild");
766                 }
767             }
768 
769             if (!ret) {
770                 g_mesh_node.prov_addr = msg->source_addr;
771                 g_mesh_node.auto_config_retry = DEF_AUTOCONFIG_STORE_CHECK_RETRY;
772                 g_mesh_node.auto_config_timeout = DEF_AUTOCONFIG_STORE_CHECK_TIMEOUT;
773                 k_timer_start(&g_mesh_node.auto_config_timer, g_mesh_node.auto_config_timeout);
774             }
775         }
776 
777     }
778 
779     break;
780 
781     case BT_MESH_MODEL_VENDOR_MESH_AUTOCONFIG_GET: {
782         if (p_arg) {
783             model_message *message = (model_message *)p_arg;
784 
785             if (!bt_mesh_store_mod_pending_check()) {
786                 ret = report_auto_config_status(message->source_addr, g_mesh_node.auto_config_status);
787 
788                 if (ret) {
789                     LOGE(TAG, "report auto config status faild");
790                 }
791             }
792         }
793     } break;
794 #endif
795     case BT_MESH_MODEL_CFG_RST_STATUS: {
796         ret = aos_kv_setint("AUTO_CONFIG", BT_MESH_AUTO_CONFIG_NOT_START);
797         if (ret) {
798             LOGE(TAG, "save auto config status faild");
799         }
800     } break;
801     default:
802         break;
803     }
804 
805     if (g_mesh_node.user_model_cb) {
806         g_mesh_node.user_model_cb(event, p_arg);
807     }
808 }
809 
node_attention_on(struct bt_mesh_model * model)810 void node_attention_on(struct bt_mesh_model *model)
811 {
812     if (g_mesh_node.health_cb.att_on) {
813         g_mesh_node.health_cb.att_on();
814     }
815 }
816 
node_attention_off(struct bt_mesh_model * model)817 void node_attention_off(struct bt_mesh_model *model)
818 {
819     if (g_mesh_node.health_cb.att_off) {
820         g_mesh_node.health_cb.att_off();
821     }
822 }
823 
824 struct bt_mesh_health_srv_cb g_health_cb = {
825     .attn_on = node_attention_on,
826     .attn_off = node_attention_off,
827 };
828 
ble_mesh_node_init(node_config_t * param)829 int ble_mesh_node_init(node_config_t *param)
830 {
831     if (!param) {
832         return -1;
833     }
834 
835     const struct bt_mesh_comp *mesh_comp = ble_mesh_model_get_comp_data();
836 
837     if (!mesh_comp || (NODE != param->role && PROVISIONER != param->role)) {
838         return -1;
839     }
840 
841     g_mesh_node.comp = mesh_comp;
842 
843     if (param->node_oob.static_oob_data) {
844         memcpy(g_static_data, param->node_oob.static_oob_data, 16);
845         node_prov.static_val_len = 16;
846     }
847 
848     if (ACTION_NUM == param->node_oob.input_action && param->node_oob.input_max_size > 0) {
849         node_prov.input_actions = BT_MESH_ENTER_NUMBER;
850         node_prov.input_size = param->node_oob.input_max_size;
851     } else if (ACTION_STR == param->node_oob.input_action && param->node_oob.input_max_size > 0) {
852         node_prov.input_actions = BT_MESH_ENTER_STRING;
853         node_prov.input_size = param->node_oob.input_max_size;
854     } else {
855         node_prov.input_actions = BT_MESH_NO_INPUT;
856         node_prov.input_size = 0;
857     }
858 
859     if (ACTION_NUM == param->node_oob.output_action && param->node_oob.output_max_size > 0) {
860         node_prov.output_actions = BT_MESH_DISPLAY_NUMBER;
861         node_prov.output_size = param->node_oob.output_max_size;
862     } else if (ACTION_STR == param->node_oob.output_action && param->node_oob.output_max_size > 0) {
863         node_prov.output_actions = BT_MESH_DISPLAY_STRING;
864         node_prov.output_size = param->node_oob.output_max_size;
865     } else {
866         node_prov.output_actions = BT_MESH_NO_OUTPUT;
867         node_prov.output_size = 0;
868     }
869 
870     if (PROVISIONER == param->role) {
871 #ifdef CONFIG_BT_MESH_PROVISIONER
872         int ret;
873         provisioner_cb app_cb;
874 
875         if (!param->provisioner_config ||
876             mesh_comp->elem_count > (param->provisioner_config->config.unicast_addr_start -
877                                      param->provisioner_config->config.unicast_addr_local)) {
878             return -EINVAL;
879         }
880 
881         app_cb = param->provisioner_config->config.cb;
882         param->provisioner_config->config.cb = provisioner_node_cb;
883         ret = ble_mesh_provisioner_init(&param->provisioner_config->config);
884 
885         if (ret) {
886             return ret;
887         }
888 
889         uint16_t appkey_idx = 0;
890         const ble_mesh_provisioner_t *prov_comp = ble_mesh_provisioner_get_provisioner_data();
891 
892         if (!prov_comp) {
893             return ret;
894         }
895 
896         dev_addr_t dev_addr;
897         ret = ble_stack_get_local_addr(&dev_addr);
898 
899         if (ret) {
900             return ret;
901         }
902 
903         memcpy(dev_uuid, param->dev_uuid, 16);
904         memcpy(dev_uuid, dev_addr.val, 6);
905 
906         ret = bt_mesh_init(&node_prov, mesh_comp, prov_comp->provisioner);
907 
908         if (ret) {
909             return ret;
910         }
911 
912         ret = ble_stack_setting_load();
913 
914         if (ret) {
915             return ret;
916         }
917 
918         ret = ble_mesh_provisioner_enable();
919 
920         if (ret && (ret != -EALREADY)) {
921             return ret;
922         }
923 
924         bt_mesh_provisioner_local_provision();
925 
926         k_timer_init(&g_mesh_node.add_appkey_timer, add_appkey_timeout_cb, NULL);
927 
928         g_mesh_node.user_provisioner_cb = app_cb;
929         //add appkey 0
930         ret = bt_mesh_provisioner_local_app_key_add(NULL, 0, &appkey_idx);
931 
932         if (ret < 0 && -EEXIST != ret) {
933             return ret;
934         } else if (0 == ret || -EEXIST == ret) {
935             //bind all model to appkey0
936             extern u16_t bt_mesh_primary_addr(void);
937             bt_mesh_cfg_app_key_add(0, bt_mesh_primary_addr(), 0, appkey_idx,
938                                     bt_mesh_provisioner_local_app_key_get(0, appkey_idx), NULL);
939             auto_config_t config = {
940                 .appkey_idx = appkey_idx,
941                 .sub_addr = param->provisioner_config->local_sub,
942                 .pub_addr = param->provisioner_config->local_pub,
943                 .mod_id = 0xffff,
944                 .cid = 0xffff,
945             };
946             auto_config(&config);
947         }
948 
949         g_mesh_node.node_provisioned = 1;
950 #else
951         return -1;
952 #endif
953     } else {
954 #ifndef CONFIG_BT_MESH_PROVISIONER
955         int ret;
956 
957         g_mesh_node.user_prov_cb = param->user_prov_cb;
958 
959         ret = bt_mesh_init(&node_prov, mesh_comp, NULL);
960 
961         if (ret) {
962             return ret;
963         }
964 
965         ret = ble_stack_setting_load();
966 
967         if (ret) {
968             return ret;
969         }
970 
971         ret = ble_stack_set_name((char *)param->dev_name);
972 
973         if (ret) {
974             return ret;
975         }
976 
977         dev_addr_t dev_addr;
978         ret = ble_stack_get_local_addr(&dev_addr);
979 
980         if (ret) {
981             return ret;
982         }
983 
984         memcpy(dev_uuid, param->dev_uuid, 16);
985         memcpy(dev_uuid, dev_addr.val, 6);
986 
987         /* This will be a no-op if settings_load() loaded provisioning info */
988         bt_mesh_prov_enable(BT_MESH_PROV_ADV | BT_MESH_PROV_GATT);
989 
990         k_timer_init(&g_mesh_node.auto_config_timer, auto_config_timeout_cb, NULL);
991         g_mesh_node.node_provisioned = bt_mesh_is_provisioned();
992 
993         if (g_mesh_node.node_provisioned) {
994             int auto_config_status = 0;
995             ret = aos_kv_getint("AUTO_CONFIG", &auto_config_status);
996             if (ret) {
997                 g_mesh_node.auto_config_status = BT_MESH_AUTO_CONFIG_NOT_START;
998             } else {
999                 g_mesh_node.auto_config_status = auto_config_status;
1000             }
1001         } else {
1002             g_mesh_node.node_provisioned = BT_MESH_AUTO_CONFIG_NOT_START;
1003         }
1004 
1005         extern struct bt_mesh_app_key *bt_mesh_app_key_find(u16_t app_idx);
1006 
1007         if (!bt_mesh_app_key_find(0)) {
1008             g_mesh_node.app_key_add_flag = 0;
1009         } else {
1010             g_mesh_node.app_key_add_flag = 1;
1011         }
1012 
1013 #ifdef BT_MESH_BEACON_RSSI_REPORT
1014         g_mesh_node.rssi_report_enable = param->rssi_report_enable;
1015 
1016         if (g_mesh_node.node_provisioned && g_mesh_node.rssi_report_enable) {
1017             init_rssi_report();
1018         }
1019 
1020 #endif
1021 #else
1022         return -1;
1023 #endif
1024     }
1025 
1026     ble_mesh_model_set_cb(node_model_message_cb);
1027 
1028     extern int mesh_event_port_init();
1029     mesh_event_port_init();
1030 
1031     if (param->health_cb && (param->health_cb->att_on || param->health_cb->att_off)) {
1032         extern int health_srv_cb_register(struct bt_mesh_health_srv_cb * health_cb);
1033 
1034         if (health_srv_cb_register(&g_health_cb)) {
1035             LOGE(TAG, "register health srv cb faild");
1036         }
1037 
1038         g_mesh_node.health_cb.att_on = param->health_cb->att_on;
1039         g_mesh_node.health_cb.att_off = param->health_cb->att_off;
1040     }
1041 
1042     g_mesh_node.user_model_cb = param->user_model_cb;
1043     g_mesh_node.init_flag = 1;
1044 
1045     return g_mesh_node.node_provisioned;
1046 }
1047