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.",
 
  197       NS_LOG_LOGIC (
"TxOpportunity (size = " << bytes << 
") too small");
 
  198       NS_ASSERT_MSG (
false, 
"TxOpportunity (size = " << bytes << 
") too small.\n" 
  199                          << 
"Your MAC scheduler is assigned too few resource blocks.");
 
  210                              << 
"Your MAC scheduler is assigned too few resource blocks.");
 
  223       std::map<uint16_t, PduBuffer>::iterator pduIt;
 
  227           if (!rlcAmHeader.OneMoreNackWouldFitIn (bytes))
 
  233           if (pduIt == 
m_rxonBuffer.end () || (!(pduIt->second.m_pduComplete)))
 
  236               rlcAmHeader.PushNack (sn.GetValue ());              
 
  244       while ((sn < m_vrMs) && (pduIt != 
m_rxonBuffer.end ()) && (pduIt->second.m_pduComplete))            
 
  246           NS_LOG_LOGIC (
"SN = " << sn << 
" < " << m_vrMs << 
" = " << (sn < m_vrMs));
 
  252       NS_ASSERT_MSG (sn <= m_vrMs, 
"first SN not reported as missing = " << sn << 
", VR(MS) = " << m_vrMs);      
 
  253       rlcAmHeader.SetAckSn (sn); 
 
  264       params.
layer = layer;
 
  278       NS_LOG_LOGIC (
"Sending data from Retransmission Buffer");
 
  285           uint16_t seqNumberValue = sn.
GetValue ();
 
  293               if (( packet->
GetSize () <= bytes )
 
  307                                 << 
" packet->GetSize ()=" << packet->
GetSize ());
 
  345                   params.
