blob: 042594292529873a900ad0d2cdeb2e5d63b7827e [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
11#include <string>
Mirko Bonadeic61ce0d2017-11-21 17:04:20 +010012#include <utility>
zstein56162b92017-04-24 16:54:35 -070013
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020014#include "p2p/base/fakepackettransport.h"
15#include "pc/rtptransport.h"
16#include "pc/rtptransporttestutil.h"
17#include "rtc_base/gunit.h"
zstein56162b92017-04-24 16:54:35 -070018
19namespace webrtc {
20
zstein56162b92017-04-24 16:54:35 -070021constexpr bool kMuxDisabled = false;
22constexpr bool kMuxEnabled = true;
Zhi Huang942bc2e2017-11-13 13:26:07 -080023constexpr uint16_t kLocalNetId = 1;
24constexpr uint16_t kRemoteNetId = 2;
25constexpr int kLastPacketId = 100;
26constexpr int kTransportOverheadPerPacket = 28; // Ipv4(20) + UDP(8).
zstein56162b92017-04-24 16:54:35 -070027
zstein3dcf0e92017-06-01 13:22:42 -070028TEST(RtpTransportTest, SetRtcpParametersCantDisableRtcpMux) {
zstein56162b92017-04-24 16:54:35 -070029 RtpTransport transport(kMuxDisabled);
sprangdb2a9fc2017-08-09 06:42:32 -070030 RtpTransportParameters params;
31 transport.SetParameters(params);
32 params.rtcp.mux = false;
33 EXPECT_FALSE(transport.SetParameters(params).ok());
zstein56162b92017-04-24 16:54:35 -070034}
35
zstein3dcf0e92017-06-01 13:22:42 -070036TEST(RtpTransportTest, SetRtcpParametersEmptyCnameUsesExisting) {
zstein56162b92017-04-24 16:54:35 -070037 static const char kName[] = "name";
38 RtpTransport transport(kMuxDisabled);
sprangdb2a9fc2017-08-09 06:42:32 -070039 RtpTransportParameters params_with_name;
40 params_with_name.rtcp.cname = kName;
41 transport.SetParameters(params_with_name);
42 EXPECT_EQ(transport.GetParameters().rtcp.cname, kName);
zstein56162b92017-04-24 16:54:35 -070043
sprangdb2a9fc2017-08-09 06:42:32 -070044 RtpTransportParameters params_without_name;
45 transport.SetParameters(params_without_name);
46 EXPECT_EQ(transport.GetParameters().rtcp.cname, kName);
47}
48
49TEST(RtpTransportTest, SetRtpTransportKeepAliveNotSupported) {
50 // Tests that we warn users that keep-alive isn't supported yet.
51 // TODO(sprang): Wire up keep-alive and remove this test.
52 RtpTransport transport(kMuxDisabled);
53 RtpTransportParameters params;
54 params.keepalive.timeout_interval_ms = 1;
55 auto result = transport.SetParameters(params);
56 EXPECT_FALSE(result.ok());
57 EXPECT_EQ(RTCErrorType::INVALID_MODIFICATION, result.type());
zstein56162b92017-04-24 16:54:35 -070058}
59
60class SignalObserver : public sigslot::has_slots<> {
61 public:
62 explicit SignalObserver(RtpTransport* transport) {
Zhi Huange830e682018-03-30 10:48:35 -070063 transport_ = transport;
zstein56162b92017-04-24 16:54:35 -070064 transport->SignalReadyToSend.connect(this, &SignalObserver::OnReadyToSend);
Zhi Huang942bc2e2017-11-13 13:26:07 -080065 transport->SignalNetworkRouteChanged.connect(
66 this, &SignalObserver::OnNetworkRouteChanged);
Zhi Huange830e682018-03-30 10:48:35 -070067 if (transport->rtp_packet_transport()) {
68 transport->rtp_packet_transport()->SignalSentPacket.connect(
69 this, &SignalObserver::OnSentPacket);
70 }
71
72 if (transport->rtcp_packet_transport()) {
73 transport->rtcp_packet_transport()->SignalSentPacket.connect(
74 this, &SignalObserver::OnSentPacket);
75 }
zstein56162b92017-04-24 16:54:35 -070076 }
Zhi Huang942bc2e2017-11-13 13:26:07 -080077
zstein3dcf0e92017-06-01 13:22:42 -070078 bool ready() const { return ready_; }
zstein56162b92017-04-24 16:54:35 -070079 void OnReadyToSend(bool ready) { ready_ = ready; }
zstein3dcf0e92017-06-01 13:22:42 -070080
Zhi Huang942bc2e2017-11-13 13:26:07 -080081 rtc::Optional<rtc::NetworkRoute> network_route() { return network_route_; }
82 void OnNetworkRouteChanged(rtc::Optional<rtc::NetworkRoute> network_route) {
Mirko Bonadeic61ce0d2017-11-21 17:04:20 +010083 network_route_ = std::move(network_route);
Zhi Huang942bc2e2017-11-13 13:26:07 -080084 }
85
Zhi Huange830e682018-03-30 10:48:35 -070086 void OnSentPacket(rtc::PacketTransportInternal* packet_transport,
87 const rtc::SentPacket& sent_packet) {
88 if (packet_transport == transport_->rtp_packet_transport()) {
89 rtp_transport_sent_count_++;
90 } else {
91 ASSERT_EQ(transport_->rtcp_packet_transport(), packet_transport);
92 rtcp_transport_sent_count_++;
93 }
94 }
95
96 int rtp_transport_sent_count() { return rtp_transport_sent_count_; }
97
98 int rtcp_transport_sent_count() { return rtcp_transport_sent_count_; }
99
zstein3dcf0e92017-06-01 13:22:42 -0700100 private:
Zhi Huange830e682018-03-30 10:48:35 -0700101 int rtp_transport_sent_count_ = 0;
102 int rtcp_transport_sent_count_ = 0;
103 RtpTransport* transport_ = nullptr;
zstein56162b92017-04-24 16:54:35 -0700104 bool ready_ = false;
Zhi Huang942bc2e2017-11-13 13:26:07 -0800105 rtc::Optional<rtc::NetworkRoute> network_route_;
zstein56162b92017-04-24 16:54:35 -0700106};
107
zstein3dcf0e92017-06-01 13:22:42 -0700108TEST(RtpTransportTest, SettingRtcpAndRtpSignalsReady) {
zstein56162b92017-04-24 16:54:35 -0700109 RtpTransport transport(kMuxDisabled);
110 SignalObserver observer(&transport);
111 rtc::FakePacketTransport fake_rtcp("fake_rtcp");
112 fake_rtcp.SetWritable(true);
113 rtc::FakePacketTransport fake_rtp("fake_rtp");
114 fake_rtp.SetWritable(true);
115
116 transport.SetRtcpPacketTransport(&fake_rtcp); // rtcp ready
zstein3dcf0e92017-06-01 13:22:42 -0700117 EXPECT_FALSE(observer.ready());
zstein56162b92017-04-24 16:54:35 -0700118 transport.SetRtpPacketTransport(&fake_rtp); // rtp ready
zstein3dcf0e92017-06-01 13:22:42 -0700119 EXPECT_TRUE(observer.ready());
zstein56162b92017-04-24 16:54:35 -0700120}
121
zstein3dcf0e92017-06-01 13:22:42 -0700122TEST(RtpTransportTest, SettingRtpAndRtcpSignalsReady) {
zstein56162b92017-04-24 16:54:35 -0700123 RtpTransport transport(kMuxDisabled);
124 SignalObserver observer(&transport);
125 rtc::FakePacketTransport fake_rtcp("fake_rtcp");
126 fake_rtcp.SetWritable(true);
127 rtc::FakePacketTransport fake_rtp("fake_rtp");
128 fake_rtp.SetWritable(true);
129
130 transport.SetRtpPacketTransport(&fake_rtp); // rtp ready
zstein3dcf0e92017-06-01 13:22:42 -0700131 EXPECT_FALSE(observer.ready());
zstein56162b92017-04-24 16:54:35 -0700132 transport.SetRtcpPacketTransport(&fake_rtcp); // rtcp ready
zstein3dcf0e92017-06-01 13:22:42 -0700133 EXPECT_TRUE(observer.ready());
zstein56162b92017-04-24 16:54:35 -0700134}
135
zstein3dcf0e92017-06-01 13:22:42 -0700136TEST(RtpTransportTest, SettingRtpWithRtcpMuxEnabledSignalsReady) {
zstein56162b92017-04-24 16:54:35 -0700137 RtpTransport transport(kMuxEnabled);
138 SignalObserver observer(&transport);
139 rtc::FakePacketTransport fake_rtp("fake_rtp");
140 fake_rtp.SetWritable(true);
141
142 transport.SetRtpPacketTransport(&fake_rtp); // rtp ready
zstein3dcf0e92017-06-01 13:22:42 -0700143 EXPECT_TRUE(observer.ready());
zstein56162b92017-04-24 16:54:35 -0700144}
145
zstein3dcf0e92017-06-01 13:22:42 -0700146TEST(RtpTransportTest, DisablingRtcpMuxSignalsNotReady) {
zstein56162b92017-04-24 16:54:35 -0700147 RtpTransport transport(kMuxEnabled);
148 SignalObserver observer(&transport);
149 rtc::FakePacketTransport fake_rtp("fake_rtp");
150 fake_rtp.SetWritable(true);
151
152 transport.SetRtpPacketTransport(&fake_rtp); // rtp ready
zstein3dcf0e92017-06-01 13:22:42 -0700153 EXPECT_TRUE(observer.ready());
zstein56162b92017-04-24 16:54:35 -0700154
155 transport.SetRtcpMuxEnabled(false);
zstein3dcf0e92017-06-01 13:22:42 -0700156 EXPECT_FALSE(observer.ready());
zstein56162b92017-04-24 16:54:35 -0700157}
158
zstein3dcf0e92017-06-01 13:22:42 -0700159TEST(RtpTransportTest, EnablingRtcpMuxSignalsReady) {
zstein56162b92017-04-24 16:54:35 -0700160 RtpTransport transport(kMuxDisabled);
161 SignalObserver observer(&transport);
162 rtc::FakePacketTransport fake_rtp("fake_rtp");
163 fake_rtp.SetWritable(true);
164
165 transport.SetRtpPacketTransport(&fake_rtp); // rtp ready
zstein3dcf0e92017-06-01 13:22:42 -0700166 EXPECT_FALSE(observer.ready());
zstein56162b92017-04-24 16:54:35 -0700167
168 transport.SetRtcpMuxEnabled(true);
zstein3dcf0e92017-06-01 13:22:42 -0700169 EXPECT_TRUE(observer.ready());
zstein56162b92017-04-24 16:54:35 -0700170}
171
Zhi Huang942bc2e2017-11-13 13:26:07 -0800172// Tests the SignalNetworkRoute is fired when setting a packet transport.
173TEST(RtpTransportTest, SetRtpTransportWithNetworkRouteChanged) {
174 RtpTransport transport(kMuxDisabled);
175 SignalObserver observer(&transport);
176 rtc::FakePacketTransport fake_rtp("fake_rtp");
177
178 EXPECT_FALSE(observer.network_route());
179
180 rtc::NetworkRoute network_route;
181 // Set a non-null RTP transport with a new network route.
182 network_route.connected = true;
183 network_route.local_network_id = kLocalNetId;
184 network_route.remote_network_id = kRemoteNetId;
185 network_route.last_sent_packet_id = kLastPacketId;
186 network_route.packet_overhead = kTransportOverheadPerPacket;
187 fake_rtp.SetNetworkRoute(rtc::Optional<rtc::NetworkRoute>(network_route));
188 transport.SetRtpPacketTransport(&fake_rtp);
189 ASSERT_TRUE(observer.network_route());
190 EXPECT_EQ(network_route, *(observer.network_route()));
191 EXPECT_EQ(kTransportOverheadPerPacket,
192 observer.network_route()->packet_overhead);
193 EXPECT_EQ(kLastPacketId, observer.network_route()->last_sent_packet_id);
194
195 // Set a null RTP transport.
196 transport.SetRtpPacketTransport(nullptr);
197 EXPECT_FALSE(observer.network_route());
198}
199
200TEST(RtpTransportTest, SetRtcpTransportWithNetworkRouteChanged) {
201 RtpTransport transport(kMuxDisabled);
202 SignalObserver observer(&transport);
203 rtc::FakePacketTransport fake_rtcp("fake_rtcp");
204
205 EXPECT_FALSE(observer.network_route());
206
207 rtc::NetworkRoute network_route;
208 // Set a non-null RTCP transport with a new network route.
209 network_route.connected = true;
210 network_route.local_network_id = kLocalNetId;
211 network_route.remote_network_id = kRemoteNetId;
212 network_route.last_sent_packet_id = kLastPacketId;
213 network_route.packet_overhead = kTransportOverheadPerPacket;
214 fake_rtcp.SetNetworkRoute(rtc::Optional<rtc::NetworkRoute>(network_route));
215 transport.SetRtcpPacketTransport(&fake_rtcp);
216 ASSERT_TRUE(observer.network_route());
217 EXPECT_EQ(network_route, *(observer.network_route()));
218 EXPECT_EQ(kTransportOverheadPerPacket,
219 observer.network_route()->packet_overhead);
220 EXPECT_EQ(kLastPacketId, observer.network_route()->last_sent_packet_id);
221
222 // Set a null RTCP transport.
223 transport.SetRtcpPacketTransport(nullptr);
224 EXPECT_FALSE(observer.network_route());
225}
226
Zhi Huange830e682018-03-30 10:48:35 -0700227// Test that RTCP packets are sent over correct transport based on the RTCP-mux
228// status.
229TEST(RtpTransportTest, RtcpPacketSentOverCorrectTransport) {
230 // If the RTCP-mux is not enabled, RTCP packets are expected to be sent over
231 // the RtcpPacketTransport.
232 RtpTransport transport(kMuxDisabled);
233 rtc::FakePacketTransport fake_rtcp("fake_rtcp");
234 rtc::FakePacketTransport fake_rtp("fake_rtp");
235 transport.SetRtcpPacketTransport(&fake_rtcp); // rtcp ready
236 transport.SetRtpPacketTransport(&fake_rtp); // rtp ready
237 SignalObserver observer(&transport);
238
239 fake_rtp.SetDestination(&fake_rtp, true);
240 fake_rtcp.SetDestination(&fake_rtcp, true);
241
242 rtc::CopyOnWriteBuffer packet;
243 EXPECT_TRUE(transport.SendRtcpPacket(&packet, rtc::PacketOptions(), 0));
244 EXPECT_EQ(1, observer.rtcp_transport_sent_count());
245
246 // The RTCP packets are expected to be sent over RtpPacketTransport if
247 // RTCP-mux is enabled.
248 transport.SetRtcpMuxEnabled(true);
249 EXPECT_TRUE(transport.SendRtcpPacket(&packet, rtc::PacketOptions(), 0));
250 EXPECT_EQ(1, observer.rtp_transport_sent_count());
251}
252
Zhi Huang95e7dbb2018-03-29 00:08:03 +0000253class SignalCounter : public sigslot::has_slots<> {
254 public:
255 explicit SignalCounter(RtpTransport* transport) {
256 transport->SignalReadyToSend.connect(this, &SignalCounter::OnReadyToSend);
257 }
258 int count() const { return count_; }
259 void OnReadyToSend(bool ready) { ++count_; }
260
261 private:
262 int count_ = 0;
263};
264
zstein3dcf0e92017-06-01 13:22:42 -0700265TEST(RtpTransportTest, ChangingReadyToSendStateOnlySignalsWhenChanged) {
zstein56162b92017-04-24 16:54:35 -0700266 RtpTransport transport(kMuxEnabled);
Zhi Huang95e7dbb2018-03-29 00:08:03 +0000267 SignalCounter observer(&transport);
zstein56162b92017-04-24 16:54:35 -0700268 rtc::FakePacketTransport fake_rtp("fake_rtp");
269 fake_rtp.SetWritable(true);
270
271 // State changes, so we should signal.
272 transport.SetRtpPacketTransport(&fake_rtp);
Zhi Huang95e7dbb2018-03-29 00:08:03 +0000273 EXPECT_EQ(observer.count(), 1);
zstein56162b92017-04-24 16:54:35 -0700274
275 // State does not change, so we should not signal.
276 transport.SetRtpPacketTransport(&fake_rtp);
Zhi Huang95e7dbb2018-03-29 00:08:03 +0000277 EXPECT_EQ(observer.count(), 1);
zstein56162b92017-04-24 16:54:35 -0700278
279 // State does not change, so we should not signal.
280 transport.SetRtcpMuxEnabled(true);
Zhi Huang95e7dbb2018-03-29 00:08:03 +0000281 EXPECT_EQ(observer.count(), 1);
zstein56162b92017-04-24 16:54:35 -0700282
283 // State changes, so we should signal.
284 transport.SetRtcpMuxEnabled(false);
Zhi Huang95e7dbb2018-03-29 00:08:03 +0000285 EXPECT_EQ(observer.count(), 2);
zstein3dcf0e92017-06-01 13:22:42 -0700286}
287
zstein3dcf0e92017-06-01 13:22:42 -0700288// Test that SignalPacketReceived fires with rtcp=true when a RTCP packet is
289// received.
290TEST(RtpTransportTest, SignalDemuxedRtcp) {
291 RtpTransport transport(kMuxDisabled);
Zhi Huang95e7dbb2018-03-29 00:08:03 +0000292 SignalPacketReceivedCounter observer(&transport);
zstein3dcf0e92017-06-01 13:22:42 -0700293 rtc::FakePacketTransport fake_rtp("fake_rtp");
294 fake_rtp.SetDestination(&fake_rtp, true);
295 transport.SetRtpPacketTransport(&fake_rtp);
296
297 // An rtcp packet.
298 const char data[] = {0, 73, 0, 0};
299 const int len = 4;
300 const rtc::PacketOptions options;
301 const int flags = 0;
302 fake_rtp.SendPacket(data, len, options, flags);
303 EXPECT_EQ(0, observer.rtp_count());
304 EXPECT_EQ(1, observer.rtcp_count());
305}
306
307static const unsigned char kRtpData[] = {0x80, 0x11, 0, 0, 0, 0,
308 0, 0, 0, 0, 0, 0};
309static const int kRtpLen = 12;
310
311// Test that SignalPacketReceived fires with rtcp=false when a RTP packet with a
312// handled payload type is received.
313TEST(RtpTransportTest, SignalHandledRtpPayloadType) {
314 RtpTransport transport(kMuxDisabled);
Zhi Huang95e7dbb2018-03-29 00:08:03 +0000315 SignalPacketReceivedCounter observer(&transport);
zstein3dcf0e92017-06-01 13:22:42 -0700316 rtc::FakePacketTransport fake_rtp("fake_rtp");
317 fake_rtp.SetDestination(&fake_rtp, true);
318 transport.SetRtpPacketTransport(&fake_rtp);
zstein3dcf0e92017-06-01 13:22:42 -0700319
320 // An rtp packet.
321 const rtc::PacketOptions options;
322 const int flags = 0;
323 rtc::Buffer rtp_data(kRtpData, kRtpLen);
324 fake_rtp.SendPacket(rtp_data.data<char>(), kRtpLen, options, flags);
325 EXPECT_EQ(1, observer.rtp_count());
326 EXPECT_EQ(0, observer.rtcp_count());
327}
328
zstein56162b92017-04-24 16:54:35 -0700329} // namespace webrtc