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