12#ifndef STACK_RLC_UM_RLCUMTRANSMITTERBUFFER_H_
13#define STACK_RLC_UM_RLCUMTRANSMITTERBUFFER_H_
17#include <inet/common/packet/Packet.h>
28 bool operator<(
const TransmitInterval& other)
const {
29 return start < other.start;
39 inet::Packet* sduPointer;
40 std::list<TransmitInterval> transmittedIntervals;
42 SduUmTxState(uint32_t s, uint32_t len, Packet* ptr)
43 : sn(s), totalLength(len), sduPointer(ptr) {}
48 bool getNextSegment(uint32_t grantSize, uint32_t& outStart, uint32_t& outEnd) {
49 uint32_t nextByteToTx = 0;
50 transmittedIntervals.sort();
52 for (
const auto& interval : transmittedIntervals) {
53 if (nextByteToTx < interval.start)
break;
54 nextByteToTx = interval.end + 1;
57 if (nextByteToTx >= totalLength)
return false;
59 outStart = nextByteToTx;
60 uint32_t remainingInSdu = totalLength - nextByteToTx;
61 uint32_t bytesToTransfer = std::min(grantSize, remainingInSdu);
62 outEnd = outStart + bytesToTransfer - 1;
68 uint32_t getNextByteToTx()
const {
69 uint32_t nextByteToTx = 0;
70 std::list<TransmitInterval> sorted = transmittedIntervals;
72 for (
const auto& interval : sorted) {
73 if (nextByteToTx < interval.start)
break;
74 nextByteToTx = interval.end + 1;
79 void markTransmitted(uint32_t start, uint32_t end) {
80 transmittedIntervals.push_back({start, end});
81 mergeIntervals(transmittedIntervals);
84 bool isFullyTransmitted() {
85 if (transmittedIntervals.empty())
return false;
86 mergeIntervals(transmittedIntervals);
87 return (transmittedIntervals.front().start == 0 &&
88 transmittedIntervals.front().end == totalLength - 1);
94 uint32_t transmittedCount = 0;
95 for (
const auto& interval : transmittedIntervals) {
96 transmittedCount += (interval.end - interval.start + 1);
98 return (totalLength > transmittedCount) ? (totalLength - transmittedCount) : 0;
101 void mergeIntervals(std::list<TransmitInterval>& intervals) {
102 if (intervals.empty())
return;
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);
116struct PendingSegmentUM {
120 uint32_t totalLength;
122 bool isValid =
false;
123 bool isLastSegment =
false;
127class RlcUmTransmitterBuffer {
129 std::list<SduUmTxState> txBuffer;
130 uint32_t TX_Next = 0;
133 RlcUmTransmitterBuffer(uint32_t snBits);
134 virtual ~RlcUmTransmitterBuffer();
141 virtual void addSdu(uint32_t length, Packet* sduPtr) {
143 txBuffer.emplace_back(0, length, sduPtr);
150 virtual PendingSegmentUM getSegmentForGrant(uint32_t grantSize);
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;
163 virtual bool hasData()
const {
164 return !txBuffer.empty();
170 virtual uint64_t getTotalPendingBytes()
const {
172 for (
const auto& sdu : txBuffer) {
173 total += sdu.getPendingBytes();
181 virtual void clearBuffer() {
182 for (
auto& sdu : txBuffer) {
183 if (sdu.sduPointer) {
184 delete sdu.sduPointer;
185 sdu.sduPointer =
nullptr;
192 uint32_t getTxNext()
const {
return TX_Next; }
193 void resetTxNext() {TX_Next=0;}
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