1#[cfg(target_os = "linux")]
4use super::ble::DefaultBleTransport;
5#[cfg(any(target_os = "linux", target_os = "macos"))]
6use super::ethernet::EthernetTransport;
7#[cfg(feature = "sim-transport")]
8use super::sim::SimTransport;
9use super::tcp::TcpTransport;
10use super::tor::TorTransport;
11use super::tor::control::TorMonitoringInfo;
12use super::udp::UdpTransport;
13#[cfg(feature = "webrtc-transport")]
14use super::webrtc::WebRtcTransport;
15use super::{
16 ConnectionState, DiscoveredPeer, Transport, TransportAddr, TransportCongestion, TransportError,
17 TransportId, TransportState, TransportType,
18};
19
20pub enum TransportHandle {
25 Udp(UdpTransport),
27 #[cfg(feature = "sim-transport")]
29 Sim(SimTransport),
30 #[cfg(any(target_os = "linux", target_os = "macos"))]
32 Ethernet(EthernetTransport),
33 Tcp(TcpTransport),
35 Tor(TorTransport),
37 #[cfg(feature = "webrtc-transport")]
39 WebRtc(Box<WebRtcTransport>),
40 #[cfg(target_os = "linux")]
42 Ble(DefaultBleTransport),
43}
44
45impl TransportHandle {
46 pub async fn start(&mut self) -> Result<(), TransportError> {
48 match self {
49 TransportHandle::Udp(t) => t.start_async().await,
50 #[cfg(feature = "sim-transport")]
51 TransportHandle::Sim(t) => t.start_async().await,
52 #[cfg(any(target_os = "linux", target_os = "macos"))]
53 TransportHandle::Ethernet(t) => t.start_async().await,
54 TransportHandle::Tcp(t) => t.start_async().await,
55 TransportHandle::Tor(t) => t.start_async().await,
56 #[cfg(feature = "webrtc-transport")]
57 TransportHandle::WebRtc(t) => t.start_async().await,
58 #[cfg(target_os = "linux")]
59 TransportHandle::Ble(t) => t.start_async().await,
60 }
61 }
62
63 pub async fn stop(&mut self) -> Result<(), TransportError> {
65 match self {
66 TransportHandle::Udp(t) => t.stop_async().await,
67 #[cfg(feature = "sim-transport")]
68 TransportHandle::Sim(t) => t.stop_async().await,
69 #[cfg(any(target_os = "linux", target_os = "macos"))]
70 TransportHandle::Ethernet(t) => t.stop_async().await,
71 TransportHandle::Tcp(t) => t.stop_async().await,
72 TransportHandle::Tor(t) => t.stop_async().await,
73 #[cfg(feature = "webrtc-transport")]
74 TransportHandle::WebRtc(t) => t.stop_async().await,
75 #[cfg(target_os = "linux")]
76 TransportHandle::Ble(t) => t.stop_async().await,
77 }
78 }
79
80 pub async fn send(&self, addr: &TransportAddr, data: &[u8]) -> Result<usize, TransportError> {
82 match self {
83 TransportHandle::Udp(t) => t.send_async(addr, data).await,
84 #[cfg(feature = "sim-transport")]
85 TransportHandle::Sim(t) => t.send_async(addr, data).await,
86 #[cfg(any(target_os = "linux", target_os = "macos"))]
87 TransportHandle::Ethernet(t) => t.send_async(addr, data).await,
88 TransportHandle::Tcp(t) => t.send_async(addr, data).await,
89 TransportHandle::Tor(t) => t.send_async(addr, data).await,
90 #[cfg(feature = "webrtc-transport")]
91 TransportHandle::WebRtc(t) => t.send_async(addr, data).await,
92 #[cfg(target_os = "linux")]
93 TransportHandle::Ble(t) => t.send_async(addr, data).await,
94 }
95 }
96
97 pub fn transport_id(&self) -> TransportId {
99 match self {
100 TransportHandle::Udp(t) => t.transport_id(),
101 #[cfg(feature = "sim-transport")]
102 TransportHandle::Sim(t) => t.transport_id(),
103 #[cfg(any(target_os = "linux", target_os = "macos"))]
104 TransportHandle::Ethernet(t) => t.transport_id(),
105 TransportHandle::Tcp(t) => t.transport_id(),
106 TransportHandle::Tor(t) => t.transport_id(),
107 #[cfg(feature = "webrtc-transport")]
108 TransportHandle::WebRtc(t) => t.transport_id(),
109 #[cfg(target_os = "linux")]
110 TransportHandle::Ble(t) => t.transport_id(),
111 }
112 }
113
114 pub fn name(&self) -> Option<&str> {
116 match self {
117 TransportHandle::Udp(t) => t.name(),
118 #[cfg(feature = "sim-transport")]
119 TransportHandle::Sim(t) => t.name(),
120 #[cfg(any(target_os = "linux", target_os = "macos"))]
121 TransportHandle::Ethernet(t) => t.name(),
122 TransportHandle::Tcp(t) => t.name(),
123 TransportHandle::Tor(t) => t.name(),
124 #[cfg(feature = "webrtc-transport")]
125 TransportHandle::WebRtc(t) => t.name(),
126 #[cfg(target_os = "linux")]
127 TransportHandle::Ble(t) => t.name(),
128 }
129 }
130
131 pub fn transport_type(&self) -> &TransportType {
133 match self {
134 TransportHandle::Udp(t) => t.transport_type(),
135 #[cfg(feature = "sim-transport")]
136 TransportHandle::Sim(t) => t.transport_type(),
137 #[cfg(any(target_os = "linux", target_os = "macos"))]
138 TransportHandle::Ethernet(t) => t.transport_type(),
139 TransportHandle::Tcp(t) => t.transport_type(),
140 TransportHandle::Tor(t) => t.transport_type(),
141 #[cfg(feature = "webrtc-transport")]
142 TransportHandle::WebRtc(t) => t.transport_type(),
143 #[cfg(target_os = "linux")]
144 TransportHandle::Ble(t) => t.transport_type(),
145 }
146 }
147
148 pub fn state(&self) -> TransportState {
150 match self {
151 TransportHandle::Udp(t) => t.state(),
152 #[cfg(feature = "sim-transport")]
153 TransportHandle::Sim(t) => t.state(),
154 #[cfg(any(target_os = "linux", target_os = "macos"))]
155 TransportHandle::Ethernet(t) => t.state(),
156 TransportHandle::Tcp(t) => t.state(),
157 TransportHandle::Tor(t) => t.state(),
158 #[cfg(feature = "webrtc-transport")]
159 TransportHandle::WebRtc(t) => t.state(),
160 #[cfg(target_os = "linux")]
161 TransportHandle::Ble(t) => t.state(),
162 }
163 }
164
165 pub fn mtu(&self) -> u16 {
167 match self {
168 TransportHandle::Udp(t) => t.mtu(),
169 #[cfg(feature = "sim-transport")]
170 TransportHandle::Sim(t) => t.mtu(),
171 #[cfg(any(target_os = "linux", target_os = "macos"))]
172 TransportHandle::Ethernet(t) => t.mtu(),
173 TransportHandle::Tcp(t) => t.mtu(),
174 TransportHandle::Tor(t) => t.mtu(),
175 #[cfg(feature = "webrtc-transport")]
176 TransportHandle::WebRtc(t) => t.mtu(),
177 #[cfg(target_os = "linux")]
178 TransportHandle::Ble(t) => t.mtu(),
179 }
180 }
181
182 pub fn link_mtu(&self, addr: &TransportAddr) -> u16 {
187 match self {
188 TransportHandle::Udp(t) => t.link_mtu(addr),
189 #[cfg(feature = "sim-transport")]
190 TransportHandle::Sim(t) => t.link_mtu(addr),
191 #[cfg(any(target_os = "linux", target_os = "macos"))]
192 TransportHandle::Ethernet(t) => t.link_mtu(addr),
193 TransportHandle::Tcp(t) => t.link_mtu(addr),
194 TransportHandle::Tor(t) => t.link_mtu(addr),
195 #[cfg(feature = "webrtc-transport")]
196 TransportHandle::WebRtc(t) => t.link_mtu(addr),
197 #[cfg(target_os = "linux")]
198 TransportHandle::Ble(t) => t.link_mtu(addr),
199 }
200 }
201
202 pub fn local_addr(&self) -> Option<std::net::SocketAddr> {
204 match self {
205 TransportHandle::Udp(t) => t.local_addr(),
206 #[cfg(feature = "sim-transport")]
207 TransportHandle::Sim(_) => None,
208 #[cfg(any(target_os = "linux", target_os = "macos"))]
209 TransportHandle::Ethernet(_) => None,
210 TransportHandle::Tcp(t) => t.local_addr(),
211 TransportHandle::Tor(_) => None,
212 #[cfg(feature = "webrtc-transport")]
213 TransportHandle::WebRtc(_) => None,
214 #[cfg(target_os = "linux")]
215 TransportHandle::Ble(_) => None,
216 }
217 }
218
219 pub fn interface_name(&self) -> Option<&str> {
221 match self {
222 TransportHandle::Udp(_) => None,
223 #[cfg(feature = "sim-transport")]
224 TransportHandle::Sim(_) => None,
225 #[cfg(any(target_os = "linux", target_os = "macos"))]
226 TransportHandle::Ethernet(t) => Some(t.interface_name()),
227 TransportHandle::Tcp(_) => None,
228 TransportHandle::Tor(_) => None,
229 #[cfg(feature = "webrtc-transport")]
230 TransportHandle::WebRtc(_) => None,
231 #[cfg(target_os = "linux")]
232 TransportHandle::Ble(_) => None,
233 }
234 }
235
236 pub fn onion_address(&self) -> Option<&str> {
238 match self {
239 TransportHandle::Tor(t) => t.onion_address(),
240 _ => None,
241 }
242 }
243
244 pub fn tor_monitoring(&self) -> Option<TorMonitoringInfo> {
246 match self {
247 TransportHandle::Tor(t) => t.cached_monitoring(),
248 _ => None,
249 }
250 }
251
252 pub fn tor_mode(&self) -> Option<&str> {
254 match self {
255 TransportHandle::Tor(t) => Some(t.mode()),
256 _ => None,
257 }
258 }
259
260 pub fn discover(&self) -> Result<Vec<DiscoveredPeer>, TransportError> {
262 match self {
263 TransportHandle::Udp(t) => t.discover(),
264 #[cfg(feature = "sim-transport")]
265 TransportHandle::Sim(t) => t.discover(),
266 #[cfg(any(target_os = "linux", target_os = "macos"))]
267 TransportHandle::Ethernet(t) => t.discover(),
268 TransportHandle::Tcp(t) => t.discover(),
269 TransportHandle::Tor(t) => t.discover(),
270 #[cfg(feature = "webrtc-transport")]
271 TransportHandle::WebRtc(t) => t.discover(),
272 #[cfg(target_os = "linux")]
273 TransportHandle::Ble(t) => t.discover(),
274 }
275 }
276
277 pub fn auto_connect(&self) -> bool {
279 match self {
280 TransportHandle::Udp(t) => t.auto_connect(),
281 #[cfg(feature = "sim-transport")]
282 TransportHandle::Sim(t) => t.auto_connect(),
283 #[cfg(any(target_os = "linux", target_os = "macos"))]
284 TransportHandle::Ethernet(t) => t.auto_connect(),
285 TransportHandle::Tcp(t) => t.auto_connect(),
286 TransportHandle::Tor(t) => t.auto_connect(),
287 #[cfg(feature = "webrtc-transport")]
288 TransportHandle::WebRtc(t) => t.auto_connect(),
289 #[cfg(target_os = "linux")]
290 TransportHandle::Ble(t) => t.auto_connect(),
291 }
292 }
293
294 pub fn accept_connections(&self) -> bool {
296 match self {
297 TransportHandle::Udp(t) => t.accept_connections(),
298 #[cfg(feature = "sim-transport")]
299 TransportHandle::Sim(t) => t.accept_connections(),
300 #[cfg(any(target_os = "linux", target_os = "macos"))]
301 TransportHandle::Ethernet(t) => t.accept_connections(),
302 TransportHandle::Tcp(t) => t.accept_connections(),
303 TransportHandle::Tor(t) => t.accept_connections(),
304 #[cfg(feature = "webrtc-transport")]
305 TransportHandle::WebRtc(t) => t.accept_connections(),
306 #[cfg(target_os = "linux")]
307 TransportHandle::Ble(t) => t.accept_connections(),
308 }
309 }
310
311 pub async fn connect(&self, addr: &TransportAddr) -> Result<(), TransportError> {
319 match self {
320 TransportHandle::Udp(_) => Ok(()), #[cfg(feature = "sim-transport")]
322 TransportHandle::Sim(_) => Ok(()), #[cfg(any(target_os = "linux", target_os = "macos"))]
324 TransportHandle::Ethernet(_) => Ok(()), TransportHandle::Tcp(t) => t.connect_async(addr).await,
326 TransportHandle::Tor(t) => t.connect_async(addr).await,
327 #[cfg(feature = "webrtc-transport")]
328 TransportHandle::WebRtc(t) => t.connect_async(addr).await,
329 #[cfg(target_os = "linux")]
330 TransportHandle::Ble(t) => t.connect_async(addr).await,
331 }
332 }
333
334 pub fn connection_state(&self, addr: &TransportAddr) -> ConnectionState {
340 match self {
341 TransportHandle::Udp(_) => ConnectionState::Connected,
342 #[cfg(feature = "sim-transport")]
343 TransportHandle::Sim(_) => ConnectionState::Connected,
344 #[cfg(any(target_os = "linux", target_os = "macos"))]
345 TransportHandle::Ethernet(_) => ConnectionState::Connected,
346 TransportHandle::Tcp(t) => t.connection_state_sync(addr),
347 TransportHandle::Tor(t) => t.connection_state_sync(addr),
348 #[cfg(feature = "webrtc-transport")]
349 TransportHandle::WebRtc(t) => t.connection_state_sync(addr),
350 #[cfg(target_os = "linux")]
351 TransportHandle::Ble(t) => t.connection_state_sync(addr),
352 }
353 }
354
355 pub async fn close_connection(&self, addr: &TransportAddr) {
360 match self {
361 TransportHandle::Udp(t) => t.close_connection(addr),
362 #[cfg(feature = "sim-transport")]
363 TransportHandle::Sim(t) => t.close_connection(addr),
364 #[cfg(any(target_os = "linux", target_os = "macos"))]
365 TransportHandle::Ethernet(t) => t.close_connection(addr),
366 TransportHandle::Tcp(t) => t.close_connection_async(addr).await,
367 TransportHandle::Tor(t) => t.close_connection_async(addr).await,
368 #[cfg(feature = "webrtc-transport")]
369 TransportHandle::WebRtc(t) => t.close_connection_async(addr).await,
370 #[cfg(target_os = "linux")]
371 TransportHandle::Ble(t) => t.close_connection_async(addr).await,
372 }
373 }
374
375 pub fn is_operational(&self) -> bool {
377 self.state().is_operational()
378 }
379
380 pub fn congestion(&self) -> TransportCongestion {
386 match self {
387 TransportHandle::Udp(t) => t.congestion(),
388 #[cfg(feature = "sim-transport")]
389 TransportHandle::Sim(_) => TransportCongestion::default(),
390 #[cfg(any(target_os = "linux", target_os = "macos"))]
391 TransportHandle::Ethernet(_) => TransportCongestion::default(),
392 TransportHandle::Tcp(_) => TransportCongestion::default(),
393 TransportHandle::Tor(_) => TransportCongestion::default(),
394 #[cfg(feature = "webrtc-transport")]
395 TransportHandle::WebRtc(_) => TransportCongestion::default(),
396 #[cfg(target_os = "linux")]
397 TransportHandle::Ble(_) => TransportCongestion::default(),
398 }
399 }
400
401 pub fn transport_stats(&self) -> serde_json::Value {
405 match self {
406 TransportHandle::Udp(t) => {
407 serde_json::to_value(t.stats().snapshot()).unwrap_or_default()
408 }
409 #[cfg(feature = "sim-transport")]
410 TransportHandle::Sim(t) => serde_json::to_value(t.stats()).unwrap_or_default(),
411 #[cfg(any(target_os = "linux", target_os = "macos"))]
412 TransportHandle::Ethernet(t) => {
413 let snap = t.stats().snapshot();
414 serde_json::json!({
415 "frames_sent": snap.frames_sent,
416 "frames_recv": snap.frames_recv,
417 "bytes_sent": snap.bytes_sent,
418 "bytes_recv": snap.bytes_recv,
419 "send_errors": snap.send_errors,
420 "recv_errors": snap.recv_errors,
421 "beacons_sent": snap.beacons_sent,
422 "beacons_recv": snap.beacons_recv,
423 "frames_too_short": snap.frames_too_short,
424 "frames_too_long": snap.frames_too_long,
425 })
426 }
427 TransportHandle::Tcp(t) => {
428 serde_json::to_value(t.stats().snapshot()).unwrap_or_default()
429 }
430 TransportHandle::Tor(t) => {
431 serde_json::to_value(t.stats().snapshot()).unwrap_or_default()
432 }
433 #[cfg(feature = "webrtc-transport")]
434 TransportHandle::WebRtc(t) => serde_json::json!({
435 "mtu": t.mtu(),
436 "state": t.state().to_string(),
437 }),
438 #[cfg(target_os = "linux")]
439 TransportHandle::Ble(t) => {
440 serde_json::to_value(t.stats().snapshot()).unwrap_or_default()
441 }
442 }
443 }
444}