uds_rs/uds/
communication.rs

1//!
2//! Backend layer for the uds-rs library.
3//!
4//! Currently built using tokio_socketcan_isotp library, the process should be similar for
5//! different network protocols and even runtimes, but it is currently tested only on tokio_socketcan_isotp and you knowledge may vary.
6//!
7//! To provide your own backend communication just rewrite the read, write and socket creation process to use your own API, and you should be good to go.
8//!
9
10pub use tokio_socketcan_isotp::{
11    Error, ExtendedId, FlowControlOptions, Id, IsoTpBehaviour, IsoTpOptions, LinkLayerOptions,
12    StandardId, TxFlags,
13};
14
15#[allow(dead_code)]
16#[derive(Debug, PartialEq)]
17pub enum UdsCommunicationError {
18    FailedToFindCanDevice,
19    SocketCanIOError,
20    StdIOError,
21    GeneralError,
22    NotImplementedError,
23    SocketCreationError,
24}
25
26impl From<Error> for UdsCommunicationError {
27    fn from(err: Error) -> Self {
28        match err {
29            Error::Io { .. } => UdsCommunicationError::SocketCanIOError,
30            Error::Lookup { .. } => UdsCommunicationError::FailedToFindCanDevice,
31        }
32    }
33}
34
35impl From<std::io::Error> for UdsCommunicationError {
36    fn from(_err: std::io::Error) -> Self {
37        UdsCommunicationError::StdIOError
38    }
39}
40
41pub struct UdsSocket {
42    isotp_socket: tokio_socketcan_isotp::IsoTpSocket,
43}
44
45impl UdsSocket {
46    pub fn new(
47        ifname: &str,
48        src: impl Into<Id>,
49        dst: impl Into<Id>,
50    ) -> Result<UdsSocket, UdsCommunicationError> {
51        Ok(UdsSocket {
52            isotp_socket: tokio_socketcan_isotp::IsoTpSocket::open(ifname, src, dst)?,
53        })
54    }
55    pub fn new_with_opts(
56        ifname: &str,
57        src: impl Into<Id>,
58        dst: impl Into<Id>,
59        isotp_options: Option<IsoTpOptions>,
60        rx_flow_control_options: Option<FlowControlOptions>,
61        link_layer_options: Option<LinkLayerOptions>,
62    ) -> Result<UdsSocket, UdsCommunicationError> {
63        Ok(UdsSocket {
64            isotp_socket: tokio_socketcan_isotp::IsoTpSocket::open_with_opts(
65                ifname,
66                src,
67                dst,
68                isotp_options,
69                rx_flow_control_options,
70                link_layer_options,
71            )?,
72        })
73    }
74
75    pub async fn send(&self, payload: &[u8]) -> Result<(), UdsCommunicationError> {
76        Ok(self.isotp_socket.write_packet(payload)?.await?)
77    }
78    pub async fn receive(&self) -> Result<Vec<u8>, UdsCommunicationError> {
79        Ok(self.isotp_socket.read_packet()?.await?)
80    }
81}