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 #[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#[repr(u8)]
99#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
100pub enum FrameType {
101 Single = 0x00,
107 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#[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#[derive(Debug, Default, Copy, Clone)]
169pub struct FlowControlContext {
170 state: FlowControlState,
171 block_size: u8,
172 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 ..=0x7F => 1000 * (self.st_min as u32),
212 0x80..=0xF0 |
213 0xFA..=0xFF => {
214 let message = format!("ISO 15765-2 - got an invalid st_min: {}", self.st_min);
216 log::error!("{}" ,message);
217 unreachable!("{}", message) },
219 0xF1..=0xF9 => 100 * (self.st_min & 0x0F) as u32,
220 }
221 }
222}
223
224#[derive(Debug, Default, Copy, Clone, Eq, PartialEq)]
226pub enum ByteOrder {
227 Big,
229 #[default]
231 Little,
232 Native,
234}
235
236