Skip to main content

docan_rs/client/service/
security_access.rs

1//! response of Service 27
2
3use crate::{client::DoCanClient, DoCanError, DoCanResult};
4use iso14229_1::Service;
5use iso15765_2::can::AddressType;
6use rs_can::{CanDevice, CanFrame};
7use std::{fmt::Display, hash::Hash};
8
9impl<D, C, F> DoCanClient<D, C, F>
10where
11    D: CanDevice<Channel = C, Frame = F> + Clone + Send + 'static,
12    C: Clone + Eq + Display + Hash + Send + Sync + 'static,
13    F: CanFrame<Channel = C> + Clone + Display + 'static,
14{
15    pub async fn security_access(&mut self, level: u8, params: Vec<u8>) -> DoCanResult<Vec<u8>> {
16        let service = Service::SecurityAccess;
17        let cfg = self.context.get_cfg().await;
18        let request = Self::make_request(service, Some(level), params, &cfg)?;
19
20        let response = self
21            .send_and_response(AddressType::Physical, request, Some((level, service)), &cfg)
22            .await?;
23
24        Ok(response.raw_data().to_vec())
25    }
26
27    pub async fn unlock_security_access(
28        &mut self,
29        level: u8,
30        params: Vec<u8>,
31        salt: Vec<u8>,
32    ) -> DoCanResult<()> {
33        let service = Service::SecurityAccess;
34        let cfg = self.context.get_cfg().await;
35        let req = Self::make_request(service, Some(level), params, &cfg)?;
36
37        let resp = self
38            .send_and_response(AddressType::Physical, req, Some((level, service)), &cfg)
39            .await?;
40
41        let seed = resp.raw_data().to_vec();
42        let algo = self
43            .context
44            .get_security_algo()
45            .await
46            .ok_or_else(|| DoCanError::OtherError("security algorithm required".into()))?;
47        match algo(level, &seed, &salt)? {
48            Some(data) => {
49                let request = Self::make_request(service, Some(level + 1), data, &cfg)?;
50                let _ = self
51                    .send_and_response(
52                        AddressType::Physical,
53                        request,
54                        Some((level + 1, service)),
55                        &cfg,
56                    )
57                    .await?;
58
59                Ok(())
60            }
61            None => Ok(()),
62        }
63    }
64}