1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
//! Functions for unlocking secure regions on the ECU
use crate::{dynamic_diag::DynamicDiagSession, DiagError, DiagServerResult};
use automotive_diag::kwp2000::KwpCommand;
impl DynamicDiagSession {
/// Requests a seed from the ECU
///
/// ## Parameters
/// * server - The KWP2000 server
/// * access_mode - The access mode. Only odd numbers between 0x01-0x7F are supported for the access level!
///
/// ## Returns
/// This function will return an error if the access_mode parameter is not a valid mode!
/// If the function succeeds, then just the ECUs key response is returned
pub fn kwp_request_seed(&self, access_mode: u8) -> DiagServerResult<Vec<u8>> {
if access_mode % 2 == 0 {
return Err(DiagError::ParameterInvalid);
}
let mut res =
self.send_command_with_response(KwpCommand::SecurityAccess, &[access_mode])?;
res.drain(0..2); // Remove SID and access mode
Ok(res) // Return just the key
}
/// Attempts to unlock the access mode to the ECU, using a computed key using the seed provided with [Kwp2000DiagnosticServer::request_seed]
///
/// ## Parameters
/// * server - The KWP2000 server
/// * access_mode - The access mode. Only odd numbers between 0x01-0x7F are supported for the access level!
///
/// ## Returns
/// This function will return an error if the access_mode parameter is not a valid mode! The access_mode
/// should be THE SAME as what was provided to [Kwp2000DiagnosticServer::request_seed]
pub fn kwp_unlock_ecu_with_key(&self, access_mode: u8, key: &[u8]) -> DiagServerResult<()> {
if access_mode % 2 == 0 {
return Err(DiagError::ParameterInvalid);
}
let mut args = vec![access_mode + 1];
args.extend_from_slice(key);
self.send_command_with_response(KwpCommand::SecurityAccess, &args)?;
Ok(())
}
}