1use ace_proto::uds::UdsFrame;
4use ace_sim::clock::{Duration, Instant};
5use ace_sim::io::NodeAddress;
6use ace_uds::ext::UdsFrameExt;
7use ace_uds::message::service::UdsServiceRequest;
8use ace_uds::message::ServiceIdentifier;
9use heapless::Vec;
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 self.outbox
457 .push((dst, frame))
458 .map_err(|_| ServerError::OutboxFull)
459 }
460
461 fn pos(
462 &mut self,
463 dst: &NodeAddress,
464 request_sid: u8,
465 payload: &[u8],
466 _now: Instant,
467 ) -> Result<(), ServerError<H::Error>> {
468 let mut frame: Vec<u8, MAX_FRAME> = Vec::new();
469 let _ = frame.push(request_sid | 0x40);
470 let _ = frame.extend_from_slice(payload);
471
472 self.enqueue(dst.clone(), frame)
473 }
474
475 fn nrc(
476 &mut self,
477 dst: &NodeAddress,
478 request_sid: u8,
479 error: H::Error,
480 _now: Instant,
481 ) -> Result<(), ServerError<H::Error>> {
482 let nrc_byte: u8 = error.into();
483 self.nrc_raw(dst, request_sid, nrc_byte, _now)
484 }
485
486 fn nrc_raw(
487 &mut self,
488 dst: &NodeAddress,
489 request_sid: u8,
490 nrc_byte: u8,
491 _now: Instant,
492 ) -> Result<(), ServerError<H::Error>> {
493 let mut frame: Vec<u8, MAX_FRAME> = Vec::new();
494 let _ = frame.push(0x7F);
495 let _ = frame.push(request_sid);
496 let _ = frame.push(nrc_byte);
497 self.enqueue(dst.clone(), frame)
498 }
499
500 fn on_tester_present(
513 &mut self,
514 src: &NodeAddress,
515 frame: &UdsFrame<'_>,
516 suppressed: bool,
517 now: Instant,
518 ) -> Result<(), ServerError<H::Error>> {
519 if suppressed {
522 return Ok(());
523 }
524 let sf = frame.sub_function_value().unwrap_or(0x00);
526 self.pos(src, 0x3E, &[sf], now)
527 }
528
529 fn on_session_control(
530 &mut self,
531 src: &NodeAddress,
532 frame: &UdsFrame<'_>,
533 suppressed: bool,
534 now: Instant,
535 ) -> Result<(), ServerError<H::Error>> {
536 let session_type = match frame.sub_function_value() {
538 Some(v) => v,
539 None => {
540 return self.nrc(
541 src,
542 0x10,
543 H::Error::incorrect_message_length_or_invalid_format(),
544 now,
545 )
546 }
547 };
548
549 if self.config.find_session(session_type).is_none() {
550 return self.nrc(src, 0x10, H::Error::sub_function_not_supported(), now);
551 }
552
553 self.session.session_type = session_type;
554 self.session.security_level = 0;
555 self.session.last_rx = now;
556 self.security.clear_pending();
557
558 if suppressed {
559 return Ok(());
560 }
561
562 let (p2_ms, p2_ext_ms) = self
563 .config
564 .find_session(session_type)
565 .map(|s| {
566 (
567 s.p2_timeout.as_millis(),
568 s.p2_extended_timeout.as_millis() / 10,
569 )
570 })
571 .unwrap_or((DEFAULT_P2, DEFAULT_P2_EXT));
572
573 let payload = [
574 session_type,
575 (p2_ms >> 8) as u8,
576 p2_ms as u8,
577 (p2_ext_ms >> 8) as u8,
578 p2_ext_ms as u8,
579 ];
580 self.pos(src, 0x10, &payload, now)
581 }
582
583 fn on_ecu_reset(
584 &mut self,
585 src: &NodeAddress,
586 frame: &UdsFrame<'_>,
587 suppressed: bool,
588 now: Instant,
589 ) -> Result<(), ServerError<H::Error>> {
590 let reset_type = match frame.sub_function_value() {
592 Some(v) => v,
593 None => {
594 return self.nrc(
595 src,
596 0x11,
597 H::Error::incorrect_message_length_or_invalid_format(),
598 now,
599 )
600 }
601 };
602
603 if !suppressed {
604 self.pos(src, 0x11, &[reset_type], now)?;
605 }
606
607 self.handler
608 .ecu_reset(reset_type)
609 .map_err(ServerError::Handler)
610 }
611
612 fn on_security_access(
613 &mut self,
614 src: &NodeAddress,
615 frame: &UdsFrame<'_>,
616 _suppressed: bool, now: Instant,
618 ) -> Result<(), ServerError<H::Error>> {
619 let access_type = match frame.sub_function_value() {
621 Some(v) => v,
622 None => {
623 return self.nrc(
624 src,
625 0x27,
626 H::Error::incorrect_message_length_or_invalid_format(),
627 now,
628 )
629 }
630 };
631
632 let is_request_seed = access_type % 2 != 0;
633
634 if is_request_seed {
635 let level = access_type;
636
637 if self.security.is_locked(level, now) {
638 return self.nrc(src, 0x27, H::Error::required_time_delay_not_expired(), now);
639 }
640 if self.config.find_security_level(level).is_none() {
641 return self.nrc(src, 0x27, H::Error::sub_function_not_supported(), now);
642 }
643
644 let mut seed_buf = [0u8; MAX_SEED];
645 let seed_len = self
646 .security_provider
647 .generate_seed(level, &mut seed_buf)
648 .map_err(|_| ServerError::Handler(H::Error::conditions_not_correct()))?;
649
650 self.security.pending_seed.clear();
651 let _ = self
652 .security
653 .pending_seed
654 .extend_from_slice(&seed_buf[..seed_len]);
655 self.security.pending_level = level;
656
657 let mut payload: Vec<u8, MAX_SEED> = Vec::new();
658 let _ = payload.push(level);
659 let _ = payload.extend_from_slice(&seed_buf[..seed_len]);
660 self.pos(src, 0x27, &payload, now)
661 } else {
662 let level = access_type - 1; if self.security.is_locked(level, now) {
666 return self.nrc(src, 0x27, H::Error::required_time_delay_not_expired(), now);
667 }
668 if self.security.pending_level != level || self.security.pending_seed.is_empty() {
669 return self.nrc(src, 0x27, H::Error::request_sequence_error(), now);
670 }
671
672 let key = frame.payload().get(1..).unwrap_or(&[]);
675
676 let level_cfg = self.config.find_security_level(level);
677 let max_attempts = level_cfg
678 .map(|l| l.max_attempts)
679 .unwrap_or(DEFAULT_MAX_SECURITY_ATTEMPTS);
680 let lockout_dur = level_cfg
681 .map(|l| l.lockout_duration)
682 .unwrap_or(Duration::from_millis(DEFAULT_LOCKOUT));
683
684 let seed = self.security.pending_seed.clone();
685
686 match self.security_provider.validate_key(level, &seed, key) {
687 Ok(()) => {
688 self.security.reset_failed(level);
689 self.security.clear_pending();
690 self.session.security_level = level;
691 self.pos(src, 0x27, &[access_type], now)
692 }
693 Err(_) => {
694 self.security.increment_failed(level);
695 if self.security.failed_count(level) >= max_attempts {
696 self.security.set_lockout(level, now + lockout_dur);
697 return self.nrc(src, 0x27, H::Error::exceeded_number_of_attempts(), now);
698 }
699 self.nrc(src, 0x27, H::Error::invalid_key(), now)
700 }
701 }
702 }
703 }
704
705 fn on_read_did(
706 &mut self,
707 src: &NodeAddress,
708 frame: &UdsFrame<'_>,
709 _suppressed: bool, now: Instant,
711 ) -> Result<(), ServerError<H::Error>> {
712 let payload = frame.payload();
714 if payload.len() < 2 || payload.len() % 2 != 0 {
715 return self.nrc(
716 src,
717 0x22,
718 H::Error::incorrect_message_length_or_invalid_format(),
719 now,
720 );
721 }
722
723 let mut resp: Vec<u8, MAX_FRAME> = Vec::new();
724
725 for chunk in payload.chunks_exact(2) {
726 let did = u16::from_be_bytes([chunk[0], chunk[1]]);
727
728 if !self.config.did_readable(did, self.session.session_type) {
729 return self.nrc(src, 0x22, H::Error::request_out_of_range(), now);
730 }
731 let required_sec = self
732 .config
733 .find_did(did)
734 .map(|d| d.security_level)
735 .unwrap_or(0);
736 if let Err(nrc) = self.guard_security(required_sec) {
737 return self.nrc_raw(src, 0x22, nrc, now);
738 }
739
740 let _ = resp.push(chunk[0]);
741 let _ = resp.push(chunk[1]);
742
743 let mut data_buf = [0u8; MAX_FRAME];
744 let len = self
745 .handler
746 .read_did(did, &mut data_buf)
747 .map_err(ServerError::Handler)?;
748 let _ = resp.extend_from_slice(&data_buf[..len]);
749 }
750
751 self.pos(src, 0x22, &resp, now)
752 }
753
754 fn on_write_did(
755 &mut self,
756 src: &NodeAddress,
757 frame: &UdsFrame<'_>,
758 _suppressed: bool,
759 now: Instant,
760 ) -> Result<(), ServerError<H::Error>> {
761 let payload = frame.payload();
762 if payload.len() < 3 {
763 return self.nrc(
764 src,
765 0x2E,
766 H::Error::incorrect_message_length_or_invalid_format(),
767 now,
768 );
769 }
770
771 let did = u16::from_be_bytes([payload[0], payload[1]]);
772 let data_rec = &payload[2..];
773
774 if !self.config.did_writable(did, self.session.session_type) {
775 return self.nrc(src, 0x2E, H::Error::request_out_of_range(), now);
776 }
777 let required_sec = self
778 .config
779 .find_did(did)
780 .map(|d| d.security_level)
781 .unwrap_or(0);
782 if let Err(nrc) = self.guard_security(required_sec) {
783 return self.nrc_raw(src, 0x2E, nrc, now);
784 }
785
786 self.handler
787 .write_did(did, data_rec)
788 .map_err(ServerError::Handler)?;
789
790 self.pos(src, 0x2E, &payload[..2], now)
791 }
792
793 fn on_periodic_did(
794 &mut self,
795 src: &NodeAddress,
796 frame: &UdsFrame<'_>,
797 _suppressed: bool,
798 now: Instant,
799 ) -> Result<(), ServerError<H::Error>> {
800 let payload = frame.payload();
801 if payload.is_empty() {
802 return self.nrc(
803 src,
804 0x2A,
805 H::Error::incorrect_message_length_or_invalid_format(),
806 now,
807 );
808 }
809
810 let mode = payload[0];
812 let periodic_ids = payload.get(1..).unwrap_or(&[]);
813
814 match mode {
815 0x04 => {
817 for &id in periodic_ids {
818 self.periodic.cancel(0xF200u16 | id as u16, src);
819 }
820 self.pos(src, 0x2A, &[mode], now)
821 }
822 0x01 | 0x02 | 0x03 => {
823 let requested_interval = match mode {
824 0x01 => periodic::SLOW,
825 0x02 => periodic::MEDIUM,
826 _ => periodic::FAST,
827 };
828
829 for &id in periodic_ids {
830 let did = 0xF200u16 | id as u16;
831
832 if !self.config.did_readable(did, self.session.session_type) {
833 return self.nrc(src, 0x2A, H::Error::request_out_of_range(), now);
834 }
835
836 let effective = self
837 .config
838 .find_did(did)
839 .map(|d| requested_interval.max(d.min_periodic_interval))
840 .unwrap_or(requested_interval);
841
842 self.periodic.register(did, effective, src.clone(), now);
843 }
844
845 self.pos(src, 0x2A, &[mode], now)
846 }
847 _ => self.nrc(src, 0x2A, H::Error::sub_function_not_supported(), now),
848 }
849 }
850
851 fn on_routine_control(
852 &mut self,
853 src: &NodeAddress,
854 frame: &UdsFrame<'_>,
855 suppressed: bool,
856 now: Instant,
857 ) -> Result<(), ServerError<H::Error>> {
858 let payload = frame.payload();
861 if payload.len() < 3 {
862 return self.nrc(
863 src,
864 0x31,
865 H::Error::incorrect_message_length_or_invalid_format(),
866 now,
867 );
868 }
869
870 let sub_function = frame.sub_function_value().unwrap_or(0);
871 let routine_id = u16::from_be_bytes([payload[1], payload[2]]);
872 let option_record = payload.get(3..).unwrap_or(&[]);
873
874 let mut buf = [0u8; MAX_FRAME];
875 let len = self
876 .handler
877 .routine_control(routine_id, sub_function, option_record, &mut buf)
878 .map_err(ServerError::Handler)?;
879
880 if suppressed {
881 return Ok(());
882 }
883
884 let mut resp: Vec<u8, MAX_FRAME> = Vec::new();
885 let _ = resp.push(sub_function);
886 let _ = resp.push(payload[1]);
887 let _ = resp.push(payload[2]);
888 let _ = resp.extend_from_slice(&buf[..len]);
889 self.pos(src, 0x31, &resp, now)
890 }
891
892 fn on_communication_control(
893 &mut self,
894 src: &NodeAddress,
895 frame: &UdsFrame<'_>,
896 suppressed: bool,
897 now: Instant,
898 ) -> Result<(), ServerError<H::Error>> {
899 let payload = frame.payload();
900 if payload.len() < 2 {
901 return self.nrc(
902 src,
903 0x28,
904 H::Error::incorrect_message_length_or_invalid_format(),
905 now,
906 );
907 }
908
909 let control_type = frame.sub_function_value().unwrap_or(0);
910 let comm_type = payload[1];
911
912 self.handler
913 .communication_control(control_type, comm_type)
914 .map_err(ServerError::Handler)?;
915
916 if suppressed {
917 return Ok(());
918 }
919
920 self.pos(src, 0x28, &[control_type], now)
921 }
922
923 fn on_io_control(
924 &mut self,
925 src: &NodeAddress,
926 frame: &UdsFrame<'_>,
927 _suppressed: bool,
928 now: Instant,
929 ) -> Result<(), ServerError<H::Error>> {
930 let payload = frame.payload();
931 if payload.len() < 3 {
932 return self.nrc(
933 src,
934 0x2F,
935 H::Error::incorrect_message_length_or_invalid_format(),
936 now,
937 );
938 }
939
940 let did = u16::from_be_bytes([payload[0], payload[1]]);
941 let control_param = payload[2];
942 let control_state = payload.get(3..).unwrap_or(&[]);
943
944 let mut buf = [0u8; MAX_FRAME];
945 let len = self
946 .handler
947 .io_control(did, control_param, control_state, &mut buf)
948 .map_err(ServerError::Handler)?;
949
950 let mut resp: Vec<u8, MAX_FRAME> = Vec::new();
951 let _ = resp.push(payload[0]);
952 let _ = resp.push(payload[1]);
953 let _ = resp.extend_from_slice(&buf[..len]);
954 self.pos(src, 0x2F, &resp, now)
955 }
956
957 fn on_request_download(
958 &mut self,
959 src: &NodeAddress,
960 frame: &UdsFrame<'_>,
961 _suppressed: bool,
962 now: Instant,
963 ) -> Result<(), ServerError<H::Error>> {
964 let payload = frame.payload();
967 if payload.len() < 3 {
968 return self.nrc(
969 src,
970 0x34,
971 H::Error::incorrect_message_length_or_invalid_format(),
972 now,
973 );
974 }
975
976 let data_format = payload[0];
977 let addr_and_len_format = payload[1];
978 let addr_len = (addr_and_len_format >> 4) as usize;
979 let size_len = (addr_and_len_format & 0x0F) as usize;
980
981 if payload.len() < 2 + addr_len + size_len {
982 return self.nrc(
983 src,
984 0x34,
985 H::Error::incorrect_message_length_or_invalid_format(),
986 now,
987 );
988 }
989
990 let memory_address = &payload[2..2 + addr_len];
991 let memory_size = &payload[2 + addr_len..2 + addr_len + size_len];
992
993 let mut buf = [0u8; 64];
994 let len = self
995 .handler
996 .request_download(memory_address, memory_size, data_format, 0, &mut buf)
997 .map_err(ServerError::Handler)?;
998
999 self.pos(src, 0x34, &buf[..len], now)
1000 }
1001
1002 fn on_transfer_data(
1003 &mut self,
1004 src: &NodeAddress,
1005 frame: &UdsFrame<'_>,
1006 _suppressed: bool,
1007 now: Instant,
1008 ) -> Result<(), ServerError<H::Error>> {
1009 let payload = frame.payload();
1010 if payload.is_empty() {
1011 return self.nrc(
1012 src,
1013 0x36,
1014 H::Error::incorrect_message_length_or_invalid_format(),
1015 now,
1016 );
1017 }
1018
1019 let block_seq = payload[0];
1020 let data = payload.get(1..).unwrap_or(&[]);
1021
1022 let mut buf = [0u8; MAX_FRAME];
1023 let len = self
1024 .handler
1025 .transfer_data(block_seq, data, &mut buf)
1026 .map_err(ServerError::Handler)?;
1027
1028 let mut resp: Vec<u8, MAX_FRAME> = Vec::new();
1029 let _ = resp.push(block_seq);
1030 let _ = resp.extend_from_slice(&buf[..len]);
1031 self.pos(src, 0x36, &resp, now)
1032 }
1033
1034 fn on_transfer_exit(
1035 &mut self,
1036 src: &NodeAddress,
1037 frame: &UdsFrame<'_>,
1038 _suppressed: bool,
1039 now: Instant,
1040 ) -> Result<(), ServerError<H::Error>> {
1041 let parameter_record = frame.payload();
1042
1043 let mut buf = [0u8; MAX_FRAME];
1044 let len = self
1045 .handler
1046 .request_transfer_exit(parameter_record, &mut buf)
1047 .map_err(ServerError::Handler)?;
1048
1049 self.pos(src, 0x37, &buf[..len], now)
1050 }
1051
1052 fn on_file_transfer(
1053 &mut self,
1054 src: &NodeAddress,
1055 frame: &UdsFrame<'_>,
1056 _suppressed: bool,
1057 now: Instant,
1058 ) -> Result<(), ServerError<H::Error>> {
1059 let payload = frame.payload();
1060 if payload.len() < 3 {
1061 return self.nrc(
1062 src,
1063 0x38,
1064 H::Error::incorrect_message_length_or_invalid_format(),
1065 now,
1066 );
1067 }
1068
1069 let operation = payload[0];
1070 let path_len = u16::from_be_bytes([payload[1], payload[2]]) as usize;
1072 let path = payload.get(3..3 + path_len).unwrap_or(&[]);
1073
1074 let mut buf = [0u8; MAX_FRAME];
1075 let len = self
1076 .handler
1077 .request_file_transfer(operation, path, &mut buf)
1078 .map_err(ServerError::Handler)?;
1079
1080 self.pos(src, 0x38, &buf[..len], now)
1081 }
1082
1083 fn dispatch_periodic(&mut self, now: Instant) -> Result<(), ServerError<H::Error>> {
1088 let mut due: Vec<(u16, NodeAddress), MAX_PERIODIC> = Vec::new();
1089 self.periodic.collect_due(now, &mut due);
1090
1091 for (did, client) in &due {
1092 let mut data_buf = [0u8; MAX_FRAME];
1093 let len = self
1094 .handler
1095 .read_did(*did, &mut data_buf)
1096 .map_err(ServerError::Handler)?;
1097
1098 let did_low = (*did & 0xFF) as u8;
1100 let mut frame = Vec::new();
1101 let _ = frame.push(did_low);
1102 let _ = frame.extend_from_slice(&data_buf[..len]);
1103
1104 self.enqueue(client.clone(), frame)?;
1105 self.periodic.advance(*did, client, now);
1106 }
1107
1108 Ok(())
1109 }
1110
1111 }
1113
1114