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