X2 handover working on the control plane

This commit is contained in:
Nicola Baldo
2012-11-22 18:35:05 +01:00
parent 6baa8583c2
commit c7b3881aab
6 changed files with 93 additions and 56 deletions

View File

@@ -39,6 +39,8 @@ NS_LOG_COMPONENT_DEFINE ("EpcX2HandoverExample");
int
main (int argc, char *argv[])
{
Config::SetDefault ("ns3::LteSpectrumPhy::CtrlErrorModelEnabled", BooleanValue (false));
Config::SetDefault ("ns3::LteSpectrumPhy::DataErrorModelEnabled", BooleanValue (false));
// LogLevel logLevel = (LogLevel)(LOG_PREFIX_FUNC | LOG_PREFIX_TIME | LOG_LEVEL_ALL);
// LogComponentEnable ("LteHelper", logLevel);
@@ -54,8 +56,8 @@ main (int argc, char *argv[])
uint16_t numberOfUes = 1;
uint16_t numberOfEnbs = 2;
double simTime = 2.0;
double distance = 60.0;
double simTime = 0.300;
double distance = 100.0;
// Command line arguments
CommandLine cmd;
@@ -104,7 +106,7 @@ main (int argc, char *argv[])
Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator> ();
for (uint16_t i = 0; i < numberOfEnbs; i++)
{
positionAlloc->Add (Vector(distance * i, 0, 0));
positionAlloc->Add (Vector(distance * 2*i - distance, 0, 0));
}
MobilityHelper mobility;
mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
@@ -145,12 +147,14 @@ main (int argc, char *argv[])
lteHelper->AddX2Interface (enbNodes);
// X2-based Handover
lteHelper->HandoverRequest (Seconds (1.0), ueLteDevs.Get (0), enbLteDevs.Get (0), enbLteDevs.Get (1));
lteHelper->HandoverRequest (Seconds (0.100), ueLteDevs.Get (0), enbLteDevs.Get (0), enbLteDevs.Get (1));
// Uncomment to enable PCAP tracing
//p2ph.EnablePcapAll("lena-x2-handover");
lteHelper->EnableMacTraces ();
Simulator::Stop(Seconds(simTime));
Simulator::Run();

View File

@@ -157,9 +157,11 @@ public:
/**
* Allocate a random access preamble for non-contention based random access (e.g., for handover).
*
* \return the newly allocated random access preamble (0 <
* \param rnti the RNTI of the UE who will perform non-contention based random access
*
* \return the newly allocated random access preamble
*/
virtual AllocateNcRaPreambleReturnValue AllocateNcRaPreamble () = 0;
virtual AllocateNcRaPreambleReturnValue AllocateNcRaPreamble (uint16_t rnti) = 0;
};

View File

