RlcUmTransmitterBuffer.h Source File

Simu5G: RlcUmTransmitterBuffer.h Source File
Simu5G
RlcUmTransmitterBuffer.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_UM_RLCUMTRANSMITTERBUFFER_H_
13#define STACK_RLC_UM_RLCUMTRANSMITTERBUFFER_H_
14
15
16#include <omnetpp.h>
17#include <inet/common/packet/Packet.h>
18namespace simu5g {
19using namespace inet;
20
24struct TransmitInterval {
25 uint32_t start;
26 uint32_t end;
27
28 bool operator<(const TransmitInterval& other) const {
29 return start < other.start;
30 }
31};
32
36struct SduUmTxState {
37 uint32_t sn;
38 uint32_t totalLength;
39 inet::Packet* sduPointer;
40 std::list<TransmitInterval> transmittedIntervals;
41
42 SduUmTxState(uint32_t s, uint32_t len, Packet* ptr)
43 : sn(s), totalLength(len), sduPointer(ptr) {}
44
48 bool getNextSegment(uint32_t grantSize, uint32_t& outStart, uint32_t& outEnd) {
49 uint32_t nextByteToTx = 0;
50 transmittedIntervals.sort();
51
52 for (const auto& interval : transmittedIntervals) {
53 if (nextByteToTx < interval.start) break;
54 nextByteToTx = interval.end + 1;
55 }
56
57 if (nextByteToTx >= totalLength) return false;
58
59 outStart = nextByteToTx;
60 uint32_t remainingInSdu = totalLength - nextByteToTx;
61 uint32_t bytesToTransfer = std::min(grantSize, remainingInSdu);
62 outEnd = outStart + bytesToTransfer - 1;
63
64 return true;
65 }
66
67 // Offset of the first not-yet-transmitted byte (0 if nothing sent yet).
68 uint32_t getNextByteToTx() const {
69 uint32_t nextByteToTx = 0;
70 std::list<TransmitInterval> sorted = transmittedIntervals;
71 sorted.sort();
72 for (const auto& interval : sorted) {
73 if (nextByteToTx < interval.start) break;
74 nextByteToTx = interval.end + 1;
75 }
76 return nextByteToTx;
77 }
78
79 void markTransmitted(uint32_t start, uint32_t end) {
80 transmittedIntervals.push_back({start, end});
81 mergeIntervals(transmittedIntervals);
82 }
83
84 bool isFullyTransmitted() {
85 if (transmittedIntervals.empty()) return false;
86 mergeIntervals(transmittedIntervals);
87 return (transmittedIntervals.front().start == 0 &&
88 transmittedIntervals.front().end == totalLength - 1);
89 }
93 uint32_t getPendingBytes() const {
94 uint32_t transmittedCount = 0;
95 for (const auto& interval : transmittedIntervals) {
96 transmittedCount += (interval.end - interval.start + 1);
97 }
98 return (totalLength > transmittedCount) ? (totalLength - transmittedCount) : 0;
99 }
100 private:
101 void mergeIntervals(std::list<TransmitInterval>& intervals) {
102 if (intervals.empty()) return;
103 intervals.sort();
104 for (auto it = intervals.begin(); it != intervals.end(); ) {
105 auto next = std::next(it);
106 if (next != intervals.end() && next->start <= it->end + 1) {
107 it->end = std::max(it->end, next->end);
108 intervals.erase(next);
109 } else {
110 ++it;
111 }
112 }
113 }
114};
115
116struct PendingSegmentUM {
117 uint32_t sn;
118 uint32_t start;
119 uint32_t end;
120 uint32_t totalLength;
121 Packet* ptr;
122 bool isValid = false;
123 bool isLastSegment = false; // Added to help UM SN logic
124 bool isFull=false;
125};
126
127class RlcUmTransmitterBuffer {
128protected:
129 std::list<SduUmTxState> txBuffer; // Using list for FIFO order
130 uint32_t TX_Next = 0; // Next SN to be assigned
131 uint32_t snModulus;
132public:
133 RlcUmTransmitterBuffer(uint32_t snBits);
134 virtual ~RlcUmTransmitterBuffer();
135
141 virtual void addSdu(uint32_t length, Packet* sduPtr) {
142 // In UM, we buffer the SDU and assign SN when it's picked for transmission
143 txBuffer.emplace_back(0, length, sduPtr);
144 }
145
150 virtual PendingSegmentUM getSegmentForGrant(uint32_t grantSize);
151
152 // Peek the head SDU without consuming it: untransmitted byte count + the offset of
153 // its next byte (0 => fresh/first piece, >0 => continuation). Lets the caller pick
154 // the RAT/segment-state-dependent header size before carving.
155 virtual bool peekHead(uint32_t& remaining, uint32_t& nextByte) const {
156 if (txBuffer.empty()) return false;
157 const auto& sdu = txBuffer.front();
158 nextByte = sdu.getNextByteToTx();
159 remaining = (sdu.totalLength > nextByte) ? (sdu.totalLength - nextByte) : 0;
160 return true;
161 }
162
163 virtual bool hasData() const {
164 return !txBuffer.empty();
165 }
170 virtual uint64_t getTotalPendingBytes() const {
171 uint64_t total = 0;
172 for (const auto& sdu : txBuffer) {
173 total += sdu.getPendingBytes();
174 }
175 return total;
176 }
177
181 virtual void clearBuffer() {
182 for (auto& sdu : txBuffer) {
183 if (sdu.sduPointer) {
184 delete sdu.sduPointer;
185 sdu.sduPointer = nullptr;
186 }
187 }
188 txBuffer.clear();
189 }
190
191
192 uint32_t getTxNext() const { return TX_Next; }
193 void resetTxNext() {TX_Next=0;}
194};
195
196} /* namespace simu5g */
197
198#endif /* STACK_RLC_UM_RLCUMTRANSMITTERBUFFER_H_ */
Definition AlertReceiver.h:24
uint32_t getPendingBytes() const
Returns the number of bytes in this SDU that have not been transmitted yet.
Definition RlcUmTransmitterBuffer.h:93
bool getNextSegment(uint32_t grantSize, uint32_t &outStart, uint32_t &outEnd)
Finds the next available byte range for UM transmission.
Definition RlcUmTransmitterBuffer.h:48
Represents a range of bytes [start, end] for transmission tracking.
Definition RlcSduSlidingWindowTransmissionBuffer.h:31