21 #include "ns3/simulator.h"
24 #include "ns3/lte-rlc-am-header.h"
25 #include "ns3/lte-rlc-am.h"
26 #include "ns3/lte-rlc-sdu-status-tag.h"
27 #include "ns3/lte-rlc-tag.h"
90 .AddConstructor<LteRlcAm> ()
91 .AddAttribute (
"PollRetransmitTimer",
92 "Value of the t-PollRetransmit (See section 7.3 of 3GPP TS 36.322)",
96 .AddAttribute (
"TxOpportunityForRetxAlwaysBigEnough",
97 "If true, always pretend that the size of a TxOpportunity is big enough "
98 "for retransmission. If false (default and realistic behavior), no retx "
99 "is performed unless the corresponding TxOpportunity is big enough.",
175 NS_LOG_LOGIC (
"TxOpportunity (size = " << bytes <<
") too small");
176 NS_ASSERT_MSG (
false,
"TxOpportunity (size = " << bytes <<
") too small.\n"
177 <<
"Your MAC scheduler is assigned too few resource blocks.");
188 <<
"Your MAC scheduler is assigned too few resource blocks.");
197 rlcAmHeader.SetAckSn (
m_vrR);
207 params.
layer = layer;
218 NS_LOG_LOGIC (
"Sending data from Retransmission Buffer");
222 if (( packet->
GetSize () <= bytes )
234 params.
layer = layer;
242 NS_LOG_LOGIC (
"TxOpportunity (size = " << bytes <<
") too small for retransmission of the packet (size = " << packet->
GetSize () <<
")");
252 NS_LOG_LOGIC (
"TxOpportunity (size = " << bytes <<
") too small for DATA PDU");
253 NS_ASSERT_MSG (
false,
"TxOpportunity (size = " << bytes <<
") too small for DATA PDU\n"
254 <<
"Your MAC scheduler is assigned too few resource blocks.");
270 if (( packet->
GetSize () <= bytes )
273 NS_LOG_INFO (
"Move SN = " << vta <<
" to retxBuffer");
290 params.
layer = layer;
298 NS_LOG_LOGIC (
"TxOpportunity (size = " << bytes <<
") too small for retransmission of the packet (size = " << packet->
GetSize () <<
")");
320 uint32_t nextSegmentSize = bytes - 4;
321 uint32_t nextSegmentId = 1;
322 uint32_t dataFieldTotalSize = 0;
323 uint32_t dataFieldAddedSize = 0;
324 std::vector < Ptr<Packet> > dataField;
337 NS_LOG_LOGIC (
"Next segment size = " << nextSegmentSize);
344 while ( firstSegment && (firstSegment->
GetSize () > 0) && (nextSegmentSize > 0) )
346 NS_LOG_LOGIC (
"WHILE ( firstSegment && firstSegment->GetSize > 0 && nextSegmentSize > 0 )");
348 NS_LOG_LOGIC (
" nextSegmentSize = " << nextSegmentSize);
349 if ( (firstSegment->
GetSize () > nextSegmentSize) ||
351 (firstSegment->
GetSize () > 2047)
356 uint32_t currSegmentSize = std::min (firstSegment->
GetSize (), nextSegmentSize);
358 NS_LOG_LOGIC (
" IF ( firstSegment > nextSegmentSize ||");
386 if (firstSegment->
GetSize () > 0)
393 NS_LOG_LOGIC (
" Txon buffer: Give back the remaining segment");
418 dataFieldAddedSize = newSegment->
GetSize ();
419 dataFieldTotalSize += dataFieldAddedSize;
420 dataField.push_back (newSegment);
428 nextSegmentSize -= dataFieldAddedSize;
436 else if ( (nextSegmentSize - firstSegment->
GetSize () <= 2) || (
m_txonBuffer.size () == 0) )
438 NS_LOG_LOGIC (
" IF nextSegmentSize - firstSegment->GetSize () <= 2 || txonBuffer.size == 0");
441 dataFieldAddedSize = firstSegment->
GetSize ();
442 dataFieldTotalSize += dataFieldAddedSize;
443 dataField.push_back (firstSegment);
451 nextSegmentSize -= dataFieldAddedSize;
460 NS_LOG_LOGIC (
" Next segment size = " << nextSegmentSize);
469 NS_LOG_LOGIC (
" IF firstSegment < NextSegmentSize && txonBuffer.size > 0");
471 dataFieldAddedSize = firstSegment->
GetSize ();
472 dataFieldTotalSize += dataFieldAddedSize;
473 dataField.push_back (firstSegment);
479 rlcAmHeader.PushLengthIndicator (firstSegment->
GetSize ());
481 nextSegmentSize -= ((nextSegmentId % 2) ? (2) : (1)) + dataFieldAddedSize;
490 NS_LOG_LOGIC (
" Next segment size = " << nextSegmentSize);
506 rlcAmHeader.SetSequenceNumber (
m_vtS++ );
509 rlcAmHeader.SetSegmentOffset (0);
512 uint8_t framingInfo = 0;
513 std::vector< Ptr<Packet> >::iterator it;
514 it = dataField.begin ();
518 (*it)->RemovePacketTag (tag);
529 (*it)->AddPacketTag (tag);
532 while (it < dataField.end ())
534 NS_LOG_LOGIC (
"Adding SDU/segment to packet, length = " << (*it)->GetSize ());
542 (*it)->RemovePacketTag (tag);
552 (*it)->AddPacketTag (tag);
555 rlcAmHeader.SetFramingInfo (framingInfo);
603 m_txedBuffer.at ( rlcAmHeader.GetSequenceNumber ().GetValue () ) = packet->
Copy ();
615 params.layer = layer;
616 params.harqProcessId = harqId;
646 if ( rlcAmHeader.IsDataPdu () )
703 NS_LOG_LOGIC (
"PDU segment received ( SN = " << seqNumber <<
" )");
707 NS_LOG_LOGIC (
"PDU received ( SN = " << seqNumber <<
" )");
711 NS_ASSERT_MSG (
false,
"Neither a PDU segment nor a PDU received");
754 NS_LOG_LOGIC (
"Place PDU in the reception buffer ( SN = " << seqNumber <<
" )");
769 if ( seqNumber >=
m_vrH )
771 m_vrH = seqNumber + 1;
802 if ( seqNumber ==
m_vrR )
815 "Too many segments. PDU Reassembly process didn't work");
965 else if ( rlcAmHeader.IsControlPdu () )
993 NS_LOG_INFO (
"ACKed SN = " << seqNumberValue <<
" from txedBuffer");
1001 NS_LOG_INFO (
"ACKed SN = " << seqNumberValue <<
" from retxBuffer");
1016 uint16_t seqNumberValue;
1017 while (seqNumber <
m_vtS)
1019 seqNumberValue = seqNumber.
GetValue ();
1022 NS_LOG_INFO (
"Move SN = " << seqNumberValue <<
" to retxBuffer");
1033 NS_LOG_INFO (
"Incr RETX_COUNT for SN = " << seqNumberValue);
1036 NS_LOG_INFO (
"Max RETX_COUNT for SN = " << seqNumberValue);
1059 m_vrR <<
" <= " << seqNumber <<
" <= " <<
m_vrMr);
1065 if ( (
m_vrR <= seqNumber) && (seqNumber <
m_vrMr ) )
1067 NS_LOG_LOGIC (seqNumber <<
" is INSIDE the receiving window");
1072 NS_LOG_LOGIC (seqNumber <<
" is OUTSIDE the receiving window");
1085 bool expectedSnLost;
1089 expectedSnLost =
true;
1095 expectedSnLost =
false;
1101 uint8_t extensionBit;
1102 uint16_t lengthIndicator;
1108 if ( extensionBit == 0 )
1118 if ( lengthIndicator >= packet->
GetSize () )
1120 NS_LOG_LOGIC (
"INTERNAL ERROR: Not enough data in the packet (" << packet->
GetSize () <<
"). Needed LI=" << lengthIndicator);
1131 while ( extensionBit == 1 );
1133 std::list < Ptr<Packet> >::iterator it;
1138 else NS_LOG_LOGIC (
"Reassembling State = Unknown state");
1141 NS_LOG_LOGIC (
"Framing Info = " << (uint16_t)framingInfo);
1145 if (!expectedSnLost)
1150 switch (framingInfo)
1190 NS_LOG_LOGIC (
"INTERNAL ERROR: Transition not possible. FI = " << (uint32_t) framingInfo);
1196 switch (framingInfo)
1261 NS_LOG_LOGIC (
"INTERNAL ERROR: Transition not possible. FI = " << (uint32_t) framingInfo);
1276 switch (framingInfo)
1366 NS_LOG_LOGIC (
"INTERNAL ERROR: Transition not possible. FI = " << (uint32_t) framingInfo);
1372 switch (framingInfo)
1483 NS_LOG_LOGIC (
"INTERNAL ERROR: Transition not possible. FI = " << (uint32_t) framingInfo);
1563 Time txonQueueHolDelay (0);
1566 RlcTag txonQueueHolTimeTag;
1567 m_txonBuffer.front ()->PeekPacketTag (txonQueueHolTimeTag);
1572 Time retxQueueHolDelay (0);
1573 RlcTag retxQueueHolTimeTag;
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)
std::vector< RetxBuffer > m_retxBuffer
#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_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)
static EventId Schedule(Time const &time, MEM mem_ptr, OBJ obj)
Schedule an event to expire at the relative time "time" is reached.
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)
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.
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)
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
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 ExpirePollRetransmitTimer(void)
SequenceNumber10 m_vtA
State variables.
bool RemovePacketTag(Tag &tag)
Remove a packet tag.
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.
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)
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...
std::vector< Ptr< Packet > > m_txedBuffer
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.