docan_rs/client/service/
security_access.rs1use 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}