xref: /aosp_15_r20/external/openscreen/cast/streaming/packet_util_unittest.cc (revision 3f982cf4871df8771c9d4abe6e9a6f8d829b2736)
1*3f982cf4SFabien Sanglard // Copyright 2019 The Chromium Authors. All rights reserved.
2*3f982cf4SFabien Sanglard // Use of this source code is governed by a BSD-style license that can be
3*3f982cf4SFabien Sanglard // found in the LICENSE file.
4*3f982cf4SFabien Sanglard 
5*3f982cf4SFabien Sanglard #include "cast/streaming/packet_util.h"
6*3f982cf4SFabien Sanglard 
7*3f982cf4SFabien Sanglard #include "absl/types/span.h"
8*3f982cf4SFabien Sanglard #include "gtest/gtest.h"
9*3f982cf4SFabien Sanglard 
10*3f982cf4SFabien Sanglard namespace openscreen {
11*3f982cf4SFabien Sanglard namespace cast {
12*3f982cf4SFabien Sanglard namespace {
13*3f982cf4SFabien Sanglard 
14*3f982cf4SFabien Sanglard // Tests that a simple RTCP packet containing only a Sender Report can be
15*3f982cf4SFabien Sanglard // identified.
TEST(PacketUtilTest,InspectsRtcpPacketFromSender)16*3f982cf4SFabien Sanglard TEST(PacketUtilTest, InspectsRtcpPacketFromSender) {
17*3f982cf4SFabien Sanglard   // clang-format off
18*3f982cf4SFabien Sanglard   const uint8_t kSenderReportPacket[] = {
19*3f982cf4SFabien Sanglard     0b10000000,  // Version=2, Padding=no, ItemCount=0.
20*3f982cf4SFabien Sanglard     200,  // RTCP Packet type.
21*3f982cf4SFabien Sanglard     0x00, 0x06,  // Length of remainder of packet, in 32-bit words.
22*3f982cf4SFabien Sanglard     1, 2, 3, 4,  // SSRC of sender.
23*3f982cf4SFabien Sanglard     0xe0, 0x73, 0x2e, 0x54,  // NTP Timestamp (late evening on 2019-04-30).
24*3f982cf4SFabien Sanglard         0x80, 0x00, 0x00, 0x00,
25*3f982cf4SFabien Sanglard     0x00, 0x14, 0x99, 0x70,  // RTP Timestamp (15 seconds, 90kHz timebase).
26*3f982cf4SFabien Sanglard     0x00, 0x00, 0x01, 0xff,  // Sender's Packet Count.
27*3f982cf4SFabien Sanglard     0x00, 0x07, 0x11, 0x0d,  // Sender's Octet Count.
28*3f982cf4SFabien Sanglard   };
29*3f982cf4SFabien Sanglard   // clang-format on
30*3f982cf4SFabien Sanglard   const Ssrc kSenderSsrc = 0x01020304;
31*3f982cf4SFabien Sanglard 
32*3f982cf4SFabien Sanglard   const auto result = InspectPacketForRouting(kSenderReportPacket);
33*3f982cf4SFabien Sanglard   EXPECT_EQ(ApparentPacketType::RTCP, result.first);
34*3f982cf4SFabien Sanglard   EXPECT_EQ(kSenderSsrc, result.second);
35*3f982cf4SFabien Sanglard }
36*3f982cf4SFabien Sanglard 
37*3f982cf4SFabien Sanglard // Tests that compound RTCP packets containing a Receiver Report and/or a Cast
38*3f982cf4SFabien Sanglard // Feedback message can be identified.
TEST(PacketUtilTest,InspectsRtcpPacketFromReceiver)39*3f982cf4SFabien Sanglard TEST(PacketUtilTest, InspectsRtcpPacketFromReceiver) {
40*3f982cf4SFabien Sanglard   // clang-format off
41*3f982cf4SFabien Sanglard   const uint8_t kReceiverReportPacket[] = {
42*3f982cf4SFabien Sanglard     0b10000001,  // Version=2, Padding=no, ItemCount=1.
43*3f982cf4SFabien Sanglard     201,  // RTCP Packet type.
44*3f982cf4SFabien Sanglard     0x00, 0x01,  // Length of remainder of packet, in 32-bit words.
45*3f982cf4SFabien Sanglard     9, 8, 7, 6,  // SSRC of receiver.
46*3f982cf4SFabien Sanglard   };
47*3f982cf4SFabien Sanglard   const uint8_t kCastFeedbackPacket[] = {
48*3f982cf4SFabien Sanglard     // Cast Feedback
49*3f982cf4SFabien Sanglard     0b10000000 | 15,  // Version=2, Padding=no, Subtype=15.
50*3f982cf4SFabien Sanglard     206,  // RTCP Packet type byte.
51*3f982cf4SFabien Sanglard     0x00, 0x04,  // Length of remainder of packet, in 32-bit words.
52*3f982cf4SFabien Sanglard     9, 8, 7, 6,  // SSRC of receiver.
53*3f982cf4SFabien Sanglard     1, 2, 3, 4,  // SSRC of sender.
54*3f982cf4SFabien Sanglard     'C', 'A', 'S', 'T',
55*3f982cf4SFabien Sanglard     0x0a,  // Checkpoint Frame ID (lower 8 bits).
56*3f982cf4SFabien Sanglard     0x00,  // Number of "Loss Fields"
57*3f982cf4SFabien Sanglard     0x00, 0x28,  // Current Playout Delay in milliseconds.
58*3f982cf4SFabien Sanglard   };
59*3f982cf4SFabien Sanglard   // clang-format on
60*3f982cf4SFabien Sanglard   const Ssrc kReceiverSsrc = 0x09080706;
61*3f982cf4SFabien Sanglard 
62*3f982cf4SFabien Sanglard   {
63*3f982cf4SFabien Sanglard     const auto result = InspectPacketForRouting(kReceiverReportPacket);
64*3f982cf4SFabien Sanglard     EXPECT_EQ(ApparentPacketType::RTCP, result.first);
65*3f982cf4SFabien Sanglard     EXPECT_EQ(kReceiverSsrc, result.second);
66*3f982cf4SFabien Sanglard   }
67*3f982cf4SFabien Sanglard 
68*3f982cf4SFabien Sanglard   {
69*3f982cf4SFabien Sanglard     const auto result = InspectPacketForRouting(kCastFeedbackPacket);
70*3f982cf4SFabien Sanglard     EXPECT_EQ(ApparentPacketType::RTCP, result.first);
71*3f982cf4SFabien Sanglard     EXPECT_EQ(kReceiverSsrc, result.second);
72*3f982cf4SFabien Sanglard   }
73*3f982cf4SFabien Sanglard 
74*3f982cf4SFabien Sanglard   const absl::Span<const uint8_t> kCompoundCombinations[2][2] = {
75*3f982cf4SFabien Sanglard       {kReceiverReportPacket, kCastFeedbackPacket},
76*3f982cf4SFabien Sanglard       {kCastFeedbackPacket, kReceiverReportPacket},
77*3f982cf4SFabien Sanglard   };
78*3f982cf4SFabien Sanglard   for (const auto& combo : kCompoundCombinations) {
79*3f982cf4SFabien Sanglard     uint8_t compound_packet[sizeof(kReceiverReportPacket) +
80*3f982cf4SFabien Sanglard                             sizeof(kCastFeedbackPacket)];
81*3f982cf4SFabien Sanglard     memcpy(compound_packet, combo[0].data(), combo[0].size());
82*3f982cf4SFabien Sanglard     memcpy(compound_packet + combo[0].size(), combo[1].data(), combo[1].size());
83*3f982cf4SFabien Sanglard 
84*3f982cf4SFabien Sanglard     const auto result = InspectPacketForRouting(compound_packet);
85*3f982cf4SFabien Sanglard     EXPECT_EQ(ApparentPacketType::RTCP, result.first);
86*3f982cf4SFabien Sanglard     EXPECT_EQ(kReceiverSsrc, result.second);
87*3f982cf4SFabien Sanglard   }
88*3f982cf4SFabien Sanglard }
89*3f982cf4SFabien Sanglard 
90*3f982cf4SFabien Sanglard // Tests that a RTP packet can be identified.
TEST(PacketUtilTest,InspectsRtpPacket)91*3f982cf4SFabien Sanglard TEST(PacketUtilTest, InspectsRtpPacket) {
92*3f982cf4SFabien Sanglard   // clang-format off
93*3f982cf4SFabien Sanglard   const uint8_t kInput[] = {
94*3f982cf4SFabien Sanglard     0b10000000,  // Version/Padding byte.
95*3f982cf4SFabien Sanglard     96,  // Payload type byte.
96*3f982cf4SFabien Sanglard     0xbe, 0xef,  // Sequence number.
97*3f982cf4SFabien Sanglard     9, 8, 7, 6,  // RTP timestamp.
98*3f982cf4SFabien Sanglard     1, 2, 3, 4,  // SSRC.
99*3f982cf4SFabien Sanglard     0b10000000,  // Is key frame, no extensions.
100*3f982cf4SFabien Sanglard     5,  // Frame ID.
101*3f982cf4SFabien Sanglard     0xa, 0xb,  // Packet ID.
102*3f982cf4SFabien Sanglard     0xa, 0xc,  // Max packet ID.
103*3f982cf4SFabien Sanglard     0xf, 0xe, 0xd, 0xc, 0xb, 0xa, 0x9, 0x8,  // Payload.
104*3f982cf4SFabien Sanglard   };
105*3f982cf4SFabien Sanglard   // clang-format on
106*3f982cf4SFabien Sanglard   const Ssrc kSenderSsrc = 0x01020304;
107*3f982cf4SFabien Sanglard 
108*3f982cf4SFabien Sanglard   const auto result = InspectPacketForRouting(kInput);
109*3f982cf4SFabien Sanglard   EXPECT_EQ(ApparentPacketType::RTP, result.first);
110*3f982cf4SFabien Sanglard   EXPECT_EQ(kSenderSsrc, result.second);
111*3f982cf4SFabien Sanglard }
112*3f982cf4SFabien Sanglard 
113*3f982cf4SFabien Sanglard // Tests that a RTP packet with the "127 payload type" hack can be identified as
114*3f982cf4SFabien Sanglard // valid. See comments in rtp_defines.h for the RtpPayloadType enum definition,
115*3f982cf4SFabien Sanglard // for further details.
TEST(PacketUtilTest,InspectsAndroidAudioRtpPacket)116*3f982cf4SFabien Sanglard TEST(PacketUtilTest, InspectsAndroidAudioRtpPacket) {
117*3f982cf4SFabien Sanglard   // clang-format off
118*3f982cf4SFabien Sanglard   const uint8_t kInput[] = {
119*3f982cf4SFabien Sanglard     0b10000000,  // Version/Padding byte.
120*3f982cf4SFabien Sanglard     127,  // Payload type byte.
121*3f982cf4SFabien Sanglard     0xbe, 0xef,  // Sequence number.
122*3f982cf4SFabien Sanglard     9, 8, 7, 6,  // RTP timestamp.
123*3f982cf4SFabien Sanglard     1, 2, 3, 4,  // SSRC.
124*3f982cf4SFabien Sanglard     0b10000000,  // Is key frame, no extensions.
125*3f982cf4SFabien Sanglard     5,  // Frame ID.
126*3f982cf4SFabien Sanglard     0xa, 0xb,  // Packet ID.
127*3f982cf4SFabien Sanglard     0xa, 0xc,  // Max packet ID.
128*3f982cf4SFabien Sanglard     0xf, 0xe, 0xd, 0xc, 0xb, 0xa, 0x9, 0x8,  // Payload.
129*3f982cf4SFabien Sanglard   };
130*3f982cf4SFabien Sanglard   // clang-format on
131*3f982cf4SFabien Sanglard   const Ssrc kSenderSsrc = 0x01020304;
132*3f982cf4SFabien Sanglard 
133*3f982cf4SFabien Sanglard   const auto result = InspectPacketForRouting(kInput);
134*3f982cf4SFabien Sanglard   EXPECT_EQ(ApparentPacketType::RTP, result.first);
135*3f982cf4SFabien Sanglard   EXPECT_EQ(kSenderSsrc, result.second);
136*3f982cf4SFabien Sanglard }
137*3f982cf4SFabien Sanglard 
138*3f982cf4SFabien Sanglard // Tests that a malformed RTP packet can be identified.
TEST(PacketUtilTest,InspectsMalformedRtpPacket)139*3f982cf4SFabien Sanglard TEST(PacketUtilTest, InspectsMalformedRtpPacket) {
140*3f982cf4SFabien Sanglard   // clang-format off
141*3f982cf4SFabien Sanglard   const uint8_t kInput[] = {
142*3f982cf4SFabien Sanglard     0b11000000,  // BAD: Version/Padding byte.
143*3f982cf4SFabien Sanglard     96,  // Payload type byte.
144*3f982cf4SFabien Sanglard     0xbe, 0xef,  // Sequence number.
145*3f982cf4SFabien Sanglard     9, 8, 7, 6,  // RTP timestamp.
146*3f982cf4SFabien Sanglard     1, 2, 3, 4,  // SSRC.
147*3f982cf4SFabien Sanglard     0b10000000,  // Is key frame, no extensions.
148*3f982cf4SFabien Sanglard     5,  // Frame ID.
149*3f982cf4SFabien Sanglard     0xa, 0xb,  // Packet ID.
150*3f982cf4SFabien Sanglard     0xa, 0xc,  // Max packet ID.
151*3f982cf4SFabien Sanglard     0xf, 0xe, 0xd, 0xc, 0xb, 0xa, 0x9, 0x8,  // Payload.
152*3f982cf4SFabien Sanglard   };
153*3f982cf4SFabien Sanglard   // clang-format on
154*3f982cf4SFabien Sanglard 
155*3f982cf4SFabien Sanglard   const auto result = InspectPacketForRouting(kInput);
156*3f982cf4SFabien Sanglard   EXPECT_EQ(ApparentPacketType::UNKNOWN, result.first);
157*3f982cf4SFabien Sanglard }
158*3f982cf4SFabien Sanglard 
159*3f982cf4SFabien Sanglard // Tests that an empty packet is classified as unknown.
TEST(PacketUtilTest,InspectsEmptyPacket)160*3f982cf4SFabien Sanglard TEST(PacketUtilTest, InspectsEmptyPacket) {
161*3f982cf4SFabien Sanglard   const uint8_t kInput[] = {};
162*3f982cf4SFabien Sanglard 
163*3f982cf4SFabien Sanglard   const auto result =
164*3f982cf4SFabien Sanglard       InspectPacketForRouting(absl::Span<const uint8_t>(kInput, 0));
165*3f982cf4SFabien Sanglard   EXPECT_EQ(ApparentPacketType::UNKNOWN, result.first);
166*3f982cf4SFabien Sanglard }
167*3f982cf4SFabien Sanglard 
168*3f982cf4SFabien Sanglard // Tests that a packet with garbage is classified as unknown.
TEST(PacketUtilTest,InspectsGarbagePacket)169*3f982cf4SFabien Sanglard TEST(PacketUtilTest, InspectsGarbagePacket) {
170*3f982cf4SFabien Sanglard   // clang-format off
171*3f982cf4SFabien Sanglard   const uint8_t kInput[] = {
172*3f982cf4SFabien Sanglard     0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef,
173*3f982cf4SFabien Sanglard     0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef,
174*3f982cf4SFabien Sanglard     0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef,
175*3f982cf4SFabien Sanglard     0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef,
176*3f982cf4SFabien Sanglard   };
177*3f982cf4SFabien Sanglard   // clang-format on
178*3f982cf4SFabien Sanglard 
179*3f982cf4SFabien Sanglard   const auto result = InspectPacketForRouting(kInput);
180*3f982cf4SFabien Sanglard   EXPECT_EQ(ApparentPacketType::UNKNOWN, result.first);
181*3f982cf4SFabien Sanglard }
182*3f982cf4SFabien Sanglard 
183*3f982cf4SFabien Sanglard }  // namespace
184*3f982cf4SFabien Sanglard }  // namespace cast
185*3f982cf4SFabien Sanglard }  // namespace openscreen
186