rvoip-rtp-core 0.2.2

RTP/RTCP protocol implementation for the rvoip stack
Documentation
//! Client API for media transport
//!
//! This module provides client-side API components for media transport.

pub mod config;
pub mod security;
pub mod transport;

// Re-export public API
pub use config::{ClientConfig, ClientConfigBuilder};
pub use security::{ClientSecurityConfig, ClientSecurityContext};
pub use transport::MediaTransportClient;

// Re-export implementation files
pub use security::DefaultClientSecurityContext;
pub use transport::default::DefaultMediaTransportClient;

// Import errors
use crate::api::common::error::MediaTransportError;

/// Factory for creating media transport clients
pub struct ClientFactory;

impl ClientFactory {
    /// Create a new media transport client
    pub async fn create_client(
        config: ClientConfig,
    ) -> Result<DefaultMediaTransportClient, MediaTransportError> {
        // Create client transport
        let client = DefaultMediaTransportClient::new(config)
            .await
            .map_err(|e| {
                MediaTransportError::InitializationError(format!("Failed to create client: {}", e))
            })?;

        Ok(client)
    }

    /// Create a client for WebRTC
    pub async fn create_webrtc_client(
        remote_addr: std::net::SocketAddr,
    ) -> Result<DefaultMediaTransportClient, MediaTransportError> {
        // Create WebRTC-optimized config
        let config = ClientConfigBuilder::webrtc()
            .remote_address(remote_addr)
            .build();

        Self::create_client(config).await
    }

    /// Create a client for SIP
    pub async fn create_sip_client(
        remote_addr: std::net::SocketAddr,
    ) -> Result<DefaultMediaTransportClient, MediaTransportError> {
        // Create SIP-optimized config
        let config = ClientConfigBuilder::sip()
            .remote_address(remote_addr)
            .build();

        Self::create_client(config).await
    }
}

// Update the ClientConfigBuilder to add a method for the unified security config
impl ClientConfigBuilder {
    /// Set the security configuration using the unified SecurityConfig
    /// This provides an easier way to configure security with predefined profiles
    pub fn with_security(
        mut self,
        security_config: crate::api::common::config::SecurityConfig,
    ) -> Self {
        match security_config.mode {
            crate::api::common::config::SecurityMode::None => {
                // No security - use plain RTP
                // Don't set any security config
            }
            crate::api::common::config::SecurityMode::Srtp => {
                // Basic SRTP with pre-shared key
                // Convert to security config format expected by client
                let client_security_config = crate::api::client::security::ClientSecurityConfig {
                    security_mode: crate::api::common::config::SecurityMode::Srtp,
                    fingerprint_algorithm: security_config.fingerprint_algorithm,
                    remote_fingerprint: security_config.remote_fingerprint.clone(),
                    remote_fingerprint_algorithm: security_config
                        .remote_fingerprint_algorithm
                        .clone(),
                    validate_fingerprint: false, // Not used for SRTP mode
                    srtp_profiles: security_config.srtp_profiles,
                    certificate_path: None, // Not used for SRTP mode
                    private_key_path: None, // Not used for SRTP mode
                    srtp_key: security_config.srtp_key.clone(),
                };

                self = self.security_config(client_security_config);

                // If a key was provided, set it up for SRTP
                if let Some(_key) = security_config.srtp_key {
                    // Here you would set up the pre-shared key
                    // This might require additional implementation in your SRTP code
                }
            }
            crate::api::common::config::SecurityMode::DtlsSrtp => {
                // DTLS-SRTP mode
                // Convert to security config format expected by client
                let client_security_config = crate::api::client::security::ClientSecurityConfig {
                    security_mode: crate::api::common::config::SecurityMode::DtlsSrtp,
                    fingerprint_algorithm: security_config.fingerprint_algorithm,
                    remote_fingerprint: security_config.remote_fingerprint.clone(),
                    remote_fingerprint_algorithm: security_config
                        .remote_fingerprint_algorithm
                        .clone(),
                    validate_fingerprint: security_config.remote_fingerprint.is_some(),
                    srtp_profiles: security_config.srtp_profiles,
                    certificate_path: security_config.certificate_path,
                    private_key_path: security_config.private_key_path,
                    srtp_key: None, // Not used for DTLS-SRTP
                };

                self = self.security_config(client_security_config);
            }
            crate::api::common::config::SecurityMode::SdesSrtp
            | crate::api::common::config::SecurityMode::MikeySrtp
            | crate::api::common::config::SecurityMode::ZrtpSrtp => {
                // SIP-derived SRTP methods use the unified security context instead
                // For now, these are handled through SecurityContextManager
                // TODO: Implement direct client config support for these methods
            }
        }

        self
    }

    /// Set up WebRTC-compatible security (DTLS-SRTP with self-signed certs)
    pub fn with_webrtc_security(self) -> Self {
        let security_config = crate::api::common::config::SecurityConfig::webrtc_compatible();
        self.with_security(security_config)
    }

    /// Set up SRTP with a pre-shared key
    pub fn with_srtp_key(self, key: Vec<u8>) -> Self {
        let security_config = crate::api::common::config::SecurityConfig::srtp_with_key(key);
        self.with_security(security_config)
    }

    /// Set up plain RTP (no security)
    pub fn with_no_security(self) -> Self {
        let security_config = crate::api::common::config::SecurityConfig::unsecured();
        self.with_security(security_config)
    }

    /// Set up DTLS-SRTP with provided certificate files
    pub fn with_dtls_certificate(self, cert_path: String, key_path: String) -> Self {
        let security_config =
            crate::api::common::config::SecurityConfig::dtls_with_certificate(cert_path, key_path);
        self.with_security(security_config)
    }
}