1 /*
2 * Copyright (C) 2019-2020 Alibaba Group Holding Limited
3 */
4
5 #include "common/log.h"
6
7 #include <stdio.h>
8 #include <string.h>
9 #include <ctype.h>
10 // #include <aos/aos.h>
11 #include <aos/kernel.h>
12
13 // #include <misc/printk.h>
14 // #include <misc/byteorder.h>
15 // #include <aos/hal/gpio.h>
16 // #include <aos/hal/pwm.h>
17
18 // #include <bluetooth.h>
19 // #include <soc.h>
20
21 #include <api/mesh.h>
22 #include "genie_service.h"
23 #include "light.h"
24 #include "light_driver.h"
25
26 static light_param_t light_param;
27 static sig_model_element_state_t light_elem_stat[ELEMENT_NUM];
28 static sig_model_powerup_t light_powerup[ELEMENT_NUM];
29
30 #ifdef CONFIG_BT_MESH_CFG_CLI
31 static struct bt_mesh_cfg_cli cfg_cli = {};
32 #endif
33
34 static struct bt_mesh_model primary_element[] = {
35 MESH_MODEL_CFG_SRV_NULL(),
36 MESH_MODEL_HEALTH_SRV_NULL(),
37 #ifdef CONFIG_BT_MESH_CFG_CLI
38 BT_MESH_MODEL_CFG_CLI(&cfg_cli),
39 #endif
40 MESH_MODEL_GEN_ONOFF_SRV(&light_elem_stat[0]),
41 MESH_MODEL_LIGHTNESS_SRV(&light_elem_stat[0]),
42 MESH_MODEL_CTL_SRV(&light_elem_stat[0]),
43 MESH_MODEL_SCENE_SRV(&light_elem_stat[0]),
44 };
45
46 static struct bt_mesh_model primary_vendor_element[] = {
47 MESH_MODEL_VENDOR_SRV(&light_elem_stat[0]),
48 };
49
50 struct bt_mesh_elem light_elements[] = {
51 BT_MESH_ELEM(0, primary_element, primary_vendor_element, GENIE_ADDR_LIGHT),
52 };
53
54 #ifdef CONFIG_GENIE_OTA
genie_sal_ota_is_allow_reboot(void)55 bool genie_sal_ota_is_allow_reboot(void)
56 {
57 // the device will reboot when it is off
58 if (light_elem_stat[0].state.onoff[TYPE_PRESENT] == 0) {
59 // save light para, always off
60 light_powerup[0].last_onoff = 0;
61 genie_storage_write_userdata(GFI_MESH_POWERUP, (uint8_t *)light_powerup, sizeof(light_powerup));
62 LIGHT_DBG("Allow to reboot!");
63
64 return true;
65 }
66
67 LIGHT_DBG("light is no so no reboot!");
68
69 return false;
70 }
71 #endif
72
_mesh_delay_timer_cb(void * p_timer,void * p_arg)73 static void _mesh_delay_timer_cb(void *p_timer, void *p_arg)
74 {
75 sig_model_element_state_t *p_elem = (sig_model_element_state_t *)p_arg;
76
77 #ifdef CONFIG_MESH_MODEL_TRANS
78 sig_model_transition_timer_stop(p_elem);
79 #endif
80 sig_model_event(SIG_MODEL_EVT_DELAY_END, p_arg);
81 }
82
83 #ifdef CONFIG_MESH_MODEL_TRANS
_mesh_trans_timer_cycle(void * p_timer,void * p_arg)84 static void _mesh_trans_timer_cycle(void *p_timer, void *p_arg)
85 {
86 sig_model_element_state_t *p_elem = (sig_model_element_state_t *)p_arg;
87 sig_model_state_t *p_state = &p_elem->state;
88
89 sig_model_transition_timer_stop(p_elem);
90
91 // do cycle
92 sig_model_event(SIG_MODEL_EVT_TRANS_CYCLE, p_arg);
93 // BT_DBG(">>>>>%d %d", (u32_t)cur_time, (u32_t)p_elem->state.trans_end_time);
94
95 if (p_state->trans == 0) {
96 sig_model_event(SIG_MODEL_EVT_TRANS_END, p_arg);
97 } else {
98 k_timer_start(&p_state->trans_timer, SIG_MODEL_TRANSITION_INTERVAL);
99 }
100 }
101 #endif
102
light_elem_state_init(void)103 void light_elem_state_init(void)
104 {
105 uint8_t index = 0;
106 genie_storage_status_e ret;
107
108 memset(light_elem_stat, 0, sizeof(light_elem_stat));
109
110 // load light param
111 ret = genie_storage_read_userdata(GFI_MESH_POWERUP, (uint8_t *)light_powerup, sizeof(light_powerup));
112 for (index = 0; index < ELEMENT_NUM; index++) {
113 light_elem_stat[index].element_id = index;
114
115 if (ret == GENIE_STORAGE_SUCCESS) {
116 // Use saved data
117 memcpy(&light_elem_stat[index].powerup, &light_powerup[index], sizeof(sig_model_powerup_t));
118 } else {
119 // Use default value
120 #ifdef CONFIG_MESH_MODEL_GEN_ONOFF_SRV
121 light_elem_stat[index].powerup.last_onoff = GEN_ONOFF_DEFAULT;
122 #endif
123 #ifdef CONFIG_MESH_MODEL_LIGHTNESS_SRV
124 light_elem_stat[index].powerup.last_lightness = LIGHTNESS_DEFAULT;
125 #endif
126 #ifdef CONFIG_MESH_MODEL_CTL_SRV
127 light_elem_stat[index].powerup.last_color_temperature = COLOR_TEMPERATURE_DEFAULT;
128 #endif
129 #ifdef CONFIG_MESH_MODEL_SCENE_SRV
130 light_elem_stat[index].powerup.last_scene = SCENE_DEFAULT;
131 #endif
132 }
133
134 #ifdef CONFIG_MESH_MODEL_GEN_ONOFF_SRV
135 light_elem_stat[index].state.onoff[TYPE_PRESENT] = 0;
136 light_elem_stat[index].state.onoff[TYPE_TARGET] = light_elem_stat[index].powerup.last_onoff;
137 #endif
138 #ifdef CONFIG_MESH_MODEL_LIGHTNESS_SRV
139 light_elem_stat[index].state.lightness[TYPE_PRESENT] = 0;
140 light_elem_stat[index].state.lightness[TYPE_TARGET] = light_elem_stat[index].powerup.last_lightness;
141 #endif
142 #ifdef CONFIG_MESH_MODEL_CTL_SRV
143 light_elem_stat[index].state.color_temperature[TYPE_PRESENT] = COLOR_TEMPERATURE_MIN;
144 light_elem_stat[index].state.color_temperature[TYPE_TARGET] =
145 light_elem_stat[index].powerup.last_color_temperature;
146 #endif
147 #ifdef CONFIG_MESH_MODEL_SCENE_SRV
148 light_elem_stat[index].state.scene[TYPE_PRESENT] = GENIE_SCENE_NORMAL;
149 light_elem_stat[index].state.scene[TYPE_TARGET] = light_elem_stat[index].powerup.last_scene;
150 #endif
151
152 #ifdef CONFIG_MESH_MODEL_TRANS
153 k_timer_init(&light_elem_stat[index].state.delay_timer, _mesh_delay_timer_cb, &light_elem_stat[index]);
154 k_timer_init(&light_elem_stat[index].state.trans_timer, _mesh_trans_timer_cycle, &light_elem_stat[index]);
155
156 light_elem_stat[index].state.trans = TRANSITION_DEFAULT_VALUE;
157 light_elem_stat[index].state.delay = DELAY_DEFAULT_VAULE;
158 if (light_elem_stat[index].state.trans) {
159 light_elem_stat[index].state.trans_start_time =
160 k_uptime_get() + light_elem_stat[index].state.delay * DELAY_TIME_UNIT;
161 light_elem_stat[index].state.trans_end_time =
162 light_elem_stat[index].state.trans_start_time +
163 sig_model_transition_get_transition_time(light_elem_stat[index].state.trans);
164 }
165
166 #ifdef CONFIG_MESH_MODEL_GEN_ONOFF_SRV
167 if (light_elem_stat[index].state.onoff[TYPE_TARGET] == 1) {
168 // light on
169 sig_model_event(SIG_MODEL_EVT_DELAY_START, &light_elem_stat[index]);
170 }
171 #endif
172 #else // No CONFIG_MESH_MODEL_TRANS
173 #ifdef CONFIG_MESH_MODEL_GEN_ONOFF_SRV
174 light_elem_stat[index].state.onoff[TYPE_PRESENT] = light_elem_stat[index].state.onoff[TYPE_TARGET];
175 if (light_elem_stat[index].state.onoff[TYPE_TARGET] == 1) {
176 // light on
177 // light_driver_update(1, light_elem_stat[index].state.lightness[TYPE_TARGET], light_elem_stat[index].state.color_temperature[TYPE_TARGET]);
178 }
179 #endif
180 #ifdef CONFIG_MESH_MODEL_LIGHTNESS_SRV
181 light_elem_stat[index].state.lightness[TYPE_PRESENT] = light_elem_stat[index].state.lightness[TYPE_TARGET];
182 #endif
183 #ifdef CONFIG_MESH_MODEL_CTL_SRV
184 light_elem_stat[index].state.color_temperature[TYPE_PRESENT] =
185 light_elem_stat[index].state.color_temperature[TYPE_TARGET];
186 #endif
187 #ifdef CONFIG_MESH_MODEL_SCENE_SRV
188 light_elem_stat[index].state.scene[TYPE_PRESENT] = light_elem_stat[index].state.scene[TYPE_TARGET];
189 #endif
190 #endif
191 }
192 }
193
194 #ifdef MESH_MODEL_VENDOR_TIMER
light_ctl_handle_order_msg(vendor_attr_data_t * attr_data)195 static void light_ctl_handle_order_msg(vendor_attr_data_t *attr_data)
196 {
197 GENIE_LOG_INFO("type:%04x data:%04x\r\n", attr_data->type, attr_data->para);
198
199 if (attr_data->type == ATTR_TYPE_GENERIC_ONOFF) {
200 #ifdef CONFIG_MESH_MODEL_GEN_ONOFF_SRV
201 light_elem_stat[0].state.onoff[TYPE_TARGET] = attr_data->para;
202
203 if (light_elem_stat[0].state.onoff[TYPE_PRESENT] != light_elem_stat[0].state.onoff[TYPE_TARGET]) {
204 sig_model_event(SIG_MODEL_EVT_DELAY_START, &light_elem_stat[0]);
205 }
206 #endif
207 }
208 }
209 #endif
210
light_param_reset(void)211 static void light_param_reset(void)
212 {
213 genie_storage_delete_userdata(GFI_MESH_POWERUP);
214 }
215
light_save_state(sig_model_element_state_t * p_elem)216 static void light_save_state(sig_model_element_state_t *p_elem)
217 {
218 uint8_t *p_read = NULL;
219
220 if (p_elem->state.lightness[TYPE_PRESENT] != 0) {
221 p_elem->powerup.last_lightness = p_elem->state.lightness[TYPE_PRESENT];
222 light_powerup[p_elem->element_id].last_lightness = p_elem->state.lightness[TYPE_PRESENT];
223 }
224
225 p_elem->powerup.last_color_temperature = p_elem->state.color_temperature[TYPE_PRESENT];
226 light_powerup[p_elem->element_id].last_color_temperature = p_elem->state.color_temperature[TYPE_PRESENT];
227 // always on
228 p_elem->powerup.last_onoff = p_elem->state.onoff[TYPE_PRESENT];
229 light_powerup[p_elem->element_id].last_onoff = p_elem->state.onoff[TYPE_PRESENT];
230
231 p_read = aos_malloc(sizeof(light_powerup));
232 if (!p_read) {
233 GENIE_LOG_WARN("no mem");
234 return;
235 }
236
237 genie_storage_read_userdata(GFI_MESH_POWERUP, p_read, sizeof(light_powerup));
238
239 if (memcmp(light_powerup, p_read, sizeof(light_powerup))) {
240 LIGHT_DBG("save %d %d %d", light_powerup[0].last_onoff, light_powerup[0].last_lightness,
241 light_powerup[0].last_color_temperature);
242 genie_storage_write_userdata(GFI_MESH_POWERUP, (uint8_t *)light_powerup, sizeof(light_powerup));
243 }
244
245 aos_free(p_read);
246 #ifdef CONFIG_GENIE_OTA
247 if (light_powerup[0].last_onoff == 0 && genie_ota_is_ready() == 1) {
248 // Means have ota, wait for reboot while light off
249 GENIE_LOG_INFO("reboot by ota");
250 aos_reboot();
251 }
252 #endif
253 }
254
light_update(sig_model_element_state_t * p_elem)255 static void light_update(sig_model_element_state_t *p_elem)
256 {
257 static uint8_t last_onoff = 0;
258 static uint16_t last_lightness = 0;
259 static uint16_t last_temperature = 0;
260
261 uint8_t onoff = p_elem->state.onoff[TYPE_PRESENT];
262 uint16_t lightness = p_elem->state.lightness[TYPE_PRESENT];
263 uint16_t temperature = p_elem->state.color_temperature[TYPE_PRESENT];
264
265 if (last_onoff != onoff || last_lightness != lightness || last_temperature != temperature) {
266 last_onoff = onoff;
267 last_lightness = lightness;
268 last_temperature = temperature;
269 // LIGHT_DBG("%d,%d,%d", onoff, lightness, temperature);
270 // light_driver_update(onoff, lightness, temperature);
271 }
272 }
273
_cal_flash_next_step(uint32_t delta_time)274 void _cal_flash_next_step(uint32_t delta_time)
275 {
276 uint16_t lightness_end;
277
278 if (delta_time < 1000) {
279 lightness_end = light_param.target_lightness;
280 light_param.present_color_temperature = light_param.target_color_temperature;
281 } else {
282 lightness_end = light_param.lightness_start;
283 delta_time %= 1000;
284 }
285
286 if (delta_time > LED_BLINK_ON_TIME) {
287 delta_time -= LED_BLINK_ON_TIME;
288 light_param.present_lightness = light_param.lightness_start * delta_time / LED_BLINK_OFF_TIME;
289 } else {
290 light_param.present_lightness = lightness_end * (LED_BLINK_ON_TIME - delta_time) / LED_BLINK_ON_TIME;
291 }
292 // LIGHT_DBG("delta %d, lightness %04x", delta_time, light_param.present_lightness);
293 }
294
_led_blink_timer_cb(void * p_timer,void * p_arg)295 static void _led_blink_timer_cb(void *p_timer, void *p_arg)
296 {
297 uint32_t cur_time = k_uptime_get();
298
299 if (cur_time >= light_param.color_temperature_end) {
300 // light_driver_update(1, light_param.target_lightness, light_param.target_color_temperature);
301 } else {
302 _cal_flash_next_step(light_param.color_temperature_end - cur_time);
303 // light_driver_update(1, light_param.present_lightness, light_param.present_color_temperature);
304 k_timer_start(&light_param.led_blink_timer, SIG_MODEL_TRANSITION_INTERVAL);
305 }
306 }
307
light_led_blink(uint8_t times,uint8_t reset)308 static void light_led_blink(uint8_t times, uint8_t reset)
309 {
310 if (light_elem_stat[0].state.onoff[TYPE_PRESENT] == 1) {
311 if (light_elem_stat[0].state.lightness[TYPE_PRESENT]) {
312 light_param.lightness_start = light_param.present_lightness =
313 light_elem_stat[0].state.lightness[TYPE_PRESENT];
314 } else {
315 light_param.lightness_start = light_param.present_lightness = LIGHTNESS_DEFAULT;
316 }
317
318 if (light_elem_stat[0].state.color_temperature[TYPE_PRESENT]) {
319 light_param.present_color_temperature = light_elem_stat[0].state.color_temperature[TYPE_PRESENT];
320 } else {
321 light_param.present_color_temperature = COLOR_TEMPERATURE_DEFAULT;
322 }
323
324 if (reset) {
325 light_param.target_lightness = LIGHTNESS_DEFAULT;
326 light_param.target_color_temperature = COLOR_TEMPERATURE_DEFAULT;
327 } else {
328 light_param.target_lightness = light_param.present_lightness;
329 light_param.target_color_temperature = light_param.present_color_temperature;
330 }
331
332 light_param.color_temperature_end = k_uptime_get() + times * LED_BLINK_PERIOD;
333 } else {
334 if (light_elem_stat[0].powerup.last_lightness && !reset) {
335 light_param.lightness_start = light_param.target_lightness = light_elem_stat[0].powerup.last_lightness;
336 } else {
337 light_param.lightness_start = light_param.target_lightness = LIGHTNESS_DEFAULT;
338 }
339
340 light_param.present_lightness = 0;
341 if (light_elem_stat[0].powerup.last_color_temperature) {
342 light_param.present_color_temperature = light_elem_stat[0].powerup.last_color_temperature;
343 } else {
344 light_param.present_color_temperature = COLOR_TEMPERATURE_DEFAULT;
345 }
346
347 if (reset) {
348 light_param.target_color_temperature = COLOR_TEMPERATURE_DEFAULT;
349 } else {
350 light_param.target_color_temperature = light_param.present_color_temperature;
351 }
352
353 light_param.color_temperature_end = k_uptime_get() + times * LED_BLINK_PERIOD - LED_BLINK_OFF_TIME;
354 }
355 // LIGHT_DBG("%d (%d-%d) tar %04x", times, k_uptime_get(), light_param.color_temperature_end, light_param.target_lightness);
356
357 k_timer_start(&light_param.led_blink_timer, SIG_MODEL_TRANSITION_INTERVAL);
358 }
359
light_report_poweron_state(sig_model_element_state_t * p_elem)360 static void light_report_poweron_state(sig_model_element_state_t *p_elem)
361 {
362 uint16_t index = 0;
363 uint8_t payload[20];
364 genie_transport_payload_param_t transport_payload_param;
365
366 #ifdef CONFIG_MESH_MODEL_GEN_ONOFF_SRV
367 payload[index++] = ATTR_TYPE_GENERIC_ONOFF & 0xff;
368 payload[index++] = (ATTR_TYPE_GENERIC_ONOFF >> 8) & 0xff;
369 payload[index++] = p_elem->state.onoff[TYPE_TARGET];
370 #endif
371 #ifdef CONFIG_MESH_MODEL_LIGHTNESS_SRV
372 payload[index++] = ATTR_TYPE_LIGHTNESS & 0xff;
373 payload[index++] = (ATTR_TYPE_LIGHTNESS >> 8) & 0xff;
374 payload[index++] = p_elem->state.lightness[TYPE_TARGET] & 0xff;
375 payload[index++] = (p_elem->state.lightness[TYPE_TARGET] >> 8) & 0xff;
376 #endif
377 #ifdef CONFIG_MESH_MODEL_CTL_SRV
378 payload[index++] = ATTR_TYPE_COLOR_TEMPERATURE & 0xff;
379 payload[index++] = (ATTR_TYPE_COLOR_TEMPERATURE >> 8) & 0xff;
380 payload[index++] = p_elem->state.color_temperature[TYPE_TARGET] & 0xff;
381 payload[index++] = (p_elem->state.color_temperature[TYPE_TARGET] >> 8) & 0xff;
382 #endif
383 #ifdef CONFIG_MESH_MODEL_SCENE_SRV
384 payload[index++] = ATTR_TYPE_SENCE & 0xff;
385 payload[index++] = (ATTR_TYPE_SENCE >> 8) & 0xff;
386 payload[index++] = p_elem->state.scene[TYPE_TARGET] & 0xff;
387 payload[index++] = (p_elem->state.scene[TYPE_TARGET] >> 8) & 0xff;
388 #endif
389
390 memset(&transport_payload_param, 0, sizeof(genie_transport_payload_param_t));
391 transport_payload_param.opid = VENDOR_OP_ATTR_INDICATE;
392 transport_payload_param.p_payload = payload;
393 transport_payload_param.payload_len = index;
394 transport_payload_param.retry_cnt = GENIE_TRANSPORT_DEFAULT_RETRY_COUNT;
395
396 genie_transport_send_payload(&transport_payload_param);
397 }
398
light_ctl_event_handler(genie_event_e event,void * p_arg)399 static void light_ctl_event_handler(genie_event_e event, void *p_arg)
400 {
401 switch (event) {
402 case GENIE_EVT_SW_RESET: {
403 light_param_reset();
404 // light_led_blink(3, 1);
405 } break;
406 case GENIE_EVT_MESH_READY: {
407 // User can report data to cloud at here
408 GENIE_LOG_INFO("User report data\n");
409 light_report_poweron_state(&light_elem_stat[0]);
410 } break;
411 case GENIE_EVT_SDK_MESH_PROV_SUCCESS: {
412 GENIE_LOG_INFO("Mesh Prov success\n");
413 light_blink();
414 // light_led_blink(3, 0);
415 } break;
416 #ifdef CONFIG_MESH_MODEL_TRANS
417 case GENIE_EVT_USER_TRANS_CYCLE:
418 #endif
419 case GENIE_EVT_USER_ACTION_DONE: {
420 sig_model_element_state_t *p_elem = (sig_model_element_state_t *)p_arg;
421 light_update(p_elem);
422 if (event == GENIE_EVT_USER_ACTION_DONE) {
423 light_save_state(p_elem);
424 }
425 } break;
426 case GENIE_EVT_SIG_MODEL_MSG: {
427 sig_model_msg *p_msg = (sig_model_msg *)p_arg;
428
429 if (p_msg) {
430 GENIE_LOG_INFO("SIG mesg ElemID(%d) in %s\n", p_msg->element_id, __func__);
431 if (p_msg->opcode == 0x8202) {
432 if (p_msg->data[0] == 0x00) {
433 light_set(0);
434 GENIE_LOG_INFO("rec SIG mesg: turn off cmd in ElemID(%d)\n", p_msg->element_id);
435 } else if (p_msg->data[0] == 0x01) {
436 light_set(1);
437 GENIE_LOG_INFO("rec SIG mesg: turn on cmd in ElemID(%d)\n", p_msg->element_id);
438 }
439 }
440 }
441 } break;
442 case GENIE_EVT_VENDOR_MODEL_MSG: {
443 genie_transport_model_param_t *p_msg = (genie_transport_model_param_t *)p_arg;
444
445 if (p_msg && p_msg->p_model && p_msg->p_model->user_data) {
446 sig_model_element_state_t *p_elem_state = (sig_model_element_state_t *)p_msg->p_model->user_data;
447 GENIE_LOG_INFO("ElemID(%d) TID(%02X)\n", p_elem_state->element_id, p_msg->tid);
448 (void)p_elem_state;
449 }
450 } break;
451 #ifdef CONIFG_GENIE_MESH_USER_CMD
452 case GENIE_EVT_DOWN_MSG: {
453 genie_down_msg_t *p_msg = (genie_down_msg_t *)p_arg;
454 // User handle this msg,such as send to MCU
455 // if (p_msg) {
456 // }
457 } break;
458 #endif
459 #ifdef MESH_MODEL_VENDOR_TIMER
460 case GENIE_EVT_TIMEOUT: {
461 vendor_attr_data_t *pdata = (vendor_attr_data_t *)p_arg;
462 // User handle vendor timeout event at here
463 if (pdata) {
464 light_ctl_handle_order_msg(pdata);
465 }
466 } break;
467 #endif
468 default:
469 break;
470 }
471 }
472
473 #ifdef CONFIG_PM_SLEEP
light_ctl_lpm_cb(genie_lpm_wakeup_reason_e reason,genie_lpm_status_e status,void * args)474 static void light_ctl_lpm_cb(genie_lpm_wakeup_reason_e reason, genie_lpm_status_e status, void *args)
475 {
476 if (status == STATUS_WAKEUP) {
477 GENIE_LOG_INFO("wakeup by %s", (reason == WAKEUP_BY_IO) ? "io" : "timer");
478 } else {
479 GENIE_LOG_INFO("sleep");
480 }
481 }
482 #endif
483
light_init(void)484 static void light_init(void)
485 {
486 light_driver_init();
487 light_set(0);
488 light_elem_state_init();
489 k_timer_init(&light_param.led_blink_timer, _led_blink_timer_cb, NULL);
490 }
491
application_start(int argc,char ** argv)492 int application_start(int argc, char **argv)
493 {
494 genie_service_ctx_t context;
495
496 aos_set_log_level(LOG_INFO);
497
498 GENIE_LOG_INFO("BTIME:%s\n", __DATE__ "," __TIME__);
499 printf("enter %s:%d\n", __func__, __LINE__);
500
501 light_init();
502
503 memset(&context, 0, sizeof(genie_service_ctx_t));
504 context.prov_timeout = MESH_PBADV_TIME;
505 context.event_cb = light_ctl_event_handler;
506 context.p_mesh_elem = light_elements;
507 context.mesh_elem_counts = sizeof(light_elements) / sizeof(struct bt_mesh_elem);
508
509 #ifdef CONFIG_PM_SLEEP
510 context.lpm_conf.is_auto_enable = 1;
511 context.lpm_conf.lpm_wakeup_io = 14;
512
513 context.lpm_conf.genie_lpm_cb = light_ctl_lpm_cb;
514
515 // User can config sleep time and wakeup time when not config GLP
516 context.lpm_conf.sleep_ms = 1000;
517 context.lpm_conf.wakeup_ms = 30;
518 #endif
519
520 genie_service_init(&context);
521
522 #ifdef CONFIG_BT_MESH_SHELL
523 extern void cli_reg_cmd_blemesh(void);
524 cli_reg_cmd_blemesh();
525 #endif
526
527 // aos_loop_run();
528
529 return 0;
530 }
531