use can_socket::{CanFrame, CanId};
use can_socket::tokio::CanSocket;
#[derive(clap::Parser)]
struct Options {
#[clap(long, short)]
interface: String,
#[clap(long)]
id: CanId,
#[clap(long)]
rtr: Option<u8>,
#[clap(long, short)]
#[clap(default_value = "1")]
repeat: usize,
#[clap(num_args = 0..=8)]
#[clap(conflicts_with = "rtr")]
data: Vec<u8>,
}
#[tokio::main]
async fn main() {
if let Err(()) = do_main(clap::Parser::parse()).await {
std::process::exit(1);
}
}
async fn do_main(options: Options) -> Result<(), ()> {
let frame = if let Some(len) = options.rtr {
CanFrame::new_rtr(options.id)
.with_data_length_code(len)
.map_err(|e| eprintln!("Invalid input: {e}"))?
} else {
CanFrame::try_new(options.id, &options.data)
.map_err(|e| eprintln!("Invalid input: {e}"))?
};
let socket = CanSocket::bind(&options.interface)
.map_err(|e| eprintln!("Failed to create CAN socket for interface {}: {e}", options.interface))?;
for i in 0.. {
if options.repeat != 0 && i == options.repeat {
break;
}
eprintln!("Sending frame {i}...");
socket.send(&frame)
.await
.map_err(|e| eprintln!("Failed to send frame on interface {}: {e}", options.interface))?;
eprintln!()
}
Ok(())
}