1use crate::call::{CallManager, CallManagerConfig};
4use crate::identity::PeerIdentity;
5use crate::media::MediaStreamManager;
6use crate::signaling::{SignalingHandler, SignalingTransport};
7use crate::types::{CallEvent, CallId, CallState, MediaConstraints, NativeQuicConfiguration};
8use serde::{Deserialize, Serialize};
9use std::sync::Arc;
10use thiserror::Error;
11use tokio::sync::broadcast;
12
13#[derive(Error, Debug)]
15pub enum ServiceError {
16 #[error("Initialization error: {0}")]
18 InitError(String),
19
20 #[error("Call error: {0}")]
22 CallError(String),
23}
24
25#[derive(Debug, Clone)]
27pub enum WebRtcEvent<I: PeerIdentity> {
28 Signaling(SignalingEvent),
30 Media(crate::media::MediaEvent),
32 Call(CallEvent<I>),
34}
35
36#[derive(Debug, Clone, Serialize, Deserialize)]
38pub enum SignalingEvent {
39 Connected,
41 Disconnected,
43}
44
45#[derive(Debug, Clone)]
47pub struct WebRtcConfig {
48 pub quic_config: NativeQuicConfiguration,
50 pub default_constraints: MediaConstraints,
52 pub call_config: CallManagerConfig,
54}
55
56impl Default for WebRtcConfig {
57 fn default() -> Self {
58 Self {
59 quic_config: NativeQuicConfiguration::default(),
60 default_constraints: MediaConstraints::audio_only(),
61 call_config: CallManagerConfig::default(),
62 }
63 }
64}
65
66pub struct WebRtcService<I: PeerIdentity, T: SignalingTransport> {
68 _signaling: Arc<SignalingHandler<T>>,
69 media: Arc<MediaStreamManager>,
70 call_manager: Arc<CallManager<I>>,
71 event_sender: broadcast::Sender<WebRtcEvent<I>>,
72}
73
74impl<I: PeerIdentity, T: SignalingTransport> WebRtcService<I, T> {
75 pub async fn new(
81 signaling: Arc<SignalingHandler<T>>,
82 config: WebRtcConfig,
83 ) -> Result<Self, ServiceError> {
84 let (event_sender, _) = broadcast::channel(1000);
85
86 let media = Arc::new(MediaStreamManager::new());
87 let call_manager = Arc::new(
88 CallManager::new(config.call_config)
89 .await
90 .map_err(|e| ServiceError::InitError(e.to_string()))?,
91 );
92
93 Ok(Self {
94 _signaling: signaling,
95 media,
96 call_manager,
97 event_sender,
98 })
99 }
100
101 pub async fn start(&self) -> Result<(), ServiceError> {
107 self.media
108 .initialize()
109 .await
110 .map_err(|e| ServiceError::InitError(e.to_string()))?;
111
112 self.call_manager
113 .start()
114 .await
115 .map_err(|e| ServiceError::InitError(e.to_string()))?;
116
117 Ok(())
118 }
119
120 pub async fn initiate_call(
126 &self,
127 callee: I,
128 constraints: MediaConstraints,
129 ) -> Result<CallId, ServiceError> {
130 self.call_manager
131 .initiate_call(callee, constraints)
132 .await
133 .map_err(|e| ServiceError::CallError(e.to_string()))
134 }
135
136 pub async fn accept_call(
142 &self,
143 call_id: CallId,
144 constraints: MediaConstraints,
145 ) -> Result<(), ServiceError> {
146 self.call_manager
147 .accept_call(call_id, constraints)
148 .await
149 .map_err(|e| ServiceError::CallError(e.to_string()))
150 }
151
152 pub async fn reject_call(&self, call_id: CallId) -> Result<(), ServiceError> {
158 self.call_manager
159 .reject_call(call_id)
160 .await
161 .map_err(|e| ServiceError::CallError(e.to_string()))
162 }
163
164 pub async fn end_call(&self, call_id: CallId) -> Result<(), ServiceError> {
170 self.call_manager
171 .end_call(call_id)
172 .await
173 .map_err(|e| ServiceError::CallError(e.to_string()))
174 }
175
176 #[must_use]
178 pub async fn get_call_state(&self, call_id: CallId) -> Option<CallState> {
179 self.call_manager.get_call_state(call_id).await
180 }
181
182 #[must_use]
184 pub fn subscribe_events(&self) -> broadcast::Receiver<WebRtcEvent<I>> {
185 self.event_sender.subscribe()
186 }
187
188 #[must_use]
190 pub fn builder(signaling: Arc<SignalingHandler<T>>) -> WebRtcServiceBuilder<I, T> {
191 WebRtcServiceBuilder::new(signaling)
192 }
193}
194
195pub struct WebRtcServiceBuilder<I: PeerIdentity, T: SignalingTransport> {
197 signaling: Arc<SignalingHandler<T>>,
198 config: WebRtcConfig,
199 _phantom: std::marker::PhantomData<I>,
200}
201
202impl<I: PeerIdentity, T: SignalingTransport> WebRtcServiceBuilder<I, T> {
203 #[must_use]
205 pub fn new(signaling: Arc<SignalingHandler<T>>) -> Self {
206 Self {
207 signaling,
208 config: WebRtcConfig::default(),
209 _phantom: std::marker::PhantomData,
210 }
211 }
212
213 #[must_use]
215 pub fn with_config(mut self, config: WebRtcConfig) -> Self {
216 self.config = config;
217 self
218 }
219
220 pub async fn build(self) -> Result<WebRtcService<I, T>, ServiceError> {
226 WebRtcService::new(self.signaling, self.config).await
227 }
228}