A Discrete-Event Network Simulator
API
epc-test-s1u-downlink.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2011 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation;
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16  *
17  * Author: Nicola Baldo <nbaldo@cttc.es>
18  */
19 
20 #include "lte-test-entities.h"
21 
22 #include "ns3/boolean.h"
23 #include "ns3/config.h"
24 #include "ns3/csma-helper.h"
25 #include "ns3/epc-enb-application.h"
26 #include "ns3/eps-bearer.h"
27 #include "ns3/inet-socket-address.h"
28 #include "ns3/internet-stack-helper.h"
29 #include "ns3/ipv4-address-helper.h"
30 #include "ns3/log.h"
31 #include "ns3/packet-sink-helper.h"
32 #include "ns3/packet-sink.h"
33 #include "ns3/point-to-point-epc-helper.h"
34 #include "ns3/point-to-point-helper.h"
35 #include "ns3/simulator.h"
36 #include "ns3/test.h"
37 #include "ns3/udp-echo-helper.h"
38 #include "ns3/uinteger.h"
39 #include <ns3/ipv4-static-routing-helper.h>
40 #include <ns3/ipv4-static-routing.h>
41 
42 using namespace ns3;
43 
44 NS_LOG_COMPONENT_DEFINE("EpcTestS1uDownlink");
45 
52 {
59  UeDlTestData(uint32_t n, uint32_t s);
60 
61  uint32_t numPkts;
62  uint32_t pktSize;
63 
66 };
67 
68 UeDlTestData::UeDlTestData(uint32_t n, uint32_t s)
69  : numPkts(n),
70  pktSize(s)
71 {
72 }
73 
81 {
82  std::vector<UeDlTestData> ues;
83 };
84 
90 class EpcS1uDlTestCase : public TestCase
91 {
92  public:
99  EpcS1uDlTestCase(std::string name, std::vector<EnbDlTestData> v);
100  ~EpcS1uDlTestCase() override;
101 
102  private:
103  void DoRun() override;
104  std::vector<EnbDlTestData> m_enbDlTestData;
105 };
106 
107 EpcS1uDlTestCase::EpcS1uDlTestCase(std::string name, std::vector<EnbDlTestData> v)
108  : TestCase(name),
109  m_enbDlTestData(v)
110 {
111 }
112 
114 {
115 }
116 
117 void
119 {
120  Ptr<PointToPointEpcHelper> epcHelper = CreateObject<PointToPointEpcHelper>();
121  Ptr<Node> pgw = epcHelper->GetPgwNode();
122 
123  // allow jumbo packets
124  Config::SetDefault("ns3::CsmaNetDevice::Mtu", UintegerValue(30000));
125  Config::SetDefault("ns3::PointToPointNetDevice::Mtu", UintegerValue(30000));
126  epcHelper->SetAttribute("S1uLinkMtu", UintegerValue(30000));
127 
128  // Create a single RemoteHost
129  NodeContainer remoteHostContainer;
130  remoteHostContainer.Create(1);
131  Ptr<Node> remoteHost = remoteHostContainer.Get(0);
133  internet.Install(remoteHostContainer);
134 
135  // Create the internet
136  PointToPointHelper p2ph;
137  p2ph.SetDeviceAttribute("DataRate", DataRateValue(DataRate("100Gb/s")));
138  NetDeviceContainer internetDevices = p2ph.Install(pgw, remoteHost);
139  Ipv4AddressHelper ipv4h;
140  ipv4h.SetBase("1.0.0.0", "255.0.0.0");
141  ipv4h.Assign(internetDevices);
142 
143  // setup default gateway for the remote hosts
144  Ipv4StaticRoutingHelper ipv4RoutingHelper;
145  Ptr<Ipv4StaticRouting> remoteHostStaticRouting =
146  ipv4RoutingHelper.GetStaticRouting(remoteHost->GetObject<Ipv4>());
147 
148  // hardcoded UE addresses for now
149  remoteHostStaticRouting->AddNetworkRouteTo(Ipv4Address("7.0.0.0"),
150  Ipv4Mask("255.255.255.0"),
151  1);
152 
153  NodeContainer enbs;
154  uint16_t cellIdCounter = 0;
155  uint64_t imsiCounter = 0;
156 
157  for (auto enbit = m_enbDlTestData.begin(); enbit < m_enbDlTestData.end(); ++enbit)
158  {
159  Ptr<Node> enb = CreateObject<Node>();
160  enbs.Add(enb);
161 
162  // we test EPC without LTE, hence we use:
163  // 1) a CSMA network to simulate the cell
164  // 2) a raw socket opened on the CSMA device to simulate the LTE socket
165 
166  uint16_t cellId = ++cellIdCounter;
167 
168  NodeContainer ues;
169  ues.Create(enbit->ues.size());
170 
171  NodeContainer cell;
172  cell.Add(ues);
173  cell.Add(enb);
174 
175  CsmaHelper csmaCell;
176  NetDeviceContainer cellDevices = csmaCell.Install(cell);
177 
178  // the eNB's CSMA NetDevice acting as an LTE NetDevice.
179  Ptr<NetDevice> enbDevice = cellDevices.Get(cellDevices.GetN() - 1);
180 
181  // Note that the EpcEnbApplication won't care of the actual NetDevice type
182  std::vector<uint16_t> cellIds;
183  cellIds.push_back(cellId);
184  epcHelper->AddEnb(enb, enbDevice, cellIds);
185 
186  // Plug test RRC entity
188  NS_ASSERT_MSG(enbApp, "cannot retrieve EpcEnbApplication");
189  Ptr<EpcTestRrc> rrc = CreateObject<EpcTestRrc>();
190  enb->AggregateObject(rrc);
191  rrc->SetS1SapProvider(enbApp->GetS1SapProvider());
192  enbApp->SetS1SapUser(rrc->GetS1SapUser());
193 
194  // we install the IP stack on UEs only
196  internet.Install(ues);
197 
198  // assign IP address to UEs, and install applications
199  for (uint32_t u = 0; u < ues.GetN(); ++u)
200  {
201  Ptr<NetDevice> ueLteDevice = cellDevices.Get(u);
202  Ipv4InterfaceContainer ueIpIface =
203  epcHelper->AssignUeIpv4Address(NetDeviceContainer(ueLteDevice));
204 
205  Ptr<Node> ue = ues.Get(u);
206 
207  // disable IP Forwarding on the UE. This is because we use
208  // CSMA broadcast MAC addresses for this test. The problem
209  // won't happen with a LteUeNetDevice.
210  ue->GetObject<Ipv4>()->SetAttribute("IpForward", BooleanValue(false));
211 
212  uint16_t port = 1234;
213  PacketSinkHelper packetSinkHelper("ns3::UdpSocketFactory",
214  InetSocketAddress(Ipv4Address::GetAny(), port));
215  ApplicationContainer apps = packetSinkHelper.Install(ue);
216  apps.Start(Seconds(1.0));
217  apps.Stop(Seconds(10.0));
218  enbit->ues[u].serverApp = apps.Get(0)->GetObject<PacketSink>();
219 
220  Time interPacketInterval = Seconds(0.01);
221  UdpEchoClientHelper client(ueIpIface.GetAddress(0), port);
222  client.SetAttribute("MaxPackets", UintegerValue(enbit->ues[u].numPkts));
223  client.SetAttribute("Interval", TimeValue(interPacketInterval));
224  client.SetAttribute("PacketSize", UintegerValue(enbit->ues[u].pktSize));
225  apps = client.Install(remoteHost);
226  apps.Start(Seconds(2.0));
227  apps.Stop(Seconds(10.0));
228  enbit->ues[u].clientApp = apps.Get(0);
229 
230  uint64_t imsi = ++imsiCounter;
231  epcHelper->AddUe(ueLteDevice, imsi);
232  epcHelper->ActivateEpsBearer(ueLteDevice,
233  imsi,
234  EpcTft::Default(),
235  EpsBearer(EpsBearer::NGBR_VIDEO_TCP_DEFAULT));
236  Simulator::Schedule(MilliSeconds(10),
237  &EpcEnbS1SapProvider::InitialUeMessage,
238  enbApp->GetS1SapProvider(),
239  imsi,
240  (uint16_t)imsi);
241  }
242  }
243 
244  Simulator::Run();
245 
246  for (auto enbit = m_enbDlTestData.begin(); enbit < m_enbDlTestData.end(); ++enbit)
247  {
248  for (auto ueit = enbit->ues.begin(); ueit < enbit->ues.end(); ++ueit)
249  {
250  NS_TEST_ASSERT_MSG_EQ(ueit->serverApp->GetTotalRx(),
251  (ueit->numPkts) * (ueit->pktSize),
252  "wrong total received bytes");
253  }
254  }
255 
256  Simulator::Destroy();
257 }
258 
263 {
264  public:
266 
268 
270  : TestSuite("epc-s1u-downlink", SYSTEM)
271 {
272  std::vector<EnbDlTestData> v1;
273  EnbDlTestData e1;
274  UeDlTestData f1(1, 100);
275  e1.ues.push_back(f1);
276  v1.push_back(e1);
277  AddTestCase(new EpcS1uDlTestCase("1 eNB, 1UE", v1), TestCase::QUICK);
278 
279  std::vector<EnbDlTestData> v2;
280  EnbDlTestData e2;
281  UeDlTestData f2_1(1, 100);
282  e2.ues.push_back(f2_1);
283  UeDlTestData f2_2(2, 200);
284  e2.ues.push_back(f2_2);
285  v2.push_back(e2);
286  AddTestCase(new EpcS1uDlTestCase("1 eNB, 2UEs", v2), TestCase::QUICK);
287 
288  std::vector<EnbDlTestData> v3;
289  v3.push_back(e1);
290  v3.push_back(e2);
291  AddTestCase(new EpcS1uDlTestCase("2 eNBs", v3), TestCase::QUICK);
292 
293  EnbDlTestData e3;
294  UeDlTestData f3_1(3, 50);
295  e3.ues.push_back(f3_1);
296  UeDlTestData f3_2(5, 1472);
297  e3.ues.push_back(f3_2);
298  UeDlTestData f3_3(1, 1);
299  e3.ues.push_back(f3_2);
300  std::vector<EnbDlTestData> v4;
301  v4.push_back(e3);
302  v4.push_back(e1);
303  v4.push_back(e2);
304  AddTestCase(new EpcS1uDlTestCase("3 eNBs", v4), TestCase::QUICK);
305 
306  std::vector<EnbDlTestData> v5;
307  EnbDlTestData e5;
308  UeDlTestData f5(10, 3000);
309  e5.ues.push_back(f5);
310  v5.push_back(e5);
311  AddTestCase(new EpcS1uDlTestCase("1 eNB, 10 pkts 3000 bytes each", v5), TestCase::QUICK);
312 
313  std::vector<EnbDlTestData> v6;
314  EnbDlTestData e6;
315  UeDlTestData f6(50, 3000);
316  e6.ues.push_back(f6);
317  v6.push_back(e6);
318  AddTestCase(new EpcS1uDlTestCase("1 eNB, 50 pkts 3000 bytes each", v6), TestCase::QUICK);
319 
320  std::vector<EnbDlTestData> v7;
321  EnbDlTestData e7;
322  UeDlTestData f7(10, 15000);
323  e7.ues.push_back(f7);
324  v7.push_back(e7);
325  AddTestCase(new EpcS1uDlTestCase("1 eNB, 10 pkts 15000 bytes each", v7), TestCase::QUICK);
326 
327  std::vector<EnbDlTestData> v8;
328  EnbDlTestData e8;
329  UeDlTestData f8(100, 15000);
330  e8.ues.push_back(f8);
331  v8.push_back(e8);
332  AddTestCase(new EpcS1uDlTestCase("1 eNB, 100 pkts 15000 bytes each", v8), TestCase::QUICK);
333 }
EpcS1uDlTestCase class.
std::vector< EnbDlTestData > m_enbDlTestData
ENB DL test data.
EpcS1uDlTestCase(std::string name, std::vector< EnbDlTestData > v)
Constructor.
void DoRun() override
Implementation to actually run this TestCase.
Test that the S1-U interface implementation works correctly.
holds a vector of ns3::Application pointers.
void Start(Time start) const
Start all of the Applications in this container at the start time given as a parameter.
Ptr< Application > Get(uint32_t i) const
Get the Ptr<Application> stored in this container at a given index.
void Stop(Time stop) const
Arrange for all of the Applications in this container to Stop() at the Time given as a parameter.
build a set of CsmaNetDevice objects
Definition: csma-helper.h:48
NetDeviceContainer Install(Ptr< Node > node) const
This method creates an ns3::CsmaChannel with the attributes configured by CsmaHelper::SetChannelAttri...
Definition: csma-helper.cc:226
This application is installed inside eNBs and provides the bridge functionality for user data plane p...
This class contains the specification of EPS Bearers.
Definition: eps-bearer.h:91
an Inet address class
aggregate IP/TCP/UDP functionality to existing Nodes.
A helper class to make life easier while doing simple IPv4 address assignment in scripts.
void SetBase(Ipv4Address network, Ipv4Mask mask, Ipv4Address base="0.0.0.1")
Set the base network number, network mask and base address.
Ipv4InterfaceContainer Assign(const NetDeviceContainer &c)
Assign IP addresses to the net devices specified in the container based on the current network prefix...
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:42
Access to the IPv4 forwarding table, interfaces, and configuration.
Definition: ipv4.h:80
holds a vector of std::pair of Ptr<Ipv4> and interface index.
Ipv4Address GetAddress(uint32_t i, uint32_t j=0) const
a class to represent an Ipv4 address mask
Definition: ipv4-address.h:257
Helper class that adds ns3::Ipv4StaticRouting objects.
Ptr< Ipv4StaticRouting > GetStaticRouting(Ptr< Ipv4 > ipv4) const
Try and find the static routing protocol as either the main routing protocol or in the list of routin...
holds a vector of ns3::NetDevice pointers
uint32_t GetN() const
Get the number of Ptr<NetDevice> stored in this container.
Ptr< NetDevice > Get(uint32_t i) const
Get the Ptr<NetDevice> stored in this container at a given index.
void AddUe(Ptr< NetDevice > ueLteDevice, uint64_t imsi) override
Notify the EPC of the existence of a new UE which might attach at a later time.
uint8_t ActivateEpsBearer(Ptr< NetDevice > ueLteDevice, uint64_t imsi, Ptr< EpcTft > tft, EpsBearer bearer) override
Activate an EPS bearer, setting up the corresponding S1-U tunnel.
Ptr< Node > GetPgwNode() const override
Get the PGW node.
Ipv4InterfaceContainer AssignUeIpv4Address(NetDeviceContainer ueDevices) override
Assign IPv4 addresses to UE devices.
keep track of a set of node pointers.
uint32_t GetN() const
Get the number of Ptr<Node> stored in this container.
void Create(uint32_t n)
Create n nodes and append pointers to them to the end of this NodeContainer.
void Add(const NodeContainer &nc)
Append the contents of another NodeContainer to the end of this container.
Ptr< Node > Get(uint32_t i) const
Get the Ptr<Node> stored in this container at a given index.
Ptr< Application > GetApplication(uint32_t index) const
Retrieve the index-th Application associated to this node.
Definition: node.cc:180
void SetAttribute(std::string name, const AttributeValue &value)
Set a single attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:204
Ptr< T > GetObject() const
Get a pointer to the requested aggregated Object.
Definition: object.h:471
void AggregateObject(Ptr< Object > other)
Aggregate two Objects together.
Definition: object.cc:259
A helper to make it easier to instantiate an ns3::PacketSinkApplication on a set of nodes.
Receive and consume traffic generated to an IP address and port.
Definition: packet-sink.h:75
void AddEnb(Ptr< Node > enbNode, Ptr< NetDevice > lteEnbNetDevice, std::vector< uint16_t > cellIds) override
Add an eNB to the EPC.
Build a set of PointToPointNetDevice objects.
void SetDeviceAttribute(std::string name, const AttributeValue &value)
Set an attribute value to be propagated to each NetDevice created by the helper.
NetDeviceContainer Install(NodeContainer c)
encapsulates test code
Definition: test.h:1060
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:301
A suite of tests to run.
Definition: test.h:1256
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
Create an application which sends a UDP packet and waits for an echo of this packet.
Hold an unsigned integer type.
Definition: uinteger.h:45
uint16_t port
Definition: dsdv-manet.cc:44
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition: assert.h:86
void SetDefault(std::string name, const AttributeValue &value)
Definition: config.cc:890
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
void(* DataRate)(DataRate oldValue, DataRate newValue)
TracedValue callback signature for DataRate.
Definition: data-rate.h:327
#define NS_TEST_ASSERT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report and abort if not.
Definition: test.h:144
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1326
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1338
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Custom structure for testing eNodeB downlink data, contains the list of data structures for UEs.
std::vector< UeDlTestData > ues
list of data structure for different UEs
Custom structure for testing UE downlink data.
uint32_t pktSize
packet size
UeDlTestData(uint32_t n, uint32_t s)
Constructor.
uint32_t numPkts
number of packets
Ptr< Application > clientApp
Client application.
Ptr< PacketSink > serverApp
Server application.
uint32_t pktSize
packet size used for the simulation (in bytes)