22#include "ns3/simulator.h" 
   25#include "ns3/lte-rlc-am-header.h" 
   26#include "ns3/lte-rlc-am.h" 
   27#include "ns3/lte-rlc-sdu-status-tag.h" 
   28#include "ns3/lte-rlc-tag.h" 
   94    .AddAttribute (
"PollRetransmitTimer",
 
   95                   "Value of the t-PollRetransmit timer (See section 7.3 of 3GPP TS 36.322)",
 
   99    .AddAttribute (
"ReorderingTimer",
 
  100                   "Value of the t-Reordering timer (See section 7.3 of 3GPP TS 36.322)",
 
  104    .AddAttribute (
"StatusProhibitTimer",
 
  105                   "Value of the t-StatusProhibit timer (See section 7.3 of 3GPP TS 36.322)",
 
  109    .AddAttribute (
"ReportBufferStatusTimer",
 
  110                   "How much to wait to issue a new Report Buffer Status since the last time " 
  111                   "a new SDU was received",     
 
  115    .AddAttribute (
"TxOpportunityForRetxAlwaysBigEnough",
 
  116                   "If true, always pretend that the size of a TxOpportunity is big enough " 
  117                   "for retransmission. If false (default and realistic behavior), no retx " 
  118                   "is performed unless the corresponding TxOpportunity is big enough.",
 
  122    .AddAttribute (
"MaxTxBufferSize",
 
  123                   "Maximum Size of the Transmission Buffer (in Bytes).  If zero is configured, the buffer is unlimited.",
 
  126                   MakeUintegerChecker<uint32_t> ())
 
  204  if (txOpParams.
bytes < 4)
 
  209      NS_ASSERT_MSG (
false, 
"TxOpportunity (size = " << txOpParams.
bytes << 
") too small.\n" 
  210                         << 
"Your MAC scheduler is assigned too few resource blocks.");
 
  221                             << 
"Your MAC scheduler is assigned too few resource blocks.");
 
  234      std::map<uint16_t, PduBuffer>::iterator pduIt;
 
  244          if (pduIt == 
m_rxonBuffer.end () || (!(pduIt->second.m_pduComplete)))
 
  255      while ((sn < 
m_vrMs) && (pduIt != 
m_rxonBuffer.end ()) && (pduIt->second.m_pduComplete))            
 
  295      NS_LOG_LOGIC (
"Sending data from Retransmission Buffer");
 
  301          uint16_t seqNumberValue = sn.
GetValue ();
 
  321                                << 
" packet->GetSize ()=" << packet->
GetSize ());
 
  375                  NS_LOG_INFO (
"Incr RETX_COUNT for SN = " << seqNumberValue);
 
  378                      NS_LOG_INFO (
"Max RETX_COUNT for SN = " << seqNumberValue);
 
  381                  NS_LOG_INFO (
"Move SN = " << seqNumberValue << 
" back to txedBuffer");
 
  398                  NS_LOG_LOGIC (
"TxOpportunity (size = " << txOpParams.
bytes << 
") too small for retransmission of the packet (size = " << packet->
GetSize () << 
")");
 
  404      NS_ASSERT_MSG (
false, 
"m_retxBufferSize > 0, but no PDU considered for retx found");
 
  408      if (txOpParams.
bytes < 7)
 
  411        NS_LOG_LOGIC (
"TxOpportunity (size = " << txOpParams.
bytes << 
") too small for DATA PDU");
 
  412        NS_ASSERT_MSG (
false, 
"TxOpportunity (size = " << txOpParams.
bytes << 
") too small for DATA PDU\n" 
  413                           << 
"Your MAC scheduler is assigned too few resource blocks.");
 
  420          NS_LOG_INFO (
"cannot transmit new RLC PDU due to window stalling");
 
  446  std::vector < Ptr<Packet> > dataField;
 
  459  NS_LOG_LOGIC (
"Next segment size = " << nextSegmentSize);
 
  467  while ( firstSegment && (firstSegment->
GetSize () > 0) && (nextSegmentSize > 0) )
 
  469      NS_LOG_LOGIC (
"WHILE ( firstSegment && firstSegment->GetSize > 0 && nextSegmentSize > 0 )");
 
  471      NS_LOG_LOGIC (
"    nextSegmentSize   = " << nextSegmentSize);
 
  472      if ( (firstSegment->
GetSize () > nextSegmentSize) ||
 
  474           (firstSegment->
GetSize () > 2047)
 
  481          NS_LOG_LOGIC (
"    IF ( firstSegment > nextSegmentSize ||");
 
  509          if (firstSegment->
GetSize () > 0)
 
  516              NS_LOG_LOGIC (
"    Txon buffer: Give back the remaining segment");
 
  541          dataFieldAddedSize = newSegment->
GetSize ();
 
  542          dataField.push_back (newSegment);
 
  550          nextSegmentSize -= dataFieldAddedSize;
 
  558      else if ( (nextSegmentSize - firstSegment->
GetSize () <= 2) || (
m_txonBuffer.size () == 0) )
 
  560          NS_LOG_LOGIC (
"    IF nextSegmentSize - firstSegment->GetSize () <= 2 || txonBuffer.size == 0");
 
  563          dataFieldAddedSize = firstSegment->
GetSize ();
 
  564          dataField.push_back (firstSegment);
 
  572          nextSegmentSize -= dataFieldAddedSize;
 
  581          NS_LOG_LOGIC (
"        Next segment size = " << nextSegmentSize);
 
  590          NS_LOG_LOGIC (
"    IF firstSegment < NextSegmentSize && txonBuffer.size > 0");
 
  592          dataFieldAddedSize = firstSegment->
GetSize ();
 
  593          dataField.push_back (firstSegment);
 
  601          nextSegmentSize -= ((nextSegmentId % 2) ? (2) : (1)) + dataFieldAddedSize;
 
  610          NS_LOG_LOGIC (
"        Next segment size = " << nextSegmentSize);
 
  615          firstSegmentTime = 
m_txonBuffer.begin ()->m_waitingSince;
 
  636  uint8_t framingInfo = 0;
 
  637  std::vector< Ptr<Packet> >::iterator it;
 
  638  it = dataField.begin ();
 
  642  NS_ASSERT_MSG ((*it)->PeekPacketTag (tag), 
"LteRlcSduStatusTag is missing");
 
  643  (*it)->PeekPacketTag (tag);
 
  656  while (it < dataField.end ())
 
  658      NS_LOG_LOGIC (
"Adding SDU/segment to packet, length = " << (*it)->GetSize ());
 
  660      NS_ASSERT_MSG ((*it)->PeekPacketTag (tag), 
"LteRlcSduStatusTag is missing");
 
  661      (*it)->RemovePacketTag (tag);
 
  781  NS_ASSERT_MSG(ret, 
"RlcTag not found in RLC Header. The packet went into a real network?");
 
  845          NS_LOG_LOGIC (
"PDU segment received ( SN = " << seqNumber << 
" )");
 
  849          NS_LOG_LOGIC (
"PDU received ( SN = " << seqNumber << 
" )");
 
  853          NS_ASSERT_MSG (
false, 
"Neither a PDU segment nor a PDU received");
 
  903              NS_ASSERT (it->second.m_byteSegments.size () > 0);
 
  904              NS_ASSERT_MSG (it->second.m_byteSegments.size () == 1, 
"re-segmentation not supported");
 
  905              NS_LOG_LOGIC (
"PDU segment already received, discarded");
 
  909              NS_LOG_LOGIC (
"Place PDU in the reception buffer ( SN = " << seqNumber << 
" )");
 
  924      if ( seqNumber >= 
m_vrH )
 
  926          m_vrH = seqNumber + 1;
 
  936           it->second.m_pduComplete )
 
  940                  it->second.m_pduComplete )
 
  957      if ( seqNumber == 
m_vrR )
 
  961               it->second.m_pduComplete )
 
  966                      it->second.m_pduComplete )
 
  970                                "Too many segments. PDU Reassembly process didn't work");
 
 1046      bool incrementVtA = 