@@ -66,7 +66,7 @@ public:
virtual void ReleaseLc (uint16_t rnti, uint8_t lcid);
virtual void UeUpdateConfigurationReq (UeConfig params);
virtual RachConfig GetRachConfig ();
virtual AllocateNcRaPreambleReturnValue AllocateNcRaPreamble ();
virtual AllocateNcRaPreambleReturnValue AllocateNcRaPreamble (uint16_t rnti);
private:
@@ -128,9 +128,9 @@ EnbMacMemberLteEnbCmacSapProvider::GetRachConfig ()
}
LteEnbCmacSapProvider::AllocateNcRaPreambleReturnValue
EnbMacMemberLteEnbCmacSapProvider::AllocateNcRaPreamble ()
EnbMacMemberLteEnbCmacSapProvider::AllocateNcRaPreamble (uint16_t rnti)
{
return m_mac->DoAllocateNcRaPreamble ();
return m_mac->DoAllocateNcRaPreamble (rnti);
}
@@ -487,17 +487,30 @@ LteEnbMac::DoSubframeIndication (uint32_t frameNo, uint32_t subframeNo)
it != m_receivedRachPreambleCount.end ();
++it)
{
NS_LOG_LOGIC ("preambleId " << (uint32_t) it->first << ": " << it->second << " received");
NS_LOG_INFO ("RA-RNTI " << raRnti << ", preambleId " << (uint32_t) it->first << ": " << it->second << " received");
NS_ASSERT (it->second != 0);
if (it->second > 1)
{
NS_LOG_INFO ("preambleId " << (uint32_t) it->first << ": collision");
// we assume that no preamble is successfully received, hence no RAR is sent
// in case of collision we assume that no preamble is
// successfully received, hence no RAR is sent
}
else
{
uint16_t rnti = m_cmacSapUser->AllocateTemporaryCellRnti ();
NS_LOG_INFO ("preambleId " << (uint32_t) it->first << ": allocated T-C-RNTI " << (uint32_t) rnti << ", sending RAR");
uint16_t rnti;
std::map<uint8_t, NcRaPreambleInfo>::iterator jt = m_allocatedNcRaPreambleMap.find (it->first);
if (jt != m_allocatedNcRaPreambleMap.end ())
{
rnti = jt->second.rnti;
NS_LOG_INFO ("preambleId previously allocated for NC based RA, RNTI =" << (uint32_t) rnti << ", sending RAR");
}
else
{
rnti = m_cmacSapUser->AllocateTemporaryCellRnti ();
NS_LOG_INFO ("preambleId " << (uint32_t) it->first << ": allocated T-C-RNTI " << (uint32_t) rnti << ", sending RAR");
}
RachListElement_s rachLe;
rachLe.m_rnti = rnti;
rachLe.m_estimatedSize = 144; // to be confirmed
@@ -841,20 +854,24 @@ LteEnbMac::DoGetRachConfig ()
}
LteEnbCmacSapProvider::AllocateNcRaPreambleReturnValue
LteEnbMac::DoAllocateNcRaPreamble ()
LteEnbMac::DoAllocateNcRaPreamble (uint16_t rnti)
{
bool found = false;
uint8_t preambleId;
for (preambleId = m_numberOfRaPreambles; preambleId < 64; ++preambleId)
{
std::map<uint8_t, Time>::iterator it = m_allocatedNcRaPreambleMap.find (preambleId);
std::map<uint8_t, NcRaPreambleInfo>::iterator it = m_allocatedNcRaPreambleMap.find (preambleId);
if ((it == m_allocatedNcRaPreambleMap.end ())
|| (it->second < Simulator::Now ()))
|| (it->second.expiryTime < Simulator::Now ()))
{
found = true;
NcRaPreambleInfo preambleInfo;
uint32_t expiryIntervalMs = (uint32_t) m_preambleTransMax * ((uint32_t) m_raResponseWindowSize + 5);
Time expiryTime = Simulator::Now () + MilliSeconds (expiryIntervalMs);
m_allocatedNcRaPreambleMap[preambleId] = expiryTime; // create if not exist, update otherwise
preambleInfo.expiryTime = Simulator::Now () + MilliSeconds (expiryIntervalMs);
preambleInfo.rnti = rnti;
NS_LOG_INFO ("allocated preamble for NC based RA: preamble " << preambleId << ", RNTI " << preambleInfo.rnti << ", exiryTime " << preambleInfo.expiryTime);
m_allocatedNcRaPreambleMap[preambleId] = preambleInfo; // create if not exist, update otherwise
break;
}
}

View File

@@ -150,7 +150,7 @@ private:
void DoReleaseLc (uint16_t rnti, uint8_t lcid);
void DoUeUpdateConfigurationReq (LteEnbCmacSapProvider::UeConfig params);
LteEnbCmacSapProvider::RachConfig DoGetRachConfig ();
LteEnbCmacSapProvider::AllocateNcRaPreambleReturnValue DoAllocateNcRaPreamble ();
LteEnbCmacSapProvider::AllocateNcRaPreambleReturnValue DoAllocateNcRaPreamble (uint16_t rnti);
// forwarded from LteMacSapProvider
void DoTransmitPdu (LteMacSapProvider::TransmitPduParameters);
@@ -238,12 +238,21 @@ private:
uint8_t m_raResponseWindowSize;
/**
* map storing as key the random acccess preamble IDs allocated for
* non-contention based access, and as value the expiration time of
* this allocation (so that stale preambles can be reused).
* info associated with a preamble allocated for non-contention based RA
*
*/
std::map<uint8_t, Time> m_allocatedNcRaPreambleMap;
struct NcRaPreambleInfo
{
uint16_t rnti; ///< rnti previously allocated for this non-contention based RA procedure
Time expiryTime; ///< value the expiration time of this allocation (so that stale preambles can be reused)
};
/**
* map storing as key the random acccess preamble IDs allocated for
* non-contention based access, and as value the associated info
*
*/
std::map<uint8_t, NcRaPreambleInfo> m_allocatedNcRaPreambleMap;
std::map<uint8_t, uint32_t> m_receivedRachPreambleCount;
};

View File

