1 /*
2  *  Copyright 2011 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/base/gunit.h"
12 #include "webrtc/media/base/testutils.h"
13 #include "webrtc/pc/rtcpmuxfilter.h"
14 
TEST(RtcpMuxFilterTest,DemuxRtcpSender)15 TEST(RtcpMuxFilterTest, DemuxRtcpSender) {
16   cricket::RtcpMuxFilter filter;
17   const char data[] = { 0, 73, 0, 0 };
18   const int len = 4;
19 
20   // Init state - refuse to demux
21   EXPECT_FALSE(filter.DemuxRtcp(data, len));
22   // After sent offer, demux should be enabled
23   filter.SetOffer(true, cricket::CS_LOCAL);
24   EXPECT_TRUE(filter.DemuxRtcp(data, len));
25   // Remote accepted, demux should be enabled
26   filter.SetAnswer(true, cricket::CS_REMOTE);
27   EXPECT_TRUE(filter.DemuxRtcp(data, len));
28 }
29 
TEST(RtcpMuxFilterTest,DemuxRtcpReceiver)30 TEST(RtcpMuxFilterTest, DemuxRtcpReceiver) {
31   cricket::RtcpMuxFilter filter;
32   const char data[] = { 0, 73, 0, 0 };
33   const int len = 4;
34 
35   // Init state - refuse to demux
36   EXPECT_FALSE(filter.DemuxRtcp(data, len));
37   // After received offer, demux should not be enabled
38   filter.SetOffer(true, cricket::CS_REMOTE);
39   EXPECT_FALSE(filter.DemuxRtcp(data, len));
40   // We accept, demux is now enabled
41   filter.SetAnswer(true, cricket::CS_LOCAL);
42   EXPECT_TRUE(filter.DemuxRtcp(data, len));
43 }
44 
TEST(RtcpMuxFilterTest,DemuxRtcpSenderProvisionalAnswer)45 TEST(RtcpMuxFilterTest, DemuxRtcpSenderProvisionalAnswer) {
46   cricket::RtcpMuxFilter filter;
47   const char data[] = { 0, 73, 0, 0 };
48   const int len = 4;
49 
50   filter.SetOffer(true, cricket::CS_REMOTE);
51   // Received provisional answer without mux enabled.
52   filter.SetProvisionalAnswer(false, cricket::CS_LOCAL);
53   EXPECT_FALSE(filter.DemuxRtcp(data, len));
54   // Received provisional answer with mux enabled.
55   filter.SetProvisionalAnswer(true, cricket::CS_LOCAL);
56   EXPECT_TRUE(filter.DemuxRtcp(data, len));
57   // Remote accepted, demux should be enabled.
58   filter.SetAnswer(true, cricket::CS_LOCAL);
59   EXPECT_TRUE(filter.DemuxRtcp(data, len));
60 }
61 
TEST(RtcpMuxFilterTest,DemuxRtcpReceiverProvisionalAnswer)62 TEST(RtcpMuxFilterTest, DemuxRtcpReceiverProvisionalAnswer) {
63   cricket::RtcpMuxFilter filter;
64   const char data[] = { 0, 73, 0, 0 };
65   const int len = 4;
66 
67   filter.SetOffer(true, cricket::CS_LOCAL);
68   // Received provisional answer without mux enabled.
69   filter.SetProvisionalAnswer(false, cricket::CS_REMOTE);
70   // After sent offer, demux should be enabled until we have received a
71   // final answer.
72   EXPECT_TRUE(filter.DemuxRtcp(data, len));
73   // Received provisional answer with mux enabled.
74   filter.SetProvisionalAnswer(true, cricket::CS_REMOTE);
75   EXPECT_TRUE(filter.DemuxRtcp(data, len));
76   // Remote accepted, demux should be enabled.
77   filter.SetAnswer(true, cricket::CS_REMOTE);
78   EXPECT_TRUE(filter.DemuxRtcp(data, len));
79 }
80 
TEST(RtcpMuxFilterTest,IsActiveSender)81 TEST(RtcpMuxFilterTest, IsActiveSender) {
82   cricket::RtcpMuxFilter filter;
83   // Init state - not active
84   EXPECT_FALSE(filter.IsActive());
85   EXPECT_FALSE(filter.IsProvisionallyActive());
86   EXPECT_FALSE(filter.IsFullyActive());
87   // After sent offer, demux should not be active.
88   filter.SetOffer(true, cricket::CS_LOCAL);
89   EXPECT_FALSE(filter.IsActive());
90   EXPECT_FALSE(filter.IsProvisionallyActive());
91   EXPECT_FALSE(filter.IsFullyActive());
92   // Remote accepted, filter is now active.
93   filter.SetAnswer(true, cricket::CS_REMOTE);
94   EXPECT_TRUE(filter.IsActive());
95   EXPECT_FALSE(filter.IsProvisionallyActive());
96   EXPECT_TRUE(filter.IsFullyActive());
97 }
98 
99 // Test that we can receive provisional answer and final answer.
TEST(RtcpMuxFilterTest,ReceivePrAnswer)100 TEST(RtcpMuxFilterTest, ReceivePrAnswer) {
101   cricket::RtcpMuxFilter filter;
102   filter.SetOffer(true, cricket::CS_LOCAL);
103   // Received provisional answer with mux enabled.
104   EXPECT_TRUE(filter.SetProvisionalAnswer(true, cricket::CS_REMOTE));
105   // We are now provisionally active since both sender and receiver support mux.
106   EXPECT_TRUE(filter.IsActive());
107   EXPECT_TRUE(filter.IsProvisionallyActive());
108   EXPECT_FALSE(filter.IsFullyActive());
109   // Received provisional answer with mux disabled.
110   EXPECT_TRUE(filter.SetProvisionalAnswer(false, cricket::CS_REMOTE));
111   // We are now inactive since the receiver doesn't support mux.
112   EXPECT_FALSE(filter.IsActive());
113   EXPECT_FALSE(filter.IsProvisionallyActive());
114   EXPECT_FALSE(filter.IsFullyActive());
115   // Received final answer with mux enabled.
116   EXPECT_TRUE(filter.SetAnswer(true, cricket::CS_REMOTE));
117   EXPECT_TRUE(filter.IsActive());
118   EXPECT_FALSE(filter.IsProvisionallyActive());
119   EXPECT_TRUE(filter.IsFullyActive());
120 }
121 
TEST(RtcpMuxFilterTest,IsActiveReceiver)122 TEST(RtcpMuxFilterTest, IsActiveReceiver) {
123   cricket::RtcpMuxFilter filter;
124   // Init state - not active.
125   EXPECT_FALSE(filter.IsActive());
126   EXPECT_FALSE(filter.IsProvisionallyActive());
127   EXPECT_FALSE(filter.IsFullyActive());
128   // After received offer, demux should not be active
129   filter.SetOffer(true, cricket::CS_REMOTE);
130   EXPECT_FALSE(filter.IsActive());
131   EXPECT_FALSE(filter.IsProvisionallyActive());
132   EXPECT_FALSE(filter.IsFullyActive());
133   // We accept, filter is now active
134   filter.SetAnswer(true, cricket::CS_LOCAL);
135   EXPECT_TRUE(filter.IsActive());
136   EXPECT_FALSE(filter.IsProvisionallyActive());
137   EXPECT_TRUE(filter.IsFullyActive());
138 }
139 
140 // Test that we can send provisional answer and final answer.
TEST(RtcpMuxFilterTest,SendPrAnswer)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   EXPECT_TRUE(filter.IsProvisionallyActive());
148   EXPECT_FALSE(filter.IsFullyActive());
149   // Received provisional answer with mux disabled.
150   EXPECT_TRUE(filter.SetProvisionalAnswer(false, cricket::CS_LOCAL));
151   EXPECT_FALSE(filter.IsActive());
152   EXPECT_FALSE(filter.IsProvisionallyActive());
153   EXPECT_FALSE(filter.IsFullyActive());
154   // Send final answer with mux enabled.
155   EXPECT_TRUE(filter.SetAnswer(true, cricket::CS_LOCAL));
156   EXPECT_TRUE(filter.IsActive());
157   EXPECT_FALSE(filter.IsProvisionallyActive());
158   EXPECT_TRUE(filter.IsFullyActive());
159 }
160 
161 // Test that we can enable the filter in an update.
162 // We can not disable the filter later since that would mean we need to
163 // recreate a rtcp transport channel.
TEST(RtcpMuxFilterTest,EnableFilterDuringUpdate)164 TEST(RtcpMuxFilterTest, EnableFilterDuringUpdate) {
165   cricket::RtcpMuxFilter filter;
166   EXPECT_FALSE(filter.IsActive());
167   EXPECT_TRUE(filter.SetOffer(false, cricket::CS_REMOTE));
168   EXPECT_TRUE(filter.SetAnswer(false, cricket::CS_LOCAL));
169   EXPECT_FALSE(filter.IsActive());
170 
171   EXPECT_TRUE(filter.SetOffer(true, cricket::CS_REMOTE));
172   EXPECT_TRUE(filter.SetAnswer(true, cricket::CS_LOCAL));
173   EXPECT_TRUE(filter.IsActive());
174 
175   EXPECT_FALSE(filter.SetOffer(false, cricket::CS_REMOTE));
176   EXPECT_FALSE(filter.SetAnswer(false, cricket::CS_LOCAL));
177   EXPECT_TRUE(filter.IsActive());
178 }
179 
180 // Test that SetOffer can be called twice.
TEST(RtcpMuxFilterTest,SetOfferTwice)181 TEST(RtcpMuxFilterTest, SetOfferTwice) {
182   cricket::RtcpMuxFilter filter;
183 
184   EXPECT_TRUE(filter.SetOffer(true, cricket::CS_REMOTE));
185   EXPECT_TRUE(filter.SetOffer(true, cricket::CS_REMOTE));
186   EXPECT_TRUE(filter.SetAnswer(true, cricket::CS_LOCAL));
187   EXPECT_TRUE(filter.IsActive());
188 
189   cricket::RtcpMuxFilter filter2;
190   EXPECT_TRUE(filter2.SetOffer(false, cricket::CS_LOCAL));
191   EXPECT_TRUE(filter2.SetOffer(false, cricket::CS_LOCAL));
192   EXPECT_TRUE(filter2.SetAnswer(false, cricket::CS_REMOTE));
193   EXPECT_FALSE(filter2.IsActive());
194 }
195 
196 // Test that the filter can be enabled twice.
TEST(RtcpMuxFilterTest,EnableFilterTwiceDuringUpdate)197 TEST(RtcpMuxFilterTest, EnableFilterTwiceDuringUpdate) {
198   cricket::RtcpMuxFilter filter;
199 
200   EXPECT_TRUE(filter.SetOffer(true, cricket::CS_REMOTE));
201   EXPECT_TRUE(filter.SetAnswer(true, cricket::CS_LOCAL));
202   EXPECT_TRUE(filter.IsActive());
203 
204   EXPECT_TRUE(filter.SetOffer(true, cricket::CS_REMOTE));
205   EXPECT_TRUE(filter.SetAnswer(true, cricket::CS_LOCAL));
206   EXPECT_TRUE(filter.IsActive());
207 }
208 
209 // Test that the filter can be kept disabled during updates.
TEST(RtcpMuxFilterTest,KeepFilterDisabledDuringUpdate)210 TEST(RtcpMuxFilterTest, KeepFilterDisabledDuringUpdate) {
211   cricket::RtcpMuxFilter filter;
212 
213   EXPECT_TRUE(filter.SetOffer(false, cricket::CS_REMOTE));
214   EXPECT_TRUE(filter.SetAnswer(false, cricket::CS_LOCAL));
215   EXPECT_FALSE(filter.IsActive());
216 
217   EXPECT_TRUE(filter.SetOffer(false, cricket::CS_REMOTE));
218   EXPECT_TRUE(filter.SetAnswer(false, cricket::CS_LOCAL));
219   EXPECT_FALSE(filter.IsActive());
220 }
221 
222 // Test that we can SetActive and then can't deactivate.
TEST(RtcpMuxFilterTest,SetActiveCantDeactivate)223 TEST(RtcpMuxFilterTest, SetActiveCantDeactivate) {
224   cricket::RtcpMuxFilter filter;
225   const char data[] = { 0, 73, 0, 0 };
226   const int len = 4;
227 
228   filter.SetActive();
229   EXPECT_TRUE(filter.IsActive());
230   EXPECT_TRUE(filter.DemuxRtcp(data, len));
231 
232   EXPECT_FALSE(filter.SetOffer(false, cricket::CS_LOCAL));
233   EXPECT_TRUE(filter.IsActive());
234   EXPECT_TRUE(filter.SetOffer(true, cricket::CS_LOCAL));
235   EXPECT_TRUE(filter.IsActive());
236 
237   EXPECT_FALSE(filter.SetProvisionalAnswer(false, cricket::CS_REMOTE));
238   EXPECT_TRUE(filter.IsActive());
239   EXPECT_TRUE(filter.SetProvisionalAnswer(true, cricket::CS_REMOTE));
240   EXPECT_TRUE(filter.IsActive());
241 
242   EXPECT_FALSE(filter.SetAnswer(false, cricket::CS_REMOTE));
243   EXPECT_TRUE(filter.IsActive());
244   EXPECT_TRUE(filter.SetAnswer(true, cricket::CS_REMOTE));
245   EXPECT_TRUE(filter.IsActive());
246 
247   EXPECT_FALSE(filter.SetOffer(false, cricket::CS_REMOTE));
248   EXPECT_TRUE(filter.IsActive());
249   EXPECT_TRUE(filter.SetOffer(true, cricket::CS_REMOTE));
250   EXPECT_TRUE(filter.IsActive());
251 
252   EXPECT_FALSE(filter.SetProvisionalAnswer(false, cricket::CS_LOCAL));
253   EXPECT_TRUE(filter.IsActive());
254   EXPECT_TRUE(filter.SetProvisionalAnswer(true, cricket::CS_LOCAL));
255   EXPECT_TRUE(filter.IsActive());
256 
257   EXPECT_FALSE(filter.SetAnswer(false, cricket::CS_LOCAL));
258   EXPECT_TRUE(filter.IsActive());
259   EXPECT_TRUE(filter.SetAnswer(true, cricket::CS_LOCAL));
260   EXPECT_TRUE(filter.IsActive());
261 }
262