Skip to content

Latest commit

 

History

History

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 

README.md

HID report descriptor item parser

Examples

Using the default stateful parser

const QEMU_USB_TABLET: &[u8] = &[
	0x05, 0x01, 0x09, 0x02, 0xa1, 0x01, 0x09, 0x01, 0xa1, 0x00, 0x05, 0x09, 0x19, 0x01, 0x29,
	0x03, 0x15, 0x00, 0x25, 0x01, 0x95, 0x03, 0x75, 0x01, 0x81, 0x02, 0x95, 0x01, 0x75, 0x05,
	0x81, 0x01, 0x05, 0x01, 0x09, 0x30, 0x09, 0x31, 0x15, 0x00, 0x26, 0xff, 0x7f, 0x35, 0x00,
	0x46, 0xff, 0x7f, 0x75, 0x10, 0x95, 0x02, 0x81, 0x02, 0x05, 0x01, 0x09, 0x38, 0x15, 0x81,
	0x25, 0x7f, 0x35, 0x00, 0x45, 0x00, 0x75, 0x08, 0x95, 0x01, 0x81, 0x06, 0xc0, 0xc0,
];

use {
	usb_hid_item::tree::{Value, Field},
	core::{mem, ops::RangeInclusive},
};

type Usages = Vec<(u16, RangeInclusive<u16>)>;

let mut report = Vec::new();
let mut usages = Usages::new();

fn f(val: Value, fields: &mut Vec<(Usages, Field)>, usages: &mut Usages) {
	match val {
		Value::Collection(_) | Value::EndCollection => usages.clear(),
		Value::Usage { page, ids } => usages.push((page, ids)),
		Value::Field(f) => fields.push((mem::take(usages), f)),
		Value::StackFrame(s) => s.for_each(|s| f(val.unwrap(), fields, usages)),
	}
}
usb_hid_item::parse(data)
	.iter()
	.for_each(|e| f(e.unwrap(), &mut fields, &mut usages));

dbg!(fields);

Using items directly

const QEMU_USB_TABLET: &[u8] = &[
	0x05, 0x01, 0x09, 0x02, 0xa1, 0x01, 0x09, 0x01, 0xa1, 0x00, 0x05, 0x09, 0x19, 0x01, 0x29,
	0x03, 0x15, 0x00, 0x25, 0x01, 0x95, 0x03, 0x75, 0x01, 0x81, 0x02, 0x95, 0x01, 0x75, 0x05,
	0x81, 0x01, 0x05, 0x01, 0x09, 0x30, 0x09, 0x31, 0x15, 0x00, 0x26, 0xff, 0x7f, 0x35, 0x00,
	0x46, 0xff, 0x7f, 0x75, 0x10, 0x95, 0x02, 0x81, 0x02, 0x05, 0x01, 0x09, 0x38, 0x15, 0x81,
	0x25, 0x7f, 0x35, 0x00, 0x45, 0x00, 0x75, 0x08, 0x95, 0x01, 0x81, 0x06, 0xc0, 0xc0,
];

dbg!(usb_hid_item::item::parse(QEMU_USB_TABLET).collect::<Vec<_>>());

References