12#ifndef STACK_RLC_AM_BUFFER_RLCSDUSLIDINGWINDOWTRANSMISSIONBUFFER_H_
13#define STACK_RLC_AM_BUFFER_RLCSDUSLIDINGWINDOWTRANSMISSIONBUFFER_H_
16#include <inet/common/packet/Packet.h>
36 return start < other.start;
46 inet::Packet *sduPointer;
49 std::list<TransmitInterval> transmittedIntervals;
51 std::list<TransmitInterval> acknowledgedIntervals;
53 SduTxState(uint32_t s, uint32_t len, inet::Packet *ptr)
54 : sn(s), totalLength(len), sduPointer(ptr) {}
55 ~SduTxState() =
default;
61 for (
const auto& interval : transmittedIntervals) {
62 count += (interval.end - interval.start + 1);
76 uint32_t nextByteToTx = 0;
77 std::list<TransmitInterval> sorted = transmittedIntervals;
79 for (
const auto &interval : sorted) {
80 if (nextByteToTx < interval.start)
82 nextByteToTx = interval.end + 1;
87 bool getNextSegment(uint32_t grantSize, uint32_t &outStart, uint32_t &outEnd) {
91 uint32_t nextByteToTx = 0;
92 transmittedIntervals.sort();
94 for (
const auto &interval : transmittedIntervals) {
95 if (nextByteToTx < interval.start)
97 nextByteToTx = interval.end + 1;
100 if (nextByteToTx >= totalLength)
103 outStart = nextByteToTx;
104 uint32_t remainingInSdu = totalLength - nextByteToTx;
105 outEnd = outStart + std::min(grantSize, remainingInSdu) - 1;
112 transmittedIntervals.push_back({start, end});
113 mergeIntervals(transmittedIntervals);
116 void markAcked(uint32_t start, uint32_t end) {
117 acknowledgedIntervals.push_back({start, end});
118 mergeIntervals(acknowledgedIntervals);
121 bool isFullyAcked() {
122 if (acknowledgedIntervals.empty())
124 mergeIntervals(acknowledgedIntervals);
125 return (acknowledgedIntervals.front().start == 0 &&
126 acknowledgedIntervals.front().end == totalLength - 1);
130 void mergeIntervals(std::list<TransmitInterval> &intervals) {
131 if (intervals.empty())
134 for (
auto it = intervals.begin(); it != intervals.end(); ) {
135 auto next = std::next(it);
136 if (next != intervals.end() && next->start <= it->end + 1) {
137 it->end = std::max(it->end, next->end);
138 intervals.erase(next);
154 uint32_t totalLength = 0;
155 inet::Packet *ptr =
nullptr;
156 bool isValid =
false;
160class RlcSduSlidingWindowTransmissionBuffer :
public omnetpp::cObject
163 RlcSduSlidingWindowTransmissionBuffer(uint32_t windowSize,
const std::string &name);
164 ~RlcSduSlidingWindowTransmissionBuffer()
override;
170 virtual uint32_t addSdu(uint32_t length, inet::Packet *sduPtr);
185 virtual bool peekNextSegmentStart(uint32_t &outStart)
const;
190 std::set<uint32_t> handleAck(uint32_t sn, uint32_t start, uint32_t end,
191 unsigned int pollSn,
bool &restartPoll);
201 PendingSegment getRetransmissionSegment(uint32_t sn, uint32_t start,
202 uint32_t end, uint32_t grantSize);
205 virtual int getTotalPendingBytes()
const;
207 bool hasUnacknowledgedData()
const {
return txNext_ > txNextAck_; }
208 bool windowFull()
const {
return txNext_ >= txNextAck_ + amWindowSize_; }
210 virtual bool isInRtxRange(uint32_t sn)
const {
211 return hasTransmitted_ && sn >= txNextAck_ && sn <= highestSnTransmitted_;
214 virtual bool getSduData(uint32_t sn, inet::Packet *&outPtr, uint32_t &outTotalLen) {
215 auto it = txBuffer_.find(sn);
216 if (it == txBuffer_.end())
218 outPtr = it->second.sduPointer;
219 outTotalLen = it->second.totalLength;
223 virtual bool isFullyAcknowledged(uint32_t sn) {
224 auto it = txBuffer_.find(sn);
225 if (it == txBuffer_.end())
227 return it->second.isFullyAcked();
230 uint32_t getTxNext()
const {
return txNext_; }
231 uint32_t getTxNextAck()
const {
return txNextAck_; }
232 uint32_t getCurrentWindowSize()
const {
return txNext_ - txNextAck_; }
233 uint32_t getHighestSnTransmitted()
const {
return highestSnTransmitted_; }
236 std::map<uint32_t, SduTxState> txBuffer_;
237 uint32_t amWindowSize_;
239 bool hasTransmitted_ =
false;
240 uint32_t highestSnTransmitted_ = 0;
243 uint32_t txNext_ = 0;
244 uint32_t txNextAck_ = 0;
Definition AlertReceiver.h:24
Structure representing a specific piece of an SDU for the MAC PDU.
Definition RlcSduSlidingWindowTransmissionBuffer.h:150
uint32_t getBytesTransmitted() const
Calculates how many bytes of this specific SDU have already been transmitted.
Definition RlcSduSlidingWindowTransmissionBuffer.h:59
void markTransmitted(uint32_t start, uint32_t end)
Marks a range as transmitted.
Definition RlcSduSlidingWindowTransmissionBuffer.h:111
uint32_t getNextByteToTx() const
Finds the next available byte range that has not been transmitted.
Definition RlcSduSlidingWindowTransmissionBuffer.h:75
Represents a range of bytes [start, end] for transmission tracking.
Definition RlcSduSlidingWindowTransmissionBuffer.h:31