xref: /aosp_15_r20/external/webrtc/net/dcsctp/packet/chunk/forward_tsn_chunk.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1 /*
2  *  Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 #include "net/dcsctp/packet/chunk/forward_tsn_chunk.h"
11 
12 #include <stddef.h>
13 #include <stdint.h>
14 
15 #include <string>
16 #include <utility>
17 #include <vector>
18 
19 #include "absl/types/optional.h"
20 #include "api/array_view.h"
21 #include "net/dcsctp/packet/bounded_byte_reader.h"
22 #include "net/dcsctp/packet/bounded_byte_writer.h"
23 #include "net/dcsctp/packet/chunk/forward_tsn_common.h"
24 #include "net/dcsctp/packet/tlv_trait.h"
25 #include "rtc_base/strings/string_builder.h"
26 
27 namespace dcsctp {
28 
29 // https://tools.ietf.org/html/rfc3758#section-3.2
30 
31 //   0                   1                   2                   3
32 //   0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
33 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
34 //  |   Type = 192  |  Flags = 0x00 |        Length = Variable      |
35 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
36 //  |                      New Cumulative TSN                       |
37 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
38 //  |         Stream-1              |       Stream Sequence-1       |
39 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
40 //  \                                                               /
41 //  /                                                               \
42 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
43 //  |         Stream-N              |       Stream Sequence-N       |
44 //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
45 constexpr int ForwardTsnChunk::kType;
46 
Parse(rtc::ArrayView<const uint8_t> data)47 absl::optional<ForwardTsnChunk> ForwardTsnChunk::Parse(
48     rtc::ArrayView<const uint8_t> data) {
49   absl::optional<BoundedByteReader<kHeaderSize>> reader = ParseTLV(data);
50   if (!reader.has_value()) {
51     return absl::nullopt;
52   }
53   TSN new_cumulative_tsn(reader->Load32<4>());
54 
55   size_t streams_skipped =
56       reader->variable_data_size() / kSkippedStreamBufferSize;
57 
58   std::vector<SkippedStream> skipped_streams;
59   skipped_streams.reserve(streams_skipped);
60   for (size_t i = 0; i < streams_skipped; ++i) {
61     BoundedByteReader<kSkippedStreamBufferSize> sub_reader =
62         reader->sub_reader<kSkippedStreamBufferSize>(i *
63                                                      kSkippedStreamBufferSize);
64 
65     StreamID stream_id(sub_reader.Load16<0>());
66     SSN ssn(sub_reader.Load16<2>());
67     skipped_streams.emplace_back(stream_id, ssn);
68   }
69   return ForwardTsnChunk(new_cumulative_tsn, std::move(skipped_streams));
70 }
71 
SerializeTo(std::vector<uint8_t> & out) const72 void ForwardTsnChunk::SerializeTo(std::vector<uint8_t>& out) const {
73   rtc::ArrayView<const SkippedStream> skipped = skipped_streams();
74   size_t variable_size = skipped.size() * kSkippedStreamBufferSize;
75   BoundedByteWriter<kHeaderSize> writer = AllocateTLV(out, variable_size);
76 
77   writer.Store32<4>(*new_cumulative_tsn());
78   for (size_t i = 0; i < skipped.size(); ++i) {
79     BoundedByteWriter<kSkippedStreamBufferSize> sub_writer =
80         writer.sub_writer<kSkippedStreamBufferSize>(i *
81                                                     kSkippedStreamBufferSize);
82     sub_writer.Store16<0>(*skipped[i].stream_id);
83     sub_writer.Store16<2>(*skipped[i].ssn);
84   }
85 }
86 
ToString() const87 std::string ForwardTsnChunk::ToString() const {
88   rtc::StringBuilder sb;
89   sb << "FORWARD-TSN, new_cumulative_tsn=" << *new_cumulative_tsn();
90   for (const auto& skipped : skipped_streams()) {
91     sb << ", skip " << skipped.stream_id.value() << ":" << *skipped.ssn;
92   }
93   return sb.str();
94 }
95 }  // namespace dcsctp
96