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