# 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('= 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('