1 /* $NetBSD: btmagic.c,v 1.2 2012/04/03 09:32:53 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.2 2012/04/03 09:32:53 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 pmf_device_register(self, NULL, NULL); 389 390 /* 391 * start bluetooth connections 392 */ 393 mutex_enter(bt_lock); 394 btmagic_listen(sc); 395 btmagic_connect(sc); 396 mutex_exit(bt_lock); 397 } 398 399 static int 400 btmagic_detach(device_t self, int flags) 401 { 402 struct btmagic_softc *sc = device_private(self); 403 int err = 0; 404 405 mutex_enter(bt_lock); 406 407 /* release interrupt listen */ 408 if (sc->sc_int_l != NULL) { 409 l2cap_detach(&sc->sc_int_l); 410 sc->sc_int_l = NULL; 411 } 412 413 /* release control listen */ 414 if (sc->sc_ctl_l != NULL) { 415 l2cap_detach(&sc->sc_ctl_l); 416 sc->sc_ctl_l = NULL; 417 } 418 419 /* close interrupt channel */ 420 if (sc->sc_int != NULL) { 421 l2cap_disconnect(sc->sc_int, 0); 422 l2cap_detach(&sc->sc_int); 423 sc->sc_int = NULL; 424 } 425 426 /* close control channel */ 427 if (sc->sc_ctl != NULL) { 428 l2cap_disconnect(sc->sc_ctl, 0); 429 l2cap_detach(&sc->sc_ctl); 430 sc->sc_ctl = NULL; 431 } 432 433 callout_halt(&sc->sc_timeout, bt_lock); 434 callout_destroy(&sc->sc_timeout); 435 436 mutex_exit(bt_lock); 437 438 pmf_device_deregister(self); 439 440 sockopt_destroy(&sc->sc_mode); 441 442 sysctl_teardown(&sc->sc_log); 443 444 if (sc->sc_wsmouse != NULL) { 445 err = config_detach(sc->sc_wsmouse, flags); 446 sc->sc_wsmouse = NULL; 447 } 448 449 return err; 450 } 451 452 /* 453 * listen for our device 454 * 455 * bt_lock is held 456 */ 457 static int 458 btmagic_listen(struct btmagic_softc *sc) 459 { 460 struct sockaddr_bt sa; 461 int err; 462 463 memset(&sa, 0, sizeof(sa)); 464 sa.bt_len = sizeof(sa); 465 sa.bt_family = AF_BLUETOOTH; 466 bdaddr_copy(&sa.bt_bdaddr, &sc->sc_laddr); 467 468 /* 469 * Listen on control PSM 470 */ 471 err = l2cap_attach(&sc->sc_ctl_l, &btmagic_ctl_proto, sc); 472 if (err) 473 return err; 474 475 err = l2cap_setopt(sc->sc_ctl_l, &sc->sc_mode); 476 if (err) 477 return err; 478 479 sa.bt_psm = L2CAP_PSM_HID_CNTL; 480 err = l2cap_bind(sc->sc_ctl_l, &sa); 481 if (err) 482 return err; 483 484 err = l2cap_listen(sc->sc_ctl_l); 485 if (err) 486 return err; 487 488 /* 489 * Listen on interrupt PSM 490 */ 491 err = l2cap_attach(&sc->sc_int_l, &btmagic_int_proto, sc); 492 if (err) 493 return err; 494 495 err = l2cap_setopt(sc->sc_int_l, &sc->sc_mode); 496 if (err) 497 return err; 498 499 sa.bt_psm = L2CAP_PSM_HID_INTR; 500 err = l2cap_bind(sc->sc_int_l, &sa); 501 if (err) 502 return err; 503 504 err = l2cap_listen(sc->sc_int_l); 505 if (err) 506 return err; 507 508 sc->sc_state = BTMAGIC_WAIT_CTL; 509 return 0; 510 } 511 512 /* 513 * start connecting to our device 514 * 515 * bt_lock is held 516 */ 517 static int 518 btmagic_connect(struct btmagic_softc *sc) 519 { 520 struct sockaddr_bt sa; 521 int err; 522 523 memset(&sa, 0, sizeof(sa)); 524 sa.bt_len = sizeof(sa); 525 sa.bt_family = AF_BLUETOOTH; 526 527 err = l2cap_attach(&sc->sc_ctl, &btmagic_ctl_proto, sc); 528 if (err) { 529 printf("%s: l2cap_attach failed (%d)\n", 530 device_xname(sc->sc_dev), err); 531 return err; 532 } 533 534 err = l2cap_setopt(sc->sc_ctl, &sc->sc_mode); 535 if (err) 536 return err; 537 538 bdaddr_copy(&sa.bt_bdaddr, &sc->sc_laddr); 539 err = l2cap_bind(sc->sc_ctl, &sa); 540 if (err) { 541 printf("%s: l2cap_bind failed (%d)\n", 542 device_xname(sc->sc_dev), err); 543 return err; 544 } 545 546 sa.bt_psm = L2CAP_PSM_HID_CNTL; 547 bdaddr_copy(&sa.bt_bdaddr, &sc->sc_raddr); 548 err = l2cap_connect(sc->sc_ctl, &sa); 549 if (err) { 550 printf("%s: l2cap_connect failed (%d)\n", 551 device_xname(sc->sc_dev), err); 552 return err; 553 } 554 555 SET(sc->sc_flags, BTMAGIC_CONNECTING); 556 sc->sc_state = BTMAGIC_WAIT_CTL; 557 return 0; 558 } 559 560 /* validate soft_resolution */ 561 static int 562 btmagic_sysctl_resolution(SYSCTLFN_ARGS) 563 { 564 struct sysctlnode node; 565 struct btmagic_softc *sc; 566 int t, error; 567 568 node = *rnode; 569 sc = node.sysctl_data; 570 571 t = sc->sc_resolution; 572 node.sysctl_data = &t; 573 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 574 if (error || newp == NULL) 575 return error; 576 577 if (t < 100 || t > 4000 || (t / sc->sc_scale) == 0) 578 return EINVAL; 579 580 sc->sc_resolution = t; 581 DPRINTF(sc, "sc_resolution = %u", t); 582 return 0; 583 } 584 585 /* validate scroll_downscale_factor */ 586 static int 587 btmagic_sysctl_scale(SYSCTLFN_ARGS) 588 { 589 struct sysctlnode node; 590 struct btmagic_softc *sc; 591 int t, error; 592 593 node = *rnode; 594 sc = node.sysctl_data; 595 596 t = sc->sc_scale; 597 node.sysctl_data = &t; 598 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 599 if (error || newp == NULL) 600 return error; 601 602 if (t < 1 || t > 40 || (sc->sc_resolution / t) == 0) 603 return EINVAL; 604 605 sc->sc_scale = t; 606 DPRINTF(sc, "sc_scale = %u", t); 607 return 0; 608 } 609 610 /***************************************************************************** 611 * 612 * wsmouse(4) accessops 613 */ 614 615 static int 616 btmagic_wsmouse_enable(void *self) 617 { 618 struct btmagic_softc *sc = device_private(self); 619 620 if (sc->sc_enabled) 621 return EBUSY; 622 623 sc->sc_enabled = 1; 624 DPRINTF(sc, "enable"); 625 return 0; 626 } 627 628 static int 629 btmagic_wsmouse_ioctl(void *self, unsigned long cmd, void *data, 630 int flag, struct lwp *l) 631 { 632 /* struct btmagic_softc *sc = device_private(self); */ 633 int err; 634 635 switch (cmd) { 636 case WSMOUSEIO_GTYPE: 637 *(uint *)data = WSMOUSE_TYPE_BLUETOOTH; 638 err = 0; 639 break; 640 641 default: 642 err = EPASSTHROUGH; 643 break; 644 } 645 646 return err; 647 } 648 649 static void 650 btmagic_wsmouse_disable(void *self) 651 { 652 struct btmagic_softc *sc = device_private(self); 653 654 DPRINTF(sc, "disable"); 655 sc->sc_enabled = 0; 656 } 657 658 659 /***************************************************************************** 660 * 661 * setup routines 662 */ 663 664 static void 665 btmagic_timeout(void *arg) 666 { 667 struct btmagic_softc *sc = arg; 668 669 mutex_enter(bt_lock); 670 callout_ack(&sc->sc_timeout); 671 672 switch (sc->sc_state) { 673 case BTMAGIC_CLOSED: 674 if (sc->sc_int != NULL) { 675 l2cap_disconnect(sc->sc_int, 0); 676 break; 677 } 678 679 if (sc->sc_ctl != NULL) { 680 l2cap_disconnect(sc->sc_ctl, 0); 681 break; 682 } 683 break; 684 685 case BTMAGIC_OPEN: 686 if (!ISSET(sc->sc_flags, BTMAGIC_ENABLED)) { 687 btmagic_enable(sc); 688 break; 689 } 690 691 btmagic_check_battery(sc); 692 break; 693 694 case BTMAGIC_WAIT_CTL: 695 case BTMAGIC_WAIT_INT: 696 default: 697 break; 698 } 699 mutex_exit(bt_lock); 700 } 701 702 /* 703 * Send report on control channel 704 * 705 * bt_lock is held 706 */ 707 static int 708 btmagic_ctl_send(struct btmagic_softc *sc, const uint8_t *data, size_t len) 709 { 710 struct mbuf *m; 711 712 if (len > MLEN) 713 return EINVAL; 714 715 m = m_gethdr(M_DONTWAIT, MT_DATA); 716 if (m == NULL) 717 return ENOMEM; 718 719 #ifdef BTMAGIC_DEBUG 720 printf("%s: send", device_xname(sc->sc_dev)); 721 for (size_t i = 0; i < len; i++) 722 printf(" 0x%02x", data[i]); 723 printf("\n"); 724 #endif 725 726 memcpy(mtod(m, uint8_t *), data, len); 727 m->m_pkthdr.len = m->m_len = len; 728 return l2cap_send(sc->sc_ctl, m); 729 } 730 731 /* 732 * Enable touch reports by sending the following report 733 * 734 * SET_REPORT(FEATURE, 0xd7) = 0x01 735 * 736 * bt_lock is held 737 */ 738 static void 739 btmagic_enable(struct btmagic_softc *sc) 740 { 741 static const uint8_t rep[] = { 0x53, 0xd7, 0x01 }; 742 743 if (btmagic_ctl_send(sc, rep, sizeof(rep)) != 0) { 744 printf("%s: cannot enable touch reports\n", 745 device_xname(sc->sc_dev)); 746 747 return; 748 } 749 750 SET(sc->sc_flags, BTMAGIC_ENABLED); 751 } 752 753 /* 754 * Request the battery level by sending the following report 755 * 756 * GET_REPORT(FEATURE, 0x47) 757 * 758 * bt_lock is held 759 */ 760 static void 761 btmagic_check_battery(struct btmagic_softc *sc) 762 { 763 static const uint8_t rep[] = { 0x43, 0x47 }; 764 765 if (btmagic_ctl_send(sc, rep, sizeof(rep)) != 0) 766 printf("%s: cannot request battery level\n", 767 device_xname(sc->sc_dev)); 768 } 769 770 /* 771 * the Magic Mouse has a base resolution of 1300dpi which is rather flighty. We 772 * scale the output to the requested resolution, taking care to account for the 773 * remainders to prevent loss of small deltas. 774 */ 775 static int 776 btmagic_scale(int delta, int *remainder, int resolution) 777 { 778 int new; 779 780 delta += *remainder; 781 new = delta * resolution / 1300; 782 *remainder = delta - new * 1300 / resolution; 783 return new; 784 } 785 786 787 /***************************************************************************** 788 * 789 * bluetooth(9) callback methods for L2CAP 790 * 791 * All these are called from Bluetooth Protocol code, holding bt_lock. 792 */ 793 794 static void 795 btmagic_connecting(void *arg) 796 { 797 798 /* dont care */ 799 } 800 801 static void 802 btmagic_ctl_connected(void *arg) 803 { 804 struct sockaddr_bt sa; 805 struct btmagic_softc *sc = arg; 806 int err; 807 808 if (sc->sc_state != BTMAGIC_WAIT_CTL) 809 return; 810 811 KASSERT(sc->sc_ctl != NULL); 812 KASSERT(sc->sc_int == NULL); 813 814 if (ISSET(sc->sc_flags, BTMAGIC_CONNECTING)) { 815 /* initiate connect on interrupt PSM */ 816 err = l2cap_attach(&sc->sc_int, &btmagic_int_proto, sc); 817 if (err) 818 goto fail; 819 820 err = l2cap_setopt(sc->sc_int, &sc->sc_mode); 821 if (err) 822 goto fail; 823 824 memset(&sa, 0, sizeof(sa)); 825 sa.bt_len = sizeof(sa); 826 sa.bt_family = AF_BLUETOOTH; 827 bdaddr_copy(&sa.bt_bdaddr, &sc->sc_laddr); 828 829 err = l2cap_bind(sc->sc_int, &sa); 830 if (err) 831 goto fail; 832 833 sa.bt_psm = L2CAP_PSM_HID_INTR; 834 bdaddr_copy(&sa.bt_bdaddr, &sc->sc_raddr); 835 err = l2cap_connect(sc->sc_int, &sa); 836 if (err) 837 goto fail; 838 } 839 840 sc->sc_state = BTMAGIC_WAIT_INT; 841 return; 842 843 fail: 844 l2cap_detach(&sc->sc_ctl); 845 sc->sc_ctl = NULL; 846 847 printf("%s: connect failed (%d)\n", device_xname(sc->sc_dev), err); 848 } 849 850 static void 851 btmagic_int_connected(void *arg) 852 { 853 struct btmagic_softc *sc = arg; 854 855 if (sc->sc_state != BTMAGIC_WAIT_INT) 856 return; 857 858 KASSERT(sc->sc_ctl != NULL); 859 KASSERT(sc->sc_int != NULL); 860 861 printf("%s: connected\n", device_xname(sc->sc_dev)); 862 CLR(sc->sc_flags, BTMAGIC_CONNECTING); 863 sc->sc_state = BTMAGIC_OPEN; 864 865 /* trigger the setup */ 866 CLR(sc->sc_flags, BTMAGIC_ENABLED); 867 callout_schedule(&sc->sc_timeout, hz); 868 } 869 870 /* 871 * Disconnected 872 * 873 * Depending on our state, this could mean several things, but essentially 874 * we are lost. If both channels are closed, schedule another connection. 875 */ 876 static void 877 btmagic_ctl_disconnected(void *arg, int err) 878 { 879 struct btmagic_softc *sc = arg; 880 881 if (sc->sc_ctl != NULL) { 882 l2cap_detach(&sc->sc_ctl); 883 sc->sc_ctl = NULL; 884 } 885 886 if (sc->sc_int == NULL) { 887 printf("%s: disconnected\n", device_xname(sc->sc_dev)); 888 CLR(sc->sc_flags, BTMAGIC_CONNECTING); 889 sc->sc_state = BTMAGIC_WAIT_CTL; 890 } else { 891 /* 892 * The interrupt channel should have been closed first, 893 * but its potentially unsafe to detach that from here. 894 * Give them a second to do the right thing or let the 895 * callout handle it. 896 */ 897 sc->sc_state = BTMAGIC_CLOSED; 898 callout_schedule(&sc->sc_timeout, hz); 899 } 900 } 901 902 static void 903 btmagic_int_disconnected(void *arg, int err) 904 { 905 struct btmagic_softc *sc = arg; 906 907 if (sc->sc_int != NULL) { 908 l2cap_detach(&sc->sc_int); 909 sc->sc_int = NULL; 910 } 911 912 if (sc->sc_ctl == NULL) { 913 printf("%s: disconnected\n", device_xname(sc->sc_dev)); 914 CLR(sc->sc_flags, BTMAGIC_CONNECTING); 915 sc->sc_state = BTMAGIC_WAIT_CTL; 916 } else { 917 /* 918 * The control channel should be closing also, allow 919 * them a chance to do that before we force it. 920 */ 921 sc->sc_state = BTMAGIC_CLOSED; 922 callout_schedule(&sc->sc_timeout, hz); 923 } 924 } 925 926 /* 927 * New Connections 928 * 929 * We give a new L2CAP handle back if this matches the BDADDR we are 930 * listening for and we are in the right state. btmagic_connected will 931 * be called when the connection is open, so nothing else to do here 932 */ 933 static void * 934 btmagic_ctl_newconn(void *arg, struct sockaddr_bt *laddr, 935 struct sockaddr_bt *raddr) 936 { 937 struct btmagic_softc *sc = arg; 938 939 if (bdaddr_same(&raddr->bt_bdaddr, &sc->sc_raddr) == 0) 940 return NULL; 941 942 if (sc->sc_state != BTMAGIC_WAIT_CTL 943 || ISSET(sc->sc_flags, BTMAGIC_CONNECTING) 944 || sc->sc_ctl != NULL 945 || sc->sc_int != NULL) { 946 DPRINTF(sc, "reject ctl newconn %s%s%s%s", 947 (sc->sc_state == BTMAGIC_WAIT_CTL) ? " (WAITING)": "", 948 ISSET(sc->sc_flags, BTMAGIC_CONNECTING) ? " (CONNECTING)" : "", 949 (sc->sc_ctl != NULL) ? " (GOT CONTROL)" : "", 950 (sc->sc_int != NULL) ? " (GOT INTERRUPT)" : ""); 951 952 return NULL; 953 } 954 955 l2cap_attach(&sc->sc_ctl, &btmagic_ctl_proto, sc); 956 return sc->sc_ctl; 957 } 958 959 static void * 960 btmagic_int_newconn(void *arg, struct sockaddr_bt *laddr, 961 struct sockaddr_bt *raddr) 962 { 963 struct btmagic_softc *sc = arg; 964 965 if (bdaddr_same(&raddr->bt_bdaddr, &sc->sc_raddr) == 0) 966 return NULL; 967 968 if (sc->sc_state != BTMAGIC_WAIT_INT 969 || ISSET(sc->sc_flags, BTMAGIC_CONNECTING) 970 || sc->sc_ctl == NULL 971 || sc->sc_int != NULL) { 972 DPRINTF(sc, "reject int newconn %s%s%s%s", 973 (sc->sc_state == BTMAGIC_WAIT_INT) ? " (WAITING)": "", 974 ISSET(sc->sc_flags, BTMAGIC_CONNECTING) ? " (CONNECTING)" : "", 975 (sc->sc_ctl == NULL) ? " (NO CONTROL)" : "", 976 (sc->sc_int != NULL) ? " (GOT INTERRUPT)" : ""); 977 978 return NULL; 979 } 980 981 l2cap_attach(&sc->sc_int, &btmagic_int_proto, sc); 982 return sc->sc_int; 983 } 984 985 static void 986 btmagic_complete(void *arg, int count) 987 { 988 989 /* dont care */ 990 } 991 992 static void 993 btmagic_linkmode(void *arg, int new) 994 { 995 struct btmagic_softc *sc = arg; 996 int mode; 997 998 (void)sockopt_getint(&sc->sc_mode, &mode); 999 1000 if (ISSET(mode, L2CAP_LM_AUTH) && !ISSET(new, L2CAP_LM_AUTH)) 1001 printf("%s: auth failed\n", device_xname(sc->sc_dev)); 1002 else if (ISSET(mode, L2CAP_LM_ENCRYPT) && !ISSET(new, L2CAP_LM_ENCRYPT)) 1003 printf("%s: encrypt off\n", device_xname(sc->sc_dev)); 1004 else if (ISSET(mode, L2CAP_LM_SECURE) && !ISSET(new, L2CAP_LM_SECURE)) 1005 printf("%s: insecure\n", device_xname(sc->sc_dev)); 1006 else 1007 return; 1008 1009 if (sc->sc_int != NULL) 1010 l2cap_disconnect(sc->sc_int, 0); 1011 1012 if (sc->sc_ctl != NULL) 1013 l2cap_disconnect(sc->sc_ctl, 0); 1014 } 1015 1016 /* 1017 * Receive transaction from the mouse. We don't differentiate between 1018 * interrupt and control channel here, there is no need. 1019 */ 1020 static void 1021 btmagic_input(void *arg, struct mbuf *m) 1022 { 1023 struct btmagic_softc *sc = arg; 1024 uint8_t *data; 1025 size_t len; 1026 1027 if (sc->sc_state != BTMAGIC_OPEN 1028 || sc->sc_wsmouse == NULL 1029 || sc->sc_enabled == 0) 1030 goto release; 1031 1032 if (m->m_pkthdr.len > m->m_len) 1033 printf("%s: truncating input\n", device_xname(sc->sc_dev)); 1034 1035 data = mtod(m, uint8_t *); 1036 len = m->m_len; 1037 1038 if (len < 1) 1039 goto release; 1040 1041 switch (BTHID_TYPE(data[0])) { 1042 case BTHID_HANDSHAKE: 1043 DPRINTF(sc, "Handshake: 0x%x", BTHID_HANDSHAKE_PARAM(data[0])); 1044 callout_schedule(&sc->sc_timeout, hz); 1045 break; 1046 1047 case BTHID_DATA: 1048 if (len < 2) 1049 break; 1050 1051 switch (data[1]) { 1052 case 0x10: /* Basic mouse (input) */ 1053 btmagic_input_basic(sc, data + 2, len - 2); 1054 break; 1055 1056 case 0x29: /* Magic touch (input) */ 1057 btmagic_input_magic(sc, data + 2, len - 2); 1058 break; 1059 1060 case 0x30: /* Battery status (input) */ 1061 if (len != 3) 1062 break; 1063 1064 printf("%s: Battery ", device_xname(sc->sc_dev)); 1065 switch (data[2]) { 1066 case 0: printf("Ok\n"); break; 1067 case 1: printf("Warning\n"); break; 1068 case 2: printf("Critical\n"); break; 1069 default: printf("0x%02x\n", data[2]); break; 1070 } 1071 break; 1072 1073 case 0x47: /* Battery strength (feature) */ 1074 if (len != 3) 1075 break; 1076 1077 printf("%s: Battery %d%%\n", device_xname(sc->sc_dev), 1078 data[2]); 1079 break; 1080 1081 case 0x61: /* Surface detection (input) */ 1082 if (len != 3) 1083 break; 1084 1085 DPRINTF(sc, "Mouse %s", 1086 (data[2] == 0 ? "lowered" : "raised")); 1087 break; 1088 1089 case 0x60: /* unknown (input) */ 1090 case 0xf0: /* unknown (feature) */ 1091 case 0xf1: /* unknown (feature) */ 1092 default: 1093 #if BTMAGIC_DEBUG 1094 printf("%s: recv", device_xname(sc->sc_dev)); 1095 for (size_t i = 0; i < len; i++) 1096 printf(" 0x%02x", data[i]); 1097 printf("\n"); 1098 #endif 1099 break; 1100 } 1101 break; 1102 1103 default: 1104 DPRINTF(sc, "transaction (type 0x%x)", BTHID_TYPE(data[0])); 1105 break; 1106 } 1107 1108 release: 1109 m_freem(m); 1110 } 1111 1112 /* 1113 * parse the Basic report (0x10), which according to the provided 1114 * HID descriptor is in the following format 1115 * 1116 * button 1 1-bit 1117 * button 2 1-bit 1118 * padding 6-bits 1119 * dX 16-bits (signed) 1120 * dY 16-bits (signed) 1121 * 1122 * Even when the magic touch reports are enabled, the basic report is 1123 * sent for mouse move events where no touches are detected. 1124 */ 1125 static const struct { 1126 struct hid_location button1; 1127 struct hid_location button2; 1128 struct hid_location dX; 1129 struct hid_location dY; 1130 } basic = { 1131 .button1 = { .pos = 0, .size = 1 }, 1132 .button2 = { .pos = 1, .size = 1 }, 1133 .dX = { .pos = 8, .size = 16 }, 1134 .dY = { .pos = 24, .size = 16 }, 1135 }; 1136 1137 static void 1138 btmagic_input_basic(struct btmagic_softc *sc, uint8_t *data, size_t len) 1139 { 1140 int dx, dy; 1141 uint32_t mb; 1142 int s; 1143 1144 if (len != 5) 1145 return; 1146 1147 dx = hid_get_data(data, &basic.dX); 1148 dx = btmagic_scale(dx, &sc->sc_rx, sc->sc_resolution); 1149 1150 dy = hid_get_data(data, &basic.dY); 1151 dy = btmagic_scale(dy, &sc->sc_ry, sc->sc_resolution); 1152 1153 mb = 0; 1154 if (hid_get_udata(data, &basic.button1)) 1155 mb |= __BIT(0); 1156 if (hid_get_udata(data, &basic.button2)) 1157 mb |= __BIT(2); 1158 1159 if (dx != 0 || dy != 0 || mb != sc->sc_mb) { 1160 sc->sc_mb = mb; 1161 1162 s = spltty(); 1163 wsmouse_input(sc->sc_wsmouse, mb, 1164 dx, -dy, 0, 0, WSMOUSE_INPUT_DELTA); 1165 splx(s); 1166 } 1167 } 1168 1169 /* 1170 * the Magic touch report (0x29), according to the Linux driver 1171 * written by Michael Poole, is variable length starting with the 1172 * fixed 40-bit header 1173 * 1174 * dX lsb 8-bits (signed) 1175 * dY lsb 8-bits (signed) 1176 * button 1 1-bit 1177 * button 2 1-bit 1178 * dX msb 2-bits (signed) 1179 * dY msb 2-bits (signed) 1180 * timestamp 18-bits 1181 * 1182 * followed by (up to 5?) touch reports of 64-bits each 1183 * 1184 * abs W 12-bits (signed) 1185 * abs Z 12-bits (signed) 1186 * axis major 8-bits 1187 * axis minor 8-bits 1188 * pressure 6-bits 1189 * id 4-bits 1190 * angle 6-bits (from E(0)->N(32)->W(64)) 1191 * unknown 4-bits 1192 * phase 4-bits 1193 */ 1194 1195 static const struct { 1196 struct hid_location dXl; 1197 struct hid_location dYl; 1198 struct hid_location button1; 1199 struct hid_location button2; 1200 struct hid_location dXm; 1201 struct hid_location dYm; 1202 struct hid_location timestamp; 1203 } magic = { 1204 .dXl = { .pos = 0, .size = 8 }, 1205 .dYl = { .pos = 8, .size = 8 }, 1206 .button1 = { .pos = 16, .size = 1 }, 1207 .button2 = { .pos = 17, .size = 1 }, 1208 .dXm = { .pos = 18, .size = 2 }, 1209 .dYm = { .pos = 20, .size = 2 }, 1210 .timestamp = { .pos = 22, .size = 18 }, 1211 }; 1212 1213 static const struct { 1214 struct hid_location aW; 1215 struct hid_location aZ; 1216 struct hid_location major; 1217 struct hid_location minor; 1218 struct hid_location pressure; 1219 struct hid_location id; 1220 struct hid_location angle; 1221 struct hid_location unknown; 1222 struct hid_location phase; 1223 } touch = { 1224 .aW = { .pos = 0, .size = 12 }, 1225 .aZ = { .pos = 12, .size = 12 }, 1226 .major = { .pos = 24, .size = 8 }, 1227 .minor = { .pos = 32, .size = 8 }, 1228 .pressure = { .pos = 40, .size = 6 }, 1229 .id = { .pos = 46, .size = 4 }, 1230 .angle = { .pos = 50, .size = 6 }, 1231 .unknown = { .pos = 56, .size = 4 }, 1232 .phase = { .pos = 60, .size = 4 }, 1233 }; 1234 1235 /* 1236 * the phase of the touch starts at 0x01 as the finger is first detected 1237 * approaching the mouse, increasing to 0x04 while the finger is touching, 1238 * then increases towards 0x07 as the finger is lifted, and we get 0x00 1239 * when the touch is cancelled. The values below seem to be produced for 1240 * every touch, the others less consistently depending on how fast the 1241 * approach or departure is. 1242 * 1243 * In fact we ignore touches unless they are in the steady 0x04 phase. 1244 */ 1245 #define BTMAGIC_PHASE_START 0x3 1246 #define BTMAGIC_PHASE_CONT 0x4 1247 #define BTMAGIC_PHASE_END 0x7 1248 #define BTMAGIC_PHASE_CANCEL 0x0 1249 1250 static void 1251 btmagic_input_magic(struct btmagic_softc *sc, uint8_t *data, size_t len) 1252 { 1253 uint32_t mb; 1254 int dx, dy, dz, dw; 1255 int id, nf, az, aw, tz, tw; 1256 int s; 1257 1258 if (((len - 5) % 8) != 0) 1259 return; 1260 1261 dx = (hid_get_data(data, &magic.dXm) << 8) 1262 | (hid_get_data(data, &magic.dXl) & 0xff); 1263 dx = btmagic_scale(dx, &sc->sc_rx, sc->sc_resolution); 1264 1265 dy = (hid_get_data(data, &magic.dYm) << 8) 1266 | (hid_get_data(data, &magic.dYl) & 0xff); 1267 dy = btmagic_scale(dy, &sc->sc_ry, sc->sc_resolution); 1268 1269 mb = 0; 1270 if (hid_get_udata(data, &magic.button1)) 1271 mb |= __BIT(0); 1272 if (hid_get_udata(data, &magic.button2)) 1273 mb |= __BIT(2); 1274 1275 nf = 0; 1276 dz = 0; 1277 dw = 0; 1278 len = (len - 5) / 8; 1279 for (data += 5; len-- > 0; data += 8) { 1280 id = hid_get_udata(data, &touch.id); 1281 az = hid_get_data(data, &touch.aZ); 1282 aw = hid_get_data(data, &touch.aW); 1283 1284 /* 1285 * scrolling is triggered by an established touch moving 1286 * beyond a minimum distance from its start point and is 1287 * cancelled as the touch starts to fade. 1288 * 1289 * Multiple touches may be scrolling simultaneously, the 1290 * effect is cumulative. 1291 */ 1292 1293 switch (hid_get_udata(data, &touch.phase)) { 1294 case BTMAGIC_PHASE_CONT: 1295 tz = az - sc->sc_az[id]; 1296 tw = aw - sc->sc_aw[id]; 1297 1298 if (ISSET(sc->sc_smask, id)) { 1299 /* scrolling finger */ 1300 dz += btmagic_scale(tz, &sc->sc_rz, 1301 sc->sc_resolution / sc->sc_scale); 1302 dw += btmagic_scale(tw, &sc->sc_rw, 1303 sc->sc_resolution / sc->sc_scale); 1304 } else if (abs(tz) > sc->sc_dist 1305 || abs(tw) > sc->sc_dist) { 1306 /* new scrolling finger */ 1307 if (sc->sc_smask == 0) { 1308 sc->sc_rz = 0; 1309 sc->sc_rw = 0; 1310 } 1311 1312 SET(sc->sc_smask, id); 1313 } else { 1314 /* not scrolling finger */ 1315 az = sc->sc_az[id]; 1316 aw = sc->sc_aw[id]; 1317 } 1318 1319 /* count firm touches for middle-click */ 1320 if (hid_get_udata(data, &touch.pressure) > sc->sc_firm) 1321 nf++; 1322 1323 break; 1324 1325 default: 1326 CLR(sc->sc_smask, id); 1327 break; 1328 } 1329 1330 sc->sc_az[id] = az; 1331 sc->sc_aw[id] = aw; 1332 } 1333 1334 /* 1335 * The mouse only has one click detector, and says left or right but 1336 * never both. We convert multiple firm touches while clicking into 1337 * a middle button press, and cancel any scroll effects while click 1338 * is active. 1339 */ 1340 if (mb != 0) { 1341 if (sc->sc_mb != 0) 1342 mb = sc->sc_mb; 1343 else if (nf > 1) 1344 mb = __BIT(1); 1345 1346 sc->sc_smask = 0; 1347 dz = 0; 1348 dw = 0; 1349 } 1350 1351 if (dx != 0 || dy != 0 || dz != 0 || dw != 0 || mb != sc->sc_mb) { 1352 sc->sc_mb = mb; 1353 1354 s = spltty(); 1355 wsmouse_input(sc->sc_wsmouse, mb, 1356 dx, -dy, -dz, dw, WSMOUSE_INPUT_DELTA); 1357 splx(s); 1358 } 1359 } 1360