use std::env;
use std::time::{SystemTime, UNIX_EPOCH};
use takproto::proto::{CotEvent, Detail};
use takproto::{TakClient, TlsConfig};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let args: Vec<String> = env::args().collect();
if args.len() < 5 {
eprintln!(
"Usage: {} <server_addr> <server_name> <ca_cert> <client_cert> <client_key>",
args[0]
);
eprintln!();
eprintln!("Example:");
eprintln!(" {} takserver.example.com:8089 takserver.example.com ca.pem client.pem client-key.pem", args[0]);
eprintln!();
eprintln!("Arguments:");
eprintln!(
" server_addr - TAK server address with port (e.g., takserver.example.com:8089)"
);
eprintln!(" server_name - Server hostname for SNI and cert validation");
eprintln!(" ca_cert - Path to CA certificate file (PEM format)");
eprintln!(" client_cert - Path to client certificate file (PEM format)");
eprintln!(" client_key - Path to client private key file (PEM format)");
std::process::exit(1);
}
let server_addr = &args[1];
let server_name = &args[2];
let ca_cert_path = &args[3];
let client_cert_path = &args[4];
let client_key_path = &args[5];
println!("Loading TLS certificates...");
println!(" CA cert: {}", ca_cert_path);
println!(" Client cert: {}", client_cert_path);
println!(" Client key: {}", client_key_path);
let tls_config =
TlsConfig::new_with_client_cert(ca_cert_path, client_cert_path, client_key_path)?;
println!();
println!("Connecting to TAK server at {}...", server_addr);
println!(" Server name (SNI): {}", server_name);
let mut client = TakClient::connect_tls(server_addr, server_name, tls_config).await?;
println!("Connected successfully with mTLS!");
println!();
println!("Negotiating TAK Protocol Version 1...");
match client.negotiate_protocol(1, 60).await {
Ok(()) => println!("Protocol negotiation successful!"),
Err(e) => {
eprintln!("Protocol negotiation failed: {}", e);
eprintln!("Falling back to XML mode...");
}
}
println!();
let now_ms = SystemTime::now().duration_since(UNIX_EPOCH)?.as_millis() as u64;
let event = CotEvent {
r#type: "a-f-G-U-C".to_string(), uid: "RUST-TAK-TLS-CLIENT-001".to_string(),
send_time: now_ms,
start_time: now_ms,
stale_time: now_ms + 60_000, how: "m-g".to_string(),
lat: 39.377445,
lon: -76.83216000,
hae: 10.0,
ce: 9.9,
le: 9.9,
detail: Some(Detail {
xml_detail: r#"<contact callsign="RustClientTLS" endpoint="*:-1:stcp"/>
<link uid="RUST-TAK-TLS-CLIENT-001" type="a-f-G-U-C" relation="p-p" url="https://github.com/rust-lang/rust" mime="text/html"/>
<link uid="RUST-TAK-TLS-CLIENT-001" type="a-f-G-U-C" relation="p-p" url="https://www.rust-lang.org/learn" mime="text/html" remarks="Rust Documentation"/>
<remarks>Position report from Rust TAK client with embedded links</remarks>"#.to_string(),
..Default::default()
}),
..Default::default()
};
println!("Sending CoT event...");
println!(" UID: {}", event.uid);
println!(" Type: {}", event.r#type);
println!(" Position: {}, {}", event.lat, event.lon);
client.send_cot_event(event).await?;
println!();
println!("Event sent successfully over mTLS!");
client.close().await?;
Ok(())
}