uds_protocol/services/
security_access.rs1use crate::{
2 Error, NegativeResponseCode, SecurityAccessType, SingleValueWireFormat,
3 SuppressablePositiveResponse, WireFormat,
4};
5use byteorder::{ReadBytesExt, WriteBytesExt};
6use std::io::{Read, Write};
7
8const SECURITY_ACCESS_NEGATIVE_RESPONSE_CODES: [NegativeResponseCode; 8] = [
10 NegativeResponseCode::SubFunctionNotSupported,
11 NegativeResponseCode::IncorrectMessageLengthOrInvalidFormat,
12 NegativeResponseCode::ConditionsNotCorrect,
13 NegativeResponseCode::RequestSequenceError,
14 NegativeResponseCode::RequestOutOfRange,
15 NegativeResponseCode::InvalidKey,
16 NegativeResponseCode::ExceedNumberOfAttempts,
17 NegativeResponseCode::RequiredTimeDelayNotExpired,
18];
19
20#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
40#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
41#[derive(Clone, Debug, Eq, PartialEq)]
42pub struct SecurityAccessRequest {
43 access_type: SuppressablePositiveResponse<SecurityAccessType>,
44 request_data: Vec<u8>,
45}
46
47impl SecurityAccessRequest {
48 pub(crate) fn new(
50 suppress_positive_response: bool,
51 access_type: SecurityAccessType,
52 request_data: Vec<u8>,
53 ) -> Self {
54 Self {
55 access_type: SuppressablePositiveResponse::new(suppress_positive_response, access_type),
56 request_data,
57 }
58 }
59
60 #[must_use]
62 pub fn suppress_positive_response(&self) -> bool {
63 self.access_type.suppress_positive_response()
64 }
65
66 #[must_use]
68 pub fn access_type(&self) -> SecurityAccessType {
69 self.access_type.value()
70 }
71
72 #[must_use]
74 pub fn request_data(&self) -> &[u8] {
75 &self.request_data
76 }
77
78 #[must_use]
80 pub fn allowed_nack_codes() -> &'static [NegativeResponseCode] {
81 &SECURITY_ACCESS_NEGATIVE_RESPONSE_CODES
82 }
83}
84
85impl WireFormat for SecurityAccessRequest {
86 fn decode<T: std::io::Read>(reader: &mut T) -> Result<Option<Self>, Error> {
88 let access_type = SuppressablePositiveResponse::try_from(reader.read_u8()?)?;
89 let mut request_data: Vec<u8> = Vec::new();
90 _ = reader.read_to_end(&mut request_data)?;
91 Ok(Some(Self {
92 access_type,
93 request_data,
94 }))
95 }
96
97 fn required_size(&self) -> usize {
98 1 + self.request_data().len()
99 }
100
101 fn encode<T: std::io::Write>(&self, writer: &mut T) -> Result<usize, Error> {
103 writer.write_u8(u8::from(self.access_type))?;
104 writer.write_all(&self.request_data)?;
105 Ok(self.required_size())
106 }
107
108 fn is_positive_response_suppressed(&self) -> bool {
109 self.suppress_positive_response()
110 }
111}
112
113impl SingleValueWireFormat for SecurityAccessRequest {}
114
115#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
125#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
126#[derive(Clone, Debug, Eq, PartialEq)]
127#[non_exhaustive]
128pub struct SecurityAccessResponse {
129 pub access_type: SecurityAccessType,
130 pub security_seed: Vec<u8>,
131}
132
133impl SecurityAccessResponse {
134 pub(crate) fn new(access_type: SecurityAccessType, security_seed: Vec<u8>) -> Self {
136 Self {
137 access_type,
138 security_seed,
139 }
140 }
141}
142
143impl WireFormat for SecurityAccessResponse {
144 fn decode<T: Read>(reader: &mut T) -> Result<Option<Self>, Error> {
146 let access_type = SecurityAccessType::try_from(reader.read_u8()?)?;
147 let mut security_seed = Vec::new();
148 let _ = reader.read_to_end(&mut security_seed)?;
149 Ok(Some(Self {
150 access_type,
151 security_seed,
152 }))
153 }
154
155 fn required_size(&self) -> usize {
156 1 + self.security_seed.len()
157 }
158
159 fn encode<T: Write>(&self, writer: &mut T) -> Result<usize, Error> {
161 writer.write_u8(u8::from(self.access_type))?;
162 writer.write_all(&self.security_seed)?;
163 Ok(self.required_size())
164 }
165}
166
167impl SingleValueWireFormat for SecurityAccessResponse {}
168
169#[cfg(test)]
170mod request {
171 use super::*;
172
173 #[test]
174 fn request_seed() {
175 let bytes: [u8; 6] = [
176 0x01, 0x00, 0x01, 0x02, 0x03, 0x04, ];
179 let req = SecurityAccessRequest::decode_single_value(&mut bytes.as_slice()).unwrap();
180
181 assert_eq!(
182 req.access_type,
183 SuppressablePositiveResponse::new(false, SecurityAccessType::RequestSeed(0x01))
184 );
185
186 let mut buf = Vec::new();
187 let written = req.encode(&mut buf).unwrap();
188 assert_eq!(written, bytes.len());
189 assert_eq!(written, req.required_size());
190 }
191}
192
193#[cfg(test)]
194mod response {
195 use super::*;
196
197 #[test]
198 fn response_send() {
199 let bytes: [u8; 6] = [
200 0x02, 0x00, 0x01, 0x02, 0x03, 0x04, ];
203 let resp = SecurityAccessResponse::decode_single_value(&mut bytes.as_slice()).unwrap();
204
205 assert_eq!(resp.access_type, SecurityAccessType::SendKey(0x02));
206 assert_eq!(resp.security_seed, vec![0x00, 0x01, 0x02, 0x03, 0x04]);
207
208 let mut buf = Vec::new();
209 let written = resp.encode(&mut buf).unwrap();
210 assert_eq!(written, bytes.len());
211 assert_eq!(written, resp.required_size());
212 }
213}