1 /*
2 * Copyright (c) 2021 Chipsea Technologies (Shenzhen) Corp., Ltd. All rights reserved.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #ifdef CFG_BT_STACK
16 #ifdef CFG_BLE_ONLY
17 #include "cs_target_config.h"
18 #include <string.h>
19 #include "al_rtos.h"
20 #include "flash_api.h"
21 #include "ble_task_msg.h"
22 #if (PLF_CONSOLE)
23 #include "console.h"
24 #include "ble_task.h"
25 #endif // (PLF_CONSOLE)
26 #include "sleep_api.h"
27 #include "app_ble_only.h"
28
29
30
31 uint8_t bt_addr[6] = {
32 0xaa,0xc0,0x00,0x88,0x88,0x33
33 };
34 uint8_t ble_addr[6] = {
35 0xaa,0xc0,0x00,0x45,0x56,0x67
36 };
37 #if (BLE_APP_SMARTCONFIG)
38 #define APP_DFLT_DEVICE_NAME ("BLE_SMARTCONFIG")
39 #elif (BLE_APP_HID)
40 #define APP_DFLT_DEVICE_NAME ("CS_BLE_HID")
41 #else
42 #define APP_DFLT_DEVICE_NAME ("CS_BLE")
43 #endif
44 #define APP_DFLT_DEVICE_NAME_LEN (sizeof(APP_DFLT_DEVICE_NAME))
45
46 #if (BLE_APP_HID)
47 static const uint8_t adv_data_uuid[] = {
48 03, GAP_AD_TYPE_COMPLETE_LIST_16_BIT_UUID,
49 ATT_SVC_HID & 0xFF,
50 ATT_SVC_HID >> 8,
51 };
52 #endif //(BLE_APP_HID)
53
54 static const uint8_t adv_data_appeareance[] = {
55 03, GAP_AD_TYPE_APPEARANCE,
56 #if (BLE_APP_HID)
57 GAPC_APPEARANCE_HID_MOUSE & 0xFF,
58 GAPC_APPEARANCE_HID_MOUSE >> 8,
59 #else
60 GAPC_APPEARANCE_UNKNOWN & 0xFF,
61 GAPC_APPEARANCE_UNKNOWN >> 8,
62 #endif //(BLE_APP_HID)
63 };
64
65
66
67 static struct gapm_adv_create_param adv_param;
68 static uint8_t adv_data[ADV_DATA_LEN];
69
70 typedef void (*app_add_svc_func_t)(void);
71 /// List of service to add in the database
72 enum app_svc_list
73 {
74 #if (BLE_APP_BATT)
75 APP_SVC_BATT,
76 #endif //(BLE_APP_BATT)
77 #if (BLE_APP_HID)
78 APP_SVC_HIDS,
79 #endif //(BLE_APP_HID)
80 #if (BLE_APP_SMARTCONFIG)
81 APP_SVC_SMARTCONFIG,
82 #endif //(BLE_APP_SMARTCONFIG)
83
84 APP_SVC_LIST_STOP,
85 };
86
87 /// List of functions used to create the database
88 static const app_add_svc_func_t app_add_svc_func_list[APP_SVC_LIST_STOP] =
89 {
90 #if (BLE_APP_BATT)
91 (app_add_svc_func_t)app_batt_add_bas,
92 #endif //(BLE_APP_BATT)
93 #if (BLE_APP_HID)
94 (app_add_svc_func_t)app_hid_add_hids,
95 #endif //(BLE_APP_HID)
96 #if (BLE_APP_SMARTCONFIG)
97 (app_add_svc_func_t)app_smartconfig_add_smartconfig,
98 #endif //(BLE_APP_SMARTCONFIG)
99 };
100
init_adv_params()101 static void init_adv_params()
102 {
103 memset(&adv_param, 0, sizeof(adv_param));
104 adv_param.type = GAPM_ADV_TYPE_LEGACY;
105 adv_param.disc_mode = GAPM_ADV_MODE_GEN_DISC;
106 adv_param.prop = GAPM_ADV_PROP_UNDIR_CONN_MASK;
107 adv_param.filter_pol = ADV_ALLOW_SCAN_ANY_CON_ANY;
108 adv_param.prim_cfg.chnl_map = APP_ADV_CHMAP;
109 adv_param.prim_cfg.phy = GAP_PHY_LE_1MBPS;
110 adv_param.prim_cfg.adv_intv_min = APP_ADV_INT_MIN;
111 adv_param.prim_cfg.adv_intv_max = APP_ADV_INT_MAX;
112 }
113
build_adv_data()114 static uint8_t build_adv_data()
115 {
116 uint8_t i = 0;
117 uint8_t *buf = &adv_data[0];
118 uint8_t len = 0;
119
120 #if (BLE_APP_HID)
121 len = sizeof(adv_data_uuid);
122 memcpy(&buf[i], adv_data_uuid, len);
123 i += len;
124 #endif
125
126 len = sizeof(adv_data_appeareance);
127 memcpy(&buf[i], adv_data_appeareance, len);
128 i += len;
129
130 buf[i] = APP_DFLT_DEVICE_NAME_LEN + 1;
131 buf[i + 1] = GAP_AD_TYPE_COMPLETE_NAME;
132 memcpy(buf + i + 2, APP_DFLT_DEVICE_NAME, APP_DFLT_DEVICE_NAME_LEN);
133 i += APP_DFLT_DEVICE_NAME_LEN + 2;
134
135 return i;
136 }
137
138 #if (PLF_CONSOLE)
139
app_ble_scan_stop(int argc,char * argv[])140 static int app_ble_scan_stop(int argc, char *argv[])
141 {
142 dbg("%s\r\n", __func__);
143 app_ble_scan_msg_stop();
144 return ERR_NONE;
145 }
146
app_ble_scan_start(int argc,char * argv[])147 static int app_ble_scan_start(int argc, char *argv[])
148 {
149 dbg("%s\r\n", __func__);
150 app_ble_scan_msg_start();
151 return ERR_NONE;
152 }
153
app_ble_adv_data_update(int argc,char * argv[])154 static int app_ble_adv_data_update(int argc, char *argv[])
155 {
156 app_ble_adv_data_update_msg_send();
157 return ERR_NONE;
158 }
159
app_ble_adv_param_update(int argc,char * argv[])160 static int app_ble_adv_param_update(int argc, char *argv[])
161 {
162 app_ble_adv_param_update_msg_send();
163
164 return ERR_NONE;
165 }
166
app_ble_adv_stop(int argc,char * argv[])167 static int app_ble_adv_stop(int argc, char *argv[])
168 {
169 dbg("%s\r\n", __func__);
170 app_ble_adv_stop_msg_send();
171 return ERR_NONE;
172 }
173
app_ble_adv_start(int argc,char * argv[])174 static int app_ble_adv_start(int argc, char *argv[])
175 {
176 dbg("%s\r\n", __func__);
177 app_ble_adv_start_msg_send();
178 return ERR_NONE;
179 }
180
app_ble_discon(int argc,char * argv[])181 static int app_ble_discon(int argc, char *argv[])
182 {
183 dbg("%s\r\n", __func__);
184 app_ble_disconnect_msg_send();
185 return ERR_NONE;
186 }
187
app_ble_con_param_update(int argc,char * argv[])188 static int app_ble_con_param_update(int argc, char *argv[])
189 {
190 app_ble_con_param_msg_send();
191 return ERR_NONE;
192 }
193
app_ble_onoff_control(int argc,char * argv[])194 static int app_ble_onoff_control(int argc, char *argv[])
195 {
196 unsigned int on_off;
197
198 if (argc < 2) {
199 return ERR_WRONG_ARGS;
200 }
201
202 on_off = console_cmd_strtoul(argv[1], NULL, 10);
203 if (on_off > 1) {
204 return ERR_WRONG_ARGS;
205 }
206
207 if(on_off){
208 ble_task_init();
209 }else{
210 ble_task_deinit();
211 }
212
213 return ERR_NONE;
214 }
215
216 #if (BLE_APP_BATT)
app_batt_set(int argc,char * argv[])217 static int app_batt_set(int argc, char *argv[])
218 {
219 uint8_t data = app_batt_get_lvl();
220 dbg("%s set %d\r\n", __func__, data);
221 app_batt_send_lvl(data);
222 return ERR_NONE;
223 }
224 #endif // (BLE_APP_BATT)
225
app_ble_user_sleep(int argc,char * argv[])226 static int app_ble_user_sleep(int argc, char *argv[])
227 {
228 unsigned int sleep;
229
230 if (argc < 2) {
231 return ERR_WRONG_ARGS;
232 }
233
234 sleep = console_cmd_strtoul(argv[1], NULL, 10);
235 if (sleep > 1) {
236 return ERR_WRONG_ARGS;
237 }
238
239 if (sleep) {
240 user_sleep_allow(1);
241 } else {
242 user_sleep_allow(0);
243 }
244 return ERR_NONE;
245 }
246
app_ble_sleep_level(int argc,char * argv[])247 static int app_ble_sleep_level(int argc, char *argv[])
248 {
249 unsigned int level;
250
251 if (argc < 2) {
252 return ERR_WRONG_ARGS;
253 }
254
255 if(*argv[1] == '?') {
256 dbg("%d\n", sleep_level_get());
257 return ERR_NONE;
258 }
259
260 level = console_cmd_strtoul(argv[1], NULL, 10);
261 if (level >= PM_LEVEL_LEVEL_NUM) {
262 return ERR_WRONG_ARGS;
263 }
264
265 sleep_level_set(level);
266
267 return ERR_NONE;
268 }
269
app_ble_user_wakeup_source(int argc,char * argv[])270 static int app_ble_user_wakeup_source(int argc, char *argv[])
271 {
272 int src, en, arg = 0;
273
274 if (argc < 3) {
275 return ERR_WRONG_ARGS;
276 }
277
278 src = console_cmd_strtoul(argv[1], NULL, 10);
279 if (src >= WAKESRC_NUM_MAX) {
280 return ERR_WRONG_ARGS;
281 }
282 en = console_cmd_strtoul(argv[2], NULL, 10);
283 if (src == WAKESRC_TIMER) {
284 if (argc < 4) {
285 return ERR_WRONG_ARGS;
286 }
287 arg = console_cmd_strtoul(argv[3], NULL, 10);
288 }
289
290 user_sleep_wakesrc_set(src, en, arg);
291
292 return ERR_NONE;
293 }
294
app_ble_del_bond(int argc,char * argv[])295 static int app_ble_del_bond(int argc, char *argv[])
296 {
297 dbg("%s \r\n", __func__);
298 app_ble_del_bond_msg_send();
299 return ERR_NONE;
300 }
301
app_ble_enable_dut(int argc,char * argv[])302 static int app_ble_enable_dut(int argc, char *argv[])
303 {
304 app_ble_enter_dut_msg_send();
305 return ERR_NONE;
306 }
307
app_ble_scan_en(int argc,char * argv[])308 static int app_ble_scan_en(int argc, char *argv[])
309 {
310 unsigned int scan_en;
311 unsigned int dut = 0;
312
313 if (argc < 2) {
314 return ERR_WRONG_ARGS;
315 }
316
317 scan_en = console_cmd_strtoul(argv[1], NULL, 0);
318 if (scan_en > 0x03) {
319 return ERR_WRONG_ARGS;
320 }
321 dut = console_cmd_strtoul(argv[2], NULL, 10);
322 TRACE("scan_en %d,dut %d\n",scan_en,dut);
323 app_ble_wr_scan_en(scan_en);
324
325 return ERR_NONE;
326 }
327
app_ble_addr_rdwr(int argc,char * argv[])328 static int app_ble_addr_rdwr(int argc, char *argv[])
329 {
330 if ((argc < 2) || ((strlen(argv[1]) == 1) && (argv[1][0] == '?'))) { // read
331 struct bd_addr user_addr;
332 if (flash_btdm_le_rand_addr_read(&user_addr.addr[0]) == INFO_READ_DONE) {
333 memcpy(&ble_addr[0], &user_addr.addr[0], BD_ADDR_LEN);
334 } else {
335 dbg("no ble addr in flash, use default\r\n");
336 }
337 dbg("read ble addr: %02x%02x%02x%02x%02x%02x\r\n",
338 ble_addr[0], ble_addr[1], ble_addr[2], ble_addr[3], ble_addr[4], ble_addr[5]);
339 } else { // write
340 char str0[8 + 1];
341 char *str1;
342 unsigned char addr[6];
343 uint32_t addr0, addr1;
344 if (strlen(argv[1]) != 12) {
345 return -1;
346 }
347 str1 = &argv[1][0];
348 memcpy(str0, &argv[1][4], 8);
349 str0[8] = '\0';
350 str1[4] = '\0';
351 addr0 = console_cmd_strtoul(str0, NULL, 16);
352 addr1 = console_cmd_strtoul(str1, NULL, 16) & 0x0000ffff;
353 addr[0] = (unsigned char)(addr1 >> 8);
354 addr[1] = (unsigned char)(addr1 >> 0);
355 addr[2] = (unsigned char)(addr0 >> 24);
356 addr[3] = (unsigned char)(addr0 >> 16);
357 addr[4] = (unsigned char)(addr0 >> 8);
358 addr[5] = (unsigned char)(addr0 >> 0);
359 memcpy(&ble_addr[0], &addr[0], BD_ADDR_LEN);
360 flash_btdm_le_rand_addr_write(addr);
361 dbg("write ble addr: %04x%08x\r\n", addr1, addr0);
362 }
363 return 0;
364 }
365
app_ble_test_command_add(void)366 void app_ble_test_command_add(void)
367 {
368 console_cmd_add("ble_scan_stop", " ble_scan_stop", 1, app_ble_scan_stop);
369 console_cmd_add("ble_scan_start", " ble_scan_start", 1, app_ble_scan_start);
370 console_cmd_add("ble_adv_data", " ble adv data update", 1, app_ble_adv_data_update);
371 console_cmd_add("ble_adv_param", " ble adv param update", 1, app_ble_adv_param_update);
372 console_cmd_add("ble_adv_stop", " ble adv stop", 1, app_ble_adv_stop);
373 console_cmd_add("ble_adv_start", " ble adv start", 1, app_ble_adv_start);
374 console_cmd_add("ble_discon", " ble disconnet", 1, app_ble_discon);
375 console_cmd_add("ble_con_param", " ble con param update", 1, app_ble_con_param_update);
376 console_cmd_add("ble_on", " ble_on/off", 2, app_ble_onoff_control);
377 #if (BLE_APP_BATT)
378 console_cmd_add("batt_set", " batt set", 1, app_batt_set);
379 #endif // (BLE_APP_BATT)
380 console_cmd_add("ble_del_bond", " ble delete bond", 2, app_ble_del_bond);
381 console_cmd_add("ble_usrslp", " Allow user sleep", 2, app_ble_user_sleep);
382 console_cmd_add("ble_slplvl", " Set system sleep level", 2, app_ble_sleep_level);
383 console_cmd_add("ble_usrwusrc", " Set user wakeup source", 4, app_ble_user_wakeup_source);
384 console_cmd_add("ble_addr", " rdwr ble addr", 2, app_ble_addr_rdwr);
385 console_cmd_add("dut", " dut :enter dut", 1, app_ble_enable_dut);
386 console_cmd_add("scan_en", " scan_en <scan_type> <is_dut>", 3, app_ble_scan_en);
387 }
388 #endif // (PLF_CONSOLE)
389
ble_user_app_init_cb()390 void ble_user_app_init_cb()
391 {
392 #if (BLE_APP_SEC)
393 // Security Module
394 app_sec_init();
395 #endif // (BLE_APP_SEC)
396
397 #if (BLE_APP_HID)
398 // HID Module
399 app_hid_init();
400 #endif //(BLE_APP_HID)
401
402 #if (BLE_APP_BATT)
403 // Battery Module
404 app_batt_init();
405 #endif //(BLE_APP_BATT)
406
407 #if (BLE_APP_SMARTCONFIG)
408 // Smart Config Module
409 app_smartconfig_init();
410 #endif //(BLE_APP_SMARTVOICE)
411
412 }
413
ble_user_app_init_complete_cb()414 void ble_user_app_init_complete_cb()
415 {
416 dbg("!!!!!!!!!!!@@@@@@@@@@@@@@@@@\n");
417 }
418
ble_user_add_svc_cb()419 bool ble_user_add_svc_cb()
420 {
421 // Indicate if more services need to be added in the database
422 bool more_svc = false;
423
424 // Check if another should be added in the database
425 if (app_env.next_svc != APP_SVC_LIST_STOP)
426 {
427 ASSERT_INFO(app_add_svc_func_list[app_env.next_svc] != NULL, app_env.next_svc, 1);
428
429 // Call the function used to add the required service
430 app_add_svc_func_list[app_env.next_svc]();
431
432 // Select following service to add
433 app_env.next_svc++;
434 more_svc = true;
435 }
436
437 return more_svc;
438
439 }
440
ble_user_enable_prf_cb(uint8_t conidx)441 void ble_user_enable_prf_cb(uint8_t conidx)
442 {
443 #if (BLE_APP_BATT)
444 // Enable Battery Service
445 app_batt_enable_prf(conidx);
446 #endif //(BLE_APP_BATT)
447
448 #if (BLE_APP_HID)
449 // Enable HID Service
450 app_hid_enable_prf(conidx);
451 #endif //(BLE_APP_HID)
452
453 #if (BLE_APP_SMARTCONFIG)
454 app_smartconfig_enable_prf(conidx);
455 #endif //(BLE_APP_SMARTCONFIG)
456 }
457
ble_app_connection_cb(uint8_t conidx,struct gapc_connection_req_ind const * param)458 void ble_app_connection_cb(uint8_t conidx, struct gapc_connection_req_ind const *param)
459 {
460 user_sleep_allow(0);
461 dbg("%s connect %d\r\n", __func__, conidx);
462 }
463
ble_app_disconnect_cb(struct gapc_disconnect_ind const * param)464 void ble_app_disconnect_cb(struct gapc_disconnect_ind const *param)
465 {
466 dbg("%s disconnect %d %d\r\n", __func__, param->conhdl, param->reason);
467 #if (BLE_APP_HID)
468 app_hid_stop_timer();
469 // Restart Advertising
470 if (app_env.del_bond) {
471 app_env.del_bond = false;
472 appm_delete_advertising();
473 } else {
474 app_ble_start_adv();
475 }
476 user_sleep_allow(1);
477 #endif //(BLE_APP_HID)
478
479 #if BLE_APP_SMARTCONFIG
480 app_smartconfig_disconnected();
481 #endif
482 }
483
ble_app_update_con_params_cb(struct gapc_param_update_req_ind const * param)484 void ble_app_update_con_params_cb(struct gapc_param_update_req_ind const *param)
485 {
486 dbg("%s con param update %d %d\r\n", __func__, param->intv_max, param->time_out);
487
488 }
489
ble_app_adv_stop_cb(struct gapm_activity_stopped_ind * param)490 void ble_app_adv_stop_cb(struct gapm_activity_stopped_ind *param)
491 {
492 dbg("%s con param update reason %d\r\n", __func__, param->reason);
493 }
494
ble_app_adv_status_cb(struct gapm_cmp_evt const * param)495 void ble_app_adv_status_cb(struct gapm_cmp_evt const *param)
496 {
497 dbg("%s operation %d, status %d\r\n", __func__, param->operation, param->status);
498 }
499
500 static struct app_callbacks ble_app_callbacks = {
501 .app_on_init = ble_user_app_init_cb,
502 .app_on_init_complete = ble_user_app_init_complete_cb,
503 .app_on_add_svc = ble_user_add_svc_cb,
504 .app_on_enable_prf = ble_user_enable_prf_cb,
505 .app_on_connection = ble_app_connection_cb,
506 .app_on_disconnect = ble_app_disconnect_cb,
507 .app_on_update_params_request = ble_app_update_con_params_cb,
508 .app_on_adv_status = ble_app_adv_status_cb,
509 };
510
app_ble_init(void)511 void app_ble_init(void)
512 {
513 struct bd_addr user_addr = {
514 0xaa,0xc0,0x00,0x45,0x56,0x67
515 };
516 #if FPGA == 0
517 bt_factory_info_t bt_factory_info;
518 if(flash_btdm_bt_factory_read((void *)&bt_factory_info,sizeof(bt_factory_info_t)) == INFO_READ_DONE){
519 memcpy(bt_addr , bt_factory_info.local_bt_addr ,6);
520 memcpy(ble_addr , bt_factory_info.local_ble_addr ,6);
521 }
522 #endif
523 #if (PLF_CONSOLE)
524 app_ble_test_command_add();
525 #endif // (PLF_CONSOLE)
526
527 if (flash_btdm_le_rand_addr_read(&user_addr.addr[0])) {
528 dbg("addr error, use default addr\r\n");
529 } else {
530 memcpy(&ble_addr[0], &user_addr.addr[0], BD_ADDR_LEN);
531 flash_btdm_le_rand_addr_write(ble_addr);
532 }
533 app_ble_env_init();
534 app_ble_register_callbak(&ble_app_callbacks);
535 app_ble_addr_init(ble_addr, GAPM_STATIC_ADDR);
536 app_ble_set_dev_name(APP_DFLT_DEVICE_NAME, APP_DFLT_DEVICE_NAME_LEN);
537 app_ble_set_adv_data(adv_data, build_adv_data());
538 init_adv_params();
539 if (app_ble_set_adv_params(&adv_param, 0))
540 {
541 TRACE("params error\r\n");
542 }
543 TRACE("app_ble_init\n");
544 }
545 #endif
546 #endif
547