can_socket/
socket.rs

1use crate::{CanFilter, CanFrame, CanInterface};
2
3/// A synchronous CAN socket.
4///
5/// Used to send and receive [`CanFrame`]'s over the network.
6///
7/// Although the socket is synchronous,
8/// it can be put into non-blocking mode with [`Self::set_nonblocking()`].
9#[repr(transparent)]
10pub struct CanSocket {
11	inner: crate::sys::Socket,
12}
13
14impl std::fmt::Debug for CanSocket {
15	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
16		let mut debug = f.debug_struct("CanSocket");
17		#[cfg(unix)]
18		{
19			use std::os::unix::io::AsRawFd;
20			debug.field("fd", &self.as_raw_fd());
21			debug.finish()
22		}
23
24		#[cfg(not(unix))]
25		debug.finish_non_exhaustive()
26	}
27}
28
29impl CanSocket {
30	/// Create a new socket bound to a named CAN interface.
31	pub fn bind(interface: impl AsRef<str>) -> std::io::Result<Self> {
32		let inner = crate::sys::Socket::new(false)?;
33		let interface = inner.get_interface_by_name(interface.as_ref())?;
34		inner.bind(&interface)?;
35		Ok(Self { inner })
36	}
37
38	/// Create a new socket bound to a interface by index.
39	pub fn bind_interface_index(index: u32) -> std::io::Result<Self> {
40		let inner = crate::sys::Socket::new(false)?;
41		inner.bind(&CanInterface::from_index(index).inner)?;
42		Ok(Self { inner })
43	}
44
45	/// Create a new socket bound to all CAN interfaces on the system.
46	///
47	/// You can use [`Self::recv_from()`] if you need to know on which interface a frame was received,
48	/// and [`Self::send_to()`] to send a frame on a particular interface.
49	pub fn bind_all() -> std::io::Result<Self> {
50		Self::bind_interface_index(0)
51	}
52
53	/// Get the interface this socket is bound to.
54	///
55	/// If the socket is bound to all interfaces, the returned `CanInterface` will report index 0.
56	pub fn local_addr(&self) -> std::io::Result<crate::CanInterface> {
57		Ok(CanInterface {
58			inner: self.inner.local_addr()?,
59		})
60	}
61
62	/// Set the socket in non-blocking or blocking mode.
63	///
64	/// If the socket is set in non-blocking mode, send and receive operations will never block.
65	/// Instead, if the operation can not be completed immediately, it will fail with a [`std::io::ErrorKind::WouldBlock`] error.
66	pub fn set_nonblocking(&self, non_blocking: bool) -> std::io::Result<()> {
67		self.inner.set_nonblocking(non_blocking)
68	}
69
70	/// Send a frame over the socket.
71	///
72	/// Note that if this function success, it only means that the kernel accepted the frame for transmission.
73	/// It does not mean the frame has been successfully transmitted over the CAN bus.
74	pub fn send(&self, frame: &CanFrame) -> std::io::Result<()> {
75		self.inner.send(&frame.inner)
76	}
77
78	/// Send a frame over a particular interface.
79	///
80	/// Note that if this function success, it only means that the kernel accepted the frame for transmission.
81	/// It does not mean the frame has been successfully transmitted over the CAN bus.
82	pub fn send_to(&self, frame: &CanFrame, interface: &CanInterface) -> std::io::Result<()> {
83		self.inner.send_to(&frame.inner, &interface.inner)
84	}
85
86	/// Receive a frame from the socket.
87	pub fn recv(&self) -> std::io::Result<CanFrame> {
88		Ok(CanFrame {
89			inner: self.inner.recv()?,
90		})
91	}
92
93	/// Receive a frame from the socket, including information about which interface the frame was received on.
94	pub fn recv_from(&self) -> std::io::Result<(CanFrame, CanInterface)> {
95		let (frame, interface) = self.inner.recv_from()?;
96		let frame = CanFrame { inner: frame };
97		let interface = CanInterface { inner: interface };
98		Ok((frame, interface))
99	}
100
101	/// Set the list of filters on the socket.
102	///
103	/// When a socket is created, it will receive all frames from the CAN interface.
104	/// You can restrict this by setting the filters with this function.
105	///
106	/// A frame has to match only one of the filters in the list to be received by the socket.
107	pub fn set_filters(&self, filters: &[CanFilter]) -> std::io::Result<()> {
108		self.inner.set_filters(filters)
109	}
110
111	/// Check if the loopback option of the socket is enabled.
112	///
113	/// When enabled (the default for new sockets),
114	/// frames sent on the same interface by other sockets are also received by this socket.
115	pub fn get_loopback(&self) -> std::io::Result<bool> {
116		self.inner.get_loopback()
117	}
118
119	/// Enable or disabling the loopback option of the socket.
120	///
121	/// When enabled (the default for new sockets),
122	/// frames sent on the same interface by other sockets are also received by this socket.
123	///
124	/// See `Self::set_receive_own_messages()` if you also want to receive messages sens on *this* socket.
125	pub fn set_loopback(&self, enable: bool) -> std::io::Result<()> {
126		self.inner.set_loopback(enable)
127	}
128
129	/// Check if the receive own messages option of the socket is enabled.
130	///
131	/// When this option is enabled, frames sent on this socket are also delivered to this socket.
132	///
133	/// Note that frames sent on this socket are subject to all the same filtering mechanisms as other frames.
134	/// To receive frames send on this socket, you must also to ensure that the loopback option is enabled ([`Self::get_loopback()`]),
135	/// and that the frame is not discarded by the filters ([`Self::set_filters()`]).
136	pub fn get_receive_own_messages(&self) -> std::io::Result<bool> {
137		self.inner.get_receive_own_messages()
138	}
139
140	/// Enable or disable the receive own messages option of the socket.
141	///
142	/// When this option is enabled, frames sent on this socket are also delivered to this socket.
143	///
144	/// Note that frames sent on this socket are subject to all the same filtering mechanisms as other frames.
145	/// To receive frames send on this socket, you must also to ensure that the loopback option is enabled ([`Self::set_loopback()`]),
146	/// and that the frame is not discarded by the filters ([`Self::set_filters()`]).
147	pub fn set_receive_own_messages(&self, enable: bool) -> std::io::Result<()> {
148		self.inner.set_receive_own_messages(enable)
149	}
150}
151
152impl std::os::fd::AsFd for CanSocket {
153	fn as_fd(&self) -> std::os::fd::BorrowedFd<'_> {
154		self.inner.as_fd()
155	}
156}
157
158impl From<CanSocket> for std::os::fd::OwnedFd {
159	fn from(value: CanSocket) -> Self {
160		value.inner.into()
161	}
162}
163
164impl From<std::os::fd::OwnedFd> for CanSocket {
165	fn from(value: std::os::fd::OwnedFd) -> Self {
166		Self {
167			inner: value.into(),
168		}
169	}
170}
171
172impl std::os::fd::AsRawFd for CanSocket {
173	fn as_raw_fd(&self) -> std::os::fd::RawFd {
174		self.inner.as_raw_fd()
175	}
176}
177
178impl std::os::fd::IntoRawFd for CanSocket {
179	fn into_raw_fd(self) -> std::os::fd::RawFd {
180		self.inner.into_raw_fd()
181	}
182}
183
184impl std::os::fd::FromRawFd for CanSocket {
185	unsafe fn from_raw_fd(fd: std::os::fd::RawFd) -> Self {
186		Self {
187			inner: crate::sys::Socket::from_raw_fd(fd)
188		}
189	}
190}