This commit is contained in:
Manuel Requena
2012-06-27 18:06:50 +02:00
8 changed files with 242 additions and 27 deletions

View File

@@ -34,4 +34,7 @@ def build(bld):
obj = bld.create_ns3_program('lena-simple-epc',
['lte'])
obj.source = 'lena-simple-epc.cc'
obj = bld.create_ns3_program('lena-x2-handover',
['lte'])
obj.source = 'lena-x2-handover.cc'

View File

@@ -32,6 +32,10 @@
#include <ns3/epc-enb-application.h>
#include <ns3/epc-sgw-pgw-application.h>
#include <ns3/lte-enb-rrc.h>
#include <ns3/epc-x2.h>
#include <ns3/lte-enb-net-device.h>
namespace ns3 {
@@ -39,8 +43,10 @@ NS_LOG_COMPONENT_DEFINE ("EpcHelper");
NS_OBJECT_ENSURE_REGISTERED (EpcHelper);
EpcHelper::EpcHelper ()
: m_gtpuUdpPort (2152) // fixed by the standard
: m_gtpuUdpPort (2152), // fixed by the standard
m_x2cUdpPort (4444) // fixed by the standard TODO
{
NS_LOG_FUNCTION (this);
@@ -49,6 +55,8 @@ EpcHelper::EpcHelper ()
// (remember that net broadcast and null address are not valid)
m_s1uIpv4AddressHelper.SetBase ("10.0.0.0", "255.255.255.252");
m_x2Ipv4AddressHelper.SetBase ("12.0.0.0", "255.255.255.252");
// we use a /8 net for all UEs
m_ueAddressHelper.SetBase ("7.0.0.0", "255.0.0.0");
@@ -191,7 +199,88 @@ EpcHelper::AddEnb (Ptr<Node> enb, Ptr<NetDevice> lteEnbNetDevice)
NS_ASSERT (enb->GetNApplications () == 1);
NS_ASSERT_MSG (enb->GetApplication (0)->GetObject<EpcEnbApplication> () != 0, "cannot retrieve EpcEnbApplication");
NS_LOG_LOGIC ("enb: " << enb << ", enb->GetApplication (0): " << enb->GetApplication (0));
NS_LOG_INFO ("Create EpcX2 entity");
Ptr<EpcX2> x2 = CreateObject<EpcX2> ();
NS_LOG_INFO ("Connect EpcX2 and LteEnbRrc entities");
Ptr<LteEnbRrc> rrc = lteEnbNetDevice->GetObject<LteEnbNetDevice> ()->GetRrc ();
x2->SetEpcX2SapUser (rrc->GetEpcX2SapUser ());
rrc->SetEpcX2SapProvider (x2->GetEpcX2SapProvider ());
enb->AggregateObject (x2);
}
void
EpcHelper::AddX2Interface (Ptr<Node> enb1, Ptr<Node> enb2)
{
NS_LOG_FUNCTION (this << enb1 << enb2);
// Create a point to point link between the two eNBs with
// the corresponding new NetDevices on each side
NodeContainer enbNodes;
enbNodes.Add (enb1);
enbNodes.Add (enb2);
PointToPointHelper p2ph;
// TODO Add m_x2Link*** parameters in epc.helper.h
// TODO Create Make***Accessor functions
// p2ph.SetDeviceAttribute ("DataRate", DataRateValue (m_x2LinkDataRate));
// p2ph.SetDeviceAttribute ("Mtu", UintegerValue (m_x2LinkMtu));
// p2ph.SetChannelAttribute ("Delay", TimeValue (m_x2LinkDelay));
NetDeviceContainer enbDevices = p2ph.Install (enb1, enb2);
NS_LOG_LOGIC ("number of Ipv4 ifaces of the eNB #1 after installing p2p dev: " << enb1->GetObject<Ipv4> ()->GetNInterfaces ());
NS_LOG_LOGIC ("number of Ipv4 ifaces of the eNB #2 after installing p2p dev: " << enb2->GetObject<Ipv4> ()->GetNInterfaces ());
Ptr<NetDevice> enb1Dev = enbDevices.Get (0);
Ptr<NetDevice> enb2Dev = enbDevices.Get (1);
m_x2Ipv4AddressHelper.NewNetwork ();
Ipv4InterfaceContainer enbIpIfaces = m_x2Ipv4AddressHelper.Assign (enbDevices);
NS_LOG_LOGIC ("number of Ipv4 ifaces of the eNB #1 after assigning Ipv4 addr to X2 dev: " << enb1->GetObject<Ipv4> ()->GetNInterfaces ());
NS_LOG_LOGIC ("number of Ipv4 ifaces of the eNB #2 after assigning Ipv4 addr to X2 dev: " << enb2->GetObject<Ipv4> ()->GetNInterfaces ());
Ipv4Address enb1Address = enbIpIfaces.GetAddress (0);
Ipv4Address enb2Address = enbIpIfaces.GetAddress (1);
// Create X2-C socket for the eNB1
Ptr<Socket> enb1X2cSocket = Socket::CreateSocket (enb1, TypeId::LookupByName ("ns3::UdpSocketFactory"));
int retval = enb1X2cSocket->Bind (InetSocketAddress (enb1Address, m_x2cUdpPort));
NS_ASSERT (retval == 0);
// Create X2-C socket for the eNB2
Ptr<Socket> enb2X2cSocket = Socket::CreateSocket (enb2, TypeId::LookupByName ("ns3::UdpSocketFactory"));
retval = enb2X2cSocket->Bind (InetSocketAddress (enb2Address, m_x2cUdpPort));
NS_ASSERT (retval == 0);
// Add X2 interface to the eNB1's X2 entity
Ptr<EpcX2> enb1X2 = enb1->GetObject<EpcX2> ();
Ptr<LteEnbNetDevice> enb1LteDev = enb1->GetDevice (0)->GetObject<LteEnbNetDevice> ();
uint16_t enb1CellId = enb1LteDev->GetCellId ();
NS_LOG_LOGIC ("LteEnbNetDevice #1 = " << enb1LteDev << " - CellId = " << enb1CellId);
// Add X2 interface to the eNB2's X2 entity
Ptr<EpcX2> enb2X2 = enb2->GetObject<EpcX2> ();
Ptr<LteEnbNetDevice> enb2LteDev = enb2->GetDevice (0)->GetObject<LteEnbNetDevice> ();
uint16_t enb2CellId = enb2LteDev->GetCellId ();
NS_LOG_LOGIC ("LteEnbNetDevice #2 = " << enb2LteDev << " - CellId = " << enb2CellId);
enb1X2->AddX2Interface (enb1CellId, enb1X2cSocket, enb2CellId, enb2X2cSocket);
enb2X2->AddX2Interface (enb2CellId, enb2X2cSocket, enb1CellId, enb1X2cSocket);
}
void
EpcHelper::SendHandoverRequest (Ptr<Node> ueNode, Ptr<Node> sourceEnbNode, Ptr<Node> targetEnbNode)
{
NS_LOG_FUNCTION (this << ueNode << sourceEnbNode << targetEnbNode);
Ptr<LteEnbRrc> sourceRrc = sourceEnbNode->GetDevice (0)->GetObject<LteEnbNetDevice> ()->GetRrc ();
sourceRrc->SendHandoverRequest (ueNode, sourceEnbNode, targetEnbNode);
}

View File

@@ -34,6 +34,7 @@ class Node;
class NetDevice;
class VirtualNetDevice;
class EpcSgwPgwApplication;
class EpcX2;
/**
* \brief Helper class to handle the creation of the EPC entities and protocols.
@@ -72,6 +73,17 @@ public:
void AddEnb (Ptr<Node> enbNode, Ptr<NetDevice> lteEnbNetDevice);
/**
* Add an X2 interface between two eNB
*
* \param enbNode1 one eNB peer of the X2 interface
* \param enbNode2 the other eNB peer of the X2 interface
*/
void AddX2Interface (Ptr<Node> enbNode1, Ptr<Node> enbNode2);
void SendHandoverRequest (Ptr<Node> ueNode, Ptr<Node> sourceEnbNode, Ptr<Node> targetEnbNode);
/**
* Activate an EPS bearer, setting up the corresponding S1-U tunnel.
*
@@ -115,12 +127,10 @@ public:
private:
/**
* helper to assign addresses to S1-U
* NetDevices
/**
* SGW-PGW network element
*/
Ipv4AddressHelper m_s1uIpv4AddressHelper;
/**
* helper to assign addresses to UE devices as well as to the TUN device of the SGW/PGW
@@ -130,17 +140,41 @@ private:
Ptr<Node> m_sgwPgw;
Ptr<EpcSgwPgwApplication> m_sgwPgwApp;
Ptr<VirtualNetDevice> m_tunDevice;
/**
* S1-U interfaces
*/
/**
* helper to assign addresses to S1-U NetDevices
*/
Ipv4AddressHelper m_s1uIpv4AddressHelper;
DataRate m_s1uLinkDataRate;
Time m_s1uLinkDelay;
uint16_t m_s1uLinkMtu;
/**
* UDP port where the GTP-U Socket is bound, fixed by the standard as 2152
*/
uint16_t m_gtpuUdpPort;
/**
* helper to assign addresses to X2 NetDevices
*/
Ipv4AddressHelper m_x2Ipv4AddressHelper;
DataRate m_x2LinkDataRate;
Time m_x2LinkDelay;
uint16_t m_x2LinkMtu;
/**
* UDP port where the GTP-U Socket is bound, fixed by the standard as 2152 TODO Check value in the spec
*/
uint16_t m_x2cUdpPort;
};

