blob: 08b90479e445ebb1d2de1bb129e52e661368257c [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"
hbosbd3dda62016-09-09 01:36:28 -070017#import "RTCLegacyStatsReport+Private.h"
tkchin9eeb6242016-04-27 01:54:20 -070018#import "RTCMediaConstraints+Private.h"
19#import "RTCMediaStream+Private.h"
Steve Anton8cb344a2018-02-27 15:34:53 -080020#import "RTCMediaStreamTrack+Private.h"
Magnus Jedvert0af86d12017-10-28 16:26:55 +020021#import "RTCPeerConnection+Native.h"
tkchin9eeb6242016-04-27 01:54:20 -070022#import "RTCPeerConnectionFactory+Private.h"
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -070023#import "RTCRtpReceiver+Private.h"
tkchin9eeb6242016-04-27 01:54:20 -070024#import "RTCRtpSender+Private.h"
Steve Anton8cb344a2018-02-27 15:34:53 -080025#import "RTCRtpTransceiver+Private.h"
tkchin9eeb6242016-04-27 01:54:20 -070026#import "RTCSessionDescription+Private.h"
tkchin9eeb6242016-04-27 01:54:20 -070027#import "WebRTC/RTCLogging.h"
hjonf396f602016-02-11 16:19:06 -080028
kwibergbfefb032016-05-01 14:53:46 -070029#include <memory>
30
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020031#include "api/jsepicecandidate.h"
32#include "rtc_base/checks.h"
hjonf396f602016-02-11 16:19:06 -080033
hjonf396f602016-02-11 16:19:06 -080034NSString * const kRTCPeerConnectionErrorDomain =
35 @"org.webrtc.RTCPeerConnection";
36int const kRTCPeerConnnectionSessionDescriptionError = -1;
37
38namespace webrtc {
39
40class CreateSessionDescriptionObserverAdapter
41 : public CreateSessionDescriptionObserver {
42 public:
43 CreateSessionDescriptionObserverAdapter(
44 void (^completionHandler)(RTCSessionDescription *sessionDescription,
45 NSError *error)) {
46 completion_handler_ = completionHandler;
47 }
48
49 ~CreateSessionDescriptionObserverAdapter() {
50 completion_handler_ = nil;
51 }
52
53 void OnSuccess(SessionDescriptionInterface *desc) override {
54 RTC_DCHECK(completion_handler_);
kwibergbfefb032016-05-01 14:53:46 -070055 std::unique_ptr<webrtc::SessionDescriptionInterface> description =
56 std::unique_ptr<webrtc::SessionDescriptionInterface>(desc);
hjonf396f602016-02-11 16:19:06 -080057 RTCSessionDescription* session =
58 [[RTCSessionDescription alloc] initWithNativeDescription:
59 description.get()];
60 completion_handler_(session, nil);
61 completion_handler_ = nil;
62 }
63
64 void OnFailure(const std::string& error) override {
65 RTC_DCHECK(completion_handler_);
66 NSString* str = [NSString stringForStdString:error];
67 NSError* err =
68 [NSError errorWithDomain:kRTCPeerConnectionErrorDomain
69 code:kRTCPeerConnnectionSessionDescriptionError
70 userInfo:@{ NSLocalizedDescriptionKey : str }];
71 completion_handler_(nil, err);
72 completion_handler_ = nil;
73 }
74
75 private:
76 void (^completion_handler_)
77 (RTCSessionDescription *sessionDescription, NSError *error);
78};
79
80class SetSessionDescriptionObserverAdapter :
81 public SetSessionDescriptionObserver {
82 public:
83 SetSessionDescriptionObserverAdapter(void (^completionHandler)
84 (NSError *error)) {
85 completion_handler_ = completionHandler;
86 }
87
88 ~SetSessionDescriptionObserverAdapter() {
89 completion_handler_ = nil;
90 }
91
92 void OnSuccess() override {
93 RTC_DCHECK(completion_handler_);
94 completion_handler_(nil);
95 completion_handler_ = nil;
96 }
97
98 void OnFailure(const std::string& error) override {
99 RTC_DCHECK(completion_handler_);
100 NSString* str = [NSString stringForStdString:error];
101 NSError* err =
102 [NSError errorWithDomain:kRTCPeerConnectionErrorDomain
103 code:kRTCPeerConnnectionSessionDescriptionError
104 userInfo:@{ NSLocalizedDescriptionKey : str }];
105 completion_handler_(err);
106 completion_handler_ = nil;
107 }
108
109 private:
110 void (^completion_handler_)(NSError *error);
111};
112
113PeerConnectionDelegateAdapter::PeerConnectionDelegateAdapter(
114 RTCPeerConnection *peerConnection) {
115 peer_connection_ = peerConnection;
116}
117
118PeerConnectionDelegateAdapter::~PeerConnectionDelegateAdapter() {
119 peer_connection_ = nil;
120}
121
122void PeerConnectionDelegateAdapter::OnSignalingChange(
123 PeerConnectionInterface::SignalingState new_state) {
124 RTCSignalingState state =
125 [[RTCPeerConnection class] signalingStateForNativeState:new_state];
126 RTCPeerConnection *peer_connection = peer_connection_;
127 [peer_connection.delegate peerConnection:peer_connection
128 didChangeSignalingState:state];
129}
130
131void PeerConnectionDelegateAdapter::OnAddStream(
deadbeefd5f41ce2016-06-08 13:31:45 -0700132 rtc::scoped_refptr<MediaStreamInterface> stream) {
magjed63bafd62017-02-27 07:04:25 -0800133 RTCMediaStream *mediaStream =
134 [[RTCMediaStream alloc] initWithNativeMediaStream:stream];
hjonf396f602016-02-11 16:19:06 -0800135 RTCPeerConnection *peer_connection = peer_connection_;
136 [peer_connection.delegate peerConnection:peer_connection
137 didAddStream:mediaStream];
138}
139
140void PeerConnectionDelegateAdapter::OnRemoveStream(
deadbeefd5f41ce2016-06-08 13:31:45 -0700141 rtc::scoped_refptr<MediaStreamInterface> stream) {
hjonf396f602016-02-11 16:19:06 -0800142 RTCMediaStream *mediaStream =
143 [[RTCMediaStream alloc] initWithNativeMediaStream:stream];
144 RTCPeerConnection *peer_connection = peer_connection_;
145 [peer_connection.delegate peerConnection:peer_connection
146 didRemoveStream:mediaStream];
147}
148
Steve Anton8cb344a2018-02-27 15:34:53 -0800149void PeerConnectionDelegateAdapter::OnTrack(
150 rtc::scoped_refptr<RtpTransceiverInterface> nativeTransceiver) {
151 RTCRtpTransceiver *transceiver =
152 [[RTCRtpTransceiver alloc] initWithNativeRtpTransceiver:nativeTransceiver];
153 RTCPeerConnection *peer_connection = peer_connection_;
154 if ([peer_connection.delegate
155 respondsToSelector:@selector(peerConnection:didStartReceivingOnTransceiver:)]) {
156 [peer_connection.delegate peerConnection:peer_connection
157 didStartReceivingOnTransceiver:transceiver];
158 }
159}
160
hjonf396f602016-02-11 16:19:06 -0800161void PeerConnectionDelegateAdapter::OnDataChannel(
deadbeefd5f41ce2016-06-08 13:31:45 -0700162 rtc::scoped_refptr<DataChannelInterface> data_channel) {
hjonf396f602016-02-11 16:19:06 -0800163 RTCDataChannel *dataChannel =
164 [[RTCDataChannel alloc] initWithNativeDataChannel:data_channel];
165 RTCPeerConnection *peer_connection = peer_connection_;
166 [peer_connection.delegate peerConnection:peer_connection
167 didOpenDataChannel:dataChannel];
168}
169
170void PeerConnectionDelegateAdapter::OnRenegotiationNeeded() {
171 RTCPeerConnection *peer_connection = peer_connection_;
172 [peer_connection.delegate peerConnectionShouldNegotiate:peer_connection];
173}
174
175void PeerConnectionDelegateAdapter::OnIceConnectionChange(
176 PeerConnectionInterface::IceConnectionState new_state) {
177 RTCIceConnectionState state =
178 [[RTCPeerConnection class] iceConnectionStateForNativeState:new_state];
179 RTCPeerConnection *peer_connection = peer_connection_;
180 [peer_connection.delegate peerConnection:peer_connection
181 didChangeIceConnectionState:state];
182}
183
184void PeerConnectionDelegateAdapter::OnIceGatheringChange(
185 PeerConnectionInterface::IceGatheringState new_state) {
186 RTCIceGatheringState state =
187 [[RTCPeerConnection class] iceGatheringStateForNativeState:new_state];
188 RTCPeerConnection *peer_connection = peer_connection_;
189 [peer_connection.delegate peerConnection:peer_connection
190 didChangeIceGatheringState:state];
191}
192
193void PeerConnectionDelegateAdapter::OnIceCandidate(
194 const IceCandidateInterface *candidate) {
195 RTCIceCandidate *iceCandidate =
196 [[RTCIceCandidate alloc] initWithNativeCandidate:candidate];
197 RTCPeerConnection *peer_connection = peer_connection_;
198 [peer_connection.delegate peerConnection:peer_connection
199 didGenerateIceCandidate:iceCandidate];
200}
Honghai Zhangda2ba4d2016-05-23 11:53:14 -0700201
202void PeerConnectionDelegateAdapter::OnIceCandidatesRemoved(
203 const std::vector<cricket::Candidate>& candidates) {
204 NSMutableArray* ice_candidates =
205 [NSMutableArray arrayWithCapacity:candidates.size()];
206 for (const auto& candidate : candidates) {
207 std::unique_ptr<JsepIceCandidate> candidate_wrapper(
208 new JsepIceCandidate(candidate.transport_name(), -1, candidate));
209 RTCIceCandidate* ice_candidate = [[RTCIceCandidate alloc]
210 initWithNativeCandidate:candidate_wrapper.get()];
211 [ice_candidates addObject:ice_candidate];
212 }
213 RTCPeerConnection* peer_connection = peer_connection_;
214 [peer_connection.delegate peerConnection:peer_connection
215 didRemoveIceCandidates:ice_candidates];
216}
217
hjonf396f602016-02-11 16:19:06 -0800218} // namespace webrtc
219
220
221@implementation RTCPeerConnection {
vopatop.skam96b6b832016-08-18 14:21:20 -0700222 NSMutableArray<RTCMediaStream *> *_localStreams;
kwibergbfefb032016-05-01 14:53:46 -0700223 std::unique_ptr<webrtc::PeerConnectionDelegateAdapter> _observer;
hjonf396f602016-02-11 16:19:06 -0800224 rtc::scoped_refptr<webrtc::PeerConnectionInterface> _peerConnection;
deadbeef5d0b6d82017-01-09 16:05:28 -0800225 std::unique_ptr<webrtc::MediaConstraints> _nativeConstraints;
ivoc14d5dbe2016-07-04 07:06:55 -0700226 BOOL _hasStartedRtcEventLog;
hjonf396f602016-02-11 16:19:06 -0800227}
228
229@synthesize delegate = _delegate;
230
231- (instancetype)initWithFactory:(RTCPeerConnectionFactory *)factory
232 configuration:(RTCConfiguration *)configuration
233 constraints:(RTCMediaConstraints *)constraints
234 delegate:(id<RTCPeerConnectionDelegate>)delegate {
235 NSParameterAssert(factory);
Henrik Boströme06c2dd2016-05-13 13:50:38 +0200236 std::unique_ptr<webrtc::PeerConnectionInterface::RTCConfiguration> config(
hbosa73ca562016-05-17 03:28:58 -0700237 [configuration createNativeConfiguration]);
238 if (!config) {
239 return nil;
240 }
hjonf396f602016-02-11 16:19:06 -0800241 if (self = [super init]) {
242 _observer.reset(new webrtc::PeerConnectionDelegateAdapter(self));
deadbeef5d0b6d82017-01-09 16:05:28 -0800243 _nativeConstraints = constraints.nativeConstraints;
244 CopyConstraintsIntoRtcConfiguration(_nativeConstraints.get(),
245 config.get());
hjonf396f602016-02-11 16:19:06 -0800246 _peerConnection =
hbosd7973cc2016-05-27 06:08:53 -0700247 factory.nativeFactory->CreatePeerConnection(*config,
hbosd7973cc2016-05-27 06:08:53 -0700248 nullptr,
249 nullptr,
250 _observer.get());
skvlad588783a2016-08-11 14:29:25 -0700251 if (!_peerConnection) {
252 return nil;
253 }
hjonf396f602016-02-11 16:19:06 -0800254 _localStreams = [[NSMutableArray alloc] init];
255 _delegate = delegate;
256 }
257 return self;
258}
259
vopatop.skam96b6b832016-08-18 14:21:20 -0700260- (NSArray<RTCMediaStream *> *)localStreams {
hjonf396f602016-02-11 16:19:06 -0800261 return [_localStreams copy];
262}
263
264- (RTCSessionDescription *)localDescription {
265 const webrtc::SessionDescriptionInterface *description =
266 _peerConnection->local_description();
267 return description ?
268 [[RTCSessionDescription alloc] initWithNativeDescription:description]
269 : nil;
270}
271
272- (RTCSessionDescription *)remoteDescription {
273 const webrtc::SessionDescriptionInterface *description =
274 _peerConnection->remote_description();
275 return description ?
276 [[RTCSessionDescription alloc] initWithNativeDescription:description]
277 : nil;
278}
279
280- (RTCSignalingState)signalingState {
281 return [[self class]
282 signalingStateForNativeState:_peerConnection->signaling_state()];
283}
284
285- (RTCIceConnectionState)iceConnectionState {
286 return [[self class] iceConnectionStateForNativeState:
287 _peerConnection->ice_connection_state()];
288}
289
290- (RTCIceGatheringState)iceGatheringState {
291 return [[self class] iceGatheringStateForNativeState:
292 _peerConnection->ice_gathering_state()];
293}
294
tkchinaac3eb22016-03-09 21:49:40 -0800295- (BOOL)setConfiguration:(RTCConfiguration *)configuration {
Henrik Boströme06c2dd2016-05-13 13:50:38 +0200296 std::unique_ptr<webrtc::PeerConnectionInterface::RTCConfiguration> config(
hbosa73ca562016-05-17 03:28:58 -0700297 [configuration createNativeConfiguration]);
298 if (!config) {
299 return NO;
300 }
deadbeef5d0b6d82017-01-09 16:05:28 -0800301 CopyConstraintsIntoRtcConfiguration(_nativeConstraints.get(),
302 config.get());
Henrik Boströme06c2dd2016-05-13 13:50:38 +0200303 return _peerConnection->SetConfiguration(*config);
tkchinaac3eb22016-03-09 21:49:40 -0800304}
305
jtteh4eeb5372017-04-03 15:06:37 -0700306- (RTCConfiguration *)configuration {
307 webrtc::PeerConnectionInterface::RTCConfiguration config =
308 _peerConnection->GetConfiguration();
jtteh465faf02017-04-04 14:00:16 -0700309 return [[RTCConfiguration alloc] initWithNativeConfiguration:config];
jtteh4eeb5372017-04-03 15:06:37 -0700310}
311
hjonf396f602016-02-11 16:19:06 -0800312- (void)close {
313 _peerConnection->Close();
314}
315
316- (void)addIceCandidate:(RTCIceCandidate *)candidate {
kwibergbfefb032016-05-01 14:53:46 -0700317 std::unique_ptr<const webrtc::IceCandidateInterface> iceCandidate(
hjonf396f602016-02-11 16:19:06 -0800318 candidate.nativeCandidate);
319 _peerConnection->AddIceCandidate(iceCandidate.get());
320}
321
Honghai Zhangda2ba4d2016-05-23 11:53:14 -0700322- (void)removeIceCandidates:(NSArray<RTCIceCandidate *> *)iceCandidates {
323 std::vector<cricket::Candidate> candidates;
324 for (RTCIceCandidate *iceCandidate in iceCandidates) {
325 std::unique_ptr<const webrtc::IceCandidateInterface> candidate(
326 iceCandidate.nativeCandidate);
327 if (candidate) {
328 candidates.push_back(candidate->candidate());
329 // Need to fill the transport name from the sdp_mid.
330 candidates.back().set_transport_name(candidate->sdp_mid());
331 }
332 }
333 if (!candidates.empty()) {
334 _peerConnection->RemoveIceCandidates(candidates);
335 }
336}
337
hjonf396f602016-02-11 16:19:06 -0800338- (void)addStream:(RTCMediaStream *)stream {
hjona2f77982016-03-04 07:09:09 -0800339 if (!_peerConnection->AddStream(stream.nativeMediaStream)) {
hjonf396f602016-02-11 16:19:06 -0800340 RTCLogError(@"Failed to add stream: %@", stream);
341 return;
342 }
343 [_localStreams addObject:stream];
344}
345
346- (void)removeStream:(RTCMediaStream *)stream {
347 _peerConnection->RemoveStream(stream.nativeMediaStream);
348 [_localStreams removeObject:stream];
349}
350
Steve Anton8cb344a2018-02-27 15:34:53 -0800351- (RTCRtpSender *)addTrack:(RTCMediaStreamTrack *)track
352 streamLabels:(NSArray<NSString *> *)streamLabels {
353 std::vector<std::string> nativeStreamLabels;
354 for (NSString *label in streamLabels) {
355 nativeStreamLabels.push_back([label UTF8String]);
356 }
357 webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::RtpSenderInterface>> nativeSenderOrError =
358 _peerConnection->AddTrack(track.nativeTrack, nativeStreamLabels);
359 if (!nativeSenderOrError.ok()) {
360 RTCLogError(@"Failed to add track %@: %s", track, nativeSenderOrError.error().message());
361 return nil;
362 }
363 return [[RTCRtpSender alloc] initWithNativeRtpSender:nativeSenderOrError.MoveValue()];
364}
365
366- (BOOL)removeTrack:(RTCRtpSender *)sender {
367 bool result = _peerConnection->RemoveTrack(sender.nativeRtpSender);
368 if (!result) {
369 RTCLogError(@"Failed to remote track %@", sender);
370 }
371 return result;
372}
373
374- (RTCRtpTransceiver *)addTransceiverWithTrack:(RTCMediaStreamTrack *)track {
375 return [self addTransceiverWithTrack:track init:[[RTCRtpTransceiverInit alloc] init]];
376}
377
378- (RTCRtpTransceiver *)addTransceiverWithTrack:(RTCMediaStreamTrack *)track
379 init:(RTCRtpTransceiverInit *)init {
380 webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>> nativeTransceiverOrError =
381 _peerConnection->AddTransceiver(track.nativeTrack, init.nativeInit);
382 if (!nativeTransceiverOrError.ok()) {
383 RTCLogError(
384 @"Failed to add transceiver %@: %s", track, nativeTransceiverOrError.error().message());
385 return nil;
386 }
387 return
388 [[RTCRtpTransceiver alloc] initWithNativeRtpTransceiver:nativeTransceiverOrError.MoveValue()];
389}
390
391- (RTCRtpTransceiver *)addTransceiverOfType:(RTCRtpMediaType)mediaType {
392 return [self addTransceiverOfType:mediaType init:[[RTCRtpTransceiverInit alloc] init]];
393}
394
395- (RTCRtpTransceiver *)addTransceiverOfType:(RTCRtpMediaType)mediaType
396 init:(RTCRtpTransceiverInit *)init {
397 webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>> nativeTransceiverOrError =
398 _peerConnection->AddTransceiver([RTCRtpReceiver nativeMediaTypeForMediaType:mediaType],
399 init.nativeInit);
400 if (!nativeTransceiverOrError.ok()) {
401 RTCLogError(@"Failed to add transceiver %@: %s",
402 [RTCRtpReceiver stringForMediaType:mediaType],
403 nativeTransceiverOrError.error().message());
404 return nil;
405 }
406 return
407 [[RTCRtpTransceiver alloc] initWithNativeRtpTransceiver:nativeTransceiverOrError.MoveValue()];
408}
409
hjonf396f602016-02-11 16:19:06 -0800410- (void)offerForConstraints:(RTCMediaConstraints *)constraints
411 completionHandler:
412 (void (^)(RTCSessionDescription *sessionDescription,
413 NSError *error))completionHandler {
414 rtc::scoped_refptr<webrtc::CreateSessionDescriptionObserverAdapter>
415 observer(new rtc::RefCountedObject
416 <webrtc::CreateSessionDescriptionObserverAdapter>(completionHandler));
417 _peerConnection->CreateOffer(observer, constraints.nativeConstraints.get());
418}
419
420- (void)answerForConstraints:(RTCMediaConstraints *)constraints
421 completionHandler:
422 (void (^)(RTCSessionDescription *sessionDescription,
423 NSError *error))completionHandler {
424 rtc::scoped_refptr<webrtc::CreateSessionDescriptionObserverAdapter>
425 observer(new rtc::RefCountedObject
426 <webrtc::CreateSessionDescriptionObserverAdapter>(completionHandler));
427 _peerConnection->CreateAnswer(observer, constraints.nativeConstraints.get());
428}
429
430- (void)setLocalDescription:(RTCSessionDescription *)sdp
431 completionHandler:(void (^)(NSError *error))completionHandler {
432 rtc::scoped_refptr<webrtc::SetSessionDescriptionObserverAdapter> observer(
433 new rtc::RefCountedObject<webrtc::SetSessionDescriptionObserverAdapter>(
434 completionHandler));
435 _peerConnection->SetLocalDescription(observer, sdp.nativeDescription);
436}
437
438- (void)setRemoteDescription:(RTCSessionDescription *)sdp
439 completionHandler:(void (^)(NSError *error))completionHandler {
440 rtc::scoped_refptr<webrtc::SetSessionDescriptionObserverAdapter> observer(
441 new rtc::RefCountedObject<webrtc::SetSessionDescriptionObserverAdapter>(
442 completionHandler));
443 _peerConnection->SetRemoteDescription(observer, sdp.nativeDescription);
444}
445
zstein8b476172017-09-05 14:43:03 -0700446- (BOOL)setBweMinBitrateBps:(nullable NSNumber *)minBitrateBps
447 currentBitrateBps:(nullable NSNumber *)currentBitrateBps
448 maxBitrateBps:(nullable NSNumber *)maxBitrateBps {
zstein03adb7c2017-08-09 14:29:42 -0700449 webrtc::PeerConnectionInterface::BitrateParameters params;
450 if (minBitrateBps != nil) {
451 params.min_bitrate_bps = rtc::Optional<int>(minBitrateBps.intValue);
452 }
453 if (currentBitrateBps != nil) {
454 params.current_bitrate_bps = rtc::Optional<int>(currentBitrateBps.intValue);
455 }
456 if (maxBitrateBps != nil) {
457 params.max_bitrate_bps = rtc::Optional<int>(maxBitrateBps.intValue);
458 }
459 return _peerConnection->SetBitrate(params).ok();
460}
461
Magnus Jedvert0af86d12017-10-28 16:26:55 +0200462- (void)setBitrateAllocationStrategy:
463 (std::unique_ptr<rtc::BitrateAllocationStrategy>)bitrateAllocationStrategy {
464 _peerConnection->SetBitrateAllocationStrategy(std::move(bitrateAllocationStrategy));
465}
466
ivoc14d5dbe2016-07-04 07:06:55 -0700467- (BOOL)startRtcEventLogWithFilePath:(NSString *)filePath
468 maxSizeInBytes:(int64_t)maxSizeInBytes {
469 RTC_DCHECK(filePath.length);
470 RTC_DCHECK_GT(maxSizeInBytes, 0);
471 RTC_DCHECK(!_hasStartedRtcEventLog);
472 if (_hasStartedRtcEventLog) {
473 RTCLogError(@"Event logging already started.");
474 return NO;
475 }
476 int fd = open(filePath.UTF8String, O_WRONLY | O_CREAT | O_TRUNC,
477 S_IRUSR | S_IWUSR);
478 if (fd < 0) {
479 RTCLogError(@"Error opening file: %@. Error: %d", filePath, errno);
480 return NO;
481 }
482 _hasStartedRtcEventLog =
483 _peerConnection->StartRtcEventLog(fd, maxSizeInBytes);
484 return _hasStartedRtcEventLog;
485}
486
487- (void)stopRtcEventLog {
488 _peerConnection->StopRtcEventLog();
489 _hasStartedRtcEventLog = NO;
490}
491
skvladf3569c82016-04-29 15:30:16 -0700492- (RTCRtpSender *)senderWithKind:(NSString *)kind
493 streamId:(NSString *)streamId {
494 std::string nativeKind = [NSString stdStringForString:kind];
495 std::string nativeStreamId = [NSString stdStringForString:streamId];
496 rtc::scoped_refptr<webrtc::RtpSenderInterface> nativeSender(
497 _peerConnection->CreateSender(nativeKind, nativeStreamId));
498 return nativeSender ?
499 [[RTCRtpSender alloc] initWithNativeRtpSender:nativeSender]
500 : nil;
501}
502
skvlad79b4b872016-04-08 17:28:55 -0700503- (NSArray<RTCRtpSender *> *)senders {
504 std::vector<rtc::scoped_refptr<webrtc::RtpSenderInterface>> nativeSenders(
505 _peerConnection->GetSenders());
506 NSMutableArray *senders = [[NSMutableArray alloc] init];
507 for (const auto &nativeSender : nativeSenders) {
508 RTCRtpSender *sender =
509 [[RTCRtpSender alloc] initWithNativeRtpSender:nativeSender];
510 [senders addObject:sender];
511 }
512 return senders;
513}
514
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700515- (NSArray<RTCRtpReceiver *> *)receivers {
516 std::vector<rtc::scoped_refptr<webrtc::RtpReceiverInterface>> nativeReceivers(
517 _peerConnection->GetReceivers());
518 NSMutableArray *receivers = [[NSMutableArray alloc] init];
519 for (const auto &nativeReceiver : nativeReceivers) {
520 RTCRtpReceiver *receiver =
521 [[RTCRtpReceiver alloc] initWithNativeRtpReceiver:nativeReceiver];
522 [receivers addObject:receiver];
523 }
524 return receivers;
525}
526
Steve Anton8cb344a2018-02-27 15:34:53 -0800527- (NSArray<RTCRtpTransceiver *> *)transceivers {
528 std::vector<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>> nativeTransceivers(
529 _peerConnection->GetTransceivers());
530 NSMutableArray *transceivers = [[NSMutableArray alloc] init];
531 for (auto nativeTransceiver : nativeTransceivers) {
532 RTCRtpTransceiver *transceiver =
533 [[RTCRtpTransceiver alloc] initWithNativeRtpTransceiver:nativeTransceiver];
534 [transceivers addObject:transceiver];
535 }
536 return transceivers;
537}
538
hjonf396f602016-02-11 16:19:06 -0800539#pragma mark - Private
540
541+ (webrtc::PeerConnectionInterface::SignalingState)nativeSignalingStateForState:
542 (RTCSignalingState)state {
543 switch (state) {
544 case RTCSignalingStateStable:
545 return webrtc::PeerConnectionInterface::kStable;
546 case RTCSignalingStateHaveLocalOffer:
547 return webrtc::PeerConnectionInterface::kHaveLocalOffer;
548 case RTCSignalingStateHaveLocalPrAnswer:
549 return webrtc::PeerConnectionInterface::kHaveLocalPrAnswer;
550 case RTCSignalingStateHaveRemoteOffer:
551 return webrtc::PeerConnectionInterface::kHaveRemoteOffer;
552 case RTCSignalingStateHaveRemotePrAnswer:
553 return webrtc::PeerConnectionInterface::kHaveRemotePrAnswer;
554 case RTCSignalingStateClosed:
555 return webrtc::PeerConnectionInterface::kClosed;
556 }
557}
558
559+ (RTCSignalingState)signalingStateForNativeState:
560 (webrtc::PeerConnectionInterface::SignalingState)nativeState {
561 switch (nativeState) {
562 case webrtc::PeerConnectionInterface::kStable:
563 return RTCSignalingStateStable;
564 case webrtc::PeerConnectionInterface::kHaveLocalOffer:
565 return RTCSignalingStateHaveLocalOffer;
566 case webrtc::PeerConnectionInterface::kHaveLocalPrAnswer:
567 return RTCSignalingStateHaveLocalPrAnswer;
568 case webrtc::PeerConnectionInterface::kHaveRemoteOffer:
569 return RTCSignalingStateHaveRemoteOffer;
570 case webrtc::PeerConnectionInterface::kHaveRemotePrAnswer:
571 return RTCSignalingStateHaveRemotePrAnswer;
572 case webrtc::PeerConnectionInterface::kClosed:
573 return RTCSignalingStateClosed;
574 }
575}
576
577+ (NSString *)stringForSignalingState:(RTCSignalingState)state {
578 switch (state) {
579 case RTCSignalingStateStable:
580 return @"STABLE";
581 case RTCSignalingStateHaveLocalOffer:
582 return @"HAVE_LOCAL_OFFER";
583 case RTCSignalingStateHaveLocalPrAnswer:
584 return @"HAVE_LOCAL_PRANSWER";
585 case RTCSignalingStateHaveRemoteOffer:
586 return @"HAVE_REMOTE_OFFER";
587 case RTCSignalingStateHaveRemotePrAnswer:
588 return @"HAVE_REMOTE_PRANSWER";
589 case RTCSignalingStateClosed:
590 return @"CLOSED";
591 }
592}
593
594+ (webrtc::PeerConnectionInterface::IceConnectionState)
595 nativeIceConnectionStateForState:(RTCIceConnectionState)state {
596 switch (state) {
597 case RTCIceConnectionStateNew:
598 return webrtc::PeerConnectionInterface::kIceConnectionNew;
599 case RTCIceConnectionStateChecking:
600 return webrtc::PeerConnectionInterface::kIceConnectionChecking;
601 case RTCIceConnectionStateConnected:
602 return webrtc::PeerConnectionInterface::kIceConnectionConnected;
603 case RTCIceConnectionStateCompleted:
604 return webrtc::PeerConnectionInterface::kIceConnectionCompleted;
605 case RTCIceConnectionStateFailed:
606 return webrtc::PeerConnectionInterface::kIceConnectionFailed;
607 case RTCIceConnectionStateDisconnected:
608 return webrtc::PeerConnectionInterface::kIceConnectionDisconnected;
609 case RTCIceConnectionStateClosed:
610 return webrtc::PeerConnectionInterface::kIceConnectionClosed;
hjon8bbbf2c2016-03-14 13:15:44 -0700611 case RTCIceConnectionStateCount:
hjonf396f602016-02-11 16:19:06 -0800612 return webrtc::PeerConnectionInterface::kIceConnectionMax;
613 }
614}
615
616+ (RTCIceConnectionState)iceConnectionStateForNativeState:
617 (webrtc::PeerConnectionInterface::IceConnectionState)nativeState {
618 switch (nativeState) {
619 case webrtc::PeerConnectionInterface::kIceConnectionNew:
620 return RTCIceConnectionStateNew;
621 case webrtc::PeerConnectionInterface::kIceConnectionChecking:
622 return RTCIceConnectionStateChecking;
623 case webrtc::PeerConnectionInterface::kIceConnectionConnected:
624 return RTCIceConnectionStateConnected;
625 case webrtc::PeerConnectionInterface::kIceConnectionCompleted:
626 return RTCIceConnectionStateCompleted;
627 case webrtc::PeerConnectionInterface::kIceConnectionFailed:
628 return RTCIceConnectionStateFailed;
629 case webrtc::PeerConnectionInterface::kIceConnectionDisconnected:
630 return RTCIceConnectionStateDisconnected;
631 case webrtc::PeerConnectionInterface::kIceConnectionClosed:
632 return RTCIceConnectionStateClosed;
633 case webrtc::PeerConnectionInterface::kIceConnectionMax:
hjon8bbbf2c2016-03-14 13:15:44 -0700634 return RTCIceConnectionStateCount;
hjonf396f602016-02-11 16:19:06 -0800635 }
636}
637
638+ (NSString *)stringForIceConnectionState:(RTCIceConnectionState)state {
639 switch (state) {
640 case RTCIceConnectionStateNew:
641 return @"NEW";
642 case RTCIceConnectionStateChecking:
643 return @"CHECKING";
644 case RTCIceConnectionStateConnected:
645 return @"CONNECTED";
646 case RTCIceConnectionStateCompleted:
647 return @"COMPLETED";
648 case RTCIceConnectionStateFailed:
649 return @"FAILED";
650 case RTCIceConnectionStateDisconnected:
651 return @"DISCONNECTED";
652 case RTCIceConnectionStateClosed:
653 return @"CLOSED";
hjon8bbbf2c2016-03-14 13:15:44 -0700654 case RTCIceConnectionStateCount:
655 return @"COUNT";
hjonf396f602016-02-11 16:19:06 -0800656 }
657}
658
659+ (webrtc::PeerConnectionInterface::IceGatheringState)
660 nativeIceGatheringStateForState:(RTCIceGatheringState)state {
661 switch (state) {
662 case RTCIceGatheringStateNew:
663 return webrtc::PeerConnectionInterface::kIceGatheringNew;
664 case RTCIceGatheringStateGathering:
665 return webrtc::PeerConnectionInterface::kIceGatheringGathering;
666 case RTCIceGatheringStateComplete:
667 return webrtc::PeerConnectionInterface::kIceGatheringComplete;
668 }
669}
670
671+ (RTCIceGatheringState)iceGatheringStateForNativeState:
672 (webrtc::PeerConnectionInterface::IceGatheringState)nativeState {
673 switch (nativeState) {
674 case webrtc::PeerConnectionInterface::kIceGatheringNew:
675 return RTCIceGatheringStateNew;
676 case webrtc::PeerConnectionInterface::kIceGatheringGathering:
677 return RTCIceGatheringStateGathering;
678 case webrtc::PeerConnectionInterface::kIceGatheringComplete:
679 return RTCIceGatheringStateComplete;
680 }
681}
682
683+ (NSString *)stringForIceGatheringState:(RTCIceGatheringState)state {
684 switch (state) {
685 case RTCIceGatheringStateNew:
686 return @"NEW";
687 case RTCIceGatheringStateGathering:
688 return @"GATHERING";
689 case RTCIceGatheringStateComplete:
690 return @"COMPLETE";
691 }
692}
693
694+ (webrtc::PeerConnectionInterface::StatsOutputLevel)
695 nativeStatsOutputLevelForLevel:(RTCStatsOutputLevel)level {
696 switch (level) {
697 case RTCStatsOutputLevelStandard:
698 return webrtc::PeerConnectionInterface::kStatsOutputLevelStandard;
699 case RTCStatsOutputLevelDebug:
700 return webrtc::PeerConnectionInterface::kStatsOutputLevelDebug;
701 }
702}
703
hjonf396f602016-02-11 16:19:06 -0800704- (rtc::scoped_refptr<webrtc::PeerConnectionInterface>)nativePeerConnection {
705 return _peerConnection;
706}
707
708@end