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