5G-LENA nr-v4.0-29-g6d8085cd
The 5G/NR module for the ns-3 simulator
Loading...
Searching...
No Matches
system-scheduler-test-qos.cc
1// Copyright (c) 2022 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
2//
3// SPDX-License-Identifier: GPL-2.0-only
4
6
7#include "ns3/antenna-module.h"
8#include "ns3/applications-module.h"
9#include "ns3/config.h"
10#include "ns3/internet-module.h"
11#include "ns3/nr-module.h"
12#include "ns3/packet.h"
13#include "ns3/point-to-point-helper.h"
14#include "ns3/pointer.h"
15#include "ns3/simulator.h"
16#include "ns3/uinteger.h"
17
18namespace ns3
19{
20
22 uint32_t numerology,
23 double bw1,
24 bool isDownlnk,
25 bool isUplink,
26 double p1,
27 double p2,
28 uint32_t priorityTrafficScenario,
29 const std::string& schedulerType)
30 : TestCase("QoS Scheduler Test Case")
31{
32 m_ueNumPergNb = ueNumPergNb;
33 m_numerology = numerology;
34 m_bw1 = bw1;
35 m_isDownlink = isDownlnk;
36 m_isUplink = isUplink;
37 m_p1 = p1;
38 m_p2 = p2;
39 m_priorityTrafficScenario = priorityTrafficScenario;
40 m_schedulerType = schedulerType;
41}
42
43// This destructor does nothing but we include it as a reminder that
44// the test case should clean up after itself
48
49void
50SystemSchedulerTestQos::DoRun()
51{
52 NS_ABORT_IF(!m_isUplink && !m_isDownlink);
53
54 // set simulation time and mobility
55 Time simTime = MilliSeconds(1500);
56 Time udpAppStartTimeDl = MilliSeconds(500);
57 Time udpAppStartTimeUl = MilliSeconds(500);
58 Time udpAppStopTimeDl = MilliSeconds(1500); // Let's give 1s to end the tx
59 Time udpAppStopTimeUl = MilliSeconds(1500); // Let's give 1 to end the tx
60 uint16_t gNbNum = 1;
61
62 Config::SetDefault("ns3::NrRlcUm::MaxTxBufferSize", UintegerValue(999999999));
63 Config::SetDefault("ns3::NrRlcUm::ReorderingTimer", TimeValue(Seconds(1)));
64 Config::SetDefault("ns3::NrEpsBearer::Release", UintegerValue(15));
65
66 // create base stations and mobile terminals
67 int64_t randomStream = 1;
68
69 GridScenarioHelper gridScenario;
70 gridScenario.SetRows(1);
71 gridScenario.SetColumns(gNbNum);
72 gridScenario.SetHorizontalBsDistance(5.0);
73 gridScenario.SetVerticalBsDistance(5.0);
74 gridScenario.SetBsHeight(1.5);
75 gridScenario.SetUtHeight(1.5);
76 // must be set before BS number
78 gridScenario.SetBsNumber(gNbNum);
79 gridScenario.SetUtNumber(m_ueNumPergNb * gNbNum);
80 gridScenario.SetScenarioHeight(3); // Create a 3x3 scenario where the UE will
81 gridScenario.SetScenarioLength(3); // be distributed.
82 randomStream += gridScenario.AssignStreams(randomStream);
83 gridScenario.CreateScenario();
84
85 if (verbose)
86 {
87 std::cout << "Test case: Scheduler type: " << m_schedulerType
88 << " numerology: " << m_numerology << " BW: " << m_bw1 << " DL: " << m_isDownlink
89 << " UL: " << m_isUplink << " number of UEs: " << m_ueNumPergNb << std::endl;
90 }
91
92 uint32_t udpPacketSizeULL = 3000; // m_priorityTrafficScenario == 0 //saturation
93 uint32_t udpPacketSizeBe = 3000;
94 uint32_t lambdaULL = 1000;
95 uint32_t lambdaBe = 1000;
96
97 if (m_priorityTrafficScenario == 1) // medium-load
98 {
99 udpPacketSizeBe = 1252;
100 }
101
102 NodeContainer ueLowLatContainer;
103 NodeContainer ueVoiceContainer;
104
105 for (uint32_t j = 0; j < gridScenario.GetUserTerminals().GetN(); ++j)
106 {
107 Ptr<Node> ue = gridScenario.GetUserTerminals().Get(j);
108 j % 2 == 0 ? ueLowLatContainer.Add(ue) : ueVoiceContainer.Add(ue);
109 }
110
111 if (m_priorityTrafficScenario == 1)
112 {
113 lambdaULL = 1000 / ueLowLatContainer.GetN();
114 lambdaBe = 1000 / ueVoiceContainer.GetN();
115 }
116
117 // setup the nr simulation
118 Ptr<NrPointToPointEpcHelper> nrEpcHelper = CreateObject<NrPointToPointEpcHelper>();
119 Ptr<IdealBeamformingHelper> idealBeamformingHelper = CreateObject<IdealBeamformingHelper>();
120 Ptr<NrHelper> nrHelper = CreateObject<NrHelper>();
121 Ptr<NrChannelHelper> channelHelper = CreateObject<NrChannelHelper>();
122 channelHelper->ConfigureFactories("UMi", "LOS");
123 Config::SetDefault("ns3::ThreeGppChannelModel::UpdatePeriod", TimeValue(MilliSeconds(0)));
124 channelHelper->SetPathlossAttribute("ShadowingEnabled", BooleanValue(false));
125
126 // Put the pointers inside nrHelper
127 nrHelper->SetBeamformingHelper(idealBeamformingHelper);
128 nrHelper->SetEpcHelper(nrEpcHelper);
129 nrEpcHelper->SetAttribute("S1uLinkDelay", TimeValue(MilliSeconds(0)));
130
131 // Set the scheduler type
132 nrHelper->SetSchedulerTypeId(TypeId::LookupByName(m_schedulerType));
133
134 uint16_t mcsTable = 2;
135 // Error Model: gNB and UE with same spectrum error model.
136 std::string errorModel = "ns3::NrEesmIrT" + std::to_string(mcsTable);
137 nrHelper->SetDlErrorModel(errorModel);
138 nrHelper->SetUlErrorModel(errorModel);
139
140 // Both DL and UL AMC will have the same model behind.
141 nrHelper->SetGnbDlAmcAttribute("AmcModel", EnumValue(NrAmc::ErrorModel));
142 nrHelper->SetGnbUlAmcAttribute("AmcModel", EnumValue(NrAmc::ErrorModel));
143
144 // Beamforming method
145 idealBeamformingHelper->SetAttribute("BeamformingMethod",
146 TypeIdValue(DirectPathBeamforming::GetTypeId()));
147
148 // set the number of antenna elements of UE
149 nrHelper->SetUeAntennaAttribute("NumRows", UintegerValue(1));
150 nrHelper->SetUeAntennaAttribute("NumColumns", UintegerValue(1));
151 nrHelper->SetUeAntennaAttribute("AntennaElement",
152 PointerValue(CreateObject<IsotropicAntennaModel>()));
153
154 // set the number of antenna elements of gNbs
155 nrHelper->SetGnbAntennaAttribute("NumRows", UintegerValue(1));
156 nrHelper->SetGnbAntennaAttribute("NumColumns", UintegerValue(1));
157 nrHelper->SetGnbAntennaAttribute("AntennaElement",
158 PointerValue(CreateObject<ThreeGppAntennaModel>()));
159
160 // gNB transmit power
161 nrHelper->SetGnbPhyAttribute("TxPower", DoubleValue(43.0));
162 nrHelper->SetUePhyAttribute("TxPower", DoubleValue(43.0));
163
164 // gNB numerology
165 nrHelper->SetGnbPhyAttribute("Numerology", UintegerValue(m_numerology));
166
167 /*
168 * The configured spectrum division for TDD is:
169 *
170 * |----Band1----|
171 * |-----CC1-----|
172 * |-----BWP1----|
173 */
175 CcBwpCreator ccBwpCreator;
176 OperationBandInfo band;
177 double centralFrequency = 4e9;
178 double bandwidth = m_bw1;
179 const uint8_t numCcPerBand = 1;
180 CcBwpCreator::SimpleOperationBandConf bandConf(centralFrequency, bandwidth, numCcPerBand);
181
182 // By using the configuration created, it is time to make the operation bands
183 band = ccBwpCreator.CreateOperationBandContiguousCc(bandConf);
184 channelHelper->AssignChannelsToBands({band});
185 allBwps = CcBwpCreator::GetAllBwps({band});
186
187 uint32_t bwpIdForLowLat = 0;
188 uint32_t bwpIdForVoice = 0;
189
190 // gNb routing between Bearer and bandwidh part
191 nrHelper->SetGnbBwpManagerAlgorithmAttribute("NGBR_LOW_LAT_EMBB",
192 UintegerValue(bwpIdForLowLat));
193 nrHelper->SetGnbBwpManagerAlgorithmAttribute("GBR_CONV_VOICE", UintegerValue(bwpIdForVoice));
194
195 // Ue routing between Bearer and bandwidth part
196 nrHelper->SetUeBwpManagerAlgorithmAttribute("NGBR_LOW_LAT_EMBB", UintegerValue(bwpIdForLowLat));
197 nrHelper->SetUeBwpManagerAlgorithmAttribute("GBR_CONV_VOICE", UintegerValue(bwpIdForVoice));
198
199 // install mmWave net devices
200 NetDeviceContainer gNbNetDevs =
201 nrHelper->InstallGnbDevice(gridScenario.GetBaseStations(), allBwps);
202 NetDeviceContainer ueLowLatNetDev = nrHelper->InstallUeDevice(ueLowLatContainer, allBwps);
203 NetDeviceContainer ueVoiceNetDev = nrHelper->InstallUeDevice(ueVoiceContainer, allBwps);
204
205 randomStream = 1;
206 randomStream += nrHelper->AssignStreams(gNbNetDevs, randomStream);
207 randomStream += nrHelper->AssignStreams(ueLowLatNetDev, randomStream);
208 randomStream += nrHelper->AssignStreams(ueVoiceNetDev, randomStream);
209
210 // create the internet and install the IP stack on the UEs
211 // get SGW/PGW and create a single RemoteHost
212 Ptr<Node> pgw = nrEpcHelper->GetPgwNode();
213 NodeContainer remoteHostContainer;
214 Ptr<Node> remoteHostLowLat;
215 Ptr<Node> remoteHostVoice;
216 Ptr<Node> remoteHost;
217
218 if (m_isDownlink)
219 {
220 remoteHostContainer.Create(1);
221 remoteHost = remoteHostContainer.Get(0);
222 }
223 else
224 {
225 remoteHostContainer.Create(2);
226 remoteHostLowLat = remoteHostContainer.Get(0);
227 remoteHostVoice = remoteHostContainer.Get(1);
228 }
229
230 InternetStackHelper internet;
231 internet.Install(remoteHostContainer);
232
233 // connect a remoteHost to pgw. Setup routing too
234 PointToPointHelper p2ph;
235 p2ph.SetDeviceAttribute("DataRate", DataRateValue(DataRate("100Gb/s")));
236 p2ph.SetDeviceAttribute("Mtu", UintegerValue(2500));
237 p2ph.SetChannelAttribute("Delay", TimeValue(Seconds(0.000)));
238
239 NetDeviceContainer internetDevicesLowLat;
240 NetDeviceContainer internetDevicesVoice;
241 NetDeviceContainer internetDevices;
242
243 Ipv4AddressHelper ipv4h;
244 Ipv4InterfaceContainer internetIpIfacesLowLat;
245 Ipv4InterfaceContainer internetIpIfacesVoice;
246 Ipv4InterfaceContainer internetIpIfaces;
247 Ipv4StaticRoutingHelper ipv4RoutingHelper;
248
249 Ptr<Ipv4StaticRouting> remoteHostStaticRoutingLowLat;
250 Ptr<Ipv4StaticRouting> remoteHostStaticRoutingVoice;
251 Ptr<Ipv4StaticRouting> remoteHostStaticRouting;
252
253 if (m_isDownlink)
254 {
255 internetDevices = p2ph.Install(pgw, remoteHost);
256
257 ipv4h.SetBase("1.0.0.0", "255.0.0.0");
258 internetIpIfaces = ipv4h.Assign(internetDevices);
259
260 remoteHostStaticRouting = ipv4RoutingHelper.GetStaticRouting(remoteHost->GetObject<Ipv4>());
261 remoteHostStaticRouting->AddNetworkRouteTo(Ipv4Address("7.0.0.0"),
262 Ipv4Mask("255.0.0.0"),
263 1);
264 }
265 else
266 {
267 internetDevicesLowLat = p2ph.Install(pgw, remoteHostLowLat);
268 internetDevicesVoice = p2ph.Install(pgw, remoteHostVoice);
269
270 ipv4h.SetBase("1.0.0.0", "255.0.0.0");
271 internetIpIfacesLowLat = ipv4h.Assign(internetDevicesLowLat);
272 ipv4h.SetBase("2.0.0.0", "255.0.0.0");
273 internetIpIfacesVoice = ipv4h.Assign(internetDevicesVoice);
274
275 remoteHostStaticRoutingLowLat =
276 ipv4RoutingHelper.GetStaticRouting(remoteHostLowLat->GetObject<Ipv4>());
277 remoteHostStaticRoutingLowLat->AddNetworkRouteTo(Ipv4Address("7.0.0.0"),
278 Ipv4Mask("255.0.0.0"),
279 1);
280 remoteHostStaticRoutingVoice =
281 ipv4RoutingHelper.GetStaticRouting(remoteHostVoice->GetObject<Ipv4>());
282 remoteHostStaticRoutingVoice->AddNetworkRouteTo(Ipv4Address("8.0.0.0"),
283 Ipv4Mask("255.0.0.0"),
284 1);
285 }
286
287 internet.Install(gridScenario.GetUserTerminals());
288
289 Ipv4InterfaceContainer ueLowLatIpIface;
290 Ipv4InterfaceContainer ueVoiceIpIface;
291 ueLowLatIpIface = nrEpcHelper->AssignUeIpv4Address(NetDeviceContainer(ueLowLatNetDev));
292 ueVoiceIpIface = nrEpcHelper->AssignUeIpv4Address(NetDeviceContainer(ueVoiceNetDev));
293
294 // attach UEs to the closest gNB
295 nrHelper->AttachToClosestGnb(ueLowLatNetDev, gNbNetDevs);
296 nrHelper->AttachToClosestGnb(ueVoiceNetDev, gNbNetDevs);
297
298 /*
299 * Traffic part. Install two kind of traffic: low-latency and voice, each
300 * identified by a particular source port.
301 */
302 uint16_t dlPortLowLat = 1234;
303 uint16_t dlPortVoice = 1235;
304
305 uint16_t ulPortLowLat = 2000;
306 uint16_t ulPortVoice = 2001;
307
308 ApplicationContainer clientAppsDl;
309 ApplicationContainer serverAppsDlLowLat;
310 ApplicationContainer serverAppsDlVoice;
311
312 ApplicationContainer clientAppsUl;
313 ApplicationContainer serverAppsUlLowLat;
314 ApplicationContainer serverAppsUlVoice;
315
316 if (m_isUplink)
317 {
318 UdpServerHelper ulPacketSinkLowLat(ulPortLowLat);
319 UdpServerHelper ulPacketSinkVoice(ulPortVoice);
320
321 serverAppsUlLowLat = (ulPacketSinkLowLat.Install(remoteHostLowLat));
322 serverAppsUlVoice = (ulPacketSinkVoice.Install(remoteHostVoice));
323
324 UdpClientHelper ulClientLowlat;
325 ulClientLowlat.SetAttribute("MaxPackets", UintegerValue(0xFFFFFFFF));
326 ulClientLowlat.SetAttribute("PacketSize", UintegerValue(udpPacketSizeULL));
327 ulClientLowlat.SetAttribute("Interval", TimeValue(Seconds(1.0 / lambdaULL)));
328
329 Ptr<NrEpcTft> ulLowLatTft = Create<NrEpcTft>();
330 NrEpcTft::PacketFilter ulpfLowLat;
331 ulpfLowLat.remotePortStart = ulPortLowLat;
332 ulpfLowLat.remotePortEnd = ulPortLowLat;
333 ulpfLowLat.direction = NrEpcTft::UPLINK;
334 ulLowLatTft->Add(ulpfLowLat);
335
336 NrEpsBearer bearerLowLat(NrEpsBearer::NGBR_LOW_LAT_EMBB);
337
338 UdpClientHelper ulClientVoice;
339 ulClientVoice.SetAttribute("MaxPackets", UintegerValue(0xFFFFFFFF));
340 ulClientVoice.SetAttribute("PacketSize", UintegerValue(udpPacketSizeBe));
341 ulClientVoice.SetAttribute("Interval", TimeValue(Seconds(1.0 / lambdaBe)));
342
343 Ptr<NrEpcTft> ulVoiceTft = Create<NrEpcTft>();
344 NrEpcTft::PacketFilter ulpfVoice;
345 ulpfVoice.remotePortStart = ulPortVoice;
346 ulpfVoice.remotePortEnd = ulPortVoice;
347 ulpfVoice.direction = NrEpcTft::UPLINK;
348 ulVoiceTft->Add(ulpfVoice);
349
350 NrEpsBearer bearerVoice(NrEpsBearer::GBR_CONV_VOICE);
351
352 // configure here UDP traffic flows
353 for (uint32_t j = 0; j < ueLowLatContainer.GetN(); ++j)
354 {
355 ulClientLowlat.SetAttribute("Remote",
356 AddressValue(addressUtils::ConvertToSocketAddress(
357 internetIpIfacesLowLat.GetAddress(1),
358 ulPortLowLat)));
359 clientAppsUl.Add(ulClientLowlat.Install(ueLowLatContainer.Get(j)));
360 nrHelper->ActivateDedicatedEpsBearer(ueLowLatNetDev.Get(j), bearerLowLat, ulLowLatTft);
361 }
362
363 // configure here UDP traffic flows
364 for (uint32_t j = 0; j < ueVoiceContainer.GetN(); ++j)
365 {
366 ulClientVoice.SetAttribute("Remote",
367 AddressValue(addressUtils::ConvertToSocketAddress(
368 internetIpIfacesVoice.GetAddress(1),
369 ulPortVoice)));
370 clientAppsUl.Add(ulClientVoice.Install(ueVoiceContainer.Get(j)));
371 nrHelper->ActivateDedicatedEpsBearer(ueVoiceNetDev.Get(j), bearerVoice, ulVoiceTft);
372 }
373
374 serverAppsUlLowLat.Start(udpAppStartTimeUl);
375 serverAppsUlVoice.Start(udpAppStartTimeUl);
376 clientAppsUl.Start(udpAppStartTimeUl);
377
378 serverAppsUlLowLat.Stop(udpAppStopTimeUl);
379 serverAppsUlVoice.Stop(udpAppStopTimeUl);
380 clientAppsUl.Stop(udpAppStopTimeUl);
381 }
382
383 if (m_isDownlink)
384 {
385 UdpServerHelper dlPacketSinkLowLat(dlPortLowLat);
386 UdpServerHelper dlPacketSinkVoice(dlPortVoice);
387
388 serverAppsDlLowLat = (dlPacketSinkLowLat.Install(ueLowLatContainer));
389 serverAppsDlVoice = (dlPacketSinkVoice.Install(ueVoiceContainer));
390
391 Ptr<NrEpcTft> dlLowLatTft = Create<NrEpcTft>();
392 NrEpcTft::PacketFilter dlpfLowLat;
393 dlpfLowLat.localPortStart = dlPortLowLat;
394 dlpfLowLat.localPortEnd = dlPortLowLat;
395 dlpfLowLat.direction = NrEpcTft::DOWNLINK;
396 dlLowLatTft->Add(dlpfLowLat);
397
398 NrEpsBearer bearerLowlat(NrEpsBearer::NGBR_LOW_LAT_EMBB);
399
400 Ptr<NrEpcTft> dlVoiceTft = Create<NrEpcTft>();
401 NrEpcTft::PacketFilter dlpfVoice;
402 dlpfVoice.localPortStart = dlPortVoice;
403 dlpfVoice.localPortEnd = dlPortVoice;
404 dlpfVoice.direction = NrEpcTft::DOWNLINK;
405 dlVoiceTft->Add(dlpfVoice);
406
407 NrEpsBearer bearerVoice(NrEpsBearer::GBR_CONV_VOICE);
408
409 for (uint32_t j = 0; j < ueLowLatContainer.GetN(); ++j)
410 {
411 UdpClientHelper dlClient(ueLowLatIpIface.GetAddress(j), dlPortLowLat);
412 dlClient.SetAttribute("MaxPackets", UintegerValue(0xFFFFFFFF));
413 dlClient.SetAttribute("PacketSize", UintegerValue(udpPacketSizeULL));
414 dlClient.SetAttribute("Interval", TimeValue(Seconds(1.0 / lambdaULL)));
415 clientAppsDl.Add(dlClient.Install(remoteHost));
416
417 nrHelper->ActivateDedicatedEpsBearer(ueLowLatNetDev.Get(j), bearerLowlat, dlLowLatTft);
418 }
419
420 for (uint32_t j = 0; j < ueVoiceContainer.GetN(); ++j)
421 {
422 UdpClientHelper dlClient(ueVoiceIpIface.GetAddress(j), dlPortVoice);
423 dlClient.SetAttribute("MaxPackets", UintegerValue(0xFFFFFFFF));
424 dlClient.SetAttribute("PacketSize", UintegerValue(udpPacketSizeBe));
425 dlClient.SetAttribute("Interval", TimeValue(Seconds(1.0 / lambdaBe)));
426 clientAppsDl.Add(dlClient.Install(remoteHost));
427
428 nrHelper->ActivateDedicatedEpsBearer(ueVoiceNetDev.Get(j), bearerVoice, dlVoiceTft);
429 }
430
431 // start UDP server and client apps
432 serverAppsDlLowLat.Start(udpAppStartTimeDl);
433 serverAppsDlVoice.Start(udpAppStartTimeDl);
434 clientAppsDl.Start(udpAppStartTimeDl);
435
436 serverAppsDlLowLat.Stop(udpAppStopTimeDl);
437 serverAppsDlVoice.Stop(udpAppStopTimeDl);
438 clientAppsDl.Stop(udpAppStopTimeDl);
439 }
440
441 // nrHelper->EnableTraces();
442 Simulator::Stop(simTime);
443 Simulator::Run();
444
445 uint32_t appTime = (simTime.GetSeconds() - udpAppStartTimeDl.GetSeconds());
446
447 // Test Case 1: Half UEs QCI 1 saturated
448 // and Half UEs QCI 80
449 // check if ratio of throughputs is equal to ratio of priorities
450 double dlThroughputLowLat = 0;
451 double dlThroughputVoice = 0;
452 double ulThroughputLowLat = 0;
453 double ulThroughputVoice = 0;
454
455 if (m_isDownlink)
456 {
457 for (uint32_t i = 0; i < serverAppsDlLowLat.GetN(); i++)
458 {
459 Ptr<UdpServer> serverApp = serverAppsDlLowLat.Get(i)->GetObject<UdpServer>();
460 dlThroughputLowLat += (serverApp->GetReceived() * udpPacketSizeULL * 8) / appTime;
461 }
462 for (uint32_t i = 0; i < serverAppsDlVoice.GetN(); i++)
463 {
464 Ptr<UdpServer> serverApp = serverAppsDlVoice.Get(i)->GetObject<UdpServer>();
465 dlThroughputVoice += (serverApp->GetReceived() * udpPacketSizeBe * 8) / appTime;
466 }
467
468 // Flow 2 is saturated and it must be prioritized (QCI 1 vs 80)
469
470 double qciRatio = (100 - m_p1) / (100 - m_p2);
471 double throughputRatio = dlThroughputVoice / dlThroughputLowLat;
472
473 if (verbose)
474 {
475 std::cout << "dlThroughputLowLat: " << dlThroughputVoice
476 << " dlThroughputVoice: " << dlThroughputLowLat << std::endl;
477 std::cout << "ratio: " << qciRatio << " throughput ratio: " << throughputRatio
478 << std::endl;
479 }
480
481 NS_TEST_ASSERT_MSG_EQ_TOL(qciRatio,
482 throughputRatio,
483 (qciRatio * 0.1),
484 "DL qci Ratio and throughput Ratio are not "
485 "equal within tolerance");
486 }
487 if (m_isUplink)
488 {
489 for (uint32_t i = 0; i < serverAppsUlLowLat.GetN(); i++)
490 {
491 Ptr<UdpServer> serverApp = serverAppsUlLowLat.Get(i)->GetObject<UdpServer>();
492 ulThroughputLowLat += (serverApp->GetReceived() * udpPacketSizeULL * 8) / appTime;
493 }
494 for (uint32_t i = 0; i < serverAppsUlVoice.GetN(); i++)
495 {
496 Ptr<UdpServer> serverApp = serverAppsUlVoice.Get(i)->GetObject<UdpServer>();
497 ulThroughputVoice += (serverApp->GetReceived() * udpPacketSizeBe * 8) / appTime;
498 }
499
500 double qciRatio = (100 - m_p1) / (100 - 90); // Hardcoded P due to scheduler restrictions
501 double throughputRatio = ulThroughputVoice / ulThroughputLowLat;
502
503 if (verbose)
504 {
505 std::cout << "ulThroughputLowLat: " << ulThroughputVoice
506 << " ulThroughputVoice: " << ulThroughputLowLat << std::endl;
507 std::cout << "ratio: " << qciRatio << " throughput ratio: " << throughputRatio
508 << std::endl;
509 }
510
511 NS_TEST_ASSERT_MSG_EQ_TOL(qciRatio,
512 throughputRatio,
513 (qciRatio * 0.1),
514 "UL qci Ratio and throughput Ratio are not "
515 "equal within tolerance");
516 }
517
518 Simulator::Destroy();
519}
520
521} // namespace ns3
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.
@ ErrorModel
Error Model version (can use different error models, see NrErrorModel)
Definition nr-amc.h:81
@ NGBR_LOW_LAT_EMBB
Non-GBR Low Latency eMBB applications.
@ GBR_CONV_VOICE
GBR Conversational Voice.
void SetBsHeight(double h)
SetGnbHeight.
void SetUtHeight(double h)
SetUeHeight.
void SetSectorization(SiteSectorizationType numSectors)
Sets the number of sectors of every site.
@ SINGLE
Site with a 360ยบ-width sector.
SystemSchedulerTestQos(uint32_t ueNumPergNb, uint32_t numerology, double bw1, bool isDownlink, bool isUplink, double p1, double p2, uint32_t priorityTrafficScenario, const std::string &schedulerType)
SystemSchedulerTest is a test constructor which is used to initialise the test parameters.
~SystemSchedulerTestQos() override
~SystemSchedulerTestQos
std::vector< std::reference_wrapper< BandwidthPartInfoPtr > > BandwidthPartInfoPtrVector
vector of unique_ptr of BandwidthPartInfo
This test case checks if the throughput obtained is as expected for the QoS scheduling logic.