use crate::peer_connection::configuration::setting_engine::SctpMaxMessageSize;
use crate::peer_connection::transport::dtls::role::RTCDtlsRole;
use crate::peer_connection::transport::sctp::capabilities::SCTPTransportCapabilities;
use crate::peer_connection::transport::sctp::state::RTCSctpTransportState;
use sctp::{Association, AssociationHandle};
use shared::error::Result;
use shared::{TransportContext, TransportProtocol};
use std::collections::HashMap;
pub(crate) mod capabilities;
pub(crate) mod state;
const SCTP_MAX_CHANNELS: u16 = u16::MAX;
#[derive(Default)]
pub(crate) struct RTCSctpTransport {
pub(crate) sctp_endpoint: Option<::sctp::Endpoint>,
pub(crate) sctp_transport_config: Option<::sctp::TransportConfig>,
pub(crate) sctp_associations: HashMap<AssociationHandle, Association>,
pub(crate) state: RTCSctpTransportState,
pub(crate) is_started: bool,
pub(crate) max_message_size: SctpMaxMessageSize,
pub(crate) max_channels: u16,
pub(crate) internal_buffer: Vec<u8>,
}
impl RTCSctpTransport {
pub(crate) fn new(max_message_size: SctpMaxMessageSize) -> Self {
Self {
sctp_endpoint: None,
sctp_transport_config: None,
sctp_associations: HashMap::new(),
state: RTCSctpTransportState::Connecting,
is_started: false,
max_message_size,
max_channels: SCTP_MAX_CHANNELS,
internal_buffer: vec![],
}
}
pub(crate) fn calc_message_size(remote_max_message_size: u32, can_send_size: u32) -> u32 {
if remote_max_message_size == 0 && can_send_size == 0 {
u32::MAX
} else if remote_max_message_size == 0 {
can_send_size
} else if can_send_size == 0 || can_send_size > remote_max_message_size {
remote_max_message_size
} else {
can_send_size
}
}
pub(crate) fn max_channels(&self) -> u16 {
self.max_channels
}
pub(crate) fn start(
&mut self,
dtls_role: RTCDtlsRole,
remote_caps: SCTPTransportCapabilities,
local_port: u16,
_remote_port: u16,
) -> Result<()> {
if self.is_started {
return Ok(());
}
self.is_started = true;
let max_message_size = RTCSctpTransport::calc_message_size(
remote_caps.max_message_size,
self.max_message_size.as_usize() as u32,
);
self.internal_buffer.resize(max_message_size as usize, 0u8);
let sctp_endpoint_config = ::sctp::EndpointConfig::default();
let sctp_transport_config = ::sctp::TransportConfig::default()
.with_max_message_size(max_message_size)
.with_sctp_port(local_port);
if dtls_role == RTCDtlsRole::Client {
self.sctp_endpoint = Some(sctp::Endpoint::new(
TransportContext::default().local_addr, TransportProtocol::UDP, sctp_endpoint_config.into(),
None,
));
self.sctp_transport_config = Some(sctp_transport_config);
} else {
self.sctp_endpoint = Some(::sctp::Endpoint::new(
TransportContext::default().local_addr, TransportProtocol::UDP, sctp_endpoint_config.into(),
Some(::sctp::ServerConfig::new(sctp_transport_config).into()),
));
}
Ok(())
}
}