session-ios/SessionMessagingKit/Messages/Control Messages/IndividualCallMessage.swift

120 lines
4.0 KiB
Swift

import SessionUtilitiesKit
public final class IndividualCallMessage : ControlMessage {
public var callID: UInt64?
public var kind: Kind?
// MARK: Call Type
public enum CallType : String {
case audio, video
fileprivate static func from(_ proto: SNProtoCallMessageOffer.SNProtoCallMessageOfferType) -> CallType {
switch proto {
case .offerAudioCall: return .audio
case .offerVideoCall: return .video
}
}
}
// MARK: Hangup Type
public enum HangupType : String {
case normal, accepted, declined, busy, needPermission
fileprivate static func from(_ proto: SNProtoCallMessageHangup.SNProtoCallMessageHangupType) -> HangupType {
switch proto {
case .hangupNormal: return .normal
case .hangupAccepted: return .accepted
case .hangupDeclined: return .declined
case .hangupBusy: return .busy
case .hangupNeedPermission: return .needPermission
}
}
}
// MARK: Kind
public enum Kind : CustomStringConvertible {
case offer(opaque: Data, callType: CallType)
case answer(opaque: Data)
case iceUpdate(candidates: [Data])
case hangup(type: HangupType)
case busy
public var description: String {
switch self {
case .offer(let opaque, let callType): return "offer(opaque: \(opaque.count) bytes, callType: \(callType.rawValue))"
case .answer(let opaque): return "answer(opaque: \(opaque.count) bytes)"
case .iceUpdate(let candidates): return "iceUpdate(candidates: \(candidates.count) candidates)"
case .hangup(let type): return "hangup(type: \(type.rawValue)"
case .busy: return "busy"
}
}
}
// MARK: Initialization
public override init() { super.init() }
internal init(callID: UInt64, kind: Kind) {
super.init()
self.callID = callID
self.kind = kind
}
// MARK: Validation
public override var isValid: Bool {
guard super.isValid else { return false }
return true
}
// MARK: Coding
public required init?(coder: NSCoder) {
super.init(coder: coder)
}
public override func encode(with coder: NSCoder) {
super.encode(with: coder)
}
// MARK: Proto Conversion
public override class func fromProto(_ proto: SNProtoContent) -> IndividualCallMessage? {
guard let callMessage = proto.callMessage else { return nil }
let callID: UInt64
let kind: Kind
if let offer = callMessage.offer {
guard let opaque = offer.opaque else { return nil }
callID = offer.id
let callType = CallType.from(offer.type)
kind = .offer(opaque: opaque, callType: callType)
} else if let answer = callMessage.answer {
guard let opaque = answer.opaque else { return nil }
callID = answer.id
kind = .answer(opaque: opaque)
} else if !callMessage.iceUpdate.isEmpty {
callID = callMessage.iceUpdate.first!.id // TODO: Is this how it's supposed to work?
kind = .iceUpdate(candidates: callMessage.iceUpdate.compactMap { $0.opaque }) // Should never contain entries with a `nil` `opaque`
} else if let hangup = callMessage.hangup {
callID = hangup.id
let type = HangupType.from(hangup.type)
kind = .hangup(type: type)
} else if let busy = callMessage.busy {
callID = busy.id
kind = .busy
} else {
return nil
}
return IndividualCallMessage(callID: callID, kind: kind)
}
public override func toProto(using transaction: YapDatabaseReadWriteTransaction) -> SNProtoContent? {
return nil
}
// MARK: Description
public override var description: String {
"""
IndividualCallMessage(
)
"""
}
}