host_can/adapter/socketcan/
mod.rs

1//! SocketCAN adapter
2use crate::adapter::{Adapter, 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::{poll, PollFd, PollFlags, PollTimeout};
12use socketcan::{BlockingCan, CanFrame as SocketCanFrame, CanSocket, Socket};
13
14pub struct SocketCanAdapter {
15    socket: RefCell<CanSocket>,
16}
17
18impl SocketCanAdapter {
19    pub fn new(
20        ifname: impl Into<String>,
21    ) -> Result<Self, Box<dyn std::error::Error>> {
22        let socket = CanSocket::open(&ifname.into())?;
23
24        Ok(Self {
25            socket: RefCell::new(socket),
26        })
27    }
28}
29
30impl Adapter for SocketCanAdapter {
31    fn send(&self, frame: &CanFrame) -> Result<(), Box<AdapterError>> {
32        let frame = SocketCanFrame::new(frame.id(), frame.data())
33            .ok_or(AdapterError::WriteFailed)?;
34
35        self.socket
36            .borrow_mut()
37            .transmit(&frame)
38            .or(Err(AdapterError::WriteFailed))?;
39
40        Ok(())
41    }
42
43    fn recv(
44        &self,
45        timeout: Option<Duration>,
46    ) -> Result<CanFrame, Box<AdapterError>> {
47        if let Some(timeout) = timeout {
48            let fd = unsafe {
49                let socket = self.socket.borrow();
50                BorrowedFd::borrow_raw(socket.as_raw_fd())
51            };
52            let pollfd = PollFd::new(fd, PollFlags::POLLIN);
53
54            let poll_timeout = timeout.try_into().unwrap_or(PollTimeout::MAX);
55
56            match poll(&mut [pollfd], poll_timeout) {
57                Ok(1) => {}
58                Ok(0) => {
59                    return Err(Box::new(AdapterError::ReadTimeout));
60                }
61                _ => return Err(Box::new(AdapterError::ReadFailed)),
62            }
63        }
64
65        match self.socket.borrow_mut().receive() {
66            Ok(frame) => {
67                let frame = CanFrame::new(frame.id(), frame.data())
68                    .ok_or(Box::new(AdapterError::ReadFailed))?;
69                Ok(frame)
70            }
71            _ => Err(Box::new(AdapterError::ReadFailed)),
72        }
73    }
74}