hidreport/
lib.rs

1// SPDX-License-Identifier: MIT
2//
3//! This crate provides parsing of HID Report Descriptors, including the [hid] module to inspect
4//! a report descriptor in more detail. Check out the `hut` crate for known HID Usages to make
5//! sense of the various HID fields.
6//!
7//! Entry point is usually [`ReportDescriptor::try_from(bytes)`](ReportDescriptor::try_from):
8//!
9//! ```
10//! # use hidreport::*;
11//! # let bytes: &[u8] = &[0x05, 0x01, 0x09, 0x02, 0xa1, 0x01, 0x05, 0x01, 0x09, 0x02, 0xa1, 0x02, 0x85, 0x1a, 0x09, 0x01, 0xa1, 0x00, 0x05, 0x09, 0x19, 0x01, 0x29, 0x05, 0x95, 0x05, 0x75, 0x01, 0x15, 0x00, 0x25, 0x01, 0x81, 0x02, 0x75, 0x03, 0x95, 0x01, 0x81, 0x01, 0x05, 0x01, 0x09, 0x30, 0x09, 0x31, 0x95, 0x02, 0x75, 0x10, 0x16, 0x01, 0x80, 0x26, 0xff, 0x7f, 0x81, 0x06, 0xa1, 0x02, 0x85, 0x12, 0x09, 0x48, 0x95, 0x01, 0x75, 0x02, 0x15, 0x00, 0x25, 0x01, 0x35, 0x01, 0x45, 0x0c, 0xb1, 0x02, 0x85, 0x1a, 0x09, 0x38, 0x35, 0x00, 0x45, 0x00, 0x95, 0x01, 0x75, 0x10, 0x16, 0x01, 0x80, 0x26, 0xff, 0x7f, 0x81, 0x06, 0xc0, 0xa1, 0x02, 0x85, 0x12, 0x09, 0x48, 0x75, 0x02, 0x15, 0x00, 0x25, 0x01, 0x35, 0x01, 0x45, 0x0c, 0xb1, 0x02, 0x35, 0x00, 0x45, 0x00, 0x75, 0x04, 0xb1, 0x01, 0x85, 0x1a, 0x05, 0x0c, 0x95, 0x01, 0x75, 0x10, 0x16, 0x01, 0x80, 0x26, 0xff, 0x7f, 0x0a, 0x38, 0x02, 0x81, 0x06, 0xc0, 0xc0, 0xc0, 0xc0, 0x05, 0x0c, 0x09, 0x01, 0xa1, 0x01, 0x05, 0x01, 0x09, 0x02, 0xa1, 0x02, 0x85, 0x1f, 0x05, 0x0c, 0x0a, 0x38, 0x02, 0x95, 0x01, 0x75, 0x10, 0x16, 0x01, 0x80, 0x26, 0xff, 0x7f, 0x81, 0x06, 0x85, 0x17, 0x06, 0x00, 0xff, 0x0a, 0x06, 0xff, 0x0a, 0x0f, 0xff, 0x15, 0x00, 0x25, 0x01, 0x35, 0x01, 0x45, 0x0c, 0x95, 0x02, 0x75, 0x02, 0xb1, 0x02, 0x0a, 0x04, 0xff, 0x35, 0x00, 0x45, 0x00, 0x95, 0x01, 0x75, 0x01, 0xb1, 0x02, 0x75, 0x03, 0xb1, 0x01, 0xc0, 0xc0];
12//! # fn read_from_device() -> Vec<u8> {
13//! #     vec![0x1a, 0x00, 0xff, 0xff, 0xfe, 0xff, 00, 00, 00, 0x00]
14//! # }
15//! #
16//! let rdesc: ReportDescriptor = ReportDescriptor::try_from(bytes).unwrap();
17//! for r in rdesc.input_reports() {
18//!     println!("Input Report with report ID: {:?}", r.report_id());
19//! }
20//!
21//! let input_report_bytes = read_from_device();
22//! let report = rdesc.find_input_report(&input_report_bytes).unwrap();
23//! println!("This is an input report for report ID: {:?}", report.report_id());
24//! let field = report.fields().first().unwrap();
25//! match field {
26//!     Field::Variable(var) => {
27//!         let val: u32 = var.extract(&input_report_bytes).unwrap().into();
28//!         println!("Field {:?} is of value {}", field, val);
29//!     }
30//!     Field::Array(arr) => {
31//!         let vals: Vec<u32> = arr.extract(&input_report_bytes).unwrap().iter().map(u32::from).collect();
32//!         println!("Field {:?} has values {:?}", field, vals);
33//!     }
34//!     Field::Constant(_) => {
35//!         println!("Field {:?} is <padding data>", field);
36//!     }
37//! }
38//! ```
39//!
40//! In this document and unless stated otherwise, a reference to "Section a.b.c" refers to the
41//! [HID Device Class Definition for HID 1.11](https://www.usb.org/document-library/device-class-definition-hid-111).
42
43use std::hash::{Hash, Hasher};
44use std::ops::Range;
45use thiserror::Error;
46
47#[cfg(feature = "hut")]
48use hut::{AsUsage, AsUsagePage};
49
50pub mod hid;
51pub mod types;
52
53pub use hid::CollectionItem as CollectionType;
54use hid::*;
55pub use types::*;
56
57macro_rules! ensure {
58    ($cond:expr, $msg:literal) => {
59        if (!$cond) {
60            return Err(ParserError::InvalidData {
61                offset: 0,
62                message: $msg.into(),
63            });
64        }
65    };
66    ($cond:expr, $err:expr) => {
67        if (!$cond) {
68            return Err($err);
69        }
70    };
71}
72pub(crate) use ensure;
73
74/// Implements `From<Foo> for Bar` to call `From<&Foo> for Bar`
75macro_rules! impl_from_without_ref {
76    ($tipo:ty, $to_expr:ident, $to:ty) => {
77        impl From<$tipo> for $to {
78            fn from(f: $tipo) -> $to {
79                $to_expr::from(&f)
80            }
81        }
82    };
83}
84
85/// Extract the bit range from the given byte array, converting the
86/// result into a [u32].
87///
88/// The number of bits in the range must be less or equal to 32.
89fn extract_bits(bytes: &[u8], bits: &Range<usize>) -> u32 {
90    let nbits = bits.len();
91    assert_ne!(nbits, 0);
92    assert!(nbits <= 32);
93    let start_index = bits.start / 8;
94    let end_index = (bits.end - 1) / 8;
95    let bytes = &bytes[start_index..=end_index];
96    let value: u64 = Range {
97        start: 0u64,
98        end: bytes.len() as u64,
99    }
100    //.inspect(|idx| println!("Accessing index {idx}: {:x?}", bytes[*idx as usize]))
101    .fold(0u64, |acc: u64, idx| {
102        acc | (bytes[idx as usize] as u64) << (8 * idx)
103    });
104
105    let base_shift = bits.start % 8;
106    let mask_shift = 32 - nbits;
107    let mask = (!0) >> mask_shift;
108    let value = (value >> base_shift) as u32;
109
110    value & mask
111}
112
113/// Calculates the two's complement for a value with
114/// a given number of of bits.
115trait TwosComplement<To> {
116    /// Returns the two's complement for a value
117    /// with a given number of bits.
118    fn twos_comp(self, nbits: usize) -> To;
119}
120
121impl TwosComplement<i8> for u8 {
122    fn twos_comp(self, nbits: usize) -> i8 {
123        assert!(nbits > 0);
124        if nbits >= 8 || self & (1 << (nbits - 1)) == 0 {
125            self as i8
126        } else {
127            let s = self as i16;
128            let min = 1 << nbits;
129            (-min + s) as i8
130        }
131    }
132}
133
134impl TwosComplement<i16> for u16 {
135    fn twos_comp(self, nbits: usize) -> i16 {
136        assert!(nbits > 0);
137        if nbits >= 16 || self & (1 << (nbits - 1)) == 0 {
138            self as i16
139        } else {
140            let s = self as i32;
141            let min = 1 << nbits;
142            (-min + s) as i16
143        }
144    }
145}
146
147impl TwosComplement<i32> for u32 {
148    fn twos_comp(self, nbits: usize) -> i32 {
149        assert!(nbits > 0);
150        if nbits >= 32 || self & (1 << (nbits - 1)) == 0 {
151            self as i32
152        } else {
153            let s = self as i64;
154            let min = 1 << nbits;
155            (-min + s) as i32
156        }
157    }
158}
159
160/// A [ReportDescriptor] is the static set of [Items](hid::Item)
161/// that define how data from the device should be interpreted.
162///
163/// A device may have up to three different types of [Reports](Report)
164/// (Input, Output, and Feature), all of which are defined in the
165/// single report descriptor.
166///
167/// ```
168/// # use hidreport::*;
169/// # let bytes: &[u8] = &[0x05, 0x01, 0x09, 0x02, 0xa1, 0x01, 0x05, 0x01, 0x09, 0x02, 0xa1, 0x02, 0x85, 0x1a, 0x09, 0x01, 0xa1, 0x00, 0x05, 0x09, 0x19, 0x01, 0x29, 0x05, 0x95, 0x05, 0x75, 0x01, 0x15, 0x00, 0x25, 0x01, 0x81, 0x02, 0x75, 0x03, 0x95, 0x01, 0x81, 0x01, 0x05, 0x01, 0x09, 0x30, 0x09, 0x31, 0x95, 0x02, 0x75, 0x10, 0x16, 0x01, 0x80, 0x26, 0xff, 0x7f, 0x81, 0x06, 0xa1, 0x02, 0x85, 0x12, 0x09, 0x48, 0x95, 0x01, 0x75, 0x02, 0x15, 0x00, 0x25, 0x01, 0x35, 0x01, 0x45, 0x0c, 0xb1, 0x02, 0x85, 0x1a, 0x09, 0x38, 0x35, 0x00, 0x45, 0x00, 0x95, 0x01, 0x75, 0x10, 0x16, 0x01, 0x80, 0x26, 0xff, 0x7f, 0x81, 0x06, 0xc0, 0xa1, 0x02, 0x85, 0x12, 0x09, 0x48, 0x75, 0x02, 0x15, 0x00, 0x25, 0x01, 0x35, 0x01, 0x45, 0x0c, 0xb1, 0x02, 0x35, 0x00, 0x45, 0x00, 0x75, 0x04, 0xb1, 0x01, 0x85, 0x1a, 0x05, 0x0c, 0x95, 0x01, 0x75, 0x10, 0x16, 0x01, 0x80, 0x26, 0xff, 0x7f, 0x0a, 0x38, 0x02, 0x81, 0x06, 0xc0, 0xc0, 0xc0, 0xc0, 0x05, 0x0c, 0x09, 0x01, 0xa1, 0x01, 0x05, 0x01, 0x09, 0x02, 0xa1, 0x02, 0x85, 0x1f, 0x05, 0x0c, 0x0a, 0x38, 0x02, 0x95, 0x01, 0x75, 0x10, 0x16, 0x01, 0x80, 0x26, 0xff, 0x7f, 0x81, 0x06, 0x85, 0x17, 0x06, 0x00, 0xff, 0x0a, 0x06, 0xff, 0x0a, 0x0f, 0xff, 0x15, 0x00, 0x25, 0x01, 0x35, 0x01, 0x45, 0x0c, 0x95, 0x02, 0x75, 0x02, 0xb1, 0x02, 0x0a, 0x04, 0xff, 0x35, 0x00, 0x45, 0x00, 0x95, 0x01, 0x75, 0x01, 0xb1, 0x02, 0x75, 0x03, 0xb1, 0x01, 0xc0, 0xc0];
170/// # fn read_from_device() -> Vec<u8> {
171/// #     vec![0x1a, 0x00, 0xff, 0xff, 0xfe, 0xff, 00, 00, 00, 0x00]
172/// # }
173/// #
174/// let rdesc: ReportDescriptor = ReportDescriptor::try_from(bytes).unwrap();
175/// for r in rdesc.input_reports() {
176///     println!("Input Report with report ID: {:?}", r.report_id());
177/// }
178/// let input_report_bytes = read_from_device();
179/// let report = rdesc.find_input_report(&input_report_bytes).unwrap();
180/// println!("This is an input report for report ID: {:?}", report.report_id());
181/// let field = report.fields().first().unwrap();
182/// match field {
183///     Field::Variable(var) => println!("Field {:?} is of value {}", field, u32::from(var.extract(&input_report_bytes).unwrap())),
184///     Field::Array(arr) => println!("Field {:?} has values {:?}", field, arr.extract(&input_report_bytes).unwrap().iter().map(u32::from)),
185///     Field::Constant(_) => println!("Field {:?} is <padding data>", field),
186/// }
187/// ```
188///
189#[derive(Debug, Default)]
190pub struct ReportDescriptor {
191    input_reports: Vec<RDescReport>,
192    output_reports: Vec<RDescReport>,
193    feature_reports: Vec<RDescReport>,
194}
195
196impl<'a> ReportDescriptor {
197    /// Returns the set of input reports or the empty
198    /// slice if none exist.
199    /// ```
200    /// # use hidreport::*;
201    /// # fn func(rdesc: &ReportDescriptor) {
202    /// let reports = rdesc.input_reports();
203    /// for report in reports {
204    ///     println!("Report ID: {:?}", report.report_id());
205    /// }
206    /// # }
207    /// ```
208    pub fn input_reports(&self) -> &[impl Report] {
209        &self.input_reports
210    }
211
212    /// Returns the set of output reports or the empty
213    /// slice if none exist.
214    /// ```
215    /// # use hidreport::*;
216    /// # fn func(rdesc: &ReportDescriptor) {
217    /// let reports = rdesc.output_reports();
218    /// for report in reports {
219    ///     println!("Report ID: {:?}", report.report_id());
220    /// }
221    /// # }
222    /// ```
223    pub fn output_reports(&self) -> &[impl Report] {
224        &self.output_reports
225    }
226
227    /// Returns the set of feature reports or the empty
228    /// slice if none exist.
229    /// ```
230    /// # use hidreport::*;
231    /// # fn func(rdesc: &ReportDescriptor) {
232    /// let reports = rdesc.feature_reports();
233    /// for report in reports {
234    ///     println!("Report ID: {:?}", report.report_id());
235    /// }
236    /// # }
237    /// ```
238    pub fn feature_reports(&self) -> &[impl Report] {
239        &self.feature_reports
240    }
241
242    fn find_report(&'a self, list: &'a [RDescReport], prefix: u8) -> Option<&impl Report> {
243        let first = list.first()?;
244        let rid = Some(ReportId(prefix));
245        // Do we have report IDs? If not, the first report is what we want.
246        match first.report_id() {
247            None => Some(first),
248            Some(_) => list.iter().find(|r| r.report_id() == &rid),
249        }
250    }
251
252    /// Find the input report that matches this byte sequence.
253    ///
254    /// ```
255    /// # use hidreport::*;
256    /// # fn func(bytes: &[u8], rdesc: &ReportDescriptor) {
257    /// // bytes was read from the device (or some other source)
258    /// let report = rdesc.find_input_report(bytes).unwrap();
259    /// for field in report.fields() {
260    ///     // ...
261    /// }
262    /// # }
263    /// ```
264    ///
265    /// ReportDescriptors with multiple reports require a report
266    /// to have a single byte prefix specifying the [ReportId].
267    pub fn find_input_report(&self, bytes: &[u8]) -> Option<&impl Report> {
268        self.find_report(&self.input_reports, bytes[0])
269    }
270
271    /// Find the output report that matches this byte sequence.
272    ///
273    /// ```
274    /// # use hidreport::*;
275    /// # fn func(bytes: &[u8], rdesc: &ReportDescriptor) {
276    /// // bytes was read from the device (or some other source)
277    /// let report = rdesc.find_output_report(bytes).unwrap();
278    /// for field in report.fields() {
279    ///     // ...
280    /// }
281    /// # }
282    /// ```
283    ///
284    /// ReportDescriptors with multiple reports require a report
285    /// to have a single byte prefix specifying the [ReportId].
286    pub fn find_output_report(&self, bytes: &[u8]) -> Option<&impl Report> {
287        self.find_report(&self.input_reports, bytes[0])
288    }
289
290    /// Find the feature report that matches this byte sequence.
291    ///
292    /// ```
293    /// # use hidreport::*;
294    /// # fn func(bytes: &[u8], rdesc: &ReportDescriptor) {
295    /// // bytes was read from the device (or some other source)
296    /// let report = rdesc.find_feature_report(bytes).unwrap();
297    /// for field in report.fields() {
298    ///     // ...
299    /// }
300    /// # }
301    /// ```
302    ///
303    /// ReportDescriptors with multiple reports require a report
304    /// to have a single byte prefix specifying the [ReportId].
305    pub fn find_feature_report(&self, bytes: &[u8]) -> Option<&impl Report> {
306        self.find_report(&self.input_reports, bytes[0])
307    }
308}
309
310impl TryFrom<&[u8]> for ReportDescriptor {
311    type Error = ParserError;
312
313    /// Try to parse the given byte array as a report descriptor.
314    fn try_from(bytes: &[u8]) -> Result<ReportDescriptor> {
315        parse_report_descriptor(bytes)
316    }
317}
318
319impl TryFrom<&Vec<u8>> for ReportDescriptor {
320    type Error = ParserError;
321
322    /// Try to parse the given byte array as a report descriptor.
323    fn try_from(bytes: &Vec<u8>) -> Result<ReportDescriptor> {
324        parse_report_descriptor(bytes)
325    }
326}
327
328#[derive(Copy, Clone, Debug)]
329enum Direction {
330    Input,
331    Output,
332    Feature,
333}
334
335/// A HID Input, Output or Feature Report.
336///
337/// Where a report contains the [Report::report_id] the first
338/// byte of the report is always that Report ID, followed
339/// by the data in the sequence announced in the HID [ReportDescriptor].
340///
341/// Use [`size_in_bits()`][Report::size_in_bits] or
342/// [`size_in_bytes()`](Report::size_in_bytes) to
343/// get the length of this report.
344///
345/// Note that each of Input, Output and Feature Reports
346/// have their own enumeration of Report IDs, i.e. an Input Report
347/// with a Report ID of e.g. 1 may have a different size and/or [Field]s
348/// to an Output Report with a Report ID of 1.
349///
350/// The Report ID has no meaning other than to distinguish
351/// different reports. See Section 6.2.2.7 for details.
352pub trait Report {
353    /// Returns the HID Report ID for this report, if any.
354    fn report_id(&self) -> &Option<ReportId>;
355
356    /// Returns the parsed HID Fields ID for this report. A caller should
357    /// iterate through these fields to find the ones it is interested
358    /// in and use the [Field::bits] to extract the data from future
359    /// reports.
360    fn fields(&self) -> &[Field];
361
362    /// The size in bits for this report.
363    fn size_in_bits(&self) -> usize;
364
365    /// The size in bytes for this object.
366    ///
367    /// Where [`size_in_bits()`](Report::size_in_bits) is
368    /// not a multiple of 8, the [`size_in_bytes()`](Report::size_in_bytes) rounds up
369    /// fit all bits.
370    fn size_in_bytes(&self) -> usize {
371        (self.size_in_bits() + 7) / 8
372    }
373}
374
375/// A HID Input, Output or Feature Report.
376///
377/// Where a report contains the [Report::report_id] the first
378/// byte of the report is always that Report ID, followed
379/// by the data in the sequence announced in the HID [ReportDescriptor].
380///
381/// Note that each of Input, Output and Feature Reports
382/// have their own enumeration of Report IDs, i.e. an Input Report
383/// with a Report ID of e.g. 1 may have a different size and/or [Field]s
384/// to an Output Report with a Report ID of 1.
385///
386/// The Report ID has no meaning other than to distinguish
387/// different reports. See Section 6.2.2.7 for details.
388#[derive(Debug)]
389struct RDescReport {
390    /// The report ID, if any
391    id: Option<ReportId>,
392    /// The size of this report in bits
393    size: usize,
394    /// The fields present in this report
395    fields: Vec<Field>,
396}
397
398impl Report for RDescReport {
399    fn report_id(&self) -> &Option<ReportId> {
400        &self.id
401    }
402
403    fn fields(&self) -> &[Field] {
404        &self.fields
405    }
406
407    /// The size of this HID report on the wire, in bits
408    fn size_in_bits(&self) -> usize {
409        self.size
410    }
411}
412
413/// The usage of a [Field] defines the interpretation of a
414/// data value. See the `hut` crate for a list of known Usages.
415///
416/// A Usage comprises of a 16 bit [UsagePage] and a 16 bit [UsageId].
417///
418/// ```
419/// # use hidreport::*;
420/// let up = UsagePage::from(0x01); // Generic Desktop
421/// let uid = UsageId::from(0x02); // Mouse
422/// let usage = Usage::from_page_and_id(up, uid);
423/// ```
424/// For known named usages see the `hut` crate.
425#[derive(Clone, Copy, Debug, PartialEq)]
426pub struct Usage {
427    pub usage_page: UsagePage,
428    pub usage_id: UsageId,
429}
430
431impl Usage {
432    /// Create a [Usage] from a [UsagePage] and a [UsageId].
433    pub fn from_page_and_id(usage_page: UsagePage, usage_id: UsageId) -> Usage {
434        Usage {
435            usage_page,
436            usage_id,
437        }
438    }
439}
440
441impl From<u32> for Usage {
442    fn from(u: u32) -> Usage {
443        Usage {
444            usage_page: UsagePage::from((u >> 16) as u16),
445            usage_id: UsageId::from((u & 0xffff) as u16),
446        }
447    }
448}
449
450impl From<&Usage> for u32 {
451    fn from(u: &Usage) -> u32 {
452        (u16::from(u.usage_page) as u32) << 16 | u16::from(u.usage_id) as u32
453    }
454}
455
456impl_from_without_ref!(Usage, u32, u32);
457
458impl From<&Usage> for UsageMinimum {
459    fn from(u: &Usage) -> UsageMinimum {
460        UsageMinimum(u32::from(u))
461    }
462}
463
464impl_from_without_ref!(Usage, UsageMinimum, UsageMinimum);
465
466impl From<&Usage> for UsageMaximum {
467    fn from(u: &Usage) -> UsageMaximum {
468        UsageMaximum(u32::from(u))
469    }
470}
471
472impl_from_without_ref!(Usage, UsageMaximum, UsageMaximum);
473
474#[cfg(feature = "hut")]
475impl From<hut::Usage> for Usage {
476    fn from(usage: hut::Usage) -> Usage {
477        let usage_page = UsagePage::from(usage.usage_page_value());
478        let usage_id = UsageId::from(usage.usage_id_value());
479        Usage::from_page_and_id(usage_page, usage_id)
480    }
481}
482
483/// A unique (within this report descriptor) identifier for a [Field].
484///
485/// The [FieldId] does not exist in the actual ReportDescriptor, it is
486/// a unique ID assigned by this crate to later identify a given field
487/// for data extraction and/or further parsing.
488#[derive(Clone, Copy, Debug, PartialEq, Hash, PartialOrd)]
489pub struct FieldId(u32);
490
491impl From<&FieldId> for u32 {
492    fn from(f: &FieldId) -> u32 {
493        f.0
494    }
495}
496
497impl_from_without_ref!(FieldId, u32, u32);
498
499/// A wrapper around the value of a [Field] inside
500/// a HID Report's byte array. This value may
501/// be signed, depending on the [Field].
502///
503/// ```
504/// # use hidreport::VariableField;
505/// # fn read_from_device() -> Vec<u8> {
506/// #     vec![0x1a, 0x00, 0xff, 0xff, 0xfe, 0xff, 00, 00, 00, 0x00]
507/// # }
508/// #
509/// # fn func(field: &VariableField, bytes: &[u8]) {
510/// let bytes: Vec<u8> = read_from_device();
511/// let val = field.extract(bytes.as_slice()).unwrap();
512/// if val.is_signed() {
513///   let unsigned: u32 = val.into();
514/// } else {
515///   let signed: i32 = val.into();
516/// }
517/// # }
518/// ```
519///
520/// The value is always of size [u32] or [i32], regardless of the
521/// number of bits in the HID Report. Cast to [u16], [u8], etc. as needed.
522#[derive(Clone, Copy, Debug)]
523pub struct FieldValue {
524    is_signed: bool,
525    value: u32,
526}
527
528impl FieldValue {
529    /// Returns `true` if the contained value is signed, `false` otherwise.
530    pub fn is_signed(&self) -> bool {
531        self.is_signed
532    }
533}
534
535impl From<&FieldValue> for u32 {
536    fn from(v: &FieldValue) -> u32 {
537        v.value
538    }
539}
540
541impl_from_without_ref!(FieldValue, u32, u32);
542
543impl From<&FieldValue> for u16 {
544    fn from(v: &FieldValue) -> u16 {
545        v.value as u16
546    }
547}
548
549impl_from_without_ref!(FieldValue, u16, u16);
550
551impl From<&FieldValue> for u8 {
552    fn from(v: &FieldValue) -> u8 {
553        v.value as u8
554    }
555}
556
557impl_from_without_ref!(FieldValue, u8, u8);
558
559impl From<&FieldValue> for i32 {
560    fn from(v: &FieldValue) -> i32 {
561        v.value as i32
562    }
563}
564
565impl_from_without_ref!(FieldValue, i32, i32);
566
567impl From<&FieldValue> for i16 {
568    fn from(v: &FieldValue) -> i16 {
569        v.value as i16
570    }
571}
572
573impl_from_without_ref!(FieldValue, i16, i16);
574
575impl From<&FieldValue> for i8 {
576    fn from(v: &FieldValue) -> i8 {
577        v.value as i8
578    }
579}
580
581impl_from_without_ref!(FieldValue, i8, i8);
582
583/// A single field inside a [Report].
584///
585/// Fields may be [Variable](Field::Variable) and represent a
586/// single element of data or they may be
587/// a [Array](Field::Array) that represent
588/// multiple elements.
589///
590/// Fields of type [Constant](Field::Constant) should be ignored by
591/// the caller.
592///
593/// Given a set of bytes that is a HID Report use [VariableField::extract()] or
594/// [ArrayField::extract()] to extract the value for this field, for example:
595/// ```
596/// # use hidreport::VariableField;
597/// # fn func(field: &VariableField, bytes: &[u8]) {
598///   let val = field.extract(bytes).unwrap();
599///   if val.is_signed() {
600///     let unsigned: u32 = val.into();
601///   } else {
602///     let signed: i32 = val.into();
603///   }
604/// # }
605/// ```
606#[derive(Clone, Debug)]
607pub enum Field {
608    /// A single element of data
609    Variable(VariableField),
610    /// A set of multiple fields
611    Array(ArrayField),
612    /// Padding
613    Constant(ConstantField),
614}
615
616impl Field {
617    /// Return the unique (within this report descriptor) ID for this field.
618    ///
619    /// The [FieldId] does not exist in the actual ReportDescriptor, it is
620    /// a unique ID assigned by this crate to later identify a given field
621    /// for data extraction and/or further parsing.
622    pub fn id(&self) -> FieldId {
623        match self {
624            Field::Variable(f) => f.id,
625            Field::Array(f) => f.id,
626            Field::Constant(f) => f.id,
627        }
628    }
629    /// Returns the bit range that make up this field.
630    pub fn bits(&self) -> &Range<usize> {
631        match self {
632            Field::Variable(f) => &f.bits,
633            Field::Array(f) => &f.bits,
634            Field::Constant(f) => &f.bits,
635        }
636    }
637
638    /// Returns the Report ID this field belongs to, if any.
639    fn report_id(&self) -> &Option<ReportId> {
640        match self {
641            Field::Variable(f) => &f.report_id,
642            Field::Array(f) => &f.report_id,
643            Field::Constant(f) => &f.report_id,
644        }
645    }
646
647    fn update_bit_offset(&mut self, offset: usize) {
648        let r = self.bits();
649        let r = (offset + r.start)..(offset + r.end);
650        match self {
651            Field::Variable(f) => f.bits = r,
652            Field::Array(f) => f.bits = r,
653            Field::Constant(f) => f.bits = r,
654        };
655    }
656
657    /// The length of the field in bits
658    fn len(&self) -> usize {
659        return self.bits().len();
660    }
661
662    /// Return the set of collections this [Field] belongs to
663    /// or the empty slice.
664    pub fn collections(&self) -> &[Collection] {
665        match self {
666            Field::Variable(f) => &f.collections,
667            Field::Array(f) => &f.collections,
668            Field::Constant(..) => &[],
669        }
670    }
671}
672
673/// A [VariableField] represents a single physical control.
674#[derive(Clone, Debug)]
675pub struct VariableField {
676    id: FieldId,
677    report_id: Option<ReportId>,
678    pub bits: Range<usize>,
679    pub usage: Usage,
680    pub logical_minimum: LogicalMinimum,
681    pub logical_maximum: LogicalMaximum,
682    pub physical_minimum: Option<PhysicalMinimum>,
683    pub physical_maximum: Option<PhysicalMaximum>,
684    pub unit: Option<Unit>,
685    pub unit_exponent: Option<UnitExponent>,
686    pub collections: Vec<Collection>,
687}
688
689impl VariableField {
690    /// Returns true if this field contains signed values,
691    /// i.e. the LogicalMinimum is less than zero.
692    pub fn is_signed(&self) -> bool {
693        self.logical_minimum < LogicalMinimum(0)
694    }
695
696    /// Extract this field's value as [FieldValue] from a report's bytes.
697    /// The value is extracted as its correct bit size, the returned [FieldValue]
698    /// can then be casted in to a [u32], [i32], etc. via the [From] trait.
699    /// ```
700    /// # use hidreport::VariableField;
701    /// # fn func(field: &VariableField, bytes: &[u8]) {
702    ///   let val = field.extract(bytes).unwrap();
703    ///   if val.is_signed() {
704    ///     let unsigned: u32 = val.into();
705    ///   } else {
706    ///     let signed: i32 = val.into();
707    ///   }
708    /// # }
709    /// ```
710    pub fn extract(&self, bytes: &[u8]) -> Result<FieldValue> {
711        if let Some(report_id) = self.report_id {
712            if ReportId(bytes[0]) != report_id {
713                return Err(ParserError::MismatchingReportId);
714            }
715        }
716
717        let v = extract_bits(bytes, &self.bits);
718        let v = if self.is_signed() {
719            v.twos_comp(self.bits.len()) as u32
720        } else {
721            v
722        };
723
724        Ok(FieldValue {
725            is_signed: self.is_signed(),
726            value: v,
727        })
728    }
729}
730
731/// Wrapper around the commonly used [UsageMinimum] and [UsageMaximum].
732#[derive(Debug)]
733pub struct UsageRange {
734    usage_page: UsagePage,
735    minimum: UsageMinimum,
736    maximum: UsageMaximum,
737}
738
739impl UsageRange {
740    /// The [UsageMinimum]. Note that in reports and report descriptors
741    /// the Usage Minimum may or may not include the Usage Page. The
742    /// minimum returned here always includes the [UsagePage].
743    pub fn minimum(&self) -> UsageMinimum {
744        self.minimum
745    }
746
747    /// The [UsageMaximum]. Note that in reports and report descriptors
748    /// the Usage Maximum may or may not include the Usage Page. The
749    /// maximum returned here always includes the [UsagePage].
750    pub fn maximum(&self) -> UsageMaximum {
751        self.maximum
752    }
753
754    /// If the given usage falls within this usage range (i.e. it is of the
755    /// same [UsagePage] and it within the inclusive [UsageMinimum]/[UsageMaximum])
756    /// return the provided usage as [Option].
757    pub fn lookup_usage<'a>(&self, usage: &'a Usage) -> Option<&'a Usage> {
758        if usage.usage_page == self.usage_page
759            && usage.usage_id >= self.minimum.usage_id()
760            && usage.usage_id <= self.maximum.usage_id()
761        {
762            Some(usage)
763        } else {
764            None
765        }
766    }
767
768    /// Look up the given [UsageId] and return the corresponding
769    /// [Usage], if any. The [UsageId] is assumed to be in the same
770    /// [UsagePage] as this range, use [lookup_usage()][Self::lookup_usage] if you need
771    /// a check for the [UsagePage] as well.
772    pub fn lookup_id(&self, id: UsageId) -> Option<Usage> {
773        if id >= self.minimum.usage_id() && id <= self.maximum.usage_id() {
774            Some(Usage::from_page_and_id(self.usage_page, id))
775        } else {
776            None
777        }
778    }
779}
780
781/// An [ArrayField] represents a group of physical controls,
782/// see section 6.2.2.5.
783///
784/// > An array provides an alternate means for
785/// > describing the data returned from a group of
786/// > buttons. Arrays are more efficient, if less flexible
787/// > than variable items. Rather than returning a single
788/// > bit for each button in the group, an array returns an
789/// > index in each field that corresponds to the pressed
790/// > button
791#[derive(Clone, Debug)]
792pub struct ArrayField {
793    id: FieldId,
794    report_id: Option<ReportId>,
795    pub bits: Range<usize>,
796    usages: Vec<Usage>,
797    pub report_count: ReportCount,
798    pub logical_minimum: LogicalMinimum,
799    pub logical_maximum: LogicalMaximum,
800    pub physical_minimum: Option<PhysicalMinimum>,
801    pub physical_maximum: Option<PhysicalMaximum>,
802    pub unit: Option<Unit>,
803    pub unit_exponent: Option<UnitExponent>,
804    pub collections: Vec<Collection>,
805}
806
807impl ArrayField {
808    /// Returns the set of usages for this field. This is the
809    /// inclusive range of [UsageMinimum]`..=`[UsageMaximum]
810    /// as defined for this field.
811    ///
812    /// In most cases it's better to use [usage_range()](Self::usage_range)
813    /// instead.
814    pub fn usages(&self) -> &[Usage] {
815        &self.usages
816    }
817
818    /// Returns the [UsageRange] for this field.
819    pub fn usage_range(&self) -> UsageRange {
820        let min = self.usages.first().unwrap();
821        let max = self.usages.last().unwrap();
822
823        UsageRange {
824            usage_page: min.usage_page,
825            minimum: UsageMinimum::from(min),
826            maximum: UsageMaximum::from(max),
827        }
828    }
829
830    /// Returns true if this field contains signed values,.
831    /// i.e. the LogicalMinimum is less than zero.
832    pub fn is_signed(&self) -> bool {
833        self.logical_minimum < LogicalMinimum(0)
834    }
835
836    /// Extract this field's value as [FieldValue] from a report's bytes.
837    /// The value is extracted as its correct bit size, the returned [FieldValue]
838    /// can then be casted in to a [u32], [i32], etc. via the [From] trait.
839    ///
840    /// ```
841    /// # use hidreport::ArrayField;
842    /// # fn func(field: &ArrayField, bytes: &[u8]) {
843    /// if field.is_signed() {
844    ///     println!("Signed values: {:?}", field
845    ///         .extract(bytes)
846    ///         .unwrap()
847    ///         .iter()
848    ///         .map(i32::from)
849    ///         .collect::<Vec<i32>>());
850    /// } else {
851    ///     println!("Unsigned values: {:?}", field
852    ///         .extract(bytes)
853    ///         .unwrap()
854    ///         .iter()
855    ///         .map(u32::from)
856    ///         .collect::<Vec<u32>>());
857    /// }
858    ///
859    /// # }
860    /// ```
861    pub fn extract(&self, bytes: &[u8]) -> Result<Vec<FieldValue>> {
862        if let Some(report_id) = self.report_id {
863            if ReportId(bytes[0]) != report_id {
864                return Err(ParserError::MismatchingReportId);
865            }
866        }
867
868        let count = usize::from(self.report_count);
869        let values: Result<Vec<FieldValue>> =
870            (0..count).map(|idx| self.extract_one(bytes, idx)).collect();
871
872        values
873    }
874
875    /// Extract a single value from this array. See [ArrayField::extract].
876    ///
877    /// The index must be less than [Self::report_count].
878    pub fn extract_one(&self, bytes: &[u8], idx: usize) -> Result<FieldValue> {
879        if idx >= usize::from(self.report_count) {
880            return Err(ParserError::OutOfBounds);
881        }
882        if let Some(report_id) = self.report_id {
883            if ReportId(bytes[0]) != report_id {
884                return Err(ParserError::MismatchingReportId);
885            }
886        }
887
888        let count = usize::from(self.report_count);
889        let bits_per_report = self.bits.len() / count;
890
891        let offset = self.bits.start + bits_per_report * idx;
892        let bits = offset..offset + bits_per_report;
893        let v = extract_bits(bytes, &bits);
894        let v = if self.is_signed() {
895            v.twos_comp(self.bits.len()) as u32
896        } else {
897            v
898        };
899
900        Ok(FieldValue {
901            is_signed: self.is_signed(),
902            value: v,
903        })
904    }
905}
906
907/// A [ConstantField] is one that represents a [hid::MainItem]
908/// with Constant data, see Section 6.2.2.4.
909///
910/// > Constant indicates the item is a static read-only field in a
911/// > report and cannot be modified (written) by the
912/// > host.
913///
914/// Data in a [ConstantField] should be ignored by the caller, it
915/// is merely used as padding, usually to align the subsequent
916/// value on a byte boundary.
917#[derive(Clone, Debug)]
918pub struct ConstantField {
919    id: FieldId,
920    report_id: Option<ReportId>,
921    pub bits: Range<usize>,
922    usages: Vec<Usage>,
923}
924
925impl ConstantField {
926    pub fn usages(&self) -> &[Usage] {
927        &self.usages
928    }
929}
930
931/// A unique (within this report descriptor) identifier for a collection.
932///
933/// A device may have multiple collections that are otherwise identical
934/// (in particular logical collections), the collection ID serves
935/// to identify whether two fields are part of the same collection.
936#[derive(Clone, Debug, PartialEq, Hash, PartialOrd)]
937pub struct CollectionId(u32);
938
939/// Collections group [Fields](Field) together into logical or physical
940/// groups.
941///
942/// For example, a set of buttons and x/y axes may be grouped
943/// together to represent a Mouse device.
944/// Each [Field] may belong to a number of collections.
945///
946/// ```
947/// # use hidreport::*;
948/// # fn func(field: &VariableField) {
949/// let collection = field.collections.first().unwrap();
950/// match collection.collection_type() {
951///     CollectionType::Physical => println!("This field is part of a physical collection"),
952///     _ => {},
953/// }
954/// # }
955/// ```
956///
957#[derive(Clone, Debug)]
958pub struct Collection {
959    id: CollectionId,
960    collection_type: CollectionType,
961    usages: Vec<Usage>,
962}
963
964impl Collection {
965    /// Returns the unique ID for this collection
966    pub fn id(&self) -> &CollectionId {
967        &self.id
968    }
969    /// Return the type of this collection (e.g. physical, logical, ...)
970    pub fn collection_type(&self) -> CollectionType {
971        self.collection_type
972    }
973
974    /// Returns the usages assigned to this collection
975    pub fn usages(&self) -> &[Usage] {
976        &self.usages
977    }
978}
979
980impl PartialEq for Collection {
981    fn eq(&self, other: &Self) -> bool {
982        self.id == other.id
983    }
984}
985
986impl Eq for Collection {}
987
988impl Hash for Collection {
989    fn hash<H: Hasher>(&self, state: &mut H) {
990        self.id.hash(state);
991    }
992}
993
994#[derive(Error, Debug)]
995pub enum ParserError {
996    #[error("Invalid data at offset {offset}: {message}")]
997    InvalidData { offset: usize, message: String },
998    #[error("Parsing would lead to out-of-bounds")]
999    OutOfBounds,
1000    #[error("Mismatching Report ID")]
1001    MismatchingReportId,
1002}
1003
1004type Result<T> = std::result::Result<T, ParserError>;
1005
1006#[derive(Clone, Copy, Debug, Default)]
1007struct Globals {
1008    usage_page: Option<UsagePage>,
1009    logical_minimum: Option<LogicalMinimum>,
1010    logical_maximum: Option<LogicalMaximum>,
1011    physical_minimum: Option<PhysicalMinimum>,
1012    physical_maximum: Option<PhysicalMaximum>,
1013    unit_exponent: Option<UnitExponent>,
1014    unit: Option<Unit>,
1015    report_size: Option<ReportSize>,
1016    report_id: Option<ReportId>,
1017    report_count: Option<ReportCount>,
1018}
1019
1020/// Special struct for the [Locals] because the usage_page
1021/// is optional for those, unlike our [Usage] struct which is
1022/// the finalized one.
1023#[derive(Clone, Copy, Debug)]
1024struct LocalUsage {
1025    usage_page: Option<UsagePage>,
1026    usage_id: UsageId,
1027}
1028
1029#[derive(Clone, Debug, Default)]
1030struct Locals {
1031    usage: Vec<LocalUsage>,
1032    // FIXME: needs the same LocalUsage treatment
1033    usage_minimum: Option<UsageMinimum>,
1034    usage_maximum: Option<UsageMaximum>,
1035    designator_index: Option<DesignatorIndex>,
1036    designator_minimum: Option<DesignatorMinimum>,
1037    designator_maximum: Option<DesignatorMaximum>,
1038    string_index: Option<StringIndex>,
1039    string_minimum: Option<StringMinimum>,
1040    string_maximum: Option<StringMaximum>,
1041    delimiter: Option<Delimiter>,
1042}
1043
1044#[derive(Debug)]
1045struct Stack {
1046    globals: Vec<Globals>,
1047    locals: Vec<Locals>,
1048    pub collections: Vec<Collection>,
1049}
1050
1051impl Stack {
1052    fn new() -> Self {
1053        Stack {
1054            globals: vec![Globals::default()],
1055            locals: vec![Locals::default()],
1056            collections: vec![],
1057        }
1058    }
1059
1060    fn push(&mut self) {
1061        let current = self.globals.last().unwrap();
1062        self.globals.push(*current);
1063
1064        // FIXME: this clones the Usage vector which is likely to mess us up, I don't
1065        // think they transfer across push/pop
1066        let current = self.locals.last().unwrap().clone();
1067        self.locals.push(current);
1068    }
1069
1070    fn pop(&mut self) -> Result<()> {
1071        ensure!(
1072            !self.globals.is_empty() && !self.locals.is_empty(),
1073            ParserError::InvalidData {
1074                offset: 0,
1075                message: "Too many Pops".into(),
1076            }
1077        );
1078        self.globals.pop();
1079        self.locals.pop();
1080        ensure!(
1081            !self.globals.is_empty() && !self.locals.is_empty(),
1082            ParserError::InvalidData {
1083                offset: 0,
1084                message: "Too many Pops, not enough Pushes".into(),
1085            }
1086        );
1087        Ok(())
1088    }
1089
1090    fn reset_locals(&mut self) {
1091        self.locals.pop();
1092        self.locals.push(Locals::default());
1093    }
1094
1095    fn globals(&mut self) -> &mut Globals {
1096        self.globals.last_mut().unwrap()
1097    }
1098
1099    fn locals(&mut self) -> &mut Locals {
1100        self.locals.last_mut().unwrap()
1101    }
1102
1103    // Should be globals and globals_mut but i'd have to
1104    // update the update_stack macro for that.
1105    fn globals_const(&self) -> &Globals {
1106        self.globals.last().unwrap()
1107    }
1108
1109    fn locals_const(&self) -> &Locals {
1110        self.locals.last().unwrap()
1111    }
1112}
1113
1114fn compile_usages(globals: &Globals, locals: &Locals) -> Result<Vec<Usage>> {
1115    // Prefer UsageMinimum/Maximum over Usage because the latter may be set from an earlier call
1116    match locals.usage_minimum {
1117        Some(_) => {
1118            let Some(min) = locals.usage_minimum else {
1119                return Err(ParserError::InvalidData {
1120                    offset: 0,
1121                    message: "Missing UsageMinimum in locals".into(),
1122                });
1123            };
1124            let Some(max) = locals.usage_maximum else {
1125                return Err(ParserError::InvalidData {
1126                    offset: 0,
1127                    message: "Missing UsageMaximum in locals".into(),
1128                });
1129            };
1130            let Some(usage_page) = globals.usage_page else {
1131                return Err(ParserError::InvalidData {
1132                    offset: 0,
1133                    message: "Missing UsagePage in globals".into(),
1134                });
1135            };
1136            let min: u32 = min.into();
1137            let max: u32 = max.into();
1138
1139            let usages = (min..=max)
1140                .map(|u| Usage {
1141                    usage_page: UsagePage(usage_page.into()),
1142                    usage_id: UsageId(u as u16),
1143                })
1144                .collect();
1145            Ok(usages)
1146        }
1147        None => {
1148            let usages = locals
1149                .usage
1150                .iter()
1151                .map(|usage| match usage {
1152                    // local item's Usage had a Usage Page included
1153                    LocalUsage {
1154                        usage_page: Some(up),
1155                        usage_id,
1156                    } => Usage {
1157                        usage_page: *up,
1158                        usage_id: *usage_id,
1159                    },
1160                    // Usage Page comes from the global item
1161                    LocalUsage {
1162                        usage_page: None,
1163                        usage_id,
1164                    } => {
1165                        let usage_page = globals.usage_page.expect("Missing UsagePage in globals");
1166                        Usage {
1167                            usage_page,
1168                            usage_id: *usage_id,
1169                        }
1170                    }
1171                })
1172                .collect();
1173            Ok(usages)
1174        }
1175    }
1176}
1177
1178fn handle_main_item(item: &MainItem, stack: &mut Stack, base_id: u32) -> Result<Vec<Field>> {
1179    let globals = stack.globals_const();
1180    let locals = stack.locals_const();
1181
1182    let report_id = globals.report_id;
1183
1184    let (is_constant, is_variable) = match item {
1185        MainItem::Input(i) => (i.is_constant(), i.is_variable()),
1186        MainItem::Output(i) => (i.is_constant(), i.is_variable()),
1187        MainItem::Feature(i) => (i.is_constant(), i.is_variable()),
1188        _ => panic!("Invalid item for handle_main_item()"),
1189    };
1190
1191    let bit_offset = 0;
1192    // We have HID report descriptors in the wild that do not set a report size/count/whatever.
1193    // Since the most important implementations so far have been in C-like languages, they
1194    // will likely default to zero for unset values (unlike our None).
1195    // Let's do this here to be as compatible as possible.
1196    let report_size = globals.report_size.unwrap_or(ReportSize(0));
1197    let report_count = globals.report_count.unwrap_or(ReportCount(0));
1198
1199    if report_count == ReportCount(0) || report_size == ReportSize(0) {
1200        return Ok(vec![]);
1201    }
1202
1203    if is_constant {
1204        let nbits = usize::from(report_size) * usize::from(report_count);
1205        let bits = bit_offset..(bit_offset + nbits);
1206
1207        let field = ConstantField {
1208            id: FieldId(base_id + bit_offset as u32),
1209            bits,
1210            report_id,
1211            usages: vec![],
1212        };
1213        return Ok(vec![Field::Constant(field)]);
1214    }
1215
1216    let logical_minimum = globals.logical_minimum.unwrap_or(LogicalMinimum(0));
1217    let logical_maximum = globals.logical_maximum.unwrap_or(LogicalMaximum(0));
1218
1219    // Some report descriptors are missing either phys min or max, assume zero
1220    // where one of them is not None
1221    let physical_maximum: Option<PhysicalMaximum>;
1222    let physical_minimum: Option<PhysicalMinimum>;
1223    if globals.physical_minimum.is_some() != globals.physical_maximum.is_some() {
1224        physical_maximum = globals.physical_maximum.or(Some(PhysicalMaximum(0)));
1225        physical_minimum = globals.physical_minimum.or(Some(PhysicalMinimum(0)));
1226    } else {
1227        physical_maximum = globals.physical_maximum;
1228        physical_minimum = globals.physical_minimum;
1229    }
1230
1231    let unit = globals.unit;
1232    let unit_exponent = globals.unit_exponent;
1233
1234    let usages = compile_usages(globals, locals)?;
1235    ensure!(!usages.is_empty(), "Missing Usages for main item");
1236
1237    // This may be an empty vec
1238    let collections = stack.collections.clone();
1239    let fields: Vec<Field> = if is_variable {
1240        let mut bit_offset = 0;
1241        Range {
1242            start: 0,
1243            end: usize::from(report_count),
1244        }
1245        .map(|c| {
1246            let nbits = usize::from(report_size);
1247            let bits = bit_offset..(bit_offset + nbits);
1248            bit_offset += nbits;
1249
1250            let usage = usages.get(c).or_else(|| usages.last()).unwrap();
1251            let field = VariableField {
1252                id: FieldId(base_id + bit_offset as u32),
1253                usage: *usage,
1254                bits,
1255                logical_minimum,
1256                logical_maximum,
1257                physical_minimum,
1258                physical_maximum,
1259                unit,
1260                unit_exponent,
1261                collections: collections.clone(),
1262                report_id,
1263            };
1264            Field::Variable(field)
1265        })
1266        .collect()
1267    } else {
1268        let bit_offset = 0;
1269        let nbits = usize::from(report_size) * usize::from(report_count);
1270        let bits = bit_offset..(bit_offset + nbits);
1271
1272        let field = ArrayField {
1273            id: FieldId(base_id + bit_offset as u32),
1274            usages,
1275            bits,
1276            logical_minimum,
1277            logical_maximum,
1278            physical_minimum,
1279            physical_maximum,
1280            unit,
1281            unit_exponent,
1282            collections,
1283            report_id,
1284            report_count,
1285        };
1286
1287        vec![Field::Array(field)]
1288    };
1289
1290    Ok(fields)
1291}
1292
1293macro_rules! update_stack {
1294    ($stack:ident, $class:ident, $which:ident, $from:ident) => {
1295        //println!("Updating {} with value {:?}", stringify!($which), &$from);
1296        let state = $stack.$class();
1297        state.$which = Some($from);
1298    };
1299}
1300
1301fn parse_report_descriptor(bytes: &[u8]) -> Result<ReportDescriptor> {
1302    ensure!(!bytes.is_empty(), "Empty report descriptor");
1303    let items = hid::ReportDescriptorItems::try_from(bytes)?;
1304
1305    let mut stack = Stack::new();
1306    let mut rdesc = ReportDescriptor::default();
1307
1308    for rdesc_item in items.iter() {
1309        //println!("Handling offset {}", rdesc_item.offset());
1310        let item = rdesc_item.item();
1311        match item.item_type() {
1312            ItemType::Main(MainItem::Collection(i)) => {
1313                let globals = stack.globals_const();
1314                let locals = stack.locals_const();
1315                // This may be an empty vec
1316                let usages = match compile_usages(globals, locals) {
1317                    Ok(usages) => usages,
1318                    Err(ParserError::InvalidData { message, .. }) => {
1319                        return Err(ParserError::InvalidData {
1320                            offset: rdesc_item.offset(),
1321                            message,
1322                        })
1323                    }
1324                    Err(e) => return Err(e),
1325                };
1326                let c = Collection {
1327                    id: CollectionId(rdesc_item.offset() as u32),
1328                    collection_type: i,
1329                    usages,
1330                };
1331                stack.collections.push(c);
1332                stack.reset_locals();
1333            }
1334            ItemType::Main(MainItem::EndCollection) => {
1335                if stack.collections.pop().is_none() {
1336                    return Err(ParserError::InvalidData {
1337                        offset: rdesc_item.offset(),
1338                        message: "Too many EndCollection".into(),
1339                    });
1340                };
1341                stack.reset_locals();
1342            }
1343            ItemType::Main(item) => {
1344                let mut fields =
1345                    match handle_main_item(&item, &mut stack, (rdesc_item.offset() * 8) as u32) {
1346                        Ok(fields) => fields,
1347                        Err(ParserError::InvalidData { message, .. }) => {
1348                            return Err(ParserError::InvalidData {
1349                                offset: rdesc_item.offset(),
1350                                message,
1351                            })
1352                        }
1353                        Err(e) => return Err(e),
1354                    };
1355                stack.reset_locals();
1356
1357                // Report descriptors with a ReportCount or ReportSize of 0 (or those missing)
1358                // will have an empty fields list. These exist in the wild.
1359                if !fields.is_empty() {
1360                    // Now update the returned field(s) and push them into the right report
1361                    let direction = match item {
1362                        MainItem::Input(_) => Direction::Input,
1363                        MainItem::Output(_) => Direction::Output,
1364                        MainItem::Feature(_) => Direction::Feature,
1365                        _ => panic!("Invalid item for handle_main_item()"),
1366                    };
1367
1368                    let reports: &mut Vec<RDescReport> = match direction {
1369                        Direction::Input => &mut rdesc.input_reports,
1370                        Direction::Output => &mut rdesc.output_reports,
1371                        Direction::Feature => &mut rdesc.feature_reports,
1372                    };
1373
1374                    let report_id = fields.first().unwrap().report_id();
1375                    let report = match report_id {
1376                        None => reports.first_mut(),
1377                        Some(id) => reports
1378                            .iter_mut()
1379                            .find(|r| r.id.is_some() && &r.id.unwrap() == id),
1380                    };
1381
1382                    let report = match report {
1383                        None => {
1384                            let initial_size = if report_id.is_some() { 8 } else { 0 };
1385                            reports.push(RDescReport {
1386                                id: *report_id,
1387                                size: initial_size,
1388                                fields: vec![],
1389                            });
1390                            reports.last_mut().unwrap()
1391                        }
1392                        Some(r) => r,
1393                    };
1394
1395                    // We know which report the fields belong to, let's update the offsets and field id
1396                    let offset = report.size;
1397                    fields.iter_mut().for_each(|f| {
1398                        f.update_bit_offset(offset);
1399                        report.size += f.len();
1400                    });
1401
1402                    report.fields.append(&mut fields);
1403                }
1404            }
1405            ItemType::Long => {}
1406            ItemType::Reserved => {}
1407            ItemType::Global(GlobalItem::UsagePage(usage_page)) => {
1408                update_stack!(stack, globals, usage_page, usage_page);
1409            }
1410            ItemType::Global(GlobalItem::LogicalMinimum(minimum)) => {
1411                update_stack!(stack, globals, logical_minimum, minimum);
1412            }
1413            ItemType::Global(GlobalItem::LogicalMaximum(maximum)) => {
1414                // We don't know if the maximum is signed or unsigned unless we
1415                // look at the minimum value and check if that is signed or unsigned.
1416                // We default to signed but if the minimum is unsigned, we might have
1417                // to re-interpret.
1418                let minimum = stack
1419                    .globals_const()
1420                    .logical_minimum
1421                    .unwrap_or(LogicalMinimum(0));
1422                let mut maximum = maximum;
1423                if minimum < LogicalMinimum(0) {
1424                    if let Some(data) = item.data() {
1425                        if data.len() > 0 {
1426                            maximum = LogicalMaximum(hid::hiddata_signed(&data).unwrap());
1427                        }
1428                    }
1429                };
1430                update_stack!(stack, globals, logical_maximum, maximum);
1431            }
1432            ItemType::Global(GlobalItem::PhysicalMinimum(minimum)) => {
1433                update_stack!(stack, globals, physical_minimum, minimum);
1434            }
1435            ItemType::Global(GlobalItem::PhysicalMaximum(maximum)) => {
1436                // We don't know if the maximum is signed or unsigned unless we
1437                // look at the minimum value and check if that is signed or unsigned.
1438                // We default to signed but if the minimum is unsigned, we might have
1439                // to re-interpret.
1440                let minimum = stack
1441                    .globals_const()
1442                    .physical_minimum
1443                    .unwrap_or(PhysicalMinimum(0));
1444                let mut maximum = maximum;
1445                if minimum < PhysicalMinimum(0) {
1446                    if let Some(data) = item.data() {
1447                        if data.len() > 0 {
1448                            maximum = PhysicalMaximum(hid::hiddata_signed(&data).unwrap())
1449                        }
1450                    }
1451                };
1452                update_stack!(stack, globals, physical_maximum, maximum);
1453            }
1454            ItemType::Global(GlobalItem::UnitExponent(exponent)) => {
1455                update_stack!(stack, globals, unit_exponent, exponent);
1456            }
1457            ItemType::Global(GlobalItem::Unit(unit)) => {
1458                update_stack!(stack, globals, unit, unit);
1459            }
1460            ItemType::Global(GlobalItem::ReportSize(size)) => {
1461                update_stack!(stack, globals, report_size, size);
1462            }
1463            ItemType::Global(GlobalItem::ReportId(id)) => {
1464                update_stack!(stack, globals, report_id, id);
1465            }
1466            ItemType::Global(GlobalItem::ReportCount(count)) => {
1467                update_stack!(stack, globals, report_count, count);
1468            }
1469            ItemType::Global(GlobalItem::Push) => {
1470                stack.push();
1471            }
1472            ItemType::Global(GlobalItem::Pop) => match stack.pop() {
1473                Ok(_) => {}
1474                Err(ParserError::InvalidData { message, .. }) => {
1475                    return Err(ParserError::InvalidData {
1476                        offset: rdesc_item.offset(),
1477                        message,
1478                    })
1479                }
1480                Err(e) => return Err(e),
1481            },
1482            ItemType::Global(GlobalItem::Reserved) => {}
1483            ItemType::Local(LocalItem::Usage(usage_page, usage_id)) => {
1484                let usage = LocalUsage {
1485                    usage_page: Some(usage_page),
1486                    usage_id,
1487                };
1488                stack.locals().usage.push(usage);
1489            }
1490            ItemType::Local(LocalItem::UsageId(usage_id)) => {
1491                let usage = LocalUsage {
1492                    usage_page: None,
1493                    usage_id,
1494                };
1495                stack.locals().usage.push(usage);
1496            }
1497            ItemType::Local(LocalItem::UsageMinimum(minimum)) => {
1498                update_stack!(stack, locals, usage_minimum, minimum);
1499            }
1500            ItemType::Local(LocalItem::UsageMaximum(maximum)) => {
1501                update_stack!(stack, locals, usage_maximum, maximum);
1502            }
1503            ItemType::Local(LocalItem::DesignatorIndex(index)) => {
1504                update_stack!(stack, locals, designator_index, index);
1505            }
1506            ItemType::Local(LocalItem::DesignatorMinimum(minimum)) => {
1507                update_stack!(stack, locals, designator_minimum, minimum);
1508            }
1509            ItemType::Local(LocalItem::DesignatorMaximum(maximum)) => {
1510                update_stack!(stack, locals, designator_maximum, maximum);
1511            }
1512            ItemType::Local(LocalItem::StringIndex(index)) => {
1513                update_stack!(stack, locals, string_index, index);
1514            }
1515            ItemType::Local(LocalItem::StringMinimum(minimum)) => {
1516                update_stack!(stack, locals, string_minimum, minimum);
1517            }
1518            ItemType::Local(LocalItem::StringMaximum(maximum)) => {
1519                update_stack!(stack, locals, string_maximum, maximum);
1520            }
1521            ItemType::Local(LocalItem::Delimiter(delimiter)) => {
1522                update_stack!(stack, locals, delimiter, delimiter);
1523            }
1524            ItemType::Local(LocalItem::Reserved { value: _ }) => {}
1525        };
1526    }
1527
1528    Ok(rdesc)
1529}
1530
1531#[cfg(test)]
1532mod tests {
1533    use super::*;
1534
1535    #[test]
1536    fn test_twos_comp() {
1537        assert_eq!(5u8.twos_comp(3), -3);
1538        assert_eq!(5u8.twos_comp(4), 5);
1539        assert_eq!(0xffu8.twos_comp(8), -1);
1540
1541        assert_eq!(5u16.twos_comp(3), -3);
1542        assert_eq!(5u16.twos_comp(4), 5);
1543        assert_eq!(0xffffu16.twos_comp(16), -1);
1544
1545        assert_eq!(5u32.twos_comp(3), -3);
1546        assert_eq!(5u32.twos_comp(4), 5);
1547        assert_eq!(0xffffffffu32.twos_comp(32), -1);
1548    }
1549
1550    #[test]
1551    fn extract() {
1552        let bytes: [u8; 4] = [0b1100_1010, 0b1011_1001, 0b1001_0110, 0b0001_0101];
1553
1554        let test_field = |bits: Range<usize>, signed: bool| -> VariableField {
1555            VariableField {
1556                id: FieldId(0),
1557                report_id: None,
1558                bits,
1559                usage: Usage::from(0),
1560                logical_minimum: LogicalMinimum(if signed { -1 } else { 0 }),
1561                logical_maximum: LogicalMaximum(0),
1562                physical_minimum: None,
1563                physical_maximum: None,
1564                unit: None,
1565                unit_exponent: None,
1566                collections: vec![],
1567            }
1568        };
1569
1570        assert_eq!(0u8, test_field(0..1, false).extract(&bytes).unwrap().into());
1571        assert_eq!(2u8, test_field(0..2, false).extract(&bytes).unwrap().into());
1572        assert_eq!(
1573            10u8,
1574            test_field(0..4, false).extract(&bytes).unwrap().into()
1575        );
1576
1577        assert_eq!(0i8, test_field(0..1, true).extract(&bytes).unwrap().into());
1578        assert_eq!(-2i8, test_field(0..2, true).extract(&bytes).unwrap().into());
1579        assert_eq!(-6i8, test_field(0..4, true).extract(&bytes).unwrap().into());
1580
1581        assert_eq!(
1582            0b1001_1100u8,
1583            test_field(4..12, true).extract(&bytes).unwrap().into()
1584        );
1585        assert_eq!(
1586            0b1001_1100u8 as i8,
1587            test_field(4..12, true).extract(&bytes).unwrap().into()
1588        );
1589
1590        assert_eq!(
1591            0u16,
1592            test_field(0..1, false).extract(&bytes).unwrap().into()
1593        );
1594        assert_eq!(
1595            2u16,
1596            test_field(0..2, false).extract(&bytes).unwrap().into()
1597        );
1598        assert_eq!(
1599            10u16,
1600            test_field(0..4, false).extract(&bytes).unwrap().into()
1601        );
1602
1603        assert_eq!(0i16, test_field(0..1, true).extract(&bytes).unwrap().into());
1604        assert_eq!(
1605            -2i16,
1606            test_field(0..2, true).extract(&bytes).unwrap().into()
1607        );
1608        assert_eq!(
1609            -6i16,
1610            test_field(0..4, true).extract(&bytes).unwrap().into()
1611        );
1612
1613        assert_eq!(
1614            0b0110_1011_1001_1100,
1615            test_field(4..20, false).extract(&bytes).unwrap().into()
1616        );
1617        assert_eq!(
1618            0b0110_1011_1001_1100,
1619            test_field(4..20, true).extract(&bytes).unwrap().into()
1620        );
1621        assert_eq!(
1622            0b1_0110_1011_1001_110u16 as i16,
1623            test_field(5..21, true).extract(&bytes).unwrap().into()
1624        );
1625
1626        assert_eq!(
1627            0b0110_1011_1001_1100,
1628            test_field(4..20, false).extract(&bytes).unwrap().into()
1629        );
1630        assert_eq!(
1631            0b0110_1011_1001_1100,
1632            test_field(4..20, true).extract(&bytes).unwrap().into()
1633        );
1634        assert_eq!(
1635            ((0b1_0110_1011_1001_110u16 as i16) as i32),
1636            test_field(5..21, true).extract(&bytes).unwrap().into()
1637        );
1638
1639        assert_eq!(
1640            ((0b1_0110_1011_1001_110u16 as i16) as i32),
1641            test_field(5..21, true).extract(&bytes).unwrap().into()
1642        );
1643
1644        let bytes: [u8; 1] = [0x0f];
1645        assert_eq!(0x3, test_field(0..2, false).extract(&bytes).unwrap().into());
1646        assert_eq!(0xf, test_field(0..4, false).extract(&bytes).unwrap().into());
1647        assert_eq!(0x0, test_field(4..8, false).extract(&bytes).unwrap().into());
1648        assert_eq!(
1649            0x0f,
1650            test_field(0..8, false).extract(&bytes).unwrap().into()
1651        );
1652
1653        let bytes: [u8; 2] = [0x0f, 0x5e];
1654        assert_eq!(0x3, test_field(0..2, false).extract(&bytes).unwrap().into());
1655        assert_eq!(0xf, test_field(0..4, false).extract(&bytes).unwrap().into());
1656        assert_eq!(0x0, test_field(4..8, false).extract(&bytes).unwrap().into());
1657        assert_eq!(
1658            0xe0f,
1659            test_field(0..12, false).extract(&bytes).unwrap().into()
1660        );
1661        assert_eq!(
1662            0x5e0f,
1663            test_field(0..16, false).extract(&bytes).unwrap().into()
1664        );
1665        assert_eq!(
1666            0xe,
1667            test_field(8..12, false).extract(&bytes).unwrap().into()
1668        );
1669        assert_eq!(
1670            0x5,
1671            test_field(12..16, false).extract(&bytes).unwrap().into()
1672        );
1673        assert_eq!(
1674            0x5e,
1675            test_field(8..16, false).extract(&bytes).unwrap().into()
1676        );
1677
1678        let bytes: [u8; 4] = [0x0f, 0x5e, 0xab, 0x78];
1679        assert_eq!(0x3, test_field(0..2, false).extract(&bytes).unwrap().into());
1680        assert_eq!(0xf, test_field(0..4, false).extract(&bytes).unwrap().into());
1681        assert_eq!(0x0, test_field(4..8, false).extract(&bytes).unwrap().into());
1682        assert_eq!(
1683            0xe0f,
1684            test_field(0..12, false).extract(&bytes).unwrap().into()
1685        );
1686        assert_eq!(
1687            0x5e0f,
1688            test_field(0..16, false).extract(&bytes).unwrap().into()
1689        );
1690        assert_eq!(
1691            0xe,
1692            test_field(8..12, false).extract(&bytes).unwrap().into()
1693        );
1694        assert_eq!(
1695            0x5,
1696            test_field(12..16, false).extract(&bytes).unwrap().into()
1697        );
1698        assert_eq!(
1699            0x5e,
1700            test_field(8..16, false).extract(&bytes).unwrap().into()
1701        );
1702        assert_eq!(
1703            0xb5e0f,
1704            test_field(0..20, false).extract(&bytes).unwrap().into()
1705        );
1706        assert_eq!(
1707            0xab5e0f,
1708            test_field(0..24, false).extract(&bytes).unwrap().into()
1709        );
1710        assert_eq!(
1711            0xb5e0,
1712            test_field(4..20, false).extract(&bytes).unwrap().into()
1713        );
1714        assert_eq!(
1715            0xab5e,
1716            test_field(8..24, false).extract(&bytes).unwrap().into()
1717        );
1718        assert_eq!(
1719            0xb,
1720            test_field(16..20, false).extract(&bytes).unwrap().into()
1721        );
1722        assert_eq!(
1723            0xab,
1724            test_field(16..24, false).extract(&bytes).unwrap().into()
1725        );
1726        assert_eq!(
1727            0x78ab5e0f,
1728            test_field(0..32, false).extract(&bytes).unwrap().into()
1729        );
1730        assert_eq!(
1731            0x7,
1732            test_field(28..32, false).extract(&bytes).unwrap().into()
1733        );
1734        assert_eq!(
1735            0x78,
1736            test_field(24..32, false).extract(&bytes).unwrap().into()
1737        );
1738    }
1739}