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
414fn default_upnp_discovery_timeout() -> std::time::Duration {
415 std::time::Duration::from_secs(1)
416}
417
418#[derive(Debug, Clone, Serialize, Deserialize)]
420pub struct RtcConfiguration {
421 pub ice_servers: Vec<IceServer>,
422 pub ice_transport_policy: IceTransportPolicy,
423 pub bundle_policy: BundlePolicy,
424 pub rtcp_mux_policy: RtcpMuxPolicy,
425 pub certificates: Vec<CertificateConfig>,
426 pub transport_mode: TransportMode,
427 pub nack_buffer_size: usize,
428 pub media_capabilities: Option<MediaCapabilities>,
429 pub external_ip: Option<String>,
434 pub external_port: Option<u16>,
446 pub bind_ip: Option<String>,
447 pub disable_ipv6: bool,
448 pub ssrc_start: u32,
449 pub stun_timeout: std::time::Duration,
450 pub nomination_timeout: std::time::Duration,
454 pub ice_connection_timeout: std::time::Duration,
455 pub ice_disconnect_threshold: std::time::Duration,
467 pub ice_disconnect_grace: std::time::Duration,
479 pub sctp_rto_initial: std::time::Duration,
480 pub sctp_rto_min: std::time::Duration,
481 pub sctp_rto_max: std::time::Duration,
482 pub sctp_max_association_retransmits: u32,
483 pub sctp_receive_window: usize,
484 pub sctp_heartbeat_interval: std::time::Duration,
485 pub sctp_max_heartbeat_failures: u32,
486 pub sctp_max_tsn_retransmits: u32,
487 pub sctp_max_burst: usize,
488 pub sctp_max_cwnd: usize,
489 pub sctp_max_buffered_amount: usize,
494 pub dtls_buffer_size: usize,
495 pub rtp_start_port: Option<u16>,
496 pub rtp_end_port: Option<u16>,
497 pub ice_gather_udp_hosts: bool,
498 pub tcp_port_range_start: Option<u16>,
499 pub tcp_port_range_end: Option<u16>,
500 pub enable_latching: bool,
501 pub probation_max_packets: Option<u8>,
502 pub enable_ice_lite: bool,
503 #[serde(default)]
510 pub prefer_srflx_over_natted_host: bool,
511 #[serde(default = "default_enable_upnp")]
513 pub enable_upnp: bool,
514 #[serde(default = "default_upnp_lease_duration")]
516 pub upnp_lease_duration: u32,
517 #[serde(default = "default_upnp_discovery_timeout")]
519 pub upnp_discovery_timeout: std::time::Duration,
520 #[serde(skip, default)]
521 pub depacketizer_strategy: DepacketizerStrategy,
522 #[serde(default = "default_rtp_buffer_capacity")]
523 pub rtp_buffer_capacity: usize,
524 #[serde(default)]
525 pub buffer_drop_strategy: BufferDropStrategy,
526 #[serde(default = "default_buffer_stats_log_interval")]
527 pub buffer_stats_log_interval: std::time::Duration,
528 #[serde(default)]
531 pub ice_tcp_policy: IceTcpPolicy,
532 #[serde(default)]
542 pub ice_udp_mux: bool,
543 #[serde(default)]
546 pub ice_udp_mux_port: Option<u16>,
547 #[serde(default)]
549 pub sdp_compatibility: SdpCompatibilityMode,
550 #[serde(skip, default)]
551 pub label: Option<String>,
552 #[serde(skip, default)]
553 pub cname: Option<String>,
554 #[serde(skip, default)]
559 pub runtime_handle: Option<tokio::runtime::Handle>,
560 #[serde(skip, default)]
565 pub recorder_interceptors: RecorderInterceptors,
566}
567
568impl PartialEq for RtcConfiguration {
569 fn eq(&self, other: &Self) -> bool {
570 self.ice_servers == other.ice_servers
572 && self.ice_transport_policy == other.ice_transport_policy
573 && self.bundle_policy == other.bundle_policy
574 && self.rtcp_mux_policy == other.rtcp_mux_policy
575 && self.certificates == other.certificates
576 && self.transport_mode == other.transport_mode
577 && self.nack_buffer_size == other.nack_buffer_size
578 && self.media_capabilities == other.media_capabilities
579 && self.external_ip == other.external_ip
580 && self.external_port == other.external_port
581 && self.bind_ip == other.bind_ip
582 && self.disable_ipv6 == other.disable_ipv6
583 && self.ssrc_start == other.ssrc_start
584 && self.stun_timeout == other.stun_timeout
585 && self.nomination_timeout == other.nomination_timeout
586 && self.ice_connection_timeout == other.ice_connection_timeout
587 && self.ice_disconnect_threshold == other.ice_disconnect_threshold
588 && self.ice_disconnect_grace == other.ice_disconnect_grace
589 && self.sctp_rto_initial == other.sctp_rto_initial
590 && self.sctp_rto_min == other.sctp_rto_min
591 && self.sctp_rto_max == other.sctp_rto_max
592 && self.sctp_max_association_retransmits == other.sctp_max_association_retransmits
593 && self.sctp_receive_window == other.sctp_receive_window
594 && self.sctp_heartbeat_interval == other.sctp_heartbeat_interval
595 && self.sctp_max_heartbeat_failures == other.sctp_max_heartbeat_failures
596 && self.sctp_max_tsn_retransmits == other.sctp_max_tsn_retransmits
597 && self.sctp_max_burst == other.sctp_max_burst
598 && self.sctp_max_cwnd == other.sctp_max_cwnd
599 && self.sctp_max_buffered_amount == other.sctp_max_buffered_amount
600 && self.dtls_buffer_size == other.dtls_buffer_size
601 && self.rtp_start_port == other.rtp_start_port
602 && self.rtp_end_port == other.rtp_end_port
603 && self.ice_gather_udp_hosts == other.ice_gather_udp_hosts
604 && self.tcp_port_range_start == other.tcp_port_range_start
605 && self.tcp_port_range_end == other.tcp_port_range_end
606 && self.enable_latching == other.enable_latching
607 && self.probation_max_packets == other.probation_max_packets
608 && self.enable_ice_lite == other.enable_ice_lite
609 && self.prefer_srflx_over_natted_host == other.prefer_srflx_over_natted_host
610 && self.enable_upnp == other.enable_upnp
611 && self.upnp_lease_duration == other.upnp_lease_duration
612 && self.upnp_discovery_timeout == other.upnp_discovery_timeout
613 && self.depacketizer_strategy == other.depacketizer_strategy
614 && self.rtp_buffer_capacity == other.rtp_buffer_capacity
615 && self.buffer_drop_strategy == other.buffer_drop_strategy
616 && self.buffer_stats_log_interval == other.buffer_stats_log_interval
617 && self.ice_tcp_policy == other.ice_tcp_policy
618 && self.ice_udp_mux == other.ice_udp_mux
619 && self.ice_udp_mux_port == other.ice_udp_mux_port
620 && self.sdp_compatibility == other.sdp_compatibility
621 && self.label == other.label
622 && self.cname == other.cname
623 }
625}
626
627impl Eq for RtcConfiguration {}
628
629impl Default for RtcConfiguration {
630 fn default() -> Self {
631 Self {
632 ice_servers: Vec::new(),
633 ice_transport_policy: IceTransportPolicy::default(),
634 bundle_policy: BundlePolicy::default(),
635 rtcp_mux_policy: RtcpMuxPolicy::default(),
636 certificates: Vec::new(),
637 transport_mode: TransportMode::default(),
638 nack_buffer_size: 200,
639 media_capabilities: None,
640 external_ip: None,
641 external_port: None,
642 bind_ip: None,
643 disable_ipv6: false,
644 ssrc_start: 10000,
645 stun_timeout: std::time::Duration::from_secs(5),
646 nomination_timeout: std::time::Duration::from_secs(10),
647 ice_connection_timeout: std::time::Duration::from_secs(30),
648 ice_disconnect_threshold: std::time::Duration::from_secs(5),
649 ice_disconnect_grace: std::time::Duration::from_secs(15),
650 sctp_rto_initial: std::time::Duration::from_secs(3),
651 sctp_rto_min: std::time::Duration::from_millis(200),
652 sctp_rto_max: std::time::Duration::from_secs(60),
653 sctp_max_association_retransmits: 20,
654 sctp_receive_window: 128 * 1024, sctp_heartbeat_interval: std::time::Duration::from_secs(15),
656 sctp_max_heartbeat_failures: 4,
657 sctp_max_tsn_retransmits: 8,
658 sctp_max_burst: 0, sctp_max_cwnd: 256 * 1024, sctp_max_buffered_amount: 256 * 1024, dtls_buffer_size: 2048,
662 rtp_start_port: None,
663 rtp_end_port: None,
664 ice_gather_udp_hosts: true,
665 tcp_port_range_start: None,
666 tcp_port_range_end: None,
667 enable_latching: false,
668 probation_max_packets: None,
669 enable_ice_lite: false,
670 prefer_srflx_over_natted_host: false,
671 enable_upnp: default_enable_upnp(),
672 upnp_lease_duration: default_upnp_lease_duration(),
673 upnp_discovery_timeout: default_upnp_discovery_timeout(),
674 depacketizer_strategy: DepacketizerStrategy::default(),
675 rtp_buffer_capacity: default_rtp_buffer_capacity(),
676 buffer_drop_strategy: BufferDropStrategy::default(),
677 buffer_stats_log_interval: default_buffer_stats_log_interval(),
678 ice_tcp_policy: IceTcpPolicy::default(),
679 ice_udp_mux: false,
680 ice_udp_mux_port: None,
681 sdp_compatibility: SdpCompatibilityMode::default(),
682 label: None,
683 cname: None,
684 runtime_handle: None,
685 recorder_interceptors: RecorderInterceptors::default(),
686 }
687 }
688}
689
690pub struct RtcConfigurationBuilder {
691 inner: RtcConfiguration,
692}
693
694impl Default for RtcConfigurationBuilder {
695 fn default() -> Self {
696 Self::new()
697 }
698}
699
700#[derive(Clone, Default)]
704pub struct RecorderInterceptors {
705 pub receivers: Vec<Arc<dyn RtpReceiverInterceptor>>,
706 pub senders: Vec<Arc<dyn RtpSenderInterceptor>>,
707}
708
709impl Debug for RecorderInterceptors {
710 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
711 f.debug_struct("RecorderInterceptors")
712 .field("receivers_len", &self.receivers.len())
713 .field("senders_len", &self.senders.len())
714 .finish()
715 }
716}
717
718impl PartialEq for RecorderInterceptors {
719 fn eq(&self, other: &Self) -> bool {
720 self.receivers.len() == other.receivers.len()
721 && self.senders.len() == other.senders.len()
722 }
723}
724
725impl Eq for RecorderInterceptors {}
726
727impl RtcConfigurationBuilder {
728 pub fn new() -> Self {
729 Self {
730 inner: RtcConfiguration::default(),
731 }
732 }
733
734 pub fn enable_latching(mut self, enable: bool) -> Self {
735 self.inner.enable_latching = enable;
736 self
737 }
738
739 pub fn probation_max_packets(mut self, max: Option<u8>) -> Self {
740 self.inner.probation_max_packets = max;
741 self
742 }
743
744 pub fn enable_ice_lite(mut self, enable: bool) -> Self {
745 self.inner.enable_ice_lite = enable;
746 self
747 }
748
749 pub fn prefer_srflx_over_natted_host(mut self, enable: bool) -> Self {
750 self.inner.prefer_srflx_over_natted_host = enable;
751 self
752 }
753
754 pub fn enable_upnp(mut self, enable: bool) -> Self {
755 self.inner.enable_upnp = enable;
756 self
757 }
758
759 pub fn upnp_lease_duration(mut self, duration_secs: u32) -> Self {
760 self.inner.upnp_lease_duration = duration_secs;
761 self
762 }
763
764 pub fn upnp_discovery_timeout(mut self, timeout: std::time::Duration) -> Self {
765 self.inner.upnp_discovery_timeout = timeout;
766 self
767 }
768
769 pub fn ice_server(mut self, server: IceServer) -> Self {
770 self.inner.ice_servers.push(server);
771 self
772 }
773
774 pub fn ice_transport_policy(mut self, policy: IceTransportPolicy) -> Self {
775 self.inner.ice_transport_policy = policy;
776 self
777 }
778
779 pub fn bundle_policy(mut self, policy: BundlePolicy) -> Self {
780 self.inner.bundle_policy = policy;
781 self
782 }
783
784 pub fn rtcp_mux_policy(mut self, policy: RtcpMuxPolicy) -> Self {
785 self.inner.rtcp_mux_policy = policy;
786 self
787 }
788
789 pub fn certificate(mut self, cert: CertificateConfig) -> Self {
790 self.inner.certificates.push(cert);
791 self
792 }
793
794 pub fn transport_mode(mut self, mode: TransportMode) -> Self {
795 self.inner.transport_mode = mode;
796 self
797 }
798
799 pub fn media_capabilities(mut self, capabilities: MediaCapabilities) -> Self {
800 self.inner.media_capabilities = Some(capabilities);
801 self
802 }
803
804 pub fn external_ip(mut self, ip: String) -> Self {
805 self.inner.external_ip = Some(ip);
806 self
807 }
808
809 pub fn external_port(mut self, port: u16) -> Self {
810 self.inner.external_port = Some(port);
811 self
812 }
813
814 pub fn bind_ip(mut self, ip: String) -> Self {
815 self.inner.bind_ip = Some(ip);
816 self
817 }
818
819 pub fn disable_ipv6(mut self, disable: bool) -> Self {
820 self.inner.disable_ipv6 = disable;
821 self
822 }
823
824 pub fn ssrc_start(mut self, start: u32) -> Self {
825 self.inner.ssrc_start = start;
826 self
827 }
828
829 pub fn stun_timeout(mut self, timeout: std::time::Duration) -> Self {
830 self.inner.stun_timeout = timeout;
831 self
832 }
833
834 pub fn nomination_timeout(mut self, timeout: std::time::Duration) -> Self {
835 self.inner.nomination_timeout = timeout;
836 self
837 }
838
839 pub fn rtp_port_range(mut self, start: u16, end: u16) -> Self {
840 self.inner.rtp_start_port = Some(start);
841 self.inner.rtp_end_port = Some(end);
842 self
843 }
844
845 pub fn ice_gather_udp_hosts(mut self, enable: bool) -> Self {
846 self.inner.ice_gather_udp_hosts = enable;
847 self
848 }
849
850 pub fn tcp_port_range(mut self, start: u16, end: u16) -> Self {
851 self.inner.tcp_port_range_start = Some(start);
852 self.inner.tcp_port_range_end = Some(end);
853 self
854 }
855
856 pub fn dtls_buffer_size(mut self, size: usize) -> Self {
857 self.inner.dtls_buffer_size = size;
858 self
859 }
860
861 pub fn sctp_rto_initial(mut self, duration: std::time::Duration) -> Self {
862 self.inner.sctp_rto_initial = duration;
863 self
864 }
865
866 pub fn sctp_rto_min(mut self, duration: std::time::Duration) -> Self {
867 self.inner.sctp_rto_min = duration;
868 self
869 }
870
871 pub fn sctp_rto_max(mut self, duration: std::time::Duration) -> Self {
872 self.inner.sctp_rto_max = duration;
873 self
874 }
875
876 pub fn sctp_max_association_retransmits(mut self, count: u32) -> Self {
877 self.inner.sctp_max_association_retransmits = count;
878 self
879 }
880
881 pub fn sctp_receive_window(mut self, size: usize) -> Self {
882 self.inner.sctp_receive_window = size;
883 self
884 }
885
886 pub fn sctp_heartbeat_interval(mut self, duration: std::time::Duration) -> Self {
887 self.inner.sctp_heartbeat_interval = duration;
888 self
889 }
890
891 pub fn sctp_max_heartbeat_failures(mut self, count: u32) -> Self {
892 self.inner.sctp_max_heartbeat_failures = count;
893 self
894 }
895
896 pub fn sctp_max_burst(mut self, packets: usize) -> Self {
901 self.inner.sctp_max_burst = packets;
902 self
903 }
904
905 pub fn sctp_max_cwnd(mut self, size: usize) -> Self {
908 self.inner.sctp_max_cwnd = size;
909 self
910 }
911
912 pub fn sctp_max_buffered_amount(mut self, bytes: usize) -> Self {
918 self.inner.sctp_max_buffered_amount = bytes;
919 self
920 }
921
922 pub fn ice_connection_timeout(mut self, timeout: std::time::Duration) -> Self {
923 self.inner.ice_connection_timeout = timeout;
924 self
925 }
926
927 pub fn ice_disconnect_threshold(mut self, threshold: std::time::Duration) -> Self {
928 self.inner.ice_disconnect_threshold = threshold;
929 self
930 }
931
932 pub fn ice_disconnect_grace(mut self, grace: std::time::Duration) -> Self {
933 self.inner.ice_disconnect_grace = grace;
934 self
935 }
936
937 pub fn rtp_buffer_capacity(mut self, capacity: usize) -> Self {
938 self.inner.rtp_buffer_capacity = capacity;
939 self
940 }
941
942 pub fn buffer_drop_strategy(mut self, strategy: BufferDropStrategy) -> Self {
943 self.inner.buffer_drop_strategy = strategy;
944 self
945 }
946
947 pub fn buffer_stats_log_interval(mut self, interval: std::time::Duration) -> Self {
948 self.inner.buffer_stats_log_interval = interval;
949 self
950 }
951
952 pub fn ice_tcp_policy(mut self, policy: IceTcpPolicy) -> Self {
953 self.inner.ice_tcp_policy = policy;
954 self
955 }
956
957 pub fn ice_udp_mux(mut self, enable: bool) -> Self {
960 self.inner.ice_udp_mux = enable;
961 self
962 }
963
964 pub fn ice_udp_mux_port(mut self, port: u16) -> Self {
966 self.inner.ice_udp_mux_port = Some(port);
967 self
968 }
969
970 pub fn sdp_compatibility(mut self, mode: SdpCompatibilityMode) -> Self {
971 self.inner.sdp_compatibility = mode;
972 self
973 }
974
975 pub fn cname(mut self, cname: String) -> Self {
976 self.inner.cname = Some(cname);
977 self
978 }
979
980 pub fn receiver_interceptor(
983 mut self,
984 interceptor: Arc<dyn RtpReceiverInterceptor>,
985 ) -> Self {
986 self.inner.recorder_interceptors.receivers.push(interceptor);
987 self
988 }
989
990 pub fn sender_interceptor(
993 mut self,
994 interceptor: Arc<dyn RtpSenderInterceptor>,
995 ) -> Self {
996 self.inner.recorder_interceptors.senders.push(interceptor);
997 self
998 }
999
1000 pub fn runtime_handle(mut self, handle: tokio::runtime::Handle) -> Self {
1004 self.inner.runtime_handle = Some(handle);
1005 self
1006 }
1007
1008 pub fn build(self) -> RtcConfiguration {
1009 self.inner
1010 }
1011}
1012
1013impl From<RtcConfigurationBuilder> for RtcConfiguration {
1014 fn from(builder: RtcConfigurationBuilder) -> Self {
1015 builder.build()
1016 }
1017}
1018
1019#[cfg(test)]
1020mod tests {
1021 use super::*;
1022 use std::time::Duration;
1023
1024 #[test]
1025 fn test_rtc_configuration_defaults() {
1026 let config = RtcConfiguration::default();
1027 assert_eq!(config.ice_connection_timeout, Duration::from_secs(30));
1028 assert_eq!(config.ice_disconnect_threshold, Duration::from_secs(5));
1029 assert_eq!(config.ice_disconnect_grace, Duration::from_secs(15));
1030 assert_eq!(config.sctp_rto_initial, Duration::from_secs(3));
1031 assert_eq!(config.sctp_rto_min, Duration::from_millis(200));
1032 assert_eq!(config.sctp_rto_max, Duration::from_secs(60));
1033 assert_eq!(config.sctp_max_association_retransmits, 20);
1034 assert_eq!(config.sctp_heartbeat_interval, Duration::from_secs(15));
1035 assert_eq!(config.sctp_max_heartbeat_failures, 4);
1036 assert_eq!(config.sctp_max_burst, 0);
1037 assert_eq!(config.sctp_max_cwnd, 256 * 1024);
1038 assert_eq!(config.rtp_buffer_capacity, 100);
1039 assert_eq!(config.buffer_drop_strategy, BufferDropStrategy::DropNew);
1040 assert_eq!(config.buffer_stats_log_interval, Duration::from_secs(10));
1041 }
1042
1043 #[test]
1044 fn test_rtc_configuration_builder() {
1045 let config = RtcConfigurationBuilder::new()
1046 .stun_timeout(Duration::from_secs(10))
1047 .build();
1048 assert_eq!(config.stun_timeout, Duration::from_secs(10));
1049 assert_eq!(config.ice_connection_timeout, Duration::from_secs(30));
1051 }
1052
1053 #[test]
1054 fn test_buffer_config_builder() {
1055 let config = RtcConfigurationBuilder::new()
1056 .rtp_buffer_capacity(200)
1057 .buffer_drop_strategy(BufferDropStrategy::DropOldest)
1058 .buffer_stats_log_interval(Duration::from_secs(5))
1059 .build();
1060 assert_eq!(config.rtp_buffer_capacity, 200);
1061 assert_eq!(config.buffer_drop_strategy, BufferDropStrategy::DropOldest);
1062 assert_eq!(config.buffer_stats_log_interval, Duration::from_secs(5));
1063 }
1064
1065 #[test]
1066 fn test_sctp_builder_methods() {
1067 let config = RtcConfigurationBuilder::new()
1068 .sctp_rto_initial(Duration::from_millis(500))
1069 .sctp_rto_min(Duration::from_millis(200))
1070 .sctp_rto_max(Duration::from_secs(10))
1071 .sctp_max_association_retransmits(30)
1072 .sctp_receive_window(512 * 1024)
1073 .sctp_heartbeat_interval(Duration::from_secs(10))
1074 .sctp_max_heartbeat_failures(8)
1075 .sctp_max_burst(4)
1076 .sctp_max_cwnd(512 * 1024)
1077 .ice_connection_timeout(Duration::from_secs(60))
1078 .build();
1079
1080 assert_eq!(config.sctp_rto_initial, Duration::from_millis(500));
1081 assert_eq!(config.sctp_rto_min, Duration::from_millis(200));
1082 assert_eq!(config.sctp_rto_max, Duration::from_secs(10));
1083 assert_eq!(config.sctp_max_association_retransmits, 30);
1084 assert_eq!(config.sctp_receive_window, 512 * 1024);
1085 assert_eq!(config.sctp_heartbeat_interval, Duration::from_secs(10));
1086 assert_eq!(config.sctp_max_heartbeat_failures, 8);
1087 assert_eq!(config.sctp_max_burst, 4);
1088 assert_eq!(config.sctp_max_cwnd, 512 * 1024);
1089 assert_eq!(config.ice_connection_timeout, Duration::from_secs(60));
1090 }
1091
1092 #[test]
1093 fn test_turn_optimized_config() {
1094 let config = RtcConfigurationBuilder::new()
1096 .sctp_rto_initial(Duration::from_millis(500))
1097 .sctp_rto_min(Duration::from_millis(100))
1098 .sctp_rto_max(Duration::from_secs(10))
1099 .sctp_max_association_retransmits(30)
1100 .sctp_max_heartbeat_failures(8)
1101 .sctp_max_burst(4)
1102 .stun_timeout(Duration::from_secs(10))
1103 .nomination_timeout(Duration::from_secs(20))
1104 .build();
1105
1106 let defaults = RtcConfiguration::default();
1108 assert!(config.sctp_rto_initial < defaults.sctp_rto_initial);
1109 assert!(config.sctp_rto_min < defaults.sctp_rto_min);
1110 assert!(config.sctp_rto_max < defaults.sctp_rto_max);
1111 assert!(
1112 config.sctp_max_association_retransmits > defaults.sctp_max_association_retransmits
1113 );
1114 assert!(config.sctp_max_heartbeat_failures > defaults.sctp_max_heartbeat_failures);
1115 assert!(config.sctp_max_burst > 0); }
1117
1118 #[test]
1119 fn test_external_port_defaults() {
1120 let config = RtcConfiguration::default();
1121 assert_eq!(config.external_port, None);
1122 }
1123
1124 #[test]
1125 fn test_external_port_builder() {
1126 let config = RtcConfigurationBuilder::new().external_port(30000).build();
1127 assert_eq!(config.external_port, Some(30000));
1128 }
1129
1130 #[test]
1131 fn test_external_port_with_external_ip_builder() {
1132 let config = RtcConfigurationBuilder::new()
1133 .external_ip("203.0.113.5".to_string())
1134 .external_port(30000)
1135 .build();
1136 assert_eq!(config.external_ip, Some("203.0.113.5".to_string()));
1137 assert_eq!(config.external_port, Some(30000));
1138 }
1139
1140 #[test]
1141 fn test_upnp_defaults() {
1142 let config = RtcConfiguration::default();
1143 assert!(!config.enable_upnp, "UPnP should be disabled by default");
1144 assert_eq!(config.upnp_lease_duration, 3600);
1145 }
1146
1147 #[test]
1148 fn test_upnp_builder_methods() {
1149 let config = RtcConfigurationBuilder::new()
1150 .enable_upnp(false)
1151 .upnp_lease_duration(7200)
1152 .build();
1153 assert!(!config.enable_upnp);
1154 assert_eq!(config.upnp_lease_duration, 7200);
1155 }
1156
1157 #[test]
1158 fn test_upnp_optimized_config() {
1159 let config = RtcConfigurationBuilder::new()
1160 .enable_upnp(true)
1161 .upnp_lease_duration(1800)
1162 .build();
1163
1164 assert!(config.enable_upnp);
1165 assert_eq!(config.upnp_lease_duration, 1800);
1166
1167 let defaults = RtcConfiguration::default();
1169 assert_eq!(
1170 config.ice_connection_timeout,
1171 defaults.ice_connection_timeout
1172 );
1173 }
1174
1175 #[test]
1176 fn test_ice_udp_mux_defaults() {
1177 let config = RtcConfiguration::default();
1178 assert!(
1179 !config.ice_udp_mux,
1180 "ICE UDP mux should be disabled by default"
1181 );
1182 assert_eq!(config.ice_udp_mux_port, None);
1183 }
1184
1185 #[test]
1186 fn test_ice_udp_mux_builder_methods() {
1187 let config = RtcConfigurationBuilder::new()
1188 .ice_udp_mux(true)
1189 .ice_udp_mux_port(30500)
1190 .build();
1191 assert!(config.ice_udp_mux);
1192 assert_eq!(config.ice_udp_mux_port, Some(30500));
1193 }
1194}