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