tester-hidhost.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722
  1. // SPDX-License-Identifier: Apache-2.0
  2. /*
  3. * Copyright (C) 2014 Intel Corporation
  4. *
  5. */
  6. #define _GNU_SOURCE
  7. #include <stdbool.h>
  8. #include "emulator/bthost.h"
  9. #include "src/shared/tester.h"
  10. #include "src/shared/queue.h"
  11. #include "lib/bluetooth.h"
  12. #include "android/utils.h"
  13. #include "tester-main.h"
  14. #define HID_GET_REPORT_PROTOCOL 0x60
  15. #define HID_GET_BOOT_PROTOCOL 0x61
  16. #define HID_SET_REPORT_PROTOCOL 0x70
  17. #define HID_SET_BOOT_PROTOCOL 0x71
  18. #define HID_SET_INPUT_REPORT 0x51
  19. #define HID_SET_OUTPUT_REPORT 0x52
  20. #define HID_SET_FEATURE_REPORT 0x53
  21. #define HID_SEND_DATA 0xa2
  22. #define HID_GET_INPUT_REPORT 0x49
  23. #define HID_GET_OUTPUT_REPORT 0x4a
  24. #define HID_GET_FEATURE_REPORT 0x4b
  25. #define HID_MODE_DEFAULT 0x00
  26. #define HID_MODE_BREDR 0x01
  27. #define HID_MODE_LE 0x02
  28. #define HID_EXPECTED_REPORT_SIZE 0x02
  29. #define HID_VIRTUAL_CABLE_UNPLUG 0x15
  30. static struct queue *list; /* List of hidhost test cases */
  31. #define did_req_pdu 0x06, \
  32. 0x00, 0x00, \
  33. 0x00, 0x0f, \
  34. 0x35, 0x03, \
  35. 0x19, 0x12, 0x00, 0xff, 0xff, 0x35, 0x05, 0x0a, 0x00, \
  36. 0x00, 0xff, 0xff, 0x00
  37. #define did_rsp_pdu 0x07, \
  38. 0x00, 0x00, \
  39. 0x00, 0x4f, \
  40. 0x00, 0x4c, \
  41. 0x35, 0x4a, 0x35, 0x48, 0x09, 0x00, 0x00, 0x0a, 0x00, \
  42. 0x01, 0x00, 0x00, 0x09, 0x00, 0x01, 0x35, 0x03, 0x19, \
  43. 0x12, 0x00, 0x09, 0x00, 0x05, 0x35, 0x03, 0x19, 0x10, \
  44. 0x02, 0x09, 0x00, 0x09, 0x35, 0x08, 0x35, 0x06, 0x19, \
  45. 0x12, 0x00, 0x09, 0x01, 0x03, 0x09, 0x02, 0x00, 0x09, \
  46. 0x01, 0x03, 0x09, 0x02, 0x01, 0x09, 0x1d, 0x6b, 0x09, \
  47. 0x02, 0x02, 0x09, 0x02, 0x46, 0x09, 0x02, 0x03, 0x09, \
  48. 0x05, 0x0e, 0x09, 0x02, 0x04, 0x28, 0x01, 0x09, 0x02, \
  49. 0x05, 0x09, 0x00, 0x02, \
  50. 0x00
  51. #define hid_req_pdu 0x06, \
  52. 0x00, 0x01, \
  53. 0x00, 0x0f, \
  54. 0x35, 0x03, \
  55. 0x19, 0x11, 0x24, 0xff, 0xff, 0x35, 0x05, 0x0a, 0x00, \
  56. 0x00, 0xff, 0xff, 0x00
  57. #define hid_rsp_pdu 0x07, \
  58. 0x00, 0x01, \
  59. 0x01, 0x71, \
  60. 0x01, 0x6E, \
  61. 0x36, 0x01, 0x6b, 0x36, 0x01, 0x68, 0x09, 0x00, 0x00, \
  62. 0x0a, 0x00, 0x01, 0x00, 0x00, 0x09, 0x00, 0x01, 0x35, \
  63. 0x03, 0x19, 0x11, 0x24, 0x09, 0x00, 0x04, 0x35, 0x0d, \
  64. 0x35, 0x06, 0x19, 0x01, 0x00, 0x09, 0x00, 0x11, 0x35, \
  65. 0x03, 0x19, 0x00, 0x11, 0x09, 0x00, 0x05, 0x35, 0x03, \
  66. 0x19, 0x10, 0x02, 0x09, 0x00, 0x06, 0x35, 0x09, 0x09, \
  67. 0x65, 0x6e, 0x09, 0x00, 0x6a, 0x09, 0x01, 0x00, 0x09, \
  68. 0x00, 0x09, 0x35, 0x08, 0x35, 0x06, 0x19, 0x11, 0x24, \
  69. 0x09, 0x01, 0x00, 0x09, 0x00, 0x0d, 0x35, 0x0f, 0x35, \
  70. 0x0d, 0x35, 0x06, 0x19, 0x01, 0x00, 0x09, 0x00, 0x13, \
  71. 0x35, 0x03, 0x19, 0x00, 0x11, 0x09, 0x01, 0x00, 0x25, \
  72. 0x1e, 0x4c, 0x6f, 0x67, 0x69, 0x74, 0x65, 0x63, 0x68, \
  73. 0x20, 0x42, 0x6c, 0x75, 0x65, 0x74, 0x6f, 0x6f, 0x74, \
  74. 0x68, 0x20, 0x4d, 0x6f, 0x75, 0x73, 0x65, 0x20, 0x4d, \
  75. 0x35, 0x35, 0x35, 0x62, 0x09, 0x01, 0x01, 0x25, 0x0f, \
  76. 0x42, 0x6c, 0x75, 0x65, 0x74, 0x6f, 0x6f, 0x74, 0x68, \
  77. 0x20, 0x4d, 0x6f, 0x75, 0x73, 0x65, 0x09, 0x01, 0x02, \
  78. 0x25, 0x08, 0x4c, 0x6f, 0x67, 0x69, 0x74, 0x65, 0x63, \
  79. 0x68, 0x09, 0x02, 0x00, 0x09, 0x01, 0x00, 0x09, 0x02, \
  80. 0x01, 0x09, 0x01, 0x11, 0x09, 0x02, 0x02, 0x08, 0x80, \
  81. 0x09, 0x02, 0x03, 0x08, 0x21, 0x09, 0x02, 0x04, 0x28, \
  82. 0x01, 0x09, 0x02, 0x05, 0x28, 0x01, 0x09, 0x02, 0x06, \
  83. 0x35, 0x74, 0x35, 0x72, 0x08, 0x22, 0x25, 0x6e, 0x05, \
  84. 0x01, 0x09, 0x02, 0xa1, 0x01, 0x85, 0x02, 0x09, 0x01, \
  85. 0xa1, 0x00, 0x05, 0x09, 0x19, 0x01, 0x29, 0x08, 0x15, \
  86. 0x00, 0x25, 0x01, 0x75, 0x01, 0x95, 0x08, 0x81, 0x02, \
  87. 0x05, 0x01, 0x09, 0x30, 0x09, 0x31, 0x16, 0x01, 0xf8, \
  88. 0x26, 0xff, 0x07, 0x75, 0x0c, 0x95, 0x02, 0x81, 0x06, \
  89. 0x09, 0x38, 0x15, 0x81, 0x25, 0x7f, 0x75, 0x08, 0x95, \
  90. 0x01, 0x81, 0x06, 0x05, 0x0c, 0x0a, 0x38, 0x02, 0x81, \
  91. 0x06, 0x05, 0x09, 0x19, 0x09, 0x29, 0x10, 0x15, 0x00, \
  92. 0x25, 0x01, 0x95, 0x08, 0x75, 0x01, 0x81, 0x02, 0xc0, \
  93. 0xc0, 0x06, 0x00, 0xff, 0x09, 0x01, 0xa1, 0x01, 0x85, \
  94. 0x10, 0x75, 0x08, 0x95, 0x06, 0x15, 0x00, 0x26, 0xff, \
  95. 0x00, 0x09, 0x01, 0x81, 0x00, 0x09, 0x01, 0x91, 0x00, \
  96. 0xc0, 0x09, 0x02, 0x07, 0x35, 0x08, 0x35, 0x06, 0x09, \
  97. 0x04, 0x09, 0x09, 0x01, 0x00, 0x09, 0x02, 0x08, 0x28, \
  98. 0x00, 0x09, 0x02, 0x09, 0x28, 0x01, 0x09, 0x02, 0x0a, \
  99. 0x28, 0x01, 0x09, 0x02, 0x0b, 0x09, 0x01, 0x00, 0x09, \
  100. 0x02, 0x0c, 0x09, 0x0c, 0x80, 0x09, 0x02, 0x0d, 0x28, \
  101. 0x00, 0x09, 0x02, 0x0e, 0x28, 0x01, \
  102. 0x00
  103. static const struct pdu_set sdp_pdus[] = {
  104. { raw_pdu(did_req_pdu), raw_pdu(did_rsp_pdu) },
  105. { raw_pdu(hid_req_pdu), raw_pdu(hid_rsp_pdu) },
  106. { end_pdu, end_pdu },
  107. };
  108. static struct emu_l2cap_cid_data sdp_cid_data = {
  109. .pdu = sdp_pdus,
  110. .is_sdp = TRUE,
  111. };
  112. #define hid_keyboard_rsp_pdu 0x07, \
  113. 0x00, 0x01, \
  114. 0x02, 0x04, \
  115. 0x02, 0x01, \
  116. 0x36, 0x01, 0xfe, 0x36, 0x01, 0x93, 0x09, 0x00, 0x00, \
  117. 0x0a, 0x00, 0x01, 0x00, 0x00, 0x09, 0x00, 0x01, 0x35, \
  118. 0x03, 0x19, 0x11, 0x24, 0x09, 0x00, 0x04, 0x35, 0x0d, \
  119. 0x35, 0x06, 0x19, 0x01, 0x00, 0x09, 0x00, 0x11, 0x35, \
  120. 0x03, 0x19, 0x00, 0x11, 0x09, 0x00, 0x06, 0x35, 0x09, \
  121. 0x09, 0x65, 0x6e, 0x09, 0x00, 0x6a, 0x09, 0x01, 0x00, \
  122. 0x09, 0x00, 0x09, 0x35, 0x08, 0x35, 0x06, 0x19, 0x11, \
  123. 0x24, 0x09, 0x01, 0x00, 0x09, 0x00, 0x0d, 0x35, 0x0f, \
  124. 0x35, 0x0d, 0x35, 0x06, 0x19, 0x01, 0x00, 0x09, 0x00, \
  125. 0x13, 0x35, 0x03, 0x19, 0x00, 0x11, 0x09, 0x01, 0x00, \
  126. 0x25, 0x10, 0x53, 0x41, 0x4d, 0x53, 0x55, 0x4e, 0x47, \
  127. 0x20, 0x4b, 0x65, 0x79, 0x62, 0x6f, 0x61, 0x72, 0x64, \
  128. 0x09, 0x01, 0x01, 0x25, 0x08, 0x4b, 0x65, 0x79, 0x62, \
  129. 0x6f, 0x61, 0x72, 0x64, 0x09, 0x01, 0x02, 0x25, 0x0d, \
  130. 0x43, 0x53, 0x52, 0x20, 0x48, 0x49, 0x44, 0x45, 0x6e, \
  131. 0x67, 0x69, 0x6e, 0x65, 0x09, 0x02, 0x00, 0x09, 0x01, \
  132. 0x00, 0x09, 0x02, 0x01, 0x09, 0x01, 0x11, 0x09, 0x02, \
  133. 0x02, 0x08, 0x40, 0x09, 0x02, 0x03, 0x08, 0x23, 0x09, \
  134. 0x02, 0x04, 0x28, 0x01, 0x09, 0x02, 0x05, 0x28, 0x01, \
  135. 0x09, 0x02, 0x06, 0x35, 0xb7, 0x35, 0xb5, 0x08, 0x22, \
  136. 0x25, 0xb1, 0x05, 0x01, 0x09, 0x06, 0xa1, 0x01, 0x05, \
  137. 0x07, 0x85, 0x01, 0x19, 0xe0, 0x29, 0xe7, 0x15, 0x00, \
  138. 0x25, 0x01, 0x75, 0x01, 0x95, 0x08, 0x81, 0x02, 0x95, \
  139. 0x01, 0x75, 0x08, 0x81, 0x01, 0x95, 0x05, 0x75, 0x01, \
  140. 0x05, 0x08, 0x85, 0x01, 0x19, 0x01, 0x29, 0x05, 0x91, \
  141. 0x02, 0x95, 0x01, 0x75, 0x03, 0x91, 0x03, 0x95, 0x06, \
  142. 0x75, 0x08, 0x15, 0x00, 0x25, 0x65, 0x05, 0x07, 0x19, \
  143. 0x00, 0x29, 0x6f, 0x81, 0x00, 0xc0, 0x05, 0x0c, 0x09, \
  144. 0x01, 0xa1, 0x01, 0x85, 0x02, 0x05, 0x0c, 0x15, 0x00, \
  145. 0x25, 0x01, 0x75, 0x01, 0x95, 0x18, 0x09, 0xe2, 0x09, \
  146. 0xea, 0x09, 0xe9, 0x09, 0xb7, 0x09, 0xcd, 0x0a, 0x23, \
  147. 0x02, 0x0a, 0x8a, 0x01, 0x0a, 0x21, 0x02, 0x75, 0x01, \
  148. 0x95, 0x03, 0x81, 0x02, 0x75, 0x01, 0x95, 0x05, 0x81, \
  149. 0x01, 0x05, 0x08, 0x85, 0xff, 0x95, 0x01, 0x75, 0x02, \
  150. 0x09, 0x24, 0x09, 0x26, 0x81, 0x02, 0x75, 0x06, 0x81, \
  151. 0x01, 0xc0, 0x06, 0x7f, 0xff, 0x09, 0x01, 0xa1, 0x01, \
  152. 0x85, 0x03, 0x15, 0x00, 0x25, 0x01, 0x09, 0xb9, 0x09, \
  153. 0xb5, 0x09, 0xba, 0x09, 0xbb, 0x09, 0xbc, 0x09, 0xbd, \
  154. 0x09, 0xb6, 0x09, 0xb7, 0x75, 0x01, 0x95, 0x06, 0x81, \
  155. 0x02, 0x75, 0x01, 0x95, 0x02, 0x81, 0x01, 0xc0, 0x09, \
  156. 0x02, 0x07, 0x35, 0x08, 0x35, 0x06, 0x09, 0x04, 0x09, \
  157. 0x09, 0x01, 0x00, 0x09, 0x02, 0x08, 0x28, 0x00, 0x09, \
  158. 0x02, 0x09, 0x28, 0x01, 0x09, 0x02, 0x0a, 0x28, 0x01, \
  159. 0x09, 0x02, 0x0b, 0x09, 0x01, 0x00, 0x09, 0x02, 0x0c, \
  160. 0x09, 0x1f, 0x40, 0x09, 0x02, 0x0d, 0x28, 0x00, 0x09, \
  161. 0x02, 0x0e, 0x28, 0x01, 0x36, 0x00, 0x65, 0x09, 0x00, \
  162. 0x00, 0x0a, 0x00, 0x01, 0x00, 0x01, 0x09, 0x00, 0x01, \
  163. 0x35, 0x03, 0x19, 0x12, 0x00, 0x09, 0x00, 0x04, 0x35, \
  164. 0x0d, 0x35, 0x06, 0x19, 0x01, 0x00, 0x09, 0x00, 0x01, \
  165. 0x35, 0x03, 0x19, 0x00, 0x01, 0x09, 0x00, 0x06, 0x35, \
  166. 0x09, 0x09, 0x65, 0x6e, 0x09, 0x00, 0x6a, 0x09, 0x01, \
  167. 0x00, 0x09, 0x00, 0x09, 0x35, 0x08, 0x35, 0x06, 0x19, \
  168. 0x12, 0x00, 0x09, 0x01, 0x00, 0x09, 0x01, 0x01, 0x25, \
  169. 0x00, 0x09, 0x02, 0x00, 0x09, 0x01, 0x00, 0x09, 0x02, \
  170. 0x01, 0x09, 0x23, 0x3d, 0x09, 0x02, 0x02, 0x09, 0x01, \
  171. 0x3d, 0x09, 0x02, 0x03, 0x09, 0x00, 0x00, 0x09, 0x02, \
  172. 0x04, 0x28, 0x01, 0x09, 0x02, 0x05, 0x09, 0x00, 0x02, \
  173. 0x00
  174. static const struct pdu_set sdp_kb_pdus[] = {
  175. { raw_pdu(did_req_pdu), raw_pdu(did_rsp_pdu) },
  176. { raw_pdu(hid_req_pdu), raw_pdu(hid_keyboard_rsp_pdu) },
  177. { end_pdu, end_pdu },
  178. };
  179. static struct emu_l2cap_cid_data sdp_kb_cid_data = {
  180. .pdu = sdp_kb_pdus,
  181. .is_sdp = TRUE,
  182. };
  183. static struct emu_l2cap_cid_data ctrl_cid_data;
  184. static struct emu_l2cap_cid_data intr_cid_data;
  185. static void hid_prepare_reply_protocol_mode(struct emu_l2cap_cid_data *cid_data)
  186. {
  187. struct test_data *t_data = tester_get_data();
  188. struct bthost *bthost = hciemu_client_get_host(t_data->hciemu);
  189. const struct iovec pdu = raw_pdu(0xa0, 0x00);
  190. bthost_send_cid_v(bthost, cid_data->handle, cid_data->cid, &pdu, 1);
  191. }
  192. static void hid_prepare_reply_report(struct emu_l2cap_cid_data *cid_data)
  193. {
  194. struct test_data *t_data = tester_get_data();
  195. struct bthost *bthost = hciemu_client_get_host(t_data->hciemu);
  196. const struct iovec pdu = raw_pdu(0xa2, 0x01, 0x00);
  197. bthost_send_cid_v(bthost, cid_data->handle, cid_data->cid, &pdu, 1);
  198. }
  199. static void hid_ctrl_cid_hook_cb(const void *data, uint16_t len,
  200. void *user_data)
  201. {
  202. struct emu_l2cap_cid_data *cid_data = user_data;
  203. uint8_t header = ((uint8_t *) data)[0];
  204. struct step *step;
  205. switch (header) {
  206. case HID_GET_REPORT_PROTOCOL:
  207. case HID_GET_BOOT_PROTOCOL:
  208. case HID_SET_REPORT_PROTOCOL:
  209. case HID_SET_BOOT_PROTOCOL:
  210. hid_prepare_reply_protocol_mode(cid_data);
  211. break;
  212. case HID_GET_INPUT_REPORT:
  213. case HID_GET_OUTPUT_REPORT:
  214. case HID_GET_FEATURE_REPORT:
  215. hid_prepare_reply_report(cid_data);
  216. break;
  217. /*
  218. * HID device doesnot reply for this commads, so reaching pdu's
  219. * to hid device means assuming test passed
  220. */
  221. case HID_SET_INPUT_REPORT:
  222. case HID_SET_OUTPUT_REPORT:
  223. case HID_SET_FEATURE_REPORT:
  224. case HID_SEND_DATA:
  225. /* Successfully verify sending data step */
  226. step = g_new0(struct step, 1);
  227. step->callback = CB_EMU_CONFIRM_SEND_DATA;
  228. schedule_callback_verification(step);
  229. break;
  230. case HID_VIRTUAL_CABLE_UNPLUG:
  231. step = g_new0(struct step, 1);
  232. step->callback = CB_EMU_CONNECTION_REJECTED;
  233. schedule_callback_verification(step);
  234. break;
  235. }
  236. }
  237. static void hid_ctrl_connect_cb(uint16_t handle, uint16_t cid, void *user_data)
  238. {
  239. struct test_data *data = tester_get_data();
  240. struct bthost *bthost = hciemu_client_get_host(data->hciemu);
  241. struct emu_l2cap_cid_data *cid_data = user_data;
  242. cid_data->handle = handle;
  243. cid_data->cid = cid;
  244. bthost_add_cid_hook(bthost, handle, cid, hid_ctrl_cid_hook_cb,
  245. cid_data);
  246. }
  247. static void hid_intr_cid_hook_cb(const void *data, uint16_t len,
  248. void *user_data)
  249. {
  250. uint8_t header = ((uint8_t *) data)[0];
  251. struct step *step;
  252. switch (header) {
  253. case HID_SEND_DATA:
  254. /* Successfully verify sending data step */
  255. step = g_new0(struct step, 1);
  256. step->callback = CB_EMU_CONFIRM_SEND_DATA;
  257. schedule_callback_verification(step);
  258. break;
  259. }
  260. }
  261. static void hid_intr_connect_cb(uint16_t handle, uint16_t cid, void *user_data)
  262. {
  263. struct test_data *data = tester_get_data();
  264. struct bthost *bthost = hciemu_client_get_host(data->hciemu);
  265. struct emu_l2cap_cid_data *cid_data = user_data;
  266. cid_data->handle = handle;
  267. cid_data->cid = cid;
  268. bthost_add_cid_hook(bthost, handle, cid, hid_intr_cid_hook_cb,
  269. cid_data);
  270. }
  271. static bt_scan_mode_t setprop_scan_mode_conn_val = BT_SCAN_MODE_CONNECTABLE;
  272. static bt_property_t prop_test_scan_mode_conn = {
  273. .type = BT_PROPERTY_ADAPTER_SCAN_MODE,
  274. .val = &setprop_scan_mode_conn_val,
  275. .len = sizeof(setprop_scan_mode_conn_val),
  276. };
  277. /* Emulate SDP (PSM = 1) */
  278. static struct emu_set_l2cap_data l2cap_setup_sdp_data = {
  279. .psm = 1,
  280. .func = tester_generic_connect_cb,
  281. .user_data = &sdp_cid_data,
  282. };
  283. static struct emu_set_l2cap_data l2cap_setup_kb_sdp_data = {
  284. .psm = 1,
  285. .func = tester_generic_connect_cb,
  286. .user_data = &sdp_kb_cid_data,
  287. };
  288. /* Emulate Control Channel (PSM = 17) */
  289. static struct emu_set_l2cap_data l2cap_setup_cc_data = {
  290. .psm = 17,
  291. .func = hid_ctrl_connect_cb,
  292. .user_data = &ctrl_cid_data,
  293. };
  294. /* Emulate Interrupt Channel (PSM = 19) */
  295. static struct emu_set_l2cap_data l2cap_setup_ic_data = {
  296. .psm = 19,
  297. .func = hid_intr_connect_cb,
  298. .user_data = &intr_cid_data,
  299. };
  300. static void hidhost_connect_action(void)
  301. {
  302. struct test_data *data = tester_get_data();
  303. const uint8_t *hid_addr = hciemu_get_client_bdaddr(data->hciemu);
  304. struct step *step = g_new0(struct step, 1);
  305. bt_bdaddr_t bdaddr;
  306. bdaddr2android((const bdaddr_t *) hid_addr, &bdaddr);
  307. step->action_status = data->if_hid->connect(&bdaddr);
  308. schedule_action_verification(step);
  309. }
  310. static void hidhost_disconnect_action(void)
  311. {
  312. struct test_data *data = tester_get_data();
  313. const uint8_t *hid_addr = hciemu_get_client_bdaddr(data->hciemu);
  314. struct step *step = g_new0(struct step, 1);
  315. bt_bdaddr_t bdaddr;
  316. bdaddr2android((const bdaddr_t *) hid_addr, &bdaddr);
  317. step->action_status = data->if_hid->disconnect(&bdaddr);
  318. schedule_action_verification(step);
  319. }
  320. static void hidhost_virtual_unplug_action(void)
  321. {
  322. struct test_data *data = tester_get_data();
  323. const uint8_t *hid_addr = hciemu_get_client_bdaddr(data->hciemu);
  324. struct step *step = g_new0(struct step, 1);
  325. bt_bdaddr_t bdaddr;
  326. bdaddr2android((const bdaddr_t *) hid_addr, &bdaddr);
  327. step->action_status = data->if_hid->virtual_unplug(&bdaddr);
  328. schedule_action_verification(step);
  329. }
  330. static void hidhost_get_protocol_action(void)
  331. {
  332. struct test_data *data = tester_get_data();
  333. const uint8_t *hid_addr = hciemu_get_client_bdaddr(data->hciemu);
  334. struct step *step = g_new0(struct step, 1);
  335. bt_bdaddr_t bdaddr;
  336. bdaddr2android((const bdaddr_t *) hid_addr, &bdaddr);
  337. step->action_status = data->if_hid->get_protocol(&bdaddr,
  338. BTHH_REPORT_MODE);
  339. schedule_action_verification(step);
  340. }
  341. static void hidhost_set_protocol_action(void)
  342. {
  343. struct test_data *data = tester_get_data();
  344. const uint8_t *hid_addr = hciemu_get_client_bdaddr(data->hciemu);
  345. struct step *step = g_new0(struct step, 1);
  346. bt_bdaddr_t bdaddr;
  347. bdaddr2android((const bdaddr_t *) hid_addr, &bdaddr);
  348. step->action_status = data->if_hid->set_protocol(&bdaddr,
  349. BTHH_REPORT_MODE);
  350. schedule_action_verification(step);
  351. }
  352. static void hidhost_get_report_action(void)
  353. {
  354. struct test_data *data = tester_get_data();
  355. const uint8_t *hid_addr = hciemu_get_client_bdaddr(data->hciemu);
  356. struct step *step = g_new0(struct step, 1);
  357. bt_bdaddr_t bdaddr;
  358. bdaddr2android((const bdaddr_t *) hid_addr, &bdaddr);
  359. step->action_status = data->if_hid->get_report(&bdaddr,
  360. BTHH_INPUT_REPORT, 1,
  361. 20);
  362. schedule_action_verification(step);
  363. }
  364. static void hidhost_set_report_action(void)
  365. {
  366. struct test_data *data = tester_get_data();
  367. const uint8_t *hid_addr = hciemu_get_client_bdaddr(data->hciemu);
  368. struct step *step = g_new0(struct step, 1);
  369. char *buf = "fe0201";
  370. bt_bdaddr_t bdaddr;
  371. bdaddr2android((const bdaddr_t *) hid_addr, &bdaddr);
  372. step->action_status = data->if_hid->send_data(&bdaddr, buf);
  373. schedule_action_verification(step);
  374. }
  375. static void hidhost_send_data_action(void)
  376. {
  377. struct test_data *data = tester_get_data();
  378. const uint8_t *hid_addr = hciemu_get_client_bdaddr(data->hciemu);
  379. struct step *step = g_new0(struct step, 1);
  380. char *buf = "010101";
  381. bt_bdaddr_t bdaddr;
  382. bdaddr2android((const bdaddr_t *) hid_addr, &bdaddr);
  383. step->action_status = data->if_hid->set_report(&bdaddr,
  384. BTHH_INPUT_REPORT, buf);
  385. schedule_action_verification(step);
  386. }
  387. static void client_l2cap_rsp(uint8_t code, const void *data, uint16_t len,
  388. void *user_data)
  389. {
  390. struct test_data *t_data = tester_get_data();
  391. struct bthost *bthost = hciemu_client_get_host(t_data->hciemu);
  392. struct emu_l2cap_cid_data *cid_data = user_data;
  393. const uint16_t *psm = data;
  394. const struct iovec con_req = raw_pdu(0x13, 0x00, /* PSM */
  395. 0x41, 0x00); /* Source CID */
  396. if (len < sizeof(*psm)) {
  397. tester_warn("Invalid l2cap response.");
  398. return;
  399. }
  400. switch (*psm) {
  401. case 0x40:
  402. bthost_add_cid_hook(bthost, cid_data->handle, 0x40,
  403. hid_ctrl_cid_hook_cb, cid_data);
  404. bthost_l2cap_req(bthost, cid_data->handle, 0x02,
  405. con_req.iov_base, con_req.iov_len,
  406. client_l2cap_rsp, cid_data);
  407. break;
  408. case 0x41:
  409. bthost_add_cid_hook(bthost, cid_data->handle, 0x41,
  410. hid_intr_cid_hook_cb, cid_data);
  411. break;
  412. default:
  413. break;
  414. }
  415. }
  416. static void hidhost_conn_cb(uint16_t handle, void *user_data)
  417. {
  418. const struct iovec con_req = raw_pdu(0x11, 0x00, /* PSM */
  419. 0x40, 0x00); /* Source CID */
  420. struct test_data *data = tester_get_data();
  421. struct bthost *bthost = hciemu_client_get_host(data->hciemu);
  422. if (data->hciemu_type == HCIEMU_TYPE_BREDR) {
  423. tester_warn("Not handled device type.");
  424. return;
  425. }
  426. ctrl_cid_data.cid = 0x40;
  427. ctrl_cid_data.handle = handle;
  428. tester_print("Sending L2CAP Request from remote");
  429. bthost_l2cap_req(bthost, handle, 0x02, con_req.iov_base,
  430. con_req.iov_len, client_l2cap_rsp,
  431. &ctrl_cid_data);
  432. }
  433. static struct test_case test_cases[] = {
  434. TEST_CASE_BREDRLE("HidHost Init",
  435. ACTION_SUCCESS(dummy_action, NULL),
  436. ),
  437. TEST_CASE_BREDRLE("HidHost Connect Success",
  438. ACTION_SUCCESS(bluetooth_enable_action, NULL),
  439. CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON),
  440. ACTION_SUCCESS(emu_setup_powered_remote_action, NULL),
  441. ACTION_SUCCESS(emu_set_ssp_mode_action, NULL),
  442. ACTION_SUCCESS(emu_add_l2cap_server_action,
  443. &l2cap_setup_sdp_data),
  444. ACTION_SUCCESS(emu_add_l2cap_server_action,
  445. &l2cap_setup_cc_data),
  446. ACTION_SUCCESS(emu_add_l2cap_server_action,
  447. &l2cap_setup_ic_data),
  448. ACTION_SUCCESS(hidhost_connect_action, NULL),
  449. CALLBACK_STATE(CB_HH_CONNECTION_STATE,
  450. BTHH_CONN_STATE_CONNECTED),
  451. ACTION_SUCCESS(bluetooth_disable_action, NULL),
  452. CALLBACK_STATE(CB_HH_CONNECTION_STATE,
  453. BTHH_CONN_STATE_DISCONNECTED),
  454. CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF),
  455. ),
  456. TEST_CASE_BREDRLE("HidHost Disconnect Success",
  457. ACTION_SUCCESS(bluetooth_enable_action, NULL),
  458. CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON),
  459. ACTION_SUCCESS(emu_setup_powered_remote_action, NULL),
  460. ACTION_SUCCESS(emu_set_ssp_mode_action, NULL),
  461. ACTION_SUCCESS(emu_add_l2cap_server_action,
  462. &l2cap_setup_sdp_data),
  463. ACTION_SUCCESS(emu_add_l2cap_server_action,
  464. &l2cap_setup_cc_data),
  465. ACTION_SUCCESS(emu_add_l2cap_server_action,
  466. &l2cap_setup_ic_data),
  467. ACTION_SUCCESS(hidhost_connect_action, NULL),
  468. CALLBACK_STATE(CB_HH_CONNECTION_STATE,
  469. BTHH_CONN_STATE_CONNECTED),
  470. ACTION_SUCCESS(hidhost_disconnect_action, NULL),
  471. CALLBACK_STATE(CB_HH_CONNECTION_STATE,
  472. BTHH_CONN_STATE_DISCONNECTED),
  473. ),
  474. TEST_CASE_BREDRLE("HidHost VirtualUnplug Success",
  475. ACTION_SUCCESS(bluetooth_enable_action, NULL),
  476. CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON),
  477. ACTION_SUCCESS(emu_setup_powered_remote_action, NULL),
  478. ACTION_SUCCESS(emu_set_ssp_mode_action, NULL),
  479. ACTION_SUCCESS(emu_add_l2cap_server_action,
  480. &l2cap_setup_sdp_data),
  481. ACTION_SUCCESS(emu_add_l2cap_server_action,
  482. &l2cap_setup_cc_data),
  483. ACTION_SUCCESS(emu_add_l2cap_server_action,
  484. &l2cap_setup_ic_data),
  485. ACTION_SUCCESS(hidhost_connect_action, NULL),
  486. CALLBACK_STATE(CB_HH_CONNECTION_STATE,
  487. BTHH_CONN_STATE_CONNECTED),
  488. ACTION_SUCCESS(hidhost_virtual_unplug_action, NULL),
  489. CALLBACK_STATE(CB_HH_CONNECTION_STATE,
  490. BTHH_CONN_STATE_DISCONNECTED),
  491. ),
  492. TEST_CASE_BREDRLE("HidHost GetProtocol Success",
  493. ACTION_SUCCESS(bluetooth_enable_action, NULL),
  494. CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON),
  495. ACTION_SUCCESS(emu_setup_powered_remote_action, NULL),
  496. ACTION_SUCCESS(emu_set_ssp_mode_action, NULL),
  497. ACTION_SUCCESS(emu_add_l2cap_server_action,
  498. &l2cap_setup_sdp_data),
  499. ACTION_SUCCESS(emu_add_l2cap_server_action,
  500. &l2cap_setup_cc_data),
  501. ACTION_SUCCESS(emu_add_l2cap_server_action,
  502. &l2cap_setup_ic_data),
  503. ACTION_SUCCESS(hidhost_connect_action, NULL),
  504. CALLBACK_STATE(CB_HH_CONNECTION_STATE,
  505. BTHH_CONN_STATE_CONNECTED),
  506. ACTION_SUCCESS(hidhost_get_protocol_action, NULL),
  507. CALLBACK_HH_MODE(CB_HH_PROTOCOL_MODE, BTHH_OK, HID_MODE_BREDR),
  508. ),
  509. TEST_CASE_BREDRLE("HidHost SetProtocol Success",
  510. ACTION_SUCCESS(bluetooth_enable_action, NULL),
  511. CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON),
  512. ACTION_SUCCESS(emu_setup_powered_remote_action, NULL),
  513. ACTION_SUCCESS(emu_set_ssp_mode_action, NULL),
  514. ACTION_SUCCESS(emu_add_l2cap_server_action,
  515. &l2cap_setup_sdp_data),
  516. ACTION_SUCCESS(emu_add_l2cap_server_action,
  517. &l2cap_setup_cc_data),
  518. ACTION_SUCCESS(emu_add_l2cap_server_action,
  519. &l2cap_setup_ic_data),
  520. ACTION_SUCCESS(hidhost_connect_action, NULL),
  521. CALLBACK_STATE(CB_HH_CONNECTION_STATE,
  522. BTHH_CONN_STATE_CONNECTED),
  523. ACTION_SUCCESS(hidhost_set_protocol_action, NULL),
  524. CALLBACK_HH_MODE(CB_HH_PROTOCOL_MODE, BTHH_OK, HID_MODE_BREDR),
  525. ),
  526. TEST_CASE_BREDRLE("HidHost GetReport Success",
  527. ACTION_SUCCESS(bluetooth_enable_action, NULL),
  528. CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON),
  529. ACTION_SUCCESS(emu_setup_powered_remote_action, NULL),
  530. ACTION_SUCCESS(emu_set_ssp_mode_action, NULL),
  531. ACTION_SUCCESS(emu_add_l2cap_server_action,
  532. &l2cap_setup_sdp_data),
  533. ACTION_SUCCESS(emu_add_l2cap_server_action,
  534. &l2cap_setup_cc_data),
  535. ACTION_SUCCESS(emu_add_l2cap_server_action,
  536. &l2cap_setup_ic_data),
  537. ACTION_SUCCESS(hidhost_connect_action, NULL),
  538. CALLBACK_STATE(CB_HH_CONNECTION_STATE,
  539. BTHH_CONN_STATE_CONNECTED),
  540. ACTION_SUCCESS(hidhost_get_report_action, NULL),
  541. CALLBACK_HHREPORT(CB_HH_GET_REPORT, BTHH_OK,
  542. HID_EXPECTED_REPORT_SIZE),
  543. ),
  544. TEST_CASE_BREDRLE("HidHost SetReport Success",
  545. ACTION_SUCCESS(bluetooth_enable_action, NULL),
  546. CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON),
  547. ACTION_SUCCESS(emu_setup_powered_remote_action, NULL),
  548. ACTION_SUCCESS(emu_set_ssp_mode_action, NULL),
  549. ACTION_SUCCESS(emu_add_l2cap_server_action,
  550. &l2cap_setup_sdp_data),
  551. ACTION_SUCCESS(emu_add_l2cap_server_action,
  552. &l2cap_setup_cc_data),
  553. ACTION_SUCCESS(emu_add_l2cap_server_action,
  554. &l2cap_setup_ic_data),
  555. ACTION_SUCCESS(hidhost_connect_action, NULL),
  556. CALLBACK_STATE(CB_HH_CONNECTION_STATE,
  557. BTHH_CONN_STATE_CONNECTING),
  558. CALLBACK_STATE(CB_HH_CONNECTION_STATE,
  559. BTHH_CONN_STATE_CONNECTED),
  560. ACTION_SUCCESS(hidhost_set_report_action, NULL),
  561. CALLBACK(CB_EMU_CONFIRM_SEND_DATA),
  562. ),
  563. TEST_CASE_BREDRLE("HidHost SendData Success",
  564. ACTION_SUCCESS(bluetooth_enable_action, NULL),
  565. CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON),
  566. ACTION_SUCCESS(emu_setup_powered_remote_action, NULL),
  567. ACTION_SUCCESS(emu_set_ssp_mode_action, NULL),
  568. ACTION_SUCCESS(emu_add_l2cap_server_action,
  569. &l2cap_setup_sdp_data),
  570. ACTION_SUCCESS(emu_add_l2cap_server_action,
  571. &l2cap_setup_cc_data),
  572. ACTION_SUCCESS(emu_add_l2cap_server_action,
  573. &l2cap_setup_ic_data),
  574. ACTION_SUCCESS(hidhost_connect_action, NULL),
  575. CALLBACK_STATE(CB_HH_CONNECTION_STATE,
  576. BTHH_CONN_STATE_CONNECTED),
  577. ACTION_SUCCESS(hidhost_send_data_action, NULL),
  578. CALLBACK(CB_EMU_CONFIRM_SEND_DATA),
  579. ),
  580. TEST_CASE_BREDRLE("HidHost Connect Encrypted Success",
  581. ACTION_SUCCESS(bluetooth_enable_action, NULL),
  582. CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON),
  583. ACTION_SUCCESS(emu_setup_powered_remote_action, NULL),
  584. ACTION_SUCCESS(emu_set_ssp_mode_action, NULL),
  585. ACTION_SUCCESS(set_default_ssp_request_handler, NULL),
  586. ACTION_SUCCESS(emu_add_l2cap_server_action,
  587. &l2cap_setup_kb_sdp_data),
  588. ACTION_SUCCESS(emu_add_l2cap_server_action,
  589. &l2cap_setup_cc_data),
  590. ACTION_SUCCESS(emu_add_l2cap_server_action,
  591. &l2cap_setup_ic_data),
  592. ACTION_SUCCESS(hidhost_connect_action, NULL),
  593. CALLBACK(CB_EMU_ENCRYPTION_ENABLED),
  594. CALLBACK_STATE(CB_HH_CONNECTION_STATE,
  595. BTHH_CONN_STATE_CONNECTED),
  596. ACTION_SUCCESS(hidhost_send_data_action, NULL),
  597. ACTION_SUCCESS(bluetooth_disable_action, NULL),
  598. CALLBACK_STATE(CB_HH_CONNECTION_STATE,
  599. BTHH_CONN_STATE_DISCONNECTED),
  600. CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF),
  601. ),
  602. TEST_CASE_BREDRLE("HidHost Reject Unknown Remote Connection",
  603. ACTION_SUCCESS(bluetooth_enable_action, NULL),
  604. CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON),
  605. ACTION_SUCCESS(bt_set_property_action,
  606. &prop_test_scan_mode_conn),
  607. CALLBACK_ADAPTER_PROPS(&prop_test_scan_mode_conn, 1),
  608. ACTION_SUCCESS(emu_setup_powered_remote_action, NULL),
  609. ACTION_SUCCESS(emu_add_l2cap_server_action,
  610. &l2cap_setup_kb_sdp_data),
  611. ACTION_SUCCESS(emu_add_l2cap_server_action,
  612. &l2cap_setup_cc_data),
  613. ACTION_SUCCESS(emu_add_l2cap_server_action,
  614. &l2cap_setup_ic_data),
  615. /* Trigger incoming connection */
  616. ACTION_SUCCESS(emu_set_connect_cb_action, hidhost_conn_cb),
  617. ACTION_SUCCESS(emu_remote_connect_hci_action, NULL),
  618. CALLBACK(CB_EMU_CONNECTION_REJECTED),
  619. ),
  620. };
  621. struct queue *get_hidhost_tests(void)
  622. {
  623. uint16_t i = 0;
  624. list = queue_new();
  625. for (; i < sizeof(test_cases) / sizeof(test_cases[0]); ++i)
  626. queue_push_tail(list, &test_cases[i]);
  627. return list;
  628. }
  629. void remove_hidhost_tests(void)
  630. {
  631. queue_destroy(list, NULL);
  632. }