Implement IndividualCallMessage.toProto(using:)

This commit is contained in:
Niels Andriesse 2021-08-02 11:04:03 +10:00
parent 5ca7b08cf6
commit f529a5a46c
2 changed files with 98 additions and 7 deletions

View File

@ -89,7 +89,7 @@ public final class ClosedGroupControlMessage : ControlMessage {
public override var isValid: Bool { public override var isValid: Bool {
guard super.isValid, let kind = kind else { return false } guard super.isValid, let kind = kind else { return false }
switch kind { switch kind {
case .new(let publicKey, let name, let encryptionKeyPair, let members, let admins, let expirationTimer): case .new(let publicKey, let name, let encryptionKeyPair, let members, let admins, _):
return !publicKey.isEmpty && !name.isEmpty && !encryptionKeyPair.publicKey.isEmpty return !publicKey.isEmpty && !name.isEmpty && !encryptionKeyPair.publicKey.isEmpty
&& !encryptionKeyPair.privateKey.isEmpty && !members.isEmpty && !admins.isEmpty && !encryptionKeyPair.privateKey.isEmpty && !members.isEmpty && !admins.isEmpty
case .encryptionKeyPair: return true case .encryptionKeyPair: return true

View File

@ -79,32 +79,98 @@ public final class IndividualCallMessage : ControlMessage {
guard let callMessage = proto.callMessage else { return nil } guard let callMessage = proto.callMessage else { return nil }
let callID: UInt64 let callID: UInt64
let kind: Kind let kind: Kind
// Offer
if let offer = callMessage.offer { if let offer = callMessage.offer {
guard let opaque = offer.opaque else { return nil } guard let opaque = offer.opaque else { return nil }
callID = offer.id callID = offer.id
let callType = CallType.from(offer.type) let callType = CallType.from(offer.type)
kind = .offer(opaque: opaque, callType: callType) kind = .offer(opaque: opaque, callType: callType)
} else if let answer = callMessage.answer { }
// Answer
else if let answer = callMessage.answer {
guard let opaque = answer.opaque else { return nil } guard let opaque = answer.opaque else { return nil }
callID = answer.id callID = answer.id
kind = .answer(opaque: opaque) kind = .answer(opaque: opaque)
} else if !callMessage.iceUpdate.isEmpty { }
// ICE Update
else if !callMessage.iceUpdate.isEmpty {
callID = callMessage.iceUpdate.first!.id // TODO: Is this how it's supposed to work? 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` kind = .iceUpdate(candidates: callMessage.iceUpdate.compactMap { $0.opaque }) // Should never contain entries with a `nil` `opaque`
} else if let hangup = callMessage.hangup { }
// Hangup
else if let hangup = callMessage.hangup {
callID = hangup.id callID = hangup.id
let type = HangupType.from(hangup.type) let type = HangupType.from(hangup.type)
kind = .hangup(type: type) kind = .hangup(type: type)
} else if let busy = callMessage.busy { }
// Busy
else if let busy = callMessage.busy {
callID = busy.id callID = busy.id
kind = .busy kind = .busy
} else { }
// Unknown
else {
return nil return nil
} }
return IndividualCallMessage(callID: callID, kind: kind) return IndividualCallMessage(callID: callID, kind: kind)
} }
public override func toProto(using transaction: YapDatabaseReadWriteTransaction) -> SNProtoContent? { public override func toProto(using transaction: YapDatabaseReadWriteTransaction) -> SNProtoContent? {
guard let callID = callID, let kind = kind else {
SNLog("Couldn't construct individual call message proto from: \(self).")
return nil
}
let callMessageProto = SNProtoCallMessage.builder()
switch kind {
case let .offer(opaque, callType):
let offerMessageProto = SNProtoCallMessageOffer.builder(id: callID)
offerMessageProto.setOpaque(opaque)
offerMessageProto.setType(SNProtoCallMessageOffer.SNProtoCallMessageOfferType.from(callType))
do {
callMessageProto.setOffer(try offerMessageProto.build())
} catch {
SNLog("Couldn't construct offer message proto from: \(self).")
return nil
}
case let .answer(opaque):
let answerMessageProto = SNProtoCallMessageAnswer.builder(id: callID)
answerMessageProto.setOpaque(opaque)
do {
callMessageProto.setAnswer(try answerMessageProto.build())
} catch {
SNLog("Couldn't construct answer message proto from: \(self).")
return nil
}
case let .iceUpdate(candidates):
let iceUpdateMessageProtos = candidates.map { candidate -> SNProtoCallMessageIceUpdate.SNProtoCallMessageIceUpdateBuilder in
let iceUpdateMessageProto = SNProtoCallMessageIceUpdate.builder(id: callID)
iceUpdateMessageProto.setOpaque(candidate)
return iceUpdateMessageProto
}
do {
callMessageProto.setIceUpdate(try iceUpdateMessageProtos.map { try $0.build() })
} catch {
SNLog("Couldn't construct ICE update message proto from: \(self).")
return nil
}
case let .hangup(type):
let hangupMessageProto = SNProtoCallMessageHangup.builder(id: callID)
hangupMessageProto.setType(SNProtoCallMessageHangup.SNProtoCallMessageHangupType.from(type))
do {
callMessageProto.setHangup(try hangupMessageProto.build())
} catch {
SNLog("Couldn't construct hangup message proto from: \(self).")
return nil
}
case .busy:
let busyMessageProto = SNProtoCallMessageBusy.builder(id: callID)
do {
callMessageProto.setBusy(try busyMessageProto.build())
} catch {
SNLog("Couldn't construct busy message proto from: \(self).")
return nil
}
}
return nil return nil
} }
@ -112,8 +178,33 @@ public final class IndividualCallMessage : ControlMessage {
public override var description: String { public override var description: String {
""" """
IndividualCallMessage( IndividualCallMessage(
callID: \(callID?.description ?? "null"),
kind: \(kind?.description ?? "null")
) )
""" """
} }
} }
// MARK: Convenience
extension SNProtoCallMessageOffer.SNProtoCallMessageOfferType {
fileprivate static func from(_ callType: IndividualCallMessage.CallType) -> SNProtoCallMessageOffer.SNProtoCallMessageOfferType {
switch callType {
case .audio: return .offerAudioCall
case .video: return .offerVideoCall
}
}
}
extension SNProtoCallMessageHangup.SNProtoCallMessageHangupType {
fileprivate static func from(_ hangupType: IndividualCallMessage.HangupType) -> SNProtoCallMessageHangup.SNProtoCallMessageHangupType {
switch hangupType {
case .normal: return .hangupNormal
case .accepted: return .hangupAccepted
case .declined: return .hangupDeclined
case .busy: return .hangupBusy
case .needPermission: return .hangupNeedPermission
}
}
}