1/* 2 * Copyright 2015 The WebRTC project authors. All Rights Reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11#import "RTCPeerConnection+Private.h" 12 13#import "RTCConfiguration+Private.h" 14#import "RTCDataChannel+Private.h" 15#import "RTCIceCandidate+Private.h" 16#import "RTCLegacyStatsReport+Private.h" 17#import "RTCMediaConstraints+Private.h" 18#import "RTCMediaStream+Private.h" 19#import "RTCMediaStreamTrack+Private.h" 20#import "RTCPeerConnectionFactory+Private.h" 21#import "RTCRtpReceiver+Private.h" 22#import "RTCRtpSender+Private.h" 23#import "RTCRtpTransceiver+Private.h" 24#import "RTCSessionDescription+Private.h" 25#import "base/RTCLogging.h" 26#import "helpers/NSString+StdString.h" 27 28#include <memory> 29 30#include "api/jsep_ice_candidate.h" 31#include "api/rtc_event_log_output_file.h" 32#include "api/transport/media/media_transport_interface.h" 33#include "rtc_base/checks.h" 34#include "rtc_base/numerics/safe_conversions.h" 35 36NSString * const kRTCPeerConnectionErrorDomain = 37 @"org.webrtc.RTCPeerConnection"; 38int const kRTCPeerConnnectionSessionDescriptionError = -1; 39 40namespace webrtc { 41 42class CreateSessionDescriptionObserverAdapter 43 : public CreateSessionDescriptionObserver { 44 public: 45 CreateSessionDescriptionObserverAdapter( 46 void (^completionHandler)(RTCSessionDescription *sessionDescription, 47 NSError *error)) { 48 completion_handler_ = completionHandler; 49 } 50 51 ~CreateSessionDescriptionObserverAdapter() override { completion_handler_ = nil; } 52 53 void OnSuccess(SessionDescriptionInterface *desc) override { 54 RTC_DCHECK(completion_handler_); 55 std::unique_ptr<webrtc::SessionDescriptionInterface> description = 56 std::unique_ptr<webrtc::SessionDescriptionInterface>(desc); 57 RTCSessionDescription* session = 58 [[RTCSessionDescription alloc] initWithNativeDescription: 59 description.get()]; 60 completion_handler_(session, nil); 61 completion_handler_ = nil; 62 } 63 64 void OnFailure(RTCError error) override { 65 RTC_DCHECK(completion_handler_); 66 // TODO(hta): Add handling of error.type() 67 NSString *str = [NSString stringForStdString:error.message()]; 68 NSError* err = 69 [NSError errorWithDomain:kRTCPeerConnectionErrorDomain 70 code:kRTCPeerConnnectionSessionDescriptionError 71 userInfo:@{ NSLocalizedDescriptionKey : str }]; 72 completion_handler_(nil, err); 73 completion_handler_ = nil; 74 } 75 76 private: 77 void (^completion_handler_) 78 (RTCSessionDescription *sessionDescription, NSError *error); 79}; 80 81class SetSessionDescriptionObserverAdapter : 82 public SetSessionDescriptionObserver { 83 public: 84 SetSessionDescriptionObserverAdapter(void (^completionHandler) 85 (NSError *error)) { 86 completion_handler_ = completionHandler; 87 } 88 89 ~SetSessionDescriptionObserverAdapter() override { completion_handler_ = nil; } 90 91 void OnSuccess() override { 92 RTC_DCHECK(completion_handler_); 93 completion_handler_(nil); 94 completion_handler_ = nil; 95 } 96 97 void OnFailure(RTCError error) override { 98 RTC_DCHECK(completion_handler_); 99 // TODO(hta): Add handling of error.type() 100 NSString *str = [NSString stringForStdString:error.message()]; 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( 132 rtc::scoped_refptr<MediaStreamInterface> stream) { 133 RTCPeerConnection *peer_connection = peer_connection_; 134 RTCMediaStream *mediaStream = 135 [[RTCMediaStream alloc] initWithFactory:peer_connection.factory nativeMediaStream:stream]; 136 [peer_connection.delegate peerConnection:peer_connection 137 didAddStream:mediaStream]; 138} 139 140void PeerConnectionDelegateAdapter::OnRemoveStream( 141 rtc::scoped_refptr<MediaStreamInterface> stream) { 142 RTCPeerConnection *peer_connection = peer_connection_; 143 RTCMediaStream *mediaStream = 144 [[RTCMediaStream alloc] initWithFactory:peer_connection.factory nativeMediaStream:stream]; 145 146 [peer_connection.delegate peerConnection:peer_connection 147 didRemoveStream:mediaStream]; 148} 149 150void PeerConnectionDelegateAdapter::OnTrack( 151 rtc::scoped_refptr<RtpTransceiverInterface> nativeTransceiver) { 152 RTCPeerConnection *peer_connection = peer_connection_; 153 RTCRtpTransceiver *transceiver = 154 [[RTCRtpTransceiver alloc] initWithFactory:peer_connection.factory 155 nativeRtpTransceiver:nativeTransceiver]; 156 if ([peer_connection.delegate 157 respondsToSelector:@selector(peerConnection:didStartReceivingOnTransceiver:)]) { 158 [peer_connection.delegate peerConnection:peer_connection 159 didStartReceivingOnTransceiver:transceiver]; 160 } 161} 162 163void PeerConnectionDelegateAdapter::OnDataChannel( 164 rtc::scoped_refptr<DataChannelInterface> data_channel) { 165 RTCPeerConnection *peer_connection = peer_connection_; 166 RTCDataChannel *dataChannel = [[RTCDataChannel alloc] initWithFactory:peer_connection.factory 167 nativeDataChannel:data_channel]; 168 [peer_connection.delegate peerConnection:peer_connection 169 didOpenDataChannel:dataChannel]; 170} 171 172void PeerConnectionDelegateAdapter::OnRenegotiationNeeded() { 173 RTCPeerConnection *peer_connection = peer_connection_; 174 [peer_connection.delegate peerConnectionShouldNegotiate:peer_connection]; 175} 176 177void PeerConnectionDelegateAdapter::OnIceConnectionChange( 178 PeerConnectionInterface::IceConnectionState new_state) { 179 RTCIceConnectionState state = [RTCPeerConnection iceConnectionStateForNativeState:new_state]; 180 [peer_connection_.delegate peerConnection:peer_connection_ didChangeIceConnectionState:state]; 181} 182 183void PeerConnectionDelegateAdapter::OnStandardizedIceConnectionChange( 184 PeerConnectionInterface::IceConnectionState new_state) { 185 if ([peer_connection_.delegate 186 respondsToSelector:@selector(peerConnection:didChangeStandardizedIceConnectionState:)]) { 187 RTCIceConnectionState state = [RTCPeerConnection iceConnectionStateForNativeState:new_state]; 188 [peer_connection_.delegate peerConnection:peer_connection_ 189 didChangeStandardizedIceConnectionState:state]; 190 } 191} 192 193void PeerConnectionDelegateAdapter::OnConnectionChange( 194 PeerConnectionInterface::PeerConnectionState new_state) { 195 if ([peer_connection_.delegate 196 respondsToSelector:@selector(peerConnection:didChangeConnectionState:)]) { 197 RTCPeerConnectionState state = [RTCPeerConnection connectionStateForNativeState:new_state]; 198 [peer_connection_.delegate peerConnection:peer_connection_ didChangeConnectionState:state]; 199 } 200} 201 202void PeerConnectionDelegateAdapter::OnIceGatheringChange( 203 PeerConnectionInterface::IceGatheringState new_state) { 204 RTCIceGatheringState state = 205 [[RTCPeerConnection class] iceGatheringStateForNativeState:new_state]; 206 RTCPeerConnection *peer_connection = peer_connection_; 207 [peer_connection.delegate peerConnection:peer_connection 208 didChangeIceGatheringState:state]; 209} 210 211void PeerConnectionDelegateAdapter::OnIceCandidate( 212 const IceCandidateInterface *candidate) { 213 RTCIceCandidate *iceCandidate = 214 [[RTCIceCandidate alloc] initWithNativeCandidate:candidate]; 215 RTCPeerConnection *peer_connection = peer_connection_; 216 [peer_connection.delegate peerConnection:peer_connection 217 didGenerateIceCandidate:iceCandidate]; 218} 219 220void PeerConnectionDelegateAdapter::OnIceCandidatesRemoved( 221 const std::vector<cricket::Candidate>& candidates) { 222 NSMutableArray* ice_candidates = 223 [NSMutableArray arrayWithCapacity:candidates.size()]; 224 for (const auto& candidate : candidates) { 225 std::unique_ptr<JsepIceCandidate> candidate_wrapper( 226 new JsepIceCandidate(candidate.transport_name(), -1, candidate)); 227 RTCIceCandidate* ice_candidate = [[RTCIceCandidate alloc] 228 initWithNativeCandidate:candidate_wrapper.get()]; 229 [ice_candidates addObject:ice_candidate]; 230 } 231 RTCPeerConnection* peer_connection = peer_connection_; 232 [peer_connection.delegate peerConnection:peer_connection 233 didRemoveIceCandidates:ice_candidates]; 234} 235 236void PeerConnectionDelegateAdapter::OnIceSelectedCandidatePairChanged( 237 const cricket::CandidatePairChangeEvent &event) { 238 const auto &selected_pair = event.selected_candidate_pair; 239 auto local_candidate_wrapper = std::make_unique<JsepIceCandidate>( 240 selected_pair.local_candidate().transport_name(), -1, selected_pair.local_candidate()); 241 RTCIceCandidate *local_candidate = 242 [[RTCIceCandidate alloc] initWithNativeCandidate:local_candidate_wrapper.release()]; 243 auto remote_candidate_wrapper = std::make_unique<JsepIceCandidate>( 244 selected_pair.remote_candidate().transport_name(), -1, selected_pair.remote_candidate()); 245 RTCIceCandidate *remote_candidate = 246 [[RTCIceCandidate alloc] initWithNativeCandidate:remote_candidate_wrapper.release()]; 247 RTCPeerConnection *peer_connection = peer_connection_; 248 NSString *nsstr_reason = [NSString stringForStdString:event.reason]; 249 if ([peer_connection.delegate 250 respondsToSelector:@selector 251 (peerConnection:didChangeLocalCandidate:remoteCandidate:lastReceivedMs:changeReason:)]) { 252 [peer_connection.delegate peerConnection:peer_connection 253 didChangeLocalCandidate:local_candidate 254 remoteCandidate:remote_candidate 255 lastReceivedMs:event.last_data_received_ms 256 changeReason:nsstr_reason]; 257 } 258} 259 260void PeerConnectionDelegateAdapter::OnAddTrack( 261 rtc::scoped_refptr<RtpReceiverInterface> receiver, 262 const std::vector<rtc::scoped_refptr<MediaStreamInterface>> &streams) { 263 RTCPeerConnection *peer_connection = peer_connection_; 264 if ([peer_connection.delegate respondsToSelector:@selector(peerConnection: 265 didAddReceiver:streams:)]) { 266 NSMutableArray *mediaStreams = [NSMutableArray arrayWithCapacity:streams.size()]; 267 for (const auto &nativeStream : streams) { 268 RTCMediaStream *mediaStream = [[RTCMediaStream alloc] initWithFactory:peer_connection.factory 269 nativeMediaStream:nativeStream]; 270 [mediaStreams addObject:mediaStream]; 271 } 272 RTCRtpReceiver *rtpReceiver = [[RTCRtpReceiver alloc] initWithFactory:peer_connection.factory 273 nativeRtpReceiver:receiver]; 274 275 [peer_connection.delegate peerConnection:peer_connection 276 didAddReceiver:rtpReceiver 277 streams:mediaStreams]; 278 } 279} 280 281void PeerConnectionDelegateAdapter::OnRemoveTrack( 282 rtc::scoped_refptr<RtpReceiverInterface> receiver) { 283 RTCPeerConnection *peer_connection = peer_connection_; 284 if ([peer_connection.delegate respondsToSelector:@selector(peerConnection:didRemoveReceiver:)]) { 285 RTCRtpReceiver *rtpReceiver = [[RTCRtpReceiver alloc] initWithFactory:peer_connection.factory 286 nativeRtpReceiver:receiver]; 287 [peer_connection.delegate peerConnection:peer_connection didRemoveReceiver:rtpReceiver]; 288 } 289} 290 291} // namespace webrtc 292 293@implementation RTCPeerConnection { 294 RTCPeerConnectionFactory *_factory; 295 NSMutableArray<RTCMediaStream *> *_localStreams; 296 std::unique_ptr<webrtc::PeerConnectionDelegateAdapter> _observer; 297 rtc::scoped_refptr<webrtc::PeerConnectionInterface> _peerConnection; 298 std::unique_ptr<webrtc::MediaConstraints> _nativeConstraints; 299 BOOL _hasStartedRtcEventLog; 300} 301 302@synthesize delegate = _delegate; 303@synthesize factory = _factory; 304 305- (instancetype)initWithFactory:(RTCPeerConnectionFactory *)factory 306 configuration:(RTCConfiguration *)configuration 307 constraints:(RTCMediaConstraints *)constraints 308 delegate:(id<RTCPeerConnectionDelegate>)delegate { 309 NSParameterAssert(factory); 310 std::unique_ptr<webrtc::PeerConnectionDependencies> dependencies = 311 std::make_unique<webrtc::PeerConnectionDependencies>(nullptr); 312 return [self initWithDependencies:factory 313 configuration:configuration 314 constraints:constraints 315 dependencies:std::move(dependencies) 316 delegate:delegate]; 317} 318 319- (instancetype)initWithDependencies:(RTCPeerConnectionFactory *)factory 320 configuration:(RTCConfiguration *)configuration 321 constraints:(RTCMediaConstraints *)constraints 322 dependencies: 323 (std::unique_ptr<webrtc::PeerConnectionDependencies>)dependencies 324 delegate:(id<RTCPeerConnectionDelegate>)delegate { 325 NSParameterAssert(factory); 326 NSParameterAssert(dependencies.get()); 327 std::unique_ptr<webrtc::PeerConnectionInterface::RTCConfiguration> config( 328 [configuration createNativeConfiguration]); 329 if (!config) { 330 return nil; 331 } 332 if (self = [super init]) { 333 _observer.reset(new webrtc::PeerConnectionDelegateAdapter(self)); 334 _nativeConstraints = constraints.nativeConstraints; 335 CopyConstraintsIntoRtcConfiguration(_nativeConstraints.get(), config.get()); 336 337 webrtc::PeerConnectionDependencies deps = std::move(*dependencies.release()); 338 deps.observer = _observer.get(); 339 _peerConnection = factory.nativeFactory->CreatePeerConnection(*config, std::move(deps)); 340 341 if (!_peerConnection) { 342 return nil; 343 } 344 _factory = factory; 345 _localStreams = [[NSMutableArray alloc] init]; 346 _delegate = delegate; 347 } 348 return self; 349} 350 351- (NSArray<RTCMediaStream *> *)localStreams { 352 return [_localStreams copy]; 353} 354 355- (RTCSessionDescription *)localDescription { 356 const webrtc::SessionDescriptionInterface *description = 357 _peerConnection->local_description(); 358 return description ? 359 [[RTCSessionDescription alloc] initWithNativeDescription:description] 360 : nil; 361} 362 363- (RTCSessionDescription *)remoteDescription { 364 const webrtc::SessionDescriptionInterface *description = 365 _peerConnection->remote_description(); 366 return description ? 367 [[RTCSessionDescription alloc] initWithNativeDescription:description] 368 : nil; 369} 370 371- (RTCSignalingState)signalingState { 372 return [[self class] 373 signalingStateForNativeState:_peerConnection->signaling_state()]; 374} 375 376- (RTCIceConnectionState)iceConnectionState { 377 return [[self class] iceConnectionStateForNativeState: 378 _peerConnection->ice_connection_state()]; 379} 380 381- (RTCPeerConnectionState)connectionState { 382 return [[self class] connectionStateForNativeState:_peerConnection->peer_connection_state()]; 383} 384 385- (RTCIceGatheringState)iceGatheringState { 386 return [[self class] iceGatheringStateForNativeState: 387 _peerConnection->ice_gathering_state()]; 388} 389 390- (BOOL)setConfiguration:(RTCConfiguration *)configuration { 391 std::unique_ptr<webrtc::PeerConnectionInterface::RTCConfiguration> config( 392 [configuration createNativeConfiguration]); 393 if (!config) { 394 return NO; 395 } 396 CopyConstraintsIntoRtcConfiguration(_nativeConstraints.get(), 397 config.get()); 398 return _peerConnection->SetConfiguration(*config).ok(); 399} 400 401- (RTCConfiguration *)configuration { 402 webrtc::PeerConnectionInterface::RTCConfiguration config = 403 _peerConnection->GetConfiguration(); 404 return [[RTCConfiguration alloc] initWithNativeConfiguration:config]; 405} 406 407- (void)close { 408 _peerConnection->Close(); 409} 410 411- (void)addIceCandidate:(RTCIceCandidate *)candidate { 412 std::unique_ptr<const webrtc::IceCandidateInterface> iceCandidate( 413 candidate.nativeCandidate); 414 _peerConnection->AddIceCandidate(iceCandidate.get()); 415} 416 417- (void)removeIceCandidates:(NSArray<RTCIceCandidate *> *)iceCandidates { 418 std::vector<cricket::Candidate> candidates; 419 for (RTCIceCandidate *iceCandidate in iceCandidates) { 420 std::unique_ptr<const webrtc::IceCandidateInterface> candidate( 421 iceCandidate.nativeCandidate); 422 if (candidate) { 423 candidates.push_back(candidate->candidate()); 424 // Need to fill the transport name from the sdp_mid. 425 candidates.back().set_transport_name(candidate->sdp_mid()); 426 } 427 } 428 if (!candidates.empty()) { 429 _peerConnection->RemoveIceCandidates(candidates); 430 } 431} 432 433- (void)addStream:(RTCMediaStream *)stream { 434 if (!_peerConnection->AddStream(stream.nativeMediaStream)) { 435 RTCLogError(@"Failed to add stream: %@", stream); 436 return; 437 } 438 [_localStreams addObject:stream]; 439} 440 441- (void)removeStream:(RTCMediaStream *)stream { 442 _peerConnection->RemoveStream(stream.nativeMediaStream); 443 [_localStreams removeObject:stream]; 444} 445 446- (RTCRtpSender *)addTrack:(RTCMediaStreamTrack *)track streamIds:(NSArray<NSString *> *)streamIds { 447 std::vector<std::string> nativeStreamIds; 448 for (NSString *streamId in streamIds) { 449 nativeStreamIds.push_back([streamId UTF8String]); 450 } 451 webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::RtpSenderInterface>> nativeSenderOrError = 452 _peerConnection->AddTrack(track.nativeTrack, nativeStreamIds); 453 if (!nativeSenderOrError.ok()) { 454 RTCLogError(@"Failed to add track %@: %s", track, nativeSenderOrError.error().message()); 455 return nil; 456 } 457 return [[RTCRtpSender alloc] initWithFactory:self.factory 458 nativeRtpSender:nativeSenderOrError.MoveValue()]; 459} 460 461- (BOOL)removeTrack:(RTCRtpSender *)sender { 462 bool result = _peerConnection->RemoveTrack(sender.nativeRtpSender); 463 if (!result) { 464 RTCLogError(@"Failed to remote track %@", sender); 465 } 466 return result; 467} 468 469- (RTCRtpTransceiver *)addTransceiverWithTrack:(RTCMediaStreamTrack *)track { 470 return [self addTransceiverWithTrack:track init:[[RTCRtpTransceiverInit alloc] init]]; 471} 472 473- (RTCRtpTransceiver *)addTransceiverWithTrack:(RTCMediaStreamTrack *)track 474 init:(RTCRtpTransceiverInit *)init { 475 webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>> nativeTransceiverOrError = 476 _peerConnection->AddTransceiver(track.nativeTrack, init.nativeInit); 477 if (!nativeTransceiverOrError.ok()) { 478 RTCLogError( 479 @"Failed to add transceiver %@: %s", track, nativeTransceiverOrError.error().message()); 480 return nil; 481 } 482 return [[RTCRtpTransceiver alloc] initWithFactory:self.factory 483 nativeRtpTransceiver:nativeTransceiverOrError.MoveValue()]; 484} 485 486- (RTCRtpTransceiver *)addTransceiverOfType:(RTCRtpMediaType)mediaType { 487 return [self addTransceiverOfType:mediaType init:[[RTCRtpTransceiverInit alloc] init]]; 488} 489 490- (RTCRtpTransceiver *)addTransceiverOfType:(RTCRtpMediaType)mediaType 491 init:(RTCRtpTransceiverInit *)init { 492 webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>> nativeTransceiverOrError = 493 _peerConnection->AddTransceiver([RTCRtpReceiver nativeMediaTypeForMediaType:mediaType], 494 init.nativeInit); 495 if (!nativeTransceiverOrError.ok()) { 496 RTCLogError(@"Failed to add transceiver %@: %s", 497 [RTCRtpReceiver stringForMediaType:mediaType], 498 nativeTransceiverOrError.error().message()); 499 return nil; 500 } 501 return [[RTCRtpTransceiver alloc] initWithFactory:self.factory 502 nativeRtpTransceiver:nativeTransceiverOrError.MoveValue()]; 503} 504 505- (void)offerForConstraints:(RTCMediaConstraints *)constraints 506 completionHandler: 507 (void (^)(RTCSessionDescription *sessionDescription, 508 NSError *error))completionHandler { 509 rtc::scoped_refptr<webrtc::CreateSessionDescriptionObserverAdapter> 510 observer(new rtc::RefCountedObject 511 <webrtc::CreateSessionDescriptionObserverAdapter>(completionHandler)); 512 webrtc::PeerConnectionInterface::RTCOfferAnswerOptions options; 513 CopyConstraintsIntoOfferAnswerOptions(constraints.nativeConstraints.get(), &options); 514 515 _peerConnection->CreateOffer(observer, options); 516} 517 518- (void)answerForConstraints:(RTCMediaConstraints *)constraints 519 completionHandler: 520 (void (^)(RTCSessionDescription *sessionDescription, 521 NSError *error))completionHandler { 522 rtc::scoped_refptr<webrtc::CreateSessionDescriptionObserverAdapter> 523 observer(new rtc::RefCountedObject 524 <webrtc::CreateSessionDescriptionObserverAdapter>(completionHandler)); 525 webrtc::PeerConnectionInterface::RTCOfferAnswerOptions options; 526 CopyConstraintsIntoOfferAnswerOptions(constraints.nativeConstraints.get(), &options); 527 528 _peerConnection->CreateAnswer(observer, options); 529} 530 531- (void)setLocalDescription:(RTCSessionDescription *)sdp 532 completionHandler:(void (^)(NSError *error))completionHandler { 533 rtc::scoped_refptr<webrtc::SetSessionDescriptionObserverAdapter> observer( 534 new rtc::RefCountedObject<webrtc::SetSessionDescriptionObserverAdapter>( 535 completionHandler)); 536 _peerConnection->SetLocalDescription(observer, sdp.nativeDescription); 537} 538 539- (void)setRemoteDescription:(RTCSessionDescription *)sdp 540 completionHandler:(void (^)(NSError *error))completionHandler { 541 rtc::scoped_refptr<webrtc::SetSessionDescriptionObserverAdapter> observer( 542 new rtc::RefCountedObject<webrtc::SetSessionDescriptionObserverAdapter>( 543 completionHandler)); 544 _peerConnection->SetRemoteDescription(observer, sdp.nativeDescription); 545} 546 547- (BOOL)setBweMinBitrateBps:(nullable NSNumber *)minBitrateBps 548 currentBitrateBps:(nullable NSNumber *)currentBitrateBps 549 maxBitrateBps:(nullable NSNumber *)maxBitrateBps { 550 webrtc::PeerConnectionInterface::BitrateParameters params; 551 if (minBitrateBps != nil) { 552 params.min_bitrate_bps = absl::optional<int>(minBitrateBps.intValue); 553 } 554 if (currentBitrateBps != nil) { 555 params.current_bitrate_bps = absl::optional<int>(currentBitrateBps.intValue); 556 } 557 if (maxBitrateBps != nil) { 558 params.max_bitrate_bps = absl::optional<int>(maxBitrateBps.intValue); 559 } 560 return _peerConnection->SetBitrate(params).ok(); 561} 562 563- (BOOL)startRtcEventLogWithFilePath:(NSString *)filePath 564 maxSizeInBytes:(int64_t)maxSizeInBytes { 565 RTC_DCHECK(filePath.length); 566 RTC_DCHECK_GT(maxSizeInBytes, 0); 567 RTC_DCHECK(!_hasStartedRtcEventLog); 568 if (_hasStartedRtcEventLog) { 569 RTCLogError(@"Event logging already started."); 570 return NO; 571 } 572 FILE *f = fopen(filePath.UTF8String, "wb"); 573 if (!f) { 574 RTCLogError(@"Error opening file: %@. Error: %d", filePath, errno); 575 return NO; 576 } 577 // TODO(eladalon): It would be better to not allow negative values into PC. 578 const size_t max_size = (maxSizeInBytes < 0) ? webrtc::RtcEventLog::kUnlimitedOutput : 579 rtc::saturated_cast<size_t>(maxSizeInBytes); 580 581 _hasStartedRtcEventLog = _peerConnection->StartRtcEventLog( 582 std::make_unique<webrtc::RtcEventLogOutputFile>(f, max_size)); 583 return _hasStartedRtcEventLog; 584} 585 586- (void)stopRtcEventLog { 587 _peerConnection->StopRtcEventLog(); 588 _hasStartedRtcEventLog = NO; 589} 590 591- (RTCRtpSender *)senderWithKind:(NSString *)kind 592 streamId:(NSString *)streamId { 593 std::string nativeKind = [NSString stdStringForString:kind]; 594 std::string nativeStreamId = [NSString stdStringForString:streamId]; 595 rtc::scoped_refptr<webrtc::RtpSenderInterface> nativeSender( 596 _peerConnection->CreateSender(nativeKind, nativeStreamId)); 597 return nativeSender ? 598 [[RTCRtpSender alloc] initWithFactory:self.factory nativeRtpSender:nativeSender] : 599 nil; 600} 601 602- (NSArray<RTCRtpSender *> *)senders { 603 std::vector<rtc::scoped_refptr<webrtc::RtpSenderInterface>> nativeSenders( 604 _peerConnection->GetSenders()); 605 NSMutableArray *senders = [[NSMutableArray alloc] init]; 606 for (const auto &nativeSender : nativeSenders) { 607 RTCRtpSender *sender = 608 [[RTCRtpSender alloc] initWithFactory:self.factory nativeRtpSender:nativeSender]; 609 [senders addObject:sender]; 610 } 611 return senders; 612} 613 614- (NSArray<RTCRtpReceiver *> *)receivers { 615 std::vector<rtc::scoped_refptr<webrtc::RtpReceiverInterface>> nativeReceivers( 616 _peerConnection->GetReceivers()); 617 NSMutableArray *receivers = [[NSMutableArray alloc] init]; 618 for (const auto &nativeReceiver : nativeReceivers) { 619 RTCRtpReceiver *receiver = 620 [[RTCRtpReceiver alloc] initWithFactory:self.factory nativeRtpReceiver:nativeReceiver]; 621 [receivers addObject:receiver]; 622 } 623 return receivers; 624} 625 626- (NSArray<RTCRtpTransceiver *> *)transceivers { 627 std::vector<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>> nativeTransceivers( 628 _peerConnection->GetTransceivers()); 629 NSMutableArray *transceivers = [[NSMutableArray alloc] init]; 630 for (const auto &nativeTransceiver : nativeTransceivers) { 631 RTCRtpTransceiver *transceiver = [[RTCRtpTransceiver alloc] initWithFactory:self.factory 632 nativeRtpTransceiver:nativeTransceiver]; 633 [transceivers addObject:transceiver]; 634 } 635 return transceivers; 636} 637 638#pragma mark - Private 639 640+ (webrtc::PeerConnectionInterface::SignalingState)nativeSignalingStateForState: 641 (RTCSignalingState)state { 642 switch (state) { 643 case RTCSignalingStateStable: 644 return webrtc::PeerConnectionInterface::kStable; 645 case RTCSignalingStateHaveLocalOffer: 646 return webrtc::PeerConnectionInterface::kHaveLocalOffer; 647 case RTCSignalingStateHaveLocalPrAnswer: 648 return webrtc::PeerConnectionInterface::kHaveLocalPrAnswer; 649 case RTCSignalingStateHaveRemoteOffer: 650 return webrtc::PeerConnectionInterface::kHaveRemoteOffer; 651 case RTCSignalingStateHaveRemotePrAnswer: 652 return webrtc::PeerConnectionInterface::kHaveRemotePrAnswer; 653 case RTCSignalingStateClosed: 654 return webrtc::PeerConnectionInterface::kClosed; 655 } 656} 657 658+ (RTCSignalingState)signalingStateForNativeState: 659 (webrtc::PeerConnectionInterface::SignalingState)nativeState { 660 switch (nativeState) { 661 case webrtc::PeerConnectionInterface::kStable: 662 return RTCSignalingStateStable; 663 case webrtc::PeerConnectionInterface::kHaveLocalOffer: 664 return RTCSignalingStateHaveLocalOffer; 665 case webrtc::PeerConnectionInterface::kHaveLocalPrAnswer: 666 return RTCSignalingStateHaveLocalPrAnswer; 667 case webrtc::PeerConnectionInterface::kHaveRemoteOffer: 668 return RTCSignalingStateHaveRemoteOffer; 669 case webrtc::PeerConnectionInterface::kHaveRemotePrAnswer: 670 return RTCSignalingStateHaveRemotePrAnswer; 671 case webrtc::PeerConnectionInterface::kClosed: 672 return RTCSignalingStateClosed; 673 } 674} 675 676+ (NSString *)stringForSignalingState:(RTCSignalingState)state { 677 switch (state) { 678 case RTCSignalingStateStable: 679 return @"STABLE"; 680 case RTCSignalingStateHaveLocalOffer: 681 return @"HAVE_LOCAL_OFFER"; 682 case RTCSignalingStateHaveLocalPrAnswer: 683 return @"HAVE_LOCAL_PRANSWER"; 684 case RTCSignalingStateHaveRemoteOffer: 685 return @"HAVE_REMOTE_OFFER"; 686 case RTCSignalingStateHaveRemotePrAnswer: 687 return @"HAVE_REMOTE_PRANSWER"; 688 case RTCSignalingStateClosed: 689 return @"CLOSED"; 690 } 691} 692 693+ (webrtc::PeerConnectionInterface::PeerConnectionState)nativeConnectionStateForState: 694 (RTCPeerConnectionState)state { 695 switch (state) { 696 case RTCPeerConnectionStateNew: 697 return webrtc::PeerConnectionInterface::PeerConnectionState::kNew; 698 case RTCPeerConnectionStateConnecting: 699 return webrtc::PeerConnectionInterface::PeerConnectionState::kConnecting; 700 case RTCPeerConnectionStateConnected: 701 return webrtc::PeerConnectionInterface::PeerConnectionState::kConnected; 702 case RTCPeerConnectionStateFailed: 703 return webrtc::PeerConnectionInterface::PeerConnectionState::kFailed; 704 case RTCPeerConnectionStateDisconnected: 705 return webrtc::PeerConnectionInterface::PeerConnectionState::kDisconnected; 706 case RTCPeerConnectionStateClosed: 707 return webrtc::PeerConnectionInterface::PeerConnectionState::kClosed; 708 } 709} 710 711+ (RTCPeerConnectionState)connectionStateForNativeState: 712 (webrtc::PeerConnectionInterface::PeerConnectionState)nativeState { 713 switch (nativeState) { 714 case webrtc::PeerConnectionInterface::PeerConnectionState::kNew: 715 return RTCPeerConnectionStateNew; 716 case webrtc::PeerConnectionInterface::PeerConnectionState::kConnecting: 717 return RTCPeerConnectionStateConnecting; 718 case webrtc::PeerConnectionInterface::PeerConnectionState::kConnected: 719 return RTCPeerConnectionStateConnected; 720 case webrtc::PeerConnectionInterface::PeerConnectionState::kFailed: 721 return RTCPeerConnectionStateFailed; 722 case webrtc::PeerConnectionInterface::PeerConnectionState::kDisconnected: 723 return RTCPeerConnectionStateDisconnected; 724 case webrtc::PeerConnectionInterface::PeerConnectionState::kClosed: 725 return RTCPeerConnectionStateClosed; 726 } 727} 728 729+ (NSString *)stringForConnectionState:(RTCPeerConnectionState)state { 730 switch (state) { 731 case RTCPeerConnectionStateNew: 732 return @"NEW"; 733 case RTCPeerConnectionStateConnecting: 734 return @"CONNECTING"; 735 case RTCPeerConnectionStateConnected: 736 return @"CONNECTED"; 737 case RTCPeerConnectionStateFailed: 738 return @"FAILED"; 739 case RTCPeerConnectionStateDisconnected: 740 return @"DISCONNECTED"; 741 case RTCPeerConnectionStateClosed: 742 return @"CLOSED"; 743 } 744} 745 746+ (webrtc::PeerConnectionInterface::IceConnectionState) 747 nativeIceConnectionStateForState:(RTCIceConnectionState)state { 748 switch (state) { 749 case RTCIceConnectionStateNew: 750 return webrtc::PeerConnectionInterface::kIceConnectionNew; 751 case RTCIceConnectionStateChecking: 752 return webrtc::PeerConnectionInterface::kIceConnectionChecking; 753 case RTCIceConnectionStateConnected: 754 return webrtc::PeerConnectionInterface::kIceConnectionConnected; 755 case RTCIceConnectionStateCompleted: 756 return webrtc::PeerConnectionInterface::kIceConnectionCompleted; 757 case RTCIceConnectionStateFailed: 758 return webrtc::PeerConnectionInterface::kIceConnectionFailed; 759 case RTCIceConnectionStateDisconnected: 760 return webrtc::PeerConnectionInterface::kIceConnectionDisconnected; 761 case RTCIceConnectionStateClosed: 762 return webrtc::PeerConnectionInterface::kIceConnectionClosed; 763 case RTCIceConnectionStateCount: 764 return webrtc::PeerConnectionInterface::kIceConnectionMax; 765 } 766} 767 768+ (RTCIceConnectionState)iceConnectionStateForNativeState: 769 (webrtc::PeerConnectionInterface::IceConnectionState)nativeState { 770 switch (nativeState) { 771 case webrtc::PeerConnectionInterface::kIceConnectionNew: 772 return RTCIceConnectionStateNew; 773 case webrtc::PeerConnectionInterface::kIceConnectionChecking: 774 return RTCIceConnectionStateChecking; 775 case webrtc::PeerConnectionInterface::kIceConnectionConnected: 776 return RTCIceConnectionStateConnected; 777 case webrtc::PeerConnectionInterface::kIceConnectionCompleted: 778 return RTCIceConnectionStateCompleted; 779 case webrtc::PeerConnectionInterface::kIceConnectionFailed: 780 return RTCIceConnectionStateFailed; 781 case webrtc::PeerConnectionInterface::kIceConnectionDisconnected: 782 return RTCIceConnectionStateDisconnected; 783 case webrtc::PeerConnectionInterface::kIceConnectionClosed: 784 return RTCIceConnectionStateClosed; 785 case webrtc::PeerConnectionInterface::kIceConnectionMax: 786 return RTCIceConnectionStateCount; 787 } 788} 789 790+ (NSString *)stringForIceConnectionState:(RTCIceConnectionState)state { 791 switch (state) { 792 case RTCIceConnectionStateNew: 793 return @"NEW"; 794 case RTCIceConnectionStateChecking: 795 return @"CHECKING"; 796 case RTCIceConnectionStateConnected: 797 return @"CONNECTED"; 798 case RTCIceConnectionStateCompleted: 799 return @"COMPLETED"; 800 case RTCIceConnectionStateFailed: 801 return @"FAILED"; 802 case RTCIceConnectionStateDisconnected: 803 return @"DISCONNECTED"; 804 case RTCIceConnectionStateClosed: 805 return @"CLOSED"; 806 case RTCIceConnectionStateCount: 807 return @"COUNT"; 808 } 809} 810 811+ (webrtc::PeerConnectionInterface::IceGatheringState) 812 nativeIceGatheringStateForState:(RTCIceGatheringState)state { 813 switch (state) { 814 case RTCIceGatheringStateNew: 815 return webrtc::PeerConnectionInterface::kIceGatheringNew; 816 case RTCIceGatheringStateGathering: 817 return webrtc::PeerConnectionInterface::kIceGatheringGathering; 818 case RTCIceGatheringStateComplete: 819 return webrtc::PeerConnectionInterface::kIceGatheringComplete; 820 } 821} 822 823+ (RTCIceGatheringState)iceGatheringStateForNativeState: 824 (webrtc::PeerConnectionInterface::IceGatheringState)nativeState { 825 switch (nativeState) { 826 case webrtc::PeerConnectionInterface::kIceGatheringNew: 827 return RTCIceGatheringStateNew; 828 case webrtc::PeerConnectionInterface::kIceGatheringGathering: 829 return RTCIceGatheringStateGathering; 830 case webrtc::PeerConnectionInterface::kIceGatheringComplete: 831 return RTCIceGatheringStateComplete; 832 } 833} 834 835+ (NSString *)stringForIceGatheringState:(RTCIceGatheringState)state { 836 switch (state) { 837 case RTCIceGatheringStateNew: 838 return @"NEW"; 839 case RTCIceGatheringStateGathering: 840 return @"GATHERING"; 841 case RTCIceGatheringStateComplete: 842 return @"COMPLETE"; 843 } 844} 845 846+ (webrtc::PeerConnectionInterface::StatsOutputLevel) 847 nativeStatsOutputLevelForLevel:(RTCStatsOutputLevel)level { 848 switch (level) { 849 case RTCStatsOutputLevelStandard: 850 return webrtc::PeerConnectionInterface::kStatsOutputLevelStandard; 851 case RTCStatsOutputLevelDebug: 852 return webrtc::PeerConnectionInterface::kStatsOutputLevelDebug; 853 } 854} 855 856- (rtc::scoped_refptr<webrtc::PeerConnectionInterface>)nativePeerConnection { 857 return _peerConnection; 858} 859 860@end 861