blob: 1ac076b3c2ecd40e0c4d538ffcc525926fafdac3 [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 Olsson04629482018-11-15 15:02:09 +0000178 RTCIceConnectionState state =
179 [[RTCPeerConnection class] iceConnectionStateForNativeState:new_state];
180 RTCPeerConnection *peer_connection = peer_connection_;
181 [peer_connection.delegate peerConnection:peer_connection
182 didChangeIceConnectionState:state];
hjonf396f602016-02-11 16:19:06 -0800183}
184
185void PeerConnectionDelegateAdapter::OnIceGatheringChange(
186 PeerConnectionInterface::IceGatheringState new_state) {
187 RTCIceGatheringState state =
188 [[RTCPeerConnection class] iceGatheringStateForNativeState:new_state];
189 RTCPeerConnection *peer_connection = peer_connection_;
190 [peer_connection.delegate peerConnection:peer_connection
191 didChangeIceGatheringState:state];
192}
193
194void PeerConnectionDelegateAdapter::OnIceCandidate(
195 const IceCandidateInterface *candidate) {
196 RTCIceCandidate *iceCandidate =
197 [[RTCIceCandidate alloc] initWithNativeCandidate:candidate];
198 RTCPeerConnection *peer_connection = peer_connection_;
199 [peer_connection.delegate peerConnection:peer_connection
200 didGenerateIceCandidate:iceCandidate];
201}
Honghai Zhangda2ba4d2016-05-23 11:53:14 -0700202
203void PeerConnectionDelegateAdapter::OnIceCandidatesRemoved(
204 const std::vector<cricket::Candidate>& candidates) {
205 NSMutableArray* ice_candidates =
206 [NSMutableArray arrayWithCapacity:candidates.size()];
207 for (const auto& candidate : candidates) {
208 std::unique_ptr<JsepIceCandidate> candidate_wrapper(
209 new JsepIceCandidate(candidate.transport_name(), -1, candidate));
210 RTCIceCandidate* ice_candidate = [[RTCIceCandidate alloc]
211 initWithNativeCandidate:candidate_wrapper.get()];
212 [ice_candidates addObject:ice_candidate];
213 }
214 RTCPeerConnection* peer_connection = peer_connection_;
215 [peer_connection.delegate peerConnection:peer_connection
216 didRemoveIceCandidates:ice_candidates];
217}
218
Yura Yaroshevich546d7f92018-02-28 21:06:34 +0300219void PeerConnectionDelegateAdapter::OnAddTrack(
220 rtc::scoped_refptr<RtpReceiverInterface> receiver,
221 const std::vector<rtc::scoped_refptr<MediaStreamInterface>>& streams) {
222 RTCPeerConnection *peer_connection = peer_connection_;
223 if ([peer_connection.delegate
224 respondsToSelector:@selector(peerConnection:didAddReceiver:streams:)]) {
225 NSMutableArray *mediaStreams = [NSMutableArray arrayWithCapacity:streams.size()];
226 for (const auto& nativeStream : streams) {
Yura Yaroshevichc806c1d2018-06-21 12:51:11 +0300227 RTCMediaStream *mediaStream = [[RTCMediaStream alloc] initWithFactory:peer_connection.factory
228 nativeMediaStream:nativeStream];
Yura Yaroshevich546d7f92018-02-28 21:06:34 +0300229 [mediaStreams addObject:mediaStream];
230 }
Yura Yaroshevich7a16c542018-07-11 12:55:04 +0300231 RTCRtpReceiver *rtpReceiver =
232 [[RTCRtpReceiver alloc] initWithFactory:peer_connection.factory nativeRtpReceiver:receiver];
Yura Yaroshevich546d7f92018-02-28 21:06:34 +0300233
234 [peer_connection.delegate peerConnection:peer_connection
235 didAddReceiver:rtpReceiver
236 streams:mediaStreams];
237 }
238}
239
Zeke Chin8de502b2018-08-21 11:41:07 -0700240void PeerConnectionDelegateAdapter::OnRemoveTrack(
241 rtc::scoped_refptr<RtpReceiverInterface> receiver) {
242 RTCPeerConnection *peer_connection = peer_connection_;
243 if ([peer_connection.delegate respondsToSelector:@selector(peerConnection:didRemoveReceiver:)]) {
244 RTCRtpReceiver *rtpReceiver =
245 [[RTCRtpReceiver alloc] initWithFactory:peer_connection.factory nativeRtpReceiver:receiver];
246 [peer_connection.delegate peerConnection:peer_connection didRemoveReceiver:rtpReceiver];
247 }
248}
249
hjonf396f602016-02-11 16:19:06 -0800250} // namespace webrtc
251
252
253@implementation RTCPeerConnection {
Yura Yaroshevich5297bd22018-06-19 12:51:51 +0300254 RTCPeerConnectionFactory *_factory;
vopatop.skam96b6b832016-08-18 14:21:20 -0700255 NSMutableArray<RTCMediaStream *> *_localStreams;
kwibergbfefb032016-05-01 14:53:46 -0700256 std::unique_ptr<webrtc::PeerConnectionDelegateAdapter> _observer;
hjonf396f602016-02-11 16:19:06 -0800257 rtc::scoped_refptr<webrtc::PeerConnectionInterface> _peerConnection;
deadbeef5d0b6d82017-01-09 16:05:28 -0800258 std::unique_ptr<webrtc::MediaConstraints> _nativeConstraints;
ivoc14d5dbe2016-07-04 07:06:55 -0700259 BOOL _hasStartedRtcEventLog;
hjonf396f602016-02-11 16:19:06 -0800260}
261
262@synthesize delegate = _delegate;
Yura Yaroshevichc806c1d2018-06-21 12:51:11 +0300263@synthesize factory = _factory;
hjonf396f602016-02-11 16:19:06 -0800264
265- (instancetype)initWithFactory:(RTCPeerConnectionFactory *)factory
266 configuration:(RTCConfiguration *)configuration
267 constraints:(RTCMediaConstraints *)constraints
268 delegate:(id<RTCPeerConnectionDelegate>)delegate {
269 NSParameterAssert(factory);
Henrik Boströme06c2dd2016-05-13 13:50:38 +0200270 std::unique_ptr<webrtc::PeerConnectionInterface::RTCConfiguration> config(
hbosa73ca562016-05-17 03:28:58 -0700271 [configuration createNativeConfiguration]);
272 if (!config) {
273 return nil;
274 }
hjonf396f602016-02-11 16:19:06 -0800275 if (self = [super init]) {
276 _observer.reset(new webrtc::PeerConnectionDelegateAdapter(self));
deadbeef5d0b6d82017-01-09 16:05:28 -0800277 _nativeConstraints = constraints.nativeConstraints;
278 CopyConstraintsIntoRtcConfiguration(_nativeConstraints.get(),
279 config.get());
hjonf396f602016-02-11 16:19:06 -0800280 _peerConnection =
hbosd7973cc2016-05-27 06:08:53 -0700281 factory.nativeFactory->CreatePeerConnection(*config,
hbosd7973cc2016-05-27 06:08:53 -0700282 nullptr,
283 nullptr,
284 _observer.get());
skvlad588783a2016-08-11 14:29:25 -0700285 if (!_peerConnection) {
286 return nil;
287 }
Yura Yaroshevich5297bd22018-06-19 12:51:51 +0300288 _factory = factory;
hjonf396f602016-02-11 16:19:06 -0800289 _localStreams = [[NSMutableArray alloc] init];
290 _delegate = delegate;
291 }
292 return self;
293}
294
vopatop.skam96b6b832016-08-18 14:21:20 -0700295- (NSArray<RTCMediaStream *> *)localStreams {
hjonf396f602016-02-11 16:19:06 -0800296 return [_localStreams copy];
297}
298
299- (RTCSessionDescription *)localDescription {
300 const webrtc::SessionDescriptionInterface *description =
301 _peerConnection->local_description();
302 return description ?
303 [[RTCSessionDescription alloc] initWithNativeDescription:description]
304 : nil;
305}
306
307- (RTCSessionDescription *)remoteDescription {
308 const webrtc::SessionDescriptionInterface *description =
309 _peerConnection->remote_description();
310 return description ?
311 [[RTCSessionDescription alloc] initWithNativeDescription:description]
312 : nil;
313}
314
315- (RTCSignalingState)signalingState {
316 return [[self class]
317 signalingStateForNativeState:_peerConnection->signaling_state()];
318}
319
320- (RTCIceConnectionState)iceConnectionState {
321 return [[self class] iceConnectionStateForNativeState:
322 _peerConnection->ice_connection_state()];
323}
324
325- (RTCIceGatheringState)iceGatheringState {
326 return [[self class] iceGatheringStateForNativeState:
327 _peerConnection->ice_gathering_state()];
328}
329
tkchinaac3eb22016-03-09 21:49:40 -0800330- (BOOL)setConfiguration:(RTCConfiguration *)configuration {
Henrik Boströme06c2dd2016-05-13 13:50:38 +0200331 std::unique_ptr<webrtc::PeerConnectionInterface::RTCConfiguration> config(
hbosa73ca562016-05-17 03:28:58 -0700332 [configuration createNativeConfiguration]);
333 if (!config) {
334 return NO;
335 }
deadbeef5d0b6d82017-01-09 16:05:28 -0800336 CopyConstraintsIntoRtcConfiguration(_nativeConstraints.get(),
337 config.get());
Henrik Boströme06c2dd2016-05-13 13:50:38 +0200338 return _peerConnection->SetConfiguration(*config);
tkchinaac3eb22016-03-09 21:49:40 -0800339}
340
jtteh4eeb5372017-04-03 15:06:37 -0700341- (RTCConfiguration *)configuration {
342 webrtc::PeerConnectionInterface::RTCConfiguration config =
343 _peerConnection->GetConfiguration();
jtteh465faf02017-04-04 14:00:16 -0700344 return [[RTCConfiguration alloc] initWithNativeConfiguration:config];
jtteh4eeb5372017-04-03 15:06:37 -0700345}
346
hjonf396f602016-02-11 16:19:06 -0800347- (void)close {
348 _peerConnection->Close();
349}
350
351- (void)addIceCandidate:(RTCIceCandidate *)candidate {
kwibergbfefb032016-05-01 14:53:46 -0700352 std::unique_ptr<const webrtc::IceCandidateInterface> iceCandidate(
hjonf396f602016-02-11 16:19:06 -0800353 candidate.nativeCandidate);
354 _peerConnection->AddIceCandidate(iceCandidate.get());
355}
356
Honghai Zhangda2ba4d2016-05-23 11:53:14 -0700357- (void)removeIceCandidates:(NSArray<RTCIceCandidate *> *)iceCandidates {
358 std::vector<cricket::Candidate> candidates;
359 for (RTCIceCandidate *iceCandidate in iceCandidates) {
360 std::unique_ptr<const webrtc::IceCandidateInterface> candidate(
361 iceCandidate.nativeCandidate);
362 if (candidate) {
363 candidates.push_back(candidate->candidate());
364 // Need to fill the transport name from the sdp_mid.
365 candidates.back().set_transport_name(candidate->sdp_mid());
366 }
367 }
368 if (!candidates.empty()) {
369 _peerConnection->RemoveIceCandidates(candidates);
370 }
371}
372
hjonf396f602016-02-11 16:19:06 -0800373- (void)addStream:(RTCMediaStream *)stream {
hjona2f77982016-03-04 07:09:09 -0800374 if (!_peerConnection->AddStream(stream.nativeMediaStream)) {
hjonf396f602016-02-11 16:19:06 -0800375 RTCLogError(@"Failed to add stream: %@", stream);
376 return;
377 }
378 [_localStreams addObject:stream];
379}
380
381- (void)removeStream:(RTCMediaStream *)stream {
382 _peerConnection->RemoveStream(stream.nativeMediaStream);
383 [_localStreams removeObject:stream];
384}
385
Seth Hampson513449e2018-03-06 09:35:56 -0800386- (RTCRtpSender *)addTrack:(RTCMediaStreamTrack *)track streamIds:(NSArray<NSString *> *)streamIds {
387 std::vector<std::string> nativeStreamIds;
388 for (NSString *streamId in streamIds) {
389 nativeStreamIds.push_back([streamId UTF8String]);
Steve Anton8cb344a2018-02-27 15:34:53 -0800390 }
391 webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::RtpSenderInterface>> nativeSenderOrError =
Seth Hampson513449e2018-03-06 09:35:56 -0800392 _peerConnection->AddTrack(track.nativeTrack, nativeStreamIds);
Steve Anton8cb344a2018-02-27 15:34:53 -0800393 if (!nativeSenderOrError.ok()) {
394 RTCLogError(@"Failed to add track %@: %s", track, nativeSenderOrError.error().message());
395 return nil;
396 }
Yura Yaroshevichef43aaf2018-07-09 19:16:32 +0300397 return [[RTCRtpSender alloc] initWithFactory:self.factory
398 nativeRtpSender:nativeSenderOrError.MoveValue()];
Steve Anton8cb344a2018-02-27 15:34:53 -0800399}
400
401- (BOOL)removeTrack:(RTCRtpSender *)sender {
402 bool result = _peerConnection->RemoveTrack(sender.nativeRtpSender);
403 if (!result) {
404 RTCLogError(@"Failed to remote track %@", sender);
405 }
406 return result;
407}
408
409- (RTCRtpTransceiver *)addTransceiverWithTrack:(RTCMediaStreamTrack *)track {
410 return [self addTransceiverWithTrack:track init:[[RTCRtpTransceiverInit alloc] init]];
411}
412
413- (RTCRtpTransceiver *)addTransceiverWithTrack:(RTCMediaStreamTrack *)track
414 init:(RTCRtpTransceiverInit *)init {
415 webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>> nativeTransceiverOrError =
416 _peerConnection->AddTransceiver(track.nativeTrack, init.nativeInit);
417 if (!nativeTransceiverOrError.ok()) {
418 RTCLogError(
419 @"Failed to add transceiver %@: %s", track, nativeTransceiverOrError.error().message());
420 return nil;
421 }
Yura Yaroshevich08f14dd2018-07-09 11:56:06 +0300422 return [[RTCRtpTransceiver alloc] initWithFactory:self.factory
423 nativeRtpTransceiver:nativeTransceiverOrError.MoveValue()];
Steve Anton8cb344a2018-02-27 15:34:53 -0800424}
425
426- (RTCRtpTransceiver *)addTransceiverOfType:(RTCRtpMediaType)mediaType {
427 return [self addTransceiverOfType:mediaType init:[[RTCRtpTransceiverInit alloc] init]];
428}
429
430- (RTCRtpTransceiver *)addTransceiverOfType:(RTCRtpMediaType)mediaType
431 init:(RTCRtpTransceiverInit *)init {
432 webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>> nativeTransceiverOrError =
433 _peerConnection->AddTransceiver([RTCRtpReceiver nativeMediaTypeForMediaType:mediaType],
434 init.nativeInit);
435 if (!nativeTransceiverOrError.ok()) {
436 RTCLogError(@"Failed to add transceiver %@: %s",
437 [RTCRtpReceiver stringForMediaType:mediaType],
438 nativeTransceiverOrError.error().message());
439 return nil;
440 }
Yura Yaroshevich08f14dd2018-07-09 11:56:06 +0300441 return [[RTCRtpTransceiver alloc] initWithFactory:self.factory
442 nativeRtpTransceiver:nativeTransceiverOrError.MoveValue()];
Steve Anton8cb344a2018-02-27 15:34:53 -0800443}
444
hjonf396f602016-02-11 16:19:06 -0800445- (void)offerForConstraints:(RTCMediaConstraints *)constraints
446 completionHandler:
447 (void (^)(RTCSessionDescription *sessionDescription,
448 NSError *error))completionHandler {
449 rtc::scoped_refptr<webrtc::CreateSessionDescriptionObserverAdapter>
450 observer(new rtc::RefCountedObject
451 <webrtc::CreateSessionDescriptionObserverAdapter>(completionHandler));
Niels Möllerf06f9232018-08-07 12:32:18 +0200452 webrtc::PeerConnectionInterface::RTCOfferAnswerOptions options;
453 CopyConstraintsIntoOfferAnswerOptions(constraints.nativeConstraints.get(), &options);
454
455 _peerConnection->CreateOffer(observer, options);
hjonf396f602016-02-11 16:19:06 -0800456}
457
458- (void)answerForConstraints:(RTCMediaConstraints *)constraints
459 completionHandler:
460 (void (^)(RTCSessionDescription *sessionDescription,
461 NSError *error))completionHandler {
462 rtc::scoped_refptr<webrtc::CreateSessionDescriptionObserverAdapter>
463 observer(new rtc::RefCountedObject
464 <webrtc::CreateSessionDescriptionObserverAdapter>(completionHandler));
Niels Möllerf06f9232018-08-07 12:32:18 +0200465 webrtc::PeerConnectionInterface::RTCOfferAnswerOptions options;
466 CopyConstraintsIntoOfferAnswerOptions(constraints.nativeConstraints.get(), &options);
467
468 _peerConnection->CreateAnswer(observer, options);
hjonf396f602016-02-11 16:19:06 -0800469}
470
471- (void)setLocalDescription:(RTCSessionDescription *)sdp
472 completionHandler:(void (^)(NSError *error))completionHandler {
473 rtc::scoped_refptr<webrtc::SetSessionDescriptionObserverAdapter> observer(
474 new rtc::RefCountedObject<webrtc::SetSessionDescriptionObserverAdapter>(
475 completionHandler));
476 _peerConnection->SetLocalDescription(observer, sdp.nativeDescription);
477}
478
479- (void)setRemoteDescription:(RTCSessionDescription *)sdp
480 completionHandler:(void (^)(NSError *error))completionHandler {
481 rtc::scoped_refptr<webrtc::SetSessionDescriptionObserverAdapter> observer(
482 new rtc::RefCountedObject<webrtc::SetSessionDescriptionObserverAdapter>(
483 completionHandler));
484 _peerConnection->SetRemoteDescription(observer, sdp.nativeDescription);
485}
486
zstein8b476172017-09-05 14:43:03 -0700487- (BOOL)setBweMinBitrateBps:(nullable NSNumber *)minBitrateBps
488 currentBitrateBps:(nullable NSNumber *)currentBitrateBps
489 maxBitrateBps:(nullable NSNumber *)maxBitrateBps {
zstein03adb7c2017-08-09 14:29:42 -0700490 webrtc::PeerConnectionInterface::BitrateParameters params;
491 if (minBitrateBps != nil) {
Danil Chapovalov196100e2018-06-21 10:17:24 +0200492 params.min_bitrate_bps = absl::optional<int>(minBitrateBps.intValue);
zstein03adb7c2017-08-09 14:29:42 -0700493 }
494 if (currentBitrateBps != nil) {
Danil Chapovalov196100e2018-06-21 10:17:24 +0200495 params.current_bitrate_bps = absl::optional<int>(currentBitrateBps.intValue);
zstein03adb7c2017-08-09 14:29:42 -0700496 }
497 if (maxBitrateBps != nil) {
Danil Chapovalov196100e2018-06-21 10:17:24 +0200498 params.max_bitrate_bps = absl::optional<int>(maxBitrateBps.intValue);
zstein03adb7c2017-08-09 14:29:42 -0700499 }
500 return _peerConnection->SetBitrate(params).ok();
501}
502
Magnus Jedvert0af86d12017-10-28 16:26:55 +0200503- (void)setBitrateAllocationStrategy:
504 (std::unique_ptr<rtc::BitrateAllocationStrategy>)bitrateAllocationStrategy {
505 _peerConnection->SetBitrateAllocationStrategy(std::move(bitrateAllocationStrategy));
506}
507
ivoc14d5dbe2016-07-04 07:06:55 -0700508- (BOOL)startRtcEventLogWithFilePath:(NSString *)filePath
509 maxSizeInBytes:(int64_t)maxSizeInBytes {
510 RTC_DCHECK(filePath.length);
511 RTC_DCHECK_GT(maxSizeInBytes, 0);
512 RTC_DCHECK(!_hasStartedRtcEventLog);
513 if (_hasStartedRtcEventLog) {
514 RTCLogError(@"Event logging already started.");
515 return NO;
516 }
517 int fd = open(filePath.UTF8String, O_WRONLY | O_CREAT | O_TRUNC,
518 S_IRUSR | S_IWUSR);
519 if (fd < 0) {
520 RTCLogError(@"Error opening file: %@. Error: %d", filePath, errno);
521 return NO;
522 }
523 _hasStartedRtcEventLog =
524 _peerConnection->StartRtcEventLog(fd, maxSizeInBytes);
525 return _hasStartedRtcEventLog;
526}
527
528- (void)stopRtcEventLog {
529 _peerConnection->StopRtcEventLog();
530 _hasStartedRtcEventLog = NO;
531}
532
skvladf3569c82016-04-29 15:30:16 -0700533- (RTCRtpSender *)senderWithKind:(NSString *)kind
534 streamId:(NSString *)streamId {
535 std::string nativeKind = [NSString stdStringForString:kind];
536 std::string nativeStreamId = [NSString stdStringForString:streamId];
537 rtc::scoped_refptr<webrtc::RtpSenderInterface> nativeSender(
538 _peerConnection->CreateSender(nativeKind, nativeStreamId));
539 return nativeSender ?
Yura Yaroshevichef43aaf2018-07-09 19:16:32 +0300540 [[RTCRtpSender alloc] initWithFactory:self.factory nativeRtpSender:nativeSender] :
541 nil;
skvladf3569c82016-04-29 15:30:16 -0700542}
543
skvlad79b4b872016-04-08 17:28:55 -0700544- (NSArray<RTCRtpSender *> *)senders {
545 std::vector<rtc::scoped_refptr<webrtc::RtpSenderInterface>> nativeSenders(
546 _peerConnection->GetSenders());
547 NSMutableArray *senders = [[NSMutableArray alloc] init];
548 for (const auto &nativeSender : nativeSenders) {
549 RTCRtpSender *sender =
Yura Yaroshevichef43aaf2018-07-09 19:16:32 +0300550 [[RTCRtpSender alloc] initWithFactory:self.factory nativeRtpSender:nativeSender];
skvlad79b4b872016-04-08 17:28:55 -0700551 [senders addObject:sender];
552 }
553 return senders;
554}
555
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700556- (NSArray<RTCRtpReceiver *> *)receivers {
557 std::vector<rtc::scoped_refptr<webrtc::RtpReceiverInterface>> nativeReceivers(
558 _peerConnection->GetReceivers());
559 NSMutableArray *receivers = [[NSMutableArray alloc] init];
560 for (const auto &nativeReceiver : nativeReceivers) {
561 RTCRtpReceiver *receiver =
Yura Yaroshevich7a16c542018-07-11 12:55:04 +0300562 [[RTCRtpReceiver alloc] initWithFactory:self.factory nativeRtpReceiver:nativeReceiver];
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700563 [receivers addObject:receiver];
564 }
565 return receivers;
566}
567
Steve Anton8cb344a2018-02-27 15:34:53 -0800568- (NSArray<RTCRtpTransceiver *> *)transceivers {
569 std::vector<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>> nativeTransceivers(
570 _peerConnection->GetTransceivers());
571 NSMutableArray *transceivers = [[NSMutableArray alloc] init];
572 for (auto nativeTransceiver : nativeTransceivers) {
Yura Yaroshevich08f14dd2018-07-09 11:56:06 +0300573 RTCRtpTransceiver *transceiver = [[RTCRtpTransceiver alloc] initWithFactory:self.factory
574 nativeRtpTransceiver:nativeTransceiver];
Steve Anton8cb344a2018-02-27 15:34:53 -0800575 [transceivers addObject:transceiver];
576 }
577 return transceivers;
578}
579
hjonf396f602016-02-11 16:19:06 -0800580#pragma mark - Private
581
582+ (webrtc::PeerConnectionInterface::SignalingState)nativeSignalingStateForState:
583 (RTCSignalingState)state {
584 switch (state) {
585 case RTCSignalingStateStable:
586 return webrtc::PeerConnectionInterface::kStable;
587 case RTCSignalingStateHaveLocalOffer:
588 return webrtc::PeerConnectionInterface::kHaveLocalOffer;
589 case RTCSignalingStateHaveLocalPrAnswer:
590 return webrtc::PeerConnectionInterface::kHaveLocalPrAnswer;
591 case RTCSignalingStateHaveRemoteOffer:
592 return webrtc::PeerConnectionInterface::kHaveRemoteOffer;
593 case RTCSignalingStateHaveRemotePrAnswer:
594 return webrtc::PeerConnectionInterface::kHaveRemotePrAnswer;
595 case RTCSignalingStateClosed:
596 return webrtc::PeerConnectionInterface::kClosed;
597 }
598}
599
600+ (RTCSignalingState)signalingStateForNativeState:
601 (webrtc::PeerConnectionInterface::SignalingState)nativeState {
602 switch (nativeState) {
603 case webrtc::PeerConnectionInterface::kStable:
604 return RTCSignalingStateStable;
605 case webrtc::PeerConnectionInterface::kHaveLocalOffer:
606 return RTCSignalingStateHaveLocalOffer;
607 case webrtc::PeerConnectionInterface::kHaveLocalPrAnswer:
608 return RTCSignalingStateHaveLocalPrAnswer;
609 case webrtc::PeerConnectionInterface::kHaveRemoteOffer:
610 return RTCSignalingStateHaveRemoteOffer;
611 case webrtc::PeerConnectionInterface::kHaveRemotePrAnswer:
612 return RTCSignalingStateHaveRemotePrAnswer;
613 case webrtc::PeerConnectionInterface::kClosed:
614 return RTCSignalingStateClosed;
615 }
616}
617
618+ (NSString *)stringForSignalingState:(RTCSignalingState)state {
619 switch (state) {
620 case RTCSignalingStateStable:
621 return @"STABLE";
622 case RTCSignalingStateHaveLocalOffer:
623 return @"HAVE_LOCAL_OFFER";
624 case RTCSignalingStateHaveLocalPrAnswer:
625 return @"HAVE_LOCAL_PRANSWER";
626 case RTCSignalingStateHaveRemoteOffer:
627 return @"HAVE_REMOTE_OFFER";
628 case RTCSignalingStateHaveRemotePrAnswer:
629 return @"HAVE_REMOTE_PRANSWER";
630 case RTCSignalingStateClosed:
631 return @"CLOSED";
632 }
633}
634
635+ (webrtc::PeerConnectionInterface::IceConnectionState)
636 nativeIceConnectionStateForState:(RTCIceConnectionState)state {
637 switch (state) {
638 case RTCIceConnectionStateNew:
639 return webrtc::PeerConnectionInterface::kIceConnectionNew;
640 case RTCIceConnectionStateChecking:
641 return webrtc::PeerConnectionInterface::kIceConnectionChecking;
642 case RTCIceConnectionStateConnected:
643 return webrtc::PeerConnectionInterface::kIceConnectionConnected;
644 case RTCIceConnectionStateCompleted:
645 return webrtc::PeerConnectionInterface::kIceConnectionCompleted;
646 case RTCIceConnectionStateFailed:
647 return webrtc::PeerConnectionInterface::kIceConnectionFailed;
648 case RTCIceConnectionStateDisconnected:
649 return webrtc::PeerConnectionInterface::kIceConnectionDisconnected;
650 case RTCIceConnectionStateClosed:
651 return webrtc::PeerConnectionInterface::kIceConnectionClosed;
hjon8bbbf2c2016-03-14 13:15:44 -0700652 case RTCIceConnectionStateCount:
hjonf396f602016-02-11 16:19:06 -0800653 return webrtc::PeerConnectionInterface::kIceConnectionMax;
654 }
655}
656
657+ (RTCIceConnectionState)iceConnectionStateForNativeState:
658 (webrtc::PeerConnectionInterface::IceConnectionState)nativeState {
659 switch (nativeState) {
660 case webrtc::PeerConnectionInterface::kIceConnectionNew:
661 return RTCIceConnectionStateNew;
662 case webrtc::PeerConnectionInterface::kIceConnectionChecking:
663 return RTCIceConnectionStateChecking;
664 case webrtc::PeerConnectionInterface::kIceConnectionConnected:
665 return RTCIceConnectionStateConnected;
666 case webrtc::PeerConnectionInterface::kIceConnectionCompleted:
667 return RTCIceConnectionStateCompleted;
668 case webrtc::PeerConnectionInterface::kIceConnectionFailed:
669 return RTCIceConnectionStateFailed;
670 case webrtc::PeerConnectionInterface::kIceConnectionDisconnected:
671 return RTCIceConnectionStateDisconnected;
672 case webrtc::PeerConnectionInterface::kIceConnectionClosed:
673 return RTCIceConnectionStateClosed;
674 case webrtc::PeerConnectionInterface::kIceConnectionMax:
hjon8bbbf2c2016-03-14 13:15:44 -0700675 return RTCIceConnectionStateCount;
hjonf396f602016-02-11 16:19:06 -0800676 }
677}
678
679+ (NSString *)stringForIceConnectionState:(RTCIceConnectionState)state {
680 switch (state) {
681 case RTCIceConnectionStateNew:
682 return @"NEW";
683 case RTCIceConnectionStateChecking:
684 return @"CHECKING";
685 case RTCIceConnectionStateConnected:
686 return @"CONNECTED";
687 case RTCIceConnectionStateCompleted:
688 return @"COMPLETED";
689 case RTCIceConnectionStateFailed:
690 return @"FAILED";
691 case RTCIceConnectionStateDisconnected:
692 return @"DISCONNECTED";
693 case RTCIceConnectionStateClosed:
694 return @"CLOSED";
hjon8bbbf2c2016-03-14 13:15:44 -0700695 case RTCIceConnectionStateCount:
696 return @"COUNT";
hjonf396f602016-02-11 16:19:06 -0800697 }
698}
699
700+ (webrtc::PeerConnectionInterface::IceGatheringState)
701 nativeIceGatheringStateForState:(RTCIceGatheringState)state {
702 switch (state) {
703 case RTCIceGatheringStateNew:
704 return webrtc::PeerConnectionInterface::kIceGatheringNew;
705 case RTCIceGatheringStateGathering:
706 return webrtc::PeerConnectionInterface::kIceGatheringGathering;
707 case RTCIceGatheringStateComplete:
708 return webrtc::PeerConnectionInterface::kIceGatheringComplete;
709 }
710}
711
712+ (RTCIceGatheringState)iceGatheringStateForNativeState:
713 (webrtc::PeerConnectionInterface::IceGatheringState)nativeState {
714 switch (nativeState) {
715 case webrtc::PeerConnectionInterface::kIceGatheringNew:
716 return RTCIceGatheringStateNew;
717 case webrtc::PeerConnectionInterface::kIceGatheringGathering:
718 return RTCIceGatheringStateGathering;
719 case webrtc::PeerConnectionInterface::kIceGatheringComplete:
720 return RTCIceGatheringStateComplete;
721 }
722}
723
724+ (NSString *)stringForIceGatheringState:(RTCIceGatheringState)state {
725 switch (state) {
726 case RTCIceGatheringStateNew:
727 return @"NEW";
728 case RTCIceGatheringStateGathering:
729 return @"GATHERING";
730 case RTCIceGatheringStateComplete:
731 return @"COMPLETE";
732 }
733}
734
735+ (webrtc::PeerConnectionInterface::StatsOutputLevel)
736 nativeStatsOutputLevelForLevel:(RTCStatsOutputLevel)level {
737 switch (level) {
738 case RTCStatsOutputLevelStandard:
739 return webrtc::PeerConnectionInterface::kStatsOutputLevelStandard;
740 case RTCStatsOutputLevelDebug:
741 return webrtc::PeerConnectionInterface::kStatsOutputLevelDebug;
742 }
743}
744
hjonf396f602016-02-11 16:19:06 -0800745- (rtc::scoped_refptr<webrtc::PeerConnectionInterface>)nativePeerConnection {
746 return _peerConnection;
747}
748
749@end