View File

@@ -570,6 +570,54 @@ LteHelper::ActivateEpsBearer (Ptr<NetDevice> ueDevice, EpsBearer bearer, Ptr<Epc
}
}
void
LteHelper::AddX2Interface (NodeContainer enbNodes)
{
NS_LOG_FUNCTION (this);
for (NodeContainer::Iterator i = enbNodes.Begin (); i != enbNodes.End (); ++i)
{
for (NodeContainer::Iterator j = i + 1; j != enbNodes.End (); ++j)
{
AddX2Interface (*i, *j);
}
}
}
void
LteHelper::AddX2Interface (Ptr<Node> enbNode1, Ptr<Node> enbNode2)
{
NS_LOG_FUNCTION (this);
NS_LOG_INFO ("setting up the X2 interface");
m_epcHelper->AddX2Interface (enbNode1, enbNode2);
}
void
LteHelper::HandoverRequest (Time hoTime, Ptr<Node> ueNode, Ptr<Node> sourceEnbNode, Ptr<Node> targetEnbNode)
{
NS_LOG_FUNCTION (this << ueNode << sourceEnbNode << targetEnbNode);
Simulator::Schedule (hoTime, &LteHelper::DoHandoverRequest, this, ueNode, sourceEnbNode, targetEnbNode);
}
void
LteHelper::DoHandoverRequest (Ptr<Node> ueNode, Ptr<Node> sourceEnbNode, Ptr<Node> targetEnbNode)
{
NS_LOG_FUNCTION (this << ueNode << sourceEnbNode << targetEnbNode);
m_epcHelper->SendHandoverRequest (ueNode, sourceEnbNode, targetEnbNode);
// lteHelper->Attach (ueNode, targetEnbNode);
// lteHelper->ActivateEpsBearer (ueNode, *);
// lteHelper->DeactivateEpsBearer (ueNode, *);
// lteHelper->Deattach (ueNode, sourceEnbNode);
}
TypeId
LteHelper::GetRlcType (EpsBearer bearer)
{

View File

@@ -219,6 +219,33 @@ public:
*/
void ActivateEpsBearer (Ptr<NetDevice> ueDevice, EpsBearer bearer, Ptr<EpcTft> tft);
/**
* Create an X2 interface between all the eNBs in a given set
*
* \param enbNodes the set of eNB nodes
*/
void AddX2Interface (NodeContainer enbNodes);
/**
* Create an X2 interface between two eNBs
*
* \param enbNode1 one eNB of the X2 interface
* \param enbNode2 the other eNB of the X2 interface
*/
void AddX2Interface (Ptr<Node> enbNode1, Ptr<Node> enbNode2);
/**
* Trigger an X2-based handover of a UE between two eNBs
*
* \param hoTime when the Handover is initiated
* \param ueNode the UE that hands off
* \param enbNode1 source eNB, originally the UE is attached to this eNB
* \param enbNode2 target eNB, the UE is finally connected to this eNB
*/
void HandoverRequest (Time hoTime, Ptr<Node> ueNode, Ptr<Node> sourceEnbNode, Ptr<Node> targetEnbNode);
/**
*
* \param bearer the specification of an EPS bearer
@@ -320,6 +347,8 @@ private:
Ptr<NetDevice> InstallSingleEnbDevice (Ptr<Node> n);
Ptr<NetDevice> InstallSingleUeDevice (Ptr<Node> n);
void DoHandoverRequest (Ptr<Node> ueNode, Ptr<Node> sourceEnbNode, Ptr<Node> targetEnbNode);
Ptr<SpectrumChannel> m_downlinkChannel;
Ptr<SpectrumChannel> m_uplinkChannel;

View File

@@ -41,19 +41,18 @@ public:
struct HandoverRequestParams
{
Ptr<Node> ueNode;
Ptr<Node> sourceEnbNode;
Ptr<Node> targetEnbNode;
uint32_t targetCellId;
uint16_t cause;
uint16_t sourceCellId;
uint16_t targetCellId;
std::list<uint32_t> bearers;
Ptr<Packet> rrcContext;
};
struct HandoverRequestAckParams
{
Ptr<Node> ueNode;
uint16_t cause;
uint16_t sourceCellId;
uint16_t targetCellId;
std::list<uint32_t> bearers;
Ptr<Packet> rrcContext;
};
@@ -84,13 +83,18 @@ public:
struct HandoverRequestParams
{
uint32_t targetCellId;
uint16_t cause;
uint16_t sourceCellId;
uint16_t targetCellId;
std::list<uint32_t> bearers;
Ptr<Packet> rrcContext;
};
struct HandoverRequestAckParams
{
uint16_t cause;
uint16_t sourceCellId;
uint16_t targetCellId;
std::list<uint32_t> bearers;
Ptr<Packet> rrcContext;
};

View File

@@ -28,6 +28,7 @@
#include "ns3/object-factory.h"
#include "ns3/lte-enb-rrc.h"
#include "ns3/lte-enb-net-device.h"
#include "ns3/lte-rlc.h"
#include "ns3/lte-pdcp.h"
#include "ns3/lte-pdcp-sap.h"
@@ -47,9 +48,6 @@ NS_LOG_COMPONENT_DEFINE ("LteEnbRrc");
namespace ns3 {
// ///////////////////////////
// CMAC SAP forwarder
// ///////////////////////////
@@ -459,30 +457,37 @@ void
LteEnbRrc::SendHandoverRequest (Ptr<Node> ueNode, Ptr<Node> sourceEnbNode, Ptr<Node> targetEnbNode)
{
NS_LOG_FUNCTION (this << ueNode << sourceEnbNode << targetEnbNode);
NS_LOG_INFO ("Request to send HANDOVER REQUEST");
NS_LOG_LOGIC ("Request to send HANDOVER REQUEST");
EpcX2SapProvider::HandoverRequestParams params;
params.ueNode = ueNode;
params.sourceEnbNode = sourceEnbNode;
params.targetEnbNode = targetEnbNode;
params.sourceCellId = sourceEnbNode->GetDevice (0)->GetObject<LteEnbNetDevice> ()->GetCellId ();
params.targetCellId = targetEnbNode->GetDevice (0)->GetObject<LteEnbNetDevice> ()->GetCellId ();
NS_LOG_LOGIC ("sourceCellId = " << params.sourceCellId);
NS_LOG_LOGIC ("targetCellId = " << params.targetCellId);
m_x2SapProvider->SendHandoverRequest (params);
}
//
// X2-User SAP
// X2 User SAP
//
void
LteEnbRrc::DoRecvHandoverRequest (EpcX2SapUser::HandoverRequestParams params)
{
NS_LOG_FUNCTION (this);
NS_LOG_INFO ("Recv X2 message: HANDOVER REQUEST");
NS_LOG_LOGIC ("Recv X2 message: HANDOVER REQUEST");
NS_LOG_INFO ("Send X2 message: HANDOVER REQUEST ACK");
NS_LOG_LOGIC ("sourceCellId = " << params.sourceCellId);
NS_LOG_LOGIC ("targetCellId = " << params.targetCellId);
NS_LOG_LOGIC ("Send X2 message: HANDOVER REQUEST ACK");
EpcX2SapProvider::HandoverRequestAckParams ackParams;
ackParams.sourceCellId = params.sourceCellId;
ackParams.targetCellId = params.targetCellId;
m_x2SapProvider->SendHandoverRequestAck (ackParams);
}
@@ -492,7 +497,10 @@ LteEnbRrc::DoRecvHandoverRequestAck (EpcX2SapUser::HandoverRequestAckParams para
{
NS_LOG_FUNCTION (this);
NS_LOG_INFO ("Recv X2 message: HANDOVER REQUEST ACK");
NS_LOG_LOGIC ("Recv X2 message: HANDOVER REQUEST ACK");
NS_LOG_LOGIC ("sourceCellId = " << params.sourceCellId);
NS_LOG_LOGIC ("targetCellId = " << params.targetCellId);
}

View File

@@ -31,7 +31,7 @@
#include "ns3/trace-source-accessor.h"
#include "ns3/pointer.h"
#include "ns3/enum.h"
#include "lte-enb-net-device.h"
#include "ns3/lte-enb-net-device.h"
#include "lte-ue-net-device.h"
#include "lte-ue-mac.h"
#include "lte-ue-rrc.h"