@@ -519,8 +519,10 @@ UeManager::RecvRrcConnectionReconfigurationCompleted (LteRrcSap::RrcConnectionRe
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));
@@ -1126,6 +1128,15 @@ LteEnbRrc::DoRecvHandoverRequest (EpcX2SapUser::HandoverRequestParams params)
NS_ASSERT (params.targetCellId == m_cellId);
uint16_t rnti = AddUe (UeManager::HANDOVER_JOINING);
LteEnbCmacSapProvider::AllocateNcRaPreambleReturnValue anrcrv = m_cmacSapProvider->AllocateNcRaPreamble (rnti);
if (anrcrv.valid == false)
{
NS_LOG_INFO (this << "failed to allocate a preamble for non-contention based RA => cannot accept HO");
RemoveUe (rnti);
NS_FATAL_ERROR ("should trigger HO Preparation Failure, but it is not implemented");
return;
}
Ptr<UeManager> ueManager = GetUeManager (rnti);
ueManager->SetSource (params.sourceCellId, params.oldEnbUeX2apId);
@@ -1139,23 +1150,16 @@ LteEnbRrc::DoRecvHandoverRequest (EpcX2SapUser::HandoverRequestParams params)
LteRrcSap::RrcConnectionReconfiguration handoverCommand = ueManager->GetRrcConnectionReconfigurationForHandover ();
handoverCommand.haveMobilityControlInfo = true;
handoverCommand.mobilityControlInfo.targetPhysCellId = m_cellId;
handoverCommand.mobilityControlInfo.haveCarrierFreq = true;
handoverCommand.mobilityControlInfo.carrierFreq.dlCarrierFreq = m_dlEarfcn;
handoverCommand.mobilityControlInfo.carrierFreq.ulCarrierFreq = m_ulEarfcn;
handoverCommand.mobilityControlInfo.haveCarrierBandwidth = true;
handoverCommand.mobilityControlInfo.carrierBandwidth.dlBandwidth = m_dlBandwidth;
handoverCommand.mobilityControlInfo.carrierBandwidth.ulBandwidth = m_ulBandwidth;
handoverCommand.mobilityControlInfo.newUeIdentity = rnti;
LteEnbCmacSapProvider::AllocateNcRaPreambleReturnValue anrcrv = m_cmacSapProvider->AllocateNcRaPreamble ();
if (anrcrv.valid == true)
{
handoverCommand.mobilityControlInfo.haveRachConfigDedicated = true;
handoverCommand.mobilityControlInfo.rachConfigDedicated.raPreambleIndex = anrcrv.raPreambleId;
handoverCommand.mobilityControlInfo.rachConfigDedicated.raPrachMaskIndex = anrcrv.raPrachMaskIndex;
}
else
{
handoverCommand.mobilityControlInfo.haveRachConfigDedicated = false;
}
handoverCommand.mobilityControlInfo.haveRachConfigDedicated = true;
handoverCommand.mobilityControlInfo.rachConfigDedicated.raPreambleIndex = anrcrv.raPreambleId;
handoverCommand.mobilityControlInfo.rachConfigDedicated.raPrachMaskIndex = anrcrv.raPrachMaskIndex;
Ptr<Packet> encodedHandoverCommand = m_rrcSapUser->EncodeHandoverCommand (handoverCommand);
NS_LOG_LOGIC ("Send X2 message: HANDOVER REQUEST ACK");
@@ -1410,11 +1414,10 @@ void
LteEnbRrc::RemoveSrsConfigurationIndex (uint16_t srcCi)
{
NS_LOG_FUNCTION (this << srcCi);
NS_FATAL_ERROR ("I though this method was unused so far...");
std::set<uint16_t>::iterator it = m_ueSrsConfigurationIndexSet.find (srcCi);
NS_ASSERT_MSG (it != m_ueSrsConfigurationIndexSet.end (), "request to remove unkwown SRS CI " << srcCi);
m_ueSrsConfigurationIndexSet.erase (it);
NS_ASSERT (m_srsCurrentPeriodicityId > 1);
NS_ASSERT (m_srsCurrentPeriodicityId >= 1 && m_srsCurrentPeriodicityId <= SRS_ENTRIES);
if (m_ueSrsConfigurationIndexSet.size () < g_srsPeriodicity[m_srsCurrentPeriodicityId - 1])
{
// reduce the periodicity

View File

@@ -755,28 +755,30 @@ LteUePhy::DoSyncronizeWithEnb (uint16_t cellId, uint16_t dlEarfcn)
void
LteUePhy::DoSetDlBandwidth (uint8_t dlBandwidth)
{
m_dlBandwidth = dlBandwidth;
int Type0AllocationRbg[4] = {
10, // RGB size 1
26, // RGB size 2
63, // RGB size 3
110 // RGB size 4
}; // see table 7.1.6.1-1 of 36.213
for (int i = 0; i < 4; i++)
NS_LOG_FUNCTION (this << (uint32_t) dlBandwidth);
if (m_dlBandwidth != dlBandwidth)
{
if (dlBandwidth < Type0AllocationRbg[i])
{
m_rbgSize = i + 1;
break;
}
}
Ptr<SpectrumValue> noisePsd = LteSpectrumValueHelper::CreateNoisePowerSpectralDensity (m_dlEarfcn, m_dlBandwidth, m_noiseFigure);
m_downlinkSpectrumPhy->SetNoisePowerSpectralDensity (noisePsd);
m_downlinkSpectrumPhy->GetChannel ()->AddRx (m_downlinkSpectrumPhy);
m_dlBandwidth = dlBandwidth;
int Type0AllocationRbg[4] = {
10, // RGB size 1
26, // RGB size 2
63, // RGB size 3
110 // RGB size 4
}; // see table 7.1.6.1-1 of 36.213
for (int i = 0; i < 4; i++)
{
if (dlBandwidth < Type0AllocationRbg[i])
{
m_rbgSize = i + 1;
break;
}
}
Ptr<SpectrumValue> noisePsd = LteSpectrumValueHelper::CreateNoisePowerSpectralDensity (m_dlEarfcn, m_dlBandwidth, m_noiseFigure);
m_downlinkSpectrumPhy->SetNoisePowerSpectralDensity (noisePsd);
m_downlinkSpectrumPhy->GetChannel ()->AddRx (m_downlinkSpectrumPhy);
}
m_dlConfigured = true;
}