Skip to main content

DialogLayer

Struct DialogLayer 

Source
pub struct DialogLayer {
    pub endpoint: EndpointInnerRef,
    pub inner: DialogLayerInnerRef,
}
Expand description

SIP Dialog Layer

DialogLayer provides high-level dialog management functionality for SIP applications. It handles dialog creation, lookup, and lifecycle management while coordinating with the transaction layer.

§Key Responsibilities

  • Creating and managing SIP dialogs
  • Dialog identification and routing
  • Dialog state tracking and cleanup
  • Integration with transaction layer
  • Sequence number management

§Usage Patterns

§Server-side Dialog Creation

use rsipstack::dialog::dialog_layer::DialogLayer;
use rsipstack::transaction::endpoint::EndpointInner;
use std::sync::Arc;

// Create dialog layer
let dialog_layer = DialogLayer::new(endpoint.clone());

// Handle incoming INVITE transaction
let server_dialog = dialog_layer.get_or_create_server_invite(
    &transaction,
    state_sender,
    credential,
    contact_uri
)?;

// Accept the call
server_dialog.accept(None, None)?;

§Dialog Lookup and Routing

// Find existing dialog for incoming request
if let Some(mut dialog) = dialog_layer.match_dialog(&transaction) {
    // Route to existing dialog
    dialog.handle(&mut transaction).await?;
} else {
    // Create new dialog or reject
}

§Dialog Cleanup

// Remove completed dialog
dialog_layer.remove_dialog(&dialog_id);

§Dialog Lifecycle

  1. Creation - Dialog created from incoming INVITE or outgoing request
  2. Early State - Dialog exists but not yet confirmed
  3. Confirmed - Dialog established with 2xx response and ACK
  4. Active - Dialog can exchange in-dialog requests
  5. Terminated - Dialog ended with BYE or error
  6. Cleanup - Dialog removed from layer

§Thread Safety

DialogLayer is thread-safe and can be shared across multiple tasks:

  • Dialog lookup operations are concurrent
  • Dialog creation is serialized when needed
  • Automatic cleanup prevents memory leaks

Fields§

§endpoint: EndpointInnerRef§inner: DialogLayerInnerRef

Implementations§

Source§

impl DialogLayer

Source

pub fn new(endpoint: EndpointInnerRef) -> Self

Source

pub fn get_or_create_server_invite( &self, tx: &Transaction, state_sender: DialogStateSender, credential: Option<Credential>, local_contact: Option<Uri>, ) -> Result<ServerInviteDialog>

Source

pub fn get_or_create_server_subscription( &self, tx: &Transaction, state_sender: DialogStateSender, credential: Option<Credential>, local_contact: Option<Uri>, ) -> Result<ServerSubscriptionDialog>

Source

pub fn get_or_create_server_publication( &self, tx: &Transaction, state_sender: DialogStateSender, credential: Option<Credential>, local_contact: Option<Uri>, ) -> Result<ServerPublicationDialog>

Source

pub fn get_or_create_client_publication( &self, call_id: String, from_tag: String, to_tag: String, initial_request: Request, state_sender: DialogStateSender, credential: Option<Credential>, local_contact: Option<Uri>, ) -> Result<ClientPublicationDialog>

Source

pub fn get_or_create_client_subscription( &self, call_id: String, from_tag: String, to_tag: String, initial_request: Request, state_sender: DialogStateSender, credential: Option<Credential>, local_contact: Option<Uri>, ) -> Result<ClientSubscriptionDialog>

Source

pub fn increment_last_seq(&self) -> u32

Source

pub fn len(&self) -> usize

Source

pub fn all_dialog_ids(&self) -> Vec<String>

Source

pub fn get_dialog(&self, id: &DialogId) -> Option<Dialog>

Source

pub fn get_dialog_with(&self, id: &String) -> Option<Dialog>

Source

pub fn get_client_dialog_by_call_id( &self, call_id: &str, ) -> Vec<ClientInviteDialog>

Returns all client-side INVITE dialogs (UAC) that share the given Call-ID.

In a forking scenario, multiple client dialogs can exist for the same Call-ID (same local From-tag, different remote To-tags). This helper scans the internal dialog registry and returns all ClientInviteDialog instances whose DialogId.call_id equals the provided call_id.

The returned vector may be empty if no matching client dialogs are found.

Source

pub fn restore_from_snapshot( &self, snapshot: DialogSnapshot, state_sender: DialogStateSender, ) -> Result<bool>

