17#include "ns3/simulator.h" 
   83            .AddAttribute(
"PollRetransmitTimer",
 
   84                          "Value of the t-PollRetransmit timer (See section 7.3 of 3GPP TS 36.322)",
 
   88            .AddAttribute(
"ReorderingTimer",
 
   89                          "Value of the t-Reordering timer (See section 7.3 of 3GPP TS 36.322)",
 
   93            .AddAttribute(
"StatusProhibitTimer",
 
   94                          "Value of the t-StatusProhibit timer (See section 7.3 of 3GPP TS 36.322)",
 
   99                "ReportBufferStatusTimer",
 
  100                "How much to wait to issue a new Report Buffer Status since the last time " 
  101                "a new SDU was received",
 
  105            .AddAttribute(
"TxOpportunityForRetxAlwaysBigEnough",
 
  106                          "If true, always pretend that the size of a TxOpportunity is big enough " 
  107                          "for retransmission. If false (default and realistic behavior), no retx " 
  108                          "is performed unless the corresponding TxOpportunity is big enough.",
 
  112            .AddAttribute(
"MaxTxBufferSize",
 
  113                          "Maximum Size of the Transmission Buffer (in Bytes).  If zero is " 
  114                          "configured, the buffer is unlimited.",
 
 
  159        p->AddPacketTag(tag);
 
 
  192    if (txOpParams.
bytes < 4)
 
  198                      "TxOpportunity (size = " 
  199                          << txOpParams.
bytes << 
") too small.\n" 
  200                          << 
"Your MAC scheduler is assigned too few resource blocks.");
 
  210                                                  << 
") too small for the STATUS PDU (size = " 
  213                          "TxOpportunity (size = " 
  214                              << txOpParams.
bytes << 
") too small for the STATUS PDU (size = " 
  216                              << 
"Your MAC scheduler is assigned too few resource blocks.");
 
  239            if (pduIt == 
m_rxonBuffer.end() || (!(pduIt->second.m_pduComplete)))
 
  250        while ((sn < 
m_vrMs) && (pduIt != 
m_rxonBuffer.end()) && (pduIt->second.m_pduComplete))
 
  259                      "first SN not reported as missing = " << sn << 
", VR(MS) = " << 
m_vrMs);
 
  263        packet->AddHeader(rlcAmHeader);
 
  275        params.layer = txOpParams.
layer;
 
  276        params.harqProcessId = txOpParams.
harqId;
 
  291        NS_LOG_LOGIC(
"Sending data from Retransmission Buffer");
 
  297            uint16_t seqNumberValue = sn.
GetValue();
 
  305                if ((packet->GetSize() <= txOpParams.
bytes) ||
 
  310                    packet->RemoveHeader(rlcAmHeader);
 
  318                                 << 
" packet->GetSize ()=" << packet->GetSize());
 
  353                    packet->AddHeader(rlcAmHeader);
 
  369                    params.layer = txOpParams.
layer;
 
  370                    params.harqProcessId = txOpParams.
harqId;
 
  377                    NS_LOG_INFO(
"Incr RETX_COUNT for SN = " << seqNumberValue);
 
  380                        NS_LOG_INFO(
"Max RETX_COUNT for SN = " << seqNumberValue);
 
  383                    NS_LOG_INFO(
"Move SN = " << seqNumberValue << 
" back to txedBuffer");
 
  405                                 << 
") too small for retransmission of the packet (size = " 
  406                                 << packet->GetSize() << 
")");
 
  412        NS_ASSERT_MSG(
false, 
"m_retxBufferSize > 0, but no PDU considered for retx found");
 
  416        if (txOpParams.
bytes < 7)
 
  420                                                  << 
") too small for DATA PDU");
 
  422                          "TxOpportunity (size = " 
  423                              << txOpParams.
bytes << 
") too small for DATA PDU\n" 
  424                              << 
