Crate rvoip_client_core

Source
Expand description

High-level SIP client library for VoIP applications

This crate provides a user-friendly API for building SIP/VoIP client applications. It handles the complexity of SIP signaling, media negotiation, and call management while presenting a simple, async-first interface.

§Architecture

┌─────────────────────────┐
│    Your Application     │
└───────────┬─────────────┘
            │ 
┌───────────▼─────────────┐
│     client-core         │ ◄── You are here
│ ┌─────────────────────┐ │
│ │   ClientManager     │ │     • High-level call control
│ │   Registration      │ │     • Event handling  
│ │   Media Control     │ │     • Clean async API
│ └─────────────────────┘ │
└───────────┬─────────────┘
            │
┌───────────▼─────────────┐
│     session-core        │     • Session management
│                         │     • Protocol coordination
└───────────┬─────────────┘     • Infrastructure abstraction
            │
┌───────────▼─────────────┐
│   Lower-level crates    │     • SIP, RTP, Media
│ (transaction, dialog,   │     • Transport layers
│  sip-core, etc.)        │     • Codec processing
└─────────────────────────┘

§Quick Start

§Basic Client Setup

use rvoip_client_core::{ClientBuilder, Client, ClientEvent};
use std::sync::Arc;
 
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Build and start a client
    let client = ClientBuilder::new()
        .user_agent("MyApp/1.0")
        .local_address("0.0.0.0:5060".parse()?)
        .build()
        .await?;
         
    client.start().await?;
     
    // Subscribe to events
    let mut events = client.subscribe_events();
     
    // Make a call
    let call_id = client.make_call(
        "sip:alice@example.com".to_string(),
        "sip:bob@example.com".to_string(),
        None, // Let session-core generate SDP
    ).await?;
     
    // Handle events (in real applications, this would run until shutdown)
    tokio::select! {
        result = events.recv() => {
            if let Ok(event) = result {
                match event {
                    ClientEvent::CallStateChanged { info, .. } => {
                        println!("Call {} state: {:?}", info.call_id, info.new_state);
                    }
                    _ => {}
                }
            }
        }
        _ = tokio::time::sleep(tokio::time::Duration::from_secs(30)) => {
            println!("Application timeout");
        }
    }
     
    Ok(())
}

§Registration Example

// Register with a SIP server
let config = RegistrationConfig::new(
    "sip:registrar.example.com".to_string(),
    "sip:alice@example.com".to_string(),
    "sip:alice@192.168.1.100:5060".to_string(),
)
.with_credentials("alice".to_string(), "secret123".to_string())
.with_expires(3600); // 1 hour
 
let reg_id = client.register(config).await?;
 
// Later, refresh the registration
client.refresh_registration(reg_id).await?;
 
// Or unregister
client.unregister(reg_id).await?;

§Network Configuration

§Bind Address Propagation

When you configure a specific IP address, it propagates through all layers:

use rvoip_client_core::ClientBuilder;
 
// This ensures 192.168.1.100 is used at all layers
let client = ClientBuilder::new()
    .local_address("192.168.1.100:5060".parse()?)
    .media_address("192.168.1.100:0".parse()?)  // Same IP, auto port
    .build()
    .await?;

The configured IP address propagates to session-core, dialog-core, and transport layers. No more hardcoded 0.0.0.0 addresses when you specify an IP.

§Automatic Port Allocation

Set media port to 0 for automatic allocation:

use rvoip_client_core::ClientBuilder;
 
let client = ClientBuilder::new()
    .local_address("127.0.0.1:5060".parse()?)      // SIP on standard port
    .media_address("127.0.0.1:0".parse()?)         // Port 0 = auto
    .rtp_ports(10000, 20000)                       // RTP port range
    .build()
    .await?;

When port is set to 0:

  • It signals automatic allocation from the RTP port range
  • Actual allocation happens when media sessions are created
  • Each media session gets unique ports from the pool

§Features

  • Call Management: Make, receive, hold, transfer calls
  • Registration: SIP REGISTER support with authentication
  • Media Control: Audio mute/unmute, codec selection, SDP handling
  • Event System: Async event notifications for all operations
  • Clean Architecture: All complexity handled through session-core
  • Network Flexibility: Automatic port allocation and bind address control

§Error Handling

All operations return ClientResult<T> which wraps ClientError:

use rvoip_client_core::{Client, ClientError};
use std::sync::Arc;
 
async fn example(client: Arc<Client>) -> Result<(), Box<dyn std::error::Error>> {
    // Example error handling pattern
    match client.make_call(
        "sip:alice@example.com".to_string(), 
        "sip:bob@example.com".to_string(), 
        None
    ).await {
        Ok(call_id) => {
            println!("Call started: {}", call_id);
        }
        Err(ClientError::NetworkError { reason }) => {
            eprintln!("Network problem: {}", reason);
            // Could retry with exponential backoff
        }
        Err(ClientError::InvalidConfiguration { field, reason }) => {
            eprintln!("Configuration error in {}: {}", field, reason);
            // Fix configuration and retry
        }
        Err(e) => {
            eprintln!("Call failed: {}", e);
            // Handle other error types
        }
    }
    Ok(())
}

Re-exports§

pub use client::ClientManager;
pub use client::ClientCallHandler;
pub use client::Client;
pub use client::ClientBuilder;
pub use client::ClientStats;
pub use client::CallCapabilities;
pub use client::CallMediaInfo;
pub use client::AudioCodecInfo;
pub use client::AudioQualityMetrics;
pub use client::MediaCapabilities;
pub use client::MediaSessionInfo;
pub use client::NegotiatedMediaParams;
pub use client::EnhancedMediaCapabilities;
pub use client::ClientConfig;
pub use client::MediaConfig;
pub use client::MediaPreset;
pub use client::MediaConfigBuilder;
pub use call::CallId;
pub use call::CallInfo;
pub use call::CallDirection;
pub use call::CallState;
pub use registration::RegistrationConfig;
pub use registration::RegistrationInfo;
pub use registration::RegistrationStatus;
pub use events::ClientEventHandler;
pub use events::ClientEvent;
pub use events::IncomingCallInfo;
pub use events::CallStatusInfo;
pub use events::RegistrationStatusInfo;
pub use events::CallAction;
pub use events::MediaEventType;
pub use events::MediaEventInfo;
pub use events::EventFilter;
pub use events::EventPriority;
pub use events::EventSubscription;
pub use events::EventEmitter;
pub use error::ClientError;
pub use error::ClientResult;

Modules§

call
Call management for SIP client
client
High-level SIP client implementation
error
Error types and handling for the client-core library
events
Event handling for client-core operations
registration
Registration management for SIP client

Structs§

AudioFrame
Audio frame with PCM data and format information
AudioFrameSubscriber
Subscriber for receiving audio frames from a session
AudioStreamConfig
Configuration for audio streaming
SessionId
Unique identifier for a session

Constants§

VERSION
Client-core version information