5G-LENA nr-v3.3-81-g75c7590d
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_srsCurrentPeriodicityId(0),
1839 m_lastAllocatedConfigurationIndex(0),
1840 m_reconfigureUes(false),
1841 m_numberOfComponentCarriers(0),
1842 m_carriersConfigured(false)
1843{
1844 NS_LOG_FUNCTION(this);
1845 m_cmacSapUser.push_back(new GnbRrcMemberNrGnbCmacSapUser(this, 0));
1846 m_handoverManagementSapUser = new MemberNrHandoverManagementSapUser<NrGnbRrc>(this);
1847 m_anrSapUser = new MemberNrAnrSapUser<NrGnbRrc>(this);
1848 m_rrcSapProvider = new MemberNrGnbRrcSapProvider<NrGnbRrc>(this);
1849 m_x2SapUser = new NrEpcX2SpecificEpcX2SapUser<NrGnbRrc>(this);
1850 m_s1SapUser = new NrMemberEpcGnbS1SapUser<NrGnbRrc>(this);
1851 m_cphySapUser.push_back(new MemberNrGnbCphySapUser<NrGnbRrc>(this));
1852 m_ccmRrcSapUser = new MemberNrCcmRrcSapUser<NrGnbRrc>(this);
1853}
1854
1855void
1856NrGnbRrc::ConfigureCarriers(std::map<uint8_t, Ptr<BandwidthPartGnb>> ccPhyConf)
1857{
1858 NS_ASSERT_MSG(!m_carriersConfigured, "Secondary carriers can be configured only once.");
1859 m_componentCarrierPhyConf = ccPhyConf;
1860 NS_ABORT_MSG_IF(m_numberOfComponentCarriers != m_componentCarrierPhyConf.size(),
1861 " Number of component carriers "
1862 "are not equal to the number of he component carrier configuration provided");
1863
1864 for (uint16_t i = 1; i < m_numberOfComponentCarriers; i++)
1865 {
1866 m_cphySapUser.push_back(new MemberNrGnbCphySapUser<NrGnbRrc>(this));
1867 m_cmacSapUser.push_back(new GnbRrcMemberNrGnbCmacSapUser(this, i));
1868 }
1869 m_carriersConfigured = true;
1870 Object::DoInitialize();
1871}
1872
1874{
1875 NS_LOG_FUNCTION(this);
1876}
1877
1878void
1879NrGnbRrc::DoDispose()
1880{
1881 NS_LOG_FUNCTION(this);
1882 for (uint16_t i = 0; i < m_numberOfComponentCarriers; i++)
1883 {
1884 delete m_cphySapUser[i];
1885 delete m_cmacSapUser[i];
1886 }
1887 // delete m_cphySapUser;
1888 m_cphySapUser.erase(m_cphySapUser.begin(), m_cphySapUser.end());
1889 m_cphySapUser.clear();
1890 // delete m_cmacSapUser;
1891 m_cmacSapUser.erase(m_cmacSapUser.begin(), m_cmacSapUser.end());
1892 m_cmacSapUser.clear();
1893 m_ueMap.clear();
1894 delete m_handoverManagementSapUser;
1895 delete m_ccmRrcSapUser;
1896 delete m_anrSapUser;
1897 delete m_rrcSapProvider;
1898 delete m_x2SapUser;
1899 delete m_s1SapUser;
1900}
1901
1902TypeId
1904{
1905 static TypeId tid =
1906 TypeId("ns3::NrGnbRrc")
1907 .SetParent<Object>()
1908 .SetGroupName("Nr")
1909 .AddConstructor<NrGnbRrc>()
1910 .AddAttribute("UeMap",
1911 "List of NrUeManager by C-RNTI.",
1912 ObjectMapValue(),
1913 MakeObjectMapAccessor(&NrGnbRrc::m_ueMap),
1914 MakeObjectMapChecker<NrUeManager>())
1915 .AddAttribute("DefaultTransmissionMode",
1916 "The default UEs' transmission mode (0: SISO)",
1917 UintegerValue(0), // default tx-mode
1918 MakeUintegerAccessor(&NrGnbRrc::m_defaultTransmissionMode),
1919 MakeUintegerChecker<uint8_t>())
1920 .AddAttribute(
1921 "EpsBearerToRlcMapping",
1922 "Specify which type of RLC will be used for each type of EPS bearer.",
1923 EnumValue(RLC_SM_ALWAYS),
1924 MakeEnumAccessor<NrEpsBearerToRlcMapping_t>(&NrGnbRrc::m_epsBearerToRlcMapping),
1925 MakeEnumChecker(RLC_SM_ALWAYS,
1926 "RlcSmAlways",
1927 RLC_UM_ALWAYS,
1928 "RlcUmAlways",
1929 RLC_AM_ALWAYS,
1930 "RlcAmAlways",
1931 PER_BASED,
1932 "PacketErrorRateBased"))
1933 .AddAttribute("SystemInformationPeriodicity",
1934 "The interval for sending system information (Time value)",
1935 TimeValue(MilliSeconds(80)),
1936 MakeTimeAccessor(&NrGnbRrc::m_systemInformationPeriodicity),
1937 MakeTimeChecker())
1938
1939 // SRS related attributes
1940 .AddAttribute(
1941 "SrsPeriodicity",
1942 "The SRS periodicity in milliseconds",
1943 UintegerValue(40),
1945 MakeUintegerChecker<uint32_t>())
1946
1947 // Timeout related attributes
1948 .AddAttribute("ConnectionRequestTimeoutDuration",
1949 "After a RA attempt, if no RRC CONNECTION REQUEST is "
1950 "received before this time, the UE context is destroyed. "
1951 "Must account for reception of RAR and transmission of "
1952 "RRC CONNECTION REQUEST over UL GRANT. The value of this"
1953 "timer should not be greater than T300 timer at UE RRC",
1954 TimeValue(MilliSeconds(15)),
1955 MakeTimeAccessor(&NrGnbRrc::m_connectionRequestTimeoutDuration),
1956 MakeTimeChecker(MilliSeconds(1), MilliSeconds(15)))
1957 .AddAttribute("ConnectionSetupTimeoutDuration",
1958 "After accepting connection request, if no RRC CONNECTION "
1959 "SETUP COMPLETE is received before this time, the UE "
1960 "context is destroyed. Must account for the UE's reception "
1961 "of RRC CONNECTION SETUP and transmission of RRC CONNECTION "
1962 "SETUP COMPLETE.",
1963 TimeValue(MilliSeconds(150)),
1964 MakeTimeAccessor(&NrGnbRrc::m_connectionSetupTimeoutDuration),
1965 MakeTimeChecker())
1966 .AddAttribute("ConnectionRejectedTimeoutDuration",
1967 "Time to wait between sending a RRC CONNECTION REJECT and "
1968 "destroying the UE context",
1969 TimeValue(MilliSeconds(30)),
1970 MakeTimeAccessor(&NrGnbRrc::m_connectionRejectedTimeoutDuration),
1971 MakeTimeChecker())
1972 .AddAttribute("HandoverJoiningTimeoutDuration",
1973 "After accepting a handover request, if no RRC CONNECTION "
1974 "RECONFIGURATION COMPLETE is received before this time, the "
1975 "UE context is destroyed. Must account for reception of "
1976 "X2 HO REQ ACK by source eNB, transmission of the Handover "
1977 "Command, non-contention-based random access and reception "
1978 "of the RRC CONNECTION RECONFIGURATION COMPLETE message.",
1979 TimeValue(MilliSeconds(200)),
1980 MakeTimeAccessor(&NrGnbRrc::m_handoverJoiningTimeoutDuration),
1981 MakeTimeChecker())
1982 .AddAttribute("HandoverLeavingTimeoutDuration",
1983 "After issuing a Handover Command, if neither RRC "
1984 "CONNECTION RE-ESTABLISHMENT nor X2 UE Context Release has "
1985 "been previously received, the UE context is destroyed.",
1986 TimeValue(MilliSeconds(500)),
1987 MakeTimeAccessor(&NrGnbRrc::m_handoverLeavingTimeoutDuration),
1988 MakeTimeChecker())
1989
1990 // Cell selection related attribute
1991 .AddAttribute("QRxLevMin",
1992 "One of information transmitted within the SIB1 message, "
1993 "indicating the required minimum RSRP level that any UE must "
1994 "receive from this cell before it is allowed to camp to this "
1995 "cell. The default value -70 corresponds to -140 dBm and is "
1996 "the lowest possible value as defined by Section 6.3.4 of "
1997 "3GPP TS 36.133. This restriction, however, only applies to "
1998 "initial cell selection and EPC-enabled simulation.",
1999 TypeId::ATTR_GET | TypeId::ATTR_CONSTRUCT,
2000 IntegerValue(-70),
2001 MakeIntegerAccessor(&NrGnbRrc::m_qRxLevMin),
2002 MakeIntegerChecker<int8_t>(-70, -22))
2003 .AddAttribute("NumberOfComponentCarriers",
2004 "Number of Component Carriers",
2005 UintegerValue(1),
2006 MakeIntegerAccessor(&NrGnbRrc::m_numberOfComponentCarriers),
2007 MakeIntegerChecker<int16_t>(nr::MIN_NO_CC, nr::MAX_NO_CC))
2008
2009 // Handover related attributes
2010 .AddAttribute("AdmitHandoverRequest",
2011 "Whether to admit an X2 handover request from another eNB",
2012 BooleanValue(true),
2013 MakeBooleanAccessor(&NrGnbRrc::m_admitHandoverRequest),
2014 MakeBooleanChecker())
2015 .AddAttribute("AdmitRrcConnectionRequest",
2016 "Whether to admit a connection request from a UE",
2017 BooleanValue(true),
2018 MakeBooleanAccessor(&NrGnbRrc::m_admitRrcConnectionRequest),
2019 MakeBooleanChecker())
2020
2021 // UE measurements related attributes
2022 .AddAttribute("RsrpFilterCoefficient",
2023 "Determines the strength of smoothing effect induced by "
2024 "layer 3 filtering of RSRP in all attached UE; "
2025 "if set to 0, no layer 3 filtering is applicable",
2026 // i.e. the variable k in 3GPP TS 36.331 section 5.5.3.2
2027 UintegerValue(4),
2028 MakeUintegerAccessor(&NrGnbRrc::m_rsrpFilterCoefficient),
2029 MakeUintegerChecker<uint8_t>(0))
2030 .AddAttribute("RsrqFilterCoefficient",
2031 "Determines the strength of smoothing effect induced by "
2032 "layer 3 filtering of RSRQ in all attached UE; "
2033 "if set to 0, no layer 3 filtering is applicable",
2034 // i.e. the variable k in 3GPP TS 36.331 section 5.5.3.2
2035 UintegerValue(4),
2036 MakeUintegerAccessor(&NrGnbRrc::m_rsrqFilterCoefficient),
2037 MakeUintegerChecker<uint8_t>(0))
2038
2039 // Trace sources
2040 .AddTraceSource("NewUeContext",
2041 "Fired upon creation of a new UE context.",
2042 MakeTraceSourceAccessor(&NrGnbRrc::m_newUeContextTrace),
2043 "ns3::NrGnbRrc::NewUeContextTracedCallback")
2044 .AddTraceSource("ConnectionEstablished",
2045 "Fired upon successful RRC connection establishment.",
2046 MakeTraceSourceAccessor(&NrGnbRrc::m_connectionEstablishedTrace),
2047 "ns3::NrGnbRrc::ConnectionHandoverTracedCallback")
2048 .AddTraceSource("ConnectionReconfiguration",
2049 "trace fired upon RRC connection reconfiguration",
2050 MakeTraceSourceAccessor(&NrGnbRrc::m_connectionReconfigurationTrace),
2051 "ns3::NrGnbRrc::ConnectionHandoverTracedCallback")
2052 .AddTraceSource("HandoverStart",
2053 "trace fired upon start of a handover procedure",
2054 MakeTraceSourceAccessor(&NrGnbRrc::m_handoverStartTrace),
2055 "ns3::NrGnbRrc::HandoverStartTracedCallback")
2056 .AddTraceSource("HandoverEndOk",
2057 "trace fired upon successful termination of a handover procedure",
2058 MakeTraceSourceAccessor(&NrGnbRrc::m_handoverEndOkTrace),
2059 "ns3::NrGnbRrc::ConnectionHandoverTracedCallback")
2060 .AddTraceSource("RecvMeasurementReport",
2061 "trace fired when measurement report is received",
2062 MakeTraceSourceAccessor(&NrGnbRrc::m_recvMeasurementReportTrace),
2063 "ns3::NrGnbRrc::ReceiveReportTracedCallback")
2064 .AddTraceSource("NotifyConnectionRelease",
2065 "trace fired when an UE is released",
2066 MakeTraceSourceAccessor(&NrGnbRrc::m_connectionReleaseTrace),
2067 "ns3::NrGnbRrc::ConnectionHandoverTracedCallback")
2068 .AddTraceSource("RrcTimeout",
2069 "trace fired when a timer expires",
2070 MakeTraceSourceAccessor(&NrGnbRrc::m_rrcTimeoutTrace),
2071 "ns3::NrGnbRrc::TimerExpiryTracedCallback")
2072 .AddTraceSource(
2073 "HandoverFailureNoPreamble",
2074 "trace fired upon handover failure due to non-allocation of non-contention based "
2075 "preamble at gNB for UE to handover due to max count reached",
2076 MakeTraceSourceAccessor(&NrGnbRrc::m_handoverFailureNoPreambleTrace),
2077 "ns3::NrGnbRrc::HandoverFailureTracedCallback")
2078 .AddTraceSource(
2079 "HandoverFailureMaxRach",
2080 "trace fired upon handover failure due to max RACH attempts from UE to target eNB",
2081 MakeTraceSourceAccessor(&NrGnbRrc::m_handoverFailureMaxRachTrace),
2082 "ns3::NrGnbRrc::HandoverFailureTracedCallback")
2083 .AddTraceSource(
2084 "HandoverFailureLeaving",
2085 "trace fired upon handover failure due to handover leaving timeout at source eNB",
2086 MakeTraceSourceAccessor(&NrGnbRrc::m_handoverFailureLeavingTrace),
2087 "ns3::NrGnbRrc::HandoverFailureTracedCallback")
2088 .AddTraceSource(
2089 "HandoverFailureJoining",
2090 "trace fired upon handover failure due to handover joining timeout at target eNB",
2091 MakeTraceSourceAccessor(&NrGnbRrc::m_handoverFailureJoiningTrace),
2092 "ns3::NrGnbRrc::HandoverFailureTracedCallback");
2093 return tid;
2094}
2095
2096void
2098{
2099 NS_LOG_FUNCTION(this << s);
2100 m_x2SapProvider = s;
2101}
2102
2105{
2106 NS_LOG_FUNCTION(this);
2107 return m_x2SapUser;
2108}
2109
2110void
2112{
2113 NS_LOG_FUNCTION(this << s);
2114 m_cmacSapProvider.at(0) = s;
2115}
2116
2117void
2119{
2120 NS_LOG_FUNCTION(this << s);
2121 if (m_cmacSapProvider.size() > pos)
2122 {
2123 m_cmacSapProvider.at(pos) = s;
2124 }
2125 else
2126 {
2127 m_cmacSapProvider.push_back(s);
2128 NS_ABORT_IF(m_cmacSapProvider.size() - 1 != pos);
2129 }
2130}
2131
2134{
2135 NS_LOG_FUNCTION(this);
2136 return m_cmacSapUser.at(0);
2137}
2138
2141{
2142 NS_LOG_FUNCTION(this);
2143 return m_cmacSapUser.at(pos);
2144}
2145
2146void
2148{
2149 NS_LOG_FUNCTION(this << s);
2150 m_handoverManagementSapProvider = s;
2151}
2152
2155{
2156 NS_LOG_FUNCTION(this);
2157 return m_handoverManagementSapUser;
2158}
2159
2160void
2162{
2163 NS_LOG_FUNCTION(this << s);
2164 m_ccmRrcSapProvider = s;
2165}
2166
2169{
2170 NS_LOG_FUNCTION(this);
2171 return m_ccmRrcSapUser;
2172}
2173
2174void
2176{
2177 NS_LOG_FUNCTION(this << s);
2178 m_anrSapProvider = s;
2179}
2180
2183{
2184 NS_LOG_FUNCTION(this);
2185 return m_anrSapUser;
2186}
2187
2188void
2190{
2191 NS_LOG_FUNCTION(this << s);
2192 m_rrcSapUser = s;
2193}
2194
2197{
2198 NS_LOG_FUNCTION(this);
2199 return m_rrcSapProvider;
2200}
2201
2202void
2204{
2205 NS_LOG_FUNCTION(this);
2206 m_macSapProvider = s;
2207}
2208
2209void
2211{
2212 m_s1SapProvider = s;
2213}
2214
2217{
2218 return m_s1SapUser;
2219}
2220
2221void
2223{
2224 NS_LOG_FUNCTION(this << s);
2225 if (!m_cphySapProvider.empty())
2226 {
2227 m_cphySapProvider.at(0) = s;
2228 }
2229 else
2230 {
2231 m_cphySapProvider.push_back(s);
2232 }
2233}
2234
2237{
2238 NS_LOG_FUNCTION(this);
2239 return m_cphySapUser.at(0);
2240}
2241
2242void
2244{
2245 NS_LOG_FUNCTION(this << s);
2246 if (m_cphySapProvider.size() > pos)
2247 {
2248 m_cphySapProvider.at(pos) = s;
2249 }
2250 else
2251 {
2252 m_cphySapProvider.push_back(s);
2253 NS_ABORT_IF(m_cphySapProvider.size() - 1 != pos);
2254 }
2255}
2256
2259{
2260 NS_LOG_FUNCTION(this);
2261 return m_cphySapUser.at(pos);
2262}
2263
2264bool
2265NrGnbRrc::HasUeManager(uint16_t rnti) const
2266{
2267 NS_LOG_FUNCTION(this << (uint32_t)rnti);
2268 auto it = m_ueMap.find(rnti);
2269 return (it != m_ueMap.end());
2270}
2271
2272Ptr<NrUeManager>
2274{
2275 NS_LOG_FUNCTION(this << (uint32_t)rnti);
2276 NS_ASSERT(0 != rnti);
2277 auto it = m_ueMap.find(rnti);
2278 NS_ASSERT_MSG(it != m_ueMap.end(), "UE manager for RNTI " << rnti << " not found");
2279 return it->second;
2280}
2281
2282std::vector<uint8_t>
2284{
2285 NS_LOG_FUNCTION(this);
2286
2287 // SANITY CHECK
2288
2289 NS_ASSERT_MSG(
2290 m_ueMeasConfig.measIdToAddModList.size() ==
2291 m_ueMeasConfig.reportConfigToAddModList.size() * m_numberOfComponentCarriers,
2292 "Measurement identities and reporting configuration should not have different quantity");
2293
2294 if (Simulator::Now() != Seconds(0))
2295 {
2296 NS_FATAL_ERROR("AddUeMeasReportConfig may not be called after the simulation has run");
2297 }
2298
2299 // INPUT VALIDATION
2300
2301 switch (config.triggerQuantity)
2302 {
2306 {
2307 NS_FATAL_ERROR(
2308 "The given triggerQuantity (RSRP) does not match with the given threshold2.choice");
2309 }
2310
2316 {
2317 NS_FATAL_ERROR(
2318 "The given triggerQuantity (RSRP) does not match with the given threshold1.choice");
2319 }
2320 break;
2321
2325 {
2326 NS_FATAL_ERROR(
2327 "The given triggerQuantity (RSRQ) does not match with the given threshold2.choice");
2328 }
2329
2335 {
2336 NS_FATAL_ERROR(
2337 "The given triggerQuantity (RSRQ) does not match with the given threshold1.choice");
2338 }
2339 break;
2340
2341 default:
2342 NS_FATAL_ERROR("unsupported triggerQuantity");
2343 break;
2344 }
2345
2346 if (config.purpose != NrRrcSap::ReportConfigEutra::REPORT_STRONGEST_CELLS)
2347 {
2348 NS_FATAL_ERROR("Only REPORT_STRONGEST_CELLS purpose is supported");
2349 }
2350
2352 {
2353 NS_LOG_WARN("reportQuantity = BOTH will be used instead of the given reportQuantity");
2354 }
2355
2356 uint8_t nextId = m_ueMeasConfig.reportConfigToAddModList.size() + 1;
2357
2358 // create the reporting configuration
2359 NrRrcSap::ReportConfigToAddMod reportConfig;
2360 reportConfig.reportConfigId = nextId;
2361 reportConfig.reportConfigEutra = config;
2362
2363 // add reporting configuration to UE measurement configuration
2364 m_ueMeasConfig.reportConfigToAddModList.push_back(reportConfig);
2365
2366 std::vector<uint8_t> measIds;
2367
2368 // create measurement identities, linking reporting configuration to all objects
2369 for (uint16_t BandwidthPartGnb = 0; BandwidthPartGnb < m_numberOfComponentCarriers;
2371 {
2372 NrRrcSap::MeasIdToAddMod measIdToAddMod;
2373
2374 uint8_t measId = m_ueMeasConfig.measIdToAddModList.size() + 1;
2375
2376 measIdToAddMod.measId = measId;
2377 measIdToAddMod.measObjectId = BandwidthPartGnb + 1;
2378 measIdToAddMod.reportConfigId = nextId;
2379
2380 m_ueMeasConfig.measIdToAddModList.push_back(measIdToAddMod);
2381 measIds.push_back(measId);
2382 }
2383
2384 return measIds;
2385}
2386
2387void
2388NrGnbRrc::ConfigureCell(const std::map<uint8_t, Ptr<BandwidthPartGnb>>& ccPhyConf)
2389{
2390 auto it = ccPhyConf.begin();
2391 NS_ASSERT(it != ccPhyConf.end());
2392 uint16_t ulBandwidth = it->second->GetUlBandwidth();
2393 uint16_t dlBandwidth = it->second->GetDlBandwidth();
2394 uint32_t ulEarfcn = it->second->GetUlEarfcn();
2395 uint32_t dlEarfcn = it->second->GetDlEarfcn();
2396 NS_LOG_FUNCTION(this << ulBandwidth << dlBandwidth << ulEarfcn << dlEarfcn);
2397 NS_ASSERT_MSG(!m_configured, "NrGnbRrc::ConfigureCell called more than once");
2398
2399 for (const auto& it : ccPhyConf)
2400 {
2401 m_cphySapProvider.at(it.first)->SetBandwidth(it.second->GetUlBandwidth(),
2402 it.second->GetDlBandwidth());
2403 m_cphySapProvider.at(it.first)->SetEarfcn(it.second->GetUlEarfcn(),
2404 it.second->GetDlEarfcn());
2405 m_cphySapProvider.at(it.first)->SetCellId(it.second->GetCellId());
2406 m_cmacSapProvider.at(it.first)->ConfigureMac(it.second->GetUlBandwidth(),
2407 it.second->GetDlBandwidth());
2408 }
2409
2410 m_dlEarfcn = dlEarfcn;
2411 m_ulEarfcn = ulEarfcn;
2412 m_dlBandwidth = dlBandwidth;
2413 m_ulBandwidth = ulBandwidth;
2414
2415 /*
2416 * Initializing the list of measurement objects.
2417 * Only intra-frequency measurements are supported,
2418 * so one measurement object is created for each carrier frequency.
2419 */
2420 for (const auto& it : ccPhyConf)
2421 {
2423 measObject.measObjectId = it.first + 1;
2424 measObject.measObjectEutra.carrierFreq = it.second->GetDlEarfcn();
2425 measObject.measObjectEutra.allowedMeasBandwidth = it.second->GetDlBandwidth();
2426 measObject.measObjectEutra.presenceAntennaPort1 = false;
2427 measObject.measObjectEutra.neighCellConfig = 0;
2428 measObject.measObjectEutra.offsetFreq = 0;
2430
2431 m_ueMeasConfig.measObjectToAddModList.push_back(measObject);
2432 }
2433
2434 m_ueMeasConfig.haveQuantityConfig = true;
2435 m_ueMeasConfig.quantityConfig.filterCoefficientRSRP = m_rsrpFilterCoefficient;
2436 m_ueMeasConfig.quantityConfig.filterCoefficientRSRQ = m_rsrqFilterCoefficient;
2437 m_ueMeasConfig.haveMeasGapConfig = false;
2438 m_ueMeasConfig.haveSmeasure = false;
2439 m_ueMeasConfig.haveSpeedStatePars = false;
2440
2441 m_sib1.clear();
2442 m_sib1.reserve(ccPhyConf.size());
2443 for (const auto& it : ccPhyConf)
2444 {
2445 // Enabling MIB transmission
2447 mib.dlBandwidth = it.second->GetDlBandwidth();
2448 mib.systemFrameNumber = 0;
2449 m_cphySapProvider.at(it.first)->SetMasterInformationBlock(mib);
2450
2451 // Enabling SIB1 transmission with default values
2453 sib1.cellAccessRelatedInfo.cellIdentity = it.second->GetCellId();
2457 sib1.cellSelectionInfo.qQualMin = -34; // not used, set as minimum value
2458 sib1.cellSelectionInfo.qRxLevMin = m_qRxLevMin; // set as minimum value
2459 m_sib1.push_back(sib1);
2460 m_cphySapProvider.at(it.first)->SetSystemInformationBlockType1(sib1);
2461 }
2462 /*
2463 * Enabling transmission of other SIB. The first time System Information is
2464 * transmitted is arbitrarily assumed to be at +0.016s, and then it will be
2465 * regularly transmitted every 80 ms by default (set the
2466 * SystemInformationPeriodicity attribute to configure this).
2467 */
2468 Simulator::Schedule(MilliSeconds(16), &NrGnbRrc::SendSystemInformation, this);
2469
2470 m_configured = true;
2471}
2472
2473void
2474NrGnbRrc::SetCellId(uint16_t cellId)
2475{
2476 // update SIB1
2477 m_sib1.at(0).cellAccessRelatedInfo.cellIdentity = cellId;
2478 m_cphySapProvider.at(0)->SetSystemInformationBlockType1(m_sib1.at(0));
2479}
2480
2481void
2482NrGnbRrc::SetCellId(uint16_t cellId, uint8_t ccIndex)
2483{
2484 // update SIB1
2485 m_sib1.at(ccIndex).cellAccessRelatedInfo.cellIdentity = cellId;
2486 m_cphySapProvider.at(ccIndex)->SetSystemInformationBlockType1(m_sib1.at(ccIndex));
2487}
2488
2489uint8_t
2491{
2492 NS_LOG_FUNCTION(this << cellId);
2493 for (auto& it : m_componentCarrierPhyConf)
2494 {
2495 if (it.second->GetCellId() == cellId)
2496 {
2497 return it.first;
2498 }
2499 }
2500 NS_FATAL_ERROR("Cell " << cellId << " not found in CC map");
2501}
2502
2503uint16_t
2504NrGnbRrc::ComponentCarrierToCellId(uint8_t componentCarrierId)
2505{
2506 NS_LOG_FUNCTION(this << +componentCarrierId);
2507 return m_componentCarrierPhyConf.at(componentCarrierId)->GetCellId();
2508}
2509
2510bool
2511NrGnbRrc::HasCellId(uint16_t cellId) const
2512{
2513 for (auto& it : m_componentCarrierPhyConf)
2514 {
2515 if (it.second->GetCellId() == cellId)
2516 {
2517 return true;
2518 }
2519 }
2520 return false;
2521}
2522
2523bool
2524NrGnbRrc::SendData(Ptr<Packet> packet)
2525{
2526 NS_LOG_FUNCTION(this << packet);
2527 NrEpsBearerTag tag;
2528 bool found = packet->RemovePacketTag(tag);
2529 NS_ASSERT_MSG(found, "no NrEpsBearerTag found in packet to be sent");
2530 Ptr<NrUeManager> ueManager = GetUeManager(tag.GetRnti());
2531
2532 NS_LOG_INFO("Sending a packet of " << packet->GetSize() << " bytes to IMSI "
2533 << ueManager->GetImsi() << ", RNTI " << ueManager->GetRnti()
2534 << ", BID " << (uint16_t)tag.GetBid());
2535 ueManager->SendData(tag.GetBid(), packet);
2536
2537 return true;
2538}
2539
2540void
2541NrGnbRrc::SetForwardUpCallback(Callback<void, Ptr<Packet>> cb)
2542{
2543 m_forwardUpCallback = cb;
2544}
2545
2546void
2548{
2549 NS_LOG_FUNCTION(this << rnti);
2550 NS_ASSERT_MSG(GetUeManager(rnti)->GetState() == NrUeManager::INITIAL_RANDOM_ACCESS,
2551 "ConnectionRequestTimeout in unexpected state "
2552 << ToString(GetUeManager(rnti)->GetState()));
2553 m_rrcTimeoutTrace(GetUeManager(rnti)->GetImsi(),
2554 rnti,
2555 ComponentCarrierToCellId(GetUeManager(rnti)->GetComponentCarrierId()),
2556 "ConnectionRequestTimeout");
2557 RemoveUe(rnti);
2558}
2559
2560void
2562{
2563 NS_LOG_FUNCTION(this << rnti);
2564 NS_ASSERT_MSG(GetUeManager(rnti)->GetState() == NrUeManager::CONNECTION_SETUP,
2565 "ConnectionSetupTimeout in unexpected state "
2566 << ToString(GetUeManager(rnti)->GetState()));
2567 m_rrcTimeoutTrace(GetUeManager(rnti)->GetImsi(),
2568 rnti,
2569 ComponentCarrierToCellId(GetUeManager(rnti)->GetComponentCarrierId()),
2570 "ConnectionSetupTimeout");
2571 RemoveUe(rnti);
2572}
2573
2574void
2576{
2577 NS_LOG_FUNCTION(this << rnti);
2578 NS_ASSERT_MSG(GetUeManager(rnti)->GetState() == NrUeManager::CONNECTION_REJECTED,
2579 "ConnectionRejectedTimeout in unexpected state "
2580 << ToString(GetUeManager(rnti)->GetState()));
2581 m_rrcTimeoutTrace(GetUeManager(rnti)->GetImsi(),
2582 rnti,
2583 ComponentCarrierToCellId(GetUeManager(rnti)->GetComponentCarrierId()),
2584 "ConnectionRejectedTimeout");
2585 RemoveUe(rnti);
2586}
2587
2588void
2590{
2591 NS_LOG_FUNCTION(this << rnti);
2592 NS_ASSERT_MSG(GetUeManager(rnti)->GetState() == NrUeManager::HANDOVER_JOINING,
2593 "HandoverJoiningTimeout in unexpected state "
2594 << ToString(GetUeManager(rnti)->GetState()));
2595 m_handoverFailureJoiningTrace(
2596 GetUeManager(rnti)->GetImsi(),
2597 rnti,
2598 ComponentCarrierToCellId(GetUeManager(rnti)->GetComponentCarrierId()));
2599 // check if the RNTI to be removed is not stale
2600 if (HasUeManager(rnti))
2601 {
2609 Ptr<NrUeManager> ueManager = GetUeManager(rnti);
2610 NrEpcX2Sap::HandoverPreparationFailureParams msg = ueManager->BuildHoPrepFailMsg();
2611 m_x2SapProvider->SendHandoverPreparationFailure(msg);
2612 RemoveUe(rnti);
2613 }
2614}
2615
2616void
2618{
2619 NS_LOG_FUNCTION(this << rnti);
2620 NS_ASSERT_MSG(GetUeManager(rnti)->GetState() == NrUeManager::HANDOVER_LEAVING,
2621 "HandoverLeavingTimeout in unexpected state "
2622 << ToString(GetUeManager(rnti)->GetState()));
2623 m_handoverFailureLeavingTrace(
2624 GetUeManager(rnti)->GetImsi(),
2625 rnti,
2626 ComponentCarrierToCellId(GetUeManager(rnti)->GetComponentCarrierId()));
2627 // check if the RNTI to be removed is not stale
2628 if (HasUeManager(rnti))
2629 {
2635 Ptr<NrUeManager> ueManager = GetUeManager(rnti);
2636 NrEpcX2Sap::HandoverCancelParams msg = ueManager->BuildHoCancelMsg();
2637 m_x2SapProvider->SendHandoverCancel(msg);
2638 ueManager->SendRrcConnectionRelease();
2639 }
2640}
2641
2642void
2643NrGnbRrc::SendHandoverRequest(uint16_t rnti, uint16_t cellId)
2644{
2645 NS_LOG_FUNCTION(this << rnti << cellId);
2646 NS_LOG_LOGIC("Request to send HANDOVER REQUEST");
2647 NS_ASSERT(m_configured);
2648
2649 Ptr<NrUeManager> ueManager = GetUeManager(rnti);
2650 ueManager->PrepareHandover(cellId);
2651}
2652
2653void
2654NrGnbRrc::DoCompleteSetupUe(uint16_t rnti, NrGnbRrcSapProvider::CompleteSetupUeParameters params)
2655{
2656 NS_LOG_FUNCTION(this << rnti);
2657 GetUeManager(rnti)->CompleteSetupUe(params);
2658}
2659
2660void
2661NrGnbRrc::DoRecvRrcConnectionRequest(uint16_t rnti, NrRrcSap::RrcConnectionRequest msg)
2662{
2663 NS_LOG_FUNCTION(this << rnti);
2664 GetUeManager(rnti)->RecvRrcConnectionRequest(msg);
2665}
2666
2667void
2668NrGnbRrc::DoRecvRrcConnectionSetupCompleted(uint16_t rnti,
2669 NrRrcSap::RrcConnectionSetupCompleted msg)
2670{
2671 NS_LOG_FUNCTION(this << rnti);
2672 GetUeManager(rnti)->RecvRrcConnectionSetupCompleted(msg);
2673}
2674
2675void
2676NrGnbRrc::DoRecvRrcConnectionReconfigurationCompleted(
2677 uint16_t rnti,
2678 NrRrcSap::RrcConnectionReconfigurationCompleted msg)
2679{
2680 NS_LOG_FUNCTION(this << rnti);
2681 GetUeManager(rnti)->RecvRrcConnectionReconfigurationCompleted(msg);
2682}
2683
2684void
2685NrGnbRrc::DoRecvRrcConnectionReestablishmentRequest(
2686 uint16_t rnti,
2687 NrRrcSap::RrcConnectionReestablishmentRequest msg)
2688{
2689 NS_LOG_FUNCTION(this << rnti);
2690 GetUeManager(rnti)->RecvRrcConnectionReestablishmentRequest(msg);
2691}
2692
2693void
2694NrGnbRrc::DoRecvRrcConnectionReestablishmentComplete(
2695 uint16_t rnti,
2696 NrRrcSap::RrcConnectionReestablishmentComplete msg)
2697{
2698 NS_LOG_FUNCTION(this << rnti);
2699 GetUeManager(rnti)->RecvRrcConnectionReestablishmentComplete(msg);
2700}
2701
2702void
2703NrGnbRrc::DoRecvMeasurementReport(uint16_t rnti, NrRrcSap::MeasurementReport msg)
2704{
2705 NS_LOG_FUNCTION(this << rnti);
2706 GetUeManager(rnti)->RecvMeasurementReport(msg);
2707}
2708
2709void
2710NrGnbRrc::DoInitialContextSetupRequest(NrEpcGnbS1SapUser::InitialContextSetupRequestParameters msg)
2711{
2712 NS_LOG_FUNCTION(this);
2713 Ptr<NrUeManager> ueManager = GetUeManager(msg.rnti);
2714 ueManager->InitialContextSetupRequest();
2715}
2716
2717void
2718NrGnbRrc::DoRecvIdealUeContextRemoveRequest(uint16_t rnti)
2719{
2720 NS_LOG_FUNCTION(this << rnti);
2721
2722 // check if the RNTI to be removed is not stale
2723 if (HasUeManager(rnti))
2724 {
2725 Ptr<NrUeManager> ueManager = GetUeManager(rnti);
2726
2727 if (ueManager->GetState() == NrUeManager::HANDOVER_JOINING)
2728 {
2729 m_handoverFailureMaxRachTrace(
2730 GetUeManager(rnti)->GetImsi(),
2731 rnti,
2732 ComponentCarrierToCellId(GetUeManager(rnti)->GetComponentCarrierId()));
2739 NrEpcX2Sap::HandoverPreparationFailureParams msg = ueManager->BuildHoPrepFailMsg();
2740 m_x2SapProvider->SendHandoverPreparationFailure(msg);
2741 }
2742
2743 GetUeManager(rnti)->RecvIdealUeContextRemoveRequest(rnti);
2744 // delete the UE context at the eNB
2745 RemoveUe(rnti);
2746 }
2747}
2748
2749void
2750NrGnbRrc::DoDataRadioBearerSetupRequest(
2751 NrEpcGnbS1SapUser::DataRadioBearerSetupRequestParameters request)
2752{
2753 NS_LOG_FUNCTION(this);
2754 Ptr<NrUeManager> ueManager = GetUeManager(request.rnti);
2755 ueManager->SetupDataRadioBearer(request.bearer,
2756 request.bearerId,
2757 request.gtpTeid,
2758 request.transportLayerAddress);
2759}
2760
2761void
2762NrGnbRrc::DoPathSwitchRequestAcknowledge(
2763 NrEpcGnbS1SapUser::PathSwitchRequestAcknowledgeParameters params)
2764{
2765 NS_LOG_FUNCTION(this);
2766 Ptr<NrUeManager> ueManager = GetUeManager(params.rnti);
2767 ueManager->SendUeContextRelease();
2768}
2769
2770void
2771NrGnbRrc::DoRecvHandoverRequest(NrEpcX2SapUser::HandoverRequestParams req)
2772{
2773 NS_LOG_FUNCTION(this);
2774
2775 NS_LOG_LOGIC("Recv X2 message: HANDOVER REQUEST");
2776
2777 NS_LOG_LOGIC("oldGnbUeX2apId = " << req.oldGnbUeX2apId);
2778 NS_LOG_LOGIC("sourceCellId = " << req.sourceCellId);
2779 NS_LOG_LOGIC("targetCellId = " << req.targetCellId);
2780 NS_LOG_LOGIC("mmeUeS1apId = " << req.mmeUeS1apId);
2781
2782 // if no SRS index is available, then do not accept the handover
2783 if (!m_admitHandoverRequest || IsMaxSrsReached())
2784 {
2785 NS_LOG_INFO("rejecting handover request from cellId " << req.sourceCellId);
2786 NrEpcX2Sap::HandoverPreparationFailureParams res;
2787 res.oldGnbUeX2apId = req.oldGnbUeX2apId;
2788 res.sourceCellId = req.sourceCellId;
2789 res.targetCellId = req.targetCellId;
2790 res.cause = 0;
2791 res.criticalityDiagnostics = 0;
2792 m_x2SapProvider->SendHandoverPreparationFailure(res);
2793 return;
2794 }
2795
2796 uint8_t componentCarrierId = CellToComponentCarrierId(req.targetCellId);
2797 uint16_t rnti = AddUe(NrUeManager::HANDOVER_JOINING, componentCarrierId);
2798 Ptr<NrUeManager> ueManager = GetUeManager(rnti);
2799 ueManager->SetSource(req.sourceCellId, req.oldGnbUeX2apId);
2800 ueManager->SetImsi(req.mmeUeS1apId);
2801 NrGnbCmacSapProvider::AllocateNcRaPreambleReturnValue anrcrv =
2802 m_cmacSapProvider.at(componentCarrierId)->AllocateNcRaPreamble(rnti);
2803 if (!anrcrv.valid)
2804 {
2805 NS_LOG_INFO(
2806 this
2807 << " failed to allocate a preamble for non-contention based RA => cannot accept HO");
2808 m_handoverFailureNoPreambleTrace(
2809 GetUeManager(rnti)->GetImsi(),
2810 rnti,
2811 ComponentCarrierToCellId(GetUeManager(rnti)->GetComponentCarrierId()));
2817 Ptr<NrUeManager> ueManager = GetUeManager(rnti);
2818 NrEpcX2Sap::HandoverPreparationFailureParams msg = ueManager->BuildHoPrepFailMsg();
2819 m_x2SapProvider->SendHandoverPreparationFailure(msg);
2820 RemoveUe(rnti); // remove the UE from the target eNB
2821 return;
2822 }
2823
2824 NrEpcX2SapProvider::HandoverRequestAckParams ackParams;
2825 ackParams.oldGnbUeX2apId = req.oldGnbUeX2apId;
2826 ackParams.newGnbUeX2apId = rnti;
2827 ackParams.sourceCellId = req.sourceCellId;
2828 ackParams.targetCellId = req.targetCellId;
2829
2830 for (auto it = req.bearers.begin(); it != req.bearers.end(); ++it)
2831 {
2832 ueManager->SetupDataRadioBearer(it->erabLevelQosParameters,
2833 it->erabId,
2834 it->gtpTeid,
2835 it->transportLayerAddress);
2836 NrEpcX2Sap::ErabAdmittedItem i;
2837 i.erabId = it->erabId;
2838 ackParams.admittedBearers.push_back(i);
2839 }
2840
2841 NrRrcSap::RrcConnectionReconfiguration handoverCommand =
2842 ueManager->GetRrcConnectionReconfigurationForHandover(componentCarrierId);
2843
2844 handoverCommand.mobilityControlInfo.newUeIdentity = rnti;
2845 handoverCommand.mobilityControlInfo.haveRachConfigDedicated = true;
2846 handoverCommand.mobilityControlInfo.rachConfigDedicated.raPreambleIndex = anrcrv.raPreambleId;
2847 handoverCommand.mobilityControlInfo.rachConfigDedicated.raPrachMaskIndex =
2848 anrcrv.raPrachMaskIndex;
2849
2850 NrGnbCmacSapProvider::RachConfig rc = m_cmacSapProvider.at(componentCarrierId)->GetRachConfig();
2851 handoverCommand.mobilityControlInfo.radioResourceConfigCommon.rachConfigCommon.preambleInfo
2852 .numberOfRaPreambles = rc.numberOfRaPreambles;
2853 handoverCommand.mobilityControlInfo.radioResourceConfigCommon.rachConfigCommon.raSupervisionInfo
2854 .preambleTransMax = rc.preambleTransMax;
2855 handoverCommand.mobilityControlInfo.radioResourceConfigCommon.rachConfigCommon.raSupervisionInfo
2856 .raResponseWindowSize = rc.raResponseWindowSize;
2857 handoverCommand.mobilityControlInfo.radioResourceConfigCommon.rachConfigCommon.txFailParam
2858 .connEstFailCount = rc.connEstFailCount;
2859
2860 Ptr<Packet> encodedHandoverCommand = m_rrcSapUser->EncodeHandoverCommand(handoverCommand);
2861
2862 ackParams.rrcContext = encodedHandoverCommand;
2863
2864 NS_LOG_LOGIC("Send X2 message: HANDOVER REQUEST ACK");
2865
2866 NS_LOG_LOGIC("oldGnbUeX2apId = " << ackParams.oldGnbUeX2apId);
2867 NS_LOG_LOGIC("newGnbUeX2apId = " << ackParams.newGnbUeX2apId);
2868 NS_LOG_LOGIC("sourceCellId = " << ackParams.sourceCellId);
2869 NS_LOG_LOGIC("targetCellId = " << ackParams.targetCellId);
2870
2871 m_x2SapProvider->SendHandoverRequestAck(ackParams);
2872}
2873
2874void
2875NrGnbRrc::DoRecvHandoverRequestAck(NrEpcX2SapUser::HandoverRequestAckParams params)
2876{
2877 NS_LOG_FUNCTION(this);
2878
2879 NS_LOG_LOGIC("Recv X2 message: HANDOVER REQUEST ACK");
2880
2881 NS_LOG_LOGIC("oldGnbUeX2apId = " << params.oldGnbUeX2apId);
2882 NS_LOG_LOGIC("newGnbUeX2apId = " << params.newGnbUeX2apId);
2883 NS_LOG_LOGIC("sourceCellId = " << params.sourceCellId);
2884 NS_LOG_LOGIC("targetCellId = " << params.targetCellId);
2885
2886 uint16_t rnti = params.oldGnbUeX2apId;
2887 Ptr<NrUeManager> ueManager = GetUeManager(rnti);
2888 ueManager->RecvHandoverRequestAck(params);
2889}
2890
2891void
2892NrGnbRrc::DoRecvHandoverPreparationFailure(NrEpcX2SapUser::HandoverPreparationFailureParams params)
2893{
2894 NS_LOG_FUNCTION(this);
2895
2896 NS_LOG_LOGIC("Recv X2 message: HANDOVER PREPARATION FAILURE");
2897
2898 NS_LOG_LOGIC("oldGnbUeX2apId = " << params.oldGnbUeX2apId);
2899 NS_LOG_LOGIC("sourceCellId = " << params.sourceCellId);
2900 NS_LOG_LOGIC("targetCellId = " << params.targetCellId);
2901 NS_LOG_LOGIC("cause = " << params.cause);
2902 NS_LOG_LOGIC("criticalityDiagnostics = " << params.criticalityDiagnostics);
2903
2904 uint16_t rnti = params.oldGnbUeX2apId;
2905
2906 // check if the RNTI is not stale
2907 if (HasUeManager(rnti))
2908 {
2909 Ptr<NrUeManager> ueManager = GetUeManager(rnti);
2910 ueManager->RecvHandoverPreparationFailure(params.targetCellId);
2911 }
2912}
2913
2914void
2915NrGnbRrc::DoRecvSnStatusTransfer(NrEpcX2SapUser::SnStatusTransferParams params)
2916{
2917 NS_LOG_FUNCTION(this);
2918
2919 NS_LOG_LOGIC("Recv X2 message: SN STATUS TRANSFER");
2920
2921 NS_LOG_LOGIC("oldGnbUeX2apId = " << params.oldGnbUeX2apId);
2922 NS_LOG_LOGIC("newGnbUeX2apId = " << params.newGnbUeX2apId);
2923 NS_LOG_LOGIC("erabsSubjectToStatusTransferList size = "
2924 << params.erabsSubjectToStatusTransferList.size());
2925
2926 uint16_t rnti = params.newGnbUeX2apId;
2927
2928 // check if the RNTI to receive SN transfer for is not stale
2929 if (HasUeManager(rnti))
2930 {
2931 Ptr<NrUeManager> ueManager = GetUeManager(rnti);
2932 ueManager->RecvSnStatusTransfer(params);
2933 }
2934}
2935
2936void
2937NrGnbRrc::DoRecvUeContextRelease(NrEpcX2SapUser::UeContextReleaseParams params)
2938{
2939 NS_LOG_FUNCTION(this);
2940
2941 NS_LOG_LOGIC("Recv X2 message: UE CONTEXT RELEASE");
2942
2943 NS_LOG_LOGIC("oldGnbUeX2apId = " << params.oldGnbUeX2apId);
2944 NS_LOG_LOGIC("newGnbUeX2apId = " << params.newGnbUeX2apId);
2945
2946 uint16_t rnti = params.oldGnbUeX2apId;
2947
2948 // check if the RNTI to be removed is not stale
2949 if (HasUeManager(rnti))
2950 {
2951 GetUeManager(rnti)->RecvUeContextRelease(params);
2952 RemoveUe(rnti);
2953 }
2954}
2955
2956void
2957NrGnbRrc::DoRecvLoadInformation(NrEpcX2SapUser::LoadInformationParams params)
2958{
2959 NS_LOG_FUNCTION(this);
2960
2961 NS_LOG_LOGIC("Recv X2 message: LOAD INFORMATION");
2962
2963 NS_LOG_LOGIC("Number of cellInformationItems = " << params.cellInformationList.size());
2964}
2965
2966void
2967NrGnbRrc::DoRecvResourceStatusUpdate(NrEpcX2SapUser::ResourceStatusUpdateParams params)
2968{
2969 NS_LOG_FUNCTION(this);
2970
2971 NS_LOG_LOGIC("Recv X2 message: RESOURCE STATUS UPDATE");
2972
2973 NS_LOG_LOGIC(
2974 "Number of cellMeasurementResultItems = " << params.cellMeasurementResultList.size());
2975
2976 NS_ASSERT("Processing of RESOURCE STATUS UPDATE X2 message IS NOT IMPLEMENTED");
2977}
2978
2979void
2980NrGnbRrc::DoRecvUeData(NrEpcX2SapUser::UeDataParams params)
2981{
2982 NS_LOG_FUNCTION(this);
2983
2984 NS_LOG_LOGIC("Recv UE DATA FORWARDING through X2 interface");
2985 NS_LOG_LOGIC("sourceCellId = " << params.sourceCellId);
2986 NS_LOG_LOGIC("targetCellId = " << params.targetCellId);
2987 NS_LOG_LOGIC("gtpTeid = " << params.gtpTeid);
2988 NS_LOG_LOGIC("ueData = " << params.ueData);
2989 NS_LOG_LOGIC("ueData size = " << params.ueData->GetSize());
2990
2991 auto teidInfoIt = m_x2uTeidInfoMap.find(params.gtpTeid);
2992 if (teidInfoIt != m_x2uTeidInfoMap.end())
2993 {
2994 GetUeManager(teidInfoIt->second.rnti)->SendData(teidInfoIt->second.drbid, params.ueData);
2995 }
2996 else
2997 {
2998 NS_FATAL_ERROR("X2-U data received but no X2uTeidInfo found");
2999 }
3000}
3001
3002void
3003NrGnbRrc::DoRecvHandoverCancel(NrEpcX2SapUser::HandoverCancelParams params)
3004{
3005 NS_LOG_FUNCTION(this);
3006
3007 NS_LOG_LOGIC("Recv X2 message: HANDOVER CANCEL");
3008
3009 NS_LOG_LOGIC("oldGnbUeX2apId = " << params.oldGnbUeX2apId);
3010 NS_LOG_LOGIC("newGnbUeX2apId = " << params.newGnbUeX2apId);
3011 NS_LOG_LOGIC("sourceCellId = " << params.sourceCellId);
3012 NS_LOG_LOGIC("targetCellId = " << params.targetCellId);
3013 NS_LOG_LOGIC("cause = " << params.cause);
3014
3015 uint16_t rnti = params.newGnbUeX2apId;
3016 if (HasUeManager(rnti))
3017 {
3018 Ptr<NrUeManager> ueManager = GetUeManager(rnti);
3019 ueManager->RecvHandoverCancel(params);
3020 GetUeManager(rnti)->RecvIdealUeContextRemoveRequest(rnti);
3021 }
3022}
3023
3024uint16_t
3025NrGnbRrc::DoAllocateTemporaryCellRnti(uint8_t componentCarrierId)
3026{
3027 NS_LOG_FUNCTION(this << +componentCarrierId);
3028 // if no SRS index is available, then do not create a new UE context.
3029 if (IsMaxSrsReached())
3030 {
3031 NS_LOG_WARN("Not enough SRS configuration indices, UE context not created");
3032 return 0; // return 0 since new RNTI was not assigned for the received preamble
3033 }
3034 return AddUe(NrUeManager::INITIAL_RANDOM_ACCESS, componentCarrierId);
3035}
3036
3037void
3038NrGnbRrc::DoRrcConfigurationUpdateInd(NrGnbCmacSapUser::UeConfig cmacParams)
3039{
3040 Ptr<NrUeManager> ueManager = GetUeManager(cmacParams.m_rnti);
3041 ueManager->CmacUeConfigUpdateInd(cmacParams);
3042}
3043
3044void
3045NrGnbRrc::DoNotifyLcConfigResult(uint16_t rnti, uint8_t lcid, bool success)
3046{
3047 NS_LOG_FUNCTION(this << (uint32_t)rnti);
3048 NS_FATAL_ERROR("not implemented");
3049}
3050
3051std::vector<uint8_t>
3052NrGnbRrc::DoAddUeMeasReportConfigForHandover(NrRrcSap::ReportConfigEutra reportConfig)
3053{
3054 NS_LOG_FUNCTION(this);
3055 std::vector<uint8_t> measIds = AddUeMeasReportConfig(reportConfig);
3056 m_handoverMeasIds.insert(measIds.begin(), measIds.end());
3057 return measIds;
3058}
3059
3060uint8_t
3061NrGnbRrc::DoAddUeMeasReportConfigForComponentCarrier(NrRrcSap::ReportConfigEutra reportConfig)
3062{
3063 NS_LOG_FUNCTION(this);
3064 uint8_t measId = AddUeMeasReportConfig(reportConfig).at(0);
3065 m_componentCarrierMeasIds.insert(measId);
3066 return measId;
3067}
3068
3069void
3070NrGnbRrc::DoSetNumberOfComponentCarriers(uint16_t numberOfComponentCarriers)
3071{
3072 m_numberOfComponentCarriers = numberOfComponentCarriers;
3073}
3074
3075void
3076NrGnbRrc::DoTriggerHandover(uint16_t rnti, uint16_t targetCellId)
3077{
3078 NS_LOG_FUNCTION(this << rnti << targetCellId);
3079
3080 bool isHandoverAllowed = true;
3081
3082 Ptr<NrUeManager> ueManager = GetUeManager(rnti);
3083 NS_ASSERT_MSG(ueManager, "Cannot find UE context with RNTI " << rnti);
3084
3085 if (m_anrSapProvider != nullptr && !HasCellId(targetCellId))
3086 {
3087 // ensure that proper neighbour relationship exists between source and target cells
3088 bool noHo = m_anrSapProvider->GetNoHo(targetCellId);
3089 bool noX2 = m_anrSapProvider->GetNoX2(targetCellId);
3090 NS_LOG_DEBUG(this << " cellId="
3091 << ComponentCarrierToCellId(ueManager->GetComponentCarrierId())
3092 << " targetCellId=" << targetCellId << " NRT.NoHo=" << noHo
3093 << " NRT.NoX2=" << noX2);
3094
3095 if (noHo || noX2)
3096 {
3097 isHandoverAllowed = false;
3098 NS_LOG_LOGIC(this << " handover to cell " << targetCellId << " is not allowed by ANR");
3099 }
3100 }
3101
3102 if (ueManager->GetState() != NrUeManager::CONNECTED_NORMALLY)
3103 {
3104 isHandoverAllowed = false;
3105 NS_LOG_LOGIC(this << " handover is not allowed because the UE"
3106 << " rnti=" << rnti << " is in " << ToString(ueManager->GetState())
3107 << " state");
3108 }
3109
3110 if (isHandoverAllowed)
3111 {
3112 // initiate handover execution
3113 ueManager->PrepareHandover(targetCellId);
3114 }
3115}
3116
3117uint8_t
3118NrGnbRrc::DoAddUeMeasReportConfigForAnr(NrRrcSap::ReportConfigEutra reportConfig)
3119{
3120 NS_LOG_FUNCTION(this);
3121 uint8_t measId = AddUeMeasReportConfig(reportConfig).at(0);
3122 m_anrMeasIds.insert(measId);
3123 return measId;
3124}
3125
3126void
3127NrGnbRrc::DoSetPdschConfigDedicated(uint16_t rnti,
3128 NrRrcSap::PdschConfigDedicated pdschConfigDedicated)
3129{
3130 NS_LOG_FUNCTION(this);
3131 Ptr<NrUeManager> ueManager = GetUeManager(rnti);
3132 ueManager->SetPdschConfigDedicated(pdschConfigDedicated);
3133}
3134
3135void
3136NrGnbRrc::DoSendLoadInformation(NrEpcX2Sap::LoadInformationParams params)
3137{
3138 NS_LOG_FUNCTION(this);
3139
3140 m_x2SapProvider->SendLoadInformation(params);
3141}
3142
3143uint16_t
3144NrGnbRrc::AddUe(NrUeManager::State state, uint8_t componentCarrierId)
3145{
3146 NS_LOG_FUNCTION(this);
3147 bool found = false;
3148 uint16_t rnti;
3149 for (rnti = m_lastAllocatedRnti + 1; (rnti != m_lastAllocatedRnti - 1) && (!found); ++rnti)
3150 {
3151 if ((rnti != 0) && (m_ueMap.find(rnti) == m_ueMap.end()))
3152 {
3153 found = true;
3154 break;
3155 }
3156 }
3157
3158 NS_ASSERT_MSG(found, "no more RNTIs available (do you have more than 65535 UEs in a cell?)");
3159 m_lastAllocatedRnti = rnti;
3160 Ptr<NrUeManager> ueManager = CreateObject<NrUeManager>(this, rnti, state, componentCarrierId);
3161 m_ccmRrcSapProvider->AddUe(rnti, (uint8_t)state);
3162 m_ueMap.insert(std::pair<uint16_t, Ptr<NrUeManager>>(rnti, ueManager));
3163 ueManager->Configure();
3164 const uint16_t cellId = ComponentCarrierToCellId(componentCarrierId);
3165 NS_LOG_DEBUG(this << " New UE RNTI " << rnti << " cellId " << cellId << " srs CI "
3166 << ueManager->GetSrsConfigurationIndex());
3167 m_newUeContextTrace(cellId, rnti);
3168 return rnti;
3169}
3170
3171void
3172NrGnbRrc::RemoveUe(uint16_t rnti)
3173{
3174 NS_LOG_FUNCTION(this << (uint32_t)rnti);
3175 auto it = m_ueMap.find(rnti);
3176 NS_ASSERT_MSG(it != m_ueMap.end(), "request to remove UE info with unknown rnti " << rnti);
3177 uint64_t imsi = it->second->GetImsi();
3178 uint16_t srsCi = (*it).second->GetSrsConfigurationIndex();
3179 // cancel pending events
3180 it->second->CancelPendingEvents();
3181 // fire trace upon connection release
3182 m_connectionReleaseTrace(imsi,
3183 ComponentCarrierToCellId(it->second->GetComponentCarrierId()),
3184 rnti);
3185 m_ueMap.erase(it);
3186 for (uint16_t i = 0; i < m_numberOfComponentCarriers; i++)
3187 {
3188 m_cmacSapProvider.at(i)->RemoveUe(rnti);
3189 m_cphySapProvider.at(i)->RemoveUe(rnti);
3190 }
3191 if (m_s1SapProvider != nullptr)
3192 {
3193 m_s1SapProvider->UeContextRelease(rnti);
3194 }
3195 m_ccmRrcSapProvider->RemoveUe(rnti);
3196 // need to do this after NrUeManager has been deleted
3197 if (srsCi != 0)
3198 {
3199 RemoveSrsConfigurationIndex(srsCi);
3200 }
3201
3202 m_rrcSapUser->RemoveUe(rnti); // Remove UE context at RRC protocol
3203}
3204
3205TypeId
3206NrGnbRrc::GetRlcType(NrEpsBearer bearer)
3207{
3208 switch (m_epsBearerToRlcMapping)
3209 {
3210 case RLC_SM_ALWAYS:
3211 return NrRlcSm::GetTypeId();
3212
3213 case RLC_UM_ALWAYS:
3214 return NrRlcUm::GetTypeId();
3215
3216 case RLC_AM_ALWAYS:
3217 return NrRlcAm::GetTypeId();
3218
3219 case PER_BASED:
3220 if (bearer.GetPacketErrorLossRate() > 1.0e-5)
3221 {
3222 return NrRlcUm::GetTypeId();
3223 }
3224 else
3225 {
3226 return NrRlcAm::GetTypeId();
3227 }
3228
3229 default:
3230 return NrRlcSm::GetTypeId();
3231 }
3232}
3233
3234void
3236{
3237 NS_LOG_FUNCTION(this << cellId);
3238
3239 if (m_anrSapProvider != nullptr)
3240 {
3241 m_anrSapProvider->AddNeighbourRelation(cellId);
3242 }
3243}
3244
3245void
3246NrGnbRrc::SetCsgId(uint32_t csgId, bool csgIndication)
3247{
3248 NS_LOG_FUNCTION(this << csgId << csgIndication);
3249 for (std::size_t componentCarrierId = 0; componentCarrierId < m_sib1.size();
3250 componentCarrierId++)
3251 {
3252 m_sib1.at(componentCarrierId).cellAccessRelatedInfo.csgIdentity = csgId;
3253 m_sib1.at(componentCarrierId).cellAccessRelatedInfo.csgIndication = csgIndication;
3254 m_cphySapProvider.at(componentCarrierId)
3255 ->SetSystemInformationBlockType1(m_sib1.at(componentCarrierId));
3256 }
3257}
3258
3260static const uint8_t SRS_ENTRIES = 9;
3265static const uint16_t g_srsPeriodicity[SRS_ENTRIES] = {0, 2, 5, 10, 20, 40, 80, 160, 320};
3271static const uint16_t g_srsCiLow[SRS_ENTRIES] = {0, 0, 2, 7, 17, 37, 77, 157, 317};
3277static const uint16_t g_srsCiHigh[SRS_ENTRIES] = {0, 1, 6, 16, 36, 76, 156, 316, 636};
3278
3279void
3281{
3282 NS_LOG_FUNCTION(this << p);
3283 for (uint32_t id = 1; id < SRS_ENTRIES; ++id)
3284 {
3285 if (g_srsPeriodicity[id] == p)
3286 {
3287 m_srsCurrentPeriodicityId = id;
3288 return;
3289 }
3290 }
3291 // no match found
3292 std::ostringstream allowedValues;
3293 for (uint32_t id = 1; id < SRS_ENTRIES; ++id)
3294 {
3295 allowedValues << g_srsPeriodicity[id] << " ";
3296 }
3297 NS_FATAL_ERROR("illecit SRS periodicity value " << p
3298 << ". Allowed values: " << allowedValues.str());
3299}
3300
3301uint32_t
3303{
3304 NS_LOG_FUNCTION(this);
3305 NS_ASSERT(m_srsCurrentPeriodicityId > 0);
3306 NS_ASSERT(m_srsCurrentPeriodicityId < SRS_ENTRIES);
3307 return g_srsPeriodicity[m_srsCurrentPeriodicityId];
3308}
3309
3310uint16_t
3311NrGnbRrc::GetNewSrsConfigurationIndex()
3312{
3313 NS_LOG_FUNCTION(this << m_ueSrsConfigurationIndexSet.size());
3314 // SRS
3315 NS_ASSERT(m_srsCurrentPeriodicityId > 0);
3316 NS_ASSERT(m_srsCurrentPeriodicityId < SRS_ENTRIES);
3317 NS_LOG_DEBUG(this << " SRS p " << g_srsPeriodicity[m_srsCurrentPeriodicityId] << " set "
3318 << m_ueSrsConfigurationIndexSet.size());
3319 if (m_ueSrsConfigurationIndexSet.size() >= g_srsPeriodicity[m_srsCurrentPeriodicityId])
3320 {
3321 NS_FATAL_ERROR("too many UEs ("
3322 << m_ueSrsConfigurationIndexSet.size() + 1
3323 << ") for current SRS periodicity "
3324 << g_srsPeriodicity[m_srsCurrentPeriodicityId]
3325 << ", consider increasing the value of ns3::NrGnbRrc::SrsPeriodicity");
3326 }
3327
3328 if (m_ueSrsConfigurationIndexSet.empty())
3329 {
3330 // first entry
3331 m_lastAllocatedConfigurationIndex = g_srsCiLow[m_srsCurrentPeriodicityId];
3332 m_ueSrsConfigurationIndexSet.insert(m_lastAllocatedConfigurationIndex);
3333 }
3334 else
3335 {
3336 // find a CI from the available ones
3337 auto rit = m_ueSrsConfigurationIndexSet.rbegin();
3338 NS_ASSERT(rit != m_ueSrsConfigurationIndexSet.rend());
3339 NS_LOG_DEBUG(this << " lower bound " << (*rit) << " of "
3340 << g_srsCiHigh[m_srsCurrentPeriodicityId]);
3341 if ((*rit) < g_srsCiHigh[m_srsCurrentPeriodicityId])
3342 {
3343 // got it from the upper bound
3344 m_lastAllocatedConfigurationIndex = (*rit) + 1;
3345 m_ueSrsConfigurationIndexSet.insert(m_lastAllocatedConfigurationIndex);
3346 }
3347 else
3348 {
3349 // look for released ones
3350 for (uint16_t srcCi = g_srsCiLow[m_srsCurrentPeriodicityId];
3351 srcCi < g_srsCiHigh[m_srsCurrentPeriodicityId];
3352 srcCi++)
3353 {
3354 auto it = m_ueSrsConfigurationIndexSet.find(srcCi);
3355 if (it == m_ueSrsConfigurationIndexSet.end())
3356 {
3357 m_lastAllocatedConfigurationIndex = srcCi;
3358 m_ueSrsConfigurationIndexSet.insert(srcCi);
3359 break;
3360 }
3361 }
3362 }
3363 }
3364 return m_lastAllocatedConfigurationIndex;
3365}
3366
3367void
3368NrGnbRrc::RemoveSrsConfigurationIndex(uint16_t srcCi)
3369{
3370 NS_LOG_FUNCTION(this << srcCi);
3371 auto it = m_ueSrsConfigurationIndexSet.find(srcCi);
3372 NS_ASSERT_MSG(it != m_ueSrsConfigurationIndexSet.end(),
3373 "request to remove unknown SRS CI " << srcCi);
3374 m_ueSrsConfigurationIndexSet.erase(it);
3375}
3376
3377bool
3378NrGnbRrc::IsMaxSrsReached()
3379{
3380 NS_ASSERT(m_srsCurrentPeriodicityId > 0);
3381 NS_ASSERT(m_srsCurrentPeriodicityId < SRS_ENTRIES);
3382 NS_LOG_DEBUG(this << " SRS p " << g_srsPeriodicity[m_srsCurrentPeriodicityId] << " set "
3383 << m_ueSrsConfigurationIndexSet.size());
3384 return m_ueSrsConfigurationIndexSet.size() >= g_srsPeriodicity[m_srsCurrentPeriodicityId];
3385}
3386
3387uint8_t
3388NrGnbRrc::GetLogicalChannelGroup(NrEpsBearer bearer)
3389{
3390 if (bearer.GetResourceType() > 0) // 1, 2 for GBR and DC-GBR
3391 {
3392 return 1;
3393 }
3394 else
3395 {
3396 return 2;
3397 }
3398}
3399
3400uint8_t
3401NrGnbRrc::GetLogicalChannelPriority(NrEpsBearer bearer)
3402{
3403 return bearer.qci;
3404}
3405
3406void
3407NrGnbRrc::SendSystemInformation()
3408{
3409 // NS_LOG_FUNCTION (this);
3410
3411 for (auto& it : m_componentCarrierPhyConf)
3412 {
3413 uint8_t ccId = it.first;
3414
3415 NrRrcSap::SystemInformation si;
3416 si.haveSib2 = true;
3417 si.sib2.freqInfo.ulCarrierFreq = it.second->GetUlEarfcn();
3418 si.sib2.freqInfo.ulBandwidth = it.second->GetUlBandwidth();
3419 si.sib2.radioResourceConfigCommon.pdschConfigCommon.referenceSignalPower =
3420 m_cphySapProvider.at(ccId)->GetReferenceSignalPower();
3421 si.sib2.radioResourceConfigCommon.pdschConfigCommon.pb = 0;
3422
3423 NrGnbCmacSapProvider::RachConfig rc = m_cmacSapProvider.at(ccId)->GetRachConfig();
3424 NrRrcSap::RachConfigCommon rachConfigCommon;
3425 rachConfigCommon.preambleInfo.numberOfRaPreambles = rc.numberOfRaPreambles;
3426 rachConfigCommon.raSupervisionInfo.preambleTransMax = rc.preambleTransMax;
3427 rachConfigCommon.raSupervisionInfo.raResponseWindowSize = rc.raResponseWindowSize;
3428 rachConfigCommon.txFailParam.connEstFailCount = rc.connEstFailCount;
3429 si.sib2.radioResourceConfigCommon.rachConfigCommon = rachConfigCommon;
3430
3431 m_rrcSapUser->SendSystemInformation(it.second->GetCellId(), si);
3432 }
3433
3434 /*
3435 * For simplicity, we use the same periodicity for all SIBs. Note that in real
3436 * systems the periodicy of each SIBs could be different.
3437 */
3438 Simulator::Schedule(m_systemInformationPeriodicity, &NrGnbRrc::SendSystemInformation, this);
3439}
3440
3441bool
3442NrGnbRrc::IsRandomAccessCompleted(uint16_t rnti)
3443{
3444 NS_LOG_FUNCTION(this << (uint32_t)rnti);
3445 Ptr<NrUeManager> ueManager = GetUeManager(rnti);
3446 switch (ueManager->GetState())
3447 {
3448 case NrUeManager::CONNECTED_NORMALLY:
3449 case NrUeManager::CONNECTION_RECONFIGURATION:
3450 return true;
3451 default:
3452 return false;
3453 }
3454}
3455
3456} // 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)
uint32_t GetSrsPeriodicity() const
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 SetSrsPeriodicity(uint32_t p)
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:661
RadioResourceConfigDedicated sourceRadioResourceConfig
source radio resource config
Definition nr-rrc-sap.h:657
MasterInformationBlock sourceMasterInformationBlock
source master information block
Definition nr-rrc-sap.h:659
MeasConfig sourceMeasConfig
source measure config
Definition nr-rrc-sap.h:656
uint16_t sourceUeIdentity
source UE identity
Definition nr-rrc-sap.h:658
SystemInformationBlockType2 sourceSystemInformationBlockType2
source system information block type 2
Definition nr-rrc-sap.h:663
uint32_t sourceDlCarrierFreq
source DL carrier frequency
Definition nr-rrc-sap.h:664
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:947
MasterInformationBlock structure.
Definition nr-rrc-sap.h:627
uint16_t systemFrameNumber
system frame number
Definition nr-rrc-sap.h:629
uint16_t dlBandwidth
DL bandwidth.
Definition nr-rrc-sap.h:628
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:679
uint8_t rsrqResult
the RSRQ result
Definition nr-rrc-sap.h:680
uint8_t measId
measure ID
Definition nr-rrc-sap.h:723
bool haveMeasResultNeighCells
have measure result neighbor cells
Definition nr-rrc-sap.h:725
std::list< MeasResultServFreq > measResultServFreqList
MeasResultServFreqList-r10.
Definition nr-rrc-sap.h:728
MeasResultPCell measResultPCell
measurement result primary cell
Definition nr-rrc-sap.h:724
std::list< MeasResultEutra > measResultListEutra
measure result list eutra
Definition nr-rrc-sap.h:726
bool haveMeasResultServFreqList
has measResultServFreqList-r10
Definition nr-rrc-sap.h:727
MeasurementReport structure.
Definition nr-rrc-sap.h:953
MeasResults measResults
measure results
Definition nr-rrc-sap.h:954
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:880
std::list< uint8_t > sCellToReleaseList
SCell to release list.
Definition nr-rrc-sap.h:881
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:903
RrcConnectionReconfiguration structure.
Definition nr-rrc-sap.h:886
MobilityControlInfo mobilityControlInfo
mobility control info
Definition nr-rrc-sap.h:891
bool haveMobilityControlInfo
have mobility control info
Definition nr-rrc-sap.h:890
NonCriticalExtensionConfiguration nonCriticalExtension
Definition nr-rrc-sap.h:898
RrcConnectionReestablishmentComplete structure.
Definition nr-rrc-sap.h:924
RrcConnectionReestablishment structure.
Definition nr-rrc-sap.h:916
RadioResourceConfigDedicated radioResourceConfigDedicated
radio resource config dedicated
Definition nr-rrc-sap.h:919
uint8_t rrcTransactionIdentifier
RRC transaction identifier.
Definition nr-rrc-sap.h:917
RrcConnectionReestablishmentRequest structure.
Definition nr-rrc-sap.h:909
RrcConnectionReject structure.
Definition nr-rrc-sap.h:941
RrcConnectionRelease structure.
Definition nr-rrc-sap.h:935
uint8_t rrcTransactionIdentifier
RRC transaction identifier.
Definition nr-rrc-sap.h:936
RrcConnectionRequest structure.
Definition nr-rrc-sap.h:735
uint64_t ueIdentity
UE identity.
Definition nr-rrc-sap.h:736
RrcConnectionSetupCompleted structure.
Definition nr-rrc-sap.h:749
RrcConnectionSetup structure.
Definition nr-rrc-sap.h:741
RadioResourceConfigDedicated radioResourceConfigDedicated
radio resource config dedicated
Definition nr-rrc-sap.h:744
uint8_t rrcTransactionIdentifier
RRC transaction identifier.
Definition nr-rrc-sap.h:742
uint16_t srsConfigIndex
SRS config index.
Definition nr-rrc-sap.h:132
SystemInformationBlockType1 structure.
Definition nr-rrc-sap.h:634
CellSelectionInfo cellSelectionInfo
cell selection info
Definition nr-rrc-sap.h:636
CellAccessRelatedInfo cellAccessRelatedInfo
cell access related info
Definition nr-rrc-sap.h:635
RadioResourceConfigCommonSib radioResourceConfigCommon
radio resource config common
Definition nr-rrc-sap.h:642
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