pub(crate) async fn populate_sdp(
    mut d: SessionDescription,
    dtls_fingerprints: &[RTCDtlsFingerprint],
    media_engine: &Arc<MediaEngine>,
    candidates: &[RTCIceCandidate],
    ice_params: &RTCIceParameters,
    media_sections: &[MediaSection],
    params: PopulateSdpParams,
) -> Result<SessionDescription> {
    let media_dtls_fingerprints = if params.media_description_fingerprint {
        dtls_fingerprints.to_vec()
    } else {
        vec![]
    };

    let mut bundle_value = "BUNDLE".to_owned();
    let mut bundle_count = 0;
    let append_bundle = |mid_value: &str, value: &mut String, count: &mut i32| {
        *value = value.clone() + " " + mid_value;
        *count += 1;
    };

    for (i, m) in media_sections.iter().enumerate() {
        if m.data && !m.transceivers.is_empty() {
            return Err(Error::ErrSDPMediaSectionMediaDataChanInvalid);
        } else if !params.is_plan_b && m.transceivers.len() > 1 {
            return Err(Error::ErrSDPMediaSectionMultipleTrackInvalid);
        }

        let should_add_candidates = i == 0;

        let should_add_id = if m.data {
            let params = AddDataMediaSectionParams {
                should_add_candidates,
                mid_value: m.id.clone(),
                ice_params: ice_params.clone(),
                dtls_role: params.connection_role,
                ice_gathering_state: params.ice_gathering_state,
            };
            d = add_data_media_section(d, &media_dtls_fingerprints, candidates, params).await?;
            true
        } else {
            let params = AddTransceiverSdpParams {
                is_plan_b: params.is_plan_b,
                should_add_candidates,
                mid_value: m.id.clone(),
                dtls_role: params.connection_role,
                ice_gathering_state: params.ice_gathering_state,
            };
            let (d1, should_add_id) = add_transceiver_sdp(
                d,
                &media_dtls_fingerprints,
                media_engine,
                ice_params,
                candidates,
                m,
                params,
            )
            .await?;
            d = d1;
            should_add_id
        };

        if should_add_id {
            append_bundle(&m.id, &mut bundle_value, &mut bundle_count);
        }
    }

    if !params.media_description_fingerprint {
        for fingerprint in dtls_fingerprints {
            d = d.with_fingerprint(
                fingerprint.algorithm.clone(),
                fingerprint.value.to_uppercase(),
            );
        }
    }

    if params.is_icelite {
        // RFC 5245 S15.3
        d = d.with_value_attribute(ATTR_KEY_ICELITE.to_owned(), ATTR_KEY_ICELITE.to_owned());
    }

    Ok(d.with_value_attribute(ATTR_KEY_GROUP.to_owned(), bundle_value))
}
/// populate_sdp serializes a PeerConnections state into an SDP
populate_sdp serializes a PeerConnections state into an SDP
populate_sdp serializes a PeerConnections state into an SDP
pub(crate) async fn populate_sdp(
    mut d: SessionDescription,
    dtls_fingerprints: &[RTCDtlsFingerprint],
    media_engine: &Arc<MediaEngine>,
    candidates: &[RTCIceCandidate],
    ice_params: &RTCIceParameters,
    media_sections: &[MediaSection],
    params: PopulateSdpParams,
) -> Result<SessionDescription> {
    let media_dtls_fingerprints = if params.media_description_fingerprint {
        dtls_fingerprints.to_vec()
    } else {
        vec![]
    };
    let mut bundle_value = "BUNDLE".to_owned();
    let mut bundle_count = 0;
    let append_bundle = |mid_value: &str, value: &mut String, count: &mut i32| {
        *value = value.clone() + " " + mid_value;
        *count += 1;
    };
    for (i, m) in media_sections.iter().enumerate() {
        if m.data && !m.transceivers.is_empty() {
            return Err(Error::ErrSDPMediaSectionMediaDataChanInvalid);
        } else if !params.is_plan_b && m.transceivers.len() > 1 {
            return Err(Error::ErrSDPMediaSectionMultipleTrackInvalid);
        }
        let should_add_candidates = i == 0;
        let should_add_id = if m.data {
            let params = AddDataMediaSectionParams {
                should_add_candidates,
                mid_value: m.id.clone(),
                ice_params: ice_params.clone(),
                dtls_role: params.connection_role,
                ice_gathering_state: params.ice_gathering_state,
            };
            d = add_data_media_section(d, &media_dtls_fingerprints, candidates, params).await?;
            true
        } else {
            let params = AddTransceiverSdpParams {
                is_plan_b: params.is_plan_b,
                should_add_candidates,
                mid_value: m.id.clone(),
                dtls_role: params.connection_role,
                ice_gathering_state: params.ice_gathering_state,
            };
            let (d1, should_add_id) = add_transceiver_sdp(
                d,
                &media_dtls_fingerprints,
                media_engine,
                ice_params,
                candidates,
                m,
                params,
            )
            .await?;
            d = d1;
            should_add_id
        };
        if should_add_id {
            append_bundle(&m.id, &mut bundle_value, &mut bundle_count);
        }
    }
    if !params.media_description_fingerprint {
        for fingerprint in dtls_fingerprints {
            d = d.with_fingerprint(
                fingerprint.algorithm.clone(),
                fingerprint.value.to_uppercase(),
            );
        }
    }
    if params.is_icelite {
        // RFC 5245 S15.3
        d = d.with_value_attribute(ATTR_KEY_ICELITE.to_owned(), ATTR_KEY_ICELITE.to_owned());
    }
    Ok(d.with_value_attribute(ATTR_KEY_GROUP.to_owned(), bundle_value))
}
pub ( crate ) async fn populate_sdp ( mut d : SessionDescription , dtls_fingerprints : & [ RTCDtlsFingerprint ] , media_engine : & Arc < MediaEngine > , candidates : & [ RTCIceCandidate ] , ice_params : & RTCIceParameters , media_sections : & [ MediaSection ] , params : PopulateSdpParams , ) -> Result < SessionDescription > { let media_dtls_fingerprints = if params . media_description_fingerprint { dtls_fingerprints . to_vec ( ) } else { vec ! [ ] } ; let mut bundle_value = " " . to_owned ( ) ; let mut bundle_count = 0 ; let append_bundle = | mid_value : & str , value : & mut String , count : & mut i32 | { * value = value . clone ( ) + " " + mid_value ; * count += 1 ; } ; for ( i , m ) in media_sections . iter ( ) . enumerate ( ) { if m . data && ! m . transceivers . is_empty ( ) { return Err ( Error :: ErrSDPMediaSectionMediaDataChanInvalid ) ; } else if ! params . is_plan_b && m . transceivers . len ( ) > 1 { return Err ( Error :: ErrSDPMediaSectionMultipleTrackInvalid ) ; } let should_add_candidates = i == 0 ; let should_add_id = if m . data { let params = AddDataMediaSectionParams { should_add_candidates , mid_value : m . id . clone ( ) , ice_params : ice_params . clone ( ) , dtls_role : params . connection_role , ice_gathering_state : params . ice_gathering_state , } ; d = add_data_media_section ( d , & media_dtls_fingerprints , candidates , params ) . await ? ; true } else { let params = AddTransceiverSdpParams { is_plan_b : params . is_plan_b , should_add_candidates , mid_value : m . id . clone ( ) , dtls_role : params . connection_role , ice_gathering_state : params . ice_gathering_state , } ; let ( d1 , should_add_id ) = add_transceiver_sdp ( d , & media_dtls_fingerprints , media_engine , ice_params , candidates , m , params , ) . await ? ; d = d1 ; should_add_id } ; if should_add_id { append_bundle ( & m . id , & mut bundle_value , & mut bundle_count ) ; } } if ! params . media_description_fingerprint { for fingerprint in dtls_fingerprints { d = d . with_fingerprint ( fingerprint . algorithm . clone ( ) , fingerprint . value . to_uppercase ( ) , ) ; } } if params . is_icelite { // RFC 5245 S15.3 d = d . with_value_attribute ( ATTR_KEY_ICELITE . to_owned ( ) , ATTR_KEY_ICELITE . to_owned ( ) ) ; } Ok ( d . with_value_attribute ( ATTR_KEY_GROUP . to_owned ( ) , bundle_value ) ) }
populate_sdp serializes a PeerConnections state into an SDP
populate_sdp serializes a PeerConnections state into an SDP
d
SessionDescription
dtls_fingerprints
&[RTCDtlsFingerprint]
media_engine
&Arc<MediaEngine>
candidates
&[RTCIceCandidate]
ice_params
&RTCIceParameters
media_sections
&[MediaSection]
params
PopulateSdpParams