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");
443 uint32_t nextSegmentSize = txOpParams.
bytes - 4;
444 uint32_t nextSegmentId = 1;
445 uint32_t dataFieldAddedSize = 0;
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)
479 uint32_t currSegmentSize =
std::min (firstSegment->
GetSize (), nextSegmentSize);
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)
1279 NS_LOG_LOGIC (
"INTERNAL ERROR: Transition not possible. FI = " << (uint32_t) framingInfo);
1285 switch (framingInfo)
1350 NS_LOG_LOGIC (
"INTERNAL ERROR: Transition not possible. FI = " << (uint32_t) framingInfo);
1365 switch (framingInfo)
1455 NS_LOG_LOGIC (
"INTERNAL ERROR: Transition not possible. FI = " << (uint32_t) framingInfo);
1461 switch (framingInfo)
1572 NS_LOG_LOGIC (
"INTERNAL ERROR: Transition not possible. FI = " << (uint32_t) 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)
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 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.
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.