1#![doc = include_str!("../README.md")]
5
6use ta1394_avc_general::*;
7
8#[derive(Copy, Clone, Debug, Eq, PartialEq)]
10pub enum SignalUnitAddr {
11 Isoc(
13 u8,
15 ),
16 Ext(
18 u8,
20 ),
21}
22
23impl Default for SignalUnitAddr {
24 fn default() -> Self {
25 Self::Isoc(Self::PLUG_ID_MASK)
26 }
27}
28
29impl SignalUnitAddr {
30 const EXT_PLUG_FLAG: u8 = 0x80;
31 const PLUG_ID_MASK: u8 = 0x7f;
32
33 const LENGTH: usize = 2;
34
35 fn from_raw(raw: &[u8]) -> Result<Self, AvcRespParseError> {
36 if raw.len() < Self::LENGTH {
37 Err(AvcRespParseError::TooShortResp(Self::LENGTH))?;
38 }
39
40 let plug_id = raw[1] & Self::PLUG_ID_MASK;
41 let plug = if raw[1] & Self::EXT_PLUG_FLAG > 0 {
42 Self::Ext(plug_id)
43 } else {
44 Self::Isoc(plug_id)
45 };
46 Ok(plug)
47 }
48
49 fn to_raw(&self) -> [u8; Self::LENGTH] {
50 let mut raw = [0; Self::LENGTH];
51 raw[0] = AvcAddr::UNIT_ADDR;
52 raw[1] = match self {
53 SignalUnitAddr::Isoc(val) => *val,
54 SignalUnitAddr::Ext(val) => SignalUnitAddr::EXT_PLUG_FLAG | *val,
55 };
56 raw
57 }
58}
59
60#[derive(Copy, Clone, Debug, Eq, PartialEq)]
62pub struct SignalSubunitAddr {
63 pub subunit: AvcAddrSubunit,
65 pub plug_id: u8,
67}
68
69impl Default for SignalSubunitAddr {
70 fn default() -> Self {
71 Self {
72 subunit: Default::default(),
73 plug_id: 0xff,
74 }
75 }
76}
77
78impl SignalSubunitAddr {
79 const LENGTH: usize = 2;
80
81 fn from_raw(raw: &[u8]) -> Result<Self, AvcRespParseError> {
82 if raw.len() < Self::LENGTH {
83 Err(AvcRespParseError::TooShortResp(Self::LENGTH))?;
84 }
85
86 let subunit = AvcAddrSubunit::from(raw[0]);
87 let plug_id = raw[1];
88 Ok(SignalSubunitAddr { subunit, plug_id })
89 }
90
91 fn to_raw(&self) -> [u8; Self::LENGTH] {
92 let mut raw = [0; Self::LENGTH];
93 raw[0] = u8::from(self.subunit);
94 raw[1] = self.plug_id;
95 raw
96 }
97}
98
99#[derive(Copy, Clone, Debug, Eq, PartialEq)]
101pub enum SignalAddr {
102 Unit(SignalUnitAddr),
103 Subunit(SignalSubunitAddr),
104}
105
106impl Default for SignalAddr {
107 fn default() -> Self {
108 Self::Unit(Default::default())
109 }
110}
111
112impl SignalAddr {
113 const LENGTH: usize = 2;
114
115 pub fn new_for_isoc_unit(plug_id: u8) -> Self {
116 SignalAddr::Unit(SignalUnitAddr::Isoc(plug_id & SignalUnitAddr::PLUG_ID_MASK))
117 }
118
119 pub fn new_for_ext_unit(plug_id: u8) -> Self {
120 SignalAddr::Unit(SignalUnitAddr::Ext(plug_id & SignalUnitAddr::PLUG_ID_MASK))
121 }
122
123 pub fn new_for_subunit(subunit_type: AvcSubunitType, subunit_id: u8, plug_id: u8) -> Self {
124 SignalAddr::Subunit(SignalSubunitAddr {
125 subunit: AvcAddrSubunit {
126 subunit_type,
127 subunit_id,
128 },
129 plug_id,
130 })
131 }
132
133 fn from_raw(raw: &[u8]) -> Result<Self, AvcRespParseError> {
134 if raw.len() < Self::LENGTH {
135 Err(AvcRespParseError::TooShortResp(Self::LENGTH))?;
136 }
137
138 let addr = if raw[0] == AvcAddr::UNIT_ADDR {
139 let data = SignalUnitAddr::from_raw(&raw)?;
140 SignalAddr::Unit(data)
141 } else {
142 let data = SignalSubunitAddr::from_raw(&raw)?;
143 SignalAddr::Subunit(data)
144 };
145
146 Ok(addr)
147 }
148
149 fn to_raw(&self) -> [u8; Self::LENGTH] {
150 match self {
151 SignalAddr::Unit(a) => a.to_raw(),
152 SignalAddr::Subunit(a) => a.to_raw(),
153 }
154 }
155}
156
157#[derive(Copy, Clone, Debug, Eq, PartialEq)]
161pub struct SignalSource {
162 pub src: SignalAddr,
164 pub dst: SignalAddr,
166}
167
168impl SignalSource {
169 const LENGTH_MIN: usize = 5;
170
171 pub fn new(dst: &SignalAddr) -> Self {
172 SignalSource {
173 dst: *dst,
174 ..Default::default()
175 }
176 }
177
178 fn build_operands(&self, for_status: bool) -> Result<Vec<u8>, AvcCmdBuildError> {
179 let mut operands = Vec::new();
180 operands.push(0xff);
181
182 if for_status {
183 operands.extend_from_slice(&[0xff, 0xfe]);
184 } else {
185 operands.extend_from_slice(&self.src.to_raw());
186 }
187
188 operands.extend_from_slice(&self.dst.to_raw());
189 Ok(operands)
190 }
191
192 fn parse_operands(&mut self, operands: &[u8]) -> Result<(), AvcRespParseError> {
193 if operands.len() < Self::LENGTH_MIN {
194 Err(AvcRespParseError::TooShortResp(4))?;
195 }
196
197 self.src = SignalAddr::from_raw(&operands[1..3]).map_err(|err| err.add_offset(1))?;
198 self.dst = SignalAddr::from_raw(&operands[3..5]).map_err(|err| err.add_offset(3))?;
199 Ok(())
200 }
201}
202
203impl Default for SignalSource {
204 fn default() -> Self {
205 Self {
206 src: Default::default(),
207 dst: Default::default(),
208 }
209 }
210}
211
212impl AvcOp for SignalSource {
213 const OPCODE: u8 = 0x1a;
214}
215
216impl AvcControl for SignalSource {
217 fn build_operands(&mut self, _: &AvcAddr) -> Result<Vec<u8>, AvcCmdBuildError> {
218 Self::build_operands(&self, false)
219 }
220
221 fn parse_operands(&mut self, _: &AvcAddr, operands: &[u8]) -> Result<(), AvcRespParseError> {
222 Self::parse_operands(self, operands)
223 }
224}
225
226impl AvcStatus for SignalSource {
227 fn build_operands(&mut self, _: &AvcAddr) -> Result<Vec<u8>, AvcCmdBuildError> {
228 Self::build_operands(&self, true)
229 }
230
231 fn parse_operands(&mut self, _: &AvcAddr, operands: &[u8]) -> Result<(), AvcRespParseError> {
232 Self::parse_operands(self, operands)
233 }
234}
235
236#[cfg(test)]
237mod test {
238 use crate::*;
239
240 #[test]
241 fn signaladdr_from() {
242 let raw = [0xff, 0x00];
243 let addr = SignalAddr::from_raw(&raw).unwrap();
244 assert_eq!(raw, addr.to_raw());
245
246 let raw = [0xff, 0x27];
247 let addr = SignalAddr::from_raw(&raw).unwrap();
248 assert_eq!(raw, addr.to_raw());
249
250 let raw = [0xff, 0x87];
251 let addr = SignalAddr::from_raw(&raw).unwrap();
252 assert_eq!(raw, addr.to_raw());
253
254 let raw = [0xff, 0xc7];
255 let addr = SignalAddr::from_raw(&raw).unwrap();
256 assert_eq!(raw, addr.to_raw());
257
258 let raw = [0x63, 0x07];
259 let addr = SignalAddr::from_raw(&raw).unwrap();
260 assert_eq!(raw, addr.to_raw());
261
262 let raw = [0x09, 0x11];
263 let addr = SignalAddr::from_raw(&raw).unwrap();
264 assert_eq!(raw, addr.to_raw());
265 }
266
267 #[test]
268 fn signalsource_operands() {
269 let operands = [0x00, 0x2e, 0x1c, 0xff, 0x05];
270 let dst = SignalAddr::Unit(SignalUnitAddr::Isoc(0x05));
271 let src = SignalAddr::Subunit(SignalSubunitAddr {
272 subunit: AvcAddrSubunit::new(AvcSubunitType::Tuner, 0x06),
273 plug_id: 0x1c,
274 });
275 let mut op = SignalSource::new(&dst);
276 AvcStatus::parse_operands(&mut op, &AvcAddr::Unit, &operands).unwrap();
277 assert_eq!(op.src, src);
278 assert_eq!(op.dst, dst);
279
280 let targets = AvcStatus::build_operands(&mut op, &AvcAddr::Unit).unwrap();
281 assert_eq!(targets, [0xff, 0xff, 0xfe, 0xff, 0x05]);
282
283 let src = SignalAddr::Subunit(SignalSubunitAddr {
284 subunit: AvcAddrSubunit::new(AvcSubunitType::Extended, 0x05),
285 plug_id: 0x07,
286 });
287 let dst = SignalAddr::Unit(SignalUnitAddr::Ext(0x03));
288 let mut op = SignalSource { src, dst };
289 let targets = AvcControl::build_operands(&mut op, &AvcAddr::Unit).unwrap();
290 assert_eq!(targets, [0xff, 0xf5, 0x07, 0xff, 0x83]);
291
292 let mut op = SignalSource {
293 src: SignalAddr::Unit(SignalUnitAddr::Isoc(0xf)),
294 dst: SignalAddr::Unit(SignalUnitAddr::Isoc(0xf)),
295 };
296 AvcControl::parse_operands(&mut op, &AvcAddr::Unit, &targets).unwrap();
297 assert_eq!(op.src, src);
298 assert_eq!(op.dst, dst);
299 }
300}