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 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 Eou {
108 track_id: String,
109 timestamp: u64,
110 completed: bool,
111 interrupt_point: Option<String>,
112 },
113 Inactivity {
115 track_id: String,
116 timestamp: u64,
117 },
118 Dtmf {
119 track_id: String,
120 timestamp: u64,
121 digit: String,
122 },
123 TrackStart {
124 track_id: String,
125 timestamp: u64,
126 play_id: Option<String>,
127 },
128 TrackEnd {
129 track_id: String,
130 timestamp: u64,
131 duration: u64,
132 ssrc: u32,
133 play_id: Option<String>,
134 },
135 Interruption {
136 track_id: String,
137 timestamp: u64,
138 play_id: Option<String>,
139 subtitle: Option<String>, position: Option<u32>, total_duration: u32, current: u32, },
144 AsrFinal {
145 track_id: String,
146 timestamp: u64,
147 index: u32,
148 start_time: Option<u64>,
149 end_time: Option<u64>,
150 text: String,
151 is_filler: Option<bool>,
152 confidence: Option<f32>,
153 task_id: Option<String>,
154 },
155 AsrDelta {
156 track_id: String,
157 index: u32,
158 timestamp: u64,
159 start_time: Option<u64>,
160 end_time: Option<u64>,
161 text: String,
162 is_filler: Option<bool>,
163 confidence: Option<f32>,
164 task_id: Option<String>,
165 },
166 Metrics {
167 timestamp: u64,
168 key: String,
169 duration: u32,
170 data: serde_json::Value,
171 },
172 Error {
173 track_id: String,
174 timestamp: u64,
175 sender: String,
176 error: String,
177 code: Option<u32>,
178 },
179 AddHistory {
180 sender: Option<String>,
181 timestamp: u64,
182 speaker: String,
183 text: String,
184 },
185 Other {
186 track_id: String,
187 timestamp: u64,
188 sender: String,
189 extra: Option<HashMap<String, String>>,
190 },
191 Binary {
192 track_id: String,
193 timestamp: u64,
194 data: Vec<u8>,
195 },
196 Ping {
197 timestamp: u64,
198 payload: Option<String>,
199 },
200}
201
202impl Display for SessionEvent {
203 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
204 match self {
205 SessionEvent::Silence {
206 track_id, duration, ..
207 } => {
208 write!(f, "Silence(track_id={}, duration={})", track_id, duration)
209 }
210 SessionEvent::Binary { track_id, data, .. } => {
211 write!(f, "Silence(track_id={}, data_len={})", track_id, data.len())
212 }
213 _ => {
214 write!(f, "{:?}", self)
215 }
216 }
217 }
218}
219
220pub type EventSender = tokio::sync::broadcast::Sender<SessionEvent>;
221pub type EventReceiver = tokio::sync::broadcast::Receiver<SessionEvent>;
222
223pub fn create_event_sender() -> EventSender {
224 EventSender::new(128)
225}