use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
#[derive(Default)]
pub enum SessionState {
#[default]
Initializing,
Ringing,
EarlyMedia,
Active,
Held,
Transferring,
AppRunning,
Ending,
Ended,
}
impl From<crate::proxy::proxy_call::state::ProxyCallPhase> for SessionState {
fn from(phase: crate::proxy::proxy_call::state::ProxyCallPhase) -> Self {
use crate::proxy::proxy_call::state::ProxyCallPhase;
match phase {
ProxyCallPhase::Initializing => SessionState::Initializing,
ProxyCallPhase::Ringing => SessionState::Ringing,
ProxyCallPhase::EarlyMedia => SessionState::EarlyMedia,
ProxyCallPhase::Bridged => SessionState::Active,
ProxyCallPhase::Terminating => SessionState::Ending,
ProxyCallPhase::Failed => SessionState::Ended,
ProxyCallPhase::Ended => SessionState::Ended,
}
}
}
impl std::fmt::Display for SessionState {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
SessionState::Initializing => write!(f, "initializing"),
SessionState::Ringing => write!(f, "ringing"),
SessionState::EarlyMedia => write!(f, "early_media"),
SessionState::Active => write!(f, "active"),
SessionState::Held => write!(f, "held"),
SessionState::Transferring => write!(f, "transferring"),
SessionState::AppRunning => write!(f, "app_running"),
SessionState::Ending => write!(f, "ending"),
SessionState::Ended => write!(f, "ended"),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
#[derive(Default)]
pub enum MediaPathMode {
#[default]
Anchored,
Bypass,
Adaptive,
}
impl std::fmt::Display for MediaPathMode {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
MediaPathMode::Anchored => write!(f, "anchored"),
MediaPathMode::Bypass => write!(f, "bypass"),
MediaPathMode::Adaptive => write!(f, "adaptive"),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum MediaCapability {
Full,
Limited,
SignalingOnly,
}
impl MediaCapability {
pub fn from_media_path(mode: MediaPathMode) -> Self {
match mode {
MediaPathMode::Anchored => MediaCapability::Full,
MediaPathMode::Bypass => MediaCapability::SignalingOnly,
MediaPathMode::Adaptive => MediaCapability::Limited, }
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MediaRuntimeProfile {
pub path: MediaPathMode,
pub capability: MediaCapability,
pub supports_local_ringback: bool,
pub supports_recording: bool,
pub supports_supervisor_media: bool,
pub supports_media_injection: bool,
}
impl Default for MediaRuntimeProfile {
fn default() -> Self {
Self::from_media_path(MediaPathMode::Anchored)
}
}
impl MediaRuntimeProfile {
pub fn from_media_path(path: MediaPathMode) -> Self {
let capability = MediaCapability::from_media_path(path);
let full = capability == MediaCapability::Full;
Self {
path,
capability,
supports_local_ringback: full,
supports_recording: full,
supports_supervisor_media: full,
supports_media_injection: full,
}
}
pub fn can_play(&self) -> bool {
self.supports_local_ringback || self.capability != MediaCapability::SignalingOnly
}
pub fn can_record(&self) -> bool {
self.supports_recording
}
pub fn can_supervise(&self) -> bool {
self.supports_supervisor_media
}
pub fn can_inject(&self) -> bool {
self.supports_media_injection
}
pub fn degraded() -> Self {
Self::from_media_path(MediaPathMode::Bypass)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn media_capability_from_path() {
assert_eq!(
MediaCapability::from_media_path(MediaPathMode::Anchored),
MediaCapability::Full
);
assert_eq!(
MediaCapability::from_media_path(MediaPathMode::Bypass),
MediaCapability::SignalingOnly
);
}
#[test]
fn media_runtime_profile_anchored() {
let profile = MediaRuntimeProfile::from_media_path(MediaPathMode::Anchored);
assert!(profile.can_record());
assert!(profile.can_supervise());
assert!(profile.can_inject());
}
#[test]
fn media_runtime_profile_bypass() {
let profile = MediaRuntimeProfile::from_media_path(MediaPathMode::Bypass);
assert!(!profile.can_record());
assert!(!profile.can_supervise());
assert!(!profile.can_inject());
}
}