1#[cfg(feature = "tokio")]
7use can_isotp_interface::{IsoTpAsyncEndpoint, IsoTpAsyncEndpointRecvInto, RecvMetaIntoStatus};
8use can_isotp_interface::{
9 IsoTpEndpoint, IsoTpRxFlowControlConfig, RecvControl, RecvError, RecvMeta, RecvStatus,
10 RxFlowControl, SendError,
11};
12use core::time::Duration;
13use embedded_can::Id;
14
15#[derive(Debug, Clone, Copy, PartialEq, Eq)]
17pub struct Error;
18
19impl core::fmt::Display for Error {
20 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
21 write!(
22 f,
23 "linux-socketcan-iso-tp is only supported on Linux targets"
24 )
25 }
26}
27
28impl std::error::Error for Error {}
29
30#[derive(Debug, Clone, Default)]
32pub struct IsoTpSocketOptions {
33 pub flags: u32,
34 pub frame_txtime: Option<Duration>,
35 pub ext_address: Option<u8>,
36 pub tx_padding: Option<u8>,
37 pub rx_padding: Option<u8>,
38 pub rx_ext_address: Option<u8>,
39}
40
41#[derive(Debug, Clone, Copy)]
43pub struct IsoTpFlowControlOptions {
44 pub block_size: u8,
45 pub st_min: u8,
46 pub wft_max: u8,
47}
48
49impl IsoTpFlowControlOptions {
50 pub fn new(block_size: u8, st_min: u8, wft_max: u8) -> Self {
51 Self {
52 block_size,
53 st_min,
54 wft_max,
55 }
56 }
57}
58
59#[derive(Debug, Clone, Copy)]
61pub struct IsoTpLinkLayerOptions {
62 pub mtu: u8,
63 pub tx_dl: u8,
64 pub tx_flags: u8,
65}
66
67impl IsoTpLinkLayerOptions {
68 pub fn new(mtu: u8, tx_dl: u8, tx_flags: u8) -> Self {
69 Self {
70 mtu,
71 tx_dl,
72 tx_flags,
73 }
74 }
75}
76
77#[derive(Debug, Clone)]
79pub struct IsoTpKernelOptions {
80 pub max_rx_payload: usize,
81 pub socket: IsoTpSocketOptions,
82 pub flow_control: Option<IsoTpFlowControlOptions>,
83 pub link_layer: Option<IsoTpLinkLayerOptions>,
84 pub force_tx_stmin: Option<Duration>,
85 pub force_rx_stmin: Option<Duration>,
86}
87
88impl Default for IsoTpKernelOptions {
89 fn default() -> Self {
90 Self {
91 max_rx_payload: 4095,
92 socket: IsoTpSocketOptions::default(),
93 flow_control: None,
94 link_layer: None,
95 force_tx_stmin: None,
96 force_rx_stmin: None,
97 }
98 }
99}
100
101#[derive(Debug)]
103pub struct SocketCanIsoTp;
104
105impl SocketCanIsoTp {
106 pub fn open(
107 _iface: &str,
108 _rx_id: Id,
109 _tx_id: Id,
110 _options: &IsoTpKernelOptions,
111 ) -> Result<Self, Error> {
112 Err(Error)
113 }
114}
115
116impl IsoTpEndpoint for SocketCanIsoTp {
117 type Error = Error;
118
119 fn send_to(
120 &mut self,
121 _to: u8,
122 _payload: &[u8],
123 _timeout: Duration,
124 ) -> Result<(), SendError<Self::Error>> {
125 Err(SendError::Backend(Error))
126 }
127
128 fn send_functional_to(
129 &mut self,
130 _functional_to: u8,
131 _payload: &[u8],
132 _timeout: Duration,
133 ) -> Result<(), SendError<Self::Error>> {
134 Err(SendError::Backend(Error))
135 }
136
137 fn recv_one<Cb>(
138 &mut self,
139 _timeout: Duration,
140 _on_payload: Cb,
141 ) -> Result<RecvStatus, RecvError<Self::Error>>
142 where
143 Cb: FnMut(RecvMeta, &[u8]) -> Result<RecvControl, Self::Error>,
144 {
145 Err(RecvError::Backend(Error))
146 }
147}
148
149impl IsoTpRxFlowControlConfig for SocketCanIsoTp {
150 type Error = Error;
151
152 fn set_rx_flow_control(&mut self, _fc: RxFlowControl) -> Result<(), Self::Error> {
153 Err(Error)
154 }
155}
156
157#[cfg(feature = "tokio")]
159#[derive(Debug)]
160pub struct TokioSocketCanIsoTp;
161
162#[cfg(feature = "tokio")]
163impl TokioSocketCanIsoTp {
164 pub fn open(
165 _iface: &str,
166 _rx_id: Id,
167 _tx_id: Id,
168 _options: &IsoTpKernelOptions,
169 ) -> Result<Self, Error> {
170 Err(Error)
171 }
172}
173
174#[cfg(feature = "tokio")]
175impl IsoTpAsyncEndpoint for TokioSocketCanIsoTp {
176 type Error = Error;
177
178 async fn send_to(
179 &mut self,
180 _to: u8,
181 _payload: &[u8],
182 _timeout: Duration,
183 ) -> Result<(), SendError<Self::Error>> {
184 Err(SendError::Backend(Error))
185 }
186
187 async fn send_functional_to(
188 &mut self,
189 _functional_to: u8,
190 _payload: &[u8],
191 _timeout: Duration,
192 ) -> Result<(), SendError<Self::Error>> {
193 Err(SendError::Backend(Error))
194 }
195
196 async fn recv_one<Cb>(
197 &mut self,
198 _timeout: Duration,
199 _on_payload: Cb,
200 ) -> Result<RecvStatus, RecvError<Self::Error>>
201 where
202 Cb: FnMut(RecvMeta, &[u8]) -> Result<RecvControl, Self::Error>,
203 {
204 Err(RecvError::Backend(Error))
205 }
206}
207
208#[cfg(feature = "tokio")]
209impl IsoTpAsyncEndpointRecvInto for TokioSocketCanIsoTp {
210 type Error = Error;
211
212 async fn recv_one_into(
213 &mut self,
214 _timeout: Duration,
215 _out: &mut [u8],
216 ) -> Result<RecvMetaIntoStatus, RecvError<Self::Error>> {
217 Err(RecvError::Backend(Error))
218 }
219}
220
221#[cfg(feature = "tokio")]
222impl IsoTpRxFlowControlConfig for TokioSocketCanIsoTp {
223 type Error = Error;
224
225 fn set_rx_flow_control(&mut self, _fc: RxFlowControl) -> Result<(), Self::Error> {
226 Err(Error)
227 }
228}
229
230#[derive(Debug)]
232pub struct KernelUdsDemux {
233 local_addr: u8,
234 _options: IsoTpKernelOptions,
235}
236
237impl KernelUdsDemux {
238 pub fn new(_iface: impl Into<String>, local_addr: u8, options: IsoTpKernelOptions) -> Self {
239 Self {
240 local_addr,
241 _options: options,
242 }
243 }
244
245 pub fn local_addr(&self) -> u8 {
246 self.local_addr
247 }
248
249 pub fn register_peer(&mut self, _peer: u8) -> Result<(), Error> {
250 Err(Error)
251 }
252}
253
254impl IsoTpEndpoint for KernelUdsDemux {
255 type Error = Error;
256
257 fn send_to(
258 &mut self,
259 _to: u8,
260 _payload: &[u8],
261 _timeout: Duration,
262 ) -> Result<(), SendError<Self::Error>> {
263 Err(SendError::Backend(Error))
264 }
265
266 fn send_functional_to(
267 &mut self,
268 _functional_to: u8,
269 _payload: &[u8],
270 _timeout: Duration,
271 ) -> Result<(), SendError<Self::Error>> {
272 Err(SendError::Backend(Error))
273 }
274
275 fn recv_one<Cb>(
276 &mut self,
277 _timeout: Duration,
278 _on_payload: Cb,
279 ) -> Result<RecvStatus, RecvError<Self::Error>>
280 where
281 Cb: FnMut(RecvMeta, &[u8]) -> Result<RecvControl, Self::Error>,
282 {
283 Err(RecvError::Backend(Error))
284 }
285}
286
287impl IsoTpRxFlowControlConfig for KernelUdsDemux {
288 type Error = Error;
289
290 fn set_rx_flow_control(&mut self, _fc: RxFlowControl) -> Result<(), Self::Error> {
291 Err(Error)
292 }
293}
294
295pub mod flags {
297 pub const CAN_ISOTP_LISTEN_MODE: u32 = 0x0001;
298 pub const CAN_ISOTP_EXTEND_ADDR: u32 = 0x0002;
299 pub const CAN_ISOTP_TX_PADDING: u32 = 0x0004;
300 pub const CAN_ISOTP_RX_PADDING: u32 = 0x0008;
301 pub const CAN_ISOTP_CHK_PAD_LEN: u32 = 0x0010;
302 pub const CAN_ISOTP_CHK_PAD_DATA: u32 = 0x0020;
303 pub const CAN_ISOTP_HALF_DUPLEX: u32 = 0x0040;
304 pub const CAN_ISOTP_FORCE_TXSTMIN: u32 = 0x0080;
305 pub const CAN_ISOTP_FORCE_RXSTMIN: u32 = 0x0100;
306 pub const CAN_ISOTP_RX_EXT_ADDR: u32 = 0x0200;
307 pub const CAN_ISOTP_WAIT_TX_DONE: u32 = 0x0400;
308 pub const CAN_ISOTP_SF_BROADCAST: u32 = 0x0800;
309 pub const CAN_ISOTP_CF_BROADCAST: u32 = 0x1000;
310 pub const CAN_ISOTP_DYN_FC_PARMS: u32 = 0x2000;
311}