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