blob: f617445a06d97d168f6ce62ae3b6d961b4ecef05 [file] [log] [blame]
zstein56162b92017-04-24 23:54:351/*
2 * Copyright 2017 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
Yves Gerey3e707812018-11-28 15:47:4911#include <cstdint>
12#include <set>
zstein56162b92017-04-24 23:54:3513#include <string>
Mirko Bonadeic61ce0d2017-11-21 16:04:2014#include <utility>
zstein56162b92017-04-24 23:54:3515
Yves Gerey3e707812018-11-28 15:47:4916#include "api/rtp_headers.h"
Steve Anton10542f22019-01-11 17:11:0017#include "api/rtp_parameters.h"
18#include "p2p/base/fake_packet_transport.h"
19#include "pc/rtp_transport.h"
20#include "pc/test/rtp_transport_test_util.h"
Yves Gerey3e707812018-11-28 15:47:4921#include "rtc_base/buffer.h"
22#include "rtc_base/third_party/sigslot/sigslot.h"
23#include "test/gtest.h"
zstein56162b92017-04-24 23:54:3524
25namespace webrtc {
26
zstein56162b92017-04-24 23:54:3527constexpr bool kMuxDisabled = false;
28constexpr bool kMuxEnabled = true;
Zhi Huang942bc2e2017-11-13 21:26:0729constexpr uint16_t kLocalNetId = 1;
30constexpr uint16_t kRemoteNetId = 2;
31constexpr int kLastPacketId = 100;
32constexpr int kTransportOverheadPerPacket = 28; // Ipv4(20) + UDP(8).
zstein56162b92017-04-24 23:54:3533
zstein3dcf0e92017-06-01 20:22:4234TEST(RtpTransportTest, SetRtcpParametersCantDisableRtcpMux) {
zstein56162b92017-04-24 23:54:3535 RtpTransport transport(kMuxDisabled);
sprangdb2a9fc2017-08-09 13:42:3236 RtpTransportParameters params;
37 transport.SetParameters(params);
38 params.rtcp.mux = false;
39 EXPECT_FALSE(transport.SetParameters(params).ok());
zstein56162b92017-04-24 23:54:3540}
41
zstein3dcf0e92017-06-01 20:22:4242TEST(RtpTransportTest, SetRtcpParametersEmptyCnameUsesExisting) {
zstein56162b92017-04-24 23:54:3543 static const char kName[] = "name";
44 RtpTransport transport(kMuxDisabled);
sprangdb2a9fc2017-08-09 13:42:3245 RtpTransportParameters params_with_name;
46 params_with_name.rtcp.cname = kName;
47 transport.SetParameters(params_with_name);
48 EXPECT_EQ(transport.GetParameters().rtcp.cname, kName);
zstein56162b92017-04-24 23:54:3549
sprangdb2a9fc2017-08-09 13:42:3250 RtpTransportParameters params_without_name;
51 transport.SetParameters(params_without_name);
52 EXPECT_EQ(transport.GetParameters().rtcp.cname, kName);
53}
54
55TEST(RtpTransportTest, SetRtpTransportKeepAliveNotSupported) {
56 // Tests that we warn users that keep-alive isn't supported yet.
57 // TODO(sprang): Wire up keep-alive and remove this test.
58 RtpTransport transport(kMuxDisabled);
59 RtpTransportParameters params;
60 params.keepalive.timeout_interval_ms = 1;
61 auto result = transport.SetParameters(params);
62 EXPECT_FALSE(result.ok());
63 EXPECT_EQ(RTCErrorType::INVALID_MODIFICATION, result.type());
zstein56162b92017-04-24 23:54:3564}
65
66class SignalObserver : public sigslot::has_slots<> {
67 public:
68 explicit SignalObserver(RtpTransport* transport) {
Zhi Huange830e682018-03-30 17:48:3569 transport_ = transport;
zstein56162b92017-04-24 23:54:3570 transport->SignalReadyToSend.connect(this, &SignalObserver::OnReadyToSend);
Zhi Huang942bc2e2017-11-13 21:26:0771 transport->SignalNetworkRouteChanged.connect(
72 this, &SignalObserver::OnNetworkRouteChanged);
Zhi Huange830e682018-03-30 17:48:3573 if (transport->rtp_packet_transport()) {
74 transport->rtp_packet_transport()->SignalSentPacket.connect(
75 this, &SignalObserver::OnSentPacket);
76 }
77
78 if (transport->rtcp_packet_transport()) {
79 transport->rtcp_packet_transport()->SignalSentPacket.connect(
80 this, &SignalObserver::OnSentPacket);
81 }
zstein56162b92017-04-24 23:54:3582 }
Zhi Huang942bc2e2017-11-13 21:26:0783
zstein3dcf0e92017-06-01 20:22:4284 bool ready() const { return ready_; }
zstein56162b92017-04-24 23:54:3585 void OnReadyToSend(bool ready) { ready_ = ready; }
zstein3dcf0e92017-06-01 20:22:4286
Danil Chapovalov66cadcc2018-06-19 14:47:4387 absl::optional<rtc::NetworkRoute> network_route() { return network_route_; }
88 void OnNetworkRouteChanged(absl::optional<rtc::NetworkRoute> network_route) {
Mirko Bonadei05cf6be2019-01-31 20:38:1289 network_route_ = network_route;
Zhi Huang942bc2e2017-11-13 21:26:0790 }
91
Zhi Huange830e682018-03-30 17:48:3592 void OnSentPacket(rtc::PacketTransportInternal* packet_transport,
93 const rtc::SentPacket& sent_packet) {
94 if (packet_transport == transport_->rtp_packet_transport()) {
95 rtp_transport_sent_count_++;
96 } else {
97 ASSERT_EQ(transport_->rtcp_packet_transport(), packet_transport);
98 rtcp_transport_sent_count_++;
99 }
100 }
101
102 int rtp_transport_sent_count() { return rtp_transport_sent_count_; }
103
104 int rtcp_transport_sent_count() { return rtcp_transport_sent_count_; }
105
zstein3dcf0e92017-06-01 20:22:42106 private:
Zhi Huange830e682018-03-30 17:48:35107 int rtp_transport_sent_count_ = 0;
108 int rtcp_transport_sent_count_ = 0;
109 RtpTransport* transport_ = nullptr;
zstein56162b92017-04-24 23:54:35110 bool ready_ = false;
Danil Chapovalov66cadcc2018-06-19 14:47:43111 absl::optional<rtc::NetworkRoute> network_route_;
zstein56162b92017-04-24 23:54:35112};
113
zstein3dcf0e92017-06-01 20:22:42114TEST(RtpTransportTest, SettingRtcpAndRtpSignalsReady) {
zstein56162b92017-04-24 23:54:35115 RtpTransport transport(kMuxDisabled);
116 SignalObserver observer(&transport);
117 rtc::FakePacketTransport fake_rtcp("fake_rtcp");
118 fake_rtcp.SetWritable(true);
119 rtc::FakePacketTransport fake_rtp("fake_rtp");
120 fake_rtp.SetWritable(true);
121
122 transport.SetRtcpPacketTransport(&fake_rtcp); // rtcp ready
zstein3dcf0e92017-06-01 20:22:42123 EXPECT_FALSE(observer.ready());
zstein56162b92017-04-24 23:54:35124 transport.SetRtpPacketTransport(&fake_rtp); // rtp ready
zstein3dcf0e92017-06-01 20:22:42125 EXPECT_TRUE(observer.ready());
zstein56162b92017-04-24 23:54:35126}
127
zstein3dcf0e92017-06-01 20:22:42128TEST(RtpTransportTest, SettingRtpAndRtcpSignalsReady) {
zstein56162b92017-04-24 23:54:35129 RtpTransport transport(kMuxDisabled);
130 SignalObserver observer(&transport);
131 rtc::FakePacketTransport fake_rtcp("fake_rtcp");
132 fake_rtcp.SetWritable(true);
133 rtc::FakePacketTransport fake_rtp("fake_rtp");
134 fake_rtp.SetWritable(true);
135
136 transport.SetRtpPacketTransport(&fake_rtp); // rtp ready
zstein3dcf0e92017-06-01 20:22:42137 EXPECT_FALSE(observer.ready());
zstein56162b92017-04-24 23:54:35138 transport.SetRtcpPacketTransport(&fake_rtcp); // rtcp ready
zstein3dcf0e92017-06-01 20:22:42139 EXPECT_TRUE(observer.ready());
zstein56162b92017-04-24 23:54:35140}
141
zstein3dcf0e92017-06-01 20:22:42142TEST(RtpTransportTest, SettingRtpWithRtcpMuxEnabledSignalsReady) {
zstein56162b92017-04-24 23:54:35143 RtpTransport transport(kMuxEnabled);
144 SignalObserver observer(&transport);
145 rtc::FakePacketTransport fake_rtp("fake_rtp");
146 fake_rtp.SetWritable(true);
147
148 transport.SetRtpPacketTransport(&fake_rtp); // rtp ready
zstein3dcf0e92017-06-01 20:22:42149 EXPECT_TRUE(observer.ready());
zstein56162b92017-04-24 23:54:35150}
151
zstein3dcf0e92017-06-01 20:22:42152TEST(RtpTransportTest, DisablingRtcpMuxSignalsNotReady) {
zstein56162b92017-04-24 23:54:35153 RtpTransport transport(kMuxEnabled);
154 SignalObserver observer(&transport);
155 rtc::FakePacketTransport fake_rtp("fake_rtp");
156 fake_rtp.SetWritable(true);
157
158 transport.SetRtpPacketTransport(&fake_rtp); // rtp ready
zstein3dcf0e92017-06-01 20:22:42159 EXPECT_TRUE(observer.ready());
zstein56162b92017-04-24 23:54:35160
161 transport.SetRtcpMuxEnabled(false);
zstein3dcf0e92017-06-01 20:22:42162 EXPECT_FALSE(observer.ready());
zstein56162b92017-04-24 23:54:35163}
164
zstein3dcf0e92017-06-01 20:22:42165TEST(RtpTransportTest, EnablingRtcpMuxSignalsReady) {
zstein56162b92017-04-24 23:54:35166 RtpTransport transport(kMuxDisabled);
167 SignalObserver observer(&transport);
168 rtc::FakePacketTransport fake_rtp("fake_rtp");
169 fake_rtp.SetWritable(true);
170
171 transport.SetRtpPacketTransport(&fake_rtp); // rtp ready
zstein3dcf0e92017-06-01 20:22:42172 EXPECT_FALSE(observer.ready());
zstein56162b92017-04-24 23:54:35173
174 transport.SetRtcpMuxEnabled(true);
zstein3dcf0e92017-06-01 20:22:42175 EXPECT_TRUE(observer.ready());
zstein56162b92017-04-24 23:54:35176}
177
Zhi Huang942bc2e2017-11-13 21:26:07178// Tests the SignalNetworkRoute is fired when setting a packet transport.
179TEST(RtpTransportTest, SetRtpTransportWithNetworkRouteChanged) {
180 RtpTransport transport(kMuxDisabled);
181 SignalObserver observer(&transport);
182 rtc::FakePacketTransport fake_rtp("fake_rtp");
183
184 EXPECT_FALSE(observer.network_route());
185
186 rtc::NetworkRoute network_route;
187 // Set a non-null RTP transport with a new network route.
188 network_route.connected = true;
189 network_route.local_network_id = kLocalNetId;
190 network_route.remote_network_id = kRemoteNetId;
191 network_route.last_sent_packet_id = kLastPacketId;
192 network_route.packet_overhead = kTransportOverheadPerPacket;
Danil Chapovalov66cadcc2018-06-19 14:47:43193 fake_rtp.SetNetworkRoute(absl::optional<rtc::NetworkRoute>(network_route));
Zhi Huang942bc2e2017-11-13 21:26:07194 transport.SetRtpPacketTransport(&fake_rtp);
195 ASSERT_TRUE(observer.network_route());
Sebastian Janssonaf2adda2018-12-04 10:16:19196 EXPECT_TRUE(observer.network_route()->connected);
197 EXPECT_EQ(kLocalNetId, observer.network_route()->local_network_id);
198 EXPECT_EQ(kRemoteNetId, observer.network_route()->remote_network_id);
Zhi Huang942bc2e2017-11-13 21:26:07199 EXPECT_EQ(kTransportOverheadPerPacket,
200 observer.network_route()->packet_overhead);
201 EXPECT_EQ(kLastPacketId, observer.network_route()->last_sent_packet_id);
202
203 // Set a null RTP transport.
204 transport.SetRtpPacketTransport(nullptr);
205 EXPECT_FALSE(observer.network_route());
206}
207
208TEST(RtpTransportTest, SetRtcpTransportWithNetworkRouteChanged) {
209 RtpTransport transport(kMuxDisabled);
210 SignalObserver observer(&transport);
211 rtc::FakePacketTransport fake_rtcp("fake_rtcp");
212
213 EXPECT_FALSE(observer.network_route());
214
215 rtc::NetworkRoute network_route;
216 // Set a non-null RTCP transport with a new network route.
217 network_route.connected = true;
218 network_route.local_network_id = kLocalNetId;
219 network_route.remote_network_id = kRemoteNetId;
220 network_route.last_sent_packet_id = kLastPacketId;
221 network_route.packet_overhead = kTransportOverheadPerPacket;
Danil Chapovalov66cadcc2018-06-19 14:47:43222 fake_rtcp.SetNetworkRoute(absl::optional<rtc::NetworkRoute>(network_route));
Zhi Huang942bc2e2017-11-13 21:26:07223 transport.SetRtcpPacketTransport(&fake_rtcp);
224 ASSERT_TRUE(observer.network_route());
Sebastian Janssonaf2adda2018-12-04 10:16:19225 EXPECT_TRUE(observer.network_route()->connected);
226 EXPECT_EQ(kLocalNetId, observer.network_route()->local_network_id);
227 EXPECT_EQ(kRemoteNetId, observer.network_route()->remote_network_id);
Zhi Huang942bc2e2017-11-13 21:26:07228 EXPECT_EQ(kTransportOverheadPerPacket,
229 observer.network_route()->packet_overhead);
230 EXPECT_EQ(kLastPacketId, observer.network_route()->last_sent_packet_id);
231
232 // Set a null RTCP transport.
233 transport.SetRtcpPacketTransport(nullptr);
234 EXPECT_FALSE(observer.network_route());
235}
236
Zhi Huange830e682018-03-30 17:48:35237// Test that RTCP packets are sent over correct transport based on the RTCP-mux
238// status.
239TEST(RtpTransportTest, RtcpPacketSentOverCorrectTransport) {
240 // If the RTCP-mux is not enabled, RTCP packets are expected to be sent over
241 // the RtcpPacketTransport.
242 RtpTransport transport(kMuxDisabled);
243 rtc::FakePacketTransport fake_rtcp("fake_rtcp");
244 rtc::FakePacketTransport fake_rtp("fake_rtp");
245 transport.SetRtcpPacketTransport(&fake_rtcp); // rtcp ready
246 transport.SetRtpPacketTransport(&fake_rtp); // rtp ready
247 SignalObserver observer(&transport);
248
249 fake_rtp.SetDestination(&fake_rtp, true);
250 fake_rtcp.SetDestination(&fake_rtcp, true);
251
252 rtc::CopyOnWriteBuffer packet;
253 EXPECT_TRUE(transport.SendRtcpPacket(&packet, rtc::PacketOptions(), 0));
254 EXPECT_EQ(1, observer.rtcp_transport_sent_count());
255
256 // The RTCP packets are expected to be sent over RtpPacketTransport if
257 // RTCP-mux is enabled.
258 transport.SetRtcpMuxEnabled(true);
259 EXPECT_TRUE(transport.SendRtcpPacket(&packet, rtc::PacketOptions(), 0));
260 EXPECT_EQ(1, observer.rtp_transport_sent_count());
261}
262
zstein3dcf0e92017-06-01 20:22:42263TEST(RtpTransportTest, ChangingReadyToSendStateOnlySignalsWhenChanged) {
zstein56162b92017-04-24 23:54:35264 RtpTransport transport(kMuxEnabled);
Zhi Huang365381f2018-04-13 23:44:34265 TransportObserver observer(&transport);
zstein56162b92017-04-24 23:54:35266 rtc::FakePacketTransport fake_rtp("fake_rtp");
267 fake_rtp.SetWritable(true);
268
269 // State changes, so we should signal.
270 transport.SetRtpPacketTransport(&fake_rtp);
Zhi Huang365381f2018-04-13 23:44:34271 EXPECT_EQ(observer.ready_to_send_signal_count(), 1);
zstein56162b92017-04-24 23:54:35272
273 // State does not change, so we should not signal.
274 transport.SetRtpPacketTransport(&fake_rtp);
Zhi Huang365381f2018-04-13 23:44:34275 EXPECT_EQ(observer.ready_to_send_signal_count(), 1);
zstein56162b92017-04-24 23:54:35276
277 // State does not change, so we should not signal.
278 transport.SetRtcpMuxEnabled(true);
Zhi Huang365381f2018-04-13 23:44:34279 EXPECT_EQ(observer.ready_to_send_signal_count(), 1);
zstein56162b92017-04-24 23:54:35280
281 // State changes, so we should signal.
282 transport.SetRtcpMuxEnabled(false);
Zhi Huang365381f2018-04-13 23:44:34283 EXPECT_EQ(observer.ready_to_send_signal_count(), 2);
zstein3dcf0e92017-06-01 20:22:42284}
285
zstein3dcf0e92017-06-01 20:22:42286// Test that SignalPacketReceived fires with rtcp=true when a RTCP packet is
287// received.
288TEST(RtpTransportTest, SignalDemuxedRtcp) {
289 RtpTransport transport(kMuxDisabled);
zstein3dcf0e92017-06-01 20:22:42290 rtc::FakePacketTransport fake_rtp("fake_rtp");
291 fake_rtp.SetDestination(&fake_rtp, true);
292 transport.SetRtpPacketTransport(&fake_rtp);
Zhi Huang365381f2018-04-13 23:44:34293 TransportObserver observer(&transport);
zstein3dcf0e92017-06-01 20:22:42294
295 // An rtcp packet.
Piotr (Peter) Slatala042bb002019-01-30 22:57:12296 const unsigned char data[] = {0x80, 73, 0, 0};
zstein3dcf0e92017-06-01 20:22:42297 const int len = 4;
298 const rtc::PacketOptions options;
299 const int flags = 0;
Piotr (Peter) Slatala042bb002019-01-30 22:57:12300 fake_rtp.SendPacket(reinterpret_cast<const char*>(data), len, options, flags);
zstein3dcf0e92017-06-01 20:22:42301 EXPECT_EQ(0, observer.rtp_count());
302 EXPECT_EQ(1, observer.rtcp_count());
303}
304
305static const unsigned char kRtpData[] = {0x80, 0x11, 0, 0, 0, 0,
306 0, 0, 0, 0, 0, 0};
307static const int kRtpLen = 12;
308
309// Test that SignalPacketReceived fires with rtcp=false when a RTP packet with a
310// handled payload type is received.
311TEST(RtpTransportTest, SignalHandledRtpPayloadType) {
312 RtpTransport transport(kMuxDisabled);
zstein3dcf0e92017-06-01 20:22:42313 rtc::FakePacketTransport fake_rtp("fake_rtp");
314 fake_rtp.SetDestination(&fake_rtp, true);
315 transport.SetRtpPacketTransport(&fake_rtp);
Zhi Huang365381f2018-04-13 23:44:34316 TransportObserver observer(&transport);
317 RtpDemuxerCriteria demuxer_criteria;
318 // Add a handled payload type.
319 demuxer_criteria.payload_types = {0x11};
320 transport.RegisterRtpDemuxerSink(demuxer_criteria, &observer);
zstein3dcf0e92017-06-01 20:22:42321
322 // An rtp packet.
323 const rtc::PacketOptions options;
324 const int flags = 0;
325 rtc::Buffer rtp_data(kRtpData, kRtpLen);
326 fake_rtp.SendPacket(rtp_data.data<char>(), kRtpLen, options, flags);
327 EXPECT_EQ(1, observer.rtp_count());
328 EXPECT_EQ(0, observer.rtcp_count());
Zhi Huang365381f2018-04-13 23:44:34329 // Remove the sink before destroying the transport.
330 transport.UnregisterRtpDemuxerSink(&observer);
331}
332
333// Test that SignalPacketReceived does not fire when a RTP packet with an
334// unhandled payload type is received.
335TEST(RtpTransportTest, DontSignalUnhandledRtpPayloadType) {
336 RtpTransport transport(kMuxDisabled);
337 rtc::FakePacketTransport fake_rtp("fake_rtp");
338 fake_rtp.SetDestination(&fake_rtp, true);
339 transport.SetRtpPacketTransport(&fake_rtp);
340 TransportObserver observer(&transport);
341 RtpDemuxerCriteria demuxer_criteria;
342 // Add an unhandled payload type.
343 demuxer_criteria.payload_types = {0x12};
344 transport.RegisterRtpDemuxerSink(demuxer_criteria, &observer);
345
346 const rtc::PacketOptions options;
347 const int flags = 0;
348 rtc::Buffer rtp_data(kRtpData, kRtpLen);
349 fake_rtp.SendPacket(rtp_data.data<char>(), kRtpLen, options, flags);
350 EXPECT_EQ(0, observer.rtp_count());
351 EXPECT_EQ(0, observer.rtcp_count());
352 // Remove the sink before destroying the transport.
353 transport.UnregisterRtpDemuxerSink(&observer);
zstein3dcf0e92017-06-01 20:22:42354}
355
zstein56162b92017-04-24 23:54:35356} // namespace webrtc