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 "cast/streaming/rtcp_common.h" 8*3f982cf4SFabien Sanglard #include "cast/streaming/rtp_defines.h" 9*3f982cf4SFabien Sanglard 10*3f982cf4SFabien Sanglard namespace openscreen { 11*3f982cf4SFabien Sanglard namespace cast { 12*3f982cf4SFabien Sanglard InspectPacketForRouting(absl::Span<const uint8_t> packet)13*3f982cf4SFabien Sanglardstd::pair<ApparentPacketType, Ssrc> InspectPacketForRouting( 14*3f982cf4SFabien Sanglard absl::Span<const uint8_t> packet) { 15*3f982cf4SFabien Sanglard // Check for RTP packets first, since they are more frequent. 16*3f982cf4SFabien Sanglard if (packet.size() >= kRtpPacketMinValidSize && 17*3f982cf4SFabien Sanglard packet[0] == kRtpRequiredFirstByte && 18*3f982cf4SFabien Sanglard IsRtpPayloadType(packet[1] & kRtpPayloadTypeMask)) { 19*3f982cf4SFabien Sanglard constexpr int kOffsetToSsrcField = 8; 20*3f982cf4SFabien Sanglard return std::make_pair( 21*3f982cf4SFabien Sanglard ApparentPacketType::RTP, 22*3f982cf4SFabien Sanglard Ssrc{ReadBigEndian<uint32_t>(packet.data() + kOffsetToSsrcField)}); 23*3f982cf4SFabien Sanglard } 24*3f982cf4SFabien Sanglard 25*3f982cf4SFabien Sanglard // While RTCP packets are valid if they consist of just the RTCP Common 26*3f982cf4SFabien Sanglard // Header, all the RTCP packet types processed by this implementation will 27*3f982cf4SFabien Sanglard // also have a SSRC field immediately following the header. This is important 28*3f982cf4SFabien Sanglard // for routing the packet to the correct parser instance. 29*3f982cf4SFabien Sanglard constexpr int kRtcpPacketMinAcceptableSize = 30*3f982cf4SFabien Sanglard kRtcpCommonHeaderSize + sizeof(uint32_t); 31*3f982cf4SFabien Sanglard if (packet.size() >= kRtcpPacketMinAcceptableSize && 32*3f982cf4SFabien Sanglard RtcpCommonHeader::Parse(packet).has_value()) { 33*3f982cf4SFabien Sanglard return std::make_pair( 34*3f982cf4SFabien Sanglard ApparentPacketType::RTCP, 35*3f982cf4SFabien Sanglard Ssrc{ReadBigEndian<uint32_t>(packet.data() + kRtcpCommonHeaderSize)}); 36*3f982cf4SFabien Sanglard } 37*3f982cf4SFabien Sanglard 38*3f982cf4SFabien Sanglard return std::make_pair(ApparentPacketType::UNKNOWN, Ssrc{0}); 39*3f982cf4SFabien Sanglard } 40*3f982cf4SFabien Sanglard 41*3f982cf4SFabien Sanglard } // namespace cast 42*3f982cf4SFabien Sanglard } // namespace openscreen 43