blob: 32f21cfaea9ca1a21e86353ff4f3f20515be199a [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>
Florent Castelli8037fc62024-08-29 13:00:4018#include <optional>
Harald Alvestrande15fb152020-10-19 13:28:0519#include <set>
Harald Alvestrand0d4af122022-01-31 09:36:0520#include <string>
Harald Alvestrand3eaee6b2020-10-19 06:35:5521#include <utility>
henrike@webrtc.org28e20752013-07-10 00:45:3622
Steve Anton64b626b2019-01-29 01:25:2623#include "absl/algorithm/container.h"
Fredrik Solenberg41f3a432018-12-17 20:02:2224#include "absl/strings/match.h"
Harald Alvestrand0d4af122022-01-31 09:36:0525#include "absl/strings/string_view.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"
Philipp Hancke41586782024-06-06 14:31:0756#include "rtc_base/crypto_random.h"
Harald Alvestrand1f7eab62020-10-18 16:51:4757#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) {
Tommi698b4e72024-01-24 07:36:45107 if (local.is_local() && remote.is_local()) {
Jeroen de Borst833979f2018-12-13 16:25:54108 bool local_hostname =
109 !local.address().hostname().empty() && local.address().IsUnresolvedIP();
110 bool remote_hostname = !remote.address().hostname().empty() &&
111 remote.address().IsUnresolvedIP();
Steve Anton75737c02017-11-06 18:37:17112 bool local_private = IPIsPrivate(local.address().ipaddr());
113 bool remote_private = IPIsPrivate(remote.address().ipaddr());
Jeroen de Borst833979f2018-12-13 16:25:54114 if (local_hostname) {
115 if (remote_hostname) {
116 return kIceCandidatePairHostNameHostName;
117 } else if (remote_private) {
118 return kIceCandidatePairHostNameHostPrivate;
119 } else {
120 return kIceCandidatePairHostNameHostPublic;
121 }
122 } else if (local_private) {
123 if (remote_hostname) {
124 return kIceCandidatePairHostPrivateHostName;
125 } else if (remote_private) {
Steve Anton75737c02017-11-06 18:37:17126 return kIceCandidatePairHostPrivateHostPrivate;
127 } else {
128 return kIceCandidatePairHostPrivateHostPublic;
129 }
130 } else {
Jeroen de Borst833979f2018-12-13 16:25:54131 if (remote_hostname) {
132 return kIceCandidatePairHostPublicHostName;
133 } else if (remote_private) {
Steve Anton75737c02017-11-06 18:37:17134 return kIceCandidatePairHostPublicHostPrivate;
135 } else {
136 return kIceCandidatePairHostPublicHostPublic;
137 }
138 }
139 }
Tommi698b4e72024-01-24 07:36:45140
141 if (local.is_local()) {
142 if (remote.is_stun())
143 return kIceCandidatePairHostSrflx;
144 if (remote.is_relay())
145 return kIceCandidatePairHostRelay;
146 if (remote.is_prflx())
147 return kIceCandidatePairHostPrflx;
148 } else if (local.is_stun()) {
149 if (remote.is_local())
150 return kIceCandidatePairSrflxHost;
151 if (remote.is_stun())
152 return kIceCandidatePairSrflxSrflx;
153 if (remote.is_relay())
154 return kIceCandidatePairSrflxRelay;
155 if (remote.is_prflx())
156 return kIceCandidatePairSrflxPrflx;
157 } else if (local.is_relay()) {
158 if (remote.is_local())
159 return kIceCandidatePairRelayHost;
160 if (remote.is_stun())
161 return kIceCandidatePairRelaySrflx;
162 if (remote.is_relay())
163 return kIceCandidatePairRelayRelay;
164 if (remote.is_prflx())
165 return kIceCandidatePairRelayPrflx;
166 } else if (local.is_prflx()) {
167 if (remote.is_local())
168 return kIceCandidatePairPrflxHost;
169 if (remote.is_stun())
170 return kIceCandidatePairPrflxSrflx;
171 if (remote.is_relay())
172 return kIceCandidatePairPrflxRelay;
173 }
174
Steve Anton75737c02017-11-06 18:37:17175 return kIceCandidatePairMax;
176}
177
Florent Castelli8037fc62024-08-29 13:00:40178std::optional<int> RTCConfigurationToIceConfigOptionalInt(
Qingsi Wang866e08d2018-03-23 00:54:23179 int rtc_configuration_parameter) {
180 if (rtc_configuration_parameter ==
Harald Alvestranda6544372023-11-13 09:33:56181 PeerConnectionInterface::RTCConfiguration::kUndefined) {
Florent Castelli8037fc62024-08-29 13:00:40182 return std::nullopt;
Qingsi Wang866e08d2018-03-23 00:54:23183 }
184 return rtc_configuration_parameter;
185}
186
Jonas Orelande3096512020-05-27 07:01:05187// Check if the changes of IceTransportsType motives an ice restart.
188bool NeedIceRestart(bool surface_ice_candidates_on_ice_transport_type_changed,
189 PeerConnectionInterface::IceTransportsType current,
190 PeerConnectionInterface::IceTransportsType modified) {
191 if (current == modified) {
192 return false;
193 }
194
195 if (!surface_ice_candidates_on_ice_transport_type_changed) {
196 return true;
197 }
198
199 auto current_filter = ConvertIceTransportTypeToCandidateFilter(current);
200 auto modified_filter = ConvertIceTransportTypeToCandidateFilter(modified);
201
202 // If surface_ice_candidates_on_ice_transport_type_changed is true and we
203 // extend the filter, then no ice restart is needed.
204 return (current_filter & modified_filter) != current_filter;
205}
206
Harald Alvestrand62166932020-10-26 08:30:41207cricket::IceConfig ParseIceConfig(
208 const PeerConnectionInterface::RTCConfiguration& config) {
209 cricket::ContinualGatheringPolicy gathering_policy;
210 switch (config.continual_gathering_policy) {
211 case PeerConnectionInterface::GATHER_ONCE:
212 gathering_policy = cricket::GATHER_ONCE;
213 break;
214 case PeerConnectionInterface::GATHER_CONTINUALLY:
215 gathering_policy = cricket::GATHER_CONTINUALLY;
216 break;
217 default:
Artem Titovd3251962021-11-15 15:57:07218 RTC_DCHECK_NOTREACHED();
Harald Alvestrand62166932020-10-26 08:30:41219 gathering_policy = cricket::GATHER_ONCE;
220 }
221
222 cricket::IceConfig ice_config;
223 ice_config.receiving_timeout = RTCConfigurationToIceConfigOptionalInt(
224 config.ice_connection_receiving_timeout);
225 ice_config.prioritize_most_likely_candidate_pairs =
226 config.prioritize_most_likely_ice_candidate_pairs;
227 ice_config.backup_connection_ping_interval =
228 RTCConfigurationToIceConfigOptionalInt(
229 config.ice_backup_candidate_pair_ping_interval);
230 ice_config.continual_gathering_policy = gathering_policy;
231 ice_config.presume_writable_when_fully_relayed =
232 config.presume_writable_when_fully_relayed;
233 ice_config.surface_ice_candidates_on_ice_transport_type_changed =
234 config.surface_ice_candidates_on_ice_transport_type_changed;
235 ice_config.ice_check_interval_strong_connectivity =
236 config.ice_check_interval_strong_connectivity;
237 ice_config.ice_check_interval_weak_connectivity =
238 config.ice_check_interval_weak_connectivity;
239 ice_config.ice_check_min_interval = config.ice_check_min_interval;
240 ice_config.ice_unwritable_timeout = config.ice_unwritable_timeout;
241 ice_config.ice_unwritable_min_checks = config.ice_unwritable_min_checks;
242 ice_config.ice_inactive_timeout = config.ice_inactive_timeout;
243 ice_config.stun_keepalive_interval = config.stun_candidate_keepalive_interval;
244 ice_config.network_preference = config.network_preference;
Derek Bailey6c127a12021-04-15 19:42:41245 ice_config.stable_writable_connection_ping_interval =
246 config.stable_writable_connection_ping_interval_ms;
Harald Alvestrand62166932020-10-26 08:30:41247 return ice_config;
248}
249
250// Ensures the configuration doesn't have any parameters with invalid values,
251// or values that conflict with other parameters.
252//
253// Returns RTCError::OK() if there are no issues.
254RTCError ValidateConfiguration(
255 const PeerConnectionInterface::RTCConfiguration& config) {
256 return cricket::P2PTransportChannel::ValidateIceConfig(
257 ParseIceConfig(config));
258}
259
Tommiaea49c92023-10-22 11:00:14260// Checks for valid pool size range and if a previous value has already been
261// set, which is done via SetLocalDescription.
262RTCError ValidateIceCandidatePoolSize(
263 int ice_candidate_pool_size,
Florent Castelli8037fc62024-08-29 13:00:40264 std::optional<int> previous_ice_candidate_pool_size) {
Tommiaea49c92023-10-22 11:00:14265 // Note that this isn't possible through chromium, since it's an unsigned
266 // short in WebIDL.
267 if (ice_candidate_pool_size < 0 ||
268 ice_candidate_pool_size > static_cast<int>(UINT16_MAX)) {
269 return RTCError(RTCErrorType::INVALID_RANGE);
270 }
271
272 // According to JSEP, after setLocalDescription, changing the candidate pool
273 // size is not allowed, and changing the set of ICE servers will not result
274 // in new candidates being gathered.
275 if (previous_ice_candidate_pool_size.has_value() &&
276 ice_candidate_pool_size != previous_ice_candidate_pool_size.value()) {
277 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_MODIFICATION,
278 "Can't change candidate pool size after calling "
279 "SetLocalDescription.");
280 }
281
282 return RTCError::OK();
283}
284
285// The simplest (and most future-compatible) way to tell if a config was
286// modified in an invalid way is to copy each property we do support modifying,
287// then use operator==. There are far more properties we don't support modifying
288// than those we do, and more could be added.
289// This helper function accepts a proposed new `configuration` object, an
290// existing configuration and returns a valid, modified, configuration that's
291// based on the existing configuration, with modified properties copied from
292// `configuration`.
293// If the result of creating a modified configuration doesn't pass the above
294// `operator==` test or a call to `ValidateConfiguration()`, then the function
295// will return an error. Otherwise, the return value will be the new config.
296RTCErrorOr<PeerConnectionInterface::RTCConfiguration> ApplyConfiguration(
297 const PeerConnectionInterface::RTCConfiguration& configuration,
298 const PeerConnectionInterface::RTCConfiguration& existing_configuration) {
299 PeerConnectionInterface::RTCConfiguration modified_config =
300 existing_configuration;
301 modified_config.servers = configuration.servers;
302 modified_config.type = configuration.type;
303 modified_config.ice_candidate_pool_size =
304 configuration.ice_candidate_pool_size;
305 modified_config.prune_turn_ports = configuration.prune_turn_ports;
306 modified_config.turn_port_prune_policy = configuration.turn_port_prune_policy;
307 modified_config.surface_ice_candidates_on_ice_transport_type_changed =
308 configuration.surface_ice_candidates_on_ice_transport_type_changed;
309 modified_config.ice_check_min_interval = configuration.ice_check_min_interval;
310 modified_config.ice_check_interval_strong_connectivity =
311 configuration.ice_check_interval_strong_connectivity;
312 modified_config.ice_check_interval_weak_connectivity =
313 configuration.ice_check_interval_weak_connectivity;
314 modified_config.ice_unwritable_timeout = configuration.ice_unwritable_timeout;
315 modified_config.ice_unwritable_min_checks =
316 configuration.ice_unwritable_min_checks;
317 modified_config.ice_inactive_timeout = configuration.ice_inactive_timeout;
318 modified_config.stun_candidate_keepalive_interval =
319 configuration.stun_candidate_keepalive_interval;
320 modified_config.turn_customizer = configuration.turn_customizer;
321 modified_config.network_preference = configuration.network_preference;
322 modified_config.active_reset_srtp_params =
323 configuration.active_reset_srtp_params;
324 modified_config.turn_logging_id = configuration.turn_logging_id;
Tommiaea49c92023-10-22 11:00:14325 modified_config.stable_writable_connection_ping_interval_ms =
326 configuration.stable_writable_connection_ping_interval_ms;
327 if (configuration != modified_config) {
328 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_MODIFICATION,
329 "Modifying the configuration in an unsupported way.");
330 }
331
332 RTCError err = ValidateConfiguration(modified_config);
333 if (!err.ok()) {
334 return err;
335 }
336
337 return modified_config;
338}
339
Harald Alvestrand62166932020-10-26 08:30:41340bool HasRtcpMuxEnabled(const cricket::ContentInfo* content) {
341 return content->media_description()->rtcp_mux();
342}
343
Tommic3257d02021-02-10 17:40:08344bool DtlsEnabled(const PeerConnectionInterface::RTCConfiguration& configuration,
345 const PeerConnectionFactoryInterface::Options& options,
346 const PeerConnectionDependencies& dependencies) {
347 if (options.disable_encryption)
348 return false;
349
350 // Enable DTLS by default if we have an identity store or a certificate.
Harald Alvestrand8c371f22024-01-30 07:39:42351 return (dependencies.cert_generator || !configuration.certificates.empty());
Tommic3257d02021-02-10 17:40:08352}
353
Tommiaea49c92023-10-22 11:00:14354// Calls `ParseIceServersOrError` to extract ice server information from the
355// `configuration` and then validates the extracted configuration. For a
356// non-empty list of servers, usage gets recorded via `usage_pattern`.
357RTCError ParseAndValidateIceServersFromConfiguration(
358 const PeerConnectionInterface::RTCConfiguration& configuration,
359 cricket::ServerAddresses& stun_servers,
360 std::vector<cricket::RelayServerConfig>& turn_servers,
361 UsagePattern& usage_pattern) {
362 RTC_DCHECK(stun_servers.empty());
363 RTC_DCHECK(turn_servers.empty());
364 RTCError err = ParseIceServersOrError(configuration.servers, &stun_servers,
365 &turn_servers);
366 if (!err.ok()) {
367 return err;
368 }
369
370 // Restrict number of TURN servers.
371 if (turn_servers.size() > cricket::kMaxTurnServers) {
372 RTC_LOG(LS_WARNING) << "Number of configured TURN servers is "
373 << turn_servers.size()
374 << " which exceeds the maximum allowed number of "
375 << cricket::kMaxTurnServers;
376 turn_servers.resize(cricket::kMaxTurnServers);
377 }
378
379 // Add the turn logging id to all turn servers
380 for (cricket::RelayServerConfig& turn_server : turn_servers) {
381 turn_server.turn_logging_id = configuration.turn_logging_id;
382 }
383
384 // Note if STUN or TURN servers were supplied.
385 if (!stun_servers.empty()) {
386 usage_pattern.NoteUsageEvent(UsageEvent::STUN_SERVER_ADDED);
387 }
388 if (!turn_servers.empty()) {
389 usage_pattern.NoteUsageEvent(UsageEvent::TURN_SERVER_ADDED);
390 }
391 return RTCError::OK();
392}
393
Steve Anton75737c02017-11-06 18:37:17394} // namespace
395
deadbeef293e9262017-01-11 20:28:30396bool PeerConnectionInterface::RTCConfiguration::operator==(
397 const PeerConnectionInterface::RTCConfiguration& o) const {
398 // This static_assert prevents us from accidentally breaking operator==.
Steve Anton300bf8e2017-07-14 17:13:10399 // Note: Order matters! Fields must be ordered the same as RTCConfiguration.
deadbeef293e9262017-01-11 20:28:30400 struct stuff_being_tested_for_equality {
Magnus Jedvert3beb2072017-07-14 14:23:56401 IceServers servers;
Steve Anton300bf8e2017-07-14 17:13:10402 IceTransportsType type;
deadbeef293e9262017-01-11 20:28:30403 BundlePolicy bundle_policy;
404 RtcpMuxPolicy rtcp_mux_policy;
Steve Anton300bf8e2017-07-14 17:13:10405 std::vector<rtc::scoped_refptr<rtc::RTCCertificate>> certificates;
406 int ice_candidate_pool_size;
Steve Anton300bf8e2017-07-14 17:13:10407 bool disable_ipv6_on_wifi;
deadbeefd21eab3e2017-07-26 23:50:11408 int max_ipv6_networks;
Daniel Lazarenko2870b0a2018-01-25 09:30:22409 bool disable_link_local_networks;
Florent Castelli8037fc62024-08-29 13:00:40410 std::optional<int> screencast_min_bitrate;
deadbeef293e9262017-01-11 20:28:30411 TcpCandidatePolicy tcp_candidate_policy;
412 CandidateNetworkPolicy candidate_network_policy;
413 int audio_jitter_buffer_max_packets;
414 bool audio_jitter_buffer_fast_accelerate;
Jakob Ivarsson10403ae2018-11-27 14:45:20415 int audio_jitter_buffer_min_delay_ms;
deadbeef293e9262017-01-11 20:28:30416 int ice_connection_receiving_timeout;
417 int ice_backup_candidate_pair_ping_interval;
418 ContinualGatheringPolicy continual_gathering_policy;
deadbeef293e9262017-01-11 20:28:30419 bool prioritize_most_likely_ice_candidate_pairs;
420 struct cricket::MediaConfig media_config;
deadbeef293e9262017-01-11 20:28:30421 bool prune_turn_ports;
Honghai Zhangf8998cf2019-10-14 18:27:50422 PortPrunePolicy turn_port_prune_policy;
deadbeef293e9262017-01-11 20:28:30423 bool presume_writable_when_fully_relayed;
424 bool enable_ice_renomination;
425 bool redetermine_role_on_ice_restart;
Qingsi Wang1fe119f2019-05-31 23:55:33426 bool surface_ice_candidates_on_ice_transport_type_changed;
Florent Castelli8037fc62024-08-29 13:00:40427 std::optional<int> ice_check_interval_strong_connectivity;
428 std::optional<int> ice_check_interval_weak_connectivity;
429 std::optional<int> ice_check_min_interval;
430 std::optional<int> ice_unwritable_timeout;
431 std::optional<int> ice_unwritable_min_checks;
432 std::optional<int> ice_inactive_timeout;
433 std::optional<int> stun_candidate_keepalive_interval;
Harald Alvestranda6544372023-11-13 09:33:56434 TurnCustomizer* turn_customizer;
Steve Anton79e79602017-11-20 18:25:56435 SdpSemantics sdp_semantics;
Florent Castelli8037fc62024-08-29 13:00:40436 std::optional<rtc::AdapterType> network_preference;
Zhi Huangb57e1692018-06-12 18:41:11437 bool active_reset_srtp_params;
Florent Castelli8037fc62024-08-29 13:00:40438 std::optional<CryptoOptions> crypto_options;
Johannes Kron89f874e2018-11-12 09:25:48439 bool offer_extmap_allow_mixed;
Jonas Oreland3c028422019-08-22 14:16:35440 std::string turn_logging_id;
Eldar Rello5ab79e62019-10-09 15:29:44441 bool enable_implicit_rollback;
Florent Castelli8037fc62024-08-29 13:00:40442 std::optional<int> report_usage_pattern_delay_ms;
443 std::optional<int> stable_writable_connection_ping_interval_ms;
Harald Alvestranda6544372023-11-13 09:33:56444 VpnPreference vpn_preference;
Jonas Oreland2ee0e642021-08-25 13:43:02445 std::vector<rtc::NetworkMask> vpn_list;
Niels Möller73d07742021-12-02 12:58:01446 PortAllocatorConfig port_allocator_config;
Florent Castelli8037fc62024-08-29 13:00:40447 std::optional<TimeDelta> pacer_burst_interval;
deadbeef293e9262017-01-11 20:28:30448 };
449 static_assert(sizeof(stuff_being_tested_for_equality) == sizeof(*this),
450 "Did you add something to RTCConfiguration and forget to "
451 "update operator==?");
452 return type == o.type && servers == o.servers &&
453 bundle_policy == o.bundle_policy &&
454 rtcp_mux_policy == o.rtcp_mux_policy &&
455 tcp_candidate_policy == o.tcp_candidate_policy &&
456 candidate_network_policy == o.candidate_network_policy &&
457 audio_jitter_buffer_max_packets == o.audio_jitter_buffer_max_packets &&
458 audio_jitter_buffer_fast_accelerate ==
459 o.audio_jitter_buffer_fast_accelerate &&
Jakob Ivarsson10403ae2018-11-27 14:45:20460 audio_jitter_buffer_min_delay_ms ==
461 o.audio_jitter_buffer_min_delay_ms &&
deadbeef293e9262017-01-11 20:28:30462 ice_connection_receiving_timeout ==
463 o.ice_connection_receiving_timeout &&
464 ice_backup_candidate_pair_ping_interval ==
465 o.ice_backup_candidate_pair_ping_interval &&
466 continual_gathering_policy == o.continual_gathering_policy &&
467 certificates == o.certificates &&
468 prioritize_most_likely_ice_candidate_pairs ==
469 o.prioritize_most_likely_ice_candidate_pairs &&
Henrik Boström24e03372022-10-27 11:49:10470 media_config == o.media_config &&
zhihuangb09b3f92017-03-07 22:40:51471 disable_ipv6_on_wifi == o.disable_ipv6_on_wifi &&
deadbeefd21eab3e2017-07-26 23:50:11472 max_ipv6_networks == o.max_ipv6_networks &&
Daniel Lazarenko2870b0a2018-01-25 09:30:22473 disable_link_local_networks == o.disable_link_local_networks &&
deadbeef293e9262017-01-11 20:28:30474 screencast_min_bitrate == o.screencast_min_bitrate &&
deadbeef293e9262017-01-11 20:28:30475 ice_candidate_pool_size == o.ice_candidate_pool_size &&
476 prune_turn_ports == o.prune_turn_ports &&
Honghai Zhangf8998cf2019-10-14 18:27:50477 turn_port_prune_policy == o.turn_port_prune_policy &&
deadbeef293e9262017-01-11 20:28:30478 presume_writable_when_fully_relayed ==
479 o.presume_writable_when_fully_relayed &&
480 enable_ice_renomination == o.enable_ice_renomination &&
skvlad51072462017-02-02 19:50:14481 redetermine_role_on_ice_restart == o.redetermine_role_on_ice_restart &&
Qingsi Wang1fe119f2019-05-31 23:55:33482 surface_ice_candidates_on_ice_transport_type_changed ==
483 o.surface_ice_candidates_on_ice_transport_type_changed &&
Qingsi Wange6826d22018-03-08 22:55:14484 ice_check_interval_strong_connectivity ==
485 o.ice_check_interval_strong_connectivity &&
486 ice_check_interval_weak_connectivity ==
487 o.ice_check_interval_weak_connectivity &&
Steve Anton300bf8e2017-07-14 17:13:10488 ice_check_min_interval == o.ice_check_min_interval &&
Qingsi Wang22e623a2018-03-13 17:53:57489 ice_unwritable_timeout == o.ice_unwritable_timeout &&
490 ice_unwritable_min_checks == o.ice_unwritable_min_checks &&
Jiawei Ou9d4fd5552018-12-07 07:30:17491 ice_inactive_timeout == o.ice_inactive_timeout &&
Qingsi Wangdb53f8e2018-02-20 22:45:49492 stun_candidate_keepalive_interval ==
493 o.stun_candidate_keepalive_interval &&
Steve Anton79e79602017-11-20 18:25:56494 turn_customizer == o.turn_customizer &&
Qingsi Wang9a5c6f82018-02-01 18:38:40495 sdp_semantics == o.sdp_semantics &&
Zhi Huangb57e1692018-06-12 18:41:11496 network_preference == o.network_preference &&
Piotr (Peter) Slatalae0c2e972018-10-08 16:43:21497 active_reset_srtp_params == o.active_reset_srtp_params &&
Johannes Kron89f874e2018-11-12 09:25:48498 crypto_options == o.crypto_options &&
Jonas Oreland3c028422019-08-22 14:16:35499 offer_extmap_allow_mixed == o.offer_extmap_allow_mixed &&
Eldar Rello5ab79e62019-10-09 15:29:44500 turn_logging_id == o.turn_logging_id &&
philipel16cec3b2019-10-25 10:23:02501 enable_implicit_rollback == o.enable_implicit_rollback &&
Derek Bailey6c127a12021-04-15 19:42:41502 report_usage_pattern_delay_ms == o.report_usage_pattern_delay_ms &&
503 stable_writable_connection_ping_interval_ms ==
Jonas Orelandc8fa1ee2021-08-25 06:58:04504 o.stable_writable_connection_ping_interval_ms &&
Niels Möller73d07742021-12-02 12:58:01505 vpn_preference == o.vpn_preference && vpn_list == o.vpn_list &&
506 port_allocator_config.min_port == o.port_allocator_config.min_port &&
507 port_allocator_config.max_port == o.port_allocator_config.max_port &&
Henrik Boströmcf2856b2022-11-15 08:23:19508 port_allocator_config.flags == o.port_allocator_config.flags &&
509 pacer_burst_interval == o.pacer_burst_interval;
deadbeef293e9262017-01-11 20:28:30510}
511
512bool PeerConnectionInterface::RTCConfiguration::operator!=(
513 const PeerConnectionInterface::RTCConfiguration& o) const {
514 return !(*this == o);
deadbeef3edec7c2016-12-10 19:44:26515}
516
Harald Alvestranda3dd7722020-11-27 08:05:42517RTCErrorOr<rtc::scoped_refptr<PeerConnection>> PeerConnection::Create(
Danil Chapovalov3bdb49b2023-11-30 07:59:39518 const Environment& env,
Harald Alvestrand62166932020-10-26 08:30:41519 rtc::scoped_refptr<ConnectionContext> context,
Harald Alvestrand4da4a872020-11-04 10:34:21520 const PeerConnectionFactoryInterface::Options& options,
Harald Alvestrand62166932020-10-26 08:30:41521 std::unique_ptr<Call> call,
522 const PeerConnectionInterface::RTCConfiguration& configuration,
523 PeerConnectionDependencies dependencies) {
Henrik Boström62995db2022-01-03 08:58:10524 // TODO(https://crbug.com/webrtc/13528): Remove support for kPlanB.
Henrik Boström6d2fe892022-01-21 08:51:07525 if (configuration.sdp_semantics == SdpSemantics::kPlanB_DEPRECATED) {
526 RTC_LOG(LS_WARNING)
527 << "PeerConnection constructed with legacy SDP semantics!";
528 }
Henrik Boström62995db2022-01-03 08:58:10529
Harald Alvestrand62166932020-10-26 08:30:41530 RTCError config_error = cricket::P2PTransportChannel::ValidateIceConfig(
531 ParseIceConfig(configuration));
532 if (!config_error.ok()) {
Harald Alvestranda3dd7722020-11-27 08:05:42533 RTC_LOG(LS_ERROR) << "Invalid ICE configuration: "
534 << config_error.message();
535 return config_error;
Harald Alvestrand62166932020-10-26 08:30:41536 }
537
538 if (!dependencies.allocator) {
539 RTC_LOG(LS_ERROR)
540 << "PeerConnection initialized without a PortAllocator? "
541 "This shouldn't happen if using PeerConnectionFactory.";
Harald Alvestranda3dd7722020-11-27 08:05:42542 return RTCError(
543 RTCErrorType::INVALID_PARAMETER,
544 "Attempt to create a PeerConnection without a PortAllocatorFactory");
Harald Alvestrand62166932020-10-26 08:30:41545 }
546
547 if (!dependencies.observer) {
548 // TODO(deadbeef): Why do we do this?
549 RTC_LOG(LS_ERROR) << "PeerConnection initialized without a "
550 "PeerConnectionObserver";
Harald Alvestranda3dd7722020-11-27 08:05:42551 return RTCError(RTCErrorType::INVALID_PARAMETER,
552 "Attempt to create a PeerConnection without an observer");
Harald Alvestrand62166932020-10-26 08:30:41553 }
554
555 bool is_unified_plan =
556 configuration.sdp_semantics == SdpSemantics::kUnifiedPlan;
Tommic3257d02021-02-10 17:40:08557 bool dtls_enabled = DtlsEnabled(configuration, options, dependencies);
Harald Alvestrand0ccfbd22021-04-08 07:25:04558
Harald Alvestrand4d25a772023-08-25 11:07:28559 if (!dependencies.async_dns_resolver_factory) {
Harald Alvestrand4d25a772023-08-25 11:07:28560 dependencies.async_dns_resolver_factory =
561 std::make_unique<BasicAsyncDnsResolverFactory>();
Harald Alvestrand0ccfbd22021-04-08 07:25:04562 }
563
Harald Alvestrandfd9a8f82020-10-26 14:17:02564 // The PeerConnection constructor consumes some, but not all, dependencies.
Tommi87f70902021-04-27 12:43:08565 auto pc = rtc::make_ref_counted<PeerConnection>(
Danil Chapovalov3bdb49b2023-11-30 07:59:39566 env, context, options, is_unified_plan, std::move(call), dependencies,
567 dtls_enabled);
Harald Alvestranda3dd7722020-11-27 08:05:42568 RTCError init_error = pc->Initialize(configuration, std::move(dependencies));
569 if (!init_error.ok()) {
570 RTC_LOG(LS_ERROR) << "PeerConnection initialization failed";
571 return init_error;
Harald Alvestrand62166932020-10-26 08:30:41572 }
573 return pc;
574}
575
Harald Alvestrand4da4a872020-11-04 10:34:21576PeerConnection::PeerConnection(
Danil Chapovalov3bdb49b2023-11-30 07:59:39577 const Environment& env,
Harald Alvestrand4da4a872020-11-04 10:34:21578 rtc::scoped_refptr<ConnectionContext> context,
579 const PeerConnectionFactoryInterface::Options& options,
580 bool is_unified_plan,
Harald Alvestrand4da4a872020-11-04 10:34:21581 std::unique_ptr<Call> call,
Tommic3257d02021-02-10 17:40:08582 PeerConnectionDependencies& dependencies,
583 bool dtls_enabled)
Danil Chapovalov3bdb49b2023-11-30 07:59:39584 : env_(env),
585 context_(context),
Harald Alvestrand4da4a872020-11-04 10:34:21586 options_(options),
Harald Alvestrandfd9a8f82020-10-26 14:17:02587 observer_(dependencies.observer),
Harald Alvestrand62166932020-10-26 08:30:41588 is_unified_plan_(is_unified_plan),
Harald Alvestrand0ccfbd22021-04-08 07:25:04589 async_dns_resolver_factory_(
590 std::move(dependencies.async_dns_resolver_factory)),
Harald Alvestrandfd9a8f82020-10-26 14:17:02591 port_allocator_(std::move(dependencies.allocator)),
592 ice_transport_factory_(std::move(dependencies.ice_transport_factory)),
593 tls_cert_verifier_(std::move(dependencies.tls_cert_verifier)),
Karl Wiberg6cab5c82019-03-26 08:57:01594 call_(std::move(call)),
Tommiaf27d4e2023-10-24 21:49:31595 worker_thread_safety_(PendingTaskSafetyFlag::CreateAttachedToTaskQueue(
596 /*alive=*/call_ != nullptr,
597 worker_thread())),
Henrik Boström79b69802019-07-18 09:16:56598 call_ptr_(call_.get()),
Tomas Gunnarsson97a387d2021-03-29 19:04:29599 // RFC 3264: The numeric value of the session id and version in the
600 // o line MUST be representable with a "64 bit signed integer".
Artem Titov880fa812021-07-30 20:30:23601 // Due to this constraint session id `session_id_` is max limited to
Tomas Gunnarsson97a387d2021-03-29 19:04:29602 // LLONG_MAX.
603 session_id_(rtc::ToString(rtc::CreateRandomId64() & LLONG_MAX)),
Tommic3257d02021-02-10 17:40:08604 dtls_enabled_(dtls_enabled),
Harald Alvestrand1090e442020-10-05 07:01:09605 data_channel_controller_(this),
Lahiru Ginnaliya Gamathige70f9e242021-01-28 07:32:46606 message_handler_(signaling_thread()),
Danil Chapovalov49c35d32023-11-27 11:55:39607 weak_factory_(this) {
Danil Chapovalov3bdb49b2023-11-30 07:59:39608 // Field trials specific to the peerconnection should be owned by the `env`,
609 RTC_DCHECK(dependencies.trials == nullptr);
Danil Chapovalov49c35d32023-11-27 11:55:39610}
henrike@webrtc.org28e20752013-07-10 00:45:36611
612PeerConnection::~PeerConnection() {
Peter Boström1a9d6152015-12-08 21:15:17613 TRACE_EVENT0("webrtc", "PeerConnection::~PeerConnection");
Steve Anton4171afb2017-11-20 18:20:22614 RTC_DCHECK_RUN_ON(signaling_thread());
615
Harald Alvestrand9cd199d2020-10-27 07:10:43616 if (sdp_handler_) {
617 sdp_handler_->PrepareForShutdown();
618 }
Henrik Boströma3728d32019-10-28 11:09:49619
Tommi94774d42023-04-24 09:31:45620 // In case `Close()` wasn't called, always make sure the controller cancels
621 // potentially pending operations.
622 data_channel_controller_.PrepareForShutdown();
623
Steve Anton8af21862017-12-15 19:20:13624 // Need to stop transceivers before destroying the stats collector because
Henrik Boströmf7859892022-07-04 12:36:37625 // AudioRtpSender has a reference to the LegacyStatsCollector it will update
626 // when stopping.
Harald Alvestrande15fb152020-10-19 13:28:05627 if (rtp_manager()) {
628 for (const auto& transceiver : rtp_manager()->transceivers()->List()) {
629 transceiver->StopInternal();
630 }
Steve Anton8af21862017-12-15 19:20:13631 }
Steve Anton4171afb2017-11-20 18:20:22632
Henrik Boströmf7859892022-07-04 12:36:37633 legacy_stats_.reset(nullptr);
hbosb78306a2016-12-19 13:06:57634 if (stats_collector_) {
635 stats_collector_->WaitForPendingRequest();
636 stats_collector_ = nullptr;
637 }
Steve Anton75737c02017-11-06 18:37:17638
Harald Alvestrand9cd199d2020-10-27 07:10:43639 if (sdp_handler_) {
640 // Don't destroy BaseChannels until after stats has been cleaned up so that
641 // the last stats request can still read from the channels.
Tommi29190752023-10-21 14:50:09642 sdp_handler_->DestroyMediaChannels();
Harald Alvestrand9cd199d2020-10-27 07:10:43643 RTC_LOG(LS_INFO) << "Session: " << session_id() << " is destroyed.";
Harald Alvestrand9cd199d2020-10-27 07:10:43644 sdp_handler_->ResetSessionDescFactory();
645 }
Steve Anton75737c02017-11-06 18:37:17646
Tomas Gunnarsson92eebef2021-02-10 12:05:44647 // port_allocator_ and transport_controller_ live on the network thread and
648 // should be destroyed there.
Harald Alvestrandbc32c562022-02-09 12:08:47649 transport_controller_copy_ = nullptr;
Danil Chapovalov9e09a1f2022-09-08 16:38:10650 network_thread()->BlockingCall([this] {
Karl Wibergfb3be392019-03-22 13:13:22651 RTC_DCHECK_RUN_ON(network_thread());
Tommib00d63c2023-04-12 17:49:53652 TeardownDataChannelTransport_n(RTCError::OK());
Tomas Gunnarsson92eebef2021-02-10 12:05:44653 transport_controller_.reset();
Karl Wibergfb3be392019-03-22 13:13:22654 port_allocator_.reset();
Tommic3257d02021-02-10 17:40:08655 if (network_thread_safety_)
Tomas Gunnarsson92eebef2021-02-10 12:05:44656 network_thread_safety_->SetNotAlive();
Karl Wibergfb3be392019-03-22 13:13:22657 });
Tommi29190752023-10-21 14:50:09658 sctp_mid_s_.reset();
659 SetSctpTransportName("");
Tomas Gunnarssond69e0702021-04-07 13:14:43660
Danil Chapovalov49c35d32023-11-27 11:55:39661 // call_ must be destroyed on the worker thread.
Danil Chapovalov9e09a1f2022-09-08 16:38:10662 worker_thread()->BlockingCall([this] {
Karl Wibergb03ab712019-02-14 10:59:57663 RTC_DCHECK_RUN_ON(worker_thread());
Tommic3257d02021-02-10 17:40:08664 worker_thread_safety_->SetNotAlive();
eladalon248fd4f2017-09-06 12:18:15665 call_.reset();
eladalon248fd4f2017-09-06 12:18:15666 });
Tommi52719652023-04-04 09:59:55667
668 data_channel_controller_.PrepareForShutdown();
henrike@webrtc.org28e20752013-07-10 00:45:36669}
670
Harald Alvestranda3dd7722020-11-27 08:05:42671RTCError PeerConnection::Initialize(
buildbot@webrtc.org41451d42014-05-03 05:39:45672 const PeerConnectionInterface::RTCConfiguration& configuration,
Benjamin Wrightcab588882018-05-02 22:12:47673 PeerConnectionDependencies dependencies) {
Karl Wiberg744310f2019-02-14 09:18:56674 RTC_DCHECK_RUN_ON(signaling_thread());
Peter Boström1a9d6152015-12-08 21:15:17675 TRACE_EVENT0("webrtc", "PeerConnection::Initialize");
Steve Anton038834f2017-07-14 22:59:59676
Harald Alvestrandb2a74782018-06-28 11:54:07677 cricket::ServerAddresses stun_servers;
678 std::vector<cricket::RelayServerConfig> turn_servers;
Tommiaea49c92023-10-22 11:00:14679 RTCError parse_error = ParseAndValidateIceServersFromConfiguration(
680 configuration, stun_servers, turn_servers, usage_pattern_);
Philipp Hancke633dc2f2022-10-12 08:16:14681 if (!parse_error.ok()) {
682 return parse_error;
Harald Alvestrandb2a74782018-06-28 11:54:07683 }
684
Tommic3257d02021-02-10 17:40:08685 // Network thread initialization.
Jared Siskinbceec842023-04-20 21:10:51686 transport_controller_copy_ = network_thread()->BlockingCall([&] {
687 RTC_DCHECK_RUN_ON(network_thread());
688 network_thread_safety_ = PendingTaskSafetyFlag::Create();
689 InitializePortAllocatorResult pa_result =
690 InitializePortAllocator_n(stun_servers, turn_servers, configuration);
691 // Send information about IPv4/IPv6 status.
692 PeerConnectionAddressFamilyCounter address_family =
693 pa_result.enable_ipv6 ? kPeerConnection_IPv6 : kPeerConnection_IPv4;
694 RTC_HISTOGRAM_ENUMERATION("WebRTC.PeerConnection.IPMetrics", address_family,
695 kPeerConnectionAddressFamilyCounter_Max);
696 return InitializeTransportController_n(configuration, dependencies);
697 });
Lahiru Ginnaliya Gamathigee99c68d2020-09-30 21:33:45698
Steve Antonba818672017-11-06 18:21:57699 configuration_ = configuration;
700
Henrik Boströmf7859892022-07-04 12:36:37701 legacy_stats_ = std::make_unique<LegacyStatsCollector>(this);
Harald Alvestrande15fb152020-10-19 13:28:05702 stats_collector_ = RTCStatsCollector::Create(this);
703
Harald Alvestrand66c40362022-01-28 17:41:30704 sdp_handler_ = SdpOfferAnswerHandler::Create(this, configuration,
Niels Möllerafb246b2022-04-20 12:26:50705 dependencies, context_.get());
Harald Alvestrand9cd199d2020-10-27 07:10:43706
Artem Titovc6c02ef2022-05-09 08:30:09707 rtp_manager_ = std::make_unique<RtpTransmissionManager>(
Florent Castellic5b9a602024-09-03 09:13:23708 env_, IsUnifiedPlan(), context_.get(), &usage_pattern_, observer_,
Henrik Boströmf7859892022-07-04 12:36:37709 legacy_stats_.get(), [this]() {
Artem Titovc6c02ef2022-05-09 08:30:09710 RTC_DCHECK_RUN_ON(signaling_thread());
711 sdp_handler_->UpdateNegotiationNeeded();
712 });
Harald Alvestrande15fb152020-10-19 13:28:05713
Artem Titovc6c02ef2022-05-09 08:30:09714 // Add default audio/video transceivers for Plan B SDP.
715 if (!IsUnifiedPlan()) {
716 rtp_manager()->transceivers()->Add(
717 RtpTransceiverProxyWithInternal<RtpTransceiver>::Create(
Harald Alvestrandc3fa7c32022-05-22 10:57:01718 signaling_thread(), rtc::make_ref_counted<RtpTransceiver>(
719 cricket::MEDIA_TYPE_AUDIO, context())));
Artem Titovc6c02ef2022-05-09 08:30:09720 rtp_manager()->transceivers()->Add(
721 RtpTransceiverProxyWithInternal<RtpTransceiver>::Create(
Harald Alvestrandc3fa7c32022-05-22 10:57:01722 signaling_thread(), rtc::make_ref_counted<RtpTransceiver>(
723 cricket::MEDIA_TYPE_VIDEO, context())));
Steve Anton4171afb2017-11-20 18:20:22724 }
Harald Alvestrand763f5a92020-10-22 10:39:40725
Harald Alvestrand62166932020-10-26 08:30:41726 int delay_ms = configuration.report_usage_pattern_delay_ms
727 ? *configuration.report_usage_pattern_delay_ms
728 : REPORT_USAGE_PATTERN_DELAY_MS;
Harald Alvestrand1090e442020-10-05 07:01:09729 message_handler_.RequestUsagePatternReport(
730 [this]() {
731 RTC_DCHECK_RUN_ON(signaling_thread());
732 ReportUsagePattern();
733 },
734 delay_ms);
Jonas Orelanda3aa9bd2019-04-17 05:38:40735
Harald Alvestranda3dd7722020-11-27 08:05:42736 return RTCError::OK();
henrike@webrtc.org28e20752013-07-10 00:45:36737}
738
Harald Alvestrandbc32c562022-02-09 12:08:47739JsepTransportController* PeerConnection::InitializeTransportController_n(
Tommic3257d02021-02-10 17:40:08740 const RTCConfiguration& configuration,
741 const PeerConnectionDependencies& dependencies) {
742 JsepTransportController::Config config;
743 config.redetermine_role_on_ice_restart =
744 configuration.redetermine_role_on_ice_restart;
745 config.ssl_max_version = options_.ssl_max_version;
746 config.disable_encryption = options_.disable_encryption;
747 config.bundle_policy = configuration.bundle_policy;
748 config.rtcp_mux_policy = configuration.rtcp_mux_policy;
749 // TODO(bugs.webrtc.org/9891) - Remove options_.crypto_options then remove
750 // this stub.
751 config.crypto_options = configuration.crypto_options.has_value()
752 ? *configuration.crypto_options
753 : options_.crypto_options;
754 config.transport_observer = this;
755 config.rtcp_handler = InitializeRtcpCallback();
Per Ke1e94ad2023-03-30 14:53:59756 config.un_demuxable_packet_handler = InitializeUnDemuxablePacketHandler();
Danil Chapovalov3bdb49b2023-11-30 07:59:39757 config.event_log = &env_.event_log();
Tommic3257d02021-02-10 17:40:08758#if defined(ENABLE_EXTERNAL_AUTH)
759 config.enable_external_auth = true;
760#endif
761 config.active_reset_srtp_params = configuration.active_reset_srtp_params;
762
763 // DTLS has to be enabled to use SCTP.
Florent Castelli516e2842021-04-19 13:29:50764 if (dtls_enabled_) {
Tommic3257d02021-02-10 17:40:08765 config.sctp_factory = context_->sctp_transport_factory();
766 }
767
768 config.ice_transport_factory = ice_transport_factory_.get();
769 config.on_dtls_handshake_error_ =
770 [weak_ptr = weak_factory_.GetWeakPtr()](rtc::SSLHandshakeError s) {
771 if (weak_ptr) {
772 weak_ptr->OnTransportControllerDtlsHandshakeError(s);
773 }
774 };
775
Harald Alvestrand53086522024-08-25 16:43:08776 transport_controller_.reset(
777 new JsepTransportController(env_, network_thread(), port_allocator_.get(),
778 async_dns_resolver_factory_.get(),
779 payload_type_picker_, std::move(config)));
Tommic3257d02021-02-10 17:40:08780
781 transport_controller_->SubscribeIceConnectionState(
782 [this](cricket::IceConnectionState s) {
783 RTC_DCHECK_RUN_ON(network_thread());
784 signaling_thread()->PostTask(
Danil Chapovalova30439b2022-07-07 08:08:49785 SafeTask(signaling_thread_safety_.flag(), [this, s]() {
Tommic3257d02021-02-10 17:40:08786 RTC_DCHECK_RUN_ON(signaling_thread());
787 OnTransportControllerConnectionState(s);
788 }));
789 });
790 transport_controller_->SubscribeConnectionState(
791 [this](PeerConnectionInterface::PeerConnectionState s) {
792 RTC_DCHECK_RUN_ON(network_thread());
793 signaling_thread()->PostTask(
Danil Chapovalova30439b2022-07-07 08:08:49794 SafeTask(signaling_thread_safety_.flag(), [this, s]() {
Tommic3257d02021-02-10 17:40:08795 RTC_DCHECK_RUN_ON(signaling_thread());
796 SetConnectionState(s);
797 }));
798 });
799 transport_controller_->SubscribeStandardizedIceConnectionState(
800 [this](PeerConnectionInterface::IceConnectionState s) {
801 RTC_DCHECK_RUN_ON(network_thread());
802 signaling_thread()->PostTask(
Danil Chapovalova30439b2022-07-07 08:08:49803 SafeTask(signaling_thread_safety_.flag(), [this, s]() {
Tommic3257d02021-02-10 17:40:08804 RTC_DCHECK_RUN_ON(signaling_thread());
805 SetStandardizedIceConnectionState(s);
806 }));
807 });
808 transport_controller_->SubscribeIceGatheringState(
809 [this](cricket::IceGatheringState s) {
810 RTC_DCHECK_RUN_ON(network_thread());
811 signaling_thread()->PostTask(
Danil Chapovalova30439b2022-07-07 08:08:49812 SafeTask(signaling_thread_safety_.flag(), [this, s]() {
Tommic3257d02021-02-10 17:40:08813 RTC_DCHECK_RUN_ON(signaling_thread());
814 OnTransportControllerGatheringState(s);
815 }));
816 });
817 transport_controller_->SubscribeIceCandidateGathered(
818 [this](const std::string& transport,
819 const std::vector<cricket::Candidate>& candidates) {
820 RTC_DCHECK_RUN_ON(network_thread());
821 signaling_thread()->PostTask(
Danil Chapovalova30439b2022-07-07 08:08:49822 SafeTask(signaling_thread_safety_.flag(),
823 [this, t = transport, c = candidates]() {
824 RTC_DCHECK_RUN_ON(signaling_thread());
825 OnTransportControllerCandidatesGathered(t, c);
826 }));
Tommic3257d02021-02-10 17:40:08827 });
828 transport_controller_->SubscribeIceCandidateError(
829 [this](const cricket::IceCandidateErrorEvent& event) {
830 RTC_DCHECK_RUN_ON(network_thread());
Danil Chapovalova30439b2022-07-07 08:08:49831 signaling_thread()->PostTask(
832 SafeTask(signaling_thread_safety_.flag(), [this, event = event]() {
Tommic3257d02021-02-10 17:40:08833 RTC_DCHECK_RUN_ON(signaling_thread());
834 OnTransportControllerCandidateError(event);
835 }));
836 });
837 transport_controller_->SubscribeIceCandidatesRemoved(
838 [this](const std::vector<cricket::Candidate>& c) {
839 RTC_DCHECK_RUN_ON(network_thread());
840 signaling_thread()->PostTask(
Danil Chapovalova30439b2022-07-07 08:08:49841 SafeTask(signaling_thread_safety_.flag(), [this, c = c]() {
Tommic3257d02021-02-10 17:40:08842 RTC_DCHECK_RUN_ON(signaling_thread());
843 OnTransportControllerCandidatesRemoved(c);
844 }));
845 });
846 transport_controller_->SubscribeIceCandidatePairChanged(
847 [this](const cricket::CandidatePairChangeEvent& event) {
848 RTC_DCHECK_RUN_ON(network_thread());
Danil Chapovalova30439b2022-07-07 08:08:49849 signaling_thread()->PostTask(
850 SafeTask(signaling_thread_safety_.flag(), [this, event = event]() {
Tommic3257d02021-02-10 17:40:08851 RTC_DCHECK_RUN_ON(signaling_thread());
852 OnTransportControllerCandidateChanged(event);
853 }));
854 });
855
856 transport_controller_->SetIceConfig(ParseIceConfig(configuration));
Harald Alvestrandbc32c562022-02-09 12:08:47857 return transport_controller_.get();
Tommic3257d02021-02-10 17:40:08858}
859
Yves Gerey665174f2018-06-19 13:03:05860rtc::scoped_refptr<StreamCollectionInterface> PeerConnection::local_streams() {
Karl Wiberg5966c502019-02-21 22:55:09861 RTC_DCHECK_RUN_ON(signaling_thread());
Steve Antonfc853712018-03-01 21:48:58862 RTC_CHECK(!IsUnifiedPlan()) << "local_streams is not available with Unified "
863 "Plan SdpSemantics. Please use GetSenders "
864 "instead.";
Harald Alvestrand9cd199d2020-10-27 07:10:43865 return sdp_handler_->local_streams();
henrike@webrtc.org28e20752013-07-10 00:45:36866}
867
Yves Gerey665174f2018-06-19 13:03:05868rtc::scoped_refptr<StreamCollectionInterface> PeerConnection::remote_streams() {
Karl Wiberg5966c502019-02-21 22:55:09869 RTC_DCHECK_RUN_ON(signaling_thread());
Steve Antonfc853712018-03-01 21:48:58870 RTC_CHECK(!IsUnifiedPlan()) << "remote_streams is not available with Unified "
871 "Plan SdpSemantics. Please use GetReceivers "
872 "instead.";
Harald Alvestrand9cd199d2020-10-27 07:10:43873 return sdp_handler_->remote_streams();
henrike@webrtc.org28e20752013-07-10 00:45:36874}
875
perkj@webrtc.orgc2dd5ee2014-11-04 11:31:29876bool PeerConnection::AddStream(MediaStreamInterface* local_stream) {
Karl Wiberg744310f2019-02-14 09:18:56877 RTC_DCHECK_RUN_ON(signaling_thread());
Steve Antonfc853712018-03-01 21:48:58878 RTC_CHECK(!IsUnifiedPlan()) << "AddStream is not available with Unified Plan "
879 "SdpSemantics. Please use AddTrack instead.";
Peter Boström1a9d6152015-12-08 21:15:17880 TRACE_EVENT0("webrtc", "PeerConnection::AddStream");
Harald Alvestrand35ba0c52022-05-05 07:37:41881 if (!ConfiguredForMedia()) {
882 RTC_LOG(LS_ERROR) << "AddStream: Not configured for media";
883 return false;
884 }
Harald Alvestrand9cd199d2020-10-27 07:10:43885 return sdp_handler_->AddStream(local_stream);
henrike@webrtc.org28e20752013-07-10 00:45:36886}
887
888void PeerConnection::RemoveStream(MediaStreamInterface* local_stream) {
Karl Wiberg744310f2019-02-14 09:18:56889 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand35ba0c52022-05-05 07:37:41890 RTC_DCHECK(ConfiguredForMedia());
Steve Antonfc853712018-03-01 21:48:58891 RTC_CHECK(!IsUnifiedPlan()) << "RemoveStream is not available with Unified "
892 "Plan SdpSemantics. Please use RemoveTrack "
893 "instead.";
Peter Boström1a9d6152015-12-08 21:15:17894 TRACE_EVENT0("webrtc", "PeerConnection::RemoveStream");
Harald Alvestrand9cd199d2020-10-27 07:10:43895 sdp_handler_->RemoveStream(local_stream);
henrike@webrtc.org28e20752013-07-10 00:45:36896}
897
Steve Anton2d6c76a2018-01-06 01:10:52898RTCErrorOr<rtc::scoped_refptr<RtpSenderInterface>> PeerConnection::AddTrack(
Steve Antonf9381f02017-12-14 18:23:57899 rtc::scoped_refptr<MediaStreamTrackInterface> track,
Seth Hampson845e8782018-03-02 19:34:10900 const std::vector<std::string>& stream_ids) {
Jonas Oreland4b2a1062022-10-19 07:24:42901 return AddTrack(std::move(track), stream_ids, nullptr);
902}
903
904RTCErrorOr<rtc::scoped_refptr<RtpSenderInterface>> PeerConnection::AddTrack(
905 rtc::scoped_refptr<MediaStreamTrackInterface> track,
906 const std::vector<std::string>& stream_ids,
907 const std::vector<RtpEncodingParameters>& init_send_encodings) {
908 return AddTrack(std::move(track), stream_ids, &init_send_encodings);
909}
910
911RTCErrorOr<rtc::scoped_refptr<RtpSenderInterface>> PeerConnection::AddTrack(
912 rtc::scoped_refptr<MediaStreamTrackInterface> track,
913 const std::vector<std::string>& stream_ids,
914 const std::vector<RtpEncodingParameters>* init_send_encodings) {
Karl Wiberg744310f2019-02-14 09:18:56915 RTC_DCHECK_RUN_ON(signaling_thread());
Steve Anton2d6c76a2018-01-06 01:10:52916 TRACE_EVENT0("webrtc", "PeerConnection::AddTrack");
Harald Alvestrand35ba0c52022-05-05 07:37:41917 if (!ConfiguredForMedia()) {
918 LOG_AND_RETURN_ERROR(RTCErrorType::UNSUPPORTED_OPERATION,
919 "Not configured for media");
920 }
Steve Antonf9381f02017-12-14 18:23:57921 if (!track) {
922 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER, "Track is null.");
923 }
924 if (!(track->kind() == MediaStreamTrackInterface::kAudioKind ||
925 track->kind() == MediaStreamTrackInterface::kVideoKind)) {
926 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
927 "Track has invalid kind: " + track->kind());
928 }
Steve Antonf9381f02017-12-14 18:23:57929 if (IsClosed()) {
930 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_STATE,
931 "PeerConnection is closed.");
deadbeefe1f9d832016-01-14 23:35:42932 }
Niels Möllerafb246b2022-04-20 12:26:50933 if (rtp_manager()->FindSenderForTrack(track.get())) {
Steve Antonf9381f02017-12-14 18:23:57934 LOG_AND_RETURN_ERROR(
935 RTCErrorType::INVALID_PARAMETER,
936 "Sender already exists for track " + track->id() + ".");
deadbeefe1f9d832016-01-14 23:35:42937 }
Jonas Oreland4b2a1062022-10-19 07:24:42938 auto sender_or_error =
939 rtp_manager()->AddTrack(track, stream_ids, init_send_encodings);
Steve Antonf9381f02017-12-14 18:23:57940 if (sender_or_error.ok()) {
Harald Alvestrand9cd199d2020-10-27 07:10:43941 sdp_handler_->UpdateNegotiationNeeded();
Henrik Boströmf7859892022-07-04 12:36:37942 legacy_stats_->AddTrack(track.get());
Steve Antonf9381f02017-12-14 18:23:57943 }
944 return sender_or_error;
945}
deadbeefe1f9d832016-01-14 23:35:42946
Harald Alvestrand09a0d012022-01-04 19:42:07947RTCError PeerConnection::RemoveTrackOrError(
Steve Antonf9381f02017-12-14 18:23:57948 rtc::scoped_refptr<RtpSenderInterface> sender) {
Karl Wiberg744310f2019-02-14 09:18:56949 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand35ba0c52022-05-05 07:37:41950 if (!ConfiguredForMedia()) {
951 LOG_AND_RETURN_ERROR(RTCErrorType::UNSUPPORTED_OPERATION,
952 "Not configured for media");
953 }
Steve Antonf9381f02017-12-14 18:23:57954 if (!sender) {
955 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER, "Sender is null.");
956 }
deadbeefe1f9d832016-01-14 23:35:42957 if (IsClosed()) {
Steve Antonf9381f02017-12-14 18:23:57958 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_STATE,
959 "PeerConnection is closed.");
deadbeefe1f9d832016-01-14 23:35:42960 }
Steve Antonf9381f02017-12-14 18:23:57961 if (IsUnifiedPlan()) {
962 auto transceiver = FindTransceiverBySender(sender);
963 if (!transceiver || !sender->track()) {
964 return RTCError::OK();
965 }
966 sender->SetTrack(nullptr);
967 if (transceiver->direction() == RtpTransceiverDirection::kSendRecv) {
Steve Anton52d86772018-02-20 23:48:12968 transceiver->internal()->set_direction(
969 RtpTransceiverDirection::kRecvOnly);
Steve Antonf9381f02017-12-14 18:23:57970 } else if (transceiver->direction() == RtpTransceiverDirection::kSendOnly) {
Steve Anton52d86772018-02-20 23:48:12971 transceiver->internal()->set_direction(
972 RtpTransceiverDirection::kInactive);
Steve Antonf9381f02017-12-14 18:23:57973 }
Steve Anton4171afb2017-11-20 18:20:22974 } else {
Steve Antonf9381f02017-12-14 18:23:57975 bool removed;
976 if (sender->media_type() == cricket::MEDIA_TYPE_AUDIO) {
Harald Alvestrande15fb152020-10-19 13:28:05977 removed = rtp_manager()->GetAudioTransceiver()->internal()->RemoveSender(
Niels Möllerafb246b2022-04-20 12:26:50978 sender.get());
Steve Antonf9381f02017-12-14 18:23:57979 } else {
980 RTC_DCHECK_EQ(cricket::MEDIA_TYPE_VIDEO, sender->media_type());
Harald Alvestrande15fb152020-10-19 13:28:05981 removed = rtp_manager()->GetVideoTransceiver()->internal()->RemoveSender(
Niels Möllerafb246b2022-04-20 12:26:50982 sender.get());
Steve Antonf9381f02017-12-14 18:23:57983 }
984 if (!removed) {
985 LOG_AND_RETURN_ERROR(
986 RTCErrorType::INVALID_PARAMETER,
987 "Couldn't find sender " + sender->id() + " to remove.");
988 }
Steve Anton4171afb2017-11-20 18:20:22989 }
Harald Alvestrand9cd199d2020-10-27 07:10:43990 sdp_handler_->UpdateNegotiationNeeded();
Steve Antonf9381f02017-12-14 18:23:57991 return RTCError::OK();
992}
993
994rtc::scoped_refptr<RtpTransceiverProxyWithInternal<RtpTransceiver>>
995PeerConnection::FindTransceiverBySender(
996 rtc::scoped_refptr<RtpSenderInterface> sender) {
Harald Alvestrande15fb152020-10-19 13:28:05997 return rtp_manager()->transceivers()->FindBySender(sender);
deadbeefe1f9d832016-01-14 23:35:42998}
999
Steve Anton9158ef62017-11-27 21:01:521000RTCErrorOr<rtc::scoped_refptr<RtpTransceiverInterface>>
1001PeerConnection::AddTransceiver(
1002 rtc::scoped_refptr<MediaStreamTrackInterface> track) {
Harald Alvestrand35ba0c52022-05-05 07:37:411003 if (!ConfiguredForMedia()) {
1004 LOG_AND_RETURN_ERROR(RTCErrorType::UNSUPPORTED_OPERATION,
1005 "Not configured for media");
1006 }
1007
Steve Anton9158ef62017-11-27 21:01:521008 return AddTransceiver(track, RtpTransceiverInit());
1009}
1010
1011RTCErrorOr<rtc::scoped_refptr<RtpTransceiverInterface>>
1012PeerConnection::AddTransceiver(
1013 rtc::scoped_refptr<MediaStreamTrackInterface> track,
1014 const RtpTransceiverInit& init) {
Karl Wiberg744310f2019-02-14 09:18:561015 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand35ba0c52022-05-05 07:37:411016 if (!ConfiguredForMedia()) {
1017 LOG_AND_RETURN_ERROR(RTCErrorType::UNSUPPORTED_OPERATION,
1018 "Not configured for media");
1019 }
Steve Antonfc853712018-03-01 21:48:581020 RTC_CHECK(IsUnifiedPlan())
1021 << "AddTransceiver is only available with Unified Plan SdpSemantics";
Steve Anton9158ef62017-11-27 21:01:521022 if (!track) {
1023 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER, "track is null");
1024 }
1025 cricket::MediaType media_type;
1026 if (track->kind() == MediaStreamTrackInterface::kAudioKind) {
1027 media_type = cricket::MEDIA_TYPE_AUDIO;
1028 } else if (track->kind() == MediaStreamTrackInterface::kVideoKind) {
1029 media_type = cricket::MEDIA_TYPE_VIDEO;
1030 } else {
1031 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
1032 "Track kind is not audio or video");
1033 }
1034 return AddTransceiver(media_type, track, init);
1035}
1036
1037RTCErrorOr<rtc::scoped_refptr<RtpTransceiverInterface>>
1038PeerConnection::AddTransceiver(cricket::MediaType media_type) {
1039 return AddTransceiver(media_type, RtpTransceiverInit());
1040}
1041
1042RTCErrorOr<rtc::scoped_refptr<RtpTransceiverInterface>>
1043PeerConnection::AddTransceiver(cricket::MediaType media_type,
1044 const RtpTransceiverInit& init) {
Karl Wiberg744310f2019-02-14 09:18:561045 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand35ba0c52022-05-05 07:37:411046 if (!ConfiguredForMedia()) {
1047 LOG_AND_RETURN_ERROR(RTCErrorType::UNSUPPORTED_OPERATION,
1048 "Not configured for media");
1049 }
Steve Antonfc853712018-03-01 21:48:581050 RTC_CHECK(IsUnifiedPlan())
1051 << "AddTransceiver is only available with Unified Plan SdpSemantics";
Steve Anton9158ef62017-11-27 21:01:521052 if (!(media_type == cricket::MEDIA_TYPE_AUDIO ||
1053 media_type == cricket::MEDIA_TYPE_VIDEO)) {
1054 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
1055 "media type is not audio or video");
1056 }
1057 return AddTransceiver(media_type, nullptr, init);
1058}
1059
1060RTCErrorOr<rtc::scoped_refptr<RtpTransceiverInterface>>
1061PeerConnection::AddTransceiver(
1062 cricket::MediaType media_type,
1063 rtc::scoped_refptr<MediaStreamTrackInterface> track,
Steve Anton22da89f2018-01-25 21:58:071064 const RtpTransceiverInit& init,
Guido Urdaneta70c2db12019-04-16 10:24:141065 bool update_negotiation_needed) {
Harald Alvestranda474fbf2020-10-01 16:47:231066 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand35ba0c52022-05-05 07:37:411067 if (!ConfiguredForMedia()) {
1068 LOG_AND_RETURN_ERROR(RTCErrorType::UNSUPPORTED_OPERATION,
1069 "Not configured for media");
1070 }
Steve Anton9158ef62017-11-27 21:01:521071 RTC_DCHECK((media_type == cricket::MEDIA_TYPE_AUDIO ||
1072 media_type == cricket::MEDIA_TYPE_VIDEO));
1073 if (track) {
1074 RTC_DCHECK_EQ(media_type,
1075 (track->kind() == MediaStreamTrackInterface::kAudioKind
1076 ? cricket::MEDIA_TYPE_AUDIO
1077 : cricket::MEDIA_TYPE_VIDEO));
1078 }
1079
Amit Hilbuchaa584152019-02-07 01:09:521080 size_t num_rids = absl::c_count_if(init.send_encodings,
1081 [](const RtpEncodingParameters& encoding) {
1082 return !encoding.rid.empty();
1083 });
1084 if (num_rids > 0 && num_rids != init.send_encodings.size()) {
Amit Hilbuchce470aa2019-02-07 01:09:521085 LOG_AND_RETURN_ERROR(
Amit Hilbuchaa584152019-02-07 01:09:521086 RTCErrorType::INVALID_PARAMETER,
1087 "RIDs must be provided for either all or none of the send encodings.");
Emircan Uysaler78323432019-02-08 20:41:391088 }
1089
Amit Hilbuchf4770402019-04-08 21:11:571090 if (num_rids > 0 && absl::c_any_of(init.send_encodings,
1091 [](const RtpEncodingParameters& encoding) {
1092 return !IsLegalRsidName(encoding.rid);
1093 })) {
1094 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
1095 "Invalid RID value provided.");
1096 }
1097
Amit Hilbuchaa584152019-02-07 01:09:521098 if (absl::c_any_of(init.send_encodings,
1099 [](const RtpEncodingParameters& encoding) {
1100 return encoding.ssrc.has_value();
1101 })) {
1102 LOG_AND_RETURN_ERROR(
1103 RTCErrorType::UNSUPPORTED_PARAMETER,
1104 "Attempted to set an unimplemented parameter of RtpParameters.");
Florent Castelli892acf02018-10-01 20:47:201105 }
1106
1107 RtpParameters parameters;
1108 parameters.encodings = init.send_encodings;
Amit Hilbuchaa584152019-02-07 01:09:521109
1110 // Encodings are dropped from the tail if too many are provided.
Florent Castellie1b685a2021-04-30 17:11:371111 size_t max_simulcast_streams =
1112 media_type == cricket::MEDIA_TYPE_VIDEO ? kMaxSimulcastStreams : 1u;
1113 if (parameters.encodings.size() > max_simulcast_streams) {
Amit Hilbuchaa584152019-02-07 01:09:521114 parameters.encodings.erase(
Florent Castellie1b685a2021-04-30 17:11:371115 parameters.encodings.begin() + max_simulcast_streams,
Amit Hilbuchaa584152019-02-07 01:09:521116 parameters.encodings.end());
1117 }
1118
1119 // Single RID should be removed.
1120 if (parameters.encodings.size() == 1 &&
1121 !parameters.encodings[0].rid.empty()) {
1122 RTC_LOG(LS_INFO) << "Removing RID: " << parameters.encodings[0].rid << ".";
1123 parameters.encodings[0].rid.clear();
1124 }
1125
1126 // If RIDs were not provided, they are generated for simulcast scenario.
1127 if (parameters.encodings.size() > 1 && num_rids == 0) {
1128 rtc::UniqueStringGenerator rid_generator;
1129 for (RtpEncodingParameters& encoding : parameters.encodings) {
Harald Alvestrand5ad491e2023-02-10 11:28:041130 encoding.rid = rid_generator.GenerateString();
Amit Hilbuchaa584152019-02-07 01:09:521131 }
1132 }
1133
Florent Castellibd1e5d52023-01-17 17:08:261134 // If no encoding parameters were provided, a default entry is created.
1135 if (parameters.encodings.empty()) {
1136 parameters.encodings.push_back({});
1137 }
1138
Florent Castelli892acf02018-10-01 20:47:201139 if (UnimplementedRtpParameterHasValue(parameters)) {
1140 LOG_AND_RETURN_ERROR(
1141 RTCErrorType::UNSUPPORTED_PARAMETER,
1142 "Attempted to set an unimplemented parameter of RtpParameters.");
1143 }
Steve Anton9158ef62017-11-27 21:01:521144
Harald Alvestrandd78e30e2024-04-29 10:15:341145 std::vector<cricket::Codec> codecs;
Florent Castelli43a5dd82023-04-12 10:45:071146 // Gather the current codec capabilities to allow checking scalabilityMode and
1147 // codec selection against supported values.
Florent Castelli725ee242022-10-18 15:05:581148 if (media_type == cricket::MEDIA_TYPE_VIDEO) {
Florent Castelli725ee242022-10-18 15:05:581149 codecs = context_->media_engine()->video().send_codecs(false);
Florent Castelli43a5dd82023-04-12 10:45:071150 } else {
1151 codecs = context_->media_engine()->voice().send_codecs();
Florent Castelli725ee242022-10-18 15:05:581152 }
1153
Florent Castellic5b9a602024-09-03 09:13:231154 auto result = cricket::CheckRtpParametersValues(
1155 parameters, codecs, std::nullopt, env_.field_trials());
Florent Castellic1a0bcb2019-01-29 13:26:481156 if (!result.ok()) {
Florent Castelli43a5dd82023-04-12 10:45:071157 if (result.type() == RTCErrorType::INVALID_MODIFICATION) {
1158 result.set_type(RTCErrorType::UNSUPPORTED_OPERATION);
1159 }
Florent Castellic1a0bcb2019-01-29 13:26:481160 LOG_AND_RETURN_ERROR(result.type(), result.message());
1161 }
1162
Steve Anton3d954a62018-04-02 18:27:231163 RTC_LOG(LS_INFO) << "Adding " << cricket::MediaTypeToString(media_type)
1164 << " transceiver in response to a call to AddTransceiver.";
Steve Anton07563732018-06-26 18:13:501165 // Set the sender ID equal to the track ID if the track is specified unless
1166 // that sender ID is already in use.
Harald Alvestrande15fb152020-10-19 13:28:051167 std::string sender_id = (track && !rtp_manager()->FindSenderById(track->id())
1168 ? track->id()
1169 : rtc::CreateRandomUuid());
1170 auto sender = rtp_manager()->CreateSender(
1171 media_type, sender_id, track, init.stream_ids, parameters.encodings);
1172 auto receiver =
1173 rtp_manager()->CreateReceiver(media_type, rtc::CreateRandomUuid());
1174 auto transceiver = rtp_manager()->CreateAndAddTransceiver(sender, receiver);
Steve Anton02ee47c2018-01-11 00:26:061175 transceiver->internal()->set_direction(init.direction);
1176
Guido Urdaneta70c2db12019-04-16 10:24:141177 if (update_negotiation_needed) {
Harald Alvestrand9cd199d2020-10-27 07:10:431178 sdp_handler_->UpdateNegotiationNeeded();
Steve Anton22da89f2018-01-25 21:58:071179 }
Steve Antonf9381f02017-12-14 18:23:571180
1181 return rtc::scoped_refptr<RtpTransceiverInterface>(transceiver);
1182}
1183
Steve Anton52d86772018-02-20 23:48:121184void PeerConnection::OnNegotiationNeeded() {
1185 RTC_DCHECK_RUN_ON(signaling_thread());
1186 RTC_DCHECK(!IsClosed());
Harald Alvestrand9cd199d2020-10-27 07:10:431187 sdp_handler_->UpdateNegotiationNeeded();
Steve Anton52d86772018-02-20 23:48:121188}
1189
deadbeeffac06552015-11-25 19:26:011190rtc::scoped_refptr<RtpSenderInterface> PeerConnection::CreateSender(
deadbeefbd7d8f72015-12-19 00:58:441191 const std::string& kind,
1192 const std::string& stream_id) {
Karl Wiberg5966c502019-02-21 22:55:091193 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand35ba0c52022-05-05 07:37:411194 if (!ConfiguredForMedia()) {
1195 RTC_LOG(LS_ERROR) << "Not configured for media";
1196 return nullptr;
1197 }
Steve Antonfc853712018-03-01 21:48:581198 RTC_CHECK(!IsUnifiedPlan()) << "CreateSender is not available with Unified "
1199 "Plan SdpSemantics. Please use AddTransceiver "
1200 "instead.";
Peter Boström1a9d6152015-12-08 21:15:171201 TRACE_EVENT0("webrtc", "PeerConnection::CreateSender");
zhihuang29ff8442016-07-27 18:07:251202 if (IsClosed()) {
1203 return nullptr;
1204 }
Steve Anton4171afb2017-11-20 18:20:221205
Seth Hampson5b4f0752018-04-02 23:31:361206 // Internally we need to have one stream with Plan B semantics, so we
1207 // generate a random stream ID if not specified.
Seth Hampson845e8782018-03-02 19:34:101208 std::vector<std::string> stream_ids;
Seth Hampson5b4f0752018-04-02 23:31:361209 if (stream_id.empty()) {
1210 stream_ids.push_back(rtc::CreateRandomUuid());
1211 RTC_LOG(LS_INFO)
1212 << "No stream_id specified for sender. Generated stream ID: "
1213 << stream_ids[0];
1214 } else {
Seth Hampson845e8782018-03-02 19:34:101215 stream_ids.push_back(stream_id);
Steve Anton02ee47c2018-01-11 00:26:061216 }
1217
Steve Anton4171afb2017-11-20 18:20:221218 // TODO(steveanton): Move construction of the RtpSenders to RtpTransceiver.
deadbeefa601f5c2016-06-06 21:27:391219 rtc::scoped_refptr<RtpSenderProxyWithInternal<RtpSenderInternal>> new_sender;
deadbeeffac06552015-11-25 19:26:011220 if (kind == MediaStreamTrackInterface::kAudioKind) {
Henrik Boströmf7859892022-07-04 12:36:371221 auto audio_sender =
Florent Castellic5b9a602024-09-03 09:13:231222 AudioRtpSender::Create(env_, worker_thread(), rtc::CreateRandomUuid(),
Henrik Boströmf7859892022-07-04 12:36:371223 legacy_stats_.get(), rtp_manager());
Harald Alvestrandc0d44d92022-12-13 12:57:241224 audio_sender->SetMediaChannel(rtp_manager()->voice_media_send_channel());
deadbeefa601f5c2016-06-06 21:27:391225 new_sender = RtpSenderProxyWithInternal<RtpSenderInternal>::Create(
Steve Anton02ee47c2018-01-11 00:26:061226 signaling_thread(), audio_sender);
Harald Alvestrande15fb152020-10-19 13:28:051227 rtp_manager()->GetAudioTransceiver()->internal()->AddSender(new_sender);
deadbeeffac06552015-11-25 19:26:011228 } else if (kind == MediaStreamTrackInterface::kVideoKind) {
Harald Alvestrande15fb152020-10-19 13:28:051229 auto video_sender = VideoRtpSender::Create(
Florent Castellic5b9a602024-09-03 09:13:231230 env_, worker_thread(), rtc::CreateRandomUuid(), rtp_manager());
Harald Alvestrandc0d44d92022-12-13 12:57:241231 video_sender->SetMediaChannel(rtp_manager()->video_media_send_channel());
deadbeefa601f5c2016-06-06 21:27:391232 new_sender = RtpSenderProxyWithInternal<RtpSenderInternal>::Create(
Steve Anton02ee47c2018-01-11 00:26:061233 signaling_thread(), video_sender);
Harald Alvestrande15fb152020-10-19 13:28:051234 rtp_manager()->GetVideoTransceiver()->internal()->AddSender(new_sender);
deadbeeffac06552015-11-25 19:26:011235 } else {
Mirko Bonadei675513b2017-11-09 10:09:251236 RTC_LOG(LS_ERROR) << "CreateSender called with invalid kind: " << kind;
Steve Anton4171afb2017-11-20 18:20:221237 return nullptr;
deadbeeffac06552015-11-25 19:26:011238 }
Henrik Andreasssoncc189172019-05-20 09:01:381239 new_sender->internal()->set_stream_ids(stream_ids);
Steve Anton4171afb2017-11-20 18:20:221240
deadbeefe1f9d832016-01-14 23:35:421241 return new_sender;
deadbeeffac06552015-11-25 19:26:011242}
1243
deadbeef70ab1a12015-09-28 23:53:551244std::vector<rtc::scoped_refptr<RtpSenderInterface>> PeerConnection::GetSenders()
1245 const {
Karl Wiberga58e1692019-03-26 12:33:431246 RTC_DCHECK_RUN_ON(signaling_thread());
deadbeefa601f5c2016-06-06 21:27:391247 std::vector<rtc::scoped_refptr<RtpSenderInterface>> ret;
Harald Alvestrand8101e7b2022-05-23 14:57:471248 if (ConfiguredForMedia()) {
1249 for (const auto& sender : rtp_manager()->GetSendersInternal()) {
1250 ret.push_back(sender);
1251 }
deadbeefa601f5c2016-06-06 21:27:391252 }
1253 return ret;
deadbeef70ab1a12015-09-28 23:53:551254}
1255
1256std::vector<rtc::scoped_refptr<RtpReceiverInterface>>
1257PeerConnection::GetReceivers() const {
Karl Wiberga58e1692019-03-26 12:33:431258 RTC_DCHECK_RUN_ON(signaling_thread());
deadbeefa601f5c2016-06-06 21:27:391259 std::vector<rtc::scoped_refptr<RtpReceiverInterface>> ret;
Harald Alvestrand8101e7b2022-05-23 14:57:471260 if (ConfiguredForMedia()) {
1261 for (const auto& receiver : rtp_manager()->GetReceiversInternal()) {
1262 ret.push_back(receiver);
1263 }
deadbeefa601f5c2016-06-06 21:27:391264 }
1265 return ret;
deadbeef70ab1a12015-09-28 23:53:551266}
1267
Steve Anton9158ef62017-11-27 21:01:521268std::vector<rtc::scoped_refptr<RtpTransceiverInterface>>
1269PeerConnection::GetTransceivers() const {
Karl Wiberg5966c502019-02-21 22:55:091270 RTC_DCHECK_RUN_ON(signaling_thread());
Steve Antonfc853712018-03-01 21:48:581271 RTC_CHECK(IsUnifiedPlan())
1272 << "GetTransceivers is only supported with Unified Plan SdpSemantics.";
Steve Anton9158ef62017-11-27 21:01:521273 std::vector<rtc::scoped_refptr<RtpTransceiverInterface>> all_transceivers;
Harald Alvestrand8101e7b2022-05-23 14:57:471274 if (ConfiguredForMedia()) {
1275 for (const auto& transceiver : rtp_manager()->transceivers()->List()) {
1276 all_transceivers.push_back(transceiver);
1277 }
Steve Anton9158ef62017-11-27 21:01:521278 }
1279 return all_transceivers;
1280}
1281
henrike@webrtc.org28e20752013-07-10 00:45:361282bool PeerConnection::GetStats(StatsObserver* observer,
wu@webrtc.orgb9a088b2014-02-13 23:18:491283 MediaStreamTrackInterface* track,
1284 StatsOutputLevel level) {
Henrik Boströmf7859892022-07-04 12:36:371285 TRACE_EVENT0("webrtc", "PeerConnection::GetStats (legacy)");
Karl Wiberg6cab5c82019-03-26 08:57:011286 RTC_DCHECK_RUN_ON(signaling_thread());
nisse7ce109a2017-01-31 08:57:561287 if (!observer) {
Henrik Boströmf7859892022-07-04 12:36:371288 RTC_LOG(LS_ERROR) << "Legacy GetStats - observer is NULL.";
henrike@webrtc.org28e20752013-07-10 00:45:361289 return false;
1290 }
1291
Tommife041642021-04-07 08:08:281292 RTC_LOG_THREAD_BLOCK_COUNT();
1293
Henrik Boströmf7859892022-07-04 12:36:371294 legacy_stats_->UpdateStats(level);
Tommi19015512022-02-02 10:49:351295
1296 RTC_DCHECK_BLOCK_COUNT_NO_MORE_THAN(4);
1297
Henrik Boströmf7859892022-07-04 12:36:371298 // The LegacyStatsCollector is used to tell if a track is valid because it may
zhihuange9e94c32016-11-04 18:38:151299 // remember tracks that the PeerConnection previously removed.
Henrik Boströmf7859892022-07-04 12:36:371300 if (track && !legacy_stats_->IsValidTrack(track->id())) {
1301 RTC_LOG(LS_WARNING) << "Legacy GetStats is called with an invalid track: "
Mirko Bonadei675513b2017-11-09 10:09:251302 << track->id();
zhihuange9e94c32016-11-04 18:38:151303 return false;
1304 }
Henrik Boströmf7859892022-07-04 12:36:371305 message_handler_.PostGetStats(observer, legacy_stats_.get(), track);
Tommife041642021-04-07 08:08:281306
henrike@webrtc.org28e20752013-07-10 00:45:361307 return true;
1308}
1309
hbos74e1a4f2016-09-16 06:33:011310void PeerConnection::GetStats(RTCStatsCollectorCallback* callback) {
Henrik Boström1df1bf82018-03-20 12:24:201311 TRACE_EVENT0("webrtc", "PeerConnection::GetStats");
Karl Wiberg6cab5c82019-03-26 08:57:011312 RTC_DCHECK_RUN_ON(signaling_thread());
hbos74e1a4f2016-09-16 06:33:011313 RTC_DCHECK(stats_collector_);
Henrik Boström1df1bf82018-03-20 12:24:201314 RTC_DCHECK(callback);
Tommife041642021-04-07 08:08:281315 RTC_LOG_THREAD_BLOCK_COUNT();
Niels Möllere7cc8832022-01-04 14:20:031316 stats_collector_->GetStatsReport(
1317 rtc::scoped_refptr<RTCStatsCollectorCallback>(callback));
Henrik Boström5023ffb2022-07-04 13:47:251318 RTC_DCHECK_BLOCK_COUNT_NO_MORE_THAN(2);
hbos74e1a4f2016-09-16 06:33:011319}
1320
Henrik Boström1df1bf82018-03-20 12:24:201321void PeerConnection::GetStats(
1322 rtc::scoped_refptr<RtpSenderInterface> selector,
1323 rtc::scoped_refptr<RTCStatsCollectorCallback> callback) {
1324 TRACE_EVENT0("webrtc", "PeerConnection::GetStats");
Karl Wiberg6cab5c82019-03-26 08:57:011325 RTC_DCHECK_RUN_ON(signaling_thread());
Henrik Boström1df1bf82018-03-20 12:24:201326 RTC_DCHECK(callback);
1327 RTC_DCHECK(stats_collector_);
Henrik Boström5023ffb2022-07-04 13:47:251328 RTC_LOG_THREAD_BLOCK_COUNT();
Henrik Boström1df1bf82018-03-20 12:24:201329 rtc::scoped_refptr<RtpSenderInternal> internal_sender;
1330 if (selector) {
Harald Alvestrande15fb152020-10-19 13:28:051331 for (const auto& proxy_transceiver :
1332 rtp_manager()->transceivers()->List()) {
Henrik Boström1df1bf82018-03-20 12:24:201333 for (const auto& proxy_sender :
1334 proxy_transceiver->internal()->senders()) {
1335 if (proxy_sender == selector) {
1336 internal_sender = proxy_sender->internal();
1337 break;
1338 }
1339 }
1340 if (internal_sender)
1341 break;
1342 }
1343 }
Artem Titov880fa812021-07-30 20:30:231344 // If there is no `internal_sender` then `selector` is either null or does not
Henrik Boström1df1bf82018-03-20 12:24:201345 // belong to the PeerConnection (in Plan B, senders can be removed from the
1346 // PeerConnection). This means that "all the stats objects representing the
1347 // selector" is an empty set. Invoking GetStatsReport() with a null selector
1348 // produces an empty stats report.
1349 stats_collector_->GetStatsReport(internal_sender, callback);
Henrik Boström5023ffb2022-07-04 13:47:251350 RTC_DCHECK_BLOCK_COUNT_NO_MORE_THAN(2);
Henrik Boström1df1bf82018-03-20 12:24:201351}
1352
1353void PeerConnection::GetStats(
1354 rtc::scoped_refptr<RtpReceiverInterface> selector,
1355 rtc::scoped_refptr<RTCStatsCollectorCallback> callback) {
1356 TRACE_EVENT0("webrtc", "PeerConnection::GetStats");
Karl Wiberg6cab5c82019-03-26 08:57:011357 RTC_DCHECK_RUN_ON(signaling_thread());
Henrik Boström1df1bf82018-03-20 12:24:201358 RTC_DCHECK(callback);
1359 RTC_DCHECK(stats_collector_);
Henrik Boström5023ffb2022-07-04 13:47:251360 RTC_LOG_THREAD_BLOCK_COUNT();
Henrik Boström1df1bf82018-03-20 12:24:201361 rtc::scoped_refptr<RtpReceiverInternal> internal_receiver;
1362 if (selector) {
Harald Alvestrande15fb152020-10-19 13:28:051363 for (const auto& proxy_transceiver :
1364 rtp_manager()->transceivers()->List()) {
Henrik Boström1df1bf82018-03-20 12:24:201365 for (const auto& proxy_receiver :
1366 proxy_transceiver->internal()->receivers()) {
1367 if (proxy_receiver == selector) {
1368 internal_receiver = proxy_receiver->internal();
1369 break;
1370 }
1371 }
1372 if (internal_receiver)
1373 break;
1374 }
1375 }
Artem Titov880fa812021-07-30 20:30:231376 // If there is no `internal_receiver` then `selector` is either null or does
Henrik Boström1df1bf82018-03-20 12:24:201377 // not belong to the PeerConnection (in Plan B, receivers can be removed from
1378 // the PeerConnection). This means that "all the stats objects representing
1379 // the selector" is an empty set. Invoking GetStatsReport() with a null
1380 // selector produces an empty stats report.
1381 stats_collector_->GetStatsReport(internal_receiver, callback);
Henrik Boström5023ffb2022-07-04 13:47:251382 RTC_DCHECK_BLOCK_COUNT_NO_MORE_THAN(2);
Henrik Boström1df1bf82018-03-20 12:24:201383}
1384
henrike@webrtc.org28e20752013-07-10 00:45:361385PeerConnectionInterface::SignalingState PeerConnection::signaling_state() {
Karl Wiberg8d2e2282019-02-17 12:00:071386 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand9cd199d2020-10-27 07:10:431387 return sdp_handler_->signaling_state();
henrike@webrtc.org28e20752013-07-10 00:45:361388}
1389
henrike@webrtc.org28e20752013-07-10 00:45:361390PeerConnectionInterface::IceConnectionState
1391PeerConnection::ice_connection_state() {
Karl Wiberg8d2e2282019-02-17 12:00:071392 RTC_DCHECK_RUN_ON(signaling_thread());
henrike@webrtc.org28e20752013-07-10 00:45:361393 return ice_connection_state_;
1394}
1395
Alex Loiko9289eda2018-11-23 16:18:591396PeerConnectionInterface::IceConnectionState
1397PeerConnection::standardized_ice_connection_state() {
Karl Wiberg8d2e2282019-02-17 12:00:071398 RTC_DCHECK_RUN_ON(signaling_thread());
Alex Loiko9289eda2018-11-23 16:18:591399 return standardized_ice_connection_state_;
1400}
1401
Jonas Olsson635474e2018-10-18 13:58:171402PeerConnectionInterface::PeerConnectionState
1403PeerConnection::peer_connection_state() {
Karl Wiberg8d2e2282019-02-17 12:00:071404 RTC_DCHECK_RUN_ON(signaling_thread());
Jonas Olsson635474e2018-10-18 13:58:171405 return connection_state_;
1406}
1407
henrike@webrtc.org28e20752013-07-10 00:45:361408PeerConnectionInterface::IceGatheringState
1409PeerConnection::ice_gathering_state() {
Karl Wiberg8d2e2282019-02-17 12:00:071410 RTC_DCHECK_RUN_ON(signaling_thread());
henrike@webrtc.org28e20752013-07-10 00:45:361411 return ice_gathering_state_;
1412}
1413
Florent Castelli8037fc62024-08-29 13:00:401414std::optional<bool> PeerConnection::can_trickle_ice_candidates() {
Harald Alvestrand61f74d92020-03-02 10:20:001415 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrandcdcfab02020-09-28 13:02:071416 const SessionDescriptionInterface* description = current_remote_description();
Harald Alvestrand61f74d92020-03-02 10:20:001417 if (!description) {
Harald Alvestrandcdcfab02020-09-28 13:02:071418 description = pending_remote_description();
Harald Alvestrand61f74d92020-03-02 10:20:001419 }
1420 if (!description) {
Florent Castelli8037fc62024-08-29 13:00:401421 return std::nullopt;
Harald Alvestrand61f74d92020-03-02 10:20:001422 }
1423 // TODO(bugs.webrtc.org/7443): Change to retrieve from session-level option.
1424 if (description->description()->transport_infos().size() < 1) {
Florent Castelli8037fc62024-08-29 13:00:401425 return std::nullopt;
Harald Alvestrand61f74d92020-03-02 10:20:001426 }
1427 return description->description()->transport_infos()[0].description.HasOption(
1428 "trickle");
1429}
1430
Harald Alvestranda9af50f2021-05-21 13:33:511431RTCErrorOr<rtc::scoped_refptr<DataChannelInterface>>
1432PeerConnection::CreateDataChannelOrError(const std::string& label,
1433 const DataChannelInit* config) {
Karl Wiberg106d92d2019-02-14 09:17:471434 RTC_DCHECK_RUN_ON(signaling_thread());
Peter Boström1a9d6152015-12-08 21:15:171435 TRACE_EVENT0("webrtc", "PeerConnection::CreateDataChannel");
zhihuang9763d562016-08-05 18:14:501436
Tommi4f7ade52023-03-29 18:46:591437 if (IsClosed()) {
1438 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_STATE,
1439 "CreateDataChannelOrError: PeerConnection is closed.");
1440 }
1441
Harald Alvestrand5da3eb02023-03-15 20:39:421442 bool first_datachannel = !data_channel_controller_.HasUsedDataChannels();
jiayl@webrtc.org001fd2d2014-05-29 15:31:111443
Tommi335d0842023-03-25 09:56:181444 InternalDataChannelInit internal_config;
henrika@webrtc.orgaebb1ad2014-01-14 10:00:581445 if (config) {
Tommi335d0842023-03-25 09:56:181446 internal_config = InternalDataChannelInit(*config);
henrika@webrtc.orgaebb1ad2014-01-14 10:00:581447 }
Tommi335d0842023-03-25 09:56:181448
1449 internal_config.fallback_ssl_role = sdp_handler_->GuessSslRole();
Tommi4f7ade52023-03-29 18:46:591450 RTCErrorOr<rtc::scoped_refptr<DataChannelInterface>> ret =
Taylor Brandstetter3a034e12020-07-09 22:32:341451 data_channel_controller_.InternalCreateDataChannelWithProxy(
Tommi4f7ade52023-03-29 18:46:591452 label, internal_config);
1453 if (!ret.ok()) {
1454 return ret.MoveError();
deadbeefab9b2d12015-10-14 18:33:111455 }
henrike@webrtc.org28e20752013-07-10 00:45:361456
Tommi4f7ade52023-03-29 18:46:591457 rtc::scoped_refptr<DataChannelInterface> channel = ret.MoveValue();
1458
Philipp Hancke522380f2023-05-09 07:41:031459 // Check the onRenegotiationNeeded event (with plan-b backward compat)
1460 if (configuration_.sdp_semantics == SdpSemantics::kUnifiedPlan ||
1461 (configuration_.sdp_semantics == SdpSemantics::kPlanB_DEPRECATED &&
1462 first_datachannel)) {
Harald Alvestrand9cd199d2020-10-27 07:10:431463 sdp_handler_->UpdateNegotiationNeeded();
jiayl@webrtc.org001fd2d2014-05-29 15:31:111464 }
Harald Alvestrand8ebba742018-05-31 12:00:341465 NoteUsageEvent(UsageEvent::DATA_ADDED);
Taylor Brandstetter3a034e12020-07-09 22:32:341466 return channel;
henrike@webrtc.org28e20752013-07-10 00:45:361467}
1468
Henrik Boström79b69802019-07-18 09:16:561469void PeerConnection::RestartIce() {
1470 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand9cd199d2020-10-27 07:10:431471 sdp_handler_->RestartIce();
Henrik Boström79b69802019-07-18 09:16:561472}
1473
henrike@webrtc.org28e20752013-07-10 00:45:361474void PeerConnection::CreateOffer(CreateSessionDescriptionObserver* observer,
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:161475 const RTCOfferAnswerOptions& options) {
Karl Wiberg5966c502019-02-21 22:55:091476 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand9cd199d2020-10-27 07:10:431477 sdp_handler_->CreateOffer(observer, options);
Henrik Boströma3728d32019-10-28 11:09:491478}
1479
Harald Alvestrandcdcfab02020-09-28 13:02:071480void PeerConnection::CreateAnswer(CreateSessionDescriptionObserver* observer,
1481 const RTCOfferAnswerOptions& options) {
Henrik Boströma3728d32019-10-28 11:09:491482 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand9cd199d2020-10-27 07:10:431483 sdp_handler_->CreateAnswer(observer, options);
henrike@webrtc.org28e20752013-07-10 00:45:361484}
1485
henrike@webrtc.org28e20752013-07-10 00:45:361486void PeerConnection::SetLocalDescription(
1487 SetSessionDescriptionObserver* observer,
Steve Anton80dd7b52018-02-17 01:08:421488 SessionDescriptionInterface* desc_ptr) {
Karl Wiberg5966c502019-02-21 22:55:091489 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand9cd199d2020-10-27 07:10:431490 sdp_handler_->SetLocalDescription(observer, desc_ptr);
Henrik Boström831ae4e2020-07-29 10:04:001491}
1492
1493void PeerConnection::SetLocalDescription(
1494 std::unique_ptr<SessionDescriptionInterface> desc,
1495 rtc::scoped_refptr<SetLocalDescriptionObserverInterface> observer) {
1496 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand9cd199d2020-10-27 07:10:431497 sdp_handler_->SetLocalDescription(std::move(desc), observer);
Henrik Boströma3728d32019-10-28 11:09:491498}
Steve Anton8a006912017-12-04 23:25:561499
Henrik Boström4e196702019-10-30 09:35:501500void PeerConnection::SetLocalDescription(
1501 SetSessionDescriptionObserver* observer) {
1502 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand9cd199d2020-10-27 07:10:431503 sdp_handler_->SetLocalDescription(observer);
Henrik Boström831ae4e2020-07-29 10:04:001504}
1505
1506void PeerConnection::SetLocalDescription(
1507 rtc::scoped_refptr<SetLocalDescriptionObserverInterface> observer) {
1508 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand9cd199d2020-10-27 07:10:431509 sdp_handler_->SetLocalDescription(observer);
Henrik Boström4e196702019-10-30 09:35:501510}
1511
henrike@webrtc.org28e20752013-07-10 00:45:361512void PeerConnection::SetRemoteDescription(
Henrik Boströma4ecf552017-11-23 14:17:071513 SetSessionDescriptionObserver* observer,
Henrik Boströma3728d32019-10-28 11:09:491514 SessionDescriptionInterface* desc_ptr) {
1515 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand9cd199d2020-10-27 07:10:431516 sdp_handler_->SetRemoteDescription(observer, desc_ptr);
Henrik Boström31638672017-11-23 16:48:321517}
1518
1519void PeerConnection::SetRemoteDescription(
1520 std::unique_ptr<SessionDescriptionInterface> desc,
1521 rtc::scoped_refptr<SetRemoteDescriptionObserverInterface> observer) {
Karl Wiberg5966c502019-02-21 22:55:091522 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand9cd199d2020-10-27 07:10:431523 sdp_handler_->SetRemoteDescription(std::move(desc), observer);
Henrik Boströmafa07dd2018-12-20 10:06:021524}
1525
deadbeef46c73892016-11-17 03:42:041526PeerConnectionInterface::RTCConfiguration PeerConnection::GetConfiguration() {
Karl Wiberg5966c502019-02-21 22:55:091527 RTC_DCHECK_RUN_ON(signaling_thread());
deadbeef46c73892016-11-17 03:42:041528 return configuration_;
1529}
1530
Niels Möller2579f0c2019-08-19 07:58:171531RTCError PeerConnection::SetConfiguration(
1532 const RTCConfiguration& configuration) {
Karl Wiberg5966c502019-02-21 22:55:091533 RTC_DCHECK_RUN_ON(signaling_thread());
Peter Boström1a9d6152015-12-08 21:15:171534 TRACE_EVENT0("webrtc", "PeerConnection::SetConfiguration");
Steve Antonc79268f2018-04-24 16:54:101535 if (IsClosed()) {
Niels Möller2579f0c2019-08-19 07:58:171536 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_STATE,
1537 "SetConfiguration: PeerConnection is closed.");
Steve Antonc79268f2018-04-24 16:54:101538 }
1539
Tommiaea49c92023-10-22 11:00:141540 const bool has_local_description = local_description() != nullptr;
1541
1542 RTCError validate_error = ValidateIceCandidatePoolSize(
1543 configuration.ice_candidate_pool_size,
1544 has_local_description
Florent Castelli8037fc62024-08-29 13:00:401545 ? std::optional<int>(configuration_.ice_candidate_pool_size)
1546 : std::nullopt);
Tommiaea49c92023-10-22 11:00:141547 if (!validate_error.ok()) {
1548 return validate_error;
buildbot@webrtc.org41451d42014-05-03 05:39:451549 }
Taylor Brandstettera1c30352016-05-13 15:15:111550
Tommiaea49c92023-10-22 11:00:141551 if (has_local_description &&
Benjamin Wright8c27cca2018-10-25 17:16:441552 configuration.crypto_options != configuration_.crypto_options) {
Niels Möller2579f0c2019-08-19 07:58:171553 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_MODIFICATION,
1554 "Can't change crypto_options after calling "
1555 "SetLocalDescription.");
Benjamin Wright8c27cca2018-10-25 17:16:441556 }
1557
Tommiaea49c92023-10-22 11:00:141558 // Create a new, configuration object whose Ice config will have been
1559 // validated..
1560 RTCErrorOr<RTCConfiguration> validated_config =
1561 ApplyConfiguration(configuration, configuration_);
1562 if (!validated_config.ok()) {
1563 return validated_config.error();
deadbeef293e9262017-01-11 20:28:301564 }
1565
1566 // Parse ICE servers before hopping to network thread.
1567 cricket::ServerAddresses stun_servers;
1568 std::vector<cricket::RelayServerConfig> turn_servers;
Tommiaea49c92023-10-22 11:00:141569 validate_error = ParseAndValidateIceServersFromConfiguration(
1570 configuration, stun_servers, turn_servers, usage_pattern_);
1571 if (!validate_error.ok()) {
1572 return validate_error;
deadbeef293e9262017-01-11 20:28:301573 }
Philipp Hancke41a83572022-11-28 13:47:451574
Tommiaea49c92023-10-22 11:00:141575 const RTCConfiguration& modified_config = validated_config.value();
Tomas Gunnarsson20f74562021-02-04 09:22:501576 const bool needs_ice_restart =
1577 modified_config.servers != configuration_.servers ||
1578 NeedIceRestart(
1579 configuration_.surface_ice_candidates_on_ice_transport_type_changed,
1580 configuration_.type, modified_config.type) ||
1581 modified_config.GetTurnPortPrunePolicy() !=
1582 configuration_.GetTurnPortPrunePolicy();
1583 cricket::IceConfig ice_config = ParseIceConfig(modified_config);
1584
1585 // Apply part of the configuration on the network thread. In theory this
1586 // shouldn't fail.
Danil Chapovalov9e09a1f2022-09-08 16:38:101587 if (!network_thread()->BlockingCall(
Tomas Gunnarsson20f74562021-02-04 09:22:501588 [this, needs_ice_restart, &ice_config, &stun_servers, &turn_servers,
1589 &modified_config, has_local_description] {
Harald Alvestrandbc32c562022-02-09 12:08:471590 RTC_DCHECK_RUN_ON(network_thread());
Tomas Gunnarsson20f74562021-02-04 09:22:501591 // As described in JSEP, calling setConfiguration with new ICE
1592 // servers or candidate policy must set a "needs-ice-restart" bit so
1593 // that the next offer triggers an ICE restart which will pick up
1594 // the changes.
1595 if (needs_ice_restart)
1596 transport_controller_->SetNeedsIceRestartFlag();
1597
1598 transport_controller_->SetIceConfig(ice_config);
Tommiaea49c92023-10-22 11:00:141599 transport_controller_->SetActiveResetSrtpParams(
1600 modified_config.active_reset_srtp_params);
Niels Möller4bab23f2021-01-18 08:24:331601 return ReconfigurePortAllocator_n(
1602 stun_servers, turn_servers, modified_config.type,
1603 modified_config.ice_candidate_pool_size,
1604 modified_config.GetTurnPortPrunePolicy(),
1605 modified_config.turn_customizer,
1606 modified_config.stun_candidate_keepalive_interval,
1607 has_local_description);
1608 })) {
Niels Möller2579f0c2019-08-19 07:58:171609 LOG_AND_RETURN_ERROR(RTCErrorType::INTERNAL_ERROR,
1610 "Failed to apply configuration to PortAllocator.");
deadbeef293e9262017-01-11 20:28:301611 }
Honghai Zhang4cedf2b2016-08-31 15:18:111612
deadbeef293e9262017-01-11 20:28:301613 configuration_ = modified_config;
Niels Möller2579f0c2019-08-19 07:58:171614 return RTCError::OK();
buildbot@webrtc.org41451d42014-05-03 05:39:451615}
1616
henrike@webrtc.org28e20752013-07-10 00:45:361617bool PeerConnection::AddIceCandidate(
1618 const IceCandidateInterface* ice_candidate) {
Karl Wiberg744310f2019-02-14 09:18:561619 RTC_DCHECK_RUN_ON(signaling_thread());
Philipp Hanckea09b9212022-06-22 05:41:221620 ClearStatsCache();
Harald Alvestrand9cd199d2020-10-27 07:10:431621 return sdp_handler_->AddIceCandidate(ice_candidate);
henrike@webrtc.org28e20752013-07-10 00:45:361622}
1623
Henrik Boströmee6f4f62019-11-06 11:36:121624void PeerConnection::AddIceCandidate(
1625 std::unique_ptr<IceCandidateInterface> candidate,
1626 std::function<void(RTCError)> callback) {
1627 RTC_DCHECK_RUN_ON(signaling_thread());
Philipp Hanckea09b9212022-06-22 05:41:221628 sdp_handler_->AddIceCandidate(std::move(candidate),
Harald Alvestranda6544372023-11-13 09:33:561629 [this, callback](RTCError result) {
Philipp Hanckea09b9212022-06-22 05:41:221630 ClearStatsCache();
1631 callback(result);
1632 });
Henrik Boströmee6f4f62019-11-06 11:36:121633}
1634
Honghai Zhang7fb69db2016-03-14 18:59:181635bool PeerConnection::RemoveIceCandidates(
1636 const std::vector<cricket::Candidate>& candidates) {
1637 TRACE_EVENT0("webrtc", "PeerConnection::RemoveIceCandidates");
Karl Wiberg2cc368f2019-04-02 09:31:561638 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand9cd199d2020-10-27 07:10:431639 return sdp_handler_->RemoveIceCandidates(candidates);
Honghai Zhang7fb69db2016-03-14 18:59:181640}
1641
Niels Möller0c4f7be2018-05-07 12:01:371642RTCError PeerConnection::SetBitrate(const BitrateSettings& bitrate) {
Steve Anton978b8762017-09-29 19:15:021643 if (!worker_thread()->IsCurrent()) {
Danil Chapovalov9e09a1f2022-09-08 16:38:101644 return worker_thread()->BlockingCall([&]() { return SetBitrate(bitrate); });
zstein4b979802017-06-02 21:37:371645 }
Karl Wiberg6cab5c82019-03-26 08:57:011646 RTC_DCHECK_RUN_ON(worker_thread());
zstein4b979802017-06-02 21:37:371647
Niels Möller0c4f7be2018-05-07 12:01:371648 const bool has_min = bitrate.min_bitrate_bps.has_value();
1649 const bool has_start = bitrate.start_bitrate_bps.has_value();
1650 const bool has_max = bitrate.max_bitrate_bps.has_value();
zstein4b979802017-06-02 21:37:371651 if (has_min && *bitrate.min_bitrate_bps < 0) {
1652 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
1653 "min_bitrate_bps <= 0");
1654 }
Niels Möller0c4f7be2018-05-07 12:01:371655 if (has_start) {
1656 if (has_min && *bitrate.start_bitrate_bps < *bitrate.min_bitrate_bps) {
zstein4b979802017-06-02 21:37:371657 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
Niels Möller0c4f7be2018-05-07 12:01:371658 "start_bitrate_bps < min_bitrate_bps");
1659 } else if (*bitrate.start_bitrate_bps < 0) {
zstein4b979802017-06-02 21:37:371660 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
1661 "curent_bitrate_bps < 0");
1662 }
1663 }
1664 if (has_max) {
Yves Gerey665174f2018-06-19 13:03:051665 if (has_start && *bitrate.max_bitrate_bps < *bitrate.start_bitrate_bps) {
zstein4b979802017-06-02 21:37:371666 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
Niels Möller0c4f7be2018-05-07 12:01:371667 "max_bitrate_bps < start_bitrate_bps");
zstein4b979802017-06-02 21:37:371668 } else if (has_min && *bitrate.max_bitrate_bps < *bitrate.min_bitrate_bps) {
1669 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
1670 "max_bitrate_bps < min_bitrate_bps");
1671 } else if (*bitrate.max_bitrate_bps < 0) {
1672 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
1673 "max_bitrate_bps < 0");
1674 }
1675 }
1676
zstein4b979802017-06-02 21:37:371677 RTC_DCHECK(call_.get());
Piotr (Peter) Slatala7fbfaa42019-03-18 17:31:541678 call_->SetClientBitratePreferences(bitrate);
zstein4b979802017-06-02 21:37:371679
1680 return RTCError::OK();
1681}
1682
Per K39ac25d2024-02-07 13:16:201683void PeerConnection::ReconfigureBandwidthEstimation(
1684 const BandwidthEstimationSettings& settings) {
1685 worker_thread()->PostTask(SafeTask(worker_thread_safety_, [this, settings]() {
1686 RTC_DCHECK_RUN_ON(worker_thread());
1687 call_->GetTransportControllerSend()->ReconfigureBandwidthEstimation(
1688 settings);
1689 }));
1690}
1691
henrika5f6bf242017-11-01 10:06:561692void PeerConnection::SetAudioPlayout(bool playout) {
1693 if (!worker_thread()->IsCurrent()) {
Danil Chapovalov9e09a1f2022-09-08 16:38:101694 worker_thread()->BlockingCall(
1695 [this, playout] { SetAudioPlayout(playout); });
henrika5f6bf242017-11-01 10:06:561696 return;
1697 }
Harald Alvestrandc3fa7c32022-05-22 10:57:011698 auto audio_state = context_->media_engine()->voice().GetAudioState();
henrika5f6bf242017-11-01 10:06:561699 audio_state->SetPlayout(playout);
1700}
1701
1702void PeerConnection::SetAudioRecording(bool recording) {
1703 if (!worker_thread()->IsCurrent()) {
Danil Chapovalov9e09a1f2022-09-08 16:38:101704 worker_thread()->BlockingCall(
1705 [this, recording] { SetAudioRecording(recording); });
henrika5f6bf242017-11-01 10:06:561706 return;
1707 }
Harald Alvestrandc3fa7c32022-05-22 10:57:011708 auto audio_state = context_->media_engine()->voice().GetAudioState();
henrika5f6bf242017-11-01 10:06:561709 audio_state->SetRecording(recording);
1710}
1711
Henrik Boström4c1e7cc2020-06-11 10:26:531712void PeerConnection::AddAdaptationResource(
1713 rtc::scoped_refptr<Resource> resource) {
1714 if (!worker_thread()->IsCurrent()) {
Danil Chapovalov9e09a1f2022-09-08 16:38:101715 return worker_thread()->BlockingCall(
1716 [this, resource]() { return AddAdaptationResource(resource); });
Henrik Boström4c1e7cc2020-06-11 10:26:531717 }
1718 RTC_DCHECK_RUN_ON(worker_thread());
1719 if (!call_) {
1720 // The PeerConnection has been closed.
1721 return;
1722 }
1723 call_->AddAdaptationResource(resource);
1724}
1725
Harald Alvestrand35ba0c52022-05-05 07:37:411726bool PeerConnection::ConfiguredForMedia() const {
Harald Alvestrandc3fa7c32022-05-22 10:57:011727 return context_->media_engine();
Harald Alvestrand35ba0c52022-05-05 07:37:411728}
1729
Bjorn Tereliusde939432017-11-20 16:38:141730bool PeerConnection::StartRtcEventLog(std::unique_ptr<RtcEventLogOutput> output,
1731 int64_t output_period_ms) {
Danil Chapovalov9e09a1f2022-09-08 16:38:101732 return worker_thread()->BlockingCall(
Danil Chapovalov116ffe72019-09-05 08:21:111733 [this, output = std::move(output), output_period_ms]() mutable {
1734 return StartRtcEventLog_w(std::move(output), output_period_ms);
1735 });
ivoc14d5dbe2016-07-04 14:06:551736}
1737
Niels Möllerf00ca1a2019-05-10 09:33:121738bool PeerConnection::StartRtcEventLog(
1739 std::unique_ptr<RtcEventLogOutput> output) {
Lionel Koenig0606eaf2023-06-27 08:46:191740 int64_t output_period_ms = 5000;
1741 if (trials().IsDisabled("WebRTC-RtcEventLogNewFormat")) {
Harald Alvestranda6544372023-11-13 09:33:561742 output_period_ms = RtcEventLog::kImmediateOutput;
Niels Möller695cf6a2019-05-13 10:27:231743 }
1744 return StartRtcEventLog(std::move(output), output_period_ms);
Niels Möllerf00ca1a2019-05-10 09:33:121745}
1746
ivoc14d5dbe2016-07-04 14:06:551747void PeerConnection::StopRtcEventLog() {
Danil Chapovalov9e09a1f2022-09-08 16:38:101748 worker_thread()->BlockingCall([this] { StopRtcEventLog_w(); });
ivoc14d5dbe2016-07-04 14:06:551749}
1750
Harald Alvestrandad88c882018-11-28 15:47:461751rtc::scoped_refptr<DtlsTransportInterface>
1752PeerConnection::LookupDtlsTransportByMid(const std::string& mid) {
Tomas Gunnarsson2aeab5e2021-02-23 20:36:141753 RTC_DCHECK_RUN_ON(network_thread());
Harald Alvestrandad88c882018-11-28 15:47:461754 return transport_controller_->LookupDtlsTransportByMid(mid);
1755}
1756
Harald Alvestrand4a7b3ac2019-01-17 09:39:401757rtc::scoped_refptr<DtlsTransport>
1758PeerConnection::LookupDtlsTransportByMidInternal(const std::string& mid) {
Karl Wiberg2cc368f2019-04-02 09:31:561759 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrandbc32c562022-02-09 12:08:471760 // TODO(bugs.webrtc.org/9987): Avoid the thread jump.
1761 // This might be done by caching the value on the signaling thread.
Danil Chapovalov9e09a1f2022-09-08 16:38:101762 return network_thread()->BlockingCall([this, mid]() {
1763 RTC_DCHECK_RUN_ON(network_thread());
1764 return transport_controller_->LookupDtlsTransportByMid(mid);
1765 });
Harald Alvestrand4a7b3ac2019-01-17 09:39:401766}
1767
Harald Alvestrandc85328f2019-02-28 06:51:001768rtc::scoped_refptr<SctpTransportInterface> PeerConnection::GetSctpTransport()
1769 const {
Tomas Gunnarsson92eebef2021-02-10 12:05:441770 RTC_DCHECK_RUN_ON(network_thread());
1771 if (!sctp_mid_n_)
Bjorn A Mellembc3eebc2019-09-23 21:53:541772 return nullptr;
Tomas Gunnarsson92eebef2021-02-10 12:05:441773
1774 return transport_controller_->GetSctpTransport(*sctp_mid_n_);
Harald Alvestrandc85328f2019-02-28 06:51:001775}
1776
henrike@webrtc.org28e20752013-07-10 00:45:361777const SessionDescriptionInterface* PeerConnection::local_description() const {
Karl Wiberg739506e2019-04-03 09:37:281778 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand9cd199d2020-10-27 07:10:431779 return sdp_handler_->local_description();
henrike@webrtc.org28e20752013-07-10 00:45:361780}
1781
1782const SessionDescriptionInterface* PeerConnection::remote_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_->remote_description();
henrike@webrtc.org28e20752013-07-10 00:45:361785}
1786
deadbeeffe4a8a42016-12-21 01:56:171787const SessionDescriptionInterface* PeerConnection::current_local_description()
1788 const {
Karl Wiberg739506e2019-04-03 09:37:281789 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand9cd199d2020-10-27 07:10:431790 return sdp_handler_->current_local_description();
deadbeeffe4a8a42016-12-21 01:56:171791}
1792
1793const SessionDescriptionInterface* PeerConnection::current_remote_description()
1794 const {
Karl Wiberg739506e2019-04-03 09:37:281795 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand9cd199d2020-10-27 07:10:431796 return sdp_handler_->current_remote_description();
deadbeeffe4a8a42016-12-21 01:56:171797}
1798
1799const SessionDescriptionInterface* PeerConnection::pending_local_description()
1800 const {
Karl Wiberg739506e2019-04-03 09:37:281801 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand9cd199d2020-10-27 07:10:431802 return sdp_handler_->pending_local_description();
deadbeeffe4a8a42016-12-21 01:56:171803}
1804
1805const SessionDescriptionInterface* PeerConnection::pending_remote_description()
1806 const {
Karl Wiberg739506e2019-04-03 09:37:281807 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand9cd199d2020-10-27 07:10:431808 return sdp_handler_->pending_remote_description();
deadbeeffe4a8a42016-12-21 01:56:171809}
1810
henrike@webrtc.org28e20752013-07-10 00:45:361811void PeerConnection::Close() {
Karl Wiberg744310f2019-02-14 09:18:561812 RTC_DCHECK_RUN_ON(signaling_thread());
Peter Boström1a9d6152015-12-08 21:15:171813 TRACE_EVENT0("webrtc", "PeerConnection::Close");
Harald Alvestrandcdcfab02020-09-28 13:02:071814
Tommife041642021-04-07 08:08:281815 RTC_LOG_THREAD_BLOCK_COUNT();
1816
Harald Alvestrandcdcfab02020-09-28 13:02:071817 if (IsClosed()) {
1818 return;
1819 }
henrike@webrtc.org28e20752013-07-10 00:45:361820 // Update stats here so that we have the most recent stats for tracks and
1821 // streams before the channels are closed.
Henrik Boströmf7859892022-07-04 12:36:371822 legacy_stats_->UpdateStats(kStatsOutputLevelStandard);
henrike@webrtc.org28e20752013-07-10 00:45:361823
Harald Alvestrandcdcfab02020-09-28 13:02:071824 ice_connection_state_ = PeerConnectionInterface::kIceConnectionClosed;
1825 Observer()->OnIceConnectionChange(ice_connection_state_);
1826 standardized_ice_connection_state_ =
1827 PeerConnectionInterface::IceConnectionState::kIceConnectionClosed;
1828 connection_state_ = PeerConnectionInterface::PeerConnectionState::kClosed;
1829 Observer()->OnConnectionChange(connection_state_);
1830
Harald Alvestrand9cd199d2020-10-27 07:10:431831 sdp_handler_->Close();
Harald Alvestrandcdcfab02020-09-28 13:02:071832
Harald Alvestrand8ebba742018-05-31 12:00:341833 NoteUsageEvent(UsageEvent::CLOSE_CALLED);
Steve Anton3fe1b152017-12-12 18:20:081834
Harald Alvestrand8101e7b2022-05-23 14:57:471835 if (ConfiguredForMedia()) {
1836 for (const auto& transceiver : rtp_manager()->transceivers()->List()) {
1837 transceiver->internal()->SetPeerConnectionClosed();
1838 if (!transceiver->stopped())
1839 transceiver->StopInternal();
1840 }
Steve Anton8af21862017-12-15 19:20:131841 }
Steve Anton25cfeb92018-04-26 18:44:001842 // Ensure that all asynchronous stats requests are completed before destroying
1843 // the transport controller below.
1844 if (stats_collector_) {
1845 stats_collector_->WaitForPendingRequest();
1846 }
1847
1848 // Don't destroy BaseChannels until after stats has been cleaned up so that
1849 // the last stats request can still read from the channels.
Tommi29190752023-10-21 14:50:091850 // TODO(tommi): The voice/video channels will be partially uninitialized on
1851 // the network thread (see `RtpTransceiver::ClearChannel`), partially on the
1852 // worker thread (see `PushNewMediaChannelAndDeleteChannel`) and then
1853 // eventually freed on the signaling thread.
1854 // It would be good to combine those steps with the teardown steps here.
1855 sdp_handler_->DestroyMediaChannels();
Steve Anton75737c02017-11-06 18:37:171856
Qingsi Wang93a84392018-01-31 01:13:091857 // The event log is used in the transport controller, which must be outlived
1858 // by the former. CreateOffer by the peer connection is implemented
1859 // asynchronously and if the peer connection is closed without resetting the
1860 // WebRTC session description factory, the session description factory would
1861 // call the transport controller.
Harald Alvestrand9cd199d2020-10-27 07:10:431862 sdp_handler_->ResetSessionDescFactory();
Harald Alvestrand8101e7b2022-05-23 14:57:471863 if (ConfiguredForMedia()) {
1864 rtp_manager_->Close();
1865 }
Qingsi Wang93a84392018-01-31 01:13:091866
Danil Chapovalov9e09a1f2022-09-08 16:38:101867 network_thread()->BlockingCall([this] {
Harald Alvestrandbc32c562022-02-09 12:08:471868 RTC_DCHECK_RUN_ON(network_thread());
Tommi29190752023-10-21 14:50:091869 TeardownDataChannelTransport_n({});
Tomas Gunnarsson92eebef2021-02-10 12:05:441870 transport_controller_.reset();
1871 port_allocator_->DiscardCandidatePool();
1872 if (network_thread_safety_) {
1873 network_thread_safety_->SetNotAlive();
Tomas Gunnarsson92eebef2021-02-10 12:05:441874 }
1875 });
nisseeaabdf62017-05-05 09:23:021876
Tommi29190752023-10-21 14:50:091877 sctp_mid_s_.reset();
1878 SetSctpTransportName("");
1879
Danil Chapovalov9e09a1f2022-09-08 16:38:101880 worker_thread()->BlockingCall([this] {
Karl Wibergb03ab712019-02-14 10:59:571881 RTC_DCHECK_RUN_ON(worker_thread());
Tommic3257d02021-02-10 17:40:081882 worker_thread_safety_->SetNotAlive();
eladalon248fd4f2017-09-06 12:18:151883 call_.reset();
Danil Chapovalov49c35d32023-11-27 11:55:391884 StopRtcEventLog_w();
eladalon248fd4f2017-09-06 12:18:151885 });
Harald Alvestrand8ebba742018-05-31 12:00:341886 ReportUsagePattern();
Tomas Gunnarsson2efb8a52021-04-01 14:26:571887
1888 // Signal shutdown to the sdp handler. This invalidates weak pointers for
1889 // internal pending callbacks.
1890 sdp_handler_->PrepareForShutdown();
Tommi1f708ef2023-03-31 16:40:501891 data_channel_controller_.PrepareForShutdown();
1892
1893 // The .h file says that observer can be discarded after close() returns.
1894 // Make sure this is true.
1895 observer_ = nullptr;
henrike@webrtc.org28e20752013-07-10 00:45:361896}
1897
Steve Antonba818672017-11-06 18:21:571898void PeerConnection::SetIceConnectionState(IceConnectionState new_state) {
Harald Alvestrandcdcfab02020-09-28 13:02:071899 RTC_DCHECK_RUN_ON(signaling_thread());
Steve Antonba818672017-11-06 18:21:571900 if (ice_connection_state_ == new_state) {
1901 return;
1902 }
1903
deadbeefcbecd352015-09-23 18:50:271904 // After transitioning to "closed", ignore any additional states from
Steve Antonba818672017-11-06 18:21:571905 // TransportController (such as "disconnected").
deadbeefab9b2d12015-10-14 18:33:111906 if (IsClosed()) {
deadbeefcbecd352015-09-23 18:50:271907 return;
1908 }
Steve Antonba818672017-11-06 18:21:571909
Mirko Bonadei675513b2017-11-09 10:09:251910 RTC_LOG(LS_INFO) << "Changing IceConnectionState " << ice_connection_state_
1911 << " => " << new_state;
Steve Antonba818672017-11-06 18:21:571912 RTC_DCHECK(ice_connection_state_ !=
1913 PeerConnectionInterface::kIceConnectionClosed);
1914
henrike@webrtc.org28e20752013-07-10 00:45:361915 ice_connection_state_ = new_state;
Harald Alvestrand7a1c7f72018-08-01 08:50:161916 Observer()->OnIceConnectionChange(ice_connection_state_);
henrike@webrtc.org28e20752013-07-10 00:45:361917}
1918
Alex Loiko9289eda2018-11-23 16:18:591919void PeerConnection::SetStandardizedIceConnectionState(
1920 PeerConnectionInterface::IceConnectionState new_state) {
Qingsi Wang36e31472019-05-29 18:37:261921 if (standardized_ice_connection_state_ == new_state) {
Alex Loiko9289eda2018-11-23 16:18:591922 return;
Qingsi Wang36e31472019-05-29 18:37:261923 }
1924
1925 if (IsClosed()) {
Alex Loiko9289eda2018-11-23 16:18:591926 return;
Qingsi Wang36e31472019-05-29 18:37:261927 }
1928
1929 RTC_LOG(LS_INFO) << "Changing standardized IceConnectionState "
1930 << standardized_ice_connection_state_ << " => " << new_state;
1931
Alex Loiko9289eda2018-11-23 16:18:591932 standardized_ice_connection_state_ = new_state;
Jonas Olsson12046902018-12-06 10:25:141933 Observer()->OnStandardizedIceConnectionChange(new_state);
Alex Loiko9289eda2018-11-23 16:18:591934}
1935
Jonas Olsson635474e2018-10-18 13:58:171936void PeerConnection::SetConnectionState(
1937 PeerConnectionInterface::PeerConnectionState new_state) {
Jonas Olsson635474e2018-10-18 13:58:171938 if (connection_state_ == new_state)
1939 return;
1940 if (IsClosed())
1941 return;
1942 connection_state_ = new_state;
1943 Observer()->OnConnectionChange(new_state);
Philipp Hanckebb8f32f2021-02-04 20:50:501944
Philipp Hancke9799fe02022-07-06 07:26:411945 // The first connection state change to connected happens once per
1946 // connection which makes it a good point to report metrics.
Philipp Hanckecd0373f2021-02-24 10:04:301947 if (new_state == PeerConnectionState::kConnected && !was_ever_connected_) {
1948 was_ever_connected_ = true;
Philipp Hancke9799fe02022-07-06 07:26:411949 ReportFirstConnectUsageMetrics();
Philipp Hanckebb8f32f2021-02-04 20:50:501950 }
Jonas Olsson635474e2018-10-18 13:58:171951}
1952
Philipp Hancke9799fe02022-07-06 07:26:411953void PeerConnection::ReportFirstConnectUsageMetrics() {
1954 // Record bundle-policy from configuration. Done here from
1955 // connectionStateChange to limit to actually established connections.
1956 BundlePolicyUsage policy = kBundlePolicyUsageMax;
1957 switch (configuration_.bundle_policy) {
1958 case kBundlePolicyBalanced:
1959 policy = kBundlePolicyUsageBalanced;
1960 break;
1961 case kBundlePolicyMaxBundle:
1962 policy = kBundlePolicyUsageMaxBundle;
1963 break;
1964 case kBundlePolicyMaxCompat:
1965 policy = kBundlePolicyUsageMaxCompat;
1966 break;
1967 }
1968 RTC_HISTOGRAM_ENUMERATION("WebRTC.PeerConnection.BundlePolicy", policy,
1969 kBundlePolicyUsageMax);
1970
Philipp Hancke9799fe02022-07-06 07:26:411971 // Record whether there was a local or remote provisional answer.
1972 ProvisionalAnswerUsage pranswer = kProvisionalAnswerNotUsed;
1973 if (local_description()->GetType() == SdpType::kPrAnswer) {
1974 pranswer = kProvisionalAnswerLocal;
1975 } else if (remote_description()->GetType() == SdpType::kPrAnswer) {
1976 pranswer = kProvisionalAnswerRemote;
1977 }
1978 RTC_HISTOGRAM_ENUMERATION("WebRTC.PeerConnection.ProvisionalAnswer", pranswer,
1979 kProvisionalAnswerMax);
1980
Philipp Hancke6f22eb52022-07-14 09:38:441981 auto transport_infos = remote_description()->description()->transport_infos();
Philipp Hancke09672472023-11-15 14:23:061982 if (!transport_infos.empty()) {
1983 // Record the number of valid / invalid ice-ufrag. We do allow certain
1984 // non-spec ice-char for backward-compat reasons. At this point we know
1985 // that the ufrag/pwd consists of a valid ice-char or one of the four
1986 // not allowed characters since we have passed the IsIceChar check done
1987 // by the p2p transport description on setRemoteDescription calls.
Philipp Hancke6f22eb52022-07-14 09:38:441988 auto ice_parameters = transport_infos[0].description.GetIceParameters();
1989 auto is_invalid_char = [](char c) {
1990 return c == '-' || c == '=' || c == '#' || c == '_';
1991 };
1992 bool isUsingInvalidIceCharInUfrag =
1993 absl::c_any_of(ice_parameters.ufrag, is_invalid_char);
1994 bool isUsingInvalidIceCharInPwd =
1995 absl::c_any_of(ice_parameters.pwd, is_invalid_char);
1996 RTC_HISTOGRAM_BOOLEAN(
1997 "WebRTC.PeerConnection.ValidIceChars",
1998 !(isUsingInvalidIceCharInUfrag || isUsingInvalidIceCharInPwd));
Philipp Hancke09672472023-11-15 14:23:061999
2000 // Record whether the hash algorithm of the first transport's
2001 // DTLS fingerprint is still using SHA-1.
2002 if (transport_infos[0].description.identity_fingerprint) {
2003 RTC_HISTOGRAM_BOOLEAN(
2004 "WebRTC.PeerConnection.DtlsFingerprintLegacySha1",
2005 absl::EqualsIgnoreCase(
2006 transport_infos[0].description.identity_fingerprint->algorithm,
2007 "sha-1"));
2008 }
Philipp Hancke6f22eb52022-07-14 09:38:442009 }
Philipp Hancke66efab22023-01-25 10:37:452010
2011 // Record RtcpMuxPolicy setting.
2012 RtcpMuxPolicyUsage rtcp_mux_policy = kRtcpMuxPolicyUsageMax;
2013 switch (configuration_.rtcp_mux_policy) {
2014 case kRtcpMuxPolicyNegotiate:
2015 rtcp_mux_policy = kRtcpMuxPolicyUsageNegotiate;
2016 break;
2017 case kRtcpMuxPolicyRequire:
2018 rtcp_mux_policy = kRtcpMuxPolicyUsageRequire;
2019 break;
2020 }
2021 RTC_HISTOGRAM_ENUMERATION("WebRTC.PeerConnection.RtcpMuxPolicy",
2022 rtcp_mux_policy, kRtcpMuxPolicyUsageMax);
Philipp Hancke9799fe02022-07-06 07:26:412023}
2024
henrike@webrtc.org28e20752013-07-10 00:45:362025void PeerConnection::OnIceGatheringChange(
2026 PeerConnectionInterface::IceGatheringState new_state) {
2027 if (IsClosed()) {
2028 return;
2029 }
2030 ice_gathering_state_ = new_state;
Harald Alvestrand7a1c7f72018-08-01 08:50:162031 Observer()->OnIceGatheringChange(ice_gathering_state_);
henrike@webrtc.org28e20752013-07-10 00:45:362032}
2033
jbauch81bf7b02017-03-25 15:31:122034void PeerConnection::OnIceCandidate(
2035 std::unique_ptr<IceCandidateInterface> candidate) {
zhihuang29ff8442016-07-27 18:07:252036 if (IsClosed()) {
2037 return;
2038 }
Qingsi Wang1ba5dec2019-08-19 18:57:172039 ReportIceCandidateCollected(candidate->candidate());
Philipp Hancke1fe14f22022-06-17 09:34:312040 ClearStatsCache();
Harald Alvestrand7a1c7f72018-08-01 08:50:162041 Observer()->OnIceCandidate(candidate.get());
henrike@webrtc.org28e20752013-07-10 00:45:362042}
2043
Eldar Rello0095d372019-12-02 20:22:072044void PeerConnection::OnIceCandidateError(const std::string& address,
2045 int port,
Eldar Relloda13ea22019-06-01 09:23:432046 const std::string& url,
2047 int error_code,
2048 const std::string& error_text) {
2049 if (IsClosed()) {
2050 return;
2051 }
Eldar Rello0095d372019-12-02 20:22:072052 Observer()->OnIceCandidateError(address, port, url, error_code, error_text);
Eldar Relloda13ea22019-06-01 09:23:432053}
2054
Honghai Zhang7fb69db2016-03-14 18:59:182055void PeerConnection::OnIceCandidatesRemoved(
2056 const std::vector<cricket::Candidate>& candidates) {
zhihuang29ff8442016-07-27 18:07:252057 if (IsClosed()) {
2058 return;
2059 }
Harald Alvestrand7a1c7f72018-08-01 08:50:162060 Observer()->OnIceCandidatesRemoved(candidates);
Honghai Zhang7fb69db2016-03-14 18:59:182061}
2062
Alex Drake00c7ecf2019-08-06 17:54:472063void PeerConnection::OnSelectedCandidatePairChanged(
2064 const cricket::CandidatePairChangeEvent& event) {
2065 if (IsClosed()) {
2066 return;
2067 }
Qingsi Wang1ba5dec2019-08-19 18:57:172068
Tommi3b2b2af2024-01-17 13:19:412069 if (event.selected_candidate_pair.local_candidate().is_local() &&
2070 event.selected_candidate_pair.remote_candidate().is_local()) {
Qingsi Wangcc46b10c2019-09-12 18:19:012071 NoteUsageEvent(UsageEvent::DIRECT_CONNECTION_SELECTED);
2072 }
2073
Alex Drake00c7ecf2019-08-06 17:54:472074 Observer()->OnIceSelectedCandidatePairChanged(event);
2075}
2076
Tommi840cf782023-10-21 14:47:562077bool PeerConnection::CreateDataChannelTransport(absl::string_view mid) {
Harald Alvestrandcdcfab02020-09-28 13:02:072078 RTC_DCHECK_RUN_ON(signaling_thread());
Tommi840cf782023-10-21 14:47:562079 RTC_DCHECK(!sctp_mid().has_value() || mid == sctp_mid().value());
2080 RTC_LOG(LS_INFO) << "Creating data channel, mid=" << mid;
Steve Antonfa2260d2017-12-29 00:38:232081
Florent Castelli8037fc62024-08-29 13:00:402082 std::optional<std::string> transport_name =
Tommi840cf782023-10-21 14:47:562083 network_thread()->BlockingCall([&] {
2084 RTC_DCHECK_RUN_ON(network_thread());
2085 return SetupDataChannelTransport_n(mid);
2086 });
2087 if (!transport_name)
2088 return false;
2089
Tommiaa3c9f22023-04-18 10:19:192090 sctp_mid_s_ = std::string(mid);
Tommi840cf782023-10-21 14:47:562091 SetSctpTransportName(transport_name.value());
2092
2093 return true;
Tomas Gunnarsson92eebef2021-02-10 12:05:442094}
2095
Tommi840cf782023-10-21 14:47:562096void PeerConnection::DestroyDataChannelTransport(RTCError error) {
Tomas Gunnarsson92eebef2021-02-10 12:05:442097 RTC_DCHECK_RUN_ON(signaling_thread());
Tommi840cf782023-10-21 14:47:562098 network_thread()->BlockingCall([&] {
2099 RTC_DCHECK_RUN_ON(network_thread());
2100 TeardownDataChannelTransport_n(error);
2101 });
Tomas Gunnarsson92eebef2021-02-10 12:05:442102 sctp_mid_s_.reset();
Henrik Boström46053e42023-01-20 12:18:532103 SetSctpTransportName("");
Tomas Gunnarsson92eebef2021-02-10 12:05:442104}
2105
Tommid2afbaf2023-03-02 09:51:162106void PeerConnection::OnSctpDataChannelStateChanged(
Tommi56548982023-03-27 16:07:342107 int channel_id,
Tommid2afbaf2023-03-02 09:51:162108 DataChannelInterface::DataState state) {
2109 RTC_DCHECK_RUN_ON(signaling_thread());
2110 if (stats_collector_)
Tommi56548982023-03-27 16:07:342111 stats_collector_->OnSctpDataChannelStateChanged(channel_id, state);
deadbeefab9b2d12015-10-14 18:33:112112}
2113
Karl Wibergfb3be392019-03-22 13:13:222114PeerConnection::InitializePortAllocatorResult
2115PeerConnection::InitializePortAllocator_n(
Harald Alvestrandb2a74782018-06-28 11:54:072116 const cricket::ServerAddresses& stun_servers,
2117 const std::vector<cricket::RelayServerConfig>& turn_servers,
Taylor Brandstettera1c30352016-05-13 15:15:112118 const RTCConfiguration& configuration) {
Karl Wibergfb3be392019-03-22 13:13:222119 RTC_DCHECK_RUN_ON(network_thread());
2120
Taylor Brandstetterf8e65772016-06-28 00:20:152121 port_allocator_->Initialize();
Taylor Brandstettera1c30352016-05-13 15:15:112122 // To handle both internal and externally created port allocator, we will
2123 // enable BUNDLE here.
Karl Wibergfb3be392019-03-22 13:13:222124 int port_allocator_flags = port_allocator_->flags();
2125 port_allocator_flags |= cricket::PORTALLOCATOR_ENABLE_SHARED_SOCKET |
2126 cricket::PORTALLOCATOR_ENABLE_IPV6 |
2127 cricket::PORTALLOCATOR_ENABLE_IPV6_ON_WIFI;
Henrik Boströma445e6a2022-12-01 09:25:122128 if (trials().IsDisabled("WebRTC-IPv6Default")) {
Karl Wibergfb3be392019-03-22 13:13:222129 port_allocator_flags &= ~(cricket::PORTALLOCATOR_ENABLE_IPV6);
Taylor Brandstettera1c30352016-05-13 15:15:112130 }
zhihuangb09b3f92017-03-07 22:40:512131 if (configuration.disable_ipv6_on_wifi) {
Karl Wibergfb3be392019-03-22 13:13:222132 port_allocator_flags &= ~(cricket::PORTALLOCATOR_ENABLE_IPV6_ON_WIFI);
Mirko Bonadei675513b2017-11-09 10:09:252133 RTC_LOG(LS_INFO) << "IPv6 candidates on Wi-Fi are disabled.";
zhihuangb09b3f92017-03-07 22:40:512134 }
2135
Taylor Brandstettera1c30352016-05-13 15:15:112136 if (configuration.tcp_candidate_policy == kTcpCandidatePolicyDisabled) {
Karl Wibergfb3be392019-03-22 13:13:222137 port_allocator_flags |= cricket::PORTALLOCATOR_DISABLE_TCP;
Mirko Bonadei675513b2017-11-09 10:09:252138 RTC_LOG(LS_INFO) << "TCP candidates are disabled.";
Taylor Brandstettera1c30352016-05-13 15:15:112139 }
2140
honghaiz60347052016-06-01 01:29:122141 if (configuration.candidate_network_policy ==
2142 kCandidateNetworkPolicyLowCost) {
Karl Wibergfb3be392019-03-22 13:13:222143 port_allocator_flags |= cricket::PORTALLOCATOR_DISABLE_COSTLY_NETWORKS;
Mirko Bonadei675513b2017-11-09 10:09:252144 RTC_LOG(LS_INFO) << "Do not gather candidates on high-cost networks";
honghaiz60347052016-06-01 01:29:122145 }
2146
Daniel Lazarenko2870b0a2018-01-25 09:30:222147 if (configuration.disable_link_local_networks) {
Karl Wibergfb3be392019-03-22 13:13:222148 port_allocator_flags |= cricket::PORTALLOCATOR_DISABLE_LINK_LOCAL_NETWORKS;
Daniel Lazarenko2870b0a2018-01-25 09:30:222149 RTC_LOG(LS_INFO) << "Disable candidates on link-local network interfaces.";
2150 }
2151
Karl Wibergfb3be392019-03-22 13:13:222152 port_allocator_->set_flags(port_allocator_flags);
Taylor Brandstettera1c30352016-05-13 15:15:112153 // No step delay is used while allocating ports.
2154 port_allocator_->set_step_delay(cricket::kMinimumStepDelay);
Qingsi Wangc129c352019-04-18 17:41:582155 port_allocator_->SetCandidateFilter(
Taylor Brandstettera1c30352016-05-13 15:15:112156 ConvertIceTransportTypeToCandidateFilter(configuration.type));
deadbeefd21eab3e2017-07-26 23:50:112157 port_allocator_->set_max_ipv6_networks(configuration.max_ipv6_networks);
Taylor Brandstettera1c30352016-05-13 15:15:112158
Harald Alvestrandb2a74782018-06-28 11:54:072159 auto turn_servers_copy = turn_servers;
Benjamin Wright6f80f092018-08-14 00:06:262160 for (auto& turn_server : turn_servers_copy) {
2161 turn_server.tls_cert_verifier = tls_cert_verifier_.get();
Benjamin Wrightd6f86e82018-05-08 20:12:252162 }
Taylor Brandstettera1c30352016-05-13 15:15:112163 // Call this last since it may create pooled allocator sessions using the
2164 // properties set above.
Qingsi Wangdb53f8e2018-02-20 22:45:492165 port_allocator_->SetConfiguration(
Benjamin Wright6f80f092018-08-14 00:06:262166 stun_servers, std::move(turn_servers_copy),
Honghai Zhangf8998cf2019-10-14 18:27:502167 configuration.ice_candidate_pool_size,
2168 configuration.GetTurnPortPrunePolicy(), configuration.turn_customizer,
Qingsi Wangdb53f8e2018-02-20 22:45:492169 configuration.stun_candidate_keepalive_interval);
Karl Wibergfb3be392019-03-22 13:13:222170
2171 InitializePortAllocatorResult res;
2172 res.enable_ipv6 = port_allocator_flags & cricket::PORTALLOCATOR_ENABLE_IPV6;
2173 return res;
Taylor Brandstettera1c30352016-05-13 15:15:112174}
2175
deadbeef91dd5672016-05-18 23:55:302176bool PeerConnection::ReconfigurePortAllocator_n(
deadbeef293e9262017-01-11 20:28:302177 const cricket::ServerAddresses& stun_servers,
2178 const std::vector<cricket::RelayServerConfig>& turn_servers,
2179 IceTransportsType type,
2180 int candidate_pool_size,
Honghai Zhangf8998cf2019-10-14 18:27:502181 PortPrunePolicy turn_port_prune_policy,
Harald Alvestranda6544372023-11-13 09:33:562182 TurnCustomizer* turn_customizer,
Florent Castelli8037fc62024-08-29 13:00:402183 std::optional<int> stun_candidate_keepalive_interval,
Karl Wiberg739506e2019-04-03 09:37:282184 bool have_local_description) {
Harald Alvestrandf598e492020-11-04 05:54:102185 RTC_DCHECK_RUN_ON(network_thread());
Qingsi Wangc129c352019-04-18 17:41:582186 port_allocator_->SetCandidateFilter(
deadbeef293e9262017-01-11 20:28:302187 ConvertIceTransportTypeToCandidateFilter(type));
Benjamin Wright6f80f092018-08-14 00:06:262188 // Add the custom tls turn servers if they exist.
2189 auto turn_servers_copy = turn_servers;
2190 for (auto& turn_server : turn_servers_copy) {
2191 turn_server.tls_cert_verifier = tls_cert_verifier_.get();
2192 }
Taylor Brandstettera1c30352016-05-13 15:15:112193 // Call this last since it may create pooled allocator sessions using the
2194 // candidate filter set above.
deadbeef6de92f92016-12-13 02:49:322195 return port_allocator_->SetConfiguration(
Benjamin Wright6f80f092018-08-14 00:06:262196 stun_servers, std::move(turn_servers_copy), candidate_pool_size,
Honghai Zhangf8998cf2019-10-14 18:27:502197 turn_port_prune_policy, turn_customizer,
2198 stun_candidate_keepalive_interval);
Taylor Brandstettera1c30352016-05-13 15:15:112199}
2200
Elad Alon99c3fe52017-10-13 14:29:402201bool PeerConnection::StartRtcEventLog_w(
Bjorn Tereliusde939432017-11-20 16:38:142202 std::unique_ptr<RtcEventLogOutput> output,
2203 int64_t output_period_ms) {
Karl Wibergb03ab712019-02-14 10:59:572204 RTC_DCHECK_RUN_ON(worker_thread());
Danil Chapovalov49c35d32023-11-27 11:55:392205 if (!worker_thread_safety_->alive()) {
zhihuang77985012017-02-07 23:45:162206 return false;
2207 }
Danil Chapovalov3bdb49b2023-11-30 07:59:392208 return env_.event_log().StartLogging(std::move(output), output_period_ms);
ivoc14d5dbe2016-07-04 14:06:552209}
2210
2211void PeerConnection::StopRtcEventLog_w() {
Karl Wibergb03ab712019-02-14 10:59:572212 RTC_DCHECK_RUN_ON(worker_thread());
Danil Chapovalov3bdb49b2023-11-30 07:59:392213 env_.event_log().StopLogging();
ivoc14d5dbe2016-07-04 14:06:552214}
nisseeaabdf62017-05-05 09:23:022215
Florent Castelli8037fc62024-08-29 13:00:402216std::optional<rtc::SSLRole> PeerConnection::GetSctpSslRole_n() {
Tommic61eee22023-03-22 07:25:382217 RTC_DCHECK_RUN_ON(network_thread());
Tommi335d0842023-03-25 09:56:182218 return sctp_mid_n_ ? transport_controller_->GetDtlsRole(*sctp_mid_n_)
Florent Castelli8037fc62024-08-29 13:00:402219 : std::nullopt;
Steve Anton75737c02017-11-06 18:37:172220}
2221
2222bool PeerConnection::GetSslRole(const std::string& content_name,
2223 rtc::SSLRole* role) {
Karl Wiberg2cc368f2019-04-02 09:31:562224 RTC_DCHECK_RUN_ON(signaling_thread());
Steve Anton75737c02017-11-06 18:37:172225 if (!local_description() || !remote_description()) {
Mirko Bonadei675513b2017-11-09 10:09:252226 RTC_LOG(LS_INFO)
2227 << "Local and Remote descriptions must be applied to get the "
Jonas Olsson45cc8902018-02-13 09:37:072228 "SSL Role of the session.";
Steve Anton75737c02017-11-06 18:37:172229 return false;
2230 }
2231
Danil Chapovalov9e09a1f2022-09-08 16:38:102232 auto dtls_role = network_thread()->BlockingCall([this, content_name]() {
2233 RTC_DCHECK_RUN_ON(network_thread());
2234 return transport_controller_->GetDtlsRole(content_name);
2235 });
Zhi Huange830e682018-03-30 17:48:352236 if (dtls_role) {
2237 *role = *dtls_role;
2238 return true;
2239 }
2240 return false;
Steve Anton75737c02017-11-06 18:37:172241}
2242
Steve Anton75737c02017-11-06 18:37:172243bool PeerConnection::GetTransportDescription(
2244 const SessionDescription* description,
2245 const std::string& content_name,
2246 cricket::TransportDescription* tdesc) {
2247 if (!description || !tdesc) {
2248 return false;
2249 }
2250 const TransportInfo* transport_info =
2251 description->GetTransportInfoByName(content_name);
2252 if (!transport_info) {
2253 return false;
2254 }
2255 *tdesc = transport_info->description;
2256 return true;
2257}
2258
Taylor Brandstetter3a034e12020-07-09 22:32:342259std::vector<DataChannelStats> PeerConnection::GetDataChannelStats() const {
Tommif9e13f82023-04-06 19:21:452260 RTC_DCHECK_RUN_ON(network_thread());
Tomas Gunnarsson2e94de52020-06-16 14:54:102261 return data_channel_controller_.GetDataChannelStats();
2262}
2263
Florent Castelli8037fc62024-08-29 13:00:402264std::optional<std::string> PeerConnection::sctp_transport_name() const {
Karl Wiberg2cc368f2019-04-02 09:31:562265 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrandbc32c562022-02-09 12:08:472266 if (sctp_mid_s_ && transport_controller_copy_)
Tomas Gunnarsson92eebef2021-02-10 12:05:442267 return sctp_transport_name_s_;
Florent Castelli8037fc62024-08-29 13:00:402268 return std::optional<std::string>();
Zhi Huange830e682018-03-30 17:48:352269}
2270
Henrik Boström46053e42023-01-20 12:18:532271void PeerConnection::SetSctpTransportName(std::string sctp_transport_name) {
2272 RTC_DCHECK_RUN_ON(signaling_thread());
2273 sctp_transport_name_s_ = std::move(sctp_transport_name);
2274 ClearStatsCache();
2275}
2276
Florent Castelli8037fc62024-08-29 13:00:402277std::optional<std::string> PeerConnection::sctp_mid() const {
Tomas Gunnarssonbfd9ba82021-04-18 09:55:572278 RTC_DCHECK_RUN_ON(signaling_thread());
2279 return sctp_mid_s_;
2280}
2281
Qingsi Wang72a43a12018-02-21 00:03:182282cricket::CandidateStatsList PeerConnection::GetPooledCandidateStats() const {
Tomas Gunnarssone1c8a432021-04-08 13:15:282283 RTC_DCHECK_RUN_ON(network_thread());
2284 if (!network_thread_safety_->alive())
2285 return {};
Philipp Hancke6e57ca22022-06-09 13:58:182286 cricket::CandidateStatsList candidate_stats_list;
2287 port_allocator_->GetCandidateStatsFromPooledSessions(&candidate_stats_list);
2288 return candidate_stats_list;
Qingsi Wang72a43a12018-02-21 00:03:182289}
2290
Steve Anton5dfde182018-02-06 18:34:402291std::map<std::string, cricket::TransportStats>
2292PeerConnection::GetTransportStatsByNames(
2293 const std::set<std::string>& transport_names) {
Markus Handell518669d2021-06-07 11:30:462294 TRACE_EVENT0("webrtc", "PeerConnection::GetTransportStatsByNames");
Karl Wiberg2cc368f2019-04-02 09:31:562295 RTC_DCHECK_RUN_ON(network_thread());
Tomas Gunnarssone1c8a432021-04-08 13:15:282296 if (!network_thread_safety_->alive())
2297 return {};
2298
2299 rtc::Thread::ScopedDisallowBlockingCalls no_blocking_calls;
Steve Anton5dfde182018-02-06 18:34:402300 std::map<std::string, cricket::TransportStats> transport_stats_by_name;
2301 for (const std::string& transport_name : transport_names) {
2302 cricket::TransportStats transport_stats;
2303 bool success =
2304 transport_controller_->GetStats(transport_name, &transport_stats);
2305 if (success) {
2306 transport_stats_by_name[transport_name] = std::move(transport_stats);
2307 } else {
2308 RTC_LOG(LS_ERROR) << "Failed to get transport stats for transport_name="
2309 << transport_name;
2310 }
2311 }
2312 return transport_stats_by_name;
Steve Anton75737c02017-11-06 18:37:172313}
2314
2315bool PeerConnection::GetLocalCertificate(
2316 const std::string& transport_name,
2317 rtc::scoped_refptr<rtc::RTCCertificate>* certificate) {
Tomas Gunnarssone1c8a432021-04-08 13:15:282318 RTC_DCHECK_RUN_ON(network_thread());
2319 if (!network_thread_safety_->alive() || !certificate) {
Zhi Huange830e682018-03-30 17:48:352320 return false;
2321 }
2322 *certificate = transport_controller_->GetLocalCertificate(transport_name);
2323 return *certificate != nullptr;
Steve Anton75737c02017-11-06 18:37:172324}
2325
Taylor Brandstetterc3928662018-02-23 21:04:512326std::unique_ptr<rtc::SSLCertChain> PeerConnection::GetRemoteSSLCertChain(
Steve Anton75737c02017-11-06 18:37:172327 const std::string& transport_name) {
Tomas Gunnarssone1c8a432021-04-08 13:15:282328 RTC_DCHECK_RUN_ON(network_thread());
Taylor Brandstetterc3928662018-02-23 21:04:512329 return transport_controller_->GetRemoteSSLCertChain(transport_name);
Steve Anton75737c02017-11-06 18:37:172330}
2331
Steve Anton75737c02017-11-06 18:37:172332bool PeerConnection::IceRestartPending(const std::string& content_name) const {
Karl Wibergf73f7d62019-04-08 13:36:532333 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand9cd199d2020-10-27 07:10:432334 return sdp_handler_->IceRestartPending(content_name);
Steve Anton75737c02017-11-06 18:37:172335}
2336
Steve Anton75737c02017-11-06 18:37:172337bool PeerConnection::NeedsIceRestart(const std::string& content_name) const {
Danil Chapovalov9e09a1f2022-09-08 16:38:102338 return network_thread()->BlockingCall([this, &content_name] {
Tommic3257d02021-02-10 17:40:082339 RTC_DCHECK_RUN_ON(network_thread());
2340 return transport_controller_->NeedsIceRestart(content_name);
2341 });
Steve Anton75737c02017-11-06 18:37:172342}
2343
Alex Loiko9289eda2018-11-23 16:18:592344void PeerConnection::OnTransportControllerConnectionState(
2345 cricket::IceConnectionState state) {
2346 switch (state) {
2347 case cricket::kIceConnectionConnecting:
2348 // If the current state is Connected or Completed, then there were
2349 // writable channels but now there are not, so the next state must
2350 // be Disconnected.
2351 // kIceConnectionConnecting is currently used as the default,
2352 // un-connected state by the TransportController, so its only use is
2353 // detecting disconnections.
2354 if (ice_connection_state_ ==
2355 PeerConnectionInterface::kIceConnectionConnected ||
2356 ice_connection_state_ ==
2357 PeerConnectionInterface::kIceConnectionCompleted) {
2358 SetIceConnectionState(
2359 PeerConnectionInterface::kIceConnectionDisconnected);
2360 }
2361 break;
2362 case cricket::kIceConnectionFailed:
2363 SetIceConnectionState(PeerConnectionInterface::kIceConnectionFailed);
2364 break;
2365 case cricket::kIceConnectionConnected:
2366 RTC_LOG(LS_INFO) << "Changing to ICE connected state because "
2367 "all transports are writable.";
Tommidba22d32023-06-01 14:08:522368 {
2369 std::vector<RtpTransceiverProxyRefPtr> transceivers;
2370 if (ConfiguredForMedia()) {
2371 transceivers = rtp_manager()->transceivers()->List();
2372 }
2373
2374 network_thread()->PostTask(
2375 SafeTask(network_thread_safety_,
2376 [this, transceivers = std::move(transceivers)] {
2377 RTC_DCHECK_RUN_ON(network_thread());
2378 ReportTransportStats(std::move(transceivers));
2379 }));
2380 }
2381
Alex Loiko9289eda2018-11-23 16:18:592382 SetIceConnectionState(PeerConnectionInterface::kIceConnectionConnected);
2383 NoteUsageEvent(UsageEvent::ICE_STATE_CONNECTED);
2384 break;
2385 case cricket::kIceConnectionCompleted:
2386 RTC_LOG(LS_INFO) << "Changing to ICE completed state because "
2387 "all transports are complete.";
2388 if (ice_connection_state_ !=
2389 PeerConnectionInterface::kIceConnectionConnected) {
2390 // If jumping directly from "checking" to "connected",
2391 // signal "connected" first.
2392 SetIceConnectionState(PeerConnectionInterface::kIceConnectionConnected);
2393 }
2394 SetIceConnectionState(PeerConnectionInterface::kIceConnectionCompleted);
Tomas Gunnarsson2001dc32021-04-06 09:36:002395
Alex Loiko9289eda2018-11-23 16:18:592396 NoteUsageEvent(UsageEvent::ICE_STATE_CONNECTED);
Alex Loiko9289eda2018-11-23 16:18:592397 break;
2398 default:
Artem Titovd3251962021-11-15 15:57:072399 RTC_DCHECK_NOTREACHED();
Alex Loiko9289eda2018-11-23 16:18:592400 }
2401}
2402
Steve Anton75737c02017-11-06 18:37:172403void PeerConnection::OnTransportControllerCandidatesGathered(
2404 const std::string& transport_name,
2405 const cricket::Candidates& candidates) {
Tomas Gunnarsson20f74562021-02-04 09:22:502406 // TODO(bugs.webrtc.org/12427): Expect this to come in on the network thread
2407 // (not signaling as it currently does), handle appropriately.
Steve Anton75737c02017-11-06 18:37:172408 int sdp_mline_index;
2409 if (!GetLocalCandidateMediaIndex(transport_name, &sdp_mline_index)) {
Mirko Bonadei675513b2017-11-09 10:09:252410 RTC_LOG(LS_ERROR)
2411 << "OnTransportControllerCandidatesGathered: content name "
2412 << transport_name << " not found";
Steve Anton75737c02017-11-06 18:37:172413 return;
2414 }
2415
2416 for (cricket::Candidates::const_iterator citer = candidates.begin();
2417 citer != candidates.end(); ++citer) {
2418 // Use transport_name as the candidate media id.
2419 std::unique_ptr<JsepIceCandidate> candidate(
2420 new JsepIceCandidate(transport_name, sdp_mline_index, *citer));
Harald Alvestrand9cd199d2020-10-27 07:10:432421 sdp_handler_->AddLocalIceCandidate(candidate.get());
Steve Anton75737c02017-11-06 18:37:172422 OnIceCandidate(std::move(candidate));
2423 }
2424}
2425
Eldar Relloda13ea22019-06-01 09:23:432426void PeerConnection::OnTransportControllerCandidateError(
2427 const cricket::IceCandidateErrorEvent& event) {
Eldar Rello0095d372019-12-02 20:22:072428 OnIceCandidateError(event.address, event.port, event.url, event.error_code,
Eldar Relloda13ea22019-06-01 09:23:432429 event.error_text);
2430}
2431
Steve Anton75737c02017-11-06 18:37:172432void PeerConnection::OnTransportControllerCandidatesRemoved(
2433 const std::vector<cricket::Candidate>& candidates) {
Steve Anton75737c02017-11-06 18:37:172434 // Sanity check.
2435 for (const cricket::Candidate& candidate : candidates) {
2436 if (candidate.transport_name().empty()) {
Mirko Bonadei675513b2017-11-09 10:09:252437 RTC_LOG(LS_ERROR) << "OnTransportControllerCandidatesRemoved: "
Jonas Olsson45cc8902018-02-13 09:37:072438 "empty content name in candidate "
Mirko Bonadei675513b2017-11-09 10:09:252439 << candidate.ToString();
Steve Anton75737c02017-11-06 18:37:172440 return;
2441 }
2442 }
Harald Alvestrand9cd199d2020-10-27 07:10:432443 sdp_handler_->RemoveLocalIceCandidates(candidates);
Steve Anton75737c02017-11-06 18:37:172444 OnIceCandidatesRemoved(candidates);
2445}
2446
Alex Drake00c7ecf2019-08-06 17:54:472447void PeerConnection::OnTransportControllerCandidateChanged(
2448 const cricket::CandidatePairChangeEvent& event) {
2449 OnSelectedCandidatePairChanged(event);
2450}
2451
Steve Anton75737c02017-11-06 18:37:172452void PeerConnection::OnTransportControllerDtlsHandshakeError(
2453 rtc::SSLHandshakeError error) {
Qingsi Wang7fc821d2018-07-12 19:54:532454 RTC_HISTOGRAM_ENUMERATION(
2455 "WebRTC.PeerConnection.DtlsHandshakeError", static_cast<int>(error),
2456 static_cast<int>(rtc::SSLHandshakeError::MAX_VALUE));
Steve Anton75737c02017-11-06 18:37:172457}
2458
Steve Anton75737c02017-11-06 18:37:172459// Returns the media index for a local ice candidate given the content name.
2460bool PeerConnection::GetLocalCandidateMediaIndex(
2461 const std::string& content_name,
2462 int* sdp_mline_index) {
2463 if (!local_description() || !sdp_mline_index) {
2464 return false;
2465 }
2466
2467 bool content_found = false;
2468 const ContentInfos& contents = local_description()->description()->contents();
2469 for (size_t index = 0; index < contents.size(); ++index) {
2470 if (contents[index].name == content_name) {
2471 *sdp_mline_index = static_cast<int>(index);
2472 content_found = true;
2473 break;
2474 }
2475 }
2476 return content_found;
2477}
2478
Steve Anton75737c02017-11-06 18:37:172479Call::Stats PeerConnection::GetCallStats() {
2480 if (!worker_thread()->IsCurrent()) {
Danil Chapovalov9e09a1f2022-09-08 16:38:102481 return worker_thread()->BlockingCall([this] { return GetCallStats(); });
Steve Anton75737c02017-11-06 18:37:172482 }
Karl Wiberg6cab5c82019-03-26 08:57:012483 RTC_DCHECK_RUN_ON(worker_thread());
Henrik Boströme88c95e2020-07-08 09:18:502484 rtc::Thread::ScopedDisallowBlockingCalls no_blocking_calls;
Steve Anton75737c02017-11-06 18:37:172485 if (call_) {
2486 return call_->GetStats();
2487 } else {
2488 return Call::Stats();
2489 }
2490}
2491
Florent Castelli8037fc62024-08-29 13:00:402492std::optional<AudioDeviceModule::Stats> PeerConnection::GetAudioDeviceStats() {
Fredrik Hernqvistefbe7532023-01-13 15:42:362493 if (context_->media_engine()) {
2494 return context_->media_engine()->voice().GetAudioDeviceStats();
2495 }
Florent Castelli8037fc62024-08-29 13:00:402496 return std::nullopt;
Fredrik Hernqvistefbe7532023-01-13 15:42:362497}
2498
Florent Castelli8037fc62024-08-29 13:00:402499std::optional<std::string> PeerConnection::SetupDataChannelTransport_n(
Tommiaa3c9f22023-04-18 10:19:192500 absl::string_view mid) {
2501 sctp_mid_n_ = std::string(mid);
Bjorn A Mellembc3eebc2019-09-23 21:53:542502 DataChannelTransportInterface* transport =
Tommiaa3c9f22023-04-18 10:19:192503 transport_controller_->GetDataChannelTransport(*sctp_mid_n_);
Bjorn A Mellembc3eebc2019-09-23 21:53:542504 if (!transport) {
Piotr (Peter) Slatalab1ae10b2019-03-01 19:14:052505 RTC_LOG(LS_ERROR)
Bjorn A Mellemb689af42019-08-21 17:44:592506 << "Data channel transport is not available for data channels, mid="
2507 << mid;
Florent Castelli8037fc62024-08-29 13:00:402508 sctp_mid_n_ = std::nullopt;
2509 return std::nullopt;
Bjorn Mellem175aa2e2018-11-08 19:23:222510 }
2511
Florent Castelli8037fc62024-08-29 13:00:402512 std::optional<std::string> transport_name;
Tomas Gunnarssone1c8a432021-04-08 13:15:282513 cricket::DtlsTransportInternal* dtls_transport =
Tommiaa3c9f22023-04-18 10:19:192514 transport_controller_->GetDtlsTransport(*sctp_mid_n_);
Tomas Gunnarsson92eebef2021-02-10 12:05:442515 if (dtls_transport) {
Tommiaa3c9f22023-04-18 10:19:192516 transport_name = dtls_transport->transport_name();
2517 } else {
2518 // Make sure we still set a valid string.
2519 transport_name = std::string("");
Tomas Gunnarsson92eebef2021-02-10 12:05:442520 }
Bjorn A Mellembc3eebc2019-09-23 21:53:542521
Tommiaa3c9f22023-04-18 10:19:192522 data_channel_controller_.SetupDataChannelTransport_n(transport);
2523
2524 return transport_name;
Bjorn Mellem175aa2e2018-11-08 19:23:222525}
2526
Tommib00d63c2023-04-12 17:49:532527void PeerConnection::TeardownDataChannelTransport_n(RTCError error) {
Tomas Gunnarssond69e0702021-04-07 13:14:432528 if (sctp_mid_n_) {
Artem Titov880fa812021-07-30 20:30:232529 // `sctp_mid_` may still be active through an SCTP transport. If not, unset
Tomas Gunnarssond69e0702021-04-07 13:14:432530 // it.
2531 RTC_LOG(LS_INFO) << "Tearing down data channel transport for mid="
2532 << *sctp_mid_n_;
2533 sctp_mid_n_.reset();
2534 }
2535
Tommib00d63c2023-04-12 17:49:532536 data_channel_controller_.TeardownDataChannelTransport_n(error);
Bjorn Mellem175aa2e2018-11-08 19:23:222537}
2538
Steve Anton75737c02017-11-06 18:37:172539// Returns false if bundle is enabled and rtcp_mux is disabled.
Henrik Boströmf8187e02021-04-26 19:04:262540bool PeerConnection::ValidateBundleSettings(
2541 const SessionDescription* desc,
2542 const std::map<std::string, const cricket::ContentGroup*>&
2543 bundle_groups_by_mid) {
2544 if (bundle_groups_by_mid.empty())
Steve Anton75737c02017-11-06 18:37:172545 return true;
2546
Steve Anton75737c02017-11-06 18:37:172547 const cricket::ContentInfos& contents = desc->contents();
2548 for (cricket::ContentInfos::const_iterator citer = contents.begin();
2549 citer != contents.end(); ++citer) {
2550 const cricket::ContentInfo* content = (&*citer);
2551 RTC_DCHECK(content != NULL);
Henrik Boströmf8187e02021-04-26 19:04:262552 auto it = bundle_groups_by_mid.find(content->name);
Philipp Hancke32dae4b2023-05-12 04:53:552553 if (it != bundle_groups_by_mid.end() &&
2554 !(content->rejected || content->bundle_only) &&
Steve Anton5adfafd2017-12-21 00:34:002555 content->type == MediaProtocolType::kRtp) {
Steve Anton75737c02017-11-06 18:37:172556 if (!HasRtcpMuxEnabled(content))
2557 return false;
2558 }
2559 }
2560 // RTCP-MUX is enabled in all the contents.
2561 return true;
2562}
2563
Philipp Hancke54b925c2021-01-28 08:56:392564void PeerConnection::ReportSdpBundleUsage(
2565 const SessionDescriptionInterface& remote_description) {
2566 RTC_DCHECK_RUN_ON(signaling_thread());
2567
2568 bool using_bundle =
2569 remote_description.description()->HasGroup(cricket::GROUP_TYPE_BUNDLE);
2570 int num_audio_mlines = 0;
2571 int num_video_mlines = 0;
2572 int num_data_mlines = 0;
2573 for (const ContentInfo& content :
2574 remote_description.description()->contents()) {
2575 cricket::MediaType media_type = content.media_description()->type();
2576 if (media_type == cricket::MEDIA_TYPE_AUDIO) {
2577 num_audio_mlines += 1;
2578 } else if (media_type == cricket::MEDIA_TYPE_VIDEO) {
2579 num_video_mlines += 1;
2580 } else if (media_type == cricket::MEDIA_TYPE_DATA) {
2581 num_data_mlines += 1;
2582 }
2583 }
2584 bool simple = num_audio_mlines <= 1 && num_video_mlines <= 1;
2585 BundleUsage usage = kBundleUsageMax;
2586 if (num_audio_mlines == 0 && num_video_mlines == 0) {
2587 if (num_data_mlines > 0) {
2588 usage = using_bundle ? kBundleUsageBundleDatachannelOnly
2589 : kBundleUsageNoBundleDatachannelOnly;
2590 } else {
2591 usage = kBundleUsageEmpty;
2592 }
Harald Alvestrandfa67aef2021-12-08 14:30:552593 } else if (configuration_.sdp_semantics == SdpSemantics::kPlanB_DEPRECATED) {
Philipp Hancke54b925c2021-01-28 08:56:392594 // In plan-b, simple/complex usage will not show up in the number of
2595 // m-lines or BUNDLE.
2596 usage = using_bundle ? kBundleUsageBundlePlanB : kBundleUsageNoBundlePlanB;
2597 } else {
2598 if (simple) {
2599 usage =
2600 using_bundle ? kBundleUsageBundleSimple : kBundleUsageNoBundleSimple;
2601 } else {
2602 usage = using_bundle ? kBundleUsageBundleComplex
2603 : kBundleUsageNoBundleComplex;
2604 }
2605 }
2606 RTC_HISTOGRAM_ENUMERATION("WebRTC.PeerConnection.BundleUsage", usage,
2607 kBundleUsageMax);
2608}
2609
Qingsi Wang1ba5dec2019-08-19 18:57:172610void PeerConnection::ReportIceCandidateCollected(
2611 const cricket::Candidate& candidate) {
2612 NoteUsageEvent(UsageEvent::CANDIDATE_COLLECTED);
2613 if (candidate.address().IsPrivateIP()) {
2614 NoteUsageEvent(UsageEvent::PRIVATE_CANDIDATE_COLLECTED);
2615 }
2616 if (candidate.address().IsUnresolvedIP()) {
2617 NoteUsageEvent(UsageEvent::MDNS_CANDIDATE_COLLECTED);
2618 }
2619 if (candidate.address().family() == AF_INET6) {
2620 NoteUsageEvent(UsageEvent::IPV6_CANDIDATE_COLLECTED);
2621 }
2622}
2623
Harald Alvestrand8ebba742018-05-31 12:00:342624void PeerConnection::NoteUsageEvent(UsageEvent event) {
2625 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand44d0dff2020-10-09 05:43:532626 usage_pattern_.NoteUsageEvent(event);
Harald Alvestrand8ebba742018-05-31 12:00:342627}
2628
Tomas Gunnarsson8cb97062021-02-08 17:57:042629// Asynchronously adds remote candidates on the network thread.
2630void PeerConnection::AddRemoteCandidate(const std::string& mid,
2631 const cricket::Candidate& candidate) {
2632 RTC_DCHECK_RUN_ON(signaling_thread());
2633
Byoungchan Lee5a925772022-10-18 17:43:182634 if (candidate.network_type() != rtc::ADAPTER_TYPE_UNKNOWN) {
2635 RTC_DLOG(LS_WARNING) << "Using candidate with adapter type set - this "
2636 "should only happen in test";
2637 }
2638
2639 // Clear fields that do not make sense as remote candidates.
2640 cricket::Candidate new_candidate(candidate);
2641 new_candidate.set_network_type(rtc::ADAPTER_TYPE_UNKNOWN);
2642 new_candidate.set_relay_protocol("");
2643 new_candidate.set_underlying_type_for_vpn(rtc::ADAPTER_TYPE_UNKNOWN);
2644
Danil Chapovalova30439b2022-07-07 08:08:492645 network_thread()->PostTask(SafeTask(
Byoungchan Lee5a925772022-10-18 17:43:182646 network_thread_safety_, [this, mid = mid, candidate = new_candidate] {
Tomas Gunnarsson8cb97062021-02-08 17:57:042647 RTC_DCHECK_RUN_ON(network_thread());
2648 std::vector<cricket::Candidate> candidates = {candidate};
2649 RTCError error =
2650 transport_controller_->AddRemoteCandidates(mid, candidates);
2651 if (error.ok()) {
Danil Chapovalova30439b2022-07-07 08:08:492652 signaling_thread()->PostTask(SafeTask(
Tomas Gunnarsson8cb97062021-02-08 17:57:042653 signaling_thread_safety_.flag(),
2654 [this, candidate = std::move(candidate)] {
2655 ReportRemoteIceCandidateAdded(candidate);
2656 // Candidates successfully submitted for checking.
2657 if (ice_connection_state() ==
2658 PeerConnectionInterface::kIceConnectionNew ||
2659 ice_connection_state() ==
2660 PeerConnectionInterface::kIceConnectionDisconnected) {
2661 // If state is New, then the session has just gotten its first
2662 // remote ICE candidates, so go to Checking. If state is
2663 // Disconnected, the session is re-using old candidates or
2664 // receiving additional ones, so go to Checking. If state is
2665 // Connected, stay Connected.
2666 // TODO(bemasc): If state is Connected, and the new candidates
2667 // are for a newly added transport, then the state actually
2668 // _should_ move to checking. Add a way to distinguish that
2669 // case.
2670 SetIceConnectionState(
2671 PeerConnectionInterface::kIceConnectionChecking);
2672 }
2673 // TODO(bemasc): If state is Completed, go back to Connected.
2674 }));
2675 } else {
2676 RTC_LOG(LS_WARNING) << error.message();
2677 }
2678 }));
2679}
2680
Harald Alvestrand8ebba742018-05-31 12:00:342681void PeerConnection::ReportUsagePattern() const {
Harald Alvestrand44d0dff2020-10-09 05:43:532682 usage_pattern_.ReportUsagePattern(observer_);
Harald Alvestrand8ebba742018-05-31 12:00:342683}
2684
Tomas Gunnarsson8cb97062021-02-08 17:57:042685void PeerConnection::ReportRemoteIceCandidateAdded(
2686 const cricket::Candidate& candidate) {
2687 RTC_DCHECK_RUN_ON(signaling_thread());
2688
2689 NoteUsageEvent(UsageEvent::REMOTE_CANDIDATE_ADDED);
2690
2691 if (candidate.address().IsPrivateIP()) {
2692 NoteUsageEvent(UsageEvent::REMOTE_PRIVATE_CANDIDATE_ADDED);
2693 }
2694 if (candidate.address().IsUnresolvedIP()) {
2695 NoteUsageEvent(UsageEvent::REMOTE_MDNS_CANDIDATE_ADDED);
2696 }
2697 if (candidate.address().family() == AF_INET6) {
2698 NoteUsageEvent(UsageEvent::REMOTE_IPV6_CANDIDATE_ADDED);
2699 }
2700}
2701
Steve Anton75737c02017-11-06 18:37:172702bool PeerConnection::SrtpRequired() const {
Tomas Gunnarsson3278a712021-03-30 15:23:422703 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand974044e2024-02-08 13:15:512704 return dtls_enabled_;
Steve Anton75737c02017-11-06 18:37:172705}
2706
2707void PeerConnection::OnTransportControllerGatheringState(
2708 cricket::IceGatheringState state) {
2709 RTC_DCHECK(signaling_thread()->IsCurrent());
2710 if (state == cricket::kIceGatheringGathering) {
2711 OnIceGatheringChange(PeerConnectionInterface::kIceGatheringGathering);
2712 } else if (state == cricket::kIceGatheringComplete) {
2713 OnIceGatheringChange(PeerConnectionInterface::kIceGatheringComplete);
Harald Alvestrandbedb6052020-08-20 12:50:102714 } else if (state == cricket::kIceGatheringNew) {
2715 OnIceGatheringChange(PeerConnectionInterface::kIceGatheringNew);
2716 } else {
2717 RTC_LOG(LS_ERROR) << "Unknown state received: " << state;
Artem Titovd3251962021-11-15 15:57:072718 RTC_DCHECK_NOTREACHED();
Steve Anton75737c02017-11-06 18:37:172719 }
2720}
2721
Tomas Gunnarsson2001dc32021-04-06 09:36:002722// Runs on network_thread().
Tommidba22d32023-06-01 14:08:522723void PeerConnection::ReportTransportStats(
2724 std::vector<RtpTransceiverProxyRefPtr> transceivers) {
Markus Handell518669d2021-06-07 11:30:462725 TRACE_EVENT0("webrtc", "PeerConnection::ReportTransportStats");
Tommic3257d02021-02-10 17:40:082726 rtc::Thread::ScopedDisallowBlockingCalls no_blocking_calls;
Steve Antonc7b964c2018-02-01 22:39:452727 std::map<std::string, std::set<cricket::MediaType>>
2728 media_types_by_transport_name;
Tommidba22d32023-06-01 14:08:522729 for (const auto& transceiver : transceivers) {
2730 if (transceiver->internal()->channel()) {
2731 std::string transport_name(
2732 transceiver->internal()->channel()->transport_name());
2733 media_types_by_transport_name[transport_name].insert(
2734 transceiver->media_type());
Steve Antonc7b964c2018-02-01 22:39:452735 }
Steve Anton75737c02017-11-06 18:37:172736 }
Tomas Gunnarsson2001dc32021-04-06 09:36:002737
Tomas Gunnarsson2001dc32021-04-06 09:36:002738 if (sctp_mid_n_) {
Tomas Gunnarssone1c8a432021-04-08 13:15:282739 cricket::DtlsTransportInternal* dtls_transport =
2740 transport_controller_->GetDtlsTransport(*sctp_mid_n_);
Tomas Gunnarsson2001dc32021-04-06 09:36:002741 if (dtls_transport) {
2742 media_types_by_transport_name[dtls_transport->transport_name()].insert(
2743 cricket::MEDIA_TYPE_DATA);
2744 }
Steve Anton75737c02017-11-06 18:37:172745 }
Zhi Huange830e682018-03-30 17:48:352746
Tomas Gunnarsson2001dc32021-04-06 09:36:002747 for (const auto& entry : media_types_by_transport_name) {
2748 const std::string& transport_name = entry.first;
2749 const std::set<cricket::MediaType> media_types = entry.second;
2750 cricket::TransportStats stats;
2751 if (transport_controller_->GetStats(transport_name, &stats)) {
2752 ReportBestConnectionState(stats);
2753 ReportNegotiatedCiphers(dtls_enabled_, stats, media_types);
2754 }
2755 }
Steve Anton75737c02017-11-06 18:37:172756}
Tomas Gunnarsson2001dc32021-04-06 09:36:002757
Steve Anton75737c02017-11-06 18:37:172758// Walk through the ConnectionInfos to gather best connection usage
2759// for IPv4 and IPv6.
Tommic3257d02021-02-10 17:40:082760// static (no member state required)
Steve Anton75737c02017-11-06 18:37:172761void PeerConnection::ReportBestConnectionState(
2762 const cricket::TransportStats& stats) {
Steve Antonc7b964c2018-02-01 22:39:452763 for (const cricket::TransportChannelStats& channel_stats :
2764 stats.channel_stats) {
2765 for (const cricket::ConnectionInfo& connection_info :
Jonas Oreland149dc722019-08-28 06:10:272766 channel_stats.ice_transport_stats.connection_infos) {
Steve Antonc7b964c2018-02-01 22:39:452767 if (!connection_info.best_connection) {
Steve Anton75737c02017-11-06 18:37:172768 continue;
2769 }
2770
Steve Antonc7b964c2018-02-01 22:39:452771 const cricket::Candidate& local = connection_info.local_candidate;
2772 const cricket::Candidate& remote = connection_info.remote_candidate;
Steve Anton75737c02017-11-06 18:37:172773
2774 // Increment the counter for IceCandidatePairType.
2775 if (local.protocol() == cricket::TCP_PROTOCOL_NAME ||
Tommi3b2b2af2024-01-17 13:19:412776 (local.is_relay() &&
Steve Anton75737c02017-11-06 18:37:172777 local.relay_protocol() == cricket::TCP_PROTOCOL_NAME)) {
Qingsi Wang7fc821d2018-07-12 19:54:532778 RTC_HISTOGRAM_ENUMERATION("WebRTC.PeerConnection.CandidatePairType_TCP",
2779 GetIceCandidatePairCounter(local, remote),
2780 kIceCandidatePairMax);
Steve Anton75737c02017-11-06 18:37:172781 } else if (local.protocol() == cricket::UDP_PROTOCOL_NAME) {
Qingsi Wang7fc821d2018-07-12 19:54:532782 RTC_HISTOGRAM_ENUMERATION("WebRTC.PeerConnection.CandidatePairType_UDP",
2783 GetIceCandidatePairCounter(local, remote),
2784 kIceCandidatePairMax);
Steve Anton75737c02017-11-06 18:37:172785 } else {
Karl Wibergc95b9392020-11-07 23:49:372786 RTC_CHECK_NOTREACHED();
Steve Anton75737c02017-11-06 18:37:172787 }
Steve Anton75737c02017-11-06 18:37:172788
2789 // Increment the counter for IP type.
2790 if (local.address().family() == AF_INET) {
Qingsi Wang7fc821d2018-07-12 19:54:532791 RTC_HISTOGRAM_ENUMERATION("WebRTC.PeerConnection.IPMetrics",
2792 kBestConnections_IPv4,
2793 kPeerConnectionAddressFamilyCounter_Max);
Steve Anton75737c02017-11-06 18:37:172794 } else if (local.address().family() == AF_INET6) {
Qingsi Wang7fc821d2018-07-12 19:54:532795 RTC_HISTOGRAM_ENUMERATION("WebRTC.PeerConnection.IPMetrics",
2796 kBestConnections_IPv6,
2797 kPeerConnectionAddressFamilyCounter_Max);
Steve Anton75737c02017-11-06 18:37:172798 } else {
Qingsi Wang1dac6d82018-12-12 23:28:472799 RTC_CHECK(!local.address().hostname().empty() &&
2800 local.address().IsUnresolvedIP());
Steve Anton75737c02017-11-06 18:37:172801 }
2802
2803 return;
2804 }
2805 }
2806}
2807
Tommic3257d02021-02-10 17:40:082808// static
Steve Anton75737c02017-11-06 18:37:172809void PeerConnection::ReportNegotiatedCiphers(
Tommic3257d02021-02-10 17:40:082810 bool dtls_enabled,
Steve Antonc7b964c2018-02-01 22:39:452811 const cricket::TransportStats& stats,
2812 const std::set<cricket::MediaType>& media_types) {
Tommic3257d02021-02-10 17:40:082813 if (!dtls_enabled || stats.channel_stats.empty()) {
Steve Anton75737c02017-11-06 18:37:172814 return;
2815 }
2816
2817 int srtp_crypto_suite = stats.channel_stats[0].srtp_crypto_suite;
2818 int ssl_cipher_suite = stats.channel_stats[0].ssl_cipher_suite;
Mirko Bonadei7750d802021-07-26 15:27:422819 if (srtp_crypto_suite == rtc::kSrtpInvalidCryptoSuite &&
2820 ssl_cipher_suite == rtc::kTlsNullWithNullNull) {
Steve Anton75737c02017-11-06 18:37:172821 return;
2822 }
2823
Mirko Bonadei7750d802021-07-26 15:27:422824 if (ssl_cipher_suite != rtc::kTlsNullWithNullNull) {
Qingsi Wang7fc821d2018-07-12 19:54:532825 for (cricket::MediaType media_type : media_types) {
2826 switch (media_type) {
2827 case cricket::MEDIA_TYPE_AUDIO:
2828 RTC_HISTOGRAM_ENUMERATION_SPARSE(
2829 "WebRTC.PeerConnection.SslCipherSuite.Audio", ssl_cipher_suite,
Mirko Bonadei7750d802021-07-26 15:27:422830 rtc::kSslCipherSuiteMaxValue);
Qingsi Wang7fc821d2018-07-12 19:54:532831 break;
2832 case cricket::MEDIA_TYPE_VIDEO:
2833 RTC_HISTOGRAM_ENUMERATION_SPARSE(
2834 "WebRTC.PeerConnection.SslCipherSuite.Video", ssl_cipher_suite,
Mirko Bonadei7750d802021-07-26 15:27:422835 rtc::kSslCipherSuiteMaxValue);
Qingsi Wang7fc821d2018-07-12 19:54:532836 break;
2837 case cricket::MEDIA_TYPE_DATA:
2838 RTC_HISTOGRAM_ENUMERATION_SPARSE(
2839 "WebRTC.PeerConnection.SslCipherSuite.Data", ssl_cipher_suite,
Mirko Bonadei7750d802021-07-26 15:27:422840 rtc::kSslCipherSuiteMaxValue);
Qingsi Wang7fc821d2018-07-12 19:54:532841 break;
2842 default:
Artem Titovd3251962021-11-15 15:57:072843 RTC_DCHECK_NOTREACHED();
Qingsi Wang7fc821d2018-07-12 19:54:532844 continue;
2845 }
Steve Antonc7b964c2018-02-01 22:39:452846 }
Steve Anton75737c02017-11-06 18:37:172847 }
Philipp Hancke36e4dd22023-09-28 09:02:212848
2849 uint16_t ssl_peer_signature_algorithm =
2850 stats.channel_stats[0].ssl_peer_signature_algorithm;
2851 if (ssl_peer_signature_algorithm != rtc::kSslSignatureAlgorithmUnknown) {
2852 for (cricket::MediaType media_type : media_types) {
2853 switch (media_type) {
2854 case cricket::MEDIA_TYPE_AUDIO:
2855 RTC_HISTOGRAM_ENUMERATION_SPARSE(
2856 "WebRTC.PeerConnection.SslPeerSignatureAlgorithm.Audio",
2857 ssl_peer_signature_algorithm,
2858 rtc::kSslSignatureAlgorithmMaxValue);
2859 break;
2860 case cricket::MEDIA_TYPE_VIDEO:
2861 RTC_HISTOGRAM_ENUMERATION_SPARSE(
2862 "WebRTC.PeerConnection.SslPeerSignatureAlgorithm.Video",
2863 ssl_peer_signature_algorithm,
2864 rtc::kSslSignatureAlgorithmMaxValue);
2865 break;
2866 case cricket::MEDIA_TYPE_DATA:
2867 RTC_HISTOGRAM_ENUMERATION_SPARSE(
2868 "WebRTC.PeerConnection.SslPeerSignatureAlgorithm.Data",
2869 ssl_peer_signature_algorithm,
2870 rtc::kSslSignatureAlgorithmMaxValue);
2871 break;
2872 default:
2873 RTC_DCHECK_NOTREACHED();
2874 continue;
2875 }
2876 }
2877 }
Steve Anton75737c02017-11-06 18:37:172878}
2879
Taylor Brandstettercbaa2542018-04-16 23:42:142880bool PeerConnection::OnTransportChanged(
Zhi Huange830e682018-03-30 17:48:352881 const std::string& mid,
Taylor Brandstettercbaa2542018-04-16 23:42:142882 RtpTransportInternal* rtp_transport,
Harald Alvestrandc85328f2019-02-28 06:51:002883 rtc::scoped_refptr<DtlsTransport> dtls_transport,
Bjorn A Mellembc3eebc2019-09-23 21:53:542884 DataChannelTransportInterface* data_channel_transport) {
Karl Wibergac025892019-03-26 12:08:372885 RTC_DCHECK_RUN_ON(network_thread());
Taylor Brandstettercbaa2542018-04-16 23:42:142886 bool ret = true;
Harald Alvestrand8101e7b2022-05-23 14:57:472887 if (ConfiguredForMedia()) {
2888 for (const auto& transceiver :
2889 rtp_manager()->transceivers()->UnsafeList()) {
2890 cricket::ChannelInterface* channel = transceiver->internal()->channel();
2891 if (channel && channel->mid() == mid) {
2892 ret = channel->SetRtpTransport(rtp_transport);
2893 }
Harald Alvestrand19ebabc2022-04-28 13:31:172894 }
Zhi Huange830e682018-03-30 17:48:352895 }
Tomas Gunnarsson92eebef2021-02-10 12:05:442896
Harald Alvestrand7a829a82020-02-12 06:38:212897 if (mid == sctp_mid_n_) {
Harald Alvestrand00cf34c2019-12-02 08:56:022898 data_channel_controller_.OnTransportChanged(data_channel_transport);
Tomas Gunnarsson92eebef2021-02-10 12:05:442899 if (dtls_transport) {
Danil Chapovalova30439b2022-07-07 08:08:492900 signaling_thread()->PostTask(SafeTask(
Tomas Gunnarsson92eebef2021-02-10 12:05:442901 signaling_thread_safety_.flag(),
Tomas Gunnarsson94f01942022-01-03 14:59:122902 [this,
2903 name = std::string(dtls_transport->internal()->transport_name())] {
Tomas Gunnarsson92eebef2021-02-10 12:05:442904 RTC_DCHECK_RUN_ON(signaling_thread());
Henrik Boström46053e42023-01-20 12:18:532905 SetSctpTransportName(std::move(name));
Tomas Gunnarsson92eebef2021-02-10 12:05:442906 }));
2907 }
Bjorn A Mellemb689af42019-08-21 17:44:592908 }
Tomas Gunnarsson92eebef2021-02-10 12:05:442909
Taylor Brandstettercbaa2542018-04-16 23:42:142910 return ret;
Steve Anton75737c02017-11-06 18:37:172911}
2912
Harald Alvestrand7a1c7f72018-08-01 08:50:162913PeerConnectionObserver* PeerConnection::Observer() const {
Harald Alvestrand05e4d082019-12-03 13:04:212914 RTC_DCHECK_RUN_ON(signaling_thread());
2915 RTC_DCHECK(observer_);
Harald Alvestrand7a1c7f72018-08-01 08:50:162916 return observer_;
2917}
2918
Tomas Gunnarsson92eebef2021-02-10 12:05:442919void PeerConnection::StartSctpTransport(int local_port,
2920 int remote_port,
2921 int max_message_size) {
2922 RTC_DCHECK_RUN_ON(signaling_thread());
2923 if (!sctp_mid_s_)
2924 return;
2925
Danil Chapovalova30439b2022-07-07 08:08:492926 network_thread()->PostTask(SafeTask(
Tomas Gunnarsson92eebef2021-02-10 12:05:442927 network_thread_safety_,
2928 [this, mid = *sctp_mid_s_, local_port, remote_port, max_message_size] {
2929 rtc::scoped_refptr<SctpTransport> sctp_transport =
Harald Alvestrandbc32c562022-02-09 12:08:472930 transport_controller_n()->GetSctpTransport(mid);
Tomas Gunnarsson92eebef2021-02-10 12:05:442931 if (sctp_transport)
2932 sctp_transport->Start(local_port, remote_port, max_message_size);
2933 }));
2934}
2935
Benjamin Wright8c27cca2018-10-25 17:16:442936CryptoOptions PeerConnection::GetCryptoOptions() {
Harald Alvestrandc06e3742020-10-01 10:23:332937 RTC_DCHECK_RUN_ON(signaling_thread());
Benjamin Wright8c27cca2018-10-25 17:16:442938 // TODO(bugs.webrtc.org/9891) - Remove PeerConnectionFactory::CryptoOptions
2939 // after it has been removed.
2940 return configuration_.crypto_options.has_value()
2941 ? *configuration_.crypto_options
Harald Alvestrand4da4a872020-11-04 10:34:212942 : options_.crypto_options;
Benjamin Wright8c27cca2018-10-25 17:16:442943}
2944
Harald Alvestrand89061872018-01-02 13:08:342945void PeerConnection::ClearStatsCache() {
Karl Wiberg6cab5c82019-03-26 08:57:012946 RTC_DCHECK_RUN_ON(signaling_thread());
Philipp Hancke7baa63f2022-09-01 13:39:502947 if (legacy_stats_) {
2948 legacy_stats_->InvalidateCache();
2949 }
Harald Alvestrand89061872018-01-02 13:08:342950 if (stats_collector_) {
2951 stats_collector_->ClearCachedStatsReport();
2952 }
2953}
2954
Henrik Boströme574a312020-08-25 08:20:112955bool PeerConnection::ShouldFireNegotiationNeededEvent(uint32_t event_id) {
2956 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand9cd199d2020-10-27 07:10:432957 return sdp_handler_->ShouldFireNegotiationNeededEvent(event_id);
Eldar Rello5ab79e62019-10-09 15:29:442958}
2959
Harald Alvestrand1090e442020-10-05 07:01:092960void PeerConnection::RequestUsagePatternReportForTesting() {
Harald Alvestrand00c62ed2021-10-20 08:52:122961 RTC_DCHECK_RUN_ON(signaling_thread());
Harald Alvestrand1090e442020-10-05 07:01:092962 message_handler_.RequestUsagePatternReport(
2963 [this]() {
2964 RTC_DCHECK_RUN_ON(signaling_thread());
2965 ReportUsagePattern();
2966 },
2967 /* delay_ms= */ 0);
2968}
2969
Tomas Gunnarsson1e40a0c2020-09-28 08:39:312970std::function<void(const rtc::CopyOnWriteBuffer& packet,
2971 int64_t packet_time_us)>
2972PeerConnection::InitializeRtcpCallback() {
Tommic3257d02021-02-10 17:40:082973 RTC_DCHECK_RUN_ON(network_thread());
Per Kcf439a02023-01-05 13:01:392974 return [this](const rtc::CopyOnWriteBuffer& packet,
2975 int64_t /*packet_time_us*/) {
2976 worker_thread()->PostTask(SafeTask(worker_thread_safety_, [this, packet]() {
2977 call_ptr_->Receiver()->DeliverRtcpPacket(packet);
2978 }));
Tomas Gunnarsson1e40a0c2020-09-28 08:39:312979 };
2980}
Harald Alvestrandcdcfab02020-09-28 13:02:072981
Per Ke1e94ad2023-03-30 14:53:592982std::function<void(const RtpPacketReceived& parsed_packet)>
2983PeerConnection::InitializeUnDemuxablePacketHandler() {
2984 RTC_DCHECK_RUN_ON(network_thread());
2985 return [this](const RtpPacketReceived& parsed_packet) {
2986 worker_thread()->PostTask(
2987 SafeTask(worker_thread_safety_, [this, parsed_packet]() {
2988 // Deliver the packet anyway to Call to allow Call to do BWE.
2989 // Even if there is no media receiver, the packet has still
2990 // been received on the network and has been correcly parsed.
2991 call_ptr_->Receiver()->DeliverRtpPacket(
2992 MediaType::ANY, parsed_packet,
2993 /*undemuxable_packet_handler=*/
2994 [](const RtpPacketReceived& packet) { return false; });
2995 }));
2996 };
2997}
2998
henrike@webrtc.org28e20752013-07-10 00:45:362999} // namespace webrtc