blob: 3fcc652e69b3d69b66c21d366e6223f4e787f6f7 [file] [log] [blame]
hjonf396f602016-02-11 16:19:06 -08001/*
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
tkchin9eeb6242016-04-27 01:54:20 -070011#import "RTCPeerConnection+Private.h"
12
13#import "NSString+StdString.h"
14#import "RTCConfiguration+Private.h"
15#import "RTCDataChannel+Private.h"
16#import "RTCIceCandidate+Private.h"
17#import "RTCMediaConstraints+Private.h"
18#import "RTCMediaStream+Private.h"
19#import "RTCPeerConnectionFactory+Private.h"
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -070020#import "RTCRtpReceiver+Private.h"
tkchin9eeb6242016-04-27 01:54:20 -070021#import "RTCRtpSender+Private.h"
22#import "RTCSessionDescription+Private.h"
23#import "RTCStatsReport+Private.h"
24#import "WebRTC/RTCLogging.h"
hjonf396f602016-02-11 16:19:06 -080025
kwibergbfefb032016-05-01 14:53:46 -070026#include <memory>
27
Honghai Zhangda2ba4d2016-05-23 11:53:14 -070028#include "webrtc/api/jsepicecandidate.h"
hjonf396f602016-02-11 16:19:06 -080029#include "webrtc/base/checks.h"
30
hjonf396f602016-02-11 16:19:06 -080031NSString * const kRTCPeerConnectionErrorDomain =
32 @"org.webrtc.RTCPeerConnection";
33int const kRTCPeerConnnectionSessionDescriptionError = -1;
34
35namespace webrtc {
36
37class CreateSessionDescriptionObserverAdapter
38 : public CreateSessionDescriptionObserver {
39 public:
40 CreateSessionDescriptionObserverAdapter(
41 void (^completionHandler)(RTCSessionDescription *sessionDescription,
42 NSError *error)) {
43 completion_handler_ = completionHandler;
44 }
45
46 ~CreateSessionDescriptionObserverAdapter() {
47 completion_handler_ = nil;
48 }
49
50 void OnSuccess(SessionDescriptionInterface *desc) override {
51 RTC_DCHECK(completion_handler_);
kwibergbfefb032016-05-01 14:53:46 -070052 std::unique_ptr<webrtc::SessionDescriptionInterface> description =
53 std::unique_ptr<webrtc::SessionDescriptionInterface>(desc);
hjonf396f602016-02-11 16:19:06 -080054 RTCSessionDescription* session =
55 [[RTCSessionDescription alloc] initWithNativeDescription:
56 description.get()];
57 completion_handler_(session, nil);
58 completion_handler_ = nil;
59 }
60
61 void OnFailure(const std::string& error) override {
62 RTC_DCHECK(completion_handler_);
63 NSString* str = [NSString stringForStdString:error];
64 NSError* err =
65 [NSError errorWithDomain:kRTCPeerConnectionErrorDomain
66 code:kRTCPeerConnnectionSessionDescriptionError
67 userInfo:@{ NSLocalizedDescriptionKey : str }];
68 completion_handler_(nil, err);
69 completion_handler_ = nil;
70 }
71
72 private:
73 void (^completion_handler_)
74 (RTCSessionDescription *sessionDescription, NSError *error);
75};
76
77class SetSessionDescriptionObserverAdapter :
78 public SetSessionDescriptionObserver {
79 public:
80 SetSessionDescriptionObserverAdapter(void (^completionHandler)
81 (NSError *error)) {
82 completion_handler_ = completionHandler;
83 }
84
85 ~SetSessionDescriptionObserverAdapter() {
86 completion_handler_ = nil;
87 }
88
89 void OnSuccess() override {
90 RTC_DCHECK(completion_handler_);
91 completion_handler_(nil);
92 completion_handler_ = nil;
93 }
94
95 void OnFailure(const std::string& error) override {
96 RTC_DCHECK(completion_handler_);
97 NSString* str = [NSString stringForStdString:error];
98 NSError* err =
99 [NSError errorWithDomain:kRTCPeerConnectionErrorDomain
100 code:kRTCPeerConnnectionSessionDescriptionError
101 userInfo:@{ NSLocalizedDescriptionKey : str }];
102 completion_handler_(err);
103 completion_handler_ = nil;
104 }
105
106 private:
107 void (^completion_handler_)(NSError *error);
108};
109
110PeerConnectionDelegateAdapter::PeerConnectionDelegateAdapter(
111 RTCPeerConnection *peerConnection) {
112 peer_connection_ = peerConnection;
113}
114
115PeerConnectionDelegateAdapter::~PeerConnectionDelegateAdapter() {
116 peer_connection_ = nil;
117}
118
119void PeerConnectionDelegateAdapter::OnSignalingChange(
120 PeerConnectionInterface::SignalingState new_state) {
121 RTCSignalingState state =
122 [[RTCPeerConnection class] signalingStateForNativeState:new_state];
123 RTCPeerConnection *peer_connection = peer_connection_;
124 [peer_connection.delegate peerConnection:peer_connection
125 didChangeSignalingState:state];
126}
127
128void PeerConnectionDelegateAdapter::OnAddStream(
129 MediaStreamInterface *stream) {
130 RTCMediaStream *mediaStream =
131 [[RTCMediaStream alloc] initWithNativeMediaStream:stream];
132 RTCPeerConnection *peer_connection = peer_connection_;
133 [peer_connection.delegate peerConnection:peer_connection
134 didAddStream:mediaStream];
135}
136
137void PeerConnectionDelegateAdapter::OnRemoveStream(
138 MediaStreamInterface *stream) {
139 RTCMediaStream *mediaStream =
140 [[RTCMediaStream alloc] initWithNativeMediaStream:stream];
141 RTCPeerConnection *peer_connection = peer_connection_;
142 [peer_connection.delegate peerConnection:peer_connection
143 didRemoveStream:mediaStream];
144}
145
146void PeerConnectionDelegateAdapter::OnDataChannel(
147 DataChannelInterface *data_channel) {
148 RTCDataChannel *dataChannel =
149 [[RTCDataChannel alloc] initWithNativeDataChannel:data_channel];
150 RTCPeerConnection *peer_connection = peer_connection_;
151 [peer_connection.delegate peerConnection:peer_connection
152 didOpenDataChannel:dataChannel];
153}
154
155void PeerConnectionDelegateAdapter::OnRenegotiationNeeded() {
156 RTCPeerConnection *peer_connection = peer_connection_;
157 [peer_connection.delegate peerConnectionShouldNegotiate:peer_connection];
158}
159
160void PeerConnectionDelegateAdapter::OnIceConnectionChange(
161 PeerConnectionInterface::IceConnectionState new_state) {
162 RTCIceConnectionState state =
163 [[RTCPeerConnection class] iceConnectionStateForNativeState:new_state];
164 RTCPeerConnection *peer_connection = peer_connection_;
165 [peer_connection.delegate peerConnection:peer_connection
166 didChangeIceConnectionState:state];
167}
168
169void PeerConnectionDelegateAdapter::OnIceGatheringChange(
170 PeerConnectionInterface::IceGatheringState new_state) {
171 RTCIceGatheringState state =
172 [[RTCPeerConnection class] iceGatheringStateForNativeState:new_state];
173 RTCPeerConnection *peer_connection = peer_connection_;
174 [peer_connection.delegate peerConnection:peer_connection
175 didChangeIceGatheringState:state];
176}
177
178void PeerConnectionDelegateAdapter::OnIceCandidate(
179 const IceCandidateInterface *candidate) {
180 RTCIceCandidate *iceCandidate =
181 [[RTCIceCandidate alloc] initWithNativeCandidate:candidate];
182 RTCPeerConnection *peer_connection = peer_connection_;
183 [peer_connection.delegate peerConnection:peer_connection
184 didGenerateIceCandidate:iceCandidate];
185}
Honghai Zhangda2ba4d2016-05-23 11:53:14 -0700186
187void PeerConnectionDelegateAdapter::OnIceCandidatesRemoved(
188 const std::vector<cricket::Candidate>& candidates) {
189 NSMutableArray* ice_candidates =
190 [NSMutableArray arrayWithCapacity:candidates.size()];
191 for (const auto& candidate : candidates) {
192 std::unique_ptr<JsepIceCandidate> candidate_wrapper(
193 new JsepIceCandidate(candidate.transport_name(), -1, candidate));
194 RTCIceCandidate* ice_candidate = [[RTCIceCandidate alloc]
195 initWithNativeCandidate:candidate_wrapper.get()];
196 [ice_candidates addObject:ice_candidate];
197 }
198 RTCPeerConnection* peer_connection = peer_connection_;
199 [peer_connection.delegate peerConnection:peer_connection
200 didRemoveIceCandidates:ice_candidates];
201}
202
hjonf396f602016-02-11 16:19:06 -0800203} // namespace webrtc
204
205
206@implementation RTCPeerConnection {
207 NSMutableArray *_localStreams;
kwibergbfefb032016-05-01 14:53:46 -0700208 std::unique_ptr<webrtc::PeerConnectionDelegateAdapter> _observer;
hjonf396f602016-02-11 16:19:06 -0800209 rtc::scoped_refptr<webrtc::PeerConnectionInterface> _peerConnection;
210}
211
212@synthesize delegate = _delegate;
213
214- (instancetype)initWithFactory:(RTCPeerConnectionFactory *)factory
215 configuration:(RTCConfiguration *)configuration
216 constraints:(RTCMediaConstraints *)constraints
217 delegate:(id<RTCPeerConnectionDelegate>)delegate {
218 NSParameterAssert(factory);
Henrik Boströme06c2dd2016-05-13 13:50:38 +0200219 std::unique_ptr<webrtc::PeerConnectionInterface::RTCConfiguration> config(
hbosa73ca562016-05-17 03:28:58 -0700220 [configuration createNativeConfiguration]);
221 if (!config) {
222 return nil;
223 }
hjonf396f602016-02-11 16:19:06 -0800224 if (self = [super init]) {
225 _observer.reset(new webrtc::PeerConnectionDelegateAdapter(self));
kwibergbfefb032016-05-01 14:53:46 -0700226 std::unique_ptr<webrtc::MediaConstraints> nativeConstraints =
hjona2f77982016-03-04 07:09:09 -0800227 constraints.nativeConstraints;
hjonf396f602016-02-11 16:19:06 -0800228 _peerConnection =
Henrik Boströme06c2dd2016-05-13 13:50:38 +0200229 factory.nativeFactory->CreatePeerConnection(*config,
hjona2f77982016-03-04 07:09:09 -0800230 nativeConstraints.get(),
hjonf396f602016-02-11 16:19:06 -0800231 nullptr,
232 nullptr,
233 _observer.get());
234 _localStreams = [[NSMutableArray alloc] init];
235 _delegate = delegate;
236 }
237 return self;
238}
239
240- (NSArray *)localStreams {
241 return [_localStreams copy];
242}
243
244- (RTCSessionDescription *)localDescription {
245 const webrtc::SessionDescriptionInterface *description =
246 _peerConnection->local_description();
247 return description ?
248 [[RTCSessionDescription alloc] initWithNativeDescription:description]
249 : nil;
250}
251
252- (RTCSessionDescription *)remoteDescription {
253 const webrtc::SessionDescriptionInterface *description =
254 _peerConnection->remote_description();
255 return description ?
256 [[RTCSessionDescription alloc] initWithNativeDescription:description]
257 : nil;
258}
259
260- (RTCSignalingState)signalingState {
261 return [[self class]
262 signalingStateForNativeState:_peerConnection->signaling_state()];
263}
264
265- (RTCIceConnectionState)iceConnectionState {
266 return [[self class] iceConnectionStateForNativeState:
267 _peerConnection->ice_connection_state()];
268}
269
270- (RTCIceGatheringState)iceGatheringState {
271 return [[self class] iceGatheringStateForNativeState:
272 _peerConnection->ice_gathering_state()];
273}
274
tkchinaac3eb22016-03-09 21:49:40 -0800275- (BOOL)setConfiguration:(RTCConfiguration *)configuration {
Henrik Boströme06c2dd2016-05-13 13:50:38 +0200276 std::unique_ptr<webrtc::PeerConnectionInterface::RTCConfiguration> config(
hbosa73ca562016-05-17 03:28:58 -0700277 [configuration createNativeConfiguration]);
278 if (!config) {
279 return NO;
280 }
Henrik Boströme06c2dd2016-05-13 13:50:38 +0200281 return _peerConnection->SetConfiguration(*config);
tkchinaac3eb22016-03-09 21:49:40 -0800282}
283
hjonf396f602016-02-11 16:19:06 -0800284- (void)close {
285 _peerConnection->Close();
286}
287
288- (void)addIceCandidate:(RTCIceCandidate *)candidate {
kwibergbfefb032016-05-01 14:53:46 -0700289 std::unique_ptr<const webrtc::IceCandidateInterface> iceCandidate(
hjonf396f602016-02-11 16:19:06 -0800290 candidate.nativeCandidate);
291 _peerConnection->AddIceCandidate(iceCandidate.get());
292}
293
Honghai Zhangda2ba4d2016-05-23 11:53:14 -0700294- (void)removeIceCandidates:(NSArray<RTCIceCandidate *> *)iceCandidates {
295 std::vector<cricket::Candidate> candidates;
296 for (RTCIceCandidate *iceCandidate in iceCandidates) {
297 std::unique_ptr<const webrtc::IceCandidateInterface> candidate(
298 iceCandidate.nativeCandidate);
299 if (candidate) {
300 candidates.push_back(candidate->candidate());
301 // Need to fill the transport name from the sdp_mid.
302 candidates.back().set_transport_name(candidate->sdp_mid());
303 }
304 }
305 if (!candidates.empty()) {
306 _peerConnection->RemoveIceCandidates(candidates);
307 }
308}
309
hjonf396f602016-02-11 16:19:06 -0800310- (void)addStream:(RTCMediaStream *)stream {
hjona2f77982016-03-04 07:09:09 -0800311 if (!_peerConnection->AddStream(stream.nativeMediaStream)) {
hjonf396f602016-02-11 16:19:06 -0800312 RTCLogError(@"Failed to add stream: %@", stream);
313 return;
314 }
315 [_localStreams addObject:stream];
316}
317
318- (void)removeStream:(RTCMediaStream *)stream {
319 _peerConnection->RemoveStream(stream.nativeMediaStream);
320 [_localStreams removeObject:stream];
321}
322
323- (void)offerForConstraints:(RTCMediaConstraints *)constraints
324 completionHandler:
325 (void (^)(RTCSessionDescription *sessionDescription,
326 NSError *error))completionHandler {
327 rtc::scoped_refptr<webrtc::CreateSessionDescriptionObserverAdapter>
328 observer(new rtc::RefCountedObject
329 <webrtc::CreateSessionDescriptionObserverAdapter>(completionHandler));
330 _peerConnection->CreateOffer(observer, constraints.nativeConstraints.get());
331}
332
333- (void)answerForConstraints:(RTCMediaConstraints *)constraints
334 completionHandler:
335 (void (^)(RTCSessionDescription *sessionDescription,
336 NSError *error))completionHandler {
337 rtc::scoped_refptr<webrtc::CreateSessionDescriptionObserverAdapter>
338 observer(new rtc::RefCountedObject
339 <webrtc::CreateSessionDescriptionObserverAdapter>(completionHandler));
340 _peerConnection->CreateAnswer(observer, constraints.nativeConstraints.get());
341}
342
343- (void)setLocalDescription:(RTCSessionDescription *)sdp
344 completionHandler:(void (^)(NSError *error))completionHandler {
345 rtc::scoped_refptr<webrtc::SetSessionDescriptionObserverAdapter> observer(
346 new rtc::RefCountedObject<webrtc::SetSessionDescriptionObserverAdapter>(
347 completionHandler));
348 _peerConnection->SetLocalDescription(observer, sdp.nativeDescription);
349}
350
351- (void)setRemoteDescription:(RTCSessionDescription *)sdp
352 completionHandler:(void (^)(NSError *error))completionHandler {
353 rtc::scoped_refptr<webrtc::SetSessionDescriptionObserverAdapter> observer(
354 new rtc::RefCountedObject<webrtc::SetSessionDescriptionObserverAdapter>(
355 completionHandler));
356 _peerConnection->SetRemoteDescription(observer, sdp.nativeDescription);
357}
358
skvladf3569c82016-04-29 15:30:16 -0700359- (RTCRtpSender *)senderWithKind:(NSString *)kind
360 streamId:(NSString *)streamId {
361 std::string nativeKind = [NSString stdStringForString:kind];
362 std::string nativeStreamId = [NSString stdStringForString:streamId];
363 rtc::scoped_refptr<webrtc::RtpSenderInterface> nativeSender(
364 _peerConnection->CreateSender(nativeKind, nativeStreamId));
365 return nativeSender ?
366 [[RTCRtpSender alloc] initWithNativeRtpSender:nativeSender]
367 : nil;
368}
369
skvlad79b4b872016-04-08 17:28:55 -0700370- (NSArray<RTCRtpSender *> *)senders {
371 std::vector<rtc::scoped_refptr<webrtc::RtpSenderInterface>> nativeSenders(
372 _peerConnection->GetSenders());
373 NSMutableArray *senders = [[NSMutableArray alloc] init];
374 for (const auto &nativeSender : nativeSenders) {
375 RTCRtpSender *sender =
376 [[RTCRtpSender alloc] initWithNativeRtpSender:nativeSender];
377 [senders addObject:sender];
378 }
379 return senders;
380}
381
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700382- (NSArray<RTCRtpReceiver *> *)receivers {
383 std::vector<rtc::scoped_refptr<webrtc::RtpReceiverInterface>> nativeReceivers(
384 _peerConnection->GetReceivers());
385 NSMutableArray *receivers = [[NSMutableArray alloc] init];
386 for (const auto &nativeReceiver : nativeReceivers) {
387 RTCRtpReceiver *receiver =
388 [[RTCRtpReceiver alloc] initWithNativeRtpReceiver:nativeReceiver];
389 [receivers addObject:receiver];
390 }
391 return receivers;
392}
393
hjonf396f602016-02-11 16:19:06 -0800394#pragma mark - Private
395
396+ (webrtc::PeerConnectionInterface::SignalingState)nativeSignalingStateForState:
397 (RTCSignalingState)state {
398 switch (state) {
399 case RTCSignalingStateStable:
400 return webrtc::PeerConnectionInterface::kStable;
401 case RTCSignalingStateHaveLocalOffer:
402 return webrtc::PeerConnectionInterface::kHaveLocalOffer;
403 case RTCSignalingStateHaveLocalPrAnswer:
404 return webrtc::PeerConnectionInterface::kHaveLocalPrAnswer;
405 case RTCSignalingStateHaveRemoteOffer:
406 return webrtc::PeerConnectionInterface::kHaveRemoteOffer;
407 case RTCSignalingStateHaveRemotePrAnswer:
408 return webrtc::PeerConnectionInterface::kHaveRemotePrAnswer;
409 case RTCSignalingStateClosed:
410 return webrtc::PeerConnectionInterface::kClosed;
411 }
412}
413
414+ (RTCSignalingState)signalingStateForNativeState:
415 (webrtc::PeerConnectionInterface::SignalingState)nativeState {
416 switch (nativeState) {
417 case webrtc::PeerConnectionInterface::kStable:
418 return RTCSignalingStateStable;
419 case webrtc::PeerConnectionInterface::kHaveLocalOffer:
420 return RTCSignalingStateHaveLocalOffer;
421 case webrtc::PeerConnectionInterface::kHaveLocalPrAnswer:
422 return RTCSignalingStateHaveLocalPrAnswer;
423 case webrtc::PeerConnectionInterface::kHaveRemoteOffer:
424 return RTCSignalingStateHaveRemoteOffer;
425 case webrtc::PeerConnectionInterface::kHaveRemotePrAnswer:
426 return RTCSignalingStateHaveRemotePrAnswer;
427 case webrtc::PeerConnectionInterface::kClosed:
428 return RTCSignalingStateClosed;
429 }
430}
431
432+ (NSString *)stringForSignalingState:(RTCSignalingState)state {
433 switch (state) {
434 case RTCSignalingStateStable:
435 return @"STABLE";
436 case RTCSignalingStateHaveLocalOffer:
437 return @"HAVE_LOCAL_OFFER";
438 case RTCSignalingStateHaveLocalPrAnswer:
439 return @"HAVE_LOCAL_PRANSWER";
440 case RTCSignalingStateHaveRemoteOffer:
441 return @"HAVE_REMOTE_OFFER";
442 case RTCSignalingStateHaveRemotePrAnswer:
443 return @"HAVE_REMOTE_PRANSWER";
444 case RTCSignalingStateClosed:
445 return @"CLOSED";
446 }
447}
448
449+ (webrtc::PeerConnectionInterface::IceConnectionState)
450 nativeIceConnectionStateForState:(RTCIceConnectionState)state {
451 switch (state) {
452 case RTCIceConnectionStateNew:
453 return webrtc::PeerConnectionInterface::kIceConnectionNew;
454 case RTCIceConnectionStateChecking:
455 return webrtc::PeerConnectionInterface::kIceConnectionChecking;
456 case RTCIceConnectionStateConnected:
457 return webrtc::PeerConnectionInterface::kIceConnectionConnected;
458 case RTCIceConnectionStateCompleted:
459 return webrtc::PeerConnectionInterface::kIceConnectionCompleted;
460 case RTCIceConnectionStateFailed:
461 return webrtc::PeerConnectionInterface::kIceConnectionFailed;
462 case RTCIceConnectionStateDisconnected:
463 return webrtc::PeerConnectionInterface::kIceConnectionDisconnected;
464 case RTCIceConnectionStateClosed:
465 return webrtc::PeerConnectionInterface::kIceConnectionClosed;
hjon8bbbf2c2016-03-14 13:15:44 -0700466 case RTCIceConnectionStateCount:
hjonf396f602016-02-11 16:19:06 -0800467 return webrtc::PeerConnectionInterface::kIceConnectionMax;
468 }
469}
470
471+ (RTCIceConnectionState)iceConnectionStateForNativeState:
472 (webrtc::PeerConnectionInterface::IceConnectionState)nativeState {
473 switch (nativeState) {
474 case webrtc::PeerConnectionInterface::kIceConnectionNew:
475 return RTCIceConnectionStateNew;
476 case webrtc::PeerConnectionInterface::kIceConnectionChecking:
477 return RTCIceConnectionStateChecking;
478 case webrtc::PeerConnectionInterface::kIceConnectionConnected:
479 return RTCIceConnectionStateConnected;
480 case webrtc::PeerConnectionInterface::kIceConnectionCompleted:
481 return RTCIceConnectionStateCompleted;
482 case webrtc::PeerConnectionInterface::kIceConnectionFailed:
483 return RTCIceConnectionStateFailed;
484 case webrtc::PeerConnectionInterface::kIceConnectionDisconnected:
485 return RTCIceConnectionStateDisconnected;
486 case webrtc::PeerConnectionInterface::kIceConnectionClosed:
487 return RTCIceConnectionStateClosed;
488 case webrtc::PeerConnectionInterface::kIceConnectionMax:
hjon8bbbf2c2016-03-14 13:15:44 -0700489 return RTCIceConnectionStateCount;
hjonf396f602016-02-11 16:19:06 -0800490 }
491}
492
493+ (NSString *)stringForIceConnectionState:(RTCIceConnectionState)state {
494 switch (state) {
495 case RTCIceConnectionStateNew:
496 return @"NEW";
497 case RTCIceConnectionStateChecking:
498 return @"CHECKING";
499 case RTCIceConnectionStateConnected:
500 return @"CONNECTED";
501 case RTCIceConnectionStateCompleted:
502 return @"COMPLETED";
503 case RTCIceConnectionStateFailed:
504 return @"FAILED";
505 case RTCIceConnectionStateDisconnected:
506 return @"DISCONNECTED";
507 case RTCIceConnectionStateClosed:
508 return @"CLOSED";
hjon8bbbf2c2016-03-14 13:15:44 -0700509 case RTCIceConnectionStateCount:
510 return @"COUNT";
hjonf396f602016-02-11 16:19:06 -0800511 }
512}
513
514+ (webrtc::PeerConnectionInterface::IceGatheringState)
515 nativeIceGatheringStateForState:(RTCIceGatheringState)state {
516 switch (state) {
517 case RTCIceGatheringStateNew:
518 return webrtc::PeerConnectionInterface::kIceGatheringNew;
519 case RTCIceGatheringStateGathering:
520 return webrtc::PeerConnectionInterface::kIceGatheringGathering;
521 case RTCIceGatheringStateComplete:
522 return webrtc::PeerConnectionInterface::kIceGatheringComplete;
523 }
524}
525
526+ (RTCIceGatheringState)iceGatheringStateForNativeState:
527 (webrtc::PeerConnectionInterface::IceGatheringState)nativeState {
528 switch (nativeState) {
529 case webrtc::PeerConnectionInterface::kIceGatheringNew:
530 return RTCIceGatheringStateNew;
531 case webrtc::PeerConnectionInterface::kIceGatheringGathering:
532 return RTCIceGatheringStateGathering;
533 case webrtc::PeerConnectionInterface::kIceGatheringComplete:
534 return RTCIceGatheringStateComplete;
535 }
536}
537
538+ (NSString *)stringForIceGatheringState:(RTCIceGatheringState)state {
539 switch (state) {
540 case RTCIceGatheringStateNew:
541 return @"NEW";
542 case RTCIceGatheringStateGathering:
543 return @"GATHERING";
544 case RTCIceGatheringStateComplete:
545 return @"COMPLETE";
546 }
547}
548
549+ (webrtc::PeerConnectionInterface::StatsOutputLevel)
550 nativeStatsOutputLevelForLevel:(RTCStatsOutputLevel)level {
551 switch (level) {
552 case RTCStatsOutputLevelStandard:
553 return webrtc::PeerConnectionInterface::kStatsOutputLevelStandard;
554 case RTCStatsOutputLevelDebug:
555 return webrtc::PeerConnectionInterface::kStatsOutputLevelDebug;
556 }
557}
558
559- (rtc::scoped_refptr<webrtc::PeerConnectionInterface>)nativePeerConnection {
560 return _peerConnection;
561}
562
563@end