5G-LENA nr-v3.3-159-ga6832aa7
The 5G/NR module for the ns-3 simulator
Loading...
Searching...
No Matches
cttc-nr-notching.cc
Go to the documentation of this file.
1// Copyright (c) 2019 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
2//
3// SPDX-License-Identifier: GPL-2.0-only
4
5#include "ns3/antenna-module.h"
6#include "ns3/applications-module.h"
7#include "ns3/config-store-module.h"
8#include "ns3/config-store.h"
9#include "ns3/core-module.h"
10#include "ns3/flow-monitor-module.h"
11#include "ns3/ideal-beamforming-algorithm.h"
12#include "ns3/internet-apps-module.h"
13#include "ns3/internet-module.h"
14#include "ns3/ipv4-global-routing-helper.h"
15#include "ns3/log.h"
16#include "ns3/nr-helper.h"
17#include "ns3/nr-mac-scheduler-tdma-rr.h"
18#include "ns3/nr-module.h"
19#include "ns3/nr-point-to-point-epc-helper.h"
20#include "ns3/point-to-point-helper.h"
21#include "ns3/point-to-point-module.h"
22
64using namespace ns3;
65
66NS_LOG_COMPONENT_DEFINE("CttcNrNotching");
67
68int
69main(int argc, char* argv[])
70{
71 uint16_t gNbNum = 1;
72 uint16_t ueNumPergNb = 2;
73
74 uint8_t numBands = 1;
75 double centralFrequencyBand = 2e9;
76
77 double bandwidth = 10e6; // BW changes later on, depending on whether TDD or FDD is selected
78
79 uint16_t numerology = 0; // Only numerology of 0 is supported in this example
80
81 double totalTxPower = 43;
82
83 std::string operationMode = "TDD"; // TDD or FDD
84 std::string pattern = "DL|S|UL|UL|DL|DL|S|UL|UL|DL|";
85
86 bool udpFullBuffer = false;
87 uint32_t udpPacketSizeUll = 100;
88 uint32_t udpPacketSizeBe = 1252;
89 uint32_t lambdaUll = 10000;
90 uint32_t lambdaBe = 1000;
91
92 bool logging = false;
93
94 bool enableDl = false;
95 bool enableUl = true;
96
97 bool enableOfdma = false;
98
99 int notchedRbStartDl = 0;
100 int numOfNotchedRbsDl = 0;
101
102 int notchedRbStartUl = 0;
103 int numOfNotchedRbsUl = 0;
104
105 std::string simTag = "default";
106 std::string outputDir = "./";
107
108 double simTime = 1; // seconds
109 double udpAppStartTime = 0.4; // seconds
110
111 double validationValue1 = 0;
112 double validationValue2 = 0;
113
114 CommandLine cmd(__FILE__);
115
116 cmd.AddValue("simTime", "Simulation time", simTime);
117 cmd.AddValue("gNbNum",
118 "The number of gNbs. In this example up to 2 gNBs are supported",
119 gNbNum);
120 cmd.AddValue("ueNumPergNb", "The number of UEs per gNb", ueNumPergNb);
121 cmd.AddValue("bandwidth", "The system bandwidth. Choose among 5, 10 and 20 MHz", bandwidth);
122 cmd.AddValue("totalTxPower",
123 "total tx power that will be proportionally assigned to"
124 " bandwidth parts depending on each BWP bandwidth ",
125 totalTxPower);
126 cmd.AddValue("operationMode", "The network operation mode can be TDD or FDD", operationMode);
127 cmd.AddValue("tddPattern",
128 "LTE TDD pattern to use (e.g. --tddPattern=DL|S|UL|UL|UL|DL|S|UL|UL|UL|)",
129 pattern);
130 cmd.AddValue("udpFullBuffer",
131 "Whether to set the full buffer traffic; if this parameter is "
132 "set then the udpInterval parameter will be neglected.",
133 udpFullBuffer);
134 cmd.AddValue("packetSizeUll",
135 "packet size in bytes to be used by ultra low latency traffic",
136 udpPacketSizeUll);
137 cmd.AddValue("packetSizeBe",
138 "packet size in bytes to be used by best effort traffic",
139 udpPacketSizeBe);
140 cmd.AddValue("lambdaUll",
141 "Number of UDP packets in one second for ultra low latency traffic",
142 lambdaUll);
143 cmd.AddValue("lambdaBe",
144 "Number of UDP packets in one second for best effort traffic",
145 lambdaBe);
146 cmd.AddValue("logging", "Enable logging", logging);
147 cmd.AddValue("enableDl", "Enable DL flow", enableDl);
148 cmd.AddValue("enableUl", "Enable UL flow", enableUl);
149 cmd.AddValue("enableOfdma",
150 "enable Ofdma scheduler. If false (default) Tdma is enabled",
151 enableOfdma);
152 cmd.AddValue("notchedRbStartDl",
153 "starting point of notched RBs (choose among RBs 0-52 for BW of 10 MHz)"
154 "for the DL",
155 notchedRbStartDl);
156 cmd.AddValue("numOfNotchedRbsDl",
157 "Number of notched RBs for the DL. "
158 "Please be sure that the number of 'normal' RBs is sufficient to "
159 "perform transmissions of the UEs. If an error occurs, please try "
160 "to reduce either the number of UEs or the number of the RBs notched.",
161 numOfNotchedRbsDl);
162 cmd.AddValue("notchedRbStartUl",
163 "starting point of notched RBs (choose among RBs 0-52 for BW of 10 MHz)"
164 "for the UL",
165 notchedRbStartUl);
166 cmd.AddValue("numOfNotchedRbsUl",
167 "Number of notched RBs for the UL. "
168 "Please be sure that the number of 'normal' RBs is sufficient to "
169 "perform transmissions of the UEs. If an error occurs, please try "
170 "to reduce either the number of UEs or the number of the RBs notched.",
171 numOfNotchedRbsUl);
172 cmd.AddValue("simTag",
173 "tag to be appended to output filenames to distinguish simulation campaigns",
174 simTag);
175 cmd.AddValue("outputDir", "directory where to store simulation results", outputDir);
176 cmd.AddValue("validationValue1",
177 "Value used when running test.py to check if the specific example result value is "
178 "as expected",
179 validationValue1);
180 cmd.AddValue("validationValue2",
181 "Value used when running test.py to check if the specific example result value is "
182 "as expected",
183 validationValue2);
184 cmd.Parse(argc, argv);
185
186 NS_ABORT_IF(numBands < 1);
187 NS_ABORT_MSG_IF(enableDl == false && enableUl == false,
188 "Enable at least one of "
189 "the flows (DL/UL)");
190 NS_ABORT_MSG_IF(numerology != 0, "Only numerology 0 is supported in this example");
191
192 // Set the size of the mask according to the supported BW
193 int size = 0;
194 if (bandwidth == 5e6)
195 {
196 size = 26;
197 NS_ABORT_MSG_IF(notchedRbStartDl < 0 || notchedRbStartDl > 25,
198 "The starting point "
199 "of the DL notched RBs must be between 0 and 25 for BW of 5MHz");
200 NS_ABORT_MSG_IF((notchedRbStartDl + numOfNotchedRbsDl) > 25,
201 "The available RBs "
202 "in DL are 26 (from 0 to 25) for BW of 5MHz");
203 NS_ABORT_MSG_IF(notchedRbStartUl < 0 || notchedRbStartUl > 25,
204 "The starting point "
205 "of the UL notched RBs must be between 0 and 25 for BW of 5MHz");
206 NS_ABORT_MSG_IF((notchedRbStartUl + numOfNotchedRbsUl) > 25,
207 "The available RBs "
208 "in UL are 26 (from 0 to 25) for BW of 5MHz");
209 }
210 else if (bandwidth == 10e6)
211 {
212 size = 53;
213 NS_ABORT_MSG_IF(notchedRbStartDl < 0 || notchedRbStartDl > 52,
214 "The starting point "
215 "of the DL notched RBs must be between 0 and 52 for BW of 10MHz");
216 NS_ABORT_MSG_IF((notchedRbStartDl + numOfNotchedRbsDl) > 52,
217 "The available RBs "
218 "in DL are 53 (from 0 to 52) for BW of 10MHz");
219 NS_ABORT_MSG_IF(notchedRbStartUl < 0 || notchedRbStartUl > 52,
220 "The starting point "
221 "of the UL notched RBs must be between 0 and 52 for BW of 10MHz");
222 NS_ABORT_MSG_IF((notchedRbStartUl + numOfNotchedRbsUl) > 52,
223 "The available RBs "
224 "in UL are 53 (from 0 to 52) for BW of 10MHz");
225 }
226 else if (bandwidth == 20e6)
227 {
228 size = 106;
229 NS_ABORT_MSG_IF(notchedRbStartDl < 0 || notchedRbStartDl > 105,
230 "The starting point "
231 "of the DL notched RBs must be between 0 and 105 for BW of 20MHz");
232 NS_ABORT_MSG_IF((notchedRbStartDl + numOfNotchedRbsDl) > 105,
233 "The available RBs "
234 "in DL are 106 (from 0 to 105) for BW of 20MHz");
235 NS_ABORT_MSG_IF(notchedRbStartUl < 0 || notchedRbStartUl > 105,
236 "The starting point "
237 "of the UL notched RBs must be between 0 and 105 for BW of 20MHz");
238 NS_ABORT_MSG_IF((notchedRbStartUl + numOfNotchedRbsUl) > 105,
239 "The available RBs "
240 "in UL are 106 (from 0 to 105) for BW of 20MHz");
241 }
242 else
243 {
244 NS_ABORT_MSG("This bandwidth is not supported in this example. "
245 "Please choose among 5MHz - 10MHz - 20MHz.");
246 }
247
248 // Default mask (all 1s)
249 std::vector<bool> notchedMaskDl(size, true);
250 std::vector<bool> notchedMaskUl(size, true);
251
252 // mute RBs from notchedRbStart to (notchedRbStart + numOfNotchedRbs)
253 for (int i = notchedRbStartDl; i < (notchedRbStartDl + numOfNotchedRbsDl); i++)
254 {
255 notchedMaskDl[i] = false;
256 }
257
258 for (int i = notchedRbStartUl; i < (notchedRbStartUl + numOfNotchedRbsUl); i++)
259 {
260 notchedMaskUl[i] = false;
261 }
262
263 std::cout << "DL notched Mask: ";
264 for (int x : notchedMaskDl)
265 {
266 std::cout << x << " ";
267 }
268 std::cout << std::endl;
269 std::cout << "UL notched Mask: ";
270 for (int x : notchedMaskUl)
271 {
272 std::cout << x << " ";
273 }
274 std::cout << std::endl;
275 std::cout << "Warning: Please be sure that the number of 'normal' RBs is "
276 << "sufficient to perform transmissions of the UEs.\n If an error "
277 << "occurs, please try to reduce either the number of notched RBs "
278 << "or the number of UEs." << std::endl;
279
280 // enable logging or not
281 if (logging)
282 {
283 LogLevel logLevel1 =
284 (LogLevel)(LOG_PREFIX_FUNC | LOG_PREFIX_TIME | LOG_PREFIX_NODE | LOG_LEVEL_INFO);
285 LogLevel logLevel2 =
286 (LogLevel)(LOG_PREFIX_FUNC | LOG_PREFIX_TIME | LOG_PREFIX_NODE | LOG_LEVEL_DEBUG);
287 LogComponentEnable("NrMacSchedulerNs3", logLevel1);
288 LogComponentEnable("NrMacSchedulerTdma", logLevel1);
289 // LogComponentEnable ("NrMacSchedulerTdmaRR", logLevel1);
290 LogComponentEnable("NrMacSchedulerOfdma", logLevel1);
291 // LogComponentEnable ("NrMacSchedulerOfdmaRR", logLevel1);
292 LogComponentEnable("CcBwpHelper", logLevel2);
293 }
294
295 Config::SetDefault("ns3::NrRlcUm::MaxTxBufferSize", UintegerValue(999999999));
296
297 int64_t randomStream = 1;
298
299 GridScenarioHelper gridScenario;
300 gridScenario.SetRows(1);
301 gridScenario.SetColumns(gNbNum);
302 gridScenario.SetHorizontalBsDistance(5.0);
303 gridScenario.SetVerticalBsDistance(5.0);
304 gridScenario.SetBsHeight(1.5);
305 gridScenario.SetUtHeight(1.5);
306 gridScenario.SetSectorization(GridScenarioHelper::SINGLE);
307 gridScenario.SetBsNumber(gNbNum);
308 gridScenario.SetUtNumber(ueNumPergNb * gNbNum);
309 gridScenario.SetScenarioHeight(3); // Create a 3x3 scenario where the UE will
310 gridScenario.SetScenarioLength(3); // be distributed.
311 randomStream += gridScenario.AssignStreams(randomStream);
312 gridScenario.CreateScenario();
313
314 // setup the nr simulation
315 Ptr<NrPointToPointEpcHelper> nrEpcHelper = CreateObject<NrPointToPointEpcHelper>();
316 Ptr<IdealBeamformingHelper> idealBeamformingHelper = CreateObject<IdealBeamformingHelper>();
317 Ptr<NrHelper> nrHelper = CreateObject<NrHelper>();
318 Ptr<NrChannelHelper> channelHelper = CreateObject<NrChannelHelper>();
319 nrHelper->SetBeamformingHelper(idealBeamformingHelper);
320 nrHelper->SetEpcHelper(nrEpcHelper);
321 nrEpcHelper->SetAttribute("S1uLinkDelay", TimeValue(MilliSeconds(0)));
322 if (enableOfdma)
323 {
324 nrHelper->SetSchedulerTypeId(TypeId::LookupByName("ns3::NrMacSchedulerOfdmaRR"));
325 }
326 else
327 {
328 nrHelper->SetSchedulerTypeId(TypeId::LookupByName("ns3::NrMacSchedulerTdmaRR"));
329 }
330
331 // Beamforming method
332 idealBeamformingHelper->SetAttribute("BeamformingMethod",
333 TypeIdValue(DirectPathBeamforming::GetTypeId()));
334
335 /*
336 * Setup the configuration of the spectrum. One operation band is deployed
337 * with 1 component carrier (CC), automatically generated by the ccBwpManager
338 */
340 CcBwpCreator ccBwpCreator;
341
343
344 /*
345 * The configured spectrum division for TDD is:
346 *
347 * |----Band1----|
348 * |-----CC1-----|
349 * |-----BWP1----|
350 *
351 * And the configured spectrum division for FDD operation is:
352 * |---------Band1---------|
353 * |----------CC1----------|
354 * |----BWP1---|----BWP2---|
355 */
356
357 const uint8_t numOfCcs = 1;
358
359 if (operationMode == "FDD")
360 {
361 // For FDD we have 2 BWPs so the BW must be doubled (e.g. for BW of 10MHz we
362 // need 20MHz --> 10MHz for the DL BWP and 10MHz for the UL BWP)
363 bandwidth = bandwidth * 2;
364 // First CC (index 0) will be DL, and second CC (index 1) will be UL
365 Config::SetDefault("ns3::NrUeNetDevice::PrimaryUlIndex", UintegerValue(1));
366 }
367
368 // Create the configuration for the CcBwpHelper
369 CcBwpCreator::SimpleOperationBandConf bandConf(centralFrequencyBand, bandwidth, numOfCcs);
370
371 bandConf.m_numBwp = operationMode == "FDD" ? 2 : 1; // FDD will have 2 BWPs per CC
372
373 // By using the configuration created, it is time to make the operation band
374 band = ccBwpCreator.CreateOperationBandContiguousCc(bandConf);
375 // Set the channel to use UMi scenario, LOS channel condition and 3GPP channel model
376 channelHelper->ConfigureFactories("UMi", "LOS", "ThreeGpp");
377 // Disable shadowing
378 channelHelper->SetPathlossAttribute("ShadowingEnabled", BooleanValue(false));
379 channelHelper->AssignChannelsToBands({band});
380 allBwps = CcBwpCreator::GetAllBwps({band});
381
382 double x = pow(10, totalTxPower / 10);
383
384 // Antennas for all the UEs
385 nrHelper->SetUeAntennaAttribute("NumRows", UintegerValue(1));
386 nrHelper->SetUeAntennaAttribute("NumColumns", UintegerValue(1));
387 nrHelper->SetUeAntennaAttribute("AntennaElement",
388 PointerValue(CreateObject<IsotropicAntennaModel>()));
389
390 // Antennas for all the gNbs
391 nrHelper->SetGnbAntennaAttribute("NumRows", UintegerValue(4));
392 nrHelper->SetGnbAntennaAttribute("NumColumns", UintegerValue(8));
393 nrHelper->SetGnbAntennaAttribute("AntennaElement",
394 PointerValue(CreateObject<IsotropicAntennaModel>()));
395
396 uint32_t bwpIdForLowLat = 0;
397 uint32_t bwpIdForVideo = 0;
398
399 // gNb and UE routing between Bearer and bandwidh part
400 if (operationMode == "TDD")
401 {
402 nrHelper->SetGnbBwpManagerAlgorithmAttribute("NGBR_LOW_LAT_EMBB",
403 UintegerValue(bwpIdForLowLat));
404 nrHelper->SetUeBwpManagerAlgorithmAttribute("NGBR_VIDEO_TCP_DEFAULT",
405 UintegerValue(bwpIdForVideo));
406 }
407 else
408 {
409 bwpIdForVideo = 1;
410 nrHelper->SetGnbBwpManagerAlgorithmAttribute("NGBR_LOW_LAT_EMBB",
411 UintegerValue(bwpIdForLowLat));
412 nrHelper->SetGnbBwpManagerAlgorithmAttribute("NGBR_VIDEO_TCP_DEFAULT",
413 UintegerValue(bwpIdForVideo));
414
415 nrHelper->SetUeBwpManagerAlgorithmAttribute("NGBR_LOW_LAT_EMBB",
416 UintegerValue(bwpIdForLowLat));
417 nrHelper->SetUeBwpManagerAlgorithmAttribute("NGBR_VIDEO_TCP_DEFAULT",
418 UintegerValue(bwpIdForVideo));
419 }
420
421 // Install and get the pointers to the NetDevices
422 NetDeviceContainer gnbNetDev =
423 nrHelper->InstallGnbDevice(gridScenario.GetBaseStations(), allBwps);
424 NetDeviceContainer ueNetDev =
425 nrHelper->InstallUeDevice(gridScenario.GetUserTerminals(), allBwps);
426
427 randomStream += nrHelper->AssignStreams(gnbNetDev, randomStream);
428 randomStream += nrHelper->AssignStreams(ueNetDev, randomStream);
429
430 for (uint32_t i = 0; i < gNbNum; ++i)
431 {
432 // Manually set the attribute of the netdevice (gnbNetDev.Get (0)) and bandwidth part (0),
433 // (1), ...
434 nrHelper->GetGnbPhy(gnbNetDev.Get(i), 0)
435 ->SetAttribute("Numerology", UintegerValue(numerology));
436 nrHelper->GetGnbPhy(gnbNetDev.Get(i), 0)
437 ->SetAttribute("TxPower", DoubleValue(10 * log10(x)));
438
439 // Set the mask
440 Ptr<NrMacSchedulerNs3> schedulerBwp1 =
441 DynamicCast<NrMacSchedulerNs3>(nrHelper->GetScheduler(gnbNetDev.Get(i), 0));
442 schedulerBwp1->SetDlNotchedRbgMask(notchedMaskDl);
443
444 if (operationMode == "TDD")
445 {
446 nrHelper->GetGnbPhy(gnbNetDev.Get(i), 0)->SetAttribute("Pattern", StringValue(pattern));
447 schedulerBwp1->SetUlNotchedRbgMask(notchedMaskUl);
448 }
449 else
450 {
451 nrHelper->GetGnbPhy(gnbNetDev.Get(i), 0)
452 ->SetAttribute("Pattern", StringValue("DL|DL|DL|DL|DL|DL|DL|DL|DL|DL|"));
453
454 nrHelper->GetGnbPhy(gnbNetDev.Get(i), 1)
455 ->SetAttribute("Numerology", UintegerValue(numerology));
456 nrHelper->GetGnbPhy(gnbNetDev.Get(i), 1)->SetAttribute("TxPower", DoubleValue(-30.0));
457 nrHelper->GetGnbPhy(gnbNetDev.Get(i), 1)
458 ->SetAttribute("Pattern", StringValue("UL|UL|UL|UL|UL|UL|UL|UL|UL|UL|"));
459
460 Ptr<NrMacSchedulerNs3> schedulerBwp2 =
461 DynamicCast<NrMacSchedulerNs3>(nrHelper->GetScheduler(gnbNetDev.Get(i), 1));
462 schedulerBwp2->SetUlNotchedRbgMask(notchedMaskUl);
463
464 // Link the two FDD BWPs:
465 nrHelper->GetBwpManagerGnb(gnbNetDev.Get(i))->SetOutputLink(1, 0);
466 }
467 }
468
469 if (operationMode == "FDD")
470 {
471 // Set the UE routing:
472 for (uint32_t i = 0; i < ueNetDev.GetN(); i++)
473 {
474 nrHelper->GetBwpManagerUe(ueNetDev.Get(i))->SetOutputLink(0, 1);
475 }
476 }
477
478 // create the internet and install the IP stack on the UEs
479 // get SGW/PGW and create a single RemoteHost
480 Ptr<Node> pgw = nrEpcHelper->GetPgwNode();
481 NodeContainer remoteHostContainer;
482 remoteHostContainer.Create(1);
483 Ptr<Node> remoteHost = remoteHostContainer.Get(0);
484 InternetStackHelper internet;
485 internet.Install(remoteHostContainer);
486
487 // connect a remoteHost to pgw. Setup routing too
488 PointToPointHelper p2ph;
489 p2ph.SetDeviceAttribute("DataRate", DataRateValue(DataRate("100Gb/s")));
490 p2ph.SetDeviceAttribute("Mtu", UintegerValue(2500));
491 p2ph.SetChannelAttribute("Delay", TimeValue(Seconds(0.000)));
492 NetDeviceContainer internetDevices = p2ph.Install(pgw, remoteHost);
493 Ipv4AddressHelper ipv4h;
494 Ipv4StaticRoutingHelper ipv4RoutingHelper;
495 ipv4h.SetBase("1.0.0.0", "255.0.0.0");
496 Ipv4InterfaceContainer internetIpIfaces = ipv4h.Assign(internetDevices);
497 Ptr<Ipv4StaticRouting> remoteHostStaticRouting =
498 ipv4RoutingHelper.GetStaticRouting(remoteHost->GetObject<Ipv4>());
499 remoteHostStaticRouting->AddNetworkRouteTo(Ipv4Address("7.0.0.0"), Ipv4Mask("255.0.0.0"), 1);
500 internet.Install(gridScenario.GetUserTerminals());
501 Ipv4InterfaceContainer ueIpIface;
502 ueIpIface = nrEpcHelper->AssignUeIpv4Address(NetDeviceContainer(ueNetDev));
503
504 // Attach to GNB
505 nrHelper->AttachToClosestGnb(ueNetDev, gnbNetDev);
506
507 // install UDP applications
508 uint16_t dlPortLowLat = 1234;
509 uint16_t ulPortVoice = 1235;
510
511 ApplicationContainer serverApps;
512
513 // The sink will always listen to the specified ports
514 UdpServerHelper dlPacketSinkLowLat(dlPortLowLat);
515 UdpServerHelper ulPacketSinkVoice(ulPortVoice);
516
517 // The server, that is the application which is listening, is installed in the UE
518 // for the DL traffic, and in the remote host for the UL traffic
519 serverApps.Add(dlPacketSinkLowLat.Install(gridScenario.GetUserTerminals()));
520 serverApps.Add(ulPacketSinkVoice.Install(remoteHost));
521
522 /*
523 * Configure attributes for the different generators, using user-provided
524 * parameters for generating a CBR traffic
525 *
526 * Low-Latency configuration and object creation:
527 */
528 UdpClientHelper dlClientLowLat;
529 dlClientLowLat.SetAttribute("RemotePort", UintegerValue(dlPortLowLat));
530 dlClientLowLat.SetAttribute("MaxPackets", UintegerValue(0xFFFFFFFF));
531 dlClientLowLat.SetAttribute("PacketSize", UintegerValue(udpPacketSizeBe));
532 dlClientLowLat.SetAttribute("Interval", TimeValue(Seconds(1.0 / lambdaBe)));
533
534 // The bearer that will carry low latency traffic
536
537 // The filter for the low-latency traffic
538 Ptr<NrEpcTft> lowLatTft = Create<NrEpcTft>();
539 NrEpcTft::PacketFilter dlpfLowLat;
540 dlpfLowLat.localPortStart = dlPortLowLat;
541 dlpfLowLat.localPortEnd = dlPortLowLat;
542 lowLatTft->Add(dlpfLowLat);
543
544 // Voice configuration and object creation:
545 UdpClientHelper ulClientVoice;
546 ulClientVoice.SetAttribute("RemotePort", UintegerValue(ulPortVoice));
547 ulClientVoice.SetAttribute("MaxPackets", UintegerValue(0xFFFFFFFF));
548 ulClientVoice.SetAttribute("PacketSize", UintegerValue(udpPacketSizeBe));
549 ulClientVoice.SetAttribute("Interval", TimeValue(Seconds(1.0 / lambdaBe)));
550
551 // The bearer that will carry voice traffic
553
554 // The filter for the voice traffic
555 Ptr<NrEpcTft> voiceTft = Create<NrEpcTft>();
556 NrEpcTft::PacketFilter ulpfVoice;
557 ulpfVoice.remotePortStart = ulPortVoice;
558 ulpfVoice.remotePortEnd = ulPortVoice;
559 ulpfVoice.direction = NrEpcTft::UPLINK;
560 voiceTft->Add(ulpfVoice);
561
562 // Install the applications
563 ApplicationContainer clientApps;
564
565 for (uint32_t i = 0; i < gridScenario.GetUserTerminals().GetN(); ++i)
566 {
567 Ptr<Node> ue = gridScenario.GetUserTerminals().Get(i);
568 Ptr<NetDevice> ueDevice = ueNetDev.Get(i);
569 Address ueAddress = ueIpIface.GetAddress(i);
570
571 // The client, who is transmitting, is installed in the remote host,
572 // with destination address set to the address of the UE
573 if (enableDl)
574 {
575 dlClientLowLat.SetAttribute("RemoteAddress", AddressValue(ueAddress));
576 clientApps.Add(dlClientLowLat.Install(remoteHost));
577
578 nrHelper->ActivateDedicatedEpsBearer(ueDevice, lowLatBearer, lowLatTft);
579 }
580 // For the uplink, the installation happens in the UE, and the remote address
581 // is the one of the remote host
582 if (enableUl)
583 {
584 ulClientVoice.SetAttribute("RemoteAddress",
585 AddressValue(internetIpIfaces.GetAddress(1)));
586 clientApps.Add(ulClientVoice.Install(ue));
587
588 nrHelper->ActivateDedicatedEpsBearer(ueDevice, videoBearer, voiceTft);
589 }
590 }
591
592 // start UDP server and client apps
593 serverApps.Start(Seconds(udpAppStartTime));
594 clientApps.Start(Seconds(udpAppStartTime));
595 serverApps.Stop(Seconds(simTime));
596 clientApps.Stop(Seconds(simTime));
597
598 // enable the traces provided by the nr module
599 nrHelper->EnableTraces();
600
601 FlowMonitorHelper flowmonHelper;
602 NodeContainer endpointNodes;
603 endpointNodes.Add(remoteHost);
604 endpointNodes.Add(gridScenario.GetUserTerminals());
605
606 Ptr<ns3::FlowMonitor> monitor = flowmonHelper.Install(endpointNodes);
607 monitor->SetAttribute("DelayBinWidth", DoubleValue(0.001));
608 monitor->SetAttribute("JitterBinWidth", DoubleValue(0.001));
609 monitor->SetAttribute("PacketSizeBinWidth", DoubleValue(20));
610
611 Simulator::Stop(Seconds(simTime));
612 Simulator::Run();
613
614 /*
615 * To check what was installed in the memory, i.e., BWPs of gNB Device, and its configuration.
616 * Example is: Node 1 -> Device 0 -> BandwidthPartMap -> {0,1} BWPs -> NrGnbPhy ->
617 NrPhyMacCommong-> Numerology, Bandwidth, ... GtkConfigStore config; config.ConfigureAttributes
618 ();
619 */
620
621 // Print per-flow statistics
622 monitor->CheckForLostPackets();
623 Ptr<Ipv4FlowClassifier> classifier =
624 DynamicCast<Ipv4FlowClassifier>(flowmonHelper.GetClassifier());
625 FlowMonitor::FlowStatsContainer stats = monitor->GetFlowStats();
626
627 double averageFlowThroughput = 0.0;
628 double averageFlowDelay = 0.0;
629
630 std::ofstream outFile;
631 std::string filename = outputDir + "/" + simTag;
632 outFile.open(filename.c_str(), std::ofstream::out | std::ofstream::trunc);
633 if (!outFile.is_open())
634 {
635 std::cerr << "Can't open file " << filename << std::endl;
636 return 1;
637 }
638
639 outFile.setf(std::ios_base::fixed);
640
641 for (std::map<FlowId, FlowMonitor::FlowStats>::const_iterator i = stats.begin();
642 i != stats.end();
643 ++i)
644 {
645 Ipv4FlowClassifier::FiveTuple t = classifier->FindFlow(i->first);
646 std::stringstream protoStream;
647 protoStream << (uint16_t)t.protocol;
648 if (t.protocol == 6)
649 {
650 protoStream.str("TCP");
651 }
652 if (t.protocol == 17)
653 {
654 protoStream.str("UDP");
655 }
656 outFile << "Flow " << i->first << " (" << t.sourceAddress << ":" << t.sourcePort << " -> "
657 << t.destinationAddress << ":" << t.destinationPort << ") proto "
658 << protoStream.str() << "\n";
659 outFile << " Tx Packets: " << i->second.txPackets << "\n";
660 outFile << " Tx Bytes: " << i->second.txBytes << "\n";
661 outFile << " TxOffered: "
662 << i->second.txBytes * 8.0 / (simTime - udpAppStartTime) / 1000 / 1000 << " Mbps\n";
663 outFile << " Rx Bytes: " << i->second.rxBytes << "\n";
664 if (i->second.rxPackets > 0)
665 {
666 // Measure the duration of the flow from receiver's perspective
667 // double rxDuration = i->second.timeLastRxPacket.GetSeconds () -
668 // i->second.timeFirstTxPacket.GetSeconds ();
669 double rxDuration = (simTime - udpAppStartTime);
670
671 averageFlowThroughput += i->second.rxBytes * 8.0 / rxDuration / 1000 / 1000;
672 averageFlowDelay += 1000 * i->second.delaySum.GetSeconds() / i->second.rxPackets;
673
674 outFile << " Throughput: " << i->second.rxBytes * 8.0 / rxDuration / 1000 / 1000
675 << " Mbps\n";
676 outFile << " Mean delay: "
677 << 1000 * i->second.delaySum.GetSeconds() / i->second.rxPackets << " ms\n";
678 // outFile << " Mean upt: " << i->second.uptSum / i->second.rxPackets / 1000/1000 << "
679 // Mbps \n";
680 outFile << " Mean jitter: "
681 << 1000 * i->second.jitterSum.GetSeconds() / i->second.rxPackets << " ms\n";
682
683 // used when running examples from test.py
684 if (validationValue1 && (i->first == 1))
685 {
686 if ((validationValue1 >
687 (i->second.rxBytes * 8.0 / rxDuration / 1000 / 1000) * 1.1) ||
688 (validationValue1 < (i->second.rxBytes * 8.0 / rxDuration / 1000 / 1000) * 0.9))
689 {
690 NS_FATAL_ERROR("Example results for flow 1 has changed for more then +- 10% "
691 "wrt to the previous version of the ns-3 and NR module");
692 }
693 }
694 else if (validationValue2 && (i->first == 2))
695 {
696 if ((validationValue2 >
697 (i->second.rxBytes * 8.0 / rxDuration / 1000 / 1000) * 1.1) ||
698 (validationValue2 < (i->second.rxBytes * 8.0 / rxDuration / 1000 / 1000) * 0.9))
699 {
700 NS_FATAL_ERROR("Example results for flow 2 has changed for more then +- 10% "
701 "wrt to the previous version of the ns-3 and NR module");
702 }
703 }
704 }
705 else
706 {
707 if ((validationValue1 && (i->first == 1)) || (validationValue2 && (i->first == 2)))
708 {
709 NS_FATAL_ERROR("Expected packets, but they never arrived");
710 }
711 outFile << " Throughput: 0 Mbps\n";
712 outFile << " Mean delay: 0 ms\n";
713 outFile << " Mean jitter: 0 ms\n";
714 }
715 outFile << " Rx Packets: " << i->second.rxPackets << "\n";
716 }
717
718 outFile << "\n\n Mean flow throughput: " << averageFlowThroughput / stats.size() << "\n";
719 outFile << " Mean flow delay: " << averageFlowDelay / stats.size() << "\n";
720
721 outFile.close();
722
723 std::ifstream f(filename.c_str());
724
725 if (f.is_open())
726 {
727 std::cout << f.rdbuf();
728 }
729
730 Simulator::Destroy();
731 return 0;
732}
Manages the correct creation of operation bands, component carriers and bandwidth parts.
OperationBandInfo CreateOperationBandContiguousCc(const SimpleOperationBandConf &conf)
Create an operation band with the CC specified.
static BandwidthPartInfoPtrVector GetAllBwps(const std::vector< std::reference_wrapper< OperationBandInfo > > &operationBands)
Get all the BWP pointers from the specified vector of operation bands.
static TypeId GetTypeId()
Get the type id.
The GridScenarioHelper class.
void SetRows(uint32_t r)
SetRows.
void SetHorizontalBsDistance(double d)
SetHorizontalBsDistance.
void SetVerticalBsDistance(double d)
SetVerticalBsDistance.
void CreateScenario() override
Create the scenario, with the configured parameter.
int64_t AssignStreams(int64_t stream)
void SetColumns(uint32_t c)
SetColumns.
const NodeContainer & GetUserTerminals() const
Get the list of user nodes.
void SetBsNumber(std::size_t n)
Set the number of base stations.
void SetUtNumber(std::size_t n)
Set the number of UT/UE.
const NodeContainer & GetBaseStations() const
Get the list of gnb/base station nodes.
This class contains the specification of EPS Bearers.
@ NGBR_LOW_LAT_EMBB
Non-GBR Low Latency eMBB applications.
@ NGBR_VIDEO_TCP_DEFAULT
Non-GBR TCP-based Video (Buffered Streaming, e.g., www, e-mail...)
void SetBsHeight(double h)
SetGnbHeight.
void SetUtHeight(double h)
SetUeHeight.
void SetSectorization(SiteSectorizationType numSectors)
Sets the number of sectors of every site.
std::vector< std::reference_wrapper< BandwidthPartInfoPtr > > BandwidthPartInfoPtrVector
vector of unique_ptr of BandwidthPartInfo
Minimum configuration requirements for a OperationBand.
Direction direction
Whether the filter needs to be applied to uplink / downlink only, or in both cases.
Definition nr-epc-tft.h:104
uint16_t remotePortEnd
end of the port number range of the remote host
Definition nr-epc-tft.h:117
uint16_t localPortStart
start of the port number range of the UE
Definition nr-epc-tft.h:118
uint16_t remotePortStart
start of the port number range of the remote host
Definition nr-epc-tft.h:116
uint16_t localPortEnd
end of the port number range of the UE
Definition nr-epc-tft.h:119
Operation band information structure.