OLD | NEW |
(Empty) | |
| 1 # Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. |
| 4 |
| 5 |
| 6 """Utility functions for constructing HID report descriptors. |
| 7 """ |
| 8 |
| 9 import struct |
| 10 |
| 11 import hid_constants |
| 12 |
| 13 |
| 14 def ReportDescriptor(*items): |
| 15 return ''.join(items) |
| 16 |
| 17 |
| 18 def _PackItem(tag, typ, value=0, force_length=0): |
| 19 """Pack a multibyte value. |
| 20 |
| 21 See Device Class Definition for Human Interface Devices (HID) Version 1.11 |
| 22 section 5.8. |
| 23 |
| 24 Args: |
| 25 tag: Item tag. |
| 26 typ: Item type. |
| 27 value: Item value. |
| 28 force_length: Force packing to a specific width. |
| 29 |
| 30 Returns: |
| 31 Packed string. |
| 32 """ |
| 33 if value == 0 and force_length <= 0: |
| 34 return struct.pack('<B', tag << 4 | typ << 2 | 0) |
| 35 elif value <= 0xff and force_length <= 1: |
| 36 return struct.pack('<BB', tag << 4 | typ << 2 | 1, value) |
| 37 elif value <= 0xffff and force_length <= 2: |
| 38 return struct.pack('<BH', tag << 4 | typ << 2 | 2, value) |
| 39 elif value <= 0xffffffff and force_length <= 4: |
| 40 return struct.pack('<BI', tag << 4 | typ << 2 | 3, value) |
| 41 else: |
| 42 raise NotImplementedError('Long items are not implemented.') |
| 43 |
| 44 |
| 45 def _DefineItem(name, tag, typ): |
| 46 """Create a function which encodes a HID item. |
| 47 |
| 48 Args: |
| 49 name: Function name. |
| 50 tag: Item tag. |
| 51 typ: Item type. |
| 52 |
| 53 Returns: |
| 54 A function which encodes a HID item of the given type. |
| 55 """ |
| 56 assert tag >= 0 and tag <= 0xF |
| 57 assert typ >= 0 and typ <= 3 |
| 58 |
| 59 def EncodeItem(value=0, force_length=0): |
| 60 return _PackItem(tag, typ, value, force_length) |
| 61 |
| 62 EncodeItem.__name__ = name |
| 63 return EncodeItem |
| 64 |
| 65 |
| 66 def _DefineMainItem(name, tag): |
| 67 """Create a function which encodes a HID Main item. |
| 68 |
| 69 See Device Class Definition for Human Interface Devices (HID) Version 1.11 |
| 70 section 6.2.2.4. |
| 71 |
| 72 Args: |
| 73 name: Function name. |
| 74 tag: Item tag. |
| 75 |
| 76 Returns: |
| 77 A function which encodes a HID item of the given type. |
| 78 |
| 79 Raises: |
| 80 ValueError: If the tag value is out of range. |
| 81 """ |
| 82 assert tag >= 0 and tag <= 0xF |
| 83 |
| 84 def EncodeMainItem(*properties): |
| 85 value = 0 |
| 86 for bit, is_set in properties: |
| 87 if is_set: |
| 88 value |= 1 << bit |
| 89 return _PackItem(tag, hid_constants.Scope.MAIN, value, force_length=1) |
| 90 |
| 91 EncodeMainItem.__name__ = name |
| 92 return EncodeMainItem |
| 93 |
| 94 Input = _DefineMainItem('Input', 8) |
| 95 Output = _DefineMainItem('Output', 9) |
| 96 Feature = _DefineMainItem('Feature', 11) |
| 97 |
| 98 # Input, Output and Feature Item Properties |
| 99 # |
| 100 # See Device Class Definition for Human Interface Devices (HID) Version 1.11 |
| 101 # section 6.2.2.5. |
| 102 Data = (0, False) |
| 103 Constant = (0, True) |
| 104 Array = (1, False) |
| 105 Variable = (1, True) |
| 106 Absolute = (2, False) |
| 107 Relative = (2, True) |
| 108 NoWrap = (3, False) |
| 109 Wrap = (3, True) |
| 110 Linear = (4, False) |
| 111 NonLinear = (4, True) |
| 112 PreferredState = (5, False) |
| 113 NoPreferred = (5, True) |
| 114 NoNullPosition = (6, False) |
| 115 NullState = (6, True) |
| 116 NonVolatile = (7, False) |
| 117 Volatile = (7, True) |
| 118 BitField = (8, False) |
| 119 BufferedBytes = (8, True) |
| 120 |
| 121 |
| 122 def Collection(typ, *items): |
| 123 start = struct.pack('<BB', 0xA1, typ) |
| 124 end = struct.pack('<B', 0xC0) |
| 125 return start + ''.join(items) + end |
| 126 |
| 127 # Global Items |
| 128 # |
| 129 # See Device Class Definition for Human Interface Devices (HID) Version 1.11 |
| 130 # section 6.2.2.7. |
| 131 UsagePage = _DefineItem('UsagePage', 0, hid_constants.Scope.GLOBAL) |
| 132 LogicalMinimum = _DefineItem('LogicalMinimum', 1, hid_constants.Scope.GLOBAL) |
| 133 LogicalMaximum = _DefineItem('LogicalMaximum', 2, hid_constants.Scope.GLOBAL) |
| 134 PhysicalMinimum = _DefineItem('PhysicalMinimum', 3, hid_constants.Scope.GLOBAL) |
| 135 PhysicalMaximum = _DefineItem('PhysicalMaximum', 4, hid_constants.Scope.GLOBAL) |
| 136 UnitExponent = _DefineItem('UnitExponent', 5, hid_constants.Scope.GLOBAL) |
| 137 Unit = _DefineItem('Unit', 6, hid_constants.Scope.GLOBAL) |
| 138 ReportSize = _DefineItem('ReportSize', 7, hid_constants.Scope.GLOBAL) |
| 139 ReportID = _DefineItem('ReportID', 8, hid_constants.Scope.GLOBAL) |
| 140 ReportCount = _DefineItem('ReportCount', 9, hid_constants.Scope.GLOBAL) |
| 141 Push = _DefineItem('Push', 10, hid_constants.Scope.GLOBAL) |
| 142 Pop = _DefineItem('Pop', 11, hid_constants.Scope.GLOBAL) |
| 143 |
| 144 # Local Items |
| 145 # |
| 146 # See Device Class Definition for Human Interface Devices (HID) Version 1.11 |
| 147 # section 6.2.2.8. |
| 148 Usage = _DefineItem('Usage', 0, hid_constants.Scope.LOCAL) |
| 149 UsageMinimum = _DefineItem('UsageMinimum', 1, hid_constants.Scope.LOCAL) |
| 150 UsageMaximum = _DefineItem('UsageMaximum', 2, hid_constants.Scope.LOCAL) |
| 151 DesignatorIndex = _DefineItem('DesignatorIndex', 3, hid_constants.Scope.LOCAL) |
| 152 DesignatorMinimum = _DefineItem('DesignatorMinimum', 4, |
| 153 hid_constants.Scope.LOCAL) |
| 154 DesignatorMaximum = _DefineItem('DesignatorMaximum', 5, |
| 155 hid_constants.Scope.LOCAL) |
| 156 StringIndex = _DefineItem('StringIndex', 7, hid_constants.Scope.LOCAL) |
| 157 StringMinimum = _DefineItem('StringMinimum', 8, hid_constants.Scope.LOCAL) |
| 158 StringMaximum = _DefineItem('StringMaximum', 9, hid_constants.Scope.LOCAL) |
| 159 Delimiter = _DefineItem('Delimiter', 10, hid_constants.Scope.LOCAL) |
OLD | NEW |