pub async fn start(&self, remote_parameters: DTLSParameters) -> Result<()> {
        let dtls_conn_result = if let Some(dtls_endpoint) =
            self.ice_transport.new_endpoint(Box::new(match_dtls)).await
        {
            let (role, mut dtls_config) = self.prepare_transport(remote_parameters).await?;
            if self.setting_engine.replay_protection.dtls != 0 {
                dtls_config.replay_protection_window = self.setting_engine.replay_protection.dtls;
            }

            // Connect as DTLS Client/Server, function is blocking and we
            // must not hold the DTLSTransport lock
            if role == DTLSRole::Client {
                dtls::conn::DTLSConn::new(
                    dtls_endpoint as Arc<dyn Conn + Send + Sync>,
                    dtls_config,
                    true,
                    None,
                )
                .await
            } else {
                dtls::conn::DTLSConn::new(
                    dtls_endpoint as Arc<dyn Conn + Send + Sync>,
                    dtls_config,
                    false,
                    None,
                )
                .await
            }
        } else {
            Err(dtls::Error::Other(
                "ice_transport.new_endpoint failed".to_owned(),
            ))
        };

        let dtls_conn = match dtls_conn_result {
            Ok(dtls_conn) => dtls_conn,
            Err(err) => {
                self.state_change(RTCDtlsTransportState::Failed).await;
                return Err(err.into());
            }
        };

        let srtp_profile = dtls_conn.selected_srtpprotection_profile();
        {
            let mut srtp_protection_profile = self.srtp_protection_profile.lock().await;
            *srtp_protection_profile = match srtp_profile {
                dtls::extension::extension_use_srtp::SrtpProtectionProfile::Srtp_Aead_Aes_128_Gcm => {
                    srtp::protection_profile::ProtectionProfile::AeadAes128Gcm
                }
                dtls::extension::extension_use_srtp::SrtpProtectionProfile::Srtp_Aes128_Cm_Hmac_Sha1_80 => {
                    srtp::protection_profile::ProtectionProfile::Aes128CmHmacSha1_80
                }
                _ => {
                    self.state_change(RTCDtlsTransportState::Failed).await;
                    return Err(Error::ErrNoSRTPProtectionProfile);
                }
            };
        }

        if self
            .setting_engine
            .disable_certificate_fingerprint_verification
        {
            return Ok(());
        }

        // Check the fingerprint if a certificate was exchanged
        let remote_certs = &dtls_conn.connection_state().await.peer_certificates;
        if remote_certs.is_empty() {
            self.state_change(RTCDtlsTransportState::Failed).await;
            return Err(Error::ErrNoRemoteCertificate);
        }

        {
            let mut remote_certificate = self.remote_certificate.lock().await;
            *remote_certificate = Bytes::from(remote_certs[0].clone());
        }

        if let Err(err) = self.validate_fingerprint(&remote_certs[0]).await {
            if dtls_conn.close().await.is_err() {
                log::error!("{}", err);
            }

            self.state_change(RTCDtlsTransportState::Failed).await;
            return Err(err);
        }

        {
            let mut conn = self.conn.lock().await;
            *conn = Some(Arc::new(dtls_conn));
        }
        self.state_change(RTCDtlsTransportState::Connected).await;

        self.start_srtp().await
    }
/// start DTLS transport negotiation with the parameters of the remote DTLS transport
start DTLS transport negotiation with the parameters of the remote DTLS transport
start DTLS transport negotiation with the parameters of the remote DTLS transport
pub async fn start(&self, remote_parameters: DTLSParameters) -> Result<()> {
        let dtls_conn_result = if let Some(dtls_endpoint) =
            self.ice_transport.new_endpoint(Box::new(match_dtls)).await
        {
            let (role, mut dtls_config) = self.prepare_transport(remote_parameters).await?;
            if self.setting_engine.replay_protection.dtls != 0 {
                dtls_config.replay_protection_window = self.setting_engine.replay_protection.dtls;
            }
            // Connect as DTLS Client/Server, function is blocking and we
            // must not hold the DTLSTransport lock
            if role == DTLSRole::Client {
                dtls::conn::DTLSConn::new(
                    dtls_endpoint as Arc<dyn Conn + Send + Sync>,
                    dtls_config,
                    true,
                    None,
                )
                .await
            } else {
                dtls::conn::DTLSConn::new(
                    dtls_endpoint as Arc<dyn Conn + Send + Sync>,
                    dtls_config,
                    false,
                    None,
                )
                .await
            }
        } else {
            Err(dtls::Error::Other(
                "ice_transport.new_endpoint failed".to_owned(),
            ))
        };
        let dtls_conn = match dtls_conn_result {
            Ok(dtls_conn) => dtls_conn,
            Err(err) => {
                self.state_change(RTCDtlsTransportState::Failed).await;
                return Err(err.into());
            }
        };
        let srtp_profile = dtls_conn.selected_srtpprotection_profile();
        {
            let mut srtp_protection_profile = self.srtp_protection_profile.lock().await;
            *srtp_protection_profile = match srtp_profile {
                dtls::extension::extension_use_srtp::SrtpProtectionProfile::Srtp_Aead_Aes_128_Gcm => {
                    srtp::protection_profile::ProtectionProfile::AeadAes128Gcm
                }
                dtls::extension::extension_use_srtp::SrtpProtectionProfile::Srtp_Aes128_Cm_Hmac_Sha1_80 => {
                    srtp::protection_profile::ProtectionProfile::Aes128CmHmacSha1_80
                }
                _ => {
                    self.state_change(RTCDtlsTransportState::Failed).await;
                    return Err(Error::ErrNoSRTPProtectionProfile);
                }
            };
        }
        if self
            .setting_engine
            .disable_certificate_fingerprint_verification
        {
            return Ok(());
        }
        // Check the fingerprint if a certificate was exchanged
        let remote_certs = &dtls_conn.connection_state().await.peer_certificates;
        if remote_certs.is_empty() {
            self.state_change(RTCDtlsTransportState::Failed).await;
            return Err(Error::ErrNoRemoteCertificate);
        }
        {
            let mut remote_certificate = self.remote_certificate.lock().await;
            *remote_certificate = Bytes::from(remote_certs[0].clone());
        }
        if let Err(err) = self.validate_fingerprint(&remote_certs[0]).await {
            if dtls_conn.close().await.is_err() {
                log::error!("{}", err);
            }
            self.state_change(RTCDtlsTransportState::Failed).await;
            return Err(err);
        }
        {
            let mut conn = self.conn.lock().await;
            *conn = Some(Arc::new(dtls_conn));
        }
        self.state_change(RTCDtlsTransportState::Connected).await;
        self.start_srtp().await
    }
