Struct UnifiedDialogApi

Source
pub struct UnifiedDialogApi { /* private fields */ }
Expand description

Unified Dialog API

Provides a comprehensive, high-level interface for SIP dialog management that combines all functionality from the previous DialogClient and DialogServer APIs into a single, configuration-driven interface.

§Key Features

  • Mode-based behavior: Client, Server, or Hybrid operation based on configuration
  • Complete SIP support: All SIP methods and dialog operations
  • Session integration: Built-in coordination with session-core
  • Convenience handles: DialogHandle and CallHandle for easy operation
  • Comprehensive monitoring: Statistics, events, and state tracking
  • Thread safety: Safe to share across async tasks using Arc

§Capabilities by Mode

§Client Mode

  • Make outgoing calls (make_call)
  • Create outgoing dialogs (create_dialog)
  • Handle authentication challenges
  • Send in-dialog requests
  • Build and send responses (when needed)

§Server Mode

  • Handle incoming calls (handle_invite)
  • Auto-respond to OPTIONS/REGISTER (if configured)
  • Build and send responses
  • Send in-dialog requests
  • Domain-based routing

§Hybrid Mode

  • All client capabilities
  • All server capabilities
  • Full bidirectional SIP support
  • Complete PBX/gateway functionality

Implementations§

Source§

impl UnifiedDialogApi

Source

pub async fn new( transaction_manager: Arc<TransactionManager>, config: DialogManagerConfig, ) -> ApiResult<Self>

Create a new unified dialog API

§Arguments
  • transaction_manager - Pre-configured transaction manager
  • config - Configuration determining the behavior mode
§Returns

New UnifiedDialogApi instance

§Examples
use rvoip_dialog_core::api::unified::UnifiedDialogApi;
use rvoip_dialog_core::config::DialogManagerConfig;

let config = DialogManagerConfig::client("127.0.0.1:0".parse()?)
    .with_from_uri("sip:alice@example.com")
    .with_auth("alice", "secret123")
    .build();

let api = UnifiedDialogApi::new(transaction_manager, config).await?;
api.start().await?;

// Make outgoing calls
let call = api.make_call(
    "sip:alice@example.com",
    "sip:bob@example.com",
    Some("SDP offer".to_string())
).await?;

// Use call operations
call.hold(Some("SDP with hold".to_string())).await?;
call.transfer("sip:voicemail@example.com".to_string()).await?;
call.hangup().await?;
Source

pub async fn with_global_events( transaction_manager: Arc<TransactionManager>, transaction_events: Receiver<TransactionEvent>, config: DialogManagerConfig, ) -> ApiResult<Self>

Create a new unified dialog API with global events (RECOMMENDED)

§Arguments
  • transaction_manager - Pre-configured transaction manager
  • transaction_events - Global transaction event receiver
  • config - Configuration determining the behavior mode
§Returns

New UnifiedDialogApi instance with proper event consumption

§Examples
use rvoip_dialog_core::api::unified::UnifiedDialogApi;
use rvoip_dialog_core::config::DialogManagerConfig;

let config = DialogManagerConfig::server("0.0.0.0:5060".parse()?)
    .with_domain("sip.company.com")
    .build();

let api = UnifiedDialogApi::with_global_events(
    transaction_manager,
    transaction_events,
    config
).await?;
Source

pub fn config(&self) -> &DialogManagerConfig

Get the current configuration

Source

pub fn dialog_manager(&self) -> &Arc<UnifiedDialogManager>

Get the underlying dialog manager

Provides access to the underlying UnifiedDialogManager for advanced operations.

Source

pub async fn start(&self) -> ApiResult<()>

Start the dialog API

Initializes the API for processing SIP messages and events.

Source

pub async fn stop(&self) -> ApiResult<()>

Stop the dialog API

Gracefully shuts down the API and all active dialogs.

Source

pub async fn set_session_coordinator( &self, sender: Sender<SessionCoordinationEvent>, ) -> ApiResult<()>

Set session coordinator

Establishes communication with session-core for session management. This is essential for media coordination and call lifecycle management.

§Arguments
  • sender - Channel sender for session coordination events
§Examples
use rvoip_dialog_core::api::unified::UnifiedDialogApi;
use rvoip_dialog_core::events::SessionCoordinationEvent;

let (session_tx, session_rx) = tokio::sync::mpsc::channel(100);
api.set_session_coordinator(session_tx).await?;

// Handle session events
tokio::spawn(async move {
    // Process session coordination events
});
Source

pub async fn set_dialog_event_sender( &self, sender: Sender<DialogEvent>, ) -> ApiResult<()>

Set dialog event sender

Establishes dialog event communication for external consumers.

Source

pub fn subscribe_to_dialog_events(&self) -> Receiver<DialogEvent>

Subscribe to dialog events

Returns a receiver for monitoring dialog state changes and events.

Source

pub async fn make_call( &self, from_uri: &str, to_uri: &str, sdp_offer: Option<String>, ) -> ApiResult<CallHandle>