"Your MAC scheduler is assigned too few resource blocks.");
 
  431            NS_LOG_INFO(
"cannot transmit new RLC PDU due to window stalling");
 
  457    std::vector<Ptr<Packet>> dataField;
 
  470    NS_LOG_LOGIC(
"Next segment size = " << nextSegmentSize);
 
  478    while (firstSegment && (firstSegment->GetSize() > 0) && (nextSegmentSize > 0))
 
  480        NS_LOG_LOGIC(
"WHILE ( firstSegment && firstSegment->GetSize > 0 && nextSegmentSize > 0 )");
 
  481        NS_LOG_LOGIC(
"    firstSegment size = " << firstSegment->GetSize());
 
  483        if ((firstSegment->GetSize() > nextSegmentSize) ||
 
  485            (firstSegment->GetSize() > 2047))
 
  489            uint32_t currSegmentSize = std::min(firstSegment->GetSize(), nextSegmentSize);
 
  491            NS_LOG_LOGIC(
"    IF ( firstSegment > nextSegmentSize ||");
 
  496            Ptr<Packet> newSegment = firstSegment->CreateFragment(0, currSegmentSize);
 
  497            NS_LOG_LOGIC(
"    newSegment size   = " << newSegment->GetSize());
 
  504            firstSegment->RemovePacketTag(oldTag);
 
  505            newSegment->RemovePacketTag(newTag);
 
  518            firstSegment->RemoveAtStart(currSegmentSize);
 
  520                "    firstSegment size (after RemoveAtStart) = " << firstSegment->GetSize());
 
  521            if (firstSegment->GetSize() > 0)
 
  523                firstSegment->AddPacketTag(oldTag);
 
  528                NS_LOG_LOGIC(
"    Txon buffer: Give back the remaining segment");
 
  547            firstSegment = 
nullptr;
 
  550            newSegment->AddPacketTag(newTag);
 
  553            dataFieldAddedSize = newSegment->GetSize();
 
  554            dataField.push_back(newSegment);
 
  555            newSegment = 
nullptr;
 
  562            nextSegmentSize -= dataFieldAddedSize;
 
  570        else if ((nextSegmentSize - firstSegment->GetSize() <= 2) || 
m_txonBuffer.empty())
 
  573                "    IF nextSegmentSize - firstSegment->GetSize () <= 2 || txonBuffer.size == 0");
 
  576            dataFieldAddedSize = firstSegment->GetSize();
 
  577            dataField.push_back(firstSegment);
 
  578            firstSegment = 
nullptr;
 
  585            nextSegmentSize -= dataFieldAddedSize;
 
  593                    "        First SDU size    = " << 
m_txonBuffer.begin()->m_pdu->GetSize());
 
  595            NS_LOG_LOGIC(
"        Next segment size = " << nextSegmentSize);
 
  604            NS_LOG_LOGIC(
"    IF firstSegment < NextSegmentSize && txonBuffer.size > 0");
 
  606            dataFieldAddedSize = firstSegment->GetSize();
 
  607            dataField.push_back(firstSegment);
 
  615            nextSegmentSize -= ((nextSegmentId % 2) ? (2) : (1)) + dataFieldAddedSize;
 
  623                    "        First SDU size    = " << 
m_txonBuffer.begin()->m_pdu->GetSize());
 
  625            NS_LOG_LOGIC(
"        Next segment size = " << nextSegmentSize);
 
  630            firstSegmentTime = 
m_txonBuffer.begin()->m_waitingSince;
 
  650    uint8_t framingInfo = 0;
 
  651    auto it = dataField.begin();
 
  655    NS_ASSERT_MSG((*it)->PeekPacketTag(tag), 
"LteRlcSduStatusTag is missing");
 
  656    (*it)->PeekPacketTag(tag);
 
  668    while (it < dataField.end())
 
  670        NS_LOG_LOGIC(
"Adding SDU/segment to packet, length = " << (*it)->GetSize());
 
  672        NS_ASSERT_MSG((*it)->PeekPacketTag(tag), 
"LteRlcSduStatusTag is missing");
 
  673        (*it)->RemovePacketTag(tag);
 
  674        if (packet->GetSize() > 0)
 
  676            packet->AddAtEnd(*it);
 
  745    packet->AddHeader(rlcAmHeader);
 
  762    params.layer = txOpParams.
layer;
 
  763    params.harqProcessId = txOpParams.
