use bp7::bundle::*;
use bp7::flags::{BundleControlFlags, BundleValidation};
use bp7::*;
use clap::Parser;
use dtn7_plus::client::DtnClient;
use std::io;
use std::{convert::TryInto, io::prelude::*};
#[derive(Parser, Debug)]
#[clap(version, author, long_about = None)]
struct Args {
#[clap(short, long, default_value_t = 3000)]
port: u16,
#[clap(short = '6', long)]
ipv6: bool,
#[clap(short, long)]
verbose: bool,
#[clap(short, long)]
sender: Option<String>,
#[clap(short, long)]
receiver: String,
#[clap(index = 1)]
infile: Option<String>,
#[clap(short = 'D', long)]
dryrun: bool,
#[clap(short, long, default_value_t = 3600)]
lifetime: u64,
}
fn main() {
let args = Args::parse();
let localhost = if args.ipv6 { "[::1]" } else { "127.0.0.1" };
let port = if let Ok(env_port) = std::env::var("DTN_WEB_PORT") {
env_port } else {
args.port.to_string()
};
let client = DtnClient::with_host_and_port(
localhost.into(),
port.parse::<u16>().expect("invalid port number"),
);
let sender: EndpointID = args
.sender
.unwrap_or_else(|| {
client
.local_node_id()
.expect("error getting node id from local dtnd")
.to_string()
})
.try_into()
.unwrap();
let receiver: EndpointID = args.receiver.try_into().unwrap();
let cts = client
.creation_timestamp()
.expect("error getting creation timestamp from local dtnd");
let mut buffer = Vec::new();
if let Some(infile) = args.infile {
if args.verbose {
println!("Sending {}", infile);
}
let mut f = std::fs::File::open(infile).expect("Error accessing file.");
f.read_to_end(&mut buffer)
.expect("Error reading from file.");
} else {
io::stdin()
.read_to_end(&mut buffer)
.expect("Error reading from stdin.");
}
if args.verbose {
println!("Sending {} bytes.", buffer.len());
}
let mut bndl = new_std_payload_bundle(sender, receiver, buffer);
let flags = BundleControlFlags::BUNDLE_MUST_NOT_FRAGMENTED
| BundleControlFlags::BUNDLE_STATUS_REQUEST_DELIVERY;
bndl.primary.bundle_control_flags.set(flags);
bndl.primary.creation_timestamp = cts;
bndl.primary.lifetime = std::time::Duration::from_secs(args.lifetime);
let binbundle = bndl.to_cbor();
println!("Bundle-Id: {}", bndl.id());
if args.verbose || args.dryrun {
let hexstr = bp7::helpers::hexify(&binbundle);
println!("{}", hexstr);
}
if !args.dryrun {
let res = attohttpc::post(format!("http://{}:{}/insert", localhost, port))
.bytes(binbundle)
.send()
.expect("error send bundle to dtnd")
.text()
.unwrap();
println!("Result: {}", res);
let now = std::time::SystemTime::now();
println!("Time: {}", humantime::format_rfc3339(now));
}
}