layer = layer;
 
  351                   NS_LOG_INFO (
"Incr RETX_COUNT for SN = " << seqNumberValue);
 
  354                       NS_LOG_INFO (
"Max RETX_COUNT for SN = " << seqNumberValue);
 
  357                   NS_LOG_INFO (
"Move SN = " << seqNumberValue << 
" back to txedBuffer");
 
  372                   NS_LOG_LOGIC (
"TxOpportunity (size = " << bytes << 
") too small for retransmission of the packet (size = " << packet->
GetSize () << 
")");
 
  378       NS_ASSERT_MSG (found, 
"m_retxBufferSize > 0, but no PDU considered for retx found");
 
  385         NS_LOG_LOGIC (
"TxOpportunity (size = " << bytes << 
") too small for DATA PDU");
 
  386         NS_ASSERT_MSG (
false, 
"TxOpportunity (size = " << bytes << 
") too small for DATA PDU\n" 
  387                            << 
"Your MAC scheduler is assigned too few resource blocks.");
 
  394           NS_LOG_INFO (
"cannot transmit new RLC PDU due to window stalling");
 
  417   uint32_t nextSegmentSize = bytes - 4;
 
  418   uint32_t nextSegmentId = 1;
 
  419   uint32_t dataFieldTotalSize = 0;
 
  420   uint32_t dataFieldAddedSize = 0;
 
  421   std::vector < Ptr<Packet> > dataField;
 
  434   NS_LOG_LOGIC (
"Next segment size = " << nextSegmentSize);
 
  441   while ( firstSegment && (firstSegment->
GetSize () > 0) && (nextSegmentSize > 0) )
 
  443       NS_LOG_LOGIC (
"WHILE ( firstSegment && firstSegment->GetSize > 0 && nextSegmentSize > 0 )");
 
  445       NS_LOG_LOGIC (
"    nextSegmentSize   = " << nextSegmentSize);
 
  446       if ( (firstSegment->
GetSize () > nextSegmentSize) ||
 
  448            (firstSegment->
GetSize () > 2047)
 
  453           uint32_t currSegmentSize = std::min (firstSegment->
GetSize (), nextSegmentSize);
 
  455           NS_LOG_LOGIC (
"    IF ( firstSegment > nextSegmentSize ||");
 
  483           if (firstSegment->
GetSize () > 0)
 
  490               NS_LOG_LOGIC (
"    Txon buffer: Give back the remaining segment");
 
  515           dataFieldAddedSize = newSegment->
GetSize ();
 
  516           dataFieldTotalSize += dataFieldAddedSize;
 
  517           dataField.push_back (newSegment);
 
  525           nextSegmentSize -= dataFieldAddedSize;
 
  533       else if ( (nextSegmentSize - firstSegment->
GetSize () <= 2) || (
m_txonBuffer.size () == 0) )
 
  535           NS_LOG_LOGIC (
"    IF nextSegmentSize - firstSegment->GetSize () <= 2 || txonBuffer.size == 0");
 
  538           dataFieldAddedSize = firstSegment->
GetSize ();
 
  539           dataFieldTotalSize += dataFieldAddedSize;
 
  540           dataField.push_back (firstSegment);
 
  548           nextSegmentSize -= dataFieldAddedSize;
 
  557           NS_LOG_LOGIC (
"        Next segment size = " << nextSegmentSize);
 
  566           NS_LOG_LOGIC (
"    IF firstSegment < NextSegmentSize && txonBuffer.size > 0");
 
  568           dataFieldAddedSize = firstSegment->
GetSize ();
 
  569           dataFieldTotalSize += dataFieldAddedSize;
 
  570           dataField.push_back (firstSegment);
 
  576           rlcAmHeader.PushLengthIndicator (firstSegment->
GetSize ());
 
  578           nextSegmentSize -= ((nextSegmentId % 2) ? (2) : (1)) + dataFieldAddedSize;
 
  587           NS_LOG_LOGIC (
"        Next segment size = " << nextSegmentSize);
 
  603   rlcAmHeader.SetSequenceNumber ( 
m_vtS++ );
 
  606   rlcAmHeader.SetSegmentOffset (0);
 
  612   uint8_t framingInfo = 0;
 
  613   std::vector< Ptr<Packet> >::iterator it;
 
  614   it = dataField.begin ();
 
  618   (*it)->RemovePacketTag (tag);
 
  629   (*it)->AddPacketTag (tag);
 
  632   while (it < dataField.end ())
 
  634       NS_LOG_LOGIC (
"Adding SDU/segment to packet, length = " << (*it)->GetSize ());
 
  642   (*it)->RemovePacketTag (tag);
 
  652   (*it)->AddPacketTag (tag);
 
  655   rlcAmHeader.SetFramingInfo (framingInfo);
 
  705   m_txedBuffer.at ( rlcAmHeader.GetSequenceNumber ().GetValue () ).m_pdu = packet->
Copy ();
 
  706   m_txedBuffer.at ( rlcAmHeader.GetSequenceNumber ().GetValue () ).m_retxCount = 0;
 
  718   params.layer = layer;
 
  719   params.harqProcessId = harqId;
 
  750   if ( rlcAmHeader.IsDataPdu () )
 
  808           NS_LOG_LOGIC (
"PDU segment received ( SN = " << seqNumber << 
" )");
 
  812           NS_LOG_LOGIC (
"PDU received ( SN = " << seqNumber << 
" )");
 
  816           NS_ASSERT_MSG (
false, 
"Neither a PDU segment nor a PDU received");
 
  866               NS_ASSERT (it->second.m_byteSegments.size () > 0);
 
  867               NS_ASSERT_MSG (it->second.m_byteSegments.size () == 1, 
"re-segmentation not supported");
 
  868               NS_LOG_LOGIC (
"PDU segment already received, discarded");
 
  872               NS_LOG_LOGIC (
"Place PDU in the reception buffer ( SN = " << seqNumber << 
" )");
 
  887       if ( seqNumber >= 
m_vrH )
 
  889           m_vrH = seqNumber + 1;
 
  899            it->second.m_pduComplete )
 
  903                   it->second.m_pduComplete )
 
  920       if ( seqNumber == 
m_vrR )
 
  924                it->second.m_pduComplete )
 
  929                       it->second.m_pduComplete )
 
  933                                 "Too many segments. PDU Reassembly process didn't work");
 
  990   else if ( rlcAmHeader.IsControlPdu () )
 
 1009       bool incrementVtA = 
true; 
 
 1011       for (sn = 
m_vtA; sn < ackSn && sn < 
m_vtS; sn++)
 
 1015           uint16_t seqNumberValue = sn.
GetValue ();
 
 1023           if (rlcAmHeader.IsNackPresent (sn))
 
 1027               incrementVtA = 
false;
 
 1031                   NS_LOG_INFO (
"Move SN = " << seqNumberValue << 
" to retxBuffer");
 
 1050                   NS_LOG_INFO (
"ACKed SN = " << seqNumberValue << 
" from txedBuffer");
 
 1059                   NS_LOG_INFO (
"ACKed SN = " << seqNumberValue << 
" from retxBuffer");
 
 1077               m_vtS.SetModulusBase (
m_vtA);
 
 1101                 m_vrR << 
" <= " << seqNumber << 
" <= " << 
m_vrMr);
 
 1107   if ( (
m_vrR <= seqNumber) && (seqNumber < 
m_vrMr ) )
 
 1109       NS_LOG_LOGIC (seqNumber << 
" is INSIDE the receiving window");
 
 1114       NS_LOG_LOGIC (seqNumber << 
" is OUTSIDE the receiving window");
 
 1127   bool expectedSnLost;
 
 1131       expectedSnLost = 
true;
 
 1137       expectedSnLost = 
