use crate::{CallOption, ReferOption, media::recorder::RecorderOption, synthesis::SynthesisOption};
use serde::{Deserialize, Serialize};
use serde_with::skip_serializing_none;
use std::{
collections::HashMap,
sync::{Arc, Mutex},
};
pub mod active_call;
pub mod sip;
pub use active_call::ActiveCall;
pub use active_call::ActiveCallRef;
pub use active_call::ActiveCallType;
pub type CommandSender = tokio::sync::broadcast::Sender<Command>;
pub type CommandReceiver = tokio::sync::broadcast::Receiver<Command>;
#[skip_serializing_none]
#[derive(Debug, Deserialize, Serialize, Clone)]
#[serde(
tag = "command",
rename_all = "camelCase",
rename_all_fields = "camelCase"
)]
pub enum Command {
Invite {
option: CallOption,
},
Accept {
option: CallOption,
},
Reject {
reason: String,
code: Option<u32>,
},
Ringing {
recorder: Option<RecorderOption>,
early_media: Option<bool>,
ringtone: Option<String>,
},
Tts {
text: String,
speaker: Option<String>,
play_id: Option<String>,
auto_hangup: Option<bool>,
streaming: Option<bool>,
end_of_stream: Option<bool>,
option: Option<SynthesisOption>,
wait_input_timeout: Option<u32>,
base64: Option<bool>,
cache_key: Option<String>,
},
Play {
url: String,
play_id: Option<String>,
auto_hangup: Option<bool>,
wait_input_timeout: Option<u32>,
offset_ms: Option<u32>,
},
Interrupt {
graceful: Option<bool>,
fade_out_ms: Option<u32>,
},
Pause {},
Resume {},
Hangup {
reason: Option<String>,
initiator: Option<String>,
headers: Option<HashMap<String, String>>,
},
Refer {
caller: String,
callee: String,
options: Option<ReferOption>,
},
Mute {
track_id: Option<String>,
},
Unmute {
track_id: Option<String>,
},
History {
speaker: String,
text: String,
},
Custom {
sender: Option<String>,
data: serde_json::Value,
},
}
#[derive(Debug)]
pub struct RoutingState {
round_robin_counters: Arc<Mutex<HashMap<String, usize>>>,
}
impl Default for RoutingState {
fn default() -> Self {
Self::new()
}
}
impl RoutingState {
pub fn new() -> Self {
Self {
round_robin_counters: Arc::new(Mutex::new(HashMap::new())),
}
}
pub fn next_round_robin_index(&self, destination_key: &str, trunk_count: usize) -> usize {
if trunk_count == 0 {
return 0;
}
let mut counters = self.round_robin_counters.lock().unwrap();
let counter = counters
.entry(destination_key.to_string())
.or_insert_with(|| 0);
let r = *counter % trunk_count;
*counter += 1;
return r;
}
}