PyHIDParser
V0.0.7
A python library for interpreting a HID descriptor to provide an application with byte structures for reading and writing to without the manual labour.
Pre-Alpha
At this stage, this library is still in early development and adoption is not recommended.
Progress
- Parse HID Report descriptor from byte array
- Support for HID spec 1.11 items (See Issue #1)
- Main items (Collections, Inputs, Outputs and Features)
- Global items
- Local items (missing
delimiter
) -
Support vender defined long items(not going to happen any time soon)
- Parse HID Physical Descriptor
- Create an application API for handing HID items - Don't want the application developer to deal with states, nesting or closing collections, etc
- Access reports based on usages
- Serialize/Deserialize reports to/from the HID device
- Allow creating a HID descriptor from the API for configuring devices with
Goals
- Allow creating HID descriptors from byte arrays
- Allow creating byte arrays from a HID descriptor
- For those wanting an API approach to creating a descriptor
- Or for anyone willing to create a new GUI tool
- Provide a (de)serializer for reading and writing to devices
- Support adding vendor defined usage pages through API
- Provide meta data about reports, such as physical descriptor index, usage switches/modifiers
Examples
More examples int the examples/ folder:
- mouse.py - Creating the example Mouse descriptor from the HID 1.11 spec
- dual-shock-3.py - Parse Sony's DualShock3 HID descriptor
Note: This is a working example. But it is subject to change
import hidparser
from hidparser.UsagePages import GenericDesktop, Button
# ...
mouse_desc = array('B', [
0x05, 0x01, # USAGE_PAGE (Generic Desktop)
0x09, 0x02, # USAGE (Mouse)
0xa1, 0x01, # COLLECTION (Application)
# ...
0xc0 # END_COLLECTION
])
# This returns a Device object from a descriptor
mouse_from_desc = hidparser.parse(mouse)
# Alternatively, create a mouse device through API instead of parsing bytes
mouse_from_api = hidparser.Device(
hidparser.Collection(
usage=GenericDesktop.MOUSE,
items=hidparser.Collection(
usage=GenericDesktop.POINTER,
items=[
hidparser.Report(
report_type=hidparser.ReportType.INPUT,
usages=hidparser.UsageRange(
minimum=Button(1),
maximum=Button(3)
).get_range(),
size=1,
count=3,
logical_range=(0, 1),
flags=hidparser.ReportFlags.VARIABLE
),
hidparser.Report(
report_type=hidparser.ReportType.INPUT,
usages=[],
size=5,
count=1,
flags=hidparser.ReportFlags.CONSTANT | hidparser.ReportFlags.VARIABLE
),
hidparser.Report(
report_type=hidparser.ReportType.INPUT,
usages=[
GenericDesktop.X,
GenericDesktop.Y
],
size=8,
count=2,
logical_range=(-127, 127),
flags=hidparser.ReportFlags.VARIABLE | hidparser.ReportFlags.RELATIVE
)
]
)
)
)
# Read from the physical device
data = bytes([0x00, 0x12, 0x34])
# Deserialize the data and populate the object members
mouse_from_api.deserialize(data)
# Read the x,y members from mouse after deserializing
pointer = mouse_from_api.reports[0].inputs.mouse.pointer
print("pointer: {}, {}".format(pointer.x, pointer.y))
# Example Output:
# pointer: 18, 52