1/* 2 * Copyright 2015 The WebRTC project authors. All Rights Reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11#import "RTCConfiguration+Private.h" 12 13#include <memory> 14 15#import "RTCCertificate.h" 16#import "RTCConfiguration+Native.h" 17#import "RTCIceServer+Private.h" 18#import "base/RTCLogging.h" 19 20#include "rtc_base/checks.h" 21#include "rtc_base/rtc_certificate_generator.h" 22#include "rtc_base/ssl_identity.h" 23 24@implementation RTC_OBJC_TYPE (RTCConfiguration) 25 26@synthesize enableDscp = _enableDscp; 27@synthesize iceServers = _iceServers; 28@synthesize certificate = _certificate; 29@synthesize iceTransportPolicy = _iceTransportPolicy; 30@synthesize bundlePolicy = _bundlePolicy; 31@synthesize rtcpMuxPolicy = _rtcpMuxPolicy; 32@synthesize tcpCandidatePolicy = _tcpCandidatePolicy; 33@synthesize candidateNetworkPolicy = _candidateNetworkPolicy; 34@synthesize continualGatheringPolicy = _continualGatheringPolicy; 35@synthesize disableIPV6OnWiFi = _disableIPV6OnWiFi; 36@synthesize maxIPv6Networks = _maxIPv6Networks; 37@synthesize disableLinkLocalNetworks = _disableLinkLocalNetworks; 38@synthesize audioJitterBufferMaxPackets = _audioJitterBufferMaxPackets; 39@synthesize audioJitterBufferFastAccelerate = _audioJitterBufferFastAccelerate; 40@synthesize iceConnectionReceivingTimeout = _iceConnectionReceivingTimeout; 41@synthesize iceBackupCandidatePairPingInterval = 42 _iceBackupCandidatePairPingInterval; 43@synthesize keyType = _keyType; 44@synthesize iceCandidatePoolSize = _iceCandidatePoolSize; 45@synthesize shouldPruneTurnPorts = _shouldPruneTurnPorts; 46@synthesize shouldPresumeWritableWhenFullyRelayed = 47 _shouldPresumeWritableWhenFullyRelayed; 48@synthesize shouldSurfaceIceCandidatesOnIceTransportTypeChanged = 49 _shouldSurfaceIceCandidatesOnIceTransportTypeChanged; 50@synthesize iceCheckMinInterval = _iceCheckMinInterval; 51@synthesize sdpSemantics = _sdpSemantics; 52@synthesize turnCustomizer = _turnCustomizer; 53@synthesize activeResetSrtpParams = _activeResetSrtpParams; 54@synthesize allowCodecSwitching = _allowCodecSwitching; 55@synthesize cryptoOptions = _cryptoOptions; 56@synthesize turnLoggingId = _turnLoggingId; 57@synthesize rtcpAudioReportIntervalMs = _rtcpAudioReportIntervalMs; 58@synthesize rtcpVideoReportIntervalMs = _rtcpVideoReportIntervalMs; 59@synthesize enableImplicitRollback = _enableImplicitRollback; 60@synthesize offerExtmapAllowMixed = _offerExtmapAllowMixed; 61@synthesize iceCheckIntervalStrongConnectivity = _iceCheckIntervalStrongConnectivity; 62@synthesize iceCheckIntervalWeakConnectivity = _iceCheckIntervalWeakConnectivity; 63@synthesize iceUnwritableTimeout = _iceUnwritableTimeout; 64@synthesize iceUnwritableMinChecks = _iceUnwritableMinChecks; 65@synthesize iceInactiveTimeout = _iceInactiveTimeout; 66 67- (instancetype)init { 68 // Copy defaults. 69 webrtc::PeerConnectionInterface::RTCConfiguration config; 70 config.sdp_semantics = webrtc::SdpSemantics::kUnifiedPlan; 71 return [self initWithNativeConfiguration:config]; 72} 73 74- (instancetype)initWithNativeConfiguration: 75 (const webrtc::PeerConnectionInterface::RTCConfiguration &)config { 76 if (self = [super init]) { 77 _enableDscp = config.dscp(); 78 NSMutableArray *iceServers = [NSMutableArray array]; 79 for (const webrtc::PeerConnectionInterface::IceServer& server : config.servers) { 80 RTC_OBJC_TYPE(RTCIceServer) *iceServer = 81 [[RTC_OBJC_TYPE(RTCIceServer) alloc] initWithNativeServer:server]; 82 [iceServers addObject:iceServer]; 83 } 84 _iceServers = iceServers; 85 if (!config.certificates.empty()) { 86 rtc::scoped_refptr<rtc::RTCCertificate> native_cert; 87 native_cert = config.certificates[0]; 88 rtc::RTCCertificatePEM native_pem = native_cert->ToPEM(); 89 _certificate = [[RTC_OBJC_TYPE(RTCCertificate) alloc] 90 initWithPrivateKey:@(native_pem.private_key().c_str()) 91 certificate:@(native_pem.certificate().c_str())]; 92 } 93 _iceTransportPolicy = 94 [[self class] transportPolicyForTransportsType:config.type]; 95 _bundlePolicy = 96 [[self class] bundlePolicyForNativePolicy:config.bundle_policy]; 97 _rtcpMuxPolicy = 98 [[self class] rtcpMuxPolicyForNativePolicy:config.rtcp_mux_policy]; 99 _tcpCandidatePolicy = [[self class] tcpCandidatePolicyForNativePolicy: 100 config.tcp_candidate_policy]; 101 _candidateNetworkPolicy = [[self class] 102 candidateNetworkPolicyForNativePolicy:config.candidate_network_policy]; 103 webrtc::PeerConnectionInterface::ContinualGatheringPolicy nativePolicy = 104 config.continual_gathering_policy; 105 _continualGatheringPolicy = [[self class] continualGatheringPolicyForNativePolicy:nativePolicy]; 106 _disableIPV6OnWiFi = config.disable_ipv6_on_wifi; 107 _maxIPv6Networks = config.max_ipv6_networks; 108 _disableLinkLocalNetworks = config.disable_link_local_networks; 109 _audioJitterBufferMaxPackets = config.audio_jitter_buffer_max_packets; 110 _audioJitterBufferFastAccelerate = config.audio_jitter_buffer_fast_accelerate; 111 _iceConnectionReceivingTimeout = config.ice_connection_receiving_timeout; 112 _iceBackupCandidatePairPingInterval = 113 config.ice_backup_candidate_pair_ping_interval; 114 _keyType = RTCEncryptionKeyTypeECDSA; 115 _iceCandidatePoolSize = config.ice_candidate_pool_size; 116 _shouldPruneTurnPorts = config.prune_turn_ports; 117 _shouldPresumeWritableWhenFullyRelayed = 118 config.presume_writable_when_fully_relayed; 119 _shouldSurfaceIceCandidatesOnIceTransportTypeChanged = 120 config.surface_ice_candidates_on_ice_transport_type_changed; 121 if (config.ice_check_min_interval) { 122 _iceCheckMinInterval = 123 [NSNumber numberWithInt:*config.ice_check_min_interval]; 124 } 125 _sdpSemantics = [[self class] sdpSemanticsForNativeSdpSemantics:config.sdp_semantics]; 126 _turnCustomizer = config.turn_customizer; 127 _activeResetSrtpParams = config.active_reset_srtp_params; 128 if (config.crypto_options) { 129 _cryptoOptions = [[RTC_OBJC_TYPE(RTCCryptoOptions) alloc] 130 initWithSrtpEnableGcmCryptoSuites:config.crypto_options->srtp 131 .enable_gcm_crypto_suites 132 srtpEnableAes128Sha1_32CryptoCipher:config.crypto_options->srtp 133 .enable_aes128_sha1_32_crypto_cipher 134 srtpEnableEncryptedRtpHeaderExtensions:config.crypto_options->srtp 135 .enable_encrypted_rtp_header_extensions 136 sframeRequireFrameEncryption:config.crypto_options->sframe 137 .require_frame_encryption]; 138 } 139 _turnLoggingId = [NSString stringWithUTF8String:config.turn_logging_id.c_str()]; 140 _rtcpAudioReportIntervalMs = config.audio_rtcp_report_interval_ms(); 141 _rtcpVideoReportIntervalMs = config.video_rtcp_report_interval_ms(); 142 _allowCodecSwitching = config.allow_codec_switching.value_or(false); 143 _enableImplicitRollback = config.enable_implicit_rollback; 144 _offerExtmapAllowMixed = config.offer_extmap_allow_mixed; 145 _iceCheckIntervalStrongConnectivity = 146 config.ice_check_interval_strong_connectivity.has_value() ? 147 [NSNumber numberWithInt:*config.ice_check_interval_strong_connectivity] : 148 nil; 149 _iceCheckIntervalWeakConnectivity = config.ice_check_interval_weak_connectivity.has_value() ? 150 [NSNumber numberWithInt:*config.ice_check_interval_weak_connectivity] : 151 nil; 152 _iceUnwritableTimeout = config.ice_unwritable_timeout.has_value() ? 153 [NSNumber numberWithInt:*config.ice_unwritable_timeout] : 154 nil; 155 _iceUnwritableMinChecks = config.ice_unwritable_min_checks.has_value() ? 156 [NSNumber numberWithInt:*config.ice_unwritable_min_checks] : 157 nil; 158 _iceInactiveTimeout = config.ice_inactive_timeout.has_value() ? 159 [NSNumber numberWithInt:*config.ice_inactive_timeout] : 160 nil; 161 } 162 return self; 163} 164 165- (NSString *)description { 166 static NSString *formatString = @"RTC_OBJC_TYPE(RTCConfiguration): " 167 @"{\n%@\n%@\n%@\n%@\n%@\n%@\n%@\n%@\n%d\n%d\n%d\n%d\n%d\n%d\n" 168 @"%d\n%@\n%d\n%d\n%d\n%d\n%d\n%d\n%d\n}\n"; 169 170 return [NSString 171 stringWithFormat:formatString, 172 _iceServers, 173 [[self class] stringForTransportPolicy:_iceTransportPolicy], 174 [[self class] stringForBundlePolicy:_bundlePolicy], 175 [[self class] stringForRtcpMuxPolicy:_rtcpMuxPolicy], 176 [[self class] stringForTcpCandidatePolicy:_tcpCandidatePolicy], 177 [[self class] stringForCandidateNetworkPolicy:_candidateNetworkPolicy], 178 [[self class] stringForContinualGatheringPolicy:_continualGatheringPolicy], 179 [[self class] stringForSdpSemantics:_sdpSemantics], 180 _audioJitterBufferMaxPackets, 181 _audioJitterBufferFastAccelerate, 182 _iceConnectionReceivingTimeout, 183 _iceBackupCandidatePairPingInterval, 184 _iceCandidatePoolSize, 185 _shouldPruneTurnPorts, 186 _shouldPresumeWritableWhenFullyRelayed, 187 _shouldSurfaceIceCandidatesOnIceTransportTypeChanged, 188 _iceCheckMinInterval, 189 _disableLinkLocalNetworks, 190 _disableIPV6OnWiFi, 191 _maxIPv6Networks, 192 _activeResetSrtpParams, 193 _enableDscp, 194 _enableImplicitRollback]; 195} 196 197#pragma mark - Private 198 199- (webrtc::PeerConnectionInterface::RTCConfiguration *) 200 createNativeConfiguration { 201 std::unique_ptr<webrtc::PeerConnectionInterface::RTCConfiguration> 202 nativeConfig(new webrtc::PeerConnectionInterface::RTCConfiguration( 203 webrtc::PeerConnectionInterface::RTCConfigurationType::kAggressive)); 204 205 nativeConfig->set_dscp(_enableDscp); 206 for (RTC_OBJC_TYPE(RTCIceServer) * iceServer in _iceServers) { 207 nativeConfig->servers.push_back(iceServer.nativeServer); 208 } 209 nativeConfig->type = 210 [[self class] nativeTransportsTypeForTransportPolicy:_iceTransportPolicy]; 211 nativeConfig->bundle_policy = 212 [[self class] nativeBundlePolicyForPolicy:_bundlePolicy]; 213 nativeConfig->rtcp_mux_policy = 214 [[self class] nativeRtcpMuxPolicyForPolicy:_rtcpMuxPolicy]; 215 nativeConfig->tcp_candidate_policy = 216 [[self class] nativeTcpCandidatePolicyForPolicy:_tcpCandidatePolicy]; 217 nativeConfig->candidate_network_policy = [[self class] 218 nativeCandidateNetworkPolicyForPolicy:_candidateNetworkPolicy]; 219 nativeConfig->continual_gathering_policy = 220 [[self class] nativeContinualGatheringPolicyForPolicy:_continualGatheringPolicy]; 221 nativeConfig->disable_ipv6_on_wifi = _disableIPV6OnWiFi; 222 nativeConfig->max_ipv6_networks = _maxIPv6Networks; 223 nativeConfig->disable_link_local_networks = _disableLinkLocalNetworks; 224 nativeConfig->audio_jitter_buffer_max_packets = _audioJitterBufferMaxPackets; 225 nativeConfig->audio_jitter_buffer_fast_accelerate = 226 _audioJitterBufferFastAccelerate ? true : false; 227 nativeConfig->ice_connection_receiving_timeout = 228 _iceConnectionReceivingTimeout; 229 nativeConfig->ice_backup_candidate_pair_ping_interval = 230 _iceBackupCandidatePairPingInterval; 231 rtc::KeyType keyType = 232 [[self class] nativeEncryptionKeyTypeForKeyType:_keyType]; 233 if (_certificate != nullptr) { 234 // if offered a pemcert use it... 235 RTC_LOG(LS_INFO) << "Have configured cert - using it."; 236 std::string pem_private_key = [[_certificate private_key] UTF8String]; 237 std::string pem_certificate = [[_certificate certificate] UTF8String]; 238 rtc::RTCCertificatePEM pem = rtc::RTCCertificatePEM(pem_private_key, pem_certificate); 239 rtc::scoped_refptr<rtc::RTCCertificate> certificate = rtc::RTCCertificate::FromPEM(pem); 240 RTC_LOG(LS_INFO) << "Created cert from PEM strings."; 241 if (!certificate) { 242 RTC_LOG(LS_ERROR) << "Failed to generate certificate from PEM."; 243 return nullptr; 244 } 245 nativeConfig->certificates.push_back(certificate); 246 } else { 247 RTC_LOG(LS_INFO) << "Don't have configured cert."; 248 // Generate non-default certificate. 249 if (keyType != rtc::KT_DEFAULT) { 250 rtc::scoped_refptr<rtc::RTCCertificate> certificate = 251 rtc::RTCCertificateGenerator::GenerateCertificate(rtc::KeyParams(keyType), 252 absl::optional<uint64_t>()); 253 if (!certificate) { 254 RTCLogError(@"Failed to generate certificate."); 255 return nullptr; 256 } 257 nativeConfig->certificates.push_back(certificate); 258 } 259 } 260 nativeConfig->ice_candidate_pool_size = _iceCandidatePoolSize; 261 nativeConfig->prune_turn_ports = _shouldPruneTurnPorts ? true : false; 262 nativeConfig->presume_writable_when_fully_relayed = 263 _shouldPresumeWritableWhenFullyRelayed ? true : false; 264 nativeConfig->surface_ice_candidates_on_ice_transport_type_changed = 265 _shouldSurfaceIceCandidatesOnIceTransportTypeChanged ? true : false; 266 if (_iceCheckMinInterval != nil) { 267 nativeConfig->ice_check_min_interval = absl::optional<int>(_iceCheckMinInterval.intValue); 268 } 269 nativeConfig->sdp_semantics = [[self class] nativeSdpSemanticsForSdpSemantics:_sdpSemantics]; 270 if (_turnCustomizer) { 271 nativeConfig->turn_customizer = _turnCustomizer; 272 } 273 nativeConfig->active_reset_srtp_params = _activeResetSrtpParams ? true : false; 274 if (_cryptoOptions) { 275 webrtc::CryptoOptions nativeCryptoOptions; 276 nativeCryptoOptions.srtp.enable_gcm_crypto_suites = 277 _cryptoOptions.srtpEnableGcmCryptoSuites ? true : false; 278 nativeCryptoOptions.srtp.enable_aes128_sha1_32_crypto_cipher = 279 _cryptoOptions.srtpEnableAes128Sha1_32CryptoCipher ? true : false; 280 nativeCryptoOptions.srtp.enable_encrypted_rtp_header_extensions = 281 _cryptoOptions.srtpEnableEncryptedRtpHeaderExtensions ? true : false; 282 nativeCryptoOptions.sframe.require_frame_encryption = 283 _cryptoOptions.sframeRequireFrameEncryption ? true : false; 284 nativeConfig->crypto_options = absl::optional<webrtc::CryptoOptions>(nativeCryptoOptions); 285 } 286 nativeConfig->turn_logging_id = [_turnLoggingId UTF8String]; 287 nativeConfig->set_audio_rtcp_report_interval_ms(_rtcpAudioReportIntervalMs); 288 nativeConfig->set_video_rtcp_report_interval_ms(_rtcpVideoReportIntervalMs); 289 nativeConfig->allow_codec_switching = _allowCodecSwitching; 290 nativeConfig->enable_implicit_rollback = _enableImplicitRollback; 291 nativeConfig->offer_extmap_allow_mixed = _offerExtmapAllowMixed; 292 if (_iceCheckIntervalStrongConnectivity != nil) { 293 nativeConfig->ice_check_interval_strong_connectivity = 294 absl::optional<int>(_iceCheckIntervalStrongConnectivity.intValue); 295 } 296 if (_iceCheckIntervalWeakConnectivity != nil) { 297 nativeConfig->ice_check_interval_weak_connectivity = 298 absl::optional<int>(_iceCheckIntervalWeakConnectivity.intValue); 299 } 300 if (_iceUnwritableTimeout != nil) { 301 nativeConfig->ice_unwritable_timeout = absl::optional<int>(_iceUnwritableTimeout.intValue); 302 } 303 if (_iceUnwritableMinChecks != nil) { 304 nativeConfig->ice_unwritable_min_checks = absl::optional<int>(_iceUnwritableMinChecks.intValue); 305 } 306 if (_iceInactiveTimeout != nil) { 307 nativeConfig->ice_inactive_timeout = absl::optional<int>(_iceInactiveTimeout.intValue); 308 } 309 return nativeConfig.release(); 310} 311 312+ (webrtc::PeerConnectionInterface::IceTransportsType) 313 nativeTransportsTypeForTransportPolicy:(RTCIceTransportPolicy)policy { 314 switch (policy) { 315 case RTCIceTransportPolicyNone: 316 return webrtc::PeerConnectionInterface::kNone; 317 case RTCIceTransportPolicyRelay: 318 return webrtc::PeerConnectionInterface::kRelay; 319 case RTCIceTransportPolicyNoHost: 320 return webrtc::PeerConnectionInterface::kNoHost; 321 case RTCIceTransportPolicyAll: 322 return webrtc::PeerConnectionInterface::kAll; 323 } 324} 325 326+ (RTCIceTransportPolicy)transportPolicyForTransportsType: 327 (webrtc::PeerConnectionInterface::IceTransportsType)nativeType { 328 switch (nativeType) { 329 case webrtc::PeerConnectionInterface::kNone: 330 return RTCIceTransportPolicyNone; 331 case webrtc::PeerConnectionInterface::kRelay: 332 return RTCIceTransportPolicyRelay; 333 case webrtc::PeerConnectionInterface::kNoHost: 334 return RTCIceTransportPolicyNoHost; 335 case webrtc::PeerConnectionInterface::kAll: 336 return RTCIceTransportPolicyAll; 337 } 338} 339 340+ (NSString *)stringForTransportPolicy:(RTCIceTransportPolicy)policy { 341 switch (policy) { 342 case RTCIceTransportPolicyNone: 343 return @"NONE"; 344 case RTCIceTransportPolicyRelay: 345 return @"RELAY"; 346 case RTCIceTransportPolicyNoHost: 347 return @"NO_HOST"; 348 case RTCIceTransportPolicyAll: 349 return @"ALL"; 350 } 351} 352 353+ (webrtc::PeerConnectionInterface::BundlePolicy)nativeBundlePolicyForPolicy: 354 (RTCBundlePolicy)policy { 355 switch (policy) { 356 case RTCBundlePolicyBalanced: 357 return webrtc::PeerConnectionInterface::kBundlePolicyBalanced; 358 case RTCBundlePolicyMaxCompat: 359 return webrtc::PeerConnectionInterface::kBundlePolicyMaxCompat; 360 case RTCBundlePolicyMaxBundle: 361 return webrtc::PeerConnectionInterface::kBundlePolicyMaxBundle; 362 } 363} 364 365+ (RTCBundlePolicy)bundlePolicyForNativePolicy: 366 (webrtc::PeerConnectionInterface::BundlePolicy)nativePolicy { 367 switch (nativePolicy) { 368 case webrtc::PeerConnectionInterface::kBundlePolicyBalanced: 369 return RTCBundlePolicyBalanced; 370 case webrtc::PeerConnectionInterface::kBundlePolicyMaxCompat: 371 return RTCBundlePolicyMaxCompat; 372 case webrtc::PeerConnectionInterface::kBundlePolicyMaxBundle: 373 return RTCBundlePolicyMaxBundle; 374 } 375} 376 377+ (NSString *)stringForBundlePolicy:(RTCBundlePolicy)policy { 378 switch (policy) { 379 case RTCBundlePolicyBalanced: 380 return @"BALANCED"; 381 case RTCBundlePolicyMaxCompat: 382 return @"MAX_COMPAT"; 383 case RTCBundlePolicyMaxBundle: 384 return @"MAX_BUNDLE"; 385 } 386} 387 388+ (webrtc::PeerConnectionInterface::RtcpMuxPolicy)nativeRtcpMuxPolicyForPolicy: 389 (RTCRtcpMuxPolicy)policy { 390 switch (policy) { 391 case RTCRtcpMuxPolicyNegotiate: 392 return webrtc::PeerConnectionInterface::kRtcpMuxPolicyNegotiate; 393 case RTCRtcpMuxPolicyRequire: 394 return webrtc::PeerConnectionInterface::kRtcpMuxPolicyRequire; 395 } 396} 397 398+ (RTCRtcpMuxPolicy)rtcpMuxPolicyForNativePolicy: 399 (webrtc::PeerConnectionInterface::RtcpMuxPolicy)nativePolicy { 400 switch (nativePolicy) { 401 case webrtc::PeerConnectionInterface::kRtcpMuxPolicyNegotiate: 402 return RTCRtcpMuxPolicyNegotiate; 403 case webrtc::PeerConnectionInterface::kRtcpMuxPolicyRequire: 404 return RTCRtcpMuxPolicyRequire; 405 } 406} 407 408+ (NSString *)stringForRtcpMuxPolicy:(RTCRtcpMuxPolicy)policy { 409 switch (policy) { 410 case RTCRtcpMuxPolicyNegotiate: 411 return @"NEGOTIATE"; 412 case RTCRtcpMuxPolicyRequire: 413 return @"REQUIRE"; 414 } 415} 416 417+ (webrtc::PeerConnectionInterface::TcpCandidatePolicy) 418 nativeTcpCandidatePolicyForPolicy:(RTCTcpCandidatePolicy)policy { 419 switch (policy) { 420 case RTCTcpCandidatePolicyEnabled: 421 return webrtc::PeerConnectionInterface::kTcpCandidatePolicyEnabled; 422 case RTCTcpCandidatePolicyDisabled: 423 return webrtc::PeerConnectionInterface::kTcpCandidatePolicyDisabled; 424 } 425} 426 427+ (webrtc::PeerConnectionInterface::CandidateNetworkPolicy) 428 nativeCandidateNetworkPolicyForPolicy:(RTCCandidateNetworkPolicy)policy { 429 switch (policy) { 430 case RTCCandidateNetworkPolicyAll: 431 return webrtc::PeerConnectionInterface::kCandidateNetworkPolicyAll; 432 case RTCCandidateNetworkPolicyLowCost: 433 return webrtc::PeerConnectionInterface::kCandidateNetworkPolicyLowCost; 434 } 435} 436 437+ (RTCTcpCandidatePolicy)tcpCandidatePolicyForNativePolicy: 438 (webrtc::PeerConnectionInterface::TcpCandidatePolicy)nativePolicy { 439 switch (nativePolicy) { 440 case webrtc::PeerConnectionInterface::kTcpCandidatePolicyEnabled: 441 return RTCTcpCandidatePolicyEnabled; 442 case webrtc::PeerConnectionInterface::kTcpCandidatePolicyDisabled: 443 return RTCTcpCandidatePolicyDisabled; 444 } 445} 446 447+ (NSString *)stringForTcpCandidatePolicy:(RTCTcpCandidatePolicy)policy { 448 switch (policy) { 449 case RTCTcpCandidatePolicyEnabled: 450 return @"TCP_ENABLED"; 451 case RTCTcpCandidatePolicyDisabled: 452 return @"TCP_DISABLED"; 453 } 454} 455 456+ (RTCCandidateNetworkPolicy)candidateNetworkPolicyForNativePolicy: 457 (webrtc::PeerConnectionInterface::CandidateNetworkPolicy)nativePolicy { 458 switch (nativePolicy) { 459 case webrtc::PeerConnectionInterface::kCandidateNetworkPolicyAll: 460 return RTCCandidateNetworkPolicyAll; 461 case webrtc::PeerConnectionInterface::kCandidateNetworkPolicyLowCost: 462 return RTCCandidateNetworkPolicyLowCost; 463 } 464} 465 466+ (NSString *)stringForCandidateNetworkPolicy: 467 (RTCCandidateNetworkPolicy)policy { 468 switch (policy) { 469 case RTCCandidateNetworkPolicyAll: 470 return @"CANDIDATE_ALL_NETWORKS"; 471 case RTCCandidateNetworkPolicyLowCost: 472 return @"CANDIDATE_LOW_COST_NETWORKS"; 473 } 474} 475 476+ (webrtc::PeerConnectionInterface::ContinualGatheringPolicy) 477 nativeContinualGatheringPolicyForPolicy: 478 (RTCContinualGatheringPolicy)policy { 479 switch (policy) { 480 case RTCContinualGatheringPolicyGatherOnce: 481 return webrtc::PeerConnectionInterface::GATHER_ONCE; 482 case RTCContinualGatheringPolicyGatherContinually: 483 return webrtc::PeerConnectionInterface::GATHER_CONTINUALLY; 484 } 485} 486 487+ (RTCContinualGatheringPolicy)continualGatheringPolicyForNativePolicy: 488 (webrtc::PeerConnectionInterface::ContinualGatheringPolicy)nativePolicy { 489 switch (nativePolicy) { 490 case webrtc::PeerConnectionInterface::GATHER_ONCE: 491 return RTCContinualGatheringPolicyGatherOnce; 492 case webrtc::PeerConnectionInterface::GATHER_CONTINUALLY: 493 return RTCContinualGatheringPolicyGatherContinually; 494 } 495} 496 497+ (NSString *)stringForContinualGatheringPolicy: 498 (RTCContinualGatheringPolicy)policy { 499 switch (policy) { 500 case RTCContinualGatheringPolicyGatherOnce: 501 return @"GATHER_ONCE"; 502 case RTCContinualGatheringPolicyGatherContinually: 503 return @"GATHER_CONTINUALLY"; 504 } 505} 506 507+ (rtc::KeyType)nativeEncryptionKeyTypeForKeyType: 508 (RTCEncryptionKeyType)keyType { 509 switch (keyType) { 510 case RTCEncryptionKeyTypeRSA: 511 return rtc::KT_RSA; 512 case RTCEncryptionKeyTypeECDSA: 513 return rtc::KT_ECDSA; 514 } 515} 516 517+ (webrtc::SdpSemantics)nativeSdpSemanticsForSdpSemantics:(RTCSdpSemantics)sdpSemantics { 518 switch (sdpSemantics) { 519 case RTCSdpSemanticsPlanB: 520 return webrtc::SdpSemantics::kPlanB_DEPRECATED; 521 case RTCSdpSemanticsUnifiedPlan: 522 return webrtc::SdpSemantics::kUnifiedPlan; 523 } 524} 525 526+ (RTCSdpSemantics)sdpSemanticsForNativeSdpSemantics:(webrtc::SdpSemantics)sdpSemantics { 527 switch (sdpSemantics) { 528 case webrtc::SdpSemantics::kPlanB_DEPRECATED: 529 return RTCSdpSemanticsPlanB; 530 case webrtc::SdpSemantics::kUnifiedPlan: 531 return RTCSdpSemanticsUnifiedPlan; 532 } 533} 534 535+ (NSString *)stringForSdpSemantics:(RTCSdpSemantics)sdpSemantics { 536 switch (sdpSemantics) { 537 case RTCSdpSemanticsPlanB: 538 return @"PLAN_B"; 539 case RTCSdpSemanticsUnifiedPlan: 540 return @"UNIFIED_PLAN"; 541 } 542} 543 544@end 545