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/internet-apps-module.h"
12#include "ns3/internet-module.h"
13#include "ns3/mobility-module.h"
14#include "ns3/nr-module.h"
15#include "ns3/point-to-point-module.h"
49NS_LOG_COMPONENT_DEFINE(
"3gppChannelNumerologiesExample");
52main(
int argc,
char* argv[])
58 LogComponentEnable(
"UdpClient", LOG_LEVEL_INFO);
59 LogComponentEnable(
"UdpServer", LOG_LEVEL_INFO);
60 LogComponentEnable(
"NrPdcp", LOG_LEVEL_INFO);
65 double udpAppStartTime = 0.4;
68 uint16_t numerology = 0;
71 uint16_t ueNumPergNb = 1;
73 double centralFrequency = 7e9;
74 double bandwidth = 100e6;
77 uint32_t udpPacketSize = 1000;
78 bool udpFullBuffer =
true;
79 uint8_t fixedMcs = 28;
80 bool useFixedMcs =
true;
81 bool singleUeTopology =
true;
83 std::string simTag =
"default";
84 std::string outputDir =
"./";
86 CommandLine cmd(__FILE__);
87 cmd.AddValue(
"gNbNum",
"The number of gNbs in multiple-ue topology", gNbNum);
88 cmd.AddValue(
"ueNumPergNb",
"The number of UE per gNb in multiple-ue topology", ueNumPergNb);
89 cmd.AddValue(
"numerology",
"The numerology to be used.", numerology);
90 cmd.AddValue(
"txPower",
"Tx power to be configured to gNB", txPower);
91 cmd.AddValue(
"simTag",
92 "tag to be appended to output filenames to distinguish simulation campaigns",
94 cmd.AddValue(
"outputDir",
"directory where to store simulation results", outputDir);
95 cmd.AddValue(
"frequency",
"The system frequency", centralFrequency);
96 cmd.AddValue(
"bandwidth",
"The system bandwidth", bandwidth);
97 cmd.AddValue(
"udpPacketSize",
"UDP packet size in bytes", udpPacketSize);
98 cmd.AddValue(
"lambda",
"Number of UDP packets per second", lambda);
99 cmd.AddValue(
"udpFullBuffer",
100 "Whether to set the full buffer traffic; if this parameter is set then the "
101 "udpInterval parameter"
106 "The fixed MCS that will be used in this example if useFixedMcs is configured to true (1).",
108 cmd.AddValue(
"useFixedMcs",
109 "Whether to use fixed mcs, normally used for testing purposes",
111 cmd.AddValue(
"singleUeTopology",
112 "If true, the example uses a predefined topology with one UE and one gNB; "
113 "if false, the example creates a grid of gNBs with a number of UEs attached",
116 cmd.Parse(argc, argv);
118 NS_ASSERT(ueNumPergNb > 0);
121 Ptr<NrHelper> nrHelper = CreateObject<NrHelper>();
123 Ptr<NrChannelHelper> channelHelper = CreateObject<NrChannelHelper>();
132 const uint8_t numCcPerBand = 1;
133 std::string scenario =
"RMa";
134 std::string condition =
"LOS";
137 scenario =
"InH-OfficeOpen";
141 channelHelper->ConfigureFactories(scenario, condition,
"ThreeGpp");
143 Config::SetDefault(
"ns3::ThreeGppChannelModel::UpdatePeriod", TimeValue(MilliSeconds(0)));
144 channelHelper->SetPathlossAttribute(
"ShadowingEnabled", BooleanValue(
false));
152 channelHelper->AssignChannelsToBands({band});
159 nrHelper->SetGnbPhyAttribute(
"TxPower", DoubleValue(txPower));
160 nrHelper->SetGnbPhyAttribute(
"Numerology", UintegerValue(numerology));
163 nrHelper->SetSchedulerTypeId(TypeId::LookupByName(
"ns3::NrMacSchedulerTdmaRR"));
164 nrHelper->SetSchedulerAttribute(
"FixedMcsDl", BooleanValue(useFixedMcs));
165 nrHelper->SetSchedulerAttribute(
"FixedMcsUl", BooleanValue(useFixedMcs));
169 nrHelper->SetSchedulerAttribute(
"StartingMcsDl", UintegerValue(fixedMcs));
170 nrHelper->SetSchedulerAttribute(
"StartingMcsUl", UintegerValue(fixedMcs));
173 Config::SetDefault(
"ns3::NrRlcUm::MaxTxBufferSize", UintegerValue(999999999));
176 nrHelper->SetUeAntennaAttribute(
"NumRows", UintegerValue(2));
177 nrHelper->SetUeAntennaAttribute(
"NumColumns", UintegerValue(4));
178 nrHelper->SetUeAntennaAttribute(
"AntennaElement",
179 PointerValue(CreateObject<IsotropicAntennaModel>()));
182 nrHelper->SetGnbAntennaAttribute(
"NumRows", UintegerValue(4));
183 nrHelper->SetGnbAntennaAttribute(
"NumColumns", UintegerValue(8));
184 nrHelper->SetGnbAntennaAttribute(
"AntennaElement",
185 PointerValue(CreateObject<ThreeGppAntennaModel>()));
188 Ptr<IdealBeamformingHelper> idealBeamformingHelper = CreateObject<IdealBeamformingHelper>();
189 idealBeamformingHelper->SetAttribute(
"BeamformingMethod",
191 nrHelper->SetBeamformingHelper(idealBeamformingHelper);
194 nrHelper->SetUlErrorModel(
"ns3::NrEesmIrT1");
195 nrHelper->SetDlErrorModel(
"ns3::NrEesmIrT1");
198 nrHelper->SetGnbDlAmcAttribute(
201 nrHelper->SetGnbUlAmcAttribute(
206 Ptr<NrPointToPointEpcHelper> nrEpcHelper = CreateObject<NrPointToPointEpcHelper>();
207 nrHelper->SetEpcHelper(nrEpcHelper);
209 nrEpcHelper->SetAttribute(
"S1uLinkDelay", TimeValue(MilliSeconds(0)));
212 uint32_t bwpIdForBearer = 0;
213 nrHelper->SetGnbBwpManagerAlgorithmAttribute(
"GBR_CONV_VOICE", UintegerValue(bwpIdForBearer));
218 NodeContainer gNbNodes;
219 NodeContainer ueNodes;
220 MobilityHelper mobility;
221 mobility.SetMobilityModel(
"ns3::ConstantPositionMobilityModel");
222 Ptr<ListPositionAllocator> bsPositionAlloc = CreateObject<ListPositionAllocator>();
223 Ptr<ListPositionAllocator> utPositionAlloc = CreateObject<ListPositionAllocator>();
225 const double gNbHeight = 10;
226 const double ueHeight = 1.5;
228 if (singleUeTopology)
235 mobility.Install(gNbNodes);
236 mobility.Install(ueNodes);
237 bsPositionAlloc->Add(Vector(0.0, 0.0, gNbHeight));
238 utPositionAlloc->Add(Vector(0.0, 30.0, ueHeight));
242 gNbNodes.Create(gNbNum);
243 ueNodes.Create(ueNumPergNb * gNbNum);
245 int32_t yValue = 0.0;
246 for (uint32_t i = 1; i <= gNbNodes.GetN(); ++i)
251 yValue =
static_cast<int>(i) * 30;
258 bsPositionAlloc->Add(Vector(0.0, yValue, gNbHeight));
262 for (uint16_t j = 1; j <= ueNumPergNb; ++j)
275 utPositionAlloc->Add(Vector(xValue, 1, ueHeight));
279 utPositionAlloc->Add(Vector(xValue, -1, ueHeight));
284 mobility.SetPositionAllocator(bsPositionAlloc);
285 mobility.Install(gNbNodes);
287 mobility.SetPositionAllocator(utPositionAlloc);
288 mobility.Install(ueNodes);
291 NetDeviceContainer gNbNetDev = nrHelper->InstallGnbDevice(gNbNodes, allBwps);
293 NetDeviceContainer ueNetDev = nrHelper->InstallUeDevice(ueNodes, allBwps);
295 int64_t randomStream = 1;
296 randomStream += nrHelper->AssignStreams(gNbNetDev, randomStream);
297 randomStream += nrHelper->AssignStreams(ueNetDev, randomStream);
301 auto [remoteHost, remoteHostIpv4Address] =
302 nrEpcHelper->SetupRemoteHost(
"100Gb/s", 2500, Seconds(0.000));
304 InternetStackHelper internet;
305 internet.Install(ueNodes);
307 Ipv4InterfaceContainer ueIpIface =
308 nrEpcHelper->AssignUeIpv4Address(NetDeviceContainer(ueNetDev));
311 nrHelper->AttachToClosestGnb(ueNetDev, gNbNetDev);
314 uint16_t dlPort = 1234;
316 ApplicationContainer serverApps;
319 UdpServerHelper dlPacketSinkHelper(dlPort);
320 serverApps.Add(dlPacketSinkHelper.Install(ueNodes.Get(0)));
322 UdpClientHelper dlClient;
323 dlClient.SetAttribute(
"RemotePort", UintegerValue(dlPort));
324 dlClient.SetAttribute(
"PacketSize", UintegerValue(udpPacketSize));
325 dlClient.SetAttribute(
"MaxPackets", UintegerValue(0xFFFFFFFF));
328 double bitRate = 75000000;
330 bitRate /= ueNumPergNb;
331 if (bandwidth > 20e6)
333 bitRate *= bandwidth / 20e6;
335 lambda = bitRate /
static_cast<double>(udpPacketSize * 8);
337 dlClient.SetAttribute(
"Interval", TimeValue(Seconds(1.0 / lambda)));
342 Ptr<NrEpcTft> tft = Create<NrEpcTft>();
351 ApplicationContainer clientApps;
353 for (uint32_t i = 0; i < ueNodes.GetN(); ++i)
355 Ptr<Node> ue = ueNodes.Get(i);
356 Ptr<NetDevice> ueDevice = ueNetDev.Get(i);
357 Address ueAddress = ueIpIface.GetAddress(i);
361 dlClient.SetAttribute(
"RemoteAddress", AddressValue(ueAddress));
362 clientApps.Add(dlClient.Install(remoteHost));
365 nrHelper->ActivateDedicatedEpsBearer(ueDevice, bearer, tft);
369 serverApps.Start(Seconds(udpAppStartTime));
370 clientApps.Start(Seconds(udpAppStartTime));
371 serverApps.Stop(Seconds(simTime));
372 clientApps.Stop(Seconds(simTime));
377 FlowMonitorHelper flowmonHelper;
378 NodeContainer endpointNodes;
379 endpointNodes.Add(remoteHost);
380 endpointNodes.Add(ueNodes);
382 Ptr<ns3::FlowMonitor> monitor = flowmonHelper.Install(endpointNodes);
383 monitor->SetAttribute(
"DelayBinWidth", DoubleValue(0.001));
384 monitor->SetAttribute(
"JitterBinWidth", DoubleValue(0.001));
385 monitor->SetAttribute(
"PacketSizeBinWidth", DoubleValue(20));
387 Simulator::Stop(Seconds(simTime));
391 monitor->CheckForLostPackets();
392 Ptr<Ipv4FlowClassifier> classifier =
393 DynamicCast<Ipv4FlowClassifier>(flowmonHelper.GetClassifier());
394 FlowMonitor::FlowStatsContainer stats = monitor->GetFlowStats();
396 double averageFlowThroughput = 0.0;
397 double averageFlowDelay = 0.0;
399 std::ofstream outFile;
400 std::string filename = outputDir +
"/" + simTag;
401 outFile.open(filename.c_str(), std::ofstream::out | std::ofstream::trunc);
402 if (!outFile.is_open())
404 NS_LOG_ERROR(
"Can't open file " << filename);
407 outFile.setf(std::ios_base::fixed);
409 for (std::map<FlowId, FlowMonitor::FlowStats>::const_iterator i = stats.begin();
413 Ipv4FlowClassifier::FiveTuple t = classifier->FindFlow(i->first);
414 std::stringstream protoStream;
415 protoStream << (uint16_t)t.protocol;
418 protoStream.str(
"TCP");
420 if (t.protocol == 17)
422 protoStream.str(
"UDP");
424 outFile <<
"Flow " << i->first <<
" (" << t.sourceAddress <<
":" << t.sourcePort <<
" -> "
425 << t.destinationAddress <<
":" << t.destinationPort <<
") proto "
426 << protoStream.str() <<
"\n";
427 outFile <<
" Tx Packets: " << i->second.txPackets <<
"\n";
428 outFile <<
" Tx Bytes: " << i->second.txBytes <<
"\n";
429 outFile <<
" TxOffered: "
430 << i->second.txBytes * 8.0 / (simTime - udpAppStartTime) / 1000 / 1000 <<
" Mbps\n";
431 outFile <<
" Rx Bytes: " << i->second.rxBytes <<
"\n";
432 if (i->second.rxPackets > 0)
436 i->second.timeLastRxPacket.GetSeconds() - i->second.timeFirstTxPacket.GetSeconds();
438 averageFlowThroughput += i->second.rxBytes * 8.0 / rxDuration / 1000 / 1000;
439 averageFlowDelay += 1000 * i->second.delaySum.GetSeconds() / i->second.rxPackets;
441 outFile <<
" Throughput: " << i->second.rxBytes * 8.0 / rxDuration / 1000 / 1000
443 outFile <<
" Mean delay: "
444 << 1000 * i->second.delaySum.GetSeconds() / i->second.rxPackets <<
" ms\n";
447 outFile <<
" Mean jitter: "
448 << 1000 * i->second.jitterSum.GetSeconds() / i->second.rxPackets <<
" ms\n";
452 outFile <<
" Throughput: 0 Mbps\n";
453 outFile <<
" Mean delay: 0 ms\n";
454 outFile <<
" Mean upt: 0 Mbps \n";
455 outFile <<
" Mean jitter: 0 ms\n";
457 outFile <<
" Rx Packets: " << i->second.rxPackets <<
"\n";
460 double meanFlowThroughput = averageFlowThroughput / stats.size();
461 double meanFlowDelay = averageFlowDelay / stats.size();
462 Ptr<UdpServer> serverApp = serverApps.Get(0)->GetObject<UdpServer>();
463 double totalUdpThroughput =
464 ((serverApp->GetReceived() * udpPacketSize * 8) / (simTime - udpAppStartTime)) * 1e-6;
466 outFile <<
"\n\n Mean flow throughput: " << meanFlowThroughput <<
"\n";
467 outFile <<
" Mean flow delay: " << meanFlowDelay <<
"\n";
468 outFile <<
"\n UDP throughput (bps) for UE with node ID 0:" << totalUdpThroughput << std::endl;
472 std::ifstream f(filename.c_str());
476 std::cout << f.rdbuf();
479 Simulator::Destroy();
481 double toleranceMeanFlowThroughput = 383.557857 * 0.0001;
482 double toleranceMeanFlowDelay = 3.533664 * 0.0001;
483 double toleranceUdpThroughput = 372.5066667 * 0.0001;
486 if (argc == 0 && (meanFlowThroughput < 383.557857 - toleranceMeanFlowThroughput ||
487 meanFlowThroughput > 383.557857 + toleranceMeanFlowThroughput ||
488 meanFlowDelay < 3.533664 - toleranceMeanFlowDelay ||
489 meanFlowDelay > 3.533664 + toleranceMeanFlowDelay ||
490 totalUdpThroughput < 372.5066667 - toleranceUdpThroughput ||
491 totalUdpThroughput > 372.5066667 + toleranceUdpThroughput))
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.
@ ErrorModel
Error Model version (can use different error models, see NrErrorModel)
This class contains the specification of EPS Bearers.
@ GBR_CONV_VOICE
GBR Conversational Voice.
std::vector< std::reference_wrapper< BandwidthPartInfoPtr > > BandwidthPartInfoPtrVector
vector of unique_ptr of BandwidthPartInfo
Minimum configuration requirements for a OperationBand.
uint16_t localPortStart
start of the port number range of the UE
uint16_t localPortEnd
end of the port number range of the UE
Operation band information structure.