blob: c38e7f44384814d87886e53fd67163e7d38ad1bd [file] [log] [blame]
/*
* Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "modules/rtp_rtcp/source/rtcp_packet/loss_notification.h"
#include "test/gmock.h"
#include "test/gtest.h"
#include "test/rtcp_packet_parser.h"
namespace webrtc {
using ::testing::ElementsAreArray;
using ::testing::make_tuple;
using ::webrtc::rtcp::LossNotification;
TEST(RtcpPacketLossNotificationTest, SetWithIllegalValuesFails) {
constexpr uint16_t kLastDecoded = 0x3c7b;
constexpr uint16_t kLastReceived = kLastDecoded + 0x7fff + 1;
constexpr bool kDecodabilityFlag = true;
LossNotification loss_notification;
EXPECT_FALSE(
loss_notification.Set(kLastDecoded, kLastReceived, kDecodabilityFlag));
}
TEST(RtcpPacketLossNotificationTest, SetWithLegalValuesSucceeds) {
constexpr uint16_t kLastDecoded = 0x3c7b;
constexpr uint16_t kLastReceived = kLastDecoded + 0x7fff;
constexpr bool kDecodabilityFlag = true;
LossNotification loss_notification;
EXPECT_TRUE(
loss_notification.Set(kLastDecoded, kLastReceived, kDecodabilityFlag));
}
TEST(RtcpPacketLossNotificationTest, CreateProducesExpectedWireFormat) {
// Note that (0x6542 >> 1) is used just to make the pattern in kPacket
// more apparent; there's nothing truly special about the value,
// it's only an implementation detail that last-received is represented
// as a delta from last-decoded, and that this delta is shifted before
// it's put on the wire.
constexpr uint16_t kLastDecoded = 0x3c7b;
constexpr uint16_t kLastReceived = kLastDecoded + (0x6542 >> 1);
constexpr bool kDecodabilityFlag = true;
const uint8_t kPacket[] = {0x8f, 206, 0x00, 0x04, 0x12, 0x34, 0x56, 0x78, //
0xab, 0xcd, 0xef, 0x01, 'L', 'N', 'T', 'F', //
0x3c, 0x7b, 0x65, 0x43};
LossNotification loss_notification;
loss_notification.SetSenderSsrc(0x12345678);
loss_notification.SetMediaSsrc(0xabcdef01);
ASSERT_TRUE(
loss_notification.Set(kLastDecoded, kLastReceived, kDecodabilityFlag));
rtc::Buffer packet = loss_notification.Build();
EXPECT_THAT(make_tuple(packet.data(), packet.size()),
ElementsAreArray(kPacket));
}
TEST(RtcpPacketLossNotificationTest,
ParseFailsOnTooSmallPacketToBeLossNotification) {
uint8_t packet[] = {0x8f, 206, 0x00, 0x04, 0x12, 0x34, 0x56, 0x78, //
0xab, 0xcd, 0xef, 0x01, 'L', 'N', 'T', 'F', //
0x3c, 0x7b, 0x65, 0x43};
size_t packet_length_bytes = sizeof(packet);
LossNotification loss_notification;
// First, prove that the failure we're expecting to see happens because of
// the length, by showing that before the modification to the length,
// the packet was correctly parsed.
ASSERT_TRUE(
test::ParseSinglePacket(packet, packet_length_bytes, &loss_notification));
// Show that after shaving off a word, the packet is no longer parsable.
packet[3] -= 1; // Change the `length` field of the RTCP packet.
packet_length_bytes -= 4; // Effectively forget the last 32-bit word.
EXPECT_FALSE(
test::ParseSinglePacket(packet, packet_length_bytes, &loss_notification));
}
TEST(RtcpPacketLossNotificationTest,
ParseFailsWhenUniqueIdentifierIsNotLossNotification) {
uint8_t packet[] = {0x8f, 206, 0x00, 0x04, 0x12, 0x34, 0x56, 0x78, //
0xab, 0xcd, 0xef, 0x01, 'L', 'N', 'T', 'F', //
0x3c, 0x7b, 0x65, 0x43};
LossNotification loss_notification;
// First, prove that the failure we're expecting to see happens because of
// the identifier, by showing that before the modification to the identifier,
// the packet was correctly parsed.
ASSERT_TRUE(test::ParseSinglePacket(packet, &loss_notification));
// Show that after changing the identifier, the packet is no longer parsable.
RTC_DCHECK_EQ(packet[12], 'L');
RTC_DCHECK_EQ(packet[13], 'N');
RTC_DCHECK_EQ(packet[14], 'T');
RTC_DCHECK_EQ(packet[15], 'F');
packet[14] = 'x';
EXPECT_FALSE(test::ParseSinglePacket(packet, &loss_notification));
}
TEST(RtcpPacketLossNotificationTest,
ParseLegalLossNotificationMessagesCorrectly) {
// Note that (0x6542 >> 1) is used just to make the pattern in kPacket
// more apparent; there's nothing truly special about the value,
// it's only an implementation detail that last-received is represented
// as a delta from last-decoded, and that this delta is shifted before
// it's put on the wire.
constexpr uint16_t kLastDecoded = 0x3c7b;
constexpr uint16_t kLastReceived = kLastDecoded + (0x6542 >> 1);
constexpr bool kDecodabilityFlag = true;
const uint8_t kPacket[] = {0x8f, 206, 0x00, 0x04, 0x12, 0x34, 0x56, 0x78, //
0xab, 0xcd, 0xef, 0x01, 'L', 'N', 'T', 'F', //
0x3c, 0x7b, 0x65, 0x43};
LossNotification loss_notification;
EXPECT_TRUE(test::ParseSinglePacket(kPacket, &loss_notification));
EXPECT_EQ(loss_notification.sender_ssrc(), 0x12345678u);
EXPECT_EQ(loss_notification.media_ssrc(), 0xabcdef01u);
EXPECT_EQ(loss_notification.last_decoded(), kLastDecoded);
EXPECT_EQ(loss_notification.last_received(), kLastReceived);
EXPECT_EQ(loss_notification.decodability_flag(), kDecodabilityFlag);
}
} // namespace webrtc