1use crate::{id::CanId, CanError, ConstructionError};
34use embedded_can::{ExtendedId, Frame as EmbeddedFrame, Id, StandardId};
35use itertools::Itertools;
36use libc::{can_frame, canfd_frame, canid_t};
37use std::{
38 ffi::c_void,
39 mem::size_of,
40 {convert::TryFrom, fmt, matches, mem},
41};
42
43pub use crate::id::{
45 id_from_raw, id_is_extended, id_to_canid_t, FdFlags, IdFlags, CANFD_BRS, CANFD_ESI, CANFD_FDF,
46 CANFD_MAX_DLEN, CAN_EFF_FLAG, CAN_EFF_MASK, CAN_ERR_FLAG, CAN_ERR_MASK, CAN_MAX_DLEN,
47 CAN_RTR_FLAG, CAN_SFF_MASK, ERR_MASK_ALL, ERR_MASK_NONE,
48};
49
50#[inline(always)]
55pub fn can_frame_default() -> can_frame {
56 unsafe { mem::zeroed() }
57}
58
59#[inline(always)]
62pub fn canfd_frame_default() -> canfd_frame {
63 unsafe { mem::zeroed() }
64}
65
66pub trait AsPtr {
70 type Inner;
72
73 fn as_ptr(&self) -> *const Self::Inner;
75
76 fn as_mut_ptr(&mut self) -> *mut Self::Inner;
78
79 fn size(&self) -> usize {
81 size_of::<Self::Inner>()
82 }
83
84 fn as_bytes(&self) -> &[u8] {
86 unsafe {
87 std::slice::from_raw_parts::<'_, u8>(
88 self.as_ptr() as *const _ as *const u8,
89 self.size(),
90 )
91 }
92 }
93
94 fn as_bytes_mut(&mut self) -> &[u8] {
96 unsafe {
97 std::slice::from_raw_parts::<'_, u8>(
98 self.as_mut_ptr() as *mut _ as *mut u8,
99 self.size(),
100 )
101 }
102 }
103}
104
105#[allow(clippy::len_without_is_empty)]
109pub trait Frame: EmbeddedFrame {
110 fn from_raw_id(id: u32, data: &[u8]) -> Option<Self> {
116 Self::new(id_from_raw(id)?, data)
117 }
118
119 fn remote_from_raw_id(id: u32, dlc: usize) -> Option<Self> {
125 Self::new_remote(id_from_raw(id)?, dlc)
126 }
127
128 fn id_word(&self) -> canid_t;
130
131 fn raw_id(&self) -> canid_t {
133 let mask = if self.is_extended() {
134 CAN_EFF_MASK
135 } else {
136 CAN_SFF_MASK
137 };
138 self.id_word() & mask
139 }
140
141 fn id_flags(&self) -> IdFlags {
143 IdFlags::from_bits_truncate(self.id_word())
144 }
145
146 fn can_id(&self) -> CanId {
148 if self.is_extended() {
149 ExtendedId::new(self.id_word() & CAN_EFF_MASK)
150 .unwrap()
151 .into()
152 } else {
153 StandardId::new((self.id_word() & CAN_SFF_MASK) as u16)
154 .unwrap()
155 .into()
156 }
157 }
158
159 fn hal_id(&self) -> Id {
161 self.can_id().as_id()
162 }
163
164 fn len(&self) -> usize {
166 self.dlc()
168 }
169
170 fn is_error_frame(&self) -> bool {
172 self.id_flags().contains(IdFlags::ERR)
173 }
174
175 fn set_id(&mut self, id: impl Into<Id>);
177
178 fn set_data(&mut self, data: &[u8]) -> Result<(), ConstructionError>;
180}
181
182#[allow(missing_debug_implementations)]
186#[derive(Clone, Copy)]
187pub enum CanRawFrame {
188 Classic(can_frame),
190 Fd(canfd_frame),
192}
193
194impl From<can_frame> for CanRawFrame {
195 fn from(frame: can_frame) -> Self {
196 Self::Classic(frame)
197 }
198}
199
200impl From<canfd_frame> for CanRawFrame {
201 fn from(frame: canfd_frame) -> Self {
202 Self::Fd(frame)
203 }
204}
205
206#[derive(Clone, Copy, Debug)]
208pub enum CanAnyFrame {
209 Normal(CanDataFrame),
211 Remote(CanRemoteFrame),
213 Error(CanErrorFrame),
215 Fd(CanFdFrame),
217}
218
219impl Frame for CanAnyFrame {
220 fn id_word(&self) -> canid_t {
222 use CanAnyFrame::*;
223 match self {
224 Normal(frame) => frame.id_word(),
225 Remote(frame) => frame.id_word(),
226 Error(frame) => frame.id_word(),
227 Fd(frame) => frame.id_word(),
228 }
229 }
230
231 fn set_id(&mut self, id: impl Into<Id>) {
233 use CanAnyFrame::*;
234 match self {
235 Normal(frame) => frame.set_id(id),
236 Remote(frame) => frame.set_id(id),
237 Error(frame) => frame.set_id(id),
238 Fd(frame) => frame.set_id(id),
239 }
240 }
241
242 fn set_data(&mut self, data: &[u8]) -> Result<(), ConstructionError> {
244 use CanAnyFrame::*;
245 match self {
246 Normal(frame) => frame.set_data(data),
247 Remote(frame) => frame.set_data(data),
248 Error(frame) => frame.set_data(data),
249 Fd(frame) => frame.set_data(data),
250 }
251 }
252}
253
254impl EmbeddedFrame for CanAnyFrame {
255 fn new(id: impl Into<Id>, data: &[u8]) -> Option<Self> {
258 if data.len() <= CAN_MAX_DLEN {
259 CanDataFrame::new(id, data).map(CanAnyFrame::Normal)
260 } else {
261 CanFdFrame::new(id, data).map(CanAnyFrame::Fd)
262 }
263 }
264
265 fn new_remote(id: impl Into<Id>, dlc: usize) -> Option<Self> {
267 CanRemoteFrame::new_remote(id, dlc).map(CanAnyFrame::Remote)
268 }
269
270 fn is_extended(&self) -> bool {
272 use CanAnyFrame::*;
273 match self {
274 Normal(frame) => frame.is_extended(),
275 Remote(frame) => frame.is_extended(),
276 Error(frame) => frame.is_extended(),
277 Fd(frame) => frame.is_extended(),
278 }
279 }
280
281 fn is_remote_frame(&self) -> bool {
283 matches!(self, CanAnyFrame::Remote(_))
284 }
285
286 fn id(&self) -> Id {
288 use CanAnyFrame::*;
289 match self {
290 Normal(frame) => frame.id(),
291 Remote(frame) => frame.id(),
292 Error(frame) => frame.id(),
293 Fd(frame) => frame.id(),
294 }
295 }
296
297 fn dlc(&self) -> usize {
299 use CanAnyFrame::*;
300 match self {
301 Normal(frame) => frame.dlc(),
302 Remote(frame) => frame.dlc(),
303 Error(frame) => frame.dlc(),
304 Fd(frame) => frame.dlc(),
305 }
306 }
307
308 fn data(&self) -> &[u8] {
310 use CanAnyFrame::*;
311 match self {
312 Normal(frame) => frame.data(),
313 Remote(frame) => frame.data(),
314 Error(frame) => frame.data(),
315 Fd(frame) => frame.data(),
316 }
317 }
318}
319
320impl fmt::UpperHex for CanAnyFrame {
321 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
322 use CanAnyFrame::*;
323 match self {
324 Normal(frame) => frame.fmt(f),
325 Remote(frame) => frame.fmt(f),
326 Error(frame) => frame.fmt(f),
327 Fd(frame) => frame.fmt(f),
328 }
329 }
330}
331
332impl From<CanFrame> for CanAnyFrame {
333 fn from(frame: CanFrame) -> Self {
334 use CanFrame::*;
335 match frame {
336 Data(frame) => Self::Normal(frame),
337 Remote(frame) => Self::Remote(frame),
338 Error(frame) => Self::Error(frame),
339 }
340 }
341}
342
343impl From<CanDataFrame> for CanAnyFrame {
344 fn from(frame: CanDataFrame) -> Self {
345 Self::Normal(frame)
346 }
347}
348
349impl From<CanRemoteFrame> for CanAnyFrame {
350 fn from(frame: CanRemoteFrame) -> Self {
351 Self::Remote(frame)
352 }
353}
354
355impl From<CanErrorFrame> for CanAnyFrame {
356 fn from(frame: CanErrorFrame) -> Self {
357 Self::Error(frame)
358 }
359}
360
361impl From<CanFdFrame> for CanAnyFrame {
362 fn from(frame: CanFdFrame) -> Self {
363 Self::Fd(frame)
364 }
365}
366
367impl From<can_frame> for CanAnyFrame {
368 fn from(frame: can_frame) -> Self {
369 let frame = CanFrame::from(frame);
370 frame.into()
371 }
372}
373
374impl From<canfd_frame> for CanAnyFrame {
375 fn from(frame: canfd_frame) -> Self {
376 let frame = CanFdFrame::from(frame);
377 frame.into()
378 }
379}
380
381impl From<CanRawFrame> for CanAnyFrame {
382 fn from(frame: CanRawFrame) -> Self {
383 use CanRawFrame::*;
384 match frame {
385 Classic(frame) => frame.into(),
386 Fd(frame) => frame.into(),
387 }
388 }
389}
390
391impl AsPtr for CanAnyFrame {
392 type Inner = c_void;
393
394 fn as_ptr(&self) -> *const Self::Inner {
395 use CanAnyFrame::*;
396 match self {
397 Normal(frame) => frame.as_ptr() as *const Self::Inner,
398 Remote(frame) => frame.as_ptr() as *const Self::Inner,
399 Error(frame) => frame.as_ptr() as *const Self::Inner,
400 Fd(frame) => frame.as_ptr() as *const Self::Inner,
401 }
402 }
403
404 fn as_mut_ptr(&mut self) -> *mut Self::Inner {
405 use CanAnyFrame::*;
406 match self {
407 Normal(frame) => frame.as_mut_ptr() as *mut Self::Inner,
408 Remote(frame) => frame.as_mut_ptr() as *mut Self::Inner,
409 Error(frame) => frame.as_mut_ptr() as *mut Self::Inner,
410 Fd(frame) => frame.as_mut_ptr() as *mut Self::Inner,
411 }
412 }
413
414 fn size(&self) -> usize {
415 use CanAnyFrame::*;
416 match self {
417 Normal(frame) => frame.size(),
418 Remote(frame) => frame.size(),
419 Error(frame) => frame.size(),
420 Fd(frame) => frame.size(),
421 }
422 }
423}
424
425impl TryFrom<CanAnyFrame> for CanDataFrame {
426 type Error = ConstructionError;
427
428 fn try_from(frame: CanAnyFrame) -> Result<Self, Self::Error> {
429 match frame {
430 CanAnyFrame::Normal(f) => Ok(f),
431 _ => Err(ConstructionError::WrongFrameType),
432 }
433 }
434}
435
436impl TryFrom<CanAnyFrame> for CanRemoteFrame {
437 type Error = ConstructionError;
438
439 fn try_from(frame: CanAnyFrame) -> Result<Self, Self::Error> {
440 match frame {
441 CanAnyFrame::Remote(f) => Ok(f),
442 _ => Err(ConstructionError::WrongFrameType),
443 }
444 }
445}
446
447impl TryFrom<CanAnyFrame> for CanErrorFrame {
448 type Error = ConstructionError;
449
450 fn try_from(frame: CanAnyFrame) -> Result<Self, Self::Error> {
451 match frame {
452 CanAnyFrame::Error(f) => Ok(f),
453 _ => Err(ConstructionError::WrongFrameType),
454 }
455 }
456}
457
458impl TryFrom<CanAnyFrame> for CanFdFrame {
459 type Error = ConstructionError;
460
461 fn try_from(frame: CanAnyFrame) -> Result<Self, Self::Error> {
462 match frame {
463 CanAnyFrame::Fd(f) => Ok(f),
464 _ => Err(ConstructionError::WrongFrameType),
465 }
466 }
467}
468
469#[derive(Clone, Copy, Debug)]
473pub enum CanFrame {
474 Data(CanDataFrame),
476 Remote(CanRemoteFrame),
478 Error(CanErrorFrame),
480}
481
482impl AsPtr for CanFrame {
483 type Inner = can_frame;
484
485 fn as_ptr(&self) -> *const Self::Inner {
488 use CanFrame::*;
489 match self {
490 Data(frame) => frame.as_ptr(),
491 Remote(frame) => frame.as_ptr(),
492 Error(frame) => frame.as_ptr(),
493 }
494 }
495
496 fn as_mut_ptr(&mut self) -> *mut Self::Inner {
499 use CanFrame::*;
500 match self {
501 Data(frame) => frame.as_mut_ptr(),
502 Remote(frame) => frame.as_mut_ptr(),
503 Error(frame) => frame.as_mut_ptr(),
504 }
505 }
506}
507
508impl EmbeddedFrame for CanFrame {
509 fn new(id: impl Into<Id>, data: &[u8]) -> Option<Self> {
511 CanDataFrame::new(id, data).map(CanFrame::Data)
512 }
513
514 fn new_remote(id: impl Into<Id>, dlc: usize) -> Option<Self> {
516 CanRemoteFrame::new_remote(id, dlc).map(CanFrame::Remote)
517 }
518
519 fn is_extended(&self) -> bool {
521 use CanFrame::*;
522 match self {
523 Data(frame) => frame.is_extended(),
524 Remote(frame) => frame.is_extended(),
525 Error(frame) => frame.is_extended(),
526 }
527 }
528
529 fn is_remote_frame(&self) -> bool {
531 matches!(self, CanFrame::Remote(_))
532 }
533
534 fn id(&self) -> Id {
536 use CanFrame::*;
537 match self {
538 Data(frame) => frame.id(),
539 Remote(frame) => frame.id(),
540 Error(frame) => frame.id(),
541 }
542 }
543
544 fn dlc(&self) -> usize {
546 use CanFrame::*;
547 match self {
548 Data(frame) => frame.dlc(),
549 Remote(frame) => frame.dlc(),
550 Error(frame) => frame.dlc(),
551 }
552 }
553
554 fn data(&self) -> &[u8] {
556 use CanFrame::*;
557 match self {
558 Data(frame) => frame.data(),
559 Remote(frame) => frame.data(),
560 Error(frame) => frame.data(),
561 }
562 }
563}
564
565impl Frame for CanFrame {
566 fn id_word(&self) -> canid_t {
568 use CanFrame::*;
569 match self {
570 Data(frame) => frame.id_word(),
571 Remote(frame) => frame.id_word(),
572 Error(frame) => frame.id_word(),
573 }
574 }
575
576 fn set_id(&mut self, id: impl Into<Id>) {
578 use CanFrame::*;
579 match self {
580 Data(frame) => frame.set_id(id),
581 Remote(frame) => frame.set_id(id),
582 Error(frame) => frame.set_id(id),
583 }
584 }
585
586 fn set_data(&mut self, data: &[u8]) -> Result<(), ConstructionError> {
588 use CanFrame::*;
589 match self {
590 Data(frame) => frame.set_data(data),
591 Remote(frame) => frame.set_data(data),
592 Error(frame) => frame.set_data(data),
593 }
594 }
595}
596
597impl Default for CanFrame {
598 fn default() -> Self {
601 CanFrame::Data(CanDataFrame::default())
602 }
603}
604
605impl fmt::UpperHex for CanFrame {
606 fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
607 use CanFrame::*;
608 match self {
609 Data(frame) => fmt::UpperHex::fmt(&frame, f),
610 Remote(frame) => fmt::UpperHex::fmt(&frame, f),
611 Error(frame) => fmt::UpperHex::fmt(&frame, f),
612 }
613 }
614}
615
616impl From<can_frame> for CanFrame {
617 fn from(frame: can_frame) -> Self {
619 if frame.can_id & CAN_ERR_FLAG != 0 {
620 CanFrame::Error(CanErrorFrame(frame))
621 } else if frame.can_id & CAN_RTR_FLAG != 0 {
622 CanFrame::Remote(CanRemoteFrame(frame))
623 } else {
624 CanFrame::Data(CanDataFrame(frame))
625 }
626 }
627}
628
629impl From<CanDataFrame> for CanFrame {
630 fn from(frame: CanDataFrame) -> Self {
632 Self::Data(frame)
633 }
634}
635
636impl From<CanRemoteFrame> for CanFrame {
637 fn from(frame: CanRemoteFrame) -> Self {
639 Self::Remote(frame)
640 }
641}
642
643impl From<CanErrorFrame> for CanFrame {
644 fn from(frame: CanErrorFrame) -> Self {
646 Self::Error(frame)
647 }
648}
649
650impl AsRef<can_frame> for CanFrame {
651 fn as_ref(&self) -> &can_frame {
652 use CanFrame::*;
653 match self {
654 Data(frame) => frame.as_ref(),
655 Remote(frame) => frame.as_ref(),
656 Error(frame) => frame.as_ref(),
657 }
658 }
659}
660
661impl TryFrom<CanFrame> for CanDataFrame {
662 type Error = ConstructionError;
663
664 fn try_from(frame: CanFrame) -> Result<Self, Self::Error> {
665 match frame {
666 CanFrame::Data(f) => Ok(f),
667 _ => Err(ConstructionError::WrongFrameType),
668 }
669 }
670}
671
672impl TryFrom<CanFrame> for CanRemoteFrame {
673 type Error = ConstructionError;
674
675 fn try_from(frame: CanFrame) -> Result<Self, Self::Error> {
676 match frame {
677 CanFrame::Remote(f) => Ok(f),
678 _ => Err(ConstructionError::WrongFrameType),
679 }
680 }
681}
682
683impl TryFrom<CanFrame> for CanErrorFrame {
684 type Error = ConstructionError;
685
686 fn try_from(frame: CanFrame) -> Result<Self, Self::Error> {
687 match frame {
688 CanFrame::Error(f) => Ok(f),
689 _ => Err(ConstructionError::WrongFrameType),
690 }
691 }
692}
693
694impl TryFrom<CanFdFrame> for CanFrame {
695 type Error = ConstructionError;
696
697 fn try_from(frame: CanFdFrame) -> Result<Self, <Self as TryFrom<CanFdFrame>>::Error> {
701 CanDataFrame::try_from(frame).map(CanFrame::Data)
702 }
703}
704
705#[derive(Clone, Copy)]
712pub struct CanDataFrame(can_frame);
713
714impl CanDataFrame {
715 pub(crate) fn init(can_id: canid_t, data: &[u8]) -> Result<Self, ConstructionError> {
717 match data.len() {
718 n if n <= CAN_MAX_DLEN => {
719 let mut frame = can_frame_default();
720 frame.can_id = can_id;
721 frame.can_dlc = n as u8;
722 frame.data[..n].copy_from_slice(data);
723 Ok(Self(frame))
724 }
725 _ => Err(ConstructionError::TooMuchData),
726 }
727 }
728}
729
730impl AsPtr for CanDataFrame {
731 type Inner = can_frame;
732
733 fn as_ptr(&self) -> *const Self::Inner {
736 &self.0
737 }
738
739 fn as_mut_ptr(&mut self) -> *mut Self::Inner {
742 &mut self.0
743 }
744}
745
746impl EmbeddedFrame for CanDataFrame {
747 fn new(id: impl Into<Id>, data: &[u8]) -> Option<Self> {
749 let can_id = id_to_canid_t(id);
750 Self::init(can_id, data).ok()
751 }
752
753 fn new_remote(_id: impl Into<Id>, _dlc: usize) -> Option<Self> {
755 None
756 }
757
758 fn is_extended(&self) -> bool {
760 self.id_flags().contains(IdFlags::EFF)
761 }
762
763 fn is_remote_frame(&self) -> bool {
765 false
766 }
767
768 fn id(&self) -> Id {
770 self.hal_id()
771 }
772
773 fn dlc(&self) -> usize {
775 self.0.can_dlc as usize
776 }
777
778 fn data(&self) -> &[u8] {
780 &self.0.data[..(self.0.can_dlc as usize)]
781 }
782}
783
784impl Frame for CanDataFrame {
785 fn id_word(&self) -> canid_t {
787 self.0.can_id
788 }
789
790 fn set_id(&mut self, id: impl Into<Id>) {
792 self.0.can_id = id_to_canid_t(id);
793 }
794
795 fn set_data(&mut self, data: &[u8]) -> Result<(), ConstructionError> {
797 match data.len() {
798 n if n <= CAN_MAX_DLEN => {
799 self.0.can_dlc = n as u8;
800 self.0.data[..n].copy_from_slice(data);
801 Ok(())
802 }
803 _ => Err(ConstructionError::TooMuchData),
804 }
805 }
806}
807
808impl Default for CanDataFrame {
809 fn default() -> Self {
811 Self(can_frame_default())
812 }
813}
814
815impl fmt::Debug for CanDataFrame {
816 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
817 write!(f, "CanDataFrame {{ ")?;
818 fmt::UpperHex::fmt(self, f)?;
819 write!(f, " }}")
820 }
821}
822
823impl fmt::UpperHex for CanDataFrame {
824 fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
825 write!(f, "{:X}#", self.0.can_id)?;
826 let mut parts = self.data().iter().map(|v| format!("{:02X}", v));
827 write!(f, "{}", parts.join(" "))
828 }
829}
830
831impl TryFrom<can_frame> for CanDataFrame {
832 type Error = ConstructionError;
833
834 fn try_from(frame: can_frame) -> Result<Self, Self::Error> {
839 if frame.can_id & (CAN_ERR_FLAG | CAN_RTR_FLAG) == 0 {
840 Ok(Self(frame))
841 } else {
842 Err(ConstructionError::WrongFrameType)
843 }
844 }
845}
846
847impl TryFrom<CanFdFrame> for CanDataFrame {
848 type Error = ConstructionError;
849
850 fn try_from(frame: CanFdFrame) -> Result<Self, Self::Error> {
851 match frame.len() {
852 n if n > CAN_MAX_DLEN => Err(ConstructionError::TooMuchData),
853 n => CanDataFrame::init(frame.id_word(), &frame.data()[..n]),
854 }
855 }
856}
857
858impl AsRef<can_frame> for CanDataFrame {
859 fn as_ref(&self) -> &can_frame {
860 &self.0
861 }
862}
863
864#[derive(Clone, Copy)]
874pub struct CanRemoteFrame(can_frame);
875
876impl CanRemoteFrame {
877 pub(crate) fn init(can_id: canid_t, len: usize) -> Result<Self, ConstructionError> {
879 match len {
880 n if n <= CAN_MAX_DLEN => {
881 let mut frame = can_frame_default();
882 frame.can_id = can_id | CAN_RTR_FLAG;
883 frame.can_dlc = n as u8;
884 Ok(Self(frame))
885 }
886 _ => Err(ConstructionError::TooMuchData),
887 }
888 }
889
890 pub fn set_dlc(&mut self, dlc: usize) -> Result<(), ConstructionError> {
892 if dlc <= CAN_MAX_DLEN {
893 self.0.can_dlc = dlc as u8;
894 Ok(())
895 } else {
896 Err(ConstructionError::TooMuchData)
897 }
898 }
899}
900
901impl AsPtr for CanRemoteFrame {
902 type Inner = can_frame;
903
904 fn as_ptr(&self) -> *const Self::Inner {
907 &self.0
908 }
909
910 fn as_mut_ptr(&mut self) -> *mut Self::Inner {
913 &mut self.0
914 }
915}
916
917impl EmbeddedFrame for CanRemoteFrame {
918 fn new(id: impl Into<Id>, data: &[u8]) -> Option<Self> {
920 Self::new_remote(id, data.len())
921 }
922
923 fn new_remote(id: impl Into<Id>, dlc: usize) -> Option<Self> {
927 let can_id = id_to_canid_t(id);
928 Self::init(can_id, dlc).ok()
929 }
930
931 fn is_extended(&self) -> bool {
933 self.id_flags().contains(IdFlags::EFF)
934 }
935
936 fn is_remote_frame(&self) -> bool {
938 true
939 }
940
941 fn id(&self) -> Id {
943 self.hal_id()
944 }
945
946 fn dlc(&self) -> usize {
948 self.0.can_dlc as usize
949 }
950
951 fn data(&self) -> &[u8] {
953 &self.0.data[..self.dlc()]
955 }
956}
957
958impl Frame for CanRemoteFrame {
959 fn id_word(&self) -> canid_t {
961 self.0.can_id
962 }
963
964 fn set_id(&mut self, id: impl Into<Id>) {
968 self.0.can_id = id_to_canid_t(id) | CAN_RTR_FLAG;
969 }
970
971 fn set_data(&mut self, data: &[u8]) -> Result<(), ConstructionError> {
975 self.set_dlc(data.len())
976 }
977}
978
979impl Default for CanRemoteFrame {
980 fn default() -> Self {
982 let mut frame = can_frame_default();
983 frame.can_id |= CAN_RTR_FLAG;
984 Self(frame)
985 }
986}
987
988impl fmt::Debug for CanRemoteFrame {
989 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
990 write!(f, "CanRemoteFrame {{ ")?;
991 fmt::UpperHex::fmt(self, f)?;
992 write!(f, " }}")
993 }
994}
995
996impl fmt::UpperHex for CanRemoteFrame {
997 fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
998 write!(f, "{:X}#", self.0.can_id)?;
999 let mut parts = self.data().iter().map(|v| format!("{:02X}", v));
1000 write!(f, "{}", parts.join(" "))
1001 }
1002}
1003
1004impl TryFrom<can_frame> for CanRemoteFrame {
1005 type Error = ConstructionError;
1006
1007 fn try_from(frame: can_frame) -> Result<Self, Self::Error> {
1011 if frame.can_id & CAN_RTR_FLAG != 0 {
1012 Ok(Self(frame))
1013 } else {
1014 Err(ConstructionError::WrongFrameType)
1015 }
1016 }
1017}
1018
1019impl AsRef<can_frame> for CanRemoteFrame {
1020 fn as_ref(&self) -> &can_frame {
1021 &self.0
1022 }
1023}
1024
1025#[derive(Clone, Copy)]
1037pub struct CanErrorFrame(can_frame);
1038
1039impl CanErrorFrame {
1040 pub fn new_error(can_id: canid_t, data: &[u8]) -> Result<Self, ConstructionError> {
1055 match data.len() {
1056 n if n <= CAN_MAX_DLEN => {
1057 let mut frame = can_frame_default();
1058 frame.can_id = (can_id & CAN_ERR_MASK) | CAN_ERR_FLAG;
1059 frame.can_dlc = CAN_MAX_DLEN as u8;
1060 frame.data[..n].copy_from_slice(data);
1061 Ok(Self(frame))
1062 }
1063 _ => Err(ConstructionError::TooMuchData),
1064 }
1065 }
1066
1067 pub fn error_bits(&self) -> u32 {
1069 self.id_word() & CAN_ERR_MASK
1070 }
1071
1072 pub fn into_error(self) -> CanError {
1074 CanError::from(self)
1075 }
1076}
1077
1078impl AsPtr for CanErrorFrame {
1079 type Inner = can_frame;
1080
1081 fn as_ptr(&self) -> *const Self::Inner {
1084 &self.0
1085 }
1086
1087 fn as_mut_ptr(&mut self) -> *mut Self::Inner {
1090 &mut self.0
1091 }
1092}
1093
1094impl EmbeddedFrame for CanErrorFrame {
1095 fn new(id: impl Into<Id>, data: &[u8]) -> Option<Self> {
1103 let can_id = id_to_canid_t(id);
1104 Self::new_error(can_id, data).ok()
1105 }
1106
1107 fn new_remote(_id: impl Into<Id>, _dlc: usize) -> Option<Self> {
1110 None
1111 }
1112
1113 fn is_extended(&self) -> bool {
1115 self.id_flags().contains(IdFlags::EFF)
1116 }
1117
1118 fn is_remote_frame(&self) -> bool {
1120 false
1121 }
1122
1123 fn is_data_frame(&self) -> bool {
1125 false
1126 }
1127
1128 fn id(&self) -> Id {
1130 self.hal_id()
1131 }
1132
1133 fn dlc(&self) -> usize {
1135 self.0.can_dlc as usize
1136 }
1137
1138 fn data(&self) -> &[u8] {
1141 &self.0.data[..]
1142 }
1143}
1144
1145impl Frame for CanErrorFrame {
1146 fn id_word(&self) -> canid_t {
1148 self.0.can_id
1149 }
1150
1151 fn set_id(&mut self, _id: impl Into<Id>) {}
1154
1155 fn set_data(&mut self, _data: &[u8]) -> Result<(), ConstructionError> {
1158 Err(ConstructionError::WrongFrameType)
1159 }
1160}
1161
1162impl fmt::Debug for CanErrorFrame {
1163 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1164 write!(f, "CanErrorFrame {{ ")?;
1165 fmt::UpperHex::fmt(self, f)?;
1166 write!(f, " }}")
1167 }
1168}
1169
1170impl fmt::UpperHex for CanErrorFrame {
1171 fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
1172 write!(f, "{:X}#", self.0.can_id)?;
1173 let mut parts = self.data().iter().map(|v| format!("{:02X}", v));
1174 write!(f, "{}", parts.join(" "))
1175 }
1176}
1177
1178impl TryFrom<can_frame> for CanErrorFrame {
1179 type Error = ConstructionError;
1180
1181 fn try_from(frame: can_frame) -> Result<Self, Self::Error> {
1185 if frame.can_id & CAN_ERR_FLAG != 0 {
1186 Ok(Self(frame))
1187 } else {
1188 Err(ConstructionError::WrongFrameType)
1189 }
1190 }
1191}
1192
1193impl From<CanError> for CanErrorFrame {
1194 fn from(err: CanError) -> Self {
1195 use CanError::*;
1196
1197 let mut data = [0u8; CAN_MAX_DLEN];
1198 let id: canid_t = match err {
1199 TransmitTimeout => 0x0001,
1200 LostArbitration(bit) => {
1201 data[0] = bit;
1202 0x0002
1203 }
1204 ControllerProblem(prob) => {
1205 data[1] = prob as u8;
1206 0x0004
1207 }
1208 ProtocolViolation { vtype, location } => {
1209 data[2] = vtype as u8;
1210 data[3] = location as u8;
1211 0x0008
1212 }
1213 TransceiverError => 0x0010,
1214 NoAck => 0x0020,
1215 BusOff => 0x0040,
1216 BusError => 0x0080,
1217 Restarted => 0x0100,
1218 DecodingFailure(_failure) => 0,
1219 Unknown(e) => e,
1220 };
1221 Self::new_error(id, &data).unwrap()
1222 }
1223}
1224
1225impl AsRef<can_frame> for CanErrorFrame {
1226 fn as_ref(&self) -> &can_frame {
1227 &self.0
1228 }
1229}
1230
1231const VALID_EXT_DLENGTHS: [usize; 7] = [12, 16, 20, 24, 32, 48, 64];
1235
1236#[derive(Clone, Copy)]
1248pub struct CanFdFrame(canfd_frame);
1249
1250impl CanFdFrame {
1251 pub fn with_flags(id: impl Into<Id>, data: &[u8], flags: FdFlags) -> Option<Self> {
1253 let can_id = id_to_canid_t(id);
1254 Self::init(can_id, data, flags).ok()
1255 }
1256
1257 pub(crate) fn init(
1259 can_id: u32,
1260 data: &[u8],
1261 fd_flags: FdFlags,
1262 ) -> Result<Self, ConstructionError> {
1263 match data.len() {
1264 n if n <= CANFD_MAX_DLEN => {
1265 let mut frame = canfd_frame_default();
1266 frame.can_id = can_id;
1267 frame.flags = (fd_flags | FdFlags::FDF).bits();
1268 frame.data[..n].copy_from_slice(data);
1269 frame.len = Self::next_valid_ext_dlen(n) as u8;
1270 Ok(Self(frame))
1271 }
1272 _ => Err(ConstructionError::TooMuchData),
1273 }
1274 }
1275
1276 pub fn flags(&self) -> FdFlags {
1281 FdFlags::from_bits_truncate(self.0.flags)
1282 }
1283
1284 pub fn is_brs(&self) -> bool {
1287 self.flags().contains(FdFlags::BRS)
1288 }
1289
1290 pub fn set_brs(&mut self, on: bool) {
1292 if on {
1293 self.0.flags |= CANFD_BRS as u8;
1294 } else {
1295 self.0.flags &= !(CANFD_BRS as u8);
1296 }
1297 }
1298
1299 pub fn is_esi(&self) -> bool {
1301 self.flags().contains(FdFlags::ESI)
1302 }
1303
1304 pub fn set_esi(&mut self, on: bool) {
1306 if on {
1307 self.0.flags |= CANFD_ESI as u8;
1308 } else {
1309 self.0.flags &= !CANFD_ESI as u8;
1310 }
1311 }
1312
1313 pub fn is_valid_data_len(len: usize) -> bool {
1317 len <= CAN_MAX_DLEN || VALID_EXT_DLENGTHS.contains(&len)
1318 }
1319
1320 pub fn next_valid_ext_dlen(len: usize) -> usize {
1323 if len <= CAN_MAX_DLEN {
1324 return len;
1325 }
1326 for valid_ext_len in VALID_EXT_DLENGTHS {
1327 if valid_ext_len >= len {
1328 return valid_ext_len;
1329 }
1330 }
1331 CANFD_MAX_DLEN
1333 }
1334}
1335
1336impl AsPtr for CanFdFrame {
1337 type Inner = canfd_frame;
1338
1339 fn as_ptr(&self) -> *const Self::Inner {
1342 &self.0
1343 }
1344
1345 fn as_mut_ptr(&mut self) -> *mut Self::Inner {
1348 &mut self.0
1349 }
1350}
1351
1352impl EmbeddedFrame for CanFdFrame {
1353 fn new(id: impl Into<Id>, data: &[u8]) -> Option<Self> {
1355 let can_id = id_to_canid_t(id);
1356 Self::init(can_id, data, FdFlags::empty()).ok()
1357 }
1358
1359 fn new_remote(_id: impl Into<Id>, _dlc: usize) -> Option<Self> {
1361 None
1362 }
1363
1364 fn is_extended(&self) -> bool {
1366 self.id_flags().contains(IdFlags::EFF)
1367 }
1368
1369 fn is_remote_frame(&self) -> bool {
1371 false
1372 }
1373
1374 fn id(&self) -> Id {
1376 self.hal_id()
1377 }
1378
1379 fn dlc(&self) -> usize {
1381 match self.0.len {
1382 0..=8 => self.0.len as usize,
1383 12 => 0x09,
1384 16 => 0x0A,
1385 20 => 0x0B,
1386 24 => 0x0C,
1387 32 => 0x0D,
1388 48 => 0x0E,
1389 64 => 0x0F,
1390 _ => 0x00,
1393 }
1394 }
1395
1396 fn data(&self) -> &[u8] {
1400 &self.0.data[..(self.0.len as usize)]
1401 }
1402}
1403
1404impl Frame for CanFdFrame {
1405 fn id_word(&self) -> canid_t {
1407 self.0.can_id
1408 }
1409
1410 fn len(&self) -> usize {
1412 self.0.len as usize
1414 }
1415
1416 fn set_id(&mut self, id: impl Into<Id>) {
1418 self.0.can_id = id_to_canid_t(id);
1419 }
1420
1421 fn set_data(&mut self, data: &[u8]) -> Result<(), ConstructionError> {
1423 match data.len() {
1424 n if n <= CANFD_MAX_DLEN => {
1425 self.0.data[..n].copy_from_slice(data);
1426 self.0.data[n..].fill(0);
1427 self.0.len = Self::next_valid_ext_dlen(n) as u8;
1428 Ok(())
1429 }
1430 _ => Err(ConstructionError::TooMuchData),
1431 }
1432 }
1433}
1434
1435impl Default for CanFdFrame {
1436 fn default() -> Self {
1438 let mut frame = canfd_frame_default();
1439 frame.flags |= CANFD_FDF as u8;
1440 Self(frame)
1441 }
1442}
1443
1444impl fmt::Debug for CanFdFrame {
1445 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1446 write!(f, "CanFdFrame {{ ")?;
1447 fmt::UpperHex::fmt(self, f)?;
1448 write!(f, " }}")
1449 }
1450}
1451
1452impl fmt::UpperHex for CanFdFrame {
1453 fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
1454 write!(f, "{:X}##", self.0.can_id)?;
1455 write!(f, "{} ", self.0.flags)?;
1456 let mut parts = self.data().iter().map(|v| format!("{:02X}", v));
1457 write!(f, "{}", parts.join(" "))
1458 }
1459}
1460
1461impl From<CanDataFrame> for CanFdFrame {
1462 fn from(frame: CanDataFrame) -> Self {
1463 let n = frame.len();
1464
1465 let mut fdframe = canfd_frame_default();
1466 fdframe.can_id = frame.id_word();
1467 fdframe.flags = CANFD_FDF as u8;
1468 fdframe.len = n as u8;
1469 fdframe.data[..n].copy_from_slice(&frame.data()[..n]);
1470 Self(fdframe)
1471 }
1472}
1473
1474impl From<canfd_frame> for CanFdFrame {
1475 fn from(mut frame: canfd_frame) -> Self {
1476 frame.flags |= CANFD_FDF as u8;
1477 Self(frame)
1478 }
1479}
1480
1481impl AsRef<canfd_frame> for CanFdFrame {
1482 fn as_ref(&self) -> &canfd_frame {
1483 &self.0
1484 }
1485}
1486
1487#[cfg(test)]
1490mod tests {
1491 use super::*;
1492 use crate::errors;
1493
1494 const STD_ID: Id = Id::Standard(StandardId::MAX);
1495 const EXT_ID: Id = Id::Extended(ExtendedId::MAX);
1496
1497 const EXT_LOW_ID: Id = Id::Extended(unsafe { ExtendedId::new_unchecked(0x7FF) });
1498
1499 const DATA: &[u8] = &[0, 1, 2, 3];
1500 const DATA_LEN: usize = DATA.len();
1501
1502 const EXT_DATA: &[u8] = &[0xAB; 32];
1503 const EXT_DATA_DLC: usize = 0x0D;
1504
1505 const EXT_DATA_INVALID_DLEN: &[u8] =
1506 &[0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA];
1507 const EXT_DATA_PADDED: &[u8] = &[
1508 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0x00, 0x00,
1509 ];
1510 const EXT_DATA_PADDED_DLC: usize = 0x09;
1511
1512 const EMPTY_DATA: &[u8] = &[];
1513 const ZERO_DATA: &[u8] = &[0u8; DATA_LEN];
1514
1515 fn id_to_raw(id: Id) -> u32 {
1516 match id {
1517 Id::Standard(id) => id.as_raw() as u32,
1518 Id::Extended(id) => id.as_raw(),
1519 }
1520 }
1521
1522 #[test]
1523 fn test_bit_flags() {
1524 let mut flags = IdFlags::RTR;
1525 assert_eq!(CAN_RTR_FLAG, flags.bits());
1526
1527 flags.set(IdFlags::EFF, true);
1528 assert_eq!(CAN_RTR_FLAG, flags.bits() & CAN_RTR_FLAG);
1529 assert_eq!(CAN_EFF_FLAG, flags.bits() & CAN_EFF_FLAG);
1530
1531 flags.set(IdFlags::EFF, false);
1532 assert_eq!(CAN_RTR_FLAG, flags.bits() & CAN_RTR_FLAG);
1533 assert_eq!(0, flags.bits() & CAN_EFF_FLAG);
1534 }
1535
1536 #[test]
1537 fn test_defaults() {
1538 let frame = CanFrame::default();
1539
1540 assert_eq!(0, frame.id_word());
1541 assert_eq!(0, frame.raw_id());
1542 assert!(frame.id_flags().is_empty());
1543
1544 assert_eq!(0, frame.dlc());
1545 assert_eq!(0, frame.len());
1546 assert_eq!(EMPTY_DATA, frame.data());
1547 }
1548
1549 #[test]
1550 fn test_data_frame() {
1551 let frame = CanDataFrame::new(STD_ID, DATA).unwrap();
1552 assert_eq!(STD_ID, frame.id());
1553 assert_eq!(id_to_raw(STD_ID), frame.raw_id());
1554 assert!(frame.is_standard());
1555 assert!(!frame.is_extended());
1556 assert!(frame.is_data_frame());
1557 assert!(!frame.is_remote_frame());
1558 assert!(!frame.is_error_frame());
1559 assert_eq!(frame.data(), DATA);
1560 assert_eq!(frame.len(), DATA.len());
1561 assert_eq!(frame.data().len(), DATA.len());
1562 assert_eq!(frame.dlc(), DATA.len());
1563
1564 let frame = CanFrame::from(frame);
1565 assert_eq!(STD_ID, frame.id());
1566 assert_eq!(id_to_raw(STD_ID), frame.raw_id());
1567 assert!(frame.is_standard());
1568 assert!(!frame.is_extended());
1569 assert!(frame.is_data_frame());
1570 assert!(!frame.is_remote_frame());
1571 assert!(!frame.is_error_frame());
1572 assert_eq!(frame.data(), DATA);
1573 assert_eq!(frame.len(), DATA.len());
1574 assert_eq!(frame.data().len(), DATA.len());
1575 assert_eq!(frame.dlc(), DATA.len());
1576
1577 let frame = CanDataFrame::from_raw_id(StandardId::MAX.as_raw() as u32, DATA).unwrap();
1578 assert_eq!(STD_ID, frame.id());
1579 assert_eq!(id_to_raw(STD_ID), frame.raw_id());
1580 assert!(frame.is_standard());
1581 assert!(!frame.is_extended());
1582 assert!(frame.is_data_frame());
1583 assert!(!frame.is_remote_frame());
1584 assert!(!frame.is_error_frame());
1585 assert_eq!(frame.data(), DATA);
1586 assert_eq!(frame.len(), DATA.len());
1587 assert_eq!(frame.data().len(), DATA.len());
1588 assert_eq!(frame.dlc(), DATA.len());
1589
1590 let frame = CanFrame::new(EXT_ID, DATA).unwrap();
1591 assert_eq!(EXT_ID, frame.id());
1592 assert_eq!(id_to_raw(EXT_ID), frame.raw_id());
1593 assert!(!frame.is_standard());
1594 assert!(frame.is_extended());
1595 assert!(frame.is_data_frame());
1596 assert!(!frame.is_remote_frame());
1597 assert!(!frame.is_error_frame());
1598 assert_eq!(frame.data(), DATA);
1599 assert_eq!(frame.len(), DATA.len());
1600 assert_eq!(frame.data().len(), DATA.len());
1601 assert_eq!(frame.dlc(), DATA.len());
1602
1603 let frame = CanFrame::from_raw_id(ExtendedId::MAX.as_raw(), DATA).unwrap();
1604 assert_eq!(EXT_ID, frame.id());
1605 assert_eq!(id_to_raw(EXT_ID), frame.raw_id());
1606 assert!(!frame.is_standard());
1607 assert!(frame.is_extended());
1608 assert!(frame.is_data_frame());
1609 assert!(!frame.is_remote_frame());
1610 assert!(!frame.is_error_frame());
1611 assert_eq!(frame.data(), DATA);
1612 assert_eq!(frame.len(), DATA.len());
1613 assert_eq!(frame.data().len(), DATA.len());
1614 assert_eq!(frame.dlc(), DATA.len());
1615
1616 let frame = CanFrame::new(EXT_LOW_ID, DATA).unwrap();
1618 assert_eq!(EXT_LOW_ID, frame.id());
1619 assert!(!frame.is_standard());
1620 assert!(frame.is_extended());
1621 }
1622
1623 #[test]
1624 fn test_remote_frame() {
1625 let frame = CanRemoteFrame::default();
1626 assert_eq!(CAN_RTR_FLAG, frame.id_word());
1627 assert!(frame.is_remote_frame());
1628 assert_eq!(0, frame.dlc());
1629 assert_eq!(0, frame.len());
1630 assert_eq!(EMPTY_DATA, frame.data());
1631
1632 assert!(frame.id_flags().contains(IdFlags::RTR));
1633 assert_eq!(CAN_RTR_FLAG, frame.id_word() & CAN_RTR_FLAG);
1634
1635 let frame = CanRemoteFrame::new_remote(STD_ID, DATA_LEN).unwrap();
1636 assert_eq!(STD_ID, frame.id());
1637 assert_eq!(id_to_raw(STD_ID), frame.raw_id());
1638 assert!(frame.is_standard());
1639 assert!(!frame.is_extended());
1640 assert!(!frame.is_data_frame());
1641 assert!(frame.is_remote_frame());
1642 assert!(!frame.is_error_frame());
1643 assert_eq!(DATA_LEN, frame.dlc());
1644 assert_eq!(DATA_LEN, frame.len());
1645 assert_eq!(ZERO_DATA, frame.data());
1646
1647 assert!(frame.id_flags().contains(IdFlags::RTR));
1648 assert_eq!(CAN_RTR_FLAG, frame.id_word() & CAN_RTR_FLAG);
1649
1650 let frame = CanFrame::from(frame);
1651 assert_eq!(STD_ID, frame.id());
1652 assert_eq!(id_to_raw(STD_ID), frame.raw_id());
1653 assert!(frame.is_standard());
1654 assert!(!frame.is_extended());
1655 assert!(!frame.is_data_frame());
1656 assert!(frame.is_remote_frame());
1657 assert!(!frame.is_error_frame());
1658 assert_eq!(ZERO_DATA, frame.data());
1659
1660 assert!(matches!(frame, CanFrame::Remote(_)));
1661 assert!(frame.id_flags().contains(IdFlags::RTR));
1662 assert_eq!(CAN_RTR_FLAG, frame.id_word() & CAN_RTR_FLAG);
1663
1664 let frame = CanFrame::new_remote(STD_ID, DATA_LEN).unwrap();
1665 assert_eq!(STD_ID, frame.id());
1666 assert_eq!(id_to_raw(STD_ID), frame.raw_id());
1667 assert!(frame.is_standard());
1668 assert!(!frame.is_extended());
1669 assert!(!frame.is_data_frame());
1670 assert!(frame.is_remote_frame());
1671 assert!(!frame.is_error_frame());
1672 assert_eq!(ZERO_DATA, frame.data());
1673
1674 assert!(matches!(frame, CanFrame::Remote(_)));
1675 assert!(frame.id_flags().contains(IdFlags::RTR));
1676 assert_eq!(CAN_RTR_FLAG, frame.id_word() & CAN_RTR_FLAG);
1677
1678 let frame = CanRemoteFrame::new_remote(STD_ID, CAN_MAX_DLEN + 1);
1679 assert!(frame.is_none());
1680 }
1681
1682 #[test]
1683 fn test_error_frame() {
1684 let mut frame = can_frame_default();
1687 frame.can_id = CAN_ERR_FLAG | 0x0010;
1688
1689 let err = CanError::from(CanErrorFrame(frame));
1690 assert!(matches!(err, CanError::TransceiverError));
1691
1692 let id = StandardId::new(0x0010).unwrap();
1693 let frame = CanErrorFrame::new(id, &[]).unwrap();
1694 assert!(!frame.is_data_frame());
1695 assert!(!frame.is_remote_frame());
1696 assert!(frame.is_error_frame());
1697
1698 let err = CanError::from(frame);
1699 assert!(matches!(err, CanError::TransceiverError));
1700
1701 let id = ExtendedId::new(0x0020).unwrap();
1702 let frame = CanErrorFrame::new(id, &[]).unwrap();
1703 assert!(!frame.is_data_frame());
1704 assert!(!frame.is_remote_frame());
1705 assert!(frame.is_error_frame());
1706
1707 let err = CanError::from(frame);
1708 assert!(matches!(err, CanError::NoAck));
1709
1710 let frame = CanErrorFrame::from(CanError::TransmitTimeout);
1713 assert!(!frame.is_data_frame());
1714 assert!(!frame.is_remote_frame());
1715 assert!(frame.is_error_frame());
1716
1717 let err = frame.into_error();
1718 assert!(matches!(err, CanError::TransmitTimeout));
1719
1720 let err = CanError::ProtocolViolation {
1721 vtype: errors::ViolationType::BitStuffingError,
1722 location: errors::Location::Id0400,
1723 };
1724 let frame = CanErrorFrame::from(err);
1725 assert!(!frame.is_data_frame());
1726 assert!(!frame.is_remote_frame());
1727 assert!(frame.is_error_frame());
1728
1729 match frame.into_error() {
1730 CanError::ProtocolViolation { vtype, location } => {
1731 assert_eq!(vtype, errors::ViolationType::BitStuffingError);
1732 assert_eq!(location, errors::Location::Id0400);
1733 }
1734 _ => assert!(false),
1735 }
1736 }
1737
1738 #[test]
1739 fn test_fd_frame() {
1740 let frame = CanFdFrame::new(STD_ID, DATA).unwrap();
1741 assert_eq!(STD_ID, frame.id());
1742 assert_eq!(id_to_raw(STD_ID), frame.raw_id());
1743 assert!(frame.is_standard());
1744 assert!(!frame.is_extended());
1745 assert!(frame.is_data_frame());
1746 assert!(!frame.is_remote_frame());
1747 assert!(!frame.is_error_frame());
1748 assert_eq!(DATA, frame.data());
1749
1750 let frame = CanFdFrame::new(EXT_ID, DATA).unwrap();
1751 assert_eq!(EXT_ID, frame.id());
1752 assert_eq!(id_to_raw(EXT_ID), frame.raw_id());
1753 assert!(!frame.is_standard());
1754 assert!(frame.is_extended());
1755 assert!(frame.is_data_frame());
1756 assert!(!frame.is_remote_frame());
1757 assert!(!frame.is_error_frame());
1758 assert_eq!(DATA, frame.data());
1759
1760 let frame = CanFdFrame::new(EXT_LOW_ID, DATA).unwrap();
1762 assert_eq!(EXT_LOW_ID, frame.id());
1763 assert!(!frame.is_standard());
1764 assert!(frame.is_extended());
1765 }
1766
1767 #[test]
1768 fn test_fd_ext_data_len() {
1769 assert!(CanFdFrame::is_valid_data_len(8));
1770 assert!(CanFdFrame::is_valid_data_len(12));
1771 assert!(CanFdFrame::is_valid_data_len(24));
1772 assert!(CanFdFrame::is_valid_data_len(64));
1773
1774 assert!(!CanFdFrame::is_valid_data_len(28));
1775 assert!(!CanFdFrame::is_valid_data_len(42));
1776 assert!(!CanFdFrame::is_valid_data_len(65));
1777
1778 assert_eq!(CanFdFrame::next_valid_ext_dlen(9), 12);
1779 assert_eq!(CanFdFrame::next_valid_ext_dlen(13), 16);
1780 assert_eq!(CanFdFrame::next_valid_ext_dlen(17), 20);
1781 assert_eq!(CanFdFrame::next_valid_ext_dlen(21), 24);
1782 assert_eq!(CanFdFrame::next_valid_ext_dlen(25), 32);
1783 assert_eq!(CanFdFrame::next_valid_ext_dlen(33), 48);
1784 assert_eq!(CanFdFrame::next_valid_ext_dlen(49), 64);
1785
1786 assert_eq!(CanFdFrame::next_valid_ext_dlen(99), 64);
1787 }
1788
1789 #[test]
1790 fn test_fd_frame_padding() {
1791 let mut frame = CanFdFrame::new(STD_ID, EXT_DATA_INVALID_DLEN).unwrap();
1793
1794 assert_eq!(frame.data(), EXT_DATA_PADDED);
1795 assert_eq!(frame.len(), EXT_DATA_PADDED.len());
1796 assert_eq!(frame.data().len(), frame.len());
1797 assert_eq!(frame.dlc(), EXT_DATA_PADDED_DLC);
1798
1799 frame = CanFdFrame::new(STD_ID, EXT_DATA).unwrap();
1801
1802 assert_eq!(frame.data(), EXT_DATA);
1803 assert_eq!(frame.len(), EXT_DATA.len());
1804 assert_eq!(frame.data().len(), frame.len());
1805 assert_eq!(frame.dlc(), EXT_DATA_DLC);
1806
1807 frame.set_data(EXT_DATA_INVALID_DLEN).unwrap();
1809
1810 assert_eq!(frame.data(), EXT_DATA_PADDED);
1811 assert_eq!(frame.len(), EXT_DATA_PADDED.len());
1812 assert_eq!(frame.data().len(), frame.len());
1813 assert_eq!(frame.dlc(), EXT_DATA_PADDED_DLC);
1814 }
1815
1816 #[test]
1817 fn test_to_fd_frame() {
1818 let data_frame = CanDataFrame::new(STD_ID, DATA).unwrap();
1819
1820 let frame = CanFdFrame::from(data_frame);
1821
1822 assert_eq!(STD_ID, frame.id());
1823 assert!(frame.is_standard());
1824 assert!(frame.is_data_frame());
1825 assert!(!frame.is_remote_frame());
1826 assert!(!frame.is_error_frame());
1827 assert!(frame.flags().contains(FdFlags::FDF));
1828 assert_eq!(frame.len(), DATA_LEN);
1829 assert_eq!(frame.data().len(), DATA_LEN);
1830 assert_eq!(frame.data(), DATA);
1831
1832 let fdframe = canfd_frame_default();
1833 let frame = CanFdFrame::from(fdframe);
1834 assert!(frame.flags().contains(FdFlags::FDF));
1835 }
1836
1837 #[test]
1838 fn test_fd_to_data_frame() {
1839 let fdframe = CanFdFrame::new(STD_ID, DATA).unwrap();
1840 assert!(fdframe.flags().contains(FdFlags::FDF));
1841
1842 let frame = CanDataFrame::try_from(fdframe).unwrap();
1843
1844 assert_eq!(STD_ID, frame.id());
1845 assert_eq!(frame.len(), DATA_LEN);
1846 assert_eq!(frame.data().len(), DATA_LEN);
1847 assert_eq!(frame.data(), DATA);
1848
1849 let mut fdframe = canfd_frame_default();
1851 crate::as_bytes_mut(&mut fdframe)[..size_of::<can_frame>()]
1852 .clone_from_slice(crate::as_bytes(&frame.0));
1853 assert_eq!(fdframe.flags, 0);
1854 }
1855}