1use ace_core::Vec;
4use ace_proto::uds::UdsFrame;
5use ace_sim::clock::{Duration, Instant};
6use ace_sim::io::NodeAddress;
7use ace_uds::ext::UdsFrameExt;
8use ace_uds::message::service::UdsServiceRequest;
9use ace_uds::message::ServiceIdentifier;
10
11use crate::config::{periodic, ServerConfig, SessionConfig};
12use crate::handler::ServerHandler;
13use crate::nrc::NrcError;
14use crate::security_provider::SecurityProvider;
15
16#[derive(Debug)]
21pub enum ServerError<E: NrcError> {
22 Handler(E),
23 Codec(ace_uds::error::UdsError),
24 OutboxFull,
25}
26
27#[derive(Debug, Clone)]
32struct SessionState {
33 session_type: u8,
34 last_rx: Instant,
35 security_level: u8,
36}
37
38impl SessionState {
39 fn new() -> Self {
40 Self {
41 session_type: 0x01,
42 last_rx: Instant::ZERO,
43 security_level: 0,
44 }
45 }
46
47 fn is_default(&self) -> bool {
48 self.session_type == 0x01
49 }
50}
51
52#[derive(Debug, Clone)]
57struct SecurityState<const MAX_SEED: usize> {
58 pending_seed: Vec<u8, MAX_SEED>,
59 pending_level: u8,
60 failed_attempts: Vec<(u8, u8), 8>,
61 lockout_until: Vec<(u8, Instant), 8>,
62}
63
64impl<const MAX_SEED: usize> SecurityState<MAX_SEED> {
65 fn new() -> Self {
66 Self {
67 pending_seed: Vec::new(),
68 pending_level: 0,
69 failed_attempts: Vec::new(),
70 lockout_until: Vec::new(),
71 }
72 }
73
74 fn is_locked(&self, level: u8, now: Instant) -> bool {
75 self.lockout_until
76 .iter()
77 .find(|(l, _)| *l == level)
78 .map(|(_, until)| now < *until)
79 .unwrap_or(false)
80 }
81
82 fn failed_count(&self, level: u8) -> u8 {
83 self.failed_attempts
84 .iter()
85 .find(|(l, _)| *l == level)
86 .map(|(_, c)| *c)
87 .unwrap_or(0)
88 }
89
90 fn increment_failed(&mut self, level: u8) {
91 if let Some(e) = self.failed_attempts.iter_mut().find(|(l, _)| *l == level) {
92 e.1 = e.1.saturating_add(1);
93 } else {
94 let _ = self.failed_attempts.push((level, 1));
95 }
96 }
97
98 fn reset_failed(&mut self, level: u8) {
99 if let Some(e) = self.failed_attempts.iter_mut().find(|(l, _)| *l == level) {
100 e.1 = 0;
101 }
102 }
103
104 fn set_lockout(&mut self, level: u8, until: Instant) {
105 if let Some(e) = self.lockout_until.iter_mut().find(|(l, _)| *l == level) {
106 e.1 = until;
107 } else {
108 let _ = self.lockout_until.push((level, until));
109 }
110 }
111
112 fn clear_pending(&mut self) {
113 self.pending_seed.clear();
114 self.pending_level = 0;
115 }
116}
117
118#[derive(Debug, Clone)]
123struct PeriodicEntry {
124 did: u16,
125 interval: Duration,
126 next_tx: Instant,
127 client: NodeAddress,
128}
129
130#[derive(Debug)]
131struct PeriodicState<const MAX_PERIODIC: usize> {
132 entries: Vec<PeriodicEntry, MAX_PERIODIC>,
133}
134
135impl<const MAX_PERIODIC: usize> PeriodicState<MAX_PERIODIC> {
136 fn new() -> Self {
137 Self {
138 entries: Vec::new(),
139 }
140 }
141
142 fn register(&mut self, did: u16, interval: Duration, client: NodeAddress, now: Instant) {
143 if let Some(e) = self
144 .entries
145 .iter_mut()
146 .find(|e| e.did == did && e.client == client)
147 {
148 e.interval = interval;
149 e.next_tx = now + interval;
150 return;
151 }
152 let _ = self.entries.push(PeriodicEntry {
153 did,
154 interval,
155 next_tx: now + interval,
156 client,
157 });
158 }
159
160 fn cancel(&mut self, did: u16, client: &NodeAddress) {
161 self.entries
162 .retain(|e| !(e.did == did && &e.client == client));
163 }
164
165 fn collect_due(&self, now: Instant, out: &mut Vec<(u16, NodeAddress), MAX_PERIODIC>) {
166 for e in self.entries.iter().filter(|e| now >= e.next_tx) {
167 let _ = out.push((e.did, e.client.clone()));
168 }
169 }
170
171 fn advance(&mut self, did: u16, client: &NodeAddress, now: Instant) {
172 if let Some(e) = self
173 .entries
174 .iter_mut()
175 .find(|e| e.did == did && &e.client == client)
176 {
177 e.next_tx = now + e.interval;
178 }
179 }
180}
181
182#[derive(Debug)]
195pub struct UdsServer<
196 const MAX_FRAME: usize,
197 const MAX_OUTBOX: usize,
198 const MAX_SESSIONS: usize,
199 const MAX_SERVICES: usize,
200 const MAX_DIDS: usize,
201 const MAX_SECURITY_LEVELS: usize,
202 const DEFAULT_S3: u64,
203 const DEFAULT_P2: u64,
204 const DEFAULT_P2_EXT: u64,
205 const DEFAULT_LOCKOUT: u64,
206 const DEFAULT_MAX_SECURITY_ATTEMPTS: u8,
207 const MAX_SEED: usize,
208 const MAX_PERIODIC: usize,
209 H,
210 S,
211> where
212 H: ServerHandler,
213 S: SecurityProvider,
214{
215 config: ServerConfig<MAX_SESSIONS, MAX_SERVICES, MAX_DIDS, MAX_SECURITY_LEVELS>,
216 handler: H,
217 security_provider: S,
218 address: NodeAddress,
219 session: SessionState,
220 security: SecurityState<MAX_SEED>,
221 periodic: PeriodicState<MAX_PERIODIC>,
222 outbox: Vec<(NodeAddress, Vec<u8, MAX_FRAME>), MAX_OUTBOX>,
223}
224
225impl<
226 const MAX_FRAME: usize,
227 const MAX_OUTBOX: usize,
228 const MAX_SESSIONS: usize,
229 const MAX_SERVICES: usize,
230 const MAX_DIDS: usize,
231 const MAX_SECURITY_LEVELS: usize,
232 const DEFAULT_S3: u64,
233 const DEFAULT_P2: u64,
234 const DEFAULT_P2_EXT: u64,
235 const DEFAULT_LOCKOUT: u64,
236 const DEFAULT_MAX_SECURITY_ATTEMPTS: u8,
237 const MAX_SEED: usize,
238 const MAX_PERIODIC: usize,
239 H,
240 S,
241 >
242 UdsServer<
243 MAX_FRAME,
244 MAX_OUTBOX,
245 MAX_SESSIONS,
246 MAX_SERVICES,
247 MAX_DIDS,
248 MAX_SECURITY_LEVELS,
249 DEFAULT_S3,
250 DEFAULT_P2,
251 DEFAULT_P2_EXT,
252 DEFAULT_LOCKOUT,
253 DEFAULT_MAX_SECURITY_ATTEMPTS,
254 MAX_SEED,
255 MAX_PERIODIC,
256 H,
257 S,
258 >
259where
260 H: ServerHandler,
261 S: SecurityProvider,
262{
263 pub fn new(
264 config: ServerConfig<MAX_SESSIONS, MAX_SERVICES, MAX_DIDS, MAX_SECURITY_LEVELS>,
265 handler: H,
266 security_provider: S,
267 address: NodeAddress,
268 ) -> Self {
269 Self {
270 config,
271 handler,
272 security_provider,
273 address,
274 session: SessionState::new(),
275 security: SecurityState::new(),
276 periodic: PeriodicState::new(),
277 outbox: Vec::new(),
278 }
279 }
280
281 pub fn address(&self) -> &NodeAddress {
284 &self.address
285 }
286 pub fn session_type(&self) -> u8 {
287 self.session.session_type
288 }
289 pub fn security_level(&self) -> u8 {
290 self.session.security_level
291 }
292
293 pub fn handle(
300 &mut self,
301 src: &NodeAddress,
302 data: &[u8],
303 now: Instant,
304 ) -> Result<(), ServerError<H::Error>> {
305 self.session.last_rx = now;
306
307 let frame = UdsFrame::from_slice(data);
308
309 if let Err(e) = frame.validate() {
311 return Err(ServerError::Codec(e));
312 }
313
314 let sid = match frame.service_identifier() {
315 Some(s) => s,
316 None => return self.nrc_raw(src, 0x00, H::Error::service_not_supported().into(), now),
317 };
318
319 let sid_byte = sid.discriminant();
321 if let Err(nrc) = self.guard_service(sid_byte) {
322 return self.nrc_raw(src, sid_byte, nrc, now);
323 }
324
325 let suppressed = frame.is_suppressed();
328
329 match sid {
330 ServiceIdentifier::UdsServiceRequest(UdsServiceRequest::TesterPresent) => {
331 self.on_tester_present(src, &frame, suppressed, now)
332 }
333
334 ServiceIdentifier::UdsServiceRequest(UdsServiceRequest::DiagnosticSessionControl) => {
335 self.on_session_control(src, &frame, suppressed, now)
336 }
337
338 ServiceIdentifier::UdsServiceRequest(UdsServiceRequest::EcuReset) => {
339 self.on_ecu_reset(src, &frame, suppressed, now)
340 }
341
342 ServiceIdentifier::UdsServiceRequest(UdsServiceRequest::SecurityAccess) => {
343 self.on_security_access(src, &frame, suppressed, now)
344 }
345
346 ServiceIdentifier::UdsServiceRequest(UdsServiceRequest::ReadDataByIdentifier) => {
347 self.on_read_did(src, &frame, suppressed, now)
348 }
349
350 ServiceIdentifier::UdsServiceRequest(UdsServiceRequest::WriteDataByIdentifier) => {
351 self.on_write_did(src, &frame, suppressed, now)
352 }
353
354 ServiceIdentifier::UdsServiceRequest(
355 UdsServiceRequest::ReadDataByPeriodicIdentifier,
356 ) => self.on_periodic_did(src, &frame, suppressed, now),
357
358 ServiceIdentifier::UdsServiceRequest(UdsServiceRequest::RoutineControl) => {
359 self.on_routine_control(src, &frame, suppressed, now)
360 }
361
362 ServiceIdentifier::UdsServiceRequest(UdsServiceRequest::CommunicationControl) => {
363 self.on_communication_control(src, &frame, suppressed, now)
364 }
365
366 ServiceIdentifier::UdsServiceRequest(
367 UdsServiceRequest::InputOutputControlByIdentifier,
368 ) => self.on_io_control(src, &frame, suppressed, now),
369
370 ServiceIdentifier::UdsServiceRequest(UdsServiceRequest::RequestDownload) => {
371 self.on_request_download(src, &frame, suppressed, now)
372 }
373
374 ServiceIdentifier::UdsServiceRequest(UdsServiceRequest::TransferData) => {
375 self.on_transfer_data(src, &frame, suppressed, now)
376 }
377
378 ServiceIdentifier::UdsServiceRequest(UdsServiceRequest::RequestTransferExit) => {
379 self.on_transfer_exit(src, &frame, suppressed, now)
380 }
381
382 ServiceIdentifier::UdsServiceRequest(UdsServiceRequest::RequestFileTransfer) => {
383 self.on_file_transfer(src, &frame, suppressed, now)
384 }
385
386 _ => self.nrc_raw(src, sid_byte, H::Error::service_not_supported().into(), now),
387 }
388 }
389
390 pub fn tick(&mut self, now: Instant) -> Result<(), ServerError<H::Error>> {
392 self.check_s3(now);
393 self.dispatch_periodic(now)
394 }
395
396 pub fn drain_outbox(
398 &mut self,
399 out: &mut Vec<(NodeAddress, Vec<u8, MAX_FRAME>), MAX_OUTBOX>,
400 ) -> usize {
401 let n = self.outbox.len();
402 for item in self.outbox.drain(..) {
403 let _ = out.push(item);
404 }
405 n
406 }
407
408 fn current_session(&self) -> Option<&SessionConfig> {
413 self.config.find_session(self.session.session_type)
414 }
415
416 fn check_s3(&mut self, now: Instant) {
417 if self.session.is_default() {
418 return;
419 }
420 let s3 = self
421 .current_session()
422 .map(|s| s.s3_timeout)
423 .unwrap_or(Duration::from_millis(DEFAULT_S3));
424 if let Some(elapsed) = now.checked_duration_since(self.session.last_rx) {
425 if elapsed > s3 {
426 self.session.session_type = 0x01;
427 self.session.security_level = 0;
428 self.security.clear_pending();
429 }
430 }
431 }
432
433 fn guard_service(&self, sid: u8) -> Result<(), u8> {
434 if !self.config.service_allowed(sid, self.session.session_type) {
435 return Err(H::Error::service_not_supported_in_active_session().into());
436 }
437 Ok(())
438 }
439
440 fn guard_security(&self, required: u8) -> Result<(), u8> {
441 if required > 0 && self.session.security_level < required {
442 return Err(H::Error::security_access_denied().into());
443 }
444 Ok(())
445 }
446
447 fn enqueue(
452 &mut self,
453 dst: NodeAddress,
454 frame: Vec<u8, MAX_FRAME>,
455 ) -> Result<(), ServerError<H::Error>> {
456 if self.outbox.len() >= MAX_OUTBOX {
457 return Err(ServerError::OutboxFull);
458 } else {
459 self.outbox.push((dst, frame));
460
461 Ok(())
462 }
463 }
464
465 fn pos(
466 &mut self,
467 dst: &NodeAddress,
468 request_sid: u8,
469 payload: &[u8],
470 _now: Instant,
471 ) -> Result<(), ServerError<H::Error>> {
472 let mut frame: Vec<u8, MAX_FRAME> = Vec::new();
473 let _ = frame.push(request_sid | 0x40);
474 let _ = frame.extend_from_slice(payload);
475
476 self.enqueue(dst.clone(), frame)
477 }
478
479 fn nrc(
480 &mut self,
481 dst: &NodeAddress,
482 request_sid: u8,
483 error: H::Error,
484 _now: Instant,
485 ) -> Result<(), ServerError<H::Error>> {
486 let nrc_byte: u8 = error.into();
487 self.nrc_raw(dst, request_sid, nrc_byte, _now)
488 }
489
490 fn nrc_raw(
491 &mut self,
492 dst: &NodeAddress,
493 request_sid: u8,
494 nrc_byte: u8,
495 _now: Instant,
496 ) -> Result<(), ServerError<H::Error>> {
497 let mut frame: Vec<u8, MAX_FRAME> = Vec::new();
498 let _ = frame.push(0x7F);
499 let _ = frame.push(request_sid);
500 let _ = frame.push(nrc_byte);
501 self.enqueue(dst.clone(), frame)
502 }
503
504 fn on_tester_present(
517 &mut self,
518 src: &NodeAddress,
519 frame: &UdsFrame<'_>,
520 suppressed: bool,
521 now: Instant,
522 ) -> Result<(), ServerError<H::Error>> {
523 if suppressed {
526 return Ok(());
527 }
528 let sf = frame.sub_function_value().unwrap_or(0x00);
530 self.pos(src, 0x3E, &[sf], now)
531 }
532
533 fn on_session_control(
534 &mut self,
535 src: &NodeAddress,
536 frame: &UdsFrame<'_>,
537 suppressed: bool,
538 now: Instant,
539 ) -> Result<(), ServerError<H::Error>> {
540 let session_type = match frame.sub_function_value() {
542 Some(v) => v,
543 None => {
544 return self.nrc(
545 src,
546 0x10,
547 H::Error::incorrect_message_length_or_invalid_format(),
548 now,
549 )
550 }
551 };
552
553 if self.config.find_session(session_type).is_none() {
554 return self.nrc(src, 0x10, H::Error::sub_function_not_supported(), now);
555 }
556
557 self.session.session_type = session_type;
558 self.session.security_level = 0;
559 self.session.last_rx = now;
560 self.security.clear_pending();
561
562 if suppressed {
563 return Ok(());
564 }
565
566 let (p2_ms, p2_ext_ms) = self
567 .config
568 .find_session(session_type)
569 .map(|s| {
570 (
571 s.p2_timeout.as_millis(),
572 s.p2_extended_timeout.as_millis() / 10,
573 )
574 })
575 .unwrap_or((DEFAULT_P2, DEFAULT_P2_EXT));
576
577 let payload = [
578 session_type,
579 (p2_ms >> 8) as u8,
580 p2_ms as u8,
581 (p2_ext_ms >> 8) as u8,
582 p2_ext_ms as u8,
583 ];
584 self.pos(src, 0x10, &payload, now)
585 }
586
587 fn on_ecu_reset(
588 &mut self,
589 src: &NodeAddress,
590 frame: &UdsFrame<'_>,
591 suppressed: bool,
592 now: Instant,
593 ) -> Result<(), ServerError<H::Error>> {
594 let reset_type = match frame.sub_function_value() {
596 Some(v) => v,
597 None => {
598 return self.nrc(
599 src,
600 0x11,
601 H::Error::incorrect_message_length_or_invalid_format(),
602 now,
603 )
604 }
605 };
606
607 if !suppressed {
608 self.pos(src, 0x11, &[reset_type], now)?;
609 }
610
611 self.handler
612 .ecu_reset(reset_type)
613 .map_err(ServerError::Handler)
614 }
615
616 fn on_security_access(
617 &mut self,
618 src: &NodeAddress,
619 frame: &UdsFrame<'_>,
620 _suppressed: bool, now: Instant,
622 ) -> Result<(), ServerError<H::Error>> {
623 let access_type = match frame.sub_function_value() {
625 Some(v) => v,
626 None => {
627 return self.nrc(
628 src,
629 0x27,
630 H::Error::incorrect_message_length_or_invalid_format(),
631 now,
632 )
633 }
634 };
635
636 let is_request_seed = access_type % 2 != 0;
637
638 if is_request_seed {
639 let level = access_type;
640
641 if self.security.is_locked(level, now) {
642 return self.nrc(src, 0x27, H::Error::required_time_delay_not_expired(), now);
643 }
644 if self.config.find_security_level(level).is_none() {
645 return self.nrc(src, 0x27, H::Error::sub_function_not_supported(), now);
646 }
647
648 let mut seed_buf = [0u8; MAX_SEED];
649 let seed_len = self
650 .security_provider
651 .generate_seed(level, &mut seed_buf)
652 .map_err(|_| ServerError::Handler(H::Error::conditions_not_correct()))?;
653
654 self.security.pending_seed.clear();
655 let _ = self
656 .security
657 .pending_seed
658 .extend_from_slice(&seed_buf[..seed_len]);
659 self.security.pending_level = level;
660
661 let mut payload: Vec<u8, MAX_SEED> = Vec::new();
662 let _ = payload.push(level);
663 let _ = payload.extend_from_slice(&seed_buf[..seed_len]);
664 self.pos(src, 0x27, &payload, now)
665 } else {
666 let level = access_type - 1; if self.security.is_locked(level, now) {
670 return self.nrc(src, 0x27, H::Error::required_time_delay_not_expired(), now);
671 }
672 if self.security.pending_level != level || self.security.pending_seed.is_empty() {
673 return self.nrc(src, 0x27, H::Error::request_sequence_error(), now);
674 }
675
676 let key = frame.payload().get(1..).unwrap_or(&[]);
679
680 let level_cfg = self.config.find_security_level(level);
681 let max_attempts = level_cfg
682 .map(|l| l.max_attempts)
683 .unwrap_or(DEFAULT_MAX_SECURITY_ATTEMPTS);
684 let lockout_dur = level_cfg
685 .map(|l| l.lockout_duration)
686 .unwrap_or(Duration::from_millis(DEFAULT_LOCKOUT));
687
688 let seed = self.security.pending_seed.clone();
689
690 match self.security_provider.validate_key(level, &seed, key) {
691 Ok(()) => {
692 self.security.reset_failed(level);
693 self.security.clear_pending();
694 self.session.security_level = level;
695 self.pos(src, 0x27, &[access_type], now)
696 }
697 Err(_) => {
698 self.security.increment_failed(level);
699 if self.security.failed_count(level) >= max_attempts {
700 self.security.set_lockout(level, now + lockout_dur);
701 return self.nrc(src, 0x27, H::Error::exceeded_number_of_attempts(), now);
702 }
703 self.nrc(src, 0x27, H::Error::invalid_key(), now)
704 }
705 }
706 }
707 }
708
709 fn on_read_did(
710 &mut self,
711 src: &NodeAddress,
712 frame: &UdsFrame<'_>,
713 _suppressed: bool, now: Instant,
715 ) -> Result<(), ServerError<H::Error>> {
716 let payload = frame.payload();
718 if payload.len() < 2 || payload.len() % 2 != 0 {
719 return self.nrc(
720 src,
721 0x22,
722 H::Error::incorrect_message_length_or_invalid_format(),
723 now,
724 );
725 }
726
727 let mut resp: Vec<u8, MAX_FRAME> = Vec::new();
728
729 for chunk in payload.chunks_exact(2) {
730 let did = u16::from_be_bytes([chunk[0], chunk[1]]);
731
732 if !self.config.did_readable(did, self.session.session_type) {
733 return self.nrc(src, 0x22, H::Error::request_out_of_range(), now);
734 }
735 let required_sec = self
736 .config
737 .find_did(did)
738 .map(|d| d.security_level)
739 .unwrap_or(0);
740 if let Err(nrc) = self.guard_security(required_sec) {
741 return self.nrc_raw(src, 0x22, nrc, now);
742 }
743
744 let _ = resp.push(chunk[0]);
745 let _ = resp.push(chunk[1]);
746
747 let mut data_buf = [0u8; MAX_FRAME];
748 let len = self
749 .handler
750 .read_did(did, &mut data_buf)
751 .map_err(ServerError::Handler)?;
752 let _ = resp.extend_from_slice(&data_buf[..len]);
753 }
754
755 self.pos(src, 0x22, &resp, now)
756 }
757
758 fn on_write_did(
759 &mut self,
760 src: &NodeAddress,
761 frame: &UdsFrame<'_>,
762 _suppressed: bool,
763 now: Instant,
764 ) -> Result<(), ServerError<H::Error>> {
765 let payload = frame.payload();
766 if payload.len() < 3 {
767 return self.nrc(
768 src,
769 0x2E,
770 H::Error::incorrect_message_length_or_invalid_format(),
771 now,
772 );
773 }
774
775 let did = u16::from_be_bytes([payload[0], payload[1]]);
776 let data_rec = &payload[2..];
777
778 if !self.config.did_writable(did, self.session.session_type) {
779 return self.nrc(src, 0x2E, H::Error::request_out_of_range(), now);
780 }
781 let required_sec = self
782 .config
783 .find_did(did)
784 .map(|d| d.security_level)
785 .unwrap_or(0);
786 if let Err(nrc) = self.guard_security(required_sec) {
787 return self.nrc_raw(src, 0x2E, nrc, now);
788 }
789
790 self.handler
791 .write_did(did, data_rec)
792 .map_err(ServerError::Handler)?;
793
794 self.pos(src, 0x2E, &payload[..2], now)
795 }
796
797 fn on_periodic_did(
798 &mut self,
799 src: &NodeAddress,
800 frame: &UdsFrame<'_>,
801 _suppressed: bool,
802 now: Instant,
803 ) -> Result<(), ServerError<H::Error>> {
804 let payload = frame.payload();
805 if payload.is_empty() {
806 return self.nrc(
807 src,
808 0x2A,
809 H::Error::incorrect_message_length_or_invalid_format(),
810 now,
811 );
812 }
813
814 let mode = payload[0];
816 let periodic_ids = payload.get(1..).unwrap_or(&[]);
817
818 match mode {
819 0x04 => {
821 for &id in periodic_ids {
822 self.periodic.cancel(0xF200u16 | id as u16, src);
823 }
824 self.pos(src, 0x2A, &[mode], now)
825 }
826 0x01 | 0x02 | 0x03 => {
827 let requested_interval = match mode {
828 0x01 => periodic::SLOW,
829 0x02 => periodic::MEDIUM,
830 _ => periodic::FAST,
831 };
832
833 for &id in periodic_ids {
834 let did = 0xF200u16 | id as u16;
835
836 if !self.config.did_readable(did, self.session.session_type) {
837 return self.nrc(src, 0x2A, H::Error::request_out_of_range(), now);
838 }
839
840 let effective = self
841 .config
842 .find_did(did)
843 .map(|d| requested_interval.max(d.min_periodic_interval))
844 .unwrap_or(requested_interval);
845
846 self.periodic.register(did, effective, src.clone(), now);
847 }
848
849 self.pos(src, 0x2A, &[mode], now)
850 }
851 _ => self.nrc(src, 0x2A, H::Error::sub_function_not_supported(), now),
852 }
853 }
854
855 fn on_routine_control(
856 &mut self,
857 src: &NodeAddress,
858 frame: &UdsFrame<'_>,
859 suppressed: bool,
860 now: Instant,
861 ) -> Result<(), ServerError<H::Error>> {
862 let payload = frame.payload();
865 if payload.len() < 3 {
866 return self.nrc(
867 src,
868 0x31,
869 H::Error::incorrect_message_length_or_invalid_format(),
870 now,
871 );
872 }
873
874 let sub_function = frame.sub_function_value().unwrap_or(0);
875 let routine_id = u16::from_be_bytes([payload[1], payload[2]]);
876 let option_record = payload.get(3..).unwrap_or(&[]);
877
878 let mut buf = [0u8; MAX_FRAME];
879 let len = self
880 .handler
881 .routine_control(routine_id, sub_function, option_record, &mut buf)
882 .map_err(ServerError::Handler)?;
883
884 if suppressed {
885 return Ok(());
886 }
887
888 let mut resp: Vec<u8, MAX_FRAME> = Vec::new();
889 let _ = resp.push(sub_function);
890 let _ = resp.push(payload[1]);
891 let _ = resp.push(payload[2]);
892 let _ = resp.extend_from_slice(&buf[..len]);
893 self.pos(src, 0x31, &resp, now)
894 }
895
896 fn on_communication_control(
897 &mut self,
898 src: &NodeAddress,
899 frame: &UdsFrame<'_>,
900 suppressed: bool,
901 now: Instant,
902 ) -> Result<(), ServerError<H::Error>> {
903 let payload = frame.payload();
904 if payload.len() < 2 {
905 return self.nrc(
906 src,
907 0x28,
908 H::Error::incorrect_message_length_or_invalid_format(),
909 now,
910 );
911 }
912
913 let control_type = frame.sub_function_value().unwrap_or(0);
914 let comm_type = payload[1];
915
916 self.handler
917 .communication_control(control_type, comm_type)
918 .map_err(ServerError::Handler)?;
919
920 if suppressed {
921 return Ok(());
922 }
923
924 self.pos(src, 0x28, &[control_type], now)
925 }
926
927 fn on_io_control(
928 &mut self,
929 src: &NodeAddress,
930 frame: &UdsFrame<'_>,
931 _suppressed: bool,
932 now: Instant,
933 ) -> Result<(), ServerError<H::Error>> {
934 let payload = frame.payload();
935 if payload.len() < 3 {
936 return self.nrc(
937 src,
938 0x2F,
939 H::Error::incorrect_message_length_or_invalid_format(),
940 now,
941 );
942 }
943
944 let did = u16::from_be_bytes([payload[0], payload[1]]);
945 let control_param = payload[2];
946 let control_state = payload.get(3..).unwrap_or(&[]);
947
948 let mut buf = [0u8; MAX_FRAME];
949 let len = self
950 .handler
951 .io_control(did, control_param, control_state, &mut buf)
952 .map_err(ServerError::Handler)?;
953
954 let mut resp: Vec<u8, MAX_FRAME> = Vec::new();
955 let _ = resp.push(payload[0]);
956 let _ = resp.push(payload[1]);
957 let _ = resp.extend_from_slice(&buf[..len]);
958 self.pos(src, 0x2F, &resp, now)
959 }
960
961 fn on_request_download(
962 &mut self,
963 src: &NodeAddress,
964 frame: &UdsFrame<'_>,
965 _suppressed: bool,
966 now: Instant,
967 ) -> Result<(), ServerError<H::Error>> {
968 let payload = frame.payload();
971 if payload.len() < 3 {
972 return self.nrc(
973 src,
974 0x34,
975 H::Error::incorrect_message_length_or_invalid_format(),
976 now,
977 );
978 }
979
980 let data_format = payload[0];
981 let addr_and_len_format = payload[1];
982 let addr_len = (addr_and_len_format >> 4) as usize;
983 let size_len = (addr_and_len_format & 0x0F) as usize;
984
985 if payload.len() < 2 + addr_len + size_len {
986 return self.nrc(
987 src,
988 0x34,
989 H::Error::incorrect_message_length_or_invalid_format(),
990 now,
991 );
992 }
993
994 let memory_address = &payload[2..2 + addr_len];
995 let memory_size = &payload[2 + addr_len..2 + addr_len + size_len];
996
997 let mut buf = [0u8; 64];
998 let len = self
999 .handler
1000 .request_download(memory_address, memory_size, data_format, 0, &mut buf)
1001 .map_err(ServerError::Handler)?;
1002
1003 self.pos(src, 0x34, &buf[..len], now)
1004 }
1005
1006 fn on_transfer_data(
1007 &mut self,
1008 src: &NodeAddress,
1009 frame: &UdsFrame<'_>,
1010 _suppressed: bool,
1011 now: Instant,
1012 ) -> Result<(), ServerError<H::Error>> {
1013 let payload = frame.payload();
1014 if payload.is_empty() {
1015 return self.nrc(
1016 src,
1017 0x36,
1018 H::Error::incorrect_message_length_or_invalid_format(),
1019 now,
1020 );
1021 }
1022
1023 let block_seq = payload[0];
1024 let data = payload.get(1..).unwrap_or(&[]);
1025
1026 let mut buf = [0u8; MAX_FRAME];
1027 let len = self
1028 .handler
1029 .transfer_data(block_seq, data, &mut buf)
1030 .map_err(ServerError::Handler)?;
1031
1032 let mut resp: Vec<u8, MAX_FRAME> = Vec::new();
1033 let _ = resp.push(block_seq);
1034 let _ = resp.extend_from_slice(&buf[..len]);
1035 self.pos(src, 0x36, &resp, now)
1036 }
1037
1038 fn on_transfer_exit(
1039 &mut self,
1040 src: &NodeAddress,
1041 frame: &UdsFrame<'_>,
1042 _suppressed: bool,
1043 now: Instant,
1044 ) -> Result<(), ServerError<H::Error>> {
1045 let parameter_record = frame.payload();
1046
1047 let mut buf = [0u8; MAX_FRAME];
1048 let len = self
1049 .handler
1050 .request_transfer_exit(parameter_record, &mut buf)
1051 .map_err(ServerError::Handler)?;
1052
1053 self.pos(src, 0x37, &buf[..len], now)
1054 }
1055
1056 fn on_file_transfer(
1057 &mut self,
1058 src: &NodeAddress,
1059 frame: &UdsFrame<'_>,
1060 _suppressed: bool,
1061 now: Instant,
1062 ) -> Result<(), ServerError<H::Error>> {
1063 let payload = frame.payload();
1064 if payload.len() < 3 {
1065 return self.nrc(
1066 src,
1067 0x38,
1068 H::Error::incorrect_message_length_or_invalid_format(),
1069 now,
1070 );
1071 }
1072
1073 let operation = payload[0];
1074 let path_len = u16::from_be_bytes([payload[1], payload[2]]) as usize;
1076 let path = payload.get(3..3 + path_len).unwrap_or(&[]);
1077
1078 let mut buf = [0u8; MAX_FRAME];
1079 let len = self
1080 .handler
1081 .request_file_transfer(operation, path, &mut buf)
1082 .map_err(ServerError::Handler)?;
1083
1084 self.pos(src, 0x38, &buf[..len], now)
1085 }
1086
1087 fn dispatch_periodic(&mut self, now: Instant) -> Result<(), ServerError<H::Error>> {
1092 let mut due: Vec<(u16, NodeAddress), MAX_PERIODIC> = Vec::new();
1093 self.periodic.collect_due(now, &mut due);
1094
1095 for (did, client) in &due {
1096 let mut data_buf = [0u8; MAX_FRAME];
1097 let len = self
1098 .handler
1099 .read_did(*did, &mut data_buf)
1100 .map_err(ServerError::Handler)?;
1101
1102 let did_low = (*did & 0xFF) as u8;
1104 let mut frame = Vec::new();
1105 let _ = frame.push(did_low);
1106 let _ = frame.extend_from_slice(&data_buf[..len]);
1107
1108 self.enqueue(client.clone(), frame)?;
1109 self.periodic.advance(*did, client, now);
1110 }
1111
1112 Ok(())
1113 }
1114
1115 }
1117
1118