--- a/src/lte/helper/epc-helper.cc Wed Nov 28 15:46:27 2012 +0100
+++ b/src/lte/helper/epc-helper.cc Thu Nov 29 12:00:06 2012 +0100
@@ -201,7 +201,7 @@
NS_LOG_INFO ("create EpcEnbApplication");
- Ptr<EpcEnbApplication> enbApp = CreateObject<EpcEnbApplication> (enbLteSocket, enbS1uSocket, sgwAddress, cellId);
+ Ptr<EpcEnbApplication> enbApp = CreateObject<EpcEnbApplication> (enbLteSocket, enbS1uSocket, enbAddress, sgwAddress, cellId);
enb->AddApplication (enbApp);
NS_ASSERT (enb->GetNApplications () == 1);
NS_ASSERT_MSG (enb->GetApplication (0)->GetObject<EpcEnbApplication> () != 0, "cannot retrieve EpcEnbApplication");
--- a/src/lte/helper/lte-helper.cc Wed Nov 28 15:46:27 2012 +0100
+++ b/src/lte/helper/lte-helper.cc Thu Nov 29 12:00:06 2012 +0100
@@ -61,6 +61,8 @@
NS_OBJECT_ENSURE_REGISTERED (LteHelper);
LteHelper::LteHelper (void)
+ : m_imsiCounter (0),
+ m_cellIdCounter (0)
{
NS_LOG_FUNCTION (this);
m_enbNetDeviceFactory.SetTypeId (LteEnbNetDevice::GetTypeId ());
@@ -374,8 +376,12 @@
phy->SetLteEnbCphySapUser (rrc->GetLteEnbCphySapUser ());
rrc->SetLteEnbCphySapProvider (phy->GetLteEnbCphySapProvider ());
+ NS_ABORT_MSG_IF (m_cellIdCounter == 65535, "max num eNBs exceeded");
+ uint16_t cellId = ++m_cellIdCounter;
+
Ptr<LteEnbNetDevice> dev = m_enbNetDeviceFactory.Create<LteEnbNetDevice> ();
dev->SetNode (n);
+ dev->SetAttribute ("CellId", UintegerValue (cellId));
dev->SetAttribute ("LteEnbPhy", PointerValue (phy));
dev->SetAttribute ("LteEnbMac", PointerValue (mac));
dev->SetAttribute ("FfMacScheduler", PointerValue (sched));
@@ -497,7 +503,9 @@
phy->SetLteUeCphySapUser (rrc->GetLteUeCphySapUser ());
rrc->SetLteUeCphySapProvider (phy->GetLteUeCphySapProvider ());
- Ptr<LteUeNetDevice> dev = CreateObject<LteUeNetDevice> (n, phy, mac, rrc, nas);
+ NS_ABORT_MSG_IF (m_imsiCounter >= 0xFFFFFFFF, "max num UEs exceeded");
+ uint64_t imsi = ++m_imsiCounter;
+ Ptr<LteUeNetDevice> dev = CreateObject<LteUeNetDevice> (n, phy, mac, rrc, nas, imsi);
phy->SetDevice (dev);
dlPhy->SetDevice (dev);
ulPhy->SetDevice (dev);
--- a/src/lte/helper/lte-helper.h Wed Nov 28 15:46:27 2012 +0100
+++ b/src/lte/helper/lte-helper.h Thu Nov 29 12:00:06 2012 +0100
@@ -406,6 +406,10 @@
Ptr<EpcHelper> m_epcHelper;
+ uint64_t m_imsiCounter;
+ uint16_t m_cellIdCounter;
+
+
};
--- a/src/lte/model/epc-enb-application.cc Wed Nov 28 15:46:27 2012 +0100
+++ b/src/lte/model/epc-enb-application.cc Thu Nov 29 12:00:06 2012 +0100
@@ -78,16 +78,17 @@
}
-EpcEnbApplication::EpcEnbApplication (Ptr<Socket> lteSocket, Ptr<Socket> s1uSocket, Ipv4Address sgwAddress, uint16_t cellId)
+EpcEnbApplication::EpcEnbApplication (Ptr<Socket> lteSocket, Ptr<Socket> s1uSocket, Ipv4Address enbS1uAddress, Ipv4Address sgwS1uAddress, uint16_t cellId)
: m_lteSocket (lteSocket),
m_s1uSocket (s1uSocket),
- m_sgwAddress (sgwAddress),
+ m_enbS1uAddress (enbS1uAddress),
+ m_sgwS1uAddress (sgwS1uAddress),
m_gtpuUdpPort (2152), // fixed by the standard
m_s1SapUser (0),
m_s1apSapMme (0),
m_cellId (cellId)
{
- NS_LOG_FUNCTION (this << lteSocket << s1uSocket << sgwAddress);
+ NS_LOG_FUNCTION (this << lteSocket << s1uSocket << sgwS1uAddress);
m_s1uSocket->SetRecvCallback (MakeCallback (&EpcEnbApplication::RecvFromS1uSocket, this));
m_lteSocket->SetRecvCallback (MakeCallback (&EpcEnbApplication::RecvFromLteSocket, this));
m_s1SapProvider = new MemberEpcEnbS1SapProvider<EpcEnbApplication> (this);
@@ -136,6 +137,41 @@
m_s1apSapMme->InitialUeMessage (imsi, rnti, imsi, m_cellId);
}
+void
+EpcEnbApplication::DoPathSwitchRequest (EpcEnbS1SapProvider::PathSwitchRequestParameters params)
+{
+ NS_LOG_FUNCTION (this);
+ uint16_t enbUeS1Id = params.rnti;
+ uint64_t mmeUeS1Id = params.mmeUeS1Id;
+ uint64_t imsi = mmeUeS1Id;
+ // side effect: create entry if not exist
+ m_imsiRntiMap[imsi] = params.rnti;
+
+ uint16_t gci = params.cellId;
+ std::list<EpcS1apSapMme::ErabSwitchedInDownlinkItem> erabToBeSwitchedInDownlinkList;
+ for (std::list<EpcEnbS1SapProvider::BearerToBeSwitched>::iterator bit = params.bearersToBeSwitched.begin ();
+ bit != params.bearersToBeSwitched.end ();
+ ++bit)
+ {
+ EpsFlowId_t flowId;
+ flowId.m_rnti = params.rnti;
+ flowId.m_bid = bit->epsBearerId;
+ uint32_t teid = bit->teid;
+
+ EpsFlowId_t rbid (params.rnti, bit->epsBearerId);
+ // side effect: create entries if not exist
+ m_rbidTeidMap[rbid] = teid;
+ m_teidRbidMap[teid] = rbid;
+
+ EpcS1apSapMme::ErabSwitchedInDownlinkItem erab;
+ erab.erabId = bit->epsBearerId;
+ erab.enbTransportLayerAddress = m_enbS1uAddress;
+ erab.enbTeid = bit->teid;
+
+ erabToBeSwitchedInDownlinkList.push_back (erab);
+ }
+ m_s1apSapMme->PathSwitchRequest (enbUeS1Id, mmeUeS1Id, gci, erabToBeSwitchedInDownlinkList);
+}
void
EpcEnbApplication::DoInitialContextSetupRequest (uint64_t mmeUeS1Id, uint16_t enbUeS1Id, std::list<EpcS1apSapEnb::ErabToBeSetupItem> erabToBeSetupList)
@@ -172,7 +208,14 @@
EpcEnbApplication::DoPathSwitchRequestAcknowledge (uint64_t enbUeS1Id, uint64_t mmeUeS1Id, uint16_t gci, std::list<EpcS1apSapEnb::ErabSwitchedInUplinkItem> erabToBeSwitchedInUplinkList)
{
NS_LOG_FUNCTION (this);
- NS_FATAL_ERROR ("not implemented");
+
+ uint64_t imsi = mmeUeS1Id;
+ std::map<uint64_t, uint16_t>::iterator imsiIt = m_imsiRntiMap.find (imsi);
+ NS_ASSERT_MSG (imsiIt != m_imsiRntiMap.end (), "unknown IMSI");
+ uint16_t rnti = imsiIt->second;
+ EpcEnbS1SapUser::PathSwitchRequestAcknowledgeParameters params;
+ params.rnti = rnti;
+ m_s1SapUser->PathSwitchRequestAcknowledge (params);
}
void
@@ -240,7 +283,7 @@
gtpu.SetLength (packet->GetSize () + gtpu.GetSerializedSize () - 8);
packet->AddHeader (gtpu);
uint32_t flags = 0;
- m_s1uSocket->SendTo (packet, flags, InetSocketAddress(m_sgwAddress, m_gtpuUdpPort));
+ m_s1uSocket->SendTo (packet, flags, InetSocketAddress(m_sgwS1uAddress, m_gtpuUdpPort));
}
--- a/src/lte/model/epc-enb-application.h Wed Nov 28 15:46:27 2012 +0100
+++ b/src/lte/model/epc-enb-application.h Thu Nov 29 12:00:06 2012 +0100
@@ -69,10 +69,11 @@
* \param lteSocket 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
+ * \param enbS1uAddress the IPv4 address of the S1-U interface of this eNB
+ * \param sgwS1uAddress the IPv4 address at which this eNB will be able to reach its SGW for S1-U communications
* \param cellId the identifier of the enb
*/
- EpcEnbApplication (Ptr<Socket> lteSocket, Ptr<Socket> s1uSocket, Ipv4Address sgwAddress, uint16_t cellId);
+ EpcEnbApplication (Ptr<Socket> lteSocket, Ptr<Socket> s1uSocket, Ipv4Address enbS1uAddress, Ipv4Address sgwS1uAddress, uint16_t cellId);
/**
* Destructor
@@ -141,6 +142,7 @@
// ENB S1 SAP provider methods
void DoInitialUeMessage (uint64_t imsi, uint16_t rnti);
+ void DoPathSwitchRequest (EpcEnbS1SapProvider::PathSwitchRequestParameters params);
// S1-AP SAP ENB methods
void DoInitialContextSetupRequest (uint64_t mmeUeS1Id, uint16_t enbUeS1Id, std::list<EpcS1apSapEnb::ErabToBeSetupItem> erabToBeSetupList);
@@ -185,9 +187,14 @@
Ptr<Socket> m_s1uSocket;
/**
+ * address of the eNB for S1-U communications
+ */
+ Ipv4Address m_enbS1uAddress;
+
+ /**
* address of the SGW which terminates all S1-U tunnels
*/
- Ipv4Address m_sgwAddress;
+ Ipv4Address m_sgwS1uAddress;
/**
* map telling for each EpsBearer (RNTI,BID) the corresponding S1-U TEID
--- a/src/lte/model/epc-enb-s1-sap.h Wed Nov 28 15:46:27 2012 +0100
+++ b/src/lte/model/epc-enb-s1-sap.h Thu Nov 29 12:00:06 2012 +0100
@@ -21,6 +21,7 @@
#ifndef EPC_ENB_S1_SAP_H
#define EPC_ENB_S1_SAP_H
+#include <list>
#include <stdint.h>
#include <ns3/eps-bearer.h>
#include <ns3/ipv4-address.h>
@@ -38,20 +39,7 @@
class EpcEnbS1SapProvider
{
public:
- virtual ~EpcEnbS1SapProvider ();
-
- /**
- * Parameters passed to S1BearerSetupRequest ()
- *
- */
- struct S1BearerSetupRequestParameters
- {
- uint16_t rnti; /**< the RNTI corresponding to the IMSI for which
- the radio bearer activation was requested */
- uint8_t bid; /**< the EPS Bearer ID of the bearer to be created*/
-
- uint32_t gtpTeid; /**< S1-bearer GTP tunnel endpoint identifier, see 36.423 9.2.1 */
- };
+ virtual ~EpcEnbS1SapProvider ();
/**
*
@@ -60,6 +48,24 @@
* \param rnti
*/
virtual void InitialUeMessage (uint64_t imsi, uint16_t rnti) = 0;
+
+
+ struct BearerToBeSwitched
+ {
+ uint8_t epsBearerId;
+ uint32_t teid;
+ };
+
+ struct PathSwitchRequestParameters
+ {
+ uint16_t rnti;
+ uint16_t cellId;
+ uint32_t mmeUeS1Id;
+ std::list<BearerToBeSwitched> bearersToBeSwitched;
+ };
+
+ virtual void PathSwitchRequest (PathSwitchRequestParameters params) = 0;
+
};
@@ -96,6 +102,14 @@
*
*/
virtual void DataRadioBearerSetupRequest (DataRadioBearerSetupRequestParameters params) = 0;
+
+
+ struct PathSwitchRequestAcknowledgeParameters
+ {
+ uint16_t rnti;
+ };
+
+ virtual void PathSwitchRequestAcknowledge (PathSwitchRequestAcknowledgeParameters params) = 0;
};
@@ -115,6 +129,8 @@
// inherited from EpcEnbS1SapProvider
virtual void InitialUeMessage (uint64_t imsi, uint16_t rnti);
+ virtual void PathSwitchRequest (PathSwitchRequestParameters params);
+
private:
MemberEpcEnbS1SapProvider ();
@@ -139,6 +155,13 @@
m_owner->DoInitialUeMessage (imsi, rnti);
}
+
+template <class C>
+void MemberEpcEnbS1SapProvider<C>::PathSwitchRequest (PathSwitchRequestParameters params)
+{
+ m_owner->DoPathSwitchRequest (params);
+}
+
/**
* Template for the implementation of the EpcEnbS1SapUser as a member
* of an owner class of type C to which all methods are forwarded
@@ -152,6 +175,7 @@
// inherited from EpcEnbS1SapUser
virtual void DataRadioBearerSetupRequest (DataRadioBearerSetupRequestParameters params);
+ virtual void PathSwitchRequestAcknowledge (PathSwitchRequestAcknowledgeParameters params);
private:
MemberEpcEnbS1SapUser ();
@@ -175,6 +199,11 @@
m_owner->DoDataRadioBearerSetupRequest (params);
}
+template <class C>
+void MemberEpcEnbS1SapUser<C>::PathSwitchRequestAcknowledge (PathSwitchRequestAcknowledgeParameters params)
+{
+ m_owner->DoPathSwitchRequestAcknowledge (params);
+}
} // namespace ns3
--- a/src/lte/model/epc-mme.cc Wed Nov 28 15:46:27 2012 +0100
+++ b/src/lte/model/epc-mme.cc Thu Nov 29 12:00:06 2012 +0100
@@ -131,20 +131,20 @@
std::map<uint64_t, Ptr<UeInfo> >::iterator it = m_ueInfoMap.find (imsi);
NS_ASSERT_MSG (it != m_ueInfoMap.end (), "could not find any UE with IMSI " << imsi);
it->second->cellId = gci;
- std::list<EpcS11SapSgw::BearerContext> bearersToBeSetup;
+ EpcS11SapSgw::CreateSessionRequestMessage msg;
+ msg.imsi = imsi;
+ msg. uli.gci = gci;
for (std::list<BearerInfo>::iterator bit = it->second->bearersToBeActivated.begin ();
bit != it->second->bearersToBeActivated.end ();
++bit)
{
- EpcS11SapSgw::BearerContext bearerContext;
+ EpcS11SapSgw::BearerContextToBeCreated bearerContext;
bearerContext.epsBearerId = bit->bearerId;
bearerContext.bearerLevelQos = bit->bearer;
bearerContext.tft = bit->tft;
- bearersToBeSetup.push_back (bearerContext);
+ msg.bearerContextsToBeCreated.push_back (bearerContext);
}
- EpcS11Sap::Uli uli;
- uli.gci = gci;
- m_s11SapSgw->RecvCreateSessionRequest (imsi, uli, bearersToBeSetup);
+ m_s11SapSgw->CreateSessionRequest (msg);
}
void
@@ -158,19 +158,32 @@
EpcMme::DoPathSwitchRequest (uint64_t enbUeS1Id, uint64_t mmeUeS1Id, uint16_t gci, std::list<EpcS1apSapMme::ErabSwitchedInDownlinkItem> erabToBeSwitchedInDownlinkList)
{
NS_LOG_FUNCTION (this << mmeUeS1Id << enbUeS1Id << gci);
- NS_FATAL_ERROR ("unimplemented");
+
+ uint64_t imsi = mmeUeS1Id;
+ std::map<uint64_t, Ptr<UeInfo> >::iterator it = m_ueInfoMap.find (imsi);
+ NS_ASSERT_MSG (it != m_ueInfoMap.end (), "could not find any UE with IMSI " << imsi);
+ NS_LOG_INFO ("IMSI " << imsi << " old eNB: " << it->second->cellId << ", new eNB: " << gci);
+ it->second->cellId = gci;
+ it->second->enbUeS1Id = enbUeS1Id;
+
+ EpcS11SapSgw::ModifyBearerRequestMessage msg;
+ msg.teid = imsi; // trick to avoid the need for allocating TEIDs on the S11 interface
+ msg.uli.gci = gci;
+ // bearer modification is not supported for now
+ m_s11SapSgw->ModifyBearerRequest (msg);
}
// S11 SAP MME forwarded methods
void
-EpcMme::DoRecvCreateSessionResponse (uint64_t imsi, std::list<EpcS11SapMme::BearerContext> bearerContextList)
+EpcMme::DoCreateSessionResponse (EpcS11SapMme::CreateSessionResponseMessage msg)
{
- NS_LOG_FUNCTION (this << imsi);
+ NS_LOG_FUNCTION (this << msg.teid);
+ uint64_t imsi = msg.teid;
std::list<EpcS1apSapEnb::ErabToBeSetupItem> erabToBeSetupList;
- for (std::list<EpcS11SapMme::BearerContext>::iterator bit = bearerContextList.begin ();
- bit != bearerContextList.end ();
+ for (std::list<EpcS11SapMme::BearerContextCreated>::iterator bit = msg.bearerContextsCreated.begin ();
+ bit != msg.bearerContextsCreated.end ();
++bit)
{
EpcS1apSapEnb::ErabToBeSetupItem erab;
@@ -191,6 +204,21 @@
}
-
+void
+EpcMme::DoModifyBearerResponse (EpcS11SapMme::ModifyBearerResponseMessage msg)
+{
+ NS_LOG_FUNCTION (this << msg.teid);
+ NS_ASSERT (msg.cause == EpcS11SapMme::ModifyBearerResponseMessage::REQUEST_ACCEPTED);
+ uint64_t imsi = msg.teid;
+ std::map<uint64_t, Ptr<UeInfo> >::iterator it = m_ueInfoMap.find (imsi);
+ NS_ASSERT_MSG (it != m_ueInfoMap.end (), "could not find any UE with IMSI " << imsi);
+ uint64_t enbUeS1Id = it->second->enbUeS1Id;
+ uint64_t mmeUeS1Id = it->second->mmeUeS1Id;
+ uint16_t cgi = it->second->cellId;
+ std::list<EpcS1apSapEnb::ErabSwitchedInUplinkItem> erabToBeSwitchedInUplinkList; // unused for now
+ std::map<uint16_t, Ptr<EnbInfo> >::iterator jt = m_enbInfoMap.find (it->second->cellId);
+ NS_ASSERT_MSG (jt != m_enbInfoMap.end (), "could not find any eNB with CellId " << it->second->cellId);
+ jt->second->s1apSapEnb->PathSwitchRequestAcknowledge (enbUeS1Id, mmeUeS1Id, cgi, erabToBeSwitchedInUplinkList);
+}
} // namespace ns3
--- a/src/lte/model/epc-mme.h Wed Nov 28 15:46:27 2012 +0100
+++ b/src/lte/model/epc-mme.h Thu Nov 29 12:00:06 2012 +0100
@@ -118,7 +118,8 @@
// S11 SAP MME forwarded methods
- void DoRecvCreateSessionResponse (uint64_t imsi, std::list<EpcS11SapMme::BearerContext>);
+ void DoCreateSessionResponse (EpcS11SapMme::CreateSessionResponseMessage msg);
+ void DoModifyBearerResponse (EpcS11SapMme::ModifyBearerResponseMessage msg);
/**
* Hold info on an EPS bearer to be activated
--- a/src/lte/model/epc-s11-sap.h Wed Nov 28 15:46:27 2012 +0100
+++ b/src/lte/model/epc-s11-sap.h Thu Nov 29 12:00:06 2012 +0100
@@ -36,6 +36,11 @@
virtual ~EpcS11Sap ();
+ struct GtpcMessage
+ {
+ uint32_t teid;
+ };
+
/**
* Fully-qualified TEID, see 3GPP TS 29.274 section 8.22
*
@@ -64,7 +69,7 @@
* MME side of the S11 Service Access Point (SAP), provides the MME
* methods to be called when an S11 message is received by the MME.
*/
- class EpcS11SapMme : public EpcS11Sap
+class EpcS11SapMme : public EpcS11Sap
{
public:
@@ -72,7 +77,7 @@
* 3GPP TS 29.274 version 8.3.1 Release 8 section 8.28
*
*/
- struct BearerContext
+ struct BearerContextCreated
{
EpcS11Sap::Fteid sgwFteid;
@@ -81,7 +86,43 @@
Ptr<EpcTft> tft;
};
- virtual void RecvCreateSessionResponse (uint64_t imsi, std::list<BearerContext> bearerContextList) = 0;
+
+ /**
+ * Create Session Response message, see 3GPP TS 29.274 7.2.2
+ */
+ struct CreateSessionResponseMessage : public GtpcMessage
+ {
+ std::list<BearerContextCreated> bearerContextsCreated;
+ };
+
+
+ /**
+ * send a Create Session Response message
+ *
+ * \params msg the message
+ */
+ virtual void CreateSessionResponse (CreateSessionResponseMessage msg) = 0;
+
+
+ /**
+ * Modify Bearer Response message, see 3GPP TS 29.274 7.2.7
+ */
+ struct ModifyBearerResponseMessage : public GtpcMessage
+ {
+ enum Cause {
+ REQUEST_ACCEPTED = 0,
+ REQUEST_ACCEPTED_PARTIALLY,
+ REQUEST_REJECTED,
+ CONTEXT_NOT_FOUND
+ } cause;
+ };
+
+ /**
+ * send a Modify Bearer Response message
+ *
+ * \params msg the message
+ */
+ virtual void ModifyBearerResponse (ModifyBearerResponseMessage msg) = 0;
};
@@ -95,36 +136,47 @@
{
public:
- struct BearerContext
- {
-
+ struct BearerContextToBeCreated
+ {
EpcS11Sap::Fteid sgwFteid;
uint8_t epsBearerId;
EpsBearer bearerLevelQos;
Ptr<EpcTft> tft;
};
+
+ /**
+ * Create Session Request message, see 3GPP TS 29.274 7.2.1
+ */
+ struct CreateSessionRequestMessage : public GtpcMessage
+ {
+ uint64_t imsi;
+ Uli uli;
+ std::list<BearerContextToBeCreated> bearerContextsToBeCreated;
+ };
+
/**
- *
+ * send a Create Session Request message
*
- * \param imsi
- * \param uli theoretically, the User Location Information (ULI) which
- * includes the EGCI. In practice, we use the Cell Id.
- * \param bearersToBeSetup default bearer + eventual other bearers
- * to be setup
+ * \params msg the message
*/
- virtual void RecvCreateSessionRequest (uint64_t imsi, Uli uli, std::list<BearerContext> bearersToBeSetup) = 0;
+ virtual void CreateSessionRequest (CreateSessionRequestMessage msg) = 0;
+ /**
+ * Modify Bearer Request message, see 3GPP TS 29.274 7.2.7
+ */
+ struct ModifyBearerRequestMessage : public GtpcMessage
+ {
+ Uli uli;
+ };
+
/**
- *
+ * send a Modify Bearer Request message
*
- * \param imsi not included in the specs, we add it for simplicity.
- * \param uli theoretically, the User Location Information (ULI) which
- * includes the EGCI. In practice, we use the Cell Id.
- * \param bearersToBeSetup
+ * \params msg the message
*/
- virtual void ModifyBearerRequest (uint64_t mei, Uli uli, std::list<BearerContext> bearersToBeSetup) = 0;
+ virtual void ModifyBearerRequest (ModifyBearerRequestMessage msg) = 0;
};
@@ -146,7 +198,8 @@
MemberEpcS11SapMme (C* owner);
// inherited from EpcS11SapMme
- void RecvCreateSessionResponse (uint64_t imsi, std::list<BearerContext>);
+ virtual void CreateSessionResponse (CreateSessionResponseMessage msg);
+ virtual void ModifyBearerResponse (ModifyBearerResponseMessage msg);
private:
MemberEpcS11SapMme ();
@@ -165,9 +218,15 @@
}
template <class C>
-void MemberEpcS11SapMme<C>::RecvCreateSessionResponse (uint64_t imsi, std::list<BearerContext> bearerContextList)
+void MemberEpcS11SapMme<C>::CreateSessionResponse (CreateSessionResponseMessage msg)
{
- m_owner->DoRecvCreateSessionResponse (imsi, bearerContextList);
+ m_owner->DoCreateSessionResponse (msg);
+}
+
+template <class C>
+void MemberEpcS11SapMme<C>::ModifyBearerResponse (ModifyBearerResponseMessage msg)
+{
+ m_owner->DoModifyBearerResponse (msg);
}
@@ -186,8 +245,8 @@
MemberEpcS11SapSgw (C* owner);
// inherited from EpcS11SapSgw
- virtual void RecvCreateSessionRequest (uint64_t imsi, Uli uli, std::list<BearerContext> bearersToBeSetup);
- virtual void ModifyBearerRequest (uint64_t mei, Uli uli, std::list<BearerContext> bearersToBeSetup);
+ virtual void CreateSessionRequest (CreateSessionRequestMessage msg);
+ virtual void ModifyBearerRequest (ModifyBearerRequestMessage msg);
private:
MemberEpcS11SapSgw ();
@@ -206,15 +265,15 @@
}
template <class C>
-void MemberEpcS11SapSgw<C>::RecvCreateSessionRequest (uint64_t imsi, Uli uli, std::list<BearerContext> bearersToBeSetup)
+void MemberEpcS11SapSgw<C>::CreateSessionRequest (CreateSessionRequestMessage msg)
{
- m_owner->DoRecvCreateSessionRequest (imsi, uli, bearersToBeSetup);
+ m_owner->DoCreateSessionRequest (msg);
}
template <class C>
-void MemberEpcS11SapSgw<C>::ModifyBearerRequest (uint64_t mei, Uli uli, std::list<BearerContext> bearersToBeSetup)
+void MemberEpcS11SapSgw<C>::ModifyBearerRequest (ModifyBearerRequestMessage msg)
{
- m_owner->DoModifyBearerRequest (mei, uli, bearersToBeSetup);
+ m_owner->DoModifyBearerRequest (msg);
}
--- a/src/lte/model/epc-s1ap-sap.h Wed Nov 28 15:46:27 2012 +0100
+++ b/src/lte/model/epc-s1ap-sap.h Thu Nov 29 12:00:06 2012 +0100
@@ -59,15 +59,20 @@
*/
virtual void InitialUeMessage (uint64_t mmeUeS1Id, uint16_t enbUeS1Id, uint64_t imsi, uint16_t ecgi) = 0;
+
+ /**
+ * E-RAB Setup Item IEs, see 3GPP TS 36.413 9.1.4.2
+ *
+ */
struct ErabSetupItem
{
uint16_t erabId;
- Ipv4Address transportLayerAddress;
+ Ipv4Address enbTransportLayerAddress;
uint32_t enbTeid;
};
/**
- *
+ * INITIAL CONTEXT SETUP RESPONSE message, see 3GPP TS 36.413 9.1.4.2
*
* \param mmeUeS1Id in practice, we use the IMSI
* \param enbUeS1Id in practice, we use the RNTI
@@ -84,7 +89,7 @@
struct ErabSwitchedInDownlinkItem
{
uint16_t erabId;
- Ipv4Address transportLayerAddress;
+ Ipv4Address enbTransportLayerAddress;
uint32_t enbTeid;
};
@@ -92,7 +97,7 @@
* PATH SWITCH REQUEST message, see 3GPP TS 36.413 9.1.5.8
*
*/
- virtual void PathSwitchRequest (uint64_t enbUeS1Id, uint64_t mmeUeS1Id, uint16_t cgi, std::list<ErabSwitchedInDownlinkItem> erabToBeSwitchedInDownlinkList) = 0;
+ virtual void PathSwitchRequest (uint64_t enbUeS1Id, uint64_t mmeUeS1Id, uint16_t gci, std::list<ErabSwitchedInDownlinkItem> erabToBeSwitchedInDownlinkList) = 0;
};
--- a/src/lte/model/epc-sgw-pgw-application.cc Wed Nov 28 15:46:27 2012 +0100
+++ b/src/lte/model/epc-sgw-pgw-application.cc Thu Nov 29 12:00:06 2012 +0100
@@ -44,9 +44,10 @@
}
void
-EpcSgwPgwApplication::UeInfo::AddBearer (Ptr<EpcTft> tft, uint32_t teid)
+EpcSgwPgwApplication::UeInfo::AddBearer (Ptr<EpcTft> tft, uint8_t bearerId, uint32_t teid)
{
NS_LOG_FUNCTION (this << tft << teid);
+ m_teidByBearerIdMap[bearerId] = teid;
return m_tftClassifier.Add (tft, teid);
}
@@ -125,23 +126,6 @@
}
-uint32_t
-EpcSgwPgwApplication::ActivateS1Bearer (Ipv4Address ueAddr, Ipv4Address enbAddr, Ptr<EpcTft> tft)
-{
- NS_LOG_FUNCTION (this << ueAddr << enbAddr << tft);
-
- // simple sanity check. If you ever need more than 4M teids
- // throughout your simulation, you'll need to implement a smarter teid
- // management algorithm.
- NS_ABORT_IF (m_teidCount == 0xFFFFFFFF);
- uint32_t teid = ++m_teidCount;
-
- std::map<Ipv4Address, Ptr<UeInfo> >::iterator it = m_ueInfoByAddrMap.find (ueAddr);
- NS_ASSERT (it != m_ueInfoByAddrMap.end ());
- it->second->AddBearer (tft, teid);
- return teid;
-}
-
bool
EpcSgwPgwApplication::RecvFromTunDevice (Ptr<Packet> packet, const Address& source, const Address& dest, uint16_t protocolNumber)
{
@@ -262,42 +246,60 @@
}
void
-EpcSgwPgwApplication::DoRecvCreateSessionRequest (uint64_t imsi, EpcS11Sap::Uli uli, std::list<EpcS11SapSgw::BearerContext> bearersToBeSetup)
+EpcSgwPgwApplication::DoCreateSessionRequest (EpcS11SapSgw::CreateSessionRequestMessage req)
{
- NS_LOG_FUNCTION (this << imsi);
- std::map<uint64_t, Ptr<UeInfo> >::iterator ueit = m_ueInfoByImsiMap.find (imsi);
- NS_ASSERT_MSG (ueit != m_ueInfoByImsiMap.end (), "unknown IMSI " << imsi);
- Ipv4Address ueAddr = ueit->second->GetUeAddr ();
- uint16_t cellId = uli.gci;
+ NS_LOG_FUNCTION (this << req.imsi);
+ std::map<uint64_t, Ptr<UeInfo> >::iterator ueit = m_ueInfoByImsiMap.find (req.imsi);
+ NS_ASSERT_MSG (ueit != m_ueInfoByImsiMap.end (), "unknown IMSI " << req.imsi);
+ uint16_t cellId = req.uli.gci;
std::map<uint16_t, EnbInfo>::iterator enbit = m_enbInfoByCellId.find (cellId);
NS_ASSERT_MSG (enbit != m_enbInfoByCellId.end (), "unknown CellId " << cellId);
Ipv4Address enbAddr = enbit->second.enbAddr;
ueit->second->SetEnbAddr (enbAddr);
- // bearer context info to be fed back to the MME in the response
- std::list<EpcS11SapMme::BearerContext> bearersContextList;
+ EpcS11SapMme::CreateSessionResponseMessage res;
+ res.teid = req.imsi; // trick to avoid the need for allocating TEIDs on the S11 interface
- for (std::list<EpcS11SapSgw::BearerContext>::iterator bit = bearersToBeSetup.begin ();
- bit != bearersToBeSetup.end ();
+ for (std::list<EpcS11SapSgw::BearerContextToBeCreated>::iterator bit = req.bearerContextsToBeCreated.begin ();
+ bit != req.bearerContextsToBeCreated.end ();
++bit)
{
- uint32_t teid = ActivateS1Bearer (ueAddr, enbAddr, bit->tft);
- EpcS11SapMme::BearerContext bearerContext;
+ // simple sanity check. If you ever need more than 4M teids
+ // throughout your simulation, you'll need to implement a smarter teid
+ // management algorithm.
+ NS_ABORT_IF (m_teidCount == 0xFFFFFFFF);
+ uint32_t teid = ++m_teidCount;
+ ueit->second->AddBearer (bit->tft, bit->epsBearerId, teid);
+
+ EpcS11SapMme::BearerContextCreated bearerContext;
bearerContext.sgwFteid.teid = teid;
bearerContext.sgwFteid.address = enbit->second.sgwAddr;
bearerContext.epsBearerId = bit->epsBearerId;
bearerContext.bearerLevelQos = bit->bearerLevelQos;
bearerContext.tft = bit->tft;
- bearersContextList.push_back (bearerContext);
+ res.bearerContextsCreated.push_back (bearerContext);
}
- m_s11SapMme->RecvCreateSessionResponse (imsi, bearersContextList);
+ m_s11SapMme->CreateSessionResponse (res);
}
void
-EpcSgwPgwApplication::DoModifyBearerRequest (uint64_t mei, EpcS11Sap::Uli uli, std::list<EpcS11SapSgw::BearerContext> bearersToBeSetup)
+EpcSgwPgwApplication::DoModifyBearerRequest (EpcS11SapSgw::ModifyBearerRequestMessage req)
{
- NS_FATAL_ERROR ("not implemented");
+ NS_LOG_FUNCTION (this << req.teid);
+ uint64_t imsi = req.teid; // trick to avoid the need for allocating TEIDs on the S11 interface
+ std::map<uint64_t, Ptr<UeInfo> >::iterator ueit = m_ueInfoByImsiMap.find (imsi);
+ NS_ASSERT_MSG (ueit != m_ueInfoByImsiMap.end (), "unknown IMSI " << imsi);
+ uint16_t cellId = req.uli.gci;
+ std::map<uint16_t, EnbInfo>::iterator enbit = m_enbInfoByCellId.find (cellId);
+ NS_ASSERT_MSG (enbit != m_enbInfoByCellId.end (), "unknown CellId " << cellId);
+ Ipv4Address enbAddr = enbit->second.enbAddr;
+ ueit->second->SetEnbAddr (enbAddr);
+ // no actual bearer modification: for now we just support the minimum needed for path switch request (handover)
+ EpcS11SapMme::ModifyBearerResponseMessage res;
+ res.teid = imsi; // trick to avoid the need for allocating TEIDs on the S11 interface
+ res.cause = EpcS11SapMme::ModifyBearerResponseMessage::REQUEST_ACCEPTED;
+ m_s11SapMme->ModifyBearerResponse (res);
}
}; // namespace ns3
--- a/src/lte/model/epc-sgw-pgw-application.h Wed Nov 28 15:46:27 2012 +0100
+++ b/src/lte/model/epc-sgw-pgw-application.h Thu Nov 29 12:00:06 2012 +0100
@@ -168,8 +168,8 @@
private:
// S11 SAP SGW methods
- void DoRecvCreateSessionRequest (uint64_t imsi, EpcS11Sap::Uli uli, std::list<EpcS11SapSgw::BearerContext> bearersToBeSetup);
- void DoModifyBearerRequest (uint64_t mei, EpcS11Sap::Uli uli, std::list<EpcS11SapSgw::BearerContext> bearersToBeSetup);
+ void DoCreateSessionRequest (EpcS11SapSgw::CreateSessionRequestMessage msg);
+ void DoModifyBearerRequest (EpcS11SapSgw::ModifyBearerRequestMessage msg);
/**
* store info for each UE connected to this SGW
@@ -182,9 +182,10 @@
/**
*
* \param tft the Traffic Flow Template of the new bearer to be added
+ * \param epsBearerId the ID of the EPS Bearer to be activated
* \param teid the TEID of the new bearer
*/
- void AddBearer (Ptr<EpcTft> tft, uint32_t teid);
+ void AddBearer (Ptr<EpcTft> tft, uint8_t epsBearerId, uint32_t teid);
/**
*
@@ -226,6 +227,7 @@
EpcTftClassifier m_tftClassifier;
Ipv4Address m_enbAddr;
Ipv4Address m_ueAddr;
+ std::map<uint8_t, uint32_t> m_teidByBearerIdMap;
};
--- a/src/lte/model/lte-enb-net-device.cc Wed Nov 28 15:46:27 2012 +0100
+++ b/src/lte/model/lte-enb-net-device.cc Thu Nov 29 12:00:06 2012 +0100
@@ -48,8 +48,6 @@
NS_OBJECT_ENSURE_REGISTERED ( LteEnbNetDevice);
-uint16_t LteEnbNetDevice::m_cellIdCounter = 0;
-
TypeId LteEnbNetDevice::GetTypeId (void)
{
static TypeId
@@ -250,8 +248,7 @@
void
LteEnbNetDevice::DoStart (void)
{
- NS_ABORT_MSG_IF (m_cellIdCounter == 65535, "max num eNBs exceeded");
- m_cellId = ++m_cellIdCounter;
+
UpdateConfig ();
m_phy->Start ();
m_mac->Start ();
--- a/src/lte/model/lte-enb-net-device.h Wed Nov 28 15:46:27 2012 +0100
+++ b/src/lte/model/lte-enb-net-device.h Thu Nov 29 12:00:06 2012 +0100
@@ -148,8 +148,6 @@
uint16_t m_cellId; /**< Cell Identifer. Part of the CGI, see TS 29.274, section 8.21.1 */
- static uint16_t m_cellIdCounter;
-
uint8_t m_dlBandwidth; /**< downlink bandwidth in RBs */
uint8_t m_ulBandwidth; /**< uplink bandwidth in RBs */
--- a/src/lte/model/lte-enb-rrc.cc Wed Nov 28 15:46:27 2012 +0100
+++ b/src/lte/model/lte-enb-rrc.cc Thu Nov 29 12:00:06 2012 +0100
@@ -103,6 +103,7 @@
"CONNECTION_RECONFIGURATION",
"CONNECTION_REESTABLISHMENT",
"HANDOVER_JOINING",
+ "HANDOVER_PATH_SWITCH",
"HANDOVER_LEAVING",
};
@@ -263,6 +264,12 @@
m_sourceCellId = sourceCellId;
}
+void
+UeManager::SetImsi (uint64_t imsi)
+{
+ m_imsi = imsi;
+}
+
uint8_t
UeManager::SetupDataRadioBearer (EpsBearer bearer, uint32_t gtpTeid, Ipv4Address transportLayerAddress)
{
@@ -449,6 +456,31 @@
return ret;
}
+void
+UeManager::SendUeContextRelease ()
+{
+ NS_LOG_FUNCTION (this);
+ switch (m_state)
+ {
+ case HANDOVER_PATH_SWITCH:
+ NS_LOG_INFO ("Send UE CONTEXT RELEASE from target eNB to source eNB");
+ EpcX2SapProvider::UeContextReleaseParams ueCtxReleaseParams;
+ ueCtxReleaseParams.oldEnbUeX2apId = m_sourceX2apId;
+ ueCtxReleaseParams.newEnbUeX2apId = m_rnti;
+ ueCtxReleaseParams.sourceCellId = m_sourceCellId;
+ m_rrc->m_x2SapProvider->SendUeContextRelease (ueCtxReleaseParams);
+ SwitchToState (CONNECTED_NORMALLY);
+ break;
+
+ default:
+ NS_FATAL_ERROR ("method unexpected in state " << ToString (m_state));
+ break;
+ }
+}
+
+
+// methods forwarded from RRC SAP
+
void
UeManager::CompleteSetupUe (LteEnbRrcSapProvider::CompleteSetupUeParameters params)
{
@@ -515,13 +547,24 @@
break;
case HANDOVER_JOINING:
- NS_LOG_INFO ("Send UE CONTEXT RELEASE from target eNB to source eNB");
- EpcX2SapProvider::UeContextReleaseParams ueCtxReleaseParams;
- ueCtxReleaseParams.oldEnbUeX2apId = m_sourceX2apId;
- ueCtxReleaseParams.newEnbUeX2apId = m_rnti;
- ueCtxReleaseParams.sourceCellId = m_sourceCellId;
- m_rrc->m_x2SapProvider->SendUeContextRelease (ueCtxReleaseParams);
- SwitchToState (CONNECTED_NORMALLY);
+ {
+ NS_LOG_INFO ("Send PATH SWITCH REQUEST to the MME");
+ EpcEnbS1SapProvider::PathSwitchRequestParameters params;
+ params.rnti = m_rnti;
+ params.cellId = m_rrc->m_cellId;
+ params.mmeUeS1Id = m_imsi;
+ SwitchToState (HANDOVER_PATH_SWITCH);
+ for (std::map <uint8_t, Ptr<LteDataRadioBearerInfo> >::iterator it = m_drbMap.begin ();
+ it != m_drbMap.end ();
+ ++it)
+ {
+ EpcEnbS1SapProvider::BearerToBeSwitched b;
+ b.epsBearerId = it->second->m_epsBearerIdentity;
+ b.teid = it->second->m_gtpTeid;
+ params.bearersToBeSwitched.push_back (b);
+ }
+ m_rrc->m_s1SapProvider->PathSwitchRequest (params);
+ }
break;
default:
@@ -549,6 +592,8 @@
}
+// methods forwarded from CMAC SAP
+
void
UeManager::CmacUeConfigUpdateInd (LteEnbCmacSapUser::UeConfig cmacParams)
{
@@ -571,6 +616,8 @@
}
+// methods forwarded from PDCP SAP
+
void
UeManager::DoReceivePdcpSdu (LtePdcpSapUser::ReceivePdcpSduParameters params)
{
@@ -1037,7 +1084,7 @@
params.cause = EpcX2SapProvider::HandoverDesirableForRadioReason;
params.sourceCellId = m_cellId;
params.targetCellId = cellId;
- params.mmeUeS1apId = 1234567;
+ params.mmeUeS1apId = ueManager->GetImsi ();
params.ueAggregateMaxBitRateDownlink = 200 * 1000;
params.ueAggregateMaxBitRateUplink = 100 * 1000;
params.bearers = ueManager->GetErabList ();
@@ -1110,6 +1157,12 @@
ueManager->ScheduleRrcConnectionReconfiguration ();
}
+void
+LteEnbRrc::DoPathSwitchRequestAcknowledge (EpcEnbS1SapUser::PathSwitchRequestAcknowledgeParameters params)
+{
+ Ptr<UeManager> ueManager = GetUeManager (params.rnti);
+ ueManager->SendUeContextRelease ();
+}
void
LteEnbRrc::DoRecvHandoverRequest (EpcX2SapUser::HandoverRequestParams params)
@@ -1137,6 +1190,7 @@
Ptr<UeManager> ueManager = GetUeManager (rnti);
ueManager->SetSource (params.sourceCellId, params.oldEnbUeX2apId);
+ ueManager->SetImsi (params.mmeUeS1apId);
for (std::vector <EpcX2Sap::ErabToBeSetupItem>::iterator it = params.bearers.begin ();
it != params.bearers.end ();
--- a/src/lte/model/lte-enb-rrc.h Wed Nov 28 15:46:27 2012 +0100
+++ b/src/lte/model/lte-enb-rrc.h Thu Nov 29 12:00:06 2012 +0100
@@ -72,6 +72,7 @@
CONNECTION_RECONFIGURATION,
CONNECTION_REESTABLISHMENT,
HANDOVER_JOINING,
+ HANDOVER_PATH_SWITCH,
HANDOVER_LEAVING,
NUM_STATES
};
@@ -107,6 +108,13 @@
void SetSource (uint16_t sourceCellId, uint16_t sourceX2apId);
/**
+ * Set the IMSI
+ *
+ * \param imsi the IMSI
+ */
+ void SetImsi (uint64_t imsi);
+
+ /**
* Setup a new data radio bearer, including both the configuration
* within the eNB and the necessary RRC signaling with the UE
*
@@ -174,6 +182,13 @@
* \return a list of ERAB-to-be-setup items to be put in a X2 HO REQ message
*/
std::vector<EpcX2Sap::ErabToBeSetupItem> GetErabList ();
+
+ /**
+ * send the UE CONTEXT RELEASE X2 message to the source eNB, thus
+ * successfully terminating an X2 handover procedure
+ *
+ */
+ void SendUeContextRelease ();
// methods forwarded from RRC SAP
@@ -537,8 +552,7 @@
// S1 SAP methods
void DoDataRadioBearerSetupRequest (EpcEnbS1SapUser::DataRadioBearerSetupRequestParameters params);
-
-
+ void DoPathSwitchRequestAcknowledge (EpcEnbS1SapUser::PathSwitchRequestAcknowledgeParameters params);
// X2 SAP methods
void DoRecvHandoverRequest (EpcX2SapUser::HandoverRequestParams params);
void DoRecvHandoverRequestAck (EpcX2SapUser::HandoverRequestAckParams params);
--- a/src/lte/model/lte-ue-net-device.cc Wed Nov 28 15:46:27 2012 +0100
+++ b/src/lte/model/lte-ue-net-device.cc Thu Nov 29 12:00:06 2012 +0100
@@ -50,8 +50,6 @@
NS_OBJECT_ENSURE_REGISTERED ( LteUeNetDevice);
-uint64_t LteUeNetDevice::m_imsiCounter = 0;
-
TypeId LteUeNetDevice::GetTypeId (void)
{
@@ -92,7 +90,7 @@
}
- LteUeNetDevice::LteUeNetDevice (Ptr<Node> node, Ptr<LteUePhy> phy, Ptr<LteUeMac> mac, Ptr<LteUeRrc> rrc, Ptr<EpcUeNas> nas)
+ LteUeNetDevice::LteUeNetDevice (Ptr<Node> node, Ptr<LteUePhy> phy, Ptr<LteUeMac> mac, Ptr<LteUeRrc> rrc, Ptr<EpcUeNas> nas, uint64_t imsi)
{
NS_LOG_FUNCTION (this);
m_phy = phy;
@@ -100,7 +98,7 @@
m_rrc = rrc;
m_nas = nas;
SetNode (node);
- m_imsi = ++m_imsiCounter;
+ m_imsi = imsi;
}
LteUeNetDevice::~LteUeNetDevice (void)
--- a/src/lte/model/lte-ue-net-device.h Wed Nov 28 15:46:27 2012 +0100
+++ b/src/lte/model/lte-ue-net-device.h Thu Nov 29 12:00:06 2012 +0100
@@ -62,9 +62,10 @@
* \param mac the MAC entity
* \param rrc the RRC entity
* \param nas the NAS entity
+ * \param imsi the unique UE identifier
*
*/
- LteUeNetDevice (Ptr<Node> node, Ptr<LteUePhy> phy, Ptr<LteUeMac> mac, Ptr<LteUeRrc> rrc, Ptr<EpcUeNas> nas);
+ LteUeNetDevice (Ptr<Node> node, Ptr<LteUePhy> phy, Ptr<LteUeMac> mac, Ptr<LteUeRrc> rrc, Ptr<EpcUeNas> nas, uint64_t imsi);
virtual ~LteUeNetDevice (void);
virtual void DoDispose ();
@@ -123,8 +124,6 @@
Ptr<EpcUeNas> m_nas;
uint64_t m_imsi;
- static uint64_t m_imsiCounter;
-
};
--- a/src/lte/model/lte-ue-phy.cc Wed Nov 28 15:46:27 2012 +0100
+++ b/src/lte/model/lte-ue-phy.cc Thu Nov 29 12:00:06 2012 +0100
@@ -743,8 +743,8 @@
m_uplinkSpectrumPhy->SetCellId (cellId);
// configure DL for receing the BCH with the minimum bandwith
- const uint8_t minDlBandwidth = 6;
- Ptr<SpectrumValue> noisePsd = LteSpectrumValueHelper::CreateNoisePowerSpectralDensity (m_dlEarfcn, minDlBandwidth, m_noiseFigure);
+ m_dlBandwidth = 6;
+ Ptr<SpectrumValue> noisePsd = LteSpectrumValueHelper::CreateNoisePowerSpectralDensity (m_dlEarfcn, m_dlBandwidth, m_noiseFigure);
m_downlinkSpectrumPhy->SetNoisePowerSpectralDensity (noisePsd);
m_downlinkSpectrumPhy->GetChannel ()->AddRx (m_downlinkSpectrumPhy);
--- a/src/lte/test/lte-test-entities.cc Wed Nov 28 15:46:27 2012 +0100
+++ b/src/lte/test/lte-test-entities.cc Thu Nov 29 12:00:06 2012 +0100
@@ -659,7 +659,12 @@
{
}
+
+void
+EpcTestRrc::DoPathSwitchRequestAcknowledge (EpcEnbS1SapUser::PathSwitchRequestAcknowledgeParameters params)
+{
+}
} // namespace ns3
--- a/src/lte/test/lte-test-entities.h Wed Nov 28 15:46:27 2012 +0100
+++ b/src/lte/test/lte-test-entities.h Thu Nov 29 12:00:06 2012 +0100
@@ -290,7 +290,8 @@
// S1 SAP methods
void DoDataRadioBearerSetupRequest (EpcEnbS1SapUser::DataRadioBearerSetupRequestParameters params);
-
+ void DoPathSwitchRequestAcknowledge (EpcEnbS1SapUser::PathSwitchRequestAcknowledgeParameters params);
+
EpcEnbS1SapProvider* m_s1SapProvider;
EpcEnbS1SapUser* m_s1SapUser;