xref: /webrtc/webrtc/src/api/mod.rs (revision 60ef728a)
1 #[cfg(test)]
2 mod api_test;
3 
4 pub mod interceptor_registry;
5 pub mod media_engine;
6 pub mod setting_engine;
7 
8 use crate::dtls_transport::RTCDtlsTransport;
9 use crate::ice_transport::ice_gatherer::RTCIceGatherOptions;
10 use crate::ice_transport::ice_gatherer::RTCIceGatherer;
11 use crate::ice_transport::RTCIceTransport;
12 use crate::peer_connection::certificate::RTCCertificate;
13 
14 use media_engine::*;
15 use setting_engine::*;
16 
17 use crate::data_channel::data_channel_parameters::DataChannelParameters;
18 use crate::data_channel::RTCDataChannel;
19 use crate::error::{Error, Result};
20 use crate::peer_connection::configuration::RTCConfiguration;
21 use crate::peer_connection::RTCPeerConnection;
22 use crate::rtp_transceiver::rtp_codec::RTPCodecType;
23 use crate::rtp_transceiver::rtp_receiver::RTCRtpReceiver;
24 use crate::rtp_transceiver::rtp_sender::RTCRtpSender;
25 use crate::sctp_transport::RTCSctpTransport;
26 use crate::track::track_local::TrackLocal;
27 use interceptor::{registry::Registry, Interceptor};
28 
29 use rcgen::KeyPair;
30 use std::sync::Arc;
31 use std::time::SystemTime;
32 
33 /// API bundles the global functions of the WebRTC and ORTC API.
34 /// Some of these functions are also exported globally using the
35 /// defaultAPI object. Note that the global version of the API
36 /// may be phased out in the future.
37 pub struct API {
38     pub(crate) setting_engine: Arc<SettingEngine>,
39     pub(crate) media_engine: Arc<MediaEngine>,
40     pub(crate) interceptor_registry: Registry,
41 }
42 
43 impl API {
44     /// new_peer_connection creates a new PeerConnection with the provided configuration against the received API object
new_peer_connection( &self, configuration: RTCConfiguration, ) -> Result<RTCPeerConnection>45     pub async fn new_peer_connection(
46         &self,
47         configuration: RTCConfiguration,
48     ) -> Result<RTCPeerConnection> {
49         RTCPeerConnection::new(self, configuration).await
50     }
51 
52     /// new_ice_gatherer creates a new ice gatherer.
53     /// This constructor is part of the ORTC API. It is not
54     /// meant to be used together with the basic WebRTC API.
new_ice_gatherer(&self, opts: RTCIceGatherOptions) -> Result<RTCIceGatherer>55     pub fn new_ice_gatherer(&self, opts: RTCIceGatherOptions) -> Result<RTCIceGatherer> {
56         let mut validated_servers = vec![];
57         if !opts.ice_servers.is_empty() {
58             for server in &opts.ice_servers {
59                 let url = server.urls()?;
60                 validated_servers.extend(url);
61             }
62         }
63 
64         Ok(RTCIceGatherer::new(
65             validated_servers,
66             opts.ice_gather_policy,
67             Arc::clone(&self.setting_engine),
68         ))
69     }
70 
71     /// new_ice_transport creates a new ice transport.
72     /// This constructor is part of the ORTC API. It is not
73     /// meant to be used together with the basic WebRTC API.
new_ice_transport(&self, gatherer: Arc<RTCIceGatherer>) -> RTCIceTransport74     pub fn new_ice_transport(&self, gatherer: Arc<RTCIceGatherer>) -> RTCIceTransport {
75         RTCIceTransport::new(gatherer)
76     }
77 
78     /// new_dtls_transport creates a new dtls_transport transport.
79     /// This constructor is part of the ORTC API. It is not
80     /// meant to be used together with the basic WebRTC API.
new_dtls_transport( &self, ice_transport: Arc<RTCIceTransport>, mut certificates: Vec<RTCCertificate>, ) -> Result<RTCDtlsTransport>81     pub fn new_dtls_transport(
82         &self,
83         ice_transport: Arc<RTCIceTransport>,
84         mut certificates: Vec<RTCCertificate>,
85     ) -> Result<RTCDtlsTransport> {
86         if !certificates.is_empty() {
87             let now = SystemTime::now();
88             for cert in &certificates {
89                 cert.expires
90                     .duration_since(now)
91                     .map_err(|_| Error::ErrCertificateExpired)?;
92             }
93         } else {
94             let kp = KeyPair::generate(&rcgen::PKCS_ECDSA_P256_SHA256)?;
95             let cert = RTCCertificate::from_key_pair(kp)?;
96             certificates = vec![cert];
97         };
98 
99         Ok(RTCDtlsTransport::new(
100             ice_transport,
101             certificates,
102             Arc::clone(&self.setting_engine),
103         ))
104     }
105 
106     /// new_sctp_transport creates a new SCTPTransport.
107     /// This constructor is part of the ORTC API. It is not
108     /// meant to be used together with the basic WebRTC API.
new_sctp_transport( &self, dtls_transport: Arc<RTCDtlsTransport>, ) -> Result<RTCSctpTransport>109     pub fn new_sctp_transport(
110         &self,
111         dtls_transport: Arc<RTCDtlsTransport>,
112     ) -> Result<RTCSctpTransport> {
113         Ok(RTCSctpTransport::new(
114             dtls_transport,
115             Arc::clone(&self.setting_engine),
116         ))
117     }
118 
119     /// new_data_channel creates a new DataChannel.
120     /// This constructor is part of the ORTC API. It is not
121     /// meant to be used together with the basic WebRTC API.
new_data_channel( &self, sctp_transport: Arc<RTCSctpTransport>, params: DataChannelParameters, ) -> Result<RTCDataChannel>122     pub async fn new_data_channel(
123         &self,
124         sctp_transport: Arc<RTCSctpTransport>,
125         params: DataChannelParameters,
126     ) -> Result<RTCDataChannel> {
127         // https://w3c.github.io/webrtc-pc/#peer-to-peer-data-api (Step #5)
128         if params.label.len() > 65535 {
129             return Err(Error::ErrStringSizeLimit);
130         }
131 
132         let d = RTCDataChannel::new(params, Arc::clone(&self.setting_engine));
133         d.open(sctp_transport).await?;
134 
135         Ok(d)
136     }
137 
138     /// new_rtp_receiver constructs a new RTPReceiver
new_rtp_receiver( &self, kind: RTPCodecType, transport: Arc<RTCDtlsTransport>, interceptor: Arc<dyn Interceptor + Send + Sync>, ) -> RTCRtpReceiver139     pub fn new_rtp_receiver(
140         &self,
141         kind: RTPCodecType,
142         transport: Arc<RTCDtlsTransport>,
143         interceptor: Arc<dyn Interceptor + Send + Sync>,
144     ) -> RTCRtpReceiver {
145         RTCRtpReceiver::new(
146             self.setting_engine.get_receive_mtu(),
147             kind,
148             transport,
149             Arc::clone(&self.media_engine),
150             interceptor,
151         )
152     }
153 
154     /// new_rtp_sender constructs a new RTPSender
new_rtp_sender( &self, track: Option<Arc<dyn TrackLocal + Send + Sync>>, transport: Arc<RTCDtlsTransport>, interceptor: Arc<dyn Interceptor + Send + Sync>, ) -> RTCRtpSender155     pub async fn new_rtp_sender(
156         &self,
157         track: Option<Arc<dyn TrackLocal + Send + Sync>>,
158         transport: Arc<RTCDtlsTransport>,
159         interceptor: Arc<dyn Interceptor + Send + Sync>,
160     ) -> RTCRtpSender {
161         RTCRtpSender::new(
162             self.setting_engine.get_receive_mtu(),
163             track,
164             transport,
165             Arc::clone(&self.media_engine),
166             interceptor,
167             false,
168         )
169         .await
170     }
171 
172     /// Returns the internal [`SettingEngine`].
setting_engine(&self) -> Arc<SettingEngine>173     pub fn setting_engine(&self) -> Arc<SettingEngine> {
174         Arc::clone(&self.setting_engine)
175     }
176 
177     /// Returns the internal [`MediaEngine`].
media_engine(&self) -> Arc<MediaEngine>178     pub fn media_engine(&self) -> Arc<MediaEngine> {
179         Arc::clone(&self.media_engine)
180     }
181 }
182 
183 #[derive(Default)]
184 pub struct APIBuilder {
185     setting_engine: Option<Arc<SettingEngine>>,
186     media_engine: Option<Arc<MediaEngine>>,
187     interceptor_registry: Option<Registry>,
188 }
189 
190 impl APIBuilder {
new() -> Self191     pub fn new() -> Self {
192         APIBuilder::default()
193     }
194 
build(mut self) -> API195     pub fn build(mut self) -> API {
196         API {
197             setting_engine: if let Some(setting_engine) = self.setting_engine.take() {
198                 setting_engine
199             } else {
200                 Arc::new(SettingEngine::default())
201             },
202             media_engine: if let Some(media_engine) = self.media_engine.take() {
203                 media_engine
204             } else {
205                 Arc::new(MediaEngine::default())
206             },
207             interceptor_registry: if let Some(interceptor_registry) =
208                 self.interceptor_registry.take()
209             {
210                 interceptor_registry
211             } else {
212                 Registry::new()
213             },
214         }
215     }
216 
217     /// WithSettingEngine allows providing a SettingEngine to the API.
218     /// Settings should not be changed after passing the engine to an API.
with_setting_engine(mut self, setting_engine: SettingEngine) -> Self219     pub fn with_setting_engine(mut self, setting_engine: SettingEngine) -> Self {
220         self.setting_engine = Some(Arc::new(setting_engine));
221         self
222     }
223 
224     /// WithMediaEngine allows providing a MediaEngine to the API.
225     /// Settings can be changed after passing the engine to an API.
with_media_engine(mut self, media_engine: MediaEngine) -> Self226     pub fn with_media_engine(mut self, media_engine: MediaEngine) -> Self {
227         self.media_engine = Some(Arc::new(media_engine));
228         self
229     }
230 
231     /// with_interceptor_registry allows providing Interceptors to the API.
232     /// Settings should not be changed after passing the registry to an API.
with_interceptor_registry(mut self, interceptor_registry: Registry) -> Self233     pub fn with_interceptor_registry(mut self, interceptor_registry: Registry) -> Self {
234         self.interceptor_registry = Some(interceptor_registry);
235         self
236     }
237 }
238