mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Merge branch 'experiments/custom-reflectors'
This commit is contained in:
commit
4261cbc2b2
@ -7,6 +7,62 @@ import TelegramUIPreferences
|
|||||||
import TgVoip
|
import TgVoip
|
||||||
import TgVoipWebrtc
|
import TgVoipWebrtc
|
||||||
|
|
||||||
|
private let debugUseLegacyVersionForReflectors: Bool = {
|
||||||
|
#if DEBUG && false
|
||||||
|
return true
|
||||||
|
#else
|
||||||
|
return false
|
||||||
|
#endif
|
||||||
|
}()
|
||||||
|
|
||||||
|
private struct PeerTag: Hashable, CustomStringConvertible {
|
||||||
|
var bytes: [UInt8] = Array<UInt8>(repeating: 0, count: 16)
|
||||||
|
|
||||||
|
var canonical: PeerTag {
|
||||||
|
var updatedBytes = self.bytes
|
||||||
|
updatedBytes[0] &= ~1
|
||||||
|
return PeerTag(bytes: updatedBytes)
|
||||||
|
}
|
||||||
|
|
||||||
|
var flipped: PeerTag {
|
||||||
|
var updatedBytes = self.bytes
|
||||||
|
updatedBytes[0] ^= 1
|
||||||
|
return PeerTag(bytes: updatedBytes)
|
||||||
|
}
|
||||||
|
|
||||||
|
var description: String {
|
||||||
|
var result = ""
|
||||||
|
|
||||||
|
for byte in bytes {
|
||||||
|
result.append(String(byte, radix: 16))
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private extension PeerTag {
|
||||||
|
init(data: Data) {
|
||||||
|
precondition(data.count >= 16)
|
||||||
|
data.withUnsafeBytes { buffer -> Void in
|
||||||
|
memcpy(&self.bytes, buffer.baseAddress!.assumingMemoryBound(to: UInt8.self), 16)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var data: Data {
|
||||||
|
var bytes = self.bytes
|
||||||
|
var resultData = Data(repeating: 0, count: 16)
|
||||||
|
resultData.withUnsafeMutableBytes { buffer -> Void in
|
||||||
|
memcpy(buffer.baseAddress!.assumingMemoryBound(to: UInt8.self), &bytes, 16)
|
||||||
|
}
|
||||||
|
return resultData
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func flippedPeerTag(_ data: Data) -> Data {
|
||||||
|
return PeerTag(data: data).flipped.data
|
||||||
|
}
|
||||||
|
|
||||||
private func callConnectionDescription(_ connection: CallSessionConnection) -> OngoingCallConnectionDescription? {
|
private func callConnectionDescription(_ connection: CallSessionConnection) -> OngoingCallConnectionDescription? {
|
||||||
switch connection {
|
switch connection {
|
||||||
case let .reflector(reflector):
|
case let .reflector(reflector):
|
||||||
@ -16,28 +72,27 @@ private func callConnectionDescription(_ connection: CallSessionConnection) -> O
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func callConnectionDescriptionsWebrtc(_ connection: CallSessionConnection) -> [OngoingCallConnectionDescriptionWebrtc] {
|
private func callConnectionDescriptionsWebrtc(_ connection: CallSessionConnection, idMapping: [Int64: UInt8]) -> [OngoingCallConnectionDescriptionWebrtc] {
|
||||||
switch connection {
|
switch connection {
|
||||||
case let .reflector(reflector):
|
case let .reflector(reflector):
|
||||||
#if DEBUG
|
guard let id = idMapping[reflector.id] else {
|
||||||
|
return []
|
||||||
|
}
|
||||||
var result: [OngoingCallConnectionDescriptionWebrtc] = []
|
var result: [OngoingCallConnectionDescriptionWebrtc] = []
|
||||||
if !reflector.ip.isEmpty {
|
if !reflector.ip.isEmpty {
|
||||||
result.append(OngoingCallConnectionDescriptionWebrtc(connectionId: reflector.id, hasStun: false, hasTurn: true, ip: reflector.ip, port: reflector.port, username: "reflector", password: hexString(reflector.peerTag)))
|
result.append(OngoingCallConnectionDescriptionWebrtc(reflectorId: id, hasStun: false, hasTurn: true, ip: reflector.ip, port: reflector.port, username: "reflector", password: hexString(reflector.peerTag)))
|
||||||
}
|
}
|
||||||
if !reflector.ipv6.isEmpty {
|
if !reflector.ipv6.isEmpty {
|
||||||
result.append(OngoingCallConnectionDescriptionWebrtc(connectionId: reflector.id, hasStun: false, hasTurn: true, ip: reflector.ipv6, port: reflector.port, username: "reflector", password: hexString(reflector.peerTag)))
|
result.append(OngoingCallConnectionDescriptionWebrtc(reflectorId: id, hasStun: false, hasTurn: true, ip: reflector.ipv6, port: reflector.port, username: "reflector", password: hexString(reflector.peerTag)))
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
#else
|
|
||||||
return []
|
|
||||||
#endif
|
|
||||||
case let .webRtcReflector(reflector):
|
case let .webRtcReflector(reflector):
|
||||||
var result: [OngoingCallConnectionDescriptionWebrtc] = []
|
var result: [OngoingCallConnectionDescriptionWebrtc] = []
|
||||||
if !reflector.ip.isEmpty {
|
if !reflector.ip.isEmpty {
|
||||||
result.append(OngoingCallConnectionDescriptionWebrtc(connectionId: reflector.id, hasStun: reflector.hasStun, hasTurn: reflector.hasTurn, ip: reflector.ip, port: reflector.port, username: reflector.username, password: reflector.password))
|
result.append(OngoingCallConnectionDescriptionWebrtc(reflectorId: 0, hasStun: reflector.hasStun, hasTurn: reflector.hasTurn, ip: reflector.ip, port: reflector.port, username: reflector.username, password: reflector.password))
|
||||||
}
|
}
|
||||||
if !reflector.ipv6.isEmpty {
|
if !reflector.ipv6.isEmpty {
|
||||||
result.append(OngoingCallConnectionDescriptionWebrtc(connectionId: reflector.id, hasStun: reflector.hasStun, hasTurn: reflector.hasTurn, ip: reflector.ipv6, port: reflector.port, username: reflector.username, password: reflector.password))
|
result.append(OngoingCallConnectionDescriptionWebrtc(reflectorId: 0, hasStun: reflector.hasStun, hasTurn: reflector.hasTurn, ip: reflector.ipv6, port: reflector.port, username: reflector.username, password: reflector.password))
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
@ -684,24 +739,21 @@ public final class OngoingCallContext {
|
|||||||
private let tempStatsLogFile: EngineTempBoxFile
|
private let tempStatsLogFile: EngineTempBoxFile
|
||||||
|
|
||||||
public static func versions(includeExperimental: Bool, includeReference: Bool) -> [(version: String, supportsVideo: Bool)] {
|
public static func versions(includeExperimental: Bool, includeReference: Bool) -> [(version: String, supportsVideo: Bool)] {
|
||||||
|
if debugUseLegacyVersionForReflectors {
|
||||||
|
return [(OngoingCallThreadLocalContext.version(), true)]
|
||||||
|
} else {
|
||||||
var result: [(version: String, supportsVideo: Bool)] = [(OngoingCallThreadLocalContext.version(), false)]
|
var result: [(version: String, supportsVideo: Bool)] = [(OngoingCallThreadLocalContext.version(), false)]
|
||||||
if includeExperimental {
|
|
||||||
result.append(contentsOf: OngoingCallThreadLocalContextWebrtc.versions(withIncludeReference: includeReference).map { version -> (version: String, supportsVideo: Bool) in
|
result.append(contentsOf: OngoingCallThreadLocalContextWebrtc.versions(withIncludeReference: includeReference).map { version -> (version: String, supportsVideo: Bool) in
|
||||||
return (version, true)
|
return (version, true)
|
||||||
})
|
})
|
||||||
}
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public init(account: Account, callSessionManager: CallSessionManager, internalId: CallSessionInternalId, proxyServer: ProxyServerSettings?, initialNetworkType: NetworkType, updatedNetworkType: Signal<NetworkType, NoError>, serializedData: String?, dataSaving: VoiceCallDataSaving, derivedState: VoipDerivedState, key: Data, isOutgoing: Bool, video: OngoingCallVideoCapturer?, connections: CallSessionConnectionSet, maxLayer: Int32, version: String, allowP2P: Bool, enableTCP: Bool, enableStunMarking: Bool, audioSessionActive: Signal<Bool, NoError>, logName: String, preferredVideoCodec: String?) {
|
public init(account: Account, callSessionManager: CallSessionManager, internalId: CallSessionInternalId, proxyServer: ProxyServerSettings?, initialNetworkType: NetworkType, updatedNetworkType: Signal<NetworkType, NoError>, serializedData: String?, dataSaving: VoiceCallDataSaving, derivedState: VoipDerivedState, key: Data, isOutgoing: Bool, video: OngoingCallVideoCapturer?, connections: CallSessionConnectionSet, maxLayer: Int32, version: String, allowP2P: Bool, enableTCP: Bool, enableStunMarking: Bool, audioSessionActive: Signal<Bool, NoError>, logName: String, preferredVideoCodec: String?) {
|
||||||
let _ = setupLogs
|
let _ = setupLogs
|
||||||
OngoingCallThreadLocalContext.applyServerConfig(serializedData)
|
OngoingCallThreadLocalContext.applyServerConfig(serializedData)
|
||||||
|
|
||||||
#if DEBUG
|
|
||||||
let version = "4.1.2"
|
|
||||||
let allowP2P = false
|
|
||||||
#endif
|
|
||||||
|
|
||||||
self.internalId = internalId
|
self.internalId = internalId
|
||||||
self.account = account
|
self.account = account
|
||||||
self.callSessionManager = callSessionManager
|
self.callSessionManager = callSessionManager
|
||||||
@ -722,7 +774,18 @@ public final class OngoingCallContext {
|
|||||||
|> take(1)
|
|> take(1)
|
||||||
|> deliverOn(queue)).start(next: { [weak self] _ in
|
|> deliverOn(queue)).start(next: { [weak self] _ in
|
||||||
if let strongSelf = self {
|
if let strongSelf = self {
|
||||||
if OngoingCallThreadLocalContextWebrtc.versions(withIncludeReference: true).contains(version) {
|
var useModernImplementation = true
|
||||||
|
var version = version
|
||||||
|
var allowP2P = allowP2P
|
||||||
|
if debugUseLegacyVersionForReflectors {
|
||||||
|
useModernImplementation = true
|
||||||
|
version = "3.0.0"
|
||||||
|
allowP2P = false
|
||||||
|
} else {
|
||||||
|
useModernImplementation = version != OngoingCallThreadLocalContext.version()
|
||||||
|
}
|
||||||
|
|
||||||
|
if useModernImplementation {
|
||||||
var voipProxyServer: VoipProxyServerWebrtc?
|
var voipProxyServer: VoipProxyServerWebrtc?
|
||||||
if let proxyServer = proxyServer {
|
if let proxyServer = proxyServer {
|
||||||
switch proxyServer.connection {
|
switch proxyServer.connection {
|
||||||
@ -734,6 +797,24 @@ public final class OngoingCallContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let unfilteredConnections = [connections.primary] + connections.alternatives
|
let unfilteredConnections = [connections.primary] + connections.alternatives
|
||||||
|
|
||||||
|
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 processedConnections: [CallSessionConnection] = []
|
var processedConnections: [CallSessionConnection] = []
|
||||||
var filteredConnections: [OngoingCallConnectionDescriptionWebrtc] = []
|
var filteredConnections: [OngoingCallConnectionDescriptionWebrtc] = []
|
||||||
for connection in unfilteredConnections {
|
for connection in unfilteredConnections {
|
||||||
@ -741,21 +822,9 @@ public final class OngoingCallContext {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
processedConnections.append(connection)
|
processedConnections.append(connection)
|
||||||
filteredConnections.append(contentsOf: callConnectionDescriptionsWebrtc(connection))
|
filteredConnections.append(contentsOf: callConnectionDescriptionsWebrtc(connection, idMapping: reflectorIdMapping))
|
||||||
}
|
}
|
||||||
|
|
||||||
/*#if DEBUG
|
|
||||||
filteredConnections.removeAll()
|
|
||||||
filteredConnections.append(OngoingCallConnectionDescriptionWebrtc(
|
|
||||||
connectionId: 1,
|
|
||||||
hasStun: true,
|
|
||||||
hasTurn: true, ip: "178.62.7.192",
|
|
||||||
port: 1400,
|
|
||||||
username: "user",
|
|
||||||
password: "user")
|
|
||||||
)
|
|
||||||
#endif*/
|
|
||||||
|
|
||||||
let context = OngoingCallThreadLocalContextWebrtc(version: version, queue: OngoingCallThreadLocalContextQueueImpl(queue: queue), proxy: voipProxyServer, networkType: ongoingNetworkTypeForTypeWebrtc(initialNetworkType), dataSaving: ongoingDataSavingForTypeWebrtc(dataSaving), derivedState: derivedState.data, key: key, isOutgoing: isOutgoing, connections: filteredConnections, maxLayer: maxLayer, allowP2P: allowP2P, allowTCP: enableTCP, enableStunMarking: enableStunMarking, logPath: tempLogPath, statsLogPath: tempStatsLogPath, sendSignalingData: { [weak callSessionManager] data in
|
let context = OngoingCallThreadLocalContextWebrtc(version: version, queue: OngoingCallThreadLocalContextQueueImpl(queue: queue), proxy: voipProxyServer, networkType: ongoingNetworkTypeForTypeWebrtc(initialNetworkType), dataSaving: ongoingDataSavingForTypeWebrtc(dataSaving), derivedState: derivedState.data, key: key, isOutgoing: isOutgoing, connections: filteredConnections, maxLayer: maxLayer, allowP2P: allowP2P, allowTCP: enableTCP, enableStunMarking: enableStunMarking, logPath: tempLogPath, statsLogPath: tempStatsLogPath, sendSignalingData: { [weak callSessionManager] data in
|
||||||
callSessionManager?.sendSignalingData(internalId: internalId, data: data)
|
callSessionManager?.sendSignalingData(internalId: internalId, data: data)
|
||||||
}, videoCapturer: video?.impl, preferredVideoCodec: preferredVideoCodec, audioInputDeviceId: "")
|
}, videoCapturer: video?.impl, preferredVideoCodec: preferredVideoCodec, audioInputDeviceId: "")
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
@interface OngoingCallConnectionDescriptionWebrtc : NSObject
|
@interface OngoingCallConnectionDescriptionWebrtc : NSObject
|
||||||
|
|
||||||
@property (nonatomic, readonly) int64_t connectionId;
|
@property (nonatomic, readonly) uint8_t reflectorId;
|
||||||
@property (nonatomic, readonly) bool hasStun;
|
@property (nonatomic, readonly) bool hasStun;
|
||||||
@property (nonatomic, readonly) bool hasTurn;
|
@property (nonatomic, readonly) bool hasTurn;
|
||||||
@property (nonatomic, strong, readonly) NSString * _Nonnull ip;
|
@property (nonatomic, strong, readonly) NSString * _Nonnull ip;
|
||||||
@ -21,7 +21,7 @@
|
|||||||
@property (nonatomic, strong, readonly) NSString * _Nonnull username;
|
@property (nonatomic, strong, readonly) NSString * _Nonnull username;
|
||||||
@property (nonatomic, strong, readonly) NSString * _Nonnull password;
|
@property (nonatomic, strong, readonly) NSString * _Nonnull password;
|
||||||
|
|
||||||
- (instancetype _Nonnull)initWithConnectionId:(int64_t)connectionId hasStun:(bool)hasStun hasTurn:(bool)hasTurn ip:(NSString * _Nonnull)ip port:(int32_t)port username:(NSString * _Nonnull)username password:(NSString * _Nonnull)password;
|
- (instancetype _Nonnull)initWithReflectorId:(uint8_t)reflectorId hasStun:(bool)hasStun hasTurn:(bool)hasTurn ip:(NSString * _Nonnull)ip port:(int32_t)port username:(NSString * _Nonnull)username password:(NSString * _Nonnull)password;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
@ -41,10 +41,10 @@
|
|||||||
|
|
||||||
@implementation OngoingCallConnectionDescriptionWebrtc
|
@implementation OngoingCallConnectionDescriptionWebrtc
|
||||||
|
|
||||||
- (instancetype _Nonnull)initWithConnectionId:(int64_t)connectionId hasStun:(bool)hasStun hasTurn:(bool)hasTurn ip:(NSString * _Nonnull)ip port:(int32_t)port username:(NSString * _Nonnull)username password:(NSString * _Nonnull)password {
|
- (instancetype _Nonnull)initWithReflectorId:(uint8_t)reflectorId hasStun:(bool)hasStun hasTurn:(bool)hasTurn ip:(NSString * _Nonnull)ip port:(int32_t)port username:(NSString * _Nonnull)username password:(NSString * _Nonnull)password {
|
||||||
self = [super init];
|
self = [super init];
|
||||||
if (self != nil) {
|
if (self != nil) {
|
||||||
_connectionId = connectionId;
|
_reflectorId = reflectorId;
|
||||||
_hasStun = hasStun;
|
_hasStun = hasStun;
|
||||||
_hasTurn = hasTurn;
|
_hasTurn = hasTurn;
|
||||||
_ip = ip;
|
_ip = ip;
|
||||||
@ -882,6 +882,7 @@ static void (*InternalVoipLoggingFunction)(NSString *) = NULL;
|
|||||||
for (OngoingCallConnectionDescriptionWebrtc *connection in connections) {
|
for (OngoingCallConnectionDescriptionWebrtc *connection in connections) {
|
||||||
if (connection.hasStun) {
|
if (connection.hasStun) {
|
||||||
parsedRtcServers.push_back((tgcalls::RtcServer){
|
parsedRtcServers.push_back((tgcalls::RtcServer){
|
||||||
|
.id = 0,
|
||||||
.host = connection.ip.UTF8String,
|
.host = connection.ip.UTF8String,
|
||||||
.port = (uint16_t)connection.port,
|
.port = (uint16_t)connection.port,
|
||||||
.login = "",
|
.login = "",
|
||||||
@ -891,6 +892,7 @@ static void (*InternalVoipLoggingFunction)(NSString *) = NULL;
|
|||||||
}
|
}
|
||||||
if (connection.hasTurn) {
|
if (connection.hasTurn) {
|
||||||
parsedRtcServers.push_back((tgcalls::RtcServer){
|
parsedRtcServers.push_back((tgcalls::RtcServer){
|
||||||
|
.id = connection.reflectorId,
|
||||||
.host = connection.ip.UTF8String,
|
.host = connection.ip.UTF8String,
|
||||||
.port = (uint16_t)connection.port,
|
.port = (uint16_t)connection.port,
|
||||||
.login = connection.username.UTF8String,
|
.login = connection.username.UTF8String,
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit 3ce2c38805ea5af7a05b8fe93a26becaf9e76bd3
|
Subproject commit 16591fbfbd3afc0b4a5a89040cae63563c0a33d0
|
Loading…
x
Reference in New Issue
Block a user