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