Struct CallCenterEngine

Source
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

Source

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 limits
  • db_path - Optional database file path. Use None for in-memory operation, Some(":memory:") for explicit in-memory, or Some("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 settings
  • CallCenterError::Database - Database initialization failure
  • CallCenterError::Integration - Session-core integration failure
  • CallCenterError::Orchestration - General initialization failure
Source

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);
Source

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
Source

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);
Source

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");
}
Source

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 events
  • CallCenterError::Integration - Session-core integration failure
Source

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 update
  • new_state - The new call state from session-core
Source

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.

Source

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.

Source

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 call
  • mos_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?;
Source

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 quality
  • mos_score - Current Mean Opinion Score
  • alert_level - Severity level of the quality issue
Source

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 DTMF
  • digit - The DTMF digit pressed (‘0’-‘9’, ‘*’, ‘#’)
Source

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 changes
  • direction - Media flow direction (incoming/outgoing)
  • active - Whether media flow is active or stopped
  • codec - Audio codec being used
Source

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 warning
  • category - Warning category for filtering and routing
  • message - Warning message
Source

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.

Source

pub fn routing_stats(&self) -> &Arc<RwLock<RoutingStats>>

Get read access to routing statistics

Provides access to routing performance metrics for APIs and reporting.

Source

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.

Source

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 assign
  • agent_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?;
Source

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
Source

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
  1. Iterate through all configured queues
  2. For each queue, attempt to dequeue calls
  3. Find available agents with matching skills
  4. Assign calls to agents or re-queue if no agents available
  5. 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

Source

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

Source

pub async fn get_queue_depth(&self, queue_id: &str) -> usize

Get the current depth of a queue

Source

pub async fn monitor_queue_for_agents(&self, queue_id: String)

Monitor queue for agent availability

Source§

impl CallCenterEngine

Source

pub async fn put_call_on_hold( &self, session_id: &SessionId, ) -> CallCenterResult<()>

Put a call on hold

Source

pub async fn resume_call_from_hold( &self, session_id: &SessionId, ) -> CallCenterResult<()>

Resume a call from hold

Source

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

Source

pub async fn register_agent(&self, agent: &Agent) -> CallCenterResult<SessionId>

Register an agent with skills and performance tracking

Source

pub async fn update_agent_status( &self, agent_id: &AgentId, new_status: AgentStatus, ) -> CallCenterResult<()>

Update agent status (Available, Busy, Away, etc.)

Source

pub async fn get_agent_info(&self, agent_id: &AgentId) -> Option<AgentInfo>

Get detailed agent information

Source

pub async fn list_agents(&self) -> Vec<AgentInfo>

List all agents with their current status

Source

pub async fn get_queue_stats( &self, ) -> CallCenterResult<Vec<(String, QueueStats)>>

Get queue statistics for monitoring

Source§

impl CallCenterEngine

Source

pub async fn create_conference( &self, session_ids: &[SessionId], ) -> CallCenterResult<BridgeId>

Create a conference with multiple participants

Source

pub async fn transfer_call( &self, customer_session: SessionId, from_agent: AgentId, to_agent: AgentId, ) -> CallCenterResult<BridgeId>

Transfer call from one agent to another

Source

pub async fn get_bridge_info( &self, bridge_id: &BridgeId, ) -> CallCenterResult<BridgeInfo>

Get real-time bridge information for monitoring

Source

pub async fn list_active_bridges(&self) -> Vec<BridgeInfo>

List all active bridges for dashboard

Source

pub async fn start_bridge_monitoring(&mut self) -> CallCenterResult<()>

Subscribe to bridge events for real-time monitoring

Trait Implementations§

Source§

impl Clone for CallCenterEngine

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<'a, T, E> AsTaggedExplicit<'a, E> for T
where T: 'a,

Source§

fn explicit(self, class: Class, tag: u32) -> TaggedParser<'a, Explicit, Self, E>

Source§

impl<'a, T, E> AsTaggedImplicit<'a, E> for T
where T: 'a,

Source§

fn implicit( self, class: Class, constructed: bool, tag: u32, ) -> TaggedParser<'a, Implicit, Self, E>

Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> FromRef<T> for T
where T: Clone,

Source§

fn from_ref(input: &T) -> T

Converts to this type from a reference to the input type.
Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts 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
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

impl<T> ErasedDestructor for T
where T: 'static,

Source§

impl<A, B, T> HttpServerConnExec<A, B> for T
where B: Body,