firewire_dice_protocols/tcat/extension/
router_entry.rs

1// SPDX-License-Identifier: LGPL-3.0-or-later
2// Copyright (c) 2020 Takashi Sakamoto
3
4use super::*;
5
6impl DstBlk {
7    const ID_MASK: u8 = 0xf0;
8    const ID_SHIFT: usize = 4;
9    const CH_MASK: u8 = 0x0f;
10    const CH_SHIFT: usize = 0;
11
12    const AES_VALUE: u8 = 0;
13    const ADAT_VALUE: u8 = 1;
14    const MIXER_TX0_VALUE: u8 = 2;
15    const MIXER_TX1_VALUE: u8 = 3;
16    const INS0_VALUE: u8 = 4;
17    const INS1_VALUE: u8 = 5;
18    const ARM_APB_AUDIO_VALUE: u8 = 10;
19    const AVS0_VALUE: u8 = 11;
20    const AVS1_VALUE: u8 = 12;
21}
22
23fn serialize_dst_blk(dst: &DstBlk, val: &mut u8) -> Result<(), String> {
24    let id = match dst.id {
25        DstBlkId::Aes => DstBlk::AES_VALUE,
26        DstBlkId::Adat => DstBlk::ADAT_VALUE,
27        DstBlkId::MixerTx0 => DstBlk::MIXER_TX0_VALUE,
28        DstBlkId::MixerTx1 => DstBlk::MIXER_TX1_VALUE,
29        DstBlkId::Ins0 => DstBlk::INS0_VALUE,
30        DstBlkId::Ins1 => DstBlk::INS1_VALUE,
31        DstBlkId::ArmApbAudio => DstBlk::ARM_APB_AUDIO_VALUE,
32        DstBlkId::Avs0 => DstBlk::AVS0_VALUE,
33        DstBlkId::Avs1 => DstBlk::AVS1_VALUE,
34        DstBlkId::Reserved(id) => id,
35    };
36
37    let ch = dst.ch;
38
39    *val =
40        ((id << DstBlk::ID_SHIFT) & DstBlk::ID_MASK) | ((ch << DstBlk::CH_SHIFT) & DstBlk::CH_MASK);
41
42    Ok(())
43}
44
45fn deserialize_dst_blk(dst: &mut DstBlk, val: &u8) -> Result<(), String> {
46    let id = (*val & DstBlk::ID_MASK) >> DstBlk::ID_SHIFT;
47    dst.id = match id {
48        DstBlk::AES_VALUE => DstBlkId::Aes,
49        DstBlk::ADAT_VALUE => DstBlkId::Adat,
50        DstBlk::MIXER_TX0_VALUE => DstBlkId::MixerTx0,
51        DstBlk::MIXER_TX1_VALUE => DstBlkId::MixerTx1,
52        DstBlk::INS0_VALUE => DstBlkId::Ins0,
53        DstBlk::INS1_VALUE => DstBlkId::Ins1,
54        DstBlk::ARM_APB_AUDIO_VALUE => DstBlkId::ArmApbAudio,
55        DstBlk::AVS0_VALUE => DstBlkId::Avs0,
56        DstBlk::AVS1_VALUE => DstBlkId::Avs1,
57        _ => DstBlkId::Reserved(id),
58    };
59
60    dst.ch = (*val & DstBlk::CH_MASK) >> DstBlk::CH_SHIFT;
61
62    Ok(())
63}
64
65impl Ord for DstBlk {
66    fn cmp(&self, other: &Self) -> Ordering {
67        let mut lval = 0u8;
68        serialize_dst_blk(self, &mut lval).unwrap();
69
70        let mut rval = 0u8;
71        serialize_dst_blk(other, &mut rval).unwrap();
72
73        lval.cmp(&rval)
74    }
75}
76
77impl PartialOrd for DstBlk {
78    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
79        Some(self.cmp(other))
80    }
81}
82
83impl SrcBlk {
84    const ID_MASK: u8 = 0xf0;
85    const ID_SHIFT: usize = 4;
86    const CH_MASK: u8 = 0x0f;
87    const CH_SHIFT: usize = 0;
88
89    const AES_VALUE: u8 = 0;
90    const ADAT_VALUE: u8 = 1;
91    const MIXER_VALUE: u8 = 2;
92    const INS0_VALUE: u8 = 4;
93    const INS1_VALUE: u8 = 5;
94    const ARMAPRAUDIO_VALUE: u8 = 10;
95    const AVS0_VALUE: u8 = 11;
96    const AVS1_VALUE: u8 = 12;
97    const MUTE_VALUE: u8 = 15;
98}
99
100fn serialize_src_blk(src: &SrcBlk, val: &mut u8) -> Result<(), String> {
101    let id = match src.id {
102        SrcBlkId::Aes => SrcBlk::AES_VALUE,
103        SrcBlkId::Adat => SrcBlk::ADAT_VALUE,
104        SrcBlkId::Mixer => SrcBlk::MIXER_VALUE,
105        SrcBlkId::Ins0 => SrcBlk::INS0_VALUE,
106        SrcBlkId::Ins1 => SrcBlk::INS1_VALUE,
107        SrcBlkId::ArmAprAudio => SrcBlk::ARMAPRAUDIO_VALUE,
108        SrcBlkId::Avs0 => SrcBlk::AVS0_VALUE,
109        SrcBlkId::Avs1 => SrcBlk::AVS1_VALUE,
110        SrcBlkId::Mute => SrcBlk::MUTE_VALUE,
111        SrcBlkId::Reserved(id) => id,
112    };
113
114    let ch = src.ch;
115
116    *val =
117        ((id << SrcBlk::ID_SHIFT) & SrcBlk::ID_MASK) | ((ch << SrcBlk::CH_SHIFT) & SrcBlk::CH_MASK);
118
119    Ok(())
120}
121
122fn deserialize_src_blk(src: &mut SrcBlk, val: &u8) -> Result<(), String> {
123    let id = (*val & SrcBlk::ID_MASK) >> SrcBlk::ID_SHIFT;
124    src.id = match id {
125        SrcBlk::AES_VALUE => SrcBlkId::Aes,
126        SrcBlk::ADAT_VALUE => SrcBlkId::Adat,
127        SrcBlk::MIXER_VALUE => SrcBlkId::Mixer,
128        SrcBlk::INS0_VALUE => SrcBlkId::Ins0,
129        SrcBlk::INS1_VALUE => SrcBlkId::Ins1,
130        SrcBlk::ARMAPRAUDIO_VALUE => SrcBlkId::ArmAprAudio,
131        SrcBlk::AVS0_VALUE => SrcBlkId::Avs0,
132        SrcBlk::AVS1_VALUE => SrcBlkId::Avs1,
133        SrcBlk::MUTE_VALUE => SrcBlkId::Mute,
134        _ => SrcBlkId::Reserved(id),
135    };
136
137    src.ch = (*val & SrcBlk::CH_MASK) >> SrcBlk::CH_SHIFT;
138
139    Ok(())
140}
141
142impl Ord for SrcBlk {
143    fn cmp(&self, other: &Self) -> Ordering {
144        let mut lval = 0u8;
145        serialize_src_blk(self, &mut lval).unwrap();
146
147        let mut rval = 0u8;
148        serialize_src_blk(other, &mut rval).unwrap();
149
150        lval.cmp(&rval)
151    }
152}
153
154impl PartialOrd for SrcBlk {
155    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
156        Some(self.cmp(other))
157    }
158}
159
160impl RouterEntry {
161    const SIZE: usize = 4;
162
163    const DST_MASK: u32 = 0x000000ff;
164    const DST_SHIFT: usize = 0;
165
166    const SRC_MASK: u32 = 0x0000ff00;
167    const SRC_SHIFT: usize = 8;
168
169    const PEAK_MASK: u32 = 0xffff0000;
170    const PEAK_SHIFT: usize = 16;
171}
172
173pub(crate) fn serialize_router_entry(entry: &RouterEntry, raw: &mut [u8]) -> Result<(), String> {
174    assert!(raw.len() >= RouterEntry::SIZE);
175
176    let mut dst_val = 0u8;
177    serialize_dst_blk(&entry.dst, &mut dst_val)?;
178
179    let mut src_val = 0u8;
180    serialize_src_blk(&entry.src, &mut src_val)?;
181
182    let val = (((entry.peak as u32) << RouterEntry::PEAK_SHIFT) & RouterEntry::PEAK_MASK)
183        | (((src_val as u32) << RouterEntry::SRC_SHIFT) & RouterEntry::SRC_MASK)
184        | (((dst_val as u32) << RouterEntry::DST_SHIFT) & RouterEntry::DST_MASK);
185    serialize_u32(&val, raw);
186
187    Ok(())
188}
189
190pub(crate) fn deserialize_router_entry(entry: &mut RouterEntry, raw: &[u8]) -> Result<(), String> {
191    assert!(raw.len() >= RouterEntry::SIZE);
192
193    let mut val = 0u32;
194    deserialize_u32(&mut val, &raw);
195
196    let dst_val = ((val & RouterEntry::DST_MASK) >> RouterEntry::DST_SHIFT) as u8;
197    deserialize_dst_blk(&mut entry.dst, &dst_val)?;
198
199    let src_val = ((val & RouterEntry::SRC_MASK) >> RouterEntry::SRC_SHIFT) as u8;
200    deserialize_src_blk(&mut entry.src, &src_val)?;
201
202    entry.peak = ((val & RouterEntry::PEAK_MASK) >> RouterEntry::PEAK_SHIFT) as u16;
203
204    Ok(())
205}
206
207pub(crate) fn calculate_router_entries_size(entry_count: usize) -> usize {
208    entry_count * RouterEntry::SIZE
209}
210
211pub(crate) fn serialize_router_entries(
212    entries: &[RouterEntry],
213    raw: &mut [u8],
214) -> Result<(), String> {
215    assert!(raw.len() >= calculate_router_entries_size(entries.len()));
216
217    entries.iter().enumerate().try_for_each(|(i, entry)| {
218        let pos = i * RouterEntry::SIZE;
219        serialize_router_entry(entry, &mut raw[pos..(pos + RouterEntry::SIZE)])
220    })
221}
222
223pub(crate) fn deserialize_router_entries(
224    entries: &mut [RouterEntry],
225    raw: &[u8],
226) -> Result<(), String> {
227    assert!(raw.len() >= calculate_router_entries_size(entries.len()));
228
229    entries.iter_mut().enumerate().try_for_each(|(i, entry)| {
230        let pos = i * RouterEntry::SIZE;
231        deserialize_router_entry(entry, &raw[pos..(pos + RouterEntry::SIZE)])
232    })
233}
234
235#[cfg(test)]
236mod test {
237    use super::*;
238
239    #[test]
240    fn dst_blk_serdes() {
241        let params = DstBlk {
242            id: DstBlkId::Ins1,
243            ch: 10,
244        };
245        let mut val = 0;
246        serialize_dst_blk(&params, &mut val).unwrap();
247
248        let mut p = DstBlk::default();
249        deserialize_dst_blk(&mut p, &val).unwrap();
250
251        assert_eq!(params, p);
252    }
253
254    #[test]
255    fn src_blk_serdes() {
256        let params = SrcBlk {
257            id: SrcBlkId::Ins1,
258            ch: 10,
259        };
260        let mut val = 0;
261        serialize_src_blk(&params, &mut val).unwrap();
262
263        let mut p = SrcBlk::default();
264        deserialize_src_blk(&mut p, &val).unwrap();
265
266        assert_eq!(params, p);
267    }
268}