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![
241 "nack".to_string(),
242 "nack pli".to_string(),
243 "ccm fir".to_string(),
244 ],
245 rtx_payload_type: None,
246 }
247 }
248
249 pub fn vp8_with_rtx(rtx_payload_type: u8) -> Self {
251 Self {
252 rtx_payload_type: Some(rtx_payload_type),
253 ..Self::default()
254 }
255 }
256}
257
258#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
259pub struct ApplicationCapability {
260 pub sctp_port: u16,
261}
262
263impl Default for ApplicationCapability {
264 fn default() -> Self {
265 Self { sctp_port: 5000 }
266 }
267}
268
269#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Default)]
270pub enum T38FaxRateManagement {
271 #[serde(rename = "transferredTCF")]
272 #[default]
273 TransferredTCF,
274 #[serde(rename = "localTCF")]
275 LocalTCF,
276}
277
278impl std::fmt::Display for T38FaxRateManagement {
279 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
280 match self {
281 Self::TransferredTCF => write!(f, "transferredTCF"),
282 Self::LocalTCF => write!(f, "localTCF"),
283 }
284 }
285}
286
287#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Default)]
288pub enum T38UdpEC {
289 #[serde(rename = "t38UDPRedundancy")]
290 #[default]
291 T38UDPRedundancy,
292 #[serde(rename = "t38UDPFEC")]
293 T38UDPFEC,
294}
295
296impl std::fmt::Display for T38UdpEC {
297 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
298 match self {
299 Self::T38UDPRedundancy => write!(f, "t38UDPRedundancy"),
300 Self::T38UDPFEC => write!(f, "t38UDPFEC"),
301 }
302 }
303}
304
305#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
306pub struct T38Capability {
307 pub payload_type: u8,
308 pub version: u8,
310 pub max_bitrate: u32,
312 pub rate_management: T38FaxRateManagement,
314 pub max_buffer: u16,
316 pub max_datagram: u16,
318 pub udp_ec: T38UdpEC,
320 pub fmtp: Option<String>,
321}
322
323impl Default for T38Capability {
324 fn default() -> Self {
325 Self {
326 payload_type: 98,
327 version: 0,
328 max_bitrate: 14400,
329 rate_management: T38FaxRateManagement::default(),
330 max_buffer: 1024,
331 max_datagram: 238,
332 udp_ec: T38UdpEC::default(),
333 fmtp: None,
334 }
335 }
336}
337
338impl T38Capability {
339 pub fn default_t38() -> Self {
340 Self::default()
341 }
342}
343
344#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
345pub struct MediaCapabilities {
346 pub audio: Vec<AudioCapability>,
347 pub video: Vec<VideoCapability>,
348 pub application: Option<ApplicationCapability>,
349 pub image: Vec<T38Capability>,
350}
351
352impl Default for MediaCapabilities {
353 fn default() -> Self {
354 Self {
355 audio: vec![AudioCapability::opus(), AudioCapability::pcmu()],
356 video: vec![VideoCapability::default()],
357 application: Some(ApplicationCapability::default()),
358 image: vec![],
359 }
360 }
361}
362
363#[derive(Clone)]
364pub struct DepacketizerStrategy {
365 pub factory: Arc<dyn DepacketizerFactory>,
366}
367
368impl Default for DepacketizerStrategy {
369 fn default() -> Self {
370 Self {
371 factory: Arc::new(DefaultDepacketizerFactory),
372 }
373 }
374}
375
376impl Debug for DepacketizerStrategy {
377 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
378 self.factory.fmt(f)
379 }
380}
381
382impl PartialEq for DepacketizerStrategy {
383 fn eq(&self, other: &Self) -> bool {
384 Arc::ptr_eq(&self.factory, &other.factory)
385 }
386}
387
388impl Eq for DepacketizerStrategy {}
389
390fn default_rtp_buffer_capacity() -> usize {
391 100
392}
393
394fn default_buffer_stats_log_interval() -> std::time::Duration {
395 std::time::Duration::from_secs(10)
396}
397
398#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Default)]
400#[serde(rename_all = "snake_case")]
401pub enum SdpCompatibilityMode {
402 #[default]
404 Standard,
405 LegacySip,
408}
409
410fn default_enable_upnp() -> bool {
411 false
412}
413
414fn default_upnp_lease_duration() -> u32 {
415 3600
416}
417
418fn default_upnp_discovery_timeout() -> std::time::Duration {
419 std::time::Duration::from_secs(1)
420}
421
422fn default_upnp_refresh_interval() -> std::time::Duration {
423 std::time::Duration::from_secs(30)
424}
425
426#[derive(Debug, Clone, Serialize, Deserialize)]
428pub struct RtcConfiguration {
429 pub ice_servers: Vec<IceServer>,
430 pub ice_transport_policy: IceTransportPolicy,
431 pub bundle_policy: BundlePolicy,
432 pub rtcp_mux_policy: RtcpMuxPolicy,
433 pub certificates: Vec<CertificateConfig>,
434 pub transport_mode: TransportMode,
435 pub nack_buffer_size: usize,
436 pub media_capabilities: Option<MediaCapabilities>,
437 pub external_ip: Option<String>,
442 pub external_port: Option<u16>,
454 pub bind_ip: Option<String>,
455 pub disable_ipv6: bool,
456 pub ssrc_start: u32,
457 pub stun_timeout: std::time::Duration,
458 pub nomination_timeout: std::time::Duration,
462 pub ice_connection_timeout: std::time::Duration,
463 pub ice_disconnect_threshold: std::time::Duration,
475 pub ice_disconnect_grace: std::time::Duration,
487 pub sctp_rto_initial: std::time::Duration,
488 pub sctp_rto_min: std::time::Duration,
489 pub sctp_rto_max: std::time::Duration,
490 pub sctp_max_association_retransmits: u32,
491 pub sctp_receive_window: usize,
492 pub sctp_heartbeat_interval: std::time::Duration,
493 pub sctp_max_heartbeat_failures: u32,
494 pub sctp_max_tsn_retransmits: u32,
495 pub sctp_max_burst: usize,
496 pub sctp_max_cwnd: usize,
497 pub sctp_max_buffered_amount: usize,
502 pub dtls_buffer_size: usize,
503 pub rtp_start_port: Option<u16>,
504 pub rtp_end_port: Option<u16>,
505 pub ice_gather_udp_hosts: bool,
506 #[serde(default)]
516 pub ice_include_loopback_candidates: bool,
517 pub tcp_port_range_start: Option<u16>,
518 pub tcp_port_range_end: Option<u16>,
519 pub enable_latching: bool,
520 pub probation_max_packets: Option<u8>,
521 pub enable_ice_lite: bool,
522 #[serde(default)]
529 pub prefer_srflx_over_natted_host: bool,
530 #[serde(default = "default_enable_upnp")]
532 pub enable_upnp: bool,
533 #[serde(default = "default_upnp_lease_duration")]
535 pub upnp_lease_duration: u32,
536 #[serde(default = "default_upnp_discovery_timeout")]
538 pub upnp_discovery_timeout: std::time::Duration,
539 #[serde(default = "default_upnp_refresh_interval")]
544 pub upnp_refresh_interval: std::time::Duration,
545 #[serde(skip, default)]
546 pub depacketizer_strategy: DepacketizerStrategy,
547 #[serde(default = "default_rtp_buffer_capacity")]
548 pub rtp_buffer_capacity: usize,
549 #[serde(default)]
550 pub buffer_drop_strategy: BufferDropStrategy,
551 #[serde(default = "default_buffer_stats_log_interval")]
552 pub buffer_stats_log_interval: std::time::Duration,
553 #[serde(default)]
556 pub ice_tcp_policy: IceTcpPolicy,
557 #[serde(default)]
567 pub ice_udp_mux: bool,
568 #[serde(default)]
571 pub ice_udp_mux_port: Option<u16>,
572 #[serde(default)]
574 pub sdp_compatibility: SdpCompatibilityMode,
575 #[serde(skip, default)]
576 pub label: Option<String>,
577 #[serde(skip, default)]
578 pub cname: Option<String>,
579 #[serde(skip, default)]
584 pub runtime_handle: Option<tokio::runtime::Handle>,
585 #[serde(skip, default)]
590 pub recorder_interceptors: RecorderInterceptors,
591}
592
593impl PartialEq for RtcConfiguration {
594 fn eq(&self, other: &Self) -> bool {
595 self.ice_servers == other.ice_servers
597 && self.ice_transport_policy == other.ice_transport_policy
598 && self.bundle_policy == other.bundle_policy
599 && self.rtcp_mux_policy == other.rtcp_mux_policy
600 && self.certificates == other.certificates
601 && self.transport_mode == other.transport_mode
602 && self.nack_buffer_size == other.nack_buffer_size
603 && self.media_capabilities == other.media_capabilities
604 && self.external_ip == other.external_ip
605 && self.external_port == other.external_port
606 && self.bind_ip == other.bind_ip
607 && self.disable_ipv6 == other.disable_ipv6
608 && self.ssrc_start == other.ssrc_start
609 && self.stun_timeout == other.stun_timeout
610 && self.nomination_timeout == other.nomination_timeout
611 && self.ice_connection_timeout == other.ice_connection_timeout
612 && self.ice_disconnect_threshold == other.ice_disconnect_threshold
613 && self.ice_disconnect_grace == other.ice_disconnect_grace
614 && self.sctp_rto_initial == other.sctp_rto_initial
615 && self.sctp_rto_min == other.sctp_rto_min
616 && self.sctp_rto_max == other.sctp_rto_max
617 && self.sctp_max_association_retransmits == other.sctp_max_association_retransmits
618 && self.sctp_receive_window == other.sctp_receive_window
619 && self.sctp_heartbeat_interval == other.sctp_heartbeat_interval
620 && self.sctp_max_heartbeat_failures == other.sctp_max_heartbeat_failures
621 && self.sctp_max_tsn_retransmits == other.sctp_max_tsn_retransmits
622 && self.sctp_max_burst == other.sctp_max_burst
623 && self.sctp_max_cwnd == other.sctp_max_cwnd
624 && self.sctp_max_buffered_amount == other.sctp_max_buffered_amount
625 && self.dtls_buffer_size == other.dtls_buffer_size
626 && self.rtp_start_port == other.rtp_start_port
627 && self.rtp_end_port == other.rtp_end_port
628 && self.ice_gather_udp_hosts == other.ice_gather_udp_hosts
629 && self.ice_include_loopback_candidates == other.ice_include_loopback_candidates
630 && self.tcp_port_range_start == other.tcp_port_range_start
631 && self.tcp_port_range_end == other.tcp_port_range_end
632 && self.enable_latching == other.enable_latching
633 && self.probation_max_packets == other.probation_max_packets
634 && self.enable_ice_lite == other.enable_ice_lite
635 && self.prefer_srflx_over_natted_host == other.prefer_srflx_over_natted_host
636 && self.enable_upnp == other.enable_upnp
637 && self.upnp_lease_duration == other.upnp_lease_duration
638 && self.upnp_discovery_timeout == other.upnp_discovery_timeout
639 && self.upnp_refresh_interval == other.upnp_refresh_interval
640 && self.depacketizer_strategy == other.depacketizer_strategy
641 && self.rtp_buffer_capacity == other.rtp_buffer_capacity
642 && self.buffer_drop_strategy == other.buffer_drop_strategy
643 && self.buffer_stats_log_interval == other.buffer_stats_log_interval
644 && self.ice_tcp_policy == other.ice_tcp_policy
645 && self.ice_udp_mux == other.ice_udp_mux
646 && self.ice_udp_mux_port == other.ice_udp_mux_port
647 && self.sdp_compatibility == other.sdp_compatibility
648 && self.label == other.label
649 && self.cname == other.cname
650 }
652}
653
654impl Eq for RtcConfiguration {}
655
656impl Default for RtcConfiguration {
657 fn default() -> Self {
658 Self {
659 ice_servers: Vec::new(),
660 ice_transport_policy: IceTransportPolicy::default(),
661 bundle_policy: BundlePolicy::default(),
662 rtcp_mux_policy: RtcpMuxPolicy::default(),
663 certificates: Vec::new(),
664 transport_mode: TransportMode::default(),
665 nack_buffer_size: 200,
666 media_capabilities: None,
667 external_ip: None,
668 external_port: None,
669 bind_ip: None,
670 disable_ipv6: false,
671 ssrc_start: 10000,
672 stun_timeout: std::time::Duration::from_secs(5),
673 nomination_timeout: std::time::Duration::from_secs(10),
674 ice_connection_timeout: std::time::Duration::from_secs(120),
675 ice_disconnect_threshold: std::time::Duration::from_secs(30),
676 ice_disconnect_grace: std::time::Duration::from_secs(60),
677 sctp_rto_initial: std::time::Duration::from_secs(3),
678 sctp_rto_min: std::time::Duration::from_millis(200),
679 sctp_rto_max: std::time::Duration::from_secs(60),
680 sctp_max_association_retransmits: 20,
681 sctp_receive_window: 128 * 1024, sctp_heartbeat_interval: std::time::Duration::from_secs(15),
683 sctp_max_heartbeat_failures: 4,
684 sctp_max_tsn_retransmits: 8,
685 sctp_max_burst: 0, sctp_max_cwnd: 256 * 1024, sctp_max_buffered_amount: 256 * 1024, dtls_buffer_size: 2048,
689 rtp_start_port: None,
690 rtp_end_port: None,
691 ice_gather_udp_hosts: true,
692 ice_include_loopback_candidates: false,
693 tcp_port_range_start: None,
694 tcp_port_range_end: None,
695 enable_latching: false,
696 probation_max_packets: None,
697 enable_ice_lite: false,
698 prefer_srflx_over_natted_host: false,
699 enable_upnp: default_enable_upnp(),
700 upnp_lease_duration: default_upnp_lease_duration(),
701 upnp_discovery_timeout: default_upnp_discovery_timeout(),
702 upnp_refresh_interval: default_upnp_refresh_interval(),
703 depacketizer_strategy: DepacketizerStrategy::default(),
704 rtp_buffer_capacity: default_rtp_buffer_capacity(),
705 buffer_drop_strategy: BufferDropStrategy::default(),
706 buffer_stats_log_interval: default_buffer_stats_log_interval(),
707 ice_tcp_policy: IceTcpPolicy::default(),
708 ice_udp_mux: false,
709 ice_udp_mux_port: None,
710 sdp_compatibility: SdpCompatibilityMode::default(),
711 label: None,
712 cname: None,
713 runtime_handle: None,
714 recorder_interceptors: RecorderInterceptors::default(),
715 }
716 }
717}
718
719pub struct RtcConfigurationBuilder {
720 inner: RtcConfiguration,
721}
722
723impl Default for RtcConfigurationBuilder {
724 fn default() -> Self {
725 Self::new()
726 }
727}
728
729#[derive(Clone, Default)]
733pub struct RecorderInterceptors {
734 pub receivers: Vec<Arc<dyn RtpReceiverInterceptor>>,
735 pub senders: Vec<Arc<dyn RtpSenderInterceptor>>,
736}
737
738impl Debug for RecorderInterceptors {
739 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
740 f.debug_struct("RecorderInterceptors")
741 .field("receivers_len", &self.receivers.len())
742 .field("senders_len", &self.senders.len())
743 .finish()
744 }
745}
746
747impl PartialEq for RecorderInterceptors {
748 fn eq(&self, other: &Self) -> bool {
749 self.receivers.len() == other.receivers.len() && self.senders.len() == other.senders.len()
750 }
751}
752
753impl Eq for RecorderInterceptors {}
754
755impl RtcConfigurationBuilder {
756 pub fn new() -> Self {
757 Self {
758 inner: RtcConfiguration::default(),
759 }
760 }
761
762 pub fn enable_latching(mut self, enable: bool) -> Self {
763 self.inner.enable_latching = enable;
764 self
765 }
766
767 pub fn probation_max_packets(mut self, max: Option<u8>) -> Self {
768 self.inner.probation_max_packets = max;
769 self
770 }
771
772 pub fn enable_ice_lite(mut self, enable: bool) -> Self {
773 self.inner.enable_ice_lite = enable;
774 self
775 }
776
777 pub fn prefer_srflx_over_natted_host(mut self, enable: bool) -> Self {
778 self.inner.prefer_srflx_over_natted_host = enable;
779 self
780 }
781
782 pub fn enable_upnp(mut self, enable: bool) -> Self {
783 self.inner.enable_upnp = enable;
784 self
785 }
786
787 pub fn upnp_lease_duration(mut self, duration_secs: u32) -> Self {
788 self.inner.upnp_lease_duration = duration_secs;
789 self
790 }
791
792 pub fn upnp_discovery_timeout(mut self, timeout: std::time::Duration) -> Self {
793 self.inner.upnp_discovery_timeout = timeout;
794 self
795 }
796
797 pub fn upnp_refresh_interval(mut self, interval: std::time::Duration) -> Self {
799 self.inner.upnp_refresh_interval = interval;
800 self
801 }
802
803 pub fn ice_server(mut self, server: IceServer) -> Self {
804 self.inner.ice_servers.push(server);
805 self
806 }
807
808 pub fn ice_transport_policy(mut self, policy: IceTransportPolicy) -> Self {
809 self.inner.ice_transport_policy = policy;
810 self
811 }
812
813 pub fn bundle_policy(mut self, policy: BundlePolicy) -> Self {
814 self.inner.bundle_policy = policy;
815 self
816 }
817
818 pub fn rtcp_mux_policy(mut self, policy: RtcpMuxPolicy) -> Self {
819 self.inner.rtcp_mux_policy = policy;
820 self
821 }
822
823 pub fn certificate(mut self, cert: CertificateConfig) -> Self {
824 self.inner.certificates.push(cert);
825 self
826 }
827
828 pub fn transport_mode(mut self, mode: TransportMode) -> Self {
829 self.inner.transport_mode = mode;
830 self
831 }
832
833 pub fn media_capabilities(mut self, capabilities: MediaCapabilities) -> Self {
834 self.inner.media_capabilities = Some(capabilities);
835 self
836 }
837
838 pub fn external_ip(mut self, ip: String) -> Self {
839 self.inner.external_ip = Some(ip);
840 self
841 }
842
843 pub fn external_port(mut self, port: u16) -> Self {
844 self.inner.external_port = Some(port);
845 self
846 }
847
848 pub fn bind_ip(mut self, ip: String) -> Self {
849 self.inner.bind_ip = Some(ip);
850 self
851 }
852
853 pub fn disable_ipv6(mut self, disable: bool) -> Self {
854 self.inner.disable_ipv6 = disable;
855 self
856 }
857
858 pub fn ssrc_start(mut self, start: u32) -> Self {
859 self.inner.ssrc_start = start;
860 self
861 }
862
863 pub fn stun_timeout(mut self, timeout: std::time::Duration) -> Self {
864 self.inner.stun_timeout = timeout;
865 self
866 }
867
868 pub fn nomination_timeout(mut self, timeout: std::time::Duration) -> Self {
869 self.inner.nomination_timeout = timeout;
870 self
871 }
872
873 pub fn rtp_port_range(mut self, start: u16, end: u16) -> Self {
874 self.inner.rtp_start_port = Some(start);
875 self.inner.rtp_end_port = Some(end);
876 self
877 }
878
879 pub fn ice_gather_udp_hosts(mut self, enable: bool) -> Self {
880 self.inner.ice_gather_udp_hosts = enable;
881 self
882 }
883
884 pub fn ice_include_loopback_candidates(mut self, enable: bool) -> Self {
887 self.inner.ice_include_loopback_candidates = enable;
888 self
889 }
890
891 pub fn tcp_port_range(mut self, start: u16, end: u16) -> Self {
892 self.inner.tcp_port_range_start = Some(start);
893 self.inner.tcp_port_range_end = Some(end);
894 self
895 }
896
897 pub fn dtls_buffer_size(mut self, size: usize) -> Self {
898 self.inner.dtls_buffer_size = size;
899 self
900 }
901
902 pub fn sctp_rto_initial(mut self, duration: std::time::Duration) -> Self {
903 self.inner.sctp_rto_initial = duration;
904 self
905 }
906
907 pub fn sctp_rto_min(mut self, duration: std::time::Duration) -> Self {
908 self.inner.sctp_rto_min = duration;
909 self
910 }
911
912 pub fn sctp_rto_max(mut self, duration: std::time::Duration) -> Self {
913 self.inner.sctp_rto_max = duration;
914 self
915 }
916
917 pub fn sctp_max_association_retransmits(mut self, count: u32) -> Self {
918 self.inner.sctp_max_association_retransmits = count;
919 self
920 }
921
922 pub fn sctp_receive_window(mut self, size: usize) -> Self {
923 self.inner.sctp_receive_window = size;
924 self
925 }
926
927 pub fn sctp_heartbeat_interval(mut self, duration: std::time::Duration) -> Self {
928 self.inner.sctp_heartbeat_interval = duration;
929 self
930 }
931
932 pub fn sctp_max_heartbeat_failures(mut self, count: u32) -> Self {
933 self.inner.sctp_max_heartbeat_failures = count;
934 self
935 }
936
937 pub fn sctp_max_burst(mut self, packets: usize) -> Self {
942 self.inner.sctp_max_burst = packets;
943 self
944 }
945
946 pub fn sctp_max_cwnd(mut self, size: usize) -> Self {
949 self.inner.sctp_max_cwnd = size;
950 self
951 }
952
953 pub fn sctp_max_buffered_amount(mut self, bytes: usize) -> Self {
959 self.inner.sctp_max_buffered_amount = bytes;
960 self
961 }
962
963 pub fn ice_connection_timeout(mut self, timeout: std::time::Duration) -> Self {
964 self.inner.ice_connection_timeout = timeout;
965 self
966 }
967
968 pub fn ice_disconnect_threshold(mut self, threshold: std::time::Duration) -> Self {
969 self.inner.ice_disconnect_threshold = threshold;
970 self
971 }
972
973 pub fn ice_disconnect_grace(mut self, grace: std::time::Duration) -> Self {
974 self.inner.ice_disconnect_grace = grace;
975 self
976 }
977
978 pub fn rtp_buffer_capacity(mut self, capacity: usize) -> Self {
979 self.inner.rtp_buffer_capacity = capacity;
980 self
981 }
982
983 pub fn buffer_drop_strategy(mut self, strategy: BufferDropStrategy) -> Self {
984 self.inner.buffer_drop_strategy = strategy;
985 self
986 }
987
988 pub fn buffer_stats_log_interval(mut self, interval: std::time::Duration) -> Self {
989 self.inner.buffer_stats_log_interval = interval;
990 self
991 }
992
993 pub fn ice_tcp_policy(mut self, policy: IceTcpPolicy) -> Self {
994 self.inner.ice_tcp_policy = policy;
995 self
996 }
997
998 pub fn ice_udp_mux(mut self, enable: bool) -> Self {
1001 self.inner.ice_udp_mux = enable;
1002 self
1003 }
1004
1005 pub fn ice_udp_mux_port(mut self, port: u16) -> Self {
1007 self.inner.ice_udp_mux_port = Some(port);
1008 self
1009 }
1010
1011 pub fn sdp_compatibility(mut self, mode: SdpCompatibilityMode) -> Self {
1012 self.inner.sdp_compatibility = mode;
1013 self
1014 }
1015
1016 pub fn cname(mut self, cname: String) -> Self {
1017 self.inner.cname = Some(cname);
1018 self
1019 }
1020
1021 pub fn receiver_interceptor(mut self, interceptor: Arc<dyn RtpReceiverInterceptor>) -> Self {
1024 self.inner.recorder_interceptors.receivers.push(interceptor);
1025 self
1026 }
1027
1028 pub fn sender_interceptor(mut self, interceptor: Arc<dyn RtpSenderInterceptor>) -> Self {
1031 self.inner.recorder_interceptors.senders.push(interceptor);
1032 self
1033 }
1034
1035 pub fn runtime_handle(mut self, handle: tokio::runtime::Handle) -> Self {
1039 self.inner.runtime_handle = Some(handle);
1040 self
1041 }
1042
1043 pub fn build(self) -> RtcConfiguration {
1044 self.inner
1045 }
1046}
1047
1048impl From<RtcConfigurationBuilder> for RtcConfiguration {
1049 fn from(builder: RtcConfigurationBuilder) -> Self {
1050 builder.build()
1051 }
1052}
1053
1054#[cfg(test)]
1055mod tests {
1056 use super::*;
1057 use std::time::Duration;
1058
1059 #[test]
1060 fn test_rtc_configuration_defaults() {
1061 let config = RtcConfiguration::default();
1062 assert_eq!(config.ice_connection_timeout, Duration::from_secs(120));
1063 assert_eq!(config.ice_disconnect_threshold, Duration::from_secs(30));
1064 assert_eq!(config.ice_disconnect_grace, Duration::from_secs(60));
1065 assert_eq!(config.sctp_rto_initial, Duration::from_secs(3));
1066 assert_eq!(config.sctp_rto_min, Duration::from_millis(200));
1067 assert_eq!(config.sctp_rto_max, Duration::from_secs(60));
1068 assert_eq!(config.sctp_max_association_retransmits, 20);
1069 assert_eq!(config.sctp_heartbeat_interval, Duration::from_secs(15));
1070 assert_eq!(config.sctp_max_heartbeat_failures, 4);
1071 assert_eq!(config.sctp_max_burst, 0);
1072 assert_eq!(config.sctp_max_cwnd, 256 * 1024);
1073 assert_eq!(config.rtp_buffer_capacity, 100);
1074 assert_eq!(config.buffer_drop_strategy, BufferDropStrategy::DropNew);
1075 assert_eq!(config.buffer_stats_log_interval, Duration::from_secs(10));
1076 }
1077
1078 #[test]
1079 fn test_rtc_configuration_builder() {
1080 let config = RtcConfigurationBuilder::new()
1081 .stun_timeout(Duration::from_secs(10))
1082 .build();
1083 assert_eq!(config.stun_timeout, Duration::from_secs(10));
1084 assert_eq!(config.ice_connection_timeout, Duration::from_secs(120));
1086 }
1087
1088 #[test]
1089 fn test_buffer_config_builder() {
1090 let config = RtcConfigurationBuilder::new()
1091 .rtp_buffer_capacity(200)
1092 .buffer_drop_strategy(BufferDropStrategy::DropOldest)
1093 .buffer_stats_log_interval(Duration::from_secs(5))
1094 .build();
1095 assert_eq!(config.rtp_buffer_capacity, 200);
1096 assert_eq!(config.buffer_drop_strategy, BufferDropStrategy::DropOldest);
1097 assert_eq!(config.buffer_stats_log_interval, Duration::from_secs(5));
1098 }
1099
1100 #[test]
1101 fn test_sctp_builder_methods() {
1102 let config = RtcConfigurationBuilder::new()
1103 .sctp_rto_initial(Duration::from_millis(500))
1104 .sctp_rto_min(Duration::from_millis(200))
1105 .sctp_rto_max(Duration::from_secs(10))
1106 .sctp_max_association_retransmits(30)
1107 .sctp_receive_window(512 * 1024)
1108 .sctp_heartbeat_interval(Duration::from_secs(10))
1109 .sctp_max_heartbeat_failures(8)
1110 .sctp_max_burst(4)
1111 .sctp_max_cwnd(512 * 1024)
1112 .ice_connection_timeout(Duration::from_secs(60))
1113 .build();
1114
1115 assert_eq!(config.sctp_rto_initial, Duration::from_millis(500));
1116 assert_eq!(config.sctp_rto_min, Duration::from_millis(200));
1117 assert_eq!(config.sctp_rto_max, Duration::from_secs(10));
1118 assert_eq!(config.sctp_max_association_retransmits, 30);
1119 assert_eq!(config.sctp_receive_window, 512 * 1024);
1120 assert_eq!(config.sctp_heartbeat_interval, Duration::from_secs(10));
1121 assert_eq!(config.sctp_max_heartbeat_failures, 8);
1122 assert_eq!(config.sctp_max_burst, 4);
1123 assert_eq!(config.sctp_max_cwnd, 512 * 1024);
1124 assert_eq!(config.ice_connection_timeout, Duration::from_secs(60));
1125 }
1126
1127 #[test]
1128 fn test_turn_optimized_config() {
1129 let config = RtcConfigurationBuilder::new()
1131 .sctp_rto_initial(Duration::from_millis(500))
1132 .sctp_rto_min(Duration::from_millis(100))
1133 .sctp_rto_max(Duration::from_secs(10))
1134 .sctp_max_association_retransmits(30)
1135 .sctp_max_heartbeat_failures(8)
1136 .sctp_max_burst(4)
1137 .stun_timeout(Duration::from_secs(10))
1138 .nomination_timeout(Duration::from_secs(20))
1139 .build();
1140
1141 let defaults = RtcConfiguration::default();
1143 assert!(config.sctp_rto_initial < defaults.sctp_rto_initial);
1144 assert!(config.sctp_rto_min < defaults.sctp_rto_min);
1145 assert!(config.sctp_rto_max < defaults.sctp_rto_max);
1146 assert!(
1147 config.sctp_max_association_retransmits > defaults.sctp_max_association_retransmits
1148 );
1149 assert!(config.sctp_max_heartbeat_failures > defaults.sctp_max_heartbeat_failures);
1150 assert!(config.sctp_max_burst > 0); }
1152
1153 #[test]
1154 fn test_external_port_defaults() {
1155 let config = RtcConfiguration::default();
1156 assert_eq!(config.external_port, None);
1157 }
1158
1159 #[test]
1160 fn test_external_port_builder() {
1161 let config = RtcConfigurationBuilder::new().external_port(30000).build();
1162 assert_eq!(config.external_port, Some(30000));
1163 }
1164
1165 #[test]
1166 fn test_external_port_with_external_ip_builder() {
1167 let config = RtcConfigurationBuilder::new()
1168 .external_ip("203.0.113.5".to_string())
1169 .external_port(30000)
1170 .build();
1171 assert_eq!(config.external_ip, Some("203.0.113.5".to_string()));
1172 assert_eq!(config.external_port, Some(30000));
1173 }
1174
1175 #[test]
1176 fn test_upnp_defaults() {
1177 let config = RtcConfiguration::default();
1178 assert!(!config.enable_upnp, "UPnP should be disabled by default");
1179 assert_eq!(config.upnp_lease_duration, 3600);
1180 assert_eq!(config.upnp_refresh_interval, Duration::from_secs(30));
1181 }
1182
1183 #[test]
1184 fn test_upnp_builder_methods() {
1185 let config = RtcConfigurationBuilder::new()
1186 .enable_upnp(false)
1187 .upnp_lease_duration(7200)
1188 .build();
1189 assert!(!config.enable_upnp);
1190 assert_eq!(config.upnp_lease_duration, 7200);
1191 }
1192
1193 #[test]
1194 fn test_upnp_refresh_interval_builder() {
1195 let config = RtcConfigurationBuilder::new()
1196 .upnp_refresh_interval(Duration::from_secs(60))
1197 .build();
1198 assert_eq!(config.upnp_refresh_interval, Duration::from_secs(60));
1199
1200 let a = RtcConfigurationBuilder::new()
1202 .upnp_refresh_interval(Duration::from_secs(60))
1203 .build();
1204 let b = RtcConfigurationBuilder::new()
1205 .upnp_refresh_interval(Duration::from_secs(120))
1206 .build();
1207 assert_ne!(a, b);
1208 assert_eq!(a, a.clone());
1209 }
1210
1211 #[test]
1212 fn test_upnp_optimized_config() {
1213 let config = RtcConfigurationBuilder::new()
1214 .enable_upnp(true)
1215 .upnp_lease_duration(1800)
1216 .build();
1217
1218 assert!(config.enable_upnp);
1219 assert_eq!(config.upnp_lease_duration, 1800);
1220
1221 let defaults = RtcConfiguration::default();
1223 assert_eq!(
1224 config.ice_connection_timeout,
1225 defaults.ice_connection_timeout
1226 );
1227 }
1228
1229 #[test]
1230 fn test_ice_udp_mux_defaults() {
1231 let config = RtcConfiguration::default();
1232 assert!(
1233 !config.ice_udp_mux,
1234 "ICE UDP mux should be disabled by default"
1235 );
1236 assert_eq!(config.ice_udp_mux_port, None);
1237 }
1238
1239 #[test]
1240 fn test_ice_udp_mux_builder_methods() {
1241 let config = RtcConfigurationBuilder::new()
1242 .ice_udp_mux(true)
1243 .ice_udp_mux_port(30500)
1244 .build();
1245 assert!(config.ice_udp_mux);
1246 assert_eq!(config.ice_udp_mux_port, Some(30500));
1247 }
1248}