1mod constant;
2pub use constant::*;
3
4pub mod driver;
5
6pub mod frame;
7pub mod identifier;
8
9pub mod isotp;
10
11#[cfg(feature = "j1939")]
12pub mod j1939;
13
14mod utils;
15
16use crate::{FlowControlContext, FlowControlState, FrameType, IsoTpFrame};
17use crate::error::Error;
19
20#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
22pub enum AddressFormat {
23 #[default]
26 Normal = 0x01, NormalFixed = 0x02, Extend = 0x03, ExtendMixed = 0x04, Enhanced = 0x05, }
32
33#[derive(Debug, Copy, Clone, Eq, PartialEq)]
39pub struct Address {
40 pub tx_id: u32,
41 pub rx_id: u32,
42 pub fid: u32,
43}
44
45#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Default)]
47pub enum AddressType {
48 #[default]
49 Physical,
50 Functional,
51}
52
53#[derive(Debug, Clone)]
55pub enum CanIsoTpFrame {
56 SingleFrame { data: Vec<u8> },
58 FirstFrame { length: u32, data: Vec<u8> },
60 ConsecutiveFrame { sequence: u8, data: Vec<u8> },
62 FlowControlFrame(FlowControlContext)
64}
65
66impl<'a> From<&'a CanIsoTpFrame> for FrameType {
67 fn from(value: &'a CanIsoTpFrame) -> Self {
68 match value {
69 CanIsoTpFrame::SingleFrame { .. } => Self::Single,
70 CanIsoTpFrame::FirstFrame { .. } => Self::First,
71 CanIsoTpFrame::ConsecutiveFrame { .. } => Self::Consecutive,
72 CanIsoTpFrame::FlowControlFrame(_) => Self::FlowControl,
73 }
74 }
75}
76
77unsafe impl Send for CanIsoTpFrame {}
78
79impl IsoTpFrame for CanIsoTpFrame {
80 fn decode<T: AsRef<[u8]>>(data: T) -> Result<Self, Error> {
81 let data = data.as_ref();
82 let length = data.len();
83 match length {
84 0 => Err(Error::EmptyPdu),
85 1..=2 => Err(Error::InvalidPdu(data.to_vec())),
86 3.. => {
87 let byte0 = data[0];
88 match FrameType::try_from(byte0)? {
89 FrameType::Single => { utils::decode_single(data, byte0, length)
91 },
92 FrameType::First => { utils::decode_first(data, byte0, length)
94 },
95 FrameType::Consecutive => {
96 let sequence = byte0 & 0x0F;
97 Ok(Self::ConsecutiveFrame { sequence, data: Vec::from(&data[1..]) })
98 },
99 FrameType::FlowControl => {
100 let state = FlowControlState::try_from(byte0 & 0x0F)?;
102 let fc = FlowControlContext::new(state, data[1], data[2])?;
103 Ok(Self::FlowControlFrame(fc))
104 },
105 }
106 }
107 }
109 }
110
111 fn encode(self, padding: Option<u8>) -> Vec<u8> {
112 match self {
113 Self::SingleFrame { data } => {
114 utils::encode_single(data, padding)
115 },
116 Self::FirstFrame { length, data } => {
117 utils::encode_first(length, data)
118 },
119 Self::ConsecutiveFrame { sequence, mut data } => {
120 let mut result = vec![FrameType::Consecutive as u8 | sequence];
121 result.append(&mut data);
122 result.resize(CAN_FRAME_MAX_SIZE, padding.unwrap_or(DEFAULT_PADDING));
123 result
124 },
125 Self::FlowControlFrame(context) => {
126 let byte0_h: u8 = FrameType::FlowControl.into();
127 let byte0_l: u8 = context.state().into();
128 let mut result = vec![
129 byte0_h | byte0_l,
130 context.block_size(),
131 context.st_min(),
132 ];
133 result.resize(CAN_FRAME_MAX_SIZE, padding.unwrap_or(DEFAULT_PADDING));
134 result
135 },
136 }
137 }
138
139 fn from_data<T: AsRef<[u8]>>(data: T) -> Result<Vec<Self>, Error> {
140 utils::from_data(data.as_ref())
141 }
142
143 fn single_frame<T: AsRef<[u8]>>(data: T) -> Result<Self, Error> {
144 utils::new_single(data)
145 }
146
147 fn flow_ctrl_frame(state: FlowControlState,
148 block_size: u8,
149 st_min: u8,
150 ) -> Result<Self, Error> {
151 Ok(Self::FlowControlFrame(
152 FlowControlContext::new(state, block_size, st_min)?
153 ))
154 }
155}
156
157#[cfg(test)]
158mod tests {
159 use hex_literal::hex;
160 use crate::can::{CAN_FRAME_MAX_SIZE, CanIsoTpFrame, CONSECUTIVE_FRAME_SIZE, DEFAULT_PADDING, FIRST_FRAME_SIZE_2004};
161 use crate::{FlowControlState, IsoTpFrame};
162
163 #[test]
164 fn test_single() -> anyhow::Result<()> {
165 let data = hex!("02 10 01 00 00 00 00 00").as_slice();
166 let frame = CanIsoTpFrame::decode(data)?;
167 match frame.clone() {
168 CanIsoTpFrame::SingleFrame { data } => {
169 assert_eq!(data, hex!("1001"));
170 },
171 _ => {
172 panic!("Invalid frame type");
173 }
174 }
175 assert_eq!(frame.encode(Some(0x00)), data.to_vec());
176
177 let frame = CanIsoTpFrame::SingleFrame { data: hex!("1001").to_vec() };
178 assert_eq!(frame.encode(Some(0x00)), data.to_vec());
179 Ok(())
180 }
181
182 #[test]
183 fn test_first() -> anyhow::Result<()> {
184 let data = hex!("10 0f 62 f1 87 44 56 43");
185 let frame = CanIsoTpFrame::decode(data)?;
186 match frame.clone() {
187 CanIsoTpFrame::FirstFrame { length, data } => {
188 assert_eq!(length, 0x0f);
189 assert_eq!(data, hex!("62 f1 87 44 56 43"));
190 },
191 _ => {
192 panic!("Invalid frame type");
193 }
194 }
195 assert_eq!(frame.encode(None), data.to_vec());
196
197 let frame = CanIsoTpFrame::FirstFrame {
198 length: 0x0f,
199 data: hex!("62 f1 87 44 56 43").to_vec()
200 };
201 assert_eq!(frame.encode(None), data.to_vec());
202
203 Ok(())
204 }
205
206 #[test]
207 fn test_consecutive() -> anyhow::Result<()> {
208 let data = hex!("21 37 45 32 30 30 30 30");
209 let frame = CanIsoTpFrame::decode(data)?;
210 match frame.clone() {
211 CanIsoTpFrame::ConsecutiveFrame { sequence, data } => {
212 assert_eq!(sequence, 1);
213 assert_eq!(data, hex!("37 45 32 30 30 30 30"));
214 },
215 _ => {
216 panic!("Invalid frame type");
217 }
218 }
219 assert_eq!(frame.encode(None), data.to_vec());
220
221 let frame = CanIsoTpFrame::ConsecutiveFrame {
222 sequence: 1,
223 data: hex!("37 45 32 30 30 30 30").to_vec()
224 };
225 assert_eq!(frame.encode(None), data.to_vec());
226 Ok(())
227 }
228
229 #[test]
230 fn test_flow_control() -> anyhow::Result<()> {
231 let data = hex!("30 80 01 55 55 55 55 55").as_slice();
232 let frame = CanIsoTpFrame::decode(data)?;
233 match frame.clone() {
234 CanIsoTpFrame::FlowControlFrame(context) => {
235 assert_eq!(context.state(), FlowControlState::Continues);
236 assert_eq!(context.block_size(), 0x80);
237 assert_eq!(context.st_min(), 0x01);
238 },
239 _ => {
240 panic!("Invalid frame type");
241 }
242 }
243 assert_eq!(frame.encode(Some(0x55)), data.to_vec());
244
245 let frame = CanIsoTpFrame::default_flow_ctrl_frame();
246 assert_eq!(frame.encode(Some(0x55)), hex!("30 00 0a 55 55 55 55 55"));
247 Ok(())
248 }
249
250 #[test]
251 fn test_data_to_multi() -> anyhow::Result<()> {
252 let data = hex!("62 f1 87 44 56 43 37 45 32 30 30 30 30 30 37").as_slice();
253 let frames = CanIsoTpFrame::from_data(data)?;
254 for (index, frame) in frames.into_iter().enumerate() {
255 match index {
256 0 => {
257 assert_eq!(frame.encode(None), hex!("10 0f 62 f1 87 44 56 43").to_vec());
258 },
259 1 => {
260 assert_eq!(frame.encode(None), hex!("21 37 45 32 30 30 30 30").to_vec());
261 },
262 2 => assert_eq!(frame.encode(None), hex!("22 30 37 aa aa aa aa aa").to_vec()),
263 _ => panic!()
264 }
265 }
266
267 let mut size = 0x96;
268 let data = vec![0x30; size];
269 let frames = CanIsoTpFrame::from_data(data)?;
270 for (index, frame) in frames.into_iter().enumerate() {
271 match index {
272 0 => {
273 size -= FIRST_FRAME_SIZE_2004;
274 assert_eq!(frame.encode(None), hex!("10 96 30 30 30 30 30 30"))
275 },
276 1..=15 => {
277 size -= CONSECUTIVE_FRAME_SIZE;
278 let expect = vec![0x20 + index as u8, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30];
279 assert_eq!(frame.encode(None), expect);
280 }
281 _ => {
282 if size > CONSECUTIVE_FRAME_SIZE {
283 size -= CONSECUTIVE_FRAME_SIZE;
284 let expect = vec![0x20 + (index % 16) as u8, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30];
285 assert_eq!(frame.encode(None), expect);
286 }
287 else {
288 let mut expect = vec![0x20 + (index % 16) as u8];
289 for _ in 0..size {
290 expect.push(0x30);
291 }
292 expect.resize(CAN_FRAME_MAX_SIZE, DEFAULT_PADDING);
293 assert_eq!(frame.encode(None), expect);
294 }
295 },
296 }
297 }
298 Ok(())
299 }
300}