bsal_rtk.c 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990
  1. /*
  2. * Copyright (c) 2006-2020, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2020-05-28 Supperthomas the first version
  9. */
  10. #include <string.h>
  11. #include <stdio.h>
  12. #include "bsal.h"
  13. #include "bsal_osif.h"
  14. #include "bsal_int.h"
  15. #include "bsal_stack_api.h"
  16. #include "bsal_rtk.h"
  17. bsal_stack_obj_t rtk_obj;
  18. static void *bsal_get_rtk_obj()
  19. {
  20. return &rtk_obj;
  21. }
  22. //================================BSAL.C==========================
  23. static void bsal_rtk_stack_init(uint8_t stack_type)
  24. {
  25. #define APP_MAX_LINKS 1
  26. le_gap_init(APP_MAX_LINKS); //if changed must be removed from here
  27. /* Device name and device appearance */
  28. // uint16_t appearance = GAP_GATT_APPEARANCE_UNKNOWN;
  29. #ifdef SOC_RTL_8762D
  30. gap_lib_init();
  31. #endif
  32. le_register_app_cb(bsal_app_gap_callback);
  33. }
  34. static void bsal_rtk_stack_startup(void)
  35. {
  36. app_task_init();
  37. }
  38. static BSAL_STATUS bsal_rtk_le_adv_enable(bool enable)
  39. {
  40. if (enable == true)
  41. {
  42. le_adv_start();
  43. }
  44. else
  45. {
  46. le_adv_stop();
  47. }
  48. return BSAL_RESULT_SUCCESS;
  49. }
  50. //for app
  51. static BSAL_STATUS bsal_srv_profile_srv_begin(bool is_continue, uint8_t service_num, void *p_fnc_callback)
  52. {
  53. server_init(service_num);
  54. //get local obj,
  55. //register obj
  56. bsal_stack_obj_t *p_bsal_stack = bsal_get_rtk_obj();
  57. //add 0xffff
  58. p_bsal_stack->bsal_srv_objs = bsal_osif_malloc((service_num + 1) * sizeof(bsal_srv_callback_t));
  59. p_bsal_stack->srv_num = service_num + 1;
  60. //server_builtin_service_reg(true);
  61. //save the profile num;
  62. server_register_app_cb(bsal_app_profile_callback);
  63. bsal_uuid_any_t srv_uuid;
  64. srv_uuid.u_type = BSAL_UUID_TYPE_16BIT; //16bit
  65. srv_uuid.u16.value = 0xffff;//p_srv[i].uuid->u16.value;
  66. // add the generate uuid for except common profile
  67. bsal_profile_insert(p_bsal_stack, 0xffff, p_fnc_callback, srv_uuid);
  68. return BSAL_RESULT_SUCCESS;
  69. }
  70. //common utils
  71. static BSAL_STATUS bsal_srv_profile_reg_service(
  72. struct bsal_gatt_app_srv_def *p_srv,
  73. void *p_func //callback
  74. )
  75. {
  76. uint16_t att_num = 0;
  77. uint8_t att_index = 0;
  78. uint16_t sum_of_descript = 0;
  79. uint8_t write_index = 0;
  80. uint8_t i = 0;
  81. uint8_t j = 0;
  82. uint8_t x = 0;
  83. uint8_t y = 0;
  84. bsal_stack_obj_t *p_bsal_stack = bsal_get_rtk_obj();
  85. bsal_gatt_res_t res;
  86. bsal_util_sum_handle_num(p_srv, &res);
  87. att_num = res.attrs;
  88. T_ATTRIB_APPL *rtk_table = bsal_osif_malloc(sizeof(T_ATTRIB_APPL) * att_num);
  89. //primary service
  90. struct bsal_gatt_app_srv_def *tmp_srv;
  91. bsal_gatt_chr_def_t *tmp_chr;
  92. for (i = 0; p_srv[i].type != 0; i++)
  93. {
  94. //service
  95. tmp_srv = p_srv + i;
  96. if ((tmp_srv->type != BSAL_GATT_UUID_PRIMARY_SERVICE) &&
  97. (tmp_srv->type != BSAL_GATT_UUID_SECONDARY_SERVICE))
  98. {
  99. return BSAL_RESULT_FAIL;
  100. }
  101. // att_res->attrs++;
  102. // att_res->svcs++;
  103. if (tmp_srv->uuid->u_type == BSAL_UUID_TYPE_16BIT)
  104. {
  105. rtk_table[write_index].type_value[0] = LO_WORD(tmp_srv->type);
  106. rtk_table[write_index].type_value[1] = HI_WORD(tmp_srv->type);
  107. rtk_table[write_index].type_value[2] = LO_WORD(tmp_srv->uuid->u16.value);
  108. rtk_table[write_index].type_value[3] = HI_WORD(tmp_srv->uuid->u16.value);
  109. rtk_table[write_index].value_len = UUID_16BIT_SIZE;
  110. rtk_table[write_index].p_value_context = NULL;
  111. rtk_table[write_index].permissions = GATT_PERM_READ;
  112. rtk_table[write_index].flags = (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_LE);
  113. }
  114. else if (tmp_srv->uuid->u_type == BSAL_UUID_TYPE_128BIT)
  115. {
  116. rtk_table[write_index].type_value[0] = LO_WORD(BSAL_GATT_UUID_PRIMARY_SERVICE);
  117. rtk_table[write_index].type_value[1] = HI_WORD(BSAL_GATT_UUID_PRIMARY_SERVICE);
  118. rtk_table[write_index].p_value_context = tmp_srv->uuid->u128.value;
  119. rtk_table[write_index].value_len = UUID_128BIT_SIZE;
  120. rtk_table[write_index].permissions = GATT_PERM_READ;
  121. rtk_table[write_index].flags = (ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_LE);
  122. }
  123. write_index++;
  124. if (tmp_srv->includes != NULL)
  125. {
  126. for (j = 0; tmp_srv->includes[j] != NULL; j++)
  127. {
  128. // att_res->attrs++;
  129. // att_res->incs++;
  130. //add include /*TODO*/
  131. }
  132. }
  133. if (tmp_srv->characteristics != NULL)
  134. {
  135. for (x = 0; tmp_srv->characteristics[x].uuid != NULL; x++)
  136. {
  137. tmp_chr = tmp_srv->characteristics + x;
  138. if (tmp_chr->uuid->u_type == BSAL_UUID_TYPE_16BIT)
  139. {
  140. /* <<Characteristic>> declear */
  141. rtk_table[write_index].flags = (ATTRIB_FLAG_VALUE_INCL);
  142. rtk_table[write_index].type_value[0] = LO_WORD(GATT_UUID_CHARACTERISTIC);
  143. rtk_table[write_index].type_value[1] = HI_WORD(GATT_UUID_CHARACTERISTIC);
  144. rtk_table[write_index].type_value[2] = LO_WORD(tmp_chr->properties & 0xff);
  145. rtk_table[write_index].type_value[3] = HI_WORD(tmp_chr->properties >> 8);
  146. rtk_table[write_index].permissions = GATT_PERM_READ;
  147. rtk_table[write_index].value_len = tmp_chr->value_length;
  148. write_index++;
  149. /* <<Characteristic>> value */
  150. rtk_table[write_index].flags = ATTRIB_FLAG_VALUE_APPL;
  151. rtk_table[write_index].type_value[0] = LO_WORD(tmp_chr->uuid->u16.value);
  152. rtk_table[write_index].type_value[1] = HI_WORD(tmp_chr->uuid->u16.value);
  153. if (BSAL_GATT_PERM_GET_READ(tmp_srv->characteristics[x].permission) != 0) ///ENCRYTYED
  154. {
  155. /* TODO*/
  156. if (BSAL_GATT_GET_ENC_TYPE_AUTHEN_REQ(BSAL_GATT_PERM_GET_READ(tmp_srv->characteristics[x].permission)))
  157. {
  158. rtk_table[write_index].permissions |= GATT_PERM_READ_AUTHEN_REQ; //tmp_chr->permission;
  159. }
  160. else if (BSAL_GATT_GET_ENC_TYPE_AUTHOR_REQ(BSAL_GATT_PERM_GET_READ(tmp_srv->characteristics[x].permission)))
  161. {
  162. rtk_table[write_index].permissions |= GATT_PERM_READ_AUTHOR_REQ;
  163. }
  164. else
  165. {
  166. rtk_table[write_index].permissions |= GATT_PERM_READ;
  167. }
  168. }
  169. else
  170. {
  171. }
  172. //write
  173. if (BSAL_GATT_PERM_GET_WRITE(tmp_srv->characteristics[x].permission) != 0) ///ENCRYTYED
  174. {
  175. /* TODO*/
  176. if (BSAL_GATT_GET_ENC_TYPE_AUTHEN_REQ(BSAL_GATT_PERM_GET_WRITE(tmp_srv->characteristics[x].permission)))
  177. {
  178. rtk_table[write_index].permissions |= GATT_PERM_WRITE_AUTHEN_REQ; //tmp_chr->permission;
  179. }
  180. else if (BSAL_GATT_GET_ENC_TYPE_AUTHOR_REQ(BSAL_GATT_PERM_GET_WRITE(tmp_srv->characteristics[x].permission)))
  181. {
  182. rtk_table[write_index].permissions |= GATT_PERM_WRITE_AUTHOR_REQ;
  183. }
  184. else
  185. {
  186. rtk_table[write_index].permissions |= GATT_PERM_WRITE;
  187. }
  188. }
  189. //rtk_table[write_index].permissions = tmp_chr->permission;
  190. rtk_table[write_index].value_len = 0;
  191. write_index++;
  192. // att_res->chrs++;
  193. // att_res->attrs +=2;
  194. if ((tmp_chr->properties & BSAL_ATT_P_NOTIFY) ||
  195. (tmp_chr->properties & BSAL_ATT_P_INDICATE))
  196. {
  197. // att_res->dscs++;
  198. // att_res->cccds++;
  199. // att_res->attrs++;
  200. //ADD CCCD:
  201. rtk_table[write_index].flags = ATTRIB_FLAG_VALUE_INCL | ATTRIB_FLAG_CCCD_APPL;
  202. rtk_table[write_index].type_value[0] = LO_WORD(GATT_UUID_CHAR_CLIENT_CONFIG);
  203. rtk_table[write_index].type_value[1] = HI_WORD(GATT_UUID_CHAR_CLIENT_CONFIG);
  204. rtk_table[write_index].type_value[2] = LO_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT);
  205. rtk_table[write_index].type_value[3] = HI_WORD(GATT_CLIENT_CHAR_CONFIG_DEFAULT);
  206. #if SIMP_SRV_AUTHEN_EN
  207. rtk_table[write_index].permissions = (GATT_PERM_READ_AUTHEN_REQ | GATT_PERM_WRITE_AUTHEN_REQ); /* permissions */
  208. #else
  209. rtk_table[write_index].permissions = (GATT_PERM_READ | GATT_PERM_WRITE); /* permissions */
  210. #endif
  211. rtk_table[write_index].value_len = 2;
  212. }
  213. if (tmp_chr->descriptors != NULL)
  214. {
  215. for (y = 0; tmp_chr->descriptors[y].uuid != NULL; y++)
  216. {
  217. // att_res->dscs++;
  218. // att_res->attrs++;
  219. /*TODO*/
  220. }
  221. }
  222. }
  223. }
  224. }
  225. }
  226. T_SERVER_ID service_id;
  227. if (false == server_add_service(&service_id,
  228. (uint8_t *)rtk_table,
  229. sizeof(T_ATTRIB_APPL) * att_num,
  230. bsal_cbs))
  231. {
  232. APP_PRINT_ERROR1("bas_add_service: service_id %d", service_id);
  233. service_id = 0xff;
  234. }
  235. APP_PRINT_ERROR1(" bas_add_service: service_id %d", service_id);
  236. // bsal_srv_objs[service_id].bsal_srv_fn_cb = (P_BSAL_PROFILE_CB)p_func;
  237. // bsal_srv_objs[service_id].start_handle = 0;// RTK NO NEED
  238. //insert the profile service_id to start_handle
  239. uint16_t start_handle = 0;
  240. for (i = 0; p_srv[i].type != 0; i++)
  241. {
  242. bsal_uuid_any_t srv_uuid;
  243. srv_uuid.u_type = BSAL_UUID_TYPE_16BIT; //16bit
  244. srv_uuid.u16.value = p_srv[i].uuid->u16.value;
  245. tmp_srv = p_srv + i;
  246. p_bsal_stack->g_att_index ++;
  247. //save the service id with the start_handle;
  248. //rtk_save_service_id_with_start_handle(service_id, p_bsal_stack->g_att_index);
  249. start_handle = p_bsal_stack->g_att_index;
  250. bsal_profile_insert(bsal_get_rtk_obj(), service_id, p_func, srv_uuid);
  251. if (tmp_srv->characteristics != NULL)
  252. {
  253. for (x = 0; tmp_srv->characteristics[x].uuid != NULL; x++)
  254. {
  255. tmp_chr = tmp_srv->characteristics + x;
  256. p_bsal_stack->g_att_index ++;//declear
  257. p_bsal_stack->g_att_index ++;//value
  258. bsal_srv_create_att(bsal_get_rtk_obj(), service_id, (p_bsal_stack->g_att_index - start_handle) , tmp_chr->value_length);
  259. }
  260. }
  261. }
  262. return BSAL_RESULT_SUCCESS;
  263. }
  264. //FOR APP
  265. static BSAL_STATUS bsal_srv_profile_srv_end(void)
  266. {
  267. //all register service is end
  268. return BSAL_RESULT_SUCCESS;
  269. }
  270. static BSAL_STATUS bsal_stack_srv_send_data(uint16_t conn_id, uint16_t service_id, uint16_t offset_handle, uint16_t value_len, const uint8_t *value, uint8_t send_type)
  271. {
  272. if (server_send_data(conn_id, service_id, offset_handle, (uint8_t *)value, value_len, send_type))
  273. {
  274. return BSAL_RESULT_SUCCESS;
  275. }
  276. return BSAL_RESULT_FAIL;
  277. }
  278. static uint32_t bsal_stack_rtk_get_unique_handle(uint16_t start_id, uint16_t offset_handle)
  279. {
  280. return (start_id << 16) | offset_handle;
  281. }
  282. static void bsal_stack_rtk_set_bond_param(bsal_bond_param_t *bond_param)
  283. {
  284. uint8_t auth_pair_mode;
  285. uint16_t auth_flags;
  286. if (bond_param->bonding_flag == false)
  287. {
  288. //do nothing
  289. auth_pair_mode = GAP_PAIRING_MODE_NO_PAIRING;
  290. //no need check the other param
  291. gap_set_param(GAP_PARAM_BOND_PAIRING_MODE, sizeof(auth_pair_mode), &auth_pair_mode);
  292. return;
  293. }
  294. else
  295. {
  296. auth_pair_mode = GAP_PAIRING_MODE_PAIRABLE;
  297. gap_set_param(GAP_PARAM_BOND_PAIRING_MODE, sizeof(auth_pair_mode), &auth_pair_mode);
  298. }
  299. if (bond_param->force_auth_type != 0)
  300. {
  301. //force the
  302. auth_flags = bond_param->force_auth_type;
  303. }
  304. else
  305. {
  306. auth_flags = bond_param->auth_type;
  307. }
  308. gap_set_param(GAP_PARAM_BOND_AUTHEN_REQUIREMENTS_FLAGS, sizeof(auth_flags), &auth_flags);
  309. le_bond_set_param(GAP_PARAM_BOND_SEC_REQ_ENABLE, sizeof(bond_param->sm_req_enable), &bond_param->sm_req_enable);
  310. if (bond_param->sm_req_enable == true)
  311. {
  312. le_bond_set_param(GAP_PARAM_BOND_SEC_REQ_REQUIREMENT, sizeof(auth_flags),
  313. &auth_flags);
  314. }
  315. gap_set_param(GAP_PARAM_BOND_IO_CAPABILITIES, sizeof(bond_param->io_capability), &bond_param->io_capability);
  316. if (bond_param->fixed_key_flag == true)
  317. {
  318. le_bond_set_param(GAP_PARAM_BOND_FIXED_PASSKEY, sizeof(bond_param->fixed_key), &bond_param->fixed_key);
  319. le_bond_set_param(GAP_PARAM_BOND_FIXED_PASSKEY_ENABLE, sizeof(bond_param->fixed_key_flag),
  320. &bond_param->fixed_key_flag);
  321. }
  322. if (bond_param->oob_flag == true)
  323. {
  324. #if F_BT_LE_SMP_OOB_SUPPORT
  325. gap_set_param(GAP_PARAM_BOND_OOB_ENABLED, sizeof(bond_param->oob_flag), &bond_param->oob_flag);
  326. #endif
  327. }
  328. }
  329. static void bsal_rtk_le_set_adv_param(bsal_adv_param_t *adv_param)
  330. {
  331. if (adv_param->set_param_flag & BSAL_SET_LE_ADV_DATA)
  332. {
  333. APP_PRINT_INFO2("bsal_rtk_le_set_adv_param :%d, %x", adv_param->adv_data[0], *((uint8_t *)((uint32_t)(adv_param->adv_data) + 1)));
  334. le_adv_set_param(GAP_PARAM_ADV_DATA, adv_param->adv_data[0], (void *)((uint32_t)(adv_param->adv_data) + 1));
  335. }
  336. else if (adv_param->set_param_flag & BSAL_SET_LE_SCAN_RSP_DATA)
  337. {
  338. le_adv_set_param(GAP_PARAM_SCAN_RSP_DATA, adv_param->scan_rsp_data[0], (void *)((uint32_t)(adv_param->scan_rsp_data) + 1));
  339. }
  340. else if (adv_param->set_param_flag & BSAL_SET_LE_ADV_PARAM)
  341. {
  342. le_adv_set_param(GAP_PARAM_ADV_EVENT_TYPE, sizeof(adv_param->adv_type), &adv_param->adv_type);
  343. le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR_TYPE, sizeof(adv_param->direct_address_type), &adv_param->direct_address_type);
  344. le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR, sizeof(adv_param->direct_address), adv_param->direct_address);
  345. le_adv_set_param(GAP_PARAM_ADV_CHANNEL_MAP, sizeof(adv_param->channel_map), &adv_param->channel_map);
  346. le_adv_set_param(GAP_PARAM_ADV_FILTER_POLICY, sizeof(adv_param->filter_policy), &adv_param->filter_policy);
  347. le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MIN, sizeof(adv_param->adv_int_min), &adv_param->adv_int_min);
  348. le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MAX, sizeof(adv_param->adv_int_max), &adv_param->adv_int_max);
  349. }
  350. }
  351. static void bsal_rtk_set_gas_param(bsal_gaps_param_t *adv_param)
  352. {
  353. uint8_t slave_init_mtu_req = false;
  354. /* Advertising parameters */
  355. /* Set device name and device appearance */
  356. le_set_gap_param(GAP_PARAM_DEVICE_NAME, GAP_DEVICE_NAME_LEN, adv_param->name);
  357. le_set_gap_param(GAP_PARAM_APPEARANCE, sizeof(adv_param->apperance), &adv_param->apperance);
  358. le_set_gap_param(GAP_PARAM_SLAVE_INIT_GATT_MTU_REQ, sizeof(slave_init_mtu_req),
  359. &slave_init_mtu_req);
  360. }
  361. bsal_stack_obj_t rtk_obj =
  362. {
  363. .bsal_ops = {
  364. .init = bsal_rtk_stack_init,
  365. .startup = bsal_rtk_stack_startup,
  366. .le_adv_enable = bsal_rtk_le_adv_enable,
  367. .le_srv_reg_begin = bsal_srv_profile_srv_begin,
  368. .le_srv_reg_fun = bsal_srv_profile_reg_service,
  369. .le_srv_reg_end = bsal_srv_profile_srv_end,
  370. .le_srv_send_data = bsal_stack_srv_send_data,
  371. .cov_handle_to_u_handle = bsal_stack_rtk_get_unique_handle,
  372. .set_bond_param = bsal_stack_rtk_set_bond_param,
  373. .le_set_adv_param = bsal_rtk_le_set_adv_param,
  374. .set_gaps_param = bsal_rtk_set_gas_param,
  375. //callback
  376. },
  377. };
  378. /*TODO*/
  379. //register rtk object
  380. //=================================realtek source orignal codeAPP TASK========
  381. //REALTEK ENTER
  382. #ifndef SOC_RTL_8762D
  383. int bt_app_main(void)
  384. {
  385. bt_trace_set_switch(true); //need called befor bt_trace_init() //default close
  386. bt_trace_init();
  387. bte_init();
  388. bsal_bt_app_main();
  389. return 0;
  390. }
  391. #endif
  392. /** @defgroup PERIPH_APP Peripheral Application
  393. * @brief This file handles BLE peripheral application routines.
  394. * @{
  395. */
  396. /*============================================================================*
  397. * Variables
  398. *============================================================================*/
  399. /** @} */ /* End of group PERIPH_SEVER_CALLBACK */
  400. /** @defgroup PERIPH_GAP_MSG GAP Message Handler
  401. * @brief Handle GAP Message
  402. * @{
  403. */
  404. static T_GAP_DEV_STATE gap_dev_state = {0, 0, 0, 0}; /**< GAP device state */
  405. static T_GAP_CONN_STATE gap_conn_state = GAP_CONN_STATE_DISCONNECTED; /**< GAP connection state */
  406. /*============================================================================*
  407. * Functions
  408. *============================================================================*/
  409. void app_handle_gap_msg(T_IO_MSG *p_gap_msg);
  410. /**
  411. * @brief Handle msg GAP_MSG_LE_DEV_STATE_CHANGE
  412. * @note All the gap device state events are pre-handled in this function.
  413. * Then the event handling function shall be called according to the new_state
  414. * @param[in] new_state New gap device state
  415. * @param[in] cause GAP device state change cause
  416. * @return void
  417. */
  418. void app_handle_dev_state_evt(T_GAP_DEV_STATE new_state, uint16_t cause)
  419. {
  420. APP_PRINT_INFO3("app_handle_dev_state_evt: init state %d, adv state %d, cause 0x%x",
  421. new_state.gap_init_state, new_state.gap_adv_state, cause);
  422. if (gap_dev_state.gap_init_state != new_state.gap_init_state)
  423. {
  424. if (new_state.gap_init_state == GAP_INIT_STATE_STACK_READY)
  425. {
  426. APP_PRINT_INFO0("GAP stack ready");
  427. /*stack ready*/
  428. #ifdef BSAL_DEBUG
  429. le_adv_start();
  430. #else
  431. bsal_stack_ready(bsal_get_rtk_obj(), true);
  432. #endif
  433. }
  434. }
  435. if (gap_dev_state.gap_adv_state != new_state.gap_adv_state)
  436. {
  437. if (new_state.gap_adv_state == GAP_ADV_STATE_IDLE)
  438. {
  439. if (new_state.gap_adv_sub_state == GAP_ADV_TO_IDLE_CAUSE_CONN)
  440. {
  441. APP_PRINT_INFO0("GAP adv stoped: because connection created");
  442. }
  443. else
  444. {
  445. APP_PRINT_INFO0("GAP adv stoped");
  446. }
  447. }
  448. else if (new_state.gap_adv_state == GAP_ADV_STATE_ADVERTISING)
  449. {
  450. APP_PRINT_INFO0("GAP adv start");
  451. }
  452. }
  453. gap_dev_state = new_state;
  454. }
  455. /**
  456. * @brief Handle msg GAP_MSG_LE_CONN_STATE_CHANGE
  457. * @note All the gap conn state events are pre-handled in this function.
  458. * Then the event handling function shall be called according to the new_state
  459. * @param[in] conn_id Connection ID
  460. * @param[in] new_state New gap connection state
  461. * @param[in] disc_cause Use this cause when new_state is GAP_CONN_STATE_DISCONNECTED
  462. * @return void
  463. */
  464. void app_handle_conn_state_evt(uint8_t conn_id, T_GAP_CONN_STATE new_state, uint16_t disc_cause)
  465. {
  466. APP_PRINT_INFO4("app_handle_conn_state_evt: conn_id %d old_state %d new_state %d, disc_cause 0x%x",
  467. conn_id, gap_conn_state, new_state, disc_cause);
  468. switch (new_state)
  469. {
  470. case GAP_CONN_STATE_DISCONNECTED:
  471. {
  472. if ((disc_cause != (HCI_ERR | HCI_ERR_REMOTE_USER_TERMINATE))
  473. && (disc_cause != (HCI_ERR | HCI_ERR_LOCAL_HOST_TERMINATE)))
  474. {
  475. APP_PRINT_ERROR1("app_handle_conn_state_evt: connection lost cause 0x%x", disc_cause);
  476. }
  477. #ifdef BSAL_DEBUG
  478. le_adv_start();
  479. #else
  480. #endif
  481. }
  482. break;
  483. case GAP_CONN_STATE_CONNECTED:
  484. {
  485. uint16_t conn_interval;
  486. uint16_t conn_latency;
  487. uint16_t conn_supervision_timeout;
  488. uint8_t remote_bd[6];
  489. T_GAP_REMOTE_ADDR_TYPE remote_bd_type;
  490. le_get_conn_param(GAP_PARAM_CONN_INTERVAL, &conn_interval, conn_id);
  491. le_get_conn_param(GAP_PARAM_CONN_LATENCY, &conn_latency, conn_id);
  492. le_get_conn_param(GAP_PARAM_CONN_TIMEOUT, &conn_supervision_timeout, conn_id);
  493. le_get_conn_addr(conn_id, remote_bd, (void *)&remote_bd_type);
  494. APP_PRINT_INFO5("GAP_CONN_STATE_CONNECTED:remote_bd %s, remote_addr_type %d, conn_interval 0x%x, conn_latency 0x%x, conn_supervision_timeout 0x%x",
  495. TRACE_BDADDR(remote_bd), remote_bd_type,
  496. conn_interval, conn_latency, conn_supervision_timeout);
  497. }
  498. break;
  499. default:
  500. break;
  501. }
  502. //TODO need to changed
  503. bsal_gap_connect_status(bsal_get_rtk_obj(), conn_id, new_state, disc_cause);
  504. gap_conn_state = new_state;
  505. }
  506. /**
  507. * @brief Handle msg GAP_MSG_LE_AUTHEN_STATE_CHANGE
  508. * @note All the gap authentication state events are pre-handled in this function.
  509. * Then the event handling function shall be called according to the new_state
  510. * @param[in] conn_id Connection ID
  511. * @param[in] new_state New authentication state
  512. * @param[in] cause Use this cause when new_state is GAP_AUTHEN_STATE_COMPLETE
  513. * @return void
  514. */
  515. void app_handle_authen_state_evt(uint8_t conn_id, uint8_t new_state, uint16_t cause)
  516. {
  517. APP_PRINT_INFO2("app_handle_authen_state_evt:conn_id %d, cause 0x%x", conn_id, cause);
  518. switch (new_state)
  519. {
  520. case GAP_AUTHEN_STATE_STARTED:
  521. {
  522. APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_STARTED");
  523. }
  524. break;
  525. case GAP_AUTHEN_STATE_COMPLETE:
  526. {
  527. if (cause == GAP_SUCCESS)
  528. {
  529. APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_COMPLETE pair success");
  530. }
  531. else
  532. {
  533. APP_PRINT_INFO0("app_handle_authen_state_evt: GAP_AUTHEN_STATE_COMPLETE pair failed");
  534. }
  535. }
  536. break;
  537. default:
  538. {
  539. APP_PRINT_ERROR1("app_handle_authen_state_evt: unknown newstate %d", new_state);
  540. }
  541. break;
  542. }
  543. }
  544. /**
  545. * @brief Handle msg GAP_MSG_LE_CONN_MTU_INFO
  546. * @note This msg is used to inform APP that exchange mtu procedure is completed.
  547. * @param[in] conn_id Connection ID
  548. * @param[in] mtu_size New mtu size
  549. * @return void
  550. */
  551. void app_handle_conn_mtu_info_evt(uint8_t conn_id, uint16_t mtu_size)
  552. {
  553. APP_PRINT_INFO2("app_handle_conn_mtu_info_evt: conn_id %d, mtu_size %d", conn_id, mtu_size);
  554. }
  555. /**
  556. * @brief Handle msg GAP_MSG_LE_CONN_PARAM_UPDATE
  557. * @note All the connection parameter update change events are pre-handled in this function.
  558. * @param[in] conn_id Connection ID
  559. * @param[in] status New update state
  560. * @param[in] cause Use this cause when status is GAP_CONN_PARAM_UPDATE_STATUS_FAIL
  561. * @return void
  562. */
  563. void app_handle_conn_param_update_evt(uint8_t conn_id, uint8_t status, uint16_t cause)
  564. {
  565. switch (status)
  566. {
  567. case GAP_CONN_PARAM_UPDATE_STATUS_SUCCESS:
  568. {
  569. uint16_t conn_interval;
  570. uint16_t conn_slave_latency;
  571. uint16_t conn_supervision_timeout;
  572. le_get_conn_param(GAP_PARAM_CONN_INTERVAL, &conn_interval, conn_id);
  573. le_get_conn_param(GAP_PARAM_CONN_LATENCY, &conn_slave_latency, conn_id);
  574. le_get_conn_param(GAP_PARAM_CONN_TIMEOUT, &conn_supervision_timeout, conn_id);
  575. APP_PRINT_INFO3("app_handle_conn_param_update_evt update success:conn_interval 0x%x, conn_slave_latency 0x%x, conn_supervision_timeout 0x%x",
  576. conn_interval, conn_slave_latency, conn_supervision_timeout);
  577. }
  578. break;
  579. case GAP_CONN_PARAM_UPDATE_STATUS_FAIL:
  580. {
  581. APP_PRINT_ERROR1("app_handle_conn_param_update_evt update failed: cause 0x%x", cause);
  582. }
  583. break;
  584. case GAP_CONN_PARAM_UPDATE_STATUS_PENDING:
  585. {
  586. APP_PRINT_INFO0("app_handle_conn_param_update_evt update pending.");
  587. }
  588. break;
  589. default:
  590. break;
  591. }
  592. }
  593. /**
  594. * @brief All the BT GAP MSG are pre-handled in this function.
  595. * @note Then the event handling function shall be called according to the
  596. * subtype of T_IO_MSG
  597. * @param[in] p_gap_msg Pointer to GAP msg
  598. * @return void
  599. */
  600. void app_handle_gap_msg(T_IO_MSG *p_gap_msg)
  601. {
  602. T_LE_GAP_MSG gap_msg;
  603. uint8_t conn_id;
  604. memcpy(&gap_msg, &p_gap_msg->u.param, sizeof(p_gap_msg->u.param));
  605. APP_PRINT_TRACE1("app_handle_gap_msg: subtype %d", p_gap_msg->subtype);
  606. switch (p_gap_msg->subtype)
  607. {
  608. case GAP_MSG_LE_DEV_STATE_CHANGE:
  609. {
  610. app_handle_dev_state_evt(gap_msg.msg_data.gap_dev_state_change.new_state,
  611. gap_msg.msg_data.gap_dev_state_change.cause);
  612. }
  613. break;
  614. case GAP_MSG_LE_CONN_STATE_CHANGE:
  615. {
  616. app_handle_conn_state_evt(gap_msg.msg_data.gap_conn_state_change.conn_id,
  617. (T_GAP_CONN_STATE)gap_msg.msg_data.gap_conn_state_change.new_state,
  618. gap_msg.msg_data.gap_conn_state_change.disc_cause);
  619. }
  620. break;
  621. case GAP_MSG_LE_CONN_MTU_INFO:
  622. {
  623. app_handle_conn_mtu_info_evt(gap_msg.msg_data.gap_conn_mtu_info.conn_id,
  624. gap_msg.msg_data.gap_conn_mtu_info.mtu_size);
  625. }
  626. break;
  627. case GAP_MSG_LE_CONN_PARAM_UPDATE:
  628. {
  629. app_handle_conn_param_update_evt(gap_msg.msg_data.gap_conn_param_update.conn_id,
  630. gap_msg.msg_data.gap_conn_param_update.status,
  631. gap_msg.msg_data.gap_conn_param_update.cause);
  632. }
  633. break;
  634. case GAP_MSG_LE_AUTHEN_STATE_CHANGE:
  635. {
  636. app_handle_authen_state_evt(gap_msg.msg_data.gap_authen_state.conn_id,
  637. gap_msg.msg_data.gap_authen_state.new_state,
  638. gap_msg.msg_data.gap_authen_state.status);
  639. }
  640. break;
  641. case GAP_MSG_LE_BOND_JUST_WORK:
  642. {
  643. conn_id = gap_msg.msg_data.gap_bond_just_work_conf.conn_id;
  644. le_bond_just_work_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
  645. APP_PRINT_INFO0("GAP_MSG_LE_BOND_JUST_WORK");
  646. }
  647. break;
  648. case GAP_MSG_LE_BOND_PASSKEY_DISPLAY:
  649. {
  650. uint32_t display_value = 0;
  651. conn_id = gap_msg.msg_data.gap_bond_passkey_display.conn_id;
  652. //le_bond_get_display_key(conn_id, &display_value);
  653. APP_PRINT_INFO1("GAP_MSG_LE_BOND_PASSKEY_DISPLAY:passkey %d", display_value);
  654. le_bond_passkey_display_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
  655. }
  656. break;
  657. case GAP_MSG_LE_BOND_USER_CONFIRMATION:
  658. {
  659. uint32_t display_value = 0;
  660. conn_id = gap_msg.msg_data.gap_bond_user_conf.conn_id;
  661. le_bond_get_display_key(conn_id, &display_value);
  662. APP_PRINT_INFO1("GAP_MSG_LE_BOND_USER_CONFIRMATION: passkey %d", display_value);
  663. le_bond_user_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
  664. }
  665. break;
  666. case GAP_MSG_LE_BOND_PASSKEY_INPUT:
  667. {
  668. uint32_t passkey = 888888;
  669. conn_id = gap_msg.msg_data.gap_bond_passkey_input.conn_id;
  670. APP_PRINT_INFO1("GAP_MSG_LE_BOND_PASSKEY_INPUT: conn_id %d", conn_id);
  671. le_bond_passkey_input_confirm(conn_id, passkey, GAP_CFM_CAUSE_ACCEPT);
  672. }
  673. break;
  674. #if F_BT_LE_SMP_OOB_SUPPORT
  675. case GAP_MSG_LE_BOND_OOB_INPUT:
  676. {
  677. uint8_t oob_data[GAP_OOB_LEN] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
  678. conn_id = gap_msg.msg_data.gap_bond_oob_input.conn_id;
  679. APP_PRINT_INFO0("GAP_MSG_LE_BOND_OOB_INPUT");
  680. le_bond_set_param(GAP_PARAM_BOND_OOB_DATA, GAP_OOB_LEN, oob_data);
  681. le_bond_oob_input_confirm(conn_id, GAP_CFM_CAUSE_ACCEPT);
  682. }
  683. break;
  684. #endif
  685. default:
  686. APP_PRINT_ERROR1("app_handle_gap_msg: unknown subtype %d", p_gap_msg->subtype);
  687. break;
  688. }
  689. }
  690. /**
  691. * @brief All the application messages are pre-handled in this function
  692. * @note All the IO MSGs are sent to this function, then the event handling
  693. * function shall be called according to the MSG type.
  694. * @param[in] io_msg IO message data
  695. * @return void
  696. */
  697. static void app_handle_io_msg(T_IO_MSG io_msg)
  698. {
  699. uint16_t msg_type = io_msg.type;
  700. switch (msg_type)
  701. {
  702. case IO_MSG_TYPE_BT_STATUS:
  703. {
  704. app_handle_gap_msg(&io_msg);
  705. }
  706. break;
  707. default:
  708. break;
  709. }
  710. }
  711. /** @defgroup PERIPH_APP_TASK Peripheral App Task
  712. * @brief This file handles the implementation of application task related functions.
  713. *
  714. * Create App task and handle events & messages
  715. * @{
  716. */
  717. /*============================================================================*
  718. * Macros
  719. *============================================================================*/
  720. #define APP_TASK_PRIORITY 12 //!< Task priorities
  721. #define APP_TASK_STACK_SIZE 256 * 4 //!< Task stack size
  722. #define MAX_NUMBER_OF_GAP_MESSAGE 0x20 //!< GAP message queue size
  723. #define MAX_NUMBER_OF_IO_MESSAGE 0x20 //!< IO message queue size
  724. #define MAX_NUMBER_OF_EVENT_MESSAGE (MAX_NUMBER_OF_GAP_MESSAGE + MAX_NUMBER_OF_IO_MESSAGE) //!< Event message queue size
  725. /*============================================================================*
  726. * Variables
  727. *============================================================================*/
  728. static void *app_task_handle; //!< APP Task handle
  729. static void *evt_queue_handle; //!< Event queue handle
  730. static void *io_queue_handle; //!< IO queue handle
  731. /*============================================================================*
  732. * Functions
  733. *============================================================================*/
  734. void app_main_task(void *p_param);
  735. void bsal_ble_loop(void *p_param);
  736. /**
  737. * @brief Initialize App task
  738. * @return void
  739. */
  740. void app_task_init()
  741. {
  742. os_task_create(&app_task_handle, "app", app_main_task, 0, APP_TASK_STACK_SIZE,
  743. APP_TASK_PRIORITY);
  744. // os_task_create(&app_task_handle, "bsal_loop", bsal_ble_loop, 0, APP_TASK_STACK_SIZE,
  745. // 3);
  746. }
  747. /**
  748. * @brief App task to handle events & messages
  749. * @param[in] p_param Parameters sending to the task
  750. * @return void
  751. */
  752. static void app_main_task(void *p_param)
  753. {
  754. uint8_t event;
  755. os_msg_queue_create(&io_queue_handle, MAX_NUMBER_OF_IO_MESSAGE, sizeof(T_IO_MSG));
  756. os_msg_queue_create(&evt_queue_handle, MAX_NUMBER_OF_EVENT_MESSAGE, sizeof(uint8_t));
  757. gap_start_bt_stack(evt_queue_handle, io_queue_handle, MAX_NUMBER_OF_GAP_MESSAGE);
  758. while (true)
  759. {
  760. if (os_msg_recv(evt_queue_handle, &event, 0xFFFFFFFF) == true)
  761. {
  762. if (event == EVENT_IO_TO_APP)
  763. {
  764. T_IO_MSG io_msg;
  765. if (os_msg_recv(io_queue_handle, &io_msg, 0) == true)
  766. {
  767. app_handle_io_msg(io_msg);
  768. }
  769. }
  770. else
  771. {
  772. gap_handle_msg(event);
  773. }
  774. }
  775. }
  776. }
  777. T_APP_RESULT bsal_attr_read_cb(uint8_t conn_id, T_SERVER_ID service_id,
  778. uint16_t attrib_index, uint16_t offset, uint16_t *p_length, uint8_t **pp_value)
  779. {
  780. T_APP_RESULT cause = APP_RESULT_SUCCESS;
  781. bsal_callbak_data_t p_param;
  782. p_param.stack_ptr = bsal_get_rtk_obj();
  783. p_param.start_handle = service_id;
  784. p_param.conn_id = conn_id;
  785. p_param.off_handle = attrib_index;
  786. p_param.msg_type = BSAL_CALLBACK_TYPE_READ_CHAR_VALUE;
  787. //load the new data
  788. //frome service_id find the service index;
  789. bsal_srv_callback_t *p_bsal_srv = bsal_profile_get(p_param.stack_ptr, service_id);
  790. memcpy(&p_param.srv_uuid, &p_bsal_srv->srv_uuid, sizeof(bsal_uuid_any_t));
  791. p_bsal_srv->bsal_srv_fn_cb((void *)&p_param);
  792. //load the new data
  793. //database get data
  794. //read from db
  795. //
  796. bsal_srv_read_data(bsal_get_rtk_obj(), service_id, attrib_index, p_length, pp_value);
  797. return (cause);
  798. }
  799. T_APP_RESULT bsal_attr_write_cb(uint8_t conn_id, T_SERVER_ID service_id,
  800. uint16_t attrib_index, T_WRITE_TYPE write_type, uint16_t length, uint8_t *p_value,
  801. P_FUN_WRITE_IND_POST_PROC *p_write_ind_post_proc)
  802. {
  803. T_APP_RESULT cause = APP_RESULT_SUCCESS;
  804. bsal_callbak_data_t p_param;
  805. p_param.stack_ptr = bsal_get_rtk_obj();
  806. p_param.conn_id = conn_id;
  807. p_param.start_handle = service_id;
  808. p_param.off_handle = attrib_index;
  809. p_param.msg_type = BSAL_CALLBACK_TYPE_WRITE_CHAR_VALUE;
  810. p_param.length = length;
  811. p_param.data = (uint8_t *)p_value;// send the cccd;
  812. bsal_srv_callback_t *p_bsal_srv = bsal_profile_get(p_param.stack_ptr, service_id);
  813. memcpy(&p_param.srv_uuid, &p_bsal_srv->srv_uuid, sizeof(bsal_uuid_any_t));
  814. p_bsal_srv->bsal_srv_fn_cb((void *)&p_param);
  815. return (cause);
  816. }
  817. void bsal_cccd_update_cb(uint8_t conn_id, T_SERVER_ID service_id, uint16_t index,
  818. uint16_t cccbits)
  819. {
  820. bsal_callbak_data_t p_param;
  821. p_param.stack_ptr = bsal_get_rtk_obj();
  822. p_param.conn_id = conn_id;
  823. p_param.off_handle = index;
  824. p_param.start_handle = service_id;
  825. p_param.msg_type = BSAL_CALLBACK_TYPE_INDIFICATION_NOTIFICATION;
  826. p_param.length = 2;
  827. p_param.value = cccbits;// send the cccd;
  828. bsal_srv_callback_t *p_bsal_srv = bsal_profile_get(p_param.stack_ptr, service_id);
  829. memcpy(&p_param.srv_uuid, &p_bsal_srv->srv_uuid, sizeof(bsal_uuid_any_t));
  830. p_bsal_srv->bsal_srv_fn_cb((void *)&p_param);
  831. }
  832. static const T_FUN_GATT_SERVICE_CBS bsal_cbs =
  833. {
  834. bsal_attr_read_cb, // Read callback function pointer
  835. bsal_attr_write_cb, // Write callback function pointer
  836. bsal_cccd_update_cb // CCCD update callback function pointer
  837. };
  838. static T_APP_RESULT bsal_app_gap_callback(uint8_t cb_type, void *p_cb_data)
  839. {
  840. T_APP_RESULT result = APP_RESULT_SUCCESS;
  841. T_LE_CB_DATA *p_data = (T_LE_CB_DATA *)p_cb_data;
  842. switch (cb_type)
  843. {
  844. case GAP_MSG_LE_MODIFY_WHITE_LIST:
  845. APP_PRINT_INFO2("GAP_MSG_LE_MODIFY_WHITE_LIST: operation %d, cause 0x%x",
  846. p_data->p_le_modify_white_list_rsp->operation,
  847. p_data->p_le_modify_white_list_rsp->cause);
  848. break;
  849. default:
  850. APP_PRINT_ERROR1("app_gap_callback: unhandled cb_type 0x%x", cb_type);
  851. break;
  852. }
  853. return result;
  854. }
  855. static T_APP_RESULT bsal_app_profile_callback(T_SERVER_ID service_id, void *p_data)
  856. {
  857. T_APP_RESULT app_result = APP_RESULT_SUCCESS;
  858. if (service_id == SERVICE_PROFILE_GENERAL_ID)
  859. {
  860. T_SERVER_APP_CB_DATA *p_param = (T_SERVER_APP_CB_DATA *)p_data;
  861. switch (p_param->eventId)
  862. {
  863. case PROFILE_EVT_SRV_REG_COMPLETE:// srv register result event.
  864. APP_PRINT_INFO1("PROFILE_EVT_SRV_REG_COMPLETE: result %d",
  865. p_param->event_data.service_reg_result);
  866. break;
  867. case PROFILE_EVT_SEND_DATA_COMPLETE:
  868. APP_PRINT_INFO5("PROFILE_EVT_SEND_DATA_COMPLETE: conn_id %d, cause 0x%x, service_id %d, attrib_idx 0x%x, credits %d",
  869. p_param->event_data.send_data_result.conn_id,
  870. p_param->event_data.send_data_result.cause,
  871. p_param->event_data.send_data_result.service_id,
  872. p_param->event_data.send_data_result.attrib_idx,
  873. p_param->event_data.send_data_result.credits);
  874. if (p_param->event_data.send_data_result.cause == GAP_SUCCESS)
  875. {
  876. APP_PRINT_INFO0("PROFILE_EVT_SEND_DATA_COMPLETE success");
  877. }
  878. else
  879. {
  880. APP_PRINT_ERROR0("PROFILE_EVT_SEND_DATA_COMPLETE failed");
  881. }
  882. break;
  883. default:
  884. break;
  885. }
  886. }
  887. return app_result;
  888. }