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