bsal_srv_uart.c 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  1. /*
  2. * Copyright (c) 2006-2021, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2021-09-09 WaterFishJ the first version
  9. * 2021-09-22 WaterFishJ fix the send bug
  10. */
  11. #include <rtthread.h>
  12. #include <rtdevice.h>
  13. #include <rthw.h>
  14. #include <stdio.h>
  15. #include <stdint.h>
  16. #include "bsal.h"
  17. #include "bsal_osif.h"
  18. #include "bsal_srv_uart.h"
  19. #define MYNEWT_VAL_BLEUART_MAX_INPUT 128
  20. #define ESC_KEY 0x1B
  21. #define BACKSPACE_KEY 0x08
  22. #define DELECT_KEY 0x7F
  23. /* {6E400001-B5A3-F393-E0A9-E50E24DCCA9E} */
  24. static const struct bsal_uuid128 gatt_svr_svc_uart_uuid =
  25. BSAL_UUID128_INIT(0x9e, 0xca, 0xdc, 0x24, 0x0e, 0xe5, 0xa9, 0xe0,
  26. 0x93, 0xf3, 0xa3, 0xb5, 0x01, 0x00, 0x40, 0x6e);
  27. /* {6E400002-B5A3-F393-E0A9-E50E24DCCA9E} */
  28. static const struct bsal_uuid128 gatt_svr_chr_uart_write_uuid =
  29. BSAL_UUID128_INIT(0x9e, 0xca, 0xdc, 0x24, 0x0e, 0xe5, 0xa9, 0xe0,
  30. 0x93, 0xf3, 0xa3, 0xb5, 0x02, 0x00, 0x40, 0x6e);
  31. /* {6E400003-B5A3-F393-E0A9-E50E24DCCA9E} */
  32. static const struct bsal_uuid128 gatt_svr_chr_uart_read_uuid =
  33. BSAL_UUID128_INIT(0x9e, 0xca, 0xdc, 0x24, 0x0e, 0xe5, 0xa9, 0xe0,
  34. 0x93, 0xf3, 0xa3, 0xb5, 0x03, 0x00, 0x40, 0x6e);
  35. /* Pointer to a console buffer */
  36. static rt_uint8_t *console_buf;
  37. struct bleuart_console
  38. {
  39. struct rt_semaphore *rx_end;
  40. struct rt_ringbuffer *rx_fifo;
  41. rt_err_t (*old_rx_ind)(rt_device_t dev, rt_size_t size);
  42. };
  43. static struct bleuart_console bleuart = {0};
  44. static P_SRV_GENERAL_CB pfn_bas_cb = NULL;
  45. static void profile_callback(void *p)
  46. {
  47. bsal_callbak_data_t *p_param = (bsal_callbak_data_t *)p;
  48. bool is_app_cb = false;
  49. if (p_param->msg_type == BSAL_CALLBACK_TYPE_READ_CHAR_VALUE)
  50. {
  51. //NO DEAL had not finished
  52. is_app_cb = true;
  53. }
  54. else if (p_param->msg_type == BSAL_CALLBACK_TYPE_WRITE_CHAR_VALUE)
  55. {
  56. if (GATT_SVC_NUS_WRITE_INDEX == p_param->off_handle)
  57. {
  58. is_app_cb = true;
  59. rt_device_write(rt_console_get_device(), 0, (char *)p_param->data, p_param->length);
  60. }
  61. }
  62. else if (p_param->msg_type == BSAL_CALLBACK_TYPE_INDIFICATION_NOTIFICATION)
  63. {
  64. if (GATT_SVC_NUS_CHAR_CCCD_INDEX == p_param->off_handle)
  65. {
  66. if (p_param->length == 2)
  67. {
  68. is_app_cb = true;
  69. }
  70. }
  71. }
  72. if (is_app_cb && (pfn_bas_cb != NULL))
  73. {
  74. pfn_bas_cb(p_param);
  75. }
  76. }
  77. void bsal_le_uart_svr_init(void *stack_ptr, void *app_callback)
  78. {
  79. struct bsal_gatt_app_srv_def ble_svc_uart_defs[] =
  80. {
  81. {
  82. /*** Uart Service. */
  83. .type = BSAL_GATT_UUID_PRIMARY_SERVICE,
  84. .uuid = BSAL_UUID128_DECLARE(0x9e, 0xca, 0xdc, 0x24, 0x0e, 0xe5, 0xa9, 0xe0,
  85. 0x93, 0xf3, 0xa3, 0xb5, 0x01, 0x00, 0x40, 0x6e),//(bsal_uuid_any_t *)&battery_srv,//BSAL_UUID16_DECLARE(GATT_UUID_BATTERY),
  86. .characteristics = (bsal_gatt_chr_def_t[])
  87. {
  88. {
  89. /*** Uart read characteristic */
  90. .uuid = BSAL_UUID128_DECLARE(0x9e, 0xca, 0xdc, 0x24, 0x0e, 0xe5, 0xa9, 0xe0,
  91. 0x93, 0xf3, 0xa3, 0xb5, 0x03, 0x00, 0x40, 0x6e),//(bsal_uuid_any_t *)&bas_char_bas_level,//BSAL_UUID16_DECLARE(GATT_UUID_CHAR_BAS_LEVEL),
  92. .properties = BSAL_ATT_P_NOTIFY,
  93. .permission = BSAL_GATT_PERM_READ_NONE,
  94. .value_length = 1,
  95. },
  96. {
  97. /*** Uart write characteristic */
  98. .uuid = BSAL_UUID128_DECLARE(0x9e, 0xca, 0xdc, 0x24, 0x0e, 0xe5, 0xa9, 0xe0,
  99. 0x93, 0xf3, 0xa3, 0xb5, 0x02, 0x00, 0x40, 0x6e),//(bsal_uuid_any_t *)&bas_char_bas_level,//BSAL_UUID16_DECLARE(GATT_UUID_CHAR_BAS_LEVEL),
  100. .properties = BSAL_ATT_P_WRITE
  101. | BSAL_ATT_P_WRITE_WITHOUT_RESPONSE
  102. ,
  103. .permission = BSAL_GATT_PERM_WRITE_NONE,
  104. .value_length = 1,
  105. },
  106. {
  107. 0, /* No more characteristics in this service. */
  108. }
  109. },
  110. },
  111. {
  112. 0, /* No more services. */
  113. },
  114. };
  115. bsal_stack_le_srv_reg_func(stack_ptr, &ble_svc_uart_defs, (P_SRV_GENERAL_CB *)profile_callback);
  116. pfn_bas_cb = (P_SRV_GENERAL_CB)app_callback;
  117. }
  118. static rt_err_t bleuart_rx_ind(rt_device_t dev, rt_size_t size)
  119. {
  120. uint8_t ch;
  121. int i;
  122. for(i = 0; i < size; i++)
  123. {
  124. /* read a char */
  125. if (rt_device_read(dev, 0, &ch, 1))
  126. {
  127. rt_ringbuffer_put_force(bleuart.rx_fifo, &ch, 1);
  128. rt_sem_release(bleuart.rx_end);
  129. }
  130. }
  131. return RT_EOK;
  132. }
  133. static uint8_t bleuart_read(void)
  134. {
  135. uint8_t ch;
  136. rt_sem_take(bleuart.rx_end, RT_WAITING_FOREVER);
  137. rt_ringbuffer_getchar(bleuart.rx_fifo, &ch);
  138. return ch;
  139. }
  140. void bsal_bleuart_deinit(void)
  141. {
  142. rt_base_t level;
  143. rt_device_t uart_console;
  144. level = rt_hw_interrupt_disable();
  145. uart_console = rt_console_get_device();
  146. if(uart_console)
  147. {
  148. rt_device_set_rx_indicate(uart_console, bleuart.old_rx_ind);
  149. }
  150. rt_hw_interrupt_enable(level);
  151. if (console_buf != RT_NULL)
  152. {
  153. rt_free(console_buf);
  154. console_buf = RT_NULL;
  155. }
  156. if (bleuart.rx_end != RT_NULL)
  157. {
  158. rt_sem_delete(bleuart.rx_end);
  159. bleuart.rx_end = RT_NULL;
  160. }
  161. if (bleuart.rx_fifo != RT_NULL)
  162. {
  163. rt_ringbuffer_destroy(bleuart.rx_fifo);
  164. bleuart.rx_fifo = RT_NULL;
  165. }
  166. }
  167. void bsal_bleuart_uart_proc(void *stack_ptr, uint16_t *conn_id)
  168. {
  169. int off = 0;
  170. char ch;
  171. struct os_mbuf *om;
  172. bsal_uuid_any_t uuid_srv;
  173. uuid_srv.u_type = BSAL_UUID_TYPE_128BIT;
  174. rt_memcpy(uuid_srv.u128.value, gatt_svr_svc_uart_uuid.value, 16);
  175. uint16_t start_handle = bsal_srv_get_start_handle(stack_ptr, uuid_srv);
  176. rt_kprintf("======== Welcome to enter bluetooth uart mode ========\n");
  177. rt_kprintf("Press 'ESC' to exit.\n");
  178. /* process user input */
  179. while (ESC_KEY != (ch = bleuart_read()))
  180. {
  181. if(ch != '\r' && ch != '\n')
  182. {
  183. if(ch == BACKSPACE_KEY || ch == DELECT_KEY)
  184. {
  185. if(off)
  186. {
  187. console_buf[off--] = 0;
  188. rt_kprintf("\b \b");
  189. }
  190. continue;
  191. }
  192. else
  193. {
  194. console_buf[off++] = ch;
  195. rt_kprintf("%c", ch);
  196. continue;
  197. }
  198. }
  199. console_buf[off] = '\0';
  200. rt_kprintf("\n");
  201. bsal_srv_send_notify_data(stack_ptr, *conn_id, start_handle, GATT_SVC_NUS_READ_INDEX, off + 1, console_buf);
  202. off = 0;
  203. }
  204. bsal_bleuart_deinit();
  205. }
  206. int bsal_bleuart_init(void *stack_ptr, uint16_t *conn_id)
  207. {
  208. int rc;
  209. rt_base_t level;
  210. rt_device_t uart_console;
  211. /* create buffer for send */
  212. console_buf = rt_malloc(MYNEWT_VAL_BLEUART_MAX_INPUT);
  213. if (console_buf == RT_NULL)
  214. {
  215. rc = -RT_ENOMEM;
  216. goto __exit;
  217. }
  218. /* create semaphore for the end of char recived */
  219. bleuart.rx_end = rt_sem_create("bleuart", 0, RT_IPC_FLAG_FIFO);
  220. if (bleuart.rx_end == RT_NULL)
  221. {
  222. rc = -RT_ENOMEM;
  223. goto __exit;
  224. }
  225. /* create recived fifo */
  226. bleuart.rx_fifo = rt_ringbuffer_create(MYNEWT_VAL_BLEUART_MAX_INPUT);
  227. if (bleuart.rx_fifo == RT_NULL)
  228. {
  229. rc = -RT_ENOMEM;
  230. goto __exit;
  231. }
  232. level = rt_hw_interrupt_disable();
  233. uart_console = rt_console_get_device();
  234. if(uart_console)
  235. {
  236. /* back uart console old indicate callback */
  237. bleuart.old_rx_ind = uart_console->rx_indicate;
  238. rt_device_set_rx_indicate(uart_console, bleuart_rx_ind);
  239. }
  240. rt_hw_interrupt_enable(level);
  241. /* Reads console and sends data over BLE */
  242. bsal_bleuart_uart_proc(stack_ptr, conn_id);
  243. return RT_EOK;
  244. __exit:
  245. if (console_buf != RT_NULL)
  246. {
  247. rt_free(console_buf);
  248. console_buf = RT_NULL;
  249. }
  250. if (bleuart.rx_end != RT_NULL)
  251. {
  252. rt_sem_delete(bleuart.rx_end);
  253. bleuart.rx_end = RT_NULL;
  254. }
  255. if (bleuart.rx_fifo != RT_NULL)
  256. {
  257. rt_ringbuffer_destroy(bleuart.rx_fifo);
  258. bleuart.rx_fifo = RT_NULL;
  259. }
  260. return rc;
  261. }