diff --git a/.changes/encrypted-dc b/.changes/encrypted-dc new file mode 100644 index 000000000..19839d00a --- /dev/null +++ b/.changes/encrypted-dc @@ -0,0 +1 @@ +minor type="added" "Added support for data channel encryption, deprecated existing E2EE options" diff --git a/Package.swift b/Package.swift index 2c12b8f73..204fd64d7 100644 --- a/Package.swift +++ b/Package.swift @@ -20,7 +20,7 @@ let package = Package( dependencies: [ // LK-Prefixed Dynamic WebRTC XCFramework .package(url: "https://github.com/livekit/webrtc-xcframework.git", exact: "137.7151.09"), - .package(url: "https://github.com/apple/swift-protobuf.git", from: "1.29.0"), + .package(url: "https://github.com/apple/swift-protobuf.git", from: "1.31.0"), .package(url: "https://github.com/apple/swift-log.git", from: "1.6.2"), .package(url: "https://github.com/apple/swift-collections.git", from: "1.1.0"), // Only used for DocC generation diff --git a/Package@swift-6.0.swift b/Package@swift-6.0.swift index c79897953..a58ef7957 100644 --- a/Package@swift-6.0.swift +++ b/Package@swift-6.0.swift @@ -21,7 +21,7 @@ let package = Package( dependencies: [ // LK-Prefixed Dynamic WebRTC XCFramework .package(url: "https://github.com/livekit/webrtc-xcframework.git", exact: "137.7151.09"), - .package(url: "https://github.com/apple/swift-protobuf.git", from: "1.29.0"), + .package(url: "https://github.com/apple/swift-protobuf.git", from: "1.31.0"), .package(url: "https://github.com/apple/swift-log.git", from: "1.6.2"), .package(url: "https://github.com/apple/swift-collections.git", from: "1.1.0"), // Only used for DocC generation diff --git a/Sources/LiveKit/Core/DataChannelPair.swift b/Sources/LiveKit/Core/DataChannelPair.swift index e35cfc772..1c3ad01d9 100644 --- a/Sources/LiveKit/Core/DataChannelPair.swift +++ b/Sources/LiveKit/Core/DataChannelPair.swift @@ -23,6 +23,7 @@ internal import LiveKitWebRTC protocol DataChannelDelegate: Sendable { func dataChannel(_ dataChannelPair: DataChannelPair, didReceiveDataPacket dataPacket: Livekit_DataPacket) + func dataChannel(_ dataChannelPair: DataChannelPair, didFailToDecryptDataPacket dataPacket: Livekit_DataPacket, error: LiveKitError) } class DataChannelPair: NSObject, @unchecked Sendable, Loggable { @@ -34,6 +35,8 @@ class DataChannelPair: NSObject, @unchecked Sendable, Loggable { var isOpen: Bool { _state.isOpen } + var e2eeManager: E2EEManager? + // MARK: - Private private struct State { @@ -87,7 +90,7 @@ class DataChannelPair: NSObject, @unchecked Sendable, Loggable { func peek() -> PublishDataRequest? { queue.first } mutating func enqueue(_ request: PublishDataRequest) { - queue.append(request) + queue.append(request.withoutContinuation()) currentAmount += UInt64(request.data.data.count) } @@ -110,6 +113,10 @@ class DataChannelPair: NSObject, @unchecked Sendable, Loggable { let data: LKRTCDataBuffer let sequence: UInt32 let continuation: CheckedContinuation? + + func withoutContinuation() -> Self { + .init(data: data, sequence: sequence, continuation: nil) + } } private struct ChannelEvent: Sendable { @@ -234,8 +241,9 @@ class DataChannelPair: NSObject, @unchecked Sendable, Loggable { log("Wrong packet sequence while retrying: \(first.sequence) > \(lastSeq + 1), \(first.sequence - lastSeq - 1) packets missing", .warning) } while let request = buffer.dequeue() { + assert(request.continuation == nil, "Continuation may fire multiple times while retrying causing crash") if request.sequence > lastSeq { - let event = ChannelEvent(channelKind: .reliable, detail: .publishData(PublishDataRequest(data: request.data, sequence: request.sequence, continuation: nil))) + let event = ChannelEvent(channelKind: .reliable, detail: .publishData(request)) _state.eventContinuation?.yield(event) } } @@ -315,7 +323,7 @@ class DataChannelPair: NSObject, @unchecked Sendable, Loggable { } func send(dataPacket packet: Livekit_DataPacket) async throws { - let packet = withSequence(packet) + let packet = try withEncryption(withSequence(packet)) let serializedData = try packet.serializedData() let rtcData = RTC.createDataBuffer(data: serializedData) @@ -333,6 +341,20 @@ class DataChannelPair: NSObject, @unchecked Sendable, Loggable { } } + private func withEncryption(_ packet: Livekit_DataPacket) throws -> Livekit_DataPacket { + guard let e2eeManager, e2eeManager.isDataChannelEncryptionEnabled, + let payload = Livekit_EncryptedPacketPayload(dataPacket: packet) else { return packet } + var packet = packet + do { + let payloadData = try payload.serializedData() + let rtcEncryptedPacket = try e2eeManager.encrypt(data: payloadData) + packet.encryptedPacket = Livekit_EncryptedPacket(rtcPacket: rtcEncryptedPacket) + } catch { + throw LiveKitError(.encryptionFailed, internalError: error) + } + return packet + } + private func withSequence(_ packet: Livekit_DataPacket) -> Livekit_DataPacket { guard packet.kind == .reliable, packet.sequence == 0 else { return packet } var packet = packet @@ -413,8 +435,29 @@ extension DataChannelPair: LKRTCDataChannelDelegate { } } - delegates.notify { - $0.dataChannel(self, didReceiveDataPacket: dataPacket) + if let encryptedPacket = dataPacket.encryptedPacketOrNil, + let e2eeManager + { + do { + let decryptedData = try e2eeManager.handle(encryptedData: encryptedPacket.toRTCEncryptedPacket(), participantIdentity: dataPacket.participantIdentity) + let decryptedPayload = try Livekit_EncryptedPacketPayload(serializedBytes: decryptedData) + + var dataPacket = dataPacket + decryptedPayload.applyTo(&dataPacket) + + delegates.notify { [dataPacket] in + $0.dataChannel(self, didReceiveDataPacket: dataPacket) + } + } catch { + log("Failed to decrypt data packet: \(error)", .error) + delegates.notify { + $0.dataChannel(self, didFailToDecryptDataPacket: dataPacket, error: LiveKitError(.decryptionFailed, internalError: error)) + } + } + } else { + delegates.notify { + $0.dataChannel(self, didReceiveDataPacket: dataPacket) + } } } } diff --git a/Sources/LiveKit/Core/Room+EngineDelegate.swift b/Sources/LiveKit/Core/Room+EngineDelegate.swift index ab4596d4c..8f32b4cbb 100644 --- a/Sources/LiveKit/Core/Room+EngineDelegate.swift +++ b/Sources/LiveKit/Core/Room+EngineDelegate.swift @@ -180,20 +180,20 @@ extension Room { await publication.set(track: nil) } - func engine(_ engine: Room, didReceiveUserPacket packet: Livekit_UserPacket) { + func engine(_ engine: Room, didReceiveUserPacket packet: Livekit_UserPacket, encryptionType: EncryptionType) { // participant could be null if data broadcasted from server let identity = Participant.Identity(from: packet.participantIdentity) let participant = _state.remoteParticipants[identity] if case .connected = engine._state.connectionState { delegates.notify(label: { "room.didReceive data: \(packet.payload)" }) { - $0.room?(self, participant: participant, didReceiveData: packet.payload, forTopic: packet.topic) + $0.room?(self, participant: participant, didReceiveData: packet.payload, forTopic: packet.topic, encryptionType: encryptionType) } if let participant { participant.delegates.notify(label: { "participant.didReceive data: \(packet.payload)" }) { [weak participant] delegate in guard let participant else { return } - delegate.participant?(participant, didReceiveData: packet.payload, forTopic: packet.topic) + delegate.participant?(participant, didReceiveData: packet.payload, forTopic: packet.topic, encryptionType: encryptionType) } } } diff --git a/Sources/LiveKit/Core/Room.swift b/Sources/LiveKit/Core/Room.swift index fedd93db9..ba1b4de46 100644 --- a/Sources/LiveKit/Core/Room.swift +++ b/Sources/LiveKit/Core/Room.swift @@ -120,6 +120,8 @@ public class Room: NSObject, @unchecked Sendable, ObservableObject, Loggable { let incomingStreamManager = IncomingStreamManager() lazy var outgoingStreamManager = OutgoingStreamManager { [weak self] packet in try await self?.send(dataPacket: packet) + } encryptionProvider: { [weak self] in + self?.e2eeManager?.dataChannelEncryptionType ?? .none } // MARK: - PreConnect @@ -340,15 +342,26 @@ public class Room: NSObject, @unchecked Sendable, ObservableObject, Loggable { _state.mutate { $0.connectOptions = connectOptions } } + await cleanUp() + + try Task.checkCancellation() + // enable E2EE if let e2eeOptions = state.roomOptions.e2eeOptions { e2eeManager = E2EEManager(e2eeOptions: e2eeOptions) e2eeManager!.setup(room: self) - } + } else if let encryptionOptions = state.roomOptions.encryptionOptions { + e2eeManager = E2EEManager(options: encryptionOptions) + e2eeManager!.setup(room: self) - await cleanUp() + subscriberDataChannel.e2eeManager = e2eeManager + publisherDataChannel.e2eeManager = e2eeManager + } else { + e2eeManager = nil - try Task.checkCancellation() + subscriberDataChannel.e2eeManager = nil + publisherDataChannel.e2eeManager = nil + } _state.mutate { $0.connectionState = .connecting } @@ -620,15 +633,21 @@ extension Room: DataChannelDelegate { func dataChannel(_: DataChannelPair, didReceiveDataPacket dataPacket: Livekit_DataPacket) { switch dataPacket.value { case let .speaker(update): engine(self, didUpdateSpeakers: update.speakers) - case let .user(userPacket): engine(self, didReceiveUserPacket: userPacket) + case let .user(userPacket): engine(self, didReceiveUserPacket: userPacket, encryptionType: dataPacket.encryptedPacket.encryptionType.toLKType()) case let .transcription(packet): room(didReceiveTranscriptionPacket: packet) case let .rpcResponse(response): room(didReceiveRpcResponse: response) case let .rpcAck(ack): room(didReceiveRpcAck: ack) case let .rpcRequest(request): room(didReceiveRpcRequest: request, from: dataPacket.participantIdentity) - case let .streamHeader(header): Task { await incomingStreamManager.handle(header: header, from: dataPacket.participantIdentity) } - case let .streamChunk(chunk): Task { await incomingStreamManager.handle(chunk: chunk) } - case let .streamTrailer(trailer): Task { await incomingStreamManager.handle(trailer: trailer) } + case let .streamHeader(header): Task { await incomingStreamManager.handle(header: header, from: dataPacket.participantIdentity, encryptionType: dataPacket.encryptedPacket.encryptionType.toLKType()) } + case let .streamChunk(chunk): Task { await incomingStreamManager.handle(chunk: chunk, encryptionType: dataPacket.encryptedPacket.encryptionType.toLKType()) } + case let .streamTrailer(trailer): Task { await incomingStreamManager.handle(trailer: trailer, encryptionType: dataPacket.encryptedPacket.encryptionType.toLKType()) } default: return } } + + func dataChannel(_: DataChannelPair, didFailToDecryptDataPacket _: Livekit_DataPacket, error: LiveKitError) { + delegates.notify { + $0.room?(self, didFailToDecryptDataWithEror: error) + } + } } diff --git a/Sources/LiveKit/Core/SignalClient.swift b/Sources/LiveKit/Core/SignalClient.swift index cd2b8f3ca..8298bad8f 100644 --- a/Sources/LiveKit/Core/SignalClient.swift +++ b/Sources/LiveKit/Core/SignalClient.swift @@ -352,6 +352,9 @@ private extension SignalClient { case .roomMoved: log("Received roomMoved message") + + case .mediaSectionsRequirement: + log("Received mediaSectionsRequirement message") } } } diff --git a/Sources/LiveKit/DataStream/Incoming/IncomingStreamManager.swift b/Sources/LiveKit/DataStream/Incoming/IncomingStreamManager.swift index 7d3507ea6..643aa1060 100644 --- a/Sources/LiveKit/DataStream/Incoming/IncomingStreamManager.swift +++ b/Sources/LiveKit/DataStream/Incoming/IncomingStreamManager.swift @@ -61,10 +61,10 @@ actor IncomingStreamManager: Loggable { // MARK: - Packet processing /// Handles a data stream header. - func handle(header: Livekit_DataStream.Header, from identityString: String) { + func handle(header: Livekit_DataStream.Header, from identityString: String, encryptionType: EncryptionType) { let identity = Participant.Identity(from: identityString) - guard let streamInfo = Self.streamInfo(from: header) else { + guard let streamInfo = Self.streamInfo(from: header, encryptionType: encryptionType) else { return } openStream(with: streamInfo, from: identity) @@ -110,9 +110,18 @@ actor IncomingStreamManager: Loggable { } /// Handles a data stream chunk. - func handle(chunk: Livekit_DataStream.Chunk) { + func handle(chunk: Livekit_DataStream.Chunk, encryptionType: EncryptionType) { guard !chunk.content.isEmpty, let descriptor = openStreams[chunk.streamID] else { return } + if descriptor.info.encryptionType != encryptionType { + let error = StreamError.encryptionTypeMismatch( + expected: descriptor.info.encryptionType, + received: encryptionType + ) + descriptor.continuation.finish(throwing: error) + return + } + let readLength = descriptor.readLength + chunk.content.count if let totalLength = descriptor.info.totalLength { @@ -126,10 +135,20 @@ actor IncomingStreamManager: Loggable { } /// Handles a data stream trailer. - func handle(trailer: Livekit_DataStream.Trailer) { + func handle(trailer: Livekit_DataStream.Trailer, encryptionType: EncryptionType) { guard let descriptor = openStreams[trailer.streamID] else { return } + + if descriptor.info.encryptionType != encryptionType { + let error = StreamError.encryptionTypeMismatch( + expected: descriptor.info.encryptionType, + received: encryptionType + ) + descriptor.continuation.finish(throwing: error) + return + } + if let totalLength = descriptor.info.totalLength { guard descriptor.readLength == totalLength else { descriptor.continuation.finish(throwing: StreamError.incomplete) @@ -186,10 +205,10 @@ public typealias TextStreamHandler = @Sendable (TextStreamReader, Participant.Id // MARK: - From protocol types extension IncomingStreamManager { - static func streamInfo(from header: Livekit_DataStream.Header) -> StreamInfo? { + static func streamInfo(from header: Livekit_DataStream.Header, encryptionType: EncryptionType) -> StreamInfo? { switch header.contentHeader { - case let .byteHeader(byteHeader): ByteStreamInfo(header, byteHeader) - case let .textHeader(textHeader): TextStreamInfo(header, textHeader) + case let .byteHeader(byteHeader): ByteStreamInfo(header, byteHeader, encryptionType) + case let .textHeader(textHeader): TextStreamInfo(header, textHeader, encryptionType) default: nil } } @@ -198,7 +217,8 @@ extension IncomingStreamManager { extension ByteStreamInfo { convenience init( _ header: Livekit_DataStream.Header, - _ byteHeader: Livekit_DataStream.ByteHeader + _ byteHeader: Livekit_DataStream.ByteHeader, + _ encryptionType: EncryptionType ) { self.init( id: header.streamID, @@ -206,6 +226,7 @@ extension ByteStreamInfo { timestamp: header.timestampDate, totalLength: header.hasTotalLength ? Int(header.totalLength) : nil, attributes: header.attributes, + encryptionType: encryptionType, // --- mimeType: header.mimeType, name: byteHeader.name @@ -216,7 +237,8 @@ extension ByteStreamInfo { extension TextStreamInfo { convenience init( _ header: Livekit_DataStream.Header, - _ textHeader: Livekit_DataStream.TextHeader + _ textHeader: Livekit_DataStream.TextHeader, + _ encryptionType: EncryptionType ) { self.init( id: header.streamID, @@ -224,6 +246,7 @@ extension TextStreamInfo { timestamp: header.timestampDate, totalLength: header.hasTotalLength ? Int(header.totalLength) : nil, attributes: header.attributes, + encryptionType: encryptionType, // --- operationType: TextStreamInfo.OperationType(textHeader.operationType), version: Int(textHeader.version), diff --git a/Sources/LiveKit/DataStream/Outgoing/OutgoingStreamManager.swift b/Sources/LiveKit/DataStream/Outgoing/OutgoingStreamManager.swift index a5458c8ca..340b952b7 100644 --- a/Sources/LiveKit/DataStream/Outgoing/OutgoingStreamManager.swift +++ b/Sources/LiveKit/DataStream/Outgoing/OutgoingStreamManager.swift @@ -19,11 +19,14 @@ import Foundation /// Manages state of outgoing data streams. actor OutgoingStreamManager: Loggable { typealias PacketHandler = @Sendable (Livekit_DataPacket) async throws -> Void + typealias EncryptionProvider = @Sendable () -> EncryptionType private nonisolated let packetHandler: PacketHandler + private nonisolated let encryptionProvider: EncryptionProvider - init(packetHandler: @escaping PacketHandler) { + init(packetHandler: @escaping PacketHandler, encryptionProvider: @escaping EncryptionProvider) { self.packetHandler = packetHandler + self.encryptionProvider = encryptionProvider } // MARK: - Opening streams @@ -35,6 +38,7 @@ actor OutgoingStreamManager: Loggable { timestamp: Date(), totalLength: text.utf8.count, // Number of bytes in UTF-8 representation attributes: options.attributes, + encryptionType: encryptionProvider(), operationType: .create, version: options.version, replyToStreamID: options.replyToStreamID, @@ -61,6 +65,7 @@ actor OutgoingStreamManager: Loggable { timestamp: Date(), totalLength: fileInfo.size, // Not overridable attributes: options.attributes, + encryptionType: encryptionProvider(), mimeType: options.mimeType ?? fileInfo.mimeType ?? Self.byteMimeType, name: options.name ?? fileInfo.name ) @@ -81,6 +86,7 @@ actor OutgoingStreamManager: Loggable { timestamp: Date(), totalLength: nil, attributes: options.attributes, + encryptionType: encryptionProvider(), operationType: .create, version: options.version, replyToStreamID: options.replyToStreamID, @@ -100,6 +106,7 @@ actor OutgoingStreamManager: Loggable { timestamp: Date(), totalLength: options.totalSize, attributes: options.attributes, + encryptionType: encryptionProvider(), mimeType: options.mimeType ?? Self.byteMimeType, name: options.name ) diff --git a/Sources/LiveKit/DataStream/StreamError.swift b/Sources/LiveKit/DataStream/StreamError.swift index fa02f5a87..74e78ef31 100644 --- a/Sources/LiveKit/DataStream/StreamError.swift +++ b/Sources/LiveKit/DataStream/StreamError.swift @@ -44,4 +44,7 @@ public enum StreamError: Error, Equatable { /// Unable to read information about the file to send. case fileInfoUnavailable + + /// Encryption type mismatch between stream header and chunk/trailer. + case encryptionTypeMismatch(expected: EncryptionType, received: EncryptionType) } diff --git a/Sources/LiveKit/DataStream/StreamInfo.swift b/Sources/LiveKit/DataStream/StreamInfo.swift index a2d3e21fa..2f23ced0a 100644 --- a/Sources/LiveKit/DataStream/StreamInfo.swift +++ b/Sources/LiveKit/DataStream/StreamInfo.swift @@ -32,6 +32,9 @@ public protocol StreamInfo: Sendable { /// Additional attributes as needed for your application. var attributes: [String: String] { get } + + /// The encryption type used for this stream. + var encryptionType: EncryptionType { get } } /// Information about a text data stream. @@ -42,6 +45,7 @@ public final class TextStreamInfo: NSObject, StreamInfo { public let timestamp: Date public let totalLength: Int? public let attributes: [String: String] + public let encryptionType: EncryptionType @objc(TextStreamInfoOperationType) public enum OperationType: Int, Sendable { @@ -63,6 +67,7 @@ public final class TextStreamInfo: NSObject, StreamInfo { timestamp: Date, totalLength: Int?, attributes: [String: String], + encryptionType: EncryptionType, operationType: OperationType, version: Int, replyToStreamID: String?, @@ -74,6 +79,7 @@ public final class TextStreamInfo: NSObject, StreamInfo { self.timestamp = timestamp self.totalLength = totalLength self.attributes = attributes + self.encryptionType = encryptionType self.operationType = operationType self.version = version self.replyToStreamID = replyToStreamID @@ -90,6 +96,7 @@ public final class ByteStreamInfo: NSObject, StreamInfo { public let timestamp: Date public let totalLength: Int? public let attributes: [String: String] + public let encryptionType: EncryptionType /// The MIME type of the stream data. public let mimeType: String @@ -103,6 +110,7 @@ public final class ByteStreamInfo: NSObject, StreamInfo { timestamp: Date, totalLength: Int?, attributes: [String: String], + encryptionType: EncryptionType, mimeType: String, name: String? ) { @@ -112,6 +120,7 @@ public final class ByteStreamInfo: NSObject, StreamInfo { self.timestamp = timestamp self.totalLength = totalLength self.attributes = attributes + self.encryptionType = encryptionType self.name = name } } diff --git a/Sources/LiveKit/E2EE/E2EEManager.swift b/Sources/LiveKit/E2EE/E2EEManager.swift index 62a62e74f..31e9eb3d9 100644 --- a/Sources/LiveKit/E2EE/E2EEManager.swift +++ b/Sources/LiveKit/E2EE/E2EEManager.swift @@ -39,10 +39,24 @@ public class E2EEManager: NSObject, @unchecked Sendable, ObservableObject, Logga // MARK: - Public - public let e2eeOptions: E2EEOptions + public let e2eeOptions: E2EEOptions? + public let options: EncryptionOptions? public var keyProvider: BaseKeyProvider { - e2eeOptions.keyProvider + options?.keyProvider ?? e2eeOptions?.keyProvider ?? BaseKeyProvider() + } + + public var frameEncryptionType: EncryptionType { + options?.encryptionType ?? e2eeOptions?.encryptionType ?? .none + } + + public var isDataChannelEncryptionEnabled: Bool { + _state.enabled && options != nil + } + + public var dataChannelEncryptionType: EncryptionType { + guard isDataChannelEncryptionEnabled else { return .none } + return options?.encryptionType ?? .none } // MARK: - Private @@ -58,10 +72,17 @@ public class E2EEManager: NSObject, @unchecked Sendable, ObservableObject, Logga var enabled: Bool = true var frameCryptors = [[Participant.Identity: Track.Sid]: LKRTCFrameCryptor]() var trackPublications = [LKRTCFrameCryptor: TrackPublication]() + var dataCryptor: LKRTCDataPacketCryptor? } public init(e2eeOptions: E2EEOptions) { self.e2eeOptions = e2eeOptions + options = nil + } + + public init(options: EncryptionOptions) { + e2eeOptions = nil + self.options = options } public func setup(room: Room) { @@ -87,6 +108,8 @@ public class E2EEManager: NSObject, @unchecked Sendable, ObservableObject, Logga } } } + + addDataChannelCryptor() } public func enableE2EE(enabled: Bool) { @@ -113,7 +136,7 @@ public class E2EEManager: NSObject, @unchecked Sendable, ObservableObject, Logga rtpSender: sender, participantId: participantIdentity.stringValue, algorithm: .aesGcm, - keyProvider: e2eeOptions.keyProvider.rtcKeyProvider) + keyProvider: keyProvider.rtcKeyProvider) else { log("frameCryptor is nil, skipping creating frame cryptor...", .warning) return @@ -143,7 +166,7 @@ public class E2EEManager: NSObject, @unchecked Sendable, ObservableObject, Logga rtpReceiver: receiver, participantId: participantIdentity.stringValue, algorithm: .aesGcm, - keyProvider: e2eeOptions.keyProvider.rtcKeyProvider) + keyProvider: keyProvider.rtcKeyProvider) else { log("frameCryptor is nil, skipping creating frame cryptor...", .warning) return @@ -158,6 +181,12 @@ public class E2EEManager: NSObject, @unchecked Sendable, ObservableObject, Logga } } + func addDataChannelCryptor() { + _state.mutate { + $0.dataCryptor = LKRTCDataPacketCryptor(algorithm: .aesGcm, keyProvider: keyProvider.rtcKeyProvider) + } + } + public func cleanUp() { _state.mutate { for (_, frameCryptor) in $0.frameCryptors { @@ -165,10 +194,13 @@ public class E2EEManager: NSObject, @unchecked Sendable, ObservableObject, Logga } $0.frameCryptors.removeAll() $0.trackPublications.removeAll() + $0.dataCryptor = nil } } } +// MARK: - Frame encryption + extension E2EEManager { func frameCryptor(_ frameCryptor: LKRTCFrameCryptor, didStateChangeWithParticipantId participantId: String, with state: LKRTCFrameCryptorState) { guard let room = _room else { @@ -234,3 +266,42 @@ extension E2EEManager: RoomDelegate { } } } + +// MARK: - Data Packet encryption + +extension E2EEManager { + func encrypt(data: Data) throws -> LKRTCEncryptedPacket { + guard let room = _room, + let identity = room.localParticipant.identity?.stringValue + else { + throw LiveKitError(.invalidState, message: "Room or participant identity is nil") + } + + guard let cryptor = _state.dataCryptor else { + throw LiveKitError(.invalidState, message: "Cryptor is nil") + } + + let keyIndex = UInt32(keyProvider.getCurrentKeyIndex()) + guard let encryptedData = cryptor.encrypt(identity, keyIndex: keyIndex, data: data) else { + throw LiveKitError(.encryptionFailed, message: "Failed to encrypt data packet") + } + + log("Encrypted \(encryptedData.data)", .trace) + + return encryptedData + } + + func handle(encryptedData: LKRTCEncryptedPacket, participantIdentity: String) throws -> Data { + guard let cryptor = _state.dataCryptor else { + throw LiveKitError(.invalidState, message: "Cryptor is nil") + } + + guard let decryptedData = cryptor.decrypt(participantIdentity, encryptedPacket: encryptedData) else { + throw LiveKitError(.decryptionFailed, message: "Failed to decrypt data packet") + } + + log("Decrypted \(decryptedData)", .trace) + + return decryptedData + } +} diff --git a/Sources/LiveKit/E2EE/KeyProvider.swift b/Sources/LiveKit/E2EE/KeyProvider.swift index 1d6cae8ee..a321e438d 100644 --- a/Sources/LiveKit/E2EE/KeyProvider.swift +++ b/Sources/LiveKit/E2EE/KeyProvider.swift @@ -20,8 +20,10 @@ internal import LiveKitWebRTC public let defaultRatchetSalt: String = "LKFrameEncryptionKey" public let defaultMagicBytes: String = "LK-ROCKS" +// Disable automatic ratcheting for the default shared key mode public let defaultRatchetWindowSize: Int32 = 0 public let defaultFailureTolerance: Int32 = -1 +public let defaultKeyRingSize: Int32 = 16 @objc public final class KeyProviderOptions: NSObject, Sendable { @@ -40,17 +42,22 @@ public final class KeyProviderOptions: NSObject, Sendable { @objc public let failureTolerance: Int32 + @objc + public let keyRingSize: Int32 + public init(sharedKey: Bool = true, ratchetSalt: Data = defaultRatchetSalt.data(using: .utf8)!, ratchetWindowSize: Int32 = defaultRatchetWindowSize, uncryptedMagicBytes: Data = defaultMagicBytes.data(using: .utf8)!, - failureTolerance: Int32 = defaultFailureTolerance) + failureTolerance: Int32 = defaultFailureTolerance, + keyRingSize: Int32 = defaultKeyRingSize) { self.sharedKey = sharedKey self.ratchetSalt = ratchetSalt self.ratchetWindowSize = ratchetWindowSize self.uncryptedMagicBytes = uncryptedMagicBytes self.failureTolerance = failureTolerance + self.keyRingSize = keyRingSize } // MARK: - Equal @@ -61,7 +68,8 @@ public final class KeyProviderOptions: NSObject, Sendable { ratchetSalt == other.ratchetSalt && ratchetWindowSize == other.ratchetWindowSize && uncryptedMagicBytes == other.uncryptedMagicBytes && - failureTolerance == other.failureTolerance + failureTolerance == other.failureTolerance && + keyRingSize == other.keyRingSize } override public var hash: Int { @@ -71,6 +79,7 @@ public final class KeyProviderOptions: NSObject, Sendable { hasher.combine(ratchetWindowSize) hasher.combine(uncryptedMagicBytes) hasher.combine(failureTolerance) + hasher.combine(keyRingSize) return hasher.finalize() } } @@ -84,6 +93,16 @@ public final class BaseKeyProvider: NSObject, Loggable, Sendable { let rtcKeyProvider: LKRTCFrameCryptorKeyProvider + // MARK: - State + + struct State { + var currentKeyIndex: Int32 = 0 + } + + private let _state = StateSync(State()) + + // MARK: Init + public init(isSharedKey: Bool, sharedKey: String? = nil) { options = KeyProviderOptions(sharedKey: isSharedKey) rtcKeyProvider = LKRTCFrameCryptorKeyProvider(ratchetSalt: options.ratchetSalt, @@ -91,7 +110,7 @@ public final class BaseKeyProvider: NSObject, Loggable, Sendable { sharedKeyMode: isSharedKey, uncryptedMagicBytes: options.uncryptedMagicBytes, failureTolerance: options.failureTolerance, - keyRingSize: 16) + keyRingSize: options.keyRingSize) if isSharedKey, sharedKey != nil { let keyData = sharedKey!.data(using: .utf8)! rtcKeyProvider.setSharedKey(keyData, with: 0) @@ -103,28 +122,37 @@ public final class BaseKeyProvider: NSObject, Loggable, Sendable { rtcKeyProvider = LKRTCFrameCryptorKeyProvider(ratchetSalt: options.ratchetSalt, ratchetWindowSize: options.ratchetWindowSize, sharedKeyMode: options.sharedKey, - uncryptedMagicBytes: options.uncryptedMagicBytes) + uncryptedMagicBytes: options.uncryptedMagicBytes, + failureTolerance: options.failureTolerance, + keyRingSize: options.keyRingSize) } - public func setKey(key: String, participantId: String? = nil, index: Int32? = 0) { + // MARK: - Key management + + public func setKey(key: String, participantId: String? = nil, index: Int32? = nil) { + let targetIndex = index ?? getCurrentKeyIndex() + if options.sharedKey { let keyData = key.data(using: .utf8)! - rtcKeyProvider.setSharedKey(keyData, with: index ?? 0) - return - } + rtcKeyProvider.setSharedKey(keyData, with: targetIndex) + } else { + if participantId == nil { + log("setKey: Please provide valid participantId for non-SharedKey mode.") + return + } - if participantId == nil { - log("setKey: Please provide valid participantId for non-SharedKey mode.") - return + let keyData = key.data(using: .utf8)! + rtcKeyProvider.setKey(keyData, with: targetIndex, forParticipant: participantId!) } - let keyData = key.data(using: .utf8)! - rtcKeyProvider.setKey(keyData, with: index!, forParticipant: participantId!) + setCurrentKeyIndex(targetIndex) } - public func ratchetKey(participantId: String? = nil, index: Int32? = 0) -> Data? { + public func ratchetKey(participantId: String? = nil, index: Int32? = nil) -> Data? { + let targetIndex = index ?? getCurrentKeyIndex() + if options.sharedKey { - return rtcKeyProvider.ratchetSharedKey(index ?? 0) + return rtcKeyProvider.ratchetSharedKey(targetIndex) } if participantId == nil { @@ -132,12 +160,14 @@ public final class BaseKeyProvider: NSObject, Loggable, Sendable { return nil } - return rtcKeyProvider.ratchetKey(participantId!, with: index ?? 0) + return rtcKeyProvider.ratchetKey(participantId!, with: targetIndex) } - public func exportKey(participantId: String? = nil, index: Int32? = 0) -> Data? { + public func exportKey(participantId: String? = nil, index: Int32? = nil) -> Data? { + let targetIndex = index ?? getCurrentKeyIndex() + if options.sharedKey { - return rtcKeyProvider.exportSharedKey(index ?? 0) + return rtcKeyProvider.exportSharedKey(targetIndex) } if participantId == nil { @@ -145,13 +175,23 @@ public final class BaseKeyProvider: NSObject, Loggable, Sendable { return nil } - return rtcKeyProvider.exportKey(participantId!, with: index ?? 0) + return rtcKeyProvider.exportKey(participantId!, with: targetIndex) } public func setSifTrailer(trailer: Data) { rtcKeyProvider.setSifTrailer(trailer) } + @objc + public func getCurrentKeyIndex() -> Int32 { + _state.currentKeyIndex + } + + @objc + public func setCurrentKeyIndex(_ index: Int32) { + _state.mutate { $0.currentKeyIndex = index % options.keyRingSize } + } + // MARK: - Equal override public func isEqual(_ object: Any?) -> Bool { diff --git a/Sources/LiveKit/E2EE/Options.swift b/Sources/LiveKit/E2EE/Options.swift index 640a5d00b..710c46a1d 100644 --- a/Sources/LiveKit/E2EE/Options.swift +++ b/Sources/LiveKit/E2EE/Options.swift @@ -45,6 +45,7 @@ extension Livekit_Encryption.TypeEnum { } } +@available(*, deprecated, message: "Migrate to 'EncryptionOptions' instead. Important: It will enable data channel encryption by default (requires support from all platforms).") @objc public final class E2EEOptions: NSObject, Sendable { @objc @@ -75,3 +76,34 @@ public final class E2EEOptions: NSObject, Sendable { return hasher.finalize() } } + +@objc +public final class EncryptionOptions: NSObject, Sendable { + @objc + public let keyProvider: BaseKeyProvider + + @objc + public let encryptionType: EncryptionType + + public init(keyProvider: BaseKeyProvider, + encryptionType: EncryptionType = .gcm) + { + self.keyProvider = keyProvider + self.encryptionType = encryptionType + } + + // MARK: - Equal + + override public func isEqual(_ object: Any?) -> Bool { + guard let other = object as? Self else { return false } + return keyProvider == other.keyProvider && + encryptionType == other.encryptionType + } + + override public var hash: Int { + var hasher = Hasher() + hasher.combine(keyProvider) + hasher.combine(encryptionType) + return hasher.finalize() + } +} diff --git a/Sources/LiveKit/E2EE/Protos+E2EE.swift b/Sources/LiveKit/E2EE/Protos+E2EE.swift new file mode 100644 index 000000000..e8fd852fc --- /dev/null +++ b/Sources/LiveKit/E2EE/Protos+E2EE.swift @@ -0,0 +1,100 @@ +/* + * Copyright 2025 LiveKit + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import Foundation + +internal import LiveKitWebRTC + +// MARK: - EncryptedPacket + +extension Livekit_EncryptedPacket { + init(rtcPacket: LKRTCEncryptedPacket) { + encryptionType = .gcm + iv = rtcPacket.iv + keyIndex = rtcPacket.keyIndex + encryptedValue = rtcPacket.data + } + + func toRTCEncryptedPacket() -> LKRTCEncryptedPacket { + LKRTCEncryptedPacket( + data: encryptedValue, + iv: iv, + keyIndex: keyIndex + ) + } +} + +// MARK: - EncryptedPacketPayload + +extension Livekit_EncryptedPacketPayload { + init?(dataPacket: Livekit_DataPacket) { + switch dataPacket.value { + case let .user(user): + self.user = user + case let .chatMessage(chatMessage): + self.chatMessage = chatMessage + case let .rpcRequest(rpcRequest): + self.rpcRequest = rpcRequest + case let .rpcAck(rpcAck): + self.rpcAck = rpcAck + case let .rpcResponse(rpcResponse): + self.rpcResponse = rpcResponse + case let .streamHeader(streamHeader): + self.streamHeader = streamHeader + case let .streamChunk(streamChunk): + self.streamChunk = streamChunk + case let .streamTrailer(streamTrailer): + self.streamTrailer = streamTrailer + default: + return nil + } + } + + func applyTo(_ dataPacket: inout Livekit_DataPacket) { + switch value { + case let .user(userPacket): + dataPacket.user = userPacket + case let .chatMessage(chatMessage): + dataPacket.chatMessage = chatMessage + case let .rpcRequest(rpcRequest): + dataPacket.rpcRequest = rpcRequest + case let .rpcAck(rpcAck): + dataPacket.rpcAck = rpcAck + case let .rpcResponse(rpcResponse): + dataPacket.rpcResponse = rpcResponse + case let .streamHeader(streamHeader): + dataPacket.streamHeader = streamHeader + case let .streamChunk(streamChunk): + dataPacket.streamChunk = streamChunk + case let .streamTrailer(streamTrailer): + dataPacket.streamTrailer = streamTrailer + case .none: + break + } + } +} + +// MARK: - DataPacket + +extension Livekit_DataPacket { + // Skip the default value returned from protobufs + var encryptedPacketOrNil: Livekit_EncryptedPacket? { + switch value { + case .encryptedPacket: encryptedPacket + default: nil + } + } +} diff --git a/Sources/LiveKit/Errors.swift b/Sources/LiveKit/Errors.swift index c509b8fbc..4f1982396 100644 --- a/Sources/LiveKit/Errors.swift +++ b/Sources/LiveKit/Errors.swift @@ -55,6 +55,10 @@ public enum LiveKitErrorType: Int, Sendable { case audioSession = 802 case codecNotSupported = 901 + + // Encryption + case encryptionFailed = 1001 + case decryptionFailed = 1002 } extension LiveKitErrorType: CustomStringConvertible { @@ -102,6 +106,12 @@ extension LiveKitErrorType: CustomStringConvertible { "Audio Engine Error" case .audioSession: "Audio Session Error" + case .codecNotSupported: + "Codec not supported" + case .encryptionFailed: + "Encryption failed" + case .decryptionFailed: + "Decryption failed" default: "Unknown" } } diff --git a/Sources/LiveKit/Participant/LocalParticipant.swift b/Sources/LiveKit/Participant/LocalParticipant.swift index 888752215..da3a89583 100644 --- a/Sources/LiveKit/Participant/LocalParticipant.swift +++ b/Sources/LiveKit/Participant/LocalParticipant.swift @@ -635,7 +635,7 @@ extension LocalParticipant { name: addTrackName, type: track.kind.toPBType(), source: track.source.toPBType(), - encryption: room.e2eeManager?.e2eeOptions.encryptionType.toPBType() ?? .none, + encryption: room.e2eeManager?.frameEncryptionType.toPBType() ?? .none, populatorFunc) } diff --git a/Sources/LiveKit/Protocols/ParticipantDelegate.swift b/Sources/LiveKit/Protocols/ParticipantDelegate.swift index 77285a46f..7f0112e9b 100644 --- a/Sources/LiveKit/Protocols/ParticipantDelegate.swift +++ b/Sources/LiveKit/Protocols/ParticipantDelegate.swift @@ -130,10 +130,15 @@ public protocol ParticipantDelegate: AnyObject, Sendable { /// Data was received from a ``RemoteParticipant``. @objc optional - func participant(_ participant: RemoteParticipant, didReceiveData data: Data, forTopic topic: String) + func participant(_ participant: RemoteParticipant, didReceiveData data: Data, forTopic topic: String, encryptionType: EncryptionType) // MARK: - Deprecated + /// Renamed to ``ParticipantDelegate/participant(_:didReceiveData:forTopic:encryptionType:)``. + @available(*, unavailable, renamed: "participant(_:didReceiveData:forTopic:encryptionType:)") + @objc optional + func participant(_ participant: RemoteParticipant, didReceiveData data: Data, forTopic topic: String) + /// Renamed to ``ParticipantDelegate/participant(_:didUpdateMetadata:)``. @available(*, unavailable, renamed: "participant(_:didUpdateMetadata:)") @objc(participant:didUpdateMetadata_:) optional diff --git a/Sources/LiveKit/Protocols/RoomDelegate.swift b/Sources/LiveKit/Protocols/RoomDelegate.swift index 157cbb279..c6b603ee1 100644 --- a/Sources/LiveKit/Protocols/RoomDelegate.swift +++ b/Sources/LiveKit/Protocols/RoomDelegate.swift @@ -151,7 +151,11 @@ public protocol RoomDelegate: AnyObject, Sendable { /// Received data from from a user or server. `participant` will be nil if broadcasted from server. @objc optional - func room(_ room: Room, participant: RemoteParticipant?, didReceiveData data: Data, forTopic topic: String) + func room(_ room: Room, participant: RemoteParticipant?, didReceiveData data: Data, forTopic topic: String, encryptionType: EncryptionType) + + /// Failed to decrypt a data packet when encryption is enabled. + @objc optional + func room(_ room: Room, didFailToDecryptDataWithEror error: LiveKitError) @objc optional func room(_ room: Room, trackPublication: TrackPublication, didUpdateE2EEState state: E2EEState) @@ -170,6 +174,11 @@ public protocol RoomDelegate: AnyObject, Sendable { // MARK: - Deprecated + /// Renamed to ``RoomDelegate/room(_:participant:didReceiveData:forTopic:encryptionType:)``. + @available(*, unavailable, renamed: "room(_:participant:didReceiveData:forTopic:encryptionType:)") + @objc optional + func room(_ room: Room, participant: RemoteParticipant?, didReceiveData data: Data, forTopic topic: String) + /// Renamed to ``RoomDelegate/room(_:didUpdateConnectionState:from:)``. @available(*, unavailable, renamed: "room(_:didUpdateConnectionState:from:)") @objc(room:didUpdateConnectionState:oldConnectionState:) optional diff --git a/Sources/LiveKit/Protos/livekit_metrics.pb.swift b/Sources/LiveKit/Protos/livekit_metrics.pb.swift index 4f0a9878a..5dfb05fcb 100644 --- a/Sources/LiveKit/Protos/livekit_metrics.pb.swift +++ b/Sources/LiveKit/Protos/livekit_metrics.pb.swift @@ -321,40 +321,12 @@ struct Livekit_EventMetric: Sendable { fileprivate let _protobuf_package = "livekit" extension Livekit_MetricLabel: SwiftProtobuf._ProtoNameProviding { - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "AGENTS_LLM_TTFT"), - 1: .same(proto: "AGENTS_STT_TTFT"), - 2: .same(proto: "AGENTS_TTS_TTFB"), - 3: .same(proto: "CLIENT_VIDEO_SUBSCRIBER_FREEZE_COUNT"), - 4: .same(proto: "CLIENT_VIDEO_SUBSCRIBER_TOTAL_FREEZE_DURATION"), - 5: .same(proto: "CLIENT_VIDEO_SUBSCRIBER_PAUSE_COUNT"), - 6: .same(proto: "CLIENT_VIDEO_SUBSCRIBER_TOTAL_PAUSES_DURATION"), - 7: .same(proto: "CLIENT_AUDIO_SUBSCRIBER_CONCEALED_SAMPLES"), - 8: .same(proto: "CLIENT_AUDIO_SUBSCRIBER_SILENT_CONCEALED_SAMPLES"), - 9: .same(proto: "CLIENT_AUDIO_SUBSCRIBER_CONCEALMENT_EVENTS"), - 10: .same(proto: "CLIENT_AUDIO_SUBSCRIBER_INTERRUPTION_COUNT"), - 11: .same(proto: "CLIENT_AUDIO_SUBSCRIBER_TOTAL_INTERRUPTION_DURATION"), - 12: .same(proto: "CLIENT_SUBSCRIBER_JITTER_BUFFER_DELAY"), - 13: .same(proto: "CLIENT_SUBSCRIBER_JITTER_BUFFER_EMITTED_COUNT"), - 14: .same(proto: "CLIENT_VIDEO_PUBLISHER_QUALITY_LIMITATION_DURATION_BANDWIDTH"), - 15: .same(proto: "CLIENT_VIDEO_PUBLISHER_QUALITY_LIMITATION_DURATION_CPU"), - 16: .same(proto: "CLIENT_VIDEO_PUBLISHER_QUALITY_LIMITATION_DURATION_OTHER"), - 17: .same(proto: "PUBLISHER_RTT"), - 18: .same(proto: "SERVER_MESH_RTT"), - 19: .same(proto: "SUBSCRIBER_RTT"), - 4096: .same(proto: "METRIC_LABEL_PREDEFINED_MAX_VALUE"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{2}\0AGENTS_LLM_TTFT\0\u{1}AGENTS_STT_TTFT\0\u{1}AGENTS_TTS_TTFB\0\u{1}CLIENT_VIDEO_SUBSCRIBER_FREEZE_COUNT\0\u{1}CLIENT_VIDEO_SUBSCRIBER_TOTAL_FREEZE_DURATION\0\u{1}CLIENT_VIDEO_SUBSCRIBER_PAUSE_COUNT\0\u{1}CLIENT_VIDEO_SUBSCRIBER_TOTAL_PAUSES_DURATION\0\u{1}CLIENT_AUDIO_SUBSCRIBER_CONCEALED_SAMPLES\0\u{1}CLIENT_AUDIO_SUBSCRIBER_SILENT_CONCEALED_SAMPLES\0\u{1}CLIENT_AUDIO_SUBSCRIBER_CONCEALMENT_EVENTS\0\u{1}CLIENT_AUDIO_SUBSCRIBER_INTERRUPTION_COUNT\0\u{1}CLIENT_AUDIO_SUBSCRIBER_TOTAL_INTERRUPTION_DURATION\0\u{1}CLIENT_SUBSCRIBER_JITTER_BUFFER_DELAY\0\u{1}CLIENT_SUBSCRIBER_JITTER_BUFFER_EMITTED_COUNT\0\u{1}CLIENT_VIDEO_PUBLISHER_QUALITY_LIMITATION_DURATION_BANDWIDTH\0\u{1}CLIENT_VIDEO_PUBLISHER_QUALITY_LIMITATION_DURATION_CPU\0\u{1}CLIENT_VIDEO_PUBLISHER_QUALITY_LIMITATION_DURATION_OTHER\0\u{1}PUBLISHER_RTT\0\u{1}SERVER_MESH_RTT\0\u{1}SUBSCRIBER_RTT\0\u{2}m?METRIC_LABEL_PREDEFINED_MAX_VALUE\0") } extension Livekit_MetricsBatch: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = _protobuf_package + ".MetricsBatch" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "timestamp_ms"), - 2: .standard(proto: "normalized_timestamp"), - 3: .standard(proto: "str_data"), - 4: .standard(proto: "time_series"), - 5: .same(proto: "events"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{3}timestamp_ms\0\u{3}normalized_timestamp\0\u{3}str_data\0\u{3}time_series\0\u{1}events\0") mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -408,13 +380,7 @@ extension Livekit_MetricsBatch: SwiftProtobuf.Message, SwiftProtobuf._MessageImp extension Livekit_TimeSeriesMetric: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = _protobuf_package + ".TimeSeriesMetric" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "label"), - 2: .standard(proto: "participant_identity"), - 3: .standard(proto: "track_sid"), - 4: .same(proto: "samples"), - 5: .same(proto: "rid"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}label\0\u{3}participant_identity\0\u{3}track_sid\0\u{1}samples\0\u{1}rid\0") mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -464,11 +430,7 @@ extension Livekit_TimeSeriesMetric: SwiftProtobuf.Message, SwiftProtobuf._Messag extension Livekit_MetricSample: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = _protobuf_package + ".MetricSample" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "timestamp_ms"), - 2: .standard(proto: "normalized_timestamp"), - 3: .same(proto: "value"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{3}timestamp_ms\0\u{3}normalized_timestamp\0\u{1}value\0") mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -512,17 +474,7 @@ extension Livekit_MetricSample: SwiftProtobuf.Message, SwiftProtobuf._MessageImp extension Livekit_EventMetric: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = _protobuf_package + ".EventMetric" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "label"), - 2: .standard(proto: "participant_identity"), - 3: .standard(proto: "track_sid"), - 4: .standard(proto: "start_timestamp_ms"), - 5: .standard(proto: "end_timestamp_ms"), - 6: .standard(proto: "normalized_start_timestamp"), - 7: .standard(proto: "normalized_end_timestamp"), - 8: .same(proto: "metadata"), - 9: .same(proto: "rid"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}label\0\u{3}participant_identity\0\u{3}track_sid\0\u{3}start_timestamp_ms\0\u{3}end_timestamp_ms\0\u{3}normalized_start_timestamp\0\u{3}normalized_end_timestamp\0\u{1}metadata\0\u{1}rid\0") mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { diff --git a/Sources/LiveKit/Protos/livekit_models.pb.swift b/Sources/LiveKit/Protos/livekit_models.pb.swift index 45beb6ea0..36478b706 100644 --- a/Sources/LiveKit/Protos/livekit_models.pb.swift +++ b/Sources/LiveKit/Protos/livekit_models.pb.swift @@ -680,6 +680,18 @@ struct Livekit_Pagination: Sendable { init() {} } +struct Livekit_TokenPagination: Sendable { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + var token: String = String() + + var unknownFields = SwiftProtobuf.UnknownStorage() + + init() {} +} + /// ListUpdate is used for updated APIs where 'repeated string' field is modified. struct Livekit_ListUpdate: Sendable { // SwiftProtobuf.Message conformance is added in an extension below. See the @@ -689,6 +701,15 @@ struct Livekit_ListUpdate: Sendable { /// set the field to a new list var set: [String] = [] + /// append items to a list, avoiding duplicates + var add: [String] = [] + + /// delete items from a list + var del: [String] = [] + + /// sets the list to an empty list + var clear: Bool = false + var unknownFields = SwiftProtobuf.UnknownStorage() init() {} @@ -1115,6 +1136,14 @@ struct Livekit_SimulcastCodecInfo: Sendable { var layers: [Livekit_VideoLayer] = [] + var videoLayerMode: Livekit_VideoLayer.Mode = .unused + + /// cid (client side id for track) could be different between + /// signalling (AddTrackRequest) and SDP offer. This field + /// will be populated only if it is different to avoid + /// duplication and keep the representation concise. + var sdpCid: String = String() + var unknownFields = SwiftProtobuf.UnknownStorage() init() {} @@ -1147,24 +1176,32 @@ struct Livekit_TrackInfo: @unchecked Sendable { /// original width of video (unset for audio) /// clients may receive a lower resolution version with simulcast + /// + /// NOTE: This field was marked as deprecated in the .proto file. var width: UInt32 { get {return _storage._width} set {_uniqueStorage()._width = newValue} } /// original height of video (unset for audio) + /// + /// NOTE: This field was marked as deprecated in the .proto file. var height: UInt32 { get {return _storage._height} set {_uniqueStorage()._height = newValue} } /// true if track is simulcasted + /// + /// NOTE: This field was marked as deprecated in the .proto file. var simulcast: Bool { get {return _storage._simulcast} set {_uniqueStorage()._simulcast = newValue} } /// true if DTX (Discontinuous Transmission) is disabled for audio + /// + /// NOTE: This field was marked as deprecated in the .proto file. var disableDtx: Bool { get {return _storage._disableDtx} set {_uniqueStorage()._disableDtx = newValue} @@ -1176,6 +1213,9 @@ struct Livekit_TrackInfo: @unchecked Sendable { set {_uniqueStorage()._source = newValue} } + /// see `codecs` for layers of individual codec + /// + /// NOTE: This field was marked as deprecated in the .proto file. var layers: [Livekit_VideoLayer] { get {return _storage._layers} set {_uniqueStorage()._layers = newValue} @@ -1197,6 +1237,9 @@ struct Livekit_TrackInfo: @unchecked Sendable { set {_uniqueStorage()._codecs = newValue} } + /// deprecated in favor of `audio_features` + /// + /// NOTE: This field was marked as deprecated in the .proto file. var stereo: Bool { get {return _storage._stereo} set {_uniqueStorage()._stereo = newValue} @@ -1262,8 +1305,50 @@ struct Livekit_VideoLayer: Sendable { var ssrc: UInt32 = 0 + var spatialLayer: Int32 = 0 + + var rid: String = String() + var unknownFields = SwiftProtobuf.UnknownStorage() + enum Mode: SwiftProtobuf.Enum, Swift.CaseIterable { + typealias RawValue = Int + case unused // = 0 + case oneSpatialLayerPerStream // = 1 + case multipleSpatialLayersPerStream // = 2 + case UNRECOGNIZED(Int) + + init() { + self = .unused + } + + init?(rawValue: Int) { + switch rawValue { + case 0: self = .unused + case 1: self = .oneSpatialLayerPerStream + case 2: self = .multipleSpatialLayersPerStream + default: self = .UNRECOGNIZED(rawValue) + } + } + + var rawValue: Int { + switch self { + case .unused: return 0 + case .oneSpatialLayerPerStream: return 1 + case .multipleSpatialLayersPerStream: return 2 + case .UNRECOGNIZED(let i): return i + } + } + + // The compiler won't synthesize support with the UNRECOGNIZED case. + static let allCases: [Livekit_VideoLayer.Mode] = [ + .unused, + .oneSpatialLayerPerStream, + .multipleSpatialLayersPerStream, + ] + + } + init() {} } @@ -1393,6 +1478,14 @@ struct Livekit_DataPacket: @unchecked Sendable { set {_uniqueStorage()._value = .streamTrailer(newValue)} } + var encryptedPacket: Livekit_EncryptedPacket { + get { + if case .encryptedPacket(let v)? = _storage._value {return v} + return Livekit_EncryptedPacket() + } + set {_uniqueStorage()._value = .encryptedPacket(newValue)} + } + /// sequence number of reliable packet var sequence: UInt32 { get {return _storage._sequence} @@ -1421,6 +1514,7 @@ struct Livekit_DataPacket: @unchecked Sendable { case streamHeader(Livekit_DataStream.Header) case streamChunk(Livekit_DataStream.Chunk) case streamTrailer(Livekit_DataStream.Trailer) + case encryptedPacket(Livekit_EncryptedPacket) } @@ -1463,6 +1557,114 @@ struct Livekit_DataPacket: @unchecked Sendable { fileprivate var _storage = _StorageClass.defaultInstance } +struct Livekit_EncryptedPacket: Sendable { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + var encryptionType: Livekit_Encryption.TypeEnum = .none + + var iv: Data = Data() + + var keyIndex: UInt32 = 0 + + /// This is an encrypted EncryptedPacketPayload message representation + var encryptedValue: Data = Data() + + var unknownFields = SwiftProtobuf.UnknownStorage() + + init() {} +} + +struct Livekit_EncryptedPacketPayload: Sendable { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + var value: Livekit_EncryptedPacketPayload.OneOf_Value? = nil + + var user: Livekit_UserPacket { + get { + if case .user(let v)? = value {return v} + return Livekit_UserPacket() + } + set {value = .user(newValue)} + } + + var chatMessage: Livekit_ChatMessage { + get { + if case .chatMessage(let v)? = value {return v} + return Livekit_ChatMessage() + } + set {value = .chatMessage(newValue)} + } + + var rpcRequest: Livekit_RpcRequest { + get { + if case .rpcRequest(let v)? = value {return v} + return Livekit_RpcRequest() + } + set {value = .rpcRequest(newValue)} + } + + var rpcAck: Livekit_RpcAck { + get { + if case .rpcAck(let v)? = value {return v} + return Livekit_RpcAck() + } + set {value = .rpcAck(newValue)} + } + + var rpcResponse: Livekit_RpcResponse { + get { + if case .rpcResponse(let v)? = value {return v} + return Livekit_RpcResponse() + } + set {value = .rpcResponse(newValue)} + } + + var streamHeader: Livekit_DataStream.Header { + get { + if case .streamHeader(let v)? = value {return v} + return Livekit_DataStream.Header() + } + set {value = .streamHeader(newValue)} + } + + var streamChunk: Livekit_DataStream.Chunk { + get { + if case .streamChunk(let v)? = value {return v} + return Livekit_DataStream.Chunk() + } + set {value = .streamChunk(newValue)} + } + + var streamTrailer: Livekit_DataStream.Trailer { + get { + if case .streamTrailer(let v)? = value {return v} + return Livekit_DataStream.Trailer() + } + set {value = .streamTrailer(newValue)} + } + + var unknownFields = SwiftProtobuf.UnknownStorage() + + enum OneOf_Value: Equatable, Sendable { + case user(Livekit_UserPacket) + case chatMessage(Livekit_ChatMessage) + case rpcRequest(Livekit_RpcRequest) + case rpcAck(Livekit_RpcAck) + case rpcResponse(Livekit_RpcResponse) + case streamHeader(Livekit_DataStream.Header) + case streamChunk(Livekit_DataStream.Chunk) + case streamTrailer(Livekit_DataStream.Trailer) + + } + + init() {} +} + +/// NOTE: This message was marked as deprecated in the .proto file. struct Livekit_ActiveSpeakerUpdate: Sendable { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for @@ -1493,7 +1695,7 @@ struct Livekit_SpeakerInfo: Sendable { init() {} } -struct Livekit_UserPacket: @unchecked Sendable { +struct Livekit_UserPacket: Sendable { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -1529,7 +1731,7 @@ struct Livekit_UserPacket: @unchecked Sendable { /// Clears the value of `topic`. Subsequent reads from it will return its default value. mutating func clearTopic() {self._topic = nil} - /// Unique ID to indentify the message + /// Unique ID to identify the message var id: String { get {return _id ?? String()} set {_id = newValue} @@ -1867,6 +2069,7 @@ struct Livekit_ClientInfo: Sendable { case unityWeb // = 11 case node // = 12 case unreal // = 13 + case esp32 // = 14 case UNRECOGNIZED(Int) init() { @@ -1889,6 +2092,7 @@ struct Livekit_ClientInfo: Sendable { case 11: self = .unityWeb case 12: self = .node case 13: self = .unreal + case 14: self = .esp32 default: self = .UNRECOGNIZED(rawValue) } } @@ -1909,6 +2113,7 @@ struct Livekit_ClientInfo: Sendable { case .unityWeb: return 11 case .node: return 12 case .unreal: return 13 + case .esp32: return 14 case .UNRECOGNIZED(let i): return i } } @@ -1929,6 +2134,7 @@ struct Livekit_ClientInfo: Sendable { .unityWeb, .node, .unreal, + .esp32, ] } @@ -2601,7 +2807,9 @@ struct Livekit_DataStream: Sendable { /// Clears the value of `totalLength`. Subsequent reads from it will return its default value. mutating func clearTotalLength() {self._totalLength = nil} - /// defaults to NONE + /// this is set on the DataPacket + /// + /// NOTE: This field was marked as deprecated in the .proto file. var encryptionType: Livekit_Encryption.TypeEnum = .none /// user defined attributes map that can carry additional info @@ -2640,7 +2848,7 @@ struct Livekit_DataStream: Sendable { fileprivate var _totalLength: UInt64? = nil } - struct Chunk: @unchecked Sendable { + struct Chunk: Sendable { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -2656,7 +2864,9 @@ struct Livekit_DataStream: Sendable { /// a version indicating that this chunk_index has been retroactively modified and the original one needs to be replaced var version: Int32 = 0 - /// optional, initialization vector for AES-GCM encryption + /// this is set on the DataPacket + /// + /// NOTE: This field was marked as deprecated in the .proto file. var iv: Data { get {return _iv ?? Data()} set {_iv = newValue} @@ -2714,139 +2924,60 @@ struct Livekit_WebhookConfig: Sendable { fileprivate let _protobuf_package = "livekit" extension Livekit_AudioCodec: SwiftProtobuf._ProtoNameProviding { - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "DEFAULT_AC"), - 1: .same(proto: "OPUS"), - 2: .same(proto: "AAC"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{2}\0DEFAULT_AC\0\u{1}OPUS\0\u{1}AAC\0") } extension Livekit_VideoCodec: SwiftProtobuf._ProtoNameProviding { - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "DEFAULT_VC"), - 1: .same(proto: "H264_BASELINE"), - 2: .same(proto: "H264_MAIN"), - 3: .same(proto: "H264_HIGH"), - 4: .same(proto: "VP8"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{2}\0DEFAULT_VC\0\u{1}H264_BASELINE\0\u{1}H264_MAIN\0\u{1}H264_HIGH\0\u{1}VP8\0") } extension Livekit_ImageCodec: SwiftProtobuf._ProtoNameProviding { - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "IC_DEFAULT"), - 1: .same(proto: "IC_JPEG"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{2}\0IC_DEFAULT\0\u{1}IC_JPEG\0") } extension Livekit_BackupCodecPolicy: SwiftProtobuf._ProtoNameProviding { - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "PREFER_REGRESSION"), - 1: .same(proto: "SIMULCAST"), - 2: .same(proto: "REGRESSION"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{2}\0PREFER_REGRESSION\0\u{1}SIMULCAST\0\u{1}REGRESSION\0") } extension Livekit_TrackType: SwiftProtobuf._ProtoNameProviding { - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "AUDIO"), - 1: .same(proto: "VIDEO"), - 2: .same(proto: "DATA"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{2}\0AUDIO\0\u{1}VIDEO\0\u{1}DATA\0") } extension Livekit_TrackSource: SwiftProtobuf._ProtoNameProviding { - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "UNKNOWN"), - 1: .same(proto: "CAMERA"), - 2: .same(proto: "MICROPHONE"), - 3: .same(proto: "SCREEN_SHARE"), - 4: .same(proto: "SCREEN_SHARE_AUDIO"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{2}\0UNKNOWN\0\u{1}CAMERA\0\u{1}MICROPHONE\0\u{1}SCREEN_SHARE\0\u{1}SCREEN_SHARE_AUDIO\0") } extension Livekit_VideoQuality: SwiftProtobuf._ProtoNameProviding { - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "LOW"), - 1: .same(proto: "MEDIUM"), - 2: .same(proto: "HIGH"), - 3: .same(proto: "OFF"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{2}\0LOW\0\u{1}MEDIUM\0\u{1}HIGH\0\u{1}OFF\0") } extension Livekit_ConnectionQuality: SwiftProtobuf._ProtoNameProviding { - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "POOR"), - 1: .same(proto: "GOOD"), - 2: .same(proto: "EXCELLENT"), - 3: .same(proto: "LOST"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{2}\0POOR\0\u{1}GOOD\0\u{1}EXCELLENT\0\u{1}LOST\0") } extension Livekit_ClientConfigSetting: SwiftProtobuf._ProtoNameProviding { - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "UNSET"), - 1: .same(proto: "DISABLED"), - 2: .same(proto: "ENABLED"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{2}\0UNSET\0\u{1}DISABLED\0\u{1}ENABLED\0") } extension Livekit_DisconnectReason: SwiftProtobuf._ProtoNameProviding { - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "UNKNOWN_REASON"), - 1: .same(proto: "CLIENT_INITIATED"), - 2: .same(proto: "DUPLICATE_IDENTITY"), - 3: .same(proto: "SERVER_SHUTDOWN"), - 4: .same(proto: "PARTICIPANT_REMOVED"), - 5: .same(proto: "ROOM_DELETED"), - 6: .same(proto: "STATE_MISMATCH"), - 7: .same(proto: "JOIN_FAILURE"), - 8: .same(proto: "MIGRATION"), - 9: .same(proto: "SIGNAL_CLOSE"), - 10: .same(proto: "ROOM_CLOSED"), - 11: .same(proto: "USER_UNAVAILABLE"), - 12: .same(proto: "USER_REJECTED"), - 13: .same(proto: "SIP_TRUNK_FAILURE"), - 14: .same(proto: "CONNECTION_TIMEOUT"), - 15: .same(proto: "MEDIA_FAILURE"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{2}\0UNKNOWN_REASON\0\u{1}CLIENT_INITIATED\0\u{1}DUPLICATE_IDENTITY\0\u{1}SERVER_SHUTDOWN\0\u{1}PARTICIPANT_REMOVED\0\u{1}ROOM_DELETED\0\u{1}STATE_MISMATCH\0\u{1}JOIN_FAILURE\0\u{1}MIGRATION\0\u{1}SIGNAL_CLOSE\0\u{1}ROOM_CLOSED\0\u{1}USER_UNAVAILABLE\0\u{1}USER_REJECTED\0\u{1}SIP_TRUNK_FAILURE\0\u{1}CONNECTION_TIMEOUT\0\u{1}MEDIA_FAILURE\0") } extension Livekit_ReconnectReason: SwiftProtobuf._ProtoNameProviding { - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "RR_UNKNOWN"), - 1: .same(proto: "RR_SIGNAL_DISCONNECTED"), - 2: .same(proto: "RR_PUBLISHER_FAILED"), - 3: .same(proto: "RR_SUBSCRIBER_FAILED"), - 4: .same(proto: "RR_SWITCH_CANDIDATE"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{2}\0RR_UNKNOWN\0\u{1}RR_SIGNAL_DISCONNECTED\0\u{1}RR_PUBLISHER_FAILED\0\u{1}RR_SUBSCRIBER_FAILED\0\u{1}RR_SWITCH_CANDIDATE\0") } extension Livekit_SubscriptionError: SwiftProtobuf._ProtoNameProviding { - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "SE_UNKNOWN"), - 1: .same(proto: "SE_CODEC_UNSUPPORTED"), - 2: .same(proto: "SE_TRACK_NOTFOUND"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{2}\0SE_UNKNOWN\0\u{1}SE_CODEC_UNSUPPORTED\0\u{1}SE_TRACK_NOTFOUND\0") } extension Livekit_AudioTrackFeature: SwiftProtobuf._ProtoNameProviding { - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "TF_STEREO"), - 1: .same(proto: "TF_NO_DTX"), - 2: .same(proto: "TF_AUTO_GAIN_CONTROL"), - 3: .same(proto: "TF_ECHO_CANCELLATION"), - 4: .same(proto: "TF_NOISE_SUPPRESSION"), - 5: .same(proto: "TF_ENHANCED_NOISE_CANCELLATION"), - 6: .same(proto: "TF_PRECONNECT_BUFFER"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{2}\0TF_STEREO\0\u{1}TF_NO_DTX\0\u{1}TF_AUTO_GAIN_CONTROL\0\u{1}TF_ECHO_CANCELLATION\0\u{1}TF_NOISE_SUPPRESSION\0\u{1}TF_ENHANCED_NOISE_CANCELLATION\0\u{1}TF_PRECONNECT_BUFFER\0") } extension Livekit_Pagination: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = _protobuf_package + ".Pagination" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "after_id"), - 2: .same(proto: "limit"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{3}after_id\0\u{1}limit\0") mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -2879,11 +3010,39 @@ extension Livekit_Pagination: SwiftProtobuf.Message, SwiftProtobuf._MessageImple } } +extension Livekit_TokenPagination: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = _protobuf_package + ".TokenPagination" + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}token\0") + + mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularStringField(value: &self.token) }() + default: break + } + } + } + + func traverse(visitor: inout V) throws { + if !self.token.isEmpty { + try visitor.visitSingularStringField(value: self.token, fieldNumber: 1) + } + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: Livekit_TokenPagination, rhs: Livekit_TokenPagination) -> Bool { + if lhs.token != rhs.token {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + extension Livekit_ListUpdate: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = _protobuf_package + ".ListUpdate" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "set"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}set\0\u{1}add\0\u{1}del\0\u{1}clear\0") mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -2892,6 +3051,9 @@ extension Livekit_ListUpdate: SwiftProtobuf.Message, SwiftProtobuf._MessageImple // enabled. https://github.com/apple/swift-protobuf/issues/1034 switch fieldNumber { case 1: try { try decoder.decodeRepeatedStringField(value: &self.set) }() + case 2: try { try decoder.decodeRepeatedStringField(value: &self.add) }() + case 3: try { try decoder.decodeRepeatedStringField(value: &self.del) }() + case 4: try { try decoder.decodeSingularBoolField(value: &self.clear) }() default: break } } @@ -2901,11 +3063,23 @@ extension Livekit_ListUpdate: SwiftProtobuf.Message, SwiftProtobuf._MessageImple if !self.set.isEmpty { try visitor.visitRepeatedStringField(value: self.set, fieldNumber: 1) } + if !self.add.isEmpty { + try visitor.visitRepeatedStringField(value: self.add, fieldNumber: 2) + } + if !self.del.isEmpty { + try visitor.visitRepeatedStringField(value: self.del, fieldNumber: 3) + } + if self.clear != false { + try visitor.visitSingularBoolField(value: self.clear, fieldNumber: 4) + } try unknownFields.traverse(visitor: &visitor) } static func ==(lhs: Livekit_ListUpdate, rhs: Livekit_ListUpdate) -> Bool { if lhs.set != rhs.set {return false} + if lhs.add != rhs.add {return false} + if lhs.del != rhs.del {return false} + if lhs.clear != rhs.clear {return false} if lhs.unknownFields != rhs.unknownFields {return false} return true } @@ -2913,22 +3087,7 @@ extension Livekit_ListUpdate: SwiftProtobuf.Message, SwiftProtobuf._MessageImple extension Livekit_Room: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = _protobuf_package + ".Room" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "sid"), - 2: .same(proto: "name"), - 3: .standard(proto: "empty_timeout"), - 14: .standard(proto: "departure_timeout"), - 4: .standard(proto: "max_participants"), - 5: .standard(proto: "creation_time"), - 15: .standard(proto: "creation_time_ms"), - 6: .standard(proto: "turn_password"), - 7: .standard(proto: "enabled_codecs"), - 8: .same(proto: "metadata"), - 9: .standard(proto: "num_participants"), - 11: .standard(proto: "num_publishers"), - 10: .standard(proto: "active_recording"), - 13: .same(proto: "version"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}sid\0\u{1}name\0\u{3}empty_timeout\0\u{3}max_participants\0\u{3}creation_time\0\u{3}turn_password\0\u{3}enabled_codecs\0\u{1}metadata\0\u{3}num_participants\0\u{3}active_recording\0\u{3}num_publishers\0\u{2}\u{2}version\0\u{3}departure_timeout\0\u{3}creation_time_ms\0") mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -3027,10 +3186,7 @@ extension Livekit_Room: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementat extension Livekit_Codec: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = _protobuf_package + ".Codec" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "mime"), - 2: .standard(proto: "fmtp_line"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}mime\0\u{3}fmtp_line\0") mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -3065,11 +3221,7 @@ extension Livekit_Codec: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementa extension Livekit_PlayoutDelay: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = _protobuf_package + ".PlayoutDelay" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "enabled"), - 2: .same(proto: "min"), - 3: .same(proto: "max"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}enabled\0\u{1}min\0\u{1}max\0") mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -3109,17 +3261,7 @@ extension Livekit_PlayoutDelay: SwiftProtobuf.Message, SwiftProtobuf._MessageImp extension Livekit_ParticipantPermission: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = _protobuf_package + ".ParticipantPermission" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "can_subscribe"), - 2: .standard(proto: "can_publish"), - 3: .standard(proto: "can_publish_data"), - 9: .standard(proto: "can_publish_sources"), - 7: .same(proto: "hidden"), - 8: .same(proto: "recorder"), - 10: .standard(proto: "can_update_metadata"), - 11: .same(proto: "agent"), - 12: .standard(proto: "can_subscribe_metrics"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{3}can_subscribe\0\u{3}can_publish\0\u{3}can_publish_data\0\u{2}\u{4}hidden\0\u{1}recorder\0\u{3}can_publish_sources\0\u{3}can_update_metadata\0\u{1}agent\0\u{3}can_subscribe_metrics\0") mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -3189,24 +3331,7 @@ extension Livekit_ParticipantPermission: SwiftProtobuf.Message, SwiftProtobuf._M extension Livekit_ParticipantInfo: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = _protobuf_package + ".ParticipantInfo" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "sid"), - 2: .same(proto: "identity"), - 3: .same(proto: "state"), - 4: .same(proto: "tracks"), - 5: .same(proto: "metadata"), - 6: .standard(proto: "joined_at"), - 17: .standard(proto: "joined_at_ms"), - 9: .same(proto: "name"), - 10: .same(proto: "version"), - 11: .same(proto: "permission"), - 12: .same(proto: "region"), - 13: .standard(proto: "is_publisher"), - 14: .same(proto: "kind"), - 15: .same(proto: "attributes"), - 16: .standard(proto: "disconnect_reason"), - 18: .standard(proto: "kind_details"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}sid\0\u{1}identity\0\u{1}state\0\u{1}tracks\0\u{1}metadata\0\u{3}joined_at\0\u{2}\u{3}name\0\u{1}version\0\u{1}permission\0\u{1}region\0\u{3}is_publisher\0\u{1}kind\0\u{1}attributes\0\u{3}disconnect_reason\0\u{3}joined_at_ms\0\u{3}kind_details\0") fileprivate class _StorageClass { var _sid: String = String() @@ -3380,29 +3505,15 @@ extension Livekit_ParticipantInfo: SwiftProtobuf.Message, SwiftProtobuf._Message } extension Livekit_ParticipantInfo.State: SwiftProtobuf._ProtoNameProviding { - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "JOINING"), - 1: .same(proto: "JOINED"), - 2: .same(proto: "ACTIVE"), - 3: .same(proto: "DISCONNECTED"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{2}\0JOINING\0\u{1}JOINED\0\u{1}ACTIVE\0\u{1}DISCONNECTED\0") } extension Livekit_ParticipantInfo.Kind: SwiftProtobuf._ProtoNameProviding { - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "STANDARD"), - 1: .same(proto: "INGRESS"), - 2: .same(proto: "EGRESS"), - 3: .same(proto: "SIP"), - 4: .same(proto: "AGENT"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{2}\0STANDARD\0\u{1}INGRESS\0\u{1}EGRESS\0\u{1}SIP\0\u{1}AGENT\0") } extension Livekit_ParticipantInfo.KindDetail: SwiftProtobuf._ProtoNameProviding { - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "CLOUD_AGENT"), - 1: .same(proto: "FORWARDED"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{2}\0CLOUD_AGENT\0\u{1}FORWARDED\0") } extension Livekit_Encryption: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { @@ -3425,21 +3536,12 @@ extension Livekit_Encryption: SwiftProtobuf.Message, SwiftProtobuf._MessageImple } extension Livekit_Encryption.TypeEnum: SwiftProtobuf._ProtoNameProviding { - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "NONE"), - 1: .same(proto: "GCM"), - 2: .same(proto: "CUSTOM"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{2}\0NONE\0\u{1}GCM\0\u{1}CUSTOM\0") } extension Livekit_SimulcastCodecInfo: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = _protobuf_package + ".SimulcastCodecInfo" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "mime_type"), - 2: .same(proto: "mid"), - 3: .same(proto: "cid"), - 4: .same(proto: "layers"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{3}mime_type\0\u{1}mid\0\u{1}cid\0\u{1}layers\0\u{3}video_layer_mode\0\u{3}sdp_cid\0") mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -3451,6 +3553,8 @@ extension Livekit_SimulcastCodecInfo: SwiftProtobuf.Message, SwiftProtobuf._Mess case 2: try { try decoder.decodeSingularStringField(value: &self.mid) }() case 3: try { try decoder.decodeSingularStringField(value: &self.cid) }() case 4: try { try decoder.decodeRepeatedMessageField(value: &self.layers) }() + case 5: try { try decoder.decodeSingularEnumField(value: &self.videoLayerMode) }() + case 6: try { try decoder.decodeSingularStringField(value: &self.sdpCid) }() default: break } } @@ -3469,6 +3573,12 @@ extension Livekit_SimulcastCodecInfo: SwiftProtobuf.Message, SwiftProtobuf._Mess if !self.layers.isEmpty { try visitor.visitRepeatedMessageField(value: self.layers, fieldNumber: 4) } + if self.videoLayerMode != .unused { + try visitor.visitSingularEnumField(value: self.videoLayerMode, fieldNumber: 5) + } + if !self.sdpCid.isEmpty { + try visitor.visitSingularStringField(value: self.sdpCid, fieldNumber: 6) + } try unknownFields.traverse(visitor: &visitor) } @@ -3477,6 +3587,8 @@ extension Livekit_SimulcastCodecInfo: SwiftProtobuf.Message, SwiftProtobuf._Mess if lhs.mid != rhs.mid {return false} if lhs.cid != rhs.cid {return false} if lhs.layers != rhs.layers {return false} + if lhs.videoLayerMode != rhs.videoLayerMode {return false} + if lhs.sdpCid != rhs.sdpCid {return false} if lhs.unknownFields != rhs.unknownFields {return false} return true } @@ -3484,28 +3596,7 @@ extension Livekit_SimulcastCodecInfo: SwiftProtobuf.Message, SwiftProtobuf._Mess extension Livekit_TrackInfo: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = _protobuf_package + ".TrackInfo" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "sid"), - 2: .same(proto: "type"), - 3: .same(proto: "name"), - 4: .same(proto: "muted"), - 5: .same(proto: "width"), - 6: .same(proto: "height"), - 7: .same(proto: "simulcast"), - 8: .standard(proto: "disable_dtx"), - 9: .same(proto: "source"), - 10: .same(proto: "layers"), - 11: .standard(proto: "mime_type"), - 12: .same(proto: "mid"), - 13: .same(proto: "codecs"), - 14: .same(proto: "stereo"), - 15: .standard(proto: "disable_red"), - 16: .same(proto: "encryption"), - 17: .same(proto: "stream"), - 18: .same(proto: "version"), - 19: .standard(proto: "audio_features"), - 20: .standard(proto: "backup_codec_policy"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}sid\0\u{1}type\0\u{1}name\0\u{1}muted\0\u{1}width\0\u{1}height\0\u{1}simulcast\0\u{3}disable_dtx\0\u{1}source\0\u{1}layers\0\u{3}mime_type\0\u{1}mid\0\u{1}codecs\0\u{1}stereo\0\u{3}disable_red\0\u{1}encryption\0\u{1}stream\0\u{1}version\0\u{3}audio_features\0\u{3}backup_codec_policy\0") fileprivate class _StorageClass { var _sid: String = String() @@ -3708,13 +3799,7 @@ extension Livekit_TrackInfo: SwiftProtobuf.Message, SwiftProtobuf._MessageImplem extension Livekit_VideoLayer: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = _protobuf_package + ".VideoLayer" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "quality"), - 2: .same(proto: "width"), - 3: .same(proto: "height"), - 4: .same(proto: "bitrate"), - 5: .same(proto: "ssrc"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}quality\0\u{1}width\0\u{1}height\0\u{1}bitrate\0\u{1}ssrc\0\u{3}spatial_layer\0\u{1}rid\0") mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -3727,6 +3812,8 @@ extension Livekit_VideoLayer: SwiftProtobuf.Message, SwiftProtobuf._MessageImple case 3: try { try decoder.decodeSingularUInt32Field(value: &self.height) }() case 4: try { try decoder.decodeSingularUInt32Field(value: &self.bitrate) }() case 5: try { try decoder.decodeSingularUInt32Field(value: &self.ssrc) }() + case 6: try { try decoder.decodeSingularInt32Field(value: &self.spatialLayer) }() + case 7: try { try decoder.decodeSingularStringField(value: &self.rid) }() default: break } } @@ -3748,6 +3835,12 @@ extension Livekit_VideoLayer: SwiftProtobuf.Message, SwiftProtobuf._MessageImple if self.ssrc != 0 { try visitor.visitSingularUInt32Field(value: self.ssrc, fieldNumber: 5) } + if self.spatialLayer != 0 { + try visitor.visitSingularInt32Field(value: self.spatialLayer, fieldNumber: 6) + } + if !self.rid.isEmpty { + try visitor.visitSingularStringField(value: self.rid, fieldNumber: 7) + } try unknownFields.traverse(visitor: &visitor) } @@ -3757,32 +3850,20 @@ extension Livekit_VideoLayer: SwiftProtobuf.Message, SwiftProtobuf._MessageImple if lhs.height != rhs.height {return false} if lhs.bitrate != rhs.bitrate {return false} if lhs.ssrc != rhs.ssrc {return false} + if lhs.spatialLayer != rhs.spatialLayer {return false} + if lhs.rid != rhs.rid {return false} if lhs.unknownFields != rhs.unknownFields {return false} return true } } +extension Livekit_VideoLayer.Mode: SwiftProtobuf._ProtoNameProviding { + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{2}\0MODE_UNUSED\0\u{1}ONE_SPATIAL_LAYER_PER_STREAM\0\u{1}MULTIPLE_SPATIAL_LAYERS_PER_STREAM\0") +} + extension Livekit_DataPacket: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = _protobuf_package + ".DataPacket" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "kind"), - 4: .standard(proto: "participant_identity"), - 5: .standard(proto: "destination_identities"), - 2: .same(proto: "user"), - 3: .same(proto: "speaker"), - 6: .standard(proto: "sip_dtmf"), - 7: .same(proto: "transcription"), - 8: .same(proto: "metrics"), - 9: .standard(proto: "chat_message"), - 10: .standard(proto: "rpc_request"), - 11: .standard(proto: "rpc_ack"), - 12: .standard(proto: "rpc_response"), - 13: .standard(proto: "stream_header"), - 14: .standard(proto: "stream_chunk"), - 15: .standard(proto: "stream_trailer"), - 16: .same(proto: "sequence"), - 17: .standard(proto: "participant_sid"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}kind\0\u{1}user\0\u{1}speaker\0\u{3}participant_identity\0\u{3}destination_identities\0\u{3}sip_dtmf\0\u{1}transcription\0\u{1}metrics\0\u{3}chat_message\0\u{3}rpc_request\0\u{3}rpc_ack\0\u{3}rpc_response\0\u{3}stream_header\0\u{3}stream_chunk\0\u{3}stream_trailer\0\u{1}sequence\0\u{3}participant_sid\0\u{3}encrypted_packet\0") fileprivate class _StorageClass { var _kind: Livekit_DataPacket.Kind = .reliable @@ -3986,6 +4067,19 @@ extension Livekit_DataPacket: SwiftProtobuf.Message, SwiftProtobuf._MessageImple }() case 16: try { try decoder.decodeSingularUInt32Field(value: &_storage._sequence) }() case 17: try { try decoder.decodeSingularStringField(value: &_storage._participantSid) }() + case 18: try { + var v: Livekit_EncryptedPacket? + var hadOneofValue = false + if let current = _storage._value { + hadOneofValue = true + if case .encryptedPacket(let m) = current {v = m} + } + try decoder.decodeSingularMessageField(value: &v) + if let v = v { + if hadOneofValue {try decoder.handleConflictingOneOf()} + _storage._value = .encryptedPacket(v) + } + }() default: break } } @@ -4067,6 +4161,9 @@ extension Livekit_DataPacket: SwiftProtobuf.Message, SwiftProtobuf._MessageImple if !_storage._participantSid.isEmpty { try visitor.visitSingularStringField(value: _storage._participantSid, fieldNumber: 17) } + try { if case .encryptedPacket(let v)? = _storage._value { + try visitor.visitSingularMessageField(value: v, fieldNumber: 18) + } }() } try unknownFields.traverse(visitor: &visitor) } @@ -4092,17 +4189,226 @@ extension Livekit_DataPacket: SwiftProtobuf.Message, SwiftProtobuf._MessageImple } extension Livekit_DataPacket.Kind: SwiftProtobuf._ProtoNameProviding { - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "RELIABLE"), - 1: .same(proto: "LOSSY"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{2}\0RELIABLE\0\u{1}LOSSY\0") +} + +extension Livekit_EncryptedPacket: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = _protobuf_package + ".EncryptedPacket" + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{3}encryption_type\0\u{1}iv\0\u{3}key_index\0\u{3}encrypted_value\0") + + mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularEnumField(value: &self.encryptionType) }() + case 2: try { try decoder.decodeSingularBytesField(value: &self.iv) }() + case 3: try { try decoder.decodeSingularUInt32Field(value: &self.keyIndex) }() + case 4: try { try decoder.decodeSingularBytesField(value: &self.encryptedValue) }() + default: break + } + } + } + + func traverse(visitor: inout V) throws { + if self.encryptionType != .none { + try visitor.visitSingularEnumField(value: self.encryptionType, fieldNumber: 1) + } + if !self.iv.isEmpty { + try visitor.visitSingularBytesField(value: self.iv, fieldNumber: 2) + } + if self.keyIndex != 0 { + try visitor.visitSingularUInt32Field(value: self.keyIndex, fieldNumber: 3) + } + if !self.encryptedValue.isEmpty { + try visitor.visitSingularBytesField(value: self.encryptedValue, fieldNumber: 4) + } + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: Livekit_EncryptedPacket, rhs: Livekit_EncryptedPacket) -> Bool { + if lhs.encryptionType != rhs.encryptionType {return false} + if lhs.iv != rhs.iv {return false} + if lhs.keyIndex != rhs.keyIndex {return false} + if lhs.encryptedValue != rhs.encryptedValue {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Livekit_EncryptedPacketPayload: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = _protobuf_package + ".EncryptedPacketPayload" + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}user\0\u{4}\u{2}chat_message\0\u{3}rpc_request\0\u{3}rpc_ack\0\u{3}rpc_response\0\u{3}stream_header\0\u{3}stream_chunk\0\u{3}stream_trailer\0") + + mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { + var v: Livekit_UserPacket? + var hadOneofValue = false + if let current = self.value { + hadOneofValue = true + if case .user(let m) = current {v = m} + } + try decoder.decodeSingularMessageField(value: &v) + if let v = v { + if hadOneofValue {try decoder.handleConflictingOneOf()} + self.value = .user(v) + } + }() + case 3: try { + var v: Livekit_ChatMessage? + var hadOneofValue = false + if let current = self.value { + hadOneofValue = true + if case .chatMessage(let m) = current {v = m} + } + try decoder.decodeSingularMessageField(value: &v) + if let v = v { + if hadOneofValue {try decoder.handleConflictingOneOf()} + self.value = .chatMessage(v) + } + }() + case 4: try { + var v: Livekit_RpcRequest? + var hadOneofValue = false + if let current = self.value { + hadOneofValue = true + if case .rpcRequest(let m) = current {v = m} + } + try decoder.decodeSingularMessageField(value: &v) + if let v = v { + if hadOneofValue {try decoder.handleConflictingOneOf()} + self.value = .rpcRequest(v) + } + }() + case 5: try { + var v: Livekit_RpcAck? + var hadOneofValue = false + if let current = self.value { + hadOneofValue = true + if case .rpcAck(let m) = current {v = m} + } + try decoder.decodeSingularMessageField(value: &v) + if let v = v { + if hadOneofValue {try decoder.handleConflictingOneOf()} + self.value = .rpcAck(v) + } + }() + case 6: try { + var v: Livekit_RpcResponse? + var hadOneofValue = false + if let current = self.value { + hadOneofValue = true + if case .rpcResponse(let m) = current {v = m} + } + try decoder.decodeSingularMessageField(value: &v) + if let v = v { + if hadOneofValue {try decoder.handleConflictingOneOf()} + self.value = .rpcResponse(v) + } + }() + case 7: try { + var v: Livekit_DataStream.Header? + var hadOneofValue = false + if let current = self.value { + hadOneofValue = true + if case .streamHeader(let m) = current {v = m} + } + try decoder.decodeSingularMessageField(value: &v) + if let v = v { + if hadOneofValue {try decoder.handleConflictingOneOf()} + self.value = .streamHeader(v) + } + }() + case 8: try { + var v: Livekit_DataStream.Chunk? + var hadOneofValue = false + if let current = self.value { + hadOneofValue = true + if case .streamChunk(let m) = current {v = m} + } + try decoder.decodeSingularMessageField(value: &v) + if let v = v { + if hadOneofValue {try decoder.handleConflictingOneOf()} + self.value = .streamChunk(v) + } + }() + case 9: try { + var v: Livekit_DataStream.Trailer? + var hadOneofValue = false + if let current = self.value { + hadOneofValue = true + if case .streamTrailer(let m) = current {v = m} + } + try decoder.decodeSingularMessageField(value: &v) + if let v = v { + if hadOneofValue {try decoder.handleConflictingOneOf()} + self.value = .streamTrailer(v) + } + }() + default: break + } + } + } + + func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + switch self.value { + case .user?: try { + guard case .user(let v)? = self.value else { preconditionFailure() } + try visitor.visitSingularMessageField(value: v, fieldNumber: 1) + }() + case .chatMessage?: try { + guard case .chatMessage(let v)? = self.value else { preconditionFailure() } + try visitor.visitSingularMessageField(value: v, fieldNumber: 3) + }() + case .rpcRequest?: try { + guard case .rpcRequest(let v)? = self.value else { preconditionFailure() } + try visitor.visitSingularMessageField(value: v, fieldNumber: 4) + }() + case .rpcAck?: try { + guard case .rpcAck(let v)? = self.value else { preconditionFailure() } + try visitor.visitSingularMessageField(value: v, fieldNumber: 5) + }() + case .rpcResponse?: try { + guard case .rpcResponse(let v)? = self.value else { preconditionFailure() } + try visitor.visitSingularMessageField(value: v, fieldNumber: 6) + }() + case .streamHeader?: try { + guard case .streamHeader(let v)? = self.value else { preconditionFailure() } + try visitor.visitSingularMessageField(value: v, fieldNumber: 7) + }() + case .streamChunk?: try { + guard case .streamChunk(let v)? = self.value else { preconditionFailure() } + try visitor.visitSingularMessageField(value: v, fieldNumber: 8) + }() + case .streamTrailer?: try { + guard case .streamTrailer(let v)? = self.value else { preconditionFailure() } + try visitor.visitSingularMessageField(value: v, fieldNumber: 9) + }() + case nil: break + } + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: Livekit_EncryptedPacketPayload, rhs: Livekit_EncryptedPacketPayload) -> Bool { + if lhs.value != rhs.value {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } } extension Livekit_ActiveSpeakerUpdate: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = _protobuf_package + ".ActiveSpeakerUpdate" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "speakers"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}speakers\0") mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -4132,11 +4438,7 @@ extension Livekit_ActiveSpeakerUpdate: SwiftProtobuf.Message, SwiftProtobuf._Mes extension Livekit_SpeakerInfo: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = _protobuf_package + ".SpeakerInfo" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "sid"), - 2: .same(proto: "level"), - 3: .same(proto: "active"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}sid\0\u{1}level\0\u{1}active\0") mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -4176,18 +4478,7 @@ extension Livekit_SpeakerInfo: SwiftProtobuf.Message, SwiftProtobuf._MessageImpl extension Livekit_UserPacket: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = _protobuf_package + ".UserPacket" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "participant_sid"), - 5: .standard(proto: "participant_identity"), - 2: .same(proto: "payload"), - 3: .standard(proto: "destination_sids"), - 6: .standard(proto: "destination_identities"), - 4: .same(proto: "topic"), - 8: .same(proto: "id"), - 9: .standard(proto: "start_time"), - 10: .standard(proto: "end_time"), - 11: .same(proto: "nonce"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{3}participant_sid\0\u{1}payload\0\u{3}destination_sids\0\u{1}topic\0\u{3}participant_identity\0\u{3}destination_identities\0\u{2}\u{2}id\0\u{3}start_time\0\u{3}end_time\0\u{1}nonce\0") mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -4266,10 +4557,7 @@ extension Livekit_UserPacket: SwiftProtobuf.Message, SwiftProtobuf._MessageImple extension Livekit_SipDTMF: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = _protobuf_package + ".SipDTMF" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 3: .same(proto: "code"), - 4: .same(proto: "digit"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{2}\u{3}code\0\u{1}digit\0") mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -4304,11 +4592,7 @@ extension Livekit_SipDTMF: SwiftProtobuf.Message, SwiftProtobuf._MessageImplemen extension Livekit_Transcription: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = _protobuf_package + ".Transcription" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 2: .standard(proto: "transcribed_participant_identity"), - 3: .standard(proto: "track_id"), - 4: .same(proto: "segments"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{4}\u{2}transcribed_participant_identity\0\u{3}track_id\0\u{1}segments\0") mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -4348,14 +4632,7 @@ extension Livekit_Transcription: SwiftProtobuf.Message, SwiftProtobuf._MessageIm extension Livekit_TranscriptionSegment: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = _protobuf_package + ".TranscriptionSegment" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "id"), - 2: .same(proto: "text"), - 3: .standard(proto: "start_time"), - 4: .standard(proto: "end_time"), - 5: .same(proto: "final"), - 6: .same(proto: "language"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}id\0\u{1}text\0\u{3}start_time\0\u{3}end_time\0\u{1}final\0\u{1}language\0") mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -4410,14 +4687,7 @@ extension Livekit_TranscriptionSegment: SwiftProtobuf.Message, SwiftProtobuf._Me extension Livekit_ChatMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = _protobuf_package + ".ChatMessage" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "id"), - 2: .same(proto: "timestamp"), - 3: .standard(proto: "edit_timestamp"), - 4: .same(proto: "message"), - 5: .same(proto: "deleted"), - 6: .same(proto: "generated"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}id\0\u{1}timestamp\0\u{3}edit_timestamp\0\u{1}message\0\u{1}deleted\0\u{1}generated\0") mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -4476,13 +4746,7 @@ extension Livekit_ChatMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImpl extension Livekit_RpcRequest: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = _protobuf_package + ".RpcRequest" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "id"), - 2: .same(proto: "method"), - 3: .same(proto: "payload"), - 4: .standard(proto: "response_timeout_ms"), - 5: .same(proto: "version"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}id\0\u{1}method\0\u{1}payload\0\u{3}response_timeout_ms\0\u{1}version\0") mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -4532,9 +4796,7 @@ extension Livekit_RpcRequest: SwiftProtobuf.Message, SwiftProtobuf._MessageImple extension Livekit_RpcAck: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = _protobuf_package + ".RpcAck" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "request_id"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{3}request_id\0") mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -4564,11 +4826,7 @@ extension Livekit_RpcAck: SwiftProtobuf.Message, SwiftProtobuf._MessageImplement extension Livekit_RpcResponse: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = _protobuf_package + ".RpcResponse" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "request_id"), - 2: .same(proto: "payload"), - 3: .same(proto: "error"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{3}request_id\0\u{1}payload\0\u{1}error\0") mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -4635,11 +4893,7 @@ extension Livekit_RpcResponse: SwiftProtobuf.Message, SwiftProtobuf._MessageImpl extension Livekit_RpcError: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = _protobuf_package + ".RpcError" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "code"), - 2: .same(proto: "message"), - 3: .same(proto: "data"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}code\0\u{1}message\0\u{1}data\0") mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -4679,10 +4933,7 @@ extension Livekit_RpcError: SwiftProtobuf.Message, SwiftProtobuf._MessageImpleme extension Livekit_ParticipantTracks: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = _protobuf_package + ".ParticipantTracks" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "participant_sid"), - 2: .standard(proto: "track_sids"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{3}participant_sid\0\u{3}track_sids\0") mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -4717,15 +4968,7 @@ extension Livekit_ParticipantTracks: SwiftProtobuf.Message, SwiftProtobuf._Messa extension Livekit_ServerInfo: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = _protobuf_package + ".ServerInfo" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "edition"), - 2: .same(proto: "version"), - 3: .same(proto: "protocol"), - 4: .same(proto: "region"), - 5: .standard(proto: "node_id"), - 6: .standard(proto: "debug_info"), - 7: .standard(proto: "agent_protocol"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}edition\0\u{1}version\0\u{1}protocol\0\u{1}region\0\u{3}node_id\0\u{3}debug_info\0\u{3}agent_protocol\0") mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -4784,27 +5027,12 @@ extension Livekit_ServerInfo: SwiftProtobuf.Message, SwiftProtobuf._MessageImple } extension Livekit_ServerInfo.Edition: SwiftProtobuf._ProtoNameProviding { - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "Standard"), - 1: .same(proto: "Cloud"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{2}\0Standard\0\u{1}Cloud\0") } extension Livekit_ClientInfo: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = _protobuf_package + ".ClientInfo" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "sdk"), - 2: .same(proto: "version"), - 3: .same(proto: "protocol"), - 4: .same(proto: "os"), - 5: .standard(proto: "os_version"), - 6: .standard(proto: "device_model"), - 7: .same(proto: "browser"), - 8: .standard(proto: "browser_version"), - 9: .same(proto: "address"), - 10: .same(proto: "network"), - 11: .standard(proto: "other_sdks"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}sdk\0\u{1}version\0\u{1}protocol\0\u{1}os\0\u{3}os_version\0\u{3}device_model\0\u{1}browser\0\u{3}browser_version\0\u{1}address\0\u{1}network\0\u{3}other_sdks\0") mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -4883,33 +5111,12 @@ extension Livekit_ClientInfo: SwiftProtobuf.Message, SwiftProtobuf._MessageImple } extension Livekit_ClientInfo.SDK: SwiftProtobuf._ProtoNameProviding { - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "UNKNOWN"), - 1: .same(proto: "JS"), - 2: .same(proto: "SWIFT"), - 3: .same(proto: "ANDROID"), - 4: .same(proto: "FLUTTER"), - 5: .same(proto: "GO"), - 6: .same(proto: "UNITY"), - 7: .same(proto: "REACT_NATIVE"), - 8: .same(proto: "RUST"), - 9: .same(proto: "PYTHON"), - 10: .same(proto: "CPP"), - 11: .same(proto: "UNITY_WEB"), - 12: .same(proto: "NODE"), - 13: .same(proto: "UNREAL"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{2}\0UNKNOWN\0\u{1}JS\0\u{1}SWIFT\0\u{1}ANDROID\0\u{1}FLUTTER\0\u{1}GO\0\u{1}UNITY\0\u{1}REACT_NATIVE\0\u{1}RUST\0\u{1}PYTHON\0\u{1}CPP\0\u{1}UNITY_WEB\0\u{1}NODE\0\u{1}UNREAL\0\u{1}ESP32\0") } extension Livekit_ClientConfiguration: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = _protobuf_package + ".ClientConfiguration" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "video"), - 2: .same(proto: "screen"), - 3: .standard(proto: "resume_connection"), - 4: .standard(proto: "disabled_codecs"), - 5: .standard(proto: "force_relay"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}video\0\u{1}screen\0\u{3}resume_connection\0\u{3}disabled_codecs\0\u{3}force_relay\0") mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -4963,9 +5170,7 @@ extension Livekit_ClientConfiguration: SwiftProtobuf.Message, SwiftProtobuf._Mes extension Livekit_VideoConfiguration: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = _protobuf_package + ".VideoConfiguration" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "hardware_encoder"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{3}hardware_encoder\0") mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -4995,10 +5200,7 @@ extension Livekit_VideoConfiguration: SwiftProtobuf.Message, SwiftProtobuf._Mess extension Livekit_DisabledCodecs: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = _protobuf_package + ".DisabledCodecs" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "codecs"), - 2: .same(proto: "publish"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}codecs\0\u{1}publish\0") mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -5033,17 +5235,7 @@ extension Livekit_DisabledCodecs: SwiftProtobuf.Message, SwiftProtobuf._MessageI extension Livekit_RTPDrift: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = _protobuf_package + ".RTPDrift" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "start_time"), - 2: .standard(proto: "end_time"), - 3: .same(proto: "duration"), - 4: .standard(proto: "start_timestamp"), - 5: .standard(proto: "end_timestamp"), - 6: .standard(proto: "rtp_clock_ticks"), - 7: .standard(proto: "drift_samples"), - 8: .standard(proto: "drift_ms"), - 9: .standard(proto: "clock_rate"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{3}start_time\0\u{3}end_time\0\u{1}duration\0\u{3}start_timestamp\0\u{3}end_timestamp\0\u{3}rtp_clock_ticks\0\u{3}drift_samples\0\u{3}drift_ms\0\u{3}clock_rate\0") mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -5117,53 +5309,7 @@ extension Livekit_RTPDrift: SwiftProtobuf.Message, SwiftProtobuf._MessageImpleme extension Livekit_RTPStats: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = _protobuf_package + ".RTPStats" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "start_time"), - 2: .standard(proto: "end_time"), - 3: .same(proto: "duration"), - 4: .same(proto: "packets"), - 5: .standard(proto: "packet_rate"), - 6: .same(proto: "bytes"), - 39: .standard(proto: "header_bytes"), - 7: .same(proto: "bitrate"), - 8: .standard(proto: "packets_lost"), - 9: .standard(proto: "packet_loss_rate"), - 10: .standard(proto: "packet_loss_percentage"), - 11: .standard(proto: "packets_duplicate"), - 12: .standard(proto: "packet_duplicate_rate"), - 13: .standard(proto: "bytes_duplicate"), - 40: .standard(proto: "header_bytes_duplicate"), - 14: .standard(proto: "bitrate_duplicate"), - 15: .standard(proto: "packets_padding"), - 16: .standard(proto: "packet_padding_rate"), - 17: .standard(proto: "bytes_padding"), - 41: .standard(proto: "header_bytes_padding"), - 18: .standard(proto: "bitrate_padding"), - 19: .standard(proto: "packets_out_of_order"), - 20: .same(proto: "frames"), - 21: .standard(proto: "frame_rate"), - 22: .standard(proto: "jitter_current"), - 23: .standard(proto: "jitter_max"), - 24: .standard(proto: "gap_histogram"), - 25: .same(proto: "nacks"), - 37: .standard(proto: "nack_acks"), - 26: .standard(proto: "nack_misses"), - 38: .standard(proto: "nack_repeated"), - 27: .same(proto: "plis"), - 28: .standard(proto: "last_pli"), - 29: .same(proto: "firs"), - 30: .standard(proto: "last_fir"), - 31: .standard(proto: "rtt_current"), - 32: .standard(proto: "rtt_max"), - 33: .standard(proto: "key_frames"), - 34: .standard(proto: "last_key_frame"), - 35: .standard(proto: "layer_lock_plis"), - 36: .standard(proto: "last_layer_lock_pli"), - 44: .standard(proto: "packet_drift"), - 45: .standard(proto: "ntp_report_drift"), - 46: .standard(proto: "rebased_report_drift"), - 47: .standard(proto: "received_report_drift"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{3}start_time\0\u{3}end_time\0\u{1}duration\0\u{1}packets\0\u{3}packet_rate\0\u{1}bytes\0\u{1}bitrate\0\u{3}packets_lost\0\u{3}packet_loss_rate\0\u{3}packet_loss_percentage\0\u{3}packets_duplicate\0\u{3}packet_duplicate_rate\0\u{3}bytes_duplicate\0\u{3}bitrate_duplicate\0\u{3}packets_padding\0\u{3}packet_padding_rate\0\u{3}bytes_padding\0\u{3}bitrate_padding\0\u{3}packets_out_of_order\0\u{1}frames\0\u{3}frame_rate\0\u{3}jitter_current\0\u{3}jitter_max\0\u{3}gap_histogram\0\u{1}nacks\0\u{3}nack_misses\0\u{1}plis\0\u{3}last_pli\0\u{1}firs\0\u{3}last_fir\0\u{3}rtt_current\0\u{3}rtt_max\0\u{3}key_frames\0\u{3}last_key_frame\0\u{3}layer_lock_plis\0\u{3}last_layer_lock_pli\0\u{3}nack_acks\0\u{3}nack_repeated\0\u{3}header_bytes\0\u{3}header_bytes_duplicate\0\u{3}header_bytes_padding\0\u{4}\u{3}packet_drift\0\u{3}ntp_report_drift\0\u{3}rebased_report_drift\0\u{3}received_report_drift\0") fileprivate class _StorageClass { var _startTime: SwiftProtobuf.Google_Protobuf_Timestamp? = nil @@ -5541,15 +5687,7 @@ extension Livekit_RTPStats: SwiftProtobuf.Message, SwiftProtobuf._MessageImpleme extension Livekit_RTCPSenderReportState: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = _protobuf_package + ".RTCPSenderReportState" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "rtp_timestamp"), - 2: .standard(proto: "rtp_timestamp_ext"), - 3: .standard(proto: "ntp_timestamp"), - 4: .same(proto: "at"), - 5: .standard(proto: "at_adjusted"), - 6: .same(proto: "packets"), - 7: .same(proto: "octets"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{3}rtp_timestamp\0\u{3}rtp_timestamp_ext\0\u{3}ntp_timestamp\0\u{1}at\0\u{3}at_adjusted\0\u{1}packets\0\u{1}octets\0") mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -5609,16 +5747,7 @@ extension Livekit_RTCPSenderReportState: SwiftProtobuf.Message, SwiftProtobuf._M extension Livekit_RTPForwarderState: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = _protobuf_package + ".RTPForwarderState" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "started"), - 2: .standard(proto: "reference_layer_spatial"), - 3: .standard(proto: "pre_start_time"), - 4: .standard(proto: "ext_first_timestamp"), - 5: .standard(proto: "dummy_start_timestamp_offset"), - 6: .standard(proto: "rtp_munger"), - 7: .standard(proto: "vp8_munger"), - 8: .standard(proto: "sender_report_state"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}started\0\u{3}reference_layer_spatial\0\u{3}pre_start_time\0\u{3}ext_first_timestamp\0\u{3}dummy_start_timestamp_offset\0\u{3}rtp_munger\0\u{3}vp8_munger\0\u{3}sender_report_state\0") fileprivate class _StorageClass { var _started: Bool = false @@ -5749,14 +5878,7 @@ extension Livekit_RTPForwarderState: SwiftProtobuf.Message, SwiftProtobuf._Messa extension Livekit_RTPMungerState: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = _protobuf_package + ".RTPMungerState" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "ext_last_sequence_number"), - 2: .standard(proto: "ext_second_last_sequence_number"), - 3: .standard(proto: "ext_last_timestamp"), - 4: .standard(proto: "ext_second_last_timestamp"), - 5: .standard(proto: "last_marker"), - 6: .standard(proto: "second_last_marker"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{3}ext_last_sequence_number\0\u{3}ext_second_last_sequence_number\0\u{3}ext_last_timestamp\0\u{3}ext_second_last_timestamp\0\u{3}last_marker\0\u{3}second_last_marker\0") mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -5811,15 +5933,7 @@ extension Livekit_RTPMungerState: SwiftProtobuf.Message, SwiftProtobuf._MessageI extension Livekit_VP8MungerState: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = _protobuf_package + ".VP8MungerState" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "ext_last_picture_id"), - 2: .standard(proto: "picture_id_used"), - 3: .standard(proto: "last_tl0_pic_idx"), - 4: .standard(proto: "tl0_pic_idx_used"), - 5: .standard(proto: "tid_used"), - 6: .standard(proto: "last_key_idx"), - 7: .standard(proto: "key_idx_used"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{3}ext_last_picture_id\0\u{3}picture_id_used\0\u{3}last_tl0_pic_idx\0\u{3}tl0_pic_idx_used\0\u{3}tid_used\0\u{3}last_key_idx\0\u{3}key_idx_used\0") mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -5879,10 +5993,7 @@ extension Livekit_VP8MungerState: SwiftProtobuf.Message, SwiftProtobuf._MessageI extension Livekit_TimedVersion: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = _protobuf_package + ".TimedVersion" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "unix_micro"), - 2: .same(proto: "ticks"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{3}unix_micro\0\u{1}ticks\0") mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -5935,23 +6046,12 @@ extension Livekit_DataStream: SwiftProtobuf.Message, SwiftProtobuf._MessageImple } extension Livekit_DataStream.OperationType: SwiftProtobuf._ProtoNameProviding { - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "CREATE"), - 1: .same(proto: "UPDATE"), - 2: .same(proto: "DELETE"), - 3: .same(proto: "REACTION"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{2}\0CREATE\0\u{1}UPDATE\0\u{1}DELETE\0\u{1}REACTION\0") } extension Livekit_DataStream.TextHeader: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = Livekit_DataStream.protoMessageName + ".TextHeader" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "operation_type"), - 2: .same(proto: "version"), - 3: .standard(proto: "reply_to_stream_id"), - 4: .standard(proto: "attached_stream_ids"), - 5: .same(proto: "generated"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{3}operation_type\0\u{1}version\0\u{3}reply_to_stream_id\0\u{3}attached_stream_ids\0\u{1}generated\0") mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -6001,9 +6101,7 @@ extension Livekit_DataStream.TextHeader: SwiftProtobuf.Message, SwiftProtobuf._M extension Livekit_DataStream.ByteHeader: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = Livekit_DataStream.protoMessageName + ".ByteHeader" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "name"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}name\0") mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -6033,17 +6131,7 @@ extension Livekit_DataStream.ByteHeader: SwiftProtobuf.Message, SwiftProtobuf._M extension Livekit_DataStream.Header: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = Livekit_DataStream.protoMessageName + ".Header" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "stream_id"), - 2: .same(proto: "timestamp"), - 3: .same(proto: "topic"), - 4: .standard(proto: "mime_type"), - 5: .standard(proto: "total_length"), - 7: .standard(proto: "encryption_type"), - 8: .same(proto: "attributes"), - 9: .standard(proto: "text_header"), - 10: .standard(proto: "byte_header"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{3}stream_id\0\u{1}timestamp\0\u{1}topic\0\u{3}mime_type\0\u{3}total_length\0\u{4}\u{2}encryption_type\0\u{1}attributes\0\u{3}text_header\0\u{3}byte_header\0") mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -6145,13 +6233,7 @@ extension Livekit_DataStream.Header: SwiftProtobuf.Message, SwiftProtobuf._Messa extension Livekit_DataStream.Chunk: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = Livekit_DataStream.protoMessageName + ".Chunk" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "stream_id"), - 2: .standard(proto: "chunk_index"), - 3: .same(proto: "content"), - 4: .same(proto: "version"), - 5: .same(proto: "iv"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{3}stream_id\0\u{3}chunk_index\0\u{1}content\0\u{1}version\0\u{1}iv\0") mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -6205,11 +6287,7 @@ extension Livekit_DataStream.Chunk: SwiftProtobuf.Message, SwiftProtobuf._Messag extension Livekit_DataStream.Trailer: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = Livekit_DataStream.protoMessageName + ".Trailer" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "stream_id"), - 2: .same(proto: "reason"), - 3: .same(proto: "attributes"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{3}stream_id\0\u{1}reason\0\u{1}attributes\0") mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -6249,10 +6327,7 @@ extension Livekit_DataStream.Trailer: SwiftProtobuf.Message, SwiftProtobuf._Mess extension Livekit_WebhookConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = _protobuf_package + ".WebhookConfig" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "url"), - 2: .standard(proto: "signing_key"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}url\0\u{3}signing_key\0") mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { diff --git a/Sources/LiveKit/Protos/livekit_rtc.pb.swift b/Sources/LiveKit/Protos/livekit_rtc.pb.swift index 0442f3415..f854dce63 100644 --- a/Sources/LiveKit/Protos/livekit_rtc.pb.swift +++ b/Sources/LiveKit/Protos/livekit_rtc.pb.swift @@ -148,7 +148,7 @@ struct Livekit_SignalRequest: Sendable { var message: Livekit_SignalRequest.OneOf_Message? = nil - /// initial join exchange, for publisher + /// participant offer for publisher var offer: Livekit_SessionDescription { get { if case .offer(let v)? = message {return v} @@ -157,7 +157,7 @@ struct Livekit_SignalRequest: Sendable { set {message = .offer(newValue)} } - /// participant answering publisher offer + /// participant answering subscriber offer var answer: Livekit_SessionDescription { get { if case .answer(let v)? = message {return v} @@ -304,9 +304,9 @@ struct Livekit_SignalRequest: Sendable { var unknownFields = SwiftProtobuf.UnknownStorage() enum OneOf_Message: Equatable, Sendable { - /// initial join exchange, for publisher + /// participant offer for publisher case offer(Livekit_SessionDescription) - /// participant answering publisher offer + /// participant answering subscriber offer case answer(Livekit_SessionDescription) case trickle(Livekit_TrickleRequest) case addTrack(Livekit_AddTrackRequest) @@ -559,6 +559,15 @@ struct Livekit_SignalResponse: Sendable { set {message = .roomMoved(newValue)} } + /// notify number of required media sections to satisfy subscribed tracks + var mediaSectionsRequirement: Livekit_MediaSectionsRequirement { + get { + if case .mediaSectionsRequirement(let v)? = message {return v} + return Livekit_MediaSectionsRequirement() + } + set {message = .mediaSectionsRequirement(newValue)} + } + var unknownFields = SwiftProtobuf.UnknownStorage() enum OneOf_Message: Equatable, Sendable { @@ -609,6 +618,8 @@ struct Livekit_SignalResponse: Sendable { case trackSubscribed(Livekit_TrackSubscribed) /// notify to the participant when they have been moved to a new room case roomMoved(Livekit_RoomMovedResponse) + /// notify number of required media sections to satisfy subscribed tracks + case mediaSectionsRequirement(Livekit_MediaSectionsRequirement) } @@ -624,6 +635,10 @@ struct Livekit_SimulcastCodec: Sendable { var cid: String = String() + var layers: [Livekit_VideoLayer] = [] + + var videoLayerMode: Livekit_VideoLayer.Mode = .unused + var unknownFields = SwiftProtobuf.UnknownStorage() init() {} @@ -650,7 +665,6 @@ struct Livekit_AddTrackRequest: @unchecked Sendable { set {_uniqueStorage()._type = newValue} } - /// to be deprecated in favor of layers var width: UInt32 { get {return _storage._width} set {_uniqueStorage()._width = newValue} @@ -1418,7 +1432,9 @@ struct Livekit_SyncState: Sendable { // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. - /// last subscribe answer before reconnecting + /// last subscribe/publish answer before reconnecting + /// subscribe answer if using dual peer connection + /// publish answer if using single peer connection var answer: Livekit_SessionDescription { get {return _answer ?? Livekit_SessionDescription()} set {_answer = newValue} @@ -1441,7 +1457,9 @@ struct Livekit_SyncState: Sendable { var dataChannels: [Livekit_DataChannelInfo] = [] - /// last received server side offer before reconnecting + /// last received server side offer/sent client side offer before reconnecting + /// received server side offer if using dual peer connection + /// sent client side offer if using single peer connection var offer: Livekit_SessionDescription { get {return _offer ?? Livekit_SessionDescription()} set {_offer = newValue} @@ -1753,53 +1771,197 @@ struct Livekit_TrackSubscribed: Sendable { init() {} } +struct Livekit_ConnectionSettings: Sendable { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + var autoSubscribe: Bool = false + + var adaptiveStream: Bool = false + + var subscriberAllowPause: Bool { + get {return _subscriberAllowPause ?? false} + set {_subscriberAllowPause = newValue} + } + /// Returns true if `subscriberAllowPause` has been explicitly set. + var hasSubscriberAllowPause: Bool {return self._subscriberAllowPause != nil} + /// Clears the value of `subscriberAllowPause`. Subsequent reads from it will return its default value. + mutating func clearSubscriberAllowPause() {self._subscriberAllowPause = nil} + + var disableIceLite: Bool = false + + var unknownFields = SwiftProtobuf.UnknownStorage() + + init() {} + + fileprivate var _subscriberAllowPause: Bool? = nil +} + +struct Livekit_JoinRequest: @unchecked Sendable { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + var clientInfo: Livekit_ClientInfo { + get {return _storage._clientInfo ?? Livekit_ClientInfo()} + set {_uniqueStorage()._clientInfo = newValue} + } + /// Returns true if `clientInfo` has been explicitly set. + var hasClientInfo: Bool {return _storage._clientInfo != nil} + /// Clears the value of `clientInfo`. Subsequent reads from it will return its default value. + mutating func clearClientInfo() {_uniqueStorage()._clientInfo = nil} + + var connectionSettings: Livekit_ConnectionSettings { + get {return _storage._connectionSettings ?? Livekit_ConnectionSettings()} + set {_uniqueStorage()._connectionSettings = newValue} + } + /// Returns true if `connectionSettings` has been explicitly set. + var hasConnectionSettings: Bool {return _storage._connectionSettings != nil} + /// Clears the value of `connectionSettings`. Subsequent reads from it will return its default value. + mutating func clearConnectionSettings() {_uniqueStorage()._connectionSettings = nil} + + /// if not empty, will overwrite `metadata` in token + var metadata: String { + get {return _storage._metadata} + set {_uniqueStorage()._metadata = newValue} + } + + /// will set keys provided via this + /// will overwrite if the same key is in the token + /// will not delete keys from token if there is a key collision and this sets that key to empty value + var participantAttributes: Dictionary { + get {return _storage._participantAttributes} + set {_uniqueStorage()._participantAttributes = newValue} + } + + var addTrackRequests: [Livekit_AddTrackRequest] { + get {return _storage._addTrackRequests} + set {_uniqueStorage()._addTrackRequests = newValue} + } + + var publisherOffer: Livekit_SessionDescription { + get {return _storage._publisherOffer ?? Livekit_SessionDescription()} + set {_uniqueStorage()._publisherOffer = newValue} + } + /// Returns true if `publisherOffer` has been explicitly set. + var hasPublisherOffer: Bool {return _storage._publisherOffer != nil} + /// Clears the value of `publisherOffer`. Subsequent reads from it will return its default value. + mutating func clearPublisherOffer() {_uniqueStorage()._publisherOffer = nil} + + var reconnect: Bool { + get {return _storage._reconnect} + set {_uniqueStorage()._reconnect = newValue} + } + + var reconnectReason: Livekit_ReconnectReason { + get {return _storage._reconnectReason} + set {_uniqueStorage()._reconnectReason = newValue} + } + + var participantSid: String { + get {return _storage._participantSid} + set {_uniqueStorage()._participantSid = newValue} + } + + var syncState: Livekit_SyncState { + get {return _storage._syncState ?? Livekit_SyncState()} + set {_uniqueStorage()._syncState = newValue} + } + /// Returns true if `syncState` has been explicitly set. + var hasSyncState: Bool {return _storage._syncState != nil} + /// Clears the value of `syncState`. Subsequent reads from it will return its default value. + mutating func clearSyncState() {_uniqueStorage()._syncState = nil} + + var unknownFields = SwiftProtobuf.UnknownStorage() + + init() {} + + fileprivate var _storage = _StorageClass.defaultInstance +} + +struct Livekit_WrappedJoinRequest: Sendable { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + var compression: Livekit_WrappedJoinRequest.Compression = .none + + /// marshalled JoinRequest + potentially compressed + var joinRequest: Data = Data() + + var unknownFields = SwiftProtobuf.UnknownStorage() + + enum Compression: SwiftProtobuf.Enum, Swift.CaseIterable { + typealias RawValue = Int + case none // = 0 + case gzip // = 1 + case UNRECOGNIZED(Int) + + init() { + self = .none + } + + init?(rawValue: Int) { + switch rawValue { + case 0: self = .none + case 1: self = .gzip + default: self = .UNRECOGNIZED(rawValue) + } + } + + var rawValue: Int { + switch self { + case .none: return 0 + case .gzip: return 1 + case .UNRECOGNIZED(let i): return i + } + } + + // The compiler won't synthesize support with the UNRECOGNIZED case. + static let allCases: [Livekit_WrappedJoinRequest.Compression] = [ + .none, + .gzip, + ] + + } + + init() {} +} + +struct Livekit_MediaSectionsRequirement: Sendable { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + var numAudios: UInt32 = 0 + + var numVideos: UInt32 = 0 + + var unknownFields = SwiftProtobuf.UnknownStorage() + + init() {} +} + // MARK: - Code below here is support for the SwiftProtobuf runtime. fileprivate let _protobuf_package = "livekit" extension Livekit_SignalTarget: SwiftProtobuf._ProtoNameProviding { - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "PUBLISHER"), - 1: .same(proto: "SUBSCRIBER"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{2}\0PUBLISHER\0\u{1}SUBSCRIBER\0") } extension Livekit_StreamState: SwiftProtobuf._ProtoNameProviding { - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "ACTIVE"), - 1: .same(proto: "PAUSED"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{2}\0ACTIVE\0\u{1}PAUSED\0") } extension Livekit_CandidateProtocol: SwiftProtobuf._ProtoNameProviding { - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "UDP"), - 1: .same(proto: "TCP"), - 2: .same(proto: "TLS"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{2}\0UDP\0\u{1}TCP\0\u{1}TLS\0") } extension Livekit_SignalRequest: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = _protobuf_package + ".SignalRequest" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "offer"), - 2: .same(proto: "answer"), - 3: .same(proto: "trickle"), - 4: .standard(proto: "add_track"), - 5: .same(proto: "mute"), - 6: .same(proto: "subscription"), - 7: .standard(proto: "track_setting"), - 8: .same(proto: "leave"), - 10: .standard(proto: "update_layers"), - 11: .standard(proto: "subscription_permission"), - 12: .standard(proto: "sync_state"), - 13: .same(proto: "simulate"), - 14: .same(proto: "ping"), - 15: .standard(proto: "update_metadata"), - 16: .standard(proto: "ping_req"), - 17: .standard(proto: "update_audio_track"), - 18: .standard(proto: "update_video_track"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}offer\0\u{1}answer\0\u{1}trickle\0\u{3}add_track\0\u{1}mute\0\u{1}subscription\0\u{3}track_setting\0\u{1}leave\0\u{4}\u{2}update_layers\0\u{3}subscription_permission\0\u{3}sync_state\0\u{1}simulate\0\u{1}ping\0\u{3}update_metadata\0\u{3}ping_req\0\u{3}update_audio_track\0\u{3}update_video_track\0") mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -2116,31 +2278,7 @@ extension Livekit_SignalRequest: SwiftProtobuf.Message, SwiftProtobuf._MessageIm extension Livekit_SignalResponse: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = _protobuf_package + ".SignalResponse" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "join"), - 2: .same(proto: "answer"), - 3: .same(proto: "offer"), - 4: .same(proto: "trickle"), - 5: .same(proto: "update"), - 6: .standard(proto: "track_published"), - 8: .same(proto: "leave"), - 9: .same(proto: "mute"), - 10: .standard(proto: "speakers_changed"), - 11: .standard(proto: "room_update"), - 12: .standard(proto: "connection_quality"), - 13: .standard(proto: "stream_state_update"), - 14: .standard(proto: "subscribed_quality_update"), - 15: .standard(proto: "subscription_permission_update"), - 16: .standard(proto: "refresh_token"), - 17: .standard(proto: "track_unpublished"), - 18: .same(proto: "pong"), - 19: .same(proto: "reconnect"), - 20: .standard(proto: "pong_resp"), - 21: .standard(proto: "subscription_response"), - 22: .standard(proto: "request_response"), - 23: .standard(proto: "track_subscribed"), - 24: .standard(proto: "room_moved"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}join\0\u{1}answer\0\u{1}offer\0\u{1}trickle\0\u{1}update\0\u{3}track_published\0\u{2}\u{2}leave\0\u{1}mute\0\u{3}speakers_changed\0\u{3}room_update\0\u{3}connection_quality\0\u{3}stream_state_update\0\u{3}subscribed_quality_update\0\u{3}subscription_permission_update\0\u{3}refresh_token\0\u{3}track_unpublished\0\u{1}pong\0\u{1}reconnect\0\u{3}pong_resp\0\u{3}subscription_response\0\u{3}request_response\0\u{3}track_subscribed\0\u{3}room_moved\0\u{3}media_sections_requirement\0") mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -2437,6 +2575,19 @@ extension Livekit_SignalResponse: SwiftProtobuf.Message, SwiftProtobuf._MessageI self.message = .roomMoved(v) } }() + case 25: try { + var v: Livekit_MediaSectionsRequirement? + var hadOneofValue = false + if let current = self.message { + hadOneofValue = true + if case .mediaSectionsRequirement(let m) = current {v = m} + } + try decoder.decodeSingularMessageField(value: &v) + if let v = v { + if hadOneofValue {try decoder.handleConflictingOneOf()} + self.message = .mediaSectionsRequirement(v) + } + }() default: break } } @@ -2540,6 +2691,10 @@ extension Livekit_SignalResponse: SwiftProtobuf.Message, SwiftProtobuf._MessageI guard case .roomMoved(let v)? = self.message else { preconditionFailure() } try visitor.visitSingularMessageField(value: v, fieldNumber: 24) }() + case .mediaSectionsRequirement?: try { + guard case .mediaSectionsRequirement(let v)? = self.message else { preconditionFailure() } + try visitor.visitSingularMessageField(value: v, fieldNumber: 25) + }() case nil: break } try unknownFields.traverse(visitor: &visitor) @@ -2554,10 +2709,7 @@ extension Livekit_SignalResponse: SwiftProtobuf.Message, SwiftProtobuf._MessageI extension Livekit_SimulcastCodec: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = _protobuf_package + ".SimulcastCodec" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "codec"), - 2: .same(proto: "cid"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}codec\0\u{1}cid\0\u{2}\u{2}layers\0\u{3}video_layer_mode\0") mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -2567,6 +2719,8 @@ extension Livekit_SimulcastCodec: SwiftProtobuf.Message, SwiftProtobuf._MessageI switch fieldNumber { case 1: try { try decoder.decodeSingularStringField(value: &self.codec) }() case 2: try { try decoder.decodeSingularStringField(value: &self.cid) }() + case 4: try { try decoder.decodeRepeatedMessageField(value: &self.layers) }() + case 5: try { try decoder.decodeSingularEnumField(value: &self.videoLayerMode) }() default: break } } @@ -2579,12 +2733,20 @@ extension Livekit_SimulcastCodec: SwiftProtobuf.Message, SwiftProtobuf._MessageI if !self.cid.isEmpty { try visitor.visitSingularStringField(value: self.cid, fieldNumber: 2) } + if !self.layers.isEmpty { + try visitor.visitRepeatedMessageField(value: self.layers, fieldNumber: 4) + } + if self.videoLayerMode != .unused { + try visitor.visitSingularEnumField(value: self.videoLayerMode, fieldNumber: 5) + } try unknownFields.traverse(visitor: &visitor) } static func ==(lhs: Livekit_SimulcastCodec, rhs: Livekit_SimulcastCodec) -> Bool { if lhs.codec != rhs.codec {return false} if lhs.cid != rhs.cid {return false} + if lhs.layers != rhs.layers {return false} + if lhs.videoLayerMode != rhs.videoLayerMode {return false} if lhs.unknownFields != rhs.unknownFields {return false} return true } @@ -2592,25 +2754,7 @@ extension Livekit_SimulcastCodec: SwiftProtobuf.Message, SwiftProtobuf._MessageI extension Livekit_AddTrackRequest: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = _protobuf_package + ".AddTrackRequest" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "cid"), - 2: .same(proto: "name"), - 3: .same(proto: "type"), - 4: .same(proto: "width"), - 5: .same(proto: "height"), - 6: .same(proto: "muted"), - 7: .standard(proto: "disable_dtx"), - 8: .same(proto: "source"), - 9: .same(proto: "layers"), - 10: .standard(proto: "simulcast_codecs"), - 11: .same(proto: "sid"), - 12: .same(proto: "stereo"), - 13: .standard(proto: "disable_red"), - 14: .same(proto: "encryption"), - 15: .same(proto: "stream"), - 16: .standard(proto: "backup_codec_policy"), - 17: .standard(proto: "audio_features"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}cid\0\u{1}name\0\u{1}type\0\u{1}width\0\u{1}height\0\u{1}muted\0\u{3}disable_dtx\0\u{1}source\0\u{1}layers\0\u{3}simulcast_codecs\0\u{1}sid\0\u{1}stereo\0\u{3}disable_red\0\u{1}encryption\0\u{1}stream\0\u{3}backup_codec_policy\0\u{3}audio_features\0") fileprivate class _StorageClass { var _cid: String = String() @@ -2788,11 +2932,7 @@ extension Livekit_AddTrackRequest: SwiftProtobuf.Message, SwiftProtobuf._Message extension Livekit_TrickleRequest: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = _protobuf_package + ".TrickleRequest" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "candidateInit"), - 2: .same(proto: "target"), - 3: .same(proto: "final"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}candidateInit\0\u{1}target\0\u{1}final\0") mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -2832,10 +2972,7 @@ extension Livekit_TrickleRequest: SwiftProtobuf.Message, SwiftProtobuf._MessageI extension Livekit_MuteTrackRequest: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = _protobuf_package + ".MuteTrackRequest" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "sid"), - 2: .same(proto: "muted"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}sid\0\u{1}muted\0") mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -2870,23 +3007,7 @@ extension Livekit_MuteTrackRequest: SwiftProtobuf.Message, SwiftProtobuf._Messag extension Livekit_JoinResponse: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = _protobuf_package + ".JoinResponse" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "room"), - 2: .same(proto: "participant"), - 3: .standard(proto: "other_participants"), - 4: .standard(proto: "server_version"), - 5: .standard(proto: "ice_servers"), - 6: .standard(proto: "subscriber_primary"), - 7: .standard(proto: "alternative_url"), - 8: .standard(proto: "client_configuration"), - 9: .standard(proto: "server_region"), - 10: .standard(proto: "ping_timeout"), - 11: .standard(proto: "ping_interval"), - 12: .standard(proto: "server_info"), - 13: .standard(proto: "sif_trailer"), - 14: .standard(proto: "enabled_publish_codecs"), - 15: .standard(proto: "fast_publish"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}room\0\u{1}participant\0\u{3}other_participants\0\u{3}server_version\0\u{3}ice_servers\0\u{3}subscriber_primary\0\u{3}alternative_url\0\u{3}client_configuration\0\u{3}server_region\0\u{3}ping_timeout\0\u{3}ping_interval\0\u{3}server_info\0\u{3}sif_trailer\0\u{3}enabled_publish_codecs\0\u{3}fast_publish\0") fileprivate class _StorageClass { var _room: Livekit_Room? = nil @@ -3054,12 +3175,7 @@ extension Livekit_JoinResponse: SwiftProtobuf.Message, SwiftProtobuf._MessageImp extension Livekit_ReconnectResponse: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = _protobuf_package + ".ReconnectResponse" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "ice_servers"), - 2: .standard(proto: "client_configuration"), - 3: .standard(proto: "server_info"), - 4: .standard(proto: "last_message_seq"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{3}ice_servers\0\u{3}client_configuration\0\u{3}server_info\0\u{3}last_message_seq\0") mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -3108,10 +3224,7 @@ extension Livekit_ReconnectResponse: SwiftProtobuf.Message, SwiftProtobuf._Messa extension Livekit_TrackPublishedResponse: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = _protobuf_package + ".TrackPublishedResponse" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "cid"), - 2: .same(proto: "track"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}cid\0\u{1}track\0") mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -3150,9 +3263,7 @@ extension Livekit_TrackPublishedResponse: SwiftProtobuf.Message, SwiftProtobuf._ extension Livekit_TrackUnpublishedResponse: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = _protobuf_package + ".TrackUnpublishedResponse" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "track_sid"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{3}track_sid\0") mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -3182,11 +3293,7 @@ extension Livekit_TrackUnpublishedResponse: SwiftProtobuf.Message, SwiftProtobuf extension Livekit_SessionDescription: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = _protobuf_package + ".SessionDescription" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "type"), - 2: .same(proto: "sdp"), - 3: .same(proto: "id"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}type\0\u{1}sdp\0\u{1}id\0") mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -3226,9 +3333,7 @@ extension Livekit_SessionDescription: SwiftProtobuf.Message, SwiftProtobuf._Mess extension Livekit_ParticipantUpdate: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = _protobuf_package + ".ParticipantUpdate" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "participants"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}participants\0") mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -3258,11 +3363,7 @@ extension Livekit_ParticipantUpdate: SwiftProtobuf.Message, SwiftProtobuf._Messa extension Livekit_UpdateSubscription: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = _protobuf_package + ".UpdateSubscription" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "track_sids"), - 2: .same(proto: "subscribe"), - 3: .standard(proto: "participant_tracks"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{3}track_sids\0\u{1}subscribe\0\u{3}participant_tracks\0") mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -3302,15 +3403,7 @@ extension Livekit_UpdateSubscription: SwiftProtobuf.Message, SwiftProtobuf._Mess extension Livekit_UpdateTrackSettings: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = _protobuf_package + ".UpdateTrackSettings" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "track_sids"), - 3: .same(proto: "disabled"), - 4: .same(proto: "quality"), - 5: .same(proto: "width"), - 6: .same(proto: "height"), - 7: .same(proto: "fps"), - 8: .same(proto: "priority"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{3}track_sids\0\u{2}\u{2}disabled\0\u{1}quality\0\u{1}width\0\u{1}height\0\u{1}fps\0\u{1}priority\0") mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -3370,10 +3463,7 @@ extension Livekit_UpdateTrackSettings: SwiftProtobuf.Message, SwiftProtobuf._Mes extension Livekit_UpdateLocalAudioTrack: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = _protobuf_package + ".UpdateLocalAudioTrack" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "track_sid"), - 2: .same(proto: "features"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{3}track_sid\0\u{1}features\0") mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -3408,11 +3498,7 @@ extension Livekit_UpdateLocalAudioTrack: SwiftProtobuf.Message, SwiftProtobuf._M extension Livekit_UpdateLocalVideoTrack: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = _protobuf_package + ".UpdateLocalVideoTrack" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "track_sid"), - 2: .same(proto: "width"), - 3: .same(proto: "height"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{3}track_sid\0\u{1}width\0\u{1}height\0") mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -3452,12 +3538,7 @@ extension Livekit_UpdateLocalVideoTrack: SwiftProtobuf.Message, SwiftProtobuf._M extension Livekit_LeaveRequest: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = _protobuf_package + ".LeaveRequest" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "can_reconnect"), - 2: .same(proto: "reason"), - 3: .same(proto: "action"), - 4: .same(proto: "regions"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{3}can_reconnect\0\u{1}reason\0\u{1}action\0\u{1}regions\0") mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -3505,19 +3586,12 @@ extension Livekit_LeaveRequest: SwiftProtobuf.Message, SwiftProtobuf._MessageImp } extension Livekit_LeaveRequest.Action: SwiftProtobuf._ProtoNameProviding { - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "DISCONNECT"), - 1: .same(proto: "RESUME"), - 2: .same(proto: "RECONNECT"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{2}\0DISCONNECT\0\u{1}RESUME\0\u{1}RECONNECT\0") } extension Livekit_UpdateVideoLayers: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = _protobuf_package + ".UpdateVideoLayers" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "track_sid"), - 2: .same(proto: "layers"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{3}track_sid\0\u{1}layers\0") mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -3552,12 +3626,7 @@ extension Livekit_UpdateVideoLayers: SwiftProtobuf.Message, SwiftProtobuf._Messa extension Livekit_UpdateParticipantMetadata: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = _protobuf_package + ".UpdateParticipantMetadata" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "metadata"), - 2: .same(proto: "name"), - 3: .same(proto: "attributes"), - 4: .standard(proto: "request_id"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}metadata\0\u{1}name\0\u{1}attributes\0\u{3}request_id\0") mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -3602,11 +3671,7 @@ extension Livekit_UpdateParticipantMetadata: SwiftProtobuf.Message, SwiftProtobu extension Livekit_ICEServer: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = _protobuf_package + ".ICEServer" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "urls"), - 2: .same(proto: "username"), - 3: .same(proto: "credential"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}urls\0\u{1}username\0\u{1}credential\0") mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -3646,9 +3711,7 @@ extension Livekit_ICEServer: SwiftProtobuf.Message, SwiftProtobuf._MessageImplem extension Livekit_SpeakersChanged: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = _protobuf_package + ".SpeakersChanged" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "speakers"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}speakers\0") mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -3678,9 +3741,7 @@ extension Livekit_SpeakersChanged: SwiftProtobuf.Message, SwiftProtobuf._Message extension Livekit_RoomUpdate: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = _protobuf_package + ".RoomUpdate" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "room"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}room\0") mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -3714,11 +3775,7 @@ extension Livekit_RoomUpdate: SwiftProtobuf.Message, SwiftProtobuf._MessageImple extension Livekit_ConnectionQualityInfo: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = _protobuf_package + ".ConnectionQualityInfo" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "participant_sid"), - 2: .same(proto: "quality"), - 3: .same(proto: "score"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{3}participant_sid\0\u{1}quality\0\u{1}score\0") mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -3758,9 +3815,7 @@ extension Livekit_ConnectionQualityInfo: SwiftProtobuf.Message, SwiftProtobuf._M extension Livekit_ConnectionQualityUpdate: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = _protobuf_package + ".ConnectionQualityUpdate" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "updates"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}updates\0") mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -3790,11 +3845,7 @@ extension Livekit_ConnectionQualityUpdate: SwiftProtobuf.Message, SwiftProtobuf. extension Livekit_StreamStateInfo: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = _protobuf_package + ".StreamStateInfo" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "participant_sid"), - 2: .standard(proto: "track_sid"), - 3: .same(proto: "state"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{3}participant_sid\0\u{3}track_sid\0\u{1}state\0") mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -3834,9 +3885,7 @@ extension Livekit_StreamStateInfo: SwiftProtobuf.Message, SwiftProtobuf._Message extension Livekit_StreamStateUpdate: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = _protobuf_package + ".StreamStateUpdate" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "stream_states"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{3}stream_states\0") mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -3866,10 +3915,7 @@ extension Livekit_StreamStateUpdate: SwiftProtobuf.Message, SwiftProtobuf._Messa extension Livekit_SubscribedQuality: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = _protobuf_package + ".SubscribedQuality" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "quality"), - 2: .same(proto: "enabled"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}quality\0\u{1}enabled\0") mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -3904,10 +3950,7 @@ extension Livekit_SubscribedQuality: SwiftProtobuf.Message, SwiftProtobuf._Messa extension Livekit_SubscribedCodec: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = _protobuf_package + ".SubscribedCodec" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "codec"), - 2: .same(proto: "qualities"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}codec\0\u{1}qualities\0") mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -3942,11 +3985,7 @@ extension Livekit_SubscribedCodec: SwiftProtobuf.Message, SwiftProtobuf._Message extension Livekit_SubscribedQualityUpdate: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = _protobuf_package + ".SubscribedQualityUpdate" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "track_sid"), - 2: .standard(proto: "subscribed_qualities"), - 3: .standard(proto: "subscribed_codecs"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{3}track_sid\0\u{3}subscribed_qualities\0\u{3}subscribed_codecs\0") mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -3986,12 +4025,7 @@ extension Livekit_SubscribedQualityUpdate: SwiftProtobuf.Message, SwiftProtobuf. extension Livekit_TrackPermission: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = _protobuf_package + ".TrackPermission" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "participant_sid"), - 2: .standard(proto: "all_tracks"), - 3: .standard(proto: "track_sids"), - 4: .standard(proto: "participant_identity"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{3}participant_sid\0\u{3}all_tracks\0\u{3}track_sids\0\u{3}participant_identity\0") mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -4036,10 +4070,7 @@ extension Livekit_TrackPermission: SwiftProtobuf.Message, SwiftProtobuf._Message extension Livekit_SubscriptionPermission: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = _protobuf_package + ".SubscriptionPermission" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "all_participants"), - 2: .standard(proto: "track_permissions"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{3}all_participants\0\u{3}track_permissions\0") mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -4074,11 +4105,7 @@ extension Livekit_SubscriptionPermission: SwiftProtobuf.Message, SwiftProtobuf._ extension Livekit_SubscriptionPermissionUpdate: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = _protobuf_package + ".SubscriptionPermissionUpdate" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "participant_sid"), - 2: .standard(proto: "track_sid"), - 3: .same(proto: "allowed"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{3}participant_sid\0\u{3}track_sid\0\u{1}allowed\0") mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -4118,12 +4145,7 @@ extension Livekit_SubscriptionPermissionUpdate: SwiftProtobuf.Message, SwiftProt extension Livekit_RoomMovedResponse: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = _protobuf_package + ".RoomMovedResponse" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "room"), - 2: .same(proto: "token"), - 3: .same(proto: "participant"), - 4: .standard(proto: "other_participants"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}room\0\u{1}token\0\u{1}participant\0\u{3}other_participants\0") fileprivate class _StorageClass { var _room: Livekit_Room? = nil @@ -4214,15 +4236,7 @@ extension Livekit_RoomMovedResponse: SwiftProtobuf.Message, SwiftProtobuf._Messa extension Livekit_SyncState: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = _protobuf_package + ".SyncState" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "answer"), - 2: .same(proto: "subscription"), - 3: .standard(proto: "publish_tracks"), - 4: .standard(proto: "data_channels"), - 5: .same(proto: "offer"), - 6: .standard(proto: "track_sids_disabled"), - 7: .standard(proto: "datachannel_receive_states"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}answer\0\u{1}subscription\0\u{3}publish_tracks\0\u{3}data_channels\0\u{1}offer\0\u{3}track_sids_disabled\0\u{3}datachannel_receive_states\0") mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -4286,10 +4300,7 @@ extension Livekit_SyncState: SwiftProtobuf.Message, SwiftProtobuf._MessageImplem extension Livekit_DataChannelReceiveState: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = _protobuf_package + ".DataChannelReceiveState" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "publisher_sid"), - 2: .standard(proto: "last_seq"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{3}publisher_sid\0\u{3}last_seq\0") mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -4324,11 +4335,7 @@ extension Livekit_DataChannelReceiveState: SwiftProtobuf.Message, SwiftProtobuf. extension Livekit_DataChannelInfo: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = _protobuf_package + ".DataChannelInfo" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "label"), - 2: .same(proto: "id"), - 3: .same(proto: "target"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}label\0\u{1}id\0\u{1}target\0") mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -4368,17 +4375,7 @@ extension Livekit_DataChannelInfo: SwiftProtobuf.Message, SwiftProtobuf._Message extension Livekit_SimulateScenario: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = _protobuf_package + ".SimulateScenario" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "speaker_update"), - 2: .standard(proto: "node_failure"), - 3: .same(proto: "migration"), - 4: .standard(proto: "server_leave"), - 5: .standard(proto: "switch_candidate_protocol"), - 6: .standard(proto: "subscriber_bandwidth"), - 7: .standard(proto: "disconnect_signal_on_resume"), - 8: .standard(proto: "disconnect_signal_on_resume_no_messages"), - 9: .standard(proto: "leave_request_full_reconnect"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{3}speaker_update\0\u{3}node_failure\0\u{1}migration\0\u{3}server_leave\0\u{3}switch_candidate_protocol\0\u{3}subscriber_bandwidth\0\u{3}disconnect_signal_on_resume\0\u{3}disconnect_signal_on_resume_no_messages\0\u{3}leave_request_full_reconnect\0") mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -4519,10 +4516,7 @@ extension Livekit_SimulateScenario: SwiftProtobuf.Message, SwiftProtobuf._Messag extension Livekit_Ping: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = _protobuf_package + ".Ping" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "timestamp"), - 2: .same(proto: "rtt"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}timestamp\0\u{1}rtt\0") mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -4557,10 +4551,7 @@ extension Livekit_Ping: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementat extension Livekit_Pong: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = _protobuf_package + ".Pong" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "last_ping_timestamp"), - 2: .same(proto: "timestamp"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{3}last_ping_timestamp\0\u{1}timestamp\0") mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -4595,9 +4586,7 @@ extension Livekit_Pong: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementat extension Livekit_RegionSettings: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = _protobuf_package + ".RegionSettings" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "regions"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}regions\0") mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -4627,11 +4616,7 @@ extension Livekit_RegionSettings: SwiftProtobuf.Message, SwiftProtobuf._MessageI extension Livekit_RegionInfo: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = _protobuf_package + ".RegionInfo" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "region"), - 2: .same(proto: "url"), - 3: .same(proto: "distance"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}region\0\u{1}url\0\u{1}distance\0") mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -4671,10 +4656,7 @@ extension Livekit_RegionInfo: SwiftProtobuf.Message, SwiftProtobuf._MessageImple extension Livekit_SubscriptionResponse: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = _protobuf_package + ".SubscriptionResponse" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "track_sid"), - 2: .same(proto: "err"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{3}track_sid\0\u{1}err\0") mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -4709,11 +4691,7 @@ extension Livekit_SubscriptionResponse: SwiftProtobuf.Message, SwiftProtobuf._Me extension Livekit_RequestResponse: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = _protobuf_package + ".RequestResponse" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "request_id"), - 2: .same(proto: "reason"), - 3: .same(proto: "message"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{3}request_id\0\u{1}reason\0\u{1}message\0") mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -4752,19 +4730,12 @@ extension Livekit_RequestResponse: SwiftProtobuf.Message, SwiftProtobuf._Message } extension Livekit_RequestResponse.Reason: SwiftProtobuf._ProtoNameProviding { - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "OK"), - 1: .same(proto: "NOT_FOUND"), - 2: .same(proto: "NOT_ALLOWED"), - 3: .same(proto: "LIMIT_EXCEEDED"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{2}\0OK\0\u{1}NOT_FOUND\0\u{1}NOT_ALLOWED\0\u{1}LIMIT_EXCEEDED\0") } extension Livekit_TrackSubscribed: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = _protobuf_package + ".TrackSubscribed" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "track_sid"), - ] + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{3}track_sid\0") mutating func decodeMessage(decoder: inout D) throws { while let fieldNumber = try decoder.nextFieldNumber() { @@ -4791,3 +4762,259 @@ extension Livekit_TrackSubscribed: SwiftProtobuf.Message, SwiftProtobuf._Message return true } } + +extension Livekit_ConnectionSettings: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = _protobuf_package + ".ConnectionSettings" + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{3}auto_subscribe\0\u{3}adaptive_stream\0\u{3}subscriber_allow_pause\0\u{3}disable_ice_lite\0") + + mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularBoolField(value: &self.autoSubscribe) }() + case 2: try { try decoder.decodeSingularBoolField(value: &self.adaptiveStream) }() + case 3: try { try decoder.decodeSingularBoolField(value: &self._subscriberAllowPause) }() + case 4: try { try decoder.decodeSingularBoolField(value: &self.disableIceLite) }() + default: break + } + } + } + + func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + if self.autoSubscribe != false { + try visitor.visitSingularBoolField(value: self.autoSubscribe, fieldNumber: 1) + } + if self.adaptiveStream != false { + try visitor.visitSingularBoolField(value: self.adaptiveStream, fieldNumber: 2) + } + try { if let v = self._subscriberAllowPause { + try visitor.visitSingularBoolField(value: v, fieldNumber: 3) + } }() + if self.disableIceLite != false { + try visitor.visitSingularBoolField(value: self.disableIceLite, fieldNumber: 4) + } + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: Livekit_ConnectionSettings, rhs: Livekit_ConnectionSettings) -> Bool { + if lhs.autoSubscribe != rhs.autoSubscribe {return false} + if lhs.adaptiveStream != rhs.adaptiveStream {return false} + if lhs._subscriberAllowPause != rhs._subscriberAllowPause {return false} + if lhs.disableIceLite != rhs.disableIceLite {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Livekit_JoinRequest: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = _protobuf_package + ".JoinRequest" + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{3}client_info\0\u{3}connection_settings\0\u{1}metadata\0\u{3}participant_attributes\0\u{3}add_track_requests\0\u{3}publisher_offer\0\u{1}reconnect\0\u{3}reconnect_reason\0\u{3}participant_sid\0\u{3}sync_state\0") + + fileprivate class _StorageClass { + var _clientInfo: Livekit_ClientInfo? = nil + var _connectionSettings: Livekit_ConnectionSettings? = nil + var _metadata: String = String() + var _participantAttributes: Dictionary = [:] + var _addTrackRequests: [Livekit_AddTrackRequest] = [] + var _publisherOffer: Livekit_SessionDescription? = nil + var _reconnect: Bool = false + var _reconnectReason: Livekit_ReconnectReason = .rrUnknown + var _participantSid: String = String() + var _syncState: Livekit_SyncState? = nil + + // This property is used as the initial default value for new instances of the type. + // The type itself is protecting the reference to its storage via CoW semantics. + // This will force a copy to be made of this reference when the first mutation occurs; + // hence, it is safe to mark this as `nonisolated(unsafe)`. + static nonisolated(unsafe) let defaultInstance = _StorageClass() + + private init() {} + + init(copying source: _StorageClass) { + _clientInfo = source._clientInfo + _connectionSettings = source._connectionSettings + _metadata = source._metadata + _participantAttributes = source._participantAttributes + _addTrackRequests = source._addTrackRequests + _publisherOffer = source._publisherOffer + _reconnect = source._reconnect + _reconnectReason = source._reconnectReason + _participantSid = source._participantSid + _syncState = source._syncState + } + } + + fileprivate mutating func _uniqueStorage() -> _StorageClass { + if !isKnownUniquelyReferenced(&_storage) { + _storage = _StorageClass(copying: _storage) + } + return _storage + } + + mutating func decodeMessage(decoder: inout D) throws { + _ = _uniqueStorage() + try withExtendedLifetime(_storage) { (_storage: _StorageClass) in + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularMessageField(value: &_storage._clientInfo) }() + case 2: try { try decoder.decodeSingularMessageField(value: &_storage._connectionSettings) }() + case 3: try { try decoder.decodeSingularStringField(value: &_storage._metadata) }() + case 4: try { try decoder.decodeMapField(fieldType: SwiftProtobuf._ProtobufMap.self, value: &_storage._participantAttributes) }() + case 5: try { try decoder.decodeRepeatedMessageField(value: &_storage._addTrackRequests) }() + case 6: try { try decoder.decodeSingularMessageField(value: &_storage._publisherOffer) }() + case 7: try { try decoder.decodeSingularBoolField(value: &_storage._reconnect) }() + case 8: try { try decoder.decodeSingularEnumField(value: &_storage._reconnectReason) }() + case 9: try { try decoder.decodeSingularStringField(value: &_storage._participantSid) }() + case 10: try { try decoder.decodeSingularMessageField(value: &_storage._syncState) }() + default: break + } + } + } + } + + func traverse(visitor: inout V) throws { + try withExtendedLifetime(_storage) { (_storage: _StorageClass) in + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + try { if let v = _storage._clientInfo { + try visitor.visitSingularMessageField(value: v, fieldNumber: 1) + } }() + try { if let v = _storage._connectionSettings { + try visitor.visitSingularMessageField(value: v, fieldNumber: 2) + } }() + if !_storage._metadata.isEmpty { + try visitor.visitSingularStringField(value: _storage._metadata, fieldNumber: 3) + } + if !_storage._participantAttributes.isEmpty { + try visitor.visitMapField(fieldType: SwiftProtobuf._ProtobufMap.self, value: _storage._participantAttributes, fieldNumber: 4) + } + if !_storage._addTrackRequests.isEmpty { + try visitor.visitRepeatedMessageField(value: _storage._addTrackRequests, fieldNumber: 5) + } + try { if let v = _storage._publisherOffer { + try visitor.visitSingularMessageField(value: v, fieldNumber: 6) + } }() + if _storage._reconnect != false { + try visitor.visitSingularBoolField(value: _storage._reconnect, fieldNumber: 7) + } + if _storage._reconnectReason != .rrUnknown { + try visitor.visitSingularEnumField(value: _storage._reconnectReason, fieldNumber: 8) + } + if !_storage._participantSid.isEmpty { + try visitor.visitSingularStringField(value: _storage._participantSid, fieldNumber: 9) + } + try { if let v = _storage._syncState { + try visitor.visitSingularMessageField(value: v, fieldNumber: 10) + } }() + } + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: Livekit_JoinRequest, rhs: Livekit_JoinRequest) -> Bool { + if lhs._storage !== rhs._storage { + let storagesAreEqual: Bool = withExtendedLifetime((lhs._storage, rhs._storage)) { (_args: (_StorageClass, _StorageClass)) in + let _storage = _args.0 + let rhs_storage = _args.1 + if _storage._clientInfo != rhs_storage._clientInfo {return false} + if _storage._connectionSettings != rhs_storage._connectionSettings {return false} + if _storage._metadata != rhs_storage._metadata {return false} + if _storage._participantAttributes != rhs_storage._participantAttributes {return false} + if _storage._addTrackRequests != rhs_storage._addTrackRequests {return false} + if _storage._publisherOffer != rhs_storage._publisherOffer {return false} + if _storage._reconnect != rhs_storage._reconnect {return false} + if _storage._reconnectReason != rhs_storage._reconnectReason {return false} + if _storage._participantSid != rhs_storage._participantSid {return false} + if _storage._syncState != rhs_storage._syncState {return false} + return true + } + if !storagesAreEqual {return false} + } + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Livekit_WrappedJoinRequest: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = _protobuf_package + ".WrappedJoinRequest" + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{1}compression\0\u{3}join_request\0") + + mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularEnumField(value: &self.compression) }() + case 2: try { try decoder.decodeSingularBytesField(value: &self.joinRequest) }() + default: break + } + } + } + + func traverse(visitor: inout V) throws { + if self.compression != .none { + try visitor.visitSingularEnumField(value: self.compression, fieldNumber: 1) + } + if !self.joinRequest.isEmpty { + try visitor.visitSingularBytesField(value: self.joinRequest, fieldNumber: 2) + } + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: Livekit_WrappedJoinRequest, rhs: Livekit_WrappedJoinRequest) -> Bool { + if lhs.compression != rhs.compression {return false} + if lhs.joinRequest != rhs.joinRequest {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Livekit_WrappedJoinRequest.Compression: SwiftProtobuf._ProtoNameProviding { + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{2}\0NONE\0\u{1}GZIP\0") +} + +extension Livekit_MediaSectionsRequirement: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = _protobuf_package + ".MediaSectionsRequirement" + static let _protobuf_nameMap = SwiftProtobuf._NameMap(bytecode: "\0\u{3}num_audios\0\u{3}num_videos\0") + + mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularUInt32Field(value: &self.numAudios) }() + case 2: try { try decoder.decodeSingularUInt32Field(value: &self.numVideos) }() + default: break + } + } + } + + func traverse(visitor: inout V) throws { + if self.numAudios != 0 { + try visitor.visitSingularUInt32Field(value: self.numAudios, fieldNumber: 1) + } + if self.numVideos != 0 { + try visitor.visitSingularUInt32Field(value: self.numVideos, fieldNumber: 2) + } + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: Livekit_MediaSectionsRequirement, rhs: Livekit_MediaSectionsRequirement) -> Bool { + if lhs.numAudios != rhs.numAudios {return false} + if lhs.numVideos != rhs.numVideos {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} diff --git a/Sources/LiveKit/Types/Options/RoomOptions.swift b/Sources/LiveKit/Types/Options/RoomOptions.swift index d56e2bc7d..f94b782a2 100644 --- a/Sources/LiveKit/Types/Options/RoomOptions.swift +++ b/Sources/LiveKit/Types/Options/RoomOptions.swift @@ -64,7 +64,11 @@ public final class RoomOptions: NSObject, Sendable { public let suspendLocalVideoTracksInBackground: Bool /// E2EE Options + @objc public let e2eeOptions: E2EEOptions? + /// Encryption + @objc + public let encryptionOptions: EncryptionOptions? @objc public let reportRemoteTrackStatistics: Bool @@ -81,6 +85,7 @@ public final class RoomOptions: NSObject, Sendable { stopLocalTrackOnUnpublish = true suspendLocalVideoTracksInBackground = true e2eeOptions = nil + encryptionOptions = nil reportRemoteTrackStatistics = false } @@ -109,6 +114,36 @@ public final class RoomOptions: NSObject, Sendable { self.stopLocalTrackOnUnpublish = stopLocalTrackOnUnpublish self.suspendLocalVideoTracksInBackground = suspendLocalVideoTracksInBackground self.e2eeOptions = e2eeOptions + encryptionOptions = nil // don't pass both + self.reportRemoteTrackStatistics = reportRemoteTrackStatistics + } + + @objc + public init(defaultCameraCaptureOptions: CameraCaptureOptions = CameraCaptureOptions(), + defaultScreenShareCaptureOptions: ScreenShareCaptureOptions = ScreenShareCaptureOptions(), + defaultAudioCaptureOptions: AudioCaptureOptions = AudioCaptureOptions(), + defaultVideoPublishOptions: VideoPublishOptions = VideoPublishOptions(), + defaultAudioPublishOptions: AudioPublishOptions = AudioPublishOptions(), + defaultDataPublishOptions: DataPublishOptions = DataPublishOptions(), + adaptiveStream: Bool = false, + dynacast: Bool = false, + stopLocalTrackOnUnpublish: Bool = true, + suspendLocalVideoTracksInBackground: Bool = true, + encryptionOptions: EncryptionOptions? = nil, + reportRemoteTrackStatistics: Bool = false) + { + self.defaultCameraCaptureOptions = defaultCameraCaptureOptions + self.defaultScreenShareCaptureOptions = defaultScreenShareCaptureOptions + self.defaultAudioCaptureOptions = defaultAudioCaptureOptions + self.defaultVideoPublishOptions = defaultVideoPublishOptions + self.defaultAudioPublishOptions = defaultAudioPublishOptions + self.defaultDataPublishOptions = defaultDataPublishOptions + self.adaptiveStream = adaptiveStream + self.dynacast = dynacast + self.stopLocalTrackOnUnpublish = stopLocalTrackOnUnpublish + self.suspendLocalVideoTracksInBackground = suspendLocalVideoTracksInBackground + e2eeOptions = nil // don't pass both + self.encryptionOptions = encryptionOptions self.reportRemoteTrackStatistics = reportRemoteTrackStatistics } @@ -127,6 +162,7 @@ public final class RoomOptions: NSObject, Sendable { stopLocalTrackOnUnpublish == other.stopLocalTrackOnUnpublish && suspendLocalVideoTracksInBackground == other.suspendLocalVideoTracksInBackground && e2eeOptions == other.e2eeOptions && + encryptionOptions == other.encryptionOptions && reportRemoteTrackStatistics == other.reportRemoteTrackStatistics } @@ -143,6 +179,7 @@ public final class RoomOptions: NSObject, Sendable { hasher.combine(stopLocalTrackOnUnpublish) hasher.combine(suspendLocalVideoTracksInBackground) hasher.combine(e2eeOptions) + hasher.combine(encryptionOptions) hasher.combine(reportRemoteTrackStatistics) return hasher.finalize() } diff --git a/Tests/LiveKitTests/DataChannel/EncryptedDataChannelTests.swift b/Tests/LiveKitTests/DataChannel/EncryptedDataChannelTests.swift new file mode 100644 index 000000000..5a7dafb72 --- /dev/null +++ b/Tests/LiveKitTests/DataChannel/EncryptedDataChannelTests.swift @@ -0,0 +1,316 @@ +/* + * Copyright 2025 LiveKit + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +@testable import LiveKit +import LiveKitWebRTC +import XCTest + +class EncryptedDataChannelTests: LKTestCase, @unchecked Sendable { + var receivedDataExpectation: XCTestExpectation! + var receivedData: Data! + var decryptionErrorExpectation: XCTestExpectation! + var lastDecryptionError: Error? + + override func setUp() { + super.setUp() + receivedData = Data() + lastDecryptionError = nil + } + + func testEncryptionWithSharedKey() async throws { + receivedDataExpectation = expectation(description: "Encrypted data received") + let testMessage = "Hello, encrypted world!" + let testData = testMessage.data(using: .utf8)! + + try await withRooms([ + RoomTestingOptions(canPublishData: true), + RoomTestingOptions(delegate: self, canSubscribe: true), + ]) { rooms in + let sender = rooms[0] + let remoteIdentity = try XCTUnwrap(sender.remoteParticipants.keys.first) + + let userPacket = Livekit_UserPacket.with { + $0.payload = testData + $0.destinationIdentities = [remoteIdentity.stringValue] + } + + try await sender.send(userPacket: userPacket, kind: .reliable) + + await self.fulfillment(of: [self.receivedDataExpectation], timeout: 5) + + let receivedMessage = String(data: self.receivedData!, encoding: .utf8) + XCTAssertEqual(receivedMessage, testMessage, "Received message should match sent message") + } + } + + func testEncryptionWithPerParticipantKeys() async throws { + receivedDataExpectation = expectation(description: "Encrypted data with per-participant keys received") + let testMessage = "Hello, per-participant encrypted world!" + let testData = testMessage.data(using: .utf8)! + + let senderKeyProvider = BaseKeyProvider(isSharedKey: false) + let receiverKeyProvider = BaseKeyProvider(isSharedKey: false) + + let senderKey = "sender-secret-key-123" + let receiverKey = "receiver-secret-key-456" + + try await withRooms([ + RoomTestingOptions( + encryptionOptions: EncryptionOptions(keyProvider: senderKeyProvider), canPublishData: true + ), + RoomTestingOptions( + delegate: self, + encryptionOptions: EncryptionOptions(keyProvider: receiverKeyProvider), canSubscribe: true + ), + ]) { rooms in + let sender = rooms[0] + let receiver = rooms[1] + + let senderIdentity = try XCTUnwrap(sender.localParticipant.identity?.stringValue) + let receiverIdentity = try XCTUnwrap(receiver.localParticipant.identity?.stringValue) + + senderKeyProvider.setKey(key: senderKey, participantId: senderIdentity) + senderKeyProvider.setKey(key: receiverKey, participantId: receiverIdentity) + receiverKeyProvider.setKey(key: senderKey, participantId: senderIdentity) + receiverKeyProvider.setKey(key: receiverKey, participantId: receiverIdentity) + + let remoteIdentity = try XCTUnwrap(sender.remoteParticipants.keys.first) + + let userPacket = Livekit_UserPacket.with { + $0.payload = testData + $0.destinationIdentities = [remoteIdentity.stringValue] + } + + try await sender.send(userPacket: userPacket, kind: .reliable) + + await self.fulfillment(of: [self.receivedDataExpectation], timeout: 5) + + let receivedMessage = String(data: self.receivedData!, encoding: .utf8) + XCTAssertEqual(receivedMessage, testMessage, "Received message should match sent message with per-participant keys") + } + } + + func testDecryptionFailureWithSharedKey() async throws { + decryptionErrorExpectation = expectation(description: "Decryption error occurred") + let testMessage = "This should fail to decrypt!" + let testData = testMessage.data(using: .utf8)! + + let senderKey = "sender-shared-key-123" + let receiverKey = "receiver-shared-key-456" + + let senderKeyProvider = BaseKeyProvider(isSharedKey: true, sharedKey: senderKey) + let receiverKeyProvider = BaseKeyProvider(isSharedKey: true, sharedKey: receiverKey) + + try await withRooms([ + RoomTestingOptions( + encryptionOptions: EncryptionOptions(keyProvider: senderKeyProvider), + canPublishData: true + ), + RoomTestingOptions( + delegate: self, + encryptionOptions: EncryptionOptions(keyProvider: receiverKeyProvider), + canSubscribe: true + ), + ]) { rooms in + let sender = rooms[0] + let remoteIdentity = try XCTUnwrap(sender.remoteParticipants.keys.first) + + let userPacket = Livekit_UserPacket.with { + $0.payload = testData + $0.destinationIdentities = [remoteIdentity.stringValue] + } + + try await sender.send(userPacket: userPacket, kind: .reliable) + + await self.fulfillment(of: [self.decryptionErrorExpectation], timeout: 5) + + XCTAssertNotNil(self.lastDecryptionError, "Decryption error should have occurred") + XCTAssertNil(self.receivedData, "No data should be received when decryption fails") + } + } + + func testDecryptionFailureWithPerParticipantKeys() async throws { + decryptionErrorExpectation = expectation(description: "Decryption error occurred with per-participant keys") + let testMessage = "This should fail to decrypt with per-participant keys!" + let testData = testMessage.data(using: .utf8)! + + let senderKeyProvider = BaseKeyProvider(isSharedKey: false) + let receiverKeyProvider = BaseKeyProvider(isSharedKey: false) + + let senderKey = "sender-secret-key-123" + let wrongSenderKey = "wrong-secret-key-999" + let receiverKey = "receiver-secret-key-456" + + try await withRooms([ + RoomTestingOptions( + encryptionOptions: EncryptionOptions(keyProvider: senderKeyProvider), + canPublishData: true + ), + RoomTestingOptions( + delegate: self, + encryptionOptions: EncryptionOptions(keyProvider: receiverKeyProvider), + canSubscribe: true + ), + ]) { rooms in + let sender = rooms[0] + let receiver = rooms[1] + + let senderIdentity = try XCTUnwrap(sender.localParticipant.identity?.stringValue) + let receiverIdentity = try XCTUnwrap(receiver.localParticipant.identity?.stringValue) + + senderKeyProvider.setKey(key: senderKey, participantId: senderIdentity) + senderKeyProvider.setKey(key: receiverKey, participantId: receiverIdentity) + receiverKeyProvider.setKey(key: wrongSenderKey, participantId: senderIdentity) + receiverKeyProvider.setKey(key: receiverKey, participantId: receiverIdentity) + + let remoteIdentity = try XCTUnwrap(sender.remoteParticipants.keys.first) + + let userPacket = Livekit_UserPacket.with { + $0.payload = testData + $0.destinationIdentities = [remoteIdentity.stringValue] + } + + try await sender.send(userPacket: userPacket, kind: .reliable) + + await self.fulfillment(of: [self.decryptionErrorExpectation], timeout: 5) + + XCTAssertNotNil(self.lastDecryptionError, "Decryption error should have occurred with mismatched per-participant keys") + XCTAssertNil(self.receivedData, "No data should be received when per-participant key decryption fails") + } + } + + func testKeyRatcheting() async throws { + receivedDataExpectation = expectation(description: "Data received after automatic key ratcheting") + let testMessage = "Hello with automatic ratcheting!" + let testData = testMessage.data(using: .utf8)! + + let senderKeyProvider = BaseKeyProvider(options: KeyProviderOptions( + sharedKey: true, + ratchetWindowSize: 2 + )) + let receiverKeyProvider = BaseKeyProvider(options: KeyProviderOptions( + sharedKey: true, + ratchetWindowSize: 2 + )) + + let initialKey = "initial-key-\(UUID().uuidString)" + senderKeyProvider.setKey(key: initialKey) + receiverKeyProvider.setKey(key: initialKey) + + try await withRooms([ + RoomTestingOptions( + encryptionOptions: EncryptionOptions(keyProvider: senderKeyProvider), + canPublishData: true + ), + RoomTestingOptions( + delegate: self, + encryptionOptions: EncryptionOptions(keyProvider: receiverKeyProvider), + canSubscribe: true + ), + ]) { rooms in + let sender = rooms[0] + let remoteIdentity = try XCTUnwrap(sender.remoteParticipants.keys.first) + + // Sender ratchets their key forward + let ratchetedKey = senderKeyProvider.ratchetKey() + XCTAssertNotNil(ratchetedKey, "Sender key ratcheting should succeed") + + // Export keys to verify they're different + let senderExportedKey = senderKeyProvider.exportKey() + let receiverExportedKey = receiverKeyProvider.exportKey() + XCTAssertNotEqual(senderExportedKey, receiverExportedKey, "Keys should be different after sender ratchets") + + // Send encrypted data with the ratcheted key + let userPacket = Livekit_UserPacket.with { + $0.payload = testData + $0.destinationIdentities = [remoteIdentity.stringValue] + } + + try await sender.send(userPacket: userPacket, kind: .reliable) + + // Receiver should automatically ratchet and decrypt successfully + await self.fulfillment(of: [self.receivedDataExpectation], timeout: 5) + + let receivedMessage = String(data: self.receivedData!, encoding: .utf8) + XCTAssertEqual(receivedMessage, testMessage, "Message should be received after automatic key ratcheting") + } + } + + func testMultipleKeysInKeyRing() async throws { + receivedDataExpectation = expectation(description: "Data received with multiple keys in key ring") + let testMessage = "Hello with multiple keys in key ring!" + let testData = testMessage.data(using: .utf8)! + + let senderKeyProvider = BaseKeyProvider(options: KeyProviderOptions( + sharedKey: true, + keyRingSize: 2 + )) + let receiverKeyProvider = BaseKeyProvider(options: KeyProviderOptions( + sharedKey: true, + keyRingSize: 2 + )) + + let key1 = "secret-key-1" + let key2 = "secret-key-2" + senderKeyProvider.setKey(key: key1, index: 0) + senderKeyProvider.setKey(key: key2, index: 1) + receiverKeyProvider.setKey(key: key1, index: 0) + receiverKeyProvider.setKey(key: key2, index: 1) + + try await withRooms([ + RoomTestingOptions( + encryptionOptions: EncryptionOptions(keyProvider: senderKeyProvider), + canPublishData: true + ), + RoomTestingOptions( + delegate: self, + encryptionOptions: EncryptionOptions(keyProvider: receiverKeyProvider), + canSubscribe: true + ), + ]) { rooms in + let sender = rooms[0] + let remoteIdentity = try XCTUnwrap(sender.remoteParticipants.keys.first) + + senderKeyProvider.setCurrentKeyIndex(1) + + let userPacket = Livekit_UserPacket.with { + $0.payload = testData + $0.destinationIdentities = [remoteIdentity.stringValue] + } + + try await sender.send(userPacket: userPacket, kind: .reliable) + + await self.fulfillment(of: [self.receivedDataExpectation], timeout: 5) + + let receivedMessage = String(data: self.receivedData!, encoding: .utf8) + XCTAssertEqual(receivedMessage, testMessage, "Message should be received with multiple keys in key ring") + } + } +} + +// MARK: - RoomDelegate + +extension EncryptedDataChannelTests: RoomDelegate { + func room(_: Room, participant _: RemoteParticipant?, didReceiveData data: Data, forTopic _: String, encryptionType _: EncryptionType) { + receivedData = data + receivedDataExpectation?.fulfill() + } + + func room(_: Room, didFailToDecryptDataWithEror error: LiveKitError) { + lastDecryptionError = error + decryptionErrorExpectation?.fulfill() + } +} diff --git a/Tests/LiveKitTests/DataStream/DataChannelTests.swift b/Tests/LiveKitTests/DataChannel/RealiableDataChannelTests.swift similarity index 93% rename from Tests/LiveKitTests/DataStream/DataChannelTests.swift rename to Tests/LiveKitTests/DataChannel/RealiableDataChannelTests.swift index 2b0217af0..37b174a74 100644 --- a/Tests/LiveKitTests/DataStream/DataChannelTests.swift +++ b/Tests/LiveKitTests/DataChannel/RealiableDataChannelTests.swift @@ -17,18 +17,18 @@ @testable import LiveKit import XCTest -class DataChannelTests: LKTestCase, @unchecked Sendable { +class RealiableDataChannelTests: LKTestCase, @unchecked Sendable { var receivedExpectation: XCTestExpectation! var receivedData: Data! override func setUp() { super.setUp() - receivedExpectation = expectation(description: "Data received") receivedData = Data() } func testReliableRetry() async throws { let iterations = 128 + receivedExpectation = expectation(description: "Data received") receivedExpectation.expectedFulfillmentCount = iterations let testString = "abcdefghijklmnopqrstuvwxyz🔥" @@ -69,8 +69,8 @@ class DataChannelTests: LKTestCase, @unchecked Sendable { } } -extension DataChannelTests: RoomDelegate { - func room(_: Room, participant _: RemoteParticipant?, didReceiveData data: Data, forTopic _: String) { +extension RealiableDataChannelTests: RoomDelegate { + func room(_: Room, participant _: RemoteParticipant?, didReceiveData data: Data, forTopic _: String, encryptionType _: EncryptionType) { receivedData.append(data) receivedExpectation.fulfill() } diff --git a/Tests/LiveKitTests/DataStream/ByteStreamInfoTests.swift b/Tests/LiveKitTests/DataStream/ByteStreamInfoTests.swift index e454ce4b0..75a70511b 100644 --- a/Tests/LiveKitTests/DataStream/ByteStreamInfoTests.swift +++ b/Tests/LiveKitTests/DataStream/ByteStreamInfoTests.swift @@ -25,6 +25,7 @@ class ByteStreamInfoTests: LKTestCase { timestamp: Date(timeIntervalSince1970: 100), totalLength: 128, attributes: ["key": "value"], + encryptionType: .none, mimeType: "image/jpeg", name: "filename.bin" ) @@ -37,7 +38,7 @@ class ByteStreamInfoTests: LKTestCase { XCTAssertEqual(header.attributes, info.attributes) XCTAssertEqual(header.byteHeader.name, info.name) - let newInfo = ByteStreamInfo(header, header.byteHeader) + let newInfo = ByteStreamInfo(header, header.byteHeader, .none) XCTAssertEqual(newInfo.id, info.id) XCTAssertEqual(newInfo.mimeType, info.mimeType) XCTAssertEqual(newInfo.topic, info.topic) diff --git a/Tests/LiveKitTests/DataStream/ByteStreamReaderTests.swift b/Tests/LiveKitTests/DataStream/ByteStreamReaderTests.swift index aec4535b2..db3ef82e0 100644 --- a/Tests/LiveKitTests/DataStream/ByteStreamReaderTests.swift +++ b/Tests/LiveKitTests/DataStream/ByteStreamReaderTests.swift @@ -27,6 +27,7 @@ class ByteStreamReaderTests: LKTestCase, @unchecked Sendable { timestamp: Date(), totalLength: nil, attributes: [:], + encryptionType: .none, mimeType: "application/octet-stream", name: "filename.bin" ) diff --git a/Tests/LiveKitTests/DataStream/IncomingStreamManagerTests.swift b/Tests/LiveKitTests/DataStream/IncomingStreamManagerTests.swift index 4f23f1f73..110997e71 100644 --- a/Tests/LiveKitTests/DataStream/IncomingStreamManagerTests.swift +++ b/Tests/LiveKitTests/DataStream/IncomingStreamManagerTests.swift @@ -86,7 +86,7 @@ class IncomingStreamManagerTests: LKTestCase, @unchecked Sendable { header.streamID = streamID header.topic = topicName header.contentHeader = .byteHeader(Livekit_DataStream.ByteHeader()) - await manager.handle(header: header, from: participant.stringValue) + await manager.handle(header: header, from: participant.stringValue, encryptionType: .none) // 2. Send chunk packets for (index, chunkData) in testChunks.enumerated() { @@ -94,14 +94,14 @@ class IncomingStreamManagerTests: LKTestCase, @unchecked Sendable { chunk.streamID = streamID chunk.chunkIndex = UInt64(index) chunk.content = chunkData - await manager.handle(chunk: chunk) + await manager.handle(chunk: chunk, encryptionType: .none) } // 3. Send trailer packet var trailer = Livekit_DataStream.Trailer() trailer.streamID = streamID trailer.reason = "" // indicates normal closure - await manager.handle(trailer: trailer) + await manager.handle(trailer: trailer, encryptionType: .none) await fulfillment( of: [receiveExpectation], @@ -136,7 +136,7 @@ class IncomingStreamManagerTests: LKTestCase, @unchecked Sendable { header.streamID = streamID header.topic = topicName header.contentHeader = .textHeader(Livekit_DataStream.TextHeader()) - await manager.handle(header: header, from: participant.stringValue) + await manager.handle(header: header, from: participant.stringValue, encryptionType: .none) // 2. Send chunk packets for (index, chunkData) in testChunks.enumerated() { @@ -144,14 +144,14 @@ class IncomingStreamManagerTests: LKTestCase, @unchecked Sendable { chunk.streamID = streamID chunk.chunkIndex = UInt64(index) chunk.content = Data(chunkData.utf8) - await manager.handle(chunk: chunk) + await manager.handle(chunk: chunk, encryptionType: .none) } // 3. Send trailer packet var trailer = Livekit_DataStream.Trailer() trailer.streamID = streamID trailer.reason = "" // indicates normal closure - await manager.handle(trailer: trailer) + await manager.handle(trailer: trailer, encryptionType: .none) await fulfillment( of: [receiveExpectation], @@ -182,20 +182,20 @@ class IncomingStreamManagerTests: LKTestCase, @unchecked Sendable { header.topic = topicName header.contentHeader = .textHeader(Livekit_DataStream.TextHeader()) header.totalLength = UInt64(testPayload.count) - await manager.handle(header: header, from: participant.stringValue) + await manager.handle(header: header, from: participant.stringValue, encryptionType: .none) // 2. Send chunk packet var chunk = Livekit_DataStream.Chunk() chunk.streamID = streamID chunk.chunkIndex = 0 chunk.content = Data(testPayload) - await manager.handle(chunk: chunk) + await manager.handle(chunk: chunk, encryptionType: .none) // 3. Send trailer packet var trailer = Livekit_DataStream.Trailer() trailer.streamID = streamID trailer.reason = "" // indicates normal closure - await manager.handle(trailer: trailer) + await manager.handle(trailer: trailer, encryptionType: .none) await fulfillment( of: [throwsExpectation], @@ -223,13 +223,13 @@ class IncomingStreamManagerTests: LKTestCase, @unchecked Sendable { header.streamID = streamID header.topic = topicName header.contentHeader = .byteHeader(Livekit_DataStream.ByteHeader()) - await manager.handle(header: header, from: participant.stringValue) + await manager.handle(header: header, from: participant.stringValue, encryptionType: .none) // 2. Send trailer packet var trailer = Livekit_DataStream.Trailer() trailer.streamID = streamID trailer.reason = closureReason // indicates abnormal closure - await manager.handle(trailer: trailer) + await manager.handle(trailer: trailer, encryptionType: .none) await fulfillment( of: [throwsExpectation], @@ -259,24 +259,63 @@ class IncomingStreamManagerTests: LKTestCase, @unchecked Sendable { header.topic = topicName header.contentHeader = .byteHeader(Livekit_DataStream.ByteHeader()) header.totalLength = UInt64(testPayload.count + 10) // expect more bytes - await manager.handle(header: header, from: participant.stringValue) + await manager.handle(header: header, from: participant.stringValue, encryptionType: .none) // 2. Send chunk packet var chunk = Livekit_DataStream.Chunk() chunk.streamID = streamID chunk.chunkIndex = 0 chunk.content = Data(testPayload) - await manager.handle(chunk: chunk) + await manager.handle(chunk: chunk, encryptionType: .none) // 3. Send trailer packet var trailer = Livekit_DataStream.Trailer() trailer.streamID = streamID trailer.reason = "" // indicates normal closure - await manager.handle(trailer: trailer) + await manager.handle(trailer: trailer, encryptionType: .none) await fulfillment( of: [throwsExpectation], timeout: 5 ) } + + func testEncryptionTypeMismatch() async throws { + let manager = IncomingStreamManager() + let topic = "test-encryption-mismatch" + let streamExpectation = expectation(description: "Stream should receive error") + + try await manager.registerByteStreamHandler(for: topic) { reader, _ in + do { + _ = try await reader.readAll() + } catch let error as StreamError { + if case let .encryptionTypeMismatch(expected, received) = error { + XCTAssertEqual(expected, .gcm) // Stream was created with .gcm + XCTAssertEqual(received, .none) // But chunk sent with .none + streamExpectation.fulfill() + } else { + XCTFail("Expected encryptionTypeMismatch error, got \(error)") + } + } + } + var header = Livekit_DataStream.Header() + header.streamID = "test-stream-id" + header.topic = topic + header.mimeType = "application/octet-stream" + header.timestamp = Int64(Date().timeIntervalSince1970 * 1000) + header.contentHeader = .byteHeader(.with { + $0.name = "test-file.bin" + }) + + await manager.handle(header: header, from: "test-participant", encryptionType: .gcm) + + var chunk = Livekit_DataStream.Chunk() + chunk.streamID = "test-stream-id" + chunk.chunkIndex = 0 + chunk.content = Data("test data".utf8) + + await manager.handle(chunk: chunk, encryptionType: .none) + + await fulfillment(of: [streamExpectation], timeout: 5.0) + } } diff --git a/Tests/LiveKitTests/DataStream/OutgoingStreamManagerTests.swift b/Tests/LiveKitTests/DataStream/OutgoingStreamManagerTests.swift index 30ae9f4de..04b27ccce 100644 --- a/Tests/LiveKitTests/DataStream/OutgoingStreamManagerTests.swift +++ b/Tests/LiveKitTests/DataStream/OutgoingStreamManagerTests.swift @@ -64,6 +64,8 @@ class OutgoingStreamManagerTests: LKTestCase { default: XCTFail("Produced unexpected packet type") } + } encryptionProvider: { + .none } let writer = try await manager.streamBytes( @@ -128,6 +130,8 @@ class OutgoingStreamManagerTests: LKTestCase { default: XCTFail("Produced unexpected packet type") } + } encryptionProvider: { + .none } let writer = try await manager.streamText( @@ -158,6 +162,8 @@ class OutgoingStreamManagerTests: LKTestCase { throw testError default: break } + } encryptionProvider: { + .none } let writer = try await manager.streamText( diff --git a/Tests/LiveKitTests/DataStream/TextStreamInfoTests.swift b/Tests/LiveKitTests/DataStream/TextStreamInfoTests.swift index 0c50a7a50..9c99fc814 100644 --- a/Tests/LiveKitTests/DataStream/TextStreamInfoTests.swift +++ b/Tests/LiveKitTests/DataStream/TextStreamInfoTests.swift @@ -25,6 +25,7 @@ class TextStreamInfoTests: LKTestCase { timestamp: Date(timeIntervalSince1970: 100), totalLength: 128, attributes: ["key": "value"], + encryptionType: .none, operationType: .reaction, version: 10, replyToStreamID: "replyID", @@ -43,7 +44,7 @@ class TextStreamInfoTests: LKTestCase { XCTAssertEqual(header.textHeader.attachedStreamIds, info.attachedStreamIDs) XCTAssertEqual(header.textHeader.generated, info.generated) - let newInfo = TextStreamInfo(header, header.textHeader) + let newInfo = TextStreamInfo(header, header.textHeader, .none) XCTAssertEqual(newInfo.id, info.id) XCTAssertEqual(newInfo.topic, info.topic) XCTAssertEqual(newInfo.timestamp, info.timestamp) diff --git a/Tests/LiveKitTests/DataStream/TextStreamReaderTests.swift b/Tests/LiveKitTests/DataStream/TextStreamReaderTests.swift index 0dd0c11ef..3016bb0c3 100644 --- a/Tests/LiveKitTests/DataStream/TextStreamReaderTests.swift +++ b/Tests/LiveKitTests/DataStream/TextStreamReaderTests.swift @@ -27,6 +27,7 @@ class TextStreamReaderTests: LKTestCase, @unchecked Sendable { timestamp: Date(), totalLength: nil, attributes: [:], + encryptionType: .none, operationType: .create, version: 1, replyToStreamID: nil, diff --git a/Tests/LiveKitTests/Support/Room.swift b/Tests/LiveKitTests/Support/Room.swift index b9cdc33d4..0d4dada5c 100644 --- a/Tests/LiveKitTests/Support/Room.swift +++ b/Tests/LiveKitTests/Support/Room.swift @@ -22,6 +22,7 @@ struct RoomTestingOptions { let url: String? let token: String? let enableMicrophone: Bool + let encryptionOptions: EncryptionOptions? // Perms let canPublish: Bool @@ -33,6 +34,7 @@ struct RoomTestingOptions { url: String? = nil, token: String? = nil, enableMicrophone: Bool = false, + encryptionOptions: EncryptionOptions? = nil, canPublish: Bool = false, canPublishData: Bool = false, canPublishSources: Set = [], @@ -42,6 +44,7 @@ struct RoomTestingOptions { self.url = url self.token = token self.enableMicrophone = enableMicrophone + self.encryptionOptions = encryptionOptions self.canPublish = canPublish self.canPublishData = canPublishData self.canPublishSources = canPublishSources @@ -87,21 +90,19 @@ extension LKTestCase { // Set up variable number of Rooms func withRooms(_ options: [RoomTestingOptions] = [], - sharedKey: String = UUID().uuidString, _ block: @escaping ([Room]) async throws -> Void) async throws { - let e2eeOptions = E2EEOptions(keyProvider: BaseKeyProvider(isSharedKey: true, sharedKey: sharedKey)) - - // Turn on stats - let roomOptions = RoomOptions(e2eeOptions: e2eeOptions, reportRemoteTrackStatistics: true) - let roomName = UUID().uuidString + let sharedKey = UUID().uuidString let rooms = try options.enumerated().map { // Connect options let connectOptions = ConnectOptions(enableMicrophone: $0.element.enableMicrophone) - // Use shared RoomOptions + // Room options + let encryptionOptions = $0.element.encryptionOptions ?? EncryptionOptions(keyProvider: BaseKeyProvider(isSharedKey: true, sharedKey: sharedKey)) + let roomOptions = RoomOptions(encryptionOptions: encryptionOptions, reportRemoteTrackStatistics: true) + let room = Room(delegate: $0.element.delegate, connectOptions: connectOptions, roomOptions: roomOptions) let identity = "identity-\($0.offset)" @@ -224,7 +225,7 @@ final class RoomWatcher: RoomDelegate, Sendable { // MARK: - Delegates - func room(_: Room, participant _: RemoteParticipant?, didReceiveData data: Data, forTopic topic: String) { + func room(_: Room, participant _: RemoteParticipant?, didReceiveData data: Data, forTopic topic: String, encryptionType _: EncryptionType) { // print("didReceiveData: \(data) for topic: \(topic)") Task { do {