From f8efd3bd54c8011d45de13dc98231c31d155cba5 Mon Sep 17 00:00:00 2001 From: Daisuke Murase Date: Tue, 14 Jan 2025 15:39:14 -0800 Subject: [PATCH 1/8] set submodule livekit-protocol/protocol to v1.31.0 --- livekit-protocol/protocol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/livekit-protocol/protocol b/livekit-protocol/protocol index 095606bc8..553f87b84 160000 --- a/livekit-protocol/protocol +++ b/livekit-protocol/protocol @@ -1 +1 @@ -Subproject commit 095606bc8e0e73535c6bf4867645dfff0825f121 +Subproject commit 553f87b849effe55777f80cb93766509868fe4f5 From 4314f5eff4a07bb1d6e4ba1911b176b04556532c Mon Sep 17 00:00:00 2001 From: Daisuke Murase Date: Tue, 14 Jan 2025 15:41:34 -0800 Subject: [PATCH 2/8] generate proto.rs for v1.31.0 --- livekit-protocol/src/livekit.rs | 244 +++++- livekit-protocol/src/livekit.serde.rs | 1045 +++++++++++++++++++++++-- 2 files changed, 1194 insertions(+), 95 deletions(-) diff --git a/livekit-protocol/src/livekit.rs b/livekit-protocol/src/livekit.rs index 9c3107e4a..901a3f2d6 100644 --- a/livekit-protocol/src/livekit.rs +++ b/livekit-protocol/src/livekit.rs @@ -1,5 +1,4 @@ // @generated -// This file is @generated by prost-build. #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct MetricsBatch { @@ -515,7 +514,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, 13, 14")] + #[prost(oneof="data_packet::Value", tags="2, 3, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15")] pub value: ::core::option::Option, } /// Nested message and enum types in `DataPacket`. @@ -571,6 +570,8 @@ pub mod data_packet { StreamHeader(super::data_stream::Header), #[prost(message, tag="14")] StreamChunk(super::data_stream::Chunk), + #[prost(message, tag="15")] + StreamTrailer(super::data_stream::Trailer), } } #[allow(clippy::derive_partial_eq_without_eq)] @@ -1166,9 +1167,6 @@ pub mod data_stream { /// 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, @@ -1202,16 +1200,26 @@ pub mod data_stream { /// 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")] + #[prost(int32, tag="4")] pub version: i32, /// optional, initialization vector for AES-GCM encryption - #[prost(bytes="vec", optional, tag="6")] + #[prost(bytes="vec", optional, tag="5")] pub iv: ::core::option::Option<::prost::alloc::vec::Vec>, } + #[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] + pub struct Trailer { + /// unique identifier for this data stream + #[prost(string, tag="1")] + pub stream_id: ::prost::alloc::string::String, + /// reason why the stream was closed (could contain "error" / "interrupted" / empty for expected end) + #[prost(string, tag="2")] + pub reason: ::prost::alloc::string::String, + /// finalizing updates for the stream, can also include additional insights for errors or endTime for transcription + #[prost(map="string, string", tag="3")] + pub extensions: ::std::collections::HashMap<::prost::alloc::string::String, ::prost::alloc::string::String>, + } /// enum for operation types (specific to TextHeader) #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] #[repr(i32)] @@ -2209,6 +2217,8 @@ pub struct EgressInfo { pub room_id: ::prost::alloc::string::String, #[prost(string, tag="13")] pub room_name: ::prost::alloc::string::String, + #[prost(enumeration="EgressSourceType", tag="26")] + pub source_type: i32, #[prost(enumeration="EgressStatus", tag="3")] pub status: i32, #[prost(int64, tag="10")] @@ -2233,7 +2243,7 @@ pub struct EgressInfo { pub image_results: ::prost::alloc::vec::Vec, #[prost(string, tag="23")] pub manifest_location: ::prost::alloc::string::String, - /// next ID: 26 + /// next ID: 27 #[prost(bool, tag="25")] pub backup_storage_used: bool, #[prost(oneof="egress_info::Request", tags="4, 14, 19, 5, 6")] @@ -2655,6 +2665,32 @@ impl EgressStatus { } } } +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] +#[repr(i32)] +pub enum EgressSourceType { + Web = 0, + Sdk = 1, +} +impl EgressSourceType { + /// 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 { + EgressSourceType::Web => "EGRESS_SOURCE_TYPE_WEB", + EgressSourceType::Sdk => "EGRESS_SOURCE_TYPE_SDK", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "EGRESS_SOURCE_TYPE_WEB" => Some(Self::Web), + "EGRESS_SOURCE_TYPE_SDK" => Some(Self::Sdk), + _ => None, + } + } +} #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct SignalRequest { @@ -4079,6 +4115,9 @@ pub struct CreateIngressRequest { pub audio: ::core::option::Option, #[prost(message, optional, tag="7")] pub video: ::core::option::Option, + /// The default value is true and when set to false, the new connection attempts will be rejected + #[prost(bool, optional, tag="12")] + pub enabled: ::core::option::Option, } #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] @@ -4186,6 +4225,9 @@ pub struct IngressInfo { /// Description of error/stream non compliance and debug info for publisher otherwise (received bitrate, resolution, bandwidth) #[prost(message, optional, tag="12")] pub state: ::core::option::Option, + /// The default value is true and when set to false, the new connection attempts will be rejected + #[prost(bool, optional, tag="16")] + pub enabled: ::core::option::Option, } #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] @@ -4301,6 +4343,9 @@ pub struct UpdateIngressRequest { pub audio: ::core::option::Option, #[prost(message, optional, tag="7")] pub video: ::core::option::Option, + /// The default value is true and when set to false, the new connection attempts will be rejected + #[prost(bool, optional, tag="11")] + pub enabled: ::core::option::Option, } #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] @@ -4636,6 +4681,14 @@ pub struct SipInboundTrunkInfo { /// 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>, + /// Map SIP headers from INVITE to sip.h.* participant attributes automatically. + /// + /// When the names of required headers is known, using headers_to_attributes is strongly recommended. + /// + /// When mapping INVITE headers to response headers with attributes_to_headers map, + /// lowercase header names should be used, for example: sip.h.x-custom-header. + #[prost(enumeration="SipHeaderOptions", tag="15")] + pub include_headers: i32, /// Max time for the caller to wait for track subscription. #[prost(message, optional, tag="11")] pub ringing_timeout: ::core::option::Option<::pbjson_types::Duration>, @@ -4644,6 +4697,8 @@ pub struct SipInboundTrunkInfo { pub max_call_duration: ::core::option::Option<::pbjson_types::Duration>, #[prost(bool, tag="13")] pub krisp_enabled: bool, + #[prost(enumeration="SipMediaEncryption", tag="16")] + pub media_encryption: i32, } #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] @@ -4691,6 +4746,16 @@ pub struct SipOutboundTrunkInfo { /// 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>, + /// Map SIP headers from 200 OK to sip.h.* participant attributes automatically. + /// + /// When the names of required headers is known, using headers_to_attributes is strongly recommended. + /// + /// When mapping 200 OK headers to follow-up request headers with attributes_to_headers map, + /// lowercase header names should be used, for example: sip.h.x-custom-header. + #[prost(enumeration="SipHeaderOptions", tag="12")] + pub include_headers: i32, + #[prost(enumeration="SipMediaEncryption", tag="13")] + pub media_encryption: i32, } #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] @@ -4726,9 +4791,17 @@ pub struct ListSipTrunkResponse { #[prost(message, repeated, tag="1")] pub items: ::prost::alloc::vec::Vec, } +/// ListSIPInboundTrunkRequest lists inbound trunks for given filters. If no filters are set, all trunks are listed. #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct ListSipInboundTrunkRequest { + /// Trunk IDs to list. If this option is set, the response will contains trunks in the same order. + /// If any of the trunks is missing, a nil item in that position will be sent in the response. + #[prost(string, repeated, tag="1")] + pub trunk_ids: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, + /// Only list trunks that contain one of the numbers, including wildcard trunks. + #[prost(string, repeated, tag="2")] + pub numbers: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, } #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] @@ -4736,9 +4809,17 @@ pub struct ListSipInboundTrunkResponse { #[prost(message, repeated, tag="1")] pub items: ::prost::alloc::vec::Vec, } +/// ListSIPOutboundTrunkRequest lists outbound trunks for given filters. If no filters are set, all trunks are listed. #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct ListSipOutboundTrunkRequest { + /// Trunk IDs to list. If this option is set, the response will contains trunks in the same order. + /// If any of the trunks is missing, a nil item in that position will be sent in the response. + #[prost(string, repeated, tag="1")] + pub trunk_ids: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, + /// Only list trunks that contain one of the numbers, including wildcard trunks. + #[prost(string, repeated, tag="2")] + pub numbers: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, } #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] @@ -4836,6 +4917,12 @@ pub struct CreateSipDispatchRuleRequest { /// Participants created by this rule will inherit these attributes. #[prost(map="string, string", tag="7")] pub attributes: ::std::collections::HashMap<::prost::alloc::string::String, ::prost::alloc::string::String>, + /// Cloud-only, config preset to use + #[prost(string, tag="8")] + pub room_preset: ::prost::alloc::string::String, + /// RoomConfiguration to use if the participant initiates the room + #[prost(message, optional, tag="9")] + pub room_config: ::core::option::Option, } #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] @@ -4862,10 +4949,29 @@ pub struct SipDispatchRuleInfo { /// Participants created by this rule will inherit these attributes. #[prost(map="string, string", tag="8")] pub attributes: ::std::collections::HashMap<::prost::alloc::string::String, ::prost::alloc::string::String>, + /// Cloud-only, config preset to use + #[prost(string, tag="9")] + pub room_preset: ::prost::alloc::string::String, + /// RoomConfiguration to use if the participant initiates the room + #[prost(message, optional, tag="10")] + pub room_config: ::core::option::Option, + #[prost(bool, tag="11")] + pub krisp_enabled: bool, + /// NEXT ID: 13 + #[prost(enumeration="SipMediaEncryption", tag="12")] + pub media_encryption: i32, } +/// ListSIPDispatchRuleRequest lists dispatch rules for given filters. If no filters are set, all rules are listed. #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct ListSipDispatchRuleRequest { + /// Rule IDs to list. If this option is set, the response will contains rules in the same order. + /// If any of the rules is missing, a nil item in that position will be sent in the response. + #[prost(string, repeated, tag="1")] + pub dispatch_rule_ids: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, + /// Only list rules that contain one of the Trunk IDs, including wildcard rules. + #[prost(string, repeated, tag="2")] + pub trunk_ids: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, } #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] @@ -4922,6 +5028,17 @@ pub struct CreateSipParticipantRequest { /// 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, + /// These headers are sent as-is and may help identify this call as coming from LiveKit for the other SIP endpoint. + #[prost(map="string, string", tag="16")] + pub headers: ::std::collections::HashMap<::prost::alloc::string::String, ::prost::alloc::string::String>, + /// Map SIP headers from 200 OK to sip.h.* participant attributes automatically. + /// + /// When the names of required headers is known, using headers_to_attributes is strongly recommended. + /// + /// When mapping 200 OK headers to follow-up request headers with attributes_to_headers map, + /// lowercase header names should be used, for example: sip.h.x-custom-header. + #[prost(enumeration="SipHeaderOptions", tag="17")] + pub include_headers: i32, /// Max time for the callee to answer the call. #[prost(message, optional, tag="11")] pub ringing_timeout: ::core::option::Option<::pbjson_types::Duration>, @@ -4929,10 +5046,11 @@ pub struct CreateSipParticipantRequest { #[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, + pub krisp_enabled: bool, + /// NEXT ID: 19 + #[prost(enumeration="SipMediaEncryption", tag="18")] + pub media_encryption: i32, } #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] @@ -4958,6 +5076,9 @@ pub struct TransferSipParticipantRequest { /// Optionally play dialtone to the SIP participant as an audible indicator of being transferred #[prost(bool, tag="4")] pub play_dialtone: bool, + /// Add the following headers to the REFER SIP request. + #[prost(map="string, string", tag="5")] + pub headers: ::std::collections::HashMap<::prost::alloc::string::String, ::prost::alloc::string::String>, } #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] @@ -4979,6 +5100,8 @@ pub struct SipCallInfo { pub to_uri: ::core::option::Option, #[prost(enumeration="SipFeature", repeated, tag="14")] pub enabled_features: ::prost::alloc::vec::Vec, + #[prost(enumeration="SipCallDirection", tag="15")] + pub call_direction: i32, #[prost(enumeration="SipCallStatus", tag="8")] pub call_status: i32, #[prost(int64, tag="9")] @@ -5040,6 +5163,70 @@ impl SipTransport { } #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] #[repr(i32)] +pub enum SipHeaderOptions { + /// do not map any headers, except ones mapped explicitly + SipNoHeaders = 0, + /// map all X-* headers to sip.h.x-* attributes + SipXHeaders = 1, + /// map all headers to sip.h.* attributes + SipAllHeaders = 2, +} +impl SipHeaderOptions { + /// 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 { + SipHeaderOptions::SipNoHeaders => "SIP_NO_HEADERS", + SipHeaderOptions::SipXHeaders => "SIP_X_HEADERS", + SipHeaderOptions::SipAllHeaders => "SIP_ALL_HEADERS", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "SIP_NO_HEADERS" => Some(Self::SipNoHeaders), + "SIP_X_HEADERS" => Some(Self::SipXHeaders), + "SIP_ALL_HEADERS" => Some(Self::SipAllHeaders), + _ => None, + } + } +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] +#[repr(i32)] +pub enum SipMediaEncryption { + /// do not enable encryption + SipMediaEncryptDisable = 0, + /// use encryption if available + SipMediaEncryptAllow = 1, + /// require encryption + SipMediaEncryptRequire = 2, +} +impl SipMediaEncryption { + /// 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 { + SipMediaEncryption::SipMediaEncryptDisable => "SIP_MEDIA_ENCRYPT_DISABLE", + SipMediaEncryption::SipMediaEncryptAllow => "SIP_MEDIA_ENCRYPT_ALLOW", + SipMediaEncryption::SipMediaEncryptRequire => "SIP_MEDIA_ENCRYPT_REQUIRE", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "SIP_MEDIA_ENCRYPT_DISABLE" => Some(Self::SipMediaEncryptDisable), + "SIP_MEDIA_ENCRYPT_ALLOW" => Some(Self::SipMediaEncryptAllow), + "SIP_MEDIA_ENCRYPT_REQUIRE" => Some(Self::SipMediaEncryptRequire), + _ => None, + } + } +} +#[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, @@ -5104,5 +5291,34 @@ impl SipFeature { } } } +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] +#[repr(i32)] +pub enum SipCallDirection { + ScdUnknown = 0, + ScdInbound = 1, + ScdOutbound = 2, +} +impl SipCallDirection { + /// 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 { + SipCallDirection::ScdUnknown => "SCD_UNKNOWN", + SipCallDirection::ScdInbound => "SCD_INBOUND", + SipCallDirection::ScdOutbound => "SCD_OUTBOUND", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "SCD_UNKNOWN" => Some(Self::ScdUnknown), + "SCD_INBOUND" => Some(Self::ScdInbound), + "SCD_OUTBOUND" => Some(Self::ScdOutbound), + _ => 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 5da36416c..ae08809a4 100644 --- a/livekit-protocol/src/livekit.serde.rs +++ b/livekit-protocol/src/livekit.serde.rs @@ -3311,6 +3311,9 @@ impl serde::Serialize for CreateIngressRequest { if self.video.is_some() { len += 1; } + if self.enabled.is_some() { + len += 1; + } let mut struct_ser = serializer.serialize_struct("livekit.CreateIngressRequest", len)?; if self.input_type != 0 { let v = IngressInput::try_from(self.input_type) @@ -3347,6 +3350,9 @@ impl serde::Serialize for CreateIngressRequest { if let Some(v) = self.video.as_ref() { struct_ser.serialize_field("video", v)?; } + if let Some(v) = self.enabled.as_ref() { + struct_ser.serialize_field("enabled", v)?; + } struct_ser.end() } } @@ -3375,6 +3381,7 @@ impl<'de> serde::Deserialize<'de> for CreateIngressRequest { "enableTranscoding", "audio", "video", + "enabled", ]; #[allow(clippy::enum_variant_names)] @@ -3390,6 +3397,7 @@ impl<'de> serde::Deserialize<'de> for CreateIngressRequest { EnableTranscoding, Audio, Video, + Enabled, __SkipField__, } impl<'de> serde::Deserialize<'de> for GeneratedField { @@ -3423,6 +3431,7 @@ impl<'de> serde::Deserialize<'de> for CreateIngressRequest { "enableTranscoding" | "enable_transcoding" => Ok(GeneratedField::EnableTranscoding), "audio" => Ok(GeneratedField::Audio), "video" => Ok(GeneratedField::Video), + "enabled" => Ok(GeneratedField::Enabled), _ => Ok(GeneratedField::__SkipField__), } } @@ -3453,6 +3462,7 @@ impl<'de> serde::Deserialize<'de> for CreateIngressRequest { let mut enable_transcoding__ = None; let mut audio__ = None; let mut video__ = None; + let mut enabled__ = None; while let Some(k) = map_.next_key()? { match k { GeneratedField::InputType => { @@ -3521,6 +3531,12 @@ impl<'de> serde::Deserialize<'de> for CreateIngressRequest { } video__ = map_.next_value()?; } + GeneratedField::Enabled => { + if enabled__.is_some() { + return Err(serde::de::Error::duplicate_field("enabled")); + } + enabled__ = map_.next_value()?; + } GeneratedField::__SkipField__ => { let _ = map_.next_value::()?; } @@ -3538,6 +3554,7 @@ impl<'de> serde::Deserialize<'de> for CreateIngressRequest { enable_transcoding: enable_transcoding__, audio: audio__, video: video__, + enabled: enabled__, }) } } @@ -3891,6 +3908,12 @@ impl serde::Serialize for CreateSipDispatchRuleRequest { if !self.attributes.is_empty() { len += 1; } + if !self.room_preset.is_empty() { + len += 1; + } + if self.room_config.is_some() { + len += 1; + } let mut struct_ser = serializer.serialize_struct("livekit.CreateSIPDispatchRuleRequest", len)?; if let Some(v) = self.rule.as_ref() { struct_ser.serialize_field("rule", v)?; @@ -3913,6 +3936,12 @@ impl serde::Serialize for CreateSipDispatchRuleRequest { if !self.attributes.is_empty() { struct_ser.serialize_field("attributes", &self.attributes)?; } + if !self.room_preset.is_empty() { + struct_ser.serialize_field("roomPreset", &self.room_preset)?; + } + if let Some(v) = self.room_config.as_ref() { + struct_ser.serialize_field("roomConfig", v)?; + } struct_ser.end() } } @@ -3933,6 +3962,10 @@ impl<'de> serde::Deserialize<'de> for CreateSipDispatchRuleRequest { "name", "metadata", "attributes", + "room_preset", + "roomPreset", + "room_config", + "roomConfig", ]; #[allow(clippy::enum_variant_names)] @@ -3944,6 +3977,8 @@ impl<'de> serde::Deserialize<'de> for CreateSipDispatchRuleRequest { Name, Metadata, Attributes, + RoomPreset, + RoomConfig, __SkipField__, } impl<'de> serde::Deserialize<'de> for GeneratedField { @@ -3973,6 +4008,8 @@ impl<'de> serde::Deserialize<'de> for CreateSipDispatchRuleRequest { "name" => Ok(GeneratedField::Name), "metadata" => Ok(GeneratedField::Metadata), "attributes" => Ok(GeneratedField::Attributes), + "roomPreset" | "room_preset" => Ok(GeneratedField::RoomPreset), + "roomConfig" | "room_config" => Ok(GeneratedField::RoomConfig), _ => Ok(GeneratedField::__SkipField__), } } @@ -3999,6 +4036,8 @@ impl<'de> serde::Deserialize<'de> for CreateSipDispatchRuleRequest { let mut name__ = None; let mut metadata__ = None; let mut attributes__ = None; + let mut room_preset__ = None; + let mut room_config__ = None; while let Some(k) = map_.next_key()? { match k { GeneratedField::Rule => { @@ -4045,6 +4084,18 @@ impl<'de> serde::Deserialize<'de> for CreateSipDispatchRuleRequest { map_.next_value::>()? ); } + GeneratedField::RoomPreset => { + if room_preset__.is_some() { + return Err(serde::de::Error::duplicate_field("roomPreset")); + } + room_preset__ = Some(map_.next_value()?); + } + GeneratedField::RoomConfig => { + if room_config__.is_some() { + return Err(serde::de::Error::duplicate_field("roomConfig")); + } + room_config__ = map_.next_value()?; + } GeneratedField::__SkipField__ => { let _ = map_.next_value::()?; } @@ -4058,6 +4109,8 @@ impl<'de> serde::Deserialize<'de> for CreateSipDispatchRuleRequest { name: name__.unwrap_or_default(), metadata: metadata__.unwrap_or_default(), attributes: attributes__.unwrap_or_default(), + room_preset: room_preset__.unwrap_or_default(), + room_config: room_config__, }) } } @@ -4298,13 +4351,22 @@ impl serde::Serialize for CreateSipParticipantRequest { if self.hide_phone_number { len += 1; } + if !self.headers.is_empty() { + len += 1; + } + if self.include_headers != 0 { + len += 1; + } if self.ringing_timeout.is_some() { len += 1; } if self.max_call_duration.is_some() { len += 1; } - if self.enable_krisp { + if self.krisp_enabled { + len += 1; + } + if self.media_encryption != 0 { len += 1; } let mut struct_ser = serializer.serialize_struct("livekit.CreateSIPParticipantRequest", len)?; @@ -4344,14 +4406,27 @@ impl serde::Serialize for CreateSipParticipantRequest { if self.hide_phone_number { struct_ser.serialize_field("hidePhoneNumber", &self.hide_phone_number)?; } + if !self.headers.is_empty() { + struct_ser.serialize_field("headers", &self.headers)?; + } + if self.include_headers != 0 { + let v = SipHeaderOptions::try_from(self.include_headers) + .map_err(|_| serde::ser::Error::custom(format!("Invalid variant {}", self.include_headers)))?; + struct_ser.serialize_field("includeHeaders", &v)?; + } 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)?; + if self.krisp_enabled { + struct_ser.serialize_field("krispEnabled", &self.krisp_enabled)?; + } + if self.media_encryption != 0 { + let v = SipMediaEncryption::try_from(self.media_encryption) + .map_err(|_| serde::ser::Error::custom(format!("Invalid variant {}", self.media_encryption)))?; + struct_ser.serialize_field("mediaEncryption", &v)?; } struct_ser.end() } @@ -4386,12 +4461,17 @@ impl<'de> serde::Deserialize<'de> for CreateSipParticipantRequest { "playDialtone", "hide_phone_number", "hidePhoneNumber", + "headers", + "include_headers", + "includeHeaders", "ringing_timeout", "ringingTimeout", "max_call_duration", "maxCallDuration", - "enable_krisp", - "enableKrisp", + "krisp_enabled", + "krispEnabled", + "media_encryption", + "mediaEncryption", ]; #[allow(clippy::enum_variant_names)] @@ -4408,9 +4488,12 @@ impl<'de> serde::Deserialize<'de> for CreateSipParticipantRequest { PlayRingtone, PlayDialtone, HidePhoneNumber, + Headers, + IncludeHeaders, RingingTimeout, MaxCallDuration, - EnableKrisp, + KrispEnabled, + MediaEncryption, __SkipField__, } impl<'de> serde::Deserialize<'de> for GeneratedField { @@ -4445,9 +4528,12 @@ impl<'de> serde::Deserialize<'de> for CreateSipParticipantRequest { "playRingtone" | "play_ringtone" => Ok(GeneratedField::PlayRingtone), "playDialtone" | "play_dialtone" => Ok(GeneratedField::PlayDialtone), "hidePhoneNumber" | "hide_phone_number" => Ok(GeneratedField::HidePhoneNumber), + "headers" => Ok(GeneratedField::Headers), + "includeHeaders" | "include_headers" => Ok(GeneratedField::IncludeHeaders), "ringingTimeout" | "ringing_timeout" => Ok(GeneratedField::RingingTimeout), "maxCallDuration" | "max_call_duration" => Ok(GeneratedField::MaxCallDuration), - "enableKrisp" | "enable_krisp" => Ok(GeneratedField::EnableKrisp), + "krispEnabled" | "krisp_enabled" => Ok(GeneratedField::KrispEnabled), + "mediaEncryption" | "media_encryption" => Ok(GeneratedField::MediaEncryption), _ => Ok(GeneratedField::__SkipField__), } } @@ -4479,9 +4565,12 @@ impl<'de> serde::Deserialize<'de> for CreateSipParticipantRequest { let mut play_ringtone__ = None; let mut play_dialtone__ = None; let mut hide_phone_number__ = None; + let mut headers__ = None; + let mut include_headers__ = None; let mut ringing_timeout__ = None; let mut max_call_duration__ = None; - let mut enable_krisp__ = None; + let mut krisp_enabled__ = None; + let mut media_encryption__ = None; while let Some(k) = map_.next_key()? { match k { GeneratedField::SipTrunkId => { @@ -4558,6 +4647,20 @@ impl<'de> serde::Deserialize<'de> for CreateSipParticipantRequest { } hide_phone_number__ = Some(map_.next_value()?); } + GeneratedField::Headers => { + if headers__.is_some() { + return Err(serde::de::Error::duplicate_field("headers")); + } + headers__ = Some( + map_.next_value::>()? + ); + } + GeneratedField::IncludeHeaders => { + if include_headers__.is_some() { + return Err(serde::de::Error::duplicate_field("includeHeaders")); + } + include_headers__ = Some(map_.next_value::()? as i32); + } GeneratedField::RingingTimeout => { if ringing_timeout__.is_some() { return Err(serde::de::Error::duplicate_field("ringingTimeout")); @@ -4570,11 +4673,17 @@ impl<'de> serde::Deserialize<'de> for CreateSipParticipantRequest { } max_call_duration__ = map_.next_value()?; } - GeneratedField::EnableKrisp => { - if enable_krisp__.is_some() { - return Err(serde::de::Error::duplicate_field("enableKrisp")); + GeneratedField::KrispEnabled => { + if krisp_enabled__.is_some() { + return Err(serde::de::Error::duplicate_field("krispEnabled")); + } + krisp_enabled__ = Some(map_.next_value()?); + } + GeneratedField::MediaEncryption => { + if media_encryption__.is_some() { + return Err(serde::de::Error::duplicate_field("mediaEncryption")); } - enable_krisp__ = Some(map_.next_value()?); + media_encryption__ = Some(map_.next_value::()? as i32); } GeneratedField::__SkipField__ => { let _ = map_.next_value::()?; @@ -4594,9 +4703,12 @@ impl<'de> serde::Deserialize<'de> for CreateSipParticipantRequest { play_ringtone: play_ringtone__.unwrap_or_default(), play_dialtone: play_dialtone__.unwrap_or_default(), hide_phone_number: hide_phone_number__.unwrap_or_default(), + headers: headers__.unwrap_or_default(), + include_headers: include_headers__.unwrap_or_default(), ringing_timeout: ringing_timeout__, max_call_duration: max_call_duration__, - enable_krisp: enable_krisp__.unwrap_or_default(), + krisp_enabled: krisp_enabled__.unwrap_or_default(), + media_encryption: media_encryption__.unwrap_or_default(), }) } } @@ -5077,6 +5189,9 @@ impl serde::Serialize for DataPacket { data_packet::Value::StreamChunk(v) => { struct_ser.serialize_field("streamChunk", v)?; } + data_packet::Value::StreamTrailer(v) => { + struct_ser.serialize_field("streamTrailer", v)?; + } } } struct_ser.end() @@ -5112,6 +5227,8 @@ impl<'de> serde::Deserialize<'de> for DataPacket { "streamHeader", "stream_chunk", "streamChunk", + "stream_trailer", + "streamTrailer", ]; #[allow(clippy::enum_variant_names)] @@ -5130,6 +5247,7 @@ impl<'de> serde::Deserialize<'de> for DataPacket { RpcResponse, StreamHeader, StreamChunk, + StreamTrailer, __SkipField__, } impl<'de> serde::Deserialize<'de> for GeneratedField { @@ -5166,6 +5284,7 @@ impl<'de> serde::Deserialize<'de> for DataPacket { "rpcResponse" | "rpc_response" => Ok(GeneratedField::RpcResponse), "streamHeader" | "stream_header" => Ok(GeneratedField::StreamHeader), "streamChunk" | "stream_chunk" => Ok(GeneratedField::StreamChunk), + "streamTrailer" | "stream_trailer" => Ok(GeneratedField::StreamTrailer), _ => Ok(GeneratedField::__SkipField__), } } @@ -5284,6 +5403,13 @@ impl<'de> serde::Deserialize<'de> for DataPacket { return Err(serde::de::Error::duplicate_field("streamChunk")); } value__ = map_.next_value::<::std::option::Option<_>>()?.map(data_packet::Value::StreamChunk) +; + } + GeneratedField::StreamTrailer => { + if value__.is_some() { + return Err(serde::de::Error::duplicate_field("streamTrailer")); + } + value__ = map_.next_value::<::std::option::Option<_>>()?.map(data_packet::Value::StreamTrailer) ; } GeneratedField::__SkipField__ => { @@ -5462,9 +5588,6 @@ impl serde::Serialize for data_stream::Chunk { if !self.content.is_empty() { len += 1; } - if self.complete { - len += 1; - } if self.version != 0 { len += 1; } @@ -5485,9 +5608,6 @@ impl serde::Serialize for data_stream::Chunk { #[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)?; } @@ -5511,7 +5631,6 @@ impl<'de> serde::Deserialize<'de> for data_stream::Chunk { "chunk_index", "chunkIndex", "content", - "complete", "version", "iv", ]; @@ -5521,7 +5640,6 @@ impl<'de> serde::Deserialize<'de> for data_stream::Chunk { StreamId, ChunkIndex, Content, - Complete, Version, Iv, __SkipField__, @@ -5549,7 +5667,6 @@ impl<'de> serde::Deserialize<'de> for data_stream::Chunk { "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__), @@ -5574,7 +5691,6 @@ impl<'de> serde::Deserialize<'de> for data_stream::Chunk { 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()? { @@ -5601,12 +5717,6 @@ impl<'de> serde::Deserialize<'de> for data_stream::Chunk { 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")); @@ -5632,7 +5742,6 @@ impl<'de> serde::Deserialize<'de> for 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__, }) @@ -5760,9 +5869,6 @@ impl serde::Serialize for data_stream::Header { if self.total_length.is_some() { len += 1; } - if self.total_chunks.is_some() { - len += 1; - } if self.encryption_type != 0 { len += 1; } @@ -5792,11 +5898,6 @@ impl serde::Serialize for data_stream::Header { #[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)))?; @@ -5833,8 +5934,6 @@ impl<'de> serde::Deserialize<'de> for data_stream::Header { "mimeType", "total_length", "totalLength", - "total_chunks", - "totalChunks", "encryption_type", "encryptionType", "extensions", @@ -5851,7 +5950,6 @@ impl<'de> serde::Deserialize<'de> for data_stream::Header { Topic, MimeType, TotalLength, - TotalChunks, EncryptionType, Extensions, TextHeader, @@ -5883,7 +5981,6 @@ impl<'de> serde::Deserialize<'de> for data_stream::Header { "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), @@ -5912,7 +6009,6 @@ impl<'de> serde::Deserialize<'de> for data_stream::Header { 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; @@ -5952,14 +6048,6 @@ impl<'de> serde::Deserialize<'de> for data_stream::Header { 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")); @@ -5999,7 +6087,6 @@ impl<'de> serde::Deserialize<'de> for data_stream::Header { 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__, @@ -6256,6 +6343,138 @@ impl<'de> serde::Deserialize<'de> for data_stream::TextHeader { deserializer.deserialize_struct("livekit.DataStream.TextHeader", FIELDS, GeneratedVisitor) } } +impl serde::Serialize for data_stream::Trailer { + #[allow(deprecated)] + fn serialize(&self, serializer: S) -> std::result::Result + where + S: serde::Serializer, + { + use serde::ser::SerializeStruct; + let mut len = 0; + if !self.stream_id.is_empty() { + len += 1; + } + if !self.reason.is_empty() { + len += 1; + } + if !self.extensions.is_empty() { + len += 1; + } + let mut struct_ser = serializer.serialize_struct("livekit.DataStream.Trailer", len)?; + if !self.stream_id.is_empty() { + struct_ser.serialize_field("streamId", &self.stream_id)?; + } + if !self.reason.is_empty() { + struct_ser.serialize_field("reason", &self.reason)?; + } + if !self.extensions.is_empty() { + struct_ser.serialize_field("extensions", &self.extensions)?; + } + struct_ser.end() + } +} +impl<'de> serde::Deserialize<'de> for data_stream::Trailer { + #[allow(deprecated)] + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + const FIELDS: &[&str] = &[ + "stream_id", + "streamId", + "reason", + "extensions", + ]; + + #[allow(clippy::enum_variant_names)] + enum GeneratedField { + StreamId, + Reason, + Extensions, + __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 { + "streamId" | "stream_id" => Ok(GeneratedField::StreamId), + "reason" => Ok(GeneratedField::Reason), + "extensions" => Ok(GeneratedField::Extensions), + _ => Ok(GeneratedField::__SkipField__), + } + } + } + deserializer.deserialize_identifier(GeneratedVisitor) + } + } + struct GeneratedVisitor; + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = data_stream::Trailer; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + formatter.write_str("struct livekit.DataStream.Trailer") + } + + fn visit_map(self, mut map_: V) -> std::result::Result + where + V: serde::de::MapAccess<'de>, + { + let mut stream_id__ = None; + let mut reason__ = None; + let mut extensions__ = 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::Reason => { + if reason__.is_some() { + return Err(serde::de::Error::duplicate_field("reason")); + } + reason__ = Some(map_.next_value()?); + } + GeneratedField::Extensions => { + if extensions__.is_some() { + return Err(serde::de::Error::duplicate_field("extensions")); + } + extensions__ = Some( + map_.next_value::>()? + ); + } + GeneratedField::__SkipField__ => { + let _ = map_.next_value::()?; + } + } + } + Ok(data_stream::Trailer { + stream_id: stream_id__.unwrap_or_default(), + reason: reason__.unwrap_or_default(), + extensions: extensions__.unwrap_or_default(), + }) + } + } + deserializer.deserialize_struct("livekit.DataStream.Trailer", FIELDS, GeneratedVisitor) + } +} impl serde::Serialize for DeleteAgentDispatchRequest { #[allow(deprecated)] fn serialize(&self, serializer: S) -> std::result::Result @@ -7234,6 +7453,9 @@ impl serde::Serialize for EgressInfo { if !self.room_name.is_empty() { len += 1; } + if self.source_type != 0 { + len += 1; + } if self.status != 0 { len += 1; } @@ -7289,6 +7511,11 @@ impl serde::Serialize for EgressInfo { if !self.room_name.is_empty() { struct_ser.serialize_field("roomName", &self.room_name)?; } + if self.source_type != 0 { + let v = EgressSourceType::try_from(self.source_type) + .map_err(|_| serde::ser::Error::custom(format!("Invalid variant {}", self.source_type)))?; + struct_ser.serialize_field("sourceType", &v)?; + } if self.status != 0 { let v = EgressStatus::try_from(self.status) .map_err(|_| serde::ser::Error::custom(format!("Invalid variant {}", self.status)))?; @@ -7384,6 +7611,8 @@ impl<'de> serde::Deserialize<'de> for EgressInfo { "roomId", "room_name", "roomName", + "source_type", + "sourceType", "status", "started_at", "startedAt", @@ -7424,6 +7653,7 @@ impl<'de> serde::Deserialize<'de> for EgressInfo { EgressId, RoomId, RoomName, + SourceType, Status, StartedAt, EndedAt, @@ -7470,6 +7700,7 @@ impl<'de> serde::Deserialize<'de> for EgressInfo { "egressId" | "egress_id" => Ok(GeneratedField::EgressId), "roomId" | "room_id" => Ok(GeneratedField::RoomId), "roomName" | "room_name" => Ok(GeneratedField::RoomName), + "sourceType" | "source_type" => Ok(GeneratedField::SourceType), "status" => Ok(GeneratedField::Status), "startedAt" | "started_at" => Ok(GeneratedField::StartedAt), "endedAt" | "ended_at" => Ok(GeneratedField::EndedAt), @@ -7513,6 +7744,7 @@ impl<'de> serde::Deserialize<'de> for EgressInfo { let mut egress_id__ = None; let mut room_id__ = None; let mut room_name__ = None; + let mut source_type__ = None; let mut status__ = None; let mut started_at__ = None; let mut ended_at__ = None; @@ -7548,6 +7780,12 @@ impl<'de> serde::Deserialize<'de> for EgressInfo { } room_name__ = Some(map_.next_value()?); } + GeneratedField::SourceType => { + if source_type__.is_some() { + return Err(serde::de::Error::duplicate_field("sourceType")); + } + source_type__ = Some(map_.next_value::()? as i32); + } GeneratedField::Status => { if status__.is_some() { return Err(serde::de::Error::duplicate_field("status")); @@ -7699,6 +7937,7 @@ impl<'de> serde::Deserialize<'de> for EgressInfo { egress_id: egress_id__.unwrap_or_default(), room_id: room_id__.unwrap_or_default(), room_name: room_name__.unwrap_or_default(), + source_type: source_type__.unwrap_or_default(), status: status__.unwrap_or_default(), started_at: started_at__.unwrap_or_default(), ended_at: ended_at__.unwrap_or_default(), @@ -7720,6 +7959,77 @@ impl<'de> serde::Deserialize<'de> for EgressInfo { deserializer.deserialize_struct("livekit.EgressInfo", FIELDS, GeneratedVisitor) } } +impl serde::Serialize for EgressSourceType { + #[allow(deprecated)] + fn serialize(&self, serializer: S) -> std::result::Result + where + S: serde::Serializer, + { + let variant = match self { + Self::Web => "EGRESS_SOURCE_TYPE_WEB", + Self::Sdk => "EGRESS_SOURCE_TYPE_SDK", + }; + serializer.serialize_str(variant) + } +} +impl<'de> serde::Deserialize<'de> for EgressSourceType { + #[allow(deprecated)] + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + const FIELDS: &[&str] = &[ + "EGRESS_SOURCE_TYPE_WEB", + "EGRESS_SOURCE_TYPE_SDK", + ]; + + struct GeneratedVisitor; + + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = EgressSourceType; + + 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 { + "EGRESS_SOURCE_TYPE_WEB" => Ok(EgressSourceType::Web), + "EGRESS_SOURCE_TYPE_SDK" => Ok(EgressSourceType::Sdk), + _ => Err(serde::de::Error::unknown_variant(value, FIELDS)), + } + } + } + deserializer.deserialize_any(GeneratedVisitor) + } +} impl serde::Serialize for EgressStatus { #[allow(deprecated)] fn serialize(&self, serializer: S) -> std::result::Result @@ -10719,6 +11029,9 @@ impl serde::Serialize for IngressInfo { if self.state.is_some() { len += 1; } + if self.enabled.is_some() { + len += 1; + } let mut struct_ser = serializer.serialize_struct("livekit.IngressInfo", len)?; if !self.ingress_id.is_empty() { struct_ser.serialize_field("ingressId", &self.ingress_id)?; @@ -10767,6 +11080,9 @@ impl serde::Serialize for IngressInfo { if let Some(v) = self.state.as_ref() { struct_ser.serialize_field("state", v)?; } + if let Some(v) = self.enabled.as_ref() { + struct_ser.serialize_field("enabled", v)?; + } struct_ser.end() } } @@ -10801,6 +11117,7 @@ impl<'de> serde::Deserialize<'de> for IngressInfo { "participantMetadata", "reusable", "state", + "enabled", ]; #[allow(clippy::enum_variant_names)] @@ -10820,6 +11137,7 @@ impl<'de> serde::Deserialize<'de> for IngressInfo { ParticipantMetadata, Reusable, State, + Enabled, __SkipField__, } impl<'de> serde::Deserialize<'de> for GeneratedField { @@ -10857,6 +11175,7 @@ impl<'de> serde::Deserialize<'de> for IngressInfo { "participantMetadata" | "participant_metadata" => Ok(GeneratedField::ParticipantMetadata), "reusable" => Ok(GeneratedField::Reusable), "state" => Ok(GeneratedField::State), + "enabled" => Ok(GeneratedField::Enabled), _ => Ok(GeneratedField::__SkipField__), } } @@ -10891,6 +11210,7 @@ impl<'de> serde::Deserialize<'de> for IngressInfo { let mut participant_metadata__ = None; let mut reusable__ = None; let mut state__ = None; + let mut enabled__ = None; while let Some(k) = map_.next_key()? { match k { GeneratedField::IngressId => { @@ -10983,6 +11303,12 @@ impl<'de> serde::Deserialize<'de> for IngressInfo { } state__ = map_.next_value()?; } + GeneratedField::Enabled => { + if enabled__.is_some() { + return Err(serde::de::Error::duplicate_field("enabled")); + } + enabled__ = map_.next_value()?; + } GeneratedField::__SkipField__ => { let _ = map_.next_value::()?; } @@ -11004,6 +11330,7 @@ impl<'de> serde::Deserialize<'de> for IngressInfo { participant_metadata: participant_metadata__.unwrap_or_default(), reusable: reusable__.unwrap_or_default(), state: state__, + enabled: enabled__, }) } } @@ -14555,8 +14882,20 @@ impl serde::Serialize for ListSipDispatchRuleRequest { S: serde::Serializer, { use serde::ser::SerializeStruct; - let len = 0; - let struct_ser = serializer.serialize_struct("livekit.ListSIPDispatchRuleRequest", len)?; + let mut len = 0; + if !self.dispatch_rule_ids.is_empty() { + len += 1; + } + if !self.trunk_ids.is_empty() { + len += 1; + } + let mut struct_ser = serializer.serialize_struct("livekit.ListSIPDispatchRuleRequest", len)?; + if !self.dispatch_rule_ids.is_empty() { + struct_ser.serialize_field("dispatchRuleIds", &self.dispatch_rule_ids)?; + } + if !self.trunk_ids.is_empty() { + struct_ser.serialize_field("trunkIds", &self.trunk_ids)?; + } struct_ser.end() } } @@ -14567,10 +14906,16 @@ impl<'de> serde::Deserialize<'de> for ListSipDispatchRuleRequest { D: serde::Deserializer<'de>, { const FIELDS: &[&str] = &[ + "dispatch_rule_ids", + "dispatchRuleIds", + "trunk_ids", + "trunkIds", ]; #[allow(clippy::enum_variant_names)] enum GeneratedField { + DispatchRuleIds, + TrunkIds, __SkipField__, } impl<'de> serde::Deserialize<'de> for GeneratedField { @@ -14592,7 +14937,11 @@ impl<'de> serde::Deserialize<'de> for ListSipDispatchRuleRequest { where E: serde::de::Error, { - Ok(GeneratedField::__SkipField__) + match value { + "dispatchRuleIds" | "dispatch_rule_ids" => Ok(GeneratedField::DispatchRuleIds), + "trunkIds" | "trunk_ids" => Ok(GeneratedField::TrunkIds), + _ => Ok(GeneratedField::__SkipField__), + } } } deserializer.deserialize_identifier(GeneratedVisitor) @@ -14610,10 +14959,30 @@ impl<'de> serde::Deserialize<'de> for ListSipDispatchRuleRequest { where V: serde::de::MapAccess<'de>, { - while map_.next_key::()?.is_some() { - let _ = map_.next_value::()?; + let mut dispatch_rule_ids__ = None; + let mut trunk_ids__ = None; + while let Some(k) = map_.next_key()? { + match k { + GeneratedField::DispatchRuleIds => { + if dispatch_rule_ids__.is_some() { + return Err(serde::de::Error::duplicate_field("dispatchRuleIds")); + } + dispatch_rule_ids__ = Some(map_.next_value()?); + } + GeneratedField::TrunkIds => { + if trunk_ids__.is_some() { + return Err(serde::de::Error::duplicate_field("trunkIds")); + } + trunk_ids__ = Some(map_.next_value()?); + } + GeneratedField::__SkipField__ => { + let _ = map_.next_value::()?; + } + } } Ok(ListSipDispatchRuleRequest { + dispatch_rule_ids: dispatch_rule_ids__.unwrap_or_default(), + trunk_ids: trunk_ids__.unwrap_or_default(), }) } } @@ -14722,8 +15091,20 @@ impl serde::Serialize for ListSipInboundTrunkRequest { S: serde::Serializer, { use serde::ser::SerializeStruct; - let len = 0; - let struct_ser = serializer.serialize_struct("livekit.ListSIPInboundTrunkRequest", len)?; + let mut len = 0; + if !self.trunk_ids.is_empty() { + len += 1; + } + if !self.numbers.is_empty() { + len += 1; + } + let mut struct_ser = serializer.serialize_struct("livekit.ListSIPInboundTrunkRequest", len)?; + if !self.trunk_ids.is_empty() { + struct_ser.serialize_field("trunkIds", &self.trunk_ids)?; + } + if !self.numbers.is_empty() { + struct_ser.serialize_field("numbers", &self.numbers)?; + } struct_ser.end() } } @@ -14734,10 +15115,15 @@ impl<'de> serde::Deserialize<'de> for ListSipInboundTrunkRequest { D: serde::Deserializer<'de>, { const FIELDS: &[&str] = &[ + "trunk_ids", + "trunkIds", + "numbers", ]; #[allow(clippy::enum_variant_names)] enum GeneratedField { + TrunkIds, + Numbers, __SkipField__, } impl<'de> serde::Deserialize<'de> for GeneratedField { @@ -14759,7 +15145,11 @@ impl<'de> serde::Deserialize<'de> for ListSipInboundTrunkRequest { where E: serde::de::Error, { - Ok(GeneratedField::__SkipField__) + match value { + "trunkIds" | "trunk_ids" => Ok(GeneratedField::TrunkIds), + "numbers" => Ok(GeneratedField::Numbers), + _ => Ok(GeneratedField::__SkipField__), + } } } deserializer.deserialize_identifier(GeneratedVisitor) @@ -14777,10 +15167,30 @@ impl<'de> serde::Deserialize<'de> for ListSipInboundTrunkRequest { where V: serde::de::MapAccess<'de>, { - while map_.next_key::()?.is_some() { - let _ = map_.next_value::()?; + let mut trunk_ids__ = None; + let mut numbers__ = None; + while let Some(k) = map_.next_key()? { + match k { + GeneratedField::TrunkIds => { + if trunk_ids__.is_some() { + return Err(serde::de::Error::duplicate_field("trunkIds")); + } + trunk_ids__ = Some(map_.next_value()?); + } + GeneratedField::Numbers => { + if numbers__.is_some() { + return Err(serde::de::Error::duplicate_field("numbers")); + } + numbers__ = Some(map_.next_value()?); + } + GeneratedField::__SkipField__ => { + let _ = map_.next_value::()?; + } + } } Ok(ListSipInboundTrunkRequest { + trunk_ids: trunk_ids__.unwrap_or_default(), + numbers: numbers__.unwrap_or_default(), }) } } @@ -14889,8 +15299,20 @@ impl serde::Serialize for ListSipOutboundTrunkRequest { S: serde::Serializer, { use serde::ser::SerializeStruct; - let len = 0; - let struct_ser = serializer.serialize_struct("livekit.ListSIPOutboundTrunkRequest", len)?; + let mut len = 0; + if !self.trunk_ids.is_empty() { + len += 1; + } + if !self.numbers.is_empty() { + len += 1; + } + let mut struct_ser = serializer.serialize_struct("livekit.ListSIPOutboundTrunkRequest", len)?; + if !self.trunk_ids.is_empty() { + struct_ser.serialize_field("trunkIds", &self.trunk_ids)?; + } + if !self.numbers.is_empty() { + struct_ser.serialize_field("numbers", &self.numbers)?; + } struct_ser.end() } } @@ -14901,10 +15323,15 @@ impl<'de> serde::Deserialize<'de> for ListSipOutboundTrunkRequest { D: serde::Deserializer<'de>, { const FIELDS: &[&str] = &[ + "trunk_ids", + "trunkIds", + "numbers", ]; #[allow(clippy::enum_variant_names)] enum GeneratedField { + TrunkIds, + Numbers, __SkipField__, } impl<'de> serde::Deserialize<'de> for GeneratedField { @@ -14926,7 +15353,11 @@ impl<'de> serde::Deserialize<'de> for ListSipOutboundTrunkRequest { where E: serde::de::Error, { - Ok(GeneratedField::__SkipField__) + match value { + "trunkIds" | "trunk_ids" => Ok(GeneratedField::TrunkIds), + "numbers" => Ok(GeneratedField::Numbers), + _ => Ok(GeneratedField::__SkipField__), + } } } deserializer.deserialize_identifier(GeneratedVisitor) @@ -14944,10 +15375,30 @@ impl<'de> serde::Deserialize<'de> for ListSipOutboundTrunkRequest { where V: serde::de::MapAccess<'de>, { - while map_.next_key::()?.is_some() { - let _ = map_.next_value::()?; + let mut trunk_ids__ = None; + let mut numbers__ = None; + while let Some(k) = map_.next_key()? { + match k { + GeneratedField::TrunkIds => { + if trunk_ids__.is_some() { + return Err(serde::de::Error::duplicate_field("trunkIds")); + } + trunk_ids__ = Some(map_.next_value()?); + } + GeneratedField::Numbers => { + if numbers__.is_some() { + return Err(serde::de::Error::duplicate_field("numbers")); + } + numbers__ = Some(map_.next_value()?); + } + GeneratedField::__SkipField__ => { + let _ = map_.next_value::()?; + } + } } Ok(ListSipOutboundTrunkRequest { + trunk_ids: trunk_ids__.unwrap_or_default(), + numbers: numbers__.unwrap_or_default(), }) } } @@ -22895,22 +23346,96 @@ impl<'de> serde::Deserialize<'de> for S3Upload { } } } - 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(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.S3Upload", FIELDS, GeneratedVisitor) + } +} +impl serde::Serialize for SipCallDirection { + #[allow(deprecated)] + fn serialize(&self, serializer: S) -> std::result::Result + where + S: serde::Serializer, + { + let variant = match self { + Self::ScdUnknown => "SCD_UNKNOWN", + Self::ScdInbound => "SCD_INBOUND", + Self::ScdOutbound => "SCD_OUTBOUND", + }; + serializer.serialize_str(variant) + } +} +impl<'de> serde::Deserialize<'de> for SipCallDirection { + #[allow(deprecated)] + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + const FIELDS: &[&str] = &[ + "SCD_UNKNOWN", + "SCD_INBOUND", + "SCD_OUTBOUND", + ]; + + struct GeneratedVisitor; + + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = SipCallDirection; + + 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 { + "SCD_UNKNOWN" => Ok(SipCallDirection::ScdUnknown), + "SCD_INBOUND" => Ok(SipCallDirection::ScdInbound), + "SCD_OUTBOUND" => Ok(SipCallDirection::ScdOutbound), + _ => Err(serde::de::Error::unknown_variant(value, FIELDS)), + } } } - deserializer.deserialize_struct("livekit.S3Upload", FIELDS, GeneratedVisitor) + deserializer.deserialize_any(GeneratedVisitor) } } impl serde::Serialize for SipCallInfo { @@ -22945,6 +23470,9 @@ impl serde::Serialize for SipCallInfo { if !self.enabled_features.is_empty() { len += 1; } + if self.call_direction != 0 { + len += 1; + } if self.call_status != 0 { len += 1; } @@ -22992,6 +23520,11 @@ impl serde::Serialize for SipCallInfo { }).collect::, _>>()?; struct_ser.serialize_field("enabledFeatures", &v)?; } + if self.call_direction != 0 { + let v = SipCallDirection::try_from(self.call_direction) + .map_err(|_| serde::ser::Error::custom(format!("Invalid variant {}", self.call_direction)))?; + struct_ser.serialize_field("callDirection", &v)?; + } 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)))?; @@ -23046,6 +23579,8 @@ impl<'de> serde::Deserialize<'de> for SipCallInfo { "toUri", "enabled_features", "enabledFeatures", + "call_direction", + "callDirection", "call_status", "callStatus", "created_at", @@ -23069,6 +23604,7 @@ impl<'de> serde::Deserialize<'de> for SipCallInfo { FromUri, ToUri, EnabledFeatures, + CallDirection, CallStatus, CreatedAt, StartedAt, @@ -23105,6 +23641,7 @@ impl<'de> serde::Deserialize<'de> for SipCallInfo { "fromUri" | "from_uri" => Ok(GeneratedField::FromUri), "toUri" | "to_uri" => Ok(GeneratedField::ToUri), "enabledFeatures" | "enabled_features" => Ok(GeneratedField::EnabledFeatures), + "callDirection" | "call_direction" => Ok(GeneratedField::CallDirection), "callStatus" | "call_status" => Ok(GeneratedField::CallStatus), "createdAt" | "created_at" => Ok(GeneratedField::CreatedAt), "startedAt" | "started_at" => Ok(GeneratedField::StartedAt), @@ -23138,6 +23675,7 @@ impl<'de> serde::Deserialize<'de> for SipCallInfo { let mut from_uri__ = None; let mut to_uri__ = None; let mut enabled_features__ = None; + let mut call_direction__ = None; let mut call_status__ = None; let mut created_at__ = None; let mut started_at__ = None; @@ -23194,6 +23732,12 @@ impl<'de> serde::Deserialize<'de> for SipCallInfo { } enabled_features__ = Some(map_.next_value::>()?.into_iter().map(|x| x as i32).collect()); } + GeneratedField::CallDirection => { + if call_direction__.is_some() { + return Err(serde::de::Error::duplicate_field("callDirection")); + } + call_direction__ = Some(map_.next_value::()? as i32); + } GeneratedField::CallStatus => { if call_status__.is_some() { return Err(serde::de::Error::duplicate_field("callStatus")); @@ -23250,6 +23794,7 @@ impl<'de> serde::Deserialize<'de> for SipCallInfo { from_uri: from_uri__, to_uri: to_uri__, enabled_features: enabled_features__.unwrap_or_default(), + call_direction: call_direction__.unwrap_or_default(), call_status: call_status__.unwrap_or_default(), created_at: created_at__.unwrap_or_default(), started_at: started_at__.unwrap_or_default(), @@ -23859,6 +24404,18 @@ impl serde::Serialize for SipDispatchRuleInfo { if !self.attributes.is_empty() { len += 1; } + if !self.room_preset.is_empty() { + len += 1; + } + if self.room_config.is_some() { + len += 1; + } + if self.krisp_enabled { + len += 1; + } + if self.media_encryption != 0 { + len += 1; + } let mut struct_ser = serializer.serialize_struct("livekit.SIPDispatchRuleInfo", len)?; if !self.sip_dispatch_rule_id.is_empty() { struct_ser.serialize_field("sipDispatchRuleId", &self.sip_dispatch_rule_id)?; @@ -23884,6 +24441,20 @@ impl serde::Serialize for SipDispatchRuleInfo { if !self.attributes.is_empty() { struct_ser.serialize_field("attributes", &self.attributes)?; } + if !self.room_preset.is_empty() { + struct_ser.serialize_field("roomPreset", &self.room_preset)?; + } + if let Some(v) = self.room_config.as_ref() { + struct_ser.serialize_field("roomConfig", v)?; + } + if self.krisp_enabled { + struct_ser.serialize_field("krispEnabled", &self.krisp_enabled)?; + } + if self.media_encryption != 0 { + let v = SipMediaEncryption::try_from(self.media_encryption) + .map_err(|_| serde::ser::Error::custom(format!("Invalid variant {}", self.media_encryption)))?; + struct_ser.serialize_field("mediaEncryption", &v)?; + } struct_ser.end() } } @@ -23906,6 +24477,14 @@ impl<'de> serde::Deserialize<'de> for SipDispatchRuleInfo { "name", "metadata", "attributes", + "room_preset", + "roomPreset", + "room_config", + "roomConfig", + "krisp_enabled", + "krispEnabled", + "media_encryption", + "mediaEncryption", ]; #[allow(clippy::enum_variant_names)] @@ -23918,6 +24497,10 @@ impl<'de> serde::Deserialize<'de> for SipDispatchRuleInfo { Name, Metadata, Attributes, + RoomPreset, + RoomConfig, + KrispEnabled, + MediaEncryption, __SkipField__, } impl<'de> serde::Deserialize<'de> for GeneratedField { @@ -23948,6 +24531,10 @@ impl<'de> serde::Deserialize<'de> for SipDispatchRuleInfo { "name" => Ok(GeneratedField::Name), "metadata" => Ok(GeneratedField::Metadata), "attributes" => Ok(GeneratedField::Attributes), + "roomPreset" | "room_preset" => Ok(GeneratedField::RoomPreset), + "roomConfig" | "room_config" => Ok(GeneratedField::RoomConfig), + "krispEnabled" | "krisp_enabled" => Ok(GeneratedField::KrispEnabled), + "mediaEncryption" | "media_encryption" => Ok(GeneratedField::MediaEncryption), _ => Ok(GeneratedField::__SkipField__), } } @@ -23975,6 +24562,10 @@ impl<'de> serde::Deserialize<'de> for SipDispatchRuleInfo { let mut name__ = None; let mut metadata__ = None; let mut attributes__ = None; + let mut room_preset__ = None; + let mut room_config__ = None; + let mut krisp_enabled__ = None; + let mut media_encryption__ = None; while let Some(k) = map_.next_key()? { match k { GeneratedField::SipDispatchRuleId => { @@ -24027,6 +24618,30 @@ impl<'de> serde::Deserialize<'de> for SipDispatchRuleInfo { map_.next_value::>()? ); } + GeneratedField::RoomPreset => { + if room_preset__.is_some() { + return Err(serde::de::Error::duplicate_field("roomPreset")); + } + room_preset__ = Some(map_.next_value()?); + } + GeneratedField::RoomConfig => { + if room_config__.is_some() { + return Err(serde::de::Error::duplicate_field("roomConfig")); + } + room_config__ = 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::MediaEncryption => { + if media_encryption__.is_some() { + return Err(serde::de::Error::duplicate_field("mediaEncryption")); + } + media_encryption__ = Some(map_.next_value::()? as i32); + } GeneratedField::__SkipField__ => { let _ = map_.next_value::()?; } @@ -24041,6 +24656,10 @@ impl<'de> serde::Deserialize<'de> for SipDispatchRuleInfo { name: name__.unwrap_or_default(), metadata: metadata__.unwrap_or_default(), attributes: attributes__.unwrap_or_default(), + room_preset: room_preset__.unwrap_or_default(), + room_config: room_config__, + krisp_enabled: krisp_enabled__.unwrap_or_default(), + media_encryption: media_encryption__.unwrap_or_default(), }) } } @@ -24118,6 +24737,80 @@ impl<'de> serde::Deserialize<'de> for SipFeature { deserializer.deserialize_any(GeneratedVisitor) } } +impl serde::Serialize for SipHeaderOptions { + #[allow(deprecated)] + fn serialize(&self, serializer: S) -> std::result::Result + where + S: serde::Serializer, + { + let variant = match self { + Self::SipNoHeaders => "SIP_NO_HEADERS", + Self::SipXHeaders => "SIP_X_HEADERS", + Self::SipAllHeaders => "SIP_ALL_HEADERS", + }; + serializer.serialize_str(variant) + } +} +impl<'de> serde::Deserialize<'de> for SipHeaderOptions { + #[allow(deprecated)] + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + const FIELDS: &[&str] = &[ + "SIP_NO_HEADERS", + "SIP_X_HEADERS", + "SIP_ALL_HEADERS", + ]; + + struct GeneratedVisitor; + + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = SipHeaderOptions; + + 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 { + "SIP_NO_HEADERS" => Ok(SipHeaderOptions::SipNoHeaders), + "SIP_X_HEADERS" => Ok(SipHeaderOptions::SipXHeaders), + "SIP_ALL_HEADERS" => Ok(SipHeaderOptions::SipAllHeaders), + _ => 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 @@ -24159,6 +24852,9 @@ impl serde::Serialize for SipInboundTrunkInfo { if !self.attributes_to_headers.is_empty() { len += 1; } + if self.include_headers != 0 { + len += 1; + } if self.ringing_timeout.is_some() { len += 1; } @@ -24168,6 +24864,9 @@ impl serde::Serialize for SipInboundTrunkInfo { if self.krisp_enabled { len += 1; } + if self.media_encryption != 0 { + 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)?; @@ -24202,6 +24901,11 @@ impl serde::Serialize for SipInboundTrunkInfo { if !self.attributes_to_headers.is_empty() { struct_ser.serialize_field("attributesToHeaders", &self.attributes_to_headers)?; } + if self.include_headers != 0 { + let v = SipHeaderOptions::try_from(self.include_headers) + .map_err(|_| serde::ser::Error::custom(format!("Invalid variant {}", self.include_headers)))?; + struct_ser.serialize_field("includeHeaders", &v)?; + } if let Some(v) = self.ringing_timeout.as_ref() { struct_ser.serialize_field("ringingTimeout", v)?; } @@ -24211,6 +24915,11 @@ impl serde::Serialize for SipInboundTrunkInfo { if self.krisp_enabled { struct_ser.serialize_field("krispEnabled", &self.krisp_enabled)?; } + if self.media_encryption != 0 { + let v = SipMediaEncryption::try_from(self.media_encryption) + .map_err(|_| serde::ser::Error::custom(format!("Invalid variant {}", self.media_encryption)))?; + struct_ser.serialize_field("mediaEncryption", &v)?; + } struct_ser.end() } } @@ -24239,12 +24948,16 @@ impl<'de> serde::Deserialize<'de> for SipInboundTrunkInfo { "headersToAttributes", "attributes_to_headers", "attributesToHeaders", + "include_headers", + "includeHeaders", "ringing_timeout", "ringingTimeout", "max_call_duration", "maxCallDuration", "krisp_enabled", "krispEnabled", + "media_encryption", + "mediaEncryption", ]; #[allow(clippy::enum_variant_names)] @@ -24260,9 +24973,11 @@ impl<'de> serde::Deserialize<'de> for SipInboundTrunkInfo { Headers, HeadersToAttributes, AttributesToHeaders, + IncludeHeaders, RingingTimeout, MaxCallDuration, KrispEnabled, + MediaEncryption, __SkipField__, } impl<'de> serde::Deserialize<'de> for GeneratedField { @@ -24296,9 +25011,11 @@ impl<'de> serde::Deserialize<'de> for SipInboundTrunkInfo { "headers" => Ok(GeneratedField::Headers), "headersToAttributes" | "headers_to_attributes" => Ok(GeneratedField::HeadersToAttributes), "attributesToHeaders" | "attributes_to_headers" => Ok(GeneratedField::AttributesToHeaders), + "includeHeaders" | "include_headers" => Ok(GeneratedField::IncludeHeaders), "ringingTimeout" | "ringing_timeout" => Ok(GeneratedField::RingingTimeout), "maxCallDuration" | "max_call_duration" => Ok(GeneratedField::MaxCallDuration), "krispEnabled" | "krisp_enabled" => Ok(GeneratedField::KrispEnabled), + "mediaEncryption" | "media_encryption" => Ok(GeneratedField::MediaEncryption), _ => Ok(GeneratedField::__SkipField__), } } @@ -24329,9 +25046,11 @@ impl<'de> serde::Deserialize<'de> for SipInboundTrunkInfo { let mut headers__ = None; let mut headers_to_attributes__ = None; let mut attributes_to_headers__ = None; + let mut include_headers__ = None; let mut ringing_timeout__ = None; let mut max_call_duration__ = None; let mut krisp_enabled__ = None; + let mut media_encryption__ = None; while let Some(k) = map_.next_key()? { match k { GeneratedField::SipTrunkId => { @@ -24406,6 +25125,12 @@ impl<'de> serde::Deserialize<'de> for SipInboundTrunkInfo { map_.next_value::>()? ); } + GeneratedField::IncludeHeaders => { + if include_headers__.is_some() { + return Err(serde::de::Error::duplicate_field("includeHeaders")); + } + include_headers__ = Some(map_.next_value::()? as i32); + } GeneratedField::RingingTimeout => { if ringing_timeout__.is_some() { return Err(serde::de::Error::duplicate_field("ringingTimeout")); @@ -24424,6 +25149,12 @@ impl<'de> serde::Deserialize<'de> for SipInboundTrunkInfo { } krisp_enabled__ = Some(map_.next_value()?); } + GeneratedField::MediaEncryption => { + if media_encryption__.is_some() { + return Err(serde::de::Error::duplicate_field("mediaEncryption")); + } + media_encryption__ = Some(map_.next_value::()? as i32); + } GeneratedField::__SkipField__ => { let _ = map_.next_value::()?; } @@ -24441,15 +25172,91 @@ impl<'de> serde::Deserialize<'de> for SipInboundTrunkInfo { headers: headers__.unwrap_or_default(), headers_to_attributes: headers_to_attributes__.unwrap_or_default(), attributes_to_headers: attributes_to_headers__.unwrap_or_default(), + include_headers: include_headers__.unwrap_or_default(), ringing_timeout: ringing_timeout__, max_call_duration: max_call_duration__, krisp_enabled: krisp_enabled__.unwrap_or_default(), + media_encryption: media_encryption__.unwrap_or_default(), }) } } deserializer.deserialize_struct("livekit.SIPInboundTrunkInfo", FIELDS, GeneratedVisitor) } } +impl serde::Serialize for SipMediaEncryption { + #[allow(deprecated)] + fn serialize(&self, serializer: S) -> std::result::Result + where + S: serde::Serializer, + { + let variant = match self { + Self::SipMediaEncryptDisable => "SIP_MEDIA_ENCRYPT_DISABLE", + Self::SipMediaEncryptAllow => "SIP_MEDIA_ENCRYPT_ALLOW", + Self::SipMediaEncryptRequire => "SIP_MEDIA_ENCRYPT_REQUIRE", + }; + serializer.serialize_str(variant) + } +} +impl<'de> serde::Deserialize<'de> for SipMediaEncryption { + #[allow(deprecated)] + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + const FIELDS: &[&str] = &[ + "SIP_MEDIA_ENCRYPT_DISABLE", + "SIP_MEDIA_ENCRYPT_ALLOW", + "SIP_MEDIA_ENCRYPT_REQUIRE", + ]; + + struct GeneratedVisitor; + + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = SipMediaEncryption; + + 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 { + "SIP_MEDIA_ENCRYPT_DISABLE" => Ok(SipMediaEncryption::SipMediaEncryptDisable), + "SIP_MEDIA_ENCRYPT_ALLOW" => Ok(SipMediaEncryption::SipMediaEncryptAllow), + "SIP_MEDIA_ENCRYPT_REQUIRE" => Ok(SipMediaEncryption::SipMediaEncryptRequire), + _ => Err(serde::de::Error::unknown_variant(value, FIELDS)), + } + } + } + deserializer.deserialize_any(GeneratedVisitor) + } +} impl serde::Serialize for SipOutboundTrunkInfo { #[allow(deprecated)] fn serialize(&self, serializer: S) -> std::result::Result @@ -24491,6 +25298,12 @@ impl serde::Serialize for SipOutboundTrunkInfo { if !self.attributes_to_headers.is_empty() { len += 1; } + if self.include_headers != 0 { + len += 1; + } + if self.media_encryption != 0 { + 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)?; @@ -24527,6 +25340,16 @@ impl serde::Serialize for SipOutboundTrunkInfo { if !self.attributes_to_headers.is_empty() { struct_ser.serialize_field("attributesToHeaders", &self.attributes_to_headers)?; } + if self.include_headers != 0 { + let v = SipHeaderOptions::try_from(self.include_headers) + .map_err(|_| serde::ser::Error::custom(format!("Invalid variant {}", self.include_headers)))?; + struct_ser.serialize_field("includeHeaders", &v)?; + } + if self.media_encryption != 0 { + let v = SipMediaEncryption::try_from(self.media_encryption) + .map_err(|_| serde::ser::Error::custom(format!("Invalid variant {}", self.media_encryption)))?; + struct_ser.serialize_field("mediaEncryption", &v)?; + } struct_ser.end() } } @@ -24553,6 +25376,10 @@ impl<'de> serde::Deserialize<'de> for SipOutboundTrunkInfo { "headersToAttributes", "attributes_to_headers", "attributesToHeaders", + "include_headers", + "includeHeaders", + "media_encryption", + "mediaEncryption", ]; #[allow(clippy::enum_variant_names)] @@ -24568,6 +25395,8 @@ impl<'de> serde::Deserialize<'de> for SipOutboundTrunkInfo { Headers, HeadersToAttributes, AttributesToHeaders, + IncludeHeaders, + MediaEncryption, __SkipField__, } impl<'de> serde::Deserialize<'de> for GeneratedField { @@ -24601,6 +25430,8 @@ impl<'de> serde::Deserialize<'de> for SipOutboundTrunkInfo { "headers" => Ok(GeneratedField::Headers), "headersToAttributes" | "headers_to_attributes" => Ok(GeneratedField::HeadersToAttributes), "attributesToHeaders" | "attributes_to_headers" => Ok(GeneratedField::AttributesToHeaders), + "includeHeaders" | "include_headers" => Ok(GeneratedField::IncludeHeaders), + "mediaEncryption" | "media_encryption" => Ok(GeneratedField::MediaEncryption), _ => Ok(GeneratedField::__SkipField__), } } @@ -24631,6 +25462,8 @@ impl<'de> serde::Deserialize<'de> for SipOutboundTrunkInfo { let mut headers__ = None; let mut headers_to_attributes__ = None; let mut attributes_to_headers__ = None; + let mut include_headers__ = None; + let mut media_encryption__ = None; while let Some(k) = map_.next_key()? { match k { GeneratedField::SipTrunkId => { @@ -24705,6 +25538,18 @@ impl<'de> serde::Deserialize<'de> for SipOutboundTrunkInfo { map_.next_value::>()? ); } + GeneratedField::IncludeHeaders => { + if include_headers__.is_some() { + return Err(serde::de::Error::duplicate_field("includeHeaders")); + } + include_headers__ = Some(map_.next_value::()? as i32); + } + GeneratedField::MediaEncryption => { + if media_encryption__.is_some() { + return Err(serde::de::Error::duplicate_field("mediaEncryption")); + } + media_encryption__ = Some(map_.next_value::()? as i32); + } GeneratedField::__SkipField__ => { let _ = map_.next_value::()?; } @@ -24722,6 +25567,8 @@ impl<'de> serde::Deserialize<'de> for SipOutboundTrunkInfo { headers: headers__.unwrap_or_default(), headers_to_attributes: headers_to_attributes__.unwrap_or_default(), attributes_to_headers: attributes_to_headers__.unwrap_or_default(), + include_headers: include_headers__.unwrap_or_default(), + media_encryption: media_encryption__.unwrap_or_default(), }) } } @@ -32730,6 +33577,9 @@ impl serde::Serialize for TransferSipParticipantRequest { if self.play_dialtone { len += 1; } + if !self.headers.is_empty() { + 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)?; @@ -32743,6 +33593,9 @@ impl serde::Serialize for TransferSipParticipantRequest { if self.play_dialtone { struct_ser.serialize_field("playDialtone", &self.play_dialtone)?; } + if !self.headers.is_empty() { + struct_ser.serialize_field("headers", &self.headers)?; + } struct_ser.end() } } @@ -32761,6 +33614,7 @@ impl<'de> serde::Deserialize<'de> for TransferSipParticipantRequest { "transferTo", "play_dialtone", "playDialtone", + "headers", ]; #[allow(clippy::enum_variant_names)] @@ -32769,6 +33623,7 @@ impl<'de> serde::Deserialize<'de> for TransferSipParticipantRequest { RoomName, TransferTo, PlayDialtone, + Headers, __SkipField__, } impl<'de> serde::Deserialize<'de> for GeneratedField { @@ -32795,6 +33650,7 @@ impl<'de> serde::Deserialize<'de> for TransferSipParticipantRequest { "roomName" | "room_name" => Ok(GeneratedField::RoomName), "transferTo" | "transfer_to" => Ok(GeneratedField::TransferTo), "playDialtone" | "play_dialtone" => Ok(GeneratedField::PlayDialtone), + "headers" => Ok(GeneratedField::Headers), _ => Ok(GeneratedField::__SkipField__), } } @@ -32818,6 +33674,7 @@ impl<'de> serde::Deserialize<'de> for TransferSipParticipantRequest { let mut room_name__ = None; let mut transfer_to__ = None; let mut play_dialtone__ = None; + let mut headers__ = None; while let Some(k) = map_.next_key()? { match k { GeneratedField::ParticipantIdentity => { @@ -32844,6 +33701,14 @@ impl<'de> serde::Deserialize<'de> for TransferSipParticipantRequest { } play_dialtone__ = Some(map_.next_value()?); } + GeneratedField::Headers => { + if headers__.is_some() { + return Err(serde::de::Error::duplicate_field("headers")); + } + headers__ = Some( + map_.next_value::>()? + ); + } GeneratedField::__SkipField__ => { let _ = map_.next_value::()?; } @@ -32854,6 +33719,7 @@ impl<'de> serde::Deserialize<'de> for TransferSipParticipantRequest { room_name: room_name__.unwrap_or_default(), transfer_to: transfer_to__.unwrap_or_default(), play_dialtone: play_dialtone__.unwrap_or_default(), + headers: headers__.unwrap_or_default(), }) } } @@ -33029,6 +33895,9 @@ impl serde::Serialize for UpdateIngressRequest { if self.video.is_some() { len += 1; } + if self.enabled.is_some() { + len += 1; + } let mut struct_ser = serializer.serialize_struct("livekit.UpdateIngressRequest", len)?; if !self.ingress_id.is_empty() { struct_ser.serialize_field("ingressId", &self.ingress_id)?; @@ -33060,6 +33929,9 @@ impl serde::Serialize for UpdateIngressRequest { if let Some(v) = self.video.as_ref() { struct_ser.serialize_field("video", v)?; } + if let Some(v) = self.enabled.as_ref() { + struct_ser.serialize_field("enabled", v)?; + } struct_ser.end() } } @@ -33087,6 +33959,7 @@ impl<'de> serde::Deserialize<'de> for UpdateIngressRequest { "enableTranscoding", "audio", "video", + "enabled", ]; #[allow(clippy::enum_variant_names)] @@ -33101,6 +33974,7 @@ impl<'de> serde::Deserialize<'de> for UpdateIngressRequest { EnableTranscoding, Audio, Video, + Enabled, __SkipField__, } impl<'de> serde::Deserialize<'de> for GeneratedField { @@ -33133,6 +34007,7 @@ impl<'de> serde::Deserialize<'de> for UpdateIngressRequest { "enableTranscoding" | "enable_transcoding" => Ok(GeneratedField::EnableTranscoding), "audio" => Ok(GeneratedField::Audio), "video" => Ok(GeneratedField::Video), + "enabled" => Ok(GeneratedField::Enabled), _ => Ok(GeneratedField::__SkipField__), } } @@ -33162,6 +34037,7 @@ impl<'de> serde::Deserialize<'de> for UpdateIngressRequest { let mut enable_transcoding__ = None; let mut audio__ = None; let mut video__ = None; + let mut enabled__ = None; while let Some(k) = map_.next_key()? { match k { GeneratedField::IngressId => { @@ -33224,6 +34100,12 @@ impl<'de> serde::Deserialize<'de> for UpdateIngressRequest { } video__ = map_.next_value()?; } + GeneratedField::Enabled => { + if enabled__.is_some() { + return Err(serde::de::Error::duplicate_field("enabled")); + } + enabled__ = map_.next_value()?; + } GeneratedField::__SkipField__ => { let _ = map_.next_value::()?; } @@ -33240,6 +34122,7 @@ impl<'de> serde::Deserialize<'de> for UpdateIngressRequest { enable_transcoding: enable_transcoding__, audio: audio__, video: video__, + enabled: enabled__, }) } } From 12e7ca4184200dbb65126f2db95729a0ab423586 Mon Sep 17 00:00:00 2001 From: Daisuke Murase Date: Wed, 15 Jan 2025 06:31:16 -0800 Subject: [PATCH 3/8] add default value for now to newly introduced properties in protocol 1.31.0 --- livekit-api/src/services/ingress.rs | 2 ++ livekit-api/src/services/sip.rs | 39 ++++++++++++++++++++++++++--- 2 files changed, 37 insertions(+), 4 deletions(-) diff --git a/livekit-api/src/services/ingress.rs b/livekit-api/src/services/ingress.rs index e46463f82..8e32fa334 100644 --- a/livekit-api/src/services/ingress.rs +++ b/livekit-api/src/services/ingress.rs @@ -93,6 +93,7 @@ impl IngressClient { bypass_transcoding: options.bypass_transcoding, enable_transcoding: options.enable_transcoding, url: options.url, + enabled: Default::default(), // TODO: support this attribute }, self.base .auth_header(VideoGrants { ingress_admin: true, ..Default::default() }, None)?, @@ -121,6 +122,7 @@ impl IngressClient { video: Some(options.video), bypass_transcoding: options.bypass_transcoding, enable_transcoding: options.enable_transcoding, + enabled: Default::default(), // TODO: support this attribute }, self.base .auth_header(VideoGrants { ingress_admin: true, ..Default::default() }, None)?, diff --git a/livekit-api/src/services/sip.rs b/livekit-api/src/services/sip.rs index aca2d11e9..d8a2b982d 100644 --- a/livekit-api/src/services/sip.rs +++ b/livekit-api/src/services/sip.rs @@ -191,6 +191,10 @@ impl SIPClient { krisp_enabled: options.krisp_enabled.unwrap_or(false), max_call_duration: Self::duration_to_proto(options.max_call_duration), ringing_timeout: Self::duration_to_proto(options.ringing_timeout), + + // TODO: support these attributes + include_headers: Default::default(), + media_encryption: Default::default(), }), }, self.base.auth_header( @@ -228,6 +232,10 @@ impl SIPClient { headers: options.headers.unwrap_or_default(), headers_to_attributes: options.headers_to_attributes.unwrap_or_default(), attributes_to_headers: options.attributes_to_headers.unwrap_or_default(), + + // TODO: support these attributes + include_headers: Default::default(), + media_encryption: Default::default(), }), }, self.base.auth_header( @@ -269,7 +277,11 @@ impl SIPClient { .request( SVC, "ListSIPInboundTrunk", - proto::ListSipInboundTrunkRequest {}, + proto::ListSipInboundTrunkRequest { + // TODO: support these attributes + trunk_ids: Default::default(), + numbers: Default::default(), + }, self.base.auth_header( Default::default(), Some(SIPGrants { admin: true, ..Default::default() }), @@ -289,7 +301,11 @@ impl SIPClient { .request( SVC, "ListSIPOutboundTrunk", - proto::ListSipOutboundTrunkRequest {}, + proto::ListSipOutboundTrunkRequest { + // TODO: support these attributes + trunk_ids: Default::default(), + numbers: Default::default(), + }, self.base.auth_header( Default::default(), Some(SIPGrants { admin: true, ..Default::default() }), @@ -332,6 +348,10 @@ impl SIPClient { inbound_numbers: options.allowed_numbers.to_owned(), hide_phone_number: options.hide_phone_number, rule: Some(proto::SipDispatchRule { rule: Some(rule.to_owned()) }), + + // TODO: support these attributes + room_preset: Default::default(), + room_config: Default::default(), }, self.base.auth_header( Default::default(), @@ -351,7 +371,11 @@ impl SIPClient { .request( SVC, "ListSIPDispatchRule", - proto::ListSipDispatchRuleRequest {}, + proto::ListSipDispatchRuleRequest { + // TODO: support these attributes + dispatch_rule_ids: Default::default(), + trunk_ids: Default::default(), + }, self.base.auth_header( Default::default(), Some(SIPGrants { admin: true, ..Default::default() }), @@ -414,7 +438,14 @@ impl SIPClient { hide_phone_number: options.hide_phone_number.unwrap_or(false), max_call_duration: Self::duration_to_proto(options.max_call_duration), ringing_timeout: Self::duration_to_proto(options.ringing_timeout), - enable_krisp: options.enable_krisp.unwrap_or(false), + + // TODO: rename local proto as well + krisp_enabled: options.enable_krisp.unwrap_or(false), + + // TODO: support these attributes + headers: Default::default(), + include_headers: Default::default(), + media_encryption: Default::default(), }, self.base.auth_header( Default::default(), From 503301bdb7930d63908debd7ed4a9c2cf14ea4a4 Mon Sep 17 00:00:00 2001 From: Daisuke Murase Date: Wed, 15 Jan 2025 06:45:15 -0800 Subject: [PATCH 4/8] update DataStream Header proto to align with changes in the livekit-protocol --- livekit-ffi/protocol/room.proto | 7 +++---- livekit-ffi/src/conversion/room.rs | 3 --- livekit-ffi/src/livekit.proto.rs | 7 ++----- 3 files changed, 5 insertions(+), 12 deletions(-) diff --git a/livekit-ffi/protocol/room.proto b/livekit-ffi/protocol/room.proto index 90f14089b..bc1cda5c5 100644 --- a/livekit-ffi/protocol/room.proto +++ b/livekit-ffi/protocol/room.proto @@ -573,9 +573,8 @@ message DataStream { 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) - optional bool complete = 4; // true only if this is the last chunk of this stream - can also be sent with empty content - optional 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 + optional int32 version = 4; // a version indicating that this chunk_index has been retroactively modified and the original one needs to be replaced + optional bytes iv = 5; // optional, initialization vector for AES-GCM encryption } } @@ -619,4 +618,4 @@ message SendStreamHeaderCallback { message SendStreamChunkCallback { required uint64 async_id = 1; optional string error = 2; -} \ No newline at end of file +} diff --git a/livekit-ffi/src/conversion/room.rs b/livekit-ffi/src/conversion/room.rs index 42479342f..0f5a0a9b6 100644 --- a/livekit-ffi/src/conversion/room.rs +++ b/livekit-ffi/src/conversion/room.rs @@ -344,7 +344,6 @@ impl From for livekit_protocol::data_stream::Header topic: msg.topic, mime_type: msg.mime_type, total_length: msg.total_length, - total_chunks: None, extensions: msg.extensions, content_header, encryption_type: 0, @@ -357,7 +356,6 @@ impl From for proto::data_stream::Chunk { proto::data_stream::Chunk { stream_id: msg.stream_id, content: msg.content, - complete: Some(msg.complete), chunk_index: msg.chunk_index, version: Some(msg.version), iv: msg.iv, @@ -370,7 +368,6 @@ impl From for livekit_protocol::data_stream::Chunk { livekit_protocol::data_stream::Chunk { stream_id: msg.stream_id, content: msg.content, - complete: msg.complete.unwrap_or(false), chunk_index: msg.chunk_index, version: msg.version.unwrap_or(0), iv: msg.iv, diff --git a/livekit-ffi/src/livekit.proto.rs b/livekit-ffi/src/livekit.proto.rs index 13b495481..e19041c7d 100644 --- a/livekit-ffi/src/livekit.proto.rs +++ b/livekit-ffi/src/livekit.proto.rs @@ -3059,14 +3059,11 @@ pub mod data_stream { /// 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, optional, tag="4")] - pub complete: ::core::option::Option, /// a version indicating that this chunk_index has been retroactively modified and the original one needs to be replaced - #[prost(int32, optional, tag="5")] + #[prost(int32, optional, tag="4")] pub version: ::core::option::Option, /// optional, initialization vector for AES-GCM encryption - #[prost(bytes="vec", optional, tag="6")] + #[prost(bytes="vec", optional, tag="5")] pub iv: ::core::option::Option<::prost::alloc::vec::Vec>, } /// enum for operation types (specific to TextHeader) From 26cffcbe93f2ca2b6196d389da5b26cbe20a9448 Mon Sep 17 00:00:00 2001 From: Daisuke Murase Date: Wed, 15 Jan 2025 08:21:06 -0800 Subject: [PATCH 5/8] implement data stream tailer in ffi --- Cargo.lock | 4 +-- livekit-ffi/protocol/ffi.proto | 10 +++--- livekit-ffi/protocol/room.proto | 22 +++++++++++++ livekit-ffi/src/conversion/room.rs | 12 +++++++ livekit-ffi/src/livekit.proto.rs | 51 ++++++++++++++++++++++++++++-- livekit-ffi/src/server/requests.rs | 15 +++++++++ livekit-ffi/src/server/room.rs | 28 ++++++++++++++++ 7 files changed, 133 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7fc649ecd..b0532c222 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1593,7 +1593,7 @@ checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456" [[package]] name = "livekit" -version = "0.7.1" +version = "0.7.2" dependencies = [ "chrono", "futures-util", @@ -1641,7 +1641,7 @@ dependencies = [ [[package]] name = "livekit-ffi" -version = "0.12.4" +version = "0.12.6" dependencies = [ "console-subscriber", "dashmap", diff --git a/livekit-ffi/protocol/ffi.proto b/livekit-ffi/protocol/ffi.proto index 8c715bbf1..daf69f83f 100644 --- a/livekit-ffi/protocol/ffi.proto +++ b/livekit-ffi/protocol/ffi.proto @@ -115,7 +115,7 @@ message FfiRequest { // Data Streams SendStreamHeaderRequest send_stream_header = 44; SendStreamChunkRequest send_stream_chunk = 45; - + SendStreamTrailerRequest send_stream_trailer = 46; } } @@ -174,9 +174,10 @@ message FfiResponse { EnableRemoteTrackPublicationResponse enable_remote_track_publication = 41; UpdateRemoteTrackPublicationDimensionResponse update_remote_track_publication_dimension = 42; - // Data Streams - SendStreamHeaderResponse send_stream_header = 43; - SendStreamChunkResponse send_stream_chunk = 44; + // Data Streams + SendStreamHeaderResponse send_stream_header = 43; + SendStreamChunkResponse send_stream_chunk = 44; + SendStreamTrailerResponse send_stream_trailer = 45; } } @@ -210,6 +211,7 @@ message FfiEvent { RpcMethodInvocationEvent rpc_method_invocation = 24; SendStreamHeaderCallback send_stream_header = 25; SendStreamChunkCallback send_stream_chunk = 26; + SendStreamTrailerCallback send_stream_trailer = 27; } } diff --git a/livekit-ffi/protocol/room.proto b/livekit-ffi/protocol/room.proto index bc1cda5c5..9baf4bc7d 100644 --- a/livekit-ffi/protocol/room.proto +++ b/livekit-ffi/protocol/room.proto @@ -576,6 +576,12 @@ message DataStream { optional int32 version = 4; // a version indicating that this chunk_index has been retroactively modified and the original one needs to be replaced optional bytes iv = 5; // optional, initialization vector for AES-GCM encryption } + + message Trailer { + required string stream_id = 1; // unique identifier for this data stream + required string reason = 2; // reason why the stream was closed (could contain "error" / "interrupted" / empty for expected end) + map extensions = 3; // finalizing updates for the stream, can also include additional insights for errors or endTime for transcription + } } message DataStreamHeaderReceived { @@ -602,6 +608,13 @@ message SendStreamChunkRequest { optional string sender_identity = 4; } +message SendStreamTrailerRequest { + required uint64 local_participant_handle = 1; + required DataStream.Trailer trailer = 2; + repeated string destination_identities = 3; + optional string sender_identity = 4; +} + message SendStreamHeaderResponse { required uint64 async_id = 1; } @@ -610,6 +623,10 @@ message SendStreamChunkResponse { required uint64 async_id = 1; } +message SendStreamTrailerResponse { + required uint64 async_id = 1; +} + message SendStreamHeaderCallback { required uint64 async_id = 1; optional string error = 2; @@ -619,3 +636,8 @@ message SendStreamChunkCallback { required uint64 async_id = 1; optional string error = 2; } + +message SendStreamTrailerCallback { + required uint64 async_id = 1; + optional string error = 2; +} diff --git a/livekit-ffi/src/conversion/room.rs b/livekit-ffi/src/conversion/room.rs index 0f5a0a9b6..260c280a8 100644 --- a/livekit-ffi/src/conversion/room.rs +++ b/livekit-ffi/src/conversion/room.rs @@ -374,3 +374,15 @@ impl From for livekit_protocol::data_stream::Chunk { } } } + +impl From for proto::data_stream::Trailer { + fn from(msg: livekit_protocol::data_stream::Trailer) -> Self { + Self { stream_id: msg.stream_id, reason: msg.reason, extensions: msg.extensions } + } +} + +impl From for livekit_protocol::data_stream::Trailer { + fn from(msg: proto::data_stream::Trailer) -> Self { + Self { stream_id: msg.stream_id, reason: msg.reason, extensions: msg.extensions } + } +} diff --git a/livekit-ffi/src/livekit.proto.rs b/livekit-ffi/src/livekit.proto.rs index e19041c7d..6487add2d 100644 --- a/livekit-ffi/src/livekit.proto.rs +++ b/livekit-ffi/src/livekit.proto.rs @@ -3066,6 +3066,19 @@ pub mod data_stream { #[prost(bytes="vec", optional, tag="5")] pub iv: ::core::option::Option<::prost::alloc::vec::Vec>, } + #[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] + pub struct Trailer { + /// unique identifier for this data stream + #[prost(string, required, tag="1")] + pub stream_id: ::prost::alloc::string::String, + /// reason why the stream was closed (could contain "error" / "interrupted" / empty for expected end) + #[prost(string, required, tag="2")] + pub reason: ::prost::alloc::string::String, + /// finalizing updates for the stream, can also include additional insights for errors or endTime for transcription + #[prost(map="string, string", tag="3")] + pub extensions: ::std::collections::HashMap<::prost::alloc::string::String, ::prost::alloc::string::String>, + } /// enum for operation types (specific to TextHeader) #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] #[repr(i32)] @@ -3142,6 +3155,18 @@ pub struct SendStreamChunkRequest { } #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] +pub struct SendStreamTrailerRequest { + #[prost(uint64, required, tag="1")] + pub local_participant_handle: u64, + #[prost(message, required, tag="2")] + pub trailer: data_stream::Trailer, + #[prost(string, repeated, tag="3")] + pub destination_identities: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, + #[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 SendStreamHeaderResponse { #[prost(uint64, required, tag="1")] pub async_id: u64, @@ -3154,6 +3179,12 @@ pub struct SendStreamChunkResponse { } #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] +pub struct SendStreamTrailerResponse { + #[prost(uint64, required, tag="1")] + pub async_id: u64, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct SendStreamHeaderCallback { #[prost(uint64, required, tag="1")] pub async_id: u64, @@ -3168,6 +3199,14 @@ pub struct SendStreamChunkCallback { #[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 SendStreamTrailerCallback { + #[prost(uint64, required, tag="1")] + pub async_id: u64, + #[prost(string, optional, tag="2")] + pub error: ::core::option::Option<::prost::alloc::string::String>, +} #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] #[repr(i32)] pub enum IceTransportType { @@ -3940,7 +3979,7 @@ pub struct RpcMethodInvocationEvent { #[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, 44, 45")] + #[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, 44, 45, 46")] pub message: ::core::option::Option, } /// Nested message and enum types in `FfiRequest`. @@ -4043,13 +4082,15 @@ pub mod ffi_request { SendStreamHeader(super::SendStreamHeaderRequest), #[prost(message, tag="45")] SendStreamChunk(super::SendStreamChunkRequest), + #[prost(message, tag="46")] + SendStreamTrailer(super::SendStreamTrailerRequest), } } /// 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, 43, 44")] + #[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, 43, 44, 45")] pub message: ::core::option::Option, } /// Nested message and enum types in `FfiResponse`. @@ -4150,6 +4191,8 @@ pub mod ffi_response { SendStreamHeader(super::SendStreamHeaderResponse), #[prost(message, tag="44")] SendStreamChunk(super::SendStreamChunkResponse), + #[prost(message, tag="45")] + SendStreamTrailer(super::SendStreamTrailerResponse), } } /// To minimize complexity, participant events are not included in the protocol. @@ -4158,7 +4201,7 @@ pub mod ffi_response { #[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, 25, 26")] + #[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, 25, 26, 27")] pub message: ::core::option::Option, } /// Nested message and enum types in `FfiEvent`. @@ -4216,6 +4259,8 @@ pub mod ffi_event { SendStreamHeader(super::SendStreamHeaderCallback), #[prost(message, tag="26")] SendStreamChunk(super::SendStreamChunkCallback), + #[prost(message, tag="27")] + SendStreamTrailer(super::SendStreamTrailerCallback), } } /// Stop all rooms synchronously (Do we need async here?). diff --git a/livekit-ffi/src/server/requests.rs b/livekit-ffi/src/server/requests.rs index 16739361c..a002a67ba 100644 --- a/livekit-ffi/src/server/requests.rs +++ b/livekit-ffi/src/server/requests.rs @@ -258,6 +258,16 @@ fn on_send_stream_chunk( Ok(ffi_participant.room.send_stream_chunk(server, stream_chunk_message)) } +fn on_send_stream_trailer( + server: &'static FfiServer, + stream_trailer_message: proto::SendStreamTrailerRequest, +) -> FfiResult { + let ffi_participant = server + .retrieve_handle::(stream_trailer_message.local_participant_handle)? + .clone(); + Ok(ffi_participant.room.send_stream_trailer(server, stream_trailer_message)) +} + /// Create a new video track from a source fn on_create_video_track( server: &'static FfiServer, @@ -1063,6 +1073,11 @@ pub fn handle_request( proto::ffi_request::Message::SendStreamChunk(request) => { proto::ffi_response::Message::SendStreamChunk(on_send_stream_chunk(server, request)?) } + proto::ffi_request::Message::SendStreamTrailer(request) => { + proto::ffi_response::Message::SendStreamTrailer(on_send_stream_trailer( + server, request, + )?) + } }); Ok(res) diff --git a/livekit-ffi/src/server/room.rs b/livekit-ffi/src/server/room.rs index 75fbfa769..d88506e5b 100644 --- a/livekit-ffi/src/server/room.rs +++ b/livekit-ffi/src/server/room.rs @@ -732,6 +732,34 @@ impl RoomInner { proto::SendStreamChunkResponse { async_id } } + pub fn send_stream_trailer( + self: &Arc, + server: &'static FfiServer, + send_stream_trailer: proto::SendStreamTrailerRequest, + ) -> proto::SendStreamTrailerResponse { + let packet = lk_proto::DataPacket { + kind: proto::DataPacketKind::KindReliable.into(), + participant_identity: send_stream_trailer.sender_identity.unwrap(), + destination_identities: send_stream_trailer.destination_identities, + value: livekit_protocol::data_packet::Value::StreamTrailer( + send_stream_trailer.trailer.into(), + ) + .into(), + }; + let async_id = server.next_id(); + let inner = self.clone(); + let handle = server.async_runtime.spawn(async move { + let res = inner.room.local_participant().publish_raw_data(packet, true).await; + let cb = proto::SendStreamTrailerCallback { + async_id, + error: res.err().map(|e| e.to_string()), + }; + let _ = server.send_event(proto::ffi_event::Message::SendStreamTrailer(cb)); + }); + server.watch_panic(handle); + proto::SendStreamTrailerResponse { async_id } + } + pub fn store_rpc_method_invocation_waiter( &self, invocation_id: u64, From f56e36761bcb78c9531ef7ff7ebba4faf290cbc3 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 15 Jan 2025 16:29:51 +0000 Subject: [PATCH 6/8] generated protobuf --- livekit-protocol/src/livekit.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/livekit-protocol/src/livekit.rs b/livekit-protocol/src/livekit.rs index 901a3f2d6..73f358d0a 100644 --- a/livekit-protocol/src/livekit.rs +++ b/livekit-protocol/src/livekit.rs @@ -1,4 +1,5 @@ // @generated +// This file is @generated by prost-build. #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct MetricsBatch { From bb273c3a3f7d6aaf1c70d8f58b96e37ad6852edc Mon Sep 17 00:00:00 2001 From: Daisuke Murase Date: Wed, 15 Jan 2025 08:29:57 -0800 Subject: [PATCH 7/8] add nanpa changeset --- .nanpa/data-stream-trailer.kdl | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .nanpa/data-stream-trailer.kdl diff --git a/.nanpa/data-stream-trailer.kdl b/.nanpa/data-stream-trailer.kdl new file mode 100644 index 000000000..84706c57a --- /dev/null +++ b/.nanpa/data-stream-trailer.kdl @@ -0,0 +1,2 @@ +patch type="changed" package="livekit-protocol" "Update protocol version to v1.31.0" +patch type="added" package="livekit-ffi" "Add DataStream.Trailer support" From cd126a37184905285c02203f43f4294ce7a172bd Mon Sep 17 00:00:00 2001 From: Daisuke Murase Date: Wed, 15 Jan 2025 10:05:27 -0800 Subject: [PATCH 8/8] make sender_identity required --- livekit-ffi/protocol/room.proto | 6 +++--- livekit-ffi/src/livekit.proto.rs | 13 ++++++------- livekit-ffi/src/server/room.rs | 6 +++--- 3 files changed, 12 insertions(+), 13 deletions(-) diff --git a/livekit-ffi/protocol/room.proto b/livekit-ffi/protocol/room.proto index 9baf4bc7d..f1d68e5c4 100644 --- a/livekit-ffi/protocol/room.proto +++ b/livekit-ffi/protocol/room.proto @@ -598,21 +598,21 @@ message SendStreamHeaderRequest { required uint64 local_participant_handle = 1; required DataStream.Header header = 2; repeated string destination_identities = 3; - optional string sender_identity = 4; + required string sender_identity = 4; } message SendStreamChunkRequest { required uint64 local_participant_handle = 1; required DataStream.Chunk chunk = 2; repeated string destination_identities = 3; - optional string sender_identity = 4; + required string sender_identity = 4; } message SendStreamTrailerRequest { required uint64 local_participant_handle = 1; required DataStream.Trailer trailer = 2; repeated string destination_identities = 3; - optional string sender_identity = 4; + required string sender_identity = 4; } message SendStreamHeaderResponse { diff --git a/livekit-ffi/src/livekit.proto.rs b/livekit-ffi/src/livekit.proto.rs index 6487add2d..f987e3b4f 100644 --- a/livekit-ffi/src/livekit.proto.rs +++ b/livekit-ffi/src/livekit.proto.rs @@ -1,5 +1,4 @@ // @generated -// This file is @generated by prost-build. #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct FrameCryptor { @@ -3138,8 +3137,8 @@ pub struct SendStreamHeaderRequest { pub header: data_stream::Header, #[prost(string, repeated, tag="3")] pub destination_identities: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, - #[prost(string, optional, tag="4")] - pub sender_identity: ::core::option::Option<::prost::alloc::string::String>, + #[prost(string, required, tag="4")] + pub sender_identity: ::prost::alloc::string::String, } #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] @@ -3150,8 +3149,8 @@ pub struct SendStreamChunkRequest { pub chunk: data_stream::Chunk, #[prost(string, repeated, tag="3")] pub destination_identities: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, - #[prost(string, optional, tag="4")] - pub sender_identity: ::core::option::Option<::prost::alloc::string::String>, + #[prost(string, required, tag="4")] + pub sender_identity: ::prost::alloc::string::String, } #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] @@ -3162,8 +3161,8 @@ pub struct SendStreamTrailerRequest { pub trailer: data_stream::Trailer, #[prost(string, repeated, tag="3")] pub destination_identities: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, - #[prost(string, optional, tag="4")] - pub sender_identity: ::core::option::Option<::prost::alloc::string::String>, + #[prost(string, required, tag="4")] + pub sender_identity: ::prost::alloc::string::String, } #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] diff --git a/livekit-ffi/src/server/room.rs b/livekit-ffi/src/server/room.rs index d88506e5b..61d32161b 100644 --- a/livekit-ffi/src/server/room.rs +++ b/livekit-ffi/src/server/room.rs @@ -682,7 +682,7 @@ impl RoomInner { ) -> proto::SendStreamHeaderResponse { let packet = lk_proto::DataPacket { kind: proto::DataPacketKind::KindReliable.into(), - participant_identity: send_stream_header.sender_identity.unwrap(), + participant_identity: send_stream_header.sender_identity, destination_identities: send_stream_header.destination_identities, value: livekit_protocol::data_packet::Value::StreamHeader( send_stream_header.header.into(), @@ -710,7 +710,7 @@ impl RoomInner { ) -> proto::SendStreamChunkResponse { let packet = lk_proto::DataPacket { kind: proto::DataPacketKind::KindReliable.into(), - participant_identity: send_stream_chunk.sender_identity.unwrap(), + participant_identity: send_stream_chunk.sender_identity, destination_identities: send_stream_chunk.destination_identities, value: livekit_protocol::data_packet::Value::StreamChunk( send_stream_chunk.chunk.into(), @@ -739,7 +739,7 @@ impl RoomInner { ) -> proto::SendStreamTrailerResponse { let packet = lk_proto::DataPacket { kind: proto::DataPacketKind::KindReliable.into(), - participant_identity: send_stream_trailer.sender_identity.unwrap(), + participant_identity: send_stream_trailer.sender_identity, destination_identities: send_stream_trailer.destination_identities, value: livekit_protocol::data_packet::Value::StreamTrailer( send_stream_trailer.trailer.into(),