true; 
 
 1048      for (sn = 
m_vtA; sn < ackSn && sn < 
m_vtS; sn++)
 
 1052          uint16_t seqNumberValue = sn.
GetValue ();
 
 1064              incrementVtA = 
false;
 
 1068                  NS_LOG_INFO (
"Move SN = " << seqNumberValue << 
" to retxBuffer");
 
 1089                  NS_LOG_INFO (
"ACKed SN = " << seqNumberValue << 
" from txedBuffer");
 
 1099                  NS_LOG_INFO (
"ACKed SN = " << seqNumberValue << 
" from retxBuffer");
 
 1142                m_vrR << 
" <= " << seqNumber << 
" <= " << 
m_vrMr);
 
 1148  if ( (
m_vrR <= seqNumber) && (seqNumber < 
m_vrMr ) )
 
 1150      NS_LOG_LOGIC (seqNumber << 
" is INSIDE the receiving window");
 
 1155      NS_LOG_LOGIC (seqNumber << 
" is OUTSIDE the receiving window");
 
 1173  bool expectedSnLost;
 
 1177      expectedSnLost = 
true;
 
 1183      expectedSnLost = 
false;
 
 1189  uint8_t extensionBit;
 
 1190  uint16_t lengthIndicator;
 
 1196      if ( extensionBit == 0 )
 
 1206          if ( lengthIndicator >= packet->
GetSize () )
 
 1208              NS_LOG_LOGIC (
"INTERNAL ERROR: Not enough data in the packet (" << packet->
GetSize () << 
"). Needed LI=" << lengthIndicator);
 
 1219  while ( extensionBit == 1 );
 
 1221  std::list < Ptr<Packet> >::iterator it;
 
 1226 else                                               NS_LOG_LOGIC (
"Reassembling State = Unknown state");
 
 1230  NS_LOG_LOGIC (
"Framing Info = " << (uint16_t)framingInfo);
 
 1234  if (!expectedSnLost)
 
 1239                  switch (framingInfo)
 
 1285                  switch (framingInfo)
 
 1365                  switch (framingInfo)
 
 1461                  switch (framingInfo)
 
 1599  Time txonQueueHolDelay (0);
 
 1602      txonQueueHolDelay = now - 
