From 92a6a73f6f99db58a313e42be563b8b4acdd473f Mon Sep 17 00:00:00 2001 From: Isaac <> Date: Tue, 25 Feb 2025 14:43:41 +0000 Subject: [PATCH] Call updates --- .gitmodules | 3 - submodules/TelegramVoip/BUILD | 1 - .../Sources/OngoingCallContext.swift | 666 +++++++----------- submodules/TgVoip/BUILD | 82 --- .../TgVoip/OngoingCallThreadLocalContext.h | 81 --- .../Sources/OngoingCallThreadLocalContext.mm | 419 ----------- submodules/TgVoip/libtgvoip | 1 - .../OngoingCallThreadLocalContext.h | 30 + .../Sources/OngoingCallThreadLocalContext.mm | 35 +- submodules/TgVoipWebrtc/tgcalls | 2 +- third-party/webrtc/webrtc | 2 +- 11 files changed, 306 insertions(+), 1016 deletions(-) delete mode 100644 submodules/TgVoip/BUILD delete mode 100644 submodules/TgVoip/PublicHeaders/TgVoip/OngoingCallThreadLocalContext.h delete mode 100644 submodules/TgVoip/Sources/OngoingCallThreadLocalContext.mm delete mode 160000 submodules/TgVoip/libtgvoip diff --git a/.gitmodules b/.gitmodules index ac9d05195d..9c7dc87aa6 100644 --- a/.gitmodules +++ b/.gitmodules @@ -11,9 +11,6 @@ url=https://github.com/bazelbuild/rules_swift.git [submodule "build-system/bazel-rules/apple_support"] path = build-system/bazel-rules/apple_support url = https://github.com/bazelbuild/apple_support.git -[submodule "submodules/TgVoip/libtgvoip"] - path = submodules/TgVoip/libtgvoip - url = https://github.com/telegramdesktop/libtgvoip.git [submodule "submodules/TgVoipWebrtc/tgcalls"] path = submodules/TgVoipWebrtc/tgcalls url=../tgcalls.git diff --git a/submodules/TelegramVoip/BUILD b/submodules/TelegramVoip/BUILD index 843dee34df..4b5b125320 100644 --- a/submodules/TelegramVoip/BUILD +++ b/submodules/TelegramVoip/BUILD @@ -15,7 +15,6 @@ swift_library( "//submodules/SSignalKit/SwiftSignalKit:SwiftSignalKit", "//submodules/TelegramCore:TelegramCore", "//submodules/TelegramUIPreferences:TelegramUIPreferences", - "//submodules/TgVoip:TgVoip", "//submodules/TgVoipWebrtc:TgVoipWebrtc", "//submodules/FFMpegBinding", "//submodules/ManagedFile", diff --git a/submodules/TelegramVoip/Sources/OngoingCallContext.swift b/submodules/TelegramVoip/Sources/OngoingCallContext.swift index e1863cd557..cf5002ad5f 100644 --- a/submodules/TelegramVoip/Sources/OngoingCallContext.swift +++ b/submodules/TelegramVoip/Sources/OngoingCallContext.swift @@ -4,7 +4,6 @@ import TelegramCore import Network import TelegramUIPreferences -import TgVoip import TgVoipWebrtc #if os(iOS) @@ -13,14 +12,6 @@ import AppBundle import Accelerate #endif -private func debugUseLegacyVersionForReflectors() -> Bool { - #if DEBUG && false - return true - #else - return false - #endif -} - private struct PeerTag: Hashable, CustomStringConvertible { var bytes: [UInt8] = Array(repeating: 0, count: 16) @@ -167,11 +158,6 @@ private func cleanupCallLogs(account: Account) { } private let setupLogs: Bool = { - OngoingCallThreadLocalContext.setupLoggingFunction({ value in - if let value = value { - Logger.shared.log("TGVOIP", value) - } - }) OngoingCallThreadLocalContextWebrtc.setupLoggingFunction({ value in if let value = value { Logger.shared.log("TGVOIP", value) @@ -253,26 +239,6 @@ private final class OngoingCallThreadLocalContextQueueImpl: NSObject, OngoingCal } } -private func ongoingNetworkTypeForType(_ type: NetworkType) -> OngoingCallNetworkType { - switch type { - case .none: - return .wifi - case .wifi: - return .wifi - case let .cellular(cellular): - switch cellular { - case .edge: - return .cellularEdge - case .gprs: - return .cellularGprs - case .thirdG, .unknown: - return .cellular3g - case .lte: - return .cellularLte - } - } -} - private func ongoingNetworkTypeForTypeWebrtc(_ type: NetworkType) -> OngoingCallNetworkTypeWebrtc { switch type { case .none: @@ -293,39 +259,6 @@ private func ongoingNetworkTypeForTypeWebrtc(_ type: NetworkType) -> OngoingCall } } -/*private func ongoingNetworkTypeForTypeWebrtcCustom(_ type: NetworkType) -> OngoingCallNetworkTypeWebrtcCustom { - switch type { - case .none: - return .wifi - case .wifi: - return .wifi - case let .cellular(cellular): - switch cellular { - case .edge: - return .cellularEdge - case .gprs: - return .cellularGprs - case .thirdG, .unknown: - return .cellular3g - case .lte: - return .cellularLte - } - } -}*/ - -private func ongoingDataSavingForType(_ type: VoiceCallDataSaving) -> OngoingCallDataSaving { - switch type { - case .never: - return .never - case .cellular: - return .cellular - case .always: - return .always - default: - return .never - } -} - private func ongoingDataSavingForTypeWebrtc(_ type: VoiceCallDataSaving) -> OngoingCallDataSavingWebrtc { switch type { case .never: @@ -363,56 +296,6 @@ private final class OngoingCallThreadLocalContextHolder { } } -extension OngoingCallThreadLocalContext: OngoingCallThreadLocalContextProtocol { - func nativeSetNetworkType(_ type: NetworkType) { - self.setNetworkType(ongoingNetworkTypeForType(type)) - } - - func nativeStop(_ completion: @escaping (String?, Int64, Int64, Int64, Int64) -> Void) { - self.stop(completion) - } - - func nativeBeginTermination() { - } - - func nativeSetIsMuted(_ value: Bool) { - self.setIsMuted(value) - } - - func nativeSetIsLowBatteryLevel(_ value: Bool) { - } - - func nativeRequestVideo(_ capturer: OngoingCallVideoCapturer) { - } - - func nativeSetRequestedVideoAspect(_ aspect: Float) { - } - - func nativeDisableVideo() { - } - - func nativeSwitchVideoCamera() { - } - - func nativeDebugInfo() -> String { - return self.debugInfo() ?? "" - } - - func nativeVersion() -> String { - return self.version() ?? "" - } - - func nativeGetDerivedState() -> Data { - return self.getDerivedState() - } - - func addExternalAudioData(data: Data) { - } - - func nativeSetIsAudioSessionActive(isActive: Bool) { - } -} - #if targetEnvironment(simulator) private extension UIImage { @available(iOS 13.0, *) @@ -816,23 +699,6 @@ extension OngoingCallThreadLocalContextWebrtc: OngoingCallThreadLocalContextProt } } -private extension OngoingCallContextState.State { - init(_ state: OngoingCallState) { - switch state { - case .initializing: - self = .initializing - case .connected: - self = .connected - case .failed: - self = .failed - case .reconnecting: - self = .reconnecting - default: - self = .failed - } - } -} - private extension OngoingCallContextState.State { init(_ state: OngoingCallStateWebrtc) { switch state { @@ -1014,7 +880,7 @@ public final class OngoingCallContext { private var networkTypeDisposable: Disposable? public static var maxLayer: Int32 { - return OngoingCallThreadLocalContext.maxLayer() + return OngoingCallThreadLocalContextWebrtc.maxLayer() } private let tempStatsLogFile: EngineTempBox.File @@ -1024,26 +890,15 @@ public final class OngoingCallContext { private let audioDevice: AudioDevice? public static func versions(includeExperimental: Bool, includeReference: Bool) -> [(version: String, supportsVideo: Bool)] { - #if os(iOS) && DEBUG && false - if "".isEmpty { - return [("5.0.0", true)] - } - #endif - - if debugUseLegacyVersionForReflectors() { - return [(OngoingCallThreadLocalContext.version(), true)] - } else { - var result: [(version: String, supportsVideo: Bool)] = [(OngoingCallThreadLocalContext.version(), false)] - result.append(contentsOf: OngoingCallThreadLocalContextWebrtc.versions(withIncludeReference: includeReference).map { version -> (version: String, supportsVideo: Bool) in - return (version, true) - }) - return result - } + var result: [(version: String, supportsVideo: Bool)] = [] + result.append(contentsOf: OngoingCallThreadLocalContextWebrtc.versions(withIncludeReference: includeReference).map { version -> (version: String, supportsVideo: Bool) in + return (version, true) + }) + return result } public init(account: Account, callSessionManager: CallSessionManager, callId: CallId, internalId: CallSessionInternalId, proxyServer: ProxyServerSettings?, initialNetworkType: NetworkType, updatedNetworkType: Signal, serializedData: String?, dataSaving: VoiceCallDataSaving, key: Data, isOutgoing: Bool, video: OngoingCallVideoCapturer?, connections: CallSessionConnectionSet, maxLayer: Int32, version: String, customParameters: String?, allowP2P: Bool, enableTCP: Bool, enableStunMarking: Bool, audioSessionActive: Signal, logName: String, preferredVideoCodec: String?, audioDevice: AudioDevice?) { let _ = setupLogs - OngoingCallThreadLocalContext.applyServerConfig(serializedData) self.callId = callId self.internalId = internalId @@ -1068,311 +923,274 @@ public final class OngoingCallContext { |> take(1) |> deliverOn(queue)).start(next: { [weak self] _ in if let strongSelf = self { - var useModernImplementation = true - var version = version var allowP2P = allowP2P - if debugUseLegacyVersionForReflectors() { - useModernImplementation = true - version = "12.0.0" - allowP2P = false - } else { - useModernImplementation = version != OngoingCallThreadLocalContext.version() + + var voipProxyServer: VoipProxyServerWebrtc? + if let proxyServer = proxyServer { + switch proxyServer.connection { + case let .socks5(username, password): + voipProxyServer = VoipProxyServerWebrtc(host: proxyServer.host, port: proxyServer.port, username: username, password: password) + case .mtp: + break + } } - if useModernImplementation { - var voipProxyServer: VoipProxyServerWebrtc? - if let proxyServer = proxyServer { - switch proxyServer.connection { - case let .socks5(username, password): - voipProxyServer = VoipProxyServerWebrtc(host: proxyServer.host, port: proxyServer.port, username: username, password: password) - case .mtp: - break - } - } - - var unfilteredConnections: [CallSessionConnection] - unfilteredConnections = [connections.primary] + connections.alternatives - - if version == "12.0.0" { - for connection in unfilteredConnections { - if case let .reflector(reflector) = connection { - unfilteredConnections.append(.reflector(CallSessionConnection.Reflector( - id: 123456, - ip: "91.108.9.38", - ipv6: "", - isTcp: true, - port: 595, - peerTag: reflector.peerTag - ))) - } - } - } - - var reflectorIdList: [Int64] = [] + var unfilteredConnections: [CallSessionConnection] + unfilteredConnections = [connections.primary] + connections.alternatives + + if version == "12.0.0" { for connection in unfilteredConnections { - switch connection { - case let .reflector(reflector): - reflectorIdList.append(reflector.id) - case .webRtcReflector: - break + if case let .reflector(reflector) = connection { + unfilteredConnections.append(.reflector(CallSessionConnection.Reflector( + id: 123456, + ip: "91.108.9.38", + ipv6: "", + isTcp: true, + port: 595, + peerTag: reflector.peerTag + ))) } } - - reflectorIdList.sort() - - var reflectorIdMapping: [Int64: UInt8] = [:] - for i in 0 ..< reflectorIdList.count { - reflectorIdMapping[reflectorIdList[i]] = UInt8(i + 1) + } + + var reflectorIdList: [Int64] = [] + for connection in unfilteredConnections { + switch connection { + case let .reflector(reflector): + reflectorIdList.append(reflector.id) + case .webRtcReflector: + break } + } + + reflectorIdList.sort() + + var reflectorIdMapping: [Int64: UInt8] = [:] + for i in 0 ..< reflectorIdList.count { + reflectorIdMapping[reflectorIdList[i]] = UInt8(i + 1) + } + + var signalingReflector: OngoingCallConnectionDescriptionWebrtc? + + var processedConnections: [CallSessionConnection] = [] + var filteredConnections: [OngoingCallConnectionDescriptionWebrtc] = [] + connectionsLoop: for connection in unfilteredConnections { + if processedConnections.contains(connection) { + continue + } + processedConnections.append(connection) - var signalingReflector: OngoingCallConnectionDescriptionWebrtc? - - var processedConnections: [CallSessionConnection] = [] - var filteredConnections: [OngoingCallConnectionDescriptionWebrtc] = [] - connectionsLoop: for connection in unfilteredConnections { - if processedConnections.contains(connection) { - continue - } - processedConnections.append(connection) - - switch connection { - case let .reflector(reflector): - if reflector.isTcp { - if version == "12.0.0" { - /*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)) - }*/ - } else { - 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) - } - - if let signalingReflector = signalingReflector { - if #available(iOS 12.0, *) { - let peerTag = dataWithHexString(signalingReflector.password) - - 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) - } - } - }) - }) - } - } - - var directConnection: OngoingCallDirectConnection? - if version == "9.0.0" && !"".isEmpty { - if #available(iOS 12.0, *) { - for connection in filteredConnections { - if connection.username == "reflector" && connection.reflectorId == 1 && !connection.hasTcp && connection.hasTurn { - directConnection = CallDirectConnectionImpl(host: connection.ip, port: Int(connection.port), peerTag: dataWithHexString(connection.password)) - break + switch connection { + case let .reflector(reflector): + if reflector.isTcp { + if version == "12.0.0" { + /*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)) + }*/ + } else { + 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 } } - } else { - directConnection = nil + case .webRtcReflector: + break } - #if DEBUG && true - var customParameters = customParameters - if let initialCustomParameters = try? JSONSerialization.jsonObject(with: (customParameters ?? "{}").data(using: .utf8)!) as? [String: Any] { - var customParametersValue: [String: Any] - customParametersValue = initialCustomParameters - if version == "12.0.0" { - customParametersValue["network_use_tcponly"] = true as NSNumber - customParameters = String(data: try! JSONSerialization.data(withJSONObject: customParametersValue), encoding: .utf8)! - } + var webrtcConnections: [OngoingCallConnectionDescriptionWebrtc] = [] + for connection in callConnectionDescriptionsWebrtc(connection, idMapping: reflectorIdMapping) { + webrtcConnections.append(connection) + } + + filteredConnections.append(contentsOf: webrtcConnections) + } + + if let signalingReflector = signalingReflector { + if #available(iOS 12.0, *) { + let peerTag = dataWithHexString(signalingReflector.password) - if let value = customParametersValue["network_use_tcponly"] as? Bool, value { - filteredConnections = filteredConnections.filter { connection in - if connection.hasTcp { - return true - } - return false - } - allowP2P = false - } - } - #endif - - /*#if DEBUG - if let initialCustomParameters = try? JSONSerialization.jsonObject(with: (customParameters ?? "{}").data(using: .utf8)!) as? [String: Any] { - var customParametersValue: [String: Any] - customParametersValue = initialCustomParameters - customParametersValue["network_kcp_experiment"] = true as NSNumber - customParameters = String(data: try! JSONSerialization.data(withJSONObject: customParametersValue), encoding: .utf8)! - } - #endif*/ - - let context = OngoingCallThreadLocalContextWebrtc( - version: version, - customParameters: customParameters, - queue: OngoingCallThreadLocalContextQueueImpl(queue: queue), - proxy: voipProxyServer, - networkType: ongoingNetworkTypeForTypeWebrtc(initialNetworkType), - dataSaving: ongoingDataSavingForTypeWebrtc(dataSaving), - derivedState: Data(), - key: key, - isOutgoing: isOutgoing, - connections: filteredConnections, - maxLayer: maxLayer, - allowP2P: allowP2P, - allowTCP: enableTCP, - enableStunMarking: enableStunMarking, - logPath: logPath, - statsLogPath: tempStatsLogPath, - sendSignalingData: { [weak callSessionManager] data in - queue.async { + strongSelf.signalingConnectionManager = QueueLocalObject(queue: queue, generate: { + return CallSignalingConnectionManager(queue: queue, peerTag: peerTag, servers: [signalingReflector], dataReceived: { data in guard let strongSelf = self else { return } - if let signalingConnectionManager = strongSelf.signalingConnectionManager { - signalingConnectionManager.with { impl in - impl.send(payloadData: data) + strongSelf.withContext { context in + if let context = context as? OngoingCallThreadLocalContextWebrtc { + context.addSignaling(data) } } - - if let callSessionManager = callSessionManager { - callSessionManager.sendSignalingData(internalId: internalId, data: data) - } + }) + }) + } + } + + var directConnection: OngoingCallDirectConnection? + if version == "9.0.0" && !"".isEmpty { + if #available(iOS 12.0, *) { + for connection in filteredConnections { + if connection.username == "reflector" && connection.reflectorId == 1 && !connection.hasTcp && connection.hasTurn { + directConnection = CallDirectConnectionImpl(host: connection.ip, port: Int(connection.port), peerTag: dataWithHexString(connection.password)) + break } - }, - videoCapturer: video?.impl, - preferredVideoCodec: preferredVideoCodec, - audioInputDeviceId: "", - audioDevice: audioDevice?.impl, - directConnection: directConnection - ) + } + } + } else { + directConnection = nil + } + + #if DEBUG && true + var customParameters = customParameters + if let initialCustomParameters = try? JSONSerialization.jsonObject(with: (customParameters ?? "{}").data(using: .utf8)!) as? [String: Any] { + var customParametersValue: [String: Any] + customParametersValue = initialCustomParameters + if version == "12.0.0" { + customParametersValue["network_use_tcponly"] = true as NSNumber + customParameters = String(data: try! JSONSerialization.data(withJSONObject: customParametersValue), encoding: .utf8)! + } - strongSelf.contextRef = Unmanaged.passRetained(OngoingCallThreadLocalContextHolder(context)) - context.stateChanged = { [weak callSessionManager] state, videoState, remoteVideoState, remoteAudioState, remoteBatteryLevel, _ in + if let value = customParametersValue["network_use_tcponly"] as? Bool, value { + filteredConnections = filteredConnections.filter { connection in + if connection.hasTcp { + return true + } + return false + } + allowP2P = false + } + } + #endif + + /*#if DEBUG + if let initialCustomParameters = try? JSONSerialization.jsonObject(with: (customParameters ?? "{}").data(using: .utf8)!) as? [String: Any] { + var customParametersValue: [String: Any] + customParametersValue = initialCustomParameters + customParametersValue["network_kcp_experiment"] = true as NSNumber + customParameters = String(data: try! JSONSerialization.data(withJSONObject: customParametersValue), encoding: .utf8)! + } + #endif*/ + + let context = OngoingCallThreadLocalContextWebrtc( + version: version, + customParameters: customParameters, + queue: OngoingCallThreadLocalContextQueueImpl(queue: queue), + proxy: voipProxyServer, + networkType: ongoingNetworkTypeForTypeWebrtc(initialNetworkType), + dataSaving: ongoingDataSavingForTypeWebrtc(dataSaving), + derivedState: Data(), + key: key, + isOutgoing: isOutgoing, + connections: filteredConnections, + maxLayer: maxLayer, + allowP2P: allowP2P, + allowTCP: enableTCP, + enableStunMarking: enableStunMarking, + logPath: logPath, + statsLogPath: tempStatsLogPath, + sendSignalingData: { [weak callSessionManager] data in queue.async { guard let strongSelf = self else { return } - let mappedState = OngoingCallContextState.State(state) - let mappedVideoState: OngoingCallContextState.VideoState - switch videoState { - case .inactive: - mappedVideoState = .inactive - case .active: - mappedVideoState = .active - case .paused: - mappedVideoState = .paused - @unknown default: - mappedVideoState = .notAvailable + if let signalingConnectionManager = strongSelf.signalingConnectionManager { + signalingConnectionManager.with { impl in + impl.send(payloadData: data) + } } - let mappedRemoteVideoState: OngoingCallContextState.RemoteVideoState - switch remoteVideoState { - case .inactive: - mappedRemoteVideoState = .inactive - case .active: - mappedRemoteVideoState = .active - case .paused: - mappedRemoteVideoState = .paused - @unknown default: - mappedRemoteVideoState = .inactive + + if let callSessionManager = callSessionManager { + callSessionManager.sendSignalingData(internalId: internalId, data: data) } - let mappedRemoteAudioState: OngoingCallContextState.RemoteAudioState - switch remoteAudioState { - case .active: - mappedRemoteAudioState = .active - case .muted: - mappedRemoteAudioState = .muted - @unknown default: - mappedRemoteAudioState = .active - } - let mappedRemoteBatteryLevel: OngoingCallContextState.RemoteBatteryLevel - switch remoteBatteryLevel { - case .normal: - mappedRemoteBatteryLevel = .normal - case .low: - mappedRemoteBatteryLevel = .low - @unknown default: - mappedRemoteBatteryLevel = .normal - } - if case .active = mappedVideoState, !strongSelf.didReportCallAsVideo { - strongSelf.didReportCallAsVideo = true - callSessionManager?.updateCallType(internalId: internalId, type: .video) - } - strongSelf.contextState.set(.single(OngoingCallContextState(state: mappedState, videoState: mappedVideoState, remoteVideoState: mappedRemoteVideoState, remoteAudioState: mappedRemoteAudioState, remoteBatteryLevel: mappedRemoteBatteryLevel))) } - } - strongSelf.receptionPromise.set(.single(4)) - context.signalBarsChanged = { signalBars in - self?.receptionPromise.set(.single(signalBars)) - } - context.audioLevelUpdated = { level in - self?.audioLevelPromise.set(.single(level)) - } - - if audioDevice == nil { - strongSelf.audioSessionActiveDisposable.set((audioSessionActive - |> deliverOn(queue)).start(next: { isActive in - guard let strongSelf = self else { - return - } - strongSelf.withContext { context in - context.nativeSetIsAudioSessionActive(isActive: isActive) - } - })) - } - - strongSelf.networkTypeDisposable = (updatedNetworkType - |> deliverOn(queue)).start(next: { networkType in - self?.withContext { context in - context.nativeSetNetworkType(networkType) + }, + videoCapturer: video?.impl, + preferredVideoCodec: preferredVideoCodec, + audioInputDeviceId: "", + audioDevice: audioDevice?.impl, + directConnection: directConnection + ) + + strongSelf.contextRef = Unmanaged.passRetained(OngoingCallThreadLocalContextHolder(context)) + context.stateChanged = { [weak callSessionManager] state, videoState, remoteVideoState, remoteAudioState, remoteBatteryLevel, _ in + queue.async { + guard let strongSelf = self else { + return } - }) - } else { - var voipProxyServer: VoipProxyServer? - if let proxyServer = proxyServer { - switch proxyServer.connection { - case let .socks5(username, password): - voipProxyServer = VoipProxyServer(host: proxyServer.host, port: proxyServer.port, username: username, password: password) - case .mtp: - break + let mappedState = OngoingCallContextState.State(state) + let mappedVideoState: OngoingCallContextState.VideoState + switch videoState { + case .inactive: + mappedVideoState = .inactive + case .active: + mappedVideoState = .active + case .paused: + mappedVideoState = .paused + @unknown default: + mappedVideoState = .notAvailable } - } - let context = OngoingCallThreadLocalContext(queue: OngoingCallThreadLocalContextQueueImpl(queue: queue), proxy: voipProxyServer, networkType: ongoingNetworkTypeForType(initialNetworkType), dataSaving: ongoingDataSavingForType(dataSaving), derivedState: Data(), key: key, isOutgoing: isOutgoing, primaryConnection: callConnectionDescription(connections.primary)!, alternativeConnections: connections.alternatives.compactMap(callConnectionDescription), maxLayer: maxLayer, allowP2P: allowP2P, logPath: logPath) - - strongSelf.contextRef = Unmanaged.passRetained(OngoingCallThreadLocalContextHolder(context)) - context.stateChanged = { state in - self?.contextState.set(.single(OngoingCallContextState(state: OngoingCallContextState.State(state), videoState: .notAvailable, remoteVideoState: .inactive, remoteAudioState: .active, remoteBatteryLevel: .normal))) - } - context.signalBarsChanged = { signalBars in - self?.receptionPromise.set(.single(signalBars)) - } - - strongSelf.networkTypeDisposable = (updatedNetworkType - |> deliverOn(queue)).start(next: { networkType in - self?.withContext { context in - context.nativeSetNetworkType(networkType) + let mappedRemoteVideoState: OngoingCallContextState.RemoteVideoState + switch remoteVideoState { + case .inactive: + mappedRemoteVideoState = .inactive + case .active: + mappedRemoteVideoState = .active + case .paused: + mappedRemoteVideoState = .paused + @unknown default: + mappedRemoteVideoState = .inactive } - }) + let mappedRemoteAudioState: OngoingCallContextState.RemoteAudioState + switch remoteAudioState { + case .active: + mappedRemoteAudioState = .active + case .muted: + mappedRemoteAudioState = .muted + @unknown default: + mappedRemoteAudioState = .active + } + let mappedRemoteBatteryLevel: OngoingCallContextState.RemoteBatteryLevel + switch remoteBatteryLevel { + case .normal: + mappedRemoteBatteryLevel = .normal + case .low: + mappedRemoteBatteryLevel = .low + @unknown default: + mappedRemoteBatteryLevel = .normal + } + if case .active = mappedVideoState, !strongSelf.didReportCallAsVideo { + strongSelf.didReportCallAsVideo = true + callSessionManager?.updateCallType(internalId: internalId, type: .video) + } + strongSelf.contextState.set(.single(OngoingCallContextState(state: mappedState, videoState: mappedVideoState, remoteVideoState: mappedRemoteVideoState, remoteAudioState: mappedRemoteAudioState, remoteBatteryLevel: mappedRemoteBatteryLevel))) + } } + strongSelf.receptionPromise.set(.single(4)) + context.signalBarsChanged = { signalBars in + self?.receptionPromise.set(.single(signalBars)) + } + context.audioLevelUpdated = { level in + self?.audioLevelPromise.set(.single(level)) + } + + if audioDevice == nil { + strongSelf.audioSessionActiveDisposable.set((audioSessionActive + |> deliverOn(queue)).start(next: { isActive in + guard let strongSelf = self else { + return + } + strongSelf.withContext { context in + context.nativeSetIsAudioSessionActive(isActive: isActive) + } + })) + } + + strongSelf.networkTypeDisposable = (updatedNetworkType + |> deliverOn(queue)).start(next: { networkType in + self?.withContext { context in + context.nativeSetNetworkType(networkType) + } + }) strongSelf.signalingDataDisposable = callSessionManager.beginReceivingCallSignalingData(internalId: internalId, { [weak self] dataList in queue.async { diff --git a/submodules/TgVoip/BUILD b/submodules/TgVoip/BUILD deleted file mode 100644 index 6ddbb134f0..0000000000 --- a/submodules/TgVoip/BUILD +++ /dev/null @@ -1,82 +0,0 @@ - -copts_arm = [ - "-DTGVOIP_USE_CUSTOM_CRYPTO", - "-DWEBRTC_APM_DEBUG_DUMP=0", - "-DWEBRTC_POSIX", - "-DTGVOIP_HAVE_TGLOG", - "-DWEBRTC_NS_FLOAT", - "-DWEBRTC_IOS", - "-DWEBRTC_HAS_NEON", - "-DTGVOIP_NO_DSP", -] - -copts_x86 = [ - "-DTGVOIP_USE_CUSTOM_CRYPTO", - "-DWEBRTC_APM_DEBUG_DUMP=0", - "-DWEBRTC_POSIX", - "-DTGVOIP_HAVE_TGLOG", - "-DTGVOIP_NO_DSP", - "-DWEBRTC_NS_FLOAT", - "-DWEBRTC_IOS", -] - -objc_library( - name = "TgVoip", - enable_modules = True, - module_name = "TgVoip", - srcs = glob([ - "Sources/**/*.m", - "Sources/**/*.mm", - "Sources/**/*.h", - "libtgvoip/*.h", - "libtgvoip/*.hpp", - "libtgvoip/*.m", - "libtgvoip/*.mm", - "libtgvoip/*.cpp", - "libtgvoip/audio/*.h", - "libtgvoip/audio/*.cpp", - "libtgvoip/video/*.h", - "libtgvoip/video/*.cpp", - "libtgvoip/os/darwin/*.h", - "libtgvoip/os/darwin/*.m", - "libtgvoip/os/darwin/*.mm", - "libtgvoip/os/darwin/*.cpp", - "libtgvoip/os/posix/*.h", - "libtgvoip/os/posix/*.cpp", - ], exclude = ["libtgvoip/os/darwin/*OSX*"]), - hdrs = glob([ - "PublicHeaders/**/*.h", - ]), - copts = [ - "-I{}/PublicHeaders/TgVoip".format(package_name()), - "-I{}/libtgvoip".format(package_name()), - "-I{}/third-party/webrtc/webrtc".format(package_name()), - "-Isubmodules/Opus/Public/opus", - "-DTGVOIP_USE_INSTALLED_OPUS", - "-Drtc=rtc1", - "-Dwebrtc=webrtc1", - ] + select({ - "@build_bazel_rules_apple//apple:ios_arm64": copts_arm, - "//build-system:ios_sim_arm64": copts_arm, - "@build_bazel_rules_apple//apple:ios_x86_64": copts_x86, - }), - includes = [ - "PublicHeaders", - ], - deps = [ - "//submodules/MtProtoKit:MtProtoKit", - "//third-party/opus:opus", - ], - sdk_frameworks = [ - "Foundation", - "UIKit", - "AudioToolbox", - "VideoToolbox", - "CoreTelephony", - "CoreMedia", - "AVFoundation", - ], - visibility = [ - "//visibility:public", - ], -) diff --git a/submodules/TgVoip/PublicHeaders/TgVoip/OngoingCallThreadLocalContext.h b/submodules/TgVoip/PublicHeaders/TgVoip/OngoingCallThreadLocalContext.h deleted file mode 100644 index d7f6e16846..0000000000 --- a/submodules/TgVoip/PublicHeaders/TgVoip/OngoingCallThreadLocalContext.h +++ /dev/null @@ -1,81 +0,0 @@ -#ifndef OngoingCallContext_h -#define OngoingCallContext_h - -#import - -@interface OngoingCallConnectionDescription : NSObject - -@property (nonatomic, readonly) int64_t connectionId; -@property (nonatomic, strong, readonly) NSString * _Nonnull ip; -@property (nonatomic, strong, readonly) NSString * _Nonnull ipv6; -@property (nonatomic, readonly) int32_t port; -@property (nonatomic, strong, readonly) NSData * _Nonnull peerTag; - -- (instancetype _Nonnull)initWithConnectionId:(int64_t)connectionId ip:(NSString * _Nonnull)ip ipv6:(NSString * _Nonnull)ipv6 port:(int32_t)port peerTag:(NSData * _Nonnull)peerTag; - -@end - -typedef NS_ENUM(int32_t, OngoingCallState) { - OngoingCallStateInitializing, - OngoingCallStateConnected, - OngoingCallStateFailed, - OngoingCallStateReconnecting -}; - -typedef NS_ENUM(int32_t, OngoingCallNetworkType) { - OngoingCallNetworkTypeWifi, - OngoingCallNetworkTypeCellularGprs, - OngoingCallNetworkTypeCellularEdge, - OngoingCallNetworkTypeCellular3g, - OngoingCallNetworkTypeCellularLte -}; - -typedef NS_ENUM(int32_t, OngoingCallDataSaving) { - OngoingCallDataSavingNever, - OngoingCallDataSavingCellular, - OngoingCallDataSavingAlways -}; - -@protocol OngoingCallThreadLocalContextQueue - -- (void)dispatch:(void (^ _Nonnull)())f; -- (bool)isCurrent; - -@end - -@interface VoipProxyServer : NSObject - -@property (nonatomic, strong, readonly) NSString * _Nonnull host; -@property (nonatomic, readonly) int32_t port; -@property (nonatomic, strong, readonly) NSString * _Nullable username; -@property (nonatomic, strong, readonly) NSString * _Nullable password; - -- (instancetype _Nonnull)initWithHost:(NSString * _Nonnull)host port:(int32_t)port username:(NSString * _Nullable)username password:(NSString * _Nullable)password; - -@end - -@interface OngoingCallThreadLocalContext : NSObject - -+ (void)setupLoggingFunction:(void (* _Nullable)(NSString * _Nullable))loggingFunction; -+ (void)applyServerConfig:(NSString * _Nullable)data; -+ (int32_t)maxLayer; -+ (NSString * _Nonnull)version; - -@property (nonatomic, copy) void (^ _Nullable stateChanged)(OngoingCallState); -@property (nonatomic, copy) void (^ _Nullable signalBarsChanged)(int32_t); - -- (instancetype _Nonnull)initWithQueue:(id _Nonnull)queue proxy:(VoipProxyServer * _Nullable)proxy networkType:(OngoingCallNetworkType)networkType dataSaving:(OngoingCallDataSaving)dataSaving derivedState:(NSData * _Nonnull)derivedState key:(NSData * _Nonnull)key isOutgoing:(bool)isOutgoing primaryConnection:(OngoingCallConnectionDescription * _Nonnull)primaryConnection alternativeConnections:(NSArray * _Nonnull)alternativeConnections maxLayer:(int32_t)maxLayer allowP2P:(BOOL)allowP2P logPath:(NSString * _Nonnull)logPath; -- (void)stop:(void (^_Nonnull)(NSString * _Nullable debugLog, int64_t bytesSentWifi, int64_t bytesReceivedWifi, int64_t bytesSentMobile, int64_t bytesReceivedMobile))completion; - -- (bool)needRate; - -- (NSString * _Nullable)debugInfo; -- (NSString * _Nullable)version; -- (NSData * _Nonnull)getDerivedState; - -- (void)setIsMuted:(bool)isMuted; -- (void)setNetworkType:(OngoingCallNetworkType)networkType; - -@end - -#endif diff --git a/submodules/TgVoip/Sources/OngoingCallThreadLocalContext.mm b/submodules/TgVoip/Sources/OngoingCallThreadLocalContext.mm deleted file mode 100644 index e650e4dec9..0000000000 --- a/submodules/TgVoip/Sources/OngoingCallThreadLocalContext.mm +++ /dev/null @@ -1,419 +0,0 @@ -#import "OngoingCallThreadLocalContext.h" - -#import "TgVoip.h" - -#import -#include - -#import - -static void TGCallAesIgeEncrypt(uint8_t *inBytes, uint8_t *outBytes, size_t length, uint8_t *key, uint8_t *iv) { - MTAesEncryptRaw(inBytes, outBytes, length, key, iv); -} - -static void TGCallAesIgeDecrypt(uint8_t *inBytes, uint8_t *outBytes, size_t length, uint8_t *key, uint8_t *iv) { - MTAesDecryptRaw(inBytes, outBytes, length, key, iv); -} - -static void TGCallSha1(uint8_t *msg, size_t length, uint8_t *output) { - MTRawSha1(msg, length, output); -} - -static void TGCallSha256(uint8_t *msg, size_t length, uint8_t *output) { - MTRawSha256(msg, length, output); -} - -static void TGCallAesCtrEncrypt(uint8_t *inOut, size_t length, uint8_t *key, uint8_t *iv, uint8_t *ecount, uint32_t *num) { - uint8_t *outData = (uint8_t *)malloc(length); - MTAesCtr *aesCtr = [[MTAesCtr alloc] initWithKey:key keyLength:32 iv:iv ecount:ecount num:*num]; - [aesCtr encryptIn:inOut out:outData len:length]; - memcpy(inOut, outData, length); - free(outData); - - [aesCtr getIv:iv]; - - memcpy(ecount, [aesCtr ecount], 16); - *num = [aesCtr num]; -} - -static void TGCallRandomBytes(uint8_t *buffer, size_t length) { - arc4random_buf(buffer, length); -} - -@implementation OngoingCallConnectionDescription - -- (instancetype _Nonnull)initWithConnectionId:(int64_t)connectionId ip:(NSString * _Nonnull)ip ipv6:(NSString * _Nonnull)ipv6 port:(int32_t)port peerTag:(NSData * _Nonnull)peerTag { - self = [super init]; - if (self != nil) { - _connectionId = connectionId; - _ip = ip; - _ipv6 = ipv6; - _port = port; - _peerTag = peerTag; - } - return self; -} - -@end - -static MTAtomic *callContexts() { - static MTAtomic *instance = nil; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - instance = [[MTAtomic alloc] initWithValue:[[NSMutableDictionary alloc] init]]; - }); - return instance; -} - -@interface OngoingCallThreadLocalContextReference : NSObject - -@property (nonatomic, weak) OngoingCallThreadLocalContext *context; -@property (nonatomic, strong, readonly) id queue; - -@end - -@implementation OngoingCallThreadLocalContextReference - -- (instancetype)initWithContext:(OngoingCallThreadLocalContext *)context queue:(id)queue { - self = [super init]; - if (self != nil) { - self.context = context; - _queue = queue; - } - return self; -} - -@end - -static int32_t nextId = 1; - -static int32_t addContext(OngoingCallThreadLocalContext *context, id queue) { - int32_t contextId = OSAtomicIncrement32(&nextId); - [callContexts() with:^id(NSMutableDictionary *dict) { - dict[@(contextId)] = [[OngoingCallThreadLocalContextReference alloc] initWithContext:context queue:queue]; - return nil; - }]; - return contextId; -} - -static void removeContext(int32_t contextId) { - [callContexts() with:^id(NSMutableDictionary *dict) { - [dict removeObjectForKey:@(contextId)]; - return nil; - }]; -} - -static void withContext(int32_t contextId, void (^f)(OngoingCallThreadLocalContext *)) { - __block OngoingCallThreadLocalContextReference *reference = nil; - [callContexts() with:^id(NSMutableDictionary *dict) { - reference = dict[@(contextId)]; - return nil; - }]; - if (reference != nil) { - [reference.queue dispatch:^{ - __strong OngoingCallThreadLocalContext *context = reference.context; - if (context != nil) { - f(context); - } - }]; - } -} - -@interface OngoingCallThreadLocalContext () { - id _queue; - int32_t _contextId; - - OngoingCallNetworkType _networkType; - NSTimeInterval _callReceiveTimeout; - NSTimeInterval _callRingTimeout; - NSTimeInterval _callConnectTimeout; - NSTimeInterval _callPacketTimeout; - - std::unique_ptr _tgVoip; - - OngoingCallState _state; - int32_t _signalBars; - NSData *_lastDerivedState; -} - -- (void)controllerStateChanged:(TgVoipState)state; -- (void)signalBarsChanged:(int32_t)signalBars; - -@end - -@implementation VoipProxyServer - -- (instancetype _Nonnull)initWithHost:(NSString * _Nonnull)host port:(int32_t)port username:(NSString * _Nullable)username password:(NSString * _Nullable)password { - self = [super init]; - if (self != nil) { - _host = host; - _port = port; - _username = username; - _password = password; - } - return self; -} - -@end - -static TgVoipNetworkType callControllerNetworkTypeForType(OngoingCallNetworkType type) { - switch (type) { - case OngoingCallNetworkTypeWifi: - return TgVoipNetworkType::WiFi; - case OngoingCallNetworkTypeCellularGprs: - return TgVoipNetworkType::Gprs; - case OngoingCallNetworkTypeCellular3g: - return TgVoipNetworkType::ThirdGeneration; - case OngoingCallNetworkTypeCellularLte: - return TgVoipNetworkType::Lte; - default: - return TgVoipNetworkType::ThirdGeneration; - } -} - -static TgVoipDataSaving callControllerDataSavingForType(OngoingCallDataSaving type) { - switch (type) { - case OngoingCallDataSavingNever: - return TgVoipDataSaving::Never; - case OngoingCallDataSavingCellular: - return TgVoipDataSaving::Mobile; - case OngoingCallDataSavingAlways: - return TgVoipDataSaving::Always; - default: - return TgVoipDataSaving::Never; - } -} - -@implementation OngoingCallThreadLocalContext - -static void (*InternalVoipLoggingFunction)(NSString *) = NULL; - -+ (void)setupLoggingFunction:(void (*)(NSString *))loggingFunction { - InternalVoipLoggingFunction = loggingFunction; - TgVoip::setLoggingFunction([](std::string const &string) { - if (InternalVoipLoggingFunction) { - InternalVoipLoggingFunction([[NSString alloc] initWithUTF8String:string.c_str()]); - } - }); -} - -+ (void)applyServerConfig:(NSString *)string { - if (string.length != 0) { - TgVoip::setGlobalServerConfig(std::string(string.UTF8String)); - } -} - -+ (int32_t)maxLayer { - return 92; -} - -+ (NSString *)version { - return [NSString stringWithUTF8String:TgVoip::getVersion().c_str()]; -} - -- (instancetype _Nonnull)initWithQueue:(id _Nonnull)queue proxy:(VoipProxyServer * _Nullable)proxy networkType:(OngoingCallNetworkType)networkType dataSaving:(OngoingCallDataSaving)dataSaving derivedState:(NSData * _Nonnull)derivedState key:(NSData * _Nonnull)key isOutgoing:(bool)isOutgoing primaryConnection:(OngoingCallConnectionDescription * _Nonnull)primaryConnection alternativeConnections:(NSArray * _Nonnull)alternativeConnections maxLayer:(int32_t)maxLayer allowP2P:(BOOL)allowP2P logPath:(NSString * _Nonnull)logPath { - self = [super init]; - if (self != nil) { - _queue = queue; - assert([queue isCurrent]); - _contextId = addContext(self, queue); - - _callReceiveTimeout = 20.0; - _callRingTimeout = 90.0; - _callConnectTimeout = 30.0; - _callPacketTimeout = 10.0; - _networkType = networkType; - - std::vector derivedStateValue; - derivedStateValue.resize(derivedState.length); - [derivedState getBytes:derivedStateValue.data() length:derivedState.length]; - - std::unique_ptr proxyValue = nullptr; - if (proxy != nil) { - TgVoipProxy *proxyObject = new TgVoipProxy(); - proxyObject->host = proxy.host.UTF8String; - proxyObject->port = (uint16_t)proxy.port; - proxyObject->login = proxy.username.UTF8String ?: ""; - proxyObject->password = proxy.password.UTF8String ?: ""; - proxyValue = std::unique_ptr(proxyObject); - } - - TgVoipCrypto crypto; - crypto.sha1 = &TGCallSha1; - crypto.sha256 = &TGCallSha256; - crypto.rand_bytes = &TGCallRandomBytes; - crypto.aes_ige_encrypt = &TGCallAesIgeEncrypt; - crypto.aes_ige_decrypt = &TGCallAesIgeDecrypt; - crypto.aes_ctr_encrypt = &TGCallAesCtrEncrypt; - - std::vector endpoints; - NSArray *connections = [@[primaryConnection] arrayByAddingObjectsFromArray:alternativeConnections]; - for (OngoingCallConnectionDescription *connection in connections) { - unsigned char peerTag[16]; - [connection.peerTag getBytes:peerTag length:16]; - - TgVoipEndpoint endpoint; - endpoint.endpointId = connection.connectionId; - endpoint.host = { - .ipv4 = std::string(connection.ip.UTF8String), - .ipv6 = std::string(connection.ipv6.UTF8String) - }; - endpoint.port = (uint16_t)connection.port; - endpoint.type = TgVoipEndpointType::UdpRelay; - memcpy(endpoint.peerTag, peerTag, 16); - endpoints.push_back(endpoint); - } - - TgVoipConfig config; - config.initializationTimeout = _callConnectTimeout; - config.receiveTimeout = _callPacketTimeout; - config.dataSaving = callControllerDataSavingForType(dataSaving); - config.enableP2P = static_cast(allowP2P); - config.enableAEC = false; - config.enableNS = true; - config.enableAGC = true; - config.enableVolumeControl = false; - config.enableCallUpgrade = false; - config.logPath = logPath.length == 0 ? "" : std::string(logPath.UTF8String); - config.maxApiLayer = [OngoingCallThreadLocalContext maxLayer]; - - std::vector encryptionKeyValue; - encryptionKeyValue.resize(key.length); - memcpy(encryptionKeyValue.data(), key.bytes, key.length); - - TgVoipEncryptionKey encryptionKey; - encryptionKey.value = encryptionKeyValue; - encryptionKey.isOutgoing = isOutgoing; - - _tgVoip = TgVoip::makeInstance( - config, - { derivedStateValue }, - endpoints, - proxyValue.get(), - callControllerNetworkTypeForType(networkType), - encryptionKey, - crypto - ); - - _state = OngoingCallStateInitializing; - _signalBars = -1; - - __weak OngoingCallThreadLocalContext *weakSelf = self; - _tgVoip->setOnStateUpdated([weakSelf](TgVoipState state) { - __strong OngoingCallThreadLocalContext *strongSelf = weakSelf; - if (strongSelf) { - [strongSelf controllerStateChanged:state]; - } - }); - _tgVoip->setOnSignalBarsUpdated([weakSelf](int signalBars) { - __strong OngoingCallThreadLocalContext *strongSelf = weakSelf; - if (strongSelf) { - [strongSelf signalBarsChanged:signalBars]; - } - }); - } - return self; -} - -- (void)dealloc { - assert([_queue isCurrent]); - removeContext(_contextId); - if (_tgVoip != NULL) { - [self stop:nil]; - } -} - -- (void)stop:(void (^)(NSString *, int64_t, int64_t, int64_t, int64_t))completion { - if (_tgVoip) { - TgVoipFinalState finalState = _tgVoip->stop(); - - NSString *debugLog = [NSString stringWithUTF8String:finalState.debugLog.c_str()]; - _lastDerivedState = [[NSData alloc] initWithBytes:finalState.persistentState.value.data() length:finalState.persistentState.value.size()]; - - _tgVoip.reset(); - - if (completion) { - completion(debugLog, finalState.trafficStats.bytesSentWifi, finalState.trafficStats.bytesReceivedWifi, finalState.trafficStats.bytesSentMobile, finalState.trafficStats.bytesReceivedMobile); - } - } -} - -- (NSString *)debugInfo { - if (_tgVoip != nil) { - auto rawDebugString = _tgVoip->getDebugInfo(); - return [NSString stringWithUTF8String:rawDebugString.c_str()]; - } else { - return nil; - } -} - -- (NSString *)version { - if (_tgVoip != nil) { - return [NSString stringWithUTF8String:_tgVoip->getVersion().c_str()]; - } else { - return nil; - } -} - -- (NSData * _Nonnull)getDerivedState { - if (_tgVoip) { - auto persistentState = _tgVoip->getPersistentState(); - return [[NSData alloc] initWithBytes:persistentState.value.data() length:persistentState.value.size()]; - } else if (_lastDerivedState != nil) { - return _lastDerivedState; - } else { - return [NSData data]; - } -} - -- (void)controllerStateChanged:(TgVoipState)state { - OngoingCallState callState = OngoingCallStateInitializing; - switch (state) { - case TgVoipState::Established: - callState = OngoingCallStateConnected; - break; - case TgVoipState::Failed: - callState = OngoingCallStateFailed; - break; - case TgVoipState::Reconnecting: - callState = OngoingCallStateReconnecting; - break; - default: - break; - } - - if (callState != _state) { - _state = callState; - - if (_stateChanged) { - _stateChanged(callState); - } - } -} - -- (void)signalBarsChanged:(int32_t)signalBars { - if (signalBars != _signalBars) { - _signalBars = signalBars; - - if (_signalBarsChanged) { - _signalBarsChanged(signalBars); - } - } -} - -- (void)setIsMuted:(bool)isMuted { - if (_tgVoip) { - _tgVoip->setMuteMicrophone(isMuted); - } -} - -- (void)setNetworkType:(OngoingCallNetworkType)networkType { - if (_networkType != networkType) { - _networkType = networkType; - if (_tgVoip) { - _tgVoip->setNetworkType(callControllerNetworkTypeForType(networkType)); - } - } -} - -@end diff --git a/submodules/TgVoip/libtgvoip b/submodules/TgVoip/libtgvoip deleted file mode 160000 index 37d98e984f..0000000000 --- a/submodules/TgVoip/libtgvoip +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 37d98e984fd6fa389262307db826d52ab86c8241 diff --git a/submodules/TgVoipWebrtc/PublicHeaders/TgVoipWebrtc/OngoingCallThreadLocalContext.h b/submodules/TgVoipWebrtc/PublicHeaders/TgVoipWebrtc/OngoingCallThreadLocalContext.h index d08d031a79..ca6be80c5a 100644 --- a/submodules/TgVoipWebrtc/PublicHeaders/TgVoipWebrtc/OngoingCallThreadLocalContext.h +++ b/submodules/TgVoipWebrtc/PublicHeaders/TgVoipWebrtc/OngoingCallThreadLocalContext.h @@ -11,6 +11,36 @@ #define UIView NSView #endif +@interface OngoingCallConnectionDescription : NSObject + +@property (nonatomic, readonly) int64_t connectionId; +@property (nonatomic, strong, readonly) NSString * _Nonnull ip; +@property (nonatomic, strong, readonly) NSString * _Nonnull ipv6; +@property (nonatomic, readonly) int32_t port; +@property (nonatomic, strong, readonly) NSData * _Nonnull peerTag; + +- (instancetype _Nonnull)initWithConnectionId:(int64_t)connectionId ip:(NSString * _Nonnull)ip ipv6:(NSString * _Nonnull)ipv6 port:(int32_t)port peerTag:(NSData * _Nonnull)peerTag; + +@end + +@protocol OngoingCallThreadLocalContextQueue + +- (void)dispatch:(void (^ _Nonnull)())f; +- (bool)isCurrent; + +@end + +@interface VoipProxyServer : NSObject + +@property (nonatomic, strong, readonly) NSString * _Nonnull host; +@property (nonatomic, readonly) int32_t port; +@property (nonatomic, strong, readonly) NSString * _Nullable username; +@property (nonatomic, strong, readonly) NSString * _Nullable password; + +- (instancetype _Nonnull)initWithHost:(NSString * _Nonnull)host port:(int32_t)port username:(NSString * _Nullable)username password:(NSString * _Nullable)password; + +@end + @interface CallAudioTone : NSObject @property (nonatomic, strong, readonly) NSData * _Nonnull samples; diff --git a/submodules/TgVoipWebrtc/Sources/OngoingCallThreadLocalContext.mm b/submodules/TgVoipWebrtc/Sources/OngoingCallThreadLocalContext.mm index 5955fe26b2..66d632c72e 100644 --- a/submodules/TgVoipWebrtc/Sources/OngoingCallThreadLocalContext.mm +++ b/submodules/TgVoipWebrtc/Sources/OngoingCallThreadLocalContext.mm @@ -42,6 +42,38 @@ #import "platform/darwin/TGRTCCVPixelBuffer.h" #include "rtc_base/logging.h" +@implementation OngoingCallConnectionDescription + +- (instancetype _Nonnull)initWithConnectionId:(int64_t)connectionId ip:(NSString * _Nonnull)ip ipv6:(NSString * _Nonnull)ipv6 port:(int32_t)port peerTag:(NSData * _Nonnull)peerTag { + self = [super init]; + if (self != nil) { + _connectionId = connectionId; + _ip = ip; + _ipv6 = ipv6; + _port = port; + _peerTag = peerTag; + } + return self; +} + +@end + +@implementation VoipProxyServer + +- (instancetype _Nonnull)initWithHost:(NSString * _Nonnull)host port:(int32_t)port username:(NSString * _Nullable)username password:(NSString * _Nullable)password { + self = [super init]; + if (self != nil) { + _host = host; + _port = port; + _username = username; + _password = password; + } + return self; +} + +@end + + @implementation CallAudioTone - (instancetype _Nonnull)initWithSamples:(NSData * _Nonnull)samples sampleRate:(NSInteger)sampleRate loopCount:(NSInteger)loopCount { @@ -1488,9 +1520,6 @@ static void (*InternalVoipLoggingFunction)(NSString *) = NULL; } + (void)applyServerConfig:(NSString *)string { - if (string.length != 0) { - //TgVoip::setGlobalServerConfig(std::string(string.UTF8String)); - } } + (void)setupAudioSession { diff --git a/submodules/TgVoipWebrtc/tgcalls b/submodules/TgVoipWebrtc/tgcalls index d50eeeb40c..1ea67f88b8 160000 --- a/submodules/TgVoipWebrtc/tgcalls +++ b/submodules/TgVoipWebrtc/tgcalls @@ -1 +1 @@ -Subproject commit d50eeeb40ce6a2d36d505bcaf0b5f4e5ed473f22 +Subproject commit 1ea67f88b8d9fd04fc151d164669f6c229d651d3 diff --git a/third-party/webrtc/webrtc b/third-party/webrtc/webrtc index 77d3d1fe2f..e8d2ef8c74 160000 --- a/third-party/webrtc/webrtc +++ b/third-party/webrtc/webrtc @@ -1 +1 @@ -Subproject commit 77d3d1fe2ff2f364e8edee58179a7b7b95239b01 +Subproject commit e8d2ef8c74f07c4f952db43bdfc08f39228f79c3