refactor. Add set_port functional for set settings in specified serial port
This commit is contained in:
parent
8ce1d95821
commit
ac7c6ba356
192
src/main.rs
192
src/main.rs
@ -1,18 +1,18 @@
|
||||
use std::time::Duration;
|
||||
use std::{thread, time};
|
||||
use serialport::{SerialPort, StopBits, Parity, FlowControl, DataBits};
|
||||
use std::io::{self, Read, Write, BufWriter};
|
||||
// use std::time::Duration;
|
||||
// use std::{thread, time};
|
||||
// use serialport::{SerialPort, StopBits, Parity, FlowControl, DataBits};
|
||||
// use std::io::{self, Read, Write, BufWriter};
|
||||
use regex::Regex;
|
||||
use rustyline::Editor;
|
||||
use rustyline::error::ReadlineError;
|
||||
use std::fs::OpenOptions;
|
||||
use std::io::{BufReader, BufRead};
|
||||
// use std::fs::OpenOptions;
|
||||
use std::io::{BufReader, BufRead, Write};
|
||||
use std::net::{TcpListener, TcpStream};
|
||||
use std::collections::HashMap;
|
||||
// use std::collections::HashMap;
|
||||
use clap::{Parser};
|
||||
|
||||
pub mod perf {
|
||||
use chrono::{DateTime, Duration, Utc, Local};
|
||||
use chrono::{DateTime, Utc, Local};
|
||||
|
||||
pub struct Perf {
|
||||
start: DateTime<Utc>,
|
||||
@ -44,8 +44,8 @@ pub mod perf {
|
||||
self.delta_mks = (self.end - self.start).num_microseconds().unwrap();
|
||||
self.delta_ns = (self.end - self.start).num_nanoseconds().unwrap();
|
||||
|
||||
if (measure == "mks") { println!("{} (mks): {:?}", out_msg, self.delta_mks); }
|
||||
else if (measure == "ns") { println!("{} (ns): {:?}", out_msg, self.delta_ns); }
|
||||
if measure == "mks" { println!("{} (mks): {:?}", out_msg, self.delta_mks); }
|
||||
else if measure == "ns" { println!("{} (ns): {:?}", out_msg, self.delta_ns); }
|
||||
else { println!("{} (ms): {:?}", out_msg, self.delta_ms); }
|
||||
}
|
||||
|
||||
@ -66,25 +66,25 @@ pub mod perf {
|
||||
use crate::perf::Perf;
|
||||
|
||||
|
||||
pub mod uartTransact {
|
||||
pub mod uart_transact {
|
||||
const MAX_BUF: usize = 4096;
|
||||
use serialport::{SerialPort, StopBits, Parity, FlowControl, DataBits};
|
||||
use std::time::Duration;
|
||||
use crate::perf::Perf;
|
||||
use std::io::{self, Read, Write, BufWriter, BufReader, BufRead};
|
||||
use std::io::{self, Write, BufWriter, BufReader, BufRead};
|
||||
use std::fs::{File, OpenOptions};
|
||||
use std::path::Path;
|
||||
|
||||
#[derive(PartialEq)]
|
||||
pub enum Type_en {
|
||||
rx = 0,
|
||||
tx,
|
||||
rx_tx,
|
||||
tx_rx,
|
||||
pub enum TypeEn {
|
||||
Rx = 0,
|
||||
Tx,
|
||||
RxTx,
|
||||
TxRx,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct PortSettings_t {
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct PortSettingsT {
|
||||
baud_rate: u32,
|
||||
data_bits: DataBits,
|
||||
parity: Parity,
|
||||
@ -93,7 +93,7 @@ pub mod uartTransact {
|
||||
timeout_msec: u64,
|
||||
}
|
||||
|
||||
impl PortSettings_t {
|
||||
impl PortSettingsT {
|
||||
pub fn new(baud_rate: u32, data_bits_: u8, parity_: &str, stop_bits_: u8,
|
||||
flow_ctrl_: &str, timeout_msec: u64) -> Result<Self, String> {
|
||||
|
||||
@ -141,17 +141,6 @@ pub mod uartTransact {
|
||||
}
|
||||
}
|
||||
|
||||
struct Packet_t {
|
||||
buf: [u8; MAX_BUF],
|
||||
size: u32,
|
||||
}
|
||||
|
||||
impl Packet_t {
|
||||
pub fn new(buf: [u8; MAX_BUF], size: u32) -> Packet_t {
|
||||
Packet_t { buf, size }
|
||||
}
|
||||
}
|
||||
|
||||
struct Logger {
|
||||
out: BufWriter<File>,
|
||||
log_flag: bool,
|
||||
@ -161,7 +150,7 @@ pub mod uartTransact {
|
||||
fn new<P: AsRef<Path>>(filename: P, log_flag: bool) -> Result<Self, io::Error> {
|
||||
let path = Path::new(filename.as_ref());
|
||||
|
||||
let mut file = match path.exists() {
|
||||
let file = match path.exists() {
|
||||
true => OpenOptions::new().write(true).append(true).open(filename.as_ref())?,
|
||||
false => File::create(filename.as_ref())?
|
||||
};
|
||||
@ -184,9 +173,9 @@ pub mod uartTransact {
|
||||
}
|
||||
|
||||
pub struct UartTransact {
|
||||
type_: Type_en,
|
||||
type_: TypeEn,
|
||||
port_name: String,
|
||||
port_settings: PortSettings_t,
|
||||
port_settings: PortSettingsT,
|
||||
tx_packet: String,
|
||||
rx_packet: String,
|
||||
|
||||
@ -200,22 +189,22 @@ pub mod uartTransact {
|
||||
impl UartTransact {
|
||||
pub fn new(trans_type: &str,
|
||||
port_name: &str,
|
||||
port_settings: PortSettings_t,
|
||||
port_settings: PortSettingsT,
|
||||
save_data_flag: bool,
|
||||
save_cmd_flag: bool) -> Result<Self, io::Error> {
|
||||
|
||||
let mut type_ = Type_en::tx_rx;
|
||||
if trans_type == "tx_rx" { type_ = Type_en::tx_rx; }
|
||||
else if trans_type == "tx" { type_ = Type_en::rx; }
|
||||
else if trans_type == "rx_tx" { type_ = Type_en::rx_tx; }
|
||||
else if trans_type == "rx" { type_ = Type_en::rx; }
|
||||
let mut type_ = TypeEn::TxRx;
|
||||
if trans_type == "TxRx" { type_ = TypeEn::TxRx; }
|
||||
else if trans_type == "Tx" { type_ = TypeEn::Rx; }
|
||||
else if trans_type == "RxTx" { type_ = TypeEn::RxTx; }
|
||||
else if trans_type == "Rx" { type_ = TypeEn::Rx; }
|
||||
|
||||
let mut filename = format!("../log/data_{}.log", Perf::cur_time("%Y%m%d"));
|
||||
let data_writer = Logger::new(filename.clone(), save_data_flag)?;
|
||||
filename = format!("../log/commands_{}.log", Perf::cur_time("%Y%m%d"));
|
||||
let cmd_writer = Logger::new(filename.clone(), save_data_flag)?;
|
||||
|
||||
let mut port = serialport::new(port_name.clone(), port_settings.baud_rate)
|
||||
let port = serialport::new(port_name, port_settings.baud_rate)
|
||||
.timeout(Duration::from_millis(port_settings.timeout_msec)).open().unwrap();
|
||||
|
||||
let tx_packet = String::new();
|
||||
@ -228,7 +217,7 @@ pub mod uartTransact {
|
||||
}
|
||||
|
||||
|
||||
pub fn addPacketForTx(&mut self, buf: String, size: u32) -> Result<(), String> {
|
||||
pub fn add_packet_for_tx(&mut self, buf: String, size: u32) -> Result<(), String> {
|
||||
if size as usize >= MAX_BUF {
|
||||
return Err(format!("too much data for transmit! Data size must be < {} bytes", MAX_BUF));
|
||||
}
|
||||
@ -237,9 +226,9 @@ pub mod uartTransact {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
pub fn startTransact(&mut self) -> Result<(), String> {
|
||||
pub fn start_transact(&mut self) -> Result<(), String> {
|
||||
|
||||
if self.type_ == Type_en::tx_rx {
|
||||
if self.type_ == TypeEn::TxRx {
|
||||
self.cmd_writer.log(&self.tx_packet).unwrap();
|
||||
|
||||
// println!("write to port: ({:?})", self.tx_packet.as_bytes());
|
||||
@ -249,8 +238,6 @@ pub mod uartTransact {
|
||||
Err(e) => eprintln!("Error sending data: {}", e),
|
||||
}
|
||||
|
||||
// self.port.flush().unwrap();
|
||||
|
||||
let mut reader = BufReader::new(&mut self.port);
|
||||
|
||||
let mut s = String::new();
|
||||
@ -266,12 +253,12 @@ pub mod uartTransact {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn getReceivedPacket(&mut self) -> String {
|
||||
pub fn get_received_packet(&mut self) -> String {
|
||||
self.rx_packet.clone()
|
||||
}
|
||||
|
||||
fn set_port_settings(port_name: &str,
|
||||
set: PortSettings_t) -> Result<Box<dyn SerialPort>, String> {
|
||||
set: PortSettingsT) -> Result<Box<dyn SerialPort>, String> {
|
||||
|
||||
let mut port = match serialport::new(port_name, set.baud_rate)
|
||||
.timeout(Duration::from_millis(set.timeout_msec)).open() {
|
||||
@ -305,7 +292,7 @@ pub mod uartTransact {
|
||||
}
|
||||
}
|
||||
|
||||
use crate::uartTransact::*;
|
||||
use crate::uart_transact::*;
|
||||
|
||||
fn read_str(s: &str) -> Result<Vec<String>, String> {
|
||||
let re = match Regex::new(r#""([^"]+)"|(\S+)"#) {
|
||||
@ -334,14 +321,20 @@ fn uart_cmd_interp(cmd: &str) -> String {
|
||||
if args_cnt == 0 { return format!("{}", out); }
|
||||
let cmd_head = &args[0].clone();
|
||||
|
||||
if cmd_head.contains("exit") { return format!("exit"); }
|
||||
let mut timeout: u64 = 200;
|
||||
let mut port_set = PortSettingsT::new(9600, 8, "None", 1, "None", timeout).unwrap();
|
||||
let mut save_data_flag = true;
|
||||
let mut save_cmd_flag = true;
|
||||
let mut trans_type = "TxRx";
|
||||
|
||||
if cmd_head == "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"));
|
||||
out.push_str(&format!("\n5. set_port - set port with specified settings\n \tUse: set_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, TxRx, RxTx (tx - transmit, rx - receive) \n\t\t<save_data_flags>: true, false \n\tExample: set_port /dev/ttyUSB0 9600 8 Even 1 None 1000 TxRx true\n"));
|
||||
return out;
|
||||
}
|
||||
else if cmd_head.contains("show_ports") {
|
||||
@ -360,63 +353,47 @@ fn uart_cmd_interp(cmd: &str) -> String {
|
||||
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 uart_trans = 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();
|
||||
uart_trans.add_packet_for_tx(data_out.clone(), data_out.len() as u32).unwrap();
|
||||
uart_trans.start_transact().unwrap();
|
||||
|
||||
let s = uartTrans.getReceivedPacket();
|
||||
let s = uart_trans.get_received_packet();
|
||||
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") {
|
||||
else if cmd_head.contains("set_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[2].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];
|
||||
timeout = args[7].parse::<u64>().unwrap();
|
||||
trans_type = &args[8];
|
||||
save_data_flag = args[9].parse::<bool>().unwrap();
|
||||
save_cmd_flag = save_data_flag;
|
||||
|
||||
// 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;
|
||||
port_set = PortSettingsT::new(speed, data_bits, parity, stop_bits,
|
||||
flow_ctrl, timeout).unwrap();
|
||||
|
||||
// let port_set = PortSettings_t::new(speed, data_bits, parity, stop_bits,
|
||||
// flow_ctrl, timeout).unwrap();
|
||||
let uart_trans = UartTransact::new(trans_type, &port_name,
|
||||
port_set.clone(), save_data_flag, save_cmd_flag).unwrap();
|
||||
|
||||
// let mut uartTrans = UartTransact::new(trans_type, &port_name,
|
||||
// port_set, save_data_flag, save_cmd_flag).unwrap();
|
||||
let data = format!("{}: port {} was set with the following settings: {:?}",
|
||||
Perf::cur_time("%H:%M:%S.%3f"),
|
||||
port_name,
|
||||
port_set);
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
@ -457,7 +434,7 @@ fn cli_mode() {
|
||||
|
||||
let reply = uart_cmd_interp(&s);
|
||||
|
||||
if reply.contains("exit") { break; }
|
||||
if reply == "exit" { break; }
|
||||
else { println!("{}", reply); }
|
||||
|
||||
}
|
||||
@ -485,10 +462,6 @@ fn tcp_server() {
|
||||
}
|
||||
|
||||
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 perf = Perf::new();
|
||||
let mut reader = BufReader::new(&stream);
|
||||
@ -504,15 +477,16 @@ fn handle_client(mut stream: TcpStream) {
|
||||
|
||||
if rx_data.starts_with("send") ||
|
||||
rx_data.starts_with("help") ||
|
||||
rx_data.starts_with("set_port") ||
|
||||
rx_data.starts_with("show_ports") {
|
||||
let mut reply = uart_cmd_interp(&rx_data.trim());
|
||||
let 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;
|
||||
}
|
||||
}
|
||||
// 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;
|
||||
@ -521,7 +495,7 @@ fn handle_client(mut stream: TcpStream) {
|
||||
else if rx_data == "" {
|
||||
let data = format!("empty string! ");
|
||||
|
||||
if let Err(msg) = stream.write_all(rx_data.as_bytes()) {
|
||||
if let Err(msg) = stream.write_all(data.as_bytes()) {
|
||||
println!("error: failed attempt to send data to client: {}", msg);
|
||||
return;
|
||||
}
|
||||
@ -536,7 +510,7 @@ fn handle_client(mut stream: TcpStream) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
perf.stop("speed: ", "mks");
|
||||
}
|
||||
}
|
||||
@ -562,9 +536,9 @@ fn main() {
|
||||
|
||||
}
|
||||
|
||||
fn print_type_of<T>(_: &T) {
|
||||
println!("{}", std::any::type_name::<T>());
|
||||
}
|
||||
// fn print_type_of<T>(_: &T) {
|
||||
// println!("{}", std::any::type_name::<T>());
|
||||
// }
|
||||
|
||||
|
||||
// perf.stop("time for transaction", "mks");
|
||||
|
Loading…
x
Reference in New Issue
Block a user