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 #ifndef CAST_STREAMING_PACKET_UTIL_H_
6*3f982cf4SFabien Sanglard #define CAST_STREAMING_PACKET_UTIL_H_
7*3f982cf4SFabien Sanglard
8*3f982cf4SFabien Sanglard #include <utility>
9*3f982cf4SFabien Sanglard
10*3f982cf4SFabien Sanglard #include "absl/types/span.h"
11*3f982cf4SFabien Sanglard #include "cast/streaming/ssrc.h"
12*3f982cf4SFabien Sanglard #include "util/big_endian.h"
13*3f982cf4SFabien Sanglard
14*3f982cf4SFabien Sanglard namespace openscreen {
15*3f982cf4SFabien Sanglard namespace cast {
16*3f982cf4SFabien Sanglard
17*3f982cf4SFabien Sanglard // Reads a field from the start of the given span and advances the span to point
18*3f982cf4SFabien Sanglard // just after the field.
19*3f982cf4SFabien Sanglard template <typename Integer>
ConsumeField(absl::Span<const uint8_t> * in)20*3f982cf4SFabien Sanglard inline Integer ConsumeField(absl::Span<const uint8_t>* in) {
21*3f982cf4SFabien Sanglard const Integer result = ReadBigEndian<Integer>(in->data());
22*3f982cf4SFabien Sanglard in->remove_prefix(sizeof(Integer));
23*3f982cf4SFabien Sanglard return result;
24*3f982cf4SFabien Sanglard }
25*3f982cf4SFabien Sanglard
26*3f982cf4SFabien Sanglard // Writes a field at the start of the given span and advances the span to point
27*3f982cf4SFabien Sanglard // just after the field.
28*3f982cf4SFabien Sanglard template <typename Integer>
AppendField(Integer value,absl::Span<uint8_t> * out)29*3f982cf4SFabien Sanglard inline void AppendField(Integer value, absl::Span<uint8_t>* out) {
30*3f982cf4SFabien Sanglard WriteBigEndian<Integer>(value, out->data());
31*3f982cf4SFabien Sanglard out->remove_prefix(sizeof(Integer));
32*3f982cf4SFabien Sanglard }
33*3f982cf4SFabien Sanglard
34*3f982cf4SFabien Sanglard // Returns a bitmask for a field having the given number of bits. For example,
35*3f982cf4SFabien Sanglard // FieldBitmask<uint8_t>(5) returns 0b00011111.
36*3f982cf4SFabien Sanglard template <typename Integer>
FieldBitmask(unsigned field_size_in_bits)37*3f982cf4SFabien Sanglard constexpr Integer FieldBitmask(unsigned field_size_in_bits) {
38*3f982cf4SFabien Sanglard return (Integer{1} << field_size_in_bits) - 1;
39*3f982cf4SFabien Sanglard }
40*3f982cf4SFabien Sanglard
41*3f982cf4SFabien Sanglard // Reserves |num_bytes| from the beginning of the given span, returning the
42*3f982cf4SFabien Sanglard // reserved space.
ReserveSpace(int num_bytes,absl::Span<uint8_t> * out)43*3f982cf4SFabien Sanglard inline absl::Span<uint8_t> ReserveSpace(int num_bytes,
44*3f982cf4SFabien Sanglard absl::Span<uint8_t>* out) {
45*3f982cf4SFabien Sanglard const absl::Span<uint8_t> reserved = out->subspan(0, num_bytes);
46*3f982cf4SFabien Sanglard out->remove_prefix(num_bytes);
47*3f982cf4SFabien Sanglard return reserved;
48*3f982cf4SFabien Sanglard }
49*3f982cf4SFabien Sanglard
50*3f982cf4SFabien Sanglard // Performs a quick-scan of the packet data for the purposes of routing it to an
51*3f982cf4SFabien Sanglard // appropriate parser. Identifies whether the packet is a RTP packet, RTCP
52*3f982cf4SFabien Sanglard // packet, or unknown; and provides the originator's SSRC. This only performs a
53*3f982cf4SFabien Sanglard // very quick scan of the packet data, and does not guarantee that a full parse
54*3f982cf4SFabien Sanglard // will later succeed.
55*3f982cf4SFabien Sanglard enum class ApparentPacketType { UNKNOWN, RTP, RTCP };
56*3f982cf4SFabien Sanglard std::pair<ApparentPacketType, Ssrc> InspectPacketForRouting(
57*3f982cf4SFabien Sanglard absl::Span<const uint8_t> packet);
58*3f982cf4SFabien Sanglard
59*3f982cf4SFabien Sanglard } // namespace cast
60*3f982cf4SFabien Sanglard } // namespace openscreen
61*3f982cf4SFabien Sanglard
62*3f982cf4SFabien Sanglard #endif // CAST_STREAMING_PACKET_UTIL_H_
63