blob: 8c9b0cbab6edb5839404d52d5920b436af4f940d [file] [log] [blame]
henrike@webrtc.org28e20752013-07-10 00:45:361/*
kjellanderb24317b2016-02-10 15:54:432 * Copyright 2012 The WebRTC project authors. All Rights Reserved.
henrike@webrtc.org28e20752013-07-10 00:45:363 *
kjellanderb24317b2016-02-10 15:54:434 * 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.
henrike@webrtc.org28e20752013-07-10 00:45:369 */
10
Steve Anton10542f22019-01-11 17:11:0011#include "pc/peer_connection.h"
henrike@webrtc.org28e20752013-07-10 00:45:3612
Harald Alvestrand1f7eab62020-10-18 16:51:4713#include <limits.h>
14#include <stddef.h>
Harald Alvestrand0ccfbd22021-04-08 07:25:0415
deadbeefeb459812015-12-16 03:24:4316#include <algorithm>
Harald Alvestrande15fb152020-10-19 13:28:0517#include <memory>
Harald Alvestrande15fb152020-10-19 13:28:0518#include <set>
Harald Alvestrand0d4af122022-01-31 09:36:0519#include <string>
Harald Alvestrand3eaee6b2020-10-19 06:35:5520#include <utility>
henrike@webrtc.org28e20752013-07-10 00:45:3621
Steve Anton64b626b2019-01-29 01:25:2622#include "absl/algorithm/container.h"
Fredrik Solenberg41f3a432018-12-17 20:02:2223#include "absl/strings/match.h"
Harald Alvestrand0d4af122022-01-31 09:36:0524#include "absl/strings/string_view.h"
Fredrik Hernqvistefbe7532023-01-13 15:42:3625#include "absl/types/optional.h"
Danil Chapovalov3bdb49b2023-11-30 07:59:3926#include "api/environment/environment.h"
Steve Anton10542f22019-01-11 17:11:0027#include "api/jsep_ice_candidate.h"
Per Ke1e94ad2023-03-30 14:53:5928#include "api/media_types.h"
Harald Alvestrand763f5a92020-10-22 10:39:4029#include "api/rtp_parameters.h"
Harald Alvestrand1f7eab62020-10-18 16:51:4730#include "api/rtp_transceiver_direction.h"
Steve Anton10542f22019-01-11 17:11:0031#include "api/uma_metrics.h"
Harald Alvestrand1f7eab62020-10-18 16:51:4732#include "api/video/video_codec_constants.h"
33#include "call/audio_state.h"
34#include "call/packet_receiver.h"
Harald Alvestrand763f5a92020-10-22 10:39:4035#include "media/base/media_channel.h"
Harald Alvestrand1f7eab62020-10-18 16:51:4736#include "media/base/media_config.h"
Harald Alvestrand0d4af122022-01-31 09:36:0537#include "media/base/media_engine.h"
Amit Hilbuchf4770402019-04-08 21:11:5738#include "media/base/rid_description.h"
Harald Alvestrand1f7eab62020-10-18 16:51:4739#include "media/base/stream_params.h"
40#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
Harald Alvestrand0ccfbd22021-04-08 07:25:0441#include "p2p/base/basic_async_resolver_factory.h"
Harald Alvestrand1f7eab62020-10-18 16:51:4742#include "p2p/base/connection.h"
43#include "p2p/base/connection_info.h"
44#include "p2p/base/dtls_transport_internal.h"
45#include "p2p/base/p2p_constants.h"
46#include "p2p/base/p2p_transport_channel.h"
47#include "p2p/base/transport_info.h"
Harald Alvestrand1f7eab62020-10-18 16:51:4748#include "pc/ice_server_parsing.h"
Harald Alvestrand763f5a92020-10-22 10:39:4049#include "pc/rtp_receiver.h"
Harald Alvestrand0d4af122022-01-31 09:36:0550#include "pc/rtp_receiver_proxy.h"
Harald Alvestrand763f5a92020-10-22 10:39:4051#include "pc/rtp_sender.h"
Harald Alvestrand0d4af122022-01-31 09:36:0552#include "pc/rtp_sender_proxy.h"
Harald Alvestrandc85328f2019-02-28 06:51:0053#include "pc/sctp_transport.h"
Harald Alvestrand1f7eab62020-10-18 16:51:4754#include "pc/simulcast_description.h"
Harald Alvestrand1f7eab62020-10-18 16:51:4755#include "pc/webrtc_session_description_factory.h"
Harald Alvestrand1f7eab62020-10-18 16:51:4756#include "rtc_base/helpers.h"
57#include "rtc_base/ip_address.h"
Mirko Bonadei92ea95e2017-09-15 04:47:3158#include "rtc_base/logging.h"
Harald Alvestrand1f7eab62020-10-18 16:51:4759#include "rtc_base/net_helper.h"
Harald Alvestrand0d4af122022-01-31 09:36:0560#include "rtc_base/network.h"
Harald Alvestrand1f7eab62020-10-18 16:51:4761#include "rtc_base/network_constants.h"
Harald Alvestrand1f7eab62020-10-18 16:51:4762#include "rtc_base/socket_address.h"
Steve Anton10542f22019-01-11 17:11:0063#include "rtc_base/string_encode.h"
Mirko Bonadei92ea95e2017-09-15 04:47:3164#include "rtc_base/trace_event.h"
Harald Alvestrand763f5a92020-10-22 10:39:4065#include "rtc_base/unique_id_generator.h"
Qingsi Wang7fc821d2018-07-12 19:54:5366#include "system_wrappers/include/metrics.h"
henrike@webrtc.org28e20752013-07-10 00:45:3667
Steve Anton75737c02017-11-06 18:37:1768using cricket::ContentInfo;
69using cricket::ContentInfos;
70using cricket::MediaContentDescription;
Steve Anton5adfafd2017-12-21 00:34:0071using cricket::MediaProtocolType;
Amit Hilbuchbcd39d42019-01-26 01:13:5672using cricket::RidDescription;
73using cricket::RidDirection;
Amit Hilbuchc63ddb22019-01-02 18:13:5874using cricket::SessionDescription;
Amit Hilbuchbcd39d42019-01-26 01:13:5675using cricket::SimulcastDescription;
76using cricket::SimulcastLayer;
Amit Hilbuchc63ddb22019-01-02 18:13:5877using cricket::SimulcastLayerList;
Amit Hilbuchbcd39d42019-01-26 01:13:5678using cricket::StreamParams;
Steve Anton75737c02017-11-06 18:37:1779using cricket::TransportInfo;
80
Steve Antonba818672017-11-06 18:21:5781namespace webrtc {
82
Steve Anton75737c02017-11-06 18:37:1783namespace {
henrike@webrtc.org28e20752013-07-10 00:45:3684
Harald Alvestrand19793842018-06-25 10:03:5085static const int REPORT_USAGE_PATTERN_DELAY_MS = 60000;
86
Taylor Brandstettera1c30352016-05-13 15:15:1187uint32_t ConvertIceTransportTypeToCandidateFilter(
88 PeerConnectionInterface::IceTransportsType type) {
89 switch (type) {
90 case PeerConnectionInterface::kNone:
91 return cricket::CF_NONE;
92 case PeerConnectionInterface::kRelay:
93 return cricket::CF_RELAY;
94 case PeerConnectionInterface::kNoHost:
95 return (cricket::CF_ALL & ~cricket::CF_HOST);
96 case PeerConnectionInterface::kAll:
97 return cricket::CF_ALL;
98 default:
Artem Titovd3251962021-11-15 15:57:0799 RTC_DCHECK_NOTREACHED();
Taylor Brandstettera1c30352016-05-13 15:15:11100 }
101 return cricket::CF_NONE;
102}
103
Steve Anton75737c02017-11-06 18:37:17104IceCandidatePairType GetIceCandidatePairCounter(
105 const cricket::Candidate& local,
106 const cricket::Candidate& remote) {
107 const auto& l = local.type();
108 const auto& r = remote.type();
Tommi3b2b2af2024-01-17 13:19:41109 const auto& host = cricket::LOCAL_PORT_TYPE;
110 const auto& srflx = cricket::STUN_PORT_TYPE;
111 const auto& relay = cricket::RELAY_PORT_TYPE;
112 const auto& prflx = cricket::PRFLX_PORT_TYPE;
Steve Anton75737c02017-11-06 18:37:17113 if (l == host && r == host) {
Jeroen de Borst833979f2018-12-13 16:25:54114 bool local_hostname =
115 !local.address().hostname().empty() && local.address().IsUnresolvedIP();
116 bool remote_hostname = !remote.address().hostname().empty() &&
117 remote.address().IsUnresolvedIP();
Steve Anton75737c02017-11-06 18:37:17118 bool local_private = IPIsPrivate(local.address().ipaddr());
119 bool remote_private = IPIsPrivate(remote.address().ipaddr());
Jeroen de Borst833979f2018-12-13 16:25:54120 if (local_hostname) {
121 if (remote_hostname) {
122 return kIceCandidatePairHostNameHostName;
123 } else if (remote_private) {
124 return kIceCandidatePairHostNameHostPrivate;
125 } else {
126 return kIceCandidatePairHostNameHostPublic;
127 }
128 } else if (local_private) {
129 if (remote_hostname) {
130 return kIceCandidatePairHostPrivateHostName;
131 } else if (remote_private) {
Steve Anton75737c02017-11-06 18:37:17132 return kIceCandidatePairHostPrivateHostPrivate;
133 } else {
134 return kIceCandidatePairHostPrivateHostPublic;
135 }
136 } else {
Jeroen de Borst833979f2018-12-13 16:25:54137 if (remote_hostname) {
138 return kIceCandidatePairHostPublicHostName;
139 } else if (remote_private) {
Steve Anton75737c02017-11-06 18:37:17140 return kIceCandidatePairHostPublicHostPrivate;
141 } else {
142 return kIceCandidatePairHostPublicHostPublic;
143 }
144 }
145 }
146 if (l == host && r == srflx)
147 return kIceCandidatePairHostSrflx;
148 if (l == host && r == relay)
149 return kIceCandidatePairHostRelay;
150 if (l == host && r == prflx)
151 return kIceCandidatePairHostPrflx;
152 if (l == srflx && r == host)
153 return kIceCandidatePairSrflxHost;
154 if (l == srflx && r == srflx)
155 return kIceCandidatePairSrflxSrflx;
156 if (l == srflx && r == relay)
157 return kIceCandidatePairSrflxRelay;
158 if (l == srflx && r == prflx)
159 return kIceCandidatePairSrflxPrflx;
160 if (l == relay && r == host)
161 return kIceCandidatePairRelayHost;
162 if (l == relay && r == srflx)
163 return kIceCandidatePairRelaySrflx;
164 if (l == relay && r == relay)
165 return kIceCandidatePairRelayRelay;
166 if (l == relay && r == prflx)
167 return kIceCandidatePairRelayPrflx;
168 if (l == prflx && r == host)
169 return kIceCandidatePairPrflxHost;
170 if (l == prflx && r == srflx)
171 return kIceCandidatePairPrflxSrflx;
172 if (l == prflx && r == relay)
173 return kIceCandidatePairPrflxRelay;
174 return kIceCandidatePairMax;
175}
176
Danil Chapovalov66cadcc2018-06-19 14:47:43177absl::optional<int> RTCConfigurationToIceConfigOptionalInt(
Qingsi Wang866e08d2018-03-23 00:54:23178 int rtc_configuration_parameter) {
179 if (rtc_configuration_parameter ==
Harald Alvestranda6544372023-11-13 09:33:56180 PeerConnectionInterface::RTCConfiguration::kUndefined) {
Danil Chapovalov66cadcc2018-06-19 14:47:43181 return absl::nullopt;
Qingsi Wang866e08d2018-03-23 00:54:23182 }
183 return rtc_configuration_parameter;
184}
185
Jonas Orelande3096512020-05-27 07:01:05186// Check if the changes of IceTransportsType motives an ice restart.
187bool NeedIceRestart(bool surface_ice_candidates_on_ice_transport_type_changed,
188 PeerConnectionInterface::IceTransportsType current,
189 PeerConnectionInterface::IceTransportsType modified) {
190 if (current == modified) {
191 return false;
192 }
193
194 if (!surface_ice_candidates_on_ice_transport_type_changed) {
195 return true;
196 }
197
198 auto current_filter = ConvertIceTransportTypeToCandidateFilter(current);
199 auto modified_filter = ConvertIceTransportTypeToCandidateFilter(modified);
200
201 // If surface_ice_candidates_on_ice_transport_type_changed is true and we
202 // extend the filter, then no ice restart is needed.
203 return (current_filter & modified_filter) != current_filter;
204}
205
Harald Alvestrand62166932020-10-26 08:30:41206cricket::IceConfig ParseIceConfig(
207 const PeerConnectionInterface::RTCConfiguration& config) {
208 cricket::ContinualGatheringPolicy gathering_policy;
209 switch (config.continual_gathering_policy) {
210 case PeerConnectionInterface::GATHER_ONCE:
211 gathering_policy = cricket::GATHER_ONCE;
212 break;
213 case PeerConnectionInterface::GATHER_CONTINUALLY:
214 gathering_policy = cricket::GATHER_CONTINUALLY;
215 break;
216 default:
Artem Titovd3251962021-11-15 15:57:07217 RTC_DCHECK_NOTREACHED();
Harald Alvestrand62166932020-10-26 08:30:41218 gathering_policy = cricket::GATHER_ONCE;
219 }
220
221 cricket::IceConfig ice_config;
222 ice_config.receiving_timeout = RTCConfigurationToIceConfigOptionalInt(
223 config.ice_connection_receiving_timeout);
224 ice_config.prioritize_most_likely_candidate_pairs =
225 config.prioritize_most_likely_ice_candidate_pairs;
226 ice_config.backup_connection_ping_interval =
227 RTCConfigurationToIceConfigOptionalInt(
228 config.ice_backup_candidate_pair_ping_interval);
229 ice_config.continual_gathering_policy = gathering_policy;
230 ice_config.presume_writable_when_fully_relayed =
231 config.presume_writable_when_fully_relayed;
232 ice_config.surface_ice_candidates_on_ice_transport_type_changed =
233 config.surface_ice_candidates_on_ice_transport_type_changed;
234 ice_config.ice_check_interval_strong_connectivity =
235 config.ice_check_interval_strong_connectivity;
236 ice_config.ice_check_interval_weak_connectivity =
237 config.ice_check_interval_weak_connectivity;
238 ice_config.ice_check_min_interval = config.ice_check_min_interval;
239 ice_config.ice_unwritable_timeout = config.ice_unwritable_timeout;
240 ice_config.ice_unwritable_min_checks = config.ice_unwritable_min_checks;
241 ice_config.ice_inactive_timeout = config.ice_inactive_timeout;
242 ice_config.stun_keepalive_interval = config.stun_candidate_keepalive_interval;
243 ice_config.network_preference = config.network_preference;
Derek Bailey6c127a12021-04-15 19:42:41244 ice_config.stable_writable_connection_ping_interval =
245 config.stable_writable_connection_ping_interval_ms;
Harald Alvestrand62166932020-10-26 08:30:41246 return ice_config;
247}
248
249// Ensures the configuration doesn't have any parameters with invalid values,
250// or values that conflict with other parameters.
251//
252// Returns RTCError::OK() if there are no issues.
253RTCError ValidateConfiguration(
254 const PeerConnectionInterface::RTCConfiguration& config) {
255 return cricket::P2PTransportChannel::ValidateIceConfig(
256 ParseIceConfig(config));
257}
258
Tommiaea49c92023-10-22 11:00:14259// Checks for valid pool size range and if a previous value has already been
260// set, which is done via SetLocalDescription.
261RTCError ValidateIceCandidatePoolSize(
262 int ice_candidate_pool_size,
263 absl::optional<int> previous_ice_candidate_pool_size) {
264 // Note that this isn't possible through chromium, since it's an unsigned
265 // short in WebIDL.
266 if (ice_candidate_pool_size < 0 ||
267 ice_candidate_pool_size > static_cast<int>(UINT16_MAX)) {
268 return RTCError(RTCErrorType::INVALID_RANGE);
269 }
270
271 // According to JSEP, after setLocalDescription, changing the candidate pool
272 // size is not allowed, and changing the set of ICE servers will not result
273 // in new candidates being gathered.
274 if (previous_ice_candidate_pool_size.has_value() &&
275 ice_candidate_pool_size != previous_ice_candidate_pool_size.value()) {
276 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_MODIFICATION,
277 "Can't change candidate pool size after calling "
278 "SetLocalDescription.");
279 }
280
281 return RTCError::OK();
282}
283
284// The simplest (and most future-compatible) way to tell if a config was
285// modified in an invalid way is to copy each property we do support modifying,
286// then use operator==. There are far more properties we don't support modifying
287// than those we do, and more could be added.
288// This helper function accepts a proposed new `configuration` object, an
289// existing configuration and returns a valid, modified, configuration that's
290// based on the existing configuration, with modified properties copied from
291// `configuration`.
292// If the result of creating a modified configuration doesn't pass the above
293// `operator==` test or a call to `ValidateConfiguration()`, then the function
294// will return an error. Otherwise, the return value will be the new config.
295RTCErrorOr<PeerConnectionInterface::RTCConfiguration> ApplyConfiguration(
296 const PeerConnectionInterface::RTCConfiguration& configuration,
297 const PeerConnectionInterface::RTCConfiguration& existing_configuration) {
298 PeerConnectionInterface::RTCConfiguration modified_config =
299 existing_configuration;
300 modified_config.servers = configuration.servers;
301 modified_config.type = configuration.type;
302 modified_config.ice_candidate_pool_size =
303 configuration.ice_candidate_pool_size;
304 modified_config.prune_turn_ports = configuration.prune_turn_ports;
305 modified_config.turn_port_prune_policy = configuration.turn_port_prune_policy;
306 modified_config.surface_ice_candidates_on_ice_transport_type_changed =
307 configuration.surface_ice_candidates_on_ice_transport_type_changed;
308 modified_config.ice_check_min_interval = configuration.ice_check_min_interval;
309 modified_config.ice_check_interval_strong_connectivity =
310 configuration.ice_check_interval_strong_connectivity;
311 modified_config.ice_check_interval_weak_connectivity =
312 configuration.ice_check_interval_weak_connectivity;
313 modified_config.ice_unwritable_timeout = configuration.ice_unwritable_timeout;
314 modified_config.ice_unwritable_min_checks =
315 configuration.ice_unwritable_min_checks;
316 modified_config.ice_inactive_timeout = configuration.ice_inactive_timeout;
317 modified_config.stun_candidate_keepalive_interval =
318 configuration.stun_candidate_keepalive_interval;
319 modified_config.turn_customizer = configuration.turn_customizer;
320 modified_config.network_preference = configuration.network_preference;
321 modified_config.active_reset_srtp_params =
322 configuration.active_reset_srtp_params;
323 modified_config.turn_logging_id = configuration.turn_logging_id;
Tommiaea49c92023-10-22 11:00:14324 modified_config.stable_writable_connection_ping_interval_ms =
325 configuration.stable_writable_connection_ping_interval_ms;
326 if (configuration != modified_config) {
327 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_MODIFICATION,
328 "Modifying the configuration in an unsupported way.");
329 }
330
331 RTCError err = ValidateConfiguration(modified_config);
332 if (!err.ok()) {
333 return err;
334 }
335
336 return modified_config;
337}
338
Harald Alvestrand62166932020-10-26 08:30:41339bool HasRtcpMuxEnabled(const cricket::ContentInfo* content) {
340 return content->media_description()->rtcp_mux();
341}
342
Tommic3257d02021-02-10 17:40:08343bool DtlsEnabled(const PeerConnectionInterface::RTCConfiguration& configuration,
344 const PeerConnectionFactoryInterface::Options& options,
345 const PeerConnectionDependencies& dependencies) {
346 if (options.disable_encryption)
347 return false;
348
349 // Enable DTLS by default if we have an identity store or a certificate.
350 bool default_enabled =
351 (dependencies.cert_generator || !configuration.certificates.empty());
352
Harald Alvestrandca327932022-04-04 15:37:31353#if defined(WEBRTC_FUCHSIA)
Harald Alvestrand50b95522021-11-18 10:01:06354 // The `configuration` can override the default value.
355 return configuration.enable_dtls_srtp.value_or(default_enabled);
Harald Alvestrandca327932022-04-04 15:37:31356#else
357 return default_enabled;
358#endif
Tommic3257d02021-02-10 17:40:08359}
360
Tommiaea49c92023-10-22 11:00:14361// Calls `ParseIceServersOrError` to extract ice server information from the
362// `configuration` and then validates the extracted configuration. For a
363// non-empty list of servers, usage gets recorded via `usage_pattern`.
364RTCError ParseAndValidateIceServersFromConfiguration(
365 const PeerConnectionInterface::RTCConfiguration& configuration,
366 cricket::ServerAddresses& stun_servers,
367 std::vector<cricket::RelayServerConfig>& turn_servers,
368 UsagePattern& usage_pattern) {
369 RTC_DCHECK(stun_servers.empty());
370 RTC_DCHECK(turn_servers.empty());
371 RTCError err = ParseIceServersOrError(configuration.servers, &stun_servers,
372 &turn_servers);
373 if (!err.ok()) {
374 return err;
375 }
376
377 // Restrict number of TURN servers.
378 if (turn_servers.size() > cricket::kMaxTurnServers) {
379 RTC_LOG(LS_WARNING) << "Number of configured TURN servers is "
380 << turn_servers.size()
381 << " which exceeds the maximum allowed number of "
382 << cricket::kMaxTurnServers;
383 turn_servers.resize(cricket::kMaxTurnServers);
384 }
385
386 // Add the turn logging id to all turn servers
387 for (cricket::RelayServerConfig& turn_server : turn_servers) {
388 turn_server.turn_logging_id = configuration.turn_logging_id;
389 }
390
391 // Note if STUN or TURN servers were supplied.
392 if (!stun_servers.empty()) {
393 usage_pattern.NoteUsageEvent(UsageEvent::STUN_SERVER_ADDED);
394 }
395 if (!turn_servers.empty()) {
396 usage_pattern.NoteUsageEvent(UsageEvent::TURN_SERVER_ADDED);
397 }
398 return RTCError::OK();
399}
400
Steve Anton75737c02017-11-06 18:37:17401} // namespace
402
deadbeef293e9262017-01-11 20:28:30403bool PeerConnectionInterface::RTCConfiguration::operator==(
404 const PeerConnectionInterface::RTCConfiguration& o) const {
405 // This static_assert prevents us from accidentally breaking operator==.
Steve Anton300bf8e2017-07-14 17:13:10406 // Note: Order matters! Fields must be ordered the same as RTCConfiguration.
deadbeef293e9262017-01-11 20:28:30407 struct stuff_being_tested_for_equality {
Magnus Jedvert3beb2072017-07-14 14:23:56408 IceServers servers;
Steve Anton300bf8e2017-07-14 17:13:10409 IceTransportsType type;
deadbeef293e9262017-01-11 20:28:30410 BundlePolicy bundle_policy;
411 RtcpMuxPolicy rtcp_mux_policy;
Steve Anton300bf8e2017-07-14 17:13:10412 std::vector<rtc::scoped_refptr<rtc::RTCCertificate>> certificates;
413 int ice_candidate_pool_size;
Steve Anton300bf8e2017-07-14 17:13:10414 bool disable_ipv6_on_wifi;
deadbeefd21eab3e2017-07-26 23:50:11415 int max_ipv6_networks;
Daniel Lazarenko2870b0a2018-01-25 09:30:22416 bool disable_link_local_networks;
Danil Chapovalov66cadcc2018-06-19 14:47:43417 absl::optional<int> screencast_min_bitrate;
Harald Alvestrandca327932022-04-04 15:37:31418#if defined(WEBRTC_FUCHSIA)
Harald Alvestrand50b95522021-11-18 10:01:06419 absl::optional<bool> enable_dtls_srtp;
Harald Alvestrandca327932022-04-04 15:37:31420#endif
deadbeef293e9262017-01-11 20:28:30421 TcpCandidatePolicy tcp_candidate_policy;
422 CandidateNetworkPolicy candidate_network_policy;
423 int audio_jitter_buffer_max_packets;
424 bool audio_jitter_buffer_fast_accelerate;
Jakob Ivarsson10403ae2018-11-27 14:45:20425 int audio_jitter_buffer_min_delay_ms;
deadbeef293e9262017-01-11 20:28:30426 int ice_connection_receiving_timeout;
427 int ice_backup_candidate_pair_ping_interval;
428 ContinualGatheringPolicy continual_gathering_policy;
deadbeef293e9262017-01-11 20:28:30429 bool prioritize_most_likely_ice_candidate_pairs;
430 struct cricket::MediaConfig media_config;
deadbeef293e9262017-01-11 20:28:30431 bool prune_turn_ports;
Honghai Zhangf8998cf2019-10-14 18:27:50432 PortPrunePolicy turn_port_prune_policy;
deadbeef293e9262017-01-11 20:28:30433 bool presume_writable_when_fully_relayed;
434 bool enable_ice_renomination;
435 bool redetermine_role_on_ice_restart;
Qingsi Wang1fe119f2019-05-31 23:55:33436 bool surface_ice_candidates_on_ice_transport_type_changed;
Danil Chapovalov66cadcc2018-06-19 14:47:43437 absl::optional<int> ice_check_interval_strong_connectivity;
438 absl::optional<int> ice_check_interval_weak_connectivity;
439 absl::optional<int> ice_check_min_interval;
440 absl::optional<int> ice_unwritable_timeout;
441 absl::optional<int> ice_unwritable_min_checks;
Jiawei Ou9d4fd5552018-12-07 07:30:17442 absl::optional<int> ice_inactive_timeout;
Danil Chapovalov66cadcc2018-06-19 14:47:43443 absl::optional<int> stun_candidate_keepalive_interval;
Harald Alvestranda6544372023-11-13 09:33:56444 TurnCustomizer* turn_customizer;
Steve Anton79e79602017-11-20 18:25:56445 SdpSemantics sdp_semantics;
Danil Chapovalov66cadcc2018-06-19 14:47:43446 absl::optional<rtc::AdapterType> network_preference;
Zhi Huangb57e1692018-06-12 18:41:11447 bool active_reset_srtp_params;
Benjamin Wright8c27cca2018-10-25 17:16:44448 absl::optional<CryptoOptions> crypto_options;
Johannes Kron89f874e2018-11-12 09:25:48449 bool offer_extmap_allow_mixed;
Jonas Oreland3c028422019-08-22 14:16:35450 std::string turn_logging_id;
Eldar Rello5ab79e62019-10-09 15:29:44451 bool enable_implicit_rollback;
Harald Alvestrand62166932020-10-26 08:30:41452 absl::optional<int> report_usage_pattern_delay_ms;
Derek Bailey6c127a12021-04-15 19:42:41453 absl::optional<int> stable_writable_connection_ping_interval_ms;
Harald Alvestranda6544372023-11-13 09:33:56454 VpnPreference vpn_preference;
Jonas Oreland2ee0e642021-08-25 13:43:02455 std::vector<rtc::NetworkMask> vpn_list;
Niels Möller73d07742021-12-02 12:58:01456 PortAllocatorConfig port_allocator_config;
Henrik Boströmcf2856b2022-11-15 08:23:19457 absl::optional<TimeDelta> pacer_burst_interval;
deadbeef293e9262017-01-11 20:28:30458 };
459 static_assert(sizeof(stuff_being_tested_for_equality) == sizeof(*this),
460 "Did you add something to RTCConfiguration and forget to "
461 "update operator==?");
462 return type == o.type && servers == o.servers &&
463 bundle_policy == o.bundle_policy &&
464 rtcp_mux_policy == o.rtcp_mux_policy &&
465 tcp_candidate_policy == o.tcp_candidate_policy &&
466 candidate_network_policy == o.candidate_network_policy &&
467 audio_jitter_buffer_max_packets == o.audio_jitter_buffer_max_packets &&
468 audio_jitter_buffer_fast_accelerate ==
469 o.audio_jitter_buffer_fast_accelerate &&
Jakob Ivarsson10403ae2018-11-27 14:45:20470 audio_jitter_buffer_min_delay_ms ==
471 o.audio_jitter_buffer_min_delay_ms &&
deadbeef293e9262017-01-11 20:28:30472 ice_connection_receiving_timeout ==
473 o.ice_connection_receiving_timeout &&
474 ice_backup_candidate_pair_ping_interval ==
475 o.ice_backup_candidate_pair_ping_interval &&
476 continual_gathering_policy == o.continual_gathering_policy &&
477 certificates == o.certificates &&
478 prioritize_most_likely_ice_candidate_pairs ==
479 o.prioritize_most_likely_ice_candidate_pairs &&
Henrik Boström24e03372022-10-27 11:49:10480 media_config == o.media_config &&
zhihuangb09b3f92017-03-07 22:40:51481 disable_ipv6_on_wifi == o.disable_ipv6_on_wifi &&
deadbeefd21eab3e2017-07-26 23:50:11482 max_ipv6_networks == o.max_ipv6_networks &&
Daniel Lazarenko2870b0a2018-01-25 09:30:22483 disable_link_local_networks == o.disable_link_local_networks &&
deadbeef293e9262017-01-11 20:28:30484 screencast_min_bitrate == o.screencast_min_bitrate &&
Harald Alvestrandca327932022-04-04 15:37:31485#if defined(WEBRTC_FUCHSIA)
Harald Alvestrand50b95522021-11-18 10:01:06486 enable_dtls_srtp == o.enable_dtls_srtp &&
Harald Alvestrandca327932022-04-04 15:37:31487#endif
deadbeef293e9262017-01-11 20:28:30488 ice_candidate_pool_size == o.ice_candidate_pool_size &&
489 prune_turn_ports == o.prune_turn_ports &&
Honghai Zhangf8998cf2019-10-14 18:27:50490 turn_port_prune_policy == o.turn_port_prune_policy &&
deadbeef293e9262017-01-11 20:28:30491 presume_writable_when_fully_relayed ==
492 o.presume_writable_when_fully_relayed &&
493 enable_ice_renomination == o.enable_ice_renomination &&
skvlad51072462017-02-02 19:50:14494 redetermine_role_on_ice_restart == o.redetermine_role_on_ice_restart &&
Qingsi Wang1fe119f2019-05-31 23:55:33495 surface_ice_candidates_on_ice_transport_type_changed ==
496 o.surface_ice_candidates_on_ice_transport_type_changed &&
Qingsi Wange6826d22018-03-08 22:55:14497 ice_check_interval_strong_connectivity ==
498 o.ice_check_interval_strong_connectivity &&
499 ice_check_interval_weak_connectivity ==
500 o.ice_check_interval_weak_connectivity &&
Steve Anton300bf8e2017-07-14 17:13:10501 ice_check_min_interval == o.ice_check_min_interval &&
Qingsi Wang22e623a2018-03-13 17:53:57502 ice_unwritable_timeout == o.ice_unwritable_timeout &&
503 ice_unwritable_min_checks == o.ice_unwritable_min_checks &&
Jiawei Ou9d4fd5552018-12-07 07:30:17504 ice_inactive_timeout == o.ice_inactive_timeout &&
Qingsi Wangdb53f8e2018-02-20 22:45:49505 stun_candidate_keepalive_interval ==
506 o.stun_candidate_keepalive_interval &&
Steve Anton79e79602017-11-20 18:25:56507 turn_customizer == o.turn_customizer &&
Qingsi Wang9a5c6f82018-02-01 18:38:40508 sdp_semantics == o.sdp_semantics &&
Zhi Huangb57e1692018-06-12 18:41:11509 network_preference == o.network_preference &&
Piotr (Peter) Slatalae0c2e972018-10-08 16:43:21510 active_reset_srtp_params == o.active_reset_srtp_params &&
Johannes Kron89f874e2018-11-12 09:25:48511 crypto_options == o.crypto_options &&
Jonas Oreland3c028422019-08-22 14:16:35512 offer_extmap_allow_mixed == o.offer_extmap_allow_mixed &&
Eldar Rello5ab79e62019-10-09 15:29:44513 turn_logging_id == o.turn_logging_id &&
philipel16cec3b2019-10-25 10:23:02514 enable_implicit_rollback == o.enable_implicit_rollback &&
Derek Bailey6c127a12021-04-15 19:42:41515 report_usage_pattern_delay_ms == o.report_usage_pattern_delay_ms &&
516 stable_writable_connection_ping_interval_ms ==
Jonas Orelandc8fa1ee2021-08-25 06:58:04517 o.stable_writable_connection_ping_interval_ms &&
Niels Möller73d07742021-12-02 12:58:01518 vpn_preference == o.vpn_preference && vpn_list == o.vpn_list &&
519 port_allocator_config.min_port == o.port_allocator_config.min_port &&
520 port_allocator_config.max_port == o.port_allocator_config.max_port &&
Henrik Boströmcf2856b2022-11-15 08:23:19521 port_allocator_config.flags == o.port_allocator_config.flags &&
522 pacer_burst_interval == o.pacer_burst_interval;
deadbeef293e9262017-01-11 20:28:30523}
524
525bool PeerConnectionInterface::RTCConfiguration::operator!=(
526 const PeerConnectionInterface::RTCConfiguration& o) const {
527 return !(*this == o);
deadbeef3edec7c2016-12-10 19:44:26528}
529
Harald Alvestranda3dd7722020-11-27 08:05:42530RTCErrorOr<rtc::scoped_refptr<PeerConnection>> PeerConnection::Create(
Danil Chapovalov3bdb49b2023-11-30 07:59:39531 const Environment& env,
Harald Alvestrand62166932020-10-26 08:30:41532 rtc::scoped_refptr<ConnectionContext> context,
Harald Alvestrand4da4a872020-11-04 10:34:21533 const PeerConnectionFactoryInterface::Options& options,
Harald Alvestrand62166932020-10-26 08:30:41534 std::unique_ptr<Call> call,
535 const PeerConnectionInterface::RTCConfiguration& configuration,
536 PeerConnectionDependencies dependencies) {
Henrik Boström62995db2022-01-03 08:58:10537 // TODO(https://crbug.com/webrtc/13528): Remove support for kPlanB.
Henrik Boström6d2fe892022-01-21 08:51:07538 if (configuration.sdp_semantics == SdpSemantics::kPlanB_DEPRECATED) {
539 RTC_LOG(LS_WARNING)
540 << "PeerConnection constructed with legacy SDP semantics!";
541 }
Henrik Boström62995db2022-01-03 08:58:10542
Harald Alvestrand62166932020-10-26 08:30:41543 RTCError config_error = cricket::P2PTransportChannel::ValidateIceConfig(
544 ParseIceConfig(configuration));
545 if (!config_error.ok()) {
Harald Alvestranda3dd7722020-11-27 08:05:42546 RTC_LOG(LS_ERROR) << "Invalid ICE configuration: "
547 << config_error.message();
548 return config_error;
Harald Alvestrand62166932020-10-26 08:30:41549 }
550
551 if (!dependencies.allocator) {
552 RTC_LOG(LS_ERROR)
553 << "PeerConnection initialized without a PortAllocator? "
554 "This shouldn't happen if using PeerConnectionFactory.";
Harald Alvestranda3dd7722020-11-27 08:05:42555 return RTCError(
556 RTCErrorType::INVALID_PARAMETER,
557 "Attempt to create a PeerConnection without a PortAllocatorFactory");
Harald Alvestrand62166932020-10-26 08:30:41558 }
559
560 if (!dependencies.observer) {
561 // TODO(deadbeef): Why do we do this?
562 RTC_LOG(LS_ERROR) << "PeerConnection initialized without a "
563 "PeerConnectionObserver";
Harald Alvestranda3dd7722020-11-27 08:05:42564 return RTCError(RTCErrorType::INVALID_PARAMETER,
565 "Attempt to create a PeerConnection without an observer");
Harald Alvestrand62166932020-10-26 08:30:41566 }
567
568 bool is_unified_plan =
569 configuration.sdp_semantics == SdpSemantics::kUnifiedPlan;
Tommic3257d02021-02-10 17:40:08570 bool dtls_enabled = DtlsEnabled(configuration, options, dependencies);
Harald Alvestrand0ccfbd22021-04-08 07:25:04571
Harald Alvestrand4d25a772023-08-25 11:07:28572 if (!dependencies.async_dns_resolver_factory) {
Harald Alvestrand4d25a772023-08-25 11:07:28573 dependencies.async_dns_resolver_factory =
574 std::make_unique<BasicAsyncDnsResolverFactory>();
Harald Alvestrand0ccfbd22021-04-08 07:25:04575 }
576
Harald Alvestrandfd9a8f82020-10-26 14:17:02577 // The PeerConnection constructor consumes some, but not all, dependencies.
Tommi87f70902021-04-27 12:43:08578 auto pc = rtc::make_ref_counted<PeerConnection>(
Danil Chapovalov3bdb49b2023-11-30 07:59:39579 env, context, options, is_unified_plan, std::move(call), dependencies,
580 dtls_enabled);
Harald Alvestranda3dd7722020-11-27 08:05:42581 RTCError init_error = pc->Initialize(configuration, std::move(dependencies));
582 if (!init_error.ok()) {
583 RTC_LOG(LS_ERROR) << "PeerConnection initialization failed";
584 return init_error;
Harald Alvestrand62166932020-10-26 08:30:41585 }
586 return pc;
587}
588
Harald Alvestrand4da4a872020-11-04 10:34:21589PeerConnection::PeerConnection(
Danil Chapovalov3bdb49b2023-11-30 07:59:39590 const Environment& env,
Harald Alvestrand4da4a872020-11-04 10:34:21591 rtc::scoped_refptr<ConnectionContext> context,
592 const PeerConnectionFactoryInterface::Options& options,
593 bool is_unified_plan,
Harald Alvestrand4da4a872020-11-04 10:34:21594 std::unique_ptr<Call> call,
Tommic3257d02021-02-10 17:40:08595 PeerConnectionDependencies& dependencies,
596 bool dtls_enabled)
Danil Chapovalov3bdb49b2023-11-30 07:59:39597 : env_(env),
598 context_(context),
Harald Alvestrand4da4a872020-11-04 10:34:21599 options_(options),
Harald Alvestrandfd9a8f82020-10-26 14:17:02600 observer_(dependencies.observer),
Harald Alvestrand62166932020-10-26 08:30:41601 is_unified_plan_(is_unified_plan),
Harald Alvestrand0ccfbd22021-04-08 07:25:04602 async_dns_resolver_factory_(
603 std::move(dependencies.async_dns_resolver_factory)),
Harald Alvestrandfd9a8f82020-10-26 14:17:02604 port_allocator_(std::move(dependencies.allocator)),
605 ice_transport_factory_(std::move(dependencies.ice_transport_factory)),
606 tls_cert_verifier_(std::move(dependencies.tls_cert_verifier)),
Karl Wiberg6cab5c82019-03-26 08:57:01607 call_(std::move(call)),
Tommiaf27d4e2023-10-24 21:49:31608 worker_thread_safety_(PendingTaskSafetyFlag::CreateAttachedToTaskQueue(
609 /*alive=*/call_ != nullptr,
610 worker_thread())),
Henrik Boström79b69802019-07-18 09:16:56611 call_ptr_(call_.get()),
Tomas Gunnarsson97a387d2021-03-29 19:04:29612 // RFC 3264: The numeric value of the session id and version in the
613 // o line MUST be representable with a "64 bit signed integer".
Artem Titov880fa812021-07-30 20:30:23614 // Due to this constraint session id `session_id_` is max limited to
Tomas Gunnarsson97a387d2021-03-29 19:04:29615 // LLONG_MAX.
616 session_id_(rtc::ToString(rtc::CreateRandomId64() & LLONG_MAX)),
Tommic3257d02021-02-10 17:40:08617 dtls_enabled_(dtls_enabled),
Harald Alvestrand1090e442020-10-05 07:01:09618 data_channel_controller_(this),
Lahiru Ginnaliya Gamathige70f9e242021-01-28 07:32:46619 message_handler_(signaling_thread()),
Danil Chapovalov49c35d32023-11-27 11:55:39620 weak_factory_(this) {
Danil Chapovalov3bdb49b2023-11-30 07:59:39621 // Field trials specific to the peerconnection should be owned by the `env`,
622 RTC_DCHECK(dependencies.trials == nullptr);
Danil Chapovalov49c35d32023-11-27 11:55:39623}
henrike@webrtc.org28e20752013-07-10 00:45:36624
625PeerConnection::~PeerConnection() {
Peter Boström1a9d6152015-12-08 21:15:17626 TRACE_EVENT0("webrtc", "PeerConnection::~PeerConnection");
Steve Anton4171afb2017-11-20 18:20:22627 RTC_DCHECK_RUN_ON(signaling_thread());
628
Harald Alvestrand9cd199d2020-10-27 07:10:43629 if (sdp_handler_) {
630 sdp_handler_->PrepareForShutdown();
631 }
Henrik Boströma3728d32019-10-28 11:09:49632
Tommi94774d42023-04-24 09:31:45633 // In case `Close()` wasn't called, always make sure the controller cancels
634 // potentially pending operations.
635 data_channel_controller_.PrepareForShutdown();
636
Steve Anton8af21862017-12-15 19:20:13637 // Need to stop transceivers before destroying the stats collector because
Henrik Boströmf7859892022-07-04 12:36:37638 // AudioRtpSender has a reference to the LegacyStatsCollector it will update
639 // when stopping.
Harald Alvestrande15fb152020-10-19 13:28:05640 if (rtp_manager()) {
641 for (const auto& transceiver : rtp_manager()->transceivers()->List()) {
642 transceiver->StopInternal();
643 }
Steve Anton8af21862017-12-15 19:20:13644 }
Steve Anton4171afb2017-11-20 18:20:22645
Henrik Boströmf7859892022-07-04 12:36:37646 legacy_stats_.reset(nullptr);
hbosb78306a2016-12-19 13:06:57647 if (stats_collector_) {
648 stats_collector_->WaitForPendingRequest();
649 stats_collector_ = nullptr;
650 }
Steve Anton75737c02017-11-06 18:37:17651
Harald Alvestrand9cd199d2020-10-27 07:10:43652 if (sdp_handler_) {
653 // Don't destroy BaseChannels until after stats has been cleaned up so that
654 // the last stats request can still read from the channels.
Tommi29190752023-10-21 14:50:09655 sdp_handler_->DestroyMediaChannels();
Harald Alvestrand9cd199d2020-10-27 07:10:43656 RTC_LOG(LS_INFO) << "Session: " << session_id() << " is destroyed.";
Harald Alvestrand9cd199d2020-10-27 07:10:43657 sdp_handler_->ResetSessionDescFactory();
658 }
Steve Anton75737c02017-11-06 18:37:17659
Tomas Gunnarsson92eebef2021-02-10 12:05:44660 // port_allocator_ and transport_controller_ live on the network thread and
661 // should be destroyed there.
Harald Alvestrandbc32c562022-02-09 12:08:47662 transport_controller_copy_ = nullptr;
Danil Chapovalov9e09a1f2022-09-08 16:38:10663 network_thread()->BlockingCall([this] {
Karl Wibergfb3be392019-03-22 13:13:22664 RTC_DCHECK_RUN_ON(network_thread());
Tommib00d63c2023-04-12 17:49:53665 TeardownDataChannelTransport_n(RTCError::OK());
Tomas Gunnarsson92eebef2021-02-10 12:05:44666 transport_controller_.reset();
Karl Wibergfb3be392019-03-22 13:13:22667 port_allocator_.reset();
Tommic3257d02021-02-10 17:40:08668 if (network_thread_safety_)
Tomas Gunnarsson92eebef2021-02-10 12:05:44669 network_thread_safety_->SetNotAlive();
Karl Wibergfb3be392019-03-22 13:13:22670 });
Tommi29190752023-10-21 14:50:09671 sctp_mid_s_.reset();
672 SetSctpTransportName("");
Tomas Gunnarssond69e0702021-04-07 13:14:43673
Danil Chapovalov49c35d32023-11-27 11:55:39674 // call_ must be destroyed on the worker thread.
Danil Chapovalov9e09a1f2022-09-08 16:38:10675 worker_thread()->BlockingCall([this] {
Karl Wibergb03ab712019-02-14 10:59:57676 RTC_DCHECK_RUN_ON(worker_thread());
Tommic3257d02021-02-10 17:40:08677 worker_thread_safety_->SetNotAlive();
eladalon248fd4f2017-09-06 12:18:15678 call_.reset();
eladalon248fd4f2017-09-06 12:18:15679 });
Tommi52719652023-04-04 09:59:55680
681 data_channel_controller_.PrepareForShutdown();
henrike@webrtc.org28e20752013-07-10 00:45:36682}
683
Harald Alvestranda3dd7722020-11-27 08:05:42684RTCError PeerConnection::Initialize(
buildbot@webrtc.org41451d42014-05-03 05:39:45685 const PeerConnectionInterface::RTCConfiguration& configuration,
Benjamin Wrightcab588882018-05-02 22:12:47686 PeerConnectionDependencies dependencies) {
Karl Wiberg744310f2019-02-14 09:18:56687 RTC_DCHECK_RUN_ON(signaling_thread());
Peter Boström1a9d6152015-12-08 21:15:17688 TRACE_EVENT0("webrtc", "PeerConnection::Initialize");
Steve Anton038834f2017-07-14 22:59:59689
Harald Alvestrandb2a74782018-06-28 11:54:07690 cricket::ServerAddresses stun_servers;
691 std::vector<cricket::RelayServerConfig> turn_servers;
Tommiaea49c92023-10-22 11:00:14692 RTCError parse_error = ParseAndValidateIceServersFromConfiguration(
693 configuration, stun_servers, turn_servers, usage_pattern_);
Philipp Hancke633dc2f2022-10-12 08:16:14694 if (!parse_error.ok()) {
695 return parse_error;
Harald Alvestrandb2a74782018-06-28 11:54:07696 }
697
Tommic3257d02021-02-10 17:40:08698 // Network thread initialization.
Jared Siskinbceec842023-04-20 21:10:51699 transport_controller_copy_ = network_thread()->BlockingCall([&] {
700 RTC_DCHECK_RUN_ON(network_thread());
701 network_thread_safety_ = PendingTaskSafetyFlag::Create();
702 InitializePortAllocatorResult pa_result =
703 InitializePortAllocator_n(stun_servers, turn_servers, configuration);
704 // Send information about IPv4/IPv6 status.
705 PeerConnectionAddressFamilyCounter address_family =
706 pa_result.enable_ipv6 ? kPeerConnection_IPv6 : kPeerConnection_IPv4;
707 RTC_HISTOGRAM_ENUMERATION("WebRTC.PeerConnection.IPMetrics", address_family,
708 kPeerConnectionAddressFamilyCounter_Max);
709 return InitializeTransportController_n(configuration, dependencies);
710 });
Lahiru Ginnaliya Gamathigee99c68d2020-09-30 21:33:45711
Steve Antonba818672017-11-06 18:21:57712 configuration_ = configuration;
713
Henrik Boströmf7859892022-07-04 12:36:37714 legacy_stats_ = std::make_unique<LegacyStatsCollector>(this);
Harald Alvestrande15fb152020-10-19 13:28:05715 stats_collector_ = RTCStatsCollector::Create(this);
716
Harald Alvestrand66c40362022-01-28 17:41:30717 sdp_handler_ = SdpOfferAnswerHandler::Create(this, configuration,
Niels Möllerafb246b2022-04-20 12:26:50718 dependencies, context_.get());
Harald Alvestrand9cd199d2020-10-27 07:10:43719
Artem Titovc6c02ef2022-05-09 08:30:09720 rtp_manager_ = std::make_unique<RtpTransmissionManager>(
Henrik Boströmf7859892022-07-04 12:36:37721 IsUnifiedPlan(), context_.get(), &usage_pattern_, observer_,
722 legacy_stats_.get(), [this]() {
Artem Titovc6c02ef2022-05-09 08:30:09723 RTC_DCHECK_RUN_ON(signaling_thread());
724 sdp_handler_->UpdateNegotiationNeeded();
725 });
Harald Alvestrande15fb152020-10-19 13:28:05726
Artem Titovc6c02ef2022-05-09 08:30:09727 // Add default audio/video transceivers for Plan B SDP.
728 if (!IsUnifiedPlan()) {
729 rtp_manager()->transceivers()->Add(
730 RtpTransceiverProxyWithInternal<RtpTransceiver>::Create(
Harald Alvestrandc3fa7c32022-05-22 10:57:01731 signaling_thread(), rtc::make_ref_counted<RtpTransceiver>(
732 cricket::MEDIA_TYPE_AUDIO, context())));
Artem Titovc6c02ef2022-05-09 08:30:09733 rtp_manager()->transceivers()->Add(
734 RtpTransceiverProxyWithInternal<RtpTransceiver>::Create(
Harald Alvestrandc3fa7c32022-05-22 10:57:01735 signaling_thread(), rtc::make_ref_counted<RtpTransceiver>(
736 cricket::MEDIA_TYPE_VIDEO, context())));
Steve Anton4171afb2017-11-20 18:20:22737 }
Harald Alvestrand763f5a92020-10-22 10:39:40738
Harald Alvestrand62166932020-10-26 08:30:41739 int delay_ms = configuration.report_usage_pattern_delay_ms
740 ? *configuration.report_usage_pattern_delay_ms
741 : REPORT_USAGE_PATTERN_DELAY_MS;
Harald Alvestrand1090e442020-10-05 07:01:09742 message_handler_.RequestUsagePatternReport(
743 [this]() {
744 RTC_DCHECK_RUN_ON(signaling_thread());
745 ReportUsagePattern();
746 },
747 delay_ms);
Jonas Orelanda3aa9bd2019-04-17 05:38:40748
Harald Alvestranda3dd7722020-11-27 08:05:42749 return RTCError::OK();
henrike@webrtc.org28e20752013-07-10 00:45:36750}
751
Harald Alvestrandbc32c562022-02-09 12:08:47752JsepTransportController* PeerConnection::InitializeTransportController_n(
Tommic3257d02021-02-10 17:40:08753 const RTCConfiguration& configuration,
754 const PeerConnectionDependencies& dependencies) {
755 JsepTransportController::Config config;
756 config.redetermine_role_on_ice_restart =
757 configuration.redetermine_role_on_ice_restart;
758 config.ssl_max_version = options_.ssl_max_version;
759 config.disable_encryption = options_.disable_encryption;
760 config.bundle_policy = configuration.bundle_policy;
761 config.rtcp_mux_policy = configuration.rtcp_mux_policy;
762 // TODO(bugs.webrtc.org/9891) - Remove options_.crypto_options then remove
763 // this stub.
764 config.crypto_options = configuration.crypto_options.has_value()
765 ? *configuration.crypto_options
766 : options_.crypto_options;
767 config.transport_observer = this;
768 config.rtcp_handler = InitializeRtcpCallback();
Per Ke1e94ad2023-03-30 14:53:59769 config.un_demuxable_packet_handler = InitializeUnDemuxablePacketHandler();
Danil Chapovalov3bdb49b2023-11-30 07:59:39770 config.event_log = &env_.event_log();
Tommic3257d02021-02-10 17:40:08771#if defined(ENABLE_EXTERNAL_AUTH)
772 config.enable_external_auth = true;
773#endif
774 config.active_reset_srtp_params = configuration.active_reset_srtp_params;
775
776 // DTLS has to be enabled to use SCTP.
Florent Castelli516e2842021-04-19 13:29:50777 if (dtls_enabled_) {
Tommic3257d02021-02-10 17:40:08778 config.sctp_factory = context_->sctp_transport_factory();
779 }
780
781 config.ice_transport_factory = ice_transport_factory_.get();
782 config.on_dtls_handshake_error_ =
783 [weak_ptr = weak_factory_.GetWeakPtr()](rtc::SSLHandshakeError s) {
784 if (weak_ptr) {
785 weak_ptr->OnTransportControllerDtlsHandshakeError(s);
786 }
787 };
788
Danil Chapovalov3bdb49b2023-11-30 07:59:39789 config.field_trials = &env_.field_trials();
Jonas Orelanded99dae2022-03-09 08:28:10790
Per Ke1e94ad2023-03-30 14:53:59791 transport_controller_.reset(new JsepTransportController(
792 network_thread(), port_allocator_.get(),
793 async_dns_resolver_factory_.get(), std::move(config)));
Tommic3257d02021-02-10 17:40:08794
795 transport_controller_->SubscribeIceConnectionState(
796 [this](cricket::IceConnectionState s) {
797 RTC_DCHECK_RUN_ON(network_thread());
798 signaling_thread()->PostTask(
Danil Chapovalova30439b2022-07-07 08:08:49799 SafeTask(signaling_thread_safety_.flag(), [this, s]() {
Tommic3257d02021-02-10 17:40:08800 RTC_DCHECK_RUN_ON(signaling_thread());
801 OnTransportControllerConnectionState(s);
802 }));
803 });
804 transport_controller_->SubscribeConnectionState(
805 [this](PeerConnectionInterface::PeerConnectionState s) {
806 RTC_DCHECK_RUN_ON(network_thread());
807 signaling_thread()->PostTask(
Danil Chapovalova30439b2022-07-07 08:08:49808 SafeTask(signaling_thread_safety_.flag(), [this, s]() {
Tommic3257d02021-02-10 17:40:08809 RTC_DCHECK_RUN_ON(signaling_thread());
810 SetConnectionState(s);
811 }));
812 });
813 transport_controller_->SubscribeStandardizedIceConnectionState(
814 [this](PeerConnectionInterface::IceConnectionState s) {
815 RTC_DCHECK_RUN_ON(network_thread());
816 signaling_thread()->PostTask(
Danil Chapovalova30439b2022-07-07 08:08:49817 SafeTask(signaling_thread_safety_.flag(), [this, s]() {
Tommic3257d02021-02-10 17:40:08818 RTC_DCHECK_RUN_ON(signaling_thread());
819 SetStandardizedIceConnectionState(s);
820 }));
821 });
822 transport_controller_->SubscribeIceGatheringState(
823 [this](cricket::IceGatheringState s) {
824 RTC_DCHECK_RUN_ON(network_thread());
825 signaling_thread()->PostTask(
Danil Chapovalova30439b2022-07-07 08:08:49826 SafeTask(signaling_thread_safety_.flag(), [this, s]() {
Tommic3257d02021-02-10 17:40:08827 RTC_DCHECK_RUN_ON(signaling_thread());
828 OnTransportControllerGatheringState(s);
829 }));
830 });
831 transport_controller_->SubscribeIceCandidateGathered(
832 [this](const std::string& transport,
833 const std::vector<cricket::Candidate>& candidates) {
834 RTC_DCHECK_RUN_ON(network_thread());
835 signaling_thread()->PostTask(
Danil Chapovalova30439b2022-07-07 08:08:49836 SafeTask(signaling_thread_safety_.flag(),
837 [this, t = transport, c = candidates]() {
838 RTC_DCHECK_RUN_ON(signaling_thread());
839 OnTransportControllerCandidatesGathered(t, c);
840 }));
Tommic3257d02021-02-10 17:40:08841 });
842 transport_controller_->SubscribeIceCandidateError(
843 [this](const cricket::IceCandidateErrorEvent& event) {
844 RTC_DCHECK_RUN_ON(network_thread());
Danil Chapovalova30439b2022-07-07 08:08:49845 signaling_thread()->PostTask(
846 SafeTask(signaling_thread_safety_.flag(), [this, event = event]() {
Tommic3257d02021-02-10 17:40:08847 RTC_DCHECK_RUN_ON(signaling_thread());
848 OnTransportControllerCandidateError(event);
849 }));
850 });
851 transport_controller_->SubscribeIceCandidatesRemoved(
852 [this](const std::vector<cricket::Candidate>& c) {
853 RTC_DCHECK_RUN_ON(network_thread());
854 signaling_thread()->PostTask(
Danil Chapovalova30439b2022-07-07 08:08:49855 SafeTask(signaling_thread_safety_.flag(), [this, c = c]() {
Tommic3257d02021-02-10 17:40:08856 RTC_DCHECK_RUN_ON(signaling_thread());
857 OnTransportControllerCandidatesRemoved(c);
858 }));
859 });
860 transport_controller_->SubscribeIceCandidatePairChanged(
861 [this](const cricket::CandidatePairChangeEvent& event) {
862 RTC_DCHECK_RUN_ON(network_thread());
Danil Chapovalova30439b2022-07-07 08:08:49863 signaling_thread()->PostTask(
864 SafeTask(signaling_thread_safety_.flag(), [this, event = event]() {
Tommic3257d02021-02-10 17:40:08865 RTC_DCHECK_RUN_ON(signaling_thread());
866 OnTransportControllerCandidateChanged(event);
867 }));
868 });
869
870 transport_controller_->SetIceConfig(ParseIceConfig(configuration));
Harald Alvestrandbc32c562022-02-09 12:08:47871 return transport_controller_.get();
Tommic3257d02021-02-10 17:40:08872}
873
Yves Gerey665174f2018-06-19 13:03:05874rtc::scoped_refptr<StreamCollectionInterface> PeerConnection::local_streams() {
Karl Wiberg5966c502019-02-21 22:55:09875 RTC_DCHECK_RUN_ON(signaling_thread());
Steve Antonfc853712018-03-01 21:48:58876 RTC_CHECK(!IsUnifiedPlan()) << "local_streams is not available with Unified "
877 "Plan SdpSemantics. Please use GetSenders "
878 "instead.";
Harald Alvestrand9cd199d2020-10-27 07:10:43879 return sdp_handler_->local_streams();
henrike@webrtc.org28e20752013-07-10 00:45:36880}
881
Yves Gerey665174f2018-06-19 13:03:05882rtc::scoped_refptr<StreamCollectionInterface> PeerConnection::remote_streams() {
Karl Wiberg5966c502019-02-21 22:55:09883 RTC_DCHECK_RUN_ON(signaling_thread());
Steve Antonfc853712018-03-01 21:48:58884 RTC_CHECK(!IsUnifiedPlan()) << "remote_streams is not available with Unified "
885 "Plan SdpSemantics. Please use GetReceivers "
886 "instead.";
Harald Alvestrand9cd199d2020-10-27 07:10:43887 return sdp_handler_->remote_streams();
henrike@webrtc.org28e20752013-07-10 00:45:36888}
889
perkj@webrtc.orgc2dd5ee2014-11-04 11:31:29890bool PeerConnection::AddStream(MediaStreamInterface* local_stream) {
Karl Wiberg744310f2019-02-14 09:18:56891 RTC_DCHECK_RUN_ON(signaling_thread());
Steve Antonfc853712018-03-01 21:48:58892 RTC_CHECK(!IsUnifiedPlan()) << "AddStream is not available with Unified Plan "
893 "SdpSemantics. Please use AddTrack instead.";
Peter Boström1a9d6152015-12-08 21:15:17894 TRACE_EVENT0("webrtc", "PeerConnection::AddStream");
Harald Alvestrand35ba0c52022-05-05 07:37:41895 if (!ConfiguredForMedia()) {
896 RTC_LOG(LS_ERROR) << "AddStream: Not configured for media";
897 return false;
898 }
Harald Alvestrand9cd199d2020-10-27 07:10:43899 return sdp_handler_->AddStream(local_stream);
henrike@webrtc.org28e20752013-07-10 00:45:36900}
901
902void PeerConnection::RemoveStream(MediaStreamInterface* local_stream) {
Karl Wiberg744310f2019-02-14 09:18:56903 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand35ba0c52022-05-05 07:37:41904 RTC_DCHECK(ConfiguredForMedia());
Steve Antonfc853712018-03-01 21:48:58905 RTC_CHECK(!IsUnifiedPlan()) << "RemoveStream is not available with Unified "
906 "Plan SdpSemantics. Please use RemoveTrack "
907 "instead.";
Peter Boström1a9d6152015-12-08 21:15:17908 TRACE_EVENT0("webrtc", "PeerConnection::RemoveStream");
Harald Alvestrand9cd199d2020-10-27 07:10:43909 sdp_handler_->RemoveStream(local_stream);
henrike@webrtc.org28e20752013-07-10 00:45:36910}
911
Steve Anton2d6c76a2018-01-06 01:10:52912RTCErrorOr<rtc::scoped_refptr<RtpSenderInterface>> PeerConnection::AddTrack(
Steve Antonf9381f02017-12-14 18:23:57913 rtc::scoped_refptr<MediaStreamTrackInterface> track,
Seth Hampson845e8782018-03-02 19:34:10914 const std::vector<std::string>& stream_ids) {
Jonas Oreland4b2a1062022-10-19 07:24:42915 return AddTrack(std::move(track), stream_ids, nullptr);
916}
917
918RTCErrorOr<rtc::scoped_refptr<RtpSenderInterface>> PeerConnection::AddTrack(
919 rtc::scoped_refptr<MediaStreamTrackInterface> track,
920 const std::vector<std::string>& stream_ids,
921 const std::vector<RtpEncodingParameters>& init_send_encodings) {
922 return AddTrack(std::move(track), stream_ids, &init_send_encodings);
923}
924
925RTCErrorOr<rtc::scoped_refptr<RtpSenderInterface>> PeerConnection::AddTrack(
926 rtc::scoped_refptr<MediaStreamTrackInterface> track,
927 const std::vector<std::string>& stream_ids,
928 const std::vector<RtpEncodingParameters>* init_send_encodings) {
Karl Wiberg744310f2019-02-14 09:18:56929 RTC_DCHECK_RUN_ON(signaling_thread());
Steve Anton2d6c76a2018-01-06 01:10:52930 TRACE_EVENT0("webrtc", "PeerConnection::AddTrack");
Harald Alvestrand35ba0c52022-05-05 07:37:41931 if (!ConfiguredForMedia()) {
932 LOG_AND_RETURN_ERROR(RTCErrorType::UNSUPPORTED_OPERATION,
933 "Not configured for media");
934 }
Steve Antonf9381f02017-12-14 18:23:57935 if (!track) {
936 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER, "Track is null.");
937 }
938 if (!(track->kind() == MediaStreamTrackInterface::kAudioKind ||
939 track->kind() == MediaStreamTrackInterface::kVideoKind)) {
940 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
941 "Track has invalid kind: " + track->kind());
942 }
Steve Antonf9381f02017-12-14 18:23:57943 if (IsClosed()) {
944 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_STATE,
945 "PeerConnection is closed.");
deadbeefe1f9d832016-01-14 23:35:42946 }
Niels Möllerafb246b2022-04-20 12:26:50947 if (rtp_manager()->FindSenderForTrack(track.get())) {
Steve Antonf9381f02017-12-14 18:23:57948 LOG_AND_RETURN_ERROR(
949 RTCErrorType::INVALID_PARAMETER,
950 "Sender already exists for track " + track->id() + ".");
deadbeefe1f9d832016-01-14 23:35:42951 }
Jonas Oreland4b2a1062022-10-19 07:24:42952 auto sender_or_error =
953 rtp_manager()->AddTrack(track, stream_ids, init_send_encodings);
Steve Antonf9381f02017-12-14 18:23:57954 if (sender_or_error.ok()) {
Harald Alvestrand9cd199d2020-10-27 07:10:43955 sdp_handler_->UpdateNegotiationNeeded();
Henrik Boströmf7859892022-07-04 12:36:37956 legacy_stats_->AddTrack(track.get());
Steve Antonf9381f02017-12-14 18:23:57957 }
958 return sender_or_error;
959}
deadbeefe1f9d832016-01-14 23:35:42960
Harald Alvestrand09a0d012022-01-04 19:42:07961RTCError PeerConnection::RemoveTrackOrError(
Steve Antonf9381f02017-12-14 18:23:57962 rtc::scoped_refptr<RtpSenderInterface> sender) {
Karl Wiberg744310f2019-02-14 09:18:56963 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand35ba0c52022-05-05 07:37:41964 if (!ConfiguredForMedia()) {
965 LOG_AND_RETURN_ERROR(RTCErrorType::UNSUPPORTED_OPERATION,
966 "Not configured for media");
967 }
Steve Antonf9381f02017-12-14 18:23:57968 if (!sender) {
969 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER, "Sender is null.");
970 }
deadbeefe1f9d832016-01-14 23:35:42971 if (IsClosed()) {
Steve Antonf9381f02017-12-14 18:23:57972 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_STATE,
973 "PeerConnection is closed.");
deadbeefe1f9d832016-01-14 23:35:42974 }
Steve Antonf9381f02017-12-14 18:23:57975 if (IsUnifiedPlan()) {
976 auto transceiver = FindTransceiverBySender(sender);
977 if (!transceiver || !sender->track()) {
978 return RTCError::OK();
979 }
980 sender->SetTrack(nullptr);
981 if (transceiver->direction() == RtpTransceiverDirection::kSendRecv) {
Steve Anton52d86772018-02-20 23:48:12982 transceiver->internal()->set_direction(
983 RtpTransceiverDirection::kRecvOnly);
Steve Antonf9381f02017-12-14 18:23:57984 } else if (transceiver->direction() == RtpTransceiverDirection::kSendOnly) {
Steve Anton52d86772018-02-20 23:48:12985 transceiver->internal()->set_direction(
986 RtpTransceiverDirection::kInactive);
Steve Antonf9381f02017-12-14 18:23:57987 }
Steve Anton4171afb2017-11-20 18:20:22988 } else {
Steve Antonf9381f02017-12-14 18:23:57989 bool removed;
990 if (sender->media_type() == cricket::MEDIA_TYPE_AUDIO) {
Harald Alvestrande15fb152020-10-19 13:28:05991 removed = rtp_manager()->GetAudioTransceiver()->internal()->RemoveSender(
Niels Möllerafb246b2022-04-20 12:26:50992 sender.get());
Steve Antonf9381f02017-12-14 18:23:57993 } else {
994 RTC_DCHECK_EQ(cricket::MEDIA_TYPE_VIDEO, sender->media_type());
Harald Alvestrande15fb152020-10-19 13:28:05995 removed = rtp_manager()->GetVideoTransceiver()->internal()->RemoveSender(
Niels Möllerafb246b2022-04-20 12:26:50996 sender.get());
Steve Antonf9381f02017-12-14 18:23:57997 }
998 if (!removed) {
999 LOG_AND_RETURN_ERROR(
1000 RTCErrorType::INVALID_PARAMETER,
1001 "Couldn't find sender " + sender->id() + " to remove.");
1002 }
Steve Anton4171afb2017-11-20 18:20:221003 }
Harald Alvestrand9cd199d2020-10-27 07:10:431004 sdp_handler_->UpdateNegotiationNeeded();
Steve Antonf9381f02017-12-14 18:23:571005 return RTCError::OK();
1006}
1007
1008rtc::scoped_refptr<RtpTransceiverProxyWithInternal<RtpTransceiver>>
1009PeerConnection::FindTransceiverBySender(
1010 rtc::scoped_refptr<RtpSenderInterface> sender) {
Harald Alvestrande15fb152020-10-19 13:28:051011 return rtp_manager()->transceivers()->FindBySender(sender);
deadbeefe1f9d832016-01-14 23:35:421012}
1013
Steve Anton9158ef62017-11-27 21:01:521014RTCErrorOr<rtc::scoped_refptr<RtpTransceiverInterface>>
1015PeerConnection::AddTransceiver(
1016 rtc::scoped_refptr<MediaStreamTrackInterface> track) {
Harald Alvestrand35ba0c52022-05-05 07:37:411017 if (!ConfiguredForMedia()) {
1018 LOG_AND_RETURN_ERROR(RTCErrorType::UNSUPPORTED_OPERATION,
1019 "Not configured for media");
1020 }
1021
Steve Anton9158ef62017-11-27 21:01:521022 return AddTransceiver(track, RtpTransceiverInit());
1023}
1024
1025RTCErrorOr<rtc::scoped_refptr<RtpTransceiverInterface>>
1026PeerConnection::AddTransceiver(
1027 rtc::scoped_refptr<MediaStreamTrackInterface> track,
1028 const RtpTransceiverInit& init) {
Karl Wiberg744310f2019-02-14 09:18:561029 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand35ba0c52022-05-05 07:37:411030 if (!ConfiguredForMedia()) {
1031 LOG_AND_RETURN_ERROR(RTCErrorType::UNSUPPORTED_OPERATION,
1032 "Not configured for media");
1033 }
Steve Antonfc853712018-03-01 21:48:581034 RTC_CHECK(IsUnifiedPlan())
1035 << "AddTransceiver is only available with Unified Plan SdpSemantics";
Steve Anton9158ef62017-11-27 21:01:521036 if (!track) {
1037 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER, "track is null");
1038 }
1039 cricket::MediaType media_type;
1040 if (track->kind() == MediaStreamTrackInterface::kAudioKind) {
1041 media_type = cricket::MEDIA_TYPE_AUDIO;
1042 } else if (track->kind() == MediaStreamTrackInterface::kVideoKind) {
1043 media_type = cricket::MEDIA_TYPE_VIDEO;
1044 } else {
1045 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
1046 "Track kind is not audio or video");
1047 }
1048 return AddTransceiver(media_type, track, init);
1049}
1050
1051RTCErrorOr<rtc::scoped_refptr<RtpTransceiverInterface>>
1052PeerConnection::AddTransceiver(cricket::MediaType media_type) {
1053 return AddTransceiver(media_type, RtpTransceiverInit());
1054}
1055
1056RTCErrorOr<rtc::scoped_refptr<RtpTransceiverInterface>>
1057PeerConnection::AddTransceiver(cricket::MediaType media_type,
1058 const RtpTransceiverInit& init) {
Karl Wiberg744310f2019-02-14 09:18:561059 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand35ba0c52022-05-05 07:37:411060 if (!ConfiguredForMedia()) {
1061 LOG_AND_RETURN_ERROR(RTCErrorType::UNSUPPORTED_OPERATION,
1062 "Not configured for media");
1063 }
Steve Antonfc853712018-03-01 21:48:581064 RTC_CHECK(IsUnifiedPlan())
1065 << "AddTransceiver is only available with Unified Plan SdpSemantics";
Steve Anton9158ef62017-11-27 21:01:521066 if (!(media_type == cricket::MEDIA_TYPE_AUDIO ||
1067 media_type == cricket::MEDIA_TYPE_VIDEO)) {
1068 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
1069 "media type is not audio or video");
1070 }
1071 return AddTransceiver(media_type, nullptr, init);
1072}
1073
1074RTCErrorOr<rtc::scoped_refptr<RtpTransceiverInterface>>
1075PeerConnection::AddTransceiver(
1076 cricket::MediaType media_type,
1077 rtc::scoped_refptr<MediaStreamTrackInterface> track,
Steve Anton22da89f2018-01-25 21:58:071078 const RtpTransceiverInit& init,
Guido Urdaneta70c2db12019-04-16 10:24:141079 bool update_negotiation_needed) {
Harald Alvestranda474fbf2020-10-01 16:47:231080 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand35ba0c52022-05-05 07:37:411081 if (!ConfiguredForMedia()) {
1082 LOG_AND_RETURN_ERROR(RTCErrorType::UNSUPPORTED_OPERATION,
1083 "Not configured for media");
1084 }
Steve Anton9158ef62017-11-27 21:01:521085 RTC_DCHECK((media_type == cricket::MEDIA_TYPE_AUDIO ||
1086 media_type == cricket::MEDIA_TYPE_VIDEO));
1087 if (track) {
1088 RTC_DCHECK_EQ(media_type,
1089 (track->kind() == MediaStreamTrackInterface::kAudioKind
1090 ? cricket::MEDIA_TYPE_AUDIO
1091 : cricket::MEDIA_TYPE_VIDEO));
1092 }
1093
Amit Hilbuchaa584152019-02-07 01:09:521094 size_t num_rids = absl::c_count_if(init.send_encodings,
1095 [](const RtpEncodingParameters& encoding) {
1096 return !encoding.rid.empty();
1097 });
1098 if (num_rids > 0 && num_rids != init.send_encodings.size()) {
Amit Hilbuchce470aa2019-02-07 01:09:521099 LOG_AND_RETURN_ERROR(
Amit Hilbuchaa584152019-02-07 01:09:521100 RTCErrorType::INVALID_PARAMETER,
1101 "RIDs must be provided for either all or none of the send encodings.");
Emircan Uysaler78323432019-02-08 20:41:391102 }
1103
Amit Hilbuchf4770402019-04-08 21:11:571104 if (num_rids > 0 && absl::c_any_of(init.send_encodings,
1105 [](const RtpEncodingParameters& encoding) {
1106 return !IsLegalRsidName(encoding.rid);
1107 })) {
1108 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
1109 "Invalid RID value provided.");
1110 }
1111
Amit Hilbuchaa584152019-02-07 01:09:521112 if (absl::c_any_of(init.send_encodings,
1113 [](const RtpEncodingParameters& encoding) {
1114 return encoding.ssrc.has_value();
1115 })) {
1116 LOG_AND_RETURN_ERROR(
1117 RTCErrorType::UNSUPPORTED_PARAMETER,
1118 "Attempted to set an unimplemented parameter of RtpParameters.");
Florent Castelli892acf02018-10-01 20:47:201119 }
1120
1121 RtpParameters parameters;
1122 parameters.encodings = init.send_encodings;
Amit Hilbuchaa584152019-02-07 01:09:521123
1124 // Encodings are dropped from the tail if too many are provided.
Florent Castellie1b685a2021-04-30 17:11:371125 size_t max_simulcast_streams =
1126 media_type == cricket::MEDIA_TYPE_VIDEO ? kMaxSimulcastStreams : 1u;
1127 if (parameters.encodings.size() > max_simulcast_streams) {
Amit Hilbuchaa584152019-02-07 01:09:521128 parameters.encodings.erase(
Florent Castellie1b685a2021-04-30 17:11:371129 parameters.encodings.begin() + max_simulcast_streams,
Amit Hilbuchaa584152019-02-07 01:09:521130 parameters.encodings.end());
1131 }
1132
1133 // Single RID should be removed.
1134 if (parameters.encodings.size() == 1 &&
1135 !parameters.encodings[0].rid.empty()) {
1136 RTC_LOG(LS_INFO) << "Removing RID: " << parameters.encodings[0].rid << ".";
1137 parameters.encodings[0].rid.clear();
1138 }
1139
1140 // If RIDs were not provided, they are generated for simulcast scenario.
1141 if (parameters.encodings.size() > 1 && num_rids == 0) {
1142 rtc::UniqueStringGenerator rid_generator;
1143 for (RtpEncodingParameters& encoding : parameters.encodings) {
Harald Alvestrand5ad491e2023-02-10 11:28:041144 encoding.rid = rid_generator.GenerateString();
Amit Hilbuchaa584152019-02-07 01:09:521145 }
1146 }
1147
Florent Castellibd1e5d52023-01-17 17:08:261148 // If no encoding parameters were provided, a default entry is created.
1149 if (parameters.encodings.empty()) {
1150 parameters.encodings.push_back({});
1151 }
1152
Florent Castelli892acf02018-10-01 20:47:201153 if (UnimplementedRtpParameterHasValue(parameters)) {
1154 LOG_AND_RETURN_ERROR(
1155 RTCErrorType::UNSUPPORTED_PARAMETER,
1156 "Attempted to set an unimplemented parameter of RtpParameters.");
1157 }
Steve Anton9158ef62017-11-27 21:01:521158
Florent Castelli725ee242022-10-18 15:05:581159 std::vector<cricket::VideoCodec> codecs;
Florent Castelli43a5dd82023-04-12 10:45:071160 // Gather the current codec capabilities to allow checking scalabilityMode and
1161 // codec selection against supported values.
Florent Castelli725ee242022-10-18 15:05:581162 if (media_type == cricket::MEDIA_TYPE_VIDEO) {
Florent Castelli725ee242022-10-18 15:05:581163 codecs = context_->media_engine()->video().send_codecs(false);
Florent Castelli43a5dd82023-04-12 10:45:071164 } else {
1165 codecs = context_->media_engine()->voice().send_codecs();
Florent Castelli725ee242022-10-18 15:05:581166 }
1167
Florent Castelli43a5dd82023-04-12 10:45:071168 auto result =
1169 cricket::CheckRtpParametersValues(parameters, codecs, absl::nullopt);
Florent Castellic1a0bcb2019-01-29 13:26:481170 if (!result.ok()) {
Florent Castelli43a5dd82023-04-12 10:45:071171 if (result.type() == RTCErrorType::INVALID_MODIFICATION) {
1172 result.set_type(RTCErrorType::UNSUPPORTED_OPERATION);
1173 }
Florent Castellic1a0bcb2019-01-29 13:26:481174 LOG_AND_RETURN_ERROR(result.type(), result.message());
1175 }
1176
Steve Anton3d954a62018-04-02 18:27:231177 RTC_LOG(LS_INFO) << "Adding " << cricket::MediaTypeToString(media_type)
1178 << " transceiver in response to a call to AddTransceiver.";
Steve Anton07563732018-06-26 18:13:501179 // Set the sender ID equal to the track ID if the track is specified unless
1180 // that sender ID is already in use.
Harald Alvestrande15fb152020-10-19 13:28:051181 std::string sender_id = (track && !rtp_manager()->FindSenderById(track->id())
1182 ? track->id()
1183 : rtc::CreateRandomUuid());
1184 auto sender = rtp_manager()->CreateSender(
1185 media_type, sender_id, track, init.stream_ids, parameters.encodings);
1186 auto receiver =
1187 rtp_manager()->CreateReceiver(media_type, rtc::CreateRandomUuid());
1188 auto transceiver = rtp_manager()->CreateAndAddTransceiver(sender, receiver);
Steve Anton02ee47c2018-01-11 00:26:061189 transceiver->internal()->set_direction(init.direction);
1190
Guido Urdaneta70c2db12019-04-16 10:24:141191 if (update_negotiation_needed) {
Harald Alvestrand9cd199d2020-10-27 07:10:431192 sdp_handler_->UpdateNegotiationNeeded();
Steve Anton22da89f2018-01-25 21:58:071193 }
Steve Antonf9381f02017-12-14 18:23:571194
1195 return rtc::scoped_refptr<RtpTransceiverInterface>(transceiver);
1196}
1197
Steve Anton52d86772018-02-20 23:48:121198void PeerConnection::OnNegotiationNeeded() {
1199 RTC_DCHECK_RUN_ON(signaling_thread());
1200 RTC_DCHECK(!IsClosed());
Harald Alvestrand9cd199d2020-10-27 07:10:431201 sdp_handler_->UpdateNegotiationNeeded();
Steve Anton52d86772018-02-20 23:48:121202}
1203
deadbeeffac06552015-11-25 19:26:011204rtc::scoped_refptr<RtpSenderInterface> PeerConnection::CreateSender(
deadbeefbd7d8f72015-12-19 00:58:441205 const std::string& kind,
1206 const std::string& stream_id) {
Karl Wiberg5966c502019-02-21 22:55:091207 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand35ba0c52022-05-05 07:37:411208 if (!ConfiguredForMedia()) {
1209 RTC_LOG(LS_ERROR) << "Not configured for media";
1210 return nullptr;
1211 }
Steve Antonfc853712018-03-01 21:48:581212 RTC_CHECK(!IsUnifiedPlan()) << "CreateSender is not available with Unified "
1213 "Plan SdpSemantics. Please use AddTransceiver "
1214 "instead.";
Peter Boström1a9d6152015-12-08 21:15:171215 TRACE_EVENT0("webrtc", "PeerConnection::CreateSender");
zhihuang29ff8442016-07-27 18:07:251216 if (IsClosed()) {
1217 return nullptr;
1218 }
Steve Anton4171afb2017-11-20 18:20:221219
Seth Hampson5b4f0752018-04-02 23:31:361220 // Internally we need to have one stream with Plan B semantics, so we
1221 // generate a random stream ID if not specified.
Seth Hampson845e8782018-03-02 19:34:101222 std::vector<std::string> stream_ids;
Seth Hampson5b4f0752018-04-02 23:31:361223 if (stream_id.empty()) {
1224 stream_ids.push_back(rtc::CreateRandomUuid());
1225 RTC_LOG(LS_INFO)
1226 << "No stream_id specified for sender. Generated stream ID: "
1227 << stream_ids[0];
1228 } else {
Seth Hampson845e8782018-03-02 19:34:101229 stream_ids.push_back(stream_id);
Steve Anton02ee47c2018-01-11 00:26:061230 }
1231
Steve Anton4171afb2017-11-20 18:20:221232 // TODO(steveanton): Move construction of the RtpSenders to RtpTransceiver.
deadbeefa601f5c2016-06-06 21:27:391233 rtc::scoped_refptr<RtpSenderProxyWithInternal<RtpSenderInternal>> new_sender;
deadbeeffac06552015-11-25 19:26:011234 if (kind == MediaStreamTrackInterface::kAudioKind) {
Henrik Boströmf7859892022-07-04 12:36:371235 auto audio_sender =
1236 AudioRtpSender::Create(worker_thread(), rtc::CreateRandomUuid(),
1237 legacy_stats_.get(), rtp_manager());
Harald Alvestrandc0d44d92022-12-13 12:57:241238 audio_sender->SetMediaChannel(rtp_manager()->voice_media_send_channel());
deadbeefa601f5c2016-06-06 21:27:391239 new_sender = RtpSenderProxyWithInternal<RtpSenderInternal>::Create(
Steve Anton02ee47c2018-01-11 00:26:061240 signaling_thread(), audio_sender);
Harald Alvestrande15fb152020-10-19 13:28:051241 rtp_manager()->GetAudioTransceiver()->internal()->AddSender(new_sender);
deadbeeffac06552015-11-25 19:26:011242 } else if (kind == MediaStreamTrackInterface::kVideoKind) {
Harald Alvestrande15fb152020-10-19 13:28:051243 auto video_sender = VideoRtpSender::Create(
1244 worker_thread(), rtc::CreateRandomUuid(), rtp_manager());
Harald Alvestrandc0d44d92022-12-13 12:57:241245 video_sender->SetMediaChannel(rtp_manager()->video_media_send_channel());
deadbeefa601f5c2016-06-06 21:27:391246 new_sender = RtpSenderProxyWithInternal<RtpSenderInternal>::Create(
Steve Anton02ee47c2018-01-11 00:26:061247 signaling_thread(), video_sender);
Harald Alvestrande15fb152020-10-19 13:28:051248 rtp_manager()->GetVideoTransceiver()->internal()->AddSender(new_sender);
deadbeeffac06552015-11-25 19:26:011249 } else {
Mirko Bonadei675513b2017-11-09 10:09:251250 RTC_LOG(LS_ERROR) << "CreateSender called with invalid kind: " << kind;
Steve Anton4171afb2017-11-20 18:20:221251 return nullptr;
deadbeeffac06552015-11-25 19:26:011252 }
Henrik Andreasssoncc189172019-05-20 09:01:381253 new_sender->internal()->set_stream_ids(stream_ids);
Steve Anton4171afb2017-11-20 18:20:221254
deadbeefe1f9d832016-01-14 23:35:421255 return new_sender;
deadbeeffac06552015-11-25 19:26:011256}
1257
deadbeef70ab1a12015-09-28 23:53:551258std::vector<rtc::scoped_refptr<RtpSenderInterface>> PeerConnection::GetSenders()
1259 const {
Karl Wiberga58e1692019-03-26 12:33:431260 RTC_DCHECK_RUN_ON(signaling_thread());
deadbeefa601f5c2016-06-06 21:27:391261 std::vector<rtc::scoped_refptr<RtpSenderInterface>> ret;
Harald Alvestrand8101e7b2022-05-23 14:57:471262 if (ConfiguredForMedia()) {
1263 for (const auto& sender : rtp_manager()->GetSendersInternal()) {
1264 ret.push_back(sender);
1265 }
deadbeefa601f5c2016-06-06 21:27:391266 }
1267 return ret;
deadbeef70ab1a12015-09-28 23:53:551268}
1269
1270std::vector<rtc::scoped_refptr<RtpReceiverInterface>>
1271PeerConnection::GetReceivers() const {
Karl Wiberga58e1692019-03-26 12:33:431272 RTC_DCHECK_RUN_ON(signaling_thread());
deadbeefa601f5c2016-06-06 21:27:391273 std::vector<rtc::scoped_refptr<RtpReceiverInterface>> ret;
Harald Alvestrand8101e7b2022-05-23 14:57:471274 if (ConfiguredForMedia()) {
1275 for (const auto& receiver : rtp_manager()->GetReceiversInternal()) {
1276 ret.push_back(receiver);
1277 }
deadbeefa601f5c2016-06-06 21:27:391278 }
1279 return ret;
deadbeef70ab1a12015-09-28 23:53:551280}
1281
Steve Anton9158ef62017-11-27 21:01:521282std::vector<rtc::scoped_refptr<RtpTransceiverInterface>>
1283PeerConnection::GetTransceivers() const {
Karl Wiberg5966c502019-02-21 22:55:091284 RTC_DCHECK_RUN_ON(signaling_thread());
Steve Antonfc853712018-03-01 21:48:581285 RTC_CHECK(IsUnifiedPlan())
1286 << "GetTransceivers is only supported with Unified Plan SdpSemantics.";
Steve Anton9158ef62017-11-27 21:01:521287 std::vector<rtc::scoped_refptr<RtpTransceiverInterface>> all_transceivers;
Harald Alvestrand8101e7b2022-05-23 14:57:471288 if (ConfiguredForMedia()) {
1289 for (const auto& transceiver : rtp_manager()->transceivers()->List()) {
1290 all_transceivers.push_back(transceiver);
1291 }
Steve Anton9158ef62017-11-27 21:01:521292 }
1293 return all_transceivers;
1294}
1295
henrike@webrtc.org28e20752013-07-10 00:45:361296bool PeerConnection::GetStats(StatsObserver* observer,
wu@webrtc.orgb9a088b2014-02-13 23:18:491297 MediaStreamTrackInterface* track,
1298 StatsOutputLevel level) {
Henrik Boströmf7859892022-07-04 12:36:371299 TRACE_EVENT0("webrtc", "PeerConnection::GetStats (legacy)");
Karl Wiberg6cab5c82019-03-26 08:57:011300 RTC_DCHECK_RUN_ON(signaling_thread());
nisse7ce109a2017-01-31 08:57:561301 if (!observer) {
Henrik Boströmf7859892022-07-04 12:36:371302 RTC_LOG(LS_ERROR) << "Legacy GetStats - observer is NULL.";
henrike@webrtc.org28e20752013-07-10 00:45:361303 return false;
1304 }
1305
Tommife041642021-04-07 08:08:281306 RTC_LOG_THREAD_BLOCK_COUNT();
1307
Henrik Boströmf7859892022-07-04 12:36:371308 legacy_stats_->UpdateStats(level);
Tommi19015512022-02-02 10:49:351309
1310 RTC_DCHECK_BLOCK_COUNT_NO_MORE_THAN(4);
1311
Henrik Boströmf7859892022-07-04 12:36:371312 // The LegacyStatsCollector is used to tell if a track is valid because it may
zhihuange9e94c32016-11-04 18:38:151313 // remember tracks that the PeerConnection previously removed.
Henrik Boströmf7859892022-07-04 12:36:371314 if (track && !legacy_stats_->IsValidTrack(track->id())) {
1315 RTC_LOG(LS_WARNING) << "Legacy GetStats is called with an invalid track: "
Mirko Bonadei675513b2017-11-09 10:09:251316 << track->id();
zhihuange9e94c32016-11-04 18:38:151317 return false;
1318 }
Henrik Boströmf7859892022-07-04 12:36:371319 message_handler_.PostGetStats(observer, legacy_stats_.get(), track);
Tommife041642021-04-07 08:08:281320
henrike@webrtc.org28e20752013-07-10 00:45:361321 return true;
1322}
1323
hbos74e1a4f2016-09-16 06:33:011324void PeerConnection::GetStats(RTCStatsCollectorCallback* callback) {
Henrik Boström1df1bf82018-03-20 12:24:201325 TRACE_EVENT0("webrtc", "PeerConnection::GetStats");
Karl Wiberg6cab5c82019-03-26 08:57:011326 RTC_DCHECK_RUN_ON(signaling_thread());
hbos74e1a4f2016-09-16 06:33:011327 RTC_DCHECK(stats_collector_);
Henrik Boström1df1bf82018-03-20 12:24:201328 RTC_DCHECK(callback);
Tommife041642021-04-07 08:08:281329 RTC_LOG_THREAD_BLOCK_COUNT();
Niels Möllere7cc8832022-01-04 14:20:031330 stats_collector_->GetStatsReport(
1331 rtc::scoped_refptr<RTCStatsCollectorCallback>(callback));
Henrik Boström5023ffb2022-07-04 13:47:251332 RTC_DCHECK_BLOCK_COUNT_NO_MORE_THAN(2);
hbos74e1a4f2016-09-16 06:33:011333}
1334
Henrik Boström1df1bf82018-03-20 12:24:201335void PeerConnection::GetStats(
1336 rtc::scoped_refptr<RtpSenderInterface> selector,
1337 rtc::scoped_refptr<RTCStatsCollectorCallback> callback) {
1338 TRACE_EVENT0("webrtc", "PeerConnection::GetStats");
Karl Wiberg6cab5c82019-03-26 08:57:011339 RTC_DCHECK_RUN_ON(signaling_thread());
Henrik Boström1df1bf82018-03-20 12:24:201340 RTC_DCHECK(callback);
1341 RTC_DCHECK(stats_collector_);
Henrik Boström5023ffb2022-07-04 13:47:251342 RTC_LOG_THREAD_BLOCK_COUNT();
Henrik Boström1df1bf82018-03-20 12:24:201343 rtc::scoped_refptr<RtpSenderInternal> internal_sender;
1344 if (selector) {
Harald Alvestrande15fb152020-10-19 13:28:051345 for (const auto& proxy_transceiver :
1346 rtp_manager()->transceivers()->List()) {
Henrik Boström1df1bf82018-03-20 12:24:201347 for (const auto& proxy_sender :
1348 proxy_transceiver->internal()->senders()) {
1349 if (proxy_sender == selector) {
1350 internal_sender = proxy_sender->internal();
1351 break;
1352 }
1353 }
1354 if (internal_sender)
1355 break;
1356 }
1357 }
Artem Titov880fa812021-07-30 20:30:231358 // If there is no `internal_sender` then `selector` is either null or does not
Henrik Boström1df1bf82018-03-20 12:24:201359 // belong to the PeerConnection (in Plan B, senders can be removed from the
1360 // PeerConnection). This means that "all the stats objects representing the
1361 // selector" is an empty set. Invoking GetStatsReport() with a null selector
1362 // produces an empty stats report.
1363 stats_collector_->GetStatsReport(internal_sender, callback);
Henrik Boström5023ffb2022-07-04 13:47:251364 RTC_DCHECK_BLOCK_COUNT_NO_MORE_THAN(2);
Henrik Boström1df1bf82018-03-20 12:24:201365}
1366
1367void PeerConnection::GetStats(
1368 rtc::scoped_refptr<RtpReceiverInterface> selector,
1369 rtc::scoped_refptr<RTCStatsCollectorCallback> callback) {
1370 TRACE_EVENT0("webrtc", "PeerConnection::GetStats");
Karl Wiberg6cab5c82019-03-26 08:57:011371 RTC_DCHECK_RUN_ON(signaling_thread());
Henrik Boström1df1bf82018-03-20 12:24:201372 RTC_DCHECK(callback);
1373 RTC_DCHECK(stats_collector_);
Henrik Boström5023ffb2022-07-04 13:47:251374 RTC_LOG_THREAD_BLOCK_COUNT();
Henrik Boström1df1bf82018-03-20 12:24:201375 rtc::scoped_refptr<RtpReceiverInternal> internal_receiver;
1376 if (selector) {
Harald Alvestrande15fb152020-10-19 13:28:051377 for (const auto& proxy_transceiver :
1378 rtp_manager()->transceivers()->List()) {
Henrik Boström1df1bf82018-03-20 12:24:201379 for (const auto& proxy_receiver :
1380 proxy_transceiver->internal()->receivers()) {
1381 if (proxy_receiver == selector) {
1382 internal_receiver = proxy_receiver->internal();
1383 break;
1384 }
1385 }
1386 if (internal_receiver)
1387 break;
1388 }
1389 }
Artem Titov880fa812021-07-30 20:30:231390 // If there is no `internal_receiver` then `selector` is either null or does
Henrik Boström1df1bf82018-03-20 12:24:201391 // not belong to the PeerConnection (in Plan B, receivers can be removed from
1392 // the PeerConnection). This means that "all the stats objects representing
1393 // the selector" is an empty set. Invoking GetStatsReport() with a null
1394 // selector produces an empty stats report.
1395 stats_collector_->GetStatsReport(internal_receiver, callback);
Henrik Boström5023ffb2022-07-04 13:47:251396 RTC_DCHECK_BLOCK_COUNT_NO_MORE_THAN(2);
Henrik Boström1df1bf82018-03-20 12:24:201397}
1398
henrike@webrtc.org28e20752013-07-10 00:45:361399PeerConnectionInterface::SignalingState PeerConnection::signaling_state() {
Karl Wiberg8d2e2282019-02-17 12:00:071400 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand9cd199d2020-10-27 07:10:431401 return sdp_handler_->signaling_state();
henrike@webrtc.org28e20752013-07-10 00:45:361402}
1403
henrike@webrtc.org28e20752013-07-10 00:45:361404PeerConnectionInterface::IceConnectionState
1405PeerConnection::ice_connection_state() {
Karl Wiberg8d2e2282019-02-17 12:00:071406 RTC_DCHECK_RUN_ON(signaling_thread());
henrike@webrtc.org28e20752013-07-10 00:45:361407 return ice_connection_state_;
1408}
1409
Alex Loiko9289eda2018-11-23 16:18:591410PeerConnectionInterface::IceConnectionState
1411PeerConnection::standardized_ice_connection_state() {
Karl Wiberg8d2e2282019-02-17 12:00:071412 RTC_DCHECK_RUN_ON(signaling_thread());
Alex Loiko9289eda2018-11-23 16:18:591413 return standardized_ice_connection_state_;
1414}
1415
Jonas Olsson635474e2018-10-18 13:58:171416PeerConnectionInterface::PeerConnectionState
1417PeerConnection::peer_connection_state() {
Karl Wiberg8d2e2282019-02-17 12:00:071418 RTC_DCHECK_RUN_ON(signaling_thread());
Jonas Olsson635474e2018-10-18 13:58:171419 return connection_state_;
1420}
1421
henrike@webrtc.org28e20752013-07-10 00:45:361422PeerConnectionInterface::IceGatheringState
1423PeerConnection::ice_gathering_state() {
Karl Wiberg8d2e2282019-02-17 12:00:071424 RTC_DCHECK_RUN_ON(signaling_thread());
henrike@webrtc.org28e20752013-07-10 00:45:361425 return ice_gathering_state_;
1426}
1427
Harald Alvestrand61f74d92020-03-02 10:20:001428absl::optional<bool> PeerConnection::can_trickle_ice_candidates() {
1429 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrandcdcfab02020-09-28 13:02:071430 const SessionDescriptionInterface* description = current_remote_description();
Harald Alvestrand61f74d92020-03-02 10:20:001431 if (!description) {
Harald Alvestrandcdcfab02020-09-28 13:02:071432 description = pending_remote_description();
Harald Alvestrand61f74d92020-03-02 10:20:001433 }
1434 if (!description) {
1435 return absl::nullopt;
1436 }
1437 // TODO(bugs.webrtc.org/7443): Change to retrieve from session-level option.
1438 if (description->description()->transport_infos().size() < 1) {
1439 return absl::nullopt;
1440 }
1441 return description->description()->transport_infos()[0].description.HasOption(
1442 "trickle");
1443}
1444
Harald Alvestranda9af50f2021-05-21 13:33:511445RTCErrorOr<rtc::scoped_refptr<DataChannelInterface>>
1446PeerConnection::CreateDataChannelOrError(const std::string& label,
1447 const DataChannelInit* config) {
Karl Wiberg106d92d2019-02-14 09:17:471448 RTC_DCHECK_RUN_ON(signaling_thread());
Peter Boström1a9d6152015-12-08 21:15:171449 TRACE_EVENT0("webrtc", "PeerConnection::CreateDataChannel");
zhihuang9763d562016-08-05 18:14:501450
Tommi4f7ade52023-03-29 18:46:591451 if (IsClosed()) {
1452 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_STATE,
1453 "CreateDataChannelOrError: PeerConnection is closed.");
1454 }
1455
Harald Alvestrand5da3eb02023-03-15 20:39:421456 bool first_datachannel = !data_channel_controller_.HasUsedDataChannels();
jiayl@webrtc.org001fd2d2014-05-29 15:31:111457
Tommi335d0842023-03-25 09:56:181458 InternalDataChannelInit internal_config;
henrika@webrtc.orgaebb1ad2014-01-14 10:00:581459 if (config) {
Tommi335d0842023-03-25 09:56:181460 internal_config = InternalDataChannelInit(*config);
henrika@webrtc.orgaebb1ad2014-01-14 10:00:581461 }
Tommi335d0842023-03-25 09:56:181462
1463 internal_config.fallback_ssl_role = sdp_handler_->GuessSslRole();
Tommi4f7ade52023-03-29 18:46:591464 RTCErrorOr<rtc::scoped_refptr<DataChannelInterface>> ret =
Taylor Brandstetter3a034e12020-07-09 22:32:341465 data_channel_controller_.InternalCreateDataChannelWithProxy(
Tommi4f7ade52023-03-29 18:46:591466 label, internal_config);
1467 if (!ret.ok()) {
1468 return ret.MoveError();
deadbeefab9b2d12015-10-14 18:33:111469 }
henrike@webrtc.org28e20752013-07-10 00:45:361470
Tommi4f7ade52023-03-29 18:46:591471 rtc::scoped_refptr<DataChannelInterface> channel = ret.MoveValue();
1472
Philipp Hancke522380f2023-05-09 07:41:031473 // Check the onRenegotiationNeeded event (with plan-b backward compat)
1474 if (configuration_.sdp_semantics == SdpSemantics::kUnifiedPlan ||
1475 (configuration_.sdp_semantics == SdpSemantics::kPlanB_DEPRECATED &&
1476 first_datachannel)) {
Harald Alvestrand9cd199d2020-10-27 07:10:431477 sdp_handler_->UpdateNegotiationNeeded();
jiayl@webrtc.org001fd2d2014-05-29 15:31:111478 }
Harald Alvestrand8ebba742018-05-31 12:00:341479 NoteUsageEvent(UsageEvent::DATA_ADDED);
Taylor Brandstetter3a034e12020-07-09 22:32:341480 return channel;
henrike@webrtc.org28e20752013-07-10 00:45:361481}
1482
Henrik Boström79b69802019-07-18 09:16:561483void PeerConnection::RestartIce() {
1484 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand9cd199d2020-10-27 07:10:431485 sdp_handler_->RestartIce();
Henrik Boström79b69802019-07-18 09:16:561486}
1487
henrike@webrtc.org28e20752013-07-10 00:45:361488void PeerConnection::CreateOffer(CreateSessionDescriptionObserver* observer,
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:161489 const RTCOfferAnswerOptions& options) {
Karl Wiberg5966c502019-02-21 22:55:091490 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand9cd199d2020-10-27 07:10:431491 sdp_handler_->CreateOffer(observer, options);
Henrik Boströma3728d32019-10-28 11:09:491492}
1493
Harald Alvestrandcdcfab02020-09-28 13:02:071494void PeerConnection::CreateAnswer(CreateSessionDescriptionObserver* observer,
1495 const RTCOfferAnswerOptions& options) {
Henrik Boströma3728d32019-10-28 11:09:491496 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand9cd199d2020-10-27 07:10:431497 sdp_handler_->CreateAnswer(observer, options);
henrike@webrtc.org28e20752013-07-10 00:45:361498}
1499
henrike@webrtc.org28e20752013-07-10 00:45:361500void PeerConnection::SetLocalDescription(
1501 SetSessionDescriptionObserver* observer,
Steve Anton80dd7b52018-02-17 01:08:421502 SessionDescriptionInterface* desc_ptr) {
Karl Wiberg5966c502019-02-21 22:55:091503 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand9cd199d2020-10-27 07:10:431504 sdp_handler_->SetLocalDescription(observer, desc_ptr);
Henrik Boström831ae4e2020-07-29 10:04:001505}
1506
1507void PeerConnection::SetLocalDescription(
1508 std::unique_ptr<SessionDescriptionInterface> desc,
1509 rtc::scoped_refptr<SetLocalDescriptionObserverInterface> observer) {
1510 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand9cd199d2020-10-27 07:10:431511 sdp_handler_->SetLocalDescription(std::move(desc), observer);
Henrik Boströma3728d32019-10-28 11:09:491512}
Steve Anton8a006912017-12-04 23:25:561513
Henrik Boström4e196702019-10-30 09:35:501514void PeerConnection::SetLocalDescription(
1515 SetSessionDescriptionObserver* observer) {
1516 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand9cd199d2020-10-27 07:10:431517 sdp_handler_->SetLocalDescription(observer);
Henrik Boström831ae4e2020-07-29 10:04:001518}
1519
1520void PeerConnection::SetLocalDescription(
1521 rtc::scoped_refptr<SetLocalDescriptionObserverInterface> observer) {
1522 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand9cd199d2020-10-27 07:10:431523 sdp_handler_->SetLocalDescription(observer);
Henrik Boström4e196702019-10-30 09:35:501524}
1525
henrike@webrtc.org28e20752013-07-10 00:45:361526void PeerConnection::SetRemoteDescription(
Henrik Boströma4ecf552017-11-23 14:17:071527 SetSessionDescriptionObserver* observer,
Henrik Boströma3728d32019-10-28 11:09:491528 SessionDescriptionInterface* desc_ptr) {
1529 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand9cd199d2020-10-27 07:10:431530 sdp_handler_->SetRemoteDescription(observer, desc_ptr);
Henrik Boström31638672017-11-23 16:48:321531}
1532
1533void PeerConnection::SetRemoteDescription(
1534 std::unique_ptr<SessionDescriptionInterface> desc,
1535 rtc::scoped_refptr<SetRemoteDescriptionObserverInterface> observer) {
Karl Wiberg5966c502019-02-21 22:55:091536 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand9cd199d2020-10-27 07:10:431537 sdp_handler_->SetRemoteDescription(std::move(desc), observer);
Henrik Boströmafa07dd2018-12-20 10:06:021538}
1539
deadbeef46c73892016-11-17 03:42:041540PeerConnectionInterface::RTCConfiguration PeerConnection::GetConfiguration() {
Karl Wiberg5966c502019-02-21 22:55:091541 RTC_DCHECK_RUN_ON(signaling_thread());
deadbeef46c73892016-11-17 03:42:041542 return configuration_;
1543}
1544
Niels Möller2579f0c2019-08-19 07:58:171545RTCError PeerConnection::SetConfiguration(
1546 const RTCConfiguration& configuration) {
Karl Wiberg5966c502019-02-21 22:55:091547 RTC_DCHECK_RUN_ON(signaling_thread());
Peter Boström1a9d6152015-12-08 21:15:171548 TRACE_EVENT0("webrtc", "PeerConnection::SetConfiguration");
Steve Antonc79268f2018-04-24 16:54:101549 if (IsClosed()) {
Niels Möller2579f0c2019-08-19 07:58:171550 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_STATE,
1551 "SetConfiguration: PeerConnection is closed.");
Steve Antonc79268f2018-04-24 16:54:101552 }
1553
Tommiaea49c92023-10-22 11:00:141554 const bool has_local_description = local_description() != nullptr;
1555
1556 RTCError validate_error = ValidateIceCandidatePoolSize(
1557 configuration.ice_candidate_pool_size,
1558 has_local_description
1559 ? absl::optional<int>(configuration_.ice_candidate_pool_size)
1560 : absl::nullopt);
1561 if (!validate_error.ok()) {
1562 return validate_error;
buildbot@webrtc.org41451d42014-05-03 05:39:451563 }
Taylor Brandstettera1c30352016-05-13 15:15:111564
Tommiaea49c92023-10-22 11:00:141565 if (has_local_description &&
Benjamin Wright8c27cca2018-10-25 17:16:441566 configuration.crypto_options != configuration_.crypto_options) {
Niels Möller2579f0c2019-08-19 07:58:171567 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_MODIFICATION,
1568 "Can't change crypto_options after calling "
1569 "SetLocalDescription.");
Benjamin Wright8c27cca2018-10-25 17:16:441570 }
1571
Tommiaea49c92023-10-22 11:00:141572 // Create a new, configuration object whose Ice config will have been
1573 // validated..
1574 RTCErrorOr<RTCConfiguration> validated_config =
1575 ApplyConfiguration(configuration, configuration_);
1576 if (!validated_config.ok()) {
1577 return validated_config.error();
deadbeef293e9262017-01-11 20:28:301578 }
1579
1580 // Parse ICE servers before hopping to network thread.
1581 cricket::ServerAddresses stun_servers;
1582 std::vector<cricket::RelayServerConfig> turn_servers;
Tommiaea49c92023-10-22 11:00:141583 validate_error = ParseAndValidateIceServersFromConfiguration(
1584 configuration, stun_servers, turn_servers, usage_pattern_);
1585 if (!validate_error.ok()) {
1586 return validate_error;
deadbeef293e9262017-01-11 20:28:301587 }
Philipp Hancke41a83572022-11-28 13:47:451588
Tommiaea49c92023-10-22 11:00:141589 const RTCConfiguration& modified_config = validated_config.value();
Tomas Gunnarsson20f74562021-02-04 09:22:501590 const bool needs_ice_restart =
1591 modified_config.servers != configuration_.servers ||
1592 NeedIceRestart(
1593 configuration_.surface_ice_candidates_on_ice_transport_type_changed,
1594 configuration_.type, modified_config.type) ||
1595 modified_config.GetTurnPortPrunePolicy() !=
1596 configuration_.GetTurnPortPrunePolicy();
1597 cricket::IceConfig ice_config = ParseIceConfig(modified_config);
1598
1599 // Apply part of the configuration on the network thread. In theory this
1600 // shouldn't fail.
Danil Chapovalov9e09a1f2022-09-08 16:38:101601 if (!network_thread()->BlockingCall(
Tomas Gunnarsson20f74562021-02-04 09:22:501602 [this, needs_ice_restart, &ice_config, &stun_servers, &turn_servers,
1603 &modified_config, has_local_description] {
Harald Alvestrandbc32c562022-02-09 12:08:471604 RTC_DCHECK_RUN_ON(network_thread());
Tomas Gunnarsson20f74562021-02-04 09:22:501605 // As described in JSEP, calling setConfiguration with new ICE
1606 // servers or candidate policy must set a "needs-ice-restart" bit so
1607 // that the next offer triggers an ICE restart which will pick up
1608 // the changes.
1609 if (needs_ice_restart)
1610 transport_controller_->SetNeedsIceRestartFlag();
1611
1612 transport_controller_->SetIceConfig(ice_config);
Tommiaea49c92023-10-22 11:00:141613 transport_controller_->SetActiveResetSrtpParams(
1614 modified_config.active_reset_srtp_params);
Niels Möller4bab23f2021-01-18 08:24:331615 return ReconfigurePortAllocator_n(
1616 stun_servers, turn_servers, modified_config.type,
1617 modified_config.ice_candidate_pool_size,
1618 modified_config.GetTurnPortPrunePolicy(),
1619 modified_config.turn_customizer,
1620 modified_config.stun_candidate_keepalive_interval,
1621 has_local_description);
1622 })) {
Niels Möller2579f0c2019-08-19 07:58:171623 LOG_AND_RETURN_ERROR(RTCErrorType::INTERNAL_ERROR,
1624 "Failed to apply configuration to PortAllocator.");
deadbeef293e9262017-01-11 20:28:301625 }
Honghai Zhang4cedf2b2016-08-31 15:18:111626
deadbeef293e9262017-01-11 20:28:301627 configuration_ = modified_config;
Niels Möller2579f0c2019-08-19 07:58:171628 return RTCError::OK();
buildbot@webrtc.org41451d42014-05-03 05:39:451629}
1630
henrike@webrtc.org28e20752013-07-10 00:45:361631bool PeerConnection::AddIceCandidate(
1632 const IceCandidateInterface* ice_candidate) {
Karl Wiberg744310f2019-02-14 09:18:561633 RTC_DCHECK_RUN_ON(signaling_thread());
Philipp Hanckea09b9212022-06-22 05:41:221634 ClearStatsCache();
Harald Alvestrand9cd199d2020-10-27 07:10:431635 return sdp_handler_->AddIceCandidate(ice_candidate);
henrike@webrtc.org28e20752013-07-10 00:45:361636}
1637
Henrik Boströmee6f4f62019-11-06 11:36:121638void PeerConnection::AddIceCandidate(
1639 std::unique_ptr<IceCandidateInterface> candidate,
1640 std::function<void(RTCError)> callback) {
1641 RTC_DCHECK_RUN_ON(signaling_thread());
Philipp Hanckea09b9212022-06-22 05:41:221642 sdp_handler_->AddIceCandidate(std::move(candidate),
Harald Alvestranda6544372023-11-13 09:33:561643 [this, callback](RTCError result) {
Philipp Hanckea09b9212022-06-22 05:41:221644 ClearStatsCache();
1645 callback(result);
1646 });
Henrik Boströmee6f4f62019-11-06 11:36:121647}
1648
Honghai Zhang7fb69db2016-03-14 18:59:181649bool PeerConnection::RemoveIceCandidates(
1650 const std::vector<cricket::Candidate>& candidates) {
1651 TRACE_EVENT0("webrtc", "PeerConnection::RemoveIceCandidates");
Karl Wiberg2cc368f2019-04-02 09:31:561652 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand9cd199d2020-10-27 07:10:431653 return sdp_handler_->RemoveIceCandidates(candidates);
Honghai Zhang7fb69db2016-03-14 18:59:181654}
1655
Niels Möller0c4f7be2018-05-07 12:01:371656RTCError PeerConnection::SetBitrate(const BitrateSettings& bitrate) {
Steve Anton978b8762017-09-29 19:15:021657 if (!worker_thread()->IsCurrent()) {
Danil Chapovalov9e09a1f2022-09-08 16:38:101658 return worker_thread()->BlockingCall([&]() { return SetBitrate(bitrate); });
zstein4b979802017-06-02 21:37:371659 }
Karl Wiberg6cab5c82019-03-26 08:57:011660 RTC_DCHECK_RUN_ON(worker_thread());
zstein4b979802017-06-02 21:37:371661
Niels Möller0c4f7be2018-05-07 12:01:371662 const bool has_min = bitrate.min_bitrate_bps.has_value();
1663 const bool has_start = bitrate.start_bitrate_bps.has_value();
1664 const bool has_max = bitrate.max_bitrate_bps.has_value();
zstein4b979802017-06-02 21:37:371665 if (has_min && *bitrate.min_bitrate_bps < 0) {
1666 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
1667 "min_bitrate_bps <= 0");
1668 }
Niels Möller0c4f7be2018-05-07 12:01:371669 if (has_start) {
1670 if (has_min && *bitrate.start_bitrate_bps < *bitrate.min_bitrate_bps) {
zstein4b979802017-06-02 21:37:371671 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
Niels Möller0c4f7be2018-05-07 12:01:371672 "start_bitrate_bps < min_bitrate_bps");
1673 } else if (*bitrate.start_bitrate_bps < 0) {
zstein4b979802017-06-02 21:37:371674 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
1675 "curent_bitrate_bps < 0");
1676 }
1677 }
1678 if (has_max) {
Yves Gerey665174f2018-06-19 13:03:051679 if (has_start && *bitrate.max_bitrate_bps < *bitrate.start_bitrate_bps) {
zstein4b979802017-06-02 21:37:371680 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
Niels Möller0c4f7be2018-05-07 12:01:371681 "max_bitrate_bps < start_bitrate_bps");
zstein4b979802017-06-02 21:37:371682 } else if (has_min && *bitrate.max_bitrate_bps < *bitrate.min_bitrate_bps) {
1683 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
1684 "max_bitrate_bps < min_bitrate_bps");
1685 } else if (*bitrate.max_bitrate_bps < 0) {
1686 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
1687 "max_bitrate_bps < 0");
1688 }
1689 }
1690
zstein4b979802017-06-02 21:37:371691 RTC_DCHECK(call_.get());
Piotr (Peter) Slatala7fbfaa42019-03-18 17:31:541692 call_->SetClientBitratePreferences(bitrate);
zstein4b979802017-06-02 21:37:371693
1694 return RTCError::OK();
1695}
1696
henrika5f6bf242017-11-01 10:06:561697void PeerConnection::SetAudioPlayout(bool playout) {
1698 if (!worker_thread()->IsCurrent()) {
Danil Chapovalov9e09a1f2022-09-08 16:38:101699 worker_thread()->BlockingCall(
1700 [this, playout] { SetAudioPlayout(playout); });
henrika5f6bf242017-11-01 10:06:561701 return;
1702 }
Harald Alvestrandc3fa7c32022-05-22 10:57:011703 auto audio_state = context_->media_engine()->voice().GetAudioState();
henrika5f6bf242017-11-01 10:06:561704 audio_state->SetPlayout(playout);
1705}
1706
1707void PeerConnection::SetAudioRecording(bool recording) {
1708 if (!worker_thread()->IsCurrent()) {
Danil Chapovalov9e09a1f2022-09-08 16:38:101709 worker_thread()->BlockingCall(
1710 [this, recording] { SetAudioRecording(recording); });
henrika5f6bf242017-11-01 10:06:561711 return;
1712 }
Harald Alvestrandc3fa7c32022-05-22 10:57:011713 auto audio_state = context_->media_engine()->voice().GetAudioState();
henrika5f6bf242017-11-01 10:06:561714 audio_state->SetRecording(recording);
1715}
1716
Henrik Boström4c1e7cc2020-06-11 10:26:531717void PeerConnection::AddAdaptationResource(
1718 rtc::scoped_refptr<Resource> resource) {
1719 if (!worker_thread()->IsCurrent()) {
Danil Chapovalov9e09a1f2022-09-08 16:38:101720 return worker_thread()->BlockingCall(
1721 [this, resource]() { return AddAdaptationResource(resource); });
Henrik Boström4c1e7cc2020-06-11 10:26:531722 }
1723 RTC_DCHECK_RUN_ON(worker_thread());
1724 if (!call_) {
1725 // The PeerConnection has been closed.
1726 return;
1727 }
1728 call_->AddAdaptationResource(resource);
1729}
1730
Harald Alvestrand35ba0c52022-05-05 07:37:411731bool PeerConnection::ConfiguredForMedia() const {
Harald Alvestrandc3fa7c32022-05-22 10:57:011732 return context_->media_engine();
Harald Alvestrand35ba0c52022-05-05 07:37:411733}
1734
Bjorn Tereliusde939432017-11-20 16:38:141735bool PeerConnection::StartRtcEventLog(std::unique_ptr<RtcEventLogOutput> output,
1736 int64_t output_period_ms) {
Danil Chapovalov9e09a1f2022-09-08 16:38:101737 return worker_thread()->BlockingCall(
Danil Chapovalov116ffe72019-09-05 08:21:111738 [this, output = std::move(output), output_period_ms]() mutable {
1739 return StartRtcEventLog_w(std::move(output), output_period_ms);
1740 });
ivoc14d5dbe2016-07-04 14:06:551741}
1742
Niels Möllerf00ca1a2019-05-10 09:33:121743bool PeerConnection::StartRtcEventLog(
1744 std::unique_ptr<RtcEventLogOutput> output) {
Lionel Koenig0606eaf2023-06-27 08:46:191745 int64_t output_period_ms = 5000;
1746 if (trials().IsDisabled("WebRTC-RtcEventLogNewFormat")) {
Harald Alvestranda6544372023-11-13 09:33:561747 output_period_ms = RtcEventLog::kImmediateOutput;
Niels Möller695cf6a2019-05-13 10:27:231748 }
1749 return StartRtcEventLog(std::move(output), output_period_ms);
Niels Möllerf00ca1a2019-05-10 09:33:121750}
1751
ivoc14d5dbe2016-07-04 14:06:551752void PeerConnection::StopRtcEventLog() {
Danil Chapovalov9e09a1f2022-09-08 16:38:101753 worker_thread()->BlockingCall([this] { StopRtcEventLog_w(); });
ivoc14d5dbe2016-07-04 14:06:551754}
1755
Harald Alvestrandad88c882018-11-28 15:47:461756rtc::scoped_refptr<DtlsTransportInterface>
1757PeerConnection::LookupDtlsTransportByMid(const std::string& mid) {
Tomas Gunnarsson2aeab5e2021-02-23 20:36:141758 RTC_DCHECK_RUN_ON(network_thread());
Harald Alvestrandad88c882018-11-28 15:47:461759 return transport_controller_->LookupDtlsTransportByMid(mid);
1760}
1761
Harald Alvestrand4a7b3ac2019-01-17 09:39:401762rtc::scoped_refptr<DtlsTransport>
1763PeerConnection::LookupDtlsTransportByMidInternal(const std::string& mid) {
Karl Wiberg2cc368f2019-04-02 09:31:561764 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrandbc32c562022-02-09 12:08:471765 // TODO(bugs.webrtc.org/9987): Avoid the thread jump.
1766 // This might be done by caching the value on the signaling thread.
Danil Chapovalov9e09a1f2022-09-08 16:38:101767 return network_thread()->BlockingCall([this, mid]() {
1768 RTC_DCHECK_RUN_ON(network_thread());
1769 return transport_controller_->LookupDtlsTransportByMid(mid);
1770 });
Harald Alvestrand4a7b3ac2019-01-17 09:39:401771}
1772
Harald Alvestrandc85328f2019-02-28 06:51:001773rtc::scoped_refptr<SctpTransportInterface> PeerConnection::GetSctpTransport()
1774 const {
Tomas Gunnarsson92eebef2021-02-10 12:05:441775 RTC_DCHECK_RUN_ON(network_thread());
1776 if (!sctp_mid_n_)
Bjorn A Mellembc3eebc2019-09-23 21:53:541777 return nullptr;
Tomas Gunnarsson92eebef2021-02-10 12:05:441778
1779 return transport_controller_->GetSctpTransport(*sctp_mid_n_);
Harald Alvestrandc85328f2019-02-28 06:51:001780}
1781
henrike@webrtc.org28e20752013-07-10 00:45:361782const SessionDescriptionInterface* PeerConnection::local_description() const {
Karl Wiberg739506e2019-04-03 09:37:281783 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand9cd199d2020-10-27 07:10:431784 return sdp_handler_->local_description();
henrike@webrtc.org28e20752013-07-10 00:45:361785}
1786
1787const SessionDescriptionInterface* PeerConnection::remote_description() const {
Karl Wiberg739506e2019-04-03 09:37:281788 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand9cd199d2020-10-27 07:10:431789 return sdp_handler_->remote_description();
henrike@webrtc.org28e20752013-07-10 00:45:361790}
1791
deadbeeffe4a8a42016-12-21 01:56:171792const SessionDescriptionInterface* PeerConnection::current_local_description()
1793 const {
Karl Wiberg739506e2019-04-03 09:37:281794 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand9cd199d2020-10-27 07:10:431795 return sdp_handler_->current_local_description();
deadbeeffe4a8a42016-12-21 01:56:171796}
1797
1798const SessionDescriptionInterface* PeerConnection::current_remote_description()
1799 const {
Karl Wiberg739506e2019-04-03 09:37:281800 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand9cd199d2020-10-27 07:10:431801 return sdp_handler_->current_remote_description();
deadbeeffe4a8a42016-12-21 01:56:171802}
1803
1804const SessionDescriptionInterface* PeerConnection::pending_local_description()
1805 const {
Karl Wiberg739506e2019-04-03 09:37:281806 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand9cd199d2020-10-27 07:10:431807 return sdp_handler_->pending_local_description();
deadbeeffe4a8a42016-12-21 01:56:171808}
1809
1810const SessionDescriptionInterface* PeerConnection::pending_remote_description()
1811 const {
Karl Wiberg739506e2019-04-03 09:37:281812 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand9cd199d2020-10-27 07:10:431813 return sdp_handler_->pending_remote_description();
deadbeeffe4a8a42016-12-21 01:56:171814}
1815
henrike@webrtc.org28e20752013-07-10 00:45:361816void PeerConnection::Close() {
Karl Wiberg744310f2019-02-14 09:18:561817 RTC_DCHECK_RUN_ON(signaling_thread());
Peter Boström1a9d6152015-12-08 21:15:171818 TRACE_EVENT0("webrtc", "PeerConnection::Close");
Harald Alvestrandcdcfab02020-09-28 13:02:071819
Tommife041642021-04-07 08:08:281820 RTC_LOG_THREAD_BLOCK_COUNT();
1821
Harald Alvestrandcdcfab02020-09-28 13:02:071822 if (IsClosed()) {
1823 return;
1824 }
henrike@webrtc.org28e20752013-07-10 00:45:361825 // Update stats here so that we have the most recent stats for tracks and
1826 // streams before the channels are closed.
Henrik Boströmf7859892022-07-04 12:36:371827 legacy_stats_->UpdateStats(kStatsOutputLevelStandard);
henrike@webrtc.org28e20752013-07-10 00:45:361828
Harald Alvestrandcdcfab02020-09-28 13:02:071829 ice_connection_state_ = PeerConnectionInterface::kIceConnectionClosed;
1830 Observer()->OnIceConnectionChange(ice_connection_state_);
1831 standardized_ice_connection_state_ =
1832 PeerConnectionInterface::IceConnectionState::kIceConnectionClosed;
1833 connection_state_ = PeerConnectionInterface::PeerConnectionState::kClosed;
1834 Observer()->OnConnectionChange(connection_state_);
1835
Harald Alvestrand9cd199d2020-10-27 07:10:431836 sdp_handler_->Close();
Harald Alvestrandcdcfab02020-09-28 13:02:071837
Harald Alvestrand8ebba742018-05-31 12:00:341838 NoteUsageEvent(UsageEvent::CLOSE_CALLED);
Steve Anton3fe1b152017-12-12 18:20:081839
Harald Alvestrand8101e7b2022-05-23 14:57:471840 if (ConfiguredForMedia()) {
1841 for (const auto& transceiver : rtp_manager()->transceivers()->List()) {
1842 transceiver->internal()->SetPeerConnectionClosed();
1843 if (!transceiver->stopped())
1844 transceiver->StopInternal();
1845 }
Steve Anton8af21862017-12-15 19:20:131846 }
Steve Anton25cfeb92018-04-26 18:44:001847 // Ensure that all asynchronous stats requests are completed before destroying
1848 // the transport controller below.
1849 if (stats_collector_) {
1850 stats_collector_->WaitForPendingRequest();
1851 }
1852
1853 // Don't destroy BaseChannels until after stats has been cleaned up so that
1854 // the last stats request can still read from the channels.
Tommi29190752023-10-21 14:50:091855 // TODO(tommi): The voice/video channels will be partially uninitialized on
1856 // the network thread (see `RtpTransceiver::ClearChannel`), partially on the
1857 // worker thread (see `PushNewMediaChannelAndDeleteChannel`) and then
1858 // eventually freed on the signaling thread.
1859 // It would be good to combine those steps with the teardown steps here.
1860 sdp_handler_->DestroyMediaChannels();
Steve Anton75737c02017-11-06 18:37:171861
Qingsi Wang93a84392018-01-31 01:13:091862 // The event log is used in the transport controller, which must be outlived
1863 // by the former. CreateOffer by the peer connection is implemented
1864 // asynchronously and if the peer connection is closed without resetting the
1865 // WebRTC session description factory, the session description factory would
1866 // call the transport controller.
Harald Alvestrand9cd199d2020-10-27 07:10:431867 sdp_handler_->ResetSessionDescFactory();
Harald Alvestrand8101e7b2022-05-23 14:57:471868 if (ConfiguredForMedia()) {
1869 rtp_manager_->Close();
1870 }
Qingsi Wang93a84392018-01-31 01:13:091871
Danil Chapovalov9e09a1f2022-09-08 16:38:101872 network_thread()->BlockingCall([this] {
Harald Alvestrandbc32c562022-02-09 12:08:471873 RTC_DCHECK_RUN_ON(network_thread());
Tommi29190752023-10-21 14:50:091874 TeardownDataChannelTransport_n({});
Tomas Gunnarsson92eebef2021-02-10 12:05:441875 transport_controller_.reset();
1876 port_allocator_->DiscardCandidatePool();
1877 if (network_thread_safety_) {
1878 network_thread_safety_->SetNotAlive();
Tomas Gunnarsson92eebef2021-02-10 12:05:441879 }
1880 });
nisseeaabdf62017-05-05 09:23:021881
Tommi29190752023-10-21 14:50:091882 sctp_mid_s_.reset();
1883 SetSctpTransportName("");
1884
Danil Chapovalov9e09a1f2022-09-08 16:38:101885 worker_thread()->BlockingCall([this] {
Karl Wibergb03ab712019-02-14 10:59:571886 RTC_DCHECK_RUN_ON(worker_thread());
Tommic3257d02021-02-10 17:40:081887 worker_thread_safety_->SetNotAlive();
eladalon248fd4f2017-09-06 12:18:151888 call_.reset();
Danil Chapovalov49c35d32023-11-27 11:55:391889 StopRtcEventLog_w();
eladalon248fd4f2017-09-06 12:18:151890 });
Harald Alvestrand8ebba742018-05-31 12:00:341891 ReportUsagePattern();
Tomas Gunnarsson2efb8a52021-04-01 14:26:571892
1893 // Signal shutdown to the sdp handler. This invalidates weak pointers for
1894 // internal pending callbacks.
1895 sdp_handler_->PrepareForShutdown();
Tommi1f708ef2023-03-31 16:40:501896 data_channel_controller_.PrepareForShutdown();
1897
1898 // The .h file says that observer can be discarded after close() returns.
1899 // Make sure this is true.
1900 observer_ = nullptr;
henrike@webrtc.org28e20752013-07-10 00:45:361901}
1902
Steve Antonba818672017-11-06 18:21:571903void PeerConnection::SetIceConnectionState(IceConnectionState new_state) {
Harald Alvestrandcdcfab02020-09-28 13:02:071904 RTC_DCHECK_RUN_ON(signaling_thread());
Steve Antonba818672017-11-06 18:21:571905 if (ice_connection_state_ == new_state) {
1906 return;
1907 }
1908
deadbeefcbecd352015-09-23 18:50:271909 // After transitioning to "closed", ignore any additional states from
Steve Antonba818672017-11-06 18:21:571910 // TransportController (such as "disconnected").
deadbeefab9b2d12015-10-14 18:33:111911 if (IsClosed()) {
deadbeefcbecd352015-09-23 18:50:271912 return;
1913 }
Steve Antonba818672017-11-06 18:21:571914
Mirko Bonadei675513b2017-11-09 10:09:251915 RTC_LOG(LS_INFO) << "Changing IceConnectionState " << ice_connection_state_
1916 << " => " << new_state;
Steve Antonba818672017-11-06 18:21:571917 RTC_DCHECK(ice_connection_state_ !=
1918 PeerConnectionInterface::kIceConnectionClosed);
1919
henrike@webrtc.org28e20752013-07-10 00:45:361920 ice_connection_state_ = new_state;
Harald Alvestrand7a1c7f72018-08-01 08:50:161921 Observer()->OnIceConnectionChange(ice_connection_state_);
henrike@webrtc.org28e20752013-07-10 00:45:361922}
1923
Alex Loiko9289eda2018-11-23 16:18:591924void PeerConnection::SetStandardizedIceConnectionState(
1925 PeerConnectionInterface::IceConnectionState new_state) {
Qingsi Wang36e31472019-05-29 18:37:261926 if (standardized_ice_connection_state_ == new_state) {
Alex Loiko9289eda2018-11-23 16:18:591927 return;
Qingsi Wang36e31472019-05-29 18:37:261928 }
1929
1930 if (IsClosed()) {
Alex Loiko9289eda2018-11-23 16:18:591931 return;
Qingsi Wang36e31472019-05-29 18:37:261932 }
1933
1934 RTC_LOG(LS_INFO) << "Changing standardized IceConnectionState "
1935 << standardized_ice_connection_state_ << " => " << new_state;
1936
Alex Loiko9289eda2018-11-23 16:18:591937 standardized_ice_connection_state_ = new_state;
Jonas Olsson12046902018-12-06 10:25:141938 Observer()->OnStandardizedIceConnectionChange(new_state);
Alex Loiko9289eda2018-11-23 16:18:591939}
1940
Jonas Olsson635474e2018-10-18 13:58:171941void PeerConnection::SetConnectionState(
1942 PeerConnectionInterface::PeerConnectionState new_state) {
Jonas Olsson635474e2018-10-18 13:58:171943 if (connection_state_ == new_state)
1944 return;
1945 if (IsClosed())
1946 return;
1947 connection_state_ = new_state;
1948 Observer()->OnConnectionChange(new_state);
Philipp Hanckebb8f32f2021-02-04 20:50:501949
Philipp Hancke9799fe02022-07-06 07:26:411950 // The first connection state change to connected happens once per
1951 // connection which makes it a good point to report metrics.
Philipp Hanckecd0373f2021-02-24 10:04:301952 if (new_state == PeerConnectionState::kConnected && !was_ever_connected_) {
1953 was_ever_connected_ = true;
Philipp Hancke9799fe02022-07-06 07:26:411954 ReportFirstConnectUsageMetrics();
Philipp Hanckebb8f32f2021-02-04 20:50:501955 }
Jonas Olsson635474e2018-10-18 13:58:171956}
1957
Philipp Hancke9799fe02022-07-06 07:26:411958void PeerConnection::ReportFirstConnectUsageMetrics() {
1959 // Record bundle-policy from configuration. Done here from
1960 // connectionStateChange to limit to actually established connections.
1961 BundlePolicyUsage policy = kBundlePolicyUsageMax;
1962 switch (configuration_.bundle_policy) {
1963 case kBundlePolicyBalanced:
1964 policy = kBundlePolicyUsageBalanced;
1965 break;
1966 case kBundlePolicyMaxBundle:
1967 policy = kBundlePolicyUsageMaxBundle;
1968 break;
1969 case kBundlePolicyMaxCompat:
1970 policy = kBundlePolicyUsageMaxCompat;
1971 break;
1972 }
1973 RTC_HISTOGRAM_ENUMERATION("WebRTC.PeerConnection.BundlePolicy", policy,
1974 kBundlePolicyUsageMax);
1975
Philipp Hancke9799fe02022-07-06 07:26:411976 // Record whether there was a local or remote provisional answer.
1977 ProvisionalAnswerUsage pranswer = kProvisionalAnswerNotUsed;
1978 if (local_description()->GetType() == SdpType::kPrAnswer) {
1979 pranswer = kProvisionalAnswerLocal;
1980 } else if (remote_description()->GetType() == SdpType::kPrAnswer) {
1981 pranswer = kProvisionalAnswerRemote;
1982 }
1983 RTC_HISTOGRAM_ENUMERATION("WebRTC.PeerConnection.ProvisionalAnswer", pranswer,
1984 kProvisionalAnswerMax);
1985
Philipp Hancke6f22eb52022-07-14 09:38:441986 auto transport_infos = remote_description()->description()->transport_infos();
Philipp Hancke09672472023-11-15 14:23:061987 if (!transport_infos.empty()) {
1988 // Record the number of valid / invalid ice-ufrag. We do allow certain
1989 // non-spec ice-char for backward-compat reasons. At this point we know
1990 // that the ufrag/pwd consists of a valid ice-char or one of the four
1991 // not allowed characters since we have passed the IsIceChar check done
1992 // by the p2p transport description on setRemoteDescription calls.
Philipp Hancke6f22eb52022-07-14 09:38:441993 auto ice_parameters = transport_infos[0].description.GetIceParameters();
1994 auto is_invalid_char = [](char c) {
1995 return c == '-' || c == '=' || c == '#' || c == '_';
1996 };
1997 bool isUsingInvalidIceCharInUfrag =
1998 absl::c_any_of(ice_parameters.ufrag, is_invalid_char);
1999 bool isUsingInvalidIceCharInPwd =
2000 absl::c_any_of(ice_parameters.pwd, is_invalid_char);
2001 RTC_HISTOGRAM_BOOLEAN(
2002 "WebRTC.PeerConnection.ValidIceChars",
2003 !(isUsingInvalidIceCharInUfrag || isUsingInvalidIceCharInPwd));
Philipp Hancke09672472023-11-15 14:23:062004
2005 // Record whether the hash algorithm of the first transport's
2006 // DTLS fingerprint is still using SHA-1.
2007 if (transport_infos[0].description.identity_fingerprint) {
2008 RTC_HISTOGRAM_BOOLEAN(
2009 "WebRTC.PeerConnection.DtlsFingerprintLegacySha1",
2010 absl::EqualsIgnoreCase(
2011 transport_infos[0].description.identity_fingerprint->algorithm,
2012 "sha-1"));
2013 }
Philipp Hancke6f22eb52022-07-14 09:38:442014 }
Philipp Hancke66efab22023-01-25 10:37:452015
2016 // Record RtcpMuxPolicy setting.
2017 RtcpMuxPolicyUsage rtcp_mux_policy = kRtcpMuxPolicyUsageMax;
2018 switch (configuration_.rtcp_mux_policy) {
2019 case kRtcpMuxPolicyNegotiate:
2020 rtcp_mux_policy = kRtcpMuxPolicyUsageNegotiate;
2021 break;
2022 case kRtcpMuxPolicyRequire:
2023 rtcp_mux_policy = kRtcpMuxPolicyUsageRequire;
2024 break;
2025 }
2026 RTC_HISTOGRAM_ENUMERATION("WebRTC.PeerConnection.RtcpMuxPolicy",
2027 rtcp_mux_policy, kRtcpMuxPolicyUsageMax);
Philipp Hancke9799fe02022-07-06 07:26:412028}
2029
henrike@webrtc.org28e20752013-07-10 00:45:362030void PeerConnection::OnIceGatheringChange(
2031 PeerConnectionInterface::IceGatheringState new_state) {
2032 if (IsClosed()) {
2033 return;
2034 }
2035 ice_gathering_state_ = new_state;
Harald Alvestrand7a1c7f72018-08-01 08:50:162036 Observer()->OnIceGatheringChange(ice_gathering_state_);
henrike@webrtc.org28e20752013-07-10 00:45:362037}
2038
jbauch81bf7b02017-03-25 15:31:122039void PeerConnection::OnIceCandidate(
2040 std::unique_ptr<IceCandidateInterface> candidate) {
zhihuang29ff8442016-07-27 18:07:252041 if (IsClosed()) {
2042 return;
2043 }
Qingsi Wang1ba5dec2019-08-19 18:57:172044 ReportIceCandidateCollected(candidate->candidate());
Philipp Hancke1fe14f22022-06-17 09:34:312045 ClearStatsCache();
Harald Alvestrand7a1c7f72018-08-01 08:50:162046 Observer()->OnIceCandidate(candidate.get());
henrike@webrtc.org28e20752013-07-10 00:45:362047}
2048
Eldar Rello0095d372019-12-02 20:22:072049void PeerConnection::OnIceCandidateError(const std::string& address,
2050 int port,
Eldar Relloda13ea22019-06-01 09:23:432051 const std::string& url,
2052 int error_code,
2053 const std::string& error_text) {
2054 if (IsClosed()) {
2055 return;
2056 }
Eldar Rello0095d372019-12-02 20:22:072057 Observer()->OnIceCandidateError(address, port, url, error_code, error_text);
Eldar Relloda13ea22019-06-01 09:23:432058}
2059
Honghai Zhang7fb69db2016-03-14 18:59:182060void PeerConnection::OnIceCandidatesRemoved(
2061 const std::vector<cricket::Candidate>& candidates) {
zhihuang29ff8442016-07-27 18:07:252062 if (IsClosed()) {
2063 return;
2064 }
Harald Alvestrand7a1c7f72018-08-01 08:50:162065 Observer()->OnIceCandidatesRemoved(candidates);
Honghai Zhang7fb69db2016-03-14 18:59:182066}
2067
Alex Drake00c7ecf2019-08-06 17:54:472068void PeerConnection::OnSelectedCandidatePairChanged(
2069 const cricket::CandidatePairChangeEvent& event) {
2070 if (IsClosed()) {
2071 return;
2072 }
Qingsi Wang1ba5dec2019-08-19 18:57:172073
Tommi3b2b2af2024-01-17 13:19:412074 if (event.selected_candidate_pair.local_candidate().is_local() &&
2075 event.selected_candidate_pair.remote_candidate().is_local()) {
Qingsi Wangcc46b10c2019-09-12 18:19:012076 NoteUsageEvent(UsageEvent::DIRECT_CONNECTION_SELECTED);
2077 }
2078
Alex Drake00c7ecf2019-08-06 17:54:472079 Observer()->OnIceSelectedCandidatePairChanged(event);
2080}
2081
Tommi840cf782023-10-21 14:47:562082bool PeerConnection::CreateDataChannelTransport(absl::string_view mid) {
Harald Alvestrandcdcfab02020-09-28 13:02:072083 RTC_DCHECK_RUN_ON(signaling_thread());
Tommi840cf782023-10-21 14:47:562084 RTC_DCHECK(!sctp_mid().has_value() || mid == sctp_mid().value());
2085 RTC_LOG(LS_INFO) << "Creating data channel, mid=" << mid;
Steve Antonfa2260d2017-12-29 00:38:232086
Tommi840cf782023-10-21 14:47:562087 absl::optional<std::string> transport_name =
2088 network_thread()->BlockingCall([&] {
2089 RTC_DCHECK_RUN_ON(network_thread());
2090 return SetupDataChannelTransport_n(mid);
2091 });
2092 if (!transport_name)
2093 return false;
2094
Tommiaa3c9f22023-04-18 10:19:192095 sctp_mid_s_ = std::string(mid);
Tommi840cf782023-10-21 14:47:562096 SetSctpTransportName(transport_name.value());
2097
2098 return true;
Tomas Gunnarsson92eebef2021-02-10 12:05:442099}
2100
Tommi840cf782023-10-21 14:47:562101void PeerConnection::DestroyDataChannelTransport(RTCError error) {
Tomas Gunnarsson92eebef2021-02-10 12:05:442102 RTC_DCHECK_RUN_ON(signaling_thread());
Tommi840cf782023-10-21 14:47:562103 network_thread()->BlockingCall([&] {
2104 RTC_DCHECK_RUN_ON(network_thread());
2105 TeardownDataChannelTransport_n(error);
2106 });
Tomas Gunnarsson92eebef2021-02-10 12:05:442107 sctp_mid_s_.reset();
Henrik Boström46053e42023-01-20 12:18:532108 SetSctpTransportName("");
Tomas Gunnarsson92eebef2021-02-10 12:05:442109}
2110
Tommid2afbaf2023-03-02 09:51:162111void PeerConnection::OnSctpDataChannelStateChanged(
Tommi56548982023-03-27 16:07:342112 int channel_id,
Tommid2afbaf2023-03-02 09:51:162113 DataChannelInterface::DataState state) {
2114 RTC_DCHECK_RUN_ON(signaling_thread());
2115 if (stats_collector_)
Tommi56548982023-03-27 16:07:342116 stats_collector_->OnSctpDataChannelStateChanged(channel_id, state);
deadbeefab9b2d12015-10-14 18:33:112117}
2118
Karl Wibergfb3be392019-03-22 13:13:222119PeerConnection::InitializePortAllocatorResult
2120PeerConnection::InitializePortAllocator_n(
Harald Alvestrandb2a74782018-06-28 11:54:072121 const cricket::ServerAddresses& stun_servers,
2122 const std::vector<cricket::RelayServerConfig>& turn_servers,
Taylor Brandstettera1c30352016-05-13 15:15:112123 const RTCConfiguration& configuration) {
Karl Wibergfb3be392019-03-22 13:13:222124 RTC_DCHECK_RUN_ON(network_thread());
2125
Taylor Brandstetterf8e65772016-06-28 00:20:152126 port_allocator_->Initialize();
Taylor Brandstettera1c30352016-05-13 15:15:112127 // To handle both internal and externally created port allocator, we will
2128 // enable BUNDLE here.
Karl Wibergfb3be392019-03-22 13:13:222129 int port_allocator_flags = port_allocator_->flags();
2130 port_allocator_flags |= cricket::PORTALLOCATOR_ENABLE_SHARED_SOCKET |
2131 cricket::PORTALLOCATOR_ENABLE_IPV6 |
2132 cricket::PORTALLOCATOR_ENABLE_IPV6_ON_WIFI;
Henrik Boströma445e6a2022-12-01 09:25:122133 if (trials().IsDisabled("WebRTC-IPv6Default")) {
Karl Wibergfb3be392019-03-22 13:13:222134 port_allocator_flags &= ~(cricket::PORTALLOCATOR_ENABLE_IPV6);
Taylor Brandstettera1c30352016-05-13 15:15:112135 }
zhihuangb09b3f92017-03-07 22:40:512136 if (configuration.disable_ipv6_on_wifi) {
Karl Wibergfb3be392019-03-22 13:13:222137 port_allocator_flags &= ~(cricket::PORTALLOCATOR_ENABLE_IPV6_ON_WIFI);
Mirko Bonadei675513b2017-11-09 10:09:252138 RTC_LOG(LS_INFO) << "IPv6 candidates on Wi-Fi are disabled.";
zhihuangb09b3f92017-03-07 22:40:512139 }
2140
Taylor Brandstettera1c30352016-05-13 15:15:112141 if (configuration.tcp_candidate_policy == kTcpCandidatePolicyDisabled) {
Karl Wibergfb3be392019-03-22 13:13:222142 port_allocator_flags |= cricket::PORTALLOCATOR_DISABLE_TCP;
Mirko Bonadei675513b2017-11-09 10:09:252143 RTC_LOG(LS_INFO) << "TCP candidates are disabled.";
Taylor Brandstettera1c30352016-05-13 15:15:112144 }
2145
honghaiz60347052016-06-01 01:29:122146 if (configuration.candidate_network_policy ==
2147 kCandidateNetworkPolicyLowCost) {
Karl Wibergfb3be392019-03-22 13:13:222148 port_allocator_flags |= cricket::PORTALLOCATOR_DISABLE_COSTLY_NETWORKS;
Mirko Bonadei675513b2017-11-09 10:09:252149 RTC_LOG(LS_INFO) << "Do not gather candidates on high-cost networks";
honghaiz60347052016-06-01 01:29:122150 }
2151
Daniel Lazarenko2870b0a2018-01-25 09:30:222152 if (configuration.disable_link_local_networks) {
Karl Wibergfb3be392019-03-22 13:13:222153 port_allocator_flags |= cricket::PORTALLOCATOR_DISABLE_LINK_LOCAL_NETWORKS;
Daniel Lazarenko2870b0a2018-01-25 09:30:222154 RTC_LOG(LS_INFO) << "Disable candidates on link-local network interfaces.";
2155 }
2156
Karl Wibergfb3be392019-03-22 13:13:222157 port_allocator_->set_flags(port_allocator_flags);
Taylor Brandstettera1c30352016-05-13 15:15:112158 // No step delay is used while allocating ports.
2159 port_allocator_->set_step_delay(cricket::kMinimumStepDelay);
Qingsi Wangc129c352019-04-18 17:41:582160 port_allocator_->SetCandidateFilter(
Taylor Brandstettera1c30352016-05-13 15:15:112161 ConvertIceTransportTypeToCandidateFilter(configuration.type));
deadbeefd21eab3e2017-07-26 23:50:112162 port_allocator_->set_max_ipv6_networks(configuration.max_ipv6_networks);
Taylor Brandstettera1c30352016-05-13 15:15:112163
Harald Alvestrandb2a74782018-06-28 11:54:072164 auto turn_servers_copy = turn_servers;
Benjamin Wright6f80f092018-08-14 00:06:262165 for (auto& turn_server : turn_servers_copy) {
2166 turn_server.tls_cert_verifier = tls_cert_verifier_.get();
Benjamin Wrightd6f86e82018-05-08 20:12:252167 }
Taylor Brandstettera1c30352016-05-13 15:15:112168 // Call this last since it may create pooled allocator sessions using the
2169 // properties set above.
Qingsi Wangdb53f8e2018-02-20 22:45:492170 port_allocator_->SetConfiguration(
Benjamin Wright6f80f092018-08-14 00:06:262171 stun_servers, std::move(turn_servers_copy),
Honghai Zhangf8998cf2019-10-14 18:27:502172 configuration.ice_candidate_pool_size,
2173 configuration.GetTurnPortPrunePolicy(), configuration.turn_customizer,
Qingsi Wangdb53f8e2018-02-20 22:45:492174 configuration.stun_candidate_keepalive_interval);
Karl Wibergfb3be392019-03-22 13:13:222175
2176 InitializePortAllocatorResult res;
2177 res.enable_ipv6 = port_allocator_flags & cricket::PORTALLOCATOR_ENABLE_IPV6;
2178 return res;
Taylor Brandstettera1c30352016-05-13 15:15:112179}
2180
deadbeef91dd5672016-05-18 23:55:302181bool PeerConnection::ReconfigurePortAllocator_n(
deadbeef293e9262017-01-11 20:28:302182 const cricket::ServerAddresses& stun_servers,
2183 const std::vector<cricket::RelayServerConfig>& turn_servers,
2184 IceTransportsType type,
2185 int candidate_pool_size,
Honghai Zhangf8998cf2019-10-14 18:27:502186 PortPrunePolicy turn_port_prune_policy,
Harald Alvestranda6544372023-11-13 09:33:562187 TurnCustomizer* turn_customizer,
Karl Wiberg739506e2019-04-03 09:37:282188 absl::optional<int> stun_candidate_keepalive_interval,
2189 bool have_local_description) {
Harald Alvestrandf598e492020-11-04 05:54:102190 RTC_DCHECK_RUN_ON(network_thread());
Qingsi Wangc129c352019-04-18 17:41:582191 port_allocator_->SetCandidateFilter(
deadbeef293e9262017-01-11 20:28:302192 ConvertIceTransportTypeToCandidateFilter(type));
Benjamin Wright6f80f092018-08-14 00:06:262193 // Add the custom tls turn servers if they exist.
2194 auto turn_servers_copy = turn_servers;
2195 for (auto& turn_server : turn_servers_copy) {
2196 turn_server.tls_cert_verifier = tls_cert_verifier_.get();
2197 }
Taylor Brandstettera1c30352016-05-13 15:15:112198 // Call this last since it may create pooled allocator sessions using the
2199 // candidate filter set above.
deadbeef6de92f92016-12-13 02:49:322200 return port_allocator_->SetConfiguration(
Benjamin Wright6f80f092018-08-14 00:06:262201 stun_servers, std::move(turn_servers_copy), candidate_pool_size,
Honghai Zhangf8998cf2019-10-14 18:27:502202 turn_port_prune_policy, turn_customizer,
2203 stun_candidate_keepalive_interval);
Taylor Brandstettera1c30352016-05-13 15:15:112204}
2205
Elad Alon99c3fe52017-10-13 14:29:402206bool PeerConnection::StartRtcEventLog_w(
Bjorn Tereliusde939432017-11-20 16:38:142207 std::unique_ptr<RtcEventLogOutput> output,
2208 int64_t output_period_ms) {
Karl Wibergb03ab712019-02-14 10:59:572209 RTC_DCHECK_RUN_ON(worker_thread());
Danil Chapovalov49c35d32023-11-27 11:55:392210 if (!worker_thread_safety_->alive()) {
zhihuang77985012017-02-07 23:45:162211 return false;
2212 }
Danil Chapovalov3bdb49b2023-11-30 07:59:392213 return env_.event_log().StartLogging(std::move(output), output_period_ms);
ivoc14d5dbe2016-07-04 14:06:552214}
2215
2216void PeerConnection::StopRtcEventLog_w() {
Karl Wibergb03ab712019-02-14 10:59:572217 RTC_DCHECK_RUN_ON(worker_thread());
Danil Chapovalov3bdb49b2023-11-30 07:59:392218 env_.event_log().StopLogging();
ivoc14d5dbe2016-07-04 14:06:552219}
nisseeaabdf62017-05-05 09:23:022220
Tommi335d0842023-03-25 09:56:182221absl::optional<rtc::SSLRole> PeerConnection::GetSctpSslRole_n() {
Tommic61eee22023-03-22 07:25:382222 RTC_DCHECK_RUN_ON(network_thread());
Tommi335d0842023-03-25 09:56:182223 return sctp_mid_n_ ? transport_controller_->GetDtlsRole(*sctp_mid_n_)
2224 : absl::nullopt;
Steve Anton75737c02017-11-06 18:37:172225}
2226
2227bool PeerConnection::GetSslRole(const std::string& content_name,
2228 rtc::SSLRole* role) {
Karl Wiberg2cc368f2019-04-02 09:31:562229 RTC_DCHECK_RUN_ON(signaling_thread());
Steve Anton75737c02017-11-06 18:37:172230 if (!local_description() || !remote_description()) {
Mirko Bonadei675513b2017-11-09 10:09:252231 RTC_LOG(LS_INFO)
2232 << "Local and Remote descriptions must be applied to get the "
Jonas Olsson45cc8902018-02-13 09:37:072233 "SSL Role of the session.";
Steve Anton75737c02017-11-06 18:37:172234 return false;
2235 }
2236
Danil Chapovalov9e09a1f2022-09-08 16:38:102237 auto dtls_role = network_thread()->BlockingCall([this, content_name]() {
2238 RTC_DCHECK_RUN_ON(network_thread());
2239 return transport_controller_->GetDtlsRole(content_name);
2240 });
Zhi Huange830e682018-03-30 17:48:352241 if (dtls_role) {
2242 *role = *dtls_role;
2243 return true;
2244 }
2245 return false;
Steve Anton75737c02017-11-06 18:37:172246}
2247
Steve Anton75737c02017-11-06 18:37:172248bool PeerConnection::GetTransportDescription(
2249 const SessionDescription* description,
2250 const std::string& content_name,
2251 cricket::TransportDescription* tdesc) {
2252 if (!description || !tdesc) {
2253 return false;
2254 }
2255 const TransportInfo* transport_info =
2256 description->GetTransportInfoByName(content_name);
2257 if (!transport_info) {
2258 return false;
2259 }
2260 *tdesc = transport_info->description;
2261 return true;
2262}
2263
Taylor Brandstetter3a034e12020-07-09 22:32:342264std::vector<DataChannelStats> PeerConnection::GetDataChannelStats() const {
Tommif9e13f82023-04-06 19:21:452265 RTC_DCHECK_RUN_ON(network_thread());
Tomas Gunnarsson2e94de52020-06-16 14:54:102266 return data_channel_controller_.GetDataChannelStats();
2267}
2268
Danil Chapovalov66cadcc2018-06-19 14:47:432269absl::optional<std::string> PeerConnection::sctp_transport_name() const {
Karl Wiberg2cc368f2019-04-02 09:31:562270 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrandbc32c562022-02-09 12:08:472271 if (sctp_mid_s_ && transport_controller_copy_)
Tomas Gunnarsson92eebef2021-02-10 12:05:442272 return sctp_transport_name_s_;
Danil Chapovalov66cadcc2018-06-19 14:47:432273 return absl::optional<std::string>();
Zhi Huange830e682018-03-30 17:48:352274}
2275
Henrik Boström46053e42023-01-20 12:18:532276void PeerConnection::SetSctpTransportName(std::string sctp_transport_name) {
2277 RTC_DCHECK_RUN_ON(signaling_thread());
2278 sctp_transport_name_s_ = std::move(sctp_transport_name);
2279 ClearStatsCache();
2280}
2281
Tomas Gunnarssonbfd9ba82021-04-18 09:55:572282absl::optional<std::string> PeerConnection::sctp_mid() const {
2283 RTC_DCHECK_RUN_ON(signaling_thread());
2284 return sctp_mid_s_;
2285}
2286
Qingsi Wang72a43a12018-02-21 00:03:182287cricket::CandidateStatsList PeerConnection::GetPooledCandidateStats() const {
Tomas Gunnarssone1c8a432021-04-08 13:15:282288 RTC_DCHECK_RUN_ON(network_thread());
2289 if (!network_thread_safety_->alive())
2290 return {};
Philipp Hancke6e57ca22022-06-09 13:58:182291 cricket::CandidateStatsList candidate_stats_list;
2292 port_allocator_->GetCandidateStatsFromPooledSessions(&candidate_stats_list);
2293 return candidate_stats_list;
Qingsi Wang72a43a12018-02-21 00:03:182294}
2295
Steve Anton5dfde182018-02-06 18:34:402296std::map<std::string, cricket::TransportStats>
2297PeerConnection::GetTransportStatsByNames(
2298 const std::set<std::string>& transport_names) {
Markus Handell518669d2021-06-07 11:30:462299 TRACE_EVENT0("webrtc", "PeerConnection::GetTransportStatsByNames");
Karl Wiberg2cc368f2019-04-02 09:31:562300 RTC_DCHECK_RUN_ON(network_thread());
Tomas Gunnarssone1c8a432021-04-08 13:15:282301 if (!network_thread_safety_->alive())
2302 return {};
2303
2304 rtc::Thread::ScopedDisallowBlockingCalls no_blocking_calls;
Steve Anton5dfde182018-02-06 18:34:402305 std::map<std::string, cricket::TransportStats> transport_stats_by_name;
2306 for (const std::string& transport_name : transport_names) {
2307 cricket::TransportStats transport_stats;
2308 bool success =
2309 transport_controller_->GetStats(transport_name, &transport_stats);
2310 if (success) {
2311 transport_stats_by_name[transport_name] = std::move(transport_stats);
2312 } else {
2313 RTC_LOG(LS_ERROR) << "Failed to get transport stats for transport_name="
2314 << transport_name;
2315 }
2316 }
2317 return transport_stats_by_name;
Steve Anton75737c02017-11-06 18:37:172318}
2319
2320bool PeerConnection::GetLocalCertificate(
2321 const std::string& transport_name,
2322 rtc::scoped_refptr<rtc::RTCCertificate>* certificate) {
Tomas Gunnarssone1c8a432021-04-08 13:15:282323 RTC_DCHECK_RUN_ON(network_thread());
2324 if (!network_thread_safety_->alive() || !certificate) {
Zhi Huange830e682018-03-30 17:48:352325 return false;
2326 }
2327 *certificate = transport_controller_->GetLocalCertificate(transport_name);
2328 return *certificate != nullptr;
Steve Anton75737c02017-11-06 18:37:172329}
2330
Taylor Brandstetterc3928662018-02-23 21:04:512331std::unique_ptr<rtc::SSLCertChain> PeerConnection::GetRemoteSSLCertChain(
Steve Anton75737c02017-11-06 18:37:172332 const std::string& transport_name) {
Tomas Gunnarssone1c8a432021-04-08 13:15:282333 RTC_DCHECK_RUN_ON(network_thread());
Taylor Brandstetterc3928662018-02-23 21:04:512334 return transport_controller_->GetRemoteSSLCertChain(transport_name);
Steve Anton75737c02017-11-06 18:37:172335}
2336
Steve Anton75737c02017-11-06 18:37:172337bool PeerConnection::IceRestartPending(const std::string& content_name) const {
Karl Wibergf73f7d62019-04-08 13:36:532338 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand9cd199d2020-10-27 07:10:432339 return sdp_handler_->IceRestartPending(content_name);
Steve Anton75737c02017-11-06 18:37:172340}
2341
Steve Anton75737c02017-11-06 18:37:172342bool PeerConnection::NeedsIceRestart(const std::string& content_name) const {
Danil Chapovalov9e09a1f2022-09-08 16:38:102343 return network_thread()->BlockingCall([this, &content_name] {
Tommic3257d02021-02-10 17:40:082344 RTC_DCHECK_RUN_ON(network_thread());
2345 return transport_controller_->NeedsIceRestart(content_name);
2346 });
Steve Anton75737c02017-11-06 18:37:172347}
2348
Alex Loiko9289eda2018-11-23 16:18:592349void PeerConnection::OnTransportControllerConnectionState(
2350 cricket::IceConnectionState state) {
2351 switch (state) {
2352 case cricket::kIceConnectionConnecting:
2353 // If the current state is Connected or Completed, then there were
2354 // writable channels but now there are not, so the next state must
2355 // be Disconnected.
2356 // kIceConnectionConnecting is currently used as the default,
2357 // un-connected state by the TransportController, so its only use is
2358 // detecting disconnections.
2359 if (ice_connection_state_ ==
2360 PeerConnectionInterface::kIceConnectionConnected ||
2361 ice_connection_state_ ==
2362 PeerConnectionInterface::kIceConnectionCompleted) {
2363 SetIceConnectionState(
2364 PeerConnectionInterface::kIceConnectionDisconnected);
2365 }
2366 break;
2367 case cricket::kIceConnectionFailed:
2368 SetIceConnectionState(PeerConnectionInterface::kIceConnectionFailed);
2369 break;
2370 case cricket::kIceConnectionConnected:
2371 RTC_LOG(LS_INFO) << "Changing to ICE connected state because "
2372 "all transports are writable.";
Tommidba22d32023-06-01 14:08:522373 {
2374 std::vector<RtpTransceiverProxyRefPtr> transceivers;
2375 if (ConfiguredForMedia()) {
2376 transceivers = rtp_manager()->transceivers()->List();
2377 }
2378
2379 network_thread()->PostTask(
2380 SafeTask(network_thread_safety_,
2381 [this, transceivers = std::move(transceivers)] {
2382 RTC_DCHECK_RUN_ON(network_thread());
2383 ReportTransportStats(std::move(transceivers));
2384 }));
2385 }
2386
Alex Loiko9289eda2018-11-23 16:18:592387 SetIceConnectionState(PeerConnectionInterface::kIceConnectionConnected);
2388 NoteUsageEvent(UsageEvent::ICE_STATE_CONNECTED);
2389 break;
2390 case cricket::kIceConnectionCompleted:
2391 RTC_LOG(LS_INFO) << "Changing to ICE completed state because "
2392 "all transports are complete.";
2393 if (ice_connection_state_ !=
2394 PeerConnectionInterface::kIceConnectionConnected) {
2395 // If jumping directly from "checking" to "connected",
2396 // signal "connected" first.
2397 SetIceConnectionState(PeerConnectionInterface::kIceConnectionConnected);
2398 }
2399 SetIceConnectionState(PeerConnectionInterface::kIceConnectionCompleted);
Tomas Gunnarsson2001dc32021-04-06 09:36:002400
Alex Loiko9289eda2018-11-23 16:18:592401 NoteUsageEvent(UsageEvent::ICE_STATE_CONNECTED);
Alex Loiko9289eda2018-11-23 16:18:592402 break;
2403 default:
Artem Titovd3251962021-11-15 15:57:072404 RTC_DCHECK_NOTREACHED();
Alex Loiko9289eda2018-11-23 16:18:592405 }
2406}
2407
Steve Anton75737c02017-11-06 18:37:172408void PeerConnection::OnTransportControllerCandidatesGathered(
2409 const std::string& transport_name,
2410 const cricket::Candidates& candidates) {
Tomas Gunnarsson20f74562021-02-04 09:22:502411 // TODO(bugs.webrtc.org/12427): Expect this to come in on the network thread
2412 // (not signaling as it currently does), handle appropriately.
Steve Anton75737c02017-11-06 18:37:172413 int sdp_mline_index;
2414 if (!GetLocalCandidateMediaIndex(transport_name, &sdp_mline_index)) {
Mirko Bonadei675513b2017-11-09 10:09:252415 RTC_LOG(LS_ERROR)
2416 << "OnTransportControllerCandidatesGathered: content name "
2417 << transport_name << " not found";
Steve Anton75737c02017-11-06 18:37:172418 return;
2419 }
2420
2421 for (cricket::Candidates::const_iterator citer = candidates.begin();
2422 citer != candidates.end(); ++citer) {
2423 // Use transport_name as the candidate media id.
2424 std::unique_ptr<JsepIceCandidate> candidate(
2425 new JsepIceCandidate(transport_name, sdp_mline_index, *citer));
Harald Alvestrand9cd199d2020-10-27 07:10:432426 sdp_handler_->AddLocalIceCandidate(candidate.get());
Steve Anton75737c02017-11-06 18:37:172427 OnIceCandidate(std::move(candidate));
2428 }
2429}
2430
Eldar Relloda13ea22019-06-01 09:23:432431void PeerConnection::OnTransportControllerCandidateError(
2432 const cricket::IceCandidateErrorEvent& event) {
Eldar Rello0095d372019-12-02 20:22:072433 OnIceCandidateError(event.address, event.port, event.url, event.error_code,
Eldar Relloda13ea22019-06-01 09:23:432434 event.error_text);
2435}
2436
Steve Anton75737c02017-11-06 18:37:172437void PeerConnection::OnTransportControllerCandidatesRemoved(
2438 const std::vector<cricket::Candidate>& candidates) {
Steve Anton75737c02017-11-06 18:37:172439 // Sanity check.
2440 for (const cricket::Candidate& candidate : candidates) {
2441 if (candidate.transport_name().empty()) {
Mirko Bonadei675513b2017-11-09 10:09:252442 RTC_LOG(LS_ERROR) << "OnTransportControllerCandidatesRemoved: "
Jonas Olsson45cc8902018-02-13 09:37:072443 "empty content name in candidate "
Mirko Bonadei675513b2017-11-09 10:09:252444 << candidate.ToString();
Steve Anton75737c02017-11-06 18:37:172445 return;
2446 }
2447 }
Harald Alvestrand9cd199d2020-10-27 07:10:432448 sdp_handler_->RemoveLocalIceCandidates(candidates);
Steve Anton75737c02017-11-06 18:37:172449 OnIceCandidatesRemoved(candidates);
2450}
2451
Alex Drake00c7ecf2019-08-06 17:54:472452void PeerConnection::OnTransportControllerCandidateChanged(
2453 const cricket::CandidatePairChangeEvent& event) {
2454 OnSelectedCandidatePairChanged(event);
2455}
2456
Steve Anton75737c02017-11-06 18:37:172457void PeerConnection::OnTransportControllerDtlsHandshakeError(
2458 rtc::SSLHandshakeError error) {
Qingsi Wang7fc821d2018-07-12 19:54:532459 RTC_HISTOGRAM_ENUMERATION(
2460 "WebRTC.PeerConnection.DtlsHandshakeError", static_cast<int>(error),
2461 static_cast<int>(rtc::SSLHandshakeError::MAX_VALUE));
Steve Anton75737c02017-11-06 18:37:172462}
2463
Steve Anton75737c02017-11-06 18:37:172464// Returns the media index for a local ice candidate given the content name.
2465bool PeerConnection::GetLocalCandidateMediaIndex(
2466 const std::string& content_name,
2467 int* sdp_mline_index) {
2468 if (!local_description() || !sdp_mline_index) {
2469 return false;
2470 }
2471
2472 bool content_found = false;
2473 const ContentInfos& contents = local_description()->description()->contents();
2474 for (size_t index = 0; index < contents.size(); ++index) {
2475 if (contents[index].name == content_name) {
2476 *sdp_mline_index = static_cast<int>(index);
2477 content_found = true;
2478 break;
2479 }
2480 }
2481 return content_found;
2482}
2483
Steve Anton75737c02017-11-06 18:37:172484Call::Stats PeerConnection::GetCallStats() {
2485 if (!worker_thread()->IsCurrent()) {
Danil Chapovalov9e09a1f2022-09-08 16:38:102486 return worker_thread()->BlockingCall([this] { return GetCallStats(); });
Steve Anton75737c02017-11-06 18:37:172487 }
Karl Wiberg6cab5c82019-03-26 08:57:012488 RTC_DCHECK_RUN_ON(worker_thread());
Henrik Boströme88c95e2020-07-08 09:18:502489 rtc::Thread::ScopedDisallowBlockingCalls no_blocking_calls;
Steve Anton75737c02017-11-06 18:37:172490 if (call_) {
2491 return call_->GetStats();
2492 } else {
2493 return Call::Stats();
2494 }
2495}
2496
Fredrik Hernqvistefbe7532023-01-13 15:42:362497absl::optional<AudioDeviceModule::Stats> PeerConnection::GetAudioDeviceStats() {
2498 if (context_->media_engine()) {
2499 return context_->media_engine()->voice().GetAudioDeviceStats();
2500 }
2501 return absl::nullopt;
2502}
2503
Tommiaa3c9f22023-04-18 10:19:192504absl::optional<std::string> PeerConnection::SetupDataChannelTransport_n(
2505 absl::string_view mid) {
2506 sctp_mid_n_ = std::string(mid);
Bjorn A Mellembc3eebc2019-09-23 21:53:542507 DataChannelTransportInterface* transport =
Tommiaa3c9f22023-04-18 10:19:192508 transport_controller_->GetDataChannelTransport(*sctp_mid_n_);
Bjorn A Mellembc3eebc2019-09-23 21:53:542509 if (!transport) {
Piotr (Peter) Slatalab1ae10b2019-03-01 19:14:052510 RTC_LOG(LS_ERROR)
Bjorn A Mellemb689af42019-08-21 17:44:592511 << "Data channel transport is not available for data channels, mid="
2512 << mid;
Tommiaa3c9f22023-04-18 10:19:192513 sctp_mid_n_ = absl::nullopt;
2514 return absl::nullopt;
Bjorn Mellem175aa2e2018-11-08 19:23:222515 }
2516
Tommiaa3c9f22023-04-18 10:19:192517 absl::optional<std::string> transport_name;
Tomas Gunnarssone1c8a432021-04-08 13:15:282518 cricket::DtlsTransportInternal* dtls_transport =
Tommiaa3c9f22023-04-18 10:19:192519 transport_controller_->GetDtlsTransport(*sctp_mid_n_);
Tomas Gunnarsson92eebef2021-02-10 12:05:442520 if (dtls_transport) {
Tommiaa3c9f22023-04-18 10:19:192521 transport_name = dtls_transport->transport_name();
2522 } else {
2523 // Make sure we still set a valid string.
2524 transport_name = std::string("");
Tomas Gunnarsson92eebef2021-02-10 12:05:442525 }
Bjorn A Mellembc3eebc2019-09-23 21:53:542526
Tommiaa3c9f22023-04-18 10:19:192527 data_channel_controller_.SetupDataChannelTransport_n(transport);
2528
2529 return transport_name;
Bjorn Mellem175aa2e2018-11-08 19:23:222530}
2531
Tommib00d63c2023-04-12 17:49:532532void PeerConnection::TeardownDataChannelTransport_n(RTCError error) {
Tomas Gunnarssond69e0702021-04-07 13:14:432533 if (sctp_mid_n_) {
Artem Titov880fa812021-07-30 20:30:232534 // `sctp_mid_` may still be active through an SCTP transport. If not, unset
Tomas Gunnarssond69e0702021-04-07 13:14:432535 // it.
2536 RTC_LOG(LS_INFO) << "Tearing down data channel transport for mid="
2537 << *sctp_mid_n_;
2538 sctp_mid_n_.reset();
2539 }
2540
Tommib00d63c2023-04-12 17:49:532541 data_channel_controller_.TeardownDataChannelTransport_n(error);
Bjorn Mellem175aa2e2018-11-08 19:23:222542}
2543
Steve Anton75737c02017-11-06 18:37:172544// Returns false if bundle is enabled and rtcp_mux is disabled.
Henrik Boströmf8187e02021-04-26 19:04:262545bool PeerConnection::ValidateBundleSettings(
2546 const SessionDescription* desc,
2547 const std::map<std::string, const cricket::ContentGroup*>&
2548 bundle_groups_by_mid) {
2549 if (bundle_groups_by_mid.empty())
Steve Anton75737c02017-11-06 18:37:172550 return true;
2551
Steve Anton75737c02017-11-06 18:37:172552 const cricket::ContentInfos& contents = desc->contents();
2553 for (cricket::ContentInfos::const_iterator citer = contents.begin();
2554 citer != contents.end(); ++citer) {
2555 const cricket::ContentInfo* content = (&*citer);
2556 RTC_DCHECK(content != NULL);
Henrik Boströmf8187e02021-04-26 19:04:262557 auto it = bundle_groups_by_mid.find(content->name);
Philipp Hancke32dae4b2023-05-12 04:53:552558 if (it != bundle_groups_by_mid.end() &&
2559 !(content->rejected || content->bundle_only) &&
Steve Anton5adfafd2017-12-21 00:34:002560 content->type == MediaProtocolType::kRtp) {
Steve Anton75737c02017-11-06 18:37:172561 if (!HasRtcpMuxEnabled(content))
2562 return false;
2563 }
2564 }
2565 // RTCP-MUX is enabled in all the contents.
2566 return true;
2567}
2568
Philipp Hancke54b925c2021-01-28 08:56:392569void PeerConnection::ReportSdpBundleUsage(
2570 const SessionDescriptionInterface& remote_description) {
2571 RTC_DCHECK_RUN_ON(signaling_thread());
2572
2573 bool using_bundle =
2574 remote_description.description()->HasGroup(cricket::GROUP_TYPE_BUNDLE);
2575 int num_audio_mlines = 0;
2576 int num_video_mlines = 0;
2577 int num_data_mlines = 0;
2578 for (const ContentInfo& content :
2579 remote_description.description()->contents()) {
2580 cricket::MediaType media_type = content.media_description()->type();
2581 if (media_type == cricket::MEDIA_TYPE_AUDIO) {
2582 num_audio_mlines += 1;
2583 } else if (media_type == cricket::MEDIA_TYPE_VIDEO) {
2584 num_video_mlines += 1;
2585 } else if (media_type == cricket::MEDIA_TYPE_DATA) {
2586 num_data_mlines += 1;
2587 }
2588 }
2589 bool simple = num_audio_mlines <= 1 && num_video_mlines <= 1;
2590 BundleUsage usage = kBundleUsageMax;
2591 if (num_audio_mlines == 0 && num_video_mlines == 0) {
2592 if (num_data_mlines > 0) {
2593 usage = using_bundle ? kBundleUsageBundleDatachannelOnly
2594 : kBundleUsageNoBundleDatachannelOnly;
2595 } else {
2596 usage = kBundleUsageEmpty;
2597 }
Harald Alvestrandfa67aef2021-12-08 14:30:552598 } else if (configuration_.sdp_semantics == SdpSemantics::kPlanB_DEPRECATED) {
Philipp Hancke54b925c2021-01-28 08:56:392599 // In plan-b, simple/complex usage will not show up in the number of
2600 // m-lines or BUNDLE.
2601 usage = using_bundle ? kBundleUsageBundlePlanB : kBundleUsageNoBundlePlanB;
2602 } else {
2603 if (simple) {
2604 usage =
2605 using_bundle ? kBundleUsageBundleSimple : kBundleUsageNoBundleSimple;
2606 } else {
2607 usage = using_bundle ? kBundleUsageBundleComplex
2608 : kBundleUsageNoBundleComplex;
2609 }
2610 }
2611 RTC_HISTOGRAM_ENUMERATION("WebRTC.PeerConnection.BundleUsage", usage,
2612 kBundleUsageMax);
2613}
2614
Qingsi Wang1ba5dec2019-08-19 18:57:172615void PeerConnection::ReportIceCandidateCollected(
2616 const cricket::Candidate& candidate) {
2617 NoteUsageEvent(UsageEvent::CANDIDATE_COLLECTED);
2618 if (candidate.address().IsPrivateIP()) {
2619 NoteUsageEvent(UsageEvent::PRIVATE_CANDIDATE_COLLECTED);
2620 }
2621 if (candidate.address().IsUnresolvedIP()) {
2622 NoteUsageEvent(UsageEvent::MDNS_CANDIDATE_COLLECTED);
2623 }
2624 if (candidate.address().family() == AF_INET6) {
2625 NoteUsageEvent(UsageEvent::IPV6_CANDIDATE_COLLECTED);
2626 }
2627}
2628
Harald Alvestrand8ebba742018-05-31 12:00:342629void PeerConnection::NoteUsageEvent(UsageEvent event) {
2630 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand44d0dff2020-10-09 05:43:532631 usage_pattern_.NoteUsageEvent(event);
Harald Alvestrand8ebba742018-05-31 12:00:342632}
2633
Tomas Gunnarsson8cb97062021-02-08 17:57:042634// Asynchronously adds remote candidates on the network thread.
2635void PeerConnection::AddRemoteCandidate(const std::string& mid,
2636 const cricket::Candidate& candidate) {
2637 RTC_DCHECK_RUN_ON(signaling_thread());
2638
Byoungchan Lee5a925772022-10-18 17:43:182639 if (candidate.network_type() != rtc::ADAPTER_TYPE_UNKNOWN) {
2640 RTC_DLOG(LS_WARNING) << "Using candidate with adapter type set - this "
2641 "should only happen in test";
2642 }
2643
2644 // Clear fields that do not make sense as remote candidates.
2645 cricket::Candidate new_candidate(candidate);
2646 new_candidate.set_network_type(rtc::ADAPTER_TYPE_UNKNOWN);
2647 new_candidate.set_relay_protocol("");
2648 new_candidate.set_underlying_type_for_vpn(rtc::ADAPTER_TYPE_UNKNOWN);
2649
Danil Chapovalova30439b2022-07-07 08:08:492650 network_thread()->PostTask(SafeTask(
Byoungchan Lee5a925772022-10-18 17:43:182651 network_thread_safety_, [this, mid = mid, candidate = new_candidate] {
Tomas Gunnarsson8cb97062021-02-08 17:57:042652 RTC_DCHECK_RUN_ON(network_thread());
2653 std::vector<cricket::Candidate> candidates = {candidate};
2654 RTCError error =
2655 transport_controller_->AddRemoteCandidates(mid, candidates);
2656 if (error.ok()) {
Danil Chapovalova30439b2022-07-07 08:08:492657 signaling_thread()->PostTask(SafeTask(
Tomas Gunnarsson8cb97062021-02-08 17:57:042658 signaling_thread_safety_.flag(),
2659 [this, candidate = std::move(candidate)] {
2660 ReportRemoteIceCandidateAdded(candidate);
2661 // Candidates successfully submitted for checking.
2662 if (ice_connection_state() ==
2663 PeerConnectionInterface::kIceConnectionNew ||
2664 ice_connection_state() ==
2665 PeerConnectionInterface::kIceConnectionDisconnected) {
2666 // If state is New, then the session has just gotten its first
2667 // remote ICE candidates, so go to Checking. If state is
2668 // Disconnected, the session is re-using old candidates or
2669 // receiving additional ones, so go to Checking. If state is
2670 // Connected, stay Connected.
2671 // TODO(bemasc): If state is Connected, and the new candidates
2672 // are for a newly added transport, then the state actually
2673 // _should_ move to checking. Add a way to distinguish that
2674 // case.
2675 SetIceConnectionState(
2676 PeerConnectionInterface::kIceConnectionChecking);
2677 }
2678 // TODO(bemasc): If state is Completed, go back to Connected.
2679 }));
2680 } else {
2681 RTC_LOG(LS_WARNING) << error.message();
2682 }
2683 }));
2684}
2685
Harald Alvestrand8ebba742018-05-31 12:00:342686void PeerConnection::ReportUsagePattern() const {
Harald Alvestrand44d0dff2020-10-09 05:43:532687 usage_pattern_.ReportUsagePattern(observer_);
Harald Alvestrand8ebba742018-05-31 12:00:342688}
2689
Tomas Gunnarsson8cb97062021-02-08 17:57:042690void PeerConnection::ReportRemoteIceCandidateAdded(
2691 const cricket::Candidate& candidate) {
2692 RTC_DCHECK_RUN_ON(signaling_thread());
2693
2694 NoteUsageEvent(UsageEvent::REMOTE_CANDIDATE_ADDED);
2695
2696 if (candidate.address().IsPrivateIP()) {
2697 NoteUsageEvent(UsageEvent::REMOTE_PRIVATE_CANDIDATE_ADDED);
2698 }
2699 if (candidate.address().IsUnresolvedIP()) {
2700 NoteUsageEvent(UsageEvent::REMOTE_MDNS_CANDIDATE_ADDED);
2701 }
2702 if (candidate.address().family() == AF_INET6) {
2703 NoteUsageEvent(UsageEvent::REMOTE_IPV6_CANDIDATE_ADDED);
2704 }
2705}
2706
Steve Anton75737c02017-11-06 18:37:172707bool PeerConnection::SrtpRequired() const {
Tomas Gunnarsson3278a712021-03-30 15:23:422708 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand0d018412021-11-04 13:52:312709 return (dtls_enabled_ ||
2710 sdp_handler_->webrtc_session_desc_factory()->SdesPolicy() ==
2711 cricket::SEC_REQUIRED);
Steve Anton75737c02017-11-06 18:37:172712}
2713
2714void PeerConnection::OnTransportControllerGatheringState(
2715 cricket::IceGatheringState state) {
2716 RTC_DCHECK(signaling_thread()->IsCurrent());
2717 if (state == cricket::kIceGatheringGathering) {
2718 OnIceGatheringChange(PeerConnectionInterface::kIceGatheringGathering);
2719 } else if (state == cricket::kIceGatheringComplete) {
2720 OnIceGatheringChange(PeerConnectionInterface::kIceGatheringComplete);
Harald Alvestrandbedb6052020-08-20 12:50:102721 } else if (state == cricket::kIceGatheringNew) {
2722 OnIceGatheringChange(PeerConnectionInterface::kIceGatheringNew);
2723 } else {
2724 RTC_LOG(LS_ERROR) << "Unknown state received: " << state;
Artem Titovd3251962021-11-15 15:57:072725 RTC_DCHECK_NOTREACHED();
Steve Anton75737c02017-11-06 18:37:172726 }
2727}
2728
Tomas Gunnarsson2001dc32021-04-06 09:36:002729// Runs on network_thread().
Tommidba22d32023-06-01 14:08:522730void PeerConnection::ReportTransportStats(
2731 std::vector<RtpTransceiverProxyRefPtr> transceivers) {
Markus Handell518669d2021-06-07 11:30:462732 TRACE_EVENT0("webrtc", "PeerConnection::ReportTransportStats");
Tommic3257d02021-02-10 17:40:082733 rtc::Thread::ScopedDisallowBlockingCalls no_blocking_calls;
Steve Antonc7b964c2018-02-01 22:39:452734 std::map<std::string, std::set<cricket::MediaType>>
2735 media_types_by_transport_name;
Tommidba22d32023-06-01 14:08:522736 for (const auto& transceiver : transceivers) {
2737 if (transceiver->internal()->channel()) {
2738 std::string transport_name(
2739 transceiver->internal()->channel()->transport_name());
2740 media_types_by_transport_name[transport_name].insert(
2741 transceiver->media_type());
Steve Antonc7b964c2018-02-01 22:39:452742 }
Steve Anton75737c02017-11-06 18:37:172743 }
Tomas Gunnarsson2001dc32021-04-06 09:36:002744
Tomas Gunnarsson2001dc32021-04-06 09:36:002745 if (sctp_mid_n_) {
Tomas Gunnarssone1c8a432021-04-08 13:15:282746 cricket::DtlsTransportInternal* dtls_transport =
2747 transport_controller_->GetDtlsTransport(*sctp_mid_n_);
Tomas Gunnarsson2001dc32021-04-06 09:36:002748 if (dtls_transport) {
2749 media_types_by_transport_name[dtls_transport->transport_name()].insert(
2750 cricket::MEDIA_TYPE_DATA);
2751 }
Steve Anton75737c02017-11-06 18:37:172752 }
Zhi Huange830e682018-03-30 17:48:352753
Tomas Gunnarsson2001dc32021-04-06 09:36:002754 for (const auto& entry : media_types_by_transport_name) {
2755 const std::string& transport_name = entry.first;
2756 const std::set<cricket::MediaType> media_types = entry.second;
2757 cricket::TransportStats stats;
2758 if (transport_controller_->GetStats(transport_name, &stats)) {
2759 ReportBestConnectionState(stats);
2760 ReportNegotiatedCiphers(dtls_enabled_, stats, media_types);
2761 }
2762 }
Steve Anton75737c02017-11-06 18:37:172763}
Tomas Gunnarsson2001dc32021-04-06 09:36:002764
Steve Anton75737c02017-11-06 18:37:172765// Walk through the ConnectionInfos to gather best connection usage
2766// for IPv4 and IPv6.
Tommic3257d02021-02-10 17:40:082767// static (no member state required)
Steve Anton75737c02017-11-06 18:37:172768void PeerConnection::ReportBestConnectionState(
2769 const cricket::TransportStats& stats) {
Steve Antonc7b964c2018-02-01 22:39:452770 for (const cricket::TransportChannelStats& channel_stats :
2771 stats.channel_stats) {
2772 for (const cricket::ConnectionInfo& connection_info :
Jonas Oreland149dc722019-08-28 06:10:272773 channel_stats.ice_transport_stats.connection_infos) {
Steve Antonc7b964c2018-02-01 22:39:452774 if (!connection_info.best_connection) {
Steve Anton75737c02017-11-06 18:37:172775 continue;
2776 }
2777
Steve Antonc7b964c2018-02-01 22:39:452778 const cricket::Candidate& local = connection_info.local_candidate;
2779 const cricket::Candidate& remote = connection_info.remote_candidate;
Steve Anton75737c02017-11-06 18:37:172780
2781 // Increment the counter for IceCandidatePairType.
2782 if (local.protocol() == cricket::TCP_PROTOCOL_NAME ||
Tommi3b2b2af2024-01-17 13:19:412783 (local.is_relay() &&
Steve Anton75737c02017-11-06 18:37:172784 local.relay_protocol() == cricket::TCP_PROTOCOL_NAME)) {
Qingsi Wang7fc821d2018-07-12 19:54:532785 RTC_HISTOGRAM_ENUMERATION("WebRTC.PeerConnection.CandidatePairType_TCP",
2786 GetIceCandidatePairCounter(local, remote),
2787 kIceCandidatePairMax);
Steve Anton75737c02017-11-06 18:37:172788 } else if (local.protocol() == cricket::UDP_PROTOCOL_NAME) {
Qingsi Wang7fc821d2018-07-12 19:54:532789 RTC_HISTOGRAM_ENUMERATION("WebRTC.PeerConnection.CandidatePairType_UDP",
2790 GetIceCandidatePairCounter(local, remote),
2791 kIceCandidatePairMax);
Steve Anton75737c02017-11-06 18:37:172792 } else {
Karl Wibergc95b9392020-11-07 23:49:372793 RTC_CHECK_NOTREACHED();
Steve Anton75737c02017-11-06 18:37:172794 }
Steve Anton75737c02017-11-06 18:37:172795
2796 // Increment the counter for IP type.
2797 if (local.address().family() == AF_INET) {
Qingsi Wang7fc821d2018-07-12 19:54:532798 RTC_HISTOGRAM_ENUMERATION("WebRTC.PeerConnection.IPMetrics",
2799 kBestConnections_IPv4,
2800 kPeerConnectionAddressFamilyCounter_Max);
Steve Anton75737c02017-11-06 18:37:172801 } else if (local.address().family() == AF_INET6) {
Qingsi Wang7fc821d2018-07-12 19:54:532802 RTC_HISTOGRAM_ENUMERATION("WebRTC.PeerConnection.IPMetrics",
2803 kBestConnections_IPv6,
2804 kPeerConnectionAddressFamilyCounter_Max);
Steve Anton75737c02017-11-06 18:37:172805 } else {
Qingsi Wang1dac6d82018-12-12 23:28:472806 RTC_CHECK(!local.address().hostname().empty() &&
2807 local.address().IsUnresolvedIP());
Steve Anton75737c02017-11-06 18:37:172808 }
2809
2810 return;
2811 }
2812 }
2813}
2814
Tommic3257d02021-02-10 17:40:082815// static
Steve Anton75737c02017-11-06 18:37:172816void PeerConnection::ReportNegotiatedCiphers(
Tommic3257d02021-02-10 17:40:082817 bool dtls_enabled,
Steve Antonc7b964c2018-02-01 22:39:452818 const cricket::TransportStats& stats,
2819 const std::set<cricket::MediaType>& media_types) {
Tommic3257d02021-02-10 17:40:082820 if (!dtls_enabled || stats.channel_stats.empty()) {
Steve Anton75737c02017-11-06 18:37:172821 return;
2822 }
2823
2824 int srtp_crypto_suite = stats.channel_stats[0].srtp_crypto_suite;
2825 int ssl_cipher_suite = stats.channel_stats[0].ssl_cipher_suite;
Mirko Bonadei7750d802021-07-26 15:27:422826 if (srtp_crypto_suite == rtc::kSrtpInvalidCryptoSuite &&
2827 ssl_cipher_suite == rtc::kTlsNullWithNullNull) {
Steve Anton75737c02017-11-06 18:37:172828 return;
2829 }
2830
Mirko Bonadei7750d802021-07-26 15:27:422831 if (ssl_cipher_suite != rtc::kTlsNullWithNullNull) {
Qingsi Wang7fc821d2018-07-12 19:54:532832 for (cricket::MediaType media_type : media_types) {
2833 switch (media_type) {
2834 case cricket::MEDIA_TYPE_AUDIO:
2835 RTC_HISTOGRAM_ENUMERATION_SPARSE(
2836 "WebRTC.PeerConnection.SslCipherSuite.Audio", ssl_cipher_suite,
Mirko Bonadei7750d802021-07-26 15:27:422837 rtc::kSslCipherSuiteMaxValue);
Qingsi Wang7fc821d2018-07-12 19:54:532838 break;
2839 case cricket::MEDIA_TYPE_VIDEO:
2840 RTC_HISTOGRAM_ENUMERATION_SPARSE(
2841 "WebRTC.PeerConnection.SslCipherSuite.Video", ssl_cipher_suite,
Mirko Bonadei7750d802021-07-26 15:27:422842 rtc::kSslCipherSuiteMaxValue);
Qingsi Wang7fc821d2018-07-12 19:54:532843 break;
2844 case cricket::MEDIA_TYPE_DATA:
2845 RTC_HISTOGRAM_ENUMERATION_SPARSE(
2846 "WebRTC.PeerConnection.SslCipherSuite.Data", ssl_cipher_suite,
Mirko Bonadei7750d802021-07-26 15:27:422847 rtc::kSslCipherSuiteMaxValue);
Qingsi Wang7fc821d2018-07-12 19:54:532848 break;
2849 default:
Artem Titovd3251962021-11-15 15:57:072850 RTC_DCHECK_NOTREACHED();
Qingsi Wang7fc821d2018-07-12 19:54:532851 continue;
2852 }
Steve Antonc7b964c2018-02-01 22:39:452853 }
Steve Anton75737c02017-11-06 18:37:172854 }
Philipp Hancke36e4dd22023-09-28 09:02:212855
2856 uint16_t ssl_peer_signature_algorithm =
2857 stats.channel_stats[0].ssl_peer_signature_algorithm;
2858 if (ssl_peer_signature_algorithm != rtc::kSslSignatureAlgorithmUnknown) {
2859 for (cricket::MediaType media_type : media_types) {
2860 switch (media_type) {
2861 case cricket::MEDIA_TYPE_AUDIO:
2862 RTC_HISTOGRAM_ENUMERATION_SPARSE(
2863 "WebRTC.PeerConnection.SslPeerSignatureAlgorithm.Audio",
2864 ssl_peer_signature_algorithm,
2865 rtc::kSslSignatureAlgorithmMaxValue);
2866 break;
2867 case cricket::MEDIA_TYPE_VIDEO:
2868 RTC_HISTOGRAM_ENUMERATION_SPARSE(
2869 "WebRTC.PeerConnection.SslPeerSignatureAlgorithm.Video",
2870 ssl_peer_signature_algorithm,
2871 rtc::kSslSignatureAlgorithmMaxValue);
2872 break;
2873 case cricket::MEDIA_TYPE_DATA:
2874 RTC_HISTOGRAM_ENUMERATION_SPARSE(
2875 "WebRTC.PeerConnection.SslPeerSignatureAlgorithm.Data",
2876 ssl_peer_signature_algorithm,
2877 rtc::kSslSignatureAlgorithmMaxValue);
2878 break;
2879 default:
2880 RTC_DCHECK_NOTREACHED();
2881 continue;
2882 }
2883 }
2884 }
Steve Anton75737c02017-11-06 18:37:172885}
2886
Taylor Brandstettercbaa2542018-04-16 23:42:142887bool PeerConnection::OnTransportChanged(
Zhi Huange830e682018-03-30 17:48:352888 const std::string& mid,
Taylor Brandstettercbaa2542018-04-16 23:42:142889 RtpTransportInternal* rtp_transport,
Harald Alvestrandc85328f2019-02-28 06:51:002890 rtc::scoped_refptr<DtlsTransport> dtls_transport,
Bjorn A Mellembc3eebc2019-09-23 21:53:542891 DataChannelTransportInterface* data_channel_transport) {
Karl Wibergac025892019-03-26 12:08:372892 RTC_DCHECK_RUN_ON(network_thread());
Taylor Brandstettercbaa2542018-04-16 23:42:142893 bool ret = true;
Harald Alvestrand8101e7b2022-05-23 14:57:472894 if (ConfiguredForMedia()) {
2895 for (const auto& transceiver :
2896 rtp_manager()->transceivers()->UnsafeList()) {
2897 cricket::ChannelInterface* channel = transceiver->internal()->channel();
2898 if (channel && channel->mid() == mid) {
2899 ret = channel->SetRtpTransport(rtp_transport);
2900 }
Harald Alvestrand19ebabc2022-04-28 13:31:172901 }
Zhi Huange830e682018-03-30 17:48:352902 }
Tomas Gunnarsson92eebef2021-02-10 12:05:442903
Harald Alvestrand7a829a82020-02-12 06:38:212904 if (mid == sctp_mid_n_) {
Harald Alvestrand00cf34c2019-12-02 08:56:022905 data_channel_controller_.OnTransportChanged(data_channel_transport);
Tomas Gunnarsson92eebef2021-02-10 12:05:442906 if (dtls_transport) {
Danil Chapovalova30439b2022-07-07 08:08:492907 signaling_thread()->PostTask(SafeTask(
Tomas Gunnarsson92eebef2021-02-10 12:05:442908 signaling_thread_safety_.flag(),
Tomas Gunnarsson94f01942022-01-03 14:59:122909 [this,
2910 name = std::string(dtls_transport->internal()->transport_name())] {
Tomas Gunnarsson92eebef2021-02-10 12:05:442911 RTC_DCHECK_RUN_ON(signaling_thread());
Henrik Boström46053e42023-01-20 12:18:532912 SetSctpTransportName(std::move(name));
Tomas Gunnarsson92eebef2021-02-10 12:05:442913 }));
2914 }
Bjorn A Mellemb689af42019-08-21 17:44:592915 }
Tomas Gunnarsson92eebef2021-02-10 12:05:442916
Taylor Brandstettercbaa2542018-04-16 23:42:142917 return ret;
Steve Anton75737c02017-11-06 18:37:172918}
2919
Harald Alvestrand7a1c7f72018-08-01 08:50:162920PeerConnectionObserver* PeerConnection::Observer() const {
Harald Alvestrand05e4d082019-12-03 13:04:212921 RTC_DCHECK_RUN_ON(signaling_thread());
2922 RTC_DCHECK(observer_);
Harald Alvestrand7a1c7f72018-08-01 08:50:162923 return observer_;
2924}
2925
Tomas Gunnarsson92eebef2021-02-10 12:05:442926void PeerConnection::StartSctpTransport(int local_port,
2927 int remote_port,
2928 int max_message_size) {
2929 RTC_DCHECK_RUN_ON(signaling_thread());
2930 if (!sctp_mid_s_)
2931 return;
2932
Danil Chapovalova30439b2022-07-07 08:08:492933 network_thread()->PostTask(SafeTask(
Tomas Gunnarsson92eebef2021-02-10 12:05:442934 network_thread_safety_,
2935 [this, mid = *sctp_mid_s_, local_port, remote_port, max_message_size] {
2936 rtc::scoped_refptr<SctpTransport> sctp_transport =
Harald Alvestrandbc32c562022-02-09 12:08:472937 transport_controller_n()->GetSctpTransport(mid);
Tomas Gunnarsson92eebef2021-02-10 12:05:442938 if (sctp_transport)
2939 sctp_transport->Start(local_port, remote_port, max_message_size);
2940 }));
2941}
2942
Benjamin Wright8c27cca2018-10-25 17:16:442943CryptoOptions PeerConnection::GetCryptoOptions() {
Harald Alvestrandc06e3742020-10-01 10:23:332944 RTC_DCHECK_RUN_ON(signaling_thread());
Benjamin Wright8c27cca2018-10-25 17:16:442945 // TODO(bugs.webrtc.org/9891) - Remove PeerConnectionFactory::CryptoOptions
2946 // after it has been removed.
2947 return configuration_.crypto_options.has_value()
2948 ? *configuration_.crypto_options
Harald Alvestrand4da4a872020-11-04 10:34:212949 : options_.crypto_options;
Benjamin Wright8c27cca2018-10-25 17:16:442950}
2951
Harald Alvestrand89061872018-01-02 13:08:342952void PeerConnection::ClearStatsCache() {
Karl Wiberg6cab5c82019-03-26 08:57:012953 RTC_DCHECK_RUN_ON(signaling_thread());
Philipp Hancke7baa63f2022-09-01 13:39:502954 if (legacy_stats_) {
2955 legacy_stats_->InvalidateCache();
2956 }
Harald Alvestrand89061872018-01-02 13:08:342957 if (stats_collector_) {
2958 stats_collector_->ClearCachedStatsReport();
2959 }
2960}
2961
Henrik Boströme574a312020-08-25 08:20:112962bool PeerConnection::ShouldFireNegotiationNeededEvent(uint32_t event_id) {
2963 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand9cd199d2020-10-27 07:10:432964 return sdp_handler_->ShouldFireNegotiationNeededEvent(event_id);
Eldar Rello5ab79e62019-10-09 15:29:442965}
2966
Harald Alvestrand1090e442020-10-05 07:01:092967void PeerConnection::RequestUsagePatternReportForTesting() {
Harald Alvestrand00c62ed2021-10-20 08:52:122968 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand1090e442020-10-05 07:01:092969 message_handler_.RequestUsagePatternReport(
2970 [this]() {
2971 RTC_DCHECK_RUN_ON(signaling_thread());
2972 ReportUsagePattern();
2973 },
2974 /* delay_ms= */ 0);
2975}
2976
Tomas Gunnarsson1e40a0c2020-09-28 08:39:312977std::function<void(const rtc::CopyOnWriteBuffer& packet,
2978 int64_t packet_time_us)>
2979PeerConnection::InitializeRtcpCallback() {
Tommic3257d02021-02-10 17:40:082980 RTC_DCHECK_RUN_ON(network_thread());
Per Kcf439a02023-01-05 13:01:392981 return [this](const rtc::CopyOnWriteBuffer& packet,
2982 int64_t /*packet_time_us*/) {
2983 worker_thread()->PostTask(SafeTask(worker_thread_safety_, [this, packet]() {
2984 call_ptr_->Receiver()->DeliverRtcpPacket(packet);
2985 }));
Tomas Gunnarsson1e40a0c2020-09-28 08:39:312986 };
2987}
Harald Alvestrandcdcfab02020-09-28 13:02:072988
Per Ke1e94ad2023-03-30 14:53:592989std::function<void(const RtpPacketReceived& parsed_packet)>
2990PeerConnection::InitializeUnDemuxablePacketHandler() {
2991 RTC_DCHECK_RUN_ON(network_thread());
2992 return [this](const RtpPacketReceived& parsed_packet) {
2993 worker_thread()->PostTask(
2994 SafeTask(worker_thread_safety_, [this, parsed_packet]() {
2995 // Deliver the packet anyway to Call to allow Call to do BWE.
2996 // Even if there is no media receiver, the packet has still
2997 // been received on the network and has been correcly parsed.
2998 call_ptr_->Receiver()->DeliverRtpPacket(
2999 MediaType::ANY, parsed_packet,
3000 /*undemuxable_packet_handler=*/
3001 [](const RtpPacketReceived& packet) { return false; });
3002 }));
3003 };
3004}
3005
henrike@webrtc.org28e20752013-07-10 00:45:363006} // namespace webrtc