#[cfg(target_os = "linux")]
use super::ble::DefaultBleTransport;
#[cfg(any(target_os = "linux", target_os = "macos"))]
use super::ethernet::EthernetTransport;
#[cfg(feature = "sim-transport")]
use super::sim::SimTransport;
use super::tcp::TcpTransport;
use super::tor::TorTransport;
use super::tor::control::TorMonitoringInfo;
use super::udp::UdpTransport;
#[cfg(feature = "webrtc-transport")]
use super::webrtc::WebRtcTransport;
use super::{
ConnectionState, DiscoveredPeer, Transport, TransportAddr, TransportCongestion, TransportError,
TransportId, TransportState, TransportType,
};
pub enum TransportHandle {
Udp(UdpTransport),
#[cfg(feature = "sim-transport")]
Sim(SimTransport),
#[cfg(any(target_os = "linux", target_os = "macos"))]
Ethernet(EthernetTransport),
Tcp(TcpTransport),
Tor(TorTransport),
#[cfg(feature = "webrtc-transport")]
WebRtc(Box<WebRtcTransport>),
#[cfg(target_os = "linux")]
Ble(DefaultBleTransport),
}
impl TransportHandle {
pub async fn start(&mut self) -> Result<(), TransportError> {
match self {
TransportHandle::Udp(t) => t.start_async().await,
#[cfg(feature = "sim-transport")]
TransportHandle::Sim(t) => t.start_async().await,
#[cfg(any(target_os = "linux", target_os = "macos"))]
TransportHandle::Ethernet(t) => t.start_async().await,
TransportHandle::Tcp(t) => t.start_async().await,
TransportHandle::Tor(t) => t.start_async().await,
#[cfg(feature = "webrtc-transport")]
TransportHandle::WebRtc(t) => t.start_async().await,
#[cfg(target_os = "linux")]
TransportHandle::Ble(t) => t.start_async().await,
}
}
pub async fn stop(&mut self) -> Result<(), TransportError> {
match self {
TransportHandle::Udp(t) => t.stop_async().await,
#[cfg(feature = "sim-transport")]
TransportHandle::Sim(t) => t.stop_async().await,
#[cfg(any(target_os = "linux", target_os = "macos"))]
TransportHandle::Ethernet(t) => t.stop_async().await,
TransportHandle::Tcp(t) => t.stop_async().await,
TransportHandle::Tor(t) => t.stop_async().await,
#[cfg(feature = "webrtc-transport")]
TransportHandle::WebRtc(t) => t.stop_async().await,
#[cfg(target_os = "linux")]
TransportHandle::Ble(t) => t.stop_async().await,
}
}
pub async fn send(&self, addr: &TransportAddr, data: &[u8]) -> Result<usize, TransportError> {
match self {
TransportHandle::Udp(t) => t.send_async(addr, data).await,
#[cfg(feature = "sim-transport")]
TransportHandle::Sim(t) => t.send_async(addr, data).await,
#[cfg(any(target_os = "linux", target_os = "macos"))]
TransportHandle::Ethernet(t) => t.send_async(addr, data).await,
TransportHandle::Tcp(t) => t.send_async(addr, data).await,
TransportHandle::Tor(t) => t.send_async(addr, data).await,
#[cfg(feature = "webrtc-transport")]
TransportHandle::WebRtc(t) => t.send_async(addr, data).await,
#[cfg(target_os = "linux")]
TransportHandle::Ble(t) => t.send_async(addr, data).await,
}
}
pub fn transport_id(&self) -> TransportId {
match self {
TransportHandle::Udp(t) => t.transport_id(),
#[cfg(feature = "sim-transport")]
TransportHandle::Sim(t) => t.transport_id(),
#[cfg(any(target_os = "linux", target_os = "macos"))]
TransportHandle::Ethernet(t) => t.transport_id(),
TransportHandle::Tcp(t) => t.transport_id(),
TransportHandle::Tor(t) => t.transport_id(),
#[cfg(feature = "webrtc-transport")]
TransportHandle::WebRtc(t) => t.transport_id(),
#[cfg(target_os = "linux")]
TransportHandle::Ble(t) => t.transport_id(),
}
}
pub fn name(&self) -> Option<&str> {
match self {
TransportHandle::Udp(t) => t.name(),
#[cfg(feature = "sim-transport")]
TransportHandle::Sim(t) => t.name(),
#[cfg(any(target_os = "linux", target_os = "macos"))]
TransportHandle::Ethernet(t) => t.name(),
TransportHandle::Tcp(t) => t.name(),
TransportHandle::Tor(t) => t.name(),
#[cfg(feature = "webrtc-transport")]
TransportHandle::WebRtc(t) => t.name(),
#[cfg(target_os = "linux")]
TransportHandle::Ble(t) => t.name(),
}
}
pub fn transport_type(&self) -> &TransportType {
match self {
TransportHandle::Udp(t) => t.transport_type(),
#[cfg(feature = "sim-transport")]
TransportHandle::Sim(t) => t.transport_type(),
#[cfg(any(target_os = "linux", target_os = "macos"))]
TransportHandle::Ethernet(t) => t.transport_type(),
TransportHandle::Tcp(t) => t.transport_type(),
TransportHandle::Tor(t) => t.transport_type(),
#[cfg(feature = "webrtc-transport")]
TransportHandle::WebRtc(t) => t.transport_type(),
#[cfg(target_os = "linux")]
TransportHandle::Ble(t) => t.transport_type(),
}
}
pub fn state(&self) -> TransportState {
match self {
TransportHandle::Udp(t) => t.state(),
#[cfg(feature = "sim-transport")]
TransportHandle::Sim(t) => t.state(),
#[cfg(any(target_os = "linux", target_os = "macos"))]
TransportHandle::Ethernet(t) => t.state(),
TransportHandle::Tcp(t) => t.state(),
TransportHandle::Tor(t) => t.state(),
#[cfg(feature = "webrtc-transport")]
TransportHandle::WebRtc(t) => t.state(),
#[cfg(target_os = "linux")]
TransportHandle::Ble(t) => t.state(),
}
}
pub fn mtu(&self) -> u16 {
match self {
TransportHandle::Udp(t) => t.mtu(),
#[cfg(feature = "sim-transport")]
TransportHandle::Sim(t) => t.mtu(),
#[cfg(any(target_os = "linux", target_os = "macos"))]
TransportHandle::Ethernet(t) => t.mtu(),
TransportHandle::Tcp(t) => t.mtu(),
TransportHandle::Tor(t) => t.mtu(),
#[cfg(feature = "webrtc-transport")]
TransportHandle::WebRtc(t) => t.mtu(),
#[cfg(target_os = "linux")]
TransportHandle::Ble(t) => t.mtu(),
}
}
pub fn link_mtu(&self, addr: &TransportAddr) -> u16 {
match self {
TransportHandle::Udp(t) => t.link_mtu(addr),
#[cfg(feature = "sim-transport")]
TransportHandle::Sim(t) => t.link_mtu(addr),
#[cfg(any(target_os = "linux", target_os = "macos"))]
TransportHandle::Ethernet(t) => t.link_mtu(addr),
TransportHandle::Tcp(t) => t.link_mtu(addr),
TransportHandle::Tor(t) => t.link_mtu(addr),
#[cfg(feature = "webrtc-transport")]
TransportHandle::WebRtc(t) => t.link_mtu(addr),
#[cfg(target_os = "linux")]
TransportHandle::Ble(t) => t.link_mtu(addr),
}
}
pub fn local_addr(&self) -> Option<std::net::SocketAddr> {
match self {
TransportHandle::Udp(t) => t.local_addr(),
#[cfg(feature = "sim-transport")]
TransportHandle::Sim(_) => None,
#[cfg(any(target_os = "linux", target_os = "macos"))]
TransportHandle::Ethernet(_) => None,
TransportHandle::Tcp(t) => t.local_addr(),
TransportHandle::Tor(_) => None,
#[cfg(feature = "webrtc-transport")]
TransportHandle::WebRtc(_) => None,
#[cfg(target_os = "linux")]
TransportHandle::Ble(_) => None,
}
}
pub fn interface_name(&self) -> Option<&str> {
match self {
TransportHandle::Udp(_) => None,
#[cfg(feature = "sim-transport")]
TransportHandle::Sim(_) => None,
#[cfg(any(target_os = "linux", target_os = "macos"))]
TransportHandle::Ethernet(t) => Some(t.interface_name()),
TransportHandle::Tcp(_) => None,
TransportHandle::Tor(_) => None,
#[cfg(feature = "webrtc-transport")]
TransportHandle::WebRtc(_) => None,
#[cfg(target_os = "linux")]
TransportHandle::Ble(_) => None,
}
}
pub fn onion_address(&self) -> Option<&str> {
match self {
TransportHandle::Tor(t) => t.onion_address(),
_ => None,
}
}
pub fn tor_monitoring(&self) -> Option<TorMonitoringInfo> {
match self {
TransportHandle::Tor(t) => t.cached_monitoring(),
_ => None,
}
}
pub fn tor_mode(&self) -> Option<&str> {
match self {
TransportHandle::Tor(t) => Some(t.mode()),
_ => None,
}
}
pub fn discover(&self) -> Result<Vec<DiscoveredPeer>, TransportError> {
match self {
TransportHandle::Udp(t) => t.discover(),
#[cfg(feature = "sim-transport")]
TransportHandle::Sim(t) => t.discover(),
#[cfg(any(target_os = "linux", target_os = "macos"))]
TransportHandle::Ethernet(t) => t.discover(),
TransportHandle::Tcp(t) => t.discover(),
TransportHandle::Tor(t) => t.discover(),
#[cfg(feature = "webrtc-transport")]
TransportHandle::WebRtc(t) => t.discover(),
#[cfg(target_os = "linux")]
TransportHandle::Ble(t) => t.discover(),
}
}
pub fn auto_connect(&self) -> bool {
match self {
TransportHandle::Udp(t) => t.auto_connect(),
#[cfg(feature = "sim-transport")]
TransportHandle::Sim(t) => t.auto_connect(),
#[cfg(any(target_os = "linux", target_os = "macos"))]
TransportHandle::Ethernet(t) => t.auto_connect(),
TransportHandle::Tcp(t) => t.auto_connect(),
TransportHandle::Tor(t) => t.auto_connect(),
#[cfg(feature = "webrtc-transport")]
TransportHandle::WebRtc(t) => t.auto_connect(),
#[cfg(target_os = "linux")]
TransportHandle::Ble(t) => t.auto_connect(),
}
}
pub fn accept_connections(&self) -> bool {
match self {
TransportHandle::Udp(t) => t.accept_connections(),
#[cfg(feature = "sim-transport")]
TransportHandle::Sim(t) => t.accept_connections(),
#[cfg(any(target_os = "linux", target_os = "macos"))]
TransportHandle::Ethernet(t) => t.accept_connections(),
TransportHandle::Tcp(t) => t.accept_connections(),
TransportHandle::Tor(t) => t.accept_connections(),
#[cfg(feature = "webrtc-transport")]
TransportHandle::WebRtc(t) => t.accept_connections(),
#[cfg(target_os = "linux")]
TransportHandle::Ble(t) => t.accept_connections(),
}
}
pub async fn connect(&self, addr: &TransportAddr) -> Result<(), TransportError> {
match self {
TransportHandle::Udp(_) => Ok(()), #[cfg(feature = "sim-transport")]
TransportHandle::Sim(_) => Ok(()), #[cfg(any(target_os = "linux", target_os = "macos"))]
TransportHandle::Ethernet(_) => Ok(()), TransportHandle::Tcp(t) => t.connect_async(addr).await,
TransportHandle::Tor(t) => t.connect_async(addr).await,
#[cfg(feature = "webrtc-transport")]
TransportHandle::WebRtc(t) => t.connect_async(addr).await,
#[cfg(target_os = "linux")]
TransportHandle::Ble(t) => t.connect_async(addr).await,
}
}
pub fn connection_state(&self, addr: &TransportAddr) -> ConnectionState {
match self {
TransportHandle::Udp(_) => ConnectionState::Connected,
#[cfg(feature = "sim-transport")]
TransportHandle::Sim(_) => ConnectionState::Connected,
#[cfg(any(target_os = "linux", target_os = "macos"))]
TransportHandle::Ethernet(_) => ConnectionState::Connected,
TransportHandle::Tcp(t) => t.connection_state_sync(addr),
TransportHandle::Tor(t) => t.connection_state_sync(addr),
#[cfg(feature = "webrtc-transport")]
TransportHandle::WebRtc(t) => t.connection_state_sync(addr),
#[cfg(target_os = "linux")]
TransportHandle::Ble(t) => t.connection_state_sync(addr),
}
}
pub async fn close_connection(&self, addr: &TransportAddr) {
match self {
TransportHandle::Udp(t) => t.close_connection(addr),
#[cfg(feature = "sim-transport")]
TransportHandle::Sim(t) => t.close_connection(addr),
#[cfg(any(target_os = "linux", target_os = "macos"))]
TransportHandle::Ethernet(t) => t.close_connection(addr),
TransportHandle::Tcp(t) => t.close_connection_async(addr).await,
TransportHandle::Tor(t) => t.close_connection_async(addr).await,
#[cfg(feature = "webrtc-transport")]
TransportHandle::WebRtc(t) => t.close_connection_async(addr).await,
#[cfg(target_os = "linux")]
TransportHandle::Ble(t) => t.close_connection_async(addr).await,
}
}
pub fn is_operational(&self) -> bool {
self.state().is_operational()
}
pub fn congestion(&self) -> TransportCongestion {
match self {
TransportHandle::Udp(t) => t.congestion(),
#[cfg(feature = "sim-transport")]
TransportHandle::Sim(_) => TransportCongestion::default(),
#[cfg(any(target_os = "linux", target_os = "macos"))]
TransportHandle::Ethernet(_) => TransportCongestion::default(),
TransportHandle::Tcp(_) => TransportCongestion::default(),
TransportHandle::Tor(_) => TransportCongestion::default(),
#[cfg(feature = "webrtc-transport")]
TransportHandle::WebRtc(_) => TransportCongestion::default(),
#[cfg(target_os = "linux")]
TransportHandle::Ble(_) => TransportCongestion::default(),
}
}
pub fn transport_stats(&self) -> serde_json::Value {
match self {
TransportHandle::Udp(t) => {
serde_json::to_value(t.stats().snapshot()).unwrap_or_default()
}
#[cfg(feature = "sim-transport")]
TransportHandle::Sim(t) => serde_json::to_value(t.stats()).unwrap_or_default(),
#[cfg(any(target_os = "linux", target_os = "macos"))]
TransportHandle::Ethernet(t) => {
let snap = t.stats().snapshot();
serde_json::json!({
"frames_sent": snap.frames_sent,
"frames_recv": snap.frames_recv,
"bytes_sent": snap.bytes_sent,
"bytes_recv": snap.bytes_recv,
"send_errors": snap.send_errors,
"recv_errors": snap.recv_errors,
"beacons_sent": snap.beacons_sent,
"beacons_recv": snap.beacons_recv,
"frames_too_short": snap.frames_too_short,
"frames_too_long": snap.frames_too_long,
})
}
TransportHandle::Tcp(t) => {
serde_json::to_value(t.stats().snapshot()).unwrap_or_default()
}
TransportHandle::Tor(t) => {
serde_json::to_value(t.stats().snapshot()).unwrap_or_default()
}
#[cfg(feature = "webrtc-transport")]
TransportHandle::WebRtc(t) => serde_json::json!({
"mtu": t.mtu(),
"state": t.state().to_string(),
}),
#[cfg(target_os = "linux")]
TransportHandle::Ble(t) => {
serde_json::to_value(t.stats().snapshot()).unwrap_or_default()
}
}
}
}