1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "media/cast/net/rtcp/test_rtcp_packet_builder.h"
7 #include "base/logging.h"
8 #include "media/cast/net/rtcp/rtcp_utility.h"
13 TestRtcpPacketBuilder::TestRtcpPacketBuilder()
14 : ptr_of_length_(NULL
),
15 big_endian_writer_(reinterpret_cast<char*>(buffer_
), kMaxIpPacketSize
),
16 big_endian_reader_(NULL
, 0) {}
18 void TestRtcpPacketBuilder::AddSr(uint32 sender_ssrc
,
19 int number_of_report_blocks
) {
20 AddRtcpHeader(200, number_of_report_blocks
);
21 big_endian_writer_
.WriteU32(sender_ssrc
);
22 big_endian_writer_
.WriteU32(kNtpHigh
); // NTP timestamp.
23 big_endian_writer_
.WriteU32(kNtpLow
);
24 big_endian_writer_
.WriteU32(kRtpTimestamp
);
25 big_endian_writer_
.WriteU32(kSendPacketCount
);
26 big_endian_writer_
.WriteU32(kSendOctetCount
);
29 void TestRtcpPacketBuilder::AddSrWithNtp(uint32 sender_ssrc
,
32 uint32 rtp_timestamp
) {
33 AddRtcpHeader(200, 0);
34 big_endian_writer_
.WriteU32(sender_ssrc
);
35 big_endian_writer_
.WriteU32(ntp_high
);
36 big_endian_writer_
.WriteU32(ntp_low
);
37 big_endian_writer_
.WriteU32(rtp_timestamp
);
38 big_endian_writer_
.WriteU32(kSendPacketCount
);
39 big_endian_writer_
.WriteU32(kSendOctetCount
);
42 void TestRtcpPacketBuilder::AddRr(uint32 sender_ssrc
,
43 int number_of_report_blocks
) {
44 AddRtcpHeader(201, number_of_report_blocks
);
45 big_endian_writer_
.WriteU32(sender_ssrc
);
48 void TestRtcpPacketBuilder::AddRb(uint32 rtp_ssrc
) {
49 big_endian_writer_
.WriteU32(rtp_ssrc
);
50 big_endian_writer_
.WriteU32(kLoss
);
51 big_endian_writer_
.WriteU32(kExtendedMax
);
52 big_endian_writer_
.WriteU32(kTestJitter
);
53 big_endian_writer_
.WriteU32(kLastSr
);
54 big_endian_writer_
.WriteU32(kDelayLastSr
);
57 void TestRtcpPacketBuilder::AddXrHeader(uint32 sender_ssrc
) {
58 AddRtcpHeader(207, 0);
59 big_endian_writer_
.WriteU32(sender_ssrc
);
62 void TestRtcpPacketBuilder::AddXrUnknownBlock() {
63 big_endian_writer_
.WriteU8(9); // Block type.
64 big_endian_writer_
.WriteU8(0); // Reserved.
65 big_endian_writer_
.WriteU16(4); // Block length.
66 // First receiver same as sender of this report.
67 big_endian_writer_
.WriteU32(0);
68 big_endian_writer_
.WriteU32(0);
69 big_endian_writer_
.WriteU32(0);
70 big_endian_writer_
.WriteU32(0);
73 void TestRtcpPacketBuilder::AddUnknownBlock() {
75 big_endian_writer_
.WriteU32(42);
76 big_endian_writer_
.WriteU32(42);
77 big_endian_writer_
.WriteU32(42);
80 void TestRtcpPacketBuilder::AddXrDlrrBlock(uint32 sender_ssrc
) {
81 big_endian_writer_
.WriteU8(5); // Block type.
82 big_endian_writer_
.WriteU8(0); // Reserved.
83 big_endian_writer_
.WriteU16(3); // Block length.
85 // First receiver same as sender of this report.
86 big_endian_writer_
.WriteU32(sender_ssrc
);
87 big_endian_writer_
.WriteU32(kLastRr
);
88 big_endian_writer_
.WriteU32(kDelayLastRr
);
91 void TestRtcpPacketBuilder::AddXrExtendedDlrrBlock(uint32 sender_ssrc
) {
92 big_endian_writer_
.WriteU8(5); // Block type.
93 big_endian_writer_
.WriteU8(0); // Reserved.
94 big_endian_writer_
.WriteU16(9); // Block length.
95 big_endian_writer_
.WriteU32(0xaaaaaaaa);
96 big_endian_writer_
.WriteU32(0xaaaaaaaa);
97 big_endian_writer_
.WriteU32(0xaaaaaaaa);
99 // First receiver same as sender of this report.
100 big_endian_writer_
.WriteU32(sender_ssrc
);
101 big_endian_writer_
.WriteU32(kLastRr
);
102 big_endian_writer_
.WriteU32(kDelayLastRr
);
103 big_endian_writer_
.WriteU32(0xbbbbbbbb);
104 big_endian_writer_
.WriteU32(0xbbbbbbbb);
105 big_endian_writer_
.WriteU32(0xbbbbbbbb);
108 void TestRtcpPacketBuilder::AddXrRrtrBlock() {
109 big_endian_writer_
.WriteU8(4); // Block type.
110 big_endian_writer_
.WriteU8(0); // Reserved.
111 big_endian_writer_
.WriteU16(2); // Block length.
112 big_endian_writer_
.WriteU32(kNtpHigh
);
113 big_endian_writer_
.WriteU32(kNtpLow
);
116 void TestRtcpPacketBuilder::AddNack(uint32 sender_ssrc
, uint32 media_ssrc
) {
117 AddRtcpHeader(205, 1);
118 big_endian_writer_
.WriteU32(sender_ssrc
);
119 big_endian_writer_
.WriteU32(media_ssrc
);
120 big_endian_writer_
.WriteU16(kMissingPacket
);
121 big_endian_writer_
.WriteU16(0);
124 void TestRtcpPacketBuilder::AddSendReportRequest(uint32 sender_ssrc
,
126 AddRtcpHeader(205, 5);
127 big_endian_writer_
.WriteU32(sender_ssrc
);
128 big_endian_writer_
.WriteU32(media_ssrc
);
131 void TestRtcpPacketBuilder::AddCast(uint32 sender_ssrc
,
133 base::TimeDelta target_delay
) {
134 AddRtcpHeader(206, 15);
135 big_endian_writer_
.WriteU32(sender_ssrc
);
136 big_endian_writer_
.WriteU32(media_ssrc
);
137 big_endian_writer_
.WriteU8('C');
138 big_endian_writer_
.WriteU8('A');
139 big_endian_writer_
.WriteU8('S');
140 big_endian_writer_
.WriteU8('T');
141 big_endian_writer_
.WriteU8(kAckFrameId
);
142 big_endian_writer_
.WriteU8(3); // Loss fields.
143 big_endian_writer_
.WriteU16(target_delay
.InMilliseconds());
144 big_endian_writer_
.WriteU8(kLostFrameId
);
145 big_endian_writer_
.WriteU16(kRtcpCastAllPacketsLost
);
146 big_endian_writer_
.WriteU8(0); // Lost packet id mask.
147 big_endian_writer_
.WriteU8(kFrameIdWithLostPackets
);
148 big_endian_writer_
.WriteU16(kLostPacketId1
);
149 big_endian_writer_
.WriteU8(0x2); // Lost packet id mask.
150 big_endian_writer_
.WriteU8(kFrameIdWithLostPackets
);
151 big_endian_writer_
.WriteU16(kLostPacketId3
);
152 big_endian_writer_
.WriteU8(0); // Lost packet id mask.
155 void TestRtcpPacketBuilder::AddReceiverLog(uint32 sender_ssrc
) {
156 AddRtcpHeader(204, 2);
157 big_endian_writer_
.WriteU32(sender_ssrc
);
158 big_endian_writer_
.WriteU8('C');
159 big_endian_writer_
.WriteU8('A');
160 big_endian_writer_
.WriteU8('S');
161 big_endian_writer_
.WriteU8('T');
164 void TestRtcpPacketBuilder::AddReceiverFrameLog(uint32 rtp_timestamp
,
166 uint32 event_timesamp_base
) {
167 big_endian_writer_
.WriteU32(rtp_timestamp
);
168 big_endian_writer_
.WriteU8(static_cast<uint8
>(num_events
- 1));
169 big_endian_writer_
.WriteU8(static_cast<uint8
>(event_timesamp_base
>> 16));
170 big_endian_writer_
.WriteU8(static_cast<uint8
>(event_timesamp_base
>> 8));
171 big_endian_writer_
.WriteU8(static_cast<uint8
>(event_timesamp_base
));
174 void TestRtcpPacketBuilder::AddReceiverEventLog(uint16 event_data
,
175 CastLoggingEvent event
,
176 uint16 event_timesamp_delta
) {
177 big_endian_writer_
.WriteU16(event_data
);
178 uint8 event_id
= ConvertEventTypeToWireFormat(event
);
179 uint16 type_and_delta
= static_cast<uint16
>(event_id
) << 12;
180 type_and_delta
+= event_timesamp_delta
& 0x0fff;
181 big_endian_writer_
.WriteU16(type_and_delta
);
184 scoped_ptr
<media::cast::Packet
> TestRtcpPacketBuilder::GetPacket() {
186 return scoped_ptr
<media::cast::Packet
>(
187 new media::cast::Packet(buffer_
, buffer_
+ Length()));
190 const uint8
* TestRtcpPacketBuilder::Data() {
195 base::BigEndianReader
* TestRtcpPacketBuilder::Reader() {
196 big_endian_reader_
= base::BigEndianReader(
197 reinterpret_cast<const char *>(Data()), Length());
198 return &big_endian_reader_
;
201 void TestRtcpPacketBuilder::PatchLengthField() {
202 if (ptr_of_length_
) {
203 // Back-patch the packet length. The client must have taken
204 // care of proper padding to 32-bit words.
205 int this_packet_length
= (big_endian_writer_
.ptr() - ptr_of_length_
- 2);
206 DCHECK_EQ(0, this_packet_length
% 4)
207 << "Packets must be a multiple of 32 bits long";
208 *ptr_of_length_
= this_packet_length
>> 10;
209 *(ptr_of_length_
+ 1) = (this_packet_length
>> 2) & 0xFF;
210 ptr_of_length_
= NULL
;
214 // Set the 5-bit value in the 1st byte of the header
215 // and the payload type. Set aside room for the length field,
216 // and make provision for back-patching it.
217 void TestRtcpPacketBuilder::AddRtcpHeader(int payload
, int format_or_count
) {
219 big_endian_writer_
.WriteU8(0x80 | (format_or_count
& 0x1F));
220 big_endian_writer_
.WriteU8(payload
);
221 ptr_of_length_
= big_endian_writer_
.ptr();
223 // Initialize length to "clearly illegal".
224 big_endian_writer_
.WriteU16(0xDEAD);