diff --git a/submodules/TelegramApi/Sources/Api0.swift b/submodules/TelegramApi/Sources/Api0.swift index 7a8a00edae..1b6023dad1 100644 --- a/submodules/TelegramApi/Sources/Api0.swift +++ b/submodules/TelegramApi/Sources/Api0.swift @@ -557,7 +557,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = { dict[1471006352] = { return Api.PhoneCallDiscardReason.parse_phoneCallDiscardReasonHangup($0) } dict[-2048646399] = { return Api.PhoneCallDiscardReason.parse_phoneCallDiscardReasonMissed($0) } dict[-58224696] = { return Api.PhoneCallProtocol.parse_phoneCallProtocol($0) } - dict[-1655957568] = { return Api.PhoneConnection.parse_phoneConnection($0) } + dict[-1665063993] = { return Api.PhoneConnection.parse_phoneConnection($0) } dict[1667228533] = { return Api.PhoneConnection.parse_phoneConnectionWebrtc($0) } dict[-82216347] = { return Api.Photo.parse_photo($0) } dict[590459437] = { return Api.Photo.parse_photoEmpty($0) } diff --git a/submodules/TelegramApi/Sources/Api14.swift b/submodules/TelegramApi/Sources/Api14.swift index 04b280b2d9..d25de327ff 100644 --- a/submodules/TelegramApi/Sources/Api14.swift +++ b/submodules/TelegramApi/Sources/Api14.swift @@ -1130,15 +1130,16 @@ public extension Api { } public extension Api { enum PhoneConnection: TypeConstructorDescription { - case phoneConnection(id: Int64, ip: String, ipv6: String, port: Int32, peerTag: Buffer) + case phoneConnection(flags: Int32, id: Int64, ip: String, ipv6: String, port: Int32, peerTag: Buffer) case phoneConnectionWebrtc(flags: Int32, id: Int64, ip: String, ipv6: String, port: Int32, username: String, password: String) public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { switch self { - case .phoneConnection(let id, let ip, let ipv6, let port, let peerTag): + case .phoneConnection(let flags, let id, let ip, let ipv6, let port, let peerTag): if boxed { - buffer.appendInt32(-1655957568) + buffer.appendInt32(-1665063993) } + serializeInt32(flags, buffer: buffer, boxed: false) serializeInt64(id, buffer: buffer, boxed: false) serializeString(ip, buffer: buffer, boxed: false) serializeString(ipv6, buffer: buffer, boxed: false) @@ -1162,31 +1163,34 @@ public extension Api { public func descriptionFields() -> (String, [(String, Any)]) { switch self { - case .phoneConnection(let id, let ip, let ipv6, let port, let peerTag): - return ("phoneConnection", [("id", String(describing: id)), ("ip", String(describing: ip)), ("ipv6", String(describing: ipv6)), ("port", String(describing: port)), ("peerTag", String(describing: peerTag))]) + case .phoneConnection(let flags, let id, let ip, let ipv6, let port, let peerTag): + return ("phoneConnection", [("flags", String(describing: flags)), ("id", String(describing: id)), ("ip", String(describing: ip)), ("ipv6", String(describing: ipv6)), ("port", String(describing: port)), ("peerTag", String(describing: peerTag))]) case .phoneConnectionWebrtc(let flags, let id, let ip, let ipv6, let port, let username, let password): return ("phoneConnectionWebrtc", [("flags", String(describing: flags)), ("id", String(describing: id)), ("ip", String(describing: ip)), ("ipv6", String(describing: ipv6)), ("port", String(describing: port)), ("username", String(describing: username)), ("password", String(describing: password))]) } } public static func parse_phoneConnection(_ reader: BufferReader) -> PhoneConnection? { - var _1: Int64? - _1 = reader.readInt64() - var _2: String? - _2 = parseString(reader) + var _1: Int32? + _1 = reader.readInt32() + var _2: Int64? + _2 = reader.readInt64() var _3: String? _3 = parseString(reader) - var _4: Int32? - _4 = reader.readInt32() - var _5: Buffer? - _5 = parseBytes(reader) + var _4: String? + _4 = parseString(reader) + var _5: Int32? + _5 = reader.readInt32() + var _6: Buffer? + _6 = parseBytes(reader) let _c1 = _1 != nil let _c2 = _2 != nil let _c3 = _3 != nil let _c4 = _4 != nil let _c5 = _5 != nil - if _c1 && _c2 && _c3 && _c4 && _c5 { - return Api.PhoneConnection.phoneConnection(id: _1!, ip: _2!, ipv6: _3!, port: _4!, peerTag: _5!) + let _c6 = _6 != nil + if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 { + return Api.PhoneConnection.phoneConnection(flags: _1!, id: _2!, ip: _3!, ipv6: _4!, port: _5!, peerTag: _6!) } else { return nil diff --git a/submodules/TelegramCore/Sources/State/CallSessionManager.swift b/submodules/TelegramCore/Sources/State/CallSessionManager.swift index ed29ae4bbe..f7a4524c28 100644 --- a/submodules/TelegramCore/Sources/State/CallSessionManager.swift +++ b/submodules/TelegramCore/Sources/State/CallSessionManager.swift @@ -217,6 +217,7 @@ public enum CallSessionConnection: Equatable { public let id: Int64 public let ip: String public let ipv6: String + public let isTcp: Bool public let port: Int32 public let peerTag: Data @@ -224,12 +225,14 @@ public enum CallSessionConnection: Equatable { id: Int64, ip: String, ipv6: String, + isTcp: Bool, port: Int32, peerTag: Data ) { self.id = id self.ip = ip self.ipv6 = ipv6 + self.isTcp = isTcp self.port = port self.peerTag = peerTag } @@ -272,8 +275,9 @@ public enum CallSessionConnection: Equatable { private func parseConnection(_ apiConnection: Api.PhoneConnection) -> CallSessionConnection { switch apiConnection { - case let .phoneConnection(id, ip, ipv6, port, peerTag): - return .reflector(CallSessionConnection.Reflector(id: id, ip: ip, ipv6: ipv6, port: port, peerTag: peerTag.makeData())) + case let .phoneConnection(flags, id, ip, ipv6, port, peerTag): + let isTcp = (flags & (1 << 0)) != 0 + return .reflector(CallSessionConnection.Reflector(id: id, ip: ip, ipv6: ipv6, isTcp: isTcp, port: port, peerTag: peerTag.makeData())) case let .phoneConnectionWebrtc(flags, id, ip, ipv6, port, username, password): return .webRtcReflector(CallSessionConnection.WebRtcReflector( id: id, diff --git a/submodules/TelegramVoip/Sources/OngoingCallContext.swift b/submodules/TelegramVoip/Sources/OngoingCallContext.swift index 67bf0508e3..ccc44a0f91 100644 --- a/submodules/TelegramVoip/Sources/OngoingCallContext.swift +++ b/submodules/TelegramVoip/Sources/OngoingCallContext.swift @@ -9,7 +9,7 @@ import TgVoip import TgVoipWebrtc private let debugUseLegacyVersionForReflectors: Bool = { - #if DEBUG + #if DEBUG && false return true #else return false @@ -81,10 +81,10 @@ private func callConnectionDescriptionsWebrtc(_ connection: CallSessionConnectio } var result: [OngoingCallConnectionDescriptionWebrtc] = [] if !reflector.ip.isEmpty { - result.append(OngoingCallConnectionDescriptionWebrtc(reflectorId: id, hasStun: false, hasTurn: true, hasTcp: false, ip: reflector.ip, port: reflector.port, username: "reflector", password: hexString(reflector.peerTag))) + result.append(OngoingCallConnectionDescriptionWebrtc(reflectorId: id, hasStun: false, hasTurn: true, hasTcp: reflector.isTcp, ip: reflector.ip, port: reflector.port, username: "reflector", password: hexString(reflector.peerTag))) } if !reflector.ipv6.isEmpty { - result.append(OngoingCallConnectionDescriptionWebrtc(reflectorId: id, hasStun: false, hasTurn: true, hasTcp: false, ip: reflector.ipv6, port: reflector.port, username: "reflector", password: hexString(reflector.peerTag))) + result.append(OngoingCallConnectionDescriptionWebrtc(reflectorId: id, hasStun: false, hasTurn: true, hasTcp: reflector.isTcp, ip: reflector.ipv6, port: reflector.port, username: "reflector", password: hexString(reflector.peerTag))) } return result case let .webRtcReflector(reflector): @@ -743,6 +743,12 @@ public final class OngoingCallContext { private var signalingConnectionManager: QueueLocalObject? public static func versions(includeExperimental: Bool, includeReference: Bool) -> [(version: String, supportsVideo: Bool)] { + #if DEBUG + if "".isEmpty { + return [("5.0.0", true)] + } + #endif + if debugUseLegacyVersionForReflectors { return [(OngoingCallThreadLocalContext.version(), true)] } else { @@ -784,7 +790,7 @@ public final class OngoingCallContext { var allowP2P = allowP2P if debugUseLegacyVersionForReflectors { useModernImplementation = true - version = "10.0.0" + version = "5.0.0" allowP2P = false } else { useModernImplementation = version != OngoingCallThreadLocalContext.version() @@ -820,35 +826,53 @@ public final class OngoingCallContext { reflectorIdMapping[reflectorIdList[i]] = UInt8(i + 1) } + var signalingReflector: OngoingCallConnectionDescriptionWebrtc? + var processedConnections: [CallSessionConnection] = [] var filteredConnections: [OngoingCallConnectionDescriptionWebrtc] = [] - for connection in unfilteredConnections { + connectionsLoop: for connection in unfilteredConnections { if processedConnections.contains(connection) { continue } processedConnections.append(connection) - filteredConnections.append(contentsOf: callConnectionDescriptionsWebrtc(connection, idMapping: reflectorIdMapping)) + + switch connection { + case let .reflector(reflector): + if reflector.isTcp { + if signalingReflector == nil { + signalingReflector = OngoingCallConnectionDescriptionWebrtc(reflectorId: 0, hasStun: false, hasTurn: true, hasTcp: true, ip: reflector.ip, port: reflector.port, username: "reflector", password: hexString(reflector.peerTag)) + } + + continue connectionsLoop + } + case .webRtcReflector: + break + } + + var webrtcConnections: [OngoingCallConnectionDescriptionWebrtc] = [] + for connection in callConnectionDescriptionsWebrtc(connection, idMapping: reflectorIdMapping) { + webrtcConnections.append(connection) + } + + filteredConnections.append(contentsOf: webrtcConnections) } - for connection in filteredConnections { - if connection.username == "reflector" { - let peerTag = dataWithHexString(connection.password) - if #available(iOS 12.0, *) { - strongSelf.signalingConnectionManager = QueueLocalObject(queue: queue, generate: { - return CallSignalingConnectionManager(queue: queue, peerTag: peerTag, servers: [OngoingCallConnectionDescriptionWebrtc(reflectorId: 0, hasStun: false, hasTurn: true, hasTcp: true, ip: "91.108.12.1", port: 533, username: "reflector", password: connection.password)], dataReceived: { data in - guard let strongSelf = self else { - return - } - strongSelf.withContext { context in - if let context = context as? OngoingCallThreadLocalContextWebrtc { - context.addSignaling(data) - } - } - }) - }) - } + if let signalingReflector = signalingReflector { + if #available(iOS 12.0, *) { + let peerTag = dataWithHexString(signalingReflector.password) - break + strongSelf.signalingConnectionManager = QueueLocalObject(queue: queue, generate: { + return CallSignalingConnectionManager(queue: queue, peerTag: peerTag, servers: [signalingReflector], dataReceived: { data in + guard let strongSelf = self else { + return + } + strongSelf.withContext { context in + if let context = context as? OngoingCallThreadLocalContextWebrtc { + context.addSignaling(data) + } + } + }) + }) } } diff --git a/submodules/TgVoipWebrtc/tgcalls b/submodules/TgVoipWebrtc/tgcalls index f3c148739b..c741da4568 160000 --- a/submodules/TgVoipWebrtc/tgcalls +++ b/submodules/TgVoipWebrtc/tgcalls @@ -1 +1 @@ -Subproject commit f3c148739bf0ad37a0882a7fcafcbc56969c4f8a +Subproject commit c741da4568b0971ed06d9ccdc7a94db566bb84a0