blob: 23c305c9007012ae549a21024760252ac2d8fbd4 [file] [log] [blame]
eladalona52722f2017-06-26 11:23:54 -07001/*
2 * Copyright (c) 2017 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
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020011#include "call/rtcp_demuxer.h"
eladalona52722f2017-06-26 11:23:54 -070012
Yves Gerey3e707812018-11-28 16:47:49 +010013#include <stddef.h>
Jonas Olssona4d87372019-07-05 19:08:33 +020014
Steve Anton80183062017-08-18 11:10:12 -070015#include <set>
eladalona52722f2017-06-26 11:23:54 -070016
Patrik Höglund3e113432017-12-15 14:40:10 +010017#include "api/rtp_headers.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020018#include "call/rtcp_packet_sink_interface.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020019#include "modules/rtp_rtcp/source/rtcp_packet/bye.h"
Niels Möllerd57efc12019-03-22 14:02:11 +010020#include "modules/rtp_rtcp/source/rtp_header_extensions.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020021#include "rtc_base/arraysize.h"
Yves Gerey3e707812018-11-28 16:47:49 +010022#include "rtc_base/buffer.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020023#include "rtc_base/checks.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020024#include "test/gmock.h"
25#include "test/gtest.h"
eladalona52722f2017-06-26 11:23:54 -070026
27namespace webrtc {
28
29namespace {
30
31using ::testing::_;
32using ::testing::AtLeast;
33using ::testing::ElementsAreArray;
34using ::testing::InSequence;
Steve Anton80183062017-08-18 11:10:12 -070035using ::testing::Matcher;
eladalona52722f2017-06-26 11:23:54 -070036using ::testing::NiceMock;
37
38class MockRtcpPacketSink : public RtcpPacketSinkInterface {
39 public:
40 MOCK_METHOD1(OnRtcpPacket, void(rtc::ArrayView<const uint8_t>));
41};
42
Mirko Bonadei6a489f22019-04-09 15:11:12 +020043class RtcpDemuxerTest : public ::testing::Test {
Steve Anton80183062017-08-18 11:10:12 -070044 protected:
45 ~RtcpDemuxerTest() {
46 for (auto* sink : sinks_to_tear_down_) {
47 demuxer_.RemoveSink(sink);
48 }
49 for (auto* sink : broadcast_sinks_to_tear_down_) {
50 demuxer_.RemoveBroadcastSink(sink);
51 }
52 }
53
54 void AddSsrcSink(uint32_t ssrc, RtcpPacketSinkInterface* sink) {
55 demuxer_.AddSink(ssrc, sink);
56 sinks_to_tear_down_.insert(sink);
57 }
58
59 void AddRsidSink(const std::string& rsid, RtcpPacketSinkInterface* sink) {
60 demuxer_.AddSink(rsid, sink);
61 sinks_to_tear_down_.insert(sink);
62 }
63
64 void RemoveSink(RtcpPacketSinkInterface* sink) {
65 sinks_to_tear_down_.erase(sink);
66 demuxer_.RemoveSink(sink);
67 }
68
69 void AddBroadcastSink(RtcpPacketSinkInterface* sink) {
70 demuxer_.AddBroadcastSink(sink);
71 broadcast_sinks_to_tear_down_.insert(sink);
72 }
73
74 void RemoveBroadcastSink(RtcpPacketSinkInterface* sink) {
75 broadcast_sinks_to_tear_down_.erase(sink);
76 demuxer_.RemoveBroadcastSink(sink);
77 }
78
79 RtcpDemuxer demuxer_;
80 std::set<RtcpPacketSinkInterface*> sinks_to_tear_down_;
81 std::set<RtcpPacketSinkInterface*> broadcast_sinks_to_tear_down_;
82};
83
eladalona52722f2017-06-26 11:23:54 -070084// Produces a packet buffer representing an RTCP packet with a given SSRC,
85// as it would look when sent over the wire.
86// |distinguishing_string| allows different RTCP packets with the same SSRC
87// to be distinguished. How this is set into the actual packet is
88// unimportant, and depends on which RTCP message we choose to use.
89rtc::Buffer CreateRtcpPacket(uint32_t ssrc,
90 const std::string& distinguishing_string = "") {
91 rtcp::Bye packet;
92 packet.SetSenderSsrc(ssrc);
93 if (distinguishing_string != "") {
94 // Actual way we use |distinguishing_string| is unimportant, so long
95 // as it ends up in the packet.
96 packet.SetReason(distinguishing_string);
97 }
98 return packet.Build();
99}
100
Steve Anton80183062017-08-18 11:10:12 -0700101static Matcher<rtc::ArrayView<const uint8_t>> SamePacketAs(
102 const rtc::Buffer& other) {
103 return ElementsAreArray(other.cbegin(), other.cend());
104}
105
eladalona52722f2017-06-26 11:23:54 -0700106} // namespace
107
Steve Anton80183062017-08-18 11:10:12 -0700108TEST_F(RtcpDemuxerTest, OnRtcpPacketCalledOnCorrectSinkBySsrc) {
eladalona52722f2017-06-26 11:23:54 -0700109 constexpr uint32_t ssrcs[] = {101, 202, 303};
110 MockRtcpPacketSink sinks[arraysize(ssrcs)];
111 for (size_t i = 0; i < arraysize(ssrcs); i++) {
Steve Anton80183062017-08-18 11:10:12 -0700112 AddSsrcSink(ssrcs[i], &sinks[i]);
eladalona52722f2017-06-26 11:23:54 -0700113 }
114
115 for (size_t i = 0; i < arraysize(ssrcs); i++) {
116 auto packet = CreateRtcpPacket(ssrcs[i]);
Steve Anton80183062017-08-18 11:10:12 -0700117 EXPECT_CALL(sinks[i], OnRtcpPacket(SamePacketAs(packet))).Times(1);
118 demuxer_.OnRtcpPacket(packet);
eladalona52722f2017-06-26 11:23:54 -0700119 }
120}
121
Steve Anton80183062017-08-18 11:10:12 -0700122TEST_F(RtcpDemuxerTest, OnRtcpPacketCalledOnResolvedRsidSink) {
eladalona52722f2017-06-26 11:23:54 -0700123 // Set up some RSID sinks.
124 const std::string rsids[] = {"a", "b", "c"};
125 MockRtcpPacketSink sinks[arraysize(rsids)];
126 for (size_t i = 0; i < arraysize(rsids); i++) {
Steve Anton80183062017-08-18 11:10:12 -0700127 AddRsidSink(rsids[i], &sinks[i]);
eladalona52722f2017-06-26 11:23:54 -0700128 }
129
130 // Only resolve one of the sinks.
131 constexpr size_t resolved_sink_index = 0;
132 constexpr uint32_t ssrc = 345;
Steve Anton80183062017-08-18 11:10:12 -0700133 demuxer_.OnSsrcBoundToRsid(rsids[resolved_sink_index], ssrc);
eladalona52722f2017-06-26 11:23:54 -0700134
135 // The resolved sink gets notifications of RTCP messages with its SSRC.
136 auto packet = CreateRtcpPacket(ssrc);
Steve Anton80183062017-08-18 11:10:12 -0700137 EXPECT_CALL(sinks[resolved_sink_index], OnRtcpPacket(SamePacketAs(packet)))
eladalona52722f2017-06-26 11:23:54 -0700138 .Times(1);
139
140 // RTCP received; expected calls triggered.
Steve Anton80183062017-08-18 11:10:12 -0700141 demuxer_.OnRtcpPacket(packet);
eladalona52722f2017-06-26 11:23:54 -0700142}
143
Steve Anton80183062017-08-18 11:10:12 -0700144TEST_F(RtcpDemuxerTest,
145 SingleCallbackAfterResolutionOfAnRsidToAlreadyRegisteredSsrc) {
eladalona52722f2017-06-26 11:23:54 -0700146 // Associate a sink with an SSRC.
147 MockRtcpPacketSink sink;
148 constexpr uint32_t ssrc = 999;
Steve Anton80183062017-08-18 11:10:12 -0700149 AddSsrcSink(ssrc, &sink);
eladalona52722f2017-06-26 11:23:54 -0700150
151 // Associate the same sink with an RSID.
152 const std::string rsid = "r";
Steve Anton80183062017-08-18 11:10:12 -0700153 AddRsidSink(rsid, &sink);
eladalona52722f2017-06-26 11:23:54 -0700154
155 // Resolve the RSID to the aforementioned SSRC.
Steve Anton80183062017-08-18 11:10:12 -0700156 demuxer_.OnSsrcBoundToRsid(rsid, ssrc);
eladalona52722f2017-06-26 11:23:54 -0700157
158 // OnRtcpPacket still called only a single time for messages with this SSRC.
159 auto packet = CreateRtcpPacket(ssrc);
Steve Anton80183062017-08-18 11:10:12 -0700160 EXPECT_CALL(sink, OnRtcpPacket(SamePacketAs(packet))).Times(1);
161 demuxer_.OnRtcpPacket(packet);
eladalona52722f2017-06-26 11:23:54 -0700162}
163
Steve Anton80183062017-08-18 11:10:12 -0700164TEST_F(RtcpDemuxerTest,
165 OnRtcpPacketCalledOnAllBroadcastSinksForAllRtcpPackets) {
eladalona52722f2017-06-26 11:23:54 -0700166 MockRtcpPacketSink sinks[3];
167 for (MockRtcpPacketSink& sink : sinks) {
Steve Anton80183062017-08-18 11:10:12 -0700168 AddBroadcastSink(&sink);
eladalona52722f2017-06-26 11:23:54 -0700169 }
170
171 constexpr uint32_t ssrc = 747;
172 auto packet = CreateRtcpPacket(ssrc);
173
174 for (MockRtcpPacketSink& sink : sinks) {
Steve Anton80183062017-08-18 11:10:12 -0700175 EXPECT_CALL(sink, OnRtcpPacket(SamePacketAs(packet))).Times(1);
eladalona52722f2017-06-26 11:23:54 -0700176 }
177
178 // RTCP received; expected calls triggered.
Steve Anton80183062017-08-18 11:10:12 -0700179 demuxer_.OnRtcpPacket(packet);
eladalona52722f2017-06-26 11:23:54 -0700180}
181
Steve Anton80183062017-08-18 11:10:12 -0700182TEST_F(RtcpDemuxerTest, PacketsDeliveredInRightOrderToNonBroadcastSink) {
eladalona52722f2017-06-26 11:23:54 -0700183 constexpr uint32_t ssrc = 101;
184 MockRtcpPacketSink sink;
Steve Anton80183062017-08-18 11:10:12 -0700185 AddSsrcSink(ssrc, &sink);
eladalona52722f2017-06-26 11:23:54 -0700186
187 std::vector<rtc::Buffer> packets;
188 for (size_t i = 0; i < 5; i++) {
189 packets.push_back(CreateRtcpPacket(ssrc, std::to_string(i)));
190 }
191
192 InSequence sequence;
193 for (const auto& packet : packets) {
Steve Anton80183062017-08-18 11:10:12 -0700194 EXPECT_CALL(sink, OnRtcpPacket(SamePacketAs(packet))).Times(1);
eladalona52722f2017-06-26 11:23:54 -0700195 }
196
197 for (const auto& packet : packets) {
Steve Anton80183062017-08-18 11:10:12 -0700198 demuxer_.OnRtcpPacket(packet);
eladalona52722f2017-06-26 11:23:54 -0700199 }
eladalona52722f2017-06-26 11:23:54 -0700200}
201
Steve Anton80183062017-08-18 11:10:12 -0700202TEST_F(RtcpDemuxerTest, PacketsDeliveredInRightOrderToBroadcastSink) {
eladalona52722f2017-06-26 11:23:54 -0700203 MockRtcpPacketSink sink;
Steve Anton80183062017-08-18 11:10:12 -0700204 AddBroadcastSink(&sink);
eladalona52722f2017-06-26 11:23:54 -0700205
206 std::vector<rtc::Buffer> packets;
207 for (size_t i = 0; i < 5; i++) {
208 constexpr uint32_t ssrc = 101;
209 packets.push_back(CreateRtcpPacket(ssrc, std::to_string(i)));
210 }
211
212 InSequence sequence;
213 for (const auto& packet : packets) {
Steve Anton80183062017-08-18 11:10:12 -0700214 EXPECT_CALL(sink, OnRtcpPacket(SamePacketAs(packet))).Times(1);
eladalona52722f2017-06-26 11:23:54 -0700215 }
216
217 for (const auto& packet : packets) {
Steve Anton80183062017-08-18 11:10:12 -0700218 demuxer_.OnRtcpPacket(packet);
eladalona52722f2017-06-26 11:23:54 -0700219 }
eladalona52722f2017-06-26 11:23:54 -0700220}
221
Steve Anton80183062017-08-18 11:10:12 -0700222TEST_F(RtcpDemuxerTest, MultipleSinksMappedToSameSsrc) {
eladalona52722f2017-06-26 11:23:54 -0700223 MockRtcpPacketSink sinks[3];
224 constexpr uint32_t ssrc = 404;
225 for (auto& sink : sinks) {
Steve Anton80183062017-08-18 11:10:12 -0700226 AddSsrcSink(ssrc, &sink);
eladalona52722f2017-06-26 11:23:54 -0700227 }
228
229 // Reception of an RTCP packet associated with the shared SSRC triggers the
230 // callback on all of the sinks associated with it.
231 auto packet = CreateRtcpPacket(ssrc);
232 for (auto& sink : sinks) {
Steve Anton80183062017-08-18 11:10:12 -0700233 EXPECT_CALL(sink, OnRtcpPacket(SamePacketAs(packet)));
eladalona52722f2017-06-26 11:23:54 -0700234 }
eladalona52722f2017-06-26 11:23:54 -0700235
Steve Anton80183062017-08-18 11:10:12 -0700236 demuxer_.OnRtcpPacket(packet);
eladalona52722f2017-06-26 11:23:54 -0700237}
238
Steve Anton80183062017-08-18 11:10:12 -0700239TEST_F(RtcpDemuxerTest, SinkMappedToMultipleSsrcs) {
eladalona52722f2017-06-26 11:23:54 -0700240 constexpr uint32_t ssrcs[] = {404, 505, 606};
241 MockRtcpPacketSink sink;
242 for (uint32_t ssrc : ssrcs) {
Steve Anton80183062017-08-18 11:10:12 -0700243 AddSsrcSink(ssrc, &sink);
eladalona52722f2017-06-26 11:23:54 -0700244 }
245
246 // The sink which is associated with multiple SSRCs gets the callback
247 // triggered for each of those SSRCs.
248 for (uint32_t ssrc : ssrcs) {
249 auto packet = CreateRtcpPacket(ssrc);
Steve Anton80183062017-08-18 11:10:12 -0700250 EXPECT_CALL(sink, OnRtcpPacket(SamePacketAs(packet)));
251 demuxer_.OnRtcpPacket(packet);
eladalona52722f2017-06-26 11:23:54 -0700252 }
eladalona52722f2017-06-26 11:23:54 -0700253}
254
Steve Anton80183062017-08-18 11:10:12 -0700255TEST_F(RtcpDemuxerTest, MultipleRsidsOnSameSink) {
eladalona52722f2017-06-26 11:23:54 -0700256 // Sink associated with multiple sinks.
257 MockRtcpPacketSink sink;
258 const std::string rsids[] = {"a", "b", "c"};
259 for (const auto& rsid : rsids) {
Steve Anton80183062017-08-18 11:10:12 -0700260 AddRsidSink(rsid, &sink);
eladalona52722f2017-06-26 11:23:54 -0700261 }
262
263 // RSIDs resolved to SSRCs.
264 uint32_t ssrcs[arraysize(rsids)];
265 for (size_t i = 0; i < arraysize(rsids); i++) {
266 ssrcs[i] = 1000 + static_cast<uint32_t>(i);
Steve Anton80183062017-08-18 11:10:12 -0700267 demuxer_.OnSsrcBoundToRsid(rsids[i], ssrcs[i]);
eladalona52722f2017-06-26 11:23:54 -0700268 }
269
270 // Set up packets to match those RSIDs/SSRCs.
271 std::vector<rtc::Buffer> packets;
272 for (size_t i = 0; i < arraysize(rsids); i++) {
273 packets.push_back(CreateRtcpPacket(ssrcs[i]));
274 }
275
276 // The sink expects to receive all of the packets.
277 for (const auto& packet : packets) {
Steve Anton80183062017-08-18 11:10:12 -0700278 EXPECT_CALL(sink, OnRtcpPacket(SamePacketAs(packet))).Times(1);
eladalona52722f2017-06-26 11:23:54 -0700279 }
280
281 // Packet demuxed correctly; OnRtcpPacket() triggered on sink.
282 for (const auto& packet : packets) {
Steve Anton80183062017-08-18 11:10:12 -0700283 demuxer_.OnRtcpPacket(packet);
eladalona52722f2017-06-26 11:23:54 -0700284 }
eladalona52722f2017-06-26 11:23:54 -0700285}
286
Steve Anton80183062017-08-18 11:10:12 -0700287TEST_F(RtcpDemuxerTest, RsidUsedByMultipleSinks) {
eladalona52722f2017-06-26 11:23:54 -0700288 MockRtcpPacketSink sinks[3];
289 const std::string shared_rsid = "a";
290
291 for (MockRtcpPacketSink& sink : sinks) {
Steve Anton80183062017-08-18 11:10:12 -0700292 AddRsidSink(shared_rsid, &sink);
eladalona52722f2017-06-26 11:23:54 -0700293 }
294
295 constexpr uint32_t shared_ssrc = 888;
Steve Anton80183062017-08-18 11:10:12 -0700296 demuxer_.OnSsrcBoundToRsid(shared_rsid, shared_ssrc);
eladalona52722f2017-06-26 11:23:54 -0700297
298 auto packet = CreateRtcpPacket(shared_ssrc);
299
300 for (MockRtcpPacketSink& sink : sinks) {
Steve Anton80183062017-08-18 11:10:12 -0700301 EXPECT_CALL(sink, OnRtcpPacket(SamePacketAs(packet))).Times(1);
eladalona52722f2017-06-26 11:23:54 -0700302 }
303
Steve Anton80183062017-08-18 11:10:12 -0700304 demuxer_.OnRtcpPacket(packet);
eladalona52722f2017-06-26 11:23:54 -0700305}
306
Steve Anton80183062017-08-18 11:10:12 -0700307TEST_F(RtcpDemuxerTest, NoCallbackOnSsrcSinkRemovedBeforeFirstPacket) {
eladalona52722f2017-06-26 11:23:54 -0700308 constexpr uint32_t ssrc = 404;
309 MockRtcpPacketSink sink;
Steve Anton80183062017-08-18 11:10:12 -0700310 AddSsrcSink(ssrc, &sink);
eladalona52722f2017-06-26 11:23:54 -0700311
Steve Anton80183062017-08-18 11:10:12 -0700312 RemoveSink(&sink);
eladalona52722f2017-06-26 11:23:54 -0700313
314 // The removed sink does not get callbacks.
315 auto packet = CreateRtcpPacket(ssrc);
316 EXPECT_CALL(sink, OnRtcpPacket(_)).Times(0); // Not called.
Steve Anton80183062017-08-18 11:10:12 -0700317 demuxer_.OnRtcpPacket(packet);
eladalona52722f2017-06-26 11:23:54 -0700318}
319
Steve Anton80183062017-08-18 11:10:12 -0700320TEST_F(RtcpDemuxerTest, NoCallbackOnSsrcSinkRemovedAfterFirstPacket) {
eladalona52722f2017-06-26 11:23:54 -0700321 constexpr uint32_t ssrc = 404;
322 NiceMock<MockRtcpPacketSink> sink;
Steve Anton80183062017-08-18 11:10:12 -0700323 AddSsrcSink(ssrc, &sink);
eladalona52722f2017-06-26 11:23:54 -0700324
325 auto before_packet = CreateRtcpPacket(ssrc);
Steve Anton80183062017-08-18 11:10:12 -0700326 demuxer_.OnRtcpPacket(before_packet);
eladalona52722f2017-06-26 11:23:54 -0700327
Steve Anton80183062017-08-18 11:10:12 -0700328 RemoveSink(&sink);
eladalona52722f2017-06-26 11:23:54 -0700329
330 // The removed sink does not get callbacks.
331 auto after_packet = CreateRtcpPacket(ssrc);
332 EXPECT_CALL(sink, OnRtcpPacket(_)).Times(0); // Not called.
Steve Anton80183062017-08-18 11:10:12 -0700333 demuxer_.OnRtcpPacket(after_packet);
eladalona52722f2017-06-26 11:23:54 -0700334}
335
Steve Anton80183062017-08-18 11:10:12 -0700336TEST_F(RtcpDemuxerTest, NoCallbackOnRsidSinkRemovedBeforeRsidResolution) {
eladalona52722f2017-06-26 11:23:54 -0700337 const std::string rsid = "a";
338 constexpr uint32_t ssrc = 404;
339 MockRtcpPacketSink sink;
Steve Anton80183062017-08-18 11:10:12 -0700340 AddRsidSink(rsid, &sink);
eladalona52722f2017-06-26 11:23:54 -0700341
342 // Removal before resolution.
Steve Anton80183062017-08-18 11:10:12 -0700343 RemoveSink(&sink);
344 demuxer_.OnSsrcBoundToRsid(rsid, ssrc);
eladalona52722f2017-06-26 11:23:54 -0700345
346 // The removed sink does not get callbacks.
347 auto packet = CreateRtcpPacket(ssrc);
348 EXPECT_CALL(sink, OnRtcpPacket(_)).Times(0); // Not called.
Steve Anton80183062017-08-18 11:10:12 -0700349 demuxer_.OnRtcpPacket(packet);
eladalona52722f2017-06-26 11:23:54 -0700350}
351
Steve Anton80183062017-08-18 11:10:12 -0700352TEST_F(RtcpDemuxerTest, NoCallbackOnRsidSinkRemovedAfterRsidResolution) {
eladalona52722f2017-06-26 11:23:54 -0700353 const std::string rsid = "a";
354 constexpr uint32_t ssrc = 404;
355 MockRtcpPacketSink sink;
Steve Anton80183062017-08-18 11:10:12 -0700356 AddRsidSink(rsid, &sink);
eladalona52722f2017-06-26 11:23:54 -0700357
358 // Removal after resolution.
Steve Anton80183062017-08-18 11:10:12 -0700359 demuxer_.OnSsrcBoundToRsid(rsid, ssrc);
360 RemoveSink(&sink);
eladalona52722f2017-06-26 11:23:54 -0700361
362 // The removed sink does not get callbacks.
363 auto packet = CreateRtcpPacket(ssrc);
364 EXPECT_CALL(sink, OnRtcpPacket(_)).Times(0); // Not called.
Steve Anton80183062017-08-18 11:10:12 -0700365 demuxer_.OnRtcpPacket(packet);
eladalona52722f2017-06-26 11:23:54 -0700366}
367
Steve Anton80183062017-08-18 11:10:12 -0700368TEST_F(RtcpDemuxerTest, NoCallbackOnBroadcastSinkRemovedBeforeFirstPacket) {
eladalona52722f2017-06-26 11:23:54 -0700369 MockRtcpPacketSink sink;
Steve Anton80183062017-08-18 11:10:12 -0700370 AddBroadcastSink(&sink);
eladalona52722f2017-06-26 11:23:54 -0700371
Steve Anton80183062017-08-18 11:10:12 -0700372 RemoveBroadcastSink(&sink);
eladalona52722f2017-06-26 11:23:54 -0700373
374 // The removed sink does not get callbacks.
375 constexpr uint32_t ssrc = 404;
376 auto packet = CreateRtcpPacket(ssrc);
377 EXPECT_CALL(sink, OnRtcpPacket(_)).Times(0); // Not called.
Steve Anton80183062017-08-18 11:10:12 -0700378 demuxer_.OnRtcpPacket(packet);
eladalona52722f2017-06-26 11:23:54 -0700379}
380
Steve Anton80183062017-08-18 11:10:12 -0700381TEST_F(RtcpDemuxerTest, NoCallbackOnBroadcastSinkRemovedAfterFirstPacket) {
eladalona52722f2017-06-26 11:23:54 -0700382 NiceMock<MockRtcpPacketSink> sink;
Steve Anton80183062017-08-18 11:10:12 -0700383 AddBroadcastSink(&sink);
eladalona52722f2017-06-26 11:23:54 -0700384
385 constexpr uint32_t ssrc = 404;
386 auto before_packet = CreateRtcpPacket(ssrc);
Steve Anton80183062017-08-18 11:10:12 -0700387 demuxer_.OnRtcpPacket(before_packet);
eladalona52722f2017-06-26 11:23:54 -0700388
Steve Anton80183062017-08-18 11:10:12 -0700389 RemoveBroadcastSink(&sink);
eladalona52722f2017-06-26 11:23:54 -0700390
391 // The removed sink does not get callbacks.
392 auto after_packet = CreateRtcpPacket(ssrc);
393 EXPECT_CALL(sink, OnRtcpPacket(_)).Times(0); // Not called.
Steve Anton80183062017-08-18 11:10:12 -0700394 demuxer_.OnRtcpPacket(after_packet);
eladalona52722f2017-06-26 11:23:54 -0700395}
396
397// The RSID to SSRC mapping should be one-to-one. If we end up receiving
398// two (or more) packets with the same SSRC, but different RSIDs, we guarantee
399// remembering the first one; no guarantees are made about further associations.
Steve Anton80183062017-08-18 11:10:12 -0700400TEST_F(RtcpDemuxerTest, FirstResolutionOfRsidNotForgotten) {
eladalona52722f2017-06-26 11:23:54 -0700401 MockRtcpPacketSink sink;
eladalona52722f2017-06-26 11:23:54 -0700402 const std::string rsid = "a";
Steve Anton80183062017-08-18 11:10:12 -0700403 AddRsidSink(rsid, &sink);
eladalona52722f2017-06-26 11:23:54 -0700404
405 constexpr uint32_t ssrc_a = 111; // First resolution - guaranteed effective.
Steve Anton80183062017-08-18 11:10:12 -0700406 demuxer_.OnSsrcBoundToRsid(rsid, ssrc_a);
eladalona52722f2017-06-26 11:23:54 -0700407
408 constexpr uint32_t ssrc_b = 222; // Second resolution - no guarantees.
Steve Anton80183062017-08-18 11:10:12 -0700409 demuxer_.OnSsrcBoundToRsid(rsid, ssrc_b);
eladalona52722f2017-06-26 11:23:54 -0700410
411 auto packet_a = CreateRtcpPacket(ssrc_a);
Steve Anton80183062017-08-18 11:10:12 -0700412 EXPECT_CALL(sink, OnRtcpPacket(SamePacketAs(packet_a))).Times(1);
413 demuxer_.OnRtcpPacket(packet_a);
eladalona52722f2017-06-26 11:23:54 -0700414
415 auto packet_b = CreateRtcpPacket(ssrc_b);
Steve Anton80183062017-08-18 11:10:12 -0700416 EXPECT_CALL(sink, OnRtcpPacket(SamePacketAs(packet_b))).Times(AtLeast(0));
417 demuxer_.OnRtcpPacket(packet_b);
eladalona52722f2017-06-26 11:23:54 -0700418}
419
420#if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
Steve Anton80183062017-08-18 11:10:12 -0700421
422TEST_F(RtcpDemuxerTest, RepeatedSsrcToSinkAssociationsDisallowed) {
eladalona52722f2017-06-26 11:23:54 -0700423 MockRtcpPacketSink sink;
424
425 constexpr uint32_t ssrc = 101;
Steve Anton80183062017-08-18 11:10:12 -0700426 AddSsrcSink(ssrc, &sink);
427 EXPECT_DEATH(AddSsrcSink(ssrc, &sink), "");
eladalona52722f2017-06-26 11:23:54 -0700428}
429
Steve Anton80183062017-08-18 11:10:12 -0700430TEST_F(RtcpDemuxerTest, RepeatedRsidToSinkAssociationsDisallowed) {
eladalona52722f2017-06-26 11:23:54 -0700431 MockRtcpPacketSink sink;
432
433 const std::string rsid = "z";
Steve Anton80183062017-08-18 11:10:12 -0700434 AddRsidSink(rsid, &sink);
435 EXPECT_DEATH(AddRsidSink(rsid, &sink), "");
eladalona52722f2017-06-26 11:23:54 -0700436}
437
Steve Anton80183062017-08-18 11:10:12 -0700438TEST_F(RtcpDemuxerTest, RepeatedBroadcastSinkRegistrationDisallowed) {
eladalona52722f2017-06-26 11:23:54 -0700439 MockRtcpPacketSink sink;
440
Steve Anton80183062017-08-18 11:10:12 -0700441 AddBroadcastSink(&sink);
442 EXPECT_DEATH(AddBroadcastSink(&sink), "");
eladalona52722f2017-06-26 11:23:54 -0700443}
444
Steve Anton80183062017-08-18 11:10:12 -0700445TEST_F(RtcpDemuxerTest, SsrcSinkCannotAlsoBeRegisteredAsBroadcast) {
eladalona52722f2017-06-26 11:23:54 -0700446 MockRtcpPacketSink sink;
447
448 constexpr uint32_t ssrc = 101;
Steve Anton80183062017-08-18 11:10:12 -0700449 AddSsrcSink(ssrc, &sink);
450 EXPECT_DEATH(AddBroadcastSink(&sink), "");
eladalona52722f2017-06-26 11:23:54 -0700451}
452
Steve Anton80183062017-08-18 11:10:12 -0700453TEST_F(RtcpDemuxerTest, RsidSinkCannotAlsoBeRegisteredAsBroadcast) {
eladalona52722f2017-06-26 11:23:54 -0700454 MockRtcpPacketSink sink;
455
456 const std::string rsid = "z";
Steve Anton80183062017-08-18 11:10:12 -0700457 AddRsidSink(rsid, &sink);
458 EXPECT_DEATH(AddBroadcastSink(&sink), "");
eladalona52722f2017-06-26 11:23:54 -0700459}
460
Steve Anton80183062017-08-18 11:10:12 -0700461TEST_F(RtcpDemuxerTest, BroadcastSinkCannotAlsoBeRegisteredAsSsrcSink) {
eladalona52722f2017-06-26 11:23:54 -0700462 MockRtcpPacketSink sink;
463
Steve Anton80183062017-08-18 11:10:12 -0700464 AddBroadcastSink(&sink);
eladalona52722f2017-06-26 11:23:54 -0700465 constexpr uint32_t ssrc = 101;
Steve Anton80183062017-08-18 11:10:12 -0700466 EXPECT_DEATH(AddSsrcSink(ssrc, &sink), "");
eladalona52722f2017-06-26 11:23:54 -0700467}
468
Steve Anton80183062017-08-18 11:10:12 -0700469TEST_F(RtcpDemuxerTest, BroadcastSinkCannotAlsoBeRegisteredAsRsidSink) {
eladalona52722f2017-06-26 11:23:54 -0700470 MockRtcpPacketSink sink;
471
Steve Anton80183062017-08-18 11:10:12 -0700472 AddBroadcastSink(&sink);
eladalona52722f2017-06-26 11:23:54 -0700473 const std::string rsid = "j";
Steve Anton80183062017-08-18 11:10:12 -0700474 EXPECT_DEATH(AddRsidSink(rsid, &sink), "");
eladalona52722f2017-06-26 11:23:54 -0700475}
476
Steve Anton80183062017-08-18 11:10:12 -0700477TEST_F(RtcpDemuxerTest, MayNotCallRemoveSinkOnNeverAddedSink) {
eladalona52722f2017-06-26 11:23:54 -0700478 MockRtcpPacketSink sink;
Steve Anton80183062017-08-18 11:10:12 -0700479 EXPECT_DEATH(RemoveSink(&sink), "");
eladalona52722f2017-06-26 11:23:54 -0700480}
481
Steve Anton80183062017-08-18 11:10:12 -0700482TEST_F(RtcpDemuxerTest, MayNotCallRemoveBroadcastSinkOnNeverAddedSink) {
eladalona52722f2017-06-26 11:23:54 -0700483 MockRtcpPacketSink sink;
Steve Anton80183062017-08-18 11:10:12 -0700484 EXPECT_DEATH(RemoveBroadcastSink(&sink), "");
eladalona52722f2017-06-26 11:23:54 -0700485}
486
Steve Anton80183062017-08-18 11:10:12 -0700487TEST_F(RtcpDemuxerTest, RsidMustBeNonEmpty) {
eladalona52722f2017-06-26 11:23:54 -0700488 MockRtcpPacketSink sink;
Steve Anton80183062017-08-18 11:10:12 -0700489 EXPECT_DEATH(AddRsidSink("", &sink), "");
eladalona52722f2017-06-26 11:23:54 -0700490}
491
Steve Anton80183062017-08-18 11:10:12 -0700492TEST_F(RtcpDemuxerTest, RsidMustBeAlphaNumeric) {
eladalona52722f2017-06-26 11:23:54 -0700493 MockRtcpPacketSink sink;
Steve Anton80183062017-08-18 11:10:12 -0700494 EXPECT_DEATH(AddRsidSink("a_3", &sink), "");
eladalona52722f2017-06-26 11:23:54 -0700495}
496
Steve Anton80183062017-08-18 11:10:12 -0700497TEST_F(RtcpDemuxerTest, RsidMustNotExceedMaximumLength) {
eladalona52722f2017-06-26 11:23:54 -0700498 MockRtcpPacketSink sink;
Niels Möllerd57efc12019-03-22 14:02:11 +0100499 std::string rsid(BaseRtpStringExtension::kMaxValueSizeBytes + 1, 'a');
Steve Anton80183062017-08-18 11:10:12 -0700500 EXPECT_DEATH(AddRsidSink(rsid, &sink), "");
eladalona52722f2017-06-26 11:23:54 -0700501}
Steve Anton80183062017-08-18 11:10:12 -0700502
eladalona52722f2017-06-26 11:23:54 -0700503#endif
Steve Anton80183062017-08-18 11:10:12 -0700504
eladalona52722f2017-06-26 11:23:54 -0700505} // namespace webrtc