pub async fn start ( & self , remote_parameters : DTLSParameters ) -> Result < ( ) > { let dtls_conn_result = if let Some ( dtls_endpoint ) = self . ice_transport . new_endpoint ( Box :: new ( match_dtls ) ) . await { let ( role , mut dtls_config ) = self . prepare_transport ( remote_parameters ) . await ? ; if self . setting_engine . replay_protection . dtls != 0 { dtls_config . replay_protection_window = self . setting_engine . replay_protection . dtls ; } // Connect as DTLS Client/Server, function is blocking and we // must not hold the DTLSTransport lock if role == DTLSRole :: Client { dtls :: conn :: DTLSConn :: new ( dtls_endpoint as Arc < dyn Conn + Send + Sync > , dtls_config , true , None , ) . await } else { dtls :: conn :: DTLSConn :: new ( dtls_endpoint as Arc < dyn Conn + Send + Sync > , dtls_config , false , None , ) . await } } else { Err ( dtls :: Error :: Other ( " " . to_owned ( ) , ) ) } ; let dtls_conn = match dtls_conn_result { Ok ( dtls_conn ) => dtls_conn , Err ( err ) => { self . state_change ( RTCDtlsTransportState :: Failed ) . await ; return Err ( err . into ( ) ) ; } } ; let srtp_profile = dtls_conn . selected_srtpprotection_profile ( ) ; { let mut srtp_protection_profile = self . srtp_protection_profile . lock ( ) . await ; * srtp_protection_profile = match srtp_profile { dtls :: extension :: extension_use_srtp :: SrtpProtectionProfile :: Srtp_Aead_Aes_128_Gcm => { srtp :: protection_profile :: ProtectionProfile :: AeadAes128Gcm } dtls :: extension :: extension_use_srtp :: SrtpProtectionProfile :: Srtp_Aes128_Cm_Hmac_Sha1_80 => { srtp :: protection_profile :: ProtectionProfile :: Aes128CmHmacSha1_80 } _ => { self . state_change ( RTCDtlsTransportState :: Failed ) . await ; return Err ( Error :: ErrNoSRTPProtectionProfile ) ; } } ; } if self . setting_engine . disable_certificate_fingerprint_verification { return Ok ( ( ) ) ; } // Check the fingerprint if a certificate was exchanged let remote_certs = & dtls_conn . connection_state ( ) . await . peer_certificates ; if remote_certs . is_empty ( ) { self . state_change ( RTCDtlsTransportState :: Failed ) . await ; return Err ( Error :: ErrNoRemoteCertificate ) ; } { let mut remote_certificate = self . remote_certificate . lock ( ) . await ; * remote_certificate = Bytes :: from ( remote_certs [ 0 ] . clone ( ) ) ; } if let Err ( err ) = self . validate_fingerprint ( & remote_certs [ 0 ] ) . await { if dtls_conn . close ( ) . await . is_err ( ) { log :: error ! ( " " err ) ; } self . state_change ( RTCDtlsTransportState :: Failed ) . await ; return Err ( err ) ; } { let mut conn = self . conn . lock ( ) . await ; * conn = Some ( Arc :: new ( dtls_conn ) ) ; } self . state_change ( RTCDtlsTransportState :: Connected ) . await ; self . start_srtp ( ) . await }
start DTLS transport negotiation with the parameters of the remote DTLS transport
start DTLS transport negotiation with the parameters of the remote DTLS transport
&self
remote_parameters
DTLSParameters