diff --git a/Session/Calls/CallService.swift b/Session/Calls/CallService.swift index 0802f1e2f..9bff359fd 100644 --- a/Session/Calls/CallService.swift +++ b/Session/Calls/CallService.swift @@ -503,11 +503,11 @@ public final class CallService: NSObject { if call.groupCall.localDeviceState.joinState == .notJoined { call.groupCall.join() } } - func buildOutgoingIndividualCallIfPossible(address: SignalServiceAddress, hasVideo: Bool) -> SignalCall? { + func buildOutgoingIndividualCallIfPossible(publicKey: String, hasVideo: Bool) -> SignalCall? { AssertIsOnMainThread() guard !hasCallInProgress else { return nil } - let call = SignalCall.outgoingIndividualCall(localId: UUID(), remoteAddress: address) + let call = SignalCall.outgoingIndividualCall(localId: UUID(), publicKey: publicKey) call.individualCall.offerMediaType = hasVideo ? .video : .audio addCall(call) diff --git a/Session/Calls/Individual/IndividualCall.swift b/Session/Calls/Individual/IndividualCall.swift index 9db064436..3a20ab918 100644 --- a/Session/Calls/Individual/IndividualCall.swift +++ b/Session/Calls/Individual/IndividualCall.swift @@ -102,7 +102,7 @@ public class IndividualCall: NSObject, IndividualCallNotificationInfo { var wasRemovedFromSystem = false @objc - public let remoteAddress: SignalServiceAddress + public let publicKey: String public var isEnded: Bool { switch state { @@ -179,12 +179,12 @@ public class IndividualCall: NSObject, IndividualCallNotificationInfo { // MARK: Initializers and Factory Methods - init(direction: CallDirection, localId: UUID, state: CallState, remoteAddress: SignalServiceAddress, sentAtTimestamp: UInt64, callAdapterType: CallAdapterType) { + init(direction: CallDirection, localId: UUID, state: CallState, publicKey: String, sentAtTimestamp: UInt64, callAdapterType: CallAdapterType) { self.direction = direction self.localId = localId self.state = state - self.remoteAddress = remoteAddress - self.thread = TSContactThread.getOrCreateThread(contactAddress: remoteAddress) + self.publicKey = publicKey + self.thread = TSContactThread.getOrCreateThread(contactSessionID: publicKey) self.sentAtTimestamp = sentAtTimestamp self.callAdapterType = callAdapterType } @@ -206,7 +206,7 @@ public class IndividualCall: NSObject, IndividualCallNotificationInfo { } override public var description: String { - return "IndividualCall: {\(remoteAddress), localId: \(localId), signalingId: \(callId as Optional)))}" + return "IndividualCall: {\(publicKey), localId: \(localId), signalingId: \(callId as Optional)))}" } private func updateCallRecordType() { diff --git a/Session/Calls/SignalCall.swift b/Session/Calls/SignalCall.swift index 0892aeb7b..0cee628ed 100644 --- a/Session/Calls/SignalCall.swift +++ b/Session/Calls/SignalCall.swift @@ -159,13 +159,13 @@ public class SignalCall: NSObject, CallManagerCallReference { return call } - public class func outgoingIndividualCall(localId: UUID, remoteAddress: SignalServiceAddress) -> SignalCall { + public class func outgoingIndividualCall(localId: UUID, publicKey: String) -> SignalCall { let individualCall = IndividualCall( direction: .outgoing, localId: localId, state: .dialing, - remoteAddress: remoteAddress, - sentAtTimestamp: Date.ows_millisecondTimestamp(), + publicKey: publicKey, + sentAtTimestamp: NSDate.ows_millisecondTimestamp(), callAdapterType: .default ) return SignalCall(individualCall: individualCall) diff --git a/SessionMessagingKit/Protos/Generated/SNProto.swift b/SessionMessagingKit/Protos/Generated/SNProto.swift index 997eab59c..d5a422e45 100644 --- a/SessionMessagingKit/Protos/Generated/SNProto.swift +++ b/SessionMessagingKit/Protos/Generated/SNProto.swift @@ -500,6 +500,1054 @@ extension SNProtoContent.SNProtoContentBuilder { #endif +// MARK: - SNProtoCallMessageOffer + +@objc public class SNProtoCallMessageOffer: NSObject { + + // MARK: - SNProtoCallMessageOfferType + + @objc public enum SNProtoCallMessageOfferType: Int32 { + case offerAudioCall = 0 + case offerVideoCall = 1 + } + + private class func SNProtoCallMessageOfferTypeWrap(_ value: SessionProtos_CallMessage.Offer.TypeEnum) -> SNProtoCallMessageOfferType { + switch value { + case .offerAudioCall: return .offerAudioCall + case .offerVideoCall: return .offerVideoCall + } + } + + private class func SNProtoCallMessageOfferTypeUnwrap(_ value: SNProtoCallMessageOfferType) -> SessionProtos_CallMessage.Offer.TypeEnum { + switch value { + case .offerAudioCall: return .offerAudioCall + case .offerVideoCall: return .offerVideoCall + } + } + + // MARK: - SNProtoCallMessageOfferBuilder + + @objc public class func builder(id: UInt64) -> SNProtoCallMessageOfferBuilder { + return SNProtoCallMessageOfferBuilder(id: id) + } + + // asBuilder() constructs a builder that reflects the proto's contents. + @objc public func asBuilder() -> SNProtoCallMessageOfferBuilder { + let builder = SNProtoCallMessageOfferBuilder(id: id) + if let _value = sdp { + builder.setSdp(_value) + } + if hasType { + builder.setType(type) + } + if let _value = opaque { + builder.setOpaque(_value) + } + return builder + } + + @objc public class SNProtoCallMessageOfferBuilder: NSObject { + + private var proto = SessionProtos_CallMessage.Offer() + + @objc fileprivate override init() {} + + @objc fileprivate init(id: UInt64) { + super.init() + + setId(id) + } + + @objc public func setId(_ valueParam: UInt64) { + proto.id = valueParam + } + + @objc public func setSdp(_ valueParam: String) { + proto.sdp = valueParam + } + + @objc public func setType(_ valueParam: SNProtoCallMessageOfferType) { + proto.type = SNProtoCallMessageOfferTypeUnwrap(valueParam) + } + + @objc public func setOpaque(_ valueParam: Data) { + proto.opaque = valueParam + } + + @objc public func build() throws -> SNProtoCallMessageOffer { + return try SNProtoCallMessageOffer.parseProto(proto) + } + + @objc public func buildSerializedData() throws -> Data { + return try SNProtoCallMessageOffer.parseProto(proto).serializedData() + } + } + + fileprivate let proto: SessionProtos_CallMessage.Offer + + @objc public let id: UInt64 + + @objc public var sdp: String? { + guard proto.hasSdp else { + return nil + } + return proto.sdp + } + @objc public var hasSdp: Bool { + return proto.hasSdp + } + + @objc public var type: SNProtoCallMessageOfferType { + return SNProtoCallMessageOffer.SNProtoCallMessageOfferTypeWrap(proto.type) + } + @objc public var hasType: Bool { + return proto.hasType + } + + @objc public var opaque: Data? { + guard proto.hasOpaque else { + return nil + } + return proto.opaque + } + @objc public var hasOpaque: Bool { + return proto.hasOpaque + } + + private init(proto: SessionProtos_CallMessage.Offer, + id: UInt64) { + self.proto = proto + self.id = id + } + + @objc + public func serializedData() throws -> Data { + return try self.proto.serializedData() + } + + @objc public class func parseData(_ serializedData: Data) throws -> SNProtoCallMessageOffer { + let proto = try SessionProtos_CallMessage.Offer(serializedData: serializedData) + return try parseProto(proto) + } + + fileprivate class func parseProto(_ proto: SessionProtos_CallMessage.Offer) throws -> SNProtoCallMessageOffer { + guard proto.hasID else { + throw SNProtoError.invalidProtobuf(description: "\(logTag) missing required field: id") + } + let id = proto.id + + // MARK: - Begin Validation Logic for SNProtoCallMessageOffer - + + // MARK: - End Validation Logic for SNProtoCallMessageOffer - + + let result = SNProtoCallMessageOffer(proto: proto, + id: id) + return result + } + + @objc public override var debugDescription: String { + return "\(proto)" + } +} + +#if DEBUG + +extension SNProtoCallMessageOffer { + @objc public func serializedDataIgnoringErrors() -> Data? { + return try! self.serializedData() + } +} + +extension SNProtoCallMessageOffer.SNProtoCallMessageOfferBuilder { + @objc public func buildIgnoringErrors() -> SNProtoCallMessageOffer? { + return try! self.build() + } +} + +#endif + +// MARK: - SNProtoCallMessageAnswer + +@objc public class SNProtoCallMessageAnswer: NSObject { + + // MARK: - SNProtoCallMessageAnswerBuilder + + @objc public class func builder(id: UInt64) -> SNProtoCallMessageAnswerBuilder { + return SNProtoCallMessageAnswerBuilder(id: id) + } + + // asBuilder() constructs a builder that reflects the proto's contents. + @objc public func asBuilder() -> SNProtoCallMessageAnswerBuilder { + let builder = SNProtoCallMessageAnswerBuilder(id: id) + if let _value = sdp { + builder.setSdp(_value) + } + if let _value = opaque { + builder.setOpaque(_value) + } + return builder + } + + @objc public class SNProtoCallMessageAnswerBuilder: NSObject { + + private var proto = SessionProtos_CallMessage.Answer() + + @objc fileprivate override init() {} + + @objc fileprivate init(id: UInt64) { + super.init() + + setId(id) + } + + @objc public func setId(_ valueParam: UInt64) { + proto.id = valueParam + } + + @objc public func setSdp(_ valueParam: String) { + proto.sdp = valueParam + } + + @objc public func setOpaque(_ valueParam: Data) { + proto.opaque = valueParam + } + + @objc public func build() throws -> SNProtoCallMessageAnswer { + return try SNProtoCallMessageAnswer.parseProto(proto) + } + + @objc public func buildSerializedData() throws -> Data { + return try SNProtoCallMessageAnswer.parseProto(proto).serializedData() + } + } + + fileprivate let proto: SessionProtos_CallMessage.Answer + + @objc public let id: UInt64 + + @objc public var sdp: String? { + guard proto.hasSdp else { + return nil + } + return proto.sdp + } + @objc public var hasSdp: Bool { + return proto.hasSdp + } + + @objc public var opaque: Data? { + guard proto.hasOpaque else { + return nil + } + return proto.opaque + } + @objc public var hasOpaque: Bool { + return proto.hasOpaque + } + + private init(proto: SessionProtos_CallMessage.Answer, + id: UInt64) { + self.proto = proto + self.id = id + } + + @objc + public func serializedData() throws -> Data { + return try self.proto.serializedData() + } + + @objc public class func parseData(_ serializedData: Data) throws -> SNProtoCallMessageAnswer { + let proto = try SessionProtos_CallMessage.Answer(serializedData: serializedData) + return try parseProto(proto) + } + + fileprivate class func parseProto(_ proto: SessionProtos_CallMessage.Answer) throws -> SNProtoCallMessageAnswer { + guard proto.hasID else { + throw SNProtoError.invalidProtobuf(description: "\(logTag) missing required field: id") + } + let id = proto.id + + // MARK: - Begin Validation Logic for SNProtoCallMessageAnswer - + + // MARK: - End Validation Logic for SNProtoCallMessageAnswer - + + let result = SNProtoCallMessageAnswer(proto: proto, + id: id) + return result + } + + @objc public override var debugDescription: String { + return "\(proto)" + } +} + +#if DEBUG + +extension SNProtoCallMessageAnswer { + @objc public func serializedDataIgnoringErrors() -> Data? { + return try! self.serializedData() + } +} + +extension SNProtoCallMessageAnswer.SNProtoCallMessageAnswerBuilder { + @objc public func buildIgnoringErrors() -> SNProtoCallMessageAnswer? { + return try! self.build() + } +} + +#endif + +// MARK: - SNProtoCallMessageIceUpdate + +@objc public class SNProtoCallMessageIceUpdate: NSObject { + + // MARK: - SNProtoCallMessageIceUpdateBuilder + + @objc public class func builder(id: UInt64) -> SNProtoCallMessageIceUpdateBuilder { + return SNProtoCallMessageIceUpdateBuilder(id: id) + } + + // asBuilder() constructs a builder that reflects the proto's contents. + @objc public func asBuilder() -> SNProtoCallMessageIceUpdateBuilder { + let builder = SNProtoCallMessageIceUpdateBuilder(id: id) + if let _value = mid { + builder.setMid(_value) + } + if hasLine { + builder.setLine(line) + } + if let _value = sdp { + builder.setSdp(_value) + } + if let _value = opaque { + builder.setOpaque(_value) + } + return builder + } + + @objc public class SNProtoCallMessageIceUpdateBuilder: NSObject { + + private var proto = SessionProtos_CallMessage.IceUpdate() + + @objc fileprivate override init() {} + + @objc fileprivate init(id: UInt64) { + super.init() + + setId(id) + } + + @objc public func setId(_ valueParam: UInt64) { + proto.id = valueParam + } + + @objc public func setMid(_ valueParam: String) { + proto.mid = valueParam + } + + @objc public func setLine(_ valueParam: UInt32) { + proto.line = valueParam + } + + @objc public func setSdp(_ valueParam: String) { + proto.sdp = valueParam + } + + @objc public func setOpaque(_ valueParam: Data) { + proto.opaque = valueParam + } + + @objc public func build() throws -> SNProtoCallMessageIceUpdate { + return try SNProtoCallMessageIceUpdate.parseProto(proto) + } + + @objc public func buildSerializedData() throws -> Data { + return try SNProtoCallMessageIceUpdate.parseProto(proto).serializedData() + } + } + + fileprivate let proto: SessionProtos_CallMessage.IceUpdate + + @objc public let id: UInt64 + + @objc public var mid: String? { + guard proto.hasMid else { + return nil + } + return proto.mid + } + @objc public var hasMid: Bool { + return proto.hasMid + } + + @objc public var line: UInt32 { + return proto.line + } + @objc public var hasLine: Bool { + return proto.hasLine + } + + @objc public var sdp: String? { + guard proto.hasSdp else { + return nil + } + return proto.sdp + } + @objc public var hasSdp: Bool { + return proto.hasSdp + } + + @objc public var opaque: Data? { + guard proto.hasOpaque else { + return nil + } + return proto.opaque + } + @objc public var hasOpaque: Bool { + return proto.hasOpaque + } + + private init(proto: SessionProtos_CallMessage.IceUpdate, + id: UInt64) { + self.proto = proto + self.id = id + } + + @objc + public func serializedData() throws -> Data { + return try self.proto.serializedData() + } + + @objc public class func parseData(_ serializedData: Data) throws -> SNProtoCallMessageIceUpdate { + let proto = try SessionProtos_CallMessage.IceUpdate(serializedData: serializedData) + return try parseProto(proto) + } + + fileprivate class func parseProto(_ proto: SessionProtos_CallMessage.IceUpdate) throws -> SNProtoCallMessageIceUpdate { + guard proto.hasID else { + throw SNProtoError.invalidProtobuf(description: "\(logTag) missing required field: id") + } + let id = proto.id + + // MARK: - Begin Validation Logic for SNProtoCallMessageIceUpdate - + + // MARK: - End Validation Logic for SNProtoCallMessageIceUpdate - + + let result = SNProtoCallMessageIceUpdate(proto: proto, + id: id) + return result + } + + @objc public override var debugDescription: String { + return "\(proto)" + } +} + +#if DEBUG + +extension SNProtoCallMessageIceUpdate { + @objc public func serializedDataIgnoringErrors() -> Data? { + return try! self.serializedData() + } +} + +extension SNProtoCallMessageIceUpdate.SNProtoCallMessageIceUpdateBuilder { + @objc public func buildIgnoringErrors() -> SNProtoCallMessageIceUpdate? { + return try! self.build() + } +} + +#endif + +// MARK: - SNProtoCallMessageBusy + +@objc public class SNProtoCallMessageBusy: NSObject { + + // MARK: - SNProtoCallMessageBusyBuilder + + @objc public class func builder(id: UInt64) -> SNProtoCallMessageBusyBuilder { + return SNProtoCallMessageBusyBuilder(id: id) + } + + // asBuilder() constructs a builder that reflects the proto's contents. + @objc public func asBuilder() -> SNProtoCallMessageBusyBuilder { + let builder = SNProtoCallMessageBusyBuilder(id: id) + return builder + } + + @objc public class SNProtoCallMessageBusyBuilder: NSObject { + + private var proto = SessionProtos_CallMessage.Busy() + + @objc fileprivate override init() {} + + @objc fileprivate init(id: UInt64) { + super.init() + + setId(id) + } + + @objc public func setId(_ valueParam: UInt64) { + proto.id = valueParam + } + + @objc public func build() throws -> SNProtoCallMessageBusy { + return try SNProtoCallMessageBusy.parseProto(proto) + } + + @objc public func buildSerializedData() throws -> Data { + return try SNProtoCallMessageBusy.parseProto(proto).serializedData() + } + } + + fileprivate let proto: SessionProtos_CallMessage.Busy + + @objc public let id: UInt64 + + private init(proto: SessionProtos_CallMessage.Busy, + id: UInt64) { + self.proto = proto + self.id = id + } + + @objc + public func serializedData() throws -> Data { + return try self.proto.serializedData() + } + + @objc public class func parseData(_ serializedData: Data) throws -> SNProtoCallMessageBusy { + let proto = try SessionProtos_CallMessage.Busy(serializedData: serializedData) + return try parseProto(proto) + } + + fileprivate class func parseProto(_ proto: SessionProtos_CallMessage.Busy) throws -> SNProtoCallMessageBusy { + guard proto.hasID else { + throw SNProtoError.invalidProtobuf(description: "\(logTag) missing required field: id") + } + let id = proto.id + + // MARK: - Begin Validation Logic for SNProtoCallMessageBusy - + + // MARK: - End Validation Logic for SNProtoCallMessageBusy - + + let result = SNProtoCallMessageBusy(proto: proto, + id: id) + return result + } + + @objc public override var debugDescription: String { + return "\(proto)" + } +} + +#if DEBUG + +extension SNProtoCallMessageBusy { + @objc public func serializedDataIgnoringErrors() -> Data? { + return try! self.serializedData() + } +} + +extension SNProtoCallMessageBusy.SNProtoCallMessageBusyBuilder { + @objc public func buildIgnoringErrors() -> SNProtoCallMessageBusy? { + return try! self.build() + } +} + +#endif + +// MARK: - SNProtoCallMessageHangup + +@objc public class SNProtoCallMessageHangup: NSObject { + + // MARK: - SNProtoCallMessageHangupType + + @objc public enum SNProtoCallMessageHangupType: Int32 { + case hangupNormal = 0 + case hangupAccepted = 1 + case hangupDeclined = 2 + case hangupBusy = 3 + case hangupNeedPermission = 4 + } + + private class func SNProtoCallMessageHangupTypeWrap(_ value: SessionProtos_CallMessage.Hangup.TypeEnum) -> SNProtoCallMessageHangupType { + switch value { + case .hangupNormal: return .hangupNormal + case .hangupAccepted: return .hangupAccepted + case .hangupDeclined: return .hangupDeclined + case .hangupBusy: return .hangupBusy + case .hangupNeedPermission: return .hangupNeedPermission + } + } + + private class func SNProtoCallMessageHangupTypeUnwrap(_ value: SNProtoCallMessageHangupType) -> SessionProtos_CallMessage.Hangup.TypeEnum { + switch value { + case .hangupNormal: return .hangupNormal + case .hangupAccepted: return .hangupAccepted + case .hangupDeclined: return .hangupDeclined + case .hangupBusy: return .hangupBusy + case .hangupNeedPermission: return .hangupNeedPermission + } + } + + // MARK: - SNProtoCallMessageHangupBuilder + + @objc public class func builder(id: UInt64) -> SNProtoCallMessageHangupBuilder { + return SNProtoCallMessageHangupBuilder(id: id) + } + + // asBuilder() constructs a builder that reflects the proto's contents. + @objc public func asBuilder() -> SNProtoCallMessageHangupBuilder { + let builder = SNProtoCallMessageHangupBuilder(id: id) + if hasType { + builder.setType(type) + } + if hasDeviceID { + builder.setDeviceID(deviceID) + } + return builder + } + + @objc public class SNProtoCallMessageHangupBuilder: NSObject { + + private var proto = SessionProtos_CallMessage.Hangup() + + @objc fileprivate override init() {} + + @objc fileprivate init(id: UInt64) { + super.init() + + setId(id) + } + + @objc public func setId(_ valueParam: UInt64) { + proto.id = valueParam + } + + @objc public func setType(_ valueParam: SNProtoCallMessageHangupType) { + proto.type = SNProtoCallMessageHangupTypeUnwrap(valueParam) + } + + @objc public func setDeviceID(_ valueParam: UInt32) { + proto.deviceID = valueParam + } + + @objc public func build() throws -> SNProtoCallMessageHangup { + return try SNProtoCallMessageHangup.parseProto(proto) + } + + @objc public func buildSerializedData() throws -> Data { + return try SNProtoCallMessageHangup.parseProto(proto).serializedData() + } + } + + fileprivate let proto: SessionProtos_CallMessage.Hangup + + @objc public let id: UInt64 + + @objc public var type: SNProtoCallMessageHangupType { + return SNProtoCallMessageHangup.SNProtoCallMessageHangupTypeWrap(proto.type) + } + @objc public var hasType: Bool { + return proto.hasType + } + + @objc public var deviceID: UInt32 { + return proto.deviceID + } + @objc public var hasDeviceID: Bool { + return proto.hasDeviceID + } + + private init(proto: SessionProtos_CallMessage.Hangup, + id: UInt64) { + self.proto = proto + self.id = id + } + + @objc + public func serializedData() throws -> Data { + return try self.proto.serializedData() + } + + @objc public class func parseData(_ serializedData: Data) throws -> SNProtoCallMessageHangup { + let proto = try SessionProtos_CallMessage.Hangup(serializedData: serializedData) + return try parseProto(proto) + } + + fileprivate class func parseProto(_ proto: SessionProtos_CallMessage.Hangup) throws -> SNProtoCallMessageHangup { + guard proto.hasID else { + throw SNProtoError.invalidProtobuf(description: "\(logTag) missing required field: id") + } + let id = proto.id + + // MARK: - Begin Validation Logic for SNProtoCallMessageHangup - + + // MARK: - End Validation Logic for SNProtoCallMessageHangup - + + let result = SNProtoCallMessageHangup(proto: proto, + id: id) + return result + } + + @objc public override var debugDescription: String { + return "\(proto)" + } +} + +#if DEBUG + +extension SNProtoCallMessageHangup { + @objc public func serializedDataIgnoringErrors() -> Data? { + return try! self.serializedData() + } +} + +extension SNProtoCallMessageHangup.SNProtoCallMessageHangupBuilder { + @objc public func buildIgnoringErrors() -> SNProtoCallMessageHangup? { + return try! self.build() + } +} + +#endif + +// MARK: - SNProtoCallMessageOpaque + +@objc public class SNProtoCallMessageOpaque: NSObject { + + // MARK: - SNProtoCallMessageOpaqueBuilder + + @objc public class func builder() -> SNProtoCallMessageOpaqueBuilder { + return SNProtoCallMessageOpaqueBuilder() + } + + // asBuilder() constructs a builder that reflects the proto's contents. + @objc public func asBuilder() -> SNProtoCallMessageOpaqueBuilder { + let builder = SNProtoCallMessageOpaqueBuilder() + if let _value = data { + builder.setData(_value) + } + return builder + } + + @objc public class SNProtoCallMessageOpaqueBuilder: NSObject { + + private var proto = SessionProtos_CallMessage.Opaque() + + @objc fileprivate override init() {} + + @objc public func setData(_ valueParam: Data) { + proto.data = valueParam + } + + @objc public func build() throws -> SNProtoCallMessageOpaque { + return try SNProtoCallMessageOpaque.parseProto(proto) + } + + @objc public func buildSerializedData() throws -> Data { + return try SNProtoCallMessageOpaque.parseProto(proto).serializedData() + } + } + + fileprivate let proto: SessionProtos_CallMessage.Opaque + + @objc public var data: Data? { + guard proto.hasData else { + return nil + } + return proto.data + } + @objc public var hasData: Bool { + return proto.hasData + } + + private init(proto: SessionProtos_CallMessage.Opaque) { + self.proto = proto + } + + @objc + public func serializedData() throws -> Data { + return try self.proto.serializedData() + } + + @objc public class func parseData(_ serializedData: Data) throws -> SNProtoCallMessageOpaque { + let proto = try SessionProtos_CallMessage.Opaque(serializedData: serializedData) + return try parseProto(proto) + } + + fileprivate class func parseProto(_ proto: SessionProtos_CallMessage.Opaque) throws -> SNProtoCallMessageOpaque { + // MARK: - Begin Validation Logic for SNProtoCallMessageOpaque - + + // MARK: - End Validation Logic for SNProtoCallMessageOpaque - + + let result = SNProtoCallMessageOpaque(proto: proto) + return result + } + + @objc public override var debugDescription: String { + return "\(proto)" + } +} + +#if DEBUG + +extension SNProtoCallMessageOpaque { + @objc public func serializedDataIgnoringErrors() -> Data? { + return try! self.serializedData() + } +} + +extension SNProtoCallMessageOpaque.SNProtoCallMessageOpaqueBuilder { + @objc public func buildIgnoringErrors() -> SNProtoCallMessageOpaque? { + return try! self.build() + } +} + +#endif + +// MARK: - SNProtoCallMessage + +@objc public class SNProtoCallMessage: NSObject { + + // MARK: - SNProtoCallMessageBuilder + + @objc public class func builder() -> SNProtoCallMessageBuilder { + return SNProtoCallMessageBuilder() + } + + // asBuilder() constructs a builder that reflects the proto's contents. + @objc public func asBuilder() -> SNProtoCallMessageBuilder { + let builder = SNProtoCallMessageBuilder() + if let _value = offer { + builder.setOffer(_value) + } + if let _value = answer { + builder.setAnswer(_value) + } + builder.setIceUpdate(iceUpdate) + if let _value = legacyHangup { + builder.setLegacyHangup(_value) + } + if let _value = busy { + builder.setBusy(_value) + } + if let _value = profileKey { + builder.setProfileKey(_value) + } + if let _value = hangup { + builder.setHangup(_value) + } + if hasSupportsMultiRing { + builder.setSupportsMultiRing(supportsMultiRing) + } + if hasDestinationDeviceID { + builder.setDestinationDeviceID(destinationDeviceID) + } + if let _value = opaque { + builder.setOpaque(_value) + } + return builder + } + + @objc public class SNProtoCallMessageBuilder: NSObject { + + private var proto = SessionProtos_CallMessage() + + @objc fileprivate override init() {} + + @objc public func setOffer(_ valueParam: SNProtoCallMessageOffer) { + proto.offer = valueParam.proto + } + + @objc public func setAnswer(_ valueParam: SNProtoCallMessageAnswer) { + proto.answer = valueParam.proto + } + + @objc public func addIceUpdate(_ valueParam: SNProtoCallMessageIceUpdate) { + var items = proto.iceUpdate + items.append(valueParam.proto) + proto.iceUpdate = items + } + + @objc public func setIceUpdate(_ wrappedItems: [SNProtoCallMessageIceUpdate]) { + proto.iceUpdate = wrappedItems.map { $0.proto } + } + + @objc public func setLegacyHangup(_ valueParam: SNProtoCallMessageHangup) { + proto.legacyHangup = valueParam.proto + } + + @objc public func setBusy(_ valueParam: SNProtoCallMessageBusy) { + proto.busy = valueParam.proto + } + + @objc public func setProfileKey(_ valueParam: Data) { + proto.profileKey = valueParam + } + + @objc public func setHangup(_ valueParam: SNProtoCallMessageHangup) { + proto.hangup = valueParam.proto + } + + @objc public func setSupportsMultiRing(_ valueParam: Bool) { + proto.supportsMultiRing = valueParam + } + + @objc public func setDestinationDeviceID(_ valueParam: UInt32) { + proto.destinationDeviceID = valueParam + } + + @objc public func setOpaque(_ valueParam: SNProtoCallMessageOpaque) { + proto.opaque = valueParam.proto + } + + @objc public func build() throws -> SNProtoCallMessage { + return try SNProtoCallMessage.parseProto(proto) + } + + @objc public func buildSerializedData() throws -> Data { + return try SNProtoCallMessage.parseProto(proto).serializedData() + } + } + + fileprivate let proto: SessionProtos_CallMessage + + @objc public let offer: SNProtoCallMessageOffer? + + @objc public let answer: SNProtoCallMessageAnswer? + + @objc public let iceUpdate: [SNProtoCallMessageIceUpdate] + + @objc public let legacyHangup: SNProtoCallMessageHangup? + + @objc public let busy: SNProtoCallMessageBusy? + + @objc public let hangup: SNProtoCallMessageHangup? + + @objc public let opaque: SNProtoCallMessageOpaque? + + @objc public var profileKey: Data? { + guard proto.hasProfileKey else { + return nil + } + return proto.profileKey + } + @objc public var hasProfileKey: Bool { + return proto.hasProfileKey + } + + @objc public var supportsMultiRing: Bool { + return proto.supportsMultiRing + } + @objc public var hasSupportsMultiRing: Bool { + return proto.hasSupportsMultiRing + } + + @objc public var destinationDeviceID: UInt32 { + return proto.destinationDeviceID + } + @objc public var hasDestinationDeviceID: Bool { + return proto.hasDestinationDeviceID + } + + private init(proto: SessionProtos_CallMessage, + offer: SNProtoCallMessageOffer?, + answer: SNProtoCallMessageAnswer?, + iceUpdate: [SNProtoCallMessageIceUpdate], + legacyHangup: SNProtoCallMessageHangup?, + busy: SNProtoCallMessageBusy?, + hangup: SNProtoCallMessageHangup?, + opaque: SNProtoCallMessageOpaque?) { + self.proto = proto + self.offer = offer + self.answer = answer + self.iceUpdate = iceUpdate + self.legacyHangup = legacyHangup + self.busy = busy + self.hangup = hangup + self.opaque = opaque + } + + @objc + public func serializedData() throws -> Data { + return try self.proto.serializedData() + } + + @objc public class func parseData(_ serializedData: Data) throws -> SNProtoCallMessage { + let proto = try SessionProtos_CallMessage(serializedData: serializedData) + return try parseProto(proto) + } + + fileprivate class func parseProto(_ proto: SessionProtos_CallMessage) throws -> SNProtoCallMessage { + var offer: SNProtoCallMessageOffer? = nil + if proto.hasOffer { + offer = try SNProtoCallMessageOffer.parseProto(proto.offer) + } + + var answer: SNProtoCallMessageAnswer? = nil + if proto.hasAnswer { + answer = try SNProtoCallMessageAnswer.parseProto(proto.answer) + } + + var iceUpdate: [SNProtoCallMessageIceUpdate] = [] + iceUpdate = try proto.iceUpdate.map { try SNProtoCallMessageIceUpdate.parseProto($0) } + + var legacyHangup: SNProtoCallMessageHangup? = nil + if proto.hasLegacyHangup { + legacyHangup = try SNProtoCallMessageHangup.parseProto(proto.legacyHangup) + } + + var busy: SNProtoCallMessageBusy? = nil + if proto.hasBusy { + busy = try SNProtoCallMessageBusy.parseProto(proto.busy) + } + + var hangup: SNProtoCallMessageHangup? = nil + if proto.hasHangup { + hangup = try SNProtoCallMessageHangup.parseProto(proto.hangup) + } + + var opaque: SNProtoCallMessageOpaque? = nil + if proto.hasOpaque { + opaque = try SNProtoCallMessageOpaque.parseProto(proto.opaque) + } + + // MARK: - Begin Validation Logic for SNProtoCallMessage - + + // MARK: - End Validation Logic for SNProtoCallMessage - + + let result = SNProtoCallMessage(proto: proto, + offer: offer, + answer: answer, + iceUpdate: iceUpdate, + legacyHangup: legacyHangup, + busy: busy, + hangup: hangup, + opaque: opaque) + return result + } + + @objc public override var debugDescription: String { + return "\(proto)" + } +} + +#if DEBUG + +extension SNProtoCallMessage { + @objc public func serializedDataIgnoringErrors() -> Data? { + return try! self.serializedData() + } +} + +extension SNProtoCallMessage.SNProtoCallMessageBuilder { + @objc public func buildIgnoringErrors() -> SNProtoCallMessage? { + return try! self.build() + } +} + +#endif + // MARK: - SNProtoKeyPair @objc public class SNProtoKeyPair: NSObject { diff --git a/SessionMessagingKit/Protos/Generated/SessionProtos.pb.swift b/SessionMessagingKit/Protos/Generated/SessionProtos.pb.swift index 37c95f8f0..ec5dd7649 100644 --- a/SessionMessagingKit/Protos/Generated/SessionProtos.pb.swift +++ b/SessionMessagingKit/Protos/Generated/SessionProtos.pb.swift @@ -257,6 +257,427 @@ struct SessionProtos_Content { fileprivate var _dataExtractionNotification: SessionProtos_DataExtractionNotification? = nil } +struct SessionProtos_CallMessage { + // 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 offer: SessionProtos_CallMessage.Offer { + get {return _storage._offer ?? SessionProtos_CallMessage.Offer()} + set {_uniqueStorage()._offer = newValue} + } + /// Returns true if `offer` has been explicitly set. + var hasOffer: Bool {return _storage._offer != nil} + /// Clears the value of `offer`. Subsequent reads from it will return its default value. + mutating func clearOffer() {_uniqueStorage()._offer = nil} + + var answer: SessionProtos_CallMessage.Answer { + get {return _storage._answer ?? SessionProtos_CallMessage.Answer()} + set {_uniqueStorage()._answer = newValue} + } + /// Returns true if `answer` has been explicitly set. + var hasAnswer: Bool {return _storage._answer != nil} + /// Clears the value of `answer`. Subsequent reads from it will return its default value. + mutating func clearAnswer() {_uniqueStorage()._answer = nil} + + var iceUpdate: [SessionProtos_CallMessage.IceUpdate] { + get {return _storage._iceUpdate} + set {_uniqueStorage()._iceUpdate = newValue} + } + + var legacyHangup: SessionProtos_CallMessage.Hangup { + get {return _storage._legacyHangup ?? SessionProtos_CallMessage.Hangup()} + set {_uniqueStorage()._legacyHangup = newValue} + } + /// Returns true if `legacyHangup` has been explicitly set. + var hasLegacyHangup: Bool {return _storage._legacyHangup != nil} + /// Clears the value of `legacyHangup`. Subsequent reads from it will return its default value. + mutating func clearLegacyHangup() {_uniqueStorage()._legacyHangup = nil} + + var busy: SessionProtos_CallMessage.Busy { + get {return _storage._busy ?? SessionProtos_CallMessage.Busy()} + set {_uniqueStorage()._busy = newValue} + } + /// Returns true if `busy` has been explicitly set. + var hasBusy: Bool {return _storage._busy != nil} + /// Clears the value of `busy`. Subsequent reads from it will return its default value. + mutating func clearBusy() {_uniqueStorage()._busy = nil} + + /// Signal-iOS sends profile key with call messages + /// for earlier discovery. + var profileKey: Data { + get {return _storage._profileKey ?? Data()} + set {_uniqueStorage()._profileKey = newValue} + } + /// Returns true if `profileKey` has been explicitly set. + var hasProfileKey: Bool {return _storage._profileKey != nil} + /// Clears the value of `profileKey`. Subsequent reads from it will return its default value. + mutating func clearProfileKey() {_uniqueStorage()._profileKey = nil} + + var hangup: SessionProtos_CallMessage.Hangup { + get {return _storage._hangup ?? SessionProtos_CallMessage.Hangup()} + set {_uniqueStorage()._hangup = newValue} + } + /// Returns true if `hangup` has been explicitly set. + var hasHangup: Bool {return _storage._hangup != nil} + /// Clears the value of `hangup`. Subsequent reads from it will return its default value. + mutating func clearHangup() {_uniqueStorage()._hangup = nil} + + var supportsMultiRing: Bool { + get {return _storage._supportsMultiRing ?? false} + set {_uniqueStorage()._supportsMultiRing = newValue} + } + /// Returns true if `supportsMultiRing` has been explicitly set. + var hasSupportsMultiRing: Bool {return _storage._supportsMultiRing != nil} + /// Clears the value of `supportsMultiRing`. Subsequent reads from it will return its default value. + mutating func clearSupportsMultiRing() {_uniqueStorage()._supportsMultiRing = nil} + + var destinationDeviceID: UInt32 { + get {return _storage._destinationDeviceID ?? 0} + set {_uniqueStorage()._destinationDeviceID = newValue} + } + /// Returns true if `destinationDeviceID` has been explicitly set. + var hasDestinationDeviceID: Bool {return _storage._destinationDeviceID != nil} + /// Clears the value of `destinationDeviceID`. Subsequent reads from it will return its default value. + mutating func clearDestinationDeviceID() {_uniqueStorage()._destinationDeviceID = nil} + + var opaque: SessionProtos_CallMessage.Opaque { + get {return _storage._opaque ?? SessionProtos_CallMessage.Opaque()} + set {_uniqueStorage()._opaque = newValue} + } + /// Returns true if `opaque` has been explicitly set. + var hasOpaque: Bool {return _storage._opaque != nil} + /// Clears the value of `opaque`. Subsequent reads from it will return its default value. + mutating func clearOpaque() {_uniqueStorage()._opaque = nil} + + var unknownFields = SwiftProtobuf.UnknownStorage() + + struct Offer { + // 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. + + /// @required + var id: UInt64 { + get {return _id ?? 0} + set {_id = newValue} + } + /// Returns true if `id` has been explicitly set. + var hasID: Bool {return self._id != nil} + /// Clears the value of `id`. Subsequent reads from it will return its default value. + mutating func clearID() {self._id = nil} + + /// Legacy/deprecated; replaced by 'opaque' + var sdp: String { + get {return _sdp ?? String()} + set {_sdp = newValue} + } + /// Returns true if `sdp` has been explicitly set. + var hasSdp: Bool {return self._sdp != nil} + /// Clears the value of `sdp`. Subsequent reads from it will return its default value. + mutating func clearSdp() {self._sdp = nil} + + var type: SessionProtos_CallMessage.Offer.TypeEnum { + get {return _type ?? .offerAudioCall} + set {_type = newValue} + } + /// Returns true if `type` has been explicitly set. + var hasType: Bool {return self._type != nil} + /// Clears the value of `type`. Subsequent reads from it will return its default value. + mutating func clearType() {self._type = nil} + + var opaque: Data { + get {return _opaque ?? Data()} + set {_opaque = newValue} + } + /// Returns true if `opaque` has been explicitly set. + var hasOpaque: Bool {return self._opaque != nil} + /// Clears the value of `opaque`. Subsequent reads from it will return its default value. + mutating func clearOpaque() {self._opaque = nil} + + var unknownFields = SwiftProtobuf.UnknownStorage() + + enum TypeEnum: SwiftProtobuf.Enum { + typealias RawValue = Int + case offerAudioCall // = 0 + + /// next index 3, skip 2 – it was the unused "NEED_PERMISSION" type + case offerVideoCall // = 1 + + init() { + self = .offerAudioCall + } + + init?(rawValue: Int) { + switch rawValue { + case 0: self = .offerAudioCall + case 1: self = .offerVideoCall + default: return nil + } + } + + var rawValue: Int { + switch self { + case .offerAudioCall: return 0 + case .offerVideoCall: return 1 + } + } + + } + + init() {} + + fileprivate var _id: UInt64? = nil + fileprivate var _sdp: String? = nil + fileprivate var _type: SessionProtos_CallMessage.Offer.TypeEnum? = nil + fileprivate var _opaque: Data? = nil + } + + struct Answer { + // 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. + + /// @required + var id: UInt64 { + get {return _id ?? 0} + set {_id = newValue} + } + /// Returns true if `id` has been explicitly set. + var hasID: Bool {return self._id != nil} + /// Clears the value of `id`. Subsequent reads from it will return its default value. + mutating func clearID() {self._id = nil} + + /// Legacy/deprecated; replaced by 'opaque' + var sdp: String { + get {return _sdp ?? String()} + set {_sdp = newValue} + } + /// Returns true if `sdp` has been explicitly set. + var hasSdp: Bool {return self._sdp != nil} + /// Clears the value of `sdp`. Subsequent reads from it will return its default value. + mutating func clearSdp() {self._sdp = nil} + + var opaque: Data { + get {return _opaque ?? Data()} + set {_opaque = newValue} + } + /// Returns true if `opaque` has been explicitly set. + var hasOpaque: Bool {return self._opaque != nil} + /// Clears the value of `opaque`. Subsequent reads from it will return its default value. + mutating func clearOpaque() {self._opaque = nil} + + var unknownFields = SwiftProtobuf.UnknownStorage() + + init() {} + + fileprivate var _id: UInt64? = nil + fileprivate var _sdp: String? = nil + fileprivate var _opaque: Data? = nil + } + + struct IceUpdate { + // 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. + + /// @required + var id: UInt64 { + get {return _id ?? 0} + set {_id = newValue} + } + /// Returns true if `id` has been explicitly set. + var hasID: Bool {return self._id != nil} + /// Clears the value of `id`. Subsequent reads from it will return its default value. + mutating func clearID() {self._id = nil} + + /// Legacy/deprecated; remove when old clients are gone. + var mid: String { + get {return _mid ?? String()} + set {_mid = newValue} + } + /// Returns true if `mid` has been explicitly set. + var hasMid: Bool {return self._mid != nil} + /// Clears the value of `mid`. Subsequent reads from it will return its default value. + mutating func clearMid() {self._mid = nil} + + /// Legacy/deprecated; remove when old clients are gone. + var line: UInt32 { + get {return _line ?? 0} + set {_line = newValue} + } + /// Returns true if `line` has been explicitly set. + var hasLine: Bool {return self._line != nil} + /// Clears the value of `line`. Subsequent reads from it will return its default value. + mutating func clearLine() {self._line = nil} + + /// Legacy/deprecated; replaced by 'opaque' + var sdp: String { + get {return _sdp ?? String()} + set {_sdp = newValue} + } + /// Returns true if `sdp` has been explicitly set. + var hasSdp: Bool {return self._sdp != nil} + /// Clears the value of `sdp`. Subsequent reads from it will return its default value. + mutating func clearSdp() {self._sdp = nil} + + var opaque: Data { + get {return _opaque ?? Data()} + set {_opaque = newValue} + } + /// Returns true if `opaque` has been explicitly set. + var hasOpaque: Bool {return self._opaque != nil} + /// Clears the value of `opaque`. Subsequent reads from it will return its default value. + mutating func clearOpaque() {self._opaque = nil} + + var unknownFields = SwiftProtobuf.UnknownStorage() + + init() {} + + fileprivate var _id: UInt64? = nil + fileprivate var _mid: String? = nil + fileprivate var _line: UInt32? = nil + fileprivate var _sdp: String? = nil + fileprivate var _opaque: Data? = nil + } + + struct Busy { + // 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. + + /// @required + var id: UInt64 { + get {return _id ?? 0} + set {_id = newValue} + } + /// Returns true if `id` has been explicitly set. + var hasID: Bool {return self._id != nil} + /// Clears the value of `id`. Subsequent reads from it will return its default value. + mutating func clearID() {self._id = nil} + + var unknownFields = SwiftProtobuf.UnknownStorage() + + init() {} + + fileprivate var _id: UInt64? = nil + } + + struct Hangup { + // 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. + + /// @required + var id: UInt64 { + get {return _id ?? 0} + set {_id = newValue} + } + /// Returns true if `id` has been explicitly set. + var hasID: Bool {return self._id != nil} + /// Clears the value of `id`. Subsequent reads from it will return its default value. + mutating func clearID() {self._id = nil} + + var type: SessionProtos_CallMessage.Hangup.TypeEnum { + get {return _type ?? .hangupNormal} + set {_type = newValue} + } + /// Returns true if `type` has been explicitly set. + var hasType: Bool {return self._type != nil} + /// Clears the value of `type`. Subsequent reads from it will return its default value. + mutating func clearType() {self._type = nil} + + var deviceID: UInt32 { + get {return _deviceID ?? 0} + set {_deviceID = newValue} + } + /// Returns true if `deviceID` has been explicitly set. + var hasDeviceID: Bool {return self._deviceID != nil} + /// Clears the value of `deviceID`. Subsequent reads from it will return its default value. + mutating func clearDeviceID() {self._deviceID = nil} + + var unknownFields = SwiftProtobuf.UnknownStorage() + + enum TypeEnum: SwiftProtobuf.Enum { + typealias RawValue = Int + case hangupNormal // = 0 + case hangupAccepted // = 1 + case hangupDeclined // = 2 + case hangupBusy // = 3 + case hangupNeedPermission // = 4 + + init() { + self = .hangupNormal + } + + init?(rawValue: Int) { + switch rawValue { + case 0: self = .hangupNormal + case 1: self = .hangupAccepted + case 2: self = .hangupDeclined + case 3: self = .hangupBusy + case 4: self = .hangupNeedPermission + default: return nil + } + } + + var rawValue: Int { + switch self { + case .hangupNormal: return 0 + case .hangupAccepted: return 1 + case .hangupDeclined: return 2 + case .hangupBusy: return 3 + case .hangupNeedPermission: return 4 + } + } + + } + + init() {} + + fileprivate var _id: UInt64? = nil + fileprivate var _type: SessionProtos_CallMessage.Hangup.TypeEnum? = nil + fileprivate var _deviceID: UInt32? = nil + } + + struct Opaque { + // 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 data: Data { + get {return _data ?? Data()} + set {_data = newValue} + } + /// Returns true if `data` has been explicitly set. + var hasData: Bool {return self._data != nil} + /// Clears the value of `data`. Subsequent reads from it will return its default value. + mutating func clearData() {self._data = nil} + + var unknownFields = SwiftProtobuf.UnknownStorage() + + init() {} + + fileprivate var _data: Data? = nil + } + + init() {} + + fileprivate var _storage = _StorageClass.defaultInstance +} + +#if swift(>=4.2) + +extension SessionProtos_CallMessage.Offer.TypeEnum: CaseIterable { + // Support synthesized by the compiler. +} + +extension SessionProtos_CallMessage.Hangup.TypeEnum: CaseIterable { + // Support synthesized by the compiler. +} + +#endif // swift(>=4.2) + struct SessionProtos_KeyPair { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for @@ -1569,6 +1990,417 @@ extension SessionProtos_Content: SwiftProtobuf.Message, SwiftProtobuf._MessageIm } } +extension SessionProtos_CallMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = _protobuf_package + ".CallMessage" + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "offer"), + 2: .same(proto: "answer"), + 3: .same(proto: "iceUpdate"), + 4: .same(proto: "legacyHangup"), + 5: .same(proto: "busy"), + 6: .same(proto: "profileKey"), + 7: .same(proto: "hangup"), + 8: .same(proto: "supportsMultiRing"), + 9: .same(proto: "destinationDeviceId"), + 10: .same(proto: "opaque"), + ] + + fileprivate class _StorageClass { + var _offer: SessionProtos_CallMessage.Offer? = nil + var _answer: SessionProtos_CallMessage.Answer? = nil + var _iceUpdate: [SessionProtos_CallMessage.IceUpdate] = [] + var _legacyHangup: SessionProtos_CallMessage.Hangup? = nil + var _busy: SessionProtos_CallMessage.Busy? = nil + var _profileKey: Data? = nil + var _hangup: SessionProtos_CallMessage.Hangup? = nil + var _supportsMultiRing: Bool? = nil + var _destinationDeviceID: UInt32? = nil + var _opaque: SessionProtos_CallMessage.Opaque? = nil + + static let defaultInstance = _StorageClass() + + private init() {} + + init(copying source: _StorageClass) { + _offer = source._offer + _answer = source._answer + _iceUpdate = source._iceUpdate + _legacyHangup = source._legacyHangup + _busy = source._busy + _profileKey = source._profileKey + _hangup = source._hangup + _supportsMultiRing = source._supportsMultiRing + _destinationDeviceID = source._destinationDeviceID + _opaque = source._opaque + } + } + + 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._offer) }() + case 2: try { try decoder.decodeSingularMessageField(value: &_storage._answer) }() + case 3: try { try decoder.decodeRepeatedMessageField(value: &_storage._iceUpdate) }() + case 4: try { try decoder.decodeSingularMessageField(value: &_storage._legacyHangup) }() + case 5: try { try decoder.decodeSingularMessageField(value: &_storage._busy) }() + case 6: try { try decoder.decodeSingularBytesField(value: &_storage._profileKey) }() + case 7: try { try decoder.decodeSingularMessageField(value: &_storage._hangup) }() + case 8: try { try decoder.decodeSingularBoolField(value: &_storage._supportsMultiRing) }() + case 9: try { try decoder.decodeSingularUInt32Field(value: &_storage._destinationDeviceID) }() + case 10: try { try decoder.decodeSingularMessageField(value: &_storage._opaque) }() + default: break + } + } + } + } + + func traverse(visitor: inout V) throws { + try withExtendedLifetime(_storage) { (_storage: _StorageClass) in + if let v = _storage._offer { + try visitor.visitSingularMessageField(value: v, fieldNumber: 1) + } + if let v = _storage._answer { + try visitor.visitSingularMessageField(value: v, fieldNumber: 2) + } + if !_storage._iceUpdate.isEmpty { + try visitor.visitRepeatedMessageField(value: _storage._iceUpdate, fieldNumber: 3) + } + if let v = _storage._legacyHangup { + try visitor.visitSingularMessageField(value: v, fieldNumber: 4) + } + if let v = _storage._busy { + try visitor.visitSingularMessageField(value: v, fieldNumber: 5) + } + if let v = _storage._profileKey { + try visitor.visitSingularBytesField(value: v, fieldNumber: 6) + } + if let v = _storage._hangup { + try visitor.visitSingularMessageField(value: v, fieldNumber: 7) + } + if let v = _storage._supportsMultiRing { + try visitor.visitSingularBoolField(value: v, fieldNumber: 8) + } + if let v = _storage._destinationDeviceID { + try visitor.visitSingularUInt32Field(value: v, fieldNumber: 9) + } + if let v = _storage._opaque { + try visitor.visitSingularMessageField(value: v, fieldNumber: 10) + } + } + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: SessionProtos_CallMessage, rhs: SessionProtos_CallMessage) -> 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._offer != rhs_storage._offer {return false} + if _storage._answer != rhs_storage._answer {return false} + if _storage._iceUpdate != rhs_storage._iceUpdate {return false} + if _storage._legacyHangup != rhs_storage._legacyHangup {return false} + if _storage._busy != rhs_storage._busy {return false} + if _storage._profileKey != rhs_storage._profileKey {return false} + if _storage._hangup != rhs_storage._hangup {return false} + if _storage._supportsMultiRing != rhs_storage._supportsMultiRing {return false} + if _storage._destinationDeviceID != rhs_storage._destinationDeviceID {return false} + if _storage._opaque != rhs_storage._opaque {return false} + return true + } + if !storagesAreEqual {return false} + } + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension SessionProtos_CallMessage.Offer: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = SessionProtos_CallMessage.protoMessageName + ".Offer" + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "id"), + 2: .same(proto: "sdp"), + 3: .same(proto: "type"), + 4: .same(proto: "opaque"), + ] + + 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.decodeSingularUInt64Field(value: &self._id) }() + case 2: try { try decoder.decodeSingularStringField(value: &self._sdp) }() + case 3: try { try decoder.decodeSingularEnumField(value: &self._type) }() + case 4: try { try decoder.decodeSingularBytesField(value: &self._opaque) }() + default: break + } + } + } + + func traverse(visitor: inout V) throws { + if let v = self._id { + try visitor.visitSingularUInt64Field(value: v, fieldNumber: 1) + } + if let v = self._sdp { + try visitor.visitSingularStringField(value: v, fieldNumber: 2) + } + if let v = self._type { + try visitor.visitSingularEnumField(value: v, fieldNumber: 3) + } + if let v = self._opaque { + try visitor.visitSingularBytesField(value: v, fieldNumber: 4) + } + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: SessionProtos_CallMessage.Offer, rhs: SessionProtos_CallMessage.Offer) -> Bool { + if lhs._id != rhs._id {return false} + if lhs._sdp != rhs._sdp {return false} + if lhs._type != rhs._type {return false} + if lhs._opaque != rhs._opaque {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension SessionProtos_CallMessage.Offer.TypeEnum: SwiftProtobuf._ProtoNameProviding { + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 0: .same(proto: "OFFER_AUDIO_CALL"), + 1: .same(proto: "OFFER_VIDEO_CALL"), + ] +} + +extension SessionProtos_CallMessage.Answer: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = SessionProtos_CallMessage.protoMessageName + ".Answer" + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "id"), + 2: .same(proto: "sdp"), + 3: .same(proto: "opaque"), + ] + + 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.decodeSingularUInt64Field(value: &self._id) }() + case 2: try { try decoder.decodeSingularStringField(value: &self._sdp) }() + case 3: try { try decoder.decodeSingularBytesField(value: &self._opaque) }() + default: break + } + } + } + + func traverse(visitor: inout V) throws { + if let v = self._id { + try visitor.visitSingularUInt64Field(value: v, fieldNumber: 1) + } + if let v = self._sdp { + try visitor.visitSingularStringField(value: v, fieldNumber: 2) + } + if let v = self._opaque { + try visitor.visitSingularBytesField(value: v, fieldNumber: 3) + } + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: SessionProtos_CallMessage.Answer, rhs: SessionProtos_CallMessage.Answer) -> Bool { + if lhs._id != rhs._id {return false} + if lhs._sdp != rhs._sdp {return false} + if lhs._opaque != rhs._opaque {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension SessionProtos_CallMessage.IceUpdate: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = SessionProtos_CallMessage.protoMessageName + ".IceUpdate" + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "id"), + 2: .same(proto: "mid"), + 3: .same(proto: "line"), + 4: .same(proto: "sdp"), + 5: .same(proto: "opaque"), + ] + + 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.decodeSingularUInt64Field(value: &self._id) }() + case 2: try { try decoder.decodeSingularStringField(value: &self._mid) }() + case 3: try { try decoder.decodeSingularUInt32Field(value: &self._line) }() + case 4: try { try decoder.decodeSingularStringField(value: &self._sdp) }() + case 5: try { try decoder.decodeSingularBytesField(value: &self._opaque) }() + default: break + } + } + } + + func traverse(visitor: inout V) throws { + if let v = self._id { + try visitor.visitSingularUInt64Field(value: v, fieldNumber: 1) + } + if let v = self._mid { + try visitor.visitSingularStringField(value: v, fieldNumber: 2) + } + if let v = self._line { + try visitor.visitSingularUInt32Field(value: v, fieldNumber: 3) + } + if let v = self._sdp { + try visitor.visitSingularStringField(value: v, fieldNumber: 4) + } + if let v = self._opaque { + try visitor.visitSingularBytesField(value: v, fieldNumber: 5) + } + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: SessionProtos_CallMessage.IceUpdate, rhs: SessionProtos_CallMessage.IceUpdate) -> Bool { + if lhs._id != rhs._id {return false} + if lhs._mid != rhs._mid {return false} + if lhs._line != rhs._line {return false} + if lhs._sdp != rhs._sdp {return false} + if lhs._opaque != rhs._opaque {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension SessionProtos_CallMessage.Busy: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = SessionProtos_CallMessage.protoMessageName + ".Busy" + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "id"), + ] + + 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.decodeSingularUInt64Field(value: &self._id) }() + default: break + } + } + } + + func traverse(visitor: inout V) throws { + if let v = self._id { + try visitor.visitSingularUInt64Field(value: v, fieldNumber: 1) + } + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: SessionProtos_CallMessage.Busy, rhs: SessionProtos_CallMessage.Busy) -> Bool { + if lhs._id != rhs._id {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension SessionProtos_CallMessage.Hangup: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = SessionProtos_CallMessage.protoMessageName + ".Hangup" + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "id"), + 2: .same(proto: "type"), + 3: .same(proto: "deviceId"), + ] + + 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.decodeSingularUInt64Field(value: &self._id) }() + case 2: try { try decoder.decodeSingularEnumField(value: &self._type) }() + case 3: try { try decoder.decodeSingularUInt32Field(value: &self._deviceID) }() + default: break + } + } + } + + func traverse(visitor: inout V) throws { + if let v = self._id { + try visitor.visitSingularUInt64Field(value: v, fieldNumber: 1) + } + if let v = self._type { + try visitor.visitSingularEnumField(value: v, fieldNumber: 2) + } + if let v = self._deviceID { + try visitor.visitSingularUInt32Field(value: v, fieldNumber: 3) + } + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: SessionProtos_CallMessage.Hangup, rhs: SessionProtos_CallMessage.Hangup) -> Bool { + if lhs._id != rhs._id {return false} + if lhs._type != rhs._type {return false} + if lhs._deviceID != rhs._deviceID {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension SessionProtos_CallMessage.Hangup.TypeEnum: SwiftProtobuf._ProtoNameProviding { + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 0: .same(proto: "HANGUP_NORMAL"), + 1: .same(proto: "HANGUP_ACCEPTED"), + 2: .same(proto: "HANGUP_DECLINED"), + 3: .same(proto: "HANGUP_BUSY"), + 4: .same(proto: "HANGUP_NEED_PERMISSION"), + ] +} + +extension SessionProtos_CallMessage.Opaque: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = SessionProtos_CallMessage.protoMessageName + ".Opaque" + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "data"), + ] + + 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.decodeSingularBytesField(value: &self._data) }() + default: break + } + } + } + + func traverse(visitor: inout V) throws { + if let v = self._data { + try visitor.visitSingularBytesField(value: v, fieldNumber: 1) + } + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: SessionProtos_CallMessage.Opaque, rhs: SessionProtos_CallMessage.Opaque) -> Bool { + if lhs._data != rhs._data {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + extension SessionProtos_KeyPair: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { static let protoMessageName: String = _protobuf_package + ".KeyPair" static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ diff --git a/SessionMessagingKit/Protos/SessionProtos.proto b/SessionMessagingKit/Protos/SessionProtos.proto index 7d9d5f56e..0b947c959 100644 --- a/SessionMessagingKit/Protos/SessionProtos.proto +++ b/SessionMessagingKit/Protos/SessionProtos.proto @@ -42,6 +42,83 @@ message Content { optional DataExtractionNotification dataExtractionNotification = 8; } +message CallMessage { + + message Offer { + + enum Type { + OFFER_AUDIO_CALL = 0; + OFFER_VIDEO_CALL = 1; + // next index 3, skip 2 – it was the unused "NEED_PERMISSION" type + } + + // @required + optional uint64 id = 1; + // Legacy/deprecated; replaced by 'opaque' + optional string sdp = 2; + optional Type type = 3; + optional bytes opaque = 4; + } + + message Answer { + // @required + optional uint64 id = 1; + // Legacy/deprecated; replaced by 'opaque' + optional string sdp = 2; + optional bytes opaque = 3; + } + + message IceUpdate { + // @required + optional uint64 id = 1; + // Legacy/deprecated; remove when old clients are gone. + optional string mid = 2; + // Legacy/deprecated; remove when old clients are gone. + optional uint32 line = 3; + // Legacy/deprecated; replaced by 'opaque' + optional string sdp = 4; + optional bytes opaque = 5; + } + + message Busy { + // @required + optional uint64 id = 1; + } + + message Hangup { + + enum Type { + HANGUP_NORMAL = 0; + HANGUP_ACCEPTED = 1; + HANGUP_DECLINED = 2; + HANGUP_BUSY = 3; + HANGUP_NEED_PERMISSION = 4; + } + + // @required + optional uint64 id = 1; + optional Type type = 2; + optional uint32 deviceId = 3; + } + + message Opaque { + optional bytes data = 1; + } + + optional Offer offer = 1; + optional Answer answer = 2; + repeated IceUpdate iceUpdate = 3; + optional Hangup legacyHangup = 4; + optional Busy busy = 5; + // Signal-iOS sends profile key with call messages + // for earlier discovery. + optional bytes profileKey = 6; + optional Hangup hangup = 7; + optional bool supportsMultiRing = 8; + optional uint32 destinationDeviceId = 9; + optional Opaque opaque = 10; +} + message KeyPair { // @required required bytes publicKey = 1; diff --git a/SessionMessagingKit/Threads/TSContactThread.m b/SessionMessagingKit/Threads/TSContactThread.m index 1024389f7..e2b913a3e 100644 --- a/SessionMessagingKit/Threads/TSContactThread.m +++ b/SessionMessagingKit/Threads/TSContactThread.m @@ -36,9 +36,14 @@ NSString *const TSContactThreadPrefix = @"c"; + (instancetype)getOrCreateThreadWithContactSessionID:(NSString *)contactSessionID { __block TSContactThread *thread; - [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { - thread = [self getOrCreateThreadWithContactSessionID:contactSessionID transaction:transaction]; + [LKStorage readWithBlock:^(YapDatabaseReadTransaction *transaction) { + thread = [self getThreadWithContactSessionID:contactSessionID transaction:transaction]; }]; + if (thread == nil) { + [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + thread = [self getOrCreateThreadWithContactSessionID:contactSessionID transaction:transaction]; + }]; + } return thread; } diff --git a/SessionUtilitiesKit/General/Weak.swift b/SessionUtilitiesKit/General/Weak.swift index fbcca5906..e0e3d7dec 100644 --- a/SessionUtilitiesKit/General/Weak.swift +++ b/SessionUtilitiesKit/General/Weak.swift @@ -26,3 +26,42 @@ public struct Weak { self.value = value } } + +public struct WeakArray { + private var array: [Weak] = [] + + public var elements: [Element] { + array.compactMap { $0.value } + } + + public var weakReferenceCount: Int { + array.count + } + + public mutating func append(_ element: Element) { + array = array.filter { $0.value != nil } + [Weak(value: element)] + } + + public mutating func removeAll(where shouldDelete: (Element) throws -> Bool) rethrows { + try array.removeAll { weakBox in + guard let element = weakBox.value else { return true } + return try shouldDelete(element) + } + } + + public mutating func cullExpired() { + array.removeAll { weakBox in + weakBox.value == nil + } + } +} + +extension WeakArray: ExpressibleByArrayLiteral { + public typealias ArrayLiteralElement = Element + public init(arrayLiteral elements: Element...) { + self.init() + for element in elements { + self.append(element) + } + } +}