12f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap/*
22f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap *  Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
32f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap *
42f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap *  Use of this source code is governed by a BSD-style license
52f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap *  that can be found in the LICENSE file in the root of the source
62f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap *  tree. An additional intellectual property rights grant can be found
72f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap *  in the file PATENTS.  All contributing project authors may
82f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap *  be found in the AUTHORS file in the root of the source tree.
92f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap */
102f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap
112f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/compound_packet.h"
122f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap
132f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap#include "testing/gtest/include/gtest/gtest.h"
142f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap#include "webrtc/modules/rtp_rtcp/source/rtcp_packet.h"
152f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/bye.h"
162f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/receiver_report.h"
172f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap#include "webrtc/test/rtcp_packet_parser.h"
182f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap
192f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchapusing webrtc::rtcp::Bye;
202f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchapusing webrtc::rtcp::CompoundPacket;
212f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchapusing webrtc::rtcp::Fir;
222f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchapusing webrtc::rtcp::RawPacket;
232f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchapusing webrtc::rtcp::ReceiverReport;
242f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchapusing webrtc::rtcp::ReportBlock;
252f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchapusing webrtc::rtcp::SenderReport;
262f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchapusing webrtc::test::RtcpPacketParser;
272f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap
282f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchapnamespace webrtc {
292f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap
302f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchapconst uint32_t kSenderSsrc = 0x12345678;
312f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap
322f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchapTEST(RtcpCompoundPacketTest, AppendPacket) {
332f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap  Fir fir;
342f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap  ReportBlock rb;
352f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap  ReceiverReport rr;
362f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap  rr.From(kSenderSsrc);
372f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap  EXPECT_TRUE(rr.WithReportBlock(rb));
382f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap  rr.Append(&fir);
392f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap
402f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap  rtc::scoped_ptr<RawPacket> packet(rr.Build());
412f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap  RtcpPacketParser parser;
422f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap  parser.Parse(packet->Buffer(), packet->Length());
432f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap  EXPECT_EQ(1, parser.receiver_report()->num_packets());
442f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap  EXPECT_EQ(kSenderSsrc, parser.receiver_report()->Ssrc());
452f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap  EXPECT_EQ(1, parser.report_block()->num_packets());
462f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap  EXPECT_EQ(1, parser.fir()->num_packets());
472f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap}
482f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap
492f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchapTEST(RtcpCompoundPacketTest, AppendPacketOnEmpty) {
502f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap  CompoundPacket empty;
512f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap  ReceiverReport rr;
522f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap  rr.From(kSenderSsrc);
532f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap  empty.Append(&rr);
542f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap
552f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap  rtc::scoped_ptr<RawPacket> packet(empty.Build());
562f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap  RtcpPacketParser parser;
572f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap  parser.Parse(packet->Buffer(), packet->Length());
582f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap  EXPECT_EQ(1, parser.receiver_report()->num_packets());
592f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap  EXPECT_EQ(0, parser.report_block()->num_packets());
602f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap}
612f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap
622f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchapTEST(RtcpCompoundPacketTest, AppendPacketWithOwnAppendedPacket) {
632f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap  Fir fir;
642f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap  Bye bye;
652f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap  ReportBlock rb;
662f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap
672f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap  ReceiverReport rr;
682f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap  EXPECT_TRUE(rr.WithReportBlock(rb));
692f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap  rr.Append(&fir);
702f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap
712f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap  SenderReport sr;
722f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap  sr.Append(&bye);
732f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap  sr.Append(&rr);
742f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap
752f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap  rtc::scoped_ptr<RawPacket> packet(sr.Build());
762f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap  RtcpPacketParser parser;
772f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap  parser.Parse(packet->Buffer(), packet->Length());
782f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap  EXPECT_EQ(1, parser.sender_report()->num_packets());
792f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap  EXPECT_EQ(1, parser.receiver_report()->num_packets());
802f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap  EXPECT_EQ(1, parser.report_block()->num_packets());
812f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap  EXPECT_EQ(1, parser.bye()->num_packets());
822f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap  EXPECT_EQ(1, parser.fir()->num_packets());
832f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap}
842f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap
852f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchapTEST(RtcpCompoundPacketTest, BuildWithInputBuffer) {
862f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap  Fir fir;
872f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap  ReportBlock rb;
882f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap  ReceiverReport rr;
892f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap  rr.From(kSenderSsrc);
902f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap  EXPECT_TRUE(rr.WithReportBlock(rb));
912f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap  rr.Append(&fir);
922f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap
932f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap  const size_t kRrLength = 8;
942f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap  const size_t kReportBlockLength = 24;
952f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap  const size_t kFirLength = 20;
962f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap
972f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap  class Verifier : public rtcp::RtcpPacket::PacketReadyCallback {
982f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap   public:
992f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap    void OnPacketReady(uint8_t* data, size_t length) override {
1002f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap      RtcpPacketParser parser;
1012f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap      parser.Parse(data, length);
1022f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap      EXPECT_EQ(1, parser.receiver_report()->num_packets());
1032f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap      EXPECT_EQ(1, parser.report_block()->num_packets());
1042f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap      EXPECT_EQ(1, parser.fir()->num_packets());
1052f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap      ++packets_created_;
1062f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap    }
1072f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap
1082f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap    int packets_created_ = 0;
1092f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap  } verifier;
1102f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap  const size_t kBufferSize = kRrLength + kReportBlockLength + kFirLength;
1112f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap  uint8_t buffer[kBufferSize];
1122f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap  EXPECT_TRUE(rr.BuildExternalBuffer(buffer, kBufferSize, &verifier));
1132f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap  EXPECT_EQ(1, verifier.packets_created_);
1142f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap}
1152f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap
1162f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchapTEST(RtcpCompoundPacketTest, BuildWithTooSmallBuffer_FragmentedSend) {
1172f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap  Fir fir;
1182f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap  ReportBlock rb;
1192f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap  ReceiverReport rr;
1202f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap  rr.From(kSenderSsrc);
1212f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap  EXPECT_TRUE(rr.WithReportBlock(rb));
1222f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap  rr.Append(&fir);
1232f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap
1242f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap  const size_t kRrLength = 8;
1252f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap  const size_t kReportBlockLength = 24;
1262f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap
1272f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap  class Verifier : public rtcp::RtcpPacket::PacketReadyCallback {
1282f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap   public:
1292f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap    void OnPacketReady(uint8_t* data, size_t length) override {
1302f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap      RtcpPacketParser parser;
1312f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap      parser.Parse(data, length);
1322f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap      switch (packets_created_++) {
1332f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap        case 0:
1342f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap          EXPECT_EQ(1, parser.receiver_report()->num_packets());
1352f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap          EXPECT_EQ(1, parser.report_block()->num_packets());
1362f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap          EXPECT_EQ(0, parser.fir()->num_packets());
1372f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap          break;
1382f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap        case 1:
1392f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap          EXPECT_EQ(0, parser.receiver_report()->num_packets());
1402f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap          EXPECT_EQ(0, parser.report_block()->num_packets());
1412f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap          EXPECT_EQ(1, parser.fir()->num_packets());
1422f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap          break;
1432f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap        default:
1442f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap          ADD_FAILURE() << "OnPacketReady not expected to be called "
1452f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap                        << packets_created_ << " times.";
1462f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap      }
1472f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap    }
1482f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap
1492f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap    int packets_created_ = 0;
1502f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap  } verifier;
1512f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap  const size_t kBufferSize = kRrLength + kReportBlockLength;
1522f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap  uint8_t buffer[kBufferSize];
1532f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap  EXPECT_TRUE(rr.BuildExternalBuffer(buffer, kBufferSize, &verifier));
1542f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap  EXPECT_EQ(2, verifier.packets_created_);
1552f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap}
1562f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap
1572f7dea164dc49ae8a0322e3c9edb1dd23266c664danilchap}  // namespace webrtc
158