Restore a dialog from persisted snapshot.

Restores only CONFIRMED snapshots. Non-confirmed snapshots are ignored (warn inside try_restore_from_snapshot).

Returns:

  • Ok(true) => restored and inserted
  • Ok(false) => skipped (already exists or not confirmed)
Source

pub fn remove_dialog(&self, id: &DialogId)

Source

pub fn match_dialog(&self, tx: &Transaction) -> Option<Dialog>

Source

pub fn new_dialog_state_channel( &self, ) -> (DialogStateSender, DialogStateReceiver)

Source

pub fn build_local_contact( &self, username: Option<String>, params: Option<Vec<Param>>, ) -> Result<Uri>

Source§

impl DialogLayer

Source

pub fn make_invite_request(&self, opt: &InviteOption) -> Result<Request>

Create an INVITE request from options

Constructs a properly formatted SIP INVITE request based on the provided options. This method handles all the required headers and parameters according to RFC 3261.

§Parameters
  • opt - INVITE options containing all necessary parameters
§Returns
  • Ok(Request) - Properly formatted INVITE request
  • Err(Error) - Failed to create request
§Generated Headers

The method automatically generates:

  • Via header with branch parameter
  • From header with tag parameter
  • To header (without tag for initial request)
  • Contact header
  • Content-Type header
  • CSeq header with incremented sequence number
  • Call-ID header
§Examples
let request = dialog_layer.make_invite_request(&invite_option)?;
println!("Created INVITE to: {}", request.uri);
Source

pub async fn do_invite( &self, opt: InviteOption, state_sender: DialogStateSender, ) -> Result<(ClientInviteDialog, Option<Response>)>

Send an INVITE request and create a client dialog

This is the main method for initiating outbound calls. It creates an INVITE request, sends it, and manages the resulting dialog. The method handles the complete INVITE transaction including authentication challenges and response processing.

§Parameters
  • opt - INVITE options containing all call parameters
  • state_sender - Channel for receiving dialog state updates
§Returns
  • Ok((ClientInviteDialog, Option<Response>)) - Created dialog and final response
  • Err(Error) - Failed to send INVITE or process responses
§Call Flow
  1. Creates INVITE request from options
  2. Creates client dialog and transaction
  3. Sends INVITE request
  4. Processes responses (1xx, 2xx, 3xx-6xx)
  5. Handles authentication challenges if needed
  6. Returns established dialog and final response
§Examples
§Basic Call Setup
let (dialog, response) = dialog_layer.do_invite(invite_option, state_sender).await?;

if let Some(resp) = response {
    match resp.status_code {
        rsip::StatusCode::OK => {
            println!("Call answered!");
            // Process SDP answer in resp.body
        },
        rsip::StatusCode::BusyHere => {
            println!("Called party is busy");
        },
        _ => {
            println!("Call failed: {}", resp.status_code);
        }
    }
}
§Monitoring Dialog State
let (state_tx, mut state_rx) = tokio::sync::mpsc::unbounded_channel();
let (dialog, response) = dialog_layer.do_invite(invite_option, state_tx).await?;

// Monitor dialog state changes
tokio::spawn(async move {
    while let Some(state) = state_rx.recv().await {
        match state {
            DialogState::Early(_, resp) => {
                println!("Ringing: {}", resp.status_code);
            },
            DialogState::Confirmed(_,_) => {
                println!("Call established");
            },
            DialogState::Terminated(_, code) => {
                println!("Call ended: {:?}", code);
                break;
            },
            _ => {}
        }
    }
});
§Error Handling

The method can fail for various reasons:

  • Network connectivity issues
  • Authentication failures
  • Invalid SIP URIs or headers
  • Transaction timeouts
  • Protocol violations
§Authentication

If credentials are provided in the options, the method will automatically handle 401/407 authentication challenges by resending the request with proper authentication headers.

Source

pub fn do_invite_async( self: &Arc<Self>, opt: InviteOption, state_sender: DialogStateSender, ) -> Result<(ClientInviteDialog, JoinHandle<InviteAsyncResult>)>

Registers the dialog under an early dialog ID while the INVITE is in progress. Once completed, the early entry is removed and, on 2xx response, the dialog is re-registered under the confirmed dialog ID. Returns a JoinHandle resolving to the final dialog ID and response.

Source

