// socketcan/examples/echo_fd.rs // // This file is part of the Rust 'socketcan-rs' library. // // Licensed under the MIT license: // // This file may not be copied, modified, or distributed except according // to those terms. // // @author Frank Pagliughi // @author Natesh Narain // @date Jul 05 2022 // use anyhow::Context; use embedded_can::{Frame as EmbeddedFrame, StandardId}; use socketcan::{CanAnyFrame, CanFdFrame, CanFdSocket, Frame, Socket}; use std::{ env, sync::atomic::{AtomicBool, Ordering}, }; fn main() -> anyhow::Result<()> { let iface = env::args().nth(1).unwrap_or_else(|| "vcan0".into()); let sock = CanFdSocket::open(&iface) .with_context(|| format!("Failed to open socket on interface {}", iface))?; sock.set_nonblocking(true) .with_context(|| "Failed to make socket non-blocking")?; static QUIT: AtomicBool = AtomicBool::new(false); ctrlc::set_handler(|| { QUIT.store(true, Ordering::Relaxed); }) .expect("Failed to set signal handler"); while !QUIT.load(Ordering::Relaxed) { if let Ok(CanAnyFrame::Fd(frame)) = sock.read_frame() { println!("{}", frame_to_string(&frame)); let new_id = frame.raw_id() + 0x01; let new_id = StandardId::new(new_id as u16).expect("Failed to create ID"); if let Some(echo_frame) = CanFdFrame::new(new_id, frame.data()) { sock.write_frame(&echo_frame) .expect("Failed to echo recieved frame"); } } } Ok(()) } fn frame_to_string(frame: &F) -> String { let id = frame.raw_id(); let data_string = frame .data() .iter() .fold(String::from(""), |a, b| format!("{} {:02x}", a, b)); format!("{:08X} [{}] {}", id, frame.dlc(), data_string) }