use crate::config::OmnimeshMode;
use crate::config::modes::TransportType;
use crate::envelope::{Did, SignedEnvelope};
use crate::runtime::transport::config::TransportConfig;
use crate::runtime::transport::interface::{DEFAULT_PAYLOAD_CAPACITY, Transport};
use crate::runtime::transport::mock::MockTransport;
use crate::runtime::transport::quic::QuicTransport;
use crate::runtime::transport::tcp::TcpTransport;
#[derive(Debug)]
pub struct TransportLayer {
transport: Box<dyn Transport>,
config: TransportConfig,
#[allow(dead_code)]
routing: std::sync::Arc<crate::runtime::RoutingTable>,
}
impl TransportLayer {
pub fn new(mode: &OmnimeshMode) -> Result<Self, String> {
let config = TransportConfig::default();
let routing = std::sync::Arc::new(crate::runtime::RoutingTable::new());
let transport: Box<dyn Transport> = match mode.transport_type() {
TransportType::Mock => Box::new(MockTransport::new(routing.clone())),
TransportType::Tcp => Box::new(TcpTransport::new(config.clone(), routing.clone())?),
TransportType::Quic => Box::new(QuicTransport::new(config.clone(), routing.clone())?),
};
if !matches!(mode.transport_type(), TransportType::Mock) {
let gossip_addr = config.tcp_listen_addr;
let broadcast_addr: std::net::SocketAddr = "255.255.255.255:9999".parse().unwrap();
routing
.clone()
.start_gossip_task(1000, gossip_addr, broadcast_addr);
}
Ok(TransportLayer {
transport,
config,
routing,
})
}
pub fn new_with_did(mode: &OmnimeshMode, local_did: Did) -> Result<Self, String> {
let config = TransportConfig::default();
let routing = std::sync::Arc::new(crate::runtime::RoutingTable::new());
let transport: Box<dyn Transport> = match mode.transport_type() {
TransportType::Mock => {
Box::new(MockTransport::new(routing.clone()).with_did(local_did))
}
TransportType::Tcp => Box::new(TcpTransport::new(config.clone(), routing.clone())?),
TransportType::Quic => Box::new(QuicTransport::new(config.clone(), routing.clone())?),
};
if !matches!(mode.transport_type(), TransportType::Mock) {
let gossip_addr = config.tcp_listen_addr;
let broadcast_addr: std::net::SocketAddr = "255.255.255.255:9999".parse().unwrap();
routing
.clone()
.start_gossip_task(1000, gossip_addr, broadcast_addr);
}
Ok(TransportLayer {
transport,
config,
routing,
})
}
pub fn with_config(mode: &OmnimeshMode, config: TransportConfig) -> Result<Self, String> {
let routing = std::sync::Arc::new(crate::runtime::RoutingTable::new());
Self::with_config_and_routing(mode, config, routing)
}
pub fn with_config_and_routing(
mode: &OmnimeshMode,
config: TransportConfig,
routing: std::sync::Arc<crate::runtime::RoutingTable>,
) -> Result<Self, String> {
let transport: Box<dyn Transport> = match mode.transport_type() {
TransportType::Mock => Box::new(MockTransport::new(routing.clone())),
TransportType::Tcp => Box::new(TcpTransport::new(config.clone(), routing.clone())?),
TransportType::Quic => Box::new(QuicTransport::new(config.clone(), routing.clone())?),
};
if !matches!(mode.transport_type(), TransportType::Mock) {
let gossip_addr = config.tcp_listen_addr;
let broadcast_addr: std::net::SocketAddr = "255.255.255.255:9999".parse().unwrap();
routing
.clone()
.start_gossip_task(1000, gossip_addr, broadcast_addr);
}
Ok(TransportLayer {
transport,
config,
routing,
})
}
pub fn initialize(&self) -> Result<(), String> {
println!("Initializing transport layer: {}", self.transport.kind());
Ok(())
}
pub fn kind(&self) -> &'static str {
self.transport.kind()
}
pub fn receive(&self) -> Option<SignedEnvelope<DEFAULT_PAYLOAD_CAPACITY>> {
self.transport.receive()
}
pub fn send(&self, envelope: &SignedEnvelope<DEFAULT_PAYLOAD_CAPACITY>) -> Result<(), String> {
self.transport.send(envelope)
}
pub fn config(&self) -> &TransportConfig {
&self.config
}
}