docan_rs/server/server_impl/
mod.rs1mod service;
2
3use crate::{
4 constants::LOG_TAG_SERVER,
5 server::{context, session::SessionManager},
6 DoCanError, SecurityAlgo, Server,
7};
8use iso14229_1::{
9 request::Request,
10 response::{Code, Response},
11 Iso14229Error, Service,
12};
13use iso15765_2::{Address, AddressType, CanIsoTp, IsoTp, IsoTpError};
14use rs_can::{CanDevice, CanFrame};
15use std::{fmt::Display, sync::Arc};
16use tokio::{spawn, task::JoinHandle};
17
18#[derive(Clone)]
19pub struct DoCanServer<D, C, F> {
20 isotp: CanIsoTp<D, C, F>,
21 session: SessionManager,
22 context: context::Context,
23 handles: Vec<Arc<JoinHandle<()>>>,
24}
25
26impl<D, C, F> DoCanServer<D, C, F>
27where
28 D: CanDevice<Channel = C, Frame = F> + Clone + Send + Sync + 'static,
29 C: Clone + Eq + Display + Send + Sync + 'static,
30 F: CanFrame<Channel = C> + Clone + Display + Send + Sync + 'static,
31{
32 pub async fn new(device: D, channel: C) -> Result<Self, DoCanError> {
33 let context = context::Context::new().await?;
34 Ok(Self {
35 isotp: CanIsoTp::new(device, channel, context.config.address, true).await,
36 session: SessionManager::new(None),
37 context,
38 handles: Default::default(),
39 })
40 }
41
42 #[inline(always)]
43 pub fn tp_layer(&mut self) -> CanIsoTp<D, C, F> {
44 self.isotp.clone()
45 }
46
47 async fn server(&mut self) {
48 loop {
49 let timing = self.context.get_timing().clone();
50 let cfg = self.context.get_did_config().clone();
51 if let Ok(data) = self.isotp.wait_data(timing.p2_ms()).await {
52 match data.len() {
54 0 => {}
55 _ => match Service::try_from(data[0]) {
56 Ok(service) => match Request::try_from((service, &data[1..], &cfg)) {
57 Ok(req) => {
58 if let Err(e) = match service {
59 Service::SessionCtrl => {
60 self.session_ctrl(req, &cfg, timing.into()).await
61 }
62 Service::ECUReset => self.ecu_reset(req, &cfg).await,
63 Service::ClearDiagnosticInfo => {
64 self.clear_diagnostic_info(req, &cfg).await
65 }
66 Service::ReadDTCInfo => self.read_dtc_info(req, &cfg).await,
67 Service::ReadDID => self.read_did(req, &cfg).await,
68 Service::ReadMemByAddr => {
69 self.read_mem_by_addr(req, &cfg).await
70 }
71 Service::ReadScalingDID => {
72 self.read_scaling_did(req, &cfg).await
73 }
74 Service::SecurityAccess => {
75 self.security_access(req, &cfg).await
76 }
77 Service::CommunicationCtrl => {
78 self.communication_ctrl(req, &cfg).await
79 }
80 #[cfg(any(feature = "std2020"))]
81 Service::Authentication => self.authentication(req, &cfg).await,
82 Service::ReadDataByPeriodId => {
83 self.read_data_by_pid(req, &cfg).await
84 }
85 Service::DynamicalDefineDID => {
86 self.dynamically_define_did(req, &cfg).await
87 }
88 Service::WriteDID => self.write_did(req, &cfg).await,
89 Service::IOCtrl => self.io_ctrl(req, &cfg).await,
90 Service::RoutineCtrl => self.routine_ctrl(req, &cfg).await,
91 Service::RequestDownload => {
92 self.request_download(req, &cfg).await
93 }
94 Service::RequestUpload => self.request_upload(req, &cfg).await,
95 Service::TransferData => self.transfer_data(req, &cfg).await,
96 Service::RequestTransferExit => {
97 self.request_transfer_exit(req, &cfg).await
98 }
99 #[cfg(any(feature = "std2013", feature = "std2020"))]
100 Service::RequestFileTransfer => {
101 self.request_file_transfer(req, &cfg).await
102 }
103 Service::WriteMemByAddr => {
104 self.write_mem_by_addr(req, &cfg).await
105 }
106 Service::TesterPresent => self.tester_present(req, &cfg).await,
107 #[cfg(any(feature = "std2006", feature = "std2013"))]
108 Service::AccessTimingParam => {
109 self.access_timing_param(req, &cfg).await
110 }
111 Service::SecuredDataTrans => {
112 self.secured_data_trans(req, &cfg).await
113 }
114 Service::CtrlDTCSetting => {
115 self.ctrl_dtc_setting(req, &cfg).await
116 }
117 Service::ResponseOnEvent => {
118 self.response_on_event(req, &cfg).await
119 }
120 Service::LinkCtrl => self.link_ctrl(req, &cfg).await,
121 Service::NRC => {
122 self.negative_service(
123 Service::NRC.into(),
124 Code::ServiceNotSupported,
125 )
126 .await;
127 Ok(())
128 }
129 } {
130 self.process_uds_error(service, e).await;
131 }
132 }
133 Err(e) => {
134 rsutil::warn!(
135 "{} error: {} when data: {} to request",
136 LOG_TAG_SERVER,
137 e,
138 hex::encode(&data)
139 );
140 self.process_uds_error(service, e).await;
141 }
142 },
143 Err(_) => {
144 self.negative_service(data[0], Code::ServiceNotSupported)
146 .await
147 }
148 },
149 }
150 }
151 }
152 }
153
154 async fn negative_service(&self, service: u8, code: Code) {
155 let data = vec![Service::NRC.into(), service, code.into()];
156 if let Err(e) = self.isotp.transmit(AddressType::Physical, data).await {
157 rsutil::error!(
158 "{} can't transmit negative response, because of: {}",
159 LOG_TAG_SERVER,
160 e
161 );
162 }
163 }
164
165 async fn process_uds_error(&self, service: Service, e: Iso14229Error) {
166 let code = match e {
167 Iso14229Error::InvalidDataLength { .. } => Code::IncorrectMessageLengthOrInvalidFormat,
170 Iso14229Error::ServiceError(_) => Code::ConditionsNotCorrect,
176 _ => Code::GeneralReject, };
180 self.transmit_response(Response::new_negative(service, code), true)
181 .await;
182 }
183
184 pub(crate) async fn transmit_response(&self, resp: Response, flag: bool) {
185 let service = resp.service();
186 let data: Vec<_> = resp.into();
187 if let Err(e) = self.isotp.transmit(AddressType::Physical, data).await {
188 rsutil::warn!("{} transmit error: {:?}", LOG_TAG_SERVER, e);
189 if !flag {
190 return;
192 }
193
194 if let Some(code) = match e {
195 IsoTpError::EmptyPdu => Some(Code::IncorrectMessageLengthOrInvalidFormat),
197 IsoTpError::InvalidPdu(_) => Some(Code::GeneralReject),
198 IsoTpError::InvalidParam(_) => Some(Code::GeneralReject),
199 IsoTpError::InvalidDataLength { .. } => {
200 Some(Code::IncorrectMessageLengthOrInvalidFormat)
201 }
202 IsoTpError::LengthOutOfRange(_) => Some(Code::RequestOutOfRange),
203 IsoTpError::InvalidStMin(_) => Some(Code::GeneralReject),
204 IsoTpError::InvalidSequence { .. } => Some(Code::WrongBlockSequenceCounter),
205 IsoTpError::MixFramesError => Some(Code::GeneralReject),
206 IsoTpError::Timeout { .. } => Some(Code::GeneralReject),
207 IsoTpError::OverloadFlow => Some(Code::RequestOutOfRange),
208 _ => None,
209 } {
210 let resp = Response::new_negative(service, code);
211 Box::pin(self.transmit_response(resp, false)).await;
212 }
213 }
214 }
215}
216
217#[async_trait::async_trait]
218impl<D, C, F> Server for DoCanServer<D, C, F>
219where
220 D: CanDevice<Channel = C, Frame = F> + Clone + Send + Sync + 'static,
221 C: Clone + Eq + Display + Send + Sync + 'static,
222 F: CanFrame<Channel = C> + Clone + Display + Send + Sync + 'static,
223{
224 #[inline(always)]
225 async fn update_address(&self, address: Address) {
226 self.isotp.update_address(address).await;
227 }
228
229 #[inline(always)]
230 async fn update_security_algo(&self, algo: SecurityAlgo) {
231 self.context.set_security_algo(algo).await;
232 }
233
234 async fn service_forever(&mut self, interval: u64) {
235 self.isotp.start(interval).await;
236 let mut clone = self.clone();
237 let session = self.session.clone();
238 let handle = spawn(async move { session.work().await });
239 self.handles.push(Arc::new(handle));
240 let handle = spawn(async move { clone.server().await });
241 self.handles.push(Arc::new(handle));
242 }
243
244 async fn service_stop(&mut self) {
245 self.isotp.stop().await;
246 for handle in &self.handles {
247 handle.abort();
248 }
249 rsutil::info!("{} stopped", LOG_TAG_SERVER);
250 }
251}