diff --git a/src/dialog/client_dialog.rs b/src/dialog/client_dialog.rs index 188392f..4fcdb79 100644 --- a/src/dialog/client_dialog.rs +++ b/src/dialog/client_dialog.rs @@ -196,11 +196,6 @@ impl ClientInviteDialog { cancel_request .headers_mut() .retain(|h| !matches!(h, Header::ContentLength(_) | Header::ContentType(_))); - - cancel_request - .to_header_mut()? - .mut_tag(self.id().to_tag.clone().into())?; // ensure to-tag has tag param - cancel_request.method = rsip::Method::Cancel; let invite_seq = self.inner.initial_request.cseq_header()?.seq()?; cancel_request diff --git a/src/dialog/dialog_layer.rs b/src/dialog/dialog_layer.rs index 461de3d..b35d35a 100644 --- a/src/dialog/dialog_layer.rs +++ b/src/dialog/dialog_layer.rs @@ -1,6 +1,7 @@ use super::authenticate::Credential; use super::dialog::DialogStateSender; use super::{dialog::Dialog, server_dialog::ServerInviteDialog, DialogId}; +use crate::dialog::client_dialog::ClientInviteDialog; use crate::dialog::dialog::{DialogInner, DialogStateReceiver}; use crate::transaction::key::TransactionRole; use crate::transaction::make_tag; @@ -229,6 +230,32 @@ impl DialogLayer { } } + /// 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. + pub fn get_client_dialog_by_call_id(&self, call_id: &str) -> Vec { + self.inner + .dialogs + .read() + .map(|guard| { + guard + .values() + .filter_map(|dlg| match dlg { + Dialog::ClientInvite(client_dlg) if client_dlg.id().call_id == call_id => { + Some(client_dlg.clone()) + } + _ => None, + }) + .collect() + }) + .unwrap_or_default() + } + pub fn remove_dialog(&self, id: &DialogId) { info!(%id, "remove dialog"); self.inner