1 /* $OpenBSD: uhidpp.c,v 1.18 2021/08/17 11:30:45 anton Exp $ */ 2 3 /* 4 * Copyright (c) 2021 Anton Lindqvist <anton@openbsd.org> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 #include <sys/param.h> 20 #include <sys/systm.h> 21 #include <sys/kernel.h> 22 #include <sys/device.h> 23 #include <sys/mutex.h> 24 #include <sys/sensors.h> 25 26 #include <dev/usb/usb.h> 27 #include <dev/usb/usbhid.h> 28 #include <dev/usb/usbdi.h> 29 #include <dev/usb/usbdevs.h> 30 #include <dev/usb/uhidev.h> 31 32 /* #define UHIDPP_DEBUG */ 33 #ifdef UHIDPP_DEBUG 34 35 #define DPRINTF(x...) do { \ 36 if (uhidpp_debug) \ 37 printf(x); \ 38 } while (0) 39 40 #define DREPORT(prefix, repid, buf, len) do { \ 41 if (uhidpp_debug) \ 42 uhidd_dump_report((prefix), (repid), (buf), (len)); \ 43 } while (0) 44 45 void uhidd_dump_report(const char *, uint8_t, const unsigned char *, u_int); 46 47 int uhidpp_debug = 1; 48 49 #else 50 51 #define DPRINTF(x...) 52 #define DREPORT(prefix, repid, buf, len) 53 54 #endif 55 56 #define HIDPP_LINK_STATUS(x) ((x) & (1 << 7)) 57 58 #define HIDPP_REPORT_ID_SHORT 0x10 59 #define HIDPP_REPORT_ID_LONG 0x11 60 61 /* 62 * Length of reports. Note that the effective length is always +1 as 63 * uhidev_set_report() prepends the report ID. 64 */ 65 #define HIDPP_REPORT_SHORT_LENGTH (7 - 1) 66 #define HIDPP_REPORT_LONG_LENGTH (20 - 1) 67 68 /* 69 * Maximum number of allowed parameters for reports. Note, the parameters always 70 * starts at offset 3 for both RAP and FAP reports. 71 */ 72 #define HIDPP_REPORT_SHORT_PARAMS_MAX (HIDPP_REPORT_SHORT_LENGTH - 3) 73 #define HIDPP_REPORT_LONG_PARAMS_MAX (HIDPP_REPORT_LONG_LENGTH - 3) 74 75 #define HIDPP_DEVICE_ID_RECEIVER 0xff 76 77 #define HIDPP_FEAT_ROOT_IDX 0x00 78 #define HIDPP_FEAT_ROOT_PING_FUNC 0x01 79 #define HIDPP_FEAT_ROOT_PING_DATA 0x5a 80 81 #define HIDPP_SET_REGISTER 0x80 82 #define HIDPP_GET_REGISTER 0x81 83 #define HIDPP_SET_LONG_REGISTER 0x82 84 #define HIDPP_GET_LONG_REGISTER 0x83 85 86 #define HIDPP_REG_ENABLE_REPORTS 0x00 87 #define HIDPP_REG_PAIRING_INFORMATION 0xb5 88 89 #define HIDPP_NOTIF_DEVICE_BATTERY_STATUS (1 << 4) 90 #define HIDPP_NOTIF_RECEIVER_WIRELESS (1 << 0) 91 #define HIDPP_NOTIF_RECEIVER_SOFTWARE_PRESENT (1 << 3) 92 93 /* HID++ 1.0 error codes. */ 94 #define HIDPP_ERROR 0x8f 95 #define HIDPP_ERROR_SUCCESS 0x00 96 #define HIDPP_ERROR_INVALID_SUBID 0x01 97 #define HIDPP_ERROR_INVALID_ADRESS 0x02 98 #define HIDPP_ERROR_INVALID_VALUE 0x03 99 #define HIDPP_ERROR_CONNECT_FAIL 0x04 100 #define HIDPP_ERROR_TOO_MANY_DEVICES 0x05 101 #define HIDPP_ERROR_ALREADY_EXISTS 0x06 102 #define HIDPP_ERROR_BUSY 0x07 103 #define HIDPP_ERROR_UNKNOWN_DEVICE 0x08 104 #define HIDPP_ERROR_RESOURCE_ERROR 0x09 105 #define HIDPP_ERROR_REQUEST_UNAVAILABLE 0x0a 106 #define HIDPP_ERROR_INVALID_PARAM_VALUE 0x0b 107 #define HIDPP_ERROR_WRONG_PIN_CODE 0x0c 108 109 /* 110 * The software ID is added to feature access reports (FAP) and used to 111 * distinguish responses from notifications. Note, the software ID must be 112 * greater than zero which is reserved for notifications. 113 */ 114 #define HIDPP_SOFTWARE_ID 0x01 115 #define HIDPP_SOFTWARE_ID_LEN 4 116 117 #define HIDPP20_FEAT_ROOT_ID 0x0000 118 #define HIDPP20_FEAT_ROOT_GET_FEATURE_FUNC 0x0000 119 120 #define HIDPP20_FEAT_FEATURE_ID 0x0001 121 #define HIDPP20_FEAT_FEATURE_COUNT_FUNC 0x0000 122 #define HIDPP20_FEAT_FEATURE_ID_FUNC 0x0001 123 124 #define HIDPP20_FEAT_BATTERY_ID 0x1000 125 #define HIDPP20_FEAT_BATTERY_LEVEL_FUNC 0x0000 126 #define HIDPP20_FEAT_BATTERY_CAPABILITY_FUNC 0x0001 127 128 #define HIDPP20_BATTERY_STATUS_CHARGING_DONE 0x0003 129 130 #define HIDPP20_BATTERY_CAPABILITY_RECHARGEABLE 0x0004 131 132 /* HID++ 2.0 error codes. */ 133 #define HIDPP20_ERROR 0xff 134 #define HIDPP20_ERROR_NO_ERROR 0x00 135 #define HIDPP20_ERROR_UNKNOWN 0x01 136 #define HIDPP20_ERROR_INVALID_ARGUMENT 0x02 137 #define HIDPP20_ERROR_OUT_OF_RANGE 0x03 138 #define HIDPP20_ERROR_HARDWARE_ERROR 0x04 139 #define HIDPP20_ERROR_LOGITECH_INTERNAL 0x05 140 #define HIDPP20_ERROR_INVALID_FEATURE_INDEX 0x06 141 #define HIDPP20_ERROR_INVALID_FUNCTION_ID 0x07 142 #define HIDPP20_ERROR_BUSY 0x08 143 #define HIDPP20_ERROR_UNSUPPORTED 0x09 144 145 /* 146 * Sentinels used for interrupt response synchronization. The values must be 147 * disjoint from existing report IDs. 148 */ 149 #define UHIDPP_RESP_NONE 0 150 #define UHIDPP_RESP_WAIT 1 151 #define UHIDPP_RESP_ERROR 2 152 153 /* Maximum number of devices associated with a single receiver. */ 154 #define UHIDPP_NDEVICES 6 155 156 /* Maximum number of pending notifications. */ 157 #define UHIDPP_NNOTIFICATIONS 4 158 159 /* Number of sensors per paired device. */ 160 #define UHIDPP_NSENSORS 3 161 162 /* Feature access report used by the HID++ 2.0 (and greater) protocol. */ 163 struct fap { 164 uint8_t feature_idx; 165 uint8_t funcidx_swid; 166 uint8_t params[HIDPP_REPORT_LONG_PARAMS_MAX]; 167 }; 168 169 /* 170 * Register access report used by the HID++ 1.0 protocol. Receivers always uses 171 * this type of report. 172 */ 173 struct rap { 174 uint8_t sub_id; 175 uint8_t reg_address; 176 uint8_t params[HIDPP_REPORT_LONG_PARAMS_MAX]; 177 }; 178 179 struct uhidpp_report { 180 uint8_t device_id; 181 union { 182 struct fap fap; 183 struct rap rap; 184 }; 185 } __packed; 186 187 struct uhidpp_notification { 188 struct uhidpp_report n_rep; 189 unsigned int n_id; 190 }; 191 192 struct uhidpp_device { 193 uint8_t d_id; 194 uint8_t d_connected; 195 uint8_t d_major; 196 uint8_t d_minor; 197 uint8_t d_features; 198 #define UHIDPP_DEVICE_FEATURE_ROOT 0x01 199 #define UHIDPP_DEVICE_FEATURE_BATTERY 0x02 200 201 struct { 202 struct ksensor b_sens[UHIDPP_NSENSORS]; 203 uint8_t b_feature_idx; 204 uint8_t b_level; 205 uint8_t b_next_level; 206 uint8_t b_status; 207 uint8_t b_nlevels; 208 uint8_t b_rechargeable; 209 } d_battery; 210 }; 211 212 /* 213 * Locking: 214 * [m] sc_mtx 215 */ 216 struct uhidpp_softc { 217 struct uhidev sc_hdev; 218 struct usbd_device *sc_udev; 219 220 struct mutex sc_mtx; 221 222 struct uhidpp_device sc_devices[UHIDPP_NDEVICES]; 223 /* [m] connected devices */ 224 225 struct uhidpp_notification sc_notifications[UHIDPP_NNOTIFICATIONS]; 226 /* [m] pending notifications */ 227 228 struct usb_task sc_task; /* [m] notification task */ 229 230 struct ksensordev sc_sensdev; /* [m] */ 231 struct sensor_task *sc_senstsk; /* [m] */ 232 233 struct uhidpp_report *sc_req; /* [m] synchronous request buffer */ 234 struct uhidpp_report *sc_resp; /* [m] synchronous response buffer */ 235 u_int sc_resp_state; /* [m] synchronous response state */ 236 237 }; 238 239 int uhidpp_match(struct device *, void *, void *); 240 void uhidpp_attach(struct device *, struct device *, void *); 241 int uhidpp_detach(struct device *, int flags); 242 void uhidpp_intr(struct uhidev *addr, void *ibuf, u_int len); 243 void uhidpp_refresh(void *); 244 void uhidpp_task(void *); 245 int uhidpp_sleep(struct uhidpp_softc *, uint64_t); 246 247 void uhidpp_device_connect(struct uhidpp_softc *, struct uhidpp_device *); 248 void uhidpp_device_refresh(struct uhidpp_softc *, struct uhidpp_device *); 249 int uhidpp_device_features(struct uhidpp_softc *, struct uhidpp_device *); 250 251 struct uhidpp_notification *uhidpp_claim_notification(struct uhidpp_softc *); 252 int uhidpp_consume_notification(struct uhidpp_softc *, struct uhidpp_report *); 253 int uhidpp_is_notification(struct uhidpp_softc *, struct uhidpp_report *); 254 255 static int uhidpp_has_sensors(struct uhidpp_softc *); 256 257 int hidpp_get_protocol_version(struct uhidpp_softc *, uint8_t, uint8_t *, 258 uint8_t *); 259 260 int hidpp10_get_name(struct uhidpp_softc *, uint8_t, char *, size_t); 261 int hidpp10_get_serial(struct uhidpp_softc *, uint8_t, uint8_t *, size_t); 262 int hidpp10_get_type(struct uhidpp_softc *, uint8_t, const char **); 263 int hidpp10_enable_notifications(struct uhidpp_softc *, uint8_t); 264 265 int hidpp20_root_get_feature(struct uhidpp_softc *, uint8_t, uint16_t, 266 uint8_t *, uint8_t *); 267 int hidpp20_feature_get_count(struct uhidpp_softc *, uint8_t, uint8_t, 268 uint8_t *); 269 int hidpp20_feature_get_id(struct uhidpp_softc *, uint8_t, uint8_t, uint8_t, 270 uint16_t *, uint8_t *); 271 int hidpp20_battery_get_level_status(struct uhidpp_softc *, uint8_t, uint8_t, 272 uint8_t *, uint8_t *, uint8_t *); 273 int hidpp20_battery_get_capability(struct uhidpp_softc *, uint8_t, uint8_t, 274 uint8_t *, uint8_t *); 275 int hidpp20_battery_status_is_charging(uint8_t); 276 277 int hidpp_send_validate(uint8_t, int); 278 int hidpp_send_rap_report(struct uhidpp_softc *, uint8_t, uint8_t, 279 uint8_t, uint8_t, uint8_t *, int, struct uhidpp_report *); 280 int hidpp_send_fap_report(struct uhidpp_softc *, uint8_t, uint8_t, uint8_t, 281 uint8_t, uint8_t *, int, struct uhidpp_report *); 282 int hidpp_send_report(struct uhidpp_softc *, uint8_t, struct uhidpp_report *, 283 struct uhidpp_report *); 284 285 struct cfdriver uhidpp_cd = { 286 NULL, "uhidpp", DV_DULL 287 }; 288 289 const struct cfattach uhidpp_ca = { 290 sizeof(struct uhidpp_softc), 291 uhidpp_match, 292 uhidpp_attach, 293 uhidpp_detach, 294 }; 295 296 static const struct usb_devno uhidpp_devs[] = { 297 { USB_VENDOR_LOGITECH, USB_PRODUCT_ANY }, 298 }; 299 300 int 301 uhidpp_match(struct device *parent, void *match, void *aux) 302 { 303 struct uhidev_attach_arg *uha = (struct uhidev_attach_arg *)aux; 304 void *desc; 305 int descsiz, siz; 306 307 if (uha->reportid != HIDPP_REPORT_ID_SHORT && 308 uha->reportid != HIDPP_REPORT_ID_LONG) 309 return UMATCH_NONE; 310 311 if (usb_lookup(uhidpp_devs, 312 uha->uaa->vendor, uha->uaa->product) == NULL) 313 return UMATCH_NONE; 314 315 uhidev_get_report_desc(uha->parent, &desc, &descsiz); 316 siz = hid_report_size(desc, descsiz, hid_output, HIDPP_REPORT_ID_SHORT); 317 if (siz != HIDPP_REPORT_SHORT_LENGTH) 318 return UMATCH_NONE; 319 siz = hid_report_size(desc, descsiz, hid_output, HIDPP_REPORT_ID_LONG); 320 if (siz != HIDPP_REPORT_LONG_LENGTH) 321 return UMATCH_NONE; 322 323 return UMATCH_VENDOR_PRODUCT; 324 } 325 326 void 327 uhidpp_attach(struct device *parent, struct device *self, void *aux) 328 { 329 struct uhidpp_softc *sc = (struct uhidpp_softc *)self; 330 struct uhidev_attach_arg *uha = (struct uhidev_attach_arg *)aux; 331 struct usb_attach_arg *uaa = uha->uaa; 332 int error, i; 333 int npaired = 0; 334 335 sc->sc_hdev.sc_intr = uhidpp_intr; 336 sc->sc_hdev.sc_udev = uaa->device; 337 sc->sc_hdev.sc_parent = uha->parent; 338 sc->sc_hdev.sc_report_id = uha->reportid; 339 /* The largest supported report dictates the sizes. */ 340 sc->sc_hdev.sc_isize = HIDPP_REPORT_LONG_LENGTH; 341 sc->sc_hdev.sc_osize = HIDPP_REPORT_LONG_LENGTH; 342 343 sc->sc_udev = uaa->device; 344 345 mtx_init(&sc->sc_mtx, IPL_USB); 346 347 sc->sc_resp = NULL; 348 sc->sc_resp_state = UHIDPP_RESP_NONE; 349 350 error = uhidev_open(&sc->sc_hdev); 351 if (error) { 352 printf(" open error %d\n", error); 353 return; 354 } 355 356 usb_init_task(&sc->sc_task, uhidpp_task, sc, USB_TASK_TYPE_GENERIC); 357 358 mtx_enter(&sc->sc_mtx); 359 360 /* 361 * Wire up report device handlers before issuing commands to the device 362 * in order to receive responses. Necessary as uhidev by default 363 * performs the wiring after the attach routine has returned. 364 */ 365 error = uhidev_set_report_dev(sc->sc_hdev.sc_parent, &sc->sc_hdev, 366 HIDPP_REPORT_ID_SHORT); 367 if (error) { 368 printf(" short report error %d\n", error); 369 return; 370 } 371 error = uhidev_set_report_dev(sc->sc_hdev.sc_parent, &sc->sc_hdev, 372 HIDPP_REPORT_ID_LONG); 373 if (error) { 374 printf(" long report error %d\n", error); 375 return; 376 } 377 378 /* Probe paired devices. */ 379 for (i = 0; i < UHIDPP_NDEVICES; i++) { 380 char name[16]; 381 uint8_t serial[4]; 382 struct uhidpp_device *dev = &sc->sc_devices[i]; 383 const char *type; 384 uint8_t device_id = i + 1; 385 386 dev->d_id = device_id; 387 388 if (hidpp10_get_serial(sc, device_id, serial, sizeof(serial)) || 389 hidpp10_get_type(sc, device_id, &type) || 390 hidpp10_get_name(sc, device_id, name, sizeof(name))) 391 continue; 392 393 if (npaired > 0) 394 printf(","); 395 printf(" device %d", device_id); 396 printf(" %s", type); 397 printf(" \"%s\"", name); 398 printf(" serial %02x-%02x-%02x-%02x", 399 serial[0], serial[1], serial[2], serial[3]); 400 npaired++; 401 } 402 if (npaired == 0) 403 goto out; 404 405 /* Enable notifications for the receiver. */ 406 error = hidpp10_enable_notifications(sc, HIDPP_DEVICE_ID_RECEIVER); 407 if (error) 408 printf(" error %d", error); 409 410 out: 411 mtx_leave(&sc->sc_mtx); 412 printf("\n"); 413 } 414 415 int 416 uhidpp_detach(struct device *self, int flags) 417 { 418 struct uhidpp_softc *sc = (struct uhidpp_softc *)self; 419 int i; 420 421 usb_rem_wait_task(sc->sc_udev, &sc->sc_task); 422 423 if (sc->sc_senstsk != NULL) 424 sensor_task_unregister(sc->sc_senstsk); 425 426 KASSERT(sc->sc_resp_state == UHIDPP_RESP_NONE); 427 428 if (uhidpp_has_sensors(sc)) 429 sensordev_deinstall(&sc->sc_sensdev); 430 431 for (i = 0; i < UHIDPP_NDEVICES; i++) { 432 struct uhidpp_device *dev = &sc->sc_devices[i]; 433 struct ksensor *sens = dev->d_battery.b_sens; 434 435 if (!dev->d_connected) 436 continue; 437 438 sensor_detach(&sc->sc_sensdev, &sens[0]); 439 sensor_detach(&sc->sc_sensdev, &sens[1]); 440 if (dev->d_battery.b_rechargeable) 441 sensor_detach(&sc->sc_sensdev, &sens[2]); 442 } 443 444 uhidev_close(&sc->sc_hdev); 445 446 return 0; 447 } 448 449 void 450 uhidpp_intr(struct uhidev *addr, void *buf, u_int len) 451 { 452 struct uhidpp_softc *sc = (struct uhidpp_softc *)addr; 453 struct uhidpp_report *rep = buf; 454 int dowake = 0; 455 uint8_t repid; 456 457 /* 458 * Ugliness ahead as the report ID is stripped of by uhidev_intr() but 459 * needed to determine if an error occurred. 460 * Note that an error response is always a short report even if the 461 * command that caused the error is a long report. 462 */ 463 repid = ((uint8_t *)buf)[-1]; 464 465 DREPORT(__func__, repid, buf, len); 466 467 mtx_enter(&sc->sc_mtx); 468 if (uhidpp_is_notification(sc, rep)) { 469 struct uhidpp_notification *ntf; 470 471 ntf = uhidpp_claim_notification(sc); 472 if (ntf != NULL) { 473 memcpy(&ntf->n_rep, buf, len); 474 usb_add_task(sc->sc_udev, &sc->sc_task); 475 } else { 476 DPRINTF("%s: too many notifications", __func__); 477 } 478 } else { 479 KASSERT(sc->sc_resp_state == UHIDPP_RESP_WAIT); 480 dowake = 1; 481 sc->sc_resp_state = repid; 482 memcpy(sc->sc_resp, buf, len); 483 } 484 mtx_leave(&sc->sc_mtx); 485 if (dowake) 486 wakeup(sc); 487 } 488 489 void 490 uhidpp_refresh(void *arg) 491 { 492 struct uhidpp_softc *sc = arg; 493 int i; 494 495 mtx_enter(&sc->sc_mtx); 496 for (i = 0; i < UHIDPP_NDEVICES; i++) { 497 struct uhidpp_device *dev = &sc->sc_devices[i]; 498 499 if (dev->d_connected) 500 uhidpp_device_refresh(sc, dev); 501 } 502 mtx_leave(&sc->sc_mtx); 503 } 504 505 void 506 uhidpp_task(void *arg) 507 { 508 struct uhidpp_softc *sc = arg; 509 510 mtx_enter(&sc->sc_mtx); 511 for (;;) { 512 struct uhidpp_report rep; 513 struct uhidpp_device *dev; 514 515 if (uhidpp_consume_notification(sc, &rep)) 516 break; 517 518 DPRINTF("%s: device_id=%d, sub_id=%02x\n", 519 __func__, rep.device_id, rep.rap.sub_id); 520 521 if (rep.device_id == 0 || rep.device_id > UHIDPP_NDEVICES) { 522 DPRINTF("%s: invalid device\n", __func__); 523 continue; 524 } 525 dev = &sc->sc_devices[rep.device_id - 1]; 526 527 switch (rep.rap.sub_id) { 528 case 0x0e: /* leds */ 529 case 0x40: /* disconnect */ 530 case 0x4b: /* pairing accepted */ 531 break; 532 case 0x41: /* connect */ 533 /* 534 * Do nothing if the link is reported to be out of 535 * range. This happens when a device has been idle for a 536 * while. 537 */ 538 if (HIDPP_LINK_STATUS(rep.rap.params[0])) 539 uhidpp_device_connect(sc, dev); 540 break; 541 } 542 } 543 mtx_leave(&sc->sc_mtx); 544 } 545 546 int 547 uhidpp_sleep(struct uhidpp_softc *sc, uint64_t nsecs) 548 { 549 return msleep_nsec(sc, &sc->sc_mtx, PZERO, "uhidpp", nsecs); 550 } 551 552 void 553 uhidpp_device_connect(struct uhidpp_softc *sc, struct uhidpp_device *dev) 554 { 555 struct ksensor *sens; 556 int error; 557 uint8_t feature_type; 558 559 MUTEX_ASSERT_LOCKED(&sc->sc_mtx); 560 561 /* A connected device will continously send connect events. */ 562 if (dev->d_connected) 563 return; 564 565 /* 566 * If features are already present, it must be a device lacking battery 567 * support. 568 */ 569 if (dev->d_features) 570 return; 571 572 error = hidpp_get_protocol_version(sc, dev->d_id, 573 &dev->d_major, &dev->d_minor); 574 if (error) { 575 DPRINTF("%s: protocol version failure: device_id=%d, " 576 "error=%d\n", 577 __func__, dev->d_id, error); 578 return; 579 } 580 581 DPRINTF("%s: device_id=%d, version=%d.%d\n", 582 __func__, dev->d_id, dev->d_major, dev->d_minor); 583 584 if (dev->d_major >= 2) { 585 error = uhidpp_device_features(sc, dev); 586 if (error) { 587 DPRINTF("%s: features failure: device_id=%d, " 588 "error=%d\n", 589 __func__, dev->d_id, error); 590 return; 591 } 592 593 error = hidpp20_root_get_feature(sc, dev->d_id, 594 HIDPP20_FEAT_BATTERY_ID, 595 &dev->d_battery.b_feature_idx, &feature_type); 596 if (error) { 597 DPRINTF("%s: battery feature index failure: " 598 "device_id=%d, error=%d\n", 599 __func__, dev->d_id, error); 600 return; 601 } 602 603 error = hidpp20_battery_get_capability(sc, 604 dev->d_id, dev->d_battery.b_feature_idx, 605 &dev->d_battery.b_nlevels, &dev->d_battery.b_rechargeable); 606 if (error) { 607 DPRINTF("%s: battery capability failure: device_id=%d, " 608 "error=%d\n", __func__, dev->d_id, error); 609 return; 610 } 611 612 } else { 613 return; 614 } 615 616 dev->d_connected = 1; 617 618 /* 619 * Delay installation of sensors until a device with battery support is 620 * connected. Allows sensorsd(8) to pick up hotplugged devices. 621 */ 622 if (!uhidpp_has_sensors(sc)) { 623 strlcpy(sc->sc_sensdev.xname, sc->sc_hdev.sc_dev.dv_xname, 624 sizeof(sc->sc_sensdev.xname)); 625 sensordev_install(&sc->sc_sensdev); 626 } 627 628 sens = &dev->d_battery.b_sens[0]; 629 strlcpy(sens->desc, "battery level", sizeof(sens->desc)); 630 sens->type = SENSOR_PERCENT; 631 sens->flags = SENSOR_FUNKNOWN; 632 sensor_attach(&sc->sc_sensdev, sens); 633 634 sens = &dev->d_battery.b_sens[1]; 635 strlcpy(sens->desc, "number of battery levels", sizeof(sens->desc)); 636 sens->type = SENSOR_INTEGER; 637 sens->value = dev->d_battery.b_nlevels; 638 sensor_attach(&sc->sc_sensdev, sens); 639 640 if (dev->d_battery.b_rechargeable) { 641 sens = &dev->d_battery.b_sens[2]; 642 strlcpy(sens->desc, "charger", sizeof(sens->desc)); 643 sens->type = SENSOR_INDICATOR; 644 sens->value = 0; 645 sensor_attach(&sc->sc_sensdev, sens); 646 } 647 648 if (sc->sc_senstsk == NULL) { 649 /* 650 * The mutex must be temporarily released while calling 651 * sensor_task_register() as it might end up sleeping. 652 */ 653 mtx_leave(&sc->sc_mtx); 654 sc->sc_senstsk = sensor_task_register(sc, uhidpp_refresh, 30); 655 mtx_enter(&sc->sc_mtx); 656 } 657 658 uhidpp_device_refresh(sc, dev); 659 } 660 661 void 662 uhidpp_device_refresh(struct uhidpp_softc *sc, struct uhidpp_device *dev) 663 { 664 MUTEX_ASSERT_LOCKED(&sc->sc_mtx); 665 666 if (dev->d_major >= 2) { 667 int charging, error; 668 669 error = hidpp20_battery_get_level_status(sc, dev->d_id, 670 dev->d_battery.b_feature_idx, 671 &dev->d_battery.b_level, &dev->d_battery.b_next_level, 672 &dev->d_battery.b_status); 673 if (error) { 674 DPRINTF("%s: battery status failure: device_id=%d, " 675 "error=%d\n", 676 __func__, dev->d_id, error); 677 return; 678 } 679 680 charging = hidpp20_battery_status_is_charging( 681 dev->d_battery.b_status); 682 683 dev->d_battery.b_sens[0].value = dev->d_battery.b_level * 1000; 684 dev->d_battery.b_sens[0].flags &= ~SENSOR_FUNKNOWN; 685 if (dev->d_battery.b_nlevels < 10) { 686 /* 687 * According to the HID++ 2.0 specification, less than 688 * 10 levels should be mapped to the following 4 levels: 689 * 690 * [0, 10] critical 691 * [11, 30] low 692 * [31, 80] good 693 * [81, 100] full 694 * 695 * Since sensors are limited to 3 valid statuses, clamp 696 * it even further. Unless the battery is charging in 697 * which the level cannot be trusted. 698 */ 699 if (charging) 700 dev->d_battery.b_sens[0].status = SENSOR_S_UNKNOWN; 701 else if (dev->d_battery.b_level <= 10) 702 dev->d_battery.b_sens[0].status = SENSOR_S_CRIT; 703 else if (dev->d_battery.b_level <= 30) 704 dev->d_battery.b_sens[0].status = SENSOR_S_WARN; 705 else 706 dev->d_battery.b_sens[0].status = SENSOR_S_OK; 707 } else { 708 /* 709 * XXX the device supports battery mileage. The current 710 * level must be checked against resp.fap.params[3] 711 * given by hidpp20_battery_get_capability(). 712 */ 713 dev->d_battery.b_sens[0].status = SENSOR_S_UNKNOWN; 714 } 715 716 if (dev->d_battery.b_rechargeable) 717 dev->d_battery.b_sens[2].value = charging; 718 } 719 } 720 721 /* 722 * Enumerate all supported HID++ 2.0 features for the given device. 723 */ 724 int 725 uhidpp_device_features(struct uhidpp_softc *sc, struct uhidpp_device *dev) 726 { 727 int error; 728 uint8_t count, feature_idx, feature_type, i; 729 730 /* All devices support the root feature. */ 731 dev->d_features |= UHIDPP_DEVICE_FEATURE_ROOT; 732 733 error = hidpp20_root_get_feature(sc, dev->d_id, 734 HIDPP20_FEAT_FEATURE_ID, 735 &feature_idx, &feature_type); 736 if (error) { 737 DPRINTF("%s: feature index failure: device_id=%d, error=%d\n", 738 __func__, dev->d_id, error); 739 return error; 740 } 741 742 error = hidpp20_feature_get_count(sc, dev->d_id, feature_idx, &count); 743 if (error) { 744 DPRINTF("%s: feature count failure: device_id=%d, error=%d\n", 745 __func__, dev->d_id, error); 746 return error; 747 } 748 749 for (i = 1; i <= count; i++) { 750 uint16_t id; 751 uint8_t type; 752 753 error = hidpp20_feature_get_id(sc, dev->d_id, feature_idx, i, 754 &id, &type); 755 if (error) 756 continue; 757 758 if (id == HIDPP20_FEAT_BATTERY_ID) 759 dev->d_features |= UHIDPP_DEVICE_FEATURE_BATTERY; 760 761 DPRINTF("%s: idx=%d, id=%x, type=%x device_id=%d\n", 762 __func__, i, id, type, dev->d_id); 763 } 764 DPRINTF("%s: device_id=%d, count=%d, features=%x\n", 765 __func__, dev->d_id, count, dev->d_features); 766 767 if ((dev->d_features & UHIDPP_DEVICE_FEATURE_BATTERY) == 0) 768 return -ENODEV; 769 return 0; 770 } 771 772 /* 773 * Returns the next available notification slot, if available. 774 */ 775 struct uhidpp_notification * 776 uhidpp_claim_notification(struct uhidpp_softc *sc) 777 { 778 struct uhidpp_notification *ntf = NULL; 779 int nclaimed = 0; 780 int i; 781 782 MUTEX_ASSERT_LOCKED(&sc->sc_mtx); 783 784 for (i = 0; i < UHIDPP_NNOTIFICATIONS; i++) { 785 struct uhidpp_notification *tmp = &sc->sc_notifications[i]; 786 787 if (tmp->n_id > 0) 788 nclaimed++; 789 else if (ntf == NULL) 790 ntf = tmp; 791 } 792 793 if (ntf == NULL) 794 return NULL; 795 ntf->n_id = nclaimed + 1; 796 return ntf; 797 } 798 799 /* 800 * Consume the first unhandled notification, if present. 801 */ 802 int 803 uhidpp_consume_notification(struct uhidpp_softc *sc, struct uhidpp_report *rep) 804 { 805 struct uhidpp_notification *ntf = NULL; 806 int i; 807 808 MUTEX_ASSERT_LOCKED(&sc->sc_mtx); 809 810 for (i = 0; i < UHIDPP_NNOTIFICATIONS; i++) { 811 struct uhidpp_notification *tmp = &sc->sc_notifications[i]; 812 813 if (tmp->n_id > 0 && (ntf == NULL || tmp->n_id < ntf->n_id)) 814 ntf = tmp; 815 } 816 if (ntf == NULL) 817 return 1; 818 819 memcpy(rep, &ntf->n_rep, sizeof(*rep)); 820 ntf->n_id = 0; 821 return 0; 822 } 823 824 825 /* 826 * Returns non-zero if the given report is a notification. Otherwise, it must be 827 * a response. 828 */ 829 int 830 uhidpp_is_notification(struct uhidpp_softc *sc, struct uhidpp_report *rep) 831 { 832 /* Not waiting for a response. */ 833 if (sc->sc_req == NULL) 834 return 1; 835 836 /* Everything except the parameters must be repeated in a response. */ 837 if (sc->sc_req->device_id == rep->device_id && 838 sc->sc_req->rap.sub_id == rep->rap.sub_id && 839 sc->sc_req->rap.reg_address == rep->rap.reg_address) 840 return 0; 841 842 /* An error must always be a response. */ 843 if ((rep->rap.sub_id == HIDPP_ERROR || 844 rep->fap.feature_idx == HIDPP20_ERROR) && 845 rep->fap.funcidx_swid == sc->sc_req->fap.feature_idx && 846 rep->fap.params[0] == sc->sc_req->fap.funcidx_swid) 847 return 0; 848 849 return 1; 850 } 851 852 static int 853 uhidpp_has_sensors(struct uhidpp_softc *sc) 854 { 855 return sc->sc_sensdev.xname[0] != '\0'; 856 } 857 858 int 859 hidpp_get_protocol_version(struct uhidpp_softc *sc, uint8_t device_id, 860 uint8_t *major, uint8_t *minor) 861 { 862 struct uhidpp_report resp; 863 uint8_t params[3] = { 0, 0, HIDPP_FEAT_ROOT_PING_DATA }; 864 int error; 865 866 error = hidpp_send_fap_report(sc, 867 HIDPP_REPORT_ID_SHORT, 868 device_id, 869 HIDPP_FEAT_ROOT_IDX, 870 HIDPP_FEAT_ROOT_PING_FUNC, 871 params, sizeof(params), &resp); 872 if (error == HIDPP_ERROR_INVALID_SUBID) { 873 *major = 1; 874 *minor = 0; 875 return 0; 876 } 877 if (error) 878 return error; 879 if (resp.rap.params[2] != HIDPP_FEAT_ROOT_PING_DATA) 880 return -EPROTO; 881 882 *major = resp.fap.params[0]; 883 *minor = resp.fap.params[1]; 884 return 0; 885 } 886 887 int 888 hidpp10_get_name(struct uhidpp_softc *sc, uint8_t device_id, 889 char *buf, size_t bufsiz) 890 { 891 struct uhidpp_report resp; 892 int error; 893 uint8_t params[1] = { 0x40 + (device_id - 1) }; 894 uint8_t len; 895 896 error = hidpp_send_rap_report(sc, 897 HIDPP_REPORT_ID_SHORT, 898 HIDPP_DEVICE_ID_RECEIVER, 899 HIDPP_GET_LONG_REGISTER, 900 HIDPP_REG_PAIRING_INFORMATION, 901 params, sizeof(params), &resp); 902 if (error) 903 return error; 904 905 len = resp.rap.params[1]; 906 if (len + 2 > sizeof(resp.rap.params)) 907 return -ENAMETOOLONG; 908 if (len > bufsiz - 1) 909 len = bufsiz - 1; 910 memcpy(buf, &resp.rap.params[2], len); 911 buf[len] = '\0'; 912 return 0; 913 } 914 915 int 916 hidpp10_get_serial(struct uhidpp_softc *sc, uint8_t device_id, 917 uint8_t *buf, size_t bufsiz) 918 { 919 struct uhidpp_report resp; 920 int error; 921 uint8_t params[1] = { 0x30 + (device_id - 1) }; 922 uint8_t len; 923 924 error = hidpp_send_rap_report(sc, 925 HIDPP_REPORT_ID_SHORT, 926 HIDPP_DEVICE_ID_RECEIVER, 927 HIDPP_GET_LONG_REGISTER, 928 HIDPP_REG_PAIRING_INFORMATION, 929 params, sizeof(params), &resp); 930 if (error) 931 return error; 932 933 len = 4; 934 if (bufsiz < len) 935 len = bufsiz; 936 memcpy(buf, &resp.rap.params[1], len); 937 return 0; 938 } 939 940 int 941 hidpp10_get_type(struct uhidpp_softc *sc, uint8_t device_id, const char **type) 942 { 943 struct uhidpp_report resp; 944 int error; 945 uint8_t params[1] = { 0x20 + (device_id - 1) }; 946 947 error = hidpp_send_rap_report(sc, 948 HIDPP_REPORT_ID_SHORT, 949 HIDPP_DEVICE_ID_RECEIVER, 950 HIDPP_GET_LONG_REGISTER, 951 HIDPP_REG_PAIRING_INFORMATION, 952 params, sizeof(params), &resp); 953 if (error) 954 return error; 955 956 switch (resp.rap.params[7]) { 957 case 0x00: 958 *type = "unknown"; 959 return 0; 960 case 0x01: 961 *type = "keyboard"; 962 return 0; 963 case 0x02: 964 *type = "mouse"; 965 return 0; 966 case 0x03: 967 *type = "numpad"; 968 return 0; 969 case 0x04: 970 *type = "presenter"; 971 return 0; 972 case 0x08: 973 *type = "trackball"; 974 return 0; 975 case 0x09: 976 *type = "touchpad"; 977 return 0; 978 } 979 return -ENOENT; 980 } 981 982 int 983 hidpp10_enable_notifications(struct uhidpp_softc *sc, uint8_t device_id) 984 { 985 struct uhidpp_report resp; 986 uint8_t params[3]; 987 988 /* Device reporting flags. */ 989 params[0] = HIDPP_NOTIF_DEVICE_BATTERY_STATUS; 990 /* Receiver reporting flags. */ 991 params[1] = HIDPP_NOTIF_RECEIVER_WIRELESS | 992 HIDPP_NOTIF_RECEIVER_SOFTWARE_PRESENT; 993 /* Device reporting flags (continued). */ 994 params[2] = 0; 995 996 return hidpp_send_rap_report(sc, 997 HIDPP_REPORT_ID_SHORT, 998 device_id, 999 HIDPP_SET_REGISTER, 1000 HIDPP_REG_ENABLE_REPORTS, 1001 params, sizeof(params), &resp); 1002 } 1003 1004 int 1005 hidpp20_root_get_feature(struct uhidpp_softc *sc, uint8_t device_id, 1006 uint16_t feature, uint8_t *feature_idx, uint8_t *feature_type) 1007 { 1008 struct uhidpp_report resp; 1009 uint8_t params[2] = { feature >> 8, feature & 0xff }; 1010 int error; 1011 1012 error = hidpp_send_fap_report(sc, 1013 HIDPP_REPORT_ID_LONG, 1014 device_id, 1015 HIDPP20_FEAT_ROOT_ID, 1016 HIDPP20_FEAT_ROOT_GET_FEATURE_FUNC, 1017 params, sizeof(params), &resp); 1018 if (error) 1019 return error; 1020 1021 if (resp.fap.params[0] == 0) 1022 return -ENOENT; 1023 1024 *feature_idx = resp.fap.params[0]; 1025 *feature_type = resp.fap.params[1]; 1026 return 0; 1027 } 1028 1029 int 1030 hidpp20_feature_get_count(struct uhidpp_softc *sc, uint8_t device_id, 1031 uint8_t feature_idx, uint8_t *count) 1032 { 1033 struct uhidpp_report resp; 1034 int error; 1035 1036 error = hidpp_send_fap_report(sc, 1037 HIDPP_REPORT_ID_LONG, 1038 device_id, 1039 feature_idx, 1040 HIDPP20_FEAT_FEATURE_COUNT_FUNC, 1041 NULL, 0, &resp); 1042 if (error) 1043 return error; 1044 1045 *count = resp.fap.params[0]; 1046 return 0; 1047 } 1048 1049 int 1050 hidpp20_feature_get_id(struct uhidpp_softc *sc, uint8_t device_id, 1051 uint8_t feature_idx, uint8_t idx, uint16_t *id, uint8_t *type) 1052 { 1053 struct uhidpp_report resp; 1054 uint8_t params[1] = { idx }; 1055 int error; 1056 1057 error = hidpp_send_fap_report(sc, 1058 HIDPP_REPORT_ID_LONG, 1059 device_id, 1060 feature_idx, 1061 HIDPP20_FEAT_FEATURE_ID_FUNC, 1062 params, sizeof(params), &resp); 1063 if (error) 1064 return error; 1065 1066 *id = bemtoh16(resp.fap.params); 1067 *type = resp.fap.params[2]; 1068 return 0; 1069 } 1070 1071 int 1072 hidpp20_battery_get_level_status(struct uhidpp_softc *sc, uint8_t device_id, 1073 uint8_t feature_idx, uint8_t *level, uint8_t *next_level, uint8_t *status) 1074 { 1075 struct uhidpp_report resp; 1076 int error; 1077 1078 error = hidpp_send_fap_report(sc, 1079 HIDPP_REPORT_ID_LONG, 1080 device_id, 1081 feature_idx, 1082 HIDPP20_FEAT_BATTERY_LEVEL_FUNC, 1083 NULL, 0, &resp); 1084 if (error) 1085 return error; 1086 1087 *level = resp.fap.params[0]; 1088 *next_level = resp.fap.params[1]; 1089 *status = resp.fap.params[2]; 1090 1091 /* 1092 * While charging, the reported level cannot be trusted. However, fake 1093 * the battery state once the charging is done. 1094 */ 1095 switch (hidpp20_battery_status_is_charging(*status)) { 1096 case HIDPP20_BATTERY_STATUS_CHARGING_DONE: 1097 *level = 100; 1098 *status = 0; 1099 break; 1100 } 1101 1102 return 0; 1103 } 1104 1105 int 1106 hidpp20_battery_get_capability(struct uhidpp_softc *sc, uint8_t device_id, 1107 uint8_t feature_idx, uint8_t *nlevels, uint8_t *rechargeable) 1108 { 1109 struct uhidpp_report resp; 1110 int error; 1111 1112 error = hidpp_send_fap_report(sc, 1113 HIDPP_REPORT_ID_LONG, 1114 device_id, 1115 feature_idx, 1116 HIDPP20_FEAT_BATTERY_CAPABILITY_FUNC, 1117 NULL, 0, &resp); 1118 if (error) 1119 return error; 1120 *nlevels = resp.fap.params[0]; 1121 *rechargeable = resp.fap.params[1] & 1122 HIDPP20_BATTERY_CAPABILITY_RECHARGEABLE; 1123 return 0; 1124 } 1125 1126 int 1127 hidpp20_battery_status_is_charging(uint8_t status) 1128 { 1129 switch (status) { 1130 case 1: /* recharging */ 1131 case 2: /* charge in final stage */ 1132 case 4: /* recharging below optimal speed */ 1133 return status; 1134 1135 case 3: /* charge complete */ 1136 return status; 1137 1138 case 0: /* discharging */ 1139 case 5: /* invalid battery type */ 1140 case 6: /* thermal error */ 1141 case 7: /* other charging error */ 1142 default: 1143 return 0; 1144 } 1145 } 1146 1147 int 1148 hidpp_send_validate(uint8_t report_id, int nparams) 1149 { 1150 if (report_id == HIDPP_REPORT_ID_SHORT) { 1151 if (nparams > HIDPP_REPORT_SHORT_PARAMS_MAX) 1152 return -EMSGSIZE; 1153 } else if (report_id == HIDPP_REPORT_ID_LONG) { 1154 if (nparams > HIDPP_REPORT_LONG_PARAMS_MAX) 1155 return -EMSGSIZE; 1156 } else { 1157 return -EINVAL; 1158 } 1159 return 0; 1160 } 1161 1162 int 1163 hidpp_send_fap_report(struct uhidpp_softc *sc, uint8_t report_id, 1164 uint8_t device_id, uint8_t feature_idx, uint8_t funcidx_swid, 1165 uint8_t *params, int nparams, struct uhidpp_report *resp) 1166 { 1167 struct uhidpp_report req; 1168 int error; 1169 1170 error = hidpp_send_validate(report_id, nparams); 1171 if (error) 1172 return error; 1173 1174 memset(&req, 0, sizeof(req)); 1175 req.device_id = device_id; 1176 req.fap.feature_idx = feature_idx; 1177 req.fap.funcidx_swid = 1178 (funcidx_swid << HIDPP_SOFTWARE_ID_LEN) | HIDPP_SOFTWARE_ID; 1179 memcpy(req.fap.params, params, nparams); 1180 return hidpp_send_report(sc, report_id, &req, resp); 1181 } 1182 1183 int 1184 hidpp_send_rap_report(struct uhidpp_softc *sc, uint8_t report_id, 1185 uint8_t device_id, uint8_t sub_id, uint8_t reg_address, 1186 uint8_t *params, int nparams, struct uhidpp_report *resp) 1187 { 1188 struct uhidpp_report req; 1189 int error; 1190 1191 error = hidpp_send_validate(report_id, nparams); 1192 if (error) 1193 return error; 1194 1195 memset(&req, 0, sizeof(req)); 1196 req.device_id = device_id; 1197 req.rap.sub_id = sub_id; 1198 req.rap.reg_address = reg_address; 1199 memcpy(req.rap.params, params, nparams); 1200 return hidpp_send_report(sc, report_id, &req, resp); 1201 } 1202 1203 int 1204 hidpp_send_report(struct uhidpp_softc *sc, uint8_t report_id, 1205 struct uhidpp_report *req, struct uhidpp_report *resp) 1206 { 1207 int error, len, n; 1208 1209 MUTEX_ASSERT_LOCKED(&sc->sc_mtx); 1210 1211 if (report_id == HIDPP_REPORT_ID_SHORT) 1212 len = HIDPP_REPORT_SHORT_LENGTH; 1213 else if (report_id == HIDPP_REPORT_ID_LONG) 1214 len = HIDPP_REPORT_LONG_LENGTH; 1215 else 1216 return -EINVAL; 1217 1218 DREPORT(__func__, report_id, (const unsigned char *)req, len); 1219 1220 /* Wait until any ongoing command has completed. */ 1221 while (sc->sc_resp_state != UHIDPP_RESP_NONE) 1222 uhidpp_sleep(sc, INFSLP); 1223 sc->sc_req = req; 1224 sc->sc_resp = resp; 1225 sc->sc_resp_state = UHIDPP_RESP_WAIT; 1226 /* 1227 * The mutex must be temporarily released while calling 1228 * uhidev_set_report() as it might end up sleeping. 1229 */ 1230 mtx_leave(&sc->sc_mtx); 1231 1232 n = uhidev_set_report(sc->sc_hdev.sc_parent, UHID_OUTPUT_REPORT, 1233 report_id, req, len); 1234 1235 mtx_enter(&sc->sc_mtx); 1236 if (len != n) { 1237 error = -EBUSY; 1238 goto out; 1239 } 1240 /* 1241 * The interrupt could already have been received while the mutex was 1242 * released. Otherwise, wait for it. 1243 */ 1244 if (sc->sc_resp_state == UHIDPP_RESP_WAIT) { 1245 /* Timeout taken from the hid-logitech-hidpp Linux driver. */ 1246 error = uhidpp_sleep(sc, SEC_TO_NSEC(5)); 1247 if (error) { 1248 error = -error; 1249 goto out; 1250 } 1251 } 1252 1253 if (sc->sc_resp_state == UHIDPP_RESP_ERROR) 1254 error = -EIO; 1255 else if (sc->sc_resp_state == HIDPP_REPORT_ID_SHORT && 1256 resp->rap.sub_id == HIDPP_ERROR) 1257 error = resp->rap.params[1]; 1258 else if (sc->sc_resp_state == HIDPP_REPORT_ID_LONG && 1259 resp->fap.feature_idx == HIDPP20_ERROR) 1260 error = resp->fap.params[1]; 1261 1262 out: 1263 sc->sc_req = NULL; 1264 sc->sc_resp = NULL; 1265 sc->sc_resp_state = UHIDPP_RESP_NONE; 1266 wakeup(sc); 1267 return error; 1268 } 1269 1270 #ifdef UHIDPP_DEBUG 1271 1272 void 1273 uhidd_dump_report(const char *prefix, uint8_t repid, const unsigned char *buf, 1274 u_int buflen) 1275 { 1276 u_int i; 1277 1278 printf("%s: %02x ", prefix, repid); 1279 for (i = 0; i < buflen; i++) { 1280 printf("%02x%s", buf[i], 1281 i == 2 ? " [" : (i + 1 < buflen ? " " : "")); 1282 } 1283 printf("]\n"); 1284 } 1285 1286 #endif 1287