summaryrefslogtreecommitdiffstats
path: root/third_party/libwebrtc/test/peer_scenario/scenario_connection.cc
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/libwebrtc/test/peer_scenario/scenario_connection.cc')
-rw-r--r--third_party/libwebrtc/test/peer_scenario/scenario_connection.cc242
1 files changed, 242 insertions, 0 deletions
diff --git a/third_party/libwebrtc/test/peer_scenario/scenario_connection.cc b/third_party/libwebrtc/test/peer_scenario/scenario_connection.cc
new file mode 100644
index 0000000000..66eca275d1
--- /dev/null
+++ b/third_party/libwebrtc/test/peer_scenario/scenario_connection.cc
@@ -0,0 +1,242 @@
+/*
+ * Copyright (c) 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.
+ */
+#include "test/peer_scenario/scenario_connection.h"
+
+#include "absl/memory/memory.h"
+#include "media/base/rtp_utils.h"
+#include "modules/rtp_rtcp/source/rtp_packet_received.h"
+#include "p2p/client/basic_port_allocator.h"
+#include "pc/channel.h"
+#include "pc/jsep_transport_controller.h"
+#include "pc/rtp_transport_internal.h"
+#include "pc/session_description.h"
+#include "rtc_base/task_queue_for_test.h"
+
+namespace webrtc {
+class ScenarioIceConnectionImpl : public ScenarioIceConnection,
+ public sigslot::has_slots<>,
+ private JsepTransportController::Observer,
+ private RtpPacketSinkInterface {
+ public:
+ ScenarioIceConnectionImpl(test::NetworkEmulationManagerImpl* net,
+ IceConnectionObserver* observer);
+ ~ScenarioIceConnectionImpl() override;
+
+ void SendRtpPacket(rtc::ArrayView<const uint8_t> packet_view) override;
+ void SendRtcpPacket(rtc::ArrayView<const uint8_t> packet_view) override;
+
+ void SetRemoteSdp(SdpType type, const std::string& remote_sdp) override;
+ void SetLocalSdp(SdpType type, const std::string& local_sdp) override;
+
+ EmulatedEndpoint* endpoint() override { return endpoint_; }
+ const cricket::TransportDescription& transport_description() const override {
+ return transport_description_;
+ }
+
+ private:
+ JsepTransportController::Config CreateJsepConfig();
+ bool OnTransportChanged(
+ const std::string& mid,
+ RtpTransportInternal* rtp_transport,
+ rtc::scoped_refptr<DtlsTransport> dtls_transport,
+ DataChannelTransportInterface* data_channel_transport) override;
+
+ void OnRtpPacket(const RtpPacketReceived& packet) override;
+ void OnCandidates(const std::string& mid,
+ const std::vector<cricket::Candidate>& candidates);
+
+ IceConnectionObserver* const observer_;
+ EmulatedEndpoint* const endpoint_;
+ EmulatedNetworkManagerInterface* const manager_;
+ rtc::Thread* const signaling_thread_;
+ rtc::Thread* const network_thread_;
+ rtc::scoped_refptr<rtc::RTCCertificate> const certificate_
+ RTC_GUARDED_BY(network_thread_);
+ cricket::TransportDescription const transport_description_
+ RTC_GUARDED_BY(signaling_thread_);
+ std::unique_ptr<cricket::BasicPortAllocator> port_allocator_
+ RTC_GUARDED_BY(network_thread_);
+ std::unique_ptr<JsepTransportController> jsep_controller_;
+ RtpTransportInternal* rtp_transport_ RTC_GUARDED_BY(network_thread_) =
+ nullptr;
+ std::unique_ptr<SessionDescriptionInterface> remote_description_
+ RTC_GUARDED_BY(signaling_thread_);
+ std::unique_ptr<SessionDescriptionInterface> local_description_
+ RTC_GUARDED_BY(signaling_thread_);
+};
+
+std::unique_ptr<ScenarioIceConnection> ScenarioIceConnection::Create(
+ webrtc::test::NetworkEmulationManagerImpl* net,
+ IceConnectionObserver* observer) {
+ return std::make_unique<ScenarioIceConnectionImpl>(net, observer);
+}
+
+ScenarioIceConnectionImpl::ScenarioIceConnectionImpl(
+ test::NetworkEmulationManagerImpl* net,
+ IceConnectionObserver* observer)
+ : observer_(observer),
+ endpoint_(net->CreateEndpoint(EmulatedEndpointConfig())),
+ manager_(net->CreateEmulatedNetworkManagerInterface({endpoint_})),
+ signaling_thread_(rtc::Thread::Current()),
+ network_thread_(manager_->network_thread()),
+ certificate_(rtc::RTCCertificate::Create(
+ rtc::SSLIdentity::Create("", ::rtc::KT_DEFAULT))),
+ transport_description_(
+ /*transport_options*/ {},
+ rtc::CreateRandomString(cricket::ICE_UFRAG_LENGTH),
+ rtc::CreateRandomString(cricket::ICE_PWD_LENGTH),
+ cricket::IceMode::ICEMODE_FULL,
+ cricket::ConnectionRole::CONNECTIONROLE_PASSIVE,
+ rtc::SSLFingerprint::CreateFromCertificate(*certificate_.get())
+ .get()),
+ port_allocator_(
+ new cricket::BasicPortAllocator(manager_->network_manager(),
+ manager_->packet_socket_factory())),
+ jsep_controller_(
+ new JsepTransportController(network_thread_,
+ port_allocator_.get(),
+ /*async_resolver_factory*/ nullptr,
+ CreateJsepConfig())) {
+ SendTask(network_thread_, [this] {
+ RTC_DCHECK_RUN_ON(network_thread_);
+ uint32_t flags = cricket::PORTALLOCATOR_DISABLE_TCP;
+ port_allocator_->set_flags(port_allocator_->flags() | flags);
+ port_allocator_->Initialize();
+ RTC_CHECK(port_allocator_->SetConfiguration(/*stun_servers*/ {},
+ /*turn_servers*/ {}, 0,
+ webrtc::NO_PRUNE));
+ jsep_controller_->SetLocalCertificate(certificate_);
+ });
+}
+
+ScenarioIceConnectionImpl::~ScenarioIceConnectionImpl() {
+ SendTask(network_thread_, [this] {
+ RTC_DCHECK_RUN_ON(network_thread_);
+ jsep_controller_.reset();
+ port_allocator_.reset();
+ rtp_transport_ = nullptr;
+ });
+}
+
+JsepTransportController::Config ScenarioIceConnectionImpl::CreateJsepConfig() {
+ JsepTransportController::Config config;
+ config.transport_observer = this;
+ config.bundle_policy =
+ PeerConnectionInterface::BundlePolicy::kBundlePolicyMaxBundle;
+ config.rtcp_handler = [this](const rtc::CopyOnWriteBuffer& packet,
+ int64_t packet_time_us) {
+ RTC_DCHECK_RUN_ON(network_thread_);
+ observer_->OnPacketReceived(packet);
+ };
+ config.field_trials = &field_trials;
+ return config;
+}
+
+void ScenarioIceConnectionImpl::SendRtpPacket(
+ rtc::ArrayView<const uint8_t> packet_view) {
+ rtc::CopyOnWriteBuffer packet(packet_view.data(), packet_view.size(),
+ ::cricket::kMaxRtpPacketLen);
+ network_thread_->PostTask([this, packet = std::move(packet)]() mutable {
+ RTC_DCHECK_RUN_ON(network_thread_);
+ if (rtp_transport_ != nullptr)
+ rtp_transport_->SendRtpPacket(&packet, rtc::PacketOptions(),
+ cricket::PF_SRTP_BYPASS);
+ });
+}
+
+void ScenarioIceConnectionImpl::SendRtcpPacket(
+ rtc::ArrayView<const uint8_t> packet_view) {
+ rtc::CopyOnWriteBuffer packet(packet_view.data(), packet_view.size(),
+ ::cricket::kMaxRtpPacketLen);
+ network_thread_->PostTask([this, packet = std::move(packet)]() mutable {
+ RTC_DCHECK_RUN_ON(network_thread_);
+ if (rtp_transport_ != nullptr)
+ rtp_transport_->SendRtcpPacket(&packet, rtc::PacketOptions(),
+ cricket::PF_SRTP_BYPASS);
+ });
+}
+void ScenarioIceConnectionImpl::SetRemoteSdp(SdpType type,
+ const std::string& remote_sdp) {
+ RTC_DCHECK_RUN_ON(signaling_thread_);
+ remote_description_ = webrtc::CreateSessionDescription(type, remote_sdp);
+ jsep_controller_->SubscribeIceCandidateGathered(
+ [this](const std::string& transport,
+ const std::vector<cricket::Candidate>& candidate) {
+ ScenarioIceConnectionImpl::OnCandidates(transport, candidate);
+ });
+
+ auto res = jsep_controller_->SetRemoteDescription(
+ remote_description_->GetType(), remote_description_->description());
+ RTC_CHECK(res.ok()) << res.message();
+ RtpDemuxerCriteria criteria;
+ for (const auto& content : remote_description_->description()->contents()) {
+ if (content.media_description()->as_audio()) {
+ for (const auto& codec :
+ content.media_description()->as_audio()->codecs()) {
+ criteria.payload_types().insert(codec.id);
+ }
+ }
+ if (content.media_description()->as_video()) {
+ for (const auto& codec :
+ content.media_description()->as_video()->codecs()) {
+ criteria.payload_types().insert(codec.id);
+ }
+ }
+ }
+
+ network_thread_->PostTask([this, criteria]() {
+ RTC_DCHECK_RUN_ON(network_thread_);
+ RTC_DCHECK(rtp_transport_);
+ rtp_transport_->RegisterRtpDemuxerSink(criteria, this);
+ });
+}
+
+void ScenarioIceConnectionImpl::SetLocalSdp(SdpType type,
+ const std::string& local_sdp) {
+ RTC_DCHECK_RUN_ON(signaling_thread_);
+ local_description_ = webrtc::CreateSessionDescription(type, local_sdp);
+ auto res = jsep_controller_->SetLocalDescription(
+ local_description_->GetType(), local_description_->description());
+ RTC_CHECK(res.ok()) << res.message();
+ jsep_controller_->MaybeStartGathering();
+}
+
+bool ScenarioIceConnectionImpl::OnTransportChanged(
+ const std::string& mid,
+ RtpTransportInternal* rtp_transport,
+ rtc::scoped_refptr<DtlsTransport> dtls_transport,
+ DataChannelTransportInterface* data_channel_transport) {
+ RTC_DCHECK_RUN_ON(network_thread_);
+ if (rtp_transport == nullptr) {
+ rtp_transport_->UnregisterRtpDemuxerSink(this);
+ } else {
+ RTC_DCHECK(rtp_transport_ == nullptr || rtp_transport_ == rtp_transport);
+ if (rtp_transport_ != rtp_transport) {
+ rtp_transport_ = rtp_transport;
+ }
+ RtpDemuxerCriteria criteria(mid);
+ rtp_transport_->RegisterRtpDemuxerSink(criteria, this);
+ }
+ return true;
+}
+
+void ScenarioIceConnectionImpl::OnRtpPacket(const RtpPacketReceived& packet) {
+ RTC_DCHECK_RUN_ON(network_thread_);
+ observer_->OnPacketReceived(packet.Buffer());
+}
+
+void ScenarioIceConnectionImpl::OnCandidates(
+ const std::string& mid,
+ const std::vector<cricket::Candidate>& candidates) {
+ RTC_DCHECK_RUN_ON(signaling_thread_);
+ observer_->OnIceCandidates(mid, candidates);
+}
+
+} // namespace webrtc