false;
 
 1143   uint8_t extensionBit;
 
 1144   uint16_t lengthIndicator;
 
 1150       if ( extensionBit == 0 )
 
 1160           if ( lengthIndicator >= packet->
GetSize () )
 
 1162               NS_LOG_LOGIC (
"INTERNAL ERROR: Not enough data in the packet (" << packet->
GetSize () << 
"). Needed LI=" << lengthIndicator);
 
 1173   while ( extensionBit == 1 );
 
 1175   std::list < Ptr<Packet> >::iterator it;
 
 1180   else                                              NS_LOG_LOGIC (
"Reassembling State = Unknown state");
 
 1183   NS_LOG_LOGIC (
"Framing Info = " << (uint16_t)framingInfo);
 
 1187   if (!expectedSnLost)
 
 1192                   switch (framingInfo)
 
 1232                               NS_LOG_LOGIC (
"INTERNAL ERROR: Transition not possible. FI = " << (uint32_t) framingInfo);
 
 1238                   switch (framingInfo)
 
 1303                               NS_LOG_LOGIC (
"INTERNAL ERROR: Transition not possible. FI = " << (uint32_t) framingInfo);
 
 1318                   switch (framingInfo)
 
 1408                               NS_LOG_LOGIC (
"INTERNAL ERROR: Transition not possible. FI = " << (uint32_t) framingInfo);
 
 1414                   switch (framingInfo)
 
 1525                               NS_LOG_LOGIC (
"INTERNAL ERROR: Transition not possible. FI = " << (uint32_t) framingInfo);
 
 1552   Time txonQueueHolDelay (0);
 
 1555       RlcTag txonQueueHolTimeTag;
 
 1556       m_txonBuffer.front ()->PeekPacketTag (txonQueueHolTimeTag);
 
 1561   Time retxQueueHolDelay;
 
 1562   RlcTag retxQueueHolTimeTag;
 
 1577       retxQueueHolDelay = 
Seconds (0);
 
 1629           it->second.m_pduComplete )
 
 1680                NS_LOG_INFO (
"Move PDU " << sn << 
" from txedBuffer to retxBuffer");
 
uint32_t RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer. 
 
TracedCallback< uint16_t, uint8_t, uint32_t > m_txPdu
Used to inform of a PDU delivery to the MAC SAP provider. 
 
bool FindFirstMatchingByteTag(Tag &tag) const 
Finds the first tag matching the parameter Tag type. 
 
Simulation virtual time values and global simulation resolution. 
 
EventId m_statusProhibitTimer
 
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
 
uint32_t m_byteWithoutPoll
 
AttributeValue implementation for Boolean. 
 
uint16_t GetValue() const 
Extracts the numeric value of the sequence number. 
 
virtual void DoReceivePdu(Ptr< Packet > p)
 
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system. 
 
virtual void DoNotifyTxOpportunity(uint32_t bytes, uint8_t layer, uint8_t harqId)
MAC SAP. 
 
uint32_t m_statusPduBufferSize
 
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
 
void DoReportBufferStatus()
 
void AddPacketTag(const Tag &tag) const 
Add a packet tag. 
 
Tag to calculate the per-PDU delay from eNb RLC to UE RLC. 
 
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file...
 
Time m_reorderingTimerValue
 
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name. 
 
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit. 
 
Time m_pollRetransmitTimerValue
 
uint32_t GetSize(void) const 
Returns the the size in bytes of the packet (including the zero-filled initial payload). 
 
EventId m_reorderingTimer
 
uint32_t retxQueueSize
the current size of the RLC retransmission queue in bytes 
 
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO. 
 
bool IsRunning(void) const 
This method is syntactic sugar for !IsExpired(). 
 
bool IsInsideReceivingWindow(SequenceNumber10 seqNumber)
 
std::vector< RetxPdu > m_txedBuffer
Buffer for transmitted and retransmitted PDUs that have not been acked but are not considered for ret...
 
uint8_t lcid
the logical channel id corresponding to the sending RLC instance 
 
uint16_t rnti
the C-RNTI identifying the UE 
 
EventId m_pollRetransmitTimer
Timers. 
 
void SetModulusBase(SequenceNumber10 modulusBase)
 
void ExpireRbsTimer(void)
 
Parameters for LteMacSapProvider::ReportBufferStatus. 
 
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range. 
 
uint32_t m_txonBufferSize
 
uint16_t txQueueHolDelay
the Head Of Line delay of the transmission queue 
 
Ptr< Packet > CreateFragment(uint32_t start, uint32_t length) const 
Create a new packet which contains a fragment of the original packet. 
 
void AddAtEnd(Ptr< const Packet > packet)
Concatenate the input packet at the end of the current packet. 
 
SequenceNumber10 m_expectedSeqNumber
Expected Sequence Number. 
 
LteRlcSapUser * m_rlcSapUser
 
void RemoveAtStart(uint32_t size)
Remove size bytes from the start of the current packet. 
 
