firewire_dice_protocols/tcat/
tx_stream_format_section.rs

1// SPDX-License-Identifier: LGPL-3.0-or-later
2// Copyright (c) 2020 Takashi Sakamoto
3
4//! Tx Stream format section in general protocol for ASICs of DICE.
5//!
6//! The module includes structure, enumeration, and trait and its implementation for Tx stream
7//! format section in general protocol defined by TCAT for ASICs of DICE.
8use super::*;
9
10/// Entry for stream format in stream transmitted by the node.
11#[derive(Default, Debug, Clone, PartialEq, Eq)]
12pub struct TxStreamFormatEntry {
13    /// The channel number for isochronous packet stream.
14    pub iso_channel: i8,
15    /// The number of PCM channels.
16    pub pcm: u32,
17    /// The number of MIDI ports.
18    pub midi: u32,
19    /// The code to express transferring speed defined in IEEE 1394 specification.
20    pub speed: u32,
21    /// The list of names for data channel.
22    pub labels: Vec<String>,
23    /// The mode for each channel of IEC 60958.
24    pub iec60958: [Iec60958Param; IEC60958_CHANNELS],
25}
26
27const MIN_SIZE: usize = 272;
28
29fn serialize_tx_stream_entry(entry: &TxStreamFormatEntry, raw: &mut [u8]) -> Result<(), String> {
30    assert!(raw.len() >= MIN_SIZE);
31
32    serialize_i32(&(entry.iso_channel as i32), &mut raw[..4]);
33
34    serialize_u32(&entry.pcm, &mut raw[4..8]);
35    serialize_u32(&entry.midi, &mut raw[8..12]);
36    serialize_u32(&entry.speed, &mut raw[12..16]);
37
38    serialize_labels(&entry.labels, &mut raw[16..272])?;
39
40    // NOTE: it's not supported by old version of firmware.
41    if raw.len() >= 272 {
42        serialize_iec60958_params(&entry.iec60958, &mut raw[272..280])?;
43    }
44
45    Ok(())
46}
47
48fn deserialize_tx_stream_entry(entry: &mut TxStreamFormatEntry, raw: &[u8]) -> Result<(), String> {
49    assert!(raw.len() >= MIN_SIZE);
50
51    let mut val = 0i32;
52    deserialize_i32(&mut val, &raw[..4]);
53    entry.iso_channel = val as i8;
54
55    deserialize_u32(&mut entry.pcm, &raw[4..8]);
56    deserialize_u32(&mut entry.midi, &raw[8..12]);
57    deserialize_u32(&mut entry.speed, &raw[12..16]);
58
59    deserialize_labels(&mut entry.labels, &raw[16..272])?;
60
61    // NOTE: it's not supported by old version of firmware.
62    if raw.len() >= MIN_SIZE {
63        deserialize_iec60958_params(&mut entry.iec60958, &raw[272..280])?;
64    }
65
66    Ok(())
67}
68
69/// Parameters for format of transmit streams.
70#[derive(Default, Debug, Clone, PartialEq, Eq)]
71pub struct TxStreamFormatParameters(pub Vec<TxStreamFormatEntry>);
72
73impl<O: TcatOperation> TcatSectionSerdes<TxStreamFormatParameters> for O {
74    const MIN_SIZE: usize = 8;
75
76    const ERROR_TYPE: GeneralProtocolError = GeneralProtocolError::TxStreamFormat;
77
78    fn serialize(params: &TxStreamFormatParameters, raw: &mut [u8]) -> Result<(), String> {
79        let mut val = 0u32;
80
81        // The number of streams is read-only.
82        deserialize_u32(&mut val, &raw[..4]);
83        let count = val as usize;
84
85        if count != params.0.len() {
86            Err(format!(
87                "The count of entries should be {}, actually {}",
88                count,
89                params.0.len(),
90            ))?;
91        }
92
93        // The size of stream format entry is read-only as well.
94        deserialize_u32(&mut val, &raw[4..8]);
95        let size = 4 * val as usize;
96
97        let expected = 8 + size * count;
98        if raw.len() < expected {
99            let msg = format!(
100                "The size of buffer should be greater than {}, actually {}",
101                expected,
102                raw.len()
103            );
104            Err(msg)?;
105        }
106
107        params.0.iter().enumerate().try_for_each(|(i, entry)| {
108            let pos = 8 + size * i;
109            serialize_tx_stream_entry(entry, &mut raw[pos..(pos + size)])
110        })
111    }
112
113    fn deserialize(params: &mut TxStreamFormatParameters, raw: &[u8]) -> Result<(), String> {
114        let mut val = 0u32;
115        deserialize_u32(&mut val, &raw[..4]);
116        let count = val as usize;
117
118        deserialize_u32(&mut val, &raw[4..8]);
119        let size = 4 * val as usize;
120
121        let expected = 8 + size * count;
122        if raw.len() < expected {
123            let msg = format!(
124                "The size of buffer should be greater than {}, actually {}",
125                expected,
126                raw.len()
127            );
128            Err(msg)?;
129        }
130
131        params.0.resize_with(count, Default::default);
132
133        params.0.iter_mut().enumerate().try_for_each(|(i, entry)| {
134            let pos = 8 + size * i;
135            deserialize_tx_stream_entry(entry, &raw[pos..(pos + size)])
136        })
137    }
138}
139
140impl<O: TcatOperation> TcatSectionOperation<TxStreamFormatParameters> for O {}
141
142impl<O: TcatSectionOperation<TxStreamFormatParameters>>
143    TcatMutableSectionOperation<TxStreamFormatParameters> for O
144{
145}
146
147impl<O: TcatSectionOperation<TxStreamFormatParameters>>
148    TcatNotifiedSectionOperation<TxStreamFormatParameters> for O
149{
150    const NOTIFY_FLAG: u32 = NOTIFY_TX_CFG_CHG;
151}
152
153#[cfg(test)]
154mod test {
155    use super::*;
156
157    #[test]
158    fn tx_stream_format_params_serdes() {
159        let params = TxStreamFormatEntry {
160            iso_channel: 32,
161            pcm: 4,
162            midi: 2,
163            speed: 4,
164            labels: vec![
165                "a".to_string(),
166                "b".to_string(),
167                "c".to_string(),
168                "d".to_string(),
169            ],
170            iec60958: [Iec60958Param {
171                cap: true,
172                enable: false,
173            }; IEC60958_CHANNELS],
174        };
175        let mut raw = [0u8; 2048];
176        serialize_tx_stream_entry(&params, &mut raw).unwrap();
177
178        let mut p = TxStreamFormatEntry::default();
179        deserialize_tx_stream_entry(&mut p, &raw).unwrap();
180
181        assert_eq!(params, p);
182    }
183}