feat: Phase 2 — relay daemon and client library with integration pipelines

wzp-relay:
- RelayPipeline: ingest → FEC decode → jitter buffer → FEC encode → send
- SessionManager: tracks active calls, idle expiry
- RelayConfig: TOML-based configuration
- Binary: accepts QUIC connections, receives media packets

wzp-client:
- CallEncoder: mic PCM → Opus encode → FEC → MediaPackets
- CallDecoder: MediaPackets → FEC decode → jitter → Opus decode → PCM
- CLI binary: connects to relay, sends test silence frames

99 tests passing across all 7 crates.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Siavash Sameni
2026-03-27 13:08:33 +04:00
parent 51e893590c
commit 43d7f70fe9
11 changed files with 1023 additions and 10 deletions

View File

@@ -0,0 +1,66 @@
//! WarzonePhone relay daemon entry point.
use std::sync::Arc;
use tokio::sync::Mutex;
use tracing::{error, info};
use wzp_proto::MediaTransport;
use wzp_relay::config::RelayConfig;
use wzp_relay::session_mgr::SessionManager;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let config = RelayConfig::default();
tracing_subscriber::fmt().init();
info!(addr = %config.listen_addr, "WarzonePhone relay starting");
let (server_config, _cert_der) = wzp_transport::server_config();
let endpoint =
wzp_transport::create_endpoint(config.listen_addr, Some(server_config))?;
let sessions = Arc::new(Mutex::new(SessionManager::new(config.max_sessions)));
info!("Listening for connections...");
loop {
let connection = match wzp_transport::accept(&endpoint).await {
Ok(conn) => conn,
Err(e) => {
error!("accept error: {e}");
continue;
}
};
let _sessions = sessions.clone();
tokio::spawn(async move {
let remote = connection.remote_address();
info!(%remote, "new connection");
let transport = wzp_transport::QuinnTransport::new(connection);
loop {
match transport.recv_media().await {
Ok(Some(packet)) => {
tracing::trace!(
seq = packet.header.seq,
block = packet.header.fec_block,
"received media packet"
);
}
Ok(None) => {
info!(%remote, "connection closed");
break;
}
Err(e) => {
error!(%remote, "recv error: {e}");
break;
}
}
}
});
}
}