diff --git a/Session.xcodeproj/project.pbxproj b/Session.xcodeproj/project.pbxproj index 70bc73c20..92db4ef14 100644 --- a/Session.xcodeproj/project.pbxproj +++ b/Session.xcodeproj/project.pbxproj @@ -157,6 +157,7 @@ 7BDCFC08242186E700641C39 /* NotificationServiceExtensionContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BDCFC07242186E700641C39 /* NotificationServiceExtensionContext.swift */; }; 7BDCFC0B2421EB7600641C39 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = B6F509951AA53F760068F56A /* Localizable.strings */; }; 7BFD1A8A2745C4F000FB91B9 /* Permissions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BFD1A892745C4F000FB91B9 /* Permissions.swift */; }; + 7BFD1A8C2747150E00FB91B9 /* TurnServerInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BFD1A8B2747150E00FB91B9 /* TurnServerInfo.swift */; }; 945AA2B82B621254F69FA9E8 /* Pods_SessionUtilitiesKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9117261809D69B3D7C26B8F1 /* Pods_SessionUtilitiesKit.framework */; }; 9EE44C6B4D4A069B86112387 /* Pods_SessionSnodeKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9559C3068280BA2383F547F7 /* Pods_SessionSnodeKit.framework */; }; A11CD70D17FA230600A2D1B1 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A11CD70C17FA230600A2D1B1 /* QuartzCore.framework */; }; @@ -1146,6 +1147,7 @@ 7BDCFC0424206E7300641C39 /* SessionNotificationServiceExtension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = SessionNotificationServiceExtension.entitlements; sourceTree = ""; }; 7BDCFC07242186E700641C39 /* NotificationServiceExtensionContext.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NotificationServiceExtensionContext.swift; sourceTree = ""; }; 7BFD1A892745C4F000FB91B9 /* Permissions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Permissions.swift; sourceTree = ""; }; + 7BFD1A8B2747150E00FB91B9 /* TurnServerInfo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TurnServerInfo.swift; sourceTree = ""; }; 7DD180F770F8518B4E8796F2 /* Pods-SessionUtilitiesKit.app store release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SessionUtilitiesKit.app store release.xcconfig"; path = "Pods/Target Support Files/Pods-SessionUtilitiesKit/Pods-SessionUtilitiesKit.app store release.xcconfig"; sourceTree = ""; }; 8981C8F64D94D3C52EB67A2C /* Pods-SignalTests.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SignalTests.test.xcconfig"; path = "Pods/Target Support Files/Pods-SignalTests/Pods-SignalTests.test.xcconfig"; sourceTree = ""; }; 8EEE74B0753448C085B48721 /* Pods-SignalMessaging.app store release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SignalMessaging.app store release.xcconfig"; path = "Pods/Target Support Files/Pods-SignalMessaging/Pods-SignalMessaging.app store release.xcconfig"; sourceTree = ""; }; @@ -2423,6 +2425,7 @@ B8B558FE26C4E05E00693325 /* WebRTCSession+MessageHandling.swift */, B8BF43B926CC95FB007828D1 /* WebRTC+Utilities.swift */, 7BCD116B27016062006330F1 /* WebRTCSession+DataChannel.swift */, + 7BFD1A8B2747150E00FB91B9 /* TurnServerInfo.swift */, ); path = Calls; sourceTree = ""; @@ -4703,6 +4706,7 @@ C3C2A74D2553A39700C340D1 /* VisibleMessage.swift in Sources */, C32C5AAD256DBE8F003C73A2 /* TSInfoMessage.m in Sources */, C32C5A13256DB7A5003C73A2 /* PushNotificationAPI.swift in Sources */, + 7BFD1A8C2747150E00FB91B9 /* TurnServerInfo.swift in Sources */, C32A026325A801AA000ED5D4 /* NSData+messagePadding.m in Sources */, C352A3932557883D00338F3E /* JobDelegate.swift in Sources */, C32C5B84256DC54F003C73A2 /* SSKEnvironment.m in Sources */, diff --git a/SessionMessagingKit/Calls/TurnServerInfo.swift b/SessionMessagingKit/Calls/TurnServerInfo.swift new file mode 100644 index 000000000..9b1a47032 --- /dev/null +++ b/SessionMessagingKit/Calls/TurnServerInfo.swift @@ -0,0 +1,30 @@ +// Copyright © 2021 Rangeproof Pty Ltd. All rights reserved. + +import Foundation + +struct TurnServerInfo { + + let password: String + let username: String + let urls: [String] + + init?(attributes: JSON) { + if let passwordAttribute = (attributes["password"] as? String) { + password = passwordAttribute + } else { + return nil + } + + if let usernameAttribute = attributes["username"] as? String { + username = usernameAttribute + } else { + return nil + } + + if let urlsAttribute = attributes["urls"] as? [String] { + urls = urlsAttribute + } else { + return nil + } + } +} diff --git a/SessionMessagingKit/Calls/WebRTCSession.swift b/SessionMessagingKit/Calls/WebRTCSession.swift index 2e5c88ec2..65a6246eb 100644 --- a/SessionMessagingKit/Calls/WebRTCSession.swift +++ b/SessionMessagingKit/Calls/WebRTCSession.swift @@ -18,6 +18,13 @@ public final class WebRTCSession : NSObject, RTCPeerConnectionDelegate { private var queuedICECandidates: [RTCIceCandidate] = [] private var iceCandidateSendTimer: Timer? + private lazy var defaultICEServer: TurnServerInfo? = { + let url = Bundle.main.url(forResource: "Session-Turn-Server", withExtension: nil)! + let data = try! Data(contentsOf: url) + let json = try! JSONSerialization.jsonObject(with: data, options: [ .fragmentsAllowed ]) as! JSON + return TurnServerInfo(attributes: json) + }() + internal lazy var factory: RTCPeerConnectionFactory = { RTCInitializeSSL() let videoEncoderFactory = RTCDefaultVideoEncoderFactory() @@ -30,6 +37,9 @@ public final class WebRTCSession : NSObject, RTCPeerConnectionDelegate { internal lazy var peerConnection: RTCPeerConnection = { let configuration = RTCConfiguration() configuration.iceServers = [ RTCIceServer(urlStrings: ["stun:freyr.getsession.org:5349"]), RTCIceServer(urlStrings: ["turn:freyr.getsession.org"], username: "session", credential: "session") ] + if let defaultICEServer = defaultICEServer { + configuration.iceServers.append(RTCIceServer(urlStrings: defaultICEServer.urls, username: defaultICEServer.username, credential: defaultICEServer.password)) + } configuration.sdpSemantics = .unifiedPlan let constraints = RTCMediaConstraints(mandatoryConstraints: [:], optionalConstraints: [:]) return factory.peerConnection(with: configuration, constraints: constraints, delegate: self)