From 65b5dbed648deb17ecd1acaa9505697499674c71 Mon Sep 17 00:00:00 2001 From: John Goerzen Date: Wed, 30 Oct 2019 21:39:13 -0500 Subject: [PATCH] initial kiss --- src/kiss.rs | 42 +++++++++++++++++++++--------------------- src/lorastik.rs | 4 ++-- src/main.rs | 21 +++++++++++++++------ 3 files changed, 38 insertions(+), 29 deletions(-) diff --git a/src/kiss.rs b/src/kiss.rs index add38c3..1dbd83b 100644 --- a/src/kiss.rs +++ b/src/kiss.rs @@ -16,43 +16,43 @@ */ use std::io; -use std::io::{Read, Write}; -use crate::lorastik::{LoraStik, ReceivedFrames}; -use crossbeam_channel; +use std::io::{BufRead}; +use crate::lorastik::{LoraStik}; +pub use crate::pipe::loratostdout; + +// Spec: http://www.ax25.net/kiss.aspx -const MAXFRAME: usize = 200; const FEND: u8 = 0xC0; -const FESC: u8 = 0xDB; -const TFEND: u8 = 0xDC; -const TFESC: u8 = 0xDD; +// const FESC: u8 = 0xDB; +// const TFEND: u8 = 0xDC; +// const TFESC: u8 = 0xDD; /// A thread for stdin processing -pub fn stdintolora(ls: &mut LoraStik) -> io::Result<()> { +pub fn stdintolorakiss(ls: &mut LoraStik, maxframesize: usize) -> io::Result<()> { let stdin = io::stdin(); let mut br = io::BufReader::new(stdin); let mut buf = vec![0u8; 8192]; loop { - let res = br.read(&mut buf)?; + let res = br.read_until(FEND, &mut buf)?; if res == 0 { // EOF return Ok(()); + } else if res < 2 { + // Every frame from stdin will start with FEND and a control character; + // we got just FEND, we are in the space between to frames, so we should just + // proceed. Similar if we have some non-data frame. + continue; + } else if buf[0] != 0 { + // A TNC control frame; do not send. + continue; } - - for chunk in buf[0..res].chunks(MAXFRAME) { + // OK, we've got it, now make sure it doesn't exceed the limit and transmit. + for chunk in buf[0..res].chunks(maxframesize) { ls.transmit(&chunk); } } } -pub fn loratostdout(receiver: crossbeam_channel::Receiver) -> io::Result<()> { - let mut stdout = io::stdout(); - - loop { - let data = receiver.recv().unwrap(); - stdout.write_all(&data.0)?; - stdout.flush()?; - } -} - +// loratostdout just comes from pipe diff --git a/src/lorastik.rs b/src/lorastik.rs index b28d7e9..b5d3f5f 100644 --- a/src/lorastik.rs +++ b/src/lorastik.rs @@ -25,7 +25,7 @@ use crossbeam_channel; use hex; use std::thread; use std::time::{Duration, Instant}; -// use format_escape_default::format_escape_default; +use format_escape_default::format_escape_default; use std::path::PathBuf; pub fn mkerror(msg: &str) -> Error { @@ -202,7 +202,7 @@ impl LoraStik { fn handlerx(&mut self, msg: String, readqual: bool) -> io::Result<()> { if msg.starts_with("radio_rx ") { if let Ok(mut decoded) = hex::decode(&msg.as_bytes()[10..]) { - // trace!("DECODED: {}", format_escape_default(&decoded)); + trace!("DECODED: {}", format_escape_default(&decoded)); let radioqual = if readqual { self.ser.writeln(String::from("radio get snr"))?; let snr = self.readerlinesrx.recv().unwrap(); diff --git a/src/main.rs b/src/main.rs index 0d56f16..891d4a9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -25,6 +25,7 @@ mod ser; mod lorastik; mod pipe; mod ping; +mod kiss; use std::path::PathBuf; use structopt::StructOpt; @@ -45,6 +46,10 @@ struct Opt { #[structopt(long, parse(from_os_str))] initfile: Option, + /// Maximum frame size sent to radio [10..250] (valid only for ping and kiss) + #[structopt(long, default_value = "100")] + maxpacketsize: usize, + /// Amount of time (ms) to pause before transmitting a packet /* The main purpose of this is to give the othe rradio a chance to finish @@ -75,15 +80,13 @@ struct Opt { #[derive(Debug, StructOpt)] enum Command { /// Pipe data across raios - Pipe { - /// Maximum frame size sent to radio [10..250] - #[structopt(long, default_value = "100")] - maxpacketsize: usize, - }, + Pipe, /// Transmit ping requests Ping, /// Receive ping requests and transmit pongs Pong, + /// Pipe KISS data across the radios + Kiss, } fn main() { @@ -101,11 +104,17 @@ fn main() { let mut ls2 = ls.clone(); thread::spawn(move || ls2.readerthread().expect("Failure in readerthread")); + let maxpacketsize = opt.maxpacketsize; + match opt.cmd { - Command::Pipe{ maxpacketsize } => { + Command::Pipe => { thread::spawn(move || pipe::stdintolora(&mut ls, maxpacketsize).expect("Failure in stdintolora")); pipe::loratostdout(radioreceiver).expect("Failure in loratostdout"); }, + Command::Kiss => { + thread::spawn(move || kiss::stdintolorakiss(&mut ls, maxpacketsize).expect("Failure in stdintolorakiss")); + kiss::loratostdout(radioreceiver).expect("Failure in loratostdout"); + }, Command::Ping => { thread::spawn(move || ping::genpings(&mut ls).expect("Failure in genpings")); pipe::loratostdout(radioreceiver).expect("Failure in loratostdout");