svn commit: r281566 - stable/10/usr.sbin/bluetooth/bthidd

Raphael Kubo da Costa rakuco at FreeBSD.org
Wed Apr 15 22:02:54 UTC 2015


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) {


More information about the svn-src-all mailing list