xref: /aosp_15_r20/external/webrtc/sdk/objc/api/peerconnection/RTCConfiguration.mm (revision d9f758449e529ab9291ac668be2861e7a55c2422)
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