RlcSduSlidingWindowReceptionBuffer.h Source File

Simu5G: RlcSduSlidingWindowReceptionBuffer.h Source File
Simu5G
RlcSduSlidingWindowReceptionBuffer.h
1//
2// Simu5G
3//
4// Authors: Esteban Egea Lopez (Universidad Politecnica de Cartagena)
5//
6// This file is part of a software released under the license included in file
7// "license.pdf". Please read LICENSE and README files before using it.
8// The above files and the present reference are part of the software itself,
9// and cannot be removed from it.
10//
11
12#ifndef STACK_RLC_AM_BUFFER_RLCSDUSLIDINGWINDOWRECEPTIONBUFFER_H_
13#define STACK_RLC_AM_BUFFER_RLCSDUSLIDINGWINDOWRECEPTIONBUFFER_H_
14
15#include <omnetpp.h>
16#include <inet/common/packet/Packet.h>
17
18#include <algorithm>
19#include <list>
20#include <map>
21
22#include "simu5g/stack/rlc/LteRlcDefs.h"
23
24namespace simu5g {
25
30 uint32_t start;
31 uint32_t end;
32
33 // Sort by start position for easy merging
34 bool operator<(const ByteInterval& other) const {
35 return start < other.start;
36 }
37};
38
42struct SduReassemblyState {
43 uint32_t totalLength;
44 inet::Packet *sduPointer;
45 std::list<ByteInterval> receivedIntervals;
46 bool isComplete;
47
48 SduReassemblyState(uint32_t length, inet::Packet *ptr)
49 : totalLength(length), sduPointer(ptr), isComplete(false) {}
50
55 std::pair<bool, bool> addSegment(uint32_t start, uint32_t end) {
56 if (isComplete)
57 return {false, true};
58 if (end >= totalLength)
59 end = totalLength - 1;
60
61 // Check if already fully covered
62 for (const auto &interval : receivedIntervals) {
63 if (start >= interval.start && end <= interval.end)
64 return {false, isComplete};
65 }
66
67 ByteInterval newInterval{start, end};
68 auto it = std::lower_bound(receivedIntervals.begin(), receivedIntervals.end(), newInterval);
69 receivedIntervals.insert(it, newInterval);
70
71 // Merge overlapping/adjacent intervals
72 for (auto current = receivedIntervals.begin(); current != receivedIntervals.end(); ) {
73 auto next = std::next(current);
74 if (next != receivedIntervals.end() && next->start <= current->end + 1) {
75 current->end = std::max(current->end, next->end);
76 receivedIntervals.erase(next);
77 }
78 else {
79 ++current;
80 }
81 }
82
83 // Check completion: single interval covering [0, totalLength-1]
84 if (!receivedIntervals.empty()) {
85 const auto &first = receivedIntervals.front();
86 if (first.start == 0 && first.end == totalLength - 1)
87 isComplete = true;
88 }
89
90 return {true, isComplete};
91 }
92
97 if (receivedIntervals.empty())
98 return false;
99 if (receivedIntervals.size() > 1)
100 return true;
101 return receivedIntervals.front().start != 0;
102 }
103};
104
105class RlcSduSlidingWindowReceptionBuffer : public omnetpp::cObject
106{
107 public:
108 RlcSduSlidingWindowReceptionBuffer(uint32_t windowSize, const std::string &name);
109 ~RlcSduSlidingWindowReceptionBuffer() override;
110
115 std::pair<bool, bool> handleSegment(uint32_t sn, uint32_t totalSduLength,
116 uint32_t start, uint32_t end,
117 inet::Packet *sduDataPtr);
118
120 virtual inet::Packet *consumeSdu(uint32_t sn);
121
123 virtual bool hasMissingByteSegmentBeforeLast(uint32_t sn);
124
126 virtual void handleReassemblyTimerExpiry(uint32_t rxNextStatusTrigger);
127
129 virtual StatusPduData generateStatusPduData();
130
132 virtual void updateRxHighestStatus();
133
135 virtual void updateRxNext();
136
137 virtual bool isReady(uint32_t sn) const {
138 auto it = sduBuffer_.find(sn);
139 return it != sduBuffer_.end() && it->second.isComplete;
140 }
141
142 virtual bool inWindow(uint32_t sn) const {
143 return sn >= rxNext_ && sn < rxNext_ + amWindowSize_;
144 }
145
146 virtual bool aboveWindow(uint32_t sn) const {
147 return sn >= rxNext_ + amWindowSize_;
148 }
149
150 void discardSdu(uint32_t sn) { sduBuffer_.erase(sn); }
151
152 uint32_t getRxNext() const { return rxNext_; }
153 uint32_t getRxNextHighest() const { return rxNextHighest_; }
154 uint32_t getRxHighestStatus() const { return rxHighestStatus_; }
155
156 protected:
157 std::map<uint32_t, SduReassemblyState> sduBuffer_;
158
159 // RLC AM reception state variables
160 uint32_t rxNext_ = 0; // Lower edge of the receiving window
161 uint32_t rxNextHighest_ = 0; // SN following highest SN received
162 uint32_t rxHighestStatus_ = 0; // SN following highest delivered SDU
163 uint32_t amWindowSize_;
164 uint32_t consumed_ = 0;
165 std::string name_;
166};
167
168} // namespace simu5g
169
170#endif // STACK_RLC_AM_BUFFER_RLCSDUSLIDINGWINDOWRECEPTIONBUFFER_H_
Definition AlertReceiver.h:24
Represents a range of bytes [start, end] within an SDU.
Definition RlcSduSlidingWindowReceptionBuffer.h:29
std::pair< bool, bool > addSegment(uint32_t start, uint32_t end)
Adds a new byte interval and merges overlapping or adjacent intervals.
Definition RlcSduSlidingWindowReceptionBuffer.h:55
bool hasMissingByteSegmentBeforeLast() const
Checks if there is a missing byte segment before the last byte of all received segments....
Definition RlcSduSlidingWindowReceptionBuffer.h:96