use anyhow::{Context, Result};
use clap::{arg, ArgAction, Command};
use socketcan::{dump::Reader, CanAnyFrame, CanFdSocket, Socket};
use std::process;
const VERSION: &str = env!("CARGO_PKG_VERSION");
fn play(filename: &str, iface: &str) -> Result<()> {
let sock = CanFdSocket::open(iface)
.with_context(|| format!("Failed to open FD socket on interface '{}'", iface))?;
let reader = Reader::from_file(filename)
.with_context(|| format!("Error opening log file '{}'", filename))?;
for rec in reader {
let rec = rec?;
println!("{}", rec);
use CanAnyFrame::*;
match rec.frame {
Normal(frame) => sock.write_frame(&frame)?,
Remote(frame) => sock.write_frame(&frame)?,
Fd(frame) => sock.write_frame(&frame)?,
_ => (),
}
}
Ok(())
}
fn main() {
let opts = Command::new("can")
.author("Frank Pagliughi")
.version(VERSION)
.about("SocketCAN example to play a candump file")
.disable_help_flag(true)
.arg(
arg!(--help "Print help information")
.short('?')
.action(ArgAction::Help)
.global(true),
)
.arg(arg!(<iface> "The CAN interface to use, like 'can0', 'vcan0', etc").required(true))
.arg(arg!(<file> "The candump log file to read").required(true))
.get_matches();
let iface = opts.get_one::<String>("iface").unwrap();
let filename = opts.get_one::<String>("file").unwrap();
if let Err(err) = play(filename, iface) {
eprintln!("{}", err);
process::exit(1);
}
}