m_txonBuffer.front ().m_waitingSince;
 
 1606  Time retxQueueHolDelay;
 
 1609      Time senderTimestamp;
 
 1618      retxQueueHolDelay = now - senderTimestamp;
 
 1622      retxQueueHolDelay = 
Seconds (0);
 
 1674          it->second.m_pduComplete )
 
 1720          bool pduAvailable = 
m_txedBuffer.at (sn.GetValue ()).m_pdu != 0;
 
 1724               uint16_t snValue = sn.GetValue ();
 
 1725               NS_LOG_INFO (
"Move PDU " << sn << 
" from txedBuffer to retxBuffer");
 
AttributeValue implementation for Boolean.
 
bool IsRunning(void) const
This method is syntactic sugar for !IsExpired().
 
void Cancel(void)
This method is syntactic sugar for the ns3::Simulator::Cancel method.
 
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.
 
virtual void DoTransmitPdcpPdu(Ptr< Packet > p)
RLC SAP.
 
ReassemblingState_t m_reassemblingState
reassembling state
 
std::vector< TxPdu > m_txonBuffer
Transmission buffer.
 
SequenceNumber10 m_vrMr
VR(MR)
 
Time m_statusProhibitTimerValue
status prohibit timer value
 
virtual void DoNotifyHarqDeliveryFailure()
Notify HARQ delivery failure.
 
void ExpirePollRetransmitTimer(void)
Expire poll retransmitter.
 
bool IsInsideReceivingWindow(SequenceNumber10 seqNumber)
method called when the T_status_prohibit timer expires
 
static TypeId GetTypeId(void)
Get the type ID.
 
uint16_t m_windowSize
Constants.
 
Ptr< Packet > m_keepS0
keep S0
 
SequenceNumber10 m_vrH
VR(H)
 
uint32_t m_txonBufferSize
transmit on buffer size
 
SequenceNumber10 m_vrMs
VR(MS)
 
uint16_t m_pollByte
poll byte
 
SequenceNumber10 m_vtS
VT(S)
 
virtual void DoDispose()
Destructor implementation.
 
SequenceNumber10 m_pollSn
POLL_SN.
 
virtual void DoNotifyTxOpportunity(LteMacSapUser::TxOpportunityParameters txOpParams)
MAC SAP.
 
SequenceNumber10 m_vtA
State variables.
 
void ExpireReorderingTimer(void)
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)
 