Make an outgoing call (Client/Hybrid modes only)

Creates a new dialog and sends an INVITE request to establish a call. Only available in Client and Hybrid modes.

§Arguments
  • from_uri - Local URI for the call
  • to_uri - Remote URI to call
  • sdp_offer - Optional SDP offer for media negotiation
§Returns

CallHandle for managing the call

§Examples
let call = api.make_call(
    "sip:alice@example.com",
    "sip:bob@example.com", 
    Some("v=0\r\no=alice 123 456 IN IP4 192.168.1.100\r\n...".to_string())
).await?;
 
println!("Call created: {}", call.call_id());
Source

pub async fn create_dialog( &self, from_uri: &str, to_uri: &str, ) -> ApiResult<DialogHandle>

Create an outgoing dialog without sending INVITE (Client/Hybrid modes only)

Creates a dialog in preparation for sending requests. Useful for scenarios where you want to create the dialog before sending the INVITE.

§Arguments
  • from_uri - Local URI
  • to_uri - Remote URI
§Returns

DialogHandle for the new dialog

§Examples
let dialog = api.create_dialog("sip:alice@example.com", "sip:bob@example.com").await?;
 
// Send custom requests within the dialog
dialog.send_info("Custom application data".to_string()).await?;
dialog.send_notify("presence".to_string(), Some("online".to_string())).await?;
Source

pub async fn handle_invite( &self, request: Request, source: SocketAddr, ) -> ApiResult<CallHandle>

Handle incoming INVITE request (Server/Hybrid modes only)

Processes an incoming INVITE to potentially establish a call. Only available in Server and Hybrid modes.

§Arguments
  • request - The INVITE request
  • source - Source address of the request
§Returns

CallHandle for managing the incoming call

§Examples
let source = "192.168.1.100:5060".parse().unwrap();
let call = api.handle_invite(request, source).await?;
 
// Accept the call
call.answer(Some("v=0\r\no=server 789 012 IN IP4 192.168.1.10\r\n...".to_string())).await?;
Source

pub async fn send_request_in_dialog( &self, dialog_id: &DialogId, method: Method, body: Option<Bytes>, ) -> ApiResult<TransactionKey>

Send a request within an existing dialog

Available in all modes for sending in-dialog requests.

§Arguments
  • dialog_id - The dialog to send the request in
  • method - SIP method to send
  • body - Optional request body
§Returns

Transaction key for tracking the request

Source

pub async fn send_response( &self, transaction_id: &TransactionKey, response: Response, ) -> ApiResult<()>

Send a response to a transaction

Available in all modes for sending responses to received requests.

§Arguments
  • transaction_id - Transaction to respond to
  • response - The response to send
Source

pub async fn build_response( &self, transaction_id: &TransactionKey, status_code: StatusCode, body: Option<String>, ) -> ApiResult<Response>

Build a response for a transaction

Constructs a properly formatted SIP response.

§Arguments
  • transaction_id - Transaction to respond to
  • status_code - HTTP-style status code
  • body - Optional response body
§Returns

Constructed response ready to send

Source

pub async fn send_status_response( &self, transaction_id: &TransactionKey, status_code: StatusCode, reason: Option<String>, ) -> ApiResult<()>

Send a status response (convenience method)

Builds and sends a simple status response.

§Arguments
  • transaction_id - Transaction to respond to
  • status_code - Status code to send
  • reason - Optional reason phrase
Source

pub async fn send_bye(&self, dialog_id: &DialogId) -> ApiResult<TransactionKey>

Send BYE request to terminate a dialog

Source

pub async fn send_refer( &self, dialog_id: &DialogId, target_uri: String, refer_body: Option<String>, ) -> ApiResult<TransactionKey>

Send REFER request for call transfer

Source

pub async fn send_notify( &self, dialog_id: &DialogId, event: String, body: Option<String>, ) -> ApiResult<TransactionKey>

Send NOTIFY request for event notifications

Source

pub async fn send_update( &self, dialog_id: &DialogId, sdp: Option<String>, ) -> ApiResult<TransactionKey>

Send UPDATE request for media modifications

Source

pub async fn send_info( &self, dialog_id: &DialogId, info_body: String, ) -> ApiResult<TransactionKey>

Send INFO request for application-specific information

Source

pub async fn send_cancel( &self, dialog_id: &DialogId, ) -> ApiResult<TransactionKey>

Send CANCEL request to cancel a pending INVITE

This method cancels a pending INVITE transaction that hasn’t received a final response. Only works for dialogs in the Early state (before 200 OK is received).

§Arguments
  • dialog_id - The dialog to cancel
§Returns

Transaction key for the CANCEL request

§Errors

Returns an error if:

  • Dialog is not found
  • Dialog is not in Early state
  • No pending INVITE transaction found
Source

pub async fn get_dialog_info(&self, dialog_id: &DialogId) -> ApiResult<Dialog>

Get information about a dialog

Source

