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(_) => continue, 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 let _ = self.socket.set_read_timeout(deadline - now);
125 continue;
126 }
127 Err(e)
128 if e.kind() == io::ErrorKind::WouldBlock
129 || e.kind() == io::ErrorKind::TimedOut =>
130 {
131 break Ok(None);
132 }
133 Err(e) => break Err(SocketCanError::Io(e)),
134 }
135 };
136 let _ = self.socket.set_read_timeout(None);
138 result
139 }
140}
141
142impl TransmitFd for SocketCanChannel {
143 type Error = SocketCanError;
144
145 fn transmit_fd(&mut self, frame: &CanFdFrame) -> Result<(), Self::Error> {
146 let sc_frame = convert::to_socketcan_fd_frame(frame)?;
147 self.socket.write_frame(&sc_frame)?;
148 Ok(())
149 }
150}
151
152impl ReceiveFd for SocketCanChannel {
153 type Error = SocketCanError;
154 type Timestamp = Instant;
155
156 fn receive_fd(&mut self) -> Result<Timestamped<Frame, Instant>, Self::Error> {
157 self.ensure_blocking()?;
158 loop {
159 let any_frame = self.socket.read_frame()?;
160 let now = Instant::now();
161 match convert::from_socketcan_any_frame(any_frame) {
162 Ok(frame) => return Ok(Timestamped::new(frame, now)),
163 Err(_) => continue, }
165 }
166 }
167
168 fn try_receive_fd(&mut self) -> Result<Option<Timestamped<Frame, Instant>>, Self::Error> {
169 self.ensure_nonblocking()?;
170 match self.socket.read_frame() {
171 Ok(any_frame) => {
172 let now = Instant::now();
173 match convert::from_socketcan_any_frame(any_frame) {
174 Ok(frame) => Ok(Some(Timestamped::new(frame, now))),
175 Err(_) => Ok(None),
176 }
177 }
178 Err(e) if e.kind() == io::ErrorKind::WouldBlock => Ok(None),
179 Err(e) => Err(SocketCanError::Io(e)),
180 }
181 }
182
183 fn receive_fd_timeout(
184 &mut self,
185 timeout: Duration,
186 ) -> Result<Option<Timestamped<Frame, Instant>>, Self::Error> {
187 self.ensure_blocking()?;
188 self.socket.set_read_timeout(timeout)?;
189 let deadline = Instant::now() + timeout;
190 let result = loop {
191 match self.socket.read_frame() {
192 Ok(any_frame) => {
193 let now = Instant::now();
194 match convert::from_socketcan_any_frame(any_frame) {
195 Ok(frame) => break Ok(Some(Timestamped::new(frame, now))),
196 Err(_) => {
197 if now >= deadline {
199 break Ok(None);
200 }
201 let _ = self.socket.set_read_timeout(deadline - now);
202 continue;
203 }
204 }
205 }
206 Err(e)
207 if e.kind() == io::ErrorKind::WouldBlock
208 || e.kind() == io::ErrorKind::TimedOut =>
209 {
210 break Ok(None);
211 }
212 Err(e) => break Err(SocketCanError::Io(e)),
213 }
214 };
215 let _ = self.socket.set_read_timeout(None);
216 result
217 }
218}
219
220impl Filterable for SocketCanChannel {
221 type Error = SocketCanError;
222
223 fn set_filters(&mut self, filters: &[Filter]) -> Result<(), Self::Error> {
224 let sc_filters: Vec<_> = filters.iter().map(convert::to_socketcan_filter).collect();
225 self.socket.set_filters(&sc_filters)?;
226 Ok(())
227 }
228
229 fn clear_filters(&mut self) -> Result<(), Self::Error> {
230 self.socket.set_filter_accept_all()?;
231 Ok(())
232 }
233}