1 /*
2  * Copyright (C) 2018-2020 Alibaba Group Holding Limited
3  */
4 
5 #include "genie_service.h"
6 #include "mesh_hal_ble.h"
7 #include "mesh/cfg_srv.h"
8 #include "mesh.h"
9 #include "prov.h"
10 
11 #define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_MESH_DEBUG_EVENT)
12 #include "common/log.h"
13 
14 extern void genie_appkey_register(u16_t net_idx, u16_t app_idx, const u8_t val[16], bool update);
15 
_genie_event_handle_mesh_init(void)16 static genie_event_e _genie_event_handle_mesh_init(void)
17 {
18 #ifndef CONFIG_BT_SETTINGS
19     genie_provision_t genie_provision;
20 
21     if (genie_provision_get_saved_data(&genie_provision) == 0)
22     {
23         bt_mesh_provision(genie_provision.netkey.key, genie_provision.netkey.net_index, genie_provision.netkey.flag, genie_provision.netkey.ivi, genie_provision.addr, genie_provision.devkey);
24         genie_appkey_register(genie_provision.appkey.net_index, genie_provision.appkey.key_index, genie_provision.appkey.key, genie_provision.appkey.flag);
25 
26         /* check hb */
27         mesh_hb_para_t hb_para = {.count = 0};
28         if (genie_storage_read_hb(&hb_para) == GENIE_STORAGE_READ_FAIL)
29         {
30             extern u8_t genie_heartbeat_set(mesh_hb_para_t * p_para);
31             genie_heartbeat_set(&hb_para);
32         }
33 
34         return GENIE_EVT_NONE;
35     }
36     else
37     {
38         bt_mesh_prov_enable(BT_MESH_PROV_GATT | BT_MESH_PROV_ADV);
39 
40         return GENIE_EVT_SDK_MESH_PBADV_START; //prov start
41     }
42 #else
43     if (bt_mesh_is_provisioned())
44     {
45         genie_mesh_load_group_addr();
46         genie_mesh_setup();
47         return GENIE_EVT_NONE;
48     }
49     else
50     {
51         bt_mesh_prov_enable(BT_MESH_PROV_GATT | BT_MESH_PROV_ADV);
52 
53         return GENIE_EVT_SDK_MESH_PBADV_START; //prov start
54     }
55 #endif
56 }
57 
_genie_event_handle_pbadv_start(void)58 static genie_event_e _genie_event_handle_pbadv_start(void)
59 {
60     genie_service_ctx_t *p_context = NULL;
61 
62 #ifdef CONFIG_PM_SLEEP
63     genie_lpm_disable();
64 #endif
65 
66     genie_provision_clear_silent_flag();
67     extern void genie_set_silent_unprov_beacon_interval(bool is_silent);
68     genie_set_silent_unprov_beacon_interval(false);
69 
70     p_context = genie_service_get_context();
71     if (p_context)
72     {
73         genie_provision_pbadv_timer_start(p_context->prov_timeout);
74     }
75 
76     return GENIE_EVT_NONE;
77 }
78 
_genie_event_handle_pbadv_timeout(void)79 static genie_event_e _genie_event_handle_pbadv_timeout(void)
80 {
81 #ifdef CONFIG_PM_SLEEP
82     genie_lpm_enable(true);
83 #endif
84 
85     genie_provision_pbadv_timer_stop();
86     bt_mesh_prov_disable(BT_MESH_PROV_GATT | BT_MESH_PROV_ADV);
87 
88     return GENIE_EVT_SDK_MESH_SILENT_START; //Enter silent provision mode
89 }
90 
_genie_event_handle_silent_start(void)91 static genie_event_e _genie_event_handle_silent_start(void)
92 {
93     genie_provision_start_slient_pbadv();
94 
95     return GENIE_EVT_NONE;
96 }
97 
_genie_event_handle_prov_start(void)98 static genie_event_e _genie_event_handle_prov_start(void)
99 {
100     if (genie_provision_get_state() == GENIE_PROVISION_UNPROV)
101     {
102         genie_provision_set_state(GENIE_PROVISION_START);
103         /* disable adv timer */
104         genie_provision_pbadv_timer_stop();
105         /* enable prov timer */
106         genie_provision_prov_timer_start();
107     }
108 
109     return GENIE_EVT_NONE;
110 }
111 
_genie_event_handle_prov_data(uint16_t * p_addr)112 static genie_event_e _genie_event_handle_prov_data(uint16_t *p_addr)
113 {
114 #ifndef CONFIG_BT_SETTINGS
115     genie_storage_write_addr(p_addr);
116 #endif
117     return GENIE_EVT_NONE;
118 }
119 
_genie_event_handle_prov_timeout(void)120 static genie_event_e _genie_event_handle_prov_timeout(void)
121 {
122     return GENIE_EVT_SDK_MESH_PROV_FAIL;
123 }
124 
_genie_event_handle_prov_success(void)125 static genie_event_e _genie_event_handle_prov_success(void)
126 {
127     genie_provision_pbadv_timer_stop();
128 
129     return GENIE_EVT_NONE;
130 }
131 
_genie_event_handle_prov_fail(void)132 static genie_event_e _genie_event_handle_prov_fail(void)
133 {
134     /* reset prov */
135     genie_provision_set_state(GENIE_PROVISION_UNPROV);
136     genie_reset_provision();
137     /* restart adv */
138     bt_mesh_prov_enable(BT_MESH_PROV_GATT | BT_MESH_PROV_ADV);
139 
140     return GENIE_EVT_SDK_MESH_PBADV_START;
141 }
142 
_genie_event_save_mesh_data(uint8_t * p_status)143 static void _genie_event_save_mesh_data(uint8_t *p_status)
144 {
145     if (*p_status == 0)
146     {
147 #ifndef CONFIG_BT_SETTINGS
148         genie_storage_write_para(&bt_mesh);
149 #endif
150     }
151 }
152 
_genie_event_handle_appkey_add(uint8_t * p_status)153 static genie_event_e _genie_event_handle_appkey_add(uint8_t *p_status)
154 {
155     if (genie_provision_get_state() == GENIE_PROVISION_START)
156     {
157         /* disable prov timer */
158         genie_provision_prov_timer_stop();
159 
160         if (*p_status == 0)
161         {
162 #ifndef CONFIG_BT_SETTINGS
163             //genie_storage_write_para(&bt_mesh);
164             uint8_t devkey[16];
165             mesh_netkey_para_t netkey;
166             mesh_appkey_para_t appkey;
167 
168             memcpy(devkey, bt_mesh.dev_key, 16);
169             memset(&netkey, 0, sizeof(netkey));
170             memcpy(netkey.key, bt_mesh.sub[0].keys[0].net, 16);
171             memset(&appkey, 0, sizeof(appkey));
172             memcpy(appkey.key, bt_mesh.app_keys[0].keys[0].val, 16);
173             genie_storage_write_devkey(devkey);
174             genie_storage_write_netkey(&netkey);
175             genie_storage_write_appkey(&appkey);
176 #endif
177             genie_provision_set_state(GENIE_PROVISION_SUCCESS);
178             genie_mesh_ready_checktimer_restart(GENIE_PROV_SUCCESS_REPORT_TIMEOUT);
179             return GENIE_EVT_SDK_MESH_PROV_SUCCESS;
180         }
181         else
182         {
183             return GENIE_EVT_SDK_MESH_PROV_FAIL;
184         }
185     }
186     else
187     {
188         _genie_event_save_mesh_data(p_status);
189         return GENIE_EVT_NONE;
190     }
191 }
192 
_genie_event_handle_hb_set(mesh_hb_para_t * p_para)193 static genie_event_e _genie_event_handle_hb_set(mesh_hb_para_t *p_para)
194 {
195 #ifndef CONFIG_BT_SETTINGS
196     BT_DBG("save");
197     genie_storage_write_hb(p_para);
198 #endif
199     return GENIE_EVT_NONE;
200 }
201 
202 #ifdef CONFIG_BT_MESH_CTRL_RELAY
_genie_event_handle_ctrl_relay_set(mesh_ctrl_relay_para_t * p_para)203 static genie_event_e _genie_event_handle_ctrl_relay_set(mesh_ctrl_relay_para_t *p_para)
204 {
205     printf("save ctrl relay param\n");
206     genie_storage_write_ctrl_relay(p_para);
207     return GENIE_EVT_NONE;
208 }
209 #endif
210 
_genie_event_handle_seq_update(void)211 static genie_event_e _genie_event_handle_seq_update(void)
212 {
213 #ifndef CONFIG_BT_SETTINGS
214     uint32_t seq = bt_mesh.seq;
215 
216     genie_storage_write_seq(&seq, false);
217 #endif
218     return GENIE_EVT_NONE;
219 }
220 
_genie_event_handle_ais_discon(void)221 static genie_event_e _genie_event_handle_ais_discon(void)
222 {
223     if (0 == bt_mesh_prov_enable(BT_MESH_PROV_GATT | BT_MESH_PROV_ADV))
224     {
225         return GENIE_EVT_SDK_MESH_PBADV_START;
226     }
227     else
228     {
229         return GENIE_EVT_NONE;
230     }
231 }
232 
_genie_event_handle_vnd_msg(genie_transport_model_param_t * p_msg)233 static genie_event_e _genie_event_handle_vnd_msg(genie_transport_model_param_t *p_msg)
234 {
235     BT_DBG("vendor message received");
236     genie_model_handle_mesg(p_msg);
237 
238     return GENIE_EVT_NONE;
239 }
240 
genie_down_msg(genie_down_mesg_type msg_type,uint32_t opcode,void * p_msg)241 int genie_down_msg(genie_down_mesg_type msg_type, uint32_t opcode, void *p_msg)
242 {
243     uint8_t *p_data = NULL;
244     uint16_t data_len = 0;
245     genie_service_ctx_t *p_context = NULL;
246 
247 #ifdef CONIFG_GENIE_MESH_USER_CMD
248     uint8_t element_id = 0;
249     genie_down_msg_t down_msg;
250 #endif
251 
252     p_context = genie_service_get_context();
253 
254     if (p_msg == NULL || !p_context || !p_context->event_cb)
255     {
256         GENIE_LOG_ERR("param err");
257         return -1;
258     }
259 
260     if (GENIE_DOWN_MESG_VENDOR_TYPE == msg_type)
261     {
262         genie_transport_model_param_t *p_vnd_mesg = (genie_transport_model_param_t *)p_msg;
263         data_len = 4 + p_vnd_mesg->len;
264         p_data = (uint8_t *)aos_malloc(data_len);
265         if (p_data == NULL)
266         {
267             return -1;
268         }
269 
270         p_data[0] = p_vnd_mesg->opid;
271         p_data[1] = opcode;
272         p_data[2] = opcode >> 8;
273         p_data[3] = p_vnd_mesg->tid;
274         if (p_vnd_mesg->len > 0)
275         {
276             memcpy(&p_data[4], p_vnd_mesg->data, p_vnd_mesg->len);
277         }
278 
279 #ifdef CONIFG_GENIE_MESH_USER_CMD
280         sig_model_element_state_t *p_elem_state = (sig_model_element_state_t *)p_vnd_mesg->p_model->user_data;
281         if (p_elem_state)
282         {
283             element_id = p_elem_state->element_id;
284         }
285 #endif
286     }
287     else
288     {
289         sig_model_msg *p_net_buf = (sig_model_msg *)p_msg;
290 
291         p_context->event_cb(GENIE_EVT_SIG_MODEL_MSG, (void *)p_msg);
292 
293         if (opcode < 0x7F) //one byte opcode
294         {
295             data_len = 1 + p_net_buf->len;
296             p_data = (uint8_t *)aos_malloc(data_len);
297             if (p_data == NULL)
298             {
299                 return -1;
300             }
301             p_data[0] = opcode & 0xFF;
302             memcpy(&p_data[1], p_net_buf->data, p_net_buf->len);
303         }
304         else
305         {
306             data_len = 2 + p_net_buf->len;
307             p_data = (uint8_t *)aos_malloc(data_len);
308             if (p_data == NULL)
309             {
310                 return -1;
311             }
312             p_data[0] = (opcode >> 8) & 0xFF;
313             p_data[1] = opcode & 0xFF;
314             memcpy(&p_data[2], p_net_buf->data, p_net_buf->len);
315         }
316 #ifdef CONIFG_GENIE_MESH_USER_CMD
317         element_id = p_net_buf->element_id;
318 #endif
319     }
320 
321 #ifdef CONFIG_GENIE_MESH_AT_CMD
322     genie_at_cmd_send_data_to_mcu(p_data, data_len);
323 #endif
324 
325 #ifdef CONIFG_GENIE_MESH_BINARY_CMD
326     genie_bin_cmds_send_data_to_mcu(p_data, data_len);
327 #endif
328 
329 #ifdef CONIFG_GENIE_MESH_USER_CMD
330     down_msg.len = data_len;
331     down_msg.data = p_data;
332     down_msg.element_id = element_id;
333 
334     p_context->event_cb(GENIE_EVT_DOWN_MSG, (void *)&down_msg);
335 #endif
336 
337     aos_free(p_data);
338 
339     return 0;
340 }
341 
342 #ifdef MESH_MODEL_VENDOR_TIMER
genie_model_notify_onoff_msg(vendor_attr_data_t * attr_data)343 static genie_event_e genie_model_notify_onoff_msg(vendor_attr_data_t *attr_data) //notify MCU
344 {
345     genie_transport_model_param_t msg;
346     uint8_t payload[3] = {0};
347 
348     BT_DBG("type:%04x data:%04x\r\n", attr_data->type, attr_data->para);
349 
350     if (attr_data->type == ATTR_TYPE_GENERIC_ONOFF)
351     {
352         payload[0] = 0x00;
353         payload[1] = 0x01;
354         payload[2] = attr_data->para;
355 
356         memset(&msg, 0, sizeof(genie_transport_model_param_t));
357         msg.opid = VENDOR_OP_ATTR_SET_UNACK;
358         msg.tid = genie_transport_gen_tid();
359         msg.data = payload;
360         msg.len = sizeof(payload);
361         genie_down_msg(GENIE_DOWN_MESG_VENDOR_TYPE, CONFIG_MESH_VENDOR_COMPANY_ID, (void *)&msg);
362     }
363 
364     return GENIE_EVT_NONE;
365 }
366 #endif
367 
genie_event(genie_event_e event,void * p_arg)368 void genie_event(genie_event_e event, void *p_arg)
369 {
370     genie_event_e next_event = event;
371     uint8_t ignore_user_event = 0;
372     genie_service_ctx_t *p_context = NULL;
373 
374     p_context = genie_service_get_context();
375     if (!p_context || !p_context->event_cb)
376     {
377         return;
378     }
379 
380     if ((event != GENIE_EVT_SDK_SEQ_UPDATE) && (event != GENIE_EVT_USER_TRANS_CYCLE))
381     {
382         GENIE_LOG_INFO("GenieE:%d\r\n", event);
383     }
384 
385     switch (event)
386     {
387     case GENIE_EVT_SW_RESET:
388     {
389         //call user_event first
390         p_context->event_cb(GENIE_EVT_SW_RESET, p_arg);
391         ignore_user_event = 1;
392         next_event = genie_reset_do_sw_reset();
393     }
394     break;
395     case GENIE_EVT_HW_RESET_START:
396     {
397         if (p_arg == NULL)
398         {
399             next_event = genie_reset_do_hw_reset(false);
400         }
401         else
402         {
403             bool is_only_report = *(bool *)p_arg;
404 
405             next_event = genie_reset_do_hw_reset(is_only_report);
406         }
407     }
408     break;
409     case GENIE_EVT_BT_READY:
410     {
411         next_event = _genie_event_handle_mesh_init();
412     }
413     break;
414     case GENIE_EVT_SDK_AIS_DISCON:
415     {
416         next_event = _genie_event_handle_ais_discon();
417     }
418     break;
419     case GENIE_EVT_SDK_MESH_PBADV_START:
420     {
421         next_event = _genie_event_handle_pbadv_start();
422     }
423     break;
424     case GENIE_EVT_SDK_MESH_PBADV_TIMEOUT:
425     {
426         next_event = _genie_event_handle_pbadv_timeout();
427     }
428     break;
429     case GENIE_EVT_SDK_MESH_SILENT_START:
430     {
431         next_event = _genie_event_handle_silent_start();
432     }
433     break;
434     case GENIE_EVT_SDK_MESH_PROV_START:
435     {
436         next_event = _genie_event_handle_prov_start();
437     }
438     break;
439     case GENIE_EVT_SDK_MESH_PROV_DATA:
440     {
441         next_event = _genie_event_handle_prov_data((uint16_t *)p_arg);
442     }
443     break;
444     case GENIE_EVT_SDK_MESH_PROV_TIMEOUT:
445     {
446         next_event = _genie_event_handle_prov_timeout();
447     }
448     break;
449     case GENIE_EVT_SDK_MESH_PROV_FAIL:
450     {
451         next_event = _genie_event_handle_prov_fail();
452     }
453     break;
454     case GENIE_EVT_SDK_MESH_PROV_SUCCESS:
455     {
456         next_event = _genie_event_handle_prov_success();
457     }
458     break;
459     case GENIE_EVT_MESH_READY:
460     {
461         p_context->event_cb(GENIE_EVT_MESH_READY, p_arg); //Report user bootup data at first
462         ignore_user_event = 1;
463         genie_mesh_init_pharse_ii();
464         next_event = GENIE_EVT_NONE;
465     }
466     break;
467     case GENIE_EVT_SDK_APPKEY_ADD:
468     {
469         next_event = _genie_event_handle_appkey_add((uint8_t *)p_arg);
470     }
471     break;
472     case GENIE_EVT_SDK_APPKEY_DEL:
473     case GENIE_EVT_SDK_APPKEY_UPDATE:
474     case GENIE_EVT_SDK_NETKEY_ADD:
475     case GENIE_EVT_SDK_NETKEY_DEL:
476     case GENIE_EVT_SDK_NETKEY_UPDATE:
477     {
478         //TODO:Support key update
479         //_genie_event_save_mesh_data((uint8_t *)p_arg);
480         next_event = GENIE_EVT_NONE;
481     }
482     break;
483     case GENIE_EVT_SDK_HB_SET:
484     {
485         next_event = _genie_event_handle_hb_set((mesh_hb_para_t *)p_arg);
486     }
487     break;
488 #ifdef CONFIG_BT_MESH_CTRL_RELAY
489     case GENIE_EVT_SDK_CTRL_RELAY_SET:
490     {
491         next_event = _genie_event_handle_ctrl_relay_set((mesh_ctrl_relay_para_t *)p_arg);
492     }
493     break;
494 #endif
495     case GENIE_EVT_SDK_SEQ_UPDATE:
496     {
497         next_event = _genie_event_handle_seq_update();
498     }
499     break;
500     case GENIE_EVT_VENDOR_MODEL_MSG:
501     {
502         next_event = _genie_event_handle_vnd_msg((genie_transport_model_param_t *)p_arg);
503     }
504     break;
505 #ifdef MESH_MODEL_VENDOR_TIMER
506     case GENIE_EVT_TIMEOUT:
507     {
508         next_event = genie_model_notify_onoff_msg((vendor_attr_data_t *)p_arg);
509     }
510     break;
511 #endif
512     default:
513     {
514         next_event = GENIE_EVT_NONE;
515     }
516     break;
517     }
518 
519     if (!ignore_user_event)
520     {
521         p_context->event_cb(event, p_arg);
522     }
523 
524 #ifdef CONFIG_GENIE_MESH_AT_CMD
525     genie_at_output_event(event, p_arg);
526 #endif
527 
528 #ifdef CONIFG_GENIE_MESH_BINARY_CMD
529     genie_bin_cmd_handle_event(event, p_arg);
530 #endif
531 
532     if (next_event != GENIE_EVT_NONE)
533     {
534         genie_event(next_event, p_arg);
535     }
536 }
537