11use clap:: Parser ;
22use std:: sync:: Arc ;
3-
3+ use std:: time:: Duration ;
4+ use tokio:: time:: interval;
45use crate :: client:: { Args , DEFAULT_MTU , P2P_UDP_PORT } ;
5- use crate :: client:: relay:: { ClientHandler , new_relay_handler} ;
6+ use crate :: client:: relay:: { RelayHandler , new_relay_handler} ;
67use crate :: client:: peer:: { PeerHandler } ;
78use crate :: client:: prettylog:: { log_startup_banner} ;
89use crate :: codec:: frame:: { DataFrame , Frame , HandshakeReplyFrame } ;
@@ -93,10 +94,11 @@ fn init_device(device_config: &HandshakeReplyFrame) -> crate::Result<DeviceHandl
9394}
9495
9596async fn run_event_loop (
96- client_handler : & mut ClientHandler ,
97+ client_handler : & mut RelayHandler ,
9798 peer_handler : & mut Option < PeerHandler > ,
9899 dev : & mut DeviceHandler ,
99100) {
101+ let mut exporter_ticker = interval ( Duration :: from_secs ( 30 ) ) ;
100102 loop {
101103 // Build select branches based on whether P2P is enabled
102104 if let Some ( peer_handler) = peer_handler {
@@ -163,6 +165,9 @@ async fn run_event_loop(
163165 }
164166 }
165167 }
168+ _ = exporter_ticker. tick( ) => {
169+ get_status( client_handler, Some ( peer_handler) ) . await ;
170+ }
166171 }
167172 } else {
168173 // P2P disabled: relay only
@@ -186,7 +191,66 @@ async fn run_event_loop(
186191 }
187192 }
188193 }
194+ _ = exporter_ticker. tick( ) => {
195+ get_status( client_handler, None ) . await ;
196+ }
189197 }
190198 }
191199 }
192200}
201+
202+ async fn get_status ( relay : & RelayHandler , peer : Option < & PeerHandler > ) {
203+ println ! ( "\n ╔══════════════════════════════════════════════════════════════════════╗" ) ;
204+ println ! ( "║ CONNECTION STATUS ║" ) ;
205+ println ! ( "╚══════════════════════════════════════════════════════════════════════╝" ) ;
206+
207+ // Relay Status
208+ let relay_status = relay. get_status ( ) ;
209+ println ! ( "\n 📡 Relay Connection (TCP)" ) ;
210+ println ! ( " ├─ RX Frames: {} (Errors: {})" , relay_status. rx_frame, relay_status. rx_error) ;
211+ println ! ( " └─ TX Frames: {} (Errors: {})" , relay_status. tx_frame, relay_status. tx_error) ;
212+
213+ // P2P Status
214+ if let Some ( peer_handler) = peer {
215+ let peer_status = peer_handler. get_status ( ) . await ;
216+
217+ if peer_status. is_empty ( ) {
218+ println ! ( "\n 🔗 P2P Connections (UDP)" ) ;
219+ println ! ( " └─ No peers configured" ) ;
220+ } else {
221+ println ! ( "\n 🔗 P2P Connections (UDP): {} peers" , peer_status. len( ) ) ;
222+
223+ for ( idx, status) in peer_status. iter ( ) . enumerate ( ) {
224+ let is_last = idx == peer_status. len ( ) - 1 ;
225+ let prefix = if is_last { "└─" } else { "├─" } ;
226+
227+ // Format connection state
228+ let state = match ( & status. addr , & status. last_active ) {
229+ ( None , _) => "❌ Unknown Address" . to_string ( ) ,
230+ ( Some ( _) , None ) => "⏳ Connecting..." . to_string ( ) ,
231+ ( Some ( _) , Some ( last) ) => {
232+ let elapsed = last. elapsed ( ) . as_secs ( ) ;
233+ if elapsed < 15 {
234+ format ! ( "✅ Active ({}s ago)" , elapsed)
235+ } else {
236+ format ! ( "⚠️ Inactive ({}s ago)" , elapsed)
237+ }
238+ }
239+ } ;
240+
241+ // Format address
242+ let addr_str = status. addr
243+ . map ( |a| format ! ( "{}" , a) )
244+ . unwrap_or_else ( || "N/A" . to_string ( ) ) ;
245+
246+ println ! ( " {} Peer: {}" , prefix, status. identity) ;
247+ println ! ( " {} Address: {}" , if is_last { " " } else { "│" } , addr_str) ;
248+ println ! ( " {} Status: {}" , if is_last { " " } else { "│" } , state) ;
249+ }
250+ }
251+ } else {
252+ println ! ( "\n 🔗 P2P Mode: Disabled" ) ;
253+ }
254+
255+ println ! ( ) ;
256+ }
0 commit comments