Date: Wed, 15 Apr 2015 22:02:53 +0000 (UTC) From: Raphael Kubo da Costa <rakuco@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r281566 - stable/10/usr.sbin/bluetooth/bthidd Message-ID: <201504152202.t3FM2rWB019394@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: rakuco (ports committer) Date: Wed Apr 15 22:02:52 2015 New Revision: 281566 URL: https://svnweb.freebsd.org/changeset/base/281566 Log: MFC r281116. bthidd: Consider usage ranges when dealing with array inputs. So far, we were always using HID_USAGE() to determine the Usage ID of a certain HID report input item. This does not work as intended if a field is an array and the allowed usages are specified with a usage range, as HID_USAGE() will return 0. We need to use the field value as an index in the usage range list in this case instead. This makes the volume keys in a Microsoft Bluetooth Mobile Keyboard 5000 be properly recognized. The relevant part of the HID report looks like this: 0xA1, 0x01, // Collection (Application) 0x85, 0x07, // Report ID (7) 0x05, 0x0C, // Usage Page (Consumer) 0x19, 0x00, // Usage Minimum (Unassigned) 0x2A, 0xFF, 0x03, // Usage Maximum (0x03FF) 0x95, 0x01, // Report Count (1) 0x75, 0x10, // Report Size (16) 0x15, 0x00, // Logical Minimum (0) 0x27, 0xFF, 0x03, 0x00, 0x00, // Logical Maximum (1023) 0x81, 0x00, // Input (Data,Array,Abs,No Wrap,Linear,Preferred // State,No Null Position) When a key such as "volume down" is pressed, the following data is transferred through Interrupt In: 0x07 0xEA 0x00 Differential Revision: https://reviews.freebsd.org/D2229 Modified: stable/10/usr.sbin/bluetooth/bthidd/hid.c Directory Properties: stable/10/ (props changed) Modified: stable/10/usr.sbin/bluetooth/bthidd/hid.c ============================================================================== --- stable/10/usr.sbin/bluetooth/bthidd/hid.c Wed Apr 15 21:48:06 2015 (r281565) +++ stable/10/usr.sbin/bluetooth/bthidd/hid.c Wed Apr 15 22:02:52 2015 (r281566) @@ -165,9 +165,21 @@ hid_interrupt(bthid_session_p s, uint8_t continue; page = HID_PAGE(h.usage); - usage = HID_USAGE(h.usage); val = hid_get_data(data, &h); + /* + * When the input field is an array and the usage is specified + * with a range instead of an ID, we have to derive the actual + * usage by using the item value as an index in the usage range + * list. + */ + if ((h.flags & HIO_VARIABLE)) { + usage = HID_USAGE(h.usage); + } else { + const uint32_t usage_offset = val - h.logical_minimum; + usage = HID_USAGE(h.usage_minimum + usage_offset); + } + switch (page) { case HUP_GENERIC_DESKTOP: switch (usage) {
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201504152202.t3FM2rWB019394>