1// libjingle 2// Copyright 2011 Google Inc. 3// 4// Redistribution and use in source and binary forms, with or without 5// modification, are permitted provided that the following conditions are met: 6// 7// 1. Redistributions of source code must retain the above copyright notice, 8// this list of conditions and the following disclaimer. 9// 2. Redistributions in binary form must reproduce the above copyright notice, 10// this list of conditions and the following disclaimer in the documentation 11// and/or other materials provided with the distribution. 12// 3. The name of the author may not be used to endorse or promote products 13// derived from this software without specific prior written permission. 14// 15// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 16// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 17// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 18// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 19// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 20// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 21// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 22// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 23// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 24// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 26#include "talk/session/media/rtcpmuxfilter.h" 27 28#include "talk/media/base/testutils.h" 29#include "webrtc/base/gunit.h" 30 31TEST(RtcpMuxFilterTest, DemuxRtcpSender) { 32 cricket::RtcpMuxFilter filter; 33 const char data[] = { 0, 73, 0, 0 }; 34 const int len = 4; 35 36 // Init state - refuse to demux 37 EXPECT_FALSE(filter.DemuxRtcp(data, len)); 38 // After sent offer, demux should be enabled 39 filter.SetOffer(true, cricket::CS_LOCAL); 40 EXPECT_TRUE(filter.DemuxRtcp(data, len)); 41 // Remote accepted, demux should be enabled 42 filter.SetAnswer(true, cricket::CS_REMOTE); 43 EXPECT_TRUE(filter.DemuxRtcp(data, len)); 44} 45 46TEST(RtcpMuxFilterTest, DemuxRtcpReceiver) { 47 cricket::RtcpMuxFilter filter; 48 const char data[] = { 0, 73, 0, 0 }; 49 const int len = 4; 50 51 // Init state - refuse to demux 52 EXPECT_FALSE(filter.DemuxRtcp(data, len)); 53 // After received offer, demux should not be enabled 54 filter.SetOffer(true, cricket::CS_REMOTE); 55 EXPECT_FALSE(filter.DemuxRtcp(data, len)); 56 // We accept, demux is now enabled 57 filter.SetAnswer(true, cricket::CS_LOCAL); 58 EXPECT_TRUE(filter.DemuxRtcp(data, len)); 59} 60 61TEST(RtcpMuxFilterTest, DemuxRtcpSenderProvisionalAnswer) { 62 cricket::RtcpMuxFilter filter; 63 const char data[] = { 0, 73, 0, 0 }; 64 const int len = 4; 65 66 filter.SetOffer(true, cricket::CS_REMOTE); 67 // Received provisional answer without mux enabled. 68 filter.SetProvisionalAnswer(false, cricket::CS_LOCAL); 69 EXPECT_FALSE(filter.DemuxRtcp(data, len)); 70 // Received provisional answer with mux enabled. 71 filter.SetProvisionalAnswer(true, cricket::CS_LOCAL); 72 EXPECT_TRUE(filter.DemuxRtcp(data, len)); 73 // Remote accepted, demux should be enabled. 74 filter.SetAnswer(true, cricket::CS_LOCAL); 75 EXPECT_TRUE(filter.DemuxRtcp(data, len)); 76} 77 78TEST(RtcpMuxFilterTest, DemuxRtcpReceiverProvisionalAnswer) { 79 cricket::RtcpMuxFilter filter; 80 const char data[] = { 0, 73, 0, 0 }; 81 const int len = 4; 82 83 filter.SetOffer(true, cricket::CS_LOCAL); 84 // Received provisional answer without mux enabled. 85 filter.SetProvisionalAnswer(false, cricket::CS_REMOTE); 86 // After sent offer, demux should be enabled until we have received a 87 // final answer. 88 EXPECT_TRUE(filter.DemuxRtcp(data, len)); 89 // Received provisional answer with mux enabled. 90 filter.SetProvisionalAnswer(true, cricket::CS_REMOTE); 91 EXPECT_TRUE(filter.DemuxRtcp(data, len)); 92 // Remote accepted, demux should be enabled. 93 filter.SetAnswer(true, cricket::CS_REMOTE); 94 EXPECT_TRUE(filter.DemuxRtcp(data, len)); 95} 96 97TEST(RtcpMuxFilterTest, IsActiveSender) { 98 cricket::RtcpMuxFilter filter; 99 // Init state - not active 100 EXPECT_FALSE(filter.IsActive()); 101 // After sent offer, demux should not be active. 102 filter.SetOffer(true, cricket::CS_LOCAL); 103 EXPECT_FALSE(filter.IsActive()); 104 // Remote accepted, filter is now active. 105 filter.SetAnswer(true, cricket::CS_REMOTE); 106 EXPECT_TRUE(filter.IsActive()); 107} 108 109// Test that we can receive provisional answer and final answer. 110TEST(RtcpMuxFilterTest, ReceivePrAnswer) { 111 cricket::RtcpMuxFilter filter; 112 filter.SetOffer(true, cricket::CS_LOCAL); 113 // Received provisional answer with mux enabled. 114 EXPECT_TRUE(filter.SetProvisionalAnswer(true, cricket::CS_REMOTE)); 115 // We are now active since both sender and receiver support mux. 116 EXPECT_TRUE(filter.IsActive()); 117 // Received provisional answer with mux disabled. 118 EXPECT_TRUE(filter.SetProvisionalAnswer(false, cricket::CS_REMOTE)); 119 // We are now inactive since the receiver doesn't support mux. 120 EXPECT_FALSE(filter.IsActive()); 121 // Received final answer with mux enabled. 122 EXPECT_TRUE(filter.SetAnswer(true, cricket::CS_REMOTE)); 123 EXPECT_TRUE(filter.IsActive()); 124} 125 126TEST(RtcpMuxFilterTest, IsActiveReceiver) { 127 cricket::RtcpMuxFilter filter; 128 // Init state - not active. 129 EXPECT_FALSE(filter.IsActive()); 130 // After received offer, demux should not be active 131 filter.SetOffer(true, cricket::CS_REMOTE); 132 EXPECT_FALSE(filter.IsActive()); 133 // We accept, filter is now active 134 filter.SetAnswer(true, cricket::CS_LOCAL); 135 EXPECT_TRUE(filter.IsActive()); 136} 137 138// Test that we can send provisional answer and final answer. 139TEST(RtcpMuxFilterTest, SendPrAnswer) { 140 cricket::RtcpMuxFilter filter; 141 filter.SetOffer(true, cricket::CS_REMOTE); 142 // Send provisional answer with mux enabled. 143 EXPECT_TRUE(filter.SetProvisionalAnswer(true, cricket::CS_LOCAL)); 144 EXPECT_TRUE(filter.IsActive()); 145 // Received provisional answer with mux disabled. 146 EXPECT_TRUE(filter.SetProvisionalAnswer(false, cricket::CS_LOCAL)); 147 EXPECT_FALSE(filter.IsActive()); 148 // Send final answer with mux enabled. 149 EXPECT_TRUE(filter.SetAnswer(true, cricket::CS_LOCAL)); 150 EXPECT_TRUE(filter.IsActive()); 151} 152 153// Test that we can enable the filter in an update. 154// We can not disable the filter later since that would mean we need to 155// recreate a rtcp transport channel. 156TEST(RtcpMuxFilterTest, EnableFilterDuringUpdate) { 157 cricket::RtcpMuxFilter filter; 158 EXPECT_FALSE(filter.IsActive()); 159 EXPECT_TRUE(filter.SetOffer(false, cricket::CS_REMOTE)); 160 EXPECT_TRUE(filter.SetAnswer(false, cricket::CS_LOCAL)); 161 EXPECT_FALSE(filter.IsActive()); 162 163 EXPECT_TRUE(filter.SetOffer(true, cricket::CS_REMOTE)); 164 EXPECT_TRUE(filter.SetAnswer(true, cricket::CS_LOCAL)); 165 EXPECT_TRUE(filter.IsActive()); 166 167 EXPECT_FALSE(filter.SetOffer(false, cricket::CS_REMOTE)); 168 EXPECT_FALSE(filter.SetAnswer(false, cricket::CS_LOCAL)); 169 EXPECT_TRUE(filter.IsActive()); 170} 171 172// Test that SetOffer can be called twice. 173TEST(RtcpMuxFilterTest, SetOfferTwice) { 174 cricket::RtcpMuxFilter filter; 175 176 EXPECT_TRUE(filter.SetOffer(true, cricket::CS_REMOTE)); 177 EXPECT_TRUE(filter.SetOffer(true, cricket::CS_REMOTE)); 178 EXPECT_TRUE(filter.SetAnswer(true, cricket::CS_LOCAL)); 179 EXPECT_TRUE(filter.IsActive()); 180 181 cricket::RtcpMuxFilter filter2; 182 EXPECT_TRUE(filter2.SetOffer(false, cricket::CS_LOCAL)); 183 EXPECT_TRUE(filter2.SetOffer(false, cricket::CS_LOCAL)); 184 EXPECT_TRUE(filter2.SetAnswer(false, cricket::CS_REMOTE)); 185 EXPECT_FALSE(filter2.IsActive()); 186} 187 188// Test that the filter can be enabled twice. 189TEST(RtcpMuxFilterTest, EnableFilterTwiceDuringUpdate) { 190 cricket::RtcpMuxFilter filter; 191 192 EXPECT_TRUE(filter.SetOffer(true, cricket::CS_REMOTE)); 193 EXPECT_TRUE(filter.SetAnswer(true, cricket::CS_LOCAL)); 194 EXPECT_TRUE(filter.IsActive()); 195 196 EXPECT_TRUE(filter.SetOffer(true, cricket::CS_REMOTE)); 197 EXPECT_TRUE(filter.SetAnswer(true, cricket::CS_LOCAL)); 198 EXPECT_TRUE(filter.IsActive()); 199} 200 201// Test that the filter can be kept disabled during updates. 202TEST(RtcpMuxFilterTest, KeepFilterDisabledDuringUpdate) { 203 cricket::RtcpMuxFilter filter; 204 205 EXPECT_TRUE(filter.SetOffer(false, cricket::CS_REMOTE)); 206 EXPECT_TRUE(filter.SetAnswer(false, cricket::CS_LOCAL)); 207 EXPECT_FALSE(filter.IsActive()); 208 209 EXPECT_TRUE(filter.SetOffer(false, cricket::CS_REMOTE)); 210 EXPECT_TRUE(filter.SetAnswer(false, cricket::CS_LOCAL)); 211 EXPECT_FALSE(filter.IsActive()); 212} 213