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