socketcan/socket.rs
1// socketcan/src/socket.rs
2//
3// Implements sockets 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//! Implementation of sockets for CANbus 2.0 and FD for SocketCAN on Linux.
13
14use crate::{
15 as_bytes, as_bytes_mut,
16 frame::{can_frame_default, canfd_frame_default, AsPtr},
17 id::CAN_ERR_MASK,
18 timestamp::CanTimestamps,
19 CanAnyFrame, CanFdFrame, CanFrame, CanRawFrame, Error, IoError, IoErrorKind, IoResult, Result,
20};
21pub use embedded_can::{
22 self, blocking::Can as BlockingCan, nb::Can as NonBlockingCan, ExtendedId,
23 Frame as EmbeddedFrame, Id, StandardId,
24};
25use libc::{canid_t, socklen_t, AF_CAN, EINPROGRESS, SOL_SOCKET};
26use socket2::SockAddr;
27use std::{
28 fmt,
29 io::{Read, Write},
30 mem::{size_of, size_of_val, zeroed},
31 os::{
32 raw::{c_int, c_void},
33 unix::io::{AsFd, AsRawFd, BorrowedFd, IntoRawFd, OwnedFd, RawFd},
34 },
35 ptr,
36 time::{Duration, SystemTime},
37};
38
39pub use libc::{
40 CANFD_MTU, CAN_MTU, CAN_RAW, CAN_RAW_ERR_FILTER, CAN_RAW_FD_FRAMES, CAN_RAW_FILTER,
41 CAN_RAW_JOIN_FILTERS, CAN_RAW_LOOPBACK, CAN_RAW_RECV_OWN_MSGS, SOL_CAN_BASE, SOL_CAN_RAW,
42};
43
44// TODO: This can be removed on the next major version update
45pub use crate::CanAddr;
46
47/// Check an error return value for timeouts.
48///
49/// Due to the fact that timeouts are reported as errors, calling `read_frame`
50/// on a socket with a timeout that does not receive a frame in time will
51/// result in an error being returned. This trait adds a `should_retry` method
52/// to `Error` and `Result` to check for this condition.
53pub trait ShouldRetry {
54 /// Check for timeout
55 ///
56 /// If `true`, the error is probably due to a timeout.
57 fn should_retry(&self) -> bool;
58}
59
60impl ShouldRetry for IoError {
61 fn should_retry(&self) -> bool {
62 match self.kind() {
63 // EAGAIN, EINPROGRESS and EWOULDBLOCK are the three possible codes
64 // returned when a timeout occurs. the stdlib already maps EAGAIN
65 // and EWOULDBLOCK os WouldBlock
66 IoErrorKind::WouldBlock => true,
67 // however, EINPROGRESS is also valid
68 IoErrorKind::Other => {
69 matches!(self.raw_os_error(), Some(errno) if errno == EINPROGRESS)
70 }
71 _ => false,
72 }
73 }
74}
75
76impl<E: fmt::Debug> ShouldRetry for IoResult<E> {
77 fn should_retry(&self) -> bool {
78 match *self {
79 Err(ref e) => e.should_retry(),
80 _ => false,
81 }
82 }
83}
84
85// ===== Private local helper functions =====
86
87/// Tries to open the CAN socket by the interface number.
88fn raw_open_socket(addr: &CanAddr) -> IoResult<socket2::Socket> {
89 let af_can = socket2::Domain::from(AF_CAN);
90 let can_raw = socket2::Protocol::from(CAN_RAW);
91
92 let sock = socket2::Socket::new_raw(af_can, socket2::Type::RAW, Some(can_raw))?;
93 sock.bind(&SockAddr::from(*addr))?;
94 Ok(sock)
95}
96
97/// `setsockopt` wrapper
98///
99/// The libc `setsockopt` function is set to set various options on a socket.
100/// `set_socket_option` offers a somewhat type-safe wrapper that does not
101/// require messing around with `*const c_void`s.
102///
103/// A proper `std::io::Error` will be returned on failure.
104///
105/// Example use:
106///
107/// ```text
108/// let fd = ...; // some file descriptor, this will be stdout
109/// set_socket_option(fd, SOL_TCP, TCP_NO_DELAY, 1 as c_int)
110/// ```
111///
112/// Note that the `val` parameter must be specified correctly; if an option
113/// expects an integer, it is advisable to pass in a `c_int`, not the default
114/// of `i32`.
115#[deprecated(since = "3.4.0", note = "Moved into `SocketOptions` trait")]
116#[inline]
117pub fn set_socket_option<T>(fd: c_int, level: c_int, name: c_int, val: &T) -> IoResult<()> {
118 let ret = unsafe {
119 libc::setsockopt(
120 fd,
121 level,
122 name,
123 val as *const _ as *const c_void,
124 size_of::<T>() as socklen_t,
125 )
126 };
127
128 match ret {
129 0 => Ok(()),
130 _ => Err(IoError::last_os_error()),
131 }
132}
133
134/// Sets a collection of multiple socket options with one call.
135#[deprecated(since = "3.4.0", note = "Moved into `SocketOptions` trait")]
136pub fn set_socket_option_mult<T>(
137 fd: c_int,
138 level: c_int,
139 name: c_int,
140 values: &[T],
141) -> IoResult<()> {
142 let ret = if values.is_empty() {
143 // can't pass in a ptr to a 0-len slice, pass a null ptr instead
144 unsafe { libc::setsockopt(fd, level, name, ptr::null(), 0) }
145 } else {
146 unsafe {
147 libc::setsockopt(
148 fd,
149 level,
150 name,
151 values.as_ptr().cast(),
152 size_of_val(values) as socklen_t,
153 )
154 }
155 };
156
157 match ret {
158 0 => Ok(()),
159 _ => Err(IoError::last_os_error()),
160 }
161}
162
163// ===== Common 'Socket' trait =====
164
165/// Common trait for SocketCAN sockets.
166///
167/// Note that a socket it created by opening it, and then closed by
168/// dropping it.
169pub trait Socket: AsRawFd {
170 /// Open a named CAN device.
171 ///
172 /// Usually the more common case, opens a socket can device by name, such
173 /// as "can0", "vcan0", or "socan0".
174 fn open(ifname: &str) -> IoResult<Self>
175 where
176 Self: Sized,
177 {
178 let addr = CanAddr::from_iface(ifname)?;
179 Self::open_addr(&addr)
180 }
181
182 /// Open CAN device by interface number.
183 ///
184 /// Opens a CAN device by kernel interface number.
185 fn open_iface(ifindex: u32) -> IoResult<Self>
186 where
187 Self: Sized,
188 {
189 let addr = CanAddr::new(ifindex);
190 Self::open_addr(&addr)
191 }
192
193 /// Open a CAN socket by address.
194 fn open_addr(addr: &CanAddr) -> IoResult<Self>
195 where
196 Self: Sized;
197
198 /// Gets a shared reference to the underlying socket object
199 fn as_raw_socket(&self) -> &socket2::Socket;
200
201 /// Gets a mutable reference to the underlying socket object
202 fn as_raw_socket_mut(&mut self) -> &mut socket2::Socket;
203
204 /// Determines if the socket is currently in nonblocking mode.
205 fn nonblocking(&self) -> IoResult<bool> {
206 self.as_raw_socket().nonblocking()
207 }
208
209 /// Change socket to non-blocking mode or back to blocking mode.
210 fn set_nonblocking(&self, nonblocking: bool) -> IoResult<()> {
211 self.as_raw_socket().set_nonblocking(nonblocking)
212 }
213
214 /// The type of CAN frame that can be read and written by the socket.
215 ///
216 /// This is typically distinguished by the size of the supported frame,
217 /// with the primary difference between a `CanFrame` and a `CanFdFrame`.
218 type FrameType;
219
220 /// Gets the read timeout on the socket, if any.
221 fn read_timeout(&self) -> IoResult<Option<Duration>> {
222 self.as_raw_socket().read_timeout()
223 }
224
225 /// Sets the read timeout on the socket
226 ///
227 /// For convenience, the result value can be checked using
228 /// `ShouldRetry::should_retry` when a timeout is set.
229 ///
230 /// If the duration is set to `None` then write calls will block
231 /// indefinitely.
232 fn set_read_timeout<D>(&self, duration: D) -> IoResult<()>
233 where
234 D: Into<Option<Duration>>,
235 {
236 self.as_raw_socket().set_read_timeout(duration.into())
237 }
238
239 /// Gets the write timeout on the socket, if any.
240 fn write_timeout(&self) -> IoResult<Option<Duration>> {
241 self.as_raw_socket().write_timeout()
242 }
243
244 /// Sets the write timeout on the socket
245 ///
246 /// If the duration is set to `None` then write calls will block
247 /// indefinitely.
248 fn set_write_timeout<D>(&self, duration: D) -> IoResult<()>
249 where
250 D: Into<Option<Duration>>,
251 {
252 self.as_raw_socket().set_write_timeout(duration.into())
253 }
254
255 /// Blocking read a single can frame.
256 ///
257 /// Concurrent readers: each `recvmsg()` consumes one frame from the
258 /// socket's kernel receive queue. If two tasks call `read_frame*` on the
259 /// same socket concurrently (via shared references), each will receive a
260 /// disjoint subset of frames, but no two will ever observe the same
261 /// frame. The frames are not duplicated and the call is safe, but the
262 /// per-reader stream is not deterministic — design with that in mind.
263 fn read_frame(&self) -> IoResult<Self::FrameType>;
264
265 /// Blocking read a single can frame with timeout.
266 fn read_frame_timeout(&self, timeout: Duration) -> IoResult<Self::FrameType> {
267 use nix::poll::{poll, PollFd, PollFlags, PollTimeout};
268 let pollfd = PollFd::new(
269 unsafe { BorrowedFd::borrow_raw(self.as_raw_fd()) },
270 PollFlags::POLLIN,
271 );
272
273 match poll(
274 &mut [pollfd],
275 timeout.try_into().unwrap_or(PollTimeout::MAX),
276 )? {
277 0 => Err(IoErrorKind::TimedOut.into()),
278 _ => self.read_frame(),
279 }
280 }
281
282 /// Blocking read a CAN frame and its socket-layer arrival timestamp.
283 ///
284 /// Requires [`SocketOptions::set_recv_timestamp`] to be called with `true`
285 /// before this method. Returns an `InvalidData` error if no
286 /// `SO_TIMESTAMPNS` control message was delivered.
287 fn read_frame_with_timestamp(&self) -> IoResult<(Self::FrameType, SystemTime)> {
288 Err(IoError::from_raw_os_error(libc::ENOSYS))
289 }
290
291 /// Blocking read a CAN frame and its raw hardware clock timestamp.
292 ///
293 /// Requires [`SocketOptions::set_timestamping`] to be called with
294 /// `SOF_TIMESTAMPING_RX_HARDWARE | SOF_TIMESTAMPING_OPT_CMSG` (and any
295 /// other desired flags) before this method. Returns an `InvalidData` error
296 /// if no hardware timestamp was delivered.
297 fn read_frame_with_hw_timestamp(&self) -> IoResult<(Self::FrameType, Duration)> {
298 Err(IoError::from_raw_os_error(libc::ENOSYS))
299 }
300
301 /// Blocking read a CAN frame and all available timestamps.
302 ///
303 /// Populates whichever [`CanTimestamps`] fields correspond to the
304 /// `SO_TIMESTAMPNS` and/or `SO_TIMESTAMPING` modes that were enabled on
305 /// the socket before the call. Fields for disabled modes are `None`.
306 fn read_frame_with_timestamps(&self) -> IoResult<(Self::FrameType, CanTimestamps)> {
307 Err(IoError::from_raw_os_error(libc::ENOSYS))
308 }
309
310 /// Writes a normal CAN 2.0 frame to the socket.
311 fn write_frame<F>(&self, frame: &F) -> IoResult<()>
312 where
313 F: Into<Self::FrameType> + AsPtr;
314
315 /// Blocking write a single can frame, retrying until it gets sent
316 /// successfully.
317 fn write_frame_insist<F>(&self, frame: &F) -> IoResult<()>
318 where
319 F: Into<Self::FrameType> + AsPtr,
320 {
321 loop {
322 match self.write_frame(frame) {
323 Ok(v) => return Ok(v),
324 Err(e) if e.should_retry() => (),
325 Err(e) => return Err(e),
326 }
327 }
328 }
329}
330
331/// Traits for setting CAN socket options.
332///
333/// These are blocking calls, even when implemented on asynchronous sockets.
334pub trait SocketOptions: AsRawFd {
335 /// Sets an option on the socket.
336 ///
337 /// The libc `setsockopt` function is set to set various options on a socket.
338 /// `set_socket_option` offers a somewhat type-safe wrapper that does not
339 /// require messing around with `*const c_void`s.
340 ///
341 /// A proper `std::io::Error` will be returned on failure.
342 ///
343 /// Example use:
344 ///
345 /// ```text
346 /// sock.set_socket_option(SOL_TCP, TCP_NO_DELAY, 1 as c_int)
347 /// ```
348 ///
349 /// Note that the `val` parameter must be specified correctly; if an option
350 /// expects an integer, it is advisable to pass in a `c_int`, not the default
351 /// of `i32`.
352 fn set_socket_option<T>(&self, level: c_int, name: c_int, val: &T) -> IoResult<()> {
353 let ret = unsafe {
354 libc::setsockopt(
355 self.as_raw_fd(),
356 level,
357 name,
358 val as *const _ as *const c_void,
359 size_of::<T>() as socklen_t,
360 )
361 };
362
363 match ret {
364 0 => Ok(()),
365 _ => Err(IoError::last_os_error()),
366 }
367 }
368
369 /// Sets a collection of multiple socket options with one call.
370 fn set_socket_option_mult<T>(&self, level: c_int, name: c_int, values: &[T]) -> IoResult<()> {
371 let ret = if values.is_empty() {
372 // can't pass in a ptr to a 0-len slice, pass a null ptr instead
373 unsafe { libc::setsockopt(self.as_raw_fd(), level, name, ptr::null(), 0) }
374 } else {
375 unsafe {
376 libc::setsockopt(
377 self.as_raw_fd(),
378 level,
379 name,
380 values.as_ptr().cast(),
381 size_of_val(values) as socklen_t,
382 )
383 }
384 };
385
386 match ret {
387 0 => Ok(()),
388 _ => Err(IoError::last_os_error()),
389 }
390 }
391
392 /// Sets CAN ID filters on the socket.
393 ///
394 /// CAN packages received by SocketCAN are matched against these filters,
395 /// only matching packets are returned by the interface.
396 ///
397 /// See `CanFilter` for details on how filtering works. By default, all
398 /// single filter matching all incoming frames is installed.
399 fn set_filters<F>(&self, filters: &[F]) -> IoResult<()>
400 where
401 F: Into<CanFilter> + Copy,
402 {
403 let filters: Vec<CanFilter> = filters.iter().map(|f| (*f).into()).collect();
404 self.set_socket_option_mult(SOL_CAN_RAW, CAN_RAW_FILTER, &filters)
405 }
406
407 /// Disable reception of CAN frames.
408 ///
409 /// Sets a completely empty filter; disabling all CAN frame reception.
410 fn set_filter_drop_all(&self) -> IoResult<()> {
411 let filters: &[CanFilter] = &[];
412 self.set_socket_option_mult(SOL_CAN_RAW, CAN_RAW_FILTER, filters)
413 }
414
415 /// Accept all frames, disabling any kind of filtering.
416 ///
417 /// Replace the current filter with one containing a single rule that
418 /// acceps all CAN frames.
419 fn set_filter_accept_all(&self) -> IoResult<()> {
420 // safe unwrap: 0, 0 is a valid mask/id pair
421 self.set_filters(&[(0, 0)])
422 }
423
424 /// Sets the error mask on the socket.
425 ///
426 /// By default (`ERR_MASK_NONE`) no error conditions are reported as
427 /// special error frames by the socket. Enabling error conditions by
428 /// setting `ERR_MASK_ALL` or another non-empty error mask causes the
429 /// socket to receive notification about the specified conditions.
430 fn set_error_filter(&self, mask: u32) -> IoResult<()> {
431 self.set_socket_option(SOL_CAN_RAW, CAN_RAW_ERR_FILTER, &mask)
432 }
433
434 /// Sets the error mask on the socket to reject all errors.
435 #[inline(always)]
436 fn set_error_filter_drop_all(&self) -> IoResult<()> {
437 self.set_error_filter(0)
438 }
439
440 /// Sets the error mask on the socket to accept all errors.
441 #[inline(always)]
442 fn set_error_filter_accept_all(&self) -> IoResult<()> {
443 self.set_error_filter(CAN_ERR_MASK)
444 }
445
446 /// Sets the error mask on the socket.
447 ///
448 /// By default (`ERR_MASK_NONE`) no error conditions are reported as
449 /// special error frames by the socket. Enabling error conditions by
450 /// setting `ERR_MASK_ALL` or another non-empty error mask causes the
451 /// socket to receive notification about the specified conditions.
452 fn set_error_mask(&self, mask: u32) -> IoResult<()> {
453 self.set_socket_option(SOL_CAN_RAW, CAN_RAW_ERR_FILTER, &mask)
454 }
455
456 /// Enable or disable loopback.
457 ///
458 /// By default, loopback is enabled, causing other applications that open
459 /// the same CAN bus to see frames emitted by different applications on
460 /// the same system.
461 fn set_loopback(&self, enabled: bool) -> IoResult<()> {
462 let loopback = c_int::from(enabled);
463 self.set_socket_option(SOL_CAN_RAW, CAN_RAW_LOOPBACK, &loopback)
464 }
465
466 /// Enable or disable receiving of own frames.
467 ///
468 /// When loopback is enabled, this settings controls if CAN frames sent
469 /// are received back immediately by sender. Default is off.
470 fn set_recv_own_msgs(&self, enabled: bool) -> IoResult<()> {
471 let recv_own_msgs = c_int::from(enabled);
472 self.set_socket_option(SOL_CAN_RAW, CAN_RAW_RECV_OWN_MSGS, &recv_own_msgs)
473 }
474
475 /// Enable or disable join filters.
476 ///
477 /// By default a frame is accepted if it matches any of the filters set
478 /// with `set_filters`. If join filters is enabled, a frame has to match
479 /// _all_ filters to be accepted.
480 fn set_join_filters(&self, enabled: bool) -> IoResult<()> {
481 let join_filters = c_int::from(enabled);
482 self.set_socket_option(SOL_CAN_RAW, CAN_RAW_JOIN_FILTERS, &join_filters)
483 }
484
485 /// Enable or disable `SO_TIMESTAMPNS` on the socket.
486 ///
487 /// When enabled, `recvmsg()` delivers a `SCM_TIMESTAMPNS` control message
488 /// containing the socket-layer arrival time as a `timespec`. Call this
489 /// before using [`Socket::read_frame_with_timestamp`].
490 ///
491 /// This option is independent of [`set_timestamping`]; both can be
492 /// enabled simultaneously and the resulting timestamps land in
493 /// separate fields of [`CanTimestamps`].
494 ///
495 /// [`set_timestamping`]: Self::set_timestamping
496 /// [`CanTimestamps`]: crate::CanTimestamps
497 fn set_recv_timestamp(&self, enable: bool) -> IoResult<()> {
498 let val = c_int::from(enable);
499 self.set_socket_option(SOL_SOCKET, libc::SO_TIMESTAMPNS, &val)
500 }
501
502 /// Set `SO_TIMESTAMPING` flags on the socket.
503 ///
504 /// `flags` is a bitmask of `SOF_TIMESTAMPING_*` constants. Each
505 /// timestamp source needs two flags — one to select **when** it is
506 /// taken, and one to request that it be **reported** in the ancillary
507 /// data:
508 ///
509 /// | When (selector) | Report (in ancillary data) |
510 /// |----------------------------------|---------------------------------------|
511 /// | [`SOF_TIMESTAMPING_RX_SOFTWARE`] | [`SOF_TIMESTAMPING_SOFTWARE`] |
512 /// | [`SOF_TIMESTAMPING_RX_HARDWARE`] | [`SOF_TIMESTAMPING_RAW_HARDWARE`] |
513 ///
514 /// Setting only a selector flag silently delivers no timestamps;
515 /// setting only a reporter flag captures nothing to report.
516 ///
517 /// In addition, [`SOF_TIMESTAMPING_OPT_CMSG`] is required for RX
518 /// timestamps to actually appear in the cmsg returned by `recvmsg()`
519 /// on non-IP sockets (which includes CAN raw).
520 ///
521 /// Call this before using [`Socket::read_frame_with_timestamps`] or
522 /// [`Socket::read_frame_with_hw_timestamp`].
523 ///
524 /// [`SOF_TIMESTAMPING_OPT_CMSG`]: crate::SOF_TIMESTAMPING_OPT_CMSG
525 /// [`SOF_TIMESTAMPING_RX_SOFTWARE`]: crate::SOF_TIMESTAMPING_RX_SOFTWARE
526 /// [`SOF_TIMESTAMPING_SOFTWARE`]: crate::SOF_TIMESTAMPING_SOFTWARE
527 /// [`SOF_TIMESTAMPING_RX_HARDWARE`]: crate::SOF_TIMESTAMPING_RX_HARDWARE
528 /// [`SOF_TIMESTAMPING_RAW_HARDWARE`]: crate::SOF_TIMESTAMPING_RAW_HARDWARE
529 fn set_timestamping(&self, flags: u32) -> IoResult<()> {
530 let val = flags as c_int;
531 self.set_socket_option(SOL_SOCKET, libc::SO_TIMESTAMPING, &val)
532 }
533}
534
535// ===== Private helpers =====
536
537/// Returns true if the interface bound to `fd` reports RX hardware timestamp support.
538///
539/// Issues a `SIOCETHTOOL` / `ETHTOOL_GET_TS_INFO` ioctl and checks the
540/// `SOF_TIMESTAMPING_RX_HARDWARE` bit.
541///
542/// Returns `false` on any error (unbound socket, unsupported ioctl,
543/// unknown interface, etc).
544fn hw_timestamps_supported(fd: RawFd) -> bool {
545 use crate::timestamp::{EthtoolTsInfo, ETHTOOL_GET_TS_INFO, SOF_TIMESTAMPING_RX_HARDWARE};
546 // Ioctl is u64 in glibc and i32 in musl this ensures the correct type is used for both
547 const SIOCETHTOOL: libc::Ioctl = libc::SIOCETHTOOL as libc::Ioctl;
548
549 // Retrieve the interface index from the bound socket address.
550 let ifindex = unsafe {
551 let mut addr: libc::sockaddr_can = zeroed();
552 let mut addrlen = size_of::<libc::sockaddr_can>() as socklen_t;
553 let ret = libc::getsockname(fd, &mut addr as *mut _ as *mut libc::sockaddr, &mut addrlen);
554 if ret != 0 || addr.can_ifindex <= 0 {
555 return false;
556 }
557 addr.can_ifindex as libc::c_uint
558 };
559
560 // Convert interface index to a name string.
561 let mut ifname = [0 as libc::c_char; libc::IF_NAMESIZE];
562 if unsafe { libc::if_indextoname(ifindex, ifname.as_mut_ptr()) }.is_null() {
563 return false;
564 }
565
566 // Query hardware timestamping capabilities via SIOCETHTOOL.
567 let mut ts_info = EthtoolTsInfo {
568 cmd: ETHTOOL_GET_TS_INFO,
569 so_timestamping: 0,
570 phc_index: 0,
571 tx_types: 0,
572 tx_reserved: [0; 3],
573 rx_filters: 0,
574 rx_reserved: [0; 3],
575 };
576
577 let ret = unsafe {
578 let mut ifr: libc::ifreq = zeroed();
579 ifr.ifr_name.copy_from_slice(&ifname);
580 ifr.ifr_ifru.ifru_data = (&mut ts_info as *mut EthtoolTsInfo).cast();
581 libc::ioctl(fd, SIOCETHTOOL, &mut ifr)
582 };
583
584 ret == 0 && ts_info.so_timestamping & SOF_TIMESTAMPING_RX_HARDWARE != 0
585}
586
587/// Size of the `recvmsg()` ancillary control buffer.
588///
589/// Comfortably larger than what we need today:
590/// `CMSG_SPACE(sizeof(timespec))` — `SO_TIMESTAMPNS` cmsg
591/// `+ CMSG_SPACE(3 * sizeof(timespec))` — `SO_TIMESTAMPING` cmsg
592/// ≈ 80 bytes on 64-bit Linux. 256 leaves headroom for future cmsg types.
593const CTRL_BUF_SIZE: usize = 256;
594
595/// Properly-aligned backing storage for the `recvmsg()` ancillary buffer.
596///
597/// `CMSG_FIRSTHDR`/`CMSG_NXTHDR` interpret the buffer as a sequence of
598/// `cmsghdr` structures, which require `usize` alignment on Linux. A raw
599/// `[u8; N]` has alignment 1; aligning to 8 bytes satisfies the contract
600/// on all supported architectures.
601#[repr(C, align(8))]
602struct CtrlBuf([u8; CTRL_BUF_SIZE]);
603
604/// Issues `recvmsg()` on `fd`, writing frame bytes into `frame_buf`, and
605/// parses any `SOL_SOCKET` timestamp control messages into a [`CanTimestamps`].
606///
607/// Returns `(bytes_received, timestamps)`. The returned byte count is the
608/// *real* packet size on the wire (via `MSG_TRUNC`), even if it exceeds
609/// `frame_buf.len()`; callers should compare against `CAN_MTU`/`CANFD_MTU`
610/// before trusting the buffer contents. Timestamp fields are `None` when
611/// the corresponding socket option was not enabled before the call.
612///
613/// Returns `InvalidData` if the kernel sets `MSG_CTRUNC`, indicating the
614/// ancillary buffer was too small to hold all delivered cmsgs.
615fn recvmsg_with_ctrl(fd: RawFd, frame_buf: &mut [u8]) -> IoResult<(usize, CanTimestamps)> {
616 use crate::timestamp::{timespec_to_duration, timespec_to_system_time};
617
618 let mut iov = libc::iovec {
619 iov_base: frame_buf.as_mut_ptr() as *mut libc::c_void,
620 iov_len: frame_buf.len(),
621 };
622
623 let mut ctrl = CtrlBuf([0u8; CTRL_BUF_SIZE]);
624 let mut msg: libc::msghdr = unsafe { zeroed() };
625 msg.msg_iov = &mut iov;
626 msg.msg_iovlen = 1;
627 msg.msg_control = ctrl.0.as_mut_ptr() as *mut libc::c_void;
628 msg.msg_controllen = ctrl.0.len() as _;
629
630 // MSG_TRUNC: return the real packet length even if the iov was too small,
631 // so callers can distinguish classic vs. FD frames by byte count rather
632 // than silently truncating an FD frame into a classic-sized buffer.
633 let n = unsafe { libc::recvmsg(fd, &mut msg, libc::MSG_TRUNC) };
634 if n < 0 {
635 return Err(IoError::last_os_error());
636 }
637
638 if msg.msg_flags & libc::MSG_CTRUNC != 0 {
639 return Err(IoError::new(
640 IoErrorKind::InvalidData,
641 "recvmsg ancillary control buffer overflowed (MSG_CTRUNC)",
642 ));
643 }
644
645 // Minimum cmsg_len for the two payload types we accept. A shorter cmsg
646 // means the payload is truncated; skip rather than reading past it.
647 let ns_min = unsafe { libc::CMSG_LEN(size_of::<libc::timespec>() as u32) } as usize;
648 let scm_min = unsafe { libc::CMSG_LEN((3 * size_of::<libc::timespec>()) as u32) } as usize;
649
650 let mut ts = CanTimestamps::default();
651 let mut cmsg = unsafe { libc::CMSG_FIRSTHDR(&msg) };
652
653 while !cmsg.is_null() {
654 let (level, typ, len) = unsafe {
655 (
656 (*cmsg).cmsg_level,
657 (*cmsg).cmsg_type,
658 (*cmsg).cmsg_len as usize,
659 )
660 };
661 let data = unsafe { libc::CMSG_DATA(cmsg) };
662 match (level, typ) {
663 (SOL_SOCKET, libc::SO_TIMESTAMPNS) if len >= ns_min => {
664 let timespec = unsafe { ptr::read_unaligned(data.cast::<libc::timespec>()) };
665 ts.socket = Some(timespec_to_system_time(timespec));
666 }
667 (SOL_SOCKET, libc::SO_TIMESTAMPING) if len >= scm_min => {
668 // scm_timestamping: [timespec; 3]
669 // [0] = RX_SOFTWARE (sw), [1] deprecated (zero), [2] = HW
670 let tss = unsafe { ptr::read_unaligned(data.cast::<[libc::timespec; 3]>()) };
671 if tss[0].tv_sec != 0 || tss[0].tv_nsec != 0 {
672 ts.sw = Some(timespec_to_system_time(tss[0]));
673 }
674 if tss[2].tv_sec != 0 || tss[2].tv_nsec != 0 {
675 ts.hw = Some(timespec_to_duration(tss[2]));
676 }
677 }
678 _ => {}
679 }
680 cmsg = unsafe { libc::CMSG_NXTHDR(&msg, cmsg) };
681 }
682
683 Ok((n as usize, ts))
684}
685
686// ===== CanSocket =====
687
688/// A socket for classic CAN 2.0 devices.
689///
690/// This provides an interface to read and write classic CAN 2.0 frames to
691/// the bus, with up to 8 bytes of data per frame. It wraps a Linux socket
692/// descriptor to a Raw SocketCAN socket.
693///
694/// The socket is automatically closed when the object is dropped. To close
695/// manually, use std::drop::Drop. Internally this is just a wrapped socket
696/// (file) descriptor.
697#[allow(missing_copy_implementations)]
698#[derive(Debug)]
699pub struct CanSocket(socket2::Socket);
700
701impl CanSocket {
702 /// Reads a low-level libc `can_frame` from the socket.
703 pub fn read_raw_frame(&self) -> IoResult<libc::can_frame> {
704 let mut frame = can_frame_default();
705 // SAFETY: `frame` is fully zero-initialised by `can_frame_default`.
706 self.as_raw_socket()
707 .read_exact(unsafe { as_bytes_mut(&mut frame) })?;
708 Ok(frame)
709 }
710
711 /// Returns `true` if the bound interface supports hardware receive timestamps.
712 ///
713 /// Returns `false` if the socket is unbound, the interface does not exist,
714 /// or the driver does not implement the ethtool timestamp query.
715 pub fn has_hw_timestamps(&self) -> bool {
716 hw_timestamps_supported(self.as_raw_fd())
717 }
718}
719
720impl Socket for CanSocket {
721 /// CanSocket reads/writes classic CAN 2.0 frames.
722 type FrameType = CanFrame;
723
724 /// Opens the socket by interface index.
725 fn open_addr(addr: &CanAddr) -> IoResult<Self> {
726 let sock = raw_open_socket(addr)?;
727 Ok(Self(sock))
728 }
729
730 /// Gets a shared reference to the underlying socket object
731 fn as_raw_socket(&self) -> &socket2::Socket {
732 &self.0
733 }
734
735 /// Gets a mutable reference to the underlying socket object
736 fn as_raw_socket_mut(&mut self) -> &mut socket2::Socket {
737 &mut self.0
738 }
739
740 /// Writes a normal CAN 2.0 frame to the socket.
741 fn write_frame<F>(&self, frame: &F) -> IoResult<()>
742 where
743 F: Into<CanFrame> + AsPtr,
744 {
745 self.as_raw_socket().write_all(frame.as_bytes())
746 }
747
748 /// Reads a normal CAN 2.0 frame from the socket.
749 fn read_frame(&self) -> IoResult<CanFrame> {
750 let frame = self.read_raw_frame()?;
751 Ok(frame.into())
752 }
753
754 fn read_frame_with_timestamp(&self) -> IoResult<(CanFrame, SystemTime)> {
755 let (frame, ts) = self.read_frame_with_timestamps()?;
756 let timestamp = ts.socket.ok_or_else(|| {
757 IoError::new(
758 IoErrorKind::InvalidData,
759 "no SO_TIMESTAMPNS control message received",
760 )
761 })?;
762 Ok((frame, timestamp))
763 }
764
765 fn read_frame_with_hw_timestamp(&self) -> IoResult<(CanFrame, Duration)> {
766 let (frame, ts) = self.read_frame_with_timestamps()?;
767 let hw_ts = ts.hw.ok_or_else(|| {
768 IoError::new(
769 IoErrorKind::InvalidData,
770 "no SO_TIMESTAMPING hardware timestamp received",
771 )
772 })?;
773 Ok((frame, hw_ts))
774 }
775
776 fn read_frame_with_timestamps(&self) -> IoResult<(CanFrame, CanTimestamps)> {
777 let mut frame = can_frame_default();
778 // SAFETY: `frame` is fully zero-initialised by `can_frame_default`.
779 let buf = unsafe { as_bytes_mut(&mut frame) };
780 let (n, ts) = recvmsg_with_ctrl(self.as_raw_fd(), buf)?;
781 if n != CAN_MTU {
782 return Err(IoError::from(IoErrorKind::InvalidData));
783 }
784 Ok((CanFrame::from(frame), ts))
785 }
786}
787
788// ===== embedded_can I/O traits =====
789
790impl embedded_can::blocking::Can for CanSocket {
791 type Frame = CanFrame;
792 type Error = Error;
793
794 /// Blocking call to receive the next frame from the bus.
795 ///
796 /// This block and wait for the next frame to be received from the bus.
797 /// If an error frame is received, it will be converted to a `CanError`
798 /// and returned as an error.
799 fn receive(&mut self) -> Result<Self::Frame> {
800 match self.read_frame() {
801 Ok(CanFrame::Error(frame)) => Err(frame.into_error().into()),
802 Ok(frame) => Ok(frame),
803 Err(e) => Err(e.into()),
804 }
805 }
806
807 /// Blocking transmit of a frame to the bus.
808 fn transmit(&mut self, frame: &Self::Frame) -> Result<()> {
809 self.write_frame_insist(frame)?;
810 Ok(())
811 }
812}
813
814impl SocketOptions for CanSocket {}
815
816impl embedded_can::nb::Can for CanSocket {
817 type Frame = CanFrame;
818 type Error = Error;
819
820 /// Non-blocking call to receive the next frame from the bus.
821 ///
822 /// If an error frame is received, it will be converted to a `CanError`
823 /// and returned as an error.
824 /// If no frame is available, it returns a `WouldBlck` error.
825 fn receive(&mut self) -> nb::Result<Self::Frame, Self::Error> {
826 match self.read_frame() {
827 Ok(CanFrame::Error(frame)) => Err(Error::from(frame.into_error()).into()),
828 Ok(frame) => Ok(frame),
829 Err(err) if err.should_retry() => Err(nb::Error::WouldBlock),
830 Err(err) => Err(Error::from(err).into()),
831 }
832 }
833
834 /// Non-blocking transmit of a frame to the bus.
835 fn transmit(&mut self, frame: &Self::Frame) -> nb::Result<Option<Self::Frame>, Self::Error> {
836 match self.write_frame(frame) {
837 Ok(_) => Ok(None),
838 Err(err) if err.should_retry() => Err(nb::Error::WouldBlock),
839 Err(err) => Err(Error::from(err).into()),
840 }
841 }
842}
843
844// Has no effect: #[deprecated(since = "3.1", note = "Use AsFd::as_fd() instead.")]
845impl AsRawFd for CanSocket {
846 fn as_raw_fd(&self) -> RawFd {
847 self.0.as_raw_fd()
848 }
849}
850
851impl From<OwnedFd> for CanSocket {
852 fn from(fd: OwnedFd) -> Self {
853 Self(socket2::Socket::from(fd))
854 }
855}
856
857impl IntoRawFd for CanSocket {
858 fn into_raw_fd(self) -> RawFd {
859 self.0.into_raw_fd()
860 }
861}
862
863impl AsFd for CanSocket {
864 fn as_fd(&self) -> BorrowedFd<'_> {
865 self.0.as_fd()
866 }
867}
868
869impl Read for CanSocket {
870 fn read(&mut self, buf: &mut [u8]) -> IoResult<usize> {
871 self.0.read(buf)
872 }
873}
874
875impl Write for CanSocket {
876 fn write(&mut self, buf: &[u8]) -> IoResult<usize> {
877 self.0.write(buf)
878 }
879
880 fn flush(&mut self) -> IoResult<()> {
881 self.0.flush()
882 }
883}
884
885// ===== CanFdSocket =====
886
887/// A socket for CAN FD devices.
888///
889/// This can transmit and receive CAN 2.0 frames with up to 8-bytes of data,
890/// or CAN Flexible Data (FD) frames with up to 64-bytes of data.
891#[allow(missing_copy_implementations)]
892#[derive(Debug)]
893pub struct CanFdSocket(socket2::Socket);
894
895impl CanFdSocket {
896 // Enable or disable FD mode on a socket.
897 fn set_fd_mode(sock: socket2::Socket, enable: bool) -> IoResult<socket2::Socket> {
898 let enable = enable as c_int;
899
900 let ret = unsafe {
901 libc::setsockopt(
902 sock.as_raw_fd(),
903 SOL_CAN_RAW,
904 CAN_RAW_FD_FRAMES,
905 &enable as *const _ as *const c_void,
906 size_of::<c_int>() as u32,
907 )
908 };
909
910 match ret {
911 0 => Ok(sock),
912 _ => Err(IoError::last_os_error()),
913 }
914 }
915
916 // Figures out the type of frame from the MTU len read in.
917 // This assumes a socket read a raw packet into a `canfd_frame` and
918 // now needs to figure out which type it is by the MTU size.
919 fn convert_raw_frame(mtu_len: usize, raw_frame: libc::canfd_frame) -> IoResult<CanAnyFrame> {
920 match mtu_len {
921 CAN_MTU => {
922 let mut frame = can_frame_default();
923 // SAFETY: `frame` is zero-initialised; `raw_frame` was either
924 // filled by the kernel or zero-initialised before partial fill,
925 // so all its bytes are valid for read.
926 unsafe {
927 as_bytes_mut(&mut frame)[..CAN_MTU]
928 .copy_from_slice(&as_bytes(&raw_frame)[..CAN_MTU]);
929 }
930 Ok(CanFrame::from(frame).into())
931 }
932 CANFD_MTU => Ok(CanFdFrame::from(raw_frame).into()),
933 _ => Err(IoError::from(IoErrorKind::InvalidData)),
934 }
935 }
936
937 /// Returns `true` if the bound interface supports hardware receive timestamps.
938 ///
939 /// Returns `false` if the socket is unbound, the interface does not exist,
940 /// or the driver does not implement the ethtool timestamp query.
941 pub fn has_hw_timestamps(&self) -> bool {
942 hw_timestamps_supported(self.as_raw_fd())
943 }
944
945 /// Reads a raw CAN frame from the socket.
946 ///
947 /// This might be either type of CAN frame, a classic CAN 2.0 frame
948 /// or an FD frame.
949 pub fn read_raw_frame(&self) -> IoResult<CanRawFrame> {
950 let mut fdframe = canfd_frame_default();
951
952 // SAFETY: `fdframe` is fully zero-initialised by `canfd_frame_default`.
953 let buf = unsafe { as_bytes_mut(&mut fdframe) };
954 match self.as_raw_socket().read(buf)? {
955 // If we only get 'can_frame' number of bytes, then the return is,
956 // by definition, a can_frame, so we just copy the bytes into the
957 // proper type.
958 CAN_MTU => {
959 let mut frame = can_frame_default();
960 // SAFETY: `frame` zero-initialised; `fdframe` likewise (and
961 // possibly partially overwritten by the kernel above).
962 unsafe {
963 as_bytes_mut(&mut frame)[..CAN_MTU]
964 .copy_from_slice(&as_bytes(&fdframe)[..CAN_MTU]);
965 }
966 Ok(frame.into())
967 }
968 CANFD_MTU => Ok(fdframe.into()),
969 _ => Err(IoError::last_os_error()),
970 }
971 }
972}
973
974impl Socket for CanFdSocket {
975 /// CanFdSocket can read/write classic CAN 2.0 or FD frames.
976 type FrameType = CanAnyFrame;
977
978 /// Opens the FD socket by interface index.
979 fn open_addr(addr: &CanAddr) -> IoResult<Self> {
980 raw_open_socket(addr)
981 .and_then(|sock| Self::set_fd_mode(sock, true))
982 .map(Self)
983 }
984
985 /// Gets a shared reference to the underlying socket object
986 fn as_raw_socket(&self) -> &socket2::Socket {
987 &self.0
988 }
989
990 /// Gets a mutable reference to the underlying socket object
991 fn as_raw_socket_mut(&mut self) -> &mut socket2::Socket {
992 &mut self.0
993 }
994
995 /// Writes any type of CAN frame to the socket.
996 fn write_frame<F>(&self, frame: &F) -> IoResult<()>
997 where
998 F: Into<Self::FrameType> + AsPtr,
999 {
1000 self.as_raw_socket().write_all(frame.as_bytes())
1001 }
1002
1003 /// Reads either type of CAN frame from the socket.
1004 fn read_frame(&self) -> IoResult<CanAnyFrame> {
1005 let mut fdframe = canfd_frame_default();
1006
1007 // SAFETY: `fdframe` is fully zero-initialised by `canfd_frame_default`.
1008 let n = self
1009 .as_raw_socket()
1010 .read(unsafe { as_bytes_mut(&mut fdframe) })?;
1011 Self::convert_raw_frame(n, fdframe)
1012 }
1013
1014 fn read_frame_with_timestamp(&self) -> IoResult<(CanAnyFrame, SystemTime)> {
1015 let (frame, ts) = self.read_frame_with_timestamps()?;
1016 let sw_ts = ts.socket.ok_or_else(|| {
1017 IoError::new(
1018 IoErrorKind::InvalidData,
1019 "no SO_TIMESTAMPNS control message received",
1020 )
1021 })?;
1022 Ok((frame, sw_ts))
1023 }
1024
1025 fn read_frame_with_hw_timestamp(&self) -> IoResult<(CanAnyFrame, Duration)> {
1026 let (frame, ts) = self.read_frame_with_timestamps()?;
1027 let hw_ts = ts.hw.ok_or_else(|| {
1028 IoError::new(
1029 IoErrorKind::InvalidData,
1030 "no SO_TIMESTAMPING hardware timestamp received",
1031 )
1032 })?;
1033 Ok((frame, hw_ts))
1034 }
1035
1036 fn read_frame_with_timestamps(&self) -> IoResult<(CanAnyFrame, CanTimestamps)> {
1037 let mut fdframe = canfd_frame_default();
1038 // SAFETY: `fdframe` is fully zero-initialised by `canfd_frame_default`.
1039 let buf = unsafe { as_bytes_mut(&mut fdframe) };
1040 let (n, ts) = recvmsg_with_ctrl(self.as_raw_fd(), buf)?;
1041 let any_frame = Self::convert_raw_frame(n, fdframe)?;
1042 Ok((any_frame, ts))
1043 }
1044}
1045
1046impl SocketOptions for CanFdSocket {}
1047
1048impl embedded_can::blocking::Can for CanFdSocket {
1049 type Frame = CanAnyFrame;
1050 type Error = Error;
1051
1052 /// Blocking call to receive the next frame from the bus.
1053 ///
1054 /// This block and wait for the next frame to be received from the bus.
1055 /// If an error frame is received, it will be converted to a `CanError`
1056 /// and returned as an error.
1057 fn receive(&mut self) -> Result<Self::Frame> {
1058 match self.read_frame() {
1059 Ok(CanAnyFrame::Error(frame)) => Err(frame.into_error().into()),
1060 Ok(frame) => Ok(frame),
1061 Err(e) => Err(e.into()),
1062 }
1063 }
1064
1065 /// Blocking transmit of a frame to the bus.
1066 fn transmit(&mut self, frame: &Self::Frame) -> Result<()> {
1067 self.write_frame_insist(frame)?;
1068 Ok(())
1069 }
1070}
1071
1072impl embedded_can::nb::Can for CanFdSocket {
1073 type Frame = CanAnyFrame;
1074 type Error = Error;
1075
1076 /// Non-blocking call to receive the next frame from the bus.
1077 ///
1078 /// If an error frame is received, it will be converted to a `CanError`
1079 /// and returned as an error.
1080 /// If no frame is available, it returns a `WouldBlck` error.
1081 fn receive(&mut self) -> nb::Result<Self::Frame, Self::Error> {
1082 match self.read_frame() {
1083 Ok(CanAnyFrame::Error(frame)) => Err(Error::from(frame.into_error()).into()),
1084 Ok(frame) => Ok(frame),
1085 Err(err) if err.should_retry() => Err(nb::Error::WouldBlock),
1086 Err(err) => Err(Error::from(err).into()),
1087 }
1088 }
1089
1090 /// Non-blocking transmit of a frame to the bus.
1091 fn transmit(&mut self, frame: &Self::Frame) -> nb::Result<Option<Self::Frame>, Self::Error> {
1092 match self.write_frame(frame) {
1093 Ok(_) => Ok(None),
1094 Err(err) if err.should_retry() => Err(nb::Error::WouldBlock),
1095 Err(err) => Err(Error::from(err).into()),
1096 }
1097 }
1098}
1099
1100// Has no effect: #[deprecated(since = "3.1", note = "Use AsFd::as_fd() instead.")]
1101impl AsRawFd for CanFdSocket {
1102 fn as_raw_fd(&self) -> RawFd {
1103 self.0.as_raw_fd()
1104 }
1105}
1106
1107impl From<OwnedFd> for CanFdSocket {
1108 fn from(fd: OwnedFd) -> CanFdSocket {
1109 Self(socket2::Socket::from(fd))
1110 }
1111}
1112
1113impl TryFrom<CanSocket> for CanFdSocket {
1114 type Error = IoError;
1115
1116 fn try_from(sock: CanSocket) -> std::result::Result<Self, Self::Error> {
1117 let CanSocket(sock2) = sock;
1118 let sock = CanFdSocket::set_fd_mode(sock2, true)?;
1119 Ok(CanFdSocket(sock))
1120 }
1121}
1122
1123impl IntoRawFd for CanFdSocket {
1124 fn into_raw_fd(self) -> RawFd {
1125 self.0.into_raw_fd()
1126 }
1127}
1128
1129impl AsFd for CanFdSocket {
1130 fn as_fd(&self) -> BorrowedFd<'_> {
1131 self.0.as_fd()
1132 }
1133}
1134
1135impl Read for CanFdSocket {
1136 fn read(&mut self, buf: &mut [u8]) -> IoResult<usize> {
1137 self.0.read(buf)
1138 }
1139}
1140
1141impl Write for CanFdSocket {
1142 fn write(&mut self, buf: &[u8]) -> IoResult<usize> {
1143 self.0.write(buf)
1144 }
1145
1146 fn flush(&mut self) -> IoResult<()> {
1147 self.0.flush()
1148 }
1149}
1150
1151// ===== CanFilter =====
1152
1153/// The CAN filter defines which ID's can be accepted on a socket.
1154///
1155/// Each filter contains an internal id and mask. Packets are considered to
1156/// be matched by a filter if `received_id & mask == filter_id & mask` holds
1157/// true.
1158///
1159/// A socket can be given multiple filters, and each one can be inverted
1160/// ([ref](https://docs.kernel.org/networking/can.html#raw-protocol-sockets-with-can-filters-sock-raw))
1161#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
1162pub struct CanFilter(libc::can_filter);
1163
1164impl CanFilter {
1165 /// Construct a new CAN filter.
1166 pub fn new(id: canid_t, mask: canid_t) -> Self {
1167 Self(libc::can_filter {
1168 can_id: id,
1169 can_mask: mask,
1170 })
1171 }
1172
1173 /// Construct a new inverted CAN filter.
1174 pub fn new_inverted(id: canid_t, mask: canid_t) -> Self {
1175 Self::new(id | libc::CAN_INV_FILTER, mask)
1176 }
1177}
1178
1179impl From<libc::can_filter> for CanFilter {
1180 fn from(filt: libc::can_filter) -> Self {
1181 Self(filt)
1182 }
1183}
1184
1185impl From<(u32, u32)> for CanFilter {
1186 fn from(filt: (u32, u32)) -> Self {
1187 CanFilter::new(filt.0, filt.1)
1188 }
1189}
1190
1191impl AsRef<libc::can_filter> for CanFilter {
1192 fn as_ref(&self) -> &libc::can_filter {
1193 &self.0
1194 }
1195}