5G-LENA nr-v4.0
The 5G/NR module for the ns-3 simulator
Loading...
Searching...
No Matches
cttc-nr-traffic-ngmn-mixed.cc
Go to the documentation of this file.
1// Copyright (c) 2023 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
2//
3// SPDX-License-Identifier: GPL-2.0-only
4
32/*
33 * Include part. Often, you will have to include the headers for an entire module;
34 * do that by including the name of the module you need with the suffix "-module.h".
35 */
36
37#include "ns3/antenna-module.h"
38#include "ns3/applications-module.h"
39#include "ns3/config-store-module.h"
40#include "ns3/config-store.h"
41#include "ns3/core-module.h"
42#include "ns3/flow-monitor-module.h"
43#include "ns3/internet-apps-module.h"
44#include "ns3/internet-module.h"
45#include "ns3/log.h"
46#include "ns3/mobility-module.h"
47#include "ns3/network-module.h"
48#include "ns3/nr-module.h"
49#include "ns3/nr-radio-environment-map-helper.h"
50#include "ns3/ping-helper.h"
51#include "ns3/point-to-point-module.h"
52#include "ns3/rng-seed-manager.h"
53#include "ns3/three-gpp-ftp-m1-helper.h"
54#include "ns3/three-gpp-http-client.h"
55#include "ns3/three-gpp-http-helper.h"
56#include "ns3/three-gpp-http-server.h"
57#include "ns3/three-gpp-http-variables.h"
58#include "ns3/traffic-generator-ngmn-ftp-multi.h"
59#include "ns3/traffic-generator-ngmn-gaming.h"
60#include "ns3/traffic-generator-ngmn-video.h"
61#include "ns3/traffic-generator-ngmn-voip.h"
62
63#include <algorithm>
64#include <iostream>
65
66using namespace ns3;
67
68/*
69 * With this line, we will be able to see the logs of the file by enabling the
70 * component "CttcTrafficExample", in this way:
71 *
72 * $ export NS_LOG="CttcTrafficExample=level_info|prefix_func|prefix_time"
73 */
74NS_LOG_COMPONENT_DEFINE("CttcNrTrafficNgmnMixed");
75
76class RadioNetworkParametersHelper
77{
78 public:
83 void SetNetworkParams(const std::string scenario,
84 const std::string operationMode,
85 uint16_t numCcs);
90 double GetTxPower() const;
91
96 double GetBandwidth() const;
97
102 double GetCentralFrequency() const;
103
104 private:
105 double m_txPower{-1.0};
106 double m_bandwidth{0.0};
107 double m_centralFrequency{-1.0};
108};
109
110void
111RadioNetworkParametersHelper::SetNetworkParams(const std::string scenario,
112 const std::string operationMode,
113 uint16_t numCcs)
114{
115 NS_ABORT_MSG_IF(scenario != "UMa" && scenario != "UMi", "Unsupported scenario");
116
117 m_centralFrequency = 2e9;
118 m_bandwidth = 20e6 * numCcs; // 100 RBs per CC (freqReuse)
119 if (operationMode == "FDD")
120 {
121 m_bandwidth += m_bandwidth;
122 }
123 if (scenario == "UMa")
124 {
125 m_txPower = 43;
126 }
127 else
128 {
129 m_txPower = 30;
130 }
131}
132
133double
134RadioNetworkParametersHelper::GetTxPower() const
135{
136 return m_txPower;
137}
138
139double
140RadioNetworkParametersHelper::GetBandwidth() const
141{
142 return m_bandwidth;
143}
144
145double
146RadioNetworkParametersHelper::GetCentralFrequency() const
147{
148 return m_centralFrequency;
149}
150
151void
153 std::string scenario,
154 std::string radioNetwork,
155 std::string operationMode,
156 std::string direction,
157 NodeContainer gnbSector1Container,
158 NodeContainer gnbSector2Container,
159 NodeContainer gnbSector3Container,
160 NodeContainer ueSector1Container,
161 NodeContainer ueSector2Container,
162 NodeContainer ueSector3Container,
163 Ptr<NrPointToPointEpcHelper>& baseNrEpcHelper,
164 Ptr<NrHelper>& nrHelper,
165 NetDeviceContainer& gnbSector1NetDev,
166 NetDeviceContainer& gnbSector2NetDev,
167 NetDeviceContainer& gnbSector3NetDev,
168 NetDeviceContainer& ueSector1NetDev,
169 NetDeviceContainer& ueSector2NetDev,
170 NetDeviceContainer& ueSector3NetDev,
171 bool uniformLambda)
172{
173 /*
174 * Create the radio network related parameters
175 */
176 RadioNetworkParametersHelper ranHelper;
177 ranHelper.SetNetworkParams(scenario, operationMode, 1);
178
179 /*
180 * Setup the NR module. We create the various helpers needed for the
181 * NR simulation:
182 * - IdealBeamformingHelper, which takes care of the beamforming part
183 * - NrHelper, which takes care of creating and connecting the various
184 * part of the NR stack
185 * - NrChannelHelper, which takes care of the spectrum channel creation and configuration
186 */
187
188 Ptr<IdealBeamformingHelper> idealBeamformingHelper = CreateObject<IdealBeamformingHelper>();
189 nrHelper = CreateObject<NrHelper>();
190
191 // Put the pointers inside nrHelper
192 nrHelper->SetBeamformingHelper(idealBeamformingHelper);
193
194 Ptr<NrPointToPointEpcHelper> nrEpcHelper =
195 DynamicCast<NrPointToPointEpcHelper>(baseNrEpcHelper);
196 nrHelper->SetEpcHelper(nrEpcHelper);
197
198 /*
199 * Spectrum division. We create one operational band containing three
200 * component carriers, and each CC containing a single bandwidth part
201 * centered at the frequency specified by the input parameters.
202 * Each spectrum part length is, as well, specified by the input parameters.
203 * The operational band will use StreetCanyon channel or UrbanMacro modeling.
204 */
209 CcBwpCreator ccBwpCreator;
210 // Create the configuration for the CcBwpHelper. SimpleOperationBandConf creates
211 // a single BWP per CC. Get the spectrum values from the RadioNetworkParametersHelper
212 double centralFrequencyBand = ranHelper.GetCentralFrequency();
213 double bandwidthBand = ranHelper.GetBandwidth();
214 const uint8_t numCcPerBand = 1; // In this example, each cell will have one CC with one BWP
215 NS_ABORT_MSG_UNLESS(scenario == "UMa" || scenario == "UMi", "Unsupported scenario");
216
217 std::string errorModel = "";
218
219 if (radioNetwork == "LTE")
220 {
221 errorModel = "ns3::LenaErrorModel";
222 }
223 else if (radioNetwork == "NR")
224 {
225 errorModel = "ns3::NrEesmIrT2";
226 }
227
228 // Error Model: UE and GNB with same spectrum error model.
229 nrHelper->SetUlErrorModel(errorModel);
230 nrHelper->SetDlErrorModel(errorModel);
231
232 // Both DL and UL AMC will have the same model behind.
233 nrHelper->SetGnbDlAmcAttribute(
234 "AmcModel",
235 EnumValue(NrAmc::ErrorModel)); // NrAmc::ShannonModel or NrAmc::ErrorModel
236 nrHelper->SetGnbUlAmcAttribute(
237 "AmcModel",
238 EnumValue(NrAmc::ErrorModel)); // NrAmc::ShannonModel or NrAmc::ErrorModel
239
240 /*
241 * Create the necessary operation bands. In this example, each sector operates
242 * in a separate band. Each band contains a single component carrier (CC),
243 * which is made of one BWP in TDD operation mode or two BWPs in FDD mode.
244 * Note that BWPs have the same bandwidth. Therefore, CCs and bands in FDD are
245 * twice larger than in TDD.
246 *
247 * The configured spectrum division for TDD operation is:
248 * |---Band1---|---Band2---|---Band3---|
249 * |----CC1----|----CC2----|----CC3----|
250 * |----BWP1---|----BWP2---|----BWP3---|
251 *
252 * And the configured spectrum division for FDD operation is:
253 * |---------Band1---------|---------Band2---------|---------Band3---------|
254 * |----------CC1----------|----------CC2----------|----------CC3----------|
255 * |----BWP1---|----BWP2---|----BWP3---|----BWP4---|----BWP5---|----BWP6---|
256 */
257 double centralFrequencyBand1 = centralFrequencyBand - bandwidthBand;
258 double centralFrequencyBand2 = centralFrequencyBand;
259 double centralFrequencyBand3 = centralFrequencyBand + bandwidthBand;
260 double bandwidthBand1 = bandwidthBand;
261 double bandwidthBand2 = bandwidthBand;
262 double bandwidthBand3 = bandwidthBand;
263
264 uint8_t numBwpPerCc = 1;
265 if (operationMode == "FDD")
266 {
267 numBwpPerCc = 2; // FDD will have 2 BWPs per CC
268 Config::SetDefault("ns3::NrUeNetDevice::PrimaryUlIndex", UintegerValue(1));
269 }
270
271 CcBwpCreator::SimpleOperationBandConf bandConf1(centralFrequencyBand1,
272 bandwidthBand1,
273 numCcPerBand);
274 bandConf1.m_numBwp = numBwpPerCc; // FDD will have 2 BWPs per CC
275 CcBwpCreator::SimpleOperationBandConf bandConf2(centralFrequencyBand2,
276 bandwidthBand2,
277 numCcPerBand);
278 bandConf2.m_numBwp = numBwpPerCc; // FDD will have 2 BWPs per CC
279 CcBwpCreator::SimpleOperationBandConf bandConf3(centralFrequencyBand3,
280 bandwidthBand3,
281 numCcPerBand);
282 bandConf3.m_numBwp = numBwpPerCc; // FDD will have 2 BWPs per CC
283
284 // By using the configuration created, it is time to make the operation bands
285 OperationBandInfo band1 = ccBwpCreator.CreateOperationBandContiguousCc(bandConf1);
286 OperationBandInfo band2 = ccBwpCreator.CreateOperationBandContiguousCc(bandConf2);
287 OperationBandInfo band3 = ccBwpCreator.CreateOperationBandContiguousCc(bandConf3);
288 // Use the channel helper to configure the spectrum channel
289 Ptr<NrChannelHelper> channelHelper = CreateObject<NrChannelHelper>();
293 channelHelper->ConfigureFactories(scenario, "Default", "ThreeGpp");
294 // Set attributes to the channel
295 Config::SetDefault("ns3::ThreeGppChannelModel::UpdatePeriod", TimeValue(MilliSeconds(0)));
296 channelHelper->SetChannelConditionModelAttribute("UpdatePeriod", TimeValue(MilliSeconds(0)));
297 channelHelper->SetPathlossAttribute("ShadowingEnabled", BooleanValue(false));
298 // Assign the channel to all created bands
299 channelHelper->AssignChannelsToBands({band1, band2, band3});
300
301 allBwps = CcBwpCreator::GetAllBwps({band1, band2, band3});
302 bwps1 = CcBwpCreator::GetAllBwps({band1});
303 bwps2 = CcBwpCreator::GetAllBwps({band2});
304 bwps3 = CcBwpCreator::GetAllBwps({band3});
305
306 double txPower = ranHelper.GetTxPower(); // Convert to mW
307
308 /*
309 * allBwps contains all the spectrum configuration needed for the nrHelper.
310 *
311 * Now, we can setup the attributes. We can have three kind of attributes:
312 * (i) parameters that are valid for all the bandwidth parts and applies to
313 * all nodes, (ii) parameters that are valid for all the bandwidth parts
314 * and applies to some node only, and (iii) parameters that are different for
315 * every bandwidth parts. The approach is:
316 *
317 * - for (i): Configure the attribute through the helper, and then install;
318 * - for (ii): Configure the attribute through the helper, and then install
319 * for the first set of nodes. Then, change the attribute through the helper,
320 * and install again;
321 * - for (iii): Install, and then configure the attributes by retrieving
322 * the pointer needed, and calling "SetAttribute" on top of such pointer.
323 *
324 */
325
326 Packet::EnableChecking();
327 Packet::EnablePrinting();
328
329 /*
330 * Case (i): Attributes valid for all the nodes
331 */
332 // Beamforming method
333 if (radioNetwork == "LTE")
334 {
335 idealBeamformingHelper->SetAttribute(
336 "BeamformingMethod",
338 }
339 else
340 {
341 idealBeamformingHelper->SetAttribute("BeamformingMethod",
342 TypeIdValue(DirectPathBeamforming::GetTypeId()));
343 }
344
345 // Scheduler type
346 if (radioNetwork == "LTE")
347 {
348 nrHelper->SetSchedulerTypeId(TypeId::LookupByName("ns3::NrMacSchedulerOfdmaPF"));
349 nrHelper->SetSchedulerAttribute("DlCtrlSymbols", UintegerValue(1));
350 }
351 // Core latency
352 nrEpcHelper->SetAttribute("S1uLinkDelay", TimeValue(MilliSeconds(0)));
353
354 // Antennas for all the UEs
355 nrHelper->SetUeAntennaAttribute("NumRows", UintegerValue(1));
356 nrHelper->SetUeAntennaAttribute("NumColumns", UintegerValue(1));
357 nrHelper->SetUeAntennaAttribute("AntennaElement",
358 PointerValue(CreateObject<IsotropicAntennaModel>()));
359
360 // Antennas for all the gNbs
361 nrHelper->SetGnbAntennaAttribute("NumRows", UintegerValue(8));
362 nrHelper->SetGnbAntennaAttribute("NumColumns", UintegerValue(8));
363 nrHelper->SetGnbAntennaAttribute("AntennaElement",
364 PointerValue(CreateObject<ThreeGppAntennaModel>()));
365
366 // Set numerology
367 nrHelper->SetGnbPhyAttribute("Numerology", UintegerValue(1));
368 // Set gNB TX power
369 nrHelper->SetGnbPhyAttribute("TxPower", DoubleValue(txPower));
370 // UE transmit power
371 nrHelper->SetUePhyAttribute("TxPower", DoubleValue(20.0));
372
373 // Set LTE RBG size
374 if (radioNetwork == "LTE")
375 {
376 nrHelper->SetGnbMacAttribute("NumRbPerRbg", UintegerValue(4));
377 }
378
379 // We assume a common traffic pattern for all UEs
380 uint32_t bwpIdForLowLat = 0;
381 if (operationMode == "FDD" && direction == "UL")
382 {
383 bwpIdForLowLat = 1;
384 }
385
386 // TODO check later when QoS scheduler is in place, that the type of bearer corresponds to the
387 // type of traffic gNb routing between Bearer and bandwidth part
388 nrHelper->SetGnbBwpManagerAlgorithmAttribute("NGBR_VIDEO_TCP_DEFAULT",
389 UintegerValue(bwpIdForLowLat));
390
391 // Ue routing between Bearer and bandwidth part
392 nrHelper->SetUeBwpManagerAlgorithmAttribute("NGBR_VIDEO_TCP_DEFAULT",
393 UintegerValue(bwpIdForLowLat));
394
395 /*
396 * We have configured the attributes we needed. Now, install and get the pointers
397 * to the NetDevices, which contains all the NR stack:
398 */
399
400 // NetDeviceContainer gnbNetDev = nrHelper->InstallGnbDevice (gridScenario.GetBaseStations (),
401 // allBwps);
402 gnbSector1NetDev = nrHelper->InstallGnbDevice(gnbSector1Container, bwps1);
403 gnbSector2NetDev = nrHelper->InstallGnbDevice(gnbSector2Container, bwps2);
404 gnbSector3NetDev = nrHelper->InstallGnbDevice(gnbSector3Container, bwps3);
405 ueSector1NetDev = nrHelper->InstallUeDevice(ueSector1Container, bwps1);
406 ueSector2NetDev = nrHelper->InstallUeDevice(ueSector2Container, bwps2);
407 ueSector3NetDev = nrHelper->InstallUeDevice(ueSector3Container, bwps3);
408
409 int64_t randomStream = 1;
410 randomStream += nrHelper->AssignStreams(gnbSector1NetDev, randomStream);
411 randomStream += nrHelper->AssignStreams(gnbSector2NetDev, randomStream);
412 randomStream += nrHelper->AssignStreams(gnbSector3NetDev, randomStream);
413 randomStream += nrHelper->AssignStreams(ueSector1NetDev, randomStream);
414 randomStream += nrHelper->AssignStreams(ueSector2NetDev, randomStream);
415 randomStream += nrHelper->AssignStreams(ueSector3NetDev, randomStream);
416
417 /*
418 * Case (iii): Go node for node and change the attributes we have to setup
419 * per-node.
420 */
421
422 // Sectors (cells) of a site are pointing at different directions
423 double orientationRads = gridScenario.GetAntennaOrientationRadians(0);
424 for (uint32_t numCell = 0; numCell < gnbSector1NetDev.GetN(); ++numCell)
425 {
426 Ptr<NetDevice> gnb = gnbSector1NetDev.Get(numCell);
427 uint32_t numBwps = nrHelper->GetNumberBwp(gnb);
428 if (numBwps == 1) // TDD
429 {
430 // Change the antenna orientation
431 Ptr<NrGnbPhy> phy = nrHelper->GetGnbPhy(gnb, 0);
432 Ptr<UniformPlanarArray> antenna =
433 DynamicCast<UniformPlanarArray>(phy->GetSpectrumPhy()->GetAntenna());
434 antenna->SetAttribute("BearingAngle", DoubleValue(orientationRads));
435 // Set TDD pattern
436 nrHelper->GetGnbPhy(gnb, 0)->SetAttribute("Pattern",
437 StringValue("F|F|F|F|F|F|F|F|F|F|"));
438 }
439
440 else if (numBwps == 2) // FDD
441 {
442 // Change the antenna orientation
443 Ptr<NrGnbPhy> phy0 = nrHelper->GetGnbPhy(gnb, 0);
444 Ptr<UniformPlanarArray> antenna0 =
445 DynamicCast<UniformPlanarArray>(phy0->GetSpectrumPhy()->GetAntenna());
446 antenna0->SetAttribute("BearingAngle", DoubleValue(orientationRads));
447 Ptr<NrGnbPhy> phy1 = nrHelper->GetGnbPhy(gnb, 1);
448 Ptr<UniformPlanarArray> antenna1 =
449 DynamicCast<UniformPlanarArray>(phy1->GetSpectrumPhy()->GetAntenna());
450 antenna1->SetAttribute("BearingAngle", DoubleValue(orientationRads));
451 // Set TDD pattern
452 nrHelper->GetGnbPhy(gnb, 0)->SetAttribute(
453 "Pattern",
454 StringValue("DL|DL|DL|DL|DL|DL|DL|DL|DL|DL|"));
455 nrHelper->GetGnbPhy(gnb, 1)->SetAttribute(
456 "Pattern",
457 StringValue("UL|UL|UL|UL|UL|UL|UL|UL|UL|UL|"));
458
459 // Link the two FDD BWP
460 nrHelper->GetBwpManagerGnb(gnb)->SetOutputLink(1, 0);
461 }
462
463 else
464 {
465 NS_ABORT_MSG("Incorrect number of BWPs per CC");
466 }
467 }
468
469 orientationRads = gridScenario.GetAntennaOrientationRadians(1);
470 for (uint32_t numCell = 0; numCell < gnbSector2NetDev.GetN(); ++numCell)
471 {
472 Ptr<NetDevice> gnb = gnbSector2NetDev.Get(numCell);
473 uint32_t numBwps = nrHelper->GetNumberBwp(gnb);
474 if (numBwps == 1) // TDD
475 {
476 // Change the antenna orientation
477 Ptr<NrGnbPhy> phy = nrHelper->GetGnbPhy(gnb, 0);
478 Ptr<UniformPlanarArray> antenna =
479 DynamicCast<UniformPlanarArray>(phy->GetSpectrumPhy()->GetAntenna());
480 antenna->SetAttribute("BearingAngle", DoubleValue(orientationRads));
481 // Set TDD pattern
482 nrHelper->GetGnbPhy(gnb, 0)->SetAttribute("Pattern",
483 StringValue("F|F|F|F|F|F|F|F|F|F|"));
484 }
485
486 else if (numBwps == 2) // FDD
487 {
488 // Change the antenna orientation
489 Ptr<NrGnbPhy> phy0 = nrHelper->GetGnbPhy(gnb, 0);
490 Ptr<UniformPlanarArray> antenna0 =
491 DynamicCast<UniformPlanarArray>(phy0->GetSpectrumPhy()->GetAntenna());
492 antenna0->SetAttribute("BearingAngle", DoubleValue(orientationRads));
493 Ptr<NrGnbPhy> phy1 = nrHelper->GetGnbPhy(gnb, 1);
494 Ptr<UniformPlanarArray> antenna1 =
495 DynamicCast<UniformPlanarArray>(phy1->GetSpectrumPhy()->GetAntenna());
496 antenna1->SetAttribute("BearingAngle", DoubleValue(orientationRads));
497 // Set TDD pattern
498 nrHelper->GetGnbPhy(gnb, 0)->SetAttribute(
499 "Pattern",
500 StringValue("DL|DL|DL|DL|DL|DL|DL|DL|DL|DL|"));
501 nrHelper->GetGnbPhy(gnb, 1)->SetAttribute(
502 "Pattern",
503 StringValue("UL|UL|UL|UL|UL|UL|UL|UL|UL|UL|"));
504 // Link the two FDD BWP
505 nrHelper->GetBwpManagerGnb(gnb)->SetOutputLink(1, 0);
506 }
507
508 else
509 {
510 NS_ABORT_MSG("Incorrect number of BWPs per CC");
511 }
512 }
513
514 orientationRads = gridScenario.GetAntennaOrientationRadians(2);
515 for (uint32_t numCell = 0; numCell < gnbSector3NetDev.GetN(); ++numCell)
516 {
517 Ptr<NetDevice> gnb = gnbSector3NetDev.Get(numCell);
518 uint32_t numBwps = nrHelper->GetNumberBwp(gnb);
519 if (numBwps == 1) // TDD
520 {
521 // Change the antenna orientation
522 Ptr<NrGnbPhy> phy = nrHelper->GetGnbPhy(gnb, 0);
523 Ptr<UniformPlanarArray> antenna =
524 DynamicCast<UniformPlanarArray>(phy->GetSpectrumPhy()->GetAntenna());
525 antenna->SetAttribute("BearingAngle", DoubleValue(orientationRads));
526 // Set TDD pattern
527 nrHelper->GetGnbPhy(gnb, 0)->SetAttribute("Pattern",
528 StringValue("F|F|F|F|F|F|F|F|F|F|"));
529 }
530
531 else if (numBwps == 2) // FDD
532 {
533 // Change the antenna orientation
534 Ptr<NrGnbPhy> phy0 = nrHelper->GetGnbPhy(gnb, 0);
535 Ptr<UniformPlanarArray> antenna0 =
536 DynamicCast<UniformPlanarArray>(phy0->GetSpectrumPhy()->GetAntenna());
537 antenna0->SetAttribute("BearingAngle", DoubleValue(orientationRads));
538 Ptr<NrGnbPhy> phy1 = nrHelper->GetGnbPhy(gnb, 1);
539 Ptr<UniformPlanarArray> antenna1 =
540 DynamicCast<UniformPlanarArray>(phy1->GetSpectrumPhy()->GetAntenna());
541 antenna1->SetAttribute("BearingAngle", DoubleValue(orientationRads));
542 // Set TDD pattern
543 nrHelper->GetGnbPhy(gnb, 0)->SetAttribute(
544 "Pattern",
545 StringValue("DL|DL|DL|DL|DL|DL|DL|DL|DL|DL|"));
546 nrHelper->GetGnbPhy(gnb, 1)->SetAttribute(
547 "Pattern",
548 StringValue("UL|UL|UL|UL|UL|UL|UL|UL|UL|UL|"));
549 // Link the two FDD BWP
550 nrHelper->GetBwpManagerGnb(gnb)->SetOutputLink(1, 0);
551 }
552
553 else
554 {
555 NS_ABORT_MSG("Incorrect number of BWPs per CC");
556 }
557 }
558
559 // Set the UE routing:
560
561 if (operationMode == "FDD")
562 {
563 for (uint32_t i = 0; i < ueSector1NetDev.GetN(); i++)
564 {
565 nrHelper->GetBwpManagerUe(ueSector1NetDev.Get(i))->SetOutputLink(0, 1);
566 }
567
568 for (uint32_t i = 0; i < ueSector2NetDev.GetN(); i++)
569 {
570 nrHelper->GetBwpManagerUe(ueSector2NetDev.Get(i))->SetOutputLink(0, 1);
571 }
572
573 for (uint32_t i = 0; i < ueSector3NetDev.GetN(); i++)
574 {
575 nrHelper->GetBwpManagerUe(ueSector3NetDev.Get(i))->SetOutputLink(0, 1);
576 }
577 }
578}
579
580enum TrafficTypeConf
581{
582 UDP_CBR, // 0
583 FTP_3GPP_M1, // 1
584 NGMN_FTP, // 2
585 NGMN_VIDEO, // 3
586 NGMN_HTTP, // 4
587 NGMN_GAMING, // 5
588 NGMN_VOIP, // 6
589 NGMN_MIXED // 7
590};
591
598static inline std::ostream&
599operator<<(std::ostream& os, const TrafficTypeConf& item)
600{
601 switch (item)
602 {
603 case UDP_CBR:
604 os << "UDP CBR";
605 break;
606 case FTP_3GPP_M1:
607 os << "FTP 3GPP M1";
608 break;
609 case NGMN_FTP:
610 os << "NGMN FTP";
611 break;
612 case NGMN_VIDEO:
613 os << "NGMN VIDEO";
614 break;
615 case NGMN_HTTP:
616 os << "NGMN HTTP";
617 break;
618 case NGMN_GAMING:
619 os << "NGMN GAMING";
620 break;
621 case NGMN_VOIP:
622 os << "NGMN VOIP";
623 break;
624 case NGMN_MIXED:
625 os << "NGMN MIXED";
626 break;
627 default:
628 NS_ABORT_MSG("Unknown traffic type");
629 }
630 return os;
631}
632
633static inline std::istream&
634operator>>(std::istream& is, TrafficTypeConf& item)
635{
636 uint32_t inputValue;
637 is >> inputValue;
638 item = (TrafficTypeConf)inputValue;
639 return is;
640}
641
642int
643main(int argc, char* argv[])
644{
645 /*
646 * Variables that represent the parameters we will accept as input by the
647 * command line. Each of them is initialized with a default value.
648 */
649
650 TrafficTypeConf trafficTypeConf = FTP_3GPP_M1;
651 // Traffic parameters (that we will use inside this script:)
652 uint32_t udpPacketSize = 600; // bytes
653 // 4000*600*8 = 19.2 Mbps/UE,
654 // 3000*600*8 = 14.4 Mbps/UE,
655 // 2000*600*8 = 9.6 Mbps/UE
656 // 1500*600*8 = 7.2 Mbps/UE
657 // 1000*600*8 = 4.8 Mbps/UE
658 uint32_t udpLambda = 2000;
659 double ftpM1Lambda = 5;
660 uint32_t ftpM1FileSize = 512000; // in bytes
661 Time clientAppStartTime = MilliSeconds(400);
662 Time serverAppStartTime = MilliSeconds(400);
663 // Simulation parameters. Please don't use double to indicate seconds, use
664 // milliseconds and integers to avoid representation errors.
665 uint32_t simTimeMs = 1400;
666 Time appStartTime = MilliSeconds(400);
667 std::string direction = "DL";
668 bool uniformLambda = true;
669
670 // topology
671 uint16_t numOuterRings = 0;
672 uint16_t uesPerGnb = 10;
673 std::string scenario = "UMi";
674 std::string radioNetwork = "NR"; // LTE or NR
675 std::string operationMode = "TDD"; // TDD or FDD
676
677 // Where we will store the output files.
678 std::string simTag = "default";
679 std::string outputDir = "./";
680 bool logging = false;
681 bool traces = true;
682 bool useUdp = true;
683
684 uint8_t ngmnMixedFtpPercentage = 10;
685 uint8_t ngmnMixedHttpPercentage = 20;
686 uint8_t ngmnMixedVideoPercentage = 20;
687 uint8_t ngmnMixedVoipPercentage = 30;
688 uint8_t ngmnMixedGamingPercentage = 20;
689
690 /*
691 * From here, we instruct the ns3::CommandLine class of all the input parameters
692 * that we may accept as input, as well as their description, and the storage
693 * variable.
694 */
695 CommandLine cmd(__FILE__);
696
697 cmd.AddValue("trafficTypeConf",
698 "The traffic type to be configured. Currently the following options are "
699 "available: 0 - UDP CBR, 1 - FTP Model 1, 2 - NGMN FTP, 3 - NGMN VIDEO, 4 - HTTP, "
700 "5-NGMN GAMING, 6 - NGMN VOIP, 7 - NGMN MIXED (e.g., "
701 "10% FTP, 20% HTTP, 20% VIDEO STREAMING, 30% VoIP, 20% GAMING)",
702 trafficTypeConf);
703 cmd.AddValue(
704 "ngmnMixedFtpPercentage",
705 "If trafficTypeConf selected is NGMN MIXED this value can be configured to determine the "
706 "percentage of the FTP traffic. Percentage should be multiply of 10.",
707 ngmnMixedFtpPercentage);
708 cmd.AddValue(
709 "ngmnMixedHttpPercentage",
710 "If trafficTypeConf selected is NGMN MIXED this value can be configured to determine the "
711 "percentage of the HTTP traffic. Percentage should be multiply of 10.",
712 ngmnMixedHttpPercentage);
713 cmd.AddValue(
714 "ngmnMixedVideoPercentage",
715 "If trafficTypeConf selected is NGMN MIXED this value can be configured to determine the "
716 "percentage of the VIDEO traffic. Percentage should be multiply of 10.",
717 ngmnMixedVideoPercentage);
718 cmd.AddValue(
719 "ngmnMixedVoipPercentage",
720 "If trafficTypeConf selected is NGMN MIXED this value can be configured to determine the "
721 "percentage of the VoIP traffic. Percentage should be multiply of 10.",
722 ngmnMixedVoipPercentage);
723 cmd.AddValue(
724 "ngmnMixedGamingPercentage",
725 "If trafficTypeConf selected is NGMN MIXED this value can be configured to determine the "
726 "percentage of the GAMING traffic. Percentage should be multiply of 10.",
727 ngmnMixedGamingPercentage);
728 cmd.AddValue("useUdp",
729 "if true, the NGMN applications will run over UDP connection, otherwise a TCP "
730 "connection will be used. "
731 "Notice that HTTP application as it is present in ns-3 simulator is implemented "
732 "as typical HTTP application, i.e., "
733 "based on the TCP protocol and as such cannot be reconfigured to use UDP.",
734 useUdp);
735 cmd.AddValue("ftpM1Lambda",
736 "The lambda to be used for FTP M1 traffic model (Typical values are 2.5, 5). ",
737 ftpM1Lambda);
738 cmd.AddValue("udpLambda", "Number of UDP packets generated in one second per UE", udpLambda);
739 cmd.AddValue("uniformLambda",
740 "1: Use same lambda (packets/s) for all UEs and cells (equal to 'lambda' input), "
741 "0: use different packet arrival rates (lambdas) among cells",
742 uniformLambda);
743 cmd.AddValue("scenario", "The urban scenario string (UMa or UMi)", scenario);
744 cmd.AddValue("numRings", "The number of rings around the central site", numOuterRings);
745 cmd.AddValue("uesPerGnb",
746 "The number of UE per gNB, should be multiply of 10 so that the mixed traffic "
747 "works correctly.",
748 uesPerGnb);
749 cmd.AddValue("logging", "Enable logging", logging);
750 cmd.AddValue("traces", "Enable output traces", traces);
751 cmd.AddValue("packetSize", "packet size in bytes to be used by UE traffic", udpPacketSize);
752 cmd.AddValue("simTimeMs", "Simulation time", simTimeMs);
753 cmd.AddValue("direction", "The flow direction (DL or UL)", direction);
754 cmd.AddValue("technology", "The radio access network technology", radioNetwork);
755 cmd.AddValue("operationMode", "The network operation mode can be TDD or FDD", operationMode);
756 cmd.AddValue("simTag",
757 "tag to be appended to output filenames to distinguish simulation campaigns",
758 simTag);
759 cmd.AddValue("outputDir", "directory where to store simulation results", outputDir);
760
761 // Parse the command line
762 cmd.Parse(argc, argv);
763
764 /*
765 * Check if the parameter values provided by the user are correct.
766 */
767 // NS_ABORT_IF (centralFrequencyBand > 100e9);]
768 NS_ABORT_MSG_IF(
769 trafficTypeConf > 7,
770 "Currently only supported values for traffic type are 0, 1, 2. Meaning: 0 -UDP CBR, 1 - "
771 "FTP Model 1, 2 - NGMN FTP, 3 - NGMN VIDEO, 4- HTTP, 5- NGMN GAMING, 6 - VOIP, 7 - NGMN "
772 "MIXED (e.g., 10% FTP, 20% HTTP, 20% VIDEO STREAMING, 30% VoIP, 20% GAMING");
773 NS_ABORT_MSG_IF(direction != "DL" && direction != "UL", "Flow direction can only be DL or UL");
774 NS_ABORT_MSG_IF(operationMode != "TDD" && operationMode != "FDD",
775 "Operation mode can only be TDD or FDD");
776 NS_ABORT_MSG_IF(radioNetwork != "LTE" && radioNetwork != "NR",
777 "Unrecognized radio network technology");
778
779 NS_ABORT_MSG_IF(
780 trafficTypeConf == 7 &&
781 (ngmnMixedFtpPercentage + ngmnMixedHttpPercentage + ngmnMixedVideoPercentage +
782 ngmnMixedVoipPercentage + ngmnMixedGamingPercentage) != 100,
783 "If trafficTypeConf selected is the NGMN mixed, then the sum of the percentages of FTP, "
784 "VOIP, HTTP, VIDEO STREAMING and GAMING traffic should give 100.");
785 /*
786 * If the logging variable is set to true, enable the log of some components
787 * through the code. The same effect can be obtained through the use
788 * of the NS_LOG environment variable:
789 *
790 * export NS_LOG="UdpClient=level_info|prefix_time|prefix_func|prefix_node:UdpServer=..."
791 *
792 * Usually, the environment variable way is preferred, as it is more customizable,
793 * and more expressive.
794 */
795 if (logging)
796 {
797 LogComponentEnable("UdpClient", LOG_LEVEL_INFO);
798 LogComponentEnable("UdpServer", LOG_LEVEL_INFO);
799 // LogComponentEnable ("NrMacSchedulerOfdma", LOG_LEVEL_ALL);
800 }
801
802 // configure the transport protocol to be used
803 std::string transportProtocol;
804 if (useUdp)
805 {
806 transportProtocol = "ns3::UdpSocketFactory";
807 }
808 else
809 {
810 transportProtocol = "ns3::TcpSocketFactory";
811 }
812
813 Time simTime = MilliSeconds(simTimeMs);
814
815 std::cout << "\n Traffic configuration selected is: " << trafficTypeConf << std::endl;
816
817 /*
818 * Create the scenario. In our examples, we heavily use helpers that setup
819 * the gnbs and ue following a pre-defined pattern. Please have a look at the
820 * GridScenarioHelper documentation to see how the nodes will be distributed.
821 */
822 HexagonalGridScenarioHelper gridScenario;
823 gridScenario.SetSectorization(HexagonalGridScenarioHelper::TRIPLE);
824 gridScenario.SetNumRings(numOuterRings);
825 gridScenario.SetScenarioParameters(scenario);
826 uint16_t gNbNum = gridScenario.GetNumCells();
827 std::cout << " GNB num: " << gNbNum << std::endl;
828 uint32_t ueNum = uesPerGnb * gNbNum;
829 std::cout << " UE num: " << ueNum << std::endl;
830 gridScenario.SetUtNumber(ueNum);
831 gridScenario.AssignStreams(RngSeedManager::GetRun());
832 gridScenario.CreateScenario();
833 const uint16_t ffr =
834 3; // Fractional Frequency Reuse scheme to mitigate intra-site inter-sector interferences
835
836 /*
837 * Create different gNB NodeContainer for the different sectors.
838 */
839 NodeContainer gnbSector1Container;
840 NodeContainer gnbSector2Container;
841 NodeContainer gnbSector3Container;
842 for (uint32_t j = 0; j < gridScenario.GetBaseStations().GetN(); ++j)
843 {
844 Ptr<Node> gnb = gridScenario.GetBaseStations().Get(j);
845 switch (j % ffr)
846 {
847 case 0:
848 gnbSector1Container.Add(gnb);
849 break;
850 case 1:
851 gnbSector2Container.Add(gnb);
852 break;
853 case 2:
854 gnbSector3Container.Add(gnb);
855 break;
856 default:
857 NS_ABORT_MSG("ffr param cannot be larger than 3");
858 break;
859 }
860 }
861
862 /*
863 * Create different UE NodeContainer for the different sectors.
864 */
865 NodeContainer ueSector1Container;
866 NodeContainer ueSector2Container;
867 NodeContainer ueSector3Container;
868
869 for (uint32_t j = 0; j < gridScenario.GetUserTerminals().GetN(); ++j)
870 {
871 Ptr<Node> ue = gridScenario.GetUserTerminals().Get(j);
872 switch (j % ffr)
873 {
874 case 0:
875 ueSector1Container.Add(ue);
876 break;
877 case 1:
878 ueSector2Container.Add(ue);
879 break;
880 case 2:
881 ueSector3Container.Add(ue);
882 break;
883 default:
884 NS_ABORT_MSG("ffr param cannot be larger than 3");
885 break;
886 }
887 }
888
889 /*
890 * Setup the 5G-LENA scenario
891 */
892 Ptr<NrPointToPointEpcHelper> nrEpcHelper;
893
894 NetDeviceContainer gnbSector1NetDev;
895 NetDeviceContainer gnbSector2NetDev;
896 NetDeviceContainer gnbSector3NetDev;
897 NetDeviceContainer ueSector1NetDev;
898 NetDeviceContainer ueSector2NetDev;
899 NetDeviceContainer ueSector3NetDev;
900
901 Ptr<NrHelper> nrHelper = nullptr;
902
903 nrEpcHelper = CreateObject<NrPointToPointEpcHelper>();
904 Set5gLenaSimulatorParameters(gridScenario,
905 scenario,
906 radioNetwork,
907 operationMode,
908 direction,
909 gnbSector1Container,
910 gnbSector2Container,
911 gnbSector3Container,
912 ueSector1Container,
913 ueSector2Container,
914 ueSector3Container,
915 nrEpcHelper,
916 nrHelper,
917 gnbSector1NetDev,
918 gnbSector2NetDev,
919 gnbSector3NetDev,
920 ueSector1NetDev,
921 ueSector2NetDev,
922 ueSector3NetDev,
923 uniformLambda);
924
925 // From here, it is standard NS3. In the future, we will create helpers
926 // for this part as well.
927 auto [remoteHost, remoteHostIpv4Address] =
928 nrEpcHelper->SetupRemoteHost("100Gb/s", 2500, Seconds(0.000));
929 auto remoteHostContainer = NodeContainer(remoteHost);
930
931 InternetStackHelper internet;
932 internet.Install(gridScenario.GetUserTerminals());
933
934 // if the mixed traffic type selected then determine for each which container IDs correposnd to
935 // each traffic type
936
937 std::set<uint16_t> ngmnFtpIds;
938 std::set<uint16_t> ngmnVideoIds;
939 std::set<uint16_t> ngmnVoipIds;
940 std::set<uint16_t> ngmnHttpIds;
941 std::set<uint16_t> ngmnGamingIds;
942
943 // configure indexes of UEs per traffic type
944
945 if (trafficTypeConf == NGMN_MIXED)
946 {
947 // check if there is enough UEs to configure NGMN_MIXED traffic type
948 NS_ABORT_MSG_UNLESS((ueSector1NetDev.GetN() % 10) == 0,
949 "The number of UEs per sector must be mupliply of 10 when NGMN MIXED "
950 "traffic configured");
951
952 std::cout << "\n ueSector1NetDev:" << ueSector1NetDev.GetN() / 10 << std::endl;
953 NS_ABORT_MSG_UNLESS((ueSector1NetDev.GetN() / 10) >= 1,
954 "The number of UEs per sector must be at least 10 when NGMN MIXED "
955 "traffic is configured");
956
957 uint16_t ftp = (ueSector1NetDev.GetN() / 10) * ngmnMixedFtpPercentage / 10;
958 uint16_t http = (ueSector1NetDev.GetN() / 10) * ngmnMixedHttpPercentage / 10;
959 uint16_t video = (ueSector1NetDev.GetN() / 10) * ngmnMixedVideoPercentage / 10;
960 uint16_t voip = (ueSector1NetDev.GetN() / 10) * ngmnMixedVoipPercentage / 10;
961 uint16_t gaming = (ueSector1NetDev.GetN() / 10) * ngmnMixedGamingPercentage / 10;
962 uint16_t index = 0;
963
964 std::cout << "\n Each sector has:" << std::endl;
965 std::cout << ftp << " UEs with NGMN FTP traffic" << std::endl;
966 std::cout << http << " UEs with NGMN HTTP traffic" << std::endl;
967 std::cout << video << " UEs with NGMN VIDEO traffic" << std::endl;
968 std::cout << voip << " UEs with NGMN VOIP traffic" << std::endl;
969 std::cout << gaming << " UEs with NGMN GAMING traffic" << std::endl;
970
971 for (uint16_t i = 0; i < ftp; i++)
972 {
973 ngmnFtpIds.insert(index++);
974 }
975
976 for (uint16_t i = 0; i < http; i++)
977 {
978 ngmnHttpIds.insert(index++);
979 }
980
981 for (uint16_t i = 0; i < video; i++)
982 {
983 ngmnVideoIds.insert(index++);
984 }
985
986 for (uint16_t i = 0; i < voip; i++)
987 {
988 ngmnVoipIds.insert(index++);
989 }
990
991 for (uint16_t i = 0; i < gaming; i++)
992 {
993 ngmnGamingIds.insert(index++);
994 }
995 }
996
997 Ipv4InterfaceContainer ueSector1IpIface =
998 nrEpcHelper->AssignUeIpv4Address(NetDeviceContainer(ueSector1NetDev));
999 Ipv4InterfaceContainer ueSector2IpIface =
1000 nrEpcHelper->AssignUeIpv4Address(NetDeviceContainer(ueSector2NetDev));
1001 Ipv4InterfaceContainer ueSector3IpIface =
1002 nrEpcHelper->AssignUeIpv4Address(NetDeviceContainer(ueSector3NetDev));
1003
1004 // attach UEs to their gNB. Try to attach them per cellId order
1005 for (uint32_t u = 0; u < ueNum; ++u)
1006 {
1007 uint32_t sector = u % ffr;
1008 uint32_t i = u / ffr;
1009 if (sector == 0)
1010 {
1011 Ptr<NetDevice> gnbNetDev = gnbSector1NetDev.Get(i % gridScenario.GetNumSites());
1012 Ptr<NetDevice> ueNetDev = ueSector1NetDev.Get(i);
1013
1014 nrHelper->AttachToGnb(ueNetDev, gnbNetDev);
1015
1016 if (logging)
1017 {
1018 Vector gnbpos = gnbNetDev->GetNode()->GetObject<MobilityModel>()->GetPosition();
1019 Vector uepos = ueNetDev->GetNode()->GetObject<MobilityModel>()->GetPosition();
1020 double distance = CalculateDistance(gnbpos, uepos);
1021 std::cout << "Distance = " << distance << " meters" << std::endl;
1022 }
1023 }
1024 else if (sector == 1)
1025 {
1026 Ptr<NetDevice> gnbNetDev = gnbSector2NetDev.Get(i % gridScenario.GetNumSites());
1027 Ptr<NetDevice> ueNetDev = ueSector2NetDev.Get(i);
1028 nrHelper->AttachToGnb(ueNetDev, gnbNetDev);
1029 if (logging)
1030 {
1031 Vector gnbpos = gnbNetDev->GetNode()->GetObject<MobilityModel>()->GetPosition();
1032 Vector uepos = ueNetDev->GetNode()->GetObject<MobilityModel>()->GetPosition();
1033 double distance = CalculateDistance(gnbpos, uepos);
1034 std::cout << "Distance = " << distance << " meters" << std::endl;
1035 }
1036 }
1037 else if (sector == 2)
1038 {
1039 Ptr<NetDevice> gnbNetDev = gnbSector3NetDev.Get(i % gridScenario.GetNumSites());
1040 Ptr<NetDevice> ueNetDev = ueSector3NetDev.Get(i);
1041 nrHelper->AttachToGnb(ueNetDev, gnbNetDev);
1042 if (logging)
1043 {
1044 Vector gnbpos = gnbNetDev->GetNode()->GetObject<MobilityModel>()->GetPosition();
1045 Vector uepos = ueNetDev->GetNode()->GetObject<MobilityModel>()->GetPosition();
1046 double distance = CalculateDistance(gnbpos, uepos);
1047 std::cout << "Distance = " << distance << " meters" << std::endl;
1048 }
1049 }
1050 else
1051 {
1052 NS_ABORT_MSG("Number of sector cannot be larger than 3");
1053 }
1054 }
1055
1056 /*
1057 * Traffic part. Install two kind of traffic: low-latency and voice, each
1058 * identified by a particular source port.
1059 */
1060 uint16_t dlPortLowLat = 1234;
1061
1062 ApplicationContainer serverApps;
1063
1064 // The sink will always listen to the specified ports
1065 UdpServerHelper dlPacketSinkLowLat(dlPortLowLat);
1066
1067 // The server, that is the application which is listening, is installed in the UE
1068 if (direction == "DL")
1069 {
1070 serverApps.Add(dlPacketSinkLowLat.Install(
1071 {ueSector1Container, ueSector2Container, ueSector3Container}));
1072 }
1073 else
1074 {
1075 serverApps.Add(dlPacketSinkLowLat.Install(remoteHost));
1076 }
1077
1078 /*
1079 * Configure attributes for the different generators, using user-provided
1080 * parameters for generating a CBR traffic
1081 *
1082 * Low-Latency configuration and object creation:
1083 */
1084 UdpClientHelper dlClientLowLat;
1085 dlClientLowLat.SetAttribute("MaxPackets", UintegerValue(0xFFFFFFFF));
1086 dlClientLowLat.SetAttribute("PacketSize", UintegerValue(udpPacketSize));
1087 // dlClientLowLat.SetAttribute ("Interval", TimeValue (Seconds (1.0/lambda)));
1088
1089 // The bearer that will carry low latency traffic
1091
1092 // The filter for the low-latency traffic
1093 Ptr<NrEpcTft> lowLatTft = Create<NrEpcTft>();
1094 NrEpcTft::PacketFilter dlpfLowLat;
1095 if (direction == "DL")
1096 {
1097 dlpfLowLat.localPortStart = dlPortLowLat;
1098 dlpfLowLat.localPortEnd = dlPortLowLat;
1099 dlpfLowLat.direction = NrEpcTft::DOWNLINK;
1100 }
1101 else
1102 {
1103 dlpfLowLat.remotePortStart = dlPortLowLat;
1104 dlpfLowLat.remotePortEnd = dlPortLowLat;
1105 dlpfLowLat.direction = NrEpcTft::UPLINK;
1106 }
1107 lowLatTft->Add(dlpfLowLat);
1108
1109 std::vector<uint32_t> lambdaPerCell(gridScenario.GetNumCells());
1110
1111 if (trafficTypeConf == UDP_CBR)
1112 {
1113 if (uniformLambda)
1114 {
1115 for (uint32_t bs = 0; bs < gridScenario.GetNumCells(); ++bs)
1116 {
1117 lambdaPerCell[bs] = udpLambda;
1118 std::cout << "Cell: " << bs << " lambda (same lambda): " << lambdaPerCell[bs]
1119 << std::endl;
1120 }
1121 }
1122 else // non-uniform lambda values among the cells!
1123 {
1124 for (uint32_t bs = 0; bs < gridScenario.GetNumCells(); ++bs)
1125 {
1126 lambdaPerCell[bs] = 1000 + bs * 2000;
1127 std::cout << "Cell: " << bs << " lambda (diff lambda): " << lambdaPerCell[bs]
1128 << std::endl;
1129 }
1130 }
1131 }
1132
1133 // We need to increase RLC buffer sizes for large files
1134 Config::SetDefault("ns3::NrRlcUm::MaxTxBufferSize", UintegerValue(999999999));
1135
1136 /*
1137 * Let's install the applications!
1138 */
1139 ApplicationContainer clientApps;
1140 ApplicationContainer ftpClientAppsSector1;
1141 ApplicationContainer ftpServerAppsSector1;
1142 ApplicationContainer ftpClientAppsSector2;
1143 ApplicationContainer ftpServerAppsSector2;
1144 ApplicationContainer ftpClientAppsSector3;
1145 ApplicationContainer ftpServerAppsSector3;
1146 Ptr<ThreeGppFtpM1Helper> ftpHelperSector1;
1147 Ptr<ThreeGppFtpM1Helper> ftpHelperSector2;
1148 Ptr<ThreeGppFtpM1Helper> ftpHelperSector3;
1149 uint32_t port1 = 2001;
1150 uint32_t port2 = 2002;
1151 uint32_t port3 = 2003;
1152 // Seed the ARP cache by pinging early in the simulation
1153 // This is a workaround until a static ARP capability is provided
1154 ApplicationContainer pingApps;
1155
1156 if (trafficTypeConf == FTP_3GPP_M1)
1157 {
1158 // sector 1 FTP M1 applications configuration
1159 ftpHelperSector1 = CreateObject<ThreeGppFtpM1Helper>(&ftpServerAppsSector1,
1160 &ftpClientAppsSector1,
1161 &ueSector1Container,
1162 &remoteHostContainer,
1163 &ueSector1IpIface);
1164 ftpHelperSector1->Configure(port1,
1165 serverAppStartTime,
1166 clientAppStartTime,
1167 simTime,
1168 ftpM1Lambda,
1169 ftpM1FileSize);
1170 ftpHelperSector1->Start();
1171
1172 // sector 2 FTP M1 applications configuration
1173 ftpHelperSector2 = CreateObject<ThreeGppFtpM1Helper>(&ftpServerAppsSector2,
1174 &ftpClientAppsSector2,
1175 &ueSector2Container,
1176 &remoteHostContainer,
1177 &ueSector2IpIface);
1178 ftpHelperSector2->Configure(port2,
1179 serverAppStartTime,
1180 clientAppStartTime,
1181 simTime,
1182 ftpM1Lambda,
1183 ftpM1FileSize);
1184 ftpHelperSector2->Start();
1185
1186 // sector 3 FTP M1 applications configuration
1187 ftpHelperSector3 = CreateObject<ThreeGppFtpM1Helper>(&ftpServerAppsSector3,
1188 &ftpClientAppsSector3,
1189 &ueSector3Container,
1190 &remoteHostContainer,
1191 &ueSector3IpIface);
1192 ftpHelperSector3->Configure(port3,
1193 serverAppStartTime,
1194 clientAppStartTime,
1195 simTime,
1196 ftpM1Lambda,
1197 ftpM1FileSize);
1198 ftpHelperSector3->Start();
1199
1200 clientApps.Add(ftpClientAppsSector1);
1201 clientApps.Add(ftpClientAppsSector2);
1202 clientApps.Add(ftpClientAppsSector3);
1203
1204 serverApps.Add(ftpServerAppsSector1);
1205 serverApps.Add(ftpServerAppsSector2);
1206 serverApps.Add(ftpServerAppsSector3);
1207 }
1208
1209 if (trafficTypeConf == NGMN_FTP || (trafficTypeConf == NGMN_MIXED && !ngmnFtpIds.empty()))
1210 {
1211 uint32_t portFtpNgmn = 2000;
1212
1213 if (direction == "DL")
1214 {
1215 // configure FTP clients with file transfer application that generates multiple file
1216 // transfers
1217 TrafficGeneratorHelper ftpHelper(transportProtocol,
1218 Address(),
1220 ftpHelper.SetAttribute("PacketSize", UintegerValue(1448));
1221 ftpHelper.SetAttribute("MaxFileSize", UintegerValue(5e6));
1222
1223 // configure clients on sector 1
1224 for (uint32_t i = 0; i < ueSector1IpIface.GetN(); i++)
1225 {
1226 // in case of NGMN traffic allow installation of the specific traffic type only on
1227 // the specific nodes
1228 if ((trafficTypeConf == NGMN_MIXED) and (ngmnFtpIds.find(i) == ngmnFtpIds.end()))
1229 {
1230 continue;
1231 }
1232
1233 Ipv4Address ipAddress = ueSector1IpIface.GetAddress(i, 0);
1234 AddressValue ueAddress(InetSocketAddress(ipAddress, portFtpNgmn));
1235 ftpHelper.SetAttribute("Remote", ueAddress);
1236 clientApps.Add(ftpHelper.Install(remoteHost));
1237 // Seed the ARP cache by pinging early in the simulation
1238 // This is a workaround until a static ARP capability is provided
1239 PingHelper ping(ipAddress);
1240 pingApps.Add(ping.Install(remoteHost));
1241 }
1242 // configure clients on sector 2
1243 for (uint32_t i = 0; i < ueSector2IpIface.GetN(); i++)
1244 {
1245 // in case of NGMN traffic allow installation of the specific traffic type only on
1246 // the specific nodes
1247 if ((trafficTypeConf == NGMN_MIXED) and (ngmnFtpIds.find(i) == ngmnFtpIds.end()))
1248 {
1249 continue;
1250 }
1251 Ipv4Address ipAddress = ueSector2IpIface.GetAddress(i, 0);
1252 AddressValue ueAddress(InetSocketAddress(ipAddress, portFtpNgmn));
1253 ftpHelper.SetAttribute("Remote", ueAddress);
1254 clientApps.Add(ftpHelper.Install(remoteHost));
1255 // Seed the ARP cache by pinging early in the simulation
1256 // This is a workaround until a static ARP capability is provided
1257 PingHelper ping(ipAddress);
1258 pingApps.Add(ping.Install(remoteHost));
1259 }
1260 // configure clients on sector 3
1261 for (uint32_t i = 0; i < ueSector3IpIface.GetN(); i++)
1262 {
1263 // in case of NGMN traffic allow installation of the specific traffic type only on
1264 // the specific nodes
1265 if ((trafficTypeConf == NGMN_MIXED) and (ngmnFtpIds.find(i) == ngmnFtpIds.end()))
1266 {
1267 continue;
1268 }
1269
1270 Ipv4Address ipAddress = ueSector3IpIface.GetAddress(i, 0);
1271 AddressValue ueAddress(InetSocketAddress(ipAddress, portFtpNgmn));
1272 ftpHelper.SetAttribute("Remote", ueAddress);
1273 clientApps.Add(ftpHelper.Install(remoteHost));
1274 // Seed the ARP cache by pinging early in the simulation
1275 // This is a workaround until a static ARP capability is provided
1276 PingHelper ping(ipAddress);
1277 pingApps.Add(ping.Install(remoteHost));
1278 }
1279
1280 // configure FTP servers
1281 InetSocketAddress localAddress(Ipv4Address::GetAny(), portFtpNgmn);
1282 PacketSinkHelper packetSinkHelper(transportProtocol, localAddress);
1283
1284 for (uint32_t index = 0; index < ueSector1IpIface.GetN(); index++)
1285 {
1286 // in case of NGMN traffic we install packet sink for the subset of the nodes
1287 if ((trafficTypeConf == NGMN_MIXED) and
1288 (ngmnFtpIds.find(index) == ngmnFtpIds.end()))
1289 {
1290 continue;
1291 }
1292 serverApps.Add(packetSinkHelper.Install(ueSector1Container.Get(index)));
1293 serverApps.Add(packetSinkHelper.Install(ueSector2Container.Get(index)));
1294 serverApps.Add(packetSinkHelper.Install(ueSector3Container.Get(index)));
1295 }
1296 }
1297 else
1298 {
1299 NS_ABORT_MSG("Not yet supported option of FTP NGMN traffic with the UL traffic in this "
1300 "example. If you need it implement this else block");
1301 }
1302 }
1303
1304 if (trafficTypeConf == NGMN_VIDEO || (trafficTypeConf == NGMN_MIXED && !ngmnVideoIds.empty()))
1305 {
1306 uint32_t portNgmnVideo = 4000;
1307
1308 if (direction == "DL")
1309 {
1310 // configure FTP clients with file transfer application that generates multiple file
1311 // transfers
1312 TrafficGeneratorHelper trafficGeneratorHelper(transportProtocol,
1313 Address(),
1315 trafficGeneratorHelper.SetAttribute("NumberOfPacketsInFrame", UintegerValue(8));
1316 trafficGeneratorHelper.SetAttribute("InterframeIntervalTime",
1317 TimeValue(Seconds(0.100)));
1318
1319 // configure clients on sector 1
1320 for (uint32_t i = 0; i < ueSector1IpIface.GetN(); i++)
1321 {
1322 // in case of NGMN traffic allow installation of the specific traffic type only on
1323 // the specific nodes
1324 if ((trafficTypeConf == NGMN_MIXED) and
1325 (ngmnVideoIds.find(i) == ngmnVideoIds.end()))
1326 {
1327 continue;
1328 }
1329
1330 Ipv4Address ipAddress = ueSector1IpIface.GetAddress(i, 0);
1331 AddressValue remoteAddress(InetSocketAddress(ipAddress, portNgmnVideo));
1332 trafficGeneratorHelper.SetAttribute("Remote", remoteAddress);
1333 clientApps.Add(trafficGeneratorHelper.Install(remoteHost));
1334 // Seed the ARP cache by pinging early in the simulation
1335 // This is a workaround until a static ARP capability is provided
1336 PingHelper ping(ipAddress);
1337 pingApps.Add(ping.Install(remoteHost));
1338 }
1339 // configure clients on sector 2
1340 for (uint32_t i = 0; i < ueSector2IpIface.GetN(); i++)
1341 {
1342 // in case of NGMN traffic allow installation of the specific traffic type only on
1343 // the specific nodes
1344 if ((trafficTypeConf == NGMN_MIXED) and
1345 (ngmnVideoIds.find(i) == ngmnVideoIds.end()))
1346 {
1347 continue;
1348 }
1349
1350 Ipv4Address ipAddress = ueSector2IpIface.GetAddress(i, 0);
1351 AddressValue remoteAddress(InetSocketAddress(ipAddress, portNgmnVideo));
1352 trafficGeneratorHelper.SetAttribute("Remote", remoteAddress);
1353 clientApps.Add(trafficGeneratorHelper.Install(remoteHost));
1354 // Seed the ARP cache by pinging early in the simulation
1355 // This is a workaround until a static ARP capability is provided
1356 PingHelper ping(ipAddress);
1357 pingApps.Add(ping.Install(remoteHost));
1358 }
1359 // configure clients on sector 3
1360 for (uint32_t i = 0; i < ueSector3IpIface.GetN(); i++)
1361 {
1362 // in case of NGMN traffic allow installation of the specific traffic type only on
1363 // the specific nodes
1364 if ((trafficTypeConf == NGMN_MIXED) and
1365 (ngmnVideoIds.find(i) == ngmnVideoIds.end()))
1366 {
1367 continue;
1368 }
1369
1370 Ipv4Address ipAddress = ueSector3IpIface.GetAddress(i, 0);
1371 AddressValue remoteAddress(InetSocketAddress(ipAddress, portNgmnVideo));
1372 trafficGeneratorHelper.SetAttribute("Remote", remoteAddress);
1373 clientApps.Add(trafficGeneratorHelper.Install(remoteHost));
1374 // Seed the ARP cache by pinging early in the simulation
1375 // This is a workaround until a static ARP capability is provided
1376 PingHelper ping(ipAddress);
1377 pingApps.Add(ping.Install(remoteHost));
1378 }
1379
1380 // configure servers
1381 InetSocketAddress localAddress(Ipv4Address::GetAny(), portNgmnVideo);
1382 PacketSinkHelper packetSinkHelper(transportProtocol, localAddress);
1383
1384 for (uint32_t index = 0; index < ueSector1IpIface.GetN(); index++)
1385 {
1386 // in case of NGMN traffic we install packet sink for the subset of the nodes
1387 if ((trafficTypeConf == NGMN_MIXED) and
1388 (ngmnVideoIds.find(index) == ngmnVideoIds.end()))
1389 {
1390 continue;
1391 }
1392
1393 Ptr<PacketSink> ps1 = packetSinkHelper.Install(ueSector1Container.Get(index))
1394 .Get(0)
1395 ->GetObject<PacketSink>();
1396 Ptr<PacketSink> ps2 = packetSinkHelper.Install(ueSector2Container.Get(index))
1397 .Get(0)
1398 ->GetObject<PacketSink>();
1399 Ptr<PacketSink> ps3 = packetSinkHelper.Install(ueSector3Container.Get(index))
1400 .Get(0)
1401 ->GetObject<PacketSink>();
1402 serverApps.Add(ps1);
1403 serverApps.Add(ps2);
1404 serverApps.Add(ps3);
1405 }
1406 }
1407 else
1408 {
1409 NS_ABORT_MSG("Not yet supported option of FTP NGMN traffic with the UL traffic in this "
1410 "example. If you need it implement this else block");
1411 }
1412 }
1413
1414 if (trafficTypeConf == NGMN_GAMING || (trafficTypeConf == NGMN_MIXED && !ngmnGamingIds.empty()))
1415 {
1416 uint32_t portNgmnGaming = 5000;
1417 if (direction == "DL")
1418 {
1419 // configure FTP clients with file transfer application that generates multiple file
1420 // transfers
1421 TrafficGeneratorHelper trafficGeneratorHelper(transportProtocol,
1422 Address(),
1424 trafficGeneratorHelper.SetAttribute("IsDownlink", BooleanValue(true));
1425 trafficGeneratorHelper.SetAttribute("aParamPacketSizeDl", UintegerValue(120));
1426 trafficGeneratorHelper.SetAttribute("bParamPacketSizeDl", DoubleValue(36));
1427 trafficGeneratorHelper.SetAttribute("aParamPacketArrivalDl", DoubleValue(45));
1428 trafficGeneratorHelper.SetAttribute("bParamPacketArrivalDl", DoubleValue(5.7));
1429 trafficGeneratorHelper.SetAttribute("InitialPacketArrivalMin", UintegerValue(0));
1430 trafficGeneratorHelper.SetAttribute("InitialPacketArrivalMax", UintegerValue(40));
1431
1432 // configure clients on sector 1
1433 for (uint32_t i = 0; i < ueSector1IpIface.GetN(); i++)
1434 {
1435 // in case of NGMN traffic allow installation of the specific traffic type only on
1436 // the specific nodes
1437 if ((trafficTypeConf == NGMN_MIXED) and
1438 (ngmnGamingIds.find(i) == ngmnGamingIds.end()))
1439 {
1440 continue;
1441 }
1442
1443 Ipv4Address ipAddress = ueSector1IpIface.GetAddress(i, 0);
1444 AddressValue remoteAddress(InetSocketAddress(ipAddress, portNgmnGaming));
1445 trafficGeneratorHelper.SetAttribute("Remote", remoteAddress);
1446 clientApps.Add(trafficGeneratorHelper.Install(remoteHost));
1447 // Seed the ARP cache by pinging early in the simulation
1448 // This is a workaround until a static ARP capability is provided
1449 PingHelper ping(ipAddress);
1450 pingApps.Add(ping.Install(remoteHost));
1451 }
1452 // configure clients on sector 2
1453 for (uint32_t i = 0; i < ueSector2IpIface.GetN(); i++)
1454 {
1455 // in case of NGMN traffic allow installation of the specific traffic type only on
1456 // the specific nodes
1457 if ((trafficTypeConf == NGMN_MIXED) and
1458 (ngmnGamingIds.find(i) == ngmnGamingIds.end()))
1459 {
1460 continue;
1461 }
1462
1463 Ipv4Address ipAddress = ueSector2IpIface.GetAddress(i, 0);
1464 AddressValue remoteAddress(InetSocketAddress(ipAddress, portNgmnGaming));
1465 trafficGeneratorHelper.SetAttribute("Remote", remoteAddress);
1466 clientApps.Add(trafficGeneratorHelper.Install(remoteHost));
1467 // Seed the ARP cache by pinging early in the simulation
1468 // This is a workaround until a static ARP capability is provided
1469 PingHelper ping(ipAddress);
1470 pingApps.Add(ping.Install(remoteHost));
1471 }
1472 // configure clients on sector 3
1473 for (uint32_t i = 0; i < ueSector3IpIface.GetN(); i++)
1474 {
1475 // in case of NGMN traffic allow installation of the specific traffic type only on
1476 // the specific nodes
1477 if ((trafficTypeConf == NGMN_MIXED) and
1478 (ngmnGamingIds.find(i) == ngmnGamingIds.end()))
1479 {
1480 continue;
1481 }
1482
1483 Ipv4Address ipAddress = ueSector3IpIface.GetAddress(i, 0);
1484 AddressValue remoteAddress(InetSocketAddress(ipAddress, portNgmnGaming));
1485 trafficGeneratorHelper.SetAttribute("Remote", remoteAddress);
1486 clientApps.Add(trafficGeneratorHelper.Install(remoteHost));
1487 // Seed the ARP cache by pinging early in the simulation
1488 // This is a workaround until a static ARP capability is provided
1489 PingHelper ping(ipAddress);
1490 pingApps.Add(ping.Install(remoteHost));
1491 }
1492
1493 // configure GAMING servers
1494 InetSocketAddress localAddress(Ipv4Address::GetAny(), portNgmnGaming);
1495 PacketSinkHelper packetSinkHelper(transportProtocol, localAddress);
1496
1497 for (uint32_t index = 0; index < ueSector1IpIface.GetN(); index++)
1498 {
1499 // in case of NGMN traffic we install packet sink for the subset of the nodes
1500 if ((trafficTypeConf == NGMN_MIXED) and
1501 (ngmnGamingIds.find(index) == ngmnGamingIds.end()))
1502 {
1503 continue;
1504 }
1505 serverApps.Add(packetSinkHelper.Install(ueSector1Container.Get(index)));
1506 serverApps.Add(packetSinkHelper.Install(ueSector2Container.Get(index)));
1507 serverApps.Add(packetSinkHelper.Install(ueSector3Container.Get(index)));
1508 }
1509 }
1510 else
1511 {
1512 NS_ABORT_MSG("Not yet supported option of FTP NGMN traffic with the UL traffic in this "
1513 "example. If you need it implement this else block");
1514
1515 // TODO extend
1516 // configure FTP clients with file transfer application that generates multiple file
1517 // transfers
1518 // TrafficGeneratorHelper trafficGeneratorHelper ("ns3::UdpSocketFactory", Address (),
1519 // TrafficGeneratorVideo::GetTypeId ()); trafficGeneratorHelper.SetAttribute
1520 // ("IsDownlink", BooleanValue (false)); trafficGeneratorHelper.SetAttribute
1521 // ("aParamPacketSizeUl", UintegerValue (45)); trafficGeneratorHelper.SetAttribute
1522 // ("bParamPacketSizeUl", DoubleValue (5.7)); trafficGeneratorHelper.SetAttribute
1523 // ("PacketArrivalUl", UintegerValue (40)); trafficGeneratorHelper.SetAttribute
1524 // ("InitialPacketArrivalMin", UintegerValue (0)); trafficGeneratorHelper.SetAttribute
1525 // ("InitialPacketArrivalMax", UintegerValue (40));
1526 }
1527 }
1528
1529 if (trafficTypeConf == NGMN_VOIP || (trafficTypeConf == NGMN_MIXED && !ngmnVoipIds.empty()))
1530 {
1531 uint32_t portNgmnVoip = 5000;
1532 if (direction == "DL")
1533 {
1534 // configure FTP clients with file transfer application that generates multiple file
1535 // transfers
1536 TrafficGeneratorHelper trafficGeneratorHelper(transportProtocol,
1537 Address(),
1539
1540 trafficGeneratorHelper.SetAttribute("EncoderFrameLength", UintegerValue(20));
1541 trafficGeneratorHelper.SetAttribute("MeanTalkSpurtDuration", UintegerValue(2000));
1542 trafficGeneratorHelper.SetAttribute("VoiceActivityFactor", DoubleValue(0.5));
1543 trafficGeneratorHelper.SetAttribute("VoicePayload", UintegerValue(40));
1544 trafficGeneratorHelper.SetAttribute("SIDPeriodicity", UintegerValue(160));
1545 trafficGeneratorHelper.SetAttribute("SIDPayload", UintegerValue(15));
1546
1547 // configure clients on sector 1
1548 for (uint32_t i = 0; i < ueSector1IpIface.GetN(); i++)
1549 {
1550 // in case of NGMN traffic allow installation of the specific traffic type only on
1551 // the specific nodes
1552 if ((trafficTypeConf == NGMN_MIXED) and (ngmnVoipIds.find(i) == ngmnVoipIds.end()))
1553 {
1554 continue;
1555 }
1556
1557 Ipv4Address ipAddress = ueSector1IpIface.GetAddress(i, 0);
1558 AddressValue remoteAddress(InetSocketAddress(ipAddress, portNgmnVoip));
1559 trafficGeneratorHelper.SetAttribute("Remote", remoteAddress);
1560 clientApps.Add(trafficGeneratorHelper.Install(remoteHost));
1561 // Seed the ARP cache by pinging early in the simulation
1562 // This is a workaround until a static ARP capability is provided
1563 PingHelper ping(ipAddress);
1564 pingApps.Add(ping.Install(remoteHost));
1565 }
1566 // configure clients on sector 2
1567 for (uint32_t i = 0; i < ueSector2IpIface.GetN(); i++)
1568 {
1569 // in case of NGMN traffic allow installation of the specific traffic type only on
1570 // the specific nodes
1571 if ((trafficTypeConf == NGMN_MIXED) and (ngmnVoipIds.find(i) == ngmnVoipIds.end()))
1572 {
1573 continue;
1574 }
1575
1576 Ipv4Address ipAddress = ueSector2IpIface.GetAddress(i, 0);
1577 AddressValue remoteAddress(InetSocketAddress(ipAddress, portNgmnVoip));
1578 trafficGeneratorHelper.SetAttribute("Remote", remoteAddress);
1579 clientApps.Add(trafficGeneratorHelper.Install(remoteHost));
1580 // Seed the ARP cache by pinging early in the simulation
1581 // This is a workaround until a static ARP capability is provided
1582 PingHelper ping(ipAddress);
1583 pingApps.Add(ping.Install(remoteHost));
1584 }
1585 // configure clients on sector 3
1586 for (uint32_t i = 0; i < ueSector3IpIface.GetN(); i++)
1587 {
1588 // in case of NGMN traffic allow installation of the specific traffic type only on
1589 // the specific nodes
1590 if ((trafficTypeConf == NGMN_MIXED) and (ngmnVoipIds.find(i) == ngmnVoipIds.end()))
1591 {
1592 continue;
1593 }
1594
1595 Ipv4Address ipAddress = ueSector3IpIface.GetAddress(i, 0);
1596 AddressValue remoteAddress(InetSocketAddress(ipAddress, portNgmnVoip));
1597 trafficGeneratorHelper.SetAttribute("Remote", remoteAddress);
1598 clientApps.Add(trafficGeneratorHelper.Install(remoteHost));
1599 // Seed the ARP cache by pinging early in the simulation
1600 // This is a workaround until a static ARP capability is provided
1601 PingHelper ping(ipAddress);
1602 pingApps.Add(ping.Install(remoteHost));
1603 }
1604
1605 // configure servers
1606 InetSocketAddress localAddress(Ipv4Address::GetAny(), portNgmnVoip);
1607 PacketSinkHelper packetSinkHelper(transportProtocol, localAddress);
1608
1609 for (uint32_t index = 0; index < ueSector1IpIface.GetN(); index++)
1610 {
1611 // in case of NGMN traffic we install packet sink for the subset of the nodes
1612 if ((trafficTypeConf == NGMN_MIXED) and
1613 (ngmnVoipIds.find(index) == ngmnVoipIds.end()))
1614 {
1615 continue;
1616 }
1617 serverApps.Add(packetSinkHelper.Install(ueSector1Container.Get(index)));
1618 serverApps.Add(packetSinkHelper.Install(ueSector2Container.Get(index)));
1619 serverApps.Add(packetSinkHelper.Install(ueSector3Container.Get(index)));
1620 }
1621 }
1622 else
1623 {
1624 NS_ABORT_MSG("Not yet supported option of NGMN VOIP traffic with the UL traffic in "
1625 "this example. If you need it implement this else block");
1626
1627 // TODO extend
1628 // configure FTP clients with file transfer application that generates multiple file
1629 // transfers
1630 // TrafficGeneratorHelper trafficGeneratorHelper ("ns3::UdpSocketFactory", Address (),
1631 // TrafficGeneratorVideo::GetTypeId ()); trafficGeneratorHelper.SetAttribute
1632 // ("IsDownlink", BooleanValue (false)); trafficGeneratorHelper.SetAttribute
1633 // ("aParamPacketSizeUl", UintegerValue (45)); trafficGeneratorHelper.SetAttribute
1634 // ("bParamPacketSizeUl", DoubleValue (5.7)); trafficGeneratorHelper.SetAttribute
1635 // ("PacketArrivalUl", UintegerValue (40)); trafficGeneratorHelper.SetAttribute
1636 // ("InitialPacketArrivalMin", UintegerValue (0)); trafficGeneratorHelper.SetAttribute
1637 // ("InitialPacketArrivalMax", UintegerValue (40));
1638 }
1639 }
1640
1641 if (trafficTypeConf == NGMN_HTTP || (trafficTypeConf == NGMN_MIXED && !ngmnHttpIds.empty()))
1642 {
1643 // uint32_t portNgmnHttp = 7000;
1644 // the way how ThreeGppHttpClient and ThreeGppHttpServer are implemented in ns-3
1645 // it seems that the client should be installed on UEs and server on remote host
1646
1647 NodeContainer httpUeContainer;
1648
1649 for (uint32_t i = 0; i < ueSector1Container.GetN(); i++)
1650 {
1651 // in case of NGMN traffic allow installation of the specific traffic type only on the
1652 // specific nodes
1653 if ((trafficTypeConf == NGMN_MIXED) and (ngmnHttpIds.find(i) == ngmnHttpIds.end()))
1654 {
1655 continue;
1656 }
1657 httpUeContainer.Add(ueSector1Container.Get(i));
1658 httpUeContainer.Add(ueSector2Container.Get(i));
1659 httpUeContainer.Add(ueSector3Container.Get(i));
1660 }
1661
1662 // 1. Create HTTP client applications
1663 ThreeGppHttpClientHelper clientHelper(remoteHostIpv4Address);
1664 // Install HTTP clients on UEs
1665 ApplicationContainer clientApps = clientHelper.Install(httpUeContainer);
1666
1667 // 2. Create HTTP server applications
1668 ThreeGppHttpServerHelper serverHelper(remoteHostIpv4Address);
1669 // Install HTTP server on a remote host node
1670 ApplicationContainer serverApps = serverHelper.Install(remoteHost);
1671 Ptr<ThreeGppHttpServer> httpServer = serverApps.Get(0)->GetObject<ThreeGppHttpServer>();
1672
1673 // 3. Setup HTTP variables for the server according to NGMN white paper
1674 PointerValue ptrVal;
1675 httpServer->GetAttribute("Variables", ptrVal);
1676 Ptr<ThreeGppHttpVariables> httpParameters = ptrVal.Get<ThreeGppHttpVariables>();
1677 httpParameters->SetMainObjectSizeMean(10710); // according to NGMN white paper
1678 httpParameters->SetMainObjectSizeStdDev(25032); // according to NGMN white paper
1679 httpParameters->SetEmbeddedObjectSizeMean(7758); // according to NGMN white paper
1680 httpParameters->SetEmbeddedObjectSizeStdDev(126168);
1681 httpParameters->SetNumOfEmbeddedObjectsMax(55); // according to NGMN white paper
1682 httpParameters->SetNumOfEmbeddedObjectsScale(2); // according to NGMN white paper
1683 httpParameters->SetNumOfEmbeddedObjectsShape(1.1); // according to NGMN white paper
1684 httpParameters->SetReadingTimeMean(Seconds(30)); // according to NGMN white paper
1685 httpParameters->SetParsingTimeMean(Seconds(0.13)); // according to NGMN white paper
1686
1687 for (uint32_t i = 0; i < ueSector1IpIface.GetN(); i++)
1688 {
1689 // in case of NGMN traffic allow installation of the specific traffic type only on the
1690 // specific nodes
1691 if ((trafficTypeConf == NGMN_MIXED) and (ngmnHttpIds.find(i) == ngmnHttpIds.end()))
1692 {
1693 continue;
1694 }
1695
1696 Ipv4Address ipAddress = ueSector1IpIface.GetAddress(i, 0);
1697 PingHelper ping(ipAddress);
1698 pingApps.Add(ping.Install(remoteHost));
1699 }
1700 // configure clients on sector 2
1701 for (uint32_t i = 0; i < ueSector2IpIface.GetN(); i++)
1702 {
1703 // in case of NGMN traffic allow installation of the specific traffic type only on the
1704 // specific nodes
1705 if ((trafficTypeConf == NGMN_MIXED) and (ngmnHttpIds.find(i) == ngmnHttpIds.end()))
1706 {
1707 continue;
1708 }
1709
1710 Ipv4Address ipAddress = ueSector2IpIface.GetAddress(i, 0);
1711 PingHelper ping(ipAddress);
1712 pingApps.Add(ping.Install(remoteHost));
1713 }
1714 // configure clients on sector 3
1715 for (uint32_t i = 0; i < ueSector3IpIface.GetN(); i++)
1716 {
1717 // in case of NGMN traffic allow installation of the specific traffic type only on the
1718 // specific nodes
1719 if ((trafficTypeConf == NGMN_MIXED) and (ngmnHttpIds.find(i) == ngmnHttpIds.end()))
1720 {
1721 continue;
1722 }
1723
1724 Ipv4Address ipAddress = ueSector3IpIface.GetAddress(i, 0);
1725 PingHelper ping(ipAddress);
1726 pingApps.Add(ping.Install(remoteHost));
1727 }
1728 }
1729
1730 if (trafficTypeConf == UDP_CBR)
1731 {
1732 for (uint32_t i = 0; i < ueSector1Container.GetN(); ++i)
1733 {
1734 dlClientLowLat.SetAttribute(
1735 "Interval",
1736 TimeValue(Seconds(1.0 / lambdaPerCell[(i % gridScenario.GetNumSites()) *
1737 gridScenario.GetNumSectorsPerSite()])));
1738 std::cout << "ue (sector1): " << i << " index: "
1739 << (i % gridScenario.GetNumSites()) * gridScenario.GetNumSectorsPerSite()
1740 << " lambda: "
1741 << lambdaPerCell[(i % gridScenario.GetNumSites()) *
1742 gridScenario.GetNumSectorsPerSite()]
1743 << std::endl;
1744 Ptr<Node> ue = ueSector1Container.Get(i);
1745 Ptr<NetDevice> ueDevice = ueSector1NetDev.Get(i);
1746 Address ueAddress = ueSector1IpIface.GetAddress(i);
1747
1748 // The client, who is transmitting, is installed in the remote host,
1749 // with destination address set to the address of the UE
1750 if (direction == "DL")
1751 {
1752 dlClientLowLat.SetAttribute(
1753 "Remote",
1754 AddressValue(addressUtils::ConvertToSocketAddress(ueAddress, dlPortLowLat)));
1755 clientApps.Add(dlClientLowLat.Install(remoteHost));
1756 }
1757 else
1758 {
1759 dlClientLowLat.SetAttribute(
1760 "Remote",
1761 AddressValue(
1762 addressUtils::ConvertToSocketAddress(remoteHostIpv4Address, dlPortLowLat)));
1763 clientApps.Add(dlClientLowLat.Install(ue));
1764 }
1765 // Activate a dedicated bearer for the traffic type
1766 nrHelper->ActivateDedicatedEpsBearer(ueDevice, lowLatBearer, lowLatTft);
1767 }
1768
1769 for (uint32_t i = 0; i < ueSector2Container.GetN(); ++i)
1770 {
1771 dlClientLowLat.SetAttribute(
1772 "Interval",
1773 TimeValue(Seconds(1.0 / lambdaPerCell[(i % gridScenario.GetNumSites()) *
1774 gridScenario.GetNumSectorsPerSite() +
1775 1])));
1776 std::cout << "ue (sector2): " << i << " index: "
1777 << (i % gridScenario.GetNumSites()) * gridScenario.GetNumSectorsPerSite() + 1
1778 << " lambda: "
1779 << lambdaPerCell[(i % gridScenario.GetNumSites()) *
1780 gridScenario.GetNumSectorsPerSite() +
1781 1]
1782 << std::endl;
1783 Ptr<Node> ue = ueSector2Container.Get(i);
1784 Ptr<NetDevice> ueDevice = ueSector2NetDev.Get(i);
1785 Address ueAddress = ueSector2IpIface.GetAddress(i);
1786
1787 // The client, who is transmitting, is instaviso entonces pronto, sualled in the remote
1788 // host, with destination address set to the address of the UE
1789 if (direction == "DL")
1790 {
1791 dlClientLowLat.SetAttribute(
1792 "Remote",
1793 AddressValue(addressUtils::ConvertToSocketAddress(ueAddress, dlPortLowLat)));
1794 clientApps.Add(dlClientLowLat.Install(remoteHost));
1795 }
1796 else
1797 {
1798 dlClientLowLat.SetAttribute(
1799 "Remote",
1800 AddressValue(
1801 addressUtils::ConvertToSocketAddress(remoteHostIpv4Address, dlPortLowLat)));
1802 clientApps.Add(dlClientLowLat.Install(ue));
1803 }
1804 // Activate a dedicated bearer for the traffic type
1805 nrHelper->ActivateDedicatedEpsBearer(ueDevice, lowLatBearer, lowLatTft);
1806 }
1807
1808 for (uint32_t i = 0; i < ueSector3Container.GetN(); ++i)
1809 {
1810 dlClientLowLat.SetAttribute(
1811 "Interval",
1812 TimeValue(Seconds(1.0 / lambdaPerCell[(i % gridScenario.GetNumSites()) *
1813 gridScenario.GetNumSectorsPerSite() +
1814 2])));
1815 std::cout << "ue (sector3): " << i << " index: "
1816 << (i % gridScenario.GetNumSites()) * gridScenario.GetNumSectorsPerSite() + 2
1817 << " lambda: "
1818 << lambdaPerCell[(i % gridScenario.GetNumSites()) *
1819 gridScenario.GetNumSectorsPerSite() +
1820 2]
1821 << std::endl;
1822 Ptr<Node> ue = ueSector3Container.Get(i);
1823 Ptr<NetDevice> ueDevice = ueSector3NetDev.Get(i);
1824 Address ueAddress = ueSector3IpIface.GetAddress(i);
1825
1826 // The client, who is transmitting, is installed in the remote host,
1827 // with destination address set to the address of the UE
1828 if (direction == "DL")
1829 {
1830 dlClientLowLat.SetAttribute(
1831 "Remote",
1832 AddressValue(addressUtils::ConvertToSocketAddress(ueAddress, dlPortLowLat)));
1833 clientApps.Add(dlClientLowLat.Install(remoteHost));
1834 }
1835 else
1836 {
1837 dlClientLowLat.SetAttribute(
1838 "Remote",
1839 AddressValue(
1840 addressUtils::ConvertToSocketAddress(remoteHostIpv4Address, dlPortLowLat)));
1841 clientApps.Add(dlClientLowLat.Install(ue));
1842 }
1843 // Activate a dedicated bearer for the traffic type
1844 nrHelper->ActivateDedicatedEpsBearer(ueDevice, lowLatBearer, lowLatTft);
1845 }
1846 }
1847
1848 // Add one or two pings for ARP at the beginning of the simulation
1849 pingApps.Start(Seconds(0.300));
1850 pingApps.Stop(Seconds(0.500));
1851 serverApps.Start(serverAppStartTime);
1852 serverApps.Stop(simTime - MilliSeconds(400));
1853 clientApps.Start(clientAppStartTime);
1854 clientApps.Stop(simTime - MilliSeconds(400));
1855
1856 // enable the traces provided by the nr module
1857 if (traces)
1858 {
1859 nrHelper->EnableTraces();
1860 }
1861
1862 FlowMonitorHelper flowmonHelper;
1863 NodeContainer endpointNodes;
1864 endpointNodes.Add(remoteHost);
1865 endpointNodes.Add(gridScenario.GetUserTerminals());
1866
1867 Ptr<ns3::FlowMonitor> monitor = flowmonHelper.Install(endpointNodes);
1868 monitor->SetAttribute("DelayBinWidth", DoubleValue(0.001));
1869 monitor->SetAttribute("JitterBinWidth", DoubleValue(0.001));
1870 monitor->SetAttribute("PacketSizeBinWidth", DoubleValue(20));
1871
1872 Simulator::Stop(simTime);
1873 Simulator::Run();
1874
1875 // Print per-flow statistics
1876 monitor->CheckForLostPackets();
1877 Ptr<Ipv4FlowClassifier> classifier =
1878 DynamicCast<Ipv4FlowClassifier>(flowmonHelper.GetClassifier());
1879 FlowMonitor::FlowStatsContainer stats = monitor->GetFlowStats();
1880
1881 double averageFlowThroughput = 0.0;
1882 double averageFlowDelay = 0.0;
1883
1884 std::ofstream outFile;
1885 std::string filename = outputDir + "/" + simTag;
1886 std::vector<double> delayValues(stats.size());
1887 uint64_t cont = 0;
1888
1889 outFile.open(filename.c_str(), std::ofstream::out | std::ofstream::trunc);
1890 if (!outFile.is_open())
1891 {
1892 std::cerr << "Can't open file " << filename << std::endl;
1893 return 1;
1894 }
1895
1896 outFile.setf(std::ios_base::fixed);
1897
1898 for (std::map<FlowId, FlowMonitor::FlowStats>::const_iterator i = stats.begin();
1899 i != stats.end();
1900 ++i)
1901 {
1902 Ipv4FlowClassifier::FiveTuple t = classifier->FindFlow(i->first);
1903 std::stringstream protoStream;
1904 protoStream << (uint16_t)t.protocol;
1905 if (t.protocol == 6)
1906 {
1907 protoStream.str("TCP");
1908 }
1909 if (t.protocol == 17)
1910 {
1911 protoStream.str("UDP");
1912 }
1913 std::cout << "Flow " << i->first << " (" << t.sourceAddress << ":" << t.sourcePort << " -> "
1914 << t.destinationAddress << ":" << t.destinationPort << ") proto "
1915 << protoStream.str() << "\n";
1916 std::cout << " Tx Packets: " << i->second.txPackets << "\n";
1917 std::cout << " Tx Bytes: " << i->second.txBytes << "\n";
1918 std::cout << " TxOffered: "
1919 << i->second.txBytes * 8.0 / (simTime - appStartTime).GetSeconds() / 1000.0 /
1920 1000.0
1921 << " Mbps\n";
1922 std::cout << " Rx Packets: " << i->second.rxPackets << "\n";
1923 std::cout << " Rx Bytes: " << i->second.rxBytes << "\n";
1924 if (i->second.rxPackets > 0)
1925 {
1926 // Measure the duration of the flow from receiver's perspective
1927 // double rxDuration = i->second.timeLastRxPacket.GetSeconds () -
1928 // i->second.timeFirstTxPacket.GetSeconds ();
1929 double rxDuration =
1930 (i->second.timeLastRxPacket - i->second.timeFirstRxPacket).GetSeconds();
1931
1932 averageFlowThroughput += i->second.rxBytes * 8.0 / rxDuration / 1000 / 1000;
1933 averageFlowDelay += 1000 * i->second.delaySum.GetSeconds() / i->second.rxPackets;
1934 delayValues[cont] = 1000 * i->second.delaySum.GetSeconds() / i->second.rxPackets;
1935 cont++;
1936
1937 std::cout << " Throughput: " << i->second.rxBytes * 8.0 / rxDuration / 1000 / 1000
1938 << " Mbps\n";
1939 std::cout << " Mean delay: "
1940 << double(1000 * i->second.delaySum.GetSeconds()) / (i->second.rxPackets)
1941 << " ms\n";
1942 std::cout << " Last packet delay: " << i->second.lastDelay.As(Time::MS) << "\n";
1943 // std::cout << " Mean upt: " << i->second.uptSum / i->second.rxPackets / 1000/1000 <<
1944 // " Mbps \n";
1945 std::cout << " Mean jitter: "
1946 << 1000 * i->second.jitterSum.GetSeconds() / i->second.rxPackets << " ms\n";
1947 }
1948 else
1949 {
1950 // outFile << " Throughput: 0 Mbps\n";
1951 // outFile << " Mean delay: 0 ms\n";
1952 // outFile << " Mean jitter: 0 ms\n";
1953 }
1954 // outFile << " Rx Packets: " << i->second.rxPackets << "\n";
1955 }
1956 std::stable_sort(delayValues.begin(), delayValues.end());
1957 // for (uint32_t i = 0; i < stats.size(); i++)
1958 // {
1959 // std::cout << delayValues[i] << " ";
1960 // }
1961 // double FiftyTileFlowDelay = (delayValues[stats.size()/2] + delayValues[stats.size()/2 -1])/2;
1962 double FiftyTileFlowDelay = delayValues[stats.size() / 2];
1963
1964 outFile << "\n\n Mean flow throughput: " << averageFlowThroughput / stats.size() << "\n";
1965 outFile << " Mean flow delay: " << averageFlowDelay / stats.size() << "\n";
1966 outFile << " Median flow delay: " << FiftyTileFlowDelay << "\n";
1967
1968 outFile.close();
1969
1970 std::ifstream f(filename.c_str());
1971
1972 if (f.is_open())
1973 {
1974 std::cout << f.rdbuf();
1975 }
1976
1977 Simulator::Destroy();
1978 return 0;
1979}
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.
static TypeId GetTypeId()
Get the type id.
The HexagonalGridScenarioHelper class.
void CreateScenario() override
Create the scenario, with the configured parameter.
void SetNumRings(uint8_t numRings)
Sets the number of outer rings of sites around the central site.
const NodeContainer & GetUserTerminals() const
Get the list of user nodes.
std::size_t GetNumSites() const
Gets the number of sites with cell base stations.
void SetUtNumber(std::size_t n)
Set the number of UT/UE.
std::size_t GetNumCells() const
Gets the total number of cells deployed.
const NodeContainer & GetBaseStations() const
Get the list of gnb/base station nodes.
double GetAntennaOrientationRadians(std::size_t cellId) const
Returns the orientation in radians of the antenna array for the given cellId.
@ ErrorModel
Error Model version (can use different error models, see NrErrorModel)
Definition nr-amc.h:81
This class contains the specification of EPS Bearers.
@ NGBR_VIDEO_TCP_DEFAULT
Non-GBR TCP-based Video (Buffered Streaming, e.g., www, e-mail...)
uint32_t GetNumSectorsPerSite() const
Gets the number of sectors per site.
void SetSectorization(SiteSectorizationType numSectors)
Sets the number of sectors of every site.
void SetScenarioParameters(const std::string &scenario)
Sets parameters to the specified scenario.
A helper to make it easier to instantiate an ns3::TrafficGenerator types of applications on a set of ...
static TypeId GetTypeId()
Get the type ID.
static TypeId GetTypeId()
Get the type ID.
static TypeId GetTypeId()
Get the type ID.
static std::ostream & operator<<(std::ostream &os, const TrafficTypeConf &item)
operator << for TrafficTypeConf
void Set5gLenaSimulatorParameters(HexagonalGridScenarioHelper gridScenario, std::string scenario, std::string radioNetwork, std::string operationMode, std::string direction, NodeContainer gnbSector1Container, NodeContainer gnbSector2Container, NodeContainer gnbSector3Container, NodeContainer ueSector1Container, NodeContainer ueSector2Container, NodeContainer ueSector3Container, Ptr< NrPointToPointEpcHelper > &baseNrEpcHelper, Ptr< NrHelper > &nrHelper, NetDeviceContainer &gnbSector1NetDev, NetDeviceContainer &gnbSector2NetDev, NetDeviceContainer &gnbSector3NetDev, NetDeviceContainer &ueSector1NetDev, NetDeviceContainer &ueSector2NetDev, NetDeviceContainer &ueSector3NetDev, bool uniformLambda)
std::vector< std::reference_wrapper< BandwidthPartInfoPtr > > BandwidthPartInfoPtrVector
vector of unique_ptr of BandwidthPartInfo
Minimum configuration requirements for a OperationBand.
uint8_t m_numBwp
Number of BWP per CC.
Direction direction
Whether the filter needs to be applied to uplink / downlink only, or in both cases.
Definition nr-epc-tft.h:104
uint16_t remotePortEnd
end of the port number range of the remote host
Definition nr-epc-tft.h:117
uint16_t localPortStart
start of the port number range of the UE
Definition nr-epc-tft.h:118
uint16_t remotePortStart
start of the port number range of the remote host
Definition nr-epc-tft.h:116
uint16_t localPortEnd
end of the port number range of the UE
Definition nr-epc-tft.h:119
Operation band information structure.