1use crate::{
2 media::{recorder::RecorderOption, track::media_pass::MediaPassOption, vad::VADOption},
3 synthesis::SynthesisOption,
4 transcription::TranscriptionOption,
5};
6use anyhow::Result;
7use rsipstack::dialog::{authenticate::Credential, invitation::InviteOption};
8use serde::{Deserialize, Serialize};
9use serde_with::skip_serializing_none;
10use std::collections::HashMap;
11
12pub mod event;
13pub mod media;
14pub mod net_tool;
15pub mod synthesis;
16pub mod transcription;
17
18#[derive(Default, Debug, Serialize, Deserialize, Clone)]
19pub struct IceServer {
20 pub urls: Vec<String>,
21 #[serde(skip_serializing_if = "Option::is_none")]
22 pub username: Option<String>,
23 #[serde(skip_serializing_if = "Option::is_none")]
24 pub credential: Option<String>,
25}
26
27#[derive(Debug, Deserialize, Serialize, Default, Clone)]
28#[serde(default)]
29pub struct SipOption {
30 pub username: Option<String>,
31 pub password: Option<String>,
32 pub realm: Option<String>,
33 pub contact: Option<String>,
34 pub headers: Option<HashMap<String, String>>,
35}
36
37#[skip_serializing_none]
38#[derive(Debug, Deserialize, Serialize, Clone)]
39#[serde(rename_all = "camelCase")]
40pub struct CallOption {
41 pub denoise: Option<bool>,
42 pub offer: Option<String>,
43 pub callee: Option<String>,
44 pub caller: Option<String>,
45 pub recorder: Option<RecorderOption>,
46 pub vad: Option<VADOption>,
47 pub asr: Option<TranscriptionOption>,
48 pub tts: Option<SynthesisOption>,
49 pub media_pass: Option<MediaPassOption>,
50 pub handshake_timeout: Option<String>,
51 pub enable_ipv6: Option<bool>,
52 pub sip: Option<SipOption>,
53 pub extra: Option<HashMap<String, String>>,
54 pub codec: Option<String>, pub eou: Option<EouOption>,
56}
57
58impl Default for CallOption {
59 fn default() -> Self {
60 Self {
61 denoise: None,
62 offer: None,
63 callee: None,
64 caller: None,
65 recorder: None,
66 asr: None,
67 vad: None,
68 tts: None,
69 media_pass: None,
70 handshake_timeout: None,
71 enable_ipv6: None,
72 sip: None,
73 extra: None,
74 codec: None,
75 eou: None,
76 }
77 }
78}
79
80impl CallOption {
81 pub fn check_default(&mut self) {
82 if let Some(tts) = &mut self.tts {
83 tts.check_default();
84 }
85 if let Some(asr) = &mut self.asr {
86 asr.check_default();
87 }
88 }
89
90 pub fn build_invite_option(&self) -> Result<InviteOption> {
91 let mut invite_option = InviteOption::default();
92 if let Some(offer) = &self.offer {
93 invite_option.offer = Some(offer.clone().into());
94 }
95 if let Some(callee) = &self.callee {
96 invite_option.callee = callee.clone().try_into()?;
97 }
98 if let Some(caller) = &self.caller {
99 invite_option.caller = caller.clone().try_into()?;
100 invite_option.contact = invite_option.caller.clone();
101 }
102
103 if let Some(sip) = &self.sip {
104 invite_option.credential = Some(Credential {
105 username: sip.username.clone().unwrap_or_default(),
106 password: sip.password.clone().unwrap_or_default(),
107 realm: sip.realm.clone(),
108 });
109 invite_option.headers = sip.headers.as_ref().map(|h| {
110 h.iter()
111 .map(|(k, v)| rsip::Header::Other(k.clone(), v.clone()))
112 .collect::<Vec<_>>()
113 });
114 sip.contact.as_ref().map(|c| match c.clone().try_into() {
115 Ok(u) => {
116 invite_option.contact = u;
117 }
118 Err(_) => {}
119 });
120 }
121 Ok(invite_option)
122 }
123}
124
125#[skip_serializing_none]
126#[derive(Debug, Deserialize, Serialize, Clone)]
127#[serde(rename_all = "camelCase")]
128pub struct ReferOption {
129 pub denoise: Option<bool>,
130 pub timeout: Option<u32>,
131 pub moh: Option<String>,
132 pub asr: Option<TranscriptionOption>,
133 pub auto_hangup: Option<bool>,
135 pub sip: Option<SipOption>,
136}
137
138#[skip_serializing_none]
139#[derive(Clone, Debug, Deserialize, Serialize)]
140#[serde(rename_all = "camelCase")]
141pub struct EouOption {
142 pub r#type: Option<String>,
143 pub endpoint: Option<String>,
144 pub secret_key: Option<String>,
145 pub secret_id: Option<String>,
146 pub timeout: Option<u32>,
148 pub extra: Option<HashMap<String, String>>,
149}