1 /*
2  *  Copyright (c) 2012 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 <algorithm>
12 #include <memory>
13 #include <vector>
14 
15 #include "common_types.h"  // NOLINT(build/include)
16 #include "modules/audio_coding/codecs/audio_format_conversion.h"
17 #include "modules/rtp_rtcp/include/receive_statistics.h"
18 #include "modules/rtp_rtcp/include/rtp_rtcp.h"
19 #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
20 #include "modules/rtp_rtcp/source/rtp_receiver_audio.h"
21 #include "modules/rtp_rtcp/test/testAPI/test_api.h"
22 #include "rtc_base/rate_limiter.h"
23 #include "test/gmock.h"
24 #include "test/gtest.h"
25 
26 namespace webrtc {
27 namespace {
28 
29 class RtcpCallback : public RtcpIntraFrameObserver {
30  public:
SetModule(RtpRtcp * module)31   void SetModule(RtpRtcp* module) {
32     _rtpRtcpModule = module;
33   }
OnRTCPPacketTimeout(const int32_t id)34   virtual void OnRTCPPacketTimeout(const int32_t id) {
35   }
OnLipSyncUpdate(const int32_t id,const int32_t audioVideoOffset)36   virtual void OnLipSyncUpdate(const int32_t id,
37                                const int32_t audioVideoOffset) {}
OnReceivedIntraFrameRequest(uint32_t ssrc)38   virtual void OnReceivedIntraFrameRequest(uint32_t ssrc) {}
39 
40  private:
41   RtpRtcp* _rtpRtcpModule;
42 };
43 
44 class TestRtpFeedback : public NullRtpFeedback {
45  public:
TestRtpFeedback(RtpRtcp * rtp_rtcp)46   explicit TestRtpFeedback(RtpRtcp* rtp_rtcp) : rtp_rtcp_(rtp_rtcp) {}
~TestRtpFeedback()47   virtual ~TestRtpFeedback() {}
48 
OnIncomingSSRCChanged(uint32_t ssrc)49   void OnIncomingSSRCChanged(uint32_t ssrc) override {
50     rtp_rtcp_->SetRemoteSSRC(ssrc);
51   }
52 
53  private:
54   RtpRtcp* rtp_rtcp_;
55 };
56 
57 class RtpRtcpRtcpTest : public ::testing::Test {
58  protected:
RtpRtcpRtcpTest()59   RtpRtcpRtcpTest()
60       : fake_clock(123456), retransmission_rate_limiter_(&fake_clock, 1000) {
61     test_csrcs.push_back(1234);
62     test_csrcs.push_back(2345);
63     test_ssrc = 3456;
64     test_timestamp = 4567;
65     test_sequence_number = 2345;
66   }
~RtpRtcpRtcpTest()67   ~RtpRtcpRtcpTest() {}
68 
SetUp()69   virtual void SetUp() {
70     receiver = new TestRtpReceiver();
71     transport1 = new LoopBackTransport();
72     transport2 = new LoopBackTransport();
73     myRTCPFeedback1 = new RtcpCallback();
74     myRTCPFeedback2 = new RtcpCallback();
75 
76     receive_statistics1_.reset(ReceiveStatistics::Create(&fake_clock));
77     receive_statistics2_.reset(ReceiveStatistics::Create(&fake_clock));
78 
79     RtpRtcp::Configuration configuration;
80     configuration.audio = true;
81     configuration.clock = &fake_clock;
82     configuration.receive_statistics = receive_statistics1_.get();
83     configuration.outgoing_transport = transport1;
84     configuration.intra_frame_callback = myRTCPFeedback1;
85     configuration.retransmission_rate_limiter = &retransmission_rate_limiter_;
86 
87     rtp_payload_registry1_.reset(new RTPPayloadRegistry());
88     rtp_payload_registry2_.reset(new RTPPayloadRegistry());
89 
90     module1 = RtpRtcp::CreateRtpRtcp(configuration);
91 
92     rtp_feedback1_.reset(new TestRtpFeedback(module1));
93 
94     rtp_receiver1_.reset(RtpReceiver::CreateAudioReceiver(
95         &fake_clock, receiver, rtp_feedback1_.get(),
96         rtp_payload_registry1_.get()));
97 
98     configuration.receive_statistics = receive_statistics2_.get();
99     configuration.outgoing_transport = transport2;
100     configuration.intra_frame_callback = myRTCPFeedback2;
101 
102     module2 = RtpRtcp::CreateRtpRtcp(configuration);
103 
104     rtp_feedback2_.reset(new TestRtpFeedback(module2));
105 
106     rtp_receiver2_.reset(RtpReceiver::CreateAudioReceiver(
107         &fake_clock, receiver, rtp_feedback2_.get(),
108         rtp_payload_registry2_.get()));
109 
110     transport1->SetSendModule(module2, rtp_payload_registry2_.get(),
111                               rtp_receiver2_.get(), receive_statistics2_.get());
112     transport2->SetSendModule(module1, rtp_payload_registry1_.get(),
113                               rtp_receiver1_.get(), receive_statistics1_.get());
114     myRTCPFeedback1->SetModule(module1);
115     myRTCPFeedback2->SetModule(module2);
116 
117     module1->SetRTCPStatus(RtcpMode::kCompound);
118     module2->SetRTCPStatus(RtcpMode::kCompound);
119 
120     module2->SetSSRC(test_ssrc + 1);
121     module1->SetSSRC(test_ssrc);
122     module1->SetSequenceNumber(test_sequence_number);
123     module1->SetStartTimestamp(test_timestamp);
124 
125     module1->SetCsrcs(test_csrcs);
126     EXPECT_EQ(0, module1->SetCNAME("john.doe@test.test"));
127 
128     EXPECT_EQ(0, module1->SetSendingStatus(true));
129 
130     CodecInst voice_codec;
131     voice_codec.pltype = 96;
132     voice_codec.plfreq = 8000;
133     voice_codec.rate = 64000;
134     memcpy(voice_codec.plname, "PCMU", 5);
135 
136     EXPECT_EQ(0, module1->RegisterSendPayload(voice_codec));
137     EXPECT_EQ(0, rtp_receiver1_->RegisterReceivePayload(
138                      voice_codec.pltype, CodecInstToSdp(voice_codec)));
139     EXPECT_EQ(0, module2->RegisterSendPayload(voice_codec));
140     EXPECT_EQ(0, rtp_receiver2_->RegisterReceivePayload(
141                      voice_codec.pltype, CodecInstToSdp(voice_codec)));
142 
143     // We need to send one RTP packet to get the RTCP packet to be accepted by
144     // the receiving module.
145     // send RTP packet with the data "testtest"
146     const uint8_t test[9] = "testtest";
147     EXPECT_EQ(true,
148               module1->SendOutgoingData(webrtc::kAudioFrameSpeech, 96, 0, -1,
149                                         test, 8, nullptr, nullptr, nullptr));
150   }
151 
TearDown()152   virtual void TearDown() {
153     delete module1;
154     delete module2;
155     delete myRTCPFeedback1;
156     delete myRTCPFeedback2;
157     delete transport1;
158     delete transport2;
159     delete receiver;
160   }
161 
162   std::unique_ptr<TestRtpFeedback> rtp_feedback1_;
163   std::unique_ptr<TestRtpFeedback> rtp_feedback2_;
164   std::unique_ptr<ReceiveStatistics> receive_statistics1_;
165   std::unique_ptr<ReceiveStatistics> receive_statistics2_;
166   std::unique_ptr<RTPPayloadRegistry> rtp_payload_registry1_;
167   std::unique_ptr<RTPPayloadRegistry> rtp_payload_registry2_;
168   std::unique_ptr<RtpReceiver> rtp_receiver1_;
169   std::unique_ptr<RtpReceiver> rtp_receiver2_;
170   RtpRtcp* module1;
171   RtpRtcp* module2;
172   TestRtpReceiver* receiver;
173   LoopBackTransport* transport1;
174   LoopBackTransport* transport2;
175   RtcpCallback* myRTCPFeedback1;
176   RtcpCallback* myRTCPFeedback2;
177 
178   uint32_t test_ssrc;
179   uint32_t test_timestamp;
180   uint16_t test_sequence_number;
181   std::vector<uint32_t> test_csrcs;
182   SimulatedClock fake_clock;
183   RateLimiter retransmission_rate_limiter_;
184 };
185 
TEST_F(RtpRtcpRtcpTest,RTCP_CNAME)186 TEST_F(RtpRtcpRtcpTest, RTCP_CNAME) {
187   uint32_t testOfCSRC[webrtc::kRtpCsrcSize];
188   EXPECT_EQ(2, rtp_receiver2_->CSRCs(testOfCSRC));
189   EXPECT_EQ(test_csrcs[0], testOfCSRC[0]);
190   EXPECT_EQ(test_csrcs[1], testOfCSRC[1]);
191 
192   // Set cname of mixed.
193   EXPECT_EQ(0, module1->AddMixedCNAME(test_csrcs[0], "john@192.168.0.1"));
194   EXPECT_EQ(0, module1->AddMixedCNAME(test_csrcs[1], "jane@192.168.0.2"));
195 
196   EXPECT_EQ(-1, module1->RemoveMixedCNAME(test_csrcs[0] + 1));
197   EXPECT_EQ(0, module1->RemoveMixedCNAME(test_csrcs[1]));
198   EXPECT_EQ(0, module1->AddMixedCNAME(test_csrcs[1], "jane@192.168.0.2"));
199 
200   // send RTCP packet, triggered by timer
201   fake_clock.AdvanceTimeMilliseconds(7500);
202   module1->Process();
203   fake_clock.AdvanceTimeMilliseconds(100);
204   module2->Process();
205 
206   char cName[RTCP_CNAME_SIZE];
207   EXPECT_EQ(-1, module2->RemoteCNAME(rtp_receiver2_->SSRC() + 1, cName));
208 
209   // Check multiple CNAME.
210   EXPECT_EQ(0, module2->RemoteCNAME(rtp_receiver2_->SSRC(), cName));
211   EXPECT_EQ(0, strncmp(cName, "john.doe@test.test", RTCP_CNAME_SIZE));
212 
213   EXPECT_EQ(0, module2->RemoteCNAME(test_csrcs[0], cName));
214   EXPECT_EQ(0, strncmp(cName, "john@192.168.0.1", RTCP_CNAME_SIZE));
215 
216   EXPECT_EQ(0, module2->RemoteCNAME(test_csrcs[1], cName));
217   EXPECT_EQ(0, strncmp(cName, "jane@192.168.0.2", RTCP_CNAME_SIZE));
218 
219   EXPECT_EQ(0, module1->SetSendingStatus(false));
220 
221   // Test that BYE clears the CNAME
222   EXPECT_EQ(-1, module2->RemoteCNAME(rtp_receiver2_->SSRC(), cName));
223 }
224 
TEST_F(RtpRtcpRtcpTest,RemoteRTCPStatRemote)225 TEST_F(RtpRtcpRtcpTest, RemoteRTCPStatRemote) {
226   std::vector<RTCPReportBlock> report_blocks;
227 
228   EXPECT_EQ(0, module1->RemoteRTCPStat(&report_blocks));
229   EXPECT_EQ(0u, report_blocks.size());
230 
231   // send RTCP packet, triggered by timer
232   fake_clock.AdvanceTimeMilliseconds(7500);
233   module1->Process();
234   fake_clock.AdvanceTimeMilliseconds(100);
235   module2->Process();
236 
237   EXPECT_EQ(0, module1->RemoteRTCPStat(&report_blocks));
238   ASSERT_EQ(1u, report_blocks.size());
239 
240   // |test_ssrc+1| is the SSRC of module2 that send the report.
241   EXPECT_EQ(test_ssrc + 1, report_blocks[0].sender_ssrc);
242   EXPECT_EQ(test_ssrc, report_blocks[0].source_ssrc);
243 
244   EXPECT_EQ(0u, report_blocks[0].packets_lost);
245   EXPECT_LT(0u, report_blocks[0].delay_since_last_sender_report);
246   EXPECT_EQ(test_sequence_number,
247             report_blocks[0].extended_highest_sequence_number);
248   EXPECT_EQ(0u, report_blocks[0].fraction_lost);
249 }
250 
251 }  // namespace
252 }  // namespace webrtc
253