66use jni:: objects:: { JClass , JObject , JString } ;
77use jni:: sys:: { jbyteArray, jint, jlong, jstring} ;
88use jni:: JNIEnv ;
9+ use std:: sync:: atomic:: { AtomicUsize , Ordering } ;
910use std:: sync:: { Arc , Mutex } ;
1011use tokio:: runtime:: Runtime ;
1112use wraith_core:: node:: { Node , NodeConfig } ;
@@ -22,6 +23,24 @@ static RUNTIME: Mutex<Option<Runtime>> = Mutex::new(None);
2223/// Global node instance
2324static NODE : Mutex < Option < Arc < Node > > > = Mutex :: new ( None ) ;
2425
26+ /// Global counter for active transfers
27+ static ACTIVE_TRANSFERS : AtomicUsize = AtomicUsize :: new ( 0 ) ;
28+
29+ /// Increment active transfer count
30+ fn increment_transfers ( ) {
31+ ACTIVE_TRANSFERS . fetch_add ( 1 , Ordering :: SeqCst ) ;
32+ }
33+
34+ /// Decrement active transfer count
35+ fn decrement_transfers ( ) {
36+ ACTIVE_TRANSFERS . fetch_sub ( 1 , Ordering :: SeqCst ) ;
37+ }
38+
39+ /// Get current active transfer count
40+ fn get_active_transfers ( ) -> usize {
41+ ACTIVE_TRANSFERS . load ( Ordering :: SeqCst )
42+ }
43+
2544/// Initialize the WRAITH node
2645///
2746/// # Safety
@@ -45,7 +64,13 @@ pub unsafe extern "C" fn Java_com_wraith_android_WraithNative_initNode(
4564
4665 // Initialize runtime if not already done
4766 {
48- let mut rt_lock = RUNTIME . lock ( ) . unwrap ( ) ;
67+ let mut rt_lock = match RUNTIME . lock ( ) {
68+ Ok ( guard) => guard,
69+ Err ( e) => {
70+ log:: error!( "Failed to acquire runtime lock: {}" , e) ;
71+ return -1 ;
72+ }
73+ } ;
4974 if rt_lock. is_none ( ) {
5075 match Runtime :: new ( ) {
5176 Ok ( rt) => * rt_lock = Some ( rt) ,
@@ -83,8 +108,20 @@ pub unsafe extern "C" fn Java_com_wraith_android_WraithNative_initNode(
83108 } ;
84109
85110 // Create node
86- let rt = RUNTIME . lock ( ) . unwrap ( ) ;
87- let rt = rt. as_ref ( ) . unwrap ( ) ;
111+ let rt = match RUNTIME . lock ( ) {
112+ Ok ( guard) => guard,
113+ Err ( e) => {
114+ log:: error!( "Failed to acquire runtime lock: {}" , e) ;
115+ return -1 ;
116+ }
117+ } ;
118+ let rt = match rt. as_ref ( ) {
119+ Some ( rt) => rt,
120+ None => {
121+ log:: error!( "Runtime not initialized" ) ;
122+ return -1 ;
123+ }
124+ } ;
88125
89126 let node = match rt. block_on ( async { Node :: new ( config) . await } ) {
90127 Ok ( n) => Arc :: new ( n) ,
@@ -110,7 +147,13 @@ pub unsafe extern "C" fn Java_com_wraith_android_WraithNative_initNode(
110147
111148 // Store node globally
112149 {
113- let mut node_lock = NODE . lock ( ) . unwrap ( ) ;
150+ let mut node_lock = match NODE . lock ( ) {
151+ Ok ( guard) => guard,
152+ Err ( e) => {
153+ log:: error!( "Failed to acquire node lock: {}" , e) ;
154+ return -1 ;
155+ }
156+ } ;
114157 * node_lock = Some ( node. clone ( ) ) ;
115158 }
116159
@@ -135,18 +178,18 @@ pub unsafe extern "C" fn Java_com_wraith_android_WraithNative_shutdownNode(
135178
136179 let node = Arc :: from_raw ( handle as * const Node ) ;
137180
138- let rt = RUNTIME . lock ( ) . unwrap ( ) ;
139- if let Some ( rt) = rt. as_ref ( ) {
140- rt. block_on ( async {
141- if let Err ( e) = node. shutdown ( ) . await {
142- log:: error!( "Error during node shutdown: {}" , e) ;
143- }
144- } ) ;
181+ if let Ok ( rt) = RUNTIME . lock ( ) {
182+ if let Some ( rt) = rt. as_ref ( ) {
183+ rt. block_on ( async {
184+ if let Err ( e) = node. stop ( ) . await {
185+ log:: error!( "Error during node shutdown: {}" , e) ;
186+ }
187+ } ) ;
188+ }
145189 }
146190
147191 // Clear global node
148- {
149- let mut node_lock = NODE . lock ( ) . unwrap ( ) ;
192+ if let Ok ( mut node_lock) = NODE . lock ( ) {
150193 * node_lock = None ;
151194 }
152195}
@@ -180,8 +223,20 @@ pub unsafe extern "C" fn Java_com_wraith_android_WraithNative_establishSession(
180223 }
181224 } ;
182225
183- let rt = RUNTIME . lock ( ) . unwrap ( ) ;
184- let rt = rt. as_ref ( ) . unwrap ( ) ;
226+ let rt = match RUNTIME . lock ( ) {
227+ Ok ( guard) => guard,
228+ Err ( e) => {
229+ log:: error!( "Failed to acquire runtime lock: {}" , e) ;
230+ return std:: ptr:: null_mut ( ) ;
231+ }
232+ } ;
233+ let rt = match rt. as_ref ( ) {
234+ Some ( rt) => rt,
235+ None => {
236+ log:: error!( "Runtime not initialized" ) ;
237+ return std:: ptr:: null_mut ( ) ;
238+ }
239+ } ;
185240
186241 let session_info = match rt. block_on ( async {
187242 // Convert peer_id string to PeerId type
@@ -251,8 +306,23 @@ pub unsafe extern "C" fn Java_com_wraith_android_WraithNative_sendFile(
251306 Err ( _) => return std:: ptr:: null_mut ( ) ,
252307 } ;
253308
254- let rt = RUNTIME . lock ( ) . unwrap ( ) ;
255- let rt = rt. as_ref ( ) . unwrap ( ) ;
309+ let rt = match RUNTIME . lock ( ) {
310+ Ok ( guard) => guard,
311+ Err ( e) => {
312+ log:: error!( "Failed to acquire runtime lock: {}" , e) ;
313+ return std:: ptr:: null_mut ( ) ;
314+ }
315+ } ;
316+ let rt = match rt. as_ref ( ) {
317+ Some ( rt) => rt,
318+ None => {
319+ log:: error!( "Runtime not initialized" ) ;
320+ return std:: ptr:: null_mut ( ) ;
321+ }
322+ } ;
323+
324+ // Track transfer start
325+ increment_transfers ( ) ;
256326
257327 let transfer_info = match rt. block_on ( async {
258328 use std:: path:: Path ;
@@ -283,6 +353,7 @@ pub unsafe extern "C" fn Java_com_wraith_android_WraithNative_sendFile(
283353 Ok ( info) => info,
284354 Err ( e) => {
285355 log:: error!( "Failed to send file: {}" , e) ;
356+ decrement_transfers ( ) ; // Decrement on failure
286357 return std:: ptr:: null_mut ( ) ;
287358 }
288359 } ;
@@ -313,9 +384,9 @@ pub unsafe extern "C" fn Java_com_wraith_android_WraithNative_getNodeStatus(
313384
314385 let status = serde_json:: json!( {
315386 "running" : node. is_running( ) ,
316- "localPeerId" : hex:: encode( node. local_peer_id ( ) ) ,
317- "sessionCount" : node. session_count ( ) ,
318- "activeTransfers" : 0 , // TODO: Track transfers
387+ "localPeerId" : hex:: encode( node. node_id ( ) ) ,
388+ "sessionCount" : node. active_route_count ( ) ,
389+ "activeTransfers" : get_active_transfers ( ) ,
319390 } ) ;
320391
321392 match env. new_string ( status. to_string ( ) ) {
0 commit comments