1use crate::{clean_str, clean_str_parse_country, AccountLite, Device};
2use cal_jambonz::rest::{InitialRequest, Request};
3use cal_jambonz::shared::shared::SIPStatus;
4use cal_jambonz::TenantType;
5use serde::{Deserialize, Serialize};
6
7pub const HANG_UP_CONNECT: &'static str = "HANGUP";
8pub const DEFAULT_TTS_VOICE: &'static str = "en-GB-Standard-B";
9pub const DEFAULT_TTS_LANGUAGE: &'static str = "en-GB";
10pub const DEFAULT_TTS_VENDOR: &'static str = "google";
11pub const DEFAULT_ASR_LANGUAGE: &'static str = "en-GB";
12pub const DEFAULT_ASR_VENDOR: &'static str = "google";
13pub const DEFAULT_RECORDING_RETENTION: &'static str = "P30D";
14pub const DEFAULT_CLIENT_PROFILE: &'static str = "generic_e164_plus";
15pub const DEFAULT_COUNTRY_CODE: &'static str = "gb";
16pub const DEFAULT_DIGITS_FINISH_KEY: &'static str = "#";
17pub const DEFAULT_ENDPOINT_PRESENT: &'static str = "pass-through";
18pub const DEFAULT_VM_FINISH_KEY: &'static str = "#";
19pub const DEFAULT_ENDPOINT_FORMAT: &'static str = "e164p";
20pub const DEFAULT_TIMEZONE: &'static str = "Europe/London";
21pub const DEFAULT_TRUNK_DESCRIPTION: &'static str = "SIP Trunk";
22pub const DEFAULT_TRUNK_PORT: u16 = 5060;
23pub const DEFAULT_RING_TIME: u8 = 180;
24pub const DEFAULT_DIGIT_TIMEOUT: u8 = 10;
25pub const DEFAULT_MAX_DIGITS: u8 = 1;
26pub const DEFAULT_VM_TIMEOUT: u8 = 30;
27pub const DEFAULT_VM_MAX_LENGTH: u8 = 30;
28pub const DEFAULT_CALL_TIME: u16 = 14400;
29
30#[derive(Serialize, Deserialize, Clone)]
31pub struct FlowState {
32 pub initial_request: InitialRequest,
33 pub current_request: Option<Request>,
34 pub account: AccountLite,
35 pub device: Option<Device>,
36 pub connect: Option<ConnectState>,
37 pub tenant_type: TenantType,
38}
39
40impl FlowState {
41 pub fn new(
42 initial_request: InitialRequest,
43 account: AccountLite,
44 proxies: Vec<&str>,
45 ) -> FlowState {
46 let tenant_type = initial_request.get_tenant_type(proxies);
47 let dialled_number = clean_str(
48 account.environment.country_code_parsed(),
49 &initial_request.to,
50 );
51 let device = match tenant_type {
52 TenantType::PROXY => {
53 account.inbound_flow(&dialled_number)
54 }
55 _ => match account.device(&dialled_number) {
56 Some(device) => Some(device),
57 None => account.outbound_flow(),
58 },
59 };
60
61 FlowState {
62 initial_request,
63 current_request: None,
64 account,
65 device,
66 connect: None,
67 tenant_type
68 }
69 }
70
71 pub fn get_country_code(&self) -> String {
72 self.account.environment.country_code.clone()
73 }
74
75 pub fn get_from(&self) -> String {
76 clean_str_parse_country(
77 self.get_country_code().as_str(),
78 self.initial_request.from.as_str(),
79 )
80 }
81 pub fn get_to(&self) -> String {
82 clean_str_parse_country(
83 self.get_country_code().as_str(),
84 self.initial_request.to.as_str(),
85 )
86 }
87 pub fn get_paid_or_from(&self) -> String {
88 match &self.initial_request.sip.headers.p_asserted_identity {
89 Some(str) => clean_str_parse_country(self.get_country_code().as_str(), str.as_str()),
90 None => self.get_from(),
91 }
92 }
93
94 pub fn get_timezone(&self) -> String {
95 self.account.environment.time_zone.clone()
96 }
97
98 pub fn get_dial_status(&self) -> Option<SIPStatus> {
99 match &self.current_request {
100 Some(request) => match request {
101 Request::Dial(value) => Some(value.sip_status.clone()),
102 _ => None,
103 },
104 _ => None,
105 }
106 }
107
108 pub fn get_digits(&self) -> Option<String> {
109 match &self.current_request {
110 Some(request) => match request {
111 Request::Subsequent(value) => match value.digits.clone() {
112 Some(d) => Some(d),
113 None => None,
114 },
115 _ => None,
116 },
117 _ => None,
118 }
119 }
120
121 pub fn add_state(&mut self, state: ConnectState) {
122 let device = self
123 .account
124 .devices
125 .iter()
126 .find(|d| d.match_device(state.connect_to.as_str()))
127 .map(|d| d.clone());
128
129 self.device = device.clone();
130 }
131}
132
133#[derive(Serialize, Deserialize, Clone)]
134pub struct ConnectState {
135 pub status: ConnectStatus,
136 pub value: Option<String>,
137 pub match_value: Option<String>,
138 pub connect_to: String,
139}
140
141impl ConnectState {
142 pub fn complete(connect_to: &str) -> ConnectState {
143 ConnectState {
144 connect_to: connect_to.to_string(),
145 status: ConnectStatus::OnCompleted,
146 match_value: None,
147 value: Some("Call Completed".to_string()),
148 }
149 }
150 pub fn fail(connect_to: &str) -> ConnectState {
151 ConnectState {
152 connect_to: connect_to.to_string(),
153 status: ConnectStatus::OnFail,
154 match_value: None,
155 value: Some("Call Failed".to_string()),
156 }
157 }
158
159 pub fn no_answer(connect_to: &str) -> ConnectState {
160 ConnectState {
161 connect_to: connect_to.to_string(),
162 status: ConnectStatus::OnNoAnswer,
163 match_value: None,
164 value: Some("No Answer".to_string()),
165 }
166 }
167
168 pub fn busy(connect_to: &str) -> ConnectState {
169 ConnectState {
170 connect_to: connect_to.to_string(),
171 status: ConnectStatus::OnBusy,
172 match_value: None,
173 value: Some("Call Busy".to_string()),
174 }
175 }
176
177 pub fn waiting() -> ConnectState {
178 ConnectState {
179 connect_to: "WAITING".to_string(),
180 status: ConnectStatus::OnWaiting,
181 match_value: None,
182 value: None,
183 }
184 }
185
186 pub fn dialling() -> ConnectState {
187 ConnectState {
188 connect_to: "DIALLING".to_string(),
189 status: ConnectStatus::OnDialling,
190 match_value: None,
191 value: None,
192 }
193 }
194
195 pub fn matched(
196 connect_to: &str,
197 value: Option<String>,
198 match_value: Option<String>,
199 ) -> ConnectState {
200 ConnectState {
201 connect_to: connect_to.to_string(),
202 status: ConnectStatus::OnMatch,
203 match_value,
204 value,
205 }
206 }
207
208 pub fn default(connect_to: &str, value: Option<String>) -> ConnectState {
209 ConnectState {
210 connect_to: connect_to.to_string(),
211 status: ConnectStatus::OnDefault,
212 match_value: None,
213 value,
214 }
215 }
216}
217
218#[derive(Serialize, Deserialize, Clone)]
219pub enum ConnectStatus {
220 OnDefault,
221 OnMatch,
222 OnCompleted,
223 OnFail,
224 OnBusy,
225 OnNoAnswer,
226 OnTransfer,
227 OnError,
228 OnWaiting,
229 OnDialling,
230}