1use crate::machine::*;
6
7#[derive(Debug, Clone, Copy)]
16pub struct CANFrame {
17 pub can_cobid: u32,
21
22 pub can_len: usize,
24
25 pub can_data: [u8; 8],
29}
30
31impl Default for CANFrame {
32 fn default() -> Self {
33 Self {
34 can_cobid: 0,
35 can_len: 0,
36 can_data: [0; 8],
37 }
38 }
39}
40
41impl CANFrame {
42 pub fn write_to_slice(self: &Self, buffer: &mut [u8]) {
44 assert!(buffer.len() >= 16, "Buffer must be at least 16 bytes long");
45
46 buffer[0..4].copy_from_slice(&self.can_cobid.to_le_bytes());
48
49 buffer[4] = self.can_len as u8;
51
52 buffer[5..8].fill(0);
54
55 buffer[8..16].copy_from_slice(&self.can_data);
57 }
58}
59
60enum State {
62 Init,
63 Id0,
64 Id1,
65 Id2,
66 Id3,
67 Len,
68 Skip0,
69 Skip1,
70 Skip2,
71 Data,
72 Final,
73}
74
75pub struct CANFrameMachine {
77 state: State,
78 can_frame: CANFrame,
79 len: usize,
80 index: usize,
81}
82
83impl Default for CANFrameMachine {
84 fn default() -> Self {
85 Self {
86 state: State::Init,
87 can_frame: CANFrame::default(),
88 len: 0,
89 index: 0,
90 }
91 }
92}
93
94impl CANFrameMachine {
95 fn get_data_byte(self: &mut Self, x: u8) {
100 if self.len > 1 {
101 self.len = self.len - 1;
102 self.state = State::Data;
103 self.can_frame.can_data[self.index] = x;
104 } else if self.len == 1 {
105 self.len = self.len - 1;
106 self.state = State::Final;
107 self.can_frame.can_data[self.index] = x;
108 } else {
109 self.state = State::Final;
110 }
111
112 self.index = self.index + 1;
113 }
114}
115
116impl MachineTrans<u8> for CANFrameMachine {
117 type Observation = Option<CANFrame>;
118
119 fn initial(self: &mut Self) {
121 self.can_frame.can_cobid = 0;
122 self.can_frame.can_data.fill(0);
123 self.can_frame.can_len = 0;
124 self.len = 0;
125 self.index = 0;
126 self.state = State::Init;
127 }
128
129 fn transit(self: &mut Self, x: u8) {
134 match &self.state {
135 State::Init => {
136 self.state = State::Id0;
137 self.can_frame.can_cobid = x.into();
138 }
139
140 State::Id0 => {
141 self.state = State::Id1;
142 self.can_frame.can_cobid = self.can_frame.can_cobid | ((x as u32) << 8);
143 }
144
145 State::Id1 => {
146 self.state = State::Id2;
147 self.can_frame.can_cobid = self.can_frame.can_cobid | ((x as u32) << 16);
148 }
149
150 State::Id2 => {
151 self.state = State::Id3;
152 self.can_frame.can_cobid = self.can_frame.can_cobid | ((x as u32) << 24);
153 }
154
155 State::Id3 => {
156 self.state = State::Len;
157 let len: usize = x.into();
158 self.len = len;
159 self.can_frame.can_len = len;
160 }
161
162 State::Len => {
163 self.state = State::Skip0;
164 }
165
166 State::Skip0 => {
167 self.state = State::Skip1;
168 }
169
170 State::Skip1 => {
171 self.state = State::Skip2;
172 }
173
174 State::Skip2 => {
175 self.get_data_byte(x);
176 }
177
178 State::Data => {
179 self.get_data_byte(x);
180 }
181
182 State::Final => {
183 self.index = self.index + 1;
184 }
185 }
186 }
187
188 fn observe(self: &Self) -> Self::Observation {
192 match self.state {
193 State::Final => {
194 if self.index == 8 {
196 Some(self.can_frame)
197 } else {
198 None
199 }
200 }
201 _ => None,
202 }
203 }
204}
205
206impl Final for Option<CANFrame> {
207 type FinalValue = CANFrame;
208
209 fn is_final(self: Self) -> Option<Self::FinalValue> {
216 self
217 }
218}
219
220#[cfg(test)]
221mod tests {
222 use super::*;
223
224 #[test]
225 fn test_raw_can_frame_parsing() {
226 let frame = [
227 0x02, 0x07, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ];
231
232 let mut parser = CANFrameMachine::default();
233
234 for x in frame {
235 parser.transit(x);
236 }
237
238 let result = parser.observe().is_final().unwrap();
239
240 assert_eq!(result.can_cobid, 0x702);
241 assert_eq!(result.can_len, 1);
242 assert_eq!(result.can_data[0], 0x7f);
243 }
244
245 #[test]
246 fn test_raw_can_frame_decode_encode() {
247 let frame0: [u8; 16] = [
248 0x02, 0x07, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x7f, 0x7e, 0x7d, 0x7c, 0x00, 0x01, 0x02, 0x03, ];
252
253 let mut frame1: [u8; 16] = [0; 16];
254
255 let mut parser = CANFrameMachine::default();
256
257 for x in frame0 {
258 parser.transit(x);
259 }
260
261 let can_frame = parser.observe().is_final().unwrap();
262
263 can_frame.write_to_slice(&mut frame1);
264
265 assert_eq!(frame0, frame1);
266 }
267}