std::map< uint16_t, PduBuffer > m_rxonBuffer
Reception buffer.
 
bool m_txOpportunityForRetxAlwaysBigEnough
transmit opportunity for retransmit?
 
bool m_pollRetransmitTimerJustExpired
poll retransmit timer just expired?
 
void ExpireStatusProhibitTimer(void)
method called when the T_status_prohibit timer expires
 
Time m_reorderingTimerValue
reordering timer value
 
uint32_t m_maxTxBufferSize
maximum transmission buffer size
 
EventId m_pollRetransmitTimer
Timers.
 
uint16_t m_maxRetxThreshold
Configurable parameters.
 
SequenceNumber10 m_vrX
VR(X)
 
void ExpireRbsTimer(void)
Expire RBS timer.
 
std::vector< RetxPdu > m_retxBuffer
Buffer for PDUs considered for retransmission.
 
uint32_t m_byteWithoutPoll
byte without poll
 
std::list< Ptr< Packet > > m_sdusBuffer
List of SDUs in a packet (PDU)
 
uint32_t m_pduWithoutPoll
Counters.
 
Time m_pollRetransmitTimerValue
poll retransmit time value
 
void DoReportBufferStatus()
Report buffer status.
 
void ReassembleAndDeliver(Ptr< Packet > packet)
Reassemble and deliver.
 
uint32_t m_txedBufferSize
transmit ed buffer size
 
uint16_t m_pollPdu
poll PDU
 
virtual void DoReceivePdu(LteMacSapUser::ReceivePduParameters rxPduParams)
Receive PDU function.
 
EventId m_reorderingTimer
reordering timer
 
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.
 
LteMacSapProvider * m_macSapProvider
MAC SAP provider.
 
virtual void DoDispose()
Destructor implementation.
 
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...
 
void SetStatus(uint8_t status)
Set status function.
 
uint8_t GetStatus(void) const
Get status function.
 
bool RemovePacketTag(Tag &tag)
Remove a packet tag.
 
uint32_t RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer.
 
void AddAtEnd(Ptr< const Packet > packet)
Concatenate the input packet at the end of the current packet.
 
void AddHeader(const Header &header)
Add header to this packet.
 
void RemoveAtStart(uint32_t size)
Remove size bytes from the start of the current packet.
 
bool FindFirstMatchingByteTag(Tag &tag) const
Finds the first tag matching the parameter Tag type.
 
void AddPacketTag(const Tag &tag) const
Add a packet tag.
 
uint32_t PeekHeader(Header &header) const
Deserialize but does not remove the header from the internal buffer.
 
Ptr< Packet > CreateFragment(uint32_t start, uint32_t length) const
Create a new packet which contains a fragment of the original packet.
 
void AddByteTag(const Tag &tag) const
Tag each byte included in this packet with a new byte tag.
 
Ptr< Packet > Copy(void) const
performs a COW copy of the packet.
 
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
 
Tag to calculate the per-PDU delay from eNb RLC to UE RLC.
 
void SetSenderTimestamp(Time senderTimestamp)
Set the sender timestamp.
 
Time GetSenderTimestamp(void) const
Get the instant when the RLC delivers the PDU to the MAC SAP provider.
 
uint16_t GetValue() const
Extracts the numeric value of the sequence number.
 
void SetModulusBase(SequenceNumber10 modulusBase)
Set modulus base.
 
static EventId Schedule(Time const &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
 
static Time Now(void)
Return the current simulation virtual time.
 
Simulation virtual time values and global simulation resolution.
 
int64_t GetMilliSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
 
int64_t GetNanoSeconds(void) 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(void)
 
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
 
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
 
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
 
#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.
 
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.
 
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
 
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.
 
uint16_t rnti
the C-RNTI identifying the UE
 
uint8_t lcid
the logical channel id corresponding to the sending RLC instance
 
uint8_t componentCarrierId
the component carrier id corresponding to the sending Mac istance
 
Ptr< Packet > pdu
the RLC PDU
 
uint8_t harqProcessId
the HARQ process id that was passed by the MAC in the call to NotifyTxOpportunity that generated this...
 
uint8_t layer
the layer value that was passed by the MAC in the call to NotifyTxOpportunity that generated this PDU
 
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.