1*d9f75844SAndroid Build Coastguard Worker /*
2*d9f75844SAndroid Build Coastguard Worker * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
3*d9f75844SAndroid Build Coastguard Worker *
4*d9f75844SAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license
5*d9f75844SAndroid Build Coastguard Worker * that can be found in the LICENSE file in the root of the source
6*d9f75844SAndroid Build Coastguard Worker * tree. An additional intellectual property rights grant can be found
7*d9f75844SAndroid Build Coastguard Worker * in the file PATENTS. All contributing project authors may
8*d9f75844SAndroid Build Coastguard Worker * be found in the AUTHORS file in the root of the source tree.
9*d9f75844SAndroid Build Coastguard Worker */
10*d9f75844SAndroid Build Coastguard Worker #include "test/peer_scenario/scenario_connection.h"
11*d9f75844SAndroid Build Coastguard Worker
12*d9f75844SAndroid Build Coastguard Worker #include "absl/memory/memory.h"
13*d9f75844SAndroid Build Coastguard Worker #include "media/base/rtp_utils.h"
14*d9f75844SAndroid Build Coastguard Worker #include "modules/rtp_rtcp/source/rtp_packet_received.h"
15*d9f75844SAndroid Build Coastguard Worker #include "p2p/client/basic_port_allocator.h"
16*d9f75844SAndroid Build Coastguard Worker #include "pc/channel.h"
17*d9f75844SAndroid Build Coastguard Worker #include "pc/jsep_transport_controller.h"
18*d9f75844SAndroid Build Coastguard Worker #include "pc/rtp_transport_internal.h"
19*d9f75844SAndroid Build Coastguard Worker #include "pc/session_description.h"
20*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/task_queue_for_test.h"
21*d9f75844SAndroid Build Coastguard Worker
22*d9f75844SAndroid Build Coastguard Worker namespace webrtc {
23*d9f75844SAndroid Build Coastguard Worker class ScenarioIceConnectionImpl : public ScenarioIceConnection,
24*d9f75844SAndroid Build Coastguard Worker public sigslot::has_slots<>,
25*d9f75844SAndroid Build Coastguard Worker private JsepTransportController::Observer,
26*d9f75844SAndroid Build Coastguard Worker private RtpPacketSinkInterface {
27*d9f75844SAndroid Build Coastguard Worker public:
28*d9f75844SAndroid Build Coastguard Worker ScenarioIceConnectionImpl(test::NetworkEmulationManagerImpl* net,
29*d9f75844SAndroid Build Coastguard Worker IceConnectionObserver* observer);
30*d9f75844SAndroid Build Coastguard Worker ~ScenarioIceConnectionImpl() override;
31*d9f75844SAndroid Build Coastguard Worker
32*d9f75844SAndroid Build Coastguard Worker void SendRtpPacket(rtc::ArrayView<const uint8_t> packet_view) override;
33*d9f75844SAndroid Build Coastguard Worker void SendRtcpPacket(rtc::ArrayView<const uint8_t> packet_view) override;
34*d9f75844SAndroid Build Coastguard Worker
35*d9f75844SAndroid Build Coastguard Worker void SetRemoteSdp(SdpType type, const std::string& remote_sdp) override;
36*d9f75844SAndroid Build Coastguard Worker void SetLocalSdp(SdpType type, const std::string& local_sdp) override;
37*d9f75844SAndroid Build Coastguard Worker
endpoint()38*d9f75844SAndroid Build Coastguard Worker EmulatedEndpoint* endpoint() override { return endpoint_; }
transport_description() const39*d9f75844SAndroid Build Coastguard Worker const cricket::TransportDescription& transport_description() const override {
40*d9f75844SAndroid Build Coastguard Worker return transport_description_;
41*d9f75844SAndroid Build Coastguard Worker }
42*d9f75844SAndroid Build Coastguard Worker
43*d9f75844SAndroid Build Coastguard Worker private:
44*d9f75844SAndroid Build Coastguard Worker JsepTransportController::Config CreateJsepConfig();
45*d9f75844SAndroid Build Coastguard Worker bool OnTransportChanged(
46*d9f75844SAndroid Build Coastguard Worker const std::string& mid,
47*d9f75844SAndroid Build Coastguard Worker RtpTransportInternal* rtp_transport,
48*d9f75844SAndroid Build Coastguard Worker rtc::scoped_refptr<DtlsTransport> dtls_transport,
49*d9f75844SAndroid Build Coastguard Worker DataChannelTransportInterface* data_channel_transport) override;
50*d9f75844SAndroid Build Coastguard Worker
51*d9f75844SAndroid Build Coastguard Worker void OnRtpPacket(const RtpPacketReceived& packet) override;
52*d9f75844SAndroid Build Coastguard Worker void OnCandidates(const std::string& mid,
53*d9f75844SAndroid Build Coastguard Worker const std::vector<cricket::Candidate>& candidates);
54*d9f75844SAndroid Build Coastguard Worker
55*d9f75844SAndroid Build Coastguard Worker IceConnectionObserver* const observer_;
56*d9f75844SAndroid Build Coastguard Worker EmulatedEndpoint* const endpoint_;
57*d9f75844SAndroid Build Coastguard Worker EmulatedNetworkManagerInterface* const manager_;
58*d9f75844SAndroid Build Coastguard Worker rtc::Thread* const signaling_thread_;
59*d9f75844SAndroid Build Coastguard Worker rtc::Thread* const network_thread_;
60*d9f75844SAndroid Build Coastguard Worker rtc::scoped_refptr<rtc::RTCCertificate> const certificate_
61*d9f75844SAndroid Build Coastguard Worker RTC_GUARDED_BY(network_thread_);
62*d9f75844SAndroid Build Coastguard Worker cricket::TransportDescription const transport_description_
63*d9f75844SAndroid Build Coastguard Worker RTC_GUARDED_BY(signaling_thread_);
64*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<cricket::BasicPortAllocator> port_allocator_
65*d9f75844SAndroid Build Coastguard Worker RTC_GUARDED_BY(network_thread_);
66*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<JsepTransportController> jsep_controller_;
67*d9f75844SAndroid Build Coastguard Worker RtpTransportInternal* rtp_transport_ RTC_GUARDED_BY(network_thread_) =
68*d9f75844SAndroid Build Coastguard Worker nullptr;
69*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<SessionDescriptionInterface> remote_description_
70*d9f75844SAndroid Build Coastguard Worker RTC_GUARDED_BY(signaling_thread_);
71*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<SessionDescriptionInterface> local_description_
72*d9f75844SAndroid Build Coastguard Worker RTC_GUARDED_BY(signaling_thread_);
73*d9f75844SAndroid Build Coastguard Worker };
74*d9f75844SAndroid Build Coastguard Worker
Create(webrtc::test::NetworkEmulationManagerImpl * net,IceConnectionObserver * observer)75*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<ScenarioIceConnection> ScenarioIceConnection::Create(
76*d9f75844SAndroid Build Coastguard Worker webrtc::test::NetworkEmulationManagerImpl* net,
77*d9f75844SAndroid Build Coastguard Worker IceConnectionObserver* observer) {
78*d9f75844SAndroid Build Coastguard Worker return std::make_unique<ScenarioIceConnectionImpl>(net, observer);
79*d9f75844SAndroid Build Coastguard Worker }
80*d9f75844SAndroid Build Coastguard Worker
ScenarioIceConnectionImpl(test::NetworkEmulationManagerImpl * net,IceConnectionObserver * observer)81*d9f75844SAndroid Build Coastguard Worker ScenarioIceConnectionImpl::ScenarioIceConnectionImpl(
82*d9f75844SAndroid Build Coastguard Worker test::NetworkEmulationManagerImpl* net,
83*d9f75844SAndroid Build Coastguard Worker IceConnectionObserver* observer)
84*d9f75844SAndroid Build Coastguard Worker : observer_(observer),
85*d9f75844SAndroid Build Coastguard Worker endpoint_(net->CreateEndpoint(EmulatedEndpointConfig())),
86*d9f75844SAndroid Build Coastguard Worker manager_(net->CreateEmulatedNetworkManagerInterface({endpoint_})),
87*d9f75844SAndroid Build Coastguard Worker signaling_thread_(rtc::Thread::Current()),
88*d9f75844SAndroid Build Coastguard Worker network_thread_(manager_->network_thread()),
89*d9f75844SAndroid Build Coastguard Worker certificate_(rtc::RTCCertificate::Create(
90*d9f75844SAndroid Build Coastguard Worker rtc::SSLIdentity::Create("", ::rtc::KT_DEFAULT))),
91*d9f75844SAndroid Build Coastguard Worker transport_description_(
92*d9f75844SAndroid Build Coastguard Worker /*transport_options*/ {},
93*d9f75844SAndroid Build Coastguard Worker rtc::CreateRandomString(cricket::ICE_UFRAG_LENGTH),
94*d9f75844SAndroid Build Coastguard Worker rtc::CreateRandomString(cricket::ICE_PWD_LENGTH),
95*d9f75844SAndroid Build Coastguard Worker cricket::IceMode::ICEMODE_FULL,
96*d9f75844SAndroid Build Coastguard Worker cricket::ConnectionRole::CONNECTIONROLE_PASSIVE,
97*d9f75844SAndroid Build Coastguard Worker rtc::SSLFingerprint::CreateFromCertificate(*certificate_.get())
98*d9f75844SAndroid Build Coastguard Worker .get()),
99*d9f75844SAndroid Build Coastguard Worker port_allocator_(
100*d9f75844SAndroid Build Coastguard Worker new cricket::BasicPortAllocator(manager_->network_manager(),
101*d9f75844SAndroid Build Coastguard Worker manager_->packet_socket_factory())),
102*d9f75844SAndroid Build Coastguard Worker jsep_controller_(
103*d9f75844SAndroid Build Coastguard Worker new JsepTransportController(network_thread_,
104*d9f75844SAndroid Build Coastguard Worker port_allocator_.get(),
105*d9f75844SAndroid Build Coastguard Worker /*async_resolver_factory*/ nullptr,
106*d9f75844SAndroid Build Coastguard Worker CreateJsepConfig())) {
__anon96c85c110102null107*d9f75844SAndroid Build Coastguard Worker SendTask(network_thread_, [this] {
108*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(network_thread_);
109*d9f75844SAndroid Build Coastguard Worker uint32_t flags = cricket::PORTALLOCATOR_DISABLE_TCP;
110*d9f75844SAndroid Build Coastguard Worker port_allocator_->set_flags(port_allocator_->flags() | flags);
111*d9f75844SAndroid Build Coastguard Worker port_allocator_->Initialize();
112*d9f75844SAndroid Build Coastguard Worker RTC_CHECK(port_allocator_->SetConfiguration(/*stun_servers*/ {},
113*d9f75844SAndroid Build Coastguard Worker /*turn_servers*/ {}, 0,
114*d9f75844SAndroid Build Coastguard Worker webrtc::NO_PRUNE));
115*d9f75844SAndroid Build Coastguard Worker jsep_controller_->SetLocalCertificate(certificate_);
116*d9f75844SAndroid Build Coastguard Worker });
117*d9f75844SAndroid Build Coastguard Worker }
118*d9f75844SAndroid Build Coastguard Worker
~ScenarioIceConnectionImpl()119*d9f75844SAndroid Build Coastguard Worker ScenarioIceConnectionImpl::~ScenarioIceConnectionImpl() {
120*d9f75844SAndroid Build Coastguard Worker SendTask(network_thread_, [this] {
121*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(network_thread_);
122*d9f75844SAndroid Build Coastguard Worker jsep_controller_.reset();
123*d9f75844SAndroid Build Coastguard Worker port_allocator_.reset();
124*d9f75844SAndroid Build Coastguard Worker rtp_transport_ = nullptr;
125*d9f75844SAndroid Build Coastguard Worker });
126*d9f75844SAndroid Build Coastguard Worker }
127*d9f75844SAndroid Build Coastguard Worker
CreateJsepConfig()128*d9f75844SAndroid Build Coastguard Worker JsepTransportController::Config ScenarioIceConnectionImpl::CreateJsepConfig() {
129*d9f75844SAndroid Build Coastguard Worker JsepTransportController::Config config;
130*d9f75844SAndroid Build Coastguard Worker config.transport_observer = this;
131*d9f75844SAndroid Build Coastguard Worker config.bundle_policy =
132*d9f75844SAndroid Build Coastguard Worker PeerConnectionInterface::BundlePolicy::kBundlePolicyMaxBundle;
133*d9f75844SAndroid Build Coastguard Worker config.rtcp_handler = [this](const rtc::CopyOnWriteBuffer& packet,
134*d9f75844SAndroid Build Coastguard Worker int64_t packet_time_us) {
135*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(network_thread_);
136*d9f75844SAndroid Build Coastguard Worker observer_->OnPacketReceived(packet);
137*d9f75844SAndroid Build Coastguard Worker };
138*d9f75844SAndroid Build Coastguard Worker config.field_trials = &field_trials;
139*d9f75844SAndroid Build Coastguard Worker return config;
140*d9f75844SAndroid Build Coastguard Worker }
141*d9f75844SAndroid Build Coastguard Worker
SendRtpPacket(rtc::ArrayView<const uint8_t> packet_view)142*d9f75844SAndroid Build Coastguard Worker void ScenarioIceConnectionImpl::SendRtpPacket(
143*d9f75844SAndroid Build Coastguard Worker rtc::ArrayView<const uint8_t> packet_view) {
144*d9f75844SAndroid Build Coastguard Worker rtc::CopyOnWriteBuffer packet(packet_view.data(), packet_view.size(),
145*d9f75844SAndroid Build Coastguard Worker ::cricket::kMaxRtpPacketLen);
146*d9f75844SAndroid Build Coastguard Worker network_thread_->PostTask([this, packet = std::move(packet)]() mutable {
147*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(network_thread_);
148*d9f75844SAndroid Build Coastguard Worker if (rtp_transport_ != nullptr)
149*d9f75844SAndroid Build Coastguard Worker rtp_transport_->SendRtpPacket(&packet, rtc::PacketOptions(),
150*d9f75844SAndroid Build Coastguard Worker cricket::PF_SRTP_BYPASS);
151*d9f75844SAndroid Build Coastguard Worker });
152*d9f75844SAndroid Build Coastguard Worker }
153*d9f75844SAndroid Build Coastguard Worker
SendRtcpPacket(rtc::ArrayView<const uint8_t> packet_view)154*d9f75844SAndroid Build Coastguard Worker void ScenarioIceConnectionImpl::SendRtcpPacket(
155*d9f75844SAndroid Build Coastguard Worker rtc::ArrayView<const uint8_t> packet_view) {
156*d9f75844SAndroid Build Coastguard Worker rtc::CopyOnWriteBuffer packet(packet_view.data(), packet_view.size(),
157*d9f75844SAndroid Build Coastguard Worker ::cricket::kMaxRtpPacketLen);
158*d9f75844SAndroid Build Coastguard Worker network_thread_->PostTask([this, packet = std::move(packet)]() mutable {
159*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(network_thread_);
160*d9f75844SAndroid Build Coastguard Worker if (rtp_transport_ != nullptr)
161*d9f75844SAndroid Build Coastguard Worker rtp_transport_->SendRtcpPacket(&packet, rtc::PacketOptions(),
162*d9f75844SAndroid Build Coastguard Worker cricket::PF_SRTP_BYPASS);
163*d9f75844SAndroid Build Coastguard Worker });
164*d9f75844SAndroid Build Coastguard Worker }
SetRemoteSdp(SdpType type,const std::string & remote_sdp)165*d9f75844SAndroid Build Coastguard Worker void ScenarioIceConnectionImpl::SetRemoteSdp(SdpType type,
166*d9f75844SAndroid Build Coastguard Worker const std::string& remote_sdp) {
167*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(signaling_thread_);
168*d9f75844SAndroid Build Coastguard Worker remote_description_ = webrtc::CreateSessionDescription(type, remote_sdp);
169*d9f75844SAndroid Build Coastguard Worker jsep_controller_->SubscribeIceCandidateGathered(
170*d9f75844SAndroid Build Coastguard Worker [this](const std::string& transport,
171*d9f75844SAndroid Build Coastguard Worker const std::vector<cricket::Candidate>& candidate) {
172*d9f75844SAndroid Build Coastguard Worker ScenarioIceConnectionImpl::OnCandidates(transport, candidate);
173*d9f75844SAndroid Build Coastguard Worker });
174*d9f75844SAndroid Build Coastguard Worker
175*d9f75844SAndroid Build Coastguard Worker auto res = jsep_controller_->SetRemoteDescription(
176*d9f75844SAndroid Build Coastguard Worker remote_description_->GetType(), remote_description_->description());
177*d9f75844SAndroid Build Coastguard Worker RTC_CHECK(res.ok()) << res.message();
178*d9f75844SAndroid Build Coastguard Worker RtpDemuxerCriteria criteria;
179*d9f75844SAndroid Build Coastguard Worker for (const auto& content : remote_description_->description()->contents()) {
180*d9f75844SAndroid Build Coastguard Worker if (content.media_description()->as_audio()) {
181*d9f75844SAndroid Build Coastguard Worker for (const auto& codec :
182*d9f75844SAndroid Build Coastguard Worker content.media_description()->as_audio()->codecs()) {
183*d9f75844SAndroid Build Coastguard Worker criteria.payload_types().insert(codec.id);
184*d9f75844SAndroid Build Coastguard Worker }
185*d9f75844SAndroid Build Coastguard Worker }
186*d9f75844SAndroid Build Coastguard Worker if (content.media_description()->as_video()) {
187*d9f75844SAndroid Build Coastguard Worker for (const auto& codec :
188*d9f75844SAndroid Build Coastguard Worker content.media_description()->as_video()->codecs()) {
189*d9f75844SAndroid Build Coastguard Worker criteria.payload_types().insert(codec.id);
190*d9f75844SAndroid Build Coastguard Worker }
191*d9f75844SAndroid Build Coastguard Worker }
192*d9f75844SAndroid Build Coastguard Worker }
193*d9f75844SAndroid Build Coastguard Worker
194*d9f75844SAndroid Build Coastguard Worker network_thread_->PostTask([this, criteria]() {
195*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(network_thread_);
196*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK(rtp_transport_);
197*d9f75844SAndroid Build Coastguard Worker rtp_transport_->RegisterRtpDemuxerSink(criteria, this);
198*d9f75844SAndroid Build Coastguard Worker });
199*d9f75844SAndroid Build Coastguard Worker }
200*d9f75844SAndroid Build Coastguard Worker
SetLocalSdp(SdpType type,const std::string & local_sdp)201*d9f75844SAndroid Build Coastguard Worker void ScenarioIceConnectionImpl::SetLocalSdp(SdpType type,
202*d9f75844SAndroid Build Coastguard Worker const std::string& local_sdp) {
203*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(signaling_thread_);
204*d9f75844SAndroid Build Coastguard Worker local_description_ = webrtc::CreateSessionDescription(type, local_sdp);
205*d9f75844SAndroid Build Coastguard Worker auto res = jsep_controller_->SetLocalDescription(
206*d9f75844SAndroid Build Coastguard Worker local_description_->GetType(), local_description_->description());
207*d9f75844SAndroid Build Coastguard Worker RTC_CHECK(res.ok()) << res.message();
208*d9f75844SAndroid Build Coastguard Worker jsep_controller_->MaybeStartGathering();
209*d9f75844SAndroid Build Coastguard Worker }
210*d9f75844SAndroid Build Coastguard Worker
OnTransportChanged(const std::string & mid,RtpTransportInternal * rtp_transport,rtc::scoped_refptr<DtlsTransport> dtls_transport,DataChannelTransportInterface * data_channel_transport)211*d9f75844SAndroid Build Coastguard Worker bool ScenarioIceConnectionImpl::OnTransportChanged(
212*d9f75844SAndroid Build Coastguard Worker const std::string& mid,
213*d9f75844SAndroid Build Coastguard Worker RtpTransportInternal* rtp_transport,
214*d9f75844SAndroid Build Coastguard Worker rtc::scoped_refptr<DtlsTransport> dtls_transport,
215*d9f75844SAndroid Build Coastguard Worker DataChannelTransportInterface* data_channel_transport) {
216*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(network_thread_);
217*d9f75844SAndroid Build Coastguard Worker if (rtp_transport == nullptr) {
218*d9f75844SAndroid Build Coastguard Worker rtp_transport_->UnregisterRtpDemuxerSink(this);
219*d9f75844SAndroid Build Coastguard Worker } else {
220*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK(rtp_transport_ == nullptr || rtp_transport_ == rtp_transport);
221*d9f75844SAndroid Build Coastguard Worker if (rtp_transport_ != rtp_transport) {
222*d9f75844SAndroid Build Coastguard Worker rtp_transport_ = rtp_transport;
223*d9f75844SAndroid Build Coastguard Worker }
224*d9f75844SAndroid Build Coastguard Worker RtpDemuxerCriteria criteria(mid);
225*d9f75844SAndroid Build Coastguard Worker rtp_transport_->RegisterRtpDemuxerSink(criteria, this);
226*d9f75844SAndroid Build Coastguard Worker }
227*d9f75844SAndroid Build Coastguard Worker return true;
228*d9f75844SAndroid Build Coastguard Worker }
229*d9f75844SAndroid Build Coastguard Worker
OnRtpPacket(const RtpPacketReceived & packet)230*d9f75844SAndroid Build Coastguard Worker void ScenarioIceConnectionImpl::OnRtpPacket(const RtpPacketReceived& packet) {
231*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(network_thread_);
232*d9f75844SAndroid Build Coastguard Worker observer_->OnPacketReceived(packet.Buffer());
233*d9f75844SAndroid Build Coastguard Worker }
234*d9f75844SAndroid Build Coastguard Worker
OnCandidates(const std::string & mid,const std::vector<cricket::Candidate> & candidates)235*d9f75844SAndroid Build Coastguard Worker void ScenarioIceConnectionImpl::OnCandidates(
236*d9f75844SAndroid Build Coastguard Worker const std::string& mid,
237*d9f75844SAndroid Build Coastguard Worker const std::vector<cricket::Candidate>& candidates) {
238*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(signaling_thread_);
239*d9f75844SAndroid Build Coastguard Worker observer_->OnIceCandidates(mid, candidates);
240*d9f75844SAndroid Build Coastguard Worker }
241*d9f75844SAndroid Build Coastguard Worker
242*d9f75844SAndroid Build Coastguard Worker } // namespace webrtc
243