harqId;
 
 
  790    NS_ASSERT_MSG(ret, 
"RlcTag not found in RLC Header. The packet went into a real network?");
 
  858            NS_LOG_LOGIC(
"PDU segment received ( SN = " << seqNumber << 
" )");
 
  862            NS_LOG_LOGIC(
"PDU received ( SN = " << seqNumber << 
" )");
 
  866            NS_ASSERT_MSG(
false, 
"Neither a PDU segment nor a PDU received");
 
  919                NS_ASSERT(!it->second.m_byteSegments.empty());
 
  921                              "re-segmentation not supported");
 
  922                NS_LOG_LOGIC(
"PDU segment already received, discarded");
 
  926                NS_LOG_LOGIC(
"Place PDU in the reception buffer ( SN = " << seqNumber << 
" )");
 
  939        if (seqNumber >= 
m_vrH)
 
  941            m_vrH = seqNumber + 1;
 
  950        if (it != 
m_rxonBuffer.end() && it->second.m_pduComplete)
 
  953            while (it != 
m_rxonBuffer.end() && it->second.m_pduComplete)
 
  974        if (seqNumber == 
m_vrR)
 
  977            if (it != 
m_rxonBuffer.end() && it->second.m_pduComplete)
 
  981                while (it != 
m_rxonBuffer.end() && it->second.m_pduComplete)
 
  985                                  "Too many segments. PDU Reassembly process didn't work");
 
 1060        bool incrementVtA = 
true;
 
 1063        for (sn = 
m_vtA; sn < ackSn && sn < 
m_vtS; sn++)
 
 1067            uint16_t seqNumberValue = sn.
GetValue();
 
 1078                incrementVtA = 
false;
 
 1082                    NS_LOG_INFO(
"Move SN = " << seqNumberValue << 
" to retxBuffer");
 
 1105                    NS_LOG_INFO(
"ACKed SN = " << seqNumberValue << 
" from txedBuffer");
 
 1116                    NS_LOG_INFO(
"ACKed SN = " << seqNumberValue << 
" from retxBuffer");
 
 
 1161        NS_LOG_LOGIC(seqNumber << 
" is INSIDE the receiving window");
 
 1166        NS_LOG_LOGIC(seqNumber << 
" is OUTSIDE the receiving window");
 
 
 1176    bool ret = packet->FindFirstMatchingByteTag(rlcTag);
 
 1178    packet->RemoveHeader(rlcAmHeader);
 
 1179    ret = packet->FindFirstMatchingByteTag(rlcTag);
 
 1183    bool expectedSnLost;
 
 1187        expectedSnLost = 
true;
 
 1189                                                        << 
". Current SN = " << currSeqNumber);
 
 1194        expectedSnLost = 
false;
 
 1196                                                 << 
". Current SN = " << currSeqNumber);
 
 1201    uint8_t extensionBit;
 
 1202    uint16_t lengthIndicator;
 
 1208        if (extensionBit == 0)
 
 1218            if (lengthIndicator >= packet->GetSize())
 
 1220                NS_LOG_LOGIC(
"INTERNAL ERROR: Not enough data in the packet (" 
 1221                             << packet->GetSize() << 
"). Needed LI=" << lengthIndicator);
 
 1226            Ptr<Packet> data_field = packet->CreateFragment(0, lengthIndicator);
 
 1227            packet->RemoveAtStart(lengthIndicator);
 
 1231    } 
while (extensionBit == 1);
 
 1236        NS_LOG_LOGIC(
"Reassembling State = 'WAITING_S0_FULL'");
 
 1248    NS_LOG_LOGIC(
"Framing Info = " << (uint16_t)framingInfo);
 
 1252    if (!expectedSnLost)
 
 1257            switch (framingInfo)
 
 1298                    "INTERNAL ERROR: Transition not possible. FI = " << (
uint32_t)framingInfo);
 
 1304            switch (framingInfo)
 
 1370                    "INTERNAL ERROR: Transition not possible. FI = " << (
uint32_t)framingInfo);
 
 1387            switch (framingInfo)
 
 1478                    "INTERNAL ERROR: Transition not possible. FI = " << (
uint32_t)framingInfo);
 
 1484            switch (framingInfo)
 
 1596                    "INTERNAL ERROR: Transition not possible. FI = " << (
uint32_t)framingInfo);
 
 
 1623    Time txonQueueHolDelay(0);
 
 1626        txonQueueHolDelay = now - 
