From f95e50737eba30f7ebe1a57072d39524168aae86 Mon Sep 17 00:00:00 2001 From: lukasIO Date: Tue, 10 Dec 2024 13:29:11 +0100 Subject: [PATCH 01/18] update protocol and streams boilerplate --- livekit-api/src/services/sip.rs | 14 + livekit-ffi/protocol/room.proto | 6 + livekit-ffi/src/conversion/room.rs | 8 +- livekit-ffi/src/livekit.proto.rs | 829 ++++--- livekit-protocol/protocol | 2 +- livekit-protocol/src/livekit.rs | 342 ++- livekit-protocol/src/livekit.serde.rs | 2966 ++++++++++++++++++++----- livekit/src/room/mod.rs | 45 + livekit/src/rtc_engine/mod.rs | 48 + livekit/src/rtc_engine/rtc_session.rs | 36 +- 10 files changed, 3436 insertions(+), 860 deletions(-) diff --git a/livekit-api/src/services/sip.rs b/livekit-api/src/services/sip.rs index e2517be9..1efd5929 100644 --- a/livekit-api/src/services/sip.rs +++ b/livekit-api/src/services/sip.rs @@ -129,6 +129,9 @@ pub struct CreateSIPParticipantOptions { /// Optionally play ringtone in the room as an audible indicator for existing participants pub play_ringtone: bool, pub hide_phone_number: bool, + pub enable_krisp: bool, + pub max_call_duration: i32, + pub play_dialtone: bool, } impl SIPClient { @@ -202,6 +205,10 @@ impl SIPClient { headers: Default::default(), headers_to_attributes: Default::default(), + krisp_enabled: Default::default(), + attributes_to_headers: Default::default(), + ringing_timeout: Default::default(), + max_call_duration: Default::default(), }), }, self.base.auth_header( @@ -238,6 +245,7 @@ impl SIPClient { headers: Default::default(), headers_to_attributes: Default::default(), + attributes_to_headers: Default::default(), }), }, self.base.auth_header( @@ -414,6 +422,12 @@ impl SIPClient { dtmf: options.dtmf.to_owned(), play_ringtone: options.play_ringtone, hide_phone_number: options.hide_phone_number, + + enable_krisp: Default::default(), + sip_number: Default::default(), + play_dialtone: Default::default(), + ringing_timeout: Default::default(), + max_call_duration: Default::default(), }, self.base.auth_header( Default::default(), diff --git a/livekit-ffi/protocol/room.proto b/livekit-ffi/protocol/room.proto index edae5c00..4a131226 100644 --- a/livekit-ffi/protocol/room.proto +++ b/livekit-ffi/protocol/room.proto @@ -338,6 +338,12 @@ enum DisconnectReason { SIGNAL_CLOSE = 9; // the room was closed, due to all Standard and Ingress participants having left ROOM_CLOSED = 10; + /// SIP callee did not respond in time + UserUnavailable = 11; + /// SIP callee rejected the call (busy) + UserRejected = 12; + /// SIP protocol failure or unexpected response + SipTrunkFailure = 13; } message TranscriptionSegment { diff --git a/livekit-ffi/src/conversion/room.rs b/livekit-ffi/src/conversion/room.rs index 2dc32170..0e2c65c4 100644 --- a/livekit-ffi/src/conversion/room.rs +++ b/livekit-ffi/src/conversion/room.rs @@ -12,7 +12,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::{proto, server::room::FfiRoom}; +use crate::{ + proto::{self, DisposeCallback}, + server::room::FfiRoom, +}; use livekit::{ e2ee::{ key_provider::{KeyProvider, KeyProviderOptions}, @@ -95,6 +98,9 @@ impl From for proto::DisconnectReason { DisconnectReason::Migration => Self::Migration, DisconnectReason::SignalClose => Self::SignalClose, DisconnectReason::RoomClosed => Self::RoomClosed, + DisconnectReason::SipTrunkFailure => Self::SipTrunkFailure, + DisconnectReason::UserRejected => Self::UserRejected, + DisconnectReason::UserUnavailable => Self::UserUnavailable, } } } diff --git a/livekit-ffi/src/livekit.proto.rs b/livekit-ffi/src/livekit.proto.rs index 077dc4ae..10efaab6 100644 --- a/livekit-ffi/src/livekit.proto.rs +++ b/livekit-ffi/src/livekit.proto.rs @@ -1,5 +1,6 @@ // @generated // This file is @generated by prost-build. +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct FrameCryptor { #[prost(string, required, tag="1")] @@ -11,6 +12,7 @@ pub struct FrameCryptor { #[prost(bool, required, tag="4")] pub enabled: bool, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct KeyProviderOptions { /// Only specify if you want to use a shared_key @@ -24,6 +26,7 @@ pub struct KeyProviderOptions { #[prost(int32, required, tag="4")] pub failure_tolerance: i32, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct E2eeOptions { #[prost(enumeration="EncryptionType", required, tag="1")] @@ -31,22 +34,27 @@ pub struct E2eeOptions { #[prost(message, required, tag="2")] pub key_provider_options: KeyProviderOptions, } -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct E2eeManagerSetEnabledRequest { #[prost(bool, required, tag="1")] pub enabled: bool, } -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct E2eeManagerSetEnabledResponse { } -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct E2eeManagerGetFrameCryptorsRequest { } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct E2eeManagerGetFrameCryptorsResponse { #[prost(message, repeated, tag="1")] pub frame_cryptors: ::prost::alloc::vec::Vec, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct FrameCryptorSetEnabledRequest { #[prost(string, required, tag="1")] @@ -56,9 +64,11 @@ pub struct FrameCryptorSetEnabledRequest { #[prost(bool, required, tag="3")] pub enabled: bool, } -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct FrameCryptorSetEnabledResponse { } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct FrameCryptorSetKeyIndexRequest { #[prost(string, required, tag="1")] @@ -68,9 +78,11 @@ pub struct FrameCryptorSetKeyIndexRequest { #[prost(int32, required, tag="3")] pub key_index: i32, } -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct FrameCryptorSetKeyIndexResponse { } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct SetSharedKeyRequest { #[prost(bytes="vec", required, tag="1")] @@ -78,29 +90,35 @@ pub struct SetSharedKeyRequest { #[prost(int32, required, tag="2")] pub key_index: i32, } -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct SetSharedKeyResponse { } -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct RatchetSharedKeyRequest { #[prost(int32, required, tag="1")] pub key_index: i32, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct RatchetSharedKeyResponse { #[prost(bytes="vec", optional, tag="1")] pub new_key: ::core::option::Option<::prost::alloc::vec::Vec>, } -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct GetSharedKeyRequest { #[prost(int32, required, tag="1")] pub key_index: i32, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct GetSharedKeyResponse { #[prost(bytes="vec", optional, tag="1")] pub key: ::core::option::Option<::prost::alloc::vec::Vec>, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct SetKeyRequest { #[prost(string, required, tag="1")] @@ -110,9 +128,11 @@ pub struct SetKeyRequest { #[prost(int32, required, tag="3")] pub key_index: i32, } -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct SetKeyResponse { } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct RatchetKeyRequest { #[prost(string, required, tag="1")] @@ -120,11 +140,13 @@ pub struct RatchetKeyRequest { #[prost(int32, required, tag="2")] pub key_index: i32, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct RatchetKeyResponse { #[prost(bytes="vec", optional, tag="1")] pub new_key: ::core::option::Option<::prost::alloc::vec::Vec>, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct GetKeyRequest { #[prost(string, required, tag="1")] @@ -132,11 +154,13 @@ pub struct GetKeyRequest { #[prost(int32, required, tag="2")] pub key_index: i32, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct GetKeyResponse { #[prost(bytes="vec", optional, tag="1")] pub key: ::core::option::Option<::prost::alloc::vec::Vec>, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct E2eeRequest { #[prost(uint64, required, tag="1")] @@ -146,7 +170,8 @@ pub struct E2eeRequest { } /// Nested message and enum types in `E2eeRequest`. pub mod e2ee_request { - #[derive(Clone, PartialEq, ::prost::Oneof)] + #[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Oneof)] pub enum Message { #[prost(message, tag="2")] ManagerSetEnabled(super::E2eeManagerSetEnabledRequest), @@ -170,6 +195,7 @@ pub mod e2ee_request { GetKey(super::GetKeyRequest), } } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct E2eeResponse { #[prost(oneof="e2ee_response::Message", tags="1, 2, 3, 4, 5, 6, 7, 8, 9, 10")] @@ -177,7 +203,8 @@ pub struct E2eeResponse { } /// Nested message and enum types in `E2eeResponse`. pub mod e2ee_response { - #[derive(Clone, PartialEq, ::prost::Oneof)] + #[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Oneof)] pub enum Message { #[prost(message, tag="1")] ManagerSetEnabled(super::E2eeManagerSetEnabledResponse), @@ -217,9 +244,9 @@ impl EncryptionType { /// (if the ProtoBuf definition does not change) and safe for programmatic use. pub fn as_str_name(&self) -> &'static str { match self { - Self::None => "NONE", - Self::Gcm => "GCM", - Self::Custom => "CUSTOM", + EncryptionType::None => "NONE", + EncryptionType::Gcm => "GCM", + EncryptionType::Custom => "CUSTOM", } } /// Creates an enum from field names used in the ProtoBuf definition. @@ -250,13 +277,13 @@ impl EncryptionState { /// (if the ProtoBuf definition does not change) and safe for programmatic use. pub fn as_str_name(&self) -> &'static str { match self { - Self::New => "NEW", - Self::Ok => "OK", - Self::EncryptionFailed => "ENCRYPTION_FAILED", - Self::DecryptionFailed => "DECRYPTION_FAILED", - Self::MissingKey => "MISSING_KEY", - Self::KeyRatcheted => "KEY_RATCHETED", - Self::InternalError => "INTERNAL_ERROR", + EncryptionState::New => "NEW", + EncryptionState::Ok => "OK", + EncryptionState::EncryptionFailed => "ENCRYPTION_FAILED", + EncryptionState::DecryptionFailed => "DECRYPTION_FAILED", + EncryptionState::MissingKey => "MISSING_KEY", + EncryptionState::KeyRatcheted => "KEY_RATCHETED", + EncryptionState::InternalError => "INTERNAL_ERROR", } } /// Creates an enum from field names used in the ProtoBuf definition. @@ -282,11 +309,13 @@ impl EncryptionState { /// /// When refering to a handle without owning it, we just use a uint32 without this message. /// (the variable name is suffixed with "_handle") -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct FfiOwnedHandle { #[prost(uint64, required, tag="1")] pub id: u64, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct RtcStats { #[prost(oneof="rtc_stats::Stats", tags="3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18")] @@ -294,14 +323,16 @@ pub struct RtcStats { } /// Nested message and enum types in `RtcStats`. pub mod rtc_stats { - #[derive(Clone, PartialEq, ::prost::Message)] + #[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct Codec { #[prost(message, required, tag="1")] pub rtc: super::RtcStatsData, #[prost(message, required, tag="2")] pub codec: super::CodecStats, } - #[derive(Clone, PartialEq, ::prost::Message)] + #[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct InboundRtp { #[prost(message, required, tag="1")] pub rtc: super::RtcStatsData, @@ -312,7 +343,8 @@ pub mod rtc_stats { #[prost(message, required, tag="4")] pub inbound: super::InboundRtpStreamStats, } - #[derive(Clone, PartialEq, ::prost::Message)] + #[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct OutboundRtp { #[prost(message, required, tag="1")] pub rtc: super::RtcStatsData, @@ -323,7 +355,8 @@ pub mod rtc_stats { #[prost(message, required, tag="4")] pub outbound: super::OutboundRtpStreamStats, } - #[derive(Clone, PartialEq, ::prost::Message)] + #[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct RemoteInboundRtp { #[prost(message, required, tag="1")] pub rtc: super::RtcStatsData, @@ -334,7 +367,8 @@ pub mod rtc_stats { #[prost(message, required, tag="4")] pub remote_inbound: super::RemoteInboundRtpStreamStats, } - #[derive(Clone, PartialEq, ::prost::Message)] + #[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct RemoteOutboundRtp { #[prost(message, required, tag="1")] pub rtc: super::RtcStatsData, @@ -345,7 +379,8 @@ pub mod rtc_stats { #[prost(message, required, tag="4")] pub remote_outbound: super::RemoteOutboundRtpStreamStats, } - #[derive(Clone, PartialEq, ::prost::Message)] + #[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct MediaSource { #[prost(message, required, tag="1")] pub rtc: super::RtcStatsData, @@ -356,63 +391,72 @@ pub mod rtc_stats { #[prost(message, required, tag="4")] pub video: super::VideoSourceStats, } - #[derive(Clone, PartialEq, ::prost::Message)] + #[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct MediaPlayout { #[prost(message, required, tag="1")] pub rtc: super::RtcStatsData, #[prost(message, required, tag="2")] pub audio_playout: super::AudioPlayoutStats, } - #[derive(Clone, PartialEq, ::prost::Message)] + #[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct PeerConnection { #[prost(message, required, tag="1")] pub rtc: super::RtcStatsData, #[prost(message, required, tag="2")] pub pc: super::PeerConnectionStats, } - #[derive(Clone, PartialEq, ::prost::Message)] + #[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct DataChannel { #[prost(message, required, tag="1")] pub rtc: super::RtcStatsData, #[prost(message, required, tag="2")] pub dc: super::DataChannelStats, } - #[derive(Clone, PartialEq, ::prost::Message)] + #[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct Transport { #[prost(message, required, tag="1")] pub rtc: super::RtcStatsData, #[prost(message, required, tag="2")] pub transport: super::TransportStats, } - #[derive(Clone, PartialEq, ::prost::Message)] + #[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct CandidatePair { #[prost(message, required, tag="1")] pub rtc: super::RtcStatsData, #[prost(message, required, tag="2")] pub candidate_pair: super::CandidatePairStats, } - #[derive(Clone, PartialEq, ::prost::Message)] + #[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct LocalCandidate { #[prost(message, required, tag="1")] pub rtc: super::RtcStatsData, #[prost(message, required, tag="2")] pub candidate: super::IceCandidateStats, } - #[derive(Clone, PartialEq, ::prost::Message)] + #[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct RemoteCandidate { #[prost(message, required, tag="1")] pub rtc: super::RtcStatsData, #[prost(message, required, tag="2")] pub candidate: super::IceCandidateStats, } - #[derive(Clone, PartialEq, ::prost::Message)] + #[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct Certificate { #[prost(message, required, tag="1")] pub rtc: super::RtcStatsData, #[prost(message, required, tag="2")] pub certificate: super::CertificateStats, } - #[derive(Clone, PartialEq, ::prost::Message)] + #[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct Stream { #[prost(message, required, tag="1")] pub rtc: super::RtcStatsData, @@ -420,10 +464,12 @@ pub mod rtc_stats { pub stream: super::StreamStats, } /// Deprecated - #[derive(Clone, Copy, PartialEq, ::prost::Message)] + #[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct Track { } - #[derive(Clone, PartialEq, ::prost::Oneof)] + #[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Oneof)] pub enum Stats { #[prost(message, tag="3")] Codec(Codec), @@ -459,6 +505,7 @@ pub mod rtc_stats { Track(Track), } } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct RtcStatsData { #[prost(string, required, tag="1")] @@ -466,6 +513,7 @@ pub struct RtcStatsData { #[prost(int64, required, tag="2")] pub timestamp: i64, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct CodecStats { #[prost(uint32, required, tag="1")] @@ -481,6 +529,7 @@ pub struct CodecStats { #[prost(string, required, tag="6")] pub sdp_fmtp_line: ::prost::alloc::string::String, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct RtpStreamStats { #[prost(uint32, required, tag="1")] @@ -492,7 +541,8 @@ pub struct RtpStreamStats { #[prost(string, required, tag="4")] pub codec_id: ::prost::alloc::string::String, } -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct ReceivedRtpStreamStats { #[prost(uint64, required, tag="1")] pub packets_received: u64, @@ -501,6 +551,7 @@ pub struct ReceivedRtpStreamStats { #[prost(double, required, tag="3")] pub jitter: f64, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct InboundRtpStreamStats { #[prost(string, required, tag="1")] @@ -610,13 +661,15 @@ pub struct InboundRtpStreamStats { #[prost(uint32, required, tag="53")] pub fec_ssrc: u32, } -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct SentRtpStreamStats { #[prost(uint64, required, tag="1")] pub packets_sent: u64, #[prost(uint64, required, tag="2")] pub bytes_sent: u64, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct OutboundRtpStreamStats { #[prost(string, required, tag="1")] @@ -680,6 +733,7 @@ pub struct OutboundRtpStreamStats { #[prost(string, required, tag="30")] pub scalability_mode: ::prost::alloc::string::String, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct RemoteInboundRtpStreamStats { #[prost(string, required, tag="1")] @@ -693,6 +747,7 @@ pub struct RemoteInboundRtpStreamStats { #[prost(uint64, required, tag="5")] pub round_trip_time_measurements: u64, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct RemoteOutboundRtpStreamStats { #[prost(string, required, tag="1")] @@ -708,6 +763,7 @@ pub struct RemoteOutboundRtpStreamStats { #[prost(uint64, required, tag="6")] pub round_trip_time_measurements: u64, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct MediaSourceStats { #[prost(string, required, tag="1")] @@ -715,7 +771,8 @@ pub struct MediaSourceStats { #[prost(string, required, tag="2")] pub kind: ::prost::alloc::string::String, } -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct AudioSourceStats { #[prost(double, required, tag="1")] pub audio_level: f64, @@ -736,7 +793,8 @@ pub struct AudioSourceStats { #[prost(uint64, required, tag="9")] pub total_samples_captured: u64, } -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct VideoSourceStats { #[prost(uint32, required, tag="1")] pub width: u32, @@ -747,6 +805,7 @@ pub struct VideoSourceStats { #[prost(double, required, tag="4")] pub frames_per_second: f64, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct AudioPlayoutStats { #[prost(string, required, tag="1")] @@ -762,13 +821,15 @@ pub struct AudioPlayoutStats { #[prost(uint64, required, tag="6")] pub total_samples_count: u64, } -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct PeerConnectionStats { #[prost(uint32, required, tag="1")] pub data_channels_opened: u32, #[prost(uint32, required, tag="2")] pub data_channels_closed: u32, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct DataChannelStats { #[prost(string, required, tag="1")] @@ -788,6 +849,7 @@ pub struct DataChannelStats { #[prost(uint64, required, tag="8")] pub bytes_received: u64, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct TransportStats { #[prost(uint64, required, tag="1")] @@ -823,6 +885,7 @@ pub struct TransportStats { #[prost(uint32, required, tag="16")] pub selected_candidate_pair_changes: u32, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct CandidatePairStats { #[prost(string, required, tag="1")] @@ -870,6 +933,7 @@ pub struct CandidatePairStats { #[prost(uint64, required, tag="22")] pub bytes_discarded_on_send: u64, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct IceCandidateStats { #[prost(string, required, tag="1")] @@ -899,6 +963,7 @@ pub struct IceCandidateStats { #[prost(enumeration="IceTcpCandidateType", optional, tag="13")] pub tcp_type: ::core::option::Option, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct CertificateStats { #[prost(string, required, tag="1")] @@ -910,6 +975,7 @@ pub struct CertificateStats { #[prost(string, required, tag="4")] pub issuer_certificate_id: ::prost::alloc::string::String, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct StreamStats { #[prost(string, required, tag="1")] @@ -933,10 +999,10 @@ impl DataChannelState { /// (if the ProtoBuf definition does not change) and safe for programmatic use. pub fn as_str_name(&self) -> &'static str { match self { - Self::DcConnecting => "DC_CONNECTING", - Self::DcOpen => "DC_OPEN", - Self::DcClosing => "DC_CLOSING", - Self::DcClosed => "DC_CLOSED", + DataChannelState::DcConnecting => "DC_CONNECTING", + DataChannelState::DcOpen => "DC_OPEN", + DataChannelState::DcClosing => "DC_CLOSING", + DataChannelState::DcClosed => "DC_CLOSED", } } /// Creates an enum from field names used in the ProtoBuf definition. @@ -965,10 +1031,10 @@ impl QualityLimitationReason { /// (if the ProtoBuf definition does not change) and safe for programmatic use. pub fn as_str_name(&self) -> &'static str { match self { - Self::LimitationNone => "LIMITATION_NONE", - Self::LimitationCpu => "LIMITATION_CPU", - Self::LimitationBandwidth => "LIMITATION_BANDWIDTH", - Self::LimitationOther => "LIMITATION_OTHER", + QualityLimitationReason::LimitationNone => "LIMITATION_NONE", + QualityLimitationReason::LimitationCpu => "LIMITATION_CPU", + QualityLimitationReason::LimitationBandwidth => "LIMITATION_BANDWIDTH", + QualityLimitationReason::LimitationOther => "LIMITATION_OTHER", } } /// Creates an enum from field names used in the ProtoBuf definition. @@ -996,9 +1062,9 @@ impl IceRole { /// (if the ProtoBuf definition does not change) and safe for programmatic use. pub fn as_str_name(&self) -> &'static str { match self { - Self::IceUnknown => "ICE_UNKNOWN", - Self::IceControlling => "ICE_CONTROLLING", - Self::IceControlled => "ICE_CONTROLLED", + IceRole::IceUnknown => "ICE_UNKNOWN", + IceRole::IceControlling => "ICE_CONTROLLING", + IceRole::IceControlled => "ICE_CONTROLLED", } } /// Creates an enum from field names used in the ProtoBuf definition. @@ -1027,11 +1093,11 @@ impl DtlsTransportState { /// (if the ProtoBuf definition does not change) and safe for programmatic use. pub fn as_str_name(&self) -> &'static str { match self { - Self::DtlsTransportNew => "DTLS_TRANSPORT_NEW", - Self::DtlsTransportConnecting => "DTLS_TRANSPORT_CONNECTING", - Self::DtlsTransportConnected => "DTLS_TRANSPORT_CONNECTED", - Self::DtlsTransportClosed => "DTLS_TRANSPORT_CLOSED", - Self::DtlsTransportFailed => "DTLS_TRANSPORT_FAILED", + DtlsTransportState::DtlsTransportNew => "DTLS_TRANSPORT_NEW", + DtlsTransportState::DtlsTransportConnecting => "DTLS_TRANSPORT_CONNECTING", + DtlsTransportState::DtlsTransportConnected => "DTLS_TRANSPORT_CONNECTED", + DtlsTransportState::DtlsTransportClosed => "DTLS_TRANSPORT_CLOSED", + DtlsTransportState::DtlsTransportFailed => "DTLS_TRANSPORT_FAILED", } } /// Creates an enum from field names used in the ProtoBuf definition. @@ -1064,13 +1130,13 @@ impl IceTransportState { /// (if the ProtoBuf definition does not change) and safe for programmatic use. pub fn as_str_name(&self) -> &'static str { match self { - Self::IceTransportNew => "ICE_TRANSPORT_NEW", - Self::IceTransportChecking => "ICE_TRANSPORT_CHECKING", - Self::IceTransportConnected => "ICE_TRANSPORT_CONNECTED", - Self::IceTransportCompleted => "ICE_TRANSPORT_COMPLETED", - Self::IceTransportDisconnected => "ICE_TRANSPORT_DISCONNECTED", - Self::IceTransportFailed => "ICE_TRANSPORT_FAILED", - Self::IceTransportClosed => "ICE_TRANSPORT_CLOSED", + IceTransportState::IceTransportNew => "ICE_TRANSPORT_NEW", + IceTransportState::IceTransportChecking => "ICE_TRANSPORT_CHECKING", + IceTransportState::IceTransportConnected => "ICE_TRANSPORT_CONNECTED", + IceTransportState::IceTransportCompleted => "ICE_TRANSPORT_COMPLETED", + IceTransportState::IceTransportDisconnected => "ICE_TRANSPORT_DISCONNECTED", + IceTransportState::IceTransportFailed => "ICE_TRANSPORT_FAILED", + IceTransportState::IceTransportClosed => "ICE_TRANSPORT_CLOSED", } } /// Creates an enum from field names used in the ProtoBuf definition. @@ -1101,9 +1167,9 @@ impl DtlsRole { /// (if the ProtoBuf definition does not change) and safe for programmatic use. pub fn as_str_name(&self) -> &'static str { match self { - Self::DtlsClient => "DTLS_CLIENT", - Self::DtlsServer => "DTLS_SERVER", - Self::DtlsUnknown => "DTLS_UNKNOWN", + DtlsRole::DtlsClient => "DTLS_CLIENT", + DtlsRole::DtlsServer => "DTLS_SERVER", + DtlsRole::DtlsUnknown => "DTLS_UNKNOWN", } } /// Creates an enum from field names used in the ProtoBuf definition. @@ -1132,11 +1198,11 @@ impl IceCandidatePairState { /// (if the ProtoBuf definition does not change) and safe for programmatic use. pub fn as_str_name(&self) -> &'static str { match self { - Self::PairFrozen => "PAIR_FROZEN", - Self::PairWaiting => "PAIR_WAITING", - Self::PairInProgress => "PAIR_IN_PROGRESS", - Self::PairFailed => "PAIR_FAILED", - Self::PairSucceeded => "PAIR_SUCCEEDED", + IceCandidatePairState::PairFrozen => "PAIR_FROZEN", + IceCandidatePairState::PairWaiting => "PAIR_WAITING", + IceCandidatePairState::PairInProgress => "PAIR_IN_PROGRESS", + IceCandidatePairState::PairFailed => "PAIR_FAILED", + IceCandidatePairState::PairSucceeded => "PAIR_SUCCEEDED", } } /// Creates an enum from field names used in the ProtoBuf definition. @@ -1166,10 +1232,10 @@ impl IceCandidateType { /// (if the ProtoBuf definition does not change) and safe for programmatic use. pub fn as_str_name(&self) -> &'static str { match self { - Self::Host => "HOST", - Self::Srflx => "SRFLX", - Self::Prflx => "PRFLX", - Self::Relay => "RELAY", + IceCandidateType::Host => "HOST", + IceCandidateType::Srflx => "SRFLX", + IceCandidateType::Prflx => "PRFLX", + IceCandidateType::Relay => "RELAY", } } /// Creates an enum from field names used in the ProtoBuf definition. @@ -1197,9 +1263,9 @@ impl IceServerTransportProtocol { /// (if the ProtoBuf definition does not change) and safe for programmatic use. pub fn as_str_name(&self) -> &'static str { match self { - Self::TransportUdp => "TRANSPORT_UDP", - Self::TransportTcp => "TRANSPORT_TCP", - Self::TransportTls => "TRANSPORT_TLS", + IceServerTransportProtocol::TransportUdp => "TRANSPORT_UDP", + IceServerTransportProtocol::TransportTcp => "TRANSPORT_TCP", + IceServerTransportProtocol::TransportTls => "TRANSPORT_TLS", } } /// Creates an enum from field names used in the ProtoBuf definition. @@ -1226,9 +1292,9 @@ impl IceTcpCandidateType { /// (if the ProtoBuf definition does not change) and safe for programmatic use. pub fn as_str_name(&self) -> &'static str { match self { - Self::CandidateActive => "CANDIDATE_ACTIVE", - Self::CandidatePassive => "CANDIDATE_PASSIVE", - Self::CandidateSo => "CANDIDATE_SO", + IceTcpCandidateType::CandidateActive => "CANDIDATE_ACTIVE", + IceTcpCandidateType::CandidatePassive => "CANDIDATE_PASSIVE", + IceTcpCandidateType::CandidateSo => "CANDIDATE_SO", } } /// Creates an enum from field names used in the ProtoBuf definition. @@ -1242,6 +1308,7 @@ impl IceTcpCandidateType { } } /// Create a new VideoTrack from a VideoSource +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct CreateVideoTrackRequest { #[prost(string, required, tag="1")] @@ -1249,12 +1316,14 @@ pub struct CreateVideoTrackRequest { #[prost(uint64, required, tag="2")] pub source_handle: u64, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct CreateVideoTrackResponse { #[prost(message, required, tag="1")] pub track: OwnedTrack, } /// Create a new AudioTrack from a AudioSource +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct CreateAudioTrackRequest { #[prost(string, required, tag="1")] @@ -1262,21 +1331,25 @@ pub struct CreateAudioTrackRequest { #[prost(uint64, required, tag="2")] pub source_handle: u64, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct CreateAudioTrackResponse { #[prost(message, required, tag="1")] pub track: OwnedTrack, } -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct GetStatsRequest { #[prost(uint64, required, tag="1")] pub track_handle: u64, } -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct GetStatsResponse { #[prost(uint64, required, tag="1")] pub async_id: u64, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct GetStatsCallback { #[prost(uint64, required, tag="1")] @@ -1290,9 +1363,11 @@ pub struct GetStatsCallback { // Track // -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct TrackEvent { } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct TrackPublicationInfo { #[prost(string, required, tag="1")] @@ -1318,6 +1393,7 @@ pub struct TrackPublicationInfo { #[prost(enumeration="EncryptionType", required, tag="11")] pub encryption_type: i32, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct OwnedTrackPublication { #[prost(message, required, tag="1")] @@ -1325,6 +1401,7 @@ pub struct OwnedTrackPublication { #[prost(message, required, tag="2")] pub info: TrackPublicationInfo, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct TrackInfo { #[prost(string, required, tag="1")] @@ -1340,6 +1417,7 @@ pub struct TrackInfo { #[prost(bool, required, tag="6")] pub remote: bool, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct OwnedTrack { #[prost(message, required, tag="1")] @@ -1348,27 +1426,31 @@ pub struct OwnedTrack { pub info: TrackInfo, } /// Mute/UnMute a track -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct LocalTrackMuteRequest { #[prost(uint64, required, tag="1")] pub track_handle: u64, #[prost(bool, required, tag="2")] pub mute: bool, } -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct LocalTrackMuteResponse { #[prost(bool, required, tag="1")] pub muted: bool, } /// Enable/Disable a remote track -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct EnableRemoteTrackRequest { #[prost(uint64, required, tag="1")] pub track_handle: u64, #[prost(bool, required, tag="2")] pub enabled: bool, } -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct EnableRemoteTrackResponse { #[prost(bool, required, tag="1")] pub enabled: bool, @@ -1387,9 +1469,9 @@ impl TrackKind { /// (if the ProtoBuf definition does not change) and safe for programmatic use. pub fn as_str_name(&self) -> &'static str { match self { - Self::KindUnknown => "KIND_UNKNOWN", - Self::KindAudio => "KIND_AUDIO", - Self::KindVideo => "KIND_VIDEO", + TrackKind::KindUnknown => "KIND_UNKNOWN", + TrackKind::KindAudio => "KIND_AUDIO", + TrackKind::KindVideo => "KIND_VIDEO", } } /// Creates an enum from field names used in the ProtoBuf definition. @@ -1418,11 +1500,11 @@ impl TrackSource { /// (if the ProtoBuf definition does not change) and safe for programmatic use. pub fn as_str_name(&self) -> &'static str { match self { - Self::SourceUnknown => "SOURCE_UNKNOWN", - Self::SourceCamera => "SOURCE_CAMERA", - Self::SourceMicrophone => "SOURCE_MICROPHONE", - Self::SourceScreenshare => "SOURCE_SCREENSHARE", - Self::SourceScreenshareAudio => "SOURCE_SCREENSHARE_AUDIO", + TrackSource::SourceUnknown => "SOURCE_UNKNOWN", + TrackSource::SourceCamera => "SOURCE_CAMERA", + TrackSource::SourceMicrophone => "SOURCE_MICROPHONE", + TrackSource::SourceScreenshare => "SOURCE_SCREENSHARE", + TrackSource::SourceScreenshareAudio => "SOURCE_SCREENSHARE_AUDIO", } } /// Creates an enum from field names used in the ProtoBuf definition. @@ -1451,9 +1533,9 @@ impl StreamState { /// (if the ProtoBuf definition does not change) and safe for programmatic use. pub fn as_str_name(&self) -> &'static str { match self { - Self::StateUnknown => "STATE_UNKNOWN", - Self::StateActive => "STATE_ACTIVE", - Self::StatePaused => "STATE_PAUSED", + StreamState::StateUnknown => "STATE_UNKNOWN", + StreamState::StateActive => "STATE_ACTIVE", + StreamState::StatePaused => "STATE_PAUSED", } } /// Creates an enum from field names used in the ProtoBuf definition. @@ -1467,18 +1549,21 @@ impl StreamState { } } /// Enable/Disable a remote track publication -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct EnableRemoteTrackPublicationRequest { #[prost(uint64, required, tag="1")] pub track_publication_handle: u64, #[prost(bool, required, tag="2")] pub enabled: bool, } -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct EnableRemoteTrackPublicationResponse { } /// update a remote track publication dimension -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct UpdateRemoteTrackPublicationDimensionRequest { #[prost(uint64, required, tag="1")] pub track_publication_handle: u64, @@ -1487,9 +1572,11 @@ pub struct UpdateRemoteTrackPublicationDimensionRequest { #[prost(uint32, required, tag="3")] pub height: u32, } -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct UpdateRemoteTrackPublicationDimensionResponse { } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct ParticipantInfo { #[prost(string, required, tag="1")] @@ -1505,6 +1592,7 @@ pub struct ParticipantInfo { #[prost(enumeration="ParticipantKind", required, tag="6")] pub kind: i32, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct OwnedParticipant { #[prost(message, required, tag="1")] @@ -1528,11 +1616,11 @@ impl ParticipantKind { /// (if the ProtoBuf definition does not change) and safe for programmatic use. pub fn as_str_name(&self) -> &'static str { match self { - Self::Standard => "PARTICIPANT_KIND_STANDARD", - Self::Ingress => "PARTICIPANT_KIND_INGRESS", - Self::Egress => "PARTICIPANT_KIND_EGRESS", - Self::Sip => "PARTICIPANT_KIND_SIP", - Self::Agent => "PARTICIPANT_KIND_AGENT", + ParticipantKind::Standard => "PARTICIPANT_KIND_STANDARD", + ParticipantKind::Ingress => "PARTICIPANT_KIND_INGRESS", + ParticipantKind::Egress => "PARTICIPANT_KIND_EGRESS", + ParticipantKind::Sip => "PARTICIPANT_KIND_SIP", + ParticipantKind::Agent => "PARTICIPANT_KIND_AGENT", } } /// Creates an enum from field names used in the ProtoBuf definition. @@ -1549,7 +1637,8 @@ impl ParticipantKind { } /// Create a new VideoStream /// VideoStream is used to receive video frames from a track -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct NewVideoStreamRequest { #[prost(uint64, required, tag="1")] pub track_handle: u64, @@ -1562,13 +1651,15 @@ pub struct NewVideoStreamRequest { #[prost(bool, optional, tag="4")] pub normalize_stride: ::core::option::Option, } -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct NewVideoStreamResponse { #[prost(message, required, tag="1")] pub stream: OwnedVideoStream, } /// Request a video stream from a participant -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct VideoStreamFromParticipantRequest { #[prost(uint64, required, tag="1")] pub participant_handle: u64, @@ -1581,14 +1672,16 @@ pub struct VideoStreamFromParticipantRequest { #[prost(bool, optional, tag="5")] pub normalize_stride: ::core::option::Option, } -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct VideoStreamFromParticipantResponse { #[prost(message, required, tag="1")] pub stream: OwnedVideoStream, } /// Create a new VideoSource /// VideoSource is used to send video frame to a track -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct NewVideoSourceRequest { #[prost(enumeration="VideoSourceType", required, tag="1")] pub r#type: i32, @@ -1597,12 +1690,14 @@ pub struct NewVideoSourceRequest { #[prost(message, required, tag="2")] pub resolution: VideoSourceResolution, } -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct NewVideoSourceResponse { #[prost(message, required, tag="1")] pub source: OwnedVideoSource, } /// Push a frame to a VideoSource +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct CaptureVideoFrameRequest { #[prost(uint64, required, tag="1")] @@ -1615,9 +1710,11 @@ pub struct CaptureVideoFrameRequest { #[prost(enumeration="VideoRotation", required, tag="4")] pub rotation: i32, } -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct CaptureVideoFrameResponse { } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct VideoConvertRequest { #[prost(bool, optional, tag="1")] @@ -1627,6 +1724,7 @@ pub struct VideoConvertRequest { #[prost(enumeration="VideoBufferType", required, tag="3")] pub dst_type: i32, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct VideoConvertResponse { #[prost(oneof="video_convert_response::Message", tags="1, 2")] @@ -1634,7 +1732,8 @@ pub struct VideoConvertResponse { } /// Nested message and enum types in `VideoConvertResponse`. pub mod video_convert_response { - #[derive(Clone, PartialEq, ::prost::Oneof)] + #[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Oneof)] pub enum Message { #[prost(string, tag="1")] Error(::prost::alloc::string::String), @@ -1646,7 +1745,8 @@ pub mod video_convert_response { // VideoFrame buffers // -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct VideoResolution { #[prost(uint32, required, tag="1")] pub width: u32, @@ -1655,6 +1755,7 @@ pub struct VideoResolution { #[prost(double, required, tag="3")] pub frame_rate: f64, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct VideoBufferInfo { #[prost(enumeration="VideoBufferType", required, tag="1")] @@ -1673,7 +1774,8 @@ pub struct VideoBufferInfo { } /// Nested message and enum types in `VideoBufferInfo`. pub mod video_buffer_info { - #[derive(Clone, Copy, PartialEq, ::prost::Message)] + #[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct ComponentInfo { #[prost(uint64, required, tag="1")] pub data_ptr: u64, @@ -1683,6 +1785,7 @@ pub mod video_buffer_info { pub size: u32, } } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct OwnedVideoBuffer { #[prost(message, required, tag="1")] @@ -1690,18 +1793,21 @@ pub struct OwnedVideoBuffer { #[prost(message, required, tag="2")] pub info: VideoBufferInfo, } -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct VideoStreamInfo { #[prost(enumeration="VideoStreamType", required, tag="1")] pub r#type: i32, } -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct OwnedVideoStream { #[prost(message, required, tag="1")] pub handle: FfiOwnedHandle, #[prost(message, required, tag="2")] pub info: VideoStreamInfo, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct VideoStreamEvent { #[prost(uint64, required, tag="1")] @@ -1711,7 +1817,8 @@ pub struct VideoStreamEvent { } /// Nested message and enum types in `VideoStreamEvent`. pub mod video_stream_event { - #[derive(Clone, PartialEq, ::prost::Oneof)] + #[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Oneof)] pub enum Message { #[prost(message, tag="2")] FrameReceived(super::VideoFrameReceived), @@ -1719,6 +1826,7 @@ pub mod video_stream_event { Eos(super::VideoStreamEos), } } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct VideoFrameReceived { #[prost(message, required, tag="1")] @@ -1729,26 +1837,30 @@ pub struct VideoFrameReceived { #[prost(enumeration="VideoRotation", required, tag="3")] pub rotation: i32, } -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct VideoStreamEos { } // // VideoSource // -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct VideoSourceResolution { #[prost(uint32, required, tag="1")] pub width: u32, #[prost(uint32, required, tag="2")] pub height: u32, } -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct VideoSourceInfo { #[prost(enumeration="VideoSourceType", required, tag="1")] pub r#type: i32, } -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct OwnedVideoSource { #[prost(message, required, tag="1")] pub handle: FfiOwnedHandle, @@ -1770,10 +1882,10 @@ impl VideoCodec { /// (if the ProtoBuf definition does not change) and safe for programmatic use. pub fn as_str_name(&self) -> &'static str { match self { - Self::Vp8 => "VP8", - Self::H264 => "H264", - Self::Av1 => "AV1", - Self::Vp9 => "VP9", + VideoCodec::Vp8 => "VP8", + VideoCodec::H264 => "H264", + VideoCodec::Av1 => "AV1", + VideoCodec::Vp9 => "VP9", } } /// Creates an enum from field names used in the ProtoBuf definition. @@ -1802,10 +1914,10 @@ impl VideoRotation { /// (if the ProtoBuf definition does not change) and safe for programmatic use. pub fn as_str_name(&self) -> &'static str { match self { - Self::VideoRotation0 => "VIDEO_ROTATION_0", - Self::VideoRotation90 => "VIDEO_ROTATION_90", - Self::VideoRotation180 => "VIDEO_ROTATION_180", - Self::VideoRotation270 => "VIDEO_ROTATION_270", + VideoRotation::VideoRotation0 => "VIDEO_ROTATION_0", + VideoRotation::VideoRotation90 => "VIDEO_ROTATION_90", + VideoRotation::VideoRotation180 => "VIDEO_ROTATION_180", + VideoRotation::VideoRotation270 => "VIDEO_ROTATION_270", } } /// Creates an enum from field names used in the ProtoBuf definition. @@ -1841,17 +1953,17 @@ impl VideoBufferType { /// (if the ProtoBuf definition does not change) and safe for programmatic use. pub fn as_str_name(&self) -> &'static str { match self { - Self::Rgba => "RGBA", - Self::Abgr => "ABGR", - Self::Argb => "ARGB", - Self::Bgra => "BGRA", - Self::Rgb24 => "RGB24", - Self::I420 => "I420", - Self::I420a => "I420A", - Self::I422 => "I422", - Self::I444 => "I444", - Self::I010 => "I010", - Self::Nv12 => "NV12", + VideoBufferType::Rgba => "RGBA", + VideoBufferType::Abgr => "ABGR", + VideoBufferType::Argb => "ARGB", + VideoBufferType::Bgra => "BGRA", + VideoBufferType::Rgb24 => "RGB24", + VideoBufferType::I420 => "I420", + VideoBufferType::I420a => "I420A", + VideoBufferType::I422 => "I422", + VideoBufferType::I444 => "I444", + VideoBufferType::I010 => "I010", + VideoBufferType::Nv12 => "NV12", } } /// Creates an enum from field names used in the ProtoBuf definition. @@ -1890,9 +2002,9 @@ impl VideoStreamType { /// (if the ProtoBuf definition does not change) and safe for programmatic use. pub fn as_str_name(&self) -> &'static str { match self { - Self::VideoStreamNative => "VIDEO_STREAM_NATIVE", - Self::VideoStreamWebgl => "VIDEO_STREAM_WEBGL", - Self::VideoStreamHtml => "VIDEO_STREAM_HTML", + VideoStreamType::VideoStreamNative => "VIDEO_STREAM_NATIVE", + VideoStreamType::VideoStreamWebgl => "VIDEO_STREAM_WEBGL", + VideoStreamType::VideoStreamHtml => "VIDEO_STREAM_HTML", } } /// Creates an enum from field names used in the ProtoBuf definition. @@ -1917,7 +2029,7 @@ impl VideoSourceType { /// (if the ProtoBuf definition does not change) and safe for programmatic use. pub fn as_str_name(&self) -> &'static str { match self { - Self::VideoSourceNative => "VIDEO_SOURCE_NATIVE", + VideoSourceType::VideoSourceNative => "VIDEO_SOURCE_NATIVE", } } /// Creates an enum from field names used in the ProtoBuf definition. @@ -1929,6 +2041,7 @@ impl VideoSourceType { } } /// Connect to a new LiveKit room +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct ConnectRequest { #[prost(string, required, tag="1")] @@ -1938,11 +2051,13 @@ pub struct ConnectRequest { #[prost(message, required, tag="3")] pub options: RoomOptions, } -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct ConnectResponse { #[prost(uint64, required, tag="1")] pub async_id: u64, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct ConnectCallback { #[prost(uint64, required, tag="1")] @@ -1952,7 +2067,8 @@ pub struct ConnectCallback { } /// Nested message and enum types in `ConnectCallback`. pub mod connect_callback { - #[derive(Clone, PartialEq, ::prost::Message)] + #[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct ParticipantWithTracks { #[prost(message, required, tag="1")] pub participant: super::OwnedParticipant, @@ -1961,7 +2077,8 @@ pub mod connect_callback { #[prost(message, repeated, tag="2")] pub publications: ::prost::alloc::vec::Vec, } - #[derive(Clone, PartialEq, ::prost::Message)] + #[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct Result { #[prost(message, required, tag="1")] pub room: super::OwnedRoom, @@ -1970,7 +2087,8 @@ pub mod connect_callback { #[prost(message, repeated, tag="3")] pub participants: ::prost::alloc::vec::Vec, } - #[derive(Clone, PartialEq, ::prost::Oneof)] + #[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Oneof)] pub enum Message { #[prost(string, tag="2")] Error(::prost::alloc::string::String), @@ -1979,22 +2097,26 @@ pub mod connect_callback { } } /// Disconnect from the a room -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct DisconnectRequest { #[prost(uint64, required, tag="1")] pub room_handle: u64, } -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct DisconnectResponse { #[prost(uint64, required, tag="1")] pub async_id: u64, } -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct DisconnectCallback { #[prost(uint64, required, tag="1")] pub async_id: u64, } /// Publish a track to the room +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct PublishTrackRequest { #[prost(uint64, required, tag="1")] @@ -2004,11 +2126,13 @@ pub struct PublishTrackRequest { #[prost(message, required, tag="3")] pub options: TrackPublishOptions, } -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct PublishTrackResponse { #[prost(uint64, required, tag="1")] pub async_id: u64, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct PublishTrackCallback { #[prost(uint64, required, tag="1")] @@ -2018,7 +2142,8 @@ pub struct PublishTrackCallback { } /// Nested message and enum types in `PublishTrackCallback`. pub mod publish_track_callback { - #[derive(Clone, PartialEq, ::prost::Oneof)] + #[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Oneof)] pub enum Message { #[prost(string, tag="2")] Error(::prost::alloc::string::String), @@ -2027,6 +2152,7 @@ pub mod publish_track_callback { } } /// Unpublish a track from the room +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct UnpublishTrackRequest { #[prost(uint64, required, tag="1")] @@ -2036,11 +2162,13 @@ pub struct UnpublishTrackRequest { #[prost(bool, required, tag="3")] pub stop_on_unpublish: bool, } -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct UnpublishTrackResponse { #[prost(uint64, required, tag="1")] pub async_id: u64, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct UnpublishTrackCallback { #[prost(uint64, required, tag="1")] @@ -2049,6 +2177,7 @@ pub struct UnpublishTrackCallback { pub error: ::core::option::Option<::prost::alloc::string::String>, } /// Publish data to other participants +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct PublishDataRequest { #[prost(uint64, required, tag="1")] @@ -2067,11 +2196,13 @@ pub struct PublishDataRequest { #[prost(string, repeated, tag="7")] pub destination_identities: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, } -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct PublishDataResponse { #[prost(uint64, required, tag="1")] pub async_id: u64, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct PublishDataCallback { #[prost(uint64, required, tag="1")] @@ -2080,6 +2211,7 @@ pub struct PublishDataCallback { pub error: ::core::option::Option<::prost::alloc::string::String>, } /// Publish transcription messages to room +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct PublishTranscriptionRequest { #[prost(uint64, required, tag="1")] @@ -2091,11 +2223,13 @@ pub struct PublishTranscriptionRequest { #[prost(message, repeated, tag="4")] pub segments: ::prost::alloc::vec::Vec, } -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct PublishTranscriptionResponse { #[prost(uint64, required, tag="1")] pub async_id: u64, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct PublishTranscriptionCallback { #[prost(uint64, required, tag="1")] @@ -2104,6 +2238,7 @@ pub struct PublishTranscriptionCallback { pub error: ::core::option::Option<::prost::alloc::string::String>, } /// Publish Sip DTMF messages to other participants +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct PublishSipDtmfRequest { #[prost(uint64, required, tag="1")] @@ -2115,11 +2250,13 @@ pub struct PublishSipDtmfRequest { #[prost(string, repeated, tag="4")] pub destination_identities: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, } -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct PublishSipDtmfResponse { #[prost(uint64, required, tag="1")] pub async_id: u64, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct PublishSipDtmfCallback { #[prost(uint64, required, tag="1")] @@ -2128,6 +2265,7 @@ pub struct PublishSipDtmfCallback { pub error: ::core::option::Option<::prost::alloc::string::String>, } /// Change the local participant's metadata +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct SetLocalMetadataRequest { #[prost(uint64, required, tag="1")] @@ -2135,11 +2273,13 @@ pub struct SetLocalMetadataRequest { #[prost(string, required, tag="2")] pub metadata: ::prost::alloc::string::String, } -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct SetLocalMetadataResponse { #[prost(uint64, required, tag="1")] pub async_id: u64, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct SetLocalMetadataCallback { #[prost(uint64, required, tag="1")] @@ -2147,6 +2287,7 @@ pub struct SetLocalMetadataCallback { #[prost(string, optional, tag="2")] pub error: ::core::option::Option<::prost::alloc::string::String>, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct SendChatMessageRequest { #[prost(uint64, required, tag="1")] @@ -2158,6 +2299,7 @@ pub struct SendChatMessageRequest { #[prost(string, optional, tag="4")] pub sender_identity: ::core::option::Option<::prost::alloc::string::String>, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct EditChatMessageRequest { #[prost(uint64, required, tag="1")] @@ -2171,11 +2313,13 @@ pub struct EditChatMessageRequest { #[prost(string, optional, tag="5")] pub sender_identity: ::core::option::Option<::prost::alloc::string::String>, } -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct SendChatMessageResponse { #[prost(uint64, required, tag="1")] pub async_id: u64, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct SendChatMessageCallback { #[prost(uint64, required, tag="1")] @@ -2185,7 +2329,8 @@ pub struct SendChatMessageCallback { } /// Nested message and enum types in `SendChatMessageCallback`. pub mod send_chat_message_callback { - #[derive(Clone, PartialEq, ::prost::Oneof)] + #[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Oneof)] pub enum Message { #[prost(string, tag="2")] Error(::prost::alloc::string::String), @@ -2194,6 +2339,7 @@ pub mod send_chat_message_callback { } } /// Change the local participant's attributes +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct SetLocalAttributesRequest { #[prost(uint64, required, tag="1")] @@ -2201,6 +2347,7 @@ pub struct SetLocalAttributesRequest { #[prost(message, repeated, tag="2")] pub attributes: ::prost::alloc::vec::Vec, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct AttributesEntry { #[prost(string, required, tag="1")] @@ -2208,11 +2355,13 @@ pub struct AttributesEntry { #[prost(string, required, tag="2")] pub value: ::prost::alloc::string::String, } -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct SetLocalAttributesResponse { #[prost(uint64, required, tag="1")] pub async_id: u64, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct SetLocalAttributesCallback { #[prost(uint64, required, tag="1")] @@ -2221,6 +2370,7 @@ pub struct SetLocalAttributesCallback { pub error: ::core::option::Option<::prost::alloc::string::String>, } /// Change the local participant's name +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct SetLocalNameRequest { #[prost(uint64, required, tag="1")] @@ -2228,11 +2378,13 @@ pub struct SetLocalNameRequest { #[prost(string, required, tag="2")] pub name: ::prost::alloc::string::String, } -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct SetLocalNameResponse { #[prost(uint64, required, tag="1")] pub async_id: u64, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct SetLocalNameCallback { #[prost(uint64, required, tag="1")] @@ -2241,26 +2393,31 @@ pub struct SetLocalNameCallback { pub error: ::core::option::Option<::prost::alloc::string::String>, } /// Change the "desire" to subs2ribe to a track -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct SetSubscribedRequest { #[prost(bool, required, tag="1")] pub subscribe: bool, #[prost(uint64, required, tag="2")] pub publication_handle: u64, } -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct SetSubscribedResponse { } -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct GetSessionStatsRequest { #[prost(uint64, required, tag="1")] pub room_handle: u64, } -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct GetSessionStatsResponse { #[prost(uint64, required, tag="1")] pub async_id: u64, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct GetSessionStatsCallback { #[prost(uint64, required, tag="1")] @@ -2270,14 +2427,16 @@ pub struct GetSessionStatsCallback { } /// Nested message and enum types in `GetSessionStatsCallback`. pub mod get_session_stats_callback { - #[derive(Clone, PartialEq, ::prost::Message)] + #[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct Result { #[prost(message, repeated, tag="1")] pub publisher_stats: ::prost::alloc::vec::Vec, #[prost(message, repeated, tag="2")] pub subscriber_stats: ::prost::alloc::vec::Vec, } - #[derive(Clone, PartialEq, ::prost::Oneof)] + #[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Oneof)] pub enum Message { #[prost(string, tag="2")] Error(::prost::alloc::string::String), @@ -2289,18 +2448,21 @@ pub mod get_session_stats_callback { // Options // -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct VideoEncoding { #[prost(uint64, required, tag="1")] pub max_bitrate: u64, #[prost(double, required, tag="2")] pub max_framerate: f64, } -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct AudioEncoding { #[prost(uint64, required, tag="1")] pub max_bitrate: u64, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct TrackPublishOptions { /// encodings are optional @@ -2321,6 +2483,7 @@ pub struct TrackPublishOptions { #[prost(string, optional, tag="8")] pub stream: ::core::option::Option<::prost::alloc::string::String>, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct IceServer { #[prost(string, repeated, tag="1")] @@ -2330,6 +2493,7 @@ pub struct IceServer { #[prost(string, optional, tag="3")] pub password: ::core::option::Option<::prost::alloc::string::String>, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct RtcConfig { #[prost(enumeration="IceTransportType", optional, tag="1")] @@ -2340,6 +2504,7 @@ pub struct RtcConfig { #[prost(message, repeated, tag="3")] pub ice_servers: ::prost::alloc::vec::Vec, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct RoomOptions { #[prost(bool, optional, tag="1")] @@ -2356,6 +2521,7 @@ pub struct RoomOptions { #[prost(uint32, optional, tag="6")] pub join_retries: ::core::option::Option, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct TranscriptionSegment { #[prost(string, required, tag="1")] @@ -2371,20 +2537,23 @@ pub struct TranscriptionSegment { #[prost(string, required, tag="6")] pub language: ::prost::alloc::string::String, } -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct BufferInfo { #[prost(uint64, required, tag="1")] pub data_ptr: u64, #[prost(uint64, required, tag="2")] pub data_len: u64, } -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct OwnedBuffer { #[prost(message, required, tag="1")] pub handle: FfiOwnedHandle, #[prost(message, required, tag="2")] pub data: BufferInfo, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct RoomEvent { #[prost(uint64, required, tag="1")] @@ -2394,7 +2563,8 @@ pub struct RoomEvent { } /// Nested message and enum types in `RoomEvent`. pub mod room_event { - #[derive(Clone, PartialEq, ::prost::Oneof)] + #[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Oneof)] pub enum Message { #[prost(message, tag="2")] ParticipantConnected(super::ParticipantConnected), @@ -2456,6 +2626,7 @@ pub mod room_event { ChatMessage(super::ChatMessageReceived), } } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct RoomInfo { #[prost(string, optional, tag="1")] @@ -2465,6 +2636,7 @@ pub struct RoomInfo { #[prost(string, required, tag="3")] pub metadata: ::prost::alloc::string::String, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct OwnedRoom { #[prost(message, required, tag="1")] @@ -2472,16 +2644,19 @@ pub struct OwnedRoom { #[prost(message, required, tag="2")] pub info: RoomInfo, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct ParticipantConnected { #[prost(message, required, tag="1")] pub info: OwnedParticipant, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct ParticipantDisconnected { #[prost(string, required, tag="1")] pub participant_identity: ::prost::alloc::string::String, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct LocalTrackPublished { /// The TrackPublicationInfo comes from the PublishTrack response @@ -2489,16 +2664,19 @@ pub struct LocalTrackPublished { #[prost(string, required, tag="1")] pub track_sid: ::prost::alloc::string::String, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct LocalTrackUnpublished { #[prost(string, required, tag="1")] pub publication_sid: ::prost::alloc::string::String, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct LocalTrackSubscribed { #[prost(string, required, tag="2")] pub track_sid: ::prost::alloc::string::String, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct TrackPublished { #[prost(string, required, tag="1")] @@ -2506,6 +2684,7 @@ pub struct TrackPublished { #[prost(message, required, tag="2")] pub publication: OwnedTrackPublication, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct TrackUnpublished { #[prost(string, required, tag="1")] @@ -2515,6 +2694,7 @@ pub struct TrackUnpublished { } /// Publication isn't needed for subscription events on the FFI /// The FFI will retrieve the publication using the Track sid +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct TrackSubscribed { #[prost(string, required, tag="1")] @@ -2522,6 +2702,7 @@ pub struct TrackSubscribed { #[prost(message, required, tag="2")] pub track: OwnedTrack, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct TrackUnsubscribed { /// The FFI language can dispose/remove the VideoSink here @@ -2530,6 +2711,7 @@ pub struct TrackUnsubscribed { #[prost(string, required, tag="2")] pub track_sid: ::prost::alloc::string::String, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct TrackSubscriptionFailed { #[prost(string, required, tag="1")] @@ -2539,6 +2721,7 @@ pub struct TrackSubscriptionFailed { #[prost(string, required, tag="3")] pub error: ::prost::alloc::string::String, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct TrackMuted { #[prost(string, required, tag="1")] @@ -2546,6 +2729,7 @@ pub struct TrackMuted { #[prost(string, required, tag="2")] pub track_sid: ::prost::alloc::string::String, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct TrackUnmuted { #[prost(string, required, tag="1")] @@ -2553,6 +2737,7 @@ pub struct TrackUnmuted { #[prost(string, required, tag="2")] pub track_sid: ::prost::alloc::string::String, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct E2eeStateChanged { /// Using sid instead of identity for ffi communication @@ -2561,21 +2746,25 @@ pub struct E2eeStateChanged { #[prost(enumeration="EncryptionState", required, tag="2")] pub state: i32, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct ActiveSpeakersChanged { #[prost(string, repeated, tag="1")] pub participant_identities: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct RoomMetadataChanged { #[prost(string, required, tag="1")] pub metadata: ::prost::alloc::string::String, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct RoomSidChanged { #[prost(string, required, tag="1")] pub sid: ::prost::alloc::string::String, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct ParticipantMetadataChanged { #[prost(string, required, tag="1")] @@ -2583,6 +2772,7 @@ pub struct ParticipantMetadataChanged { #[prost(string, required, tag="2")] pub metadata: ::prost::alloc::string::String, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct ParticipantAttributesChanged { #[prost(string, required, tag="1")] @@ -2592,6 +2782,7 @@ pub struct ParticipantAttributesChanged { #[prost(message, repeated, tag="3")] pub changed_attributes: ::prost::alloc::vec::Vec, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct ParticipantNameChanged { #[prost(string, required, tag="1")] @@ -2599,6 +2790,7 @@ pub struct ParticipantNameChanged { #[prost(string, required, tag="2")] pub name: ::prost::alloc::string::String, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct ConnectionQualityChanged { #[prost(string, required, tag="1")] @@ -2606,6 +2798,7 @@ pub struct ConnectionQualityChanged { #[prost(enumeration="ConnectionQuality", required, tag="2")] pub quality: i32, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct UserPacket { #[prost(message, required, tag="1")] @@ -2613,6 +2806,7 @@ pub struct UserPacket { #[prost(string, optional, tag="2")] pub topic: ::core::option::Option<::prost::alloc::string::String>, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct ChatMessage { #[prost(string, required, tag="1")] @@ -2628,6 +2822,7 @@ pub struct ChatMessage { #[prost(bool, optional, tag="6")] pub generated: ::core::option::Option, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct ChatMessageReceived { #[prost(message, required, tag="1")] @@ -2635,6 +2830,7 @@ pub struct ChatMessageReceived { #[prost(string, required, tag="2")] pub participant_identity: ::prost::alloc::string::String, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct SipDtmf { #[prost(uint32, required, tag="1")] @@ -2642,6 +2838,7 @@ pub struct SipDtmf { #[prost(string, optional, tag="2")] pub digit: ::core::option::Option<::prost::alloc::string::String>, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct DataPacketReceived { #[prost(enumeration="DataPacketKind", required, tag="1")] @@ -2654,7 +2851,8 @@ pub struct DataPacketReceived { } /// Nested message and enum types in `DataPacketReceived`. pub mod data_packet_received { - #[derive(Clone, PartialEq, ::prost::Oneof)] + #[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Oneof)] pub enum Value { #[prost(message, tag="4")] User(super::UserPacket), @@ -2662,6 +2860,7 @@ pub mod data_packet_received { SipDtmf(super::SipDtmf), } } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct TranscriptionReceived { #[prost(string, optional, tag="1")] @@ -2671,26 +2870,32 @@ pub struct TranscriptionReceived { #[prost(message, repeated, tag="3")] pub segments: ::prost::alloc::vec::Vec, } -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct ConnectionStateChanged { #[prost(enumeration="ConnectionState", required, tag="1")] pub state: i32, } -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct Connected { } -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct Disconnected { #[prost(enumeration="DisconnectReason", required, tag="1")] pub reason: i32, } -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct Reconnecting { } -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct Reconnected { } -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct RoomEos { } #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] @@ -2707,9 +2912,9 @@ impl IceTransportType { /// (if the ProtoBuf definition does not change) and safe for programmatic use. pub fn as_str_name(&self) -> &'static str { match self { - Self::TransportRelay => "TRANSPORT_RELAY", - Self::TransportNohost => "TRANSPORT_NOHOST", - Self::TransportAll => "TRANSPORT_ALL", + IceTransportType::TransportRelay => "TRANSPORT_RELAY", + IceTransportType::TransportNohost => "TRANSPORT_NOHOST", + IceTransportType::TransportAll => "TRANSPORT_ALL", } } /// Creates an enum from field names used in the ProtoBuf definition. @@ -2735,8 +2940,8 @@ impl ContinualGatheringPolicy { /// (if the ProtoBuf definition does not change) and safe for programmatic use. pub fn as_str_name(&self) -> &'static str { match self { - Self::GatherOnce => "GATHER_ONCE", - Self::GatherContinually => "GATHER_CONTINUALLY", + ContinualGatheringPolicy::GatherOnce => "GATHER_ONCE", + ContinualGatheringPolicy::GatherContinually => "GATHER_CONTINUALLY", } } /// Creates an enum from field names used in the ProtoBuf definition. @@ -2767,10 +2972,10 @@ impl ConnectionQuality { /// (if the ProtoBuf definition does not change) and safe for programmatic use. pub fn as_str_name(&self) -> &'static str { match self { - Self::QualityPoor => "QUALITY_POOR", - Self::QualityGood => "QUALITY_GOOD", - Self::QualityExcellent => "QUALITY_EXCELLENT", - Self::QualityLost => "QUALITY_LOST", + ConnectionQuality::QualityPoor => "QUALITY_POOR", + ConnectionQuality::QualityGood => "QUALITY_GOOD", + ConnectionQuality::QualityExcellent => "QUALITY_EXCELLENT", + ConnectionQuality::QualityLost => "QUALITY_LOST", } } /// Creates an enum from field names used in the ProtoBuf definition. @@ -2798,9 +3003,9 @@ impl ConnectionState { /// (if the ProtoBuf definition does not change) and safe for programmatic use. pub fn as_str_name(&self) -> &'static str { match self { - Self::ConnDisconnected => "CONN_DISCONNECTED", - Self::ConnConnected => "CONN_CONNECTED", - Self::ConnReconnecting => "CONN_RECONNECTING", + ConnectionState::ConnDisconnected => "CONN_DISCONNECTED", + ConnectionState::ConnConnected => "CONN_CONNECTED", + ConnectionState::ConnReconnecting => "CONN_RECONNECTING", } } /// Creates an enum from field names used in the ProtoBuf definition. @@ -2826,8 +3031,8 @@ impl DataPacketKind { /// (if the ProtoBuf definition does not change) and safe for programmatic use. pub fn as_str_name(&self) -> &'static str { match self { - Self::KindLossy => "KIND_LOSSY", - Self::KindReliable => "KIND_RELIABLE", + DataPacketKind::KindLossy => "KIND_LOSSY", + DataPacketKind::KindReliable => "KIND_RELIABLE", } } /// Creates an enum from field names used in the ProtoBuf definition. @@ -2863,6 +3068,12 @@ pub enum DisconnectReason { SignalClose = 9, /// the room was closed, due to all Standard and Ingress participants having left RoomClosed = 10, + /// / SIP callee did not respond in time + UserUnavailable = 11, + /// / SIP callee rejected the call (busy) + UserRejected = 12, + /// / SIP protocol failure or unexpected response + SipTrunkFailure = 13, } impl DisconnectReason { /// String value of the enum field names used in the ProtoBuf definition. @@ -2871,17 +3082,20 @@ impl DisconnectReason { /// (if the ProtoBuf definition does not change) and safe for programmatic use. pub fn as_str_name(&self) -> &'static str { match self { - Self::UnknownReason => "UNKNOWN_REASON", - Self::ClientInitiated => "CLIENT_INITIATED", - Self::DuplicateIdentity => "DUPLICATE_IDENTITY", - Self::ServerShutdown => "SERVER_SHUTDOWN", - Self::ParticipantRemoved => "PARTICIPANT_REMOVED", - Self::RoomDeleted => "ROOM_DELETED", - Self::StateMismatch => "STATE_MISMATCH", - Self::JoinFailure => "JOIN_FAILURE", - Self::Migration => "MIGRATION", - Self::SignalClose => "SIGNAL_CLOSE", - Self::RoomClosed => "ROOM_CLOSED", + DisconnectReason::UnknownReason => "UNKNOWN_REASON", + DisconnectReason::ClientInitiated => "CLIENT_INITIATED", + DisconnectReason::DuplicateIdentity => "DUPLICATE_IDENTITY", + DisconnectReason::ServerShutdown => "SERVER_SHUTDOWN", + DisconnectReason::ParticipantRemoved => "PARTICIPANT_REMOVED", + DisconnectReason::RoomDeleted => "ROOM_DELETED", + DisconnectReason::StateMismatch => "STATE_MISMATCH", + DisconnectReason::JoinFailure => "JOIN_FAILURE", + DisconnectReason::Migration => "MIGRATION", + DisconnectReason::SignalClose => "SIGNAL_CLOSE", + DisconnectReason::RoomClosed => "ROOM_CLOSED", + DisconnectReason::UserUnavailable => "UserUnavailable", + DisconnectReason::UserRejected => "UserRejected", + DisconnectReason::SipTrunkFailure => "SipTrunkFailure", } } /// Creates an enum from field names used in the ProtoBuf definition. @@ -2898,13 +3112,17 @@ impl DisconnectReason { "MIGRATION" => Some(Self::Migration), "SIGNAL_CLOSE" => Some(Self::SignalClose), "ROOM_CLOSED" => Some(Self::RoomClosed), + "UserUnavailable" => Some(Self::UserUnavailable), + "UserRejected" => Some(Self::UserRejected), + "SipTrunkFailure" => Some(Self::SipTrunkFailure), _ => None, } } } /// Create a new AudioStream /// AudioStream is used to receive audio frames from a track -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct NewAudioStreamRequest { #[prost(uint64, required, tag="1")] pub track_handle: u64, @@ -2915,12 +3133,14 @@ pub struct NewAudioStreamRequest { #[prost(uint32, optional, tag="4")] pub num_channels: ::core::option::Option, } -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct NewAudioStreamResponse { #[prost(message, required, tag="1")] pub stream: OwnedAudioStream, } -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct AudioStreamFromParticipantRequest { #[prost(uint64, required, tag="1")] pub participant_handle: u64, @@ -2933,13 +3153,15 @@ pub struct AudioStreamFromParticipantRequest { #[prost(uint32, optional, tag="6")] pub num_channels: ::core::option::Option, } -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct AudioStreamFromParticipantResponse { #[prost(message, required, tag="1")] pub stream: OwnedAudioStream, } /// Create a new AudioSource -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct NewAudioSourceRequest { #[prost(enumeration="AudioSourceType", required, tag="1")] pub r#type: i32, @@ -2952,25 +3174,29 @@ pub struct NewAudioSourceRequest { #[prost(uint32, optional, tag="5")] pub queue_size_ms: ::core::option::Option, } -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct NewAudioSourceResponse { #[prost(message, required, tag="1")] pub source: OwnedAudioSource, } /// Push a frame to an AudioSource /// The data provided must be available as long as the client receive the callback. -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct CaptureAudioFrameRequest { #[prost(uint64, required, tag="1")] pub source_handle: u64, #[prost(message, required, tag="2")] pub buffer: AudioFrameBufferInfo, } -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct CaptureAudioFrameResponse { #[prost(uint64, required, tag="1")] pub async_id: u64, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct CaptureAudioFrameCallback { #[prost(uint64, required, tag="1")] @@ -2978,25 +3204,30 @@ pub struct CaptureAudioFrameCallback { #[prost(string, optional, tag="2")] pub error: ::core::option::Option<::prost::alloc::string::String>, } -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct ClearAudioBufferRequest { #[prost(uint64, required, tag="1")] pub source_handle: u64, } -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct ClearAudioBufferResponse { } /// Create a new AudioResampler -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct NewAudioResamplerRequest { } -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct NewAudioResamplerResponse { #[prost(message, required, tag="1")] pub resampler: OwnedAudioResampler, } /// Remix and resample an audio frame -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct RemixAndResampleRequest { #[prost(uint64, required, tag="1")] pub resampler_handle: u64, @@ -3007,14 +3238,16 @@ pub struct RemixAndResampleRequest { #[prost(uint32, required, tag="4")] pub sample_rate: u32, } -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct RemixAndResampleResponse { #[prost(message, required, tag="1")] pub buffer: OwnedAudioFrameBuffer, } // New resampler using SoX (much better quality) -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct NewSoxResamplerRequest { #[prost(double, required, tag="1")] pub input_rate: f64, @@ -3031,6 +3264,7 @@ pub struct NewSoxResamplerRequest { #[prost(uint32, optional, tag="7")] pub flags: ::core::option::Option, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct NewSoxResamplerResponse { #[prost(oneof="new_sox_resampler_response::Message", tags="1, 2")] @@ -3038,7 +3272,8 @@ pub struct NewSoxResamplerResponse { } /// Nested message and enum types in `NewSoxResamplerResponse`. pub mod new_sox_resampler_response { - #[derive(Clone, PartialEq, ::prost::Oneof)] + #[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Oneof)] pub enum Message { #[prost(message, tag="1")] Resampler(super::OwnedSoxResampler), @@ -3046,7 +3281,8 @@ pub mod new_sox_resampler_response { Error(::prost::alloc::string::String), } } -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct PushSoxResamplerRequest { #[prost(uint64, required, tag="1")] pub resampler_handle: u64, @@ -3057,6 +3293,7 @@ pub struct PushSoxResamplerRequest { #[prost(uint32, required, tag="3")] pub size: u32, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct PushSoxResamplerResponse { /// *const i16 (could be null) @@ -3068,11 +3305,13 @@ pub struct PushSoxResamplerResponse { #[prost(string, optional, tag="3")] pub error: ::core::option::Option<::prost::alloc::string::String>, } -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct FlushSoxResamplerRequest { #[prost(uint64, required, tag="1")] pub resampler_handle: u64, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct FlushSoxResamplerResponse { /// *const i16 (could be null) @@ -3088,7 +3327,8 @@ pub struct FlushSoxResamplerResponse { // AudioFrame buffer // -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct AudioFrameBufferInfo { /// *const i16 #[prost(uint64, required, tag="1")] @@ -3100,26 +3340,30 @@ pub struct AudioFrameBufferInfo { #[prost(uint32, required, tag="4")] pub samples_per_channel: u32, } -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct OwnedAudioFrameBuffer { #[prost(message, required, tag="1")] pub handle: FfiOwnedHandle, #[prost(message, required, tag="2")] pub info: AudioFrameBufferInfo, } -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct AudioStreamInfo { #[prost(enumeration="AudioStreamType", required, tag="1")] pub r#type: i32, } -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct OwnedAudioStream { #[prost(message, required, tag="1")] pub handle: FfiOwnedHandle, #[prost(message, required, tag="2")] pub info: AudioStreamInfo, } -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct AudioStreamEvent { #[prost(uint64, required, tag="1")] pub stream_handle: u64, @@ -3128,7 +3372,8 @@ pub struct AudioStreamEvent { } /// Nested message and enum types in `AudioStreamEvent`. pub mod audio_stream_event { - #[derive(Clone, Copy, PartialEq, ::prost::Oneof)] + #[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Oneof)] pub enum Message { #[prost(message, tag="2")] FrameReceived(super::AudioFrameReceived), @@ -3136,19 +3381,22 @@ pub mod audio_stream_event { Eos(super::AudioStreamEos), } } -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct AudioFrameReceived { #[prost(message, required, tag="1")] pub frame: OwnedAudioFrameBuffer, } -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct AudioStreamEos { } // // AudioSource // -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct AudioSourceOptions { #[prost(bool, required, tag="1")] pub echo_cancellation: bool, @@ -3157,12 +3405,14 @@ pub struct AudioSourceOptions { #[prost(bool, required, tag="3")] pub auto_gain_control: bool, } -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct AudioSourceInfo { #[prost(enumeration="AudioSourceType", required, tag="2")] pub r#type: i32, } -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct OwnedAudioSource { #[prost(message, required, tag="1")] pub handle: FfiOwnedHandle, @@ -3173,10 +3423,12 @@ pub struct OwnedAudioSource { // AudioResampler // -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct AudioResamplerInfo { } -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct OwnedAudioResampler { #[prost(message, required, tag="1")] pub handle: FfiOwnedHandle, @@ -3187,10 +3439,12 @@ pub struct OwnedAudioResampler { // Sox AudioResampler // -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct SoxResamplerInfo { } -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct OwnedSoxResampler { #[prost(message, required, tag="1")] pub handle: FfiOwnedHandle, @@ -3211,8 +3465,8 @@ impl SoxResamplerDataType { /// (if the ProtoBuf definition does not change) and safe for programmatic use. pub fn as_str_name(&self) -> &'static str { match self { - Self::SoxrDatatypeInt16i => "SOXR_DATATYPE_INT16I", - Self::SoxrDatatypeInt16s => "SOXR_DATATYPE_INT16S", + SoxResamplerDataType::SoxrDatatypeInt16i => "SOXR_DATATYPE_INT16I", + SoxResamplerDataType::SoxrDatatypeInt16s => "SOXR_DATATYPE_INT16S", } } /// Creates an enum from field names used in the ProtoBuf definition. @@ -3240,11 +3494,11 @@ impl SoxQualityRecipe { /// (if the ProtoBuf definition does not change) and safe for programmatic use. pub fn as_str_name(&self) -> &'static str { match self { - Self::SoxrQualityQuick => "SOXR_QUALITY_QUICK", - Self::SoxrQualityLow => "SOXR_QUALITY_LOW", - Self::SoxrQualityMedium => "SOXR_QUALITY_MEDIUM", - Self::SoxrQualityHigh => "SOXR_QUALITY_HIGH", - Self::SoxrQualityVeryhigh => "SOXR_QUALITY_VERYHIGH", + SoxQualityRecipe::SoxrQualityQuick => "SOXR_QUALITY_QUICK", + SoxQualityRecipe::SoxrQualityLow => "SOXR_QUALITY_LOW", + SoxQualityRecipe::SoxrQualityMedium => "SOXR_QUALITY_MEDIUM", + SoxQualityRecipe::SoxrQualityHigh => "SOXR_QUALITY_HIGH", + SoxQualityRecipe::SoxrQualityVeryhigh => "SOXR_QUALITY_VERYHIGH", } } /// Creates an enum from field names used in the ProtoBuf definition. @@ -3282,12 +3536,12 @@ impl SoxFlagBits { /// (if the ProtoBuf definition does not change) and safe for programmatic use. pub fn as_str_name(&self) -> &'static str { match self { - Self::SoxrRolloffSmall => "SOXR_ROLLOFF_SMALL", - Self::SoxrRolloffMedium => "SOXR_ROLLOFF_MEDIUM", - Self::SoxrRolloffNone => "SOXR_ROLLOFF_NONE", - Self::SoxrHighPrecClock => "SOXR_HIGH_PREC_CLOCK", - Self::SoxrDoublePrecision => "SOXR_DOUBLE_PRECISION", - Self::SoxrVr => "SOXR_VR", + SoxFlagBits::SoxrRolloffSmall => "SOXR_ROLLOFF_SMALL", + SoxFlagBits::SoxrRolloffMedium => "SOXR_ROLLOFF_MEDIUM", + SoxFlagBits::SoxrRolloffNone => "SOXR_ROLLOFF_NONE", + SoxFlagBits::SoxrHighPrecClock => "SOXR_HIGH_PREC_CLOCK", + SoxFlagBits::SoxrDoublePrecision => "SOXR_DOUBLE_PRECISION", + SoxFlagBits::SoxrVr => "SOXR_VR", } } /// Creates an enum from field names used in the ProtoBuf definition. @@ -3320,8 +3574,8 @@ impl AudioStreamType { /// (if the ProtoBuf definition does not change) and safe for programmatic use. pub fn as_str_name(&self) -> &'static str { match self { - Self::AudioStreamNative => "AUDIO_STREAM_NATIVE", - Self::AudioStreamHtml => "AUDIO_STREAM_HTML", + AudioStreamType::AudioStreamNative => "AUDIO_STREAM_NATIVE", + AudioStreamType::AudioStreamHtml => "AUDIO_STREAM_HTML", } } /// Creates an enum from field names used in the ProtoBuf definition. @@ -3345,7 +3599,7 @@ impl AudioSourceType { /// (if the ProtoBuf definition does not change) and safe for programmatic use. pub fn as_str_name(&self) -> &'static str { match self { - Self::AudioSourceNative => "AUDIO_SOURCE_NATIVE", + AudioSourceType::AudioSourceNative => "AUDIO_SOURCE_NATIVE", } } /// Creates an enum from field names used in the ProtoBuf definition. @@ -3356,6 +3610,7 @@ impl AudioSourceType { } } } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct RpcError { #[prost(uint32, required, tag="1")] @@ -3366,6 +3621,7 @@ pub struct RpcError { pub data: ::core::option::Option<::prost::alloc::string::String>, } /// FFI Requests +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct PerformRpcRequest { #[prost(uint64, required, tag="1")] @@ -3379,6 +3635,7 @@ pub struct PerformRpcRequest { #[prost(uint32, optional, tag="5")] pub response_timeout_ms: ::core::option::Option, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct RegisterRpcMethodRequest { #[prost(uint64, required, tag="1")] @@ -3386,6 +3643,7 @@ pub struct RegisterRpcMethodRequest { #[prost(string, required, tag="2")] pub method: ::prost::alloc::string::String, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct UnregisterRpcMethodRequest { #[prost(uint64, required, tag="1")] @@ -3393,6 +3651,7 @@ pub struct UnregisterRpcMethodRequest { #[prost(string, required, tag="2")] pub method: ::prost::alloc::string::String, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct RpcMethodInvocationResponseRequest { #[prost(uint64, required, tag="1")] @@ -3405,23 +3664,28 @@ pub struct RpcMethodInvocationResponseRequest { pub error: ::core::option::Option, } /// FFI Responses -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct PerformRpcResponse { #[prost(uint64, required, tag="1")] pub async_id: u64, } -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct RegisterRpcMethodResponse { } -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct UnregisterRpcMethodResponse { } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct RpcMethodInvocationResponseResponse { #[prost(string, optional, tag="1")] pub error: ::core::option::Option<::prost::alloc::string::String>, } /// FFI Callbacks +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct PerformRpcCallback { #[prost(uint64, required, tag="1")] @@ -3432,6 +3696,7 @@ pub struct PerformRpcCallback { pub error: ::core::option::Option, } /// FFI Events +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct RpcMethodInvocationEvent { #[prost(uint64, required, tag="1")] @@ -3477,6 +3742,7 @@ pub struct RpcMethodInvocationEvent { /// This is the input of livekit_ffi_request function /// We always expect a response (FFIResponse, even if it's empty) +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct FfiRequest { #[prost(oneof="ffi_request::Message", tags="2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43")] @@ -3484,7 +3750,8 @@ pub struct FfiRequest { } /// Nested message and enum types in `FfiRequest`. pub mod ffi_request { - #[derive(Clone, PartialEq, ::prost::Oneof)] + #[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Oneof)] pub enum Message { #[prost(message, tag="2")] Dispose(super::DisposeRequest), @@ -3579,6 +3846,7 @@ pub mod ffi_request { } } /// This is the output of livekit_ffi_request function. +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct FfiResponse { #[prost(oneof="ffi_response::Message", tags="2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42")] @@ -3586,7 +3854,8 @@ pub struct FfiResponse { } /// Nested message and enum types in `FfiResponse`. pub mod ffi_response { - #[derive(Clone, PartialEq, ::prost::Oneof)] + #[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Oneof)] pub enum Message { #[prost(message, tag="2")] Dispose(super::DisposeResponse), @@ -3681,6 +3950,7 @@ pub mod ffi_response { /// To minimize complexity, participant events are not included in the protocol. /// It is easily deducible from the room events and it turned out that is is easier to implement /// on the ffi client side. +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct FfiEvent { #[prost(oneof="ffi_event::Message", tags="1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24")] @@ -3688,7 +3958,8 @@ pub struct FfiEvent { } /// Nested message and enum types in `FfiEvent`. pub mod ffi_event { - #[derive(Clone, PartialEq, ::prost::Oneof)] + #[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Oneof)] pub enum Message { #[prost(message, tag="1")] RoomEvent(super::RoomEvent), @@ -3741,22 +4012,26 @@ pub mod ffi_event { /// Stop all rooms synchronously (Do we need async here?). /// e.g: This is used for the Unity Editor after each assemblies reload. /// TODO(theomonnom): Implement a debug mode where we can find all leaked handles? -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct DisposeRequest { #[prost(bool, required, tag="1")] pub r#async: bool, } -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct DisposeResponse { /// None if sync #[prost(uint64, optional, tag="1")] pub async_id: ::core::option::Option, } -#[derive(Clone, Copy, PartialEq, ::prost::Message)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct DisposeCallback { #[prost(uint64, required, tag="1")] pub async_id: u64, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct LogRecord { #[prost(enumeration="LogLevel", required, tag="1")] @@ -3773,11 +4048,13 @@ pub struct LogRecord { #[prost(string, required, tag="6")] pub message: ::prost::alloc::string::String, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct LogBatch { #[prost(message, repeated, tag="1")] pub records: ::prost::alloc::vec::Vec, } +#[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct Panic { #[prost(string, required, tag="1")] @@ -3799,11 +4076,11 @@ impl LogLevel { /// (if the ProtoBuf definition does not change) and safe for programmatic use. pub fn as_str_name(&self) -> &'static str { match self { - Self::LogError => "LOG_ERROR", - Self::LogWarn => "LOG_WARN", - Self::LogInfo => "LOG_INFO", - Self::LogDebug => "LOG_DEBUG", - Self::LogTrace => "LOG_TRACE", + LogLevel::LogError => "LOG_ERROR", + LogLevel::LogWarn => "LOG_WARN", + LogLevel::LogInfo => "LOG_INFO", + LogLevel::LogDebug => "LOG_DEBUG", + LogLevel::LogTrace => "LOG_TRACE", } } /// Creates an enum from field names used in the ProtoBuf definition. diff --git a/livekit-protocol/protocol b/livekit-protocol/protocol index a601adc5..095606bc 160000 --- a/livekit-protocol/protocol +++ b/livekit-protocol/protocol @@ -1 +1 @@ -Subproject commit a601adc5e9027820857a6d445b32a868b19d4184 +Subproject commit 095606bc8e0e73535c6bf4867645dfff0825f121 diff --git a/livekit-protocol/src/livekit.rs b/livekit-protocol/src/livekit.rs index 19181c25..9c3107e4 100644 --- a/livekit-protocol/src/livekit.rs +++ b/livekit-protocol/src/livekit.rs @@ -124,6 +124,12 @@ pub enum MetricLabel { ClientVideoPublisherQualityLimitationDurationCpu = 15, /// total duration spent in other quality limitation ClientVideoPublisherQualityLimitationDurationOther = 16, + /// Publisher RTT (participant -> server) + PublisherRtt = 17, + /// RTT between publisher node and subscriber node (could involve intermedia node(s)) + ServerMeshRtt = 18, + /// Subscribe RTT (server -> participant) + SubscriberRtt = 19, PredefinedMaxValue = 4096, } impl MetricLabel { @@ -150,6 +156,9 @@ impl MetricLabel { MetricLabel::ClientVideoPublisherQualityLimitationDurationBandwidth => "CLIENT_VIDEO_PUBLISHER_QUALITY_LIMITATION_DURATION_BANDWIDTH", MetricLabel::ClientVideoPublisherQualityLimitationDurationCpu => "CLIENT_VIDEO_PUBLISHER_QUALITY_LIMITATION_DURATION_CPU", MetricLabel::ClientVideoPublisherQualityLimitationDurationOther => "CLIENT_VIDEO_PUBLISHER_QUALITY_LIMITATION_DURATION_OTHER", + MetricLabel::PublisherRtt => "PUBLISHER_RTT", + MetricLabel::ServerMeshRtt => "SERVER_MESH_RTT", + MetricLabel::SubscriberRtt => "SUBSCRIBER_RTT", MetricLabel::PredefinedMaxValue => "METRIC_LABEL_PREDEFINED_MAX_VALUE", } } @@ -173,6 +182,9 @@ impl MetricLabel { "CLIENT_VIDEO_PUBLISHER_QUALITY_LIMITATION_DURATION_BANDWIDTH" => Some(Self::ClientVideoPublisherQualityLimitationDurationBandwidth), "CLIENT_VIDEO_PUBLISHER_QUALITY_LIMITATION_DURATION_CPU" => Some(Self::ClientVideoPublisherQualityLimitationDurationCpu), "CLIENT_VIDEO_PUBLISHER_QUALITY_LIMITATION_DURATION_OTHER" => Some(Self::ClientVideoPublisherQualityLimitationDurationOther), + "PUBLISHER_RTT" => Some(Self::PublisherRtt), + "SERVER_MESH_RTT" => Some(Self::ServerMeshRtt), + "SUBSCRIBER_RTT" => Some(Self::SubscriberRtt), "METRIC_LABEL_PREDEFINED_MAX_VALUE" => Some(Self::PredefinedMaxValue), _ => None, } @@ -503,7 +515,7 @@ pub struct DataPacket { /// identities of participants who will receive the message (sent to all by default) #[prost(string, repeated, tag="5")] pub destination_identities: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, - #[prost(oneof="data_packet::Value", tags="2, 3, 6, 7, 8, 9, 10, 11, 12")] + #[prost(oneof="data_packet::Value", tags="2, 3, 6, 7, 8, 9, 10, 11, 12, 13, 14")] pub value: ::core::option::Option, } /// Nested message and enum types in `DataPacket`. @@ -555,6 +567,10 @@ pub mod data_packet { RpcAck(super::RpcAck), #[prost(message, tag="12")] RpcResponse(super::RpcResponse), + #[prost(message, tag="13")] + StreamHeader(super::data_stream::Header), + #[prost(message, tag="14")] + StreamChunk(super::data_stream::Chunk), } } #[allow(clippy::derive_partial_eq_without_eq)] @@ -1100,6 +1116,136 @@ pub struct TimedVersion { #[prost(int32, tag="2")] pub ticks: i32, } +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct DataStream { +} +/// Nested message and enum types in `DataStream`. +pub mod data_stream { + /// header properties specific to text streams + #[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] + pub struct TextHeader { + #[prost(enumeration="OperationType", tag="1")] + pub operation_type: i32, + /// Optional: Version for updates/edits + #[prost(int32, tag="2")] + pub version: i32, + /// Optional: Reply to specific message + #[prost(string, tag="3")] + pub reply_to_stream_id: ::prost::alloc::string::String, + /// file attachments for text streams + #[prost(string, repeated, tag="4")] + pub attached_stream_ids: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, + /// true if the text has been generated by an agent from a participant's audio transcription + #[prost(bool, tag="5")] + pub generated: bool, + } + /// header properties specific to file or image streams + #[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] + pub struct FileHeader { + /// name of the file + #[prost(string, tag="1")] + pub file_name: ::prost::alloc::string::String, + } + /// main DataStream.Header that contains a oneof for specific headers + #[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] + pub struct Header { + /// unique identifier for this data stream + #[prost(string, tag="1")] + pub stream_id: ::prost::alloc::string::String, + /// using int64 for Unix timestamp + #[prost(int64, tag="2")] + pub timestamp: i64, + #[prost(string, tag="3")] + pub topic: ::prost::alloc::string::String, + #[prost(string, tag="4")] + pub mime_type: ::prost::alloc::string::String, + /// only populated for finite streams, if it's a stream of unknown size this stays empty + #[prost(uint64, optional, tag="5")] + pub total_length: ::core::option::Option, + /// only populated for finite streams, if it's a stream of unknown size this stays empty + #[prost(uint64, optional, tag="6")] + pub total_chunks: ::core::option::Option, + /// defaults to NONE + #[prost(enumeration="super::encryption::Type", tag="7")] + pub encryption_type: i32, + /// user defined extensions map that can carry additional info + #[prost(map="string, string", tag="8")] + pub extensions: ::std::collections::HashMap<::prost::alloc::string::String, ::prost::alloc::string::String>, + /// oneof to choose between specific header types + #[prost(oneof="header::ContentHeader", tags="9, 10")] + pub content_header: ::core::option::Option, + } + /// Nested message and enum types in `Header`. + pub mod header { + /// oneof to choose between specific header types + #[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Oneof)] + pub enum ContentHeader { + #[prost(message, tag="9")] + TextHeader(super::TextHeader), + #[prost(message, tag="10")] + FileHeader(super::FileHeader), + } + } + #[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] + pub struct Chunk { + /// unique identifier for this data stream to map it to the correct header + #[prost(string, tag="1")] + pub stream_id: ::prost::alloc::string::String, + #[prost(uint64, tag="2")] + pub chunk_index: u64, + /// content as binary (bytes) + #[prost(bytes="vec", tag="3")] + pub content: ::prost::alloc::vec::Vec, + /// true only if this is the last chunk of this stream - can also be sent with empty content + #[prost(bool, tag="4")] + pub complete: bool, + /// a version indicating that this chunk_index has been retroactively modified and the original one needs to be replaced + #[prost(int32, tag="5")] + pub version: i32, + /// optional, initialization vector for AES-GCM encryption + #[prost(bytes="vec", optional, tag="6")] + pub iv: ::core::option::Option<::prost::alloc::vec::Vec>, + } + /// enum for operation types (specific to TextHeader) + #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] + #[repr(i32)] + pub enum OperationType { + Create = 0, + Update = 1, + Delete = 2, + Reaction = 3, + } + impl OperationType { + /// 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 { + OperationType::Create => "CREATE", + OperationType::Update => "UPDATE", + OperationType::Delete => "DELETE", + OperationType::Reaction => "REACTION", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "CREATE" => Some(Self::Create), + "UPDATE" => Some(Self::Update), + "DELETE" => Some(Self::Delete), + "REACTION" => Some(Self::Reaction), + _ => None, + } + } + } +} #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] #[repr(i32)] pub enum AudioCodec { @@ -1371,6 +1517,12 @@ pub enum DisconnectReason { SignalClose = 9, /// the room was closed, due to all Standard and Ingress participants having left RoomClosed = 10, + /// SIP callee did not respond in time + UserUnavailable = 11, + /// SIP callee rejected the call (busy) + UserRejected = 12, + /// SIP protocol failure or unexpected response + SipTrunkFailure = 13, } impl DisconnectReason { /// String value of the enum field names used in the ProtoBuf definition. @@ -1390,6 +1542,9 @@ impl DisconnectReason { DisconnectReason::Migration => "MIGRATION", DisconnectReason::SignalClose => "SIGNAL_CLOSE", DisconnectReason::RoomClosed => "ROOM_CLOSED", + DisconnectReason::UserUnavailable => "USER_UNAVAILABLE", + DisconnectReason::UserRejected => "USER_REJECTED", + DisconnectReason::SipTrunkFailure => "SIP_TRUNK_FAILURE", } } /// Creates an enum from field names used in the ProtoBuf definition. @@ -1406,6 +1561,9 @@ impl DisconnectReason { "MIGRATION" => Some(Self::Migration), "SIGNAL_CLOSE" => Some(Self::SignalClose), "ROOM_CLOSED" => Some(Self::RoomClosed), + "USER_UNAVAILABLE" => Some(Self::UserUnavailable), + "USER_REJECTED" => Some(Self::UserRejected), + "SIP_TRUNK_FAILURE" => Some(Self::SipTrunkFailure), _ => None, } } @@ -2073,6 +2231,11 @@ pub struct EgressInfo { pub segment_results: ::prost::alloc::vec::Vec, #[prost(message, repeated, tag="20")] pub image_results: ::prost::alloc::vec::Vec, + #[prost(string, tag="23")] + pub manifest_location: ::prost::alloc::string::String, + /// next ID: 26 + #[prost(bool, tag="25")] + pub backup_storage_used: bool, #[prost(oneof="egress_info::Request", tags="4, 14, 19, 5, 6")] pub request: ::core::option::Option, /// deprecated (use _result fields) @@ -3471,8 +3634,8 @@ pub struct UpdateWorkerStatus { /// optional string metadata = 2 \[deprecated=true\]; #[prost(float, tag="3")] pub load: f32, - #[prost(int32, tag="4")] - pub job_count: i32, + #[prost(uint32, tag="4")] + pub job_count: u32, } #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] @@ -3650,7 +3813,7 @@ pub struct CreateRoomRequest { pub name: ::prost::alloc::string::String, /// configuration to use for this room parameters. Setting parameters below override the config defaults. #[prost(string, tag="12")] - pub config_name: ::prost::alloc::string::String, + pub room_preset: ::prost::alloc::string::String, /// number of seconds to keep the room open if no one joins #[prost(uint32, tag="2")] pub empty_timeout: u32, @@ -3666,12 +3829,9 @@ pub struct CreateRoomRequest { /// metadata of room #[prost(string, tag="5")] pub metadata: ::prost::alloc::string::String, - /// egress + /// auto-egress configurations #[prost(message, optional, tag="6")] pub egress: ::core::option::Option, - /// agent - #[prost(message, optional, tag="11")] - pub agent: ::core::option::Option, /// playout delay of subscriber #[prost(uint32, tag="7")] pub min_playout_delay: u32, @@ -3682,10 +3842,13 @@ pub struct CreateRoomRequest { #[prost(bool, tag="9")] pub sync_streams: bool, /// replay - /// - /// NEXT-ID: 14 #[prost(bool, tag="13")] pub replay_enabled: bool, + /// Define agents that should be dispatched to this room + /// + /// NEXT-ID: 15 + #[prost(message, repeated, tag="14")] + pub agents: ::prost::alloc::vec::Vec, } #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] @@ -3863,15 +4026,12 @@ pub struct RoomConfiguration { /// number of seconds to keep the room open after everyone leaves #[prost(uint32, tag="3")] pub departure_timeout: u32, - /// limit number of participants that can be in a room + /// limit number of participants that can be in a room, excluding Egress and Ingress participants #[prost(uint32, tag="4")] pub max_participants: u32, /// egress #[prost(message, optional, tag="5")] pub egress: ::core::option::Option, - /// agent - #[prost(message, optional, tag="6")] - pub agent: ::core::option::Option, /// playout delay of subscriber #[prost(uint32, tag="7")] pub min_playout_delay: u32, @@ -3881,6 +4041,9 @@ pub struct RoomConfiguration { /// so not recommended for rooms with frequent subscription changes #[prost(bool, tag="9")] pub sync_streams: bool, + /// Define agents that should be dispatched to this room + #[prost(message, repeated, tag="10")] + pub agents: ::prost::alloc::vec::Vec, } #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] @@ -4469,6 +4632,18 @@ pub struct SipInboundTrunkInfo { /// Map SIP X-* headers from INVITE to SIP participant attributes. #[prost(map="string, string", tag="10")] pub headers_to_attributes: ::std::collections::HashMap<::prost::alloc::string::String, ::prost::alloc::string::String>, + /// Map LiveKit attributes to SIP X-* headers when sending BYE or REFER requests. + /// Keys are the names of attributes and values are the names of X-* headers they will be mapped to. + #[prost(map="string, string", tag="14")] + pub attributes_to_headers: ::std::collections::HashMap<::prost::alloc::string::String, ::prost::alloc::string::String>, + /// Max time for the caller to wait for track subscription. + #[prost(message, optional, tag="11")] + pub ringing_timeout: ::core::option::Option<::pbjson_types::Duration>, + /// Max call duration. + #[prost(message, optional, tag="12")] + pub max_call_duration: ::core::option::Option<::pbjson_types::Duration>, + #[prost(bool, tag="13")] + pub krisp_enabled: bool, } #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] @@ -4512,6 +4687,10 @@ pub struct SipOutboundTrunkInfo { /// Keys are the names of X-* headers and values are the names of attributes they will be mapped to. #[prost(map="string, string", tag="10")] pub headers_to_attributes: ::std::collections::HashMap<::prost::alloc::string::String, ::prost::alloc::string::String>, + /// Map LiveKit attributes to SIP X-* headers when sending BYE or REFER requests. + /// Keys are the names of attributes and values are the names of X-* headers they will be mapped to. + #[prost(map="string, string", tag="11")] + pub attributes_to_headers: ::std::collections::HashMap<::prost::alloc::string::String, ::prost::alloc::string::String>, } #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] @@ -4711,6 +4890,9 @@ pub struct CreateSipParticipantRequest { /// What number should be dialed via SIP #[prost(string, tag="2")] pub sip_call_to: ::prost::alloc::string::String, + /// Optional SIP From number to use. If empty, trunk number is used. + #[prost(string, tag="15")] + pub sip_number: ::prost::alloc::string::String, /// What LiveKit room should this participant be connected too #[prost(string, tag="3")] pub room_name: ::prost::alloc::string::String, @@ -4730,13 +4912,27 @@ pub struct CreateSipParticipantRequest { /// Character 'w' can be used to add a 0.5 sec delay. #[prost(string, tag="5")] pub dtmf: ::prost::alloc::string::String, - /// Optionally play ringtone in the room as an audible indicator for existing participants + /// Optionally play dialtone in the room as an audible indicator for existing participants. The `play_ringtone` option is deprectated but has the same effect. + #[deprecated] #[prost(bool, tag="6")] pub play_ringtone: bool, + #[prost(bool, tag="13")] + pub play_dialtone: bool, /// By default the From value (Phone number) is used for participant name/identity (if not set) and added to attributes. /// If true, a random value for identity will be used and numbers will be omitted from attributes. #[prost(bool, tag="10")] pub hide_phone_number: bool, + /// Max time for the callee to answer the call. + #[prost(message, optional, tag="11")] + pub ringing_timeout: ::core::option::Option<::pbjson_types::Duration>, + /// Max call duration. + #[prost(message, optional, tag="12")] + pub max_call_duration: ::core::option::Option<::pbjson_types::Duration>, + /// Enable voice isolation for the callee. + /// + /// NEXT ID: 16 + #[prost(bool, tag="14")] + pub enable_krisp: bool, } #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] @@ -4759,6 +4955,56 @@ pub struct TransferSipParticipantRequest { pub room_name: ::prost::alloc::string::String, #[prost(string, tag="3")] pub transfer_to: ::prost::alloc::string::String, + /// Optionally play dialtone to the SIP participant as an audible indicator of being transferred + #[prost(bool, tag="4")] + pub play_dialtone: bool, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct SipCallInfo { + #[prost(string, tag="1")] + pub call_id: ::prost::alloc::string::String, + #[prost(string, tag="2")] + pub trunk_id: ::prost::alloc::string::String, + #[prost(string, tag="3")] + pub room_name: ::prost::alloc::string::String, + /// ID of the current/previous room published to + #[prost(string, tag="4")] + pub room_id: ::prost::alloc::string::String, + #[prost(string, tag="5")] + pub participant_identity: ::prost::alloc::string::String, + #[prost(message, optional, tag="6")] + pub from_uri: ::core::option::Option, + #[prost(message, optional, tag="7")] + pub to_uri: ::core::option::Option, + #[prost(enumeration="SipFeature", repeated, tag="14")] + pub enabled_features: ::prost::alloc::vec::Vec, + #[prost(enumeration="SipCallStatus", tag="8")] + pub call_status: i32, + #[prost(int64, tag="9")] + pub created_at: i64, + #[prost(int64, tag="10")] + pub started_at: i64, + #[prost(int64, tag="11")] + pub ended_at: i64, + #[prost(enumeration="DisconnectReason", tag="12")] + pub disconnect_reason: i32, + #[prost(string, tag="13")] + pub error: ::prost::alloc::string::String, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct SipUri { + #[prost(string, tag="1")] + pub user: ::prost::alloc::string::String, + #[prost(string, tag="2")] + pub host: ::prost::alloc::string::String, + #[prost(string, tag="3")] + pub ip: ::prost::alloc::string::String, + #[prost(uint32, tag="4")] + pub port: u32, + #[prost(enumeration="SipTransport", tag="5")] + pub transport: i32, } #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] #[repr(i32)] @@ -4792,5 +5038,71 @@ impl SipTransport { } } } +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] +#[repr(i32)] +pub enum SipCallStatus { + /// Incoming call is being handled by the SIP service. The SIP participant hasn't joined a LiveKit room yet + ScsCallIncoming = 0, + /// SIP participant for outgoing call has been created. The SIP outgoing call is being established + ScsParticipantJoined = 1, + /// Call is ongoing. SIP participant is active in the LiveKit room + ScsActive = 2, + /// Call has ended + ScsDisconnected = 3, + /// Call has ended or never succeeded because of an error + ScsError = 4, +} +impl SipCallStatus { + /// 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 { + SipCallStatus::ScsCallIncoming => "SCS_CALL_INCOMING", + SipCallStatus::ScsParticipantJoined => "SCS_PARTICIPANT_JOINED", + SipCallStatus::ScsActive => "SCS_ACTIVE", + SipCallStatus::ScsDisconnected => "SCS_DISCONNECTED", + SipCallStatus::ScsError => "SCS_ERROR", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "SCS_CALL_INCOMING" => Some(Self::ScsCallIncoming), + "SCS_PARTICIPANT_JOINED" => Some(Self::ScsParticipantJoined), + "SCS_ACTIVE" => Some(Self::ScsActive), + "SCS_DISCONNECTED" => Some(Self::ScsDisconnected), + "SCS_ERROR" => Some(Self::ScsError), + _ => None, + } + } +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] +#[repr(i32)] +pub enum SipFeature { + None = 0, + KrispEnabled = 1, +} +impl SipFeature { + /// 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 { + SipFeature::None => "NONE", + SipFeature::KrispEnabled => "KRISP_ENABLED", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "NONE" => Some(Self::None), + "KRISP_ENABLED" => Some(Self::KrispEnabled), + _ => None, + } + } +} include!("livekit.serde.rs"); // @@protoc_insertion_point(module) diff --git a/livekit-protocol/src/livekit.serde.rs b/livekit-protocol/src/livekit.serde.rs index 4e6a0fb0..5da36416 100644 --- a/livekit-protocol/src/livekit.serde.rs +++ b/livekit-protocol/src/livekit.serde.rs @@ -3555,7 +3555,7 @@ impl serde::Serialize for CreateRoomRequest { if !self.name.is_empty() { len += 1; } - if !self.config_name.is_empty() { + if !self.room_preset.is_empty() { len += 1; } if self.empty_timeout != 0 { @@ -3576,9 +3576,6 @@ impl serde::Serialize for CreateRoomRequest { if self.egress.is_some() { len += 1; } - if self.agent.is_some() { - len += 1; - } if self.min_playout_delay != 0 { len += 1; } @@ -3591,12 +3588,15 @@ impl serde::Serialize for CreateRoomRequest { if self.replay_enabled { len += 1; } + if !self.agents.is_empty() { + len += 1; + } let mut struct_ser = serializer.serialize_struct("livekit.CreateRoomRequest", len)?; if !self.name.is_empty() { struct_ser.serialize_field("name", &self.name)?; } - if !self.config_name.is_empty() { - struct_ser.serialize_field("configName", &self.config_name)?; + if !self.room_preset.is_empty() { + struct_ser.serialize_field("roomPreset", &self.room_preset)?; } if self.empty_timeout != 0 { struct_ser.serialize_field("emptyTimeout", &self.empty_timeout)?; @@ -3616,9 +3616,6 @@ impl serde::Serialize for CreateRoomRequest { if let Some(v) = self.egress.as_ref() { struct_ser.serialize_field("egress", v)?; } - if let Some(v) = self.agent.as_ref() { - struct_ser.serialize_field("agent", v)?; - } if self.min_playout_delay != 0 { struct_ser.serialize_field("minPlayoutDelay", &self.min_playout_delay)?; } @@ -3631,6 +3628,9 @@ impl serde::Serialize for CreateRoomRequest { if self.replay_enabled { struct_ser.serialize_field("replayEnabled", &self.replay_enabled)?; } + if !self.agents.is_empty() { + struct_ser.serialize_field("agents", &self.agents)?; + } struct_ser.end() } } @@ -3642,8 +3642,8 @@ impl<'de> serde::Deserialize<'de> for CreateRoomRequest { { const FIELDS: &[&str] = &[ "name", - "config_name", - "configName", + "room_preset", + "roomPreset", "empty_timeout", "emptyTimeout", "departure_timeout", @@ -3654,7 +3654,6 @@ impl<'de> serde::Deserialize<'de> for CreateRoomRequest { "nodeId", "metadata", "egress", - "agent", "min_playout_delay", "minPlayoutDelay", "max_playout_delay", @@ -3663,23 +3662,24 @@ impl<'de> serde::Deserialize<'de> for CreateRoomRequest { "syncStreams", "replay_enabled", "replayEnabled", + "agents", ]; #[allow(clippy::enum_variant_names)] enum GeneratedField { Name, - ConfigName, + RoomPreset, EmptyTimeout, DepartureTimeout, MaxParticipants, NodeId, Metadata, Egress, - Agent, MinPlayoutDelay, MaxPlayoutDelay, SyncStreams, ReplayEnabled, + Agents, __SkipField__, } impl<'de> serde::Deserialize<'de> for GeneratedField { @@ -3703,18 +3703,18 @@ impl<'de> serde::Deserialize<'de> for CreateRoomRequest { { match value { "name" => Ok(GeneratedField::Name), - "configName" | "config_name" => Ok(GeneratedField::ConfigName), + "roomPreset" | "room_preset" => Ok(GeneratedField::RoomPreset), "emptyTimeout" | "empty_timeout" => Ok(GeneratedField::EmptyTimeout), "departureTimeout" | "departure_timeout" => Ok(GeneratedField::DepartureTimeout), "maxParticipants" | "max_participants" => Ok(GeneratedField::MaxParticipants), "nodeId" | "node_id" => Ok(GeneratedField::NodeId), "metadata" => Ok(GeneratedField::Metadata), "egress" => Ok(GeneratedField::Egress), - "agent" => Ok(GeneratedField::Agent), "minPlayoutDelay" | "min_playout_delay" => Ok(GeneratedField::MinPlayoutDelay), "maxPlayoutDelay" | "max_playout_delay" => Ok(GeneratedField::MaxPlayoutDelay), "syncStreams" | "sync_streams" => Ok(GeneratedField::SyncStreams), "replayEnabled" | "replay_enabled" => Ok(GeneratedField::ReplayEnabled), + "agents" => Ok(GeneratedField::Agents), _ => Ok(GeneratedField::__SkipField__), } } @@ -3735,18 +3735,18 @@ impl<'de> serde::Deserialize<'de> for CreateRoomRequest { V: serde::de::MapAccess<'de>, { let mut name__ = None; - let mut config_name__ = None; + let mut room_preset__ = None; let mut empty_timeout__ = None; let mut departure_timeout__ = None; let mut max_participants__ = None; let mut node_id__ = None; let mut metadata__ = None; let mut egress__ = None; - let mut agent__ = None; let mut min_playout_delay__ = None; let mut max_playout_delay__ = None; let mut sync_streams__ = None; let mut replay_enabled__ = None; + let mut agents__ = None; while let Some(k) = map_.next_key()? { match k { GeneratedField::Name => { @@ -3755,11 +3755,11 @@ impl<'de> serde::Deserialize<'de> for CreateRoomRequest { } name__ = Some(map_.next_value()?); } - GeneratedField::ConfigName => { - if config_name__.is_some() { - return Err(serde::de::Error::duplicate_field("configName")); + GeneratedField::RoomPreset => { + if room_preset__.is_some() { + return Err(serde::de::Error::duplicate_field("roomPreset")); } - config_name__ = Some(map_.next_value()?); + room_preset__ = Some(map_.next_value()?); } GeneratedField::EmptyTimeout => { if empty_timeout__.is_some() { @@ -3803,12 +3803,6 @@ impl<'de> serde::Deserialize<'de> for CreateRoomRequest { } egress__ = map_.next_value()?; } - GeneratedField::Agent => { - if agent__.is_some() { - return Err(serde::de::Error::duplicate_field("agent")); - } - agent__ = map_.next_value()?; - } GeneratedField::MinPlayoutDelay => { if min_playout_delay__.is_some() { return Err(serde::de::Error::duplicate_field("minPlayoutDelay")); @@ -3837,6 +3831,12 @@ impl<'de> serde::Deserialize<'de> for CreateRoomRequest { } replay_enabled__ = Some(map_.next_value()?); } + GeneratedField::Agents => { + if agents__.is_some() { + return Err(serde::de::Error::duplicate_field("agents")); + } + agents__ = Some(map_.next_value()?); + } GeneratedField::__SkipField__ => { let _ = map_.next_value::()?; } @@ -3844,18 +3844,18 @@ impl<'de> serde::Deserialize<'de> for CreateRoomRequest { } Ok(CreateRoomRequest { name: name__.unwrap_or_default(), - config_name: config_name__.unwrap_or_default(), + room_preset: room_preset__.unwrap_or_default(), empty_timeout: empty_timeout__.unwrap_or_default(), departure_timeout: departure_timeout__.unwrap_or_default(), max_participants: max_participants__.unwrap_or_default(), node_id: node_id__.unwrap_or_default(), metadata: metadata__.unwrap_or_default(), egress: egress__, - agent: agent__, min_playout_delay: min_playout_delay__.unwrap_or_default(), max_playout_delay: max_playout_delay__.unwrap_or_default(), sync_streams: sync_streams__.unwrap_or_default(), replay_enabled: replay_enabled__.unwrap_or_default(), + agents: agents__.unwrap_or_default(), }) } } @@ -4268,6 +4268,9 @@ impl serde::Serialize for CreateSipParticipantRequest { if !self.sip_call_to.is_empty() { len += 1; } + if !self.sip_number.is_empty() { + len += 1; + } if !self.room_name.is_empty() { len += 1; } @@ -4289,9 +4292,21 @@ impl serde::Serialize for CreateSipParticipantRequest { if self.play_ringtone { len += 1; } + if self.play_dialtone { + len += 1; + } if self.hide_phone_number { len += 1; } + if self.ringing_timeout.is_some() { + len += 1; + } + if self.max_call_duration.is_some() { + len += 1; + } + if self.enable_krisp { + len += 1; + } let mut struct_ser = serializer.serialize_struct("livekit.CreateSIPParticipantRequest", len)?; if !self.sip_trunk_id.is_empty() { struct_ser.serialize_field("sipTrunkId", &self.sip_trunk_id)?; @@ -4299,6 +4314,9 @@ impl serde::Serialize for CreateSipParticipantRequest { if !self.sip_call_to.is_empty() { struct_ser.serialize_field("sipCallTo", &self.sip_call_to)?; } + if !self.sip_number.is_empty() { + struct_ser.serialize_field("sipNumber", &self.sip_number)?; + } if !self.room_name.is_empty() { struct_ser.serialize_field("roomName", &self.room_name)?; } @@ -4320,9 +4338,21 @@ impl serde::Serialize for CreateSipParticipantRequest { if self.play_ringtone { struct_ser.serialize_field("playRingtone", &self.play_ringtone)?; } + if self.play_dialtone { + struct_ser.serialize_field("playDialtone", &self.play_dialtone)?; + } if self.hide_phone_number { struct_ser.serialize_field("hidePhoneNumber", &self.hide_phone_number)?; } + if let Some(v) = self.ringing_timeout.as_ref() { + struct_ser.serialize_field("ringingTimeout", v)?; + } + if let Some(v) = self.max_call_duration.as_ref() { + struct_ser.serialize_field("maxCallDuration", v)?; + } + if self.enable_krisp { + struct_ser.serialize_field("enableKrisp", &self.enable_krisp)?; + } struct_ser.end() } } @@ -4337,6 +4367,8 @@ impl<'de> serde::Deserialize<'de> for CreateSipParticipantRequest { "sipTrunkId", "sip_call_to", "sipCallTo", + "sip_number", + "sipNumber", "room_name", "roomName", "participant_identity", @@ -4350,14 +4382,23 @@ impl<'de> serde::Deserialize<'de> for CreateSipParticipantRequest { "dtmf", "play_ringtone", "playRingtone", + "play_dialtone", + "playDialtone", "hide_phone_number", "hidePhoneNumber", + "ringing_timeout", + "ringingTimeout", + "max_call_duration", + "maxCallDuration", + "enable_krisp", + "enableKrisp", ]; #[allow(clippy::enum_variant_names)] enum GeneratedField { SipTrunkId, SipCallTo, + SipNumber, RoomName, ParticipantIdentity, ParticipantName, @@ -4365,7 +4406,11 @@ impl<'de> serde::Deserialize<'de> for CreateSipParticipantRequest { ParticipantAttributes, Dtmf, PlayRingtone, + PlayDialtone, HidePhoneNumber, + RingingTimeout, + MaxCallDuration, + EnableKrisp, __SkipField__, } impl<'de> serde::Deserialize<'de> for GeneratedField { @@ -4390,6 +4435,7 @@ impl<'de> serde::Deserialize<'de> for CreateSipParticipantRequest { match value { "sipTrunkId" | "sip_trunk_id" => Ok(GeneratedField::SipTrunkId), "sipCallTo" | "sip_call_to" => Ok(GeneratedField::SipCallTo), + "sipNumber" | "sip_number" => Ok(GeneratedField::SipNumber), "roomName" | "room_name" => Ok(GeneratedField::RoomName), "participantIdentity" | "participant_identity" => Ok(GeneratedField::ParticipantIdentity), "participantName" | "participant_name" => Ok(GeneratedField::ParticipantName), @@ -4397,7 +4443,11 @@ impl<'de> serde::Deserialize<'de> for CreateSipParticipantRequest { "participantAttributes" | "participant_attributes" => Ok(GeneratedField::ParticipantAttributes), "dtmf" => Ok(GeneratedField::Dtmf), "playRingtone" | "play_ringtone" => Ok(GeneratedField::PlayRingtone), + "playDialtone" | "play_dialtone" => Ok(GeneratedField::PlayDialtone), "hidePhoneNumber" | "hide_phone_number" => Ok(GeneratedField::HidePhoneNumber), + "ringingTimeout" | "ringing_timeout" => Ok(GeneratedField::RingingTimeout), + "maxCallDuration" | "max_call_duration" => Ok(GeneratedField::MaxCallDuration), + "enableKrisp" | "enable_krisp" => Ok(GeneratedField::EnableKrisp), _ => Ok(GeneratedField::__SkipField__), } } @@ -4419,6 +4469,7 @@ impl<'de> serde::Deserialize<'de> for CreateSipParticipantRequest { { let mut sip_trunk_id__ = None; let mut sip_call_to__ = None; + let mut sip_number__ = None; let mut room_name__ = None; let mut participant_identity__ = None; let mut participant_name__ = None; @@ -4426,7 +4477,11 @@ impl<'de> serde::Deserialize<'de> for CreateSipParticipantRequest { let mut participant_attributes__ = None; let mut dtmf__ = None; let mut play_ringtone__ = None; + let mut play_dialtone__ = None; let mut hide_phone_number__ = None; + let mut ringing_timeout__ = None; + let mut max_call_duration__ = None; + let mut enable_krisp__ = None; while let Some(k) = map_.next_key()? { match k { GeneratedField::SipTrunkId => { @@ -4441,6 +4496,12 @@ impl<'de> serde::Deserialize<'de> for CreateSipParticipantRequest { } sip_call_to__ = Some(map_.next_value()?); } + GeneratedField::SipNumber => { + if sip_number__.is_some() { + return Err(serde::de::Error::duplicate_field("sipNumber")); + } + sip_number__ = Some(map_.next_value()?); + } GeneratedField::RoomName => { if room_name__.is_some() { return Err(serde::de::Error::duplicate_field("roomName")); @@ -4485,12 +4546,36 @@ impl<'de> serde::Deserialize<'de> for CreateSipParticipantRequest { } play_ringtone__ = Some(map_.next_value()?); } + GeneratedField::PlayDialtone => { + if play_dialtone__.is_some() { + return Err(serde::de::Error::duplicate_field("playDialtone")); + } + play_dialtone__ = Some(map_.next_value()?); + } GeneratedField::HidePhoneNumber => { if hide_phone_number__.is_some() { return Err(serde::de::Error::duplicate_field("hidePhoneNumber")); } hide_phone_number__ = Some(map_.next_value()?); } + GeneratedField::RingingTimeout => { + if ringing_timeout__.is_some() { + return Err(serde::de::Error::duplicate_field("ringingTimeout")); + } + ringing_timeout__ = map_.next_value()?; + } + GeneratedField::MaxCallDuration => { + if max_call_duration__.is_some() { + return Err(serde::de::Error::duplicate_field("maxCallDuration")); + } + max_call_duration__ = map_.next_value()?; + } + GeneratedField::EnableKrisp => { + if enable_krisp__.is_some() { + return Err(serde::de::Error::duplicate_field("enableKrisp")); + } + enable_krisp__ = Some(map_.next_value()?); + } GeneratedField::__SkipField__ => { let _ = map_.next_value::()?; } @@ -4499,6 +4584,7 @@ impl<'de> serde::Deserialize<'de> for CreateSipParticipantRequest { Ok(CreateSipParticipantRequest { sip_trunk_id: sip_trunk_id__.unwrap_or_default(), sip_call_to: sip_call_to__.unwrap_or_default(), + sip_number: sip_number__.unwrap_or_default(), room_name: room_name__.unwrap_or_default(), participant_identity: participant_identity__.unwrap_or_default(), participant_name: participant_name__.unwrap_or_default(), @@ -4506,7 +4592,11 @@ impl<'de> serde::Deserialize<'de> for CreateSipParticipantRequest { participant_attributes: participant_attributes__.unwrap_or_default(), dtmf: dtmf__.unwrap_or_default(), play_ringtone: play_ringtone__.unwrap_or_default(), + play_dialtone: play_dialtone__.unwrap_or_default(), hide_phone_number: hide_phone_number__.unwrap_or_default(), + ringing_timeout: ringing_timeout__, + max_call_duration: max_call_duration__, + enable_krisp: enable_krisp__.unwrap_or_default(), }) } } @@ -4981,6 +5071,12 @@ impl serde::Serialize for DataPacket { data_packet::Value::RpcResponse(v) => { struct_ser.serialize_field("rpcResponse", v)?; } + data_packet::Value::StreamHeader(v) => { + struct_ser.serialize_field("streamHeader", v)?; + } + data_packet::Value::StreamChunk(v) => { + struct_ser.serialize_field("streamChunk", v)?; + } } } struct_ser.end() @@ -5012,6 +5108,10 @@ impl<'de> serde::Deserialize<'de> for DataPacket { "rpcAck", "rpc_response", "rpcResponse", + "stream_header", + "streamHeader", + "stream_chunk", + "streamChunk", ]; #[allow(clippy::enum_variant_names)] @@ -5028,6 +5128,8 @@ impl<'de> serde::Deserialize<'de> for DataPacket { RpcRequest, RpcAck, RpcResponse, + StreamHeader, + StreamChunk, __SkipField__, } impl<'de> serde::Deserialize<'de> for GeneratedField { @@ -5062,6 +5164,8 @@ impl<'de> serde::Deserialize<'de> for DataPacket { "rpcRequest" | "rpc_request" => Ok(GeneratedField::RpcRequest), "rpcAck" | "rpc_ack" => Ok(GeneratedField::RpcAck), "rpcResponse" | "rpc_response" => Ok(GeneratedField::RpcResponse), + "streamHeader" | "stream_header" => Ok(GeneratedField::StreamHeader), + "streamChunk" | "stream_chunk" => Ok(GeneratedField::StreamChunk), _ => Ok(GeneratedField::__SkipField__), } } @@ -5166,6 +5270,20 @@ impl<'de> serde::Deserialize<'de> for DataPacket { return Err(serde::de::Error::duplicate_field("rpcResponse")); } value__ = map_.next_value::<::std::option::Option<_>>()?.map(data_packet::Value::RpcResponse) +; + } + GeneratedField::StreamHeader => { + if value__.is_some() { + return Err(serde::de::Error::duplicate_field("streamHeader")); + } + value__ = map_.next_value::<::std::option::Option<_>>()?.map(data_packet::Value::StreamHeader) +; + } + GeneratedField::StreamChunk => { + if value__.is_some() { + return Err(serde::de::Error::duplicate_field("streamChunk")); + } + value__ = map_.next_value::<::std::option::Option<_>>()?.map(data_packet::Value::StreamChunk) ; } GeneratedField::__SkipField__ => { @@ -5255,46 +5373,29 @@ impl<'de> serde::Deserialize<'de> for data_packet::Kind { deserializer.deserialize_any(GeneratedVisitor) } } -impl serde::Serialize for DeleteAgentDispatchRequest { +impl serde::Serialize for DataStream { #[allow(deprecated)] fn serialize(&self, serializer: S) -> std::result::Result where S: serde::Serializer, { use serde::ser::SerializeStruct; - let mut len = 0; - if !self.dispatch_id.is_empty() { - len += 1; - } - if !self.room.is_empty() { - len += 1; - } - let mut struct_ser = serializer.serialize_struct("livekit.DeleteAgentDispatchRequest", len)?; - if !self.dispatch_id.is_empty() { - struct_ser.serialize_field("dispatchId", &self.dispatch_id)?; - } - if !self.room.is_empty() { - struct_ser.serialize_field("room", &self.room)?; - } + let len = 0; + let struct_ser = serializer.serialize_struct("livekit.DataStream", len)?; struct_ser.end() } } -impl<'de> serde::Deserialize<'de> for DeleteAgentDispatchRequest { +impl<'de> serde::Deserialize<'de> for DataStream { #[allow(deprecated)] fn deserialize(deserializer: D) -> std::result::Result where D: serde::Deserializer<'de>, { const FIELDS: &[&str] = &[ - "dispatch_id", - "dispatchId", - "room", ]; #[allow(clippy::enum_variant_names)] enum GeneratedField { - DispatchId, - Room, __SkipField__, } impl<'de> serde::Deserialize<'de> for GeneratedField { @@ -5316,11 +5417,7 @@ impl<'de> serde::Deserialize<'de> for DeleteAgentDispatchRequest { where E: serde::de::Error, { - match value { - "dispatchId" | "dispatch_id" => Ok(GeneratedField::DispatchId), - "room" => Ok(GeneratedField::Room), - _ => Ok(GeneratedField::__SkipField__), - } + Ok(GeneratedField::__SkipField__) } } deserializer.deserialize_identifier(GeneratedVisitor) @@ -5328,47 +5425,27 @@ impl<'de> serde::Deserialize<'de> for DeleteAgentDispatchRequest { } struct GeneratedVisitor; impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { - type Value = DeleteAgentDispatchRequest; + type Value = DataStream; fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - formatter.write_str("struct livekit.DeleteAgentDispatchRequest") + formatter.write_str("struct livekit.DataStream") } - fn visit_map(self, mut map_: V) -> std::result::Result + fn visit_map(self, mut map_: V) -> std::result::Result where V: serde::de::MapAccess<'de>, { - let mut dispatch_id__ = None; - let mut room__ = None; - while let Some(k) = map_.next_key()? { - match k { - GeneratedField::DispatchId => { - if dispatch_id__.is_some() { - return Err(serde::de::Error::duplicate_field("dispatchId")); - } - dispatch_id__ = Some(map_.next_value()?); - } - GeneratedField::Room => { - if room__.is_some() { - return Err(serde::de::Error::duplicate_field("room")); - } - room__ = Some(map_.next_value()?); - } - GeneratedField::__SkipField__ => { - let _ = map_.next_value::()?; - } - } + while map_.next_key::()?.is_some() { + let _ = map_.next_value::()?; } - Ok(DeleteAgentDispatchRequest { - dispatch_id: dispatch_id__.unwrap_or_default(), - room: room__.unwrap_or_default(), + Ok(DataStream { }) } } - deserializer.deserialize_struct("livekit.DeleteAgentDispatchRequest", FIELDS, GeneratedVisitor) + deserializer.deserialize_struct("livekit.DataStream", FIELDS, GeneratedVisitor) } } -impl serde::Serialize for DeleteIngressRequest { +impl serde::Serialize for data_stream::Chunk { #[allow(deprecated)] fn serialize(&self, serializer: S) -> std::result::Result where @@ -5376,30 +5453,77 @@ impl serde::Serialize for DeleteIngressRequest { { use serde::ser::SerializeStruct; let mut len = 0; - if !self.ingress_id.is_empty() { + if !self.stream_id.is_empty() { len += 1; } - let mut struct_ser = serializer.serialize_struct("livekit.DeleteIngressRequest", len)?; - if !self.ingress_id.is_empty() { - struct_ser.serialize_field("ingressId", &self.ingress_id)?; + if self.chunk_index != 0 { + len += 1; + } + if !self.content.is_empty() { + len += 1; + } + if self.complete { + len += 1; + } + if self.version != 0 { + len += 1; + } + if self.iv.is_some() { + len += 1; + } + let mut struct_ser = serializer.serialize_struct("livekit.DataStream.Chunk", len)?; + if !self.stream_id.is_empty() { + struct_ser.serialize_field("streamId", &self.stream_id)?; + } + if self.chunk_index != 0 { + #[allow(clippy::needless_borrow)] + #[allow(clippy::needless_borrows_for_generic_args)] + struct_ser.serialize_field("chunkIndex", ToString::to_string(&self.chunk_index).as_str())?; + } + if !self.content.is_empty() { + #[allow(clippy::needless_borrow)] + #[allow(clippy::needless_borrows_for_generic_args)] + struct_ser.serialize_field("content", pbjson::private::base64::encode(&self.content).as_str())?; + } + if self.complete { + struct_ser.serialize_field("complete", &self.complete)?; + } + if self.version != 0 { + struct_ser.serialize_field("version", &self.version)?; + } + if let Some(v) = self.iv.as_ref() { + #[allow(clippy::needless_borrow)] + #[allow(clippy::needless_borrows_for_generic_args)] + struct_ser.serialize_field("iv", pbjson::private::base64::encode(&v).as_str())?; } struct_ser.end() } } -impl<'de> serde::Deserialize<'de> for DeleteIngressRequest { +impl<'de> serde::Deserialize<'de> for data_stream::Chunk { #[allow(deprecated)] fn deserialize(deserializer: D) -> std::result::Result where D: serde::Deserializer<'de>, { const FIELDS: &[&str] = &[ - "ingress_id", - "ingressId", + "stream_id", + "streamId", + "chunk_index", + "chunkIndex", + "content", + "complete", + "version", + "iv", ]; #[allow(clippy::enum_variant_names)] enum GeneratedField { - IngressId, + StreamId, + ChunkIndex, + Content, + Complete, + Version, + Iv, __SkipField__, } impl<'de> serde::Deserialize<'de> for GeneratedField { @@ -5422,7 +5546,12 @@ impl<'de> serde::Deserialize<'de> for DeleteIngressRequest { E: serde::de::Error, { match value { - "ingressId" | "ingress_id" => Ok(GeneratedField::IngressId), + "streamId" | "stream_id" => Ok(GeneratedField::StreamId), + "chunkIndex" | "chunk_index" => Ok(GeneratedField::ChunkIndex), + "content" => Ok(GeneratedField::Content), + "complete" => Ok(GeneratedField::Complete), + "version" => Ok(GeneratedField::Version), + "iv" => Ok(GeneratedField::Iv), _ => Ok(GeneratedField::__SkipField__), } } @@ -5432,39 +5561,87 @@ impl<'de> serde::Deserialize<'de> for DeleteIngressRequest { } struct GeneratedVisitor; impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { - type Value = DeleteIngressRequest; + type Value = data_stream::Chunk; fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - formatter.write_str("struct livekit.DeleteIngressRequest") + formatter.write_str("struct livekit.DataStream.Chunk") } - fn visit_map(self, mut map_: V) -> std::result::Result + fn visit_map(self, mut map_: V) -> std::result::Result where V: serde::de::MapAccess<'de>, { - let mut ingress_id__ = None; + let mut stream_id__ = None; + let mut chunk_index__ = None; + let mut content__ = None; + let mut complete__ = None; + let mut version__ = None; + let mut iv__ = None; while let Some(k) = map_.next_key()? { match k { - GeneratedField::IngressId => { - if ingress_id__.is_some() { - return Err(serde::de::Error::duplicate_field("ingressId")); + GeneratedField::StreamId => { + if stream_id__.is_some() { + return Err(serde::de::Error::duplicate_field("streamId")); } - ingress_id__ = Some(map_.next_value()?); + stream_id__ = Some(map_.next_value()?); + } + GeneratedField::ChunkIndex => { + if chunk_index__.is_some() { + return Err(serde::de::Error::duplicate_field("chunkIndex")); + } + chunk_index__ = + Some(map_.next_value::<::pbjson::private::NumberDeserialize<_>>()?.0) + ; + } + GeneratedField::Content => { + if content__.is_some() { + return Err(serde::de::Error::duplicate_field("content")); + } + content__ = + Some(map_.next_value::<::pbjson::private::BytesDeserialize<_>>()?.0) + ; + } + GeneratedField::Complete => { + if complete__.is_some() { + return Err(serde::de::Error::duplicate_field("complete")); + } + complete__ = Some(map_.next_value()?); + } + GeneratedField::Version => { + if version__.is_some() { + return Err(serde::de::Error::duplicate_field("version")); + } + version__ = + Some(map_.next_value::<::pbjson::private::NumberDeserialize<_>>()?.0) + ; + } + GeneratedField::Iv => { + if iv__.is_some() { + return Err(serde::de::Error::duplicate_field("iv")); + } + iv__ = + map_.next_value::<::std::option::Option<::pbjson::private::BytesDeserialize<_>>>()?.map(|x| x.0) + ; } GeneratedField::__SkipField__ => { let _ = map_.next_value::()?; } } } - Ok(DeleteIngressRequest { - ingress_id: ingress_id__.unwrap_or_default(), + Ok(data_stream::Chunk { + stream_id: stream_id__.unwrap_or_default(), + chunk_index: chunk_index__.unwrap_or_default(), + content: content__.unwrap_or_default(), + complete: complete__.unwrap_or_default(), + version: version__.unwrap_or_default(), + iv: iv__, }) } } - deserializer.deserialize_struct("livekit.DeleteIngressRequest", FIELDS, GeneratedVisitor) + deserializer.deserialize_struct("livekit.DataStream.Chunk", FIELDS, GeneratedVisitor) } } -impl serde::Serialize for DeleteRoomRequest { +impl serde::Serialize for data_stream::FileHeader { #[allow(deprecated)] fn serialize(&self, serializer: S) -> std::result::Result where @@ -5472,29 +5649,30 @@ impl serde::Serialize for DeleteRoomRequest { { use serde::ser::SerializeStruct; let mut len = 0; - if !self.room.is_empty() { + if !self.file_name.is_empty() { len += 1; } - let mut struct_ser = serializer.serialize_struct("livekit.DeleteRoomRequest", len)?; - if !self.room.is_empty() { - struct_ser.serialize_field("room", &self.room)?; + let mut struct_ser = serializer.serialize_struct("livekit.DataStream.FileHeader", len)?; + if !self.file_name.is_empty() { + struct_ser.serialize_field("fileName", &self.file_name)?; } struct_ser.end() } } -impl<'de> serde::Deserialize<'de> for DeleteRoomRequest { +impl<'de> serde::Deserialize<'de> for data_stream::FileHeader { #[allow(deprecated)] fn deserialize(deserializer: D) -> std::result::Result where D: serde::Deserializer<'de>, { const FIELDS: &[&str] = &[ - "room", + "file_name", + "fileName", ]; #[allow(clippy::enum_variant_names)] enum GeneratedField { - Room, + FileName, __SkipField__, } impl<'de> serde::Deserialize<'de> for GeneratedField { @@ -5517,7 +5695,7 @@ impl<'de> serde::Deserialize<'de> for DeleteRoomRequest { E: serde::de::Error, { match value { - "room" => Ok(GeneratedField::Room), + "fileName" | "file_name" => Ok(GeneratedField::FileName), _ => Ok(GeneratedField::__SkipField__), } } @@ -5527,61 +5705,157 @@ impl<'de> serde::Deserialize<'de> for DeleteRoomRequest { } struct GeneratedVisitor; impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { - type Value = DeleteRoomRequest; + type Value = data_stream::FileHeader; fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - formatter.write_str("struct livekit.DeleteRoomRequest") + formatter.write_str("struct livekit.DataStream.FileHeader") } - fn visit_map(self, mut map_: V) -> std::result::Result + fn visit_map(self, mut map_: V) -> std::result::Result where V: serde::de::MapAccess<'de>, { - let mut room__ = None; + let mut file_name__ = None; while let Some(k) = map_.next_key()? { match k { - GeneratedField::Room => { - if room__.is_some() { - return Err(serde::de::Error::duplicate_field("room")); + GeneratedField::FileName => { + if file_name__.is_some() { + return Err(serde::de::Error::duplicate_field("fileName")); } - room__ = Some(map_.next_value()?); + file_name__ = Some(map_.next_value()?); } GeneratedField::__SkipField__ => { let _ = map_.next_value::()?; } } } - Ok(DeleteRoomRequest { - room: room__.unwrap_or_default(), + Ok(data_stream::FileHeader { + file_name: file_name__.unwrap_or_default(), }) } } - deserializer.deserialize_struct("livekit.DeleteRoomRequest", FIELDS, GeneratedVisitor) + deserializer.deserialize_struct("livekit.DataStream.FileHeader", FIELDS, GeneratedVisitor) } } -impl serde::Serialize for DeleteRoomResponse { +impl serde::Serialize for data_stream::Header { #[allow(deprecated)] fn serialize(&self, serializer: S) -> std::result::Result where S: serde::Serializer, { use serde::ser::SerializeStruct; - let len = 0; - let struct_ser = serializer.serialize_struct("livekit.DeleteRoomResponse", len)?; + let mut len = 0; + if !self.stream_id.is_empty() { + len += 1; + } + if self.timestamp != 0 { + len += 1; + } + if !self.topic.is_empty() { + len += 1; + } + if !self.mime_type.is_empty() { + len += 1; + } + if self.total_length.is_some() { + len += 1; + } + if self.total_chunks.is_some() { + len += 1; + } + if self.encryption_type != 0 { + len += 1; + } + if !self.extensions.is_empty() { + len += 1; + } + if self.content_header.is_some() { + len += 1; + } + let mut struct_ser = serializer.serialize_struct("livekit.DataStream.Header", len)?; + if !self.stream_id.is_empty() { + struct_ser.serialize_field("streamId", &self.stream_id)?; + } + if self.timestamp != 0 { + #[allow(clippy::needless_borrow)] + #[allow(clippy::needless_borrows_for_generic_args)] + struct_ser.serialize_field("timestamp", ToString::to_string(&self.timestamp).as_str())?; + } + if !self.topic.is_empty() { + struct_ser.serialize_field("topic", &self.topic)?; + } + if !self.mime_type.is_empty() { + struct_ser.serialize_field("mimeType", &self.mime_type)?; + } + if let Some(v) = self.total_length.as_ref() { + #[allow(clippy::needless_borrow)] + #[allow(clippy::needless_borrows_for_generic_args)] + struct_ser.serialize_field("totalLength", ToString::to_string(&v).as_str())?; + } + if let Some(v) = self.total_chunks.as_ref() { + #[allow(clippy::needless_borrow)] + #[allow(clippy::needless_borrows_for_generic_args)] + struct_ser.serialize_field("totalChunks", ToString::to_string(&v).as_str())?; + } + if self.encryption_type != 0 { + let v = encryption::Type::try_from(self.encryption_type) + .map_err(|_| serde::ser::Error::custom(format!("Invalid variant {}", self.encryption_type)))?; + struct_ser.serialize_field("encryptionType", &v)?; + } + if !self.extensions.is_empty() { + struct_ser.serialize_field("extensions", &self.extensions)?; + } + if let Some(v) = self.content_header.as_ref() { + match v { + data_stream::header::ContentHeader::TextHeader(v) => { + struct_ser.serialize_field("textHeader", v)?; + } + data_stream::header::ContentHeader::FileHeader(v) => { + struct_ser.serialize_field("fileHeader", v)?; + } + } + } struct_ser.end() } } -impl<'de> serde::Deserialize<'de> for DeleteRoomResponse { +impl<'de> serde::Deserialize<'de> for data_stream::Header { #[allow(deprecated)] fn deserialize(deserializer: D) -> std::result::Result where D: serde::Deserializer<'de>, { const FIELDS: &[&str] = &[ + "stream_id", + "streamId", + "timestamp", + "topic", + "mime_type", + "mimeType", + "total_length", + "totalLength", + "total_chunks", + "totalChunks", + "encryption_type", + "encryptionType", + "extensions", + "text_header", + "textHeader", + "file_header", + "fileHeader", ]; #[allow(clippy::enum_variant_names)] enum GeneratedField { + StreamId, + Timestamp, + Topic, + MimeType, + TotalLength, + TotalChunks, + EncryptionType, + Extensions, + TextHeader, + FileHeader, __SkipField__, } impl<'de> serde::Deserialize<'de> for GeneratedField { @@ -5603,7 +5877,19 @@ impl<'de> serde::Deserialize<'de> for DeleteRoomResponse { where E: serde::de::Error, { - Ok(GeneratedField::__SkipField__) + match value { + "streamId" | "stream_id" => Ok(GeneratedField::StreamId), + "timestamp" => Ok(GeneratedField::Timestamp), + "topic" => Ok(GeneratedField::Topic), + "mimeType" | "mime_type" => Ok(GeneratedField::MimeType), + "totalLength" | "total_length" => Ok(GeneratedField::TotalLength), + "totalChunks" | "total_chunks" => Ok(GeneratedField::TotalChunks), + "encryptionType" | "encryption_type" => Ok(GeneratedField::EncryptionType), + "extensions" => Ok(GeneratedField::Extensions), + "textHeader" | "text_header" => Ok(GeneratedField::TextHeader), + "fileHeader" | "file_header" => Ok(GeneratedField::FileHeader), + _ => Ok(GeneratedField::__SkipField__), + } } } deserializer.deserialize_identifier(GeneratedVisitor) @@ -5611,27 +5897,196 @@ impl<'de> serde::Deserialize<'de> for DeleteRoomResponse { } struct GeneratedVisitor; impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { - type Value = DeleteRoomResponse; + type Value = data_stream::Header; fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - formatter.write_str("struct livekit.DeleteRoomResponse") + formatter.write_str("struct livekit.DataStream.Header") } - fn visit_map(self, mut map_: V) -> std::result::Result + fn visit_map(self, mut map_: V) -> std::result::Result where V: serde::de::MapAccess<'de>, { - while map_.next_key::()?.is_some() { - let _ = map_.next_value::()?; + let mut stream_id__ = None; + let mut timestamp__ = None; + let mut topic__ = None; + let mut mime_type__ = None; + let mut total_length__ = None; + let mut total_chunks__ = None; + let mut encryption_type__ = None; + let mut extensions__ = None; + let mut content_header__ = None; + while let Some(k) = map_.next_key()? { + match k { + GeneratedField::StreamId => { + if stream_id__.is_some() { + return Err(serde::de::Error::duplicate_field("streamId")); + } + stream_id__ = Some(map_.next_value()?); + } + GeneratedField::Timestamp => { + if timestamp__.is_some() { + return Err(serde::de::Error::duplicate_field("timestamp")); + } + timestamp__ = + Some(map_.next_value::<::pbjson::private::NumberDeserialize<_>>()?.0) + ; + } + GeneratedField::Topic => { + if topic__.is_some() { + return Err(serde::de::Error::duplicate_field("topic")); + } + topic__ = Some(map_.next_value()?); + } + GeneratedField::MimeType => { + if mime_type__.is_some() { + return Err(serde::de::Error::duplicate_field("mimeType")); + } + mime_type__ = Some(map_.next_value()?); + } + GeneratedField::TotalLength => { + if total_length__.is_some() { + return Err(serde::de::Error::duplicate_field("totalLength")); + } + total_length__ = + map_.next_value::<::std::option::Option<::pbjson::private::NumberDeserialize<_>>>()?.map(|x| x.0) + ; + } + GeneratedField::TotalChunks => { + if total_chunks__.is_some() { + return Err(serde::de::Error::duplicate_field("totalChunks")); + } + total_chunks__ = + map_.next_value::<::std::option::Option<::pbjson::private::NumberDeserialize<_>>>()?.map(|x| x.0) + ; + } + GeneratedField::EncryptionType => { + if encryption_type__.is_some() { + return Err(serde::de::Error::duplicate_field("encryptionType")); + } + encryption_type__ = Some(map_.next_value::()? as i32); + } + GeneratedField::Extensions => { + if extensions__.is_some() { + return Err(serde::de::Error::duplicate_field("extensions")); + } + extensions__ = Some( + map_.next_value::>()? + ); + } + GeneratedField::TextHeader => { + if content_header__.is_some() { + return Err(serde::de::Error::duplicate_field("textHeader")); + } + content_header__ = map_.next_value::<::std::option::Option<_>>()?.map(data_stream::header::ContentHeader::TextHeader) +; + } + GeneratedField::FileHeader => { + if content_header__.is_some() { + return Err(serde::de::Error::duplicate_field("fileHeader")); + } + content_header__ = map_.next_value::<::std::option::Option<_>>()?.map(data_stream::header::ContentHeader::FileHeader) +; + } + GeneratedField::__SkipField__ => { + let _ = map_.next_value::()?; + } + } } - Ok(DeleteRoomResponse { + Ok(data_stream::Header { + stream_id: stream_id__.unwrap_or_default(), + timestamp: timestamp__.unwrap_or_default(), + topic: topic__.unwrap_or_default(), + mime_type: mime_type__.unwrap_or_default(), + total_length: total_length__, + total_chunks: total_chunks__, + encryption_type: encryption_type__.unwrap_or_default(), + extensions: extensions__.unwrap_or_default(), + content_header: content_header__, }) } } - deserializer.deserialize_struct("livekit.DeleteRoomResponse", FIELDS, GeneratedVisitor) + deserializer.deserialize_struct("livekit.DataStream.Header", FIELDS, GeneratedVisitor) } } -impl serde::Serialize for DeleteSipDispatchRuleRequest { +impl serde::Serialize for data_stream::OperationType { + #[allow(deprecated)] + fn serialize(&self, serializer: S) -> std::result::Result + where + S: serde::Serializer, + { + let variant = match self { + Self::Create => "CREATE", + Self::Update => "UPDATE", + Self::Delete => "DELETE", + Self::Reaction => "REACTION", + }; + serializer.serialize_str(variant) + } +} +impl<'de> serde::Deserialize<'de> for data_stream::OperationType { + #[allow(deprecated)] + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + const FIELDS: &[&str] = &[ + "CREATE", + "UPDATE", + "DELETE", + "REACTION", + ]; + + struct GeneratedVisitor; + + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = data_stream::OperationType; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(formatter, "expected one of: {:?}", &FIELDS) + } + + fn visit_i64(self, v: i64) -> std::result::Result + where + E: serde::de::Error, + { + i32::try_from(v) + .ok() + .and_then(|x| x.try_into().ok()) + .ok_or_else(|| { + serde::de::Error::invalid_value(serde::de::Unexpected::Signed(v), &self) + }) + } + + fn visit_u64(self, v: u64) -> std::result::Result + where + E: serde::de::Error, + { + i32::try_from(v) + .ok() + .and_then(|x| x.try_into().ok()) + .ok_or_else(|| { + serde::de::Error::invalid_value(serde::de::Unexpected::Unsigned(v), &self) + }) + } + + fn visit_str(self, value: &str) -> std::result::Result + where + E: serde::de::Error, + { + match value { + "CREATE" => Ok(data_stream::OperationType::Create), + "UPDATE" => Ok(data_stream::OperationType::Update), + "DELETE" => Ok(data_stream::OperationType::Delete), + "REACTION" => Ok(data_stream::OperationType::Reaction), + _ => Err(serde::de::Error::unknown_variant(value, FIELDS)), + } + } + } + deserializer.deserialize_any(GeneratedVisitor) + } +} +impl serde::Serialize for data_stream::TextHeader { #[allow(deprecated)] fn serialize(&self, serializer: S) -> std::result::Result where @@ -5639,30 +6094,66 @@ impl serde::Serialize for DeleteSipDispatchRuleRequest { { use serde::ser::SerializeStruct; let mut len = 0; - if !self.sip_dispatch_rule_id.is_empty() { + if self.operation_type != 0 { len += 1; } - let mut struct_ser = serializer.serialize_struct("livekit.DeleteSIPDispatchRuleRequest", len)?; - if !self.sip_dispatch_rule_id.is_empty() { - struct_ser.serialize_field("sipDispatchRuleId", &self.sip_dispatch_rule_id)?; + if self.version != 0 { + len += 1; + } + if !self.reply_to_stream_id.is_empty() { + len += 1; + } + if !self.attached_stream_ids.is_empty() { + len += 1; + } + if self.generated { + len += 1; + } + let mut struct_ser = serializer.serialize_struct("livekit.DataStream.TextHeader", len)?; + if self.operation_type != 0 { + let v = data_stream::OperationType::try_from(self.operation_type) + .map_err(|_| serde::ser::Error::custom(format!("Invalid variant {}", self.operation_type)))?; + struct_ser.serialize_field("operationType", &v)?; + } + if self.version != 0 { + struct_ser.serialize_field("version", &self.version)?; + } + if !self.reply_to_stream_id.is_empty() { + struct_ser.serialize_field("replyToStreamId", &self.reply_to_stream_id)?; + } + if !self.attached_stream_ids.is_empty() { + struct_ser.serialize_field("attachedStreamIds", &self.attached_stream_ids)?; + } + if self.generated { + struct_ser.serialize_field("generated", &self.generated)?; } struct_ser.end() } } -impl<'de> serde::Deserialize<'de> for DeleteSipDispatchRuleRequest { +impl<'de> serde::Deserialize<'de> for data_stream::TextHeader { #[allow(deprecated)] fn deserialize(deserializer: D) -> std::result::Result where D: serde::Deserializer<'de>, { const FIELDS: &[&str] = &[ - "sip_dispatch_rule_id", - "sipDispatchRuleId", + "operation_type", + "operationType", + "version", + "reply_to_stream_id", + "replyToStreamId", + "attached_stream_ids", + "attachedStreamIds", + "generated", ]; #[allow(clippy::enum_variant_names)] enum GeneratedField { - SipDispatchRuleId, + OperationType, + Version, + ReplyToStreamId, + AttachedStreamIds, + Generated, __SkipField__, } impl<'de> serde::Deserialize<'de> for GeneratedField { @@ -5685,7 +6176,11 @@ impl<'de> serde::Deserialize<'de> for DeleteSipDispatchRuleRequest { E: serde::de::Error, { match value { - "sipDispatchRuleId" | "sip_dispatch_rule_id" => Ok(GeneratedField::SipDispatchRuleId), + "operationType" | "operation_type" => Ok(GeneratedField::OperationType), + "version" => Ok(GeneratedField::Version), + "replyToStreamId" | "reply_to_stream_id" => Ok(GeneratedField::ReplyToStreamId), + "attachedStreamIds" | "attached_stream_ids" => Ok(GeneratedField::AttachedStreamIds), + "generated" => Ok(GeneratedField::Generated), _ => Ok(GeneratedField::__SkipField__), } } @@ -5695,39 +6190,73 @@ impl<'de> serde::Deserialize<'de> for DeleteSipDispatchRuleRequest { } struct GeneratedVisitor; impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { - type Value = DeleteSipDispatchRuleRequest; + type Value = data_stream::TextHeader; fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - formatter.write_str("struct livekit.DeleteSIPDispatchRuleRequest") + formatter.write_str("struct livekit.DataStream.TextHeader") } - fn visit_map(self, mut map_: V) -> std::result::Result + fn visit_map(self, mut map_: V) -> std::result::Result where V: serde::de::MapAccess<'de>, { - let mut sip_dispatch_rule_id__ = None; + let mut operation_type__ = None; + let mut version__ = None; + let mut reply_to_stream_id__ = None; + let mut attached_stream_ids__ = None; + let mut generated__ = None; while let Some(k) = map_.next_key()? { match k { - GeneratedField::SipDispatchRuleId => { - if sip_dispatch_rule_id__.is_some() { - return Err(serde::de::Error::duplicate_field("sipDispatchRuleId")); + GeneratedField::OperationType => { + if operation_type__.is_some() { + return Err(serde::de::Error::duplicate_field("operationType")); } - sip_dispatch_rule_id__ = Some(map_.next_value()?); + operation_type__ = Some(map_.next_value::()? as i32); + } + GeneratedField::Version => { + if version__.is_some() { + return Err(serde::de::Error::duplicate_field("version")); + } + version__ = + Some(map_.next_value::<::pbjson::private::NumberDeserialize<_>>()?.0) + ; + } + GeneratedField::ReplyToStreamId => { + if reply_to_stream_id__.is_some() { + return Err(serde::de::Error::duplicate_field("replyToStreamId")); + } + reply_to_stream_id__ = Some(map_.next_value()?); + } + GeneratedField::AttachedStreamIds => { + if attached_stream_ids__.is_some() { + return Err(serde::de::Error::duplicate_field("attachedStreamIds")); + } + attached_stream_ids__ = Some(map_.next_value()?); + } + GeneratedField::Generated => { + if generated__.is_some() { + return Err(serde::de::Error::duplicate_field("generated")); + } + generated__ = Some(map_.next_value()?); } GeneratedField::__SkipField__ => { let _ = map_.next_value::()?; } } } - Ok(DeleteSipDispatchRuleRequest { - sip_dispatch_rule_id: sip_dispatch_rule_id__.unwrap_or_default(), + Ok(data_stream::TextHeader { + operation_type: operation_type__.unwrap_or_default(), + version: version__.unwrap_or_default(), + reply_to_stream_id: reply_to_stream_id__.unwrap_or_default(), + attached_stream_ids: attached_stream_ids__.unwrap_or_default(), + generated: generated__.unwrap_or_default(), }) } } - deserializer.deserialize_struct("livekit.DeleteSIPDispatchRuleRequest", FIELDS, GeneratedVisitor) + deserializer.deserialize_struct("livekit.DataStream.TextHeader", FIELDS, GeneratedVisitor) } } -impl serde::Serialize for DeleteSipTrunkRequest { +impl serde::Serialize for DeleteAgentDispatchRequest { #[allow(deprecated)] fn serialize(&self, serializer: S) -> std::result::Result where @@ -5735,30 +6264,38 @@ impl serde::Serialize for DeleteSipTrunkRequest { { use serde::ser::SerializeStruct; let mut len = 0; - if !self.sip_trunk_id.is_empty() { + if !self.dispatch_id.is_empty() { len += 1; } - let mut struct_ser = serializer.serialize_struct("livekit.DeleteSIPTrunkRequest", len)?; - if !self.sip_trunk_id.is_empty() { - struct_ser.serialize_field("sipTrunkId", &self.sip_trunk_id)?; + if !self.room.is_empty() { + len += 1; + } + let mut struct_ser = serializer.serialize_struct("livekit.DeleteAgentDispatchRequest", len)?; + if !self.dispatch_id.is_empty() { + struct_ser.serialize_field("dispatchId", &self.dispatch_id)?; + } + if !self.room.is_empty() { + struct_ser.serialize_field("room", &self.room)?; } struct_ser.end() } } -impl<'de> serde::Deserialize<'de> for DeleteSipTrunkRequest { +impl<'de> serde::Deserialize<'de> for DeleteAgentDispatchRequest { #[allow(deprecated)] fn deserialize(deserializer: D) -> std::result::Result where D: serde::Deserializer<'de>, { const FIELDS: &[&str] = &[ - "sip_trunk_id", - "sipTrunkId", + "dispatch_id", + "dispatchId", + "room", ]; #[allow(clippy::enum_variant_names)] enum GeneratedField { - SipTrunkId, + DispatchId, + Room, __SkipField__, } impl<'de> serde::Deserialize<'de> for GeneratedField { @@ -5781,7 +6318,8 @@ impl<'de> serde::Deserialize<'de> for DeleteSipTrunkRequest { E: serde::de::Error, { match value { - "sipTrunkId" | "sip_trunk_id" => Ok(GeneratedField::SipTrunkId), + "dispatchId" | "dispatch_id" => Ok(GeneratedField::DispatchId), + "room" => Ok(GeneratedField::Room), _ => Ok(GeneratedField::__SkipField__), } } @@ -5791,39 +6329,47 @@ impl<'de> serde::Deserialize<'de> for DeleteSipTrunkRequest { } struct GeneratedVisitor; impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { - type Value = DeleteSipTrunkRequest; + type Value = DeleteAgentDispatchRequest; fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - formatter.write_str("struct livekit.DeleteSIPTrunkRequest") + formatter.write_str("struct livekit.DeleteAgentDispatchRequest") } - fn visit_map(self, mut map_: V) -> std::result::Result + fn visit_map(self, mut map_: V) -> std::result::Result where V: serde::de::MapAccess<'de>, { - let mut sip_trunk_id__ = None; + let mut dispatch_id__ = None; + let mut room__ = None; while let Some(k) = map_.next_key()? { match k { - GeneratedField::SipTrunkId => { - if sip_trunk_id__.is_some() { - return Err(serde::de::Error::duplicate_field("sipTrunkId")); + GeneratedField::DispatchId => { + if dispatch_id__.is_some() { + return Err(serde::de::Error::duplicate_field("dispatchId")); } - sip_trunk_id__ = Some(map_.next_value()?); + dispatch_id__ = Some(map_.next_value()?); + } + GeneratedField::Room => { + if room__.is_some() { + return Err(serde::de::Error::duplicate_field("room")); + } + room__ = Some(map_.next_value()?); } GeneratedField::__SkipField__ => { let _ = map_.next_value::()?; } } } - Ok(DeleteSipTrunkRequest { - sip_trunk_id: sip_trunk_id__.unwrap_or_default(), + Ok(DeleteAgentDispatchRequest { + dispatch_id: dispatch_id__.unwrap_or_default(), + room: room__.unwrap_or_default(), }) } } - deserializer.deserialize_struct("livekit.DeleteSIPTrunkRequest", FIELDS, GeneratedVisitor) + deserializer.deserialize_struct("livekit.DeleteAgentDispatchRequest", FIELDS, GeneratedVisitor) } } -impl serde::Serialize for DirectFileOutput { +impl serde::Serialize for DeleteIngressRequest { #[allow(deprecated)] fn serialize(&self, serializer: S) -> std::result::Result where @@ -5831,65 +6377,30 @@ impl serde::Serialize for DirectFileOutput { { use serde::ser::SerializeStruct; let mut len = 0; - if !self.filepath.is_empty() { - len += 1; - } - if self.disable_manifest { - len += 1; - } - if self.output.is_some() { + if !self.ingress_id.is_empty() { len += 1; } - let mut struct_ser = serializer.serialize_struct("livekit.DirectFileOutput", len)?; - if !self.filepath.is_empty() { - struct_ser.serialize_field("filepath", &self.filepath)?; - } - if self.disable_manifest { - struct_ser.serialize_field("disableManifest", &self.disable_manifest)?; - } - if let Some(v) = self.output.as_ref() { - match v { - direct_file_output::Output::S3(v) => { - struct_ser.serialize_field("s3", v)?; - } - direct_file_output::Output::Gcp(v) => { - struct_ser.serialize_field("gcp", v)?; - } - direct_file_output::Output::Azure(v) => { - struct_ser.serialize_field("azure", v)?; - } - direct_file_output::Output::AliOss(v) => { - struct_ser.serialize_field("aliOSS", v)?; - } - } + let mut struct_ser = serializer.serialize_struct("livekit.DeleteIngressRequest", len)?; + if !self.ingress_id.is_empty() { + struct_ser.serialize_field("ingressId", &self.ingress_id)?; } struct_ser.end() } } -impl<'de> serde::Deserialize<'de> for DirectFileOutput { +impl<'de> serde::Deserialize<'de> for DeleteIngressRequest { #[allow(deprecated)] fn deserialize(deserializer: D) -> std::result::Result where D: serde::Deserializer<'de>, { const FIELDS: &[&str] = &[ - "filepath", - "disable_manifest", - "disableManifest", - "s3", - "gcp", - "azure", - "aliOSS", + "ingress_id", + "ingressId", ]; #[allow(clippy::enum_variant_names)] enum GeneratedField { - Filepath, - DisableManifest, - S3, - Gcp, - Azure, - AliOss, + IngressId, __SkipField__, } impl<'de> serde::Deserialize<'de> for GeneratedField { @@ -5912,12 +6423,7 @@ impl<'de> serde::Deserialize<'de> for DirectFileOutput { E: serde::de::Error, { match value { - "filepath" => Ok(GeneratedField::Filepath), - "disableManifest" | "disable_manifest" => Ok(GeneratedField::DisableManifest), - "s3" => Ok(GeneratedField::S3), - "gcp" => Ok(GeneratedField::Gcp), - "azure" => Ok(GeneratedField::Azure), - "aliOSS" => Ok(GeneratedField::AliOss), + "ingressId" | "ingress_id" => Ok(GeneratedField::IngressId), _ => Ok(GeneratedField::__SkipField__), } } @@ -5927,77 +6433,39 @@ impl<'de> serde::Deserialize<'de> for DirectFileOutput { } struct GeneratedVisitor; impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { - type Value = DirectFileOutput; + type Value = DeleteIngressRequest; fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - formatter.write_str("struct livekit.DirectFileOutput") + formatter.write_str("struct livekit.DeleteIngressRequest") } - fn visit_map(self, mut map_: V) -> std::result::Result + fn visit_map(self, mut map_: V) -> std::result::Result where V: serde::de::MapAccess<'de>, { - let mut filepath__ = None; - let mut disable_manifest__ = None; - let mut output__ = None; + let mut ingress_id__ = None; while let Some(k) = map_.next_key()? { match k { - GeneratedField::Filepath => { - if filepath__.is_some() { - return Err(serde::de::Error::duplicate_field("filepath")); - } - filepath__ = Some(map_.next_value()?); - } - GeneratedField::DisableManifest => { - if disable_manifest__.is_some() { - return Err(serde::de::Error::duplicate_field("disableManifest")); - } - disable_manifest__ = Some(map_.next_value()?); - } - GeneratedField::S3 => { - if output__.is_some() { - return Err(serde::de::Error::duplicate_field("s3")); - } - output__ = map_.next_value::<::std::option::Option<_>>()?.map(direct_file_output::Output::S3) -; - } - GeneratedField::Gcp => { - if output__.is_some() { - return Err(serde::de::Error::duplicate_field("gcp")); - } - output__ = map_.next_value::<::std::option::Option<_>>()?.map(direct_file_output::Output::Gcp) -; - } - GeneratedField::Azure => { - if output__.is_some() { - return Err(serde::de::Error::duplicate_field("azure")); - } - output__ = map_.next_value::<::std::option::Option<_>>()?.map(direct_file_output::Output::Azure) -; - } - GeneratedField::AliOss => { - if output__.is_some() { - return Err(serde::de::Error::duplicate_field("aliOSS")); + GeneratedField::IngressId => { + if ingress_id__.is_some() { + return Err(serde::de::Error::duplicate_field("ingressId")); } - output__ = map_.next_value::<::std::option::Option<_>>()?.map(direct_file_output::Output::AliOss) -; + ingress_id__ = Some(map_.next_value()?); } GeneratedField::__SkipField__ => { let _ = map_.next_value::()?; } } } - Ok(DirectFileOutput { - filepath: filepath__.unwrap_or_default(), - disable_manifest: disable_manifest__.unwrap_or_default(), - output: output__, + Ok(DeleteIngressRequest { + ingress_id: ingress_id__.unwrap_or_default(), }) } } - deserializer.deserialize_struct("livekit.DirectFileOutput", FIELDS, GeneratedVisitor) + deserializer.deserialize_struct("livekit.DeleteIngressRequest", FIELDS, GeneratedVisitor) } } -impl serde::Serialize for DisabledCodecs { +impl serde::Serialize for DeleteRoomRequest { #[allow(deprecated)] fn serialize(&self, serializer: S) -> std::result::Result where @@ -6005,37 +6473,29 @@ impl serde::Serialize for DisabledCodecs { { use serde::ser::SerializeStruct; let mut len = 0; - if !self.codecs.is_empty() { - len += 1; - } - if !self.publish.is_empty() { + if !self.room.is_empty() { len += 1; } - let mut struct_ser = serializer.serialize_struct("livekit.DisabledCodecs", len)?; - if !self.codecs.is_empty() { - struct_ser.serialize_field("codecs", &self.codecs)?; - } - if !self.publish.is_empty() { - struct_ser.serialize_field("publish", &self.publish)?; + let mut struct_ser = serializer.serialize_struct("livekit.DeleteRoomRequest", len)?; + if !self.room.is_empty() { + struct_ser.serialize_field("room", &self.room)?; } struct_ser.end() } } -impl<'de> serde::Deserialize<'de> for DisabledCodecs { +impl<'de> serde::Deserialize<'de> for DeleteRoomRequest { #[allow(deprecated)] fn deserialize(deserializer: D) -> std::result::Result where D: serde::Deserializer<'de>, { const FIELDS: &[&str] = &[ - "codecs", - "publish", + "room", ]; #[allow(clippy::enum_variant_names)] enum GeneratedField { - Codecs, - Publish, + Room, __SkipField__, } impl<'de> serde::Deserialize<'de> for GeneratedField { @@ -6058,8 +6518,7 @@ impl<'de> serde::Deserialize<'de> for DisabledCodecs { E: serde::de::Error, { match value { - "codecs" => Ok(GeneratedField::Codecs), - "publish" => Ok(GeneratedField::Publish), + "room" => Ok(GeneratedField::Room), _ => Ok(GeneratedField::__SkipField__), } } @@ -6069,110 +6528,658 @@ impl<'de> serde::Deserialize<'de> for DisabledCodecs { } struct GeneratedVisitor; impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { - type Value = DisabledCodecs; + type Value = DeleteRoomRequest; fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - formatter.write_str("struct livekit.DisabledCodecs") + formatter.write_str("struct livekit.DeleteRoomRequest") } - fn visit_map(self, mut map_: V) -> std::result::Result + fn visit_map(self, mut map_: V) -> std::result::Result where V: serde::de::MapAccess<'de>, { - let mut codecs__ = None; - let mut publish__ = None; + let mut room__ = None; while let Some(k) = map_.next_key()? { match k { - GeneratedField::Codecs => { - if codecs__.is_some() { - return Err(serde::de::Error::duplicate_field("codecs")); - } - codecs__ = Some(map_.next_value()?); - } - GeneratedField::Publish => { - if publish__.is_some() { - return Err(serde::de::Error::duplicate_field("publish")); + GeneratedField::Room => { + if room__.is_some() { + return Err(serde::de::Error::duplicate_field("room")); } - publish__ = Some(map_.next_value()?); + room__ = Some(map_.next_value()?); } GeneratedField::__SkipField__ => { let _ = map_.next_value::()?; } } } - Ok(DisabledCodecs { - codecs: codecs__.unwrap_or_default(), - publish: publish__.unwrap_or_default(), + Ok(DeleteRoomRequest { + room: room__.unwrap_or_default(), }) } } - deserializer.deserialize_struct("livekit.DisabledCodecs", FIELDS, GeneratedVisitor) + deserializer.deserialize_struct("livekit.DeleteRoomRequest", FIELDS, GeneratedVisitor) } } -impl serde::Serialize for DisconnectReason { +impl serde::Serialize for DeleteRoomResponse { #[allow(deprecated)] fn serialize(&self, serializer: S) -> std::result::Result where S: serde::Serializer, { - let variant = match self { - Self::UnknownReason => "UNKNOWN_REASON", - Self::ClientInitiated => "CLIENT_INITIATED", - Self::DuplicateIdentity => "DUPLICATE_IDENTITY", - Self::ServerShutdown => "SERVER_SHUTDOWN", - Self::ParticipantRemoved => "PARTICIPANT_REMOVED", - Self::RoomDeleted => "ROOM_DELETED", - Self::StateMismatch => "STATE_MISMATCH", - Self::JoinFailure => "JOIN_FAILURE", - Self::Migration => "MIGRATION", - Self::SignalClose => "SIGNAL_CLOSE", - Self::RoomClosed => "ROOM_CLOSED", - }; - serializer.serialize_str(variant) + use serde::ser::SerializeStruct; + let len = 0; + let struct_ser = serializer.serialize_struct("livekit.DeleteRoomResponse", len)?; + struct_ser.end() } } -impl<'de> serde::Deserialize<'de> for DisconnectReason { +impl<'de> serde::Deserialize<'de> for DeleteRoomResponse { #[allow(deprecated)] fn deserialize(deserializer: D) -> std::result::Result where D: serde::Deserializer<'de>, { const FIELDS: &[&str] = &[ - "UNKNOWN_REASON", - "CLIENT_INITIATED", - "DUPLICATE_IDENTITY", - "SERVER_SHUTDOWN", - "PARTICIPANT_REMOVED", - "ROOM_DELETED", - "STATE_MISMATCH", - "JOIN_FAILURE", - "MIGRATION", - "SIGNAL_CLOSE", - "ROOM_CLOSED", ]; - struct GeneratedVisitor; + #[allow(clippy::enum_variant_names)] + enum GeneratedField { + __SkipField__, + } + impl<'de> serde::Deserialize<'de> for GeneratedField { + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + struct GeneratedVisitor; + + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = GeneratedField; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(formatter, "expected one of: {:?}", &FIELDS) + } + #[allow(unused_variables)] + fn visit_str(self, value: &str) -> std::result::Result + where + E: serde::de::Error, + { + Ok(GeneratedField::__SkipField__) + } + } + deserializer.deserialize_identifier(GeneratedVisitor) + } + } + struct GeneratedVisitor; impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { - type Value = DisconnectReason; + type Value = DeleteRoomResponse; fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(formatter, "expected one of: {:?}", &FIELDS) + formatter.write_str("struct livekit.DeleteRoomResponse") } - fn visit_i64(self, v: i64) -> std::result::Result - where - E: serde::de::Error, + fn visit_map(self, mut map_: V) -> std::result::Result + where + V: serde::de::MapAccess<'de>, { - i32::try_from(v) - .ok() - .and_then(|x| x.try_into().ok()) - .ok_or_else(|| { - serde::de::Error::invalid_value(serde::de::Unexpected::Signed(v), &self) - }) - } - - fn visit_u64(self, v: u64) -> std::result::Result + while map_.next_key::()?.is_some() { + let _ = map_.next_value::()?; + } + Ok(DeleteRoomResponse { + }) + } + } + deserializer.deserialize_struct("livekit.DeleteRoomResponse", FIELDS, GeneratedVisitor) + } +} +impl serde::Serialize for DeleteSipDispatchRuleRequest { + #[allow(deprecated)] + fn serialize(&self, serializer: S) -> std::result::Result + where + S: serde::Serializer, + { + use serde::ser::SerializeStruct; + let mut len = 0; + if !self.sip_dispatch_rule_id.is_empty() { + len += 1; + } + let mut struct_ser = serializer.serialize_struct("livekit.DeleteSIPDispatchRuleRequest", len)?; + if !self.sip_dispatch_rule_id.is_empty() { + struct_ser.serialize_field("sipDispatchRuleId", &self.sip_dispatch_rule_id)?; + } + struct_ser.end() + } +} +impl<'de> serde::Deserialize<'de> for DeleteSipDispatchRuleRequest { + #[allow(deprecated)] + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + const FIELDS: &[&str] = &[ + "sip_dispatch_rule_id", + "sipDispatchRuleId", + ]; + + #[allow(clippy::enum_variant_names)] + enum GeneratedField { + SipDispatchRuleId, + __SkipField__, + } + impl<'de> serde::Deserialize<'de> for GeneratedField { + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + struct GeneratedVisitor; + + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = GeneratedField; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(formatter, "expected one of: {:?}", &FIELDS) + } + + #[allow(unused_variables)] + fn visit_str(self, value: &str) -> std::result::Result + where + E: serde::de::Error, + { + match value { + "sipDispatchRuleId" | "sip_dispatch_rule_id" => Ok(GeneratedField::SipDispatchRuleId), + _ => Ok(GeneratedField::__SkipField__), + } + } + } + deserializer.deserialize_identifier(GeneratedVisitor) + } + } + struct GeneratedVisitor; + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = DeleteSipDispatchRuleRequest; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + formatter.write_str("struct livekit.DeleteSIPDispatchRuleRequest") + } + + fn visit_map(self, mut map_: V) -> std::result::Result + where + V: serde::de::MapAccess<'de>, + { + let mut sip_dispatch_rule_id__ = None; + while let Some(k) = map_.next_key()? { + match k { + GeneratedField::SipDispatchRuleId => { + if sip_dispatch_rule_id__.is_some() { + return Err(serde::de::Error::duplicate_field("sipDispatchRuleId")); + } + sip_dispatch_rule_id__ = Some(map_.next_value()?); + } + GeneratedField::__SkipField__ => { + let _ = map_.next_value::()?; + } + } + } + Ok(DeleteSipDispatchRuleRequest { + sip_dispatch_rule_id: sip_dispatch_rule_id__.unwrap_or_default(), + }) + } + } + deserializer.deserialize_struct("livekit.DeleteSIPDispatchRuleRequest", FIELDS, GeneratedVisitor) + } +} +impl serde::Serialize for DeleteSipTrunkRequest { + #[allow(deprecated)] + fn serialize(&self, serializer: S) -> std::result::Result + where + S: serde::Serializer, + { + use serde::ser::SerializeStruct; + let mut len = 0; + if !self.sip_trunk_id.is_empty() { + len += 1; + } + let mut struct_ser = serializer.serialize_struct("livekit.DeleteSIPTrunkRequest", len)?; + if !self.sip_trunk_id.is_empty() { + struct_ser.serialize_field("sipTrunkId", &self.sip_trunk_id)?; + } + struct_ser.end() + } +} +impl<'de> serde::Deserialize<'de> for DeleteSipTrunkRequest { + #[allow(deprecated)] + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + const FIELDS: &[&str] = &[ + "sip_trunk_id", + "sipTrunkId", + ]; + + #[allow(clippy::enum_variant_names)] + enum GeneratedField { + SipTrunkId, + __SkipField__, + } + impl<'de> serde::Deserialize<'de> for GeneratedField { + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + struct GeneratedVisitor; + + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = GeneratedField; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(formatter, "expected one of: {:?}", &FIELDS) + } + + #[allow(unused_variables)] + fn visit_str(self, value: &str) -> std::result::Result + where + E: serde::de::Error, + { + match value { + "sipTrunkId" | "sip_trunk_id" => Ok(GeneratedField::SipTrunkId), + _ => Ok(GeneratedField::__SkipField__), + } + } + } + deserializer.deserialize_identifier(GeneratedVisitor) + } + } + struct GeneratedVisitor; + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = DeleteSipTrunkRequest; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + formatter.write_str("struct livekit.DeleteSIPTrunkRequest") + } + + fn visit_map(self, mut map_: V) -> std::result::Result + where + V: serde::de::MapAccess<'de>, + { + let mut sip_trunk_id__ = None; + while let Some(k) = map_.next_key()? { + match k { + GeneratedField::SipTrunkId => { + if sip_trunk_id__.is_some() { + return Err(serde::de::Error::duplicate_field("sipTrunkId")); + } + sip_trunk_id__ = Some(map_.next_value()?); + } + GeneratedField::__SkipField__ => { + let _ = map_.next_value::()?; + } + } + } + Ok(DeleteSipTrunkRequest { + sip_trunk_id: sip_trunk_id__.unwrap_or_default(), + }) + } + } + deserializer.deserialize_struct("livekit.DeleteSIPTrunkRequest", FIELDS, GeneratedVisitor) + } +} +impl serde::Serialize for DirectFileOutput { + #[allow(deprecated)] + fn serialize(&self, serializer: S) -> std::result::Result + where + S: serde::Serializer, + { + use serde::ser::SerializeStruct; + let mut len = 0; + if !self.filepath.is_empty() { + len += 1; + } + if self.disable_manifest { + len += 1; + } + if self.output.is_some() { + len += 1; + } + let mut struct_ser = serializer.serialize_struct("livekit.DirectFileOutput", len)?; + if !self.filepath.is_empty() { + struct_ser.serialize_field("filepath", &self.filepath)?; + } + if self.disable_manifest { + struct_ser.serialize_field("disableManifest", &self.disable_manifest)?; + } + if let Some(v) = self.output.as_ref() { + match v { + direct_file_output::Output::S3(v) => { + struct_ser.serialize_field("s3", v)?; + } + direct_file_output::Output::Gcp(v) => { + struct_ser.serialize_field("gcp", v)?; + } + direct_file_output::Output::Azure(v) => { + struct_ser.serialize_field("azure", v)?; + } + direct_file_output::Output::AliOss(v) => { + struct_ser.serialize_field("aliOSS", v)?; + } + } + } + struct_ser.end() + } +} +impl<'de> serde::Deserialize<'de> for DirectFileOutput { + #[allow(deprecated)] + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + const FIELDS: &[&str] = &[ + "filepath", + "disable_manifest", + "disableManifest", + "s3", + "gcp", + "azure", + "aliOSS", + ]; + + #[allow(clippy::enum_variant_names)] + enum GeneratedField { + Filepath, + DisableManifest, + S3, + Gcp, + Azure, + AliOss, + __SkipField__, + } + impl<'de> serde::Deserialize<'de> for GeneratedField { + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + struct GeneratedVisitor; + + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = GeneratedField; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(formatter, "expected one of: {:?}", &FIELDS) + } + + #[allow(unused_variables)] + fn visit_str(self, value: &str) -> std::result::Result + where + E: serde::de::Error, + { + match value { + "filepath" => Ok(GeneratedField::Filepath), + "disableManifest" | "disable_manifest" => Ok(GeneratedField::DisableManifest), + "s3" => Ok(GeneratedField::S3), + "gcp" => Ok(GeneratedField::Gcp), + "azure" => Ok(GeneratedField::Azure), + "aliOSS" => Ok(GeneratedField::AliOss), + _ => Ok(GeneratedField::__SkipField__), + } + } + } + deserializer.deserialize_identifier(GeneratedVisitor) + } + } + struct GeneratedVisitor; + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = DirectFileOutput; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + formatter.write_str("struct livekit.DirectFileOutput") + } + + fn visit_map(self, mut map_: V) -> std::result::Result + where + V: serde::de::MapAccess<'de>, + { + let mut filepath__ = None; + let mut disable_manifest__ = None; + let mut output__ = None; + while let Some(k) = map_.next_key()? { + match k { + GeneratedField::Filepath => { + if filepath__.is_some() { + return Err(serde::de::Error::duplicate_field("filepath")); + } + filepath__ = Some(map_.next_value()?); + } + GeneratedField::DisableManifest => { + if disable_manifest__.is_some() { + return Err(serde::de::Error::duplicate_field("disableManifest")); + } + disable_manifest__ = Some(map_.next_value()?); + } + GeneratedField::S3 => { + if output__.is_some() { + return Err(serde::de::Error::duplicate_field("s3")); + } + output__ = map_.next_value::<::std::option::Option<_>>()?.map(direct_file_output::Output::S3) +; + } + GeneratedField::Gcp => { + if output__.is_some() { + return Err(serde::de::Error::duplicate_field("gcp")); + } + output__ = map_.next_value::<::std::option::Option<_>>()?.map(direct_file_output::Output::Gcp) +; + } + GeneratedField::Azure => { + if output__.is_some() { + return Err(serde::de::Error::duplicate_field("azure")); + } + output__ = map_.next_value::<::std::option::Option<_>>()?.map(direct_file_output::Output::Azure) +; + } + GeneratedField::AliOss => { + if output__.is_some() { + return Err(serde::de::Error::duplicate_field("aliOSS")); + } + output__ = map_.next_value::<::std::option::Option<_>>()?.map(direct_file_output::Output::AliOss) +; + } + GeneratedField::__SkipField__ => { + let _ = map_.next_value::()?; + } + } + } + Ok(DirectFileOutput { + filepath: filepath__.unwrap_or_default(), + disable_manifest: disable_manifest__.unwrap_or_default(), + output: output__, + }) + } + } + deserializer.deserialize_struct("livekit.DirectFileOutput", FIELDS, GeneratedVisitor) + } +} +impl serde::Serialize for DisabledCodecs { + #[allow(deprecated)] + fn serialize(&self, serializer: S) -> std::result::Result + where + S: serde::Serializer, + { + use serde::ser::SerializeStruct; + let mut len = 0; + if !self.codecs.is_empty() { + len += 1; + } + if !self.publish.is_empty() { + len += 1; + } + let mut struct_ser = serializer.serialize_struct("livekit.DisabledCodecs", len)?; + if !self.codecs.is_empty() { + struct_ser.serialize_field("codecs", &self.codecs)?; + } + if !self.publish.is_empty() { + struct_ser.serialize_field("publish", &self.publish)?; + } + struct_ser.end() + } +} +impl<'de> serde::Deserialize<'de> for DisabledCodecs { + #[allow(deprecated)] + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + const FIELDS: &[&str] = &[ + "codecs", + "publish", + ]; + + #[allow(clippy::enum_variant_names)] + enum GeneratedField { + Codecs, + Publish, + __SkipField__, + } + impl<'de> serde::Deserialize<'de> for GeneratedField { + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + struct GeneratedVisitor; + + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = GeneratedField; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(formatter, "expected one of: {:?}", &FIELDS) + } + + #[allow(unused_variables)] + fn visit_str(self, value: &str) -> std::result::Result + where + E: serde::de::Error, + { + match value { + "codecs" => Ok(GeneratedField::Codecs), + "publish" => Ok(GeneratedField::Publish), + _ => Ok(GeneratedField::__SkipField__), + } + } + } + deserializer.deserialize_identifier(GeneratedVisitor) + } + } + struct GeneratedVisitor; + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = DisabledCodecs; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + formatter.write_str("struct livekit.DisabledCodecs") + } + + fn visit_map(self, mut map_: V) -> std::result::Result + where + V: serde::de::MapAccess<'de>, + { + let mut codecs__ = None; + let mut publish__ = None; + while let Some(k) = map_.next_key()? { + match k { + GeneratedField::Codecs => { + if codecs__.is_some() { + return Err(serde::de::Error::duplicate_field("codecs")); + } + codecs__ = Some(map_.next_value()?); + } + GeneratedField::Publish => { + if publish__.is_some() { + return Err(serde::de::Error::duplicate_field("publish")); + } + publish__ = Some(map_.next_value()?); + } + GeneratedField::__SkipField__ => { + let _ = map_.next_value::()?; + } + } + } + Ok(DisabledCodecs { + codecs: codecs__.unwrap_or_default(), + publish: publish__.unwrap_or_default(), + }) + } + } + deserializer.deserialize_struct("livekit.DisabledCodecs", FIELDS, GeneratedVisitor) + } +} +impl serde::Serialize for DisconnectReason { + #[allow(deprecated)] + fn serialize(&self, serializer: S) -> std::result::Result + where + S: serde::Serializer, + { + let variant = match self { + Self::UnknownReason => "UNKNOWN_REASON", + Self::ClientInitiated => "CLIENT_INITIATED", + Self::DuplicateIdentity => "DUPLICATE_IDENTITY", + Self::ServerShutdown => "SERVER_SHUTDOWN", + Self::ParticipantRemoved => "PARTICIPANT_REMOVED", + Self::RoomDeleted => "ROOM_DELETED", + Self::StateMismatch => "STATE_MISMATCH", + Self::JoinFailure => "JOIN_FAILURE", + Self::Migration => "MIGRATION", + Self::SignalClose => "SIGNAL_CLOSE", + Self::RoomClosed => "ROOM_CLOSED", + Self::UserUnavailable => "USER_UNAVAILABLE", + Self::UserRejected => "USER_REJECTED", + Self::SipTrunkFailure => "SIP_TRUNK_FAILURE", + }; + serializer.serialize_str(variant) + } +} +impl<'de> serde::Deserialize<'de> for DisconnectReason { + #[allow(deprecated)] + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + const FIELDS: &[&str] = &[ + "UNKNOWN_REASON", + "CLIENT_INITIATED", + "DUPLICATE_IDENTITY", + "SERVER_SHUTDOWN", + "PARTICIPANT_REMOVED", + "ROOM_DELETED", + "STATE_MISMATCH", + "JOIN_FAILURE", + "MIGRATION", + "SIGNAL_CLOSE", + "ROOM_CLOSED", + "USER_UNAVAILABLE", + "USER_REJECTED", + "SIP_TRUNK_FAILURE", + ]; + + struct GeneratedVisitor; + + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = DisconnectReason; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(formatter, "expected one of: {:?}", &FIELDS) + } + + fn visit_i64(self, v: i64) -> std::result::Result + where + E: serde::de::Error, + { + i32::try_from(v) + .ok() + .and_then(|x| x.try_into().ok()) + .ok_or_else(|| { + serde::de::Error::invalid_value(serde::de::Unexpected::Signed(v), &self) + }) + } + + fn visit_u64(self, v: u64) -> std::result::Result where E: serde::de::Error, { @@ -6200,6 +7207,9 @@ impl<'de> serde::Deserialize<'de> for DisconnectReason { "MIGRATION" => Ok(DisconnectReason::Migration), "SIGNAL_CLOSE" => Ok(DisconnectReason::SignalClose), "ROOM_CLOSED" => Ok(DisconnectReason::RoomClosed), + "USER_UNAVAILABLE" => Ok(DisconnectReason::UserUnavailable), + "USER_REJECTED" => Ok(DisconnectReason::UserRejected), + "SIP_TRUNK_FAILURE" => Ok(DisconnectReason::SipTrunkFailure), _ => Err(serde::de::Error::unknown_variant(value, FIELDS)), } } @@ -6257,6 +7267,12 @@ impl serde::Serialize for EgressInfo { if !self.image_results.is_empty() { len += 1; } + if !self.manifest_location.is_empty() { + len += 1; + } + if self.backup_storage_used { + len += 1; + } if self.request.is_some() { len += 1; } @@ -6314,6 +7330,12 @@ impl serde::Serialize for EgressInfo { if !self.image_results.is_empty() { struct_ser.serialize_field("imageResults", &self.image_results)?; } + if !self.manifest_location.is_empty() { + struct_ser.serialize_field("manifestLocation", &self.manifest_location)?; + } + if self.backup_storage_used { + struct_ser.serialize_field("backupStorageUsed", &self.backup_storage_used)?; + } if let Some(v) = self.request.as_ref() { match v { egress_info::Request::RoomComposite(v) => { @@ -6381,6 +7403,10 @@ impl<'de> serde::Deserialize<'de> for EgressInfo { "segmentResults", "image_results", "imageResults", + "manifest_location", + "manifestLocation", + "backup_storage_used", + "backupStorageUsed", "room_composite", "roomComposite", "web", @@ -6409,6 +7435,8 @@ impl<'de> serde::Deserialize<'de> for EgressInfo { FileResults, SegmentResults, ImageResults, + ManifestLocation, + BackupStorageUsed, RoomComposite, Web, Participant, @@ -6453,6 +7481,8 @@ impl<'de> serde::Deserialize<'de> for EgressInfo { "fileResults" | "file_results" => Ok(GeneratedField::FileResults), "segmentResults" | "segment_results" => Ok(GeneratedField::SegmentResults), "imageResults" | "image_results" => Ok(GeneratedField::ImageResults), + "manifestLocation" | "manifest_location" => Ok(GeneratedField::ManifestLocation), + "backupStorageUsed" | "backup_storage_used" => Ok(GeneratedField::BackupStorageUsed), "roomComposite" | "room_composite" => Ok(GeneratedField::RoomComposite), "web" => Ok(GeneratedField::Web), "participant" => Ok(GeneratedField::Participant), @@ -6494,6 +7524,8 @@ impl<'de> serde::Deserialize<'de> for EgressInfo { let mut file_results__ = None; let mut segment_results__ = None; let mut image_results__ = None; + let mut manifest_location__ = None; + let mut backup_storage_used__ = None; let mut request__ = None; let mut result__ = None; while let Some(k) = map_.next_key()? { @@ -6590,6 +7622,18 @@ impl<'de> serde::Deserialize<'de> for EgressInfo { } image_results__ = Some(map_.next_value()?); } + GeneratedField::ManifestLocation => { + if manifest_location__.is_some() { + return Err(serde::de::Error::duplicate_field("manifestLocation")); + } + manifest_location__ = Some(map_.next_value()?); + } + GeneratedField::BackupStorageUsed => { + if backup_storage_used__.is_some() { + return Err(serde::de::Error::duplicate_field("backupStorageUsed")); + } + backup_storage_used__ = Some(map_.next_value()?); + } GeneratedField::RoomComposite => { if request__.is_some() { return Err(serde::de::Error::duplicate_field("roomComposite")); @@ -6666,6 +7710,8 @@ impl<'de> serde::Deserialize<'de> for EgressInfo { file_results: file_results__.unwrap_or_default(), segment_results: segment_results__.unwrap_or_default(), image_results: image_results__.unwrap_or_default(), + manifest_location: manifest_location__.unwrap_or_default(), + backup_storage_used: backup_storage_used__.unwrap_or_default(), request: request__, result: result__, }) @@ -14194,6 +15240,9 @@ impl serde::Serialize for MetricLabel { Self::ClientVideoPublisherQualityLimitationDurationBandwidth => "CLIENT_VIDEO_PUBLISHER_QUALITY_LIMITATION_DURATION_BANDWIDTH", Self::ClientVideoPublisherQualityLimitationDurationCpu => "CLIENT_VIDEO_PUBLISHER_QUALITY_LIMITATION_DURATION_CPU", Self::ClientVideoPublisherQualityLimitationDurationOther => "CLIENT_VIDEO_PUBLISHER_QUALITY_LIMITATION_DURATION_OTHER", + Self::PublisherRtt => "PUBLISHER_RTT", + Self::ServerMeshRtt => "SERVER_MESH_RTT", + Self::SubscriberRtt => "SUBSCRIBER_RTT", Self::PredefinedMaxValue => "METRIC_LABEL_PREDEFINED_MAX_VALUE", }; serializer.serialize_str(variant) @@ -14223,6 +15272,9 @@ impl<'de> serde::Deserialize<'de> for MetricLabel { "CLIENT_VIDEO_PUBLISHER_QUALITY_LIMITATION_DURATION_BANDWIDTH", "CLIENT_VIDEO_PUBLISHER_QUALITY_LIMITATION_DURATION_CPU", "CLIENT_VIDEO_PUBLISHER_QUALITY_LIMITATION_DURATION_OTHER", + "PUBLISHER_RTT", + "SERVER_MESH_RTT", + "SUBSCRIBER_RTT", "METRIC_LABEL_PREDEFINED_MAX_VALUE", ]; @@ -14281,6 +15333,9 @@ impl<'de> serde::Deserialize<'de> for MetricLabel { "CLIENT_VIDEO_PUBLISHER_QUALITY_LIMITATION_DURATION_BANDWIDTH" => Ok(MetricLabel::ClientVideoPublisherQualityLimitationDurationBandwidth), "CLIENT_VIDEO_PUBLISHER_QUALITY_LIMITATION_DURATION_CPU" => Ok(MetricLabel::ClientVideoPublisherQualityLimitationDurationCpu), "CLIENT_VIDEO_PUBLISHER_QUALITY_LIMITATION_DURATION_OTHER" => Ok(MetricLabel::ClientVideoPublisherQualityLimitationDurationOther), + "PUBLISHER_RTT" => Ok(MetricLabel::PublisherRtt), + "SERVER_MESH_RTT" => Ok(MetricLabel::ServerMeshRtt), + "SUBSCRIBER_RTT" => Ok(MetricLabel::SubscriberRtt), "METRIC_LABEL_PREDEFINED_MAX_VALUE" => Ok(MetricLabel::PredefinedMaxValue), _ => Err(serde::de::Error::unknown_variant(value, FIELDS)), } @@ -20502,9 +21557,6 @@ impl serde::Serialize for RoomConfiguration { if self.egress.is_some() { len += 1; } - if self.agent.is_some() { - len += 1; - } if self.min_playout_delay != 0 { len += 1; } @@ -20514,6 +21566,9 @@ impl serde::Serialize for RoomConfiguration { if self.sync_streams { len += 1; } + if !self.agents.is_empty() { + len += 1; + } let mut struct_ser = serializer.serialize_struct("livekit.RoomConfiguration", len)?; if !self.name.is_empty() { struct_ser.serialize_field("name", &self.name)?; @@ -20530,9 +21585,6 @@ impl serde::Serialize for RoomConfiguration { if let Some(v) = self.egress.as_ref() { struct_ser.serialize_field("egress", v)?; } - if let Some(v) = self.agent.as_ref() { - struct_ser.serialize_field("agent", v)?; - } if self.min_playout_delay != 0 { struct_ser.serialize_field("minPlayoutDelay", &self.min_playout_delay)?; } @@ -20542,6 +21594,9 @@ impl serde::Serialize for RoomConfiguration { if self.sync_streams { struct_ser.serialize_field("syncStreams", &self.sync_streams)?; } + if !self.agents.is_empty() { + struct_ser.serialize_field("agents", &self.agents)?; + } struct_ser.end() } } @@ -20560,13 +21615,13 @@ impl<'de> serde::Deserialize<'de> for RoomConfiguration { "max_participants", "maxParticipants", "egress", - "agent", "min_playout_delay", "minPlayoutDelay", "max_playout_delay", "maxPlayoutDelay", "sync_streams", "syncStreams", + "agents", ]; #[allow(clippy::enum_variant_names)] @@ -20576,10 +21631,10 @@ impl<'de> serde::Deserialize<'de> for RoomConfiguration { DepartureTimeout, MaxParticipants, Egress, - Agent, MinPlayoutDelay, MaxPlayoutDelay, SyncStreams, + Agents, __SkipField__, } impl<'de> serde::Deserialize<'de> for GeneratedField { @@ -20607,10 +21662,10 @@ impl<'de> serde::Deserialize<'de> for RoomConfiguration { "departureTimeout" | "departure_timeout" => Ok(GeneratedField::DepartureTimeout), "maxParticipants" | "max_participants" => Ok(GeneratedField::MaxParticipants), "egress" => Ok(GeneratedField::Egress), - "agent" => Ok(GeneratedField::Agent), "minPlayoutDelay" | "min_playout_delay" => Ok(GeneratedField::MinPlayoutDelay), "maxPlayoutDelay" | "max_playout_delay" => Ok(GeneratedField::MaxPlayoutDelay), "syncStreams" | "sync_streams" => Ok(GeneratedField::SyncStreams), + "agents" => Ok(GeneratedField::Agents), _ => Ok(GeneratedField::__SkipField__), } } @@ -20635,10 +21690,10 @@ impl<'de> serde::Deserialize<'de> for RoomConfiguration { let mut departure_timeout__ = None; let mut max_participants__ = None; let mut egress__ = None; - let mut agent__ = None; let mut min_playout_delay__ = None; let mut max_playout_delay__ = None; let mut sync_streams__ = None; + let mut agents__ = None; while let Some(k) = map_.next_key()? { match k { GeneratedField::Name => { @@ -20677,12 +21732,6 @@ impl<'de> serde::Deserialize<'de> for RoomConfiguration { } egress__ = map_.next_value()?; } - GeneratedField::Agent => { - if agent__.is_some() { - return Err(serde::de::Error::duplicate_field("agent")); - } - agent__ = map_.next_value()?; - } GeneratedField::MinPlayoutDelay => { if min_playout_delay__.is_some() { return Err(serde::de::Error::duplicate_field("minPlayoutDelay")); @@ -20705,6 +21754,12 @@ impl<'de> serde::Deserialize<'de> for RoomConfiguration { } sync_streams__ = Some(map_.next_value()?); } + GeneratedField::Agents => { + if agents__.is_some() { + return Err(serde::de::Error::duplicate_field("agents")); + } + agents__ = Some(map_.next_value()?); + } GeneratedField::__SkipField__ => { let _ = map_.next_value::()?; } @@ -20716,10 +21771,10 @@ impl<'de> serde::Deserialize<'de> for RoomConfiguration { departure_timeout: departure_timeout__.unwrap_or_default(), max_participants: max_participants__.unwrap_or_default(), egress: egress__, - agent: agent__, min_playout_delay: min_playout_delay__.unwrap_or_default(), max_playout_delay: max_playout_delay__.unwrap_or_default(), sync_streams: sync_streams__.unwrap_or_default(), + agents: agents__.unwrap_or_default(), }) } } @@ -21468,44 +22523,240 @@ impl serde::Serialize for RpcResponse { if !self.request_id.is_empty() { len += 1; } - if self.value.is_some() { + if self.value.is_some() { + len += 1; + } + let mut struct_ser = serializer.serialize_struct("livekit.RpcResponse", len)?; + if !self.request_id.is_empty() { + struct_ser.serialize_field("requestId", &self.request_id)?; + } + if let Some(v) = self.value.as_ref() { + match v { + rpc_response::Value::Payload(v) => { + struct_ser.serialize_field("payload", v)?; + } + rpc_response::Value::Error(v) => { + struct_ser.serialize_field("error", v)?; + } + } + } + struct_ser.end() + } +} +impl<'de> serde::Deserialize<'de> for RpcResponse { + #[allow(deprecated)] + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + const FIELDS: &[&str] = &[ + "request_id", + "requestId", + "payload", + "error", + ]; + + #[allow(clippy::enum_variant_names)] + enum GeneratedField { + RequestId, + Payload, + Error, + __SkipField__, + } + impl<'de> serde::Deserialize<'de> for GeneratedField { + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + struct GeneratedVisitor; + + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = GeneratedField; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(formatter, "expected one of: {:?}", &FIELDS) + } + + #[allow(unused_variables)] + fn visit_str(self, value: &str) -> std::result::Result + where + E: serde::de::Error, + { + match value { + "requestId" | "request_id" => Ok(GeneratedField::RequestId), + "payload" => Ok(GeneratedField::Payload), + "error" => Ok(GeneratedField::Error), + _ => Ok(GeneratedField::__SkipField__), + } + } + } + deserializer.deserialize_identifier(GeneratedVisitor) + } + } + struct GeneratedVisitor; + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = RpcResponse; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + formatter.write_str("struct livekit.RpcResponse") + } + + fn visit_map(self, mut map_: V) -> std::result::Result + where + V: serde::de::MapAccess<'de>, + { + let mut request_id__ = None; + let mut value__ = None; + while let Some(k) = map_.next_key()? { + match k { + GeneratedField::RequestId => { + if request_id__.is_some() { + return Err(serde::de::Error::duplicate_field("requestId")); + } + request_id__ = Some(map_.next_value()?); + } + GeneratedField::Payload => { + if value__.is_some() { + return Err(serde::de::Error::duplicate_field("payload")); + } + value__ = map_.next_value::<::std::option::Option<_>>()?.map(rpc_response::Value::Payload); + } + GeneratedField::Error => { + if value__.is_some() { + return Err(serde::de::Error::duplicate_field("error")); + } + value__ = map_.next_value::<::std::option::Option<_>>()?.map(rpc_response::Value::Error) +; + } + GeneratedField::__SkipField__ => { + let _ = map_.next_value::()?; + } + } + } + Ok(RpcResponse { + request_id: request_id__.unwrap_or_default(), + value: value__, + }) + } + } + deserializer.deserialize_struct("livekit.RpcResponse", FIELDS, GeneratedVisitor) + } +} +impl serde::Serialize for S3Upload { + #[allow(deprecated)] + fn serialize(&self, serializer: S) -> std::result::Result + where + S: serde::Serializer, + { + use serde::ser::SerializeStruct; + let mut len = 0; + if !self.access_key.is_empty() { + len += 1; + } + if !self.secret.is_empty() { + len += 1; + } + if !self.session_token.is_empty() { + len += 1; + } + if !self.region.is_empty() { + len += 1; + } + if !self.endpoint.is_empty() { + len += 1; + } + if !self.bucket.is_empty() { + len += 1; + } + if self.force_path_style { + len += 1; + } + if !self.metadata.is_empty() { + len += 1; + } + if !self.tagging.is_empty() { + len += 1; + } + if !self.content_disposition.is_empty() { len += 1; } - let mut struct_ser = serializer.serialize_struct("livekit.RpcResponse", len)?; - if !self.request_id.is_empty() { - struct_ser.serialize_field("requestId", &self.request_id)?; + if self.proxy.is_some() { + len += 1; } - if let Some(v) = self.value.as_ref() { - match v { - rpc_response::Value::Payload(v) => { - struct_ser.serialize_field("payload", v)?; - } - rpc_response::Value::Error(v) => { - struct_ser.serialize_field("error", v)?; - } - } + let mut struct_ser = serializer.serialize_struct("livekit.S3Upload", len)?; + if !self.access_key.is_empty() { + struct_ser.serialize_field("accessKey", &self.access_key)?; + } + if !self.secret.is_empty() { + struct_ser.serialize_field("secret", &self.secret)?; + } + if !self.session_token.is_empty() { + struct_ser.serialize_field("sessionToken", &self.session_token)?; + } + if !self.region.is_empty() { + struct_ser.serialize_field("region", &self.region)?; + } + if !self.endpoint.is_empty() { + struct_ser.serialize_field("endpoint", &self.endpoint)?; + } + if !self.bucket.is_empty() { + struct_ser.serialize_field("bucket", &self.bucket)?; + } + if self.force_path_style { + struct_ser.serialize_field("forcePathStyle", &self.force_path_style)?; + } + if !self.metadata.is_empty() { + struct_ser.serialize_field("metadata", &self.metadata)?; + } + if !self.tagging.is_empty() { + struct_ser.serialize_field("tagging", &self.tagging)?; + } + if !self.content_disposition.is_empty() { + struct_ser.serialize_field("contentDisposition", &self.content_disposition)?; + } + if let Some(v) = self.proxy.as_ref() { + struct_ser.serialize_field("proxy", v)?; } struct_ser.end() } } -impl<'de> serde::Deserialize<'de> for RpcResponse { +impl<'de> serde::Deserialize<'de> for S3Upload { #[allow(deprecated)] fn deserialize(deserializer: D) -> std::result::Result where D: serde::Deserializer<'de>, { const FIELDS: &[&str] = &[ - "request_id", - "requestId", - "payload", - "error", + "access_key", + "accessKey", + "secret", + "session_token", + "sessionToken", + "region", + "endpoint", + "bucket", + "force_path_style", + "forcePathStyle", + "metadata", + "tagging", + "content_disposition", + "contentDisposition", + "proxy", ]; #[allow(clippy::enum_variant_names)] enum GeneratedField { - RequestId, - Payload, - Error, + AccessKey, + Secret, + SessionToken, + Region, + Endpoint, + Bucket, + ForcePathStyle, + Metadata, + Tagging, + ContentDisposition, + Proxy, __SkipField__, } impl<'de> serde::Deserialize<'de> for GeneratedField { @@ -21528,9 +22779,17 @@ impl<'de> serde::Deserialize<'de> for RpcResponse { E: serde::de::Error, { match value { - "requestId" | "request_id" => Ok(GeneratedField::RequestId), - "payload" => Ok(GeneratedField::Payload), - "error" => Ok(GeneratedField::Error), + "accessKey" | "access_key" => Ok(GeneratedField::AccessKey), + "secret" => Ok(GeneratedField::Secret), + "sessionToken" | "session_token" => Ok(GeneratedField::SessionToken), + "region" => Ok(GeneratedField::Region), + "endpoint" => Ok(GeneratedField::Endpoint), + "bucket" => Ok(GeneratedField::Bucket), + "forcePathStyle" | "force_path_style" => Ok(GeneratedField::ForcePathStyle), + "metadata" => Ok(GeneratedField::Metadata), + "tagging" => Ok(GeneratedField::Tagging), + "contentDisposition" | "content_disposition" => Ok(GeneratedField::ContentDisposition), + "proxy" => Ok(GeneratedField::Proxy), _ => Ok(GeneratedField::__SkipField__), } } @@ -21540,54 +22799,121 @@ impl<'de> serde::Deserialize<'de> for RpcResponse { } struct GeneratedVisitor; impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { - type Value = RpcResponse; + type Value = S3Upload; fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - formatter.write_str("struct livekit.RpcResponse") + formatter.write_str("struct livekit.S3Upload") } - fn visit_map(self, mut map_: V) -> std::result::Result + fn visit_map(self, mut map_: V) -> std::result::Result where V: serde::de::MapAccess<'de>, { - let mut request_id__ = None; - let mut value__ = None; + let mut access_key__ = None; + let mut secret__ = None; + let mut session_token__ = None; + let mut region__ = None; + let mut endpoint__ = None; + let mut bucket__ = None; + let mut force_path_style__ = None; + let mut metadata__ = None; + let mut tagging__ = None; + let mut content_disposition__ = None; + let mut proxy__ = None; while let Some(k) = map_.next_key()? { match k { - GeneratedField::RequestId => { - if request_id__.is_some() { - return Err(serde::de::Error::duplicate_field("requestId")); + GeneratedField::AccessKey => { + if access_key__.is_some() { + return Err(serde::de::Error::duplicate_field("accessKey")); } - request_id__ = Some(map_.next_value()?); + access_key__ = Some(map_.next_value()?); } - GeneratedField::Payload => { - if value__.is_some() { - return Err(serde::de::Error::duplicate_field("payload")); + GeneratedField::Secret => { + if secret__.is_some() { + return Err(serde::de::Error::duplicate_field("secret")); } - value__ = map_.next_value::<::std::option::Option<_>>()?.map(rpc_response::Value::Payload); + secret__ = Some(map_.next_value()?); } - GeneratedField::Error => { - if value__.is_some() { - return Err(serde::de::Error::duplicate_field("error")); + GeneratedField::SessionToken => { + if session_token__.is_some() { + return Err(serde::de::Error::duplicate_field("sessionToken")); } - value__ = map_.next_value::<::std::option::Option<_>>()?.map(rpc_response::Value::Error) -; + session_token__ = Some(map_.next_value()?); + } + GeneratedField::Region => { + if region__.is_some() { + return Err(serde::de::Error::duplicate_field("region")); + } + region__ = Some(map_.next_value()?); + } + GeneratedField::Endpoint => { + if endpoint__.is_some() { + return Err(serde::de::Error::duplicate_field("endpoint")); + } + endpoint__ = Some(map_.next_value()?); + } + GeneratedField::Bucket => { + if bucket__.is_some() { + return Err(serde::de::Error::duplicate_field("bucket")); + } + bucket__ = Some(map_.next_value()?); + } + GeneratedField::ForcePathStyle => { + if force_path_style__.is_some() { + return Err(serde::de::Error::duplicate_field("forcePathStyle")); + } + force_path_style__ = Some(map_.next_value()?); + } + GeneratedField::Metadata => { + if metadata__.is_some() { + return Err(serde::de::Error::duplicate_field("metadata")); + } + metadata__ = Some( + map_.next_value::>()? + ); + } + GeneratedField::Tagging => { + if tagging__.is_some() { + return Err(serde::de::Error::duplicate_field("tagging")); + } + tagging__ = Some(map_.next_value()?); + } + GeneratedField::ContentDisposition => { + if content_disposition__.is_some() { + return Err(serde::de::Error::duplicate_field("contentDisposition")); + } + content_disposition__ = Some(map_.next_value()?); + } + GeneratedField::Proxy => { + if proxy__.is_some() { + return Err(serde::de::Error::duplicate_field("proxy")); + } + proxy__ = map_.next_value()?; } GeneratedField::__SkipField__ => { let _ = map_.next_value::()?; } } } - Ok(RpcResponse { - request_id: request_id__.unwrap_or_default(), - value: value__, + Ok(S3Upload { + access_key: access_key__.unwrap_or_default(), + secret: secret__.unwrap_or_default(), + session_token: session_token__.unwrap_or_default(), + region: region__.unwrap_or_default(), + endpoint: endpoint__.unwrap_or_default(), + bucket: bucket__.unwrap_or_default(), + force_path_style: force_path_style__.unwrap_or_default(), + metadata: metadata__.unwrap_or_default(), + tagging: tagging__.unwrap_or_default(), + content_disposition: content_disposition__.unwrap_or_default(), + proxy: proxy__, }) } } - deserializer.deserialize_struct("livekit.RpcResponse", FIELDS, GeneratedVisitor) + deserializer.deserialize_struct("livekit.S3Upload", FIELDS, GeneratedVisitor) } } -impl serde::Serialize for S3Upload { +impl serde::Serialize for SipCallInfo { #[allow(deprecated)] fn serialize(&self, serializer: S) -> std::result::Result where @@ -21595,113 +22921,160 @@ impl serde::Serialize for S3Upload { { use serde::ser::SerializeStruct; let mut len = 0; - if !self.access_key.is_empty() { + if !self.call_id.is_empty() { len += 1; } - if !self.secret.is_empty() { + if !self.trunk_id.is_empty() { len += 1; } - if !self.session_token.is_empty() { + if !self.room_name.is_empty() { len += 1; } - if !self.region.is_empty() { + if !self.room_id.is_empty() { len += 1; } - if !self.endpoint.is_empty() { + if !self.participant_identity.is_empty() { len += 1; } - if !self.bucket.is_empty() { + if self.from_uri.is_some() { len += 1; } - if self.force_path_style { + if self.to_uri.is_some() { len += 1; } - if !self.metadata.is_empty() { + if !self.enabled_features.is_empty() { len += 1; } - if !self.tagging.is_empty() { + if self.call_status != 0 { len += 1; } - if !self.content_disposition.is_empty() { + if self.created_at != 0 { len += 1; } - if self.proxy.is_some() { + if self.started_at != 0 { len += 1; } - let mut struct_ser = serializer.serialize_struct("livekit.S3Upload", len)?; - if !self.access_key.is_empty() { - struct_ser.serialize_field("accessKey", &self.access_key)?; + if self.ended_at != 0 { + len += 1; } - if !self.secret.is_empty() { - struct_ser.serialize_field("secret", &self.secret)?; + if self.disconnect_reason != 0 { + len += 1; } - if !self.session_token.is_empty() { - struct_ser.serialize_field("sessionToken", &self.session_token)?; + if !self.error.is_empty() { + len += 1; } - if !self.region.is_empty() { - struct_ser.serialize_field("region", &self.region)?; + let mut struct_ser = serializer.serialize_struct("livekit.SIPCallInfo", len)?; + if !self.call_id.is_empty() { + struct_ser.serialize_field("callId", &self.call_id)?; } - if !self.endpoint.is_empty() { - struct_ser.serialize_field("endpoint", &self.endpoint)?; + if !self.trunk_id.is_empty() { + struct_ser.serialize_field("trunkId", &self.trunk_id)?; + } + if !self.room_name.is_empty() { + struct_ser.serialize_field("roomName", &self.room_name)?; + } + if !self.room_id.is_empty() { + struct_ser.serialize_field("roomId", &self.room_id)?; + } + if !self.participant_identity.is_empty() { + struct_ser.serialize_field("participantIdentity", &self.participant_identity)?; + } + if let Some(v) = self.from_uri.as_ref() { + struct_ser.serialize_field("fromUri", v)?; + } + if let Some(v) = self.to_uri.as_ref() { + struct_ser.serialize_field("toUri", v)?; + } + if !self.enabled_features.is_empty() { + let v = self.enabled_features.iter().cloned().map(|v| { + SipFeature::try_from(v) + .map_err(|_| serde::ser::Error::custom(format!("Invalid variant {}", v))) + }).collect::, _>>()?; + struct_ser.serialize_field("enabledFeatures", &v)?; } - if !self.bucket.is_empty() { - struct_ser.serialize_field("bucket", &self.bucket)?; + if self.call_status != 0 { + let v = SipCallStatus::try_from(self.call_status) + .map_err(|_| serde::ser::Error::custom(format!("Invalid variant {}", self.call_status)))?; + struct_ser.serialize_field("callStatus", &v)?; } - if self.force_path_style { - struct_ser.serialize_field("forcePathStyle", &self.force_path_style)?; + if self.created_at != 0 { + #[allow(clippy::needless_borrow)] + #[allow(clippy::needless_borrows_for_generic_args)] + struct_ser.serialize_field("createdAt", ToString::to_string(&self.created_at).as_str())?; } - if !self.metadata.is_empty() { - struct_ser.serialize_field("metadata", &self.metadata)?; + if self.started_at != 0 { + #[allow(clippy::needless_borrow)] + #[allow(clippy::needless_borrows_for_generic_args)] + struct_ser.serialize_field("startedAt", ToString::to_string(&self.started_at).as_str())?; } - if !self.tagging.is_empty() { - struct_ser.serialize_field("tagging", &self.tagging)?; + if self.ended_at != 0 { + #[allow(clippy::needless_borrow)] + #[allow(clippy::needless_borrows_for_generic_args)] + struct_ser.serialize_field("endedAt", ToString::to_string(&self.ended_at).as_str())?; } - if !self.content_disposition.is_empty() { - struct_ser.serialize_field("contentDisposition", &self.content_disposition)?; + if self.disconnect_reason != 0 { + let v = DisconnectReason::try_from(self.disconnect_reason) + .map_err(|_| serde::ser::Error::custom(format!("Invalid variant {}", self.disconnect_reason)))?; + struct_ser.serialize_field("disconnectReason", &v)?; } - if let Some(v) = self.proxy.as_ref() { - struct_ser.serialize_field("proxy", v)?; + if !self.error.is_empty() { + struct_ser.serialize_field("error", &self.error)?; } struct_ser.end() } } -impl<'de> serde::Deserialize<'de> for S3Upload { +impl<'de> serde::Deserialize<'de> for SipCallInfo { #[allow(deprecated)] fn deserialize(deserializer: D) -> std::result::Result where D: serde::Deserializer<'de>, { const FIELDS: &[&str] = &[ - "access_key", - "accessKey", - "secret", - "session_token", - "sessionToken", - "region", - "endpoint", - "bucket", - "force_path_style", - "forcePathStyle", - "metadata", - "tagging", - "content_disposition", - "contentDisposition", - "proxy", + "call_id", + "callId", + "trunk_id", + "trunkId", + "room_name", + "roomName", + "room_id", + "roomId", + "participant_identity", + "participantIdentity", + "from_uri", + "fromUri", + "to_uri", + "toUri", + "enabled_features", + "enabledFeatures", + "call_status", + "callStatus", + "created_at", + "createdAt", + "started_at", + "startedAt", + "ended_at", + "endedAt", + "disconnect_reason", + "disconnectReason", + "error", ]; #[allow(clippy::enum_variant_names)] enum GeneratedField { - AccessKey, - Secret, - SessionToken, - Region, - Endpoint, - Bucket, - ForcePathStyle, - Metadata, - Tagging, - ContentDisposition, - Proxy, + CallId, + TrunkId, + RoomName, + RoomId, + ParticipantIdentity, + FromUri, + ToUri, + EnabledFeatures, + CallStatus, + CreatedAt, + StartedAt, + EndedAt, + DisconnectReason, + Error, __SkipField__, } impl<'de> serde::Deserialize<'de> for GeneratedField { @@ -21724,17 +23097,20 @@ impl<'de> serde::Deserialize<'de> for S3Upload { E: serde::de::Error, { match value { - "accessKey" | "access_key" => Ok(GeneratedField::AccessKey), - "secret" => Ok(GeneratedField::Secret), - "sessionToken" | "session_token" => Ok(GeneratedField::SessionToken), - "region" => Ok(GeneratedField::Region), - "endpoint" => Ok(GeneratedField::Endpoint), - "bucket" => Ok(GeneratedField::Bucket), - "forcePathStyle" | "force_path_style" => Ok(GeneratedField::ForcePathStyle), - "metadata" => Ok(GeneratedField::Metadata), - "tagging" => Ok(GeneratedField::Tagging), - "contentDisposition" | "content_disposition" => Ok(GeneratedField::ContentDisposition), - "proxy" => Ok(GeneratedField::Proxy), + "callId" | "call_id" => Ok(GeneratedField::CallId), + "trunkId" | "trunk_id" => Ok(GeneratedField::TrunkId), + "roomName" | "room_name" => Ok(GeneratedField::RoomName), + "roomId" | "room_id" => Ok(GeneratedField::RoomId), + "participantIdentity" | "participant_identity" => Ok(GeneratedField::ParticipantIdentity), + "fromUri" | "from_uri" => Ok(GeneratedField::FromUri), + "toUri" | "to_uri" => Ok(GeneratedField::ToUri), + "enabledFeatures" | "enabled_features" => Ok(GeneratedField::EnabledFeatures), + "callStatus" | "call_status" => Ok(GeneratedField::CallStatus), + "createdAt" | "created_at" => Ok(GeneratedField::CreatedAt), + "startedAt" | "started_at" => Ok(GeneratedField::StartedAt), + "endedAt" | "ended_at" => Ok(GeneratedField::EndedAt), + "disconnectReason" | "disconnect_reason" => Ok(GeneratedField::DisconnectReason), + "error" => Ok(GeneratedField::Error), _ => Ok(GeneratedField::__SkipField__), } } @@ -21744,118 +23120,226 @@ impl<'de> serde::Deserialize<'de> for S3Upload { } struct GeneratedVisitor; impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { - type Value = S3Upload; + type Value = SipCallInfo; fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - formatter.write_str("struct livekit.S3Upload") + formatter.write_str("struct livekit.SIPCallInfo") } - fn visit_map(self, mut map_: V) -> std::result::Result + fn visit_map(self, mut map_: V) -> std::result::Result where V: serde::de::MapAccess<'de>, { - let mut access_key__ = None; - let mut secret__ = None; - let mut session_token__ = None; - let mut region__ = None; - let mut endpoint__ = None; - let mut bucket__ = None; - let mut force_path_style__ = None; - let mut metadata__ = None; - let mut tagging__ = None; - let mut content_disposition__ = None; - let mut proxy__ = None; + let mut call_id__ = None; + let mut trunk_id__ = None; + let mut room_name__ = None; + let mut room_id__ = None; + let mut participant_identity__ = None; + let mut from_uri__ = None; + let mut to_uri__ = None; + let mut enabled_features__ = None; + let mut call_status__ = None; + let mut created_at__ = None; + let mut started_at__ = None; + let mut ended_at__ = None; + let mut disconnect_reason__ = None; + let mut error__ = None; while let Some(k) = map_.next_key()? { match k { - GeneratedField::AccessKey => { - if access_key__.is_some() { - return Err(serde::de::Error::duplicate_field("accessKey")); + GeneratedField::CallId => { + if call_id__.is_some() { + return Err(serde::de::Error::duplicate_field("callId")); } - access_key__ = Some(map_.next_value()?); + call_id__ = Some(map_.next_value()?); } - GeneratedField::Secret => { - if secret__.is_some() { - return Err(serde::de::Error::duplicate_field("secret")); + GeneratedField::TrunkId => { + if trunk_id__.is_some() { + return Err(serde::de::Error::duplicate_field("trunkId")); } - secret__ = Some(map_.next_value()?); + trunk_id__ = Some(map_.next_value()?); } - GeneratedField::SessionToken => { - if session_token__.is_some() { - return Err(serde::de::Error::duplicate_field("sessionToken")); + GeneratedField::RoomName => { + if room_name__.is_some() { + return Err(serde::de::Error::duplicate_field("roomName")); } - session_token__ = Some(map_.next_value()?); + room_name__ = Some(map_.next_value()?); } - GeneratedField::Region => { - if region__.is_some() { - return Err(serde::de::Error::duplicate_field("region")); + GeneratedField::RoomId => { + if room_id__.is_some() { + return Err(serde::de::Error::duplicate_field("roomId")); } - region__ = Some(map_.next_value()?); + room_id__ = Some(map_.next_value()?); } - GeneratedField::Endpoint => { - if endpoint__.is_some() { - return Err(serde::de::Error::duplicate_field("endpoint")); + GeneratedField::ParticipantIdentity => { + if participant_identity__.is_some() { + return Err(serde::de::Error::duplicate_field("participantIdentity")); } - endpoint__ = Some(map_.next_value()?); + participant_identity__ = Some(map_.next_value()?); } - GeneratedField::Bucket => { - if bucket__.is_some() { - return Err(serde::de::Error::duplicate_field("bucket")); + GeneratedField::FromUri => { + if from_uri__.is_some() { + return Err(serde::de::Error::duplicate_field("fromUri")); } - bucket__ = Some(map_.next_value()?); + from_uri__ = map_.next_value()?; } - GeneratedField::ForcePathStyle => { - if force_path_style__.is_some() { - return Err(serde::de::Error::duplicate_field("forcePathStyle")); + GeneratedField::ToUri => { + if to_uri__.is_some() { + return Err(serde::de::Error::duplicate_field("toUri")); } - force_path_style__ = Some(map_.next_value()?); + to_uri__ = map_.next_value()?; } - GeneratedField::Metadata => { - if metadata__.is_some() { - return Err(serde::de::Error::duplicate_field("metadata")); + GeneratedField::EnabledFeatures => { + if enabled_features__.is_some() { + return Err(serde::de::Error::duplicate_field("enabledFeatures")); } - metadata__ = Some( - map_.next_value::>()? - ); + enabled_features__ = Some(map_.next_value::>()?.into_iter().map(|x| x as i32).collect()); } - GeneratedField::Tagging => { - if tagging__.is_some() { - return Err(serde::de::Error::duplicate_field("tagging")); + GeneratedField::CallStatus => { + if call_status__.is_some() { + return Err(serde::de::Error::duplicate_field("callStatus")); } - tagging__ = Some(map_.next_value()?); + call_status__ = Some(map_.next_value::()? as i32); } - GeneratedField::ContentDisposition => { - if content_disposition__.is_some() { - return Err(serde::de::Error::duplicate_field("contentDisposition")); + GeneratedField::CreatedAt => { + if created_at__.is_some() { + return Err(serde::de::Error::duplicate_field("createdAt")); } - content_disposition__ = Some(map_.next_value()?); + created_at__ = + Some(map_.next_value::<::pbjson::private::NumberDeserialize<_>>()?.0) + ; } - GeneratedField::Proxy => { - if proxy__.is_some() { - return Err(serde::de::Error::duplicate_field("proxy")); + GeneratedField::StartedAt => { + if started_at__.is_some() { + return Err(serde::de::Error::duplicate_field("startedAt")); } - proxy__ = map_.next_value()?; + started_at__ = + Some(map_.next_value::<::pbjson::private::NumberDeserialize<_>>()?.0) + ; + } + GeneratedField::EndedAt => { + if ended_at__.is_some() { + return Err(serde::de::Error::duplicate_field("endedAt")); + } + ended_at__ = + Some(map_.next_value::<::pbjson::private::NumberDeserialize<_>>()?.0) + ; + } + GeneratedField::DisconnectReason => { + if disconnect_reason__.is_some() { + return Err(serde::de::Error::duplicate_field("disconnectReason")); + } + disconnect_reason__ = Some(map_.next_value::()? as i32); + } + GeneratedField::Error => { + if error__.is_some() { + return Err(serde::de::Error::duplicate_field("error")); + } + error__ = Some(map_.next_value()?); } GeneratedField::__SkipField__ => { let _ = map_.next_value::()?; } } } - Ok(S3Upload { - access_key: access_key__.unwrap_or_default(), - secret: secret__.unwrap_or_default(), - session_token: session_token__.unwrap_or_default(), - region: region__.unwrap_or_default(), - endpoint: endpoint__.unwrap_or_default(), - bucket: bucket__.unwrap_or_default(), - force_path_style: force_path_style__.unwrap_or_default(), - metadata: metadata__.unwrap_or_default(), - tagging: tagging__.unwrap_or_default(), - content_disposition: content_disposition__.unwrap_or_default(), - proxy: proxy__, - }) + Ok(SipCallInfo { + call_id: call_id__.unwrap_or_default(), + trunk_id: trunk_id__.unwrap_or_default(), + room_name: room_name__.unwrap_or_default(), + room_id: room_id__.unwrap_or_default(), + participant_identity: participant_identity__.unwrap_or_default(), + from_uri: from_uri__, + to_uri: to_uri__, + enabled_features: enabled_features__.unwrap_or_default(), + call_status: call_status__.unwrap_or_default(), + created_at: created_at__.unwrap_or_default(), + started_at: started_at__.unwrap_or_default(), + ended_at: ended_at__.unwrap_or_default(), + disconnect_reason: disconnect_reason__.unwrap_or_default(), + error: error__.unwrap_or_default(), + }) + } + } + deserializer.deserialize_struct("livekit.SIPCallInfo", FIELDS, GeneratedVisitor) + } +} +impl serde::Serialize for SipCallStatus { + #[allow(deprecated)] + fn serialize(&self, serializer: S) -> std::result::Result + where + S: serde::Serializer, + { + let variant = match self { + Self::ScsCallIncoming => "SCS_CALL_INCOMING", + Self::ScsParticipantJoined => "SCS_PARTICIPANT_JOINED", + Self::ScsActive => "SCS_ACTIVE", + Self::ScsDisconnected => "SCS_DISCONNECTED", + Self::ScsError => "SCS_ERROR", + }; + serializer.serialize_str(variant) + } +} +impl<'de> serde::Deserialize<'de> for SipCallStatus { + #[allow(deprecated)] + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + const FIELDS: &[&str] = &[ + "SCS_CALL_INCOMING", + "SCS_PARTICIPANT_JOINED", + "SCS_ACTIVE", + "SCS_DISCONNECTED", + "SCS_ERROR", + ]; + + struct GeneratedVisitor; + + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = SipCallStatus; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(formatter, "expected one of: {:?}", &FIELDS) + } + + fn visit_i64(self, v: i64) -> std::result::Result + where + E: serde::de::Error, + { + i32::try_from(v) + .ok() + .and_then(|x| x.try_into().ok()) + .ok_or_else(|| { + serde::de::Error::invalid_value(serde::de::Unexpected::Signed(v), &self) + }) + } + + fn visit_u64(self, v: u64) -> std::result::Result + where + E: serde::de::Error, + { + i32::try_from(v) + .ok() + .and_then(|x| x.try_into().ok()) + .ok_or_else(|| { + serde::de::Error::invalid_value(serde::de::Unexpected::Unsigned(v), &self) + }) + } + + fn visit_str(self, value: &str) -> std::result::Result + where + E: serde::de::Error, + { + match value { + "SCS_CALL_INCOMING" => Ok(SipCallStatus::ScsCallIncoming), + "SCS_PARTICIPANT_JOINED" => Ok(SipCallStatus::ScsParticipantJoined), + "SCS_ACTIVE" => Ok(SipCallStatus::ScsActive), + "SCS_DISCONNECTED" => Ok(SipCallStatus::ScsDisconnected), + "SCS_ERROR" => Ok(SipCallStatus::ScsError), + _ => Err(serde::de::Error::unknown_variant(value, FIELDS)), + } } } - deserializer.deserialize_struct("livekit.S3Upload", FIELDS, GeneratedVisitor) + deserializer.deserialize_any(GeneratedVisitor) } } impl serde::Serialize for SipDispatchRule { @@ -22563,6 +24047,77 @@ impl<'de> serde::Deserialize<'de> for SipDispatchRuleInfo { deserializer.deserialize_struct("livekit.SIPDispatchRuleInfo", FIELDS, GeneratedVisitor) } } +impl serde::Serialize for SipFeature { + #[allow(deprecated)] + fn serialize(&self, serializer: S) -> std::result::Result + where + S: serde::Serializer, + { + let variant = match self { + Self::None => "NONE", + Self::KrispEnabled => "KRISP_ENABLED", + }; + serializer.serialize_str(variant) + } +} +impl<'de> serde::Deserialize<'de> for SipFeature { + #[allow(deprecated)] + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + const FIELDS: &[&str] = &[ + "NONE", + "KRISP_ENABLED", + ]; + + struct GeneratedVisitor; + + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = SipFeature; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(formatter, "expected one of: {:?}", &FIELDS) + } + + fn visit_i64(self, v: i64) -> std::result::Result + where + E: serde::de::Error, + { + i32::try_from(v) + .ok() + .and_then(|x| x.try_into().ok()) + .ok_or_else(|| { + serde::de::Error::invalid_value(serde::de::Unexpected::Signed(v), &self) + }) + } + + fn visit_u64(self, v: u64) -> std::result::Result + where + E: serde::de::Error, + { + i32::try_from(v) + .ok() + .and_then(|x| x.try_into().ok()) + .ok_or_else(|| { + serde::de::Error::invalid_value(serde::de::Unexpected::Unsigned(v), &self) + }) + } + + fn visit_str(self, value: &str) -> std::result::Result + where + E: serde::de::Error, + { + match value { + "NONE" => Ok(SipFeature::None), + "KRISP_ENABLED" => Ok(SipFeature::KrispEnabled), + _ => Err(serde::de::Error::unknown_variant(value, FIELDS)), + } + } + } + deserializer.deserialize_any(GeneratedVisitor) + } +} impl serde::Serialize for SipInboundTrunkInfo { #[allow(deprecated)] fn serialize(&self, serializer: S) -> std::result::Result @@ -22601,6 +24156,18 @@ impl serde::Serialize for SipInboundTrunkInfo { if !self.headers_to_attributes.is_empty() { len += 1; } + if !self.attributes_to_headers.is_empty() { + len += 1; + } + if self.ringing_timeout.is_some() { + len += 1; + } + if self.max_call_duration.is_some() { + len += 1; + } + if self.krisp_enabled { + len += 1; + } let mut struct_ser = serializer.serialize_struct("livekit.SIPInboundTrunkInfo", len)?; if !self.sip_trunk_id.is_empty() { struct_ser.serialize_field("sipTrunkId", &self.sip_trunk_id)?; @@ -22632,6 +24199,18 @@ impl serde::Serialize for SipInboundTrunkInfo { if !self.headers_to_attributes.is_empty() { struct_ser.serialize_field("headersToAttributes", &self.headers_to_attributes)?; } + if !self.attributes_to_headers.is_empty() { + struct_ser.serialize_field("attributesToHeaders", &self.attributes_to_headers)?; + } + if let Some(v) = self.ringing_timeout.as_ref() { + struct_ser.serialize_field("ringingTimeout", v)?; + } + if let Some(v) = self.max_call_duration.as_ref() { + struct_ser.serialize_field("maxCallDuration", v)?; + } + if self.krisp_enabled { + struct_ser.serialize_field("krispEnabled", &self.krisp_enabled)?; + } struct_ser.end() } } @@ -22658,6 +24237,14 @@ impl<'de> serde::Deserialize<'de> for SipInboundTrunkInfo { "headers", "headers_to_attributes", "headersToAttributes", + "attributes_to_headers", + "attributesToHeaders", + "ringing_timeout", + "ringingTimeout", + "max_call_duration", + "maxCallDuration", + "krisp_enabled", + "krispEnabled", ]; #[allow(clippy::enum_variant_names)] @@ -22672,6 +24259,10 @@ impl<'de> serde::Deserialize<'de> for SipInboundTrunkInfo { AuthPassword, Headers, HeadersToAttributes, + AttributesToHeaders, + RingingTimeout, + MaxCallDuration, + KrispEnabled, __SkipField__, } impl<'de> serde::Deserialize<'de> for GeneratedField { @@ -22704,6 +24295,10 @@ impl<'de> serde::Deserialize<'de> for SipInboundTrunkInfo { "authPassword" | "auth_password" => Ok(GeneratedField::AuthPassword), "headers" => Ok(GeneratedField::Headers), "headersToAttributes" | "headers_to_attributes" => Ok(GeneratedField::HeadersToAttributes), + "attributesToHeaders" | "attributes_to_headers" => Ok(GeneratedField::AttributesToHeaders), + "ringingTimeout" | "ringing_timeout" => Ok(GeneratedField::RingingTimeout), + "maxCallDuration" | "max_call_duration" => Ok(GeneratedField::MaxCallDuration), + "krispEnabled" | "krisp_enabled" => Ok(GeneratedField::KrispEnabled), _ => Ok(GeneratedField::__SkipField__), } } @@ -22733,6 +24328,10 @@ impl<'de> serde::Deserialize<'de> for SipInboundTrunkInfo { let mut auth_password__ = None; let mut headers__ = None; let mut headers_to_attributes__ = None; + let mut attributes_to_headers__ = None; + let mut ringing_timeout__ = None; + let mut max_call_duration__ = None; + let mut krisp_enabled__ = None; while let Some(k) = map_.next_key()? { match k { GeneratedField::SipTrunkId => { @@ -22799,6 +24398,32 @@ impl<'de> serde::Deserialize<'de> for SipInboundTrunkInfo { map_.next_value::>()? ); } + GeneratedField::AttributesToHeaders => { + if attributes_to_headers__.is_some() { + return Err(serde::de::Error::duplicate_field("attributesToHeaders")); + } + attributes_to_headers__ = Some( + map_.next_value::>()? + ); + } + GeneratedField::RingingTimeout => { + if ringing_timeout__.is_some() { + return Err(serde::de::Error::duplicate_field("ringingTimeout")); + } + ringing_timeout__ = map_.next_value()?; + } + GeneratedField::MaxCallDuration => { + if max_call_duration__.is_some() { + return Err(serde::de::Error::duplicate_field("maxCallDuration")); + } + max_call_duration__ = map_.next_value()?; + } + GeneratedField::KrispEnabled => { + if krisp_enabled__.is_some() { + return Err(serde::de::Error::duplicate_field("krispEnabled")); + } + krisp_enabled__ = Some(map_.next_value()?); + } GeneratedField::__SkipField__ => { let _ = map_.next_value::()?; } @@ -22815,6 +24440,10 @@ impl<'de> serde::Deserialize<'de> for SipInboundTrunkInfo { auth_password: auth_password__.unwrap_or_default(), headers: headers__.unwrap_or_default(), headers_to_attributes: headers_to_attributes__.unwrap_or_default(), + attributes_to_headers: attributes_to_headers__.unwrap_or_default(), + ringing_timeout: ringing_timeout__, + max_call_duration: max_call_duration__, + krisp_enabled: krisp_enabled__.unwrap_or_default(), }) } } @@ -22859,6 +24488,9 @@ impl serde::Serialize for SipOutboundTrunkInfo { if !self.headers_to_attributes.is_empty() { len += 1; } + if !self.attributes_to_headers.is_empty() { + len += 1; + } let mut struct_ser = serializer.serialize_struct("livekit.SIPOutboundTrunkInfo", len)?; if !self.sip_trunk_id.is_empty() { struct_ser.serialize_field("sipTrunkId", &self.sip_trunk_id)?; @@ -22892,6 +24524,9 @@ impl serde::Serialize for SipOutboundTrunkInfo { if !self.headers_to_attributes.is_empty() { struct_ser.serialize_field("headersToAttributes", &self.headers_to_attributes)?; } + if !self.attributes_to_headers.is_empty() { + struct_ser.serialize_field("attributesToHeaders", &self.attributes_to_headers)?; + } struct_ser.end() } } @@ -22916,6 +24551,8 @@ impl<'de> serde::Deserialize<'de> for SipOutboundTrunkInfo { "headers", "headers_to_attributes", "headersToAttributes", + "attributes_to_headers", + "attributesToHeaders", ]; #[allow(clippy::enum_variant_names)] @@ -22930,6 +24567,7 @@ impl<'de> serde::Deserialize<'de> for SipOutboundTrunkInfo { AuthPassword, Headers, HeadersToAttributes, + AttributesToHeaders, __SkipField__, } impl<'de> serde::Deserialize<'de> for GeneratedField { @@ -22962,6 +24600,7 @@ impl<'de> serde::Deserialize<'de> for SipOutboundTrunkInfo { "authPassword" | "auth_password" => Ok(GeneratedField::AuthPassword), "headers" => Ok(GeneratedField::Headers), "headersToAttributes" | "headers_to_attributes" => Ok(GeneratedField::HeadersToAttributes), + "attributesToHeaders" | "attributes_to_headers" => Ok(GeneratedField::AttributesToHeaders), _ => Ok(GeneratedField::__SkipField__), } } @@ -22991,6 +24630,7 @@ impl<'de> serde::Deserialize<'de> for SipOutboundTrunkInfo { let mut auth_password__ = None; let mut headers__ = None; let mut headers_to_attributes__ = None; + let mut attributes_to_headers__ = None; while let Some(k) = map_.next_key()? { match k { GeneratedField::SipTrunkId => { @@ -23057,6 +24697,14 @@ impl<'de> serde::Deserialize<'de> for SipOutboundTrunkInfo { map_.next_value::>()? ); } + GeneratedField::AttributesToHeaders => { + if attributes_to_headers__.is_some() { + return Err(serde::de::Error::duplicate_field("attributesToHeaders")); + } + attributes_to_headers__ = Some( + map_.next_value::>()? + ); + } GeneratedField::__SkipField__ => { let _ = map_.next_value::()?; } @@ -23073,6 +24721,7 @@ impl<'de> serde::Deserialize<'de> for SipOutboundTrunkInfo { auth_password: auth_password__.unwrap_or_default(), headers: headers__.unwrap_or_default(), headers_to_attributes: headers_to_attributes__.unwrap_or_default(), + attributes_to_headers: attributes_to_headers__.unwrap_or_default(), }) } } @@ -23710,6 +25359,173 @@ impl<'de> serde::Deserialize<'de> for sip_trunk_info::TrunkKind { deserializer.deserialize_any(GeneratedVisitor) } } +impl serde::Serialize for SipUri { + #[allow(deprecated)] + fn serialize(&self, serializer: S) -> std::result::Result + where + S: serde::Serializer, + { + use serde::ser::SerializeStruct; + let mut len = 0; + if !self.user.is_empty() { + len += 1; + } + if !self.host.is_empty() { + len += 1; + } + if !self.ip.is_empty() { + len += 1; + } + if self.port != 0 { + len += 1; + } + if self.transport != 0 { + len += 1; + } + let mut struct_ser = serializer.serialize_struct("livekit.SIPUri", len)?; + if !self.user.is_empty() { + struct_ser.serialize_field("user", &self.user)?; + } + if !self.host.is_empty() { + struct_ser.serialize_field("host", &self.host)?; + } + if !self.ip.is_empty() { + struct_ser.serialize_field("ip", &self.ip)?; + } + if self.port != 0 { + struct_ser.serialize_field("port", &self.port)?; + } + if self.transport != 0 { + let v = SipTransport::try_from(self.transport) + .map_err(|_| serde::ser::Error::custom(format!("Invalid variant {}", self.transport)))?; + struct_ser.serialize_field("transport", &v)?; + } + struct_ser.end() + } +} +impl<'de> serde::Deserialize<'de> for SipUri { + #[allow(deprecated)] + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + const FIELDS: &[&str] = &[ + "user", + "host", + "ip", + "port", + "transport", + ]; + + #[allow(clippy::enum_variant_names)] + enum GeneratedField { + User, + Host, + Ip, + Port, + Transport, + __SkipField__, + } + impl<'de> serde::Deserialize<'de> for GeneratedField { + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + struct GeneratedVisitor; + + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = GeneratedField; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(formatter, "expected one of: {:?}", &FIELDS) + } + + #[allow(unused_variables)] + fn visit_str(self, value: &str) -> std::result::Result + where + E: serde::de::Error, + { + match value { + "user" => Ok(GeneratedField::User), + "host" => Ok(GeneratedField::Host), + "ip" => Ok(GeneratedField::Ip), + "port" => Ok(GeneratedField::Port), + "transport" => Ok(GeneratedField::Transport), + _ => Ok(GeneratedField::__SkipField__), + } + } + } + deserializer.deserialize_identifier(GeneratedVisitor) + } + } + struct GeneratedVisitor; + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = SipUri; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + formatter.write_str("struct livekit.SIPUri") + } + + fn visit_map(self, mut map_: V) -> std::result::Result + where + V: serde::de::MapAccess<'de>, + { + let mut user__ = None; + let mut host__ = None; + let mut ip__ = None; + let mut port__ = None; + let mut transport__ = None; + while let Some(k) = map_.next_key()? { + match k { + GeneratedField::User => { + if user__.is_some() { + return Err(serde::de::Error::duplicate_field("user")); + } + user__ = Some(map_.next_value()?); + } + GeneratedField::Host => { + if host__.is_some() { + return Err(serde::de::Error::duplicate_field("host")); + } + host__ = Some(map_.next_value()?); + } + GeneratedField::Ip => { + if ip__.is_some() { + return Err(serde::de::Error::duplicate_field("ip")); + } + ip__ = Some(map_.next_value()?); + } + GeneratedField::Port => { + if port__.is_some() { + return Err(serde::de::Error::duplicate_field("port")); + } + port__ = + Some(map_.next_value::<::pbjson::private::NumberDeserialize<_>>()?.0) + ; + } + GeneratedField::Transport => { + if transport__.is_some() { + return Err(serde::de::Error::duplicate_field("transport")); + } + transport__ = Some(map_.next_value::()? as i32); + } + GeneratedField::__SkipField__ => { + let _ = map_.next_value::()?; + } + } + } + Ok(SipUri { + user: user__.unwrap_or_default(), + host: host__.unwrap_or_default(), + ip: ip__.unwrap_or_default(), + port: port__.unwrap_or_default(), + transport: transport__.unwrap_or_default(), + }) + } + } + deserializer.deserialize_struct("livekit.SIPUri", FIELDS, GeneratedVisitor) + } +} impl serde::Serialize for SegmentedFileOutput { #[allow(deprecated)] fn serialize(&self, serializer: S) -> std::result::Result @@ -30911,6 +32727,9 @@ impl serde::Serialize for TransferSipParticipantRequest { if !self.transfer_to.is_empty() { len += 1; } + if self.play_dialtone { + len += 1; + } let mut struct_ser = serializer.serialize_struct("livekit.TransferSIPParticipantRequest", len)?; if !self.participant_identity.is_empty() { struct_ser.serialize_field("participantIdentity", &self.participant_identity)?; @@ -30921,6 +32740,9 @@ impl serde::Serialize for TransferSipParticipantRequest { if !self.transfer_to.is_empty() { struct_ser.serialize_field("transferTo", &self.transfer_to)?; } + if self.play_dialtone { + struct_ser.serialize_field("playDialtone", &self.play_dialtone)?; + } struct_ser.end() } } @@ -30937,6 +32759,8 @@ impl<'de> serde::Deserialize<'de> for TransferSipParticipantRequest { "roomName", "transfer_to", "transferTo", + "play_dialtone", + "playDialtone", ]; #[allow(clippy::enum_variant_names)] @@ -30944,6 +32768,7 @@ impl<'de> serde::Deserialize<'de> for TransferSipParticipantRequest { ParticipantIdentity, RoomName, TransferTo, + PlayDialtone, __SkipField__, } impl<'de> serde::Deserialize<'de> for GeneratedField { @@ -30969,6 +32794,7 @@ impl<'de> serde::Deserialize<'de> for TransferSipParticipantRequest { "participantIdentity" | "participant_identity" => Ok(GeneratedField::ParticipantIdentity), "roomName" | "room_name" => Ok(GeneratedField::RoomName), "transferTo" | "transfer_to" => Ok(GeneratedField::TransferTo), + "playDialtone" | "play_dialtone" => Ok(GeneratedField::PlayDialtone), _ => Ok(GeneratedField::__SkipField__), } } @@ -30991,6 +32817,7 @@ impl<'de> serde::Deserialize<'de> for TransferSipParticipantRequest { let mut participant_identity__ = None; let mut room_name__ = None; let mut transfer_to__ = None; + let mut play_dialtone__ = None; while let Some(k) = map_.next_key()? { match k { GeneratedField::ParticipantIdentity => { @@ -31011,6 +32838,12 @@ impl<'de> serde::Deserialize<'de> for TransferSipParticipantRequest { } transfer_to__ = Some(map_.next_value()?); } + GeneratedField::PlayDialtone => { + if play_dialtone__.is_some() { + return Err(serde::de::Error::duplicate_field("playDialtone")); + } + play_dialtone__ = Some(map_.next_value()?); + } GeneratedField::__SkipField__ => { let _ = map_.next_value::()?; } @@ -31020,6 +32853,7 @@ impl<'de> serde::Deserialize<'de> for TransferSipParticipantRequest { participant_identity: participant_identity__.unwrap_or_default(), room_name: room_name__.unwrap_or_default(), transfer_to: transfer_to__.unwrap_or_default(), + play_dialtone: play_dialtone__.unwrap_or_default(), }) } } diff --git a/livekit/src/room/mod.rs b/livekit/src/room/mod.rs index 7e38cbff..c76f3436 100644 --- a/livekit/src/room/mod.rs +++ b/livekit/src/room/mod.rs @@ -720,6 +720,26 @@ impl RoomSession { EngineEvent::LocalTrackSubscribed { track_sid } => { self.handle_track_subscribed(track_sid) } + EngineEvent::DataStreamHeader { + stream_id, + timestamp, + topic, + mime_type, + total_length, + total_chunks, + } => { + self.handle_data_stream_header( + stream_id, + timestamp, + topic, + mime_type, + total_length, + total_chunks, + ); + } + EngineEvent::DataStreamChunk { stream_id, chunk_index, content, complete, version } => { + self.handle_data_stream_chunk(stream_id, chunk_index, content, complete, version); + } _ => {} } @@ -1229,6 +1249,31 @@ impl RoomSession { }); } + fn handle_data_stream_header( + &self, + stream_id: String, + timestamp: i64, + topic: String, + mime_type: String, + total_length: Option, + total_chunks: Option, + ) { + + // create and store readable stream + // emit event with readable stream and info + } + + fn handle_data_stream_chunk( + &self, + stream_id: String, + chunk_index: u64, + content: Vec, + complete: bool, + version: i32, + ) { + // update readable stream + } + /// Create a new participant /// Also add it to the participants list fn create_participant( diff --git a/livekit/src/rtc_engine/mod.rs b/livekit/src/rtc_engine/mod.rs index 4b3c4493..9fb5eee1 100644 --- a/livekit/src/rtc_engine/mod.rs +++ b/livekit/src/rtc_engine/mod.rs @@ -24,6 +24,7 @@ use tokio::sync::{ mpsc, oneshot, Mutex as AsyncMutex, Notify, RwLock as AsyncRwLock, RwLockReadGuard as AsyncRwLockReadGuard, }; +use tokio_stream::StreamExt; pub use self::rtc_session::SessionStats; use crate::prelude::ParticipantIdentity; @@ -159,6 +160,21 @@ pub enum EngineEvent { LocalTrackSubscribed { track_sid: String, }, + DataStreamHeader { + stream_id: String, + timestamp: i64, + topic: String, + mime_type: String, + total_length: Option, + total_chunks: Option, + }, + DataStreamChunk { + stream_id: String, + chunk_index: u64, + content: Vec, + complete: bool, + version: i32, + }, } /// Represents a running RtcSession with the ability to close the session @@ -524,6 +540,38 @@ impl EngineInner { SessionEvent::LocalTrackSubscribed { track_sid } => { let _ = self.engine_tx.send(EngineEvent::LocalTrackSubscribed { track_sid }); } + SessionEvent::DataStreamHeader { + stream_id, + timestamp, + topic, + mime_type, + total_length, + total_chunks, + } => { + let _ = self.engine_tx.send(EngineEvent::DataStreamHeader { + stream_id, + timestamp, + topic, + mime_type, + total_length, + total_chunks, + }); + } + SessionEvent::DataStreamChunk { + stream_id, + chunk_index, + content, + complete, + version, + } => { + let _ = self.engine_tx.send(EngineEvent::DataStreamChunk { + stream_id, + chunk_index, + content, + complete, + version, + }); + } } Ok(()) } diff --git a/livekit/src/rtc_engine/rtc_session.rs b/livekit/src/rtc_engine/rtc_session.rs index fa01a69f..2c9ba139 100644 --- a/livekit/src/rtc_engine/rtc_session.rs +++ b/livekit/src/rtc_engine/rtc_session.rs @@ -26,7 +26,7 @@ use std::{ use libwebrtc::{prelude::*, stats::RtcStats}; use livekit_api::signal_client::{SignalClient, SignalEvent, SignalEvents}; -use livekit_protocol as proto; +use livekit_protocol::{self as proto, Encryption}; use livekit_runtime::{sleep, JoinHandle}; use parking_lot::Mutex; use prost::Message; @@ -135,6 +135,21 @@ pub enum SessionEvent { action: proto::leave_request::Action, retry_now: bool, }, + DataStreamHeader { + stream_id: String, + timestamp: i64, + topic: String, + mime_type: String, + total_length: Option, + total_chunks: Option, + }, + DataStreamChunk { + stream_id: String, + chunk_index: u64, + content: Vec, + complete: bool, + version: i32, + }, } #[derive(Serialize, Deserialize)] @@ -723,6 +738,25 @@ impl SessionInner { message: ChatMessage::from(message.clone()), }); } + proto::data_packet::Value::StreamHeader(message) => { + let _ = self.emitter.send(SessionEvent::DataStreamHeader { + stream_id: message.stream_id.clone(), + timestamp: message.timestamp.clone(), + topic: message.topic.clone(), + mime_type: message.mime_type.clone(), + total_length: message.total_length.clone(), + total_chunks: message.total_chunks.clone(), + }); + } + proto::data_packet::Value::StreamChunk(message) => { + let _ = self.emitter.send(SessionEvent::DataStreamChunk { + stream_id: message.stream_id.clone(), + chunk_index: message.chunk_index.clone(), + content: message.content.clone(), + complete: message.complete.clone(), + version: message.version.clone(), + }); + } _ => {} } } From 55e0ee182806a96eca36eadbefce46296296d7fc Mon Sep 17 00:00:00 2001 From: lukasIO Date: Tue, 10 Dec 2024 19:18:47 +0100 Subject: [PATCH 02/18] wip filestream reader --- livekit/src/room/data_streams/mod.rs | 84 ++++++++++++++++++++++++++++ livekit/src/room/mod.rs | 26 ++++++++- livekit/src/rtc_engine/mod.rs | 1 - 3 files changed, 109 insertions(+), 2 deletions(-) create mode 100644 livekit/src/room/data_streams/mod.rs diff --git a/livekit/src/room/data_streams/mod.rs b/livekit/src/room/data_streams/mod.rs new file mode 100644 index 00000000..32ac8658 --- /dev/null +++ b/livekit/src/room/data_streams/mod.rs @@ -0,0 +1,84 @@ +use std::{ + pin::Pin, + task::{Context, Poll}, +}; + +use livekit_runtime::Stream; +use tokio::sync::mpsc; + +pub struct DataStreamChunk { + pub stream_id: String, + pub chunk_index: u64, + pub content: Vec, + pub complete: bool, + pub version: i32, +} + +pub struct FileStreamInfo { + pub stream_id: String, + pub timestamp: i64, + pub topic: String, + pub mime_type: String, + pub total_length: Option, + pub total_chunks: Option, +} + +pub struct FileStreamReader { + update_rx: mpsc::UnboundedReceiver, + pub info: FileStreamInfo, + is_closed: bool, +} + +impl FileStreamReader { + pub fn new(info: FileStreamInfo) -> (Self, FileStreamUpdater) { + let (update_tx, update_rx) = mpsc::unbounded_channel(); + (Self { update_rx, info, is_closed: false }, FileStreamUpdater { update_tx }) + } + + fn close(&mut self) { + self.is_closed = true; + self.update_rx.close(); + } +} + +impl Drop for FileStreamReader { + fn drop(&mut self) { + self.close(); + } +} + +impl Stream for FileStreamReader { + type Item = Vec; + + fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + if self.is_closed { + return Poll::Ready(None); // Stream is closed‚, stop yielding updates + } + match self.update_rx.poll_recv(cx) { + Poll::Ready(Some(update)) => { + if update.complete { + Poll::Ready(None) // Close stream after receiving a complete update + } else { + Poll::Ready(Some(update.content)) // Continue with data updates + } + } + Poll::Ready(None) => Poll::Ready(None), + Poll::Pending => Poll::Pending, + } + } +} + +/// Helper to send updates to the `FileStream`. +pub struct FileStreamUpdater { + update_tx: mpsc::UnboundedSender, +} + +impl FileStreamUpdater { + /// Sends an update to the `FileStream`. + pub fn send_update( + &self, + data: DataStreamChunk, + ) -> Result<(), mpsc::error::SendError> { + self.update_tx.send(data) + } +} diff --git a/livekit/src/room/mod.rs b/livekit/src/room/mod.rs index c76f3436..5b8f8248 100644 --- a/livekit/src/room/mod.rs +++ b/livekit/src/room/mod.rs @@ -14,6 +14,8 @@ use std::{collections::HashMap, fmt::Debug, sync::Arc, time::Duration}; +use data_streams::{DataStreamChunk, FileStreamInfo, FileStreamUpdater}; +use futures_util::StreamExt; use libwebrtc::{ native::frame_cryptor::EncryptionState, prelude::{ @@ -50,6 +52,7 @@ use crate::{ }, }; +pub mod data_streams; pub mod e2ee; pub mod id; pub mod options; @@ -365,6 +368,7 @@ pub(crate) struct RoomSession { remote_participants: RwLock>, e2ee_manager: E2eeManager, room_task: AsyncMutex, oneshot::Sender<()>)>>, + file_streams: HashMap, } impl Debug for RoomSession { @@ -506,6 +510,7 @@ impl Room { dispatcher: dispatcher.clone(), e2ee_manager: e2ee_manager.clone(), room_task: Default::default(), + file_streams: HashMap::new(), }); e2ee_manager.on_state_changed({ @@ -1258,6 +1263,18 @@ impl RoomSession { total_length: Option, total_chunks: Option, ) { + let (mut stream_reader, updater) = data_streams::FileStreamReader::new(FileStreamInfo { + stream_id, + timestamp, + topic, + mime_type, + total_length, + total_chunks, + }); + + self.file_streams.insert(stream_reader.info.stream_id.clone(), updater); + + let _ = self.dispatcher.dispatch(RoomEvent::FileStreamReceived { stream_reader }); // create and store readable stream // emit event with readable stream and info @@ -1271,7 +1288,14 @@ impl RoomSession { complete: bool, version: i32, ) { - // update readable stream + let file_updater = self.file_streams.get(&stream_id).unwrap(); + let _ = file_updater.send_update(DataStreamChunk { + stream_id, + chunk_index, + content, + complete, + version, + }); } /// Create a new participant diff --git a/livekit/src/rtc_engine/mod.rs b/livekit/src/rtc_engine/mod.rs index 9fb5eee1..5a177e95 100644 --- a/livekit/src/rtc_engine/mod.rs +++ b/livekit/src/rtc_engine/mod.rs @@ -24,7 +24,6 @@ use tokio::sync::{ mpsc, oneshot, Mutex as AsyncMutex, Notify, RwLock as AsyncRwLock, RwLockReadGuard as AsyncRwLockReadGuard, }; -use tokio_stream::StreamExt; pub use self::rtc_session::SessionStats; use crate::prelude::ParticipantIdentity; From 663e781a95ff6e508f6a5def6d46dfdab065d7fb Mon Sep 17 00:00:00 2001 From: lukasIO Date: Wed, 11 Dec 2024 12:49:59 +0100 Subject: [PATCH 03/18] text stream reader --- Cargo.lock | 10 +++ livekit/Cargo.toml | 1 + livekit/src/room/data_streams/mod.rs | 104 +++++++++++++++++++++++++++ livekit/src/room/mod.rs | 33 +++++---- 4 files changed, 135 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d907dc78..88d0c3d0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1423,6 +1423,15 @@ dependencies = [ "waker-fn", ] +[[package]] +name = "itertools" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f56a2d0bc861f9165be4eb3442afd3c236d8a98afd426f65d92324ae1091a484" +dependencies = [ + "either", +] + [[package]] name = "itertools" version = "0.10.5" @@ -1599,6 +1608,7 @@ version = "0.7.0" dependencies = [ "chrono", "futures-util", + "itertools 0.8.2", "lazy_static", "libwebrtc", "livekit-api", diff --git a/livekit/Cargo.toml b/livekit/Cargo.toml index 29113321..7609e51a 100644 --- a/livekit/Cargo.toml +++ b/livekit/Cargo.toml @@ -42,3 +42,4 @@ lazy_static = "1.4" log = "0.4" chrono = "0.4.38" semver = "1.0" +itertools = "0.8" diff --git a/livekit/src/room/data_streams/mod.rs b/livekit/src/room/data_streams/mod.rs index 32ac8658..d25e9966 100644 --- a/livekit/src/room/data_streams/mod.rs +++ b/livekit/src/room/data_streams/mod.rs @@ -1,11 +1,14 @@ use std::{ + collections::BTreeMap, pin::Pin, task::{Context, Poll}, }; +use itertools::Itertools; use livekit_runtime::Stream; use tokio::sync::mpsc; +#[derive(Debug, Clone)] pub struct DataStreamChunk { pub stream_id: String, pub chunk_index: u64, @@ -14,6 +17,7 @@ pub struct DataStreamChunk { pub version: i32, } +#[derive(Debug, Clone)] pub struct FileStreamInfo { pub stream_id: String, pub timestamp: i64, @@ -21,6 +25,7 @@ pub struct FileStreamInfo { pub mime_type: String, pub total_length: Option, pub total_chunks: Option, + pub file_name: String, } pub struct FileStreamReader { @@ -57,6 +62,7 @@ impl Stream for FileStreamReader { match self.update_rx.poll_recv(cx) { Poll::Ready(Some(update)) => { if update.complete { + self.close(); Poll::Ready(None) // Close stream after receiving a complete update } else { Poll::Ready(Some(update.content)) // Continue with data updates @@ -82,3 +88,101 @@ impl FileStreamUpdater { self.update_tx.send(data) } } + +#[derive(Debug, Clone)] +pub struct TexStreamInfo { + pub stream_id: String, + pub timestamp: i64, + pub topic: String, + pub mime_type: String, + pub total_length: Option, + pub total_chunks: Option, +} + +#[derive(Debug, Clone)] +pub struct TextStreamChunk { + pub collected: String, + pub current: String, + pub index: u64, +} + +pub struct TextStreamReader { + update_rx: mpsc::UnboundedReceiver, + pub info: TexStreamInfo, + is_closed: bool, + chunks: BTreeMap, +} + +impl TextStreamReader { + pub fn new(info: TexStreamInfo) -> (Self, TextStreamUpdater) { + let (update_tx, update_rx) = mpsc::unbounded_channel(); + ( + Self { update_rx, info, is_closed: false, chunks: BTreeMap::new() }, + TextStreamUpdater { update_tx }, + ) + } + + fn close(&mut self) { + self.is_closed = true; + self.chunks.clear(); + self.update_rx.close(); + } +} + +impl Drop for TextStreamReader { + fn drop(&mut self) { + self.close(); + } +} + +impl Stream for TextStreamReader { + type Item = TextStreamChunk; + + fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + if self.is_closed { + return Poll::Ready(None); // Stream is closed‚, stop yielding updates + } + match self.update_rx.poll_recv(cx) { + Poll::Ready(Some(update)) => { + if update.complete { + self.close(); + Poll::Ready(None) + } else { + if let Some(existing_chunk) = self.chunks.get(&update.chunk_index) { + if existing_chunk.version > update.version { + return Poll::Pending; // TODO verify this does what it sounds like it does + } + } + self.chunks.insert(update.chunk_index.clone(), update.clone()); + + Poll::Ready(Some(TextStreamChunk { + index: update.chunk_index, + current: String::from_utf8(update.content.clone()).unwrap(), + collected: self + .chunks + .iter() + .map(|val| String::from_utf8(val.1.content.clone()).unwrap()) + .join(""), + })) + } + } + Poll::Ready(None) => Poll::Ready(None), + Poll::Pending => Poll::Pending, + } + } +} + +/// Helper to send updates to the `FileStream`. +pub struct TextStreamUpdater { + update_tx: mpsc::UnboundedSender, +} + +impl TextStreamUpdater { + /// Sends an update to the `FileStream`. + pub fn send_update( + &self, + data: DataStreamChunk, + ) -> Result<(), mpsc::error::SendError> { + self.update_tx.send(data) + } +} diff --git a/livekit/src/room/mod.rs b/livekit/src/room/mod.rs index 5b8f8248..24d2fa7f 100644 --- a/livekit/src/room/mod.rs +++ b/livekit/src/room/mod.rs @@ -12,7 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -use std::{collections::HashMap, fmt::Debug, sync::Arc, time::Duration}; +use std::{ + borrow::BorrowMut, collections::HashMap, fmt::Debug, ops::Deref, sync::Arc, time::Duration, +}; use data_streams::{DataStreamChunk, FileStreamInfo, FileStreamUpdater}; use futures_util::StreamExt; @@ -368,7 +370,7 @@ pub(crate) struct RoomSession { remote_participants: RwLock>, e2ee_manager: E2eeManager, room_task: AsyncMutex, oneshot::Sender<()>)>>, - file_streams: HashMap, + file_streams: RwLock>, } impl Debug for RoomSession { @@ -510,7 +512,7 @@ impl Room { dispatcher: dispatcher.clone(), e2ee_manager: e2ee_manager.clone(), room_task: Default::default(), - file_streams: HashMap::new(), + file_streams: RwLock::new(HashMap::new()), }); e2ee_manager.on_state_changed({ @@ -659,7 +661,7 @@ impl RoomSession { log::debug!("room_task closed"); } - async fn on_engine_event(self: &Arc, event: EngineEvent) -> RoomResult<()> { + async fn on_engine_event(self: Arc, event: EngineEvent) -> RoomResult<()> { match event { EngineEvent::ParticipantUpdate { updates } => self.handle_participant_update(updates), EngineEvent::MediaTrack { track, stream, transceiver } => { @@ -1272,7 +1274,7 @@ impl RoomSession { total_chunks, }); - self.file_streams.insert(stream_reader.info.stream_id.clone(), updater); + self.file_streams.write().insert(stream_reader.info.stream_id.clone(), updater); let _ = self.dispatcher.dispatch(RoomEvent::FileStreamReceived { stream_reader }); @@ -1288,14 +1290,19 @@ impl RoomSession { complete: bool, version: i32, ) { - let file_updater = self.file_streams.get(&stream_id).unwrap(); - let _ = file_updater.send_update(DataStreamChunk { - stream_id, - chunk_index, - content, - complete, - version, - }); + if let Some(file_updater) = self.file_streams.read().get(&stream_id) { + let _ = file_updater.send_update(DataStreamChunk { + stream_id: stream_id.clone(), + chunk_index, + content, + complete, + version, + }); + + if complete { + let _ = self.file_streams.write().remove(&stream_id); + } + } } /// Create a new participant From 8974bc6f1083d1337d6cf3204b82900432f011f9 Mon Sep 17 00:00:00 2001 From: lukasIO Date: Wed, 11 Dec 2024 14:50:16 +0100 Subject: [PATCH 04/18] finish data stream receiving --- livekit/src/room/data_streams/mod.rs | 79 +++++++++++++++++++-------- livekit/src/room/mod.rs | 66 +++++++++++++++++----- livekit/src/rtc_engine/mod.rs | 4 ++ livekit/src/rtc_engine/rtc_session.rs | 4 +- 4 files changed, 116 insertions(+), 37 deletions(-) diff --git a/livekit/src/room/data_streams/mod.rs b/livekit/src/room/data_streams/mod.rs index d25e9966..58888aa1 100644 --- a/livekit/src/room/data_streams/mod.rs +++ b/livekit/src/room/data_streams/mod.rs @@ -1,11 +1,13 @@ use std::{ collections::BTreeMap, pin::Pin, + sync::Arc, task::{Context, Poll}, }; use itertools::Itertools; use livekit_runtime::Stream; +use parking_lot::Mutex; use tokio::sync::mpsc; #[derive(Debug, Clone)] @@ -27,9 +29,9 @@ pub struct FileStreamInfo { pub total_chunks: Option, pub file_name: String, } - +#[derive(Debug, Clone)] pub struct FileStreamReader { - update_rx: mpsc::UnboundedReceiver, + update_rx: Arc>>, pub info: FileStreamInfo, is_closed: bool, } @@ -37,12 +39,15 @@ pub struct FileStreamReader { impl FileStreamReader { pub fn new(info: FileStreamInfo) -> (Self, FileStreamUpdater) { let (update_tx, update_rx) = mpsc::unbounded_channel(); - (Self { update_rx, info, is_closed: false }, FileStreamUpdater { update_tx }) + ( + Self { update_rx: Arc::new(Mutex::new(update_rx)), info, is_closed: false }, + FileStreamUpdater { update_tx }, + ) } fn close(&mut self) { self.is_closed = true; - self.update_rx.close(); + self.update_rx.lock().close(); } } @@ -59,7 +64,12 @@ impl Stream for FileStreamReader { if self.is_closed { return Poll::Ready(None); // Stream is closed‚, stop yielding updates } - match self.update_rx.poll_recv(cx) { + let update_option = { + let mut guarded = self.update_rx.lock(); + guarded.poll_recv(cx) + }; + + match update_option { Poll::Ready(Some(update)) => { if update.complete { self.close(); @@ -90,13 +100,15 @@ impl FileStreamUpdater { } #[derive(Debug, Clone)] -pub struct TexStreamInfo { +pub struct TextStreamInfo { pub stream_id: String, pub timestamp: i64, pub topic: String, pub mime_type: String, pub total_length: Option, pub total_chunks: Option, + pub attachments: Vec, + pub version: i32, } #[derive(Debug, Clone)] @@ -105,19 +117,24 @@ pub struct TextStreamChunk { pub current: String, pub index: u64, } - +#[derive(Debug, Clone)] pub struct TextStreamReader { - update_rx: mpsc::UnboundedReceiver, - pub info: TexStreamInfo, + update_rx: Arc>>, + pub info: TextStreamInfo, is_closed: bool, chunks: BTreeMap, } impl TextStreamReader { - pub fn new(info: TexStreamInfo) -> (Self, TextStreamUpdater) { + pub fn new(info: TextStreamInfo) -> (Self, TextStreamUpdater) { let (update_tx, update_rx) = mpsc::unbounded_channel(); ( - Self { update_rx, info, is_closed: false, chunks: BTreeMap::new() }, + Self { + update_rx: Arc::new(Mutex::new(update_rx)), + info, + is_closed: false, + chunks: BTreeMap::new(), + }, TextStreamUpdater { update_tx }, ) } @@ -125,7 +142,7 @@ impl TextStreamReader { fn close(&mut self) { self.is_closed = true; self.chunks.clear(); - self.update_rx.close(); + self.update_rx.lock().close(); } } @@ -140,29 +157,45 @@ impl Stream for TextStreamReader { fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { if self.is_closed { + self.close(); return Poll::Ready(None); // Stream is closed‚, stop yielding updates } - match self.update_rx.poll_recv(cx) { + + let update_option = { + let mut guarded = self.update_rx.lock(); + guarded.poll_recv(cx) + }; + + match update_option { Poll::Ready(Some(update)) => { if update.complete { self.close(); Poll::Ready(None) } else { - if let Some(existing_chunk) = self.chunks.get(&update.chunk_index) { + let update_clone = update.clone(); + let chunk_index = update.chunk_index.clone(); + let content = update.content.clone(); + + // Check for existing chunk version + if let Some(existing_chunk) = self.chunks.get(&chunk_index) { if existing_chunk.version > update.version { - return Poll::Pending; // TODO verify this does what it sounds like it does + return Poll::Pending; } } - self.chunks.insert(update.chunk_index.clone(), update.clone()); + // Insert new chunk after immutable access + self.chunks.insert(chunk_index, update_clone); + + // Collect chunks + let collected = self + .chunks + .iter() + .map(|(_, chunk)| String::from_utf8(chunk.content.clone()).unwrap()) + .join(""); Poll::Ready(Some(TextStreamChunk { - index: update.chunk_index, - current: String::from_utf8(update.content.clone()).unwrap(), - collected: self - .chunks - .iter() - .map(|val| String::from_utf8(val.1.content.clone()).unwrap()) - .join(""), + index: chunk_index, + current: String::from_utf8(content).unwrap(), + collected, })) } } diff --git a/livekit/src/room/mod.rs b/livekit/src/room/mod.rs index 24d2fa7f..26b73aad 100644 --- a/livekit/src/room/mod.rs +++ b/livekit/src/room/mod.rs @@ -13,10 +13,14 @@ // limitations under the License. use std::{ - borrow::BorrowMut, collections::HashMap, fmt::Debug, ops::Deref, sync::Arc, time::Duration, + borrow::BorrowMut, collections::HashMap, fmt::Debug, hash::Hash, ops::Deref, sync::Arc, + time::Duration, }; -use data_streams::{DataStreamChunk, FileStreamInfo, FileStreamUpdater}; +use data_streams::{ + DataStreamChunk, FileStreamInfo, FileStreamReader, FileStreamUpdater, TextStreamInfo, + TextStreamReader, TextStreamUpdater, +}; use futures_util::StreamExt; use libwebrtc::{ native::frame_cryptor::EncryptionState, @@ -28,8 +32,8 @@ use libwebrtc::{ RtcError, }; use livekit_api::signal_client::{SignalOptions, SignalSdkOptions}; -use livekit_protocol as proto; use livekit_protocol::observer::Dispatcher; +use livekit_protocol::{self as proto, data_stream::header::ContentHeader}; use livekit_runtime::JoinHandle; use parking_lot::RwLock; pub use proto::DisconnectReason; @@ -176,6 +180,12 @@ pub enum RoomEvent { message: ChatMessage, participant: Option, }, + TextStreamReceived { + stream_reader: TextStreamReader, + }, + FileStreamReceived { + stream_reader: FileStreamReader, + }, E2eeStateChanged { participant: Participant, state: EncryptionState, @@ -371,6 +381,7 @@ pub(crate) struct RoomSession { e2ee_manager: E2eeManager, room_task: AsyncMutex, oneshot::Sender<()>)>>, file_streams: RwLock>, + text_streams: RwLock>, } impl Debug for RoomSession { @@ -513,6 +524,7 @@ impl Room { e2ee_manager: e2ee_manager.clone(), room_task: Default::default(), file_streams: RwLock::new(HashMap::new()), + text_streams: RwLock::new(HashMap::new()), }); e2ee_manager.on_state_changed({ @@ -734,6 +746,7 @@ impl RoomSession { mime_type, total_length, total_chunks, + content_header, } => { self.handle_data_stream_header( stream_id, @@ -742,6 +755,7 @@ impl RoomSession { mime_type, total_length, total_chunks, + content_header, ); } EngineEvent::DataStreamChunk { stream_id, chunk_index, content, complete, version } => { @@ -1264,19 +1278,45 @@ impl RoomSession { mime_type: String, total_length: Option, total_chunks: Option, + content_header: Option, ) { - let (mut stream_reader, updater) = data_streams::FileStreamReader::new(FileStreamInfo { - stream_id, - timestamp, - topic, - mime_type, - total_length, - total_chunks, - }); + match content_header.unwrap() { + ContentHeader::TextHeader(text_header) => { + let (stream_reader, updater) = + data_streams::TextStreamReader::new(TextStreamInfo { + stream_id, + timestamp, + topic, + mime_type, + total_length, + total_chunks, + attachments: text_header.attached_stream_ids, + version: text_header.version, + }); - self.file_streams.write().insert(stream_reader.info.stream_id.clone(), updater); + self.text_streams.write().insert(stream_reader.info.stream_id.clone(), updater); - let _ = self.dispatcher.dispatch(RoomEvent::FileStreamReceived { stream_reader }); + let event = RoomEvent::TextStreamReceived { stream_reader }; + self.dispatcher.dispatch(&event); + } + ContentHeader::FileHeader(file_header) => { + let (stream_reader, updater) = + data_streams::FileStreamReader::new(FileStreamInfo { + stream_id, + timestamp, + topic, + mime_type, + total_length, + total_chunks, + file_name: file_header.file_name, + }); + + self.file_streams.write().insert(stream_reader.info.stream_id.clone(), updater); + + let event = RoomEvent::FileStreamReceived { stream_reader }; + self.dispatcher.dispatch(&event); + } + } // create and store readable stream // emit event with readable stream and info diff --git a/livekit/src/rtc_engine/mod.rs b/livekit/src/rtc_engine/mod.rs index 5a177e95..18a6ff2b 100644 --- a/livekit/src/rtc_engine/mod.rs +++ b/livekit/src/rtc_engine/mod.rs @@ -17,6 +17,7 @@ use std::{borrow::Cow, fmt::Debug, sync::Arc, time::Duration}; use libwebrtc::prelude::*; use livekit_api::signal_client::{SignalError, SignalOptions}; use livekit_protocol as proto; +use livekit_protocol::data_stream::header::ContentHeader; use livekit_runtime::{interval, Interval, JoinHandle}; use parking_lot::{RwLock, RwLockReadGuard}; use thiserror::Error; @@ -166,6 +167,7 @@ pub enum EngineEvent { mime_type: String, total_length: Option, total_chunks: Option, + content_header: Option, }, DataStreamChunk { stream_id: String, @@ -546,6 +548,7 @@ impl EngineInner { mime_type, total_length, total_chunks, + content_header, } => { let _ = self.engine_tx.send(EngineEvent::DataStreamHeader { stream_id, @@ -554,6 +557,7 @@ impl EngineInner { mime_type, total_length, total_chunks, + content_header, }); } SessionEvent::DataStreamChunk { diff --git a/livekit/src/rtc_engine/rtc_session.rs b/livekit/src/rtc_engine/rtc_session.rs index 2c9ba139..841e0af5 100644 --- a/livekit/src/rtc_engine/rtc_session.rs +++ b/livekit/src/rtc_engine/rtc_session.rs @@ -26,7 +26,7 @@ use std::{ use libwebrtc::{prelude::*, stats::RtcStats}; use livekit_api::signal_client::{SignalClient, SignalEvent, SignalEvents}; -use livekit_protocol::{self as proto, Encryption}; +use livekit_protocol::{self as proto, data_stream::header::ContentHeader, Encryption}; use livekit_runtime::{sleep, JoinHandle}; use parking_lot::Mutex; use prost::Message; @@ -142,6 +142,7 @@ pub enum SessionEvent { mime_type: String, total_length: Option, total_chunks: Option, + content_header: Option, }, DataStreamChunk { stream_id: String, @@ -746,6 +747,7 @@ impl SessionInner { mime_type: message.mime_type.clone(), total_length: message.total_length.clone(), total_chunks: message.total_chunks.clone(), + content_header: message.content_header.clone(), }); } proto::data_packet::Value::StreamChunk(message) => { From 111e99746c6a08928ae0e38c704984822056d92e Mon Sep 17 00:00:00 2001 From: lukasIO Date: Wed, 11 Dec 2024 19:07:22 +0100 Subject: [PATCH 05/18] cleanup --- livekit/src/room/data_streams/mod.rs | 6 +++--- livekit/src/room/mod.rs | 29 +++++++++------------------- 2 files changed, 12 insertions(+), 23 deletions(-) diff --git a/livekit/src/room/data_streams/mod.rs b/livekit/src/room/data_streams/mod.rs index 58888aa1..df482fae 100644 --- a/livekit/src/room/data_streams/mod.rs +++ b/livekit/src/room/data_streams/mod.rs @@ -173,7 +173,7 @@ impl Stream for TextStreamReader { Poll::Ready(None) } else { let update_clone = update.clone(); - let chunk_index = update.chunk_index.clone(); + let chunk_index = update.chunk_index; let content = update.content.clone(); // Check for existing chunk version @@ -188,8 +188,8 @@ impl Stream for TextStreamReader { // Collect chunks let collected = self .chunks - .iter() - .map(|(_, chunk)| String::from_utf8(chunk.content.clone()).unwrap()) + .values() + .map(|chunk| String::from_utf8(chunk.content.clone()).unwrap()) .join(""); Poll::Ready(Some(TextStreamChunk { diff --git a/livekit/src/room/mod.rs b/livekit/src/room/mod.rs index 26b73aad..30f4f0de 100644 --- a/livekit/src/room/mod.rs +++ b/livekit/src/room/mod.rs @@ -12,16 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -use std::{ - borrow::BorrowMut, collections::HashMap, fmt::Debug, hash::Hash, ops::Deref, sync::Arc, - time::Duration, -}; +use std::{collections::HashMap, fmt::Debug, sync::Arc, time::Duration}; -use data_streams::{ - DataStreamChunk, FileStreamInfo, FileStreamReader, FileStreamUpdater, TextStreamInfo, - TextStreamReader, TextStreamUpdater, -}; -use futures_util::StreamExt; use libwebrtc::{ native::frame_cryptor::EncryptionState, prelude::{ @@ -39,10 +31,7 @@ use parking_lot::RwLock; pub use proto::DisconnectReason; use proto::{promise::Promise, SignalTarget}; use thiserror::Error; -use tokio::{ - signal, - sync::{mpsc, oneshot, Mutex as AsyncMutex}, -}; +use tokio::sync::{mpsc, oneshot, Mutex as AsyncMutex}; pub use self::{ e2ee::{manager::E2eeManager, E2eeOptions}, @@ -181,10 +170,10 @@ pub enum RoomEvent { participant: Option, }, TextStreamReceived { - stream_reader: TextStreamReader, + stream_reader: data_streams::TextStreamReader, }, FileStreamReceived { - stream_reader: FileStreamReader, + stream_reader: data_streams::FileStreamReader, }, E2eeStateChanged { participant: Participant, @@ -380,8 +369,8 @@ pub(crate) struct RoomSession { remote_participants: RwLock>, e2ee_manager: E2eeManager, room_task: AsyncMutex, oneshot::Sender<()>)>>, - file_streams: RwLock>, - text_streams: RwLock>, + file_streams: RwLock>, + text_streams: RwLock>, } impl Debug for RoomSession { @@ -1283,7 +1272,7 @@ impl RoomSession { match content_header.unwrap() { ContentHeader::TextHeader(text_header) => { let (stream_reader, updater) = - data_streams::TextStreamReader::new(TextStreamInfo { + data_streams::TextStreamReader::new(data_streams::TextStreamInfo { stream_id, timestamp, topic, @@ -1301,7 +1290,7 @@ impl RoomSession { } ContentHeader::FileHeader(file_header) => { let (stream_reader, updater) = - data_streams::FileStreamReader::new(FileStreamInfo { + data_streams::FileStreamReader::new(data_streams::FileStreamInfo { stream_id, timestamp, topic, @@ -1331,7 +1320,7 @@ impl RoomSession { version: i32, ) { if let Some(file_updater) = self.file_streams.read().get(&stream_id) { - let _ = file_updater.send_update(DataStreamChunk { + let _ = file_updater.send_update(data_streams::DataStreamChunk { stream_id: stream_id.clone(), chunk_index, content, From 922674200dada4fadb33d605b5606d57ddbd2b32 Mon Sep 17 00:00:00 2001 From: lukasIO Date: Thu, 12 Dec 2024 10:45:16 +0100 Subject: [PATCH 06/18] receiving working --- livekit/src/room/data_streams/mod.rs | 17 ++++++++++++----- livekit/src/room/mod.rs | 12 ++++++++++++ 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/livekit/src/room/data_streams/mod.rs b/livekit/src/room/data_streams/mod.rs index df482fae..6a113d85 100644 --- a/livekit/src/room/data_streams/mod.rs +++ b/livekit/src/room/data_streams/mod.rs @@ -142,7 +142,6 @@ impl TextStreamReader { fn close(&mut self) { self.is_closed = true; self.chunks.clear(); - self.update_rx.lock().close(); } } @@ -157,19 +156,19 @@ impl Stream for TextStreamReader { fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { if self.is_closed { - self.close(); return Poll::Ready(None); // Stream is closed‚, stop yielding updates } + log::info!("acquiring update_rx"); let update_option = { let mut guarded = self.update_rx.lock(); guarded.poll_recv(cx) }; + log::info!("matching update_rx"); match update_option { Poll::Ready(Some(update)) => { if update.complete { - self.close(); Poll::Ready(None) } else { let update_clone = update.clone(); @@ -192,6 +191,7 @@ impl Stream for TextStreamReader { .map(|chunk| String::from_utf8(chunk.content.clone()).unwrap()) .join(""); + log::info!("new text chunk ready"); Poll::Ready(Some(TextStreamChunk { index: chunk_index, current: String::from_utf8(content).unwrap(), @@ -199,8 +199,14 @@ impl Stream for TextStreamReader { })) } } - Poll::Ready(None) => Poll::Ready(None), - Poll::Pending => Poll::Pending, + Poll::Ready(None) => { + log::info!("poll none ready"); + Poll::Pending + } + Poll::Pending => { + log::info!("poll pending"); + Poll::Pending + } } } } @@ -216,6 +222,7 @@ impl TextStreamUpdater { &self, data: DataStreamChunk, ) -> Result<(), mpsc::error::SendError> { + log::info!("received text chunk update"); self.update_tx.send(data) } } diff --git a/livekit/src/room/mod.rs b/livekit/src/room/mod.rs index 30f4f0de..3b629b3a 100644 --- a/livekit/src/room/mod.rs +++ b/livekit/src/room/mod.rs @@ -1331,6 +1331,18 @@ impl RoomSession { if complete { let _ = self.file_streams.write().remove(&stream_id); } + } else if let Some(text_updater) = self.text_streams.read().get(&stream_id) { + let _ = text_updater.send_update(data_streams::DataStreamChunk { + stream_id: stream_id.clone(), + chunk_index, + content, + complete, + version, + }); + + if complete { + let _ = self.text_streams.write().remove(&stream_id); + } } } From 5073edaf927f02fac1bd594cba12cddc15ae4c52 Mon Sep 17 00:00:00 2001 From: lukasIO Date: Thu, 12 Dec 2024 12:34:51 +0100 Subject: [PATCH 07/18] working with mutex --- livekit/src/room/data_streams/mod.rs | 70 ++++++++++++++++------------ livekit/src/room/mod.rs | 26 ++++++----- 2 files changed, 55 insertions(+), 41 deletions(-) diff --git a/livekit/src/room/data_streams/mod.rs b/livekit/src/room/data_streams/mod.rs index 6a113d85..ca89d952 100644 --- a/livekit/src/room/data_streams/mod.rs +++ b/livekit/src/room/data_streams/mod.rs @@ -168,36 +168,39 @@ impl Stream for TextStreamReader { match update_option { Poll::Ready(Some(update)) => { - if update.complete { - Poll::Ready(None) - } else { - let update_clone = update.clone(); - let chunk_index = update.chunk_index; - let content = update.content.clone(); - - // Check for existing chunk version - if let Some(existing_chunk) = self.chunks.get(&chunk_index) { - if existing_chunk.version > update.version { - return Poll::Pending; - } + let update_clone = update.clone(); + let chunk_index = update.chunk_index; + let content = update.content.clone(); + + // Check for existing chunk version + if let Some(existing_chunk) = self.chunks.get(&chunk_index) { + if existing_chunk.version > update.version { + return Poll::Pending; } - // Insert new chunk after immutable access - self.chunks.insert(chunk_index, update_clone); - - // Collect chunks - let collected = self - .chunks - .values() - .map(|chunk| String::from_utf8(chunk.content.clone()).unwrap()) - .join(""); - - log::info!("new text chunk ready"); - Poll::Ready(Some(TextStreamChunk { - index: chunk_index, - current: String::from_utf8(content).unwrap(), - collected, - })) } + // Insert new chunk after immutable access + self.chunks.insert(chunk_index, update_clone); + + if update.complete { + log::info!("should be closing stream"); + self.update_rx.lock().close(); + return Poll::Ready(None); + } + + // Collect chunks + let collected = self + .chunks + .values() + .map(|chunk| String::from_utf8(chunk.content.clone()).unwrap()) + .join(""); + + log::info!("new text chunk ready"); + + Poll::Ready(Some(TextStreamChunk { + index: chunk_index, + current: String::from_utf8(content).unwrap(), + collected, + })) } Poll::Ready(None) => { log::info!("poll none ready"); @@ -205,13 +208,20 @@ impl Stream for TextStreamReader { } Poll::Pending => { log::info!("poll pending"); - Poll::Pending + if self.is_closed { + log::info!("closing pending update"); + self.update_rx.lock().close(); + Poll::Ready(None) + } else { + Poll::Pending + } } } } } /// Helper to send updates to the `FileStream`. +#[derive(Debug, Clone)] pub struct TextStreamUpdater { update_tx: mpsc::UnboundedSender, } @@ -222,7 +232,7 @@ impl TextStreamUpdater { &self, data: DataStreamChunk, ) -> Result<(), mpsc::error::SendError> { - log::info!("received text chunk update"); + log::info!("received text chunk update complete: {:?}", data.complete); self.update_tx.send(data) } } diff --git a/livekit/src/room/mod.rs b/livekit/src/room/mod.rs index 3b629b3a..22c57673 100644 --- a/livekit/src/room/mod.rs +++ b/livekit/src/room/mod.rs @@ -27,7 +27,7 @@ use livekit_api::signal_client::{SignalOptions, SignalSdkOptions}; use livekit_protocol::observer::Dispatcher; use livekit_protocol::{self as proto, data_stream::header::ContentHeader}; use livekit_runtime::JoinHandle; -use parking_lot::RwLock; +use parking_lot::{Mutex, RwLock}; pub use proto::DisconnectReason; use proto::{promise::Promise, SignalTarget}; use thiserror::Error; @@ -369,8 +369,8 @@ pub(crate) struct RoomSession { remote_participants: RwLock>, e2ee_manager: E2eeManager, room_task: AsyncMutex, oneshot::Sender<()>)>>, - file_streams: RwLock>, - text_streams: RwLock>, + file_streams: Arc>>, + text_streams: Arc>>, } impl Debug for RoomSession { @@ -512,8 +512,8 @@ impl Room { dispatcher: dispatcher.clone(), e2ee_manager: e2ee_manager.clone(), room_task: Default::default(), - file_streams: RwLock::new(HashMap::new()), - text_streams: RwLock::new(HashMap::new()), + file_streams: Arc::new(Mutex::new(HashMap::new())), + text_streams: Arc::new(Mutex::new(HashMap::new())), }); e2ee_manager.on_state_changed({ @@ -1283,7 +1283,7 @@ impl RoomSession { version: text_header.version, }); - self.text_streams.write().insert(stream_reader.info.stream_id.clone(), updater); + self.text_streams.lock().insert(stream_reader.info.stream_id.clone(), updater); let event = RoomEvent::TextStreamReceived { stream_reader }; self.dispatcher.dispatch(&event); @@ -1300,7 +1300,7 @@ impl RoomSession { file_name: file_header.file_name, }); - self.file_streams.write().insert(stream_reader.info.stream_id.clone(), updater); + self.file_streams.lock().insert(stream_reader.info.stream_id.clone(), updater); let event = RoomEvent::FileStreamReceived { stream_reader }; self.dispatcher.dispatch(&event); @@ -1319,7 +1319,9 @@ impl RoomSession { complete: bool, version: i32, ) { - if let Some(file_updater) = self.file_streams.read().get(&stream_id) { + let mut locked_file_streams = self.file_streams.lock(); + let mut locked_text_streams = self.text_streams.lock(); + if let Some(file_updater) = locked_file_streams.get(&stream_id) { let _ = file_updater.send_update(data_streams::DataStreamChunk { stream_id: stream_id.clone(), chunk_index, @@ -1329,9 +1331,9 @@ impl RoomSession { }); if complete { - let _ = self.file_streams.write().remove(&stream_id); + let _ = locked_file_streams.remove(&stream_id); } - } else if let Some(text_updater) = self.text_streams.read().get(&stream_id) { + } else if let Some(text_updater) = locked_text_streams.get(&stream_id) { let _ = text_updater.send_update(data_streams::DataStreamChunk { stream_id: stream_id.clone(), chunk_index, @@ -1341,7 +1343,9 @@ impl RoomSession { }); if complete { - let _ = self.text_streams.write().remove(&stream_id); + log::info!("removing text stream"); + let _ = locked_text_streams.remove(&stream_id); + log::info!("removed text stream"); } } } From 9fe04ce30b5e5c2e2a15fb1c16d9780056a1ebd9 Mon Sep 17 00:00:00 2001 From: lukasIO Date: Thu, 12 Dec 2024 12:40:24 +0100 Subject: [PATCH 08/18] working with RWLock --- livekit/src/room/mod.rs | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/livekit/src/room/mod.rs b/livekit/src/room/mod.rs index 22c57673..a5587442 100644 --- a/livekit/src/room/mod.rs +++ b/livekit/src/room/mod.rs @@ -27,7 +27,7 @@ use livekit_api::signal_client::{SignalOptions, SignalSdkOptions}; use livekit_protocol::observer::Dispatcher; use livekit_protocol::{self as proto, data_stream::header::ContentHeader}; use livekit_runtime::JoinHandle; -use parking_lot::{Mutex, RwLock}; +use parking_lot::RwLock; pub use proto::DisconnectReason; use proto::{promise::Promise, SignalTarget}; use thiserror::Error; @@ -369,8 +369,8 @@ pub(crate) struct RoomSession { remote_participants: RwLock>, e2ee_manager: E2eeManager, room_task: AsyncMutex, oneshot::Sender<()>)>>, - file_streams: Arc>>, - text_streams: Arc>>, + file_streams: RwLock>, + text_streams: RwLock>, } impl Debug for RoomSession { @@ -512,8 +512,8 @@ impl Room { dispatcher: dispatcher.clone(), e2ee_manager: e2ee_manager.clone(), room_task: Default::default(), - file_streams: Arc::new(Mutex::new(HashMap::new())), - text_streams: Arc::new(Mutex::new(HashMap::new())), + file_streams: RwLock::new(HashMap::new()), + text_streams: RwLock::new(HashMap::new()), }); e2ee_manager.on_state_changed({ @@ -1283,7 +1283,7 @@ impl RoomSession { version: text_header.version, }); - self.text_streams.lock().insert(stream_reader.info.stream_id.clone(), updater); + self.text_streams.write().insert(stream_reader.info.stream_id.clone(), updater); let event = RoomEvent::TextStreamReceived { stream_reader }; self.dispatcher.dispatch(&event); @@ -1300,15 +1300,12 @@ impl RoomSession { file_name: file_header.file_name, }); - self.file_streams.lock().insert(stream_reader.info.stream_id.clone(), updater); + self.file_streams.write().insert(stream_reader.info.stream_id.clone(), updater); let event = RoomEvent::FileStreamReceived { stream_reader }; self.dispatcher.dispatch(&event); } } - - // create and store readable stream - // emit event with readable stream and info } fn handle_data_stream_chunk( @@ -1319,8 +1316,8 @@ impl RoomSession { complete: bool, version: i32, ) { - let mut locked_file_streams = self.file_streams.lock(); - let mut locked_text_streams = self.text_streams.lock(); + let mut locked_file_streams = self.file_streams.write(); + let mut locked_text_streams = self.text_streams.write(); if let Some(file_updater) = locked_file_streams.get(&stream_id) { let _ = file_updater.send_update(data_streams::DataStreamChunk { stream_id: stream_id.clone(), From ed3ae077a65ed81bd2dbb714f34d90189c30d151 Mon Sep 17 00:00:00 2001 From: lukasIO Date: Thu, 12 Dec 2024 13:08:30 +0100 Subject: [PATCH 09/18] cleanup --- livekit/src/room/data_streams/mod.rs | 17 ++++------------- livekit/src/room/mod.rs | 2 -- 2 files changed, 4 insertions(+), 15 deletions(-) diff --git a/livekit/src/room/data_streams/mod.rs b/livekit/src/room/data_streams/mod.rs index ca89d952..047851ff 100644 --- a/livekit/src/room/data_streams/mod.rs +++ b/livekit/src/room/data_streams/mod.rs @@ -156,15 +156,14 @@ impl Stream for TextStreamReader { fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { if self.is_closed { + self.update_rx.lock().close(); return Poll::Ready(None); // Stream is closed‚, stop yielding updates } - log::info!("acquiring update_rx"); let update_option = { let mut guarded = self.update_rx.lock(); guarded.poll_recv(cx) }; - log::info!("matching update_rx"); match update_option { Poll::Ready(Some(update)) => { @@ -182,7 +181,7 @@ impl Stream for TextStreamReader { self.chunks.insert(chunk_index, update_clone); if update.complete { - log::info!("should be closing stream"); + log::debug!("closing stream as it's complete"); self.update_rx.lock().close(); return Poll::Ready(None); } @@ -194,22 +193,16 @@ impl Stream for TextStreamReader { .map(|chunk| String::from_utf8(chunk.content.clone()).unwrap()) .join(""); - log::info!("new text chunk ready"); - Poll::Ready(Some(TextStreamChunk { index: chunk_index, current: String::from_utf8(content).unwrap(), collected, })) } - Poll::Ready(None) => { - log::info!("poll none ready"); - Poll::Pending - } + Poll::Ready(None) => Poll::Pending, Poll::Pending => { - log::info!("poll pending"); if self.is_closed { - log::info!("closing pending update"); + log::debug!("closing pending update"); self.update_rx.lock().close(); Poll::Ready(None) } else { @@ -221,7 +214,6 @@ impl Stream for TextStreamReader { } /// Helper to send updates to the `FileStream`. -#[derive(Debug, Clone)] pub struct TextStreamUpdater { update_tx: mpsc::UnboundedSender, } @@ -232,7 +224,6 @@ impl TextStreamUpdater { &self, data: DataStreamChunk, ) -> Result<(), mpsc::error::SendError> { - log::info!("received text chunk update complete: {:?}", data.complete); self.update_tx.send(data) } } diff --git a/livekit/src/room/mod.rs b/livekit/src/room/mod.rs index a5587442..8c43d62e 100644 --- a/livekit/src/room/mod.rs +++ b/livekit/src/room/mod.rs @@ -1340,9 +1340,7 @@ impl RoomSession { }); if complete { - log::info!("removing text stream"); let _ = locked_text_streams.remove(&stream_id); - log::info!("removed text stream"); } } } From 2346e5a36491214fa5b95dfbe1d7cccce4c58372 Mon Sep 17 00:00:00 2001 From: lukasIO Date: Thu, 12 Dec 2024 14:37:02 +0100 Subject: [PATCH 10/18] simplify --- livekit/src/room/data_streams/mod.rs | 38 +++++++++++-------------- livekit/src/room/mod.rs | 41 +++++++-------------------- livekit/src/rtc_engine/mod.rs | 25 ++++------------ livekit/src/rtc_engine/rtc_session.rs | 16 +++-------- 4 files changed, 37 insertions(+), 83 deletions(-) diff --git a/livekit/src/room/data_streams/mod.rs b/livekit/src/room/data_streams/mod.rs index 047851ff..c77638f2 100644 --- a/livekit/src/room/data_streams/mod.rs +++ b/livekit/src/room/data_streams/mod.rs @@ -10,14 +10,16 @@ use livekit_runtime::Stream; use parking_lot::Mutex; use tokio::sync::mpsc; -#[derive(Debug, Clone)] -pub struct DataStreamChunk { - pub stream_id: String, - pub chunk_index: u64, - pub content: Vec, - pub complete: bool, - pub version: i32, -} +use livekit_protocol::data_stream::Chunk; + +// #[derive(Debug, Clone)] +// pub struct DataStreamChunk { +// pub stream_id: String, +// pub chunk_index: u64, +// pub content: Vec, +// pub complete: bool, +// pub version: i32, +// } #[derive(Debug, Clone)] pub struct FileStreamInfo { @@ -31,7 +33,7 @@ pub struct FileStreamInfo { } #[derive(Debug, Clone)] pub struct FileStreamReader { - update_rx: Arc>>, + update_rx: Arc>>, pub info: FileStreamInfo, is_closed: bool, } @@ -86,15 +88,12 @@ impl Stream for FileStreamReader { /// Helper to send updates to the `FileStream`. pub struct FileStreamUpdater { - update_tx: mpsc::UnboundedSender, + update_tx: mpsc::UnboundedSender, } impl FileStreamUpdater { /// Sends an update to the `FileStream`. - pub fn send_update( - &self, - data: DataStreamChunk, - ) -> Result<(), mpsc::error::SendError> { + pub fn send_update(&self, data: Chunk) -> Result<(), mpsc::error::SendError> { self.update_tx.send(data) } } @@ -119,10 +118,10 @@ pub struct TextStreamChunk { } #[derive(Debug, Clone)] pub struct TextStreamReader { - update_rx: Arc>>, + update_rx: Arc>>, pub info: TextStreamInfo, is_closed: bool, - chunks: BTreeMap, + chunks: BTreeMap, } impl TextStreamReader { @@ -215,15 +214,12 @@ impl Stream for TextStreamReader { /// Helper to send updates to the `FileStream`. pub struct TextStreamUpdater { - update_tx: mpsc::UnboundedSender, + update_tx: mpsc::UnboundedSender, } impl TextStreamUpdater { /// Sends an update to the `FileStream`. - pub fn send_update( - &self, - data: DataStreamChunk, - ) -> Result<(), mpsc::error::SendError> { + pub fn send_update(&self, data: Chunk) -> Result<(), mpsc::error::SendError> { self.update_tx.send(data) } } diff --git a/livekit/src/room/mod.rs b/livekit/src/room/mod.rs index 8c43d62e..0ef8bcd7 100644 --- a/livekit/src/room/mod.rs +++ b/livekit/src/room/mod.rs @@ -747,8 +747,8 @@ impl RoomSession { content_header, ); } - EngineEvent::DataStreamChunk { stream_id, chunk_index, content, complete, version } => { - self.handle_data_stream_chunk(stream_id, chunk_index, content, complete, version); + EngineEvent::DataStreamChunk { chunk } => { + self.handle_data_stream_chunk(chunk); } _ => {} } @@ -1308,39 +1308,20 @@ impl RoomSession { } } - fn handle_data_stream_chunk( - &self, - stream_id: String, - chunk_index: u64, - content: Vec, - complete: bool, - version: i32, - ) { + fn handle_data_stream_chunk(&self, chunk: proto::data_stream::Chunk) { let mut locked_file_streams = self.file_streams.write(); let mut locked_text_streams = self.text_streams.write(); - if let Some(file_updater) = locked_file_streams.get(&stream_id) { - let _ = file_updater.send_update(data_streams::DataStreamChunk { - stream_id: stream_id.clone(), - chunk_index, - content, - complete, - version, - }); + if let Some(file_updater) = locked_file_streams.get(&chunk.stream_id) { + let _ = file_updater.send_update(chunk.clone()); - if complete { - let _ = locked_file_streams.remove(&stream_id); + if chunk.complete { + let _ = locked_file_streams.remove(&chunk.stream_id); } - } else if let Some(text_updater) = locked_text_streams.get(&stream_id) { - let _ = text_updater.send_update(data_streams::DataStreamChunk { - stream_id: stream_id.clone(), - chunk_index, - content, - complete, - version, - }); + } else if let Some(text_updater) = locked_text_streams.get(&chunk.stream_id) { + let _ = text_updater.send_update(chunk.clone()); - if complete { - let _ = locked_text_streams.remove(&stream_id); + if chunk.complete { + let _ = locked_text_streams.remove(&chunk.stream_id); } } } diff --git a/livekit/src/rtc_engine/mod.rs b/livekit/src/rtc_engine/mod.rs index 18a6ff2b..49f8070b 100644 --- a/livekit/src/rtc_engine/mod.rs +++ b/livekit/src/rtc_engine/mod.rs @@ -16,8 +16,8 @@ use std::{borrow::Cow, fmt::Debug, sync::Arc, time::Duration}; use libwebrtc::prelude::*; use livekit_api::signal_client::{SignalError, SignalOptions}; -use livekit_protocol as proto; use livekit_protocol::data_stream::header::ContentHeader; +use livekit_protocol::{self as proto, data_stream}; use livekit_runtime::{interval, Interval, JoinHandle}; use parking_lot::{RwLock, RwLockReadGuard}; use thiserror::Error; @@ -29,6 +29,7 @@ use tokio::sync::{ pub use self::rtc_session::SessionStats; use crate::prelude::ParticipantIdentity; use crate::{ + data_streams, id::ParticipantSid, options::TrackPublishOptions, prelude::LocalTrack, @@ -170,11 +171,7 @@ pub enum EngineEvent { content_header: Option, }, DataStreamChunk { - stream_id: String, - chunk_index: u64, - content: Vec, - complete: bool, - version: i32, + chunk: proto::data_stream::Chunk, }, } @@ -560,20 +557,8 @@ impl EngineInner { content_header, }); } - SessionEvent::DataStreamChunk { - stream_id, - chunk_index, - content, - complete, - version, - } => { - let _ = self.engine_tx.send(EngineEvent::DataStreamChunk { - stream_id, - chunk_index, - content, - complete, - version, - }); + SessionEvent::DataStreamChunk { chunk } => { + let _ = self.engine_tx.send(EngineEvent::DataStreamChunk { chunk }); } } Ok(()) diff --git a/livekit/src/rtc_engine/rtc_session.rs b/livekit/src/rtc_engine/rtc_session.rs index 841e0af5..f0228d19 100644 --- a/livekit/src/rtc_engine/rtc_session.rs +++ b/livekit/src/rtc_engine/rtc_session.rs @@ -145,11 +145,7 @@ pub enum SessionEvent { content_header: Option, }, DataStreamChunk { - stream_id: String, - chunk_index: u64, - content: Vec, - complete: bool, - version: i32, + chunk: proto::data_stream::Chunk, }, } @@ -751,13 +747,9 @@ impl SessionInner { }); } proto::data_packet::Value::StreamChunk(message) => { - let _ = self.emitter.send(SessionEvent::DataStreamChunk { - stream_id: message.stream_id.clone(), - chunk_index: message.chunk_index.clone(), - content: message.content.clone(), - complete: message.complete.clone(), - version: message.version.clone(), - }); + let _ = self + .emitter + .send(SessionEvent::DataStreamChunk { chunk: message.clone() }); } _ => {} } From a651795237da9ce869f034493440d029b034888a Mon Sep 17 00:00:00 2001 From: lukasIO Date: Thu, 12 Dec 2024 15:34:44 +0100 Subject: [PATCH 11/18] better lock scope --- livekit/src/room/data_streams/mod.rs | 18 ++++-- livekit/src/room/mod.rs | 86 ++++++++++----------------- livekit/src/rtc_engine/mod.rs | 28 +-------- livekit/src/rtc_engine/rtc_session.rs | 20 ++----- 4 files changed, 53 insertions(+), 99 deletions(-) diff --git a/livekit/src/room/data_streams/mod.rs b/livekit/src/room/data_streams/mod.rs index c77638f2..2dae7446 100644 --- a/livekit/src/room/data_streams/mod.rs +++ b/livekit/src/room/data_streams/mod.rs @@ -49,7 +49,6 @@ impl FileStreamReader { fn close(&mut self) { self.is_closed = true; - self.update_rx.lock().close(); } } @@ -64,6 +63,7 @@ impl Stream for FileStreamReader { fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { if self.is_closed { + self.update_rx.lock().close(); return Poll::Ready(None); // Stream is closed‚, stop yielding updates } let update_option = { @@ -81,7 +81,15 @@ impl Stream for FileStreamReader { } } Poll::Ready(None) => Poll::Ready(None), - Poll::Pending => Poll::Pending, + Poll::Pending => { + if self.is_closed { + log::debug!("closing pending update"); + self.update_rx.lock().close(); + Poll::Ready(None) + } else { + Poll::Pending + } + } } } } @@ -198,7 +206,7 @@ impl Stream for TextStreamReader { collected, })) } - Poll::Ready(None) => Poll::Pending, + Poll::Ready(None) => Poll::Ready(None), Poll::Pending => { if self.is_closed { log::debug!("closing pending update"); @@ -212,13 +220,13 @@ impl Stream for TextStreamReader { } } -/// Helper to send updates to the `FileStream`. +/// Helper to send updates to the `TextStream`. pub struct TextStreamUpdater { update_tx: mpsc::UnboundedSender, } impl TextStreamUpdater { - /// Sends an update to the `FileStream`. + /// Sends an update to the `TextStream``. pub fn send_update(&self, data: Chunk) -> Result<(), mpsc::error::SendError> { self.update_tx.send(data) } diff --git a/livekit/src/room/mod.rs b/livekit/src/room/mod.rs index 0ef8bcd7..671b3bad 100644 --- a/livekit/src/room/mod.rs +++ b/livekit/src/room/mod.rs @@ -728,24 +728,8 @@ impl RoomSession { EngineEvent::LocalTrackSubscribed { track_sid } => { self.handle_track_subscribed(track_sid) } - EngineEvent::DataStreamHeader { - stream_id, - timestamp, - topic, - mime_type, - total_length, - total_chunks, - content_header, - } => { - self.handle_data_stream_header( - stream_id, - timestamp, - topic, - mime_type, - total_length, - total_chunks, - content_header, - ); + EngineEvent::DataStreamHeader { header } => { + self.handle_data_stream_header(header); } EngineEvent::DataStreamChunk { chunk } => { self.handle_data_stream_chunk(chunk); @@ -1259,26 +1243,17 @@ impl RoomSession { }); } - fn handle_data_stream_header( - &self, - stream_id: String, - timestamp: i64, - topic: String, - mime_type: String, - total_length: Option, - total_chunks: Option, - content_header: Option, - ) { - match content_header.unwrap() { + fn handle_data_stream_header(&self, header: proto::data_stream::Header) { + match header.content_header.unwrap() { ContentHeader::TextHeader(text_header) => { let (stream_reader, updater) = data_streams::TextStreamReader::new(data_streams::TextStreamInfo { - stream_id, - timestamp, - topic, - mime_type, - total_length, - total_chunks, + stream_id: header.stream_id, + timestamp: header.timestamp, + topic: header.topic, + mime_type: header.mime_type, + total_length: header.total_length, + total_chunks: header.total_chunks, attachments: text_header.attached_stream_ids, version: text_header.version, }); @@ -1291,12 +1266,12 @@ impl RoomSession { ContentHeader::FileHeader(file_header) => { let (stream_reader, updater) = data_streams::FileStreamReader::new(data_streams::FileStreamInfo { - stream_id, - timestamp, - topic, - mime_type, - total_length, - total_chunks, + stream_id: header.stream_id, + timestamp: header.timestamp, + topic: header.topic, + mime_type: header.mime_type, + total_length: header.total_length, + total_chunks: header.total_chunks, file_name: file_header.file_name, }); @@ -1309,19 +1284,24 @@ impl RoomSession { } fn handle_data_stream_chunk(&self, chunk: proto::data_stream::Chunk) { - let mut locked_file_streams = self.file_streams.write(); - let mut locked_text_streams = self.text_streams.write(); - if let Some(file_updater) = locked_file_streams.get(&chunk.stream_id) { - let _ = file_updater.send_update(chunk.clone()); - - if chunk.complete { - let _ = locked_file_streams.remove(&chunk.stream_id); + let is_file_stream = self.file_streams.read().contains_key(&chunk.stream_id); + let is_text_stream = self.text_streams.read().contains_key(&chunk.stream_id); + + if is_file_stream { + let mut locked_file_streams = self.file_streams.write(); + if let Some(file_updater) = locked_file_streams.get(&chunk.stream_id) { + let _ = file_updater.send_update(chunk.clone()); + if chunk.complete { + let _ = locked_file_streams.remove(&chunk.stream_id); + } } - } else if let Some(text_updater) = locked_text_streams.get(&chunk.stream_id) { - let _ = text_updater.send_update(chunk.clone()); - - if chunk.complete { - let _ = locked_text_streams.remove(&chunk.stream_id); + } else if is_text_stream { + let mut locked_text_streams = self.text_streams.write(); + if let Some(text_updater) = locked_text_streams.get(&chunk.stream_id) { + let _ = text_updater.send_update(chunk.clone()); + if chunk.complete { + let _ = locked_text_streams.remove(&chunk.stream_id); + } } } } diff --git a/livekit/src/rtc_engine/mod.rs b/livekit/src/rtc_engine/mod.rs index 49f8070b..842eadbc 100644 --- a/livekit/src/rtc_engine/mod.rs +++ b/livekit/src/rtc_engine/mod.rs @@ -162,13 +162,7 @@ pub enum EngineEvent { track_sid: String, }, DataStreamHeader { - stream_id: String, - timestamp: i64, - topic: String, - mime_type: String, - total_length: Option, - total_chunks: Option, - content_header: Option, + header: proto::data_stream::Header, }, DataStreamChunk { chunk: proto::data_stream::Chunk, @@ -538,24 +532,8 @@ impl EngineInner { SessionEvent::LocalTrackSubscribed { track_sid } => { let _ = self.engine_tx.send(EngineEvent::LocalTrackSubscribed { track_sid }); } - SessionEvent::DataStreamHeader { - stream_id, - timestamp, - topic, - mime_type, - total_length, - total_chunks, - content_header, - } => { - let _ = self.engine_tx.send(EngineEvent::DataStreamHeader { - stream_id, - timestamp, - topic, - mime_type, - total_length, - total_chunks, - content_header, - }); + SessionEvent::DataStreamHeader { header } => { + let _ = self.engine_tx.send(EngineEvent::DataStreamHeader { header }); } SessionEvent::DataStreamChunk { chunk } => { let _ = self.engine_tx.send(EngineEvent::DataStreamChunk { chunk }); diff --git a/livekit/src/rtc_engine/rtc_session.rs b/livekit/src/rtc_engine/rtc_session.rs index f0228d19..357ecb4d 100644 --- a/livekit/src/rtc_engine/rtc_session.rs +++ b/livekit/src/rtc_engine/rtc_session.rs @@ -136,13 +136,7 @@ pub enum SessionEvent { retry_now: bool, }, DataStreamHeader { - stream_id: String, - timestamp: i64, - topic: String, - mime_type: String, - total_length: Option, - total_chunks: Option, - content_header: Option, + header: proto::data_stream::Header, }, DataStreamChunk { chunk: proto::data_stream::Chunk, @@ -736,15 +730,9 @@ impl SessionInner { }); } proto::data_packet::Value::StreamHeader(message) => { - let _ = self.emitter.send(SessionEvent::DataStreamHeader { - stream_id: message.stream_id.clone(), - timestamp: message.timestamp.clone(), - topic: message.topic.clone(), - mime_type: message.mime_type.clone(), - total_length: message.total_length.clone(), - total_chunks: message.total_chunks.clone(), - content_header: message.content_header.clone(), - }); + let _ = self + .emitter + .send(SessionEvent::DataStreamHeader { header: message.clone() }); } proto::data_packet::Value::StreamChunk(message) => { let _ = self From 8be1cdba7ca447ccd6dfdd027c2c71b8535a472c Mon Sep 17 00:00:00 2001 From: lukasIO Date: Thu, 12 Dec 2024 15:54:06 +0100 Subject: [PATCH 12/18] filestream fixes --- livekit/src/room/mod.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/livekit/src/room/mod.rs b/livekit/src/room/mod.rs index 671b3bad..12481231 100644 --- a/livekit/src/room/mod.rs +++ b/livekit/src/room/mod.rs @@ -1294,6 +1294,7 @@ impl RoomSession { if chunk.complete { let _ = locked_file_streams.remove(&chunk.stream_id); } + return; } } else if is_text_stream { let mut locked_text_streams = self.text_streams.write(); @@ -1302,8 +1303,13 @@ impl RoomSession { if chunk.complete { let _ = locked_text_streams.remove(&chunk.stream_id); } + return; } } + log::warn!( + "could not find matching stream header for incoming chunks, stream_id: {:?}", + chunk.stream_id + ) } /// Create a new participant From cfea22136ac356c1e85f8709c7a6eb76e8a5c641 Mon Sep 17 00:00:00 2001 From: lukasIO Date: Thu, 12 Dec 2024 16:33:18 +0100 Subject: [PATCH 13/18] add example --- examples/data_streams/Cargo.toml | 13 ++++++ examples/data_streams/src/main.rs | 73 +++++++++++++++++++++++++++++++ 2 files changed, 86 insertions(+) create mode 100644 examples/data_streams/Cargo.toml create mode 100644 examples/data_streams/src/main.rs diff --git a/examples/data_streams/Cargo.toml b/examples/data_streams/Cargo.toml new file mode 100644 index 00000000..7247a695 --- /dev/null +++ b/examples/data_streams/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "data_streams" +version = "0.1.0" +edition = "2021" + +[dependencies] +tokio = { version = "1", features = ["full", "parking_lot"] } +futures = "0.3" +parking_lot = { version = "0.12.1", features = ["deadlock_detection"] } +env_logger = "0.10" +livekit = { path = "../../livekit", features = ["native-tls"] } +livekit-api = { path = "../../livekit-api" } +log = "0.4" diff --git a/examples/data_streams/src/main.rs b/examples/data_streams/src/main.rs new file mode 100644 index 00000000..149c7f1e --- /dev/null +++ b/examples/data_streams/src/main.rs @@ -0,0 +1,73 @@ +use futures::StreamExt; +use livekit::prelude::*; +use livekit_api::access_token; +use std::env; + +// Connect to a room using the specified env variables +// and read data streams + +#[tokio::main] +async fn main() { + env_logger::init(); + + let url = env::var("LIVEKIT_URL").expect("LIVEKIT_URL is not set"); + let api_key = env::var("LIVEKIT_API_KEY").expect("LIVEKIT_API_KEY is not set"); + let api_secret = env::var("LIVEKIT_API_SECRET").expect("LIVEKIT_API_SECRET is not set"); + + let token = access_token::AccessToken::with_api_key(&api_key, &api_secret) + .with_identity("rust-bot") + .with_name("Rust Bot") + .with_grants(access_token::VideoGrants { + room_join: true, + room: "dev".to_string(), + ..Default::default() + }) + .to_jwt() + .unwrap(); + + log::info!("Connecting to room"); + let (room, mut rx) = Room::connect(&url, &token, RoomOptions::default()).await.unwrap(); + log::info!("Connected to room: {}", room.name()); + + room.local_participant() + .publish_data(DataPacket { + payload: "Hello world".to_owned().into_bytes(), + reliable: true, + ..Default::default() + }) + .await + .unwrap(); + + while let Some(msg) = rx.recv().await { + match msg { + RoomEvent::TextStreamReceived { mut stream_reader } => { + log::info!("TextStreamReceived: {:?}", stream_reader.info.stream_id); + + tokio::spawn(async move { + let mut collected = String::new(); + while let Some(chunk) = stream_reader.next().await { + log::info!("received text frame - {:?}", chunk.current); + collected = chunk.collected; + } + log::info!("finished reading text stream: {:?}", collected); + }); + } + RoomEvent::FileStreamReceived { mut stream_reader } => { + log::info!("FileStreamReceived: {:?}", stream_reader.info.stream_id); + + tokio::spawn(async move { + let file_name = stream_reader.info.file_name.clone(); + let mut data: Vec = vec![]; + while let Some(mut chunk) = stream_reader.next().await { + data.append(&mut chunk); + } + log::info!("finished reading file stream, now writing to disk"); + std::fs::write(file_name, data).unwrap(); + }); + } + other => { + log::debug!("Event: {:?}", other); + } + } + } +} From 6baf0336408265cf6309dcba666cbf2615e83b8f Mon Sep 17 00:00:00 2001 From: lukasIO Date: Mon, 16 Dec 2024 12:03:15 +0100 Subject: [PATCH 14/18] remove rust client api and replace with raw events --- examples/data_streams/Cargo.toml | 13 -- examples/data_streams/src/main.rs | 73 --------- livekit/src/room/data_streams/mod.rs | 233 --------------------------- livekit/src/room/mod.rs | 82 ++-------- livekit/src/rtc_engine/mod.rs | 1 - 5 files changed, 9 insertions(+), 393 deletions(-) delete mode 100644 examples/data_streams/Cargo.toml delete mode 100644 examples/data_streams/src/main.rs delete mode 100644 livekit/src/room/data_streams/mod.rs diff --git a/examples/data_streams/Cargo.toml b/examples/data_streams/Cargo.toml deleted file mode 100644 index 7247a695..00000000 --- a/examples/data_streams/Cargo.toml +++ /dev/null @@ -1,13 +0,0 @@ -[package] -name = "data_streams" -version = "0.1.0" -edition = "2021" - -[dependencies] -tokio = { version = "1", features = ["full", "parking_lot"] } -futures = "0.3" -parking_lot = { version = "0.12.1", features = ["deadlock_detection"] } -env_logger = "0.10" -livekit = { path = "../../livekit", features = ["native-tls"] } -livekit-api = { path = "../../livekit-api" } -log = "0.4" diff --git a/examples/data_streams/src/main.rs b/examples/data_streams/src/main.rs deleted file mode 100644 index 149c7f1e..00000000 --- a/examples/data_streams/src/main.rs +++ /dev/null @@ -1,73 +0,0 @@ -use futures::StreamExt; -use livekit::prelude::*; -use livekit_api::access_token; -use std::env; - -// Connect to a room using the specified env variables -// and read data streams - -#[tokio::main] -async fn main() { - env_logger::init(); - - let url = env::var("LIVEKIT_URL").expect("LIVEKIT_URL is not set"); - let api_key = env::var("LIVEKIT_API_KEY").expect("LIVEKIT_API_KEY is not set"); - let api_secret = env::var("LIVEKIT_API_SECRET").expect("LIVEKIT_API_SECRET is not set"); - - let token = access_token::AccessToken::with_api_key(&api_key, &api_secret) - .with_identity("rust-bot") - .with_name("Rust Bot") - .with_grants(access_token::VideoGrants { - room_join: true, - room: "dev".to_string(), - ..Default::default() - }) - .to_jwt() - .unwrap(); - - log::info!("Connecting to room"); - let (room, mut rx) = Room::connect(&url, &token, RoomOptions::default()).await.unwrap(); - log::info!("Connected to room: {}", room.name()); - - room.local_participant() - .publish_data(DataPacket { - payload: "Hello world".to_owned().into_bytes(), - reliable: true, - ..Default::default() - }) - .await - .unwrap(); - - while let Some(msg) = rx.recv().await { - match msg { - RoomEvent::TextStreamReceived { mut stream_reader } => { - log::info!("TextStreamReceived: {:?}", stream_reader.info.stream_id); - - tokio::spawn(async move { - let mut collected = String::new(); - while let Some(chunk) = stream_reader.next().await { - log::info!("received text frame - {:?}", chunk.current); - collected = chunk.collected; - } - log::info!("finished reading text stream: {:?}", collected); - }); - } - RoomEvent::FileStreamReceived { mut stream_reader } => { - log::info!("FileStreamReceived: {:?}", stream_reader.info.stream_id); - - tokio::spawn(async move { - let file_name = stream_reader.info.file_name.clone(); - let mut data: Vec = vec![]; - while let Some(mut chunk) = stream_reader.next().await { - data.append(&mut chunk); - } - log::info!("finished reading file stream, now writing to disk"); - std::fs::write(file_name, data).unwrap(); - }); - } - other => { - log::debug!("Event: {:?}", other); - } - } - } -} diff --git a/livekit/src/room/data_streams/mod.rs b/livekit/src/room/data_streams/mod.rs deleted file mode 100644 index 2dae7446..00000000 --- a/livekit/src/room/data_streams/mod.rs +++ /dev/null @@ -1,233 +0,0 @@ -use std::{ - collections::BTreeMap, - pin::Pin, - sync::Arc, - task::{Context, Poll}, -}; - -use itertools::Itertools; -use livekit_runtime::Stream; -use parking_lot::Mutex; -use tokio::sync::mpsc; - -use livekit_protocol::data_stream::Chunk; - -// #[derive(Debug, Clone)] -// pub struct DataStreamChunk { -// pub stream_id: String, -// pub chunk_index: u64, -// pub content: Vec, -// pub complete: bool, -// pub version: i32, -// } - -#[derive(Debug, Clone)] -pub struct FileStreamInfo { - pub stream_id: String, - pub timestamp: i64, - pub topic: String, - pub mime_type: String, - pub total_length: Option, - pub total_chunks: Option, - pub file_name: String, -} -#[derive(Debug, Clone)] -pub struct FileStreamReader { - update_rx: Arc>>, - pub info: FileStreamInfo, - is_closed: bool, -} - -impl FileStreamReader { - pub fn new(info: FileStreamInfo) -> (Self, FileStreamUpdater) { - let (update_tx, update_rx) = mpsc::unbounded_channel(); - ( - Self { update_rx: Arc::new(Mutex::new(update_rx)), info, is_closed: false }, - FileStreamUpdater { update_tx }, - ) - } - - fn close(&mut self) { - self.is_closed = true; - } -} - -impl Drop for FileStreamReader { - fn drop(&mut self) { - self.close(); - } -} - -impl Stream for FileStreamReader { - type Item = Vec; - - fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { - if self.is_closed { - self.update_rx.lock().close(); - return Poll::Ready(None); // Stream is closed‚, stop yielding updates - } - let update_option = { - let mut guarded = self.update_rx.lock(); - guarded.poll_recv(cx) - }; - - match update_option { - Poll::Ready(Some(update)) => { - if update.complete { - self.close(); - Poll::Ready(None) // Close stream after receiving a complete update - } else { - Poll::Ready(Some(update.content)) // Continue with data updates - } - } - Poll::Ready(None) => Poll::Ready(None), - Poll::Pending => { - if self.is_closed { - log::debug!("closing pending update"); - self.update_rx.lock().close(); - Poll::Ready(None) - } else { - Poll::Pending - } - } - } - } -} - -/// Helper to send updates to the `FileStream`. -pub struct FileStreamUpdater { - update_tx: mpsc::UnboundedSender, -} - -impl FileStreamUpdater { - /// Sends an update to the `FileStream`. - pub fn send_update(&self, data: Chunk) -> Result<(), mpsc::error::SendError> { - self.update_tx.send(data) - } -} - -#[derive(Debug, Clone)] -pub struct TextStreamInfo { - pub stream_id: String, - pub timestamp: i64, - pub topic: String, - pub mime_type: String, - pub total_length: Option, - pub total_chunks: Option, - pub attachments: Vec, - pub version: i32, -} - -#[derive(Debug, Clone)] -pub struct TextStreamChunk { - pub collected: String, - pub current: String, - pub index: u64, -} -#[derive(Debug, Clone)] -pub struct TextStreamReader { - update_rx: Arc>>, - pub info: TextStreamInfo, - is_closed: bool, - chunks: BTreeMap, -} - -impl TextStreamReader { - pub fn new(info: TextStreamInfo) -> (Self, TextStreamUpdater) { - let (update_tx, update_rx) = mpsc::unbounded_channel(); - ( - Self { - update_rx: Arc::new(Mutex::new(update_rx)), - info, - is_closed: false, - chunks: BTreeMap::new(), - }, - TextStreamUpdater { update_tx }, - ) - } - - fn close(&mut self) { - self.is_closed = true; - self.chunks.clear(); - } -} - -impl Drop for TextStreamReader { - fn drop(&mut self) { - self.close(); - } -} - -impl Stream for TextStreamReader { - type Item = TextStreamChunk; - - fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { - if self.is_closed { - self.update_rx.lock().close(); - return Poll::Ready(None); // Stream is closed‚, stop yielding updates - } - - let update_option = { - let mut guarded = self.update_rx.lock(); - guarded.poll_recv(cx) - }; - - match update_option { - Poll::Ready(Some(update)) => { - let update_clone = update.clone(); - let chunk_index = update.chunk_index; - let content = update.content.clone(); - - // Check for existing chunk version - if let Some(existing_chunk) = self.chunks.get(&chunk_index) { - if existing_chunk.version > update.version { - return Poll::Pending; - } - } - // Insert new chunk after immutable access - self.chunks.insert(chunk_index, update_clone); - - if update.complete { - log::debug!("closing stream as it's complete"); - self.update_rx.lock().close(); - return Poll::Ready(None); - } - - // Collect chunks - let collected = self - .chunks - .values() - .map(|chunk| String::from_utf8(chunk.content.clone()).unwrap()) - .join(""); - - Poll::Ready(Some(TextStreamChunk { - index: chunk_index, - current: String::from_utf8(content).unwrap(), - collected, - })) - } - Poll::Ready(None) => Poll::Ready(None), - Poll::Pending => { - if self.is_closed { - log::debug!("closing pending update"); - self.update_rx.lock().close(); - Poll::Ready(None) - } else { - Poll::Pending - } - } - } - } -} - -/// Helper to send updates to the `TextStream`. -pub struct TextStreamUpdater { - update_tx: mpsc::UnboundedSender, -} - -impl TextStreamUpdater { - /// Sends an update to the `TextStream``. - pub fn send_update(&self, data: Chunk) -> Result<(), mpsc::error::SendError> { - self.update_tx.send(data) - } -} diff --git a/livekit/src/room/mod.rs b/livekit/src/room/mod.rs index 12481231..19517508 100644 --- a/livekit/src/room/mod.rs +++ b/livekit/src/room/mod.rs @@ -25,7 +25,7 @@ use libwebrtc::{ }; use livekit_api::signal_client::{SignalOptions, SignalSdkOptions}; use livekit_protocol::observer::Dispatcher; -use livekit_protocol::{self as proto, data_stream::header::ContentHeader}; +use livekit_protocol::{self as proto}; use livekit_runtime::JoinHandle; use parking_lot::RwLock; pub use proto::DisconnectReason; @@ -47,7 +47,6 @@ use crate::{ }, }; -pub mod data_streams; pub mod e2ee; pub mod id; pub mod options; @@ -169,11 +168,11 @@ pub enum RoomEvent { message: ChatMessage, participant: Option, }, - TextStreamReceived { - stream_reader: data_streams::TextStreamReader, + StreamHeaderReceived { + header: proto::data_stream::Header, }, - FileStreamReceived { - stream_reader: data_streams::FileStreamReader, + StreamChunkReceived { + chunk: proto::data_stream::Chunk, }, E2eeStateChanged { participant: Participant, @@ -369,8 +368,6 @@ pub(crate) struct RoomSession { remote_participants: RwLock>, e2ee_manager: E2eeManager, room_task: AsyncMutex, oneshot::Sender<()>)>>, - file_streams: RwLock>, - text_streams: RwLock>, } impl Debug for RoomSession { @@ -512,8 +509,6 @@ impl Room { dispatcher: dispatcher.clone(), e2ee_manager: e2ee_manager.clone(), room_task: Default::default(), - file_streams: RwLock::new(HashMap::new()), - text_streams: RwLock::new(HashMap::new()), }); e2ee_manager.on_state_changed({ @@ -1244,72 +1239,13 @@ impl RoomSession { } fn handle_data_stream_header(&self, header: proto::data_stream::Header) { - match header.content_header.unwrap() { - ContentHeader::TextHeader(text_header) => { - let (stream_reader, updater) = - data_streams::TextStreamReader::new(data_streams::TextStreamInfo { - stream_id: header.stream_id, - timestamp: header.timestamp, - topic: header.topic, - mime_type: header.mime_type, - total_length: header.total_length, - total_chunks: header.total_chunks, - attachments: text_header.attached_stream_ids, - version: text_header.version, - }); - - self.text_streams.write().insert(stream_reader.info.stream_id.clone(), updater); - - let event = RoomEvent::TextStreamReceived { stream_reader }; - self.dispatcher.dispatch(&event); - } - ContentHeader::FileHeader(file_header) => { - let (stream_reader, updater) = - data_streams::FileStreamReader::new(data_streams::FileStreamInfo { - stream_id: header.stream_id, - timestamp: header.timestamp, - topic: header.topic, - mime_type: header.mime_type, - total_length: header.total_length, - total_chunks: header.total_chunks, - file_name: file_header.file_name, - }); - - self.file_streams.write().insert(stream_reader.info.stream_id.clone(), updater); - - let event = RoomEvent::FileStreamReceived { stream_reader }; - self.dispatcher.dispatch(&event); - } - } + let event = RoomEvent::StreamHeaderReceived { header }; + self.dispatcher.dispatch(&event); } fn handle_data_stream_chunk(&self, chunk: proto::data_stream::Chunk) { - let is_file_stream = self.file_streams.read().contains_key(&chunk.stream_id); - let is_text_stream = self.text_streams.read().contains_key(&chunk.stream_id); - - if is_file_stream { - let mut locked_file_streams = self.file_streams.write(); - if let Some(file_updater) = locked_file_streams.get(&chunk.stream_id) { - let _ = file_updater.send_update(chunk.clone()); - if chunk.complete { - let _ = locked_file_streams.remove(&chunk.stream_id); - } - return; - } - } else if is_text_stream { - let mut locked_text_streams = self.text_streams.write(); - if let Some(text_updater) = locked_text_streams.get(&chunk.stream_id) { - let _ = text_updater.send_update(chunk.clone()); - if chunk.complete { - let _ = locked_text_streams.remove(&chunk.stream_id); - } - return; - } - } - log::warn!( - "could not find matching stream header for incoming chunks, stream_id: {:?}", - chunk.stream_id - ) + let event = RoomEvent::StreamChunkReceived { chunk }; + self.dispatcher.dispatch(&event); } /// Create a new participant diff --git a/livekit/src/rtc_engine/mod.rs b/livekit/src/rtc_engine/mod.rs index 842eadbc..04d9ab4e 100644 --- a/livekit/src/rtc_engine/mod.rs +++ b/livekit/src/rtc_engine/mod.rs @@ -29,7 +29,6 @@ use tokio::sync::{ pub use self::rtc_session::SessionStats; use crate::prelude::ParticipantIdentity; use crate::{ - data_streams, id::ParticipantSid, options::TrackPublishOptions, prelude::LocalTrack, From c189b29182cc50624091187abe3bd93885f9b453 Mon Sep 17 00:00:00 2001 From: lukasIO Date: Mon, 16 Dec 2024 12:06:45 +0100 Subject: [PATCH 15/18] cleanup imports --- livekit/src/room/mod.rs | 2 +- livekit/src/rtc_engine/mod.rs | 3 +-- livekit/src/rtc_engine/rtc_session.rs | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/livekit/src/room/mod.rs b/livekit/src/room/mod.rs index 19517508..440d1964 100644 --- a/livekit/src/room/mod.rs +++ b/livekit/src/room/mod.rs @@ -24,8 +24,8 @@ use libwebrtc::{ RtcError, }; use livekit_api::signal_client::{SignalOptions, SignalSdkOptions}; +use livekit_protocol as proto; use livekit_protocol::observer::Dispatcher; -use livekit_protocol::{self as proto}; use livekit_runtime::JoinHandle; use parking_lot::RwLock; pub use proto::DisconnectReason; diff --git a/livekit/src/rtc_engine/mod.rs b/livekit/src/rtc_engine/mod.rs index 04d9ab4e..d4f5dec9 100644 --- a/livekit/src/rtc_engine/mod.rs +++ b/livekit/src/rtc_engine/mod.rs @@ -16,8 +16,7 @@ use std::{borrow::Cow, fmt::Debug, sync::Arc, time::Duration}; use libwebrtc::prelude::*; use livekit_api::signal_client::{SignalError, SignalOptions}; -use livekit_protocol::data_stream::header::ContentHeader; -use livekit_protocol::{self as proto, data_stream}; +use livekit_protocol as proto; use livekit_runtime::{interval, Interval, JoinHandle}; use parking_lot::{RwLock, RwLockReadGuard}; use thiserror::Error; diff --git a/livekit/src/rtc_engine/rtc_session.rs b/livekit/src/rtc_engine/rtc_session.rs index 357ecb4d..e8309ac1 100644 --- a/livekit/src/rtc_engine/rtc_session.rs +++ b/livekit/src/rtc_engine/rtc_session.rs @@ -26,7 +26,7 @@ use std::{ use libwebrtc::{prelude::*, stats::RtcStats}; use livekit_api::signal_client::{SignalClient, SignalEvent, SignalEvents}; -use livekit_protocol::{self as proto, data_stream::header::ContentHeader, Encryption}; +use livekit_protocol as proto; use livekit_runtime::{sleep, JoinHandle}; use parking_lot::Mutex; use prost::Message; From dbf1a160eed9c3c2c959d15bdbbb869320b7eb6c Mon Sep 17 00:00:00 2001 From: lukasIO Date: Mon, 16 Dec 2024 12:10:55 +0100 Subject: [PATCH 16/18] more cleanup --- Cargo.lock | 10 ---------- livekit-api/src/services/sip.rs | 3 --- livekit/Cargo.toml | 1 - livekit/src/room/mod.rs | 2 +- 4 files changed, 1 insertion(+), 15 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 88d0c3d0..d907dc78 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1423,15 +1423,6 @@ dependencies = [ "waker-fn", ] -[[package]] -name = "itertools" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f56a2d0bc861f9165be4eb3442afd3c236d8a98afd426f65d92324ae1091a484" -dependencies = [ - "either", -] - [[package]] name = "itertools" version = "0.10.5" @@ -1608,7 +1599,6 @@ version = "0.7.0" dependencies = [ "chrono", "futures-util", - "itertools 0.8.2", "lazy_static", "libwebrtc", "livekit-api", diff --git a/livekit-api/src/services/sip.rs b/livekit-api/src/services/sip.rs index 1efd5929..39b67d1d 100644 --- a/livekit-api/src/services/sip.rs +++ b/livekit-api/src/services/sip.rs @@ -129,9 +129,6 @@ pub struct CreateSIPParticipantOptions { /// Optionally play ringtone in the room as an audible indicator for existing participants pub play_ringtone: bool, pub hide_phone_number: bool, - pub enable_krisp: bool, - pub max_call_duration: i32, - pub play_dialtone: bool, } impl SIPClient { diff --git a/livekit/Cargo.toml b/livekit/Cargo.toml index 7609e51a..29113321 100644 --- a/livekit/Cargo.toml +++ b/livekit/Cargo.toml @@ -42,4 +42,3 @@ lazy_static = "1.4" log = "0.4" chrono = "0.4.38" semver = "1.0" -itertools = "0.8" diff --git a/livekit/src/room/mod.rs b/livekit/src/room/mod.rs index 440d1964..c9177c97 100644 --- a/livekit/src/room/mod.rs +++ b/livekit/src/room/mod.rs @@ -657,7 +657,7 @@ impl RoomSession { log::debug!("room_task closed"); } - async fn on_engine_event(self: Arc, event: EngineEvent) -> RoomResult<()> { + async fn on_engine_event(self: &Arc, event: EngineEvent) -> RoomResult<()> { match event { EngineEvent::ParticipantUpdate { updates } => self.handle_participant_update(updates), EngineEvent::MediaTrack { track, stream, transceiver } => { From c00e161c1c45c2db05a940a58380d65bd6378b81 Mon Sep 17 00:00:00 2001 From: lukasIO Date: Mon, 16 Dec 2024 12:12:32 +0100 Subject: [PATCH 17/18] ffi imports --- livekit-ffi/src/conversion/room.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/livekit-ffi/src/conversion/room.rs b/livekit-ffi/src/conversion/room.rs index 0e2c65c4..c2d04916 100644 --- a/livekit-ffi/src/conversion/room.rs +++ b/livekit-ffi/src/conversion/room.rs @@ -12,10 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::{ - proto::{self, DisposeCallback}, - server::room::FfiRoom, -}; +use crate::{proto, server::room::FfiRoom}; use livekit::{ e2ee::{ key_provider::{KeyProvider, KeyProviderOptions}, From 0fbb49ac7ddc6c895406b61d70f682894872f48c Mon Sep 17 00:00:00 2001 From: lukasIO Date: Mon, 16 Dec 2024 13:39:33 +0100 Subject: [PATCH 18/18] implement ffi --- livekit-ffi/protocol/room.proto | 54 ++++++++++++ livekit-ffi/src/conversion/room.rs | 48 +++++++++++ livekit-ffi/src/livekit.proto.rs | 133 ++++++++++++++++++++++++++++- livekit-ffi/src/server/room.rs | 6 ++ 4 files changed, 240 insertions(+), 1 deletion(-) diff --git a/livekit-ffi/protocol/room.proto b/livekit-ffi/protocol/room.proto index 4a131226..6e4043f2 100644 --- a/livekit-ffi/protocol/room.proto +++ b/livekit-ffi/protocol/room.proto @@ -397,6 +397,8 @@ message RoomEvent { DataPacketReceived data_packet_received = 27; TranscriptionReceived transcription_received = 28; ChatMessageReceived chat_message = 29; + DataStream.Header stream_header = 30; + DataStream.Chunk stream_chunk = 31; } } @@ -556,3 +558,55 @@ message Reconnected {} message RoomEOS {} +message DataStream { + + // enum for operation types (specific to TextHeader) + enum OperationType { + CREATE = 0; + UPDATE = 1; + DELETE = 2; + REACTION = 3; + } + + // header properties specific to text streams + message TextHeader { + required OperationType operation_type = 1; + required int32 version = 2; // Optional: Version for updates/edits + required string reply_to_stream_id = 3; // Optional: Reply to specific message + repeated string attached_stream_ids = 4; // file attachments for text streams + required bool generated = 5; // true if the text has been generated by an agent from a participant's audio transcription + + } + + // header properties specific to file or image streams + message FileHeader { + required string file_name = 1; // name of the file + } + + // main DataStream.Header that contains a oneof for specific headers + message Header { + required string stream_id = 1; // unique identifier for this data stream + required int64 timestamp = 2; // using int64 for Unix timestamp + required string topic = 3; + required string mime_type = 4; + optional uint64 total_length = 5; // only populated for finite streams, if it's a stream of unknown size this stays empty + optional uint64 total_chunks = 6; // only populated for finite streams, if it's a stream of unknown size this stays empty + map extensions = 7; // user defined extensions map that can carry additional info + + // oneof to choose between specific header types + oneof content_header { + TextHeader text_header = 8; + FileHeader file_header = 9; + } + } + + message Chunk { + required string stream_id = 1; // unique identifier for this data stream to map it to the correct header + required uint64 chunk_index = 2; + required bytes content = 3; // content as binary (bytes) + required bool complete = 4; // true only if this is the last chunk of this stream - can also be sent with empty content + required int32 version = 5; // a version indicating that this chunk_index has been retroactively modified and the original one needs to be replaced + optional bytes iv = 6; // optional, initialization vector for AES-GCM encryption + } +} + diff --git a/livekit-ffi/src/conversion/room.rs b/livekit-ffi/src/conversion/room.rs index c2d04916..f41753bc 100644 --- a/livekit-ffi/src/conversion/room.rs +++ b/livekit-ffi/src/conversion/room.rs @@ -281,3 +281,51 @@ impl From for proto::ChatMessage { } } } + +impl From for proto::data_stream::Header { + fn from(msg: livekit_protocol::data_stream::Header) -> Self { + let content_header = match msg.content_header { + Some(livekit_protocol::data_stream::header::ContentHeader::TextHeader(text_header)) => { + Some(proto::data_stream::header::ContentHeader::TextHeader( + proto::data_stream::TextHeader { + operation_type: text_header.operation_type, + version: text_header.version, + reply_to_stream_id: text_header.reply_to_stream_id, + attached_stream_ids: text_header.attached_stream_ids, + generated: text_header.generated, + }, + )) + } + Some(livekit_protocol::data_stream::header::ContentHeader::FileHeader(file_header)) => { + Some(proto::data_stream::header::ContentHeader::FileHeader( + proto::data_stream::FileHeader { file_name: file_header.file_name }, + )) + } + None => None, + }; + + proto::data_stream::Header { + stream_id: msg.stream_id, + timestamp: msg.timestamp, + topic: msg.topic, + mime_type: msg.mime_type, + total_chunks: msg.total_chunks, + total_length: msg.total_length, + extensions: msg.extensions, + content_header, + } + } +} + +impl From for proto::data_stream::Chunk { + fn from(msg: livekit_protocol::data_stream::Chunk) -> Self { + proto::data_stream::Chunk { + stream_id: msg.stream_id, + content: msg.content, + complete: msg.complete, + chunk_index: msg.chunk_index, + version: msg.version, + iv: msg.iv, + } + } +} diff --git a/livekit-ffi/src/livekit.proto.rs b/livekit-ffi/src/livekit.proto.rs index 10efaab6..85221e0b 100644 --- a/livekit-ffi/src/livekit.proto.rs +++ b/livekit-ffi/src/livekit.proto.rs @@ -2558,7 +2558,7 @@ pub struct OwnedBuffer { pub struct RoomEvent { #[prost(uint64, required, tag="1")] pub room_handle: u64, - #[prost(oneof="room_event::Message", tags="2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29")] + #[prost(oneof="room_event::Message", tags="2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31")] pub message: ::core::option::Option, } /// Nested message and enum types in `RoomEvent`. @@ -2624,6 +2624,10 @@ pub mod room_event { TranscriptionReceived(super::TranscriptionReceived), #[prost(message, tag="29")] ChatMessage(super::ChatMessageReceived), + #[prost(message, tag="30")] + StreamHeader(super::data_stream::Header), + #[prost(message, tag="31")] + StreamChunk(super::data_stream::Chunk), } } #[allow(clippy::derive_partial_eq_without_eq)] @@ -2898,6 +2902,133 @@ pub struct Reconnected { #[derive(Clone, PartialEq, ::prost::Message)] pub struct RoomEos { } +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct DataStream { +} +/// Nested message and enum types in `DataStream`. +pub mod data_stream { + /// header properties specific to text streams + #[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] + pub struct TextHeader { + #[prost(enumeration="OperationType", required, tag="1")] + pub operation_type: i32, + /// Optional: Version for updates/edits + #[prost(int32, required, tag="2")] + pub version: i32, + /// Optional: Reply to specific message + #[prost(string, required, tag="3")] + pub reply_to_stream_id: ::prost::alloc::string::String, + /// file attachments for text streams + #[prost(string, repeated, tag="4")] + pub attached_stream_ids: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, + /// true if the text has been generated by an agent from a participant's audio transcription + #[prost(bool, required, tag="5")] + pub generated: bool, + } + /// header properties specific to file or image streams + #[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] + pub struct FileHeader { + /// name of the file + #[prost(string, required, tag="1")] + pub file_name: ::prost::alloc::string::String, + } + /// main DataStream.Header that contains a oneof for specific headers + #[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] + pub struct Header { + /// unique identifier for this data stream + #[prost(string, required, tag="1")] + pub stream_id: ::prost::alloc::string::String, + /// using int64 for Unix timestamp + #[prost(int64, required, tag="2")] + pub timestamp: i64, + #[prost(string, required, tag="3")] + pub topic: ::prost::alloc::string::String, + #[prost(string, required, tag="4")] + pub mime_type: ::prost::alloc::string::String, + /// only populated for finite streams, if it's a stream of unknown size this stays empty + #[prost(uint64, optional, tag="5")] + pub total_length: ::core::option::Option, + /// only populated for finite streams, if it's a stream of unknown size this stays empty + #[prost(uint64, optional, tag="6")] + pub total_chunks: ::core::option::Option, + /// user defined extensions map that can carry additional info + #[prost(map="string, string", tag="7")] + pub extensions: ::std::collections::HashMap<::prost::alloc::string::String, ::prost::alloc::string::String>, + /// oneof to choose between specific header types + #[prost(oneof="header::ContentHeader", tags="8, 9")] + pub content_header: ::core::option::Option, + } + /// Nested message and enum types in `Header`. + pub mod header { + /// oneof to choose between specific header types + #[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Oneof)] + pub enum ContentHeader { + #[prost(message, tag="8")] + TextHeader(super::TextHeader), + #[prost(message, tag="9")] + FileHeader(super::FileHeader), + } + } + #[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] + pub struct Chunk { + /// unique identifier for this data stream to map it to the correct header + #[prost(string, required, tag="1")] + pub stream_id: ::prost::alloc::string::String, + #[prost(uint64, required, tag="2")] + pub chunk_index: u64, + /// content as binary (bytes) + #[prost(bytes="vec", required, tag="3")] + pub content: ::prost::alloc::vec::Vec, + /// true only if this is the last chunk of this stream - can also be sent with empty content + #[prost(bool, required, tag="4")] + pub complete: bool, + /// a version indicating that this chunk_index has been retroactively modified and the original one needs to be replaced + #[prost(int32, required, tag="5")] + pub version: i32, + /// optional, initialization vector for AES-GCM encryption + #[prost(bytes="vec", optional, tag="6")] + pub iv: ::core::option::Option<::prost::alloc::vec::Vec>, + } + /// enum for operation types (specific to TextHeader) + #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] + #[repr(i32)] + pub enum OperationType { + Create = 0, + Update = 1, + Delete = 2, + Reaction = 3, + } + impl OperationType { + /// 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 { + OperationType::Create => "CREATE", + OperationType::Update => "UPDATE", + OperationType::Delete => "DELETE", + OperationType::Reaction => "REACTION", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "CREATE" => Some(Self::Create), + "UPDATE" => Some(Self::Update), + "DELETE" => Some(Self::Delete), + "REACTION" => Some(Self::Reaction), + _ => None, + } + } + } +} #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] #[repr(i32)] pub enum IceTransportType { diff --git a/livekit-ffi/src/server/room.rs b/livekit-ffi/src/server/room.rs index 1367897e..ca0d26ac 100644 --- a/livekit-ffi/src/server/room.rs +++ b/livekit-ffi/src/server/room.rs @@ -1137,6 +1137,12 @@ async fn forward_event( state: proto::EncryptionState::from(state).into(), })); } + RoomEvent::StreamHeaderReceived { header } => { + let _ = send_event(proto::room_event::Message::StreamHeader(header.into())); + } + RoomEvent::StreamChunkReceived { chunk } => { + let _ = send_event(proto::room_event::Message::StreamChunk(chunk.into())); + } _ => { log::warn!("unhandled room event: {:?}", event); }