5G-LENA nr-v3.3-161-gad18933f
The 5G/NR module for the ns-3 simulator
Loading...
Searching...
No Matches
nr-a2-a4-rsrq-handover-algorithm.cc
1// Copyright (c) 2011 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
2// Copyright (c) 2013 Budiarto Herman
3//
4// SPDX-License-Identifier: GPL-2.0-only
5//
6// Original work authors (from lte-enb-rrc.cc):
7// Nicola Baldo <nbaldo@cttc.es>
8// Marco Miozzo <mmiozzo@cttc.es>
9// Manuel Requena <manuel.requena@cttc.es>
10//
11// Converted to handover algorithm interface by:
12// Budiarto Herman <budiarto.herman@magister.fi>
13
14#include "nr-a2-a4-rsrq-handover-algorithm.h"
15
16#include "ns3/log.h"
17#include "ns3/uinteger.h"
18
19#include <algorithm>
20
21namespace ns3
22{
23
24NS_LOG_COMPONENT_DEFINE("NrA2A4RsrqHandoverAlgorithm");
25
26NS_OBJECT_ENSURE_REGISTERED(NrA2A4RsrqHandoverAlgorithm);
27
29// Handover Management SAP forwarder
31
33 : m_servingCellThreshold(30),
34 m_neighbourCellOffset(1),
35 m_handoverManagementSapUser(nullptr)
36{
37 NS_LOG_FUNCTION(this);
38 m_handoverManagementSapProvider =
40}
41
42NrA2A4RsrqHandoverAlgorithm::~NrA2A4RsrqHandoverAlgorithm()
43{
44 NS_LOG_FUNCTION(this);
45}
46
47TypeId
49{
50 static TypeId tid =
51 TypeId("ns3::NrA2A4RsrqHandoverAlgorithm")
52 .SetParent<NrHandoverAlgorithm>()
53 .SetGroupName("Nr")
54 .AddConstructor<NrA2A4RsrqHandoverAlgorithm>()
55 .AddAttribute(
56 "ServingCellThreshold",
57 "If the RSRQ of the serving cell is worse than this "
58 "threshold, neighbour cells are consider for handover. "
59 "Expressed in quantized range of [0..34] as per Section "
60 "9.1.7 of 3GPP TS 36.133.",
61 UintegerValue(30),
62 MakeUintegerAccessor(&NrA2A4RsrqHandoverAlgorithm::m_servingCellThreshold),
63 MakeUintegerChecker<uint8_t>(0, 34))
64 .AddAttribute("NeighbourCellOffset",
65 "Minimum offset between the serving and the best neighbour "
66 "cell to trigger the handover. Expressed in quantized "
67 "range of [0..34] as per Section 9.1.7 of 3GPP TS 36.133.",
68 UintegerValue(1),
69 MakeUintegerAccessor(&NrA2A4RsrqHandoverAlgorithm::m_neighbourCellOffset),
70 MakeUintegerChecker<uint8_t>());
71 return tid;
72}
73
74void
76{
77 NS_LOG_FUNCTION(this << s);
78 m_handoverManagementSapUser = s;
79}
80
83{
84 NS_LOG_FUNCTION(this);
85 return m_handoverManagementSapProvider;
86}
87
88void
89NrA2A4RsrqHandoverAlgorithm::DoInitialize()
90{
91 NS_LOG_FUNCTION(this);
92
93 NS_LOG_LOGIC(this << " requesting Event A2 measurements"
94 << " (threshold=" << (uint16_t)m_servingCellThreshold << ")");
95 NrRrcSap::ReportConfigEutra reportConfigA2;
98 reportConfigA2.threshold1.range = m_servingCellThreshold;
100 reportConfigA2.reportInterval = NrRrcSap::ReportConfigEutra::MS240;
101 m_a2MeasIds = m_handoverManagementSapUser->AddUeMeasReportConfigForHandover(reportConfigA2);
102
103 NS_LOG_LOGIC(this << " requesting Event A4 measurements"
104 << " (threshold=0)");
105 NrRrcSap::ReportConfigEutra reportConfigA4;
108 reportConfigA4.threshold1.range = 0; // intentionally very low threshold
110 reportConfigA4.reportInterval = NrRrcSap::ReportConfigEutra::MS480;
111 m_a4MeasIds = m_handoverManagementSapUser->AddUeMeasReportConfigForHandover(reportConfigA4);
112
113 NrHandoverAlgorithm::DoInitialize();
114}
115
116void
117NrA2A4RsrqHandoverAlgorithm::DoDispose()
118{
119 NS_LOG_FUNCTION(this);
120 delete m_handoverManagementSapProvider;
121}
122
123void
125{
126 NS_LOG_FUNCTION(this << rnti << (uint16_t)measResults.measId);
127
128 if (std::find(begin(m_a2MeasIds), end(m_a2MeasIds), measResults.measId) !=
129 std::end(m_a2MeasIds))
130 {
131 NS_ASSERT_MSG(measResults.measResultPCell.rsrqResult <= m_servingCellThreshold,
132 "Invalid UE measurement report");
133 EvaluateHandover(rnti, measResults.measResultPCell.rsrqResult);
134 }
135 else if (std::find(begin(m_a4MeasIds), end(m_a4MeasIds), measResults.measId) !=
136 std::end(m_a4MeasIds))
137 {
138 if (measResults.haveMeasResultNeighCells && !measResults.measResultListEutra.empty())
139 {
140 for (auto it = measResults.measResultListEutra.begin();
141 it != measResults.measResultListEutra.end();
142 ++it)
143 {
144 NS_ASSERT_MSG(it->haveRsrqResult == true,
145 "RSRQ measurement is missing from cellId " << it->physCellId);
146 UpdateNeighbourMeasurements(rnti, it->physCellId, it->rsrqResult);
147 }
148 }
149 else
150 {
151 NS_LOG_WARN(
152 this << " Event A4 received without measurement results from neighbouring cells");
153 }
154 }
155 else
156 {
157 NS_LOG_WARN("Ignoring measId " << (uint16_t)measResults.measId);
158 }
159
160} // end of DoReportUeMeas
161
162void
163NrA2A4RsrqHandoverAlgorithm::EvaluateHandover(uint16_t rnti, uint8_t servingCellRsrq)
164{
165 NS_LOG_FUNCTION(this << rnti << (uint16_t)servingCellRsrq);
166
167 auto it1 = m_neighbourCellMeasures.find(rnti);
168
169 if (it1 == m_neighbourCellMeasures.end())
170 {
171 NS_LOG_WARN("Skipping handover evaluation for RNTI "
172 << rnti << " because neighbour cells information is not found");
173 }
174 else
175 {
176 // Find the best neighbour cell (eNB)
177 NS_LOG_LOGIC("Number of neighbour cells = " << it1->second.size());
178 uint16_t bestNeighbourCellId = 0;
179 uint8_t bestNeighbourRsrq = 0;
180 for (auto it2 = it1->second.begin(); it2 != it1->second.end(); ++it2)
181 {
182 if ((it2->second->m_rsrq > bestNeighbourRsrq) && IsValidNeighbour(it2->first))
183 {
184 bestNeighbourCellId = it2->first;
185 bestNeighbourRsrq = it2->second->m_rsrq;
186 }
187 }
188
189 // Trigger Handover, if needed
190 if (bestNeighbourCellId > 0)
191 {
192 NS_LOG_LOGIC("Best neighbour cellId " << bestNeighbourCellId);
193
194 if ((bestNeighbourRsrq - servingCellRsrq) >= m_neighbourCellOffset)
195 {
196 NS_LOG_LOGIC("Trigger Handover to cellId " << bestNeighbourCellId);
197 NS_LOG_LOGIC("target cell RSRQ " << (uint16_t)bestNeighbourRsrq);
198 NS_LOG_LOGIC("serving cell RSRQ " << (uint16_t)servingCellRsrq);
199
200 // Inform eNodeB RRC about handover
201 m_handoverManagementSapUser->TriggerHandover(rnti, bestNeighbourCellId);
202 }
203 }
204
205 } // end of else of if (it1 == m_neighbourCellMeasures.end ())
206
207} // end of EvaluateMeasurementReport
208
209bool
210NrA2A4RsrqHandoverAlgorithm::IsValidNeighbour(uint16_t cellId)
211{
212 NS_LOG_FUNCTION(this << cellId);
213
220 return true;
221}
222
223void
224NrA2A4RsrqHandoverAlgorithm::UpdateNeighbourMeasurements(uint16_t rnti,
225 uint16_t cellId,
226 uint8_t rsrq)
227{
228 NS_LOG_FUNCTION(this << rnti << cellId << (uint16_t)rsrq);
229 auto it1 = m_neighbourCellMeasures.find(rnti);
230
231 if (it1 == m_neighbourCellMeasures.end())
232 {
233 // insert a new UE entry
234 MeasurementRow_t row;
235 auto ret = m_neighbourCellMeasures.insert(std::pair<uint16_t, MeasurementRow_t>(rnti, row));
236 NS_ASSERT(ret.second);
237 it1 = ret.first;
238 }
239
240 NS_ASSERT(it1 != m_neighbourCellMeasures.end());
241 Ptr<UeMeasure> neighbourCellMeasures;
242 auto it2 = it1->second.find(cellId);
243
244 if (it2 != it1->second.end())
245 {
246 neighbourCellMeasures = it2->second;
247 neighbourCellMeasures->m_cellId = cellId;
248 neighbourCellMeasures->m_rsrp = 0;
249 neighbourCellMeasures->m_rsrq = rsrq;
250 }
251 else
252 {
253 // insert a new cell entry
254 neighbourCellMeasures = Create<UeMeasure>();
255 neighbourCellMeasures->m_cellId = cellId;
256 neighbourCellMeasures->m_rsrp = 0;
257 neighbourCellMeasures->m_rsrq = rsrq;
258 it1->second[cellId] = neighbourCellMeasures;
259 }
260
261} // end of UpdateNeighbourMeasurements
262
263} // end of namespace ns3
Handover algorithm implementation based on RSRQ measurements, Event A2 and Event A4.
friend class MemberNrHandoverManagementSapProvider< NrA2A4RsrqHandoverAlgorithm >
let the forwarder class access the protected and private members
void SetNrHandoverManagementSapUser(NrHandoverManagementSapUser *s) override
Set the "user" part of the Handover Management SAP interface that this handover algorithm instance wi...
NrHandoverManagementSapProvider * GetNrHandoverManagementSapProvider() override
Export the "provider" part of the Handover Management SAP interface.
NrA2A4RsrqHandoverAlgorithm()
Creates an A2-A4-RSRQ handover algorithm instance.
void DoReportUeMeas(uint16_t rnti, NrRrcSap::MeasResults measResults) override
Implementation of NrHandoverManagementSapProvider::ReportUeMeas.
The abstract base class of a handover algorithm that operates using the Handover Management SAP inter...
Service Access Point (SAP) offered by the handover algorithm instance to the eNodeB RRC instance.
Service Access Point (SAP) offered by the eNodeB RRC instance to the handover algorithm instance.
virtual void TriggerHandover(uint16_t rnti, uint16_t targetCellId)=0
Instruct the eNodeB RRC entity to prepare a handover.
virtual std::vector< uint8_t > AddUeMeasReportConfigForHandover(NrRrcSap::ReportConfigEutra reportConfig)=0
Request a certain reporting configuration to be fulfilled by the UEs attached to the eNodeB entity.
uint8_t rsrqResult
the RSRQ result
Definition nr-rrc-sap.h:681
MeasResults structure.
Definition nr-rrc-sap.h:723
uint8_t measId
measure ID
Definition nr-rrc-sap.h:724
bool haveMeasResultNeighCells
have measure result neighbor cells
Definition nr-rrc-sap.h:726
MeasResultPCell measResultPCell
measurement result primary cell
Definition nr-rrc-sap.h:725
std::list< MeasResultEutra > measResultListEutra
measure result list eutra
Definition nr-rrc-sap.h:727
Specifies criteria for triggering of an E-UTRA measurement reporting event.
Definition nr-rrc-sap.h:360
enum ns3::NrRrcSap::ReportConfigEutra::@5 triggerQuantity
Trigger type enumeration.
@ RSRQ
Reference Signal Received Quality.
Definition nr-rrc-sap.h:413
enum ns3::NrRrcSap::ReportConfigEutra::@7 reportInterval
Report interval enumeration.
@ EVENT_A2
Event A2: Serving becomes worse than absolute threshold.
Definition nr-rrc-sap.h:372
@ EVENT_A4
Event A4: Neighbour becomes better than absolute threshold.
Definition nr-rrc-sap.h:374
enum ns3::NrRrcSap::ReportConfigEutra::@4 eventId
Event enumeration.
ThresholdEutra threshold1
Threshold for event A1, A2, A4, and A5.
Definition nr-rrc-sap.h:380
enum ns3::NrRrcSap::ThresholdEutra::@2 choice
Threshold enumeration.
uint8_t range
Value range used in RSRP/RSRQ threshold.
Definition nr-rrc-sap.h:355
@ THRESHOLD_RSRQ
RSRQ is used for the threshold.
Definition nr-rrc-sap.h:352