A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
point-to-point-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-2013 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/point-to-point-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 ("PointToPointEpcHelper")
46  ;
47 
48 NS_OBJECT_ENSURE_REGISTERED (PointToPointEpcHelper)
49  ;
50 
51 
53  : m_gtpuUdpPort (2152) // fixed by the standard
54 {
55  NS_LOG_FUNCTION (this);
56 
57  // since we use point-to-point links for all S1-U links,
58  // we use a /30 subnet which can hold exactly two addresses
59  // (remember that net broadcast and null address are not valid)
60  m_s1uIpv4AddressHelper.SetBase ("10.0.0.0", "255.255.255.252");
61 
62  m_x2Ipv4AddressHelper.SetBase ("12.0.0.0", "255.255.255.252");
63 
64  // we use a /8 net for all UEs
65  m_ueAddressHelper.SetBase ("7.0.0.0", "255.0.0.0");
66 
67  // create SgwPgwNode
68  m_sgwPgw = CreateObject<Node> ();
69  InternetStackHelper internet;
70  internet.Install (m_sgwPgw);
71 
72  // create S1-U socket
73  Ptr<Socket> sgwPgwS1uSocket = Socket::CreateSocket (m_sgwPgw, TypeId::LookupByName ("ns3::UdpSocketFactory"));
74  int retval = sgwPgwS1uSocket->Bind (InetSocketAddress (Ipv4Address::GetAny (), m_gtpuUdpPort));
75  NS_ASSERT (retval == 0);
76 
77  // create TUN device implementing tunneling of user data over GTP-U/UDP/IP
78  m_tunDevice = CreateObject<VirtualNetDevice> ();
79  // allow jumbo packets
80  m_tunDevice->SetAttribute ("Mtu", UintegerValue (30000));
81 
82  // yes we need this
84 
86  NetDeviceContainer tunDeviceContainer;
87  tunDeviceContainer.Add (m_tunDevice);
88 
89  // the TUN device is on the same subnet as the UEs, so when a packet
90  // addressed to an UE arrives at the intenet to the WAN interface of
91  // the PGW it will be forwarded to the TUN device.
92  Ipv4InterfaceContainer tunDeviceIpv4IfContainer = m_ueAddressHelper.Assign (tunDeviceContainer);
93 
94  // create EpcSgwPgwApplication
95  m_sgwPgwApp = CreateObject<EpcSgwPgwApplication> (m_tunDevice, sgwPgwS1uSocket);
97 
98  // connect SgwPgwApplication and virtual net device for tunneling
99  m_tunDevice->SetSendCallback (MakeCallback (&EpcSgwPgwApplication::RecvFromTunDevice, m_sgwPgwApp));
100 
101  // Create MME and connect with SGW via S11 interface
102  m_mme = CreateObject<EpcMme> ();
103  m_mme->SetS11SapSgw (m_sgwPgwApp->GetS11SapSgw ());
104  m_sgwPgwApp->SetS11SapMme (m_mme->GetS11SapMme ());
105 }
106 
108 {
109  NS_LOG_FUNCTION (this);
110 }
111 
112 TypeId
114 {
115  static TypeId tid = TypeId ("ns3::PointToPointEpcHelper")
116  .SetParent<EpcHelper> ()
117  .AddConstructor<PointToPointEpcHelper> ()
118  .AddAttribute ("S1uLinkDataRate",
119  "The data rate to be used for the next S1-U link to be created",
120  DataRateValue (DataRate ("10Gb/s")),
121  MakeDataRateAccessor (&PointToPointEpcHelper::m_s1uLinkDataRate),
122  MakeDataRateChecker ())
123  .AddAttribute ("S1uLinkDelay",
124  "The delay to be used for the next S1-U link to be created",
125  TimeValue (Seconds (0)),
126  MakeTimeAccessor (&PointToPointEpcHelper::m_s1uLinkDelay),
127  MakeTimeChecker ())
128  .AddAttribute ("S1uLinkMtu",
129  "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.",
130  UintegerValue (2000),
131  MakeUintegerAccessor (&PointToPointEpcHelper::m_s1uLinkMtu),
132  MakeUintegerChecker<uint16_t> ())
133  .AddAttribute ("X2LinkDataRate",
134  "The data rate to be used for the next X2 link to be created",
135  DataRateValue (DataRate ("10Gb/s")),
136  MakeDataRateAccessor (&PointToPointEpcHelper::m_x2LinkDataRate),
137  MakeDataRateChecker ())
138  .AddAttribute ("X2LinkDelay",
139  "The delay to be used for the next X2 link to be created",
140  TimeValue (Seconds (0)),
141  MakeTimeAccessor (&PointToPointEpcHelper::m_x2LinkDelay),
142  MakeTimeChecker ())
143  .AddAttribute ("X2LinkMtu",
144  "The MTU of the next X2 link to be created. Note that, because of some big X2 messages, you need a big MTU.",
145  UintegerValue (3000),
146  MakeUintegerAccessor (&PointToPointEpcHelper::m_x2LinkMtu),
147  MakeUintegerChecker<uint16_t> ())
148  ;
149  return tid;
150 }
151 
152 void
154 {
155  NS_LOG_FUNCTION (this);
156  m_tunDevice->SetSendCallback (MakeNullCallback<bool, Ptr<Packet>, const Address&, const Address&, uint16_t> ());
157  m_tunDevice = 0;
158  m_sgwPgwApp = 0;
159  m_sgwPgw->Dispose ();
160 }
161 
162 
163 void
164 PointToPointEpcHelper::AddEnb (Ptr<Node> enb, Ptr<NetDevice> lteEnbNetDevice, uint16_t cellId)
165 {
166  NS_LOG_FUNCTION (this << enb << lteEnbNetDevice << cellId);
167 
168  NS_ASSERT (enb == lteEnbNetDevice->GetNode ());
169 
170  // add an IPv4 stack to the previously created eNB
171  InternetStackHelper internet;
172  internet.Install (enb);
173  NS_LOG_LOGIC ("number of Ipv4 ifaces of the eNB after node creation: " << enb->GetObject<Ipv4> ()->GetNInterfaces ());
174 
175  // create a point to point link between the new eNB and the SGW with
176  // the corresponding new NetDevices on each side
177  NodeContainer enbSgwNodes;
178  enbSgwNodes.Add (m_sgwPgw);
179  enbSgwNodes.Add (enb);
180  PointToPointHelper p2ph;
183  p2ph.SetChannelAttribute ("Delay", TimeValue (m_s1uLinkDelay));
184  NetDeviceContainer enbSgwDevices = p2ph.Install (enb, m_sgwPgw);
185  NS_LOG_LOGIC ("number of Ipv4 ifaces of the eNB after installing p2p dev: " << enb->GetObject<Ipv4> ()->GetNInterfaces ());
186  Ptr<NetDevice> enbDev = enbSgwDevices.Get (0);
187  Ptr<NetDevice> sgwDev = enbSgwDevices.Get (1);
189  Ipv4InterfaceContainer enbSgwIpIfaces = m_s1uIpv4AddressHelper.Assign (enbSgwDevices);
190  NS_LOG_LOGIC ("number of Ipv4 ifaces of the eNB after assigning Ipv4 addr to S1 dev: " << enb->GetObject<Ipv4> ()->GetNInterfaces ());
191 
192  Ipv4Address enbAddress = enbSgwIpIfaces.GetAddress (0);
193  Ipv4Address sgwAddress = enbSgwIpIfaces.GetAddress (1);
194 
195  // create S1-U socket for the ENB
196  Ptr<Socket> enbS1uSocket = Socket::CreateSocket (enb, TypeId::LookupByName ("ns3::UdpSocketFactory"));
197  int retval = enbS1uSocket->Bind (InetSocketAddress (enbAddress, m_gtpuUdpPort));
198  NS_ASSERT (retval == 0);
199 
200 
201  // give PacketSocket powers to the eNB
202  //PacketSocketHelper packetSocket;
203  //packetSocket.Install (enb);
204 
205  // create LTE socket for the ENB
206  Ptr<Socket> enbLteSocket = Socket::CreateSocket (enb, TypeId::LookupByName ("ns3::PacketSocketFactory"));
207  PacketSocketAddress enbLteSocketBindAddress;
208  enbLteSocketBindAddress.SetSingleDevice (lteEnbNetDevice->GetIfIndex ());
209  enbLteSocketBindAddress.SetProtocol (Ipv4L3Protocol::PROT_NUMBER);
210  retval = enbLteSocket->Bind (enbLteSocketBindAddress);
211  NS_ASSERT (retval == 0);
212  PacketSocketAddress enbLteSocketConnectAddress;
213  enbLteSocketConnectAddress.SetPhysicalAddress (Mac48Address::GetBroadcast ());
214  enbLteSocketConnectAddress.SetSingleDevice (lteEnbNetDevice->GetIfIndex ());
215  enbLteSocketConnectAddress.SetProtocol (Ipv4L3Protocol::PROT_NUMBER);
216  retval = enbLteSocket->Connect (enbLteSocketConnectAddress);
217  NS_ASSERT (retval == 0);
218 
219 
220  NS_LOG_INFO ("create EpcEnbApplication");
221  Ptr<EpcEnbApplication> enbApp = CreateObject<EpcEnbApplication> (enbLteSocket, enbS1uSocket, enbAddress, sgwAddress, cellId);
222  enb->AddApplication (enbApp);
223  NS_ASSERT (enb->GetNApplications () == 1);
224  NS_ASSERT_MSG (enb->GetApplication (0)->GetObject<EpcEnbApplication> () != 0, "cannot retrieve EpcEnbApplication");
225  NS_LOG_LOGIC ("enb: " << enb << ", enb->GetApplication (0): " << enb->GetApplication (0));
226 
227 
228  NS_LOG_INFO ("Create EpcX2 entity");
229  Ptr<EpcX2> x2 = CreateObject<EpcX2> ();
230  enb->AggregateObject (x2);
231 
232  NS_LOG_INFO ("connect S1-AP interface");
233  m_mme->AddEnb (cellId, enbAddress, enbApp->GetS1apSapEnb ());
234  m_sgwPgwApp->AddEnb (cellId, enbAddress, sgwAddress);
235  enbApp->SetS1apSapMme (m_mme->GetS1apSapMme ());
236 }
237 
238 
239 void
241 {
242  NS_LOG_FUNCTION (this << enb1 << enb2);
243 
244  // Create a point to point link between the two eNBs with
245  // the corresponding new NetDevices on each side
246  NodeContainer enbNodes;
247  enbNodes.Add (enb1);
248  enbNodes.Add (enb2);
249  PointToPointHelper p2ph;
252  p2ph.SetChannelAttribute ("Delay", TimeValue (m_x2LinkDelay));
253  NetDeviceContainer enbDevices = p2ph.Install (enb1, enb2);
254  NS_LOG_LOGIC ("number of Ipv4 ifaces of the eNB #1 after installing p2p dev: " << enb1->GetObject<Ipv4> ()->GetNInterfaces ());
255  NS_LOG_LOGIC ("number of Ipv4 ifaces of the eNB #2 after installing p2p dev: " << enb2->GetObject<Ipv4> ()->GetNInterfaces ());
256  Ptr<NetDevice> enb1Dev = enbDevices.Get (0);
257  Ptr<NetDevice> enb2Dev = enbDevices.Get (1);
258 
260  Ipv4InterfaceContainer enbIpIfaces = m_x2Ipv4AddressHelper.Assign (enbDevices);
261  NS_LOG_LOGIC ("number of Ipv4 ifaces of the eNB #1 after assigning Ipv4 addr to X2 dev: " << enb1->GetObject<Ipv4> ()->GetNInterfaces ());
262  NS_LOG_LOGIC ("number of Ipv4 ifaces of the eNB #2 after assigning Ipv4 addr to X2 dev: " << enb2->GetObject<Ipv4> ()->GetNInterfaces ());
263 
264  Ipv4Address enb1X2Address = enbIpIfaces.GetAddress (0);
265  Ipv4Address enb2X2Address = enbIpIfaces.GetAddress (1);
266 
267  // Add X2 interface to both eNBs' X2 entities
268  Ptr<EpcX2> enb1X2 = enb1->GetObject<EpcX2> ();
269  Ptr<LteEnbNetDevice> enb1LteDev = enb1->GetDevice (0)->GetObject<LteEnbNetDevice> ();
270  uint16_t enb1CellId = enb1LteDev->GetCellId ();
271  NS_LOG_LOGIC ("LteEnbNetDevice #1 = " << enb1LteDev << " - CellId = " << enb1CellId);
272 
273  Ptr<EpcX2> enb2X2 = enb2->GetObject<EpcX2> ();
274  Ptr<LteEnbNetDevice> enb2LteDev = enb2->GetDevice (0)->GetObject<LteEnbNetDevice> ();
275  uint16_t enb2CellId = enb2LteDev->GetCellId ();
276  NS_LOG_LOGIC ("LteEnbNetDevice #2 = " << enb2LteDev << " - CellId = " << enb2CellId);
277 
278  enb1X2->AddX2Interface (enb1CellId, enb1X2Address, enb2CellId, enb2X2Address);
279  enb2X2->AddX2Interface (enb2CellId, enb2X2Address, enb1CellId, enb1X2Address);
280 
281  enb1LteDev->GetRrc ()->AddX2Neighbour (enb2LteDev->GetCellId ());
282  enb2LteDev->GetRrc ()->AddX2Neighbour (enb1LteDev->GetCellId ());
283 }
284 
285 
286 void
288 {
289  NS_LOG_FUNCTION (this << imsi << ueDevice );
290 
291  m_mme->AddUe (imsi);
292  m_sgwPgwApp->AddUe (imsi);
293 
294 
295 }
296 
297 void
299 {
300  NS_LOG_FUNCTION (this << ueDevice << imsi);
301 
302  // we now retrieve the IPv4 address of the UE and notify it to the SGW;
303  // we couldn't do it before since address assignment is triggered by
304  // the user simulation program, rather than done by the EPC
305  Ptr<Node> ueNode = ueDevice->GetNode ();
306  Ptr<Ipv4> ueIpv4 = ueNode->GetObject<Ipv4> ();
307  NS_ASSERT_MSG (ueIpv4 != 0, "UEs need to have IPv4 installed before EPS bearers can be activated");
308  int32_t interface = ueIpv4->GetInterfaceForDevice (ueDevice);
309  NS_ASSERT (interface >= 0);
310  NS_ASSERT (ueIpv4->GetNAddresses (interface) == 1);
311  Ipv4Address ueAddr = ueIpv4->GetAddress (interface, 0).GetLocal ();
312  NS_LOG_LOGIC (" UE IP address: " << ueAddr); m_sgwPgwApp->SetUeAddress (imsi, ueAddr);
313 
314  m_mme->AddBearer (imsi, tft, bearer);
315  Ptr<LteUeNetDevice> ueLteDevice = ueDevice->GetObject<LteUeNetDevice> ();
316  if (ueLteDevice)
317  {
318  ueLteDevice->GetNas ()->ActivateEpsBearer (bearer, tft);
319  }
320 }
321 
322 
323 Ptr<Node>
325 {
326  return m_sgwPgw;
327 }
328 
329 
332 {
333  return m_ueAddressHelper.Assign (ueDevices);
334 }
335 
336 
337 
340 {
341  // return the address of the tun device
342  return m_sgwPgw->GetObject<Ipv4> ()->GetAddress (1, 0).GetLocal ();
343 }
344 
345 
346 } // namespace ns3
uint32_t AddApplication(Ptr< Application > application)
Definition: node.cc:147
an Inet address class
static Ipv4Address GetAny(void)
#define NS_LOG_FUNCTION(parameters)
Definition: log.h:345
uint32_t GetNApplications(void) const
Definition: node.cc:166
NS_LOG_COMPONENT_DEFINE("GrantedTimeWindowMpiInterface")
holds a vector of std::pair of Ptr and interface index.
virtual void ActivateEpsBearer(Ptr< NetDevice > ueLteDevice, uint64_t imsi, Ptr< EpcTft > tft, EpsBearer bearer)
Activate an EPS bearer, setting up the corresponding S1-U tunnel.
uint16_t GetCellId() const
Ptr< NetDevice > Get(uint32_t i) const
Get the Ptr stored in this container at a given index.
NetDeviceContainer Install(NodeContainer c)
an address for a packet socket
#define NS_ASSERT(condition)
Definition: assert.h:64
NS_OBJECT_ENSURE_REGISTERED(NullMessageSimulatorImpl)
virtual void AddUe(Ptr< NetDevice > ueLteDevice, uint64_t imsi)
Notify the EPC of the existance of a new UE which might attach at a later time.
aggregate IP/TCP/UDP functionality to existing Nodes.
Ptr< EpcSgwPgwApplication > m_sgwPgwApp
#define NS_LOG_INFO(msg)
Definition: log.h:298
Callback< R > MakeNullCallback(void)
Definition: callback.h:1395
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.
void SetSingleDevice(uint32_t device)
a polymophic address class
Definition: address.h:86
Class for representing data rates.
Definition: data-rate.h:71
This class contains the specification of EPS Bearers.
Definition: eps-bearer.h:71
Ptr< Application > GetApplication(uint32_t index) const
Definition: node.cc:158
static Mac48Address Allocate(void)
Allocate a new Mac48Address.
hold objects of type ns3::Time
Definition: nstime.h:961
bool RecvFromTunDevice(Ptr< Packet > packet, const Address &source, const Address &dest, uint16_t protocolNumber)
Method to be assigned to the callback of the Gi TUN VirtualNetDevice.
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)
Set the address of this interface.
holds a vector of ns3::NetDevice pointers
Ptr< NetDevice > GetDevice(uint32_t index) const
Definition: node.cc:132
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)
This method wraps the creation of sockets that is performed on a given node by a SocketFactory specif...
Definition: socket.cc:71
virtual void DoDispose()
This method is called by Object::Dispose or by the object's destructor, whichever comes first...
void AggregateObject(Ptr< Object > other)
Definition: object.cc:243
#define NS_LOG_LOGIC(msg)
Definition: log.h:368
virtual void AddEnb(Ptr< Node > enbNode, Ptr< NetDevice > lteEnbNetDevice, uint16_t cellId)
Add an eNB to the EPC.
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
Ipv4AddressHelper m_x2Ipv4AddressHelper
helper to assign addresses to X2 NetDevices
Base helper class to handle the creation of the EPC entities.
Definition: epc-helper.h:48
virtual Ipv4Address GetUeDefaultGatewayAddress()
virtual int Bind(const Address &address)=0
Allocate a local endpoint for this socket.
void SetPhysicalAddress(const Address address)
keep track of a set of node pointers.
This entity is installed inside an eNB and provides the functionality for the X2 interface.
Definition: epc-x2.h:70
void Install(std::string nodeName) const
Aggregate implementations of the ns3::Ipv4, ns3::Ipv6, ns3::Udp, and ns3::Tcp classes onto the provid...
Ipv4AddressHelper m_ueAddressHelper
SGW-PGW network element.
uint16_t m_gtpuUdpPort
UDP port where the GTP-U Socket is bound, fixed by the standard as 2152.
void SetChannelAttribute(std::string name, const AttributeValue &value)
Set an attribute value to be propagated to each Channel created by the helper.
#define NS_ASSERT_MSG(condition, message)
Definition: assert.h:86
virtual Ipv4InterfaceContainer AssignUeIpv4Address(NetDeviceContainer ueDevices)
Assign IPv4 addresses to UE devices.
Ipv4AddressHelper m_s1uIpv4AddressHelper
S1-U interfaces.
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...
This application is installed inside eNBs and provides the bridge functionality for user data plane p...
void Add(NodeContainer other)
Append the contents of another NodeContainer to the end of this container.
uint32_t AddDevice(Ptr< NetDevice > device)
Definition: node.cc:118
hold objects of type ns3::DataRate
virtual ~PointToPointEpcHelper()
Destructor.
void SetProtocol(uint16_t protocol)
virtual void AddX2Interface(Ptr< Node > enbNode1, Ptr< Node > enbNode2)
Add an X2 interface between two eNB.
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.
Definition: time.cc:452
void SetSendCallback(SendCallback transmitCb)
Set the user callback to be called when a L2 packet is to be transmitted.
void SetAttribute(std::string name, const AttributeValue &value)
Definition: object-base.cc:161
The eNodeB device implementation.
Ptr< T > GetObject(void) const
Definition: object.h:361
a unique identifier for an interface.
Definition: type-id.h:49
TypeId SetParent(TypeId tid)
Definition: type-id.cc:611
void Dispose(void)
Run the DoDispose methods of this object and all the objects aggregated to it.
Definition: object.cc:205
virtual uint32_t GetNInterfaces(void) const =0
static const uint16_t PROT_NUMBER
Protocol number (0x0800)
void SetBase(Ipv4Address network, Ipv4Mask mask, Ipv4Address base="0.0.0.1")
Set the base network number, network mask and base address.
Ptr< VirtualNetDevice > m_tunDevice
static TypeId LookupByName(std::string name)
Definition: type-id.cc:536
Ipv4Address GetAddress(uint32_t i, uint32_t j=0) const
The LteUeNetDevice class implements the UE net device.