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)",
167 NS_LOG_LOGIC (
"TxOpportunity (size = " << bytes <<
") too small");
168 NS_ASSERT_MSG (
false,
"TxOpportunity (size = " << bytes <<
") too small.\n"
169 <<
"Your MAC scheduler is assigned too few resource blocks.");
180 <<
"Your MAC scheduler is assigned too few resource blocks.");
189 rlcAmHeader.SetAckSn (
m_vrR);
199 params.
layer = layer;
210 NS_LOG_LOGIC (
"Sending data from Retransmission Buffer");
214 if ( packet->
GetSize () <= bytes )
225 params.
layer = layer;
233 NS_LOG_LOGIC (
"TxOpportunity (size = " << bytes <<
") too small for retransmission of the packet (size = " << packet->
GetSize () <<
")");
243 NS_LOG_LOGIC (
"TxOpportunity (size = " << bytes <<
") too small for DATA PDU");
244 NS_ASSERT_MSG (
false,
"TxOpportunity (size = " << bytes <<
") too small for DATA PDU\n"
245 <<
"Your MAC scheduler is assigned too few resource blocks.");
261 if ( packet->
GetSize () <= bytes )
263 NS_LOG_INFO (
"Move SN = " << vta <<
" to retxBuffer");
280 params.
layer = layer;
288 NS_LOG_LOGIC (
"TxOpportunity (size = " << bytes <<
") too small for retransmission of the packet (size = " << packet->
GetSize () <<
")");
310 uint32_t nextSegmentSize = bytes - 4;
311 uint32_t nextSegmentId = 1;
312 uint32_t dataFieldTotalSize = 0;
313 uint32_t dataFieldAddedSize = 0;
314 std::vector < Ptr<Packet> > dataField;
327 NS_LOG_LOGIC (
"Next segment size = " << nextSegmentSize);
334 while ( firstSegment && (firstSegment->
GetSize () > 0) && (nextSegmentSize > 0) )
336 NS_LOG_LOGIC (
"WHILE ( firstSegment && firstSegment->GetSize > 0 && nextSegmentSize > 0 )");
338 NS_LOG_LOGIC (
" nextSegmentSize = " << nextSegmentSize);
339 if ( (firstSegment->
GetSize () > nextSegmentSize) ||
341 (firstSegment->
GetSize () > 2047)
346 uint32_t currSegmentSize = std::min (firstSegment->
GetSize (), nextSegmentSize);
348 NS_LOG_LOGIC (
" IF ( firstSegment > nextSegmentSize ||");
376 if (firstSegment->
GetSize () > 0)
383 NS_LOG_LOGIC (
" Txon buffer: Give back the remaining segment");
408 dataFieldAddedSize = newSegment->
GetSize ();
409 dataFieldTotalSize += dataFieldAddedSize;
410 dataField.push_back (newSegment);
418 nextSegmentSize -= dataFieldAddedSize;
426 else if ( (nextSegmentSize - firstSegment->
GetSize () <= 2) || (
m_txonBuffer.size () == 0) )
428 NS_LOG_LOGIC (
" IF nextSegmentSize - firstSegment->GetSize () <= 2 || txonBuffer.size == 0");
431 dataFieldAddedSize = firstSegment->
GetSize ();
432 dataFieldTotalSize += dataFieldAddedSize;
433 dataField.push_back (firstSegment);
441 nextSegmentSize -= dataFieldAddedSize;
450 NS_LOG_LOGIC (
" Next segment size = " << nextSegmentSize);
459 NS_LOG_LOGIC (
" IF firstSegment < NextSegmentSize && txonBuffer.size > 0");
461 dataFieldAddedSize = firstSegment->
GetSize ();
462 dataFieldTotalSize += dataFieldAddedSize;
463 dataField.push_back (firstSegment);
469 rlcAmHeader.PushLengthIndicator (firstSegment->
GetSize ());
471 nextSegmentSize -= ((nextSegmentId % 2) ? (2) : (1)) + dataFieldAddedSize;
480 NS_LOG_LOGIC (
" Next segment size = " << nextSegmentSize);
496 rlcAmHeader.SetSequenceNumber (
m_vtS++ );
499 rlcAmHeader.SetSegmentOffset (0);
502 uint8_t framingInfo = 0;
503 std::vector< Ptr<Packet> >::iterator it;
504 it = dataField.begin ();
508 (*it)->RemovePacketTag (tag);
519 (*it)->AddPacketTag (tag);
522 while (it < dataField.end ())
524 NS_LOG_LOGIC (
"Adding SDU/segment to packet, length = " << (*it)->GetSize ());
532 (*it)->RemovePacketTag (tag);
542 (*it)->AddPacketTag (tag);
545 rlcAmHeader.SetFramingInfo (framingInfo);
593 m_txedBuffer.at ( rlcAmHeader.GetSequenceNumber ().GetValue () ) = packet->
Copy ();
605 params.layer = layer;
606 params.harqProcessId = harqId;
636 if ( rlcAmHeader.IsDataPdu () )
693 NS_LOG_LOGIC (
"PDU segment received ( SN = " << seqNumber <<
" )");
697 NS_LOG_LOGIC (
"PDU received ( SN = " << seqNumber <<
" )");
701 NS_ASSERT_MSG (
false,
"Neither a PDU segment nor a PDU received");
744 NS_LOG_LOGIC (
"Place PDU in the reception buffer ( SN = " << seqNumber <<
" )");
759 if ( seqNumber >=
m_vrH )
761 m_vrH = seqNumber + 1;
792 if ( seqNumber ==
m_vrR )
805 "Too many segments. PDU Reassembly process didn't work");
955 else if ( rlcAmHeader.IsControlPdu () )
973 NS_LOG_INFO (
"ACKed SN = " << seqNumberValue <<
" from txedBuffer");
981 NS_LOG_INFO (
"ACKed SN = " << seqNumberValue <<
" from retxBuffer");
993 uint16_t seqNumberValue;
994 while (seqNumber <
m_vtS)
996 seqNumberValue = seqNumber.
GetValue ();
999 NS_LOG_INFO (
"Move SN = " << seqNumberValue <<
" to retxBuffer");
1010 NS_LOG_INFO (
"Incr RETX_COUNT for SN = " << seqNumberValue);
1013 NS_LOG_INFO (
"Max RETX_COUNT for SN = " << seqNumberValue);
1036 m_vrR <<
" <= " << seqNumber <<
" <= " <<
m_vrMr);
1042 if ( (
m_vrR <= seqNumber) && (seqNumber <
m_vrMr ) )
1044 NS_LOG_LOGIC (seqNumber <<
" is INSIDE the receiving window");
1049 NS_LOG_LOGIC (seqNumber <<
" is OUTSIDE the receiving window");
1062 bool expectedSnLost;
1066 expectedSnLost =
true;
1072 expectedSnLost =
false;
1078 uint8_t extensionBit;
1079 uint16_t lengthIndicator;
1085 if ( extensionBit == 0 )
1095 if ( lengthIndicator >= packet->
GetSize () )
1097 NS_LOG_LOGIC (
"INTERNAL ERROR: Not enough data in the packet (" << packet->
GetSize () <<
"). Needed LI=" << lengthIndicator);
1108 while ( extensionBit == 1 );
1110 std::list < Ptr<Packet> >::iterator it;
1115 else NS_LOG_LOGIC (
"Reassembling State = Unknown state");
1118 NS_LOG_LOGIC (
"Framing Info = " << (uint16_t)framingInfo);
1122 if (!expectedSnLost)
1127 switch (framingInfo)
1167 NS_LOG_LOGIC (
"INTERNAL ERROR: Transition not possible. FI = " << (uint32_t) framingInfo);
1173 switch (framingInfo)
1238 NS_LOG_LOGIC (
"INTERNAL ERROR: Transition not possible. FI = " << (uint32_t) framingInfo);
1253 switch (framingInfo)
1343 NS_LOG_LOGIC (
"INTERNAL ERROR: Transition not possible. FI = " << (uint32_t) framingInfo);
1349 switch (framingInfo)
1460 NS_LOG_LOGIC (
"INTERNAL ERROR: Transition not possible. FI = " << (uint32_t) framingInfo);
1540 Time txonQueueHolDelay (0);
1543 RlcTag txonQueueHolTimeTag;
1544 m_txonBuffer.front ()->PeekPacketTag (txonQueueHolTimeTag);
1549 Time retxQueueHolDelay (0);
1550 RlcTag retxQueueHolTimeTag;
uint32_t RemoveHeader(Header &header)
TracedCallback< uint16_t, uint8_t, uint32_t > m_txPdu
bool FindFirstMatchingByteTag(Tag &tag) const
keep track of time values and allow control of global simulation resolution
EventId m_statusProhibitTimer
#define NS_LOG_FUNCTION(parameters)
uint32_t m_byteWithoutPoll
uint16_t GetValue() const
Extracts the numeric value of the sequence number.
virtual void DoReceivePdu(Ptr< Packet > p)
std::vector< RetxBuffer > m_retxBuffer
virtual void DoNotifyTxOpportunity(uint32_t bytes, uint8_t layer, uint8_t harqId)
uint32_t m_statusPduBufferSize
void DoReportBufferStatus()
void AddPacketTag(const Tag &tag) const
#define NS_LOG_COMPONENT_DEFINE(name)
Time m_pollRetransmitTimerValue
uint32_t GetSize(void) const
EventId m_reorderingTimer
bool IsRunning(void) const
bool IsInsideReceivingWindow(SequenceNumber10 seqNumber)
static EventId Schedule(Time const &time, MEM mem_ptr, OBJ obj)
EventId m_pollRetransmitTimer
void SetModulusBase(SequenceNumber10 modulusBase)
uint32_t m_txonBufferSize
Ptr< Packet > CreateFragment(uint32_t start, uint32_t length) const
void AddAtEnd(Ptr< const Packet > packet)
SequenceNumber10 m_expectedSeqNumber
LteRlcSapUser * m_rlcSapUser
void RemoveAtStart(uint32_t size)
std::map< uint16_t, PduBuffer > m_rxonBuffer
hold objects of type ns3::Time
NS_OBJECT_ENSURE_REGISTERED(AntennaModel)
virtual void ReceivePdcpPdu(Ptr< Packet > p)=0
uint8_t GetStatus(void) const
SequenceNumber10 m_pollSn
LteMacSapProvider * m_macSapProvider
#define NS_LOG_LOGIC(msg)
Ptr< Packet > Copy(void) const
uint32_t PeekHeader(Header &header) const
std::list< Ptr< Packet > > m_sdusBuffer
Time GetSenderTimestamp(void) const
uint32_t m_pduWithoutPoll
uint32_t m_txedBufferSize
virtual void DoNotifyHarqDeliveryFailure()
uint16_t m_maxRetxThreshold
#define NS_ASSERT_MSG(condition, message)
int64_t GetNanoSeconds(void) const
This class implements a tag that carries the status of a RLC SDU for the fragmentation process Status...
void ExpirePollRetransmitTimer(void)
bool RemovePacketTag(Tag &tag)
void SetStatus(uint8_t status)
uint16_t retxQueueHolDelay
virtual void ReportBufferStatus(ReportBufferStatusParameters params)=0
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range. Both limits are inclusive.
std::vector< Ptr< Packet > > m_txonBuffer
TracedCallback< uint16_t, uint8_t, uint32_t, uint64_t > m_rxPdu
Ptr< Packet > m_controlPduBuffer
void ReassembleAndDeliver(Ptr< Packet > packet)
virtual void TransmitPdu(TransmitPduParameters params)=0
ReassemblingState_t m_reassemblingState
a unique identifier for an interface.
uint32_t m_retxBufferSize
int64_t GetMilliSeconds(void) const
TypeId SetParent(TypeId tid)
static TypeId GetTypeId(void)
bool m_statusPduRequested
void ExpireReorderingTimer(void)
std::vector< Ptr< Packet > > m_txedBuffer
virtual void DoTransmitPdcpPdu(Ptr< Packet > p)
void AddHeader(const Header &header)
void AddByteTag(const Tag &tag) const