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