1 /*
2 * Copyright (c) 2016 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 "modules/rtp_rtcp/source/rtcp_packet/compound_packet.h"
12
13 #include <memory>
14 #include <utility>
15
16 #include "modules/rtp_rtcp/source/rtcp_packet.h"
17 #include "modules/rtp_rtcp/source/rtcp_packet/bye.h"
18 #include "modules/rtp_rtcp/source/rtcp_packet/fir.h"
19 #include "modules/rtp_rtcp/source/rtcp_packet/receiver_report.h"
20 #include "modules/rtp_rtcp/source/rtcp_packet/sender_report.h"
21 #include "test/gmock.h"
22 #include "test/gtest.h"
23 #include "test/rtcp_packet_parser.h"
24
25 using ::testing::_;
26 using ::testing::Invoke;
27 using ::testing::MockFunction;
28 using webrtc::rtcp::Bye;
29 using webrtc::rtcp::CompoundPacket;
30 using webrtc::rtcp::Fir;
31 using webrtc::rtcp::ReceiverReport;
32 using webrtc::rtcp::ReportBlock;
33 using webrtc::rtcp::SenderReport;
34 using webrtc::test::RtcpPacketParser;
35
36 namespace webrtc {
37
38 const uint32_t kSenderSsrc = 0x12345678;
39 const uint32_t kRemoteSsrc = 0x23456789;
40 const uint8_t kSeqNo = 13;
41
TEST(RtcpCompoundPacketTest,AppendPacket)42 TEST(RtcpCompoundPacketTest, AppendPacket) {
43 CompoundPacket compound;
44 auto fir = std::make_unique<Fir>();
45 fir->AddRequestTo(kRemoteSsrc, kSeqNo);
46 ReportBlock rb;
47 auto rr = std::make_unique<ReceiverReport>();
48 rr->SetSenderSsrc(kSenderSsrc);
49 EXPECT_TRUE(rr->AddReportBlock(rb));
50 compound.Append(std::move(rr));
51 compound.Append(std::move(fir));
52
53 rtc::Buffer packet = compound.Build();
54 RtcpPacketParser parser;
55 parser.Parse(packet.data(), packet.size());
56 EXPECT_EQ(1, parser.receiver_report()->num_packets());
57 EXPECT_EQ(kSenderSsrc, parser.receiver_report()->sender_ssrc());
58 EXPECT_EQ(1u, parser.receiver_report()->report_blocks().size());
59 EXPECT_EQ(1, parser.fir()->num_packets());
60 }
61
TEST(RtcpCompoundPacketTest,AppendPacketWithOwnAppendedPacket)62 TEST(RtcpCompoundPacketTest, AppendPacketWithOwnAppendedPacket) {
63 CompoundPacket root;
64 auto leaf = std::make_unique<CompoundPacket>();
65
66 auto fir = std::make_unique<Fir>();
67 fir->AddRequestTo(kRemoteSsrc, kSeqNo);
68 auto bye = std::make_unique<Bye>();
69 ReportBlock rb;
70
71 auto rr = std::make_unique<ReceiverReport>();
72 EXPECT_TRUE(rr->AddReportBlock(rb));
73 leaf->Append(std::move(rr));
74 leaf->Append(std::move(fir));
75
76 auto sr = std::make_unique<SenderReport>();
77 root.Append(std::move(sr));
78 root.Append(std::move(bye));
79 root.Append(std::move(leaf));
80
81 rtc::Buffer packet = root.Build();
82 RtcpPacketParser parser;
83 parser.Parse(packet.data(), packet.size());
84 EXPECT_EQ(1, parser.sender_report()->num_packets());
85 EXPECT_EQ(1, parser.receiver_report()->num_packets());
86 EXPECT_EQ(1u, parser.receiver_report()->report_blocks().size());
87 EXPECT_EQ(1, parser.bye()->num_packets());
88 EXPECT_EQ(1, parser.fir()->num_packets());
89 }
90
TEST(RtcpCompoundPacketTest,BuildWithInputBuffer)91 TEST(RtcpCompoundPacketTest, BuildWithInputBuffer) {
92 CompoundPacket compound;
93 auto fir = std::make_unique<Fir>();
94 fir->AddRequestTo(kRemoteSsrc, kSeqNo);
95 ReportBlock rb;
96 auto rr = std::make_unique<ReceiverReport>();
97 rr->SetSenderSsrc(kSenderSsrc);
98 EXPECT_TRUE(rr->AddReportBlock(rb));
99 compound.Append(std::move(rr));
100 compound.Append(std::move(fir));
101
102 const size_t kRrLength = 8;
103 const size_t kReportBlockLength = 24;
104 const size_t kFirLength = 20;
105
106 const size_t kBufferSize = kRrLength + kReportBlockLength + kFirLength;
107 MockFunction<void(rtc::ArrayView<const uint8_t>)> callback;
108 EXPECT_CALL(callback, Call(_))
109 .WillOnce(Invoke([&](rtc::ArrayView<const uint8_t> packet) {
110 RtcpPacketParser parser;
111 parser.Parse(packet.data(), packet.size());
112 EXPECT_EQ(1, parser.receiver_report()->num_packets());
113 EXPECT_EQ(1u, parser.receiver_report()->report_blocks().size());
114 EXPECT_EQ(1, parser.fir()->num_packets());
115 }));
116
117 EXPECT_TRUE(compound.Build(kBufferSize, callback.AsStdFunction()));
118 }
119
TEST(RtcpCompoundPacketTest,BuildWithTooSmallBuffer_FragmentedSend)120 TEST(RtcpCompoundPacketTest, BuildWithTooSmallBuffer_FragmentedSend) {
121 CompoundPacket compound;
122 auto fir = std::make_unique<Fir>();
123 fir->AddRequestTo(kRemoteSsrc, kSeqNo);
124 ReportBlock rb;
125 auto rr = std::make_unique<ReceiverReport>();
126 rr->SetSenderSsrc(kSenderSsrc);
127 EXPECT_TRUE(rr->AddReportBlock(rb));
128 compound.Append(std::move(rr));
129 compound.Append(std::move(fir));
130
131 const size_t kRrLength = 8;
132 const size_t kReportBlockLength = 24;
133
134 const size_t kBufferSize = kRrLength + kReportBlockLength;
135 MockFunction<void(rtc::ArrayView<const uint8_t>)> callback;
136 EXPECT_CALL(callback, Call(_))
137 .WillOnce(Invoke([&](rtc::ArrayView<const uint8_t> packet) {
138 RtcpPacketParser parser;
139 parser.Parse(packet.data(), packet.size());
140 EXPECT_EQ(1, parser.receiver_report()->num_packets());
141 EXPECT_EQ(1U, parser.receiver_report()->report_blocks().size());
142 EXPECT_EQ(0, parser.fir()->num_packets());
143 }))
144 .WillOnce(Invoke([&](rtc::ArrayView<const uint8_t> packet) {
145 RtcpPacketParser parser;
146 parser.Parse(packet.data(), packet.size());
147 EXPECT_EQ(0, parser.receiver_report()->num_packets());
148 EXPECT_EQ(0U, parser.receiver_report()->report_blocks().size());
149 EXPECT_EQ(1, parser.fir()->num_packets());
150 }));
151
152 EXPECT_TRUE(compound.Build(kBufferSize, callback.AsStdFunction()));
153 }
154
155 } // namespace webrtc
156