firewire_motu_protocols/config_rom.rs
1// SPDX-License-Identifier: LGPL-3.0-or-later
2// Copyright (c) 2021 Takashi Sakamoto
3
4//! Parser for Configuration ROM.
5//!
6//! The module includes structure, enumeration, and trait and its implementaion to parse
7//! configuration ROM according to specification defined by Mark of the Unicorn.
8
9use ieee1212_config_rom::*;
10
11/// Data in unit directory of Configuration ROM.
12#[derive(Default, Debug, Clone, Copy)]
13pub struct UnitData {
14 pub model_id: u32,
15 pub version: u32,
16}
17
18const OUI_MOTU: u32 = 0x0001f2;
19
20/// The trait for parser of configuration ROM.
21pub trait MotuConfigRom {
22 fn get_unit_data(&self) -> Option<UnitData>;
23}
24
25impl<'a> MotuConfigRom for ConfigRom<'a> {
26 fn get_unit_data(&self) -> Option<UnitData> {
27 self.root
28 .iter()
29 .find_map(|entry| {
30 EntryDataAccess::<u32>::get(entry, KeyType::Vendor).and_then(|vendor_id| {
31 if vendor_id == OUI_MOTU {
32 Some(vendor_id)
33 } else {
34 None
35 }
36 })
37 })
38 .and_then(|_| {
39 self.root
40 .iter()
41 .find_map(|entry| EntryDataAccess::<&[Entry]>::get(entry, KeyType::Unit))
42 .and_then(|entries| {
43 entries
44 .iter()
45 .find_map(|entry| {
46 EntryDataAccess::<u32>::get(entry, KeyType::SpecifierId).and_then(
47 |specifier_id| {
48 if specifier_id == OUI_MOTU {
49 Some(specifier_id)
50 } else {
51 None
52 }
53 },
54 )
55 })
56 .and_then(|_| {
57 // NOTE: It's odd but version field is used for model ID and model field is
58 // used for version in MOTU case.
59 entries
60 .iter()
61 .find_map(|entry| {
62 EntryDataAccess::<u32>::get(entry, KeyType::Version)
63 })
64 .and_then(|model_id| {
65 entries
66 .iter()
67 .find_map(|entry| {
68 EntryDataAccess::<u32>::get(entry, KeyType::Model)
69 })
70 .map(|version| UnitData { model_id, version })
71 })
72 })
73 })
74 })
75 }
76}