1pub mod constant;
2pub mod error;
3pub mod can;
4pub mod device;
5
6use std::fmt::{Debug, Display, Formatter};
7use std::sync::atomic::{AtomicU8, Ordering};
8use bitflags::bitflags;
9use crate::error::Error;
10
11bitflags! {
12 #[derive(Default, Debug, Clone, Copy, PartialEq, Eq)]
14 pub struct IsoTpState: u8 {
15 const Idle = 0b0000_0000;
16 #[deprecated]
17 const WaitSingle = 0b0000_0001;
18 #[deprecated]
19 const WaitFirst = 0b0000_0010;
20 const WaitFlowCtrl = 0b0000_0100;
21 #[deprecated]
22 const WaitData = 0b0000_1000;
23 const WaitBusy = 0b0001_0000;
24 #[deprecated]
25 const ResponsePending = 0b0010_0000;
26 const Sending = 0b0100_0000;
27 const Error = 0b1000_0000;
28 }
29}
30
31impl Display for IsoTpState {
32 #[allow(deprecated)]
33 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
34 let mut idle = true;
35 let mut first = true;
36 if self.contains(IsoTpState::WaitSingle) {
37 write!(f, "WaitSingle")?;
38 idle = false;
39 first = false;
40 }
41 if self.contains(IsoTpState::WaitFirst) {
42 write!(f, "{}", format!("{}WaitFirst", if first { "" } else { " | " }))?;
43 idle = false;
44 first = false;
45 }
46 if self.contains(IsoTpState::WaitFlowCtrl) {
47 write!(f, "{}", format!("{}WaitFlowCtrl", if first { "" } else { " | " }))?;
48 idle = false;
49 first = false;
50 }
51 if self.contains(IsoTpState::WaitData) {
52 write!(f, "{}", format!("{}WaitData", if first { "" } else { " | " }))?;
53 idle = false;
54 first = false;
55 }
56 if self.contains(IsoTpState::WaitBusy) {
57 write!(f, "{}", format!("{}WaitBusy", if first { "" } else { " | " }))?;
58 idle = false;
59 first = false;
60 }
61 if self.contains(IsoTpState::ResponsePending) {
62 write!(f, "{}", format!("{}ResponsePending", if first { "" } else { " | " }))?;
63 idle = false;
64 first = false;
65 }
66 if self.contains(IsoTpState::Sending) {
67 write!(f, "{}", format!("{}Sending", if first { "" } else { " | " }))?;
68 idle = false;
69 first = false;
70 }
71 if self.contains(IsoTpState::Error) {
72 write!(f, "{}", format!("{}Error", if first { "" } else { " | " }))?;
73 idle = false;
74 }
75 if idle {
76 write!(f, "Idle")?;
77 }
78
79 Ok(())
80 }
81}
82
83#[derive(Debug)]
85pub struct AtomicState(AtomicU8);
86
87impl Default for AtomicState {
88 fn default() -> Self {
89 Self(AtomicU8::from(IsoTpState::Idle.bits()))
90 }
91}
92
93impl AtomicState {
94 pub fn new(state: IsoTpState) -> Self {
96 Self(AtomicU8::new(state.bits()))
97 }
98
99 #[inline]
101 pub fn load(&self, order: Ordering) -> IsoTpState {
102 IsoTpState::from_bits_truncate(self.0.load(order))
103 }
104
105 #[inline]
107 pub fn store(&self, state: IsoTpState, order: Ordering) {
108 self.0.store(state.bits(), order);
109 }
110
111 pub fn fetch_update(&self,
113 set_order: Ordering,
114 fetch_order: Ordering,
115 mut f: impl FnMut(IsoTpState) -> Option<IsoTpState>,
116 ) -> Result<IsoTpState, IsoTpState> {
117 let mut prev = self.load(fetch_order);
118 while let Some(next) = f(prev) {
119 match self.0.compare_exchange_weak(prev.bits(), next.bits(), set_order, fetch_order) {
120 Ok(_) => return Ok(next),
121 Err(next_prev) => prev = IsoTpState::from_bits_truncate(next_prev),
122 }
123 }
124 Err(prev)
125 }
126
127 #[inline]
129 pub fn fetch_add(&self,
130 flags: IsoTpState,
131 success: Ordering,
132 failure: Ordering,
133 ) -> Result<IsoTpState, IsoTpState> {
134 self.fetch_update(success, failure, |state| Some(state | flags))
135 }
136
137 #[inline]
139 pub fn fetch_remove(&self,
140 flags: IsoTpState,
141 success: Ordering,
142 failure: Ordering,
143 ) -> Result<IsoTpState, IsoTpState> {
144 self.fetch_update(success, failure, |state| Some(state & !flags))
145 }
146}
147
148#[derive(Debug, Clone)]
149pub enum IsoTpEvent {
150 Wait,
151 FirstFrameReceived,
152 DataReceived(Vec<u8>),
153 ErrorOccurred(Error),
154}
155
156pub trait IsoTpEventListener {
157 fn from_buffer(&mut self) -> Option<IsoTpEvent>;
158 fn clear_buffer(&mut self);
159 fn on_iso_tp_event(&mut self, event: IsoTpEvent);
160}
161
162#[derive(Debug, Copy, Clone)]
165pub enum IsoTpTimeout {
166 TimeoutAr { timeout_ms: u32 },
167 TimeoutAs { timeout_ms: u32 },
168 TimeoutBr { timeout_ms: u32 },
169 TimeoutBs { timeout_ms: u32 },
170 TimeoutCr { timeout_ms: u32 },
171 TimeoutCs { timeout_ms: u32 },
172}
173
174#[repr(u8)]
176#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
177pub enum FrameType {
178 Single = 0x00,
184 First = 0x10,
190 Consecutive = 0x20,
191 FlowControl = 0x30,
192}
193
194impl Into<u8> for FrameType {
195 #[inline]
196 fn into(self) -> u8 {
197 self as u8
198 }
199}
200
201impl TryFrom<u8> for FrameType {
202 type Error = Error;
203 #[inline]
204 fn try_from(value: u8) -> Result<Self, Self::Error> {
205 match value & 0xF0 {
206 0x00 => Ok(Self::Single),
207 0x10 => Ok(Self::First),
208 0x20 => Ok(Self::Consecutive),
209 0x30 => Ok(Self::FlowControl),
210 v => Err(Error::InvalidParam(format!("`frame type`({})", v))),
211 }
212 }
213}
214
215#[repr(u8)]
217#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
218pub enum FlowControlState {
219 #[default]
220 Continues = 0x00,
221 Wait = 0x01,
222 Overload = 0x02,
223}
224
225impl TryFrom<u8> for FlowControlState {
226 type Error = Error;
227 fn try_from(value: u8) -> Result<Self, Self::Error> {
228 match value {
229 0x00 => Ok(Self::Continues),
230 0x01 => Ok(Self::Wait),
231 0x02 => Ok(Self::Overload),
232 v => Err(Error::InvalidParam(format!("`state` ({})", v))),
233 }
234 }
235}
236
237impl Into<u8> for FlowControlState {
238 #[inline]
239 fn into(self) -> u8 {
240 self as u8
241 }
242}
243
244#[derive(Debug, Default, Copy, Clone)]
246pub struct FlowControlContext {
247 state: FlowControlState,
248 block_size: u8,
249 st_min: u8,
257}
258
259impl FlowControlContext {
260 #[inline]
261 pub fn new(
262 state: FlowControlState,
263 block_size: u8,
264 st_min: u8,
265 ) -> Result<Self, Error> {
266 match st_min {
267 0x80..=0xF0 |
268 0xFA..=0xFF => Err(Error::InvalidStMin(st_min)),
269 v => Ok(Self { state, block_size, st_min: v }),
270 }
271 }
272 #[inline]
273 pub fn state(&self) -> FlowControlState {
274 self.state
275 }
276 #[inline]
277 pub fn block_size(&self) -> u8 {
278 self.block_size
279 }
280 #[inline]
281 pub fn st_min(&self) -> u8 {
282 self.st_min
283 }
284 #[inline]
285 pub fn st_min_us(&self) -> u32 {
286 match self.st_min {
287 ..=0x7F => 1000 * (self.st_min as u32),
289 0x80..=0xF0 |
290 0xFA..=0xFF => {
291 let message = format!("ISO-TP: got an invalid st_min: {}", self.st_min);
293 log::error!("{}" ,message);
294 panic!("{}", message) },
296 0xF1..=0xF9 => 100 * (self.st_min & 0x0F) as u32,
297 }
298 }
299}
300
301#[derive(Debug, Default, Copy, Clone, Eq, PartialEq)]
303pub enum ByteOrder {
304 Big,
306 #[default]
308 Little,
309 Native,
311}
312
313pub trait IsoTpFrame: Send {
315 fn decode<T: AsRef<[u8]>>(data: T) -> Result<Self, Error>
325 where
326 Self: Sized;
327 fn encode(self, padding: Option<u8>) -> Vec<u8>;
337 fn from_data<T: AsRef<[u8]>>(data: T) -> Result<Vec<Self>, Error>
351 where
352 Self: Sized;
353
354 fn single_frame<T: AsRef<[u8]>>(data: T) -> Result<Self, Error>
362 where
363 Self: Sized;
364 fn flow_ctrl_frame(state: FlowControlState, block_size: u8, st_min: u8) -> Result<Self, Error>
376 where
377 Self: Sized;
378
379 #[inline]
380 fn default_flow_ctrl_frame() -> Self
381 where
382 Self: Sized
383 {
384 Self::flow_ctrl_frame(FlowControlState::Continues, 0x00, 10)
385 .unwrap()
386 }
387}