bt-hid.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571
  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-common.h"
  21. #include "usb.h"
  22. #include "bt.h"
  23. enum hid_transaction_req {
  24. BT_HANDSHAKE = 0x0,
  25. BT_HID_CONTROL = 0x1,
  26. BT_GET_REPORT = 0x4,
  27. BT_SET_REPORT = 0x5,
  28. BT_GET_PROTOCOL = 0x6,
  29. BT_SET_PROTOCOL = 0x7,
  30. BT_GET_IDLE = 0x8,
  31. BT_SET_IDLE = 0x9,
  32. BT_DATA = 0xa,
  33. BT_DATC = 0xb,
  34. };
  35. enum hid_transaction_handshake {
  36. BT_HS_SUCCESSFUL = 0x0,
  37. BT_HS_NOT_READY = 0x1,
  38. BT_HS_ERR_INVALID_REPORT_ID = 0x2,
  39. BT_HS_ERR_UNSUPPORTED_REQUEST = 0x3,
  40. BT_HS_ERR_INVALID_PARAMETER = 0x4,
  41. BT_HS_ERR_UNKNOWN = 0xe,
  42. BT_HS_ERR_FATAL = 0xf,
  43. };
  44. enum hid_transaction_control {
  45. BT_HC_NOP = 0x0,
  46. BT_HC_HARD_RESET = 0x1,
  47. BT_HC_SOFT_RESET = 0x2,
  48. BT_HC_SUSPEND = 0x3,
  49. BT_HC_EXIT_SUSPEND = 0x4,
  50. BT_HC_VIRTUAL_CABLE_UNPLUG = 0x5,
  51. };
  52. enum hid_protocol {
  53. BT_HID_PROTO_BOOT = 0,
  54. BT_HID_PROTO_REPORT = 1,
  55. };
  56. enum hid_boot_reportid {
  57. BT_HID_BOOT_INVALID = 0,
  58. BT_HID_BOOT_KEYBOARD,
  59. BT_HID_BOOT_MOUSE,
  60. };
  61. enum hid_data_pkt {
  62. BT_DATA_OTHER = 0,
  63. BT_DATA_INPUT,
  64. BT_DATA_OUTPUT,
  65. BT_DATA_FEATURE,
  66. };
  67. #define BT_HID_MTU 48
  68. /* HID interface requests */
  69. #define GET_REPORT 0xa101
  70. #define GET_IDLE 0xa102
  71. #define GET_PROTOCOL 0xa103
  72. #define SET_REPORT 0x2109
  73. #define SET_IDLE 0x210a
  74. #define SET_PROTOCOL 0x210b
  75. struct bt_hid_device_s {
  76. struct bt_l2cap_device_s btdev;
  77. struct bt_l2cap_conn_params_s *control;
  78. struct bt_l2cap_conn_params_s *interrupt;
  79. USBDevice *usbdev;
  80. int proto;
  81. int connected;
  82. int data_type;
  83. int intr_state;
  84. struct {
  85. int len;
  86. uint8_t buffer[1024];
  87. } dataother, datain, dataout, feature, intrdataout;
  88. enum {
  89. bt_state_ready,
  90. bt_state_transaction,
  91. bt_state_suspend,
  92. } state;
  93. };
  94. static void bt_hid_reset(struct bt_hid_device_s *s)
  95. {
  96. struct bt_scatternet_s *net = s->btdev.device.net;
  97. /* Go as far as... */
  98. bt_l2cap_device_done(&s->btdev);
  99. bt_l2cap_device_init(&s->btdev, net);
  100. s->usbdev->info->handle_reset(s->usbdev);
  101. s->proto = BT_HID_PROTO_REPORT;
  102. s->state = bt_state_ready;
  103. s->dataother.len = 0;
  104. s->datain.len = 0;
  105. s->dataout.len = 0;
  106. s->feature.len = 0;
  107. s->intrdataout.len = 0;
  108. s->intr_state = 0;
  109. }
  110. static int bt_hid_out(struct bt_hid_device_s *s)
  111. {
  112. USBPacket p;
  113. if (s->data_type == BT_DATA_OUTPUT) {
  114. p.pid = USB_TOKEN_OUT;
  115. p.devep = 1;
  116. p.data = s->dataout.buffer;
  117. p.len = s->dataout.len;
  118. s->dataout.len = s->usbdev->info->handle_data(s->usbdev, &p);
  119. return s->dataout.len;
  120. }
  121. if (s->data_type == BT_DATA_FEATURE) {
  122. /* XXX:
  123. * does this send a USB_REQ_CLEAR_FEATURE/USB_REQ_SET_FEATURE
  124. * or a SET_REPORT? */
  125. p.devep = 0;
  126. }
  127. return -1;
  128. }
  129. static int bt_hid_in(struct bt_hid_device_s *s)
  130. {
  131. USBPacket p;
  132. p.pid = USB_TOKEN_IN;
  133. p.devep = 1;
  134. p.data = s->datain.buffer;
  135. p.len = sizeof(s->datain.buffer);
  136. s->datain.len = s->usbdev->info->handle_data(s->usbdev, &p);
  137. return s->datain.len;
  138. }
  139. static void bt_hid_send_handshake(struct bt_hid_device_s *s, int result)
  140. {
  141. *s->control->sdu_out(s->control, 1) =
  142. (BT_HANDSHAKE << 4) | result;
  143. s->control->sdu_submit(s->control);
  144. }
  145. static void bt_hid_send_control(struct bt_hid_device_s *s, int operation)
  146. {
  147. *s->control->sdu_out(s->control, 1) =
  148. (BT_HID_CONTROL << 4) | operation;
  149. s->control->sdu_submit(s->control);
  150. }
  151. static void bt_hid_disconnect(struct bt_hid_device_s *s)
  152. {
  153. /* Disconnect s->control and s->interrupt */
  154. }
  155. static void bt_hid_send_data(struct bt_l2cap_conn_params_s *ch, int type,
  156. const uint8_t *data, int len)
  157. {
  158. uint8_t *pkt, hdr = (BT_DATA << 4) | type;
  159. int plen;
  160. do {
  161. plen = MIN(len, ch->remote_mtu - 1);
  162. pkt = ch->sdu_out(ch, plen + 1);
  163. pkt[0] = hdr;
  164. if (plen)
  165. memcpy(pkt + 1, data, plen);
  166. ch->sdu_submit(ch);
  167. len -= plen;
  168. data += plen;
  169. hdr = (BT_DATC << 4) | type;
  170. } while (plen == ch->remote_mtu - 1);
  171. }
  172. static void bt_hid_control_transaction(struct bt_hid_device_s *s,
  173. const uint8_t *data, int len)
  174. {
  175. uint8_t type, parameter;
  176. int rlen, ret = -1;
  177. if (len < 1)
  178. return;
  179. type = data[0] >> 4;
  180. parameter = data[0] & 0xf;
  181. switch (type) {
  182. case BT_HANDSHAKE:
  183. case BT_DATA:
  184. switch (parameter) {
  185. default:
  186. /* These are not expected to be sent this direction. */
  187. ret = BT_HS_ERR_INVALID_PARAMETER;
  188. }
  189. break;
  190. case BT_HID_CONTROL:
  191. if (len != 1 || (parameter != BT_HC_VIRTUAL_CABLE_UNPLUG &&
  192. s->state == bt_state_transaction)) {
  193. ret = BT_HS_ERR_INVALID_PARAMETER;
  194. break;
  195. }
  196. switch (parameter) {
  197. case BT_HC_NOP:
  198. break;
  199. case BT_HC_HARD_RESET:
  200. case BT_HC_SOFT_RESET:
  201. bt_hid_reset(s);
  202. break;
  203. case BT_HC_SUSPEND:
  204. if (s->state == bt_state_ready)
  205. s->state = bt_state_suspend;
  206. else
  207. ret = BT_HS_ERR_INVALID_PARAMETER;
  208. break;
  209. case BT_HC_EXIT_SUSPEND:
  210. if (s->state == bt_state_suspend)
  211. s->state = bt_state_ready;
  212. else
  213. ret = BT_HS_ERR_INVALID_PARAMETER;
  214. break;
  215. case BT_HC_VIRTUAL_CABLE_UNPLUG:
  216. bt_hid_disconnect(s);
  217. break;
  218. default:
  219. ret = BT_HS_ERR_INVALID_PARAMETER;
  220. }
  221. break;
  222. case BT_GET_REPORT:
  223. /* No ReportIDs declared. */
  224. if (((parameter & 8) && len != 3) ||
  225. (!(parameter & 8) && len != 1) ||
  226. s->state != bt_state_ready) {
  227. ret = BT_HS_ERR_INVALID_PARAMETER;
  228. break;
  229. }
  230. if (parameter & 8)
  231. rlen = data[2] | (data[3] << 8);
  232. else
  233. rlen = INT_MAX;
  234. switch (parameter & 3) {
  235. case BT_DATA_OTHER:
  236. ret = BT_HS_ERR_INVALID_PARAMETER;
  237. break;
  238. case BT_DATA_INPUT:
  239. /* Here we can as well poll s->usbdev */
  240. bt_hid_send_data(s->control, BT_DATA_INPUT,
  241. s->datain.buffer, MIN(rlen, s->datain.len));
  242. break;
  243. case BT_DATA_OUTPUT:
  244. bt_hid_send_data(s->control, BT_DATA_OUTPUT,
  245. s->dataout.buffer, MIN(rlen, s->dataout.len));
  246. break;
  247. case BT_DATA_FEATURE:
  248. bt_hid_send_data(s->control, BT_DATA_FEATURE,
  249. s->feature.buffer, MIN(rlen, s->feature.len));
  250. break;
  251. }
  252. break;
  253. case BT_SET_REPORT:
  254. if (len < 2 || len > BT_HID_MTU || s->state != bt_state_ready ||
  255. (parameter & 3) == BT_DATA_OTHER ||
  256. (parameter & 3) == BT_DATA_INPUT) {
  257. ret = BT_HS_ERR_INVALID_PARAMETER;
  258. break;
  259. }
  260. s->data_type = parameter & 3;
  261. if (s->data_type == BT_DATA_OUTPUT) {
  262. s->dataout.len = len - 1;
  263. memcpy(s->dataout.buffer, data + 1, s->dataout.len);
  264. } else {
  265. s->feature.len = len - 1;
  266. memcpy(s->feature.buffer, data + 1, s->feature.len);
  267. }
  268. if (len == BT_HID_MTU)
  269. s->state = bt_state_transaction;
  270. else
  271. bt_hid_out(s);
  272. break;
  273. case BT_GET_PROTOCOL:
  274. if (len != 1 || s->state == bt_state_transaction) {
  275. ret = BT_HS_ERR_INVALID_PARAMETER;
  276. break;
  277. }
  278. *s->control->sdu_out(s->control, 1) = s->proto;
  279. s->control->sdu_submit(s->control);
  280. break;
  281. case BT_SET_PROTOCOL:
  282. if (len != 1 || s->state == bt_state_transaction ||
  283. (parameter != BT_HID_PROTO_BOOT &&
  284. parameter != BT_HID_PROTO_REPORT)) {
  285. ret = BT_HS_ERR_INVALID_PARAMETER;
  286. break;
  287. }
  288. s->proto = parameter;
  289. s->usbdev->info->handle_control(s->usbdev, NULL, SET_PROTOCOL, s->proto, 0, 0,
  290. NULL);
  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->info->handle_control(s->usbdev, NULL, 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->info->handle_control(s->usbdev, NULL,
  310. SET_IDLE, data[1], 0, 0, NULL) ?
  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. 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->info->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 = NULL;
  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 = NULL;
  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->info->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->product_desc;
  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. USBDevice *dev = usb_create_simple(NULL /* FIXME */, "usb-kbd");
  486. return bt_hid_init(net, dev, class_keyboard);
  487. }