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