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