blob: f4db472380a0084e3ec1e2e49b3d8068a885b5cb [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"
Jaehyun Kod2110982021-11-30 19:01:43 +090016#import "RTCIceCandidateErrorEvent+Private.h"
hbosbd3dda62016-09-09 01:36:28 -070017#import "RTCLegacyStatsReport+Private.h"
tkchin9eeb6242016-04-27 01:54:20 -070018#import "RTCMediaConstraints+Private.h"
19#import "RTCMediaStream+Private.h"
Steve Anton8cb344a2018-02-27 15:34:53 -080020#import "RTCMediaStreamTrack+Private.h"
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"
Artem Titov63ee39d2022-05-13 14:46:42 +000027#import "helpers/NSString+StdString.h"
hjonf396f602016-02-11 16:19:06 -080028
kwibergbfefb032016-05-01 14:53:46 -070029#include <memory>
30
Steve Anton10542f22019-01-11 09:11:00 -080031#include "api/jsep_ice_candidate.h"
Niels Möller695cf6a2019-05-13 12:27:23 +020032#include "api/rtc_event_log_output_file.h"
Yura Yaroshevichd6725352021-03-05 18:21:16 +030033#include "api/set_local_description_observer_interface.h"
34#include "api/set_remote_description_observer_interface.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020035#include "rtc_base/checks.h"
Niels Möller695cf6a2019-05-13 12:27:23 +020036#include "rtc_base/numerics/safe_conversions.h"
Yury Yaroshevich19a6e942022-03-11 09:22:08 +010037#include "sdk/objc/native/api/ssl_certificate_verifier.h"
hjonf396f602016-02-11 16:19:06 -080038
Mirko Bonadeia81e9c82020-05-04 16:14:32 +020039NSString *const kRTCPeerConnectionErrorDomain = @"org.webrtc.RTC_OBJC_TYPE(RTCPeerConnection)";
hjonf396f602016-02-11 16:19:06 -080040int const kRTCPeerConnnectionSessionDescriptionError = -1;
41
Yura Yaroshevichd6725352021-03-05 18:21:16 +030042namespace {
43
44class SetSessionDescriptionObserver : public webrtc::SetLocalDescriptionObserverInterface,
45 public webrtc::SetRemoteDescriptionObserverInterface {
46 public:
Yura Yaroshevich8bfa2752021-03-10 13:07:27 +030047 SetSessionDescriptionObserver(RTCSetSessionDescriptionCompletionHandler completionHandler) {
Yura Yaroshevichd6725352021-03-05 18:21:16 +030048 completion_handler_ = completionHandler;
49 }
50
51 virtual void OnSetLocalDescriptionComplete(webrtc::RTCError error) override {
Yura Yaroshevich8bfa2752021-03-10 13:07:27 +030052 OnCompelete(error);
Yura Yaroshevichd6725352021-03-05 18:21:16 +030053 }
54
55 virtual void OnSetRemoteDescriptionComplete(webrtc::RTCError error) override {
Yura Yaroshevich8bfa2752021-03-10 13:07:27 +030056 OnCompelete(error);
Yura Yaroshevichd6725352021-03-05 18:21:16 +030057 }
58
59 private:
60 void OnCompelete(webrtc::RTCError error) {
Yura Yaroshevich8bfa2752021-03-10 13:07:27 +030061 RTC_DCHECK(completion_handler_ != nil);
Yura Yaroshevichd6725352021-03-05 18:21:16 +030062 if (error.ok()) {
63 completion_handler_(nil);
64 } else {
65 // TODO(hta): Add handling of error.type()
Artem Titov63ee39d2022-05-13 14:46:42 +000066 NSString *str = [NSString stringForStdString:error.message()];
Yura Yaroshevichd6725352021-03-05 18:21:16 +030067 NSError *err = [NSError errorWithDomain:kRTCPeerConnectionErrorDomain
68 code:kRTCPeerConnnectionSessionDescriptionError
69 userInfo:@{NSLocalizedDescriptionKey : str}];
70 completion_handler_(err);
71 }
72 completion_handler_ = nil;
73 }
74 RTCSetSessionDescriptionCompletionHandler completion_handler_;
75};
76
77} // anonymous namespace
78
hjonf396f602016-02-11 16:19:06 -080079namespace webrtc {
80
81class CreateSessionDescriptionObserverAdapter
82 : public CreateSessionDescriptionObserver {
83 public:
Mirko Bonadeia81e9c82020-05-04 16:14:32 +020084 CreateSessionDescriptionObserverAdapter(void (^completionHandler)(
85 RTC_OBJC_TYPE(RTCSessionDescription) * sessionDescription, NSError *error)) {
hjonf396f602016-02-11 16:19:06 -080086 completion_handler_ = completionHandler;
87 }
88
Mirko Bonadei17aff352018-07-26 12:20:40 +020089 ~CreateSessionDescriptionObserverAdapter() override { completion_handler_ = nil; }
hjonf396f602016-02-11 16:19:06 -080090
91 void OnSuccess(SessionDescriptionInterface *desc) override {
92 RTC_DCHECK(completion_handler_);
kwibergbfefb032016-05-01 14:53:46 -070093 std::unique_ptr<webrtc::SessionDescriptionInterface> description =
94 std::unique_ptr<webrtc::SessionDescriptionInterface>(desc);
Mirko Bonadeia81e9c82020-05-04 16:14:32 +020095 RTC_OBJC_TYPE(RTCSessionDescription) *session =
96 [[RTC_OBJC_TYPE(RTCSessionDescription) alloc] initWithNativeDescription:description.get()];
hjonf396f602016-02-11 16:19:06 -080097 completion_handler_(session, nil);
98 completion_handler_ = nil;
99 }
100
Harald Alvestrand73771a82018-05-24 10:53:49 +0200101 void OnFailure(RTCError error) override {
hjonf396f602016-02-11 16:19:06 -0800102 RTC_DCHECK(completion_handler_);
Harald Alvestrand73771a82018-05-24 10:53:49 +0200103 // TODO(hta): Add handling of error.type()
Artem Titov63ee39d2022-05-13 14:46:42 +0000104 NSString *str = [NSString stringForStdString:error.message()];
hjonf396f602016-02-11 16:19:06 -0800105 NSError* err =
106 [NSError errorWithDomain:kRTCPeerConnectionErrorDomain
107 code:kRTCPeerConnnectionSessionDescriptionError
108 userInfo:@{ NSLocalizedDescriptionKey : str }];
109 completion_handler_(nil, err);
110 completion_handler_ = nil;
111 }
112
113 private:
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200114 void (^completion_handler_)(RTC_OBJC_TYPE(RTCSessionDescription) * sessionDescription,
115 NSError *error);
hjonf396f602016-02-11 16:19:06 -0800116};
117
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200118PeerConnectionDelegateAdapter::PeerConnectionDelegateAdapter(RTC_OBJC_TYPE(RTCPeerConnection) *
119 peerConnection) {
hjonf396f602016-02-11 16:19:06 -0800120 peer_connection_ = peerConnection;
121}
122
123PeerConnectionDelegateAdapter::~PeerConnectionDelegateAdapter() {
124 peer_connection_ = nil;
125}
126
127void PeerConnectionDelegateAdapter::OnSignalingChange(
128 PeerConnectionInterface::SignalingState new_state) {
129 RTCSignalingState state =
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200130 [[RTC_OBJC_TYPE(RTCPeerConnection) class] signalingStateForNativeState:new_state];
131 RTC_OBJC_TYPE(RTCPeerConnection) *peer_connection = peer_connection_;
hjonf396f602016-02-11 16:19:06 -0800132 [peer_connection.delegate peerConnection:peer_connection
133 didChangeSignalingState:state];
134}
135
136void PeerConnectionDelegateAdapter::OnAddStream(
deadbeefd5f41ce2016-06-08 13:31:45 -0700137 rtc::scoped_refptr<MediaStreamInterface> stream) {
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200138 RTC_OBJC_TYPE(RTCPeerConnection) *peer_connection = peer_connection_;
139 RTC_OBJC_TYPE(RTCMediaStream) *mediaStream =
140 [[RTC_OBJC_TYPE(RTCMediaStream) alloc] initWithFactory:peer_connection.factory
141 nativeMediaStream:stream];
hjonf396f602016-02-11 16:19:06 -0800142 [peer_connection.delegate peerConnection:peer_connection
143 didAddStream:mediaStream];
144}
145
146void PeerConnectionDelegateAdapter::OnRemoveStream(
deadbeefd5f41ce2016-06-08 13:31:45 -0700147 rtc::scoped_refptr<MediaStreamInterface> stream) {
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200148 RTC_OBJC_TYPE(RTCPeerConnection) *peer_connection = peer_connection_;
149 RTC_OBJC_TYPE(RTCMediaStream) *mediaStream =
150 [[RTC_OBJC_TYPE(RTCMediaStream) alloc] initWithFactory:peer_connection.factory
151 nativeMediaStream:stream];
Yura Yaroshevichc806c1d2018-06-21 12:51:11 +0300152
hjonf396f602016-02-11 16:19:06 -0800153 [peer_connection.delegate peerConnection:peer_connection
154 didRemoveStream:mediaStream];
155}
156
Steve Anton8cb344a2018-02-27 15:34:53 -0800157void PeerConnectionDelegateAdapter::OnTrack(
158 rtc::scoped_refptr<RtpTransceiverInterface> nativeTransceiver) {
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200159 RTC_OBJC_TYPE(RTCPeerConnection) *peer_connection = peer_connection_;
160 RTC_OBJC_TYPE(RTCRtpTransceiver) *transceiver =
161 [[RTC_OBJC_TYPE(RTCRtpTransceiver) alloc] initWithFactory:peer_connection.factory
162 nativeRtpTransceiver:nativeTransceiver];
Steve Anton8cb344a2018-02-27 15:34:53 -0800163 if ([peer_connection.delegate
164 respondsToSelector:@selector(peerConnection:didStartReceivingOnTransceiver:)]) {
165 [peer_connection.delegate peerConnection:peer_connection
166 didStartReceivingOnTransceiver:transceiver];
167 }
168}
169
hjonf396f602016-02-11 16:19:06 -0800170void PeerConnectionDelegateAdapter::OnDataChannel(
deadbeefd5f41ce2016-06-08 13:31:45 -0700171 rtc::scoped_refptr<DataChannelInterface> data_channel) {
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200172 RTC_OBJC_TYPE(RTCPeerConnection) *peer_connection = peer_connection_;
173 RTC_OBJC_TYPE(RTCDataChannel) *dataChannel =
174 [[RTC_OBJC_TYPE(RTCDataChannel) alloc] initWithFactory:peer_connection.factory
175 nativeDataChannel:data_channel];
hjonf396f602016-02-11 16:19:06 -0800176 [peer_connection.delegate peerConnection:peer_connection
177 didOpenDataChannel:dataChannel];
178}
179
180void PeerConnectionDelegateAdapter::OnRenegotiationNeeded() {
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200181 RTC_OBJC_TYPE(RTCPeerConnection) *peer_connection = peer_connection_;
hjonf396f602016-02-11 16:19:06 -0800182 [peer_connection.delegate peerConnectionShouldNegotiate:peer_connection];
183}
184
185void PeerConnectionDelegateAdapter::OnIceConnectionChange(
186 PeerConnectionInterface::IceConnectionState new_state) {
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200187 RTCIceConnectionState state =
188 [RTC_OBJC_TYPE(RTCPeerConnection) iceConnectionStateForNativeState:new_state];
Jonas Olssoncfddbb72018-11-15 16:52:45 +0100189 [peer_connection_.delegate peerConnection:peer_connection_ didChangeIceConnectionState:state];
190}
191
Qingsi Wang36e31472019-05-29 11:37:26 -0700192void PeerConnectionDelegateAdapter::OnStandardizedIceConnectionChange(
193 PeerConnectionInterface::IceConnectionState new_state) {
194 if ([peer_connection_.delegate
195 respondsToSelector:@selector(peerConnection:didChangeStandardizedIceConnectionState:)]) {
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200196 RTCIceConnectionState state =
197 [RTC_OBJC_TYPE(RTCPeerConnection) iceConnectionStateForNativeState:new_state];
Qingsi Wang36e31472019-05-29 11:37:26 -0700198 [peer_connection_.delegate peerConnection:peer_connection_
199 didChangeStandardizedIceConnectionState:state];
200 }
201}
202
Jonas Olssoncfddbb72018-11-15 16:52:45 +0100203void PeerConnectionDelegateAdapter::OnConnectionChange(
204 PeerConnectionInterface::PeerConnectionState new_state) {
205 if ([peer_connection_.delegate
206 respondsToSelector:@selector(peerConnection:didChangeConnectionState:)]) {
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200207 RTCPeerConnectionState state =
208 [RTC_OBJC_TYPE(RTCPeerConnection) connectionStateForNativeState:new_state];
Jonas Olssoncfddbb72018-11-15 16:52:45 +0100209 [peer_connection_.delegate peerConnection:peer_connection_ didChangeConnectionState:state];
210 }
hjonf396f602016-02-11 16:19:06 -0800211}
212
213void PeerConnectionDelegateAdapter::OnIceGatheringChange(
214 PeerConnectionInterface::IceGatheringState new_state) {
215 RTCIceGatheringState state =
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200216 [[RTC_OBJC_TYPE(RTCPeerConnection) class] iceGatheringStateForNativeState:new_state];
217 RTC_OBJC_TYPE(RTCPeerConnection) *peer_connection = peer_connection_;
hjonf396f602016-02-11 16:19:06 -0800218 [peer_connection.delegate peerConnection:peer_connection
219 didChangeIceGatheringState:state];
220}
221
222void PeerConnectionDelegateAdapter::OnIceCandidate(
223 const IceCandidateInterface *candidate) {
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200224 RTC_OBJC_TYPE(RTCIceCandidate) *iceCandidate =
225 [[RTC_OBJC_TYPE(RTCIceCandidate) alloc] initWithNativeCandidate:candidate];
226 RTC_OBJC_TYPE(RTCPeerConnection) *peer_connection = peer_connection_;
hjonf396f602016-02-11 16:19:06 -0800227 [peer_connection.delegate peerConnection:peer_connection
228 didGenerateIceCandidate:iceCandidate];
229}
Honghai Zhangda2ba4d2016-05-23 11:53:14 -0700230
Jaehyun Kod2110982021-11-30 19:01:43 +0900231void PeerConnectionDelegateAdapter::OnIceCandidateError(const std::string &address,
232 int port,
233 const std::string &url,
234 int error_code,
235 const std::string &error_text) {
236 RTC_OBJC_TYPE(RTCPeerConnection) *peer_connection = peer_connection_;
237 RTC_OBJC_TYPE(RTCIceCandidateErrorEvent) *event =
238 [[RTC_OBJC_TYPE(RTCIceCandidateErrorEvent) alloc] initWithAddress:address
239 port:port
240 url:url
241 errorCode:error_code
242 errorText:error_text];
Chuck Hays0a3836a2021-12-21 14:24:46 -0600243 if ([peer_connection.delegate respondsToSelector:@selector(peerConnection:
244 didFailToGatherIceCandidate:)]) {
245 [peer_connection.delegate peerConnection:peer_connection didFailToGatherIceCandidate:event];
246 }
Jaehyun Kod2110982021-11-30 19:01:43 +0900247}
248
Honghai Zhangda2ba4d2016-05-23 11:53:14 -0700249void PeerConnectionDelegateAdapter::OnIceCandidatesRemoved(
250 const std::vector<cricket::Candidate>& candidates) {
251 NSMutableArray* ice_candidates =
252 [NSMutableArray arrayWithCapacity:candidates.size()];
253 for (const auto& candidate : candidates) {
254 std::unique_ptr<JsepIceCandidate> candidate_wrapper(
255 new JsepIceCandidate(candidate.transport_name(), -1, candidate));
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200256 RTC_OBJC_TYPE(RTCIceCandidate) *ice_candidate =
257 [[RTC_OBJC_TYPE(RTCIceCandidate) alloc] initWithNativeCandidate:candidate_wrapper.get()];
Honghai Zhangda2ba4d2016-05-23 11:53:14 -0700258 [ice_candidates addObject:ice_candidate];
259 }
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200260 RTC_OBJC_TYPE(RTCPeerConnection) *peer_connection = peer_connection_;
Honghai Zhangda2ba4d2016-05-23 11:53:14 -0700261 [peer_connection.delegate peerConnection:peer_connection
262 didRemoveIceCandidates:ice_candidates];
263}
264
Alex Drake43faee02019-08-12 16:27:34 -0700265void PeerConnectionDelegateAdapter::OnIceSelectedCandidatePairChanged(
266 const cricket::CandidatePairChangeEvent &event) {
Qingsi Wang7cdcda92019-08-28 09:18:37 -0700267 const auto &selected_pair = event.selected_candidate_pair;
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200268 auto local_candidate_wrapper = std::make_unique<JsepIceCandidate>(
Qingsi Wang7cdcda92019-08-28 09:18:37 -0700269 selected_pair.local_candidate().transport_name(), -1, selected_pair.local_candidate());
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200270 RTC_OBJC_TYPE(RTCIceCandidate) *local_candidate = [[RTC_OBJC_TYPE(RTCIceCandidate) alloc]
271 initWithNativeCandidate:local_candidate_wrapper.release()];
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200272 auto remote_candidate_wrapper = std::make_unique<JsepIceCandidate>(
Qingsi Wang7cdcda92019-08-28 09:18:37 -0700273 selected_pair.remote_candidate().transport_name(), -1, selected_pair.remote_candidate());
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200274 RTC_OBJC_TYPE(RTCIceCandidate) *remote_candidate = [[RTC_OBJC_TYPE(RTCIceCandidate) alloc]
275 initWithNativeCandidate:remote_candidate_wrapper.release()];
276 RTC_OBJC_TYPE(RTCPeerConnection) *peer_connection = peer_connection_;
Artem Titov63ee39d2022-05-13 14:46:42 +0000277 NSString *nsstr_reason = [NSString stringForStdString:event.reason];
Alex Drake43faee02019-08-12 16:27:34 -0700278 if ([peer_connection.delegate
279 respondsToSelector:@selector
280 (peerConnection:didChangeLocalCandidate:remoteCandidate:lastReceivedMs:changeReason:)]) {
281 [peer_connection.delegate peerConnection:peer_connection
282 didChangeLocalCandidate:local_candidate
283 remoteCandidate:remote_candidate
284 lastReceivedMs:event.last_data_received_ms
285 changeReason:nsstr_reason];
286 }
287}
288
Yura Yaroshevich546d7f92018-02-28 21:06:34 +0300289void PeerConnectionDelegateAdapter::OnAddTrack(
290 rtc::scoped_refptr<RtpReceiverInterface> receiver,
Alex Drake43faee02019-08-12 16:27:34 -0700291 const std::vector<rtc::scoped_refptr<MediaStreamInterface>> &streams) {
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200292 RTC_OBJC_TYPE(RTCPeerConnection) *peer_connection = peer_connection_;
Alex Drake43faee02019-08-12 16:27:34 -0700293 if ([peer_connection.delegate respondsToSelector:@selector(peerConnection:
294 didAddReceiver:streams:)]) {
Yura Yaroshevich546d7f92018-02-28 21:06:34 +0300295 NSMutableArray *mediaStreams = [NSMutableArray arrayWithCapacity:streams.size()];
Alex Drake43faee02019-08-12 16:27:34 -0700296 for (const auto &nativeStream : streams) {
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200297 RTC_OBJC_TYPE(RTCMediaStream) *mediaStream =
298 [[RTC_OBJC_TYPE(RTCMediaStream) alloc] initWithFactory:peer_connection.factory
299 nativeMediaStream:nativeStream];
Yura Yaroshevich546d7f92018-02-28 21:06:34 +0300300 [mediaStreams addObject:mediaStream];
301 }
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200302 RTC_OBJC_TYPE(RTCRtpReceiver) *rtpReceiver =
303 [[RTC_OBJC_TYPE(RTCRtpReceiver) alloc] initWithFactory:peer_connection.factory
304 nativeRtpReceiver:receiver];
Yura Yaroshevich546d7f92018-02-28 21:06:34 +0300305
306 [peer_connection.delegate peerConnection:peer_connection
307 didAddReceiver:rtpReceiver
308 streams:mediaStreams];
309 }
310}
311
Zeke Chin8de502b2018-08-21 11:41:07 -0700312void PeerConnectionDelegateAdapter::OnRemoveTrack(
313 rtc::scoped_refptr<RtpReceiverInterface> receiver) {
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200314 RTC_OBJC_TYPE(RTCPeerConnection) *peer_connection = peer_connection_;
Zeke Chin8de502b2018-08-21 11:41:07 -0700315 if ([peer_connection.delegate respondsToSelector:@selector(peerConnection:didRemoveReceiver:)]) {
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200316 RTC_OBJC_TYPE(RTCRtpReceiver) *rtpReceiver =
317 [[RTC_OBJC_TYPE(RTCRtpReceiver) alloc] initWithFactory:peer_connection.factory
318 nativeRtpReceiver:receiver];
Zeke Chin8de502b2018-08-21 11:41:07 -0700319 [peer_connection.delegate peerConnection:peer_connection didRemoveReceiver:rtpReceiver];
320 }
321}
322
hjonf396f602016-02-11 16:19:06 -0800323} // namespace webrtc
324
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200325@implementation RTC_OBJC_TYPE (RTCPeerConnection) {
326 RTC_OBJC_TYPE(RTCPeerConnectionFactory) * _factory;
327 NSMutableArray<RTC_OBJC_TYPE(RTCMediaStream) *> *_localStreams;
kwibergbfefb032016-05-01 14:53:46 -0700328 std::unique_ptr<webrtc::PeerConnectionDelegateAdapter> _observer;
hjonf396f602016-02-11 16:19:06 -0800329 rtc::scoped_refptr<webrtc::PeerConnectionInterface> _peerConnection;
deadbeef5d0b6d82017-01-09 16:05:28 -0800330 std::unique_ptr<webrtc::MediaConstraints> _nativeConstraints;
ivoc14d5dbe2016-07-04 07:06:55 -0700331 BOOL _hasStartedRtcEventLog;
hjonf396f602016-02-11 16:19:06 -0800332}
333
334@synthesize delegate = _delegate;
Yura Yaroshevichc806c1d2018-06-21 12:51:11 +0300335@synthesize factory = _factory;
hjonf396f602016-02-11 16:19:06 -0800336
Yura Yaroshevichd140c8f2021-03-02 23:25:10 +0300337- (nullable instancetype)initWithFactory:(RTC_OBJC_TYPE(RTCPeerConnectionFactory) *)factory
338 configuration:(RTC_OBJC_TYPE(RTCConfiguration) *)configuration
339 constraints:(RTC_OBJC_TYPE(RTCMediaConstraints) *)constraints
Yury Yaroshevich19a6e942022-03-11 09:22:08 +0100340 certificateVerifier:
341 (nullable id<RTC_OBJC_TYPE(RTCSSLCertificateVerifier)>)certificateVerifier
Yura Yaroshevichd140c8f2021-03-02 23:25:10 +0300342 delegate:(id<RTC_OBJC_TYPE(RTCPeerConnectionDelegate)>)delegate {
hjonf396f602016-02-11 16:19:06 -0800343 NSParameterAssert(factory);
Jonas Oreland285f83d2020-02-07 10:30:08 +0100344 std::unique_ptr<webrtc::PeerConnectionDependencies> dependencies =
345 std::make_unique<webrtc::PeerConnectionDependencies>(nullptr);
Yury Yaroshevich19a6e942022-03-11 09:22:08 +0100346 if (certificateVerifier != nil) {
347 dependencies->tls_cert_verifier = webrtc::ObjCToNativeCertificateVerifier(certificateVerifier);
348 }
Jonas Oreland285f83d2020-02-07 10:30:08 +0100349 return [self initWithDependencies:factory
350 configuration:configuration
351 constraints:constraints
352 dependencies:std::move(dependencies)
353 delegate:delegate];
354}
355
Yura Yaroshevichd140c8f2021-03-02 23:25:10 +0300356- (nullable instancetype)
357 initWithDependencies:(RTC_OBJC_TYPE(RTCPeerConnectionFactory) *)factory
358 configuration:(RTC_OBJC_TYPE(RTCConfiguration) *)configuration
359 constraints:(RTC_OBJC_TYPE(RTCMediaConstraints) *)constraints
360 dependencies:(std::unique_ptr<webrtc::PeerConnectionDependencies>)dependencies
361 delegate:(id<RTC_OBJC_TYPE(RTCPeerConnectionDelegate)>)delegate {
Jonas Oreland285f83d2020-02-07 10:30:08 +0100362 NSParameterAssert(factory);
363 NSParameterAssert(dependencies.get());
Henrik Boströme06c2dd2016-05-13 13:50:38 +0200364 std::unique_ptr<webrtc::PeerConnectionInterface::RTCConfiguration> config(
hbosa73ca562016-05-17 03:28:58 -0700365 [configuration createNativeConfiguration]);
366 if (!config) {
367 return nil;
368 }
hjonf396f602016-02-11 16:19:06 -0800369 if (self = [super init]) {
370 _observer.reset(new webrtc::PeerConnectionDelegateAdapter(self));
deadbeef5d0b6d82017-01-09 16:05:28 -0800371 _nativeConstraints = constraints.nativeConstraints;
Jonas Oreland285f83d2020-02-07 10:30:08 +0100372 CopyConstraintsIntoRtcConfiguration(_nativeConstraints.get(), config.get());
373
374 webrtc::PeerConnectionDependencies deps = std::move(*dependencies.release());
375 deps.observer = _observer.get();
Harald Alvestrandf33f7a22021-05-09 14:58:57 +0000376 auto result = factory.nativeFactory->CreatePeerConnectionOrError(*config, std::move(deps));
Jonas Oreland285f83d2020-02-07 10:30:08 +0100377
Harald Alvestrandf33f7a22021-05-09 14:58:57 +0000378 if (!result.ok()) {
skvlad588783a2016-08-11 14:29:25 -0700379 return nil;
380 }
Harald Alvestrandf33f7a22021-05-09 14:58:57 +0000381 _peerConnection = result.MoveValue();
Yura Yaroshevich5297bd22018-06-19 12:51:51 +0300382 _factory = factory;
hjonf396f602016-02-11 16:19:06 -0800383 _localStreams = [[NSMutableArray alloc] init];
384 _delegate = delegate;
385 }
386 return self;
387}
388
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200389- (NSArray<RTC_OBJC_TYPE(RTCMediaStream) *> *)localStreams {
hjonf396f602016-02-11 16:19:06 -0800390 return [_localStreams copy];
391}
392
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200393- (RTC_OBJC_TYPE(RTCSessionDescription) *)localDescription {
Taylor Brandstetterc88fe702020-08-03 16:36:16 -0700394 // It's only safe to operate on SessionDescriptionInterface on the signaling thread.
395 return _peerConnection->signaling_thread()->Invoke<RTC_OBJC_TYPE(RTCSessionDescription) *>(
396 RTC_FROM_HERE, [self] {
397 const webrtc::SessionDescriptionInterface *description =
398 _peerConnection->local_description();
399 return description ?
400 [[RTC_OBJC_TYPE(RTCSessionDescription) alloc] initWithNativeDescription:description] :
401 nil;
402 });
hjonf396f602016-02-11 16:19:06 -0800403}
404
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200405- (RTC_OBJC_TYPE(RTCSessionDescription) *)remoteDescription {
Taylor Brandstetterc88fe702020-08-03 16:36:16 -0700406 // It's only safe to operate on SessionDescriptionInterface on the signaling thread.
407 return _peerConnection->signaling_thread()->Invoke<RTC_OBJC_TYPE(RTCSessionDescription) *>(
408 RTC_FROM_HERE, [self] {
409 const webrtc::SessionDescriptionInterface *description =
410 _peerConnection->remote_description();
411 return description ?
412 [[RTC_OBJC_TYPE(RTCSessionDescription) alloc] initWithNativeDescription:description] :
413 nil;
414 });
hjonf396f602016-02-11 16:19:06 -0800415}
416
417- (RTCSignalingState)signalingState {
418 return [[self class]
419 signalingStateForNativeState:_peerConnection->signaling_state()];
420}
421
422- (RTCIceConnectionState)iceConnectionState {
423 return [[self class] iceConnectionStateForNativeState:
424 _peerConnection->ice_connection_state()];
425}
426
Jonas Olssoncfddbb72018-11-15 16:52:45 +0100427- (RTCPeerConnectionState)connectionState {
428 return [[self class] connectionStateForNativeState:_peerConnection->peer_connection_state()];
429}
430
hjonf396f602016-02-11 16:19:06 -0800431- (RTCIceGatheringState)iceGatheringState {
432 return [[self class] iceGatheringStateForNativeState:
433 _peerConnection->ice_gathering_state()];
434}
435
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200436- (BOOL)setConfiguration:(RTC_OBJC_TYPE(RTCConfiguration) *)configuration {
Henrik Boströme06c2dd2016-05-13 13:50:38 +0200437 std::unique_ptr<webrtc::PeerConnectionInterface::RTCConfiguration> config(
hbosa73ca562016-05-17 03:28:58 -0700438 [configuration createNativeConfiguration]);
439 if (!config) {
440 return NO;
441 }
deadbeef5d0b6d82017-01-09 16:05:28 -0800442 CopyConstraintsIntoRtcConfiguration(_nativeConstraints.get(),
443 config.get());
Niels Möller2579f0c2019-08-19 09:58:17 +0200444 return _peerConnection->SetConfiguration(*config).ok();
tkchinaac3eb22016-03-09 21:49:40 -0800445}
446
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200447- (RTC_OBJC_TYPE(RTCConfiguration) *)configuration {
jtteh4eeb5372017-04-03 15:06:37 -0700448 webrtc::PeerConnectionInterface::RTCConfiguration config =
449 _peerConnection->GetConfiguration();
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200450 return [[RTC_OBJC_TYPE(RTCConfiguration) alloc] initWithNativeConfiguration:config];
jtteh4eeb5372017-04-03 15:06:37 -0700451}
452
hjonf396f602016-02-11 16:19:06 -0800453- (void)close {
454 _peerConnection->Close();
455}
456
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200457- (void)addIceCandidate:(RTC_OBJC_TYPE(RTCIceCandidate) *)candidate {
kwibergbfefb032016-05-01 14:53:46 -0700458 std::unique_ptr<const webrtc::IceCandidateInterface> iceCandidate(
hjonf396f602016-02-11 16:19:06 -0800459 candidate.nativeCandidate);
460 _peerConnection->AddIceCandidate(iceCandidate.get());
461}
Yura Yaroshevich2d9f53c2021-03-10 13:03:00 +0300462- (void)addIceCandidate:(RTC_OBJC_TYPE(RTCIceCandidate) *)candidate
463 completionHandler:(void (^)(NSError *_Nullable error))completionHandler {
464 RTC_DCHECK(completionHandler != nil);
Byoungchan Lee8c487572021-08-04 20:55:25 +0900465 _peerConnection->AddIceCandidate(
466 candidate.nativeCandidate, [completionHandler](const auto &error) {
467 if (error.ok()) {
468 completionHandler(nil);
469 } else {
Artem Titov63ee39d2022-05-13 14:46:42 +0000470 NSString *str = [NSString stringForStdString:error.message()];
Byoungchan Lee8c487572021-08-04 20:55:25 +0900471 NSError *err = [NSError errorWithDomain:kRTCPeerConnectionErrorDomain
472 code:static_cast<NSInteger>(error.type())
473 userInfo:@{NSLocalizedDescriptionKey : str}];
474 completionHandler(err);
475 }
476 });
Yura Yaroshevich2d9f53c2021-03-10 13:03:00 +0300477}
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200478- (void)removeIceCandidates:(NSArray<RTC_OBJC_TYPE(RTCIceCandidate) *> *)iceCandidates {
Honghai Zhangda2ba4d2016-05-23 11:53:14 -0700479 std::vector<cricket::Candidate> candidates;
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200480 for (RTC_OBJC_TYPE(RTCIceCandidate) * iceCandidate in iceCandidates) {
Honghai Zhangda2ba4d2016-05-23 11:53:14 -0700481 std::unique_ptr<const webrtc::IceCandidateInterface> candidate(
482 iceCandidate.nativeCandidate);
483 if (candidate) {
484 candidates.push_back(candidate->candidate());
485 // Need to fill the transport name from the sdp_mid.
486 candidates.back().set_transport_name(candidate->sdp_mid());
487 }
488 }
489 if (!candidates.empty()) {
490 _peerConnection->RemoveIceCandidates(candidates);
491 }
492}
493
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200494- (void)addStream:(RTC_OBJC_TYPE(RTCMediaStream) *)stream {
Niels Möller03486fc2022-04-25 10:46:59 +0200495 if (!_peerConnection->AddStream(stream.nativeMediaStream.get())) {
hjonf396f602016-02-11 16:19:06 -0800496 RTCLogError(@"Failed to add stream: %@", stream);
497 return;
498 }
499 [_localStreams addObject:stream];
500}
501
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200502- (void)removeStream:(RTC_OBJC_TYPE(RTCMediaStream) *)stream {
Niels Möller03486fc2022-04-25 10:46:59 +0200503 _peerConnection->RemoveStream(stream.nativeMediaStream.get());
hjonf396f602016-02-11 16:19:06 -0800504 [_localStreams removeObject:stream];
505}
506
Yura Yaroshevichd140c8f2021-03-02 23:25:10 +0300507- (nullable RTC_OBJC_TYPE(RTCRtpSender) *)addTrack:(RTC_OBJC_TYPE(RTCMediaStreamTrack) *)track
508 streamIds:(NSArray<NSString *> *)streamIds {
Seth Hampson513449e2018-03-06 09:35:56 -0800509 std::vector<std::string> nativeStreamIds;
510 for (NSString *streamId in streamIds) {
511 nativeStreamIds.push_back([streamId UTF8String]);
Steve Anton8cb344a2018-02-27 15:34:53 -0800512 }
513 webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::RtpSenderInterface>> nativeSenderOrError =
Seth Hampson513449e2018-03-06 09:35:56 -0800514 _peerConnection->AddTrack(track.nativeTrack, nativeStreamIds);
Steve Anton8cb344a2018-02-27 15:34:53 -0800515 if (!nativeSenderOrError.ok()) {
516 RTCLogError(@"Failed to add track %@: %s", track, nativeSenderOrError.error().message());
517 return nil;
518 }
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200519 return [[RTC_OBJC_TYPE(RTCRtpSender) alloc] initWithFactory:self.factory
520 nativeRtpSender:nativeSenderOrError.MoveValue()];
Steve Anton8cb344a2018-02-27 15:34:53 -0800521}
522
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200523- (BOOL)removeTrack:(RTC_OBJC_TYPE(RTCRtpSender) *)sender {
Harald Alvestrand09a0d012022-01-04 19:42:07 +0000524 bool result = _peerConnection->RemoveTrackOrError(sender.nativeRtpSender).ok();
Steve Anton8cb344a2018-02-27 15:34:53 -0800525 if (!result) {
526 RTCLogError(@"Failed to remote track %@", sender);
527 }
528 return result;
529}
530
Yura Yaroshevichd140c8f2021-03-02 23:25:10 +0300531- (nullable RTC_OBJC_TYPE(RTCRtpTransceiver) *)addTransceiverWithTrack:
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200532 (RTC_OBJC_TYPE(RTCMediaStreamTrack) *)track {
533 return [self addTransceiverWithTrack:track
534 init:[[RTC_OBJC_TYPE(RTCRtpTransceiverInit) alloc] init]];
Steve Anton8cb344a2018-02-27 15:34:53 -0800535}
536
Yura Yaroshevichd140c8f2021-03-02 23:25:10 +0300537- (nullable RTC_OBJC_TYPE(RTCRtpTransceiver) *)
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200538 addTransceiverWithTrack:(RTC_OBJC_TYPE(RTCMediaStreamTrack) *)track
539 init:(RTC_OBJC_TYPE(RTCRtpTransceiverInit) *)init {
Steve Anton8cb344a2018-02-27 15:34:53 -0800540 webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>> nativeTransceiverOrError =
541 _peerConnection->AddTransceiver(track.nativeTrack, init.nativeInit);
542 if (!nativeTransceiverOrError.ok()) {
543 RTCLogError(
544 @"Failed to add transceiver %@: %s", track, nativeTransceiverOrError.error().message());
545 return nil;
546 }
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200547 return [[RTC_OBJC_TYPE(RTCRtpTransceiver) alloc]
548 initWithFactory:self.factory
549 nativeRtpTransceiver:nativeTransceiverOrError.MoveValue()];
Steve Anton8cb344a2018-02-27 15:34:53 -0800550}
551
Yura Yaroshevichd140c8f2021-03-02 23:25:10 +0300552- (nullable RTC_OBJC_TYPE(RTCRtpTransceiver) *)addTransceiverOfType:(RTCRtpMediaType)mediaType {
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200553 return [self addTransceiverOfType:mediaType
554 init:[[RTC_OBJC_TYPE(RTCRtpTransceiverInit) alloc] init]];
Steve Anton8cb344a2018-02-27 15:34:53 -0800555}
556
Yura Yaroshevichd140c8f2021-03-02 23:25:10 +0300557- (nullable RTC_OBJC_TYPE(RTCRtpTransceiver) *)
558 addTransceiverOfType:(RTCRtpMediaType)mediaType
559 init:(RTC_OBJC_TYPE(RTCRtpTransceiverInit) *)init {
Steve Anton8cb344a2018-02-27 15:34:53 -0800560 webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>> nativeTransceiverOrError =
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200561 _peerConnection->AddTransceiver(
562 [RTC_OBJC_TYPE(RTCRtpReceiver) nativeMediaTypeForMediaType:mediaType], init.nativeInit);
Steve Anton8cb344a2018-02-27 15:34:53 -0800563 if (!nativeTransceiverOrError.ok()) {
564 RTCLogError(@"Failed to add transceiver %@: %s",
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200565 [RTC_OBJC_TYPE(RTCRtpReceiver) stringForMediaType:mediaType],
Steve Anton8cb344a2018-02-27 15:34:53 -0800566 nativeTransceiverOrError.error().message());
567 return nil;
568 }
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200569 return [[RTC_OBJC_TYPE(RTCRtpTransceiver) alloc]
570 initWithFactory:self.factory
571 nativeRtpTransceiver:nativeTransceiverOrError.MoveValue()];
Steve Anton8cb344a2018-02-27 15:34:53 -0800572}
573
Yura Yaroshevich92d12702021-03-06 23:55:17 +0300574- (void)restartIce {
575 _peerConnection->RestartIce();
576}
577
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200578- (void)offerForConstraints:(RTC_OBJC_TYPE(RTCMediaConstraints) *)constraints
Yura Yaroshevich8bfa2752021-03-10 13:07:27 +0300579 completionHandler:(RTCCreateSessionDescriptionCompletionHandler)completionHandler {
580 RTC_DCHECK(completionHandler != nil);
Niels Möllerac0d1832022-01-17 15:26:54 +0100581 rtc::scoped_refptr<webrtc::CreateSessionDescriptionObserverAdapter> observer =
582 rtc::make_ref_counted<webrtc::CreateSessionDescriptionObserverAdapter>(completionHandler);
Niels Möllerf06f9232018-08-07 12:32:18 +0200583 webrtc::PeerConnectionInterface::RTCOfferAnswerOptions options;
584 CopyConstraintsIntoOfferAnswerOptions(constraints.nativeConstraints.get(), &options);
585
Niels Möller03486fc2022-04-25 10:46:59 +0200586 _peerConnection->CreateOffer(observer.get(), options);
hjonf396f602016-02-11 16:19:06 -0800587}
588
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200589- (void)answerForConstraints:(RTC_OBJC_TYPE(RTCMediaConstraints) *)constraints
Yura Yaroshevich8bfa2752021-03-10 13:07:27 +0300590 completionHandler:(RTCCreateSessionDescriptionCompletionHandler)completionHandler {
591 RTC_DCHECK(completionHandler != nil);
Niels Möllerac0d1832022-01-17 15:26:54 +0100592 rtc::scoped_refptr<webrtc::CreateSessionDescriptionObserverAdapter> observer =
593 rtc::make_ref_counted<webrtc::CreateSessionDescriptionObserverAdapter>(completionHandler);
Niels Möllerf06f9232018-08-07 12:32:18 +0200594 webrtc::PeerConnectionInterface::RTCOfferAnswerOptions options;
595 CopyConstraintsIntoOfferAnswerOptions(constraints.nativeConstraints.get(), &options);
596
Niels Möller03486fc2022-04-25 10:46:59 +0200597 _peerConnection->CreateAnswer(observer.get(), options);
hjonf396f602016-02-11 16:19:06 -0800598}
599
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200600- (void)setLocalDescription:(RTC_OBJC_TYPE(RTCSessionDescription) *)sdp
Yura Yaroshevich8bfa2752021-03-10 13:07:27 +0300601 completionHandler:(RTCSetSessionDescriptionCompletionHandler)completionHandler {
602 RTC_DCHECK(completionHandler != nil);
Niels Möllerac0d1832022-01-17 15:26:54 +0100603 rtc::scoped_refptr<webrtc::SetLocalDescriptionObserverInterface> observer =
604 rtc::make_ref_counted<::SetSessionDescriptionObserver>(completionHandler);
Byoungchan Lee33728152021-08-04 20:54:45 +0900605 _peerConnection->SetLocalDescription(sdp.nativeDescription, observer);
Yura Yaroshevichd6725352021-03-05 18:21:16 +0300606}
607
608- (void)setLocalDescriptionWithCompletionHandler:
Yura Yaroshevich8bfa2752021-03-10 13:07:27 +0300609 (RTCSetSessionDescriptionCompletionHandler)completionHandler {
610 RTC_DCHECK(completionHandler != nil);
Niels Möllerac0d1832022-01-17 15:26:54 +0100611 rtc::scoped_refptr<webrtc::SetLocalDescriptionObserverInterface> observer =
612 rtc::make_ref_counted<::SetSessionDescriptionObserver>(completionHandler);
Yura Yaroshevichd6725352021-03-05 18:21:16 +0300613 _peerConnection->SetLocalDescription(observer);
hjonf396f602016-02-11 16:19:06 -0800614}
615
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200616- (void)setRemoteDescription:(RTC_OBJC_TYPE(RTCSessionDescription) *)sdp
Yura Yaroshevich8bfa2752021-03-10 13:07:27 +0300617 completionHandler:(RTCSetSessionDescriptionCompletionHandler)completionHandler {
618 RTC_DCHECK(completionHandler != nil);
Niels Möllerac0d1832022-01-17 15:26:54 +0100619 rtc::scoped_refptr<webrtc::SetRemoteDescriptionObserverInterface> observer =
620 rtc::make_ref_counted<::SetSessionDescriptionObserver>(completionHandler);
Byoungchan Lee33728152021-08-04 20:54:45 +0900621 _peerConnection->SetRemoteDescription(sdp.nativeDescription, observer);
hjonf396f602016-02-11 16:19:06 -0800622}
623
zstein8b476172017-09-05 14:43:03 -0700624- (BOOL)setBweMinBitrateBps:(nullable NSNumber *)minBitrateBps
625 currentBitrateBps:(nullable NSNumber *)currentBitrateBps
626 maxBitrateBps:(nullable NSNumber *)maxBitrateBps {
Niels Möller9ad1f6f2020-07-13 10:25:41 +0200627 webrtc::BitrateSettings params;
zstein03adb7c2017-08-09 14:29:42 -0700628 if (minBitrateBps != nil) {
Danil Chapovalov196100e2018-06-21 10:17:24 +0200629 params.min_bitrate_bps = absl::optional<int>(minBitrateBps.intValue);
zstein03adb7c2017-08-09 14:29:42 -0700630 }
631 if (currentBitrateBps != nil) {
Niels Möller9ad1f6f2020-07-13 10:25:41 +0200632 params.start_bitrate_bps = absl::optional<int>(currentBitrateBps.intValue);
zstein03adb7c2017-08-09 14:29:42 -0700633 }
634 if (maxBitrateBps != nil) {
Danil Chapovalov196100e2018-06-21 10:17:24 +0200635 params.max_bitrate_bps = absl::optional<int>(maxBitrateBps.intValue);
zstein03adb7c2017-08-09 14:29:42 -0700636 }
637 return _peerConnection->SetBitrate(params).ok();
638}
639
ivoc14d5dbe2016-07-04 07:06:55 -0700640- (BOOL)startRtcEventLogWithFilePath:(NSString *)filePath
641 maxSizeInBytes:(int64_t)maxSizeInBytes {
642 RTC_DCHECK(filePath.length);
643 RTC_DCHECK_GT(maxSizeInBytes, 0);
644 RTC_DCHECK(!_hasStartedRtcEventLog);
645 if (_hasStartedRtcEventLog) {
646 RTCLogError(@"Event logging already started.");
647 return NO;
648 }
Niels Möllerdec9f742019-06-03 15:25:20 +0200649 FILE *f = fopen(filePath.UTF8String, "wb");
650 if (!f) {
ivoc14d5dbe2016-07-04 07:06:55 -0700651 RTCLogError(@"Error opening file: %@. Error: %d", filePath, errno);
652 return NO;
653 }
Niels Möller695cf6a2019-05-13 12:27:23 +0200654 // TODO(eladalon): It would be better to not allow negative values into PC.
655 const size_t max_size = (maxSizeInBytes < 0) ? webrtc::RtcEventLog::kUnlimitedOutput :
656 rtc::saturated_cast<size_t>(maxSizeInBytes);
657
658 _hasStartedRtcEventLog = _peerConnection->StartRtcEventLog(
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200659 std::make_unique<webrtc::RtcEventLogOutputFile>(f, max_size));
ivoc14d5dbe2016-07-04 07:06:55 -0700660 return _hasStartedRtcEventLog;
661}
662
663- (void)stopRtcEventLog {
664 _peerConnection->StopRtcEventLog();
665 _hasStartedRtcEventLog = NO;
666}
667
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200668- (RTC_OBJC_TYPE(RTCRtpSender) *)senderWithKind:(NSString *)kind streamId:(NSString *)streamId {
Artem Titov63ee39d2022-05-13 14:46:42 +0000669 std::string nativeKind = [NSString stdStringForString:kind];
670 std::string nativeStreamId = [NSString stdStringForString:streamId];
skvladf3569c82016-04-29 15:30:16 -0700671 rtc::scoped_refptr<webrtc::RtpSenderInterface> nativeSender(
672 _peerConnection->CreateSender(nativeKind, nativeStreamId));
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200673 return nativeSender ? [[RTC_OBJC_TYPE(RTCRtpSender) alloc] initWithFactory:self.factory
674 nativeRtpSender:nativeSender] :
675 nil;
skvladf3569c82016-04-29 15:30:16 -0700676}
677
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200678- (NSArray<RTC_OBJC_TYPE(RTCRtpSender) *> *)senders {
skvlad79b4b872016-04-08 17:28:55 -0700679 std::vector<rtc::scoped_refptr<webrtc::RtpSenderInterface>> nativeSenders(
680 _peerConnection->GetSenders());
681 NSMutableArray *senders = [[NSMutableArray alloc] init];
682 for (const auto &nativeSender : nativeSenders) {
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200683 RTC_OBJC_TYPE(RTCRtpSender) *sender =
684 [[RTC_OBJC_TYPE(RTCRtpSender) alloc] initWithFactory:self.factory
685 nativeRtpSender:nativeSender];
skvlad79b4b872016-04-08 17:28:55 -0700686 [senders addObject:sender];
687 }
688 return senders;
689}
690
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200691- (NSArray<RTC_OBJC_TYPE(RTCRtpReceiver) *> *)receivers {
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700692 std::vector<rtc::scoped_refptr<webrtc::RtpReceiverInterface>> nativeReceivers(
693 _peerConnection->GetReceivers());
694 NSMutableArray *receivers = [[NSMutableArray alloc] init];
695 for (const auto &nativeReceiver : nativeReceivers) {
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200696 RTC_OBJC_TYPE(RTCRtpReceiver) *receiver =
697 [[RTC_OBJC_TYPE(RTCRtpReceiver) alloc] initWithFactory:self.factory
698 nativeRtpReceiver:nativeReceiver];
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700699 [receivers addObject:receiver];
700 }
701 return receivers;
702}
703
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200704- (NSArray<RTC_OBJC_TYPE(RTCRtpTransceiver) *> *)transceivers {
Steve Anton8cb344a2018-02-27 15:34:53 -0800705 std::vector<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>> nativeTransceivers(
706 _peerConnection->GetTransceivers());
707 NSMutableArray *transceivers = [[NSMutableArray alloc] init];
Mirko Bonadei739baf02019-01-27 17:29:42 +0100708 for (const auto &nativeTransceiver : nativeTransceivers) {
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200709 RTC_OBJC_TYPE(RTCRtpTransceiver) *transceiver =
710 [[RTC_OBJC_TYPE(RTCRtpTransceiver) alloc] initWithFactory:self.factory
711 nativeRtpTransceiver:nativeTransceiver];
Steve Anton8cb344a2018-02-27 15:34:53 -0800712 [transceivers addObject:transceiver];
713 }
714 return transceivers;
715}
716
hjonf396f602016-02-11 16:19:06 -0800717#pragma mark - Private
718
719+ (webrtc::PeerConnectionInterface::SignalingState)nativeSignalingStateForState:
720 (RTCSignalingState)state {
721 switch (state) {
722 case RTCSignalingStateStable:
723 return webrtc::PeerConnectionInterface::kStable;
724 case RTCSignalingStateHaveLocalOffer:
725 return webrtc::PeerConnectionInterface::kHaveLocalOffer;
726 case RTCSignalingStateHaveLocalPrAnswer:
727 return webrtc::PeerConnectionInterface::kHaveLocalPrAnswer;
728 case RTCSignalingStateHaveRemoteOffer:
729 return webrtc::PeerConnectionInterface::kHaveRemoteOffer;
730 case RTCSignalingStateHaveRemotePrAnswer:
731 return webrtc::PeerConnectionInterface::kHaveRemotePrAnswer;
732 case RTCSignalingStateClosed:
733 return webrtc::PeerConnectionInterface::kClosed;
734 }
735}
736
737+ (RTCSignalingState)signalingStateForNativeState:
738 (webrtc::PeerConnectionInterface::SignalingState)nativeState {
739 switch (nativeState) {
740 case webrtc::PeerConnectionInterface::kStable:
741 return RTCSignalingStateStable;
742 case webrtc::PeerConnectionInterface::kHaveLocalOffer:
743 return RTCSignalingStateHaveLocalOffer;
744 case webrtc::PeerConnectionInterface::kHaveLocalPrAnswer:
745 return RTCSignalingStateHaveLocalPrAnswer;
746 case webrtc::PeerConnectionInterface::kHaveRemoteOffer:
747 return RTCSignalingStateHaveRemoteOffer;
748 case webrtc::PeerConnectionInterface::kHaveRemotePrAnswer:
749 return RTCSignalingStateHaveRemotePrAnswer;
750 case webrtc::PeerConnectionInterface::kClosed:
751 return RTCSignalingStateClosed;
752 }
753}
754
755+ (NSString *)stringForSignalingState:(RTCSignalingState)state {
756 switch (state) {
757 case RTCSignalingStateStable:
758 return @"STABLE";
759 case RTCSignalingStateHaveLocalOffer:
760 return @"HAVE_LOCAL_OFFER";
761 case RTCSignalingStateHaveLocalPrAnswer:
762 return @"HAVE_LOCAL_PRANSWER";
763 case RTCSignalingStateHaveRemoteOffer:
764 return @"HAVE_REMOTE_OFFER";
765 case RTCSignalingStateHaveRemotePrAnswer:
766 return @"HAVE_REMOTE_PRANSWER";
767 case RTCSignalingStateClosed:
768 return @"CLOSED";
769 }
770}
771
Jonas Olssoncfddbb72018-11-15 16:52:45 +0100772+ (webrtc::PeerConnectionInterface::PeerConnectionState)nativeConnectionStateForState:
773 (RTCPeerConnectionState)state {
774 switch (state) {
775 case RTCPeerConnectionStateNew:
776 return webrtc::PeerConnectionInterface::PeerConnectionState::kNew;
777 case RTCPeerConnectionStateConnecting:
778 return webrtc::PeerConnectionInterface::PeerConnectionState::kConnecting;
779 case RTCPeerConnectionStateConnected:
780 return webrtc::PeerConnectionInterface::PeerConnectionState::kConnected;
781 case RTCPeerConnectionStateFailed:
782 return webrtc::PeerConnectionInterface::PeerConnectionState::kFailed;
783 case RTCPeerConnectionStateDisconnected:
784 return webrtc::PeerConnectionInterface::PeerConnectionState::kDisconnected;
785 case RTCPeerConnectionStateClosed:
786 return webrtc::PeerConnectionInterface::PeerConnectionState::kClosed;
787 }
788}
789
790+ (RTCPeerConnectionState)connectionStateForNativeState:
791 (webrtc::PeerConnectionInterface::PeerConnectionState)nativeState {
792 switch (nativeState) {
793 case webrtc::PeerConnectionInterface::PeerConnectionState::kNew:
794 return RTCPeerConnectionStateNew;
795 case webrtc::PeerConnectionInterface::PeerConnectionState::kConnecting:
796 return RTCPeerConnectionStateConnecting;
797 case webrtc::PeerConnectionInterface::PeerConnectionState::kConnected:
798 return RTCPeerConnectionStateConnected;
799 case webrtc::PeerConnectionInterface::PeerConnectionState::kFailed:
800 return RTCPeerConnectionStateFailed;
801 case webrtc::PeerConnectionInterface::PeerConnectionState::kDisconnected:
802 return RTCPeerConnectionStateDisconnected;
803 case webrtc::PeerConnectionInterface::PeerConnectionState::kClosed:
804 return RTCPeerConnectionStateClosed;
805 }
806}
807
808+ (NSString *)stringForConnectionState:(RTCPeerConnectionState)state {
809 switch (state) {
810 case RTCPeerConnectionStateNew:
811 return @"NEW";
812 case RTCPeerConnectionStateConnecting:
813 return @"CONNECTING";
814 case RTCPeerConnectionStateConnected:
815 return @"CONNECTED";
816 case RTCPeerConnectionStateFailed:
817 return @"FAILED";
818 case RTCPeerConnectionStateDisconnected:
819 return @"DISCONNECTED";
820 case RTCPeerConnectionStateClosed:
821 return @"CLOSED";
822 }
823}
824
hjonf396f602016-02-11 16:19:06 -0800825+ (webrtc::PeerConnectionInterface::IceConnectionState)
826 nativeIceConnectionStateForState:(RTCIceConnectionState)state {
827 switch (state) {
828 case RTCIceConnectionStateNew:
829 return webrtc::PeerConnectionInterface::kIceConnectionNew;
830 case RTCIceConnectionStateChecking:
831 return webrtc::PeerConnectionInterface::kIceConnectionChecking;
832 case RTCIceConnectionStateConnected:
833 return webrtc::PeerConnectionInterface::kIceConnectionConnected;
834 case RTCIceConnectionStateCompleted:
835 return webrtc::PeerConnectionInterface::kIceConnectionCompleted;
836 case RTCIceConnectionStateFailed:
837 return webrtc::PeerConnectionInterface::kIceConnectionFailed;
838 case RTCIceConnectionStateDisconnected:
839 return webrtc::PeerConnectionInterface::kIceConnectionDisconnected;
840 case RTCIceConnectionStateClosed:
841 return webrtc::PeerConnectionInterface::kIceConnectionClosed;
hjon8bbbf2c2016-03-14 13:15:44 -0700842 case RTCIceConnectionStateCount:
hjonf396f602016-02-11 16:19:06 -0800843 return webrtc::PeerConnectionInterface::kIceConnectionMax;
844 }
845}
846
847+ (RTCIceConnectionState)iceConnectionStateForNativeState:
848 (webrtc::PeerConnectionInterface::IceConnectionState)nativeState {
849 switch (nativeState) {
850 case webrtc::PeerConnectionInterface::kIceConnectionNew:
851 return RTCIceConnectionStateNew;
852 case webrtc::PeerConnectionInterface::kIceConnectionChecking:
853 return RTCIceConnectionStateChecking;
854 case webrtc::PeerConnectionInterface::kIceConnectionConnected:
855 return RTCIceConnectionStateConnected;
856 case webrtc::PeerConnectionInterface::kIceConnectionCompleted:
857 return RTCIceConnectionStateCompleted;
858 case webrtc::PeerConnectionInterface::kIceConnectionFailed:
859 return RTCIceConnectionStateFailed;
860 case webrtc::PeerConnectionInterface::kIceConnectionDisconnected:
861 return RTCIceConnectionStateDisconnected;
862 case webrtc::PeerConnectionInterface::kIceConnectionClosed:
863 return RTCIceConnectionStateClosed;
864 case webrtc::PeerConnectionInterface::kIceConnectionMax:
hjon8bbbf2c2016-03-14 13:15:44 -0700865 return RTCIceConnectionStateCount;
hjonf396f602016-02-11 16:19:06 -0800866 }
867}
868
869+ (NSString *)stringForIceConnectionState:(RTCIceConnectionState)state {
870 switch (state) {
871 case RTCIceConnectionStateNew:
872 return @"NEW";
873 case RTCIceConnectionStateChecking:
874 return @"CHECKING";
875 case RTCIceConnectionStateConnected:
876 return @"CONNECTED";
877 case RTCIceConnectionStateCompleted:
878 return @"COMPLETED";
879 case RTCIceConnectionStateFailed:
880 return @"FAILED";
881 case RTCIceConnectionStateDisconnected:
882 return @"DISCONNECTED";
883 case RTCIceConnectionStateClosed:
884 return @"CLOSED";
hjon8bbbf2c2016-03-14 13:15:44 -0700885 case RTCIceConnectionStateCount:
886 return @"COUNT";
hjonf396f602016-02-11 16:19:06 -0800887 }
888}
889
890+ (webrtc::PeerConnectionInterface::IceGatheringState)
891 nativeIceGatheringStateForState:(RTCIceGatheringState)state {
892 switch (state) {
893 case RTCIceGatheringStateNew:
894 return webrtc::PeerConnectionInterface::kIceGatheringNew;
895 case RTCIceGatheringStateGathering:
896 return webrtc::PeerConnectionInterface::kIceGatheringGathering;
897 case RTCIceGatheringStateComplete:
898 return webrtc::PeerConnectionInterface::kIceGatheringComplete;
899 }
900}
901
902+ (RTCIceGatheringState)iceGatheringStateForNativeState:
903 (webrtc::PeerConnectionInterface::IceGatheringState)nativeState {
904 switch (nativeState) {
905 case webrtc::PeerConnectionInterface::kIceGatheringNew:
906 return RTCIceGatheringStateNew;
907 case webrtc::PeerConnectionInterface::kIceGatheringGathering:
908 return RTCIceGatheringStateGathering;
909 case webrtc::PeerConnectionInterface::kIceGatheringComplete:
910 return RTCIceGatheringStateComplete;
911 }
912}
913
914+ (NSString *)stringForIceGatheringState:(RTCIceGatheringState)state {
915 switch (state) {
916 case RTCIceGatheringStateNew:
917 return @"NEW";
918 case RTCIceGatheringStateGathering:
919 return @"GATHERING";
920 case RTCIceGatheringStateComplete:
921 return @"COMPLETE";
922 }
923}
924
925+ (webrtc::PeerConnectionInterface::StatsOutputLevel)
926 nativeStatsOutputLevelForLevel:(RTCStatsOutputLevel)level {
927 switch (level) {
928 case RTCStatsOutputLevelStandard:
929 return webrtc::PeerConnectionInterface::kStatsOutputLevelStandard;
930 case RTCStatsOutputLevelDebug:
931 return webrtc::PeerConnectionInterface::kStatsOutputLevelDebug;
932 }
933}
934
hjonf396f602016-02-11 16:19:06 -0800935- (rtc::scoped_refptr<webrtc::PeerConnectionInterface>)nativePeerConnection {
936 return _peerConnection;
937}
938
939@end