First proof of concept

This commit is contained in:
2023-12-30 11:20:20 -05:00
commit 2af878c03e
4 changed files with 883 additions and 0 deletions

154
src/main.rs Normal file
View File

@@ -0,0 +1,154 @@
use clap::{Parser, Subcommand};
use minipac::{client::Client, hostname::Hostname, server::Server, stream::Stream};
use std::io;
use std::time::Duration;
#[derive(Parser, Debug)]
#[command(author, version, about, long_about = None)]
struct Args {
/// TCP/IP Address of kiss tnc
#[arg(short, long, default_value_t = String::from("127.0.0.1:8001"))]
kiss_tnc: String,
/// Callsign
#[arg(short)]
callsign: String,
/// SSID
#[arg(short, long, default_value_t = 0)]
ssid: u8,
/// The baudrate to use, in bps
#[arg(short, long, default_value_t = 1200)]
baudrate: usize,
/// The maximum packet size. Dependant on your KISS TNC
#[arg(short, long, default_value_t = 1000)]
packet_size: usize,
/// The maximum amount of retries to make before aborting
#[arg(short, long, default_value_t = 5)]
retries: usize,
/// The amount of time to wait for a reply (in seconds)
#[arg(short, long, default_value_t = 4.0)]
timeout: f32,
#[command(subcommand)]
command: Commands,
}
#[derive(Subcommand, Debug)]
enum Commands {
Serve,
Recv,
}
async fn serv_echo_test(
me: &Hostname,
caller: Hostname,
mut stream: Stream,
) -> Result<(), minipac::error::Error> {
stream
.write(
format!("{me} Echo Test\nHello {caller} I will repeat what you send to me",)
.into_bytes(),
)
.await?;
loop {
let data = stream.read().await?;
stream.write(data).await?;
}
}
/*async fn connect_text_mode(
me: &Hostname,
hostname: Hostname,
mut stream: Stream,
) -> Result<(), minipac::error::Error> {
}*/
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let args = Args::parse();
println!("tnc: {:?}", args.kiss_tnc);
println!("callsign: {}-{}", args.callsign, args.ssid);
let me = Hostname::new(&format!("{}-{}", args.callsign, args.ssid)).unwrap();
println!("hostname: {}", me);
let hostname = me.clone();
match &args.command {
Commands::Serve => {
let mut server = Server::new_tcp(
args.kiss_tnc,
hostname,
Duration::from_secs_f32(args.timeout),
args.packet_size,
args.retries,
args.baudrate,
)
.await?;
loop {
let (caller, stream) = server.accept().await?;
tokio::spawn(async move {
if let Err(e) = serv_echo_test(&me, caller, stream).await {
println!("Client Dropped: {e}");
}
});
}
}
Commands::Recv => {
let client = Client::new_tcp(
args.kiss_tnc,
hostname,
Duration::from_secs_f32(args.timeout),
args.packet_size,
args.retries,
args.baudrate,
)
.await?;
let server = Hostname::new(&format!("{}-{}", args.callsign, args.ssid + 1)).unwrap();
let stream = client.connect(server).await?;
let (mut rx, mut tx) = stream.split();
tokio::spawn(async move {
loop {
match rx.read().await {
Ok(data) => {
if let Ok(string) = String::from_utf8(data) {
println!("{}", string);
} else {
println!("Rx not valid utf-8")
}
}
Err(e) => {
println!("Recv error: {e}");
break;
}
}
}
});
let mut buffer = String::new();
loop {
// TODO FIXME use tokio io not std!?!?
match io::stdin().read_line(&mut buffer) {
Ok(0) => {
println!("Exiting...");
break;
}
Ok(_) => {
tx.write(buffer.clone().into_bytes()).await?;
}
Err(e) => {
println!("Tx Error: {e}");
break;
}
}
buffer.clear();
}
}
}
Ok(())
}