|
- import unittest
-
- from contextlib import contextmanager
-
- from .. import emitter_for_format
- from ..descriptor import ComplexDescriptorEmitter
- from ...types.descriptors.hid import \
- HIDDescriptor as HIDDescriptorType
- from ...types.descriptors.hid import *
-
- ReportDescriptorItemEmitter = emitter_for_format(ReportDescriptorItem)
-
- from ...types.descriptors.hid import _hid_item_length, ItemFlags1, ItemFlags2
-
- class HIDDescriptor(ComplexDescriptorEmitter):
- DESCRIPTOR_FORMAT = HIDDescriptorType
-
- def add_report_raw(self, report_data):
- """Append raw report item or bytes to HID report
-
- Arguments:
- report_data -- bytes-like or ReportDescriptor to be appended to
- the HID report.
- """
- self._reports.append(report_data)
-
- def add_report_item(self, report_prefix, *report_data):
- """Convenience function to add formatted HID report item
-
- Arguments:
- report_prefix -- HIDPrefix enum representing report item type
- *report_data -- Additional bytes-like report item data.
- Valid lengths are 1, 2, or 4 bytes.
- """
- hid_report = ReportDescriptorItemEmitter()
- report_len = _hid_item_length.index(len(report_data))
- hid_report.bHeader = {
- "prefix": report_prefix,
- "bSize": report_len
- }
- hid_report.data = report_data
- self._reports.append(hid_report)
-
- def add_input_item(self, *args, **kwargs):
- """Convenience function to add HID input item with preformatted flags.
- See HID 1.11 section 6.2.2.5 for flag meanings.
-
- See add_inpout_item for argument names and defaults.
- """
-
- return self.add_inpout_item(HIDPrefix.INPUT, *args, **kwargs)
-
- def add_output_item(self, *args, **kwargs):
- """Convenience function to add HID output item with preformatted flags.
- See HID 1.11 section 6.2.2.5 for flag meanings.
-
- See add_inpout_item for argument names and defaults.
- """
-
- return self.add_inpout_item(HIDPrefix.OUTPUT, *args, **kwargs)
-
- def add_inpout_item(self, item,
- data_constant = False,
- array_variable = True,
- absolute_relative = False,
- wrap = False,
- linear = False,
- preferred = True,
- null = False,
- volatile = False,
- bitfield_bufferedbytes = False):
-
- if bitfield_bufferedbytes:
- itmf = ItemFlags2
- else:
- itmf = ItemFlags1
-
- item_flags = itmf.build({
- "data_constant": data_constant,
- "array_variable": array_variable,
- "absolute_relative": absolute_relative,
- "wrap": wrap,
- "nLinear": not linear,
- "nPreferred": not preferred,
- "null": null,
- "volatile": volatile,
- })
- self.add_report_item(item, item_flags)
-
- def __init__(self, parent_descriptor):
- super().__init__()
- # The HID Report Descriptor sits under a different USB Descriptor,
- # we need access to the descriptor root to create this.
- self._parent_descriptor = parent_descriptor
- self._reports = []
-
- def _pre_emit(self):
- report_descriptor = []
- for report in self._reports:
- if hasattr(report, "emit"):
- report_descriptor.append(report.emit())
- else:
- report_descriptor.append(report)
- report_descriptor = b"".join(report_descriptor)
- descriptor_len = len(report_descriptor)
- self.wDescriptorLength = descriptor_len
- self._parent_descriptor.add_descriptor(report_descriptor, descriptor_type=0x22)
-
- from ..descriptors import DeviceDescriptorCollection
- import unittest
-
- class TestHIDEmitter(unittest.TestCase):
- def test_hidemitter(self):
- collection = DeviceDescriptorCollection()
-
- hd = HIDDescriptor(collection)
-
- hd.add_report_item(HIDPrefix.USAGE_PAGE, 1)
- hd.add_report_item(HIDPrefix.USAGE, 6)
- hd.add_report_item(HIDPrefix.COLLECTION, 1)
- hd.add_report_item(HIDPrefix.USAGE_PAGE, 7)
- hd.add_report_item(HIDPrefix.USAGE_MIN, 224)
- hd.add_report_item(HIDPrefix.USAGE_MAX, 231)
- hd.add_report_item(HIDPrefix.LOGICAL_MIN, 0)
- hd.add_report_item(HIDPrefix.LOGICAL_MAX, 1)
- hd.add_report_item(HIDPrefix.REPORT_SIZE, 1)
- hd.add_report_item(HIDPrefix.REPORT_COUNT, 8)
- hd.add_input_item(data_constant=False, array_variable=True, absolute_relative=False)
-
- import codecs
- print(repr(codecs.encode(hd.emit(), 'hex')))
|