luat_ble_server_api.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609
  1. #include <string.h>
  2. #include <stdint.h>
  3. #include <stdbool.h>
  4. #include <assert.h>
  5. #include "wm_bt_config.h"
  6. // #if (WM_NIMBLE_INCLUDED == CFG_ON)
  7. #include "wm_bt_app.h"
  8. #include "wm_bt_util.h"
  9. #include "host/ble_hs.h"
  10. #include "wm_ble_gap.h"
  11. #include "wm_ble_uart_if.h"
  12. int tls_ble_server_api_init(tls_ble_output_func_ptr output_func_ptr);
  13. int tls_ble_server_api_deinit();
  14. uint32_t tls_ble_server_api_get_mtu();
  15. int tls_ble_server_api_send_msg(uint8_t *data, int data_len);
  16. #include "luat_base.h"
  17. #include "luat_msgbus.h"
  18. #include "luat_malloc.h"
  19. typedef struct ble_write_msg {
  20. // uint16_t conn_handle,
  21. // uint16_t attr_handle,
  22. ble_uuid_t* uuid;
  23. uint16_t len;
  24. char buff[1];
  25. }ble_write_msg_t;
  26. /*
  27. * GLOBAL VARIABLE DEFINITIONS
  28. ****************************************************************************************
  29. */
  30. typedef enum{
  31. BLE_SERVER_MODE_IDLE = 0x00,
  32. BLE_SERVER_MODE_ADVERTISING = 0x01,
  33. BLE_SERVER_MODE_CONNECTED,
  34. BLE_SERVER_MODE_INDICATING,
  35. BLE_SERVER_MODE_EXITING
  36. } ble_server_state_t;
  37. static uint8_t g_ble_prof_connected = 0;
  38. static uint8_t g_ble_indicate_enable = 0;
  39. static tls_ble_output_func_ptr g_ble_uart_output_fptr = NULL;
  40. static int g_mtu = 20;
  41. static uint8_t g_ind_data[255];
  42. static volatile uint8_t g_send_pending = 0;
  43. static volatile ble_server_state_t g_ble_server_state = BLE_SERVER_MODE_IDLE;
  44. /* ble attr write/notify handle */
  45. uint16_t g_ble_attr_indicate_handle;
  46. uint16_t g_ble_attr_write_handle;
  47. uint16_t g_ble_conn_handle ;
  48. #define WM_GATT_SVC_UUID 0xFFF0
  49. #define WM_GATT_INDICATE_UUID 0xFFF1
  50. #define WM_GATT_WRITE_UUID 0xFFF2
  51. #define WM_GATT_NOTIFY_UUID 0xFFF3
  52. static int
  53. gatt_svr_chr_access_func(uint16_t conn_handle, uint16_t attr_handle,
  54. struct ble_gatt_access_ctxt *ctxt, void *arg);
  55. /*
  56. * LOCAL FUNCTION DECLARATIONS
  57. ****************************************************************************************
  58. */
  59. static int
  60. gatt_svr_chr_write_func(uint16_t conn_handle, uint16_t attr_handle,
  61. struct ble_gatt_access_ctxt *ctxt, void *arg);
  62. static const struct ble_gatt_svc_def gatt_svr_svcs[] = {
  63. {
  64. /* Service: uart */
  65. .type = BLE_GATT_SVC_TYPE_PRIMARY,
  66. .uuid = BLE_UUID16_DECLARE(WM_GATT_SVC_UUID),
  67. .characteristics = (struct ble_gatt_chr_def[]) { {
  68. .uuid = BLE_UUID16_DECLARE(WM_GATT_WRITE_UUID),
  69. .val_handle = &g_ble_attr_write_handle,
  70. .access_cb = gatt_svr_chr_access_func,
  71. .flags = BLE_GATT_CHR_F_WRITE,
  72. },{
  73. .uuid = BLE_UUID16_DECLARE(WM_GATT_INDICATE_UUID),
  74. .val_handle = &g_ble_attr_indicate_handle,
  75. .access_cb = gatt_svr_chr_access_func,
  76. .flags = BLE_GATT_CHR_F_INDICATE,
  77. },{
  78. // 暂不支持NOTIFY
  79. // .uuid = BLE_UUID16_DECLARE(WM_GATT_NOTIFY_UUID),
  80. // .val_handle = &g_ble_attr_notify_handle,
  81. // .access_cb = gatt_svr_chr_access_func,
  82. // .flags = BLE_GATT_CHR_F_NOTIFY,
  83. // },{
  84. 0, /* No more characteristics in this service */
  85. }
  86. },
  87. },
  88. {
  89. 0, /* No more services */
  90. },
  91. };
  92. int wm_ble_server_api_adv(bool enable)
  93. {
  94. int rc;
  95. if(enable)
  96. {
  97. struct ble_hs_adv_fields fields;
  98. const char *name;
  99. /**
  100. * Set the advertisement data included in our advertisements:
  101. * o Flags (indicates advertisement type and other general info).
  102. * o Device name.
  103. * o user specific field (winner micro).
  104. */
  105. memset(&fields, 0, sizeof fields);
  106. /* Advertise two flags:
  107. * o Discoverability in forthcoming advertisement (general)
  108. * o BLE-only (BR/EDR unsupported).
  109. */
  110. fields.flags = BLE_HS_ADV_F_DISC_GEN |
  111. BLE_HS_ADV_F_BREDR_UNSUP;
  112. name = ble_svc_gap_device_name();
  113. fields.name = (uint8_t *)name;
  114. fields.name_len = strlen(name);
  115. fields.name_is_complete = 1;
  116. fields.uuids16 = (ble_uuid16_t[]){
  117. BLE_UUID16_INIT(0xFFF0)
  118. };
  119. fields.num_uuids16 = 1;
  120. fields.uuids16_is_complete = 1;
  121. rc = ble_gap_adv_set_fields(&fields);
  122. if (rc != 0) {
  123. TLS_BT_APPL_TRACE_ERROR("error setting advertisement data; rc=%d\r\n", rc);
  124. return rc;
  125. }
  126. /* As own address type we use hard-coded value, because we generate
  127. NRPA and by definition it's random */
  128. rc = tls_nimble_gap_adv(WM_BLE_ADV_IND, 0);
  129. assert(rc == 0);
  130. }else
  131. {
  132. rc = tls_nimble_gap_adv(WM_BLE_ADV_STOP, 0);
  133. }
  134. return rc;
  135. }
  136. /*
  137. * LOCAL FUNCTION DEFINITIONS
  138. ****************************************************************************************
  139. */
  140. static int l_ble_chr_write_cb(lua_State* L, void* ptr) {
  141. ble_write_msg_t* wmsg = (ble_write_msg_t*)ptr;
  142. rtos_msg_t* msg = (rtos_msg_t*)lua_topointer(L, -1);
  143. lua_getglobal(L, "sys_pub");
  144. if (lua_isfunction(L, -1)) {
  145. lua_pushstring(L, "BLE_GATT_WRITE_CHR");
  146. lua_newtable(L);
  147. lua_pushlstring(L, wmsg->buff, wmsg->len);
  148. lua_call(L, 3, 0);
  149. }
  150. return 0;
  151. }
  152. static int
  153. gatt_svr_chr_access_func(uint16_t conn_handle, uint16_t attr_handle,
  154. struct ble_gatt_access_ctxt *ctxt, void *arg)
  155. {
  156. int i = 0;
  157. struct os_mbuf *om = ctxt->om;
  158. ble_write_msg_t* wmsg;
  159. rtos_msg_t msg = {0};
  160. switch (ctxt->op) {
  161. case BLE_GATT_ACCESS_OP_WRITE_CHR:
  162. while(om) {
  163. //LLOG("");
  164. wmsg = (ble_write_msg_t*)(luat_heap_malloc(sizeof(ble_write_msg_t) + om->om_len - 1));
  165. if (wmsg != NULL) {
  166. wmsg->len = om->om_len;
  167. msg.handler = l_ble_chr_write_cb;
  168. msg.ptr = wmsg;
  169. msg.arg1 = conn_handle;
  170. msg.arg2 = attr_handle;
  171. memcpy(wmsg->buff, om->om_data, om->om_len);
  172. luat_msgbus_put(&msg, 0);
  173. }
  174. // if(g_ble_uart_output_fptr)
  175. // {
  176. // g_ble_uart_output_fptr((uint8_t *)om->om_data, om->om_len);
  177. // }else
  178. // {
  179. // print_bytes(om->om_data, om->om_len);
  180. // }
  181. om = SLIST_NEXT(om, om_next);
  182. }
  183. return 0;
  184. default:
  185. assert(0);
  186. return BLE_ATT_ERR_UNLIKELY;
  187. }
  188. }
  189. int
  190. wm_ble_server_gatt_svr_init(void)
  191. {
  192. int rc;
  193. rc = ble_gatts_count_cfg(gatt_svr_svcs);
  194. if (rc != 0) {
  195. goto err;
  196. }
  197. rc = ble_gatts_add_svcs(gatt_svr_svcs);
  198. if (rc != 0) {
  199. return rc;
  200. }
  201. err:
  202. return rc;
  203. }
  204. static uint8_t ss = 0x00;
  205. static void ble_server_indication_sent_cb(int conn_id, int status)
  206. {
  207. int len = 0;
  208. tls_bt_status_t ret;
  209. g_send_pending = 0;
  210. if(!g_ble_indicate_enable)
  211. {
  212. TLS_BT_APPL_TRACE_DEBUG("Indicate disabled... when trying to send...\r\n");
  213. return;
  214. }
  215. if(g_ble_uart_output_fptr == NULL)
  216. {
  217. memset(g_ind_data, ss, sizeof(g_ind_data));
  218. ss++;
  219. if(ss > 0xFE) ss = 0x00;
  220. tls_ble_server_api_send_msg(g_ind_data, g_mtu);
  221. }else
  222. {
  223. len = tls_ble_uart_buffer_size();
  224. len = MIN(len, g_mtu);
  225. if(len)
  226. {
  227. tls_ble_uart_buffer_peek(g_ind_data, len);
  228. ret = tls_ble_server_api_send_msg(g_ind_data, len);
  229. if(ret == TLS_BT_STATUS_SUCCESS)
  230. {
  231. tls_ble_uart_buffer_delete(len);
  232. g_send_pending = 1;
  233. }else
  234. {
  235. TLS_BT_APPL_TRACE_DEBUG("server send via ble failed(%d), retry...\r\n", ret);
  236. }
  237. }
  238. }
  239. }
  240. static void wm_ble_server_start_indicate(void *arg)
  241. {
  242. int len;
  243. int rc;
  244. uint8_t *tmp_ptr = NULL;
  245. tls_bt_status_t status;
  246. /*No uart ble interface*/
  247. if(g_ble_uart_output_fptr == NULL)
  248. {
  249. rc = tls_ble_server_api_send_msg(g_ind_data, g_mtu);
  250. TLS_BT_APPL_TRACE_DEBUG("Indicating sending...rc=%d\r\n", rc);
  251. }else
  252. {
  253. /*check and send*/
  254. len = tls_ble_uart_buffer_size();
  255. len = MIN(len, g_mtu);
  256. if(len)
  257. {
  258. tls_ble_uart_buffer_peek(g_ind_data, len);
  259. status = tls_ble_server_api_send_msg(g_ind_data, g_mtu);
  260. if(status == TLS_BT_STATUS_SUCCESS)
  261. {
  262. tls_ble_uart_buffer_delete(len);
  263. }else
  264. {
  265. TLS_BT_APPL_TRACE_DEBUG("Server send failed(%d), retry...\r\n", status);
  266. tls_bt_async_proc_func(wm_ble_server_start_indicate,(void*)g_ble_indicate_enable,1000);
  267. }
  268. }
  269. }
  270. }
  271. static void conn_param_update_cb(uint16_t conn_handle, int status, void *arg)
  272. {
  273. TLS_BT_APPL_TRACE_DEBUG("conn param update complete; conn_handle=%d status=%d\n",
  274. conn_handle, status);
  275. }
  276. static void wm_ble_server_conn_param_update_slave()
  277. {
  278. int rc;
  279. struct ble_l2cap_sig_update_params params;
  280. params.itvl_min = 0x0006;
  281. params.itvl_max = 0x0006;
  282. params.slave_latency = 0;
  283. params.timeout_multiplier = 0x07d0;
  284. rc = ble_l2cap_sig_update(g_ble_conn_handle, &params,
  285. conn_param_update_cb, NULL);
  286. assert(rc == 0);
  287. }
  288. static int ble_gap_evt_cb(struct ble_gap_event *event, void *arg)
  289. {
  290. int rc;
  291. struct ble_gap_conn_desc desc;
  292. switch(event->type)
  293. {
  294. case BLE_GAP_EVENT_CONNECT:
  295. g_ble_prof_connected = 1;
  296. g_send_pending = 0;
  297. TLS_BT_APPL_TRACE_DEBUG("connected status=%d handle=%d,g_ble_attr_indicate_handle=%d\r\n",event->connect.status, g_ble_conn_handle, g_ble_attr_indicate_handle );
  298. if (event->connect.status == 0) {
  299. g_ble_server_state = BLE_SERVER_MODE_CONNECTED;
  300. //re set this flag, to prevent stop adv, but connected evt reported when deinit this demo
  301. g_ble_conn_handle = event->connect.conn_handle;
  302. rc = ble_gap_conn_find(event->connect.conn_handle, &desc);
  303. assert(rc == 0);
  304. print_conn_desc(&desc);
  305. #if MYNEWT_VAL(BLEPRPH_LE_PHY_SUPPORT)
  306. phy_conn_changed(event->connect.conn_handle);
  307. #endif
  308. }
  309. TLS_BT_APPL_TRACE_DEBUG("\r\n");
  310. if (event->connect.status != 0) {
  311. /* Connection failed; resume advertising. */
  312. tls_nimble_gap_adv(WM_BLE_ADV_IND, 0);
  313. }
  314. break;
  315. case BLE_GAP_EVENT_DISCONNECT:
  316. g_ble_prof_connected = 0;
  317. g_ble_indicate_enable = 0;
  318. g_send_pending = 0;
  319. TLS_BT_APPL_TRACE_DEBUG("disconnect reason=%d,state=%d\r\n", event->disconnect.reason,g_ble_server_state);
  320. if(g_ble_server_state == BLE_SERVER_MODE_EXITING)
  321. {
  322. if(g_ble_uart_output_fptr)
  323. {
  324. g_ble_uart_output_fptr = NULL;
  325. }
  326. g_ble_server_state = BLE_SERVER_MODE_IDLE;
  327. }else
  328. {
  329. rc = tls_nimble_gap_adv(WM_BLE_ADV_IND, 0);
  330. if(!rc)
  331. {
  332. g_ble_server_state = BLE_SERVER_MODE_ADVERTISING;
  333. }
  334. }
  335. #if 0
  336. if(event->disconnect.reason == 534)
  337. {
  338. //hci error code: 0x16 + 0x200 = 534; //local host terminate the connection;
  339. }else
  340. {
  341. tls_nimble_gap_adv(WM_BLE_ADV_IND, 0);
  342. }
  343. #endif
  344. break;
  345. case BLE_GAP_EVENT_NOTIFY_TX:
  346. if(event->notify_tx.status == BLE_HS_EDONE)
  347. {
  348. ble_server_indication_sent_cb(event->notify_tx.attr_handle, event->notify_tx.status);
  349. }else
  350. {
  351. /*Application will handle other cases*/
  352. }
  353. break;
  354. case BLE_GAP_EVENT_SUBSCRIBE:
  355. TLS_BT_APPL_TRACE_DEBUG("subscribe indicate(%d,%d)\r\n", event->subscribe.prev_indicate,event->subscribe.cur_indicate );
  356. g_ble_indicate_enable = event->subscribe.cur_indicate;
  357. if(g_ble_indicate_enable)
  358. {
  359. g_ble_server_state = BLE_SERVER_MODE_INDICATING;
  360. /*To reach the max passthrough, in ble_uart mode, I conifg the min connection_interval*/
  361. if(g_ble_uart_output_fptr)
  362. {
  363. tls_bt_async_proc_func(wm_ble_server_conn_param_update_slave, NULL, 30);
  364. }
  365. tls_bt_async_proc_func(wm_ble_server_start_indicate,(void*)g_ble_indicate_enable, 30);
  366. }else
  367. {
  368. if(g_ble_server_state != BLE_SERVER_MODE_EXITING)
  369. {
  370. g_ble_server_state = BLE_SERVER_MODE_CONNECTED;
  371. }
  372. }
  373. break;
  374. case BLE_GAP_EVENT_MTU:
  375. TLS_BT_APPL_TRACE_DEBUG("wm ble dm mtu changed to(%d)\r\n", event->mtu.value);
  376. /*nimBLE config prefered ATT_MTU is 256. here 256-12 = 244. */
  377. /* preamble(1)+access address(4)+pdu(2~257)+crc*/
  378. /* ATT_MTU(247):pdu= pdu_header(2)+l2cap_len(2)+l2cap_chn(2)+mic(4)*/
  379. /* GATT MTU(244): ATT_MTU +opcode+chn*/
  380. g_mtu = min(event->mtu.value - 12, 244);
  381. break;
  382. case BLE_GAP_EVENT_REPEAT_PAIRING:
  383. /* We already have a bond with the peer, but it is attempting to
  384. * establish a new secure link. This app sacrifices security for
  385. * convenience: just throw away the old bond and accept the new link.
  386. */
  387. /* Delete the old bond. */
  388. rc = ble_gap_conn_find(event->repeat_pairing.conn_handle, &desc);
  389. assert(rc == 0);
  390. ble_store_util_delete_peer(&desc.peer_id_addr);
  391. TLS_BT_APPL_TRACE_DEBUG("!!!BLE_GAP_EVENT_REPEAT_PAIRING\r\n");
  392. return BLE_GAP_REPEAT_PAIRING_RETRY;
  393. case BLE_GAP_EVENT_PASSKEY_ACTION:
  394. TLS_BT_APPL_TRACE_DEBUG(">>>BLE_GAP_EVENT_REPEAT_PAIRING\r\n");
  395. return 0;
  396. default:
  397. break;
  398. }
  399. return 0;
  400. }
  401. /*
  402. * EXPORTED FUNCTION DEFINITIONS
  403. ****************************************************************************************
  404. */
  405. int tls_ble_server_api_init(tls_ble_output_func_ptr output_func_ptr)
  406. {
  407. int rc = BLE_HS_EAPP;
  408. if(bt_adapter_state == WM_BT_STATE_OFF)
  409. {
  410. TLS_BT_APPL_TRACE_ERROR("%s failed rc=%s\r\n", __FUNCTION__, tls_bt_rc_2_str(BLE_HS_EDISABLED));
  411. return BLE_HS_EDISABLED;
  412. }
  413. TLS_BT_APPL_TRACE_DEBUG("%s, state=%d\r\n", __FUNCTION__, g_ble_server_state);
  414. if(g_ble_server_state == BLE_SERVER_MODE_IDLE)
  415. {
  416. g_ble_prof_connected = 0;
  417. //step 0: reset other services. Note
  418. rc = ble_gatts_reset();
  419. if(rc != 0)
  420. {
  421. TLS_BT_APPL_TRACE_ERROR("tls_ble_server_api_init failed rc=%d\r\n", rc);
  422. return rc;
  423. }
  424. //step 1: config/adding the services
  425. rc = wm_ble_server_gatt_svr_init();
  426. if(rc == 0)
  427. {
  428. tls_ble_register_gap_evt(WM_BLE_GAP_EVENT_CONNECT|WM_BLE_GAP_EVENT_DISCONNECT|WM_BLE_GAP_EVENT_NOTIFY_TX|WM_BLE_GAP_EVENT_SUBSCRIBE|WM_BLE_GAP_EVENT_MTU|WM_BLE_GAP_EVENT_REPEAT_PAIRING, ble_gap_evt_cb);
  429. TLS_BT_APPL_TRACE_DEBUG("### wm_ble_server_api_init \r\n");
  430. g_ble_uart_output_fptr = output_func_ptr;
  431. /*step 2: start the service*/
  432. rc = ble_gatts_start();
  433. assert(rc == 0);
  434. /*step 3: start advertisement*/
  435. rc = wm_ble_server_api_adv(true);
  436. if(rc == 0)
  437. {
  438. g_ble_server_state = BLE_SERVER_MODE_ADVERTISING;
  439. }
  440. }else
  441. {
  442. TLS_BT_APPL_TRACE_ERROR("### wm_ble_server_api_init failed(rc=%d)\r\n", rc);
  443. }
  444. }
  445. else
  446. {
  447. TLS_BT_APPL_TRACE_WARNING("wm_ble_server_api_init registered\r\n");
  448. rc = BLE_HS_EALREADY;
  449. }
  450. return rc;
  451. }
  452. int tls_ble_server_api_deinit()
  453. {
  454. int rc = BLE_HS_EAPP;
  455. if(bt_adapter_state == WM_BT_STATE_OFF)
  456. {
  457. TLS_BT_APPL_TRACE_ERROR("%s failed rc=%s\r\n", __FUNCTION__, tls_bt_rc_2_str(BLE_HS_EDISABLED));
  458. return BLE_HS_EDISABLED;
  459. }
  460. TLS_BT_APPL_TRACE_DEBUG("%s, state=%d\r\n", __FUNCTION__, g_ble_server_state);
  461. if(g_ble_server_state == BLE_SERVER_MODE_CONNECTED || g_ble_server_state == BLE_SERVER_MODE_INDICATING)
  462. {
  463. g_ble_indicate_enable = 0;
  464. rc = ble_gap_terminate(g_ble_conn_handle, BLE_ERR_REM_USER_CONN_TERM);
  465. if(rc == 0)
  466. {
  467. g_ble_server_state = BLE_SERVER_MODE_EXITING;
  468. }
  469. }else if(g_ble_server_state == BLE_SERVER_MODE_ADVERTISING)
  470. {
  471. rc = tls_nimble_gap_adv(WM_BLE_ADV_STOP, 0);
  472. if(rc == 0)
  473. {
  474. if(g_ble_uart_output_fptr)
  475. {
  476. g_ble_uart_output_fptr = NULL;
  477. }
  478. g_send_pending = 0;
  479. g_ble_server_state = BLE_SERVER_MODE_IDLE;
  480. }
  481. }else if(g_ble_server_state == BLE_SERVER_MODE_IDLE)
  482. {
  483. rc = 0;
  484. }else
  485. {
  486. rc = BLE_HS_EALREADY;
  487. }
  488. return rc;
  489. }
  490. uint32_t tls_ble_server_api_get_mtu()
  491. {
  492. return g_mtu;
  493. }
  494. int tls_ble_server_api_send_msg(uint8_t *data, int data_len)
  495. {
  496. int rc;
  497. struct os_mbuf *om;
  498. //TLS_BT_APPL_TRACE_DEBUG("### %s len=%d\r\n", __FUNCTION__, data_len);
  499. if(g_send_pending) return BLE_HS_EBUSY;
  500. if(data_len<=0 || data == NULL)
  501. {
  502. return BLE_HS_EINVAL;
  503. }
  504. om = ble_hs_mbuf_from_flat(data, data_len);
  505. if (!om) {
  506. return BLE_HS_ENOMEM;
  507. }
  508. rc = ble_gattc_indicate_custom(g_ble_conn_handle,g_ble_attr_indicate_handle, om);
  509. if(rc == 0)
  510. {
  511. g_send_pending = 1;
  512. }
  513. return rc;
  514. }
  515. // #endif