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 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 Eou {
109 track_id: String,
110 timestamp: u64,
111 completed: bool,
112 interrupt_point: Option<String>,
113 },
114 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>, position: Option<u32>, total_duration: u32, current: u32, },
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}