2 // Copyright 2011 Google Inc.
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are met:
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.
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.
26 #include "talk/session/media/rtcpmuxfilter.h"
28 #include "talk/media/base/testutils.h"
29 #include "webrtc/base/gunit.h"
31 TEST(RtcpMuxFilterTest, DemuxRtcpSender) {
32 cricket::RtcpMuxFilter filter;
33 const char data[] = { 0, 73, 0, 0 };
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));
46 TEST(RtcpMuxFilterTest, DemuxRtcpReceiver) {
47 cricket::RtcpMuxFilter filter;
48 const char data[] = { 0, 73, 0, 0 };
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));
61 TEST(RtcpMuxFilterTest, DemuxRtcpSenderProvisionalAnswer) {
62 cricket::RtcpMuxFilter filter;
63 const char data[] = { 0, 73, 0, 0 };
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));
78 TEST(RtcpMuxFilterTest, DemuxRtcpReceiverProvisionalAnswer) {
79 cricket::RtcpMuxFilter filter;
80 const char data[] = { 0, 73, 0, 0 };
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
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));
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());
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());
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());
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());
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());
163 EXPECT_TRUE(filter.SetOffer(true, cricket::CS_REMOTE));
164 EXPECT_TRUE(filter.SetAnswer(true, cricket::CS_LOCAL));
165 EXPECT_TRUE(filter.IsActive());
167 EXPECT_FALSE(filter.SetOffer(false, cricket::CS_REMOTE));
168 EXPECT_FALSE(filter.SetAnswer(false, cricket::CS_LOCAL));
169 EXPECT_TRUE(filter.IsActive());
172 // Test that SetOffer can be called twice.
173 TEST(RtcpMuxFilterTest, SetOfferTwice) {
174 cricket::RtcpMuxFilter filter;
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());
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());
188 // Test that the filter can be enabled twice.
189 TEST(RtcpMuxFilterTest, EnableFilterTwiceDuringUpdate) {
190 cricket::RtcpMuxFilter filter;
192 EXPECT_TRUE(filter.SetOffer(true, cricket::CS_REMOTE));
193 EXPECT_TRUE(filter.SetAnswer(true, cricket::CS_LOCAL));
194 EXPECT_TRUE(filter.IsActive());
196 EXPECT_TRUE(filter.SetOffer(true, cricket::CS_REMOTE));
197 EXPECT_TRUE(filter.SetAnswer(true, cricket::CS_LOCAL));
198 EXPECT_TRUE(filter.IsActive());
201 // Test that the filter can be kept disabled during updates.
202 TEST(RtcpMuxFilterTest, KeepFilterDisabledDuringUpdate) {
203 cricket::RtcpMuxFilter filter;
205 EXPECT_TRUE(filter.SetOffer(false, cricket::CS_REMOTE));
206 EXPECT_TRUE(filter.SetAnswer(false, cricket::CS_LOCAL));
207 EXPECT_FALSE(filter.IsActive());
209 EXPECT_TRUE(filter.SetOffer(false, cricket::CS_REMOTE));
210 EXPECT_TRUE(filter.SetAnswer(false, cricket::CS_LOCAL));
211 EXPECT_FALSE(filter.IsActive());