diff --git a/src/app.rs b/src/app.rs index d06fa76..3d73e97 100644 --- a/src/app.rs +++ b/src/app.rs @@ -426,6 +426,16 @@ impl AppStateInner { info!(?key, "ignoring out-of-dialog OPTIONS request"); continue; } + rsipstack::rsip::Method::Refer => { + info!(?key, "ignoring out-of-dialog REFER"); + match tx.reply(rsipstack::rsip::StatusCode::BadRequest).await { + Ok(_) => (), + Err(e) => { + info!("error replying to out-of-dialog REFER: {:?}", e); + } + } + continue; + } _ => { info!(?key, "received request: {:?}", tx.original.method); match tx.reply(rsipstack::rsip::StatusCode::OK).await { diff --git a/src/call/sip.rs b/src/call/sip.rs index 2a5888d..dcf7c1a 100644 --- a/src/call/sip.rs +++ b/src/call/sip.rs @@ -398,6 +398,30 @@ impl DialogStateReceiverGuard { info!(session_id = states.session_id, %dialog_id, "dialog options received"); tx_handle.reply(rsipstack::rsip::StatusCode::OK).await.ok(); } + DialogState::Refer(dialog_id, req, tx_handle) => { + let refer_to = req.headers.iter().find_map(|h| { + if let rsipstack::rsip::Header::ReferTo(h) = h { + return Some(h.value().to_string()); + } + None + }).unwrap_or_default(); + let referred_by = req.headers.iter().find_map(|h| { + if let rsipstack::rsip::Header::ReferredBy(h) = h { + return Some(h.value().to_string()); + } + None + }); + info!(session_id = states.session_id, %dialog_id, %refer_to, "received REFER"); + tx_handle.reply(rsipstack::rsip::StatusCode::Other(202, "Accepted".into())).await.ok(); + let is_refer = states.call_state.read().await.is_refer; + states.event_sender.send(crate::event::SessionEvent::TransferRequest { + track_id: states.track_id.clone(), + timestamp: crate::media::get_timestamp(), + refer_to, + referred_by, + refer: Some(is_refer), + }).ok(); + } DialogState::Terminated(dialog_id, reason) => { info!( session_id = states.session_id, diff --git a/src/event.rs b/src/event.rs index be70114..41bdea4 100644 --- a/src/event.rs +++ b/src/event.rs @@ -126,6 +126,13 @@ pub enum SessionEvent { timestamp: u64, on_hold: bool, }, + TransferRequest { + track_id: String, + timestamp: u64, + refer_to: String, + referred_by: Option, + refer: Option, + }, TrackStart { track_id: String, timestamp: u64,