#[cfg(feature = "tokio")]
use can_isotp_interface::{IsoTpAsyncEndpoint, IsoTpAsyncEndpointRecvInto, RecvMetaIntoStatus};
use can_isotp_interface::{
IsoTpEndpoint, IsoTpRxFlowControlConfig, RecvControl, RecvError, RecvMeta, RecvStatus,
RxFlowControl, SendError,
};
use core::time::Duration;
use embedded_can::Id;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Error;
impl core::fmt::Display for Error {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(
f,
"linux-socketcan-iso-tp is only supported on Linux targets"
)
}
}
impl std::error::Error for Error {}
#[derive(Debug, Clone, Default)]
pub struct IsoTpSocketOptions {
pub flags: u32,
pub frame_txtime: Option<Duration>,
pub ext_address: Option<u8>,
pub tx_padding: Option<u8>,
pub rx_padding: Option<u8>,
pub rx_ext_address: Option<u8>,
}
#[derive(Debug, Clone, Copy)]
pub struct IsoTpFlowControlOptions {
pub block_size: u8,
pub st_min: u8,
pub wft_max: u8,
}
impl IsoTpFlowControlOptions {
pub fn new(block_size: u8, st_min: u8, wft_max: u8) -> Self {
Self {
block_size,
st_min,
wft_max,
}
}
}
#[derive(Debug, Clone, Copy)]
pub struct IsoTpLinkLayerOptions {
pub mtu: u8,
pub tx_dl: u8,
pub tx_flags: u8,
}
impl IsoTpLinkLayerOptions {
pub fn new(mtu: u8, tx_dl: u8, tx_flags: u8) -> Self {
Self {
mtu,
tx_dl,
tx_flags,
}
}
}
#[derive(Debug, Clone)]
pub struct IsoTpKernelOptions {
pub max_rx_payload: usize,
pub socket: IsoTpSocketOptions,
pub flow_control: Option<IsoTpFlowControlOptions>,
pub link_layer: Option<IsoTpLinkLayerOptions>,
pub force_tx_stmin: Option<Duration>,
pub force_rx_stmin: Option<Duration>,
}
impl Default for IsoTpKernelOptions {
fn default() -> Self {
Self {
max_rx_payload: 4095,
socket: IsoTpSocketOptions::default(),
flow_control: None,
link_layer: None,
force_tx_stmin: None,
force_rx_stmin: None,
}
}
}
#[derive(Debug)]
pub struct SocketCanIsoTp;
impl SocketCanIsoTp {
pub fn open(
_iface: &str,
_rx_id: Id,
_tx_id: Id,
_options: &IsoTpKernelOptions,
) -> Result<Self, Error> {
Err(Error)
}
}
impl IsoTpEndpoint for SocketCanIsoTp {
type Error = Error;
fn send_to(
&mut self,
_to: u8,
_payload: &[u8],
_timeout: Duration,
) -> Result<(), SendError<Self::Error>> {
Err(SendError::Backend(Error))
}
fn send_functional_to(
&mut self,
_functional_to: u8,
_payload: &[u8],
_timeout: Duration,
) -> Result<(), SendError<Self::Error>> {
Err(SendError::Backend(Error))
}
fn recv_one<Cb>(
&mut self,
_timeout: Duration,
_on_payload: Cb,
) -> Result<RecvStatus, RecvError<Self::Error>>
where
Cb: FnMut(RecvMeta, &[u8]) -> Result<RecvControl, Self::Error>,
{
Err(RecvError::Backend(Error))
}
}
impl IsoTpRxFlowControlConfig for SocketCanIsoTp {
type Error = Error;
fn set_rx_flow_control(&mut self, _fc: RxFlowControl) -> Result<(), Self::Error> {
Err(Error)
}
}
#[cfg(feature = "tokio")]
#[derive(Debug)]
pub struct TokioSocketCanIsoTp;
#[cfg(feature = "tokio")]
impl TokioSocketCanIsoTp {
pub fn open(
_iface: &str,
_rx_id: Id,
_tx_id: Id,
_options: &IsoTpKernelOptions,
) -> Result<Self, Error> {
Err(Error)
}
}
#[cfg(feature = "tokio")]
impl IsoTpAsyncEndpoint for TokioSocketCanIsoTp {
type Error = Error;
async fn send_to(
&mut self,
_to: u8,
_payload: &[u8],
_timeout: Duration,
) -> Result<(), SendError<Self::Error>> {
Err(SendError::Backend(Error))
}
async fn send_functional_to(
&mut self,
_functional_to: u8,
_payload: &[u8],
_timeout: Duration,
) -> Result<(), SendError<Self::Error>> {
Err(SendError::Backend(Error))
}
async fn recv_one<Cb>(
&mut self,
_timeout: Duration,
_on_payload: Cb,
) -> Result<RecvStatus, RecvError<Self::Error>>
where
Cb: FnMut(RecvMeta, &[u8]) -> Result<RecvControl, Self::Error>,
{
Err(RecvError::Backend(Error))
}
}
#[cfg(feature = "tokio")]
impl IsoTpAsyncEndpointRecvInto for TokioSocketCanIsoTp {
type Error = Error;
async fn recv_one_into(
&mut self,
_timeout: Duration,
_out: &mut [u8],
) -> Result<RecvMetaIntoStatus, RecvError<Self::Error>> {
Err(RecvError::Backend(Error))
}
}
#[cfg(feature = "tokio")]
impl IsoTpRxFlowControlConfig for TokioSocketCanIsoTp {
type Error = Error;
fn set_rx_flow_control(&mut self, _fc: RxFlowControl) -> Result<(), Self::Error> {
Err(Error)
}
}
#[derive(Debug)]
pub struct KernelUdsDemux {
local_addr: u8,
_options: IsoTpKernelOptions,
}
impl KernelUdsDemux {
pub fn new(_iface: impl Into<String>, local_addr: u8, options: IsoTpKernelOptions) -> Self {
Self {
local_addr,
_options: options,
}
}
pub fn local_addr(&self) -> u8 {
self.local_addr
}
pub fn register_peer(&mut self, _peer: u8) -> Result<(), Error> {
Err(Error)
}
}
impl IsoTpEndpoint for KernelUdsDemux {
type Error = Error;
fn send_to(
&mut self,
_to: u8,
_payload: &[u8],
_timeout: Duration,
) -> Result<(), SendError<Self::Error>> {
Err(SendError::Backend(Error))
}
fn send_functional_to(
&mut self,
_functional_to: u8,
_payload: &[u8],
_timeout: Duration,
) -> Result<(), SendError<Self::Error>> {
Err(SendError::Backend(Error))
}
fn recv_one<Cb>(
&mut self,
_timeout: Duration,
_on_payload: Cb,
) -> Result<RecvStatus, RecvError<Self::Error>>
where
Cb: FnMut(RecvMeta, &[u8]) -> Result<RecvControl, Self::Error>,
{
Err(RecvError::Backend(Error))
}
}
impl IsoTpRxFlowControlConfig for KernelUdsDemux {
type Error = Error;
fn set_rx_flow_control(&mut self, _fc: RxFlowControl) -> Result<(), Self::Error> {
Err(Error)
}
}
pub mod flags {
pub const CAN_ISOTP_LISTEN_MODE: u32 = 0x0001;
pub const CAN_ISOTP_EXTEND_ADDR: u32 = 0x0002;
pub const CAN_ISOTP_TX_PADDING: u32 = 0x0004;
pub const CAN_ISOTP_RX_PADDING: u32 = 0x0008;
pub const CAN_ISOTP_CHK_PAD_LEN: u32 = 0x0010;
pub const CAN_ISOTP_CHK_PAD_DATA: u32 = 0x0020;
pub const CAN_ISOTP_HALF_DUPLEX: u32 = 0x0040;
pub const CAN_ISOTP_FORCE_TXSTMIN: u32 = 0x0080;
pub const CAN_ISOTP_FORCE_RXSTMIN: u32 = 0x0100;
pub const CAN_ISOTP_RX_EXT_ADDR: u32 = 0x0200;
pub const CAN_ISOTP_WAIT_TX_DONE: u32 = 0x0400;
pub const CAN_ISOTP_SF_BROADCAST: u32 = 0x0800;
pub const CAN_ISOTP_CF_BROADCAST: u32 = 0x1000;
pub const CAN_ISOTP_DYN_FC_PARMS: u32 = 0x2000;
}