diff --git a/pc/BUILD.gn b/pc/BUILD.gn index 70becebc99..aaf6c4e119 100644 --- a/pc/BUILD.gn +++ b/pc/BUILD.gn @@ -167,6 +167,7 @@ rtc_library("peerconnection") { "data_channel.cc", "data_channel.h", "data_channel_controller.cc", + "data_channel_controller.h", "dtmf_sender.cc", "dtmf_sender.h", "ice_server_parsing.cc", diff --git a/pc/data_channel_controller.cc b/pc/data_channel_controller.cc index 484886b79c..cc9f149364 100644 --- a/pc/data_channel_controller.cc +++ b/pc/data_channel_controller.cc @@ -8,22 +8,23 @@ * be found in the AUTHORS file in the root of the source tree. */ -// This file contains the implementation of the class -// webrtc::PeerConnection::DataChannelController. -// -// The intent is that this should be webrtc::DataChannelController, but -// as a migration stage, it is simpler to have it as an inner class, -// declared in the header file pc/peer_connection.h +#include "pc/data_channel_controller.h" + +#include #include "pc/peer_connection.h" #include "pc/sctp_utils.h" namespace webrtc { -bool PeerConnection::DataChannelController::SendData( - const cricket::SendDataParams& params, - const rtc::CopyOnWriteBuffer& payload, - cricket::SendDataResult* result) { +bool DataChannelController::HasDataChannels() const { + RTC_DCHECK_RUN_ON(signaling_thread()); + return !rtp_data_channels_.empty() || !sctp_data_channels_.empty(); +} + +bool DataChannelController::SendData(const cricket::SendDataParams& params, + const rtc::CopyOnWriteBuffer& payload, + cricket::SendDataResult* result) { // RTC_DCHECK_RUN_ON(signaling_thread()); if (data_channel_transport()) { SendDataParams send_params; @@ -59,7 +60,7 @@ bool PeerConnection::DataChannelController::SendData( return false; } -bool PeerConnection::DataChannelController::ConnectDataChannel( +bool DataChannelController::ConnectDataChannel( DataChannel* webrtc_data_channel) { RTC_DCHECK_RUN_ON(signaling_thread()); if (!rtp_data_channel() && !data_channel_transport()) { @@ -87,7 +88,7 @@ bool PeerConnection::DataChannelController::ConnectDataChannel( return true; } -void PeerConnection::DataChannelController::DisconnectDataChannel( +void DataChannelController::DisconnectDataChannel( DataChannel* webrtc_data_channel) { RTC_DCHECK_RUN_ON(signaling_thread()); if (!rtp_data_channel() && !data_channel_transport()) { @@ -108,7 +109,7 @@ void PeerConnection::DataChannelController::DisconnectDataChannel( } } -void PeerConnection::DataChannelController::AddSctpDataStream(int sid) { +void DataChannelController::AddSctpDataStream(int sid) { if (data_channel_transport()) { network_thread()->Invoke(RTC_FROM_HERE, [this, sid] { if (data_channel_transport()) { @@ -118,7 +119,7 @@ void PeerConnection::DataChannelController::AddSctpDataStream(int sid) { } } -void PeerConnection::DataChannelController::RemoveSctpDataStream(int sid) { +void DataChannelController::RemoveSctpDataStream(int sid) { if (data_channel_transport()) { network_thread()->Invoke(RTC_FROM_HERE, [this, sid] { if (data_channel_transport()) { @@ -128,13 +129,13 @@ void PeerConnection::DataChannelController::RemoveSctpDataStream(int sid) { } } -bool PeerConnection::DataChannelController::ReadyToSendData() const { +bool DataChannelController::ReadyToSendData() const { RTC_DCHECK_RUN_ON(signaling_thread()); return (rtp_data_channel() && rtp_data_channel()->ready_to_send_data()) || (data_channel_transport() && data_channel_transport_ready_to_send_); } -void PeerConnection::DataChannelController::OnDataReceived( +void DataChannelController::OnDataReceived( int channel_id, DataMessageType type, const rtc::CopyOnWriteBuffer& buffer) { @@ -151,7 +152,7 @@ void PeerConnection::DataChannelController::OnDataReceived( }); } -void PeerConnection::DataChannelController::OnChannelClosing(int channel_id) { +void DataChannelController::OnChannelClosing(int channel_id) { RTC_DCHECK_RUN_ON(network_thread()); data_channel_transport_invoker_->AsyncInvoke( RTC_FROM_HERE, signaling_thread(), [this, channel_id] { @@ -160,7 +161,7 @@ void PeerConnection::DataChannelController::OnChannelClosing(int channel_id) { }); } -void PeerConnection::DataChannelController::OnChannelClosed(int channel_id) { +void DataChannelController::OnChannelClosed(int channel_id) { RTC_DCHECK_RUN_ON(network_thread()); data_channel_transport_invoker_->AsyncInvoke( RTC_FROM_HERE, signaling_thread(), [this, channel_id] { @@ -169,7 +170,7 @@ void PeerConnection::DataChannelController::OnChannelClosed(int channel_id) { }); } -void PeerConnection::DataChannelController::OnReadyToSend() { +void DataChannelController::OnReadyToSend() { RTC_DCHECK_RUN_ON(network_thread()); data_channel_transport_invoker_->AsyncInvoke( RTC_FROM_HERE, signaling_thread(), [this] { @@ -180,12 +181,12 @@ void PeerConnection::DataChannelController::OnReadyToSend() { }); } -void PeerConnection::DataChannelController::SetupDataChannelTransport_n() { +void DataChannelController::SetupDataChannelTransport_n() { RTC_DCHECK_RUN_ON(network_thread()); data_channel_transport_invoker_ = std::make_unique(); } -void PeerConnection::DataChannelController::TeardownDataChannelTransport_n() { +void DataChannelController::TeardownDataChannelTransport_n() { RTC_DCHECK_RUN_ON(network_thread()); data_channel_transport_invoker_ = nullptr; if (data_channel_transport()) { @@ -194,7 +195,7 @@ void PeerConnection::DataChannelController::TeardownDataChannelTransport_n() { set_data_channel_transport(nullptr); } -void PeerConnection::DataChannelController::OnTransportChanged( +void DataChannelController::OnTransportChanged( DataChannelTransportInterface* new_data_channel_transport) { RTC_DCHECK_RUN_ON(network_thread()); if (data_channel_transport() && @@ -211,8 +212,8 @@ void PeerConnection::DataChannelController::OnTransportChanged( // necessary when bundling is applied. data_channel_transport_invoker_->AsyncInvoke( RTC_FROM_HERE, signaling_thread(), [this] { - RTC_DCHECK_RUN_ON(pc_->signaling_thread()); - for (auto channel : pc_->sctp_data_channels_) { + RTC_DCHECK_RUN_ON(signaling_thread()); + for (auto channel : sctp_data_channels_) { channel->OnTransportChannelCreated(); } }); @@ -220,7 +221,7 @@ void PeerConnection::DataChannelController::OnTransportChanged( } } -bool PeerConnection::DataChannelController::HandleOpenMessage_s( +bool DataChannelController::HandleOpenMessage_s( const cricket::ReceiveDataParams& params, const rtc::CopyOnWriteBuffer& buffer) { if (params.type == cricket::DMT_CONTROL && IsOpenMessage(buffer)) { @@ -241,7 +242,7 @@ bool PeerConnection::DataChannelController::HandleOpenMessage_s( return false; } -void PeerConnection::DataChannelController::OnDataChannelOpenMessage( +void DataChannelController::OnDataChannelOpenMessage( const std::string& label, const InternalDataChannelInit& config) { rtc::scoped_refptr channel( @@ -253,29 +254,26 @@ void PeerConnection::DataChannelController::OnDataChannelOpenMessage( rtc::scoped_refptr proxy_channel = DataChannelProxy::Create(signaling_thread(), channel); - { - RTC_DCHECK_RUN_ON(pc_->signaling_thread()); - pc_->Observer()->OnDataChannel(std::move(proxy_channel)); - pc_->NoteUsageEvent(UsageEvent::DATA_ADDED); - } + pc_->Observer()->OnDataChannel(std::move(proxy_channel)); + pc_->NoteDataAddedEvent(); } rtc::scoped_refptr -PeerConnection::DataChannelController::InternalCreateDataChannel( +DataChannelController::InternalCreateDataChannel( const std::string& label, const InternalDataChannelInit* config) { - RTC_DCHECK_RUN_ON(pc_->signaling_thread()); + RTC_DCHECK_RUN_ON(signaling_thread()); if (pc_->IsClosed()) { return nullptr; } - if (pc_->data_channel_type() == cricket::DCT_NONE) { + if (data_channel_type_ == cricket::DCT_NONE) { RTC_LOG(LS_ERROR) << "InternalCreateDataChannel: Data is not supported in this call."; return nullptr; } InternalDataChannelInit new_config = config ? (*config) : InternalDataChannelInit(); - if (DataChannel::IsSctpLike(pc_->data_channel_type_)) { + if (DataChannel::IsSctpLike(data_channel_type_)) { if (new_config.id < 0) { rtc::SSLRole role; if ((pc_->GetSctpSslRole(&role)) && @@ -292,36 +290,33 @@ PeerConnection::DataChannelController::InternalCreateDataChannel( } rtc::scoped_refptr channel( - DataChannel::Create(this, pc_->data_channel_type(), label, new_config)); + DataChannel::Create(this, data_channel_type(), label, new_config)); if (!channel) { sid_allocator_.ReleaseSid(new_config.id); return nullptr; } if (channel->data_channel_type() == cricket::DCT_RTP) { - if (pc_->rtp_data_channels_.find(channel->label()) != - pc_->rtp_data_channels_.end()) { + if (rtp_data_channels_.find(channel->label()) != rtp_data_channels_.end()) { RTC_LOG(LS_ERROR) << "DataChannel with label " << channel->label() << " already exists."; return nullptr; } - pc_->rtp_data_channels_[channel->label()] = channel; + rtp_data_channels_[channel->label()] = channel; } else { - RTC_DCHECK(DataChannel::IsSctpLike(pc_->data_channel_type_)); - pc_->sctp_data_channels_.push_back(channel); + RTC_DCHECK(DataChannel::IsSctpLike(data_channel_type_)); + sctp_data_channels_.push_back(channel); channel->SignalClosed.connect(pc_, &PeerConnection::OnSctpDataChannelClosed); } - - pc_->SignalDataChannelCreated_(channel.get()); + SignalDataChannelCreated_(channel.get()); return channel; } -void PeerConnection::DataChannelController::AllocateSctpSids( - rtc::SSLRole role) { - RTC_DCHECK_RUN_ON(pc_->signaling_thread()); +void DataChannelController::AllocateSctpSids(rtc::SSLRole role) { + RTC_DCHECK_RUN_ON(signaling_thread()); std::vector> channels_to_close; - for (const auto& channel : pc_->sctp_data_channels_) { + for (const auto& channel : sctp_data_channels_) { if (channel->id() < 0) { int sid; if (!sid_allocator_.AllocateSid(role, &sid)) { @@ -339,11 +334,10 @@ void PeerConnection::DataChannelController::AllocateSctpSids( } } -void PeerConnection::DataChannelController::OnSctpDataChannelClosed( - DataChannel* channel) { - RTC_DCHECK_RUN_ON(pc_->signaling_thread()); - for (auto it = pc_->sctp_data_channels_.begin(); - it != pc_->sctp_data_channels_.end(); ++it) { +void DataChannelController::OnSctpDataChannelClosed(DataChannel* channel) { + RTC_DCHECK_RUN_ON(signaling_thread()); + for (auto it = sctp_data_channels_.begin(); it != sctp_data_channels_.end(); + ++it) { if (it->get() == channel) { if (channel->id() >= 0) { // After the closing procedure is done, it's safe to use this ID for @@ -352,12 +346,138 @@ void PeerConnection::DataChannelController::OnSctpDataChannelClosed( } // Since this method is triggered by a signal from the DataChannel, // we can't free it directly here; we need to free it asynchronously. - pc_->sctp_data_channels_to_free_.push_back(*it); - pc_->sctp_data_channels_.erase(it); + sctp_data_channels_to_free_.push_back(*it); + sctp_data_channels_.erase(it); pc_->SignalFreeDataChannels(); return; } } } +void DataChannelController::OnTransportChannelClosed() { + RTC_DCHECK_RUN_ON(signaling_thread()); + // Use a temporary copy of the RTP/SCTP DataChannel list because the + // DataChannel may callback to us and try to modify the list. + std::map> temp_rtp_dcs; + temp_rtp_dcs.swap(rtp_data_channels_); + for (const auto& kv : temp_rtp_dcs) { + kv.second->OnTransportChannelClosed(); + } + + std::vector> temp_sctp_dcs; + temp_sctp_dcs.swap(sctp_data_channels_); + for (const auto& channel : temp_sctp_dcs) { + channel->OnTransportChannelClosed(); + } +} + +DataChannel* DataChannelController::FindDataChannelBySid(int sid) const { + RTC_DCHECK_RUN_ON(signaling_thread()); + for (const auto& channel : sctp_data_channels_) { + if (channel->id() == sid) { + return channel; + } + } + return nullptr; +} + +void DataChannelController::UpdateLocalRtpDataChannels( + const cricket::StreamParamsVec& streams) { + std::vector existing_channels; + + RTC_DCHECK_RUN_ON(signaling_thread()); + // Find new and active data channels. + for (const cricket::StreamParams& params : streams) { + // |it->sync_label| is actually the data channel label. The reason is that + // we use the same naming of data channels as we do for + // MediaStreams and Tracks. + // For MediaStreams, the sync_label is the MediaStream label and the + // track label is the same as |streamid|. + const std::string& channel_label = params.first_stream_id(); + auto data_channel_it = rtp_data_channels()->find(channel_label); + if (data_channel_it == rtp_data_channels()->end()) { + RTC_LOG(LS_ERROR) << "channel label not found"; + continue; + } + // Set the SSRC the data channel should use for sending. + data_channel_it->second->SetSendSsrc(params.first_ssrc()); + existing_channels.push_back(data_channel_it->first); + } + + UpdateClosingRtpDataChannels(existing_channels, true); +} + +void DataChannelController::UpdateRemoteRtpDataChannels( + const cricket::StreamParamsVec& streams) { + std::vector existing_channels; + + RTC_DCHECK_RUN_ON(signaling_thread()); + // Find new and active data channels. + for (const cricket::StreamParams& params : streams) { + // The data channel label is either the mslabel or the SSRC if the mslabel + // does not exist. Ex a=ssrc:444330170 mslabel:test1. + std::string label = params.first_stream_id().empty() + ? rtc::ToString(params.first_ssrc()) + : params.first_stream_id(); + auto data_channel_it = rtp_data_channels()->find(label); + if (data_channel_it == rtp_data_channels()->end()) { + // This is a new data channel. + CreateRemoteRtpDataChannel(label, params.first_ssrc()); + } else { + data_channel_it->second->SetReceiveSsrc(params.first_ssrc()); + } + existing_channels.push_back(label); + } + + UpdateClosingRtpDataChannels(existing_channels, false); +} + +void DataChannelController::UpdateClosingRtpDataChannels( + const std::vector& active_channels, + bool is_local_update) { + auto it = rtp_data_channels_.begin(); + while (it != rtp_data_channels_.end()) { + DataChannel* data_channel = it->second; + if (absl::c_linear_search(active_channels, data_channel->label())) { + ++it; + continue; + } + + if (is_local_update) { + data_channel->SetSendSsrc(0); + } else { + data_channel->RemotePeerRequestClose(); + } + + if (data_channel->state() == DataChannel::kClosed) { + rtp_data_channels_.erase(it); + it = rtp_data_channels_.begin(); + } else { + ++it; + } + } +} + +void DataChannelController::CreateRemoteRtpDataChannel(const std::string& label, + uint32_t remote_ssrc) { + rtc::scoped_refptr channel( + InternalCreateDataChannel(label, nullptr)); + if (!channel.get()) { + RTC_LOG(LS_WARNING) << "Remote peer requested a DataChannel but" + "CreateDataChannel failed."; + return; + } + channel->SetReceiveSsrc(remote_ssrc); + rtc::scoped_refptr proxy_channel = + DataChannelProxy::Create(signaling_thread(), channel); + pc_->Observer()->OnDataChannel(std::move(proxy_channel)); +} + +rtc::Thread* DataChannelController::network_thread() const { + return pc_->network_thread(); +} +rtc::Thread* DataChannelController::signaling_thread() const { + return pc_->signaling_thread(); +} + } // namespace webrtc diff --git a/pc/data_channel_controller.h b/pc/data_channel_controller.h new file mode 100644 index 0000000000..bfce16c10c --- /dev/null +++ b/pc/data_channel_controller.h @@ -0,0 +1,214 @@ +/* + * Copyright 2019 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef PC_DATA_CHANNEL_CONTROLLER_H_ +#define PC_DATA_CHANNEL_CONTROLLER_H_ + +#include +#include +#include +#include + +#include "pc/channel.h" +#include "pc/data_channel.h" + +namespace webrtc { + +class PeerConnection; + +class DataChannelController : public DataChannelProviderInterface, + public DataChannelSink { + public: + explicit DataChannelController(PeerConnection* pc) : pc_(pc) {} + + // Implements DataChannelProviderInterface. + bool SendData(const cricket::SendDataParams& params, + const rtc::CopyOnWriteBuffer& payload, + cricket::SendDataResult* result) override; + bool ConnectDataChannel(DataChannel* webrtc_data_channel) override; + void DisconnectDataChannel(DataChannel* webrtc_data_channel) override; + void AddSctpDataStream(int sid) override; + void RemoveSctpDataStream(int sid) override; + bool ReadyToSendData() const override; + + // Implements DataChannelSink. + void OnDataReceived(int channel_id, + DataMessageType type, + const rtc::CopyOnWriteBuffer& buffer) override; + void OnChannelClosing(int channel_id) override; + void OnChannelClosed(int channel_id) override; + void OnReadyToSend() override; + + // Called from PeerConnection::SetupDataChannelTransport_n + void SetupDataChannelTransport_n(); + // Called from PeerConnection::TeardownDataChannelTransport_n + void TeardownDataChannelTransport_n(); + + // Called from PeerConnection::OnTransportChanged + // to make required changes to datachannels' transports. + void OnTransportChanged( + DataChannelTransportInterface* data_channel_transport); + + // Creates channel and adds it to the collection of DataChannels that will + // be offered in a SessionDescription. + rtc::scoped_refptr InternalCreateDataChannel( + const std::string& label, + const InternalDataChannelInit* + config) /* RTC_RUN_ON(signaling_thread()) */; + void AllocateSctpSids(rtc::SSLRole role); + + DataChannel* FindDataChannelBySid(int sid) const; + + // Checks if any data channel has been added. + bool HasDataChannels() const; + bool HasSctpDataChannels() const { + RTC_DCHECK_RUN_ON(signaling_thread()); + return !sctp_data_channels_.empty(); + } + bool HasRtpDataChannels() const { + RTC_DCHECK_RUN_ON(signaling_thread()); + return !rtp_data_channels_.empty(); + } + + // Called when it's appropriate to delete released datachannels. + void FreeDataChannels() { + RTC_DCHECK_RUN_ON(signaling_thread()); + sctp_data_channels_to_free_.clear(); + } + + void UpdateLocalRtpDataChannels(const cricket::StreamParamsVec& streams); + void UpdateRemoteRtpDataChannels(const cricket::StreamParamsVec& streams); + + // Accessors + cricket::DataChannelType data_channel_type() const { + return data_channel_type_; + } + void set_data_channel_type(cricket::DataChannelType type) { + data_channel_type_ = type; + } + cricket::RtpDataChannel* rtp_data_channel() const { + return rtp_data_channel_; + } + void set_rtp_data_channel(cricket::RtpDataChannel* channel) { + rtp_data_channel_ = channel; + } + DataChannelTransportInterface* data_channel_transport() const { + return data_channel_transport_; + } + void set_data_channel_transport(DataChannelTransportInterface* transport) { + data_channel_transport_ = transport; + } + const std::map>* + rtp_data_channels() const { + RTC_DCHECK_RUN_ON(signaling_thread()); + return &rtp_data_channels_; + } + const std::vector>* sctp_data_channels() + const { + RTC_DCHECK_RUN_ON(signaling_thread()); + return &sctp_data_channels_; + } + + sigslot::signal1& SignalDataChannelCreated() { + RTC_DCHECK_RUN_ON(signaling_thread()); + return SignalDataChannelCreated_; + } + // Called when the transport for the data channels is closed or destroyed. + void OnTransportChannelClosed(); + + void OnSctpDataChannelClosed(DataChannel* channel); + + private: + // Parses and handles open messages. Returns true if the message is an open + // message, false otherwise. + bool HandleOpenMessage_s(const cricket::ReceiveDataParams& params, + const rtc::CopyOnWriteBuffer& buffer) + RTC_RUN_ON(signaling_thread()); + // Called when a valid data channel OPEN message is received. + void OnDataChannelOpenMessage(const std::string& label, + const InternalDataChannelInit& config) + RTC_RUN_ON(signaling_thread()); + + void CreateRemoteRtpDataChannel(const std::string& label, + uint32_t remote_ssrc) + RTC_RUN_ON(signaling_thread()); + + void UpdateClosingRtpDataChannels( + const std::vector& active_channels, + bool is_local_update) RTC_RUN_ON(signaling_thread()); + + rtc::Thread* network_thread() const; + rtc::Thread* signaling_thread() const; + + // Specifies which kind of data channel is allowed. This is controlled + // by the chrome command-line flag and constraints: + // 1. If chrome command-line switch 'enable-sctp-data-channels' is enabled, + // constraint kEnableDtlsSrtp is true, and constaint kEnableRtpDataChannels is + // not set or false, SCTP is allowed (DCT_SCTP); + // 2. If constraint kEnableRtpDataChannels is true, RTP is allowed (DCT_RTP); + // 3. If both 1&2 are false, data channel is not allowed (DCT_NONE). + cricket::DataChannelType data_channel_type_ = + cricket::DCT_NONE; // TODO(bugs.webrtc.org/9987): Accessed on both + // signaling and network thread. + + // Plugin transport used for data channels. Pointer may be accessed and + // checked from any thread, but the object may only be touched on the + // network thread. + // TODO(bugs.webrtc.org/9987): Accessed on both signaling and network + // thread. + DataChannelTransportInterface* data_channel_transport_ = nullptr; + + // Cached value of whether the data channel transport is ready to send. + bool data_channel_transport_ready_to_send_ + RTC_GUARDED_BY(signaling_thread()) = false; + + // |rtp_data_channel_| is used if in RTP data channel mode, + // |data_channel_transport_| when using SCTP. + cricket::RtpDataChannel* rtp_data_channel_ = nullptr; + // TODO(bugs.webrtc.org/9987): Accessed on both + // signaling and some other thread. + + SctpSidAllocator sid_allocator_ /* RTC_GUARDED_BY(signaling_thread()) */; + std::vector> sctp_data_channels_ + RTC_GUARDED_BY(signaling_thread()); + std::vector> sctp_data_channels_to_free_ + RTC_GUARDED_BY(signaling_thread()); + + // Map of label -> DataChannel + std::map> rtp_data_channels_ + RTC_GUARDED_BY(signaling_thread()); + + // Signals from |data_channel_transport_|. These are invoked on the + // signaling thread. + sigslot::signal1 SignalDataChannelTransportWritable_s + RTC_GUARDED_BY(signaling_thread()); + sigslot::signal2 + SignalDataChannelTransportReceivedData_s + RTC_GUARDED_BY(signaling_thread()); + sigslot::signal1 SignalDataChannelTransportChannelClosing_s + RTC_GUARDED_BY(signaling_thread()); + sigslot::signal1 SignalDataChannelTransportChannelClosed_s + RTC_GUARDED_BY(signaling_thread()); + + sigslot::signal1 SignalDataChannelCreated_ + RTC_GUARDED_BY(signaling_thread()); + + // Used to invoke data channel transport signals on the signaling thread. + std::unique_ptr data_channel_transport_invoker_ + RTC_GUARDED_BY(network_thread()); + + // Owning PeerConnection. + PeerConnection* const pc_; +}; + +} // namespace webrtc + +#endif // PC_DATA_CHANNEL_CONTROLLER_H_ diff --git a/pc/peer_connection.cc b/pc/peer_connection.cc index 0f632abb69..855df75718 100644 --- a/pc/peer_connection.cc +++ b/pc/peer_connection.cc @@ -1306,21 +1306,23 @@ bool PeerConnection::Initialize( } if (configuration.enable_dtls_srtp && !*configuration.enable_dtls_srtp) { RTC_LOG(LS_INFO) << "Using data channel transport with no fallback"; - data_channel_type_ = cricket::DCT_DATA_CHANNEL_TRANSPORT; + data_channel_controller_.set_data_channel_type( + cricket::DCT_DATA_CHANNEL_TRANSPORT); } else { RTC_LOG(LS_INFO) << "Using data channel transport with fallback to SCTP"; - data_channel_type_ = cricket::DCT_DATA_CHANNEL_TRANSPORT_SCTP; + data_channel_controller_.set_data_channel_type( + cricket::DCT_DATA_CHANNEL_TRANSPORT_SCTP); config.sctp_factory = sctp_factory_.get(); } } else if (configuration.enable_rtp_data_channel) { // Enable creation of RTP data channels if the kEnableRtpDataChannels is // set. It takes precendence over the disable_sctp_data_channels // PeerConnectionFactoryInterface::Options. - data_channel_type_ = cricket::DCT_RTP; + data_channel_controller_.set_data_channel_type(cricket::DCT_RTP); } else { // DTLS has to be enabled to use SCTP. if (!options.disable_sctp_data_channels && dtls_enabled_) { - data_channel_type_ = cricket::DCT_SCTP; + data_channel_controller_.set_data_channel_type(cricket::DCT_SCTP); config.sctp_factory = sctp_factory_.get(); } } @@ -2159,7 +2161,7 @@ rtc::scoped_refptr PeerConnection::CreateDataChannel( RTC_DCHECK_RUN_ON(signaling_thread()); TRACE_EVENT0("webrtc", "PeerConnection::CreateDataChannel"); - bool first_datachannel = !HasDataChannels(); + bool first_datachannel = !data_channel_controller_.HasDataChannels(); std::unique_ptr internal_config; if (config) { @@ -2766,7 +2768,7 @@ RTCError PeerConnection::ApplyLocalDescription( // If setting the description decided our SSL role, allocate any necessary // SCTP sids. rtc::SSLRole role; - if (DataChannel::IsSctpLike(data_channel_type_) && GetSctpSslRole(&role)) { + if (DataChannel::IsSctpLike(data_channel_type()) && GetSctpSslRole(&role)) { data_channel_controller_.AllocateSctpSids(role); } @@ -2830,7 +2832,8 @@ RTCError PeerConnection::ApplyLocalDescription( data_content->media_description()->as_rtp_data(); // rtp_data_desc will be null if this is an SCTP description. if (rtp_data_desc) { - UpdateLocalRtpDataChannels(rtp_data_desc->streams()); + data_channel_controller_.UpdateLocalRtpDataChannels( + rtp_data_desc->streams()); } } @@ -3204,7 +3207,7 @@ RTCError PeerConnection::ApplyRemoteDescription( // If setting the description decided our SSL role, allocate any necessary // SCTP sids. rtc::SSLRole role; - if (DataChannel::IsSctpLike(data_channel_type_) && GetSctpSslRole(&role)) { + if (DataChannel::IsSctpLike(data_channel_type()) && GetSctpSslRole(&role)) { data_channel_controller_.AllocateSctpSids(role); } @@ -3385,7 +3388,8 @@ RTCError PeerConnection::ApplyRemoteDescription( // If this is an RTP data transport, update the DataChannels with the // information from the remote peer. if (rtp_data_desc) { - UpdateRemoteRtpDataChannels(GetActiveStreams(rtp_data_desc)); + data_channel_controller_.UpdateRemoteRtpDataChannels( + GetActiveStreams(rtp_data_desc)); } // Iterate new_streams and notify the observer about new MediaStreams. @@ -3584,7 +3588,7 @@ RTCError PeerConnection::UpdateDataChannel( cricket::ContentSource source, const cricket::ContentInfo& content, const cricket::ContentGroup* bundle_group) { - if (data_channel_type_ == cricket::DCT_NONE) { + if (data_channel_type() == cricket::DCT_NONE) { // If data channels are disabled, ignore this media section. CreateAnswer // will take care of rejecting it. return RTCError::OK(); @@ -3604,7 +3608,8 @@ RTCError PeerConnection::UpdateDataChannel( if (source == cricket::CS_REMOTE) { const MediaContentDescription* data_desc = content.media_description(); if (data_desc && cricket::IsRtpProtocol(data_desc->protocol())) { - UpdateRemoteRtpDataChannels(GetActiveStreams(data_desc)); + data_channel_controller_.UpdateRemoteRtpDataChannels( + GetActiveStreams(data_desc)); } } } @@ -4492,7 +4497,7 @@ void PeerConnection::OnMessage(rtc::Message* msg) { break; } case MSG_FREE_DATACHANNELS: { - sctp_data_channels_to_free_.clear(); + data_channel_controller_.FreeDataChannels(); break; } case MSG_REPORT_USAGE_PATTERN: { @@ -4874,7 +4879,8 @@ void PeerConnection::GetOptionsForOffer( // negotiated by default and the unit tests in WebRtcDataBrowserTest will fail // when building with chromium. We want to leave RTP data channels broken, so // people won't try to use them. - if (!rtp_data_channels_.empty() || data_channel_type() != cricket::DCT_RTP) { + if (data_channel_controller_.HasRtpDataChannels() || + data_channel_type() != cricket::DCT_RTP) { session_options->data_channel_type = data_channel_type(); } @@ -4937,7 +4943,7 @@ void PeerConnection::GetOptionsForPlanBOffer( // By default, only offer a new m= section if we have media to send with it. bool offer_new_audio_description = send_audio; bool offer_new_video_description = send_video; - bool offer_new_data_description = HasDataChannels(); + bool offer_new_data_description = data_channel_controller_.HasDataChannels(); // The "offer_to_receive_X" options allow those defaults to be overridden. if (offer_answer_options.offer_to_receive_audio != @@ -5175,7 +5181,7 @@ void PeerConnection::GetOptionsForUnifiedPlanOffer( } // Lastly, add a m-section if we have local data channels and an m section // does not already exist. - if (!GetDataMid() && HasDataChannels()) { + if (!GetDataMid() && data_channel_controller_.HasDataChannels()) { session_options->media_description_options.push_back( GetMediaDescriptionOptionsForActiveData(mid_generator_())); } @@ -5196,7 +5202,8 @@ void PeerConnection::GetOptionsForAnswer( // the RTP data channels would be successfully negotiated by default and the // unit tests in WebRtcDataBrowserTest will fail when building with chromium. // We want to leave RTP data channels broken, so people won't try to use them. - if (!rtp_data_channels_.empty() || data_channel_type() != cricket::DCT_RTP) { + if (data_channel_controller_.HasRtpDataChannels() || + data_channel_type() != cricket::DCT_RTP) { session_options->data_channel_type = data_channel_type(); } @@ -5303,7 +5310,7 @@ void PeerConnection::GetOptionsForUnifiedPlanAnswer( // Reject all data sections if data channels are disabled. // Reject a data section if it has already been rejected. // Reject all data sections except for the first one. - if (data_channel_type_ == cricket::DCT_NONE || content.rejected || + if (data_channel_type() == cricket::DCT_NONE || content.rejected || content.name != *GetDataMid()) { session_options->media_description_options.push_back( GetMediaDescriptionOptionsForRejectedData(content.name)); @@ -5378,7 +5385,8 @@ PeerConnection::GetMediaDescriptionOptionsForActiveData( cricket::MediaDescriptionOptions options(cricket::MEDIA_TYPE_DATA, mid, RtpTransceiverDirection::kSendRecv, /*stopped=*/false); - AddRtpDataChannelOptions(rtp_data_channels_, &options); + AddRtpDataChannelOptions(*data_channel_controller_.rtp_data_channels(), + &options); return options; } @@ -5388,12 +5396,13 @@ PeerConnection::GetMediaDescriptionOptionsForRejectedData( cricket::MediaDescriptionOptions options(cricket::MEDIA_TYPE_DATA, mid, RtpTransceiverDirection::kInactive, /*stopped=*/true); - AddRtpDataChannelOptions(rtp_data_channels_, &options); + AddRtpDataChannelOptions(*data_channel_controller_.rtp_data_channels(), + &options); return options; } absl::optional PeerConnection::GetDataMid() const { - switch (data_channel_type_) { + switch (data_channel_type()) { case cricket::DCT_RTP: if (!data_channel_controller_.rtp_data_channel()) { return absl::nullopt; @@ -5661,100 +5670,6 @@ void PeerConnection::OnLocalSenderRemoved(const RtpSenderInfo& sender_info, sender->internal()->SetSsrc(0); } -void PeerConnection::UpdateLocalRtpDataChannels( - const cricket::StreamParamsVec& streams) { - std::vector existing_channels; - - // Find new and active data channels. - for (const cricket::StreamParams& params : streams) { - // |it->sync_label| is actually the data channel label. The reason is that - // we use the same naming of data channels as we do for - // MediaStreams and Tracks. - // For MediaStreams, the sync_label is the MediaStream label and the - // track label is the same as |streamid|. - const std::string& channel_label = params.first_stream_id(); - auto data_channel_it = rtp_data_channels_.find(channel_label); - if (data_channel_it == rtp_data_channels_.end()) { - RTC_LOG(LS_ERROR) << "channel label not found"; - continue; - } - // Set the SSRC the data channel should use for sending. - data_channel_it->second->SetSendSsrc(params.first_ssrc()); - existing_channels.push_back(data_channel_it->first); - } - - UpdateClosingRtpDataChannels(existing_channels, true); -} - -void PeerConnection::UpdateRemoteRtpDataChannels( - const cricket::StreamParamsVec& streams) { - std::vector existing_channels; - - // Find new and active data channels. - for (const cricket::StreamParams& params : streams) { - // The data channel label is either the mslabel or the SSRC if the mslabel - // does not exist. Ex a=ssrc:444330170 mslabel:test1. - std::string label = params.first_stream_id().empty() - ? rtc::ToString(params.first_ssrc()) - : params.first_stream_id(); - auto data_channel_it = rtp_data_channels_.find(label); - if (data_channel_it == rtp_data_channels_.end()) { - // This is a new data channel. - CreateRemoteRtpDataChannel(label, params.first_ssrc()); - } else { - data_channel_it->second->SetReceiveSsrc(params.first_ssrc()); - } - existing_channels.push_back(label); - } - - UpdateClosingRtpDataChannels(existing_channels, false); -} - -void PeerConnection::UpdateClosingRtpDataChannels( - const std::vector& active_channels, - bool is_local_update) { - auto it = rtp_data_channels_.begin(); - while (it != rtp_data_channels_.end()) { - DataChannel* data_channel = it->second; - if (absl::c_linear_search(active_channels, data_channel->label())) { - ++it; - continue; - } - - if (is_local_update) { - data_channel->SetSendSsrc(0); - } else { - data_channel->RemotePeerRequestClose(); - } - - if (data_channel->state() == DataChannel::kClosed) { - rtp_data_channels_.erase(it); - it = rtp_data_channels_.begin(); - } else { - ++it; - } - } -} - -void PeerConnection::CreateRemoteRtpDataChannel(const std::string& label, - uint32_t remote_ssrc) { - rtc::scoped_refptr channel( - data_channel_controller_.InternalCreateDataChannel(label, nullptr)); - if (!channel.get()) { - RTC_LOG(LS_WARNING) << "Remote peer requested a DataChannel but" - "CreateDataChannel failed."; - return; - } - channel->SetReceiveSsrc(remote_ssrc); - rtc::scoped_refptr proxy_channel = - DataChannelProxy::Create(signaling_thread(), channel); - Observer()->OnDataChannel(std::move(proxy_channel)); -} - -bool PeerConnection::HasDataChannels() const { - return !rtp_data_channels_.empty() || !sctp_data_channels_.empty(); -} - void PeerConnection::OnSctpDataChannelClosed(DataChannel* channel) { // Since data_channel_controller doesn't do signals, this // signal is relayed here. @@ -5765,22 +5680,6 @@ void PeerConnection::SignalFreeDataChannels() { signaling_thread()->Post(RTC_FROM_HERE, this, MSG_FREE_DATACHANNELS, nullptr); } -void PeerConnection::OnTransportChannelClosed() { - // Use a temporary copy of the RTP/SCTP DataChannel list because the - // DataChannel may callback to us and try to modify the list. - std::map> temp_rtp_dcs; - temp_rtp_dcs.swap(rtp_data_channels_); - for (const auto& kv : temp_rtp_dcs) { - kv.second->OnTransportChannelClosed(); - } - - std::vector> temp_sctp_dcs; - temp_sctp_dcs.swap(sctp_data_channels_); - for (const auto& channel : temp_sctp_dcs) { - channel->OnTransportChannelClosed(); - } -} - rtc::scoped_refptr> PeerConnection::GetAudioTransceiver() const { // This method only works with Plan B SDP, where there is a single @@ -5891,12 +5790,7 @@ const PeerConnection::RtpSenderInfo* PeerConnection::FindSenderInfo( } DataChannel* PeerConnection::FindDataChannelBySid(int sid) const { - for (const auto& channel : sctp_data_channels_) { - if (channel->id() == sid) { - return channel; - } - } - return nullptr; + return data_channel_controller_.FindDataChannelBySid(sid); } PeerConnection::InitializePortAllocatorResult @@ -6370,7 +6264,7 @@ std::unique_ptr PeerConnection::GetRemoteSSLCertChain( } cricket::DataChannelType PeerConnection::data_channel_type() const { - return data_channel_type_; + return data_channel_controller_.data_channel_type(); } bool PeerConnection::IceRestartPending(const std::string& content_name) const { @@ -6692,7 +6586,7 @@ RTCError PeerConnection::CreateChannels(const SessionDescription& desc) { } const cricket::ContentInfo* data = cricket::GetFirstDataContent(&desc); - if (data_channel_type_ != cricket::DCT_NONE && data && !data->rejected && + if (data_channel_type() != cricket::DCT_NONE && data && !data->rejected && !data_channel_controller_.rtp_data_channel() && !data_channel_controller_.data_channel_transport()) { if (!CreateDataChannel(data->name)) { @@ -6752,7 +6646,7 @@ cricket::VideoChannel* PeerConnection::CreateVideoChannel( } bool PeerConnection::CreateDataChannel(const std::string& mid) { - switch (data_channel_type_) { + switch (data_channel_type()) { case cricket::DCT_SCTP: case cricket::DCT_DATA_CHANNEL_TRANSPORT_SCTP: case cricket::DCT_DATA_CHANNEL_TRANSPORT: @@ -6764,7 +6658,8 @@ bool PeerConnection::CreateDataChannel(const std::string& mid) { } // All non-RTP data channels must initialize |sctp_data_channels_|. - for (const auto& channel : sctp_data_channels_) { + for (const auto& channel : + *data_channel_controller_.sctp_data_channels()) { channel->OnTransportChannelCreated(); } return true; @@ -7379,7 +7274,7 @@ void PeerConnection::DestroyTransceiverChannel( void PeerConnection::DestroyDataChannelTransport() { if (data_channel_controller_.rtp_data_channel()) { - OnTransportChannelClosed(); + data_channel_controller_.OnTransportChannelClosed(); DestroyChannelInterface(data_channel_controller_.rtp_data_channel()); data_channel_controller_.set_rtp_data_channel(nullptr); } @@ -7391,7 +7286,7 @@ void PeerConnection::DestroyDataChannelTransport() { // rtc::Bind will cause "Pure virtual function called" error to appear. if (sctp_mid_) { - OnTransportChannelClosed(); + data_channel_controller_.OnTransportChannelClosed(); network_thread()->Invoke(RTC_FROM_HERE, [this] { RTC_DCHECK_RUN_ON(network_thread()); TeardownDataChannelTransport_n(); @@ -7445,12 +7340,8 @@ void PeerConnection::OnSetStreams() { } PeerConnectionObserver* PeerConnection::Observer() const { - // In earlier production code, the pointer was not cleared on close, - // which might have led to undefined behavior if the observer was not - // deallocated, or strange crashes if it was. - // We use CHECK in order to catch such behavior if it exists. - // TODO(hta): Remove or replace with DCHECK if nothing is found. - RTC_CHECK(observer_); + RTC_DCHECK_RUN_ON(signaling_thread()); + RTC_DCHECK(observer_); return observer_; } @@ -7534,7 +7425,7 @@ bool PeerConnection::CheckIfNegotiationIsNeeded() { // 4. If connection has created any RTCDataChannels, and no m= section in // description has been negotiated yet for data, return true. - if (!sctp_data_channels_.empty()) { + if (data_channel_controller_.HasSctpDataChannels()) { if (!cricket::GetFirstDataContent(description->description()->contents())) return true; } diff --git a/pc/peer_connection.h b/pc/peer_connection.h index 7a1576611b..941b744b13 100644 --- a/pc/peer_connection.h +++ b/pc/peer_connection.h @@ -21,6 +21,7 @@ #include "api/peer_connection_interface.h" #include "api/transport/data_channel_transport_interface.h" #include "api/turn_customizer.h" +#include "pc/data_channel_controller.h" #include "pc/ice_server_parsing.h" #include "pc/jsep_transport_controller.h" #include "pc/peer_connection_factory.h" @@ -269,7 +270,7 @@ class PeerConnection : public PeerConnectionInternal, } sigslot::signal1& SignalDataChannelCreated() override { - return SignalDataChannelCreated_; + return data_channel_controller_.SignalDataChannelCreated(); } cricket::RtpDataChannel* rtp_data_channel() const override { @@ -279,7 +280,7 @@ class PeerConnection : public PeerConnectionInternal, std::vector> sctp_data_channels() const override { RTC_DCHECK_RUN_ON(signaling_thread()); - return sctp_data_channels_; + return *data_channel_controller_.sctp_data_channels(); } absl::optional sctp_content_name() const override { @@ -304,6 +305,22 @@ class PeerConnection : public PeerConnectionInternal, bool NeedsIceRestart(const std::string& content_name) const override; bool GetSslRole(const std::string& content_name, rtc::SSLRole* role) override; + // Functions needed by DataChannelController + void NoteDataAddedEvent() { NoteUsageEvent(UsageEvent::DATA_ADDED); } + // Returns the observer. Will crash on CHECK if the observer is removed. + PeerConnectionObserver* Observer() const; + bool IsClosed() const { + RTC_DCHECK_RUN_ON(signaling_thread()); + return signaling_state_ == PeerConnectionInterface::kClosed; + } + // Get current SSL role used by SCTP's underlying transport. + bool GetSctpSslRole(rtc::SSLRole* role); + // Handler for the "channel closed" signal + void OnSctpDataChannelClosed(DataChannel* channel); + // Sends the MSG_FREE_DATACHANNELS signal + void SignalFreeDataChannels(); + + // Functions made public for testing. void ReturnHistogramVeryQuicklyForTesting() { RTC_DCHECK_RUN_ON(signaling_thread()); return_histogram_very_quickly_ = true; @@ -318,6 +335,7 @@ class PeerConnection : public PeerConnectionInternal, friend class ImplicitCreateSessionDescriptionObserver; class SetRemoteDescriptionObserverAdapter; friend class SetRemoteDescriptionObserverAdapter; + // Represents the [[LocalIceCredentialsToReplace]] internal slot in the spec. // It makes the next CreateOffer() produce new ICE credentials even if // RTCOfferAnswerOptions::ice_restart is false. @@ -395,120 +413,6 @@ class PeerConnection : public PeerConnectionInternal, FieldTrialFlag receive_only; }; - // Controller for datachannels. Intended to be separated out; placed here as a - // first stage in refactoring. - class DataChannelController : public DataChannelProviderInterface, - public DataChannelSink { - public: - explicit DataChannelController(PeerConnection* pc) : pc_(pc) {} - ~DataChannelController() { data_channel_transport_invoker_.reset(); } - - // Implements DataChannelProviderInterface. - bool SendData(const cricket::SendDataParams& params, - const rtc::CopyOnWriteBuffer& payload, - cricket::SendDataResult* result) override; - bool ConnectDataChannel(DataChannel* webrtc_data_channel) override; - void DisconnectDataChannel(DataChannel* webrtc_data_channel) override; - void AddSctpDataStream(int sid) override; - void RemoveSctpDataStream(int sid) override; - bool ReadyToSendData() const override; - - // Implements DataChannelSink. - void OnDataReceived(int channel_id, - DataMessageType type, - const rtc::CopyOnWriteBuffer& buffer) override; - void OnChannelClosing(int channel_id) override; - void OnChannelClosed(int channel_id) override; - void OnReadyToSend() override; - - // Called from PeerConnection::SetupDataChannelTransport_n - void SetupDataChannelTransport_n(); - // Called from PeerConnection::TeardownDataChannelTransport_n - void TeardownDataChannelTransport_n(); - - // Called from PeerConnection::OnTransportChanged - // to make required changes to datachannels' transports. - void OnTransportChanged( - DataChannelTransportInterface* data_channel_transport); - - // Parses and handles open messages. Returns true if the message is an open - // message, false otherwise. - bool HandleOpenMessage_s(const cricket::ReceiveDataParams& params, - const rtc::CopyOnWriteBuffer& buffer) - RTC_RUN_ON(signaling_thread()); - // Called when a valid data channel OPEN message is received. - void OnDataChannelOpenMessage(const std::string& label, - const InternalDataChannelInit& config) - RTC_RUN_ON(signaling_thread()); - - // Creates channel and adds it to the collection of DataChannels that will - // be offered in a SessionDescription. - rtc::scoped_refptr InternalCreateDataChannel( - const std::string& label, - const InternalDataChannelInit* - config) /* RTC_RUN_ON(signaling_thread()) */; - void AllocateSctpSids( - rtc::SSLRole role) /* RTC_RUN_ON(signaling_thread()) */; - void OnSctpDataChannelClosed(DataChannel* channel); - /* RTC_RUN_ON(signaling_thread() */ - - // Accessors - cricket::RtpDataChannel* rtp_data_channel() const { - return rtp_data_channel_; - } - void set_rtp_data_channel(cricket::RtpDataChannel* channel) { - rtp_data_channel_ = channel; - } - DataChannelTransportInterface* data_channel_transport() const { - return data_channel_transport_; - } - void set_data_channel_transport(DataChannelTransportInterface* transport) { - data_channel_transport_ = transport; - } - - private: - rtc::Thread* network_thread() const { return pc_->network_thread(); } - rtc::Thread* signaling_thread() const { return pc_->signaling_thread(); } - // Plugin transport used for data channels. Pointer may be accessed and - // checked from any thread, but the object may only be touched on the - // network thread. - // TODO(bugs.webrtc.org/9987): Accessed on both signaling and network - // thread. - DataChannelTransportInterface* data_channel_transport_ = nullptr; - - // Cached value of whether the data channel transport is ready to send. - bool data_channel_transport_ready_to_send_ - RTC_GUARDED_BY(signaling_thread()) = false; - - // |rtp_data_channel_| is used if in RTP data channel mode, - // |data_channel_transport_| when using SCTP. - cricket::RtpDataChannel* rtp_data_channel_ = nullptr; - // TODO(bugs.webrtc.org/9987): Accessed on both - // signaling and some other thread. - - SctpSidAllocator sid_allocator_ /* RTC_GUARDED_BY(signaling_thread()) */; - - // Signals from |data_channel_transport_|. These are invoked on the - // signaling thread. - sigslot::signal1 SignalDataChannelTransportWritable_s - RTC_GUARDED_BY(signaling_thread()); - sigslot::signal2 - SignalDataChannelTransportReceivedData_s - RTC_GUARDED_BY(signaling_thread()); - sigslot::signal1 SignalDataChannelTransportChannelClosing_s - RTC_GUARDED_BY(signaling_thread()); - sigslot::signal1 SignalDataChannelTransportChannelClosed_s - RTC_GUARDED_BY(signaling_thread()); - - // Used to invoke data channel transport signals on the signaling thread. - std::unique_ptr data_channel_transport_invoker_ - RTC_GUARDED_BY(network_thread()); - - // Owning PeerConnection. - PeerConnection* pc_; - }; - // Captures partial state to be used for rollback. Applicable only in // Unified Plan. class TransceiverStableState { @@ -807,11 +711,6 @@ class PeerConnection : public PeerConnectionInternal, void OnNegotiationNeeded(); - bool IsClosed() const { - RTC_DCHECK_RUN_ON(signaling_thread()); - return signaling_state_ == PeerConnectionInterface::kClosed; - } - // Returns a MediaSessionOptions struct with options decided by |options|, // the local MediaStreams and DataChannels. void GetOptionsForOffer(const PeerConnectionInterface::RTCOfferAnswerOptions& @@ -944,27 +843,6 @@ class PeerConnection : public PeerConnectionInternal, cricket::MediaType media_type) RTC_RUN_ON(signaling_thread()); - void UpdateLocalRtpDataChannels(const cricket::StreamParamsVec& streams) - RTC_RUN_ON(signaling_thread()); - void UpdateRemoteRtpDataChannels(const cricket::StreamParamsVec& streams) - RTC_RUN_ON(signaling_thread()); - void UpdateClosingRtpDataChannels( - const std::vector& active_channels, - bool is_local_update) RTC_RUN_ON(signaling_thread()); - void CreateRemoteRtpDataChannel(const std::string& label, - uint32_t remote_ssrc) - RTC_RUN_ON(signaling_thread()); - - // Checks if any data channel has been added. - bool HasDataChannels() const RTC_RUN_ON(signaling_thread()); - // Handler for the "channel closed" signal - void OnSctpDataChannelClosed(DataChannel* channel); - // Sends the MSG_FREE_DATACHANNELS signal - void SignalFreeDataChannels(); - - // Called when the transport for the data channels is closed or destroyed. - void OnTransportChannelClosed() RTC_RUN_ON(signaling_thread()); - // Returns true if the PeerConnection is configured to use Unified Plan // semantics for creating offers/answers and setting local/remote // descriptions. If this is true the RtpTransceiver API will also be available @@ -1065,9 +943,6 @@ class PeerConnection : public PeerConnectionInternal, cricket::ChannelInterface* GetChannel(const std::string& content_name); - // Get current SSL role used by SCTP's underlying transport. - bool GetSctpSslRole(rtc::SSLRole* role); - cricket::IceConfig ParseIceConfig( const PeerConnectionInterface::RTCConfiguration& config) const; @@ -1283,9 +1158,6 @@ class PeerConnection : public PeerConnectionInternal, // RtpSenderBase::SetStreamsObserver override. void OnSetStreams() override; - // Returns the observer. Will crash on CHECK if the observer is removed. - PeerConnectionObserver* Observer() const RTC_RUN_ON(signaling_thread()); - // Returns the CryptoOptions for this PeerConnection. This will always // return the RTCConfiguration.crypto_options if set and will only default // back to the PeerConnectionFactory settings if nothing was set. @@ -1305,9 +1177,6 @@ class PeerConnection : public PeerConnectionInternal, // | sdp_type | is the type of the SDP that caused the rollback. RTCError Rollback(SdpType sdp_type); - sigslot::signal1 SignalDataChannelCreated_ - RTC_GUARDED_BY(signaling_thread()); - // Storing the factory as a scoped reference pointer ensures that the memory // in the PeerConnectionFactoryImpl remains available as long as the // PeerConnection is running. It is passed to PeerConnection as a raw pointer. @@ -1406,14 +1275,6 @@ class PeerConnection : public PeerConnectionInternal, std::vector local_video_sender_infos_ RTC_GUARDED_BY(signaling_thread()); - // label -> DataChannel - std::map> rtp_data_channels_ - RTC_GUARDED_BY(signaling_thread()); - std::vector> sctp_data_channels_ - RTC_GUARDED_BY(signaling_thread()); - std::vector> sctp_data_channels_to_free_ - RTC_GUARDED_BY(signaling_thread()); - bool remote_peer_supports_msid_ RTC_GUARDED_BY(signaling_thread()) = false; // The unique_ptr belongs to the worker thread, but the Call object manages @@ -1489,16 +1350,6 @@ class PeerConnection : public PeerConnectionInternal, std::unique_ptr pending_remote_description_ RTC_GUARDED_BY(signaling_thread()); bool dtls_enabled_ RTC_GUARDED_BY(signaling_thread()) = false; - // Specifies which kind of data channel is allowed. This is controlled - // by the chrome command-line flag and constraints: - // 1. If chrome command-line switch 'enable-sctp-data-channels' is enabled, - // constraint kEnableDtlsSrtp is true, and constaint kEnableRtpDataChannels is - // not set or false, SCTP is allowed (DCT_SCTP); - // 2. If constraint kEnableRtpDataChannels is true, RTP is allowed (DCT_RTP); - // 3. If both 1&2 are false, data channel is not allowed (DCT_NONE). - cricket::DataChannelType data_channel_type_ = - cricket::DCT_NONE; // TODO(bugs.webrtc.org/9987): Accessed on both - // signaling and network thread. // List of content names for which the remote side triggered an ICE restart. std::set pending_ice_restarts_