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