From c7b3881aabc288adaff65003d5826194afa28a8a Mon Sep 17 00:00:00 2001 From: Nicola Baldo Date: Thu, 22 Nov 2012 18:35:05 +0100 Subject: [PATCH] X2 handover working on the control plane --- src/lte/examples/lena-x2-handover.cc | 12 +++++--- src/lte/model/lte-enb-cmac-sap.h | 6 ++-- src/lte/model/lte-enb-mac.cc | 41 +++++++++++++++++++-------- src/lte/model/lte-enb-mac.h | 19 +++++++++---- src/lte/model/lte-enb-rrc.cc | 29 ++++++++++--------- src/lte/model/lte-ue-phy.cc | 42 +++++++++++++++------------- 6 files changed, 93 insertions(+), 56 deletions(-) diff --git a/src/lte/examples/lena-x2-handover.cc b/src/lte/examples/lena-x2-handover.cc index 39cc664d2..be7b4decf 100644 --- a/src/lte/examples/lena-x2-handover.cc +++ b/src/lte/examples/lena-x2-handover.cc @@ -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 positionAlloc = CreateObject (); 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(); diff --git a/src/lte/model/lte-enb-cmac-sap.h b/src/lte/model/lte-enb-cmac-sap.h index 1e0f52732..68cf4f715 100644 --- a/src/lte/model/lte-enb-cmac-sap.h +++ b/src/lte/model/lte-enb-cmac-sap.h @@ -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; }; diff --git a/src/lte/model/lte-enb-mac.cc b/src/lte/model/lte-enb-mac.cc index 232772383..db3337e81 100644 --- a/src/lte/model/lte-enb-mac.cc +++ b/src/lte/model/lte-enb-mac.cc @@ -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::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::iterator it = m_allocatedNcRaPreambleMap.find (preambleId); + std::map::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; } } diff --git a/src/lte/model/lte-enb-mac.h b/src/lte/model/lte-enb-mac.h index 5e85e2f0b..6d826521b 100644 --- a/src/lte/model/lte-enb-mac.h +++ b/src/lte/model/lte-enb-mac.h @@ -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 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 m_allocatedNcRaPreambleMap; std::map m_receivedRachPreambleCount; }; diff --git a/src/lte/model/lte-enb-rrc.cc b/src/lte/model/lte-enb-rrc.cc index c43ce5dbb..4c5cd35c1 100644 --- a/src/lte/model/lte-enb-rrc.cc +++ b/src/lte/model/lte-enb-rrc.cc @@ -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 = 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 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::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 diff --git a/src/lte/model/lte-ue-phy.cc b/src/lte/model/lte-ue-phy.cc index 91c61ac39..f410fbf67 100644 --- a/src/lte/model/lte-ue-phy.cc +++ b/src/lte/model/lte-ue-phy.cc @@ -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 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 noisePsd = LteSpectrumValueHelper::CreateNoisePowerSpectralDensity (m_dlEarfcn, m_dlBandwidth, m_noiseFigure); + m_downlinkSpectrumPhy->SetNoisePowerSpectralDensity (noisePsd); + m_downlinkSpectrumPhy->GetChannel ()->AddRx (m_downlinkSpectrumPhy); + } m_dlConfigured = true; }