pub struct IsoTpSocket { /* private fields */ }
Expand description

An ISO-TP socketcan socket.

Will be closed upon deallocation. To close manually, use std::drop::Drop. Internally this is just a wrapped file-descriptor.

Implementations§

source§

impl IsoTpSocket

source

pub fn open( ifname: &str, rx_id: impl Into<Id>, tx_id: impl Into<Id> ) -> Result<Self, Error>

Open a named CAN ISO-TP device.

Usually the more common case, opens a socket can device by name, such as “vcan0” or “socan0”.

Examples found in repository?
examples/isotprecv.rs (lines 4-8)
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
fn main() -> Result<(), socketcan_isotp::Error> {
    let mut tp_socket = IsoTpSocket::open(
        "vcan0",
        StandardId::new(0x123).expect("Invalid rx id"),
        StandardId::new(0x321).expect("Invalid tx id"),
    )?;

    let buffer = tp_socket.read()?;
    println!("read {} bytes", buffer.len());

    for x in buffer {
        print!("{:X?} ", x);
    }

    println!("");

    Ok(())
}
More examples
Hide additional examples
examples/isotpsend.rs (lines 5-9)
4
5
6
7
8
9
10
11
12
13
14
15
16
fn main() -> Result<(), socketcan_isotp::Error> {
    let tp_socket = IsoTpSocket::open(
        "vcan0",
        StandardId::new(0x321).expect("Invalid rx id"),
        StandardId::new(0x123).expect("Invalid tx id"),
    )?;

    loop {
        tp_socket.write(&[0xAA, 0x11, 0x22, 0x33, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF])?;
        println!("Sent frame");
        std::thread::sleep(Duration::from_millis(1000));
    }
}
examples/uds.rs (lines 12-16)
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
fn main() -> Result<(), socketcan_isotp::Error> {
    let (tx, rx) = mpsc::channel();

    // Reader
    let mut reader_tp_socket = IsoTpSocket::open(
        "vcan0",
        StandardId::new(0x7E8).expect("Invalid rx CAN ID"),
        StandardId::new(0x77A).expect("Invalid tx CAN ID"),
    )?;
    std::thread::spawn(move || loop {
        let buffer = reader_tp_socket.read().expect("Failed to read from socket");
        tx.send(buffer.to_vec()).expect("Receiver deallocated");
    });

    let tp_socket = IsoTpSocket::open(
        "vcan0",
        StandardId::new(0x77A).expect("Invalid rx CAN ID"),
        StandardId::new(0x7E0).expect("Invalid tx CAN ID"),
    )?;

    // 0x22 - Service Identifier for "Read data by identifier" request
    // 0xF189 - Data identifer - VehicleManufacturerECUSoftwareVersionNumberDataIdentifier
    tp_socket.write(&[0x22, 0xF1, 0x89])?;

    println!("Sent read data by identifier 0xF189 - VehicleManufacturerECUSoftwareVersionNumberDataIdentifier");

    loop {
        let recv_buffer = rx.recv().expect("Failed to receive");
        // 0x62 - Service Identifier for "Read data by identifier" response
        // 0xF189 - Data identifer - VehicleManufacturerECUSoftwareVersionNumberDataIdentifier
        if recv_buffer[0..=2] != [0x62, 0xF1, 0x89] {
            println!("Skipping: {:X?}", recv_buffer);
        } else {
            println!("Response: {:X?}", &recv_buffer[3..]);
        }
    }
}
source

pub fn open_with_opts( ifname: &str, rx_id: impl Into<Id>, tx_id: impl Into<Id>, isotp_options: Option<IsoTpOptions>, rx_flow_control_options: Option<FlowControlOptions>, link_layer_options: Option<LinkLayerOptions> ) -> Result<Self, Error>

Open a named CAN ISO-TP device, passing additional options.

Usually the more common case, opens a socket can device by name, such as “vcan0” or “socan0”.

source

pub fn open_if( if_index: c_int, rx_id: impl Into<Id>, tx_id: impl Into<Id> ) -> Result<Self, Error>

Open CAN ISO-TP device device by interface number.

Opens a CAN device by kernel interface number.

source

pub fn open_if_with_opts( if_index: c_int, rx_id: impl Into<Id>, tx_id: impl Into<Id>, isotp_options: Option<IsoTpOptions>, rx_flow_control_options: Option<FlowControlOptions>, link_layer_options: Option<LinkLayerOptions> ) -> Result<Self, Error>

Open CAN ISO-TP device device by interface number, passing additional options.

Opens a CAN device by kernel interface number.

source

pub fn set_nonblocking(&self, nonblocking: bool) -> Result<()>

Change socket to non-blocking mode

source

pub fn read(&mut self) -> Result<&[u8]>

Blocking read data

