5#include "ns3/antenna-module.h"
6#include "ns3/applications-module.h"
7#include "ns3/boolean.h"
8#include "ns3/config-store-module.h"
9#include "ns3/config-store.h"
10#include "ns3/core-module.h"
11#include "ns3/flow-monitor-module.h"
12#include "ns3/internet-apps-module.h"
13#include "ns3/internet-module.h"
14#include "ns3/mobility-module.h"
15#include "ns3/nr-gnb-rrc.h"
16#include "ns3/nr-module.h"
17#include "ns3/packet-sink.h"
18#include "ns3/point-to-point-module.h"
19#include "ns3/xr-traffic-mixer-helper.h"
39NS_LOG_COMPONENT_DEFINE(
"CttcNrTraffic3gppXr");
42ConfigureXrApp(NodeContainer& ueContainer,
44 Ipv4InterfaceContainer& ueIpIface,
45 enum NrXrConfig config,
49 std::string transportProtocol,
50 NodeContainer& remoteHostContainer,
51 NetDeviceContainer& ueNetDev,
52 Ptr<NrHelper> nrHelper,
56 std::vector<Ptr<NrEpcTft>>& tfts,
57 ApplicationContainer& serverApps,
58 ApplicationContainer& clientApps,
59 ApplicationContainer& pingApps)
62 Ipv4Address ipAddress = ueIpIface.GetAddress(i, 0);
63 trafficMixerHelper.ConfigureXr(config);
64 auto it = XrPreconfig.find(config);
66 std::vector<Address> addresses;
67 std::vector<InetSocketAddress> localAddresses;
68 for (
size_t j = 0; j < it->second.size(); j++)
70 addresses.emplace_back(InetSocketAddress(ipAddress, port + j));
72 localAddresses.emplace_back(Ipv4Address::GetAny(), port + j);
75 ApplicationContainer currentUeClientApps;
76 currentUeClientApps.Add(
77 trafficMixerHelper.Install(transportProtocol, addresses, remoteHostContainer.Get(0)));
81 PingHelper ping(ipAddress);
82 pingApps.Add(ping.Install(remoteHostContainer));
84 Ptr<NetDevice> ueDevice = ueNetDev.Get(i);
86 nrHelper->ActivateDedicatedEpsBearer(ueDevice, bearer, tft);
90 nrHelper->ActivateDedicatedEpsBearer(ueDevice, bearer, tft);
94 NS_ASSERT(tfts.size() >= currentUeClientApps.GetN());
95 for (uint32_t j = 0; j < currentUeClientApps.GetN(); j++)
97 nrHelper->ActivateDedicatedEpsBearer(ueDevice, bearer, tfts[j]);
101 for (uint32_t j = 0; j < currentUeClientApps.GetN(); j++)
103 PacketSinkHelper dlPacketSinkHelper(transportProtocol, localAddresses.at(j));
104 Ptr<Application> packetSink = dlPacketSinkHelper.Install(ueContainer.Get(i)).Get(0);
105 serverApps.Add(packetSink);
106 Ptr<TrafficGenerator3gppGenericVideo> app =
107 DynamicCast<TrafficGenerator3gppGenericVideo>(currentUeClientApps.Get(j));
110 app->SetAttribute(
"DataRate", DoubleValue(appDataRate));
111 app->SetAttribute(
"Fps", UintegerValue(appFps));
114 clientApps.Add(currentUeClientApps);
118main(
int argc,
char* argv[])
121 uint32_t appDuration = 10000;
122 uint32_t appStartTimeMs = 400;
123 uint16_t numerology = 0;
124 uint16_t arUeNum = 1;
125 uint16_t vrUeNum = 1;
126 uint16_t cgUeNum = 1;
127 double centralFrequency = 4e9;
128 double bandwidth = 10e6;
132 double arDataRate = 5;
133 double vrDataRate = 30;
134 double cgDataRate = 20;
140 CommandLine cmd(__FILE__);
141 cmd.AddValue(
"arUeNum",
"The number of AR UEs", arUeNum);
142 cmd.AddValue(
"vrUeNum",
"The number of VR UEs", vrUeNum);
143 cmd.AddValue(
"cgUeNum",
"The number of CG UEs", cgUeNum);
144 cmd.AddValue(
"arDataRate",
"The Datarate for AR UEs", arDataRate);
145 cmd.AddValue(
"vrDataRate",
"The Datarate for vR UEs", vrDataRate);
146 cmd.AddValue(
"cgDataRate",
"The Datarate for cg UEs", cgDataRate);
147 cmd.AddValue(
"arFps",
"The fps for AR UEs", arFps);
148 cmd.AddValue(
"vrFps",
"The fps for vR UEs", vrFps);
149 cmd.AddValue(
"cgFps",
"The fps for cg UEs", cgFps);
150 cmd.AddValue(
"numerology",
"The numerology to be used.", numerology);
151 cmd.AddValue(
"txPower",
"Tx power to be configured to gNB", txPower);
152 cmd.AddValue(
"frequency",
"The system frequency", centralFrequency);
153 cmd.AddValue(
"bandwidth",
"The system bandwidth", bandwidth);
154 cmd.AddValue(
"useUdp",
155 "if true, the NGMN applications will run over UDP connection, otherwise a TCP "
156 "connection will be used.",
158 cmd.AddValue(
"isMx1",
159 "if true M SDFs will be mapped to 1 DRB, otherwise the mapping will "
160 "be 1x1, i.e., 1 SDF to 1 DRB.",
162 cmd.AddValue(
"rngRun",
"Rng run random number.", rngRun);
163 cmd.AddValue(
"appDuration",
"Duration of the application in milliseconds.", appDuration);
164 cmd.Parse(argc, argv);
166 NS_ABORT_MSG_IF(appDuration < 1000,
"The appDuration should be at least 1000ms.");
168 !vrUeNum && !arUeNum && !cgUeNum,
169 "Activate at least one type of XR traffic by configuring the number of XR users");
171 uint32_t simTimeMs = appStartTimeMs + appDuration + 2000;
174 SeedManager::SetRun(rngRun);
177 Ptr<NrHelper> nrHelper = CreateObject<NrHelper>();
178 Ptr<NrChannelHelper> channelHelper = CreateObject<NrChannelHelper>();
180 channelHelper->ConfigureFactories(
"UMa",
"LOS",
"ThreeGpp");
187 channelHelper->AssignChannelsToBands({band});
190 nrHelper->SetGnbPhyAttribute(
"TxPower", DoubleValue(txPower));
191 nrHelper->SetGnbPhyAttribute(
"Numerology", UintegerValue(numerology));
192 nrHelper->SetGnbPhyAttribute(
"NoiseFigure", DoubleValue(5));
193 nrHelper->SetUePhyAttribute(
"TxPower", DoubleValue(23));
194 nrHelper->SetUePhyAttribute(
"NoiseFigure", DoubleValue(7));
196 Config::SetDefault(
"ns3::NrRlcUm::MaxTxBufferSize", UintegerValue(999999999));
197 Config::SetDefault(
"ns3::NrGnbRrc::EpsBearerToRlcMapping",
198 EnumValue(useUdp ? NrGnbRrc::RLC_UM_ALWAYS :
NrGnbRrc::RLC_AM_ALWAYS));
200 nrHelper->SetGnbAntennaAttribute(
"NumRows", UintegerValue(4));
201 nrHelper->SetGnbAntennaAttribute(
"NumColumns", UintegerValue(8));
202 nrHelper->SetGnbAntennaAttribute(
"AntennaElement",
203 PointerValue(CreateObject<ThreeGppAntennaModel>()));
204 nrHelper->SetGnbAntennaAttribute(
"AntennaHorizontalSpacing", DoubleValue(0.5));
205 nrHelper->SetGnbAntennaAttribute(
"AntennaVerticalSpacing", DoubleValue(0.8));
206 nrHelper->SetGnbAntennaAttribute(
"DowntiltAngle", DoubleValue(0 * M_PI / 180.0));
207 nrHelper->SetUeAntennaAttribute(
"NumRows", UintegerValue(1));
208 nrHelper->SetUeAntennaAttribute(
"NumColumns", UintegerValue(1));
209 nrHelper->SetUeAntennaAttribute(
"AntennaElement",
210 PointerValue(CreateObject<IsotropicAntennaModel>()));
213 Ptr<IdealBeamformingHelper> idealBeamformingHelper = CreateObject<IdealBeamformingHelper>();
214 idealBeamformingHelper->SetAttribute(
"BeamformingMethod",
216 nrHelper->SetBeamformingHelper(idealBeamformingHelper);
218 Ptr<NrPointToPointEpcHelper> nrEpcHelper = CreateObject<NrPointToPointEpcHelper>();
219 nrHelper->SetEpcHelper(nrEpcHelper);
220 nrEpcHelper->SetAttribute(
"S1uLinkDelay", TimeValue(MilliSeconds(0)));
222 NodeContainer gNbNodes;
223 NodeContainer ueNodes;
224 MobilityHelper mobility;
225 mobility.SetMobilityModel(
"ns3::ConstantPositionMobilityModel");
227 const double gNbHeight = 25;
228 const double ueHeight = 1.5;
231 ueNodes.Create(arUeNum + vrUeNum + cgUeNum);
233 Ptr<ListPositionAllocator> bsPositionAlloc = CreateObject<ListPositionAllocator>();
234 bsPositionAlloc->Add(Vector(0.0, 0.0, gNbHeight));
235 mobility.SetPositionAllocator(bsPositionAlloc);
236 mobility.Install(gNbNodes);
238 Ptr<RandomDiscPositionAllocator> ueDiscPositionAlloc =
239 CreateObject<RandomDiscPositionAllocator>();
240 ueDiscPositionAlloc->SetX(0.0);
241 ueDiscPositionAlloc->SetY(0.0);
242 ueDiscPositionAlloc->SetZ(ueHeight);
243 mobility.SetPositionAllocator(ueDiscPositionAlloc);
245 for (uint32_t i = 0; i < ueNodes.GetN(); i++)
247 mobility.Install(ueNodes.Get(i));
254 NodeContainer ueArContainer;
255 NodeContainer ueVrContainer;
256 NodeContainer ueCgContainer;
258 for (
auto j = 0; j < arUeNum; ++j)
260 Ptr<Node> ue = ueNodes.Get(j);
261 ueArContainer.Add(ue);
263 for (
auto j = arUeNum; j < arUeNum + vrUeNum; ++j)
265 Ptr<Node> ue = ueNodes.Get(j);
266 ueVrContainer.Add(ue);
268 for (
auto j = arUeNum + vrUeNum; j < arUeNum + vrUeNum + cgUeNum; ++j)
270 Ptr<Node> ue = ueNodes.Get(j);
271 ueCgContainer.Add(ue);
274 NetDeviceContainer gNbNetDev = nrHelper->InstallGnbDevice(gNbNodes, allBwps);
275 NetDeviceContainer ueArNetDev = nrHelper->InstallUeDevice(ueArContainer, allBwps);
276 NetDeviceContainer ueVrNetDev = nrHelper->InstallUeDevice(ueVrContainer, allBwps);
277 NetDeviceContainer ueCgNetDev = nrHelper->InstallUeDevice(ueCgContainer, allBwps);
279 int64_t randomStream = 1;
280 randomStream += nrHelper->AssignStreams(gNbNetDev, randomStream);
281 randomStream += nrHelper->AssignStreams(ueArNetDev, randomStream);
282 randomStream += nrHelper->AssignStreams(ueVrNetDev, randomStream);
283 randomStream += nrHelper->AssignStreams(ueCgNetDev, randomStream);
287 auto [remoteHost, remoteHostIpv4Address] =
288 nrEpcHelper->SetupRemoteHost(
"100Gb/s", 1000, Seconds(0.000));
289 auto remoteHostContainer = NodeContainer(remoteHost);
291 InternetStackHelper internet;
292 internet.Install(ueNodes);
294 Ipv4InterfaceContainer ueArIpIface;
295 Ipv4InterfaceContainer ueVrIpIface;
296 Ipv4InterfaceContainer ueCgIpIface;
298 ueArIpIface = nrEpcHelper->AssignUeIpv4Address(NetDeviceContainer(ueArNetDev));
299 ueVrIpIface = nrEpcHelper->AssignUeIpv4Address(NetDeviceContainer(ueVrNetDev));
300 ueCgIpIface = nrEpcHelper->AssignUeIpv4Address(NetDeviceContainer(ueCgNetDev));
303 nrHelper->AttachToClosestGnb(ueArNetDev, gNbNetDev);
304 nrHelper->AttachToClosestGnb(ueVrNetDev, gNbNetDev);
305 nrHelper->AttachToClosestGnb(ueCgNetDev, gNbNetDev);
308 ApplicationContainer serverApps;
311 std::string transportProtocol;
312 transportProtocol = useUdp ?
"ns3::UdpSocketFactory" :
"ns3::TcpSocketFactory";
313 uint16_t dlPortArStart = 1121;
314 uint16_t dlPortArStop = 1124;
315 uint16_t dlPortVrStart = 1131;
316 uint16_t dlPortCgStart = 1141;
320 Ptr<NrEpcTft> arTft = Create<NrEpcTft>();
322 std::vector<Ptr<NrEpcTft>> arTfts;
333 for (uint32_t i = 0; i < 3; i++)
335 Ptr<NrEpcTft> tempTft = Create<NrEpcTft>();
338 tempTft->Add(dlpfAr);
339 arTfts.emplace_back(tempTft);
345 Ptr<NrEpcTft> vrTft = Create<NrEpcTft>();
354 Ptr<NrEpcTft> cgTft = Create<NrEpcTft>();
361 ApplicationContainer clientApps;
362 ApplicationContainer pingApps;
364 std::ostringstream xrFileTag;
366 for (uint32_t i = 0; i < ueArContainer.GetN(); ++i)
368 ConfigureXrApp(ueArContainer,
389 for (uint32_t i = 0; i < ueVrContainer.GetN(); ++i)
391 ConfigureXrApp(ueVrContainer,
410 for (uint32_t i = 0; i < ueCgContainer.GetN(); ++i)
412 ConfigureXrApp(ueCgContainer,
432 pingApps.Start(MilliSeconds(100));
433 pingApps.Stop(MilliSeconds(appStartTimeMs));
436 serverApps.Start(MilliSeconds(appStartTimeMs));
437 clientApps.Start(MilliSeconds(appStartTimeMs));
438 serverApps.Stop(MilliSeconds(simTimeMs));
439 clientApps.Stop(MilliSeconds(appStartTimeMs + appDuration));
441 FlowMonitorHelper flowmonHelper;
442 NodeContainer endpointNodes;
443 endpointNodes.Add(remoteHost);
444 endpointNodes.Add(ueNodes);
446 Ptr<ns3::FlowMonitor> monitor = flowmonHelper.Install(endpointNodes);
447 monitor->SetAttribute(
"DelayBinWidth", DoubleValue(0.0001));
448 monitor->SetAttribute(
"JitterBinWidth", DoubleValue(0.001));
449 monitor->SetAttribute(
"PacketSizeBinWidth", DoubleValue(20));
451 Simulator::Stop(MilliSeconds(simTimeMs));
455 monitor->CheckForLostPackets();
456 Ptr<Ipv4FlowClassifier> classifier =
457 DynamicCast<Ipv4FlowClassifier>(flowmonHelper.GetClassifier());
458 FlowMonitor::FlowStatsContainer stats = monitor->GetFlowStats();
460 double averageFlowThroughput = 0.0;
461 double averageFlowDelay = 0.0;
463 for (std::map<FlowId, FlowMonitor::FlowStats>::const_iterator i = stats.begin();
467 Ipv4FlowClassifier::FiveTuple t = classifier->FindFlow(i->first);
468 std::stringstream protoStream;
469 protoStream << (uint16_t)t.protocol;
472 protoStream.str(
"TCP");
474 if (t.protocol == 17)
476 protoStream.str(
"UDP");
479 Time txDuration = MilliSeconds(appDuration);
480 std::cout <<
"Flow " << i->first <<
" (" << t.sourceAddress <<
":" << t.sourcePort <<
" -> "
481 << t.destinationAddress <<
":" << t.destinationPort <<
") proto "
482 << protoStream.str() <<
"\n";
483 std::cout <<
" Tx Packets: " << i->second.txPackets <<
"\n";
484 std::cout <<
" Tx Bytes: " << i->second.txBytes <<
"\n";
485 std::cout <<
" TxOffered: "
486 << ((i->second.txBytes * 8.0) / txDuration.GetSeconds()) * 1e-6 <<
" Mbps\n";
487 std::cout <<
" Rx Bytes: " << i->second.rxBytes <<
"\n";
489 if (i->second.rxPackets > 0)
492 Time rxDuration = i->second.timeLastRxPacket - i->second.timeFirstTxPacket;
493 averageFlowThroughput += ((i->second.rxBytes * 8.0) / rxDuration.GetSeconds()) * 1e-6;
494 averageFlowDelay += 1000 * i->second.delaySum.GetSeconds() / i->second.rxPackets;
496 double throughput = ((i->second.rxBytes * 8.0) / rxDuration.GetSeconds()) * 1e-6;
497 double delay = 1000 * i->second.delaySum.GetSeconds() / i->second.rxPackets;
498 double jitter = 1000 * i->second.jitterSum.GetSeconds() / i->second.rxPackets;
500 std::cout <<
" Throughput: " << throughput <<
" Mbps\n";
501 std::cout <<
" Mean delay: " << delay <<
" ms\n";
502 std::cout <<
" Mean jitter: " << jitter <<
" ms\n";
506 std::cout <<
" Throughput: 0 Mbps\n";
507 std::cout <<
" Mean delay: 0 ms\n";
508 std::cout <<
" Mean upt: 0 Mbps \n";
509 std::cout <<
" Mean jitter: 0 ms\n";
511 std::cout <<
" Rx Packets: " << i->second.rxPackets <<
"\n";
514 std::cout <<
"\n\n Mean flow throughput: " << averageFlowThroughput / stats.size()
516 std::cout <<
" Mean flow delay: " << averageFlowDelay / stats.size() <<
" ms\n";
518 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.
This class contains the specification of EPS Bearers.
@ NGBR_LOW_LAT_EMBB
Non-GBR Low Latency eMBB applications.
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.