Skip to content

Commit

Permalink
docs
Browse files Browse the repository at this point in the history
  • Loading branch information
pd0wm committed May 11, 2024
1 parent 5e653c3 commit ea1c2b1
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 6 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ The automotive crate also supplies interfaces for various diagnostic protocols s
The following CAN adapters are supported.

### Supported CAN adapters
- SocketCAN (Linux only, supported using [socketcan-rs](https://github.com/socketcan-rs/socketcan-rs))
- SocketCAN (Linux only)
- comma.ai panda (all platforms using [rusb](https://crates.io/crates/rusb))

### Known limitations / Notes
Expand Down
8 changes: 5 additions & 3 deletions src/socketcan/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//! This module provides a [`CanAdapter`] implementation for the [`socketcan`] crate.
//! This module provides a [`CanAdapter`] implementation for SocketCAN interfaces
use crate::can::{AsyncCanAdapter, CanAdapter, Frame};
use crate::socketcan::socket::CanFdSocket;
use crate::Result;
Expand All @@ -10,7 +10,7 @@ mod socket;

const IFF_ECHO: u64 = 1 << 18; // include/uapi/linux/if.h

/// Aadapter for a [`socketcan::CanFdSocket`].
/// SocketCAN Adapter
pub struct SocketCan {
socket: CanFdSocket,
/// If the IFF_ECHO flag is set on the interface, it will implement proper ACK logic.
Expand All @@ -33,11 +33,13 @@ fn read_iff_echo(if_name: &str) -> Option<bool> {
}

impl SocketCan {
/// Creates a new [`AsyncCanAdapter`] from a SocketCAN iface name (e.g. `can0`)
pub fn new_async(name: &str) -> Result<AsyncCanAdapter> {
let socket = SocketCan::new(name)?;
Ok(AsyncCanAdapter::new(socket))
}

/// Creates a new blocking [`SocketCan`] from a SocketCAN iface name (e.g. `can0`)
pub fn new(name: &str) -> Result<SocketCan> {
let socket = match CanFdSocket::open(name) {
Ok(socket) => socket,
Expand Down Expand Up @@ -65,7 +67,7 @@ impl SocketCan {
};

if iff_echo {
// socket.set_recv_own_msgs(true).unwrap();
socket.set_recv_own_msgs(true).unwrap();
} else {
tracing::warn!("IFF_ECHO is not set on the interface. ACK support is emulated.");
}
Expand Down
20 changes: 18 additions & 2 deletions src/socketcan/socket.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
//! Low Level SocketCAN code
//! Code based on https://github.com/socketcan-rs/socketcan-rs
//! Code based on socketcan-rs
use libc::{
c_int, c_void, can_frame, canfd_frame, sa_family_t, sockaddr_can, socklen_t, AF_CAN, CANFD_MTU,
CAN_MTU, CAN_RAW, CAN_RAW_FD_FRAMES, CAN_RAW_LOOPBACK, SOL_CAN_RAW,
CAN_MTU, CAN_RAW, CAN_RAW_FD_FRAMES, CAN_RAW_LOOPBACK, CAN_RAW_RECV_OWN_MSGS, SOL_CAN_RAW,
};
use nix::net::if_::if_nametoindex;
use std::io::Write;
Expand Down Expand Up @@ -106,15 +106,22 @@ impl CanFdSocket {
}
}

/// Enable or disable FD mode on a socket.
pub fn set_fd_mode(&self, enabled: bool) -> std::io::Result<()> {
let enable = c_int::from(enabled);
self.set_socket_option(SOL_CAN_RAW, CAN_RAW_FD_FRAMES, &enable)
}

/// Change socket to non-blocking mode or back to blocking mode.
pub fn set_nonblocking(&self, nonblocking: bool) -> std::io::Result<()> {
self.as_raw_socket().set_nonblocking(nonblocking)
}

/// Enable or disable loopback.
///
/// By default, loopback is enabled, causing other applications that open
/// the same CAN bus to see frames emitted by different applications on
/// the same system.
pub fn set_loopback(&self, enabled: bool) -> std::io::Result<()> {
let loopback = c_int::from(enabled);
self.set_socket_option(SOL_CAN_RAW, CAN_RAW_LOOPBACK, &loopback)
Expand All @@ -128,6 +135,15 @@ impl CanFdSocket {
self.as_raw_socket().recv_buffer_size()
}

/// Enable or disable receiving of own frames.
///
/// When enabled, this settings controls if CAN frames sent
/// are received back by sender when ACKed. Default is off.
pub fn set_recv_own_msgs(&self, enabled: bool) -> std::io::Result<()> {
let recv_own_msgs = c_int::from(enabled);
self.set_socket_option(SOL_CAN_RAW, CAN_RAW_RECV_OWN_MSGS, &recv_own_msgs)
}

fn as_raw_socket(&self) -> &socket2::Socket {
&self.0
}
Expand Down

0 comments on commit ea1c2b1

Please sign in to comment.