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 "webrtc/system_wrappers/interface/atomic32.h" 12#include "webrtc/system_wrappers/interface/critical_section_wrapper.h" 13#include "webrtc/system_wrappers/interface/event_wrapper.h" 14#include "webrtc/test/testsupport/fileutils.h" 15#include "webrtc/voice_engine/test/auto_test/fixtures/after_streaming_fixture.h" 16#include "webrtc/voice_engine/test/auto_test/voe_standard_test.h" 17 18class TestRtpObserver : public webrtc::VoERTPObserver { 19 public: 20 TestRtpObserver() 21 : crit_(voetest::CriticalSectionWrapper::CreateCriticalSection()), 22 changed_ssrc_event_(voetest::EventWrapper::Create()) {} 23 virtual ~TestRtpObserver() {} 24 virtual void OnIncomingCSRCChanged(int channel, 25 unsigned int CSRC, 26 bool added) {} 27 virtual void OnIncomingSSRCChanged(int channel, 28 unsigned int SSRC); 29 void WaitForChangedSsrc() { 30 // 10 seconds should be enough. 31 EXPECT_EQ(voetest::kEventSignaled, changed_ssrc_event_->Wait(10*1000)); 32 changed_ssrc_event_->Reset(); 33 } 34 void SetIncomingSsrc(unsigned int ssrc) { 35 voetest::CriticalSectionScoped lock(crit_.get()); 36 incoming_ssrc_ = ssrc; 37 } 38 public: 39 voetest::scoped_ptr<voetest::CriticalSectionWrapper> crit_; 40 unsigned int incoming_ssrc_; 41 voetest::scoped_ptr<voetest::EventWrapper> changed_ssrc_event_; 42}; 43 44void TestRtpObserver::OnIncomingSSRCChanged(int channel, 45 unsigned int SSRC) { 46 char msg[128]; 47 sprintf(msg, "\n=> OnIncomingSSRCChanged(channel=%d, SSRC=%u)\n", channel, 48 SSRC); 49 TEST_LOG("%s", msg); 50 51 { 52 voetest::CriticalSectionScoped lock(crit_.get()); 53 if (incoming_ssrc_ == SSRC) 54 changed_ssrc_event_->Set(); 55 } 56} 57 58class RtcpAppHandler : public webrtc::VoERTCPObserver { 59 public: 60 RtcpAppHandler() : length_in_bytes_(0), sub_type_(0), name_(0) {} 61 void OnApplicationDataReceived(int channel, 62 unsigned char sub_type, 63 unsigned int name, 64 const unsigned char* data, 65 unsigned short length_in_bytes); 66 void Reset(); 67 ~RtcpAppHandler() {} 68 unsigned short length_in_bytes_; 69 unsigned char data_[256]; 70 unsigned char sub_type_; 71 unsigned int name_; 72}; 73 74 75static const char* const RTCP_CNAME = "Whatever"; 76 77class RtpRtcpTest : public AfterStreamingFixture { 78 protected: 79 void SetUp() { 80 // We need a second channel for this test, so set it up. 81 second_channel_ = voe_base_->CreateChannel(); 82 EXPECT_GE(second_channel_, 0); 83 84 transport_ = new LoopBackTransport(voe_network_); 85 EXPECT_EQ(0, voe_network_->RegisterExternalTransport(second_channel_, 86 *transport_)); 87 88 EXPECT_EQ(0, voe_base_->StartReceive(second_channel_)); 89 EXPECT_EQ(0, voe_base_->StartPlayout(second_channel_)); 90 EXPECT_EQ(0, voe_rtp_rtcp_->SetLocalSSRC(second_channel_, 5678)); 91 EXPECT_EQ(0, voe_base_->StartSend(second_channel_)); 92 93 // We'll set up the RTCP CNAME and SSRC to something arbitrary here. 94 voe_rtp_rtcp_->SetRTCP_CNAME(channel_, RTCP_CNAME); 95 } 96 97 void TearDown() { 98 EXPECT_EQ(0, voe_network_->DeRegisterExternalTransport(second_channel_)); 99 voe_base_->DeleteChannel(second_channel_); 100 delete transport_; 101 } 102 103 int second_channel_; 104 LoopBackTransport* transport_; 105}; 106 107void RtcpAppHandler::OnApplicationDataReceived( 108 const int /*channel*/, unsigned char sub_type, 109 unsigned int name, const unsigned char* data, 110 unsigned short length_in_bytes) { 111 length_in_bytes_ = length_in_bytes; 112 memcpy(data_, &data[0], length_in_bytes); 113 sub_type_ = sub_type; 114 name_ = name; 115} 116 117void RtcpAppHandler::Reset() { 118 length_in_bytes_ = 0; 119 memset(data_, 0, sizeof(data_)); 120 sub_type_ = 0; 121 name_ = 0; 122} 123 124TEST_F(RtpRtcpTest, RemoteRtcpCnameHasPropagatedToRemoteSide) { 125 if (!FLAGS_include_timing_dependent_tests) { 126 TEST_LOG("Skipping test - running in slow execution environment...\n"); 127 return; 128 } 129 130 // We need to sleep a bit here for the name to propagate. For instance, 131 // 200 milliseconds is not enough, so we'll go with one second here. 132 Sleep(1000); 133 134 char char_buffer[256]; 135 voe_rtp_rtcp_->GetRemoteRTCP_CNAME(channel_, char_buffer); 136 EXPECT_STREQ(RTCP_CNAME, char_buffer); 137} 138 139// Flakily hangs on Linux. code.google.com/p/webrtc/issues/detail?id=2178. 140TEST_F(RtpRtcpTest, DISABLED_ON_LINUX(SSRCPropagatesCorrectly)) { 141 unsigned int local_ssrc = 1234; 142 EXPECT_EQ(0, voe_base_->StopSend(channel_)); 143 EXPECT_EQ(0, voe_rtp_rtcp_->SetLocalSSRC(channel_, local_ssrc)); 144 EXPECT_EQ(0, voe_base_->StartSend(channel_)); 145 146 Sleep(1000); 147 148 unsigned int ssrc; 149 EXPECT_EQ(0, voe_rtp_rtcp_->GetLocalSSRC(channel_, ssrc)); 150 EXPECT_EQ(local_ssrc, ssrc); 151 152 EXPECT_EQ(0, voe_rtp_rtcp_->GetRemoteSSRC(channel_, ssrc)); 153 EXPECT_EQ(local_ssrc, ssrc); 154} 155 156// TODO(xians, phoglund): Re-enable when issue 372 is resolved. 157TEST_F(RtpRtcpTest, DISABLED_CanCreateRtpDumpFilesWithoutError) { 158 // Create two RTP dump files (3 seconds long). You can verify these after 159 // the test using rtpplay or NetEqRTPplay if you like. 160 std::string output_path = webrtc::test::OutputPath(); 161 std::string incoming_filename = output_path + "dump_in_3sec.rtp"; 162 std::string outgoing_filename = output_path + "dump_out_3sec.rtp"; 163 164 EXPECT_EQ(0, voe_rtp_rtcp_->StartRTPDump( 165 channel_, incoming_filename.c_str(), webrtc::kRtpIncoming)); 166 EXPECT_EQ(0, voe_rtp_rtcp_->StartRTPDump( 167 channel_, outgoing_filename.c_str(), webrtc::kRtpOutgoing)); 168 169 Sleep(3000); 170 171 EXPECT_EQ(0, voe_rtp_rtcp_->StopRTPDump(channel_, webrtc::kRtpIncoming)); 172 EXPECT_EQ(0, voe_rtp_rtcp_->StopRTPDump(channel_, webrtc::kRtpOutgoing)); 173} 174 175