bt-hid.c 16 KB

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