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