uart server works correctly in CLI and TCP mode
This commit is contained in:
parent
120aaadbb9
commit
90bd7fbae9
84
README.markdown
Normal file
84
README.markdown
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
# uart_server
|
||||||
|
|
||||||
|
The uart server is intended for work with serial ports (COM-ports): UART (RS232), RS485 via RS485-USB and etc. interface converters
|
||||||
|
|
||||||
|
## Contents
|
||||||
|
|
||||||
|
- **Setup**
|
||||||
|
- **Using**
|
||||||
|
- work with uart_server in CLI mode
|
||||||
|
- work with uart_server in TCP mode
|
||||||
|
- **Output uart_server data files description**
|
||||||
|
- **Contacts**
|
||||||
|
|
||||||
|
## Setup
|
||||||
|
1. Install Rust compiler (if you don't have).
|
||||||
|
Installation on Linux:
|
||||||
|
```
|
||||||
|
curl --proto '=https' --tlsv1.2 https://sh.rustup.rs -sSf | sh
|
||||||
|
```
|
||||||
|
|
||||||
|
Installation on Windows:
|
||||||
|
Go to address https://www.rust-lang.org/tools/install and follow instructions
|
||||||
|
For more detailed information you can go to: https://doc.rust-lang.ru/book/ch01-01-installation.html
|
||||||
|
|
||||||
|
**Instruction for setup uart_server project**
|
||||||
|
|
||||||
|
2. Clone the repo to your computer:
|
||||||
|
|
||||||
|
```
|
||||||
|
git clone http://heagit.cosmos.ru/gamkov/uart_server.git
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Enter the repo and compile it:
|
||||||
|
```
|
||||||
|
cd <PATH_TO_UART_SERVER>
|
||||||
|
cargo build --release
|
||||||
|
```
|
||||||
|
|
||||||
|
After running this commands you will get an execution file (uart_server) in the following directory:
|
||||||
|
\<PATH_TO_UART_SERVER\>/target/release/
|
||||||
|
|
||||||
|
## Using
|
||||||
|
### work with uart_server in CLI mode
|
||||||
|
1. See current available serial ports (Ubuntu):
|
||||||
|
```
|
||||||
|
sudo setserial -g /dev/ttyUSB*
|
||||||
|
```
|
||||||
|
2. for access to operation with hardware run program with sudo (specify available serial port):
|
||||||
|
```
|
||||||
|
sudo ./uart_server -m cli -p /dev/ttyUSB1
|
||||||
|
```
|
||||||
|
3. In cli mode type 'help' in order to get information about programs command system
|
||||||
|
|
||||||
|
### work with uart_server in TCP mode
|
||||||
|
1. See current available serial ports (Ubuntu):
|
||||||
|
```
|
||||||
|
sudo setserial -g /dev/ttyUSB*
|
||||||
|
```
|
||||||
|
2. for access to operation with hardware run program with sudo (specify available serial port and desired IP-address, port for uart-server):
|
||||||
|
```
|
||||||
|
sudo ./uart_server -m tcp:127.0.0.1:10000 -p /dev/ttyUSB1
|
||||||
|
```
|
||||||
|
## Output uart_server data files description
|
||||||
|
log files are located in directory:
|
||||||
|
\<PATH_TO_UART_SERVER\>/log/
|
||||||
|
|
||||||
|
**description:**
|
||||||
|
cmd_\<data\>\_\<user_name_file\>.log - file with output data to serial port
|
||||||
|
data_\<data\>\_\<user_name_file\>.log - file with input data from serial port
|
||||||
|
cmd_data_\<data\>\_\<user_name_file\>.log - file with output and input data to and from serial port
|
||||||
|
|
||||||
|
where \<data\> - file generation date,
|
||||||
|
\<user_name_file\> - user filename addition (for more information type help in CLI mode)
|
||||||
|
|
||||||
|
**File data log fromat:**
|
||||||
|
data represented in csv-format (with \';\' separation)
|
||||||
|
*column 1:* timestamp in format: YYYY.mm.dd HH:MM:SS.zzz (for example: 2025.03.26 16:00:01.158)
|
||||||
|
*column 2 for cmd and cmd_data log files:* data that was sent to the serial port
|
||||||
|
*column 2 for data log file:* data that was received from serial port
|
||||||
|
*column 3 for cmd_data log file:* data that was received from serial port
|
||||||
|
*column 3 for cmd and data log files:* no data available
|
||||||
|
|
||||||
|
## Contatcs
|
||||||
|
For questions about the program, please contact Danila Gamkov, mail: danila_gamkov@cosmos.ru
|
BIN
release/uart_server
Executable file
BIN
release/uart_server
Executable file
Binary file not shown.
178
src/main.rs
178
src/main.rs
@ -146,7 +146,10 @@ pub mod uart_transact {
|
|||||||
|
|
||||||
let file = match path.exists() {
|
let file = match path.exists() {
|
||||||
true => OpenOptions::new().write(true).append(true).open(filename.as_ref())?,
|
true => OpenOptions::new().write(true).append(true).open(filename.as_ref())?,
|
||||||
false => File::create(filename.as_ref())?
|
false => {
|
||||||
|
println!("path: {:?}", path);
|
||||||
|
File::create(filename.as_ref())?
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
let out = BufWriter::new(file);
|
let out = BufWriter::new(file);
|
||||||
@ -185,12 +188,13 @@ pub mod uart_transact {
|
|||||||
tx_packet: String,
|
tx_packet: String,
|
||||||
rx_packet: String,
|
rx_packet: String,
|
||||||
|
|
||||||
port: Box<dyn SerialPort>,
|
pub port: Box<dyn SerialPort>,
|
||||||
save_data_flag: bool,
|
save_data_flag: bool,
|
||||||
save_cmd_flag: bool,
|
save_cmd_flag: bool,
|
||||||
data_writer: Logger,
|
data_writer: Logger,
|
||||||
cmd_writer: Logger,
|
cmd_writer: Logger,
|
||||||
cmd_data_writer: Logger,
|
cmd_data_writer: Logger,
|
||||||
|
specific_fname: String
|
||||||
}
|
}
|
||||||
|
|
||||||
impl UartTransact {
|
impl UartTransact {
|
||||||
@ -198,7 +202,8 @@ pub mod uart_transact {
|
|||||||
port_name: &str,
|
port_name: &str,
|
||||||
port_settings: PortSettingsT,
|
port_settings: PortSettingsT,
|
||||||
save_data_flag: bool,
|
save_data_flag: bool,
|
||||||
save_cmd_flag: bool) -> Result<Self, io::Error> {
|
save_cmd_flag: bool,
|
||||||
|
specific_fname: &str) -> Result<Self, io::Error> {
|
||||||
|
|
||||||
let mut type_ = TypeEn::TxRx;
|
let mut type_ = TypeEn::TxRx;
|
||||||
if trans_type == "TxRx" { type_ = TypeEn::TxRx; }
|
if trans_type == "TxRx" { type_ = TypeEn::TxRx; }
|
||||||
@ -206,17 +211,23 @@ pub mod uart_transact {
|
|||||||
else if trans_type == "RxTx" { type_ = TypeEn::RxTx; }
|
else if trans_type == "RxTx" { type_ = TypeEn::RxTx; }
|
||||||
else if trans_type == "Rx" { type_ = TypeEn::Rx; }
|
else if trans_type == "Rx" { type_ = TypeEn::Rx; }
|
||||||
|
|
||||||
let mut filename = format!("../log/data_{}.log", Perf::cur_time("%Y%m%d"));
|
let mut filename = format!("../log/data_{}_{}.log",
|
||||||
|
Perf::cur_time("%Y%m%d"),
|
||||||
|
specific_fname);
|
||||||
let data_writer = Logger::new(filename.clone(), save_data_flag)?;
|
let data_writer = Logger::new(filename.clone(), save_data_flag)?;
|
||||||
filename = format!("../log/commands_{}.log", Perf::cur_time("%Y%m%d"));
|
filename = format!("../log/cmd_{}_{}.log",
|
||||||
|
Perf::cur_time("%Y%m%d"),
|
||||||
|
specific_fname);
|
||||||
let cmd_writer = Logger::new(filename.clone(), save_data_flag)?;
|
let cmd_writer = Logger::new(filename.clone(), save_data_flag)?;
|
||||||
filename = format!("../log/cmd_data_{}.log", Perf::cur_time("%Y%m%d"));
|
filename = format!("../log/cmd_data_{}_{}.log",
|
||||||
|
Perf::cur_time("%Y%m%d"),
|
||||||
|
specific_fname);
|
||||||
let cmd_data_writer = Logger::new(filename.clone(), save_data_flag)?;
|
let cmd_data_writer = Logger::new(filename.clone(), save_data_flag)?;
|
||||||
|
|
||||||
let mut port = Self::set_port_settings(port_name,
|
let port = Self::open_port_settings(port_name,
|
||||||
port_settings.clone()).unwrap();
|
port_settings.clone()).unwrap();
|
||||||
|
|
||||||
println!("{:#?}", port);
|
// println!("port: {:#?}", port);
|
||||||
let tx_packet = String::new();
|
let tx_packet = String::new();
|
||||||
let rx_packet = String::new();
|
let rx_packet = String::new();
|
||||||
|
|
||||||
@ -231,6 +242,7 @@ pub mod uart_transact {
|
|||||||
port,
|
port,
|
||||||
tx_packet,
|
tx_packet,
|
||||||
rx_packet,
|
rx_packet,
|
||||||
|
specific_fname: specific_fname.to_string(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -244,9 +256,10 @@ pub mod uart_transact {
|
|||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn start_transact(&mut self) -> Result<(), String> {
|
pub fn start_transact(&mut self, type_: &str) ->
|
||||||
|
Result<(), String> {
|
||||||
|
|
||||||
if self.type_ == TypeEn::TxRx {
|
if type_ == "txRx" {
|
||||||
self.cmd_writer.log(&self.tx_packet).unwrap();
|
self.cmd_writer.log(&self.tx_packet).unwrap();
|
||||||
|
|
||||||
match self.port.write(&self.tx_packet.as_bytes()) {
|
match self.port.write(&self.tx_packet.as_bytes()) {
|
||||||
@ -259,7 +272,10 @@ pub mod uart_transact {
|
|||||||
let mut reader = BufReader::new(&mut self.port);
|
let mut reader = BufReader::new(&mut self.port);
|
||||||
let mut s = String::new();
|
let mut s = String::new();
|
||||||
if let Err(err) = reader.read_line(&mut s) {
|
if let Err(err) = reader.read_line(&mut s) {
|
||||||
println!("error: {}", err);
|
let msg = format!("serial port error: {}", err);
|
||||||
|
self.rx_packet = msg.clone();
|
||||||
|
self.data_writer.log(&msg).unwrap();
|
||||||
|
self.cmd_data_writer.log_cmd_data(&self.tx_packet, &msg).unwrap();
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -269,6 +285,18 @@ pub mod uart_transact {
|
|||||||
self.cmd_data_writer.log_cmd_data(&self.tx_packet, &s).unwrap();
|
self.cmd_data_writer.log_cmd_data(&self.tx_packet, &s).unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if type_ == "tx" {
|
||||||
|
self.cmd_writer.log(&self.tx_packet).unwrap();
|
||||||
|
self.cmd_data_writer.log_cmd_data(&self.tx_packet,
|
||||||
|
"").unwrap();
|
||||||
|
|
||||||
|
match self.port.write(&self.tx_packet.as_bytes()) {
|
||||||
|
Ok(_) => {},
|
||||||
|
Err(e) => eprintln!("Error sending data: {}", e),
|
||||||
|
}
|
||||||
|
|
||||||
|
self.port.flush().unwrap();
|
||||||
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -276,7 +304,7 @@ pub mod uart_transact {
|
|||||||
self.rx_packet.clone()
|
self.rx_packet.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_port_settings(port_name: &str,
|
fn open_port_settings(port_name: &str,
|
||||||
set: PortSettingsT) -> Result<Box<dyn SerialPort>, String> {
|
set: PortSettingsT) -> Result<Box<dyn SerialPort>, String> {
|
||||||
|
|
||||||
let mut port = match serialport::new(port_name, set.baud_rate)
|
let mut port = match serialport::new(port_name, set.baud_rate)
|
||||||
@ -326,7 +354,7 @@ fn read_str(s: &str) -> Result<Vec<String>, String> {
|
|||||||
Ok(res)
|
Ok(res)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn uart_cmd_interp(cmd: &str) -> String {
|
fn uart_cmd_interp(cmd: &str, uart_trans: &mut UartTransact) -> String {
|
||||||
let mut out = String::new();
|
let mut out = String::new();
|
||||||
|
|
||||||
let args = match read_str(&cmd) {
|
let args = match read_str(&cmd) {
|
||||||
@ -338,25 +366,19 @@ fn uart_cmd_interp(cmd: &str) -> String {
|
|||||||
|
|
||||||
let args_cnt = args.len();
|
let args_cnt = args.len();
|
||||||
if args_cnt == 0 { return format!("{}", out); }
|
if args_cnt == 0 { return format!("{}", out); }
|
||||||
let cmd_head = &args[0].clone();
|
let cmd_head = &args[0].trim();
|
||||||
|
|
||||||
let mut timeout: u64 = 1000;
|
if *cmd_head == "exit" { return format!("exit"); }
|
||||||
let mut port_set = PortSettingsT::new(19200, 8, "Even", 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") {
|
else if cmd_head.contains("help") {
|
||||||
out.push_str(&format!("Serial port terminal supports the following commands:"));
|
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!("\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!("\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!("\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!("\n4. send - \t\tsends specified <data> to serial port\n\tUse: send <transaction mode: txRx or tx> <data>\n\tExample: send txRx \"command data1 data2\""));
|
||||||
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"));
|
out.push_str(&format!("\n5. open_port - open serial port with specified settings\n \tUse: open_port <port_name> <speed> <data_bits> <parity> <stop_bits> <flow_ctrl> <timeout> <transact_type> <save_data_flags> <specific filename>\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\t\t<specific filename>: specify a specific string that will be added to the filename for logging commands and data \n\tExample: open_port /dev/ttyUSB0 9600 8 Even 1 None 1000 TxRx true device1\n"));
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
else if cmd_head.contains("show_ports") {
|
else if *cmd_head == "show_ports" {
|
||||||
match serialport::available_ports() {
|
match serialport::available_ports() {
|
||||||
Ok(ports) => {
|
Ok(ports) => {
|
||||||
for port in ports {
|
for port in ports {
|
||||||
@ -368,33 +390,38 @@ fn uart_cmd_interp(cmd: &str) -> String {
|
|||||||
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
else if cmd_head == "send" {
|
else if *cmd_head == "send" {
|
||||||
if args_cnt != 3 { return format!("Error while parse command! {}", "arguments count must be 2"); }
|
if args_cnt != 3 { return format!("Error while parse command! {}", "arguments count must be 2"); }
|
||||||
else {
|
else {
|
||||||
let port_name = &args[1];
|
let transact_type = &args[1];
|
||||||
// let mut perf = Perf::new();
|
// let mut perf = Perf::new();
|
||||||
// perf.start();
|
// perf.start();
|
||||||
|
// println!("port_set: {:#?}", uart_trans.port);
|
||||||
|
|
||||||
println!("port_set: {:#?}", port_set);
|
|
||||||
let mut uart_trans = UartTransact::new(trans_type, port_name,
|
|
||||||
port_set, save_data_flag, save_cmd_flag).unwrap();
|
|
||||||
|
|
||||||
// perf.stop("time for create port: ", "mks");
|
|
||||||
let mut data_out = args[2].clone();
|
let mut data_out = args[2].clone();
|
||||||
data_out.push_str(std::str::from_utf8(b"\x0D\x0A").unwrap()); // CR + LF
|
data_out.push_str(std::str::from_utf8(b"\x0D\x0A").unwrap()); // CR + LF
|
||||||
|
|
||||||
println!("data out: {:?}", data_out);
|
// perf.stop_restart("time for push_str: ", "mks");
|
||||||
|
// println!("data out: {:?}", data_out);
|
||||||
uart_trans.add_packet_for_tx(data_out.clone(), data_out.len() as u32).unwrap();
|
uart_trans.add_packet_for_tx(data_out.clone(), data_out.len() as u32).unwrap();
|
||||||
uart_trans.start_transact().unwrap();
|
// perf.stop_restart("time for add packet for tx: ", "mks");
|
||||||
|
uart_trans.start_transact(&transact_type).unwrap();
|
||||||
|
// perf.stop_restart("time for transaction: ", "mks");
|
||||||
|
|
||||||
let s = uart_trans.get_received_packet();
|
let mut data = "".to_string();
|
||||||
let data = format!("{}: {}", Perf::cur_time("%H:%M:%S.%3f"), s.trim());
|
|
||||||
|
if transact_type == "txRx" {
|
||||||
|
let s = uart_trans.get_received_packet();
|
||||||
|
data = format!("{}: {}", Perf::cur_time("%H:%M:%S.%3f"), s.trim());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if cmd_head.contains("set_port") {
|
else if *cmd_head == "open_port" {
|
||||||
|
|
||||||
if args_cnt != 10 { return format!("Error while parse command! {}", "arguments count must be 9"); }
|
if args_cnt != 11 { return format!("Error while parse command! {}", "arguments count must be 10"); }
|
||||||
else {
|
else {
|
||||||
let port_name = &args[1];
|
let port_name = &args[1];
|
||||||
let speed = args[2].parse::<u32>().unwrap();
|
let speed = args[2].parse::<u32>().unwrap();
|
||||||
@ -402,17 +429,22 @@ fn uart_cmd_interp(cmd: &str) -> String {
|
|||||||
let parity = &args[4];
|
let parity = &args[4];
|
||||||
let stop_bits = args[5].parse::<u8>().unwrap();
|
let stop_bits = args[5].parse::<u8>().unwrap();
|
||||||
let flow_ctrl = &args[6];
|
let flow_ctrl = &args[6];
|
||||||
timeout = args[7].parse::<u64>().unwrap();
|
let timeout = args[7].parse::<u64>().unwrap();
|
||||||
trans_type = &args[8];
|
let trans_type = &args[8];
|
||||||
save_data_flag = args[9].parse::<bool>().unwrap();
|
let save_data_flag = args[9].parse::<bool>().unwrap();
|
||||||
save_cmd_flag = save_data_flag;
|
let save_cmd_flag = save_data_flag;
|
||||||
|
let specific_fname = &args[10];
|
||||||
|
|
||||||
port_set = PortSettingsT::new(speed, data_bits, parity, stop_bits,
|
let port_set = PortSettingsT::new(speed, data_bits, parity, stop_bits,
|
||||||
flow_ctrl, timeout).unwrap();
|
flow_ctrl, timeout).unwrap();
|
||||||
|
|
||||||
println!("port_set: {:#?}", port_set);
|
// println!("port_set: {:#?}", port_set);
|
||||||
let uart_trans = UartTransact::new(trans_type, &port_name,
|
*uart_trans = UartTransact::new(trans_type,
|
||||||
port_set.clone(), save_data_flag, save_cmd_flag).unwrap();
|
&port_name,
|
||||||
|
port_set.clone(),
|
||||||
|
save_data_flag,
|
||||||
|
save_cmd_flag,
|
||||||
|
&specific_fname).unwrap();
|
||||||
|
|
||||||
let data = format!("{}: port {} was set with the following settings: {:?}",
|
let data = format!("{}: port {} was set with the following settings: {:?}",
|
||||||
Perf::cur_time("%H:%M:%S.%3f"),
|
Perf::cur_time("%H:%M:%S.%3f"),
|
||||||
@ -421,12 +453,14 @@ fn uart_cmd_interp(cmd: &str) -> String {
|
|||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
return "unknown command!".to_string();
|
||||||
|
}
|
||||||
|
|
||||||
return out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fn cli_mode() {
|
fn cli_mode(uart_trans: &mut UartTransact) {
|
||||||
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() {
|
||||||
@ -457,7 +491,7 @@ fn cli_mode() {
|
|||||||
|
|
||||||
editor.add_history_entry(&s);
|
editor.add_history_entry(&s);
|
||||||
|
|
||||||
let reply = uart_cmd_interp(&s);
|
let reply = uart_cmd_interp(&s, uart_trans);
|
||||||
|
|
||||||
if reply == "exit" { break; }
|
if reply == "exit" { break; }
|
||||||
else { println!("{}", reply); }
|
else { println!("{}", reply); }
|
||||||
@ -467,15 +501,15 @@ fn cli_mode() {
|
|||||||
editor.save_history(&fname_hist).unwrap();
|
editor.save_history(&fname_hist).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tcp_server() {
|
fn tcp_server(uart_transact: &mut UartTransact, addr: &str) {
|
||||||
let listener = TcpListener::bind("127.0.0.1:10000").unwrap();
|
let listener = TcpListener::bind(addr).unwrap();
|
||||||
println!("TCP-server is running");
|
println!("TCP-server is running on address: {}", addr);
|
||||||
|
|
||||||
for stream in listener.incoming() {
|
for stream in listener.incoming() {
|
||||||
match stream {
|
match stream {
|
||||||
Ok(stream) => {
|
Ok(stream) => {
|
||||||
println!("connect to client: {:?}", stream);
|
println!("connect to client: {:?}", stream);
|
||||||
handle_client(stream);
|
handle_client(stream, uart_transact);
|
||||||
|
|
||||||
},
|
},
|
||||||
Err(ref msg) => {
|
Err(ref msg) => {
|
||||||
@ -486,7 +520,7 @@ fn tcp_server() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_client(mut stream: TcpStream) {
|
fn handle_client(mut stream: TcpStream, uart_transact: &mut UartTransact) {
|
||||||
loop {
|
loop {
|
||||||
// let mut perf = Perf::new();
|
// let mut perf = Perf::new();
|
||||||
// perf.start();
|
// perf.start();
|
||||||
@ -500,12 +534,15 @@ fn handle_client(mut stream: TcpStream) {
|
|||||||
// println!("rx_data: ({})", rx_data.trim());
|
// println!("rx_data: ({})", rx_data.trim());
|
||||||
if rx_data.starts_with("send") ||
|
if rx_data.starts_with("send") ||
|
||||||
rx_data.starts_with("help") ||
|
rx_data.starts_with("help") ||
|
||||||
rx_data.starts_with("set_port") ||
|
rx_data.starts_with("open_port") ||
|
||||||
rx_data.starts_with("show_ports") {
|
rx_data.starts_with("show_ports") {
|
||||||
let reply = uart_cmd_interp(&rx_data.trim());
|
let reply = uart_cmd_interp(&rx_data.trim(), uart_transact);
|
||||||
|
|
||||||
// reply.push('\n');
|
// reply.push('\n');
|
||||||
println!("rx_uart: ({})", reply.trim());
|
if rx_data.starts_with("send") ||
|
||||||
|
rx_data.starts_with("open_port") {
|
||||||
|
println!("rx_uart: ({})", reply.trim());
|
||||||
|
}
|
||||||
if let Err(msg) = stream.write_all(reply.as_bytes()) {
|
if let Err(msg) = stream.write_all(reply.as_bytes()) {
|
||||||
println!("error: failed attempt to send data to client: {}", msg);
|
println!("error: failed attempt to send data to client: {}", msg);
|
||||||
return;
|
return;
|
||||||
@ -540,20 +577,39 @@ fn handle_client(mut stream: TcpStream) {
|
|||||||
#[derive(Parser, Debug)]
|
#[derive(Parser, Debug)]
|
||||||
#[command(version, author, about, long_about = None)]
|
#[command(version, author, about, long_about = None)]
|
||||||
struct Cli {
|
struct Cli {
|
||||||
/// working mode: tcp - remote control with TCP/IP, cli - command line interface
|
/// working mode:
|
||||||
|
/// tcp:ip:port - remote control with TCP/IP, or cli - command line interface.
|
||||||
|
/// Example1: <uart_server> -m tcp:127.0.0.1:10000.
|
||||||
|
/// Example2: <uart_server> -m cli
|
||||||
#[arg(long, short = 'm', value_name = "MODE")]
|
#[arg(long, short = 'm', value_name = "MODE")]
|
||||||
mode: Option<String>,
|
mode: Option<String>,
|
||||||
|
|
||||||
|
/// port name: type serial port name in order to start working
|
||||||
|
#[arg(long, short = 'p', value_name = "PORT_NAME")]
|
||||||
|
port_name: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|
||||||
let cli = Cli::parse();
|
let cli = Cli::parse();
|
||||||
// println!("{:#?}", cli);
|
|
||||||
|
let mut port_name = "/dev/ttyUSB1".to_string();
|
||||||
|
let port_set = PortSettingsT::new(9600, 8, "None", 1, "None", 1000).unwrap();
|
||||||
|
|
||||||
|
if let Some(port) = &cli.port_name { port_name = port.to_string(); }
|
||||||
|
else
|
||||||
|
{ println!("error: incorrect parameter: PORT_NAME. Type --help"); return; }
|
||||||
|
|
||||||
|
let mut uart_trans = UartTransact::new("TxRx", &port_name,
|
||||||
|
port_set.clone(),
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
"data").unwrap();
|
||||||
|
|
||||||
if let Some(mode) = &cli.mode {
|
if let Some(mode) = &cli.mode {
|
||||||
if mode == "cli" { cli_mode(); }
|
if mode.contains("cli") { cli_mode(&mut uart_trans); }
|
||||||
else if mode == "tcp" { tcp_server(); }
|
else if mode.contains("tcp") { tcp_server(&mut uart_trans, &mode[4..]); }
|
||||||
else { println!("error: incorrect parameter. type --help"); }
|
else { println!("error: incorrect parameter: MODE. type --help"); }
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user