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"
33 NS_OBJECT_ENSURE_REGISTERED (LteRlcAm);
41 m_retxBuffer.resize (1024);
43 m_txedBuffer.resize (1024);
46 m_statusPduRequested =
false;
47 m_statusPduBufferSize = 0;
65 m_byteWithoutPoll = 0;
73 m_reassemblingState = WAITING_S0_FULL;
80 LteRlcAm::~LteRlcAm ()
86 LteRlcAm::GetTypeId (
void)
88 static TypeId tid = TypeId (
"ns3::LteRlcAm")
90 .AddConstructor<LteRlcAm> ()
91 .AddAttribute (
"PollRetransmitTimer",
92 "Value of the t-PollRetransmit (See section 7.3 of 3GPP TS 36.322)",
94 MakeTimeAccessor (&LteRlcAm::m_pollRetransmitTimerValue),
105 m_reorderingTimer.
Cancel ();
106 m_statusProhibitTimer.
Cancel ();
108 m_txonBuffer.clear ();
109 m_txonBufferSize = 0;
110 m_txedBuffer.clear ();
111 m_txedBufferSize = 0;
112 m_retxBuffer.clear ();
113 m_retxBufferSize = 0;
114 m_rxonBuffer.clear ();
115 m_sdusBuffer.clear ();
117 m_controlPduBuffer = 0;
140 tag.SetStatus (LteRlcSduStatusTag::FULL_SDU);
144 m_txonBuffer.push_back (p);
145 m_txonBufferSize += p->
GetSize ();
146 NS_LOG_LOGIC (
"NumOfBuffers = " << m_txonBuffer.size() );
150 DoReportBufferStatus ();
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.");
173 if ( m_statusPduRequested && ! m_statusProhibitTimer.
IsRunning () )
175 if (bytes < m_statusPduBufferSize)
178 NS_LOG_LOGIC (
"TxOpportunity (size = " << bytes <<
") too small for the STATUS PDU (size = " << m_statusPduBufferSize <<
")");
179 NS_ASSERT_MSG (
false,
"TxOpportunity (size = " << bytes <<
") too small for the STATUS PDU (size = " << m_statusPduBufferSize <<
")\n"
180 <<
"Your MAC scheduler is assigned too few resource blocks.");
188 rlcAmHeader.SetControlPdu (LteRlcAmHeader::STATUS_PDU);
189 rlcAmHeader.SetAckSn (m_vrR);
197 params.
rnti = m_rnti;
198 params.
lcid = m_lcid;
199 params.
layer = layer;
204 m_statusPduRequested =
false;
205 m_statusPduBufferSize = 0;
208 else if ( m_retxBufferSize > 0 )
210 NS_LOG_LOGIC (
"Sending data from Retransmission Buffer");
214 if ( packet->
GetSize () <= bytes )
223 params.
rnti = m_rnti;
224 params.
lcid = m_lcid;
225 params.
layer = layer;
233 NS_LOG_LOGIC (
"TxOpportunity (size = " << bytes <<
") too small for retransmission of the packet (size = " << packet->
GetSize () <<
")");
238 else if ( m_txonBufferSize > 0 )
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.");
251 else if ( m_txedBufferSize > 0 )
259 Ptr<Packet> packet = m_txedBuffer.at (vta)->Copy ();
261 if ( packet->
GetSize () <= bytes )
263 NS_LOG_INFO (
"Move SN = " << vta <<
" to retxBuffer");
264 m_retxBuffer.at (vta).m_pdu = m_txedBuffer.at (vta)->Copy ();
265 m_retxBuffer.at (vta).m_retxCount = 1;
266 m_retxBufferSize += m_retxBuffer.at (vta).m_pdu->GetSize ();
268 m_txedBufferSize -= m_txedBuffer.at (vta)->GetSize ();
269 m_txedBuffer.at (vta) = 0;
278 params.
rnti = m_rnti;
279 params.
lcid = m_lcid;
280 params.
layer = layer;
288 NS_LOG_LOGIC (
"TxOpportunity (size = " << bytes <<
") too small for retransmission of the packet (size = " << packet->
GetSize () <<
")");
307 rlcAmHeader.SetDataPdu ();
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;
318 if ( m_txonBuffer.size () == 0 )
324 NS_LOG_LOGIC (
"SDUs in TxonBuffer = " << m_txonBuffer.size ());
325 NS_LOG_LOGIC (
"First SDU buffer = " << *(m_txonBuffer.begin()));
326 NS_LOG_LOGIC (
"First SDU size = " << (*(m_txonBuffer.begin()))->GetSize ());
327 NS_LOG_LOGIC (
"Next segment size = " << nextSegmentSize);
330 m_txonBufferSize -= (*(m_txonBuffer.begin()))->GetSize ();
332 m_txonBuffer.erase (m_txonBuffer.begin ());
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 ||");
362 if (oldTag.GetStatus () == LteRlcSduStatusTag::FULL_SDU)
364 newTag.SetStatus (LteRlcSduStatusTag::FIRST_SEGMENT);
365 oldTag.SetStatus (LteRlcSduStatusTag::LAST_SEGMENT);
367 else if (oldTag.GetStatus () == LteRlcSduStatusTag::LAST_SEGMENT)
369 newTag.SetStatus (LteRlcSduStatusTag::MIDDLE_SEGMENT);
376 if (firstSegment->
GetSize () > 0)
380 m_txonBuffer.insert (m_txonBuffer.begin (), firstSegment);
381 m_txonBufferSize += (*(m_txonBuffer.begin()))->GetSize ();
383 NS_LOG_LOGIC (
" Txon buffer: Give back the remaining segment");
384 NS_LOG_LOGIC (
" Txon buffers = " << m_txonBuffer.size ());
385 NS_LOG_LOGIC (
" Front buffer size = " << (*(m_txonBuffer.begin()))->GetSize ());
386 NS_LOG_LOGIC (
" txonBufferSize = " << m_txonBufferSize );
391 if (newTag.GetStatus () == LteRlcSduStatusTag::FIRST_SEGMENT)
393 newTag.SetStatus (LteRlcSduStatusTag::FULL_SDU);
395 else if (newTag.GetStatus () == LteRlcSduStatusTag::MIDDLE_SEGMENT)
397 newTag.SetStatus (LteRlcSduStatusTag::LAST_SEGMENT);
408 dataFieldAddedSize = newSegment->
GetSize ();
409 dataFieldTotalSize += dataFieldAddedSize;
410 dataField.push_back (newSegment);
414 rlcAmHeader.PushExtensionBit (LteRlcAmHeader::DATA_FIELD_FOLLOWS);
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);
437 rlcAmHeader.PushExtensionBit (LteRlcAmHeader::DATA_FIELD_FOLLOWS);
441 nextSegmentSize -= dataFieldAddedSize;
444 NS_LOG_LOGIC (
" SDUs in TxBuffer = " << m_txonBuffer.size ());
445 if (m_txonBuffer.size () > 0)
447 NS_LOG_LOGIC (
" First SDU buffer = " << *(m_txonBuffer.begin()));
448 NS_LOG_LOGIC (
" First SDU size = " << (*(m_txonBuffer.begin()))->GetSize ());
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);
466 rlcAmHeader.PushExtensionBit (LteRlcAmHeader::E_LI_FIELDS_FOLLOWS);
469 rlcAmHeader.PushLengthIndicator (firstSegment->
GetSize ());
471 nextSegmentSize -= ((nextSegmentId % 2) ? (2) : (1)) + dataFieldAddedSize;
474 NS_LOG_LOGIC (
" SDUs in TxBuffer = " << m_txonBuffer.size ());
475 if (m_txonBuffer.size () > 0)
477 NS_LOG_LOGIC (
" First SDU buffer = " << *(m_txonBuffer.begin()));
478 NS_LOG_LOGIC (
" First SDU size = " << (*(m_txonBuffer.begin()))->GetSize ());
480 NS_LOG_LOGIC (
" Next segment size = " << nextSegmentSize);
484 firstSegment = (*(m_txonBuffer.begin ()))->
Copy ();
485 m_txonBufferSize -= (*(m_txonBuffer.begin()))->GetSize ();
486 m_txonBuffer.erase (m_txonBuffer.begin ());
496 rlcAmHeader.SetSequenceNumber ( m_vtS++ );
497 rlcAmHeader.SetResegmentationFlag (LteRlcAmHeader::PDU);
498 rlcAmHeader.SetLastSegmentFlag (LteRlcAmHeader::LAST_PDU_SEGMENT);
499 rlcAmHeader.SetSegmentOffset (0);
502 uint8_t framingInfo = 0;
503 std::vector< Ptr<Packet> >::iterator it;
504 it = dataField.begin ();
508 (*it)->RemovePacketTag (tag);
509 if ( (tag.GetStatus () == LteRlcSduStatusTag::FULL_SDU) ||
510 (tag.GetStatus () == LteRlcSduStatusTag::FIRST_SEGMENT)
513 framingInfo |= LteRlcAmHeader::FIRST_BYTE;
517 framingInfo |= LteRlcAmHeader::NO_FIRST_BYTE;
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);
533 if ( (tag.GetStatus () == LteRlcSduStatusTag::FULL_SDU) ||
534 (tag.GetStatus () == LteRlcSduStatusTag::LAST_SEGMENT) )
536 framingInfo |= LteRlcAmHeader::LAST_BYTE;
540 framingInfo |= LteRlcAmHeader::NO_LAST_BYTE;
542 (*it)->AddPacketTag (tag);
545 rlcAmHeader.SetFramingInfo (framingInfo);
549 rlcAmHeader.SetPollingBit (LteRlcAmHeader::STATUS_REPORT_NOT_REQUESTED);
553 m_byteWithoutPoll += packet->
GetSize ();
554 NS_LOG_LOGIC (
"BYTE_WITHOUT_POLL = " << m_byteWithoutPoll);
556 if ( (
m_pduWithoutPoll >= m_pollPdu) || (m_byteWithoutPoll >= m_pollByte) ||
557 ( (m_txonBuffer.empty ()) && (m_retxBuffer.empty ()) ) ||
561 rlcAmHeader.SetPollingBit (LteRlcAmHeader::STATUS_REPORT_IS_REQUESTED);
563 m_byteWithoutPoll = 0;
565 m_pollSn = m_vtS - 1;
573 &LteRlcAm::ExpirePollRetransmitTimer,
this);
581 &LteRlcAm::ExpirePollRetransmitTimer,
this);
592 m_txedBufferSize += packet->
GetSize ();
593 m_txedBuffer.at ( rlcAmHeader.GetSequenceNumber ().GetValue () ) = packet->
Copy ();
603 params.rnti = m_rnti;
604 params.lcid = m_lcid;
605 params.layer = layer;
606 params.harqProcessId = harqId;
612 LteRlcAm::DoNotifyHarqDeliveryFailure ()
618 LteRlcAm::DoReceivePdu (Ptr<Packet> p)
620 NS_LOG_FUNCTION (
this << m_rnti << (uint32_t) m_lcid << p->GetSize ());
625 if (p->FindFirstMatchingByteTag (rlcTag))
629 m_rxPdu (m_rnti, m_lcid, p->GetSize (), delay.GetNanoSeconds ());
632 LteRlcAmHeader rlcAmHeader;
633 p->PeekHeader (rlcAmHeader);
636 if ( rlcAmHeader.IsDataPdu () )
689 SequenceNumber10 seqNumber = rlcAmHeader.GetSequenceNumber ();
691 if ( rlcAmHeader.GetResegmentationFlag () == LteRlcAmHeader::SEGMENT )
693 NS_LOG_LOGIC (
"PDU segment received ( SN = " << seqNumber <<
" )");
695 else if ( rlcAmHeader.GetResegmentationFlag () == LteRlcAmHeader::PDU )
697 NS_LOG_LOGIC (
"PDU received ( SN = " << seqNumber <<
" )");
701 NS_ASSERT_MSG (
false,
"Neither a PDU segment nor a PDU received");
706 if ( rlcAmHeader.GetPollingBit () == LteRlcAmHeader::STATUS_REPORT_IS_REQUESTED )
708 m_statusPduRequested =
true;
709 m_statusPduBufferSize = 4;
711 if (! m_statusProhibitTimer.
IsRunning ())
713 DoReportBufferStatus ();
737 if ( ! IsInsideReceivingWindow (seqNumber) )
744 NS_LOG_LOGIC (
"Place PDU in the reception buffer ( SN = " << seqNumber <<
" )");
745 m_rxonBuffer[ seqNumber.GetValue () ].m_byteSegments.push_back (p);
746 m_rxonBuffer[ seqNumber.GetValue () ].m_pduComplete =
true;
759 if ( seqNumber >= m_vrH )
761 m_vrH = seqNumber + 1;
769 std::map <uint16_t, PduBuffer>::iterator it = m_rxonBuffer.find (m_vrMs.
GetValue ());
770 if ( it != m_rxonBuffer.end () &&
771 m_rxonBuffer[ m_vrMs.
GetValue () ].m_pduComplete )
774 while ( it != m_rxonBuffer.end () &&
775 m_rxonBuffer[ m_vrMs.
GetValue () ].m_pduComplete )
778 it = m_rxonBuffer.find (m_vrMs.
GetValue ());
792 if ( seqNumber == m_vrR )
794 std::map <uint16_t, PduBuffer>::iterator it = m_rxonBuffer.find (seqNumber.GetValue ());
795 if ( it != m_rxonBuffer.end () &&
796 m_rxonBuffer[ seqNumber.GetValue () ].m_pduComplete )
798 it = m_rxonBuffer.find (m_vrR.
GetValue ());
800 while ( it != m_rxonBuffer.end () &&
801 m_rxonBuffer[ m_vrR.
GetValue () ].m_pduComplete )
803 NS_LOG_LOGIC (
"Reassemble and Deliver ( SN = " << m_vrR <<
" )");
805 "Too many segments. PDU Reassembly process didn't work");
807 m_rxonBuffer.erase (m_vrR.
GetValue ());
810 it = m_rxonBuffer.find (m_vrR.
GetValue ());
834 if ( (m_vrX == m_vrR) ||
835 ( (! IsInsideReceivingWindow (m_vrX)) && (m_vrX != m_vrMr) )
840 m_reorderingTimer.
Cancel ();
955 else if ( rlcAmHeader.IsControlPdu () )
959 SequenceNumber10 ackSn = rlcAmHeader.GetAckSn ();
971 if (m_txedBuffer.at (seqNumberValue))
973 NS_LOG_INFO (
"ACKed SN = " << seqNumberValue <<
" from txedBuffer");
975 m_txedBufferSize -= m_txedBuffer.at (seqNumberValue)->GetSize ();
976 m_txedBuffer.at (seqNumberValue) = 0;
979 if (m_retxBuffer.at (seqNumberValue).m_pdu)
981 NS_LOG_INFO (
"ACKed SN = " << seqNumberValue <<
" from retxBuffer");
982 m_retxBufferSize -= m_retxBuffer.at (seqNumberValue).m_pdu->GetSize ();
983 m_retxBuffer.at (seqNumberValue).m_pdu = 0;
984 m_retxBuffer.at (seqNumberValue).m_retxCount = 0;
992 SequenceNumber10 seqNumber =
m_vtA;
993 uint16_t seqNumberValue;
994 while (seqNumber < m_vtS)
996 seqNumberValue = seqNumber.
GetValue ();
997 if (m_txedBuffer.at (seqNumberValue))
999 NS_LOG_INFO (
"Move SN = " << seqNumberValue <<
" to retxBuffer");
1000 m_retxBuffer.at (seqNumberValue).m_pdu = m_txedBuffer.at (seqNumberValue)->Copy ();
1001 m_retxBuffer.at (seqNumberValue).m_retxCount = 0;
1002 m_retxBufferSize += m_retxBuffer.at (seqNumberValue).m_pdu->GetSize ();
1004 m_txedBufferSize -= m_txedBuffer.at (seqNumberValue)->GetSize ();
1005 m_txedBuffer.at (seqNumberValue) = 0;
1007 else if (m_retxBuffer.at (seqNumberValue).m_pdu)
1009 m_retxBuffer.at (seqNumberValue).m_retxCount++;
1010 NS_LOG_INFO (
"Incr RETX_COUNT for SN = " << seqNumberValue);
1013 NS_LOG_INFO (
"Max RETX_COUNT for SN = " << seqNumberValue);
1032 LteRlcAm::IsInsideReceivingWindow (SequenceNumber10 seqNumber)
1036 m_vrR <<
" <= " << seqNumber <<
" <= " << m_vrMr);
1038 m_vrR.SetModulusBase (m_vrR);
1039 m_vrMr.SetModulusBase (m_vrR);
1040 seqNumber.SetModulusBase (m_vrR);
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");
1060 uint8_t framingInfo = rlcAmHeader.GetFramingInfo ();
1062 bool expectedSnLost;
1066 expectedSnLost =
true;
1072 expectedSnLost =
false;
1078 uint8_t extensionBit;
1079 uint16_t lengthIndicator;
1082 extensionBit = rlcAmHeader.PopExtensionBit ();
1085 if ( extensionBit == 0 )
1087 m_sdusBuffer.push_back (packet);
1091 lengthIndicator = rlcAmHeader.PopLengthIndicator ();
1095 if ( lengthIndicator >= packet->
GetSize () )
1097 NS_LOG_LOGIC (
"INTERNAL ERROR: Not enough data in the packet (" << packet->
GetSize () <<
"). Needed LI=" << lengthIndicator);
1105 m_sdusBuffer.push_back (data_field);
1108 while ( extensionBit == 1 );
1110 std::list < Ptr<Packet> >::iterator it;
1113 if (m_reassemblingState == WAITING_S0_FULL)
NS_LOG_LOGIC (
"Reassembling State = 'WAITING_S0_FULL'");
1114 else if (m_reassemblingState == WAITING_SI_SF)
NS_LOG_LOGIC (
"Reassembling State = 'WAITING_SI_SF'");
1115 else NS_LOG_LOGIC (
"Reassembling State = Unknown state");
1118 NS_LOG_LOGIC (
"Framing Info = " << (uint16_t)framingInfo);
1119 NS_LOG_LOGIC (
"m_sdusBuffer = " << m_sdusBuffer.size ());
1122 if (!expectedSnLost)
1124 switch (m_reassemblingState)
1126 case WAITING_S0_FULL:
1127 switch (framingInfo)
1129 case (LteRlcAmHeader::FIRST_BYTE | LteRlcAmHeader::LAST_BYTE):
1130 m_reassemblingState = WAITING_S0_FULL;
1135 for ( it = m_sdusBuffer.begin () ; it != m_sdusBuffer.end () ; it++ )
1139 m_sdusBuffer.clear ();
1142 case (LteRlcAmHeader::FIRST_BYTE | LteRlcAmHeader::NO_LAST_BYTE):
1143 m_reassemblingState = WAITING_SI_SF;
1148 while ( m_sdusBuffer.size () > 1 )
1151 m_sdusBuffer.pop_front ();
1157 m_keepS0 = m_sdusBuffer.front ();
1158 m_sdusBuffer.pop_front ();
1161 case (LteRlcAmHeader::NO_FIRST_BYTE | LteRlcAmHeader::LAST_BYTE):
1162 case (LteRlcAmHeader::NO_FIRST_BYTE | LteRlcAmHeader::NO_LAST_BYTE):
1167 NS_LOG_LOGIC (
"INTERNAL ERROR: Transition not possible. FI = " << (uint32_t) framingInfo);
1173 switch (framingInfo)
1175 case (LteRlcAmHeader::NO_FIRST_BYTE | LteRlcAmHeader::LAST_BYTE):
1176 m_reassemblingState = WAITING_S0_FULL;
1181 m_keepS0->
AddAtEnd (m_sdusBuffer.front ());
1182 m_sdusBuffer.pop_front ();
1188 while ( ! m_sdusBuffer.empty () )
1191 m_sdusBuffer.pop_front ();
1195 case (LteRlcAmHeader::NO_FIRST_BYTE | LteRlcAmHeader::NO_LAST_BYTE):
1196 m_reassemblingState = WAITING_SI_SF;
1201 if ( m_sdusBuffer.size () == 1 )
1203 m_keepS0->
AddAtEnd (m_sdusBuffer.front ());
1204 m_sdusBuffer.pop_front ();
1211 m_keepS0->
AddAtEnd (m_sdusBuffer.front ());
1212 m_sdusBuffer.pop_front ();
1218 while ( m_sdusBuffer.size () > 1 )
1221 m_sdusBuffer.pop_front ();
1227 m_keepS0 = m_sdusBuffer.front ();
1228 m_sdusBuffer.pop_front ();
1232 case (LteRlcAmHeader::FIRST_BYTE | LteRlcAmHeader::LAST_BYTE):
1233 case (LteRlcAmHeader::FIRST_BYTE | LteRlcAmHeader::NO_LAST_BYTE):
1238 NS_LOG_LOGIC (
"INTERNAL ERROR: Transition not possible. FI = " << (uint32_t) framingInfo);
1244 NS_LOG_LOGIC (
"INTERNAL ERROR: Wrong reassembling state = " << (uint32_t) m_reassemblingState);
1250 switch (m_reassemblingState)
1252 case WAITING_S0_FULL:
1253 switch (framingInfo)
1255 case (LteRlcAmHeader::FIRST_BYTE | LteRlcAmHeader::LAST_BYTE):
1256 m_reassemblingState = WAITING_S0_FULL;
1261 for ( it = m_sdusBuffer.begin () ; it != m_sdusBuffer.end () ; it++ )
1265 m_sdusBuffer.clear ();
1268 case (LteRlcAmHeader::FIRST_BYTE | LteRlcAmHeader::NO_LAST_BYTE):
1269 m_reassemblingState = WAITING_SI_SF;
1274 while ( m_sdusBuffer.size () > 1 )
1277 m_sdusBuffer.pop_front ();
1283 m_keepS0 = m_sdusBuffer.front ();
1284 m_sdusBuffer.pop_front ();
1287 case (LteRlcAmHeader::NO_FIRST_BYTE | LteRlcAmHeader::LAST_BYTE):
1288 m_reassemblingState = WAITING_S0_FULL;
1293 m_sdusBuffer.pop_front ();
1298 while ( ! m_sdusBuffer.empty () )
1301 m_sdusBuffer.pop_front ();
1305 case (LteRlcAmHeader::NO_FIRST_BYTE | LteRlcAmHeader::NO_LAST_BYTE):
1306 if ( m_sdusBuffer.size () == 1 )
1308 m_reassemblingState = WAITING_S0_FULL;
1312 m_reassemblingState = WAITING_SI_SF;
1318 m_sdusBuffer.pop_front ();
1320 if ( m_sdusBuffer.size () > 0 )
1325 while ( m_sdusBuffer.size () > 1 )
1328 m_sdusBuffer.pop_front ();
1334 m_keepS0 = m_sdusBuffer.front ();
1335 m_sdusBuffer.pop_front ();
1343 NS_LOG_LOGIC (
"INTERNAL ERROR: Transition not possible. FI = " << (uint32_t) framingInfo);
1349 switch (framingInfo)
1351 case (LteRlcAmHeader::FIRST_BYTE | LteRlcAmHeader::LAST_BYTE):
1352 m_reassemblingState = WAITING_S0_FULL;
1362 while ( ! m_sdusBuffer.empty () )
1365 m_sdusBuffer.pop_front ();
1369 case (LteRlcAmHeader::FIRST_BYTE | LteRlcAmHeader::NO_LAST_BYTE):
1370 m_reassemblingState = WAITING_SI_SF;
1380 while ( m_sdusBuffer.size () > 1 )
1383 m_sdusBuffer.pop_front ();
1389 m_keepS0 = m_sdusBuffer.front ();
1390 m_sdusBuffer.pop_front ();
1394 case (LteRlcAmHeader::NO_FIRST_BYTE | LteRlcAmHeader::LAST_BYTE):
1395 m_reassemblingState = WAITING_S0_FULL;
1405 m_sdusBuffer.pop_front ();
1410 while ( ! m_sdusBuffer.empty () )
1413 m_sdusBuffer.pop_front ();
1417 case (LteRlcAmHeader::NO_FIRST_BYTE | LteRlcAmHeader::NO_LAST_BYTE):
1418 if ( m_sdusBuffer.size () == 1 )
1420 m_reassemblingState = WAITING_S0_FULL;
1424 m_reassemblingState = WAITING_SI_SF;
1435 m_sdusBuffer.pop_front ();
1437 if ( m_sdusBuffer.size () > 0 )
1442 while ( m_sdusBuffer.size () > 1 )
1445 m_sdusBuffer.pop_front ();
1451 m_keepS0 = m_sdusBuffer.front ();
1452 m_sdusBuffer.pop_front ();
1460 NS_LOG_LOGIC (
"INTERNAL ERROR: Transition not possible. FI = " << (uint32_t) framingInfo);
1466 NS_LOG_LOGIC (
"INTERNAL ERROR: Wrong reassembling state = " << (uint32_t) m_reassemblingState);
1527 LteRlcAm::DoReportBufferStatus (
void)
1533 NS_LOG_LOGIC (
"txonBufferSize = " << m_txonBufferSize);
1534 NS_LOG_LOGIC (
"retxBufferSize = " << m_retxBufferSize);
1535 NS_LOG_LOGIC (
"txedBufferSize = " << m_txedBufferSize);
1540 Time txonQueueHolDelay (0);
1541 if ( m_txonBufferSize > 0 )
1543 RlcTag txonQueueHolTimeTag;
1544 m_txonBuffer.front ()->PeekPacketTag (txonQueueHolTimeTag);
1549 Time retxQueueHolDelay (0);
1550 RlcTag retxQueueHolTimeTag;
1551 if ( m_retxBufferSize > 0 )
1553 m_retxBuffer.at (
m_vtA.
GetValue ()).m_pdu->PeekPacketTag (retxQueueHolTimeTag);
1554 retxQueueHolDelay = now - retxQueueHolTimeTag.GetSenderTimestamp ();
1556 else if ( m_txedBufferSize > 0 )
1558 m_txedBuffer.at (
m_vtA.
GetValue ())->PeekPacketTag (retxQueueHolTimeTag);
1559 retxQueueHolDelay = now - retxQueueHolTimeTag.GetSenderTimestamp ();
1562 LteMacSapProvider::ReportBufferStatusParameters r;
1565 r.txQueueSize = m_txonBufferSize;
1566 r.txQueueHolDelay = txonQueueHolDelay.GetMilliSeconds ();
1567 r.retxQueueSize = m_retxBufferSize + m_txedBufferSize;
1568 r.retxQueueHolDelay = retxQueueHolDelay.GetMilliSeconds ();
1570 if ( m_statusPduRequested && ! m_statusProhibitTimer.
IsRunning () )
1572 r.statusPduSize = m_statusPduBufferSize;
1576 r.statusPduSize = 0;
1579 if ( r.txQueueSize != 0 || r.retxQueueSize != 0 || r.statusPduSize != 0 )
1581 NS_LOG_INFO (
"Send ReportBufferStatus: " << r.txQueueSize <<
", " << r.txQueueHolDelay <<
", "
1582 << r.retxQueueSize <<
", " << r.retxQueueHolDelay <<
", "
1583 << r.statusPduSize);
1608 int firstVrMs = m_vrMs.
GetValue ();
1609 std::map <uint16_t, PduBuffer>::iterator it = m_rxonBuffer.find (m_vrMs.
GetValue ());
1610 while ( it != m_rxonBuffer.end () &&
1611 m_rxonBuffer[ m_vrMs.
GetValue () ].m_pduComplete )
1614 it = m_rxonBuffer.find (m_vrMs.
GetValue ());
1620 if ( m_vrH > m_vrMs )
1631 LteRlcAm::ExpirePollRetransmitTimer (
void)
1636 NS_LOG_LOGIC (
"txonBufferSize = " << m_txonBufferSize);
1637 NS_LOG_LOGIC (
"retxBufferSize = " << m_retxBufferSize);
1638 NS_LOG_LOGIC (
"txedBufferSize = " << m_txedBufferSize);
1639 NS_LOG_LOGIC (
"statusPduRequested = " << m_statusPduRequested);
1641 DoReportBufferStatus ();
uint32_t RemoveHeader(Header &header)
TracedCallback< uint16_t, uint8_t, uint32_t > m_txPdu
#define NS_LOG_FUNCTION(parameters)
uint16_t GetValue() const
Extracts the numeric value of the sequence number.
virtual void DoNotifyTxOpportunity(uint32_t bytes, uint8_t layer, uint8_t harqId)
void AddPacketTag(const Tag &tag) const
#define NS_LOG_COMPONENT_DEFINE(name)
uint32_t GetSize(void) const
bool IsRunning(void) const
static EventId Schedule(Time const &time, MEM mem_ptr, OBJ obj)
EventId m_pollRetransmitTimer
Ptr< Packet > CreateFragment(uint32_t start, uint32_t length) const
void AddAtEnd(Ptr< const Packet > packet)
SequenceNumber10 m_expectedSeqNumber
void RemoveAtStart(uint32_t size)
virtual void ReceivePdcpPdu(Ptr< Packet > p)=0
#define NS_LOG_LOGIC(msg)
Ptr< Packet > Copy(void) const
uint32_t PeekHeader(Header &header) const
Time GetSenderTimestamp(void) const
uint32_t m_pduWithoutPoll
uint16_t m_maxRetxThreshold
#define NS_ASSERT_MSG(condition, message)
This class implements a tag that carries the status of a RLC SDU for the fragmentation process Status...
bool RemovePacketTag(Tag &tag)
virtual void ReportBufferStatus(ReportBufferStatusParameters params)=0
Time MilliSeconds(uint64_t ms)
create ns3::Time instances in units of milliseconds.
TracedCallback< uint16_t, uint8_t, uint32_t, uint64_t > m_rxPdu
void ReassembleAndDeliver(Ptr< Packet > packet)
virtual void TransmitPdu(TransmitPduParameters params)=0
void ExpireReorderingTimer(void)
virtual void DoTransmitPdcpPdu(Ptr< Packet > p)
void AddHeader(const Header &header)
void AddByteTag(const Tag &tag) const