9#include "nr-rlc-header.h"
10#include "nr-rlc-sdu-status-tag.h"
11#include "nr-rlc-tag.h"
14#include "ns3/simulator.h"
19NS_LOG_COMPONENT_DEFINE(
"NrRlcUm");
21NS_OBJECT_ENSURE_REGISTERED(NrRlcUm);
24 : m_maxTxBufferSize(10 * 1024),
31 m_expectedSeqNumber(0)
33 NS_LOG_FUNCTION(
this);
34 m_reassemblingState = WAITING_S0_FULL;
39 NS_LOG_FUNCTION(
this);
46 TypeId(
"ns3::NrRlcUm")
50 .AddAttribute(
"MaxTxBufferSize",
51 "Maximum Size of the Transmission Buffer (in Bytes)",
52 UintegerValue(10 * 1024),
53 MakeUintegerAccessor(&NrRlcUm::m_maxTxBufferSize),
54 MakeUintegerChecker<uint32_t>())
55 .AddAttribute(
"ReorderingTimer",
56 "Value of the t-Reordering timer (See section 7.3 of 3GPP TS 36.322)",
57 TimeValue(MilliSeconds(100)),
58 MakeTimeAccessor(&NrRlcUm::m_reorderingTimerValue),
61 "EnablePdcpDiscarding",
62 "Whether to use the PDCP discarding, i.e., perform discarding at the moment "
63 "of passing the PDCP SDU to RLC)",
65 MakeBooleanAccessor(&NrRlcUm::m_enablePdcpDiscarding),
67 .AddAttribute(
"DiscardTimerMs",
68 "Discard timer in milliseconds to be used to discard packets. "
69 "If set to 0 then packet delay budget will be used as the discard "
70 "timer value, otherwise it will be used this value.",
72 MakeUintegerAccessor(&NrRlcUm::m_discardTimerMs),
73 MakeUintegerChecker<uint32_t>())
74 .AddAttribute(
"OutOfOfOrderDelivery",
75 "Whether to deliver RLC SDUs out of order without waiting for a "
76 "reordering timer to expire",
78 MakeBooleanAccessor(&NrRlcUm::m_outOfOrderDelivery),
79 MakeBooleanChecker());
86 NS_LOG_FUNCTION(
this);
87 m_reorderingTimer.Cancel();
98NrRlcUm::DoTransmitPdcpPdu(Ptr<Packet> p)
100 NS_LOG_FUNCTION(
this << m_rnti << (uint32_t)m_lcid << p->GetSize());
101 if (m_txBufferSize + p->GetSize() <= m_maxTxBufferSize)
103 if (m_enablePdcpDiscarding)
106 uint32_t headOfLineDelayInMs = 0;
107 uint32_t discardTimerMs =
108 (m_discardTimerMs > 0) ? m_discardTimerMs : m_packetDelayBudgetMs;
110 if (!m_txBuffer.empty())
112 headOfLineDelayInMs =
113 (Simulator::Now() - m_txBuffer.begin()->m_waitingSince).GetMilliSeconds();
115 NS_LOG_DEBUG(
"head of line delay in MS:" << headOfLineDelayInMs);
116 if (headOfLineDelayInMs > discardTimerMs)
118 NS_LOG_INFO(
"Tx HOL is higher than this packet can allow. RLC SDU discarded");
119 NS_LOG_DEBUG(
"headOfLineDelayInMs = " << headOfLineDelayInMs);
120 NS_LOG_DEBUG(
"m_packetDelayBudgetMs = " << m_packetDelayBudgetMs);
121 NS_LOG_DEBUG(
"packet size = " << p->GetSize());
128 tag.
SetStatus(NrRlcSduStatusTag::FULL_SDU);
129 p->AddPacketTag(tag);
130 NS_LOG_INFO(
"Adding RLC SDU to Tx Buffer after adding NrRlcSduStatusTag: FULL_SDU");
131 m_txBuffer.emplace_back(p, Simulator::Now());
132 m_txBufferSize += p->GetSize();
133 NS_LOG_LOGIC(
"NumOfBuffers = " << m_txBuffer.size());
134 NS_LOG_LOGIC(
"txBufferSize = " << m_txBufferSize);
139 NS_LOG_INFO(
"Tx Buffer is full. RLC SDU discarded");
140 NS_LOG_LOGIC(
"MaxTxBufferSize = " << m_maxTxBufferSize);
141 NS_LOG_LOGIC(
"txBufferSize = " << m_txBufferSize);
142 NS_LOG_LOGIC(
"packet size = " << p->GetSize());
147 DoTransmitBufferStatusReport();
158 NS_LOG_FUNCTION(
this << m_rnti << (uint32_t)m_lcid << txOpParams.
bytes);
159 NS_LOG_INFO(
"RLC layer is preparing data for the following Tx opportunity of "
160 << txOpParams.
bytes <<
" bytes for RNTI=" << m_rnti <<
", LCID=" << (uint32_t)m_lcid
162 << (uint32_t)txOpParams.
harqId <<
", MIMO Layer=" << (uint32_t)txOpParams.
layer);
164 if (txOpParams.
bytes <= 2)
167 NS_LOG_INFO(
"TX opportunity too small - Only " << txOpParams.
bytes <<
" bytes");
171 Ptr<Packet> packet = Create<Packet>();
175 uint32_t nextSegmentSize = txOpParams.
bytes - 2;
176 uint32_t nextSegmentId = 1;
177 uint32_t dataFieldAddedSize = 0;
178 std::vector<Ptr<Packet>> dataField;
182 if (m_txBuffer.empty())
184 NS_LOG_LOGIC(
"No data pending");
188 Ptr<Packet> firstSegment = m_txBuffer.begin()->m_pdu->Copy();
189 Time firstSegmentTime = m_txBuffer.begin()->m_waitingSince;
191 NS_LOG_LOGIC(
"SDUs in TxBuffer = " << m_txBuffer.size());
192 NS_LOG_LOGIC(
"First SDU buffer = " << firstSegment);
193 NS_LOG_LOGIC(
"First SDU size = " << firstSegment->GetSize());
194 NS_LOG_LOGIC(
"Next segment size = " << nextSegmentSize);
195 NS_LOG_LOGIC(
"Remove SDU from TxBuffer");
196 m_txBufferSize -= firstSegment->GetSize();
197 NS_LOG_LOGIC(
"txBufferSize = " << m_txBufferSize);
198 m_txBuffer.erase(m_txBuffer.begin());
200 while (firstSegment && (firstSegment->GetSize() > 0) && (nextSegmentSize > 0))
202 NS_LOG_LOGIC(
"WHILE ( firstSegment && firstSegment->GetSize > 0 && nextSegmentSize > 0 )");
203 NS_LOG_LOGIC(
" firstSegment size = " << firstSegment->GetSize());
204 NS_LOG_LOGIC(
" nextSegmentSize = " << nextSegmentSize);
205 if ((firstSegment->GetSize() > nextSegmentSize) ||
207 (firstSegment->GetSize() > 2047))
211 uint32_t currSegmentSize = std::min(firstSegment->GetSize(), nextSegmentSize);
213 NS_LOG_LOGIC(
" IF ( firstSegment > nextSegmentSize ||");
214 NS_LOG_LOGIC(
" firstSegment > 2047 )");
218 Ptr<Packet> newSegment = firstSegment->CreateFragment(0, currSegmentSize);
219 NS_LOG_LOGIC(
" newSegment size = " << newSegment->GetSize());
226 firstSegment->RemovePacketTag(oldTag);
227 newSegment->RemovePacketTag(newTag);
228 if (oldTag.
GetStatus() == NrRlcSduStatusTag::FULL_SDU)
230 newTag.
SetStatus(NrRlcSduStatusTag::FIRST_SEGMENT);
231 oldTag.
SetStatus(NrRlcSduStatusTag::LAST_SEGMENT);
233 else if (oldTag.
GetStatus() == NrRlcSduStatusTag::LAST_SEGMENT)
235 newTag.
SetStatus(NrRlcSduStatusTag::MIDDLE_SEGMENT);
240 firstSegment->RemoveAtStart(currSegmentSize);
242 " firstSegment size (after RemoveAtStart) = " << firstSegment->GetSize());
243 if (firstSegment->GetSize() > 0)
245 firstSegment->AddPacketTag(oldTag);
247 m_txBuffer.insert(m_txBuffer.begin(), TxPdu(firstSegment, firstSegmentTime));
248 m_txBufferSize += m_txBuffer.begin()->m_pdu->GetSize();
250 NS_LOG_LOGIC(
" TX buffer: Give back the remaining segment");
251 NS_LOG_LOGIC(
" TX buffers = " << m_txBuffer.size());
252 NS_LOG_LOGIC(
" Front buffer size = " << m_txBuffer.begin()->m_pdu->GetSize());
253 NS_LOG_LOGIC(
" txBufferSize = " << m_txBufferSize);
258 if (newTag.
GetStatus() == NrRlcSduStatusTag::FIRST_SEGMENT)
260 newTag.
SetStatus(NrRlcSduStatusTag::FULL_SDU);
262 else if (newTag.
GetStatus() == NrRlcSduStatusTag::MIDDLE_SEGMENT)
264 newTag.
SetStatus(NrRlcSduStatusTag::LAST_SEGMENT);
269 firstSegment =
nullptr;
272 newSegment->AddPacketTag(newTag);
275 dataFieldAddedSize = newSegment->GetSize();
276 dataField.push_back(newSegment);
277 newSegment =
nullptr;
284 nextSegmentSize -= dataFieldAddedSize;
292 else if ((nextSegmentSize - firstSegment->GetSize() <= 2) || m_txBuffer.empty())
295 " IF nextSegmentSize - firstSegment->GetSize () <= 2 || txBuffer.size == 0");
297 dataFieldAddedSize = firstSegment->GetSize();
298 dataField.push_back(firstSegment);
299 firstSegment =
nullptr;
306 nextSegmentSize -= dataFieldAddedSize;
309 NS_LOG_LOGIC(
" SDUs in TxBuffer = " << m_txBuffer.size());
310 if (!m_txBuffer.empty())
312 NS_LOG_LOGIC(
" First SDU buffer = " << m_txBuffer.begin()->m_pdu);
314 " First SDU size = " << m_txBuffer.begin()->m_pdu->GetSize());
316 NS_LOG_LOGIC(
" Next segment size = " << nextSegmentSize);
325 NS_LOG_LOGIC(
" IF firstSegment < NextSegmentSize && txBuffer.size > 0");
327 dataFieldAddedSize = firstSegment->GetSize();
328 dataField.push_back(firstSegment);
336 nextSegmentSize -= ((nextSegmentId % 2) ? (2) : (1)) + dataFieldAddedSize;
339 NS_LOG_LOGIC(
" SDUs in TxBuffer = " << m_txBuffer.size());
340 if (!m_txBuffer.empty())
342 NS_LOG_LOGIC(
" First SDU buffer = " << m_txBuffer.begin()->m_pdu);
344 " First SDU size = " << m_txBuffer.begin()->m_pdu->GetSize());
346 NS_LOG_LOGIC(
" Next segment size = " << nextSegmentSize);
347 NS_LOG_LOGIC(
" Remove SDU from TxBuffer");
350 firstSegment = m_txBuffer.begin()->m_pdu->Copy();
351 firstSegmentTime = m_txBuffer.begin()->m_waitingSince;
352 m_txBufferSize -= firstSegment->GetSize();
353 m_txBuffer.pop_front();
354 NS_LOG_LOGIC(
" txBufferSize = " << m_txBufferSize);
362 auto it = dataField.begin();
364 uint8_t framingInfo = 0;
368 NS_ASSERT_MSG((*it)->PeekPacketTag(tag),
"NrRlcSduStatusTag is missing");
369 (*it)->PeekPacketTag(tag);
370 if ((tag.
GetStatus() == NrRlcSduStatusTag::FULL_SDU) ||
371 (tag.
GetStatus() == NrRlcSduStatusTag::FIRST_SEGMENT))
373 framingInfo |= NrRlcHeader::FIRST_BYTE;
377 framingInfo |= NrRlcHeader::NO_FIRST_BYTE;
380 while (it < dataField.end())
382 NS_LOG_LOGIC(
"Adding SDU/segment to packet, length = " << (*it)->GetSize());
384 NS_ASSERT_MSG((*it)->PeekPacketTag(tag),
"NrRlcSduStatusTag is missing");
385 (*it)->RemovePacketTag(tag);
386 if (packet->GetSize() > 0)
388 packet->AddAtEnd(*it);
399 if ((tag.
GetStatus() == NrRlcSduStatusTag::FULL_SDU) ||
400 (tag.
GetStatus() == NrRlcSduStatusTag::LAST_SEGMENT))
402 framingInfo |= NrRlcHeader::LAST_BYTE;
406 framingInfo |= NrRlcHeader::NO_LAST_BYTE;
411 NS_LOG_LOGIC(
"RLC header: " << rlcHeader);
412 packet->AddHeader(rlcHeader);
416 packet->AddByteTag(rlcTag, 1, rlcHeader.GetSerializedSize());
417 m_txPdu(m_rnti, m_lcid, packet->GetSize());
422 params.
rnti = m_rnti;
423 params.
lcid = m_lcid;
428 NS_LOG_INFO(
"Forward RLC PDU to MAC Layer");
429 m_macSapProvider->TransmitPdu(params);
431 if (!m_txBuffer.empty())
434 m_bsrTimer = Simulator::Schedule(MilliSeconds(10), &NrRlcUm::ExpireBsrTimer,
this);
439NrRlcUm::DoNotifyHarqDeliveryFailure()
441 NS_LOG_FUNCTION(
this);
447 NS_LOG_FUNCTION(
this << m_rnti << (uint32_t)m_lcid << rxPduParams.
p->GetSize());
453 bool ret = rxPduParams.
p->FindFirstMatchingByteTag(rlcTag);
454 NS_ASSERT_MSG(ret,
"NrRlcTag is missing");
457 m_rxPdu(m_rnti, m_lcid, rxPduParams.
p->GetSize(), delay.GetNanoSeconds());
463 rxPduParams.
p->PeekHeader(rlcHeader);
464 NS_LOG_LOGIC(
"RLC header: " << rlcHeader);
490 NS_LOG_LOGIC(
"VR(UR) = " << m_vrUr);
491 NS_LOG_LOGIC(
"VR(UX) = " << m_vrUx);
492 NS_LOG_LOGIC(
"VR(UH) = " << m_vrUh);
493 NS_LOG_LOGIC(
"SN = " << seqNumber);
495 m_vrUr.SetModulusBase(m_vrUh - m_windowSize);
496 m_vrUh.SetModulusBase(m_vrUh - m_windowSize);
499 if (((m_vrUr < seqNumber) && (seqNumber < m_vrUh) &&
500 (m_rxBuffer.count(seqNumber.
GetValue()) > 0)) ||
501 (((m_vrUh - m_windowSize) <= seqNumber) && (seqNumber < m_vrUr)))
503 NS_LOG_LOGIC(
"PDU discarded");
504 rxPduParams.
p =
nullptr;
509 NS_LOG_LOGIC(
"Place PDU in the reception buffer");
510 m_rxBuffer[seqNumber.
GetValue()] = rxPduParams.
p;
522 if (m_outOfOrderDelivery)
524 ReassembleOutsideWindow();
536 if (!IsInsideReorderingWindow(seqNumber))
538 NS_LOG_LOGIC(
"SN is outside the reordering window");
540 m_vrUh = seqNumber + 1;
541 NS_LOG_LOGIC(
"New VR(UH) = " << m_vrUh);
543 ReassembleOutsideWindow();
545 if (!IsInsideReorderingWindow(m_vrUr))
547 m_vrUr = m_vrUh - m_windowSize;
548 NS_LOG_LOGIC(
"VR(UR) is outside the reordering window");
549 NS_LOG_LOGIC(
"New VR(UR) = " << m_vrUr);
561 if (m_rxBuffer.count(m_vrUr.GetValue()) > 0)
563 NS_LOG_LOGIC(
"Reception buffer contains SN = " << m_vrUr);
568 auto it = m_rxBuffer.find(m_vrUr.GetValue());
569 newVrUr = (it->first) + 1;
570 while (m_rxBuffer.count(newVrUr) > 0)
575 NS_LOG_LOGIC(
"New VR(UR) = " << m_vrUr);
577 ReassembleSnInterval(oldVrUr, m_vrUr);
582 m_vrUr.SetModulusBase(m_vrUh - m_windowSize);
583 m_vrUx.SetModulusBase(m_vrUh - m_windowSize);
584 m_vrUh.SetModulusBase(m_vrUh - m_windowSize);
590 if (m_reorderingTimer.IsPending())
592 NS_LOG_LOGIC(
"Reordering timer is running");
594 if ((m_vrUx <= m_vrUr) || ((!IsInsideReorderingWindow(m_vrUx)) && (m_vrUx != m_vrUh)))
596 NS_LOG_LOGIC(
"Stop reordering timer");
597 m_reorderingTimer.Cancel();
606 if (!m_reorderingTimer.IsPending())
608 NS_LOG_LOGIC(
"Reordering timer is not running");
612 NS_LOG_LOGIC(
"VR(UH) > VR(UR)");
613 NS_LOG_LOGIC(
"Start reordering timer");
615 Simulator::Schedule(m_reorderingTimerValue, &NrRlcUm::ExpireReorderingTimer,
this);
617 NS_LOG_LOGIC(
"New VR(UX) = " << m_vrUx);
625 NS_LOG_FUNCTION(
this << seqNumber);
626 NS_LOG_LOGIC(
"Reordering Window: " << m_vrUh <<
" - " << m_windowSize <<
" <= " << seqNumber
629 m_vrUh.SetModulusBase(m_vrUh - m_windowSize);
632 if (((m_vrUh - m_windowSize) <= seqNumber) && (seqNumber < m_vrUh))
634 NS_LOG_LOGIC(seqNumber <<
" is INSIDE the reordering window");
639 NS_LOG_LOGIC(seqNumber <<
" is OUTSIDE the reordering window");
645NrRlcUm::ReassembleAndDeliver(Ptr<Packet> packet)
647 NrRlcHeader rlcHeader;
648 packet->RemoveHeader(rlcHeader);
649 uint8_t framingInfo = rlcHeader.GetFramingInfo();
650 nr::SequenceNumber10 currSeqNumber = rlcHeader.GetSequenceNumber();
653 if (currSeqNumber != m_expectedSeqNumber)
655 expectedSnLost =
true;
656 NS_LOG_LOGIC(
"There are losses. Expected SN = " << m_expectedSeqNumber
657 <<
". Current SN = " << currSeqNumber);
658 m_expectedSeqNumber = currSeqNumber + 1;
662 expectedSnLost =
false;
663 NS_LOG_LOGIC(
"No losses. Expected SN = " << m_expectedSeqNumber
664 <<
". Current SN = " << currSeqNumber);
665 m_expectedSeqNumber++;
669 uint8_t extensionBit;
670 uint16_t lengthIndicator;
673 extensionBit = rlcHeader.PopExtensionBit();
674 NS_LOG_LOGIC(
"E = " << (uint16_t)extensionBit);
676 if (extensionBit == 0)
678 m_sdusBuffer.push_back(packet);
682 lengthIndicator = rlcHeader.PopLengthIndicator();
683 NS_LOG_LOGIC(
"LI = " << lengthIndicator);
686 if (lengthIndicator >= packet->GetSize())
688 NS_LOG_LOGIC(
"INTERNAL ERROR: Not enough data in the packet ("
689 << packet->GetSize() <<
"). Needed LI=" << lengthIndicator);
693 Ptr<Packet> data_field = packet->CreateFragment(0, lengthIndicator);
694 packet->RemoveAtStart(lengthIndicator);
696 m_sdusBuffer.push_back(data_field);
698 }
while (extensionBit == 1);
701 if (m_reassemblingState == WAITING_S0_FULL)
703 NS_LOG_LOGIC(
"Reassembling State = 'WAITING_S0_FULL'");
705 else if (m_reassemblingState == WAITING_SI_SF)
707 NS_LOG_LOGIC(
"Reassembling State = 'WAITING_SI_SF'");
711 NS_LOG_LOGIC(
"Reassembling State = Unknown state");
715 NS_LOG_LOGIC(
"Framing Info = " << (uint16_t)framingInfo);
720 switch (m_reassemblingState)
722 case WAITING_S0_FULL:
725 case (NrRlcHeader::FIRST_BYTE | NrRlcHeader::LAST_BYTE):
726 m_reassemblingState = WAITING_S0_FULL;
731 for (
auto it = m_sdusBuffer.begin(); it != m_sdusBuffer.end(); it++)
733 m_rlcSapUser->ReceivePdcpPdu(*it);
735 m_sdusBuffer.clear();
738 case (NrRlcHeader::FIRST_BYTE | NrRlcHeader::NO_LAST_BYTE):
739 m_reassemblingState = WAITING_SI_SF;
744 while (m_sdusBuffer.size() > 1)
746 m_rlcSapUser->ReceivePdcpPdu(m_sdusBuffer.front());
747 m_sdusBuffer.pop_front();
753 m_keepS0 = m_sdusBuffer.front();
754 m_sdusBuffer.pop_front();
757 case (NrRlcHeader::NO_FIRST_BYTE | NrRlcHeader::LAST_BYTE):
758 m_reassemblingState = WAITING_S0_FULL;
763 m_sdusBuffer.pop_front();
768 while (!m_sdusBuffer.empty())
770 m_rlcSapUser->ReceivePdcpPdu(m_sdusBuffer.front());
771 m_sdusBuffer.pop_front();
775 case (NrRlcHeader::NO_FIRST_BYTE | NrRlcHeader::NO_LAST_BYTE):
776 if (m_sdusBuffer.size() == 1)
778 m_reassemblingState = WAITING_S0_FULL;
782 m_reassemblingState = WAITING_SI_SF;
788 m_sdusBuffer.pop_front();
790 if (!m_sdusBuffer.empty())
795 while (m_sdusBuffer.size() > 1)
797 m_rlcSapUser->ReceivePdcpPdu(m_sdusBuffer.front());
798 m_sdusBuffer.pop_front();
804 m_keepS0 = m_sdusBuffer.front();
805 m_sdusBuffer.pop_front();
814 "INTERNAL ERROR: Transition not possible. FI = " << (uint32_t)framingInfo);
822 case (NrRlcHeader::NO_FIRST_BYTE | NrRlcHeader::LAST_BYTE):
823 m_reassemblingState = WAITING_S0_FULL;
828 m_keepS0->AddAtEnd(m_sdusBuffer.front());
829 m_sdusBuffer.pop_front();
830 m_rlcSapUser->ReceivePdcpPdu(m_keepS0);
835 while (!m_sdusBuffer.empty())
837 m_rlcSapUser->ReceivePdcpPdu(m_sdusBuffer.front());
838 m_sdusBuffer.pop_front();
842 case (NrRlcHeader::NO_FIRST_BYTE | NrRlcHeader::NO_LAST_BYTE):
843 m_reassemblingState = WAITING_SI_SF;
848 if (m_sdusBuffer.size() == 1)
850 m_keepS0->AddAtEnd(m_sdusBuffer.front());
851 m_sdusBuffer.pop_front();
858 m_keepS0->AddAtEnd(m_sdusBuffer.front());
859 m_sdusBuffer.pop_front();
860 m_rlcSapUser->ReceivePdcpPdu(m_keepS0);
865 while (m_sdusBuffer.size() > 1)
867 m_rlcSapUser->ReceivePdcpPdu(m_sdusBuffer.front());
868 m_sdusBuffer.pop_front();
874 m_keepS0 = m_sdusBuffer.front();
875 m_sdusBuffer.pop_front();
879 case (NrRlcHeader::FIRST_BYTE | NrRlcHeader::LAST_BYTE):
880 case (NrRlcHeader::FIRST_BYTE | NrRlcHeader::NO_LAST_BYTE):
886 "INTERNAL ERROR: Transition not possible. FI = " << (uint32_t)framingInfo);
893 "INTERNAL ERROR: Wrong reassembling state = " << (uint32_t)m_reassemblingState);
900 switch (m_reassemblingState)
902 case WAITING_S0_FULL:
905 case (NrRlcHeader::FIRST_BYTE | NrRlcHeader::LAST_BYTE):
906 m_reassemblingState = WAITING_S0_FULL;
911 for (
auto it = m_sdusBuffer.begin(); it != m_sdusBuffer.end(); it++)
913 m_rlcSapUser->ReceivePdcpPdu(*it);
915 m_sdusBuffer.clear();
918 case (NrRlcHeader::FIRST_BYTE | NrRlcHeader::NO_LAST_BYTE):
919 m_reassemblingState = WAITING_SI_SF;
924 while (m_sdusBuffer.size() > 1)
926 m_rlcSapUser->ReceivePdcpPdu(m_sdusBuffer.front());
927 m_sdusBuffer.pop_front();
933 m_keepS0 = m_sdusBuffer.front();
934 m_sdusBuffer.pop_front();
937 case (NrRlcHeader::NO_FIRST_BYTE | NrRlcHeader::LAST_BYTE):
938 m_reassemblingState = WAITING_S0_FULL;
943 m_sdusBuffer.pop_front();
948 while (!m_sdusBuffer.empty())
950 m_rlcSapUser->ReceivePdcpPdu(m_sdusBuffer.front());
951 m_sdusBuffer.pop_front();
955 case (NrRlcHeader::NO_FIRST_BYTE | NrRlcHeader::NO_LAST_BYTE):
956 if (m_sdusBuffer.size() == 1)
958 m_reassemblingState = WAITING_S0_FULL;
962 m_reassemblingState = WAITING_SI_SF;
968 m_sdusBuffer.pop_front();
970 if (!m_sdusBuffer.empty())
975 while (m_sdusBuffer.size() > 1)
977 m_rlcSapUser->ReceivePdcpPdu(m_sdusBuffer.front());
978 m_sdusBuffer.pop_front();
984 m_keepS0 = m_sdusBuffer.front();
985 m_sdusBuffer.pop_front();
994 "INTERNAL ERROR: Transition not possible. FI = " << (uint32_t)framingInfo);
1000 switch (framingInfo)
1002 case (NrRlcHeader::FIRST_BYTE | NrRlcHeader::LAST_BYTE):
1003 m_reassemblingState = WAITING_S0_FULL;
1013 while (!m_sdusBuffer.empty())
1015 m_rlcSapUser->ReceivePdcpPdu(m_sdusBuffer.front());
1016 m_sdusBuffer.pop_front();
1020 case (NrRlcHeader::FIRST_BYTE | NrRlcHeader::NO_LAST_BYTE):
1021 m_reassemblingState = WAITING_SI_SF;
1031 while (m_sdusBuffer.size() > 1)
1033 m_rlcSapUser->ReceivePdcpPdu(m_sdusBuffer.front());
1034 m_sdusBuffer.pop_front();
1040 m_keepS0 = m_sdusBuffer.front();
1041 m_sdusBuffer.pop_front();
1045 case (NrRlcHeader::NO_FIRST_BYTE | NrRlcHeader::LAST_BYTE):
1046 m_reassemblingState = WAITING_S0_FULL;
1056 m_sdusBuffer.pop_front();
1061 while (!m_sdusBuffer.empty())
1063 m_rlcSapUser->ReceivePdcpPdu(m_sdusBuffer.front());
1064 m_sdusBuffer.pop_front();
1068 case (NrRlcHeader::NO_FIRST_BYTE | NrRlcHeader::NO_LAST_BYTE):
1069 if (m_sdusBuffer.size() == 1)
1071 m_reassemblingState = WAITING_S0_FULL;
1075 m_reassemblingState = WAITING_SI_SF;
1086 m_sdusBuffer.pop_front();
1088 if (!m_sdusBuffer.empty())
1093 while (m_sdusBuffer.size() > 1)
1095 m_rlcSapUser->ReceivePdcpPdu(m_sdusBuffer.front());
1096 m_sdusBuffer.pop_front();
1102 m_keepS0 = m_sdusBuffer.front();
1103 m_sdusBuffer.pop_front();
1112 "INTERNAL ERROR: Transition not possible. FI = " << (uint32_t)framingInfo);
1119 "INTERNAL ERROR: Wrong reassembling state = " << (uint32_t)m_reassemblingState);
1126NrRlcUm::ReassembleOutsideWindow()
1128 NS_LOG_LOGIC(
"Reassemble Outside Window");
1130 auto it = m_rxBuffer.begin();
1132 while ((it != m_rxBuffer.end()) && !IsInsideReorderingWindow(nr::SequenceNumber10(it->first)))
1134 NS_LOG_LOGIC(
"SN = " << it->first);
1137 ReassembleAndDeliver(it->second);
1141 m_rxBuffer.erase(it_tmp);
1144 if (it != m_rxBuffer.end())
1146 NS_LOG_LOGIC(
"(SN = " << it->first <<
") is inside the reordering window");
1151NrRlcUm::ReassembleSnInterval(nr::SequenceNumber10 lowSeqNumber, nr::SequenceNumber10 highSeqNumber)
1153 NS_LOG_LOGIC(
"Reassemble SN between " << lowSeqNumber <<
" and " << highSeqNumber);
1155 nr::SequenceNumber10 reassembleSn = lowSeqNumber;
1156 NS_LOG_LOGIC(
"reassembleSN = " << reassembleSn);
1157 NS_LOG_LOGIC(
"highSeqNumber = " << highSeqNumber);
1158 while (reassembleSn < highSeqNumber)
1160 NS_LOG_LOGIC(
"reassembleSn < highSeqNumber");
1161 auto it = m_rxBuffer.find(reassembleSn.GetValue());
1162 NS_LOG_LOGIC(
"it->first = " << it->first);
1163 NS_LOG_LOGIC(
"it->second = " << it->second);
1164 if (it != m_rxBuffer.end())
1166 NS_LOG_LOGIC(
"SN = " << it->first);
1169 ReassembleAndDeliver(it->second);
1171 m_rxBuffer.erase(it);
1179NrRlcUm::DoTransmitBufferStatusReport()
1182 uint32_t queueSize = 0;
1184 if (!m_txBuffer.empty())
1186 holDelay = Simulator::Now() - m_txBuffer.front().m_waitingSince;
1189 m_txBufferSize + 2 * m_txBuffer.size();
1192 NrMacSapProvider::BufferStatusReportParameters r;
1195 r.txQueueSize = queueSize;
1196 r.txQueueHolDelay = holDelay.GetMilliSeconds();
1197 r.retxQueueSize = 0;
1198 r.retxQueueHolDelay = 0;
1199 r.statusPduSize = 0;
1200 r.expBsrTimer = m_expBsrTimer;
1202 m_expBsrTimer =
false;
1204 NS_LOG_LOGIC(
"Send BufferStatusReport = " << r.txQueueSize <<
", " << r.txQueueHolDelay);
1205 m_macSapProvider->BufferStatusReport(r);
1209NrRlcUm::ExpireReorderingTimer()
1211 NS_LOG_FUNCTION(
this << m_rnti << (uint32_t)m_lcid);
1212 NS_LOG_LOGIC(
"Reordering timer has expired");
1225 nr::SequenceNumber10 newVrUr = m_vrUx;
1227 while (m_rxBuffer.find(newVrUr.GetValue()) != m_rxBuffer.end())
1231 nr::SequenceNumber10 oldVrUr = m_vrUr;
1233 NS_LOG_LOGIC(
"New VR(UR) = " << m_vrUr);
1235 ReassembleSnInterval(oldVrUr, m_vrUr);
1237 if (m_vrUh > m_vrUr)
1239 NS_LOG_LOGIC(
"Start reordering timer");
1241 Simulator::Schedule(m_reorderingTimerValue, &NrRlcUm::ExpireReorderingTimer,
this);
1243 NS_LOG_LOGIC(
"New VR(UX) = " << m_vrUx);
1248NrRlcUm::ExpireBsrTimer()
1250 NS_LOG_LOGIC(
"BSR Timer expires");
1252 if (!m_txBuffer.empty())
1254 m_expBsrTimer =
true;
1255 DoTransmitBufferStatusReport();
1256 m_bsrTimer = Simulator::Schedule(MilliSeconds(10), &NrRlcUm::ExpireBsrTimer,
this);
This class implements a tag that carries the status of a RLC SDU for the fragmentation process Status...
void SetStatus(uint8_t status)
uint8_t GetStatus() const
Time GetSenderTimestamp() const
uint16_t GetValue() const
Extracts the numeric value of the sequence number.
void SetModulusBase(SequenceNumber10 modulusBase)
Set modulus base.
uint8_t componentCarrierId
uint8_t componentCarrierId