5G-LENA nr-v4.0
The 5G/NR module for the ns-3 simulator
Loading...
Searching...
No Matches
nr-rlc-tm.cc
1// Copyright (c) 2011,2012 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
2//
3// SPDX-License-Identifier: GPL-2.0-only
4//
5// Author: Manuel Requena <manuel.requena@cttc.es>
6// Nicola Baldo <nbaldo@cttc.es>
7
8#include "nr-rlc-tm.h"
9
10#include "ns3/log.h"
11#include "ns3/simulator.h"
12
13namespace ns3
14{
15
16NS_LOG_COMPONENT_DEFINE("NrRlcTm");
17
18NS_OBJECT_ENSURE_REGISTERED(NrRlcTm);
19
20NrRlcTm::NrRlcTm()
21 : m_maxTxBufferSize(0),
22 m_txBufferSize(0)
23{
24 NS_LOG_FUNCTION(this);
25}
26
27NrRlcTm::~NrRlcTm()
28{
29 NS_LOG_FUNCTION(this);
30}
31
32TypeId
33NrRlcTm::GetTypeId()
34{
35 static TypeId tid = TypeId("ns3::NrRlcTm")
36 .SetParent<NrRlc>()
37 .SetGroupName("Nr")
38 .AddConstructor<NrRlcTm>()
39 .AddAttribute("MaxTxBufferSize",
40 "Maximum Size of the Transmission Buffer (in Bytes)",
41 UintegerValue(2 * 1024 * 1024),
42 MakeUintegerAccessor(&NrRlcTm::m_maxTxBufferSize),
43 MakeUintegerChecker<uint32_t>());
44 return tid;
45}
46
47void
48NrRlcTm::DoDispose()
49{
50 NS_LOG_FUNCTION(this);
51 m_bsrTimer.Cancel();
52 m_txBuffer.clear();
53
54 NrRlc::DoDispose();
55}
56
61void
62NrRlcTm::DoTransmitPdcpPdu(Ptr<Packet> p)
63{
64 NS_LOG_FUNCTION(this << m_rnti << (uint32_t)m_lcid << p->GetSize());
65
66 if (m_txBufferSize + p->GetSize() <= m_maxTxBufferSize)
67 {
68 NS_LOG_LOGIC("Tx Buffer: New packet added");
69 m_txBuffer.emplace_back(p, Simulator::Now());
70 m_txBufferSize += p->GetSize();
71 NS_LOG_LOGIC("NumOfBuffers = " << m_txBuffer.size());
72 NS_LOG_LOGIC("txBufferSize = " << m_txBufferSize);
73 }
74 else
75 {
76 // Discard full RLC SDU
77 NS_LOG_LOGIC("TxBuffer is full. RLC SDU discarded");
78 NS_LOG_LOGIC("MaxTxBufferSize = " << m_maxTxBufferSize);
79 NS_LOG_LOGIC("txBufferSize = " << m_txBufferSize);
80 NS_LOG_LOGIC("packet size = " << p->GetSize());
81 }
82
84 DoTransmitBufferStatusReport();
85 m_bsrTimer.Cancel();
86}
87
92void
93NrRlcTm::DoNotifyTxOpportunity(NrMacSapUser::TxOpportunityParameters txOpParams)
94{
95 NS_LOG_FUNCTION(this << m_rnti << (uint32_t)m_lcid << txOpParams.bytes
96 << (uint32_t)txOpParams.layer << (uint32_t)txOpParams.harqId);
97
98 // 5.1.1.1 Transmit operations
99 // 5.1.1.1.1 General
100 // When submitting a new TMD PDU to lower layer, the transmitting TM RLC entity shall:
101 // - submit a RLC SDU without any modification to lower layer.
102
103 if (m_txBuffer.empty())
104 {
105 NS_LOG_LOGIC("No data pending");
106 return;
107 }
108
109 Ptr<Packet> packet = m_txBuffer.begin()->m_pdu->Copy();
110
111 if (txOpParams.bytes < packet->GetSize())
112 {
113 NS_LOG_WARN("TX opportunity too small = " << txOpParams.bytes
114 << " (PDU size: " << packet->GetSize() << ")");
115 return;
116 }
117
118 m_txBufferSize -= packet->GetSize();
119 m_txBuffer.erase(m_txBuffer.begin());
120
121 m_txPdu(m_rnti, m_lcid, packet->GetSize());
122
123 // Send RLC PDU to MAC layer
125 params.pdu = packet;
126 params.rnti = m_rnti;
127 params.lcid = m_lcid;
128 params.layer = txOpParams.layer;
129 params.harqProcessId = txOpParams.harqId;
130 params.componentCarrierId = txOpParams.componentCarrierId;
131
132 m_macSapProvider->TransmitPdu(params);
133
134 if (!m_txBuffer.empty())
135 {
136 m_bsrTimer.Cancel();
137 m_bsrTimer = Simulator::Schedule(MilliSeconds(10), &NrRlcTm::ExpireBsrTimer, this);
138 }
139}
140
141void
142NrRlcTm::DoNotifyHarqDeliveryFailure()
143{
144 NS_LOG_FUNCTION(this);
145}
146
147void
148NrRlcTm::DoReceivePdu(NrMacSapUser::ReceivePduParameters rxPduParams)
149{
150 NS_LOG_FUNCTION(this << m_rnti << (uint32_t)m_lcid << rxPduParams.p->GetSize());
151
152 m_rxPdu(m_rnti, m_lcid, rxPduParams.p->GetSize(), 0);
153
154 // 5.1.1.2 Receive operations
155 // 5.1.1.2.1 General
156 // When receiving a new TMD PDU from lower layer, the receiving TM RLC entity shall:
157 // - deliver the TMD PDU without any modification to upper layer.
158
159 m_rlcSapUser->ReceivePdcpPdu(rxPduParams.p);
160}
161
162void
163NrRlcTm::DoTransmitBufferStatusReport()
164{
165 Time holDelay(0);
166 uint32_t queueSize = 0;
167
168 if (!m_txBuffer.empty())
169 {
170 holDelay = Simulator::Now() - m_txBuffer.front().m_waitingSince;
171
172 queueSize = m_txBufferSize; // just data in tx queue (no header overhead for RLC TM)
173 }
174
175 NrMacSapProvider::BufferStatusReportParameters r;
176 r.rnti = m_rnti;
177 r.lcid = m_lcid;
178 r.txQueueSize = queueSize;
179 r.txQueueHolDelay = holDelay.GetMilliSeconds();
180 r.retxQueueSize = 0;
181 r.retxQueueHolDelay = 0;
182 r.statusPduSize = 0;
183
184 NS_LOG_LOGIC("Send BufferStatusReport = " << r.txQueueSize << ", " << r.txQueueHolDelay);
185 m_macSapProvider->BufferStatusReport(r);
186}
187
188void
189NrRlcTm::ExpireBsrTimer()
190{
191 NS_LOG_LOGIC("BSR Timer expires");
192
193 if (!m_txBuffer.empty())
194 {
195 DoTransmitBufferStatusReport();
196 m_bsrTimer = Simulator::Schedule(MilliSeconds(10), &NrRlcTm::ExpireBsrTimer, this);
197 }
198}
199
200} // namespace ns3