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 pub physical_address: u16,
222
223 pub functional_address: u16,
225
226 pub sessions: heapless::Vec<SessionConfig, 8>,
227 pub services: heapless::Vec<ServiceConfig, 32>,
228 pub data_identifiers: heapless::Vec<DidConfig, 64>,
229 pub security_levels: heapless::Vec<SecurityLevelConfig, 8>,
230}
231
232impl ServerConfig {
233 pub fn new(physical_address: u16, functional_address: u16) -> Self {
234 Self {
235 physical_address,
236 functional_address,
237 sessions: heapless::Vec::new(),
238 services: heapless::Vec::new(),
239 data_identifiers: heapless::Vec::new(),
240 security_levels: heapless::Vec::new(),
241 }
242 }
243
244 pub fn with_session(mut self, s: SessionConfig) -> Self {
247 let _ = self.sessions.push(s);
248 self
249 }
250
251 pub fn with_service(mut self, s: ServiceConfig) -> Self {
252 let _ = self.services.push(s);
253 self
254 }
255
256 pub fn with_did(mut self, d: DidConfig) -> Self {
257 let _ = self.data_identifiers.push(d);
258 self
259 }
260 pub fn with_security_level(mut self, l: SecurityLevelConfig) -> Self {
261 let _ = self.security_levels.push(l);
262 self
263 }
264
265 pub fn find_session(&self, session_type: u8) -> Option<&SessionConfig> {
270 self.sessions
271 .iter()
272 .find(|s| s.session_type == session_type)
273 }
274
275 pub fn find_service(&self, service_id: u8) -> Option<&ServiceConfig> {
276 self.services.iter().find(|s| s.service_id == service_id)
277 }
278
279 pub fn find_did(&self, identifier: u16) -> Option<&DidConfig> {
280 self.data_identifiers
281 .iter()
282 .find(|d| d.identifier == identifier)
283 }
284
285 pub fn find_security_level(&self, level: u8) -> Option<&SecurityLevelConfig> {
286 self.security_levels.iter().find(|l| l.level == level)
287 }
288
289 pub fn service_allowed(&self, service_id: u8, session_type: u8) -> bool {
290 self.find_service(service_id)
291 .map(|s| s.supported_in.contains(&session_type))
292 .unwrap_or(false)
293 }
294
295 pub fn did_readable(&self, identifier: u16, session_type: u8) -> bool {
296 self.find_did(identifier)
297 .map(|s| s.readable_in.contains(&session_type))
298 .unwrap_or(false)
299 }
300
301 pub fn did_writable(&self, identifier: u16, session_type: u8) -> bool {
302 self.find_did(identifier)
303 .map(|s| s.writable_in.contains(&session_type))
304 .unwrap_or(false)
305 }
306
307 }
309
310