diff --git a/examples/Cargo.lock b/examples/Cargo.lock index e319fe4c..71248b37 100644 --- a/examples/Cargo.lock +++ b/examples/Cargo.lock @@ -167,12 +167,6 @@ dependencies = [ "x11rb", ] -[[package]] -name = "arc-swap" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bddcadddf5e9015d310179a59bb28c4d4b9920ad0f11e8e14dbadf654890c9a6" - [[package]] name = "arrayref" version = "0.3.7" @@ -1786,7 +1780,6 @@ checksum = "57bcfdad1b858c2db7c38303a6d2ad4dfaf5eb53dfeb0910128b2c26d6158503" name = "livekit" version = "0.2.0" dependencies = [ - "arc-swap", "futures-util", "lazy_static", "livekit-api", diff --git a/livekit-ffi/protocol/e2ee.proto b/livekit-ffi/protocol/e2ee.proto index 75871575..39f142bb 100644 --- a/livekit-ffi/protocol/e2ee.proto +++ b/livekit-ffi/protocol/e2ee.proto @@ -37,7 +37,7 @@ message KeyProviderOptions { optional bytes shared_key = 1; int32 ratchet_window_size = 2; bytes ratchet_salt = 3; - bytes uncrypted_magic_bytes = 4; + int32 failure_tolerance = 4; // -1 = no tolerence } message E2eeOptions { diff --git a/livekit-ffi/src/conversion/room.rs b/livekit-ffi/src/conversion/room.rs index fde2a2f3..6a03868b 100644 --- a/livekit-ffi/src/conversion/room.rs +++ b/livekit-ffi/src/conversion/room.rs @@ -79,7 +79,7 @@ impl From for KeyProviderOptions { Self { ratchet_window_size: value.ratchet_window_size, ratchet_salt: value.ratchet_salt, - uncrypted_magic_bytes: value.uncrypted_magic_bytes, + failure_tolerance: value.failure_tolerance, } } } diff --git a/livekit-ffi/src/livekit.proto.rs b/livekit-ffi/src/livekit.proto.rs index 8f0ad409..bfc22e5d 100644 --- a/livekit-ffi/src/livekit.proto.rs +++ b/livekit-ffi/src/livekit.proto.rs @@ -21,8 +21,9 @@ pub struct KeyProviderOptions { pub ratchet_window_size: i32, #[prost(bytes="vec", tag="3")] pub ratchet_salt: ::prost::alloc::vec::Vec, - #[prost(bytes="vec", tag="4")] - pub uncrypted_magic_bytes: ::prost::alloc::vec::Vec, + /// -1 = no tolerence + #[prost(int32, tag="4")] + pub failure_tolerance: i32, } #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] @@ -1216,6 +1217,24 @@ pub struct TrackPublishOptions { } #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] +pub struct IceServer { + #[prost(string, repeated, tag="1")] + pub urls: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, + #[prost(string, tag="2")] + pub username: ::prost::alloc::string::String, + #[prost(string, tag="3")] + pub credential: ::prost::alloc::string::String, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct RtcConfig { + #[prost(enumeration="IceTransportPolicy", tag="1")] + pub ice_transport_policy: i32, + #[prost(message, repeated, tag="2")] + pub ice_servers: ::prost::alloc::vec::Vec, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct RoomOptions { #[prost(bool, tag="1")] pub auto_subscribe: bool, @@ -1225,6 +1244,9 @@ pub struct RoomOptions { pub dynacast: bool, #[prost(message, optional, tag="4")] pub e2ee: ::core::option::Option, + /// allow to setup a custom RtcConfiguration + #[prost(message, optional, tag="5")] + pub rtc_config: ::core::option::Option, } #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] @@ -1457,6 +1479,38 @@ pub struct Reconnecting { #[derive(Clone, PartialEq, ::prost::Message)] pub struct Reconnected { } +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] +#[repr(i32)] +pub enum IceTransportPolicy { + TransportNone = 0, + TransportRelay = 1, + TransportNohost = 2, + TransportAll = 3, +} +impl IceTransportPolicy { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + IceTransportPolicy::TransportNone => "TRANSPORT_NONE", + IceTransportPolicy::TransportRelay => "TRANSPORT_RELAY", + IceTransportPolicy::TransportNohost => "TRANSPORT_NOHOST", + IceTransportPolicy::TransportAll => "TRANSPORT_ALL", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "TRANSPORT_NONE" => Some(Self::TransportNone), + "TRANSPORT_RELAY" => Some(Self::TransportRelay), + "TRANSPORT_NOHOST" => Some(Self::TransportNohost), + "TRANSPORT_ALL" => Some(Self::TransportAll), + _ => None, + } + } +} // // Room // diff --git a/livekit-webrtc/src/native/frame_cryptor.rs b/livekit-webrtc/src/native/frame_cryptor.rs index 668206e7..18191a5a 100644 --- a/livekit-webrtc/src/native/frame_cryptor.rs +++ b/livekit-webrtc/src/native/frame_cryptor.rs @@ -3,6 +3,7 @@ use parking_lot::Mutex; use std::sync::Arc; use webrtc_sys::frame_cryptor::{self as sys_fc}; +use crate::peer_connection_factory::PeerConnectionFactory; use crate::{rtp_receiver::RtpReceiver, rtp_sender::RtpSender}; pub type OnStateChange = Box; @@ -12,7 +13,7 @@ pub struct KeyProviderOptions { pub shared_key: bool, pub ratchet_window_size: i32, pub ratchet_salt: Vec, - pub uncrypted_magic_bytes: Vec, + pub failure_tolerance: i32, } #[derive(Debug, Clone, Copy, PartialEq, Eq)] @@ -67,6 +68,10 @@ impl KeyProvider { pub fn get_key(&self, participant_id: String, key_index: i32) -> Option> { self.sys_handle.get_key(participant_id, key_index).ok() } + + pub fn set_sif_trailer(&self, trailer: Vec) { + self.sys_handle.set_sif_trailer(trailer); + } } #[derive(Clone)] @@ -77,6 +82,7 @@ pub struct FrameCryptor { impl FrameCryptor { pub fn new_for_rtp_sender( + peer_factory: &PeerConnectionFactory, participant_id: String, algorithm: EncryptionAlgorithm, key_provider: KeyProvider, @@ -84,6 +90,7 @@ impl FrameCryptor { ) -> Self { let observer = Arc::new(RtcFrameCryptorObserver::default()); let sys_handle = sys_fc::ffi::new_frame_cryptor_for_rtp_sender( + peer_factory.handle.sys_handle.clone(), participant_id, algorithm.into(), key_provider.sys_handle, @@ -101,6 +108,7 @@ impl FrameCryptor { } pub fn new_for_rtp_receiver( + peer_factory: &PeerConnectionFactory, participant_id: String, algorithm: EncryptionAlgorithm, key_provider: KeyProvider, @@ -108,6 +116,7 @@ impl FrameCryptor { ) -> Self { let observer = Arc::new(RtcFrameCryptorObserver::default()); let sys_handle = sys_fc::ffi::new_frame_cryptor_for_rtp_receiver( + peer_factory.handle.sys_handle.clone(), participant_id, algorithm.into(), key_provider.sys_handle, @@ -207,7 +216,7 @@ impl From for sys_fc::ffi::KeyProviderOptions { shared_key: value.shared_key, ratchet_window_size: value.ratchet_window_size, ratchet_salt: value.ratchet_salt, - uncrypted_magic_bytes: value.uncrypted_magic_bytes, + failure_tolerance: value.failure_tolerance, } } } diff --git a/livekit-webrtc/src/native/peer_connection_factory.rs b/livekit-webrtc/src/native/peer_connection_factory.rs index ecc8f299..a9c5db71 100644 --- a/livekit-webrtc/src/native/peer_connection_factory.rs +++ b/livekit-webrtc/src/native/peer_connection_factory.rs @@ -40,7 +40,7 @@ lazy_static! { #[derive(Clone)] pub struct PeerConnectionFactory { - sys_handle: SharedPtr, + pub(crate) sys_handle: SharedPtr, } impl Default for PeerConnectionFactory { diff --git a/livekit/src/room/e2ee/key_provider.rs b/livekit/src/room/e2ee/key_provider.rs index 0c56335d..d6cfe256 100644 --- a/livekit/src/room/e2ee/key_provider.rs +++ b/livekit/src/room/e2ee/key_provider.rs @@ -17,14 +17,14 @@ use livekit_webrtc::native::frame_cryptor as fc; use crate::id::ParticipantIdentity; const DEFAULT_RATCHET_SALT: &str = "LKFrameEncryptionKey"; -const DEFAULT_MAGIC_BYTES: &str = "LK-ROCKS"; const DEFAULT_RATCHET_WINDOW_SIZE: i32 = 16; +const DEFAULT_FAILURE_TOLERANCE: i32 = -1; // no tolerance by default #[derive(Clone)] pub struct KeyProviderOptions { pub ratchet_window_size: i32, pub ratchet_salt: Vec, - pub uncrypted_magic_bytes: Vec, + pub failure_tolerance: i32, } impl Default for KeyProviderOptions { @@ -32,7 +32,7 @@ impl Default for KeyProviderOptions { Self { ratchet_window_size: DEFAULT_RATCHET_WINDOW_SIZE, ratchet_salt: DEFAULT_RATCHET_SALT.to_owned().into_bytes(), - uncrypted_magic_bytes: DEFAULT_MAGIC_BYTES.to_owned().into_bytes(), + failure_tolerance: DEFAULT_FAILURE_TOLERANCE, } } } @@ -50,7 +50,7 @@ impl KeyProvider { shared_key: false, ratchet_window_size: options.ratchet_window_size, ratchet_salt: options.ratchet_salt, - uncrypted_magic_bytes: options.uncrypted_magic_bytes, + failure_tolerance: options.failure_tolerance, }), } } @@ -60,7 +60,7 @@ impl KeyProvider { shared_key: true, ratchet_window_size: options.ratchet_window_size, ratchet_salt: options.ratchet_salt, - uncrypted_magic_bytes: options.uncrypted_magic_bytes, + failure_tolerance: options.failure_tolerance, }); handle.set_shared_key(0, shared_key); Self { handle } @@ -89,4 +89,8 @@ impl KeyProvider { pub fn get_key(&self, identity: &ParticipantIdentity, key_index: i32) -> Option> { self.handle.get_key(identity.to_string(), key_index) } + + pub fn set_sif_trailer(&self, trailer: Vec) { + self.handle.set_sif_trailer(trailer); + } } diff --git a/livekit/src/room/e2ee/manager.rs b/livekit/src/room/e2ee/manager.rs index ae271f5a..ee2ece37 100644 --- a/livekit/src/room/e2ee/manager.rs +++ b/livekit/src/room/e2ee/manager.rs @@ -18,6 +18,7 @@ use crate::e2ee::E2eeOptions; use crate::id::{ParticipantIdentity, TrackSid}; use crate::participant::{LocalParticipant, RemoteParticipant}; use crate::prelude::{LocalTrack, LocalTrackPublication, RemoteTrack, RemoteTrackPublication}; +use crate::rtc_engine::lk_runtime::LkRuntime; use livekit_webrtc::native::frame_cryptor::{EncryptionAlgorithm, EncryptionState, FrameCryptor}; use livekit_webrtc::{rtp_receiver::RtpReceiver, rtp_sender::RtpSender}; use parking_lot::Mutex; @@ -194,6 +195,7 @@ impl E2eeManager { let options = inner.options.as_ref().unwrap(); let frame_cryptor = FrameCryptor::new_for_rtp_sender( + LkRuntime::instance().pc_factory(), participant_identity.to_string(), EncryptionAlgorithm::AesGcm, options.key_provider.handle.clone(), @@ -212,6 +214,7 @@ impl E2eeManager { let options = inner.options.as_ref().unwrap(); let frame_cryptor = FrameCryptor::new_for_rtp_receiver( + LkRuntime::instance().pc_factory(), participant_identity.to_string(), EncryptionAlgorithm::AesGcm, options.key_provider.handle.clone(), diff --git a/livekit/src/room/mod.rs b/livekit/src/room/mod.rs index c58e85f8..57baf5bf 100644 --- a/livekit/src/room/mod.rs +++ b/livekit/src/room/mod.rs @@ -202,6 +202,10 @@ impl Room { let rtc_engine = Arc::new(rtc_engine); let join_response = rtc_engine.last_info().join_response; + if let Some(key_provider) = e2ee_manager.key_provider() { + key_provider.set_sif_trailer(join_response.sif_trailer); + } + let pi = join_response.participant.unwrap(); let local_participant = LocalParticipant::new( rtc_engine.clone(), diff --git a/webrtc-sys/build/src/lib.rs b/webrtc-sys/build/src/lib.rs index d938c4bd..98e5f8c9 100644 --- a/webrtc-sys/build/src/lib.rs +++ b/webrtc-sys/build/src/lib.rs @@ -26,7 +26,7 @@ use regex::Regex; use reqwest::StatusCode; pub const SCRATH_PATH: &str = "livekit_webrtc"; -pub const WEBRTC_TAG: &str = "webrtc-fcdef0d"; +pub const WEBRTC_TAG: &str = "webrtc-0649214"; pub const IGNORE_DEFINES: [&str; 2] = ["CR_CLANG_REVISION", "CR_XCODE_VERSION"]; pub fn target_os() -> String { diff --git a/webrtc-sys/include/livekit/frame_cryptor.h b/webrtc-sys/include/livekit/frame_cryptor.h index 668dbe62..2775bd73 100644 --- a/webrtc-sys/include/livekit/frame_cryptor.h +++ b/webrtc-sys/include/livekit/frame_cryptor.h @@ -23,8 +23,11 @@ #include #include "api/crypto/frame_crypto_transformer.h" +#include "api/scoped_refptr.h" +#include "livekit/peer_connection.h" #include "livekit/rtp_receiver.h" #include "livekit/rtp_sender.h" +#include "livekit/webrtc.h" #include "rtc_base/synchronization/mutex.h" #include "rust/cxx.h" @@ -106,6 +109,12 @@ class KeyProvider { return vec; } + void set_sif_trailer(rust::Vec<::std::uint8_t> trailer) const { + std::vector trailer_vec; + std::copy(trailer.begin(), trailer.end(), std::back_inserter(trailer_vec)); + impl_->SetSifTrailer(trailer_vec); + } + rtc::scoped_refptr rtc_key_provider() { return impl_; } private: @@ -114,12 +123,14 @@ class KeyProvider { class FrameCryptor { public: - FrameCryptor(const std::string participant_id, + FrameCryptor(std::shared_ptr rtc_runtime, + const std::string participant_id, webrtc::FrameCryptorTransformer::Algorithm algorithm, rtc::scoped_refptr key_provider, rtc::scoped_refptr sender); - FrameCryptor(const std::string participant_id, + FrameCryptor(std::shared_ptr rtc_runtime, + const std::string participant_id, webrtc::FrameCryptorTransformer::Algorithm algorithm, rtc::scoped_refptr key_provider, rtc::scoped_refptr receiver); @@ -146,13 +157,14 @@ class FrameCryptor { void unregister_observer() const; private: + std::shared_ptr rtc_runtime_; const rust::String participant_id_; mutable webrtc::Mutex mutex_; rtc::scoped_refptr e2ee_transformer_; rtc::scoped_refptr key_provider_; rtc::scoped_refptr sender_; rtc::scoped_refptr receiver_; - mutable std::unique_ptr observer_; + mutable rtc::scoped_refptr observer_; }; class NativeFrameCryptorObserver @@ -171,12 +183,14 @@ class NativeFrameCryptorObserver }; std::shared_ptr new_frame_cryptor_for_rtp_sender( + std::shared_ptr peer_factory, const ::rust::String participant_id, Algorithm algorithm, std::shared_ptr key_provider, std::shared_ptr sender); std::shared_ptr new_frame_cryptor_for_rtp_receiver( + std::shared_ptr peer_factory, const ::rust::String participant_id, Algorithm algorithm, std::shared_ptr key_provider, diff --git a/webrtc-sys/include/livekit/peer_connection_factory.h b/webrtc-sys/include/livekit/peer_connection_factory.h index 199a0129..f4b351fb 100644 --- a/webrtc-sys/include/livekit/peer_connection_factory.h +++ b/webrtc-sys/include/livekit/peer_connection_factory.h @@ -56,6 +56,8 @@ class PeerConnectionFactory { RtpCapabilities rtp_receiver_capabilities(MediaType type) const; + std::shared_ptr rtc_runtime() const { return rtc_runtime_; } + private: std::shared_ptr rtc_runtime_; rtc::scoped_refptr audio_device_; diff --git a/webrtc-sys/src/frame_cryptor.cpp b/webrtc-sys/src/frame_cryptor.cpp index a3494e1d..eca5ec8a 100644 --- a/webrtc-sys/src/frame_cryptor.cpp +++ b/webrtc-sys/src/frame_cryptor.cpp @@ -19,6 +19,11 @@ #include #include "absl/types/optional.h" +#include "api/make_ref_counted.h" +#include "livekit/peer_connection.h" +#include "livekit/peer_connection_factory.h" +#include "livekit/webrtc.h" +#include "rtc_base/thread.h" #include "webrtc-sys/src/frame_cryptor.rs.h" namespace livekit { @@ -44,24 +49,21 @@ KeyProvider::KeyProvider(KeyProviderOptions options) { std::back_inserter(ratchet_salt)); rtc_options.ratchet_salt = ratchet_salt; - - std::vector uncrypted_magic_bytes; - std::copy(options.uncrypted_magic_bytes.begin(), - options.uncrypted_magic_bytes.end(), - std::back_inserter(uncrypted_magic_bytes)); - - rtc_options.uncrypted_magic_bytes = uncrypted_magic_bytes; rtc_options.ratchet_window_size = options.ratchet_window_size; + rtc_options.failure_tolerance = options.failure_tolerance; + impl_ = new rtc::RefCountedObject(rtc_options); } FrameCryptor::FrameCryptor( + std::shared_ptr rtc_runtime, const std::string participant_id, webrtc::FrameCryptorTransformer::Algorithm algorithm, rtc::scoped_refptr key_provider, rtc::scoped_refptr sender) - : participant_id_(participant_id), + : rtc_runtime_(rtc_runtime), + participant_id_(participant_id), key_provider_(key_provider), sender_(sender) { auto mediaType = @@ -69,18 +71,21 @@ FrameCryptor::FrameCryptor( ? webrtc::FrameCryptorTransformer::MediaType::kAudioFrame : webrtc::FrameCryptorTransformer::MediaType::kVideoFrame; e2ee_transformer_ = rtc::scoped_refptr( - new webrtc::FrameCryptorTransformer(participant_id, mediaType, algorithm, + new webrtc::FrameCryptorTransformer(rtc_runtime->signaling_thread(), + participant_id, mediaType, algorithm, key_provider_)); sender->SetEncoderToPacketizerFrameTransformer(e2ee_transformer_); e2ee_transformer_->SetEnabled(false); } FrameCryptor::FrameCryptor( + std::shared_ptr rtc_runtime, const std::string participant_id, webrtc::FrameCryptorTransformer::Algorithm algorithm, rtc::scoped_refptr key_provider, rtc::scoped_refptr receiver) - : participant_id_(participant_id), + : rtc_runtime_(rtc_runtime), + participant_id_(participant_id), key_provider_(key_provider), receiver_(receiver) { auto mediaType = @@ -88,26 +93,31 @@ FrameCryptor::FrameCryptor( ? webrtc::FrameCryptorTransformer::MediaType::kAudioFrame : webrtc::FrameCryptorTransformer::MediaType::kVideoFrame; e2ee_transformer_ = rtc::scoped_refptr( - new webrtc::FrameCryptorTransformer(participant_id, mediaType, algorithm, + new webrtc::FrameCryptorTransformer(rtc_runtime->signaling_thread(), + participant_id, mediaType, algorithm, key_provider_)); receiver->SetDepacketizerToDecoderFrameTransformer(e2ee_transformer_); e2ee_transformer_->SetEnabled(false); } -FrameCryptor::~FrameCryptor() {} +FrameCryptor::~FrameCryptor() { + if (observer_) { + unregister_observer(); + } +} void FrameCryptor::register_observer( rust::Box observer) const { webrtc::MutexLock lock(&mutex_); - observer_ = - std::make_unique(std::move(observer), this); - e2ee_transformer_->SetFrameCryptorTransformerObserver(observer_.get()); + observer_ = rtc::make_ref_counted( + std::move(observer), this); + e2ee_transformer_->RegisterFrameCryptorTransformerObserver(observer_); } void FrameCryptor::unregister_observer() const { webrtc::MutexLock lock(&mutex_); observer_ = nullptr; - e2ee_transformer_->SetFrameCryptorTransformerObserver(nullptr); + e2ee_transformer_->UnRegisterFrameCryptorTransformerObserver(); } NativeFrameCryptorObserver::NativeFrameCryptorObserver( @@ -115,9 +125,7 @@ NativeFrameCryptorObserver::NativeFrameCryptorObserver( const FrameCryptor* fc) : observer_(std::move(observer)), fc_(fc) {} -NativeFrameCryptorObserver::~NativeFrameCryptorObserver() { - fc_->unregister_observer(); -} +NativeFrameCryptorObserver::~NativeFrameCryptorObserver() {} void NativeFrameCryptorObserver::OnFrameCryptionStateChanged( const std::string participant_id, @@ -151,22 +159,26 @@ std::shared_ptr new_key_provider(KeyProviderOptions options) { } std::shared_ptr new_frame_cryptor_for_rtp_sender( + std::shared_ptr peer_factory, const ::rust::String participant_id, Algorithm algorithm, std::shared_ptr key_provider, std::shared_ptr sender) { return std::make_shared( + peer_factory->rtc_runtime(), std::string(participant_id.data(), participant_id.size()), AlgorithmToFrameCryptorAlgorithm(algorithm), key_provider->rtc_key_provider(), sender->rtc_sender()); } std::shared_ptr new_frame_cryptor_for_rtp_receiver( + std::shared_ptr peer_factory, const ::rust::String participant_id, Algorithm algorithm, std::shared_ptr key_provider, std::shared_ptr receiver) { return std::make_shared( + peer_factory->rtc_runtime(), std::string(participant_id.data(), participant_id.size()), AlgorithmToFrameCryptorAlgorithm(algorithm), key_provider->rtc_key_provider(), receiver->rtc_receiver()); diff --git a/webrtc-sys/src/frame_cryptor.rs b/webrtc-sys/src/frame_cryptor.rs index 888a1011..3210d5ca 100644 --- a/webrtc-sys/src/frame_cryptor.rs +++ b/webrtc-sys/src/frame_cryptor.rs @@ -24,7 +24,7 @@ pub mod ffi { pub shared_key: bool, pub ratchet_window_size: i32, pub ratchet_salt: Vec, - pub uncrypted_magic_bytes: Vec, + pub failure_tolerance: i32, } #[derive(Debug)] @@ -59,6 +59,8 @@ pub mod ffi { pub fn get_shared_key(self: &KeyProvider, key_index: i32) -> Result>; + pub fn set_sif_trailer(&self, trailer: Vec); + pub fn set_key( self: &KeyProvider, participant_id: String, @@ -83,13 +85,16 @@ pub mod ffi { include!("livekit/frame_cryptor.h"); include!("livekit/rtp_sender.h"); include!("livekit/rtp_receiver.h"); + include!("livekit/peer_connection_factory.h"); type RtpSender = crate::rtp_sender::ffi::RtpSender; type RtpReceiver = crate::rtp_receiver::ffi::RtpReceiver; + type PeerConnectionFactory = crate::peer_connection_factory::ffi::PeerConnectionFactory; pub type FrameCryptor; pub fn new_frame_cryptor_for_rtp_sender( + peer_factory: SharedPtr, participant_id: String, algorithm: Algorithm, key_provider: SharedPtr, @@ -97,6 +102,7 @@ pub mod ffi { ) -> SharedPtr; pub fn new_frame_cryptor_for_rtp_receiver( + peer_factory: SharedPtr, participant_id: String, algorithm: Algorithm, key_provider: SharedPtr,