VoIPCallOfferMessage.swift 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. // _____ _
  2. // |_ _| |_ _ _ ___ ___ _ __ __ _
  3. // | | | ' \| '_/ -_) -_) ' \/ _` |_
  4. // |_| |_||_|_| \___\___|_|_|_\__,_(_)
  5. //
  6. // Threema iOS Client
  7. // Copyright (c) 2019-2020 Threema GmbH
  8. //
  9. // This program is free software: you can redistribute it and/or modify
  10. // it under the terms of the GNU Affero General Public License, version 3,
  11. // as published by the Free Software Foundation.
  12. //
  13. // This program is distributed in the hope that it will be useful,
  14. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. // GNU Affero General Public License for more details.
  17. //
  18. // You should have received a copy of the GNU Affero General Public License
  19. // along with this program. If not, see <https://www.gnu.org/licenses/>.
  20. import Foundation
  21. @objc class VoIPCallOfferMessage: NSObject {
  22. @objc var offer: RTCSessionDescription?
  23. @objc var contact: Contact?
  24. @objc var completion: (() -> Void)?
  25. var callId: VoIPCallId
  26. var features: [String: Any?]?
  27. var isVideoAvailable: Bool
  28. @objc override init() {
  29. offer = nil
  30. contact = nil
  31. completion = nil
  32. features = nil
  33. isVideoAvailable = false
  34. callId = VoIPCallId.init(callId: 0)
  35. super.init()
  36. }
  37. init(offer: RTCSessionDescription?, contact: Contact?, features:[String: Any?]?, isVideoAvailable: Bool, callId: VoIPCallId, completion: (() -> Void)?) {
  38. self.offer = offer
  39. self.contact = contact
  40. self.completion = completion
  41. self.features = features
  42. self.isVideoAvailable = isVideoAvailable
  43. self.callId = callId
  44. super.init()
  45. }
  46. }
  47. extension VoIPCallOfferMessage {
  48. static let kOfferKey = "offer"
  49. static let kRTCSessionDescriptionTypeKey = "sdpType"
  50. static let kRTCSessionDescriptionSdpKey = "sdp"
  51. static let kFeaturesKey = "features"
  52. static let kFeaturesVideoKey = "video"
  53. static let kCallId = "callId"
  54. enum VoIPCallOfferMessageError: Error {
  55. case generateJson(error: Error)
  56. }
  57. @objc class func offerFromJSONDictionary(_ dictionary: [AnyHashable: Any]) -> VoIPCallOfferMessage {
  58. var tmpOffer: RTCSessionDescription? = nil
  59. if let offerKey = dictionary[VoIPCallOfferMessage.kOfferKey] {
  60. tmpOffer = RTCSessionDescription.description(from: offerKey as! [AnyHashable : Any])
  61. }
  62. var tmpFeatures: [String: Any?]?
  63. var isVideoAvailable: Bool = false
  64. if let features = dictionary[kFeaturesKey] as? [String: Any?] {
  65. tmpFeatures = features
  66. if features.keys.contains(kFeaturesVideoKey) {
  67. isVideoAvailable = true
  68. }
  69. }
  70. let tmpCallId = VoIPCallId(callId: dictionary[kCallId] as? UInt32)
  71. return VoIPCallOfferMessage.init(offer: tmpOffer, contact: nil, features: tmpFeatures, isVideoAvailable: isVideoAvailable, callId: tmpCallId, completion: nil)
  72. }
  73. private func stringForType() -> String {
  74. if offer != nil {
  75. switch offer!.type {
  76. case .offer:
  77. return "offer"
  78. case .prAnswer:
  79. return "pranswer"
  80. case .answer:
  81. return "answer"
  82. default:
  83. return ""
  84. }
  85. }
  86. return ""
  87. }
  88. func jsonData() throws -> Data {
  89. var json = [AnyHashable: Any]()
  90. if offer != nil {
  91. json = [VoIPCallOfferMessage.kCallId: callId.callId, VoIPCallOfferMessage.kOfferKey: [VoIPCallOfferMessage.kRTCSessionDescriptionTypeKey: stringForType(), VoIPCallOfferMessage.kRTCSessionDescriptionSdpKey: offer?.sdp]]
  92. if isVideoAvailable {
  93. json[VoIPCallOfferMessage.kFeaturesKey] = [VoIPCallOfferMessage.kFeaturesVideoKey: nil]
  94. }
  95. }
  96. do {
  97. return try JSONSerialization.data(withJSONObject: json, options: .prettyPrinted)
  98. }
  99. catch let error {
  100. throw VoIPCallOfferMessageError.generateJson(error: error)
  101. }
  102. }
  103. }