static EventId Schedule(Time const &delay, MEM mem_ptr, OBJ obj)
Schedule an event to expire after delay. 
 
std::map< uint16_t, PduBuffer > m_rxonBuffer
 
AttributeValue implementation for Time. 
 
uint16_t rnti
the C-RNTI identifying the UE 
 
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...
 
uint8_t GetStatus(void) const 
 
virtual void DoDispose()
Destructor implementation. 
 
SequenceNumber10 m_pollSn
 
LteMacSapProvider * m_macSapProvider
 
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC. 
 
Ptr< Packet > Copy(void) const 
performs a COW copy of the packet. 
 
uint32_t PeekHeader(Header &header) const 
Deserialize but does not remove the header from the internal buffer. 
 
uint8_t layer
the layer value that was passed by the MAC in the call to NotifyTxOpportunity that generated this PDU...
 
Every class exported by the ns3 library is enclosed in the ns3 namespace. 
 
std::list< Ptr< Packet > > m_sdusBuffer
 
Ptr< const AttributeChecker > MakeBooleanChecker(void)
 
bool m_pollRetransmitTimerJustExpired
 
Time GetSenderTimestamp(void) const 
Get the instant when the RLC delivers the PDU to the MAC SAP provider. 
 
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
 
uint8_t lcid
the logical channel id corresponding to the sending RLC instance 
 
uint32_t m_pduWithoutPoll
Counters. 
 
uint32_t txQueueSize
the current size of the RLC transmission queue 
 
static Time Now(void)
Return the current simulation virtual time. 
 
uint32_t m_txedBufferSize
 
Time m_statusProhibitTimerValue
 
virtual void DoNotifyHarqDeliveryFailure()
 
uint16_t m_maxRetxThreshold
Configurable parameters. 
 
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
 
int64_t GetNanoSeconds(void) const 
Get an approximation of the time stored in this instance in the indicated unit. 
 
uint16_t statusPduSize
the current size of the pending STATUS RLC PDU message in bytes 
 
This class implements a tag that carries the status of a RLC SDU for the fragmentation process Status...
 
virtual void DoDispose()
Destructor implementation. 
 
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN. 
 
void ExpireStatusProhibitTimer(void)
method called when the T_status_prohibit timer expires 
 
void ExpirePollRetransmitTimer(void)
 
SequenceNumber10 m_vtA
State variables. 
 
bool RemovePacketTag(Tag &tag)
Remove a packet tag. 
 
Time Seconds(double value)
Construct a Time in the indicated unit. 
 
std::vector< RetxPdu > m_retxBuffer
Buffer for PDUs considered for retransmission. 
 
void SetStatus(uint8_t status)
 
uint16_t retxQueueHolDelay
the Head Of Line delay of the retransmission queue 
 
Ptr< Packet > pdu
the RLC PDU 
 
void Cancel(void)
This method is syntactic sugar for the ns3::Simulator::Cancel method. 
 
virtual void ReportBufferStatus(ReportBufferStatusParameters params)=0
Report the RLC buffer status to the MAC. 
 
std::vector< Ptr< Packet > > m_txonBuffer
 
TracedCallback< uint16_t, uint8_t, uint32_t, uint64_t > m_rxPdu
Used to inform of a PDU reception from the MAC SAP user. 
 
LTE RLC Acknowledged Mode (AM), see 3GPP TS 36.322. 
 
Ptr< Packet > m_controlPduBuffer
 
void ReassembleAndDeliver(Ptr< Packet > packet)
 
uint16_t m_windowSize
Constants. 
 
uint8_t harqProcessId
the HARQ process id that was passed by the MAC in the call to NotifyTxOpportunity that generated this...
 
bool m_txOpportunityForRetxAlwaysBigEnough
 
virtual void TransmitPdu(TransmitPduParameters params)=0
send an RLC PDU to the MAC for transmission. 
 
ReassemblingState_t m_reassemblingState
 
This abstract base class defines the API to interact with the Radio Link Control (LTE_RLC) in LTE...
 
a unique identifier for an interface. 
 
uint32_t m_retxBufferSize
 
int64_t GetMilliSeconds(void) const 
Get an approximation of the time stored in this instance in the indicated unit. 
 
TypeId SetParent(TypeId tid)
Set the parent TypeId. 
 
static TypeId GetTypeId(void)
 
bool m_statusPduRequested
 
void ExpireReorderingTimer(void)
This method will schedule a timeout at WaitReplyTimeout interval in the future, unless a timer is alr...
 
virtual void DoTransmitPdcpPdu(Ptr< Packet > p)
RLC SAP. 
 
void AddHeader(const Header &header)
Add header to this packet. 
 
void AddByteTag(const Tag &tag) const 
Tag each byte included in this packet with a new byte tag. 
 
Parameters for LteMacSapProvider::TransmitPdu.