#rom #configuration #ieee #parser #data #configuration-rom #ieee1212

bin+lib ieee1212-config-rom

解析 IEEE 1212 中定义的配置 ROM 内容的解析器

1 个不稳定版本

0.1.2 2022年7月28日
0.1.1 2022年7月27日
0.1.0 2022年7月24日
0.0.90 2022年7月24日

解析器实现 中排名 1187

Download history 35/week @ 2024-03-11 31/week @ 2024-03-18 52/week @ 2024-03-25 58/week @ 2024-04-01 37/week @ 2024-04-08 22/week @ 2024-04-15 30/week @ 2024-04-22 30/week @ 2024-04-29 32/week @ 2024-05-06 27/week @ 2024-05-13 34/week @ 2024-05-20 18/week @ 2024-05-27 23/week @ 2024-06-03 22/week @ 2024-06-10 37/week @ 2024-06-17 29/week @ 2024-06-24

每月下载量 112
10crates 中使用 (直接使用 5 个)

使用 MIT 许可证

39KB
803

该 crate 包含用于处理 IEEE 1212 中配置 ROM 内容的结构体、枚举、特性和其实例。

结构体和枚举

ConfigRom 结构体代表配置 ROM 的结构化数据。该结构体实现了 std::convert::TryFrom<&[u8]> 来解析配置 ROM 的原始数据。`ConfigRom` 结构体的生命周期与原始数据相同,以节省字符串的内存消耗。

ConfigRom 结构体的 root 成员是一个 Entry 结构体的向量,代表目录条目。在 Entry 结构体中,key 成员以 KeyType 类型表示键的类型,而 data 成员以 EntryData 类型表示以调度条目中的四种类型的数据。

In IEEE 1212,叶条目的文本描述符包括字符串信息。`DescriptorLeaf` 结构体用于解析描述符。

为了方便,提供了 `EntryDataAccess` 特性,可以通过键访问每个条目中的多种类型的数据。

用法

将以下行添加到您的 Cargo.toml 文件中

[dependencies]
ieee1212-config-rom = "0.1"

ConfigRom 结构体是开始使用该 crate 的好方法。

use ieee1212_config_rom::*;
use std::convert::TryFrom;

// Prepare raw data of Configuration ROM as array with u8 elements aligned to big endian.
let raw = [
    0x04, 0x04, 0x02, 0x91, 0x31, 0x33, 0x39, 0x34,
    0xf0, 0x00, 0xb2, 0x73, 0x08, 0x00, 0x28, 0x51,
    0x01, 0x00, 0x01, 0x4a, 0x00, 0x06, 0xa2, 0xd2,
    0x0c, 0x00, 0x83, 0xc0, 0x03, 0x00, 0x1f, 0x11,
    0x81, 0x00, 0x00, 0x04, 0x17, 0x02, 0x39, 0x01,
    0x81, 0x00, 0x00, 0x09, 0xd1, 0x00, 0x00, 0x0c,
    0x00, 0x06, 0x4c, 0xb7, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x4c, 0x69, 0x6e, 0x75,
    0x78, 0x20, 0x46, 0x69, 0x72, 0x65, 0x77, 0x69,
    0x72, 0x65, 0x00, 0x00, 0x00, 0x03, 0xff, 0x1c,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x4a, 0x75, 0x6a, 0x75, 0x00, 0x04, 0x66, 0xd5,
    0x12, 0x00, 0xa0, 0x2d, 0x13, 0x01, 0x00, 0x01,
    0x17, 0x02, 0x39, 0x03, 0x81, 0x00, 0x00, 0x01,
    0x00, 0x05, 0x40, 0x09, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x4c, 0x69, 0x6e, 0x75,
    0x78, 0x20, 0x41, 0x4c, 0x53, 0x41, 0x00, 0x00,
];

let config_rom = ConfigRom::try_from(&raw[..]).unwrap();

let expected = ConfigRom {
    bus_info: &raw[4..20],
    root: vec![
        Entry {
            key: KeyType::NodeCapabilities,
            data: EntryData::Immediate(0x0083c0),
        },
        Entry {
            key: KeyType::Vendor,
            data: EntryData::Immediate(0x001f11),
        },
        Entry {
            key: KeyType::Descriptor,
            data: EntryData::Leaf(&raw[52..76]),
        },
        Entry {
            key: KeyType::Model,
            data: EntryData::Immediate(0x023901),
        },
        Entry {
            key: KeyType::Descriptor,
            data: EntryData::Leaf(&raw[80..92]),
        },
        Entry {
            key: KeyType::Unit,
            data: EntryData::Directory(vec![
                Entry {
                    key: KeyType::SpecifierId,
                    data: EntryData::Immediate(0x00a02d),
                },
                Entry {
                    key: KeyType::Version,
                    data: EntryData::Immediate(0x010001),
                },
                Entry {
                    key: KeyType::Model,
                    data: EntryData::Immediate(0x023903),
                },
                Entry {
                    key: KeyType::Descriptor,
                    data: EntryData::Leaf(&raw[116..136]),
                },
            ]),
        },
    ],
};

assert_eq!(expected, config_rom);

// Without implementation of accessor trait.
let desc = DescriptorLeaf::try_from(&config_rom.root[2]).unwrap();
if let DescriptorData::Textual(d) = desc.data {
    assert_eq!("Linux Firewire", d.text);
} else {
    unreachable!();
}

// With implementation of accessor trait.
let model_id: u32 = config_rom.root[3].get(KeyType::Model).unwrap();
assert_eq!(0x023901, model_id);

let model_name: &str = config_rom.root[4].get(KeyType::Descriptor).unwrap();
assert_eq!("Juju", model_name);

let unit_entries: &[Entry] = config_rom.root[5].get(KeyType::Unit).unwrap();
let unit_model_name: &str = unit_entries[3].get(KeyType::Descriptor).unwrap();
assert_eq!("Linux ALSA", unit_model_name);

工具

一些程序位于 src/bin 目录下。

config-rom-parser.rs

此程序从 stdin 解析配置 ROM 的原始数据,或作为命令行参数的映像文件。

如果没有命令行参数,则打印帮助信息并退出。

$ cargo run --bin config-rom-parser
Usage:
  config-rom-parser FILENAME | "-"

  where:
    FILENAME:       the name of file including the image of configuration ROM.
    "-":            the content of configuration ROM comes from STDIN.

  In both cases, the content of configuration ROM should be aligned to big endian.

对于文件中的配置 ROM 数据

$ cargo run --bin config-rom-parser -- /sys/bus/firewire/devices/fw0/config_rom

对于 stdin 中的配置 ROM 数据

$ cat /sys/bus/firewire/devices/fw0/config_rom  | cargo run --bin config-rom-parser -- -

在两种情况下,需要解析的内容应按照大端序排列。

许可证

ieee1212-config-rom crate 采用 MIT 许可证 发布。

支持

如果发现问题,请将其提交至 https://github.com/alsa-project/snd-firewire-ctl-services/

无运行时依赖