1mod context;
2mod service;
3mod session;
4mod util;
5
6use crate::{constants::LOG_TAG_SERVER, server::session::SessionManager, DoCanError, SecurityAlgo};
7use iso14229_1::{response::SessionTiming, Configuration, DataIdentifier};
8use rsutil::types::ByteOrder;
9use serde::{Deserialize, Deserializer};
10use std::collections::HashMap;
11
12use iso14229_1::{
13 request::Request,
14 response::{Code, Response},
15 Iso14229Error, Service,
16};
17use iso15765_2::{
18 can::{Address, AddressType, CanIsoTp},
19 IsoTp, IsoTpError,
20};
21use rs_can::{CanDevice, CanFrame};
22use std::{fmt::Display, sync::Arc};
23use tokio::{spawn, task::JoinHandle};
24
25pub type DidSaLevel = HashMap<DataIdentifier, u8>;
26
27fn did_sa_level_deserialize<'de, D>(deserializer: D) -> Result<DidSaLevel, D::Error>
28where
29 D: Deserializer<'de>,
30{
31 let raw_map: HashMap<u16, u8> = HashMap::deserialize(deserializer)?;
32
33 let res = raw_map
34 .into_iter()
35 .map(|(k, v)| (DataIdentifier::from(k), v))
36 .collect::<HashMap<_, _>>();
37
38 Ok(res)
39}
40
41#[allow(unused)]
42#[derive(Debug, Clone, Deserialize)]
43pub struct Config {
44 pub(crate) address: Address,
45 pub(crate) timing: SessionTiming,
46 pub(crate) extend_sa_level: u8,
48 pub(crate) program_sa_level: u8,
50 pub(crate) seed_len: usize,
51 pub(crate) sa_salt: Vec<u8>,
52 pub(crate) cfg: Configuration,
53 #[serde(deserialize_with = "did_sa_level_deserialize")]
54 pub(crate) did_sa_level: DidSaLevel,
55 pub(crate) byte_order: ByteOrder,
56}
57
58#[async_trait::async_trait]
59pub trait Server {
60 async fn update_address(&self, address: Address);
61 async fn update_security_algo(&self, algo: SecurityAlgo);
62 async fn service_forever(&mut self, interval_us: u64);
63
64 async fn service_stop(&mut self);
65}
66
67#[derive(Clone)]
68pub struct DoCanServer<D, C, F> {
69 isotp: CanIsoTp<D, C, F>,
70 session: SessionManager,
71 context: context::Context,
72 handles: Vec<Arc<JoinHandle<()>>>,
73}
74
75impl<D, C, F> DoCanServer<D, C, F>
76where
77 D: CanDevice<Channel = C, Frame = F> + Clone + Send + 'static,
78 C: Clone + Eq + Display + Send + Sync + 'static,
79 F: CanFrame<Channel = C> + Clone + Display + 'static,
80{
81 pub async fn new(device: D, channel: C) -> Result<Self, DoCanError> {
82 let context = context::Context::new().await?;
83 Ok(Self {
84 isotp: CanIsoTp::new(device, channel, context.config.address, true).await,
85 session: SessionManager::new(None),
86 context,
87 handles: Default::default(),
88 })
89 }
90
91 #[inline(always)]
92 pub fn tp_layer(&mut self) -> CanIsoTp<D, C, F> {
93 self.isotp.clone()
94 }
95
96 async fn server(&mut self) {
97 loop {
98 let timing = self.context.get_active_timing().await;
99 let cfg = self.context.get_cfg().clone();
100 if let Ok(data) = self.isotp.wait_data(timing.p2_ms()).await {
101 match data.len() {
103 0 => {}
104 _ => match Service::try_from(data[0]) {
105 Ok(service) => match Request::try_from((service, &data[1..], &cfg)) {
106 Ok(req) => {
107 if let Err(e) = match service {
108 Service::SessionCtrl => {
109 self.session_ctrl(req, &cfg, timing.into()).await
110 }
111 Service::ECUReset => self.ecu_reset(req, &cfg).await,
112 Service::ClearDiagnosticInfo => {
113 self.clear_diagnostic_info(req, &cfg).await
114 }
115 Service::ReadDTCInfo => self.read_dtc_info(req, &cfg).await,
116 Service::ReadDID => self.read_did(req, &cfg).await,
117 Service::ReadMemByAddr => {
118 self.read_mem_by_addr(req, &cfg).await
119 }
120 Service::ReadScalingDID => {
121 self.read_scaling_did(req, &cfg).await
122 }
123 Service::SecurityAccess => {
124 self.security_access(req, &cfg).await
125 }
126 Service::CommunicationCtrl => {
127 self.communication_ctrl(req, &cfg).await
128 }
129 #[cfg(any(feature = "std2020"))]
130 Service::Authentication => self.authentication(req, &cfg).await,
131 Service::ReadDataByPeriodId => {
132 self.read_data_by_pid(req, &cfg).await
133 }
134 Service::DynamicalDefineDID => {
135 self.dynamically_define_did(req, &cfg).await
136 }
137 Service::WriteDID => self.write_did(req, &cfg).await,
138 Service::IOCtrl => self.io_ctrl(req, &cfg).await,
139 Service::RoutineCtrl => self.routine_ctrl(req, &cfg).await,
140 Service::RequestDownload => {
141 self.request_download(req, &cfg).await
142 }
143 Service::RequestUpload => self.request_upload(req, &cfg).await,
144 Service::TransferData => self.transfer_data(req, &cfg).await,
145 Service::RequestTransferExit => {
146 self.request_transfer_exit(req, &cfg).await
147 }
148 #[cfg(any(feature = "std2013", feature = "std2020"))]
149 Service::RequestFileTransfer => {
150 self.request_file_transfer(req, &cfg).await
151 }
152 Service::WriteMemByAddr => {
153 self.write_mem_by_addr(req, &cfg).await
154 }
155 Service::TesterPresent => self.tester_present(req, &cfg).await,
156 #[cfg(any(feature = "std2006", feature = "std2013"))]
157 Service::AccessTimingParam => {
158 self.access_timing_parameter(req, &cfg).await
159 }
160 Service::SecuredDataTrans => {
161 self.secured_data_trans(req, &cfg).await
162 }
163 Service::CtrlDTCSetting => {
164 self.ctrl_dtc_setting(req, &cfg).await
165 }
166 Service::ResponseOnEvent => {
167 self.response_on_event(req, &cfg).await
168 }
169 Service::LinkCtrl => self.link_ctrl(req, &cfg).await,
170 Service::NRC => {
171 self.negative_service(
172 Service::NRC.into(),
173 Code::ServiceNotSupported,
174 )
175 .await;
176 Ok(())
177 }
178 } {
179 self.process_uds_error(service, e).await;
180 }
181 }
182 Err(e) => {
183 rsutil::warn!(
184 "{} error: {} when data: {} to request",
185 LOG_TAG_SERVER,
186 e,
187 hex::encode(&data)
188 );
189 self.process_uds_error(service, e).await;
190 }
191 },
192 Err(_) => {
193 self.negative_service(data[0], Code::ServiceNotSupported)
195 .await
196 }
197 },
198 }
199 }
200 }
201 }
202
203 async fn negative_service(&self, service: u8, code: Code) {
204 let data = vec![Service::NRC.into(), service, code.into()];
205 if let Err(e) = self.isotp.transmit(AddressType::Physical, data).await {
206 rsutil::error!(
207 "{} can't transmit negative response, because of: {}",
208 LOG_TAG_SERVER,
209 e
210 );
211 }
212 }
213
214 async fn process_uds_error(&self, service: Service, e: Iso14229Error) {
215 let code = match e {
216 Iso14229Error::InvalidDataLength { .. } => Code::IncorrectMessageLengthOrInvalidFormat,
219 Iso14229Error::ServiceError(_) => Code::ConditionsNotCorrect,
225 _ => Code::GeneralReject, };
229 self.transmit_response(Response::new_negative(service, code), true)
230 .await;
231 }
232
233 pub(crate) async fn transmit_response(&self, resp: Response, flag: bool) {
234 let service = resp.service();
235 let data: Vec<_> = resp.into();
236 if let Err(e) = self.isotp.transmit(AddressType::Physical, data).await {
237 rsutil::warn!("{} transmit error: {:?}", LOG_TAG_SERVER, e);
238 if !flag {
239 return;
241 }
242
243 if let Some(code) = match e {
244 IsoTpError::EmptyPdu => Some(Code::IncorrectMessageLengthOrInvalidFormat),
246 IsoTpError::InvalidPdu(_) => Some(Code::GeneralReject),
247 IsoTpError::InvalidParam(_) => Some(Code::GeneralReject),
248 IsoTpError::InvalidDataLength { .. } => {
249 Some(Code::IncorrectMessageLengthOrInvalidFormat)
250 }
251 IsoTpError::LengthOutOfRange(_) => Some(Code::RequestOutOfRange),
252 IsoTpError::InvalidStMin(_) => Some(Code::GeneralReject),
253 IsoTpError::InvalidSequence { .. } => Some(Code::WrongBlockSequenceCounter),
254 IsoTpError::MixFramesError => Some(Code::GeneralReject),
255 IsoTpError::Timeout { .. } => Some(Code::GeneralReject),
256 IsoTpError::OverloadFlow => Some(Code::RequestOutOfRange),
257 _ => None,
258 } {
259 let resp = Response::new_negative(service, code);
260 Box::pin(self.transmit_response(resp, false)).await;
261 }
262 }
263 }
264}
265
266#[async_trait::async_trait]
267impl<D, C, F> Server for DoCanServer<D, C, F>
268where
269 D: CanDevice<Channel = C, Frame = F> + Clone + Send + 'static,
270 C: Clone + Eq + Display + Send + Sync + 'static,
271 F: CanFrame<Channel = C> + Clone + Display + 'static,
272{
273 #[inline(always)]
274 async fn update_address(&self, address: Address) {
275 self.isotp.update_address(address).await;
276 }
277
278 #[inline(always)]
279 async fn update_security_algo(&self, algo: SecurityAlgo) {
280 self.context.set_security_algo(algo).await;
281 }
282
283 async fn service_forever(&mut self, interval_us: u64) {
284 self.isotp.start(interval_us).await;
285 let mut clone = self.clone();
286 let session = self.session.clone();
287 let handle = spawn(async move { session.work().await });
288 self.handles.push(Arc::new(handle));
289 let handle = spawn(async move { clone.server().await });
290 self.handles.push(Arc::new(handle));
291 }
292
293 async fn service_stop(&mut self) {
294 self.isotp.stop().await;
295 for handle in &self.handles {
296 handle.abort();
297 }
298 rsutil::info!("{} stopped", LOG_TAG_SERVER);
299 }
300}