28#include "ns3/antenna-module.h"
29#include "ns3/applications-module.h"
30#include "ns3/config-store-module.h"
31#include "ns3/config-store.h"
32#include "ns3/core-module.h"
33#include "ns3/flow-monitor-module.h"
34#include "ns3/internet-apps-module.h"
35#include "ns3/internet-module.h"
36#include "ns3/mobility-module.h"
37#include "ns3/nr-module.h"
38#include "ns3/point-to-point-module.h"
42NS_LOG_COMPONENT_DEFINE(
"3gppChannelNumsFdm");
45main(
int argc,
char* argv[])
50 uint32_t udpPacketSizeVideo = 100;
51 uint32_t udpPacketSizeVoice = 1252;
52 uint32_t udpPacketSizeGaming = 500;
53 uint32_t lambdaVideo = 50;
54 uint32_t lambdaVoice = 100;
55 uint32_t lambdaGaming = 250;
57 uint32_t simTimeMs = 1400;
58 uint32_t udpAppStartTimeMs = 400;
60 double centralFrequencyBand1 = 28e9;
61 double bandwidthBand1 = 100e6;
62 double centralFrequencyBand2 = 28.2e9;
63 double bandwidthBand2 = 100e6;
64 double totalTxPower = 4;
65 std::string simTag =
"default";
66 std::string outputDir =
"./";
67 bool enableVideo =
true;
68 bool enableVoice =
true;
69 bool enableGaming =
true;
71 CommandLine cmd(__FILE__);
73 cmd.AddValue(
"packetSizeVideo",
74 "packet size in bytes to be used by video traffic",
76 cmd.AddValue(
"packetSizeVoice",
77 "packet size in bytes to be used by voice traffic",
79 cmd.AddValue(
"packetSizeGaming",
80 "packet size in bytes to be used by gaming traffic",
82 cmd.AddValue(
"lambdaVideo",
83 "Number of UDP packets in one second for video traffic",
85 cmd.AddValue(
"lambdaVoice",
86 "Number of UDP packets in one second for voice traffic",
88 cmd.AddValue(
"lambdaGaming",
89 "Number of UDP packets in one second for gaming traffic",
91 cmd.AddValue(
"enableVideo",
"If true, enables video traffic transmission (DL)", enableVideo);
92 cmd.AddValue(
"enableVoice",
"If true, enables voice traffic transmission (DL)", enableVoice);
93 cmd.AddValue(
"enableGaming",
"If true, enables gaming traffic transmission (UL)", enableGaming);
94 cmd.AddValue(
"simTimeMs",
"Simulation time", simTimeMs);
95 cmd.AddValue(
"centralFrequencyBand1",
96 "The system frequency to be used in band 1",
97 centralFrequencyBand1);
98 cmd.AddValue(
"bandwidthBand1",
"The system bandwidth to be used in band 1", bandwidthBand1);
99 cmd.AddValue(
"centralFrequencyBand2",
100 "The system frequency to be used in band 2",
101 centralFrequencyBand2);
102 cmd.AddValue(
"bandwidthBand2",
"The system bandwidth to be used in band 2", bandwidthBand2);
103 cmd.AddValue(
"totalTxPower",
104 "total tx power that will be proportionally assigned to"
105 " bands, CCs and bandwidth parts depending on each BWP bandwidth ",
107 cmd.AddValue(
"simTag",
108 "tag to be appended to output filenames to distinguish simulation campaigns",
110 cmd.AddValue(
"outputDir",
"directory where to store simulation results", outputDir);
112 cmd.Parse(argc, argv);
114 NS_ABORT_IF(centralFrequencyBand1 > 100e9);
115 NS_ABORT_IF(centralFrequencyBand2 > 100e9);
117 Config::SetDefault(
"ns3::NrRlcUm::MaxTxBufferSize", UintegerValue(999999999));
119 int64_t randomStream = 1;
122 gridScenario.
SetRows(gNbNum / 2);
131 gridScenario.SetScenarioHeight(3);
132 gridScenario.SetScenarioLength(3);
139 Ptr<NrPointToPointEpcHelper> nrEpcHelper = CreateObject<NrPointToPointEpcHelper>();
140 Ptr<IdealBeamformingHelper> idealBeamformingHelper = CreateObject<IdealBeamformingHelper>();
141 Ptr<NrHelper> nrHelper = CreateObject<NrHelper>();
142 Ptr<NrChannelHelper> channelHelper = CreateObject<NrChannelHelper>();
145 nrHelper->SetBeamformingHelper(idealBeamformingHelper);
146 nrHelper->SetEpcHelper(nrEpcHelper);
148 channelHelper->ConfigureFactories(
"UMi",
"Default",
"ThreeGpp");
149 Config::SetDefault(
"ns3::ThreeGppChannelModel::UpdatePeriod", TimeValue(MilliSeconds(0)));
150 channelHelper->SetChannelConditionModelAttribute(
"UpdatePeriod", TimeValue(MilliSeconds(0)));
151 channelHelper->SetPathlossAttribute(
"ShadowingEnabled", BooleanValue(
false));
155 const uint8_t numCcPerBand = 1;
165 bandConfFdd.m_numBwp = 2;
171 channelHelper->AssignChannelsToBands({bandTdd, bandFdd});
183 idealBeamformingHelper->SetAttribute(
"BeamformingMethod",
187 nrEpcHelper->SetAttribute(
"S1uLinkDelay", TimeValue(MilliSeconds(0)));
190 nrHelper->SetUeAntennaAttribute(
"NumRows", UintegerValue(2));
191 nrHelper->SetUeAntennaAttribute(
"NumColumns", UintegerValue(4));
192 nrHelper->SetUeAntennaAttribute(
"AntennaElement",
193 PointerValue(CreateObject<IsotropicAntennaModel>()));
196 nrHelper->SetGnbAntennaAttribute(
"NumRows", UintegerValue(4));
197 nrHelper->SetGnbAntennaAttribute(
"NumColumns", UintegerValue(8));
198 nrHelper->SetGnbAntennaAttribute(
"AntennaElement",
199 PointerValue(CreateObject<IsotropicAntennaModel>()));
201 nrHelper->SetGnbPhyAttribute(
"TxPower", DoubleValue(4.0));
203 uint32_t bwpIdForVoice = 0;
204 uint32_t bwpIdForVideo = 1;
205 uint32_t bwpIdForGaming = 2;
207 nrHelper->SetGnbBwpManagerAlgorithmAttribute(
"GBR_CONV_VOICE", UintegerValue(bwpIdForVoice));
208 nrHelper->SetGnbBwpManagerAlgorithmAttribute(
"GBR_CONV_VIDEO", UintegerValue(bwpIdForVideo));
209 nrHelper->SetGnbBwpManagerAlgorithmAttribute(
"GBR_GAMING", UintegerValue(bwpIdForGaming));
211 nrHelper->SetUeBwpManagerAlgorithmAttribute(
"GBR_CONV_VOICE", UintegerValue(bwpIdForVoice));
212 nrHelper->SetUeBwpManagerAlgorithmAttribute(
"GBR_CONV_VIDEO", UintegerValue(bwpIdForVideo));
213 nrHelper->SetUeBwpManagerAlgorithmAttribute(
"GBR_GAMING", UintegerValue(bwpIdForGaming));
215 NetDeviceContainer gnbNetDev =
217 NetDeviceContainer ueNetDev =
220 randomStream += nrHelper->AssignStreams(gnbNetDev, randomStream);
221 randomStream += nrHelper->AssignStreams(ueNetDev, randomStream);
223 NS_ASSERT(gnbNetDev.GetN() == 4);
228 nrHelper->GetGnbPhy(gnbNetDev.Get(0), 0)->SetAttribute(
"Numerology", UintegerValue(0));
229 nrHelper->GetGnbPhy(gnbNetDev.Get(0), 0)
230 ->SetAttribute(
"Pattern", StringValue(
"F|F|F|F|F|F|F|F|F|F|"));
231 nrHelper->GetGnbPhy(gnbNetDev.Get(0), 0)->SetAttribute(
"TxPower", DoubleValue(4.0));
234 nrHelper->GetGnbPhy(gnbNetDev.Get(0), 1)->SetAttribute(
"Numerology", UintegerValue(0));
235 nrHelper->GetGnbPhy(gnbNetDev.Get(0), 1)
236 ->SetAttribute(
"Pattern", StringValue(
"DL|DL|DL|DL|DL|DL|DL|DL|DL|DL|"));
237 nrHelper->GetGnbPhy(gnbNetDev.Get(0), 1)->SetAttribute(
"TxPower", DoubleValue(4.0));
240 nrHelper->GetGnbPhy(gnbNetDev.Get(0), 2)->SetAttribute(
"Numerology", UintegerValue(0));
241 nrHelper->GetGnbPhy(gnbNetDev.Get(0), 2)
242 ->SetAttribute(
"Pattern", StringValue(
"UL|UL|UL|UL|UL|UL|UL|UL|UL|UL|"));
243 nrHelper->GetGnbPhy(gnbNetDev.Get(0), 2)->SetAttribute(
"TxPower", DoubleValue(0.0));
246 nrHelper->GetBwpManagerGnb(gnbNetDev.Get(0))->SetOutputLink(2, 1);
251 nrHelper->GetGnbPhy(gnbNetDev.Get(1), 0)->SetAttribute(
"Numerology", UintegerValue(1));
252 nrHelper->GetGnbPhy(gnbNetDev.Get(1), 0)
253 ->SetAttribute(
"Pattern", StringValue(
"F|F|F|F|F|F|F|F|F|F|"));
254 nrHelper->GetGnbPhy(gnbNetDev.Get(1), 0)->SetAttribute(
"TxPower", DoubleValue(4.0));
257 nrHelper->GetGnbPhy(gnbNetDev.Get(1), 1)->SetAttribute(
"Numerology", UintegerValue(1));
258 nrHelper->GetGnbPhy(gnbNetDev.Get(1), 1)
259 ->SetAttribute(
"Pattern", StringValue(
"DL|DL|DL|DL|DL|DL|DL|DL|DL|DL|"));
260 nrHelper->GetGnbPhy(gnbNetDev.Get(1), 1)->SetAttribute(
"TxPower", DoubleValue(4.0));
263 nrHelper->GetGnbPhy(gnbNetDev.Get(1), 2)->SetAttribute(
"Numerology", UintegerValue(1));
264 nrHelper->GetGnbPhy(gnbNetDev.Get(1), 2)
265 ->SetAttribute(
"Pattern", StringValue(
"UL|UL|UL|UL|UL|UL|UL|UL|UL|UL|"));
266 nrHelper->GetGnbPhy(gnbNetDev.Get(1), 2)->SetAttribute(
"TxPower", DoubleValue(0.0));
269 nrHelper->GetBwpManagerGnb(gnbNetDev.Get(1))->SetOutputLink(2, 1);
274 nrHelper->GetGnbPhy(gnbNetDev.Get(2), 0)->SetAttribute(
"Numerology", UintegerValue(2));
275 nrHelper->GetGnbPhy(gnbNetDev.Get(2), 0)
276 ->SetAttribute(
"Pattern", StringValue(
"F|F|F|F|F|F|F|F|F|F|"));
277 nrHelper->GetGnbPhy(gnbNetDev.Get(2), 0)->SetAttribute(
"TxPower", DoubleValue(4.0));
280 nrHelper->GetGnbPhy(gnbNetDev.Get(2), 1)->SetAttribute(
"Numerology", UintegerValue(2));
281 nrHelper->GetGnbPhy(gnbNetDev.Get(2), 1)
282 ->SetAttribute(
"Pattern", StringValue(
"DL|DL|DL|DL|DL|DL|DL|DL|DL|DL|"));
283 nrHelper->GetGnbPhy(gnbNetDev.Get(2), 1)->SetAttribute(
"TxPower", DoubleValue(4.0));
286 nrHelper->GetGnbPhy(gnbNetDev.Get(2), 2)->SetAttribute(
"Numerology", UintegerValue(2));
287 nrHelper->GetGnbPhy(gnbNetDev.Get(2), 2)
288 ->SetAttribute(
"Pattern", StringValue(
"UL|UL|UL|UL|UL|UL|UL|UL|UL|UL|"));
289 nrHelper->GetGnbPhy(gnbNetDev.Get(2), 2)->SetAttribute(
"TxPower", DoubleValue(0.0));
292 nrHelper->GetBwpManagerGnb(gnbNetDev.Get(2))->SetOutputLink(2, 1);
297 nrHelper->GetGnbPhy(gnbNetDev.Get(3), 0)->SetAttribute(
"Numerology", UintegerValue(3));
298 nrHelper->GetGnbPhy(gnbNetDev.Get(3), 0)
299 ->SetAttribute(
"Pattern", StringValue(
"F|F|F|F|F|F|F|F|F|F|"));
300 nrHelper->GetGnbPhy(gnbNetDev.Get(3), 0)->SetAttribute(
"TxPower", DoubleValue(4.0));
303 nrHelper->GetGnbPhy(gnbNetDev.Get(3), 1)->SetAttribute(
"Numerology", UintegerValue(3));
304 nrHelper->GetGnbPhy(gnbNetDev.Get(3), 1)
305 ->SetAttribute(
"Pattern", StringValue(
"DL|DL|DL|DL|DL|DL|DL|DL|DL|DL|"));
306 nrHelper->GetGnbPhy(gnbNetDev.Get(3), 1)->SetAttribute(
"TxPower", DoubleValue(4.0));
309 nrHelper->GetGnbPhy(gnbNetDev.Get(3), 2)->SetAttribute(
"Numerology", UintegerValue(3));
310 nrHelper->GetGnbPhy(gnbNetDev.Get(3), 2)
311 ->SetAttribute(
"Pattern", StringValue(
"UL|UL|UL|UL|UL|UL|UL|UL|UL|UL|"));
312 nrHelper->GetGnbPhy(gnbNetDev.Get(3), 2)->SetAttribute(
"TxPower", DoubleValue(0.0));
315 nrHelper->GetBwpManagerGnb(gnbNetDev.Get(3))->SetOutputLink(2, 1);
319 for (uint32_t i = 0; i < ueNetDev.GetN(); i++)
321 nrHelper->GetBwpManagerUe(ueNetDev.Get(i))->SetOutputLink(1, 2);
327 auto [remoteHost, remoteHostIpv4Address] =
328 nrEpcHelper->SetupRemoteHost(
"100Gb/s", 2500, Seconds(0.000));
330 InternetStackHelper internet;
334 Ipv4InterfaceContainer ueIpIface =
335 nrEpcHelper->AssignUeIpv4Address(NetDeviceContainer(ueNetDev));
338 for (uint32_t i = 0; i < ueNetDev.GetN(); ++i)
340 auto gnbDev = DynamicCast<NrGnbNetDevice>(gnbNetDev.Get(i));
341 auto ueDev = DynamicCast<NrUeNetDevice>(ueNetDev.Get(i));
342 NS_ASSERT(gnbDev !=
nullptr);
343 NS_ASSERT(ueDev !=
nullptr);
344 nrHelper->AttachToGnb(ueDev, gnbDev);
351 uint16_t dlPortVideo = 1234;
352 uint16_t dlPortVoice = 1235;
353 uint16_t ulPortGaming = 1236;
355 ApplicationContainer serverApps;
358 UdpServerHelper dlPacketSinkVideo(dlPortVideo);
359 UdpServerHelper dlPacketSinkVoice(dlPortVoice);
360 UdpServerHelper ulPacketSinkVoice(ulPortGaming);
366 serverApps.Add(ulPacketSinkVoice.Install(remoteHost));
374 UdpClientHelper dlClientVideo;
375 dlClientVideo.SetAttribute(
"RemotePort", UintegerValue(dlPortVideo));
376 dlClientVideo.SetAttribute(
"MaxPackets", UintegerValue(0xFFFFFFFF));
377 dlClientVideo.SetAttribute(
"PacketSize", UintegerValue(udpPacketSizeVideo));
378 dlClientVideo.SetAttribute(
"Interval", TimeValue(Seconds(1.0 / lambdaVideo)));
384 Ptr<NrEpcTft> videoTft = Create<NrEpcTft>();
388 videoTft->Add(dlpfVideo);
391 UdpClientHelper dlClientVoice;
392 dlClientVoice.SetAttribute(
"RemotePort", UintegerValue(dlPortVoice));
393 dlClientVoice.SetAttribute(
"MaxPackets", UintegerValue(0xFFFFFFFF));
394 dlClientVoice.SetAttribute(
"PacketSize", UintegerValue(udpPacketSizeVoice));
395 dlClientVoice.SetAttribute(
"Interval", TimeValue(Seconds(1.0 / lambdaVoice)));
401 Ptr<NrEpcTft> voiceTft = Create<NrEpcTft>();
405 voiceTft->Add(dlpfVoice);
408 UdpClientHelper ulClientGaming;
409 ulClientGaming.SetAttribute(
"RemotePort", UintegerValue(ulPortGaming));
410 ulClientGaming.SetAttribute(
"MaxPackets", UintegerValue(0xFFFFFFFF));
411 ulClientGaming.SetAttribute(
"PacketSize", UintegerValue(udpPacketSizeGaming));
412 ulClientGaming.SetAttribute(
"Interval", TimeValue(Seconds(1.0 / lambdaGaming)));
418 Ptr<NrEpcTft> gamingTft = Create<NrEpcTft>();
423 gamingTft->Add(ulpfGaming);
428 ApplicationContainer clientApps;
433 Ptr<NetDevice> ueDevice = ueNetDev.Get(i);
434 Address ueAddress = ueIpIface.GetAddress(i);
440 dlClientVoice.SetAttribute(
"RemoteAddress", AddressValue(ueAddress));
441 clientApps.Add(dlClientVoice.Install(remoteHost));
443 nrHelper->ActivateDedicatedEpsBearer(ueDevice, voiceBearer, voiceTft);
448 dlClientVideo.SetAttribute(
"RemoteAddress", AddressValue(ueAddress));
449 clientApps.Add(dlClientVideo.Install(remoteHost));
451 nrHelper->ActivateDedicatedEpsBearer(ueDevice, videoBearer, videoTft);
459 ulClientGaming.SetAttribute(
"RemoteAddress", AddressValue(remoteHostIpv4Address));
460 clientApps.Add(ulClientGaming.Install(ue));
462 nrHelper->ActivateDedicatedEpsBearer(ueDevice, gamingBearer, gamingTft);
467 serverApps.Start(MilliSeconds(udpAppStartTimeMs));
468 clientApps.Start(MilliSeconds(udpAppStartTimeMs));
469 serverApps.Stop(MilliSeconds(simTimeMs));
470 clientApps.Stop(MilliSeconds(simTimeMs));
475 FlowMonitorHelper flowmonHelper;
476 NodeContainer endpointNodes;
477 endpointNodes.Add(remoteHost);
480 Ptr<ns3::FlowMonitor> monitor = flowmonHelper.Install(endpointNodes);
481 monitor->SetAttribute(
"DelayBinWidth", DoubleValue(0.001));
482 monitor->SetAttribute(
"JitterBinWidth", DoubleValue(0.001));
483 monitor->SetAttribute(
"PacketSizeBinWidth", DoubleValue(20));
485 Simulator::Stop(MilliSeconds(simTimeMs));
496 monitor->CheckForLostPackets();
497 Ptr<Ipv4FlowClassifier> classifier =
498 DynamicCast<Ipv4FlowClassifier>(flowmonHelper.GetClassifier());
499 FlowMonitor::FlowStatsContainer stats = monitor->GetFlowStats();
501 double averageFlowThroughput = 0.0;
502 double averageFlowDelay = 0.0;
504 std::ofstream outFile;
505 std::string filename = outputDir +
"/" + simTag;
506 outFile.open(filename.c_str(), std::ofstream::out | std::ofstream::trunc);
507 if (!outFile.is_open())
509 std::cerr <<
"Can't open file " << filename << std::endl;
513 outFile.setf(std::ios_base::fixed);
515 for (std::map<FlowId, FlowMonitor::FlowStats>::const_iterator i = stats.begin();
519 Ipv4FlowClassifier::FiveTuple t = classifier->FindFlow(i->first);
520 std::stringstream protoStream;
521 protoStream << (uint16_t)t.protocol;
524 protoStream.str(
"TCP");
526 if (t.protocol == 17)
528 protoStream.str(
"UDP");
530 outFile <<
"Flow " << i->first <<
" (" << t.sourceAddress <<
":" << t.sourcePort <<
" -> "
531 << t.destinationAddress <<
":" << t.destinationPort <<
") proto "
532 << protoStream.str() <<
"\n";
533 outFile <<
" Tx Packets: " << i->second.txPackets <<
"\n";
534 outFile <<
" Tx Bytes: " << i->second.txBytes <<
"\n";
535 outFile <<
" TxOffered: "
536 << i->second.txBytes * 8.0 / ((simTimeMs - udpAppStartTimeMs) / 1000.0) / 1000.0 /
539 outFile <<
" Rx Bytes: " << i->second.rxBytes <<
"\n";
540 if (i->second.rxPackets > 0)
545 double rxDuration = (simTimeMs - udpAppStartTimeMs) / 1000.0;
547 averageFlowThroughput += i->second.rxBytes * 8.0 / rxDuration / 1000 / 1000;
548 averageFlowDelay += 1000 * i->second.delaySum.GetSeconds() / i->second.rxPackets;
550 outFile <<
" Throughput: " << i->second.rxBytes * 8.0 / rxDuration / 1000 / 1000
552 outFile <<
" Mean delay: "
553 << 1000 * i->second.delaySum.GetSeconds() / i->second.rxPackets <<
" ms\n";
556 outFile <<
" Mean jitter: "
557 << 1000 * i->second.jitterSum.GetSeconds() / i->second.rxPackets <<
" ms\n";
561 outFile <<
" Throughput: 0 Mbps\n";
562 outFile <<
" Mean delay: 0 ms\n";
563 outFile <<
" Mean jitter: 0 ms\n";
565 outFile <<
" Rx Packets: " << i->second.rxPackets <<
"\n";
568 double meanFlowThroughput = averageFlowThroughput / stats.size();
569 double meanFlowDelay = averageFlowDelay / stats.size();
570 double throughputTolerance = meanFlowThroughput * 0.001;
572 outFile <<
"\n\n Mean flow throughput: " << meanFlowThroughput <<
"\n";
573 outFile <<
" Mean flow delay: " << meanFlowDelay <<
"\n";
577 std::ifstream f(filename.c_str());
581 std::cout << f.rdbuf();
584 Simulator::Destroy();
587 if (argc == 0 && (meanFlowThroughput < 0.709696 - throughputTolerance ||
588 meanFlowThroughput > 0.709696 + throughputTolerance))
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 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.
@ GBR_CONV_VOICE
GBR Conversational Voice.
@ GBR_GAMING
GBR Real Time Gaming.
@ GBR_CONV_VIDEO
GBR Conversational Video (Live streaming)
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.
uint16_t remotePortEnd
end of the port number range of the remote host
uint16_t localPortStart
start of the port number range of the UE
uint16_t remotePortStart
start of the port number range of the remote host
uint16_t localPortEnd
end of the port number range of the UE
Operation band information structure.