m_txonBuffer.front().m_waitingSince;
 
 1630    Time retxQueueHolDelay;
 
 1633        Time senderTimestamp;
 
 1642        retxQueueHolDelay = now - senderTimestamp;
 
 1646        retxQueueHolDelay = 
Seconds(0);
 
 
 1697    while (it != 
m_rxonBuffer.end() && it->second.m_pduComplete)
 
 
 1740                                                                          << 
" to retxBuffer");
 
 1743            bool pduAvailable = (bool)
m_txedBuffer.at(sn.GetValue()).m_pdu;
 
 1747                uint16_t snValue = sn.GetValue();
 
 1748                NS_LOG_INFO(
"Move PDU " << sn << 
" from txedBuffer to retxBuffer");
 
 
AttributeValue implementation for Boolean.
void Cancel()
This method is syntactic sugar for the ns3::Simulator::Cancel method.
bool IsPending() const
This method is syntactic sugar for !IsExpired().
virtual void TransmitPdu(TransmitPduParameters params)=0
send an RLC PDU to the MAC for transmission.
virtual void ReportBufferStatus(ReportBufferStatusParameters params)=0
Report the RLC buffer status to the MAC.
LTE RLC Acknowledged Mode (AM), see 3GPP TS 36.322.
ReassemblingState_t m_reassemblingState
reassembling state
void ExpireStatusProhibitTimer()
method called when the T_status_prohibit timer expires
SequenceNumber10 m_vrMr
VR(MR)
Time m_statusProhibitTimerValue
status prohibit timer value
bool IsInsideReceivingWindow(SequenceNumber10 seqNumber)
method called when the T_status_prohibit timer expires
uint16_t m_windowSize
Constants.
Ptr< Packet > m_keepS0
keep S0
void DoNotifyHarqDeliveryFailure() override
Notify HARQ delivery failure.
SequenceNumber10 m_vrH
VR(H)
uint32_t m_txonBufferSize
transmit on buffer size
std::vector< TxPdu > m_txonBuffer
Transmission buffer.
SequenceNumber10 m_vrMs
VR(MS)
uint16_t m_pollByte
poll byte
SequenceNumber10 m_vtS
VT(S)
void DoDispose() override
Destructor implementation.
SequenceNumber10 m_pollSn
POLL_SN.
SequenceNumber10 m_vtA
State variables.
void ExpireReorderingTimer()
This method will schedule a timeout at WaitReplyTimeout interval in the future, unless a timer is alr...
SequenceNumber10 m_vtMs
VT(MS)
EventId m_rbsTimer
RBS timer.
uint32_t m_statusPduBufferSize
status PDU buffer size
Ptr< Packet > m_controlPduBuffer
Control PDU buffer (just one PDU)
bool m_txOpportunityForRetxAlwaysBigEnough
transmit opportunity for retransmit?
bool m_pollRetransmitTimerJustExpired
poll retransmit timer just expired?
void DoTransmitPdcpPdu(Ptr< Packet > p) override
RLC SAP.
Time m_reorderingTimerValue
reordering timer value
uint32_t m_maxTxBufferSize
maximum transmission buffer size
void DoReceivePdu(LteMacSapUser::ReceivePduParameters rxPduParams) override
Receive PDU function.
std::list< Ptr< Packet > > m_sdusBuffer
List of SDUs in a packet (PDU)
EventId m_pollRetransmitTimer
Timers.
uint16_t m_maxRetxThreshold
Configurable parameters.
SequenceNumber10 m_vrX
VR(X)
std::vector< RetxPdu > m_retxBuffer
Buffer for PDUs considered for retransmission.
uint32_t m_byteWithoutPoll
byte without poll
void ExpireRbsTimer()
Expire RBS timer.
uint32_t m_pduWithoutPoll
Counters.
static TypeId GetTypeId()
Get the type ID.
void DoNotifyTxOpportunity(LteMacSapUser::TxOpportunityParameters txOpParams) override
MAC SAP.
Time m_pollRetransmitTimerValue
poll retransmit time value
void DoReportBufferStatus()
Report buffer status.
void ReassembleAndDeliver(Ptr< Packet > packet)
Reassemble and deliver.
std::map< uint16_t, PduBuffer > m_rxonBuffer
Reception buffer.
uint32_t m_txedBufferSize
transmit ed buffer size
uint16_t m_pollPdu
poll PDU
EventId m_reorderingTimer
reordering timer
void ExpirePollRetransmitTimer()
Expire poll retransmitter.
SequenceNumber10 m_vrR
VR(R)
SequenceNumber10 m_expectedSeqNumber
Expected Sequence Number.
uint32_t m_retxBufferSize
retransmit buffer size
EventId m_statusProhibitTimer
status prohibit timer
std::vector< RetxPdu > m_txedBuffer
Buffer for transmitted and retransmitted PDUs that have not been acked but are not considered for ret...
bool m_statusPduRequested
status PDU requested
Time m_rbsTimerValue
RBS timer value.
This abstract base class defines the API to interact with the Radio Link Control (LTE_RLC) in LTE,...
LteRlcSapUser * m_rlcSapUser
RLC SAP user.
TracedCallback< Ptr< const Packet > > m_txDropTrace
The trace source fired when the RLC drops a packet before transmission.
TracedCallback< uint16_t, uint8_t, uint32_t, uint64_t > m_rxPdu
Used to inform of a PDU reception from the MAC SAP user.
void DoDispose() override
Destructor implementation.
LteMacSapProvider * m_macSapProvider
MAC SAP provider.
TracedCallback< uint16_t, uint8_t, uint32_t > m_txPdu
Used to inform of a PDU delivery to the MAC SAP provider.
virtual void ReceivePdcpPdu(Ptr< Packet > p)=0
Called by the RLC entity to notify the PDCP entity of the reception of a new PDCP PDU.
This class implements a tag that carries the status of a RLC SDU for the fragmentation process Status...
uint8_t GetStatus() const
Get status function.
void SetStatus(uint8_t status)
Set status function.
void AddAtEnd(Ptr< const Packet > packet)
Concatenate the input packet at the end of the current packet.
uint32_t GetSize() const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
bool FindFirstMatchingByteTag(Tag &tag) const
Finds the first tag matching the parameter Tag type.
uint32_t PeekHeader(Header &header) const
Deserialize but does not remove the header from the internal buffer.
Smart pointer class similar to boost::intrusive_ptr.
Tag to calculate the per-PDU delay from eNb RLC to UE RLC.
Time GetSenderTimestamp() const
Get the instant when the RLC delivers the PDU to the MAC SAP provider.
void SetSenderTimestamp(Time senderTimestamp)
Set the sender timestamp.
uint16_t GetValue() const
Extracts the numeric value of the sequence number.
void SetModulusBase(SequenceNumber10 modulusBase)
Set modulus base.
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
static Time Now()
Return the current simulation virtual time.
Simulation virtual time values and global simulation resolution.
int64_t GetNanoSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
int64_t GetMilliSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
AttributeValue implementation for Time.
a unique identifier for an interface.
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Hold an unsigned integer type.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Ptr< const AttributeChecker > MakeBooleanChecker()
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Ptr< const AttributeChecker > MakeTimeChecker()
Helper to make an unbounded Time checker.
Ptr< const AttributeChecker > MakeUintegerChecker()
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Time Seconds(double value)
Construct a Time in the indicated unit.
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Parameters for LteMacSapProvider::ReportBufferStatus.
uint32_t txQueueSize
the current size of the RLC transmission queue
uint16_t retxQueueHolDelay
the Head Of Line delay of the retransmission queue
uint16_t txQueueHolDelay
the Head Of Line delay of the transmission queue
uint32_t retxQueueSize
the current size of the RLC retransmission queue in bytes
uint8_t lcid
the logical channel id corresponding to the sending RLC instance
uint16_t rnti
the C-RNTI identifying the UE
uint16_t statusPduSize
the current size of the pending STATUS RLC PDU message in bytes
Parameters for LteMacSapProvider::TransmitPdu.
Parameters for LteMacSapUser::ReceivePdu.
Ptr< Packet > p
the RLC PDU to be received
Parameters for LteMacSapUser::NotifyTxOpportunity.
uint8_t harqId
the HARQ ID
uint32_t bytes
the number of bytes to transmit
uint8_t componentCarrierId
the component carrier id
uint8_t layer
the layer of transmission (MIMO)
Store an incoming (from layer above us) PDU, waiting to transmit it.