can_hal_socketcan/
channel.rs1use std::io;
2use std::time::{Duration, Instant};
3
4use socketcan::frame::CanAnyFrame;
5use socketcan::{CanFdSocket, Socket, SocketOptions};
6
7use can_hal::channel::{Receive, ReceiveFd, Transmit, TransmitFd};
8use can_hal::filter::{Filter, Filterable};
9use can_hal::frame::{CanFdFrame, CanFrame, Frame, Timestamped};
10
11use crate::convert;
12use crate::error::SocketCanError;
13
14pub struct SocketCanChannel {
21 socket: CanFdSocket,
22 nonblocking: bool,
23}
24
25impl SocketCanChannel {
26 pub fn open(ifname: &str) -> Result<Self, SocketCanError> {
28 let socket = CanFdSocket::open(ifname)?;
29 Ok(Self {
30 socket,
31 nonblocking: false,
32 })
33 }
34
35 pub fn open_iface(ifindex: u32) -> Result<Self, SocketCanError> {
37 let socket = CanFdSocket::open_iface(ifindex)?;
38 Ok(Self {
39 socket,
40 nonblocking: false,
41 })
42 }
43
44 fn ensure_blocking(&mut self) -> Result<(), SocketCanError> {
45 if self.nonblocking {
46 self.socket.set_nonblocking(false)?;
47 self.nonblocking = false;
48 }
49 Ok(())
50 }
51
52 fn ensure_nonblocking(&mut self) -> Result<(), SocketCanError> {
53 if !self.nonblocking {
54 self.socket.set_nonblocking(true)?;
55 self.nonblocking = true;
56 }
57 Ok(())
58 }
59}
60
61impl Transmit for SocketCanChannel {
62 type Error = SocketCanError;
63
64 fn transmit(&mut self, frame: &CanFrame) -> Result<(), Self::Error> {
65 let sc_frame = convert::to_socketcan_data_frame(frame)?;
66 self.socket.write_frame(&sc_frame)?;
67 Ok(())
68 }
69}
70
71impl Receive for SocketCanChannel {
72 type Error = SocketCanError;
73 type Timestamp = Instant;
74
75 fn receive(&mut self) -> Result<Timestamped<CanFrame, Instant>, Self::Error> {
76 self.ensure_blocking()?;
77 loop {
78 let any_frame = self.socket.read_frame()?;
79 let now = Instant::now();
80 if let CanAnyFrame::Normal(data_frame) = any_frame {
81 let frame = convert::from_socketcan_data_frame(&data_frame)?;
82 return Ok(Timestamped::new(frame, now));
83 }
84 }
86 }
87
88 fn try_receive(&mut self) -> Result<Option<Timestamped<CanFrame, Instant>>, Self::Error> {
89 self.ensure_nonblocking()?;
90 loop {
91 match self.socket.read_frame() {
92 Ok(CanAnyFrame::Normal(data_frame)) => {
93 let now = Instant::now();
94 let frame = convert::from_socketcan_data_frame(&data_frame)?;
95 return Ok(Some(Timestamped::new(frame, now)));
96 }
97 Ok(_) => {} Err(e) if e.kind() == io::ErrorKind::WouldBlock => return Ok(None),
99 Err(e) => return Err(SocketCanError::Io(e)),
100 }
101 }
102 }
103
104 fn receive_timeout(
105 &mut self,
106 timeout: Duration,
107 ) -> Result<Option<Timestamped<CanFrame, Instant>>, Self::Error> {
108 self.ensure_blocking()?;
109 self.socket.set_read_timeout(timeout)?;
110 let deadline = Instant::now() + timeout;
111 let result = loop {
112 match self.socket.read_frame() {
113 Ok(CanAnyFrame::Normal(data_frame)) => {
114 let now = Instant::now();
115 break convert::from_socketcan_data_frame(&data_frame)
116 .map(|f| Some(Timestamped::new(f, now)));
117 }
118 Ok(_) => {
119 let now = Instant::now();
121 if now >= deadline {
122 break Ok(None);
123 }
124 self.socket.set_read_timeout(deadline - now).ok();
125 }
126 Err(e)
127 if e.kind() == io::ErrorKind::WouldBlock
128 || e.kind() == io::ErrorKind::TimedOut =>
129 {
130 break Ok(None);
131 }
132 Err(e) => break Err(SocketCanError::Io(e)),
133 }
134 };
135 self.socket.set_read_timeout(None).ok();
137 result
138 }
139}
140
141impl TransmitFd for SocketCanChannel {
142 type Error = SocketCanError;
143
144 fn transmit_fd(&mut self, frame: &CanFdFrame) -> Result<(), Self::Error> {
145 let sc_frame = convert::to_socketcan_fd_frame(frame)?;
146 self.socket.write_frame(&sc_frame)?;
147 Ok(())
148 }
149}
150
151impl ReceiveFd for SocketCanChannel {
152 type Error = SocketCanError;
153 type Timestamp = Instant;
154
155 fn receive_fd(&mut self) -> Result<Timestamped<Frame, Instant>, Self::Error> {
156 self.ensure_blocking()?;
157 loop {
158 let any_frame = self.socket.read_frame()?;
159 let now = Instant::now();
160 if let Ok(frame) = convert::from_socketcan_any_frame(any_frame) {
161 return Ok(Timestamped::new(frame, now));
162 }
163 }
165 }
166
167 fn try_receive_fd(&mut self) -> Result<Option<Timestamped<Frame, Instant>>, Self::Error> {
168 self.ensure_nonblocking()?;
169 match self.socket.read_frame() {
170 Ok(any_frame) => {
171 let now = Instant::now();
172 Ok(convert::from_socketcan_any_frame(any_frame)
173 .ok()
174 .map(|frame| Timestamped::new(frame, now)))
175 }
176 Err(e) if e.kind() == io::ErrorKind::WouldBlock => Ok(None),
177 Err(e) => Err(SocketCanError::Io(e)),
178 }
179 }
180
181 fn receive_fd_timeout(
182 &mut self,
183 timeout: Duration,
184 ) -> Result<Option<Timestamped<Frame, Instant>>, Self::Error> {
185 self.ensure_blocking()?;
186 self.socket.set_read_timeout(timeout)?;
187 let deadline = Instant::now() + timeout;
188 let result = loop {
189 match self.socket.read_frame() {
190 Ok(any_frame) => {
191 let now = Instant::now();
192 if let Ok(frame) = convert::from_socketcan_any_frame(any_frame) {
193 break Ok(Some(Timestamped::new(frame, now)));
194 }
195 if now >= deadline {
197 break Ok(None);
198 }
199 self.socket.set_read_timeout(deadline - now).ok();
200 }
201 Err(e)
202 if e.kind() == io::ErrorKind::WouldBlock
203 || e.kind() == io::ErrorKind::TimedOut =>
204 {
205 break Ok(None);
206 }
207 Err(e) => break Err(SocketCanError::Io(e)),
208 }
209 };
210 self.socket.set_read_timeout(None).ok();
211 result
212 }
213}
214
215impl Filterable for SocketCanChannel {
216 type Error = SocketCanError;
217
218 fn set_filters(&mut self, filters: &[Filter]) -> Result<(), Self::Error> {
219 if filters.is_empty() {
223 return self.clear_filters();
224 }
225 let sc_filters: Vec<_> = filters.iter().map(convert::to_socketcan_filter).collect();
226 self.socket.set_filters(&sc_filters)?;
227 Ok(())
228 }
229
230 fn clear_filters(&mut self) -> Result<(), Self::Error> {
231 self.socket.set_filter_accept_all()?;
232 Ok(())
233 }
234}