Skip to content

Commit 1a63cbb

Browse files
committed
feat: update version to 0.2.25
1 parent ef8c47e commit 1a63cbb

File tree

5 files changed

+104
-20
lines changed

5 files changed

+104
-20
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "rsipstack"
3-
version = "0.2.24"
3+
version = "0.2.25"
44
edition = "2021"
55
description = "SIP Stack Rust library for building SIP applications"
66
license = "MIT"

examples/client/main.rs

Lines changed: 57 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,47 @@ struct Args {
7373
call: Option<String>,
7474
}
7575

76+
async fn handle_user_input(cancel_token: CancellationToken) -> Result<()> {
77+
use tokio::io::{AsyncBufReadExt, BufReader};
78+
79+
let stdin = tokio::io::stdin();
80+
let reader = BufReader::new(stdin);
81+
let mut lines = reader.lines();
82+
83+
info!("Press 'q' and Enter to hang up current call");
84+
85+
loop {
86+
select! {
87+
line = lines.next_line() => {
88+
match line {
89+
Ok(Some(input)) => {
90+
let input = input.trim().to_lowercase();
91+
if input == "q" {
92+
info!("User requested to hang up");
93+
cancel_token.cancel();
94+
info!("Cancelled all dialogs");
95+
break;
96+
}
97+
},
98+
Ok(None) => {
99+
// EOF reached
100+
break;
101+
},
102+
Err(e) => {
103+
info!("Error reading input: {:?}", e);
104+
break;
105+
}
106+
}
107+
},
108+
_ = cancel_token.cancelled() => {
109+
info!("User input handler cancelled");
110+
break;
111+
}
112+
}
113+
}
114+
Ok(())
115+
}
116+
76117
// A sip client example, that sends a REGISTER request to a sip server.
77118
#[tokio::main]
78119
async fn main() -> rsipstack::Result<()> {
@@ -443,12 +484,22 @@ async fn play_example_pcmu(opt: &MediaSessionOption, dialog: ServerInviteDialog)
443484
let rtp_token = dialog.cancel_token().child_token();
444485
let echo = opt.echo;
445486
tokio::spawn(async move {
446-
if echo {
447-
play_echo(conn, rtp_token).await.expect("play echo");
448-
} else {
449-
play_example_file(conn, rtp_token, ssrc, peer_addr)
450-
.await
451-
.expect("play example file");
487+
let input_token = CancellationToken::new();
488+
select! {
489+
_ = handle_user_input(input_token) => {
490+
info!("user input handler finished");
491+
}
492+
_ = async {
493+
if echo {
494+
play_echo(conn, rtp_token).await.expect("play echo");
495+
} else {
496+
play_example_file(conn, rtp_token, ssrc, peer_addr)
497+
.await
498+
.expect("play example file");
499+
}
500+
} => {
501+
info!("play example finished");
502+
}
452503
}
453504
dialog.bye().await.expect("send BYE");
454505
});

src/dialog/client_dialog.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -112,10 +112,10 @@ impl ClientInviteDialog {
112112
/// If the dialog is confirmed, send a BYE request to terminate the call.
113113
/// If the dialog is not confirmed, send a CANCEL request to cancel the call.
114114
pub async fn hangup(&self) -> Result<()> {
115-
if self.inner.is_confirmed() {
116-
self.bye().await
117-
} else {
115+
if self.inner.can_cancel() {
118116
self.cancel().await
117+
} else {
118+
self.bye().await
119119
}
120120
}
121121

src/dialog/dialog.rs

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,12 @@ pub(super) type DialogInnerRef = Arc<DialogInner>;
189189
pub(super) type TuSenderRef = Mutex<Option<TransactionEventSender>>;
190190

191191
impl DialogState {
192+
pub fn can_cancel(&self) -> bool {
193+
matches!(
194+
self,
195+
DialogState::Calling(_) | DialogState::Trying(_) | DialogState::Early(_, _)
196+
)
197+
}
192198
pub fn is_confirmed(&self) -> bool {
193199
matches!(self, DialogState::Confirmed(_))
194200
}
@@ -258,6 +264,9 @@ impl DialogInner {
258264
remote_contact: Mutex::new(None),
259265
})
260266
}
267+
pub fn can_cancel(&self) -> bool {
268+
self.state.lock().unwrap().can_cancel()
269+
}
261270
pub fn is_confirmed(&self) -> bool {
262271
self.state.lock().unwrap().is_confirmed()
263272
}
@@ -440,13 +449,11 @@ impl DialogInner {
440449
Err(e) => {
441450
warn!(
442451
id = self.id.lock().unwrap().to_string(),
443-
method = %method,
444-
destination=?tx.destination,"failed to send request: {}", e);
452+
destination=?tx.destination,"failed to send request error: {}\n{}", e, tx.original);
445453
return Err(e);
446454
}
447455
}
448456
let mut auth_sent = false;
449-
450457
while let Some(msg) = tx.receive().await {
451458
match msg {
452459
SipMessage::Response(resp) => match resp.status_code {
@@ -460,7 +467,10 @@ impl DialogInner {
460467
StatusCode::ProxyAuthenticationRequired | StatusCode::Unauthorized => {
461468
let id = self.id.lock().unwrap().clone();
462469
if auth_sent {
463-
info!("received {} response after auth sent", resp.status_code);
470+
info!(
471+
id = self.id.lock().unwrap().to_string(),
472+
"received {} response after auth sent", resp.status_code
473+
);
464474
self.transition(DialogState::Terminated(
465475
id,
466476
TerminatedReason::ProxyAuthRequired,
@@ -477,15 +487,22 @@ impl DialogInner {
477487
tx.send().await?;
478488
continue;
479489
} else {
480-
info!("received 407 response without auth option");
490+
info!(
491+
id = self.id.lock().unwrap().to_string(),
492+
"received 407 response without auth option"
493+
);
481494
self.transition(DialogState::Terminated(
482495
id,
483496
TerminatedReason::ProxyAuthRequired,
484497
))?;
485498
}
486499
}
487500
_ => {
488-
debug!("dialog do_request done: {:?}", resp.status_code);
501+
debug!(
502+
id = self.id.lock().unwrap().to_string(),
503+
method = %method,
504+
"dialog do_request done: {:?}", resp.status_code
505+
);
489506
return Ok(Some(resp));
490507
}
491508
},

src/dialog/server_dialog.rs

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
use super::dialog::{Dialog, DialogInnerRef, DialogState, TerminatedReason};
22
use super::DialogId;
3+
use crate::transport::SipConnection;
34
use crate::{
45
transaction::transaction::{Transaction, TransactionEvent},
56
Result,
67
};
78
use rsip::{prelude::HeadersExt, Header, Request, SipMessage, StatusCode};
89
use std::sync::atomic::Ordering;
910
use tokio_util::sync::CancellationToken;
10-
use tracing::{info, trace, warn};
11+
use tracing::{debug, info, trace, warn};
1112

1213
/// Server-side INVITE Dialog (UAS)
1314
///
@@ -154,7 +155,15 @@ impl ServerInviteDialog {
154155
headers,
155156
body,
156157
);
157-
158+
let via = self.inner.initial_request.via_header()?;
159+
let via_received = SipConnection::parse_target_from_via(via)?;
160+
let contact = rsip::Uri {
161+
host_with_port: via_received,
162+
params: vec![rsip::Param::Transport(via.trasnport()?)],
163+
..Default::default()
164+
};
165+
debug!(id = %self.id(), "accepting dialog with contact: {}", contact);
166+
self.inner.remote_contact.lock().unwrap().replace(contact);
158167
sender.send(TransactionEvent::Respond(resp.clone()))?;
159168

160169
self.inner
@@ -492,9 +501,9 @@ impl ServerInviteDialog {
492501
/// * `UPDATE` - Handles session updates
493502
/// * `INVITE` - Handles initial INVITE or re-INVITE
494503
pub async fn handle(&mut self, tx: &mut Transaction) -> Result<()> {
495-
trace!(
504+
debug!(
496505
id = %self.id(),
497-
"handle request: {:?} state:{}",
506+
"handle request: {} state:{}",
498507
tx.original,
499508
self.inner.state.lock().unwrap()
500509
);
@@ -608,6 +617,13 @@ impl ServerInviteDialog {
608617
SipMessage::Request(req) => match req.method {
609618
rsip::Method::Ack => {
610619
info!(id = %self.id(),"received ack {}", req.uri);
620+
match req.contact_header() {
621+
Ok(contact) => {
622+
let contact = contact.uri()?.into();
623+
self.inner.remote_contact.lock().unwrap().replace(contact);
624+
}
625+
_ => {}
626+
}
611627
self.inner.transition(DialogState::Confirmed(self.id()))?;
612628
}
613629
rsip::Method::Cancel => {

0 commit comments

Comments
 (0)