docan_rs/client/
synchronous.rs

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 source: u8 = session_type.into();
142                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}