iso15765_2/
lib.rs

1#![allow(deprecated)]
2
3mod error;
4pub use error::*;
5mod constants;
6pub use constants::*;
7
8use std::fmt::{Display, Formatter};
9use bitflags::bitflags;
10
11bitflags! {
12    /// ISO 15765-2 state.
13    #[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, Clone)]
84pub enum IsoTpEvent {
85    Wait,
86    FirstFrameReceived,
87    DataReceived(Vec<u8>),
88    ErrorOccurred(Iso15765Error),
89}
90
91pub trait IsoTpEventListener {
92    fn buffer_data(&mut self) -> Option<IsoTpEvent>;
93    fn clear_buffer(&mut self);
94    fn on_iso_tp_event(&mut self, event: IsoTpEvent);
95}
96
97/// ISO 15765-2 frame type define.
98#[repr(u8)]
99#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
100pub enum FrameType {
101    /// | - data length -| - N_PCI bytes - | - note - |
102    ///
103    /// | -     le 8   - | -  bit0(3~0) = length  - | - std2004 - |
104    ///
105    /// | -     gt 8    - | -  bit0(3~0) = 0; bit1(7~0) = length  - | - std2016 - |
106    Single = 0x00,
107    /// | - data length -| - N_PCI bytes - | - note - |
108    ///
109    /// | -  le 4095   - | - bit0(3~0) + bit1(7~0) = length - | - std2004 - |
110    ///
111    /// | -  gt 4095   - | - bit0(3~0) + bit1(7~0) = 0; byte2~5(7~0) = length - | - std2016 - |
112    First = 0x10,
113    Consecutive = 0x20,
114    FlowControl = 0x30,
115}
116
117impl Into<u8> for FrameType {
118    #[inline]
119    fn into(self) -> u8 {
120        self as u8
121    }
122}
123
124impl TryFrom<u8> for FrameType {
125    type Error = Iso15765Error;
126    #[inline]
127    fn try_from(value: u8) -> Result<Self, Self::Error> {
128        match value & 0xF0 {
129            0x00 => Ok(Self::Single),
130            0x10 => Ok(Self::First),
131            0x20 => Ok(Self::Consecutive),
132            0x30 => Ok(Self::FlowControl),
133            v => Err(Iso15765Error::InvalidParam(format!("`frame type`({})", v))),
134        }
135    }
136}
137
138/// Flow control type define.
139#[repr(u8)]
140#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
141pub enum FlowControlState {
142    #[default]
143    Continues = 0x00,
144    Wait = 0x01,
145    Overload = 0x02,
146}
147
148impl TryFrom<u8> for FlowControlState {
149    type Error = Iso15765Error;
150    fn try_from(value: u8) -> Result<Self, Self::Error> {
151        match value {
152            0x00 => Ok(Self::Continues),
153            0x01 => Ok(Self::Wait),
154            0x02 => Ok(Self::Overload),
155            v => Err(Iso15765Error::InvalidParam(format!("`state` ({})", v))),
156        }
157    }
158}
159
160impl Into<u8> for FlowControlState {
161    #[inline]
162    fn into(self) -> u8 {
163        self as u8
164    }
165}
166
167/// Flow control frame context.
168#[derive(Debug, Default, Copy, Clone)]
169pub struct FlowControlContext {
170    state: FlowControlState,
171    block_size: u8,
172    /// Use milliseconds (ms) for values in the range 00 to 7F (0 ms to 127 ms).
173    /// If st_min is 0, set to default value. See [`ST_MIN_ISO15765_2`]
174    /// and [`ST_MIN_ISO15765_4`]
175    ///
176    /// Use microseconds (μs) for values in the range F1 to F9 (100 μs to 900 μs).
177    ///
178    /// Values in the ranges 80 to F0 and FA to FF are reserved.
179    st_min: u8,
180}
181
182impl FlowControlContext {
183    #[inline]
184    pub fn new(
185        state: FlowControlState,
186        block_size: u8,
187        st_min: u8,
188    ) -> Result<Self, Iso15765Error> {
189        match st_min {
190            0x80..=0xF0 |
191            0xFA..=0xFF => Err(Iso15765Error::InvalidStMin(st_min)),
192            v => Ok(Self { state, block_size, st_min: v }),
193        }
194    }
195    #[inline]
196    pub fn state(&self) -> FlowControlState {
197        self.state
198    }
199    #[inline]
200    pub fn block_size(&self) -> u8 {
201        self.block_size
202    }
203    #[inline]
204    pub fn st_min(&self) -> u8 {
205        self.st_min
206    }
207    #[inline]
208    pub fn st_min_us(&self) -> u32 {
209        match self.st_min {
210            // 0x00 => 1000 * 10,
211            ..=0x7F => 1000 * (self.st_min as u32),
212            0x80..=0xF0 |
213            0xFA..=0xFF => {
214                // should not enter
215                let message = format!("ISO 15765-2 - got an invalid st_min: {}", self.st_min);
216                log::error!("{}" ,message);
217                unreachable!("{}", message)   // panic is dangerous
218            },
219            0xF1..=0xF9 => 100 * (self.st_min & 0x0F) as u32,
220        }
221    }
222}
223
224/// byte order define.
225#[derive(Debug, Default, Copy, Clone, Eq, PartialEq)]
226pub enum ByteOrder {
227    /// Motorola byte order
228    Big,
229    /// Intel byte order
230    #[default]
231    Little,
232    /// The native byte order depends on your CPU
233    Native,
234}
235
236// #[derive(Debug, Clone)]
237// pub enum IsoTpFrame {
238//     /// The ISO 15765-2 single frame.
239//     SingleFrame { data: Vec<u8> },
240//     /// The ISO 15765-2 first frame.
241//     FirstFrame { length: u32, data: Vec<u8> },
242//     /// The ISO 15765-2 consecutive frame.
243//     ConsecutiveFrame { sequence: u8, data: Vec<u8> },
244//     /// The ISO 15765-2 flow control frame.
245//     FlowControlFrame(FlowControlContext)
246// }
247//
248// impl IsoTpFrame {
249//     #[inline]
250//     pub fn flow_ctrl_frame(
251//         state: FlowControlState,
252//         block_size: u8,
253//         st_min: u8,
254//     ) -> Result<Self, IsoTpError> {
255//         Ok(Self::FlowControlFrame(FlowControlContext::new(state, block_size, st_min)?))
256//     }
257//
258//     #[inline]
259//     pub fn default_flow_ctrl_frame() -> Self {
260//         Self::flow_ctrl_frame(
261//             FlowControlState::Continues,
262//             ISO_TP_DEFAULT_BLOCK_SIZE,
263//             ISO_TP_DEFAULT_ST_MIN
264//         )
265//             .unwrap()
266//     }
267// }