btsrv_hid.c 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  1. /*
  2. * Copyright (c) 2017 Actions Semi Co., Ltd.
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. /**
  7. * @file
  8. * @brief btsrvice hid
  9. */
  10. #define SYS_LOG_DOMAIN "btsrv_hid"
  11. #include "btsrv_os_common.h"
  12. #include "btsrv_inner.h"
  13. static btsrv_hid_callback hid_user_callback;
  14. static void btsrv_hid_user_callback(struct bt_conn *conn, btsrv_hid_event_e event, void *packet, int size)
  15. {
  16. if (hid_user_callback) {
  17. hid_user_callback(hostif_bt_conn_get_handle(conn), event, packet, size);
  18. }
  19. }
  20. static void hid_connected_cb(struct bt_conn *conn)
  21. {
  22. btsrv_event_notify(MSG_BTSRV_CONNECT, MSG_BTSRV_HID_CONNECTED, conn);
  23. }
  24. static void hid_disconnected_cb(struct bt_conn *conn)
  25. {
  26. btsrv_event_notify(MSG_BTSRV_CONNECT, MSG_BTSRV_HID_DISCONNECTED, conn);
  27. }
  28. static void hid_event_cb(struct bt_conn *conn, uint8_t event, uint8_t *data, uint16_t len)
  29. {
  30. struct hid_stack_report stack_report, *p_stack_report;
  31. if (!data) {
  32. memset(&stack_report, 0, sizeof(stack_report));
  33. p_stack_report = &stack_report;
  34. } else {
  35. p_stack_report = (struct hid_stack_report *)data;
  36. }
  37. p_stack_report->conn = conn;
  38. btsrv_event_notify_malloc(MSG_BTSRV_HID, MSG_BTSRV_HID_EVENT_CB, (uint8_t *)p_stack_report, sizeof(stack_report), event);
  39. }
  40. static void hid_event_proc(void *data, uint8_t event)
  41. {
  42. int cb_ev = -1;
  43. struct hid_stack_report *stack_report = data;
  44. struct bt_hid_report hid_report;
  45. /* Callback by hci_rx thread, in negative priority,
  46. * just check hid_user_callback is enough, not need to lock.
  47. */
  48. switch(event){
  49. case BT_HID_EVENT_GET_REPORT:
  50. cb_ev = BTSRV_HID_GET_REPORT;
  51. break;
  52. case BT_HID_EVENT_SET_REPORT:
  53. cb_ev = BTSRV_HID_SET_REPORT;
  54. break;
  55. case BT_HID_EVENT_GET_PROTOCOL:
  56. cb_ev = BTSRV_HID_GET_PROTOCOL;
  57. break;
  58. case BT_HID_EVENT_SET_PROTOCOL:
  59. cb_ev = BTSRV_HID_SET_PROTOCOL;
  60. break;
  61. case BT_HID_EVENT_INTR_DATA:
  62. cb_ev = BTSRV_HID_INTR_DATA;
  63. break;
  64. case BT_HID_EVENT_UNPLUG:
  65. cb_ev = BTSRV_HID_UNPLUG;
  66. btsrv_event_notify(MSG_BTSRV_CONNECT, MSG_BTSRV_HID_UNPLUG, stack_report->conn);
  67. break;
  68. case BT_HID_EVENT_SUSPEND:
  69. cb_ev = BTSRV_HID_SUSPEND;
  70. break;
  71. case BT_HID_EVENT_EXIT_SUSPEND:
  72. cb_ev = BTSRV_HID_EXIT_SUSPEND;
  73. break;
  74. }
  75. if (cb_ev >= 0) {
  76. memset(&hid_report, 0, sizeof(hid_report));
  77. hid_report.hdl = hostif_bt_conn_get_handle(stack_report->conn);
  78. hid_report.report_type = stack_report->report_type;
  79. hid_report.has_size = stack_report->has_size;
  80. hid_report.reserved = stack_report->reserved;
  81. hid_report.len = stack_report->len;
  82. if (stack_report->len) {
  83. memcpy(hid_report.data, stack_report->data, stack_report->len);
  84. }
  85. btsrv_hid_user_callback(stack_report->conn, cb_ev, &hid_report, sizeof(hid_report));
  86. }
  87. }
  88. static const struct bt_hid_app_cb hid_app_cb = {
  89. .connected = hid_connected_cb,
  90. .disconnected = hid_disconnected_cb,
  91. .event_cb = hid_event_cb,
  92. };
  93. void btsrv_hid_connect(struct bt_conn *conn)
  94. {
  95. int ret;
  96. if (conn && !btsrv_rdm_is_hid_connected(conn)) {
  97. ret = hostif_bt_hid_connect(conn);
  98. if (!ret) {
  99. SYS_LOG_INF("Connect hid");
  100. } else {
  101. SYS_LOG_ERR("Connect hid failed %d", ret);
  102. }
  103. }
  104. }
  105. static void btsrv_hid_connect_by_hdl(void *param)
  106. {
  107. uint16_t hdl = (uint16_t)(uint32_t)param;
  108. struct bt_conn *conn;
  109. if (!hdl) {
  110. return;
  111. }
  112. conn = btsrv_rdm_find_conn_by_hdl(hdl);
  113. if (conn) {
  114. btsrv_hid_connect(conn);
  115. }
  116. }
  117. static void btsrv_hid_disconnect_by_hdl(void *param)
  118. {
  119. uint16_t hdl = (uint16_t)(uint32_t)param;
  120. struct bt_conn *conn;
  121. if (hdl) {
  122. conn = btsrv_rdm_find_conn_by_hdl(hdl);
  123. if (conn && btsrv_rdm_is_hid_connected(conn)) {
  124. SYS_LOG_INF("hid_disconnect");
  125. hostif_bt_hid_disconnect(conn);
  126. }
  127. }
  128. }
  129. static void btsrv_hid_connected(struct bt_conn *conn)
  130. {
  131. btsrv_hid_user_callback(conn, BTSRV_HID_CONNECTED, NULL, 0);
  132. }
  133. static void btsrv_hid_disconnected(struct bt_conn *conn)
  134. {
  135. btsrv_hid_user_callback(conn, BTSRV_HID_DISCONNECTED, NULL, 0);
  136. }
  137. static int btsrv_hid_send_ctrl_data(struct bt_hid_report *report)
  138. {
  139. struct bt_conn *conn;
  140. if (report->hdl) {
  141. conn = btsrv_rdm_find_conn_by_hdl(report->hdl);
  142. } else {
  143. conn = btsrv_rdm_hid_get_actived();
  144. }
  145. if(conn) {
  146. return hostif_bt_hid_send_ctrl_data(conn, report->report_type, report->data, report->len);
  147. }
  148. return 0;
  149. }
  150. static int btsrv_hid_send_intr_data(struct bt_hid_report * report)
  151. {
  152. struct bt_conn *conn;
  153. if (report->hdl) {
  154. conn = btsrv_rdm_find_conn_by_hdl(report->hdl);
  155. } else {
  156. conn = btsrv_rdm_hid_get_actived();
  157. }
  158. if (!btsrv_rdm_is_hid_connected(conn)) {
  159. return -EIO;
  160. }
  161. if(conn) {
  162. return hostif_bt_hid_send_intr_data(conn,report->report_type, report->data, report->len);
  163. }
  164. return 0;
  165. }
  166. static int btsrv_hid_send_rsp(void *param, uint8_t status)
  167. {
  168. uint16_t hdl = (uint16_t)(uint32_t)param;
  169. struct bt_conn *conn = btsrv_rdm_find_conn_by_hdl(hdl);
  170. return hostif_bt_hid_send_rsp(conn, status);
  171. }
  172. int btsrv_hid_process(struct app_msg *msg)
  173. {
  174. switch (_btsrv_get_msg_param_cmd(msg)) {
  175. case MSG_BTSRV_HID_START:
  176. hid_user_callback = (btsrv_hid_callback)msg->ptr;
  177. hostif_bt_hid_register_cb((struct bt_hid_app_cb *)&hid_app_cb);
  178. break;
  179. case MSG_BTSRV_HID_STOP:
  180. hid_user_callback = NULL;
  181. break;
  182. case MSG_BTSRV_HID_REGISTER:
  183. hostif_bt_hid_register_sdp(msg->ptr,_btsrv_get_msg_param_reserve(msg));
  184. break;
  185. case MSG_BTSRV_DID_REGISTER:
  186. hostif_bt_did_register_sdp(msg->ptr);
  187. break;
  188. case MSG_BTSRV_HID_CONNECT:
  189. SYS_LOG_INF("MSG_BTSRV_HID_CONNECT");
  190. btsrv_hid_connect_by_hdl(msg->ptr);
  191. break;
  192. case MSG_BTSRV_HID_DISCONNECT:
  193. SYS_LOG_INF("MSG_BTSRV_HID_DISCONNECT");
  194. btsrv_hid_disconnect_by_hdl(msg->ptr);
  195. break;
  196. case MSG_BTSRV_HID_CONNECTED:
  197. SYS_LOG_INF("MSG_BTSRV_HID_CONNECTED");
  198. btsrv_hid_connected(_btsrv_get_msg_param_ptr(msg));
  199. break;
  200. case MSG_BTSRV_HID_DISCONNECTED:
  201. SYS_LOG_INF("MSG_BTSRV_HID_DISCONNECTED");
  202. btsrv_hid_disconnected(_btsrv_get_msg_param_ptr(msg));
  203. break;
  204. case MSG_BTSRV_HID_EVENT_CB:
  205. SYS_LOG_INF("MSG_BTSRV_HID_EVENT_CB");
  206. hid_event_proc(msg->ptr, _btsrv_get_msg_param_reserve(msg));
  207. case MSG_BTSRV_HID_SEND_CTRL_DATA:
  208. SYS_LOG_INF("MSG_BTSRV_HID_SEND_CTRL_DATA");
  209. btsrv_hid_send_ctrl_data(_btsrv_get_msg_param_ptr(msg));
  210. break;
  211. case MSG_BTSRV_HID_SEND_INTR_DATA:
  212. SYS_LOG_INF("MSG_BTSRV_HID_SEND_INTR_DATA");
  213. btsrv_hid_send_intr_data(_btsrv_get_msg_param_ptr(msg));
  214. break;
  215. case MSG_BTSRV_HID_SEND_RSP:
  216. SYS_LOG_INF("MSG_BTSRV_HID_SEND_RSP");
  217. btsrv_hid_send_rsp(msg->ptr, _btsrv_get_msg_param_reserve(msg));
  218. break;
  219. default:
  220. break;
  221. }
  222. return 0;
  223. }