--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lte/helper/epc-helper.cc Wed Sep 28 14:12:34 2011 +0200
@@ -0,0 +1,199 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2011 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Jaume Nin <jnin@cttc.es>
+ * Nicola Baldo <nbaldo@cttc.es>
+ */
+
+#include <ns3/epc-helper.h>
+#include <ns3/log.h>
+#include "ns3/inet-socket-address.h"
+#include "ns3/mac48-address.h"
+#include "ns3/epc-gtpu-tunnel-endpoint.h"
+
+
+namespace ns3 {
+
+NS_LOG_COMPONENT_DEFINE ("EpcHelper");
+
+NS_OBJECT_ENSURE_REGISTERED (EpcHelper);
+
+EpcHelper::EpcHelper ()
+{
+ NS_LOG_FUNCTION (this);
+
+ // since we use point-to-point links for all S1-U links,
+ // we use a /30 subnet which can hold exactly two addresses
+ // (remember that net broadcast and null address are not valid)
+ m_s1uIpv4AddressHelper.SetBase ("10.7.0.0", "255.255.255.252");
+
+ // create SgwPgwNode
+ m_sgwPgw = CreateObject<Node> ();
+
+ Ptr<Socket> sgwPgwS1uSocket = Socket::CreateSocket (m_sgwPgw, TypeId::LookupByName ("ns3::UdpSocketFactory"));
+ sgwPgwS1uSocket->Bind (InetSocketAddress (Ipv4Address::GetAny (), m_gtpuUdpPort));
+
+ // create SgwPgwApplication
+
+ // create WAN NetDevice?
+
+ // create virtual net device
+
+ // interface SgwPgwApplication and virtual net device for tunneling
+
+ // set up static routes appropriately
+
+
+}
+
+EpcHelper::~EpcHelper ()
+{
+ NS_LOG_FUNCTION (this);
+}
+
+TypeId
+EpcHelper::GetTypeId (void)
+{
+ static TypeId tid = TypeId ("ns3::EpcHelper")
+ .SetParent<Object> ()
+ .AddConstructor<EpcHelper> ()
+ .AddAttribute ("", "The IP address to assign to the tap device, when in ConfigureLocal mode. "
+ Ipv4AddressValue ("255.255.255.255"),
+ MakeIpv4AddressAccessor (&TapBridge::m_tapIp),
+ MakeIpv4AddressChecker ())
+ .AddAttribute ("S1uLinkDataRate",
+ "The data rate to be used for the next S1-U link to be created",
+ DataRateValue (DataRate ("10Gb/s")),
+ MakeDataRateAccessor (&EpcHelper::m_s1uLinkDataRate),
+ MakeDataRateChecker ())
+ .AddAttribute ("S1uLinkDelay",
+ "The delay to be used for the next S1-U link to be created",
+ TimeValue (Seconds (0)),
+ MakeTimeAccessor (&EpcHelper::m_m_s1uLinkDelay),
+ MakeTimeChecker ())
+ .AddAttribute("GtpuPort",
+ "UDP Port to be used for GTP-U",
+ UintegerValue (2152),
+ MakeUintegerAccessor (&EpcHelper::m_gtpuUdpPort),
+ MakeUintegerChecker<uint16_t> ())
+ ;
+ return tid;
+}
+
+void
+EpcHelper::CreateSgwPgw ()
+{
+
+}
+
+
+void
+EpcHelper::AddEnb (Ptr<Node> enb, Ptr<NetDevice> lteEnbNetDevice)
+{
+
+ // add an IPv4 stack to the previously created eNB
+ InternetStackHelper internet;
+ internet.Install (enb);
+
+ // create a point to point link between the new eNB and the SGW with
+ // the corresponding new NetDevices on each side
+ NodeContainer enbSgwNodes;
+ enbSgwNodes.Add (m_sgwPgw);
+ enbSgwNodes.Add (enb);
+ PointToPointHelper p2ph;
+ p2ph.SetDeviceAttribute ("DataRate", DataRateValue (m_s1uLinkDataRate));
+ p2ph.SetChannelAttribute ("Delay", TimeValue (m_s1uLinkDelay));
+ NetDeviceContainer enbSgwDevices = p2ph.Install (enb, m_sgwPgw);
+ Ptr<NetDevice> enbDev = enbSgwDevices.Get (0);
+ Ptr<NetDevice> sgwDev = enbSgwDevices.Get (1);
+ m_s1uIpv4AddressHelper.NewNetwork ();
+ Ipv4InterfaceContainer enbSgwIpIfaces m_s1uIpv4AddressHelper.Assign (enbSgwDevices);
+ Ipv4Address enbAddress = enbSgwIpIfaces.GetAddress (0);
+ Ipv4Address sgwAddress = enbSgwIpIfaces.GetAddress (1);
+
+ // create S1-U socket for the ENB
+ Ptr<Socket> enbS1uSocket = Socket::CreateSocket (enb, TypeId::LookupByName ("ns3::UdpSocketFactory"));
+ enbS1uSocket->Bind (InetSocketAddress (enbAddress, m_gtpuUdpPort));
+
+ // create LTE socket for the ENB
+ PacketSocketAddress enbLteSocketAddr;
+ enbLteSocketAddr.SetSingleDevice (lteEnbNetDevice->GetIfIndex ());
+ // do we need the following?
+ //enbLteSocketAddr.SetPhysicalAddress (devices.Get (1)->GetAddress ());
+ //enbLteSocketAddr.SetProtocol (1);
+
+ Ptr<Socket> enbLteSocket = Socket::CreateSocket (enb, TypeId::LookupByName ("ns3::PacketSocketFactory"));
+ enbLteSocket->Bind (enbLteSocketAddr);
+
+ // create EpcEnbApplication
+ Ptr<EpcEnbApplication> = CreateObject<EpcEnbApplication> (enbLteSocket, enbS1uSocket, sgwAddress);
+
+
+}
+
+
+void
+EpcHelper::ActivateEpsBearer ()
+{
+ // add tunnel at EpcSgwPgwApplication
+ // add tunnel at EpcEnbApplication
+}
+
+
+Ptr<Node>
+EpcHelper::GetSgwPgwNode ()
+{
+ return m_sgwPgw;
+}
+
+
+void
+EpcHelper::InstallGtpu (Ptr<Node> n)
+{
+ InstallGtpu (n, m_ipv4.NewAddress ());
+}
+
+void
+EpcHelper::InstallGtpu (Ptr<Node> n, Ipv4Address addr)
+{
+ NS_LOG_FUNCTION (this);
+ // UDP socket creation and configuration
+ Ptr<Socket> m_socket = Socket::CreateSocket (n, TypeId::LookupByName ("ns3::UdpSocketFactory"));
+ m_socket->Bind (InetSocketAddress (Ipv4Address::GetAny (), m_udpPort));
+
+ // tap device creation and configuration
+ Ptr<VirtualNetDevice> m_tap = CreateObject<VirtualNetDevice> ();
+ m_tap->SetAddress (Mac48Address::Allocate ());
+
+ n->AddDevice (m_tap);
+ Ptr<Ipv4> ipv4 = n->GetObject<Ipv4> ();
+ uint32_t i = ipv4->AddInterface (m_tap);
+ ipv4->AddAddress (i, Ipv4InterfaceAddress (addr, m_mask));
+ ipv4->SetUp (i);
+ Ptr<GtpuTunnelEndpoint> tunnel = CreateObject<GtpuTunnelEndpoint> (m_tap, m_socket);
+ m_gtpuEndpoint[n] = tunnel;
+}
+
+void
+EpcHelper::CreateGtpuTunnel (Ptr<Node> n, Ipv4Address nAddr, Ptr<Node> m, Ipv4Address mAddr)
+{
+ uint32_t teid = m_gtpuEndpoint[n]->CreateGtpuTunnel (mAddr);
+ m_gtpuEndpoint[m]->CreateGtpuTunnel (nAddr, teid);
+}
+
+
+} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lte/helper/epc-helper.h Wed Sep 28 14:12:34 2011 +0200
@@ -0,0 +1,112 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2011 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Jaume Nin <jnin@cttc.es>
+ */
+
+#ifndef EPC_HELPER_H
+#define EPC_HELPER_H
+
+#include <ns3/object.h>
+
+
+
+
+namespace ns3 {
+
+class Node;
+class NetDevice;
+
+/**
+ * \brief Helper class to handle the creation of the EPC entities and protocols.
+ *
+ * This Helper will create an EPC network topology comprising of a
+ * single node that implements both the SGW and PGW functionality, and
+ * is connected to all the eNBs in the simulation by means of the S1-U
+ * interface.
+ */
+class EpcHelper : public Object
+{
+public:
+
+ /**
+ * Constructor
+ */
+ EpcHelper ();
+
+ /**
+ * Destructor
+ */
+ virtual ~EpcHelper ();
+
+ // inherited from Object
+ TypeId GetTypeId (void);
+
+
+ /**
+ * Add an eNB to the EPC
+ *
+ * \param enbNode the previosuly created eNB node which is to be
+ * added to the EPC
+ * \param lteEnbNetDevice the LteEnbNetDevice of the eNB node
+ */
+ void AddEnb (Ptr<Node> enbNode, Ptr<NetDevice> lteEnbNetDevice);
+
+
+ /**
+ * Activate an EPS bearer, setting up the corresponding S1-U tunnel.
+ *
+ */
+ void ActivateEpsBearer ();
+
+
+ /**
+ *
+ * \return a pointer to the node implementing PGW
+ * functionality. Note that in this particular implementation this
+ * node will also hold the SGW functionality. The primary use
+ * intended for this method is to allow the user to configure the Gi
+ * interface of the PGW, i.e., to connect the PGW to the internet.
+ */
+ Ptr<Node> GetPgwNode ();
+
+private:
+
+
+ Ipv4AddressHelper m_s1uIpv4AddressHelper; /**< helper to assign
+ addresses to S1-U
+ NetDevices */
+
+ Ptr<Node> m_sgwPgw; /**< the SGW/PGW node */
+
+ DataRate m_s1uLinkDataRate;
+ Time m_s1uLinkDelay;
+
+
+ /**
+ * UDP port where the GTP-U Socket is bound, fixed by the standard as 2152
+ */
+ uint16_t m_gtpuUdpPort;
+
+};
+
+
+
+
+} // namespace ns3
+
+#endif // EPC_HELPER_H
--- a/src/lte/model/epc-enb-application.cc Fri Sep 09 18:20:08 2011 +0200
+++ b/src/lte/model/epc-enb-application.cc Wed Sep 28 14:12:34 2011 +0200
@@ -38,24 +38,73 @@
EpcEnbApplication::GetTypeId (void)
{
static TypeId tid = TypeId ("ns3::EpcEnbApplication")
- .SetParent<Object> ();
+ .SetParent<Object> ()
+ .AddAttribute("GtpuPort",
+ "UDP Port to be used for GTP-U",
+ UintegerValue (2152),
+ MakeUintegerAccessor (&EpcEnbApplication::m_updPort),
+ MakeUintegerChecker<uint16_t> ());
return tid;
}
-EpcEnbApplication::EpcEnbApplication (const Ptr<VirtualNetDevice> tap, const Ptr<Socket> s)
- : m_udpPort (2152)
+EpcEnbApplication::EpcEnbApplication (Address sgwAddress)
{
NS_LOG_FUNCTION (this);
- m_tap = tap;
- m_tap->SetSendCallback (MakeCallback (&EpcEnbApplication::GtpuSend, this));
- m_socket = s;
- m_socket->SetRecvCallback (MakeCallback (&EpcEnbApplication::GtpuRecv, this));
+}
+
+
+EpcEnbApplication::~EpcEnbApplication (void)
+{
+}
+
+
+void
+EpcEnbApplication::RecvFromLteSocket (Ptr<Socket> socket)
+{
+ NS_LOG_FUNCTION (this);
+ NS_ASSERT (socket == m_lteSocket);
+ Ptr<Packet> packet = socket->Recv ();
+ GtpuHeader gtpu;
+ // TODO: should determine the TEID based on the Radio Bearer ID
+ // which should be conveyed by means of a Packet Tag
+ uint32_t teid = 0;
+ SendToS1uSocket (packet, teid);
}
+void
+EpcEnbApplication::RecvFromS1uSocket (Ptr<Socket> socket)
+{
+ NS_LOG_FUNCTION (this);
+ NS_ASSERT (socket == m_s1uSocket);
+ Ptr<Packet> packet = socket->Recv ();
+ GtpuHeader gtpu;
+ packet->RemoveHeader (gtpu);
+ uint32_t teid = gtpu.GetTeid ();
+ uint32_t rbid = GetRbid (teid);
+ SendToLteSocket (packet, rbid);
+}
+
+void
+EpcEnbApplication::SendToS1uSocket (Ptr<Packet> packet, uint32_t teid)
+{
+ gtpu.SetTeid (teid);
+ // From 3GPP TS 29.281 v10.0.0 Section 5.1
+ // Length of the payload + the non obligatory GTP-U header
+ gtpu.SetLength (p->GetSize () + h.GetSerializedSize () - 8);
+ packet->AddHeader (gtpu);
+ uint32_t flags = 0;
+ m_s1uSocket->SendTo (packet, flags, m_sgwAddress);
+}
+
+
uint32_t
EpcEnbApplication::CreateGtpuTunnel (Ipv4Address destination)
{
NS_LOG_FUNCTION (this);
+ if (m_teidCounter == 0xffffffff)
+ {
+ NS_FATAL_ERROR ("TEID space exhausted, please implement some TEID reuse mechanism");
+ }
CreateGtpuTunnel (destination, ++m_teidCounter);
return m_teidCounter;
}
@@ -68,12 +117,25 @@
m_dstAddrMap[m_indexCounter] = destination;
}
+uint32_t
+EpcEnbApplication::GetRbid (uint32_t teid)
+{
+ // since we don't have SRBs for now, we can just use the same identifiers
+ return teid;
+}
+
+uint32_t
+EpcEnbApplication::GetTeid (uint32_t rbid)
+{
+ // since we don't have SRBs for now, we can just use the same identifiers
+ return rbid;
+}
void
EpcEnbApplication::GtpuRecv (Ptr<Socket> socket)
{
- NS_LOG_FUNCTION (this);
- Ptr<Packet> packet = socket->Recv (65535, 0);
+ NS_LOG_FUNCTION (this);
+ Ptr<Packet> packet = socket->Recv ();
uint32_t index = 0;
m_gtpuMap[index]->RemoveHeader (packet);
m_tap->Receive (packet, 0x0800, m_tap->GetAddress (), m_tap->GetAddress (), NetDevice::PACKET_HOST);
--- a/src/lte/model/epc-enb-application.h Fri Sep 09 18:20:08 2011 +0200
+++ b/src/lte/model/epc-enb-application.h Wed Sep 28 14:12:34 2011 +0200
@@ -44,25 +44,64 @@
public:
static TypeId GetTypeId (void);
+
+
+ /**
+ *
+ *
+ * \param radioSocket the socket to be used to send/receive packets to/from the LTE radio interface
+ * \param s1uSocket the socket to be used to send/receive packets
+ * to/from the S1-U interface connected with the SGW
+ * \param sgwAddress the IPv4 address at which this eNB will be able to reach its SGW
+ *
+ */
+ EpcEnbApplication (Ptr<Socket> radioSocket, Ptr<Socket> s1uSocket, Address sgwAddress);
/**
- * Method assigned to the send callback of the upper end of the tunnel. It adds
- * the GTP header and sends it through the tunnel
+ * destructor
+ *
*/
- bool GtpuSend (Ptr<Packet> packet, const Address& source, const Address& dest, uint16_t protocolNumber);
- /**
- * Method assigned to the receive callback of the upper end of the tunnel. It strips
- * the GTP header and sends it up to the application
+ virtual ~EpcEnbApplication (void);
+
+
+
+ void SetupS1Bearer ()
+
+ /**
+ * Method to be assigned to the recv callback of the LTE socket. It is called when the eNB receives a data packet from the radio interface that is to be forwarded to the SGW.
+ *
+ * \param socket pointer to the LTE socket
+ */
+ void RecvFromLteSocket (Ptr<Socket> socket);
+
+
+ /**
+ * Method to be assigned to the recv callback of the S1-U socket. It is called when the eNB receives a data packet from the SGW that is to be forwarded to the UE.
+ *
+ * \param socket pointer to the S1-U socket
*/
- void GtpuRecv (Ptr<Socket> socket);
+ void RecvFromS1uSocket (Ptr<Socket> socket);
+
+ /**
+ * Send a packet to the UE via the LTE radio interface of the eNB
+ *
+ * \param packet t
+ * \param rbid the Radio Bearer IDentifier
+ */
+ void SendToLteSocket (Ptr<Packet> packet, uint32_t rbid);
+
- /**
- * Constructor that binds the tap device to the callback methods.
- * \param tap VirtualNetDevice used to tunnel the packets
- * \param s Socket used to send the tunneled packets
+ /**
+ * Send a packet to the SGW via the S1-U interface
+ *
+ * \param packet packet to be sent
+ * \param teid the Tunnel Enpoint IDentifier
*/
- EpcEnbApplication (const Ptr<VirtualNetDevice> tap, const Ptr<Socket> s);
- virtual ~EpcEnbApplication (void);
+ void SendToS1uSocket (Ptr<Packet> packet, uint32_t teid);
+
+
+private:
+
/**
* Creates a GTPv1-U tunnel between the given destination and the enpoint
@@ -76,31 +115,54 @@
* Creates a GTPv1-U tunnel between the given destination and the enpoint. The
* TEID is automatically sellected.
* \param destination IP address of the other end of the tunnel
- * \return teid Tunnel Endpoint IDentifier assigned to the tunnel
+ * \return the Tunnel Endpoint IDentifier (TEID) assigned to the tunnel
*/
uint32_t CreateGtpuTunnel (Ipv4Address destination);
-private:
- /**
- * UDP socket to send and receive the packets to and from the tunnel
+
+ /**
+ * this function implements the 1-to-1 mapping between S1 Bearers and Radio Bearers
+ *
+ * \param teid the Tunnel Endpoint IDentifier (TEID) that identifies an S1-bearer on this eNB
+ *
+ * \return the corresponding Radio Bearer Identifier
*/
- Ptr<Socket> m_socket;
+ uint32_t GetRbid (uint32_t teid);
+
+
+ /**
+ * this function implements the 1-to-1 mapping between Radio Bearers and S1 Bearers
+ *
+ * \param rbid the Radio Bearer Identifier
+ *
+ * \return the corresponding the Tunnel Endpoint IDentifier (TEID) that identifies an S1-bearer on this eNB
+ */
+ uint32_t GetTeid (uint32_t rbid);
+
/**
- * UDP port where the socket is bind, fixed by the standard as 2152
+ * raw packet socket to send and receive the packets to and from the LTE radio interface
+ */
+ Ptr<Socket> m_lteSocket;
+
+ /**
+ * UDP socket to send and receive GTP-U the packets to and from the S1-U interface
+ */
+ Ptr<Socket> m_epcSocket;
+
+ /**
+ * UDP port where the GTP-U Socket is bound, fixed by the standard as 2152
*/
uint16_t m_udpPort;
- /**
- * VirtualNetDevice to create the tunnel
- */
- Ptr<VirtualNetDevice> m_tap;
+
/**
* Map holding the GTP instances of the active tunnels on this endpoint
*/
std::map<uint32_t, Ptr<GtpuL5Protocol> > m_gtpuMap;
+
/**
- * Map holding the destination address of the active tunnels on this endpoint
+ * address of the SGW which terminates all tunnels
*/
- std::map<uint32_t, Ipv4Address> m_dstAddrMap;
+ Ipv4Address m_sgwAddress;
static uint16_t m_teidCounter;
static uint32_t m_indexCounter;
--- a/src/lte/wscript Fri Sep 09 18:20:08 2011 +0200
+++ b/src/lte/wscript Wed Sep 28 14:12:34 2011 +0200
@@ -33,6 +33,7 @@
'model/ideal-control-messages.cc',
'helper/lena-helper.cc',
'helper/gtpu-tunnel-helper.cc',
+ 'helper/epc-helper.cc',
'helper/rlc-stats-calculator.cc',
'helper/mac-stats-calculator.cc',
'model/ff-mac-csched-sap.cc',
@@ -109,6 +110,7 @@
'model/ideal-control-messages.h',
'helper/lena-helper.h',
'helper/gtpu-tunnel-helper.h',
+ 'helper/epc-helper.h',
'helper/mac-stats-calculator.h',
'helper/rlc-stats-calculator.h',
'model/ff-mac-common.h',