sipx_sip/transaction/
server.rs1use std::time::Duration;
4
5use crate::message::{Message, Method, Request, Response, StatusCode};
6use crate::transaction::timing::{Timer, Timers};
7use crate::transaction::{Output, Reason, Reliability, TuEvent};
8
9#[derive(Debug, Clone, Copy, PartialEq, Eq)]
11pub enum ServerState {
12 Trying,
14 Proceeding,
16 Completed,
18 Confirmed,
20 Accepted,
22 Terminated,
24}
25
26impl ServerState {
27 #[must_use]
29 pub fn is_terminated(self) -> bool {
30 matches!(self, Self::Terminated)
31 }
32}
33
34#[derive(Debug)]
36pub struct ServerTransaction {
37 request: Request,
38 is_invite: bool,
39 state: ServerState,
40 reliability: Reliability,
41 timers: Timers,
42 last_response: Option<Response>,
44 interval: Duration,
46}
47
48impl ServerTransaction {
49 #[must_use]
56 pub fn new(request: Request, reliability: Reliability, timers: Timers) -> (Self, Vec<Output>) {
57 let is_invite = request.method == Method::Invite;
58 let tx = Self {
59 request: request.clone(),
60 is_invite,
61 state: if is_invite {
62 ServerState::Proceeding
63 } else {
64 ServerState::Trying
65 },
66 reliability,
67 timers,
68 last_response: None,
69 interval: timers.t1,
70 };
71
72 let mut out = vec![Output::to_tu(TuEvent::Request(Box::new(request)))];
73 if is_invite {
74 out.push(Output::SetTimer {
78 timer: Timer::Trying100,
79 after: timers.trying_100(),
80 });
81 }
82 (tx, out)
83 }
84
85 #[must_use]
87 pub fn state(&self) -> ServerState {
88 self.state
89 }
90
91 #[must_use]
93 pub fn request(&self) -> &Request {
94 &self.request
95 }
96
97 pub fn on_request(&mut self, request: &Request) -> Vec<Output> {
101 if request.method == Method::Ack {
102 return self.on_ack(request);
103 }
104 match self.state {
105 ServerState::Proceeding | ServerState::Completed => self
106 .last_response
107 .as_ref()
108 .map(|r| Output::send(Message::Response(r.clone())))
109 .into_iter()
110 .collect(),
111 _ => Vec::new(),
116 }
117 }
118
119 fn on_ack(&mut self, ack: &Request) -> Vec<Output> {
120 match self.state {
121 ServerState::Completed => {
122 self.state = ServerState::Confirmed;
124 vec![
125 Output::ClearTimer(Timer::G),
126 Output::ClearTimer(Timer::H),
127 Output::SetTimer {
128 timer: Timer::I,
129 after: self.timers.absorb(self.reliability),
130 },
131 ]
132 }
133 ServerState::Accepted => {
134 vec![Output::to_tu(TuEvent::Ack(Box::new(ack.clone())))]
138 }
139 _ => Vec::new(),
141 }
142 }
143
144 pub fn on_tu_response(&mut self, response: Response) -> Vec<Output> {
146 let status = response.status;
147 match self.state {
148 ServerState::Trying | ServerState::Proceeding => {
149 let mut out = vec![Output::ClearTimer(Timer::Trying100)];
150 self.last_response = Some(response.clone());
151 out.push(Output::send(Message::Response(response)));
152
153 if status.is_provisional() {
154 self.state = ServerState::Proceeding;
155 return out;
156 }
157
158 if self.is_invite {
159 if status.is_success() {
160 self.state = ServerState::Accepted;
161 out.push(Output::SetTimer {
162 timer: Timer::L,
163 after: self.timers.timeout(),
164 });
165 } else {
166 self.state = ServerState::Completed;
167 if !self.reliability.is_reliable() {
168 self.interval = self.timers.t1;
169 out.push(Output::SetTimer {
170 timer: Timer::G,
171 after: self.interval,
172 });
173 }
174 out.push(Output::SetTimer {
175 timer: Timer::H,
176 after: self.timers.timeout(),
177 });
178 }
179 } else {
180 self.state = ServerState::Completed;
181 out.push(Output::SetTimer {
182 timer: Timer::J,
183 after: self.timers.timer_j(self.reliability),
184 });
185 }
186 out
187 }
188 ServerState::Accepted if status.is_success() => {
189 self.last_response = Some(response.clone());
191 vec![Output::send(Message::Response(response))]
192 }
193 _ => Vec::new(),
194 }
195 }
196
197 pub fn on_timer(&mut self, timer: Timer) -> Vec<Output> {
199 match (self.state, timer) {
200 (ServerState::Proceeding, Timer::Trying100) => {
201 if self.last_response.is_some() {
206 return Vec::new();
207 }
208 let Some(trying) = self.build_trying() else {
210 return Vec::new();
211 };
212 self.last_response = Some(trying.clone());
213 vec![Output::send(Message::Response(trying))]
214 }
215 (ServerState::Completed, Timer::G) => {
216 self.interval = self.timers.double_capped(self.interval);
217 let mut out = Vec::new();
218 if let Some(response) = &self.last_response {
219 out.push(Output::send(Message::Response(response.clone())));
220 }
221 out.push(Output::SetTimer {
222 timer: Timer::G,
223 after: self.interval,
224 });
225 out
226 }
227 (ServerState::Completed, Timer::H) => {
228 self.state = ServerState::Terminated;
230 vec![
231 Output::to_tu(TuEvent::Timeout),
232 Output::Terminated(Reason::Timeout),
233 ]
234 }
235 (ServerState::Completed, Timer::J)
236 | (ServerState::Confirmed, Timer::I)
237 | (ServerState::Accepted, Timer::L) => {
238 self.state = ServerState::Terminated;
239 vec![Output::Terminated(Reason::Completed)]
240 }
241 _ => Vec::new(),
242 }
243 }
244
245 pub fn on_transport_error(&mut self) -> Vec<Output> {
247 if self.state.is_terminated() {
248 return Vec::new();
249 }
250 self.state = ServerState::Terminated;
251 vec![
252 Output::to_tu(TuEvent::TransportError),
253 Output::Terminated(Reason::TransportError),
254 ]
255 }
256
257 fn build_trying(&self) -> Option<Response> {
258 let status = StatusCode::new(100)?;
259 crate::build::ResponseBuilder::to_request(&self.request, status, "Trying")
260 .ok()
261 .map(crate::build::ResponseBuilder::build)
262 }
263}