rvoip_client_core/client/
manager.rs

1use std::sync::Arc;
2use std::collections::HashMap;
3use tokio::sync::{RwLock, Mutex};
4use dashmap::DashMap;
5use uuid::Uuid;
6
7// Import session-core APIs - UPDATED to use new API structure
8use rvoip_session_core::api::{
9    SessionCoordinator,
10    SessionManagerBuilder,
11    SessionManagerConfig,
12    SessionControl,
13    MediaControl,
14    SipClient,
15    MediaConfig as SessionMediaConfig,
16    types::SessionId,
17    handlers::CallHandler,
18};
19
20// Import client-core types
21use crate::{
22    ClientConfig, ClientResult, ClientError,
23    call::{CallId, CallInfo},
24    registration::{RegistrationConfig, RegistrationInfo},
25    events::{ClientEventHandler, ClientEvent},
26};
27
28// Import types from our types module
29use super::types::*;
30use super::events::ClientCallHandler;
31use super::recovery::{retry_with_backoff, RetryConfig, ErrorContext};
32use super::config::MediaConfig;
33
34/// High-level SIP client manager that coordinates all client operations
35/// 
36/// The `ClientManager` is the primary entry point for VoIP client functionality.
37/// It provides a high-level, async API for SIP registration, call management,
38/// and media control while delegating to session-core for the underlying
39/// SIP protocol implementation.
40/// 
41/// # Architecture
42/// 
43/// ```text
44/// ┌─────────────────────────┐
45/// │   Application Layer     │
46/// └───────────┬─────────────┘
47///             │
48/// ┌───────────▼─────────────┐
49/// │   ClientManager         │ ◄── This Layer
50/// │ ┌─────────────────────┐ │
51/// │ │ Registration Mgmt   │ │  • SIP REGISTER handling
52/// │ │ Call Management     │ │  • Event coordination
53/// │ │ Media Integration   │ │  • State management
54/// │ │ Event Broadcasting  │ │  • Error handling
55/// │ └─────────────────────┘ │
56/// └───────────┬─────────────┘
57///             │
58/// ┌───────────▼─────────────┐
59/// │    session-core         │
60/// │  SessionCoordinator     │
61/// └─────────────────────────┘
62/// ```
63/// 
64/// # Core Features
65/// 
66/// ## Registration Management
67/// - **SIP Registration**: Register with SIP servers using REGISTER requests
68/// - **Authentication**: Handle digest authentication challenges
69/// - **Refresh**: Automatic and manual registration refresh
70/// - **Multiple Registrations**: Support multiple simultaneous registrations
71/// 
72/// ## Call Management
73/// - **Outbound Calls**: Initiate calls to SIP URIs or phone numbers
74/// - **Inbound Calls**: Accept incoming calls with proper SDP negotiation
75/// - **Call Control**: Hold, resume, transfer, and hangup operations
76/// - **DTMF**: Send dual-tone multi-frequency signals during calls
77/// 
78/// ## Media Integration
79/// - **Codec Support**: Multiple audio codecs (G.711, G.729, Opus)
80/// - **Quality Control**: Real-time media quality monitoring
81/// - **Echo Cancellation**: Built-in acoustic echo cancellation
82/// - **Noise Suppression**: Advanced noise reduction algorithms
83/// 
84/// ## Event System
85/// - **Real-time Events**: Registration, call, and media events
86/// - **Broadcast Channel**: Multi-consumer event distribution
87/// - **Typed Events**: Strongly-typed event structures
88/// - **Priority Levels**: Event prioritization for handling
89/// 
90/// # Usage Examples
91/// 
92/// ## Basic Client Setup
93/// 
94/// ```rust
95/// use rvoip_client_core::{ClientManager, ClientConfig};
96/// use std::net::SocketAddr;
97/// 
98/// async fn basic_setup() -> Result<(), Box<dyn std::error::Error>> {
99///     // Create client configuration
100///     let config = ClientConfig::new()
101///         .with_sip_addr("127.0.0.1:5060".parse()?);
102///     
103///     // Create and start client manager
104///     let client = ClientManager::new(config).await?;
105///     client.start().await?;
106///     
107///     println!("✅ SIP client started successfully");
108///     
109///     // Clean shutdown
110///     client.stop().await?;
111///     Ok(())
112/// }
113/// ```
114/// 
115/// ## Registration and Call Flow
116/// 
117/// ```rust
118/// use rvoip_client_core::{ClientManager, ClientConfig, RegistrationConfig};
119/// use std::time::Duration;
120/// 
121/// async fn registration_flow() -> Result<(), Box<dyn std::error::Error>> {
122///     let config = ClientConfig::new()
123///         .with_sip_addr("127.0.0.1:5061".parse()?);
124///     
125///     let client = ClientManager::new(config).await?;
126///     client.start().await?;
127///     
128///     // Register with SIP server
129    ///     let reg_config = RegistrationConfig {
130    ///         server_uri: "sip:192.168.1.100:5060".to_string(),
131    ///         from_uri: "sip:alice@example.com".to_string(),
132    ///         contact_uri: "sip:alice@127.0.0.1:5061".to_string(),
133    ///         expires: 3600,
134    ///         username: None,
135    ///         password: None,
136    ///         realm: None,
137    ///     };
138///     
139///     let registration_id = client.register(reg_config).await?;
140///     println!("✅ Registered with ID: {}", registration_id);
141///     
142///     // Make a call (would be implemented in calls.rs)
143///     // let call_id = client.make_call("sip:bob@example.com").await?;
144///     
145///     // Clean up
146///     client.unregister(registration_id).await?;
147///     client.stop().await?;
148///     Ok(())
149/// }
150/// ```
151/// 
152/// ## Event Monitoring
153/// 
154/// ```rust
155/// use rvoip_client_core::{ClientManager, ClientConfig, ClientEvent};
156/// use tokio::time::{timeout, Duration};
157/// 
158/// async fn event_monitoring() -> Result<(), Box<dyn std::error::Error>> {
159///     let config = ClientConfig::new()
160///         .with_sip_addr("127.0.0.1:5062".parse()?);
161///     
162///     let client = ClientManager::new(config).await?;
163///     client.start().await?;
164///     
165///     // Subscribe to events
166///     let mut event_rx = client.subscribe_events();
167///     
168///     // Monitor events for a short time
169///     let event_task = tokio::spawn(async move {
170///         let mut event_count = 0;
171///         while event_count < 3 {
172    ///             if let Ok(event) = timeout(Duration::from_millis(100), event_rx.recv()).await {
173    ///                 match event {
174    ///                     Ok(ClientEvent::RegistrationStatusChanged { info, .. }) => {
175    ///                         println!("📋 Registration event: {} -> {:?}", 
176    ///                             info.user_uri, info.status);
177    ///                     }
178    ///                     Ok(ClientEvent::CallStateChanged { info, .. }) => {
179    ///                         println!("📞 Call event: {} -> {:?}", 
180    ///                             info.call_id, info.new_state);
181    ///                     }
182    ///                     Ok(ClientEvent::MediaEvent { info, .. }) => {
183    ///                         println!("🎵 Media event: Call {} event occurred", 
184    ///                             info.call_id);
185    ///                     }
186    ///                     Ok(ClientEvent::IncomingCall { .. }) | 
187    ///                     Ok(ClientEvent::ClientError { .. }) | 
188    ///                     Ok(ClientEvent::NetworkEvent { .. }) => {
189    ///                         // Handle other events as needed
190    ///                     }
191    ///                     Err(_) => break,
192    ///                 }
193///                 event_count += 1;
194///             } else {
195///                 break; // Timeout
196///             }
197///         }
198///     });
199///     
200///     // Wait for event monitoring to complete
201///     let _ = event_task.await;
202///     
203///     client.stop().await?;
204///     Ok(())
205/// }
206/// ```
207pub struct ClientManager {
208    /// Session coordinator from session-core
209    pub(crate) coordinator: Arc<SessionCoordinator>,
210    
211    /// Local SIP address (bound)
212    pub(crate) local_sip_addr: std::net::SocketAddr,
213    
214    /// Media configuration
215    pub(crate) media_config: MediaConfig,
216    
217    /// Whether the client is running
218    pub(crate) is_running: Arc<RwLock<bool>>,
219    
220    /// Statistics
221    pub(crate) stats: Arc<Mutex<ClientStats>>,
222    
223    /// Active registrations
224    pub(crate) registrations: Arc<RwLock<HashMap<Uuid, RegistrationInfo>>>,
225    
226    /// Call/Session mapping (CallId -> SessionId)
227    pub(crate) session_mapping: Arc<DashMap<CallId, SessionId>>,
228    
229    /// Call info storage
230    pub(crate) call_info: Arc<DashMap<CallId, CallInfo>>,
231    
232    /// Call handler
233    pub(crate) call_handler: Arc<ClientCallHandler>,
234    
235    /// Event broadcast channel
236    pub(crate) event_tx: tokio::sync::broadcast::Sender<ClientEvent>,
237    
238    /// Tracks which calls have audio frame subscription set up
239    pub(crate) audio_setup_calls: Arc<DashMap<CallId, bool>>,
240    
241    /// Handle to the audio setup task
242    audio_setup_task: Arc<Mutex<Option<tokio::task::JoinHandle<()>>>>,
243    
244}
245
246impl ClientManager {
247    /// Create a new client manager with the given configuration
248    /// 
249    /// This method initializes a new `ClientManager` instance with the provided
250    /// configuration. It sets up the underlying session coordinator, event system,
251    /// call mapping structures, and media configuration.
252    /// 
253    /// # Arguments
254    /// 
255    /// * `config` - The client configuration specifying SIP addresses, media settings,
256    ///              codec preferences, and other operational parameters
257    /// 
258    /// # Returns
259    /// 
260    /// Returns an `Arc<ClientManager>` wrapped in a `ClientResult`. The Arc allows
261    /// the manager to be shared across multiple async tasks safely.
262    /// 
263    /// # Errors
264    /// 
265    /// * `ClientError::InternalError` - If the session coordinator cannot be created
266    ///   due to invalid configuration or system resource constraints
267    /// 
268    /// # Examples
269    /// 
270    /// ## Basic Client Creation
271    /// 
272    /// ```rust
273    /// use rvoip_client_core::{ClientManager, ClientConfig};
274    /// 
275    /// async fn create_basic_client() -> Result<(), Box<dyn std::error::Error>> {
276    ///     let config = ClientConfig::new()
277    ///         .with_sip_addr("127.0.0.1:5060".parse()?);
278    ///     
279    ///     let client = ClientManager::new(config).await?;
280    ///     println!("✅ Client created successfully");
281    ///     
282    ///     // Client is ready but not started yet
283    ///     assert!(!client.is_running().await);
284    ///     
285    ///     Ok(())
286    /// }
287    /// ```
288    /// 
289    /// ## Client with Custom Media Configuration
290    /// 
291    /// ```rust
292    /// use rvoip_client_core::{ClientManager, ClientConfig, MediaConfig, MediaPreset};
293    /// 
294    /// async fn create_custom_media_client() -> Result<(), Box<dyn std::error::Error>> {
295    ///     use rvoip_client_core::client::config::MediaPreset;
296    ///     let mut media_config = MediaConfig::from_preset(MediaPreset::VoiceOptimized);
297    ///     media_config.echo_cancellation = true;
298    ///     media_config.noise_suppression = true;
299    ///     media_config.rtp_port_start = 10000;
300    ///     media_config.rtp_port_end = 20000;
301    ///     
302    ///     let config = ClientConfig::new()
303    ///         .with_sip_addr("127.0.0.1:5061".parse()?)
304    ///         .with_media(media_config);
305    ///     
306    ///     let client = ClientManager::new(config).await?;
307    ///     
308    ///     // Verify media configuration was applied
309    ///     let applied_config = client.get_media_config();
310    ///     assert!(applied_config.echo_cancellation);
311    ///     assert!(applied_config.noise_suppression);
312    ///     assert_eq!(applied_config.rtp_port_start, 10000);
313    ///     assert_eq!(applied_config.rtp_port_end, 20000);
314    ///     
315    ///     println!("✅ Custom media client created");
316    ///     Ok(())
317    /// }
318    /// ```
319    /// 
320    /// ## Enterprise Client Setup
321    /// 
322    /// ```rust
323    /// use rvoip_client_core::{ClientManager, ClientConfig, MediaConfig};
324    /// 
325    /// async fn create_enterprise_client() -> Result<(), Box<dyn std::error::Error>> {
326    ///     use rvoip_client_core::client::config::MediaPreset;
327    ///     let mut media_config = MediaConfig::from_preset(MediaPreset::Secure);
328    ///     media_config.max_bandwidth_kbps = Some(128);  // 128 kbps max
329    ///     media_config.preferred_ptime = Some(20);      // 20ms packet time
330    ///     
331    ///     let config = ClientConfig::new()
332    ///         .with_sip_addr("0.0.0.0:5060".parse()?)  // Bind to all interfaces
333    ///         .with_media_addr("0.0.0.0:0".parse()?)   // Dynamic media port
334    ///         .with_media(media_config);
335    ///     
336    ///     let client = ClientManager::new(config).await?;
337    ///     
338    ///     println!("✅ Enterprise client ready for production");
339    ///     Ok(())
340    /// }
341    /// ```
342    /// 
343    /// ## Error Handling
344    /// 
345    /// ```rust
346    /// use rvoip_client_core::{ClientManager, ClientConfig, ClientError};
347    /// 
348    /// async fn handle_creation_errors() -> Result<(), Box<dyn std::error::Error>> {
349    ///     // Try to create client with potentially problematic config
350    ///     let config = ClientConfig::new()
351    ///         .with_sip_addr("127.0.0.1:5062".parse()?);
352    ///     
353    ///     match ClientManager::new(config).await {
354    ///         Ok(client) => {
355    ///             println!("✅ Client created successfully");
356    ///             // Use client...
357    ///         }
358    ///         Err(ClientError::InternalError { message }) => {
359    ///             println!("❌ Failed to create client: {}", message);
360    ///             // Handle error (retry, use different config, etc.)
361    ///         }
362    ///         Err(e) => {
363    ///             println!("❌ Unexpected error: {}", e);
364    ///         }
365    ///     }
366    ///     
367    ///     Ok(())
368    /// }
369    /// ```
370    /// 
371    /// ## Multi-Client Architecture
372    /// 
373    /// ```rust
374    /// use rvoip_client_core::{ClientManager, ClientConfig};
375    /// use std::sync::Arc;
376    /// 
377    /// async fn multi_client_setup() -> Result<(), Box<dyn std::error::Error>> {
378    ///     // Create multiple clients for different purposes
379    ///     let client1_config = ClientConfig::new()
380    ///         .with_sip_addr("127.0.0.1:5060".parse()?);
381    ///     let client1 = ClientManager::new(client1_config).await?;
382    ///     
383    ///     let client2_config = ClientConfig::new()
384    ///         .with_sip_addr("127.0.0.1:5061".parse()?);
385    ///     let client2 = ClientManager::new(client2_config).await?;
386    ///     
387    ///     // Clients can be shared across tasks
388    ///     let client1_clone = Arc::clone(&client1);
389    ///     let task1 = tokio::spawn(async move {
390    ///         // Use client1_clone in this task
391    ///         println!("Task 1 using client on port 5060");
392    ///     });
393    ///     
394    ///     let client2_clone = Arc::clone(&client2);
395    ///     let task2 = tokio::spawn(async move {
396    ///         // Use client2_clone in this task
397    ///         println!("Task 2 using client on port 5061");
398    ///     });
399    ///     
400    ///     // Wait for tasks to complete
401    ///     let _ = tokio::try_join!(task1, task2)?;
402    ///     
403    ///     println!("✅ Multi-client setup complete");
404    ///     Ok(())
405    /// }
406    /// ```
407    /// 
408    /// # Implementation Notes
409    /// 
410    /// The constructor performs several key initialization steps:
411    /// 
412    /// 1. **Session Coordinator Setup**: Creates the underlying session-core coordinator
413    ///    with media preferences and SIP configuration
414    /// 2. **Event System**: Initializes broadcast channels for real-time events
415    /// 3. **Call Mapping**: Sets up concurrent data structures for call tracking
416    /// 4. **Media Configuration**: Applies codec preferences and quality settings
417    /// 5. **Handler Registration**: Registers the call handler for SIP events
418    /// 
419    /// The returned `Arc<ClientManager>` enables safe sharing across async tasks
420    /// and ensures proper cleanup through RAII patterns.
421    pub async fn new(config: ClientConfig) -> ClientResult<Arc<Self>> {
422        // Create call/session mapping
423        let call_mapping = Arc::new(DashMap::new());
424        let session_mapping = Arc::new(DashMap::new());
425        let call_info = Arc::new(DashMap::new());
426        let incoming_calls = Arc::new(DashMap::new());
427        
428        // Create event broadcast channel
429        let (event_tx, _) = tokio::sync::broadcast::channel(256);
430        
431        // Create channel for call establishment notifications
432        let (call_established_tx, call_established_rx) = tokio::sync::mpsc::unbounded_channel();
433        
434        // Create call handler
435        let call_handler = Arc::new(ClientCallHandler::new(
436            call_mapping.clone(),
437            session_mapping.clone(),
438            call_info.clone(),
439            incoming_calls.clone(),
440        ).with_event_tx(event_tx.clone())
441        .with_call_established_tx(call_established_tx));
442        
443
444        
445        // Build session coordinator with media preferences
446        // The media preferences will be used by session-core's SDP negotiator
447        // to generate offers/answers based on the configured codecs
448        let session_media_config = SessionMediaConfig {
449            preferred_codecs: config.media.preferred_codecs.clone(),
450            port_range: Some((config.media.rtp_port_start, config.media.rtp_port_end)),
451            quality_monitoring: true,
452            dtmf_support: config.media.dtmf_enabled,
453            echo_cancellation: config.media.echo_cancellation,
454            noise_suppression: config.media.noise_suppression,
455            auto_gain_control: config.media.auto_gain_control,
456            max_bandwidth_kbps: config.media.max_bandwidth_kbps,
457            preferred_ptime: config.media.preferred_ptime,
458            custom_sdp_attributes: config.media.custom_sdp_attributes.clone(),
459        };
460        
461        // Note: If media port is 0, it signals automatic allocation
462        // The actual port will be allocated by session-core when creating media sessions
463        // This is the proper layered approach that respects the architecture
464
465        // Create session manager using session-core builder with media preferences
466        let coordinator = SessionManagerBuilder::new()
467            .with_local_address(&format!("sip:client@{}", config.local_sip_addr.ip()))
468            .with_sip_port(config.local_sip_addr.port())
469            .with_local_bind_addr(config.local_sip_addr)  // Add this line to propagate bind address
470            .with_media_ports(config.media.rtp_port_start, config.media.rtp_port_end)
471            .with_media_config(session_media_config)  // Pass media preferences to session-core
472            .with_handler(call_handler.clone() as Arc<dyn CallHandler>)
473            .enable_sip_client()  // Enable SIP client features for REGISTER support
474            .build()
475            .await
476            .map_err(|e| ClientError::InternalError { 
477                message: format!("Failed to create session coordinator: {}", e) 
478            })?;
479        
480
481            
482        let mut stats = ClientStats {
483            is_running: false,
484            local_sip_addr: config.local_sip_addr,
485            local_media_addr: config.local_media_addr,
486            total_calls: 0,
487            connected_calls: 0,
488            total_registrations: 0,
489            active_registrations: 0,
490                };
491        
492
493        
494        let audio_setup_calls = Arc::new(DashMap::new());
495        
496        // Create the client manager
497        let client = Arc::new(Self {
498            coordinator,
499            local_sip_addr: config.local_sip_addr,
500            media_config: config.media.clone(),
501            is_running: Arc::new(RwLock::new(false)),
502            stats: Arc::new(Mutex::new(stats)),
503            registrations: Arc::new(RwLock::new(HashMap::new())),
504            session_mapping,
505            call_info,
506            call_handler,
507            event_tx,
508            audio_setup_calls,
509            audio_setup_task: Arc::new(Mutex::new(None)),
510        });
511        
512        // Spawn task to handle call establishment notifications
513        let client_clone = client.clone();
514        let mut call_established_rx = call_established_rx;
515        let audio_setup_task = tokio::spawn(async move {
516            while let Some(call_id) = call_established_rx.recv().await {
517                // Set up audio for the established call
518                if let Err(e) = client_clone.setup_call_audio(&call_id).await {
519                    tracing::warn!("Failed to set up audio for established call {}: {}", call_id, e);
520                }
521            }
522        });
523        
524        // Store the task handle
525        *client.audio_setup_task.lock().await = Some(audio_setup_task);
526        
527        Ok(client)
528    }
529    
530    /// Set the event handler for client events
531    /// 
532    /// This method registers an application-provided event handler that will receive
533    /// notifications for all client events including registration changes, call status
534    /// updates, and media quality notifications. The handler is called asynchronously
535    /// and should not block for extended periods.
536    /// 
537    /// # Arguments
538    /// 
539    /// * `handler` - An implementation of the `ClientEventHandler` trait wrapped in an `Arc`
540    ///               for thread-safe sharing across the event system
541    /// 
542    /// # Examples
543    /// 
544    /// ## Basic Event Handler
545    /// 
546    /// ```rust
547    /// use rvoip_client_core::{
548    ///     ClientManager, ClientConfig, ClientEventHandler,
549    ///     events::{CallStatusInfo, RegistrationStatusInfo, MediaEventInfo, IncomingCallInfo, CallAction}
550    /// };
551    /// use async_trait::async_trait;
552    /// use std::sync::Arc;
553    /// 
554    /// struct MyEventHandler;
555    /// 
556    /// #[async_trait]
557    /// impl ClientEventHandler for MyEventHandler {
558    ///     async fn on_incoming_call(&self, _info: IncomingCallInfo) -> CallAction {
559    ///         CallAction::Accept
560    ///     }
561    ///     
562    ///     async fn on_call_state_changed(&self, info: CallStatusInfo) {
563    ///         println!("📞 Call {} changed to {:?}", info.call_id, info.new_state);
564    ///     }
565    ///     
566    ///     async fn on_registration_status_changed(&self, info: RegistrationStatusInfo) {
567    ///         println!("📋 Registration {} changed to {:?}", info.user_uri, info.status);
568    ///     }
569    ///     
570    ///     async fn on_media_event(&self, info: MediaEventInfo) {
571    ///         println!("🎵 Media event for call {}: {:?}", info.call_id, info.event_type);
572    ///     }
573    /// }
574    /// 
575    /// async fn setup_event_handler() -> Result<(), Box<dyn std::error::Error>> {
576    ///     let config = ClientConfig::new()
577    ///         .with_sip_addr("127.0.0.1:5063".parse()?);
578    ///     
579    ///     let client = ClientManager::new(config).await?;
580    ///     
581    ///     // Register our event handler
582    ///     let handler = Arc::new(MyEventHandler);
583    ///     client.set_event_handler(handler).await;
584    ///     
585    ///     client.start().await?;
586    ///     println!("✅ Event handler registered and client started");
587    ///     
588    ///     client.stop().await?;
589    ///     Ok(())
590    /// }
591    /// ```
592    /// 
593    /// ## Stateful Event Handler
594    /// 
595    /// ```rust
596    /// use rvoip_client_core::{
597    ///     ClientManager, ClientConfig, ClientEventHandler,
598    ///     events::{CallStatusInfo, RegistrationStatusInfo, MediaEventInfo, IncomingCallInfo, CallAction}
599    /// };
600    /// use async_trait::async_trait;
601    /// use std::sync::{Arc, Mutex};
602    /// use std::collections::HashMap;
603    /// 
604    /// struct StatefulEventHandler {
605    ///     call_states: Mutex<HashMap<String, String>>,
606    ///     event_count: Mutex<u64>,
607    /// }
608    /// 
609    /// impl StatefulEventHandler {
610    ///     fn new() -> Self {
611    ///         Self {
612    ///             call_states: Mutex::new(HashMap::new()),
613    ///             event_count: Mutex::new(0),
614    ///         }
615    ///     }
616    /// }
617    /// 
618    /// #[async_trait]
619    /// impl ClientEventHandler for StatefulEventHandler {
620    ///     async fn on_incoming_call(&self, _info: IncomingCallInfo) -> CallAction {
621    ///         CallAction::Accept
622    ///     }
623    ///     
624    ///     async fn on_call_state_changed(&self, info: CallStatusInfo) {
625    ///         // Update state tracking
626    ///         let mut states = self.call_states.lock().unwrap();
627    ///         states.insert(info.call_id.to_string(), format!("{:?}", info.new_state));
628    ///         
629    ///         let mut count = self.event_count.lock().unwrap();
630    ///         *count += 1;
631    ///         
632    ///         println!("📞 Call event #{}: {} -> {:?}", *count, info.call_id, info.new_state);
633    ///     }
634    ///     
635    ///     async fn on_registration_status_changed(&self, info: RegistrationStatusInfo) {
636    ///         println!("📋 Registration: {} -> {:?}", info.user_uri, info.status);
637    ///     }
638    ///     
639    ///     async fn on_media_event(&self, info: MediaEventInfo) {
640    ///         println!("🎵 Media: Call {} -> {:?}", info.call_id, info.event_type);
641    ///     }
642    /// }
643    /// 
644    /// async fn stateful_handler() -> Result<(), Box<dyn std::error::Error>> {
645    ///     let config = ClientConfig::new()
646    ///         .with_sip_addr("127.0.0.1:5064".parse()?);
647    ///     
648    ///     let client = ClientManager::new(config).await?;
649    ///     
650    ///     // Create stateful handler
651    ///     let handler = Arc::new(StatefulEventHandler::new());
652    ///     client.set_event_handler(handler.clone()).await;
653    ///     
654    ///     client.start().await?;
655    ///     
656    ///     // Handler is now tracking events
657    ///     println!("✅ Stateful event handler active");
658    ///     
659    ///     client.stop().await?;
660    ///     Ok(())
661    /// }
662    /// ```
663    /// 
664    /// ## Logging Event Handler
665    /// 
666    /// ```rust
667    /// use rvoip_client_core::{
668    ///     ClientManager, ClientConfig, ClientEventHandler,
669    ///     events::{CallStatusInfo, RegistrationStatusInfo, MediaEventInfo, IncomingCallInfo, CallAction}
670    /// };
671    /// use async_trait::async_trait;
672    /// use std::sync::Arc;
673    /// use chrono::Utc;
674    /// 
675    /// struct LoggingEventHandler {
676    ///     component_name: String,
677    /// }
678    /// 
679    /// impl LoggingEventHandler {
680    ///     fn new(name: &str) -> Self {
681    ///         Self {
682    ///             component_name: name.to_string(),
683    ///         }
684    ///     }
685    /// }
686    /// 
687    /// #[async_trait]
688    /// impl ClientEventHandler for LoggingEventHandler {
689    ///     async fn on_incoming_call(&self, _info: IncomingCallInfo) -> CallAction {
690    ///         CallAction::Accept
691    ///     }
692    ///     
693    ///     async fn on_call_state_changed(&self, info: CallStatusInfo) {
694    ///         tracing::info!(
695    ///             component = %self.component_name,
696    ///             call_id = %info.call_id,
697    ///             previous_state = ?info.previous_state,
698    ///             new_state = ?info.new_state,
699    ///             timestamp = %info.timestamp,
700    ///             "Call status changed"
701    ///         );
702    ///     }
703    ///     
704    ///     async fn on_registration_status_changed(&self, info: RegistrationStatusInfo) {
705    ///         tracing::info!(
706    ///             component = %self.component_name,
707    ///             user_uri = %info.user_uri,
708    ///             status = ?info.status,
709    ///             server = %info.server_uri,
710    ///             "Registration status changed"
711    ///         );
712    ///     }
713    ///     
714    ///     async fn on_media_event(&self, info: MediaEventInfo) {
715    ///         tracing::debug!(
716    ///             component = %self.component_name,
717    ///             call_id = %info.call_id,
718    ///             event_type = ?info.event_type,
719    ///             "Media event occurred"
720    ///         );
721    ///     }
722    /// }
723    /// 
724    /// async fn logging_handler() -> Result<(), Box<dyn std::error::Error>> {
725    ///     let config = ClientConfig::new()
726    ///         .with_sip_addr("127.0.0.1:5065".parse()?);
727    ///     
728    ///     let client = ClientManager::new(config).await?;
729    ///     
730    ///     // Create logging handler
731    ///     let handler = Arc::new(LoggingEventHandler::new("MyVoIPApp"));
732    ///     client.set_event_handler(handler).await;
733    ///     
734    ///     client.start().await?;
735    ///     println!("✅ Logging event handler registered");
736    ///     
737    ///     client.stop().await?;
738    ///     Ok(())
739    /// }
740    /// ```
741    /// 
742    /// ## Event Handler Replacement
743    /// 
744    /// ```rust
745    /// use rvoip_client_core::{
746    ///     ClientManager, ClientConfig, ClientEventHandler,
747    ///     events::{CallStatusInfo, RegistrationStatusInfo, MediaEventInfo, IncomingCallInfo, CallAction}
748    /// };
749    /// use async_trait::async_trait;
750    /// use std::sync::Arc;
751    /// 
752    /// struct Handler1;
753    /// struct Handler2;
754    /// 
755    /// #[async_trait]
756    /// impl ClientEventHandler for Handler1 {
757    ///     async fn on_incoming_call(&self, _info: IncomingCallInfo) -> CallAction {
758    ///         CallAction::Accept
759    ///     }
760    ///     async fn on_call_state_changed(&self, info: CallStatusInfo) {
761    ///         println!("Handler1: Call {} -> {:?}", info.call_id, info.new_state);
762    ///     }
763    ///     async fn on_registration_status_changed(&self, _info: RegistrationStatusInfo) {}
764    ///     async fn on_media_event(&self, _info: MediaEventInfo) {}
765    /// }
766    /// 
767    /// #[async_trait]
768    /// impl ClientEventHandler for Handler2 {
769    ///     async fn on_incoming_call(&self, _info: IncomingCallInfo) -> CallAction {
770    ///         CallAction::Accept
771    ///     }
772    ///     async fn on_call_state_changed(&self, info: CallStatusInfo) {
773    ///         println!("Handler2: Call {} -> {:?}", info.call_id, info.new_state);
774    ///     }
775    ///     async fn on_registration_status_changed(&self, _info: RegistrationStatusInfo) {}
776    ///     async fn on_media_event(&self, _info: MediaEventInfo) {}
777    /// }
778    /// 
779    /// async fn handler_replacement() -> Result<(), Box<dyn std::error::Error>> {
780    ///     let config = ClientConfig::new()
781    ///         .with_sip_addr("127.0.0.1:5066".parse()?);
782    ///     
783    ///     let client = ClientManager::new(config).await?;
784    ///     client.start().await?;
785    ///     
786    ///     // Set initial handler
787    ///     let handler1 = Arc::new(Handler1);
788    ///     client.set_event_handler(handler1).await;
789    ///     println!("✅ Handler1 registered");
790    ///     
791    ///     // Replace with different handler
792    ///     let handler2 = Arc::new(Handler2);
793    ///     client.set_event_handler(handler2).await;
794    ///     println!("✅ Handler2 replaced Handler1");
795    ///     
796    ///     client.stop().await?;
797    ///     Ok(())
798    /// }
799    /// ```
800    /// 
801    /// # Implementation Notes
802    /// 
803    /// - **Thread Safety**: The handler is stored in an Arc<RwLock> for safe concurrent access
804    /// - **Async Execution**: All handler methods are called asynchronously
805    /// - **No Blocking**: Handlers should avoid blocking operations to prevent event queue backup
806    /// - **Error Handling**: Handler errors are logged but don't affect client operation
807    /// - **Replacement**: Setting a new handler replaces the previous one
808    /// 
809    /// # Best Practices
810    /// 
811    /// 1. **Keep handlers lightweight** - Avoid heavy computation in event callbacks
812    /// 2. **Use async patterns** - Leverage tokio for concurrent event processing
813    /// 3. **Handle errors gracefully** - Don't panic in event handlers
814    /// 4. **Consider batching** - For high-frequency events, consider batching updates
815    /// 5. **State management** - Use appropriate synchronization for handler state
816    pub async fn set_event_handler(&self, handler: Arc<dyn ClientEventHandler>) {
817        self.call_handler.set_event_handler(handler).await;
818    }
819    
820    /// Start the client manager
821    /// 
822    /// This method starts the client manager, initializing the underlying SIP transport,
823    /// binding to network addresses, and beginning event processing. The client must be
824    /// started before it can handle registrations, calls, or other SIP operations.
825    /// 
826    /// # Returns
827    /// 
828    /// Returns `Ok(())` if the client started successfully.
829    /// 
830    /// # Errors
831    /// 
832    /// * `ClientError::InternalError` - If the session coordinator fails to start
833    ///   (e.g., port already in use, network unavailable)
834    /// 
835    /// # Examples
836    /// 
837    /// ## Basic Start/Stop Cycle
838    /// 
839    /// ```rust
840    /// use rvoip_client_core::{ClientManager, ClientConfig};
841    /// 
842    /// async fn start_stop_cycle() -> Result<(), Box<dyn std::error::Error>> {
843    ///     let config = ClientConfig::new()
844    ///         .with_sip_addr("127.0.0.1:5067".parse()?);
845    ///     
846    ///     let client = ClientManager::new(config).await?;
847    ///     
848    ///     // Initially not running
849    ///     assert!(!client.is_running().await);
850    ///     
851    ///     // Start the client
852    ///     client.start().await?;
853    ///     assert!(client.is_running().await);
854    ///     println!("✅ Client started successfully");
855    ///     
856    ///     // Stop the client
857    ///     client.stop().await?;
858    ///     assert!(!client.is_running().await);
859    ///     println!("✅ Client stopped successfully");
860    ///     
861    ///     Ok(())
862    /// }
863    /// ```
864    /// 
865    /// ## Error Handling on Start
866    /// 
867    /// ```rust
868    /// use rvoip_client_core::{ClientManager, ClientConfig, ClientError};
869    /// 
870    /// async fn handle_start_errors() -> Result<(), Box<dyn std::error::Error>> {
871    ///     let config = ClientConfig::new()
872    ///         .with_sip_addr("127.0.0.1:5068".parse()?);
873    ///     
874    ///     let client = ClientManager::new(config).await?;
875    ///     
876    ///     match client.start().await {
877    ///         Ok(()) => {
878    ///             println!("✅ Client started successfully");
879    ///             client.stop().await?;
880    ///         }
881    ///         Err(ClientError::InternalError { message }) => {
882    ///             println!("❌ Failed to start client: {}", message);
883    ///             // Handle the error (retry with different port, etc.)
884    ///         }
885    ///         Err(e) => {
886    ///             println!("❌ Unexpected error: {}", e);
887    ///         }
888    ///     }
889    ///     
890    ///     Ok(())
891    /// }
892    /// ```
893    /// 
894    /// ## Multiple Start Attempts
895    /// 
896    /// ```rust
897    /// use rvoip_client_core::{ClientManager, ClientConfig};
898    /// 
899    /// async fn multiple_start_safe() -> Result<(), Box<dyn std::error::Error>> {
900    ///     let config = ClientConfig::new()
901    ///         .with_sip_addr("127.0.0.1:5069".parse()?);
902    ///     
903    ///     let client = ClientManager::new(config).await?;
904    ///     
905    ///     // Start the client
906    ///     client.start().await?;
907    ///     println!("✅ First start successful");
908    ///     
909    ///     // Multiple starts should be safe (idempotent)
910    ///     client.start().await?;
911    ///     println!("✅ Second start (should be no-op)");
912    ///     
913    ///     assert!(client.is_running().await);
914    ///     
915    ///     client.stop().await?;
916    ///     Ok(())
917    /// }
918    /// ```
919    pub async fn start(&self) -> ClientResult<()> {
920        // Start the session coordinator using SessionControl trait
921        SessionControl::start(&self.coordinator)
922            .await
923            .map_err(|e| ClientError::InternalError { 
924                message: format!("Failed to start session coordinator: {}", e) 
925            })?;
926            
927        *self.is_running.write().await = true;
928        
929        // Update stats with actual bound addresses
930        let actual_addr = SessionControl::get_bound_address(&self.coordinator);
931        let mut stats = self.stats.lock().await;
932        stats.is_running = true;
933        stats.local_sip_addr = actual_addr;
934        
935        tracing::info!("ClientManager started on {}", actual_addr);
936        Ok(())
937    }
938    
939    /// Stop the client manager
940    /// 
941    /// This method gracefully shuts down the client manager, terminating all active
942    /// calls, cleaning up network resources, and stopping event processing. Any active
943    /// registrations will be automatically unregistered.
944    /// 
945    /// # Returns
946    /// 
947    /// Returns `Ok(())` if the client stopped successfully.
948    /// 
949    /// # Errors
950    /// 
951    /// * `ClientError::InternalError` - If the session coordinator fails to stop cleanly
952    /// 
953    /// # Examples
954    /// 
955    /// ## Graceful Shutdown
956    /// 
957    /// ```rust
958    /// use rvoip_client_core::{ClientManager, ClientConfig};
959    /// 
960    /// async fn graceful_shutdown() -> Result<(), Box<dyn std::error::Error>> {
961    ///     let config = ClientConfig::new()
962    ///         .with_sip_addr("127.0.0.1:5070".parse()?);
963    ///     
964    ///     let client = ClientManager::new(config).await?;
965    ///     client.start().await?;
966    ///     
967    ///     // Do some work...
968    ///     println!("Client running...");
969    ///     
970    ///     // Graceful shutdown
971    ///     client.stop().await?;
972    ///     assert!(!client.is_running().await);
973    ///     println!("✅ Client stopped gracefully");
974    ///     
975    ///     Ok(())
976    /// }
977    /// ```
978    /// 
979    /// ## Error Handling on Stop
980    /// 
981    /// ```rust
982    /// use rvoip_client_core::{ClientManager, ClientConfig, ClientError};
983    /// 
984    /// async fn handle_stop_errors() -> Result<(), Box<dyn std::error::Error>> {
985    ///     let config = ClientConfig::new()
986    ///         .with_sip_addr("127.0.0.1:5071".parse()?);
987    ///     
988    ///     let client = ClientManager::new(config).await?;
989    ///     client.start().await?;
990    ///     
991    ///     match client.stop().await {
992    ///         Ok(()) => {
993    ///             println!("✅ Client stopped successfully");
994    ///         }
995    ///         Err(ClientError::InternalError { message }) => {
996    ///             println!("⚠️  Stop had issues: {}", message);
997    ///             // Resources may still be partially cleaned up
998    ///         }
999    ///         Err(e) => {
1000    ///             println!("❌ Unexpected error during stop: {}", e);
1001    ///         }
1002    ///     }
1003    ///     
1004    ///     Ok(())
1005    /// }
1006    /// ```
1007    /// 
1008    /// ## Multiple Stop Attempts
1009    /// 
1010    /// ```rust
1011    /// use rvoip_client_core::{ClientManager, ClientConfig};
1012    /// 
1013    /// async fn multiple_stop_safe() -> Result<(), Box<dyn std::error::Error>> {
1014    ///     let config = ClientConfig::new()
1015    ///         .with_sip_addr("127.0.0.1:5072".parse()?);
1016    ///     
1017    ///     let client = ClientManager::new(config).await?;
1018    ///     client.start().await?;
1019    ///     
1020    ///     // Stop the client
1021    ///     client.stop().await?;
1022    ///     println!("✅ First stop successful");
1023    ///     
1024    ///     // Multiple stops should be safe (idempotent)
1025    ///     client.stop().await?;
1026    ///     println!("✅ Second stop (should be no-op)");
1027    ///     
1028    ///     assert!(!client.is_running().await);
1029    ///     
1030    ///     Ok(())
1031    /// }
1032    /// ```
1033    pub async fn stop(&self) -> ClientResult<()> {
1034        // Cancel the audio setup task if it's running
1035        if let Some(task) = self.audio_setup_task.lock().await.take() {
1036            task.abort();
1037        }
1038        
1039        SessionControl::stop(&self.coordinator)
1040            .await
1041            .map_err(|e| ClientError::InternalError { 
1042                message: format!("Failed to stop session coordinator: {}", e) 
1043            })?;
1044            
1045        *self.is_running.write().await = false;
1046        
1047        let mut stats = self.stats.lock().await;
1048        stats.is_running = false;
1049        
1050        tracing::info!("ClientManager stopped");
1051        Ok(())
1052    }
1053    
1054    /// Register with a SIP server
1055    /// 
1056    /// This method registers the client with a SIP server using the REGISTER method.
1057    /// Registration allows the client to receive incoming calls and establishes its
1058    /// presence on the SIP network. The method handles authentication challenges
1059    /// automatically and includes retry logic for network issues.
1060    /// 
1061    /// # Arguments
1062    /// 
1063    /// * `config` - Registration configuration including server URI, user credentials,
1064    ///              and expiration settings
1065    /// 
1066    /// # Returns
1067    /// 
1068    /// Returns a `Uuid` that uniquely identifies this registration for future operations.
1069    /// 
1070    /// # Errors
1071    /// 
1072    /// * `ClientError::AuthenticationFailed` - Invalid credentials or auth challenge failed
1073    /// * `ClientError::RegistrationFailed` - Server rejected registration (403, etc.)
1074    /// * `ClientError::NetworkError` - Network timeout or connectivity issues
1075    /// 
1076    /// # Examples
1077    /// 
1078    /// ## Basic Registration
1079    /// 
1080    /// ```rust
1081    /// use rvoip_client_core::{ClientManager, ClientConfig, RegistrationConfig};
1082    /// 
1083    /// async fn basic_registration() -> Result<(), Box<dyn std::error::Error>> {
1084    ///     let config = ClientConfig::new()
1085    ///         .with_sip_addr("127.0.0.1:5073".parse()?);
1086    ///     
1087    ///     let client = ClientManager::new(config).await?;
1088    ///     client.start().await?;
1089    ///     
1090    ///     let reg_config = RegistrationConfig {
1091    ///         server_uri: "sip:sip.example.com:5060".to_string(),
1092    ///         from_uri: "sip:alice@example.com".to_string(),
1093    ///         contact_uri: "sip:alice@127.0.0.1:5073".to_string(),
1094    ///         expires: 3600,
1095    ///         username: None,
1096    ///         password: None,
1097    ///         realm: None,
1098    ///     };
1099    ///     
1100    ///     let reg_id = client.register(reg_config).await?;
1101    ///     println!("✅ Registered with ID: {}", reg_id);
1102    ///     
1103    ///     client.unregister(reg_id).await?;
1104    ///     client.stop().await?;
1105    ///     Ok(())
1106    /// }
1107    /// ```
1108    /// 
1109    /// ## Registration with Authentication
1110    /// 
1111    /// ```rust
1112    /// use rvoip_client_core::{ClientManager, ClientConfig, RegistrationConfig};
1113    /// 
1114    /// async fn authenticated_registration() -> Result<(), Box<dyn std::error::Error>> {
1115    ///     let config = ClientConfig::new()
1116    ///         .with_sip_addr("127.0.0.1:5074".parse()?);
1117    ///     
1118    ///     let client = ClientManager::new(config).await?;
1119    ///     client.start().await?;
1120    ///     
1121    ///     let reg_config = RegistrationConfig {
1122    ///         server_uri: "sip:pbx.company.com".to_string(),
1123    ///         from_uri: "sip:user@company.com".to_string(),
1124    ///         contact_uri: "sip:user@127.0.0.1:5074".to_string(),
1125    ///         expires: 1800, // 30 minutes
1126    ///         username: Some("user".to_string()),
1127    ///         password: Some("password123".to_string()),
1128    ///         realm: Some("company.com".to_string()),
1129    ///     };
1130    ///     
1131    ///     match client.register(reg_config).await {
1132    ///         Ok(reg_id) => {
1133    ///             println!("✅ Authenticated registration successful: {}", reg_id);
1134    ///             client.unregister(reg_id).await?;
1135    ///         }
1136    ///         Err(e) => {
1137    ///             println!("❌ Registration failed: {}", e);
1138    ///         }
1139    ///     }
1140    ///     
1141    ///     client.stop().await?;
1142    ///     Ok(())
1143    /// }
1144    /// ```
1145    /// 
1146    /// ## Multiple Registrations
1147    /// 
1148    /// ```rust
1149    /// use rvoip_client_core::{ClientManager, ClientConfig, RegistrationConfig};
1150    /// 
1151    /// async fn multiple_registrations() -> Result<(), Box<dyn std::error::Error>> {
1152    ///     let config = ClientConfig::new()
1153    ///         .with_sip_addr("127.0.0.1:5075".parse()?);
1154    ///     
1155    ///     let client = ClientManager::new(config).await?;
1156    ///     client.start().await?;
1157    ///     
1158    ///     // Register with multiple servers
1159    ///     let reg1_config = RegistrationConfig {
1160    ///         server_uri: "sip:server1.com".to_string(),
1161    ///         from_uri: "sip:alice@server1.com".to_string(),
1162    ///         contact_uri: "sip:alice@127.0.0.1:5075".to_string(),
1163    ///         expires: 3600,
1164    ///         username: None,
1165    ///         password: None,
1166    ///         realm: None,
1167    ///     };
1168    ///     
1169    ///     let reg2_config = RegistrationConfig {
1170    ///         server_uri: "sip:server2.com".to_string(),
1171    ///         from_uri: "sip:alice@server2.com".to_string(),
1172    ///         contact_uri: "sip:alice@127.0.0.1:5075".to_string(),
1173    ///         expires: 3600,
1174    ///         username: None,
1175    ///         password: None,
1176    ///         realm: None,
1177    ///     };
1178    ///     
1179    ///     let reg1_id = client.register(reg1_config).await?;
1180    ///     let reg2_id = client.register(reg2_config).await?;
1181    ///     
1182    ///     println!("✅ Registered with {} servers", 2);
1183    ///     
1184    ///     // Check all registrations
1185    ///     let all_regs = client.get_all_registrations().await;
1186    ///     assert_eq!(all_regs.len(), 2);
1187    ///     
1188    ///     // Clean up
1189    ///     client.unregister(reg1_id).await?;
1190    ///     client.unregister(reg2_id).await?;
1191    ///     client.stop().await?;
1192    ///     Ok(())
1193    /// }
1194    /// ```
1195    pub async fn register(&self, config: RegistrationConfig) -> ClientResult<Uuid> {
1196        // Use SipClient trait to register with retry logic for network errors
1197        let registration_handle = retry_with_backoff(
1198            "sip_registration",
1199            RetryConfig::slow(),  // Use slower retry for registration
1200            || async {
1201                SipClient::register(
1202                    &self.coordinator,
1203                    &config.server_uri,
1204                    &config.from_uri,
1205                    &config.contact_uri,
1206                    config.expires,
1207                )
1208                .await
1209                .map_err(|e| {
1210                    // Categorize the error properly based on response
1211                    let error_msg = e.to_string();
1212                    if error_msg.contains("401") || error_msg.contains("407") {
1213                        ClientError::AuthenticationFailed {
1214                            reason: format!("Authentication required: {}", e)
1215                        }
1216                    } else if error_msg.contains("timeout") {
1217                        ClientError::NetworkError {
1218                            reason: format!("Registration timeout: {}", e)
1219                        }
1220                    } else if error_msg.contains("403") {
1221                        ClientError::RegistrationFailed {
1222                            reason: format!("Registration forbidden: {}", e)
1223                        }
1224                    } else {
1225                        ClientError::RegistrationFailed {
1226                            reason: format!("Registration failed: {}", e)
1227                        }
1228                    }
1229                })
1230            }
1231        )
1232        .await
1233        .with_context(|| format!("Failed to register {} with {}", config.from_uri, config.server_uri))?;
1234        
1235        // Create registration info
1236        let reg_id = Uuid::new_v4();
1237        let registration_info = RegistrationInfo {
1238            id: reg_id,
1239            server_uri: config.server_uri.clone(),
1240            from_uri: config.from_uri.clone(),
1241            contact_uri: config.contact_uri.clone(),
1242            expires: config.expires,
1243            status: crate::registration::RegistrationStatus::Active,
1244            registration_time: chrono::Utc::now(),
1245            refresh_time: None,
1246            handle: Some(registration_handle),
1247        };
1248        
1249        // Store registration
1250        self.registrations.write().await.insert(reg_id, registration_info);
1251        
1252        // Update stats
1253        let mut stats = self.stats.lock().await;
1254        stats.total_registrations += 1;
1255        stats.active_registrations += 1;
1256        
1257        // Broadcast registration event
1258        let _ = self.event_tx.send(ClientEvent::RegistrationStatusChanged {
1259            info: crate::events::RegistrationStatusInfo {
1260                registration_id: reg_id,
1261                server_uri: config.server_uri.clone(),
1262                user_uri: config.from_uri.clone(),
1263                status: crate::registration::RegistrationStatus::Active,
1264                reason: Some("Registration successful".to_string()),
1265                timestamp: chrono::Utc::now(),
1266            },
1267            priority: crate::events::EventPriority::Normal,
1268        });
1269        
1270        tracing::info!("Registered {} with server {}", config.from_uri, config.server_uri);
1271        Ok(reg_id)
1272    }
1273    
1274    /// Unregister from a SIP server
1275    /// 
1276    /// This method removes a registration from a SIP server by sending a REGISTER
1277    /// request with expires=0. This gracefully removes the client's presence from
1278    /// the server and stops receiving incoming calls for that registration.
1279    /// 
1280    /// # Arguments
1281    /// 
1282    /// * `reg_id` - The UUID of the registration to remove
1283    /// 
1284    /// # Returns
1285    /// 
1286    /// Returns `Ok(())` if the unregistration was successful.
1287    /// 
1288    /// # Errors
1289    /// 
1290    /// * `ClientError::InvalidConfiguration` - If the registration ID is not found
1291    /// * `ClientError::InternalError` - If the unregistration request fails
1292    /// 
1293    /// # Examples
1294    /// 
1295    /// ```rust
1296    /// use rvoip_client_core::{ClientManager, ClientConfig, RegistrationConfig};
1297    /// 
1298    /// async fn unregister_example() -> Result<(), Box<dyn std::error::Error>> {
1299    ///     let config = ClientConfig::new()
1300    ///         .with_sip_addr("127.0.0.1:5079".parse()?);
1301    ///     
1302    ///     let client = ClientManager::new(config).await?;
1303    ///     client.start().await?;
1304    ///     
1305    ///     let reg_config = RegistrationConfig {
1306    ///         server_uri: "sip:server.example.com".to_string(),
1307    ///         from_uri: "sip:alice@example.com".to_string(),
1308    ///         contact_uri: "sip:alice@127.0.0.1:5079".to_string(),
1309    ///         expires: 3600,
1310    ///         username: None,
1311    ///         password: None,
1312    ///         realm: None,
1313    ///     };
1314    ///     
1315    ///     let reg_id = client.register(reg_config).await?;
1316    ///     println!("✅ Registered with ID: {}", reg_id);
1317    ///     
1318    ///     // Unregister
1319    ///     client.unregister(reg_id).await?;
1320    ///     println!("✅ Successfully unregistered");
1321    ///     
1322    ///     client.stop().await?;
1323    ///     Ok(())
1324    /// }
1325    /// ```
1326    pub async fn unregister(&self, reg_id: Uuid) -> ClientResult<()> {
1327        let mut registrations = self.registrations.write().await;
1328        
1329        if let Some(registration_info) = registrations.get_mut(&reg_id) {
1330            // To unregister, send REGISTER with expires=0
1331            if let Some(handle) = &registration_info.handle {
1332                SipClient::register(
1333                    &self.coordinator,
1334                    &handle.registrar_uri,
1335                    &registration_info.from_uri,
1336                    &handle.contact_uri,
1337                    0, // expires=0 means unregister
1338                )
1339                .await
1340                .map_err(|e| ClientError::InternalError { 
1341                    message: format!("Failed to unregister: {}", e) 
1342                })?;
1343            }
1344            
1345            // Update status
1346            registration_info.status = crate::registration::RegistrationStatus::Cancelled;
1347            registration_info.handle = None;
1348            
1349            // Update stats
1350            let mut stats = self.stats.lock().await;
1351            if stats.active_registrations > 0 {
1352                stats.active_registrations -= 1;
1353            }
1354            
1355            tracing::info!("Unregistered {}", registration_info.from_uri);
1356            Ok(())
1357        } else {
1358            Err(ClientError::InvalidConfiguration { 
1359                field: "registration_id".to_string(),
1360                reason: "Registration not found".to_string() 
1361            })
1362        }
1363    }
1364    
1365    /// Get registration information
1366    /// 
1367    /// Retrieves detailed information about a specific registration including
1368    /// status, timestamps, and server details.
1369    /// 
1370    /// # Arguments
1371    /// 
1372    /// * `reg_id` - The UUID of the registration to retrieve
1373    /// 
1374    /// # Returns
1375    /// 
1376    /// Returns the `RegistrationInfo` struct containing all registration details.
1377    /// 
1378    /// # Errors
1379    /// 
1380    /// * `ClientError::InvalidConfiguration` - If the registration ID is not found
1381    /// 
1382    /// # Examples
1383    /// 
1384    /// ```rust
1385    /// use rvoip_client_core::{ClientManager, ClientConfig, RegistrationConfig};
1386    /// 
1387    /// async fn get_registration_info() -> Result<(), Box<dyn std::error::Error>> {
1388    ///     let config = ClientConfig::new()
1389    ///         .with_sip_addr("127.0.0.1:5080".parse()?);
1390    ///     
1391    ///     let client = ClientManager::new(config).await?;
1392    ///     client.start().await?;
1393    ///     
1394    ///     let reg_config = RegistrationConfig {
1395    ///         server_uri: "sip:server.example.com".to_string(),
1396    ///         from_uri: "sip:user@example.com".to_string(),
1397    ///         contact_uri: "sip:user@127.0.0.1:5080".to_string(),
1398    ///         expires: 1800,
1399    ///         username: None,
1400    ///         password: None,
1401    ///         realm: None,
1402    ///     };
1403    ///     
1404    ///     let reg_id = client.register(reg_config).await?;
1405    ///     
1406    ///     // Get registration details
1407    ///     let reg_info = client.get_registration(reg_id).await?;
1408    ///     println!("Registration status: {:?}", reg_info.status);
1409    ///     println!("Server: {}", reg_info.server_uri);
1410    ///     println!("User: {}", reg_info.from_uri);
1411    ///     println!("Expires: {} seconds", reg_info.expires);
1412    ///     
1413    ///     client.unregister(reg_id).await?;
1414    ///     client.stop().await?;
1415    ///     Ok(())
1416    /// }
1417    /// ```
1418    pub async fn get_registration(&self, reg_id: Uuid) -> ClientResult<crate::registration::RegistrationInfo> {
1419        let registrations = self.registrations.read().await;
1420        registrations.get(&reg_id)
1421            .cloned()
1422            .ok_or(ClientError::InvalidConfiguration { 
1423                field: "registration_id".to_string(),
1424                reason: "Registration not found".to_string() 
1425            })
1426    }
1427    
1428    /// Get all active registrations
1429    /// 
1430    /// Returns a list of all currently active registrations. This includes only
1431    /// registrations with status `Active`, filtering out expired or cancelled ones.
1432    /// 
1433    /// # Returns
1434    /// 
1435    /// Returns a `Vec<RegistrationInfo>` containing all active registrations.
1436    /// 
1437    /// # Examples
1438    /// 
1439    /// ```rust
1440    /// use rvoip_client_core::{ClientManager, ClientConfig, RegistrationConfig};
1441    /// 
1442    /// async fn list_registrations() -> Result<(), Box<dyn std::error::Error>> {
1443    ///     let config = ClientConfig::new()
1444    ///         .with_sip_addr("127.0.0.1:5081".parse()?);
1445    ///     
1446    ///     let client = ClientManager::new(config).await?;
1447    ///     client.start().await?;
1448    ///     
1449    ///     // Create multiple registrations
1450    ///     let reg1_config = RegistrationConfig {
1451    ///         server_uri: "sip:server1.com".to_string(),
1452    ///         from_uri: "sip:alice@server1.com".to_string(),
1453    ///         contact_uri: "sip:alice@127.0.0.1:5081".to_string(),
1454    ///         expires: 3600,
1455    ///         username: None,
1456    ///         password: None,
1457    ///         realm: None,
1458    ///     };
1459    ///     
1460    ///     let reg2_config = RegistrationConfig {
1461    ///         server_uri: "sip:server2.com".to_string(),
1462    ///         from_uri: "sip:alice@server2.com".to_string(),
1463    ///         contact_uri: "sip:alice@127.0.0.1:5081".to_string(),
1464    ///         expires: 1800,
1465    ///         username: None,
1466    ///         password: None,
1467    ///         realm: None,
1468    ///     };
1469    ///     
1470    ///     let _reg1_id = client.register(reg1_config).await?;
1471    ///     let _reg2_id = client.register(reg2_config).await?;
1472    ///     
1473    ///     // List all active registrations
1474    ///     let active_regs = client.get_all_registrations().await;
1475    ///     println!("Active registrations: {}", active_regs.len());
1476    ///     
1477    ///     for reg in active_regs {
1478    ///         println!("- {} at {}", reg.from_uri, reg.server_uri);
1479    ///     }
1480    ///     
1481    ///     client.stop().await?;
1482    ///     Ok(())
1483    /// }
1484    /// ```
1485    pub async fn get_all_registrations(&self) -> Vec<crate::registration::RegistrationInfo> {
1486        let registrations = self.registrations.read().await;
1487        registrations.values()
1488            .filter(|r| r.status == crate::registration::RegistrationStatus::Active)
1489            .cloned()
1490            .collect()
1491    }
1492    
1493    /// Refresh a registration
1494    /// 
1495    /// Manually refreshes a registration by sending a new REGISTER request with
1496    /// the same parameters. This is useful for extending registration lifetime
1497    /// before expiration or after network connectivity issues.
1498    /// 
1499    /// # Arguments
1500    /// 
1501    /// * `reg_id` - The UUID of the registration to refresh
1502    /// 
1503    /// # Returns
1504    /// 
1505    /// Returns `Ok(())` if the registration was successfully refreshed.
1506    /// 
1507    /// # Errors
1508    /// 
1509    /// * `ClientError::InvalidConfiguration` - If the registration ID is not found
1510    /// * `ClientError::InternalError` - If the refresh request fails
1511    /// 
1512    /// # Examples
1513    /// 
1514    /// ```rust
1515    /// use rvoip_client_core::{ClientManager, ClientConfig, RegistrationConfig};
1516    /// 
1517    /// async fn refresh_registration_example() -> Result<(), Box<dyn std::error::Error>> {
1518    ///     let config = ClientConfig::new()
1519    ///         .with_sip_addr("127.0.0.1:5082".parse()?);
1520    ///     
1521    ///     let client = ClientManager::new(config).await?;
1522    ///     client.start().await?;
1523    ///     
1524    ///     let reg_config = RegistrationConfig {
1525    ///         server_uri: "sip:server.example.com".to_string(),
1526    ///         from_uri: "sip:user@example.com".to_string(),
1527    ///         contact_uri: "sip:user@127.0.0.1:5082".to_string(),
1528    ///         expires: 300, // Short expiration for demo
1529    ///         username: None,
1530    ///         password: None,
1531    ///         realm: None,
1532    ///     };
1533    ///     
1534    ///     let reg_id = client.register(reg_config).await?;
1535    ///     println!("✅ Initial registration completed");
1536    ///     
1537    ///     // Refresh the registration
1538    ///     client.refresh_registration(reg_id).await?;
1539    ///     println!("✅ Registration refreshed successfully");
1540    ///     
1541    ///     // Check registration info
1542    ///     if let Ok(reg_info) = client.get_registration(reg_id).await {
1543    ///         if let Some(refresh_time) = reg_info.refresh_time {
1544    ///             println!("Last refreshed: {}", refresh_time);
1545    ///         }
1546    ///     }
1547    ///     
1548    ///     client.unregister(reg_id).await?;
1549    ///     client.stop().await?;
1550    ///     Ok(())
1551    /// }
1552    /// ```
1553    pub async fn refresh_registration(&self, reg_id: Uuid) -> ClientResult<()> {
1554        // Get registration data
1555        let (registrar_uri, from_uri, contact_uri, expires) = {
1556            let registrations = self.registrations.read().await;
1557            
1558            if let Some(registration_info) = registrations.get(&reg_id) {
1559                if let Some(handle) = &registration_info.handle {
1560                    (
1561                        handle.registrar_uri.clone(),
1562                        registration_info.from_uri.clone(),
1563                        handle.contact_uri.clone(),
1564                        registration_info.expires,
1565                    )
1566                } else {
1567                    return Err(ClientError::InvalidConfiguration { 
1568                        field: "registration".to_string(),
1569                        reason: "Registration has no handle".to_string() 
1570                    });
1571                }
1572            } else {
1573                return Err(ClientError::InvalidConfiguration { 
1574                    field: "registration_id".to_string(),
1575                    reason: "Registration not found".to_string() 
1576                });
1577            }
1578        };
1579        
1580        // Re-register with the same parameters
1581        let new_handle = SipClient::register(
1582            &self.coordinator,
1583            &registrar_uri,
1584            &from_uri,
1585            &contact_uri,
1586            expires,
1587        )
1588        .await
1589        .map_err(|e| ClientError::InternalError { 
1590            message: format!("Failed to refresh registration: {}", e) 
1591        })?;
1592        
1593        // Update registration with new handle
1594        let mut registrations = self.registrations.write().await;
1595        if let Some(reg) = registrations.get_mut(&reg_id) {
1596            reg.handle = Some(new_handle);
1597            reg.refresh_time = Some(chrono::Utc::now());
1598        }
1599        
1600        tracing::info!("Refreshed registration for {}", from_uri);
1601        Ok(())
1602    }
1603    
1604    /// Clear expired registrations
1605    /// 
1606    /// Removes all registrations with `Expired` status from the internal storage.
1607    /// This is a maintenance operation that cleans up stale registration entries
1608    /// and updates statistics accordingly.
1609    /// 
1610    /// # Examples
1611    /// 
1612    /// ```rust
1613    /// use rvoip_client_core::{ClientManager, ClientConfig};
1614    /// 
1615    /// async fn cleanup_registrations() -> Result<(), Box<dyn std::error::Error>> {
1616    ///     let config = ClientConfig::new()
1617    ///         .with_sip_addr("127.0.0.1:5083".parse()?);
1618    ///     
1619    ///     let client = ClientManager::new(config).await?;
1620    ///     client.start().await?;
1621    ///     
1622    ///     // In a real application, you might have some expired registrations
1623    ///     // This method would clean them up
1624    ///     client.clear_expired_registrations().await;
1625    ///     println!("✅ Expired registrations cleaned up");
1626    ///     
1627    ///     // Check remaining active registrations
1628    ///     let active_count = client.get_all_registrations().await.len();
1629    ///     println!("Active registrations remaining: {}", active_count);
1630    ///     
1631    ///     client.stop().await?;
1632    ///     Ok(())
1633    /// }
1634    /// ```
1635    pub async fn clear_expired_registrations(&self) {
1636        let mut registrations = self.registrations.write().await;
1637        let mut to_remove = Vec::new();
1638        
1639        for (id, reg) in registrations.iter() {
1640            if reg.status == crate::registration::RegistrationStatus::Expired {
1641                to_remove.push(*id);
1642            }
1643        }
1644        
1645        for id in to_remove {
1646            registrations.remove(&id);
1647            
1648            // Update stats
1649            let mut stats = self.stats.lock().await;
1650            if stats.active_registrations > 0 {
1651                stats.active_registrations -= 1;
1652            }
1653        }
1654    }
1655    
1656    // ===== CONVENIENCE METHODS FOR EXAMPLES =====
1657    
1658    /// Convenience method: Register with simple parameters (for examples)
1659    /// 
1660    /// This is a simplified registration method that takes basic parameters and
1661    /// constructs a complete `RegistrationConfig` automatically. It's designed
1662    /// for quick testing and simple use cases.
1663    /// 
1664    /// # Arguments
1665    /// 
1666    /// * `agent_uri` - The SIP URI for this agent (e.g., "sip:alice@example.com")
1667    /// * `server_addr` - The SIP server address and port
1668    /// * `duration` - How long the registration should last
1669    /// 
1670    /// # Returns
1671    /// 
1672    /// Returns `Ok(())` if registration was successful.
1673    /// 
1674    /// # Examples
1675    /// 
1676    /// ```rust
1677    /// use rvoip_client_core::{ClientManager, ClientConfig};
1678    /// use std::time::Duration;
1679    /// 
1680    /// async fn simple_register() -> Result<(), Box<dyn std::error::Error>> {
1681    ///     let config = ClientConfig::new()
1682    ///         .with_sip_addr("127.0.0.1:5084".parse()?);
1683    ///     
1684    ///     let client = ClientManager::new(config).await?;
1685    ///     client.start().await?;
1686    ///     
1687    ///     let server_addr = "192.168.1.100:5060".parse()?;
1688    ///     let duration = Duration::from_secs(3600); // 1 hour
1689    ///     
1690    ///     // Simple registration
1691    ///     client.register_simple(
1692    ///         "sip:testuser@example.com",
1693    ///         &server_addr,
1694    ///         duration
1695    ///     ).await?;
1696    ///     
1697    ///     println!("✅ Simple registration completed");
1698    ///     
1699    ///     // Cleanup using the simple unregister method
1700    ///     client.unregister_simple(
1701    ///         "sip:testuser@example.com",
1702    ///         &server_addr
1703    ///     ).await?;
1704    ///     
1705    ///     client.stop().await?;
1706    ///     Ok(())
1707    /// }
1708    /// ```
1709    pub async fn register_simple(
1710        &self, 
1711        agent_uri: &str, 
1712        server_addr: &std::net::SocketAddr,
1713        duration: std::time::Duration
1714    ) -> ClientResult<()> {
1715        let config = RegistrationConfig {
1716            server_uri: format!("sip:{}", server_addr),
1717            from_uri: agent_uri.to_string(),
1718            contact_uri: format!("sip:{}:{}", self.local_sip_addr.ip(), self.local_sip_addr.port()),
1719            expires: duration.as_secs() as u32,
1720            username: None,
1721            password: None,
1722            realm: None,
1723        };
1724        
1725        self.register(config).await?;
1726        Ok(())
1727    }
1728    
1729    /// Convenience method: Unregister with simple parameters (for examples)
1730    /// 
1731    /// This method finds and unregisters a registration that matches the given
1732    /// agent URI and server address. It's the counterpart to `register_simple()`
1733    /// and provides an easy way to clean up simple registrations.
1734    /// 
1735    /// # Arguments
1736    /// 
1737    /// * `agent_uri` - The SIP URI that was registered
1738    /// * `server_addr` - The SIP server address that was used
1739    /// 
1740    /// # Returns
1741    /// 
1742    /// Returns `Ok(())` if unregistration was successful.
1743    /// 
1744    /// # Errors
1745    /// 
1746    /// * `ClientError::InvalidConfiguration` - If no matching registration is found
1747    /// 
1748    /// # Examples
1749    /// 
1750    /// ```rust
1751    /// use rvoip_client_core::{ClientManager, ClientConfig};
1752    /// use std::time::Duration;
1753    /// 
1754    /// async fn simple_unregister() -> Result<(), Box<dyn std::error::Error>> {
1755    ///     let config = ClientConfig::new()
1756    ///         .with_sip_addr("127.0.0.1:5085".parse()?);
1757    ///     
1758    ///     let client = ClientManager::new(config).await?;
1759    ///     client.start().await?;
1760    ///     
1761    ///     let agent_uri = "sip:testuser@example.com";
1762    ///     let server_addr = "192.168.1.100:5060".parse()?;
1763    ///     
1764    ///     // Register first
1765    ///     client.register_simple(
1766    ///         agent_uri,
1767    ///         &server_addr,
1768    ///         Duration::from_secs(3600)
1769    ///     ).await?;
1770    ///     
1771    ///     println!("✅ Registration completed");
1772    ///     
1773    ///     // Now unregister using the same parameters
1774    ///     client.unregister_simple(agent_uri, &server_addr).await?;
1775    ///     println!("✅ Unregistration completed");
1776    ///     
1777    ///     // Verify no active registrations remain
1778    ///     let active_regs = client.get_all_registrations().await;
1779    ///     assert_eq!(active_regs.len(), 0);
1780    ///     
1781    ///     client.stop().await?;
1782    ///     Ok(())
1783    /// }
1784    /// ```
1785    pub async fn unregister_simple(
1786        &self, 
1787        agent_uri: &str, 
1788        server_addr: &std::net::SocketAddr
1789    ) -> ClientResult<()> {
1790        // Find the registration matching these parameters
1791        let registrations = self.registrations.read().await;
1792        let reg_id = registrations.iter()
1793            .find(|(_, reg)| {
1794                reg.from_uri == agent_uri && 
1795                reg.server_uri == format!("sip:{}", server_addr)
1796            })
1797            .map(|(id, _)| *id);
1798        drop(registrations);
1799        
1800        if let Some(id) = reg_id {
1801            self.unregister(id).await
1802        } else {
1803            Err(ClientError::InvalidConfiguration { 
1804                field: "registration".to_string(),
1805                reason: "No matching registration found".to_string() 
1806            })
1807        }
1808    }
1809    
1810    /// Subscribe to client events
1811    /// 
1812    /// Creates a new receiver for the client event broadcast channel. Multiple
1813    /// subscribers can listen to the same events simultaneously.
1814    /// 
1815    /// # Returns
1816    /// 
1817    /// Returns a `broadcast::Receiver<ClientEvent>` for receiving real-time events.
1818    /// 
1819    /// # Examples
1820    /// 
1821    /// ```rust
1822    /// use rvoip_client_core::{ClientManager, ClientConfig, ClientEvent};
1823    /// use tokio::time::{timeout, Duration};
1824    /// 
1825    /// async fn event_subscription() -> Result<(), Box<dyn std::error::Error>> {
1826    ///     let config = ClientConfig::new()
1827    ///         .with_sip_addr("127.0.0.1:5076".parse()?);
1828    ///     
1829    ///     let client = ClientManager::new(config).await?;
1830    ///     let mut events = client.subscribe_events();
1831    ///     
1832    ///     client.start().await?;
1833    ///     
1834    ///     // Listen for events (with timeout for doc test)
1835    ///     if let Ok(Ok(event)) = timeout(Duration::from_millis(10), events.recv()).await {
1836    ///         match event {
1837    ///             ClientEvent::CallStateChanged { info, .. } => {
1838    ///                 println!("Call event: {:?}", info.new_state);
1839    ///             }
1840    ///             ClientEvent::RegistrationStatusChanged { info, .. } => {
1841    ///                 println!("Registration event: {:?}", info.status);
1842    ///             }
1843    ///             ClientEvent::MediaEvent { info, .. } => {
1844    ///                 println!("Media event for call: {}", info.call_id);
1845    ///             }
1846    ///             ClientEvent::IncomingCall { .. } | 
1847    ///             ClientEvent::ClientError { .. } | 
1848    ///             ClientEvent::NetworkEvent { .. } => {
1849    ///                 // Handle other events as needed
1850    ///             }
1851    ///         }
1852    ///     }
1853    ///     
1854    ///     client.stop().await?;
1855    ///     Ok(())
1856    /// }
1857    /// ```
1858    pub fn subscribe_events(&self) -> tokio::sync::broadcast::Receiver<ClientEvent> {
1859        self.event_tx.subscribe()
1860    }
1861    
1862    /// Check if the client is running
1863    /// 
1864    /// Returns the current running state of the client manager. A client must be
1865    /// started before it can handle SIP operations.
1866    /// 
1867    /// # Returns
1868    /// 
1869    /// Returns `true` if the client is currently running, `false` otherwise.
1870    /// 
1871    /// # Examples
1872    /// 
1873    /// ```rust
1874    /// use rvoip_client_core::{ClientManager, ClientConfig};
1875    /// 
1876    /// async fn check_running_state() -> Result<(), Box<dyn std::error::Error>> {
1877    ///     let config = ClientConfig::new()
1878    ///         .with_sip_addr("127.0.0.1:5077".parse()?);
1879    ///     
1880    ///     let client = ClientManager::new(config).await?;
1881    ///     
1882    ///     // Initially not running
1883    ///     assert!(!client.is_running().await);
1884    ///     
1885    ///     // Start and check
1886    ///     client.start().await?;
1887    ///     assert!(client.is_running().await);
1888    ///     
1889    ///     // Stop and check
1890    ///     client.stop().await?;
1891    ///     assert!(!client.is_running().await);
1892    ///     
1893    ///     Ok(())
1894    /// }
1895    /// ```
1896    pub async fn is_running(&self) -> bool {
1897        *self.is_running.read().await
1898    }
1899    
1900    /// Get the media configuration
1901    /// 
1902    /// Returns a reference to the current media configuration being used by the client.
1903    /// This includes codec preferences, quality settings, and network parameters.
1904    /// 
1905    /// # Returns
1906    /// 
1907    /// Returns a reference to the `MediaConfig` used during client initialization.
1908    /// 
1909    /// # Examples
1910    /// 
1911    /// ```rust
1912    /// use rvoip_client_core::{ClientManager, ClientConfig, MediaConfig, MediaPreset};
1913    /// 
1914    /// async fn check_media_config() -> Result<(), Box<dyn std::error::Error>> {
1915    ///     use rvoip_client_core::client::config::MediaPreset;
1916    ///     let mut media_config = MediaConfig::from_preset(MediaPreset::VoiceOptimized);
1917    ///     media_config.echo_cancellation = true;
1918    ///     media_config.max_bandwidth_kbps = Some(128);
1919    ///     
1920    ///     let config = ClientConfig::new()
1921    ///         .with_sip_addr("127.0.0.1:5078".parse()?)
1922    ///         .with_media(media_config);
1923    ///     
1924    ///     let client = ClientManager::new(config).await?;
1925    ///     
1926    ///     // Check applied configuration
1927    ///     let applied_config = client.get_media_config();
1928    ///     assert!(applied_config.echo_cancellation);
1929    ///     assert_eq!(applied_config.max_bandwidth_kbps, Some(128));
1930    ///     
1931    ///     println!("Echo cancellation: {}", applied_config.echo_cancellation);
1932    ///     println!("Noise suppression: {}", applied_config.noise_suppression);
1933    ///     println!("RTP port range: {}-{}", 
1934    ///         applied_config.rtp_port_start, applied_config.rtp_port_end);
1935    ///     
1936    ///     Ok(())
1937    /// }
1938    /// ```
1939    pub fn get_media_config(&self) -> &MediaConfig {
1940        &self.media_config
1941    }
1942    
1943    // ===== PRIORITY 3.2: CALL CONTROL OPERATIONS =====
1944    // Call control operations have been moved to controls.rs
1945    
1946    // ===== PRIORITY 4.1: ENHANCED MEDIA INTEGRATION =====
1947    // Media operations have been moved to media.rs
1948    
1949    /// Set up audio frame subscription for a call
1950    /// 
1951    /// This internal method is called when a call becomes established to automatically
1952    /// set up audio frame subscription, enabling audio to flow for the call.
1953    pub(crate) async fn setup_call_audio(&self, call_id: &CallId) -> ClientResult<()> {
1954        // Get the session ID for this call
1955        if let Some(session_id_entry) = self.session_mapping.get(call_id) {
1956            let session_id = session_id_entry.clone();
1957            
1958            // Subscribe to audio frames from this session
1959            match MediaControl::subscribe_to_audio_frames(&self.coordinator, &session_id).await {
1960                Ok(audio_subscriber) => {
1961                    // Mark that audio is set up for this call
1962                    self.audio_setup_calls.insert(*call_id, true);
1963                    
1964                    // Audio subscriber is now available for the application to use
1965                    // The application (e.g., sip-client) can integrate with audio-core
1966                    // to connect this subscriber to speakers and set up microphone capture
1967                    tracing::info!("Audio frame subscription ready for call {}", call_id);
1968                    tracing::info!("To enable audio, integrate with audio-core in your application");
1969                    
1970                    // For now, just drop the subscriber as we can't use audio-core directly
1971                    // due to circular dependency issues
1972                    drop(audio_subscriber);
1973                    
1974                    // TODO: In the future, this is where we would connect to audio-core
1975                    // to route audio frames to the appropriate audio device.
1976                    // For now, the audio frames are available via the subscriber.
1977                    
1978                    tracing::info!("Set up audio frame subscription for call {}", call_id);
1979                    Ok(())
1980                }
1981                Err(e) => {
1982                    // Log the error but don't fail the call - audio might still work
1983                    // through other means or this might be a non-audio call
1984                    tracing::warn!("Failed to set up audio frame subscription for call {}: {}", call_id, e);
1985                    Err(ClientError::MediaError { 
1986                        details: format!("Failed to subscribe to audio frames: {}", e) 
1987                    })
1988                }
1989            }
1990        } else {
1991            Err(ClientError::CallNotFound { call_id: *call_id })
1992        }
1993    }
1994}
1995
1996impl Drop for ClientManager {
1997    fn drop(&mut self) {
1998        // Check if still running using try_read to avoid blocking
1999        if let Ok(is_running) = self.is_running.try_read() {
2000            if *is_running {
2001                tracing::warn!("ClientManager dropped while still running! Call stop() before dropping to ensure proper cleanup.");
2002            }
2003        }
2004    }
2005}
2006
2007