10#include "nr-rlc-am-header.h"
11#include "nr-rlc-sdu-status-tag.h"
12#include "nr-rlc-tag.h"
15#include "ns3/simulator.h"
20NS_LOG_COMPONENT_DEFINE(
"NrRlcAm");
22NS_OBJECT_ENSURE_REGISTERED(NrRlcAm);
26 NS_LOG_FUNCTION(
this);
30 m_retxBuffer.resize(1024);
32 m_txedBuffer.resize(1024);
35 m_statusPduRequested =
false;
36 m_statusPduBufferSize = 0;
41 m_vtMs = m_vtA + m_windowSize;
47 m_vrMr = m_vrR + m_windowSize;
54 m_byteWithoutPoll = 0;
57 m_maxRetxThreshold = 5;
62 m_reassemblingState = WAITING_S0_FULL;
63 m_expectedSeqNumber = 0;
65 m_pollRetransmitTimerJustExpired =
false;
70 NS_LOG_FUNCTION(
this);
77 TypeId(
"ns3::NrRlcAm")
81 .AddAttribute(
"PollRetransmitTimer",
82 "Value of the t-PollRetransmit timer (See section 7.3 of 3GPP TS 36.322)",
83 TimeValue(MilliSeconds(20)),
84 MakeTimeAccessor(&NrRlcAm::m_pollRetransmitTimerValue),
86 .AddAttribute(
"ReorderingTimer",
87 "Value of the t-Reordering timer (See section 7.3 of 3GPP TS 36.322)",
88 TimeValue(MilliSeconds(10)),
89 MakeTimeAccessor(&NrRlcAm::m_reorderingTimerValue),
91 .AddAttribute(
"StatusProhibitTimer",
92 "Value of the t-StatusProhibit timer (See section 7.3 of 3GPP TS 36.322)",
93 TimeValue(MilliSeconds(10)),
94 MakeTimeAccessor(&NrRlcAm::m_statusProhibitTimerValue),
97 "BufferStatusReportTimer",
98 "How much to wait to issue a new Buffer Status Report since the last time "
99 "a new SDU was received",
100 TimeValue(MilliSeconds(20)),
101 MakeTimeAccessor(&NrRlcAm::m_bsrTimerValue),
103 .AddAttribute(
"TxOpportunityForRetxAlwaysBigEnough",
104 "If true, always pretend that the size of a TxOpportunity is big enough "
105 "for retransmission. If false (default and realistic behavior), no retx "
106 "is performed unless the corresponding TxOpportunity is big enough.",
108 MakeBooleanAccessor(&NrRlcAm::m_txOpportunityForRetxAlwaysBigEnough),
109 MakeBooleanChecker())
110 .AddAttribute(
"MaxTxBufferSize",
111 "Maximum Size of the Transmission Buffer (in Bytes). If zero is "
112 "configured, the buffer is unlimited.",
113 UintegerValue(10 * 1024),
114 MakeUintegerAccessor(&NrRlcAm::m_maxTxBufferSize),
115 MakeUintegerChecker<uint32_t>());
122 NS_LOG_FUNCTION(
this);
123 m_pollRetransmitTimer.Cancel();
124 m_reorderingTimer.Cancel();
125 m_statusProhibitTimer.Cancel();
128 m_maxTxBufferSize = 0;
129 m_txonBuffer.clear();
130 m_txonBufferSize = 0;
131 m_txedBuffer.clear();
132 m_txedBufferSize = 0;
133 m_retxBuffer.clear();
134 m_retxBufferSize = 0;
135 m_rxonBuffer.clear();
136 m_sdusBuffer.clear();
138 m_controlPduBuffer =
nullptr;
150 NS_LOG_FUNCTION(
this <<
m_rnti << (uint32_t)
m_lcid << p->GetSize());
152 if (m_txonBufferSize + p->GetSize() <= m_maxTxBufferSize || (m_maxTxBufferSize == 0))
156 tag.
SetStatus(NrRlcSduStatusTag::FULL_SDU);
157 p->AddPacketTag(tag);
159 NS_LOG_LOGIC(
"Txon Buffer: New packet added");
160 m_txonBuffer.emplace_back(p, Simulator::Now());
161 m_txonBufferSize += p->GetSize();
162 NS_LOG_LOGIC(
"NumOfBuffers = " << m_txonBuffer.size());
163 NS_LOG_LOGIC(
"txonBufferSize = " << m_txonBufferSize);
168 NS_LOG_LOGIC(
"TxonBuffer is full. RLC SDU discarded");
169 NS_LOG_LOGIC(
"MaxTxBufferSize = " << m_maxTxBufferSize);
170 NS_LOG_LOGIC(
"txonBufferSize = " << m_txonBufferSize);
171 NS_LOG_LOGIC(
"packet size = " << p->GetSize());
176 DoTransmitBufferStatusReport();
178 m_bsrTimer = Simulator::Schedule(m_bsrTimerValue, &NrRlcAm::ExpireBsrTimer,
this);
190 if (txOpParams.
bytes < 4)
194 NS_LOG_LOGIC(
"TxOpportunity (size = " << txOpParams.
bytes <<
") too small");
196 "TxOpportunity (size = "
197 << txOpParams.
bytes <<
") too small.\n"
198 <<
"Your MAC scheduler is assigned too few resource blocks.");
202 if (m_statusPduRequested && !m_statusProhibitTimer.IsPending())
204 if (txOpParams.
bytes < m_statusPduBufferSize)
207 NS_LOG_LOGIC(
"TxOpportunity (size = " << txOpParams.
bytes
208 <<
") too small for the STATUS PDU (size = "
209 << m_statusPduBufferSize <<
")");
211 "TxOpportunity (size = "
212 << txOpParams.
bytes <<
") too small for the STATUS PDU (size = "
213 << m_statusPduBufferSize <<
")\n"
214 <<
"Your MAC scheduler is assigned too few resource blocks.");
218 NS_LOG_LOGIC(
"Sending STATUS PDU");
220 Ptr<Packet> packet = Create<Packet>();
224 NS_LOG_LOGIC(
"Check for SNs to NACK from " << m_vrR.
GetValue() <<
" to "
228 for (sn = m_vrR; sn < m_vrMs; sn++)
230 NS_LOG_LOGIC(
"SN = " << sn);
233 NS_LOG_LOGIC(
"Can't fit more NACKs in STATUS PDU");
236 auto pduIt = m_rxonBuffer.find(sn.
GetValue());
237 if (pduIt == m_rxonBuffer.end() || (!(pduIt->second.m_pduComplete)))
239 NS_LOG_LOGIC(
"adding NACK_SN " << sn.
GetValue());
243 NS_LOG_LOGIC(
"SN at end of NACK loop = " << sn);
247 auto pduIt = m_rxonBuffer.find(sn.
GetValue());
248 while ((sn < m_vrMs) && (pduIt != m_rxonBuffer.end()) && (pduIt->second.m_pduComplete))
250 NS_LOG_LOGIC(
"SN = " << sn <<
" < " << m_vrMs <<
" = " << (sn < m_vrMs));
252 NS_LOG_LOGIC(
"SN = " << sn);
253 pduIt = m_rxonBuffer.find(sn.
GetValue());
256 NS_ASSERT_MSG(sn <= m_vrMs,
257 "first SN not reported as missing = " << sn <<
", VR(MS) = " << m_vrMs);
260 NS_LOG_LOGIC(
"RLC header: " << rlcAmHeader);
261 packet->AddHeader(rlcAmHeader);
265 packet->AddByteTag(rlcTag, 1, rlcAmHeader.GetSerializedSize());
279 m_statusPduRequested =
false;
280 m_statusPduBufferSize = 0;
281 m_statusProhibitTimer = Simulator::Schedule(m_statusProhibitTimerValue,
282 &NrRlcAm::ExpireStatusProhibitTimer,
286 else if (m_retxBufferSize > 0)
288 NS_LOG_LOGIC(
"retxBufferSize = " << m_retxBufferSize);
289 NS_LOG_LOGIC(
"Sending data from Retransmission Buffer");
290 NS_ASSERT(m_vtA < m_vtS);
293 for (sn = m_vtA; sn < m_vtS; sn++)
295 uint16_t seqNumberValue = sn.
GetValue();
296 NS_LOG_LOGIC(
"SN = " << seqNumberValue <<
" m_pdu "
297 << m_retxBuffer.at(seqNumberValue).m_pdu);
299 if (m_retxBuffer.at(seqNumberValue).m_pdu)
301 Ptr<Packet> packet = m_retxBuffer.at(seqNumberValue).m_pdu->Copy();
303 if ((packet->GetSize() <= txOpParams.
bytes) ||
304 m_txOpportunityForRetxAlwaysBigEnough)
308 packet->RemoveHeader(rlcAmHeader);
309 NS_LOG_LOGIC(
"old AM RLC header: " << rlcAmHeader);
312 rlcAmHeader.
SetPollingBit(NrRlcAmHeader::STATUS_REPORT_NOT_REQUESTED);
314 NS_LOG_LOGIC(
"polling conditions: m_txonBuffer.empty="
315 << m_txonBuffer.empty() <<
" retxBufferSize=" << m_retxBufferSize
316 <<
" packet->GetSize ()=" << packet->GetSize());
317 if (((m_txonBuffer.empty()) &&
319 packet->GetSize() + rlcAmHeader.GetSerializedSize())) ||
320 (m_vtS >= m_vtMs) || m_pollRetransmitTimerJustExpired)
322 m_pollRetransmitTimerJustExpired =
false;
323 rlcAmHeader.
SetPollingBit(NrRlcAmHeader::STATUS_REPORT_IS_REQUESTED);
324 m_pduWithoutPoll = 0;
325 m_byteWithoutPoll = 0;
327 m_pollSn = m_vtS - 1;
328 NS_LOG_LOGIC(
"New POLL_SN = " << m_pollSn);
330 if (!m_pollRetransmitTimer.IsPending())
332 NS_LOG_LOGIC(
"Start PollRetransmit timer");
334 m_pollRetransmitTimer =
335 Simulator::Schedule(m_pollRetransmitTimerValue,
336 &NrRlcAm::ExpirePollRetransmitTimer,
341 NS_LOG_LOGIC(
"Restart PollRetransmit timer");
343 m_pollRetransmitTimer.Cancel();
344 m_pollRetransmitTimer =
345 Simulator::Schedule(m_pollRetransmitTimerValue,
346 &NrRlcAm::ExpirePollRetransmitTimer,
351 packet->AddHeader(rlcAmHeader);
356 packet->AddByteTag(rlcTag, 1, rlcAmHeader.GetSerializedSize());
358 NS_LOG_LOGIC(
"new AM RLC header: " << rlcAmHeader);
373 m_retxBuffer.at(seqNumberValue).m_retxCount++;
374 m_retxBuffer.at(seqNumberValue).m_waitingSince = Simulator::Now();
375 NS_LOG_INFO(
"Incr RETX_COUNT for SN = " << seqNumberValue);
376 if (m_retxBuffer.at(seqNumberValue).m_retxCount >= m_maxRetxThreshold)
378 NS_LOG_INFO(
"Max RETX_COUNT for SN = " << seqNumberValue);
381 NS_LOG_INFO(
"Move SN = " << seqNumberValue <<
" back to txedBuffer");
382 m_txedBuffer.at(seqNumberValue).m_pdu =
383 m_retxBuffer.at(seqNumberValue).m_pdu->Copy();
384 m_txedBuffer.at(seqNumberValue).m_retxCount =
385 m_retxBuffer.at(seqNumberValue).m_retxCount;
386 m_txedBuffer.at(seqNumberValue).m_waitingSince =
387 m_retxBuffer.at(seqNumberValue).m_waitingSince;
388 m_txedBufferSize += m_txedBuffer.at(seqNumberValue).m_pdu->GetSize();
390 m_retxBufferSize -= m_retxBuffer.at(seqNumberValue).m_pdu->GetSize();
391 m_retxBuffer.at(seqNumberValue).m_pdu =
nullptr;
392 m_retxBuffer.at(seqNumberValue).m_retxCount = 0;
393 m_retxBuffer.at(seqNumberValue).m_waitingSince = MilliSeconds(0);
395 NS_LOG_LOGIC(
"retxBufferSize = " << m_retxBufferSize);
401 NS_LOG_LOGIC(
"TxOpportunity (size = "
403 <<
") too small for retransmission of the packet (size = "
404 << packet->GetSize() <<
")");
405 NS_LOG_LOGIC(
"Waiting for bigger TxOpportunity");
410 NS_ASSERT_MSG(
false,
"m_retxBufferSize > 0, but no PDU considered for retx found");
412 else if (m_txonBufferSize > 0)
414 if (txOpParams.
bytes < 7)
417 NS_LOG_LOGIC(
"TxOpportunity (size = " << txOpParams.
bytes
418 <<
") too small for DATA PDU");
420 "TxOpportunity (size = "
421 << txOpParams.
bytes <<
") too small for DATA PDU\n"
422 <<
"Your MAC scheduler is assigned too few resource blocks.");
426 NS_ASSERT(m_vtS <= m_vtMs);
429 NS_LOG_INFO(
"cannot transmit new RLC PDU due to window stalling");
433 NS_LOG_LOGIC(
"Sending data from Transmission Buffer");
437 NS_LOG_LOGIC(
"No data pending");
447 Ptr<Packet> packet = Create<Packet>();
452 uint32_t nextSegmentSize = txOpParams.
bytes - 4;
453 uint32_t nextSegmentId = 1;
454 uint32_t dataFieldAddedSize = 0;
455 std::vector<Ptr<Packet>> dataField;
459 if (m_txonBuffer.empty())
461 NS_LOG_LOGIC(
"No data pending");
465 NS_LOG_LOGIC(
"SDUs in TxonBuffer = " << m_txonBuffer.size());
466 NS_LOG_LOGIC(
"First SDU buffer = " << m_txonBuffer.begin()->m_pdu);
467 NS_LOG_LOGIC(
"First SDU size = " << m_txonBuffer.begin()->m_pdu->GetSize());
468 NS_LOG_LOGIC(
"Next segment size = " << nextSegmentSize);
469 NS_LOG_LOGIC(
"Remove SDU from TxBuffer");
470 Time firstSegmentTime = m_txonBuffer.begin()->m_waitingSince;
471 Ptr<Packet> firstSegment = m_txonBuffer.begin()->m_pdu->Copy();
472 m_txonBufferSize -= m_txonBuffer.begin()->m_pdu->GetSize();
473 NS_LOG_LOGIC(
"txBufferSize = " << m_txonBufferSize);
474 m_txonBuffer.erase(m_txonBuffer.begin());
476 while (firstSegment && (firstSegment->GetSize() > 0) && (nextSegmentSize > 0))
478 NS_LOG_LOGIC(
"WHILE ( firstSegment && firstSegment->GetSize > 0 && nextSegmentSize > 0 )");
479 NS_LOG_LOGIC(
" firstSegment size = " << firstSegment->GetSize());
480 NS_LOG_LOGIC(
" nextSegmentSize = " << nextSegmentSize);
481 if ((firstSegment->GetSize() > nextSegmentSize) ||
483 (firstSegment->GetSize() > 2047))
487 uint32_t currSegmentSize = std::min(firstSegment->GetSize(), nextSegmentSize);
489 NS_LOG_LOGIC(
" IF ( firstSegment > nextSegmentSize ||");
490 NS_LOG_LOGIC(
" firstSegment > 2047 )");
494 Ptr<Packet> newSegment = firstSegment->CreateFragment(0, currSegmentSize);
495 NS_LOG_LOGIC(
" newSegment size = " << newSegment->GetSize());
502 firstSegment->RemovePacketTag(oldTag);
503 newSegment->RemovePacketTag(newTag);
504 if (oldTag.
GetStatus() == NrRlcSduStatusTag::FULL_SDU)
506 newTag.
SetStatus(NrRlcSduStatusTag::FIRST_SEGMENT);
507 oldTag.
SetStatus(NrRlcSduStatusTag::LAST_SEGMENT);
509 else if (oldTag.
GetStatus() == NrRlcSduStatusTag::LAST_SEGMENT)
511 newTag.
SetStatus(NrRlcSduStatusTag::MIDDLE_SEGMENT);
516 firstSegment->RemoveAtStart(currSegmentSize);
518 " firstSegment size (after RemoveAtStart) = " << firstSegment->GetSize());
519 if (firstSegment->GetSize() > 0)
521 firstSegment->AddPacketTag(oldTag);
523 m_txonBuffer.insert(m_txonBuffer.begin(), TxPdu(firstSegment, firstSegmentTime));
524 m_txonBufferSize += m_txonBuffer.begin()->m_pdu->GetSize();
526 NS_LOG_LOGIC(
" Txon buffer: Give back the remaining segment");
527 NS_LOG_LOGIC(
" Txon buffers = " << m_txonBuffer.size());
528 NS_LOG_LOGIC(
" Front buffer size = " << m_txonBuffer.begin()->m_pdu->GetSize());
529 NS_LOG_LOGIC(
" txonBufferSize = " << m_txonBufferSize);
534 if (newTag.
GetStatus() == NrRlcSduStatusTag::FIRST_SEGMENT)
536 newTag.
SetStatus(NrRlcSduStatusTag::FULL_SDU);
538 else if (newTag.
GetStatus() == NrRlcSduStatusTag::MIDDLE_SEGMENT)
540 newTag.
SetStatus(NrRlcSduStatusTag::LAST_SEGMENT);
545 firstSegment =
nullptr;
548 newSegment->AddPacketTag(newTag);
551 dataFieldAddedSize = newSegment->GetSize();
552 dataField.push_back(newSegment);
553 newSegment =
nullptr;
560 nextSegmentSize -= dataFieldAddedSize;
568 else if ((nextSegmentSize - firstSegment->GetSize() <= 2) || m_txonBuffer.empty())
571 " IF nextSegmentSize - firstSegment->GetSize () <= 2 || txonBuffer.size == 0");
574 dataFieldAddedSize = firstSegment->GetSize();
575 dataField.push_back(firstSegment);
576 firstSegment =
nullptr;
583 nextSegmentSize -= dataFieldAddedSize;
586 NS_LOG_LOGIC(
" SDUs in TxBuffer = " << m_txonBuffer.size());
587 if (!m_txonBuffer.empty())
589 NS_LOG_LOGIC(
" First SDU buffer = " << m_txonBuffer.begin()->m_pdu);
591 " First SDU size = " << m_txonBuffer.begin()->m_pdu->GetSize());
593 NS_LOG_LOGIC(
" Next segment size = " << nextSegmentSize);
602 NS_LOG_LOGIC(
" IF firstSegment < NextSegmentSize && txonBuffer.size > 0");
604 dataFieldAddedSize = firstSegment->GetSize();
605 dataField.push_back(firstSegment);
613 nextSegmentSize -= ((nextSegmentId % 2) ? (2) : (1)) + dataFieldAddedSize;
616 NS_LOG_LOGIC(
" SDUs in TxBuffer = " << m_txonBuffer.size());
617 if (!m_txonBuffer.empty())
619 NS_LOG_LOGIC(
" First SDU buffer = " << m_txonBuffer.begin()->m_pdu);
621 " First SDU size = " << m_txonBuffer.begin()->m_pdu->GetSize());
623 NS_LOG_LOGIC(
" Next segment size = " << nextSegmentSize);
624 NS_LOG_LOGIC(
" Remove SDU from TxBuffer");
627 firstSegment = m_txonBuffer.begin()->m_pdu->Copy();
628 firstSegmentTime = m_txonBuffer.begin()->m_waitingSince;
629 m_txonBufferSize -= m_txonBuffer.begin()->m_pdu->GetSize();
630 m_txonBuffer.erase(m_txonBuffer.begin());
631 NS_LOG_LOGIC(
" txBufferSize = " << m_txonBufferSize);
648 uint8_t framingInfo = 0;
649 auto it = dataField.begin();
653 NS_ASSERT_MSG((*it)->PeekPacketTag(tag),
"NrRlcSduStatusTag is missing");
654 (*it)->PeekPacketTag(tag);
655 if ((tag.
GetStatus() == NrRlcSduStatusTag::FULL_SDU) ||
656 (tag.
GetStatus() == NrRlcSduStatusTag::FIRST_SEGMENT))
658 framingInfo |= NrRlcAmHeader::FIRST_BYTE;
662 framingInfo |= NrRlcAmHeader::NO_FIRST_BYTE;
666 while (it < dataField.end())
668 NS_LOG_LOGIC(
"Adding SDU/segment to packet, length = " << (*it)->GetSize());
670 NS_ASSERT_MSG((*it)->PeekPacketTag(tag),
"NrRlcSduStatusTag is missing");
671 (*it)->RemovePacketTag(tag);
672 if (packet->GetSize() > 0)
674 packet->AddAtEnd(*it);
685 if ((tag.
GetStatus() == NrRlcSduStatusTag::FULL_SDU) ||
686 (tag.
GetStatus() == NrRlcSduStatusTag::LAST_SEGMENT))
688 framingInfo |= NrRlcAmHeader::LAST_BYTE;
692 framingInfo |= NrRlcAmHeader::NO_LAST_BYTE;
699 rlcAmHeader.
SetPollingBit(NrRlcAmHeader::STATUS_REPORT_NOT_REQUESTED);
702 NS_LOG_LOGIC(
"PDU_WITHOUT_POLL = " << m_pduWithoutPoll);
703 m_byteWithoutPoll += packet->GetSize();
704 NS_LOG_LOGIC(
"BYTE_WITHOUT_POLL = " << m_byteWithoutPoll);
706 if ((m_pduWithoutPoll >= m_pollPdu) || (m_byteWithoutPoll >= m_pollByte) ||
707 ((m_txonBuffer.empty()) && (m_retxBufferSize == 0)) || (m_vtS >= m_vtMs) ||
708 m_pollRetransmitTimerJustExpired)
710 m_pollRetransmitTimerJustExpired =
false;
711 rlcAmHeader.
SetPollingBit(NrRlcAmHeader::STATUS_REPORT_IS_REQUESTED);
712 m_pduWithoutPoll = 0;
713 m_byteWithoutPoll = 0;
715 m_pollSn = m_vtS - 1;
716 NS_LOG_LOGIC(
"New POLL_SN = " << m_pollSn);
718 if (!m_pollRetransmitTimer.IsPending())
720 NS_LOG_LOGIC(
"Start PollRetransmit timer");
722 m_pollRetransmitTimer = Simulator::Schedule(m_pollRetransmitTimerValue,
723 &NrRlcAm::ExpirePollRetransmitTimer,
728 NS_LOG_LOGIC(
"Restart PollRetransmit timer");
730 m_pollRetransmitTimer.Cancel();
731 m_pollRetransmitTimer = Simulator::Schedule(m_pollRetransmitTimerValue,
732 &NrRlcAm::ExpirePollRetransmitTimer,
738 NS_LOG_LOGIC(
"AM RLC header: " << rlcAmHeader);
743 packet->AddHeader(rlcAmHeader);
744 packet->AddByteTag(rlcTag, 1, rlcAmHeader.GetSerializedSize());
747 NS_LOG_LOGIC(
"Put transmitted PDU in the txedBuffer");
748 m_txedBufferSize += packet->GetSize();
770 NS_LOG_FUNCTION(
this);
776 NS_LOG_FUNCTION(
this <<
m_rnti << (uint32_t)
m_lcid << rxPduParams.
p->GetSize());
780 rxPduParams.
p->PeekHeader(rlcAmHeader);
781 NS_LOG_LOGIC(
"RLC header: " << rlcAmHeader);
787 bool ret = rxPduParams.
p->FindFirstMatchingByteTag(rlcTag);
788 NS_ASSERT_MSG(ret,
"NrRlcTag not found in RLC Header. The packet went into a real network?");
856 NS_LOG_LOGIC(
"PDU segment received ( SN = " << seqNumber <<
" )");
860 NS_LOG_LOGIC(
"PDU received ( SN = " << seqNumber <<
" )");
864 NS_ASSERT_MSG(
false,
"Neither a PDU segment nor a PDU received");
869 if (rlcAmHeader.
GetPollingBit() == NrRlcAmHeader::STATUS_REPORT_IS_REQUESTED)
871 m_statusPduRequested =
true;
872 m_statusPduBufferSize = 4;
874 if (!m_statusProhibitTimer.IsPending())
876 DoTransmitBufferStatusReport();
894 NS_LOG_LOGIC(
"VR(R) = " << m_vrR);
895 NS_LOG_LOGIC(
"VR(MR) = " << m_vrMr);
896 NS_LOG_LOGIC(
"VR(X) = " << m_vrX);
897 NS_LOG_LOGIC(
"VR(MS) = " << m_vrMs);
898 NS_LOG_LOGIC(
"VR(H) = " << m_vrH);
902 if (!IsInsideReceivingWindow(seqNumber))
904 NS_LOG_LOGIC(
"PDU discarded");
914 auto it = m_rxonBuffer.find(seqNumber.
GetValue());
915 if (it != m_rxonBuffer.end())
917 NS_ASSERT(!it->second.m_byteSegments.empty());
918 NS_ASSERT_MSG(it->second.m_byteSegments.size() == 1,
919 "re-segmentation not supported");
920 NS_LOG_LOGIC(
"PDU segment already received, discarded");
924 NS_LOG_LOGIC(
"Place PDU in the reception buffer ( SN = " << seqNumber <<
" )");
925 m_rxonBuffer[seqNumber.
GetValue()].m_byteSegments.push_back(rxPduParams.
p);
926 m_rxonBuffer[seqNumber.
GetValue()].m_pduComplete =
true;
937 if (seqNumber >= m_vrH)
939 m_vrH = seqNumber + 1;
940 NS_LOG_LOGIC(
"New VR(H) = " << m_vrH);
947 auto it = m_rxonBuffer.find(m_vrMs.
GetValue());
948 if (it != m_rxonBuffer.end() && it->second.m_pduComplete)
951 while (it != m_rxonBuffer.end() && it->second.m_pduComplete)
954 it = m_rxonBuffer.find(m_vrMs.
GetValue());
955 NS_LOG_LOGIC(
"Incr VR(MS) = " << m_vrMs);
957 NS_ASSERT_MSG(firstVrMs != m_vrMs.
GetValue(),
"Infinite loop in RxonBuffer");
959 NS_LOG_LOGIC(
"New VR(MS) = " << m_vrMs);
972 if (seqNumber == m_vrR)
974 auto it = m_rxonBuffer.find(seqNumber.
GetValue());
975 if (it != m_rxonBuffer.end() && it->second.m_pduComplete)
977 it = m_rxonBuffer.find(m_vrR.
GetValue());
979 while (it != m_rxonBuffer.end() && it->second.m_pduComplete)
981 NS_LOG_LOGIC(
"Reassemble and Deliver ( SN = " << m_vrR <<
" )");
982 NS_ASSERT_MSG(it->second.m_byteSegments.size() == 1,
983 "Too many segments. PDU Reassembly process didn't work");
984 ReassembleAndDeliver(it->second.m_byteSegments.front());
985 m_rxonBuffer.erase(m_vrR.
GetValue());
992 it = m_rxonBuffer.find(m_vrR.
GetValue());
994 NS_ASSERT_MSG(firstVrR != m_vrR.
GetValue(),
"Infinite loop in RxonBuffer");
996 NS_LOG_LOGIC(
"New VR(R) = " << m_vrR);
997 m_vrMr = m_vrR + m_windowSize;
999 NS_LOG_LOGIC(
"New VR(MR) = " << m_vrMr);
1008 if (m_reorderingTimer.IsPending())
1010 NS_LOG_LOGIC(
"Reordering timer is running");
1011 if ((m_vrX == m_vrR) || ((!IsInsideReceivingWindow(m_vrX)) && (m_vrX != m_vrMr)))
1014 NS_LOG_LOGIC(
"Stop reordering timer");
1015 m_reorderingTimer.Cancel();
1025 if (!m_reorderingTimer.IsPending())
1027 NS_LOG_LOGIC(
"Reordering timer is not running");
1030 NS_LOG_LOGIC(
"Start reordering timer");
1031 m_reorderingTimer = Simulator::Schedule(m_reorderingTimerValue,
1032 &NrRlcAm::ExpireReorderingTimer,
1035 NS_LOG_LOGIC(
"New VR(X) = " << m_vrX);
1041 NS_LOG_INFO(
"Control AM RLC PDU");
1046 NS_LOG_INFO(
"ackSn = " << ackSn);
1047 NS_LOG_INFO(
"VT(A) = " << m_vtA);
1048 NS_LOG_INFO(
"VT(S) = " << m_vtS);
1049 NS_LOG_LOGIC(
"retxBufferSize = " << m_retxBufferSize);
1050 NS_LOG_LOGIC(
"txedBufferSize = " << m_txedBufferSize);
1058 bool incrementVtA =
true;
1060 for (sn = m_vtA; sn < ackSn && sn < m_vtS; sn++)
1062 NS_LOG_LOGIC(
"sn = " << sn);
1064 uint16_t seqNumberValue = sn.
GetValue();
1066 if (m_pollRetransmitTimer.IsPending() && (seqNumberValue == m_pollSn.
GetValue()))
1068 m_pollRetransmitTimer.Cancel();
1073 NS_LOG_LOGIC(
"sn " << sn <<
" is NACKed");
1075 incrementVtA =
false;
1077 if (m_txedBuffer.at(seqNumberValue).m_pdu)
1079 NS_LOG_INFO(
"Move SN = " << seqNumberValue <<
" to retxBuffer");
1080 m_retxBuffer.at(seqNumberValue).m_pdu =
1081 m_txedBuffer.at(seqNumberValue).m_pdu->Copy();
1082 m_retxBuffer.at(seqNumberValue).m_retxCount =
1083 m_txedBuffer.at(seqNumberValue).m_retxCount;
1084 m_retxBuffer.at(seqNumberValue).m_waitingSince =
1085 m_txedBuffer.at(seqNumberValue).m_waitingSince;
1086 m_retxBufferSize += m_retxBuffer.at(seqNumberValue).m_pdu->GetSize();
1088 m_txedBufferSize -= m_txedBuffer.at(seqNumberValue).m_pdu->GetSize();
1089 m_txedBuffer.at(seqNumberValue).m_pdu =
nullptr;
1090 m_txedBuffer.at(seqNumberValue).m_retxCount = 0;
1091 m_txedBuffer.at(seqNumberValue).m_waitingSince = MilliSeconds(0);
1094 NS_ASSERT(m_retxBuffer.at(seqNumberValue).m_pdu);
1098 NS_LOG_LOGIC(
"sn " << sn <<
" is ACKed");
1100 if (m_txedBuffer.at(seqNumberValue).m_pdu)
1102 NS_LOG_INFO(
"ACKed SN = " << seqNumberValue <<
" from txedBuffer");
1105 m_txedBufferSize -= m_txedBuffer.at(seqNumberValue).m_pdu->GetSize();
1106 m_txedBuffer.at(seqNumberValue).m_pdu =
nullptr;
1107 m_txedBuffer.at(seqNumberValue).m_waitingSince = MilliSeconds(0);
1108 NS_ASSERT(!m_retxBuffer.at(seqNumberValue).m_pdu);
1111 if (m_retxBuffer.at(seqNumberValue).m_pdu)
1113 NS_LOG_INFO(
"ACKed SN = " << seqNumberValue <<
" from retxBuffer");
1114 m_retxBufferSize -= m_retxBuffer.at(seqNumberValue).m_pdu->GetSize();
1115 m_retxBuffer.at(seqNumberValue).m_pdu =
nullptr;
1116 m_retxBuffer.at(seqNumberValue).m_retxCount = 0;
1117 m_retxBuffer.at(seqNumberValue).m_waitingSince = MilliSeconds(0);
1121 NS_LOG_LOGIC(
"retxBufferSize = " << m_retxBufferSize);
1122 NS_LOG_LOGIC(
"txedBufferSize = " << m_txedBufferSize);
1127 m_vtMs = m_vtA + m_windowSize;
1128 NS_LOG_INFO(
"New VT(A) = " << m_vtA);
1131 m_vtS.SetModulusBase(m_vtA);
1142 NS_LOG_WARN(
"Wrong AM RLC PDU type");
1150 NS_LOG_FUNCTION(
this << seqNumber);
1151 NS_LOG_LOGIC(
"Receiving Window: " << m_vrR <<
" <= " << seqNumber <<
" <= " << m_vrMr);
1157 if ((m_vrR <= seqNumber) && (seqNumber < m_vrMr))
1159 NS_LOG_LOGIC(seqNumber <<
" is INSIDE the receiving window");
1164 NS_LOG_LOGIC(seqNumber <<
" is OUTSIDE the receiving window");
1170NrRlcAm::ReassembleAndDeliver(Ptr<Packet> packet)
1172 NrRlcAmHeader rlcAmHeader;
1174 bool ret = packet->FindFirstMatchingByteTag(rlcTag);
1176 packet->RemoveHeader(rlcAmHeader);
1177 ret = packet->FindFirstMatchingByteTag(rlcTag);
1179 uint8_t framingInfo = rlcAmHeader.GetFramingInfo();
1180 nr::SequenceNumber10 currSeqNumber = rlcAmHeader.GetSequenceNumber();
1181 bool expectedSnLost;
1183 if (currSeqNumber != m_expectedSeqNumber)
1185 expectedSnLost =
true;
1186 NS_LOG_LOGIC(
"There are losses. Expected SN = " << m_expectedSeqNumber
1187 <<
". Current SN = " << currSeqNumber);
1188 m_expectedSeqNumber = currSeqNumber + 1;
1192 expectedSnLost =
false;
1193 NS_LOG_LOGIC(
"No losses. Expected SN = " << m_expectedSeqNumber
1194 <<
". Current SN = " << currSeqNumber);
1195 m_expectedSeqNumber = m_expectedSeqNumber + 1;
1199 uint8_t extensionBit;
1200 uint16_t lengthIndicator;
1203 extensionBit = rlcAmHeader.PopExtensionBit();
1204 NS_LOG_LOGIC(
"E = " << (uint16_t)extensionBit);
1206 if (extensionBit == 0)
1208 m_sdusBuffer.push_back(packet);
1212 lengthIndicator = rlcAmHeader.PopLengthIndicator();
1213 NS_LOG_LOGIC(
"LI = " << lengthIndicator);
1216 if (lengthIndicator >= packet->GetSize())
1218 NS_LOG_LOGIC(
"INTERNAL ERROR: Not enough data in the packet ("
1219 << packet->GetSize() <<
"). Needed LI=" << lengthIndicator);
1224 Ptr<Packet> data_field = packet->CreateFragment(0, lengthIndicator);
1225 packet->RemoveAtStart(lengthIndicator);
1227 m_sdusBuffer.push_back(data_field);
1229 }
while (extensionBit == 1);
1232 if (m_reassemblingState == WAITING_S0_FULL)
1234 NS_LOG_LOGIC(
"Reassembling State = 'WAITING_S0_FULL'");
1236 else if (m_reassemblingState == WAITING_SI_SF)
1238 NS_LOG_LOGIC(
"Reassembling State = 'WAITING_SI_SF'");
1242 NS_LOG_LOGIC(
"Reassembling State = Unknown state");
1246 NS_LOG_LOGIC(
"Framing Info = " << (uint16_t)framingInfo);
1247 NS_LOG_LOGIC(
"m_sdusBuffer = " << m_sdusBuffer.size());
1250 if (!expectedSnLost)
1252 switch (m_reassemblingState)
1254 case WAITING_S0_FULL:
1255 switch (framingInfo)
1257 case (NrRlcAmHeader::FIRST_BYTE | NrRlcAmHeader::LAST_BYTE):
1258 m_reassemblingState = WAITING_S0_FULL;
1263 for (
auto it = m_sdusBuffer.begin(); it != m_sdusBuffer.end(); it++)
1267 m_sdusBuffer.clear();
1270 case (NrRlcAmHeader::FIRST_BYTE | NrRlcAmHeader::NO_LAST_BYTE):
1271 m_reassemblingState = WAITING_SI_SF;
1276 while (m_sdusBuffer.size() > 1)
1279 m_sdusBuffer.pop_front();
1285 m_keepS0 = m_sdusBuffer.front();
1286 m_sdusBuffer.pop_front();
1289 case (NrRlcAmHeader::NO_FIRST_BYTE | NrRlcAmHeader::LAST_BYTE):
1290 case (NrRlcAmHeader::NO_FIRST_BYTE | NrRlcAmHeader::NO_LAST_BYTE):
1296 "INTERNAL ERROR: Transition not possible. FI = " << (uint32_t)framingInfo);
1302 switch (framingInfo)
1304 case (NrRlcAmHeader::NO_FIRST_BYTE | NrRlcAmHeader::LAST_BYTE):
1305 m_reassemblingState = WAITING_S0_FULL;
1310 m_keepS0->AddAtEnd(m_sdusBuffer.front());
1311 m_sdusBuffer.pop_front();
1317 while (!m_sdusBuffer.empty())
1320 m_sdusBuffer.pop_front();
1324 case (NrRlcAmHeader::NO_FIRST_BYTE | NrRlcAmHeader::NO_LAST_BYTE):
1325 m_reassemblingState = WAITING_SI_SF;
1330 if (m_sdusBuffer.size() == 1)
1332 m_keepS0->AddAtEnd(m_sdusBuffer.front());
1333 m_sdusBuffer.pop_front();
1340 m_keepS0->AddAtEnd(m_sdusBuffer.front());
1341 m_sdusBuffer.pop_front();
1347 while (m_sdusBuffer.size() > 1)
1350 m_sdusBuffer.pop_front();
1356 m_keepS0 = m_sdusBuffer.front();
1357 m_sdusBuffer.pop_front();
1361 case (NrRlcAmHeader::FIRST_BYTE | NrRlcAmHeader::LAST_BYTE):
1362 case (NrRlcAmHeader::FIRST_BYTE | NrRlcAmHeader::NO_LAST_BYTE):
1368 "INTERNAL ERROR: Transition not possible. FI = " << (uint32_t)framingInfo);
1375 "INTERNAL ERROR: Wrong reassembling state = " << (uint32_t)m_reassemblingState);
1382 switch (m_reassemblingState)
1384 case WAITING_S0_FULL:
1385 switch (framingInfo)
1387 case (NrRlcAmHeader::FIRST_BYTE | NrRlcAmHeader::LAST_BYTE):
1388 m_reassemblingState = WAITING_S0_FULL;
1393 for (
auto it = m_sdusBuffer.begin(); it != m_sdusBuffer.end(); it++)
1397 m_sdusBuffer.clear();
1400 case (NrRlcAmHeader::FIRST_BYTE | NrRlcAmHeader::NO_LAST_BYTE):
1401 m_reassemblingState = WAITING_SI_SF;
1406 while (m_sdusBuffer.size() > 1)
1409 m_sdusBuffer.pop_front();
1415 m_keepS0 = m_sdusBuffer.front();
1416 m_sdusBuffer.pop_front();
1419 case (NrRlcAmHeader::NO_FIRST_BYTE | NrRlcAmHeader::LAST_BYTE):
1420 m_reassemblingState = WAITING_S0_FULL;
1425 m_sdusBuffer.pop_front();
1430 while (!m_sdusBuffer.empty())
1433 m_sdusBuffer.pop_front();
1437 case (NrRlcAmHeader::NO_FIRST_BYTE | NrRlcAmHeader::NO_LAST_BYTE):
1438 if (m_sdusBuffer.size() == 1)
1440 m_reassemblingState = WAITING_S0_FULL;
1444 m_reassemblingState = WAITING_SI_SF;
1450 m_sdusBuffer.pop_front();
1452 if (!m_sdusBuffer.empty())
1457 while (m_sdusBuffer.size() > 1)
1460 m_sdusBuffer.pop_front();
1466 m_keepS0 = m_sdusBuffer.front();
1467 m_sdusBuffer.pop_front();
1476 "INTERNAL ERROR: Transition not possible. FI = " << (uint32_t)framingInfo);
1482 switch (framingInfo)
1484 case (NrRlcAmHeader::FIRST_BYTE | NrRlcAmHeader::LAST_BYTE):
1485 m_reassemblingState = WAITING_S0_FULL;
1495 while (!m_sdusBuffer.empty())
1498 m_sdusBuffer.pop_front();
1502 case (NrRlcAmHeader::FIRST_BYTE | NrRlcAmHeader::NO_LAST_BYTE):
1503 m_reassemblingState = WAITING_SI_SF;
1513 while (m_sdusBuffer.size() > 1)
1516 m_sdusBuffer.pop_front();
1522 m_keepS0 = m_sdusBuffer.front();
1523 m_sdusBuffer.pop_front();
1527 case (NrRlcAmHeader::NO_FIRST_BYTE | NrRlcAmHeader::LAST_BYTE):
1528 m_reassemblingState = WAITING_S0_FULL;
1538 m_sdusBuffer.pop_front();
1543 while (!m_sdusBuffer.empty())
1546 m_sdusBuffer.pop_front();
1550 case (NrRlcAmHeader::NO_FIRST_BYTE | NrRlcAmHeader::NO_LAST_BYTE):
1551 if (m_sdusBuffer.size() == 1)
1553 m_reassemblingState = WAITING_S0_FULL;
1557 m_reassemblingState = WAITING_SI_SF;
1568 m_sdusBuffer.pop_front();
1570 if (!m_sdusBuffer.empty())
1575 while (m_sdusBuffer.size() > 1)
1578 m_sdusBuffer.pop_front();
1584 m_keepS0 = m_sdusBuffer.front();
1585 m_sdusBuffer.pop_front();
1594 "INTERNAL ERROR: Transition not possible. FI = " << (uint32_t)framingInfo);
1601 "INTERNAL ERROR: Wrong reassembling state = " << (uint32_t)m_reassemblingState);
1608NrRlcAm::DoTransmitBufferStatusReport()
1610 NS_LOG_FUNCTION(
this);
1612 Time now = Simulator::Now();
1614 NS_LOG_LOGIC(
"txonBufferSize = " << m_txonBufferSize);
1615 NS_LOG_LOGIC(
"retxBufferSize = " << m_retxBufferSize);
1616 NS_LOG_LOGIC(
"txedBufferSize = " << m_txedBufferSize);
1617 NS_LOG_LOGIC(
"VT(A) = " << m_vtA);
1618 NS_LOG_LOGIC(
"VT(S) = " << m_vtS);
1621 Time txonQueueHolDelay(0);
1622 if (m_txonBufferSize > 0)
1624 txonQueueHolDelay = now - m_txonBuffer.front().m_waitingSince;
1628 Time retxQueueHolDelay;
1629 if (m_retxBufferSize > 0)
1631 Time senderTimestamp;
1632 if (m_retxBuffer.at(m_vtA.
GetValue()).m_pdu)
1634 senderTimestamp = m_retxBuffer.at(m_vtA.
GetValue()).m_waitingSince;
1638 senderTimestamp = m_txedBuffer.at(m_vtA.
GetValue()).m_waitingSince;
1640 retxQueueHolDelay = now - senderTimestamp;
1644 retxQueueHolDelay = Seconds(0);
1647 NrMacSapProvider::BufferStatusReportParameters r;
1650 r.txQueueSize = m_txonBufferSize;
1651 r.txQueueHolDelay = txonQueueHolDelay.GetMilliSeconds();
1652 r.retxQueueSize = m_retxBufferSize + m_txedBufferSize;
1653 r.retxQueueHolDelay = retxQueueHolDelay.GetMilliSeconds();
1655 if (m_statusPduRequested && !m_statusProhibitTimer.IsPending())
1657 r.statusPduSize = m_statusPduBufferSize;
1661 r.statusPduSize = 0;
1664 if (r.txQueueSize != 0 || r.retxQueueSize != 0 || r.statusPduSize != 0)
1666 NS_LOG_INFO(
"Send BufferStatusReport: " << r.txQueueSize <<
", " << r.txQueueHolDelay
1667 <<
", " << r.retxQueueSize <<
", "
1668 << r.retxQueueHolDelay <<
", " << r.statusPduSize);
1673 NS_LOG_INFO(
"BufferStatusReport don't needed");
1678NrRlcAm::ExpireReorderingTimer()
1680 NS_LOG_FUNCTION(
this);
1681 NS_LOG_LOGIC(
"Reordering Timer has expired");
1694 auto it = m_rxonBuffer.find(m_vrMs.
GetValue());
1695 while (it != m_rxonBuffer.end() && it->second.m_pduComplete)
1698 it = m_rxonBuffer.find(m_vrMs.
GetValue());
1700 NS_ASSERT_MSG(firstVrMs != m_vrMs.
GetValue(),
"Infinite loop in ExpireReorderingTimer");
1702 NS_LOG_LOGIC(
"New VR(MS) = " << m_vrMs);
1706 NS_LOG_LOGIC(
"Start reordering timer");
1708 Simulator::Schedule(m_reorderingTimerValue, &NrRlcAm::ExpireReorderingTimer,
this);
1710 NS_LOG_LOGIC(
"New VR(MS) = " << m_vrMs);
1716 m_statusPduRequested =
true;
1720NrRlcAm::ExpirePollRetransmitTimer()
1722 NS_LOG_FUNCTION(
this);
1723 NS_LOG_LOGIC(
"PollRetransmit Timer has expired");
1725 NS_LOG_LOGIC(
"txonBufferSize = " << m_txonBufferSize);
1726 NS_LOG_LOGIC(
"retxBufferSize = " << m_retxBufferSize);
1727 NS_LOG_LOGIC(
"txedBufferSize = " << m_txedBufferSize);
1728 NS_LOG_LOGIC(
"statusPduRequested = " << m_statusPduRequested);
1730 m_pollRetransmitTimerJustExpired =
true;
1734 NS_ASSERT(m_vtS <= m_vtMs);
1735 if ((m_txonBufferSize == 0 && m_retxBufferSize == 0) || (m_vtS == m_vtMs))
1737 NS_LOG_INFO(
"txonBuffer and retxBuffer empty. Move PDUs up to = " << m_vtS.
GetValue() - 1
1738 <<
" to retxBuffer");
1739 for (nr::SequenceNumber10 sn = m_vtA; sn < m_vtS; sn++)
1741 bool pduAvailable = (bool)m_txedBuffer.at(sn.GetValue()).m_pdu;
1745 uint16_t snValue = sn.GetValue();
1746 NS_LOG_INFO(
"Move PDU " << sn <<
" from txedBuffer to retxBuffer");
1747 m_retxBuffer.at(snValue).m_pdu = m_txedBuffer.at(snValue).m_pdu->Copy();
1748 m_retxBuffer.at(snValue).m_retxCount = m_txedBuffer.at(snValue).m_retxCount;
1749 m_retxBuffer.at(snValue).m_waitingSince = m_txedBuffer.at(snValue).m_waitingSince;
1750 m_retxBufferSize += m_retxBuffer.at(snValue).m_pdu->GetSize();
1752 m_txedBufferSize -= m_txedBuffer.at(snValue).m_pdu->GetSize();
1753 m_txedBuffer.at(snValue).m_pdu =
nullptr;
1754 m_txedBuffer.at(snValue).m_retxCount = 0;
1755 m_txedBuffer.at(snValue).m_waitingSince = MilliSeconds(0);
1760 DoTransmitBufferStatusReport();
1764NrRlcAm::ExpireStatusProhibitTimer()
1766 NS_LOG_FUNCTION(
this);
1770NrRlcAm::ExpireBsrTimer()
1772 NS_LOG_LOGIC(
"BSR Timer expires");
1774 if (m_txonBufferSize + m_txedBufferSize + m_retxBufferSize > 0)
1776 DoTransmitBufferStatusReport();
1777 m_bsrTimer = Simulator::Schedule(m_bsrTimerValue, &NrRlcAm::ExpireBsrTimer,
this);
virtual void TransmitPdu(TransmitPduParameters params)=0
virtual void BufferStatusReport(BufferStatusReportParameters params)=0
void DoNotifyHarqDeliveryFailure() override
static TypeId GetTypeId()
Get the type ID.
void DoNotifyTxOpportunity(NrMacSapUser::TxOpportunityParameters txOpParams) override
void DoReceivePdu(NrMacSapUser::ReceivePduParameters rxPduParams) override
void DoTransmitPdcpPdu(Ptr< Packet > p) override
TracedCallback< Ptr< const Packet > > m_txDropTrace
TracedCallback< uint16_t, uint8_t, uint32_t, uint64_t > m_rxPdu
NrRlcSapUser * m_rlcSapUser
RLC SAP user.
NrMacSapProvider * m_macSapProvider
MAC SAP provider.
TracedCallback< uint16_t, uint8_t, uint32_t > m_txPdu
virtual void ReceivePdcpPdu(Ptr< Packet > p)=0
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
void SetSenderTimestamp(Time senderTimestamp)
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