acn_protocol/
root_layer.rs1use crate::AcnError;
2use core::error::Error;
3
4pub trait RootLayerCodec {
5 type Error: Error + From<AcnError>;
6
7 fn size(&self) -> usize {
8 self.preamble_length() + self.pdu_block_length() + self.postamble_length()
9 }
10
11 fn preamble_length(&self) -> usize {
12 0
13 }
14
15 fn encode_preamble(&self, _buf: &mut [u8]) -> Result<usize, Self::Error> {
16 Ok(self.preamble_length())
17 }
18
19 fn pdu_block_length(&self) -> usize {
20 0
21 }
22
23 fn encode_pdu_block(&self, _buf: &mut [u8]) -> Result<usize, Self::Error> {
24 Ok(self.pdu_block_length())
25 }
26
27 fn postamble_length(&self) -> usize {
28 0
29 }
30
31 fn encode_postamble(&self, _buf: &mut [u8]) -> Result<usize, Self::Error> {
32 Ok(self.postamble_length())
33 }
34
35 fn encode(&self, buf: &mut [u8]) -> Result<usize, Self::Error> {
36 let buffer_len = buf.len();
37 let expected_len = self.size();
38
39 if buffer_len < expected_len {
40 return Err(AcnError::InvalidBufferLength {
41 actual: buffer_len,
42 expected: expected_len,
43 }.into());
44 }
45
46 let mut offset = 0;
47
48 offset += self.encode_preamble(&mut buf[offset..])?;
49
50 offset += self.encode_pdu_block(&mut buf[offset..])?;
51
52 offset += self.encode_postamble(&mut buf[offset..])?;
53
54 Ok(offset)
55 }
56
57 fn decode(buf: &[u8]) -> Result<Self, Self::Error>
58 where
59 Self: Sized;
60}
61
62#[cfg(test)]
63mod tests {
64 use super::*;
65
66 struct TestPdu {
67 target_id: u8,
68 source_id: u8,
69 data: u32,
70 }
71
72 struct TestRootLayerPacket {
73 pdu1: TestPdu,
74 pdu2: TestPdu,
75 }
76
77 impl RootLayerCodec for TestRootLayerPacket {
78 type Error = AcnError;
79
80 fn preamble_length(&self) -> usize {
81 4
82 }
83
84 fn encode_preamble(&self, buf: &mut [u8]) -> Result<usize, AcnError> {
85 buf[0..4].copy_from_slice(&[0x01, 0x02, 0x03, 0x04]);
86
87 Ok(self.preamble_length())
88 }
89
90 fn pdu_block_length(&self) -> usize {
91 12
92 }
93
94 fn encode_pdu_block(&self, buf: &mut [u8]) -> Result<usize, AcnError> {
95 buf[0] = self.pdu1.target_id;
96 buf[1] = self.pdu1.source_id;
97 buf[2..6].copy_from_slice(&self.pdu1.data.to_be_bytes());
98 buf[6] = self.pdu2.target_id;
99 buf[7] = self.pdu2.source_id;
100 buf[8..12].copy_from_slice(&self.pdu2.data.to_be_bytes());
101
102 Ok(self.pdu_block_length())
103 }
104
105 fn postamble_length(&self) -> usize {
106 4
107 }
108
109 fn encode_postamble(&self, buf: &mut [u8]) -> Result<usize, AcnError> {
110 buf[0..4].copy_from_slice(&[0x05, 0x06, 0x07, 0x08]);
111
112 Ok(self.postamble_length())
113 }
114
115 fn decode(buf: &[u8]) -> Result<Self, Self::Error> {
116 if buf.len() < 4 {
117 return Err(AcnError::InvalidBufferLength {
118 actual: buf.len(),
119 expected: 4,
120 });
121 }
122
123 if buf[0..4] != [0x01, 0x02, 0x03, 0x04] {
124 return Err(AcnError::InvalidPreamble);
125 }
126
127 let pdu1 = TestPdu {
128 target_id: buf[0],
129 source_id: buf[1],
130 data: u32::from_be_bytes(buf[2..6].try_into()?),
131 };
132
133 let pdu2 = TestPdu {
134 target_id: buf[6],
135 source_id: buf[7],
136 data: u32::from_be_bytes(buf[8..12].try_into()?),
137 };
138
139 if buf[12..16] != [0x05, 0x06, 0x07, 0x08] {
140 return Err(AcnError::InvalidPostamble);
141 }
142
143 Ok(Self { pdu1, pdu2 })
144 }
145 }
146
147 #[test]
148 fn should_encode_root_layer_packet() {
149 let buf = &mut [0u8; 20];
150
151 let root_layer_packet = TestRootLayerPacket {
152 pdu1: TestPdu {
153 target_id: 0x01,
154 source_id: 0x02,
155 data: 0x12345678,
156 },
157 pdu2: TestPdu {
158 target_id: 0x03,
159 source_id: 0x04,
160 data: 0x87654321,
161 },
162 };
163
164 let bytes_written = root_layer_packet.encode(buf).unwrap();
165
166 assert_eq!(bytes_written, 20);
167
168 assert_eq!(
169 buf,
170 &[
171 0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x12, 0x34, 0x56, 0x78, 0x03, 0x04, 0x87, 0x65, 0x43, 0x21, 0x05, 0x06, 0x07, 0x08, ]
192 );
193 }
194}