Thanks to visit codestin.com
Credit goes to docs.rs

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    CanAnyFrame, CanFdFrame, CanFrame, CanRawFrame, Error, IoError, IoErrorKind, IoResult, Result,
19};
20pub use embedded_can::{
21    self, blocking::Can as BlockingCan, nb::Can as NonBlockingCan, ExtendedId,
22    Frame as EmbeddedFrame, Id, StandardId,
23};
24use libc::{canid_t, socklen_t, AF_CAN, EINPROGRESS};
25use socket2::SockAddr;
26use std::{
27    fmt,
28    io::{Read, Write},
29    mem::{size_of, size_of_val},
30    os::{
31        raw::{c_int, c_void},
32        unix::io::{AsFd, AsRawFd, BorrowedFd, IntoRawFd, OwnedFd, RawFd},
33    },
34    ptr,
35    time::Duration,
36};
37
38pub use libc::{
39    CANFD_MTU, CAN_MTU, CAN_RAW, CAN_RAW_ERR_FILTER, CAN_RAW_FD_FRAMES, CAN_RAW_FILTER,
40    CAN_RAW_JOIN_FILTERS, CAN_RAW_LOOPBACK, CAN_RAW_RECV_OWN_MSGS, SOL_CAN_BASE, SOL_CAN_RAW,
41};
42
43// TODO: This can be removed on the next major version update
44pub use crate::CanAddr;
45
46/// Check an error return value for timeouts.
47///
48/// Due to the fact that timeouts are reported as errors, calling `read_frame`
49/// on a socket with a timeout that does not receive a frame in time will
50/// result in an error being returned. This trait adds a `should_retry` method
51/// to `Error` and `Result` to check for this condition.
52pub trait ShouldRetry {
53    /// Check for timeout
54    ///
55    /// If `true`, the error is probably due to a timeout.
56    fn should_retry(&self) -> bool;
57}
58
59impl ShouldRetry for IoError {
60    fn should_retry(&self) -> bool {
61        match self.kind() {
62            // EAGAIN, EINPROGRESS and EWOULDBLOCK are the three possible codes
63            // returned when a timeout occurs. the stdlib already maps EAGAIN
64            // and EWOULDBLOCK os WouldBlock
65            IoErrorKind::WouldBlock => true,
66            // however, EINPROGRESS is also valid
67            IoErrorKind::Other => {
68                matches!(self.raw_os_error(), Some(errno) if errno == EINPROGRESS)
69            }
70            _ => false,
71        }
72    }
73}
74
75impl<E: fmt::Debug> ShouldRetry for IoResult<E> {
76    fn should_retry(&self) -> bool {
77        match *self {
78            Err(ref e) => e.should_retry(),
79            _ => false,
80        }
81    }
82}
83
84// ===== Private local helper functions =====
85
86/// Tries to open the CAN socket by the interface number.
87fn raw_open_socket(addr: &CanAddr) -> IoResult<socket2::Socket> {
88    let af_can = socket2::Domain::from(AF_CAN);
89    let can_raw = socket2::Protocol::from(CAN_RAW);
90
91    let sock = socket2::Socket::new_raw(af_can, socket2::Type::RAW, Some(can_raw))?;
92    sock.bind(&SockAddr::from(*addr))?;
93    Ok(sock)
94}
95
96/// `setsockopt` wrapper
97///
98/// The libc `setsockopt` function is set to set various options on a socket.
99/// `set_socket_option` offers a somewhat type-safe wrapper that does not
100/// require messing around with `*const c_void`s.
101///
102/// A proper `std::io::Error` will be returned on failure.
103///
104/// Example use:
105///
106/// ```text
107/// let fd = ...;  // some file descriptor, this will be stdout
108/// set_socket_option(fd, SOL_TCP, TCP_NO_DELAY, 1 as c_int)
109/// ```
110///
111/// Note that the `val` parameter must be specified correctly; if an option
112/// expects an integer, it is advisable to pass in a `c_int`, not the default
113/// of `i32`.
114#[deprecated(since = "3.4.0", note = "Moved into `SocketOptions` trait")]
115#[inline]
116pub fn set_socket_option<T>(fd: c_int, level: c_int, name: c_int, val: &T) -> IoResult<()> {
117    let ret = unsafe {
118        libc::setsockopt(
119            fd,
120            level,
121            name,
122            val as *const _ as *const c_void,
123            size_of::<T>() as socklen_t,
124        )
125    };
126
127    match ret {
128        0 => Ok(()),
129        _ => Err(IoError::last_os_error()),
130    }
131}
132
133/// Sets a collection of multiple socket options with one call.
134#[deprecated(since = "3.4.0", note = "Moved into `SocketOptions` trait")]
135pub fn set_socket_option_mult<T>(
136    fd: c_int,
137    level: c_int,
138    name: c_int,
139    values: &[T],
140) -> IoResult<()> {
141    let ret = if values.is_empty() {
142        // can't pass in a ptr to a 0-len slice, pass a null ptr instead
143        unsafe { libc::setsockopt(fd, level, name, ptr::null(), 0) }
144    } else {
145        unsafe {
146            libc::setsockopt(
147                fd,
148                level,
149                name,
150                values.as_ptr().cast(),
151                size_of_val(values) as socklen_t,
152            )
153        }
154    };
155
156    match ret {
157        0 => Ok(()),
158        _ => Err(IoError::last_os_error()),
159    }
160}
161
162// ===== Common 'Socket' trait =====
163
164/// Common trait for SocketCAN sockets.
165///
166/// Note that a socket it created by opening it, and then closed by
167/// dropping it.
168pub trait Socket: AsRawFd {
169    /// Open a named CAN device.
170    ///
171    /// Usually the more common case, opens a socket can device by name, such
172    /// as "can0", "vcan0", or "socan0".
173    fn open(ifname: &str) -> IoResult<Self>
174    where
175        Self: Sized,
176    {
177        let addr = CanAddr::from_iface(ifname)?;
178        Self::open_addr(&addr)
179    }
180
181    /// Open CAN device by interface number.
182    ///
183    /// Opens a CAN device by kernel interface number.
184    fn open_iface(ifindex: u32) -> IoResult<Self>
185    where
186        Self: Sized,
187    {
188        let addr = CanAddr::new(ifindex);
189        Self::open_addr(&addr)
190    }
191
192    /// Open a CAN socket by address.
193    fn open_addr(addr: &CanAddr) -> IoResult<Self>
194    where
195        Self: Sized;
196
197    /// Gets a shared reference to the underlying socket object
198    fn as_raw_socket(&self) -> &socket2::Socket;
199
200    /// Gets a mutable reference to the underlying socket object
201    fn as_raw_socket_mut(&mut self) -> &mut socket2::Socket;
202
203    /// Determines if the socket is currently in nonblocking mode.
204    fn nonblocking(&self) -> IoResult<bool> {
205        self.as_raw_socket().nonblocking()
206    }
207
208    /// Change socket to non-blocking mode or back to blocking mode.
209    fn set_nonblocking(&self, nonblocking: bool) -> IoResult<()> {
210        self.as_raw_socket().set_nonblocking(nonblocking)
211    }
212
213    /// The type of CAN frame that can be read and written by the socket.
214    ///
215    /// This is typically distinguished by the size of the supported frame,
216    /// with the primary difference between a `CanFrame` and a `CanFdFrame`.
217    type FrameType;
218
219    /// Gets the read timeout on the socket, if any.
220    fn read_timeout(&self) -> IoResult<Option<Duration>> {
221        self.as_raw_socket().read_timeout()
222    }
223
224    /// Sets the read timeout on the socket
225    ///
226    /// For convenience, the result value can be checked using
227    /// `ShouldRetry::should_retry` when a timeout is set.
228    ///
229    /// If the duration is set to `None` then write calls will block
230    /// indefinitely.
231    fn set_read_timeout<D>(&self, duration: D) -> IoResult<()>
232    where
233        D: Into<Option<Duration>>,
234    {
235        self.as_raw_socket().set_read_timeout(duration.into())
236    }
237
238    /// Gets the write timeout on the socket, if any.
239    fn write_timeout(&self) -> IoResult<Option<Duration>> {
240        self.as_raw_socket().write_timeout()
241    }
242
243    /// Sets the write timeout on the socket
244    ///
245    /// If the duration is set to `None` then write calls will block
246    /// indefinitely.
247    fn set_write_timeout<D>(&self, duration: D) -> IoResult<()>
248    where
249        D: Into<Option<Duration>>,
250    {
251        self.as_raw_socket().set_write_timeout(duration.into())
252    }
253
254    /// Blocking read a single can frame.
255    fn read_frame(&self) -> IoResult<Self::FrameType>;
256
257    /// Blocking read a single can frame with timeout.
258    fn read_frame_timeout(&self, timeout: Duration) -> IoResult<Self::FrameType> {
259        use nix::poll::{poll, PollFd, PollFlags, PollTimeout};
260        let pollfd = PollFd::new(
261            unsafe { BorrowedFd::borrow_raw(self.as_raw_fd()) },
262            PollFlags::POLLIN,
263        );
264
265        match poll(
266            &mut [pollfd],
267            timeout.try_into().unwrap_or(PollTimeout::MAX),
268        )? {
269            0 => Err(IoErrorKind::TimedOut.into()),
270            _ => self.read_frame(),
271        }
272    }
273
274    //
275    // /// Write a single can frame.
276    // ///
277    // /// Note that this function can fail with an `EAGAIN` error or similar.
278    // /// Use `write_frame_insist` if you need to be sure that the message got
279    // /// sent or failed.
280    // fn write_frame(&self, frame: &Self::FrameType) -> IoResult<()>;
281
282    /// Writes a normal CAN 2.0 frame to the socket.
283    fn write_frame<F>(&self, frame: &F) -> IoResult<()>
284    where
285        F: Into<Self::FrameType> + AsPtr;
286
287    /// Blocking write a single can frame, retrying until it gets sent
288    /// successfully.
289    fn write_frame_insist<F>(&self, frame: &F) -> IoResult<()>
290    where
291        F: Into<Self::FrameType> + AsPtr,
292    {
293        loop {
294            match self.write_frame(frame) {
295                Ok(v) => return Ok(v),
296                Err(e) if e.should_retry() => (),
297                Err(e) => return Err(e),
298            }
299        }
300    }
301}
302
303/// Traits for setting CAN socket options.
304///
305/// These are blocking calls, even when implemented on asynchronous sockets.
306pub trait SocketOptions: AsRawFd {
307    /// Sets an option on the socket.
308    ///
309    /// The libc `setsockopt` function is set to set various options on a socket.
310    /// `set_socket_option` offers a somewhat type-safe wrapper that does not
311    /// require messing around with `*const c_void`s.
312    ///
313    /// A proper `std::io::Error` will be returned on failure.
314    ///
315    /// Example use:
316    ///
317    /// ```text
318    /// sock.set_socket_option(SOL_TCP, TCP_NO_DELAY, 1 as c_int)
319    /// ```
320    ///
321    /// Note that the `val` parameter must be specified correctly; if an option
322    /// expects an integer, it is advisable to pass in a `c_int`, not the default
323    /// of `i32`.
324    fn set_socket_option<T>(&self, level: c_int, name: c_int, val: &T) -> IoResult<()> {
325        let ret = unsafe {
326            libc::setsockopt(
327                self.as_raw_fd(),
328                level,
329                name,
330                val as *const _ as *const c_void,
331                size_of::<T>() as socklen_t,
332            )
333        };
334
335        match ret {
336            0 => Ok(()),
337            _ => Err(IoError::last_os_error()),
338        }
339    }
340
341    /// Sets a collection of multiple socke options with one call.
342    fn set_socket_option_mult<T>(&self, level: c_int, name: c_int, values: &[T]) -> IoResult<()> {
343        let ret = if values.is_empty() {
344            // can't pass in a ptr to a 0-len slice, pass a null ptr instead
345            unsafe { libc::setsockopt(self.as_raw_fd(), level, name, ptr::null(), 0) }
346        } else {
347            unsafe {
348                libc::setsockopt(
349                    self.as_raw_fd(),
350                    level,
351                    name,
352                    values.as_ptr().cast(),
353                    size_of_val(values) as socklen_t,
354                )
355            }
356        };
357
358        match ret {
359            0 => Ok(()),
360            _ => Err(IoError::last_os_error()),
361        }
362    }
363
364    /// Sets CAN ID filters on the socket.
365    ///
366    /// CAN packages received by SocketCAN are matched against these filters,
367    /// only matching packets are returned by the interface.
368    ///
369    /// See `CanFilter` for details on how filtering works. By default, all
370    /// single filter matching all incoming frames is installed.
371    fn set_filters<F>(&self, filters: &[F]) -> IoResult<()>
372    where
373        F: Into<CanFilter> + Copy,
374    {
375        let filters: Vec<CanFilter> = filters.iter().map(|f| (*f).into()).collect();
376        self.set_socket_option_mult(SOL_CAN_RAW, CAN_RAW_FILTER, &filters)
377    }
378
379    /// Disable reception of CAN frames.
380    ///
381    /// Sets a completely empty filter; disabling all CAN frame reception.
382    fn set_filter_drop_all(&self) -> IoResult<()> {
383        let filters: &[CanFilter] = &[];
384        self.set_socket_option_mult(SOL_CAN_RAW, CAN_RAW_FILTER, filters)
385    }
386
387    /// Accept all frames, disabling any kind of filtering.
388    ///
389    /// Replace the current filter with one containing a single rule that
390    /// acceps all CAN frames.
391    fn set_filter_accept_all(&self) -> IoResult<()> {
392        // safe unwrap: 0, 0 is a valid mask/id pair
393        self.set_filters(&[(0, 0)])
394    }
395
396    /// Sets the error mask on the socket.
397    ///
398    /// By default (`ERR_MASK_NONE`) no error conditions are reported as
399    /// special error frames by the socket. Enabling error conditions by
400    /// setting `ERR_MASK_ALL` or another non-empty error mask causes the
401    /// socket to receive notification about the specified conditions.
402    fn set_error_filter(&self, mask: u32) -> IoResult<()> {
403        self.set_socket_option(SOL_CAN_RAW, CAN_RAW_ERR_FILTER, &mask)
404    }
405
406    /// Sets the error mask on the socket to reject all errors.
407    #[inline(always)]
408    fn set_error_filter_drop_all(&self) -> IoResult<()> {
409        self.set_error_filter(0)
410    }
411
412    /// Sets the error mask on the socket to accept all errors.
413    #[inline(always)]
414    fn set_error_filter_accept_all(&self) -> IoResult<()> {
415        self.set_error_filter(CAN_ERR_MASK)
416    }
417
418    /// Sets the error mask on the socket.
419    ///
420    /// By default (`ERR_MASK_NONE`) no error conditions are reported as
421    /// special error frames by the socket. Enabling error conditions by
422    /// setting `ERR_MASK_ALL` or another non-empty error mask causes the
423    /// socket to receive notification about the specified conditions.
424    fn set_error_mask(&self, mask: u32) -> IoResult<()> {
425        self.set_socket_option(SOL_CAN_RAW, CAN_RAW_ERR_FILTER, &mask)
426    }
427
428    /// Enable or disable loopback.
429    ///
430    /// By default, loopback is enabled, causing other applications that open
431    /// the same CAN bus to see frames emitted by different applications on
432    /// the same system.
433    fn set_loopback(&self, enabled: bool) -> IoResult<()> {
434        let loopback = c_int::from(enabled);
435        self.set_socket_option(SOL_CAN_RAW, CAN_RAW_LOOPBACK, &loopback)
436    }
437
438    /// Enable or disable receiving of own frames.
439    ///
440    /// When loopback is enabled, this settings controls if CAN frames sent
441    /// are received back immediately by sender. Default is off.
442    fn set_recv_own_msgs(&self, enabled: bool) -> IoResult<()> {
443        let recv_own_msgs = c_int::from(enabled);
444        self.set_socket_option(SOL_CAN_RAW, CAN_RAW_RECV_OWN_MSGS, &recv_own_msgs)
445    }
446
447    /// Enable or disable join filters.
448    ///
449    /// By default a frame is accepted if it matches any of the filters set
450    /// with `set_filters`. If join filters is enabled, a frame has to match
451    /// _all_ filters to be accepted.
452    fn set_join_filters(&self, enabled: bool) -> IoResult<()> {
453        let join_filters = c_int::from(enabled);
454        self.set_socket_option(SOL_CAN_RAW, CAN_RAW_JOIN_FILTERS, &join_filters)
455    }
456}
457
458// TODO: We need to restore this, but preferably with TIMESTAMPING
459
460/*
461impl CanSocket {
462
463    /// Blocking read a single can frame with timestamp
464    ///
465    /// Note that reading a frame and retrieving the timestamp requires two
466    /// consecutive syscalls. To avoid race conditions, exclusive access
467    /// to the socket is enforce through requiring a `mut &self`.
468    pub fn read_frame_with_timestamp(&mut self) -> IoResult<(CanFrame, time::SystemTime)> {
469        let frame = self.read_frame()?;
470
471        let mut ts = timespec { tv_sec: 0, tv_nsec: 0 };
472        let ret = unsafe {
473            libc::ioctl(self.fd, SIOCGSTAMPNS as c_ulong, &mut ts as *mut timespec)
474        };
475
476        if ret == -1 {
477            return Err(IoError::last_os_error());
478        }
479
480        Ok((frame, system_time_from_timespec(ts)))
481    }
482
483}
484*/
485
486// ===== CanSocket =====
487
488/// A socket for classic CAN 2.0 devices.
489///
490/// This provides an interface to read and write classic CAN 2.0 frames to
491/// the bus, with up to 8 bytes of data per frame. It wraps a Linux socket
492/// descriptor to a Raw SocketCAN socket.
493///
494/// The socket is automatically closed when the object is dropped. To close
495/// manually, use std::drop::Drop. Internally this is just a wrapped socket
496/// (file) descriptor.
497#[allow(missing_copy_implementations)]
498#[derive(Debug)]
499pub struct CanSocket(socket2::Socket);
500
501impl CanSocket {
502    /// Reads a low-level libc `can_frame` from the socket.
503    pub fn read_raw_frame(&self) -> IoResult<libc::can_frame> {
504        let mut frame = can_frame_default();
505        self.as_raw_socket().read_exact(as_bytes_mut(&mut frame))?;
506        Ok(frame)
507    }
508}
509
510impl Socket for CanSocket {
511    /// CanSocket reads/writes classic CAN 2.0 frames.
512    type FrameType = CanFrame;
513
514    /// Opens the socket by interface index.
515    fn open_addr(addr: &CanAddr) -> IoResult<Self> {
516        let sock = raw_open_socket(addr)?;
517        Ok(Self(sock))
518    }
519
520    /// Gets a shared reference to the underlying socket object
521    fn as_raw_socket(&self) -> &socket2::Socket {
522        &self.0
523    }
524
525    /// Gets a mutable reference to the underlying socket object
526    fn as_raw_socket_mut(&mut self) -> &mut socket2::Socket {
527        &mut self.0
528    }
529
530    /// Writes a normal CAN 2.0 frame to the socket.
531    fn write_frame<F>(&self, frame: &F) -> IoResult<()>
532    where
533        F: Into<CanFrame> + AsPtr,
534    {
535        self.as_raw_socket().write_all(frame.as_bytes())
536    }
537
538    /// Reads a normal CAN 2.0 frame from the socket.
539    fn read_frame(&self) -> IoResult<CanFrame> {
540        let frame = self.read_raw_frame()?;
541        Ok(frame.into())
542    }
543}
544
545// ===== embedded_can I/O traits =====
546
547impl embedded_can::blocking::Can for CanSocket {
548    type Frame = CanFrame;
549    type Error = Error;
550
551    /// Blocking call to receive the next frame from the bus.
552    ///
553    /// This block and wait for the next frame to be received from the bus.
554    /// If an error frame is received, it will be converted to a `CanError`
555    /// and returned as an error.
556    fn receive(&mut self) -> Result<Self::Frame> {
557        match self.read_frame() {
558            Ok(CanFrame::Error(frame)) => Err(frame.into_error().into()),
559            Ok(frame) => Ok(frame),
560            Err(e) => Err(e.into()),
561        }
562    }
563
564    /// Blocking transmit of a frame to the bus.
565    fn transmit(&mut self, frame: &Self::Frame) -> Result<()> {
566        self.write_frame_insist(frame)?;
567        Ok(())
568    }
569}
570
571impl SocketOptions for CanSocket {}
572
573impl embedded_can::nb::Can for CanSocket {
574    type Frame = CanFrame;
575    type Error = Error;
576
577    /// Non-blocking call to receive the next frame from the bus.
578    ///
579    /// If an error frame is received, it will be converted to a `CanError`
580    /// and returned as an error.
581    /// If no frame is available, it returns a `WouldBlck` error.
582    fn receive(&mut self) -> nb::Result<Self::Frame, Self::Error> {
583        match self.read_frame() {
584            Ok(CanFrame::Error(frame)) => Err(Error::from(frame.into_error()).into()),
585            Ok(frame) => Ok(frame),
586            Err(err) if err.should_retry() => Err(nb::Error::WouldBlock),
587            Err(err) => Err(Error::from(err).into()),
588        }
589    }
590
591    /// Non-blocking transmit of a frame to the bus.
592    fn transmit(&mut self, frame: &Self::Frame) -> nb::Result<Option<Self::Frame>, Self::Error> {
593        match self.write_frame(frame) {
594            Ok(_) => Ok(None),
595            Err(err) if err.should_retry() => Err(nb::Error::WouldBlock),
596            Err(err) => Err(Error::from(err).into()),
597        }
598    }
599}
600
601// Has no effect: #[deprecated(since = "3.1", note = "Use AsFd::as_fd() instead.")]
602impl AsRawFd for CanSocket {
603    fn as_raw_fd(&self) -> RawFd {
604        self.0.as_raw_fd()
605    }
606}
607
608impl From<OwnedFd> for CanSocket {
609    fn from(fd: OwnedFd) -> Self {
610        Self(socket2::Socket::from(fd))
611    }
612}
613
614impl IntoRawFd for CanSocket {
615    fn into_raw_fd(self) -> RawFd {
616        self.0.into_raw_fd()
617    }
618}
619
620impl AsFd for CanSocket {
621    fn as_fd(&self) -> BorrowedFd<'_> {
622        self.0.as_fd()
623    }
624}
625
626impl Read for CanSocket {
627    fn read(&mut self, buf: &mut [u8]) -> IoResult<usize> {
628        self.0.read(buf)
629    }
630}
631
632impl Write for CanSocket {
633    fn write(&mut self, buf: &[u8]) -> IoResult<usize> {
634        self.0.write(buf)
635    }
636
637    fn flush(&mut self) -> IoResult<()> {
638        self.0.flush()
639    }
640}
641
642// ===== CanFdSocket =====
643
644/// A socket for CAN FD devices.
645///
646/// This can transmit and receive CAN 2.0 frames with up to 8-bytes of data,
647/// or CAN Flexible Data (FD) frames with up to 64-bytes of data.
648#[allow(missing_copy_implementations)]
649#[derive(Debug)]
650pub struct CanFdSocket(socket2::Socket);
651
652impl CanFdSocket {
653    // Enable or disable FD mode on a socket.
654    fn set_fd_mode(sock: socket2::Socket, enable: bool) -> IoResult<socket2::Socket> {
655        let enable = enable as c_int;
656
657        let ret = unsafe {
658            libc::setsockopt(
659                sock.as_raw_fd(),
660                SOL_CAN_RAW,
661                CAN_RAW_FD_FRAMES,
662                &enable as *const _ as *const c_void,
663                size_of::<c_int>() as u32,
664            )
665        };
666
667        match ret {
668            0 => Ok(sock),
669            _ => Err(IoError::last_os_error()),
670        }
671    }
672
673    /// Reads a raw CAN frame from the socket.
674    ///
675    /// This might be either type of CAN frame, a classic CAN 2.0 frame
676    /// or an FD frame.
677    pub fn read_raw_frame(&self) -> IoResult<CanRawFrame> {
678        let mut fdframe = canfd_frame_default();
679
680        match self.as_raw_socket().read(as_bytes_mut(&mut fdframe))? {
681            // If we only get 'can_frame' number of bytes, then the return is,
682            // by definition, a can_frame, so we just copy the bytes into the
683            // proper type.
684            CAN_MTU => {
685                let mut frame = can_frame_default();
686                as_bytes_mut(&mut frame)[..CAN_MTU].copy_from_slice(&as_bytes(&fdframe)[..CAN_MTU]);
687                Ok(frame.into())
688            }
689            CANFD_MTU => Ok(fdframe.into()),
690            _ => Err(IoError::last_os_error()),
691        }
692    }
693}
694
695impl Socket for CanFdSocket {
696    /// CanFdSocket can read/write classic CAN 2.0 or FD frames.
697    type FrameType = CanAnyFrame;
698
699    /// Opens the FD socket by interface index.
700    fn open_addr(addr: &CanAddr) -> IoResult<Self> {
701        raw_open_socket(addr)
702            .and_then(|sock| Self::set_fd_mode(sock, true))
703            .map(Self)
704    }
705
706    /// Gets a shared reference to the underlying socket object
707    fn as_raw_socket(&self) -> &socket2::Socket {
708        &self.0
709    }
710
711    /// Gets a mutable reference to the underlying socket object
712    fn as_raw_socket_mut(&mut self) -> &mut socket2::Socket {
713        &mut self.0
714    }
715
716    /// Writes any type of CAN frame to the socket.
717    fn write_frame<F>(&self, frame: &F) -> IoResult<()>
718    where
719        F: Into<Self::FrameType> + AsPtr,
720    {
721        self.as_raw_socket().write_all(frame.as_bytes())
722    }
723
724    /// Reads either type of CAN frame from the socket.
725    fn read_frame(&self) -> IoResult<CanAnyFrame> {
726        let mut fdframe = canfd_frame_default();
727
728        match self.as_raw_socket().read(as_bytes_mut(&mut fdframe))? {
729            // If we only get 'can_frame' number of bytes, then the return is,
730            // by definition, a can_frame, so we just copy the bytes into the
731            // proper type.
732            CAN_MTU => {
733                let mut frame = can_frame_default();
734                as_bytes_mut(&mut frame)[..CAN_MTU].copy_from_slice(&as_bytes(&fdframe)[..CAN_MTU]);
735                Ok(CanFrame::from(frame).into())
736            }
737            CANFD_MTU => Ok(CanFdFrame::from(fdframe).into()),
738            _ => Err(IoError::last_os_error()),
739        }
740    }
741}
742
743impl SocketOptions for CanFdSocket {}
744
745impl embedded_can::blocking::Can for CanFdSocket {
746    type Frame = CanAnyFrame;
747    type Error = Error;
748
749    /// Blocking call to receive the next frame from the bus.
750    ///
751    /// This block and wait for the next frame to be received from the bus.
752    /// If an error frame is received, it will be converted to a `CanError`
753    /// and returned as an error.
754    fn receive(&mut self) -> Result<Self::Frame> {
755        match self.read_frame() {
756            Ok(CanAnyFrame::Error(frame)) => Err(frame.into_error().into()),
757            Ok(frame) => Ok(frame),
758            Err(e) => Err(e.into()),
759        }
760    }
761
762    /// Blocking transmit of a frame to the bus.
763    fn transmit(&mut self, frame: &Self::Frame) -> Result<()> {
764        self.write_frame_insist(frame)?;
765        Ok(())
766    }
767}
768
769impl embedded_can::nb::Can for CanFdSocket {
770    type Frame = CanAnyFrame;
771    type Error = Error;
772
773    /// Non-blocking call to receive the next frame from the bus.
774    ///
775    /// If an error frame is received, it will be converted to a `CanError`
776    /// and returned as an error.
777    /// If no frame is available, it returns a `WouldBlck` error.
778    fn receive(&mut self) -> nb::Result<Self::Frame, Self::Error> {
779        match self.read_frame() {
780            Ok(CanAnyFrame::Error(frame)) => Err(Error::from(frame.into_error()).into()),
781            Ok(frame) => Ok(frame),
782            Err(err) if err.should_retry() => Err(nb::Error::WouldBlock),
783            Err(err) => Err(Error::from(err).into()),
784        }
785    }
786
787    /// Non-blocking transmit of a frame to the bus.
788    fn transmit(&mut self, frame: &Self::Frame) -> nb::Result<Option<Self::Frame>, Self::Error> {
789        match self.write_frame(frame) {
790            Ok(_) => Ok(None),
791            Err(err) if err.should_retry() => Err(nb::Error::WouldBlock),
792            Err(err) => Err(Error::from(err).into()),
793        }
794    }
795}
796
797// Has no effect: #[deprecated(since = "3.1", note = "Use AsFd::as_fd() instead.")]
798impl AsRawFd for CanFdSocket {
799    fn as_raw_fd(&self) -> RawFd {
800        self.0.as_raw_fd()
801    }
802}
803
804impl From<OwnedFd> for CanFdSocket {
805    fn from(fd: OwnedFd) -> CanFdSocket {
806        Self(socket2::Socket::from(fd))
807    }
808}
809
810impl TryFrom<CanSocket> for CanFdSocket {
811    type Error = IoError;
812
813    fn try_from(sock: CanSocket) -> std::result::Result<Self, Self::Error> {
814        let CanSocket(sock2) = sock;
815        let sock = CanFdSocket::set_fd_mode(sock2, true)?;
816        Ok(CanFdSocket(sock))
817    }
818}
819
820impl IntoRawFd for CanFdSocket {
821    fn into_raw_fd(self) -> RawFd {
822        self.0.into_raw_fd()
823    }
824}
825
826impl AsFd for CanFdSocket {
827    fn as_fd(&self) -> BorrowedFd<'_> {
828        self.0.as_fd()
829    }
830}
831
832impl Read for CanFdSocket {
833    fn read(&mut self, buf: &mut [u8]) -> IoResult<usize> {
834        self.0.read(buf)
835    }
836}
837
838impl Write for CanFdSocket {
839    fn write(&mut self, buf: &[u8]) -> IoResult<usize> {
840        self.0.write(buf)
841    }
842
843    fn flush(&mut self) -> IoResult<()> {
844        self.0.flush()
845    }
846}
847
848// ===== CanFilter =====
849
850/// The CAN filter defines which ID's can be accepted on a socket.
851///
852/// Each filter contains an internal id and mask. Packets are considered to
853/// be matched by a filter if `received_id & mask == filter_id & mask` holds
854/// true.
855///
856/// A socket can be given multiple filters, and each one can be inverted
857/// ([ref](https://docs.kernel.org/networking/can.html#raw-protocol-sockets-with-can-filters-sock-raw))
858#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
859pub struct CanFilter(libc::can_filter);
860
861impl CanFilter {
862    /// Construct a new CAN filter.
863    pub fn new(id: canid_t, mask: canid_t) -> Self {
864        Self(libc::can_filter {
865            can_id: id,
866            can_mask: mask,
867        })
868    }
869
870    /// Construct a new inverted CAN filter.
871    pub fn new_inverted(id: canid_t, mask: canid_t) -> Self {
872        Self::new(id | libc::CAN_INV_FILTER, mask)
873    }
874}
875
876impl From<libc::can_filter> for CanFilter {
877    fn from(filt: libc::can_filter) -> Self {
878        Self(filt)
879    }
880}
881
882impl From<(u32, u32)> for CanFilter {
883    fn from(filt: (u32, u32)) -> Self {
884        CanFilter::new(filt.0, filt.1)
885    }
886}
887
888impl AsRef<libc::can_filter> for CanFilter {
889    fn as_ref(&self) -> &libc::can_filter {
890        &self.0
891    }
892}