1use 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
74macro_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
85fn 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 .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
113trait TwosComplement<To> {
116 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#[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 pub fn input_reports(&self) -> &[impl Report] {
209 &self.input_reports
210 }
211
212 pub fn output_reports(&self) -> &[impl Report] {
224 &self.output_reports
225 }
226
227 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 match first.report_id() {
247 None => Some(first),
248 Some(_) => list.iter().find(|r| r.report_id() == &rid),
249 }
250 }
251
252 pub fn find_input_report(&self, bytes: &[u8]) -> Option<&impl Report> {
268 self.find_report(&self.input_reports, bytes[0])
269 }
270
271 pub fn find_output_report(&self, bytes: &[u8]) -> Option<&impl Report> {
287 self.find_report(&self.input_reports, bytes[0])
288 }
289
290 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 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 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
335pub trait Report {
353 fn report_id(&self) -> &Option<ReportId>;
355
356 fn fields(&self) -> &[Field];
361
362 fn size_in_bits(&self) -> usize;
364
365 fn size_in_bytes(&self) -> usize {
371 (self.size_in_bits() + 7) / 8
372 }
373}
374
375#[derive(Debug)]
389struct RDescReport {
390 id: Option<ReportId>,
392 size: usize,
394 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 fn size_in_bits(&self) -> usize {
409 self.size
410 }
411}
412
413#[derive(Clone, Copy, Debug, PartialEq)]
426pub struct Usage {
427 pub usage_page: UsagePage,
428 pub usage_id: UsageId,
429}
430
431impl Usage {
432 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#[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#[derive(Clone, Copy, Debug)]
523pub struct FieldValue {
524 is_signed: bool,
525 value: u32,
526}
527
528impl FieldValue {
529 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#[derive(Clone, Debug)]
607pub enum Field {
608 Variable(VariableField),
610 Array(ArrayField),
612 Constant(ConstantField),
614}
615
616impl Field {
617 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 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 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 fn len(&self) -> usize {
659 return self.bits().len();
660 }
661
662 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#[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 pub fn is_signed(&self) -> bool {
693 self.logical_minimum < LogicalMinimum(0)
694 }
695
696 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#[derive(Debug)]
733pub struct UsageRange {
734 usage_page: UsagePage,
735 minimum: UsageMinimum,
736 maximum: UsageMaximum,
737}
738
739impl UsageRange {
740 pub fn minimum(&self) -> UsageMinimum {
744 self.minimum
745 }
746
747 pub fn maximum(&self) -> UsageMaximum {
751 self.maximum
752 }
753
754 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 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#[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 pub fn usages(&self) -> &[Usage] {
815 &self.usages
816 }
817
818 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 pub fn is_signed(&self) -> bool {
833 self.logical_minimum < LogicalMinimum(0)
834 }
835
836 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 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#[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#[derive(Clone, Debug, PartialEq, Hash, PartialOrd)]
937pub struct CollectionId(u32);
938
939#[derive(Clone, Debug)]
958pub struct Collection {
959 id: CollectionId,
960 collection_type: CollectionType,
961 usages: Vec<Usage>,
962}
963
964impl Collection {
965 pub fn id(&self) -> &CollectionId {
967 &self.id
968 }
969 pub fn collection_type(&self) -> CollectionType {
971 self.collection_type
972 }
973
974 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#[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 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 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 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 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 LocalUsage {
1154 usage_page: Some(up),
1155 usage_id,
1156 } => Usage {
1157 usage_page: *up,
1158 usage_id: *usage_id,
1159 },
1160 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 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 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 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 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 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 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 if !fields.is_empty() {
1360 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 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 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 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}