Skip to main content

rs_can/
device.rs

1use crate::{
2    error::Error,
3    frame::{
4        identifier::{Filter, Id},
5        Frame,
6    },
7    CanResult,
8};
9use derive_getters::Getters;
10use serde::{Deserialize, Serialize};
11use std::{
12    any::{type_name, Any},
13    collections::HashMap,
14    fmt::{self, Debug, Display},
15    hash::Hash,
16    sync::Weak,
17};
18
19#[async_trait::async_trait]
20pub trait Listener<C, F>: Send + Sync
21where
22    F: Frame,
23{
24    fn as_any(&self) -> &dyn Any;
25    /// Callback when frame transmit success.
26    async fn on_frame_transmitted(&self, channel: C, id: Id);
27    /// Callback when frames received.
28    async fn on_frame_received(&self, frames: Weak<Vec<F>>);
29}
30
31#[async_trait::async_trait]
32pub trait Device: Send + Sync {
33    type Channel: Hash + Eq + Display + 'static;
34    type Frame: Frame<Channel = Self::Channel>;
35
36    fn new(builder: DeviceBuilder<Self::Channel>) -> CanResult<Self>
37    where
38        Self: Sized;
39
40    #[inline]
41    fn is_closed(&self) -> bool {
42        self.opened_channels().is_empty()
43    }
44    /// get all channels that has opened
45    fn opened_channels(&self) -> Vec<Self::Channel>;
46    /// Transmit a CAN or CAN-FD Frame.
47    async fn transmit(&self, msg: Self::Frame, timeout: Option<u32>) -> CanResult<()>;
48    /// Receive CAN and CAN-FD Frames.
49    async fn receive(
50        &self,
51        channel: Self::Channel,
52        timeout: Option<u32>,
53    ) -> CanResult<Vec<Self::Frame>>;
54    /// Close CAN device.
55    fn shutdown(&mut self);
56}
57
58#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
59pub enum ChannelMode {
60    Normal,
61    ListenOnly,
62    Loopback,
63    OneShot,
64}
65
66#[derive(Default, Deserialize, Serialize)]
67pub struct ChannelConfig {
68    /// Nominal bitrate for both CAN and CAN-FD, and data bitrate for CAN-FD.
69    pub nominal_bitrate: u32,
70    /// Data bitrate for CAN-FD, if not set, it will be the same as nominal bitrate.
71    pub data_bitrate: Option<u32>,
72    /// Whether the channel has termination resistor, if not set, it will be determined by device implementation.
73    pub termination: Option<bool>,
74    /// Channel mode, if not set, it will be normal mode. Loopback and ListenOnly modes are useful for testing.
75    pub mode: Option<ChannelMode>,
76    /// Whether the device can receive its own transmitted messages, if not set, it will be determined by device implementation.
77    pub recv_own_msg: Option<bool>,
78    /// Filters for the channel, if not set, it will receive all frames. If the device does not support filtering, it will be ignored.
79    pub filters: Vec<Filter>,
80    #[serde(skip)]
81    others: HashMap<String, Box<dyn Any + Send + Sync>>,
82}
83
84impl Debug for ChannelConfig {
85    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
86        f.debug_struct("ChannelConfig")
87            .field("nominal_bitrate", &self.nominal_bitrate)
88            .field("data_bitrate", &self.data_bitrate)
89            .field("termination", &self.termination)
90            .field("mode", &self.mode)
91            .field("filters", &self.filters)
92            .finish_non_exhaustive()
93    }
94}
95
96impl ChannelConfig {
97    pub fn new(bitrate: u32) -> Self {
98        Self {
99            nominal_bitrate: bitrate,
100            ..Default::default()
101        }
102    }
103
104    pub fn set_data_bitrate(&mut self, bitrate: u32) -> &mut Self {
105        self.data_bitrate = Some(bitrate);
106        self
107    }
108
109    pub fn set_termination(&mut self, termination: bool) -> &mut Self {
110        self.termination = Some(termination);
111        self
112    }
113
114    pub fn set_channel_mode(&mut self, mode: ChannelMode) -> &mut Self {
115        self.mode = Some(mode);
116        self
117    }
118
119    pub fn set_recv_own_msg(&mut self, recv_own_msg: bool) -> &mut Self {
120        self.recv_own_msg = Some(recv_own_msg);
121        self
122    }
123
124    pub fn add_other(&mut self, name: &str, other: Box<dyn Any + Send + Sync>) -> &mut Self {
125        self.others.insert(name.into(), other);
126        self
127    }
128
129    pub fn get_other<T: Clone + 'static>(&self, name: &str) -> CanResult<Option<T>> {
130        get_other(&self.others, name)
131    }
132}
133
134#[derive(Default, Getters)]
135pub struct DeviceBuilder<K: Hash + Eq> {
136    #[getter(rename = "channel_configs")]
137    configs: HashMap<K, ChannelConfig>,
138    others: HashMap<String, Box<dyn Any + Send + Sync>>,
139}
140
141impl<K: Hash + Eq + Debug> Debug for DeviceBuilder<K> {
142    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
143        f.debug_struct("DeviceBuilder")
144            .field("configs", &self.configs)
145            .finish_non_exhaustive()
146    }
147}
148
149impl<K: Hash + Eq + Default> DeviceBuilder<K> {
150    pub fn new() -> Self {
151        Self::default()
152    }
153
154    pub fn add_config(&mut self, channel: K, cfg: ChannelConfig) -> &mut Self {
155        self.configs.insert(channel.into(), cfg);
156        self
157    }
158
159    pub fn add_other(&mut self, name: &str, cfg: Box<dyn Any + Send + Sync>) -> &mut Self {
160        self.others.insert(name.into(), cfg);
161        self
162    }
163
164    pub fn get_other<T: Clone + 'static>(&self, name: &str) -> CanResult<Option<T>> {
165        get_other(&self.others, name)
166    }
167
168    pub fn build<T: Device<Channel = K>>(self) -> CanResult<T> {
169        T::new(self)
170    }
171}
172
173#[inline(always)]
174fn get_other<T: Clone + 'static>(
175    others: &HashMap<String, Box<dyn Any + Send + Sync>>,
176    name: &str,
177) -> CanResult<Option<T>> {
178    match others.get(name) {
179        Some(v) => Ok(Some(
180            v.downcast_ref::<T>()
181                .ok_or(Error::OtherError(format!(
182                    "type mismatched for `{}` expected: `{}`",
183                    name,
184                    type_name::<T>()
185                )))?
186                .clone(),
187        )),
188        None => Ok(None),
189    }
190}
191
192#[cfg(test)]
193mod tests {
194    use super::*;
195
196    #[test]
197    fn get_other_returns_inserted_value() {
198        let mut builder = DeviceBuilder::<u8>::new();
199        builder.add_other("answer", Box::new(42_u32));
200
201        let value = builder.get_other::<u32>("answer").unwrap();
202        assert_eq!(value, Some(42));
203    }
204
205    #[test]
206    fn get_other_reports_type_mismatch() {
207        let mut builder = DeviceBuilder::<u8>::new();
208        builder.add_other("answer", Box::new(42_u32));
209
210        let err = builder.get_other::<String>("answer").unwrap_err();
211        assert!(matches!(err, Error::OtherError(_)));
212    }
213}