rvoip_transaction_core/server/data.rs
1/// # Server Transaction Data Structures
2///
3/// This module provides data structures and traits for implementing the server transaction
4/// state machines defined in RFC 3261 Section 17.2.
5///
6/// Server transactions in SIP are responsible for:
7/// - Processing incoming requests from clients
8/// - Sending responses reliably
9/// - Managing state transitions based on request/response types
10/// - Handling retransmissions according to RFC 3261 rules
11///
12/// The key components in this module are:
13/// - `ServerTransactionData`: Core data structure shared by all server transaction types
14/// - `CommonServerTransaction`: Trait providing shared behavior across transaction types
15/// - Command channels for communication with the transaction's event loop
16
17use std::fmt;
18use std::future::Future;
19use std::net::SocketAddr;
20use std::pin::Pin;
21use std::sync::Arc;
22use tokio::sync::{mpsc, Mutex};
23use tokio::task::JoinHandle;
24use tracing::{debug, trace};
25
26use rvoip_sip_core::prelude::*;
27use rvoip_sip_transport::Transport;
28
29use crate::error::{Error, Result};
30use crate::transaction::{
31 Transaction, TransactionState, TransactionKey, TransactionEvent,
32 InternalTransactionCommand, AtomicTransactionState
33};
34use crate::timer::TimerSettings;
35use crate::transaction::runner::{AsRefState, AsRefKey, HasTransactionEvents, HasTransport, HasCommandSender};
36
37/// Command sender for transaction event loops.
38///
39/// Used to send commands to the transaction's internal event loop, allowing
40/// asynchronous control of the transaction's behavior.
41pub type CommandSender = mpsc::Sender<InternalTransactionCommand>;
42
43/// Command receiver for transaction event loops.
44///
45/// Used by the transaction's event loop to receive commands from other
46/// components, such as the TransactionManager or the transaction itself.
47pub type CommandReceiver = mpsc::Receiver<InternalTransactionCommand>;
48
49/// Common data structure for both INVITE and non-INVITE server transactions.
50///
51/// This structure contains all the state required for implementing the server transaction
52/// state machines defined in RFC 3261 Section 17.2. It includes:
53///
54/// - Identity information (transaction key)
55/// - State tracking (current transaction state)
56/// - Message storage (original request, last response)
57/// - Communication channels (transport, event channels, command channels)
58/// - Timer configuration
59///
60/// Both `ServerInviteTransaction` and `ServerNonInviteTransaction` use this structure
61/// as their core data store, while implementing different behavior around it.
62#[derive(Debug)]
63pub struct ServerTransactionData {
64 /// Transaction ID based on RFC 3261 transaction matching rules
65 pub id: TransactionKey,
66
67 /// Current transaction state (Trying/Proceeding, Completed, Confirmed, Terminated)
68 pub state: Arc<AtomicTransactionState>,
69
70 /// Original request that initiated this transaction
71 pub request: Arc<Mutex<Request>>,
72
73 /// Last response sent by this transaction
74 pub last_response: Arc<Mutex<Option<Response>>>,
75
76 /// Remote address to which responses are sent
77 pub remote_addr: SocketAddr,
78
79 /// Transport layer for sending SIP messages
80 pub transport: Arc<dyn Transport>,
81
82 /// Channel for sending events to the Transaction User (TU)
83 pub events_tx: mpsc::Sender<TransactionEvent>,
84
85 /// Channel for sending commands to the transaction's event loop
86 pub cmd_tx: CommandSender,
87
88 /// Channel for receiving commands in the transaction's event loop
89 pub cmd_rx: Arc<Mutex<CommandReceiver>>,
90
91 /// Handle to the transaction's event loop task
92 pub event_loop_handle: Arc<Mutex<Option<JoinHandle<()>>>>,
93
94 /// Configuration for transaction timers (T1, T2, etc.)
95 pub timer_config: TimerSettings,
96}
97
98impl Drop for ServerTransactionData {
99 fn drop(&mut self) {
100 // Try to terminate the event loop when the transaction is dropped
101 debug!(id=%self.id, "ServerTransactionData dropped, attempting to terminate event loop");
102
103 if let Ok(mut handle_guard) = self.event_loop_handle.try_lock() {
104 if let Some(handle) = handle_guard.take() {
105 handle.abort();
106 debug!(id=%self.id, "Aborted server transaction event loop");
107 }
108 }
109 }
110}
111
112/// Common behavior trait for all server transactions.
113///
114/// This trait provides shared functionality that all server transactions need,
115/// regardless of whether they are INVITE or non-INVITE transactions. It serves
116/// as a base for the more specific transaction type implementations.
117pub trait CommonServerTransaction {
118 /// Returns the shared transaction data.
119 ///
120 /// # Returns
121 ///
122 /// A reference to the `ServerTransactionData` structure containing the transaction's state.
123 fn data(&self) -> &Arc<ServerTransactionData>;
124}
125
126// Implementation of transaction runner traits for ServerTransactionData
127
128/// Allows access to the transaction state.
129/// Required by the transaction runner to manage state transitions.
130impl AsRefState for ServerTransactionData {
131 fn as_ref_state(&self) -> &Arc<AtomicTransactionState> {
132 &self.state
133 }
134}
135
136/// Allows access to the transaction key.
137/// Required by the transaction runner for identification and logging.
138impl AsRefKey for ServerTransactionData {
139 fn as_ref_key(&self) -> &TransactionKey {
140 &self.id
141 }
142}
143
144/// Provides access to the event channel.
145/// Required by the transaction runner to send events to the Transaction User.
146impl HasTransactionEvents for ServerTransactionData {
147 fn get_tu_event_sender(&self) -> mpsc::Sender<TransactionEvent> {
148 self.events_tx.clone()
149 }
150}
151
152/// Provides access to the transport layer.
153/// Required by the transaction runner to send messages.
154impl HasTransport for ServerTransactionData {
155 fn get_transport_layer(&self) -> Arc<dyn Transport> {
156 self.transport.clone()
157 }
158}
159
160/// Provides access to the command channel.
161/// Required by the transaction runner to send commands to itself.
162impl HasCommandSender for ServerTransactionData {
163 fn get_self_command_sender(&self) -> mpsc::Sender<InternalTransactionCommand> {
164 self.cmd_tx.clone()
165 }
166}