#![cfg_attr(not(feature = "std"), no_std)]
mod item_tokenizer;
pub mod report_data_types;
pub mod report_descriptor_parser;
mod utils;
extern crate alloc;
use crate::report_descriptor_parser::{ReportDescriptorError, ReportDescriptorParser};
use alloc::{vec, vec::Vec};
use core::ops::Range;
use report_data_types::{
DesignatorIndex, DesignatorRange, LogicalMaximum, LogicalMinimum, PhysicalMaximum, PhysicalMinimum,
ReportAttributes, ReportId, StringIndex, StringRange, Unit, UnitExponent, Usage, UsageRange,
};
use utils::u32_from_bytes;
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum FieldAccessError {
InvalidBufferSize,
InvalidFieldValue,
}
fn field_data(bits: &Range<u32>, buffer: &[u8]) -> Result<Vec<u8>, FieldAccessError> {
if (bits.end.div_ceil(8)) as usize > buffer.len() {
return Err(FieldAccessError::InvalidBufferSize);
}
let mut dst_vec = vec![0u8; (bits.len()).div_ceil(8)];
for (dst_bit, src_bit) in bits.clone().enumerate() {
let src_byte = buffer[(src_bit / 8) as usize];
let src_bit_value = (src_byte >> (src_bit % 8)) & 0x01;
let dst_byte_or_mask = src_bit_value << (dst_bit % 8);
dst_vec[dst_bit / 8] |= dst_byte_or_mask;
}
Ok(dst_vec)
}
fn set_field_data(bits: &Range<u32>, data: &[u8], buffer: &mut [u8]) -> Result<(), FieldAccessError> {
if (bits.end.div_ceil(8)) as usize > buffer.len() {
return Err(FieldAccessError::InvalidBufferSize);
}
for (src_bit, dst_bit) in bits.clone().enumerate() {
let src_byte = data[src_bit / 8];
let src_bit_value = (src_byte >> (src_bit % 8)) & 0x01;
let dst_byte_and_mask = !(1u8 << (dst_bit % 8));
let dst_byte_or_mask = src_bit_value << (dst_bit % 8);
buffer[(dst_bit / 8) as usize] &= dst_byte_and_mask;
buffer[(dst_bit / 8) as usize] |= dst_byte_or_mask;
}
Ok(())
}
fn field_value(
bits: &Range<u32>,
min: LogicalMinimum,
max: LogicalMaximum,
buffer: &[u8],
) -> Result<i64, FieldAccessError> {
let mut field_data = field_data(bits, buffer)?;
let mut raw_value_bytes = [0_u8; 8];
let adjusted_max: i64;
if i32::from(min).is_negative() {
let sign_position_within_msb = ((bits.len() - 1) % 8) as u8;
let msb_idx = field_data.len() - 1;
let msb = field_data[msb_idx];
if msb & (1 << sign_position_within_msb) != 0 {
if sign_position_within_msb != 7 {
let extended_byte = msb | !((1 << (sign_position_within_msb + 1)) - 1);
field_data[msb_idx] = extended_byte;
}
raw_value_bytes.fill(0xff);
}
adjusted_max = i32::from(max) as i64;
} else {
adjusted_max = u32::from(max) as i64;
}
raw_value_bytes[..field_data.len()].copy_from_slice(field_data.as_slice());
let value = i64::from_le_bytes(raw_value_bytes);
if (value < i32::from(min) as i64) || (value > adjusted_max) {
Err(FieldAccessError::InvalidFieldValue)
} else {
Ok(i64::from_le_bytes(raw_value_bytes))
}
}
fn set_field_value(
bits: &Range<u32>,
min: LogicalMinimum,
max: LogicalMaximum,
data: i64,
buffer: &mut [u8],
) -> Result<(), FieldAccessError> {
if (data < i32::from(min) as i64) || (data > i32::from(max) as i64) {
return Err(FieldAccessError::InvalidFieldValue);
}
set_field_data(bits, &data.to_le_bytes()[0..4], buffer)
}
fn field_range(min: LogicalMinimum, max: LogicalMaximum) -> Option<u32> {
if i32::from(min).is_negative() {
i32::from(max).checked_sub(i32::from(min)).and_then(|f| if f > 0 { Some(f as u32) } else { None })
} else {
u32::from(max).checked_sub(u32::from(min)).and_then(|f| if f > 0 { Some(f) } else { None })
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ReportCollection {
pub usage: Usage,
pub designator: Option<DesignatorIndex>,
pub string: Option<StringIndex>,
pub member_of: Vec<ReportCollection>,
}
#[derive(Debug, Default, Clone, PartialEq, Eq)]
pub struct VariableField {
pub bits: Range<u32>,
pub attributes: ReportAttributes,
pub usage: Usage,
pub logical_minimum: LogicalMinimum,
pub logical_maximum: LogicalMaximum,
pub physical_minimum: Option<PhysicalMinimum>,
pub physical_maximum: Option<PhysicalMaximum>,
pub unit: Option<Unit>,
pub unit_exponent: Option<UnitExponent>,
pub designator_index: Option<DesignatorIndex>,
pub string_index: Option<StringIndex>,
pub member_of: Vec<ReportCollection>,
}
impl VariableField {
pub fn field_data(&self, buffer: &[u8]) -> Option<Vec<u8>> {
field_data(&self.bits, buffer).ok()
}
pub fn set_field_data(&self, data: &[u8], buffer: &mut [u8]) -> Result<(), FieldAccessError> {
set_field_data(&self.bits, data, buffer)
}
pub fn field_value(&self, buffer: &[u8]) -> Option<i64> {
field_value(&self.bits, self.logical_minimum, self.logical_maximum, buffer).ok()
}
pub fn set_field_value(&self, data: i64, buffer: &mut [u8]) -> Result<(), FieldAccessError> {
set_field_value(&self.bits, self.logical_minimum, self.logical_maximum, data, buffer)
}
pub fn field_range(&self) -> Option<u32> {
field_range(self.logical_minimum, self.logical_maximum)
}
}
#[derive(Debug, Default, Clone, PartialEq, Eq)]
pub struct ArrayField {
pub bits: Range<u32>,
pub attributes: ReportAttributes,
pub usage_list: Vec<UsageRange>,
pub logical_minimum: LogicalMinimum,
pub logical_maximum: LogicalMaximum,
pub designator_list: Vec<DesignatorRange>,
pub string_list: Vec<StringRange>,
pub member_of: Vec<ReportCollection>,
}
impl ArrayField {
pub fn field_data(&self, buffer: &[u8]) -> Option<Vec<u8>> {
field_data(&self.bits, buffer).ok()
}
pub fn field_value(&self, buffer: &[u8]) -> Option<i64> {
field_value(&self.bits, self.logical_minimum, self.logical_maximum, buffer).ok()
}
pub fn field_range(&self) -> Option<u32> {
field_range(self.logical_minimum, self.logical_maximum)
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct PaddingField {
pub bits: Range<u32>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum ReportField {
Variable(VariableField),
Array(ArrayField),
Padding(PaddingField),
}
#[derive(Debug, PartialEq, Eq)]
pub struct Report {
pub report_id: Option<ReportId>,
pub size_in_bits: usize,
pub fields: Vec<ReportField>,
}
#[derive(Debug, PartialEq, Eq)]
pub struct ReportDescriptor {
pub input_reports: Vec<Report>,
pub bad_input_reports: Vec<(Option<ReportId>, ReportDescriptorError)>,
pub output_reports: Vec<Report>,
pub bad_output_reports: Vec<(Option<ReportId>, ReportDescriptorError)>,
pub features: Vec<Report>,
pub bad_features: Vec<(Option<ReportId>, ReportDescriptorError)>,
}
pub fn parse_report_descriptor(report_descriptor: &[u8]) -> Result<ReportDescriptor, ReportDescriptorError> {
ReportDescriptorParser::parse(report_descriptor)
}
#[cfg(test)]
mod tests {
extern crate std;
use crate::{
report_data_types::{LogicalMaximum, LogicalMinimum},
ArrayField, FieldAccessError, VariableField,
};
use alloc::vec;
#[test]
fn field_data_should_return_field_data() {
let mut field: VariableField = Default::default();
let buffer: [u8; 10] = [0xaa; 10];
field.bits = 0..8;
assert_eq!(field.field_data(&buffer), Some(vec![0xaa]));
field.bits = 1..5;
assert_eq!(field.field_data(&buffer), Some(vec![0x5]));
field.bits = 3..9;
assert_eq!(field.field_data(&buffer), Some(vec![0x15]));
field.bits = 0..9;
assert_eq!(field.field_data(&buffer), Some(vec![0xaa, 0x00]));
field.bits = 7..21;
assert_eq!(field.field_data(&buffer), Some(vec![0x55, 0x15]));
field.bits = 100..257;
assert_eq!(field.field_data(&buffer), None);
let mut field: ArrayField = Default::default();
let buffer: [u8; 10] = [0x71; 10];
field.bits = 0..8;
assert_eq!(field.field_data(&buffer), Some(vec![0x71]));
field.bits = 1..5;
assert_eq!(field.field_data(&buffer), Some(vec![0x8]));
field.bits = 3..9;
assert_eq!(field.field_data(&buffer), Some(vec![0x2E]));
field.bits = 7..21;
assert_eq!(field.field_data(&buffer), Some(vec![0xE2, 0x22]));
field.bits = 100..257;
assert_eq!(field.field_data(&buffer), None);
}
#[test]
fn set_field_data_should_set_field_data() {
let mut field: VariableField = Default::default();
let mut buffer: [u8; 10] = [0x00; 10];
field.bits = 0..8;
field.set_field_data(&[0xaa], &mut buffer).unwrap();
assert_eq!(buffer[0], 0xaa);
assert_eq!(buffer[1..], [0x0u8; 9]);
let mut buffer: [u8; 10] = [0x00; 10];
field.bits = 4..12;
field.set_field_data(&[0xaa], &mut buffer).unwrap();
assert_eq!(buffer[0..2], [0xa0, 0x0a]);
assert_eq!(buffer[2..], [0x0u8; 8]);
let mut buffer: [u8; 1] = [0x00; 1];
field.bits = 4..12;
assert_eq!(field.set_field_data(&[0xaa], &mut buffer), Err(FieldAccessError::InvalidBufferSize));
}
#[test]
fn field_value_should_return_field_value() {
let mut field: VariableField = Default::default();
field.logical_minimum = LogicalMinimum::from(-127i32);
field.logical_maximum = LogicalMaximum::from(127i32);
field.bits = 0..8;
let buffer = (-1i8).to_le_bytes();
assert_eq!(field.field_value(&buffer), Some(-1i64));
let buffer = (-17i8).to_le_bytes();
assert_eq!(field.field_value(&buffer), Some(-17i64));
let buffer = (127i8).to_le_bytes();
assert_eq!(field.field_value(&buffer), Some(127i64));
field.logical_minimum = LogicalMinimum::from(-1024i32);
field.logical_maximum = LogicalMaximum::from(1024i32);
field.bits = 0..11;
let buffer = (-1i16).to_le_bytes();
assert_eq!(field.field_value(&buffer), Some(-1i64));
let buffer = (-17i16).to_le_bytes();
assert_eq!(field.field_value(&buffer), Some(-17i64));
let buffer = (127i16).to_le_bytes();
assert_eq!(field.field_value(&buffer), Some(127i64));
field.logical_minimum = LogicalMinimum::from(-1024i32);
field.logical_maximum = LogicalMaximum::from(1024i32);
field.bits = 1..12;
let buffer = (-1i16).to_le_bytes();
assert_eq!(field.field_value(&buffer), Some(-1i64));
let buffer = (-18i16).to_le_bytes();
assert_eq!(field.field_value(&buffer), Some(-9i64));
let buffer = (128i16).to_le_bytes();
assert_eq!(field.field_value(&buffer), Some(64i64));
field.logical_minimum = LogicalMinimum::from(-1024i32);
field.logical_maximum = LogicalMaximum::from(1024i32);
field.bits = 0..12;
let buffer = (1025i16).to_le_bytes();
assert_eq!(field.field_value(&buffer), None);
let buffer = (-1025i16).to_le_bytes();
assert_eq!(field.field_value(&buffer), None);
field.logical_minimum = LogicalMinimum::from(0);
field.logical_maximum = LogicalMaximum::from(u32::MAX);
let buffer = (1025i16).to_le_bytes();
assert_eq!(field.field_value(&buffer), Some(1025));
let mut field: ArrayField = Default::default();
field.logical_minimum = LogicalMinimum::from(-127i32);
field.logical_maximum = LogicalMaximum::from(127i32);
field.bits = 0..8;
let buffer = (-1i8).to_le_bytes();
assert_eq!(field.field_value(&buffer), Some(-1i64));
let buffer = (-17i8).to_le_bytes();
assert_eq!(field.field_value(&buffer), Some(-17i64));
let buffer = (127i8).to_le_bytes();
assert_eq!(field.field_value(&buffer), Some(127i64));
field.logical_minimum = LogicalMinimum::from(-1024i32);
field.logical_maximum = LogicalMaximum::from(1024i32);
field.bits = 0..11;
let buffer = (-1i16).to_le_bytes();
assert_eq!(field.field_value(&buffer), Some(-1i64));
let buffer = (-17i16).to_le_bytes();
assert_eq!(field.field_value(&buffer), Some(-17i64));
let buffer = (127i16).to_le_bytes();
assert_eq!(field.field_value(&buffer), Some(127i64));
field.logical_minimum = LogicalMinimum::from(-1024i32);
field.logical_maximum = LogicalMaximum::from(1024i32);
field.bits = 1..12;
let buffer = (-1i16).to_le_bytes();
assert_eq!(field.field_value(&buffer), Some(-1i64));
let buffer = (-18i16).to_le_bytes();
assert_eq!(field.field_value(&buffer), Some(-9i64));
let buffer = (128i16).to_le_bytes();
assert_eq!(field.field_value(&buffer), Some(64i64));
field.logical_minimum = LogicalMinimum::from(-1024i32);
field.logical_maximum = LogicalMaximum::from(1024i32);
field.bits = 0..12;
let buffer = (1025i16).to_le_bytes();
assert_eq!(field.field_value(&buffer), None);
let buffer = (-1025i16).to_le_bytes();
assert_eq!(field.field_value(&buffer), None);
field.logical_minimum = LogicalMinimum::from(0);
field.logical_maximum = LogicalMaximum::from(u32::MAX);
let buffer = (1025i16).to_le_bytes();
assert_eq!(field.field_value(&buffer), Some(1025));
}
#[test]
fn set_field_value_should_set_field_data() {
let mut field: VariableField = Default::default();
field.logical_minimum = LogicalMinimum::from(0i32);
field.logical_maximum = LogicalMaximum::from(0xffi32);
let mut buffer: [u8; 10] = [0x00; 10];
field.bits = 0..8;
field.set_field_value(0xaai64, &mut buffer).unwrap();
assert_eq!(buffer[0], 0xaa);
assert_eq!(buffer[1..], [0x0u8; 9]);
let mut buffer: [u8; 10] = [0x00; 10];
field.bits = 4..12;
field.set_field_value(0xaai64, &mut buffer).unwrap();
assert_eq!(buffer[0..2], [0xa0, 0x0a]);
assert_eq!(buffer[2..], [0x0u8; 8]);
let mut buffer: [u8; 1] = [0x00; 1];
field.bits = 4..12;
assert_eq!(field.set_field_value(0xaa, &mut buffer), Err(FieldAccessError::InvalidBufferSize));
assert_eq!(field.set_field_value(0xaaa, &mut buffer), Err(FieldAccessError::InvalidFieldValue));
}
#[test]
fn field_range_should_return_field_range() {
let mut field: VariableField = Default::default();
field.logical_minimum = LogicalMinimum::from(-127i32);
field.logical_maximum = LogicalMaximum::from(127i32);
assert_eq!(field.field_range(), Some(254u32));
field.logical_minimum = LogicalMinimum::from(-127i32);
field.logical_maximum = LogicalMaximum::from(-120i32);
assert_eq!(field.field_range(), Some(7u32));
field.logical_minimum = LogicalMinimum::from(128i32);
field.logical_maximum = LogicalMaximum::from(384i32);
assert_eq!(field.field_range(), Some(256u32));
field.logical_minimum = LogicalMinimum::from(0i32);
field.logical_maximum = LogicalMaximum::from(u32::MAX);
assert_eq!(field.field_range(), Some(u32::MAX));
field.logical_minimum = LogicalMinimum::from(0i32);
field.logical_maximum = LogicalMaximum::from(0u32);
assert_eq!(field.field_range(), None);
field.logical_minimum = LogicalMinimum::from(-127i32);
field.logical_maximum = LogicalMaximum::from(-127i32);
assert_eq!(field.field_range(), None);
field.logical_minimum = LogicalMinimum::from(-1i32);
field.logical_maximum = LogicalMaximum::from(-127i32);
assert_eq!(field.field_range(), None);
field.logical_minimum = LogicalMinimum::from(i32::MAX);
field.logical_maximum = LogicalMaximum::from(0);
assert_eq!(field.field_range(), None);
field.logical_minimum = LogicalMinimum::from(i32::MIN + 1);
field.logical_maximum = LogicalMaximum::from(0);
assert_eq!(field.field_range(), Some(i32::MAX as u32));
let mut field: ArrayField = Default::default();
field.logical_minimum = LogicalMinimum::from(-127i32);
field.logical_maximum = LogicalMaximum::from(127i32);
assert_eq!(field.field_range(), Some(254u32));
field.logical_minimum = LogicalMinimum::from(-127i32);
field.logical_maximum = LogicalMaximum::from(-120i32);
assert_eq!(field.field_range(), Some(7u32));
field.logical_minimum = LogicalMinimum::from(128i32);
field.logical_maximum = LogicalMaximum::from(384i32);
assert_eq!(field.field_range(), Some(256u32));
field.logical_minimum = LogicalMinimum::from(0i32);
field.logical_maximum = LogicalMaximum::from(u32::MAX);
assert_eq!(field.field_range(), Some(u32::MAX));
field.logical_minimum = LogicalMinimum::from(0i32);
field.logical_maximum = LogicalMaximum::from(0u32);
assert_eq!(field.field_range(), None);
field.logical_minimum = LogicalMinimum::from(-127i32);
field.logical_maximum = LogicalMaximum::from(-127i32);
assert_eq!(field.field_range(), None);
field.logical_minimum = LogicalMinimum::from(-1i32);
field.logical_maximum = LogicalMaximum::from(-127i32);
assert_eq!(field.field_range(), None);
field.logical_minimum = LogicalMinimum::from(i32::MAX);
field.logical_maximum = LogicalMaximum::from(0);
assert_eq!(field.field_range(), None);
field.logical_minimum = LogicalMinimum::from(i32::MIN + 1);
field.logical_maximum = LogicalMaximum::from(0);
assert_eq!(field.field_range(), Some(i32::MAX as u32));
}
}