Skip to main content

ace_uds/message/services/
security_access.rs

1use crate::{UdsError, ValidationError};
2use ace_core::{DiagError, FrameWrite};
3use ace_macros::{FrameCodec, FrameRead, FrameWrite};
4
5#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
6pub enum SecurityAccessRequest<'a> {
7    RequestSeed(RequestSeed<'a>),
8    SendKey(SendKey<'a>),
9    IsoSaeReserved(u8),
10    IsoSaeReservedRequestSeed(RequestSeed<'a>),
11    IsoSaeReservedSendKey(SendKey<'a>),
12    PyroTechnicSecurityRequestSeed(RequestSeed<'a>),
13    PyroTechnicSecuritySendKey(SendKey<'a>),
14    SystemSupplierSpecificRequestSeed(RequestSeed<'a>),
15    SystemSupplierSpecificSendKey(SendKey<'a>),
16}
17
18#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, FrameRead, FrameWrite)]
19#[frame(error = UdsError)]
20pub struct RequestSeed<'a> {
21    pub request_seed: u8,
22    pub security_access_data_record: &'a [u8],
23}
24
25#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, FrameRead, FrameWrite)]
26#[frame(error = UdsError)]
27pub struct SendKey<'a> {
28    pub send_key: u8,
29    pub security_key: &'a [u8],
30}
31
32#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
33pub enum SecurityAccessResponse<'a> {
34    KeyResponse(u8),
35    SeedResponse(SeedResponse<'a>),
36}
37
38#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, FrameCodec)]
39#[frame(error = UdsError)]
40pub struct SeedResponse<'a> {
41    pub security_access_type: u8,
42    pub security_seed: &'a [u8],
43}
44
45impl<'a> ace_core::codec::FrameRead<'a> for SecurityAccessResponse<'a> {
46    type Error = UdsError;
47
48    fn decode(buf: &mut &'a [u8]) -> Result<Self, Self::Error> {
49        let access_type = *buf
50            .first()
51            .ok_or(UdsError::from(DiagError::LengthMismatch {
52                expected: 1,
53                actual: 0,
54            }))?;
55
56        if access_type % 2 == 1 {
57            Ok(Self::SeedResponse(SeedResponse::decode(buf)?))
58        } else {
59            Ok(Self::KeyResponse(access_type))
60        }
61    }
62}
63
64impl<'a> ace_core::codec::FrameRead<'a> for SecurityAccessRequest<'a> {
65    type Error = UdsError;
66
67    fn decode(buf: &mut &'a [u8]) -> Result<Self, Self::Error> {
68        let access_type = *buf
69            .first()
70            .ok_or(UdsError::from(DiagError::LengthMismatch {
71                expected: 1,
72                actual: 0,
73            }))?;
74
75        match access_type {
76            0x00 | 0x7F => Ok(Self::IsoSaeReserved(access_type)),
77            0x43..=0x5E if access_type % 2 == 1 => {
78                Ok(Self::IsoSaeReservedRequestSeed(RequestSeed::decode(buf)?))
79            }
80            0x43..=0x5E if access_type % 2 == 0 => {
81                Ok(Self::IsoSaeReservedSendKey(SendKey::decode(buf)?))
82            }
83            0x01..=0x41 if access_type % 2 == 1 => Ok(Self::RequestSeed(RequestSeed::decode(buf)?)),
84            0x02..=0x42 if access_type % 2 == 0 => Ok(Self::SendKey(SendKey::decode(buf)?)),
85            0x5F => Ok(Self::PyroTechnicSecurityRequestSeed(RequestSeed::decode(
86                buf,
87            )?)),
88            0x60 => Ok(Self::PyroTechnicSecuritySendKey(SendKey::decode(buf)?)),
89            0x61..=0x7E if access_type % 2 == 1 => Ok(Self::SystemSupplierSpecificRequestSeed(
90                RequestSeed::decode(buf)?,
91            )),
92            0x61..=0x7E if access_type % 2 == 0 => {
93                Ok(Self::SystemSupplierSpecificSendKey(SendKey::decode(buf)?))
94            }
95            _ => Err(UdsError::Validation(
96                ValidationError::InvalidSecurityAccessType(access_type),
97            )),
98        }
99    }
100}
101
102impl FrameWrite for SecurityAccessResponse<'_> {
103    type Error = UdsError;
104
105    fn encode<W: ace_core::codec::Writer>(&self, buf: &mut W) -> Result<(), Self::Error> {
106        match self {
107            Self::SeedResponse(inner) => Ok(inner.encode(buf)?),
108            Self::KeyResponse(inner) => Ok(inner.encode(buf)?),
109        }
110    }
111}
112
113impl FrameWrite for SecurityAccessRequest<'_> {
114    type Error = UdsError;
115
116    fn encode<W: ace_core::codec::Writer>(&self, buf: &mut W) -> Result<(), Self::Error> {
117        match self {
118            Self::RequestSeed(inner)
119            | Self::PyroTechnicSecurityRequestSeed(inner)
120            | Self::SystemSupplierSpecificRequestSeed(inner)
121            | Self::IsoSaeReservedRequestSeed(inner) => inner.encode(buf),
122            Self::SendKey(inner)
123            | Self::SystemSupplierSpecificSendKey(inner)
124            | Self::PyroTechnicSecuritySendKey(inner)
125            | Self::IsoSaeReservedSendKey(inner) => inner.encode(buf),
126            Self::IsoSaeReserved(inner) => Ok(inner.encode(buf)?),
127        }
128    }
129}