iso14229_1/
lib.rs

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    /// the service marked with `✅` is completed.
16    ///
17    /// the service marked with `⭕` is partially completed.
18    ///
19    /// The service marked with `❌` is not implemented.
20    pub enum Service {
21        SessionCtrl = 0x10,         // ✅
22        ECUReset = 0x11,            // ✅
23        ClearDiagnosticInfo = 0x14, // ✅
24        ReadDTCInfo = 0x19,         // ⭕
25        ReadDID = 0x22,             // ✅
26        ReadMemByAddr = 0x23,       // ✅
27        ReadScalingDID = 0x24,      // ✅
28        SecurityAccess = 0x27,      // ✅
29        CommunicationCtrl = 0x28,   // ✅
30        #[cfg(any(feature = "std2020"))]
31        Authentication = 0x29,      // ✅
32        ReadDataByPeriodId = 0x2A,  // ✅
33        DynamicalDefineDID = 0x2C,  // ✅
34        WriteDID = 0x2E,            // ✅
35        IOCtrl = 0x2F,              // ✅
36        RoutineCtrl = 0x31,         // ✅
37        RequestDownload = 0x34,     // ✅
38        RequestUpload = 0x35,       // ✅
39        TransferData = 0x36,        // ✅
40        RequestTransferExit = 0x37, // ✅
41        #[cfg(any(feature = "std2013", feature = "std2020"))]
42        RequestFileTransfer = 0x38, // ✅
43        WriteMemByAddr = 0x3D,      // ✅
44        TesterPresent = 0x3E,       // ✅
45        #[cfg(any(feature = "std2006", feature = "std2013"))]
46        AccessTimingParam = 0x83,   // ✅
47        SecuredDataTrans = 0x84,    // ✅
48        CtrlDTCSetting = 0x85,      // ✅
49        ResponseOnEvent = 0x86,     // ❌
50        LinkCtrl = 0x87,            // ✅
51        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
92/// SecurityAlgo
93///
94/// # Params
95///
96/// #1 level of security
97///
98/// #2 seed
99///
100/// #3 salt or other params
101///
102/// # Return
103///
104/// if all seed is 0x00, return None
105/// else all seed is not 0xFF return algo data,
106/// otherwise return Error
107pub 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/// The sub-function placeholder
117#[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    /// ISO 14229-2 default using big-endian.
144    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