blob: df9903011123a97ae331ef0ccf3fd0f42456fada [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.
Danil Chapovalov9e09a1f2022-09-08 18:38:10 +0200395 return _peerConnection->signaling_thread()->BlockingCall([self] {
396 const webrtc::SessionDescriptionInterface *description = _peerConnection->local_description();
397 return description ?
398 [[RTC_OBJC_TYPE(RTCSessionDescription) alloc] initWithNativeDescription:description] :
399 nil;
400 });
hjonf396f602016-02-11 16:19:06 -0800401}
402
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200403- (RTC_OBJC_TYPE(RTCSessionDescription) *)remoteDescription {
Taylor Brandstetterc88fe702020-08-03 16:36:16 -0700404 // It's only safe to operate on SessionDescriptionInterface on the signaling thread.
Danil Chapovalov9e09a1f2022-09-08 18:38:10 +0200405 return _peerConnection->signaling_thread()->BlockingCall([self] {
406 const webrtc::SessionDescriptionInterface *description = _peerConnection->remote_description();
407 return description ?
408 [[RTC_OBJC_TYPE(RTCSessionDescription) alloc] initWithNativeDescription:description] :
409 nil;
410 });
hjonf396f602016-02-11 16:19:06 -0800411}
412
413- (RTCSignalingState)signalingState {
414 return [[self class]
415 signalingStateForNativeState:_peerConnection->signaling_state()];
416}
417
418- (RTCIceConnectionState)iceConnectionState {
419 return [[self class] iceConnectionStateForNativeState:
420 _peerConnection->ice_connection_state()];
421}
422
Jonas Olssoncfddbb72018-11-15 16:52:45 +0100423- (RTCPeerConnectionState)connectionState {
424 return [[self class] connectionStateForNativeState:_peerConnection->peer_connection_state()];
425}
426
hjonf396f602016-02-11 16:19:06 -0800427- (RTCIceGatheringState)iceGatheringState {
428 return [[self class] iceGatheringStateForNativeState:
429 _peerConnection->ice_gathering_state()];
430}
431
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200432- (BOOL)setConfiguration:(RTC_OBJC_TYPE(RTCConfiguration) *)configuration {
Henrik Boströme06c2dd2016-05-13 13:50:38 +0200433 std::unique_ptr<webrtc::PeerConnectionInterface::RTCConfiguration> config(
hbosa73ca562016-05-17 03:28:58 -0700434 [configuration createNativeConfiguration]);
435 if (!config) {
436 return NO;
437 }
deadbeef5d0b6d82017-01-09 16:05:28 -0800438 CopyConstraintsIntoRtcConfiguration(_nativeConstraints.get(),
439 config.get());
Niels Möller2579f0c2019-08-19 09:58:17 +0200440 return _peerConnection->SetConfiguration(*config).ok();
tkchinaac3eb22016-03-09 21:49:40 -0800441}
442
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200443- (RTC_OBJC_TYPE(RTCConfiguration) *)configuration {
jtteh4eeb5372017-04-03 15:06:37 -0700444 webrtc::PeerConnectionInterface::RTCConfiguration config =
445 _peerConnection->GetConfiguration();
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200446 return [[RTC_OBJC_TYPE(RTCConfiguration) alloc] initWithNativeConfiguration:config];
jtteh4eeb5372017-04-03 15:06:37 -0700447}
448
hjonf396f602016-02-11 16:19:06 -0800449- (void)close {
450 _peerConnection->Close();
451}
452
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200453- (void)addIceCandidate:(RTC_OBJC_TYPE(RTCIceCandidate) *)candidate {
kwibergbfefb032016-05-01 14:53:46 -0700454 std::unique_ptr<const webrtc::IceCandidateInterface> iceCandidate(
hjonf396f602016-02-11 16:19:06 -0800455 candidate.nativeCandidate);
456 _peerConnection->AddIceCandidate(iceCandidate.get());
457}
Yura Yaroshevich2d9f53c2021-03-10 13:03:00 +0300458- (void)addIceCandidate:(RTC_OBJC_TYPE(RTCIceCandidate) *)candidate
459 completionHandler:(void (^)(NSError *_Nullable error))completionHandler {
460 RTC_DCHECK(completionHandler != nil);
Byoungchan Lee8c487572021-08-04 20:55:25 +0900461 _peerConnection->AddIceCandidate(
462 candidate.nativeCandidate, [completionHandler](const auto &error) {
463 if (error.ok()) {
464 completionHandler(nil);
465 } else {
Artem Titov63ee39d2022-05-13 14:46:42 +0000466 NSString *str = [NSString stringForStdString:error.message()];
Byoungchan Lee8c487572021-08-04 20:55:25 +0900467 NSError *err = [NSError errorWithDomain:kRTCPeerConnectionErrorDomain
468 code:static_cast<NSInteger>(error.type())
469 userInfo:@{NSLocalizedDescriptionKey : str}];
470 completionHandler(err);
471 }
472 });
Yura Yaroshevich2d9f53c2021-03-10 13:03:00 +0300473}
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200474- (void)removeIceCandidates:(NSArray<RTC_OBJC_TYPE(RTCIceCandidate) *> *)iceCandidates {
Honghai Zhangda2ba4d2016-05-23 11:53:14 -0700475 std::vector<cricket::Candidate> candidates;
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200476 for (RTC_OBJC_TYPE(RTCIceCandidate) * iceCandidate in iceCandidates) {
Honghai Zhangda2ba4d2016-05-23 11:53:14 -0700477 std::unique_ptr<const webrtc::IceCandidateInterface> candidate(
478 iceCandidate.nativeCandidate);
479 if (candidate) {
480 candidates.push_back(candidate->candidate());
481 // Need to fill the transport name from the sdp_mid.
482 candidates.back().set_transport_name(candidate->sdp_mid());
483 }
484 }
485 if (!candidates.empty()) {
486 _peerConnection->RemoveIceCandidates(candidates);
487 }
488}
489
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200490- (void)addStream:(RTC_OBJC_TYPE(RTCMediaStream) *)stream {
Niels Möller03486fc2022-04-25 10:46:59 +0200491 if (!_peerConnection->AddStream(stream.nativeMediaStream.get())) {
hjonf396f602016-02-11 16:19:06 -0800492 RTCLogError(@"Failed to add stream: %@", stream);
493 return;
494 }
495 [_localStreams addObject:stream];
496}
497
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200498- (void)removeStream:(RTC_OBJC_TYPE(RTCMediaStream) *)stream {
Niels Möller03486fc2022-04-25 10:46:59 +0200499 _peerConnection->RemoveStream(stream.nativeMediaStream.get());
hjonf396f602016-02-11 16:19:06 -0800500 [_localStreams removeObject:stream];
501}
502
Yura Yaroshevichd140c8f2021-03-02 23:25:10 +0300503- (nullable RTC_OBJC_TYPE(RTCRtpSender) *)addTrack:(RTC_OBJC_TYPE(RTCMediaStreamTrack) *)track
504 streamIds:(NSArray<NSString *> *)streamIds {
Seth Hampson513449e2018-03-06 09:35:56 -0800505 std::vector<std::string> nativeStreamIds;
506 for (NSString *streamId in streamIds) {
507 nativeStreamIds.push_back([streamId UTF8String]);
Steve Anton8cb344a2018-02-27 15:34:53 -0800508 }
509 webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::RtpSenderInterface>> nativeSenderOrError =
Seth Hampson513449e2018-03-06 09:35:56 -0800510 _peerConnection->AddTrack(track.nativeTrack, nativeStreamIds);
Steve Anton8cb344a2018-02-27 15:34:53 -0800511 if (!nativeSenderOrError.ok()) {
512 RTCLogError(@"Failed to add track %@: %s", track, nativeSenderOrError.error().message());
513 return nil;
514 }
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200515 return [[RTC_OBJC_TYPE(RTCRtpSender) alloc] initWithFactory:self.factory
516 nativeRtpSender:nativeSenderOrError.MoveValue()];
Steve Anton8cb344a2018-02-27 15:34:53 -0800517}
518
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200519- (BOOL)removeTrack:(RTC_OBJC_TYPE(RTCRtpSender) *)sender {
Harald Alvestrand09a0d012022-01-04 19:42:07 +0000520 bool result = _peerConnection->RemoveTrackOrError(sender.nativeRtpSender).ok();
Steve Anton8cb344a2018-02-27 15:34:53 -0800521 if (!result) {
522 RTCLogError(@"Failed to remote track %@", sender);
523 }
524 return result;
525}
526
Yura Yaroshevichd140c8f2021-03-02 23:25:10 +0300527- (nullable RTC_OBJC_TYPE(RTCRtpTransceiver) *)addTransceiverWithTrack:
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200528 (RTC_OBJC_TYPE(RTCMediaStreamTrack) *)track {
529 return [self addTransceiverWithTrack:track
530 init:[[RTC_OBJC_TYPE(RTCRtpTransceiverInit) alloc] init]];
Steve Anton8cb344a2018-02-27 15:34:53 -0800531}
532
Yura Yaroshevichd140c8f2021-03-02 23:25:10 +0300533- (nullable RTC_OBJC_TYPE(RTCRtpTransceiver) *)
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200534 addTransceiverWithTrack:(RTC_OBJC_TYPE(RTCMediaStreamTrack) *)track
535 init:(RTC_OBJC_TYPE(RTCRtpTransceiverInit) *)init {
Steve Anton8cb344a2018-02-27 15:34:53 -0800536 webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>> nativeTransceiverOrError =
537 _peerConnection->AddTransceiver(track.nativeTrack, init.nativeInit);
538 if (!nativeTransceiverOrError.ok()) {
539 RTCLogError(
540 @"Failed to add transceiver %@: %s", track, nativeTransceiverOrError.error().message());
541 return nil;
542 }
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200543 return [[RTC_OBJC_TYPE(RTCRtpTransceiver) alloc]
544 initWithFactory:self.factory
545 nativeRtpTransceiver:nativeTransceiverOrError.MoveValue()];
Steve Anton8cb344a2018-02-27 15:34:53 -0800546}
547
Yura Yaroshevichd140c8f2021-03-02 23:25:10 +0300548- (nullable RTC_OBJC_TYPE(RTCRtpTransceiver) *)addTransceiverOfType:(RTCRtpMediaType)mediaType {
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200549 return [self addTransceiverOfType:mediaType
550 init:[[RTC_OBJC_TYPE(RTCRtpTransceiverInit) alloc] init]];
Steve Anton8cb344a2018-02-27 15:34:53 -0800551}
552
Yura Yaroshevichd140c8f2021-03-02 23:25:10 +0300553- (nullable RTC_OBJC_TYPE(RTCRtpTransceiver) *)
554 addTransceiverOfType:(RTCRtpMediaType)mediaType
555 init:(RTC_OBJC_TYPE(RTCRtpTransceiverInit) *)init {
Steve Anton8cb344a2018-02-27 15:34:53 -0800556 webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>> nativeTransceiverOrError =
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200557 _peerConnection->AddTransceiver(
558 [RTC_OBJC_TYPE(RTCRtpReceiver) nativeMediaTypeForMediaType:mediaType], init.nativeInit);
Steve Anton8cb344a2018-02-27 15:34:53 -0800559 if (!nativeTransceiverOrError.ok()) {
560 RTCLogError(@"Failed to add transceiver %@: %s",
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200561 [RTC_OBJC_TYPE(RTCRtpReceiver) stringForMediaType:mediaType],
Steve Anton8cb344a2018-02-27 15:34:53 -0800562 nativeTransceiverOrError.error().message());
563 return nil;
564 }
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200565 return [[RTC_OBJC_TYPE(RTCRtpTransceiver) alloc]
566 initWithFactory:self.factory
567 nativeRtpTransceiver:nativeTransceiverOrError.MoveValue()];
Steve Anton8cb344a2018-02-27 15:34:53 -0800568}
569
Yura Yaroshevich92d12702021-03-06 23:55:17 +0300570- (void)restartIce {
571 _peerConnection->RestartIce();
572}
573
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200574- (void)offerForConstraints:(RTC_OBJC_TYPE(RTCMediaConstraints) *)constraints
Yura Yaroshevich8bfa2752021-03-10 13:07:27 +0300575 completionHandler:(RTCCreateSessionDescriptionCompletionHandler)completionHandler {
576 RTC_DCHECK(completionHandler != nil);
Niels Möllerac0d1832022-01-17 15:26:54 +0100577 rtc::scoped_refptr<webrtc::CreateSessionDescriptionObserverAdapter> observer =
578 rtc::make_ref_counted<webrtc::CreateSessionDescriptionObserverAdapter>(completionHandler);
Niels Möllerf06f9232018-08-07 12:32:18 +0200579 webrtc::PeerConnectionInterface::RTCOfferAnswerOptions options;
580 CopyConstraintsIntoOfferAnswerOptions(constraints.nativeConstraints.get(), &options);
581
Niels Möller03486fc2022-04-25 10:46:59 +0200582 _peerConnection->CreateOffer(observer.get(), options);
hjonf396f602016-02-11 16:19:06 -0800583}
584
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200585- (void)answerForConstraints:(RTC_OBJC_TYPE(RTCMediaConstraints) *)constraints
Yura Yaroshevich8bfa2752021-03-10 13:07:27 +0300586 completionHandler:(RTCCreateSessionDescriptionCompletionHandler)completionHandler {
587 RTC_DCHECK(completionHandler != nil);
Niels Möllerac0d1832022-01-17 15:26:54 +0100588 rtc::scoped_refptr<webrtc::CreateSessionDescriptionObserverAdapter> observer =
589 rtc::make_ref_counted<webrtc::CreateSessionDescriptionObserverAdapter>(completionHandler);
Niels Möllerf06f9232018-08-07 12:32:18 +0200590 webrtc::PeerConnectionInterface::RTCOfferAnswerOptions options;
591 CopyConstraintsIntoOfferAnswerOptions(constraints.nativeConstraints.get(), &options);
592
Niels Möller03486fc2022-04-25 10:46:59 +0200593 _peerConnection->CreateAnswer(observer.get(), options);
hjonf396f602016-02-11 16:19:06 -0800594}
595
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200596- (void)setLocalDescription:(RTC_OBJC_TYPE(RTCSessionDescription) *)sdp
Yura Yaroshevich8bfa2752021-03-10 13:07:27 +0300597 completionHandler:(RTCSetSessionDescriptionCompletionHandler)completionHandler {
598 RTC_DCHECK(completionHandler != nil);
Niels Möllerac0d1832022-01-17 15:26:54 +0100599 rtc::scoped_refptr<webrtc::SetLocalDescriptionObserverInterface> observer =
600 rtc::make_ref_counted<::SetSessionDescriptionObserver>(completionHandler);
Byoungchan Lee33728152021-08-04 20:54:45 +0900601 _peerConnection->SetLocalDescription(sdp.nativeDescription, observer);
Yura Yaroshevichd6725352021-03-05 18:21:16 +0300602}
603
604- (void)setLocalDescriptionWithCompletionHandler:
Yura Yaroshevich8bfa2752021-03-10 13:07:27 +0300605 (RTCSetSessionDescriptionCompletionHandler)completionHandler {
606 RTC_DCHECK(completionHandler != nil);
Niels Möllerac0d1832022-01-17 15:26:54 +0100607 rtc::scoped_refptr<webrtc::SetLocalDescriptionObserverInterface> observer =
608 rtc::make_ref_counted<::SetSessionDescriptionObserver>(completionHandler);
Yura Yaroshevichd6725352021-03-05 18:21:16 +0300609 _peerConnection->SetLocalDescription(observer);
hjonf396f602016-02-11 16:19:06 -0800610}
611
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200612- (void)setRemoteDescription:(RTC_OBJC_TYPE(RTCSessionDescription) *)sdp
Yura Yaroshevich8bfa2752021-03-10 13:07:27 +0300613 completionHandler:(RTCSetSessionDescriptionCompletionHandler)completionHandler {
614 RTC_DCHECK(completionHandler != nil);
Niels Möllerac0d1832022-01-17 15:26:54 +0100615 rtc::scoped_refptr<webrtc::SetRemoteDescriptionObserverInterface> observer =
616 rtc::make_ref_counted<::SetSessionDescriptionObserver>(completionHandler);
Byoungchan Lee33728152021-08-04 20:54:45 +0900617 _peerConnection->SetRemoteDescription(sdp.nativeDescription, observer);
hjonf396f602016-02-11 16:19:06 -0800618}
619
zstein8b476172017-09-05 14:43:03 -0700620- (BOOL)setBweMinBitrateBps:(nullable NSNumber *)minBitrateBps
621 currentBitrateBps:(nullable NSNumber *)currentBitrateBps
622 maxBitrateBps:(nullable NSNumber *)maxBitrateBps {
Niels Möller9ad1f6f2020-07-13 10:25:41 +0200623 webrtc::BitrateSettings params;
zstein03adb7c2017-08-09 14:29:42 -0700624 if (minBitrateBps != nil) {
Danil Chapovalov196100e2018-06-21 10:17:24 +0200625 params.min_bitrate_bps = absl::optional<int>(minBitrateBps.intValue);
zstein03adb7c2017-08-09 14:29:42 -0700626 }
627 if (currentBitrateBps != nil) {
Niels Möller9ad1f6f2020-07-13 10:25:41 +0200628 params.start_bitrate_bps = absl::optional<int>(currentBitrateBps.intValue);
zstein03adb7c2017-08-09 14:29:42 -0700629 }
630 if (maxBitrateBps != nil) {
Danil Chapovalov196100e2018-06-21 10:17:24 +0200631 params.max_bitrate_bps = absl::optional<int>(maxBitrateBps.intValue);
zstein03adb7c2017-08-09 14:29:42 -0700632 }
633 return _peerConnection->SetBitrate(params).ok();
634}
635
ivoc14d5dbe2016-07-04 07:06:55 -0700636- (BOOL)startRtcEventLogWithFilePath:(NSString *)filePath
637 maxSizeInBytes:(int64_t)maxSizeInBytes {
638 RTC_DCHECK(filePath.length);
639 RTC_DCHECK_GT(maxSizeInBytes, 0);
640 RTC_DCHECK(!_hasStartedRtcEventLog);
641 if (_hasStartedRtcEventLog) {
642 RTCLogError(@"Event logging already started.");
643 return NO;
644 }
Niels Möllerdec9f742019-06-03 15:25:20 +0200645 FILE *f = fopen(filePath.UTF8String, "wb");
646 if (!f) {
ivoc14d5dbe2016-07-04 07:06:55 -0700647 RTCLogError(@"Error opening file: %@. Error: %d", filePath, errno);
648 return NO;
649 }
Niels Möller695cf6a2019-05-13 12:27:23 +0200650 // TODO(eladalon): It would be better to not allow negative values into PC.
651 const size_t max_size = (maxSizeInBytes < 0) ? webrtc::RtcEventLog::kUnlimitedOutput :
652 rtc::saturated_cast<size_t>(maxSizeInBytes);
653
654 _hasStartedRtcEventLog = _peerConnection->StartRtcEventLog(
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200655 std::make_unique<webrtc::RtcEventLogOutputFile>(f, max_size));
ivoc14d5dbe2016-07-04 07:06:55 -0700656 return _hasStartedRtcEventLog;
657}
658
659- (void)stopRtcEventLog {
660 _peerConnection->StopRtcEventLog();
661 _hasStartedRtcEventLog = NO;
662}
663
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200664- (RTC_OBJC_TYPE(RTCRtpSender) *)senderWithKind:(NSString *)kind streamId:(NSString *)streamId {
Artem Titov63ee39d2022-05-13 14:46:42 +0000665 std::string nativeKind = [NSString stdStringForString:kind];
666 std::string nativeStreamId = [NSString stdStringForString:streamId];
skvladf3569c82016-04-29 15:30:16 -0700667 rtc::scoped_refptr<webrtc::RtpSenderInterface> nativeSender(
668 _peerConnection->CreateSender(nativeKind, nativeStreamId));
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200669 return nativeSender ? [[RTC_OBJC_TYPE(RTCRtpSender) alloc] initWithFactory:self.factory
670 nativeRtpSender:nativeSender] :
671 nil;
skvladf3569c82016-04-29 15:30:16 -0700672}
673
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200674- (NSArray<RTC_OBJC_TYPE(RTCRtpSender) *> *)senders {
skvlad79b4b872016-04-08 17:28:55 -0700675 std::vector<rtc::scoped_refptr<webrtc::RtpSenderInterface>> nativeSenders(
676 _peerConnection->GetSenders());
677 NSMutableArray *senders = [[NSMutableArray alloc] init];
678 for (const auto &nativeSender : nativeSenders) {
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200679 RTC_OBJC_TYPE(RTCRtpSender) *sender =
680 [[RTC_OBJC_TYPE(RTCRtpSender) alloc] initWithFactory:self.factory
681 nativeRtpSender:nativeSender];
skvlad79b4b872016-04-08 17:28:55 -0700682 [senders addObject:sender];
683 }
684 return senders;
685}
686
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200687- (NSArray<RTC_OBJC_TYPE(RTCRtpReceiver) *> *)receivers {
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700688 std::vector<rtc::scoped_refptr<webrtc::RtpReceiverInterface>> nativeReceivers(
689 _peerConnection->GetReceivers());
690 NSMutableArray *receivers = [[NSMutableArray alloc] init];
691 for (const auto &nativeReceiver : nativeReceivers) {
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200692 RTC_OBJC_TYPE(RTCRtpReceiver) *receiver =
693 [[RTC_OBJC_TYPE(RTCRtpReceiver) alloc] initWithFactory:self.factory
694 nativeRtpReceiver:nativeReceiver];
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700695 [receivers addObject:receiver];
696 }
697 return receivers;
698}
699
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200700- (NSArray<RTC_OBJC_TYPE(RTCRtpTransceiver) *> *)transceivers {
Steve Anton8cb344a2018-02-27 15:34:53 -0800701 std::vector<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>> nativeTransceivers(
702 _peerConnection->GetTransceivers());
703 NSMutableArray *transceivers = [[NSMutableArray alloc] init];
Mirko Bonadei739baf02019-01-27 17:29:42 +0100704 for (const auto &nativeTransceiver : nativeTransceivers) {
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200705 RTC_OBJC_TYPE(RTCRtpTransceiver) *transceiver =
706 [[RTC_OBJC_TYPE(RTCRtpTransceiver) alloc] initWithFactory:self.factory
707 nativeRtpTransceiver:nativeTransceiver];
Steve Anton8cb344a2018-02-27 15:34:53 -0800708 [transceivers addObject:transceiver];
709 }
710 return transceivers;
711}
712
hjonf396f602016-02-11 16:19:06 -0800713#pragma mark - Private
714
715+ (webrtc::PeerConnectionInterface::SignalingState)nativeSignalingStateForState:
716 (RTCSignalingState)state {
717 switch (state) {
718 case RTCSignalingStateStable:
719 return webrtc::PeerConnectionInterface::kStable;
720 case RTCSignalingStateHaveLocalOffer:
721 return webrtc::PeerConnectionInterface::kHaveLocalOffer;
722 case RTCSignalingStateHaveLocalPrAnswer:
723 return webrtc::PeerConnectionInterface::kHaveLocalPrAnswer;
724 case RTCSignalingStateHaveRemoteOffer:
725 return webrtc::PeerConnectionInterface::kHaveRemoteOffer;
726 case RTCSignalingStateHaveRemotePrAnswer:
727 return webrtc::PeerConnectionInterface::kHaveRemotePrAnswer;
728 case RTCSignalingStateClosed:
729 return webrtc::PeerConnectionInterface::kClosed;
730 }
731}
732
733+ (RTCSignalingState)signalingStateForNativeState:
734 (webrtc::PeerConnectionInterface::SignalingState)nativeState {
735 switch (nativeState) {
736 case webrtc::PeerConnectionInterface::kStable:
737 return RTCSignalingStateStable;
738 case webrtc::PeerConnectionInterface::kHaveLocalOffer:
739 return RTCSignalingStateHaveLocalOffer;
740 case webrtc::PeerConnectionInterface::kHaveLocalPrAnswer:
741 return RTCSignalingStateHaveLocalPrAnswer;
742 case webrtc::PeerConnectionInterface::kHaveRemoteOffer:
743 return RTCSignalingStateHaveRemoteOffer;
744 case webrtc::PeerConnectionInterface::kHaveRemotePrAnswer:
745 return RTCSignalingStateHaveRemotePrAnswer;
746 case webrtc::PeerConnectionInterface::kClosed:
747 return RTCSignalingStateClosed;
748 }
749}
750
751+ (NSString *)stringForSignalingState:(RTCSignalingState)state {
752 switch (state) {
753 case RTCSignalingStateStable:
754 return @"STABLE";
755 case RTCSignalingStateHaveLocalOffer:
756 return @"HAVE_LOCAL_OFFER";
757 case RTCSignalingStateHaveLocalPrAnswer:
758 return @"HAVE_LOCAL_PRANSWER";
759 case RTCSignalingStateHaveRemoteOffer:
760 return @"HAVE_REMOTE_OFFER";
761 case RTCSignalingStateHaveRemotePrAnswer:
762 return @"HAVE_REMOTE_PRANSWER";
763 case RTCSignalingStateClosed:
764 return @"CLOSED";
765 }
766}
767
Jonas Olssoncfddbb72018-11-15 16:52:45 +0100768+ (webrtc::PeerConnectionInterface::PeerConnectionState)nativeConnectionStateForState:
769 (RTCPeerConnectionState)state {
770 switch (state) {
771 case RTCPeerConnectionStateNew:
772 return webrtc::PeerConnectionInterface::PeerConnectionState::kNew;
773 case RTCPeerConnectionStateConnecting:
774 return webrtc::PeerConnectionInterface::PeerConnectionState::kConnecting;
775 case RTCPeerConnectionStateConnected:
776 return webrtc::PeerConnectionInterface::PeerConnectionState::kConnected;
777 case RTCPeerConnectionStateFailed:
778 return webrtc::PeerConnectionInterface::PeerConnectionState::kFailed;
779 case RTCPeerConnectionStateDisconnected:
780 return webrtc::PeerConnectionInterface::PeerConnectionState::kDisconnected;
781 case RTCPeerConnectionStateClosed:
782 return webrtc::PeerConnectionInterface::PeerConnectionState::kClosed;
783 }
784}
785
786+ (RTCPeerConnectionState)connectionStateForNativeState:
787 (webrtc::PeerConnectionInterface::PeerConnectionState)nativeState {
788 switch (nativeState) {
789 case webrtc::PeerConnectionInterface::PeerConnectionState::kNew:
790 return RTCPeerConnectionStateNew;
791 case webrtc::PeerConnectionInterface::PeerConnectionState::kConnecting:
792 return RTCPeerConnectionStateConnecting;
793 case webrtc::PeerConnectionInterface::PeerConnectionState::kConnected:
794 return RTCPeerConnectionStateConnected;
795 case webrtc::PeerConnectionInterface::PeerConnectionState::kFailed:
796 return RTCPeerConnectionStateFailed;
797 case webrtc::PeerConnectionInterface::PeerConnectionState::kDisconnected:
798 return RTCPeerConnectionStateDisconnected;
799 case webrtc::PeerConnectionInterface::PeerConnectionState::kClosed:
800 return RTCPeerConnectionStateClosed;
801 }
802}
803
804+ (NSString *)stringForConnectionState:(RTCPeerConnectionState)state {
805 switch (state) {
806 case RTCPeerConnectionStateNew:
807 return @"NEW";
808 case RTCPeerConnectionStateConnecting:
809 return @"CONNECTING";
810 case RTCPeerConnectionStateConnected:
811 return @"CONNECTED";
812 case RTCPeerConnectionStateFailed:
813 return @"FAILED";
814 case RTCPeerConnectionStateDisconnected:
815 return @"DISCONNECTED";
816 case RTCPeerConnectionStateClosed:
817 return @"CLOSED";
818 }
819}
820
hjonf396f602016-02-11 16:19:06 -0800821+ (webrtc::PeerConnectionInterface::IceConnectionState)
822 nativeIceConnectionStateForState:(RTCIceConnectionState)state {
823 switch (state) {
824 case RTCIceConnectionStateNew:
825 return webrtc::PeerConnectionInterface::kIceConnectionNew;
826 case RTCIceConnectionStateChecking:
827 return webrtc::PeerConnectionInterface::kIceConnectionChecking;
828 case RTCIceConnectionStateConnected:
829 return webrtc::PeerConnectionInterface::kIceConnectionConnected;
830 case RTCIceConnectionStateCompleted:
831 return webrtc::PeerConnectionInterface::kIceConnectionCompleted;
832 case RTCIceConnectionStateFailed:
833 return webrtc::PeerConnectionInterface::kIceConnectionFailed;
834 case RTCIceConnectionStateDisconnected:
835 return webrtc::PeerConnectionInterface::kIceConnectionDisconnected;
836 case RTCIceConnectionStateClosed:
837 return webrtc::PeerConnectionInterface::kIceConnectionClosed;
hjon8bbbf2c2016-03-14 13:15:44 -0700838 case RTCIceConnectionStateCount:
hjonf396f602016-02-11 16:19:06 -0800839 return webrtc::PeerConnectionInterface::kIceConnectionMax;
840 }
841}
842
843+ (RTCIceConnectionState)iceConnectionStateForNativeState:
844 (webrtc::PeerConnectionInterface::IceConnectionState)nativeState {
845 switch (nativeState) {
846 case webrtc::PeerConnectionInterface::kIceConnectionNew:
847 return RTCIceConnectionStateNew;
848 case webrtc::PeerConnectionInterface::kIceConnectionChecking:
849 return RTCIceConnectionStateChecking;
850 case webrtc::PeerConnectionInterface::kIceConnectionConnected:
851 return RTCIceConnectionStateConnected;
852 case webrtc::PeerConnectionInterface::kIceConnectionCompleted:
853 return RTCIceConnectionStateCompleted;
854 case webrtc::PeerConnectionInterface::kIceConnectionFailed:
855 return RTCIceConnectionStateFailed;
856 case webrtc::PeerConnectionInterface::kIceConnectionDisconnected:
857 return RTCIceConnectionStateDisconnected;
858 case webrtc::PeerConnectionInterface::kIceConnectionClosed:
859 return RTCIceConnectionStateClosed;
860 case webrtc::PeerConnectionInterface::kIceConnectionMax:
hjon8bbbf2c2016-03-14 13:15:44 -0700861 return RTCIceConnectionStateCount;
hjonf396f602016-02-11 16:19:06 -0800862 }
863}
864
865+ (NSString *)stringForIceConnectionState:(RTCIceConnectionState)state {
866 switch (state) {
867 case RTCIceConnectionStateNew:
868 return @"NEW";
869 case RTCIceConnectionStateChecking:
870 return @"CHECKING";
871 case RTCIceConnectionStateConnected:
872 return @"CONNECTED";
873 case RTCIceConnectionStateCompleted:
874 return @"COMPLETED";
875 case RTCIceConnectionStateFailed:
876 return @"FAILED";
877 case RTCIceConnectionStateDisconnected:
878 return @"DISCONNECTED";
879 case RTCIceConnectionStateClosed:
880 return @"CLOSED";
hjon8bbbf2c2016-03-14 13:15:44 -0700881 case RTCIceConnectionStateCount:
882 return @"COUNT";
hjonf396f602016-02-11 16:19:06 -0800883 }
884}
885
886+ (webrtc::PeerConnectionInterface::IceGatheringState)
887 nativeIceGatheringStateForState:(RTCIceGatheringState)state {
888 switch (state) {
889 case RTCIceGatheringStateNew:
890 return webrtc::PeerConnectionInterface::kIceGatheringNew;
891 case RTCIceGatheringStateGathering:
892 return webrtc::PeerConnectionInterface::kIceGatheringGathering;
893 case RTCIceGatheringStateComplete:
894 return webrtc::PeerConnectionInterface::kIceGatheringComplete;
895 }
896}
897
898+ (RTCIceGatheringState)iceGatheringStateForNativeState:
899 (webrtc::PeerConnectionInterface::IceGatheringState)nativeState {
900 switch (nativeState) {
901 case webrtc::PeerConnectionInterface::kIceGatheringNew:
902 return RTCIceGatheringStateNew;
903 case webrtc::PeerConnectionInterface::kIceGatheringGathering:
904 return RTCIceGatheringStateGathering;
905 case webrtc::PeerConnectionInterface::kIceGatheringComplete:
906 return RTCIceGatheringStateComplete;
907 }
908}
909
910+ (NSString *)stringForIceGatheringState:(RTCIceGatheringState)state {
911 switch (state) {
912 case RTCIceGatheringStateNew:
913 return @"NEW";
914 case RTCIceGatheringStateGathering:
915 return @"GATHERING";
916 case RTCIceGatheringStateComplete:
917 return @"COMPLETE";
918 }
919}
920
921+ (webrtc::PeerConnectionInterface::StatsOutputLevel)
922 nativeStatsOutputLevelForLevel:(RTCStatsOutputLevel)level {
923 switch (level) {
924 case RTCStatsOutputLevelStandard:
925 return webrtc::PeerConnectionInterface::kStatsOutputLevelStandard;
926 case RTCStatsOutputLevelDebug:
927 return webrtc::PeerConnectionInterface::kStatsOutputLevelDebug;
928 }
929}
930
hjonf396f602016-02-11 16:19:06 -0800931- (rtc::scoped_refptr<webrtc::PeerConnectionInterface>)nativePeerConnection {
932 return _peerConnection;
933}
934
935@end