hid.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554
  1. /*
  2. * QEMU Bluetooth HID Profile wrapper for USB HID.
  3. *
  4. * Copyright (C) 2007-2008 OpenMoko, Inc.
  5. * Written by Andrzej Zaborowski <andrew@openedhand.com>
  6. *
  7. * This program is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU General Public License as
  9. * published by the Free Software Foundation; either version 2 or
  10. * (at your option) version 3 of the License.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License along
  18. * with this program; if not, if not, see <http://www.gnu.org/licenses/>.
  19. */
  20. #include "qemu/osdep.h"
  21. #include "qemu-common.h"
  22. #include "qemu/timer.h"
  23. #include "ui/console.h"
  24. #include "hw/input/hid.h"
  25. #include "hw/bt.h"
  26. enum hid_transaction_req {
  27. BT_HANDSHAKE = 0x0,
  28. BT_HID_CONTROL = 0x1,
  29. BT_GET_REPORT = 0x4,
  30. BT_SET_REPORT = 0x5,
  31. BT_GET_PROTOCOL = 0x6,
  32. BT_SET_PROTOCOL = 0x7,
  33. BT_GET_IDLE = 0x8,
  34. BT_SET_IDLE = 0x9,
  35. BT_DATA = 0xa,
  36. BT_DATC = 0xb,
  37. };
  38. enum hid_transaction_handshake {
  39. BT_HS_SUCCESSFUL = 0x0,
  40. BT_HS_NOT_READY = 0x1,
  41. BT_HS_ERR_INVALID_REPORT_ID = 0x2,
  42. BT_HS_ERR_UNSUPPORTED_REQUEST = 0x3,
  43. BT_HS_ERR_INVALID_PARAMETER = 0x4,
  44. BT_HS_ERR_UNKNOWN = 0xe,
  45. BT_HS_ERR_FATAL = 0xf,
  46. };
  47. enum hid_transaction_control {
  48. BT_HC_NOP = 0x0,
  49. BT_HC_HARD_RESET = 0x1,
  50. BT_HC_SOFT_RESET = 0x2,
  51. BT_HC_SUSPEND = 0x3,
  52. BT_HC_EXIT_SUSPEND = 0x4,
  53. BT_HC_VIRTUAL_CABLE_UNPLUG = 0x5,
  54. };
  55. enum hid_protocol {
  56. BT_HID_PROTO_BOOT = 0,
  57. BT_HID_PROTO_REPORT = 1,
  58. };
  59. enum hid_boot_reportid {
  60. BT_HID_BOOT_INVALID = 0,
  61. BT_HID_BOOT_KEYBOARD,
  62. BT_HID_BOOT_MOUSE,
  63. };
  64. enum hid_data_pkt {
  65. BT_DATA_OTHER = 0,
  66. BT_DATA_INPUT,
  67. BT_DATA_OUTPUT,
  68. BT_DATA_FEATURE,
  69. };
  70. #define BT_HID_MTU 48
  71. /* HID interface requests */
  72. #define GET_REPORT 0xa101
  73. #define GET_IDLE 0xa102
  74. #define GET_PROTOCOL 0xa103
  75. #define SET_REPORT 0x2109
  76. #define SET_IDLE 0x210a
  77. #define SET_PROTOCOL 0x210b
  78. struct bt_hid_device_s {
  79. struct bt_l2cap_device_s btdev;
  80. struct bt_l2cap_conn_params_s *control;
  81. struct bt_l2cap_conn_params_s *interrupt;
  82. HIDState hid;
  83. int proto;
  84. int connected;
  85. int data_type;
  86. int intr_state;
  87. struct {
  88. int len;
  89. uint8_t buffer[1024];
  90. } dataother, datain, dataout, feature, intrdataout;
  91. enum {
  92. bt_state_ready,
  93. bt_state_transaction,
  94. bt_state_suspend,
  95. } state;
  96. };
  97. static void bt_hid_reset(struct bt_hid_device_s *s)
  98. {
  99. struct bt_scatternet_s *net = s->btdev.device.net;
  100. /* Go as far as... */
  101. bt_l2cap_device_done(&s->btdev);
  102. bt_l2cap_device_init(&s->btdev, net);
  103. hid_reset(&s->hid);
  104. s->proto = BT_HID_PROTO_REPORT;
  105. s->state = bt_state_ready;
  106. s->dataother.len = 0;
  107. s->datain.len = 0;
  108. s->dataout.len = 0;
  109. s->feature.len = 0;
  110. s->intrdataout.len = 0;
  111. s->intr_state = 0;
  112. }
  113. static int bt_hid_out(struct bt_hid_device_s *s)
  114. {
  115. if (s->data_type == BT_DATA_OUTPUT) {
  116. /* nothing */
  117. ;
  118. }
  119. if (s->data_type == BT_DATA_FEATURE) {
  120. /* XXX:
  121. * does this send a USB_REQ_CLEAR_FEATURE/USB_REQ_SET_FEATURE
  122. * or a SET_REPORT? */
  123. ;
  124. }
  125. return -1;
  126. }
  127. static int bt_hid_in(struct bt_hid_device_s *s)
  128. {
  129. s->datain.len = hid_keyboard_poll(&s->hid, s->datain.buffer,
  130. sizeof(s->datain.buffer));
  131. return s->datain.len;
  132. }
  133. static void bt_hid_send_handshake(struct bt_hid_device_s *s, int result)
  134. {
  135. *s->control->sdu_out(s->control, 1) =
  136. (BT_HANDSHAKE << 4) | result;
  137. s->control->sdu_submit(s->control);
  138. }
  139. static void bt_hid_send_control(struct bt_hid_device_s *s, int operation)
  140. {
  141. *s->control->sdu_out(s->control, 1) =
  142. (BT_HID_CONTROL << 4) | operation;
  143. s->control->sdu_submit(s->control);
  144. }
  145. static void bt_hid_disconnect(struct bt_hid_device_s *s)
  146. {
  147. /* Disconnect s->control and s->interrupt */
  148. }
  149. static void bt_hid_send_data(struct bt_l2cap_conn_params_s *ch, int type,
  150. const uint8_t *data, int len)
  151. {
  152. uint8_t *pkt, hdr = (BT_DATA << 4) | type;
  153. int plen;
  154. do {
  155. plen = MIN(len, ch->remote_mtu - 1);
  156. pkt = ch->sdu_out(ch, plen + 1);
  157. pkt[0] = hdr;
  158. if (plen)
  159. memcpy(pkt + 1, data, plen);
  160. ch->sdu_submit(ch);
  161. len -= plen;
  162. data += plen;
  163. hdr = (BT_DATC << 4) | type;
  164. } while (plen == ch->remote_mtu - 1);
  165. }
  166. static void bt_hid_control_transaction(struct bt_hid_device_s *s,
  167. const uint8_t *data, int len)
  168. {
  169. uint8_t type, parameter;
  170. int rlen, ret = -1;
  171. if (len < 1)
  172. return;
  173. type = data[0] >> 4;
  174. parameter = data[0] & 0xf;
  175. switch (type) {
  176. case BT_HANDSHAKE:
  177. case BT_DATA:
  178. switch (parameter) {
  179. default:
  180. /* These are not expected to be sent this direction. */
  181. ret = BT_HS_ERR_INVALID_PARAMETER;
  182. }
  183. break;
  184. case BT_HID_CONTROL:
  185. if (len != 1 || (parameter != BT_HC_VIRTUAL_CABLE_UNPLUG &&
  186. s->state == bt_state_transaction)) {
  187. ret = BT_HS_ERR_INVALID_PARAMETER;
  188. break;
  189. }
  190. switch (parameter) {
  191. case BT_HC_NOP:
  192. break;
  193. case BT_HC_HARD_RESET:
  194. case BT_HC_SOFT_RESET:
  195. bt_hid_reset(s);
  196. break;
  197. case BT_HC_SUSPEND:
  198. if (s->state == bt_state_ready)
  199. s->state = bt_state_suspend;
  200. else
  201. ret = BT_HS_ERR_INVALID_PARAMETER;
  202. break;
  203. case BT_HC_EXIT_SUSPEND:
  204. if (s->state == bt_state_suspend)
  205. s->state = bt_state_ready;
  206. else
  207. ret = BT_HS_ERR_INVALID_PARAMETER;
  208. break;
  209. case BT_HC_VIRTUAL_CABLE_UNPLUG:
  210. bt_hid_disconnect(s);
  211. break;
  212. default:
  213. ret = BT_HS_ERR_INVALID_PARAMETER;
  214. }
  215. break;
  216. case BT_GET_REPORT:
  217. /* No ReportIDs declared. */
  218. if (((parameter & 8) && len != 3) ||
  219. (!(parameter & 8) && len != 1) ||
  220. s->state != bt_state_ready) {
  221. ret = BT_HS_ERR_INVALID_PARAMETER;
  222. break;
  223. }
  224. if (parameter & 8)
  225. rlen = data[2] | (data[3] << 8);
  226. else
  227. rlen = INT_MAX;
  228. switch (parameter & 3) {
  229. case BT_DATA_OTHER:
  230. ret = BT_HS_ERR_INVALID_PARAMETER;
  231. break;
  232. case BT_DATA_INPUT:
  233. /* Here we can as well poll s->usbdev */
  234. bt_hid_send_data(s->control, BT_DATA_INPUT,
  235. s->datain.buffer, MIN(rlen, s->datain.len));
  236. break;
  237. case BT_DATA_OUTPUT:
  238. bt_hid_send_data(s->control, BT_DATA_OUTPUT,
  239. s->dataout.buffer, MIN(rlen, s->dataout.len));
  240. break;
  241. case BT_DATA_FEATURE:
  242. bt_hid_send_data(s->control, BT_DATA_FEATURE,
  243. s->feature.buffer, MIN(rlen, s->feature.len));
  244. break;
  245. }
  246. break;
  247. case BT_SET_REPORT:
  248. if (len < 2 || len > BT_HID_MTU || s->state != bt_state_ready ||
  249. (parameter & 3) == BT_DATA_OTHER ||
  250. (parameter & 3) == BT_DATA_INPUT) {
  251. ret = BT_HS_ERR_INVALID_PARAMETER;
  252. break;
  253. }
  254. s->data_type = parameter & 3;
  255. if (s->data_type == BT_DATA_OUTPUT) {
  256. s->dataout.len = len - 1;
  257. memcpy(s->dataout.buffer, data + 1, s->dataout.len);
  258. } else {
  259. s->feature.len = len - 1;
  260. memcpy(s->feature.buffer, data + 1, s->feature.len);
  261. }
  262. if (len == BT_HID_MTU)
  263. s->state = bt_state_transaction;
  264. else
  265. bt_hid_out(s);
  266. break;
  267. case BT_GET_PROTOCOL:
  268. if (len != 1 || s->state == bt_state_transaction) {
  269. ret = BT_HS_ERR_INVALID_PARAMETER;
  270. break;
  271. }
  272. *s->control->sdu_out(s->control, 1) = s->proto;
  273. s->control->sdu_submit(s->control);
  274. break;
  275. case BT_SET_PROTOCOL:
  276. if (len != 1 || s->state == bt_state_transaction ||
  277. (parameter != BT_HID_PROTO_BOOT &&
  278. parameter != BT_HID_PROTO_REPORT)) {
  279. ret = BT_HS_ERR_INVALID_PARAMETER;
  280. break;
  281. }
  282. s->proto = parameter;
  283. s->hid.protocol = parameter;
  284. ret = BT_HS_SUCCESSFUL;
  285. break;
  286. case BT_GET_IDLE:
  287. if (len != 1 || s->state == bt_state_transaction) {
  288. ret = BT_HS_ERR_INVALID_PARAMETER;
  289. break;
  290. }
  291. *s->control->sdu_out(s->control, 1) = s->hid.idle;
  292. s->control->sdu_submit(s->control);
  293. break;
  294. case BT_SET_IDLE:
  295. if (len != 2 || s->state == bt_state_transaction) {
  296. ret = BT_HS_ERR_INVALID_PARAMETER;
  297. break;
  298. }
  299. s->hid.idle = data[1];
  300. /* XXX: Does this generate a handshake? */
  301. break;
  302. case BT_DATC:
  303. if (len > BT_HID_MTU || s->state != bt_state_transaction) {
  304. ret = BT_HS_ERR_INVALID_PARAMETER;
  305. break;
  306. }
  307. if (s->data_type == BT_DATA_OUTPUT) {
  308. memcpy(s->dataout.buffer + s->dataout.len, data + 1, len - 1);
  309. s->dataout.len += len - 1;
  310. } else {
  311. memcpy(s->feature.buffer + s->feature.len, data + 1, len - 1);
  312. s->feature.len += len - 1;
  313. }
  314. if (len < BT_HID_MTU) {
  315. bt_hid_out(s);
  316. s->state = bt_state_ready;
  317. }
  318. break;
  319. default:
  320. ret = BT_HS_ERR_UNSUPPORTED_REQUEST;
  321. }
  322. if (ret != -1)
  323. bt_hid_send_handshake(s, ret);
  324. }
  325. static void bt_hid_control_sdu(void *opaque, const uint8_t *data, int len)
  326. {
  327. struct bt_hid_device_s *hid = opaque;
  328. bt_hid_control_transaction(hid, data, len);
  329. }
  330. static void bt_hid_datain(HIDState *hs)
  331. {
  332. struct bt_hid_device_s *hid =
  333. container_of(hs, struct bt_hid_device_s, hid);
  334. /* If suspended, wake-up and send a wake-up event first. We might
  335. * want to also inspect the input report and ignore event like
  336. * mouse movements until a button event occurs. */
  337. if (hid->state == bt_state_suspend) {
  338. hid->state = bt_state_ready;
  339. }
  340. if (bt_hid_in(hid) > 0)
  341. /* TODO: when in boot-mode precede any Input reports with the ReportID
  342. * byte, here and in GetReport/SetReport on the Control channel. */
  343. bt_hid_send_data(hid->interrupt, BT_DATA_INPUT,
  344. hid->datain.buffer, hid->datain.len);
  345. }
  346. static void bt_hid_interrupt_sdu(void *opaque, const uint8_t *data, int len)
  347. {
  348. struct bt_hid_device_s *hid = opaque;
  349. if (len > BT_HID_MTU || len < 1)
  350. goto bad;
  351. if ((data[0] & 3) != BT_DATA_OUTPUT)
  352. goto bad;
  353. if ((data[0] >> 4) == BT_DATA) {
  354. if (hid->intr_state)
  355. goto bad;
  356. hid->data_type = BT_DATA_OUTPUT;
  357. hid->intrdataout.len = 0;
  358. } else if ((data[0] >> 4) == BT_DATC) {
  359. if (!hid->intr_state)
  360. goto bad;
  361. } else
  362. goto bad;
  363. memcpy(hid->intrdataout.buffer + hid->intrdataout.len, data + 1, len - 1);
  364. hid->intrdataout.len += len - 1;
  365. hid->intr_state = (len == BT_HID_MTU);
  366. if (!hid->intr_state) {
  367. memcpy(hid->dataout.buffer, hid->intrdataout.buffer,
  368. hid->dataout.len = hid->intrdataout.len);
  369. bt_hid_out(hid);
  370. }
  371. return;
  372. bad:
  373. error_report("%s: bad transaction on Interrupt channel.",
  374. __func__);
  375. }
  376. /* "Virtual cable" plug/unplug event. */
  377. static void bt_hid_connected_update(struct bt_hid_device_s *hid)
  378. {
  379. int prev = hid->connected;
  380. hid->connected = hid->control && hid->interrupt;
  381. /* Stop page-/inquiry-scanning when a host is connected. */
  382. hid->btdev.device.page_scan = !hid->connected;
  383. hid->btdev.device.inquiry_scan = !hid->connected;
  384. if (hid->connected && !prev) {
  385. hid_reset(&hid->hid);
  386. hid->proto = BT_HID_PROTO_REPORT;
  387. }
  388. /* Should set HIDVirtualCable in SDP (possibly need to check that SDP
  389. * isn't destroyed yet, in case we're being called from handle_destroy) */
  390. }
  391. static void bt_hid_close_control(void *opaque)
  392. {
  393. struct bt_hid_device_s *hid = opaque;
  394. hid->control = NULL;
  395. bt_hid_connected_update(hid);
  396. }
  397. static void bt_hid_close_interrupt(void *opaque)
  398. {
  399. struct bt_hid_device_s *hid = opaque;
  400. hid->interrupt = NULL;
  401. bt_hid_connected_update(hid);
  402. }
  403. static int bt_hid_new_control_ch(struct bt_l2cap_device_s *dev,
  404. struct bt_l2cap_conn_params_s *params)
  405. {
  406. struct bt_hid_device_s *hid = (struct bt_hid_device_s *) dev;
  407. if (hid->control)
  408. return 1;
  409. hid->control = params;
  410. hid->control->opaque = hid;
  411. hid->control->close = bt_hid_close_control;
  412. hid->control->sdu_in = bt_hid_control_sdu;
  413. bt_hid_connected_update(hid);
  414. return 0;
  415. }
  416. static int bt_hid_new_interrupt_ch(struct bt_l2cap_device_s *dev,
  417. struct bt_l2cap_conn_params_s *params)
  418. {
  419. struct bt_hid_device_s *hid = (struct bt_hid_device_s *) dev;
  420. if (hid->interrupt)
  421. return 1;
  422. hid->interrupt = params;
  423. hid->interrupt->opaque = hid;
  424. hid->interrupt->close = bt_hid_close_interrupt;
  425. hid->interrupt->sdu_in = bt_hid_interrupt_sdu;
  426. bt_hid_connected_update(hid);
  427. return 0;
  428. }
  429. static void bt_hid_destroy(struct bt_device_s *dev)
  430. {
  431. struct bt_hid_device_s *hid = (struct bt_hid_device_s *) dev;
  432. if (hid->connected)
  433. bt_hid_send_control(hid, BT_HC_VIRTUAL_CABLE_UNPLUG);
  434. bt_l2cap_device_done(&hid->btdev);
  435. hid_free(&hid->hid);
  436. g_free(hid);
  437. }
  438. enum peripheral_minor_class {
  439. class_other = 0 << 4,
  440. class_keyboard = 1 << 4,
  441. class_pointing = 2 << 4,
  442. class_combo = 3 << 4,
  443. };
  444. static struct bt_device_s *bt_hid_init(struct bt_scatternet_s *net,
  445. enum peripheral_minor_class minor)
  446. {
  447. struct bt_hid_device_s *s = g_malloc0(sizeof(*s));
  448. uint32_t class =
  449. /* Format type */
  450. (0 << 0) |
  451. /* Device class */
  452. (minor << 2) |
  453. (5 << 8) | /* "Peripheral" */
  454. /* Service classes */
  455. (1 << 13) | /* Limited discoverable mode */
  456. (1 << 19); /* Capturing device (?) */
  457. bt_l2cap_device_init(&s->btdev, net);
  458. bt_l2cap_sdp_init(&s->btdev);
  459. bt_l2cap_psm_register(&s->btdev, BT_PSM_HID_CTRL,
  460. BT_HID_MTU, bt_hid_new_control_ch);
  461. bt_l2cap_psm_register(&s->btdev, BT_PSM_HID_INTR,
  462. BT_HID_MTU, bt_hid_new_interrupt_ch);
  463. hid_init(&s->hid, HID_KEYBOARD, bt_hid_datain);
  464. s->btdev.device.lmp_name = "BT Keyboard";
  465. s->btdev.device.handle_destroy = bt_hid_destroy;
  466. s->btdev.device.class[0] = (class >> 0) & 0xff;
  467. s->btdev.device.class[1] = (class >> 8) & 0xff;
  468. s->btdev.device.class[2] = (class >> 16) & 0xff;
  469. return &s->btdev.device;
  470. }
  471. struct bt_device_s *bt_keyboard_init(struct bt_scatternet_s *net)
  472. {
  473. return bt_hid_init(net, class_keyboard);
  474. }