Skip to content

Latest commit

 

History

History

usb_hid_item

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 

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