pub fn create_client_invite_dialog( &self, opt: InviteOption, state_sender: DialogStateSender, ) -> Result<(ClientInviteDialog, Transaction)>

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> Conv for T

Source§

fn conv<T>(self) -> T
where Self: Into<T>,

Converts self into T using Into<T>. Read more
Source§

impl<T> Conv for T

Source§

fn conv<T>(self) -> T
where Self: Into<T>,

Converts self into a target type. Read more
Source§

impl<T> FmtForward for T

Source§

fn fmt_binary(self) -> FmtBinary<Self>
where Self: Binary,

Causes self to use its Binary implementation when Debug-formatted.
Source§

fn fmt_display(self) -> FmtDisplay<Self>
where Self: Display,

Causes self to use its Display implementation when Debug-formatted.
Source§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>
where Self: LowerExp,

Causes self to use its LowerExp implementation when Debug-formatted.
Source§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>
where Self: LowerHex,

Causes self to use its LowerHex implementation when Debug-formatted.
Source§

fn fmt_octal(self) -> FmtOctal<Self>
where Self: Octal,

Causes self to use its Octal implementation when Debug-formatted.
Source§

fn fmt_pointer(self) -> FmtPointer<Self>
where Self: Pointer,

Causes self to use its Pointer implementation when Debug-formatted.
Source§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>
where Self: UpperExp,

Causes self to use its UpperExp implementation when Debug-formatted.
Source§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>
where Self: UpperHex,

Causes self to use its UpperHex implementation when Debug-formatted.
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> Pipe for T
where T: ?Sized,

Source§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R
where Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
Source§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R
where R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
Source§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> R
where R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
Source§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
where Self: Borrow<B>, B: 'a + ?Sized, R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
Source§

fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
where Self: BorrowMut<B>, B: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe function. Read more
Source§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
where Self: AsRef<U>, U: 'a + ?Sized, R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
Source§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
where Self: AsMut<U>, U: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe function.
Source§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
where Self: Deref<Target = T>, T: 'a + ?Sized, R: 'a,

Borrows self, then passes self.deref() into the pipe function.
Source§

