Files
bioz-host-rs/src/tcp.rs
2026-05-03 17:07:08 +02:00

120 lines
4.5 KiB
Rust

use tokio::net::TcpListener;
use tokio::io::{AsyncBufReadExt, AsyncWriteExt, BufReader, BufWriter};
use tokio::sync::mpsc::Sender;
use crate::state::ControlCommand;
pub async fn tcp_command_server(app_control_tx: Sender<ControlCommand>) {
let listener = TcpListener::bind("127.0.0.1:12345").await.unwrap();
println!("TCP command server listening on 12345");
loop {
let (socket, addr) = listener.accept().await.unwrap();
app_control_tx.try_send(ControlCommand::TcpConnected(true)).unwrap();
println!("Client connected: {:?}", addr);
let tx = app_control_tx.clone();
tokio::spawn(async move {
let (reader, writer) = socket.into_split();
let reader = BufReader::new(reader);
let mut writer = BufWriter::new(writer);
let mut lines = reader.lines();
while let Ok(Some(line)) = lines.next_line().await {
println!("Received: {}", line);
match parse_command(&line) {
Some(signal) => {
if tx.send(signal).await.is_ok() {
let _ = writer.write_all(b"OK\n").await;
} else {
let _ = writer.write_all(b"ERR internal channel failure\n").await;
break;
}
}
None => {
let _ = writer.write_all(b"ERR unknown command\n").await;
}
}
let _ = writer.flush().await;
}
println!("Client disconnected: {:?}", addr);
tx.try_send(ControlCommand::TcpConnected(false)).unwrap();
});
}
}
fn parse_command(line: &str) -> Option<ControlCommand> {
let parts: Vec<&str> = line.split_whitespace().collect();
match parts.as_slice() {
// ["SET_FREQ", freq_str] => {
// if let Ok(freq) = freq_str.parse::<f32>() {
// Some(ControlCommand::SetFrequency(freq))
// } else {
// None
// }
// }
// ["SET_LEAD_MODE", mode_str] => {
// match mode_str.to_uppercase().as_str() {
// "LEAD_OFF" => Some(ControlCommand::ChangeLeadMode(crate::state::LeadMode::LeadOff)),
// "LEAD_I" => Some(ControlCommand::ChangeLeadMode(crate::state::LeadMode::LeadI)),
// "LEAD_II" => Some(ControlCommand::ChangeLeadMode(crate::state::LeadMode::LeadII)),
// "LEAD_III" => Some(ControlCommand::ChangeLeadMode(crate::state::LeadMode::LeadIII)),
// _ => None,
// }
// }
// ["SET_DFT_NUM", dft_num_str] => {
// if let Ok(dft_num) = dft_num_str.parse::<u32>() {
// Some(ControlCommand::ChangeDftNum(IcdDftNum(dft_num)))
// } else {
// None
// }
// }
// ["SET_SWEEP_POINTS", sweep_points_str] => {
// if let Ok(sweep_points) = sweep_points_str.parse::<u32>() {
// Some(ControlCommand::ChangeSweepPoints(SweepPoints(sweep_points)))
// } else {
// None
// }
// }
// ["SET_ELECTRODE_CONFIG", config_str] => {
// // Example: "SET_ELECTRODE_CONFIG 1,0,1,0,1,0,1,0"
// let config_parts: Vec<&str> = config_str.split(',').collect();
// if config_parts.len() == 8 {
// let mut config = [false; 8];
// for (i, part) in config_parts.iter().enumerate() {
// if let Ok(val) = part.parse::<u8>() {
// config[i] = val != 0;
// } else {
// return None;
// }
// }
// Some(ControlCommand::ChangeElectrodeSettings(crate::state::ElectrodeSettings(config)))
// } else {
// None
// }
// }
["START", mode_str] => {
match mode_str.to_uppercase().as_str() {
"SINGLE" => {
Some(ControlCommand::Start(crate::state::Mode::Single))
},
"SWEEP" => {
Some(ControlCommand::Start(crate::state::Mode::Sweep))
},
_ => None,
}
}
["STOP"] => Some(ControlCommand::Stop),
_ => {
eprintln!("Unknown command: {}", line);
None
}
}
}