1 /* $NetBSD: btmagic.c,v 1.1 2010/05/22 18:56:01 plunky Exp $ */ 2 3 /*- 4 * Copyright (c) 2010 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Iain Hibbert. 9 * 10 * This code is derived from software contributed to The NetBSD Foundation 11 * by Lennart Augustsson (lennart@augustsson.net) at 12 * Carlstedt Research & Technology. 13 * 14 * Redistribution and use in source and binary forms, with or without 15 * modification, are permitted provided that the following conditions 16 * are met: 17 * 1. Redistributions of source code must retain the above copyright 18 * notice, this list of conditions and the following disclaimer. 19 * 2. Redistributions in binary form must reproduce the above copyright 20 * notice, this list of conditions and the following disclaimer in the 21 * documentation and/or other materials provided with the distribution. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 24 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 25 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 26 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 27 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 28 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 29 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 30 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 31 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 32 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 33 * POSSIBILITY OF SUCH DAMAGE. 34 */ 35 /*- 36 * Copyright (c) 2006 Itronix Inc. 37 * All rights reserved. 38 * 39 * Written by Iain Hibbert for Itronix Inc. 40 * 41 * Redistribution and use in source and binary forms, with or without 42 * modification, are permitted provided that the following conditions 43 * are met: 44 * 1. Redistributions of source code must retain the above copyright 45 * notice, this list of conditions and the following disclaimer. 46 * 2. Redistributions in binary form must reproduce the above copyright 47 * notice, this list of conditions and the following disclaimer in the 48 * documentation and/or other materials provided with the distribution. 49 * 3. The name of Itronix Inc. may not be used to endorse 50 * or promote products derived from this software without specific 51 * prior written permission. 52 * 53 * THIS SOFTWARE IS PROVIDED BY ITRONIX INC. ``AS IS'' AND 54 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 55 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 56 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ITRONIX INC. BE LIABLE FOR ANY 57 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 58 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 59 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 60 * ON ANY THEORY OF LIABILITY, WHETHER IN 61 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 62 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 63 * POSSIBILITY OF SUCH DAMAGE. 64 */ 65 66 67 /***************************************************************************** 68 * 69 * Apple Bluetooth Magic Mouse driver 70 * 71 * The Apple Magic Mouse is a HID device but it doesn't provide a proper HID 72 * descriptor, and requires extra initializations to enable the proprietary 73 * touch reports. We match against the vendor-id and product-id and provide 74 * our own Bluetooth connection handling as the bthidev driver does not cater 75 * for such complications. 76 * 77 * This driver interprets the touch reports only as far as emulating a 78 * middle mouse button and providing horizontal and vertical scroll action. 79 * Full gesture support would be more complicated and is left as an exercise 80 * for the reader. 81 * 82 * Credit for decoding the proprietary touch reports goes to Michael Poole 83 * who wrote the Linux hid-magicmouse input driver. 84 * 85 *****************************************************************************/ 86 87 #include <sys/cdefs.h> 88 __KERNEL_RCSID(0, "$NetBSD: btmagic.c,v 1.1 2010/05/22 18:56:01 plunky Exp $"); 89 90 #include <sys/param.h> 91 #include <sys/conf.h> 92 #include <sys/device.h> 93 #include <sys/fcntl.h> 94 #include <sys/kernel.h> 95 #include <sys/malloc.h> 96 #include <sys/mbuf.h> 97 #include <sys/proc.h> 98 #include <sys/socketvar.h> 99 #include <sys/systm.h> 100 #include <sys/sysctl.h> 101 102 #include <prop/proplib.h> 103 104 #include <netbt/bluetooth.h> 105 #include <netbt/l2cap.h> 106 107 #include <dev/bluetooth/btdev.h> 108 #include <dev/bluetooth/bthid.h> 109 #include <dev/bluetooth/bthidev.h> 110 111 #include <dev/usb/hid.h> 112 #include <dev/usb/usb.h> 113 #include <dev/usb/usbdevs.h> 114 115 #include <dev/wscons/wsconsio.h> 116 #include <dev/wscons/wsmousevar.h> 117 118 #undef DPRINTF 119 #ifdef BTMAGIC_DEBUG 120 #define DPRINTF(sc, ...) do { \ 121 printf("%s: ", device_xname((sc)->sc_dev)); \ 122 printf(__VA_ARGS__); \ 123 printf("\n"); \ 124 } while (/*CONSTCOND*/0) 125 #else 126 #define DPRINTF(...) (void)0 127 #endif 128 129 struct btmagic_softc { 130 bdaddr_t sc_laddr; /* local address */ 131 bdaddr_t sc_raddr; /* remote address */ 132 struct sockopt sc_mode; /* link mode */ 133 134 device_t sc_dev; 135 uint16_t sc_state; 136 uint16_t sc_flags; 137 138 callout_t sc_timeout; 139 140 /* control */ 141 struct l2cap_channel *sc_ctl; 142 struct l2cap_channel *sc_ctl_l; 143 144 /* interrupt */ 145 struct l2cap_channel *sc_int; 146 struct l2cap_channel *sc_int_l; 147 148 /* wsmouse child */ 149 device_t sc_wsmouse; 150 int sc_enabled; 151 152 /* config */ 153 int sc_resolution; /* for soft scaling */ 154 int sc_firm; /* firm touch threshold */ 155 int sc_dist; /* scroll distance threshold */ 156 int sc_scale; /* scroll descaling */ 157 struct sysctllog *sc_log; /* sysctl teardown log */ 158 159 /* remainders */ 160 int sc_rx; 161 int sc_ry; 162 int sc_rz; 163 int sc_rw; 164 165 /* previous touches */ 166 uint32_t sc_smask; /* scrolling */ 167 int sc_az[16]; 168 int sc_aw[16]; 169 170 /* previous mouse buttons */ 171 uint32_t sc_mb; 172 }; 173 174 /* sc_flags */ 175 #define BTMAGIC_CONNECTING __BIT(0) /* we are connecting */ 176 #define BTMAGIC_ENABLED __BIT(1) /* touch reports enabled */ 177 178 /* sc_state */ 179 #define BTMAGIC_CLOSED 0 180 #define BTMAGIC_WAIT_CTL 1 181 #define BTMAGIC_WAIT_INT 2 182 #define BTMAGIC_OPEN 3 183 184 /* autoconf(9) glue */ 185 static int btmagic_match(device_t, cfdata_t, void *); 186 static void btmagic_attach(device_t, device_t, void *); 187 static int btmagic_detach(device_t, int); 188 static int btmagic_listen(struct btmagic_softc *); 189 static int btmagic_connect(struct btmagic_softc *); 190 static int btmagic_sysctl_resolution(SYSCTLFN_PROTO); 191 static int btmagic_sysctl_scale(SYSCTLFN_PROTO); 192 193 CFATTACH_DECL_NEW(btmagic, sizeof(struct btmagic_softc), 194 btmagic_match, btmagic_attach, btmagic_detach, NULL); 195 196 /* wsmouse(4) accessops */ 197 static int btmagic_wsmouse_enable(void *); 198 static int btmagic_wsmouse_ioctl(void *, unsigned long, void *, int, struct lwp *); 199 static void btmagic_wsmouse_disable(void *); 200 201 static const struct wsmouse_accessops btmagic_wsmouse_accessops = { 202 btmagic_wsmouse_enable, 203 btmagic_wsmouse_ioctl, 204 btmagic_wsmouse_disable, 205 }; 206 207 /* bluetooth(9) protocol methods for L2CAP */ 208 static void btmagic_connecting(void *); 209 static void btmagic_ctl_connected(void *); 210 static void btmagic_int_connected(void *); 211 static void btmagic_ctl_disconnected(void *, int); 212 static void btmagic_int_disconnected(void *, int); 213 static void *btmagic_ctl_newconn(void *, struct sockaddr_bt *, struct sockaddr_bt *); 214 static void *btmagic_int_newconn(void *, struct sockaddr_bt *, struct sockaddr_bt *); 215 static void btmagic_complete(void *, int); 216 static void btmagic_linkmode(void *, int); 217 static void btmagic_input(void *, struct mbuf *); 218 static void btmagic_input_basic(struct btmagic_softc *, uint8_t *, size_t); 219 static void btmagic_input_magic(struct btmagic_softc *, uint8_t *, size_t); 220 221 static const struct btproto btmagic_ctl_proto = { 222 btmagic_connecting, 223 btmagic_ctl_connected, 224 btmagic_ctl_disconnected, 225 btmagic_ctl_newconn, 226 btmagic_complete, 227 btmagic_linkmode, 228 btmagic_input, 229 }; 230 231 static const struct btproto btmagic_int_proto = { 232 btmagic_connecting, 233 btmagic_int_connected, 234 btmagic_int_disconnected, 235 btmagic_int_newconn, 236 btmagic_complete, 237 btmagic_linkmode, 238 btmagic_input, 239 }; 240 241 /* btmagic internals */ 242 static void btmagic_timeout(void *); 243 static int btmagic_ctl_send(struct btmagic_softc *, const uint8_t *, size_t); 244 static void btmagic_enable(struct btmagic_softc *); 245 static void btmagic_check_battery(struct btmagic_softc *); 246 static int btmagic_scale(int, int *, int); 247 248 249 /***************************************************************************** 250 * 251 * Magic Mouse autoconf(9) routines 252 */ 253 254 static int 255 btmagic_match(device_t self, cfdata_t cfdata, void *aux) 256 { 257 uint16_t v, p; 258 259 if (prop_dictionary_get_uint16(aux, BTDEVvendor, &v) 260 && prop_dictionary_get_uint16(aux, BTDEVproduct, &p) 261 && v == USB_VENDOR_APPLE 262 && p == USB_PRODUCT_APPLE_MAGICMOUSE) 263 return 2; /* trump bthidev(4) */ 264 265 return 0; 266 } 267 268 static void 269 btmagic_attach(device_t parent, device_t self, void *aux) 270 { 271 struct btmagic_softc *sc = device_private(self); 272 struct wsmousedev_attach_args wsma; 273 const struct sysctlnode *node; 274 prop_object_t obj; 275 276 /* 277 * Init softc 278 */ 279 sc->sc_dev = self; 280 sc->sc_state = BTMAGIC_CLOSED; 281 callout_init(&sc->sc_timeout, 0); 282 callout_setfunc(&sc->sc_timeout, btmagic_timeout, sc); 283 sockopt_init(&sc->sc_mode, BTPROTO_L2CAP, SO_L2CAP_LM, 0); 284 285 /* 286 * extract config from proplist 287 */ 288 obj = prop_dictionary_get(aux, BTDEVladdr); 289 bdaddr_copy(&sc->sc_laddr, prop_data_data_nocopy(obj)); 290 291 obj = prop_dictionary_get(aux, BTDEVraddr); 292 bdaddr_copy(&sc->sc_raddr, prop_data_data_nocopy(obj)); 293 294 obj = prop_dictionary_get(aux, BTDEVmode); 295 if (prop_object_type(obj) == PROP_TYPE_STRING) { 296 if (prop_string_equals_cstring(obj, BTDEVauth)) 297 sockopt_setint(&sc->sc_mode, L2CAP_LM_AUTH); 298 else if (prop_string_equals_cstring(obj, BTDEVencrypt)) 299 sockopt_setint(&sc->sc_mode, L2CAP_LM_ENCRYPT); 300 else if (prop_string_equals_cstring(obj, BTDEVsecure)) 301 sockopt_setint(&sc->sc_mode, L2CAP_LM_SECURE); 302 else { 303 aprint_error(" unknown %s\n", BTDEVmode); 304 return; 305 } 306 307 aprint_verbose(" %s %s", BTDEVmode, 308 prop_string_cstring_nocopy(obj)); 309 } 310 311 aprint_normal(": 3 buttons, W and Z dirs\n"); 312 aprint_naive("\n"); 313 314 /* 315 * set defaults 316 */ 317 sc->sc_resolution = 650; 318 sc->sc_firm = 6; 319 sc->sc_dist = 130; 320 sc->sc_scale = 20; 321 322 sysctl_createv(&sc->sc_log, 0, NULL, NULL, 323 CTLFLAG_PERMANENT, 324 CTLTYPE_NODE, "hw", 325 NULL, 326 NULL, 0, 327 NULL, 0, 328 CTL_HW, CTL_EOL); 329 330 sysctl_createv(&sc->sc_log, 0, NULL, &node, 331 0, 332 CTLTYPE_NODE, device_xname(self), 333 NULL, 334 NULL, 0, 335 NULL, 0, 336 CTL_HW, 337 CTL_CREATE, CTL_EOL); 338 339 if (node != NULL) { 340 sysctl_createv(&sc->sc_log, 0, NULL, NULL, 341 CTLFLAG_READWRITE, 342 CTLTYPE_INT, "soft_resolution", 343 NULL, 344 btmagic_sysctl_resolution, 0, 345 sc, 0, 346 CTL_HW, node->sysctl_num, 347 CTL_CREATE, CTL_EOL); 348 349 sysctl_createv(&sc->sc_log, 0, NULL, NULL, 350 CTLFLAG_READWRITE, 351 CTLTYPE_INT, "firm_touch_threshold", 352 NULL, 353 NULL, 0, 354 &sc->sc_firm, sizeof(sc->sc_firm), 355 CTL_HW, node->sysctl_num, 356 CTL_CREATE, CTL_EOL); 357 358 sysctl_createv(&sc->sc_log, 0, NULL, NULL, 359 CTLFLAG_READWRITE, 360 CTLTYPE_INT, "scroll_distance_threshold", 361 NULL, 362 NULL, 0, 363 &sc->sc_dist, sizeof(sc->sc_dist), 364 CTL_HW, node->sysctl_num, 365 CTL_CREATE, CTL_EOL); 366 367 sysctl_createv(&sc->sc_log, 0, NULL, NULL, 368 CTLFLAG_READWRITE, 369 CTLTYPE_INT, "scroll_downscale_factor", 370 NULL, 371 btmagic_sysctl_scale, 0, 372 sc, 0, 373 CTL_HW, node->sysctl_num, 374 CTL_CREATE, CTL_EOL); 375 } 376 377 /* 378 * attach the wsmouse 379 */ 380 wsma.accessops = &btmagic_wsmouse_accessops; 381 wsma.accesscookie = self; 382 sc->sc_wsmouse = config_found(self, &wsma, wsmousedevprint); 383 if (sc->sc_wsmouse == NULL) { 384 aprint_error_dev(self, "failed to attach wsmouse\n"); 385 return; 386 } 387 388 /* 389 * start bluetooth connections 390 */ 391 mutex_enter(bt_lock); 392 btmagic_listen(sc); 393 btmagic_connect(sc); 394 mutex_exit(bt_lock); 395 } 396 397 static int 398 btmagic_detach(device_t self, int flags) 399 { 400 struct btmagic_softc *sc = device_private(self); 401 int err = 0; 402 403 mutex_enter(bt_lock); 404 405 /* release interrupt listen */ 406 if (sc->sc_int_l != NULL) { 407 l2cap_detach(&sc->sc_int_l); 408 sc->sc_int_l = NULL; 409 } 410 411 /* release control listen */ 412 if (sc->sc_ctl_l != NULL) { 413 l2cap_detach(&sc->sc_ctl_l); 414 sc->sc_ctl_l = NULL; 415 } 416 417 /* close interrupt channel */ 418 if (sc->sc_int != NULL) { 419 l2cap_disconnect(sc->sc_int, 0); 420 l2cap_detach(&sc->sc_int); 421 sc->sc_int = NULL; 422 } 423 424 /* close control channel */ 425 if (sc->sc_ctl != NULL) { 426 l2cap_disconnect(sc->sc_ctl, 0); 427 l2cap_detach(&sc->sc_ctl); 428 sc->sc_ctl = NULL; 429 } 430 431 callout_halt(&sc->sc_timeout, bt_lock); 432 callout_destroy(&sc->sc_timeout); 433 434 mutex_exit(bt_lock); 435 436 sockopt_destroy(&sc->sc_mode); 437 438 sysctl_teardown(&sc->sc_log); 439 440 if (sc->sc_wsmouse != NULL) { 441 err = config_detach(sc->sc_wsmouse, flags); 442 sc->sc_wsmouse = NULL; 443 } 444 445 return err; 446 } 447 448 /* 449 * listen for our device 450 * 451 * bt_lock is held 452 */ 453 static int 454 btmagic_listen(struct btmagic_softc *sc) 455 { 456 struct sockaddr_bt sa; 457 int err; 458 459 memset(&sa, 0, sizeof(sa)); 460 sa.bt_len = sizeof(sa); 461 sa.bt_family = AF_BLUETOOTH; 462 bdaddr_copy(&sa.bt_bdaddr, &sc->sc_laddr); 463 464 /* 465 * Listen on control PSM 466 */ 467 err = l2cap_attach(&sc->sc_ctl_l, &btmagic_ctl_proto, sc); 468 if (err) 469 return err; 470 471 err = l2cap_setopt(sc->sc_ctl_l, &sc->sc_mode); 472 if (err) 473 return err; 474 475 sa.bt_psm = L2CAP_PSM_HID_CNTL; 476 err = l2cap_bind(sc->sc_ctl_l, &sa); 477 if (err) 478 return err; 479 480 err = l2cap_listen(sc->sc_ctl_l); 481 if (err) 482 return err; 483 484 /* 485 * Listen on interrupt PSM 486 */ 487 err = l2cap_attach(&sc->sc_int_l, &btmagic_int_proto, sc); 488 if (err) 489 return err; 490 491 err = l2cap_setopt(sc->sc_int_l, &sc->sc_mode); 492 if (err) 493 return err; 494 495 sa.bt_psm = L2CAP_PSM_HID_INTR; 496 err = l2cap_bind(sc->sc_int_l, &sa); 497 if (err) 498 return err; 499 500 err = l2cap_listen(sc->sc_int_l); 501 if (err) 502 return err; 503 504 sc->sc_state = BTMAGIC_WAIT_CTL; 505 return 0; 506 } 507 508 /* 509 * start connecting to our device 510 * 511 * bt_lock is held 512 */ 513 static int 514 btmagic_connect(struct btmagic_softc *sc) 515 { 516 struct sockaddr_bt sa; 517 int err; 518 519 memset(&sa, 0, sizeof(sa)); 520 sa.bt_len = sizeof(sa); 521 sa.bt_family = AF_BLUETOOTH; 522 523 err = l2cap_attach(&sc->sc_ctl, &btmagic_ctl_proto, sc); 524 if (err) { 525 printf("%s: l2cap_attach failed (%d)\n", 526 device_xname(sc->sc_dev), err); 527 return err; 528 } 529 530 err = l2cap_setopt(sc->sc_ctl, &sc->sc_mode); 531 if (err) 532 return err; 533 534 bdaddr_copy(&sa.bt_bdaddr, &sc->sc_laddr); 535 err = l2cap_bind(sc->sc_ctl, &sa); 536 if (err) { 537 printf("%s: l2cap_bind failed (%d)\n", 538 device_xname(sc->sc_dev), err); 539 return err; 540 } 541 542 sa.bt_psm = L2CAP_PSM_HID_CNTL; 543 bdaddr_copy(&sa.bt_bdaddr, &sc->sc_raddr); 544 err = l2cap_connect(sc->sc_ctl, &sa); 545 if (err) { 546 printf("%s: l2cap_connect failed (%d)\n", 547 device_xname(sc->sc_dev), err); 548 return err; 549 } 550 551 SET(sc->sc_flags, BTMAGIC_CONNECTING); 552 sc->sc_state = BTMAGIC_WAIT_CTL; 553 return 0; 554 } 555 556 /* validate soft_resolution */ 557 static int 558 btmagic_sysctl_resolution(SYSCTLFN_ARGS) 559 { 560 struct sysctlnode node; 561 struct btmagic_softc *sc; 562 int t, error; 563 564 node = *rnode; 565 sc = node.sysctl_data; 566 567 t = sc->sc_resolution; 568 node.sysctl_data = &t; 569 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 570 if (error || newp == NULL) 571 return error; 572 573 if (t < 100 || t > 4000 || (t / sc->sc_scale) == 0) 574 return EINVAL; 575 576 sc->sc_resolution = t; 577 DPRINTF(sc, "sc_resolution = %u", t); 578 return 0; 579 } 580 581 /* validate scroll_downscale_factor */ 582 static int 583 btmagic_sysctl_scale(SYSCTLFN_ARGS) 584 { 585 struct sysctlnode node; 586 struct btmagic_softc *sc; 587 int t, error; 588 589 node = *rnode; 590 sc = node.sysctl_data; 591 592 t = sc->sc_scale; 593 node.sysctl_data = &t; 594 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 595 if (error || newp == NULL) 596 return error; 597 598 if (t < 1 || t > 40 || (sc->sc_resolution / t) == 0) 599 return EINVAL; 600 601 sc->sc_scale = t; 602 DPRINTF(sc, "sc_scale = %u", t); 603 return 0; 604 } 605 606 /***************************************************************************** 607 * 608 * wsmouse(4) accessops 609 */ 610 611 static int 612 btmagic_wsmouse_enable(void *self) 613 { 614 struct btmagic_softc *sc = device_private(self); 615 616 if (sc->sc_enabled) 617 return EBUSY; 618 619 sc->sc_enabled = 1; 620 DPRINTF(sc, "enable"); 621 return 0; 622 } 623 624 static int 625 btmagic_wsmouse_ioctl(void *self, unsigned long cmd, void *data, 626 int flag, struct lwp *l) 627 { 628 /* struct btmagic_softc *sc = device_private(self); */ 629 int err; 630 631 switch (cmd) { 632 case WSMOUSEIO_GTYPE: 633 *(uint *)data = WSMOUSE_TYPE_BLUETOOTH; 634 err = 0; 635 break; 636 637 default: 638 err = EPASSTHROUGH; 639 break; 640 } 641 642 return err; 643 } 644 645 static void 646 btmagic_wsmouse_disable(void *self) 647 { 648 struct btmagic_softc *sc = device_private(self); 649 650 DPRINTF(sc, "disable"); 651 sc->sc_enabled = 0; 652 } 653 654 655 /***************************************************************************** 656 * 657 * setup routines 658 */ 659 660 static void 661 btmagic_timeout(void *arg) 662 { 663 struct btmagic_softc *sc = arg; 664 665 mutex_enter(bt_lock); 666 callout_ack(&sc->sc_timeout); 667 668 switch (sc->sc_state) { 669 case BTMAGIC_CLOSED: 670 if (sc->sc_int != NULL) { 671 l2cap_disconnect(sc->sc_int, 0); 672 break; 673 } 674 675 if (sc->sc_ctl != NULL) { 676 l2cap_disconnect(sc->sc_ctl, 0); 677 break; 678 } 679 break; 680 681 case BTMAGIC_OPEN: 682 if (!ISSET(sc->sc_flags, BTMAGIC_ENABLED)) { 683 btmagic_enable(sc); 684 break; 685 } 686 687 btmagic_check_battery(sc); 688 break; 689 690 case BTMAGIC_WAIT_CTL: 691 case BTMAGIC_WAIT_INT: 692 default: 693 break; 694 } 695 mutex_exit(bt_lock); 696 } 697 698 /* 699 * Send report on control channel 700 * 701 * bt_lock is held 702 */ 703 static int 704 btmagic_ctl_send(struct btmagic_softc *sc, const uint8_t *data, size_t len) 705 { 706 struct mbuf *m; 707 708 if (len > MLEN) 709 return EINVAL; 710 711 m = m_gethdr(M_DONTWAIT, MT_DATA); 712 if (m == NULL) 713 return ENOMEM; 714 715 #ifdef BTMAGIC_DEBUG 716 printf("%s: send", device_xname(sc->sc_dev)); 717 for (size_t i = 0; i < len; i++) 718 printf(" 0x%02x", data[i]); 719 printf("\n"); 720 #endif 721 722 memcpy(mtod(m, uint8_t *), data, len); 723 m->m_pkthdr.len = m->m_len = len; 724 return l2cap_send(sc->sc_ctl, m); 725 } 726 727 /* 728 * Enable touch reports by sending the following report 729 * 730 * SET_REPORT(FEATURE, 0xd7) = 0x01 731 * 732 * bt_lock is held 733 */ 734 static void 735 btmagic_enable(struct btmagic_softc *sc) 736 { 737 static const uint8_t rep[] = { 0x53, 0xd7, 0x01 }; 738 739 if (btmagic_ctl_send(sc, rep, sizeof(rep)) != 0) { 740 printf("%s: cannot enable touch reports\n", 741 device_xname(sc->sc_dev)); 742 743 return; 744 } 745 746 SET(sc->sc_flags, BTMAGIC_ENABLED); 747 } 748 749 /* 750 * Request the battery level by sending the following report 751 * 752 * GET_REPORT(FEATURE, 0x47) 753 * 754 * bt_lock is held 755 */ 756 static void 757 btmagic_check_battery(struct btmagic_softc *sc) 758 { 759 static const uint8_t rep[] = { 0x43, 0x47 }; 760 761 if (btmagic_ctl_send(sc, rep, sizeof(rep)) != 0) 762 printf("%s: cannot request battery level\n", 763 device_xname(sc->sc_dev)); 764 } 765 766 /* 767 * the Magic Mouse has a base resolution of 1300dpi which is rather flighty. We 768 * scale the output to the requested resolution, taking care to account for the 769 * remainders to prevent loss of small deltas. 770 */ 771 static int 772 btmagic_scale(int delta, int *remainder, int resolution) 773 { 774 int new; 775 776 delta += *remainder; 777 new = delta * resolution / 1300; 778 *remainder = delta - new * 1300 / resolution; 779 return new; 780 } 781 782 783 /***************************************************************************** 784 * 785 * bluetooth(9) callback methods for L2CAP 786 * 787 * All these are called from Bluetooth Protocol code, holding bt_lock. 788 */ 789 790 static void 791 btmagic_connecting(void *arg) 792 { 793 794 /* dont care */ 795 } 796 797 static void 798 btmagic_ctl_connected(void *arg) 799 { 800 struct sockaddr_bt sa; 801 struct btmagic_softc *sc = arg; 802 int err; 803 804 if (sc->sc_state != BTMAGIC_WAIT_CTL) 805 return; 806 807 KASSERT(sc->sc_ctl != NULL); 808 KASSERT(sc->sc_int == NULL); 809 810 if (ISSET(sc->sc_flags, BTMAGIC_CONNECTING)) { 811 /* initiate connect on interrupt PSM */ 812 err = l2cap_attach(&sc->sc_int, &btmagic_int_proto, sc); 813 if (err) 814 goto fail; 815 816 err = l2cap_setopt(sc->sc_int, &sc->sc_mode); 817 if (err) 818 goto fail; 819 820 memset(&sa, 0, sizeof(sa)); 821 sa.bt_len = sizeof(sa); 822 sa.bt_family = AF_BLUETOOTH; 823 bdaddr_copy(&sa.bt_bdaddr, &sc->sc_laddr); 824 825 err = l2cap_bind(sc->sc_int, &sa); 826 if (err) 827 goto fail; 828 829 sa.bt_psm = L2CAP_PSM_HID_INTR; 830 bdaddr_copy(&sa.bt_bdaddr, &sc->sc_raddr); 831 err = l2cap_connect(sc->sc_int, &sa); 832 if (err) 833 goto fail; 834 } 835 836 sc->sc_state = BTMAGIC_WAIT_INT; 837 return; 838 839 fail: 840 l2cap_detach(&sc->sc_ctl); 841 sc->sc_ctl = NULL; 842 843 printf("%s: connect failed (%d)\n", device_xname(sc->sc_dev), err); 844 } 845 846 static void 847 btmagic_int_connected(void *arg) 848 { 849 struct btmagic_softc *sc = arg; 850 851 if (sc->sc_state != BTMAGIC_WAIT_INT) 852 return; 853 854 KASSERT(sc->sc_ctl != NULL); 855 KASSERT(sc->sc_int != NULL); 856 857 printf("%s: connected\n", device_xname(sc->sc_dev)); 858 CLR(sc->sc_flags, BTMAGIC_CONNECTING); 859 sc->sc_state = BTMAGIC_OPEN; 860 861 /* trigger the setup */ 862 CLR(sc->sc_flags, BTMAGIC_ENABLED); 863 callout_schedule(&sc->sc_timeout, hz); 864 } 865 866 /* 867 * Disconnected 868 * 869 * Depending on our state, this could mean several things, but essentially 870 * we are lost. If both channels are closed, schedule another connection. 871 */ 872 static void 873 btmagic_ctl_disconnected(void *arg, int err) 874 { 875 struct btmagic_softc *sc = arg; 876 877 if (sc->sc_ctl != NULL) { 878 l2cap_detach(&sc->sc_ctl); 879 sc->sc_ctl = NULL; 880 } 881 882 if (sc->sc_int == NULL) { 883 printf("%s: disconnected\n", device_xname(sc->sc_dev)); 884 CLR(sc->sc_flags, BTMAGIC_CONNECTING); 885 sc->sc_state = BTMAGIC_WAIT_CTL; 886 } else { 887 /* 888 * The interrupt channel should have been closed first, 889 * but its potentially unsafe to detach that from here. 890 * Give them a second to do the right thing or let the 891 * callout handle it. 892 */ 893 sc->sc_state = BTMAGIC_CLOSED; 894 callout_schedule(&sc->sc_timeout, hz); 895 } 896 } 897 898 static void 899 btmagic_int_disconnected(void *arg, int err) 900 { 901 struct btmagic_softc *sc = arg; 902 903 if (sc->sc_int != NULL) { 904 l2cap_detach(&sc->sc_int); 905 sc->sc_int = NULL; 906 } 907 908 if (sc->sc_ctl == NULL) { 909 printf("%s: disconnected\n", device_xname(sc->sc_dev)); 910 CLR(sc->sc_flags, BTMAGIC_CONNECTING); 911 sc->sc_state = BTMAGIC_WAIT_CTL; 912 } else { 913 /* 914 * The control channel should be closing also, allow 915 * them a chance to do that before we force it. 916 */ 917 sc->sc_state = BTMAGIC_CLOSED; 918 callout_schedule(&sc->sc_timeout, hz); 919 } 920 } 921 922 /* 923 * New Connections 924 * 925 * We give a new L2CAP handle back if this matches the BDADDR we are 926 * listening for and we are in the right state. btmagic_connected will 927 * be called when the connection is open, so nothing else to do here 928 */ 929 static void * 930 btmagic_ctl_newconn(void *arg, struct sockaddr_bt *laddr, 931 struct sockaddr_bt *raddr) 932 { 933 struct btmagic_softc *sc = arg; 934 935 if (bdaddr_same(&raddr->bt_bdaddr, &sc->sc_raddr) == 0) 936 return NULL; 937 938 if (sc->sc_state != BTMAGIC_WAIT_CTL 939 || ISSET(sc->sc_flags, BTMAGIC_CONNECTING) 940 || sc->sc_ctl != NULL 941 || sc->sc_int != NULL) { 942 DPRINTF(sc, "reject ctl newconn %s%s%s%s", 943 (sc->sc_state == BTMAGIC_WAIT_CTL) ? " (WAITING)": "", 944 ISSET(sc->sc_flags, BTMAGIC_CONNECTING) ? " (CONNECTING)" : "", 945 (sc->sc_ctl != NULL) ? " (GOT CONTROL)" : "", 946 (sc->sc_int != NULL) ? " (GOT INTERRUPT)" : ""); 947 948 return NULL; 949 } 950 951 l2cap_attach(&sc->sc_ctl, &btmagic_ctl_proto, sc); 952 return sc->sc_ctl; 953 } 954 955 static void * 956 btmagic_int_newconn(void *arg, struct sockaddr_bt *laddr, 957 struct sockaddr_bt *raddr) 958 { 959 struct btmagic_softc *sc = arg; 960 961 if (bdaddr_same(&raddr->bt_bdaddr, &sc->sc_raddr) == 0) 962 return NULL; 963 964 if (sc->sc_state != BTMAGIC_WAIT_INT 965 || ISSET(sc->sc_flags, BTMAGIC_CONNECTING) 966 || sc->sc_ctl == NULL 967 || sc->sc_int != NULL) { 968 DPRINTF(sc, "reject int newconn %s%s%s%s", 969 (sc->sc_state == BTMAGIC_WAIT_INT) ? " (WAITING)": "", 970 ISSET(sc->sc_flags, BTMAGIC_CONNECTING) ? " (CONNECTING)" : "", 971 (sc->sc_ctl == NULL) ? " (NO CONTROL)" : "", 972 (sc->sc_int != NULL) ? " (GOT INTERRUPT)" : ""); 973 974 return NULL; 975 } 976 977 l2cap_attach(&sc->sc_int, &btmagic_int_proto, sc); 978 return sc->sc_int; 979 } 980 981 static void 982 btmagic_complete(void *arg, int count) 983 { 984 985 /* dont care */ 986 } 987 988 static void 989 btmagic_linkmode(void *arg, int new) 990 { 991 struct btmagic_softc *sc = arg; 992 int mode; 993 994 (void)sockopt_getint(&sc->sc_mode, &mode); 995 996 if (ISSET(mode, L2CAP_LM_AUTH) && !ISSET(new, L2CAP_LM_AUTH)) 997 printf("%s: auth failed\n", device_xname(sc->sc_dev)); 998 else if (ISSET(mode, L2CAP_LM_ENCRYPT) && !ISSET(new, L2CAP_LM_ENCRYPT)) 999 printf("%s: encrypt off\n", device_xname(sc->sc_dev)); 1000 else if (ISSET(mode, L2CAP_LM_SECURE) && !ISSET(new, L2CAP_LM_SECURE)) 1001 printf("%s: insecure\n", device_xname(sc->sc_dev)); 1002 else 1003 return; 1004 1005 if (sc->sc_int != NULL) 1006 l2cap_disconnect(sc->sc_int, 0); 1007 1008 if (sc->sc_ctl != NULL) 1009 l2cap_disconnect(sc->sc_ctl, 0); 1010 } 1011 1012 /* 1013 * Receive transaction from the mouse. We don't differentiate between 1014 * interrupt and control channel here, there is no need. 1015 */ 1016 static void 1017 btmagic_input(void *arg, struct mbuf *m) 1018 { 1019 struct btmagic_softc *sc = arg; 1020 uint8_t *data; 1021 size_t len; 1022 1023 if (sc->sc_state != BTMAGIC_OPEN 1024 || sc->sc_wsmouse == NULL 1025 || sc->sc_enabled == 0) 1026 goto release; 1027 1028 if (m->m_pkthdr.len > m->m_len) 1029 printf("%s: truncating input\n", device_xname(sc->sc_dev)); 1030 1031 data = mtod(m, uint8_t *); 1032 len = m->m_len; 1033 1034 if (len < 1) 1035 goto release; 1036 1037 switch (BTHID_TYPE(data[0])) { 1038 case BTHID_HANDSHAKE: 1039 DPRINTF(sc, "Handshake: 0x%x", BTHID_HANDSHAKE_PARAM(data[0])); 1040 callout_schedule(&sc->sc_timeout, hz); 1041 break; 1042 1043 case BTHID_DATA: 1044 if (len < 2) 1045 break; 1046 1047 switch (data[1]) { 1048 case 0x10: /* Basic mouse (input) */ 1049 btmagic_input_basic(sc, data + 2, len - 2); 1050 break; 1051 1052 case 0x29: /* Magic touch (input) */ 1053 btmagic_input_magic(sc, data + 2, len - 2); 1054 break; 1055 1056 case 0x30: /* Battery status (input) */ 1057 if (len != 3) 1058 break; 1059 1060 printf("%s: Battery ", device_xname(sc->sc_dev)); 1061 switch (data[2]) { 1062 case 0: printf("Ok\n"); break; 1063 case 1: printf("Warning\n"); break; 1064 case 2: printf("Critical\n"); break; 1065 default: printf("0x%02x\n", data[2]); break; 1066 } 1067 break; 1068 1069 case 0x47: /* Battery strength (feature) */ 1070 if (len != 3) 1071 break; 1072 1073 printf("%s: Battery %d%%\n", device_xname(sc->sc_dev), 1074 data[2]); 1075 break; 1076 1077 case 0x61: /* Surface detection (input) */ 1078 if (len != 3) 1079 break; 1080 1081 DPRINTF(sc, "Mouse %s", 1082 (data[2] == 0 ? "lowered" : "raised")); 1083 break; 1084 1085 case 0x60: /* unknown (input) */ 1086 case 0xf0: /* unknown (feature) */ 1087 case 0xf1: /* unknown (feature) */ 1088 default: 1089 #if BTMAGIC_DEBUG 1090 printf("%s: recv", device_xname(sc->sc_dev)); 1091 for (size_t i = 0; i < len; i++) 1092 printf(" 0x%02x", data[i]); 1093 printf("\n"); 1094 #endif 1095 break; 1096 } 1097 break; 1098 1099 default: 1100 DPRINTF(sc, "transaction (type 0x%x)", BTHID_TYPE(data[0])); 1101 break; 1102 } 1103 1104 release: 1105 m_freem(m); 1106 } 1107 1108 /* 1109 * parse the Basic report (0x10), which according to the provided 1110 * HID descriptor is in the following format 1111 * 1112 * button 1 1-bit 1113 * button 2 1-bit 1114 * padding 6-bits 1115 * dX 16-bits (signed) 1116 * dY 16-bits (signed) 1117 * 1118 * Even when the magic touch reports are enabled, the basic report is 1119 * sent for mouse move events where no touches are detected. 1120 */ 1121 static const struct { 1122 struct hid_location button1; 1123 struct hid_location button2; 1124 struct hid_location dX; 1125 struct hid_location dY; 1126 } basic = { 1127 .button1 = { .pos = 0, .size = 1 }, 1128 .button2 = { .pos = 1, .size = 1 }, 1129 .dX = { .pos = 8, .size = 16 }, 1130 .dY = { .pos = 24, .size = 16 }, 1131 }; 1132 1133 static void 1134 btmagic_input_basic(struct btmagic_softc *sc, uint8_t *data, size_t len) 1135 { 1136 int dx, dy; 1137 uint32_t mb; 1138 int s; 1139 1140 if (len != 5) 1141 return; 1142 1143 dx = hid_get_data(data, &basic.dX); 1144 dx = btmagic_scale(dx, &sc->sc_rx, sc->sc_resolution); 1145 1146 dy = hid_get_data(data, &basic.dY); 1147 dy = btmagic_scale(dy, &sc->sc_ry, sc->sc_resolution); 1148 1149 mb = 0; 1150 if (hid_get_udata(data, &basic.button1)) 1151 mb |= __BIT(0); 1152 if (hid_get_udata(data, &basic.button2)) 1153 mb |= __BIT(2); 1154 1155 if (dx != 0 || dy != 0 || mb != sc->sc_mb) { 1156 sc->sc_mb = mb; 1157 1158 s = spltty(); 1159 wsmouse_input(sc->sc_wsmouse, mb, 1160 dx, -dy, 0, 0, WSMOUSE_INPUT_DELTA); 1161 splx(s); 1162 } 1163 } 1164 1165 /* 1166 * the Magic touch report (0x29), according to the Linux driver 1167 * written by Michael Poole, is variable length starting with the 1168 * fixed 40-bit header 1169 * 1170 * dX lsb 8-bits (signed) 1171 * dY lsb 8-bits (signed) 1172 * button 1 1-bit 1173 * button 2 1-bit 1174 * dX msb 2-bits (signed) 1175 * dY msb 2-bits (signed) 1176 * timestamp 18-bits 1177 * 1178 * followed by (up to 5?) touch reports of 64-bits each 1179 * 1180 * abs W 12-bits (signed) 1181 * abs Z 12-bits (signed) 1182 * axis major 8-bits 1183 * axis minor 8-bits 1184 * pressure 6-bits 1185 * id 4-bits 1186 * angle 6-bits (from E(0)->N(32)->W(64)) 1187 * unknown 4-bits 1188 * phase 4-bits 1189 */ 1190 1191 static const struct { 1192 struct hid_location dXl; 1193 struct hid_location dYl; 1194 struct hid_location button1; 1195 struct hid_location button2; 1196 struct hid_location dXm; 1197 struct hid_location dYm; 1198 struct hid_location timestamp; 1199 } magic = { 1200 .dXl = { .pos = 0, .size = 8 }, 1201 .dYl = { .pos = 8, .size = 8 }, 1202 .button1 = { .pos = 16, .size = 1 }, 1203 .button2 = { .pos = 17, .size = 1 }, 1204 .dXm = { .pos = 18, .size = 2 }, 1205 .dYm = { .pos = 20, .size = 2 }, 1206 .timestamp = { .pos = 22, .size = 18 }, 1207 }; 1208 1209 static const struct { 1210 struct hid_location aW; 1211 struct hid_location aZ; 1212 struct hid_location major; 1213 struct hid_location minor; 1214 struct hid_location pressure; 1215 struct hid_location id; 1216 struct hid_location angle; 1217 struct hid_location unknown; 1218 struct hid_location phase; 1219 } touch = { 1220 .aW = { .pos = 0, .size = 12 }, 1221 .aZ = { .pos = 12, .size = 12 }, 1222 .major = { .pos = 24, .size = 8 }, 1223 .minor = { .pos = 32, .size = 8 }, 1224 .pressure = { .pos = 40, .size = 6 }, 1225 .id = { .pos = 46, .size = 4 }, 1226 .angle = { .pos = 50, .size = 6 }, 1227 .unknown = { .pos = 56, .size = 4 }, 1228 .phase = { .pos = 60, .size = 4 }, 1229 }; 1230 1231 /* 1232 * the phase of the touch starts at 0x01 as the finger is first detected 1233 * approaching the mouse, increasing to 0x04 while the finger is touching, 1234 * then increases towards 0x07 as the finger is lifted, and we get 0x00 1235 * when the touch is cancelled. The values below seem to be produced for 1236 * every touch, the others less consistently depending on how fast the 1237 * approach or departure is. 1238 * 1239 * In fact we ignore touches unless they are in the steady 0x04 phase. 1240 */ 1241 #define BTMAGIC_PHASE_START 0x3 1242 #define BTMAGIC_PHASE_CONT 0x4 1243 #define BTMAGIC_PHASE_END 0x7 1244 #define BTMAGIC_PHASE_CANCEL 0x0 1245 1246 static void 1247 btmagic_input_magic(struct btmagic_softc *sc, uint8_t *data, size_t len) 1248 { 1249 uint32_t mb; 1250 int dx, dy, dz, dw; 1251 int id, nf, az, aw, tz, tw; 1252 int s; 1253 1254 if (((len - 5) % 8) != 0) 1255 return; 1256 1257 dx = (hid_get_data(data, &magic.dXm) << 8) 1258 | (hid_get_data(data, &magic.dXl) & 0xff); 1259 dx = btmagic_scale(dx, &sc->sc_rx, sc->sc_resolution); 1260 1261 dy = (hid_get_data(data, &magic.dYm) << 8) 1262 | (hid_get_data(data, &magic.dYl) & 0xff); 1263 dy = btmagic_scale(dy, &sc->sc_ry, sc->sc_resolution); 1264 1265 mb = 0; 1266 if (hid_get_udata(data, &magic.button1)) 1267 mb |= __BIT(0); 1268 if (hid_get_udata(data, &magic.button2)) 1269 mb |= __BIT(2); 1270 1271 nf = 0; 1272 dz = 0; 1273 dw = 0; 1274 len = (len - 5) / 8; 1275 for (data += 5; len-- > 0; data += 8) { 1276 id = hid_get_udata(data, &touch.id); 1277 az = hid_get_data(data, &touch.aZ); 1278 aw = hid_get_data(data, &touch.aW); 1279 1280 /* 1281 * scrolling is triggered by an established touch moving 1282 * beyond a minimum distance from its start point and is 1283 * cancelled as the touch starts to fade. 1284 * 1285 * Multiple touches may be scrolling simultaneously, the 1286 * effect is cumulative. 1287 */ 1288 1289 switch (hid_get_udata(data, &touch.phase)) { 1290 case BTMAGIC_PHASE_CONT: 1291 tz = az - sc->sc_az[id]; 1292 tw = aw - sc->sc_aw[id]; 1293 1294 if (ISSET(sc->sc_smask, id)) { 1295 /* scrolling finger */ 1296 dz += btmagic_scale(tz, &sc->sc_rz, 1297 sc->sc_resolution / sc->sc_scale); 1298 dw += btmagic_scale(tw, &sc->sc_rw, 1299 sc->sc_resolution / sc->sc_scale); 1300 } else if (abs(tz) > sc->sc_dist 1301 || abs(tw) > sc->sc_dist) { 1302 /* new scrolling finger */ 1303 if (sc->sc_smask == 0) { 1304 sc->sc_rz = 0; 1305 sc->sc_rw = 0; 1306 } 1307 1308 SET(sc->sc_smask, id); 1309 } else { 1310 /* not scrolling finger */ 1311 az = sc->sc_az[id]; 1312 aw = sc->sc_aw[id]; 1313 } 1314 1315 /* count firm touches for middle-click */ 1316 if (hid_get_udata(data, &touch.pressure) > sc->sc_firm) 1317 nf++; 1318 1319 break; 1320 1321 default: 1322 CLR(sc->sc_smask, id); 1323 break; 1324 } 1325 1326 sc->sc_az[id] = az; 1327 sc->sc_aw[id] = aw; 1328 } 1329 1330 /* 1331 * The mouse only has one click detector, and says left or right but 1332 * never both. We convert multiple firm touches while clicking into 1333 * a middle button press, and cancel any scroll effects while click 1334 * is active. 1335 */ 1336 if (mb != 0) { 1337 if (sc->sc_mb != 0) 1338 mb = sc->sc_mb; 1339 else if (nf > 1) 1340 mb = __BIT(1); 1341 1342 sc->sc_smask = 0; 1343 dz = 0; 1344 dw = 0; 1345 } 1346 1347 if (dx != 0 || dy != 0 || dz != 0 || dw != 0 || mb != sc->sc_mb) { 1348 sc->sc_mb = mb; 1349 1350 s = spltty(); 1351 wsmouse_input(sc->sc_wsmouse, mb, 1352 dx, -dy, -dz, dw, WSMOUSE_INPUT_DELTA); 1353 splx(s); 1354 } 1355 } 1356