blob: 97bc408c20e0d41279166ce9a12d2c12c2a583b5 [file] [log] [blame]
zstein56162b92017-04-24 16:54:35 -07001/*
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 16:47:49 +010011#include <cstdint>
12#include <set>
zstein56162b92017-04-24 16:54:35 -070013#include <string>
Mirko Bonadeic61ce0d2017-11-21 17:04:20 +010014#include <utility>
zstein56162b92017-04-24 16:54:35 -070015
Yves Gerey3e707812018-11-28 16:47:49 +010016#include "api/rtp_headers.h"
17#include "api/rtpparameters.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020018#include "p2p/base/fakepackettransport.h"
19#include "pc/rtptransport.h"
20#include "pc/rtptransporttestutil.h"
Yves Gerey3e707812018-11-28 16:47:49 +010021#include "rtc_base/buffer.h"
22#include "rtc_base/third_party/sigslot/sigslot.h"
23#include "test/gtest.h"
zstein56162b92017-04-24 16:54:35 -070024
25namespace webrtc {
26
zstein56162b92017-04-24 16:54:35 -070027constexpr bool kMuxDisabled = false;
28constexpr bool kMuxEnabled = true;
Zhi Huang942bc2e2017-11-13 13:26:07 -080029constexpr uint16_t kLocalNetId = 1;
30constexpr uint16_t kRemoteNetId = 2;
31constexpr int kLastPacketId = 100;
32constexpr int kTransportOverheadPerPacket = 28; // Ipv4(20) + UDP(8).
zstein56162b92017-04-24 16:54:35 -070033
zstein3dcf0e92017-06-01 13:22:42 -070034TEST(RtpTransportTest, SetRtcpParametersCantDisableRtcpMux) {
zstein56162b92017-04-24 16:54:35 -070035 RtpTransport transport(kMuxDisabled);
sprangdb2a9fc2017-08-09 06:42:32 -070036 RtpTransportParameters params;
37 transport.SetParameters(params);
38 params.rtcp.mux = false;
39 EXPECT_FALSE(transport.SetParameters(params).ok());
zstein56162b92017-04-24 16:54:35 -070040}
41
zstein3dcf0e92017-06-01 13:22:42 -070042TEST(RtpTransportTest, SetRtcpParametersEmptyCnameUsesExisting) {
zstein56162b92017-04-24 16:54:35 -070043 static const char kName[] = "name";
44 RtpTransport transport(kMuxDisabled);
sprangdb2a9fc2017-08-09 06:42:32 -070045 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 16:54:35 -070049
sprangdb2a9fc2017-08-09 06:42:32 -070050 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 16:54:35 -070064}
65
66class SignalObserver : public sigslot::has_slots<> {
67 public:
68 explicit SignalObserver(RtpTransport* transport) {
Zhi Huange830e682018-03-30 10:48:35 -070069 transport_ = transport;
zstein56162b92017-04-24 16:54:35 -070070 transport->SignalReadyToSend.connect(this, &SignalObserver::OnReadyToSend);
Zhi Huang942bc2e2017-11-13 13:26:07 -080071 transport->SignalNetworkRouteChanged.connect(
72 this, &SignalObserver::OnNetworkRouteChanged);
Zhi Huange830e682018-03-30 10:48:35 -070073 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 16:54:35 -070082 }
Zhi Huang942bc2e2017-11-13 13:26:07 -080083
zstein3dcf0e92017-06-01 13:22:42 -070084 bool ready() const { return ready_; }
zstein56162b92017-04-24 16:54:35 -070085 void OnReadyToSend(bool ready) { ready_ = ready; }
zstein3dcf0e92017-06-01 13:22:42 -070086
Danil Chapovalov66cadcc2018-06-19 16:47:43 +020087 absl::optional<rtc::NetworkRoute> network_route() { return network_route_; }
88 void OnNetworkRouteChanged(absl::optional<rtc::NetworkRoute> network_route) {
Mirko Bonadeic61ce0d2017-11-21 17:04:20 +010089 network_route_ = std::move(network_route);
Zhi Huang942bc2e2017-11-13 13:26:07 -080090 }
91
Zhi Huange830e682018-03-30 10:48:35 -070092 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 13:22:42 -0700106 private:
Zhi Huange830e682018-03-30 10:48:35 -0700107 int rtp_transport_sent_count_ = 0;
108 int rtcp_transport_sent_count_ = 0;
109 RtpTransport* transport_ = nullptr;
zstein56162b92017-04-24 16:54:35 -0700110 bool ready_ = false;
Danil Chapovalov66cadcc2018-06-19 16:47:43 +0200111 absl::optional<rtc::NetworkRoute> network_route_;
zstein56162b92017-04-24 16:54:35 -0700112};
113
zstein3dcf0e92017-06-01 13:22:42 -0700114TEST(RtpTransportTest, SettingRtcpAndRtpSignalsReady) {
zstein56162b92017-04-24 16:54:35 -0700115 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 13:22:42 -0700123 EXPECT_FALSE(observer.ready());
zstein56162b92017-04-24 16:54:35 -0700124 transport.SetRtpPacketTransport(&fake_rtp); // rtp ready
zstein3dcf0e92017-06-01 13:22:42 -0700125 EXPECT_TRUE(observer.ready());
zstein56162b92017-04-24 16:54:35 -0700126}
127
zstein3dcf0e92017-06-01 13:22:42 -0700128TEST(RtpTransportTest, SettingRtpAndRtcpSignalsReady) {
zstein56162b92017-04-24 16:54:35 -0700129 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 13:22:42 -0700137 EXPECT_FALSE(observer.ready());
zstein56162b92017-04-24 16:54:35 -0700138 transport.SetRtcpPacketTransport(&fake_rtcp); // rtcp ready
zstein3dcf0e92017-06-01 13:22:42 -0700139 EXPECT_TRUE(observer.ready());
zstein56162b92017-04-24 16:54:35 -0700140}
141
zstein3dcf0e92017-06-01 13:22:42 -0700142TEST(RtpTransportTest, SettingRtpWithRtcpMuxEnabledSignalsReady) {
zstein56162b92017-04-24 16:54:35 -0700143 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 13:22:42 -0700149 EXPECT_TRUE(observer.ready());
zstein56162b92017-04-24 16:54:35 -0700150}
151
zstein3dcf0e92017-06-01 13:22:42 -0700152TEST(RtpTransportTest, DisablingRtcpMuxSignalsNotReady) {
zstein56162b92017-04-24 16:54:35 -0700153 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 13:22:42 -0700159 EXPECT_TRUE(observer.ready());
zstein56162b92017-04-24 16:54:35 -0700160
161 transport.SetRtcpMuxEnabled(false);
zstein3dcf0e92017-06-01 13:22:42 -0700162 EXPECT_FALSE(observer.ready());
zstein56162b92017-04-24 16:54:35 -0700163}
164
zstein3dcf0e92017-06-01 13:22:42 -0700165TEST(RtpTransportTest, EnablingRtcpMuxSignalsReady) {
zstein56162b92017-04-24 16:54:35 -0700166 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 13:22:42 -0700172 EXPECT_FALSE(observer.ready());
zstein56162b92017-04-24 16:54:35 -0700173
174 transport.SetRtcpMuxEnabled(true);
zstein3dcf0e92017-06-01 13:22:42 -0700175 EXPECT_TRUE(observer.ready());
zstein56162b92017-04-24 16:54:35 -0700176}
177
Zhi Huang942bc2e2017-11-13 13:26:07 -0800178// 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 16:47:43 +0200193 fake_rtp.SetNetworkRoute(absl::optional<rtc::NetworkRoute>(network_route));
Zhi Huang942bc2e2017-11-13 13:26:07 -0800194 transport.SetRtpPacketTransport(&fake_rtp);
195 ASSERT_TRUE(observer.network_route());
196 EXPECT_EQ(network_route, *(observer.network_route()));
197 EXPECT_EQ(kTransportOverheadPerPacket,
198 observer.network_route()->packet_overhead);
199 EXPECT_EQ(kLastPacketId, observer.network_route()->last_sent_packet_id);
200
201 // Set a null RTP transport.
202 transport.SetRtpPacketTransport(nullptr);
203 EXPECT_FALSE(observer.network_route());
204}
205
206TEST(RtpTransportTest, SetRtcpTransportWithNetworkRouteChanged) {
207 RtpTransport transport(kMuxDisabled);
208 SignalObserver observer(&transport);
209 rtc::FakePacketTransport fake_rtcp("fake_rtcp");
210
211 EXPECT_FALSE(observer.network_route());
212
213 rtc::NetworkRoute network_route;
214 // Set a non-null RTCP transport with a new network route.
215 network_route.connected = true;
216 network_route.local_network_id = kLocalNetId;
217 network_route.remote_network_id = kRemoteNetId;
218 network_route.last_sent_packet_id = kLastPacketId;
219 network_route.packet_overhead = kTransportOverheadPerPacket;
Danil Chapovalov66cadcc2018-06-19 16:47:43 +0200220 fake_rtcp.SetNetworkRoute(absl::optional<rtc::NetworkRoute>(network_route));
Zhi Huang942bc2e2017-11-13 13:26:07 -0800221 transport.SetRtcpPacketTransport(&fake_rtcp);
222 ASSERT_TRUE(observer.network_route());
223 EXPECT_EQ(network_route, *(observer.network_route()));
224 EXPECT_EQ(kTransportOverheadPerPacket,
225 observer.network_route()->packet_overhead);
226 EXPECT_EQ(kLastPacketId, observer.network_route()->last_sent_packet_id);
227
228 // Set a null RTCP transport.
229 transport.SetRtcpPacketTransport(nullptr);
230 EXPECT_FALSE(observer.network_route());
231}
232
Zhi Huange830e682018-03-30 10:48:35 -0700233// Test that RTCP packets are sent over correct transport based on the RTCP-mux
234// status.
235TEST(RtpTransportTest, RtcpPacketSentOverCorrectTransport) {
236 // If the RTCP-mux is not enabled, RTCP packets are expected to be sent over
237 // the RtcpPacketTransport.
238 RtpTransport transport(kMuxDisabled);
239 rtc::FakePacketTransport fake_rtcp("fake_rtcp");
240 rtc::FakePacketTransport fake_rtp("fake_rtp");
241 transport.SetRtcpPacketTransport(&fake_rtcp); // rtcp ready
242 transport.SetRtpPacketTransport(&fake_rtp); // rtp ready
243 SignalObserver observer(&transport);
244
245 fake_rtp.SetDestination(&fake_rtp, true);
246 fake_rtcp.SetDestination(&fake_rtcp, true);
247
248 rtc::CopyOnWriteBuffer packet;
249 EXPECT_TRUE(transport.SendRtcpPacket(&packet, rtc::PacketOptions(), 0));
250 EXPECT_EQ(1, observer.rtcp_transport_sent_count());
251
252 // The RTCP packets are expected to be sent over RtpPacketTransport if
253 // RTCP-mux is enabled.
254 transport.SetRtcpMuxEnabled(true);
255 EXPECT_TRUE(transport.SendRtcpPacket(&packet, rtc::PacketOptions(), 0));
256 EXPECT_EQ(1, observer.rtp_transport_sent_count());
257}
258
zstein3dcf0e92017-06-01 13:22:42 -0700259TEST(RtpTransportTest, ChangingReadyToSendStateOnlySignalsWhenChanged) {
zstein56162b92017-04-24 16:54:35 -0700260 RtpTransport transport(kMuxEnabled);
Zhi Huang365381f2018-04-13 16:44:34 -0700261 TransportObserver observer(&transport);
zstein56162b92017-04-24 16:54:35 -0700262 rtc::FakePacketTransport fake_rtp("fake_rtp");
263 fake_rtp.SetWritable(true);
264
265 // State changes, so we should signal.
266 transport.SetRtpPacketTransport(&fake_rtp);
Zhi Huang365381f2018-04-13 16:44:34 -0700267 EXPECT_EQ(observer.ready_to_send_signal_count(), 1);
zstein56162b92017-04-24 16:54:35 -0700268
269 // State does not change, so we should not signal.
270 transport.SetRtpPacketTransport(&fake_rtp);
Zhi Huang365381f2018-04-13 16:44:34 -0700271 EXPECT_EQ(observer.ready_to_send_signal_count(), 1);
zstein56162b92017-04-24 16:54:35 -0700272
273 // State does not change, so we should not signal.
274 transport.SetRtcpMuxEnabled(true);
Zhi Huang365381f2018-04-13 16:44:34 -0700275 EXPECT_EQ(observer.ready_to_send_signal_count(), 1);
zstein56162b92017-04-24 16:54:35 -0700276
277 // State changes, so we should signal.
278 transport.SetRtcpMuxEnabled(false);
Zhi Huang365381f2018-04-13 16:44:34 -0700279 EXPECT_EQ(observer.ready_to_send_signal_count(), 2);
zstein3dcf0e92017-06-01 13:22:42 -0700280}
281
zstein3dcf0e92017-06-01 13:22:42 -0700282// Test that SignalPacketReceived fires with rtcp=true when a RTCP packet is
283// received.
284TEST(RtpTransportTest, SignalDemuxedRtcp) {
285 RtpTransport transport(kMuxDisabled);
zstein3dcf0e92017-06-01 13:22:42 -0700286 rtc::FakePacketTransport fake_rtp("fake_rtp");
287 fake_rtp.SetDestination(&fake_rtp, true);
288 transport.SetRtpPacketTransport(&fake_rtp);
Zhi Huang365381f2018-04-13 16:44:34 -0700289 TransportObserver observer(&transport);
zstein3dcf0e92017-06-01 13:22:42 -0700290
291 // An rtcp packet.
292 const char data[] = {0, 73, 0, 0};
293 const int len = 4;
294 const rtc::PacketOptions options;
295 const int flags = 0;
296 fake_rtp.SendPacket(data, len, options, flags);
297 EXPECT_EQ(0, observer.rtp_count());
298 EXPECT_EQ(1, observer.rtcp_count());
299}
300
301static const unsigned char kRtpData[] = {0x80, 0x11, 0, 0, 0, 0,
302 0, 0, 0, 0, 0, 0};
303static const int kRtpLen = 12;
304
305// Test that SignalPacketReceived fires with rtcp=false when a RTP packet with a
306// handled payload type is received.
307TEST(RtpTransportTest, SignalHandledRtpPayloadType) {
308 RtpTransport transport(kMuxDisabled);
zstein3dcf0e92017-06-01 13:22:42 -0700309 rtc::FakePacketTransport fake_rtp("fake_rtp");
310 fake_rtp.SetDestination(&fake_rtp, true);
311 transport.SetRtpPacketTransport(&fake_rtp);
Zhi Huang365381f2018-04-13 16:44:34 -0700312 TransportObserver observer(&transport);
313 RtpDemuxerCriteria demuxer_criteria;
314 // Add a handled payload type.
315 demuxer_criteria.payload_types = {0x11};
316 transport.RegisterRtpDemuxerSink(demuxer_criteria, &observer);
zstein3dcf0e92017-06-01 13:22:42 -0700317
318 // An rtp packet.
319 const rtc::PacketOptions options;
320 const int flags = 0;
321 rtc::Buffer rtp_data(kRtpData, kRtpLen);
322 fake_rtp.SendPacket(rtp_data.data<char>(), kRtpLen, options, flags);
323 EXPECT_EQ(1, observer.rtp_count());
324 EXPECT_EQ(0, observer.rtcp_count());
Zhi Huang365381f2018-04-13 16:44:34 -0700325 // Remove the sink before destroying the transport.
326 transport.UnregisterRtpDemuxerSink(&observer);
327}
328
329// Test that SignalPacketReceived does not fire when a RTP packet with an
330// unhandled payload type is received.
331TEST(RtpTransportTest, DontSignalUnhandledRtpPayloadType) {
332 RtpTransport transport(kMuxDisabled);
333 rtc::FakePacketTransport fake_rtp("fake_rtp");
334 fake_rtp.SetDestination(&fake_rtp, true);
335 transport.SetRtpPacketTransport(&fake_rtp);
336 TransportObserver observer(&transport);
337 RtpDemuxerCriteria demuxer_criteria;
338 // Add an unhandled payload type.
339 demuxer_criteria.payload_types = {0x12};
340 transport.RegisterRtpDemuxerSink(demuxer_criteria, &observer);
341
342 const rtc::PacketOptions options;
343 const int flags = 0;
344 rtc::Buffer rtp_data(kRtpData, kRtpLen);
345 fake_rtp.SendPacket(rtp_data.data<char>(), kRtpLen, options, flags);
346 EXPECT_EQ(0, observer.rtp_count());
347 EXPECT_EQ(0, observer.rtcp_count());
348 // Remove the sink before destroying the transport.
349 transport.UnregisterRtpDemuxerSink(&observer);
zstein3dcf0e92017-06-01 13:22:42 -0700350}
351
zstein56162b92017-04-24 16:54:35 -0700352} // namespace webrtc