refactor module for communication with serial port. Create TCP server for accept requests from client and interacting with serial port with command from clients. It is works
This commit is contained in:
parent
d645ee64ef
commit
8ce1d95821
115
Cargo.lock
generated
115
Cargo.lock
generated
@ -26,6 +26,56 @@ dependencies = [
|
|||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anstream"
|
||||||
|
version = "0.6.18"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b"
|
||||||
|
dependencies = [
|
||||||
|
"anstyle",
|
||||||
|
"anstyle-parse",
|
||||||
|
"anstyle-query",
|
||||||
|
"anstyle-wincon",
|
||||||
|
"colorchoice",
|
||||||
|
"is_terminal_polyfill",
|
||||||
|
"utf8parse",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anstyle"
|
||||||
|
version = "1.0.10"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anstyle-parse"
|
||||||
|
version = "0.2.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9"
|
||||||
|
dependencies = [
|
||||||
|
"utf8parse",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anstyle-query"
|
||||||
|
version = "1.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c"
|
||||||
|
dependencies = [
|
||||||
|
"windows-sys 0.59.0",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anstyle-wincon"
|
||||||
|
version = "3.0.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e"
|
||||||
|
dependencies = [
|
||||||
|
"anstyle",
|
||||||
|
"once_cell",
|
||||||
|
"windows-sys 0.59.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "autocfg"
|
name = "autocfg"
|
||||||
version = "1.4.0"
|
version = "1.4.0"
|
||||||
@ -79,6 +129,46 @@ dependencies = [
|
|||||||
"windows-link",
|
"windows-link",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clap"
|
||||||
|
version = "4.5.31"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "027bb0d98429ae334a8698531da7077bdf906419543a35a55c2cb1b66437d767"
|
||||||
|
dependencies = [
|
||||||
|
"clap_builder",
|
||||||
|
"clap_derive",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clap_builder"
|
||||||
|
version = "4.5.31"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5589e0cba072e0f3d23791efac0fd8627b49c829c196a492e88168e6a669d863"
|
||||||
|
dependencies = [
|
||||||
|
"anstream",
|
||||||
|
"anstyle",
|
||||||
|
"clap_lex",
|
||||||
|
"strsim",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clap_derive"
|
||||||
|
version = "4.5.28"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bf4ced95c6f4a675af3da73304b9ac4ed991640c36374e4b46795c49e17cf1ed"
|
||||||
|
dependencies = [
|
||||||
|
"heck",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clap_lex"
|
||||||
|
version = "0.7.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clipboard-win"
|
name = "clipboard-win"
|
||||||
version = "4.5.0"
|
version = "4.5.0"
|
||||||
@ -90,6 +180,12 @@ dependencies = [
|
|||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "colorchoice"
|
||||||
|
version = "1.0.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "core-foundation"
|
name = "core-foundation"
|
||||||
version = "0.10.0"
|
version = "0.10.0"
|
||||||
@ -175,6 +271,12 @@ dependencies = [
|
|||||||
"wasi",
|
"wasi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "heck"
|
||||||
|
version = "0.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "iana-time-zone"
|
name = "iana-time-zone"
|
||||||
version = "0.1.61"
|
version = "0.1.61"
|
||||||
@ -208,6 +310,12 @@ dependencies = [
|
|||||||
"mach2",
|
"mach2",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "is_terminal_polyfill"
|
||||||
|
version = "1.70.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "js-sys"
|
name = "js-sys"
|
||||||
version = "0.3.77"
|
version = "0.3.77"
|
||||||
@ -498,6 +606,12 @@ version = "1.0.6"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9e08d8363704e6c71fc928674353e6b7c23dcea9d82d7012c8faf2a3a025f8d0"
|
checksum = "9e08d8363704e6c71fc928674353e6b7c23dcea9d82d7012c8faf2a3a025f8d0"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "strsim"
|
||||||
|
version = "0.11.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "2.0.98"
|
version = "2.0.98"
|
||||||
@ -534,6 +648,7 @@ name = "uart_server"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"chrono",
|
"chrono",
|
||||||
|
"clap",
|
||||||
"log",
|
"log",
|
||||||
"regex",
|
"regex",
|
||||||
"rustyline",
|
"rustyline",
|
||||||
|
@ -9,3 +9,4 @@ rustyline = "9.*"
|
|||||||
regex = "1.7.0"
|
regex = "1.7.0"
|
||||||
chrono = "0.4.40"
|
chrono = "0.4.40"
|
||||||
log = "0.4.26"
|
log = "0.4.26"
|
||||||
|
clap = { version = "4.*", features = ["derive"] }
|
||||||
|
338
src/main.rs
338
src/main.rs
@ -9,6 +9,7 @@ use std::fs::OpenOptions;
|
|||||||
use std::io::{BufReader, BufRead};
|
use std::io::{BufReader, BufRead};
|
||||||
use std::net::{TcpListener, TcpStream};
|
use std::net::{TcpListener, TcpStream};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
use clap::{Parser};
|
||||||
|
|
||||||
pub mod perf {
|
pub mod perf {
|
||||||
use chrono::{DateTime, Duration, Utc, Local};
|
use chrono::{DateTime, Duration, Utc, Local};
|
||||||
@ -64,45 +65,6 @@ pub mod perf {
|
|||||||
|
|
||||||
use crate::perf::Perf;
|
use crate::perf::Perf;
|
||||||
|
|
||||||
fn tcp_server() {
|
|
||||||
let listener = TcpListener::bind("127.0.0.1:10000").unwrap();
|
|
||||||
println!("TCP-server is running");
|
|
||||||
|
|
||||||
for stream in listener.incoming() {
|
|
||||||
match stream {
|
|
||||||
Ok(stream) => {
|
|
||||||
println!("connect to client: {:?}", stream);
|
|
||||||
handle_client(stream);
|
|
||||||
|
|
||||||
},
|
|
||||||
Err(ref msg) => {
|
|
||||||
println!("error: failed attempt to set connection with client: ({:?}): {}",
|
|
||||||
stream, msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn handle_client(mut stream: TcpStream) {
|
|
||||||
let mut cmd_descr: HashMap::<&str, &str> = HashMap::new();
|
|
||||||
cmd_descr.insert("send", "send data to serial port");
|
|
||||||
cmd_descr.insert("exit", "cancel connection with server");
|
|
||||||
|
|
||||||
loop {
|
|
||||||
let mut reader = BufReader::new(&stream);
|
|
||||||
let mut rx_data = String::new();
|
|
||||||
if let Err(msg) = reader.read_line(&mut rx_data) {
|
|
||||||
println!("error: failed attempt to read data from client: {}", msg);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if rx_data.contains("exit") {
|
|
||||||
println!("The client requested to close the connection");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
pub mod uartTransact {
|
pub mod uartTransact {
|
||||||
const MAX_BUF: usize = 4096;
|
const MAX_BUF: usize = 4096;
|
||||||
@ -280,6 +242,8 @@ pub mod uartTransact {
|
|||||||
if self.type_ == Type_en::tx_rx {
|
if self.type_ == Type_en::tx_rx {
|
||||||
self.cmd_writer.log(&self.tx_packet).unwrap();
|
self.cmd_writer.log(&self.tx_packet).unwrap();
|
||||||
|
|
||||||
|
// println!("write to port: ({:?})", self.tx_packet.as_bytes());
|
||||||
|
|
||||||
match self.port.write(&self.tx_packet.as_bytes()) {
|
match self.port.write(&self.tx_packet.as_bytes()) {
|
||||||
Ok(_) => {},
|
Ok(_) => {},
|
||||||
Err(e) => eprintln!("Error sending data: {}", e),
|
Err(e) => eprintln!("Error sending data: {}", e),
|
||||||
@ -341,6 +305,8 @@ pub mod uartTransact {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
use crate::uartTransact::*;
|
||||||
|
|
||||||
fn read_str(s: &str) -> Result<Vec<String>, String> {
|
fn read_str(s: &str) -> Result<Vec<String>, String> {
|
||||||
let re = match Regex::new(r#""([^"]+)"|(\S+)"#) {
|
let re = match Regex::new(r#""([^"]+)"|(\S+)"#) {
|
||||||
Ok(val) => val,
|
Ok(val) => val,
|
||||||
@ -354,15 +320,111 @@ fn read_str(s: &str) -> Result<Vec<String>, String> {
|
|||||||
Ok(res)
|
Ok(res)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn uart_cmd_interp(cmd: &str) -> String {
|
||||||
|
let mut out = String::new();
|
||||||
|
|
||||||
|
let args = match read_str(&cmd) {
|
||||||
|
Ok(arg) => arg,
|
||||||
|
Err(msg) => {
|
||||||
|
return format!("error: failed read input string: {}", msg);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let args_cnt = args.len();
|
||||||
|
if args_cnt == 0 { return format!("{}", out); }
|
||||||
|
let cmd_head = &args[0].clone();
|
||||||
|
|
||||||
|
if cmd_head.contains("exit") { return format!("exit"); }
|
||||||
|
else if cmd_head.contains("help") {
|
||||||
|
out.push_str(&format!("Serial port terminal supports the following commands:"));
|
||||||
|
out.push_str(&format!("\n1. exit - \t\texcecute quit from this program"));
|
||||||
|
out.push_str(&format!("\n2. help - \t\texplain how to use this program"));
|
||||||
|
out.push_str(&format!("\n3. show_ports - \tshows all available serial ports"));
|
||||||
|
out.push_str(&format!("\n4. send - \t\tsends specified <data>\n\tUse: send <port_name> <data>\n\tExample: send /dev/ttyUSB0 \"command data1 data2\""));
|
||||||
|
out.push_str(&format!("\n5. open_port - open port with specified settings\n \tUse: open_port <port_name> <speed> <data_bits> <parity> <stop_bits> <flow_ctrl> <timeout> <transact_type> <save_data_flags>\n \tWhere: \n\t\t<port name> - port name \n\t\t<speed> - speed (9600 for example) \n\t\t<data bits>: 5, 6, 7, 8 \n\t\t<parity>: None, Even, Odd \n\t\t<stop bits>: 1, 2 \n\t\t<flow ctrl>: None, Software, Hardware \n\t\t<timeout> - timeout for receive and transmit in msec \n\t\t<transaction type>: tx, rx, tx_rx, rx_tx (tx - transmit, rx - receive) \n\t\t<save_data_flags>: true, false \n\tExample: open_port /dev/ttyUSB0 9600 8 Even 1 None 1000 tx_rx true\n"));
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
else if cmd_head.contains("show_ports") {
|
||||||
|
match serialport::available_ports() {
|
||||||
|
Ok(ports) => {
|
||||||
|
for port in ports {
|
||||||
|
out.push_str(&format!("{}: {:?}\n", port.port_name, port.port_type));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(msg) => { return format!("error while get all available serial port list: {}", msg); }
|
||||||
|
}
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
else if cmd_head == "send" {
|
||||||
|
if args_cnt != 3 { return format!("Error while parse command! {}", "arguments count must be 2"); }
|
||||||
|
else {
|
||||||
|
let port_name = &args[1];
|
||||||
|
let timeout: u64 = 200;
|
||||||
|
let port_set = PortSettings_t::new(9600, 8, "None", 1, "None", timeout).unwrap();
|
||||||
|
let save_data_flag_ = true;
|
||||||
|
let save_cmd_flag_ = true;
|
||||||
|
let trans_type = "tx_rx";
|
||||||
|
|
||||||
|
let mut uartTrans = UartTransact::new(trans_type, port_name,
|
||||||
|
port_set, save_data_flag_, save_cmd_flag_).unwrap();
|
||||||
|
|
||||||
|
let mut data_out = args[2].clone();
|
||||||
|
data_out.push_str(std::str::from_utf8(b"\x0D\x0A").unwrap()); // CR + LF
|
||||||
|
|
||||||
|
uartTrans.addPacketForTx(data_out.clone(), data_out.len() as u32).unwrap();
|
||||||
|
uartTrans.startTransact().unwrap();
|
||||||
|
|
||||||
|
let s = uartTrans.getReceivedPacket();
|
||||||
|
let data = format!("{}: {}", Perf::cur_time("%H:%M:%S.%3f"), s.trim());
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if cmd_head == "send_loop" {
|
||||||
|
if args_cnt != 5 { return format!("Error while parse command! {}", "arguments count must be 4"); }
|
||||||
|
else {
|
||||||
|
let cnt = args[3].parse::<u32>().unwrap();
|
||||||
|
let period = args[4].parse::<u64>().unwrap();
|
||||||
|
let mut i = 0;
|
||||||
|
while i < cnt {
|
||||||
|
i += 1;
|
||||||
|
let mut data_out = args[2].clone();
|
||||||
|
thread::sleep(time::Duration::from_millis(period));
|
||||||
|
}
|
||||||
|
|
||||||
|
return format!("command have not yet realized");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if cmd_head.contains("open_port") {
|
||||||
|
|
||||||
|
if args_cnt != 10 { return format!("Error while parse command! {}", "arguments count must be 9"); }
|
||||||
|
else {
|
||||||
|
return format!("command have not yet realized");
|
||||||
|
|
||||||
|
// let port_name = &args[1];
|
||||||
|
// let speed = args[3].parse::<u32>().unwrap();
|
||||||
|
// let data_bits = args[3].parse::<u8>().unwrap();
|
||||||
|
// let parity = &args[4];
|
||||||
|
// let stop_bits = args[5].parse::<u8>().unwrap();
|
||||||
|
// let flow_ctrl = &args[6];
|
||||||
|
// let timeout = args[7].parse::<u64>().unwrap();
|
||||||
|
// let trans_type = &args[8];
|
||||||
|
// let save_data_flag = args[9].parse::<bool>().unwrap();
|
||||||
|
// let save_cmd_flag = save_data_flag;
|
||||||
|
|
||||||
|
// let port_set = PortSettings_t::new(speed, data_bits, parity, stop_bits,
|
||||||
|
// flow_ctrl, timeout).unwrap();
|
||||||
|
|
||||||
|
// let mut uartTrans = UartTransact::new(trans_type, &port_name,
|
||||||
|
// port_set, save_data_flag, save_cmd_flag).unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fn cli_mode() {
|
||||||
|
|
||||||
fn main() {
|
|
||||||
use crate::perf::Perf;
|
|
||||||
use crate::uartTransact::*;
|
|
||||||
let mut perf = Perf::new();
|
|
||||||
|
|
||||||
let fname_hist = "../settings/cmd_history.log".to_string();
|
let fname_hist = "../settings/cmd_history.log".to_string();
|
||||||
let mut editor = Editor::<()>::new();
|
let mut editor = Editor::<()>::new();
|
||||||
if editor.load_history(&fname_hist).is_err() {
|
if editor.load_history(&fname_hist).is_err() {
|
||||||
@ -393,106 +455,110 @@ fn main() {
|
|||||||
|
|
||||||
editor.add_history_entry(&s);
|
editor.add_history_entry(&s);
|
||||||
|
|
||||||
|
let reply = uart_cmd_interp(&s);
|
||||||
|
|
||||||
let args = match read_str(&s) {
|
if reply.contains("exit") { break; }
|
||||||
Ok(arg) => arg,
|
else { println!("{}", reply); }
|
||||||
Err(msg) => {
|
|
||||||
println!("{}", msg);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let args_cnt = args.len();
|
}
|
||||||
|
|
||||||
let cmd_head = &args[0].clone();
|
editor.save_history(&fname_hist).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
if cmd_head.contains("exit") { break; }
|
fn tcp_server() {
|
||||||
else if cmd_head.contains("help") {
|
let listener = TcpListener::bind("127.0.0.1:10000").unwrap();
|
||||||
println!("Serial port terminal supports the following commands:");
|
println!("TCP-server is running");
|
||||||
println!("\nexit - excecute quit from this program");
|
|
||||||
println!("\nhelp - explain how to use this program");
|
|
||||||
println!("\nshow_ports - shows all available serial ports");
|
|
||||||
println!("\nsend <port_name> <data> - sends specified <data>");
|
|
||||||
println!("\nsend_loop <port name> <data> <count times> <period in msec> \n\tsends specified <data> to <port name> in loop mode: <count times> times with period specified in <period in msec> ");
|
|
||||||
println!("\nopen_port <port name> <speed> <data bits: 5, 6, 7, 8> <parity: None, Even, Odd> <stop bits: 1, 2> <flow control: None, Software, Hardware> <timeout_ms> <transaction type: tx, rx, tx_rx, rx_tx> <save commands and data to file: true, false>.\n\tExample1: open_port /dev/ttyUSB0 9600 8 Even 1 None 1000 tx_rx true");
|
|
||||||
}
|
|
||||||
else if cmd_head.contains("show_ports") {
|
|
||||||
match serialport::available_ports() {
|
|
||||||
Ok(ports) => {
|
|
||||||
for port in ports {
|
|
||||||
println!("{}: {:?}", port.port_name, port.port_type);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Err(msg) => { eprintln!("error while get all available serial port list: {}", msg); return; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if cmd_head == "send" {
|
|
||||||
if args_cnt != 3 { eprintln!("Error while parse command! {}", "arguments count must be 2"); }
|
|
||||||
else {
|
|
||||||
let port_name = &args[1];
|
|
||||||
let timeout: u64 = 200;
|
|
||||||
let port_set = PortSettings_t::new(9600, 8, "None", 1, "None", timeout).unwrap();
|
|
||||||
let save_data_flag_ = true;
|
|
||||||
let save_cmd_flag_ = true;
|
|
||||||
let trans_type = "tx_rx";
|
|
||||||
|
|
||||||
let mut uartTrans = UartTransact::new(trans_type, port_name,
|
for stream in listener.incoming() {
|
||||||
port_set, save_data_flag_, save_cmd_flag_).unwrap();
|
match stream {
|
||||||
|
Ok(stream) => {
|
||||||
|
println!("connect to client: {:?}", stream);
|
||||||
|
handle_client(stream);
|
||||||
|
|
||||||
let mut perf = Perf::new();
|
},
|
||||||
perf.start();
|
Err(ref msg) => {
|
||||||
let mut data_out = args[2].clone();
|
println!("error: failed attempt to set connection with client: ({:?}): {}",
|
||||||
data_out.push_str(std::str::from_utf8(b"\x0D\x0A").unwrap()); // CR + LF
|
stream, msg);
|
||||||
|
|
||||||
uartTrans.addPacketForTx(data_out.clone(), data_out.len() as u32).unwrap();
|
|
||||||
uartTrans.startTransact().unwrap();
|
|
||||||
|
|
||||||
let s = uartTrans.getReceivedPacket();
|
|
||||||
let data = format!("{}: {}", Perf::cur_time("%H:%M:%S.%f"), s.trim());
|
|
||||||
println!("{}", data);
|
|
||||||
perf.stop("time for transaction", "mks");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if cmd_head == "send_loop" {
|
|
||||||
if args_cnt != 5 { eprintln!("Error while parse command! {}", "arguments count must be 4"); }
|
|
||||||
else {
|
|
||||||
let cnt = args[3].parse::<u32>().unwrap();
|
|
||||||
let period = args[4].parse::<u64>().unwrap();
|
|
||||||
let mut i = 0;
|
|
||||||
while i < cnt {
|
|
||||||
i += 1;
|
|
||||||
let mut data_out = args[2].clone();
|
|
||||||
thread::sleep(time::Duration::from_millis(period));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if cmd_head.contains("open_port") {
|
|
||||||
|
|
||||||
if args_cnt != 10 { eprintln!("Error while parse command! {}", "arguments count must be 9"); }
|
|
||||||
else {
|
|
||||||
let port_name = &args[1];
|
|
||||||
let speed = args[3].parse::<u32>().unwrap();
|
|
||||||
let data_bits = args[3].parse::<u8>().unwrap();
|
|
||||||
let parity = &args[4];
|
|
||||||
let stop_bits = args[5].parse::<u8>().unwrap();
|
|
||||||
let flow_ctrl = &args[6];
|
|
||||||
let timeout = args[7].parse::<u64>().unwrap();
|
|
||||||
let trans_type = &args[8];
|
|
||||||
let save_data_flag = args[9].parse::<bool>().unwrap();
|
|
||||||
let save_cmd_flag = save_data_flag;
|
|
||||||
|
|
||||||
let port_set = PortSettings_t::new(speed, data_bits, parity, stop_bits,
|
|
||||||
flow_ctrl, timeout).unwrap();
|
|
||||||
|
|
||||||
let mut uartTrans = UartTransact::new(trans_type, &port_name,
|
|
||||||
port_set, save_data_flag, save_cmd_flag).unwrap();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// close ports
|
fn handle_client(mut stream: TcpStream) {
|
||||||
editor.save_history(&fname_hist).unwrap();
|
let mut cmd_descr: HashMap::<&str, &str> = HashMap::new();
|
||||||
// drop(port1);
|
cmd_descr.insert("send", "send data to serial port");
|
||||||
|
cmd_descr.insert("exit", "cancel connection with server");
|
||||||
|
|
||||||
|
loop {
|
||||||
|
let mut perf = Perf::new();
|
||||||
|
let mut reader = BufReader::new(&stream);
|
||||||
|
let mut rx_data = String::new();
|
||||||
|
if let Err(msg) = reader.read_line(&mut rx_data) {
|
||||||
|
println!("error: failed attempt to read data from client: {}", msg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// println!("rx_data: ({})", rx_data.trim());
|
||||||
|
|
||||||
|
perf.start();
|
||||||
|
|
||||||
|
if rx_data.starts_with("send") ||
|
||||||
|
rx_data.starts_with("help") ||
|
||||||
|
rx_data.starts_with("show_ports") {
|
||||||
|
let mut reply = uart_cmd_interp(&rx_data.trim());
|
||||||
|
|
||||||
|
// reply.push('\n');
|
||||||
|
if let Err(msg) = stream.write_all(reply.as_bytes()) {
|
||||||
|
println!("error: failed attempt to send data to client: {}", msg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if rx_data.starts_with("exit") {
|
||||||
|
println!("The client requested to close the connection");
|
||||||
|
return;
|
||||||
|
|
||||||
|
}
|
||||||
|
else if rx_data == "" {
|
||||||
|
let data = format!("empty string! ");
|
||||||
|
|
||||||
|
if let Err(msg) = stream.write_all(rx_data.as_bytes()) {
|
||||||
|
println!("error: failed attempt to send data to client: {}", msg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
let data = format!("unsuppoted command: ({})\n", rx_data.trim());
|
||||||
|
|
||||||
|
if let Err(msg) = stream.write_all(data.as_bytes()) {
|
||||||
|
println!("error: failed attempt to send data to client: {}", msg);
|
||||||
|
return;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
perf.stop("speed: ", "mks");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Parser, Debug)]
|
||||||
|
#[command(version, author, about, long_about = None)]
|
||||||
|
struct Cli {
|
||||||
|
/// working mode: tcp - remote control with TCP/IP, cli - command line interface
|
||||||
|
#[arg(long, short = 'm', value_name = "MODE")]
|
||||||
|
mode: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
|
||||||
|
let cli = Cli::parse();
|
||||||
|
// println!("{:#?}", cli);
|
||||||
|
|
||||||
|
if let Some(mode) = &cli.mode {
|
||||||
|
if mode == "cli" { cli_mode(); }
|
||||||
|
else if mode == "tcp" { tcp_server(); }
|
||||||
|
else { println!("error: incorrect parameter. type --help"); }
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user