pub struct CallCenterEngine {
pub session_to_dialog: Arc<DashMap<String, String>>,
/* private fields */
}
Expand description
Primary call center orchestration engine
This is the main orchestration component that integrates with rvoip-session-core to provide comprehensive call center functionality on top of SIP session management.
The CallCenterEngine
serves as the central coordinator for:
- Agent Management: Registration, authentication, and availability tracking
- Call Routing: Intelligent routing based on skills, availability, and business rules
- Queue Management: Call queuing with priorities and overflow handling
- Bridge Operations: SIP bridge creation and management between agents and customers
- Real-time Monitoring: Statistics collection and supervisor notifications
- Database Integration: Persistent storage of call data and agent information
§Architecture
The engine integrates multiple subsystems:
┌─────────────────────────────────────┐
│ CallCenterEngine │
├─────────────────────────────────────┤
│ ┌─────────────┐ ┌─────────────────┐ │
│ │ Agent │ │ Queue │ │
│ │ Registry │ │ Manager │ │
│ └─────────────┘ └─────────────────┘ │
│ ┌─────────────┐ ┌─────────────────┐ │
│ │ Routing │ │ Database │ │
│ │ Engine │ │ Manager │ │
│ └─────────────┘ └─────────────────┘ │
└─────────────────────────────────────┘
│
┌─────────────────┐
│ Session │
│ Coordinator │ (rvoip-session-core)
└─────────────────┘
§Examples
§Basic Setup
use rvoip_call_engine::prelude::*;
let config = CallCenterConfig::default();
let engine = CallCenterEngine::new(config, None).await?;
println!("Call center engine started successfully!");
§Agent Registration
use rvoip_call_engine::prelude::*;
use std::sync::Arc;
let agent = Agent {
id: "agent-001".to_string(),
sip_uri: "sip:alice@call-center.local".to_string(),
display_name: "Alice Johnson".to_string(),
skills: vec!["english".to_string(), "sales".to_string()],
max_concurrent_calls: 3,
status: AgentStatus::Available,
department: Some("sales".to_string()),
extension: Some("1001".to_string()),
};
let session_id = engine.register_agent(&agent).await?;
println!("Agent registered with session: {}", session_id);
§Statistics Monitoring
use rvoip_call_engine::prelude::*;
use std::sync::Arc;
let stats = engine.get_stats().await;
println!("Call center status:");
println!(" Active calls: {}", stats.active_calls);
println!(" Available agents: {}", stats.available_agents);
println!(" Queued calls: {}", stats.queued_calls);
Fields§
§session_to_dialog: Arc<DashMap<String, String>>
Session ID to Dialog ID mappings for robust lookup
Implementations§
Source§impl CallCenterEngine
impl CallCenterEngine
Sourcepub async fn new(
config: CallCenterConfig,
db_path: Option<String>,
) -> CallCenterResult<Arc<Self>>
pub async fn new( config: CallCenterConfig, db_path: Option<String>, ) -> CallCenterResult<Arc<Self>>
Create a new call center engine with configuration and optional database
This is the primary constructor for the call center engine. It initializes all subsystems including session management, agent registry, queue management, and database connectivity.
§Arguments
config
- Call center configuration including networking, routing, and system limitsdb_path
- Optional database file path. UseNone
for in-memory operation,Some(":memory:")
for explicit in-memory, orSome("path.db")
for persistent storage
§Returns
Returns an Arc<CallCenterEngine>
for shared ownership across the application,
or a CallCenterError
if initialization fails.
§Examples
use rvoip_call_engine::prelude::*;
// In-memory call center for testing
let engine1 = CallCenterEngine::new(
CallCenterConfig::default(),
None
).await?;
// Persistent call center for production
let engine2 = CallCenterEngine::new(
CallCenterConfig::default(),
Some("callcenter.db".to_string())
).await?;
§Errors
CallCenterError::Configuration
- Invalid configuration settingsCallCenterError::Database
- Database initialization failureCallCenterError::Integration
- Session-core integration failureCallCenterError::Orchestration
- General initialization failure
Sourcepub async fn get_stats(&self) -> OrchestratorStats
pub async fn get_stats(&self) -> OrchestratorStats
Get comprehensive orchestrator statistics and performance metrics
Returns a snapshot of the current call center state including active calls, agent availability, queue status, and routing performance metrics.
§Returns
OrchestratorStats
containing:
- Current active calls and bridges
- Agent availability (available vs busy)
- Queued calls waiting for agents
- Total calls handled since startup
- Detailed routing statistics
§Examples
use rvoip_call_engine::prelude::*;
use std::sync::Arc;
let stats = engine.get_stats().await;
println!("📊 Call Center Dashboard");
println!(" Active calls: {}", stats.active_calls);
println!(" Available agents: {}", stats.available_agents);
println!(" Busy agents: {}", stats.busy_agents);
println!(" Queued calls: {}", stats.queued_calls);
println!(" Total handled: {}", stats.total_calls_handled);
println!("📈 Routing Performance");
println!(" Direct routes: {}", stats.routing_stats.calls_routed_directly);
println!(" Queued routes: {}", stats.routing_stats.calls_queued);
println!(" Rejected calls: {}", stats.routing_stats.calls_rejected);
Sourcepub fn session_manager(&self) -> &Arc<SessionCoordinator>
pub fn session_manager(&self) -> &Arc<SessionCoordinator>
Get the underlying session coordinator for advanced SIP operations
Provides access to the rvoip-session-core coordinator for advanced SIP operations, custom call handling, or direct session management.
§Returns
A reference to the SessionCoordinator
for direct session operations.
§Examples
use rvoip_call_engine::prelude::*;
use std::sync::Arc;
let session_manager = engine.session_manager();
// Access session-core functionality directly
// let custom_session = session_manager.create_session(...).await?;
§Use Cases
- Custom SIP message handling
- Advanced session configuration
- Direct bridge management
- Low-level SIP debugging
Sourcepub fn config(&self) -> &CallCenterConfig
pub fn config(&self) -> &CallCenterConfig
Get call center configuration
Returns a reference to the current call center configuration. Useful for accessing configuration values in application logic.
§Examples
use rvoip_call_engine::prelude::*;
use std::sync::Arc;
let config = engine.config();
println!("Max concurrent calls: {}", config.general.max_concurrent_calls);
println!("Max agents: {}", config.general.max_agents);
println!("Routing strategy: {:?}", config.routing.default_strategy);
Sourcepub fn database_manager(&self) -> Option<&Arc<DatabaseManager>>
pub fn database_manager(&self) -> Option<&Arc<DatabaseManager>>
Get database manager reference for direct database operations
Provides access to the database manager for custom queries, reporting, or data export operations.
§Returns
Some(&DatabaseManager)
if database is configured, None
for in-memory operation.
§Examples
use rvoip_call_engine::prelude::*;
use std::sync::Arc;
if let Some(db) = engine.database_manager() {
match db.get_available_agents().await {
Ok(agents) => println!("Found {} available agents in database", agents.len()),
Err(e) => println!("Error fetching agents: {}", e),
}
} else {
println!("Running in memory-only mode");
}
Sourcepub async fn start_event_monitoring(self: Arc<Self>) -> CallCenterResult<()>
pub async fn start_event_monitoring(self: Arc<Self>) -> CallCenterResult<()>
Start monitoring session events including REGISTER requests and call events
Begins monitoring all session events from the underlying SIP stack, including agent registrations, incoming calls, and call state changes. This method should be called after engine initialization to enable full call center functionality.
§Returns
Ok(())
if monitoring started successfully, or CallCenterError
if
event subscription failed.
§Examples
use rvoip_call_engine::prelude::*;
let engine = CallCenterEngine::new(CallCenterConfig::default(), None).await?;
// Start event monitoring (essential for call center operation)
engine.clone().start_event_monitoring().await?;
println!("Call center is now monitoring for calls and registrations");
§Background Processing
This method spawns a background task that continuously processes:
- Agent REGISTER requests
- Incoming call INVITE requests
- Call state changes
- Media quality events
- Call termination events
§Errors
CallCenterError::Orchestration
- Failed to subscribe to session eventsCallCenterError::Integration
- Session-core integration failure
Sourcepub async fn update_call_state(
&self,
session_id: &SessionId,
new_state: &CallState,
) -> CallCenterResult<()>
pub async fn update_call_state( &self, session_id: &SessionId, new_state: &CallState, ) -> CallCenterResult<()>
Update call state tracking when call states change
Internal method that maintains consistency between session-core call states and call center call tracking.
§Arguments
session_id
- The session ID of the call to updatenew_state
- The new call state from session-core
Sourcepub async fn route_incoming_call(
&self,
session_id: &SessionId,
) -> CallCenterResult<()>
pub async fn route_incoming_call( &self, session_id: &SessionId, ) -> CallCenterResult<()>
Route incoming call when it starts ringing
Internal method called when a new call arrives that needs to be routed to an appropriate agent or queue.
Sourcepub async fn cleanup_call(&self, session_id: &SessionId) -> CallCenterResult<()>
pub async fn cleanup_call(&self, session_id: &SessionId) -> CallCenterResult<()>
Clean up resources when call terminates
Internal method that handles cleanup when a call ends, including removing call tracking, updating agent availability, and database cleanup.
Sourcepub async fn record_quality_metrics(
&self,
session_id: &SessionId,
mos_score: f32,
packet_loss: f32,
) -> CallCenterResult<()>
pub async fn record_quality_metrics( &self, session_id: &SessionId, mos_score: f32, packet_loss: f32, ) -> CallCenterResult<()>
Record quality metrics for a call
Records call quality information for monitoring and reporting purposes. Quality metrics are used for supervisor dashboards and quality alerts.
§Arguments
session_id
- The session ID of the callmos_score
- Mean Opinion Score (1.0 to 5.0, higher is better)packet_loss
- Packet loss percentage (0.0 to 100.0)
§Examples
use rvoip_call_engine::prelude::*;
use std::sync::Arc;
// Record good quality metrics
engine.record_quality_metrics(&session_id, 4.2, 0.1).await?;
// Record poor quality metrics
engine.record_quality_metrics(&session_id, 2.1, 5.5).await?;
Sourcepub async fn alert_poor_quality(
&self,
session_id: &SessionId,
mos_score: f32,
alert_level: MediaQualityAlertLevel,
) -> CallCenterResult<()>
pub async fn alert_poor_quality( &self, session_id: &SessionId, mos_score: f32, alert_level: MediaQualityAlertLevel, ) -> CallCenterResult<()>
Alert supervisors about poor call quality
Generates alerts for supervisors when call quality falls below acceptable thresholds. Alerts can trigger supervisor intervention or call recording.
§Arguments
session_id
- The session ID of the call with poor qualitymos_score
- Current Mean Opinion Scorealert_level
- Severity level of the quality issue
Sourcepub async fn process_dtmf_input(
&self,
session_id: &SessionId,
digit: char,
) -> CallCenterResult<()>
pub async fn process_dtmf_input( &self, session_id: &SessionId, digit: char, ) -> CallCenterResult<()>
Process DTMF input for IVR or call features
Handles DTMF (touch-tone) input from callers for Interactive Voice Response systems, call transfers, or other telephony features.
§Arguments
session_id
- The session ID generating the DTMFdigit
- The DTMF digit pressed (‘0’-‘9’, ‘*’, ‘#’)
Sourcepub async fn update_media_flow(
&self,
session_id: &SessionId,
direction: MediaFlowDirection,
active: bool,
codec: &str,
) -> CallCenterResult<()>
pub async fn update_media_flow( &self, session_id: &SessionId, direction: MediaFlowDirection, active: bool, codec: &str, ) -> CallCenterResult<()>
Update media flow status for a call
Tracks media flow status (audio start/stop) for monitoring and troubleshooting purposes.
§Arguments
session_id
- The session ID with media flow changesdirection
- Media flow direction (incoming/outgoing)active
- Whether media flow is active or stoppedcodec
- Audio codec being used
Sourcepub async fn log_warning(
&self,
session_id: Option<&SessionId>,
category: WarningCategory,
message: &str,
) -> CallCenterResult<()>
pub async fn log_warning( &self, session_id: Option<&SessionId>, category: WarningCategory, message: &str, ) -> CallCenterResult<()>
Log warning for monitoring and troubleshooting
Logs warnings with appropriate categorization for monitoring systems and troubleshooting.
§Arguments
session_id
- Optional session ID related to the warningcategory
- Warning category for filtering and routingmessage
- Warning message
Sourcepub fn active_calls(&self) -> &Arc<DashMap<SessionId, CallInfo>>
pub fn active_calls(&self) -> &Arc<DashMap<SessionId, CallInfo>>
Get read access to active calls tracking
Provides access to the active calls collection for API implementations and monitoring systems.
Sourcepub fn routing_stats(&self) -> &Arc<RwLock<RoutingStats>>
pub fn routing_stats(&self) -> &Arc<RwLock<RoutingStats>>
Get read access to routing statistics
Provides access to routing performance metrics for APIs and reporting.
Sourcepub fn queue_manager(&self) -> &Arc<RwLock<QueueManager>>
pub fn queue_manager(&self) -> &Arc<RwLock<QueueManager>>
Get read access to queue manager
Provides access to the queue manager for API implementations and queue monitoring.
Sourcepub async fn assign_agent_to_call(
&self,
session_id: SessionId,
agent_id: AgentId,
) -> CallCenterResult<()>
pub async fn assign_agent_to_call( &self, session_id: SessionId, agent_id: AgentId, ) -> CallCenterResult<()>
Assign a specific agent to a call (public for supervisor API)
Allows supervisors to manually assign agents to specific calls, overriding automatic routing decisions.
§Arguments
session_id
- The call session to assignagent_id
- The agent to assign to the call
§Examples
use rvoip_call_engine::prelude::*;
use std::sync::Arc;
let session_id = SessionId::new(); // From incoming call
let agent_id = AgentId::from("agent-specialist-001");
// Supervisor assigns specialist agent to complex call
engine.assign_agent_to_call(session_id, agent_id).await?;
Sourcepub async fn create_queue(&self, queue_id: &str) -> CallCenterResult<()>
pub async fn create_queue(&self, queue_id: &str) -> CallCenterResult<()>
Ensure a queue exists (public for admin API)
Creates a queue if it doesn’t already exist. Used by administrative APIs for queue management.
§Arguments
queue_id
- The queue identifier to create
Sourcepub async fn process_all_queues(&self) -> CallCenterResult<()>
pub async fn process_all_queues(&self) -> CallCenterResult<()>
Process all queues to assign waiting calls to available agents
Attempts to match queued calls with available agents across all queues. This method is called periodically and can also be triggered manually for immediate queue processing.
§Queue Processing Logic
- Iterate through all configured queues
- For each queue, attempt to dequeue calls
- Find available agents with matching skills
- Assign calls to agents or re-queue if no agents available
- Update routing statistics
§Examples
use rvoip_call_engine::prelude::*;
use std::sync::Arc;
// Manually trigger queue processing
engine.process_all_queues().await?;
println!("Queue processing completed");
§Performance Considerations
- Processing time scales with queue size and agent count
- Database queries are performed for agent availability
- Should not be called too frequently to avoid performance impact
Source§impl CallCenterEngine
impl CallCenterEngine
Sourcepub async fn handle_register_request(
&self,
transaction_id: &str,
from_uri: String,
contact_uri: String,
expires: u32,
) -> Result<(), CallCenterError>
pub async fn handle_register_request( &self, transaction_id: &str, from_uri: String, contact_uri: String, expires: u32, ) -> Result<(), CallCenterError>
Handle SIP REGISTER request forwarded from session-core This is called when dialog-core receives a REGISTER and forwards it to us
Source§impl CallCenterEngine
impl CallCenterEngine
Sourcepub async fn get_queue_depth(&self, queue_id: &str) -> usize
pub async fn get_queue_depth(&self, queue_id: &str) -> usize
Get the current depth of a queue
Sourcepub async fn monitor_queue_for_agents(&self, queue_id: String)
pub async fn monitor_queue_for_agents(&self, queue_id: String)
Monitor queue for agent availability
Source§impl CallCenterEngine
impl CallCenterEngine
Sourcepub async fn put_call_on_hold(
&self,
session_id: &SessionId,
) -> CallCenterResult<()>
pub async fn put_call_on_hold( &self, session_id: &SessionId, ) -> CallCenterResult<()>
Put a call on hold
Sourcepub async fn resume_call_from_hold(
&self,
session_id: &SessionId,
) -> CallCenterResult<()>
pub async fn resume_call_from_hold( &self, session_id: &SessionId, ) -> CallCenterResult<()>
Resume a call from hold
Sourcepub async fn transfer_call_simple(
&self,
session_id: &SessionId,
target: &str,
) -> CallCenterResult<()>
pub async fn transfer_call_simple( &self, session_id: &SessionId, target: &str, ) -> CallCenterResult<()>
Transfer a call to another agent or queue (simple version)
Source§impl CallCenterEngine
impl CallCenterEngine
Sourcepub async fn register_agent(&self, agent: &Agent) -> CallCenterResult<SessionId>
pub async fn register_agent(&self, agent: &Agent) -> CallCenterResult<SessionId>
Register an agent with skills and performance tracking
Sourcepub async fn update_agent_status(
&self,
agent_id: &AgentId,
new_status: AgentStatus,
) -> CallCenterResult<()>
pub async fn update_agent_status( &self, agent_id: &AgentId, new_status: AgentStatus, ) -> CallCenterResult<()>
Update agent status (Available, Busy, Away, etc.)
Sourcepub async fn get_agent_info(&self, agent_id: &AgentId) -> Option<AgentInfo>
pub async fn get_agent_info(&self, agent_id: &AgentId) -> Option<AgentInfo>
Get detailed agent information
Sourcepub async fn list_agents(&self) -> Vec<AgentInfo>
pub async fn list_agents(&self) -> Vec<AgentInfo>
List all agents with their current status
Sourcepub async fn get_queue_stats(
&self,
) -> CallCenterResult<Vec<(String, QueueStats)>>
pub async fn get_queue_stats( &self, ) -> CallCenterResult<Vec<(String, QueueStats)>>
Get queue statistics for monitoring
Source§impl CallCenterEngine
impl CallCenterEngine
Sourcepub async fn create_conference(
&self,
session_ids: &[SessionId],
) -> CallCenterResult<BridgeId>
pub async fn create_conference( &self, session_ids: &[SessionId], ) -> CallCenterResult<BridgeId>
Create a conference with multiple participants
Sourcepub async fn transfer_call(
&self,
customer_session: SessionId,
from_agent: AgentId,
to_agent: AgentId,
) -> CallCenterResult<BridgeId>
pub async fn transfer_call( &self, customer_session: SessionId, from_agent: AgentId, to_agent: AgentId, ) -> CallCenterResult<BridgeId>
Transfer call from one agent to another
Sourcepub async fn get_bridge_info(
&self,
bridge_id: &BridgeId,
) -> CallCenterResult<BridgeInfo>
pub async fn get_bridge_info( &self, bridge_id: &BridgeId, ) -> CallCenterResult<BridgeInfo>
Get real-time bridge information for monitoring
Sourcepub async fn list_active_bridges(&self) -> Vec<BridgeInfo>
pub async fn list_active_bridges(&self) -> Vec<BridgeInfo>
List all active bridges for dashboard
Sourcepub async fn start_bridge_monitoring(&mut self) -> CallCenterResult<()>
pub async fn start_bridge_monitoring(&mut self) -> CallCenterResult<()>
Subscribe to bridge events for real-time monitoring
Trait Implementations§
Auto Trait Implementations§
impl Freeze for CallCenterEngine
impl !RefUnwindSafe for CallCenterEngine
impl Send for CallCenterEngine
impl Sync for CallCenterEngine
impl Unpin for CallCenterEngine
impl !UnwindSafe for CallCenterEngine
Blanket Implementations§
Source§impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
Source§impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left
is true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left(&self)
returns true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read more