uds_client/socket_can/
mod.rs1#[cfg(target_os = "windows")]
2use embedded_can::ExtendedId;
3use embedded_can::{Frame, nb::Can};
4use embedded_io_async::ErrorType;
5#[cfg(target_os = "windows")]
6use peak_can::{
7 bus::UsbBus,
8 df::ReceiveStatus,
9 error::CanError,
10 socket::usb::UsbCanSocket,
11 socket::{Baudrate, RecvCan, SendCan},
12 socket::{CanFrame, MessageType},
13};
14#[cfg(target_os = "linux")]
15use socketcan::{CanFrame, CanSocket, Socket};
16use std::{
17 sync::{Arc, Mutex},
18 time::Duration,
19};
20
21#[cfg(target_os = "windows")]
22#[derive(Default)]
23pub struct WrappedCanFrame(pub CanFrame);
24#[cfg(target_os = "windows")]
25#[derive(Debug)]
26pub struct WrappedPcanError(pub CanError);
27
28pub trait CanSocketTx {
29 type Frame: Frame;
31
32 type Error: embedded_can::Error;
34
35 fn transmit(&mut self, frame: &Self::Frame) -> nb::Result<Option<Self::Frame>, Self::Error>;
37}
38
39#[allow(dead_code)]
40pub trait CanSocketRx {
41 type Frame: Frame;
43
44 type Error: embedded_can::Error;
46
47 fn receive(&mut self) -> nb::Result<Self::Frame, Self::Error>;
49}
50
51pub struct UdsSocket {
52 #[cfg(target_os = "linux")]
53 can_socket: CanSocket,
54 #[cfg(target_os = "windows")]
55 can_socket: UsbCanSocket,
56}
57
58pub struct UdsSocketTx {
59 #[cfg(target_os = "linux")]
60 tx: Arc<Mutex<CanSocket>>,
61 #[cfg(target_os = "windows")]
62 tx: Arc<Mutex<UsbCanSocket>>,
63}
64
65pub struct UdsSocketRx {
66 #[cfg(target_os = "linux")]
67 rx: Arc<Mutex<CanSocket>>,
68 #[cfg(target_os = "windows")]
69 rx: Arc<Mutex<UsbCanSocket>>,
70}
71
72impl UdsSocket {
73 #[cfg(target_os = "linux")]
74 pub fn new(socket: &str) -> Self {
75 use socketcan::{CanFilter, SocketOptions};
76
77 let can_socket = CanSocket::open(socket).unwrap();
78 let filter = CanFilter::new(0x7F0, 0x1FFFFFFF);
79 let _ = can_socket.set_filters(&[filter]);
80 Self { can_socket }
81 }
82
83 #[cfg(target_os = "windows")]
84 pub fn new() -> Self {
85 let can_socket = match UsbCanSocket::open(UsbBus::USB1, Baudrate::Baud500K) {
86 Ok(socket) => socket,
87 Err(e) => {
88 log::warn!("The PCAN initialize failed {:?}, just open", e);
89 UsbCanSocket::open_with_usb_bus(UsbBus::USB1)
90 }
91 };
92 Self { can_socket }
93 }
94
95 pub fn split(self) -> (UdsSocketTx, UdsSocketRx) {
96 let shared_socket = Arc::new(Mutex::new(self.can_socket));
97 let rx_socket = UdsSocketRx {
98 rx: shared_socket.clone(),
99 };
100 let tx_socket = UdsSocketTx {
101 tx: shared_socket.clone(),
102 };
103 (tx_socket, rx_socket)
104 }
105}
106
107impl ErrorType for UdsSocket {
109 type Error = embedded_io_async::ErrorKind;
110}
111
112#[cfg(target_os = "linux")]
113impl Can for UdsSocket {
114 type Frame = CanFrame;
115
116 type Error = socketcan::Error;
117
118 fn transmit(&mut self, frame: &Self::Frame) -> nb::Result<Option<Self::Frame>, Self::Error> {
119 self.can_socket.transmit(frame)
120 }
121
122 fn receive(&mut self) -> nb::Result<Self::Frame, Self::Error> {
123 self.can_socket.receive()
124 }
125}
126
127#[cfg(target_os = "linux")]
128impl CanSocketTx for UdsSocketTx {
129 type Frame = CanFrame;
130 type Error = socketcan::Error;
131
132 fn transmit(&mut self, frame: &Self::Frame) -> nb::Result<Option<Self::Frame>, Self::Error> {
133 self.tx.lock().unwrap().transmit(frame)
134 }
135}
136
137#[cfg(target_os = "linux")]
138impl CanSocketRx for UdsSocketRx {
139 type Frame = CanFrame;
140 type Error = socketcan::Error;
141
142 fn receive(&mut self) -> nb::Result<CanFrame, socketcan::Error> {
143 self.rx.lock().unwrap().receive()
144 }
145}
146
147#[cfg(target_os = "linux")]
148impl UdsSocketRx {
149 pub fn receive_with_timeout(&mut self, timeout: Duration) -> socketcan::IoResult<CanFrame> {
150 self.rx.lock().unwrap().read_frame_timeout(timeout)
151 }
152}
153
154#[cfg(target_os = "windows")]
155impl embedded_can::Error for WrappedPcanError {
156 fn kind(&self) -> embedded_can::ErrorKind {
157 match self.0 {
158 CanError::Overrun => embedded_can::ErrorKind::Overrun,
159 _ => embedded_can::ErrorKind::Other,
160 }
161 }
162}
163
164#[cfg(target_os = "windows")]
165impl embedded_can::Frame for WrappedCanFrame {
166 fn new(id: impl Into<embedded_can::Id>, data: &[u8]) -> Option<Self> {
167 let can_id: embedded_can::Id = id.into();
168 let raw_id = match can_id {
169 embedded_can::Id::Standard(standard_id) => standard_id.as_raw() as u32,
170 embedded_can::Id::Extended(extended_id) => extended_id.as_raw(),
171 };
172 match CanFrame::new(raw_id, MessageType::Extended, data) {
173 Ok(frame) => Some(WrappedCanFrame(frame)),
174 Err(_) => None,
175 }
176 }
177
178 fn id(&self) -> embedded_can::Id {
179 embedded_can::Id::Extended(ExtendedId::new(self.0.can_id()).unwrap())
180 }
181
182 fn data(&self) -> &[u8] {
183 self.0.data()
184 }
185
186 fn new_remote(id: impl Into<embedded_can::Id>, dlc: usize) -> Option<Self> {
187 let _ = dlc;
188 let _ = id;
189 todo!()
190 }
191
192 fn is_extended(&self) -> bool {
193 self.0.is_extended_frame()
194 }
195
196 fn is_remote_frame(&self) -> bool {
197 todo!()
198 }
199
200 fn dlc(&self) -> usize {
201 self.0.dlc() as usize
202 }
203
204 fn is_standard(&self) -> bool {
205 !self.0.is_extended_frame()
206 }
207
208 fn is_data_frame(&self) -> bool {
209 todo!()
210 }
211}
212
213#[cfg(target_os = "windows")]
214impl Can for UdsSocket {
215 type Frame = WrappedCanFrame;
216
217 type Error = WrappedPcanError;
218
219 fn transmit(&mut self, frame: &Self::Frame) -> nb::Result<Option<Self::Frame>, Self::Error> {
220 match self.can_socket.send(frame.0) {
221 Ok(_) => Ok(Some(Self::Frame::default())),
222 Err(e) => Err(nb::Error::Other(WrappedPcanError(e))),
223 }
224 }
225
226 fn receive(&mut self) -> nb::Result<Self::Frame, Self::Error> {
227 match self.can_socket.recv() {
228 Ok(f) => Ok(WrappedCanFrame(f.0)),
229 Err(e) => Err(nb::Error::Other(WrappedPcanError(e))),
230 }
231 }
232}
233
234#[cfg(target_os = "windows")]
235impl CanSocketTx for UdsSocketTx {
236 type Frame = WrappedCanFrame;
237
238 type Error = WrappedPcanError;
239
240 fn transmit(&mut self, frame: &Self::Frame) -> nb::Result<Option<Self::Frame>, Self::Error> {
241 match self.tx.lock().unwrap().send(frame.0) {
242 Ok(_) => Ok(Some(Self::Frame::default())),
243 Err(e) => Err(nb::Error::Other(WrappedPcanError(e))),
244 }
245 }
246}
247
248#[cfg(target_os = "windows")]
249impl CanSocketRx for UdsSocketRx {
250 type Frame = WrappedCanFrame;
251
252 type Error = WrappedPcanError;
253
254 fn receive(&mut self) -> nb::Result<Self::Frame, Self::Error> {
255 match self.rx.lock().unwrap().recv() {
256 Ok(f) => Ok(WrappedCanFrame(f.0)),
257 Err(e) => Err(nb::Error::Other(WrappedPcanError(e))),
258 }
259 }
260}
261
262#[cfg(target_os = "windows")]
263impl UdsSocketRx {
264 pub fn receive_with_timeout(&mut self, timeout: Duration) -> Result<CanFrame, CanError> {
265 let start = chrono::Local::now();
266 while !self.rx.lock().unwrap().is_receiving()? {
267 if chrono::Local::now() > start + timeout {
268 return Err(CanError::Unknown);
269 }
270 }
271
272 self.rx.lock().unwrap().recv_frame()
273 }
274}