pub mod tasks;
#[non_exhaustive]
#[derive(Debug)]
pub enum SerialMessage {
Write(Vec<u8>),
SendBreak,
Shutdown,
}
#[non_exhaustive]
#[derive(Clone, Debug)]
pub enum SerialEvent {
Data(std::sync::Arc<[u8]>),
Error(String),
ConnectionClosed,
}
pub struct SerialActor {
connection: serial2_tokio::SerialPort,
command_rx: tokio::sync::mpsc::Receiver<SerialMessage>,
broadcast_channel: tokio::sync::broadcast::Sender<SerialEvent>,
}
impl SerialActor {
pub fn new(
connection: serial2_tokio::SerialPort,
command_rx: tokio::sync::mpsc::Receiver<SerialMessage>,
broadcast_channel: tokio::sync::broadcast::Sender<SerialEvent>,
) -> Self {
Self {
connection,
command_rx,
broadcast_channel,
}
}
pub async fn run(mut self) {
let mut buffer = vec![0u8; 4096];
loop {
tokio::select! {
cmd = self.command_rx.recv() => {
match cmd {
Some(SerialMessage::Write(data)) => {
if let Err(e) = self.connection.write_all(&data).await {
self.broadcast_channel.send(SerialEvent::Error(e.to_string())).ok();
}
}
Some(SerialMessage::Shutdown) => {
self.broadcast_channel.send(SerialEvent::ConnectionClosed).ok();
}
Some(SerialMessage::SendBreak) => {
self.send_break().await;
}
None => break,
}
}
read_result = self.connection.read(&mut buffer) => {
match read_result {
Ok(0) => {
self.broadcast_channel.send(SerialEvent::ConnectionClosed).ok();
break;
}
Ok(n) => {
let data: std::sync::Arc<[u8]> = buffer[..n].into();
self.broadcast_channel.send(SerialEvent::Data(data)).ok();
}
Err(e) => {
self.broadcast_channel.send(SerialEvent::Error(e.to_string())).ok();
break;
}
}
}
}
}
}
async fn send_break(&mut self) {
use tokio::time::{Duration, sleep};
let _ = self.connection.set_break(true);
sleep(Duration::from_millis(500)).await;
let _ = self.connection.set_break(false);
}
}