pub async fn get_dialog_state( &self, dialog_id: &DialogId, ) -> ApiResult<DialogState>

Get the current state of a dialog

Source

pub async fn terminate_dialog(&self, dialog_id: &DialogId) -> ApiResult<()>

Terminate a dialog

Source

pub async fn list_active_dialogs(&self) -> Vec<DialogId>

List all active dialogs

Source

pub async fn get_dialog_handle( &self, dialog_id: &DialogId, ) -> ApiResult<DialogHandle>

Get a dialog handle for convenient operations

§Arguments
  • dialog_id - The dialog ID to create a handle for
§Returns

DialogHandle for the specified dialog

Source

pub async fn get_call_handle( &self, dialog_id: &DialogId, ) -> ApiResult<CallHandle>

Get a call handle for convenient call operations

§Arguments
  • dialog_id - The dialog ID representing the call
§Returns

CallHandle for the specified call

Source

pub async fn get_stats(&self) -> DialogStats

Get comprehensive statistics for this API instance

Returns detailed statistics including dialog counts, call metrics, and mode-specific information.

Source

pub async fn active_dialogs(&self) -> Vec<DialogHandle>

Get active dialogs with handles for easy management

Returns a list of DialogHandle instances for all active dialogs.

Source

pub async fn send_ack_for_2xx_response( &self, dialog_id: &DialogId, original_invite_tx_id: &TransactionKey, response: &Response, ) -> ApiResult<()>

Send ACK for 2xx response to INVITE

Handles the automatic ACK sending required by RFC 3261 for 200 OK responses to INVITE. This method ensures proper completion of the 3-way handshake (INVITE → 200 OK → ACK).

§Arguments
  • dialog_id - Dialog ID for the call
  • original_invite_tx_id - Transaction ID of the original INVITE
  • response - The 200 OK response to acknowledge
§Returns

Success or error

Source

pub fn supports_outgoing_calls(&self) -> bool

Check if this API supports outgoing calls

Source

pub fn supports_incoming_calls(&self) -> bool

Check if this API supports incoming calls

Source

pub fn from_uri(&self) -> Option<&str>

Get the from URI for outgoing requests (if configured)

Source

pub fn domain(&self) -> Option<&str>

Get the domain for server operations (if configured)

Source

pub fn auto_auth_enabled(&self) -> bool

Check if automatic authentication is enabled

Source

pub fn auto_options_enabled(&self) -> bool

Check if automatic OPTIONS response is enabled

Source

pub fn auto_register_enabled(&self) -> bool

Check if automatic REGISTER response is enabled

Source

pub async fn create(config: DialogManagerConfig) -> ApiResult<Self>

Create a new unified dialog API with automatic transport setup (SIMPLE)

This is the recommended constructor for most use cases. It automatically creates and configures the transport and transaction managers internally, providing a clean high-level API.

§Arguments
  • config - Configuration determining the behavior mode and bind address
§Returns

New UnifiedDialogApi instance with automatic transport setup

§Examples
use rvoip_dialog_core::api::unified::UnifiedDialogApi;
use rvoip_dialog_core::config::DialogManagerConfig;

let config = DialogManagerConfig::client("127.0.0.1:0".parse()?)
    .with_from_uri("sip:alice@example.com")
    .build();

let api = UnifiedDialogApi::create(config).await?;
api.start().await?;
Source

pub async fn send_non_dialog_request( &self, request: Request, destination: SocketAddr, timeout: Duration, ) -> ApiResult<Response>

Send a non-dialog SIP request (for REGISTER, OPTIONS, etc.)

This method allows sending SIP requests that don’t establish or require a dialog context. Useful for:

  • REGISTER requests for endpoint registration
  • OPTIONS requests for capability discovery
  • MESSAGE requests for instant messaging
  • SUBSCRIBE requests for event subscriptions
§Arguments
  • request - Complete SIP request to send
  • destination - Target address to send the request to
  • timeout - Maximum time to wait for a response
§Returns

The SIP response received

§Examples
use rvoip_sip_core::builder::SimpleRequestBuilder;
use rvoip_sip_core::builder::expires::ExpiresExt;
use std::time::Duration;

// Build a REGISTER request
let request = SimpleRequestBuilder::register("sip:registrar.example.com")?
    .from("", "sip:alice@example.com", Some("tag123"))
    .to("", "sip:alice@example.com", None)
    .call_id("reg-12345")
    .cseq(1)
    .via("192.168.1.100:5060", "UDP", Some("branch123"))
    .contact("sip:alice@192.168.1.100:5060", None)
    .expires(3600)
    .build();

let destination = "192.168.1.1:5060".parse()?;
let response = api.send_non_dialog_request(
    request,
    destination,
    Duration::from_secs(32)
).await?;

println!("Registration response: {}", response.status_code());

Trait Implementations§

Source§

impl Clone for UnifiedDialogApi

Source§

fn clone(&self) -> UnifiedDialogApi

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

impl Debug for UnifiedDialogApi

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. 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<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> 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> 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,