1 /*
2  * Copyright (C) 2018-2020 Alibaba Group Holding Limited
3  */
4 #include <stdio.h>
5 #include <string.h>
6 #include <ctype.h>
7 //#include <aos/aos.h>
8 #include <aos/kernel.h>
9 
10 #include <misc/printk.h>
11 //#include <hal/hal.h>
12 #include <ble_os.h>
13 #include <bluetooth/bluetooth.h>
14 #include <api/mesh.h>
15 
16 #include "net.h"
17 //#include "transport.h"
18 #include "genie_service.h"
19 
20 #define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_MESH_DEBUG_MODEL)
21 #include "common/log.h"
22 
23 static struct bt_mesh_prov genie_mesh_provision;
24 static struct bt_mesh_comp genie_composition;
25 static aos_timer_t do_mesh_ready_timer;
26 
27 uint8_t g_mesh_log_mode = 1;
28 
genie_mesh_get_primary_element(void)29 struct bt_mesh_elem *genie_mesh_get_primary_element(void)
30 {
31     return genie_composition.elem;
32 }
33 
genie_mesh_load_group_addr(void)34 void genie_mesh_load_group_addr(void)
35 {
36     if (genie_storage_read_sub(g_sub_list) == GENIE_STORAGE_SUCCESS)
37     {
38         BT_INFO("g_sub_list %s", bt_hex(g_sub_list, sizeof(g_sub_list)));
39     }
40 }
41 
report_poweron_callback(transport_result_e result)42 static int report_poweron_callback(transport_result_e result)
43 {
44 #ifdef CONFIG_PM_SLEEP
45     genie_lpm_start();
46 #endif
47     return 0;
48 }
49 
genie_mesh_report_poweron(void)50 static int genie_mesh_report_poweron(void)
51 {
52     uint8_t payload[3];
53     genie_transport_payload_param_t transport_payload_param;
54 
55     payload[0] = ATTR_TYPE_DEVICE_EVENT & 0xFF;
56     payload[1] = (ATTR_TYPE_DEVICE_EVENT >> 8) & 0xFF;
57     payload[2] = EL_DEV_UP_T;
58 
59     memset(&transport_payload_param, 0, sizeof(genie_transport_payload_param_t));
60     transport_payload_param.opid = VENDOR_OP_ATTR_INDICATE;
61     transport_payload_param.p_payload = payload;
62     transport_payload_param.payload_len = sizeof(payload);
63     transport_payload_param.retry_cnt = GENIE_TRANSPORT_DEFAULT_RETRY_COUNT;
64     transport_payload_param.result_cb = report_poweron_callback;
65 
66     return genie_transport_send_payload(&transport_payload_param);
67 }
68 
genie_mesh_init_pharse_ii(void)69 int genie_mesh_init_pharse_ii(void)
70 {
71 #ifdef CONFIG_GENIE_OTA
72     genie_ota_init();
73 #endif
74 
75 #ifdef MESH_MODEL_VENDOR_TIMER
76     genie_time_init();
77 #endif
78 
79     genie_mesh_report_poweron();
80 
81 #if defined(CONFIG_BT_MESH_CTRL_RELAY) && !defined(CONFIG_PM_SLEEP)
82     /* check ctrl relay */
83     extern uint8_t genie_ctrl_relay_conf_set(mesh_ctrl_relay_para_t * p_para);
84     mesh_ctrl_relay_para_t cr_para;
85     genie_storage_status_e cr_ret = GENIE_STORAGE_SUCCESS;
86     memset(&cr_para, 0, sizeof(mesh_ctrl_relay_para_t));
87     cr_ret = genie_storage_read_ctrl_relay(&cr_para);
88     if (cr_ret == GENIE_STORAGE_SUCCESS)
89     {
90         GENIE_LOG_INFO("proved, use save ctrl relay config");
91         genie_ctrl_relay_conf_set(&cr_para);
92     }
93     else
94     {
95         GENIE_LOG_INFO("proved, use default ctrl relay config");
96         genie_ctrl_relay_conf_set(NULL);
97     }
98 #endif
99     return 0;
100 }
101 
do_mesh_ready_timer_cb(void * p_timer,void * args)102 static void do_mesh_ready_timer_cb(void *p_timer, void *args)
103 {
104     char mesh_init_state = *(char *)args;
105 
106     GENIE_LOG_INFO("mesh init state:%d\n", mesh_init_state);
107     if (mesh_init_state == GENIE_MESH_INIT_STATE_PROVISION)
108     {
109         if (genie_provision_get_state() != GENIE_PROVISION_SUCCESS)
110         {
111             GENIE_LOG_INFO("wait app key timeout");
112             genie_event(GENIE_EVT_SDK_MESH_PROV_TIMEOUT, NULL);
113 
114             return;
115         }
116     }
117     else if (mesh_init_state == GENIE_MESH_INIT_STATE_HW_RESET)
118     {
119         return genie_event(GENIE_EVT_HW_RESET_START, NULL);
120     }
121 
122     genie_event(GENIE_EVT_MESH_READY, NULL);
123 }
124 
genie_mesh_ready_checktimer_restart(uint32_t timeout)125 void genie_mesh_ready_checktimer_restart(uint32_t timeout)
126 {
127     aos_timer_stop(&do_mesh_ready_timer);
128     aos_timer_change_once(&do_mesh_ready_timer, timeout);
129     aos_timer_start(&do_mesh_ready_timer);
130 }
131 
mesh_provision_complete(u16_t net_idx,u16_t addr)132 static void mesh_provision_complete(u16_t net_idx, u16_t addr)
133 {
134     uint8_t rand;
135     uint16_t random_time;
136     static char mesh_init_state = 0; //1:now is provision 2:hw reset 3:normal boot
137 
138     //This time is in provision
139     if (genie_provision_get_state() != GENIE_PROVISION_UNPROV)
140     {
141         GENIE_LOG_INFO("is in prov");
142         mesh_init_state = GENIE_MESH_INIT_STATE_PROVISION;
143         aos_timer_new(&do_mesh_ready_timer, do_mesh_ready_timer_cb, &mesh_init_state, GENIE_MESH_INIT_PHARSE_II_CHECK_APPKEY_TIMEOUT, 0);
144     }
145     else
146     {
147         if (genie_reset_get_hw_reset_flag())
148         {
149             GENIE_LOG_INFO("hw reset");
150             mesh_init_state = GENIE_MESH_INIT_STATE_HW_RESET;
151             aos_timer_new(&do_mesh_ready_timer, do_mesh_ready_timer_cb, &mesh_init_state, GENIE_MESH_INIT_PHARSE_II_HW_RESET_DELAY, 0);
152         }
153         else
154         {
155             bt_rand(&rand, 1);
156 
157             //Random range[GENIE_MESH_INIT_PHARSE_II_DELAY_START_MIN-GENIE_MESH_INIT_PHARSE_II_DELAY_START_MAX]
158             random_time = GENIE_MESH_INIT_PHARSE_II_DELAY_START_MIN + (GENIE_MESH_INIT_PHARSE_II_DELAY_START_MAX - GENIE_MESH_INIT_PHARSE_II_DELAY_START_MIN) * rand / 255;
159 
160             GENIE_LOG_INFO("Rand delay:%dms", random_time);
161             aos_timer_new(&do_mesh_ready_timer, do_mesh_ready_timer_cb, &mesh_init_state, random_time, 0);
162         }
163     }
164 
165 #ifdef CONFIG_BT_MESH_SHELL
166     extern void genie_prov_complete_notify(u16_t net_idx, u16_t addr);
167     genie_prov_complete_notify(net_idx, addr);
168 #endif
169 }
170 
mesh_provision_reset(void)171 static void mesh_provision_reset(void)
172 {
173     BT_INFO("reset genie_mesh_provision");
174 
175 #ifdef MESH_MODEL_VENDOR_TIMER
176     genie_time_finalize();
177 #endif
178 }
179 
bt_ready_cb(int err)180 static void bt_ready_cb(int err)
181 {
182     if (err)
183     {
184         BT_ERR("BT init err %d", err);
185         return;
186     }
187 #if 0
188     k_work_init(&genie_mesh_work, do_genie_mesh_work);
189 #endif
190 
191     BT_INFO(">>>Mesh initialized<<<");
192     err = bt_mesh_init(&genie_mesh_provision, &genie_composition, NULL);
193     if (err)
194     {
195         BT_ERR("mesh init err %d", err);
196         return;
197     }
198 #ifdef CONFIG_GENIE_MESH_PORT
199     extern int genie_mesh_port_init(void);
200     genie_mesh_port_init();
201 #endif
202     //send event
203     genie_event(GENIE_EVT_BT_READY, NULL);
204 }
205 
genie_mesh_init(struct bt_mesh_elem * p_mesh_elem,unsigned int mesh_elem_counts)206 int genie_mesh_init(struct bt_mesh_elem *p_mesh_elem, unsigned int mesh_elem_counts)
207 {
208     int ret;
209     uint8_t random[16] = {0};
210 
211     BT_INFO(">>>init genie<<<");
212 
213     genie_mesh_provision.uuid = genie_provision_get_uuid();
214 
215     genie_mesh_provision.static_val = genie_crypto_get_auth(random);
216     genie_mesh_provision.static_val_len = STATIC_OOB_LENGTH;
217 
218     genie_mesh_provision.complete = mesh_provision_complete;
219     genie_mesh_provision.reset = mesh_provision_reset;
220 
221     genie_composition.cid = CONFIG_MESH_VENDOR_COMPANY_ID;
222     genie_composition.pid = 0;
223     genie_composition.vid = 1; // firmware version for ota
224     genie_composition.elem = p_mesh_elem;
225     genie_composition.elem_count = mesh_elem_counts;
226     genie_sal_ble_init();
227     ret = bt_enable(NULL);
228     //BT_INFO("the return of bt_enable is %d\n", ret);
229     bt_ready_cb(ret);
230     return ret;
231 }
232 
genie_mesh_suspend(bool force)233 int genie_mesh_suspend(bool force)
234 {
235     BT_INFO("[%u]%s, force:%d", k_uptime_get_32(), __func__, force);
236     return bt_mesh_suspend(force);
237 }
238 
genie_mesh_resume(void)239 int genie_mesh_resume(void)
240 {
241     BT_INFO("[%u]%s", k_uptime_get_32(), __func__);
242     return bt_mesh_resume();
243 }
244