1 /* $OpenBSD: uhidpp.c,v 1.20 2021/12/05 15:35:32 jsg 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 (!UHIDEV_CLAIM_MULTIPLE_REPORTID(uha)) 308 return UMATCH_NONE; 309 310 if (usb_lookup(uhidpp_devs, 311 uha->uaa->vendor, uha->uaa->product) == NULL) 312 return UMATCH_NONE; 313 314 uhidev_get_report_desc(uha->parent, &desc, &descsiz); 315 siz = hid_report_size(desc, descsiz, hid_output, HIDPP_REPORT_ID_SHORT); 316 if (siz != HIDPP_REPORT_SHORT_LENGTH) 317 return UMATCH_NONE; 318 siz = hid_report_size(desc, descsiz, hid_output, HIDPP_REPORT_ID_LONG); 319 if (siz != HIDPP_REPORT_LONG_LENGTH) 320 return UMATCH_NONE; 321 322 uha->claimed[HIDPP_REPORT_ID_SHORT] = 1; 323 uha->claimed[HIDPP_REPORT_ID_LONG] = 1; 324 return UMATCH_VENDOR_PRODUCT; 325 } 326 327 void 328 uhidpp_attach(struct device *parent, struct device *self, void *aux) 329 { 330 struct uhidpp_softc *sc = (struct uhidpp_softc *)self; 331 struct uhidev_attach_arg *uha = (struct uhidev_attach_arg *)aux; 332 struct usb_attach_arg *uaa = uha->uaa; 333 int error, i; 334 int npaired = 0; 335 336 sc->sc_hdev.sc_intr = uhidpp_intr; 337 sc->sc_hdev.sc_udev = uaa->device; 338 sc->sc_hdev.sc_parent = uha->parent; 339 sc->sc_hdev.sc_report_id = uha->reportid; 340 /* The largest supported report dictates the sizes. */ 341 sc->sc_hdev.sc_isize = HIDPP_REPORT_LONG_LENGTH; 342 sc->sc_hdev.sc_osize = HIDPP_REPORT_LONG_LENGTH; 343 344 sc->sc_udev = uaa->device; 345 346 mtx_init(&sc->sc_mtx, IPL_USB); 347 348 sc->sc_resp = NULL; 349 sc->sc_resp_state = UHIDPP_RESP_NONE; 350 351 error = uhidev_open(&sc->sc_hdev); 352 if (error) { 353 printf(" open error %d\n", error); 354 return; 355 } 356 357 usb_init_task(&sc->sc_task, uhidpp_task, sc, USB_TASK_TYPE_GENERIC); 358 359 mtx_enter(&sc->sc_mtx); 360 361 /* 362 * Wire up report device handlers before issuing commands to the device 363 * in order to receive responses. Necessary as uhidev by default 364 * performs the wiring after the attach routine has returned. 365 */ 366 error = uhidev_set_report_dev(sc->sc_hdev.sc_parent, &sc->sc_hdev, 367 HIDPP_REPORT_ID_SHORT); 368 if (error) { 369 mtx_leave(&sc->sc_mtx); 370 printf(" short report error %d\n", error); 371 return; 372 } 373 error = uhidev_set_report_dev(sc->sc_hdev.sc_parent, &sc->sc_hdev, 374 HIDPP_REPORT_ID_LONG); 375 if (error) { 376 mtx_leave(&sc->sc_mtx); 377 printf(" long report error %d\n", error); 378 return; 379 } 380 381 /* Probe paired devices. */ 382 for (i = 0; i < UHIDPP_NDEVICES; i++) { 383 char name[16]; 384 uint8_t serial[4]; 385 struct uhidpp_device *dev = &sc->sc_devices[i]; 386 const char *type; 387 uint8_t device_id = i + 1; 388 389 dev->d_id = device_id; 390 391 if (hidpp10_get_serial(sc, device_id, serial, sizeof(serial)) || 392 hidpp10_get_type(sc, device_id, &type) || 393 hidpp10_get_name(sc, device_id, name, sizeof(name))) 394 continue; 395 396 if (npaired > 0) 397 printf(","); 398 printf(" device %d", device_id); 399 printf(" %s", type); 400 printf(" \"%s\"", name); 401 printf(" serial %02x-%02x-%02x-%02x", 402 serial[0], serial[1], serial[2], serial[3]); 403 npaired++; 404 } 405 if (npaired == 0) 406 goto out; 407 408 /* Enable notifications for the receiver. */ 409 error = hidpp10_enable_notifications(sc, HIDPP_DEVICE_ID_RECEIVER); 410 if (error) 411 printf(" error %d", error); 412 413 out: 414 mtx_leave(&sc->sc_mtx); 415 printf("\n"); 416 } 417 418 int 419 uhidpp_detach(struct device *self, int flags) 420 { 421 struct uhidpp_softc *sc = (struct uhidpp_softc *)self; 422 int i; 423 424 usb_rem_wait_task(sc->sc_udev, &sc->sc_task); 425 426 if (sc->sc_senstsk != NULL) 427 sensor_task_unregister(sc->sc_senstsk); 428 429 KASSERT(sc->sc_resp_state == UHIDPP_RESP_NONE); 430 431 if (uhidpp_has_sensors(sc)) 432 sensordev_deinstall(&sc->sc_sensdev); 433 434 for (i = 0; i < UHIDPP_NDEVICES; i++) { 435 struct uhidpp_device *dev = &sc->sc_devices[i]; 436 struct ksensor *sens = dev->d_battery.b_sens; 437 438 if (!dev->d_connected) 439 continue; 440 441 sensor_detach(&sc->sc_sensdev, &sens[0]); 442 sensor_detach(&sc->sc_sensdev, &sens[1]); 443 if (dev->d_battery.b_rechargeable) 444 sensor_detach(&sc->sc_sensdev, &sens[2]); 445 } 446 447 uhidev_close(&sc->sc_hdev); 448 449 return 0; 450 } 451 452 void 453 uhidpp_intr(struct uhidev *addr, void *buf, u_int len) 454 { 455 struct uhidpp_softc *sc = (struct uhidpp_softc *)addr; 456 struct uhidpp_report *rep = buf; 457 int dowake = 0; 458 uint8_t repid; 459 460 /* 461 * Ugliness ahead as the report ID is stripped of by uhidev_intr() but 462 * needed to determine if an error occurred. 463 * Note that an error response is always a short report even if the 464 * command that caused the error is a long report. 465 */ 466 repid = ((uint8_t *)buf)[-1]; 467 468 DREPORT(__func__, repid, buf, len); 469 470 mtx_enter(&sc->sc_mtx); 471 if (uhidpp_is_notification(sc, rep)) { 472 struct uhidpp_notification *ntf; 473 474 ntf = uhidpp_claim_notification(sc); 475 if (ntf != NULL) { 476 memcpy(&ntf->n_rep, buf, len); 477 usb_add_task(sc->sc_udev, &sc->sc_task); 478 } else { 479 DPRINTF("%s: too many notifications", __func__); 480 } 481 } else { 482 KASSERT(sc->sc_resp_state == UHIDPP_RESP_WAIT); 483 dowake = 1; 484 sc->sc_resp_state = repid; 485 memcpy(sc->sc_resp, buf, len); 486 } 487 mtx_leave(&sc->sc_mtx); 488 if (dowake) 489 wakeup(sc); 490 } 491 492 void 493 uhidpp_refresh(void *arg) 494 { 495 struct uhidpp_softc *sc = arg; 496 int i; 497 498 mtx_enter(&sc->sc_mtx); 499 for (i = 0; i < UHIDPP_NDEVICES; i++) { 500 struct uhidpp_device *dev = &sc->sc_devices[i]; 501 502 if (dev->d_connected) 503 uhidpp_device_refresh(sc, dev); 504 } 505 mtx_leave(&sc->sc_mtx); 506 } 507 508 void 509 uhidpp_task(void *arg) 510 { 511 struct uhidpp_softc *sc = arg; 512 513 mtx_enter(&sc->sc_mtx); 514 for (;;) { 515 struct uhidpp_report rep; 516 struct uhidpp_device *dev; 517 518 if (uhidpp_consume_notification(sc, &rep)) 519 break; 520 521 DPRINTF("%s: device_id=%d, sub_id=%02x\n", 522 __func__, rep.device_id, rep.rap.sub_id); 523 524 if (rep.device_id == 0 || rep.device_id > UHIDPP_NDEVICES) { 525 DPRINTF("%s: invalid device\n", __func__); 526 continue; 527 } 528 dev = &sc->sc_devices[rep.device_id - 1]; 529 530 switch (rep.rap.sub_id) { 531 case 0x0e: /* leds */ 532 case 0x40: /* disconnect */ 533 case 0x4b: /* pairing accepted */ 534 break; 535 case 0x41: /* connect */ 536 /* 537 * Do nothing if the link is reported to be out of 538 * range. This happens when a device has been idle for a 539 * while. 540 */ 541 if (HIDPP_LINK_STATUS(rep.rap.params[0])) 542 uhidpp_device_connect(sc, dev); 543 break; 544 } 545 } 546 mtx_leave(&sc->sc_mtx); 547 } 548 549 int 550 uhidpp_sleep(struct uhidpp_softc *sc, uint64_t nsecs) 551 { 552 return msleep_nsec(sc, &sc->sc_mtx, PZERO, "uhidpp", nsecs); 553 } 554 555 void 556 uhidpp_device_connect(struct uhidpp_softc *sc, struct uhidpp_device *dev) 557 { 558 struct ksensor *sens; 559 int error; 560 uint8_t feature_type; 561 562 MUTEX_ASSERT_LOCKED(&sc->sc_mtx); 563 564 /* A connected device will continously send connect events. */ 565 if (dev->d_connected) 566 return; 567 568 /* 569 * If features are already present, it must be a device lacking battery 570 * support. 571 */ 572 if (dev->d_features) 573 return; 574 575 error = hidpp_get_protocol_version(sc, dev->d_id, 576 &dev->d_major, &dev->d_minor); 577 if (error) { 578 DPRINTF("%s: protocol version failure: device_id=%d, " 579 "error=%d\n", 580 __func__, dev->d_id, error); 581 return; 582 } 583 584 DPRINTF("%s: device_id=%d, version=%d.%d\n", 585 __func__, dev->d_id, dev->d_major, dev->d_minor); 586 587 if (dev->d_major >= 2) { 588 error = uhidpp_device_features(sc, dev); 589 if (error) { 590 DPRINTF("%s: features failure: device_id=%d, " 591 "error=%d\n", 592 __func__, dev->d_id, error); 593 return; 594 } 595 596 error = hidpp20_root_get_feature(sc, dev->d_id, 597 HIDPP20_FEAT_BATTERY_ID, 598 &dev->d_battery.b_feature_idx, &feature_type); 599 if (error) { 600 DPRINTF("%s: battery feature index failure: " 601 "device_id=%d, error=%d\n", 602 __func__, dev->d_id, error); 603 return; 604 } 605 606 error = hidpp20_battery_get_capability(sc, 607 dev->d_id, dev->d_battery.b_feature_idx, 608 &dev->d_battery.b_nlevels, &dev->d_battery.b_rechargeable); 609 if (error) { 610 DPRINTF("%s: battery capability failure: device_id=%d, " 611 "error=%d\n", __func__, dev->d_id, error); 612 return; 613 } 614 615 } else { 616 return; 617 } 618 619 dev->d_connected = 1; 620 621 /* 622 * Delay installation of sensors until a device with battery support is 623 * connected. Allows sensorsd(8) to pick up hotplugged devices. 624 */ 625 if (!uhidpp_has_sensors(sc)) { 626 strlcpy(sc->sc_sensdev.xname, sc->sc_hdev.sc_dev.dv_xname, 627 sizeof(sc->sc_sensdev.xname)); 628 sensordev_install(&sc->sc_sensdev); 629 } 630 631 sens = &dev->d_battery.b_sens[0]; 632 strlcpy(sens->desc, "battery level", sizeof(sens->desc)); 633 sens->type = SENSOR_PERCENT; 634 sens->flags = SENSOR_FUNKNOWN; 635 sensor_attach(&sc->sc_sensdev, sens); 636 637 sens = &dev->d_battery.b_sens[1]; 638 strlcpy(sens->desc, "number of battery levels", sizeof(sens->desc)); 639 sens->type = SENSOR_INTEGER; 640 sens->value = dev->d_battery.b_nlevels; 641 sensor_attach(&sc->sc_sensdev, sens); 642 643 if (dev->d_battery.b_rechargeable) { 644 sens = &dev->d_battery.b_sens[2]; 645 strlcpy(sens->desc, "charger", sizeof(sens->desc)); 646 sens->type = SENSOR_INDICATOR; 647 sens->value = 0; 648 sensor_attach(&sc->sc_sensdev, sens); 649 } 650 651 if (sc->sc_senstsk == NULL) { 652 /* 653 * The mutex must be temporarily released while calling 654 * sensor_task_register() as it might end up sleeping. 655 */ 656 mtx_leave(&sc->sc_mtx); 657 sc->sc_senstsk = sensor_task_register(sc, uhidpp_refresh, 30); 658 mtx_enter(&sc->sc_mtx); 659 } 660 661 uhidpp_device_refresh(sc, dev); 662 } 663 664 void 665 uhidpp_device_refresh(struct uhidpp_softc *sc, struct uhidpp_device *dev) 666 { 667 MUTEX_ASSERT_LOCKED(&sc->sc_mtx); 668 669 if (dev->d_major >= 2) { 670 int charging, error; 671 672 error = hidpp20_battery_get_level_status(sc, dev->d_id, 673 dev->d_battery.b_feature_idx, 674 &dev->d_battery.b_level, &dev->d_battery.b_next_level, 675 &dev->d_battery.b_status); 676 if (error) { 677 DPRINTF("%s: battery status failure: device_id=%d, " 678 "error=%d\n", 679 __func__, dev->d_id, error); 680 return; 681 } 682 683 charging = hidpp20_battery_status_is_charging( 684 dev->d_battery.b_status); 685 686 dev->d_battery.b_sens[0].value = dev->d_battery.b_level * 1000; 687 dev->d_battery.b_sens[0].flags &= ~SENSOR_FUNKNOWN; 688 if (dev->d_battery.b_nlevels < 10) { 689 /* 690 * According to the HID++ 2.0 specification, less than 691 * 10 levels should be mapped to the following 4 levels: 692 * 693 * [0, 10] critical 694 * [11, 30] low 695 * [31, 80] good 696 * [81, 100] full 697 * 698 * Since sensors are limited to 3 valid statuses, clamp 699 * it even further. Unless the battery is charging in 700 * which the level cannot be trusted. 701 */ 702 if (charging) 703 dev->d_battery.b_sens[0].status = SENSOR_S_UNKNOWN; 704 else if (dev->d_battery.b_level <= 10) 705 dev->d_battery.b_sens[0].status = SENSOR_S_CRIT; 706 else if (dev->d_battery.b_level <= 30) 707 dev->d_battery.b_sens[0].status = SENSOR_S_WARN; 708 else 709 dev->d_battery.b_sens[0].status = SENSOR_S_OK; 710 } else { 711 /* 712 * XXX the device supports battery mileage. The current 713 * level must be checked against resp.fap.params[3] 714 * given by hidpp20_battery_get_capability(). 715 */ 716 dev->d_battery.b_sens[0].status = SENSOR_S_UNKNOWN; 717 } 718 719 if (dev->d_battery.b_rechargeable) 720 dev->d_battery.b_sens[2].value = charging; 721 } 722 } 723 724 /* 725 * Enumerate all supported HID++ 2.0 features for the given device. 726 */ 727 int 728 uhidpp_device_features(struct uhidpp_softc *sc, struct uhidpp_device *dev) 729 { 730 int error; 731 uint8_t count, feature_idx, feature_type, i; 732 733 /* All devices support the root feature. */ 734 dev->d_features |= UHIDPP_DEVICE_FEATURE_ROOT; 735 736 error = hidpp20_root_get_feature(sc, dev->d_id, 737 HIDPP20_FEAT_FEATURE_ID, 738 &feature_idx, &feature_type); 739 if (error) { 740 DPRINTF("%s: feature index failure: device_id=%d, error=%d\n", 741 __func__, dev->d_id, error); 742 return error; 743 } 744 745 error = hidpp20_feature_get_count(sc, dev->d_id, feature_idx, &count); 746 if (error) { 747 DPRINTF("%s: feature count failure: device_id=%d, error=%d\n", 748 __func__, dev->d_id, error); 749 return error; 750 } 751 752 for (i = 1; i <= count; i++) { 753 uint16_t id; 754 uint8_t type; 755 756 error = hidpp20_feature_get_id(sc, dev->d_id, feature_idx, i, 757 &id, &type); 758 if (error) 759 continue; 760 761 if (id == HIDPP20_FEAT_BATTERY_ID) 762 dev->d_features |= UHIDPP_DEVICE_FEATURE_BATTERY; 763 764 DPRINTF("%s: idx=%d, id=%x, type=%x device_id=%d\n", 765 __func__, i, id, type, dev->d_id); 766 } 767 DPRINTF("%s: device_id=%d, count=%d, features=%x\n", 768 __func__, dev->d_id, count, dev->d_features); 769 770 if ((dev->d_features & UHIDPP_DEVICE_FEATURE_BATTERY) == 0) 771 return -ENODEV; 772 return 0; 773 } 774 775 /* 776 * Returns the next available notification slot, if available. 777 */ 778 struct uhidpp_notification * 779 uhidpp_claim_notification(struct uhidpp_softc *sc) 780 { 781 struct uhidpp_notification *ntf = NULL; 782 int nclaimed = 0; 783 int i; 784 785 MUTEX_ASSERT_LOCKED(&sc->sc_mtx); 786 787 for (i = 0; i < UHIDPP_NNOTIFICATIONS; i++) { 788 struct uhidpp_notification *tmp = &sc->sc_notifications[i]; 789 790 if (tmp->n_id > 0) 791 nclaimed++; 792 else if (ntf == NULL) 793 ntf = tmp; 794 } 795 796 if (ntf == NULL) 797 return NULL; 798 ntf->n_id = nclaimed + 1; 799 return ntf; 800 } 801 802 /* 803 * Consume the first unhandled notification, if present. 804 */ 805 int 806 uhidpp_consume_notification(struct uhidpp_softc *sc, struct uhidpp_report *rep) 807 { 808 struct uhidpp_notification *ntf = NULL; 809 int i; 810 811 MUTEX_ASSERT_LOCKED(&sc->sc_mtx); 812 813 for (i = 0; i < UHIDPP_NNOTIFICATIONS; i++) { 814 struct uhidpp_notification *tmp = &sc->sc_notifications[i]; 815 816 if (tmp->n_id > 0 && (ntf == NULL || tmp->n_id < ntf->n_id)) 817 ntf = tmp; 818 } 819 if (ntf == NULL) 820 return 1; 821 822 memcpy(rep, &ntf->n_rep, sizeof(*rep)); 823 ntf->n_id = 0; 824 return 0; 825 } 826 827 828 /* 829 * Returns non-zero if the given report is a notification. Otherwise, it must be 830 * a response. 831 */ 832 int 833 uhidpp_is_notification(struct uhidpp_softc *sc, struct uhidpp_report *rep) 834 { 835 /* Not waiting for a response. */ 836 if (sc->sc_req == NULL) 837 return 1; 838 839 /* Everything except the parameters must be repeated in a response. */ 840 if (sc->sc_req->device_id == rep->device_id && 841 sc->sc_req->rap.sub_id == rep->rap.sub_id && 842 sc->sc_req->rap.reg_address == rep->rap.reg_address) 843 return 0; 844 845 /* An error must always be a response. */ 846 if ((rep->rap.sub_id == HIDPP_ERROR || 847 rep->fap.feature_idx == HIDPP20_ERROR) && 848 rep->fap.funcidx_swid == sc->sc_req->fap.feature_idx && 849 rep->fap.params[0] == sc->sc_req->fap.funcidx_swid) 850 return 0; 851 852 return 1; 853 } 854 855 static int 856 uhidpp_has_sensors(struct uhidpp_softc *sc) 857 { 858 return sc->sc_sensdev.xname[0] != '\0'; 859 } 860 861 int 862 hidpp_get_protocol_version(struct uhidpp_softc *sc, uint8_t device_id, 863 uint8_t *major, uint8_t *minor) 864 { 865 struct uhidpp_report resp; 866 uint8_t params[3] = { 0, 0, HIDPP_FEAT_ROOT_PING_DATA }; 867 int error; 868 869 error = hidpp_send_fap_report(sc, 870 HIDPP_REPORT_ID_SHORT, 871 device_id, 872 HIDPP_FEAT_ROOT_IDX, 873 HIDPP_FEAT_ROOT_PING_FUNC, 874 params, sizeof(params), &resp); 875 if (error == HIDPP_ERROR_INVALID_SUBID) { 876 *major = 1; 877 *minor = 0; 878 return 0; 879 } 880 if (error) 881 return error; 882 if (resp.rap.params[2] != HIDPP_FEAT_ROOT_PING_DATA) 883 return -EPROTO; 884 885 *major = resp.fap.params[0]; 886 *minor = resp.fap.params[1]; 887 return 0; 888 } 889 890 int 891 hidpp10_get_name(struct uhidpp_softc *sc, uint8_t device_id, 892 char *buf, size_t bufsiz) 893 { 894 struct uhidpp_report resp; 895 int error; 896 uint8_t params[1] = { 0x40 + (device_id - 1) }; 897 uint8_t len; 898 899 error = hidpp_send_rap_report(sc, 900 HIDPP_REPORT_ID_SHORT, 901 HIDPP_DEVICE_ID_RECEIVER, 902 HIDPP_GET_LONG_REGISTER, 903 HIDPP_REG_PAIRING_INFORMATION, 904 params, sizeof(params), &resp); 905 if (error) 906 return error; 907 908 len = resp.rap.params[1]; 909 if (len + 2 > sizeof(resp.rap.params)) 910 return -ENAMETOOLONG; 911 if (len > bufsiz - 1) 912 len = bufsiz - 1; 913 memcpy(buf, &resp.rap.params[2], len); 914 buf[len] = '\0'; 915 return 0; 916 } 917 918 int 919 hidpp10_get_serial(struct uhidpp_softc *sc, uint8_t device_id, 920 uint8_t *buf, size_t bufsiz) 921 { 922 struct uhidpp_report resp; 923 int error; 924 uint8_t params[1] = { 0x30 + (device_id - 1) }; 925 uint8_t len; 926 927 error = hidpp_send_rap_report(sc, 928 HIDPP_REPORT_ID_SHORT, 929 HIDPP_DEVICE_ID_RECEIVER, 930 HIDPP_GET_LONG_REGISTER, 931 HIDPP_REG_PAIRING_INFORMATION, 932 params, sizeof(params), &resp); 933 if (error) 934 return error; 935 936 len = 4; 937 if (bufsiz < len) 938 len = bufsiz; 939 memcpy(buf, &resp.rap.params[1], len); 940 return 0; 941 } 942 943 int 944 hidpp10_get_type(struct uhidpp_softc *sc, uint8_t device_id, const char **type) 945 { 946 struct uhidpp_report resp; 947 int error; 948 uint8_t params[1] = { 0x20 + (device_id - 1) }; 949 950 error = hidpp_send_rap_report(sc, 951 HIDPP_REPORT_ID_SHORT, 952 HIDPP_DEVICE_ID_RECEIVER, 953 HIDPP_GET_LONG_REGISTER, 954 HIDPP_REG_PAIRING_INFORMATION, 955 params, sizeof(params), &resp); 956 if (error) 957 return error; 958 959 switch (resp.rap.params[7]) { 960 case 0x00: 961 *type = "unknown"; 962 return 0; 963 case 0x01: 964 *type = "keyboard"; 965 return 0; 966 case 0x02: 967 *type = "mouse"; 968 return 0; 969 case 0x03: 970 *type = "numpad"; 971 return 0; 972 case 0x04: 973 *type = "presenter"; 974 return 0; 975 case 0x08: 976 *type = "trackball"; 977 return 0; 978 case 0x09: 979 *type = "touchpad"; 980 return 0; 981 } 982 return -ENOENT; 983 } 984 985 int 986 hidpp10_enable_notifications(struct uhidpp_softc *sc, uint8_t device_id) 987 { 988 struct uhidpp_report resp; 989 uint8_t params[3]; 990 991 /* Device reporting flags. */ 992 params[0] = HIDPP_NOTIF_DEVICE_BATTERY_STATUS; 993 /* Receiver reporting flags. */ 994 params[1] = HIDPP_NOTIF_RECEIVER_WIRELESS | 995 HIDPP_NOTIF_RECEIVER_SOFTWARE_PRESENT; 996 /* Device reporting flags (continued). */ 997 params[2] = 0; 998 999 return hidpp_send_rap_report(sc, 1000 HIDPP_REPORT_ID_SHORT, 1001 device_id, 1002 HIDPP_SET_REGISTER, 1003 HIDPP_REG_ENABLE_REPORTS, 1004 params, sizeof(params), &resp); 1005 } 1006 1007 int 1008 hidpp20_root_get_feature(struct uhidpp_softc *sc, uint8_t device_id, 1009 uint16_t feature, uint8_t *feature_idx, uint8_t *feature_type) 1010 { 1011 struct uhidpp_report resp; 1012 uint8_t params[2] = { feature >> 8, feature & 0xff }; 1013 int error; 1014 1015 error = hidpp_send_fap_report(sc, 1016 HIDPP_REPORT_ID_LONG, 1017 device_id, 1018 HIDPP20_FEAT_ROOT_ID, 1019 HIDPP20_FEAT_ROOT_GET_FEATURE_FUNC, 1020 params, sizeof(params), &resp); 1021 if (error) 1022 return error; 1023 1024 if (resp.fap.params[0] == 0) 1025 return -ENOENT; 1026 1027 *feature_idx = resp.fap.params[0]; 1028 *feature_type = resp.fap.params[1]; 1029 return 0; 1030 } 1031 1032 int 1033 hidpp20_feature_get_count(struct uhidpp_softc *sc, uint8_t device_id, 1034 uint8_t feature_idx, uint8_t *count) 1035 { 1036 struct uhidpp_report resp; 1037 int error; 1038 1039 error = hidpp_send_fap_report(sc, 1040 HIDPP_REPORT_ID_LONG, 1041 device_id, 1042 feature_idx, 1043 HIDPP20_FEAT_FEATURE_COUNT_FUNC, 1044 NULL, 0, &resp); 1045 if (error) 1046 return error; 1047 1048 *count = resp.fap.params[0]; 1049 return 0; 1050 } 1051 1052 int 1053 hidpp20_feature_get_id(struct uhidpp_softc *sc, uint8_t device_id, 1054 uint8_t feature_idx, uint8_t idx, uint16_t *id, uint8_t *type) 1055 { 1056 struct uhidpp_report resp; 1057 uint8_t params[1] = { idx }; 1058 int error; 1059 1060 error = hidpp_send_fap_report(sc, 1061 HIDPP_REPORT_ID_LONG, 1062 device_id, 1063 feature_idx, 1064 HIDPP20_FEAT_FEATURE_ID_FUNC, 1065 params, sizeof(params), &resp); 1066 if (error) 1067 return error; 1068 1069 *id = bemtoh16(resp.fap.params); 1070 *type = resp.fap.params[2]; 1071 return 0; 1072 } 1073 1074 int 1075 hidpp20_battery_get_level_status(struct uhidpp_softc *sc, uint8_t device_id, 1076 uint8_t feature_idx, uint8_t *level, uint8_t *next_level, uint8_t *status) 1077 { 1078 struct uhidpp_report resp; 1079 int error; 1080 1081 error = hidpp_send_fap_report(sc, 1082 HIDPP_REPORT_ID_LONG, 1083 device_id, 1084 feature_idx, 1085 HIDPP20_FEAT_BATTERY_LEVEL_FUNC, 1086 NULL, 0, &resp); 1087 if (error) 1088 return error; 1089 1090 *level = resp.fap.params[0]; 1091 *next_level = resp.fap.params[1]; 1092 *status = resp.fap.params[2]; 1093 1094 /* 1095 * While charging, the reported level cannot be trusted. However, fake 1096 * the battery state once the charging is done. 1097 */ 1098 switch (hidpp20_battery_status_is_charging(*status)) { 1099 case HIDPP20_BATTERY_STATUS_CHARGING_DONE: 1100 *level = 100; 1101 *status = 0; 1102 break; 1103 } 1104 1105 return 0; 1106 } 1107 1108 int 1109 hidpp20_battery_get_capability(struct uhidpp_softc *sc, uint8_t device_id, 1110 uint8_t feature_idx, uint8_t *nlevels, uint8_t *rechargeable) 1111 { 1112 struct uhidpp_report resp; 1113 int error; 1114 1115 error = hidpp_send_fap_report(sc, 1116 HIDPP_REPORT_ID_LONG, 1117 device_id, 1118 feature_idx, 1119 HIDPP20_FEAT_BATTERY_CAPABILITY_FUNC, 1120 NULL, 0, &resp); 1121 if (error) 1122 return error; 1123 *nlevels = resp.fap.params[0]; 1124 *rechargeable = resp.fap.params[1] & 1125 HIDPP20_BATTERY_CAPABILITY_RECHARGEABLE; 1126 return 0; 1127 } 1128 1129 int 1130 hidpp20_battery_status_is_charging(uint8_t status) 1131 { 1132 switch (status) { 1133 case 1: /* recharging */ 1134 case 2: /* charge in final stage */ 1135 case 4: /* recharging below optimal speed */ 1136 return status; 1137 1138 case 3: /* charge complete */ 1139 return status; 1140 1141 case 0: /* discharging */ 1142 case 5: /* invalid battery type */ 1143 case 6: /* thermal error */ 1144 case 7: /* other charging error */ 1145 default: 1146 return 0; 1147 } 1148 } 1149 1150 int 1151 hidpp_send_validate(uint8_t report_id, int nparams) 1152 { 1153 if (report_id == HIDPP_REPORT_ID_SHORT) { 1154 if (nparams > HIDPP_REPORT_SHORT_PARAMS_MAX) 1155 return -EMSGSIZE; 1156 } else if (report_id == HIDPP_REPORT_ID_LONG) { 1157 if (nparams > HIDPP_REPORT_LONG_PARAMS_MAX) 1158 return -EMSGSIZE; 1159 } else { 1160 return -EINVAL; 1161 } 1162 return 0; 1163 } 1164 1165 int 1166 hidpp_send_fap_report(struct uhidpp_softc *sc, uint8_t report_id, 1167 uint8_t device_id, uint8_t feature_idx, uint8_t funcidx_swid, 1168 uint8_t *params, int nparams, struct uhidpp_report *resp) 1169 { 1170 struct uhidpp_report req; 1171 int error; 1172 1173 error = hidpp_send_validate(report_id, nparams); 1174 if (error) 1175 return error; 1176 1177 memset(&req, 0, sizeof(req)); 1178 req.device_id = device_id; 1179 req.fap.feature_idx = feature_idx; 1180 req.fap.funcidx_swid = 1181 (funcidx_swid << HIDPP_SOFTWARE_ID_LEN) | HIDPP_SOFTWARE_ID; 1182 memcpy(req.fap.params, params, nparams); 1183 return hidpp_send_report(sc, report_id, &req, resp); 1184 } 1185 1186 int 1187 hidpp_send_rap_report(struct uhidpp_softc *sc, uint8_t report_id, 1188 uint8_t device_id, uint8_t sub_id, uint8_t reg_address, 1189 uint8_t *params, int nparams, struct uhidpp_report *resp) 1190 { 1191 struct uhidpp_report req; 1192 int error; 1193 1194 error = hidpp_send_validate(report_id, nparams); 1195 if (error) 1196 return error; 1197 1198 memset(&req, 0, sizeof(req)); 1199 req.device_id = device_id; 1200 req.rap.sub_id = sub_id; 1201 req.rap.reg_address = reg_address; 1202 memcpy(req.rap.params, params, nparams); 1203 return hidpp_send_report(sc, report_id, &req, resp); 1204 } 1205 1206 int 1207 hidpp_send_report(struct uhidpp_softc *sc, uint8_t report_id, 1208 struct uhidpp_report *req, struct uhidpp_report *resp) 1209 { 1210 int error, len, n; 1211 1212 MUTEX_ASSERT_LOCKED(&sc->sc_mtx); 1213 1214 if (report_id == HIDPP_REPORT_ID_SHORT) 1215 len = HIDPP_REPORT_SHORT_LENGTH; 1216 else if (report_id == HIDPP_REPORT_ID_LONG) 1217 len = HIDPP_REPORT_LONG_LENGTH; 1218 else 1219 return -EINVAL; 1220 1221 DREPORT(__func__, report_id, (const unsigned char *)req, len); 1222 1223 /* Wait until any ongoing command has completed. */ 1224 while (sc->sc_resp_state != UHIDPP_RESP_NONE) 1225 uhidpp_sleep(sc, INFSLP); 1226 sc->sc_req = req; 1227 sc->sc_resp = resp; 1228 sc->sc_resp_state = UHIDPP_RESP_WAIT; 1229 /* 1230 * The mutex must be temporarily released while calling 1231 * uhidev_set_report() as it might end up sleeping. 1232 */ 1233 mtx_leave(&sc->sc_mtx); 1234 1235 n = uhidev_set_report(sc->sc_hdev.sc_parent, UHID_OUTPUT_REPORT, 1236 report_id, req, len); 1237 1238 mtx_enter(&sc->sc_mtx); 1239 if (len != n) { 1240 error = -EBUSY; 1241 goto out; 1242 } 1243 /* 1244 * The interrupt could already have been received while the mutex was 1245 * released. Otherwise, wait for it. 1246 */ 1247 if (sc->sc_resp_state == UHIDPP_RESP_WAIT) { 1248 /* Timeout taken from the hid-logitech-hidpp Linux driver. */ 1249 error = uhidpp_sleep(sc, SEC_TO_NSEC(5)); 1250 if (error) { 1251 error = -error; 1252 goto out; 1253 } 1254 } 1255 1256 if (sc->sc_resp_state == UHIDPP_RESP_ERROR) 1257 error = -EIO; 1258 else if (sc->sc_resp_state == HIDPP_REPORT_ID_SHORT && 1259 resp->rap.sub_id == HIDPP_ERROR) 1260 error = resp->rap.params[1]; 1261 else if (sc->sc_resp_state == HIDPP_REPORT_ID_LONG && 1262 resp->fap.feature_idx == HIDPP20_ERROR) 1263 error = resp->fap.params[1]; 1264 1265 out: 1266 sc->sc_req = NULL; 1267 sc->sc_resp = NULL; 1268 sc->sc_resp_state = UHIDPP_RESP_NONE; 1269 wakeup(sc); 1270 return error; 1271 } 1272 1273 #ifdef UHIDPP_DEBUG 1274 1275 void 1276 uhidd_dump_report(const char *prefix, uint8_t repid, const unsigned char *buf, 1277 u_int buflen) 1278 { 1279 u_int i; 1280 1281 printf("%s: %02x ", prefix, repid); 1282 for (i = 0; i < buflen; i++) { 1283 printf("%02x%s", buf[i], 1284 i == 2 ? " [" : (i + 1 < buflen ? " " : "")); 1285 } 1286 printf("]\n"); 1287 } 1288 1289 #endif 1290