sipx_sip/transaction/
layer.rs1use std::collections::HashMap;
4
5use crate::message::{Message, Method, Request, Response};
6use crate::transaction::client::{ClientState, ClientTransaction};
7use crate::transaction::key::TransactionKey;
8use crate::transaction::server::{ServerState, ServerTransaction};
9use crate::transaction::timing::{Timer, Timers};
10use crate::transaction::{Output, Reliability, TuEvent};
11
12#[derive(Debug)]
14pub enum Dispatch {
15 Matched {
17 key: TransactionKey,
19 outputs: Vec<Output>,
21 },
22 Created {
24 key: TransactionKey,
26 outputs: Vec<Output>,
28 },
29 Unmatched(Box<Message>),
34}
35
36#[derive(Debug)]
41pub struct TransactionLayer {
42 client: HashMap<TransactionKey, ClientTransaction>,
43 server: HashMap<TransactionKey, ServerTransaction>,
44 timers: Timers,
45}
46
47impl TransactionLayer {
48 #[must_use]
50 pub fn new(timers: Timers) -> Self {
51 Self {
52 client: HashMap::new(),
53 server: HashMap::new(),
54 timers,
55 }
56 }
57
58 #[must_use]
63 pub fn len(&self) -> (usize, usize) {
64 (self.client.len(), self.server.len())
65 }
66
67 #[must_use]
69 pub fn is_empty(&self) -> bool {
70 self.client.is_empty() && self.server.is_empty()
71 }
72
73 pub fn send_request(
75 &mut self,
76 request: Request,
77 reliability: Reliability,
78 ) -> Option<(TransactionKey, Vec<Output>)> {
79 let key = TransactionKey::from_sent_request(&request)?;
80 let (tx, outputs) = ClientTransaction::new(request, reliability, self.timers);
81 self.client.insert(key.clone(), tx);
82 Some((key, outputs))
83 }
84
85 pub fn receive(&mut self, message: Message, reliability: Reliability) -> Dispatch {
87 match message {
88 Message::Request(request) => self.receive_request(request, reliability),
89 Message::Response(response) => self.receive_response(response),
90 }
91 }
92
93 fn receive_request(&mut self, request: Request, reliability: Reliability) -> Dispatch {
94 let Some(key) = TransactionKey::from_request(&request) else {
95 return Dispatch::Unmatched(Box::new(Message::Request(request)));
96 };
97
98 if let Some(tx) = self.server.get_mut(&key) {
99 let outputs = tx.on_request(&request);
100 let terminated = tx.state().is_terminated();
101 if terminated {
102 self.server.remove(&key);
103 }
104 return Dispatch::Matched { key, outputs };
105 }
106
107 if request.method == Method::Ack {
110 return Dispatch::Unmatched(Box::new(Message::Request(request)));
111 }
112
113 let (tx, outputs) = ServerTransaction::new(request, reliability, self.timers);
114 self.server.insert(key.clone(), tx);
115 Dispatch::Created { key, outputs }
116 }
117
118 fn receive_response(&mut self, response: Response) -> Dispatch {
119 let Some(key) = TransactionKey::from_response(&response) else {
120 return Dispatch::Unmatched(Box::new(Message::Response(response)));
121 };
122
123 let Some(tx) = self.client.get_mut(&key) else {
124 return Dispatch::Unmatched(Box::new(Message::Response(response)));
125 };
126
127 let outputs = tx.on_response(response);
128 if tx.state().is_terminated() {
129 self.client.remove(&key);
130 }
131 Dispatch::Matched { key, outputs }
132 }
133
134 pub fn send_response(&mut self, key: &TransactionKey, response: Response) -> Vec<Output> {
136 let Some(tx) = self.server.get_mut(key) else {
137 return Vec::new();
138 };
139 let outputs = tx.on_tu_response(response);
140 if tx.state().is_terminated() {
141 self.server.remove(key);
142 }
143 outputs
144 }
145
146 pub fn abandon(&mut self, key: &TransactionKey) -> bool {
160 self.server.remove(key).is_some()
161 }
162
163 pub fn on_timer(&mut self, key: &TransactionKey, timer: Timer) -> Vec<Output> {
165 if let Some(tx) = self.client.get_mut(key) {
166 let outputs = tx.on_timer(timer);
167 if tx.state().is_terminated() {
168 self.client.remove(key);
169 }
170 return outputs;
171 }
172 if let Some(tx) = self.server.get_mut(key) {
173 let outputs = tx.on_timer(timer);
174 if tx.state().is_terminated() {
175 self.server.remove(key);
176 }
177 return outputs;
178 }
179 Vec::new()
180 }
181
182 pub fn on_transport_error(&mut self, key: &TransactionKey) -> Vec<Output> {
184 if let Some(tx) = self.client.get_mut(key) {
185 let outputs = tx.on_transport_error();
186 self.client.remove(key);
187 return outputs;
188 }
189 if let Some(tx) = self.server.get_mut(key) {
190 let outputs = tx.on_transport_error();
191 self.server.remove(key);
192 return outputs;
193 }
194 Vec::new()
195 }
196
197 #[must_use]
203 pub fn server_request(&self, key: &TransactionKey) -> Option<&Request> {
204 self.server.get(key).map(ServerTransaction::request)
205 }
206
207 #[must_use]
212 pub fn client_request(&self, key: &TransactionKey) -> Option<&Request> {
213 self.client.get(key).map(ClientTransaction::request)
214 }
215
216 #[must_use]
218 pub fn client_state(&self, key: &TransactionKey) -> Option<ClientState> {
219 self.client.get(key).map(ClientTransaction::state)
220 }
221
222 #[must_use]
224 pub fn server_state(&self, key: &TransactionKey) -> Option<ServerState> {
225 self.server.get(key).map(ServerTransaction::state)
226 }
227}
228
229#[must_use]
231pub fn tu_events(outputs: &[Output]) -> Vec<&TuEvent> {
232 outputs
233 .iter()
234 .filter_map(|o| match o {
235 Output::ToTu(event) => Some(event.as_ref()),
236 _ => None,
237 })
238 .collect()
239}
240
241#[must_use]
243pub fn sent_messages(outputs: &[Output]) -> Vec<&Message> {
244 outputs
245 .iter()
246 .filter_map(|o| match o {
247 Output::Send(message) => Some(message.as_ref()),
248 _ => None,
249 })
250 .collect()
251}