1use acex_core::Vec;
4use acex_sim::clock::Duration;
5use acex_uds::message::DiagnosticSessionType;
6pub mod periodic {
13 use acex_sim::clock::Duration;
14
15 pub const SLOW: Duration = Duration::from_millis(2_000);
17
18 pub const MEDIUM: Duration = Duration::from_millis(500);
20
21 pub const FAST: Duration = Duration::from_millis(50);
23}
24
25#[derive(Debug, Clone)]
33#[cfg_attr(feature = "defmt", derive(defmt::Format))]
34pub struct SessionConfig {
35 pub session_type: u8,
38
39 pub p2_timeout: Duration,
41
42 pub p2_extended_timeout: Duration,
45
46 pub s3_timeout: Duration,
52}
53
54impl SessionConfig {
55 pub const fn default_session() -> Self {
56 Self {
57 session_type: 0x01,
58 p2_timeout: Duration::from_millis(50),
59 p2_extended_timeout: Duration::from_millis(5_000),
60 s3_timeout: Duration::from_millis(5_000),
61 }
62 }
63
64 pub const fn programming_session() -> Self {
65 Self {
66 session_type: 0x02,
67 p2_timeout: Duration::from_millis(50),
68 p2_extended_timeout: Duration::from_millis(5_000),
69 s3_timeout: Duration::from_millis(5_000),
70 }
71 }
72
73 pub const fn extended_session() -> Self {
74 Self {
75 session_type: 0x03,
76 p2_timeout: Duration::from_millis(50),
77 p2_extended_timeout: Duration::from_millis(5_000),
78 s3_timeout: Duration::from_millis(5_000),
79 }
80 }
81}
82
83#[derive(Debug, Clone)]
91#[cfg_attr(feature = "defmt", derive(defmt::Format))]
92pub struct ServiceConfig {
93 pub service_id: u8,
95
96 pub supported_in: &'static [u8],
99
100 pub security_level: u8,
102}
103
104impl ServiceConfig {
105 pub const fn new(service_id: u8, supported_in: &'static [u8]) -> Self {
106 ServiceConfig {
107 service_id,
108 supported_in,
109 security_level: 0,
110 }
111 }
112
113 pub const fn secured(service_id: u8, supported_in: &'static [u8], security_level: u8) -> Self {
114 Self {
115 service_id,
116 supported_in,
117 security_level,
118 }
119 }
120}
121
122#[derive(Debug, Clone)]
130#[cfg_attr(feature = "defmt", derive(defmt::Format))]
131pub struct DidConfig {
132 pub identifier: u16,
134
135 pub readable_in: &'static [u8],
137
138 pub writable_in: &'static [u8],
140
141 pub security_level: u8,
143
144 pub periodic: bool,
146
147 pub min_periodic_interval: Duration,
150}
151
152impl DidConfig {
153 pub const fn read_only(identifier: u16, readable_in: &'static [u8]) -> Self {
154 Self {
155 identifier,
156 readable_in,
157 writable_in: &[],
158 security_level: 0,
159 periodic: false,
160 min_periodic_interval: Duration::from_millis(50),
161 }
162 }
163
164 pub const fn read_write(
165 identifier: u16,
166 readable_in: &'static [u8],
167 writable_in: &'static [u8],
168 ) -> Self {
169 Self {
170 identifier,
171 readable_in,
172 writable_in,
173 security_level: 0,
174 periodic: false,
175 min_periodic_interval: Duration::from_millis(50),
176 }
177 }
178
179 pub const fn periodic(mut self, min_interval: Duration) -> Self {
180 self.periodic = true;
181 self.min_periodic_interval = min_interval;
182 self
183 }
184
185 pub const fn secured(mut self, level: u8) -> Self {
186 self.security_level = level;
187 self
188 }
189}
190
191#[derive(Debug, Clone)]
199#[cfg_attr(feature = "defmt", derive(defmt::Format))]
200pub struct SecurityLevelConfig {
201 pub level: u8,
203
204 pub max_attempts: Option<u8>,
206
207 pub lockout_duration: Option<Duration>,
209
210 pub seed_length: usize,
212
213 pub key_length: usize,
215}
216
217#[derive(Debug, Clone)]
227#[cfg_attr(all(feature = "defmt", not(feature = "alloc")), derive(defmt::Format))]
228pub struct ServerConfig<
229 const MAX_SESSIONS: usize,
230 const MAX_SERVICES: usize,
231 const MAX_DIDS: usize,
232 const MAX_SECURITY_LEVELS: usize,
233> {
234 pub physical_address: u16,
236
237 pub functional_address: u16,
239
240 pub sessions: Vec<SessionConfig, MAX_SESSIONS>,
241 pub services: Vec<ServiceConfig, MAX_SERVICES>,
242 pub data_identifiers: Vec<DidConfig, MAX_DIDS>,
243 pub security_levels: Vec<SecurityLevelConfig, MAX_SECURITY_LEVELS>,
244
245 pub default_session_type: DiagnosticSessionType,
247
248 pub allow_read_many_dids: bool
250}
251
252impl<
253 const MAX_SESSIONS: usize,
254 const MAX_SERVICES: usize,
255 const MAX_DIDS: usize,
256 const MAX_SECURITY_LEVELS: usize,
257 > ServerConfig<MAX_SESSIONS, MAX_SERVICES, MAX_DIDS, MAX_SECURITY_LEVELS>
258{
259 pub fn new(physical_address: u16, functional_address: u16) -> Self {
260 Self {
261 physical_address,
262 functional_address,
263 sessions: Vec::new(),
264 services: Vec::new(),
265 data_identifiers: Vec::new(),
266 security_levels: Vec::new(),
267 default_session_type: DiagnosticSessionType::DefaultSession,
268 allow_read_many_dids: false
269 }
270 }
271
272 pub fn with_session(mut self, s: SessionConfig) -> Self {
275 #[cfg(feature = "defmt")]
276 defmt::unwrap!(self.sessions.push(s));
277
278 #[cfg(not(feature = "defmt"))]
279 let _ = self.sessions.push(s);
280
281 self
282 }
283
284 pub fn with_service(mut self, s: ServiceConfig) -> Self {
285 #[cfg(feature = "defmt")]
286 defmt::unwrap!(self.services.push(s));
287
288 #[cfg(not(feature = "defmt"))]
289 let _ = self.services.push(s);
290
291 self
292 }
293
294 pub fn with_did(mut self, d: DidConfig) -> Self {
295 #[cfg(feature = "defmt")]
296 defmt::unwrap!(self.data_identifiers.push(d));
297
298 #[cfg(not(feature = "defmt"))]
299 let _ = self.data_identifiers.push(d);
300
301 self
302 }
303
304 pub fn with_security_level(mut self, l: SecurityLevelConfig) -> Self {
305 #[cfg(feature = "defmt")]
306 defmt::unwrap!(self.security_levels.push(l));
307
308 #[cfg(not(feature = "defmt"))]
309 let _ = self.security_levels.push(l);
310
311 self
312 }
313
314 pub fn with_default_session_type(mut self, session_type: DiagnosticSessionType) -> Self {
315 self.default_session_type = session_type;
316 self
317 }
318
319 pub fn with_allow_read_many_dids(mut self, status: bool) -> Self {
320 self.allow_read_many_dids = status;
321 self
322 }
323
324 pub fn find_session(&self, session_type: u8) -> Option<&SessionConfig> {
329 self.sessions
330 .iter()
331 .find(|s| s.session_type == session_type)
332 }
333
334 pub fn find_service(&self, service_id: u8) -> Option<&ServiceConfig> {
335 self.services.iter().find(|s| s.service_id == service_id)
336 }
337
338 pub fn find_did(&self, identifier: u16) -> Option<&DidConfig> {
339 self.data_identifiers
340 .iter()
341 .find(|d| d.identifier == identifier)
342 }
343
344 pub fn find_security_level(&self, level: u8) -> Option<&SecurityLevelConfig> {
345 self.security_levels.iter().find(|l| l.level == level)
346 }
347
348 pub fn service_allowed(&self, service_id: u8, session_type: u8) -> bool {
349 self.find_service(service_id)
350 .map(|s| s.supported_in.contains(&session_type))
351 .unwrap_or(false)
352 }
353
354 pub fn service_unlocked(&self, service_id: u8, security_level: u8) -> bool {
355 self.find_service(service_id)
356 .map(|s| security_level >= s.security_level)
357 .unwrap_or(false)
358 }
359
360 pub fn did_readable(&self, identifier: u16, session_type: u8) -> bool {
361 self.find_did(identifier)
362 .map(|s| s.readable_in.contains(&session_type))
363 .unwrap_or(false)
364 }
365
366 pub fn did_writable(&self, identifier: u16, session_type: u8) -> bool {
367 self.find_did(identifier)
368 .map(|s| s.writable_in.contains(&session_type))
369 .unwrap_or(false)
370 }
371
372 }
374
375