1use ace_sim::clock::Duration;
4
5pub mod periodic {
12 use ace_sim::clock::Duration;
13
14 pub const SLOW: Duration = Duration::from_millis(2_000);
16
17 pub const MEDIUM: Duration = Duration::from_millis(500);
19
20 pub const FAST: Duration = Duration::from_millis(50);
22}
23
24#[derive(Debug, Clone)]
32pub struct SessionConfig {
33 pub session_type: u8,
36
37 pub p2_timeout: Duration,
39
40 pub p2_extended_timeout: Duration,
43
44 pub s3_timeout: Duration,
47}
48
49impl SessionConfig {
50 pub const fn default_session() -> Self {
51 Self {
52 session_type: 0x01,
53 p2_timeout: Duration::from_millis(50),
54 p2_extended_timeout: Duration::from_millis(5_000),
55 s3_timeout: Duration::from_millis(5_000),
56 }
57 }
58
59 pub const fn programming_session() -> Self {
60 Self {
61 session_type: 0x02,
62 p2_timeout: Duration::from_millis(50),
63 p2_extended_timeout: Duration::from_millis(5_000),
64 s3_timeout: Duration::from_millis(5_000),
65 }
66 }
67
68 pub const fn extended_session() -> Self {
69 Self {
70 session_type: 0x03,
71 p2_timeout: Duration::from_millis(50),
72 p2_extended_timeout: Duration::from_millis(5_000),
73 s3_timeout: Duration::from_millis(5_000),
74 }
75 }
76}
77
78#[derive(Debug, Clone)]
86pub struct ServiceConfig {
87 pub service_id: u8,
89
90 pub supported_in: &'static [u8],
93
94 pub security_level: u8,
96}
97
98impl ServiceConfig {
99 pub const fn new(service_id: u8, supported_in: &'static [u8]) -> Self {
100 ServiceConfig {
101 service_id,
102 supported_in,
103 security_level: 0,
104 }
105 }
106
107 pub const fn secured(service_id: u8, supported_in: &'static [u8], security_level: u8) -> Self {
108 Self {
109 service_id,
110 supported_in,
111 security_level,
112 }
113 }
114}
115
116#[derive(Debug, Clone)]
124pub struct DidConfig {
125 pub identifier: u16,
127
128 pub readable_in: &'static [u8],
130
131 pub writable_in: &'static [u8],
133
134 pub security_level: u8,
136
137 pub periodic: bool,
139
140 pub min_periodic_interval: Duration,
143}
144
145impl DidConfig {
146 pub const fn read_only(identifier: u16, readable_in: &'static [u8]) -> Self {
147 Self {
148 identifier,
149 readable_in,
150 writable_in: &[],
151 security_level: 0,
152 periodic: false,
153 min_periodic_interval: Duration::from_millis(50),
154 }
155 }
156
157 pub const fn read_write(
158 identifier: u16,
159 readable_in: &'static [u8],
160 writable_in: &'static [u8],
161 ) -> Self {
162 Self {
163 identifier,
164 readable_in,
165 writable_in,
166 security_level: 0,
167 periodic: false,
168 min_periodic_interval: Duration::from_millis(50),
169 }
170 }
171
172 pub const fn periodic(mut self, min_interval: Duration) -> Self {
173 self.periodic = true;
174 self.min_periodic_interval = min_interval;
175 self
176 }
177
178 pub const fn secured(mut self, level: u8) -> Self {
179 self.security_level = level;
180 self
181 }
182}
183
184#[derive(Debug, Clone)]
192pub struct SecurityLevelConfig {
193 pub level: u8,
195
196 pub max_attempts: u8,
198
199 pub lockout_duration: Duration,
201
202 pub seed_length: usize,
204
205 pub key_length: usize,
207}
208
209#[derive(Debug, Clone)]
219pub struct ServerConfig<
220 const MAX_SESSIONS: usize,
221 const MAX_SERVICES: usize,
222 const MAX_DIDS: usize,
223 const MAX_SECURITY_LEVELS: usize,
224> {
225 pub physical_address: u16,
227
228 pub functional_address: u16,
230
231 pub sessions: heapless::Vec<SessionConfig, MAX_SESSIONS>,
232 pub services: heapless::Vec<ServiceConfig, MAX_SERVICES>,
233 pub data_identifiers: heapless::Vec<DidConfig, MAX_DIDS>,
234 pub security_levels: heapless::Vec<SecurityLevelConfig, MAX_SECURITY_LEVELS>,
235}
236
237impl<
238 const MAX_SESSIONS: usize,
239 const MAX_SERVICES: usize,
240 const MAX_DIDS: usize,
241 const MAX_SECURITY_LEVELS: usize,
242 > ServerConfig<MAX_SESSIONS, MAX_SERVICES, MAX_DIDS, MAX_SECURITY_LEVELS>
243{
244 pub fn new(physical_address: u16, functional_address: u16) -> Self {
245 Self {
246 physical_address,
247 functional_address,
248 sessions: heapless::Vec::new(),
249 services: heapless::Vec::new(),
250 data_identifiers: heapless::Vec::new(),
251 security_levels: heapless::Vec::new(),
252 }
253 }
254
255 pub fn with_session(mut self, s: SessionConfig) -> Self {
258 let _ = self.sessions.push(s);
259 self
260 }
261
262 pub fn with_service(mut self, s: ServiceConfig) -> Self {
263 let _ = self.services.push(s);
264 self
265 }
266
267 pub fn with_did(mut self, d: DidConfig) -> Self {
268 let _ = self.data_identifiers.push(d);
269 self
270 }
271
272 pub fn with_security_level(mut self, l: SecurityLevelConfig) -> Self {
273 let _ = self.security_levels.push(l);
274 self
275 }
276
277 pub fn find_session(&self, session_type: u8) -> Option<&SessionConfig> {
282 self.sessions
283 .iter()
284 .find(|s| s.session_type == session_type)
285 }
286
287 pub fn find_service(&self, service_id: u8) -> Option<&ServiceConfig> {
288 self.services.iter().find(|s| s.service_id == service_id)
289 }
290
291 pub fn find_did(&self, identifier: u16) -> Option<&DidConfig> {
292 self.data_identifiers
293 .iter()
294 .find(|d| d.identifier == identifier)
295 }
296
297 pub fn find_security_level(&self, level: u8) -> Option<&SecurityLevelConfig> {
298 self.security_levels.iter().find(|l| l.level == level)
299 }
300
301 pub fn service_allowed(&self, service_id: u8, session_type: u8) -> bool {
302 self.find_service(service_id)
303 .map(|s| s.supported_in.contains(&session_type))
304 .unwrap_or(false)
305 }
306
307 pub fn did_readable(&self, identifier: u16, session_type: u8) -> bool {
308 self.find_did(identifier)
309 .map(|s| s.readable_in.contains(&session_type))
310 .unwrap_or(false)
311 }
312
313 pub fn did_writable(&self, identifier: u16, session_type: u8) -> bool {
314 self.find_did(identifier)
315 .map(|s| s.writable_in.contains(&session_type))
316 .unwrap_or(false)
317 }
318
319 }
321
322