blob: c19562bfc254389ac99629c2a339505f81ec1e88 [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
tkchin9eeb6242016-04-27 01:54:20 -070013#import "RTCConfiguration+Private.h"
14#import "RTCDataChannel+Private.h"
15#import "RTCIceCandidate+Private.h"
hbosbd3dda62016-09-09 01:36:28 -070016#import "RTCLegacyStatsReport+Private.h"
tkchin9eeb6242016-04-27 01:54:20 -070017#import "RTCMediaConstraints+Private.h"
18#import "RTCMediaStream+Private.h"
Steve Anton8cb344a2018-02-27 15:34:53 -080019#import "RTCMediaStreamTrack+Private.h"
Magnus Jedvert0af86d12017-10-28 16:26:55 +020020#import "RTCPeerConnection+Native.h"
tkchin9eeb6242016-04-27 01:54:20 -070021#import "RTCPeerConnectionFactory+Private.h"
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -070022#import "RTCRtpReceiver+Private.h"
tkchin9eeb6242016-04-27 01:54:20 -070023#import "RTCRtpSender+Private.h"
Steve Anton8cb344a2018-02-27 15:34:53 -080024#import "RTCRtpTransceiver+Private.h"
tkchin9eeb6242016-04-27 01:54:20 -070025#import "RTCSessionDescription+Private.h"
Anders Carlsson7bca8ca2018-08-30 09:30:29 +020026#import "base/RTCLogging.h"
27#import "helpers/NSString+StdString.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"
Piotr (Peter) Slatalae0c2e972018-10-08 09:43:21 -070032#include "api/media_transport_interface.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020033#include "rtc_base/checks.h"
hjonf396f602016-02-11 16:19:06 -080034
hjonf396f602016-02-11 16:19:06 -080035NSString * const kRTCPeerConnectionErrorDomain =
36 @"org.webrtc.RTCPeerConnection";
37int const kRTCPeerConnnectionSessionDescriptionError = -1;
38
39namespace webrtc {
40
41class CreateSessionDescriptionObserverAdapter
42 : public CreateSessionDescriptionObserver {
43 public:
44 CreateSessionDescriptionObserverAdapter(
45 void (^completionHandler)(RTCSessionDescription *sessionDescription,
46 NSError *error)) {
47 completion_handler_ = completionHandler;
48 }
49
Mirko Bonadei17aff352018-07-26 12:20:40 +020050 ~CreateSessionDescriptionObserverAdapter() override { completion_handler_ = nil; }
hjonf396f602016-02-11 16:19:06 -080051
52 void OnSuccess(SessionDescriptionInterface *desc) override {
53 RTC_DCHECK(completion_handler_);
kwibergbfefb032016-05-01 14:53:46 -070054 std::unique_ptr<webrtc::SessionDescriptionInterface> description =
55 std::unique_ptr<webrtc::SessionDescriptionInterface>(desc);
hjonf396f602016-02-11 16:19:06 -080056 RTCSessionDescription* session =
57 [[RTCSessionDescription alloc] initWithNativeDescription:
58 description.get()];
59 completion_handler_(session, nil);
60 completion_handler_ = nil;
61 }
62
Harald Alvestrand73771a82018-05-24 10:53:49 +020063 void OnFailure(RTCError error) override {
hjonf396f602016-02-11 16:19:06 -080064 RTC_DCHECK(completion_handler_);
Harald Alvestrand73771a82018-05-24 10:53:49 +020065 // TODO(hta): Add handling of error.type()
66 NSString *str = [NSString stringForStdString:error.message()];
hjonf396f602016-02-11 16:19:06 -080067 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
Mirko Bonadei17aff352018-07-26 12:20:40 +020088 ~SetSessionDescriptionObserverAdapter() override { completion_handler_ = nil; }
hjonf396f602016-02-11 16:19:06 -080089
90 void OnSuccess() override {
91 RTC_DCHECK(completion_handler_);
92 completion_handler_(nil);
93 completion_handler_ = nil;
94 }
95
Harald Alvestrand73771a82018-05-24 10:53:49 +020096 void OnFailure(RTCError error) override {
hjonf396f602016-02-11 16:19:06 -080097 RTC_DCHECK(completion_handler_);
Harald Alvestrand73771a82018-05-24 10:53:49 +020098 // TODO(hta): Add handling of error.type()
99 NSString *str = [NSString stringForStdString:error.message()];
hjonf396f602016-02-11 16:19:06 -0800100 NSError* err =
101 [NSError errorWithDomain:kRTCPeerConnectionErrorDomain
102 code:kRTCPeerConnnectionSessionDescriptionError
103 userInfo:@{ NSLocalizedDescriptionKey : str }];
104 completion_handler_(err);
105 completion_handler_ = nil;
106 }
107
108 private:
109 void (^completion_handler_)(NSError *error);
110};
111
112PeerConnectionDelegateAdapter::PeerConnectionDelegateAdapter(
113 RTCPeerConnection *peerConnection) {
114 peer_connection_ = peerConnection;
115}
116
117PeerConnectionDelegateAdapter::~PeerConnectionDelegateAdapter() {
118 peer_connection_ = nil;
119}
120
121void PeerConnectionDelegateAdapter::OnSignalingChange(
122 PeerConnectionInterface::SignalingState new_state) {
123 RTCSignalingState state =
124 [[RTCPeerConnection class] signalingStateForNativeState:new_state];
125 RTCPeerConnection *peer_connection = peer_connection_;
126 [peer_connection.delegate peerConnection:peer_connection
127 didChangeSignalingState:state];
128}
129
130void PeerConnectionDelegateAdapter::OnAddStream(
deadbeefd5f41ce2016-06-08 13:31:45 -0700131 rtc::scoped_refptr<MediaStreamInterface> stream) {
hjonf396f602016-02-11 16:19:06 -0800132 RTCPeerConnection *peer_connection = peer_connection_;
Yura Yaroshevichc806c1d2018-06-21 12:51:11 +0300133 RTCMediaStream *mediaStream =
134 [[RTCMediaStream alloc] initWithFactory:peer_connection.factory nativeMediaStream:stream];
hjonf396f602016-02-11 16:19:06 -0800135 [peer_connection.delegate peerConnection:peer_connection
136 didAddStream:mediaStream];
137}
138
139void PeerConnectionDelegateAdapter::OnRemoveStream(
deadbeefd5f41ce2016-06-08 13:31:45 -0700140 rtc::scoped_refptr<MediaStreamInterface> stream) {
hjonf396f602016-02-11 16:19:06 -0800141 RTCPeerConnection *peer_connection = peer_connection_;
Yura Yaroshevichc806c1d2018-06-21 12:51:11 +0300142 RTCMediaStream *mediaStream =
143 [[RTCMediaStream alloc] initWithFactory:peer_connection.factory nativeMediaStream:stream];
144
hjonf396f602016-02-11 16:19:06 -0800145 [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) {
Steve Anton8cb344a2018-02-27 15:34:53 -0800151 RTCPeerConnection *peer_connection = peer_connection_;
Yura Yaroshevich08f14dd2018-07-09 11:56:06 +0300152 RTCRtpTransceiver *transceiver =
153 [[RTCRtpTransceiver alloc] initWithFactory:peer_connection.factory
154 nativeRtpTransceiver:nativeTransceiver];
Steve Anton8cb344a2018-02-27 15:34:53 -0800155 if ([peer_connection.delegate
156 respondsToSelector:@selector(peerConnection:didStartReceivingOnTransceiver:)]) {
157 [peer_connection.delegate peerConnection:peer_connection
158 didStartReceivingOnTransceiver:transceiver];
159 }
160}
161
hjonf396f602016-02-11 16:19:06 -0800162void PeerConnectionDelegateAdapter::OnDataChannel(
deadbeefd5f41ce2016-06-08 13:31:45 -0700163 rtc::scoped_refptr<DataChannelInterface> data_channel) {
hjonf396f602016-02-11 16:19:06 -0800164 RTCPeerConnection *peer_connection = peer_connection_;
Yura Yaroshevichc75b35a2018-06-27 17:09:14 +0300165 RTCDataChannel *dataChannel = [[RTCDataChannel alloc] initWithFactory:peer_connection.factory
166 nativeDataChannel:data_channel];
hjonf396f602016-02-11 16:19:06 -0800167 [peer_connection.delegate peerConnection:peer_connection
168 didOpenDataChannel:dataChannel];
169}
170
171void PeerConnectionDelegateAdapter::OnRenegotiationNeeded() {
172 RTCPeerConnection *peer_connection = peer_connection_;
173 [peer_connection.delegate peerConnectionShouldNegotiate:peer_connection];
174}
175
176void PeerConnectionDelegateAdapter::OnIceConnectionChange(
177 PeerConnectionInterface::IceConnectionState new_state) {
Jonas Olsson586725d2018-11-15 11:30:57 +0100178 RTCIceConnectionState state = [RTCPeerConnection iceConnectionStateForNativeState:new_state];
179 [peer_connection_.delegate peerConnection:peer_connection_ didChangeIceConnectionState:state];
180}
181
182void PeerConnectionDelegateAdapter::OnConnectionChange(
183 PeerConnectionInterface::PeerConnectionState new_state) {
184 RTCPeerConnectionState state = [RTCPeerConnection connectionStateForNativeState:new_state];
185 [peer_connection_.delegate peerConnection:peer_connection_ didChangeConnectionState:state];
hjonf396f602016-02-11 16:19:06 -0800186}
187
188void PeerConnectionDelegateAdapter::OnIceGatheringChange(
189 PeerConnectionInterface::IceGatheringState new_state) {
190 RTCIceGatheringState state =
191 [[RTCPeerConnection class] iceGatheringStateForNativeState:new_state];
192 RTCPeerConnection *peer_connection = peer_connection_;
193 [peer_connection.delegate peerConnection:peer_connection
194 didChangeIceGatheringState:state];
195}
196
197void PeerConnectionDelegateAdapter::OnIceCandidate(
198 const IceCandidateInterface *candidate) {
199 RTCIceCandidate *iceCandidate =
200 [[RTCIceCandidate alloc] initWithNativeCandidate:candidate];
201 RTCPeerConnection *peer_connection = peer_connection_;
202 [peer_connection.delegate peerConnection:peer_connection
203 didGenerateIceCandidate:iceCandidate];
204}
Honghai Zhangda2ba4d2016-05-23 11:53:14 -0700205
206void PeerConnectionDelegateAdapter::OnIceCandidatesRemoved(
207 const std::vector<cricket::Candidate>& candidates) {
208 NSMutableArray* ice_candidates =
209 [NSMutableArray arrayWithCapacity:candidates.size()];
210 for (const auto& candidate : candidates) {
211 std::unique_ptr<JsepIceCandidate> candidate_wrapper(
212 new JsepIceCandidate(candidate.transport_name(), -1, candidate));
213 RTCIceCandidate* ice_candidate = [[RTCIceCandidate alloc]
214 initWithNativeCandidate:candidate_wrapper.get()];
215 [ice_candidates addObject:ice_candidate];
216 }
217 RTCPeerConnection* peer_connection = peer_connection_;
218 [peer_connection.delegate peerConnection:peer_connection
219 didRemoveIceCandidates:ice_candidates];
220}
221
Yura Yaroshevich546d7f92018-02-28 21:06:34 +0300222void PeerConnectionDelegateAdapter::OnAddTrack(
223 rtc::scoped_refptr<RtpReceiverInterface> receiver,
224 const std::vector<rtc::scoped_refptr<MediaStreamInterface>>& streams) {
225 RTCPeerConnection *peer_connection = peer_connection_;
226 if ([peer_connection.delegate
227 respondsToSelector:@selector(peerConnection:didAddReceiver:streams:)]) {
228 NSMutableArray *mediaStreams = [NSMutableArray arrayWithCapacity:streams.size()];
229 for (const auto& nativeStream : streams) {
Yura Yaroshevichc806c1d2018-06-21 12:51:11 +0300230 RTCMediaStream *mediaStream = [[RTCMediaStream alloc] initWithFactory:peer_connection.factory
231 nativeMediaStream:nativeStream];
Yura Yaroshevich546d7f92018-02-28 21:06:34 +0300232 [mediaStreams addObject:mediaStream];
233 }
Yura Yaroshevich7a16c542018-07-11 12:55:04 +0300234 RTCRtpReceiver *rtpReceiver =
235 [[RTCRtpReceiver alloc] initWithFactory:peer_connection.factory nativeRtpReceiver:receiver];
Yura Yaroshevich546d7f92018-02-28 21:06:34 +0300236
237 [peer_connection.delegate peerConnection:peer_connection
238 didAddReceiver:rtpReceiver
239 streams:mediaStreams];
240 }
241}
242
Zeke Chin8de502b2018-08-21 11:41:07 -0700243void PeerConnectionDelegateAdapter::OnRemoveTrack(
244 rtc::scoped_refptr<RtpReceiverInterface> receiver) {
245 RTCPeerConnection *peer_connection = peer_connection_;
246 if ([peer_connection.delegate respondsToSelector:@selector(peerConnection:didRemoveReceiver:)]) {
247 RTCRtpReceiver *rtpReceiver =
248 [[RTCRtpReceiver alloc] initWithFactory:peer_connection.factory nativeRtpReceiver:receiver];
249 [peer_connection.delegate peerConnection:peer_connection didRemoveReceiver:rtpReceiver];
250 }
251}
252
hjonf396f602016-02-11 16:19:06 -0800253} // namespace webrtc
254
255
256@implementation RTCPeerConnection {
Yura Yaroshevich5297bd22018-06-19 12:51:51 +0300257 RTCPeerConnectionFactory *_factory;
vopatop.skam96b6b832016-08-18 14:21:20 -0700258 NSMutableArray<RTCMediaStream *> *_localStreams;
kwibergbfefb032016-05-01 14:53:46 -0700259 std::unique_ptr<webrtc::PeerConnectionDelegateAdapter> _observer;
hjonf396f602016-02-11 16:19:06 -0800260 rtc::scoped_refptr<webrtc::PeerConnectionInterface> _peerConnection;
deadbeef5d0b6d82017-01-09 16:05:28 -0800261 std::unique_ptr<webrtc::MediaConstraints> _nativeConstraints;
ivoc14d5dbe2016-07-04 07:06:55 -0700262 BOOL _hasStartedRtcEventLog;
hjonf396f602016-02-11 16:19:06 -0800263}
264
265@synthesize delegate = _delegate;
Yura Yaroshevichc806c1d2018-06-21 12:51:11 +0300266@synthesize factory = _factory;
hjonf396f602016-02-11 16:19:06 -0800267
268- (instancetype)initWithFactory:(RTCPeerConnectionFactory *)factory
269 configuration:(RTCConfiguration *)configuration
270 constraints:(RTCMediaConstraints *)constraints
271 delegate:(id<RTCPeerConnectionDelegate>)delegate {
272 NSParameterAssert(factory);
Henrik Boströme06c2dd2016-05-13 13:50:38 +0200273 std::unique_ptr<webrtc::PeerConnectionInterface::RTCConfiguration> config(
hbosa73ca562016-05-17 03:28:58 -0700274 [configuration createNativeConfiguration]);
275 if (!config) {
276 return nil;
277 }
hjonf396f602016-02-11 16:19:06 -0800278 if (self = [super init]) {
279 _observer.reset(new webrtc::PeerConnectionDelegateAdapter(self));
deadbeef5d0b6d82017-01-09 16:05:28 -0800280 _nativeConstraints = constraints.nativeConstraints;
281 CopyConstraintsIntoRtcConfiguration(_nativeConstraints.get(),
282 config.get());
hjonf396f602016-02-11 16:19:06 -0800283 _peerConnection =
hbosd7973cc2016-05-27 06:08:53 -0700284 factory.nativeFactory->CreatePeerConnection(*config,
hbosd7973cc2016-05-27 06:08:53 -0700285 nullptr,
286 nullptr,
287 _observer.get());
skvlad588783a2016-08-11 14:29:25 -0700288 if (!_peerConnection) {
289 return nil;
290 }
Yura Yaroshevich5297bd22018-06-19 12:51:51 +0300291 _factory = factory;
hjonf396f602016-02-11 16:19:06 -0800292 _localStreams = [[NSMutableArray alloc] init];
293 _delegate = delegate;
294 }
295 return self;
296}
297
vopatop.skam96b6b832016-08-18 14:21:20 -0700298- (NSArray<RTCMediaStream *> *)localStreams {
hjonf396f602016-02-11 16:19:06 -0800299 return [_localStreams copy];
300}
301
302- (RTCSessionDescription *)localDescription {
303 const webrtc::SessionDescriptionInterface *description =
304 _peerConnection->local_description();
305 return description ?
306 [[RTCSessionDescription alloc] initWithNativeDescription:description]
307 : nil;
308}
309
310- (RTCSessionDescription *)remoteDescription {
311 const webrtc::SessionDescriptionInterface *description =
312 _peerConnection->remote_description();
313 return description ?
314 [[RTCSessionDescription alloc] initWithNativeDescription:description]
315 : nil;
316}
317
318- (RTCSignalingState)signalingState {
319 return [[self class]
320 signalingStateForNativeState:_peerConnection->signaling_state()];
321}
322
323- (RTCIceConnectionState)iceConnectionState {
324 return [[self class] iceConnectionStateForNativeState:
325 _peerConnection->ice_connection_state()];
326}
327
Jonas Olsson586725d2018-11-15 11:30:57 +0100328- (RTCPeerConnectionState)connectionState {
329 return [[self class] connectionStateForNativeState:_peerConnection->peer_connection_state()];
330}
331
hjonf396f602016-02-11 16:19:06 -0800332- (RTCIceGatheringState)iceGatheringState {
333 return [[self class] iceGatheringStateForNativeState:
334 _peerConnection->ice_gathering_state()];
335}
336
tkchinaac3eb22016-03-09 21:49:40 -0800337- (BOOL)setConfiguration:(RTCConfiguration *)configuration {
Henrik Boströme06c2dd2016-05-13 13:50:38 +0200338 std::unique_ptr<webrtc::PeerConnectionInterface::RTCConfiguration> config(
hbosa73ca562016-05-17 03:28:58 -0700339 [configuration createNativeConfiguration]);
340 if (!config) {
341 return NO;
342 }
deadbeef5d0b6d82017-01-09 16:05:28 -0800343 CopyConstraintsIntoRtcConfiguration(_nativeConstraints.get(),
344 config.get());
Henrik Boströme06c2dd2016-05-13 13:50:38 +0200345 return _peerConnection->SetConfiguration(*config);
tkchinaac3eb22016-03-09 21:49:40 -0800346}
347
jtteh4eeb5372017-04-03 15:06:37 -0700348- (RTCConfiguration *)configuration {
349 webrtc::PeerConnectionInterface::RTCConfiguration config =
350 _peerConnection->GetConfiguration();
jtteh465faf02017-04-04 14:00:16 -0700351 return [[RTCConfiguration alloc] initWithNativeConfiguration:config];
jtteh4eeb5372017-04-03 15:06:37 -0700352}
353
hjonf396f602016-02-11 16:19:06 -0800354- (void)close {
355 _peerConnection->Close();
356}
357
358- (void)addIceCandidate:(RTCIceCandidate *)candidate {
kwibergbfefb032016-05-01 14:53:46 -0700359 std::unique_ptr<const webrtc::IceCandidateInterface> iceCandidate(
hjonf396f602016-02-11 16:19:06 -0800360 candidate.nativeCandidate);
361 _peerConnection->AddIceCandidate(iceCandidate.get());
362}
363
Honghai Zhangda2ba4d2016-05-23 11:53:14 -0700364- (void)removeIceCandidates:(NSArray<RTCIceCandidate *> *)iceCandidates {
365 std::vector<cricket::Candidate> candidates;
366 for (RTCIceCandidate *iceCandidate in iceCandidates) {
367 std::unique_ptr<const webrtc::IceCandidateInterface> candidate(
368 iceCandidate.nativeCandidate);
369 if (candidate) {
370 candidates.push_back(candidate->candidate());
371 // Need to fill the transport name from the sdp_mid.
372 candidates.back().set_transport_name(candidate->sdp_mid());
373 }
374 }
375 if (!candidates.empty()) {
376 _peerConnection->RemoveIceCandidates(candidates);
377 }
378}
379
hjonf396f602016-02-11 16:19:06 -0800380- (void)addStream:(RTCMediaStream *)stream {
hjona2f77982016-03-04 07:09:09 -0800381 if (!_peerConnection->AddStream(stream.nativeMediaStream)) {
hjonf396f602016-02-11 16:19:06 -0800382 RTCLogError(@"Failed to add stream: %@", stream);
383 return;
384 }
385 [_localStreams addObject:stream];
386}
387
388- (void)removeStream:(RTCMediaStream *)stream {
389 _peerConnection->RemoveStream(stream.nativeMediaStream);
390 [_localStreams removeObject:stream];
391}
392
Seth Hampson513449e2018-03-06 09:35:56 -0800393- (RTCRtpSender *)addTrack:(RTCMediaStreamTrack *)track streamIds:(NSArray<NSString *> *)streamIds {
394 std::vector<std::string> nativeStreamIds;
395 for (NSString *streamId in streamIds) {
396 nativeStreamIds.push_back([streamId UTF8String]);
Steve Anton8cb344a2018-02-27 15:34:53 -0800397 }
398 webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::RtpSenderInterface>> nativeSenderOrError =
Seth Hampson513449e2018-03-06 09:35:56 -0800399 _peerConnection->AddTrack(track.nativeTrack, nativeStreamIds);
Steve Anton8cb344a2018-02-27 15:34:53 -0800400 if (!nativeSenderOrError.ok()) {
401 RTCLogError(@"Failed to add track %@: %s", track, nativeSenderOrError.error().message());
402 return nil;
403 }
Yura Yaroshevichef43aaf2018-07-09 19:16:32 +0300404 return [[RTCRtpSender alloc] initWithFactory:self.factory
405 nativeRtpSender:nativeSenderOrError.MoveValue()];
Steve Anton8cb344a2018-02-27 15:34:53 -0800406}
407
408- (BOOL)removeTrack:(RTCRtpSender *)sender {
409 bool result = _peerConnection->RemoveTrack(sender.nativeRtpSender);
410 if (!result) {
411 RTCLogError(@"Failed to remote track %@", sender);
412 }
413 return result;
414}
415
416- (RTCRtpTransceiver *)addTransceiverWithTrack:(RTCMediaStreamTrack *)track {
417 return [self addTransceiverWithTrack:track init:[[RTCRtpTransceiverInit alloc] init]];
418}
419
420- (RTCRtpTransceiver *)addTransceiverWithTrack:(RTCMediaStreamTrack *)track
421 init:(RTCRtpTransceiverInit *)init {
422 webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>> nativeTransceiverOrError =
423 _peerConnection->AddTransceiver(track.nativeTrack, init.nativeInit);
424 if (!nativeTransceiverOrError.ok()) {
425 RTCLogError(
426 @"Failed to add transceiver %@: %s", track, nativeTransceiverOrError.error().message());
427 return nil;
428 }
Yura Yaroshevich08f14dd2018-07-09 11:56:06 +0300429 return [[RTCRtpTransceiver alloc] initWithFactory:self.factory
430 nativeRtpTransceiver:nativeTransceiverOrError.MoveValue()];
Steve Anton8cb344a2018-02-27 15:34:53 -0800431}
432
433- (RTCRtpTransceiver *)addTransceiverOfType:(RTCRtpMediaType)mediaType {
434 return [self addTransceiverOfType:mediaType init:[[RTCRtpTransceiverInit alloc] init]];
435}
436
437- (RTCRtpTransceiver *)addTransceiverOfType:(RTCRtpMediaType)mediaType
438 init:(RTCRtpTransceiverInit *)init {
439 webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>> nativeTransceiverOrError =
440 _peerConnection->AddTransceiver([RTCRtpReceiver nativeMediaTypeForMediaType:mediaType],
441 init.nativeInit);
442 if (!nativeTransceiverOrError.ok()) {
443 RTCLogError(@"Failed to add transceiver %@: %s",
444 [RTCRtpReceiver stringForMediaType:mediaType],
445 nativeTransceiverOrError.error().message());
446 return nil;
447 }
Yura Yaroshevich08f14dd2018-07-09 11:56:06 +0300448 return [[RTCRtpTransceiver alloc] initWithFactory:self.factory
449 nativeRtpTransceiver:nativeTransceiverOrError.MoveValue()];
Steve Anton8cb344a2018-02-27 15:34:53 -0800450}
451
hjonf396f602016-02-11 16:19:06 -0800452- (void)offerForConstraints:(RTCMediaConstraints *)constraints
453 completionHandler:
454 (void (^)(RTCSessionDescription *sessionDescription,
455 NSError *error))completionHandler {
456 rtc::scoped_refptr<webrtc::CreateSessionDescriptionObserverAdapter>
457 observer(new rtc::RefCountedObject
458 <webrtc::CreateSessionDescriptionObserverAdapter>(completionHandler));
Niels Möllerf06f9232018-08-07 12:32:18 +0200459 webrtc::PeerConnectionInterface::RTCOfferAnswerOptions options;
460 CopyConstraintsIntoOfferAnswerOptions(constraints.nativeConstraints.get(), &options);
461
462 _peerConnection->CreateOffer(observer, options);
hjonf396f602016-02-11 16:19:06 -0800463}
464
465- (void)answerForConstraints:(RTCMediaConstraints *)constraints
466 completionHandler:
467 (void (^)(RTCSessionDescription *sessionDescription,
468 NSError *error))completionHandler {
469 rtc::scoped_refptr<webrtc::CreateSessionDescriptionObserverAdapter>
470 observer(new rtc::RefCountedObject
471 <webrtc::CreateSessionDescriptionObserverAdapter>(completionHandler));
Niels Möllerf06f9232018-08-07 12:32:18 +0200472 webrtc::PeerConnectionInterface::RTCOfferAnswerOptions options;
473 CopyConstraintsIntoOfferAnswerOptions(constraints.nativeConstraints.get(), &options);
474
475 _peerConnection->CreateAnswer(observer, options);
hjonf396f602016-02-11 16:19:06 -0800476}
477
478- (void)setLocalDescription:(RTCSessionDescription *)sdp
479 completionHandler:(void (^)(NSError *error))completionHandler {
480 rtc::scoped_refptr<webrtc::SetSessionDescriptionObserverAdapter> observer(
481 new rtc::RefCountedObject<webrtc::SetSessionDescriptionObserverAdapter>(
482 completionHandler));
483 _peerConnection->SetLocalDescription(observer, sdp.nativeDescription);
484}
485
486- (void)setRemoteDescription:(RTCSessionDescription *)sdp
487 completionHandler:(void (^)(NSError *error))completionHandler {
488 rtc::scoped_refptr<webrtc::SetSessionDescriptionObserverAdapter> observer(
489 new rtc::RefCountedObject<webrtc::SetSessionDescriptionObserverAdapter>(
490 completionHandler));
491 _peerConnection->SetRemoteDescription(observer, sdp.nativeDescription);
492}
493
zstein8b476172017-09-05 14:43:03 -0700494- (BOOL)setBweMinBitrateBps:(nullable NSNumber *)minBitrateBps
495 currentBitrateBps:(nullable NSNumber *)currentBitrateBps
496 maxBitrateBps:(nullable NSNumber *)maxBitrateBps {
zstein03adb7c2017-08-09 14:29:42 -0700497 webrtc::PeerConnectionInterface::BitrateParameters params;
498 if (minBitrateBps != nil) {
Danil Chapovalov196100e2018-06-21 10:17:24 +0200499 params.min_bitrate_bps = absl::optional<int>(minBitrateBps.intValue);
zstein03adb7c2017-08-09 14:29:42 -0700500 }
501 if (currentBitrateBps != nil) {
Danil Chapovalov196100e2018-06-21 10:17:24 +0200502 params.current_bitrate_bps = absl::optional<int>(currentBitrateBps.intValue);
zstein03adb7c2017-08-09 14:29:42 -0700503 }
504 if (maxBitrateBps != nil) {
Danil Chapovalov196100e2018-06-21 10:17:24 +0200505 params.max_bitrate_bps = absl::optional<int>(maxBitrateBps.intValue);
zstein03adb7c2017-08-09 14:29:42 -0700506 }
507 return _peerConnection->SetBitrate(params).ok();
508}
509
Magnus Jedvert0af86d12017-10-28 16:26:55 +0200510- (void)setBitrateAllocationStrategy:
511 (std::unique_ptr<rtc::BitrateAllocationStrategy>)bitrateAllocationStrategy {
512 _peerConnection->SetBitrateAllocationStrategy(std::move(bitrateAllocationStrategy));
513}
514
ivoc14d5dbe2016-07-04 07:06:55 -0700515- (BOOL)startRtcEventLogWithFilePath:(NSString *)filePath
516 maxSizeInBytes:(int64_t)maxSizeInBytes {
517 RTC_DCHECK(filePath.length);
518 RTC_DCHECK_GT(maxSizeInBytes, 0);
519 RTC_DCHECK(!_hasStartedRtcEventLog);
520 if (_hasStartedRtcEventLog) {
521 RTCLogError(@"Event logging already started.");
522 return NO;
523 }
524 int fd = open(filePath.UTF8String, O_WRONLY | O_CREAT | O_TRUNC,
525 S_IRUSR | S_IWUSR);
526 if (fd < 0) {
527 RTCLogError(@"Error opening file: %@. Error: %d", filePath, errno);
528 return NO;
529 }
530 _hasStartedRtcEventLog =
531 _peerConnection->StartRtcEventLog(fd, maxSizeInBytes);
532 return _hasStartedRtcEventLog;
533}
534
535- (void)stopRtcEventLog {
536 _peerConnection->StopRtcEventLog();
537 _hasStartedRtcEventLog = NO;
538}
539
skvladf3569c82016-04-29 15:30:16 -0700540- (RTCRtpSender *)senderWithKind:(NSString *)kind
541 streamId:(NSString *)streamId {
542 std::string nativeKind = [NSString stdStringForString:kind];
543 std::string nativeStreamId = [NSString stdStringForString:streamId];
544 rtc::scoped_refptr<webrtc::RtpSenderInterface> nativeSender(
545 _peerConnection->CreateSender(nativeKind, nativeStreamId));
546 return nativeSender ?
Yura Yaroshevichef43aaf2018-07-09 19:16:32 +0300547 [[RTCRtpSender alloc] initWithFactory:self.factory nativeRtpSender:nativeSender] :
548 nil;
skvladf3569c82016-04-29 15:30:16 -0700549}
550
skvlad79b4b872016-04-08 17:28:55 -0700551- (NSArray<RTCRtpSender *> *)senders {
552 std::vector<rtc::scoped_refptr<webrtc::RtpSenderInterface>> nativeSenders(
553 _peerConnection->GetSenders());
554 NSMutableArray *senders = [[NSMutableArray alloc] init];
555 for (const auto &nativeSender : nativeSenders) {
556 RTCRtpSender *sender =
Yura Yaroshevichef43aaf2018-07-09 19:16:32 +0300557 [[RTCRtpSender alloc] initWithFactory:self.factory nativeRtpSender:nativeSender];
skvlad79b4b872016-04-08 17:28:55 -0700558 [senders addObject:sender];
559 }
560 return senders;
561}
562
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700563- (NSArray<RTCRtpReceiver *> *)receivers {
564 std::vector<rtc::scoped_refptr<webrtc::RtpReceiverInterface>> nativeReceivers(
565 _peerConnection->GetReceivers());
566 NSMutableArray *receivers = [[NSMutableArray alloc] init];
567 for (const auto &nativeReceiver : nativeReceivers) {
568 RTCRtpReceiver *receiver =
Yura Yaroshevich7a16c542018-07-11 12:55:04 +0300569 [[RTCRtpReceiver alloc] initWithFactory:self.factory nativeRtpReceiver:nativeReceiver];
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700570 [receivers addObject:receiver];
571 }
572 return receivers;
573}
574
Steve Anton8cb344a2018-02-27 15:34:53 -0800575- (NSArray<RTCRtpTransceiver *> *)transceivers {
576 std::vector<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>> nativeTransceivers(
577 _peerConnection->GetTransceivers());
578 NSMutableArray *transceivers = [[NSMutableArray alloc] init];
579 for (auto nativeTransceiver : nativeTransceivers) {
Yura Yaroshevich08f14dd2018-07-09 11:56:06 +0300580 RTCRtpTransceiver *transceiver = [[RTCRtpTransceiver alloc] initWithFactory:self.factory
581 nativeRtpTransceiver:nativeTransceiver];
Steve Anton8cb344a2018-02-27 15:34:53 -0800582 [transceivers addObject:transceiver];
583 }
584 return transceivers;
585}
586
hjonf396f602016-02-11 16:19:06 -0800587#pragma mark - Private
588
589+ (webrtc::PeerConnectionInterface::SignalingState)nativeSignalingStateForState:
590 (RTCSignalingState)state {
591 switch (state) {
592 case RTCSignalingStateStable:
593 return webrtc::PeerConnectionInterface::kStable;
594 case RTCSignalingStateHaveLocalOffer:
595 return webrtc::PeerConnectionInterface::kHaveLocalOffer;
596 case RTCSignalingStateHaveLocalPrAnswer:
597 return webrtc::PeerConnectionInterface::kHaveLocalPrAnswer;
598 case RTCSignalingStateHaveRemoteOffer:
599 return webrtc::PeerConnectionInterface::kHaveRemoteOffer;
600 case RTCSignalingStateHaveRemotePrAnswer:
601 return webrtc::PeerConnectionInterface::kHaveRemotePrAnswer;
602 case RTCSignalingStateClosed:
603 return webrtc::PeerConnectionInterface::kClosed;
604 }
605}
606
607+ (RTCSignalingState)signalingStateForNativeState:
608 (webrtc::PeerConnectionInterface::SignalingState)nativeState {
609 switch (nativeState) {
610 case webrtc::PeerConnectionInterface::kStable:
611 return RTCSignalingStateStable;
612 case webrtc::PeerConnectionInterface::kHaveLocalOffer:
613 return RTCSignalingStateHaveLocalOffer;
614 case webrtc::PeerConnectionInterface::kHaveLocalPrAnswer:
615 return RTCSignalingStateHaveLocalPrAnswer;
616 case webrtc::PeerConnectionInterface::kHaveRemoteOffer:
617 return RTCSignalingStateHaveRemoteOffer;
618 case webrtc::PeerConnectionInterface::kHaveRemotePrAnswer:
619 return RTCSignalingStateHaveRemotePrAnswer;
620 case webrtc::PeerConnectionInterface::kClosed:
621 return RTCSignalingStateClosed;
622 }
623}
624
625+ (NSString *)stringForSignalingState:(RTCSignalingState)state {
626 switch (state) {
627 case RTCSignalingStateStable:
628 return @"STABLE";
629 case RTCSignalingStateHaveLocalOffer:
630 return @"HAVE_LOCAL_OFFER";
631 case RTCSignalingStateHaveLocalPrAnswer:
632 return @"HAVE_LOCAL_PRANSWER";
633 case RTCSignalingStateHaveRemoteOffer:
634 return @"HAVE_REMOTE_OFFER";
635 case RTCSignalingStateHaveRemotePrAnswer:
636 return @"HAVE_REMOTE_PRANSWER";
637 case RTCSignalingStateClosed:
638 return @"CLOSED";
639 }
640}
641
Jonas Olsson586725d2018-11-15 11:30:57 +0100642+ (webrtc::PeerConnectionInterface::PeerConnectionState)nativeConnectionStateForState:
643 (RTCPeerConnectionState)state {
644 switch (state) {
645 case RTCPeerConnectionStateNew:
646 return webrtc::PeerConnectionInterface::PeerConnectionState::kNew;
647 case RTCPeerConnectionStateConnecting:
648 return webrtc::PeerConnectionInterface::PeerConnectionState::kConnecting;
649 case RTCPeerConnectionStateConnected:
650 return webrtc::PeerConnectionInterface::PeerConnectionState::kConnected;
651 case RTCPeerConnectionStateFailed:
652 return webrtc::PeerConnectionInterface::PeerConnectionState::kFailed;
653 case RTCPeerConnectionStateDisconnected:
654 return webrtc::PeerConnectionInterface::PeerConnectionState::kDisconnected;
655 case RTCPeerConnectionStateClosed:
656 return webrtc::PeerConnectionInterface::PeerConnectionState::kClosed;
657 }
658}
659
660+ (RTCPeerConnectionState)connectionStateForNativeState:
661 (webrtc::PeerConnectionInterface::PeerConnectionState)nativeState {
662 switch (nativeState) {
663 case webrtc::PeerConnectionInterface::PeerConnectionState::kNew:
664 return RTCPeerConnectionStateNew;
665 case webrtc::PeerConnectionInterface::PeerConnectionState::kConnecting:
666 return RTCPeerConnectionStateConnecting;
667 case webrtc::PeerConnectionInterface::PeerConnectionState::kConnected:
668 return RTCPeerConnectionStateConnected;
669 case webrtc::PeerConnectionInterface::PeerConnectionState::kFailed:
670 return RTCPeerConnectionStateFailed;
671 case webrtc::PeerConnectionInterface::PeerConnectionState::kDisconnected:
672 return RTCPeerConnectionStateDisconnected;
673 case webrtc::PeerConnectionInterface::PeerConnectionState::kClosed:
674 return RTCPeerConnectionStateClosed;
675 }
676}
677
678+ (NSString *)stringForConnectionState:(RTCPeerConnectionState)state {
679 switch (state) {
680 case RTCPeerConnectionStateNew:
681 return @"NEW";
682 case RTCPeerConnectionStateConnecting:
683 return @"CONNECTING";
684 case RTCPeerConnectionStateConnected:
685 return @"CONNECTED";
686 case RTCPeerConnectionStateFailed:
687 return @"FAILED";
688 case RTCPeerConnectionStateDisconnected:
689 return @"DISCONNECTED";
690 case RTCPeerConnectionStateClosed:
691 return @"CLOSED";
692 }
693}
694
hjonf396f602016-02-11 16:19:06 -0800695+ (webrtc::PeerConnectionInterface::IceConnectionState)
696 nativeIceConnectionStateForState:(RTCIceConnectionState)state {
697 switch (state) {
698 case RTCIceConnectionStateNew:
699 return webrtc::PeerConnectionInterface::kIceConnectionNew;
700 case RTCIceConnectionStateChecking:
701 return webrtc::PeerConnectionInterface::kIceConnectionChecking;
702 case RTCIceConnectionStateConnected:
703 return webrtc::PeerConnectionInterface::kIceConnectionConnected;
704 case RTCIceConnectionStateCompleted:
705 return webrtc::PeerConnectionInterface::kIceConnectionCompleted;
706 case RTCIceConnectionStateFailed:
707 return webrtc::PeerConnectionInterface::kIceConnectionFailed;
708 case RTCIceConnectionStateDisconnected:
709 return webrtc::PeerConnectionInterface::kIceConnectionDisconnected;
710 case RTCIceConnectionStateClosed:
711 return webrtc::PeerConnectionInterface::kIceConnectionClosed;
hjon8bbbf2c2016-03-14 13:15:44 -0700712 case RTCIceConnectionStateCount:
hjonf396f602016-02-11 16:19:06 -0800713 return webrtc::PeerConnectionInterface::kIceConnectionMax;
714 }
715}
716
717+ (RTCIceConnectionState)iceConnectionStateForNativeState:
718 (webrtc::PeerConnectionInterface::IceConnectionState)nativeState {
719 switch (nativeState) {
720 case webrtc::PeerConnectionInterface::kIceConnectionNew:
721 return RTCIceConnectionStateNew;
722 case webrtc::PeerConnectionInterface::kIceConnectionChecking:
723 return RTCIceConnectionStateChecking;
724 case webrtc::PeerConnectionInterface::kIceConnectionConnected:
725 return RTCIceConnectionStateConnected;
726 case webrtc::PeerConnectionInterface::kIceConnectionCompleted:
727 return RTCIceConnectionStateCompleted;
728 case webrtc::PeerConnectionInterface::kIceConnectionFailed:
729 return RTCIceConnectionStateFailed;
730 case webrtc::PeerConnectionInterface::kIceConnectionDisconnected:
731 return RTCIceConnectionStateDisconnected;
732 case webrtc::PeerConnectionInterface::kIceConnectionClosed:
733 return RTCIceConnectionStateClosed;
734 case webrtc::PeerConnectionInterface::kIceConnectionMax:
hjon8bbbf2c2016-03-14 13:15:44 -0700735 return RTCIceConnectionStateCount;
hjonf396f602016-02-11 16:19:06 -0800736 }
737}
738
739+ (NSString *)stringForIceConnectionState:(RTCIceConnectionState)state {
740 switch (state) {
741 case RTCIceConnectionStateNew:
742 return @"NEW";
743 case RTCIceConnectionStateChecking:
744 return @"CHECKING";
745 case RTCIceConnectionStateConnected:
746 return @"CONNECTED";
747 case RTCIceConnectionStateCompleted:
748 return @"COMPLETED";
749 case RTCIceConnectionStateFailed:
750 return @"FAILED";
751 case RTCIceConnectionStateDisconnected:
752 return @"DISCONNECTED";
753 case RTCIceConnectionStateClosed:
754 return @"CLOSED";
hjon8bbbf2c2016-03-14 13:15:44 -0700755 case RTCIceConnectionStateCount:
756 return @"COUNT";
hjonf396f602016-02-11 16:19:06 -0800757 }
758}
759
760+ (webrtc::PeerConnectionInterface::IceGatheringState)
761 nativeIceGatheringStateForState:(RTCIceGatheringState)state {
762 switch (state) {
763 case RTCIceGatheringStateNew:
764 return webrtc::PeerConnectionInterface::kIceGatheringNew;
765 case RTCIceGatheringStateGathering:
766 return webrtc::PeerConnectionInterface::kIceGatheringGathering;
767 case RTCIceGatheringStateComplete:
768 return webrtc::PeerConnectionInterface::kIceGatheringComplete;
769 }
770}
771
772+ (RTCIceGatheringState)iceGatheringStateForNativeState:
773 (webrtc::PeerConnectionInterface::IceGatheringState)nativeState {
774 switch (nativeState) {
775 case webrtc::PeerConnectionInterface::kIceGatheringNew:
776 return RTCIceGatheringStateNew;
777 case webrtc::PeerConnectionInterface::kIceGatheringGathering:
778 return RTCIceGatheringStateGathering;
779 case webrtc::PeerConnectionInterface::kIceGatheringComplete:
780 return RTCIceGatheringStateComplete;
781 }
782}
783
784+ (NSString *)stringForIceGatheringState:(RTCIceGatheringState)state {
785 switch (state) {
786 case RTCIceGatheringStateNew:
787 return @"NEW";
788 case RTCIceGatheringStateGathering:
789 return @"GATHERING";
790 case RTCIceGatheringStateComplete:
791 return @"COMPLETE";
792 }
793}
794
795+ (webrtc::PeerConnectionInterface::StatsOutputLevel)
796 nativeStatsOutputLevelForLevel:(RTCStatsOutputLevel)level {
797 switch (level) {
798 case RTCStatsOutputLevelStandard:
799 return webrtc::PeerConnectionInterface::kStatsOutputLevelStandard;
800 case RTCStatsOutputLevelDebug:
801 return webrtc::PeerConnectionInterface::kStatsOutputLevelDebug;
802 }
803}
804
hjonf396f602016-02-11 16:19:06 -0800805- (rtc::scoped_refptr<webrtc::PeerConnectionInterface>)nativePeerConnection {
806 return _peerConnection;
807}
808
809@end