1 /* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
2 /*
3 * Copyright (c) 2011 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: Marco Miozzo <marco.miozzo@cttc.es>
19 */
20
21 #include <iostream>
22 #include <sstream>
23 #include <string>
24 #include <ns3/object.h>
25 #include <ns3/spectrum-interference.h>
26 #include <ns3/spectrum-error-model.h>
27 #include <ns3/log.h>
28 #include <ns3/test.h>
29 #include <ns3/simulator.h>
30 #include <ns3/packet.h>
31 #include <ns3/ptr.h>
32 #include "ns3/radio-bearer-stats-calculator.h"
33 #include <ns3/mobility-building-info.h>
34 #include <ns3/buildings-propagation-loss-model.h>
35 #include <ns3/eps-bearer.h>
36 #include <ns3/node-container.h>
37 #include <ns3/mobility-helper.h>
38 #include <ns3/net-device-container.h>
39 #include <ns3/lte-ue-net-device.h>
40 #include <ns3/lte-enb-net-device.h>
41 #include <ns3/lte-ue-rrc.h>
42 #include <ns3/lte-helper.h>
43 #include "ns3/string.h"
44 #include "ns3/double.h"
45 #include <ns3/lte-enb-phy.h>
46 #include <ns3/lte-ue-phy.h>
47 #include <ns3/boolean.h>
48 #include <ns3/rr-ff-mac-scheduler.h>
49 #include <ns3/pf-ff-mac-scheduler.h>
50 #include <ns3/pointer.h>
51 #include <ns3/enum.h>
52 #include <ns3/buildings-helper.h>
53 #include "lte-test-mimo.h"
54
55
56 using namespace ns3;
57
58 NS_LOG_COMPONENT_DEFINE ("LteTestMimo");
59
LenaTestMimoSuite()60 LenaTestMimoSuite::LenaTestMimoSuite ()
61 : TestSuite ("lte-mimo", SYSTEM)
62 {
63 NS_LOG_INFO ("creating LenaMimoTestCase");
64
65 // RR DOWNLINK- DISTANCE 300
66 // interval 1 : [0.1, 0.2) sec TxMode 0: MCS 20 -> TB size 1191 bytes
67 // interval 2 : [0.3, 0.4) sec TxMode 1: MCS 26 -> TB size 1836 bytes
68 // interval 3 : [0.5, 0.6) sec TxMode 2: MCS 18 -> TB size 967 bytes (x2 layers)
69 // -->
70 std::vector<uint32_t> estThrDl;
71 estThrDl.push_back (119100); // interval 1 : estimated throughput for TxMode 1
72 estThrDl.push_back (183600); // interval 2 : estimated throughput for TxMode 2
73 estThrDl.push_back (193400); // interval 3 : estimated throughput for TxMode 3
74 AddTestCase (new LenaMimoTestCase(300, estThrDl, "ns3::RrFfMacScheduler", true), TestCase::QUICK);
75 AddTestCase (new LenaMimoTestCase(300, estThrDl, "ns3::PfFfMacScheduler", true), TestCase::QUICK);
76 AddTestCase (new LenaMimoTestCase(300, estThrDl, "ns3::RrFfMacScheduler", false), TestCase::QUICK);
77 AddTestCase (new LenaMimoTestCase(300, estThrDl, "ns3::PfFfMacScheduler", false), TestCase::QUICK);
78
79 }
80
81 static LenaTestMimoSuite lenaTestMimoSuite;
82
83 std::string
BuildNameString(uint16_t dist,std::string schedulerType,bool useIdealRrc)84 LenaMimoTestCase::BuildNameString (uint16_t dist, std::string schedulerType, bool useIdealRrc)
85 {
86 std::ostringstream oss;
87 oss << " UE distance " << dist << " m" << " Scheduler " << schedulerType;
88 if (useIdealRrc)
89 {
90 oss << ", ideal RRC";
91 }
92 else
93 {
94 oss << ", real RRC";
95 }
96 return oss.str ();
97 }
98
LenaMimoTestCase(uint16_t dist,std::vector<uint32_t> estThrDl,std::string schedulerType,bool useIdealRrc)99 LenaMimoTestCase::LenaMimoTestCase (uint16_t dist, std::vector<uint32_t> estThrDl, std::string schedulerType, bool useIdealRrc)
100 : TestCase (BuildNameString (dist, schedulerType, useIdealRrc)),
101 m_dist (dist),
102 m_estThrDl (estThrDl),
103 m_schedulerType (schedulerType),
104 m_useIdealRrc (useIdealRrc)
105 {
106 }
107
~LenaMimoTestCase()108 LenaMimoTestCase::~LenaMimoTestCase ()
109 {
110 }
111
112 void
DoRun(void)113 LenaMimoTestCase::DoRun (void)
114 {
115 NS_LOG_FUNCTION (this << GetName ());
116 Config::SetDefault ("ns3::LteSpectrumPhy::DataErrorModelEnabled", BooleanValue (false));
117 Config::SetDefault ("ns3::LteAmc::AmcModel", EnumValue (LteAmc::PiroEW2010));
118 Config::SetDefault ("ns3::LteHelper::UseIdealRrc", BooleanValue (m_useIdealRrc));
119 Config::SetDefault ("ns3::MacStatsCalculator::DlOutputFilename", StringValue (CreateTempDirFilename ("DlMacStats.txt")));
120 Config::SetDefault ("ns3::MacStatsCalculator::UlOutputFilename", StringValue (CreateTempDirFilename ("UlMacStats.txt")));
121 Config::SetDefault ("ns3::RadioBearerStatsCalculator::DlRlcOutputFilename", StringValue (CreateTempDirFilename ("DlRlcStats.txt")));
122 Config::SetDefault ("ns3::RadioBearerStatsCalculator::UlRlcOutputFilename", StringValue (CreateTempDirFilename ("UlRlcStats.txt")));
123
124 //Disable Uplink Power Control
125 Config::SetDefault ("ns3::LteUePhy::EnableUplinkPowerControl", BooleanValue (false));
126
127 /**
128 * Initialize Simulation Scenario: 1 eNB and m_nUser UEs
129 */
130
131
132 Ptr<LteHelper> lteHelper = CreateObject<LteHelper> ();
133 Config::SetDefault ("ns3::RrFfMacScheduler::HarqEnabled", BooleanValue (false));
134 Config::SetDefault ("ns3::PfFfMacScheduler::HarqEnabled", BooleanValue (false));
135
136 // lteHelper->SetSchedulerAttribute ("HarqEnabled", BooleanValue (false));
137
138
139 lteHelper->SetAttribute ("PathlossModel", StringValue ("ns3::HybridBuildingsPropagationLossModel"));
140 lteHelper->SetPathlossModelAttribute ("ShadowSigmaOutdoor", DoubleValue (0.0));
141 lteHelper->SetPathlossModelAttribute ("ShadowSigmaIndoor", DoubleValue (0.0));
142 lteHelper->SetPathlossModelAttribute ("ShadowSigmaExtWalls", DoubleValue (0.0));
143
144 // lteHelper->EnableLogComponents ();
145
146 // Create Nodes: eNodeB and UE
147 NodeContainer enbNodes;
148 NodeContainer ueNodes;
149 enbNodes.Create (1);
150 ueNodes.Create (1);
151
152 // Install Mobility Model
153 MobilityHelper mobility;
154 mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
155 mobility.Install (enbNodes);
156 BuildingsHelper::Install (enbNodes);
157 mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
158 mobility.Install (ueNodes);
159 BuildingsHelper::Install (ueNodes);
160
161 // Create Devices and install them in the Nodes (eNB and UE)
162 NetDeviceContainer enbDevs;
163 NetDeviceContainer ueDevs;
164 lteHelper->SetSchedulerType (m_schedulerType);
165 enbDevs = lteHelper->InstallEnbDevice (enbNodes);
166 ueDevs = lteHelper->InstallUeDevice (ueNodes);
167
168 // Attach a UE to a eNB
169 lteHelper->Attach (ueDevs, enbDevs.Get (0));
170
171 // Activate an EPS bearer
172 enum EpsBearer::Qci q = EpsBearer::GBR_CONV_VOICE;
173 EpsBearer bearer (q);
174 lteHelper->ActivateDataRadioBearer (ueDevs, bearer);
175
176
177 Ptr<LteEnbNetDevice> lteEnbDev = enbDevs.Get (0)->GetObject<LteEnbNetDevice> ();
178 Ptr<LteEnbPhy> enbPhy = lteEnbDev->GetPhy ();
179 enbPhy->SetAttribute ("TxPower", DoubleValue (46.0));
180 enbPhy->SetAttribute ("NoiseFigure", DoubleValue (5.0));
181 Ptr<MobilityModel> mmenb = enbNodes.Get (0)->GetObject<MobilityModel> ();
182 mmenb->SetPosition (Vector (0.0, 0.0, 30.0));
183
184 // Set UE's position and power
185 Ptr<MobilityModel> mmue = ueNodes.Get (0)->GetObject<MobilityModel> ();
186 mmue->SetPosition (Vector (m_dist, 0.0, 1.0));
187 Ptr<LteUeNetDevice> lteUeDev = ueDevs.Get (0)->GetObject<LteUeNetDevice> ();
188 Ptr<LteUePhy> uePhy = lteUeDev->GetPhy ();
189 uePhy->SetAttribute ("TxPower", DoubleValue (23.0));
190 uePhy->SetAttribute ("NoiseFigure", DoubleValue (9.0));
191
192 // need to allow for RRC connection establishment + SRS before enabling traces
193 lteHelper->EnableRlcTraces ();
194 lteHelper->EnableMacTraces ();
195 double simulationTime = 0.6;
196 double tolerance = 0.1;
197
198 uint8_t rnti = 1;
199 Ptr<LteEnbNetDevice> enbNetDev = enbDevs.Get (0)->GetObject<LteEnbNetDevice> ();
200
201 PointerValue ptrval;
202 enbNetDev->GetCcMap()[0]->GetAttribute ("FfMacScheduler", ptrval);
203 Ptr<PfFfMacScheduler> pfsched;
204 Ptr<RrFfMacScheduler> rrsched;
205 if (m_schedulerType.compare ("ns3::RrFfMacScheduler") == 0)
206 {
207 rrsched = ptrval.Get<RrFfMacScheduler> ();
208 if (rrsched == 0)
209 {
210 NS_FATAL_ERROR ("No RR Scheduler available");
211 }
212 Simulator::Schedule (Seconds (0.2), &RrFfMacScheduler::TransmissionModeConfigurationUpdate, rrsched, rnti, 1);
213 Simulator::Schedule (Seconds (0.4), &RrFfMacScheduler::TransmissionModeConfigurationUpdate, rrsched, rnti, 2);
214 }
215 else if (m_schedulerType.compare ("ns3::PfFfMacScheduler") == 0)
216 {
217 pfsched = ptrval.Get<PfFfMacScheduler> ();
218 if (pfsched == 0)
219 {
220 NS_FATAL_ERROR ("No Pf Scheduler available");
221 }
222
223 Simulator::Schedule (Seconds (0.2), &PfFfMacScheduler::TransmissionModeConfigurationUpdate, pfsched, rnti, 1);
224 Simulator::Schedule (Seconds (0.4), &PfFfMacScheduler::TransmissionModeConfigurationUpdate, pfsched, rnti, 2);
225 }
226 else
227 {
228 NS_FATAL_ERROR ("Scheduler not supported by this test");
229 }
230
231
232 Ptr<RadioBearerStatsCalculator> rlcStats = lteHelper->GetRlcStats ();
233 rlcStats->SetAttribute ("EpochDuration", TimeValue (Seconds (0.1)));
234
235 NS_LOG_INFO (m_schedulerType << " MIMO test:");
236 double sampleTime = 0.199999; // at 0.2 RlcStats are reset
237 for (uint8_t j = 0; j < m_estThrDl.size (); j ++)
238 {
239 NS_LOG_INFO ("\t test with user at distance " << m_dist << " time " << sampleTime);
240 // get the imsi
241 uint64_t imsi = ueDevs.Get (0)->GetObject<LteUeNetDevice> ()->GetImsi ();
242 uint8_t lcId = 3;
243 Time t = Seconds (sampleTime);
244 Simulator::Schedule(t, &LenaMimoTestCase::GetRlcBufferSample, this, rlcStats, imsi, lcId);
245 sampleTime += 0.2;
246 }
247 Simulator::Stop (Seconds (simulationTime));
248 Simulator::Run ();
249 Simulator::Destroy ();
250
251 NS_LOG_INFO ("Check consistency");
252 for (uint8_t i = 0; i < m_estThrDl.size (); i++)
253 {
254 NS_LOG_INFO ("interval " << i + 1 << ": bytes rxed " << (double)m_dlDataRxed.at (i) << " ref " << m_estThrDl.at (i));
255 NS_TEST_ASSERT_MSG_EQ_TOL ((double)m_dlDataRxed.at (i) , m_estThrDl.at (i), m_estThrDl.at (i) * tolerance, " Unfair Throughput!");
256 }
257
258 }
259
260
261 void
GetRlcBufferSample(Ptr<RadioBearerStatsCalculator> rlcStats,uint64_t imsi,uint8_t lcId)262 LenaMimoTestCase::GetRlcBufferSample (Ptr<RadioBearerStatsCalculator> rlcStats, uint64_t imsi, uint8_t lcId)
263 {
264 m_dlDataRxed.push_back (rlcStats->GetDlRxData (imsi, lcId));
265 NS_LOG_INFO (Simulator::Now () << "\t get bytes " << m_dlDataRxed.at (m_dlDataRxed.size () - 1));
266 }
267