1use crate::{
2 client::{Client, DoCanClient},
3 error::DoCanError,
4 SecurityAlgo,
5};
6use iso14229_1::{
7 request::{self, Request},
8 response,
9 utils::U24,
10 *,
11};
12use iso15765_2::can::{Address, AddressType};
13use rs_can::{CanDevice, CanFrame, CanResult};
14use std::{fmt::Display, hash::Hash, time::Duration};
15use tokio::time::sleep;
16
17#[async_trait::async_trait]
18impl<D, C, F> Client for DoCanClient<D, C, F>
19where
20 D: CanDevice<Channel = C, Frame = F> + Clone + Send + 'static,
21 C: Display + Clone + Hash + Eq + Send + Sync + 'static,
22 F: CanFrame<Channel = C> + Clone + Display + 'static,
23{
24 async fn update_address(&self, address: Address) {
25 self.isotp.update_address(address).await;
26 }
27
28 async fn update_security_algo(&self, algo: SecurityAlgo) {
29 self.context.set_security_algo(algo).await;
30 }
31
32 async fn add_data_identifier(&self, did: DataIdentifier, length: usize) {
33 self.context.add_did(did, length).await;
34 }
35
36 async fn remove_data_identifier(&self, did: DataIdentifier) {
37 self.context.remove_did(&did).await;
38 }
39
40 async fn session_ctrl(
41 &mut self,
42 r#type: SessionType,
43 suppress_positive: bool,
44 addr_type: AddressType,
45 ) -> CanResult<(), DoCanError> {
46 let service = Service::SessionCtrl;
47 let mut sub_func: u8 = r#type.into();
48 if suppress_positive {
49 sub_func |= SUPPRESS_POSITIVE;
50 }
51 let cfg = self.context.get_did_cfg().await;
52 let request = Request::new(service, Some(sub_func), vec![], &cfg)
53 .map_err(DoCanError::Iso14229Error)?;
54
55 let timing = match self
56 .suppress_positive_sr(addr_type, request, suppress_positive, &cfg)
57 .await?
58 {
59 Some(resp) => {
60 Self::sub_func_check(&resp, r#type.into(), service)?;
61
62 Some(
63 resp.data::<response::SessionCtrl>(&cfg)
64 .map_err(DoCanError::Iso14229Error)?
65 .0,
66 )
67 }
68 None => None,
69 };
70
71 if let Some(timing) = timing {
72 self.context.set_session_timing(timing).await;
73 }
74
75 Ok(())
76 }
77
78 async fn ecu_reset(
79 &mut self,
80 r#type: ECUResetType,
81 suppress_positive: bool,
82 addr_type: AddressType,
83 ) -> CanResult<(), DoCanError> {
84 let service = Service::ECUReset;
85 let mut sub_func: u8 = r#type.into();
86 if suppress_positive {
87 sub_func |= SUPPRESS_POSITIVE;
88 }
89 let cfg = self.context.get_did_cfg().await;
90 let request = Request::new(service, Some(sub_func), vec![], &cfg)
91 .map_err(DoCanError::Iso14229Error)?;
92
93 if let Some(response) = self
94 .suppress_positive_sr(addr_type, request, suppress_positive, &cfg)
95 .await?
96 {
97 Self::sub_func_check(&response, r#type.into(), service)?;
98
99 let resp = response
100 .data::<response::ECUReset>(&cfg)
101 .map_err(DoCanError::Iso14229Error)?;
102 if let Some(seconds) = resp.second {
103 sleep(Duration::from_secs(seconds as u64)).await;
104 }
105 }
106
107 Ok(())
108 }
109
110 async fn security_access(
111 &mut self,
112 level: u8,
113 params: Vec<u8>,
114 ) -> CanResult<Vec<u8>, DoCanError> {
115 let service = Service::SecurityAccess;
116 let cfg = self.context.get_did_cfg().await;
117 let request =
118 Request::new(service, Some(level), params, &cfg).map_err(DoCanError::Iso14229Error)?;
119
120 let response = self
121 .send_and_response(AddressType::Physical, request, &cfg)
122 .await?;
123
124 Self::sub_func_check(&response, level, service)?;
125
126 Ok(response.raw_data().to_vec())
127 }
128
129 async fn unlock_security_access(
130 &mut self,
131 level: u8,
132 params: Vec<u8>,
133 salt: Vec<u8>,
134 ) -> CanResult<(), DoCanError> {
135 let service = Service::SecurityAccess;
136 let cfg = self.context.get_did_cfg().await;
137 let req =
138 Request::new(service, Some(level), params, &cfg).map_err(DoCanError::Iso14229Error)?;
139
140 let resp = self
141 .send_and_response(AddressType::Physical, req, &cfg)
142 .await?;
143 Self::sub_func_check(&resp, level, service)?;
144
145 let seed = resp.raw_data().to_vec();
146 let algo = self
147 .context
148 .get_security_algo()
149 .await
150 .ok_or_else(|| DoCanError::OtherError("security algorithm required".into()))?;
151 match algo(level, &seed, &salt)? {
152 Some(data) => {
153 let request = Request::new(service, Some(level + 1), data, &cfg)
154 .map_err(DoCanError::Iso14229Error)?;
155 let response = self
156 .send_and_response(AddressType::Physical, request, &cfg)
157 .await?;
158
159 Self::sub_func_check(&response, level + 1, service)
160 }
161 None => Ok(()),
162 }
163 }
164
165 async fn communication_control(
166 &mut self,
167 ctrl_type: CommunicationCtrlType,
168 comm_type: CommunicationType,
169 node_id: Option<request::NodeId>,
170 suppress_positive: bool,
171 addr_type: AddressType,
172 ) -> CanResult<(), DoCanError> {
173 let service = Service::CommunicationCtrl;
174 let mut sub_func = ctrl_type.into();
175 if suppress_positive {
176 sub_func |= SUPPRESS_POSITIVE;
177 }
178 let data = request::CommunicationCtrl::new(ctrl_type, comm_type, node_id)
179 .map_err(DoCanError::Iso14229Error)?;
180 let cfg = self.context.get_did_cfg().await;
181 let req = Request::new::<Vec<_>>(service, Some(sub_func), data.into(), &cfg)
182 .map_err(DoCanError::Iso14229Error)?;
183
184 let resp = self
185 .suppress_positive_sr(addr_type, req, suppress_positive, &cfg)
186 .await?;
187
188 if let Some(response) = resp {
189 Self::sub_func_check(&response, ctrl_type.into(), service)?;
190 }
191
192 Ok(())
193 }
194
195 #[cfg(feature = "std2020")]
196 async fn authentication(
197 &mut self,
198 auth_task: AuthenticationTask,
199 data: request::Authentication,
200 ) -> CanResult<response::Authentication, DoCanError> {
201 let service = Service::Authentication;
202 let cfg = self.context.get_did_cfg().await;
203 let request = Request::new::<Vec<_>>(service, Some(auth_task.into()), data.into(), &cfg)
204 .map_err(DoCanError::Iso14229Error)?;
205
206 let response = self
207 .send_and_response(AddressType::Physical, request, &cfg)
208 .await?;
209 Self::sub_func_check(&response, auth_task.into(), service)?;
210
211 response
212 .data::<response::Authentication>(&cfg)
213 .map_err(DoCanError::Iso14229Error)
214 }
215
216 async fn tester_present(
217 &mut self,
218 r#type: TesterPresentType,
219 suppress_positive: bool,
220 addr_type: AddressType,
221 ) -> CanResult<(), DoCanError> {
222 let cfg = self.context.get_did_cfg().await;
223 let (service, request) =
224 Self::tester_present_request(r#type, suppress_positive, &cfg).await?;
225
226 let response = self
227 .suppress_positive_sr(addr_type, request, suppress_positive, &cfg)
228 .await?;
229
230 if let Some(response) = response {
231 Self::sub_func_check(&response, r#type.into(), service)?;
232 }
233
234 Ok(())
235 }
236
237 #[cfg(any(feature = "std2006", feature = "std2013"))]
238 async fn access_timing_parameter(
239 &mut self,
240 r#type: request::TimingParameterAccessType,
241 parameter: Vec<u8>,
242 suppress_positive: bool,
243 ) -> CanResult<Option<response::AccessTimingParameter>, DoCanError> {
244 let service = Service::AccessTimingParam;
245 let mut sub_func = r#type.into();
246 if suppress_positive {
247 sub_func |= SUPPRESS_POSITIVE;
248 }
249 let cfg = self.context.get_did_cfg().await;
250 let request = Request::new(service, Some(sub_func), parameter, &cfg)
251 .map_err(DoCanError::Iso14229Error)?;
252
253 let response = self
254 .suppress_positive_sr(AddressType::Physical, request, suppress_positive, &cfg)
255 .await?;
256
257 match response {
258 Some(v) => {
259 Self::sub_func_check(&v, r#type.into(), service)?;
260 Ok(Some(v.data(&cfg).map_err(DoCanError::Iso14229Error)?))
261 }
262 None => Ok(None),
263 }
264 }
265
266 async fn secured_data_transmit(
267 &mut self,
268 apar: AdministrativeParameter,
269 signature: SignatureEncryptionCalculation,
270 anti_replay_cnt: u16,
271 service: u8,
272 service_data: Vec<u8>,
273 signature_data: Vec<u8>,
274 ) -> CanResult<response::SecuredDataTrans, DoCanError> {
275 let data = request::SecuredDataTrans::new(
276 apar,
277 signature,
278 anti_replay_cnt,
279 service,
280 service_data,
281 signature_data,
282 )
283 .map_err(DoCanError::Iso14229Error)?;
284 let cfg = self.context.get_did_cfg().await;
285 let request = Request::new::<Vec<_>>(Service::SecuredDataTrans, None, data.into(), &cfg)
286 .map_err(DoCanError::Iso14229Error)?;
287
288 let response = self
289 .send_and_response(AddressType::Physical, request, &cfg)
290 .await?;
291
292 response
293 .data::<response::SecuredDataTrans>(&cfg)
294 .map_err(DoCanError::Iso14229Error)
295 }
296
297 async fn control_dtc_setting(
298 &mut self,
299 r#type: DTCSettingType,
300 parameter: Vec<u8>,
301 suppress_positive: bool,
302 ) -> CanResult<(), DoCanError> {
303 let service = Service::CtrlDTCSetting;
304 let mut sub_func = r#type.into();
305 if suppress_positive {
306 sub_func |= SUPPRESS_POSITIVE;
307 }
308 let cfg = self.context.get_did_cfg().await;
309 let request = Request::new(service, Some(sub_func), parameter, &cfg)
310 .map_err(DoCanError::Iso14229Error)?;
311
312 let response = self
313 .suppress_positive_sr(AddressType::Physical, request, suppress_positive, &cfg)
314 .await?;
315
316 if let Some(response) = response {
317 Self::sub_func_check(&response, r#type.into(), service)?;
318 }
319
320 Ok(())
321 }
322
323 async fn response_on_event(&mut self) -> CanResult<(), DoCanError> {
324 Err(DoCanError::NotImplement(Service::ResponseOnEvent))
325 }
326
327 async fn link_control(
328 &mut self,
329 r#type: LinkCtrlType,
330 data: request::LinkCtrl,
331 suppress_positive: bool,
332 ) -> CanResult<(), DoCanError> {
333 let service = Service::LinkCtrl;
334 let mut sub_func = r#type.into();
335 if suppress_positive {
336 sub_func |= SUPPRESS_POSITIVE;
337 }
338 let cfg = self.context.get_did_cfg().await;
339 let request = Request::new::<Vec<_>>(service, Some(sub_func), data.into(), &cfg)
340 .map_err(DoCanError::Iso14229Error)?;
341
342 let response = self
343 .suppress_positive_sr(AddressType::Physical, request, suppress_positive, &cfg)
344 .await?;
345
346 if let Some(response) = response {
347 Self::sub_func_check(&response, r#type.into(), service)?;
348 }
349
350 Ok(())
351 }
352
353 async fn read_data_by_identifier(
354 &mut self,
355 did: DataIdentifier,
356 others: Vec<DataIdentifier>,
357 ) -> CanResult<response::ReadDID, DoCanError> {
358 let data = request::ReadDID::new(did, others);
359 let cfg = self.context.get_did_cfg().await;
360 let request = Request::new::<Vec<_>>(Service::ReadDID, None, data.into(), &cfg)
361 .map_err(DoCanError::Iso14229Error)?;
362
363 let response = self
364 .send_and_response(AddressType::Physical, request, &cfg)
365 .await?;
366
367 response
368 .data::<response::ReadDID>(&cfg)
369 .map_err(DoCanError::Iso14229Error)
370 }
371
372 async fn read_memory_by_address(
373 &mut self,
374 mem_loc: MemoryLocation,
375 ) -> CanResult<Vec<u8>, DoCanError> {
376 let data = request::ReadMemByAddr(mem_loc);
377 let cfg = self.context.get_did_cfg().await;
378 let request = Request::new::<Vec<_>>(Service::ReadMemByAddr, None, data.into(), &cfg)
379 .map_err(DoCanError::Iso14229Error)?;
380
381 let response = self
382 .send_and_response(AddressType::Physical, request, &cfg)
383 .await?;
384
385 Ok(response.raw_data().to_vec())
386 }
387
388 async fn read_scaling_data_by_identifier(
389 &mut self,
390 did: DataIdentifier,
391 ) -> CanResult<response::ReadScalingDID, DoCanError> {
392 let data = request::ReadScalingDID(did);
393 let cfg = self.context.get_did_cfg().await;
394 let request = Request::new::<Vec<_>>(Service::ReadScalingDID, None, data.into(), &cfg)
395 .map_err(DoCanError::Iso14229Error)?;
396
397 let response = self
398 .send_and_response(AddressType::Physical, request, &cfg)
399 .await?;
400
401 response
402 .data::<response::ReadScalingDID>(&cfg)
403 .map_err(DoCanError::Iso14229Error)
404 }
405
406 async fn read_data_by_period_identifier(
407 &mut self,
408 mode: request::TransmissionMode,
409 did: Vec<u8>,
410 ) -> CanResult<response::ReadDataByPeriodId, DoCanError> {
411 let data =
412 request::ReadDataByPeriodId::new(mode, did).map_err(DoCanError::Iso14229Error)?;
413 let cfg = self.context.get_did_cfg().await;
414 let request = Request::new::<Vec<_>>(Service::ReadDataByPeriodId, None, data.into(), &cfg)
415 .map_err(DoCanError::Iso14229Error)?;
416
417 let response = self
418 .send_and_response(AddressType::Physical, request, &cfg)
419 .await?;
420
421 response
422 .data::<response::ReadDataByPeriodId>(&cfg)
423 .map_err(DoCanError::Iso14229Error)
424 }
425
426 async fn dynamically_define_data_by_identifier(
427 &mut self,
428 r#type: DefinitionType,
429 data: request::DynamicallyDefineDID,
430 suppress_positive: bool,
431 ) -> CanResult<Option<response::DynamicallyDefineDID>, DoCanError> {
432 let service = Service::DynamicalDefineDID;
433 let mut sub_func = r#type.into();
434 if suppress_positive {
435 sub_func |= SUPPRESS_POSITIVE;
436 }
437 let cfg = self.context.get_did_cfg().await;
438 let request = Request::new::<Vec<_>>(service, Some(sub_func), data.into(), &cfg)
439 .map_err(DoCanError::Iso14229Error)?;
440
441 let response = self
442 .suppress_positive_sr(AddressType::Physical, request, suppress_positive, &cfg)
443 .await?;
444
445 match response {
446 Some(v) => {
447 Self::sub_func_check(&v, r#type.into(), service)?;
448 Ok(Some(v.data(&cfg).map_err(DoCanError::Iso14229Error)?))
449 }
450 None => Ok(None),
451 }
452 }
453
454 async fn write_data_by_identifier(
455 &mut self,
456 did: DataIdentifier,
457 data: Vec<u8>,
458 ) -> CanResult<(), DoCanError> {
459 let data = request::WriteDID(DIDData { did, data });
460 let cfg = self.context.get_did_cfg().await;
461 let request = Request::new::<Vec<_>>(Service::WriteDID, None, data.into(), &cfg)
462 .map_err(DoCanError::Iso14229Error)?;
463
464 let _ = self
465 .send_and_response(AddressType::Physical, request, &cfg)
466 .await?;
467
468 Ok(())
469 }
470
471 async fn write_memory_by_address(
472 &mut self,
473 alfi: AddressAndLengthFormatIdentifier,
474 mem_addr: u128,
475 mem_size: u128,
476 record: Vec<u8>,
477 ) -> CanResult<response::WriteMemByAddr, DoCanError> {
478 let data = request::WriteMemByAddr::new(alfi, mem_addr, mem_size, record)
479 .map_err(DoCanError::Iso14229Error)?;
480 let cfg = self.context.get_did_cfg().await;
481 let request = Request::new::<Vec<_>>(Service::WriteMemByAddr, None, data.into(), &cfg)
482 .map_err(DoCanError::Iso14229Error)?;
483
484 let response = self
485 .send_and_response(AddressType::Physical, request, &cfg)
486 .await?;
487
488 response
489 .data::<response::WriteMemByAddr>(&cfg)
490 .map_err(DoCanError::Iso14229Error)
491 }
492
493 async fn clear_dtc_info(
494 &mut self,
495 group: U24,
496 mem_sel: Option<u8>,
497 addr_type: AddressType,
498 ) -> CanResult<(), DoCanError> {
499 #[cfg(any(feature = "std2020"))]
500 let data = request::ClearDiagnosticInfo::new(group, mem_sel);
501 #[cfg(any(feature = "std2006", feature = "std2013"))]
502 let data = request::ClearDiagnosticInfo::new(group);
503 let cfg = self.context.get_did_cfg().await;
504 let request = Request::new::<Vec<_>>(Service::ClearDiagnosticInfo, None, data.into(), &cfg)
505 .map_err(DoCanError::Iso14229Error)?;
506
507 let _ = self.send_and_response(addr_type, request, &cfg).await?;
508
509 Ok(())
510 }
511
512 async fn read_dtc_info(
513 &mut self,
514 r#type: DTCReportType,
515 data: request::DTCInfo,
516 ) -> CanResult<response::DTCInfo, DoCanError> {
517 let service = Service::ReadDTCInfo;
518 let cfg = self.context.get_did_cfg().await;
519 let request = Request::new::<Vec<_>>(service, Some(r#type.into()), data.into(), &cfg)
520 .map_err(DoCanError::Iso14229Error)?;
521
522 let response = self
523 .send_and_response(AddressType::Physical, request, &cfg)
524 .await?;
525 Self::sub_func_check(&response, r#type.into(), service)?;
526
527 response
528 .data::<response::DTCInfo>(&cfg)
529 .map_err(DoCanError::Iso14229Error)
530 }
531
532 async fn io_control(
533 &mut self,
534 did: DataIdentifier,
535 param: IOCtrlParameter,
536 state: Vec<u8>,
537 mask: Vec<u8>,
538 ) -> CanResult<response::IOCtrl, DoCanError> {
539 let cfg = self.context.get_did_cfg().await;
540 let data = request::IOCtrl::new(did, param, state, mask, &cfg)
541 .map_err(DoCanError::Iso14229Error)?;
542 let request = Request::new::<Vec<_>>(Service::IOCtrl, None, data.into(), &cfg)
543 .map_err(DoCanError::Iso14229Error)?;
544
545 let response = self
546 .send_and_response(AddressType::Physical, request, &cfg)
547 .await?;
548
549 response
550 .data::<response::IOCtrl>(&cfg)
551 .map_err(DoCanError::Iso14229Error)
552 }
553
554 async fn routine_control(
555 &mut self,
556 r#type: RoutineCtrlType,
557 routine_id: u16,
558 option_record: Vec<u8>,
559 ) -> CanResult<response::RoutineCtrl, DoCanError> {
560 let service = Service::RoutineCtrl;
561 let data = request::RoutineCtrl {
562 routine_id: RoutineId(routine_id),
563 option_record,
564 };
565 let cfg = self.context.get_did_cfg().await;
566 let request = Request::new::<Vec<_>>(service, Some(r#type.into()), data.into(), &cfg)
567 .map_err(DoCanError::Iso14229Error)?;
568
569 let response = self
570 .send_and_response(AddressType::Physical, request, &cfg)
571 .await?;
572 Self::sub_func_check(&response, r#type.into(), service)?;
573
574 response
575 .data::<response::RoutineCtrl>(&cfg)
576 .map_err(DoCanError::Iso14229Error)
577 }
578
579 async fn request_download(
580 &mut self,
581 alfi: AddressAndLengthFormatIdentifier,
582 mem_addr: u128,
583 mem_size: u128,
584 dfi: Option<DataFormatIdentifier>,
585 ) -> CanResult<response::RequestDownload, DoCanError> {
586 let data = request::RequestDownload {
587 dfi: dfi.unwrap_or_default(),
588 mem_loc: MemoryLocation::new(alfi, mem_addr, mem_size)
589 .map_err(DoCanError::Iso14229Error)?,
590 };
591 let cfg = self.context.get_did_cfg().await;
592 let request = Request::new::<Vec<_>>(Service::RequestDownload, None, data.into(), &cfg)
593 .map_err(DoCanError::Iso14229Error)?;
594
595 let response = self
596 .send_and_response(AddressType::Physical, request, &cfg)
597 .await?;
598
599 response
600 .data::<response::RequestDownload>(&cfg)
601 .map_err(DoCanError::Iso14229Error)
602 }
603
604 async fn request_upload(
605 &mut self,
606 alfi: AddressAndLengthFormatIdentifier,
607 mem_addr: u128,
608 mem_size: u128,
609 dfi: Option<DataFormatIdentifier>,
610 ) -> CanResult<response::RequestUpload, DoCanError> {
611 let data = request::RequestUpload {
612 dfi: dfi.unwrap_or_default(),
613 mem_loc: MemoryLocation::new(alfi, mem_addr, mem_size)
614 .map_err(DoCanError::Iso14229Error)?,
615 };
616 let cfg = self.context.get_did_cfg().await;
617 let request = Request::new::<Vec<_>>(Service::RequestDownload, None, data.into(), &cfg)
618 .map_err(DoCanError::Iso14229Error)?;
619
620 let response = self
621 .send_and_response(AddressType::Physical, request, &cfg)
622 .await?;
623
624 response
625 .data::<response::RequestUpload>(&cfg)
626 .map_err(DoCanError::Iso14229Error)
627 }
628
629 async fn transfer_data(
630 &mut self,
631 sequence: u8,
632 data: Vec<u8>,
633 ) -> CanResult<response::TransferData, DoCanError> {
634 let data = response::TransferData { sequence, data };
635 let cfg = self.context.get_did_cfg().await;
636 let request = Request::new::<Vec<_>>(Service::TransferData, None, data.into(), &cfg)
637 .map_err(DoCanError::Iso14229Error)?;
638
639 let response = self
640 .send_and_response(AddressType::Physical, request, &cfg)
641 .await?;
642
643 let data = response
644 .data::<response::TransferData>(&cfg)
645 .map_err(DoCanError::Iso14229Error)?;
646
647 if data.sequence != sequence {
648 return Err(DoCanError::UnexpectedTransferSequence {
649 expect: sequence,
650 actual: data.sequence,
651 });
652 }
653
654 Ok(data)
655 }
656
657 async fn request_transfer_exit(
658 &mut self,
659 parameter: Vec<u8>,
660 ) -> CanResult<Vec<u8>, DoCanError> {
661 let cfg = self.context.get_did_cfg().await;
662 let request = Request::new(Service::RequestTransferExit, None, parameter, &cfg)
663 .map_err(DoCanError::Iso14229Error)?;
664
665 let response = self
666 .send_and_response(AddressType::Physical, request, &cfg)
667 .await?;
668
669 Ok(response.raw_data().to_vec())
670 }
671
672 #[cfg(any(feature = "std2013", feature = "std2020"))]
673 async fn request_file_transfer(
674 &mut self,
675 operation: ModeOfOperation,
676 data: request::RequestFileTransfer,
677 ) -> CanResult<response::RequestFileTransfer, DoCanError> {
678 let service = Service::RequestFileTransfer;
679 let sub_func = operation.into();
680 let cfg = self.context.get_did_cfg().await;
681 let request = Request::new::<Vec<_>>(service, Some(sub_func), data.into(), &cfg)
682 .map_err(DoCanError::Iso14229Error)?;
683
684 let response = self
685 .send_and_response(AddressType::Physical, request, &cfg)
686 .await?;
687 Self::sub_func_check(&response, operation.into(), service)?;
688
689 response
690 .data::<response::RequestFileTransfer>(&cfg)
691 .map_err(DoCanError::Iso14229Error)
692 }
693}