Skip to main content

rs_can/frame/
mod.rs

1pub(crate) mod identifier;
2
3use self::identifier::{CanFdFlags, Id};
4use crate::utils;
5use crate::CanResult;
6use std::fmt::{Display, Formatter, Write};
7
8#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
9pub enum TimestampSource {
10    System,
11    Hardware,
12    #[default]
13    Unknown,
14}
15
16#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
17pub struct Timestamp {
18    pub nanos: u128,
19    pub source: TimestampSource,
20}
21
22#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
23pub enum FrameFormat {
24    #[default]
25    Data,
26    Remote,
27    Error,
28}
29
30#[repr(C)]
31#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
32pub enum Kind {
33    #[default]
34    Classical,
35    FD,
36    XL,
37}
38
39#[repr(C)]
40#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
41pub enum Direction {
42    #[default]
43    Transmit,
44    Receive,
45}
46
47impl Display for Direction {
48    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
49        match self {
50            Self::Transmit => f.write_str("Tx"),
51            Self::Receive => f.write_str("Rx"),
52        }
53    }
54}
55
56/// CAN 2.0 | CAN 1.0
57pub trait Frame: Send + Sync {
58    type Channel: Display;
59
60    fn new_can(id: Id, data: &[u8]) -> CanResult<Self>
61    where
62        Self: Sized;
63
64    fn new_remote(id: Id, dlc: u8) -> CanResult<Self>
65    where
66        Self: Sized;
67
68    fn new_can_fd(id: Id, data: &[u8], flags: CanFdFlags) -> CanResult<Self>
69    where
70        Self: Sized;
71
72    fn id(&self) -> Id;
73    fn channel(&self) -> Self::Channel;
74    fn set_channel(&mut self, v: Self::Channel) -> &mut Self
75    where
76        Self: Sized;
77
78    fn kind(&self) -> Kind;
79    fn format(&self) -> FrameFormat;
80
81    fn data(&self) -> &[u8];
82    fn len(&self) -> usize;
83    fn dlc(&self) -> CanResult<u8> {
84        utils::can_dlc(self.len(), self.kind())
85    }
86
87    fn direction(&self) -> Direction;
88    fn set_direction(&mut self, d: Direction) -> &mut Self
89    where
90        Self: Sized;
91
92    fn timestamp(&self) -> Option<Timestamp>;
93    fn set_timestamp(&mut self, ts: Option<Timestamp>) -> &mut Self
94    where
95        Self: Sized;
96
97    fn is_bitrate_switch(&self) -> bool;
98    fn set_bitrate_switch(&mut self, v: bool) -> &mut Self
99    where
100        Self: Sized;
101
102    fn is_remote(&self) -> bool {
103        matches!(self.format(), FrameFormat::Remote)
104    }
105
106    fn is_error_frame(&self) -> bool {
107        matches!(self.format(), FrameFormat::Error)
108    }
109
110    fn is_extended(&self) -> bool {
111        matches!(self.id(), Id::Extended(_))
112    }
113
114    fn is_esi(&self) -> bool;
115    fn set_esi(&mut self, v: bool) -> &mut Self
116    where
117        Self: Sized;
118}
119
120impl<T: Display> Display for dyn Frame<Channel = T> {
121    /// Output Frame as `asc` String.
122    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
123        let data_str = if self.is_remote() {
124            " ".to_owned()
125        } else {
126            self.data().iter().fold(String::new(), |mut out, &b| {
127                let _ = write!(out, "{b:02x} ");
128                out
129            })
130        };
131
132        match self.kind() {
133            Kind::Classical => {
134                let timestamp_secs = self
135                    .timestamp()
136                    .map(|ts| ts.nanos as f64 / 1_000_000_000.)
137                    .unwrap_or_default();
138                write!(
139                    f,
140                    "{:.3} {} {}{: <4} {} {} {} {}",
141                    timestamp_secs,
142                    self.channel(),
143                    format!("{: >8x}", self.id().as_raw()),
144                    if self.is_extended() { "x" } else { "" },
145                    self.direction(),
146                    // if self.is_rx() { "Rx" } else { "Tx" },
147                    if self.is_remote() { "r" } else { "d" },
148                    format!("{: >2}", self.len()),
149                    data_str,
150                )
151            }
152            Kind::FD => {
153                let timestamp_secs = self
154                    .timestamp()
155                    .map(|ts| ts.nanos as f64 / 1_000_000_000.)
156                    .unwrap_or_default();
157                let dlc = self.dlc().map_err(|_| std::fmt::Error)?;
158                let mut flags = 1 << 12;
159                write!(
160                    f,
161                    "{:.3} CANFD {} {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}",
162                    timestamp_secs,
163                    self.channel(),
164                    self.direction(),
165                    // if self.is_rx() { "Rx" } else { "Tx" },
166                    format!("{: >8x}", self.id().as_raw()),
167                    if self.is_bitrate_switch() {
168                        flags |= 1 << 13;
169                        1
170                    } else {
171                        0
172                    },
173                    if self.is_esi() {
174                        flags |= 1 << 14;
175                        1
176                    } else {
177                        0
178                    },
179                    format!("{: >2}", dlc),
180                    format!("{: >2}", self.len()),
181                    data_str,
182                    format!("{: >8}", 0), // message_duration
183                    format!("{: <4}", 0), // message_length
184                    format!("{: >8x}", flags),
185                    format!("{: >8}", 0), // crc
186                    format!("{: >8}", 0), // bit_timing_conf_arb
187                    format!("{: >8}", 0), // bit_timing_conf_data
188                    format!("{: >8}", 0), // bit_timing_conf_ext_arb
189                    format!("{: >8}", 0), // bit_timing_conf_ext_data
190                )
191            }
192            Kind::XL => {
193                // TODO
194                write!(f, "CANXL Frame")
195            }
196        }
197    }
198}