| Index: tools/usb_gadget/hid_descriptors.py
|
| diff --git a/tools/usb_gadget/hid_descriptors.py b/tools/usb_gadget/hid_descriptors.py
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..ad0d58071170f2f421836f6cfbc2b586d057023a
|
| --- /dev/null
|
| +++ b/tools/usb_gadget/hid_descriptors.py
|
| @@ -0,0 +1,159 @@
|
| +# Copyright 2014 The Chromium Authors. All rights reserved.
|
| +# Use of this source code is governed by a BSD-style license that can be
|
| +# found in the LICENSE file.
|
| +
|
| +
|
| +"""Utility functions for constructing HID report descriptors.
|
| +"""
|
| +
|
| +import struct
|
| +
|
| +import hid_constants
|
| +
|
| +
|
| +def ReportDescriptor(*items):
|
| + return ''.join(items)
|
| +
|
| +
|
| +def _PackItem(tag, typ, value=0, force_length=0):
|
| + """Pack a multibyte value.
|
| +
|
| + See Device Class Definition for Human Interface Devices (HID) Version 1.11
|
| + section 5.8.
|
| +
|
| + Args:
|
| + tag: Item tag.
|
| + typ: Item type.
|
| + value: Item value.
|
| + force_length: Force packing to a specific width.
|
| +
|
| + Returns:
|
| + Packed string.
|
| + """
|
| + if value == 0 and force_length <= 0:
|
| + return struct.pack('<B', tag << 4 | typ << 2 | 0)
|
| + elif value <= 0xff and force_length <= 1:
|
| + return struct.pack('<BB', tag << 4 | typ << 2 | 1, value)
|
| + elif value <= 0xffff and force_length <= 2:
|
| + return struct.pack('<BH', tag << 4 | typ << 2 | 2, value)
|
| + elif value <= 0xffffffff and force_length <= 4:
|
| + return struct.pack('<BI', tag << 4 | typ << 2 | 3, value)
|
| + else:
|
| + raise NotImplementedError('Long items are not implemented.')
|
| +
|
| +
|
| +def _DefineItem(name, tag, typ):
|
| + """Create a function which encodes a HID item.
|
| +
|
| + Args:
|
| + name: Function name.
|
| + tag: Item tag.
|
| + typ: Item type.
|
| +
|
| + Returns:
|
| + A function which encodes a HID item of the given type.
|
| + """
|
| + assert tag >= 0 and tag <= 0xF
|
| + assert typ >= 0 and typ <= 3
|
| +
|
| + def EncodeItem(value=0, force_length=0):
|
| + return _PackItem(tag, typ, value, force_length)
|
| +
|
| + EncodeItem.__name__ = name
|
| + return EncodeItem
|
| +
|
| +
|
| +def _DefineMainItem(name, tag):
|
| + """Create a function which encodes a HID Main item.
|
| +
|
| + See Device Class Definition for Human Interface Devices (HID) Version 1.11
|
| + section 6.2.2.4.
|
| +
|
| + Args:
|
| + name: Function name.
|
| + tag: Item tag.
|
| +
|
| + Returns:
|
| + A function which encodes a HID item of the given type.
|
| +
|
| + Raises:
|
| + ValueError: If the tag value is out of range.
|
| + """
|
| + assert tag >= 0 and tag <= 0xF
|
| +
|
| + def EncodeMainItem(*properties):
|
| + value = 0
|
| + for bit, is_set in properties:
|
| + if is_set:
|
| + value |= 1 << bit
|
| + return _PackItem(tag, hid_constants.Scope.MAIN, value, force_length=1)
|
| +
|
| + EncodeMainItem.__name__ = name
|
| + return EncodeMainItem
|
| +
|
| +Input = _DefineMainItem('Input', 8)
|
| +Output = _DefineMainItem('Output', 9)
|
| +Feature = _DefineMainItem('Feature', 11)
|
| +
|
| +# Input, Output and Feature Item Properties
|
| +#
|
| +# See Device Class Definition for Human Interface Devices (HID) Version 1.11
|
| +# section 6.2.2.5.
|
| +Data = (0, False)
|
| +Constant = (0, True)
|
| +Array = (1, False)
|
| +Variable = (1, True)
|
| +Absolute = (2, False)
|
| +Relative = (2, True)
|
| +NoWrap = (3, False)
|
| +Wrap = (3, True)
|
| +Linear = (4, False)
|
| +NonLinear = (4, True)
|
| +PreferredState = (5, False)
|
| +NoPreferred = (5, True)
|
| +NoNullPosition = (6, False)
|
| +NullState = (6, True)
|
| +NonVolatile = (7, False)
|
| +Volatile = (7, True)
|
| +BitField = (8, False)
|
| +BufferedBytes = (8, True)
|
| +
|
| +
|
| +def Collection(typ, *items):
|
| + start = struct.pack('<BB', 0xA1, typ)
|
| + end = struct.pack('<B', 0xC0)
|
| + return start + ''.join(items) + end
|
| +
|
| +# Global Items
|
| +#
|
| +# See Device Class Definition for Human Interface Devices (HID) Version 1.11
|
| +# section 6.2.2.7.
|
| +UsagePage = _DefineItem('UsagePage', 0, hid_constants.Scope.GLOBAL)
|
| +LogicalMinimum = _DefineItem('LogicalMinimum', 1, hid_constants.Scope.GLOBAL)
|
| +LogicalMaximum = _DefineItem('LogicalMaximum', 2, hid_constants.Scope.GLOBAL)
|
| +PhysicalMinimum = _DefineItem('PhysicalMinimum', 3, hid_constants.Scope.GLOBAL)
|
| +PhysicalMaximum = _DefineItem('PhysicalMaximum', 4, hid_constants.Scope.GLOBAL)
|
| +UnitExponent = _DefineItem('UnitExponent', 5, hid_constants.Scope.GLOBAL)
|
| +Unit = _DefineItem('Unit', 6, hid_constants.Scope.GLOBAL)
|
| +ReportSize = _DefineItem('ReportSize', 7, hid_constants.Scope.GLOBAL)
|
| +ReportID = _DefineItem('ReportID', 8, hid_constants.Scope.GLOBAL)
|
| +ReportCount = _DefineItem('ReportCount', 9, hid_constants.Scope.GLOBAL)
|
| +Push = _DefineItem('Push', 10, hid_constants.Scope.GLOBAL)
|
| +Pop = _DefineItem('Pop', 11, hid_constants.Scope.GLOBAL)
|
| +
|
| +# Local Items
|
| +#
|
| +# See Device Class Definition for Human Interface Devices (HID) Version 1.11
|
| +# section 6.2.2.8.
|
| +Usage = _DefineItem('Usage', 0, hid_constants.Scope.LOCAL)
|
| +UsageMinimum = _DefineItem('UsageMinimum', 1, hid_constants.Scope.LOCAL)
|
| +UsageMaximum = _DefineItem('UsageMaximum', 2, hid_constants.Scope.LOCAL)
|
| +DesignatorIndex = _DefineItem('DesignatorIndex', 3, hid_constants.Scope.LOCAL)
|
| +DesignatorMinimum = _DefineItem('DesignatorMinimum', 4,
|
| + hid_constants.Scope.LOCAL)
|
| +DesignatorMaximum = _DefineItem('DesignatorMaximum', 5,
|
| + hid_constants.Scope.LOCAL)
|
| +StringIndex = _DefineItem('StringIndex', 7, hid_constants.Scope.LOCAL)
|
| +StringMinimum = _DefineItem('StringMinimum', 8, hid_constants.Scope.LOCAL)
|
| +StringMaximum = _DefineItem('StringMaximum', 9, hid_constants.Scope.LOCAL)
|
| +Delimiter = _DefineItem('Delimiter', 10, hid_constants.Scope.LOCAL)
|
|
|