fn pipe_deref_mut<'a, T, R>( &'a mut self, func: impl FnOnce(&'a mut T) -> R, ) -> R
where Self: DerefMut<Target = T> + Deref, T: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe function.
Source§

impl<T> Pipe for T

Source§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R

Pipes a value into a function that cannot ordinarily be called in suffix position. Read more
Source§

impl<T> PipeAsRef for T

Source§

fn pipe_as_ref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
where Self: AsRef<T>, T: 'a, R: 'a,

Pipes a trait borrow into a function that cannot normally be called in suffix position. Read more
Source§

fn pipe_as_mut<'a, T, R>(&'a mut self, func: impl FnOnce(&'a mut T) -> R) -> R
where Self: AsMut<T>, T: 'a, R: 'a,

Pipes a trait mutable borrow into a function that cannot normally be called in suffix position. Read more
Source§

impl<T> PipeBorrow for T

Source§

fn pipe_borrow<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
where Self: Borrow<T>, T: 'a, R: 'a,

Pipes a trait borrow into a function that cannot normally be called in suffix position. Read more
Source§

fn pipe_borrow_mut<'a, T, R>( &'a mut self, func: impl FnOnce(&'a mut T) -> R, ) -> R
where Self: BorrowMut<T>, T: 'a, R: 'a,

Pipes a trait mutable borrow into a function that cannot normally be called in suffix position. Read more
Source§

impl<T> PipeDeref for T

Source§

fn pipe_deref<'a, R>(&'a self, func: impl FnOnce(&'a Self::Target) -> R) -> R
where Self: Deref, R: 'a,

Pipes a dereference into a function that cannot normally be called in suffix position. Read more
Source§

fn pipe_deref_mut<'a, R>( &'a mut self, func: impl FnOnce(&'a mut Self::Target) -> R, ) -> R
where Self: DerefMut, R: 'a,

Pipes a mutable dereference into a function that cannot normally be called in suffix position. Read more
Source§

impl<T> PipeRef for T

Source§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R
where R: 'a,

Pipes a reference into a function that cannot ordinarily be called in suffix position. Read more
Source§

fn pipe_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> R
where R: 'a,

Pipes a mutable reference into a function that cannot ordinarily be called in suffix position. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> Tap for T

Source§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
Source§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
Source§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
where Self: Borrow<B>, B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
Source§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
where Self: BorrowMut<B>, B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
Source§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
where Self: AsRef<R>, R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
Source§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
where Self: AsMut<R>, R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
Source§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
where Self: Deref<Target = T>, T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
Source§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
where Self: DerefMut<Target = T> + Deref, T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
Source§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
Source§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release builds.
Source§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
where Self: Borrow<B>, B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release builds.
Source§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
where Self: BorrowMut<B>, B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release builds.
Source§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
where Self: AsRef<R>, R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release builds.
Source§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
where Self: AsMut<R>, R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release builds.
Source§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
where Self: Deref<Target = T>, T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release builds.
Source§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Self
where Self: DerefMut<Target = T> + Deref, T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release builds.
Source§

impl<T> Tap for T

Source§

fn tap<F, R>(self, func: F) -> Self
where F: FnOnce(&Self) -> R,

Provides immutable access for inspection. Read more
Source§

fn tap_dbg<F, R>(self, func: F) -> Self
where F: FnOnce(&Self) -> R,

Calls tap in debug builds, and does nothing in release builds.
Source§

fn tap_mut<F, R>(self, func: F) -> Self
where F: FnOnce(&mut Self) -> R,

Provides mutable access for modification. Read more
Source§

fn tap_mut_dbg<F, R>(self, func: F) -> Self
where F: FnOnce(&mut Self) -> R,

Calls tap_mut in debug builds, and does nothing in release builds.
Source§

impl<T, U> TapAsRef<U> for T
where U: ?Sized,

Source§

fn tap_ref<F, R>(self, func: F) -> Self
where Self: AsRef<T>, F: FnOnce(&T) -> R,

Provides immutable access to the reference for inspection.
Source§

fn tap_ref_dbg<F, R>(self, func: F) -> Self
where Self: AsRef<T>, F: FnOnce(&T) -> R,

Calls tap_ref in debug builds, and does nothing in release builds.
Source§

fn tap_ref_mut<F, R>(self, func: F) -> Self
where Self: AsMut<T>, F: FnOnce(&mut T) -> R,

Provides mutable access to the reference for modification.
Source§

fn tap_ref_mut_dbg<F, R>(self, func: F) -> Self
where Self: AsMut<T>, F: FnOnce(&mut T) -> R,

Calls tap_ref_mut in debug builds, and does nothing in release builds.
Source§

impl<T, U> TapBorrow<U> for T
where U: ?Sized,

Source§

fn tap_borrow<F, R>(self, func: F) -> Self
where Self: Borrow<T>, F: FnOnce(&T) -> R,

Provides immutable access to the borrow for inspection. Read more
Source§

fn tap_borrow_dbg<F, R>(self, func: F) -> Self
where Self: Borrow<T>, F: FnOnce(&T) -> R,

Calls tap_borrow in debug builds, and does nothing in release builds.
Source§

fn tap_borrow_mut<F, R>(self, func: F) -> Self
where Self: BorrowMut<T>, F: FnOnce(&mut T) -> R,

Provides mutable access to the borrow for modification.
Source§

fn tap_borrow_mut_dbg<F, R>(self, func: F) -> Self
where Self: BorrowMut<T>, F: FnOnce(&mut T) -> R,

Calls tap_borrow_mut in debug builds, and does nothing in release builds.
Source§

impl<T> TapDeref for T

Source§

fn tap_deref<F, R>(self, func: F) -> Self
where Self: Deref, F: FnOnce(&Self::Target) -> R,

Immutably dereferences self for inspection.
Source§

fn tap_deref_dbg<F, R>(self, func: F) -> Self
where Self: Deref, F: FnOnce(&Self::Target) -> R,

Calls tap_deref in debug builds, and does nothing in release builds.
Source§

fn tap_deref_mut<F, R>(self, func: F) -> Self
where Self: DerefMut, F: FnOnce(&mut Self::Target) -> R,

Mutably dereferences self for modification.
Source§

fn tap_deref_mut_dbg<F, R>(self, func: F) -> Self
where Self: DerefMut, F: FnOnce(&mut Self::Target) -> R,

Calls tap_deref_mut in debug builds, and does nothing in release builds.
Source§

impl<T> TryConv for T

Source§

fn try_conv<T>(self) -> Result<T, Self::Error>
where Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
Source§

impl<T> TryConv for T

Source§

fn try_conv<T>(self) -> Result<T, Self::Error>
where Self: TryInto<T>,

Attempts to convert self into a target type. 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,