1mod common;
2pub use common::*;
3pub mod request;
4pub mod response;
5pub mod utils;
6mod constant;
7pub use constant::*;
8mod error;
9pub use error::*;
10
11use std::collections::HashMap;
12use std::fmt::{Display, Formatter};
13
14enum_to_vec! (
15 pub enum Service {
21 SessionCtrl = 0x10, ECUReset = 0x11, ClearDiagnosticInfo = 0x14, ReadDTCInfo = 0x19, ReadDID = 0x22, ReadMemByAddr = 0x23, ReadScalingDID = 0x24, SecurityAccess = 0x27, CommunicationCtrl = 0x28, #[cfg(any(feature = "std2020"))]
31 Authentication = 0x29, ReadDataByPeriodId = 0x2A, DynamicalDefineDID = 0x2C, WriteDID = 0x2E, IOCtrl = 0x2F, RoutineCtrl = 0x31, RequestDownload = 0x34, RequestUpload = 0x35, TransferData = 0x36, RequestTransferExit = 0x37, #[cfg(any(feature = "std2013", feature = "std2020"))]
42 RequestFileTransfer = 0x38, WriteMemByAddr = 0x3D, TesterPresent = 0x3E, #[cfg(any(feature = "std2006", feature = "std2013"))]
46 AccessTimingParam = 0x83, SecuredDataTrans = 0x84, CtrlDTCSetting = 0x85, ResponseOnEvent = 0x86, LinkCtrl = 0x87, NRC = 0x7F,
52 }, u8);
53
54impl Display for Service {
55 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
56 match self {
57 Self::SessionCtrl => write!(f, "DiagnosticSessionControl"),
58 Self::ECUReset => write!(f, "ECUReset"),
59 Self::ClearDiagnosticInfo => write!(f, "ClearDiagnosticInformation"),
60 Self::ReadDTCInfo => write!(f, "ReadDTCInformation"),
61 Self::ReadDID => write!(f, "ReadDataByIdentifier"),
62 Self::ReadMemByAddr => write!(f, "ReadMemoryByAddress"),
63 Self::ReadScalingDID => write!(f, "ReadScalingDataByIdentifier"),
64 Self::SecurityAccess => write!(f, "SecurityAccess"),
65 Self::CommunicationCtrl => write!(f, "CommunicationControl"),
66 #[cfg(any(feature = "std2020"))]
67 Self::Authentication => write!(f, "Authentication"),
68 Self::ReadDataByPeriodId => write!(f, "ReadDataByPeriodicIdentifier"),
69 Self::DynamicalDefineDID => write!(f, "DynamicalDefineDyIdentifier"),
70 Self::WriteDID => write!(f, "WriteDataByIdentifier"),
71 Self::IOCtrl => write!(f, "IOControl"),
72 Self::RoutineCtrl => write!(f, "RoutineControl"),
73 Self::RequestDownload => write!(f, "RequestDownload"),
74 Self::RequestUpload => write!(f, "RequestUpload"),
75 Self::TransferData => write!(f, "TransferData"),
76 Self::RequestTransferExit => write!(f, "RequestTransferExit"),
77 #[cfg(any(feature = "std2013", feature = "std2020"))]
78 Self::RequestFileTransfer => write!(f, "RequestFileTransfer"),
79 Self::WriteMemByAddr => write!(f, "WriteMemoryByAddress"),
80 Self::TesterPresent => write!(f, "TesterPresent"),
81 #[cfg(any(feature = "std2006", feature = "std2013"))]
82 Self::AccessTimingParam => write!(f, "AccessTimingParam"),
83 Self::SecuredDataTrans => write!(f, "SecuredDataTransmission"),
84 Self::CtrlDTCSetting => write!(f, "ControlDTCSetting"),
85 Self::ResponseOnEvent => write!(f, "ResponseOnEvent"),
86 Self::LinkCtrl => write!(f, "LinkControl"),
87 Self::NRC => write!(f, "Negative Response with Code"),
88 }
89 }
90}
91
92pub type SecurityAlgo = fn(u8, Vec<u8>, Vec<u8>) -> Result<Option<Vec<u8>>, Error>;
108
109#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
110pub enum ByteOrder {
111 Big,
112 Little,
113 Native,
114}
115
116#[derive(Debug, Copy, Clone)]
118pub struct Placeholder;
119
120impl TryFrom<u8> for Placeholder{
121 type Error = Error;
122 #[inline]
123 fn try_from(_: u8) -> Result<Self, Self::Error> {
124 Ok(Self)
125 }
126}
127
128impl Into<u8> for Placeholder {
129 fn into(self) -> u8 {
130 panic!("The placeholder sub-function is `None`. Should not call this!");
131 }
132}
133
134#[derive(Clone)]
135pub struct Configuration {
136 pub security_algo: Option<SecurityAlgo>,
137 pub did_cfg: HashMap<DataIdentifier, usize>,
138 pub bo_addr: ByteOrder,
139 pub bo_mem_size: ByteOrder,
140}
141
142impl Default for Configuration {
143 fn default() -> Self {
145 Self {
146 security_algo: None,
147 did_cfg: Default::default(),
148 bo_addr: ByteOrder::Big,
149 bo_mem_size: ByteOrder::Big,
150 }
151 }
152}
153
154pub trait RequestData {
155 type SubFunc;
156 fn try_parse(data: &[u8], sub_func: Option<Self::SubFunc>, cfg: &Configuration) -> Result<Self, Error>
157 where
158 Self: Sized;
159 fn to_vec(self, cfg: &Configuration) -> Vec<u8>;
160}
161
162impl RequestData for Vec<u8> {
163 type SubFunc = Placeholder;
164 #[inline]
165 fn try_parse(data: &[u8], _: Option<Self::SubFunc>, _: &Configuration) -> Result<Self, Error> {
166 Ok(data.to_vec())
167 }
168 #[inline]
169 fn to_vec(self, _: &Configuration) -> Vec<u8> {
170 self
171 }
172}
173
174pub trait ResponseData {
175 type SubFunc;
176 fn try_parse(data: &[u8], sub_func: Option<Self::SubFunc>, cfg: &Configuration) -> Result<Self, Error>
177 where
178 Self: Sized;
179 fn to_vec(self, cfg: &Configuration) -> Vec<u8>;
180}
181
182impl ResponseData for Vec<u8> {
183 type SubFunc = Placeholder;
184 #[inline]
185 fn try_parse(data: &[u8], _: Option<Self::SubFunc>, _: &Configuration) -> Result<Self, Error> {
186 Ok(data.to_vec())
187 }
188 #[inline]
189 fn to_vec(self, _: &Configuration) -> Vec<u8> {
190 self
191 }
192}
193