Skip to content

btielen/hid_tools

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

20 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

HID-Tools

This crate provides tools for working with the Human Interface Devices (HID) protocol. It can parse, build and display Report Descriptors.

Getting started

Following example parses a raw HID Report Descriptor

use hid_tools::parse;

fn main() {
    let bytes = [
        0x05, 0x01, 0x09, 0x06, 0xa1, 0x01, 0x85, 0x01, 0x05, 0x07, 
        0x19, 0xe0, 0x29, 0xe7, 0x15, 0x00, 0x25, 0x01, 0x75, 0x01, 
        0x95, 0x08, 0x81, 0x02, 0x19, 0x01, 0x29, 0x97, 0x15, 0x00, 
        0x25, 0x01, 0x75, 0x01, 0x95, 0x98, 0x81, 0x02, 0xc0, 
    ];

    let parsed = parse::report_descriptor(&bytes).unwrap();
    println!("{}", parsed);
}

Example Output

Following is an example output for a 2-factor authentication usb-stick.

[06, d0, f1]        Usage Page (FIDO Alliance) 
[09, 01]            Usage (U2F Authenticator Device)
[a1, 01]            Collection (Application) 
[09, 20]                Usage (Input Report Data)
[15, 00]                Logical Minimum (0) 
[26, ff, 00]            Logical Maximum (255) 
[75, 08]                Report Size (8) 
[95, 40]                Report Count (64) 
[81, 02]                Input (Data, Var, Abs) 
[09, 21]                Usage (Output Report Data)
[15, 00]                Logical Minimum (0) 
[26, ff, 00]            Logical Maximum (255) 
[75, 08]                Report Size (8) 
[95, 40]                Report Count (64) 
[91, 02]                Output (Data, Var, Abs) 
[c0]                End Collection (0) 

Report Descriptor

The HID Report Descriptor is a hard coded array of bytes that describe the device's data packets. This package provides a builder to create a Report Descriptor.

use hid_tools::report_builder::ReportDescriptorBuilder;
use hid_tools::hid::Collection;
use hid_tools::usage_table::{UsagePage};
use hid_tools::usage_table::generic_desktop::GenericDesktopControlsUsage;

fn main() {
    let raw_report = ReportDescriptorBuilder::new()
        .usage_page(UsagePage::GenericDesktopControls)
        .usage(GenericDesktopControlsUsage::Mouse)
        .item(Collection::Application)
        // add more items here (see also examples)
        .end_collection()
        .build()
        .bytes();

    println!("{:02x?}", raw_report)
}

Report

With the parsed or built Report Descriptor we know which data Reports to expect. With this we can parse a Report.

use hid_tools::parse::report_descriptor;
use hid_tools::report::{expected_input_reports, parse_raw_input_report};

fn main() {
    let keyboard_report_descriptor_bytes: Vec<u8> = vec![0x05, 0x01, 0x09, 0x06, 0xa1, 0x01, 0x05, 0x08, 0x19, 0x01,0x29, 0x03, 0x15, 0x00, 0x25,
                                                         0x01, 0x75, 0x01, 0x95, 0x03,0x91, 0x02, 0x95, 0x05, 0x91, 0x01, 0x05, 0x07, 0x19, 0xe0,0x29,
                                                         0xe7, 0x95, 0x08, 0x81, 0x02, 0x75, 0x08, 0x95, 0x01,0x81, 0x01, 0x19, 0x00, 0x29, 0x91,
                                                         0x26, 0xff, 0x00, 0x95, 0x06, 0x81, 0x00, 0xc0];

    let event_report: Vec<u8> = vec![0x02, 0, 0x04, 0x05, 0, 0, 0, 0]; // Left shift, a and b pressed on keyboard

    let report_descriptor = report_descriptor(&keyboard_report_descriptor_bytes).unwrap();
    let expected_reports = expected_input_reports(&report_descriptor).unwrap();
    let parsed_report = parse_raw_input_report(&event_report, &expected_reports).unwrap();

    println!("Event: {:?} \n\n{}", event_report, parsed_report);
}

will print

Event: [2, 0, 4, 5, 0, 0, 0, 0] 

Keyboard - Keyboard Left Control(0)
Keyboard - Keyboard Left Shift(1)
Keyboard - Keyboard Left Alt(0)
Keyboard - Keyboard Left GUI(0)
Keyboard - Keyboard Right Control(0)
Keyboard - Keyboard Right Shift(0)
Keyboard - Keyboard Right Alt(0)
Keyboard - Keyboard Right GUI(0)
Constant(0)
Keyboard - Keyboard a and A
Keyboard - Keyboard b and B

See also the parse_raw_report_keyboard example.

Todo

  • Logical minimum/maximum
  • Convert more Usage tables (help wanted)

Resources

About

Parse a USB HID Report Descriptor

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages