Skip to content

Commit a5567c4

Browse files
committed
fix: update version to 0.2.46 and modify transaction state handling
1 parent 5367f5e commit a5567c4

File tree

5 files changed

+54
-18
lines changed

5 files changed

+54
-18
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.45"
3+
version = "0.2.46"
44
edition = "2021"
55
description = "SIP Stack Rust library for building SIP applications"
66
license = "MIT"

src/transaction/endpoint.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -430,15 +430,15 @@ impl EndpointInner {
430430
}
431431

432432
pub fn attach_transaction(&self, key: &TransactionKey, tu_sender: TransactionEventSender) {
433-
trace!("attach_transaction {}", key);
433+
trace!(%key, "attach transaction");
434434
self.transactions
435435
.lock()
436436
.unwrap()
437437
.insert(key.clone(), tu_sender);
438438
}
439439

440440
pub fn detach_transaction(&self, key: &TransactionKey, last_message: Option<SipMessage>) {
441-
trace!("detach_transaction {}", key);
441+
trace!(%key, "detach transaction");
442442
self.transactions.lock().unwrap().remove(key);
443443

444444
if let Some(msg) = last_message {

src/transaction/mod.rs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ pub type TransactionSender = UnboundedSender<Transaction>;
3535
///
3636
/// # States
3737
///
38-
/// * `Calling` - Initial state for client transactions when request is sent
38+
/// * `Nothing` - Initial state for client transactions created
39+
/// * `Calling` - Initial state for client transactions when request is sent or received
3940
/// * `Trying` - Request has been sent/received, waiting for response/processing
4041
/// * `Proceeding` - Provisional response received/sent (1xx except 100 Trying)
4142
/// * `Completed` - Final response received/sent, waiting for ACK (INVITE) or cleanup
@@ -46,21 +47,21 @@ pub type TransactionSender = UnboundedSender<Transaction>;
4647
///
4748
/// ## Client Non-INVITE Transaction
4849
/// ```text
49-
/// Calling → Trying → Proceeding → Completed → Terminated
50+
/// Nothing → Calling → Trying → Proceeding → Completed → Terminated
5051
/// ```
5152
///
5253
/// ## Client INVITE Transaction
5354
/// ```text
54-
/// Calling → Trying → Proceeding → Completed → Terminated
55+
/// Nothing → Calling → Trying → Proceeding → Completed → Terminated
5556
/// ↓
56-
/// Confirmed → Terminated
57+
/// Confirmed → Terminated
5758
/// ```
5859
///
5960
/// ## Server Transactions
6061
/// ```text
61-
/// Trying → Proceeding → Completed → Terminated
62+
/// Calling → Trying → Proceeding → Completed → Terminated
6263
/// ↓
63-
/// Confirmed → Terminated (INVITE only)
64+
/// Confirmed → Terminated (INVITE only)
6465
/// ```
6566
///
6667
/// # Examples
@@ -70,7 +71,8 @@ pub type TransactionSender = UnboundedSender<Transaction>;
7071
///
7172
/// let state = TransactionState::Proceeding;
7273
/// match state {
73-
/// TransactionState::Calling => println!("Transaction starting"),
74+
/// TransactionState::Nothing => println!("Transaction starting"),
75+
/// TransactionState::Calling => println!("Request sent"),
7476
/// TransactionState::Trying => println!("Request sent/received"),
7577
/// TransactionState::Proceeding => println!("Provisional response"),
7678
/// TransactionState::Completed => println!("Final response"),
@@ -80,6 +82,7 @@ pub type TransactionSender = UnboundedSender<Transaction>;
8082
/// ```
8183
#[derive(Debug, Clone, PartialEq)]
8284
pub enum TransactionState {
85+
Nothing,
8386
Calling,
8487
Trying,
8588
Proceeding,
@@ -91,6 +94,7 @@ pub enum TransactionState {
9194
impl std::fmt::Display for TransactionState {
9295
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
9396
match self {
97+
TransactionState::Nothing => write!(f, "Nothing"),
9498
TransactionState::Calling => write!(f, "Calling"),
9599
TransactionState::Trying => write!(f, "Trying"),
96100
TransactionState::Proceeding => write!(f, "Proceeding"),

src/transaction/tests/test_transaction_states.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ async fn test_client_invite_transaction_creation() -> crate::Result<()> {
5050
);
5151

5252
// Initial state should be Calling
53-
assert_eq!(tx.state, TransactionState::Calling);
53+
assert_eq!(tx.state, TransactionState::Nothing);
5454
assert_eq!(tx.transaction_type, TransactionType::ClientInvite);
5555

5656
Ok(())
@@ -72,7 +72,7 @@ async fn test_client_non_invite_transaction_creation() -> crate::Result<()> {
7272
);
7373

7474
// Initial state should be Calling
75-
assert_eq!(tx.state, TransactionState::Calling);
75+
assert_eq!(tx.state, TransactionState::Nothing);
7676
assert_eq!(tx.transaction_type, TransactionType::ClientNonInvite);
7777

7878
Ok(())

src/transaction/transaction.rs

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -175,15 +175,23 @@ impl Transaction {
175175
endpoint_inner: EndpointInnerRef,
176176
) -> Self {
177177
let (tu_sender, tu_receiver) = unbounded_channel();
178-
info!(%key, "transaction created");
178+
let state = if matches!(
179+
transaction_type,
180+
TransactionType::ServerInvite | TransactionType::ServerNonInvite
181+
) {
182+
TransactionState::Calling
183+
} else {
184+
TransactionState::Nothing
185+
};
186+
info!(%key, %state, "transaction created");
179187
let tx = Self {
180188
transaction_type,
181189
endpoint_inner,
182190
connection,
183191
key,
184192
original,
185193
destination: None,
186-
state: TransactionState::Calling,
194+
state,
187195
last_response: None,
188196
last_ack: None,
189197
timer_a: None,
@@ -270,7 +278,7 @@ impl Transaction {
270278
};
271279

272280
connection.send(message, self.destination.as_ref()).await?;
273-
self.transition(TransactionState::Trying).map(|_| ())
281+
self.transition(TransactionState::Calling).map(|_| ())
274282
}
275283

276284
pub async fn reply_with(
@@ -348,7 +356,11 @@ impl Transaction {
348356

349357
fn can_transition(&self, target: &TransactionState) -> Result<()> {
350358
match (&self.state, target) {
351-
(&TransactionState::Calling, &TransactionState::Trying)
359+
(&TransactionState::Nothing, &TransactionState::Calling)
360+
| (&TransactionState::Nothing, &TransactionState::Trying)
361+
| (&TransactionState::Nothing, &TransactionState::Proceeding)
362+
| (&TransactionState::Nothing, &TransactionState::Terminated)
363+
| (&TransactionState::Calling, &TransactionState::Trying)
352364
| (&TransactionState::Calling, &TransactionState::Proceeding)
353365
| (&TransactionState::Calling, &TransactionState::Completed)
354366
| (&TransactionState::Calling, &TransactionState::Terminated)
@@ -615,7 +627,7 @@ impl Transaction {
615627

616628
async fn on_timer(&mut self, timer: TransactionTimer) -> Result<()> {
617629
match self.state {
618-
TransactionState::Trying => {
630+
TransactionState::Calling | TransactionState::Trying => {
619631
if matches!(
620632
self.transaction_type,
621633
TransactionType::ClientInvite | TransactionType::ClientNonInvite
@@ -704,8 +716,28 @@ impl Transaction {
704716
return Ok(self.state.clone());
705717
}
706718
match state {
719+
TransactionState::Nothing => {}
707720
TransactionState::Calling => {
708-
// not state can transition to Calling
721+
let connection = self.connection.as_ref().ok_or(Error::TransactionError(
722+
"no connection found".to_string(),
723+
self.key.clone(),
724+
))?;
725+
726+
if matches!(
727+
self.transaction_type,
728+
TransactionType::ClientInvite | TransactionType::ClientNonInvite
729+
) {
730+
if !connection.is_reliable() {
731+
let timer_a = self.endpoint_inner.timers.timeout(
732+
self.endpoint_inner.option.t1,
733+
TransactionTimer::TimerA(
734+
self.key.clone(),
735+
self.endpoint_inner.option.t1,
736+
),
737+
);
738+
self.timer_a.replace(timer_a);
739+
}
740+
}
709741
}
710742
TransactionState::Trying => {
711743
let connection = self.connection.as_ref().ok_or(Error::TransactionError(

0 commit comments

Comments
 (0)