--- a/src/lte/examples/lena-x2-handover.cc Fri Jul 20 18:24:23 2012 +0200
+++ b/src/lte/examples/lena-x2-handover.cc Sun Jul 29 14:29:41 2012 +0200
@@ -145,7 +145,7 @@
lteHelper->AddX2Interface (enbNodes);
// X2-based Handover
- lteHelper->HandoverRequest (Seconds (2.0), ueNodes.Get (0), enbNodes.Get (0), enbNodes.Get (1));
+ lteHelper->HandoverRequest (Seconds (2.0), ueLteDevs.Get (0), enbLteDevs.Get (0), enbLteDevs.Get (1));
Simulator::Stop(Seconds(simTime));
--- a/src/lte/helper/epc-helper.cc Fri Jul 20 18:24:23 2012 +0200
+++ b/src/lte/helper/epc-helper.cc Sun Jul 29 14:29:41 2012 +0200
@@ -267,17 +267,6 @@
}
-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);
-}
-
-
void
EpcHelper::AttachUe (Ptr<NetDevice> ueLteDevice, uint64_t imsi, Ptr<NetDevice> enbDevice)
{
--- a/src/lte/helper/epc-helper.h Fri Jul 20 18:24:23 2012 +0200
+++ b/src/lte/helper/epc-helper.h Sun Jul 29 14:29:41 2012 +0200
@@ -90,9 +90,6 @@
*/
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.
*
--- a/src/lte/helper/lte-helper.cc Fri Jul 20 18:24:23 2012 +0200
+++ b/src/lte/helper/lte-helper.cc Sun Jul 29 14:29:41 2012 +0200
@@ -571,7 +571,7 @@
Ptr<LteEnbNetDevice> enbDevice = ueDevice->GetObject<LteUeNetDevice> ()->GetTargetEnb ();
Ptr<LteEnbRrc> enbRrc = enbDevice->GetObject<LteEnbNetDevice> ()->GetRrc ();
EpcEnbS1SapUser::DataRadioBearerSetupRequestParameters params;
- params.imsi = ueDevice->GetObject<LteUeNetDevice> ()->GetImsi ();
+ params.rnti = ueDevice->GetObject<LteUeNetDevice> ()->GetRrc ()->GetRnti();
params.bearer = bearer;
params.teid = 0; // don't care
enbRrc->GetS1SapUser ()->DataRadioBearerSetupRequest (params);
@@ -601,25 +601,21 @@
}
void
-LteHelper::HandoverRequest (Time hoTime, Ptr<Node> ueNode, Ptr<Node> sourceEnbNode, Ptr<Node> targetEnbNode)
+LteHelper::HandoverRequest (Time hoTime, Ptr<NetDevice> ueDev, Ptr<NetDevice> sourceEnbDev, Ptr<NetDevice> targetEnbDev)
{
- NS_LOG_FUNCTION (this << ueNode << sourceEnbNode << targetEnbNode);
- Simulator::Schedule (hoTime, &LteHelper::DoHandoverRequest, this, ueNode, sourceEnbNode, targetEnbNode);
+ NS_LOG_FUNCTION (this << ueDev << sourceEnbDev << targetEnbDev);
+ Simulator::Schedule (hoTime, &LteHelper::DoHandoverRequest, this, ueDev, sourceEnbDev, targetEnbDev);
}
void
-LteHelper::DoHandoverRequest (Ptr<Node> ueNode, Ptr<Node> sourceEnbNode, Ptr<Node> targetEnbNode)
+LteHelper::DoHandoverRequest (Ptr<NetDevice> ueDev, Ptr<NetDevice> sourceEnbDev, Ptr<NetDevice> targetEnbDev)
{
- NS_LOG_FUNCTION (this << ueNode << sourceEnbNode << targetEnbNode);
-
- m_epcHelper->SendHandoverRequest (ueNode, sourceEnbNode, targetEnbNode);
-
- // lteHelper->Attach (ueNode, targetEnbNode);
- // lteHelper->ActivateEpsBearer (ueNode, *);
+ NS_LOG_FUNCTION (this << ueDev << sourceEnbDev << targetEnbDev);
- // lteHelper->DeactivateEpsBearer (ueNode, *);
- // lteHelper->Deattach (ueNode, sourceEnbNode);
-
+ uint16_t targetCellId = targetEnbDev->GetObject<LteEnbNetDevice> ()->GetCellId ();
+ Ptr<LteEnbRrc> sourceRrc = sourceEnbDev->GetObject<LteEnbNetDevice> ()->GetRrc ();
+ uint64_t imsi = ueDev->GetObject<LteUeNetDevice> ()->GetImsi ();
+ sourceRrc->SendHandoverRequest (imsi, targetCellId);
}
--- a/src/lte/helper/lte-helper.h Fri Jul 20 18:24:23 2012 +0200
+++ b/src/lte/helper/lte-helper.h Sun Jul 29 14:29:41 2012 +0200
@@ -245,11 +245,11 @@
* 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
+ * \param ueDev the UE that hands off
+ * \param enbDev1 source eNB, originally the UE is attached to this eNB
+ * \param enbDev2 target eNB, the UE is finally connected to this eNB
*/
- void HandoverRequest (Time hoTime, Ptr<Node> ueNode, Ptr<Node> sourceEnbNode, Ptr<Node> targetEnbNode);
+ void HandoverRequest (Time hoTime, Ptr<NetDevice> ueDev, Ptr<NetDevice> sourceEnbDev, Ptr<NetDevice> targetEnbDev);
/**
@@ -360,7 +360,7 @@
Ptr<NetDevice> InstallSingleEnbDevice (Ptr<Node> n);
Ptr<NetDevice> InstallSingleUeDevice (Ptr<Node> n);
- void DoHandoverRequest (Ptr<Node> ueNode, Ptr<Node> sourceEnbNode, Ptr<Node> targetEnbNode);
+ void DoHandoverRequest (Ptr<NetDevice> ueDev, Ptr<NetDevice> sourceEnbDev, Ptr<NetDevice> targetEnbDev);
Ptr<SpectrumChannel> m_downlinkChannel;
Ptr<SpectrumChannel> m_uplinkChannel;
--- a/src/lte/model/epc-enb-application.cc Fri Jul 20 18:24:23 2012 +0200
+++ b/src/lte/model/epc-enb-application.cc Sun Jul 29 14:29:41 2012 +0200
@@ -82,22 +82,33 @@
NS_LOG_FUNCTION (this << teid << imsi);
// request the RRC to setup a radio bearer
struct EpcEnbS1SapUser::DataRadioBearerSetupRequestParameters params;
- params.imsi = imsi;
params.bearer = bearer;
params.teid = teid;
+ std::map<uint64_t, uint16_t>::iterator it = m_imsiRntiMap.find (imsi);
+ NS_ASSERT_MSG (it != m_imsiRntiMap.end (), "unknown IMSI");
+ params.rnti = it->second;
m_s1SapUser->DataRadioBearerSetupRequest (params);
}
void
-EpcEnbApplication::DoDataRadioBearerSetupResponse (EpcEnbS1SapProvider::DataRadioBearerSetupResponseParameters params)
+EpcEnbApplication::DoS1BearerSetupRequest (EpcEnbS1SapProvider::S1BearerSetupRequestParameters params)
{
- NS_ASSERT_MSG (params.success, "Radio Bearer Setup failed");
+ NS_LOG_FUNCTION (this);
LteFlowId_t rbid (params.rnti, params.lcid);
// side effect: create entries if not exist
m_rbidTeidMap[rbid] = params.teid;
m_teidRbidMap[params.teid] = rbid;
}
+
+void
+EpcEnbApplication::DoInitialUeMessage (uint64_t imsi, uint16_t rnti)
+{
+ NS_LOG_FUNCTION (this);
+ // side effect: create entry if not exist
+ m_imsiRntiMap[imsi] = rnti;
+}
+
void
EpcEnbApplication::RecvFromLteSocket (Ptr<Socket> socket)
{
--- a/src/lte/model/epc-enb-application.h Fri Jul 20 18:24:23 2012 +0200
+++ b/src/lte/model/epc-enb-application.h Sun Jul 29 14:29:41 2012 +0200
@@ -48,6 +48,8 @@
class EpcEnbApplication : public Application
{
+ friend class MemberEpcEnbS1SapProvider<EpcEnbApplication>;
+
public:
// inherited from Object
@@ -85,14 +87,6 @@
*/
EpcEnbS1SapProvider* GetS1SapProvider ();
-
- /**
- * \see EpcEnbS1SapUser::DataRadioBearerSetupResponse
- *
- * \param params
- */
- void DoDataRadioBearerSetupResponse (EpcEnbS1SapProvider::DataRadioBearerSetupResponseParameters params);
-
/**
* This method is triggered after the eNB received
* a S1-AP message of type E-RAB Setup Request by the MME and will
@@ -119,6 +113,13 @@
*/
void RecvFromS1uSocket (Ptr<Socket> socket);
+
+private:
+
+ // S1 SAP provider methods
+ void DoS1BearerSetupRequest (EpcEnbS1SapProvider::S1BearerSetupRequestParameters params);
+ void DoInitialUeMessage (uint64_t imsi, uint16_t rnti);
+
/**
* Send a packet to the UE via the LTE radio interface of the eNB
*
@@ -137,8 +138,15 @@
void SendToS1uSocket (Ptr<Packet> packet, uint32_t teid);
-private:
-
+
+ /**
+ * internal method used for the actual setup of the S1 Bearer
+ *
+ * \param teid
+ * \param rnti
+ * \param lcid
+ */
+ void SetupS1Bearer (uint32_t teid, uint16_t rnti, uint8_t lcid);
/**
* raw packet socket to send and receive the packets to and from the LTE radio interface
@@ -183,6 +191,12 @@
EpcEnbS1SapUser* m_s1SapUser;
+ /**
+ * UE context info
+ *
+ */
+ std::map<uint64_t, uint16_t> m_imsiRntiMap;
+
};
} //namespace ns3
--- a/src/lte/model/epc-enb-s1-sap.h Fri Jul 20 18:24:23 2012 +0200
+++ b/src/lte/model/epc-enb-s1-sap.h Sun Jul 29 14:29:41 2012 +0200
@@ -40,13 +40,11 @@
virtual ~EpcEnbS1SapProvider ();
/**
- * Parameters passed to DataRadioBearerSetupResponse ()
+ * Parameters passed to S1BearerSetupRequest ()
*
*/
- struct DataRadioBearerSetupResponseParameters
+ struct S1BearerSetupRequestParameters
{
- bool success; /**< true if DataRadioBearer was setup
- successfully, false otherwise*/
uint16_t rnti; /**< the RNTI corresponding to the IMSI for which
the radio bearer activation was requested */
uint8_t lcid; /**< the LCID of the newly created radio bearer */
@@ -57,12 +55,18 @@
};
/**
- * response after a call to
- * EpcEnbS1SapUser::DataRadioBearerSetupRequest ()
+ * Request the setup of a S1 bearer
*
*/
- virtual void DataRadioBearerSetupResponse (DataRadioBearerSetupResponseParameters params) = 0;
+ virtual void S1BearerSetupRequest (S1BearerSetupRequestParameters params) = 0;
+ /**
+ *
+ *
+ * \param imsi
+ * \param rnti
+ */
+ virtual void InitialUeMessage (uint64_t imsi, uint16_t rnti) = 0;
};
@@ -85,13 +89,13 @@
*/
struct DataRadioBearerSetupRequestParameters
{
- uint64_t imsi; /**< the IMSI identifying the UE for which the
+ uint16_t rnti; /**< the RNTI identifying the UE for which the
DataRadioBearer is to be created */
EpsBearer bearer; /**< the characteristics of the bearer to be set
up */
uint32_t teid; /**< context information that needs to be passed
to the corresponding call to
- EpcEnbS1SapProvider::DataRadioBearerSetupResponse */
+ EpcEnbS1SapProvider::S1BearerSetupRequest */
};
/**
@@ -117,8 +121,8 @@
MemberEpcEnbS1SapProvider (C* owner);
// inherited from EpcEnbS1SapProvider
- virtual void DataRadioBearerSetupResponse (DataRadioBearerSetupResponseParameters params);
-
+ virtual void S1BearerSetupRequest (S1BearerSetupRequestParameters params);
+ virtual void InitialUeMessage (uint64_t imsi, uint16_t rnti);
private:
MemberEpcEnbS1SapProvider ();
@@ -137,12 +141,18 @@
}
template <class C>
-void MemberEpcEnbS1SapProvider<C>::DataRadioBearerSetupResponse (DataRadioBearerSetupResponseParameters params)
+void MemberEpcEnbS1SapProvider<C>::S1BearerSetupRequest (S1BearerSetupRequestParameters params)
{
- m_owner->DoDataRadioBearerSetupResponse (params);
+ m_owner->DoS1BearerSetupRequest (params);
}
+template <class C>
+void MemberEpcEnbS1SapProvider<C>::InitialUeMessage (uint64_t imsi, uint16_t rnti)
+{
+ m_owner->DoInitialUeMessage (imsi, rnti);
+}
+
/**
* Template for the implementation of the EpcEnbS1SapUser as a member
* of an owner class of type C to which all methods are forwarded
--- a/src/lte/model/epc-x2.cc Fri Jul 20 18:24:23 2012 +0200
+++ b/src/lte/model/epc-x2.cc Sun Jul 29 14:29:41 2012 +0200
@@ -194,8 +194,7 @@
"Missing infos of local and remote CellId");
Ptr<X2CellInfo> cellsInfo = m_x2InterfaceCellIds [socket];
- EpcX2SapUser::HandoverRequestAckParams params;
- params.cause = x2HoReqAckHeader.GetCause ();
+ EpcX2SapUser::HandoverRequestAckParams params;
params.sourceCellId = cellsInfo->m_localCellId;
params.targetCellId = cellsInfo->m_remoteCellId;
--- a/src/lte/model/lte-enb-cmac-sap.h Fri Jul 20 18:24:23 2012 +0200
+++ b/src/lte/model/lte-enb-cmac-sap.h Sun Jul 29 14:29:41 2012 +0200
@@ -55,6 +55,12 @@
virtual void AddUe (uint16_t rnti) = 0;
+ /**
+ * remove the UE, e.g., after handover or termination of the RRC connection
+ *
+ * \param rnti
+ */
+ virtual void RemoveUe (uint16_t rnti) = 0;
/**
* Logical Channel information to be passed to CmacSapProvider::ConfigureLc
--- a/src/lte/model/lte-enb-cphy-sap.h Fri Jul 20 18:24:23 2012 +0200
+++ b/src/lte/model/lte-enb-cphy-sap.h Sun Jul 29 14:29:41 2012 +0200
@@ -67,10 +67,9 @@
/**
* Add a new UE to the cell
*
- * \param imsi the unique UE id
* \param rnti the UE id relative to this cell
*/
- virtual void AddUe (uint64_t imsi, uint16_t rnti) = 0;
+ virtual void AddUe (uint16_t rnti) = 0;
/**
@@ -115,7 +114,7 @@
virtual void SetCellId (uint16_t cellId);
virtual void SetBandwidth (uint8_t ulBandwidth, uint8_t dlBandwidth);
virtual void SetEarfcn (uint16_t ulEarfcn, uint16_t dlEarfcn);
- virtual void AddUe (uint64_t imsi, uint16_t rnti);
+ virtual void AddUe (uint16_t rnti);
virtual void SetTransmissionMode (uint16_t rnti, uint8_t txMode);
private:
@@ -158,9 +157,9 @@
template <class C>
void
-MemberLteEnbCphySapProvider<C>::AddUe (uint64_t imsi, uint16_t rnti)
+MemberLteEnbCphySapProvider<C>::AddUe (uint16_t rnti)
{
- m_owner->DoAddUe (imsi, rnti);
+ m_owner->DoAddUe (rnti);
}
--- a/src/lte/model/lte-enb-mac.cc Fri Jul 20 18:24:23 2012 +0200
+++ b/src/lte/model/lte-enb-mac.cc Sun Jul 29 14:29:41 2012 +0200
@@ -59,6 +59,7 @@
// inherited from LteEnbCmacSapProvider
virtual void ConfigureMac (uint8_t ulBandwidth, uint8_t dlBandwidth);
virtual void AddUe (uint16_t rnti);
+ virtual void RemoveUe (uint16_t rnti);
virtual void AddLc (LcInfo lcinfo, LteMacSapUser* msu);
virtual void ReconfigureLc (LcInfo lcinfo);
virtual void ReleaseLc (uint16_t rnti, uint8_t lcid);
@@ -87,6 +88,12 @@
}
void
+EnbMacMemberLteEnbCmacSapProvider::RemoveUe (uint16_t rnti)
+{
+ m_mac->DoRemoveUe (rnti);
+}
+
+void
EnbMacMemberLteEnbCmacSapProvider::AddLc (LcInfo lcinfo, LteMacSapUser* msu)
{
m_mac->DoAddLc (lcinfo, msu);
@@ -640,6 +647,14 @@
m_cschedSapProvider->CschedUeConfigReq (params);
}
+void
+LteEnbMac::DoRemoveUe (uint16_t rnti)
+{
+ NS_LOG_FUNCTION (this << " rnti=" << rnti);
+ FfMacCschedSapProvider::CschedUeReleaseReqParameters params;
+ params.m_rnti = rnti;
+ m_cschedSapProvider->CschedUeReleaseReq (params);
+}
void
LteEnbMac::DoAddLc (LteEnbCmacSapProvider::LcInfo lcinfo, LteMacSapUser* msu)
--- a/src/lte/model/lte-enb-mac.h Fri Jul 20 18:24:23 2012 +0200
+++ b/src/lte/model/lte-enb-mac.h Sun Jul 29 14:29:41 2012 +0200
@@ -141,6 +141,7 @@
// forwarded from LteEnbCmacSapProvider
void DoConfigureMac (uint8_t ulBandwidth, uint8_t dlBandwidth);
void DoAddUe (uint16_t rnti);
+ void DoRemoveUe (uint16_t rnti);
void DoAddLc (LteEnbCmacSapProvider::LcInfo lcinfo, LteMacSapUser* msu);
void DoReconfigureLc (LteEnbCmacSapProvider::LcInfo lcinfo);
void DoReleaseLc (uint16_t rnti, uint8_t lcid);
--- a/src/lte/model/lte-enb-phy.cc Fri Jul 20 18:24:23 2012 +0200
+++ b/src/lte/model/lte-enb-phy.cc Sun Jul 29 14:29:41 2012 +0200
@@ -33,6 +33,7 @@
#include "lte-spectrum-value-helper.h"
#include "ideal-control-messages.h"
#include "lte-enb-net-device.h"
+#include "lte-ue-rrc.h"
#include "lte-enb-mac.h"
#include <ns3/lte-common.h>
@@ -606,9 +607,9 @@
void
-LteEnbPhy::DoAddUe (uint64_t imsi, uint16_t rnti)
+LteEnbPhy::DoAddUe (uint16_t rnti)
{
- NS_LOG_FUNCTION (this << imsi << rnti);
+ NS_LOG_FUNCTION (this << rnti);
// since for now ctrl messages are still sent directly to the UePhy
// without passing to the channel, we need to get a pointer to the
// UePhy. We do so by walking the whole UE list. This code will
@@ -630,7 +631,8 @@
}
else
{
- if (ueDev->GetImsi () == imsi)
+ Ptr<LteUeRrc> rrc = ueDev->GetRrc ();
+ if ((rrc->GetRnti () == rnti) && (rrc->GetCellId () == m_cellId))
{
found = true;
uePhy = ueDev->GetPhy ();
@@ -638,7 +640,7 @@
}
}
}
- NS_ASSERT_MSG (found , " Unable to find UE with IMSI =" << imsi);
+ NS_ASSERT_MSG (found , " Unable to find UE with RNTI=" << rnti << " cellId=" << m_cellId);
bool success = AddUePhy (rnti, uePhy);
NS_ASSERT_MSG (success, "AddUePhy() failed");
}
--- a/src/lte/model/lte-enb-phy.h Fri Jul 20 18:24:23 2012 +0200
+++ b/src/lte/model/lte-enb-phy.h Sun Jul 29 14:29:41 2012 +0200
@@ -207,7 +207,7 @@
// LteEnbCphySapProvider forwarded methods
void DoSetBandwidth (uint8_t ulBandwidth, uint8_t dlBandwidth);
void DoSetEarfcn (uint16_t dlEarfcn, uint16_t ulEarfcn);
- void DoAddUe (uint64_t imsi, uint16_t rnti);
+ void DoAddUe (uint16_t rnti);
void DoSetTransmissionMode (uint16_t rnti, uint8_t txMode);
--- a/src/lte/model/lte-enb-rrc.cc Fri Jul 20 18:24:23 2012 +0200
+++ b/src/lte/model/lte-enb-rrc.cc Sun Jul 29 14:29:41 2012 +0200
@@ -26,6 +26,7 @@
#include "ns3/pointer.h"
#include "ns3/object-map.h"
#include "ns3/object-factory.h"
+#include "ns3/simulator.h"
#include "ns3/lte-enb-rrc.h"
#include "ns3/lte-enb-net-device.h"
@@ -132,6 +133,12 @@
return m_imsi;
}
+void
+UeInfo::SetImsi (uint64_t imsi)
+{
+ m_imsi = imsi;
+}
+
uint8_t
UeInfo::AddRadioBearer (Ptr<LteRadioBearerInfo> rbi)
{
@@ -171,11 +178,7 @@
NS_ASSERT_MSG (it != m_rbMap.end (), "request to remove radio bearer with unknown lcid " << lcid);
m_rbMap.erase (it);
}
-
-
-
-
-
+
// ///////////////////////////
// eNB RRC methods
// ///////////////////////////
@@ -356,20 +359,60 @@
m_cmacSapProvider->ConfigureMac (ulBandwidth, dlBandwidth);
m_cphySapProvider->SetBandwidth (ulBandwidth, dlBandwidth);
m_cphySapProvider->SetEarfcn (ulEarfcn, dlEarfcn);
+ m_cellId = cellId;
m_cphySapProvider->SetCellId (cellId);
m_configured = true;
}
uint16_t
-LteEnbRrc::AddUe (uint64_t imsi)
+LteEnbRrc::ConnectionRequest (uint64_t imsi)
+{
+ NS_LOG_FUNCTION (this);
+ // no Call Admission Control for now
+ uint16_t rnti = AddUe ();
+ std::map<uint16_t, Ptr<UeInfo> >::iterator it = m_ueMap.find (rnti);
+ NS_ASSERT_MSG (it != m_ueMap.end (), "RNTI " << rnti << " not found in eNB with cellId " << m_cellId);
+ it->second->SetImsi (imsi);
+
+ if (m_s1SapProvider != 0)
+ {
+ m_s1SapProvider->InitialUeMessage (imsi, rnti);
+ }
+
+ return rnti;
+}
+
+
+uint16_t
+LteEnbRrc::ConnectionReestablishmentRequest (uint64_t imsi, uint16_t rnti)
{
- NS_LOG_FUNCTION (this << imsi);
+ NS_LOG_FUNCTION (this);
// no Call Admission Control for now
- uint16_t rnti = CreateUeInfo (imsi); // side effect: create UeInfo for this UE
- m_imsiRntiMap[imsi] = rnti; // side effect: add entry if not present
+ std::map<uint16_t, Ptr<UeInfo> >::iterator it = m_ueMap.find (rnti);
+ NS_ASSERT_MSG (it != m_ueMap.end (), "RNTI " << rnti << " not found in eNB with cellId " << m_cellId);
+
+ // this is needed because if the reestablishment comes from handover we don't know the imsi yet
+ it->second->SetImsi (imsi);
+
+ if (m_s1SapProvider != 0)
+ {
+ m_s1SapProvider->InitialUeMessage (imsi, rnti);
+ }
+
+ return rnti;
+}
+
+
+uint16_t
+LteEnbRrc::AddUe ()
+{
+ NS_LOG_FUNCTION (this);
+ // no Call Admission Control for now
+ uint16_t rnti = CreateUeInfo (); // side effect: create UeInfo for this UE
NS_ASSERT_MSG (rnti != 0, "CreateUeInfo returned RNTI==0");
m_cmacSapProvider->AddUe (rnti);
- m_cphySapProvider->AddUe (imsi, rnti);
+ // need to do this after the present method returns, because under the hood a lookup is done for the RNTI, and otherwise the UE will not have it assigned yet
+ Simulator::ScheduleNow (&LteEnbCphySapProvider::AddUe, m_cphySapProvider, rnti);
return rnti;
}
@@ -378,7 +421,6 @@
{
NS_LOG_FUNCTION (this << (uint32_t) rnti);
RemoveUeInfo (rnti);
- m_imsiRntiMap.erase (rnti);
NS_FATAL_ERROR ("missing RemoveUe method in CMAC SAP");
}
@@ -420,32 +462,21 @@
void
LteEnbRrc::DoDataRadioBearerSetupRequest (EpcEnbS1SapUser::DataRadioBearerSetupRequestParameters request)
{
- EpcEnbS1SapProvider::DataRadioBearerSetupResponseParameters response;
- std::map<uint64_t, uint16_t>::iterator it = m_imsiRntiMap.find (request.imsi);
- if (it == m_imsiRntiMap.end ())
- {
- NS_LOG_ERROR ("unknown IMSI");
- response.success = false;
- if (m_s1SapProvider)
- {
- m_s1SapProvider->DataRadioBearerSetupResponse (response);
- }
- }
- else
- {
- response.rnti = it->second;
- response.lcid = SetupRadioBearer (response.rnti, request.bearer);
- response.success = (response.lcid > 0);
- response.teid = request.teid;
- if (m_s1SapProvider)
- {
- m_s1SapProvider->DataRadioBearerSetupResponse (response);
- }
+ EpcEnbS1SapProvider::S1BearerSetupRequestParameters response;
+ std::map<uint16_t, Ptr<UeInfo> >::iterator it = m_ueMap.find (request.rnti);
+ NS_ASSERT_MSG (it != m_ueMap.end (), "unknown RNTI");
+ response.rnti = request.rnti;
+ response.lcid = SetupRadioBearer (response.rnti, request.bearer, request.teid);
+ NS_ASSERT_MSG (response.lcid > 0, "SetupRadioBearer() returned LCID == 0. Too many LCs?");
+ response.teid = request.teid;
+ if (m_s1SapProvider)
+ {
+ m_s1SapProvider->S1BearerSetupRequest (response);
}
}
uint8_t
-LteEnbRrc::SetupRadioBearer (uint16_t rnti, EpsBearer bearer)
+LteEnbRrc::SetupRadioBearer (uint16_t rnti, EpsBearer bearer, uint32_t teid)
{
NS_LOG_FUNCTION (this << (uint32_t) rnti);
@@ -461,6 +492,8 @@
rlc->SetRnti (rnti);
Ptr<LteRadioBearerInfo> rbInfo = CreateObject<LteRadioBearerInfo> ();
+ rbInfo->m_epsBearer = bearer;
+ rbInfo->m_teid = teid;
rbInfo->m_rlc = rlc;
uint8_t lcid = ueInfo->AddRadioBearer (rbInfo);
if (lcid == 0)
@@ -546,19 +579,19 @@
// User API
//
void
-LteEnbRrc::SendHandoverRequest (Ptr<Node> ueNode, Ptr<Node> sourceEnbNode, Ptr<Node> targetEnbNode)
+LteEnbRrc::SendHandoverRequest (uint16_t rnti, uint16_t cellId)
{
- NS_LOG_FUNCTION (this << ueNode << sourceEnbNode << targetEnbNode);
+ NS_LOG_FUNCTION (this << rnti << cellId);
NS_LOG_LOGIC ("Request to send HANDOVER REQUEST");
-
- Ptr<LteUeRrc> ueRrc = ueNode->GetDevice (0)->GetObject<LteUeNetDevice> ()->GetRrc ();
- uint16_t rnti = ueRrc->GetRnti ();
+
+ std::map<uint16_t, Ptr<UeInfo> >::iterator it = m_ueMap.find (rnti);
+ NS_ASSERT_MSG (it != m_ueMap.end (), "RNTI " << rnti << " not found in eNB with cellId " << m_cellId);
EpcX2SapProvider::HandoverRequestParams params;
params.oldEnbUeX2apId = rnti;
params.cause = EpcX2SapProvider::HandoverDesirableForRadioReason;
- params.sourceCellId = sourceEnbNode->GetDevice (0)->GetObject<LteEnbNetDevice> ()->GetCellId ();
- params.targetCellId = targetEnbNode->GetDevice (0)->GetObject<LteEnbNetDevice> ()->GetCellId ();
+ params.sourceCellId = m_cellId;
+ params.targetCellId = cellId;
params.ueAggregateMaxBitRateDownlink = 200 * 1000;
params.ueAggregateMaxBitRateUplink = 100 * 1000;
@@ -588,9 +621,19 @@
NS_LOG_LOGIC ("sourceCellId = " << params.sourceCellId);
NS_LOG_LOGIC ("targetCellId = " << params.targetCellId);
- uint8_t rrcData [100];
- params.rrcContext->CopyData (rrcData, params.rrcContext->GetSize ());
- NS_LOG_LOGIC ("rrcContext = " << rrcData);
+ // this crashes, apparently EpcX2 is not correctly filling in the params yet
+ // uint8_t rrcData [100];
+ // params.rrcContext->CopyData (rrcData, params.rrcContext->GetSize ());
+ // NS_LOG_LOGIC ("rrcContext = " << rrcData);
+
+ uint16_t rnti = AddUe ();
+
+ for (std::vector <EpcX2Sap::ErabToBeSetupItem>::iterator it = params.bearers.begin ();
+ it != params.bearers.end ();
+ ++it)
+ {
+ SetupRadioBearer (rnti, it->erabLevelQosParameters, it->gtpTeid);
+ }
NS_LOG_LOGIC ("Send X2 message: HANDOVER REQUEST ACK");
@@ -651,9 +694,9 @@
uint16_t
-LteEnbRrc::CreateUeInfo (uint64_t imsi)
+LteEnbRrc::CreateUeInfo ()
{
- NS_LOG_FUNCTION (this << imsi);
+ NS_LOG_FUNCTION (this);
for (uint16_t rnti = m_lastAllocatedRnti; rnti != m_lastAllocatedRnti - 1; ++rnti)
{
if (rnti != 0)
@@ -661,7 +704,7 @@
if (m_ueMap.find (rnti) == m_ueMap.end ())
{
m_lastAllocatedRnti = rnti;
- m_ueMap.insert (std::pair<uint16_t, Ptr<UeInfo> > (rnti, CreateObject<UeInfo> (imsi)));
+ m_ueMap.insert (std::pair<uint16_t, Ptr<UeInfo> > (rnti, CreateObject<UeInfo> ()));
return rnti;
}
}
--- a/src/lte/model/lte-enb-rrc.h Fri Jul 20 18:24:23 2012 +0200
+++ b/src/lte/model/lte-enb-rrc.h Sun Jul 29 14:29:41 2012 +0200
@@ -41,7 +41,6 @@
class EpcEnbS1SapProvider;
class LteUeRrc;
-
/**
* Manages all the radio bearer information possessed by the ENB RRC for a single UE
*
@@ -75,6 +74,19 @@
*/
void RemoveRadioBearer (uint8_t lcid);
+ /**
+ *
+ * \return a const iterator pointing to the beginning of the embedded map of radio bearers
+ */
+ std::map <uint8_t, Ptr<LteRadioBearerInfo> >::const_iterator RadioBearerMapBegin ();
+
+
+ /**
+ *
+ * \return a const iterator pointing to the end of the embedded map of radio bearers
+ */
+ std::map <uint8_t, Ptr<LteRadioBearerInfo> >::const_iterator RadioBearerMapEnd ();
+
UeInfo (void);
UeInfo (uint64_t imsi);
virtual ~UeInfo (void);
@@ -83,6 +95,8 @@
uint64_t GetImsi (void);
+ void SetImsi (uint64_t imsi);
+
private:
std::map <uint8_t, Ptr<LteRadioBearerInfo> > m_rbMap;
uint8_t m_lastAllocatedId;
@@ -212,13 +226,25 @@
uint16_t dlEarfcn,
uint16_t cellId);
- /**
- * Add a new UE to the cell
- *
- * \param imsi IMSI of the attaching UE
- * \return the C-RNTI of the newly added UE
+
+ /**
+ * RRC connection request by an UE
+ *
+ * \param imsi the id of the UE
+ *
+ * \return the RNTI identifying the UE in this cell
*/
- uint16_t AddUe (uint64_t imsi);
+ uint16_t ConnectionRequest (uint64_t imsi);
+
+ /**
+ * RRC connection reestablishment request by UE
+ *
+ * \param imsi
+ * \param rnti
+ *
+ * \return
+ */
+ uint16_t ConnectionReestablishmentRequest (uint64_t imsi, uint16_t rnti);
/**
* remove a UE from the cell
@@ -242,17 +268,6 @@
/**
- * Setup a new radio bearer for the given user
- *
- * \param rnti the RNTI of the user
- * \param bearer the characteristics of the bearer to be activated
- *
- * \return the logical channel identifier of the radio bearer for the considered user
- */
- uint8_t SetupRadioBearer (uint16_t rnti, EpsBearer bearer);
-
-
- /**
*
* Release the given radio bearer
*
@@ -281,8 +296,15 @@
/**
* Send a HandoverRequest through the X2 SAP interface
+ *
+ * This method will trigger a handover which is started by the RRC
+ * by sending a handover request to the target eNB over the X2
+ * interface
+ *
+ * \param imsi the id of the UE to be handed over
+ * \param cellId the id of the target eNB
*/
- void SendHandoverRequest (Ptr<Node> ueNode, Ptr<Node> sourceEnbNode, Ptr<Node> targetEnbNode);
+ void SendHandoverRequest (uint16_t rnti, uint16_t cellId);
/**
* Identifies how EPS Bearer parameters are mapped to different RLC types
@@ -293,6 +315,28 @@
RLC_AM_ALWAYS = 3,
PER_BASED = 4};
private:
+
+ /**
+ * Add a new UE to the cell
+ *
+ * \return the C-RNTI of the newly added UE
+ */
+ uint16_t AddUe ();
+
+
+
+ /**
+ * Setup a new radio bearer for the given user
+ *
+ * \param rnti the RNTI of the user
+ * \param bearer the characteristics of the bearer to be activated
+ * \param teid the S1-U Tunnel Endpoint Identifier for this bearer
+ *
+ * \return the logical channel identifier of the radio bearer for the considered user
+ */
+ uint8_t SetupRadioBearer (uint16_t rnti, EpsBearer bearer, uint32_t teid);
+
+
void DoRecvHandoverRequest (EpcX2SapUser::HandoverRequestParams params);
void DoRecvHandoverRequestAck (EpcX2SapUser::HandoverRequestAckParams params);
@@ -311,7 +355,7 @@
// management of multiple UE info instances
- uint16_t CreateUeInfo (uint64_t imsi);
+ uint16_t CreateUeInfo ();
Ptr<UeInfo> GetUeInfo (uint16_t rnti);
void RemoveUeInfo (uint16_t rnti);
@@ -338,10 +382,9 @@
LteEnbCphySapProvider* m_cphySapProvider;
bool m_configured;
+ uint16_t m_cellId;
uint16_t m_lastAllocatedRnti;
- std::map<uint64_t, uint16_t> m_imsiRntiMap;
-
std::map<uint16_t, Ptr<UeInfo> > m_ueMap;
uint8_t m_defaultTransmissionMode;
--- a/src/lte/model/lte-radio-bearer-info.h Fri Jul 20 18:24:23 2012 +0200
+++ b/src/lte/model/lte-radio-bearer-info.h Sun Jul 29 14:29:41 2012 +0200
@@ -21,6 +21,7 @@
#include <ns3/object.h>
#include <ns3/pointer.h>
+#include <ns3/eps-bearer.h>
namespace ns3 {
@@ -41,7 +42,8 @@
Ptr<LteRlc> m_rlc;
Ptr<LtePdcp> m_pdcp;
-
+ EpsBearer m_epsBearer;
+ uint32_t m_teid;
};
--- a/src/lte/model/lte-ue-rrc.cc Fri Jul 20 18:24:23 2012 +0200
+++ b/src/lte/model/lte-ue-rrc.cc Sun Jul 29 14:29:41 2012 +0200
@@ -22,6 +22,8 @@
#include <ns3/log.h>
#include "ns3/object-map.h"
#include "ns3/object-factory.h"
+#include "ns3/node-list.h"
+#include "ns3/node.h"
#include "lte-ue-rrc.h"
#include "lte-enb-rrc.h"
@@ -289,7 +291,7 @@
{
NS_LOG_FUNCTION (this);
- m_rnti = m_enbRrc->AddUe (m_imsi);
+ m_rnti = m_enbRrc->ConnectionRequest (m_imsi);
m_cmacSapProvider->ConfigureUe (m_rnti);
m_cphySapProvider->SetRnti (m_rnti);
}
@@ -327,6 +329,43 @@
m_cphySapProvider->SetTransmissionMode (params.m_transmissionMode);
}
+void
+LteUeRrc::ConnectionReconfigurationWithMobilityControlInfo (uint16_t targetCellId, uint16_t newRnti)
+{
+ Ptr<LteEnbNetDevice> enbDev;
+ // WILD HACK - eventually we'll get rid of all these Ptr<Device> around
+ NodeList::Iterator listEnd = NodeList::End ();
+ bool found = false;
+ for (NodeList::Iterator i = NodeList::Begin (); i != listEnd; i++)
+ {
+ Ptr<Node> node = *i;
+ int nDevs = node->GetNDevices ();
+ for (int j = 0; j < nDevs; j++)
+ {
+ enbDev = node->GetDevice (j)->GetObject <LteEnbNetDevice> ();
+ if (!enbDev)
+ {
+ continue;
+ }
+ else
+ {
+ if (enbDev->GetCellId () == targetCellId)
+ {
+ found = true;
+ }
+ }
+ }
+ }
+ NS_ASSERT_MSG (found , " Unable to find eNB with CellId =" << targetCellId);
+
+ DoForceCampedOnEnb (enbDev, targetCellId);
+ m_rnti = newRnti;
+ m_cmacSapProvider->ConfigureUe (m_rnti);
+ m_cphySapProvider->SetRnti (m_rnti);
+ enbDev->GetObject<LteEnbRrc> ()->ConnectionReestablishmentRequest (m_imsi, m_rnti);
+
+}
+
} // namespace ns3
--- a/src/lte/model/lte-ue-rrc.h Fri Jul 20 18:24:23 2012 +0200
+++ b/src/lte/model/lte-ue-rrc.h Sun Jul 29 14:29:41 2012 +0200
@@ -185,6 +185,15 @@
*
*/
void DoRrcConfigurationUpdateInd (LteUeConfig_t params);
+
+
+ /**
+ * Execute a handover
+ *
+ * \param targetCellId
+ * \param newRnti
+ */
+ void ConnectionReconfigurationWithMobilityControlInfo (uint16_t targetCellId, uint16_t newRnti);
private:
--- a/src/lte/test/epc-test-s1u-downlink.cc Fri Jul 20 18:24:23 2012 +0200
+++ b/src/lte/test/epc-test-s1u-downlink.cc Sun Jul 29 14:29:41 2012 +0200
@@ -202,6 +202,7 @@
uint64_t imsi = u+1;
epcHelper->AttachUe (ueLteDevice, imsi, enbDevice);
+ enbApp->GetS1SapProvider ()->InitialUeMessage (imsi, (uint16_t) imsi);
epcHelper->ActivateEpsBearer (ueLteDevice, imsi, EpcTft::Default (), EpsBearer (EpsBearer::NGBR_VIDEO_TCP_DEFAULT));
}
--- a/src/lte/test/epc-test-s1u-uplink.cc Fri Jul 20 18:24:23 2012 +0200
+++ b/src/lte/test/epc-test-s1u-uplink.cc Sun Jul 29 14:29:41 2012 +0200
@@ -425,6 +425,7 @@
uint64_t imsi = u+1;
epcHelper->AttachUe (ueLteDevice, imsi, enbDevice);
+ enbApp->GetS1SapProvider ()->InitialUeMessage (imsi, (uint16_t) imsi);
epcHelper->ActivateEpsBearer (ueLteDevice, imsi, EpcTft::Default (), EpsBearer (EpsBearer::NGBR_VIDEO_TCP_DEFAULT));
// need this since all sinks are installed in the same node
--- a/src/lte/test/lte-test-entities.cc Fri Jul 20 18:24:23 2012 +0200
+++ b/src/lte/test/lte-test-entities.cc Sun Jul 29 14:29:41 2012 +0200
@@ -657,13 +657,11 @@
void
EpcTestRrc::DoDataRadioBearerSetupRequest (EpcEnbS1SapUser::DataRadioBearerSetupRequestParameters request)
{
- EpcEnbS1SapProvider::DataRadioBearerSetupResponseParameters response;
- // works for a single eNB scenario with at most 1 LCID per UE
- response.rnti = (uint16_t) request.imsi;
+ EpcEnbS1SapProvider::S1BearerSetupRequestParameters response;
+ response.rnti = request.rnti;
response.lcid = 1;
- response.success = true;
response.teid = request.teid;
- m_s1SapProvider->DataRadioBearerSetupResponse (response);
+ m_s1SapProvider->S1BearerSetupRequest (response);
}