voice_engine/
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    Speaking {
83        track_id: String,
84        timestamp: u64,
85        start_time: u64,
86    },
87    Silence {
88        track_id: String,
89        timestamp: u64,
90        start_time: u64,
91        duration: u64,
92        #[serde(skip)]
93        samples: Option<PcmBuf>,
94    },
95    ///End of Utterance
96    Eou {
97        track_id: String,
98        timestamp: u64,
99        completed: bool,
100    },
101    Dtmf {
102        track_id: String,
103        timestamp: u64,
104        digit: String,
105    },
106    TrackStart {
107        track_id: String,
108        timestamp: u64,
109        play_id: Option<String>,
110    },
111    TrackEnd {
112        track_id: String,
113        timestamp: u64,
114        duration: u64,
115        ssrc: u32,
116        play_id: Option<String>,
117    },
118    Interruption {
119        track_id: String,
120        timestamp: u64,
121        play_id: Option<String>,
122        subtitle: Option<String>, // current tts text
123        position: Option<u32>,    // word index in subtitle
124        total_duration: u32,      // whole tts duration
125        current: u32,             // elapsed time since start of tts
126    },
127    AsrFinal {
128        track_id: String,
129        timestamp: u64,
130        index: u32,
131        start_time: Option<u64>,
132        end_time: Option<u64>,
133        text: String,
134    },
135    AsrDelta {
136        track_id: String,
137        index: u32,
138        timestamp: u64,
139        start_time: Option<u64>,
140        end_time: Option<u64>,
141        text: String,
142    },
143    Metrics {
144        timestamp: u64,
145        key: String,
146        duration: u32,
147        data: serde_json::Value,
148    },
149    Error {
150        track_id: String,
151        timestamp: u64,
152        sender: String,
153        error: String,
154        code: Option<u32>,
155    },
156    AddHistory {
157        sender: Option<String>,
158        timestamp: u64,
159        speaker: String,
160        text: String,
161    },
162    Other {
163        track_id: String,
164        timestamp: u64,
165        sender: String,
166        extra: Option<HashMap<String, String>>,
167    },
168    Binary {
169        track_id: String,
170        timestamp: u64,
171        data: Vec<u8>,
172    },
173    Ping {
174        timestamp: u64,
175        payload: Option<String>,
176    },
177}
178
179pub type EventSender = tokio::sync::broadcast::Sender<SessionEvent>;
180pub type EventReceiver = tokio::sync::broadcast::Receiver<SessionEvent>;
181
182pub fn create_event_sender() -> EventSender {
183    EventSender::new(128)
184}