1use crate::media::depacketizer::{DefaultDepacketizerFactory, DepacketizerFactory};
2use crate::peer_connection::{RtpReceiverInterceptor, RtpSenderInterceptor};
3use serde::{Deserialize, Serialize};
4use std::fmt::{Debug, Formatter};
5use std::sync::Arc;
6
7#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Default)]
9#[serde(rename_all = "lowercase")]
10pub enum IceCredentialType {
11 #[default]
12 Password,
13 Oauth,
14}
15
16#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
18pub struct IceServer {
19 pub urls: Vec<String>,
20 pub username: Option<String>,
21 pub credential: Option<String>,
22 #[serde(default)]
23 pub credential_type: IceCredentialType,
24}
25
26impl IceServer {
27 pub fn new<T: Into<Vec<String>>>(urls: T) -> Self {
28 Self {
29 urls: urls.into(),
30 username: None,
31 credential: None,
32 credential_type: IceCredentialType::default(),
33 }
34 }
35
36 pub fn with_credential(
37 mut self,
38 username: impl Into<String>,
39 credential: impl Into<String>,
40 ) -> Self {
41 self.username = Some(username.into());
42 self.credential = Some(credential.into());
43 self
44 }
45
46 pub fn credential_type(mut self, kind: IceCredentialType) -> Self {
47 self.credential_type = kind;
48 self
49 }
50}
51
52impl Default for IceServer {
53 fn default() -> Self {
54 Self::new(Vec::new())
55 }
56}
57
58#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Default)]
59pub enum IceTransportPolicy {
60 #[default]
61 All,
62 Relay,
63}
64
65#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Default)]
67pub enum IceTcpPolicy {
68 #[default]
70 Disabled,
71 Enabled,
73 PassiveOnly,
75}
76
77#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Default)]
78pub enum BundlePolicy {
79 #[default]
80 Balanced,
81 MaxCompat,
82 MaxBundle,
83}
84
85#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Default)]
86pub enum RtcpMuxPolicy {
87 #[default]
88 Require,
89 Negotiate,
90}
91
92#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Default)]
93pub enum TransportMode {
94 #[default]
95 WebRtc,
96 Srtp,
97 Rtp,
98}
99
100#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Default)]
102pub enum BufferDropStrategy {
103 #[default]
104 DropNew,
105 DropOldest,
106}
107
108#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Default)]
110pub struct CertificateConfig {
111 pub pem_chain: Vec<String>,
112 pub private_key_pem: Option<String>,
113}
114
115#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
117pub struct AudioCapability {
118 pub payload_type: u8,
119 pub codec_name: String,
120 pub clock_rate: u32,
121 pub channels: u8,
122 pub fmtp: Option<String>,
123 pub rtcp_fbs: Vec<String>,
124}
125
126impl Default for AudioCapability {
127 fn default() -> Self {
128 Self {
129 payload_type: 111,
130 codec_name: "opus".to_string(),
131 clock_rate: 48000,
132 channels: 2,
133 fmtp: Some("minptime=10;useinbandfec=1;stereo=1".to_string()),
134 rtcp_fbs: vec![],
135 }
136 }
137}
138
139impl AudioCapability {
140 pub fn opus() -> Self {
141 Self::default()
142 }
143
144 pub fn pcmu() -> Self {
145 Self {
146 payload_type: 0,
147 codec_name: "PCMU".to_string(),
148 clock_rate: 8000,
149 channels: 1,
150 fmtp: None,
151 rtcp_fbs: vec![],
152 }
153 }
154
155 pub fn pcma() -> Self {
156 Self {
157 payload_type: 8,
158 codec_name: "PCMA".to_string(),
159 clock_rate: 8000,
160 channels: 1,
161 fmtp: None,
162 rtcp_fbs: vec![],
163 }
164 }
165
166 pub fn g722() -> Self {
167 Self {
168 payload_type: 9,
169 codec_name: "G722".to_string(),
170 clock_rate: 8000,
171 channels: 1,
172 fmtp: None,
173 rtcp_fbs: vec![],
174 }
175 }
176
177 pub fn g729() -> Self {
178 Self {
179 payload_type: 18,
180 codec_name: "G729".to_string(),
181 clock_rate: 8000,
182 channels: 1,
183 fmtp: None,
184 rtcp_fbs: vec![],
185 }
186 }
187
188 pub fn telephone_event() -> Self {
189 Self {
190 payload_type: 101,
191 codec_name: "telephone-event".to_string(),
192 clock_rate: 8000,
193 channels: 1,
194 fmtp: Some("0-16".to_string()),
195 rtcp_fbs: vec![],
196 }
197 }
198}
199
200#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
201pub struct VideoCapability {
202 pub payload_type: u8,
203 pub codec_name: String,
204 pub clock_rate: u32,
205 pub fmtp: Option<String>,
206 pub rtcp_fbs: Vec<String>,
207 #[serde(default, skip_serializing_if = "Option::is_none")]
211 pub rtx_payload_type: Option<u8>,
212}
213
214impl Default for VideoCapability {
215 fn default() -> Self {
216 Self {
217 payload_type: 96,
218 codec_name: "VP8".to_string(),
219 clock_rate: 90000,
220 fmtp: None,
221 rtcp_fbs: vec![
222 "nack".to_string(),
223 "nack pli".to_string(),
224 "ccm fir".to_string(),
225 "goog-remb".to_string(),
226 "transport-cc".to_string(),
227 ],
228 rtx_payload_type: None,
229 }
230 }
231}
232
233impl VideoCapability {
234 pub fn h264() -> Self {
235 Self {
236 payload_type: 96,
237 codec_name: "H264".to_string(),
238 clock_rate: 90000,
239 fmtp: Some("packetization-mode=1;profile-level-id=42e01f".to_string()),
240 rtcp_fbs: vec!["nack pli".to_string(), "ccm fir".to_string()],
241 rtx_payload_type: None,
242 }
243 }
244
245 pub fn vp8_with_rtx(rtx_payload_type: u8) -> Self {
247 Self {
248 rtx_payload_type: Some(rtx_payload_type),
249 ..Self::default()
250 }
251 }
252}
253
254#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
255pub struct ApplicationCapability {
256 pub sctp_port: u16,
257}
258
259impl Default for ApplicationCapability {
260 fn default() -> Self {
261 Self { sctp_port: 5000 }
262 }
263}
264
265#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Default)]
266pub enum T38FaxRateManagement {
267 #[serde(rename = "transferredTCF")]
268 #[default]
269 TransferredTCF,
270 #[serde(rename = "localTCF")]
271 LocalTCF,
272}
273
274impl std::fmt::Display for T38FaxRateManagement {
275 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
276 match self {
277 Self::TransferredTCF => write!(f, "transferredTCF"),
278 Self::LocalTCF => write!(f, "localTCF"),
279 }
280 }
281}
282
283#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Default)]
284pub enum T38UdpEC {
285 #[serde(rename = "t38UDPRedundancy")]
286 #[default]
287 T38UDPRedundancy,
288 #[serde(rename = "t38UDPFEC")]
289 T38UDPFEC,
290}
291
292impl std::fmt::Display for T38UdpEC {
293 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
294 match self {
295 Self::T38UDPRedundancy => write!(f, "t38UDPRedundancy"),
296 Self::T38UDPFEC => write!(f, "t38UDPFEC"),
297 }
298 }
299}
300
301#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
302pub struct T38Capability {
303 pub payload_type: u8,
304 pub version: u8,
306 pub max_bitrate: u32,
308 pub rate_management: T38FaxRateManagement,
310 pub max_buffer: u16,
312 pub max_datagram: u16,
314 pub udp_ec: T38UdpEC,
316 pub fmtp: Option<String>,
317}
318
319impl Default for T38Capability {
320 fn default() -> Self {
321 Self {
322 payload_type: 98,
323 version: 0,
324 max_bitrate: 14400,
325 rate_management: T38FaxRateManagement::default(),
326 max_buffer: 1024,
327 max_datagram: 238,
328 udp_ec: T38UdpEC::default(),
329 fmtp: None,
330 }
331 }
332}
333
334impl T38Capability {
335 pub fn default_t38() -> Self {
336 Self::default()
337 }
338}
339
340#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
341pub struct MediaCapabilities {
342 pub audio: Vec<AudioCapability>,
343 pub video: Vec<VideoCapability>,
344 pub application: Option<ApplicationCapability>,
345 pub image: Vec<T38Capability>,
346}
347
348impl Default for MediaCapabilities {
349 fn default() -> Self {
350 Self {
351 audio: vec![AudioCapability::opus(), AudioCapability::pcmu()],
352 video: vec![VideoCapability::default()],
353 application: Some(ApplicationCapability::default()),
354 image: vec![],
355 }
356 }
357}
358
359#[derive(Clone)]
360pub struct DepacketizerStrategy {
361 pub factory: Arc<dyn DepacketizerFactory>,
362}
363
364impl Default for DepacketizerStrategy {
365 fn default() -> Self {
366 Self {
367 factory: Arc::new(DefaultDepacketizerFactory),
368 }
369 }
370}
371
372impl Debug for DepacketizerStrategy {
373 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
374 self.factory.fmt(f)
375 }
376}
377
378impl PartialEq for DepacketizerStrategy {
379 fn eq(&self, other: &Self) -> bool {
380 Arc::ptr_eq(&self.factory, &other.factory)
381 }
382}
383
384impl Eq for DepacketizerStrategy {}
385
386fn default_rtp_buffer_capacity() -> usize {
387 100
388}
389
390fn default_buffer_stats_log_interval() -> std::time::Duration {
391 std::time::Duration::from_secs(10)
392}
393
394#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Default)]
396#[serde(rename_all = "snake_case")]
397pub enum SdpCompatibilityMode {
398 #[default]
400 Standard,
401 LegacySip,
404}
405
406fn default_enable_upnp() -> bool {
407 false
408}
409
410fn default_upnp_lease_duration() -> u32 {
411 3600
412}
413
414#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
416pub struct RtcConfiguration {
417 pub ice_servers: Vec<IceServer>,
418 pub ice_transport_policy: IceTransportPolicy,
419 pub bundle_policy: BundlePolicy,
420 pub rtcp_mux_policy: RtcpMuxPolicy,
421 pub certificates: Vec<CertificateConfig>,
422 pub transport_mode: TransportMode,
423 pub nack_buffer_size: usize,
424 pub media_capabilities: Option<MediaCapabilities>,
425 pub external_ip: Option<String>,
430 pub external_port: Option<u16>,
442 pub bind_ip: Option<String>,
443 pub disable_ipv6: bool,
444 pub ssrc_start: u32,
445 pub stun_timeout: std::time::Duration,
446 pub nomination_timeout: std::time::Duration,
450 pub ice_connection_timeout: std::time::Duration,
451 pub sctp_rto_initial: std::time::Duration,
452 pub sctp_rto_min: std::time::Duration,
453 pub sctp_rto_max: std::time::Duration,
454 pub sctp_max_association_retransmits: u32,
455 pub sctp_receive_window: usize,
456 pub sctp_heartbeat_interval: std::time::Duration,
457 pub sctp_max_heartbeat_failures: u32,
458 pub sctp_max_tsn_retransmits: u32,
459 pub sctp_max_burst: usize,
460 pub sctp_max_cwnd: usize,
461 pub dtls_buffer_size: usize,
462 pub rtp_start_port: Option<u16>,
463 pub rtp_end_port: Option<u16>,
464 pub ice_gather_udp_hosts: bool,
465 pub tcp_port_range_start: Option<u16>,
466 pub tcp_port_range_end: Option<u16>,
467 pub enable_latching: bool,
468 pub probation_max_packets: Option<u8>,
469 pub enable_ice_lite: bool,
470 #[serde(default)]
477 pub prefer_srflx_over_natted_host: bool,
478 #[serde(default = "default_enable_upnp")]
480 pub enable_upnp: bool,
481 #[serde(default = "default_upnp_lease_duration")]
483 pub upnp_lease_duration: u32,
484 #[serde(skip, default)]
485 pub depacketizer_strategy: DepacketizerStrategy,
486 #[serde(default = "default_rtp_buffer_capacity")]
487 pub rtp_buffer_capacity: usize,
488 #[serde(default)]
489 pub buffer_drop_strategy: BufferDropStrategy,
490 #[serde(default = "default_buffer_stats_log_interval")]
491 pub buffer_stats_log_interval: std::time::Duration,
492 #[serde(default)]
495 pub ice_tcp_policy: IceTcpPolicy,
496 #[serde(default)]
506 pub ice_udp_mux: bool,
507 #[serde(default)]
510 pub ice_udp_mux_port: Option<u16>,
511 #[serde(default)]
513 pub sdp_compatibility: SdpCompatibilityMode,
514 #[serde(skip, default)]
515 pub label: Option<String>,
516 #[serde(skip, default)]
517 pub cname: Option<String>,
518 #[serde(skip, default)]
523 pub recorder_interceptors: RecorderInterceptors,
524}
525
526impl Default for RtcConfiguration {
527 fn default() -> Self {
528 Self {
529 ice_servers: Vec::new(),
530 ice_transport_policy: IceTransportPolicy::default(),
531 bundle_policy: BundlePolicy::default(),
532 rtcp_mux_policy: RtcpMuxPolicy::default(),
533 certificates: Vec::new(),
534 transport_mode: TransportMode::default(),
535 nack_buffer_size: 200,
536 media_capabilities: None,
537 external_ip: None,
538 external_port: None,
539 bind_ip: None,
540 disable_ipv6: false,
541 ssrc_start: 10000,
542 stun_timeout: std::time::Duration::from_secs(5),
543 nomination_timeout: std::time::Duration::from_secs(10),
544 ice_connection_timeout: std::time::Duration::from_secs(30),
545 sctp_rto_initial: std::time::Duration::from_secs(3),
546 sctp_rto_min: std::time::Duration::from_secs(1),
547 sctp_rto_max: std::time::Duration::from_secs(60),
548 sctp_max_association_retransmits: 20,
549 sctp_receive_window: 128 * 1024, sctp_heartbeat_interval: std::time::Duration::from_secs(15),
551 sctp_max_heartbeat_failures: 4,
552 sctp_max_tsn_retransmits: 8,
553 sctp_max_burst: 0, sctp_max_cwnd: 256 * 1024, dtls_buffer_size: 2048,
556 rtp_start_port: None,
557 rtp_end_port: None,
558 ice_gather_udp_hosts: true,
559 tcp_port_range_start: None,
560 tcp_port_range_end: None,
561 enable_latching: false,
562 probation_max_packets: None,
563 enable_ice_lite: false,
564 prefer_srflx_over_natted_host: false,
565 enable_upnp: default_enable_upnp(),
566 upnp_lease_duration: default_upnp_lease_duration(),
567 depacketizer_strategy: DepacketizerStrategy::default(),
568 rtp_buffer_capacity: default_rtp_buffer_capacity(),
569 buffer_drop_strategy: BufferDropStrategy::default(),
570 buffer_stats_log_interval: default_buffer_stats_log_interval(),
571 ice_tcp_policy: IceTcpPolicy::default(),
572 ice_udp_mux: false,
573 ice_udp_mux_port: None,
574 sdp_compatibility: SdpCompatibilityMode::default(),
575 label: None,
576 cname: None,
577 recorder_interceptors: RecorderInterceptors::default(),
578 }
579 }
580}
581
582pub struct RtcConfigurationBuilder {
583 inner: RtcConfiguration,
584}
585
586impl Default for RtcConfigurationBuilder {
587 fn default() -> Self {
588 Self::new()
589 }
590}
591
592#[derive(Clone, Default)]
596pub struct RecorderInterceptors {
597 pub receivers: Vec<Arc<dyn RtpReceiverInterceptor>>,
598 pub senders: Vec<Arc<dyn RtpSenderInterceptor>>,
599}
600
601impl Debug for RecorderInterceptors {
602 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
603 f.debug_struct("RecorderInterceptors")
604 .field("receivers_len", &self.receivers.len())
605 .field("senders_len", &self.senders.len())
606 .finish()
607 }
608}
609
610impl PartialEq for RecorderInterceptors {
611 fn eq(&self, other: &Self) -> bool {
612 self.receivers.len() == other.receivers.len()
613 && self.senders.len() == other.senders.len()
614 }
615}
616
617impl Eq for RecorderInterceptors {}
618
619impl RtcConfigurationBuilder {
620 pub fn new() -> Self {
621 Self {
622 inner: RtcConfiguration::default(),
623 }
624 }
625
626 pub fn enable_latching(mut self, enable: bool) -> Self {
627 self.inner.enable_latching = enable;
628 self
629 }
630
631 pub fn probation_max_packets(mut self, max: Option<u8>) -> Self {
632 self.inner.probation_max_packets = max;
633 self
634 }
635
636 pub fn enable_ice_lite(mut self, enable: bool) -> Self {
637 self.inner.enable_ice_lite = enable;
638 self
639 }
640
641 pub fn prefer_srflx_over_natted_host(mut self, enable: bool) -> Self {
642 self.inner.prefer_srflx_over_natted_host = enable;
643 self
644 }
645
646 pub fn enable_upnp(mut self, enable: bool) -> Self {
647 self.inner.enable_upnp = enable;
648 self
649 }
650
651 pub fn upnp_lease_duration(mut self, duration_secs: u32) -> Self {
652 self.inner.upnp_lease_duration = duration_secs;
653 self
654 }
655
656 pub fn ice_server(mut self, server: IceServer) -> Self {
657 self.inner.ice_servers.push(server);
658 self
659 }
660
661 pub fn ice_transport_policy(mut self, policy: IceTransportPolicy) -> Self {
662 self.inner.ice_transport_policy = policy;
663 self
664 }
665
666 pub fn bundle_policy(mut self, policy: BundlePolicy) -> Self {
667 self.inner.bundle_policy = policy;
668 self
669 }
670
671 pub fn rtcp_mux_policy(mut self, policy: RtcpMuxPolicy) -> Self {
672 self.inner.rtcp_mux_policy = policy;
673 self
674 }
675
676 pub fn certificate(mut self, cert: CertificateConfig) -> Self {
677 self.inner.certificates.push(cert);
678 self
679 }
680
681 pub fn transport_mode(mut self, mode: TransportMode) -> Self {
682 self.inner.transport_mode = mode;
683 self
684 }
685
686 pub fn media_capabilities(mut self, capabilities: MediaCapabilities) -> Self {
687 self.inner.media_capabilities = Some(capabilities);
688 self
689 }
690
691 pub fn external_ip(mut self, ip: String) -> Self {
692 self.inner.external_ip = Some(ip);
693 self
694 }
695
696 pub fn external_port(mut self, port: u16) -> Self {
697 self.inner.external_port = Some(port);
698 self
699 }
700
701 pub fn bind_ip(mut self, ip: String) -> Self {
702 self.inner.bind_ip = Some(ip);
703 self
704 }
705
706 pub fn disable_ipv6(mut self, disable: bool) -> Self {
707 self.inner.disable_ipv6 = disable;
708 self
709 }
710
711 pub fn ssrc_start(mut self, start: u32) -> Self {
712 self.inner.ssrc_start = start;
713 self
714 }
715
716 pub fn stun_timeout(mut self, timeout: std::time::Duration) -> Self {
717 self.inner.stun_timeout = timeout;
718 self
719 }
720
721 pub fn nomination_timeout(mut self, timeout: std::time::Duration) -> Self {
722 self.inner.nomination_timeout = timeout;
723 self
724 }
725
726 pub fn rtp_port_range(mut self, start: u16, end: u16) -> Self {
727 self.inner.rtp_start_port = Some(start);
728 self.inner.rtp_end_port = Some(end);
729 self
730 }
731
732 pub fn ice_gather_udp_hosts(mut self, enable: bool) -> Self {
733 self.inner.ice_gather_udp_hosts = enable;
734 self
735 }
736
737 pub fn tcp_port_range(mut self, start: u16, end: u16) -> Self {
738 self.inner.tcp_port_range_start = Some(start);
739 self.inner.tcp_port_range_end = Some(end);
740 self
741 }
742
743 pub fn dtls_buffer_size(mut self, size: usize) -> Self {
744 self.inner.dtls_buffer_size = size;
745 self
746 }
747
748 pub fn sctp_rto_initial(mut self, duration: std::time::Duration) -> Self {
749 self.inner.sctp_rto_initial = duration;
750 self
751 }
752
753 pub fn sctp_rto_min(mut self, duration: std::time::Duration) -> Self {
754 self.inner.sctp_rto_min = duration;
755 self
756 }
757
758 pub fn sctp_rto_max(mut self, duration: std::time::Duration) -> Self {
759 self.inner.sctp_rto_max = duration;
760 self
761 }
762
763 pub fn sctp_max_association_retransmits(mut self, count: u32) -> Self {
764 self.inner.sctp_max_association_retransmits = count;
765 self
766 }
767
768 pub fn sctp_receive_window(mut self, size: usize) -> Self {
769 self.inner.sctp_receive_window = size;
770 self
771 }
772
773 pub fn sctp_heartbeat_interval(mut self, duration: std::time::Duration) -> Self {
774 self.inner.sctp_heartbeat_interval = duration;
775 self
776 }
777
778 pub fn sctp_max_heartbeat_failures(mut self, count: u32) -> Self {
779 self.inner.sctp_max_heartbeat_failures = count;
780 self
781 }
782
783 pub fn sctp_max_burst(mut self, packets: usize) -> Self {
788 self.inner.sctp_max_burst = packets;
789 self
790 }
791
792 pub fn sctp_max_cwnd(mut self, size: usize) -> Self {
795 self.inner.sctp_max_cwnd = size;
796 self
797 }
798
799 pub fn ice_connection_timeout(mut self, timeout: std::time::Duration) -> Self {
800 self.inner.ice_connection_timeout = timeout;
801 self
802 }
803
804 pub fn rtp_buffer_capacity(mut self, capacity: usize) -> Self {
805 self.inner.rtp_buffer_capacity = capacity;
806 self
807 }
808
809 pub fn buffer_drop_strategy(mut self, strategy: BufferDropStrategy) -> Self {
810 self.inner.buffer_drop_strategy = strategy;
811 self
812 }
813
814 pub fn buffer_stats_log_interval(mut self, interval: std::time::Duration) -> Self {
815 self.inner.buffer_stats_log_interval = interval;
816 self
817 }
818
819 pub fn ice_tcp_policy(mut self, policy: IceTcpPolicy) -> Self {
820 self.inner.ice_tcp_policy = policy;
821 self
822 }
823
824 pub fn ice_udp_mux(mut self, enable: bool) -> Self {
827 self.inner.ice_udp_mux = enable;
828 self
829 }
830
831 pub fn ice_udp_mux_port(mut self, port: u16) -> Self {
833 self.inner.ice_udp_mux_port = Some(port);
834 self
835 }
836
837 pub fn sdp_compatibility(mut self, mode: SdpCompatibilityMode) -> Self {
838 self.inner.sdp_compatibility = mode;
839 self
840 }
841
842 pub fn cname(mut self, cname: String) -> Self {
843 self.inner.cname = Some(cname);
844 self
845 }
846
847 pub fn receiver_interceptor(
850 mut self,
851 interceptor: Arc<dyn RtpReceiverInterceptor>,
852 ) -> Self {
853 self.inner.recorder_interceptors.receivers.push(interceptor);
854 self
855 }
856
857 pub fn sender_interceptor(
860 mut self,
861 interceptor: Arc<dyn RtpSenderInterceptor>,
862 ) -> Self {
863 self.inner.recorder_interceptors.senders.push(interceptor);
864 self
865 }
866
867 pub fn build(self) -> RtcConfiguration {
868 self.inner
869 }
870}
871
872impl From<RtcConfigurationBuilder> for RtcConfiguration {
873 fn from(builder: RtcConfigurationBuilder) -> Self {
874 builder.build()
875 }
876}
877
878#[cfg(test)]
879mod tests {
880 use super::*;
881 use std::time::Duration;
882
883 #[test]
884 fn test_rtc_configuration_defaults() {
885 let config = RtcConfiguration::default();
886 assert_eq!(config.ice_connection_timeout, Duration::from_secs(30));
887 assert_eq!(config.sctp_rto_initial, Duration::from_secs(3));
888 assert_eq!(config.sctp_rto_min, Duration::from_secs(1));
889 assert_eq!(config.sctp_rto_max, Duration::from_secs(60));
890 assert_eq!(config.sctp_max_association_retransmits, 20);
891 assert_eq!(config.sctp_heartbeat_interval, Duration::from_secs(15));
892 assert_eq!(config.sctp_max_heartbeat_failures, 4);
893 assert_eq!(config.sctp_max_burst, 0);
894 assert_eq!(config.sctp_max_cwnd, 256 * 1024);
895 assert_eq!(config.rtp_buffer_capacity, 100);
896 assert_eq!(config.buffer_drop_strategy, BufferDropStrategy::DropNew);
897 assert_eq!(config.buffer_stats_log_interval, Duration::from_secs(10));
898 }
899
900 #[test]
901 fn test_rtc_configuration_builder() {
902 let config = RtcConfigurationBuilder::new()
903 .stun_timeout(Duration::from_secs(10))
904 .build();
905 assert_eq!(config.stun_timeout, Duration::from_secs(10));
906 assert_eq!(config.ice_connection_timeout, Duration::from_secs(30));
908 }
909
910 #[test]
911 fn test_buffer_config_builder() {
912 let config = RtcConfigurationBuilder::new()
913 .rtp_buffer_capacity(200)
914 .buffer_drop_strategy(BufferDropStrategy::DropOldest)
915 .buffer_stats_log_interval(Duration::from_secs(5))
916 .build();
917 assert_eq!(config.rtp_buffer_capacity, 200);
918 assert_eq!(config.buffer_drop_strategy, BufferDropStrategy::DropOldest);
919 assert_eq!(config.buffer_stats_log_interval, Duration::from_secs(5));
920 }
921
922 #[test]
923 fn test_sctp_builder_methods() {
924 let config = RtcConfigurationBuilder::new()
925 .sctp_rto_initial(Duration::from_millis(500))
926 .sctp_rto_min(Duration::from_millis(200))
927 .sctp_rto_max(Duration::from_secs(10))
928 .sctp_max_association_retransmits(30)
929 .sctp_receive_window(512 * 1024)
930 .sctp_heartbeat_interval(Duration::from_secs(10))
931 .sctp_max_heartbeat_failures(8)
932 .sctp_max_burst(4)
933 .sctp_max_cwnd(512 * 1024)
934 .ice_connection_timeout(Duration::from_secs(60))
935 .build();
936
937 assert_eq!(config.sctp_rto_initial, Duration::from_millis(500));
938 assert_eq!(config.sctp_rto_min, Duration::from_millis(200));
939 assert_eq!(config.sctp_rto_max, Duration::from_secs(10));
940 assert_eq!(config.sctp_max_association_retransmits, 30);
941 assert_eq!(config.sctp_receive_window, 512 * 1024);
942 assert_eq!(config.sctp_heartbeat_interval, Duration::from_secs(10));
943 assert_eq!(config.sctp_max_heartbeat_failures, 8);
944 assert_eq!(config.sctp_max_burst, 4);
945 assert_eq!(config.sctp_max_cwnd, 512 * 1024);
946 assert_eq!(config.ice_connection_timeout, Duration::from_secs(60));
947 }
948
949 #[test]
950 fn test_turn_optimized_config() {
951 let config = RtcConfigurationBuilder::new()
953 .sctp_rto_initial(Duration::from_millis(500))
954 .sctp_rto_min(Duration::from_millis(200))
955 .sctp_rto_max(Duration::from_secs(10))
956 .sctp_max_association_retransmits(30)
957 .sctp_max_heartbeat_failures(8)
958 .sctp_max_burst(4)
959 .stun_timeout(Duration::from_secs(10))
960 .nomination_timeout(Duration::from_secs(20))
961 .build();
962
963 let defaults = RtcConfiguration::default();
965 assert!(config.sctp_rto_initial < defaults.sctp_rto_initial);
966 assert!(config.sctp_rto_min < defaults.sctp_rto_min);
967 assert!(config.sctp_rto_max < defaults.sctp_rto_max);
968 assert!(
969 config.sctp_max_association_retransmits > defaults.sctp_max_association_retransmits
970 );
971 assert!(config.sctp_max_heartbeat_failures > defaults.sctp_max_heartbeat_failures);
972 assert!(config.sctp_max_burst > 0); }
974
975 #[test]
976 fn test_external_port_defaults() {
977 let config = RtcConfiguration::default();
978 assert_eq!(config.external_port, None);
979 }
980
981 #[test]
982 fn test_external_port_builder() {
983 let config = RtcConfigurationBuilder::new().external_port(30000).build();
984 assert_eq!(config.external_port, Some(30000));
985 }
986
987 #[test]
988 fn test_external_port_with_external_ip_builder() {
989 let config = RtcConfigurationBuilder::new()
990 .external_ip("203.0.113.5".to_string())
991 .external_port(30000)
992 .build();
993 assert_eq!(config.external_ip, Some("203.0.113.5".to_string()));
994 assert_eq!(config.external_port, Some(30000));
995 }
996
997 #[test]
998 fn test_upnp_defaults() {
999 let config = RtcConfiguration::default();
1000 assert!(!config.enable_upnp, "UPnP should be disabled by default");
1001 assert_eq!(config.upnp_lease_duration, 3600);
1002 }
1003
1004 #[test]
1005 fn test_upnp_builder_methods() {
1006 let config = RtcConfigurationBuilder::new()
1007 .enable_upnp(false)
1008 .upnp_lease_duration(7200)
1009 .build();
1010 assert!(!config.enable_upnp);
1011 assert_eq!(config.upnp_lease_duration, 7200);
1012 }
1013
1014 #[test]
1015 fn test_upnp_optimized_config() {
1016 let config = RtcConfigurationBuilder::new()
1017 .enable_upnp(true)
1018 .upnp_lease_duration(1800)
1019 .build();
1020
1021 assert!(config.enable_upnp);
1022 assert_eq!(config.upnp_lease_duration, 1800);
1023
1024 let defaults = RtcConfiguration::default();
1026 assert_eq!(
1027 config.ice_connection_timeout,
1028 defaults.ice_connection_timeout
1029 );
1030 }
1031
1032 #[test]
1033 fn test_ice_udp_mux_defaults() {
1034 let config = RtcConfiguration::default();
1035 assert!(
1036 !config.ice_udp_mux,
1037 "ICE UDP mux should be disabled by default"
1038 );
1039 assert_eq!(config.ice_udp_mux_port, None);
1040 }
1041
1042 #[test]
1043 fn test_ice_udp_mux_builder_methods() {
1044 let config = RtcConfigurationBuilder::new()
1045 .ice_udp_mux(true)
1046 .ice_udp_mux_port(30500)
1047 .build();
1048 assert!(config.ice_udp_mux);
1049 assert_eq!(config.ice_udp_mux_port, Some(30500));
1050 }
1051}