host_can/adapter/socketcan/
mod.rs1use 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}