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}