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