lesavka/server/src/main.rs

75 lines
2.3 KiB
Rust
Raw Normal View History

2025-06-02 20:41:36 -05:00
//! navka-server — receive HidReport and write to /dev/hidg0
2025-06-01 16:04:00 -05:00
#![forbid(unsafe_code)]
2025-06-01 13:31:22 -05:00
2025-06-02 20:41:36 -05:00
use std::{pin::Pin, sync::Arc};
use tokio::{fs::OpenOptions, io::AsyncWriteExt};
use tokio_stream::{wrappers::ReceiverStream, Stream, StreamExt};
use tonic::{transport::Server, Request, Response, Status};
2025-06-05 22:44:27 -05:00
use tracing::{info, error};
use tracing_subscriber::FmtSubscriber;
2025-06-01 21:26:57 -05:00
2025-06-01 16:04:00 -05:00
use navka_common::navka::{
2025-06-01 21:26:57 -05:00
relay_server::{Relay, RelayServer},
HidReport,
2025-06-01 16:04:00 -05:00
};
2025-06-02 20:24:00 -05:00
2025-06-02 20:41:36 -05:00
struct Handler {
/// shared async handle to /dev/hidg0
hid: Arc<tokio::sync::Mutex<tokio::fs::File>>,
2025-06-01 16:04:00 -05:00
}
2025-06-01 13:31:22 -05:00
2025-06-02 20:41:36 -05:00
#[tonic::async_trait]
impl Relay for Handler {
type StreamStream =
Pin<Box<dyn Stream<Item = Result<HidReport, Status>> + Send + 'static>>;
2025-06-01 13:31:22 -05:00
async fn stream(
&self,
request: Request<tonic::Streaming<HidReport>>,
2025-06-02 20:24:30 -05:00
) -> Result<Response<Self::StreamStream>, Status> {
2025-06-02 20:41:36 -05:00
let mut in_stream = request.into_inner();
let hid = self.hid.clone();
// echo everything back to caller & push down USB
let (tx, rx) = tokio::sync::mpsc::channel(32);
tokio::spawn(async move {
while let Some(msg) = in_stream.next().await.transpose()? {
// 1) write to /dev/hidg0
let mut file = hid.lock().await;
file.write_all(&msg.data).await.map_err(|e| Status::internal(e.to_string()))?;
file.flush().await.ok();
2025-06-05 22:44:27 -05:00
// 2) structured log (shows hex + length)
info!(bytes = ?msg.data, len = msg.data.len(), "HID report received");
// 3) echo back
2025-06-02 20:41:36 -05:00
tx.send(Ok(msg)).await.ok();
2025-06-01 13:31:22 -05:00
}
2025-06-02 20:41:36 -05:00
Ok::<_, Status>(())
2025-06-01 13:31:22 -05:00
});
2025-06-02 20:41:36 -05:00
Ok(Response::new(Box::pin(ReceiverStream::new(rx))))
2025-06-01 13:31:22 -05:00
}
}
#[tokio::main]
2025-06-02 20:41:36 -05:00
async fn main() -> anyhow::Result<()> {
2025-06-05 22:44:27 -05:00
let subscriber = FmtSubscriber::builder().with_target(false).finish();
tracing::subscriber::set_global_default(subscriber)?;
2025-06-02 20:41:36 -05:00
let file = OpenOptions::new()
.write(true)
.open("/dev/hidg0")
.await?;
let hid = Arc::new(tokio::sync::Mutex::new(file));
let handler = Handler { hid };
2025-06-01 16:04:00 -05:00
2025-06-02 20:41:36 -05:00
println!("🌐 navka-server listening on 0.0.0.0:50051");
2025-06-01 13:31:22 -05:00
Server::builder()
2025-06-02 20:41:36 -05:00
.add_service(RelayServer::new(handler))
.serve(([0, 0, 0, 0], 50051).into())
2025-06-01 13:31:22 -05:00
.await?;
Ok(())
}