active_call/
event.rs

1use crate::media::PcmBuf;
2use serde::{Deserialize, Serialize};
3use serde_with::skip_serializing_none;
4use std::collections::HashMap;
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    Transcription {
83        track_id: String,
84        text: String,
85        is_final: bool,
86        timestamp: u64,
87        extra: Option<serde_json::Value>,
88    },
89    Interrupt {
90        receiver: Option<String>,
91    },
92    FunctionCall {
93        track_id: String,
94        call_id: String,
95        name: String,
96        arguments: String,
97        timestamp: u64,
98    },
99    Speaking {
100        track_id: String,
101        timestamp: u64,
102        start_time: u64,
103        is_filler: Option<bool>,
104        confidence: Option<f32>,
105    },
106    Silence {
107        track_id: String,
108        timestamp: u64,
109        start_time: u64,
110        duration: u64,
111        #[serde(skip)]
112        samples: Option<PcmBuf>,
113    },
114    ///End of Utterance
115    Eou {
116        track_id: String,
117        timestamp: u64,
118        completed: bool,
119    },
120    ///Inactivity timeout
121    Inactivity {
122        track_id: String,
123        timestamp: u64,
124    },
125    Dtmf {
126        track_id: String,
127        timestamp: u64,
128        digit: String,
129    },
130    TrackStart {
131        track_id: String,
132        timestamp: u64,
133        play_id: Option<String>,
134    },
135    TrackEnd {
136        track_id: String,
137        timestamp: u64,
138        duration: u64,
139        ssrc: u32,
140        play_id: Option<String>,
141    },
142    Interruption {
143        track_id: String,
144        timestamp: u64,
145        play_id: Option<String>,
146        subtitle: Option<String>, // current tts text
147        position: Option<u32>,    // word index in subtitle
148        total_duration: u32,      // whole tts duration
149        current: u32,             // elapsed time since start of tts
150    },
151    AsrFinal {
152        track_id: String,
153        timestamp: u64,
154        index: u32,
155        start_time: Option<u64>,
156        end_time: Option<u64>,
157        text: String,
158        is_filler: Option<bool>,
159        confidence: Option<f32>,
160    },
161    AsrDelta {
162        track_id: String,
163        index: u32,
164        timestamp: u64,
165        start_time: Option<u64>,
166        end_time: Option<u64>,
167        text: String,
168        is_filler: Option<bool>,
169        confidence: Option<f32>,
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
207pub type EventSender = tokio::sync::broadcast::Sender<SessionEvent>;
208pub type EventReceiver = tokio::sync::broadcast::Receiver<SessionEvent>;
209
210pub fn create_event_sender() -> EventSender {
211    EventSender::new(128)
212}