1 /* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
2 /*
3 * Copyright (c) 2012 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation;
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * Author: Nicola Baldo <nbaldo@cttc.es>
19 */
20
21 #include <ns3/core-module.h>
22 #include <ns3/network-module.h>
23 #include <ns3/mobility-module.h>
24 #include <ns3/internet-module.h>
25 #include <ns3/lte-module.h>
26 #include <ns3/config-store-module.h>
27 #include <ns3/buildings-module.h>
28 #include <ns3/point-to-point-helper.h>
29 #include <ns3/applications-module.h>
30 #include <ns3/log.h>
31 #include <iomanip>
32 #include <ios>
33 #include <string>
34 #include <vector>
35
36 // The topology of this simulation program is inspired from
37 // 3GPP R4-092042, Section 4.2.1 Dual Stripe Model
38 // note that the term "apartments" used in that document matches with
39 // the term "room" used in the BuildingsMobilityModel
40
41 using namespace ns3;
42
43 NS_LOG_COMPONENT_DEFINE ("LenaDualStripe");
44
AreOverlapping(Box a,Box b)45 bool AreOverlapping (Box a, Box b)
46 {
47 return !((a.xMin > b.xMax) || (b.xMin > a.xMax) || (a.yMin > b.yMax) || (b.yMin > a.yMax));
48 }
49
50 /**
51 * Class that takes care of installing blocks of the
52 * buildings in a given area. Buildings are installed in pairs
53 * as in dual stripe scenario.
54 */
55 class FemtocellBlockAllocator
56 {
57 public:
58 /**
59 * Constructor
60 * \param area the total area
61 * \param nApartmentsX the number of apartments in the X direction
62 * \param nFloors the number of floors
63 */
64 FemtocellBlockAllocator (Box area, uint32_t nApartmentsX, uint32_t nFloors);
65 /**
66 * Function that creates building blocks.
67 * \param n the number of blocks to create
68 */
69 void Create (uint32_t n);
70 /// Create function
71 void Create ();
72
73 private:
74 /**
75 * Function that checks if the box area is overlapping with some of previously created building blocks.
76 * \param box the area to check
77 * \returns true if there is an overlap
78 */
79 bool OverlapsWithAnyPrevious (Box box);
80 Box m_area; ///< Area
81 uint32_t m_nApartmentsX; ///< X apartments
82 uint32_t m_nFloors; ///< number of floors
83 std::list<Box> m_previousBlocks; ///< previous bocks
84 double m_xSize; ///< X size
85 double m_ySize; ///< Y size
86 Ptr<UniformRandomVariable> m_xMinVar; ///< X minimum variance
87 Ptr<UniformRandomVariable> m_yMinVar; ///< Y minimum variance
88
89 };
90
FemtocellBlockAllocator(Box area,uint32_t nApartmentsX,uint32_t nFloors)91 FemtocellBlockAllocator::FemtocellBlockAllocator (Box area, uint32_t nApartmentsX, uint32_t nFloors)
92 : m_area (area),
93 m_nApartmentsX (nApartmentsX),
94 m_nFloors (nFloors),
95 m_xSize (nApartmentsX*10 + 20),
96 m_ySize (70)
97 {
98 m_xMinVar = CreateObject<UniformRandomVariable> ();
99 m_xMinVar->SetAttribute ("Min", DoubleValue (area.xMin));
100 m_xMinVar->SetAttribute ("Max", DoubleValue (area.xMax - m_xSize));
101 m_yMinVar = CreateObject<UniformRandomVariable> ();
102 m_yMinVar->SetAttribute ("Min", DoubleValue (area.yMin));
103 m_yMinVar->SetAttribute ("Max", DoubleValue (area.yMax - m_ySize));
104 }
105
106 void
Create(uint32_t n)107 FemtocellBlockAllocator::Create (uint32_t n)
108 {
109 for (uint32_t i = 0; i < n; ++i)
110 {
111 Create ();
112 }
113 }
114
115 void
Create()116 FemtocellBlockAllocator::Create ()
117 {
118 Box box;
119 uint32_t attempt = 0;
120 do
121 {
122 NS_ASSERT_MSG (attempt < 100, "Too many failed attempts to position apartment block. Too many blocks? Too small area?");
123 box.xMin = m_xMinVar->GetValue ();
124 box.xMax = box.xMin + m_xSize;
125 box.yMin = m_yMinVar->GetValue ();
126 box.yMax = box.yMin + m_ySize;
127 ++attempt;
128 }
129 while (OverlapsWithAnyPrevious (box));
130
131 NS_LOG_LOGIC ("allocated non overlapping block " << box);
132 m_previousBlocks.push_back (box);
133 Ptr<GridBuildingAllocator> gridBuildingAllocator;
134 gridBuildingAllocator = CreateObject<GridBuildingAllocator> ();
135 gridBuildingAllocator->SetAttribute ("GridWidth", UintegerValue (1));
136 gridBuildingAllocator->SetAttribute ("LengthX", DoubleValue (10*m_nApartmentsX));
137 gridBuildingAllocator->SetAttribute ("LengthY", DoubleValue (10*2));
138 gridBuildingAllocator->SetAttribute ("DeltaX", DoubleValue (10));
139 gridBuildingAllocator->SetAttribute ("DeltaY", DoubleValue (10));
140 gridBuildingAllocator->SetAttribute ("Height", DoubleValue (3*m_nFloors));
141 gridBuildingAllocator->SetBuildingAttribute ("NRoomsX", UintegerValue (m_nApartmentsX));
142 gridBuildingAllocator->SetBuildingAttribute ("NRoomsY", UintegerValue (2));
143 gridBuildingAllocator->SetBuildingAttribute ("NFloors", UintegerValue (m_nFloors));
144 gridBuildingAllocator->SetAttribute ("MinX", DoubleValue (box.xMin + 10));
145 gridBuildingAllocator->SetAttribute ("MinY", DoubleValue (box.yMin + 10));
146 gridBuildingAllocator->Create (2);
147 }
148
149 bool
OverlapsWithAnyPrevious(Box box)150 FemtocellBlockAllocator::OverlapsWithAnyPrevious (Box box)
151 {
152 for (std::list<Box>::iterator it = m_previousBlocks.begin (); it != m_previousBlocks.end (); ++it)
153 {
154 if (AreOverlapping (*it, box))
155 {
156 return true;
157 }
158 }
159 return false;
160 }
161
162 void
PrintGnuplottableBuildingListToFile(std::string filename)163 PrintGnuplottableBuildingListToFile (std::string filename)
164 {
165 std::ofstream outFile;
166 outFile.open (filename.c_str (), std::ios_base::out | std::ios_base::trunc);
167 if (!outFile.is_open ())
168 {
169 NS_LOG_ERROR ("Can't open file " << filename);
170 return;
171 }
172 uint32_t index = 0;
173 for (BuildingList::Iterator it = BuildingList::Begin (); it != BuildingList::End (); ++it)
174 {
175 ++index;
176 Box box = (*it)->GetBoundaries ();
177 outFile << "set object " << index
178 << " rect from " << box.xMin << "," << box.yMin
179 << " to " << box.xMax << "," << box.yMax
180 << " front fs empty "
181 << std::endl;
182 }
183 }
184
185 void
PrintGnuplottableUeListToFile(std::string filename)186 PrintGnuplottableUeListToFile (std::string filename)
187 {
188 std::ofstream outFile;
189 outFile.open (filename.c_str (), std::ios_base::out | std::ios_base::trunc);
190 if (!outFile.is_open ())
191 {
192 NS_LOG_ERROR ("Can't open file " << filename);
193 return;
194 }
195 for (NodeList::Iterator it = NodeList::Begin (); it != NodeList::End (); ++it)
196 {
197 Ptr<Node> node = *it;
198 int nDevs = node->GetNDevices ();
199 for (int j = 0; j < nDevs; j++)
200 {
201 Ptr<LteUeNetDevice> uedev = node->GetDevice (j)->GetObject <LteUeNetDevice> ();
202 if (uedev)
203 {
204 Vector pos = node->GetObject<MobilityModel> ()->GetPosition ();
205 outFile << "set label \"" << uedev->GetImsi ()
206 << "\" at "<< pos.x << "," << pos.y << " left font \"Helvetica,4\" textcolor rgb \"grey\" front point pt 1 ps 0.3 lc rgb \"grey\" offset 0,0"
207 << std::endl;
208 }
209 }
210 }
211 }
212
213 void
PrintGnuplottableEnbListToFile(std::string filename)214 PrintGnuplottableEnbListToFile (std::string filename)
215 {
216 std::ofstream outFile;
217 outFile.open (filename.c_str (), std::ios_base::out | std::ios_base::trunc);
218 if (!outFile.is_open ())
219 {
220 NS_LOG_ERROR ("Can't open file " << filename);
221 return;
222 }
223 for (NodeList::Iterator it = NodeList::Begin (); it != NodeList::End (); ++it)
224 {
225 Ptr<Node> node = *it;
226 int nDevs = node->GetNDevices ();
227 for (int j = 0; j < nDevs; j++)
228 {
229 Ptr<LteEnbNetDevice> enbdev = node->GetDevice (j)->GetObject <LteEnbNetDevice> ();
230 if (enbdev)
231 {
232 Vector pos = node->GetObject<MobilityModel> ()->GetPosition ();
233 outFile << "set label \"" << enbdev->GetCellId ()
234 << "\" at "<< pos.x << "," << pos.y
235 << " left font \"Helvetica,4\" textcolor rgb \"white\" front point pt 2 ps 0.3 lc rgb \"white\" offset 0,0"
236 << std::endl;
237 }
238 }
239 }
240 }
241
242
243 static ns3::GlobalValue g_nBlocks ("nBlocks",
244 "Number of femtocell blocks",
245 ns3::UintegerValue (1),
246 ns3::MakeUintegerChecker<uint32_t> ());
247 static ns3::GlobalValue g_nApartmentsX ("nApartmentsX",
248 "Number of apartments along the X axis in a femtocell block",
249 ns3::UintegerValue (10),
250 ns3::MakeUintegerChecker<uint32_t> ());
251 static ns3::GlobalValue g_nFloors ("nFloors",
252 "Number of floors",
253 ns3::UintegerValue (1),
254 ns3::MakeUintegerChecker<uint32_t> ());
255 static ns3::GlobalValue g_nMacroEnbSites ("nMacroEnbSites",
256 "How many macro sites there are",
257 ns3::UintegerValue (3),
258 ns3::MakeUintegerChecker<uint32_t> ());
259 static ns3::GlobalValue g_nMacroEnbSitesX ("nMacroEnbSitesX",
260 "(minimum) number of sites along the X-axis of the hex grid",
261 ns3::UintegerValue (1),
262 ns3::MakeUintegerChecker<uint32_t> ());
263 static ns3::GlobalValue g_interSiteDistance ("interSiteDistance",
264 "min distance between two nearby macro cell sites",
265 ns3::DoubleValue (500),
266 ns3::MakeDoubleChecker<double> ());
267 static ns3::GlobalValue g_areaMarginFactor ("areaMarginFactor",
268 "how much the UE area extends outside the macrocell grid, "
269 "expressed as fraction of the interSiteDistance",
270 ns3::DoubleValue (0.5),
271 ns3::MakeDoubleChecker<double> ());
272 static ns3::GlobalValue g_macroUeDensity ("macroUeDensity",
273 "How many macrocell UEs there are per square meter",
274 ns3::DoubleValue (0.00002),
275 ns3::MakeDoubleChecker<double> ());
276 static ns3::GlobalValue g_homeEnbDeploymentRatio ("homeEnbDeploymentRatio",
277 "The HeNB deployment ratio as per 3GPP R4-092042",
278 ns3::DoubleValue (0.2),
279 ns3::MakeDoubleChecker<double> ());
280 static ns3::GlobalValue g_homeEnbActivationRatio ("homeEnbActivationRatio",
281 "The HeNB activation ratio as per 3GPP R4-092042",
282 ns3::DoubleValue (0.5),
283 ns3::MakeDoubleChecker<double> ());
284 static ns3::GlobalValue g_homeUesHomeEnbRatio ("homeUesHomeEnbRatio",
285 "How many (on average) home UEs per HeNB there are in the simulation",
286 ns3::DoubleValue (1.0),
287 ns3::MakeDoubleChecker<double> ());
288 static ns3::GlobalValue g_macroEnbTxPowerDbm ("macroEnbTxPowerDbm",
289 "TX power [dBm] used by macro eNBs",
290 ns3::DoubleValue (46.0),
291 ns3::MakeDoubleChecker<double> ());
292 static ns3::GlobalValue g_homeEnbTxPowerDbm ("homeEnbTxPowerDbm",
293 "TX power [dBm] used by HeNBs",
294 ns3::DoubleValue (20.0),
295 ns3::MakeDoubleChecker<double> ());
296 static ns3::GlobalValue g_macroEnbDlEarfcn ("macroEnbDlEarfcn",
297 "DL EARFCN used by macro eNBs",
298 ns3::UintegerValue (100),
299 ns3::MakeUintegerChecker<uint16_t> ());
300 static ns3::GlobalValue g_homeEnbDlEarfcn ("homeEnbDlEarfcn",
301 "DL EARFCN used by HeNBs",
302 ns3::UintegerValue (100),
303 ns3::MakeUintegerChecker<uint16_t> ());
304 static ns3::GlobalValue g_macroEnbBandwidth ("macroEnbBandwidth",
305 "bandwidth [num RBs] used by macro eNBs",
306 ns3::UintegerValue (25),
307 ns3::MakeUintegerChecker<uint16_t> ());
308 static ns3::GlobalValue g_homeEnbBandwidth ("homeEnbBandwidth",
309 "bandwidth [num RBs] used by HeNBs",
310 ns3::UintegerValue (25),
311 ns3::MakeUintegerChecker<uint16_t> ());
312 static ns3::GlobalValue g_simTime ("simTime",
313 "Total duration of the simulation [s]",
314 ns3::DoubleValue (0.25),
315 ns3::MakeDoubleChecker<double> ());
316 static ns3::GlobalValue g_generateRem ("generateRem",
317 "if true, will generate a REM and then abort the simulation;"
318 "if false, will run the simulation normally (without generating any REM)",
319 ns3::BooleanValue (false),
320 ns3::MakeBooleanChecker ());
321 static ns3::GlobalValue g_remRbId ("remRbId",
322 "Resource Block Id of Data Channel, for which REM will be generated;"
323 "default value is -1, what means REM will be averaged from all RBs of "
324 "Control Channel",
325 ns3::IntegerValue (-1),
326 MakeIntegerChecker<int32_t> ());
327 static ns3::GlobalValue g_epc ("epc",
328 "If true, will setup the EPC to simulate an end-to-end topology, "
329 "with real IP applications over PDCP and RLC UM (or RLC AM by changing "
330 "the default value of EpsBearerToRlcMapping e.g. to RLC_AM_ALWAYS). "
331 "If false, only the LTE radio access will be simulated with RLC SM. ",
332 ns3::BooleanValue (false),
333 ns3::MakeBooleanChecker ());
334 static ns3::GlobalValue g_epcDl ("epcDl",
335 "if true, will activate data flows in the downlink when EPC is being used. "
336 "If false, downlink flows won't be activated. "
337 "If EPC is not used, this parameter will be ignored.",
338 ns3::BooleanValue (true),
339 ns3::MakeBooleanChecker ());
340 static ns3::GlobalValue g_epcUl ("epcUl",
341 "if true, will activate data flows in the uplink when EPC is being used. "
342 "If false, uplink flows won't be activated. "
343 "If EPC is not used, this parameter will be ignored.",
344 ns3::BooleanValue (true),
345 ns3::MakeBooleanChecker ());
346 static ns3::GlobalValue g_useUdp ("useUdp",
347 "if true, the UdpClient application will be used. "
348 "Otherwise, the BulkSend application will be used over a TCP connection. "
349 "If EPC is not used, this parameter will be ignored.",
350 ns3::BooleanValue (true),
351 ns3::MakeBooleanChecker ());
352 static ns3::GlobalValue g_fadingTrace ("fadingTrace",
353 "The path of the fading trace (by default no fading trace "
354 "is loaded, i.e., fading is not considered)",
355 ns3::StringValue (""),
356 ns3::MakeStringChecker ());
357 static ns3::GlobalValue g_numBearersPerUe ("numBearersPerUe",
358 "How many bearers per UE there are in the simulation",
359 ns3::UintegerValue (1),
360 ns3::MakeUintegerChecker<uint16_t> ());
361 static ns3::GlobalValue g_srsPeriodicity ("srsPeriodicity",
362 "SRS Periodicity (has to be at least "
363 "greater than the number of UEs per eNB)",
364 ns3::UintegerValue (80),
365 ns3::MakeUintegerChecker<uint16_t> ());
366 static ns3::GlobalValue g_outdoorUeMinSpeed ("outdoorUeMinSpeed",
367 "Minimum speed value of macro UE with random waypoint model [m/s].",
368 ns3::DoubleValue (0.0),
369 ns3::MakeDoubleChecker<double> ());
370 static ns3::GlobalValue g_outdoorUeMaxSpeed ("outdoorUeMaxSpeed",
371 "Maximum speed value of macro UE with random waypoint model [m/s].",
372 ns3::DoubleValue (0.0),
373 ns3::MakeDoubleChecker<double> ());
374
375 int
main(int argc,char * argv[])376 main (int argc, char *argv[])
377 {
378 // change some default attributes so that they are reasonable for
379 // this scenario, but do this before processing command line
380 // arguments, so that the user is allowed to override these settings
381 Config::SetDefault ("ns3::UdpClient::Interval", TimeValue (MilliSeconds (1)));
382 Config::SetDefault ("ns3::UdpClient::MaxPackets", UintegerValue (1000000));
383 Config::SetDefault ("ns3::LteRlcUm::MaxTxBufferSize", UintegerValue (10 * 1024));
384
385 CommandLine cmd (__FILE__);
386 cmd.Parse (argc, argv);
387 ConfigStore inputConfig;
388 inputConfig.ConfigureDefaults ();
389 // parse again so you can override input file default values via command line
390 cmd.Parse (argc, argv);
391
392 // the scenario parameters get their values from the global attributes defined above
393 UintegerValue uintegerValue;
394 IntegerValue integerValue;
395 DoubleValue doubleValue;
396 BooleanValue booleanValue;
397 StringValue stringValue;
398 GlobalValue::GetValueByName ("nBlocks", uintegerValue);
399 uint32_t nBlocks = uintegerValue.Get ();
400 GlobalValue::GetValueByName ("nApartmentsX", uintegerValue);
401 uint32_t nApartmentsX = uintegerValue.Get ();
402 GlobalValue::GetValueByName ("nFloors", uintegerValue);
403 uint32_t nFloors = uintegerValue.Get ();
404 GlobalValue::GetValueByName ("nMacroEnbSites", uintegerValue);
405 uint32_t nMacroEnbSites = uintegerValue.Get ();
406 GlobalValue::GetValueByName ("nMacroEnbSitesX", uintegerValue);
407 uint32_t nMacroEnbSitesX = uintegerValue.Get ();
408 GlobalValue::GetValueByName ("interSiteDistance", doubleValue);
409 double interSiteDistance = doubleValue.Get ();
410 GlobalValue::GetValueByName ("areaMarginFactor", doubleValue);
411 double areaMarginFactor = doubleValue.Get ();
412 GlobalValue::GetValueByName ("macroUeDensity", doubleValue);
413 double macroUeDensity = doubleValue.Get ();
414 GlobalValue::GetValueByName ("homeEnbDeploymentRatio", doubleValue);
415 double homeEnbDeploymentRatio = doubleValue.Get ();
416 GlobalValue::GetValueByName ("homeEnbActivationRatio", doubleValue);
417 double homeEnbActivationRatio = doubleValue.Get ();
418 GlobalValue::GetValueByName ("homeUesHomeEnbRatio", doubleValue);
419 double homeUesHomeEnbRatio = doubleValue.Get ();
420 GlobalValue::GetValueByName ("macroEnbTxPowerDbm", doubleValue);
421 double macroEnbTxPowerDbm = doubleValue.Get ();
422 GlobalValue::GetValueByName ("homeEnbTxPowerDbm", doubleValue);
423 double homeEnbTxPowerDbm = doubleValue.Get ();
424 GlobalValue::GetValueByName ("macroEnbDlEarfcn", uintegerValue);
425 uint32_t macroEnbDlEarfcn = uintegerValue.Get ();
426 GlobalValue::GetValueByName ("homeEnbDlEarfcn", uintegerValue);
427 uint32_t homeEnbDlEarfcn = uintegerValue.Get ();
428 GlobalValue::GetValueByName ("macroEnbBandwidth", uintegerValue);
429 uint16_t macroEnbBandwidth = uintegerValue.Get ();
430 GlobalValue::GetValueByName ("homeEnbBandwidth", uintegerValue);
431 uint16_t homeEnbBandwidth = uintegerValue.Get ();
432 GlobalValue::GetValueByName ("simTime", doubleValue);
433 double simTime = doubleValue.Get ();
434 GlobalValue::GetValueByName ("epc", booleanValue);
435 bool epc = booleanValue.Get ();
436 GlobalValue::GetValueByName ("epcDl", booleanValue);
437 bool epcDl = booleanValue.Get ();
438 GlobalValue::GetValueByName ("epcUl", booleanValue);
439 bool epcUl = booleanValue.Get ();
440 GlobalValue::GetValueByName ("useUdp", booleanValue);
441 bool useUdp = booleanValue.Get ();
442 GlobalValue::GetValueByName ("generateRem", booleanValue);
443 bool generateRem = booleanValue.Get ();
444 GlobalValue::GetValueByName ("remRbId", integerValue);
445 int32_t remRbId = integerValue.Get ();
446 GlobalValue::GetValueByName ("fadingTrace", stringValue);
447 std::string fadingTrace = stringValue.Get ();
448 GlobalValue::GetValueByName ("numBearersPerUe", uintegerValue);
449 uint16_t numBearersPerUe = uintegerValue.Get ();
450 GlobalValue::GetValueByName ("srsPeriodicity", uintegerValue);
451 uint16_t srsPeriodicity = uintegerValue.Get ();
452 GlobalValue::GetValueByName ("outdoorUeMinSpeed", doubleValue);
453 uint16_t outdoorUeMinSpeed = doubleValue.Get ();
454 GlobalValue::GetValueByName ("outdoorUeMaxSpeed", doubleValue);
455 uint16_t outdoorUeMaxSpeed = doubleValue.Get ();
456
457 Config::SetDefault ("ns3::LteEnbRrc::SrsPeriodicity", UintegerValue (srsPeriodicity));
458
459 Box macroUeBox;
460 double ueZ = 1.5;
461 if (nMacroEnbSites > 0)
462 {
463 uint32_t currentSite = nMacroEnbSites -1;
464 uint32_t biRowIndex = (currentSite / (nMacroEnbSitesX + nMacroEnbSitesX + 1));
465 uint32_t biRowRemainder = currentSite % (nMacroEnbSitesX + nMacroEnbSitesX + 1);
466 uint32_t rowIndex = biRowIndex*2 + 1;
467 if (biRowRemainder >= nMacroEnbSitesX)
468 {
469 ++rowIndex;
470 }
471 uint32_t nMacroEnbSitesY = rowIndex;
472 NS_LOG_LOGIC ("nMacroEnbSitesY = " << nMacroEnbSitesY);
473
474 macroUeBox = Box (-areaMarginFactor*interSiteDistance,
475 (nMacroEnbSitesX + areaMarginFactor)*interSiteDistance,
476 -areaMarginFactor*interSiteDistance,
477 (nMacroEnbSitesY -1)*interSiteDistance*sqrt (0.75) + areaMarginFactor*interSiteDistance,
478 ueZ, ueZ);
479 }
480 else
481 {
482 // still need the box to place femtocell blocks
483 macroUeBox = Box (0, 150, 0, 150, ueZ, ueZ);
484 }
485
486 FemtocellBlockAllocator blockAllocator (macroUeBox, nApartmentsX, nFloors);
487 blockAllocator.Create (nBlocks);
488
489
490 uint32_t nHomeEnbs = round (4 * nApartmentsX * nBlocks * nFloors * homeEnbDeploymentRatio * homeEnbActivationRatio);
491 NS_LOG_LOGIC ("nHomeEnbs = " << nHomeEnbs);
492 uint32_t nHomeUes = round (nHomeEnbs * homeUesHomeEnbRatio);
493 NS_LOG_LOGIC ("nHomeUes = " << nHomeUes);
494 double macroUeAreaSize = (macroUeBox.xMax - macroUeBox.xMin) * (macroUeBox.yMax - macroUeBox.yMin);
495 uint32_t nMacroUes = round (macroUeAreaSize * macroUeDensity);
496 NS_LOG_LOGIC ("nMacroUes = " << nMacroUes << " (density=" << macroUeDensity << ")");
497
498 NodeContainer homeEnbs;
499 homeEnbs.Create (nHomeEnbs);
500 NodeContainer macroEnbs;
501 macroEnbs.Create (3 * nMacroEnbSites);
502 NodeContainer homeUes;
503 homeUes.Create (nHomeUes);
504 NodeContainer macroUes;
505 macroUes.Create (nMacroUes);
506
507 MobilityHelper mobility;
508 mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
509
510
511 Ptr <LteHelper> lteHelper = CreateObject<LteHelper> ();
512 lteHelper->SetAttribute ("PathlossModel", StringValue ("ns3::HybridBuildingsPropagationLossModel"));
513 lteHelper->SetPathlossModelAttribute ("ShadowSigmaExtWalls", DoubleValue (0));
514 lteHelper->SetPathlossModelAttribute ("ShadowSigmaOutdoor", DoubleValue (1));
515 lteHelper->SetPathlossModelAttribute ("ShadowSigmaIndoor", DoubleValue (1.5));
516 // use always LOS model
517 lteHelper->SetPathlossModelAttribute ("Los2NlosThr", DoubleValue (1e6));
518 lteHelper->SetSpectrumChannelType ("ns3::MultiModelSpectrumChannel");
519
520 // lteHelper->EnableLogComponents ();
521 // LogComponentEnable ("PfFfMacScheduler", LOG_LEVEL_ALL);
522
523 if (!fadingTrace.empty ())
524 {
525 lteHelper->SetAttribute ("FadingModel", StringValue ("ns3::TraceFadingLossModel"));
526 lteHelper->SetFadingModelAttribute ("TraceFilename", StringValue (fadingTrace));
527 }
528
529 Ptr<PointToPointEpcHelper> epcHelper;
530 if (epc)
531 {
532 NS_LOG_LOGIC ("enabling EPC");
533 epcHelper = CreateObject<PointToPointEpcHelper> ();
534 lteHelper->SetEpcHelper (epcHelper);
535 }
536
537 // Macro eNBs in 3-sector hex grid
538
539 mobility.Install (macroEnbs);
540 BuildingsHelper::Install (macroEnbs);
541 Ptr<LteHexGridEnbTopologyHelper> lteHexGridEnbTopologyHelper = CreateObject<LteHexGridEnbTopologyHelper> ();
542 lteHexGridEnbTopologyHelper->SetLteHelper (lteHelper);
543 lteHexGridEnbTopologyHelper->SetAttribute ("InterSiteDistance", DoubleValue (interSiteDistance));
544 lteHexGridEnbTopologyHelper->SetAttribute ("MinX", DoubleValue (interSiteDistance/2));
545 lteHexGridEnbTopologyHelper->SetAttribute ("GridWidth", UintegerValue (nMacroEnbSitesX));
546 Config::SetDefault ("ns3::LteEnbPhy::TxPower", DoubleValue (macroEnbTxPowerDbm));
547 lteHelper->SetEnbAntennaModelType ("ns3::ParabolicAntennaModel");
548 lteHelper->SetEnbAntennaModelAttribute ("Beamwidth", DoubleValue (70));
549 lteHelper->SetEnbAntennaModelAttribute ("MaxAttenuation", DoubleValue (20.0));
550 lteHelper->SetEnbDeviceAttribute ("DlEarfcn", UintegerValue (macroEnbDlEarfcn));
551 lteHelper->SetEnbDeviceAttribute ("UlEarfcn", UintegerValue (macroEnbDlEarfcn + 18000));
552 lteHelper->SetEnbDeviceAttribute ("DlBandwidth", UintegerValue (macroEnbBandwidth));
553 lteHelper->SetEnbDeviceAttribute ("UlBandwidth", UintegerValue (macroEnbBandwidth));
554 NetDeviceContainer macroEnbDevs = lteHexGridEnbTopologyHelper->SetPositionAndInstallEnbDevice (macroEnbs);
555
556 if (epc)
557 {
558 // this enables handover for macro eNBs
559 lteHelper->AddX2Interface (macroEnbs);
560 }
561
562 // HomeEnbs randomly indoor
563
564 Ptr<PositionAllocator> positionAlloc = CreateObject<RandomRoomPositionAllocator> ();
565 mobility.SetPositionAllocator (positionAlloc);
566 mobility.Install (homeEnbs);
567 BuildingsHelper::Install (homeEnbs);
568 Config::SetDefault ("ns3::LteEnbPhy::TxPower", DoubleValue (homeEnbTxPowerDbm));
569 lteHelper->SetEnbAntennaModelType ("ns3::IsotropicAntennaModel");
570 lteHelper->SetEnbDeviceAttribute ("DlEarfcn", UintegerValue (homeEnbDlEarfcn));
571 lteHelper->SetEnbDeviceAttribute ("UlEarfcn", UintegerValue (homeEnbDlEarfcn + 18000));
572 lteHelper->SetEnbDeviceAttribute ("DlBandwidth", UintegerValue (homeEnbBandwidth));
573 lteHelper->SetEnbDeviceAttribute ("UlBandwidth", UintegerValue (homeEnbBandwidth));
574 lteHelper->SetEnbDeviceAttribute ("CsgId", UintegerValue (1));
575 lteHelper->SetEnbDeviceAttribute ("CsgIndication", BooleanValue (true));
576 NetDeviceContainer homeEnbDevs = lteHelper->InstallEnbDevice (homeEnbs);
577
578 // home UEs located in the same apartment in which there are the Home eNBs
579 positionAlloc = CreateObject<SameRoomPositionAllocator> (homeEnbs);
580 mobility.SetPositionAllocator (positionAlloc);
581 mobility.Install (homeUes);
582 BuildingsHelper::Install (homeUes);
583 // set the home UE as a CSG member of the home eNodeBs
584 lteHelper->SetUeDeviceAttribute ("CsgId", UintegerValue (1));
585 NetDeviceContainer homeUeDevs = lteHelper->InstallUeDevice (homeUes);
586
587 // macro Ues
588 NS_LOG_LOGIC ("randomly allocating macro UEs in " << macroUeBox << " speedMin " << outdoorUeMinSpeed << " speedMax " << outdoorUeMaxSpeed);
589 if (outdoorUeMaxSpeed!=0.0)
590 {
591 mobility.SetMobilityModel ("ns3::SteadyStateRandomWaypointMobilityModel");
592
593 Config::SetDefault ("ns3::SteadyStateRandomWaypointMobilityModel::MinX", DoubleValue (macroUeBox.xMin));
594 Config::SetDefault ("ns3::SteadyStateRandomWaypointMobilityModel::MinY", DoubleValue (macroUeBox.yMin));
595 Config::SetDefault ("ns3::SteadyStateRandomWaypointMobilityModel::MaxX", DoubleValue (macroUeBox.xMax));
596 Config::SetDefault ("ns3::SteadyStateRandomWaypointMobilityModel::MaxY", DoubleValue (macroUeBox.yMax));
597 Config::SetDefault ("ns3::SteadyStateRandomWaypointMobilityModel::Z", DoubleValue (ueZ));
598 Config::SetDefault ("ns3::SteadyStateRandomWaypointMobilityModel::MaxSpeed", DoubleValue (outdoorUeMaxSpeed));
599 Config::SetDefault ("ns3::SteadyStateRandomWaypointMobilityModel::MinSpeed", DoubleValue (outdoorUeMinSpeed));
600
601 // this is not used since SteadyStateRandomWaypointMobilityModel
602 // takes care of initializing the positions; however we need to
603 // reset it since the previously used PositionAllocator
604 // (SameRoom) will cause an error when used with homeDeploymentRatio=0
605 positionAlloc = CreateObject<RandomBoxPositionAllocator> ();
606 mobility.SetPositionAllocator (positionAlloc);
607 mobility.Install (macroUes);
608
609 // forcing initialization so we don't have to wait for Nodes to
610 // start before positions are assigned (which is needed to
611 // output node positions to file and to make AttachToClosestEnb work)
612 for (NodeContainer::Iterator it = macroUes.Begin ();
613 it != macroUes.End ();
614 ++it)
615 {
616 (*it)->Initialize ();
617 }
618 }
619 else
620 {
621 positionAlloc = CreateObject<RandomBoxPositionAllocator> ();
622 Ptr<UniformRandomVariable> xVal = CreateObject<UniformRandomVariable> ();
623 xVal->SetAttribute ("Min", DoubleValue (macroUeBox.xMin));
624 xVal->SetAttribute ("Max", DoubleValue (macroUeBox.xMax));
625 positionAlloc->SetAttribute ("X", PointerValue (xVal));
626 Ptr<UniformRandomVariable> yVal = CreateObject<UniformRandomVariable> ();
627 yVal->SetAttribute ("Min", DoubleValue (macroUeBox.yMin));
628 yVal->SetAttribute ("Max", DoubleValue (macroUeBox.yMax));
629 positionAlloc->SetAttribute ("Y", PointerValue (yVal));
630 Ptr<UniformRandomVariable> zVal = CreateObject<UniformRandomVariable> ();
631 zVal->SetAttribute ("Min", DoubleValue (macroUeBox.zMin));
632 zVal->SetAttribute ("Max", DoubleValue (macroUeBox.zMax));
633 positionAlloc->SetAttribute ("Z", PointerValue (zVal));
634 mobility.SetPositionAllocator (positionAlloc);
635 mobility.Install (macroUes);
636 }
637 BuildingsHelper::Install (macroUes);
638
639 NetDeviceContainer macroUeDevs = lteHelper->InstallUeDevice (macroUes);
640
641 Ipv4Address remoteHostAddr;
642 NodeContainer ues;
643 Ipv4StaticRoutingHelper ipv4RoutingHelper;
644 Ipv4InterfaceContainer ueIpIfaces;
645 Ptr<Node> remoteHost;
646 NetDeviceContainer ueDevs;
647
648 if (epc)
649 {
650 NS_LOG_LOGIC ("setting up internet and remote host");
651
652 // Create a single RemoteHost
653 NodeContainer remoteHostContainer;
654 remoteHostContainer.Create (1);
655 remoteHost = remoteHostContainer.Get (0);
656 InternetStackHelper internet;
657 internet.Install (remoteHostContainer);
658
659 // Create the Internet
660 PointToPointHelper p2ph;
661 p2ph.SetDeviceAttribute ("DataRate", DataRateValue (DataRate ("100Gb/s")));
662 p2ph.SetDeviceAttribute ("Mtu", UintegerValue (1500));
663 p2ph.SetChannelAttribute ("Delay", TimeValue (Seconds (0.010)));
664 Ptr<Node> pgw = epcHelper->GetPgwNode ();
665 NetDeviceContainer internetDevices = p2ph.Install (pgw, remoteHost);
666 Ipv4AddressHelper ipv4h;
667 ipv4h.SetBase ("1.0.0.0", "255.0.0.0");
668 Ipv4InterfaceContainer internetIpIfaces = ipv4h.Assign (internetDevices);
669 // in this container, interface 0 is the pgw, 1 is the remoteHost
670 remoteHostAddr = internetIpIfaces.GetAddress (1);
671
672 Ipv4StaticRoutingHelper ipv4RoutingHelper;
673 Ptr<Ipv4StaticRouting> remoteHostStaticRouting = ipv4RoutingHelper.GetStaticRouting (remoteHost->GetObject<Ipv4> ());
674 remoteHostStaticRouting->AddNetworkRouteTo (Ipv4Address ("7.0.0.0"), Ipv4Mask ("255.0.0.0"), 1);
675
676 // for internetworking purposes, consider together home UEs and macro UEs
677 ues.Add (homeUes);
678 ues.Add (macroUes);
679 ueDevs.Add (homeUeDevs);
680 ueDevs.Add (macroUeDevs);
681
682 // Install the IP stack on the UEs
683 internet.Install (ues);
684 ueIpIfaces = epcHelper->AssignUeIpv4Address (NetDeviceContainer (ueDevs));
685
686 // attachment (needs to be done after IP stack configuration)
687 // using initial cell selection
688 lteHelper->Attach (macroUeDevs);
689 lteHelper->Attach (homeUeDevs);
690 }
691 else
692 {
693 // macro UEs attached to the closest macro eNB
694 lteHelper->AttachToClosestEnb (macroUeDevs, macroEnbDevs);
695
696 // each home UE is attached explicitly to its home eNB
697 NetDeviceContainer::Iterator ueDevIt;
698 NetDeviceContainer::Iterator enbDevIt;
699 for (ueDevIt = homeUeDevs.Begin (), enbDevIt = homeEnbDevs.Begin ();
700 ueDevIt != homeUeDevs.End (); ++ueDevIt, ++enbDevIt)
701 {
702 // this because of the order in which SameRoomPositionAllocator
703 // will place the UEs
704 if (enbDevIt == homeEnbDevs.End ())
705 {
706 enbDevIt = homeEnbDevs.Begin ();
707 }
708 lteHelper->Attach (*ueDevIt, *enbDevIt);
709 }
710 }
711
712 if (epc)
713 {
714 NS_LOG_LOGIC ("setting up applications");
715
716 // Install and start applications on UEs and remote host
717 uint16_t dlPort = 10000;
718 uint16_t ulPort = 20000;
719
720 // randomize a bit start times to avoid simulation artifacts
721 // (e.g., buffer overflows due to packet transmissions happening
722 // exactly at the same time)
723 Ptr<UniformRandomVariable> startTimeSeconds = CreateObject<UniformRandomVariable> ();
724 if (useUdp)
725 {
726 startTimeSeconds->SetAttribute ("Min", DoubleValue (0));
727 startTimeSeconds->SetAttribute ("Max", DoubleValue (0.010));
728 }
729 else
730 {
731 // TCP needs to be started late enough so that all UEs are connected
732 // otherwise TCP SYN packets will get lost
733 startTimeSeconds->SetAttribute ("Min", DoubleValue (0.100));
734 startTimeSeconds->SetAttribute ("Max", DoubleValue (0.110));
735 }
736
737 for (uint32_t u = 0; u < ues.GetN (); ++u)
738 {
739 Ptr<Node> ue = ues.Get (u);
740 // Set the default gateway for the UE
741 Ptr<Ipv4StaticRouting> ueStaticRouting = ipv4RoutingHelper.GetStaticRouting (ue->GetObject<Ipv4> ());
742 ueStaticRouting->SetDefaultRoute (epcHelper->GetUeDefaultGatewayAddress (), 1);
743
744 for (uint32_t b = 0; b < numBearersPerUe; ++b)
745 {
746 ++dlPort;
747 ++ulPort;
748
749 ApplicationContainer clientApps;
750 ApplicationContainer serverApps;
751
752 if (useUdp)
753 {
754 if (epcDl)
755 {
756 NS_LOG_LOGIC ("installing UDP DL app for UE " << u);
757 UdpClientHelper dlClientHelper (ueIpIfaces.GetAddress (u), dlPort);
758 clientApps.Add (dlClientHelper.Install (remoteHost));
759 PacketSinkHelper dlPacketSinkHelper ("ns3::UdpSocketFactory",
760 InetSocketAddress (Ipv4Address::GetAny (), dlPort));
761 serverApps.Add (dlPacketSinkHelper.Install (ue));
762 }
763 if (epcUl)
764 {
765 NS_LOG_LOGIC ("installing UDP UL app for UE " << u);
766 UdpClientHelper ulClientHelper (remoteHostAddr, ulPort);
767 clientApps.Add (ulClientHelper.Install (ue));
768 PacketSinkHelper ulPacketSinkHelper ("ns3::UdpSocketFactory",
769 InetSocketAddress (Ipv4Address::GetAny (), ulPort));
770 serverApps.Add (ulPacketSinkHelper.Install (remoteHost));
771 }
772 }
773 else // use TCP
774 {
775 if (epcDl)
776 {
777 NS_LOG_LOGIC ("installing TCP DL app for UE " << u);
778 BulkSendHelper dlClientHelper ("ns3::TcpSocketFactory",
779 InetSocketAddress (ueIpIfaces.GetAddress (u), dlPort));
780 dlClientHelper.SetAttribute ("MaxBytes", UintegerValue (0));
781 clientApps.Add (dlClientHelper.Install (remoteHost));
782 PacketSinkHelper dlPacketSinkHelper ("ns3::TcpSocketFactory",
783 InetSocketAddress (Ipv4Address::GetAny (), dlPort));
784 serverApps.Add (dlPacketSinkHelper.Install (ue));
785 }
786 if (epcUl)
787 {
788 NS_LOG_LOGIC ("installing TCP UL app for UE " << u);
789 BulkSendHelper ulClientHelper ("ns3::TcpSocketFactory",
790 InetSocketAddress (remoteHostAddr, ulPort));
791 ulClientHelper.SetAttribute ("MaxBytes", UintegerValue (0));
792 clientApps.Add (ulClientHelper.Install (ue));
793 PacketSinkHelper ulPacketSinkHelper ("ns3::TcpSocketFactory",
794 InetSocketAddress (Ipv4Address::GetAny (), ulPort));
795 serverApps.Add (ulPacketSinkHelper.Install (remoteHost));
796 }
797 } // end if (useUdp)
798
799 Ptr<EpcTft> tft = Create<EpcTft> ();
800 if (epcDl)
801 {
802 EpcTft::PacketFilter dlpf;
803 dlpf.localPortStart = dlPort;
804 dlpf.localPortEnd = dlPort;
805 tft->Add (dlpf);
806 }
807 if (epcUl)
808 {
809 EpcTft::PacketFilter ulpf;
810 ulpf.remotePortStart = ulPort;
811 ulpf.remotePortEnd = ulPort;
812 tft->Add (ulpf);
813 }
814
815 if (epcDl || epcUl)
816 {
817 EpsBearer bearer (EpsBearer::NGBR_VIDEO_TCP_DEFAULT);
818 lteHelper->ActivateDedicatedEpsBearer (ueDevs.Get (u), bearer, tft);
819 }
820 Time startTime = Seconds (startTimeSeconds->GetValue ());
821 serverApps.Start (startTime);
822 clientApps.Start (startTime);
823
824 } // end for b
825 }
826
827 }
828 else // (epc == false)
829 {
830 // for radio bearer activation purposes, consider together home UEs and macro UEs
831 NetDeviceContainer ueDevs;
832 ueDevs.Add (homeUeDevs);
833 ueDevs.Add (macroUeDevs);
834 for (uint32_t u = 0; u < ueDevs.GetN (); ++u)
835 {
836 Ptr<NetDevice> ueDev = ueDevs.Get (u);
837 for (uint32_t b = 0; b < numBearersPerUe; ++b)
838 {
839 enum EpsBearer::Qci q = EpsBearer::NGBR_VIDEO_TCP_DEFAULT;
840 EpsBearer bearer (q);
841 lteHelper->ActivateDataRadioBearer (ueDev, bearer);
842 }
843 }
844 }
845
846 Ptr<RadioEnvironmentMapHelper> remHelper;
847 if (generateRem)
848 {
849 PrintGnuplottableBuildingListToFile ("buildings.txt");
850 PrintGnuplottableEnbListToFile ("enbs.txt");
851 PrintGnuplottableUeListToFile ("ues.txt");
852
853 remHelper = CreateObject<RadioEnvironmentMapHelper> ();
854 remHelper->SetAttribute ("Channel", PointerValue (lteHelper->GetDownlinkSpectrumChannel ()));
855 remHelper->SetAttribute ("OutputFile", StringValue ("lena-dual-stripe.rem"));
856 remHelper->SetAttribute ("XMin", DoubleValue (macroUeBox.xMin));
857 remHelper->SetAttribute ("XMax", DoubleValue (macroUeBox.xMax));
858 remHelper->SetAttribute ("YMin", DoubleValue (macroUeBox.yMin));
859 remHelper->SetAttribute ("YMax", DoubleValue (macroUeBox.yMax));
860 remHelper->SetAttribute ("Z", DoubleValue (1.5));
861
862 if (remRbId >= 0)
863 {
864 remHelper->SetAttribute ("UseDataChannel", BooleanValue (true));
865 remHelper->SetAttribute ("RbId", IntegerValue (remRbId));
866 }
867
868 remHelper->Install ();
869 // simulation will stop right after the REM has been generated
870 }
871 else
872 {
873 Simulator::Stop (Seconds (simTime));
874 }
875
876 lteHelper->EnableMacTraces ();
877 lteHelper->EnableRlcTraces ();
878 if (epc)
879 {
880 lteHelper->EnablePdcpTraces ();
881 }
882
883 Simulator::Run ();
884
885 //GtkConfigStore config;
886 //config.ConfigureAttributes ();
887
888 lteHelper = 0;
889 Simulator::Destroy ();
890 return 0;
891 }
892