Thanks to visit codestin.com
Credit goes to docs.rs

socketcan/
frame.rs

1// socketcan/src/frame.rs
2//
3// Implements frames for CANbus 2.0 and FD for SocketCAN on Linux.
4//
5// This file is part of the Rust 'socketcan-rs' library.
6//
7// Licensed under the MIT license:
8//   <LICENSE or http://opensource.org/licenses/MIT>
9// This file may not be copied, modified, or distributed except according
10// to those terms.
11
12//! CAN bus frames.
13//!
14//! At the lowest level, [libc](https://crates.io/crates/libc) defines the
15//! CAN frames as low-level structs that are binary compatible with the C
16//! data types sent to and from the kernel:
17//! - [can_frame](https://docs.rs/libc/latest/libc/struct.can_frame.html)
18//!   The Classic CAN 2.0 frame with up to 8 bytes of data.
19//! - [canfd_frame](https://docs.rs/libc/latest/libc/struct.canfd_frame.html)
20//!   The CAN Flexible Data Rate frame with up to 64 bytes of data.
21//!
22//! The classic frame represents three possibilities:
23//! - `CanDataFrame` - A standard CAN frame that can contain up to 8 bytes
24//!   of data.
25//! - `CanRemoteFrame` - A CAN Remote frame which is meant to request a
26//!   transmission by another node on the bus. It contain no data.
27//! - `CanErrorFrame` - This is an incoming (only) frame that contains
28//!   information about a problem on the bus or in the driver. Error frames
29//!   can not be sent to the bus, but can be converted to standard Rust
30//!   [Error](https://doc.rust-lang.org/std/error/trait.Error.html) types.
31//!
32
33use 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
43// TODO: Remove these on the next major ver update.
44pub 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// ===== can_frame =====
51
52/// Creates a default C `can_frame`.
53/// This initializes the entire structure to zeros.
54#[inline(always)]
55pub fn can_frame_default() -> can_frame {
56    unsafe { mem::zeroed() }
57}
58
59/// Creates a default C `can_frame`.
60/// This initializes the entire structure to zeros.
61#[inline(always)]
62pub fn canfd_frame_default() -> canfd_frame {
63    unsafe { mem::zeroed() }
64}
65
66// ===== AsPtr trait =====
67
68/// Trait to get a pointer to an inner type
69pub trait AsPtr {
70    /// The inner type to which we resolve as a pointer
71    type Inner;
72
73    /// Gets a const pointer to the inner type
74    fn as_ptr(&self) -> *const Self::Inner;
75
76    /// Gets a mutable pointer to the inner type
77    fn as_mut_ptr(&mut self) -> *mut Self::Inner;
78
79    /// The size of the inner type
80    fn size(&self) -> usize {
81        size_of::<Self::Inner>()
82    }
83
84    /// Gets a byte slice to the inner type
85    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    /// Gets a mutable byte slice to the inner type
95    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// ===== Frame trait =====
106
107/// Shared trait for CAN frames
108#[allow(clippy::len_without_is_empty)]
109pub trait Frame: EmbeddedFrame {
110    /// Creates a frame using a raw, integer CAN ID.
111    ///
112    /// If the `id` is <= 0x7FF, it's assumed to be a standard ID, otherwise
113    /// it is created as an Extended ID. If you require an Extended ID <= 0x7FF,
114    /// use `new()`.
115    fn from_raw_id(id: u32, data: &[u8]) -> Option<Self> {
116        Self::new(id_from_raw(id)?, data)
117    }
118
119    /// Creates a remote frame using a raw, integer CAN ID.
120    ///
121    /// If the `id` is <= 0x7FF, it's assumed to be a standard ID, otherwise
122    /// it is created as an Extended ID. If you require an Extended ID <= 0x7FF,
123    /// use `new_remote()`.
124    fn remote_from_raw_id(id: u32, dlc: usize) -> Option<Self> {
125        Self::new_remote(id_from_raw(id)?, dlc)
126    }
127
128    /// Get the composite SocketCAN ID word, with EFF/RTR/ERR flags
129    fn id_word(&self) -> canid_t;
130
131    /// Return the actual raw CAN ID (without EFF/RTR/ERR flags)
132    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    /// Returns the EFF/RTR/ERR flags from the ID word
142    fn id_flags(&self) -> IdFlags {
143        IdFlags::from_bits_truncate(self.id_word())
144    }
145
146    /// Return the CAN ID.
147    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    /// Return the CAN ID as the embedded HAL Id type.
160    fn hal_id(&self) -> Id {
161        self.can_id().as_id()
162    }
163
164    /// Get the data length
165    fn len(&self) -> usize {
166        // For standard frames, dlc == len
167        self.dlc()
168    }
169
170    /// Check if frame is an error message
171    fn is_error_frame(&self) -> bool {
172        self.id_flags().contains(IdFlags::ERR)
173    }
174
175    /// Sets the CAN ID for the frame
176    fn set_id(&mut self, id: impl Into<Id>);
177
178    /// Sets the data payload of the frame.
179    fn set_data(&mut self, data: &[u8]) -> Result<(), ConstructionError>;
180}
181
182// ===== CanAnyFrame =====
183
184/// An FD socket can read a raw classic 2.0 or FD frame.
185#[allow(missing_debug_implementations)]
186#[derive(Clone, Copy)]
187pub enum CanRawFrame {
188    /// A classic CAN 2.0 frame, with up to 8-bytes of data
189    Classic(can_frame),
190    /// A flexible data rate frame, with up to 64-bytes of data
191    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/// Any frame type.
207#[derive(Clone, Copy, Debug)]
208pub enum CanAnyFrame {
209    /// A classic CAN 2.0 frame, with up to 8-bytes of data
210    Normal(CanDataFrame),
211    /// A CAN Remote Frame
212    Remote(CanRemoteFrame),
213    /// An error frame
214    Error(CanErrorFrame),
215    /// A flexible data rate frame, with up to 64-bytes of data
216    Fd(CanFdFrame),
217}
218
219impl Frame for CanAnyFrame {
220    /// Get the composite SocketCAN ID word, with EFF/RTR/ERR flags
221    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    /// Sets the CAN ID for the frame
232    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    /// Sets the data payload of the frame.
243    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    /// Create a new CAN frame
256    /// If the data
257    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    /// Create a new remote transmission request frame.
266    fn new_remote(id: impl Into<Id>, dlc: usize) -> Option<Self> {
267        CanRemoteFrame::new_remote(id, dlc).map(CanAnyFrame::Remote)
268    }
269
270    /// Check if frame uses 29-bit extended ID format.
271    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    /// Check if frame is a remote transmission request.
282    fn is_remote_frame(&self) -> bool {
283        matches!(self, CanAnyFrame::Remote(_))
284    }
285
286    /// Return the frame identifier.
287    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    /// Data length
298    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    /// A slice into the actual data. Slice will always be <= 8 bytes in length
309    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// ===== CanFrame =====
470
471/// The classic CAN 2.0 frame with up to 8-bytes of data.
472#[derive(Clone, Copy, Debug)]
473pub enum CanFrame {
474    /// A data frame
475    Data(CanDataFrame),
476    /// A remote frame
477    Remote(CanRemoteFrame),
478    /// An error frame
479    Error(CanErrorFrame),
480}
481
482impl AsPtr for CanFrame {
483    type Inner = can_frame;
484
485    /// Gets a pointer to the CAN frame structure that is compatible with
486    /// the Linux C API.
487    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    /// Gets a mutable pointer to the CAN frame structure that is compatible
497    /// with the Linux C API.
498    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    /// Create a new CAN 2.0 data frame
510    fn new(id: impl Into<Id>, data: &[u8]) -> Option<Self> {
511        CanDataFrame::new(id, data).map(CanFrame::Data)
512    }
513
514    /// Create a new remote transmission request frame.
515    fn new_remote(id: impl Into<Id>, dlc: usize) -> Option<Self> {
516        CanRemoteFrame::new_remote(id, dlc).map(CanFrame::Remote)
517    }
518
519    /// Check if frame uses 29-bit extended ID format.
520    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    /// Check if frame is a remote transmission request.
530    fn is_remote_frame(&self) -> bool {
531        matches!(self, CanFrame::Remote(_))
532    }
533
534    /// Return the frame identifier.
535    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    /// Data length
545    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    /// A slice into the actual data. Slice will always be <= 8 bytes in length
555    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    /// Get the composite SocketCAN ID word, with EFF/RTR/ERR flags
567    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    /// Sets the CAN ID for the frame
577    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    /// Sets the data payload of the frame.
587    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    /// The default frame is a default data frame - all fields and data set
599    /// to zero, and all flags off.
600    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    /// Create a `CanFrame` from a C `can_frame` struct.
618    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    /// Create a `CanFrame` from a data frame
631    fn from(frame: CanDataFrame) -> Self {
632        Self::Data(frame)
633    }
634}
635
636impl From<CanRemoteFrame> for CanFrame {
637    /// Create a `CanFrame` from a remote frame
638    fn from(frame: CanRemoteFrame) -> Self {
639        Self::Remote(frame)
640    }
641}
642
643impl From<CanErrorFrame> for CanFrame {
644    /// Create a `CanFrame` from an error frame
645    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    /// Try to convert a CAN FD frame into a classic CAN 2.0 frame.
698    ///
699    /// This should work if it's a data frame with 8 or fewer data bytes.
700    fn try_from(frame: CanFdFrame) -> Result<Self, <Self as TryFrom<CanFdFrame>>::Error> {
701        CanDataFrame::try_from(frame).map(CanFrame::Data)
702    }
703}
704
705// ===== CanDataFrame =====
706
707/// The classic CAN 2.0 frame with up to 8-bytes of data.
708///
709/// This is highly compatible with the `can_frame` from libc.
710/// ([ref](https://docs.rs/libc/latest/libc/struct.can_frame.html))
711#[derive(Clone, Copy)]
712pub struct CanDataFrame(can_frame);
713
714impl CanDataFrame {
715    /// Initializes a CAN data frame from raw parts.
716    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    /// Gets a pointer to the CAN frame structure that is compatible with
734    /// the Linux C API.
735    fn as_ptr(&self) -> *const Self::Inner {
736        &self.0
737    }
738
739    /// Gets a mutable pointer to the CAN frame structure that is compatible
740    /// with the Linux C API.
741    fn as_mut_ptr(&mut self) -> *mut Self::Inner {
742        &mut self.0
743    }
744}
745
746impl EmbeddedFrame for CanDataFrame {
747    /// Create a new CAN 2.0 data frame
748    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    /// Create a new remote transmission request frame.
754    fn new_remote(_id: impl Into<Id>, _dlc: usize) -> Option<Self> {
755        None
756    }
757
758    /// Check if frame uses 29-bit extended ID format.
759    fn is_extended(&self) -> bool {
760        self.id_flags().contains(IdFlags::EFF)
761    }
762
763    /// Check if frame is a remote transmission request.
764    fn is_remote_frame(&self) -> bool {
765        false
766    }
767
768    /// Return the frame identifier.
769    fn id(&self) -> Id {
770        self.hal_id()
771    }
772
773    /// Data length
774    fn dlc(&self) -> usize {
775        self.0.can_dlc as usize
776    }
777
778    /// A slice into the actual data. Slice will always be <= 8 bytes in length
779    fn data(&self) -> &[u8] {
780        &self.0.data[..(self.0.can_dlc as usize)]
781    }
782}
783
784impl Frame for CanDataFrame {
785    /// Get the composite SocketCAN ID word, with EFF/RTR/ERR flags
786    fn id_word(&self) -> canid_t {
787        self.0.can_id
788    }
789
790    /// Sets the CAN ID for the frame
791    fn set_id(&mut self, id: impl Into<Id>) {
792        self.0.can_id = id_to_canid_t(id);
793    }
794
795    /// Sets the data payload of the frame.
796    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    /// The default FD frame has all fields and data set to zero, and all flags off.
810    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    /// Try to create a `CanDataFrame` from a C `can_frame`
835    ///
836    /// This will succeed as long as the C frame is not marked as an error
837    /// or remote frame.
838    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// ===== CanRemoteFrame =====
865
866/// The classic CAN 2.0 remote request frame.
867///
868/// This is is meant to request a transmission by another node on the bus.
869/// It contain no data.
870///
871/// This is highly compatible with the `can_frame` from libc.
872/// ([ref](https://docs.rs/libc/latest/libc/struct.can_frame.html))
873#[derive(Clone, Copy)]
874pub struct CanRemoteFrame(can_frame);
875
876impl CanRemoteFrame {
877    /// Initializes a CAN data frame from raw parts.
878    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    /// Sets the data length code for the frame
891    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    /// Gets a pointer to the CAN frame structure that is compatible with
905    /// the Linux C API.
906    fn as_ptr(&self) -> *const Self::Inner {
907        &self.0
908    }
909
910    /// Gets a mutable pointer to the CAN frame structure that is compatible
911    /// with the Linux C API.
912    fn as_mut_ptr(&mut self) -> *mut Self::Inner {
913        &mut self.0
914    }
915}
916
917impl EmbeddedFrame for CanRemoteFrame {
918    /// Create a new CAN 2.0 remote frame
919    fn new(id: impl Into<Id>, data: &[u8]) -> Option<Self> {
920        Self::new_remote(id, data.len())
921    }
922
923    /// Create a new remote transmission request frame.
924    ///
925    /// This will set the RTR flag in the CAN ID word.
926    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    /// Check if frame uses 29-bit extended ID format.
932    fn is_extended(&self) -> bool {
933        self.id_flags().contains(IdFlags::EFF)
934    }
935
936    /// Check if frame is a remote transmission request.
937    fn is_remote_frame(&self) -> bool {
938        true
939    }
940
941    /// Return the frame identifier.
942    fn id(&self) -> Id {
943        self.hal_id()
944    }
945
946    /// Data length code
947    fn dlc(&self) -> usize {
948        self.0.can_dlc as usize
949    }
950
951    /// A slice into the actual data. Slice will always be <= 8 bytes in length
952    fn data(&self) -> &[u8] {
953        // TODO: Is this OK, or just an empty slice?
954        &self.0.data[..self.dlc()]
955    }
956}
957
958impl Frame for CanRemoteFrame {
959    /// Get the composite SocketCAN ID word, with EFF/RTR/ERR flags
960    fn id_word(&self) -> canid_t {
961        self.0.can_id
962    }
963
964    /// Sets the CAN ID for the frame.
965    ///
966    /// This will set the RTR flag in the CAN ID word.
967    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    /// Sets the data payload of the frame.
972    /// For the Remote frame, this just updates the DLC to the length of the
973    /// data slice.
974    fn set_data(&mut self, data: &[u8]) -> Result<(), ConstructionError> {
975        self.set_dlc(data.len())
976    }
977}
978
979impl Default for CanRemoteFrame {
980    /// The default remote frame has all fields and data set to zero, and all flags off.
981    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    /// Try to create a `CanRemoteFrame` from a C `can_frame`
1008    ///
1009    /// This will only succeed the C frame is marked as a remote frame.
1010    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// ===== CanErrorFrame =====
1026
1027/// A SocketCAN error frame.
1028///
1029/// This is returned from a read/receive by the OS or interface device
1030/// driver when it detects an error, such as a problem on the bus. The
1031/// frame encodes detailed information about the error, which can be
1032/// managed directly by the application or converted into a Rust error
1033///
1034/// This is highly compatible with the `can_frame` from libc.
1035/// ([ref](https://docs.rs/libc/latest/libc/struct.can_frame.html))
1036#[derive(Clone, Copy)]
1037pub struct CanErrorFrame(can_frame);
1038
1039impl CanErrorFrame {
1040    /// Creates a CAN error frame from raw parts.
1041    ///
1042    /// Note that an application would not normally _ever_ create an error
1043    /// frame. This is included mainly to aid in implementing mocks and other
1044    /// tests for an application.
1045    ///
1046    /// The data byte slice should have the necessary codes for the supplied
1047    /// error. They will be zero padded to a full frame of 8 bytes.
1048    ///
1049    /// Also note:
1050    /// - The error flag is forced on
1051    /// - The other, non-error, flags are forced off
1052    /// - The frame data is always padded with zero's to 8 bytes,
1053    ///   regardless of the length of the `data` parameter provided.
1054    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    /// Return the error bits from the ID word of the error frame.
1068    pub fn error_bits(&self) -> u32 {
1069        self.id_word() & CAN_ERR_MASK
1070    }
1071
1072    /// Converts this error frame into a `CanError`
1073    pub fn into_error(self) -> CanError {
1074        CanError::from(self)
1075    }
1076}
1077
1078impl AsPtr for CanErrorFrame {
1079    type Inner = can_frame;
1080
1081    /// Gets a pointer to the CAN frame structure that is compatible with
1082    /// the Linux C API.
1083    fn as_ptr(&self) -> *const Self::Inner {
1084        &self.0
1085    }
1086
1087    /// Gets a mutable pointer to the CAN frame structure that is compatible
1088    /// with the Linux C API.
1089    fn as_mut_ptr(&mut self) -> *mut Self::Inner {
1090        &mut self.0
1091    }
1092}
1093
1094impl EmbeddedFrame for CanErrorFrame {
1095    /// Create an error frame.
1096    ///
1097    /// Note that an application would not normally _ever_ create an error
1098    /// frame. This is included mainly to aid in implementing mocks and other
1099    /// tests for an application.
1100    ///
1101    /// This will set the error bit in the CAN ID word.
1102    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    /// The application should not create an error frame.
1108    /// This will always return None.
1109    fn new_remote(_id: impl Into<Id>, _dlc: usize) -> Option<Self> {
1110        None
1111    }
1112
1113    /// Check if frame uses 29-bit extended ID format.
1114    fn is_extended(&self) -> bool {
1115        self.id_flags().contains(IdFlags::EFF)
1116    }
1117
1118    /// Check if frame is a remote transmission request.
1119    fn is_remote_frame(&self) -> bool {
1120        false
1121    }
1122
1123    /// Check if frame is a data frame.
1124    fn is_data_frame(&self) -> bool {
1125        false
1126    }
1127
1128    /// Return the frame identifier.
1129    fn id(&self) -> Id {
1130        self.hal_id()
1131    }
1132
1133    /// Data length code
1134    fn dlc(&self) -> usize {
1135        self.0.can_dlc as usize
1136    }
1137
1138    /// A slice into the actual data.
1139    /// An error frame can always access the full 8-byte data payload.
1140    fn data(&self) -> &[u8] {
1141        &self.0.data[..]
1142    }
1143}
1144
1145impl Frame for CanErrorFrame {
1146    /// Get the composite SocketCAN ID word, with EFF/RTR/ERR flags
1147    fn id_word(&self) -> canid_t {
1148        self.0.can_id
1149    }
1150
1151    /// Sets the CAN ID for the frame
1152    /// This does nothing on an error frame.
1153    fn set_id(&mut self, _id: impl Into<Id>) {}
1154
1155    /// Sets the data payload of the frame.
1156    /// This is an error on an error frame.
1157    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    /// Try to create a `CanErrorFrame` from a C `can_frame`
1182    ///
1183    /// This will only succeed the C frame is marked as an error frame.
1184    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
1231// ===== CanFdFrame =====
1232
1233// Valid extended data lengths
1234const VALID_EXT_DLENGTHS: [usize; 7] = [12, 16, 20, 24, 32, 48, 64];
1235
1236/// The CAN flexible data rate frame with up to 64-bytes of data.
1237///
1238/// This is highly compatible with the `canfd_frame` from libc.
1239/// ([ref](https://docs.rs/libc/latest/libc/struct.canfd_frame.html))
1240///
1241/// Payload data that is greater than 8 bytes and whose data length does
1242/// not match a valid CANFD data length is padded with 0 bytes to the
1243/// next higher valid CANFD data length.
1244///
1245/// Note:
1246///   - The FDF flag is forced on when created.
1247#[derive(Clone, Copy)]
1248pub struct CanFdFrame(canfd_frame);
1249
1250impl CanFdFrame {
1251    /// Create a new FD frame with FD flags
1252    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    /// Initialize an FD frame from the raw components.
1258    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    /// Gets the flags for the FD frame.
1277    ///
1278    /// These are the bits from the separate FD frame flags, not the flags
1279    /// in the composite ID word.
1280    pub fn flags(&self) -> FdFlags {
1281        FdFlags::from_bits_truncate(self.0.flags)
1282    }
1283
1284    /// Whether the frame uses a bit rate switch (second bit rate for
1285    /// payload data).
1286    pub fn is_brs(&self) -> bool {
1287        self.flags().contains(FdFlags::BRS)
1288    }
1289
1290    /// Sets whether the frame uses a bit rate switch.
1291    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    /// Gets the error state indicator of the transmitting node
1300    pub fn is_esi(&self) -> bool {
1301        self.flags().contains(FdFlags::ESI)
1302    }
1303
1304    /// Sets the error state indicator of the transmitting node
1305    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    /// Checks whether a given length is a valid CANFD data length.
1314    ///
1315    /// Valid values are `0` - `8`, `12`, `16`, `20`, `24`, `32`, `48` or `64`.
1316    pub fn is_valid_data_len(len: usize) -> bool {
1317        len <= CAN_MAX_DLEN || VALID_EXT_DLENGTHS.contains(&len)
1318    }
1319
1320    /// Returns the next larger valid CANFD extended data length into which
1321    /// the given length fits, up to a maximum of CANFD_MAX_DLEN.
1322    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        // return CANFD_MAX_DLEN if len > CANFD_MAX_DLEN
1332        CANFD_MAX_DLEN
1333    }
1334}
1335
1336impl AsPtr for CanFdFrame {
1337    type Inner = canfd_frame;
1338
1339    /// Gets a pointer to the CAN frame structure that is compatible with
1340    /// the Linux C API.
1341    fn as_ptr(&self) -> *const Self::Inner {
1342        &self.0
1343    }
1344
1345    /// Gets a mutable pointer to the CAN frame structure that is compatible
1346    /// with the Linux C API.
1347    fn as_mut_ptr(&mut self) -> *mut Self::Inner {
1348        &mut self.0
1349    }
1350}
1351
1352impl EmbeddedFrame for CanFdFrame {
1353    /// Create a new FD frame
1354    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    /// CAN FD frames don't support remote
1360    fn new_remote(_id: impl Into<Id>, _dlc: usize) -> Option<Self> {
1361        None
1362    }
1363
1364    /// Check if frame uses 29-bit extended ID format.
1365    fn is_extended(&self) -> bool {
1366        self.id_flags().contains(IdFlags::EFF)
1367    }
1368
1369    /// The FD frames don't support remote request
1370    fn is_remote_frame(&self) -> bool {
1371        false
1372    }
1373
1374    /// Return the frame identifier.
1375    fn id(&self) -> Id {
1376        self.hal_id()
1377    }
1378
1379    /// Data length code
1380    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            // invalid data length, should never occur as the data is
1391            // padded to a valid CANFD data length on frame creation
1392            _ => 0x00,
1393        }
1394    }
1395
1396    /// A slice into the actual data.
1397    ///
1398    /// This should only be one of the valid CAN FD data lengths.
1399    fn data(&self) -> &[u8] {
1400        &self.0.data[..(self.0.len as usize)]
1401    }
1402}
1403
1404impl Frame for CanFdFrame {
1405    /// Get the composite SocketCAN ID word, with EFF/RTR/ERR flags
1406    fn id_word(&self) -> canid_t {
1407        self.0.can_id
1408    }
1409
1410    /// Get the data length
1411    fn len(&self) -> usize {
1412        // For FD frames, len not always equal to dlc
1413        self.0.len as usize
1414    }
1415
1416    /// Sets the CAN ID for the frame
1417    fn set_id(&mut self, id: impl Into<Id>) {
1418        self.0.can_id = id_to_canid_t(id);
1419    }
1420
1421    /// Sets the data payload of the frame.
1422    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    /// The default FD frame has all fields and data set to zero, and all flags off.
1437    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/////////////////////////////////////////////////////////////////////////////
1488
1489#[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        // Should keep Extended flag even if ID <= 0x7FF (standard range)
1617        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        // Create an error frame indicating transceiver error
1685        // from a C frame.
1686        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        // From CanErrors
1711
1712        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        // Should keep Extended flag even if ID <= 0x7FF (standard range)
1761        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        // Creating a frame w/ invalid length should "pad up"
1792        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        // Creating a frame w/ valid length
1800        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        // Setting frame data to smaller length should pad w/ zeros
1808        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        // Make sure FD flags turned off
1850        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}