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