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/base/gunit.h" 29 #include "talk/media/base/testutils.h" 30 31 TEST(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 46 TEST(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 61 TEST(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 78 TEST(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 97 TEST(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. 110 TEST(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 126 TEST(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. 139 TEST(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. 156 TEST(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. 173 TEST(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. 189 TEST(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. 202 TEST(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