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