Skip to main content

active_call/
event.rs

1use crate::media::PcmBuf;
2use serde::{Deserialize, Serialize};
3use serde_with::skip_serializing_none;
4use std::{collections::HashMap, fmt::Display};
5
6#[derive(Debug, Clone, Serialize, Deserialize)]
7#[serde(tag = "event")]
8#[serde(rename_all = "camelCase")]
9pub struct Attendee {
10    pub username: String,
11    pub realm: String,
12    pub source: String,
13}
14
15impl From<&String> for Attendee {
16    fn from(source: &String) -> Self {
17        let uri = rsip::Uri::try_from(source.as_str()).unwrap_or_default();
18        Self {
19            username: uri.user().unwrap_or_default().to_string(),
20            realm: uri.host().to_string(),
21            source: source.to_string(),
22        }
23    }
24}
25
26#[skip_serializing_none]
27#[derive(Debug, Clone, Serialize, Deserialize)]
28#[serde(
29    tag = "event",
30    rename_all = "camelCase",
31    rename_all_fields = "camelCase"
32)]
33pub enum SessionEvent {
34    Incoming {
35        track_id: String,
36        timestamp: u64,
37        caller: String,
38        callee: String,
39        sdp: String,
40    },
41    Answer {
42        track_id: String,
43        timestamp: u64,
44        sdp: String,
45        refer: Option<bool>,
46    },
47    Reject {
48        track_id: String,
49        timestamp: u64,
50        reason: String,
51        refer: Option<bool>,
52        code: Option<u32>,
53    },
54    Ringing {
55        track_id: String,
56        timestamp: u64,
57        early_media: bool,
58        refer: Option<bool>,
59    },
60    Hangup {
61        track_id: String,
62        timestamp: u64,
63        reason: Option<String>,
64        initiator: Option<String>,
65        start_time: String,
66        hangup_time: String,
67        answer_time: Option<String>,
68        ringing_time: Option<String>,
69        from: Option<Attendee>,
70        to: Option<Attendee>,
71        extra: Option<HashMap<String, serde_json::Value>>,
72        refer: Option<bool>,
73    },
74    AnswerMachineDetection {
75        // Answer machine detection
76        track_id: String,
77        timestamp: u64,
78        start_time: u64,
79        end_time: u64,
80        text: String,
81    },
82    Interrupt {
83        receiver: Option<String>,
84    },
85    FunctionCall {
86        track_id: String,
87        call_id: String,
88        name: String,
89        arguments: String,
90        timestamp: u64,
91    },
92    Speaking {
93        track_id: String,
94        timestamp: u64,
95        start_time: u64,
96        is_filler: Option<bool>,
97        confidence: Option<f32>,
98    },
99    Silence {
100        track_id: String,
101        timestamp: u64,
102        start_time: u64,
103        duration: u64,
104        #[serde(skip)]
105        samples: Option<PcmBuf>,
106    },
107    ///End of Utterance
108    Eou {
109        track_id: String,
110        timestamp: u64,
111        completed: bool,
112        interrupt_point: Option<String>,
113    },
114    ///Inactivity timeout
115    Inactivity {
116        track_id: String,
117        timestamp: u64,
118    },
119    Dtmf {
120        track_id: String,
121        timestamp: u64,
122        digit: String,
123    },
124    TrackStart {
125        track_id: String,
126        timestamp: u64,
127        play_id: Option<String>,
128    },
129    TrackEnd {
130        track_id: String,
131        timestamp: u64,
132        duration: u64,
133        ssrc: u32,
134        play_id: Option<String>,
135    },
136    Interruption {
137        track_id: String,
138        timestamp: u64,
139        play_id: Option<String>,
140        subtitle: Option<String>, // current tts text
141        position: Option<u32>,    // word index in subtitle
142        total_duration: u32,      // whole tts duration
143        current: u32,             // elapsed time since start of tts
144    },
145    AsrFinal {
146        track_id: String,
147        timestamp: u64,
148        index: u32,
149        start_time: Option<u64>,
150        end_time: Option<u64>,
151        text: String,
152        is_filler: Option<bool>,
153        confidence: Option<f32>,
154        task_id: Option<String>,
155    },
156    AsrDelta {
157        track_id: String,
158        index: u32,
159        timestamp: u64,
160        start_time: Option<u64>,
161        end_time: Option<u64>,
162        text: String,
163        is_filler: Option<bool>,
164        confidence: Option<f32>,
165        task_id: Option<String>,
166    },
167    Metrics {
168        timestamp: u64,
169        key: String,
170        duration: u32,
171        data: serde_json::Value,
172    },
173    Error {
174        track_id: String,
175        timestamp: u64,
176        sender: String,
177        error: String,
178        code: Option<u32>,
179    },
180    AddHistory {
181        sender: Option<String>,
182        timestamp: u64,
183        speaker: String,
184        text: String,
185    },
186    Other {
187        track_id: String,
188        timestamp: u64,
189        sender: String,
190        extra: Option<HashMap<String, String>>,
191    },
192    Binary {
193        track_id: String,
194        timestamp: u64,
195        data: Vec<u8>,
196    },
197    Ping {
198        timestamp: u64,
199        payload: Option<String>,
200    },
201}
202
203impl Display for SessionEvent {
204    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
205        match self {
206            SessionEvent::Silence {
207                track_id, duration, ..
208            } => {
209                write!(f, "Silence(track_id={}, duration={})", track_id, duration)
210            }
211            SessionEvent::Binary { track_id, data, .. } => {
212                write!(f, "Silence(track_id={}, data_len={})", track_id, data.len())
213            }
214            _ => {
215                write!(f, "{:?}", self)
216            }
217        }
218    }
219}
220
221pub type EventSender = tokio::sync::broadcast::Sender<SessionEvent>;
222pub type EventReceiver = tokio::sync::broadcast::Receiver<SessionEvent>;
223
224pub fn create_event_sender() -> EventSender {
225    EventSender::new(128)
226}