use std::fmt::{Debug, Formatter};
use serde::{Serialize, Deserialize};
use cal_jambonz::listen::Listen;
use crate::{NumberFormat, VoiceServer, Region, ConnectState, FlowState};
use std::sync::Arc;
use crate::device::device::{Connector, EndpointDevice};
use crate::device::shared::{AiOptions, CallControl, RecordOptions, TranscribeOptions};
#[derive(Serialize, Deserialize, Clone)]
#[serde(rename_all = "camelCase")]
pub struct SipExtension {
pub gateway: String,
#[serde(default = "crate::device::shared::build_present")]
pub present: String,
#[serde(default)]
pub proxies: Vec<String>,
#[serde(default = "crate::device::shared::build_format")]
pub format: NumberFormat,
#[serde(default = "crate::device::shared::build_country_code")]
pub country_code: String,
#[serde(default = "crate::device::shared::build_connect_to")]
pub on_complete: String,
#[serde(default = "crate::device::shared::build_connect_to")]
pub on_busy: String,
#[serde(default = "crate::device::shared::build_connect_to")]
pub on_fail: String,
#[serde(default = "crate::device::shared::build_connect_to")]
pub on_no_answer: String,
#[serde(default = "crate::device::shared::build_ring_time")]
pub ring_time: u8,
#[serde(default = "crate::device::shared::build_call_time")]
pub max_call_time: u16,
#[serde(default)]
pub transcribe_options: TranscribeOptions,
#[serde(default)]
pub record_options: RecordOptions,
#[serde(default)]
pub ai_options: AiOptions,
#[serde(default)]
pub call_control: CallControl,
}
impl Debug for SipExtension {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
f.debug_struct("SipExtension")
.field("gateway", &self.gateway)
.field("present", &self.present)
.field("proxies", &self.proxies)
.field("format", &self.format)
.field("country_code", &self.country_code)
.field("on_complete", &self.on_complete)
.field("on_busy", &self.on_busy)
.field("on_fail", &self.on_fail)
.field("on_no_answer", &self.on_no_answer)
.field("ring_time", &self.ring_time)
.field("max_call_time", &self.max_call_time)
.field("transcribe_options", &self.transcribe_options)
.field("record_options", &self.record_options)
.field("ai_options", &self.ai_options)
.field("call_control", &self.call_control)
.finish()
}
}
impl Connector for SipExtension {
fn get_connect_to(&mut self, state: &mut FlowState) -> ConnectState {
match &state.get_dial_status() {
Some(status) => match status {
cal_jambonz::shared::shared::SIPStatus::Ok => {
ConnectState::complete(self.on_complete.as_str())
}
cal_jambonz::shared::shared::SIPStatus::RequestTerminated => {
ConnectState::no_answer(self.on_no_answer.as_str())
}
cal_jambonz::shared::shared::SIPStatus::BusyHere | cal_jambonz::shared::shared::SIPStatus::BusyEverywhere => {
ConnectState::busy(self.on_busy.as_str())
}
_ => ConnectState::fail(self.on_fail.as_str()),
},
None => ConnectState::dialling(),
}
}
}
impl EndpointDevice for SipExtension {
fn device_type_name(&self) -> &'static str {
"SipExtension"
}
fn supports_routing(&self) -> bool {
true
}
}
impl crate::device::device::Endpoint for SipExtension {
fn get_listen(&self, _state: &FlowState) -> Option<Listen> {
None
}
fn get_proxy(&self, _state: &FlowState, _regions: Vec<Arc<Region>>) -> Option<VoiceServer> {
None
}
}