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