host_can/adapter/socketcan/
mod.rs

1//! SocketCAN adapter
2use crate::adapter::{Adapter, AdapterBaud, AdapterError};
3use crate::frame::{CanFrame, Frame};
4
5use core::cell::RefCell;
6use std::os::fd::AsRawFd;
7use std::os::unix::io::BorrowedFd;
8use std::result::Result;
9use std::time::Duration;
10
11use nix::poll::{PollFd, PollFlags, PollTimeout, poll};
12use socketcan::{
13    BlockingCan, CanFrame as SocketCanFrame, CanInterface, CanSocket, Socket,
14};
15
16pub struct SocketCanAdapter {
17    rx: RefCell<CanSocket>,
18    tx: RefCell<CanSocket>,
19}
20
21impl SocketCanAdapter {
22    pub fn new(
23        ifname: &str,
24        baud: AdapterBaud,
25    ) -> Result<Self, Box<dyn std::error::Error>> {
26        let iface = CanInterface::open(ifname)?;
27        if let Some(bit_rate) = iface.bit_rate()?
28            && bit_rate as AdapterBaud != baud
29        {
30            return Err(Box::new(AdapterError::UnsupportedBaud));
31        }
32
33        Ok(Self {
34            rx: RefCell::new(CanSocket::open(ifname)?),
35            tx: RefCell::new(CanSocket::open(ifname)?),
36        })
37    }
38}
39
40impl Adapter for SocketCanAdapter {
41    fn send(&self, frame: &CanFrame) -> Result<(), Box<AdapterError>> {
42        let frame = SocketCanFrame::new(frame.id(), frame.data())
43            .ok_or(AdapterError::WriteFailed)?;
44
45        self.tx
46            .borrow_mut()
47            .transmit(&frame)
48            .or(Err(AdapterError::WriteFailed))?;
49
50        Ok(())
51    }
52
53    fn recv(
54        &self,
55        timeout: Option<Duration>,
56    ) -> Result<CanFrame, Box<AdapterError>> {
57        if let Some(timeout) = timeout {
58            let fd = unsafe {
59                let socket = self.rx.borrow();
60                BorrowedFd::borrow_raw(socket.as_raw_fd())
61            };
62            let pollfd = PollFd::new(fd, PollFlags::POLLIN);
63
64            let poll_timeout = timeout.try_into().unwrap_or(PollTimeout::MAX);
65
66            match poll(&mut [pollfd], poll_timeout) {
67                Ok(1) => {}
68                Ok(0) => {
69                    return Err(Box::new(AdapterError::ReadTimeout));
70                }
71                _ => return Err(Box::new(AdapterError::ReadFailed)),
72            }
73        }
74
75        match self.rx.borrow_mut().receive() {
76            Ok(frame) => {
77                let frame = CanFrame::new(frame.id(), frame.data())
78                    .ok_or(Box::new(AdapterError::ReadFailed))?;
79                Ok(frame)
80            }
81            _ => Err(Box::new(AdapterError::ReadFailed)),
82        }
83    }
84}