5G-LENA nr-v3.0-32-g83aee33
The 5G/NR module for the ns-3 simulator
Loading...
Searching...
No Matches
nr-helper.cc
1/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
2
3// Copyright (c) 2019 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
4//
5// SPDX-License-Identifier: GPL-2.0-only
6
7#include "nr-helper.h"
8
9#include "nr-bearer-stats-calculator.h"
10#include "nr-mac-rx-trace.h"
11#include "nr-phy-rx-trace.h"
12
13#include <ns3/bandwidth-part-gnb.h>
14#include <ns3/bandwidth-part-ue.h>
15#include <ns3/beam-manager.h>
16#include <ns3/buildings-channel-condition-model.h>
17#include <ns3/bwp-manager-algorithm.h>
18#include <ns3/bwp-manager-gnb.h>
19#include <ns3/bwp-manager-ue.h>
20#include <ns3/config.h>
21#include <ns3/epc-enb-application.h>
22#include <ns3/epc-helper.h>
23#include <ns3/epc-ue-nas.h>
24#include <ns3/epc-x2.h>
25#include <ns3/lte-chunk-processor.h>
26#include <ns3/lte-rrc-protocol-ideal.h>
27#include <ns3/lte-rrc-protocol-real.h>
28#include <ns3/lte-ue-rrc.h>
29#include <ns3/multi-model-spectrum-channel.h>
30#include <ns3/names.h>
31#include <ns3/nr-ch-access-manager.h>
32#include <ns3/nr-gnb-mac.h>
33#include <ns3/nr-gnb-net-device.h>
34#include <ns3/nr-gnb-phy.h>
35#include <ns3/nr-mac-scheduler-tdma-rr.h>
36#include <ns3/nr-pm-search-full.h>
37#include <ns3/nr-rrc-protocol-ideal.h>
38#include <ns3/nr-ue-mac.h>
39#include <ns3/nr-ue-net-device.h>
40#include <ns3/nr-ue-phy.h>
41#include <ns3/pointer.h>
42#include <ns3/three-gpp-channel-model.h>
43#include <ns3/three-gpp-propagation-loss-model.h>
44#include <ns3/three-gpp-spectrum-propagation-loss-model.h>
45#include <ns3/three-gpp-v2v-channel-condition-model.h>
46#include <ns3/three-gpp-v2v-propagation-loss-model.h>
47#include <ns3/uniform-planar-array.h>
48
49#include <algorithm>
50
51namespace ns3
52{
53
54/* ... */
55NS_LOG_COMPONENT_DEFINE("NrHelper");
56
57NS_OBJECT_ENSURE_REGISTERED(NrHelper);
58
60{
61 NS_LOG_FUNCTION(this);
62 m_channelFactory.SetTypeId(MultiModelSpectrumChannel::GetTypeId());
63 m_gnbNetDeviceFactory.SetTypeId(NrGnbNetDevice::GetTypeId());
64 m_ueNetDeviceFactory.SetTypeId(NrUeNetDevice::GetTypeId());
65 m_ueMacFactory.SetTypeId(NrUeMac::GetTypeId());
66 m_gnbMacFactory.SetTypeId(NrGnbMac::GetTypeId());
67 m_ueSpectrumFactory.SetTypeId(NrSpectrumPhy::GetTypeId());
68 m_gnbSpectrumFactory.SetTypeId(NrSpectrumPhy::GetTypeId());
69 m_uePhyFactory.SetTypeId(NrUePhy::GetTypeId());
70 m_gnbPhyFactory.SetTypeId(NrGnbPhy::GetTypeId());
71 m_ueChannelAccessManagerFactory.SetTypeId(NrAlwaysOnAccessManager::GetTypeId());
72 m_gnbChannelAccessManagerFactory.SetTypeId(NrAlwaysOnAccessManager::GetTypeId());
73 m_schedFactory.SetTypeId(NrMacSchedulerTdmaRR::GetTypeId());
74 m_ueAntennaFactory.SetTypeId(UniformPlanarArray::GetTypeId());
75 m_gnbAntennaFactory.SetTypeId(UniformPlanarArray::GetTypeId());
76 m_gnbBwpManagerAlgoFactory.SetTypeId(BwpManagerAlgorithmStatic::GetTypeId());
77 m_ueBwpManagerAlgoFactory.SetTypeId(BwpManagerAlgorithmStatic::GetTypeId());
78 m_gnbUlAmcFactory.SetTypeId(NrAmc::GetTypeId());
79 m_gnbDlAmcFactory.SetTypeId(NrAmc::GetTypeId());
80 m_gnbBeamManagerFactory.SetTypeId(BeamManager::GetTypeId());
81 m_ueBeamManagerFactory.SetTypeId(BeamManager::GetTypeId());
82 m_spectrumPropagationFactory.SetTypeId(ThreeGppSpectrumPropagationLossModel::GetTypeId());
83
84 // Initialization that is there just because the user can configure attribute
85 // through the helper methods without making it sad that no TypeId is set.
86 // When the TypeId is changed, the user-set attribute will be maintained.
87 m_pathlossModelFactory.SetTypeId(ThreeGppPropagationLossModel::GetTypeId());
88 m_channelConditionModelFactory.SetTypeId(ThreeGppChannelConditionModel::GetTypeId());
89
90 Config::SetDefault("ns3::EpsBearer::Release", UintegerValue(18));
91
92 m_phyStats = CreateObject<NrPhyRxTrace>();
93 m_macSchedStats = CreateObject<NrMacSchedulingStats>();
94}
95
97{
98 NS_LOG_FUNCTION(this);
99}
100
101TypeId
103{
104 static TypeId tid = TypeId("ns3::NrHelper")
105 .SetParent<Object>()
106 .AddConstructor<NrHelper>()
107 .AddAttribute("EnableMimoFeedback",
108 "Generate CQI feedback with RI and PMI for MIMO support",
109 BooleanValue(false),
110 MakeBooleanAccessor(&NrHelper::m_enableMimoFeedback),
111 MakeBooleanChecker())
112 .AddAttribute("PmSearchMethod",
113 "Type of the precoding matrix search method.",
114 TypeIdValue(NrPmSearchFull::GetTypeId()),
115 MakeTypeIdAccessor(&NrHelper::SetPmSearchTypeId),
116 MakeTypeIdChecker())
117 .AddAttribute("HarqEnabled",
118 "Enable Hybrid ARQ",
119 BooleanValue(true),
120 MakeBooleanAccessor(&NrHelper::m_harqEnabled),
121 MakeBooleanChecker());
122 return tid;
123}
124
125typedef std::function<void(ObjectFactory*, ObjectFactory*)> InitPathLossFn;
126
127static void
128InitRma(ObjectFactory* pathlossModelFactory, ObjectFactory* channelConditionModelFactory)
129{
130 pathlossModelFactory->SetTypeId(ThreeGppRmaPropagationLossModel::GetTypeId());
131 channelConditionModelFactory->SetTypeId(ThreeGppRmaChannelConditionModel::GetTypeId());
132}
133
134static void
135InitRma_LoS(ObjectFactory* pathlossModelFactory, ObjectFactory* channelConditionModelFactory)
136{
137 pathlossModelFactory->SetTypeId(ThreeGppRmaPropagationLossModel::GetTypeId());
138 channelConditionModelFactory->SetTypeId(AlwaysLosChannelConditionModel::GetTypeId());
139}
140
141static void
142InitRma_nLoS(ObjectFactory* pathlossModelFactory, ObjectFactory* channelConditionModelFactory)
143{
144 pathlossModelFactory->SetTypeId(ThreeGppRmaPropagationLossModel::GetTypeId());
145 channelConditionModelFactory->SetTypeId(NeverLosChannelConditionModel::GetTypeId());
146}
147
148static void
149InitUma(ObjectFactory* pathlossModelFactory, ObjectFactory* channelConditionModelFactory)
150{
151 pathlossModelFactory->SetTypeId(ThreeGppUmaPropagationLossModel::GetTypeId());
152 channelConditionModelFactory->SetTypeId(ThreeGppUmaChannelConditionModel::GetTypeId());
153}
154
155static void
156InitUma_LoS(ObjectFactory* pathlossModelFactory, ObjectFactory* channelConditionModelFactory)
157{
158 pathlossModelFactory->SetTypeId(ThreeGppUmaPropagationLossModel::GetTypeId());
159 channelConditionModelFactory->SetTypeId(AlwaysLosChannelConditionModel::GetTypeId());
160}
161
162static void
163InitUma_nLoS(ObjectFactory* pathlossModelFactory, ObjectFactory* channelConditionModelFactory)
164{
165 pathlossModelFactory->SetTypeId(ThreeGppUmaPropagationLossModel::GetTypeId());
166 channelConditionModelFactory->SetTypeId(NeverLosChannelConditionModel::GetTypeId());
167}
168
169static void
170InitUmi(ObjectFactory* pathlossModelFactory, ObjectFactory* channelConditionModelFactory)
171{
172 pathlossModelFactory->SetTypeId(ThreeGppUmiStreetCanyonPropagationLossModel::GetTypeId());
173 channelConditionModelFactory->SetTypeId(
174 ThreeGppUmiStreetCanyonChannelConditionModel::GetTypeId());
175}
176
177static void
178InitUmi_LoS(ObjectFactory* pathlossModelFactory, ObjectFactory* channelConditionModelFactory)
179{
180 pathlossModelFactory->SetTypeId(ThreeGppUmiStreetCanyonPropagationLossModel::GetTypeId());
181 channelConditionModelFactory->SetTypeId(AlwaysLosChannelConditionModel::GetTypeId());
182}
183
184static void
185InitUmi_nLoS(ObjectFactory* pathlossModelFactory, ObjectFactory* channelConditionModelFactory)
186{
187 pathlossModelFactory->SetTypeId(ThreeGppUmiStreetCanyonPropagationLossModel::GetTypeId());
188 channelConditionModelFactory->SetTypeId(NeverLosChannelConditionModel::GetTypeId());
189}
190
191static void
192InitIndoorOpen(ObjectFactory* pathlossModelFactory, ObjectFactory* channelConditionModelFactory)
193{
194 pathlossModelFactory->SetTypeId(ThreeGppIndoorOfficePropagationLossModel::GetTypeId());
195 channelConditionModelFactory->SetTypeId(
196 ThreeGppIndoorOpenOfficeChannelConditionModel::GetTypeId());
197}
198
199static void
200InitIndoorOpen_LoS(ObjectFactory* pathlossModelFactory, ObjectFactory* channelConditionModelFactory)
201{
202 pathlossModelFactory->SetTypeId(ThreeGppIndoorOfficePropagationLossModel::GetTypeId());
203 channelConditionModelFactory->SetTypeId(AlwaysLosChannelConditionModel::GetTypeId());
204}
205
206static void
207InitIndoorOpen_nLoS(ObjectFactory* pathlossModelFactory,
208 ObjectFactory* channelConditionModelFactory)
209{
210 pathlossModelFactory->SetTypeId(ThreeGppIndoorOfficePropagationLossModel::GetTypeId());
211 channelConditionModelFactory->SetTypeId(NeverLosChannelConditionModel::GetTypeId());
212}
213
214static void
215InitIndoorMixed(ObjectFactory* pathlossModelFactory, ObjectFactory* channelConditionModelFactory)
216{
217 pathlossModelFactory->SetTypeId(ThreeGppIndoorOfficePropagationLossModel::GetTypeId());
218 channelConditionModelFactory->SetTypeId(
219 ThreeGppIndoorMixedOfficeChannelConditionModel::GetTypeId());
220}
221
222static void
223InitIndoorMixed_LoS(ObjectFactory* pathlossModelFactory,
224 ObjectFactory* channelConditionModelFactory)
225{
226 pathlossModelFactory->SetTypeId(ThreeGppIndoorOfficePropagationLossModel::GetTypeId());
227 channelConditionModelFactory->SetTypeId(AlwaysLosChannelConditionModel::GetTypeId());
228}
229
230static void
231InitIndoorMixed_nLoS(ObjectFactory* pathlossModelFactory,
232 ObjectFactory* channelConditionModelFactory)
233{
234 pathlossModelFactory->SetTypeId(ThreeGppIndoorOfficePropagationLossModel::GetTypeId());
235 channelConditionModelFactory->SetTypeId(NeverLosChannelConditionModel::GetTypeId());
236}
237
238static void
239InitUmaBuildings(ObjectFactory* pathlossModelFactory, ObjectFactory* channelConditionModelFactory)
240{
241 pathlossModelFactory->SetTypeId(ThreeGppUmaPropagationLossModel::GetTypeId());
242 channelConditionModelFactory->SetTypeId(BuildingsChannelConditionModel::GetTypeId());
243}
244
245static void
246InitUmiBuildings(ObjectFactory* pathlossModelFactory, ObjectFactory* channelConditionModelFactory)
247{
248 pathlossModelFactory->SetTypeId(ThreeGppUmiStreetCanyonPropagationLossModel::GetTypeId());
249 channelConditionModelFactory->SetTypeId(BuildingsChannelConditionModel::GetTypeId());
250}
251
252static void
253InitV2VHighway(ObjectFactory* pathlossModelFactory, ObjectFactory* channelConditionModelFactory)
254{
255 pathlossModelFactory->SetTypeId(ThreeGppV2vHighwayPropagationLossModel::GetTypeId());
256 channelConditionModelFactory->SetTypeId(ThreeGppV2vHighwayChannelConditionModel::GetTypeId());
257}
258
259static void
260InitV2VUrban(ObjectFactory* pathlossModelFactory, ObjectFactory* channelConditionModelFactory)
261{
262 pathlossModelFactory->SetTypeId(ThreeGppV2vUrbanPropagationLossModel::GetTypeId());
263 channelConditionModelFactory->SetTypeId(ThreeGppV2vUrbanChannelConditionModel::GetTypeId());
264}
265
266void
268{
269 NS_LOG_FUNCTION(this);
270
271 static std::unordered_map<BandwidthPartInfo::Scenario, InitPathLossFn, std::hash<int>>
272 initLookupTable{
273 {BandwidthPartInfo::RMa,
274 std::bind(&InitRma, std::placeholders::_1, std::placeholders::_2)},
276 std::bind(&InitRma_LoS, std::placeholders::_1, std::placeholders::_2)},
278 std::bind(&InitRma_nLoS, std::placeholders::_1, std::placeholders::_2)},
280 std::bind(&InitUma, std::placeholders::_1, std::placeholders::_2)},
282 std::bind(&InitUma_LoS, std::placeholders::_1, std::placeholders::_2)},
284 std::bind(&InitUma_nLoS, std::placeholders::_1, std::placeholders::_2)},
286 std::bind(&InitUmi, std::placeholders::_1, std::placeholders::_2)},
288 std::bind(&InitUmi_LoS, std::placeholders::_1, std::placeholders::_2)},
290 std::bind(&InitUmi_nLoS, std::placeholders::_1, std::placeholders::_2)},
292 std::bind(&InitIndoorOpen, std::placeholders::_1, std::placeholders::_2)},
294 std::bind(&InitIndoorOpen_LoS, std::placeholders::_1, std::placeholders::_2)},
296 std::bind(&InitIndoorOpen_nLoS, std::placeholders::_1, std::placeholders::_2)},
298 std::bind(&InitIndoorMixed, std::placeholders::_1, std::placeholders::_2)},
300 std::bind(&InitIndoorMixed_LoS, std::placeholders::_1, std::placeholders::_2)},
302 std::bind(&InitIndoorMixed_nLoS, std::placeholders::_1, std::placeholders::_2)},
304 std::bind(&InitUmaBuildings, std::placeholders::_1, std::placeholders::_2)},
306 std::bind(&InitUmiBuildings, std::placeholders::_1, std::placeholders::_2)},
308 std::bind(&InitV2VHighway, std::placeholders::_1, std::placeholders::_2)},
310 std::bind(&InitV2VUrban, std::placeholders::_1, std::placeholders::_2)},
311 };
312
313 // Iterate over all CCs, and instantiate the channel and propagation model
314 for (const auto& cc : band->m_cc)
315 {
316 for (const auto& bwp : cc->m_bwp)
317 {
318 // Initialize the type ID of the factories by calling the relevant
319 // static function defined above and stored inside the lookup table
320 initLookupTable.at(bwp->m_scenario)(&m_pathlossModelFactory,
321 &m_channelConditionModelFactory);
322
323 auto channelConditionModel =
324 m_channelConditionModelFactory.Create<ChannelConditionModel>();
325
326 if (bwp->m_propagation == nullptr && flags & INIT_PROPAGATION)
327 {
328 bwp->m_propagation = m_pathlossModelFactory.Create<ThreeGppPropagationLossModel>();
329 bwp->m_propagation->SetAttributeFailSafe("Frequency",
330 DoubleValue(bwp->m_centralFrequency));
331 DynamicCast<ThreeGppPropagationLossModel>(bwp->m_propagation)
332 ->SetChannelConditionModel(channelConditionModel);
333 }
334
335 if (bwp->m_3gppChannel == nullptr && flags & INIT_FADING)
336 {
337 bwp->m_3gppChannel =
338 m_spectrumPropagationFactory.Create<ThreeGppSpectrumPropagationLossModel>();
339 DynamicCast<ThreeGppSpectrumPropagationLossModel>(bwp->m_3gppChannel)
340 ->SetChannelModelAttribute("Frequency", DoubleValue(bwp->m_centralFrequency));
341 DynamicCast<ThreeGppSpectrumPropagationLossModel>(bwp->m_3gppChannel)
342 ->SetChannelModelAttribute("Scenario", StringValue(bwp->GetScenario()));
343 DynamicCast<ThreeGppSpectrumPropagationLossModel>(bwp->m_3gppChannel)
344 ->SetChannelModelAttribute("ChannelConditionModel",
345 PointerValue(channelConditionModel));
346 }
347
348 if (bwp->m_channel == nullptr && flags & INIT_CHANNEL)
349 {
350 bwp->m_channel = m_channelFactory.Create<SpectrumChannel>();
351 bwp->m_channel->AddPropagationLossModel(bwp->m_propagation);
352 bwp->m_channel->AddPhasedArraySpectrumPropagationLossModel(bwp->m_3gppChannel);
353 }
354 }
355 }
356}
357
358uint32_t
359NrHelper::GetNumberBwp(const Ptr<const NetDevice>& gnbDevice)
360{
361 NS_LOG_FUNCTION(gnbDevice);
362 Ptr<const NrGnbNetDevice> netDevice = DynamicCast<const NrGnbNetDevice>(gnbDevice);
363 if (netDevice == nullptr)
364 {
365 return 0;
366 }
367 return netDevice->GetCcMapSize();
368}
369
370Ptr<NrGnbPhy>
371NrHelper::GetGnbPhy(const Ptr<NetDevice>& gnbDevice, uint32_t bwpIndex)
372{
373 NS_LOG_FUNCTION(gnbDevice << bwpIndex);
374 NS_ASSERT(bwpIndex < UINT8_MAX);
375 Ptr<NrGnbNetDevice> netDevice = DynamicCast<NrGnbNetDevice>(gnbDevice);
376 if (netDevice == nullptr)
377 {
378 return nullptr;
379 }
380 return netDevice->GetPhy(static_cast<uint8_t>(bwpIndex));
381}
382
383Ptr<NrGnbMac>
384NrHelper::GetGnbMac(const Ptr<NetDevice>& gnbDevice, uint32_t bwpIndex)
385{
386 NS_LOG_FUNCTION(gnbDevice << bwpIndex);
387 NS_ASSERT(bwpIndex < UINT8_MAX);
388 Ptr<NrGnbNetDevice> netDevice = DynamicCast<NrGnbNetDevice>(gnbDevice);
389 if (netDevice == nullptr)
390 {
391 return nullptr;
392 }
393 return netDevice->GetMac(static_cast<uint8_t>(bwpIndex));
394}
395
396Ptr<NrUeMac>
397NrHelper::GetUeMac(const Ptr<NetDevice>& ueDevice, uint32_t bwpIndex)
398{
399 NS_LOG_FUNCTION(ueDevice << bwpIndex);
400 NS_ASSERT(bwpIndex < UINT8_MAX);
401 Ptr<NrUeNetDevice> netDevice = DynamicCast<NrUeNetDevice>(ueDevice);
402 if (netDevice == nullptr)
403 {
404 return nullptr;
405 }
406 return netDevice->GetMac(static_cast<uint8_t>(bwpIndex));
407}
408
409Ptr<NrUePhy>
410NrHelper::GetUePhy(const Ptr<NetDevice>& ueDevice, uint32_t bwpIndex)
411{
412 NS_LOG_FUNCTION(ueDevice << bwpIndex);
413 NS_ASSERT(bwpIndex < UINT8_MAX);
414 Ptr<NrUeNetDevice> netDevice = DynamicCast<NrUeNetDevice>(ueDevice);
415 if (netDevice == nullptr)
416 {
417 return nullptr;
418 }
419 return netDevice->GetPhy(static_cast<uint8_t>(bwpIndex));
420}
421
422Ptr<BwpManagerGnb>
423NrHelper::GetBwpManagerGnb(const Ptr<NetDevice>& gnbDevice)
424{
425 NS_LOG_FUNCTION(gnbDevice);
426
427 Ptr<NrGnbNetDevice> netDevice = DynamicCast<NrGnbNetDevice>(gnbDevice);
428 if (netDevice == nullptr)
429 {
430 return nullptr;
431 }
432
433 return netDevice->GetBwpManager();
434}
435
436Ptr<BwpManagerUe>
437NrHelper::GetBwpManagerUe(const Ptr<NetDevice>& ueDevice)
438{
439 NS_LOG_FUNCTION(ueDevice);
440
441 Ptr<NrUeNetDevice> netDevice = DynamicCast<NrUeNetDevice>(ueDevice);
442 if (netDevice == nullptr)
443 {
444 return nullptr;
445 }
446
447 return netDevice->GetBwpManager();
448}
449
450Ptr<NrMacScheduler>
451NrHelper::GetScheduler(const Ptr<NetDevice>& gnbDevice, uint32_t bwpIndex)
452{
453 NS_LOG_FUNCTION(gnbDevice << bwpIndex);
454
455 Ptr<NrGnbNetDevice> netDevice = DynamicCast<NrGnbNetDevice>(gnbDevice);
456 if (netDevice == nullptr)
457 {
458 return nullptr;
459 }
460
461 return netDevice->GetScheduler(bwpIndex);
462}
463
464void
466{
467 m_harqEnabled = harqEnabled;
468}
469
470bool
472{
473 return m_harqEnabled;
474}
475
476void
478{
479 m_snrTest = snrTest;
480}
481
482bool
484{
485 return m_snrTest;
486}
487
488NetDeviceContainer
489NrHelper::InstallUeDevice(const NodeContainer& c,
490 const std::vector<std::reference_wrapper<BandwidthPartInfoPtr>>& allBwps)
491{
492 NS_LOG_FUNCTION(this);
493 Initialize(); // Run DoInitialize (), if necessary
494 NetDeviceContainer devices;
495 for (NodeContainer::Iterator i = c.Begin(); i != c.End(); ++i)
496 {
497 Ptr<Node> node = *i;
498 Ptr<NetDevice> device = InstallSingleUeDevice(node, allBwps);
499 device->SetAddress(Mac48Address::Allocate());
500 devices.Add(device);
501 }
502 return devices;
503}
504
505NetDeviceContainer
506NrHelper::InstallGnbDevice(const NodeContainer& c,
507 const std::vector<std::reference_wrapper<BandwidthPartInfoPtr>> allBwps)
508{
509 NS_LOG_FUNCTION(this);
510 Initialize(); // Run DoInitialize (), if necessary
511 NetDeviceContainer devices;
512 for (NodeContainer::Iterator i = c.Begin(); i != c.End(); ++i)
513 {
514 Ptr<Node> node = *i;
515 Ptr<NetDevice> device = InstallSingleGnbDevice(node, allBwps);
516 device->SetAddress(Mac48Address::Allocate());
517 devices.Add(device);
518 }
519 return devices;
520}
521
522Ptr<NrUeMac>
523NrHelper::CreateUeMac() const
524{
525 NS_LOG_FUNCTION(this);
526 Ptr<NrUeMac> mac = m_ueMacFactory.Create<NrUeMac>();
527 return mac;
528}
529
530Ptr<NrUePhy>
531NrHelper::CreateUePhy(const Ptr<Node>& n,
532 const std::unique_ptr<BandwidthPartInfo>& bwp,
533 const Ptr<NrUeNetDevice>& dev,
534 const NrSpectrumPhy::NrPhyDlHarqFeedbackCallback& dlHarqCallback,
535 const NrSpectrumPhy::NrPhyRxCtrlEndOkCallback& phyRxCtrlCallback)
536{
537 NS_LOG_FUNCTION(this);
538
539 Ptr<NrUePhy> phy = m_uePhyFactory.Create<NrUePhy>();
540
541 NS_ASSERT(bwp->m_channel != nullptr);
542
543 phy->InstallCentralFrequency(bwp->m_centralFrequency);
544
545 phy->ScheduleStartEventLoop(n->GetId(), 0, 0, 0);
546
547 // connect CAM and PHY
548 Ptr<NrChAccessManager> cam =
549 DynamicCast<NrChAccessManager>(m_ueChannelAccessManagerFactory.Create());
550 phy->SetCam(cam);
551 // set device
552 phy->SetDevice(dev);
553
554 Ptr<MobilityModel> mm = n->GetObject<MobilityModel>();
555 NS_ASSERT_MSG(
556 mm,
557 "MobilityModel needs to be set on node before calling NrHelper::InstallUeDevice ()");
558
559 Ptr<NrSpectrumPhy> channelPhy =
560 m_ueSpectrumFactory.Create<NrSpectrumPhy>(); // Create NrSpectrumPhy
561
562 if (m_harqEnabled)
563 {
564 Ptr<NrHarqPhy> harq = Create<NrHarqPhy>(); // Create HARQ instance
565 channelPhy->InstallHarqPhyModule(harq);
566 channelPhy->SetPhyDlHarqFeedbackCallback(dlHarqCallback);
567 }
568 channelPhy->SetIsEnb(false);
569 channelPhy->SetDevice(dev); // each NrSpectrumPhy should have a pointer to device
570
571 Ptr<UniformPlanarArray> antenna =
572 m_ueAntennaFactory.Create<UniformPlanarArray>(); // Create antenna per panel
573 channelPhy->SetAntenna(antenna);
574
575 cam->SetNrSpectrumPhy(channelPhy); // connect CAM
576
577 Ptr<LteChunkProcessor> pData = Create<LteChunkProcessor>();
578 pData->AddCallback(MakeCallback(&NrSpectrumPhy::UpdateSinrPerceived, channelPhy));
579 channelPhy->AddDataSinrChunkProcessor(pData);
580
581 Ptr<NrMimoChunkProcessor> pDataMimo{nullptr};
582 if (bwp->m_3gppChannel)
583 {
584 pDataMimo = Create<NrMimoChunkProcessor>();
585 pDataMimo->AddCallback(MakeCallback(&NrSpectrumPhy::UpdateMimoSinrPerceived, channelPhy));
586 channelPhy->AddDataMimoChunkProcessor(pDataMimo);
587 }
588 if (bwp->m_3gppChannel && m_enableMimoFeedback)
589 {
590 // Report DL CQI, PMI, RI (channel quality, MIMO precoding matrix and rank indicators)
591 pDataMimo->AddCallback(MakeCallback(&NrUePhy::GenerateDlCqiReportMimo, phy));
592 }
593 else
594 {
595 // SISO CQI feedback
596 pData->AddCallback(MakeCallback(&NrUePhy::GenerateDlCqiReport, phy));
597 }
598
599 Ptr<LteChunkProcessor> pRs = Create<LteChunkProcessor>();
600 pRs->AddCallback(MakeCallback(&NrUePhy::ReportRsReceivedPower, phy));
601 channelPhy->AddRsPowerChunkProcessor(pRs);
602
603 Ptr<LteChunkProcessor> pSinr = Create<LteChunkProcessor>();
604 pSinr->AddCallback(MakeCallback(&NrSpectrumPhy::ReportDlCtrlSinr, channelPhy));
605 channelPhy->AddDlCtrlSinrChunkProcessor(pSinr);
606
607 channelPhy->SetChannel(bwp->m_channel);
608 channelPhy->InstallPhy(phy);
609 channelPhy->SetMobility(mm);
610 channelPhy->SetPhyRxDataEndOkCallback(MakeCallback(&NrUePhy::PhyDataPacketReceived, phy));
611 channelPhy->SetPhyRxCtrlEndOkCallback(phyRxCtrlCallback);
612
613 Ptr<BeamManager> beamManager = m_ueBeamManagerFactory.Create<BeamManager>();
614 beamManager->Configure(antenna);
615 channelPhy->SetBeamManager(beamManager);
616 phy->InstallSpectrumPhy(channelPhy);
617 return phy;
618}
619
620Ptr<NetDevice>
621NrHelper::InstallSingleUeDevice(
622 const Ptr<Node>& n,
623 const std::vector<std::reference_wrapper<BandwidthPartInfoPtr>> allBwps)
624{
625 NS_LOG_FUNCTION(this);
626
627 Ptr<NrUeNetDevice> dev = m_ueNetDeviceFactory.Create<NrUeNetDevice>();
628 dev->SetNode(n);
629
630 std::map<uint8_t, Ptr<BandwidthPartUe>> ueCcMap;
631
632 // Create, for each ue, its bandwidth parts
633 for (uint32_t bwpId = 0; bwpId < allBwps.size(); ++bwpId)
634 {
635 Ptr<BandwidthPartUe> cc = CreateObject<BandwidthPartUe>();
636 double bwInKhz = allBwps[bwpId].get()->m_channelBandwidth / 1000.0;
637 NS_ABORT_MSG_IF(bwInKhz / 100.0 > 65535.0,
638 "A bandwidth of " << bwInKhz / 100.0 << " kHz cannot be represented");
639 cc->SetUlBandwidth(static_cast<uint16_t>(bwInKhz / 100));
640 cc->SetDlBandwidth(static_cast<uint16_t>(bwInKhz / 100));
641 cc->SetDlEarfcn(0); // Used for nothing..
642 cc->SetUlEarfcn(0); // Used for nothing..
643
644 auto mac = CreateUeMac();
645 cc->SetMac(mac);
646
647 auto phy = CreateUePhy(
648 n,
649 allBwps[bwpId].get(),
650 dev,
651 MakeCallback(&NrUeNetDevice::EnqueueDlHarqFeedback, dev),
652 std::bind(&NrUeNetDevice::RouteIngoingCtrlMsgs, dev, std::placeholders::_1, bwpId));
653
654 phy->SetBwpId(bwpId);
655 cc->SetPhy(phy);
656
657 if (bwpId == 0)
658 {
659 cc->SetAsPrimary(true);
660 }
661 else
662 {
663 cc->SetAsPrimary(false);
664 }
665
666 ueCcMap.insert(std::make_pair(bwpId, cc));
667 }
668
669 Ptr<LteUeComponentCarrierManager> ccmUe =
670 DynamicCast<LteUeComponentCarrierManager>(CreateObject<BwpManagerUe>());
671 DynamicCast<BwpManagerUe>(ccmUe)->SetBwpManagerAlgorithm(
672 m_ueBwpManagerAlgoFactory.Create<BwpManagerAlgorithm>());
673
674 Ptr<LteUeRrc> rrc = CreateObject<LteUeRrc>();
675 rrc->m_numberOfComponentCarriers = ueCcMap.size();
676 // run InitializeSap to create the proper number of sap provider/users
677 rrc->InitializeSap();
678 rrc->SetLteMacSapProvider(ccmUe->GetLteMacSapProvider());
679 // setting ComponentCarrierManager SAP
680 rrc->SetLteCcmRrcSapProvider(ccmUe->GetLteCcmRrcSapProvider());
681 ccmUe->SetLteCcmRrcSapUser(rrc->GetLteCcmRrcSapUser());
682 ccmUe->SetNumberOfComponentCarriers(ueCcMap.size());
683
684 bool useIdealRrc = true;
685 if (useIdealRrc)
686 {
687 Ptr<nrUeRrcProtocolIdeal> rrcProtocol = CreateObject<nrUeRrcProtocolIdeal>();
688 rrcProtocol->SetUeRrc(rrc);
689 rrc->AggregateObject(rrcProtocol);
690 rrcProtocol->SetLteUeRrcSapProvider(rrc->GetLteUeRrcSapProvider());
691 rrc->SetLteUeRrcSapUser(rrcProtocol->GetLteUeRrcSapUser());
692 }
693 else
694 {
695 Ptr<LteUeRrcProtocolReal> rrcProtocol = CreateObject<LteUeRrcProtocolReal>();
696 rrcProtocol->SetUeRrc(rrc);
697 rrc->AggregateObject(rrcProtocol);
698 rrcProtocol->SetLteUeRrcSapProvider(rrc->GetLteUeRrcSapProvider());
699 rrc->SetLteUeRrcSapUser(rrcProtocol->GetLteUeRrcSapUser());
700 }
701
702 if (m_epcHelper != nullptr)
703 {
704 rrc->SetUseRlcSm(false);
705 }
706 else
707 {
708 rrc->SetUseRlcSm(true);
709 }
710 Ptr<EpcUeNas> nas = CreateObject<EpcUeNas>();
711
712 nas->SetAsSapProvider(rrc->GetAsSapProvider());
713 nas->SetDevice(dev);
714 nas->SetForwardUpCallback(MakeCallback(&NrUeNetDevice::Receive, dev));
715
716 rrc->SetAsSapUser(nas->GetAsSapUser());
717
718 for (auto& it : ueCcMap)
719 {
720 rrc->SetLteUeCmacSapProvider(it.second->GetMac()->GetUeCmacSapProvider(), it.first);
721 it.second->GetMac()->SetUeCmacSapUser(rrc->GetLteUeCmacSapUser(it.first));
722
723 it.second->GetPhy()->SetUeCphySapUser(rrc->GetLteUeCphySapUser());
724 rrc->SetLteUeCphySapProvider(it.second->GetPhy()->GetUeCphySapProvider(), it.first);
725
726 it.second->GetPhy()->SetPhySapUser(it.second->GetMac()->GetPhySapUser());
727 it.second->GetMac()->SetPhySapProvider(it.second->GetPhy()->GetPhySapProvider());
728
729 bool ccmTest =
730 ccmUe->SetComponentCarrierMacSapProviders(it.first,
731 it.second->GetMac()->GetUeMacSapProvider());
732
733 if (!ccmTest)
734 {
735 NS_FATAL_ERROR("Error in SetComponentCarrierMacSapProviders");
736 }
737 }
738
739 NS_ABORT_MSG_IF(m_imsiCounter >= 0xFFFFFFFF, "max num UEs exceeded");
740 uint64_t imsi = ++m_imsiCounter;
741
742 dev->SetAttribute("Imsi", UintegerValue(imsi));
743 dev->SetCcMap(ueCcMap);
744 dev->SetAttribute("nrUeRrc", PointerValue(rrc));
745 dev->SetAttribute("EpcUeNas", PointerValue(nas));
746 dev->SetAttribute("LteUeComponentCarrierManager", PointerValue(ccmUe));
747
748 n->AddDevice(dev);
749
750 if (m_epcHelper != nullptr)
751 {
752 m_epcHelper->AddUe(dev, dev->GetImsi());
753 }
754
755 dev->Initialize();
756
757 return dev;
758}
759
760Ptr<NrGnbPhy>
761NrHelper::CreateGnbPhy(const Ptr<Node>& n,
762 const std::unique_ptr<BandwidthPartInfo>& bwp,
763 const Ptr<NrGnbNetDevice>& dev,
764 const NrSpectrumPhy::NrPhyRxCtrlEndOkCallback& phyEndCtrlCallback)
765{
766 NS_LOG_FUNCTION(this);
767
768 Ptr<NrGnbPhy> phy = m_gnbPhyFactory.Create<NrGnbPhy>();
769
770 DoubleValue frequency;
771 phy->InstallCentralFrequency(bwp->m_centralFrequency);
772
773 phy->ScheduleStartEventLoop(n->GetId(), 0, 0, 0);
774
775 // PHY <--> CAM
776 Ptr<NrChAccessManager> cam =
777 DynamicCast<NrChAccessManager>(m_gnbChannelAccessManagerFactory.Create());
778 phy->SetCam(cam);
779 phy->SetDevice(dev);
780
781 Ptr<MobilityModel> mm = n->GetObject<MobilityModel>();
782 NS_ASSERT_MSG(
783 mm,
784 "MobilityModel needs to be set on node before calling NrHelper::InstallEnbDevice ()");
785
786 Ptr<NrSpectrumPhy> channelPhy = m_gnbSpectrumFactory.Create<NrSpectrumPhy>();
787 Ptr<UniformPlanarArray> antenna = m_gnbAntennaFactory.Create<UniformPlanarArray>();
788 channelPhy->SetAntenna(antenna);
789 cam->SetNrSpectrumPhy(channelPhy);
790
791 channelPhy->InstallHarqPhyModule(
792 Create<NrHarqPhy>()); // there should be one HARQ instance per NrSpectrumPhy
793 channelPhy->SetIsEnb(true);
794 channelPhy->SetDevice(dev); // each NrSpectrumPhy should have a pointer to device
795 channelPhy->SetChannel(
796 bwp->m_channel); // each NrSpectrumPhy needs to have a pointer to the SpectrumChannel
797 // object of the corresponding spectrum part
798 channelPhy->InstallPhy(phy); // each NrSpectrumPhy should have a pointer to its NrPhy
799
800 Ptr<LteChunkProcessor> pData =
801 Create<LteChunkProcessor>(); // create pData chunk processor per NrSpectrumPhy
802 Ptr<LteChunkProcessor> pSrs =
803 Create<LteChunkProcessor>(); // create pSrs per processor per NrSpectrumPhy
804 if (!m_snrTest)
805 {
806 // TODO: rename to GeneratePuschCqiReport, replace when enabling uplink MIMO
807 pData->AddCallback(MakeCallback(&NrGnbPhy::GenerateDataCqiReport,
808 phy)); // connect DATA chunk processor that will
809 // call GenerateDataCqiReport function
810 pData->AddCallback(MakeCallback(&NrSpectrumPhy::UpdateSinrPerceived,
811 channelPhy)); // connect DATA chunk processor that will
812 // call UpdateSinrPerceived function
813 pSrs->AddCallback(MakeCallback(&NrSpectrumPhy::UpdateSrsSinrPerceived,
814 channelPhy)); // connect SRS chunk processor that will
815 // call UpdateSrsSinrPerceived function
816 if (bwp->m_3gppChannel)
817 {
818 auto pDataMimo = Create<NrMimoChunkProcessor>();
819 pDataMimo->AddCallback(
820 MakeCallback(&NrSpectrumPhy::UpdateMimoSinrPerceived, channelPhy));
821 channelPhy->AddDataMimoChunkProcessor(pDataMimo);
822 }
823 }
824 channelPhy->AddDataSinrChunkProcessor(pData); // set DATA chunk processor to NrSpectrumPhy
825 channelPhy->AddSrsSinrChunkProcessor(pSrs); // set SRS chunk processor to NrSpectrumPhy
826 channelPhy->SetMobility(mm); // set mobility model to this NrSpectrumPhy
827 channelPhy->SetPhyRxDataEndOkCallback(
828 MakeCallback(&NrGnbPhy::PhyDataPacketReceived, phy)); // connect PhyRxDataEndOk callback
829 channelPhy->SetPhyRxCtrlEndOkCallback(phyEndCtrlCallback); // connect PhyRxCtrlEndOk
830 // callback
831 channelPhy->SetPhyUlHarqFeedbackCallback(
832 MakeCallback(&NrGnbPhy::ReportUlHarqFeedback, phy)); // PhyUlHarqFeedback callback
833
834 Ptr<BeamManager> beamManager = m_gnbBeamManagerFactory.Create<BeamManager>();
835 beamManager->Configure(antenna);
836 channelPhy->SetBeamManager(beamManager);
837 phy->InstallSpectrumPhy(channelPhy); // finally let know phy that there is this spectrum phy
838
839 return phy;
840}
841
842Ptr<NrGnbMac>
843NrHelper::CreateGnbMac()
844{
845 NS_LOG_FUNCTION(this);
846
847 Ptr<NrGnbMac> mac = m_gnbMacFactory.Create<NrGnbMac>();
848 return mac;
849}
850
851Ptr<NrMacScheduler>
852NrHelper::CreateGnbSched()
853{
854 NS_LOG_FUNCTION(this);
855
856 auto sched = m_schedFactory.Create<NrMacSchedulerNs3>();
857 auto dlAmc = m_gnbDlAmcFactory.Create<NrAmc>();
858 auto ulAmc = m_gnbUlAmcFactory.Create<NrAmc>();
859
860 sched->InstallDlAmc(dlAmc);
861 sched->InstallUlAmc(ulAmc);
862
863 return sched;
864}
865
866Ptr<NetDevice>
867NrHelper::InstallSingleGnbDevice(
868 const Ptr<Node>& n,
869 const std::vector<std::reference_wrapper<BandwidthPartInfoPtr>> allBwps)
870{
871 NS_ABORT_MSG_IF(m_cellIdCounter == 65535, "max num gNBs exceeded");
872
873 Ptr<NrGnbNetDevice> dev = m_gnbNetDeviceFactory.Create<NrGnbNetDevice>();
874
875 NS_LOG_DEBUG("Creating gNB, cellId = " << m_cellIdCounter);
876 uint16_t cellId = m_cellIdCounter++;
877
878 dev->SetCellId(cellId);
879 dev->SetNode(n);
880
881 // create component carrier map for this gNB device
882 std::map<uint8_t, Ptr<BandwidthPartGnb>> ccMap;
883
884 for (uint32_t bwpId = 0; bwpId < allBwps.size(); ++bwpId)
885 {
886 NS_LOG_DEBUG("Creating BandwidthPart, id = " << bwpId);
887 Ptr<BandwidthPartGnb> cc = CreateObject<BandwidthPartGnb>();
888 double bwInKhz = allBwps[bwpId].get()->m_channelBandwidth / 1000.0;
889 NS_ABORT_MSG_IF(bwInKhz / 100.0 > 65535.0,
890 "A bandwidth of " << bwInKhz / 100.0 << " kHz cannot be represented");
891
892 cc->SetUlBandwidth(static_cast<uint16_t>(bwInKhz / 100));
893 cc->SetDlBandwidth(static_cast<uint16_t>(bwInKhz / 100));
894 cc->SetDlEarfcn(0); // Argh... handover not working
895 cc->SetUlEarfcn(0); // Argh... handover not working
896 cc->SetCellId(m_cellIdCounter++);
897
898 auto phy = CreateGnbPhy(
899 n,
900 allBwps[bwpId].get(),
901 dev,
902 std::bind(&NrGnbNetDevice::RouteIngoingCtrlMsgs, dev, std::placeholders::_1, bwpId));
903 phy->SetBwpId(bwpId);
904 cc->SetPhy(phy);
905
906 auto mac = CreateGnbMac();
907 cc->SetMac(mac);
908 phy->GetCam()->SetNrGnbMac(mac);
909
910 auto sched = CreateGnbSched();
911 cc->SetNrMacScheduler(sched);
912
913 if (bwpId == 0)
914 {
915 cc->SetAsPrimary(true);
916 }
917 else
918 {
919 cc->SetAsPrimary(false);
920 }
921
922 ccMap.insert(std::make_pair(bwpId, cc));
923 }
924
925 Ptr<LteEnbRrc> rrc = CreateObject<LteEnbRrc>();
926 Ptr<LteEnbComponentCarrierManager> ccmEnbManager =
927 DynamicCast<LteEnbComponentCarrierManager>(CreateObject<BwpManagerGnb>());
928 DynamicCast<BwpManagerGnb>(ccmEnbManager)
929 ->SetBwpManagerAlgorithm(m_gnbBwpManagerAlgoFactory.Create<BwpManagerAlgorithm>());
930
931 // Convert Enb carrier map to only PhyConf map
932 // we want to make RRC to be generic, to be able to work with any type of carriers, not only
933 // strictly LTE carriers
934 std::map<uint8_t, Ptr<ComponentCarrierBaseStation>> ccPhyConfMap;
935 for (const auto& i : ccMap)
936 {
937 Ptr<ComponentCarrierBaseStation> c = i.second;
938 ccPhyConfMap.insert(std::make_pair(i.first, c));
939 }
940
941 // ComponentCarrierManager SAP
942 rrc->SetLteCcmRrcSapProvider(ccmEnbManager->GetLteCcmRrcSapProvider());
943 ccmEnbManager->SetLteCcmRrcSapUser(rrc->GetLteCcmRrcSapUser());
944 // Set number of component carriers. Note: eNB CCM would also set the
945 // number of component carriers in eNB RRC
946
947 ccmEnbManager->SetNumberOfComponentCarriers(ccMap.size());
948 rrc->ConfigureCarriers(ccPhyConfMap);
949
950 // nr module currently uses only RRC ideal mode
951 bool useIdealRrc = true;
952
953 if (useIdealRrc)
954 {
955 Ptr<NrGnbRrcProtocolIdeal> rrcProtocol = CreateObject<NrGnbRrcProtocolIdeal>();
956 rrcProtocol->SetLteEnbRrcSapProvider(rrc->GetLteEnbRrcSapProvider());
957 rrc->SetLteEnbRrcSapUser(rrcProtocol->GetLteEnbRrcSapUser());
958 rrc->AggregateObject(rrcProtocol);
959 }
960 else
961 {
962 Ptr<LteEnbRrcProtocolReal> rrcProtocol = CreateObject<LteEnbRrcProtocolReal>();
963 rrcProtocol->SetLteEnbRrcSapProvider(rrc->GetLteEnbRrcSapProvider());
964 rrc->SetLteEnbRrcSapUser(rrcProtocol->GetLteEnbRrcSapUser());
965 rrc->AggregateObject(rrcProtocol);
966 }
967
968 if (m_epcHelper != nullptr)
969 {
970 EnumValue<LteEnbRrc::LteEpsBearerToRlcMapping_t> epsBearerToRlcMapping;
971 rrc->GetAttribute("EpsBearerToRlcMapping", epsBearerToRlcMapping);
972 // it does not make sense to use RLC/SM when also using the EPC
973 if (epsBearerToRlcMapping.Get() == LteEnbRrc::RLC_SM_ALWAYS)
974 {
975 rrc->SetAttribute("EpsBearerToRlcMapping", EnumValue(LteEnbRrc::RLC_UM_ALWAYS));
976 }
977 }
978
979 // This RRC attribute is used to connect each new RLC instance with the MAC layer
980 // (for function such as TransmitPdu, ReportBufferStatusReport).
981 // Since in this new architecture, the component carrier manager acts a proxy, it
982 // will have its own LteMacSapProvider interface, RLC will see it as through original MAC
983 // interface LteMacSapProvider, but the function call will go now through
984 // LteEnbComponentCarrierManager instance that needs to implement functions of this interface,
985 // and its task will be to forward these calls to the specific MAC of some of the instances of
986 // component carriers. This decision will depend on the specific implementation of the component
987 // carrier manager.
988 rrc->SetLteMacSapProvider(ccmEnbManager->GetLteMacSapProvider());
989 rrc->SetForwardUpCallback(MakeCallback(&NrGnbNetDevice::Receive, dev));
990
991 for (auto& it : ccMap)
992 {
993 it.second->GetPhy()->SetEnbCphySapUser(rrc->GetLteEnbCphySapUser(it.first));
994 rrc->SetLteEnbCphySapProvider(it.second->GetPhy()->GetEnbCphySapProvider(), it.first);
995
996 rrc->SetLteEnbCmacSapProvider(it.second->GetMac()->GetEnbCmacSapProvider(), it.first);
997 it.second->GetMac()->SetEnbCmacSapUser(rrc->GetLteEnbCmacSapUser(it.first));
998
999 // PHY <--> MAC SAP
1000 it.second->GetPhy()->SetPhySapUser(it.second->GetMac()->GetPhySapUser());
1001 it.second->GetMac()->SetPhySapProvider(it.second->GetPhy()->GetPhySapProvider());
1002 // PHY <--> MAC SAP END
1003
1004 // Scheduler SAP
1005 it.second->GetMac()->SetNrMacSchedSapProvider(
1006 it.second->GetScheduler()->GetMacSchedSapProvider());
1007 it.second->GetMac()->SetNrMacCschedSapProvider(
1008 it.second->GetScheduler()->GetMacCschedSapProvider());
1009
1010 it.second->GetScheduler()->SetMacSchedSapUser(it.second->GetMac()->GetNrMacSchedSapUser());
1011 it.second->GetScheduler()->SetMacCschedSapUser(
1012 it.second->GetMac()->GetNrMacCschedSapUser());
1013 // Scheduler SAP END
1014
1015 it.second->GetMac()->SetLteCcmMacSapUser(ccmEnbManager->GetLteCcmMacSapUser());
1016 ccmEnbManager->SetCcmMacSapProviders(it.first,
1017 it.second->GetMac()->GetLteCcmMacSapProvider());
1018
1019 // insert the pointer to the LteMacSapProvider interface of the MAC layer of the specific
1020 // component carrier
1021 ccmEnbManager->SetMacSapProvider(it.first, it.second->GetMac()->GetMacSapProvider());
1022 }
1023
1024 dev->SetAttribute("LteEnbComponentCarrierManager", PointerValue(ccmEnbManager));
1025 dev->SetCcMap(ccMap);
1026 dev->SetAttribute("LteEnbRrc", PointerValue(rrc));
1027 dev->Initialize();
1028
1029 n->AddDevice(dev);
1030
1031 if (m_epcHelper != nullptr)
1032 {
1033 NS_LOG_INFO("adding this eNB to the EPC");
1034 m_epcHelper->AddEnb(n, dev, dev->GetCellIds());
1035 Ptr<EpcEnbApplication> enbApp = n->GetApplication(0)->GetObject<EpcEnbApplication>();
1036 NS_ASSERT_MSG(enbApp != nullptr, "cannot retrieve EpcEnbApplication");
1037
1038 // S1 SAPs
1039 rrc->SetS1SapProvider(enbApp->GetS1SapProvider());
1040 enbApp->SetS1SapUser(rrc->GetS1SapUser());
1041
1042 // X2 SAPs
1043 Ptr<EpcX2> x2 = n->GetObject<EpcX2>();
1044 x2->SetEpcX2SapUser(rrc->GetEpcX2SapUser());
1045 rrc->SetEpcX2SapProvider(x2->GetEpcX2SapProvider());
1046 }
1047
1048 return dev;
1049}
1050
1051void
1052NrHelper::AttachToClosestEnb(NetDeviceContainer ueDevices, NetDeviceContainer enbDevices)
1053{
1054 NS_LOG_FUNCTION(this);
1055
1056 for (NetDeviceContainer::Iterator i = ueDevices.Begin(); i != ueDevices.End(); i++)
1057 {
1058 AttachToClosestEnb(*i, enbDevices);
1059 }
1060}
1061
1062void
1063NrHelper::AttachToClosestEnb(Ptr<NetDevice> ueDevice, NetDeviceContainer enbDevices)
1064{
1065 NS_LOG_FUNCTION(this);
1066 NS_ASSERT_MSG(enbDevices.GetN() > 0, "empty enb device container");
1067 Vector uepos = ueDevice->GetNode()->GetObject<MobilityModel>()->GetPosition();
1068 double minDistance = std::numeric_limits<double>::infinity();
1069 Ptr<NetDevice> closestEnbDevice;
1070 for (NetDeviceContainer::Iterator i = enbDevices.Begin(); i != enbDevices.End(); ++i)
1071 {
1072 Vector enbpos = (*i)->GetNode()->GetObject<MobilityModel>()->GetPosition();
1073 double distance = CalculateDistance(uepos, enbpos);
1074 if (distance < minDistance)
1075 {
1076 minDistance = distance;
1077 closestEnbDevice = *i;
1078 }
1079 }
1080 NS_ASSERT(closestEnbDevice);
1081
1082 AttachToEnb(ueDevice, closestEnbDevice);
1083}
1084
1085void
1086NrHelper::AttachToEnb(const Ptr<NetDevice>& ueDevice, const Ptr<NetDevice>& gnbDevice)
1087{
1088 Ptr<NrGnbNetDevice> enbNetDev = gnbDevice->GetObject<NrGnbNetDevice>();
1089 Ptr<NrUeNetDevice> ueNetDev = ueDevice->GetObject<NrUeNetDevice>();
1090
1091 NS_ABORT_IF(enbNetDev == nullptr || ueNetDev == nullptr);
1092
1093 for (uint32_t i = 0; i < enbNetDev->GetCcMapSize(); ++i)
1094 {
1095 enbNetDev->GetPhy(i)->RegisterUe(ueNetDev->GetImsi(), ueNetDev);
1096 ueNetDev->GetPhy(i)->RegisterToEnb(enbNetDev->GetBwpId(i));
1097 ueNetDev->GetPhy(i)->SetDlAmc(
1098 DynamicCast<NrMacSchedulerNs3>(enbNetDev->GetScheduler(i))->GetDlAmc());
1099 ueNetDev->GetPhy(i)->SetDlCtrlSyms(enbNetDev->GetMac(i)->GetDlCtrlSyms());
1100 ueNetDev->GetPhy(i)->SetUlCtrlSyms(enbNetDev->GetMac(i)->GetUlCtrlSyms());
1101 ueNetDev->GetPhy(i)->SetNumRbPerRbg(enbNetDev->GetMac(i)->GetNumRbPerRbg());
1102 ueNetDev->GetPhy(i)->SetRbOverhead(enbNetDev->GetPhy(i)->GetRbOverhead());
1103 ueNetDev->GetPhy(i)->SetSymbolsPerSlot(enbNetDev->GetPhy(i)->GetSymbolsPerSlot());
1104 ueNetDev->GetPhy(i)->SetNumerology(enbNetDev->GetPhy(i)->GetNumerology());
1105 ueNetDev->GetPhy(i)->SetPattern(enbNetDev->GetPhy(i)->GetPattern());
1106 Ptr<EpcUeNas> ueNas = ueNetDev->GetNas();
1107 ueNas->Connect(enbNetDev->GetBwpId(i), enbNetDev->GetEarfcn(i));
1108
1109 if (m_enableMimoFeedback)
1110 {
1111 // Initialize parameters for MIMO precoding matrix search (PMI feedback)
1112 auto pmSearch = m_pmSearchFactory.Create<NrPmSearch>();
1113 ueNetDev->GetPhy(i)->SetPmSearch(pmSearch);
1114 auto gnbAnt =
1115 enbNetDev->GetPhy(i)->GetSpectrumPhy()->GetAntenna()->GetObject<PhasedArrayModel>();
1116 auto ueAnt =
1117 ueNetDev->GetPhy(i)->GetSpectrumPhy()->GetAntenna()->GetObject<PhasedArrayModel>();
1118 pmSearch->SetGnbParams(gnbAnt->IsDualPol(),
1119 gnbAnt->GetNumHorizontalPorts(),
1120 gnbAnt->GetNumVerticalPorts());
1121 pmSearch->SetUeParams(ueAnt->GetNumPorts());
1122 pmSearch->InitCodebooks();
1123 }
1124 }
1125
1126 if (m_epcHelper)
1127 {
1128 // activate default EPS bearer
1129 m_epcHelper->ActivateEpsBearer(ueDevice,
1130 ueNetDev->GetImsi(),
1131 EpcTft::Default(),
1132 EpsBearer(EpsBearer::NGBR_VIDEO_TCP_DEFAULT));
1133 }
1134
1135 // tricks needed for the simplified LTE-only simulations
1136 // if (m_epcHelper == 0)
1137 //{
1138 ueNetDev->SetTargetEnb(enbNetDev);
1139 //}
1140
1141 if (m_beamformingHelper)
1142 {
1143 m_beamformingHelper->AddBeamformingTask(enbNetDev, ueNetDev);
1144 }
1145}
1146
1147uint8_t
1148NrHelper::ActivateDedicatedEpsBearer(NetDeviceContainer ueDevices,
1149 EpsBearer bearer,
1150 Ptr<EpcTft> tft)
1151{
1152 NS_LOG_FUNCTION(this);
1153 for (NetDeviceContainer::Iterator i = ueDevices.Begin(); i != ueDevices.End(); ++i)
1154 {
1155 uint8_t bearerId = ActivateDedicatedEpsBearer(*i, bearer, tft);
1156 return bearerId;
1157 }
1158 return 0;
1159}
1160
1161uint8_t
1162NrHelper::ActivateDedicatedEpsBearer(Ptr<NetDevice> ueDevice, EpsBearer bearer, Ptr<EpcTft> tft)
1163{
1164 NS_LOG_FUNCTION(this);
1165
1166 NS_ASSERT_MSG(m_epcHelper, "dedicated EPS bearers cannot be set up when the EPC is not used");
1167
1168 uint64_t imsi = ueDevice->GetObject<NrUeNetDevice>()->GetImsi();
1169 uint8_t bearerId = m_epcHelper->ActivateEpsBearer(ueDevice, imsi, tft, bearer);
1170 return bearerId;
1171}
1172
1173void
1175 Ptr<NetDevice> enbDevice,
1176 uint8_t bearerId)
1177{
1178 NS_LOG_FUNCTION(this << ueDevice << bearerId);
1179 NS_ASSERT_MSG(m_epcHelper != nullptr,
1180 "Dedicated EPS bearers cannot be de-activated when the EPC is not used");
1181 NS_ASSERT_MSG(bearerId != 1,
1182 "Default bearer cannot be de-activated until and unless and UE is released");
1183
1184 DoDeActivateDedicatedEpsBearer(ueDevice, enbDevice, bearerId);
1185}
1186
1187void
1188NrHelper::SetUeMacAttribute(const std::string& n, const AttributeValue& v)
1189{
1190 NS_LOG_FUNCTION(this);
1191 m_ueMacFactory.Set(n, v);
1192}
1193
1194void
1195NrHelper::SetGnbMacAttribute(const std::string& n, const AttributeValue& v)
1196{
1197 NS_LOG_FUNCTION(this);
1198 m_gnbMacFactory.Set(n, v);
1199}
1200
1201void
1202NrHelper::SetGnbSpectrumAttribute(const std::string& n, const AttributeValue& v)
1203{
1204 NS_LOG_FUNCTION(this);
1205 m_gnbSpectrumFactory.Set(n, v);
1206}
1207
1208void
1209NrHelper::SetUeSpectrumAttribute(const std::string& n, const AttributeValue& v)
1210{
1211 NS_LOG_FUNCTION(this);
1212 m_ueSpectrumFactory.Set(n, v);
1213}
1214
1215void
1216NrHelper::SetUeChannelAccessManagerAttribute(const std::string& n, const AttributeValue& v)
1217{
1218 NS_LOG_FUNCTION(this);
1219 m_ueChannelAccessManagerFactory.Set(n, v);
1220}
1221
1222void
1223NrHelper::SetGnbChannelAccessManagerAttribute(const std::string& n, const AttributeValue& v)
1224{
1225 NS_LOG_FUNCTION(this);
1226 m_gnbChannelAccessManagerFactory.Set(n, v);
1227}
1228
1229void
1230NrHelper::SetSchedulerAttribute(const std::string& n, const AttributeValue& v)
1231{
1232 NS_LOG_FUNCTION(this);
1233 m_schedFactory.Set(n, v);
1234}
1235
1236void
1237NrHelper::SetUePhyAttribute(const std::string& n, const AttributeValue& v)
1238{
1239 NS_LOG_FUNCTION(this);
1240 m_uePhyFactory.Set(n, v);
1241}
1242
1243void
1244NrHelper::SetGnbPhyAttribute(const std::string& n, const AttributeValue& v)
1245{
1246 NS_LOG_FUNCTION(this);
1247 m_gnbPhyFactory.Set(n, v);
1248}
1249
1250void
1251NrHelper::SetUeAntennaAttribute(const std::string& n, const AttributeValue& v)
1252{
1253 NS_LOG_FUNCTION(this);
1254 m_ueAntennaFactory.Set(n, v);
1255}
1256
1257void
1258NrHelper::SetGnbAntennaAttribute(const std::string& n, const AttributeValue& v)
1259{
1260 NS_LOG_FUNCTION(this);
1261 m_gnbAntennaFactory.Set(n, v);
1262}
1263
1264void
1266{
1267 NS_LOG_FUNCTION(this);
1268 m_ueChannelAccessManagerFactory.SetTypeId(typeId);
1269}
1270
1271void
1273{
1274 NS_LOG_FUNCTION(this);
1275 m_gnbChannelAccessManagerFactory.SetTypeId(typeId);
1276}
1277
1278void
1279NrHelper::SetSchedulerTypeId(const TypeId& typeId)
1280{
1281 NS_LOG_FUNCTION(this);
1282 m_schedFactory.SetTypeId(typeId);
1283}
1284
1285void
1287{
1288 NS_LOG_FUNCTION(this);
1289 m_ueBwpManagerAlgoFactory.SetTypeId(typeId);
1290}
1291
1292void
1293NrHelper::SetPhasedArraySpectrumPropagationLossModelTypeId(const TypeId& typeId)
1294{
1295 NS_LOG_FUNCTION(this);
1296 m_spectrumPropagationFactory.SetTypeId(typeId);
1297}
1298
1299void
1300NrHelper::SetUeBwpManagerAlgorithmAttribute(const std::string& n, const AttributeValue& v)
1301{
1302 NS_LOG_FUNCTION(this);
1303 m_ueBwpManagerAlgoFactory.Set(n, v);
1304}
1305
1306void
1308 const AttributeValue& v)
1309{
1310 NS_LOG_FUNCTION(this);
1311 m_spectrumPropagationFactory.Set(n, v);
1312}
1313
1314void
1315NrHelper::SetChannelConditionModelAttribute(const std::string& n, const AttributeValue& v)
1316{
1317 NS_LOG_FUNCTION(this);
1318 m_channelConditionModelFactory.Set(n, v);
1319}
1320
1321void
1322NrHelper::SetPathlossAttribute(const std::string& n, const AttributeValue& v)
1323{
1324 NS_LOG_FUNCTION(this);
1325 m_pathlossModelFactory.Set(n, v);
1326}
1327
1328void
1329NrHelper::SetGnbDlAmcAttribute(const std::string& n, const AttributeValue& v)
1330{
1331 NS_LOG_FUNCTION(this);
1332 m_gnbDlAmcFactory.Set(n, v);
1333}
1334
1335void
1336NrHelper::SetGnbUlAmcAttribute(const std::string& n, const AttributeValue& v)
1337{
1338 NS_LOG_FUNCTION(this);
1339 m_gnbUlAmcFactory.Set(n, v);
1340}
1341
1342void
1343NrHelper::SetGnbBeamManagerAttribute(const std::string& n, const AttributeValue& v)
1344{
1345 NS_LOG_FUNCTION(this);
1346 m_gnbBeamManagerFactory.Set(n, v);
1347}
1348
1349void
1351{
1352 NS_LOG_FUNCTION(this);
1353 m_gnbBeamManagerFactory.SetTypeId(typeId);
1354}
1355
1356void
1357NrHelper::SetUlErrorModel(const std::string& errorModelTypeId)
1358{
1359 NS_LOG_FUNCTION(this);
1360
1361 SetGnbUlAmcAttribute("ErrorModelType", TypeIdValue(TypeId::LookupByName(errorModelTypeId)));
1362 SetGnbSpectrumAttribute("ErrorModelType", TypeIdValue(TypeId::LookupByName(errorModelTypeId)));
1363}
1364
1365void
1366NrHelper::SetDlErrorModel(const std::string& errorModelTypeId)
1367{
1368 NS_LOG_FUNCTION(this);
1369
1370 SetGnbDlAmcAttribute("ErrorModelType", TypeIdValue(TypeId::LookupByName(errorModelTypeId)));
1371 SetUeSpectrumAttribute("ErrorModelType", TypeIdValue(TypeId::LookupByName(errorModelTypeId)));
1372}
1373
1374int64_t
1375NrHelper::AssignStreams(NetDeviceContainer c, int64_t stream)
1376{
1377 int64_t currentStream = stream;
1378 Ptr<NetDevice> netDevice;
1379 for (NetDeviceContainer::Iterator i = c.Begin(); i != c.End(); ++i)
1380 {
1381 netDevice = (*i);
1382 Ptr<NrGnbNetDevice> nrGnb = DynamicCast<NrGnbNetDevice>(netDevice);
1383 if (nrGnb)
1384 {
1385 for (uint32_t bwp = 0; bwp < nrGnb->GetCcMapSize(); bwp++)
1386 {
1387 currentStream += nrGnb->GetPhy(bwp)->GetSpectrumPhy()->AssignStreams(currentStream);
1388 currentStream += nrGnb->GetScheduler(bwp)->AssignStreams(currentStream);
1389 currentStream +=
1390 DoAssignStreamsToChannelObjects(nrGnb->GetPhy(bwp)->GetSpectrumPhy(),
1391 currentStream);
1392 }
1393 }
1394
1395 Ptr<NrUeNetDevice> nrUe = DynamicCast<NrUeNetDevice>(netDevice);
1396 if (nrUe)
1397 {
1398 for (uint32_t bwp = 0; bwp < nrUe->GetCcMapSize(); bwp++)
1399 {
1400 currentStream += nrUe->GetPhy(bwp)->GetSpectrumPhy()->AssignStreams(currentStream);
1401 currentStream += nrUe->GetMac(bwp)->AssignStreams(currentStream);
1402 currentStream +=
1403 DoAssignStreamsToChannelObjects(nrUe->GetPhy(bwp)->GetSpectrumPhy(),
1404 currentStream);
1405 }
1406 }
1407 }
1408
1409 return (currentStream - stream);
1410}
1411
1412int64_t
1413NrHelper::DoAssignStreamsToChannelObjects(Ptr<NrSpectrumPhy> phy, int64_t currentStream)
1414{
1415 int64_t initialStream = currentStream;
1416
1417 Ptr<ThreeGppPropagationLossModel> propagationLossModel =
1418 DynamicCast<ThreeGppPropagationLossModel>(
1419 phy->GetSpectrumChannel()->GetPropagationLossModel());
1420 if (!propagationLossModel)
1421 {
1422 currentStream +=
1423 phy->GetSpectrumChannel()->GetPropagationLossModel()->AssignStreams(currentStream);
1424 return currentStream - initialStream;
1425 }
1426
1427 if (std::find(m_channelObjectsWithAssignedStreams.begin(),
1428 m_channelObjectsWithAssignedStreams.end(),
1429 propagationLossModel) == m_channelObjectsWithAssignedStreams.end())
1430 {
1431 currentStream += propagationLossModel->AssignStreams(currentStream);
1432 m_channelObjectsWithAssignedStreams.emplace_back(propagationLossModel);
1433 }
1434
1435 Ptr<ChannelConditionModel> channelConditionModel =
1436 propagationLossModel->GetChannelConditionModel();
1437
1438 if (std::find(m_channelObjectsWithAssignedStreams.begin(),
1439 m_channelObjectsWithAssignedStreams.end(),
1440 channelConditionModel) == m_channelObjectsWithAssignedStreams.end())
1441 {
1442 currentStream += channelConditionModel->AssignStreams(currentStream);
1443 m_channelObjectsWithAssignedStreams.emplace_back(channelConditionModel);
1444 }
1445
1446 Ptr<ThreeGppSpectrumPropagationLossModel> spectrumLossModel =
1447 DynamicCast<ThreeGppSpectrumPropagationLossModel>(
1448 phy->GetSpectrumChannel()->GetPhasedArraySpectrumPropagationLossModel());
1449
1450 if (spectrumLossModel)
1451 {
1452 if (std::find(m_channelObjectsWithAssignedStreams.begin(),
1453 m_channelObjectsWithAssignedStreams.end(),
1454 spectrumLossModel) == m_channelObjectsWithAssignedStreams.end())
1455 {
1456 Ptr<ThreeGppChannelModel> channel =
1457 DynamicCast<ThreeGppChannelModel>(spectrumLossModel->GetChannelModel());
1458 currentStream += channel->AssignStreams(currentStream);
1459 m_channelObjectsWithAssignedStreams.emplace_back(spectrumLossModel);
1460 }
1461 }
1462
1463 return currentStream - initialStream;
1464}
1465
1466void
1468{
1469 NS_LOG_FUNCTION(this);
1470 m_gnbBwpManagerAlgoFactory.SetTypeId(typeId);
1471}
1472
1473void
1474NrHelper::SetGnbBwpManagerAlgorithmAttribute(const std::string& n, const AttributeValue& v)
1475{
1476 NS_LOG_FUNCTION(this);
1477 m_gnbBwpManagerAlgoFactory.Set(n, v);
1478}
1479
1480void
1481NrHelper::DoDeActivateDedicatedEpsBearer(Ptr<NetDevice> ueDevice,
1482 Ptr<NetDevice> enbDevice,
1483 uint8_t bearerId)
1484{
1485 NS_LOG_FUNCTION(this << ueDevice << bearerId);
1486
1487 // Extract IMSI and rnti
1488 uint64_t imsi = ueDevice->GetObject<NrUeNetDevice>()->GetImsi();
1489 uint16_t rnti = ueDevice->GetObject<NrUeNetDevice>()->GetRrc()->GetRnti();
1490
1491 Ptr<LteEnbRrc> enbRrc = enbDevice->GetObject<NrGnbNetDevice>()->GetRrc();
1492
1493 enbRrc->DoSendReleaseDataRadioBearer(imsi, rnti, bearerId);
1494}
1495
1496void
1497NrHelper::SetEpcHelper(Ptr<EpcHelper> epcHelper)
1498{
1499 m_epcHelper = epcHelper;
1500}
1501
1502void
1503NrHelper::SetBeamformingHelper(Ptr<BeamformingHelperBase> beamformingHelper)
1504{
1505 m_beamformingHelper = beamformingHelper;
1506 m_beamformingHelper->Initialize();
1507}
1508
1509class NrDrbActivator : public SimpleRefCount<NrDrbActivator>
1510{
1511 public:
1512 NrDrbActivator(Ptr<NetDevice> ueDevice, EpsBearer bearer);
1513 static void ActivateCallback(Ptr<NrDrbActivator> a,
1514 std::string context,
1515 uint64_t imsi,
1516 uint16_t cellId,
1517 uint16_t rnti);
1518 void ActivateDrb(uint64_t imsi, uint16_t cellId, uint16_t rnti);
1519
1520 private:
1521 bool m_active;
1522 Ptr<NetDevice> m_ueDevice;
1523 EpsBearer m_bearer;
1524 uint64_t m_imsi;
1525};
1526
1527NrDrbActivator::NrDrbActivator(Ptr<NetDevice> ueDevice, EpsBearer bearer)
1528 : m_active(false),
1529 m_ueDevice(ueDevice),
1530 m_bearer(bearer),
1531 m_imsi(m_ueDevice->GetObject<NrUeNetDevice>()->GetImsi())
1532{
1533}
1534
1535void
1536NrDrbActivator::ActivateCallback(Ptr<NrDrbActivator> a,
1537 std::string context,
1538 uint64_t imsi,
1539 uint16_t cellId,
1540 uint16_t rnti)
1541{
1542 NS_LOG_FUNCTION(a << context << imsi << cellId << rnti);
1543 a->ActivateDrb(imsi, cellId, rnti);
1544}
1545
1546void
1547NrDrbActivator::ActivateDrb(uint64_t imsi, uint16_t cellId, uint16_t rnti)
1548{
1549 NS_LOG_FUNCTION(this << imsi << cellId << rnti << m_active);
1550 if ((!m_active) && (imsi == m_imsi))
1551 {
1552 Ptr<LteUeRrc> ueRrc = m_ueDevice->GetObject<NrUeNetDevice>()->GetRrc();
1553 NS_ASSERT(ueRrc->GetState() == LteUeRrc::CONNECTED_NORMALLY);
1554 uint16_t rnti = ueRrc->GetRnti();
1555 Ptr<const NrGnbNetDevice> enbLteDevice =
1556 m_ueDevice->GetObject<NrUeNetDevice>()->GetTargetEnb();
1557 Ptr<LteEnbRrc> enbRrc = enbLteDevice->GetObject<NrGnbNetDevice>()->GetRrc();
1558 NS_ASSERT(ueRrc->GetCellId() == enbLteDevice->GetCellId());
1559 Ptr<UeManager> ueManager = enbRrc->GetUeManager(rnti);
1560 NS_ASSERT(ueManager->GetState() == UeManager::CONNECTED_NORMALLY ||
1561 ueManager->GetState() == UeManager::CONNECTION_RECONFIGURATION);
1562 EpcEnbS1SapUser::DataRadioBearerSetupRequestParameters params;
1563 params.rnti = rnti;
1564 params.bearer = m_bearer;
1565 params.bearerId = 0;
1566 params.gtpTeid = 0; // don't care
1567 enbRrc->GetS1SapUser()->DataRadioBearerSetupRequest(params);
1568 m_active = true;
1569 }
1570}
1571
1572void
1573NrHelper::ActivateDataRadioBearer(NetDeviceContainer ueDevices, EpsBearer bearer)
1574{
1575 NS_LOG_FUNCTION(this);
1576 for (NetDeviceContainer::Iterator i = ueDevices.Begin(); i != ueDevices.End(); ++i)
1577 {
1578 ActivateDataRadioBearer(*i, bearer);
1579 }
1580}
1581
1582void
1583NrHelper::ActivateDataRadioBearer(Ptr<NetDevice> ueDevice, EpsBearer bearer)
1584{
1585 NS_LOG_FUNCTION(this << ueDevice);
1586 NS_ASSERT_MSG(!m_epcHelper, "this method must not be used when the EPC is being used");
1587
1588 // Normally it is the EPC that takes care of activating DRBs
1589 // when the UE gets connected. When the EPC is not used, we achieve
1590 // the same behavior by hooking a dedicated DRB activation function
1591 // to the Enb RRC Connection Established trace source
1592
1593 Ptr<const NrGnbNetDevice> enbnrDevice = ueDevice->GetObject<NrUeNetDevice>()->GetTargetEnb();
1594
1595 std::ostringstream path;
1596 path << "/NodeList/" << enbnrDevice->GetNode()->GetId() << "/DeviceList/"
1597 << enbnrDevice->GetIfIndex() << "/LteEnbRrc/ConnectionEstablished";
1598 Ptr<NrDrbActivator> arg = Create<NrDrbActivator>(ueDevice, bearer);
1599 Config::Connect(path.str(), MakeBoundCallback(&NrDrbActivator::ActivateCallback, arg));
1600}
1601
1602void
1604{
1608 // EnableEnbPacketCountTrace ();
1609 // EnableUePacketCountTrace ();
1610 // EnableTransportBlockTrace ();
1622}
1623
1624Ptr<NrPhyRxTrace>
1626{
1627 return m_phyStats;
1628}
1629
1630void
1632{
1633 // NS_LOG_FUNCTION_NOARGS ();
1634 Config::Connect("/NodeList/*/DeviceList/*/ComponentCarrierMapUe/*/NrUePhy/DlDataSinr",
1635 MakeBoundCallback(&NrPhyRxTrace::DlDataSinrCallback, m_phyStats));
1636
1637 Config::Connect(
1638 "/NodeList/*/DeviceList/*/ComponentCarrierMapUe/*/NrUePhy/SpectrumPhy/RxPacketTraceUe",
1639 MakeBoundCallback(&NrPhyRxTrace::RxPacketTraceUeCallback, m_phyStats));
1640}
1641
1642void
1644{
1645 // NS_LOG_FUNCTION_NOARGS ();
1646 Config::Connect("/NodeList/*/DeviceList/*/ComponentCarrierMapUe/*/NrUePhy/DlCtrlSinr",
1647 MakeBoundCallback(&NrPhyRxTrace::DlCtrlSinrCallback, m_phyStats));
1648}
1649
1650void
1652{
1653 Config::Connect("/NodeList/*/DeviceList/*/BandwidthPartMap/*/NrGnbPhy/GnbPhyRxedCtrlMsgsTrace",
1654 MakeBoundCallback(&NrPhyRxTrace::RxedGnbPhyCtrlMsgsCallback, m_phyStats));
1655 Config::Connect("/NodeList/*/DeviceList/*/BandwidthPartMap/*/NrGnbPhy/GnbPhyTxedCtrlMsgsTrace",
1656 MakeBoundCallback(&NrPhyRxTrace::TxedGnbPhyCtrlMsgsCallback, m_phyStats));
1657}
1658
1659void
1661{
1662 Config::Connect("/NodeList/*/DeviceList/*/BandwidthPartMap/*/NrGnbMac/GnbMacRxedCtrlMsgsTrace",
1663 MakeBoundCallback(&NrMacRxTrace::RxedGnbMacCtrlMsgsCallback, m_macStats));
1664
1665 Config::Connect("/NodeList/*/DeviceList/*/BandwidthPartMap/*/NrGnbMac/GnbMacTxedCtrlMsgsTrace",
1666 MakeBoundCallback(&NrMacRxTrace::TxedGnbMacCtrlMsgsCallback, m_macStats));
1667}
1668
1669void
1671{
1672 Config::Connect(
1673 "/NodeList/*/DeviceList/*/ComponentCarrierMapUe/*/NrUePhy/UePhyRxedCtrlMsgsTrace",
1674 MakeBoundCallback(&NrPhyRxTrace::RxedUePhyCtrlMsgsCallback, m_phyStats));
1675 Config::Connect(
1676 "/NodeList/*/DeviceList/*/ComponentCarrierMapUe/*/NrUePhy/UePhyTxedCtrlMsgsTrace",
1677 MakeBoundCallback(&NrPhyRxTrace::TxedUePhyCtrlMsgsCallback, m_phyStats));
1678 Config::Connect("/NodeList/*/DeviceList/*/ComponentCarrierMapUe/*/NrUePhy/UePhyRxedDlDciTrace",
1679 MakeBoundCallback(&NrPhyRxTrace::RxedUePhyDlDciCallback, m_phyStats));
1680 Config::Connect(
1681 "/NodeList/*/DeviceList/*/ComponentCarrierMapUe/*/NrUePhy/UePhyTxedHarqFeedbackTrace",
1682 MakeBoundCallback(&NrPhyRxTrace::TxedUePhyHarqFeedbackCallback, m_phyStats));
1683}
1684
1685void
1687{
1688 Config::Connect(
1689 "/NodeList/*/DeviceList/*/ComponentCarrierMapUe/*/NrUeMac/UeMacRxedCtrlMsgsTrace",
1690 MakeBoundCallback(&NrMacRxTrace::RxedUeMacCtrlMsgsCallback, m_macStats));
1691 Config::Connect(
1692 "/NodeList/*/DeviceList/*/ComponentCarrierMapUe/*/NrUeMac/UeMacTxedCtrlMsgsTrace",
1693 MakeBoundCallback(&NrMacRxTrace::TxedUeMacCtrlMsgsCallback, m_macStats));
1694}
1695
1696void
1698{
1699 NS_LOG_FUNCTION_NOARGS();
1700 Config::Connect(
1701 "/NodeList/*/DeviceList/*/BandwidthPartMap/*/NrGnbPhy/SpectrumPhy/RxPacketTraceEnb",
1702 MakeBoundCallback(&NrPhyRxTrace::RxPacketTraceEnbCallback, m_phyStats));
1703}
1704
1705void
1707{
1708 NS_LOG_FUNCTION_NOARGS();
1709 Config::Connect(
1710 "/NodeList/*/DeviceList/*/BandwidthPartMap/*/NrGnbPhy/SpectrumPhy/ReportEnbTxRxPacketCount",
1711 MakeBoundCallback(&NrPhyRxTrace::ReportPacketCountEnbCallback, m_phyStats));
1712}
1713
1714void
1716{
1717 NS_LOG_FUNCTION_NOARGS();
1718 Config::Connect("/NodeList/*/DeviceList/*/ComponentCarrierMapUe/*/NrUePhy/SpectrumPhy/"
1719 "ReportUeTxRxPacketCount",
1720 MakeBoundCallback(&NrPhyRxTrace::ReportPacketCountUeCallback, m_phyStats));
1721}
1722
1723void
1725{
1726 NS_LOG_FUNCTION_NOARGS();
1727 Config::Connect("/NodeList/*/DeviceList/*/ComponentCarrierMapUe/*/NrUePhy/ReportDownlinkTbSize",
1728 MakeBoundCallback(&NrPhyRxTrace::ReportDownLinkTBSize, m_phyStats));
1729}
1730
1731void
1733{
1734 Ptr<NrBearerStatsSimple> rlcStats = CreateObject<NrBearerStatsSimple>("RLC");
1735 m_radioBearerStatsConnectorSimpleTraces.EnableRlcStats(rlcStats);
1736}
1737
1738void
1740{
1741 Ptr<NrBearerStatsSimple> pdcpStats = CreateObject<NrBearerStatsSimple>("PDCP");
1742 m_radioBearerStatsConnectorSimpleTraces.EnablePdcpStats(pdcpStats);
1743}
1744
1745void
1747{
1748 Ptr<NrBearerStatsCalculator> rlcStats = CreateObject<NrBearerStatsCalculator>("RLC");
1749 m_radioBearerStatsConnectorCalculator.EnableRlcStats(rlcStats);
1750}
1751
1752void
1754{
1755 Ptr<NrBearerStatsCalculator> pdcpStats = CreateObject<NrBearerStatsCalculator>("PDCP");
1756 m_radioBearerStatsConnectorCalculator.EnablePdcpStats(pdcpStats);
1757}
1758
1759Ptr<NrBearerStatsCalculator>
1761{
1762 return DynamicCast<NrBearerStatsCalculator>(
1763 m_radioBearerStatsConnectorCalculator.GetRlcStats());
1764}
1765
1766Ptr<NrBearerStatsCalculator>
1768{
1769 return DynamicCast<NrBearerStatsCalculator>(
1770 m_radioBearerStatsConnectorCalculator.GetPdcpStats());
1771}
1772
1773void
1775{
1776 NS_LOG_FUNCTION_NOARGS();
1777 Config::Connect(
1778 "/NodeList/*/DeviceList/*/BandwidthPartMap/*/NrGnbMac/DlScheduling",
1779 MakeBoundCallback(&NrMacSchedulingStats::DlSchedulingCallback, m_macSchedStats));
1780}
1781
1782void
1784{
1785 NS_LOG_FUNCTION_NOARGS();
1786 Config::Connect(
1787 "/NodeList/*/DeviceList/*/BandwidthPartMap/*/NrGnbMac/UlScheduling",
1788 MakeBoundCallback(&NrMacSchedulingStats::UlSchedulingCallback, m_macSchedStats));
1789}
1790
1791void
1793{
1794 NS_LOG_FUNCTION_NOARGS();
1795 Config::Connect("/ChannelList/*/$ns3::SpectrumChannel/PathLoss",
1796 MakeBoundCallback(&NrPhyRxTrace::PathlossTraceCallback, m_phyStats));
1797}
1798
1799void
1800NrHelper::EnableDlCtrlPathlossTraces(NetDeviceContainer& ueDevs)
1801{
1802 NS_LOG_FUNCTION_NOARGS();
1803
1804 for (uint32_t i = 0; i < ueDevs.GetN(); i++)
1805 {
1806 Ptr<NrUeNetDevice> ueDev = DynamicCast<NrUeNetDevice>(ueDevs.Get(i));
1807 NS_ASSERT_MSG(ueDev,
1808 "To EnableDlCtrlPathlossTracesfunction is passed device "
1809 "container that contains non UE devices.");
1810 for (uint32_t j = 0; j < ueDev->GetCcMapSize(); j++)
1811 {
1812 Ptr<NrUePhy> nrUePhy = ueDev->GetPhy(j);
1813 Ptr<NrSpectrumPhy> nrSpectrumPhy = nrUePhy->GetSpectrumPhy();
1814 nrSpectrumPhy->EnableDlCtrlPathlossTrace();
1815 }
1816 }
1817
1818 Config::Connect("/NodeList/*/DeviceList/*/ComponentCarrierMapUe/*/NrUePhy/NrSpectrumPhyList/*/"
1819 "DlCtrlPathloss",
1820 MakeBoundCallback(&NrPhyRxTrace::ReportDlCtrlPathloss, m_phyStats));
1821}
1822
1823void
1824NrHelper::EnableDlDataPathlossTraces(NetDeviceContainer& ueDevs)
1825{
1826 NS_LOG_FUNCTION_NOARGS();
1827
1828 NS_ASSERT_MSG(ueDevs.GetN(),
1829 "Passed an empty UE net device container EnableDlDataPathlossTraces function");
1830
1831 for (uint32_t i = 0; i < ueDevs.GetN(); i++)
1832 {
1833 Ptr<NrUeNetDevice> ueDev = DynamicCast<NrUeNetDevice>(ueDevs.Get(i));
1834 NS_ASSERT_MSG(ueDev,
1835 "To EnableDlDataPathlossTracesfunction is passed device "
1836 "container that contains non UE devices.");
1837 for (uint32_t j = 0; j < ueDev->GetCcMapSize(); j++)
1838 {
1839 Ptr<NrUePhy> nrUePhy = ueDev->GetPhy(j);
1840 Ptr<NrSpectrumPhy> nrSpectrumPhy = nrUePhy->GetSpectrumPhy();
1841 nrSpectrumPhy->EnableDlDataPathlossTrace();
1842 }
1843 }
1844
1845 Config::Connect("/NodeList/*/DeviceList/*/ComponentCarrierMapUe/*/NrUePhy/NrSpectrumPhyList/*/"
1846 "DlDataPathloss",
1847 MakeBoundCallback(&NrPhyRxTrace::ReportDlDataPathloss, m_phyStats));
1848}
1849
1850void
1851NrHelper::SetPmSearchTypeId(const TypeId& typeId)
1852{
1853 m_pmSearchFactory.SetTypeId(typeId);
1854}
1855
1856void
1857NrHelper::SetPmSearchAttribute(const std::string& name, const AttributeValue& value)
1858{
1859 NS_LOG_FUNCTION(this);
1860 m_pmSearchFactory.Set(name, value);
1861}
1862
1863void
1865{
1866 auto antFactory = ObjectFactory{};
1867 antFactory.SetTypeId(ap.antennaElem);
1868 SetGnbAntennaAttribute("AntennaElement", PointerValue(antFactory.Create()));
1869 SetGnbAntennaAttribute("NumColumns", UintegerValue(ap.nAntCols));
1870 SetGnbAntennaAttribute("NumRows", UintegerValue(ap.nAntRows));
1871 SetGnbAntennaAttribute("IsDualPolarized", BooleanValue(ap.isDualPolarized));
1872 SetGnbAntennaAttribute("NumHorizontalPorts", UintegerValue(ap.nHorizPorts));
1873 SetGnbAntennaAttribute("NumVerticalPorts", UintegerValue(ap.nVertPorts));
1874 SetGnbAntennaAttribute("BearingAngle", DoubleValue(ap.bearingAngle));
1875 SetGnbAntennaAttribute("PolSlantAngle", DoubleValue(ap.polSlantAngle));
1876}
1877
1878void
1880{
1881 auto antFactory = ObjectFactory{};
1882 antFactory.SetTypeId(ap.antennaElem);
1883 SetUeAntennaAttribute("AntennaElement", PointerValue(antFactory.Create()));
1884 SetUeAntennaAttribute("NumColumns", UintegerValue(ap.nAntCols));
1885 SetUeAntennaAttribute("NumRows", UintegerValue(ap.nAntRows));
1886 SetUeAntennaAttribute("IsDualPolarized", BooleanValue(ap.isDualPolarized));
1887 SetUeAntennaAttribute("NumHorizontalPorts", UintegerValue(ap.nHorizPorts));
1888 SetUeAntennaAttribute("NumVerticalPorts", UintegerValue(ap.nVertPorts));
1889 SetUeAntennaAttribute("BearingAngle", DoubleValue(ap.bearingAngle));
1890 SetUeAntennaAttribute("PolSlantAngle", DoubleValue(ap.polSlantAngle));
1891}
1892
1893void
1895{
1896 // Set parameters for MIMO precoding matrix search
1897 SetAttribute("EnableMimoFeedback", BooleanValue(true));
1898 auto searchTypeId = TypeId::LookupByName(mp.pmSearchMethod);
1899 SetPmSearchTypeId(searchTypeId);
1900 SetPmSearchAttribute("RankLimit", UintegerValue(mp.rankLimit));
1901 if (searchTypeId == NrPmSearchFull::GetTypeId())
1902 {
1903 SetPmSearchAttribute("NrPmSearchFull::CodebookType",
1904 TypeIdValue(TypeId::LookupByName(mp.fullSearchCb)));
1905 }
1906}
1907
1908} // namespace ns3
static TypeId GetTypeId()
GetTypeId.
static TypeId GetTypeId()
GetTypeId.
static TypeId GetTypeId()
Get the type ID.
static TypeId GetTypeId()
GetTypeId.
Definition nr-amc.cc:51
Ptr< NrBearerStatsBase > GetPdcpStats()
void EnablePdcpStats(Ptr< NrBearerStatsBase > pdcpStats)
void EnableRlcStats(Ptr< NrBearerStatsBase > rlcStats)
Ptr< NrBearerStatsBase > GetRlcStats()
static TypeId GetTypeId()
Get the TypeId.
The NrGnbNetDevice class.
void RouteIngoingCtrlMsgs(const std::list< Ptr< NrControlMessage > > &msgList, uint8_t sourceBwpId)
The gNB received a CTRL message list.
void GenerateDataCqiReport(const SpectrumValue &sinr)
Generate a DL CQI report.
void ReportUlHarqFeedback(const UlHarqInfo &mes)
Get the HARQ feedback from NrSpectrumPhy and forward it to the scheduler.
void PhyDataPacketReceived(const Ptr< Packet > &p)
Receive a PHY data packet.
static TypeId GetTypeId()
Get Type id.
Definition nr-gnb-phy.cc:65
void EnableDlDataPhyTraces()
Enable DL DATA PHY traces.
static Ptr< BwpManagerGnb > GetBwpManagerGnb(const Ptr< NetDevice > &gnbDevice)
Get the BwpManager of the GNB.
Definition nr-helper.cc:423
void SetPhasedArraySpectrumPropagationLossModelAttribute(const std::string &n, const AttributeValue &v)
Set an attribute for the PhasedArraySpectrumPropagationLossModel before it is created.
int64_t AssignStreams(NetDeviceContainer c, int64_t stream)
static Ptr< NrUeMac > GetUeMac(const Ptr< NetDevice > &ueDevice, uint32_t bwpIndex)
Get a pointer to the MAC of the UE at the specified BWP.
Definition nr-helper.cc:397
void EnableTraces()
Enables the following traces: Transmitted/Received Control Messages DL/UL Phy Traces RLC traces PDCP ...
void AttachToEnb(const Ptr< NetDevice > &ueDevice, const Ptr< NetDevice > &gnbDevice)
Attach a UE to a particular GNB.
void AttachToClosestEnb(NetDeviceContainer ueDevices, NetDeviceContainer enbDevices)
Attach the UE specified to the closest GNB.
NetDeviceContainer InstallGnbDevice(const NodeContainer &c, const std::vector< std::reference_wrapper< BandwidthPartInfoPtr > > allBwps)
Install one (or more) GNBs.
Definition nr-helper.cc:506
void SetBeamformingHelper(Ptr< BeamformingHelperBase > beamformingHelper)
Set an ideal beamforming helper.
bool GetHarqEnabled() const
GetHarqEnabled.
Definition nr-helper.cc:471
void SetGnbDlAmcAttribute(const std::string &n, const AttributeValue &v)
NrHelper()
NrHelper constructor.
Definition nr-helper.cc:59
Ptr< NrBearerStatsCalculator > GetPdcpStatsCalculator()
Get the PDCP stats calculator object.
void EnableUePhyCtrlMsgsTraces()
Enable UE PHY CTRL TX and RX traces.
void EnableRlcSimpleTraces()
Enable RLC simple traces (DL RLC TX, DL RLC RX, UL DL TX, UL DL RX)
void SetUeAntennaAttribute(const std::string &n, const AttributeValue &v)
Set an attribute for the UE antenna, before it is created.
void SetUeChannelAccessManagerAttribute(const std::string &n, const AttributeValue &v)
Set an attribute for the UE channel access manager, before it is created.
bool GetSnrTest() const
GetSnrTest.
Definition nr-helper.cc:483
void EnableGnbPhyCtrlMsgsTraces()
Enable gNB PHY CTRL TX and RX traces.
~NrHelper() override
~NrHelper
Definition nr-helper.cc:96
void SetGnbBwpManagerAlgorithmTypeId(const TypeId &typeId)
Set the TypeId of the GNB BWP Manager. Works only before it is created.
static Ptr< BwpManagerUe > GetBwpManagerUe(const Ptr< NetDevice > &ueDevice)
Get the BwpManager of the UE.
Definition nr-helper.cc:437
void EnableDlMacSchedTraces()
void SetUeMacAttribute(const std::string &n, const AttributeValue &v)
Set an attribute for the UE MAC, before it is created.
void SetUlErrorModel(const std::string &errorModelTypeId)
Set the ErrorModel for UL AMC and UE spectrum at the same time.
@ INIT_PROPAGATION
Initialize the propagation loss model.
Definition nr-helper.h:386
@ INIT_FADING
Initialize the fading model.
Definition nr-helper.h:387
@ INIT_CHANNEL
Initialize the channel model.
Definition nr-helper.h:388
void SetUeBwpManagerAlgorithmTypeId(const TypeId &typeId)
Set the TypeId of the UE BWP Manager. Works only before it is created.
void EnableUlPhyTraces()
Enable UL PHY traces.
void EnablePathlossTraces()
Enable trace sinks for DL and UL pathloss.
void ActivateDataRadioBearer(NetDeviceContainer ueDevices, EpsBearer bearer)
Activate a Data Radio Bearer on a given UE devices.
void SetEpcHelper(Ptr< EpcHelper > epcHelper)
void SetPmSearchAttribute(const std::string &name, const AttributeValue &value)
Set attribute of the precoding matrix search algorithm.
void SetGnbAntennaAttribute(const std::string &n, const AttributeValue &v)
Set an attribute for the GNB antenna, before it is created.
void SetupGnbAntennas(const AntennaParams &ap)
Set parameters for gNB and UE antenna arrays.
static Ptr< NrGnbPhy > GetGnbPhy(const Ptr< NetDevice > &gnbDevice, uint32_t bwpIndex)
Get a pointer to the PHY of the GNB at the specified BWP.
Definition nr-helper.cc:371
void EnableUlMacSchedTraces()
void SetGnbUlAmcAttribute(const std::string &n, const AttributeValue &v)
static uint32_t GetNumberBwp(const Ptr< const NetDevice > &gnbDevice)
Get the number of configured BWP for a specific GNB NetDevice.
Definition nr-helper.cc:359
void EnableGnbMacCtrlMsgsTraces()
Enable gNB MAC CTRL TX and RX traces.
void SetUeChannelAccessManagerTypeId(const TypeId &typeId)
Set the TypeId of the UE Channel Access Manager. Works only before it is created.
void DeActivateDedicatedEpsBearer(Ptr< NetDevice > ueDevice, Ptr< NetDevice > enbDevice, uint8_t bearerId)
Manually trigger dedicated bearer de-activation at specific simulation time.
void SetHarqEnabled(bool harqEnabled)
SetHarqEnabled.
Definition nr-helper.cc:465
Ptr< NrBearerStatsCalculator > GetRlcStatsCalculator()
Get the RLC stats calculator object.
void EnableTransportBlockTrace()
Enable transport block trace.
void InitializeOperationBand(OperationBandInfo *band, uint8_t flags=INIT_PROPAGATION|INIT_FADING|INIT_CHANNEL)
Initialize the bandwidth parts by creating and configuring the channel models, if they are not alread...
Definition nr-helper.cc:267
void EnableGnbPacketCountTrace()
Enable gNB packet count trace.
void SetDlErrorModel(const std::string &errorModelTypeId)
Set the ErrorModel for DL AMC and GNB spectrum at the same time.
void EnableRlcE2eTraces()
Enable RLC calculator and end-to-end RCL traces to file.
void EnablePdcpSimpleTraces()
Enable PDCP traces (DL PDCP TX, DL PDCP RX, UL PDCP TX, UL PDCP RX)
static Ptr< NrMacScheduler > GetScheduler(const Ptr< NetDevice > &gnbDevice, uint32_t bwpIndex)
Get the Scheduler from the GNB specified.
Definition nr-helper.cc:451
void SetUeBwpManagerAlgorithmAttribute(const std::string &n, const AttributeValue &v)
Set an attribute for the GNB BWP Manager, before it is created.
void SetGnbMacAttribute(const std::string &n, const AttributeValue &v)
Set an attribute for the GNB MAC, before it is created.
void SetGnbPhyAttribute(const std::string &n, const AttributeValue &v)
Set an attribute for the GNB PHY, before it is created.
void EnableDlCtrlPhyTraces()
Enable DL CTRL PHY traces.
void SetupUeAntennas(const AntennaParams &ap)
Set parameters for gNB and UE antenna arrays.
static Ptr< NrGnbMac > GetGnbMac(const Ptr< NetDevice > &gnbDevice, uint32_t bwpIndex)
Get a pointer to the MAC of the GNB at the specified BWP.
Definition nr-helper.cc:384
void SetUePhyAttribute(const std::string &n, const AttributeValue &v)
Set an attribute for the UE PHY, before it is created.
static Ptr< NrUePhy > GetUePhy(const Ptr< NetDevice > &ueDevice, uint32_t bwpIndex)
Get a pointer to the PHY of the UE at the specified BWP.
Definition nr-helper.cc:410
uint8_t ActivateDedicatedEpsBearer(NetDeviceContainer ueDevices, EpsBearer bearer, Ptr< EpcTft > tft)
void SetupMimoPmi(const MimoPmiParams &mp)
Set parameters for PMI search in MIMO operation.
void EnableUePacketCountTrace()
Enable UE packet count trace.
static TypeId GetTypeId()
GetTypeId.
Definition nr-helper.cc:102
void SetUeSpectrumAttribute(const std::string &n, const AttributeValue &v)
Set an attribute for the UE spectrum, before it is created.
void SetPathlossAttribute(const std::string &n, const AttributeValue &v)
void SetSchedulerAttribute(const std::string &n, const AttributeValue &v)
Set an attribute for the scheduler, before it is created.
void EnableUeMacCtrlMsgsTraces()
Enable UE MAC CTRL TX and RX traces.
void SetSchedulerTypeId(const TypeId &typeId)
Set the Scheduler TypeId. Works only before it is created.
void SetGnbBwpManagerAlgorithmAttribute(const std::string &n, const AttributeValue &v)
Set an attribute for the GNB BWP Manager, before it is created.
Ptr< NrPhyRxTrace > GetPhyRxTrace()
Get the phy traces object.
void SetGnbSpectrumAttribute(const std::string &n, const AttributeValue &v)
Set an attribute for the GNB spectrum, before it is created.
NetDeviceContainer InstallUeDevice(const NodeContainer &c, const std::vector< std::reference_wrapper< BandwidthPartInfoPtr > > &allBwps)
Install one (or more) UEs.
Definition nr-helper.cc:489
void SetChannelConditionModelAttribute(const std::string &n, const AttributeValue &v)
void SetGnbChannelAccessManagerAttribute(const std::string &n, const AttributeValue &v)
Set an attribute for the GNB channel access manager, before it is created.
void EnablePdcpE2eTraces()
Enable PDCP calculator and end-to-end PDCP traces to file.
void SetGnbChannelAccessManagerTypeId(const TypeId &typeId)
Set the TypeId of the GNB Channel Access Manager. Works only before it is created.
void SetGnbBeamManagerTypeId(const TypeId &typeId)
Set the TypeId of the beam manager.
void SetPmSearchTypeId(const TypeId &typeId)
Set TypeId of the precoding matrix search algorithm.
void SetSnrTest(bool snrTest)
SetSnrTest.
Definition nr-helper.cc:477
static void RxedGnbMacCtrlMsgsCallback(Ptr< NrMacRxTrace > macStats, std::string path, SfnSf sfn, uint16_t nodeId, uint16_t rnti, uint8_t bwpId, Ptr< const NrControlMessage > msg)
static void TxedGnbMacCtrlMsgsCallback(Ptr< NrMacRxTrace > macStats, std::string path, SfnSf sfn, uint16_t nodeId, uint16_t rnti, uint8_t bwpId, Ptr< const NrControlMessage > msg)
static void RxedUeMacCtrlMsgsCallback(Ptr< NrMacRxTrace > macStats, std::string path, SfnSf sfn, uint16_t nodeId, uint16_t rnti, uint8_t bwpId, Ptr< const NrControlMessage > msg)
static void TxedUeMacCtrlMsgsCallback(Ptr< NrMacRxTrace > macStats, std::string path, SfnSf sfn, uint16_t nodeId, uint16_t rnti, uint8_t bwpId, Ptr< const NrControlMessage > msg)
static TypeId GetTypeId()
GetTypeId.
static void UlSchedulingCallback(Ptr< NrMacSchedulingStats > macStats, std::string path, NrSchedulingCallbackInfo traceInfo)
static void DlSchedulingCallback(Ptr< NrMacSchedulingStats > macStats, std::string path, NrSchedulingCallbackInfo traceInfo)
static void RxedGnbPhyCtrlMsgsCallback(Ptr< NrPhyRxTrace > phyStats, std::string path, SfnSf sfn, uint16_t nodeId, uint16_t rnti, uint8_t bwpId, Ptr< const NrControlMessage > msg)
static void ReportDlDataPathloss(Ptr< NrPhyRxTrace > phyStats, std::string path, uint16_t cellId, uint8_t bwpId, uint32_t ueNodeId, double lossDb, uint8_t cqi)
Write DL DATA pathloss values in a file.
static void PathlossTraceCallback(Ptr< NrPhyRxTrace > phyStats, std::string path, Ptr< const SpectrumPhy > txPhy, Ptr< const SpectrumPhy > rxPhy, double lossDb)
Trace sink for spectrum channel pathloss trace.
static void TxedGnbPhyCtrlMsgsCallback(Ptr< NrPhyRxTrace > phyStats, std::string path, SfnSf sfn, uint16_t nodeId, uint16_t rnti, uint8_t bwpId, Ptr< const NrControlMessage > msg)
static void TxedUePhyCtrlMsgsCallback(Ptr< NrPhyRxTrace > phyStats, std::string path, SfnSf sfn, uint16_t nodeId, uint16_t rnti, uint8_t bwpId, Ptr< const NrControlMessage > msg)
static void TxedUePhyHarqFeedbackCallback(Ptr< NrPhyRxTrace > phyStats, std::string path, SfnSf sfn, uint16_t nodeId, uint16_t rnti, uint8_t bwpId, uint8_t harqId, uint32_t k1Delay)
static void RxedUePhyCtrlMsgsCallback(Ptr< NrPhyRxTrace > phyStats, std::string path, SfnSf sfn, uint16_t nodeId, uint16_t rnti, uint8_t bwpId, Ptr< const NrControlMessage > msg)
static void DlCtrlSinrCallback(Ptr< NrPhyRxTrace > phyStats, std::string path, uint16_t cellId, uint16_t rnti, double avgSinr, uint16_t bwpId)
Trace sink for DL Average SINR of CTRL (in dB).
static void RxedUePhyDlDciCallback(Ptr< NrPhyRxTrace > phyStats, std::string path, SfnSf sfn, uint16_t nodeId, uint16_t rnti, uint8_t bwpId, uint8_t harqId, uint32_t k1Delay)
static void DlDataSinrCallback(Ptr< NrPhyRxTrace > phyStats, std::string path, uint16_t cellId, uint16_t rnti, double avgSinr, uint16_t bwpId)
Trace sink for DL Average SINR of DATA (in dB).
static void ReportDlCtrlPathloss(Ptr< NrPhyRxTrace > phyStats, std::string path, uint16_t cellId, uint8_t bwpId, uint32_t ueNodeId, double lossDb)
Write DL CTRL pathloss values in a file.
static TypeId GetTypeId()
Get TypeId.
Base class for searching optimal precoding matrices and creating full CQI/PMI feedback This is a most...
void SetGnbParams(bool isDualPol, size_t numHPorts, size_t numVPorts)
Set the antenna parameters of the gNB antenna.
void UpdateSinrPerceived(const SpectrumValue &sinr)
SpectrumPhy that will be called when the SINR for the received DATA is being calculated by the interf...
static TypeId GetTypeId()
Get the object TypeId.
std::function< void(const std::list< Ptr< NrControlMessage > > &, uint8_t)> NrPhyRxCtrlEndOkCallback
This callback method type is used to notify that CTRL is received.
void UpdateSrsSinrPerceived(const SpectrumValue &srsSinr)
SpectrumPhy that will be called when the SINR for the received SRS at gNB is being calculated by the ...
void UpdateMimoSinrPerceived(const std::vector< MimoSinrChunk > &sinr)
Store the SINR chunks for all received signals at end of interference calculations.
Callback< void, const DlHarqInfo & > NrPhyDlHarqFeedbackCallback
void ReportDlCtrlSinr(const SpectrumValue &sinr)
Called when DlCtrlSinr is fired.
The MAC class for the UE.
Definition nr-ue-mac.h:106
static TypeId GetTypeId()
Get the Type id.
Definition nr-ue-mac.cc:207
The User Equipment NetDevice.
void RouteIngoingCtrlMsgs(const std::list< Ptr< NrControlMessage > > &msgList, uint8_t sourceBwpId)
The UE received a CTRL message list.
static TypeId GetTypeId()
GetTypeId.
void EnqueueDlHarqFeedback(const DlHarqInfo &m) const
Spectrum has calculated the HarqFeedback for one DL transmission, and give it to the NetDevice of the...
void GenerateDlCqiReport(const SpectrumValue &sinr)
Generate a DL CQI report.
void GenerateDlCqiReportMimo(const std::vector< MimoSignalChunk > &mimoChunks)
Generate DL CQI, PMI, and RI (channel quality precoding matrix and rank indicators)
void PhyDataPacketReceived(const Ptr< Packet > &p)
Receive a PHY data packet.
void ReportRsReceivedPower(const SpectrumValue &power)
Called when rsReceivedPower is fired.
static TypeId GetTypeId()
Get the object TypeId.
Definition nr-ue-phy.cc:77
@ UMi_Buildings
UMi_StreetCanyon with buildings.
@ UMa_LoS
UMa where all the nodes will be in Line-of-Sight.
@ RMa_LoS
RMa where all the nodes will be in Line-of-Sight.
@ InH_OfficeOpen
InH_OfficeOpen.
@ InH_OfficeOpen_nLoS
indoor office where all the nodes will not be in Line-of-Sight
@ V2V_Highway
V2V_Highway.
@ RMa_nLoS
RMA where all the nodes will not be in Line-of-Sight.
@ InH_OfficeMixed_nLoS
indoor office where all the nodes will not be in Line-of-Sight
@ UMa_Buildings
UMa with buildings.
@ InH_OfficeOpen_LoS
indoor office where all the nodes will be in Line-of-Sight
@ UMa_nLoS
UMa where all the nodes will not be in Line-of-Sight.
@ UMi_StreetCanyon_LoS
UMi_StreetCanyon where all the nodes will be in Line-of-Sight.
@ InH_OfficeMixed
InH_OfficeMixed.
@ UMi_StreetCanyon
UMi_StreetCanyon.
@ InH_OfficeMixed_LoS
indoor office where all the nodes will be in Line-of-Sight
parameters of the gNB or UE antenna arrays
Definition nr-helper.h:856
size_t nAntRows
Number of antenna element rows (vertical height)
Definition nr-helper.h:859
bool isDualPolarized
true if antennas are cross-polarized (dual-polarized)
Definition nr-helper.h:860
double bearingAngle
Bearing angle in radians.
Definition nr-helper.h:863
std::string antennaElem
Antenna type.
Definition nr-helper.h:857
size_t nHorizPorts
Number of antenna ports in horizontal direction.
Definition nr-helper.h:861
size_t nVertPorts
Number of antenna ports in vertical direction.
Definition nr-helper.h:862
size_t nAntCols
Number of antenna element columns (horizontal width)
Definition nr-helper.h:858
double polSlantAngle
Polarization slant angle in radians.
Definition nr-helper.h:864
parameters for the search of optimal rank and precoding matrix indicator (RI, PMI)
Definition nr-helper.h:869
uint8_t rankLimit
Limit maximum MIMO rank to model limited UE capabilities.
Definition nr-helper.h:872
std::string fullSearchCb
Codebook when using full-search algorithm.
Definition nr-helper.h:871
std::string pmSearchMethod
Precoding matrix search algorithm.
Definition nr-helper.h:870
Operation band information structure.
std::vector< ComponentCarrierInfoPtr > m_cc
Operation band component carriers.