1
2 #include <stdint.h>
3
4 #include "genie_service.h"
5 #include "genie_sal_ble.h"
6 #include "genie_sal_uart.h"
7
8 static uint8_t g_rssi_mac[GENIE_BLE_MAC_LEN];
9
genie_bin_cmds_send(uint16_t opcode,uint8_t * p_data,uint16_t len)10 static void genie_bin_cmds_send(uint16_t opcode, uint8_t *p_data, uint16_t len)
11 {
12 uint8_t checksum = 0;
13
14 genie_sal_uart_send_one_byte(opcode >> 8);
15 genie_sal_uart_send_one_byte(opcode & 0xff);
16 genie_sal_uart_send_one_byte(len >> 8);
17 genie_sal_uart_send_one_byte(len & 0xff);
18
19 checksum += len >> 8;
20 checksum += (len & 0xff);
21
22 while (len--)
23 {
24 checksum += *p_data;
25 genie_sal_uart_send_one_byte(*p_data++);
26 }
27
28 genie_sal_uart_send_one_byte(checksum);
29 }
30
genie_bin_cmds_error(uint8_t err_code)31 static void genie_bin_cmds_error(uint8_t err_code)
32 {
33 uint8_t code = err_code;
34
35 genie_bin_cmds_send(GENIE_BIN_OPCODE_ERR, &code, 1);
36 }
37
mesh_adv_ctl(uint8_t ctl,uint8_t * resp)38 static uint16_t mesh_adv_ctl(uint8_t ctl, uint8_t *resp)
39 {
40 resp[0] = 0x01;
41 resp[1] = ctl;
42
43 switch (ctl)
44 {
45 case 0x00:
46 {
47 bt_mesh_adv_stop();
48 bt_mesh_prov_disable(BT_MESH_PROV_GATT | BT_MESH_PROV_ADV);
49 }
50 break;
51 case 0x01:
52 {
53 bt_mesh_adv_stop();
54 bt_mesh_prov_enable(BT_MESH_PROV_GATT | BT_MESH_PROV_ADV);
55 genie_event(GENIE_EVT_SDK_MESH_PBADV_START, NULL);
56 }
57 break;
58 case 0x02:
59 {
60 genie_event(GENIE_EVT_SDK_MESH_PBADV_TIMEOUT, NULL);
61 }
62 break;
63 default:
64 break;
65 }
66 return 2;
67 }
68
reset_prov_info(uint8_t * resp)69 static uint16_t reset_prov_info(uint8_t *resp)
70 {
71 resp[0] = 0x03;
72 resp[1] = 0x01;
73 resp[2] = 0x01;
74
75 genie_event(GENIE_EVT_HW_RESET_START, NULL);
76
77 return 3;
78 }
79
_send_rssi_msg(int8_t rssi)80 static void _send_rssi_msg(int8_t rssi)
81 {
82 uint8_t resp[9];
83
84 resp[0] = 0x03;
85 resp[1] = 0x02;
86 //get mac
87 memcpy(resp + 2, g_rssi_mac, GENIE_BLE_MAC_LEN);
88 //get rssi
89 resp[8] = rssi;
90
91 genie_bin_cmds_send(GENIE_BIN_OPCODE_CMD, resp, 9);
92 }
93
get_device_info(uint8_t type,uint8_t * resp)94 static uint16_t get_device_info(uint8_t type, uint8_t *resp)
95 {
96 switch (type)
97 {
98 case 0x00:
99 { //Get provision info
100 resp[0] = 0x03;
101 resp[1] = 0x03;
102 if (bt_mesh_is_provisioned())
103 {
104 resp[2] = 0x01;
105 }
106 else
107 {
108 resp[2] = 0x00;
109 }
110 return 3;
111 }
112 case 0x01:
113 { //Get device version
114 uint32_t app_version = genie_version_appver_get();
115
116 resp[0] = GENIE_CTL_DEVIE_INFO_AND_EVENT;
117 resp[1] = 0x06;
118 resp[2] = (uint8_t)(app_version >> 24);
119 resp[3] = (uint8_t)(app_version >> 16);
120 resp[4] = (uint8_t)(app_version >> 8);
121 resp[5] = (uint8_t)(app_version);
122
123 return 6;
124 }
125 default:
126 break;
127 }
128 return 0;
129 }
130
genie_bin_cmd_type_data(uint8_t * p_data)131 static void genie_bin_cmd_type_data(uint8_t *p_data)
132 {
133 uint16_t len = p_data[3] + (p_data[2] << 8);
134
135 if (genie_sal_ble_send_msg(0, &p_data[4], len))
136 {
137 genie_bin_cmds_error(GENIE_BINARY_CMD_TRANSPARENT_ERR);
138 }
139 }
140
get_ble_rssi_cb(uint8_t mac[6],int8_t rssi)141 static void get_ble_rssi_cb(uint8_t mac[6], int8_t rssi)
142 {
143 if (memcmp(g_rssi_mac, mac, GENIE_BLE_MAC_LEN) == 0)
144 {
145 _send_rssi_msg(rssi);
146 memset(g_rssi_mac, 0, GENIE_BLE_MAC_LEN);
147 }
148 else
149 {
150 genie_bin_cmds_error(GENIE_BINARY_CMD_GET_RSSI_MAC_NOT_MATCH_ERR);
151 }
152 }
153
genie_bin_cmd_update_group_addr(uint8_t * addr_list,int addr_len)154 static int genie_bin_cmd_update_group_addr(uint8_t *addr_list, int addr_len)
155 {
156 int index = 0;
157 uint8_t group_addr_list[CONFIG_BT_MESH_MODEL_GROUP_COUNT * 2] = {0};
158
159 if ((addr_len > CONFIG_BT_MESH_MODEL_GROUP_COUNT * 2) || ((addr_len % 2) != 0))
160 {
161 return -1;
162 }
163
164 memset(group_addr_list, 0, CONFIG_BT_MESH_MODEL_GROUP_COUNT * 2);
165 memcpy(group_addr_list, addr_list, addr_len);
166
167 for (index = 0; index < addr_len; index++)
168 {
169 if ((index % 2) == 0)
170 {
171 if ((group_addr_list[index + 1] & 0xC0) != 0xC0) //invalid group address
172 {
173 return -2;
174 }
175 }
176 }
177
178 /* set group addr */
179 if (genie_storage_write_sub((uint16_t *)group_addr_list) != GENIE_STORAGE_SUCCESS)
180 {
181 return -3;
182 }
183
184 /* get group addr */
185 if (genie_storage_read_sub((uint16_t *)g_sub_list) != GENIE_STORAGE_SUCCESS)
186 {
187 return -3;
188 }
189
190 return 0;
191 }
192
get_mesh_group_addr(uint8_t * response)193 static int get_mesh_group_addr(uint8_t *response)
194 {
195 int i = 0;
196 int j = 0;
197 uint8_t group_addr_list[CONFIG_BT_MESH_MODEL_GROUP_COUNT * 2] = {0};
198
199 /* get group addr */
200 if (genie_storage_read_sub((uint16_t *)group_addr_list) != GENIE_STORAGE_SUCCESS)
201 {
202 return -1;
203 }
204
205 for (i = 0; i < CONFIG_BT_MESH_MODEL_GROUP_COUNT * 2; i++)
206 {
207 if (i % 2 == 0)
208 {
209 if ((group_addr_list[i + 1] & 0xC0) == 0xC0) //valid group address
210 {
211 response[j] = group_addr_list[i];
212 response[j + 1] = group_addr_list[i + 1];
213 j += 2;
214 }
215 }
216 }
217
218 return j;
219 }
220
genie_bin_cmd_type_command(uint8_t * p_data)221 static void genie_bin_cmd_type_command(uint8_t *p_data)
222 {
223 uint8_t *p_u8 = p_data;
224 uint16_t len = p_u8[3] + (p_u8[2] << 8);
225
226 uint8_t resp[20];
227 uint16_t resp_len = 0;
228
229 switch (p_u8[4])
230 {
231 case GENIE_CTL_MESH_ADV:
232 if (len == 2)
233 {
234 resp_len = mesh_adv_ctl(p_u8[5], resp);
235 }
236 break;
237
238 case GENIE_CTL_CLEAR_PROV_INFO:
239 if (len == 1)
240 {
241 resp_len = reset_prov_info(resp);
242 }
243 break;
244
245 case GENIE_CTL_TEST_MODE:
246 if (len == 8)
247 {
248 if (p_u8[5] == 0x00)
249 {
250 memcpy(g_rssi_mac, &p_u8[6], GENIE_BLE_MAC_LEN); //backup mac addr
251 if (genie_sal_ble_get_rssi(g_rssi_mac, (genie_sal_ble_get_rssi_cb)get_ble_rssi_cb, 5000) < 0)
252 {
253 return genie_bin_cmds_error(GENIE_BINARY_CMD_GET_RSSI_BLE_ERR);
254 }
255 }
256 else
257 {
258 return genie_bin_cmds_error(GENIE_BINARY_CMD_GET_RSSI_INPUT_ERR);
259 }
260 }
261 else
262 {
263 return genie_bin_cmds_error(GENIE_BINARY_CMD_GET_RSSI_INPUT_ERR);
264 }
265 break;
266 case GENIE_CTL_DEVICE_INFO:
267 if (len == 2)
268 {
269 resp_len = get_device_info(p_u8[5], resp);
270 }
271 break;
272 case GENIE_CTL_REBOOT_DEVICE:
273 if (len == 1)
274 {
275 aos_reboot();
276 }
277 break;
278 case GENIE_CTL_UPDATE_GROUP_ADDR:
279 {
280 int ret = 0;
281
282 resp[0] = GENIE_CTL_UPDATE_GROUP_ADDR_RESPONSE;
283 ret = genie_bin_cmd_update_group_addr(&p_u8[5], len - 1);
284 if (0 == ret)
285 {
286 resp[1] = 0x00; //successful
287 resp_len = 2;
288 }
289 else if (-1 == ret)
290 {
291 return genie_bin_cmds_error(GENIE_BINARY_CMD_UPDATE_GROUP_ADDR_LEN_ERR);
292 }
293 else if (-2 == ret)
294 {
295 return genie_bin_cmds_error(GENIE_BINARY_CMD_UPDATE_GROUP_ADDR_INVALID_ERR);
296 }
297 else if (-3 == ret)
298 {
299 return genie_bin_cmds_error(GENIE_BINARY_CMD_UPDATE_GROUP_ADDR_FLASH_ERR);
300 }
301 }
302 break;
303 case GENIE_CTL_GET_GROUP_ADDR:
304 {
305 if (len == 1)
306 {
307 resp[0] = GENIE_CTL_GET_GOURP_ADDR_RESPONSE;
308 resp_len = get_mesh_group_addr(&resp[2]);
309 if (resp_len > 0) //Have valid group addr
310 {
311 resp[1] = 0x00;
312 resp_len += 2;
313 }
314 else //Have no valid group addr
315 {
316 resp[1] = 0x01;
317 resp_len = 2;
318 }
319 }
320 }
321 break;
322 case GENIE_CTL_FACTORY_TEST:
323 {
324 if (genie_sal_ble_set_factory_flag() != 0)
325 {
326 return genie_bin_cmds_error(GENIE_BINARY_CMD_START_FACTORY_ERR);
327 }
328 else
329 {
330 resp[0] = GENIE_CTL_FACTORY_TEST;
331 resp[1] = 0x00;
332 resp_len = 2;
333 genie_bin_cmds_send(GENIE_BIN_OPCODE_CMD, resp, resp_len);
334 aos_msleep(1000);
335 aos_reboot();
336 }
337 }
338 break;
339 case GENIE_CTL_SWITCH_DEBUG:
340 {
341 if (len == 2)
342 {
343 if (p_u8[5] > 0)
344 {
345 g_mesh_log_mode = 1;
346 aos_set_log_level(GENIE_MESH_DEFAULT_LOG_LEVEL);
347 }
348 else
349 {
350 g_mesh_log_mode = 0;
351 aos_set_log_level(LOG_EMERG);
352 }
353 resp[0] = GENIE_CTL_SWITCH_DEBUG;
354 resp[1] = 0x00;
355 resp_len = 2;
356 }
357 else
358 {
359 resp[0] = GENIE_CTL_SWITCH_DEBUG;
360 resp[1] = 0x01;
361 resp_len = 2;
362 }
363 }
364 break;
365 default:
366 break;
367 }
368
369 //if resp_len = 0 do nothing
370 if (resp_len > 0) //need response
371 {
372 genie_bin_cmds_send(GENIE_BIN_OPCODE_CMD, resp, resp_len);
373 }
374 else if (resp_len < 0)
375 {
376 genie_bin_cmds_error(GENIE_BINARY_CMD_UNKNOW_ERR);
377 }
378 }
379
genie_bin_cmds_handle(uint8_t * p_data,uint8_t data_len)380 int genie_bin_cmds_handle(uint8_t *p_data, uint8_t data_len)
381 {
382 uint16_t len = 0;
383 uint16_t index = 0;
384 uint8_t checksum = 0;
385
386 if ((data_len > 0) && (p_data[0] != 0xFF) && (p_data[0] != 0xFE))
387 {
388 return 0; //Don't send any data by UART
389 }
390
391 if (data_len < GENIE_BIN_MIN_DATA_LEN)
392 {
393 genie_bin_cmds_error(GENIE_BINARY_CMD_TOTAL_LEN_ERR);
394 return -1;
395 }
396
397 len = p_data[3] + (p_data[2] << 8);
398 if (len != (data_len - 5))
399 {
400 genie_bin_cmds_error(GENIE_BINARY_CMD_DATA_LEN_ERR);
401 return -1;
402 }
403
404 checksum += p_data[2];
405 checksum += p_data[3];
406
407 while (index < len)
408 {
409 checksum += p_data[4 + index];
410 index++;
411 }
412
413 if (checksum != p_data[data_len - 1])
414 {
415 genie_bin_cmds_error(GENIE_BINARY_CMD_CRC_ERR);
416 return -1;
417 }
418
419 if (((p_data[0] << 8) | p_data[1]) == GENIE_BIN_OPCODE_DATA)
420 {
421 genie_bin_cmd_type_data(p_data);
422 }
423 else if (((p_data[0] << 8) | p_data[1]) == GENIE_BIN_OPCODE_CMD)
424 {
425 genie_bin_cmd_type_command(p_data);
426 }
427
428 return 0;
429 }
430
genie_bin_cmd_handle_event(genie_event_e event,void * p_arg)431 int genie_bin_cmd_handle_event(genie_event_e event, void *p_arg)
432 {
433 uint8_t report_data[2];
434 uint8_t report_data_len = 0;
435
436 if (event == GENIE_EVT_MESH_READY)
437 {
438 report_data[0] = 0x03;
439 report_data[1] = 0x04;
440 report_data_len = 2;
441 }
442 else if (event == GENIE_EVT_SDK_MESH_PROV_SUCCESS)
443 {
444 report_data[0] = 0x03;
445 report_data[1] = 0x00;
446 report_data_len = 2;
447 }
448 else if (event == GENIE_EVT_SDK_MESH_PROV_FAIL)
449 {
450 report_data[0] = 0x03;
451 report_data[1] = 0x05;
452 report_data_len = 2;
453 }
454
455 if (report_data_len > 0)
456 {
457 genie_bin_cmds_send(GENIE_BIN_OPCODE_CMD, report_data, report_data_len);
458 }
459
460 return 0;
461 }
462
genie_bin_cmds_send_data_to_mcu(uint8_t * p_data,uint8_t len)463 void genie_bin_cmds_send_data_to_mcu(uint8_t *p_data, uint8_t len)
464 {
465 genie_bin_cmds_send(GENIE_BIN_OPCODE_DATA, p_data, len);
466 }
467