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