23#include "ns3/antenna-module.h"
24#include "ns3/applications-module.h"
25#include "ns3/buildings-module.h"
26#include "ns3/config-store-module.h"
27#include "ns3/core-module.h"
28#include "ns3/flow-monitor-module.h"
29#include "ns3/internet-apps-module.h"
30#include "ns3/internet-module.h"
31#include "ns3/mobility-module.h"
32#include "ns3/nr-module.h"
33#include "ns3/point-to-point-module.h"
37NS_LOG_COMPONENT_DEFINE(
"CttcNrSimpleQosSched");
40main(
int argc,
char* argv[])
49 uint16_t ueNumPergNb = 2;
54 Time simTime = MilliSeconds(1000);
55 Time udpAppStartTime = MilliSeconds(400);
59 uint16_t numerology = 0;
60 double centralFrequency = 4e9;
61 double bandwidth = 10e6;
62 double totalTxPower = 43;
64 bool enableOfdma =
false;
65 std::string schedulerType =
"PF";
66 bool enableQoSLcScheduler =
false;
68 uint8_t priorityTrafficScenario = 0;
70 uint16_t mcsTable = 2;
72 bool enablePdcpDiscarding =
false;
73 uint32_t discardTimerMs = 0;
75 bool enableNrHelperTraces =
false;
76 bool enableQosTrafficTraces =
true;
78 std::string simTag =
"default";
79 std::string outputDir =
"./";
88 cmd.AddValue(
"gNbNum",
"The number of gNbs in multiple-ue topology", gNbNum);
89 cmd.AddValue(
"ueNumPergNb",
"The number of UE per gNb in multiple-ue topology", ueNumPergNb);
90 cmd.AddValue(
"logging",
"Enable logging", logging);
91 cmd.AddValue(
"priorityTrafficScenario",
92 "The traffic scenario for the case of priority. Can be 0: saturation"
94 priorityTrafficScenario);
95 cmd.AddValue(
"simTime",
"Simulation time", simTime);
96 cmd.AddValue(
"numerology",
"The numerology to be used", numerology);
97 cmd.AddValue(
"centralFrequency",
"The system frequency to be used", centralFrequency);
98 cmd.AddValue(
"bandwidth",
"The system bandwidth to be used", bandwidth);
99 cmd.AddValue(
"totalTxPower",
100 "total tx power that will be proportionally assigned to"
101 " bands, CCs and bandwidth parts depending on each BWP bandwidth ",
103 cmd.AddValue(
"simTag",
104 "tag to be appended to output filenames to distinguish simulation campaigns",
106 cmd.AddValue(
"outputDir",
"directory where to store simulation results", outputDir);
107 cmd.AddValue(
"enableOfdma",
108 "If set to true it enables Ofdma scheduler. Default value is false (Tdma)",
110 cmd.AddValue(
"schedulerType",
111 "PF: Proportional Fair (default), RR: Round-Robin, Qos",
113 cmd.AddValue(
"enableQoSLcScheduler",
114 "If set to true, it enables the QoS LC scheduler. Default is RR (false)",
115 enableQoSLcScheduler);
116 cmd.AddValue(
"enableNrHelperTraces",
117 "If true, it enables the generation of the NrHelper traces, otherwise"
118 "NrHelper traces will not be generated. Default value is false",
119 enableNrHelperTraces);
120 cmd.AddValue(
"enableQosTrafficTraces",
121 "If true, it enables the generation of the the Delay and Throughput"
122 "traces, otherwise these traces will not be generated. Default value is true",
123 enableQosTrafficTraces);
124 cmd.AddValue(
"enablePdcpDiscarding",
125 "Whether to enable PDCP TX discarding",
126 enablePdcpDiscarding);
127 cmd.AddValue(
"discardTimerMs",
128 "Discard timer value in milliseconds to use for all the flows",
131 cmd.Parse(argc, argv);
137 (LogLevel)(LOG_PREFIX_FUNC | LOG_PREFIX_TIME | LOG_PREFIX_NODE | LOG_LEVEL_INFO);
138 LogComponentEnable(
"NrMacSchedulerNs3", logLevel1);
139 LogComponentEnable(
"NrMacSchedulerTdma", logLevel1);
142 Config::SetDefault(
"ns3::NrRlcUm::MaxTxBufferSize", UintegerValue(999999999));
143 Config::SetDefault(
"ns3::NrRlcUm::EnablePdcpDiscarding", BooleanValue(enablePdcpDiscarding));
144 Config::SetDefault(
"ns3::NrRlcUm::DiscardTimerMs", UintegerValue(discardTimerMs));
151 int64_t randomStream = 1;
164 gridScenario.SetScenarioHeight(3);
165 gridScenario.SetScenarioLength(3);
169 uint32_t udpPacketSize1;
170 uint32_t udpPacketSize2;
171 uint32_t lambda1 = 1000;
172 uint32_t lambda2 = 1000;
174 if (priorityTrafficScenario == 0)
176 udpPacketSize1 = 3000;
177 udpPacketSize2 = 3000;
179 else if (priorityTrafficScenario == 1)
181 udpPacketSize1 = 3000;
182 udpPacketSize2 = 1252;
186 NS_ABORT_MSG(
"The priorityTrafficScenario chosen is not correct. "
187 "Please choose among 0: saturation and 1: medium-load");
195 NodeContainer ue1flowContainer;
196 NodeContainer ue2flowsContainer;
202 j % 2 == 0 ? ue1flowContainer.Add(ue) : ue2flowsContainer.Add(ue);
205 if (priorityTrafficScenario == 1)
207 lambda1 = 1000 / ue1flowContainer.GetN();
208 lambda2 = 1000 / ue2flowsContainer.GetN();
212 Ptr<NrPointToPointEpcHelper> nrEpcHelper = CreateObject<NrPointToPointEpcHelper>();
213 Ptr<IdealBeamformingHelper> idealBeamformingHelper = CreateObject<IdealBeamformingHelper>();
214 Ptr<NrHelper> nrHelper = CreateObject<NrHelper>();
217 nrHelper->SetBeamformingHelper(idealBeamformingHelper);
218 nrHelper->SetEpcHelper(nrEpcHelper);
219 nrEpcHelper->SetAttribute(
"S1uLinkDelay", TimeValue(MilliSeconds(0)));
221 std::stringstream scheduler;
224 subType = !enableOfdma ?
"Tdma" :
"Ofdma";
225 scheduler <<
"ns3::NrMacScheduler" << subType << schedulerType;
226 std::cout <<
"Scheduler: " << scheduler.str() << std::endl;
227 nrHelper->SetSchedulerTypeId(TypeId::LookupByName(scheduler.str()));
229 if (enableQoSLcScheduler)
231 nrHelper->SetSchedulerAttribute(
"SchedLcAlgorithmType",
236 std::string errorModel =
"ns3::NrEesmIrT" + std::to_string(mcsTable);
237 nrHelper->SetDlErrorModel(errorModel);
238 nrHelper->SetUlErrorModel(errorModel);
245 idealBeamformingHelper->SetAttribute(
"BeamformingMethod",
249 nrHelper->SetUeAntennaAttribute(
"NumRows", UintegerValue(1));
250 nrHelper->SetUeAntennaAttribute(
"NumColumns", UintegerValue(1));
251 nrHelper->SetUeAntennaAttribute(
"AntennaElement",
252 PointerValue(CreateObject<IsotropicAntennaModel>()));
255 nrHelper->SetGnbAntennaAttribute(
"NumRows", UintegerValue(1));
256 nrHelper->SetGnbAntennaAttribute(
"NumColumns", UintegerValue(1));
257 nrHelper->SetGnbAntennaAttribute(
"AntennaElement",
258 PointerValue(CreateObject<IsotropicAntennaModel>()));
267 const uint8_t numOfCcs = 1;
281 bandConf.m_numBwp = 1;
285 Ptr<NrChannelHelper> channelHelper = CreateObject<NrChannelHelper>();
287 channelHelper->ConfigureFactories(
"UMi",
"LOS",
"ThreeGpp");
289 channelHelper->SetPathlossAttribute(
"ShadowingEnabled", BooleanValue(
false));
294 double x = pow(10, totalTxPower / 10);
296 Packet::EnableChecking();
297 Packet::EnablePrinting();
299 uint32_t bwpIdUe1 = 0;
300 uint32_t bwpIdUe2Flow1 = 0;
301 uint32_t bwpIdUe2Flow2 = 0;
304 nrHelper->SetGnbBwpManagerAlgorithmAttribute(
"NGBR_LOW_LAT_EMBB", UintegerValue(bwpIdUe1));
305 nrHelper->SetGnbBwpManagerAlgorithmAttribute(
"NGBR_LOW_LAT_EMBB", UintegerValue(bwpIdUe2Flow1));
306 nrHelper->SetGnbBwpManagerAlgorithmAttribute(
"DGBR_INTER_SERV_87",
307 UintegerValue(bwpIdUe2Flow2));
310 nrHelper->SetUeBwpManagerAlgorithmAttribute(
"NGBR_LOW_LAT_EMBB", UintegerValue(bwpIdUe1));
311 nrHelper->SetUeBwpManagerAlgorithmAttribute(
"NGBR_LOW_LAT_EMBB", UintegerValue(bwpIdUe2Flow1));
312 nrHelper->SetUeBwpManagerAlgorithmAttribute(
"DGBR_INTER_SERV_87", UintegerValue(bwpIdUe2Flow2));
318 NetDeviceContainer gnbNetDev =
320 NetDeviceContainer ue1flowNetDev = nrHelper->InstallUeDevice(ue1flowContainer, allBwps);
321 NetDeviceContainer ue2flowsNetDev = nrHelper->InstallUeDevice(ue2flowsContainer, allBwps);
323 randomStream += nrHelper->AssignStreams(gnbNetDev, randomStream);
324 randomStream += nrHelper->AssignStreams(ue1flowNetDev, randomStream);
325 randomStream += nrHelper->AssignStreams(ue2flowsNetDev, randomStream);
327 nrHelper->GetGnbPhy(gnbNetDev.Get(0), 0)->SetAttribute(
"Numerology", UintegerValue(numerology));
328 nrHelper->GetGnbPhy(gnbNetDev.Get(0), 0)->SetAttribute(
"TxPower", DoubleValue(10 * log10(x)));
332 auto [remoteHost, remoteHostIpv4Address] =
333 nrEpcHelper->SetupRemoteHost(
"100Gb/s", 2500, Seconds(0.000));
335 InternetStackHelper internet;
339 Ipv4InterfaceContainer ue1FlowIpIface;
340 Ipv4InterfaceContainer ue2FlowsIpIface;
341 ue1FlowIpIface = nrEpcHelper->AssignUeIpv4Address(NetDeviceContainer(ue1flowNetDev));
342 ue2FlowsIpIface = nrEpcHelper->AssignUeIpv4Address(NetDeviceContainer(ue2flowsNetDev));
345 nrHelper->AttachToClosestGnb(ue1flowNetDev, gnbNetDev);
346 nrHelper->AttachToClosestGnb(ue2flowsNetDev, gnbNetDev);
352 uint16_t dlPortUe1flow = 1234;
353 uint16_t dlPortUe2flowsNgbr = 1235;
354 uint16_t dlPortUe2flowsDcGbr = 1236;
356 ApplicationContainer serverApps;
359 UdpServerHelper dlPacketSinkUe1flow(dlPortUe1flow);
360 UdpServerHelper dlPacketSinkUe2flowsNgbr(dlPortUe2flowsNgbr);
361 UdpServerHelper dlPacketSinkUe2flowsDcGgbr(dlPortUe2flowsDcGbr);
364 serverApps.Add(dlPacketSinkUe1flow.Install(ue1flowContainer));
365 serverApps.Add(dlPacketSinkUe2flowsNgbr.Install(ue2flowsContainer));
366 serverApps.Add(dlPacketSinkUe2flowsDcGgbr.Install(ue2flowsContainer));
375 UdpClientHelper dlClientUe1flow;
376 dlClientUe1flow.SetAttribute(
"RemotePort", UintegerValue(dlPortUe1flow));
377 dlClientUe1flow.SetAttribute(
"MaxPackets", UintegerValue(0xFFFFFFFF));
378 dlClientUe1flow.SetAttribute(
"PacketSize", UintegerValue(udpPacketSize1));
379 dlClientUe1flow.SetAttribute(
"Interval", TimeValue(Seconds(1.0 / lambda1)));
385 Ptr<NrEpcTft> ue1flowTft = Create<NrEpcTft>();
389 ue1flowTft->Add(dlpfUe1flow);
394 UdpClientHelper dlClientUe2flowsNgbr;
395 dlClientUe2flowsNgbr.SetAttribute(
"RemotePort", UintegerValue(dlPortUe2flowsNgbr));
396 dlClientUe2flowsNgbr.SetAttribute(
"MaxPackets", UintegerValue(0xFFFFFFFF));
397 dlClientUe2flowsNgbr.SetAttribute(
"PacketSize", UintegerValue(udpPacketSize1));
398 dlClientUe2flowsNgbr.SetAttribute(
"Interval", TimeValue(Seconds(1.0 / lambda1)));
407 Ptr<NrEpcTft> ue2flowsNgbrTft = Create<NrEpcTft>();
411 ue2flowsNgbrTft->Add(dlpfUe2flowsNgbr);
415 UdpClientHelper dlClientUe2flowsDcGbr;
416 dlClientUe2flowsDcGbr.SetAttribute(
"RemotePort", UintegerValue(dlPortUe2flowsDcGbr));
417 dlClientUe2flowsDcGbr.SetAttribute(
"MaxPackets", UintegerValue(0xFFFFFFFF));
418 dlClientUe2flowsDcGbr.SetAttribute(
"PacketSize", UintegerValue(udpPacketSize2));
419 dlClientUe2flowsDcGbr.SetAttribute(
"Interval", TimeValue(Seconds(1.0 / lambda2)));
422 qosUe2flowsDcGbr.
gbrDl = 5e6;
428 Ptr<NrEpcTft> ue2FlowsDcGbrTft = Create<NrEpcTft>();
432 ue2FlowsDcGbrTft->Add(dlpfUe2flowsDcGbr);
436 ApplicationContainer clientApps;
438 for (uint32_t i = 0; i < ue1flowContainer.GetN(); ++i)
440 Ptr<NetDevice> ueDevice = ue1flowNetDev.Get(i);
441 Address ueAddress = ue1FlowIpIface.GetAddress(i);
445 dlClientUe1flow.SetAttribute(
"RemoteAddress", AddressValue(ueAddress));
446 clientApps.Add(dlClientUe1flow.Install(remoteHost));
449 nrHelper->ActivateDedicatedEpsBearer(ueDevice, ue1flowBearer, ue1flowTft);
452 for (uint32_t i = 0; i < ue2flowsContainer.GetN(); ++i)
454 Ptr<NetDevice> ueDevice = ue2flowsNetDev.Get(i);
455 Address ueAddress = ue2FlowsIpIface.GetAddress(i);
459 dlClientUe2flowsNgbr.SetAttribute(
"RemoteAddress", AddressValue(ueAddress));
460 clientApps.Add(dlClientUe2flowsNgbr.Install(remoteHost));
463 nrHelper->ActivateDedicatedEpsBearer(ueDevice, ue2flowsNgbrBearer, ue2flowsNgbrTft);
466 for (uint32_t i = 0; i < ue2flowsContainer.GetN(); ++i)
468 Ptr<NetDevice> ueDevice = ue2flowsNetDev.Get(i);
469 Address ueAddress = ue2FlowsIpIface.GetAddress(i);
473 dlClientUe2flowsDcGbr.SetAttribute(
"RemoteAddress", AddressValue(ueAddress));
474 clientApps.Add(dlClientUe2flowsDcGbr.Install(remoteHost));
477 nrHelper->ActivateDedicatedEpsBearer(ueDevice, ue2flowsDcGbrBearer, ue2FlowsDcGbrTft);
481 serverApps.Start(udpAppStartTime);
482 clientApps.Start(udpAppStartTime);
483 serverApps.Stop(simTime);
484 clientApps.Stop(simTime);
487 if (enableNrHelperTraces)
489 nrHelper->EnableTraces();
492 FlowMonitorHelper flowmonHelper;
493 NodeContainer endpointNodes;
494 endpointNodes.Add(remoteHost);
497 Ptr<ns3::FlowMonitor> monitor = flowmonHelper.Install(endpointNodes);
498 monitor->SetAttribute(
"DelayBinWidth", DoubleValue(0.001));
499 monitor->SetAttribute(
"JitterBinWidth", DoubleValue(0.001));
500 monitor->SetAttribute(
"PacketSizeBinWidth", DoubleValue(20));
502 Simulator::Stop(simTime);
505 double averageFlowThroughput = 0.0;
506 double averageFlowDelay = 0.0;
508 std::ofstream delayFile;
509 std::ofstream throughputFile;
511 std::ostringstream delayFileName;
512 std::ostringstream throughputFileName;
515 lcSced = enableQoSLcScheduler ?
"LcQos" :
"LcRR";
519 delayFileName <<
"Delay"
520 <<
"_" << schedulerType.c_str() <<
"_" << lcSced.c_str() <<
".txt";
522 throughputFileName <<
"Throughput"
523 <<
"_" << schedulerType.c_str() <<
"_" << lcSced.c_str() <<
".txt";
527 delayFileName << outputDir <<
"Delay" << simTag << std::string(
".txt").c_str();
528 throughputFileName << outputDir <<
"Throughput" << simTag << std::string(
".txt").c_str();
531 if (enableQosTrafficTraces)
533 delayFile.open(delayFileName.str());
534 delayFile.setf(std::ios_base::fixed);
536 if (!delayFile.is_open())
538 NS_ABORT_MSG(
"Can't open file " << delayFileName.str());
540 delayFile <<
"source_address"
551 throughputFile.open(throughputFileName.str());
552 throughputFile.setf(std::ios_base::fixed);
554 if (!throughputFile.is_open())
556 NS_ABORT_MSG(
"Can't open file " << throughputFileName.str());
559 throughputFile <<
"source_port"
577 monitor->CheckForLostPackets();
578 Ptr<Ipv4FlowClassifier> classifier =
579 DynamicCast<Ipv4FlowClassifier>(flowmonHelper.GetClassifier());
580 FlowMonitor::FlowStatsContainer stats = monitor->GetFlowStats();
582 std::ofstream outFile;
583 std::string filename = outputDir +
"/" + simTag;
584 outFile.open(filename.c_str(), std::ofstream::out | std::ofstream::trunc);
585 if (!outFile.is_open())
587 std::cerr <<
"Can't open file " << filename << std::endl;
591 outFile.setf(std::ios_base::fixed);
593 double flowDuration = (simTime - udpAppStartTime).GetSeconds();
594 for (std::map<FlowId, FlowMonitor::FlowStats>::const_iterator i = stats.begin();
598 Ipv4FlowClassifier::FiveTuple t = classifier->FindFlow(i->first);
600 if (enableQosTrafficTraces)
602 for (uint32_t j = 0; j < i->second.delayHistogram.GetNBins(); j++)
604 Histogram h = i->second.delayHistogram;
605 if (h.GetBinCount(j))
607 for (uint32_t k = 0; k < h.GetBinCount(j); k++)
609 delayFile << t.sourceAddress <<
"\t" << t.sourcePort <<
"\t"
610 << t.destinationAddress <<
"\t" << t.destinationPort <<
"\t"
611 << h.GetBinStart(j) <<
"\n";
617 std::stringstream protoStream;
618 protoStream << (uint16_t)t.protocol;
621 protoStream.str(
"TCP");
623 if (t.protocol == 17)
625 protoStream.str(
"UDP");
627 outFile <<
"Flow " << i->first <<
" (" << t.sourceAddress <<
":" << t.sourcePort <<
" -> "
628 << t.destinationAddress <<
":" << t.destinationPort <<
") proto "
629 << protoStream.str() <<
"\n";
630 outFile <<
" Tx Packets: " << i->second.txPackets <<
"\n";
631 outFile <<
" Tx Bytes: " << i->second.txBytes <<
"\n";
632 outFile <<
" TxOffered: " << i->second.txBytes * 8.0 / flowDuration / 1000.0 / 1000.0
634 outFile <<
" Rx Bytes: " << i->second.rxBytes <<
"\n";
635 if (i->second.rxPackets > 0)
638 averageFlowThroughput += i->second.rxBytes * 8.0 / flowDuration / 1000 / 1000;
639 averageFlowDelay += 1000 * i->second.delaySum.GetSeconds() / i->second.rxPackets;
641 double throughput = i->second.rxBytes * 8.0 / flowDuration / 1000 / 1000;
642 double delay = 1000 * i->second.delaySum.GetSeconds() / i->second.rxPackets;
644 outFile <<
" Throughput: " << i->second.rxBytes * 8.0 / flowDuration / 1000 / 1000
646 outFile <<
" Mean delay: "
647 << 1000 * i->second.delaySum.GetSeconds() / i->second.rxPackets <<
" ms\n";
650 outFile <<
" Mean jitter: "
651 << 1000 * i->second.jitterSum.GetSeconds() / i->second.rxPackets <<
" ms\n";
653 if (enableQosTrafficTraces)
655 throughputFile << t.sourcePort <<
"\t" << t.destinationPort <<
"\t" << throughput
656 <<
"\t" << delay << std::endl;
661 outFile <<
" Throughput: 0 Mbps\n";
662 outFile <<
" Mean delay: 0 ms\n";
663 outFile <<
" Mean jitter: 0 ms\n";
665 if (enableQosTrafficTraces)
667 throughputFile << t.sourcePort <<
"\t" << t.destinationPort <<
"\t" << 0 <<
"\t"
671 outFile <<
" Rx Packets: " << i->second.rxPackets <<
"\n";
674 outFile <<
"\n\n Mean flow throughput: " << averageFlowThroughput / stats.size() <<
"\n";
675 outFile <<
" Mean flow delay: " << averageFlowDelay / stats.size() <<
"\n";
679 std::ifstream f(filename.c_str());
683 std::cout << f.rdbuf();
686 Simulator::Destroy();
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.
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.
@ ErrorModel
Error Model version (can use different error models, see NrErrorModel)
@ INIT_PROPAGATION
Initialize the propagation loss model.
This class contains the specification of EPS Bearers.
@ NGBR_LOW_LAT_EMBB
Non-GBR Low Latency eMBB applications.
@ DGBR_INTER_SERV_87
Delay-Critical GBR Interactive Service - Motion tracking data (TS 23.501)
static TypeId GetTypeId()
Get the type ID.
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.
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.