Examples found in repository?
examples/isotprecv.rs (line 10)
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
fn main() -> Result<(), socketcan_isotp::Error> {
    let mut tp_socket = IsoTpSocket::open(
        "vcan0",
        StandardId::new(0x123).expect("Invalid rx id"),
        StandardId::new(0x321).expect("Invalid tx id"),
    )?;

    let buffer = tp_socket.read()?;
    println!("read {} bytes", buffer.len());

    for x in buffer {
        print!("{:X?} ", x);
    }

    println!("");

    Ok(())
}
More examples
Hide additional examples
examples/uds.rs (line 18)
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
fn main() -> Result<(), socketcan_isotp::Error> {
    let (tx, rx) = mpsc::channel();

    // Reader
    let mut reader_tp_socket = IsoTpSocket::open(
        "vcan0",
        StandardId::new(0x7E8).expect("Invalid rx CAN ID"),
        StandardId::new(0x77A).expect("Invalid tx CAN ID"),
    )?;
    std::thread::spawn(move || loop {
        let buffer = reader_tp_socket.read().expect("Failed to read from socket");
        tx.send(buffer.to_vec()).expect("Receiver deallocated");
    });

    let tp_socket = IsoTpSocket::open(
        "vcan0",
        StandardId::new(0x77A).expect("Invalid rx CAN ID"),
        StandardId::new(0x7E0).expect("Invalid tx CAN ID"),
    )?;

    // 0x22 - Service Identifier for "Read data by identifier" request
    // 0xF189 - Data identifer - VehicleManufacturerECUSoftwareVersionNumberDataIdentifier
    tp_socket.write(&[0x22, 0xF1, 0x89])?;

    println!("Sent read data by identifier 0xF189 - VehicleManufacturerECUSoftwareVersionNumberDataIdentifier");

    loop {
        let recv_buffer = rx.recv().expect("Failed to receive");
        // 0x62 - Service Identifier for "Read data by identifier" response
        // 0xF189 - Data identifer - VehicleManufacturerECUSoftwareVersionNumberDataIdentifier
        if recv_buffer[0..=2] != [0x62, 0xF1, 0x89] {
            println!("Skipping: {:X?}", recv_buffer);
        } else {
            println!("Response: {:X?}", &recv_buffer[3..]);
        }
    }
}
source

pub fn write(&self, buffer: &[u8]) -> Result<()>

Blocking write a slice of data

Examples found in repository?
examples/isotpsend.rs (line 12)
4
5
6
7
8
9
10
11
12
13
14
15
16
fn main() -> Result<(), socketcan_isotp::Error> {
    let tp_socket = IsoTpSocket::open(
        "vcan0",
        StandardId::new(0x321).expect("Invalid rx id"),
        StandardId::new(0x123).expect("Invalid tx id"),
    )?;

    loop {
        tp_socket.write(&[0xAA, 0x11, 0x22, 0x33, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF])?;
        println!("Sent frame");
        std::thread::sleep(Duration::from_millis(1000));
    }
}
More examples
Hide additional examples
examples/uds.rs (line 30)
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
fn main() -> Result<(), socketcan_isotp::Error> {
    let (tx, rx) = mpsc::channel();

    // Reader
    let mut reader_tp_socket = IsoTpSocket::open(
        "vcan0",
        StandardId::new(0x7E8).expect("Invalid rx CAN ID"),
        StandardId::new(0x77A).expect("Invalid tx CAN ID"),
    )?;
    std::thread::spawn(move || loop {
        let buffer = reader_tp_socket.read().expect("Failed to read from socket");
        tx.send(buffer.to_vec()).expect("Receiver deallocated");
    });

    let tp_socket = IsoTpSocket::open(
        "vcan0",
        StandardId::new(0x77A).expect("Invalid rx CAN ID"),
        StandardId::new(0x7E0).expect("Invalid tx CAN ID"),
    )?;

    // 0x22 - Service Identifier for "Read data by identifier" request
    // 0xF189 - Data identifer - VehicleManufacturerECUSoftwareVersionNumberDataIdentifier
    tp_socket.write(&[0x22, 0xF1, 0x89])?;

    println!("Sent read data by identifier 0xF189 - VehicleManufacturerECUSoftwareVersionNumberDataIdentifier");

    loop {
        let recv_buffer = rx.recv().expect("Failed to receive");
        // 0x62 - Service Identifier for "Read data by identifier" response
        // 0xF189 - Data identifer - VehicleManufacturerECUSoftwareVersionNumberDataIdentifier
        if recv_buffer[0..=2] != [0x62, 0xF1, 0x89] {
            println!("Skipping: {:X?}", recv_buffer);
        } else {
            println!("Response: {:X?}", &recv_buffer[3..]);
        }
    }
}

Trait Implementations§

source§

impl AsRawFd for IsoTpSocket

source§

fn as_raw_fd(&self) -> RawFd

Extracts the raw file descriptor. Read more
source§

impl Drop for IsoTpSocket

source§

fn drop(&mut self)

Executes the destructor for this type. Read more
source§

impl FromRawFd for IsoTpSocket

source§

unsafe fn from_raw_fd(fd: RawFd) -> Self

Constructs a new instance of Self from the given raw file descriptor. Read more
source§

impl IntoRawFd for IsoTpSocket

source§

fn into_raw_fd(self) -> RawFd

Consumes this object, returning the raw underlying file descriptor. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for Twhere T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for Twhere U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T, U> TryFrom<U> for Twhere U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.