blob: d324fb223a290612c66e0b71d4ea4f604f2082b0 [file] [log] [blame]
Victor Boiviea4d5e242021-03-30 08:03:511/*
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#ifndef NET_DCSCTP_COMMON_SEQUENCE_NUMBERS_H_
11#define NET_DCSCTP_COMMON_SEQUENCE_NUMBERS_H_
12
13#include <cstdint>
14#include <limits>
15#include <utility>
16
Victor Boivie83c726f2021-04-01 22:18:4817#include "net/dcsctp/common/internal_types.h"
Evan Shrubsole4387ad62023-01-09 13:28:5318#include "rtc_base/numerics/sequence_number_unwrapper.h"
Victor Boivie83c726f2021-04-01 22:18:4819
Victor Boiviea4d5e242021-03-30 08:03:5120namespace dcsctp {
21
22// UnwrappedSequenceNumber handles wrapping sequence numbers and unwraps them to
23// an int64_t value space, to allow wrapped sequence numbers to be easily
24// compared for ordering.
25//
26// Sequence numbers are expected to be monotonically increasing, but they do not
27// need to be unwrapped in order, as long as the difference to the previous one
28// is not larger than half the range of the wrapped sequence number.
Victor Boivie83c726f2021-04-01 22:18:4829//
Victor Boivieb9182302021-09-21 12:51:0530// The WrappedType must be a webrtc::StrongAlias type.
Victor Boiviea4d5e242021-03-30 08:03:5131template <typename WrappedType>
32class UnwrappedSequenceNumber {
33 public:
Victor Boivie83c726f2021-04-01 22:18:4834 static_assert(
35 !std::numeric_limits<typename WrappedType::UnderlyingType>::is_signed,
36 "The wrapped type must be unsigned");
37 static_assert(
38 std::numeric_limits<typename WrappedType::UnderlyingType>::max() <
39 std::numeric_limits<int64_t>::max(),
40 "The wrapped type must be less than the int64_t value space");
Victor Boiviea4d5e242021-03-30 08:03:5141
42 // The unwrapper is a sort of factory and converts wrapped sequence numbers to
43 // unwrapped ones.
44 class Unwrapper {
45 public:
Evan Shrubsole4387ad62023-01-09 13:28:5346 Unwrapper() = default;
Victor Boiviea4d5e242021-03-30 08:03:5147 Unwrapper(const Unwrapper&) = default;
48 Unwrapper& operator=(const Unwrapper&) = default;
49
50 // Given a wrapped `value`, and with knowledge of its current last seen
51 // largest number, will return a value that can be compared using normal
52 // operators, such as less-than, greater-than etc.
53 //
54 // This will also update the Unwrapper's state, to track the last seen
55 // largest value.
56 UnwrappedSequenceNumber<WrappedType> Unwrap(WrappedType value) {
Evan Shrubsole4387ad62023-01-09 13:28:5357 return UnwrappedSequenceNumber<WrappedType>(unwrapper_.Unwrap(*value));
Victor Boiviea4d5e242021-03-30 08:03:5158 }
59
60 // Similar to `Unwrap`, but will not update the Unwrappers's internal state.
61 UnwrappedSequenceNumber<WrappedType> PeekUnwrap(WrappedType value) const {
Evan Shrubsole4387ad62023-01-09 13:28:5362 return UnwrappedSequenceNumber<WrappedType>(
63 unwrapper_.PeekUnwrap(*value));
Victor Boiviea4d5e242021-03-30 08:03:5164 }
65
66 // Resets the Unwrapper to its pristine state. Used when a sequence number
67 // is to be reset to zero.
Evan Shrubsole4387ad62023-01-09 13:28:5368 void Reset() { unwrapper_.Reset(); }
Victor Boiviea4d5e242021-03-30 08:03:5169
70 private:
Evan Shrubsole4387ad62023-01-09 13:28:5371 webrtc::SeqNumUnwrapper<typename WrappedType::UnderlyingType> unwrapper_;
Victor Boiviea4d5e242021-03-30 08:03:5172 };
73
74 // Returns the wrapped value this type represents.
75 WrappedType Wrap() const {
76 return static_cast<WrappedType>(value_ % kValueLimit);
77 }
78
79 template <typename H>
80 friend H AbslHashValue(H state,
81 const UnwrappedSequenceNumber<WrappedType>& hash) {
82 return H::combine(std::move(state), hash.value_);
83 }
84
85 bool operator==(const UnwrappedSequenceNumber<WrappedType>& other) const {
86 return value_ == other.value_;
87 }
88 bool operator!=(const UnwrappedSequenceNumber<WrappedType>& other) const {
89 return value_ != other.value_;
90 }
91 bool operator<(const UnwrappedSequenceNumber<WrappedType>& other) const {
92 return value_ < other.value_;
93 }
94 bool operator>(const UnwrappedSequenceNumber<WrappedType>& other) const {
95 return value_ > other.value_;
96 }
97 bool operator>=(const UnwrappedSequenceNumber<WrappedType>& other) const {
98 return value_ >= other.value_;
99 }
100 bool operator<=(const UnwrappedSequenceNumber<WrappedType>& other) const {
101 return value_ <= other.value_;
102 }
103
Evan Shrubsoleaa5897d2022-12-15 09:30:52104 // Const accessors for underlying value.
105 constexpr const int64_t* operator->() const { return &value_; }
106 constexpr const int64_t& operator*() const& { return value_; }
107 constexpr const int64_t&& operator*() const&& { return std::move(value_); }
108 constexpr const int64_t& value() const& { return value_; }
109 constexpr const int64_t&& value() const&& { return std::move(value_); }
110 constexpr explicit operator const int64_t&() const& { return value_; }
111
Victor Boiviea4d5e242021-03-30 08:03:51112 // Increments the value.
113 void Increment() { ++value_; }
Victor Boivie250fbb32021-04-13 09:11:04114
115 // Returns the next value relative to this sequence number.
Victor Boiviea4d5e242021-03-30 08:03:51116 UnwrappedSequenceNumber<WrappedType> next_value() const {
117 return UnwrappedSequenceNumber<WrappedType>(value_ + 1);
118 }
119
Victor Boivie250fbb32021-04-13 09:11:04120 // Returns a new sequence number based on `value`, and adding `delta` (which
121 // may be negative).
122 static UnwrappedSequenceNumber<WrappedType> AddTo(
123 UnwrappedSequenceNumber<WrappedType> value,
124 int delta) {
125 return UnwrappedSequenceNumber<WrappedType>(value.value_ + delta);
Victor Boiviea4d5e242021-03-30 08:03:51126 }
127
Victor Boivie250fbb32021-04-13 09:11:04128 // Returns the absolute difference between `lhs` and `rhs`.
129 static typename WrappedType::UnderlyingType Difference(
130 UnwrappedSequenceNumber<WrappedType> lhs,
131 UnwrappedSequenceNumber<WrappedType> rhs) {
132 return (lhs.value_ > rhs.value_) ? (lhs.value_ - rhs.value_)
133 : (rhs.value_ - lhs.value_);
Victor Boiviea4d5e242021-03-30 08:03:51134 }
135
136 private:
137 explicit UnwrappedSequenceNumber(int64_t value) : value_(value) {}
138 static constexpr int64_t kValueLimit =
Victor Boivie83c726f2021-04-01 22:18:48139 static_cast<int64_t>(1)
140 << std::numeric_limits<typename WrappedType::UnderlyingType>::digits;
Victor Boiviea4d5e242021-03-30 08:03:51141
142 int64_t value_;
143};
144
Victor Boiviea8655192021-04-01 06:23:54145// Unwrapped Transmission Sequence Numbers (TSN)
Victor Boivie83c726f2021-04-01 22:18:48146using UnwrappedTSN = UnwrappedSequenceNumber<TSN>;
Victor Boiviea4d5e242021-03-30 08:03:51147
Victor Boiviea8655192021-04-01 06:23:54148// Unwrapped Stream Sequence Numbers (SSN)
Victor Boivie83c726f2021-04-01 22:18:48149using UnwrappedSSN = UnwrappedSequenceNumber<SSN>;
Victor Boiviea4d5e242021-03-30 08:03:51150
Victor Boiviea8655192021-04-01 06:23:54151// Unwrapped Message Identifier (MID)
Victor Boivie83c726f2021-04-01 22:18:48152using UnwrappedMID = UnwrappedSequenceNumber<MID>;
Victor Boiviea4d5e242021-03-30 08:03:51153
154} // namespace dcsctp
155
156#endif // NET_DCSCTP_COMMON_SEQUENCE_NUMBERS_H_