5G-LENA nr-v4.0-29-g6d8085cd
The 5G/NR module for the ns-3 simulator
Loading...
Searching...
No Matches
nr-gnb-rrc.cc
1// Copyright (c) 2011 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
2// Copyright (c) 2018 Fraunhofer ESK : RLF extensions
3//
4// SPDX-License-Identifier: GPL-2.0-only
5//
6// Authors:
7// Nicola Baldo <nbaldo@cttc.es>
8// Marco Miozzo <mmiozzo@cttc.es>
9// Manuel Requena <manuel.requena@cttc.es>
10// Modified by:
11// Danilo Abrignani <danilo.abrignani@unibo.it> (Carrier Aggregation - GSoC 2015),
12// Biljana Bojovic <biljana.bojovic@cttc.es> (Carrier Aggregation)
13// Vignesh Babu <ns3-dev@esk.fraunhofer.de> (RLF extensions)
14
15#include "nr-gnb-rrc.h"
16
17#include "bandwidth-part-gnb.h"
18#include "nr-common.h"
19#include "nr-eps-bearer-tag.h"
20#include "nr-pdcp.h"
21#include "nr-radio-bearer-info.h"
22#include "nr-rlc-am.h"
23#include "nr-rlc-tm.h"
24#include "nr-rlc-um.h"
25#include "nr-rlc.h"
26
27#include "ns3/abort.h"
28#include "ns3/fatal-error.h"
29#include "ns3/log.h"
30#include "ns3/object-factory.h"
31#include "ns3/object-map.h"
32#include "ns3/packet.h"
33#include "ns3/pointer.h"
34#include "ns3/simulator.h"
35
36namespace ns3
37{
38
39NS_LOG_COMPONENT_DEFINE("NrGnbRrc");
40
42// CMAC SAP forwarder
44
48class GnbRrcMemberNrGnbCmacSapUser : public NrGnbCmacSapUser
49{
50 public:
57 GnbRrcMemberNrGnbCmacSapUser(NrGnbRrc* rrc, uint8_t componentCarrierId);
58
59 uint16_t AllocateTemporaryCellRnti() override;
60 void NotifyLcConfigResult(uint16_t rnti, uint8_t lcid, bool success) override;
61 void RrcConfigurationUpdateInd(UeConfig params) override;
62 bool IsRandomAccessCompleted(uint16_t rnti) override;
63
64 private:
65 NrGnbRrc* m_rrc;
66 uint8_t m_componentCarrierId;
67};
68
69GnbRrcMemberNrGnbCmacSapUser::GnbRrcMemberNrGnbCmacSapUser(NrGnbRrc* rrc,
70 uint8_t componentCarrierId)
71 : m_rrc(rrc),
72 m_componentCarrierId{componentCarrierId}
73{
74}
75
76uint16_t
77GnbRrcMemberNrGnbCmacSapUser::AllocateTemporaryCellRnti()
78{
79 return m_rrc->DoAllocateTemporaryCellRnti(m_componentCarrierId);
80}
81
82void
83GnbRrcMemberNrGnbCmacSapUser::NotifyLcConfigResult(uint16_t rnti, uint8_t lcid, bool success)
84{
85 m_rrc->DoNotifyLcConfigResult(rnti, lcid, success);
86}
87
88void
89GnbRrcMemberNrGnbCmacSapUser::RrcConfigurationUpdateInd(UeConfig params)
90{
91 m_rrc->DoRrcConfigurationUpdateInd(params);
92}
93
94bool
95GnbRrcMemberNrGnbCmacSapUser::IsRandomAccessCompleted(uint16_t rnti)
96{
97 return m_rrc->IsRandomAccessCompleted(rnti);
98}
99
101// NrUeManager
103
105static const std::string g_ueManagerStateName[NrUeManager::NUM_STATES] = {
106 "INITIAL_RANDOM_ACCESS",
107 "CONNECTION_SETUP",
108 "CONNECTION_REJECTED",
109 "ATTACH_REQUEST",
110 "CONNECTED_NORMALLY",
111 "CONNECTION_RECONFIGURATION",
112 "CONNECTION_REESTABLISHMENT",
113 "HANDOVER_PREPARATION",
114 "HANDOVER_JOINING",
115 "HANDOVER_PATH_SWITCH",
116 "HANDOVER_LEAVING",
117};
118
123static const std::string&
124ToString(NrUeManager::State s)
125{
126 return g_ueManagerStateName[s];
127}
128
129NS_OBJECT_ENSURE_REGISTERED(NrUeManager);
130
131NrUeManager::NrUeManager()
132{
133 NS_FATAL_ERROR("this constructor is not expected to be used");
134}
135
136NrUeManager::NrUeManager(Ptr<NrGnbRrc> rrc, uint16_t rnti, State s, uint8_t componentCarrierId)
137 : m_lastAllocatedDrbid(0),
138 m_rnti(rnti),
139 m_imsi(0),
140 m_componentCarrierId(componentCarrierId),
141 m_lastRrcTransactionIdentifier(0),
142 m_rrc(rrc),
143 m_state(s),
144 m_pendingRrcConnectionReconfiguration(false),
145 m_sourceX2apId(0),
146 m_sourceCellId(0),
147 m_needPhyMacConfiguration(false),
148 m_caSupportConfigured(false),
149 m_pendingStartDataRadioBearers(false)
150{
151 NS_LOG_FUNCTION(this);
152}
153
154void
156{
157 NS_LOG_FUNCTION(this);
158 ConfigureSap();
162}
163
164void
166{
167 NS_LOG_FUNCTION(this);
168 m_drbPdcpSapUser = new NrPdcpSpecificNrPdcpSapUser<NrUeManager>(this);
169
170 m_physicalConfigDedicated.haveAntennaInfoDedicated = true;
171 m_physicalConfigDedicated.antennaInfo.transmissionMode = m_rrc->m_defaultTransmissionMode;
172 m_physicalConfigDedicated.haveSoundingRsUlConfigDedicated = true;
173 m_physicalConfigDedicated.soundingRsUlConfigDedicated.srsConfigIndex =
174 m_rrc->GetNewSrsConfigurationIndex();
175 m_physicalConfigDedicated.soundingRsUlConfigDedicated.type =
176 NrRrcSap::SoundingRsUlConfigDedicated::SETUP;
177 m_physicalConfigDedicated.soundingRsUlConfigDedicated.srsBandwidth = 0;
178 m_physicalConfigDedicated.havePdschConfigDedicated = true;
179 m_physicalConfigDedicated.pdschConfigDedicated.pa = NrRrcSap::PdschConfigDedicated::dB0;
180
181 for (uint16_t i = 0; i < m_rrc->m_numberOfComponentCarriers; i++)
182 {
183 m_rrc->m_cmacSapProvider.at(i)->AddUe(m_rnti);
184 m_rrc->m_cphySapProvider.at(i)->AddUe(m_rnti);
185 }
186}
187
188void
190{
191 NS_LOG_FUNCTION(this);
192 // setup the gNB side of SRB0
193 {
194 uint8_t lcid = 0;
195
196 Ptr<NrRlc> rlc = CreateObject<NrRlcTm>()->GetObject<NrRlc>();
197 rlc->SetNrMacSapProvider(m_rrc->m_macSapProvider);
198 rlc->SetRnti(m_rnti);
199 rlc->SetLcId(lcid);
200
201 m_srb0 = CreateObject<NrSignalingRadioBearerInfo>();
202 m_srb0->m_rlc = rlc;
203 m_srb0->m_srbIdentity = 0;
204 // no need to store logicalChannelConfig as SRB0 is pre-configured
205
207 lcinfo.rnti = m_rnti;
208 lcinfo.lcId = lcid;
209 // Initialise the rest of lcinfo structure even if CCCH (LCID 0) is pre-configured, and only
210 // m_rnti and lcid will be used from passed lcinfo structure. See FF LTE MAC Scheduler
211 // Iinterface Specification v1.11, 4.3.4 logicalChannelConfigListElement
212 lcinfo.lcGroup = 0;
213 lcinfo.qci = 0;
214 lcinfo.resourceType = 0;
215 lcinfo.mbrUl = 0;
216 lcinfo.mbrDl = 0;
217 lcinfo.gbrUl = 0;
218 lcinfo.gbrDl = 0;
219
220 // MacSapUserForRlc in the ComponentCarrierManager MacSapUser
221 NrMacSapUser* nrMacSapUser =
222 m_rrc->m_ccmRrcSapProvider->ConfigureSignalBearer(lcinfo, rlc->GetNrMacSapUser());
223 // Signal Channel are only on Primary Carrier
224 m_rrc->m_cmacSapProvider.at(m_componentCarrierId)->AddLc(lcinfo, nrMacSapUser);
225 m_rrc->m_ccmRrcSapProvider->AddLc(lcinfo, nrMacSapUser);
226 }
227}
228
229void
231{
232 NS_LOG_FUNCTION(this);
233 // setup the gNB side of SRB1; the UE side will be set up upon RRC connection establishment
234 {
235 uint8_t lcid = 1;
236
237 Ptr<NrRlc> rlc = CreateObject<NrRlcAm>()->GetObject<NrRlc>();
238 rlc->SetNrMacSapProvider(m_rrc->m_macSapProvider);
239 rlc->SetRnti(m_rnti);
240 rlc->SetLcId(lcid);
241
242 Ptr<NrPdcp> pdcp = CreateObject<NrPdcp>();
243 pdcp->SetRnti(m_rnti);
244 pdcp->SetLcId(lcid);
245 pdcp->SetNrPdcpSapUser(m_drbPdcpSapUser);
246 pdcp->SetNrRlcSapProvider(rlc->GetNrRlcSapProvider());
247 rlc->SetNrRlcSapUser(pdcp->GetNrRlcSapUser());
248
249 m_srb1 = CreateObject<NrSignalingRadioBearerInfo>();
250 m_srb1->m_rlc = rlc;
251 m_srb1->m_pdcp = pdcp;
252 m_srb1->m_srbIdentity = 1;
253 m_srb1->m_logicalChannelConfig.priority = 1;
254 m_srb1->m_logicalChannelConfig.prioritizedBitRateKbps = 100;
255 m_srb1->m_logicalChannelConfig.bucketSizeDurationMs = 100;
256 m_srb1->m_logicalChannelConfig.logicalChannelGroup = 0;
257
259 lcinfo.rnti = m_rnti;
260 lcinfo.lcId = lcid;
261 lcinfo.lcGroup = 0; // all SRBs always mapped to LCG 0
262 lcinfo.qci =
263 NrEpsBearer::GBR_CONV_VOICE; // not sure why the FF API requires a CQI even for SRBs...
264 lcinfo.resourceType = 1; // GBR resource type
265 lcinfo.mbrUl = 1e6;
266 lcinfo.mbrDl = 1e6;
267 lcinfo.gbrUl = 1e4;
268 lcinfo.gbrDl = 1e4;
269 // MacSapUserForRlc in the ComponentCarrierManager MacSapUser
270 NrMacSapUser* MacSapUserForRlc =
271 m_rrc->m_ccmRrcSapProvider->ConfigureSignalBearer(lcinfo, rlc->GetNrMacSapUser());
272 // Signal Channel are only on Primary Carrier
273 m_rrc->m_cmacSapProvider.at(m_componentCarrierId)->AddLc(lcinfo, MacSapUserForRlc);
274 m_rrc->m_ccmRrcSapProvider->AddLc(lcinfo, MacSapUserForRlc);
275 }
276
278 ueParams.srb0SapProvider = m_srb0->m_rlc->GetNrRlcSapProvider();
279 ueParams.srb1SapProvider = m_srb1->m_pdcp->GetNrPdcpSapProvider();
280 m_rrc->m_rrcSapUser->SetupUe(m_rnti, ueParams);
281}
282
283void
285{
286 NS_LOG_FUNCTION(this);
287 // configure MAC (and scheduler)
289 req.m_rnti = m_rnti;
290 req.m_transmissionMode = m_physicalConfigDedicated.antennaInfo.transmissionMode;
291
292 // configure PHY
293 for (uint16_t i = 0; i < m_rrc->m_numberOfComponentCarriers; i++)
294 {
295 m_rrc->m_cmacSapProvider.at(i)->UeUpdateConfigurationReq(req);
296 m_rrc->m_cphySapProvider.at(i)->SetTransmissionMode(
297 m_rnti,
298 m_physicalConfigDedicated.antennaInfo.transmissionMode);
299 m_rrc->m_cphySapProvider.at(i)->SetSrsConfigurationIndex(
300 m_rnti,
301 m_physicalConfigDedicated.soundingRsUlConfigDedicated.srsConfigIndex);
302 }
303 // schedule this NrUeManager instance to be deleted if the UE does not give any sign of life
304 // within a reasonable time
305 Time maxConnectionDelay;
306 switch (m_state)
307 {
308 case INITIAL_RANDOM_ACCESS:
309 m_connectionRequestTimeout = Simulator::Schedule(m_rrc->m_connectionRequestTimeoutDuration,
311 m_rrc,
312 m_rnti);
313 break;
314
315 case HANDOVER_JOINING:
316 m_handoverJoiningTimeout = Simulator::Schedule(m_rrc->m_handoverJoiningTimeoutDuration,
318 m_rrc,
319 m_rnti);
320 break;
321
322 default:
323 NS_FATAL_ERROR("unexpected state " << ToString(m_state));
324 break;
325 }
326 m_caSupportConfigured = false;
327}
328
329NrUeManager::~NrUeManager()
330{
331}
332
333void
334NrUeManager::DoDispose()
335{
336 delete m_drbPdcpSapUser;
337 // delete eventual X2-U TEIDs
338 for (auto it = m_drbMap.begin(); it != m_drbMap.end(); ++it)
339 {
340 m_rrc->m_x2uTeidInfoMap.erase(it->second->m_gtpTeid);
341 }
342}
343
344TypeId
346{
347 static TypeId tid =
348 TypeId("ns3::NrUeManager")
349 .SetParent<Object>()
350 .AddConstructor<NrUeManager>()
351 .AddAttribute("DataRadioBearerMap",
352 "List of UE DataRadioBearerInfo by DRBID.",
353 ObjectMapValue(),
354 MakeObjectMapAccessor(&NrUeManager::m_drbMap),
355 MakeObjectMapChecker<NrDataRadioBearerInfo>())
356 .AddAttribute("Srb0",
357 "SignalingRadioBearerInfo for SRB0",
358 PointerValue(),
359 MakePointerAccessor(&NrUeManager::m_srb0),
360 MakePointerChecker<NrSignalingRadioBearerInfo>())
361 .AddAttribute("Srb1",
362 "SignalingRadioBearerInfo for SRB1",
363 PointerValue(),
364 MakePointerAccessor(&NrUeManager::m_srb1),
365 MakePointerChecker<NrSignalingRadioBearerInfo>())
366 .AddAttribute("C-RNTI",
367 "Cell Radio Network Temporary Identifier",
368 TypeId::ATTR_GET, // read-only attribute
369 UintegerValue(0), // unused, read-only attribute
370 MakeUintegerAccessor(&NrUeManager::m_rnti),
371 MakeUintegerChecker<uint16_t>())
372 .AddTraceSource("StateTransition",
373 "fired upon every UE state transition seen by the "
374 "NrUeManager at the gNB RRC",
375 MakeTraceSourceAccessor(&NrUeManager::m_stateTransitionTrace),
376 "ns3::NrUeManager::StateTracedCallback")
377 .AddTraceSource("DrbCreated",
378 "trace fired after DRB is created",
379 MakeTraceSourceAccessor(&NrUeManager::m_drbCreatedTrace),
380 "ns3::NrUeManager::ImsiCidRntiLcIdTracedCallback");
381 return tid;
382}
383
384void
385NrUeManager::SetSource(uint16_t sourceCellId, uint16_t sourceX2apId)
386{
387 m_sourceX2apId = sourceX2apId;
388 m_sourceCellId = sourceCellId;
389}
390
391void
393{
394 m_imsi = imsi;
395}
396
397void
399{
400 NS_LOG_FUNCTION(this << m_rnti);
401
402 if (m_state == ATTACH_REQUEST)
403 {
404 SwitchToState(CONNECTED_NORMALLY);
405 }
406 else
407 {
408 NS_FATAL_ERROR("method unexpected in state " << ToString(m_state));
409 }
410}
411
412void
414 uint8_t bearerId,
415 uint32_t gtpTeid,
416 Ipv4Address transportLayerAddress)
417{
418 NS_LOG_FUNCTION(this << (uint32_t)m_rnti);
419
420 Ptr<NrDataRadioBearerInfo> drbInfo = CreateObject<NrDataRadioBearerInfo>();
421 uint8_t drbid = AddDataRadioBearerInfo(drbInfo);
422 uint8_t lcid = Drbid2Lcid(drbid);
423 uint8_t bid = Drbid2Bid(drbid);
424 NS_ASSERT_MSG(bearerId == 0 || bid == bearerId,
425 "bearer ID mismatch (" << (uint32_t)bid << " != " << (uint32_t)bearerId
426 << ", the assumption that ID are allocated in the same "
427 "way by MME and RRC is not valid any more");
428 drbInfo->m_epsBearer = bearer;
429 drbInfo->m_epsBearerIdentity = bid;
430 drbInfo->m_drbIdentity = drbid;
431 drbInfo->m_logicalChannelIdentity = lcid;
432 drbInfo->m_gtpTeid = gtpTeid;
433 drbInfo->m_transportLayerAddress = transportLayerAddress;
434
435 if (m_state == HANDOVER_JOINING)
436 {
437 // setup TEIDs for receiving data eventually forwarded over X2-U
438 NrGnbRrc::X2uTeidInfo x2uTeidInfo;
439 x2uTeidInfo.rnti = m_rnti;
440 x2uTeidInfo.drbid = drbid;
441 auto ret = m_rrc->m_x2uTeidInfoMap.insert(
442 std::pair<uint32_t, NrGnbRrc::X2uTeidInfo>(gtpTeid, x2uTeidInfo));
443 NS_ASSERT_MSG(ret.second == true, "overwriting a pre-existing entry in m_x2uTeidInfoMap");
444 }
445
446 TypeId rlcTypeId = m_rrc->GetRlcType(bearer);
447
448 ObjectFactory rlcObjectFactory;
449 rlcObjectFactory.SetTypeId(rlcTypeId);
450 Ptr<NrRlc> rlc = rlcObjectFactory.Create()->GetObject<NrRlc>();
451 rlc->SetNrMacSapProvider(m_rrc->m_macSapProvider);
452 rlc->SetRnti(m_rnti);
453 rlc->SetPacketDelayBudgetMs(bearer.GetPacketDelayBudgetMs());
454 if (rlcTypeId == NrRlcSm::GetTypeId())
455 {
456 // Starts the chain of calls:
457 // DoReportBufferStatus->DoNotifyTxOpp->DoReportBufferStatus...
458 Simulator::ScheduleNow(&NrRlcSm::Initialize, rlc);
459 }
460
461 drbInfo->m_rlc = rlc;
462
463 rlc->SetLcId(lcid);
464
465 // we need PDCP only for real RLC, i.e., RLC/UM or RLC/AM
466 // if we are using RLC/SM we don't care of anything above RLC
467 if (rlcTypeId != NrRlcSm::GetTypeId())
468 {
469 Ptr<NrPdcp> pdcp = CreateObject<NrPdcp>();
470 pdcp->SetRnti(m_rnti);
471 pdcp->SetLcId(lcid);
472 pdcp->SetNrPdcpSapUser(m_drbPdcpSapUser);
473 pdcp->SetNrRlcSapProvider(rlc->GetNrRlcSapProvider());
474 rlc->SetNrRlcSapUser(pdcp->GetNrRlcSapUser());
475 drbInfo->m_pdcp = pdcp;
476 }
477
478 m_drbCreatedTrace(m_imsi, m_rrc->ComponentCarrierToCellId(m_componentCarrierId), m_rnti, lcid);
479
480 std::vector<NrCcmRrcSapProvider::LcsConfig> lcOnCcMapping =
481 m_rrc->m_ccmRrcSapProvider->SetupDataRadioBearer(bearer,
482 bearerId,
483 m_rnti,
484 lcid,
485 m_rrc->GetLogicalChannelGroup(bearer),
486 rlc->GetNrMacSapUser());
487 // NrGnbCmacSapProvider::LcInfo lcinfo;
488 // lcinfo.rnti = m_rnti;
489 // lcinfo.lcId = lcid;
490 // lcinfo.lcGroup = m_rrc->GetLogicalChannelGroup (bearer);
491 // lcinfo.qci = bearer.qci;
492 // lcinfo.resourceType = bearer.GetResourceType();
493 // lcinfo.mbrUl = bearer.gbrQosInfo.mbrUl;
494 // lcinfo.mbrDl = bearer.gbrQosInfo.mbrDl;
495 // lcinfo.gbrUl = bearer.gbrQosInfo.gbrUl;
496 // lcinfo.gbrDl = bearer.gbrQosInfo.gbrDl;
497 // use a for cycle to send the AddLc to the appropriate Mac Sap
498 // if the sap is not initialized the appropriated method has to be called
499 auto itLcOnCcMapping = lcOnCcMapping.begin();
500 NS_ASSERT_MSG(itLcOnCcMapping != lcOnCcMapping.end(), "Problem");
501 for (itLcOnCcMapping = lcOnCcMapping.begin(); itLcOnCcMapping != lcOnCcMapping.end();
502 ++itLcOnCcMapping)
503 {
504 NS_LOG_DEBUG(this << " RNTI " << itLcOnCcMapping->lc.rnti << "Lcid "
505 << (uint16_t)itLcOnCcMapping->lc.lcId << " lcGroup "
506 << (uint16_t)itLcOnCcMapping->lc.lcGroup << " ComponentCarrierId "
507 << itLcOnCcMapping->componentCarrierId);
508 uint8_t index = itLcOnCcMapping->componentCarrierId;
509 NrGnbCmacSapProvider::LcInfo lcinfo = itLcOnCcMapping->lc;
510 NrMacSapUser* msu = itLcOnCcMapping->msu;
511 m_rrc->m_cmacSapProvider.at(index)->AddLc(lcinfo, msu);
512 m_rrc->m_ccmRrcSapProvider->AddLc(lcinfo, msu);
513 }
514
515 if (rlcTypeId == NrRlcAm::GetTypeId())
516 {
517 drbInfo->m_rlcConfig.choice = NrRrcSap::RlcConfig::AM;
518 }
519 else
520 {
521 drbInfo->m_rlcConfig.choice = NrRrcSap::RlcConfig::UM_BI_DIRECTIONAL;
522 }
523
524 drbInfo->m_logicalChannelIdentity = lcid;
525 drbInfo->m_logicalChannelConfig.priority = m_rrc->GetLogicalChannelPriority(bearer);
526 drbInfo->m_logicalChannelConfig.logicalChannelGroup = m_rrc->GetLogicalChannelGroup(bearer);
527 if (bearer.GetResourceType() > 0) // 1, 2 for GBR and DC-GBR
528 {
529 drbInfo->m_logicalChannelConfig.prioritizedBitRateKbps = bearer.gbrQosInfo.gbrUl;
530 }
531 else
532 {
533 drbInfo->m_logicalChannelConfig.prioritizedBitRateKbps = 0;
534 }
535 drbInfo->m_logicalChannelConfig.bucketSizeDurationMs = 1000;
536
538}
539
540void
542{
543 NS_LOG_FUNCTION(this << (uint32_t)m_rnti);
544 for (auto it = m_drbMap.begin(); it != m_drbMap.end(); ++it)
545 {
546 m_drbsToBeStarted.push_back(it->first);
547 }
548}
549
550void
552{
553 NS_LOG_FUNCTION(this << (uint32_t)m_rnti);
554 for (auto drbIdIt = m_drbsToBeStarted.begin(); drbIdIt != m_drbsToBeStarted.end(); ++drbIdIt)
555 {
556 auto drbIt = m_drbMap.find(*drbIdIt);
557 NS_ASSERT(drbIt != m_drbMap.end());
558 }
559 m_drbsToBeStarted.clear();
560}
561
562void
564{
565 NS_LOG_FUNCTION(this << (uint32_t)m_rnti << (uint32_t)drbid);
566 uint8_t lcid = Drbid2Lcid(drbid);
567 auto it = m_drbMap.find(drbid);
568 NS_ASSERT_MSG(it != m_drbMap.end(),
569 "request to remove radio bearer with unknown drbid " << drbid);
570
571 // first delete eventual X2-U TEIDs
572 m_rrc->m_x2uTeidInfoMap.erase(it->second->m_gtpTeid);
573
574 m_drbMap.erase(it);
575 std::vector<uint8_t> ccToRelease =
576 m_rrc->m_ccmRrcSapProvider->ReleaseDataRadioBearer(m_rnti, lcid);
577 auto itCcToRelease = ccToRelease.begin();
578 NS_ASSERT_MSG(itCcToRelease != ccToRelease.end(),
579 "request to remove radio bearer with unknown drbid (ComponentCarrierManager)");
580 for (itCcToRelease = ccToRelease.begin(); itCcToRelease != ccToRelease.end(); ++itCcToRelease)
581 {
582 m_rrc->m_cmacSapProvider.at(*itCcToRelease)->ReleaseLc(m_rnti, lcid);
583 }
585 rrcd.havePhysicalConfigDedicated = false;
586 rrcd.drbToReleaseList.push_back(drbid);
587 // populating RadioResourceConfigDedicated information element as per 3GPP TS 36.331
588 // version 9.2.0
589 rrcd.havePhysicalConfigDedicated = true;
590 rrcd.physicalConfigDedicated = m_physicalConfigDedicated;
591
592 // populating RRCConnectionReconfiguration message as per 3GPP TS 36.331 version 9.2.0 Release 9
594 msg.haveMeasConfig = false;
595 msg.haveMobilityControlInfo = false;
596 msg.radioResourceConfigDedicated = rrcd;
597 msg.haveRadioResourceConfigDedicated = true;
598 // ToDo: Resend in any case this configuration
599 // needs to be initialized
600 msg.haveNonCriticalExtension = false;
601 // RRC Connection Reconfiguration towards UE
602 m_rrc->m_rrcSapUser->SendRrcConnectionReconfiguration(m_rnti, msg);
603}
604
605void
606NrGnbRrc::DoSendReleaseDataRadioBearer(uint64_t imsi, uint16_t rnti, uint8_t bearerId)
607{
608 NS_LOG_FUNCTION(this << imsi << rnti << (uint16_t)bearerId);
609
610 // check if the RNTI to be removed is not stale
611 if (HasUeManager(rnti))
612 {
613 Ptr<NrUeManager> ueManager = GetUeManager(rnti);
614 // Bearer de-activation towards UE
615 ueManager->ReleaseDataRadioBearer(bearerId);
616 // Bearer de-activation indication towards epc-gNB application
617 m_s1SapProvider->DoSendReleaseIndication(imsi, rnti, bearerId);
618 }
619}
620
621void
623{
624 NS_LOG_FUNCTION(this << m_rnti);
625
626 // release the bearer info for the UE at SGW/PGW
627 if (m_rrc->m_s1SapProvider != nullptr) // if EPC is enabled
628 {
629 for (const auto& it : m_drbMap)
630 {
631 NS_LOG_DEBUG("Sending release of bearer id : "
632 << (uint16_t)(it.first)
633 << "LCID : " << (uint16_t)(it.second->m_logicalChannelIdentity));
634 // Bearer de-activation indication towards epc-gnb application
635 m_rrc->m_s1SapProvider->DoSendReleaseIndication(GetImsi(), rnti, it.first);
636 }
637 }
638}
639
640void
642{
643 NS_LOG_FUNCTION(this);
644 switch (m_state)
645 {
646 case INITIAL_RANDOM_ACCESS:
647 case CONNECTION_SETUP:
648 case ATTACH_REQUEST:
649 case CONNECTION_RECONFIGURATION:
650 case CONNECTION_REESTABLISHMENT:
651 case HANDOVER_PREPARATION:
652 case HANDOVER_JOINING:
653 case HANDOVER_LEAVING:
654 // a previous reconfiguration still ongoing, we need to wait for it to be finished
655 m_pendingRrcConnectionReconfiguration = true;
656 break;
657
658 case CONNECTED_NORMALLY: {
659 m_pendingRrcConnectionReconfiguration = false;
660 NrRrcSap::RrcConnectionReconfiguration msg = BuildRrcConnectionReconfiguration();
661 m_rrc->m_rrcSapUser->SendRrcConnectionReconfiguration(m_rnti, msg);
663 SwitchToState(CONNECTION_RECONFIGURATION);
664 }
665 break;
666
667 default:
668 NS_FATAL_ERROR("method unexpected in state " << ToString(m_state));
669 break;
670 }
671}
672
673void
675{
676 NS_LOG_FUNCTION(this << cellId);
677 switch (m_state)
678 {
679 case CONNECTED_NORMALLY: {
680 m_targetCellId = cellId;
681
682 auto sourceComponentCarrier = DynamicCast<BandwidthPartGnb>(
683 m_rrc->m_componentCarrierPhyConf.at(m_componentCarrierId));
684 NS_ASSERT(m_targetCellId != sourceComponentCarrier->GetCellId());
685
686 if (m_rrc->HasCellId(cellId))
687 {
688 // Intra-gNB handover
689 NS_LOG_DEBUG("Intra-gNB handover for cellId " << cellId);
690 uint8_t componentCarrierId = m_rrc->CellToComponentCarrierId(cellId);
691 uint16_t rnti = m_rrc->AddUe(NrUeManager::HANDOVER_JOINING, componentCarrierId);
693 m_rrc->m_cmacSapProvider.at(componentCarrierId)->AllocateNcRaPreamble(rnti);
694 if (!anrcrv.valid)
695 {
696 NS_LOG_INFO(this << " failed to allocate a preamble for non-contention based RA => "
697 "cannot perform HO");
698 NS_FATAL_ERROR("should trigger HO Preparation Failure, but it is not implemented");
699 return;
700 }
701
702 Ptr<NrUeManager> ueManager = m_rrc->GetUeManager(rnti);
703 ueManager->SetSource(sourceComponentCarrier->GetCellId(), m_rnti);
704 ueManager->SetImsi(m_imsi);
705
706 // Setup data radio bearers
707 for (auto& it : m_drbMap)
708 {
709 ueManager->SetupDataRadioBearer(it.second->m_epsBearer,
710 it.second->m_epsBearerIdentity,
711 it.second->m_gtpTeid,
712 it.second->m_transportLayerAddress);
713 }
714
717
718 handoverCommand.mobilityControlInfo.newUeIdentity = rnti;
719 handoverCommand.mobilityControlInfo.haveRachConfigDedicated = true;
721 anrcrv.raPreambleId;
723 anrcrv.raPrachMaskIndex;
724
726 m_rrc->m_cmacSapProvider.at(componentCarrierId)->GetRachConfig();
733
734 m_rrc->m_rrcSapUser->SendRrcConnectionReconfiguration(m_rnti, handoverCommand);
735
736 // We skip handover preparation
737 SwitchToState(HANDOVER_LEAVING);
738 m_handoverLeavingTimeout = Simulator::Schedule(m_rrc->m_handoverLeavingTimeoutDuration,
740 m_rrc,
741 m_rnti);
742 m_rrc->m_handoverStartTrace(m_imsi,
743 sourceComponentCarrier->GetCellId(),
744 m_rnti,
745 handoverCommand.mobilityControlInfo.targetPhysCellId);
746 }
747 else
748 {
749 // Inter-gNB aka X2 handover
750 NS_LOG_DEBUG("Inter-gNB handover (i.e., X2) for cellId " << cellId);
752 params.oldGnbUeX2apId = m_rnti;
753 params.cause = NrEpcX2SapProvider::HandoverDesirableForRadioReason;
754 params.sourceCellId = m_rrc->ComponentCarrierToCellId(m_componentCarrierId);
755 params.targetCellId = cellId;
756 params.mmeUeS1apId = m_imsi;
757 params.ueAggregateMaxBitRateDownlink = 200 * 1000;
758 params.ueAggregateMaxBitRateUplink = 100 * 1000;
759 params.bearers = GetErabList();
760
762 hpi.asConfig.sourceUeIdentity = m_rnti;
763 hpi.asConfig.sourceDlCarrierFreq = sourceComponentCarrier->GetDlEarfcn();
764 hpi.asConfig.sourceMeasConfig = m_rrc->m_ueMeasConfig;
768 sourceComponentCarrier->GetDlBandwidth();
771 .plmnIdentity = m_rrc->m_sib1.at(m_componentCarrierId)
772 .cellAccessRelatedInfo.plmnIdentityInfo.plmnIdentity;
774 m_rrc->ComponentCarrierToCellId(m_componentCarrierId);
776 m_rrc->m_sib1.at(m_componentCarrierId).cellAccessRelatedInfo.csgIndication;
778 m_rrc->m_sib1.at(m_componentCarrierId).cellAccessRelatedInfo.csgIdentity;
780 m_rrc->m_cmacSapProvider.at(m_componentCarrierId)->GetRachConfig();
790 sourceComponentCarrier->GetUlEarfcn();
792 sourceComponentCarrier->GetUlBandwidth();
793 params.rrcContext = m_rrc->m_rrcSapUser->EncodeHandoverPreparationInformation(hpi);
794
795 NS_LOG_LOGIC("oldGnbUeX2apId = " << params.oldGnbUeX2apId);
796 NS_LOG_LOGIC("sourceCellId = " << params.sourceCellId);
797 NS_LOG_LOGIC("targetCellId = " << params.targetCellId);
798 NS_LOG_LOGIC("mmeUeS1apId = " << params.mmeUeS1apId);
799 NS_LOG_LOGIC("rrcContext = " << params.rrcContext);
800
801 m_rrc->m_x2SapProvider->SendHandoverRequest(params);
802 SwitchToState(HANDOVER_PREPARATION);
803 }
804 }
805 break;
806
807 default:
808 NS_FATAL_ERROR("method unexpected in state " << ToString(m_state));
809 break;
810 }
811}
812
813void
815{
816 NS_LOG_FUNCTION(this);
817
818 NS_ASSERT_MSG(params.notAdmittedBearers.empty(),
819 "not admission of some bearers upon handover is not supported");
820 NS_ASSERT_MSG(params.admittedBearers.size() == m_drbMap.size(),
821 "not enough bearers in admittedBearers");
822
823 // note: the Handover command from the target gNB to the source gNB
824 // is expected to be sent transparently to the UE; however, here we
825 // decode the message and eventually re-encode it. This way we can
826 // support both a real RRC protocol implementation and an ideal one
827 // without actual RRC protocol encoding.
828
829 Ptr<Packet> encodedHandoverCommand = params.rrcContext;
831 m_rrc->m_rrcSapUser->DecodeHandoverCommand(encodedHandoverCommand);
832 if (handoverCommand.haveNonCriticalExtension)
833 {
834 // Total number of component carriers =
835 // handoverCommand.nonCriticalExtension.sCellToAddModList.size() + 1 (Primary carrier)
836 if (handoverCommand.nonCriticalExtension.sCellToAddModList.size() + 1 !=
837 m_rrc->m_numberOfComponentCarriers)
838 {
839 // Currently handover is only possible if source and target eNBs have equal number of
840 // component carriers
841 NS_FATAL_ERROR("The source and target eNBs have unequal number of component carriers. "
842 "Target gNB CCs = "
843 << handoverCommand.nonCriticalExtension.sCellToAddModList.size() + 1
844 << " Source gNB CCs = " << m_rrc->m_numberOfComponentCarriers);
845 }
846 }
847 m_rrc->m_rrcSapUser->SendRrcConnectionReconfiguration(m_rnti, handoverCommand);
848 SwitchToState(HANDOVER_LEAVING);
849 m_handoverLeavingTimeout = Simulator::Schedule(m_rrc->m_handoverLeavingTimeoutDuration,
851 m_rrc,
852 m_rnti);
853 NS_ASSERT(handoverCommand.haveMobilityControlInfo);
854 m_rrc->m_handoverStartTrace(m_imsi,
855 m_rrc->ComponentCarrierToCellId(m_componentCarrierId),
856 m_rnti,
857 handoverCommand.mobilityControlInfo.targetPhysCellId);
858
859 // Set the target cell ID and the RNTI so that handover cancel message can be sent if required
860 m_targetX2apId = params.newGnbUeX2apId;
861 m_targetCellId = params.targetCellId;
862
864 sst.oldGnbUeX2apId = params.oldGnbUeX2apId;
865 sst.newGnbUeX2apId = params.newGnbUeX2apId;
866 sst.sourceCellId = params.sourceCellId;
867 sst.targetCellId = params.targetCellId;
868 for (auto drbIt = m_drbMap.begin(); drbIt != m_drbMap.end(); ++drbIt)
869 {
870 // SN status transfer is only for AM RLC
871 if (drbIt->second->m_rlc->GetObject<NrRlcAm>())
872 {
873 NrPdcp::Status status = drbIt->second->m_pdcp->GetStatus();
875 i.dlPdcpSn = status.txSn;
876 i.ulPdcpSn = status.rxSn;
877 sst.erabsSubjectToStatusTransferList.push_back(i);
878 }
879 }
880 m_rrc->m_x2SapProvider->SendSnStatusTransfer(sst);
881}
882
885{
886 NS_LOG_FUNCTION(this);
887 return BuildRadioResourceConfigDedicated();
888}
889
892{
893 NS_LOG_FUNCTION(this);
894
895 NrRrcSap::RrcConnectionReconfiguration result = BuildRrcConnectionReconfiguration();
896
897 auto targetComponentCarrier = m_rrc->m_componentCarrierPhyConf.at(componentCarrierId);
898 result.haveMobilityControlInfo = true;
899 result.mobilityControlInfo.targetPhysCellId = targetComponentCarrier->GetCellId();
901 result.mobilityControlInfo.carrierFreq.dlCarrierFreq = targetComponentCarrier->GetDlEarfcn();
902 result.mobilityControlInfo.carrierFreq.ulCarrierFreq = targetComponentCarrier->GetUlEarfcn();
905 targetComponentCarrier->GetDlBandwidth();
907 targetComponentCarrier->GetUlBandwidth();
908
909 if (m_caSupportConfigured && m_rrc->m_numberOfComponentCarriers > 1)
910 {
911 // Release sCells
912 result.haveNonCriticalExtension = true;
913
914 for (auto& it : m_rrc->m_componentCarrierPhyConf)
915 {
916 uint8_t ccId = it.first;
917
918 if (ccId == m_componentCarrierId)
919 {
920 // Skip primary CC.
921 continue;
922 }
923 else if (ccId < m_componentCarrierId)
924 {
925 // Shift all IDs below PCC forward so PCC can use CC ID 1.
926 result.nonCriticalExtension.sCellToReleaseList.push_back(ccId + 1);
927 }
928 }
929 }
930 else
931 {
932 result.haveNonCriticalExtension = false;
933 }
934
935 return result;
936}
937
938void
939NrUeManager::SendPacket(uint8_t bid, Ptr<Packet> p)
940{
941 NS_LOG_FUNCTION(this << p << (uint16_t)bid);
943 params.pdcpSdu = p;
944 params.rnti = m_rnti;
945 params.lcid = Bid2Lcid(bid);
946 uint8_t drbid = Bid2Drbid(bid);
947 // Transmit PDCP sdu only if DRB ID found in drbMap
948 auto it = m_drbMap.find(drbid);
949 if (it != m_drbMap.end())
950 {
951 Ptr<NrDataRadioBearerInfo> bearerInfo = GetDataRadioBearerInfo(drbid);
952 if (bearerInfo)
953 {
954 NS_LOG_INFO("Send packet to PDCP layer");
955 NrPdcpSapProvider* pdcpSapProvider = bearerInfo->m_pdcp->GetNrPdcpSapProvider();
956 pdcpSapProvider->TransmitPdcpSdu(params);
957 }
958 }
959}
960
961void
962NrUeManager::SendData(uint8_t bid, Ptr<Packet> p)
963{
964 NS_LOG_FUNCTION(this << p << (uint16_t)bid);
965 switch (m_state)
966 {
967 case INITIAL_RANDOM_ACCESS:
968 case CONNECTION_SETUP:
969 NS_LOG_WARN("not connected, discarding packet");
970 return;
971
972 case CONNECTED_NORMALLY:
973 case CONNECTION_RECONFIGURATION:
974 case CONNECTION_REESTABLISHMENT:
975 case HANDOVER_PREPARATION:
976 case HANDOVER_PATH_SWITCH: {
977 NS_LOG_INFO("queueing data on PDCP for transmission over the air");
978 SendPacket(bid, p);
979 }
980 break;
981
982 case HANDOVER_JOINING: {
983 // Buffer data until RRC Connection Reconfiguration Complete message is received
984 NS_LOG_INFO("buffering data");
985 m_packetBuffer.emplace_back(bid, p);
986 }
987 break;
988
989 case HANDOVER_LEAVING: {
990 NS_LOG_INFO("forwarding data to target gNB over X2-U");
991 uint8_t drbid = Bid2Drbid(bid);
993 params.sourceCellId = m_rrc->ComponentCarrierToCellId(m_componentCarrierId);
994 params.targetCellId = m_targetCellId;
995 params.gtpTeid = GetDataRadioBearerInfo(drbid)->m_gtpTeid;
996 params.ueData = p;
997 m_rrc->m_x2SapProvider->SendUeData(params);
998 }
999 break;
1000
1001 default:
1002 NS_FATAL_ERROR("method unexpected in state " << ToString(m_state));
1003 break;
1004 }
1005}
1006
1007std::vector<NrEpcX2Sap::ErabToBeSetupItem>
1009{
1010 NS_LOG_FUNCTION(this);
1011 std::vector<NrEpcX2Sap::ErabToBeSetupItem> ret;
1012 for (auto it = m_drbMap.begin(); it != m_drbMap.end(); ++it)
1013 {
1015 etbsi.erabId = it->second->m_epsBearerIdentity;
1016 etbsi.erabLevelQosParameters = it->second->m_epsBearer;
1017 etbsi.dlForwarding = false;
1018 etbsi.transportLayerAddress = it->second->m_transportLayerAddress;
1019 etbsi.gtpTeid = it->second->m_gtpTeid;
1020 ret.push_back(etbsi);
1021 }
1022 return ret;
1023}
1024
1025void
1027{
1028 NS_LOG_FUNCTION(this);
1029 switch (m_state)
1030 {
1031 case HANDOVER_PATH_SWITCH:
1032 NS_LOG_INFO("Send UE CONTEXT RELEASE from target gNB to source gNB");
1034 ueCtxReleaseParams.oldGnbUeX2apId = m_sourceX2apId;
1035 ueCtxReleaseParams.newGnbUeX2apId = m_rnti;
1036 ueCtxReleaseParams.sourceCellId = m_sourceCellId;
1037 ueCtxReleaseParams.targetCellId = m_targetCellId;
1038 if (!m_rrc->HasCellId(m_sourceCellId))
1039 {
1040 m_rrc->m_x2SapProvider->SendUeContextRelease(ueCtxReleaseParams);
1041 }
1042 else
1043 {
1044 NS_LOG_INFO("Not sending UE CONTEXT RELEASE because handover is internal");
1045 m_rrc->DoRecvUeContextRelease(ueCtxReleaseParams);
1046 }
1047 SwitchToState(CONNECTED_NORMALLY);
1048 m_rrc->m_handoverEndOkTrace(m_imsi,
1049 m_rrc->ComponentCarrierToCellId(m_componentCarrierId),
1050 m_rnti);
1051 break;
1052
1053 default:
1054 NS_FATAL_ERROR("method unexpected in state " << ToString(m_state));
1055 break;
1056 }
1057}
1058
1059void
1061{
1062 NS_LOG_FUNCTION(this << cellId);
1063 switch (m_state)
1064 {
1065 case HANDOVER_PREPARATION:
1066 NS_ASSERT(cellId == m_targetCellId);
1067 NS_LOG_INFO("target gNB sent HO preparation failure, aborting HO");
1068 SwitchToState(CONNECTED_NORMALLY);
1069 break;
1070 case HANDOVER_LEAVING: // case added to tackle HO leaving timer expiration
1071 NS_ASSERT(cellId == m_targetCellId);
1072 NS_LOG_INFO("target gNB sent HO preparation failure, aborting HO");
1073 m_handoverLeavingTimeout.Cancel();
1075 break;
1076
1077 default:
1078 NS_FATAL_ERROR("method unexpected in state " << ToString(m_state));
1079 break;
1080 }
1081}
1082
1083void
1085{
1086 NS_LOG_FUNCTION(this);
1087 for (auto erabIt = params.erabsSubjectToStatusTransferList.begin();
1088 erabIt != params.erabsSubjectToStatusTransferList.end();
1089 ++erabIt)
1090 {
1091 NrPdcp::Status status;
1092 status.txSn = erabIt->dlPdcpSn;
1093 status.rxSn = erabIt->ulPdcpSn;
1094 uint8_t drbId = Bid2Drbid(erabIt->erabId);
1095 auto drbIt = m_drbMap.find(drbId);
1096 NS_ASSERT_MSG(drbIt != m_drbMap.end(), "could not find DRBID " << (uint32_t)drbId);
1097 drbIt->second->m_pdcp->SetStatus(status);
1098 }
1099}
1100
1101void
1103{
1104 NS_LOG_FUNCTION(this);
1105 NS_ASSERT_MSG(m_state == HANDOVER_LEAVING, "method unexpected in state " << ToString(m_state));
1106 m_handoverLeavingTimeout.Cancel();
1107}
1108
1109void
1111{
1112 NS_LOG_FUNCTION(this);
1113 NS_ASSERT_MSG(m_state == HANDOVER_JOINING, "method unexpected in state " << ToString(m_state));
1114 m_handoverJoiningTimeout.Cancel();
1115}
1116
1117void
1119{
1120 // TODO implement in the 3gpp way, see Section 5.3.8 of 3GPP TS 36.331.
1121 NS_LOG_FUNCTION(this << (uint32_t)m_rnti);
1122 // De-activation towards UE, it will deactivate all bearers
1124 msg.rrcTransactionIdentifier = this->GetNewRrcTransactionIdentifier();
1125 m_rrc->m_rrcSapUser->SendRrcConnectionRelease(m_rnti, msg);
1126
1132 m_rrc->DoRecvIdealUeContextRemoveRequest(m_rnti);
1133}
1134
1135// methods forwarded from RRC SAP
1136
1137void
1139{
1140 NS_LOG_FUNCTION(this);
1141 m_srb0->m_rlc->SetNrRlcSapUser(params.srb0SapUser);
1142 m_srb1->m_pdcp->SetNrPdcpSapUser(params.srb1SapUser);
1143}
1144
1145void
1147{
1148 NS_LOG_FUNCTION(this);
1149 switch (m_state)
1150 {
1151 case INITIAL_RANDOM_ACCESS: {
1152 m_connectionRequestTimeout.Cancel();
1153
1154 if (m_rrc->m_admitRrcConnectionRequest)
1155 {
1156 m_imsi = msg.ueIdentity;
1157
1158 // send RRC CONNECTION SETUP to UE
1160 msg2.rrcTransactionIdentifier = GetNewRrcTransactionIdentifier();
1161 msg2.radioResourceConfigDedicated = BuildRadioResourceConfigDedicated();
1162 m_rrc->m_rrcSapUser->SendRrcConnectionSetup(m_rnti, msg2);
1163
1165 m_connectionSetupTimeout = Simulator::Schedule(m_rrc->m_connectionSetupTimeoutDuration,
1167 m_rrc,
1168 m_rnti);
1169 SwitchToState(CONNECTION_SETUP);
1170 }
1171 else
1172 {
1173 NS_LOG_INFO("rejecting connection request for RNTI " << m_rnti);
1174
1175 // send RRC CONNECTION REJECT to UE
1177 rejectMsg.waitTime = 3;
1178 m_rrc->m_rrcSapUser->SendRrcConnectionReject(m_rnti, rejectMsg);
1179
1180 m_connectionRejectedTimeout =
1181 Simulator::Schedule(m_rrc->m_connectionRejectedTimeoutDuration,
1183 m_rrc,
1184 m_rnti);
1185 SwitchToState(CONNECTION_REJECTED);
1186 }
1187 }
1188 break;
1189
1190 default:
1191 NS_FATAL_ERROR("method unexpected in state " << ToString(m_state));
1192 break;
1193 }
1194}
1195
1196void
1198{
1199 NS_LOG_FUNCTION(this);
1200 switch (m_state)
1201 {
1202 case CONNECTION_SETUP:
1203 m_connectionSetupTimeout.Cancel();
1204 if (!m_caSupportConfigured && m_rrc->m_numberOfComponentCarriers > 1)
1205 {
1206 m_pendingRrcConnectionReconfiguration = true; // Force Reconfiguration
1207 m_pendingStartDataRadioBearers = true;
1208 }
1209
1210 if (m_rrc->m_s1SapProvider != nullptr)
1211 {
1212 m_rrc->m_s1SapProvider->InitialUeMessage(m_imsi, m_rnti);
1213 SwitchToState(ATTACH_REQUEST);
1214 }
1215 else
1216 {
1217 SwitchToState(CONNECTED_NORMALLY);
1218 }
1219 m_rrc->m_connectionEstablishedTrace(m_imsi,
1220 m_rrc->ComponentCarrierToCellId(m_componentCarrierId),
1221 m_rnti);
1222 break;
1223
1224 default:
1225 NS_FATAL_ERROR("method unexpected in state " << ToString(m_state));
1226 break;
1227 }
1228}
1229
1230void
1233{
1234 NS_LOG_FUNCTION(this);
1235 switch (m_state)
1236 {
1237 case CONNECTION_RECONFIGURATION:
1239 if (m_needPhyMacConfiguration)
1240 {
1241 // configure MAC (and scheduler)
1243 req.m_rnti = m_rnti;
1244 req.m_transmissionMode = m_physicalConfigDedicated.antennaInfo.transmissionMode;
1245 for (uint16_t i = 0; i < m_rrc->m_numberOfComponentCarriers; i++)
1246 {
1247 m_rrc->m_cmacSapProvider.at(i)->UeUpdateConfigurationReq(req);
1248
1249 // configure PHY
1250 m_rrc->m_cphySapProvider.at(i)->SetTransmissionMode(req.m_rnti,
1251 req.m_transmissionMode);
1253 m_physicalConfigDedicated.pdschConfigDedicated);
1254 m_rrc->m_cphySapProvider.at(i)->SetPa(m_rnti, paDouble);
1255 }
1256
1257 m_needPhyMacConfiguration = false;
1258 }
1259 SwitchToState(CONNECTED_NORMALLY);
1260 m_rrc->m_connectionReconfigurationTrace(
1261 m_imsi,
1262 m_rrc->ComponentCarrierToCellId(m_componentCarrierId),
1263 m_rnti);
1264 break;
1265
1266 // This case is added to NS-3 in order to handle bearer de-activation scenario for CONNECTED
1267 // state UE
1268 case CONNECTED_NORMALLY:
1269 case HANDOVER_LEAVING:
1270 NS_LOG_INFO("ignoring RecvRrcConnectionReconfigurationCompleted in state "
1271 << ToString(m_state));
1272 break;
1273
1274 case HANDOVER_JOINING: {
1275 m_handoverJoiningTimeout.Cancel();
1276
1277 while (!m_packetBuffer.empty())
1278 {
1279 NS_LOG_LOGIC("dequeueing data from buffer");
1280 std::pair<uint8_t, Ptr<Packet>> bidPacket = m_packetBuffer.front();
1281 uint8_t bid = bidPacket.first;
1282 Ptr<Packet> p = bidPacket.second;
1283
1284 NS_LOG_LOGIC("queueing data on PDCP for transmission over the air");
1285 SendPacket(bid, p);
1286
1287 m_packetBuffer.pop_front();
1288 }
1289
1290 NS_LOG_INFO("Send PATH SWITCH REQUEST to the MME");
1292 params.rnti = m_rnti;
1293 params.cellId = m_rrc->ComponentCarrierToCellId(m_componentCarrierId);
1294 params.mmeUeS1Id = m_imsi;
1295 SwitchToState(HANDOVER_PATH_SWITCH);
1296 for (auto it = m_drbMap.begin(); it != m_drbMap.end(); ++it)
1297 {
1299 b.epsBearerId = it->second->m_epsBearerIdentity;
1300 b.teid = it->second->m_gtpTeid;
1301 params.bearersToBeSwitched.push_back(b);
1302 }
1303 m_rrc->m_s1SapProvider->PathSwitchRequest(params);
1304 }
1305 break;
1306
1307 default:
1308 NS_FATAL_ERROR("method unexpected in state " << ToString(m_state));
1309 break;
1310 }
1311}
1312
1313void
1316{
1317 NS_LOG_FUNCTION(this);
1318 switch (m_state)
1319 {
1320 case CONNECTED_NORMALLY:
1321 break;
1322
1323 case HANDOVER_LEAVING:
1324 m_handoverLeavingTimeout.Cancel();
1325 break;
1326
1327 default:
1328 NS_FATAL_ERROR("method unexpected in state " << ToString(m_state));
1329 break;
1330 }
1331
1333 msg2.rrcTransactionIdentifier = GetNewRrcTransactionIdentifier();
1334 msg2.radioResourceConfigDedicated = BuildRadioResourceConfigDedicated();
1335 m_rrc->m_rrcSapUser->SendRrcConnectionReestablishment(m_rnti, msg2);
1336 SwitchToState(CONNECTION_REESTABLISHMENT);
1337}
1338
1339void
1342{
1343 NS_LOG_FUNCTION(this);
1344 SwitchToState(CONNECTED_NORMALLY);
1345}
1346
1347void
1349{
1350 uint8_t measId = msg.measResults.measId;
1351 NS_LOG_FUNCTION(this << (uint16_t)measId);
1352 NS_LOG_LOGIC(
1353 "measId " << (uint16_t)measId << " haveMeasResultNeighCells "
1354 << msg.measResults.haveMeasResultNeighCells << " measResultListEutra "
1355 << msg.measResults.measResultListEutra.size() << " haveMeasResultServFreqList "
1356 << msg.measResults.haveMeasResultServFreqList << " measResultServFreqList "
1357 << msg.measResults.measResultServFreqList.size());
1358 NS_LOG_LOGIC("serving cellId "
1359 << m_rrc->ComponentCarrierToCellId(m_componentCarrierId) << " RSRP "
1360 << (uint16_t)msg.measResults.measResultPCell.rsrpResult << " RSRQ "
1361 << (uint16_t)msg.measResults.measResultPCell.rsrqResult);
1362
1363 for (auto it = msg.measResults.measResultListEutra.begin();
1364 it != msg.measResults.measResultListEutra.end();
1365 ++it)
1366 {
1367 NS_LOG_LOGIC("neighbour cellId " << it->physCellId << " RSRP "
1368 << (it->haveRsrpResult ? (uint16_t)it->rsrpResult : 255)
1369 << " RSRQ "
1370 << (it->haveRsrqResult ? (uint16_t)it->rsrqResult : 255));
1371 }
1372
1373 if ((m_rrc->m_handoverManagementSapProvider != nullptr) &&
1374 (m_rrc->m_handoverMeasIds.find(measId) != m_rrc->m_handoverMeasIds.end()))
1375 {
1376 // this measurement was requested by the handover algorithm
1377 m_rrc->m_handoverManagementSapProvider->ReportUeMeas(m_rnti, msg.measResults);
1378 }
1379
1380 if ((m_rrc->m_ccmRrcSapProvider != nullptr) &&
1381 (m_rrc->m_componentCarrierMeasIds.find(measId) != m_rrc->m_componentCarrierMeasIds.end()))
1382 {
1383 // this measurement was requested by the handover algorithm
1384 m_rrc->m_ccmRrcSapProvider->ReportUeMeas(m_rnti, msg.measResults);
1385 }
1386
1387 if ((m_rrc->m_anrSapProvider != nullptr) &&
1388 (m_rrc->m_anrMeasIds.find(measId) != m_rrc->m_anrMeasIds.end()))
1389 {
1390 // this measurement was requested by the ANR function
1391 m_rrc->m_anrSapProvider->ReportUeMeas(msg.measResults);
1392 }
1393
1396 m_rrc->m_ccmRrcSapProvider->ReportUeMeas(m_rnti, msg.measResults);
1397 // fire a trace source
1398 m_rrc->m_recvMeasurementReportTrace(m_imsi,
1399 m_rrc->ComponentCarrierToCellId(m_componentCarrierId),
1400 m_rnti,
1401 msg);
1402
1403} // end of NrUeManager::RecvMeasurementReport
1404
1405// methods forwarded from CMAC SAP
1406
1407void
1409{
1410 NS_LOG_FUNCTION(this << m_rnti);
1411 // at this stage used only by the scheduler for updating txMode
1412
1413 m_physicalConfigDedicated.antennaInfo.transmissionMode = cmacParams.m_transmissionMode;
1414
1415 m_needPhyMacConfiguration = true;
1416
1417 // reconfigure the UE RRC
1419}
1420
1421// methods forwarded from PDCP SAP
1422
1423void
1425{
1426 NS_LOG_FUNCTION(this);
1427 if (params.lcid > 2)
1428 {
1429 // data radio bearer
1430 NrEpsBearerTag tag;
1431 tag.SetRnti(params.rnti);
1432 tag.SetBid(Lcid2Bid(params.lcid));
1433 params.pdcpSdu->AddPacketTag(tag);
1434 m_rrc->m_forwardUpCallback(params.pdcpSdu);
1435 }
1436}
1437
1438uint16_t
1440{
1441 return m_rnti;
1442}
1443
1444uint64_t
1446{
1447 return m_imsi;
1448}
1449
1450uint8_t
1452{
1453 return m_componentCarrierId;
1454}
1455
1456uint16_t
1458{
1459 return m_physicalConfigDedicated.soundingRsUlConfigDedicated.srsConfigIndex;
1460}
1461
1462void
1464{
1465 NS_LOG_FUNCTION(this);
1466 m_physicalConfigDedicated.soundingRsUlConfigDedicated.srsConfigIndex = srsConfIndex;
1467 for (uint16_t i = 0; i < m_rrc->m_numberOfComponentCarriers; i++)
1468 {
1469 m_rrc->m_cphySapProvider.at(i)->SetSrsConfigurationIndex(m_rnti, srsConfIndex);
1470 }
1471 switch (m_state)
1472 {
1473 case INITIAL_RANDOM_ACCESS:
1474 // do nothing, srs conf index will be correctly enforced upon
1475 // RRC connection establishment
1476 break;
1477
1478 default:
1480 break;
1481 }
1482}
1483
1486{
1487 return m_state;
1488}
1489
1490void
1492{
1493 NS_LOG_FUNCTION(this);
1494 m_physicalConfigDedicated.pdschConfigDedicated = pdschConfigDedicated;
1495
1496 m_needPhyMacConfiguration = true;
1497
1498 // reconfigure the UE RRC
1500}
1501
1502void
1504{
1505 NS_LOG_FUNCTION(this);
1506 m_connectionRequestTimeout.Cancel();
1507 m_connectionRejectedTimeout.Cancel();
1508 m_connectionSetupTimeout.Cancel();
1509 m_handoverJoiningTimeout.Cancel();
1510 m_handoverLeavingTimeout.Cancel();
1511}
1512
1515{
1516 NS_LOG_FUNCTION(this);
1518 res.oldGnbUeX2apId = m_sourceX2apId;
1519 res.sourceCellId = m_sourceCellId;
1520 res.targetCellId = m_rrc->ComponentCarrierToCellId(m_componentCarrierId);
1521 res.cause = 0;
1522 res.criticalityDiagnostics = 0;
1523
1524 return res;
1525}
1526
1529{
1530 NS_LOG_FUNCTION(this);
1532 res.oldGnbUeX2apId = m_rnti; // source cell rnti
1533 res.newGnbUeX2apId = m_targetX2apId;
1534 res.sourceCellId = m_rrc->ComponentCarrierToCellId(m_componentCarrierId);
1535 res.targetCellId = m_targetCellId;
1536 res.cause = 0;
1537
1538 return res;
1539}
1540
1541uint8_t
1542NrUeManager::AddDataRadioBearerInfo(Ptr<NrDataRadioBearerInfo> drbInfo)
1543{
1544 NS_LOG_FUNCTION(this);
1545 const uint8_t MAX_DRB_ID = 32;
1546 for (int drbid = (m_lastAllocatedDrbid + 1) % MAX_DRB_ID; drbid != m_lastAllocatedDrbid;
1547 drbid = (drbid + 1) % MAX_DRB_ID)
1548 {
1549 if (drbid != 0) // 0 is not allowed
1550 {
1551 if (m_drbMap.find(drbid) == m_drbMap.end())
1552 {
1553 m_drbMap.insert(std::pair<uint8_t, Ptr<NrDataRadioBearerInfo>>(drbid, drbInfo));
1554 drbInfo->m_drbIdentity = drbid;
1555 m_lastAllocatedDrbid = drbid;
1556 return drbid;
1557 }
1558 }
1559 }
1560 NS_FATAL_ERROR("no more data radio bearer ids available");
1561 return 0;
1562}
1563
1564Ptr<NrDataRadioBearerInfo>
1565NrUeManager::GetDataRadioBearerInfo(uint8_t drbid)
1566{
1567 NS_LOG_FUNCTION(this << (uint32_t)drbid);
1568 NS_ASSERT(0 != drbid);
1569 auto it = m_drbMap.find(drbid);
1570 NS_ABORT_IF(it == m_drbMap.end());
1571 return it->second;
1572}
1573
1574void
1575NrUeManager::RemoveDataRadioBearerInfo(uint8_t drbid)
1576{
1577 NS_LOG_FUNCTION(this << (uint32_t)drbid);
1578 auto it = m_drbMap.find(drbid);
1579 NS_ASSERT_MSG(it != m_drbMap.end(),
1580 "request to remove radio bearer with unknown drbid " << drbid);
1581 m_drbMap.erase(it);
1582}
1583
1584NrRrcSap::RrcConnectionReconfiguration
1585NrUeManager::BuildRrcConnectionReconfiguration()
1586{
1587 NS_LOG_FUNCTION(this);
1588 NrRrcSap::RrcConnectionReconfiguration msg{};
1589 msg.rrcTransactionIdentifier = GetNewRrcTransactionIdentifier();
1590 msg.haveRadioResourceConfigDedicated = true;
1591 msg.radioResourceConfigDedicated = BuildRadioResourceConfigDedicated();
1592 msg.haveMobilityControlInfo = false;
1593 msg.haveMeasConfig = true;
1594 msg.measConfig = m_rrc->m_ueMeasConfig;
1595 if (!m_caSupportConfigured && m_rrc->m_numberOfComponentCarriers > 1)
1596 {
1597 m_caSupportConfigured = true;
1598 NS_LOG_FUNCTION(this << "CA not configured. Configure now!");
1599 msg.haveNonCriticalExtension = true;
1600 msg.nonCriticalExtension = BuildNonCriticalExtensionConfigurationCa();
1601 NS_LOG_FUNCTION(this << " haveNonCriticalExtension " << msg.haveNonCriticalExtension);
1602 }
1603 else
1604 {
1605 msg.haveNonCriticalExtension = false;
1606 }
1607
1608 return msg;
1609}
1610
1611NrRrcSap::RadioResourceConfigDedicated
1612NrUeManager::BuildRadioResourceConfigDedicated()
1613{
1614 NS_LOG_FUNCTION(this);
1615 NrRrcSap::RadioResourceConfigDedicated rrcd;
1616
1617 if (m_srb1)
1618 {
1619 NrRrcSap::SrbToAddMod stam;
1620 stam.srbIdentity = m_srb1->m_srbIdentity;
1621 stam.logicalChannelConfig = m_srb1->m_logicalChannelConfig;
1622 rrcd.srbToAddModList.push_back(stam);
1623 }
1624
1625 for (auto it = m_drbMap.begin(); it != m_drbMap.end(); ++it)
1626 {
1627 NrRrcSap::DrbToAddMod dtam;
1628 dtam.epsBearerIdentity = it->second->m_epsBearerIdentity;
1629 dtam.drbIdentity = it->second->m_drbIdentity;
1630 dtam.rlcConfig = it->second->m_rlcConfig;
1631 dtam.logicalChannelIdentity = it->second->m_logicalChannelIdentity;
1632 dtam.logicalChannelConfig = it->second->m_logicalChannelConfig;
1633 rrcd.drbToAddModList.push_back(dtam);
1634 }
1635
1636 rrcd.havePhysicalConfigDedicated = true;
1637 rrcd.physicalConfigDedicated = m_physicalConfigDedicated;
1638 return rrcd;
1639}
1640
1641uint8_t
1642NrUeManager::GetNewRrcTransactionIdentifier()
1643{
1644 NS_LOG_FUNCTION(this);
1645 ++m_lastRrcTransactionIdentifier;
1646 m_lastRrcTransactionIdentifier %= 4;
1647 return m_lastRrcTransactionIdentifier;
1648}
1649
1650uint8_t
1651NrUeManager::Lcid2Drbid(uint8_t lcid)
1652{
1653 NS_ASSERT(lcid > 2);
1654 return lcid - 2;
1655}
1656
1657uint8_t
1658NrUeManager::Drbid2Lcid(uint8_t drbid)
1659{
1660 return drbid + 2;
1661}
1662
1663uint8_t
1664NrUeManager::Lcid2Bid(uint8_t lcid)
1665{
1666 NS_ASSERT(lcid > 2);
1667 return lcid - 2;
1668}
1669
1670uint8_t
1671NrUeManager::Bid2Lcid(uint8_t bid)
1672{
1673 return bid + 2;
1674}
1675
1676uint8_t
1677NrUeManager::Drbid2Bid(uint8_t drbid)
1678{
1679 return drbid;
1680}
1681
1682uint8_t
1683NrUeManager::Bid2Drbid(uint8_t bid)
1684{
1685 return bid;
1686}
1687
1688void
1689NrUeManager::SwitchToState(State newState)
1690{
1691 NS_LOG_FUNCTION(this << ToString(newState));
1692 State oldState = m_state;
1693 m_state = newState;
1694 NS_LOG_INFO(this << " IMSI " << m_imsi << " RNTI " << m_rnti << " NrUeManager "
1695 << ToString(oldState) << " --> " << ToString(newState));
1696 m_stateTransitionTrace(m_imsi,
1697 m_rrc->ComponentCarrierToCellId(m_componentCarrierId),
1698 m_rnti,
1699 oldState,
1700 newState);
1701
1702 switch (newState)
1703 {
1704 case INITIAL_RANDOM_ACCESS:
1705 case HANDOVER_JOINING:
1706 NS_FATAL_ERROR("cannot switch to an initial state");
1707 break;
1708
1709 case CONNECTION_SETUP:
1710 case ATTACH_REQUEST:
1711 break;
1712
1713 case CONNECTED_NORMALLY: {
1714 if (m_pendingRrcConnectionReconfiguration)
1715 {
1717 }
1718 if (m_pendingStartDataRadioBearers && m_caSupportConfigured)
1719 {
1721 }
1722 }
1723 break;
1724
1725 case CONNECTION_RECONFIGURATION:
1726 case CONNECTION_REESTABLISHMENT:
1727 case HANDOVER_LEAVING:
1728 default:
1729 break;
1730 }
1731}
1732
1733NrRrcSap::NonCriticalExtensionConfiguration
1734NrUeManager::BuildNonCriticalExtensionConfigurationCa()
1735{
1736 NS_LOG_FUNCTION(this);
1737 NrRrcSap::NonCriticalExtensionConfiguration ncec;
1738
1739 for (auto& it : m_rrc->m_componentCarrierPhyConf)
1740 {
1741 uint8_t ccId = it.first;
1742
1743 if (ccId == m_componentCarrierId)
1744 {
1745 // Skip primary CC.
1746 continue;
1747 }
1748 else if (ccId < m_componentCarrierId)
1749 {
1750 // Shift all IDs below PCC forward so PCC can use CC ID 1.
1751 ccId++;
1752 }
1753
1754 Ptr<BandwidthPartGnb> eNbCcm = it.second;
1755 NrRrcSap::SCellToAddMod component;
1756 component.sCellIndex = ccId;
1757 component.cellIdentification.physCellId = eNbCcm->GetCellId();
1758 component.cellIdentification.dlCarrierFreq = eNbCcm->GetDlEarfcn();
1759 component.radioResourceConfigCommonSCell.haveNonUlConfiguration = true;
1760 component.radioResourceConfigCommonSCell.nonUlConfiguration.dlBandwidth =
1761 eNbCcm->GetDlBandwidth();
1762 component.radioResourceConfigCommonSCell.nonUlConfiguration.antennaInfoCommon
1763 .antennaPortsCount = 0;
1764 component.radioResourceConfigCommonSCell.nonUlConfiguration.pdschConfigCommon
1765 .referenceSignalPower = m_rrc->m_cphySapProvider.at(0)->GetReferenceSignalPower();
1766 component.radioResourceConfigCommonSCell.nonUlConfiguration.pdschConfigCommon.pb = 0;
1767 component.radioResourceConfigCommonSCell.haveUlConfiguration = true;
1768 component.radioResourceConfigCommonSCell.ulConfiguration.ulFreqInfo.ulCarrierFreq =
1769 eNbCcm->GetUlEarfcn();
1770 component.radioResourceConfigCommonSCell.ulConfiguration.ulFreqInfo.ulBandwidth =
1771 eNbCcm->GetUlBandwidth();
1772 component.radioResourceConfigCommonSCell.ulConfiguration.ulPowerControlCommonSCell.alpha =
1773 0;
1774 // component.radioResourceConfigCommonSCell.ulConfiguration.soundingRsUlConfigCommon.type =
1775 // NrRrcSap::SoundingRsUlConfigDedicated::SETUP;
1776 component.radioResourceConfigCommonSCell.ulConfiguration.soundingRsUlConfigCommon
1777 .srsBandwidthConfig = 0;
1778 component.radioResourceConfigCommonSCell.ulConfiguration.soundingRsUlConfigCommon
1779 .srsSubframeConfig = 0;
1780 component.radioResourceConfigCommonSCell.ulConfiguration.prachConfigSCell.index = 0;
1781
1782 component.haveRadioResourceConfigDedicatedSCell = true;
1783 component.radioResourceConfigDedicatedSCell.physicalConfigDedicatedSCell
1784 .haveNonUlConfiguration = true;
1785 component.radioResourceConfigDedicatedSCell.physicalConfigDedicatedSCell
1786 .haveAntennaInfoDedicated = true;
1787 component.radioResourceConfigDedicatedSCell.physicalConfigDedicatedSCell.antennaInfo
1788 .transmissionMode = m_rrc->m_defaultTransmissionMode;
1789 component.radioResourceConfigDedicatedSCell.physicalConfigDedicatedSCell
1790 .crossCarrierSchedulingConfig = false;
1791 component.radioResourceConfigDedicatedSCell.physicalConfigDedicatedSCell
1792 .havePdschConfigDedicated = true;
1793 component.radioResourceConfigDedicatedSCell.physicalConfigDedicatedSCell
1794 .pdschConfigDedicated.pa = NrRrcSap::PdschConfigDedicated::dB0;
1795 component.radioResourceConfigDedicatedSCell.physicalConfigDedicatedSCell
1796 .haveUlConfiguration = true;
1797 component.radioResourceConfigDedicatedSCell.physicalConfigDedicatedSCell
1798 .haveAntennaInfoUlDedicated = true;
1799 component.radioResourceConfigDedicatedSCell.physicalConfigDedicatedSCell.antennaInfoUl
1800 .transmissionMode = m_rrc->m_defaultTransmissionMode;
1801 component.radioResourceConfigDedicatedSCell.physicalConfigDedicatedSCell
1802 .pushConfigDedicatedSCell.nPuschIdentity = 0;
1803 component.radioResourceConfigDedicatedSCell.physicalConfigDedicatedSCell
1804 .ulPowerControlDedicatedSCell.pSrsOffset = 0;
1805 component.radioResourceConfigDedicatedSCell.physicalConfigDedicatedSCell
1806 .haveSoundingRsUlConfigDedicated = true;
1807 component.radioResourceConfigDedicatedSCell.physicalConfigDedicatedSCell
1808 .soundingRsUlConfigDedicated.srsConfigIndex = GetSrsConfigurationIndex();
1809 component.radioResourceConfigDedicatedSCell.physicalConfigDedicatedSCell
1810 .soundingRsUlConfigDedicated.type = NrRrcSap::SoundingRsUlConfigDedicated::SETUP;
1811 component.radioResourceConfigDedicatedSCell.physicalConfigDedicatedSCell
1812 .soundingRsUlConfigDedicated.srsBandwidth = 0;
1813
1814 ncec.sCellToAddModList.push_back(component);
1815 }
1816
1817 return ncec;
1818}
1819
1821// gNB RRC methods
1823
1824NS_OBJECT_ENSURE_REGISTERED(NrGnbRrc);
1825
1827 : m_x2SapProvider(nullptr),
1828 m_cmacSapProvider(0),
1829 m_handoverManagementSapProvider(nullptr),
1830 m_ccmRrcSapProvider(nullptr),
1831 m_anrSapProvider(nullptr),
1832 m_rrcSapUser(nullptr),
1833 m_macSapProvider(nullptr),
1834 m_s1SapProvider(nullptr),
1835 m_cphySapProvider(0),
1836 m_configured(false),
1837 m_lastAllocatedRnti(0),
1838 m_lastAllocatedConfigurationIndex(0),
1839 m_reconfigureUes(false),
1840 m_numberOfComponentCarriers(0),
1841 m_carriersConfigured(false)
1842{
1843 NS_LOG_FUNCTION(this);
1844 m_cmacSapUser.push_back(new GnbRrcMemberNrGnbCmacSapUser(this, 0));
1845 m_handoverManagementSapUser = new MemberNrHandoverManagementSapUser<NrGnbRrc>(this);
1846 m_anrSapUser = new MemberNrAnrSapUser<NrGnbRrc>(this);
1847 m_rrcSapProvider = new MemberNrGnbRrcSapProvider<NrGnbRrc>(this);
1848 m_x2SapUser = new NrEpcX2SpecificEpcX2SapUser<NrGnbRrc>(this);
1849 m_s1SapUser = new NrMemberEpcGnbS1SapUser<NrGnbRrc>(this);
1850 m_cphySapUser.push_back(new MemberNrGnbCphySapUser<NrGnbRrc>(this));
1851 m_ccmRrcSapUser = new MemberNrCcmRrcSapUser<NrGnbRrc>(this);
1852}
1853
1854void
1855NrGnbRrc::ConfigureCarriers(std::map<uint8_t, Ptr<BandwidthPartGnb>> ccPhyConf)
1856{
1857 NS_ASSERT_MSG(!m_carriersConfigured, "Secondary carriers can be configured only once.");
1858 m_componentCarrierPhyConf = ccPhyConf;
1859 NS_ABORT_MSG_IF(m_numberOfComponentCarriers != m_componentCarrierPhyConf.size(),
1860 " Number of component carriers "
1861 "are not equal to the number of he component carrier configuration provided");
1862
1863 for (uint16_t i = 1; i < m_numberOfComponentCarriers; i++)
1864 {
1865 m_cphySapUser.push_back(new MemberNrGnbCphySapUser<NrGnbRrc>(this));
1866 m_cmacSapUser.push_back(new GnbRrcMemberNrGnbCmacSapUser(this, i));
1867 }
1868 m_carriersConfigured = true;
1869 Object::DoInitialize();
1870}
1871
1873{
1874 NS_LOG_FUNCTION(this);
1875}
1876
1877void
1878NrGnbRrc::DoDispose()
1879{
1880 NS_LOG_FUNCTION(this);
1881 for (uint16_t i = 0; i < m_numberOfComponentCarriers; i++)
1882 {
1883 delete m_cphySapUser[i];
1884 delete m_cmacSapUser[i];
1885 }
1886 // delete m_cphySapUser;
1887 m_cphySapUser.erase(m_cphySapUser.begin(), m_cphySapUser.end());
1888 m_cphySapUser.clear();
1889 // delete m_cmacSapUser;
1890 m_cmacSapUser.erase(m_cmacSapUser.begin(), m_cmacSapUser.end());
1891 m_cmacSapUser.clear();
1892 m_ueMap.clear();
1893 delete m_handoverManagementSapUser;
1894 delete m_ccmRrcSapUser;
1895 delete m_anrSapUser;
1896 delete m_rrcSapProvider;
1897 delete m_x2SapUser;
1898 delete m_s1SapUser;
1899}
1900
1901TypeId
1903{
1904 static TypeId tid =
1905 TypeId("ns3::NrGnbRrc")
1906 .SetParent<Object>()
1907 .SetGroupName("Nr")
1908 .AddConstructor<NrGnbRrc>()
1909 .AddAttribute("UeMap",
1910 "List of NrUeManager by C-RNTI.",
1911 ObjectMapValue(),
1912 MakeObjectMapAccessor(&NrGnbRrc::m_ueMap),
1913 MakeObjectMapChecker<NrUeManager>())
1914 .AddAttribute("DefaultTransmissionMode",
1915 "The default UEs' transmission mode (0: SISO)",
1916 UintegerValue(0), // default tx-mode
1917 MakeUintegerAccessor(&NrGnbRrc::m_defaultTransmissionMode),
1918 MakeUintegerChecker<uint8_t>())
1919 .AddAttribute(
1920 "EpsBearerToRlcMapping",
1921 "Specify which type of RLC will be used for each type of EPS bearer.",
1922 EnumValue(RLC_SM_ALWAYS),
1923 MakeEnumAccessor<NrEpsBearerToRlcMapping_t>(&NrGnbRrc::m_epsBearerToRlcMapping),
1924 MakeEnumChecker(RLC_SM_ALWAYS,
1925 "RlcSmAlways",
1926 RLC_UM_ALWAYS,
1927 "RlcUmAlways",
1928 RLC_AM_ALWAYS,
1929 "RlcAmAlways",
1930 PER_BASED,
1931 "PacketErrorRateBased"))
1932 .AddAttribute("SystemInformationPeriodicity",
1933 "The interval for sending system information (Time value)",
1934 TimeValue(MilliSeconds(80)),
1935 MakeTimeAccessor(&NrGnbRrc::m_systemInformationPeriodicity),
1936 MakeTimeChecker())
1937
1938 // Timeout related attributes
1939 .AddAttribute("ConnectionRequestTimeoutDuration",
1940 "After a RA attempt, if no RRC CONNECTION REQUEST is "
1941 "received before this time, the UE context is destroyed. "
1942 "Must account for reception of RAR and transmission of "
1943 "RRC CONNECTION REQUEST over UL GRANT. The value of this"
1944 "timer should not be greater than T300 timer at UE RRC",
1945 TimeValue(MilliSeconds(15)),
1946 MakeTimeAccessor(&NrGnbRrc::m_connectionRequestTimeoutDuration),
1947 MakeTimeChecker(MilliSeconds(1), MilliSeconds(15)))
1948 .AddAttribute("ConnectionSetupTimeoutDuration",
1949 "After accepting connection request, if no RRC CONNECTION "
1950 "SETUP COMPLETE is received before this time, the UE "
1951 "context is destroyed. Must account for the UE's reception "
1952 "of RRC CONNECTION SETUP and transmission of RRC CONNECTION "
1953 "SETUP COMPLETE.",
1954 TimeValue(MilliSeconds(150)),
1955 MakeTimeAccessor(&NrGnbRrc::m_connectionSetupTimeoutDuration),
1956 MakeTimeChecker())
1957 .AddAttribute("ConnectionRejectedTimeoutDuration",
1958 "Time to wait between sending a RRC CONNECTION REJECT and "
1959 "destroying the UE context",
1960 TimeValue(MilliSeconds(30)),
1961 MakeTimeAccessor(&NrGnbRrc::m_connectionRejectedTimeoutDuration),
1962 MakeTimeChecker())
1963 .AddAttribute("HandoverJoiningTimeoutDuration",
1964 "After accepting a handover request, if no RRC CONNECTION "
1965 "RECONFIGURATION COMPLETE is received before this time, the "
1966 "UE context is destroyed. Must account for reception of "
1967 "X2 HO REQ ACK by source eNB, transmission of the Handover "
1968 "Command, non-contention-based random access and reception "
1969 "of the RRC CONNECTION RECONFIGURATION COMPLETE message.",
1970 TimeValue(MilliSeconds(200)),
1971 MakeTimeAccessor(&NrGnbRrc::m_handoverJoiningTimeoutDuration),
1972 MakeTimeChecker())
1973 .AddAttribute("HandoverLeavingTimeoutDuration",
1974 "After issuing a Handover Command, if neither RRC "
1975 "CONNECTION RE-ESTABLISHMENT nor X2 UE Context Release has "
1976 "been previously received, the UE context is destroyed.",
1977 TimeValue(MilliSeconds(500)),
1978 MakeTimeAccessor(&NrGnbRrc::m_handoverLeavingTimeoutDuration),
1979 MakeTimeChecker())
1980
1981 // Cell selection related attribute
1982 .AddAttribute("QRxLevMin",
1983 "One of information transmitted within the SIB1 message, "
1984 "indicating the required minimum RSRP level that any UE must "
1985 "receive from this cell before it is allowed to camp to this "
1986 "cell. The default value -70 corresponds to -140 dBm and is "
1987 "the lowest possible value as defined by Section 6.3.4 of "
1988 "3GPP TS 36.133. This restriction, however, only applies to "
1989 "initial cell selection and EPC-enabled simulation.",
1990 TypeId::ATTR_GET | TypeId::ATTR_CONSTRUCT,
1991 IntegerValue(-70),
1992 MakeIntegerAccessor(&NrGnbRrc::m_qRxLevMin),
1993 MakeIntegerChecker<int8_t>(-70, -22))
1994 .AddAttribute("NumberOfComponentCarriers",
1995 "Number of Component Carriers",
1996 UintegerValue(1),
1997 MakeIntegerAccessor(&NrGnbRrc::m_numberOfComponentCarriers),
1998 MakeIntegerChecker<int16_t>(nr::MIN_NO_CC, nr::MAX_NO_CC))
1999
2000 // Handover related attributes
2001 .AddAttribute("AdmitHandoverRequest",
2002 "Whether to admit an X2 handover request from another eNB",
2003 BooleanValue(true),
2004 MakeBooleanAccessor(&NrGnbRrc::m_admitHandoverRequest),
2005 MakeBooleanChecker())
2006 .AddAttribute("AdmitRrcConnectionRequest",
2007 "Whether to admit a connection request from a UE",
2008 BooleanValue(true),
2009 MakeBooleanAccessor(&NrGnbRrc::m_admitRrcConnectionRequest),
2010 MakeBooleanChecker())
2011
2012 // UE measurements related attributes
2013 .AddAttribute("RsrpFilterCoefficient",
2014 "Determines the strength of smoothing effect induced by "
2015 "layer 3 filtering of RSRP in all attached UE; "
2016 "if set to 0, no layer 3 filtering is applicable",
2017 // i.e. the variable k in 3GPP TS 36.331 section 5.5.3.2
2018 UintegerValue(4),
2019 MakeUintegerAccessor(&NrGnbRrc::m_rsrpFilterCoefficient),
2020 MakeUintegerChecker<uint8_t>(0))
2021 .AddAttribute("RsrqFilterCoefficient",
2022 "Determines the strength of smoothing effect induced by "
2023 "layer 3 filtering of RSRQ in all attached UE; "
2024 "if set to 0, no layer 3 filtering is applicable",
2025 // i.e. the variable k in 3GPP TS 36.331 section 5.5.3.2
2026 UintegerValue(4),
2027 MakeUintegerAccessor(&NrGnbRrc::m_rsrqFilterCoefficient),
2028 MakeUintegerChecker<uint8_t>(0))
2029
2030 // Trace sources
2031 .AddTraceSource("NewUeContext",
2032 "Fired upon creation of a new UE context.",
2033 MakeTraceSourceAccessor(&NrGnbRrc::m_newUeContextTrace),
2034 "ns3::NrGnbRrc::NewUeContextTracedCallback")
2035 .AddTraceSource("ConnectionEstablished",
2036 "Fired upon successful RRC connection establishment.",
2037 MakeTraceSourceAccessor(&NrGnbRrc::m_connectionEstablishedTrace),
2038 "ns3::NrGnbRrc::ConnectionHandoverTracedCallback")
2039 .AddTraceSource("ConnectionReconfiguration",
2040 "trace fired upon RRC connection reconfiguration",
2041 MakeTraceSourceAccessor(&NrGnbRrc::m_connectionReconfigurationTrace),
2042 "ns3::NrGnbRrc::ConnectionHandoverTracedCallback")
2043 .AddTraceSource("HandoverStart",
2044 "trace fired upon start of a handover procedure",
2045 MakeTraceSourceAccessor(&NrGnbRrc::m_handoverStartTrace),
2046 "ns3::NrGnbRrc::HandoverStartTracedCallback")
2047 .AddTraceSource("HandoverEndOk",
2048 "trace fired upon successful termination of a handover procedure",
2049 MakeTraceSourceAccessor(&NrGnbRrc::m_handoverEndOkTrace),
2050 "ns3::NrGnbRrc::ConnectionHandoverTracedCallback")
2051 .AddTraceSource("RecvMeasurementReport",
2052 "trace fired when measurement report is received",
2053 MakeTraceSourceAccessor(&NrGnbRrc::m_recvMeasurementReportTrace),
2054 "ns3::NrGnbRrc::ReceiveReportTracedCallback")
2055 .AddTraceSource("NotifyConnectionRelease",
2056 "trace fired when an UE is released",
2057 MakeTraceSourceAccessor(&NrGnbRrc::m_connectionReleaseTrace),
2058 "ns3::NrGnbRrc::ConnectionHandoverTracedCallback")
2059 .AddTraceSource("RrcTimeout",
2060 "trace fired when a timer expires",
2061 MakeTraceSourceAccessor(&NrGnbRrc::m_rrcTimeoutTrace),
2062 "ns3::NrGnbRrc::TimerExpiryTracedCallback")
2063 .AddTraceSource(
2064 "HandoverFailureNoPreamble",
2065 "trace fired upon handover failure due to non-allocation of non-contention based "
2066 "preamble at gNB for UE to handover due to max count reached",
2067 MakeTraceSourceAccessor(&NrGnbRrc::m_handoverFailureNoPreambleTrace),
2068 "ns3::NrGnbRrc::HandoverFailureTracedCallback")
2069 .AddTraceSource(
2070 "HandoverFailureMaxRach",
2071 "trace fired upon handover failure due to max RACH attempts from UE to target eNB",
2072 MakeTraceSourceAccessor(&NrGnbRrc::m_handoverFailureMaxRachTrace),
2073 "ns3::NrGnbRrc::HandoverFailureTracedCallback")
2074 .AddTraceSource(
2075 "HandoverFailureLeaving",
2076 "trace fired upon handover failure due to handover leaving timeout at source eNB",
2077 MakeTraceSourceAccessor(&NrGnbRrc::m_handoverFailureLeavingTrace),
2078 "ns3::NrGnbRrc::HandoverFailureTracedCallback")
2079 .AddTraceSource(
2080 "HandoverFailureJoining",
2081 "trace fired upon handover failure due to handover joining timeout at target eNB",
2082 MakeTraceSourceAccessor(&NrGnbRrc::m_handoverFailureJoiningTrace),
2083 "ns3::NrGnbRrc::HandoverFailureTracedCallback");
2084 return tid;
2085}
2086
2087void
2089{
2090 NS_LOG_FUNCTION(this << s);
2091 m_x2SapProvider = s;
2092}
2093
2096{
2097 NS_LOG_FUNCTION(this);
2098 return m_x2SapUser;
2099}
2100
2101void
2103{
2104 NS_LOG_FUNCTION(this << s);
2105 m_cmacSapProvider.at(0) = s;
2106}
2107
2108void
2110{
2111 NS_LOG_FUNCTION(this << s);
2112 if (m_cmacSapProvider.size() > pos)
2113 {
2114 m_cmacSapProvider.at(pos) = s;
2115 }
2116 else
2117 {
2118 m_cmacSapProvider.push_back(s);
2119 NS_ABORT_IF(m_cmacSapProvider.size() - 1 != pos);
2120 }
2121}
2122
2125{
2126 NS_LOG_FUNCTION(this);
2127 return m_cmacSapUser.at(0);
2128}
2129
2132{
2133 NS_LOG_FUNCTION(this);
2134 return m_cmacSapUser.at(pos);
2135}
2136
2137void
2139{
2140 NS_LOG_FUNCTION(this << s);
2141 m_handoverManagementSapProvider = s;
2142}
2143
2146{
2147 NS_LOG_FUNCTION(this);
2148 return m_handoverManagementSapUser;
2149}
2150
2151void
2153{
2154 NS_LOG_FUNCTION(this << s);
2155 m_ccmRrcSapProvider = s;
2156}
2157
2160{
2161 NS_LOG_FUNCTION(this);
2162 return m_ccmRrcSapUser;
2163}
2164
2165void
2167{
2168 NS_LOG_FUNCTION(this << s);
2169 m_anrSapProvider = s;
2170}
2171
2174{
2175 NS_LOG_FUNCTION(this);
2176 return m_anrSapUser;
2177}
2178
2179void
2181{
2182 NS_LOG_FUNCTION(this << s);
2183 m_rrcSapUser = s;
2184}
2185
2188{
2189 NS_LOG_FUNCTION(this);
2190 return m_rrcSapProvider;
2191}
2192
2193void
2195{
2196 NS_LOG_FUNCTION(this);
2197 m_macSapProvider = s;
2198}
2199
2200void
2202{
2203 m_s1SapProvider = s;
2204}
2205
2208{
2209 return m_s1SapUser;
2210}
2211
2212void
2214{
2215 NS_LOG_FUNCTION(this << s);
2216 if (!m_cphySapProvider.empty())
2217 {
2218 m_cphySapProvider.at(0) = s;
2219 }
2220 else
2221 {
2222 m_cphySapProvider.push_back(s);
2223 }
2224}
2225
2228{
2229 NS_LOG_FUNCTION(this);
2230 return m_cphySapUser.at(0);
2231}
2232
2233void
2235{
2236 NS_LOG_FUNCTION(this << s);
2237 if (m_cphySapProvider.size() > pos)
2238 {
2239 m_cphySapProvider.at(pos) = s;
2240 }
2241 else
2242 {
2243 m_cphySapProvider.push_back(s);
2244 NS_ABORT_IF(m_cphySapProvider.size() - 1 != pos);
2245 }
2246}
2247
2250{
2251 NS_LOG_FUNCTION(this);
2252 return m_cphySapUser.at(pos);
2253}
2254
2255bool
2256NrGnbRrc::HasUeManager(uint16_t rnti) const
2257{
2258 NS_LOG_FUNCTION(this << (uint32_t)rnti);
2259 auto it = m_ueMap.find(rnti);
2260 return (it != m_ueMap.end());
2261}
2262
2263Ptr<NrUeManager>
2265{
2266 NS_LOG_FUNCTION(this << (uint32_t)rnti);
2267 NS_ASSERT(0 != rnti);
2268 auto it = m_ueMap.find(rnti);
2269 NS_ASSERT_MSG(it != m_ueMap.end(), "UE manager for RNTI " << rnti << " not found");
2270 return it->second;
2271}
2272
2273std::vector<uint8_t>
2275{
2276 NS_LOG_FUNCTION(this);
2277
2278 // SANITY CHECK
2279
2280 NS_ASSERT_MSG(
2281 m_ueMeasConfig.measIdToAddModList.size() ==
2282 m_ueMeasConfig.reportConfigToAddModList.size() * m_numberOfComponentCarriers,
2283 "Measurement identities and reporting configuration should not have different quantity");
2284
2285 if (Simulator::Now() != Seconds(0))
2286 {
2287 NS_FATAL_ERROR("AddUeMeasReportConfig may not be called after the simulation has run");
2288 }
2289
2290 // INPUT VALIDATION
2291
2292 switch (config.triggerQuantity)
2293 {
2297 {
2298 NS_FATAL_ERROR(
2299 "The given triggerQuantity (RSRP) does not match with the given threshold2.choice");
2300 }
2301
2307 {
2308 NS_FATAL_ERROR(
2309 "The given triggerQuantity (RSRP) does not match with the given threshold1.choice");
2310 }
2311 break;
2312
2316 {
2317 NS_FATAL_ERROR(
2318 "The given triggerQuantity (RSRQ) does not match with the given threshold2.choice");
2319 }
2320
2326 {
2327 NS_FATAL_ERROR(
2328 "The given triggerQuantity (RSRQ) does not match with the given threshold1.choice");
2329 }
2330 break;
2331
2332 default:
2333 NS_FATAL_ERROR("unsupported triggerQuantity");
2334 break;
2335 }
2336
2337 if (config.purpose != NrRrcSap::ReportConfigEutra::REPORT_STRONGEST_CELLS)
2338 {
2339 NS_FATAL_ERROR("Only REPORT_STRONGEST_CELLS purpose is supported");
2340 }
2341
2343 {
2344 NS_LOG_WARN("reportQuantity = BOTH will be used instead of the given reportQuantity");
2345 }
2346
2347 uint8_t nextId = m_ueMeasConfig.reportConfigToAddModList.size() + 1;
2348
2349 // create the reporting configuration
2350 NrRrcSap::ReportConfigToAddMod reportConfig;
2351 reportConfig.reportConfigId = nextId;
2352 reportConfig.reportConfigEutra = config;
2353
2354 // add reporting configuration to UE measurement configuration
2355 m_ueMeasConfig.reportConfigToAddModList.push_back(reportConfig);
2356
2357 std::vector<uint8_t> measIds;
2358
2359 // create measurement identities, linking reporting configuration to all objects
2360 for (uint16_t BandwidthPartGnb = 0; BandwidthPartGnb < m_numberOfComponentCarriers;
2362 {
2363 NrRrcSap::MeasIdToAddMod measIdToAddMod;
2364
2365 uint8_t measId = m_ueMeasConfig.measIdToAddModList.size() + 1;
2366
2367 measIdToAddMod.measId = measId;
2368 measIdToAddMod.measObjectId = BandwidthPartGnb + 1;
2369 measIdToAddMod.reportConfigId = nextId;
2370
2371 m_ueMeasConfig.measIdToAddModList.push_back(measIdToAddMod);
2372 measIds.push_back(measId);
2373 }
2374
2375 return measIds;
2376}
2377
2378void
2379NrGnbRrc::ConfigureCell(const std::map<uint8_t, Ptr<BandwidthPartGnb>>& ccPhyConf)
2380{
2381 auto it = ccPhyConf.begin();
2382 NS_ASSERT(it != ccPhyConf.end());
2383 uint16_t ulBandwidth = it->second->GetUlBandwidth();
2384 uint16_t dlBandwidth = it->second->GetDlBandwidth();
2385 uint32_t ulEarfcn = it->second->GetUlEarfcn();
2386 uint32_t dlEarfcn = it->second->GetDlEarfcn();
2387 NS_LOG_FUNCTION(this << ulBandwidth << dlBandwidth << ulEarfcn << dlEarfcn);
2388 NS_ASSERT_MSG(!m_configured, "NrGnbRrc::ConfigureCell called more than once");
2389
2390 for (const auto& it : ccPhyConf)
2391 {
2392 m_cphySapProvider.at(it.first)->SetBandwidth(it.second->GetUlBandwidth(),
2393 it.second->GetDlBandwidth());
2394 m_cphySapProvider.at(it.first)->SetEarfcn(it.second->GetUlEarfcn(),
2395 it.second->GetDlEarfcn());
2396 m_cphySapProvider.at(it.first)->SetCellId(it.second->GetCellId());
2397 m_cmacSapProvider.at(it.first)->ConfigureMac(it.second->GetUlBandwidth(),
2398 it.second->GetDlBandwidth());
2399 }
2400
2401 m_dlEarfcn = dlEarfcn;
2402 m_ulEarfcn = ulEarfcn;
2403 m_dlBandwidth = dlBandwidth;
2404 m_ulBandwidth = ulBandwidth;
2405
2406 /*
2407 * Initializing the list of measurement objects.
2408 * Only intra-frequency measurements are supported,
2409 * so one measurement object is created for each carrier frequency.
2410 */
2411 for (const auto& it : ccPhyConf)
2412 {
2414 measObject.measObjectId = it.first + 1;
2415 measObject.measObjectEutra.carrierFreq = it.second->GetDlEarfcn();
2416 measObject.measObjectEutra.allowedMeasBandwidth = it.second->GetDlBandwidth();
2417 measObject.measObjectEutra.presenceAntennaPort1 = false;
2418 measObject.measObjectEutra.neighCellConfig = 0;
2419 measObject.measObjectEutra.offsetFreq = 0;
2421
2422 m_ueMeasConfig.measObjectToAddModList.push_back(measObject);
2423 }
2424
2425 m_ueMeasConfig.haveQuantityConfig = true;
2426 m_ueMeasConfig.quantityConfig.filterCoefficientRSRP = m_rsrpFilterCoefficient;
2427 m_ueMeasConfig.quantityConfig.filterCoefficientRSRQ = m_rsrqFilterCoefficient;
2428 m_ueMeasConfig.haveMeasGapConfig = false;
2429 m_ueMeasConfig.haveSmeasure = false;
2430 m_ueMeasConfig.haveSpeedStatePars = false;
2431
2432 m_sib1.clear();
2433 m_sib1.reserve(ccPhyConf.size());
2434 for (const auto& it : ccPhyConf)
2435 {
2436 // Enabling MIB transmission
2438 mib.numerology = it.second->GetPhy()->GetNumerology();
2439 mib.dlBandwidth = it.second->GetDlBandwidth();
2440 mib.systemFrameNumber = 0;
2441 m_cphySapProvider.at(it.first)->SetMasterInformationBlock(mib);
2442
2443 // Enabling SIB1 transmission with default values
2445 sib1.cellAccessRelatedInfo.cellIdentity = it.second->GetCellId();
2449 sib1.cellSelectionInfo.qQualMin = -34; // not used, set as minimum value
2450 sib1.cellSelectionInfo.qRxLevMin = m_qRxLevMin; // set as minimum value
2451 m_sib1.push_back(sib1);
2452 m_cphySapProvider.at(it.first)->SetSystemInformationBlockType1(sib1);
2453 }
2454 /*
2455 * Enabling transmission of other SIB. The first time System Information is
2456 * transmitted is arbitrarily assumed to be at +0.016s, and then it will be
2457 * regularly transmitted every 80 ms by default (set the
2458 * SystemInformationPeriodicity attribute to configure this).
2459 */
2460 Simulator::Schedule(MilliSeconds(16), &NrGnbRrc::SendSystemInformation, this);
2461
2462 m_configured = true;
2463}
2464
2465void
2466NrGnbRrc::SetCellId(uint16_t cellId)
2467{
2468 // update SIB1
2469 m_sib1.at(0).cellAccessRelatedInfo.cellIdentity = cellId;
2470 m_cphySapProvider.at(0)->SetSystemInformationBlockType1(m_sib1.at(0));
2471}
2472
2473void
2474NrGnbRrc::SetCellId(uint16_t cellId, uint8_t ccIndex)
2475{
2476 // update SIB1
2477 m_sib1.at(ccIndex).cellAccessRelatedInfo.cellIdentity = cellId;
2478 m_cphySapProvider.at(ccIndex)->SetSystemInformationBlockType1(m_sib1.at(ccIndex));
2479}
2480
2481uint8_t
2483{
2484 NS_LOG_FUNCTION(this << cellId);
2485 for (auto& it : m_componentCarrierPhyConf)
2486 {
2487 if (it.second->GetCellId() == cellId)
2488 {
2489 return it.first;
2490 }
2491 }
2492 NS_FATAL_ERROR("Cell " << cellId << " not found in CC map");
2493}
2494
2495uint16_t
2496NrGnbRrc::ComponentCarrierToCellId(uint8_t componentCarrierId)
2497{
2498 NS_LOG_FUNCTION(this << +componentCarrierId);
2499 return m_componentCarrierPhyConf.at(componentCarrierId)->GetCellId();
2500}
2501
2502bool
2503NrGnbRrc::HasCellId(uint16_t cellId) const
2504{
2505 for (auto& it : m_componentCarrierPhyConf)
2506 {
2507 if (it.second->GetCellId() == cellId)
2508 {
2509 return true;
2510 }
2511 }
2512 return false;
2513}
2514
2515bool
2516NrGnbRrc::SendData(Ptr<Packet> packet)
2517{
2518 NS_LOG_FUNCTION(this << packet);
2519 NrEpsBearerTag tag;
2520 bool found = packet->RemovePacketTag(tag);
2521 NS_ASSERT_MSG(found, "no NrEpsBearerTag found in packet to be sent");
2522 Ptr<NrUeManager> ueManager = GetUeManager(tag.GetRnti());
2523
2524 NS_LOG_INFO("Sending a packet of " << packet->GetSize() << " bytes to IMSI "
2525 << ueManager->GetImsi() << ", RNTI " << ueManager->GetRnti()
2526 << ", BID " << (uint16_t)tag.GetBid());
2527 ueManager->SendData(tag.GetBid(), packet);
2528
2529 return true;
2530}
2531
2532void
2533NrGnbRrc::SetForwardUpCallback(Callback<void, Ptr<Packet>> cb)
2534{
2535 m_forwardUpCallback = cb;
2536}
2537
2538void
2540{
2541 NS_LOG_FUNCTION(this << rnti);
2542 NS_ASSERT_MSG(GetUeManager(rnti)->GetState() == NrUeManager::INITIAL_RANDOM_ACCESS,
2543 "ConnectionRequestTimeout in unexpected state "
2544 << ToString(GetUeManager(rnti)->GetState()));
2545 m_rrcTimeoutTrace(GetUeManager(rnti)->GetImsi(),
2546 rnti,
2547 ComponentCarrierToCellId(GetUeManager(rnti)->GetComponentCarrierId()),
2548 "ConnectionRequestTimeout");
2549 RemoveUe(rnti);
2550}
2551
2552void
2554{
2555 NS_LOG_FUNCTION(this << rnti);
2556 NS_ASSERT_MSG(GetUeManager(rnti)->GetState() == NrUeManager::CONNECTION_SETUP,
2557 "ConnectionSetupTimeout in unexpected state "
2558 << ToString(GetUeManager(rnti)->GetState()));
2559 m_rrcTimeoutTrace(GetUeManager(rnti)->GetImsi(),
2560 rnti,
2561 ComponentCarrierToCellId(GetUeManager(rnti)->GetComponentCarrierId()),
2562 "ConnectionSetupTimeout");
2563 RemoveUe(rnti);
2564}
2565
2566void
2568{
2569 NS_LOG_FUNCTION(this << rnti);
2570 NS_ASSERT_MSG(GetUeManager(rnti)->GetState() == NrUeManager::CONNECTION_REJECTED,
2571 "ConnectionRejectedTimeout in unexpected state "
2572 << ToString(GetUeManager(rnti)->GetState()));
2573 m_rrcTimeoutTrace(GetUeManager(rnti)->GetImsi(),
2574 rnti,
2575 ComponentCarrierToCellId(GetUeManager(rnti)->GetComponentCarrierId()),
2576 "ConnectionRejectedTimeout");
2577 RemoveUe(rnti);
2578}
2579
2580void
2582{
2583 NS_LOG_FUNCTION(this << rnti);
2584 NS_ASSERT_MSG(GetUeManager(rnti)->GetState() == NrUeManager::HANDOVER_JOINING,
2585 "HandoverJoiningTimeout in unexpected state "
2586 << ToString(GetUeManager(rnti)->GetState()));
2587 m_handoverFailureJoiningTrace(
2588 GetUeManager(rnti)->GetImsi(),
2589 rnti,
2590 ComponentCarrierToCellId(GetUeManager(rnti)->GetComponentCarrierId()));
2591 // check if the RNTI to be removed is not stale
2592 if (HasUeManager(rnti))
2593 {
2601 Ptr<NrUeManager> ueManager = GetUeManager(rnti);
2602 NrEpcX2Sap::HandoverPreparationFailureParams msg = ueManager->BuildHoPrepFailMsg();
2603 m_x2SapProvider->SendHandoverPreparationFailure(msg);
2604 RemoveUe(rnti);
2605 }
2606}
2607
2608void
2610{
2611 NS_LOG_FUNCTION(this << rnti);
2612 NS_ASSERT_MSG(GetUeManager(rnti)->GetState() == NrUeManager::HANDOVER_LEAVING,
2613 "HandoverLeavingTimeout in unexpected state "
2614 << ToString(GetUeManager(rnti)->GetState()));
2615 m_handoverFailureLeavingTrace(
2616 GetUeManager(rnti)->GetImsi(),
2617 rnti,
2618 ComponentCarrierToCellId(GetUeManager(rnti)->GetComponentCarrierId()));
2619 // check if the RNTI to be removed is not stale
2620 if (HasUeManager(rnti))
2621 {
2627 Ptr<NrUeManager> ueManager = GetUeManager(rnti);
2628 NrEpcX2Sap::HandoverCancelParams msg = ueManager->BuildHoCancelMsg();
2629 m_x2SapProvider->SendHandoverCancel(msg);
2630 ueManager->SendRrcConnectionRelease();
2631 }
2632}
2633
2634void
2635NrGnbRrc::SendHandoverRequest(uint16_t rnti, uint16_t cellId)
2636{
2637 NS_LOG_FUNCTION(this << rnti << cellId);
2638 NS_LOG_LOGIC("Request to send HANDOVER REQUEST");
2639 NS_ASSERT(m_configured);
2640
2641 Ptr<NrUeManager> ueManager = GetUeManager(rnti);
2642 ueManager->PrepareHandover(cellId);
2643}
2644
2645void
2646NrGnbRrc::DoCompleteSetupUe(uint16_t rnti, NrGnbRrcSapProvider::CompleteSetupUeParameters params)
2647{
2648 NS_LOG_FUNCTION(this << rnti);
2649 GetUeManager(rnti)->CompleteSetupUe(params);
2650}
2651
2652void
2653NrGnbRrc::DoRecvRrcConnectionRequest(uint16_t rnti, NrRrcSap::RrcConnectionRequest msg)
2654{
2655 NS_LOG_FUNCTION(this << rnti);
2656 GetUeManager(rnti)->RecvRrcConnectionRequest(msg);
2657}
2658
2659void
2660NrGnbRrc::DoRecvRrcConnectionSetupCompleted(uint16_t rnti,
2661 NrRrcSap::RrcConnectionSetupCompleted msg)
2662{
2663 NS_LOG_FUNCTION(this << rnti);
2664 GetUeManager(rnti)->RecvRrcConnectionSetupCompleted(msg);
2665}
2666
2667void
2668NrGnbRrc::DoRecvRrcConnectionReconfigurationCompleted(
2669 uint16_t rnti,
2670 NrRrcSap::RrcConnectionReconfigurationCompleted msg)
2671{
2672 NS_LOG_FUNCTION(this << rnti);
2673 GetUeManager(rnti)->RecvRrcConnectionReconfigurationCompleted(msg);
2674}
2675
2676void
2677NrGnbRrc::DoRecvRrcConnectionReestablishmentRequest(
2678 uint16_t rnti,
2679 NrRrcSap::RrcConnectionReestablishmentRequest msg)
2680{
2681 NS_LOG_FUNCTION(this << rnti);
2682 GetUeManager(rnti)->RecvRrcConnectionReestablishmentRequest(msg);
2683}
2684
2685void
2686NrGnbRrc::DoRecvRrcConnectionReestablishmentComplete(
2687 uint16_t rnti,
2688 NrRrcSap::RrcConnectionReestablishmentComplete msg)
2689{
2690 NS_LOG_FUNCTION(this << rnti);
2691 GetUeManager(rnti)->RecvRrcConnectionReestablishmentComplete(msg);
2692}
2693
2694void
2695NrGnbRrc::DoRecvMeasurementReport(uint16_t rnti, NrRrcSap::MeasurementReport msg)
2696{
2697 NS_LOG_FUNCTION(this << rnti);
2698 GetUeManager(rnti)->RecvMeasurementReport(msg);
2699}
2700
2701void
2702NrGnbRrc::DoInitialContextSetupRequest(NrEpcGnbS1SapUser::InitialContextSetupRequestParameters msg)
2703{
2704 NS_LOG_FUNCTION(this);
2705 Ptr<NrUeManager> ueManager = GetUeManager(msg.rnti);
2706 ueManager->InitialContextSetupRequest();
2707}
2708
2709void
2710NrGnbRrc::DoRecvIdealUeContextRemoveRequest(uint16_t rnti)
2711{
2712 NS_LOG_FUNCTION(this << rnti);
2713
2714 // check if the RNTI to be removed is not stale
2715 if (HasUeManager(rnti))
2716 {
2717 Ptr<NrUeManager> ueManager = GetUeManager(rnti);
2718
2719 if (ueManager->GetState() == NrUeManager::HANDOVER_JOINING)
2720 {
2721 m_handoverFailureMaxRachTrace(
2722 GetUeManager(rnti)->GetImsi(),
2723 rnti,
2724 ComponentCarrierToCellId(GetUeManager(rnti)->GetComponentCarrierId()));
2731 NrEpcX2Sap::HandoverPreparationFailureParams msg = ueManager->BuildHoPrepFailMsg();
2732 m_x2SapProvider->SendHandoverPreparationFailure(msg);
2733 }
2734
2735 GetUeManager(rnti)->RecvIdealUeContextRemoveRequest(rnti);
2736 // delete the UE context at the eNB
2737 RemoveUe(rnti);
2738 }
2739}
2740
2741void
2742NrGnbRrc::DoDataRadioBearerSetupRequest(
2743 NrEpcGnbS1SapUser::DataRadioBearerSetupRequestParameters request)
2744{
2745 NS_LOG_FUNCTION(this);
2746 Ptr<NrUeManager> ueManager = GetUeManager(request.rnti);
2747 ueManager->SetupDataRadioBearer(request.bearer,
2748 request.bearerId,
2749 request.gtpTeid,
2750 request.transportLayerAddress);
2751}
2752
2753void
2754NrGnbRrc::DoPathSwitchRequestAcknowledge(
2755 NrEpcGnbS1SapUser::PathSwitchRequestAcknowledgeParameters params)
2756{
2757 NS_LOG_FUNCTION(this);
2758 Ptr<NrUeManager> ueManager = GetUeManager(params.rnti);
2759 ueManager->SendUeContextRelease();
2760}
2761
2762void
2763NrGnbRrc::DoRecvHandoverRequest(NrEpcX2SapUser::HandoverRequestParams req)
2764{
2765 NS_LOG_FUNCTION(this);
2766
2767 NS_LOG_LOGIC("Recv X2 message: HANDOVER REQUEST");
2768
2769 NS_LOG_LOGIC("oldGnbUeX2apId = " << req.oldGnbUeX2apId);
2770 NS_LOG_LOGIC("sourceCellId = " << req.sourceCellId);
2771 NS_LOG_LOGIC("targetCellId = " << req.targetCellId);
2772 NS_LOG_LOGIC("mmeUeS1apId = " << req.mmeUeS1apId);
2773
2774 // if no SRS index is available, then do not accept the handover
2775 if (!m_admitHandoverRequest || IsMaxSrsReached())
2776 {
2777 NS_LOG_INFO("rejecting handover request from cellId " << req.sourceCellId);
2778 NrEpcX2Sap::HandoverPreparationFailureParams res;
2779 res.oldGnbUeX2apId = req.oldGnbUeX2apId;
2780 res.sourceCellId = req.sourceCellId;
2781 res.targetCellId = req.targetCellId;
2782 res.cause = 0;
2783 res.criticalityDiagnostics = 0;
2784 m_x2SapProvider->SendHandoverPreparationFailure(res);
2785 return;
2786 }
2787
2788 uint8_t componentCarrierId = CellToComponentCarrierId(req.targetCellId);
2789 uint16_t rnti = AddUe(NrUeManager::HANDOVER_JOINING, componentCarrierId);
2790 Ptr<NrUeManager> ueManager = GetUeManager(rnti);
2791 ueManager->SetSource(req.sourceCellId, req.oldGnbUeX2apId);
2792 ueManager->SetImsi(req.mmeUeS1apId);
2793 NrGnbCmacSapProvider::AllocateNcRaPreambleReturnValue anrcrv =
2794 m_cmacSapProvider.at(componentCarrierId)->AllocateNcRaPreamble(rnti);
2795 if (!anrcrv.valid)
2796 {
2797 NS_LOG_INFO(
2798 this
2799 << " failed to allocate a preamble for non-contention based RA => cannot accept HO");
2800 m_handoverFailureNoPreambleTrace(
2801 GetUeManager(rnti)->GetImsi(),
2802 rnti,
2803 ComponentCarrierToCellId(GetUeManager(rnti)->GetComponentCarrierId()));
2809 Ptr<NrUeManager> ueManager = GetUeManager(rnti);
2810 NrEpcX2Sap::HandoverPreparationFailureParams msg = ueManager->BuildHoPrepFailMsg();
2811 m_x2SapProvider->SendHandoverPreparationFailure(msg);
2812 RemoveUe(rnti); // remove the UE from the target eNB
2813 return;
2814 }
2815
2816 NrEpcX2SapProvider::HandoverRequestAckParams ackParams;
2817 ackParams.oldGnbUeX2apId = req.oldGnbUeX2apId;
2818 ackParams.newGnbUeX2apId = rnti;
2819 ackParams.sourceCellId = req.sourceCellId;
2820 ackParams.targetCellId = req.targetCellId;
2821
2822 for (auto it = req.bearers.begin(); it != req.bearers.end(); ++it)
2823 {
2824 ueManager->SetupDataRadioBearer(it->erabLevelQosParameters,
2825 it->erabId,
2826 it->gtpTeid,
2827 it->transportLayerAddress);
2828 NrEpcX2Sap::ErabAdmittedItem i;
2829 i.erabId = it->erabId;
2830 ackParams.admittedBearers.push_back(i);
2831 }
2832
2833 NrRrcSap::RrcConnectionReconfiguration handoverCommand =
2834 ueManager->GetRrcConnectionReconfigurationForHandover(componentCarrierId);
2835
2836 handoverCommand.mobilityControlInfo.newUeIdentity = rnti;
2837 handoverCommand.mobilityControlInfo.haveRachConfigDedicated = true;
2838 handoverCommand.mobilityControlInfo.rachConfigDedicated.raPreambleIndex = anrcrv.raPreambleId;
2839 handoverCommand.mobilityControlInfo.rachConfigDedicated.raPrachMaskIndex =
2840 anrcrv.raPrachMaskIndex;
2841
2842 NrGnbCmacSapProvider::RachConfig rc = m_cmacSapProvider.at(componentCarrierId)->GetRachConfig();
2843 handoverCommand.mobilityControlInfo.radioResourceConfigCommon.rachConfigCommon.preambleInfo
2844 .numberOfRaPreambles = rc.numberOfRaPreambles;
2845 handoverCommand.mobilityControlInfo.radioResourceConfigCommon.rachConfigCommon.raSupervisionInfo
2846 .preambleTransMax = rc.preambleTransMax;
2847 handoverCommand.mobilityControlInfo.radioResourceConfigCommon.rachConfigCommon.raSupervisionInfo
2848 .raResponseWindowSize = rc.raResponseWindowSize;
2849 handoverCommand.mobilityControlInfo.radioResourceConfigCommon.rachConfigCommon.txFailParam
2850 .connEstFailCount = rc.connEstFailCount;
2851
2852 Ptr<Packet> encodedHandoverCommand = m_rrcSapUser->EncodeHandoverCommand(handoverCommand);
2853
2854 ackParams.rrcContext = encodedHandoverCommand;
2855
2856 NS_LOG_LOGIC("Send X2 message: HANDOVER REQUEST ACK");
2857
2858 NS_LOG_LOGIC("oldGnbUeX2apId = " << ackParams.oldGnbUeX2apId);
2859 NS_LOG_LOGIC("newGnbUeX2apId = " << ackParams.newGnbUeX2apId);
2860 NS_LOG_LOGIC("sourceCellId = " << ackParams.sourceCellId);
2861 NS_LOG_LOGIC("targetCellId = " << ackParams.targetCellId);
2862
2863 m_x2SapProvider->SendHandoverRequestAck(ackParams);
2864}
2865
2866void
2867NrGnbRrc::DoRecvHandoverRequestAck(NrEpcX2SapUser::HandoverRequestAckParams params)
2868{
2869 NS_LOG_FUNCTION(this);
2870
2871 NS_LOG_LOGIC("Recv X2 message: HANDOVER REQUEST ACK");
2872
2873 NS_LOG_LOGIC("oldGnbUeX2apId = " << params.oldGnbUeX2apId);
2874 NS_LOG_LOGIC("newGnbUeX2apId = " << params.newGnbUeX2apId);
2875 NS_LOG_LOGIC("sourceCellId = " << params.sourceCellId);
2876 NS_LOG_LOGIC("targetCellId = " << params.targetCellId);
2877
2878 uint16_t rnti = params.oldGnbUeX2apId;
2879 Ptr<NrUeManager> ueManager = GetUeManager(rnti);
2880 ueManager->RecvHandoverRequestAck(params);
2881}
2882
2883void
2884NrGnbRrc::DoRecvHandoverPreparationFailure(NrEpcX2SapUser::HandoverPreparationFailureParams params)
2885{
2886 NS_LOG_FUNCTION(this);
2887
2888 NS_LOG_LOGIC("Recv X2 message: HANDOVER PREPARATION FAILURE");
2889
2890 NS_LOG_LOGIC("oldGnbUeX2apId = " << params.oldGnbUeX2apId);
2891 NS_LOG_LOGIC("sourceCellId = " << params.sourceCellId);
2892 NS_LOG_LOGIC("targetCellId = " << params.targetCellId);
2893 NS_LOG_LOGIC("cause = " << params.cause);
2894 NS_LOG_LOGIC("criticalityDiagnostics = " << params.criticalityDiagnostics);
2895
2896 uint16_t rnti = params.oldGnbUeX2apId;
2897
2898 // check if the RNTI is not stale
2899 if (HasUeManager(rnti))
2900 {
2901 Ptr<NrUeManager> ueManager = GetUeManager(rnti);
2902 ueManager->RecvHandoverPreparationFailure(params.targetCellId);
2903 }
2904}
2905
2906void
2907NrGnbRrc::DoRecvSnStatusTransfer(NrEpcX2SapUser::SnStatusTransferParams params)
2908{
2909 NS_LOG_FUNCTION(this);
2910
2911 NS_LOG_LOGIC("Recv X2 message: SN STATUS TRANSFER");
2912
2913 NS_LOG_LOGIC("oldGnbUeX2apId = " << params.oldGnbUeX2apId);
2914 NS_LOG_LOGIC("newGnbUeX2apId = " << params.newGnbUeX2apId);
2915 NS_LOG_LOGIC("erabsSubjectToStatusTransferList size = "
2916 << params.erabsSubjectToStatusTransferList.size());
2917
2918 uint16_t rnti = params.newGnbUeX2apId;
2919
2920 // check if the RNTI to receive SN transfer for is not stale
2921 if (HasUeManager(rnti))
2922 {
2923 Ptr<NrUeManager> ueManager = GetUeManager(rnti);
2924 ueManager->RecvSnStatusTransfer(params);
2925 }
2926}
2927
2928void
2929NrGnbRrc::DoRecvUeContextRelease(NrEpcX2SapUser::UeContextReleaseParams params)
2930{
2931 NS_LOG_FUNCTION(this);
2932
2933 NS_LOG_LOGIC("Recv X2 message: UE CONTEXT RELEASE");
2934
2935 NS_LOG_LOGIC("oldGnbUeX2apId = " << params.oldGnbUeX2apId);
2936 NS_LOG_LOGIC("newGnbUeX2apId = " << params.newGnbUeX2apId);
2937
2938 uint16_t rnti = params.oldGnbUeX2apId;
2939
2940 // check if the RNTI to be removed is not stale
2941 if (HasUeManager(rnti))
2942 {
2943 GetUeManager(rnti)->RecvUeContextRelease(params);
2944 RemoveUe(rnti);
2945 }
2946}
2947
2948void
2949NrGnbRrc::DoRecvLoadInformation(NrEpcX2SapUser::LoadInformationParams params)
2950{
2951 NS_LOG_FUNCTION(this);
2952
2953 NS_LOG_LOGIC("Recv X2 message: LOAD INFORMATION");
2954
2955 NS_LOG_LOGIC("Number of cellInformationItems = " << params.cellInformationList.size());
2956}
2957
2958void
2959NrGnbRrc::DoRecvResourceStatusUpdate(NrEpcX2SapUser::ResourceStatusUpdateParams params)
2960{
2961 NS_LOG_FUNCTION(this);
2962
2963 NS_LOG_LOGIC("Recv X2 message: RESOURCE STATUS UPDATE");
2964
2965 NS_LOG_LOGIC(
2966 "Number of cellMeasurementResultItems = " << params.cellMeasurementResultList.size());
2967
2968 NS_ASSERT("Processing of RESOURCE STATUS UPDATE X2 message IS NOT IMPLEMENTED");
2969}
2970
2971void
2972NrGnbRrc::DoRecvUeData(NrEpcX2SapUser::UeDataParams params)
2973{
2974 NS_LOG_FUNCTION(this);
2975
2976 NS_LOG_LOGIC("Recv UE DATA FORWARDING through X2 interface");
2977 NS_LOG_LOGIC("sourceCellId = " << params.sourceCellId);
2978 NS_LOG_LOGIC("targetCellId = " << params.targetCellId);
2979 NS_LOG_LOGIC("gtpTeid = " << params.gtpTeid);
2980 NS_LOG_LOGIC("ueData = " << params.ueData);
2981 NS_LOG_LOGIC("ueData size = " << params.ueData->GetSize());
2982
2983 auto teidInfoIt = m_x2uTeidInfoMap.find(params.gtpTeid);
2984 if (teidInfoIt != m_x2uTeidInfoMap.end())
2985 {
2986 GetUeManager(teidInfoIt->second.rnti)->SendData(teidInfoIt->second.drbid, params.ueData);
2987 }
2988 else
2989 {
2990 NS_FATAL_ERROR("X2-U data received but no X2uTeidInfo found");
2991 }
2992}
2993
2994void
2995NrGnbRrc::DoRecvHandoverCancel(NrEpcX2SapUser::HandoverCancelParams params)
2996{
2997 NS_LOG_FUNCTION(this);
2998
2999 NS_LOG_LOGIC("Recv X2 message: HANDOVER CANCEL");
3000
3001 NS_LOG_LOGIC("oldGnbUeX2apId = " << params.oldGnbUeX2apId);
3002 NS_LOG_LOGIC("newGnbUeX2apId = " << params.newGnbUeX2apId);
3003 NS_LOG_LOGIC("sourceCellId = " << params.sourceCellId);
3004 NS_LOG_LOGIC("targetCellId = " << params.targetCellId);
3005 NS_LOG_LOGIC("cause = " << params.cause);
3006
3007 uint16_t rnti = params.newGnbUeX2apId;
3008 if (HasUeManager(rnti))
3009 {
3010 Ptr<NrUeManager> ueManager = GetUeManager(rnti);
3011 ueManager->RecvHandoverCancel(params);
3012 GetUeManager(rnti)->RecvIdealUeContextRemoveRequest(rnti);
3013 }
3014}
3015
3016uint16_t
3017NrGnbRrc::DoAllocateTemporaryCellRnti(uint8_t componentCarrierId)
3018{
3019 NS_LOG_FUNCTION(this << +componentCarrierId);
3020 // if no SRS index is available, then do not create a new UE context.
3021 if (IsMaxSrsReached())
3022 {
3023 NS_LOG_WARN("Not enough SRS configuration indices, UE context not created");
3024 return 0; // return 0 since new RNTI was not assigned for the received preamble
3025 }
3026 return AddUe(NrUeManager::INITIAL_RANDOM_ACCESS, componentCarrierId);
3027}
3028
3029void
3030NrGnbRrc::DoRrcConfigurationUpdateInd(NrGnbCmacSapUser::UeConfig cmacParams)
3031{
3032 Ptr<NrUeManager> ueManager = GetUeManager(cmacParams.m_rnti);
3033 ueManager->CmacUeConfigUpdateInd(cmacParams);
3034}
3035
3036void
3037NrGnbRrc::DoNotifyLcConfigResult(uint16_t rnti, uint8_t lcid, bool success)
3038{
3039 NS_LOG_FUNCTION(this << (uint32_t)rnti);
3040 NS_FATAL_ERROR("not implemented");
3041}
3042
3043std::vector<uint8_t>
3044NrGnbRrc::DoAddUeMeasReportConfigForHandover(NrRrcSap::ReportConfigEutra reportConfig)
3045{
3046 NS_LOG_FUNCTION(this);
3047 std::vector<uint8_t> measIds = AddUeMeasReportConfig(reportConfig);
3048 m_handoverMeasIds.insert(measIds.begin(), measIds.end());
3049 return measIds;
3050}
3051
3052uint8_t
3053NrGnbRrc::DoAddUeMeasReportConfigForComponentCarrier(NrRrcSap::ReportConfigEutra reportConfig)
3054{
3055 NS_LOG_FUNCTION(this);
3056 uint8_t measId = AddUeMeasReportConfig(reportConfig).at(0);
3057 m_componentCarrierMeasIds.insert(measId);
3058 return measId;
3059}
3060
3061void
3062NrGnbRrc::DoSetNumberOfComponentCarriers(uint16_t numberOfComponentCarriers)
3063{
3064 m_numberOfComponentCarriers = numberOfComponentCarriers;
3065}
3066
3067void
3068NrGnbRrc::DoTriggerHandover(uint16_t rnti, uint16_t targetCellId)
3069{
3070 NS_LOG_FUNCTION(this << rnti << targetCellId);
3071
3072 bool isHandoverAllowed = true;
3073
3074 Ptr<NrUeManager> ueManager = GetUeManager(rnti);
3075 NS_ASSERT_MSG(ueManager, "Cannot find UE context with RNTI " << rnti);
3076
3077 if (m_anrSapProvider != nullptr && !HasCellId(targetCellId))
3078 {
3079 // ensure that proper neighbour relationship exists between source and target cells
3080 bool noHo = m_anrSapProvider->GetNoHo(targetCellId);
3081 bool noX2 = m_anrSapProvider->GetNoX2(targetCellId);
3082 NS_LOG_DEBUG(this << " cellId="
3083 << ComponentCarrierToCellId(ueManager->GetComponentCarrierId())
3084 << " targetCellId=" << targetCellId << " NRT.NoHo=" << noHo
3085 << " NRT.NoX2=" << noX2);
3086
3087 if (noHo || noX2)
3088 {
3089 isHandoverAllowed = false;
3090 NS_LOG_LOGIC(this << " handover to cell " << targetCellId << " is not allowed by ANR");
3091 }
3092 }
3093
3094 if (ueManager->GetState() != NrUeManager::CONNECTED_NORMALLY)
3095 {
3096 isHandoverAllowed = false;
3097 NS_LOG_LOGIC(this << " handover is not allowed because the UE"
3098 << " rnti=" << rnti << " is in " << ToString(ueManager->GetState())
3099 << " state");
3100 }
3101
3102 if (isHandoverAllowed)
3103 {
3104 // initiate handover execution
3105 ueManager->PrepareHandover(targetCellId);
3106 }
3107}
3108
3109uint8_t
3110NrGnbRrc::DoAddUeMeasReportConfigForAnr(NrRrcSap::ReportConfigEutra reportConfig)
3111{
3112 NS_LOG_FUNCTION(this);
3113 uint8_t measId = AddUeMeasReportConfig(reportConfig).at(0);
3114 m_anrMeasIds.insert(measId);
3115 return measId;
3116}
3117
3118void
3119NrGnbRrc::DoSetPdschConfigDedicated(uint16_t rnti,
3120 NrRrcSap::PdschConfigDedicated pdschConfigDedicated)
3121{
3122 NS_LOG_FUNCTION(this);
3123 Ptr<NrUeManager> ueManager = GetUeManager(rnti);
3124 ueManager->SetPdschConfigDedicated(pdschConfigDedicated);
3125}
3126
3127void
3128NrGnbRrc::DoSendLoadInformation(NrEpcX2Sap::LoadInformationParams params)
3129{
3130 NS_LOG_FUNCTION(this);
3131
3132 m_x2SapProvider->SendLoadInformation(params);
3133}
3134
3135uint16_t
3136NrGnbRrc::AddUe(NrUeManager::State state, uint8_t componentCarrierId)
3137{
3138 NS_LOG_FUNCTION(this);
3139 bool found = false;
3140 uint16_t rnti;
3141 for (rnti = m_lastAllocatedRnti + 1; (rnti != m_lastAllocatedRnti - 1) && (!found); ++rnti)
3142 {
3143 if ((rnti != 0) && (m_ueMap.find(rnti) == m_ueMap.end()))
3144 {
3145 found = true;
3146 break;
3147 }
3148 }
3149
3150 NS_ASSERT_MSG(found, "no more RNTIs available (do you have more than 65535 UEs in a cell?)");
3151 m_lastAllocatedRnti = rnti;
3152 Ptr<NrUeManager> ueManager = CreateObject<NrUeManager>(this, rnti, state, componentCarrierId);
3153 m_ccmRrcSapProvider->AddUe(rnti, (uint8_t)state);
3154 m_ueMap.insert(std::pair<uint16_t, Ptr<NrUeManager>>(rnti, ueManager));
3155 ueManager->Configure();
3156 const uint16_t cellId = ComponentCarrierToCellId(componentCarrierId);
3157 NS_LOG_DEBUG(this << " New UE RNTI " << rnti << " cellId " << cellId << " srs CI "
3158 << ueManager->GetSrsConfigurationIndex());
3159 m_newUeContextTrace(cellId, rnti);
3160 return rnti;
3161}
3162
3163void
3164NrGnbRrc::RemoveUe(uint16_t rnti)
3165{
3166 NS_LOG_FUNCTION(this << (uint32_t)rnti);
3167 auto it = m_ueMap.find(rnti);
3168 NS_ASSERT_MSG(it != m_ueMap.end(), "request to remove UE info with unknown rnti " << rnti);
3169 uint64_t imsi = it->second->GetImsi();
3170 uint16_t srsCi = (*it).second->GetSrsConfigurationIndex();
3171 // cancel pending events
3172 it->second->CancelPendingEvents();
3173 // fire trace upon connection release
3174 m_connectionReleaseTrace(imsi,
3175 ComponentCarrierToCellId(it->second->GetComponentCarrierId()),
3176 rnti);
3177 m_ueMap.erase(it);
3178 for (uint16_t i = 0; i < m_numberOfComponentCarriers; i++)
3179 {
3180 m_cmacSapProvider.at(i)->RemoveUe(rnti);
3181 m_cphySapProvider.at(i)->RemoveUe(rnti);
3182 }
3183 if (m_s1SapProvider != nullptr)
3184 {
3185 m_s1SapProvider->UeContextRelease(rnti);
3186 }
3187 m_ccmRrcSapProvider->RemoveUe(rnti);
3188 // need to do this after NrUeManager has been deleted
3189 if (srsCi != 0)
3190 {
3191 RemoveSrsConfigurationIndex(srsCi);
3192 }
3193
3194 m_rrcSapUser->RemoveUe(rnti); // Remove UE context at RRC protocol
3195}
3196
3197TypeId
3198NrGnbRrc::GetRlcType(NrEpsBearer bearer)
3199{
3200 switch (m_epsBearerToRlcMapping)
3201 {
3202 case RLC_SM_ALWAYS:
3203 return NrRlcSm::GetTypeId();
3204
3205 case RLC_UM_ALWAYS:
3206 return NrRlcUm::GetTypeId();
3207
3208 case RLC_AM_ALWAYS:
3209 return NrRlcAm::GetTypeId();
3210
3211 case PER_BASED:
3212 if (bearer.GetPacketErrorLossRate() > 1.0e-5)
3213 {
3214 return NrRlcUm::GetTypeId();
3215 }
3216 else
3217 {
3218 return NrRlcAm::GetTypeId();
3219 }
3220
3221 default:
3222 return NrRlcSm::GetTypeId();
3223 }
3224}
3225
3226void
3228{
3229 NS_LOG_FUNCTION(this << cellId);
3230
3231 if (m_anrSapProvider != nullptr)
3232 {
3233 m_anrSapProvider->AddNeighbourRelation(cellId);
3234 }
3235}
3236
3237void
3238NrGnbRrc::SetCsgId(uint32_t csgId, bool csgIndication)
3239{
3240 NS_LOG_FUNCTION(this << csgId << csgIndication);
3241 for (std::size_t componentCarrierId = 0; componentCarrierId < m_sib1.size();
3242 componentCarrierId++)
3243 {
3244 m_sib1.at(componentCarrierId).cellAccessRelatedInfo.csgIdentity = csgId;
3245 m_sib1.at(componentCarrierId).cellAccessRelatedInfo.csgIndication = csgIndication;
3246 m_cphySapProvider.at(componentCarrierId)
3247 ->SetSystemInformationBlockType1(m_sib1.at(componentCarrierId));
3248 }
3249}
3250
3251uint16_t
3252NrGnbRrc::GetNewSrsConfigurationIndex()
3253{
3254 NS_LOG_FUNCTION(this << m_ueSrsConfigurationIndexSet.size());
3255
3256 uint16_t configIndex = 0;
3257 if (IsMaxSrsReached() && m_unusedUeSrsConfigurationIndexSet.empty())
3258 {
3259 // There are absolutely no more SRS offsets, and SRS periodicity cannot be further
3260 // increased, so we need to interrupt
3261 NS_ABORT_MSG("Out of SRS configuration indices");
3262 }
3263 else if (!IsMaxSrsReached() && m_unusedUeSrsConfigurationIndexSet.empty())
3264 {
3265 // We ran out of configuration indices, but we still can have more
3266 // since we can have more SRS offsets available, so create a new one
3267 configIndex = m_lastAllocatedConfigurationIndex++;
3268 m_ueSrsConfigurationIndexSet.emplace(m_lastAllocatedConfigurationIndex);
3269 }
3270 else
3271 {
3272 // We have available configuration indices, so use them
3273 auto it = m_unusedUeSrsConfigurationIndexSet.begin();
3274 configIndex = *it;
3275 m_unusedUeSrsConfigurationIndexSet.erase(it);
3276 m_ueSrsConfigurationIndexSet.emplace(configIndex);
3277 }
3278 return configIndex;
3279}
3280
3281void
3282NrGnbRrc::RemoveSrsConfigurationIndex(uint16_t srcCi)
3283{
3284 NS_LOG_FUNCTION(this << srcCi);
3285 auto it = m_ueSrsConfigurationIndexSet.find(srcCi);
3286 NS_ASSERT_MSG(it != m_ueSrsConfigurationIndexSet.end(),
3287 "request to remove unknown SRS CI " << srcCi);
3288 m_unusedUeSrsConfigurationIndexSet.emplace(*it);
3289 m_ueSrsConfigurationIndexSet.erase(it);
3290}
3291
3292bool
3293NrGnbRrc::IsMaxSrsReached() const
3294{
3295 return m_cmacSapProvider.at(0)->IsMaxSrsReached();
3296}
3297
3298uint8_t
3299NrGnbRrc::GetLogicalChannelGroup(NrEpsBearer bearer)
3300{
3301 if (bearer.GetResourceType() > 0) // 1, 2 for GBR and DC-GBR
3302 {
3303 return 1;
3304 }
3305 else
3306 {
3307 return 2;
3308 }
3309}
3310
3311uint8_t
3312NrGnbRrc::GetLogicalChannelPriority(NrEpsBearer bearer)
3313{
3314 return bearer.qci;
3315}
3316
3317void
3318NrGnbRrc::SendSystemInformation()
3319{
3320 // NS_LOG_FUNCTION (this);
3321
3322 for (auto& it : m_componentCarrierPhyConf)
3323 {
3324 uint8_t ccId = it.first;
3325
3326 NrRrcSap::SystemInformation si;
3327 si.haveSib2 = true;
3328 si.sib2.freqInfo.ulCarrierFreq = it.second->GetUlEarfcn();
3329 si.sib2.freqInfo.ulBandwidth = it.second->GetUlBandwidth();
3330 si.sib2.radioResourceConfigCommon.pdschConfigCommon.referenceSignalPower =
3331 m_cphySapProvider.at(ccId)->GetReferenceSignalPower();
3332 si.sib2.radioResourceConfigCommon.pdschConfigCommon.pb = 0;
3333
3334 NrGnbCmacSapProvider::RachConfig rc = m_cmacSapProvider.at(ccId)->GetRachConfig();
3335 NrRrcSap::RachConfigCommon rachConfigCommon;
3336 rachConfigCommon.preambleInfo.numberOfRaPreambles = rc.numberOfRaPreambles;
3337 rachConfigCommon.raSupervisionInfo.preambleTransMax = rc.preambleTransMax;
3338 rachConfigCommon.raSupervisionInfo.raResponseWindowSize = rc.raResponseWindowSize;
3339 rachConfigCommon.txFailParam.connEstFailCount = rc.connEstFailCount;
3340 si.sib2.radioResourceConfigCommon.rachConfigCommon = rachConfigCommon;
3341
3342 m_rrcSapUser->SendSystemInformation(it.second->GetCellId(), si);
3343 }
3344
3345 /*
3346 * For simplicity, we use the same periodicity for all SIBs. Note that in real
3347 * systems the periodicy of each SIBs could be different.
3348 */
3349 Simulator::Schedule(m_systemInformationPeriodicity, &NrGnbRrc::SendSystemInformation, this);
3350}
3351
3352bool
3353NrGnbRrc::IsRandomAccessCompleted(uint16_t rnti)
3354{
3355 NS_LOG_FUNCTION(this << (uint32_t)rnti);
3356 Ptr<NrUeManager> ueManager = GetUeManager(rnti);
3357 switch (ueManager->GetState())
3358 {
3359 case NrUeManager::CONNECTED_NORMALLY:
3360 case NrUeManager::CONNECTION_RECONFIGURATION:
3361 return true;
3362 default:
3363 return false;
3364 }
3365}
3366
3367} // namespace ns3
GNB bandwidth part representation.
Service Access Point (SAP) offered by the ANR instance to the eNodeB RRC instance.
Definition nr-anr-sap.h:23
virtual bool GetNoX2(uint16_t cellId) const =0
Get the value of No X2 field of a neighbouring cell from the Neighbour Relation Table (NRT).
virtual void AddNeighbourRelation(uint16_t cellId)=0
Add a new Neighbour Relation entry.
virtual bool GetNoHo(uint16_t cellId) const =0
Get the value of No HO field of a neighbouring cell from the Neighbour Relation Table (NRT).
Service Access Point (SAP) offered by the eNodeB RRC instance to the ANR instance.
Definition nr-anr-sap.h:81
Service Access Point (SAP) offered by the Component Carrier Manager (CCM) instance to the eNodeB RRC ...
virtual void RemoveUe(uint16_t rnti)=0
Remove an existing UE.
virtual void AddUe(uint16_t rnti, uint8_t state)=0
Add a new UE in the NrGnbComponentCarrierManager.
Service Access Point (SAP) offered by the eNodeB RRC instance to the component carrier manager (CCM) ...
virtual void UeContextRelease(uint16_t rnti)=0
virtual void DoSendReleaseIndication(uint64_t imsi, uint16_t rnti, uint8_t bearerId)=0
Triggers epc-gnb-application to send ERAB Release Indication message towards MME.
virtual void SendLoadInformation(LoadInformationParams params)=0
virtual void SendHandoverPreparationFailure(HandoverPreparationFailureParams params)=0
virtual void SendHandoverCancel(HandoverCancelParams params)=0
Send handover Cancel to the target gNB.
virtual void SendHandoverRequestAck(HandoverRequestAckParams params)=0
This class contains the specification of EPS Bearers.
uint16_t GetPacketDelayBudgetMs() const
NrGbrQosInformation gbrQosInfo
GBR QOS information.
uint8_t GetResourceType() const
@ GBR_CONV_VOICE
GBR Conversational Voice.
uint16_t GetRnti() const
void SetBid(uint8_t bid)
void SetRnti(uint16_t rnti)
void SetForwardUpCallback(Callback< void, Ptr< Packet > > cb)
friend class NrMemberEpcGnbS1SapUser< NrGnbRrc >
allow MemberNrGnbRrcSapProvider<NrGnbRrc> class friend access
Definition nr-gnb-rrc.h:687
void ConfigureCarriers(std::map< uint8_t, Ptr< BandwidthPartGnb > > ccPhyConf)
Configure carriers.
NrGnbRrcSapProvider * GetNrGnbRrcSapProvider()
void ConnectionRejectedTimeout(uint16_t rnti)
friend class MemberNrAnrSapUser< NrGnbRrc >
allow MemberNrAnrSapUser<NrGnbRrc> class friend access
Definition nr-gnb-rrc.h:683
Ptr< NrUeManager > GetUeManager(uint16_t rnti)
void SetNrAnrSapProvider(NrAnrSapProvider *s)
friend class MemberNrCcmRrcSapUser< NrGnbRrc >
allow MemberNrCcmRrcSapUser<NrGnbRrc> class friend access
Definition nr-gnb-rrc.h:693
NrCcmRrcSapUser * GetNrCcmRrcSapUser()
uint8_t CellToComponentCarrierId(uint16_t cellId)
std::vector< uint8_t > AddUeMeasReportConfig(NrRrcSap::ReportConfigEutra config)
Add a new UE measurement reporting configuration.
friend class GnbRrcMemberNrGnbCmacSapUser
allow GnbRrcMemberNrGnbCmacSapUser class friend access
Definition nr-gnb-rrc.h:679
void AddX2Neighbour(uint16_t cellId)
NrHandoverManagementSapUser * GetNrHandoverManagementSapUser()
void SetNrCcmRrcSapProvider(NrCcmRrcSapProvider *s)
void HandoverJoiningTimeout(uint16_t rnti)
void ConnectionSetupTimeout(uint16_t rnti)
void SetNrGnbCphySapProvider(NrGnbCphySapProvider *s)
bool HasUeManager(uint16_t rnti) const
bool HasCellId(uint16_t cellId) const
NrGnbCmacSapUser * GetNrGnbCmacSapUser()
void SetEpcX2SapProvider(NrEpcX2SapProvider *s)
void DoSendReleaseDataRadioBearer(uint64_t imsi, uint16_t rnti, uint8_t bearerId)
This function acts as an interface to trigger Release indication messages towards gNB and EPC.
void SetCellId(uint16_t m_cellId)
bool SendData(Ptr< Packet > p)
static TypeId GetTypeId()
Get the type ID.
void SendHandoverRequest(uint16_t rnti, uint16_t cellId)
friend class NrEpcX2SpecificEpcX2SapUser< NrGnbRrc >
allow NrMemberEpcGnbS1SapUser<NrGnbRrc> class friend access
Definition nr-gnb-rrc.h:689
uint16_t ComponentCarrierToCellId(uint8_t componentCarrierId)
NrGnbCphySapUser * GetNrGnbCphySapUser()
NrAnrSapUser * GetNrAnrSapUser()
void ConnectionRequestTimeout(uint16_t rnti)
friend class MemberNrHandoverManagementSapUser< NrGnbRrc >
allow MemberNrHandoverManagementSapUser<NrGnbRrc> class friend access
Definition nr-gnb-rrc.h:681
NrEpcGnbS1SapUser * GetS1SapUser()
void SetNrGnbRrcSapUser(NrGnbRrcSapUser *s)
void ConfigureCell(const std::map< uint8_t, Ptr< BandwidthPartGnb > > &ccPhyConf)
Configure cell-specific parameters.
NrEpcX2SapUser * GetEpcX2SapUser()
void SetCsgId(uint32_t csgId, bool csgIndication)
Associate this RRC entity with a particular CSG information.
void HandoverLeavingTimeout(uint16_t rnti)
void SetNrMacSapProvider(NrMacSapProvider *s)
~NrGnbRrc() override
void SetS1SapProvider(NrEpcGnbS1SapProvider *s)
friend class MemberNrGnbRrcSapProvider< NrGnbRrc >
allow MemberNrGnbRrcSapProvider<NrGnbRrc> class friend access
Definition nr-gnb-rrc.h:685
void SetNrHandoverManagementSapProvider(NrHandoverManagementSapProvider *s)
void SetNrGnbCmacSapProvider(NrGnbCmacSapProvider *s)
Part of the RRC protocol. This Service Access Point (SAP) is used to let the gNB RRC receive a messag...
Part of the RRC protocol. This Service Access Point (SAP) is used by the gNB RRC to send messages to ...
virtual void SendSystemInformation(uint16_t cellId, SystemInformation msg)=0
Send a SystemInformation message to all attached UEs during a system information acquisition procedur...
virtual void RemoveUe(uint16_t rnti)=0
Remove UE function.
virtual Ptr< Packet > EncodeHandoverCommand(RrcConnectionReconfiguration msg)=0
Encode handover command.
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 TransmitPdcpSdu(TransmitPdcpSduParameters params)=0
static TypeId GetTypeId()
Get the type ID.
Definition nr-rlc-am.cc:74
void SetNrMacSapProvider(NrMacSapProvider *s)
Definition nr-rlc.cc:156
static TypeId GetTypeId()
Get the type ID.
Definition nr-rlc.cc:184
static TypeId GetTypeId()
Get the type ID.
Definition nr-rlc-um.cc:43
static double ConvertPdschConfigDedicated2Double(PdschConfigDedicated pdschConfigDedicated)
Definition nr-rrc-sap.h:176
NrRrcSap::RrcConnectionReconfiguration GetRrcConnectionReconfigurationForHandover(uint8_t componentCarrierId)
State GetState() const
std::vector< NrEpcX2Sap::ErabToBeSetupItem > GetErabList()
void RecvRrcConnectionSetupCompleted(NrRrcSap::RrcConnectionSetupCompleted msg)
void SetSource(uint16_t sourceCellId, uint16_t sourceX2apId)
uint16_t GetSrsConfigurationIndex() const
void PrepareHandover(uint16_t cellId)
void RecvRrcConnectionRequest(NrRrcSap::RrcConnectionRequest msg)
void RecvHandoverCancel(NrEpcX2SapUser::HandoverCancelParams params)
void DoReceivePdcpSdu(NrPdcpSapUser::ReceivePdcpSduParameters params)
uint64_t GetImsi() const
NrEpcX2Sap::HandoverPreparationFailureParams BuildHoPrepFailMsg()
build handover preparation failure message
void CancelPendingEvents()
void ScheduleRrcConnectionReconfiguration()
void SendData(uint8_t bid, Ptr< Packet > p)
void ConfigureMacPhy()
Configure MAC and PHY aspects.
void ReleaseDataRadioBearer(uint8_t drbid)
uint16_t GetRnti() const
void Configure()
Perform post-creation configuration steps.
uint8_t GetComponentCarrierId() const
void CmacUeConfigUpdateInd(NrGnbCmacSapUser::UeConfig cmacParams)
void ConfigureSrb0()
Initialize the gNB side of SRB0.
void StartDataRadioBearers()
void RecvHandoverPreparationFailure(uint16_t cellId)
void InitialContextSetupRequest()
NrEpcX2Sap::HandoverCancelParams BuildHoCancelMsg()
build handover cancel message
void RecvRrcConnectionReestablishmentComplete(NrRrcSap::RrcConnectionReestablishmentComplete msg)
void SetImsi(uint64_t imsi)
void ConfigureSrb1()
Initialize the gNB side of SRB1.
void RecvRrcConnectionReconfigurationCompleted(NrRrcSap::RrcConnectionReconfigurationCompleted msg)
void SendRrcConnectionRelease()
This function acts as an interface to trigger the connection release towards gNB, EPC and UE.
void RecvHandoverRequestAck(NrEpcX2SapUser::HandoverRequestAckParams params)
void RecvUeContextRelease(NrEpcX2SapUser::UeContextReleaseParams params)
void RecvSnStatusTransfer(NrEpcX2SapUser::SnStatusTransferParams params)
void CompleteSetupUe(NrGnbRrcSapProvider::CompleteSetupUeParameters params)
void ConfigureSap()
Initialize the SAP objects.
void RecvRrcConnectionReestablishmentRequest(NrRrcSap::RrcConnectionReestablishmentRequest msg)
void SetSrsConfigurationIndex(uint16_t srsConfIndex)
void RecordDataRadioBearersToBeStarted()
void RecvMeasurementReport(NrRrcSap::MeasurementReport msg)
void SendUeContextRelease()
static TypeId GetTypeId()
Get the type ID.
void SetPdschConfigDedicated(NrRrcSap::PdschConfigDedicated pdschConfigDedicated)
NrRrcSap::RadioResourceConfigDedicated GetRadioResourceConfigForHandoverPreparationInfo()
void RecvIdealUeContextRemoveRequest(uint16_t rnti)
void SetupDataRadioBearer(NrEpsBearer bearer, uint8_t bearerId, uint32_t gtpTeid, Ipv4Address transportLayerAddress)
friend class NrPdcpSpecificNrPdcpSapUser< NrUeManager >
allow NrPdcpSpecificNrPdcpSapUser<NrUeManager> class friend access
Definition nr-gnb-rrc.h:57
std::list< BearerToBeSwitched > bearersToBeSwitched
list of bearers to be switched
uint32_t mmeUeS1Id
mmeUeS1Id in practice, we use the IMSI
NrEpsBearer erabLevelQosParameters
E-RAB level QOS parameters.
Ipv4Address transportLayerAddress
transport layer address
ErabsSubjectToStatusTransferItem structure.
Parameters of the HANDOVER CANCEL message.
uint16_t oldGnbUeX2apId
old gNB UE X2 AP ID
uint16_t newGnbUeX2apId
new gNB UE X2 AP ID
Parameters of the HANDOVER PREPARATION FAILURE message.
uint16_t criticalityDiagnostics
criticality diagnostics
Parameters of the HANDOVER REQUEST ACKNOWLEDGE message.
std::vector< ErabNotAdmittedItem > notAdmittedBearers
not admitted bearers
uint16_t newGnbUeX2apId
new gNB UE X2 AP ID
uint16_t oldGnbUeX2apId
old gNB UE X2 AP ID
std::vector< ErabAdmittedItem > admittedBearers
admitted bearers
Parameters of the HANDOVER REQUEST message.
uint64_t ueAggregateMaxBitRateDownlink
UE aggregate max bit rate downlink.
uint32_t mmeUeS1apId
MME UE S1 AP ID.
std::vector< ErabToBeSetupItem > bearers
bearers
Ptr< Packet > rrcContext
RRC context.
uint64_t ueAggregateMaxBitRateUplink
UE aggregate max bit rate uplink.
uint16_t oldGnbUeX2apId
old gNB UE X2 AP ID
Parameters of the SN STATUS TRANSFER message.
std::vector< ErabsSubjectToStatusTransferItem > erabsSubjectToStatusTransferList
ERABs subject to status transfer list.
uint16_t oldGnbUeX2apId
old gNB UE X2 AP ID
uint16_t newGnbUeX2apId
new gNB UE X2 AP ID
Parameters of the UE CONTEXT RELEASE message.
uint16_t oldGnbUeX2apId
old gNB UE X2 AP ID
uint16_t newGnbUeX2apId
new gNB UE X2 AP ID
Parameters of the UE DATA primitive.
uint16_t targetCellId
target cell ID
uint16_t sourceCellId
source cell ID
Ptr< Packet > ueData
UE data.
AllocateNcRaPreambleReturnValue structure.
bool valid
true if a valid RA config was allocated, false otherwise
uint8_t connEstFailCount
the counter value for T300 timer expiration
uint8_t preambleTransMax
preamble transmit maximum
uint8_t raResponseWindowSize
RA response window size.
uint8_t numberOfRaPreambles
number of RA preambles
Parameters for [re]configuring the UE.
Parameters for [re]configuring the UE.
CompleteSetupUeParameters structure.
SetupUeParameters structure.
NrPdcpSapProvider * srb1SapProvider
SRB1 SAP provider.
NrRlcSapProvider * srb0SapProvider
SRB0 SAP provider.
uint16_t rxSn
RX sequence number.
Definition nr-pdcp.h:91
uint16_t txSn
TX sequence number.
Definition nr-pdcp.h:90
uint8_t transmissionMode
transmission mode
Definition nr-rrc-sap.h:138
SystemInformationBlockType1 sourceSystemInformationBlockType1
source system information block type 1
Definition nr-rrc-sap.h:662
RadioResourceConfigDedicated sourceRadioResourceConfig
source radio resource config
Definition nr-rrc-sap.h:658
MasterInformationBlock sourceMasterInformationBlock
source master information block
Definition nr-rrc-sap.h:660
MeasConfig sourceMeasConfig
source measure config
Definition nr-rrc-sap.h:657
uint16_t sourceUeIdentity
source UE identity
Definition nr-rrc-sap.h:659
SystemInformationBlockType2 sourceSystemInformationBlockType2
source system information block type 2
Definition nr-rrc-sap.h:664
uint32_t sourceDlCarrierFreq
source DL carrier frequency
Definition nr-rrc-sap.h:665
uint16_t dlBandwidth
DL bandwidth.
Definition nr-rrc-sap.h:585
uint16_t ulBandwidth
UL bandwidth.
Definition nr-rrc-sap.h:586
uint32_t ulCarrierFreq
UL carrier frequency.
Definition nr-rrc-sap.h:579
uint32_t dlCarrierFreq
DL carrier frequency.
Definition nr-rrc-sap.h:578
int8_t qQualMin
INTEGER (-34..-3), actual value = IE value [dB].
Definition nr-rrc-sap.h:69
int8_t qRxLevMin
INTEGER (-70..-22), actual value = IE value * 2 [dBm].
Definition nr-rrc-sap.h:68
uint16_t ulBandwidth
UL bandwidth.
Definition nr-rrc-sap.h:76
uint32_t ulCarrierFreq
UL carrier frequency.
Definition nr-rrc-sap.h:75
HandoverPreparationInfo structure.
Definition nr-rrc-sap.h:948
MasterInformationBlock structure.
Definition nr-rrc-sap.h:627
uint16_t systemFrameNumber
system frame number
Definition nr-rrc-sap.h:630
uint16_t dlBandwidth
DL bandwidth.
Definition nr-rrc-sap.h:629
std::list< ReportConfigToAddMod > reportConfigToAddModList
report config to add mod list
Definition nr-rrc-sap.h:562
bool haveQuantityConfig
have quantity config?
Definition nr-rrc-sap.h:565
bool haveSpeedStatePars
have speed state parameters?
Definition nr-rrc-sap.h:571
std::list< MeasObjectToAddMod > measObjectToAddModList
measure object to add mod list
Definition nr-rrc-sap.h:560
bool haveSmeasure
have S measure?
Definition nr-rrc-sap.h:569
QuantityConfig quantityConfig
quantity config
Definition nr-rrc-sap.h:566
bool haveMeasGapConfig
have measure gap config?
Definition nr-rrc-sap.h:567
std::list< MeasIdToAddMod > measIdToAddModList
measure ID to add mod list
Definition nr-rrc-sap.h:564
MeasIdToAddMod structure.
Definition nr-rrc-sap.h:493
uint8_t measObjectId
measure object ID
Definition nr-rrc-sap.h:495
uint8_t reportConfigId
report config ID
Definition nr-rrc-sap.h:496
uint32_t carrierFreq
carrier frequency
Definition nr-rrc-sap.h:324
uint16_t allowedMeasBandwidth
allowed measure bandwidth
Definition nr-rrc-sap.h:325
uint8_t neighCellConfig
neighbor cell config
Definition nr-rrc-sap.h:327
bool haveCellForWhichToReportCGI
have cell for which to report CGI?
Definition nr-rrc-sap.h:333
bool presenceAntennaPort1
antenna port 1 present?
Definition nr-rrc-sap.h:326
int8_t offsetFreq
offset frequency
Definition nr-rrc-sap.h:328
MeasObjectToAddMod structure.
Definition nr-rrc-sap.h:479
MeasObjectEutra measObjectEutra
measure object eutra
Definition nr-rrc-sap.h:481
uint8_t measObjectId
measure object ID
Definition nr-rrc-sap.h:480
uint8_t rsrpResult
the RSRP result
Definition nr-rrc-sap.h:680
uint8_t rsrqResult
the RSRQ result
Definition nr-rrc-sap.h:681
uint8_t measId
measure ID
Definition nr-rrc-sap.h:724
bool haveMeasResultNeighCells
have measure result neighbor cells
Definition nr-rrc-sap.h:726
std::list< MeasResultServFreq > measResultServFreqList
MeasResultServFreqList-r10.
Definition nr-rrc-sap.h:729
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
bool haveMeasResultServFreqList
has measResultServFreqList-r10
Definition nr-rrc-sap.h:728
MeasurementReport structure.
Definition nr-rrc-sap.h:954
MeasResults measResults
measure results
Definition nr-rrc-sap.h:955
uint16_t newUeIdentity
new UE identity
Definition nr-rrc-sap.h:604
RachConfigDedicated rachConfigDedicated
RACH config dedicated.
Definition nr-rrc-sap.h:607
bool haveCarrierFreq
have carrier frequency?
Definition nr-rrc-sap.h:600
uint16_t targetPhysCellId
target Phy cell ID
Definition nr-rrc-sap.h:599
bool haveCarrierBandwidth
have carrier bandwidth?
Definition nr-rrc-sap.h:602
bool haveRachConfigDedicated
Have RACH config dedicated?
Definition nr-rrc-sap.h:606
CarrierBandwidthEutra carrierBandwidth
carrier bandwidth
Definition nr-rrc-sap.h:603
CarrierFreqEutra carrierFreq
carrier frequency
Definition nr-rrc-sap.h:601
RadioResourceConfigCommon radioResourceConfigCommon
radio resource config common
Definition nr-rrc-sap.h:605
std::list< SCellToAddMod > sCellToAddModList
SCell to add mod list.
Definition nr-rrc-sap.h:881
std::list< uint8_t > sCellToReleaseList
SCell to release list.
Definition nr-rrc-sap.h:882
PdschConfigDedicated structure.
Definition nr-rrc-sap.h:150
bool haveSoundingRsUlConfigDedicated
have sounding RS UL config dedicated?
Definition nr-rrc-sap.h:214
SoundingRsUlConfigDedicated soundingRsUlConfigDedicated
sounding RS UL config dedicated
Definition nr-rrc-sap.h:216
PdschConfigDedicated pdschConfigDedicated
PDSCH config dedicated.
Definition nr-rrc-sap.h:220
AntennaInfoDedicated antennaInfo
antenna info
Definition nr-rrc-sap.h:218
bool havePdschConfigDedicated
have PDSCH config dedicated?
Definition nr-rrc-sap.h:219
bool haveAntennaInfoDedicated
have antenna info dedicated?
Definition nr-rrc-sap.h:217
uint32_t plmnIdentity
PLMN identity.
Definition nr-rrc-sap.h:53
uint8_t numberOfRaPreambles
number of RA preambles
Definition nr-rrc-sap.h:243
uint8_t filterCoefficientRSRP
filter coefficient RSRP
Definition nr-rrc-sap.h:294
uint8_t filterCoefficientRSRQ
filter coefficient RSRQ
Definition nr-rrc-sap.h:295
uint8_t raResponseWindowSize
RA response window size.
Definition nr-rrc-sap.h:250
uint8_t preambleTransMax
preamble transmit maximum
Definition nr-rrc-sap.h:249
PreambleInfo preambleInfo
preamble info
Definition nr-rrc-sap.h:263
RaSupervisionInfo raSupervisionInfo
RA supervision info.
Definition nr-rrc-sap.h:264
TxFailParam txFailParam
txFailParams
Definition nr-rrc-sap.h:265
uint8_t raPreambleIndex
RA preamble index.
Definition nr-rrc-sap.h:592
uint8_t raPrachMaskIndex
RA PRACH mask index.
Definition nr-rrc-sap.h:593
RachConfigCommon rachConfigCommon
RACH config common.
Definition nr-rrc-sap.h:271
RachConfigCommon rachConfigCommon
RACH config common.
Definition nr-rrc-sap.h:277
RadioResourceConfigDedicated structure.
Definition nr-rrc-sap.h:283
PhysicalConfigDedicated physicalConfigDedicated
physical config dedicated
Definition nr-rrc-sap.h:288
std::list< uint8_t > drbToReleaseList
DRB to release list.
Definition nr-rrc-sap.h:286
bool havePhysicalConfigDedicated
have physical config dedicated?
Definition nr-rrc-sap.h:287
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.
enum ns3::NrRrcSap::ReportConfigEutra::@6 reportQuantity
Report type enumeration.
@ RSRP
Reference Signal Received Power.
Definition nr-rrc-sap.h:412
@ RSRQ
Reference Signal Received Quality.
Definition nr-rrc-sap.h:413
@ EVENT_A2
Event A2: Serving becomes worse than absolute threshold.
Definition nr-rrc-sap.h:372
@ EVENT_A1
Event A1: Serving becomes better than absolute threshold.
Definition nr-rrc-sap.h:371
@ EVENT_A4
Event A4: Neighbour becomes better than absolute threshold.
Definition nr-rrc-sap.h:374
ThresholdEutra threshold2
Threshold for event A5.
Definition nr-rrc-sap.h:381
enum ns3::NrRrcSap::ReportConfigEutra::@4 eventId
Event enumeration.
ThresholdEutra threshold1
Threshold for event A1, A2, A4, and A5.
Definition nr-rrc-sap.h:380
ReportConfigToAddMod structure.
Definition nr-rrc-sap.h:486
uint8_t reportConfigId
report config ID
Definition nr-rrc-sap.h:487
ReportConfigEutra reportConfigEutra
report config eutra
Definition nr-rrc-sap.h:488
RrcConnectionReconfigurationCompleted structure.
Definition nr-rrc-sap.h:904
RrcConnectionReconfiguration structure.
Definition nr-rrc-sap.h:887
MobilityControlInfo mobilityControlInfo
mobility control info
Definition nr-rrc-sap.h:892
bool haveMobilityControlInfo
have mobility control info
Definition nr-rrc-sap.h:891
NonCriticalExtensionConfiguration nonCriticalExtension
Definition nr-rrc-sap.h:899
RrcConnectionReestablishmentComplete structure.
Definition nr-rrc-sap.h:925
RrcConnectionReestablishment structure.
Definition nr-rrc-sap.h:917
RadioResourceConfigDedicated radioResourceConfigDedicated
radio resource config dedicated
Definition nr-rrc-sap.h:920
uint8_t rrcTransactionIdentifier
RRC transaction identifier.
Definition nr-rrc-sap.h:918
RrcConnectionReestablishmentRequest structure.
Definition nr-rrc-sap.h:910
RrcConnectionReject structure.
Definition nr-rrc-sap.h:942
RrcConnectionRelease structure.
Definition nr-rrc-sap.h:936
uint8_t rrcTransactionIdentifier
RRC transaction identifier.
Definition nr-rrc-sap.h:937
RrcConnectionRequest structure.
Definition nr-rrc-sap.h:736
uint64_t ueIdentity
UE identity.
Definition nr-rrc-sap.h:737
RrcConnectionSetupCompleted structure.
Definition nr-rrc-sap.h:750
RrcConnectionSetup structure.
Definition nr-rrc-sap.h:742
RadioResourceConfigDedicated radioResourceConfigDedicated
radio resource config dedicated
Definition nr-rrc-sap.h:745
uint8_t rrcTransactionIdentifier
RRC transaction identifier.
Definition nr-rrc-sap.h:743
uint16_t srsConfigIndex
SRS config index.
Definition nr-rrc-sap.h:132
SystemInformationBlockType1 structure.
Definition nr-rrc-sap.h:635
CellSelectionInfo cellSelectionInfo
cell selection info
Definition nr-rrc-sap.h:637
CellAccessRelatedInfo cellAccessRelatedInfo
cell access related info
Definition nr-rrc-sap.h:636
RadioResourceConfigCommonSib radioResourceConfigCommon
radio resource config common
Definition nr-rrc-sap.h:643
enum ns3::NrRrcSap::ThresholdEutra::@2 choice
Threshold enumeration.
@ THRESHOLD_RSRQ
RSRQ is used for the threshold.
Definition nr-rrc-sap.h:352
@ THRESHOLD_RSRP
RSRP is used for the threshold.
Definition nr-rrc-sap.h:351
uint8_t connEstFailCount
Number of times that the UE detects T300 expiry on the same cell.
Definition nr-rrc-sap.h:256