A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
epc-helper.cc
Go to the documentation of this file.
1 /* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2011-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: Jaume Nin <jnin@cttc.es>
19  * Nicola Baldo <nbaldo@cttc.es>
20  * Manuel Requena <manuel.requena@cttc.es>
21  */
22 
23 #include <ns3/epc-helper.h>
24 #include <ns3/log.h>
25 #include <ns3/inet-socket-address.h>
26 #include <ns3/mac48-address.h>
27 #include <ns3/eps-bearer.h>
28 #include <ns3/ipv4-address.h>
29 #include <ns3/internet-stack-helper.h>
30 #include <ns3/point-to-point-helper.h>
31 #include <ns3/packet-socket-helper.h>
32 #include <ns3/packet-socket-address.h>
33 #include <ns3/epc-enb-application.h>
34 #include <ns3/epc-sgw-pgw-application.h>
35 
36 #include <ns3/lte-enb-rrc.h>
37 #include <ns3/epc-x2.h>
38 #include <ns3/lte-enb-net-device.h>
39 #include <ns3/lte-ue-net-device.h>
40 #include <ns3/epc-mme.h>
41 #include <ns3/epc-ue-nas.h>
42 
43 namespace ns3 {
44 
45 NS_LOG_COMPONENT_DEFINE ("EpcHelper");
46 
47 NS_OBJECT_ENSURE_REGISTERED (EpcHelper);
48 
49 
51  : m_gtpuUdpPort (2152) // fixed by the standard
52 {
53  NS_LOG_FUNCTION (this);
54 
55  // since we use point-to-point links for all S1-U links,
56  // we use a /30 subnet which can hold exactly two addresses
57  // (remember that net broadcast and null address are not valid)
58  m_s1uIpv4AddressHelper.SetBase ("10.0.0.0", "255.255.255.252");
59 
60  m_x2Ipv4AddressHelper.SetBase ("12.0.0.0", "255.255.255.252");
61 
62  // we use a /8 net for all UEs
63  m_ueAddressHelper.SetBase ("7.0.0.0", "255.0.0.0");
64 
65  // create SgwPgwNode
66  m_sgwPgw = CreateObject<Node> ();
67  InternetStackHelper internet;
68  internet.Install (m_sgwPgw);
69 
70  // create S1-U socket
71  Ptr<Socket> sgwPgwS1uSocket = Socket::CreateSocket (m_sgwPgw, TypeId::LookupByName ("ns3::UdpSocketFactory"));
72  int retval = sgwPgwS1uSocket->Bind (InetSocketAddress (Ipv4Address::GetAny (), m_gtpuUdpPort));
73  NS_ASSERT (retval == 0);
74 
75  // create TUN device implementing tunneling of user data over GTP-U/UDP/IP
76  m_tunDevice = CreateObject<VirtualNetDevice> ();
77  // allow jumbo packets
78  m_tunDevice->SetAttribute ("Mtu", UintegerValue (30000));
79 
80  // yes we need this
82 
84  NetDeviceContainer tunDeviceContainer;
85  tunDeviceContainer.Add (m_tunDevice);
86 
87  // the TUN device is on the same subnet as the UEs, so when a packet
88  // addressed to an UE arrives at the intenet to the WAN interface of
89  // the PGW it will be forwarded to the TUN device.
90  Ipv4InterfaceContainer tunDeviceIpv4IfContainer = m_ueAddressHelper.Assign (tunDeviceContainer);
91 
92  // create EpcSgwPgwApplication
93  m_sgwPgwApp = CreateObject<EpcSgwPgwApplication> (m_tunDevice, sgwPgwS1uSocket);
95 
96  // connect SgwPgwApplication and virtual net device for tunneling
97  m_tunDevice->SetSendCallback (MakeCallback (&EpcSgwPgwApplication::RecvFromTunDevice, m_sgwPgwApp));
98 
99  // Create MME and connect with SGW via S11 interface
100  m_mme = CreateObject<EpcMme> ();
101  m_mme->SetS11SapSgw (m_sgwPgwApp->GetS11SapSgw ());
102  m_sgwPgwApp->SetS11SapMme (m_mme->GetS11SapMme ());
103 }
104 
106 {
107  NS_LOG_FUNCTION (this);
108 }
109 
110 TypeId
112 {
113  static TypeId tid = TypeId ("ns3::EpcHelper")
114  .SetParent<Object> ()
115  .AddConstructor<EpcHelper> ()
116  .AddAttribute ("S1uLinkDataRate",
117  "The data rate to be used for the next S1-U link to be created",
118  DataRateValue (DataRate ("10Gb/s")),
119  MakeDataRateAccessor (&EpcHelper::m_s1uLinkDataRate),
120  MakeDataRateChecker ())
121  .AddAttribute ("S1uLinkDelay",
122  "The delay to be used for the next S1-U link to be created",
123  TimeValue (Seconds (0)),
124  MakeTimeAccessor (&EpcHelper::m_s1uLinkDelay),
125  MakeTimeChecker ())
126  .AddAttribute ("S1uLinkMtu",
127  "The MTU of the next S1-U link to be created. Note that, because of the additional GTP/UDP/IP tunneling overhead, you need a MTU larger than the end-to-end MTU that you want to support.",
128  UintegerValue (2000),
129  MakeUintegerAccessor (&EpcHelper::m_s1uLinkMtu),
130  MakeUintegerChecker<uint16_t> ())
131  .AddAttribute ("X2LinkDataRate",
132  "The data rate to be used for the next X2 link to be created",
133  DataRateValue (DataRate ("10Gb/s")),
134  MakeDataRateAccessor (&EpcHelper::m_x2LinkDataRate),
135  MakeDataRateChecker ())
136  .AddAttribute ("X2LinkDelay",
137  "The delay to be used for the next X2 link to be created",
138  TimeValue (Seconds (0)),
139  MakeTimeAccessor (&EpcHelper::m_x2LinkDelay),
140  MakeTimeChecker ())
141  .AddAttribute ("X2LinkMtu",
142  "The MTU of the next X2 link to be created. Note that, because of some big X2 messages, you need a big MTU.",
143  UintegerValue (3000),
144  MakeUintegerAccessor (&EpcHelper::m_x2LinkMtu),
145  MakeUintegerChecker<uint16_t> ())
146  ;
147  return tid;
148 }
149 
150 void
152 {
153  NS_LOG_FUNCTION (this);
154  m_tunDevice->SetSendCallback (MakeNullCallback<bool, Ptr<Packet>, const Address&, const Address&, uint16_t> ());
155  m_tunDevice = 0;
156  m_sgwPgwApp = 0;
157  m_sgwPgw->Dispose ();
158 }
159 
160 
161 void
162 EpcHelper::AddEnb (Ptr<Node> enb, Ptr<NetDevice> lteEnbNetDevice, uint16_t cellId)
163 {
164  NS_LOG_FUNCTION (this << enb << lteEnbNetDevice << cellId);
165 
166  NS_ASSERT (enb == lteEnbNetDevice->GetNode ());
167 
168  // add an IPv4 stack to the previously created eNB
169  InternetStackHelper internet;
170  internet.Install (enb);
171  NS_LOG_LOGIC ("number of Ipv4 ifaces of the eNB after node creation: " << enb->GetObject<Ipv4> ()->GetNInterfaces ());
172 
173  // create a point to point link between the new eNB and the SGW with
174  // the corresponding new NetDevices on each side
175  NodeContainer enbSgwNodes;
176  enbSgwNodes.Add (m_sgwPgw);
177  enbSgwNodes.Add (enb);
178  PointToPointHelper p2ph;
181  p2ph.SetChannelAttribute ("Delay", TimeValue (m_s1uLinkDelay));
182  NetDeviceContainer enbSgwDevices = p2ph.Install (enb, m_sgwPgw);
183  NS_LOG_LOGIC ("number of Ipv4 ifaces of the eNB after installing p2p dev: " << enb->GetObject<Ipv4> ()->GetNInterfaces ());
184  Ptr<NetDevice> enbDev = enbSgwDevices.Get (0);
185  Ptr<NetDevice> sgwDev = enbSgwDevices.Get (1);
187  Ipv4InterfaceContainer enbSgwIpIfaces = m_s1uIpv4AddressHelper.Assign (enbSgwDevices);
188  NS_LOG_LOGIC ("number of Ipv4 ifaces of the eNB after assigning Ipv4 addr to S1 dev: " << enb->GetObject<Ipv4> ()->GetNInterfaces ());
189 
190  Ipv4Address enbAddress = enbSgwIpIfaces.GetAddress (0);
191  Ipv4Address sgwAddress = enbSgwIpIfaces.GetAddress (1);
192 
193  // create S1-U socket for the ENB
194  Ptr<Socket> enbS1uSocket = Socket::CreateSocket (enb, TypeId::LookupByName ("ns3::UdpSocketFactory"));
195  int retval = enbS1uSocket->Bind (InetSocketAddress (enbAddress, m_gtpuUdpPort));
196  NS_ASSERT (retval == 0);
197 
198 
199  // give PacketSocket powers to the eNB
200  //PacketSocketHelper packetSocket;
201  //packetSocket.Install (enb);
202 
203  // create LTE socket for the ENB
204  Ptr<Socket> enbLteSocket = Socket::CreateSocket (enb, TypeId::LookupByName ("ns3::PacketSocketFactory"));
205  PacketSocketAddress enbLteSocketBindAddress;
206  enbLteSocketBindAddress.SetSingleDevice (lteEnbNetDevice->GetIfIndex ());
207  enbLteSocketBindAddress.SetProtocol (Ipv4L3Protocol::PROT_NUMBER);
208  retval = enbLteSocket->Bind (enbLteSocketBindAddress);
209  NS_ASSERT (retval == 0);
210  PacketSocketAddress enbLteSocketConnectAddress;
211  enbLteSocketConnectAddress.SetPhysicalAddress (Mac48Address::GetBroadcast ());
212  enbLteSocketConnectAddress.SetSingleDevice (lteEnbNetDevice->GetIfIndex ());
213  enbLteSocketConnectAddress.SetProtocol (Ipv4L3Protocol::PROT_NUMBER);
214  retval = enbLteSocket->Connect (enbLteSocketConnectAddress);
215  NS_ASSERT (retval == 0);
216 
217 
218  NS_LOG_INFO ("create EpcEnbApplication");
219  Ptr<EpcEnbApplication> enbApp = CreateObject<EpcEnbApplication> (enbLteSocket, enbS1uSocket, enbAddress, sgwAddress, cellId);
220  enb->AddApplication (enbApp);
221  NS_ASSERT (enb->GetNApplications () == 1);
222  NS_ASSERT_MSG (enb->GetApplication (0)->GetObject<EpcEnbApplication> () != 0, "cannot retrieve EpcEnbApplication");
223  NS_LOG_LOGIC ("enb: " << enb << ", enb->GetApplication (0): " << enb->GetApplication (0));
224 
225 
226  NS_LOG_INFO ("Create EpcX2 entity");
227  Ptr<EpcX2> x2 = CreateObject<EpcX2> ();
228  enb->AggregateObject (x2);
229 
230  NS_LOG_INFO ("connect S1-AP interface");
231  m_mme->AddEnb (cellId, enbAddress, enbApp->GetS1apSapEnb ());
232  m_sgwPgwApp->AddEnb (cellId, enbAddress, sgwAddress);
233  enbApp->SetS1apSapMme (m_mme->GetS1apSapMme ());
234 }
235 
236 
237 void
239 {
240  NS_LOG_FUNCTION (this << enb1 << enb2);
241 
242  // Create a point to point link between the two eNBs with
243  // the corresponding new NetDevices on each side
244  NodeContainer enbNodes;
245  enbNodes.Add (enb1);
246  enbNodes.Add (enb2);
247  PointToPointHelper p2ph;
250  p2ph.SetChannelAttribute ("Delay", TimeValue (m_x2LinkDelay));
251  NetDeviceContainer enbDevices = p2ph.Install (enb1, enb2);
252  NS_LOG_LOGIC ("number of Ipv4 ifaces of the eNB #1 after installing p2p dev: " << enb1->GetObject<Ipv4> ()->GetNInterfaces ());
253  NS_LOG_LOGIC ("number of Ipv4 ifaces of the eNB #2 after installing p2p dev: " << enb2->GetObject<Ipv4> ()->GetNInterfaces ());
254  Ptr<NetDevice> enb1Dev = enbDevices.Get (0);
255  Ptr<NetDevice> enb2Dev = enbDevices.Get (1);
256 
258  Ipv4InterfaceContainer enbIpIfaces = m_x2Ipv4AddressHelper.Assign (enbDevices);
259  NS_LOG_LOGIC ("number of Ipv4 ifaces of the eNB #1 after assigning Ipv4 addr to X2 dev: " << enb1->GetObject<Ipv4> ()->GetNInterfaces ());
260  NS_LOG_LOGIC ("number of Ipv4 ifaces of the eNB #2 after assigning Ipv4 addr to X2 dev: " << enb2->GetObject<Ipv4> ()->GetNInterfaces ());
261 
262  Ipv4Address enb1X2Address = enbIpIfaces.GetAddress (0);
263  Ipv4Address enb2X2Address = enbIpIfaces.GetAddress (1);
264 
265  // Add X2 interface to both eNBs' X2 entities
266  Ptr<EpcX2> enb1X2 = enb1->GetObject<EpcX2> ();
267  Ptr<LteEnbNetDevice> enb1LteDev = enb1->GetDevice (0)->GetObject<LteEnbNetDevice> ();
268  uint16_t enb1CellId = enb1LteDev->GetCellId ();
269  NS_LOG_LOGIC ("LteEnbNetDevice #1 = " << enb1LteDev << " - CellId = " << enb1CellId);
270 
271  Ptr<EpcX2> enb2X2 = enb2->GetObject<EpcX2> ();
272  Ptr<LteEnbNetDevice> enb2LteDev = enb2->GetDevice (0)->GetObject<LteEnbNetDevice> ();
273  uint16_t enb2CellId = enb2LteDev->GetCellId ();
274  NS_LOG_LOGIC ("LteEnbNetDevice #2 = " << enb2LteDev << " - CellId = " << enb2CellId);
275 
276  enb1X2->AddX2Interface (enb1CellId, enb1X2Address, enb2CellId, enb2X2Address);
277  enb2X2->AddX2Interface (enb2CellId, enb2X2Address, enb1CellId, enb1X2Address);
278 
279  enb1LteDev->GetRrc ()->AddX2Neighbour (enb2LteDev->GetCellId ());
280  enb2LteDev->GetRrc ()->AddX2Neighbour (enb1LteDev->GetCellId ());
281 }
282 
283 
284 void
285 EpcHelper::AddUe (Ptr<NetDevice> ueDevice, uint64_t imsi)
286 {
287  NS_LOG_FUNCTION (this << imsi << ueDevice );
288 
289  m_mme->AddUe (imsi);
290  m_sgwPgwApp->AddUe (imsi);
291 
292 
293 }
294 
295 void
296 EpcHelper::ActivateEpsBearer (Ptr<NetDevice> ueDevice, uint64_t imsi, Ptr<EpcTft> tft, EpsBearer bearer)
297 {
298  NS_LOG_FUNCTION (this << ueDevice << imsi);
299 
300  // we now retrieve the IPv4 address of the UE and notify it to the SGW;
301  // we couldn't do it before since address assignment is triggered by
302  // the user simulation program, rather than done by the EPC
303  Ptr<Node> ueNode = ueDevice->GetNode ();
304  Ptr<Ipv4> ueIpv4 = ueNode->GetObject<Ipv4> ();
305  NS_ASSERT_MSG (ueIpv4 != 0, "UEs need to have IPv4 installed before EPS bearers can be activated");
306  int32_t interface = ueIpv4->GetInterfaceForDevice (ueDevice);
307  NS_ASSERT (interface >= 0);
308  NS_ASSERT (ueIpv4->GetNAddresses (interface) == 1);
309  Ipv4Address ueAddr = ueIpv4->GetAddress (interface, 0).GetLocal ();
310  NS_LOG_LOGIC (" UE IP address: " << ueAddr); m_sgwPgwApp->SetUeAddress (imsi, ueAddr);
311 
312  m_mme->AddBearer (imsi, tft, bearer);
313  Ptr<LteUeNetDevice> ueLteDevice = ueDevice->GetObject<LteUeNetDevice> ();
314  if (ueLteDevice)
315  {
316  ueLteDevice->GetNas ()->ActivateEpsBearer (bearer, tft);
317  }
318 }
319 
320 
321 Ptr<Node>
323 {
324  return m_sgwPgw;
325 }
326 
327 
330 {
331  return m_ueAddressHelper.Assign (ueDevices);
332 }
333 
334 
335 
338 {
339  // return the address of the tun device
340  return m_sgwPgw->GetObject<Ipv4> ()->GetAddress (1, 0).GetLocal ();
341 }
342 
343 
344 } // namespace ns3
Ipv4AddressHelper m_x2Ipv4AddressHelper
Definition: epc-helper.h:179
uint32_t AddApplication(Ptr< Application > application)
Definition: node.cc:146
an Inet address class
static Ipv4Address GetAny(void)
#define NS_LOG_FUNCTION(parameters)
Definition: log.h:311
uint32_t GetNApplications(void) const
Definition: node.cc:165
holds a vector of std::pair of Ptr and interface index.
uint16_t GetCellId() const
Ptr< NetDevice > Get(uint32_t i) const
Get the Ptr stored in this container at a given index.
Time m_x2LinkDelay
Definition: epc-helper.h:182
NetDeviceContainer Install(NodeContainer c)
uint16_t m_s1uLinkMtu
Definition: epc-helper.h:163
DataRate m_x2LinkDataRate
Definition: epc-helper.h:181
an address for a packet socket
Ptr< EpcMme > m_mme
Definition: epc-helper.h:150
#define NS_ASSERT(condition)
Definition: assert.h:64
aggregate IP/TCP/UDP functionality to existing Nodes.
#define NS_LOG_INFO(msg)
Definition: log.h:264
Callback< R > MakeNullCallback(void)
Definition: callback.h:1395
Build a set of PointToPointNetDevice objects.
Ptr< VirtualNetDevice > m_tunDevice
Definition: epc-helper.h:149
void SetDeviceAttribute(std::string name, const AttributeValue &value)
uint16_t m_gtpuUdpPort
Definition: epc-helper.h:168
void SetSingleDevice(uint32_t device)
Ptr< EpcSgwPgwApplication > m_sgwPgwApp
Definition: epc-helper.h:148
Ptr< Node > GetPgwNode()
Definition: epc-helper.cc:322
a polymophic address class
Definition: address.h:86
Class for representing data rates.
Definition: data-rate.h:71
Ptr< Application > GetApplication(uint32_t index) const
Definition: node.cc:157
static Mac48Address Allocate(void)
hold objects of type ns3::Time
Definition: nstime.h:828
bool RecvFromTunDevice(Ptr< Packet > packet, const Address &source, const Address &dest, uint16_t protocolNumber)
void Add(NetDeviceContainer other)
Append the contents of another NetDeviceContainer to the end of this container.
Hold an unsigned integer type.
Definition: uinteger.h:46
virtual void SetAddress(Address address)
NS_OBJECT_ENSURE_REGISTERED(AntennaModel)
holds a vector of ns3::NetDevice pointers
Ptr< NetDevice > GetDevice(uint32_t index) const
Definition: node.cc:131
static Mac48Address GetBroadcast(void)
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:1238
static Ptr< Socket > CreateSocket(Ptr< Node > node, TypeId tid)
Definition: socket.cc:70
virtual ~EpcHelper()
Definition: epc-helper.cc:105
void AggregateObject(Ptr< Object > other)
Definition: object.cc:242
#define NS_LOG_LOGIC(msg)
Definition: log.h:334
virtual int Connect(const Address &address)=0
Initiate a connection to a remote host.
Access to the Ipv4 forwarding table, interfaces, and configuration.
Definition: ipv4.h:75
uint16_t m_x2LinkMtu
Definition: epc-helper.h:183
void AddUe(Ptr< NetDevice > ueLteDevice, uint64_t imsi)
Definition: epc-helper.cc:285
virtual int Bind(const Address &address)=0
Allocate a local endpoint for this socket.
virtual void DoDispose()
Definition: epc-helper.cc:151
void SetPhysicalAddress(const Address address)
keep track of a set of node pointers.
Time m_s1uLinkDelay
Definition: epc-helper.h:162
void Install(std::string nodeName) const
Ptr< Node > m_sgwPgw
Definition: epc-helper.h:147
void SetChannelAttribute(std::string name, const AttributeValue &value)
#define NS_ASSERT_MSG(condition, message)
Definition: assert.h:86
Ipv4InterfaceContainer AssignUeIpv4Address(NetDeviceContainer ueDevices)
Definition: epc-helper.cc:329
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:38
Ipv4InterfaceContainer Assign(const NetDeviceContainer &c)
Assign IP addresses to the net devices specified in the container based on the current network prefix...
void Add(NodeContainer other)
Append the contents of another NodeContainer to the end of this container.
NS_LOG_COMPONENT_DEFINE("PacketLossCounter")
uint32_t AddDevice(Ptr< NetDevice > device)
Definition: node.cc:117
hold objects of type ns3::DataRate
void SetProtocol(uint16_t protocol)
static TypeId GetTypeId(void)
Definition: epc-helper.cc:111
Ipv4Address NewNetwork(void)
Increment the network number and reset the IP address counter to the base value provided in the SetBa...
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range. Both limits are inclusive.
Definition: time.cc:404
DataRate m_s1uLinkDataRate
Definition: epc-helper.h:161
void ActivateEpsBearer(Ptr< NetDevice > ueLteDevice, uint64_t imsi, Ptr< EpcTft > tft, EpsBearer bearer)
Definition: epc-helper.cc:296
a base class which provides memory management and object aggregation
Definition: object.h:63
Ipv4AddressHelper m_s1uIpv4AddressHelper
Definition: epc-helper.h:159
void SetSendCallback(SendCallback transmitCb)
Set the user callback to be called when a L2 packet is to be transmitted.
void AddEnb(Ptr< Node > enbNode, Ptr< NetDevice > lteEnbNetDevice, uint16_t cellId)
Definition: epc-helper.cc:162
void SetAttribute(std::string name, const AttributeValue &value)
Definition: object-base.cc:160
Ptr< T > GetObject(void) const
Definition: object.h:360
void AddX2Interface(Ptr< Node > enbNode1, Ptr< Node > enbNode2)
Definition: epc-helper.cc:238
a unique identifier for an interface.
Definition: type-id.h:49
TypeId SetParent(TypeId tid)
Definition: type-id.cc:610
void Dispose(void)
Definition: object.cc:204
Ipv4Address GetUeDefaultGatewayAddress()
Definition: epc-helper.cc:337
virtual uint32_t GetNInterfaces(void) const =0
static const uint16_t PROT_NUMBER
void SetBase(Ipv4Address network, Ipv4Mask mask, Ipv4Address base="0.0.0.1")
Set the base network number, network mask and base address.
Ipv4AddressHelper m_ueAddressHelper
Definition: epc-helper.h:145
static TypeId LookupByName(std::string name)
Definition: type-id.cc:535
Ipv4Address GetAddress(uint32_t i, uint32_t j=0) const