Crate hidparser

Source
Expand description

HID Report Descriptor Parser

This crate defines data types to describe a HID report descriptor, and implements a parser that will process a raw descriptor and return a ReportDescriptor object that describes the contents of the report descriptor.

Refer to the USB Device Class Definition for Human Interface Devices (HID) Version 1.11 https://www.usb.org/sites/default/files/hid1_11.pdf

§Example


  let BOOT_KEYBOARD_REPORT_DESCRIPTOR: &[u8] = &[
    0x05, 0x01, // USAGE_PAGE (Generic Desktop)
    0x09, 0x06, // USAGE (Keyboard)
    0xa1, 0x01, // COLLECTION (Application)
    0x75, 0x01, //    REPORT_SIZE (1)
    0x95, 0x08, //    REPORT_COUNT (8)
    0x05, 0x07, //    USAGE_PAGE (Key Codes)
    0x19, 0xE0, //    USAGE_MINIMUM (224)
    0x29, 0xE7, //    USAGE_MAXIMUM (231)
    0x15, 0x00, //    LOGICAL_MAXIMUM (0)
    0x25, 0x01, //    LOGICAL_MINIMUM (1)
    0x81, 0x02, //    INPUT (Data, Var, Abs) (Modifier Byte)
    0x95, 0x01, //    REPORT_COUNT (1)
    0x75, 0x08, //    REPORT_SIZE (8)
    0x81, 0x03, //    INPUT (Const) (Reserved Byte)
    0x95, 0x05, //    REPORT_COUNT (5)
    0x75, 0x01, //    REPORT_SIZE (1)
    0x05, 0x08, //    USAGE_PAGE (LEDs)
    0x19, 0x01, //    USAGE_MINIMUM (1)
    0x29, 0x05, //    USAGE_MAXIMUM (5)
    0x91, 0x02, //    OUTPUT (Data, Var, Abs) (LED report)
    0x95, 0x01, //    REPORT_COUNT (1)
    0x75, 0x03, //    REPORT_SIZE (3)
    0x91, 0x02, //    OUTPUT (Constant) (LED report padding)
    0x95, 0x06, //    REPORT_COUNT (6)
    0x75, 0x08, //    REPORT_SIZE (8)
    0x15, 0x00, //    LOGICAL_MINIMUM (0)
    0x26, 0xff, 00, //    LOGICAL_MAXIMUM (255)
    0x05, 0x07, //    USAGE_PAGE (Key Codes)
    0x19, 0x00, //    USAGE_MINIMUM (0)
    0x2a, 0xff, 00, //    USAGE_MAXIMUM (255)
    0x81, 0x00, //    INPUT (Data, Array)
    0xc0, // END_COLLECTION
  ];

  let descriptor = parse_report_descriptor(BOOT_KEYBOARD_REPORT_DESCRIPTOR).unwrap();
  // singleton input/output reports with no report id.
  assert_eq!(descriptor.input_reports.len(), 1);
  assert_eq!(descriptor.output_reports.len(), 1);
  assert_eq!(descriptor.input_reports[0].report_id, None);
  assert_eq!(descriptor.output_reports[0].report_id, None);

  //Input report field[4] is right control - Usage Page 7, Usage 0xE4, occupying bit 4 of the input report.
  let ReportField::Variable(ref field) = descriptor.input_reports[0].fields[4] else {panic!("Unexpected field type.")};
  let usage = Usage::from_page_and_id(Some(UsagePage::from(0x07)), Usage::from(0xe4));
  assert_eq!(field.usage, usage);
  assert_eq!(field.bits, 4..5);

  //Input report field[8] is padding, occupying bit 8 through 15 of the input report.
  let ReportField::Padding(ref field) = descriptor.input_reports[0].fields[8] else {panic!("Unexpected field type.")};
  assert_eq!(field.bits, 8..16);

  //Input report field[9] is the first keycode byte, occupying bit 16 through 23 of the input report.
  //The key code can have usages in Usage Page 7, in the range 0x00 to 0xFF
  let ReportField::Array(ref field) = descriptor.input_reports[0].fields[9] else {panic!("Unexpected field type.")};
  assert_eq!(field.bits, 16..24);
  assert_eq!(field.usage_list, Vec::from([UsageRange::from(0x00070000..=0x000700ff)]));


  //Output report field[1] is caps lock - Usage Page 8, Usage 0x01, occupying bit 1 of the output report.
  let ReportField::Variable(ref field) = descriptor.output_reports[0].fields[1] else {panic!("Unexpected field type.")};
  let usage = Usage::from_page_and_id(Some(UsagePage::from(0x08)), Usage::from(0x02));
  assert_eq!(field.usage, usage);
  assert_eq!(field.bits, 1..2);

§License

Copyright (C) Microsoft Corporation. All rights reserved.

SPDX-License-Identifier: BSD-2-Clause-Patent

Modules§

report_data_types
Report Descriptor Data Types
report_descriptor_parser
Report Descriptor Parser Core

Structs§

ArrayField
Describes an Array data field in a report descriptor.
PaddingField
Describes a Padding data field in a report descriptor (i.e. a field without usages).
Report
Describes a report.
ReportCollection
Describes a report collection.
ReportDescriptor
A collection of input/output/feature reports that are described by a given Report Descriptor.
VariableField
Describes a Variable data field in a report descriptor.

Enums§

FieldAccessError
Describes errors encountered when using field accessor methods.
ReportField
Defines the types of fields that appear in a report.

Functions§

parse_report_descriptor
Parse the raw report descriptor in the given byte slice.