diff --git a/src/lte/helper/lte-helper.cc b/src/lte/helper/lte-helper.cc index f11ade32f..9aaf261ce 100644 --- a/src/lte/helper/lte-helper.cc +++ b/src/lte/helper/lte-helper.cc @@ -328,6 +328,9 @@ LteHelper::InstallSingleEnbDevice (Ptr n) Ptr dlPhy = CreateObject (); Ptr ulPhy = CreateObject (); + dlPhy->SetChannel (m_downlinkChannel); + ulPhy->SetChannel (m_uplinkChannel); + Ptr phy = CreateObject (dlPhy, ulPhy); Ptr harq = Create (); @@ -344,9 +347,6 @@ LteHelper::InstallSingleEnbDevice (Ptr n) Ptr pInterf = Create (phy); ulPhy->AddInterferenceDataChunkProcessor (pInterf); // for interference power tracing - dlPhy->SetChannel (m_downlinkChannel); - ulPhy->SetChannel (m_uplinkChannel); - Ptr mm = n->GetObject (); NS_ASSERT_MSG (mm, "MobilityModel needs to be set on node before calling LteHelper::InstallUeDevice ()"); dlPhy->SetMobility (mm); @@ -472,6 +472,9 @@ LteHelper::InstallSingleUeDevice (Ptr n) Ptr dlPhy = CreateObject (); Ptr ulPhy = CreateObject (); + dlPhy->SetChannel (m_downlinkChannel); + ulPhy->SetChannel (m_uplinkChannel); + Ptr phy = CreateObject (dlPhy, ulPhy); Ptr harq = Create (); @@ -491,9 +494,6 @@ LteHelper::InstallSingleUeDevice (Ptr n) Ptr pData = Create (dlPhy); dlPhy->AddDataSinrChunkProcessor (pData); - dlPhy->SetChannel (m_downlinkChannel); - ulPhy->SetChannel (m_uplinkChannel); - Ptr mm = n->GetObject (); NS_ASSERT_MSG (mm, "MobilityModel needs to be set on node before calling LteHelper::InstallUeDevice ()"); dlPhy->SetMobility (mm); @@ -555,6 +555,7 @@ LteHelper::InstallSingleUeDevice (Ptr n) dlPhy->SetLtePhyRxDataEndOkCallback (MakeCallback (&LteUePhy::PhyPduReceived, phy)); dlPhy->SetLtePhyRxCtrlEndOkCallback (MakeCallback (&LteUePhy::ReceiveLteControlMessageList, phy)); dlPhy->SetLtePhyRxPssCallback (MakeCallback (&LteUePhy::ReceivePss, phy)); + dlPhy->SetLtePhyRxMibCallback (MakeCallback (&LteUePhy::ReceiveMib, phy)); dlPhy->SetLtePhyDlHarqFeedbackCallback (MakeCallback (&LteUePhy::ReceiveLteDlHarqFeedback, phy)); nas->SetForwardUpCallback (MakeCallback (&LteUeNetDevice::Receive, dev)); diff --git a/src/lte/model/lte-enb-phy.cc b/src/lte/model/lte-enb-phy.cc index 4e604170c..637571a73 100644 --- a/src/lte/model/lte-enb-phy.cc +++ b/src/lte/model/lte-enb-phy.cc @@ -509,12 +509,6 @@ LteEnbPhy::StartFrame (void) NS_LOG_INFO ("-----frame " << m_nrFrames << "-----"); m_nrSubFrames = 0; - // send MIB at beginning of every frame - m_mib.systemFrameNumber = m_nrSubFrames; - Ptr mibMsg = Create (); - mibMsg->SetMib (m_mib); - m_controlMessagesQueue.at (0).push_back (mibMsg); - StartSubFrame (); } @@ -688,8 +682,18 @@ LteEnbPhy::SendControlChannels (std::list > ctrlMsgList) { pss = true; } - m_downlinkSpectrumPhy->StartTxDlCtrlFrame (ctrlMsgList, pss); - + // send MIB at beginning of every frame + bool mib = false; + if (m_nrSubFrames == 1) + { + m_mib.systemFrameNumber = m_nrFrames; + Ptr mibMsg = Create (); + mibMsg->SetMib (m_mib); + ctrlMsgList.push_back (mibMsg); + mib = true; + } + m_downlinkSpectrumPhy->StartTxDlCtrlFrame (ctrlMsgList, pss, mib, false); + } void diff --git a/src/lte/model/lte-spectrum-phy.cc b/src/lte/model/lte-spectrum-phy.cc index 094a33c5b..04ec69fce 100644 --- a/src/lte/model/lte-spectrum-phy.cc +++ b/src/lte/model/lte-spectrum-phy.cc @@ -114,6 +114,7 @@ NS_OBJECT_ENSURE_REGISTERED (LteSpectrumPhy); LteSpectrumPhy::LteSpectrumPhy () : m_state (IDLE), + m_cellId (0), m_transmissionMode (0), m_layersNum (1) { @@ -156,6 +157,7 @@ void LteSpectrumPhy::DoDispose () m_ltePhyDlHarqFeedbackCallback = MakeNullCallback< void, DlInfoListElement_s > (); m_ltePhyUlHarqFeedbackCallback = MakeNullCallback< void, UlInfoListElement_s > (); m_ltePhyRxPssCallback = MakeNullCallback< void, uint16_t, Ptr > (); + m_ltePhyRxMibCallback = MakeNullCallback< void, uint16_t, std::list > > (); SpectrumPhy::DoDispose (); } @@ -363,6 +365,13 @@ LteSpectrumPhy::SetLtePhyRxPssCallback (LtePhyRxPssCallback c) m_ltePhyRxPssCallback = c; } +void +LteSpectrumPhy::SetLtePhyRxMibCallback (LtePhyRxMibCallback c) +{ + NS_LOG_FUNCTION (this); + m_ltePhyRxMibCallback = c; +} + void LteSpectrumPhy::SetLtePhyDlHarqFeedbackCallback (LtePhyDlHarqFeedbackCallback c) { @@ -472,13 +481,15 @@ LteSpectrumPhy::StartTxDataFrame (Ptr pb, std::list > ctrlMsgList, bool pss) +LteSpectrumPhy::StartTxDlCtrlFrame (std::list > ctrlMsgList, + bool pss, bool mib, bool sib1) { - NS_LOG_FUNCTION (this << " PSS " << (uint16_t)pss); + NS_LOG_FUNCTION (this << " PSS " << (uint16_t) pss + << " MIB " << (uint16_t) mib + << " SIB1 " << (uint16_t) sib1); NS_LOG_LOGIC (this << " state: " << m_state); - - -// m_phyTxStartTrace (pb); + + // m_phyTxStartTrace (pb); switch (m_state) { @@ -514,6 +525,8 @@ LteSpectrumPhy::StartTxDlCtrlFrame (std::list > ctrlMsgLi txParams->psd = m_txPsd; txParams->cellId = m_cellId; txParams->pss = pss; + txParams->mib = mib; + txParams->sib1 = sib1; txParams->ctrlMsgList = ctrlMsgList; m_channel->StartTx (txParams); m_endTxEvent = Simulator::Schedule (DL_CTRL_DURATION, &LteSpectrumPhy::EndTx, this); @@ -732,7 +745,7 @@ LteSpectrumPhy::StartRxCtrl (Ptr params) NS_FATAL_ERROR ("cannot RX while TX: according to FDD channel access, the physical layer for transmission cannot be used for reception"); break; case RX_DATA: - NS_FATAL_ERROR ("cannot RX data while receing control"); + NS_FATAL_ERROR ("cannot RX control while receiving data"); break; case IDLE: case RX_CTRL: @@ -757,19 +770,8 @@ LteSpectrumPhy::StartRxCtrl (Ptr params) cellId = lteUlSrsRxParams->cellId; dl = false; } - if (dl) - { - // check presence of PSS for UE measuerements - if (lteDlCtrlRxParams->pss == true) - { - SpectrumValue pssPsd = *params->psd; - if (!m_ltePhyRxPssCallback.IsNull ()) - { - m_ltePhyRxPssCallback (cellId, params->psd); - } - } - } - if (cellId == m_cellId) + + if (cellId == m_cellId) { NS_LOG_LOGIC (this << " synchronized with this signal (cellId=" << cellId << ")"); if (m_state == IDLE) @@ -797,27 +799,67 @@ LteSpectrumPhy::StartRxCtrl (Ptr params) // should occur at the same time and have the same // duration, otherwise the interference calculation // won't be correct - NS_ASSERT ((m_firstRxStart == Simulator::Now ()) + NS_ASSERT ((m_firstRxStart == Simulator::Now ()) && (m_firstRxDuration == params->duration)); } - + ChangeState (RX_CTRL); m_interferenceCtrl->StartRx (params->psd); - -// NS_LOG_LOGIC (this << " numSimultaneousRxEvents = " << m_rxPacketBurstList.size ()); - } + + // NS_LOG_LOGIC (this << " numSimultaneousRxEvents = " << m_rxPacketBurstList.size ()); + + } // end of if (m_state == IDLE) else { - NS_LOG_LOGIC (this << " not in sync with this signal (cellId=" - << cellId << ", m_cellId=" << m_cellId << ")"); + NS_LOG_LOGIC (this << " not in sync with this signal (cellId=" + << cellId << ", m_cellId=" << m_cellId << ")"); } - } + + if (dl) + { + // check the presence of PSS for UE measurements + if (lteDlCtrlRxParams->pss == true) + { + SpectrumValue pssPsd = *params->psd; + if (!m_ltePhyRxPssCallback.IsNull ()) + { + m_ltePhyRxPssCallback (cellId, params->psd); + } + } + + // check the presence of MIB + if ((lteDlCtrlRxParams->mib == true) + && !m_ltePhyRxMibCallback.IsNull () + && ((m_cellId == cellId) || (m_cellId == 0))) + { + /* + * i.e. if UE is attached, then only consider MIB which comes + * from the serving cell. Else if UE is NOT attached, then + * MIB from any cell is considered. + */ + Simulator::Schedule (params->duration, + &LteSpectrumPhy::m_ltePhyRxMibCallback, + this, cellId, + lteDlCtrlRxParams->ctrlMsgList); + /* + * The upper layer will enforce a bandwidth change upon + * receiving MIB, which will disturb the currently running RX + * and interference calculation. That's why the above callback + * is scheduled here, so that it will run after EndRxDlCtrl. + */ + } + + } // end of if (dl) + + } // end of case IDLE or RX_CTRL + break; - default: - NS_FATAL_ERROR ("unknown state"); - break; - } + default: + NS_FATAL_ERROR ("unknown state"); + break; + + } // end of switch (m_state) NS_LOG_LOGIC (this << " state: " << m_state); } diff --git a/src/lte/model/lte-spectrum-phy.h b/src/lte/model/lte-spectrum-phy.h index 9a3f475b4..14dffc385 100644 --- a/src/lte/model/lte-spectrum-phy.h +++ b/src/lte/model/lte-spectrum-phy.h @@ -127,6 +127,12 @@ typedef Callback< void > LtePhyRxCtrlEndErrorCallback; */ typedef Callback< void, uint16_t, Ptr > LtePhyRxPssCallback; +/** +* This method is used by the LteSpectrumPhy to notify the UE PHY that an +* MIB has been received +*/ +typedef Callback< void, uint16_t, std::list > > LtePhyRxMibCallback; + /** * This method is used by the LteSpectrumPhy to notify the PHY about @@ -228,12 +234,15 @@ public: * * * @param ctrlMsgList the burst of contrl messages to be transmitted - * @param pss the flag for transmitting the primary synchronization signal + * @param pss the flag for transmitting the Primary Synchronization Signal + * @param mib the flag for transmitting the Master Information Block + * @param sib1 the flag for transmitting the System Information Block Type 1 * * @return true if an error occurred and the transmission was not * started, false otherwise. */ - bool StartTxDlCtrlFrame (std::list > ctrlMsgList, bool pss); + bool StartTxDlCtrlFrame (std::list > ctrlMsgList, + bool pss, bool mib, bool sib1); /** @@ -271,7 +280,7 @@ public: * @param c the callback */ void SetLtePhyRxDataEndOkCallback (LtePhyRxDataEndOkCallback c); - + /** * set the callback for the successful end of a RX ctrl frame, as part * of the interconnections betweenthe LteSpectrumPhy and the PHY @@ -279,7 +288,7 @@ public: * @param c the callback */ void SetLtePhyRxCtrlEndOkCallback (LtePhyRxCtrlEndOkCallback c); - + /** * set the callback for the erroneous end of a RX ctrl frame, as part * of the interconnections betweenthe LteSpectrumPhy and the PHY @@ -296,6 +305,14 @@ public: */ void SetLtePhyRxPssCallback (LtePhyRxPssCallback c); + /** + * set the callback for the reception of the MIB as part + * of the interconnections between the LteSpectrumPhy and the UE PHY + * + * @param c the callback + */ + void SetLtePhyRxMibCallback (LtePhyRxMibCallback c); + /** * set the callback for the DL HARQ feedback as part of the * interconnections betweenthe LteSpectrumPhy and the PHY @@ -455,6 +472,7 @@ private: LtePhyRxCtrlEndOkCallback m_ltePhyRxCtrlEndOkCallback; LtePhyRxCtrlEndErrorCallback m_ltePhyRxCtrlEndErrorCallback; LtePhyRxPssCallback m_ltePhyRxPssCallback; + LtePhyRxMibCallback m_ltePhyRxMibCallback; Ptr m_interferenceData; Ptr m_interferenceCtrl; diff --git a/src/lte/model/lte-spectrum-signal-parameters.cc b/src/lte/model/lte-spectrum-signal-parameters.cc index 30456b4d6..0e25e6328 100644 --- a/src/lte/model/lte-spectrum-signal-parameters.cc +++ b/src/lte/model/lte-spectrum-signal-parameters.cc @@ -97,11 +97,13 @@ LteSpectrumSignalParametersDlCtrlFrame::LteSpectrumSignalParametersDlCtrlFrame ( } LteSpectrumSignalParametersDlCtrlFrame::LteSpectrumSignalParametersDlCtrlFrame (const LteSpectrumSignalParametersDlCtrlFrame& p) -: SpectrumSignalParameters (p) + : SpectrumSignalParameters (p) { NS_LOG_FUNCTION (this << &p); cellId = p.cellId; pss = p.pss; + mib = p.mib; + sib1 = p.sib1; ctrlMsgList = p.ctrlMsgList; } @@ -115,7 +117,7 @@ LteSpectrumSignalParametersDlCtrlFrame::Copy () // return Copy (this); // but it causes a double creation of the object, hence it is less efficient. // The solution below is copied from the implementation of Copy<> (Ptr<>) in ptr.h - Ptr lssp (new LteSpectrumSignalParametersDlCtrlFrame (*this), false); + Ptr lssp (new LteSpectrumSignalParametersDlCtrlFrame (*this), false); return lssp; } diff --git a/src/lte/model/lte-spectrum-signal-parameters.h b/src/lte/model/lte-spectrum-signal-parameters.h index 72486970b..c0c7fa66f 100644 --- a/src/lte/model/lte-spectrum-signal-parameters.h +++ b/src/lte/model/lte-spectrum-signal-parameters.h @@ -100,25 +100,27 @@ struct LteSpectrumSignalParametersDataFrame : public SpectrumSignalParameters */ struct LteSpectrumSignalParametersDlCtrlFrame : public SpectrumSignalParameters { - + // inherited from SpectrumSignalParameters virtual Ptr Copy (); - + /** * default constructor */ LteSpectrumSignalParametersDlCtrlFrame (); - + /** * copy constructor */ LteSpectrumSignalParametersDlCtrlFrame (const LteSpectrumSignalParametersDlCtrlFrame& p); - std::list > ctrlMsgList; - - uint16_t cellId; - bool pss; // primary synchronization signal + std::list > ctrlMsgList; ///< control message list + + uint16_t cellId; ///< cell ID of the eNodeB where the signal originates from + bool pss; ///< true when this signal contains Primary Synchronization Signal + bool mib; ///< true when the control message list contains Master Information Block + bool sib1; ///< true when the control message list contains System Information Block Type 1 }; diff --git a/src/lte/model/lte-ue-phy.cc b/src/lte/model/lte-ue-phy.cc index 41625b477..2b83ed96b 100644 --- a/src/lte/model/lte-ue-phy.cc +++ b/src/lte/model/lte-ue-phy.cc @@ -825,11 +825,9 @@ LteUePhy::ReceiveLteControlMessageList (std::list > msgLi } } } - else if (msg->GetMessageType () == LteControlMessage::MIB) + else if (msg->GetMessageType () == LteControlMessage::MIB) { - NS_LOG_INFO ("received MIB"); - Ptr msg2 = DynamicCast (msg); - m_ueCphySapUser->RecvMasterInformationBlock (msg2->GetMib ()); + // ignore } else { @@ -871,6 +869,22 @@ LteUePhy::ReceivePss (uint16_t cellId, Ptr p) } +void +LteUePhy::ReceiveMib (uint16_t cellId, std::list > ctrlMsgList) +{ + std::list >::const_iterator it; + for (it = ctrlMsgList.begin (); it != ctrlMsgList.end (); ++it) + { + if ((*it)->GetMessageType () == LteControlMessage::MIB) + { + NS_LOG_INFO ("received MIB from cellId=" << cellId); + Ptr msg = DynamicCast (*it); + m_ueCphySapUser->RecvMasterInformationBlock (msg->GetMib ()); + } + } +} + + void LteUePhy::QueueSubChannelsForTransmission (std::vector rbMap) { @@ -884,7 +898,7 @@ LteUePhy::SubframeIndication (uint32_t frameNo, uint32_t subframeNo) NS_LOG_FUNCTION (this << frameNo << subframeNo); NS_ASSERT_MSG (frameNo > 0, "the SRS index check code assumes that frameNo starts at 1"); - + // refresh internal variables m_rsReceivedPowerUpdated = false; m_rsInterferencePowerUpdated = false; @@ -1005,6 +1019,20 @@ LteUePhy::DoReset () m_sendSrsEvent.Cancel (); m_downlinkSpectrumPhy->Reset (); m_uplinkSpectrumPhy->Reset (); + + // configure DL for receiving the BCH with the minimum bandwidth + m_dlEarfcn = 100; + m_dlBandwidth = 6; + m_noiseFigure = 9.0; + // TODO any better way to define those default values? + Ptr noisePsd = + LteSpectrumValueHelper::CreateNoisePowerSpectralDensity (m_dlEarfcn, + m_dlBandwidth, + m_noiseFigure); + m_downlinkSpectrumPhy->SetNoisePowerSpectralDensity (noisePsd); + NS_ASSERT (m_downlinkSpectrumPhy->GetChannel () != 0); + m_downlinkSpectrumPhy->GetChannel ()->AddRx (m_downlinkSpectrumPhy); + } void @@ -1016,11 +1044,11 @@ LteUePhy::DoSyncronizeWithEnb (uint16_t cellId, uint16_t dlEarfcn) m_downlinkSpectrumPhy->SetCellId (cellId); m_uplinkSpectrumPhy->SetCellId (cellId); - // configure DL for receing the BCH with the minimum bandwith + // configure DL for receiving the BCH with the minimum bandwidth m_dlBandwidth = 6; Ptr noisePsd = LteSpectrumValueHelper::CreateNoisePowerSpectralDensity (m_dlEarfcn, m_dlBandwidth, m_noiseFigure); m_downlinkSpectrumPhy->SetNoisePowerSpectralDensity (noisePsd); - m_downlinkSpectrumPhy->GetChannel ()->AddRx (m_downlinkSpectrumPhy); + m_downlinkSpectrumPhy->GetChannel ()->AddRx (m_downlinkSpectrumPhy); m_dlConfigured = false; m_ulConfigured = false; diff --git a/src/lte/model/lte-ue-phy.h b/src/lte/model/lte-ue-phy.h index 30cf2cc4e..f869762dd 100644 --- a/src/lte/model/lte-ue-phy.h +++ b/src/lte/model/lte-ue-phy.h @@ -179,8 +179,7 @@ public: // callbacks for LteSpectrumPhy virtual void ReceiveLteControlMessageList (std::list >); virtual void ReceivePss (uint16_t cellId, Ptr p); - - + virtual void ReceiveMib (uint16_t cellId, std::list > ctrlMsgList); diff --git a/src/lte/model/lte-ue-rrc.cc b/src/lte/model/lte-ue-rrc.cc index 45305e028..f106d8721 100644 --- a/src/lte/model/lte-ue-rrc.cc +++ b/src/lte/model/lte-ue-rrc.cc @@ -187,6 +187,9 @@ LteUeRrc::GetTypeId (void) UintegerValue (0), // unused, read-only attribute MakeUintegerAccessor (&LteUeRrc::GetRnti), MakeUintegerChecker ()) + .AddTraceSource ("MasterInformationBlockReceived", + "trace fired upon reception of MIB (typically every 10 ms)", + MakeTraceSourceAccessor (&LteUeRrc::m_mibReceivedTrace)) .AddTraceSource ("StateTransition", "trace fired upon every UE RRC state transition", MakeTraceSourceAccessor (&LteUeRrc::m_stateTransitionTrace)) @@ -205,7 +208,7 @@ LteUeRrc::GetTypeId (void) .AddTraceSource ("HandoverEndOk", "trace fired upon successful termination of a handover procedure", MakeTraceSourceAccessor (&LteUeRrc::m_handoverEndOkTrace)) - ; + ; return tid; } @@ -355,7 +358,7 @@ LteUeRrc::DoInitialize (void) rlc->SetRnti (m_rnti); rlc->SetLcId (lcid); - m_srb0 = CreateObject (); + m_srb0 = CreateObject (); m_srb0->m_rlc = rlc; m_srb0->m_srbIdentity = 0; LteUeRrcSapUser::SetupParameters ueParams; @@ -535,9 +538,11 @@ void LteUeRrc::DoRecvMasterInformationBlock (LteRrcSap::MasterInformationBlock msg) { NS_LOG_FUNCTION (this); + // TODO may speed up a bit if only execute the following when bandwidth changes? m_dlBandwidth = msg.dlBandwidth; m_cphySapProvider->SetDlBandwidth (msg.dlBandwidth); m_receivedMib = true; + m_mibReceivedTrace (m_imsi, m_cellId, m_rnti); if (m_state == IDLE_WAIT_SYSTEM_INFO && m_receivedMib && m_receivedSib2) { SwitchToState (IDLE_CAMPED_NORMALLY); diff --git a/src/lte/model/lte-ue-rrc.h b/src/lte/model/lte-ue-rrc.h index d9a62af6f..87793dc09 100644 --- a/src/lte/model/lte-ue-rrc.h +++ b/src/lte/model/lte-ue-rrc.h @@ -332,6 +332,8 @@ private: uint16_t m_dlEarfcn; /**< downlink carrier frequency */ uint16_t m_ulEarfcn; /**< uplink carrier frequency */ + // imsi cellid rnti + TracedCallback m_mibReceivedTrace; // imsi cellid rnti TracedCallback m_stateTransitionTrace; // imsi cellid rnti diff --git a/src/lte/test/lte-test-cell-selection.cc b/src/lte/test/lte-test-cell-selection.cc new file mode 100644 index 000000000..179e14f72 --- /dev/null +++ b/src/lte/test/lte-test-cell-selection.cc @@ -0,0 +1,250 @@ +/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2013 University of Jyväskylä + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Budiarto Herman + * + */ + +#include "lte-test-cell-selection.h" + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +NS_LOG_COMPONENT_DEFINE ("LteCellSelectionTest"); + +namespace ns3 { + + +/* + * Test Suite + */ + + +LteCellSelectionTestSuite::LteCellSelectionTestSuite () + : TestSuite ("lte-cell-selection", SYSTEM) +{ + LogComponentEnableAll (LOG_PREFIX_ALL); + LogComponentEnable ("LteCellSelectionTest", LOG_FUNCTION); + // LogComponentEnable ("LteUePhy", LOG_INFO); + // LogComponentEnable ("LteEnbPhy", LOG_FUNCTION); + // LogComponentEnable ("LteSpectrumPhy", LOG_FUNCTION); + + std::vector x; + + x.clear (); + x.push_back (LteCellSelectionTestCase::UeSetup_t (Vector (0, 0, 0), 0, 0, 1)); + AddTestCase (new LteCellSelectionTestCase ("First test with EPC", true, x), + TestCase::QUICK); + + x.clear (); + x.push_back (LteCellSelectionTestCase::UeSetup_t (Vector (0, 0, 0), 0, 0, 1)); + AddTestCase (new LteCellSelectionTestCase ("First test without EPC", false, x), + TestCase::QUICK); + +} // end of LteCellSelectionTestSuite::LteCellSelectionTestSuite () + + +static LteCellSelectionTestSuite g_lteCellSelectionTestSuite; + + + +/* + * Test Case + */ + + +LteCellSelectionTestCase::UeSetup_t::UeSetup_t (Vector position, + uint32_t plmnIdentity, + uint32_t csgIdentity, + uint16_t expectedCellId) + : position (position), plmnIdentity (plmnIdentity), csgIdentity (csgIdentity), + expectedCellId (expectedCellId) +{ +} + + +LteCellSelectionTestCase::LteCellSelectionTestCase ( + std::string name, bool isEpcMode, std::vector ueSetupList) + : TestCase (name), m_isEpcMode (isEpcMode), m_ueSetupList (ueSetupList) +{ + NS_LOG_FUNCTION (this << GetName ()); +} + + +LteCellSelectionTestCase::~LteCellSelectionTestCase () +{ + NS_LOG_FUNCTION (this << GetName ()); +} + + +void +LteCellSelectionTestCase::DoRun () +{ + NS_LOG_FUNCTION (this << GetName ()); + + Ptr lteHelper = CreateObject (); + lteHelper->SetAttribute ("PathlossModel", + StringValue ("ns3::FriisSpectrumPropagationLossModel")); + lteHelper->SetAttribute ("UseIdealRrc", BooleanValue (true)); + + /* + * The topology is the following: + * + * <--x eNodeB 2 - Both cells are separated by 10 m + * | - Parabolic antenna model is used + * | 10 m - eNodeB 1 at (0, 10, 0) is facing east + * | - eNodeB 2 at (0, 20, 0) is facing west + * eNodeB 1 x--> - UEs are placed according to input + * - UEs do not move during simulation + */ + + // Create Nodes: eNodeB + NodeContainer enbNodes; + enbNodes.Create (2); + + Ptr positionAlloc = CreateObject (); + positionAlloc->Add (Vector (0.0, 10.0, 0.0)); + positionAlloc->Add (Vector (0.0, 20.0, 0.0)); + + MobilityHelper mobility; + mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel"); + mobility.SetPositionAllocator (positionAlloc); + mobility.Install (enbNodes); + + // Create Nodes: UE + NodeContainer ueNodes; + uint16_t nUe = m_ueSetupList.size (); + ueNodes.Create (nUe); + + std::vector::const_iterator it; + for (it = m_ueSetupList.begin (); it != m_ueSetupList.end (); it++) + { + positionAlloc->Add (it->position); + } + + mobility.Install (ueNodes); + + // Create Devices and install them in the Nodes (eNB and UE) + NetDeviceContainer enbDevs; + NetDeviceContainer ueDevs; + enbDevs = lteHelper->InstallEnbDevice (enbNodes); + ueDevs = lteHelper->InstallUeDevice (ueNodes); + + // Set the PLMN and CSG ID + for (it = m_ueSetupList.begin (); it != m_ueSetupList.end (); it++) + { + // TODO + } + + if (m_isEpcMode) + { + Ptr epcHelper = CreateObject (); + lteHelper->SetEpcHelper (epcHelper); + + // Create P-GW node + Ptr pgw = epcHelper->GetPgwNode (); + + // Create a single RemoteHost + NodeContainer remoteHostContainer; + remoteHostContainer.Create (1); + Ptr remoteHost = remoteHostContainer.Get (0); + InternetStackHelper internet; + internet.Install (remoteHostContainer); + + // Create the Internet + PointToPointHelper p2ph; + p2ph.SetDeviceAttribute ("DataRate", DataRateValue (DataRate ("100Gb/s"))); + p2ph.SetDeviceAttribute ("Mtu", UintegerValue (1500)); + p2ph.SetChannelAttribute ("Delay", TimeValue (Seconds (0.010))); + NetDeviceContainer internetDevices = p2ph.Install (pgw, remoteHost); + Ipv4AddressHelper ipv4h; + ipv4h.SetBase ("1.0.0.0", "255.0.0.0"); + Ipv4InterfaceContainer internetIpIfaces = ipv4h.Assign (internetDevices); + + // Routing of the Internet Host (towards the LTE network) + Ipv4StaticRoutingHelper ipv4RoutingHelper; + Ptr remoteHostStaticRouting = ipv4RoutingHelper.GetStaticRouting (remoteHost->GetObject ()); + remoteHostStaticRouting->AddNetworkRouteTo (Ipv4Address ("7.0.0.0"), Ipv4Mask ("255.0.0.0"), 1); + + // Install the IP stack on the UEs + internet.Install (ueNodes); + Ipv4InterfaceContainer ueIpIfaces; + ueIpIfaces = epcHelper->AssignUeIpv4Address (NetDeviceContainer (ueDevs)); + + // Assign IP address to UEs + for (uint32_t u = 0; u < ueNodes.GetN (); ++u) + { + Ptr ueNode = ueNodes.Get (u); + // Set the default gateway for the UE + Ptr ueStaticRouting = ipv4RoutingHelper.GetStaticRouting (ueNode->GetObject ()); + ueStaticRouting->SetDefaultRoute (epcHelper->GetUeDefaultGatewayAddress (), 1); + } + + } // end of if (m_isEpcMode) + else + { + // // TODO remove this + // lteHelper->Attach (ueDevs, enbDevs.Get (0)); + // + // // Activate an EPS bearer + // enum EpsBearer::Qci q = EpsBearer::GBR_CONV_VOICE; + // EpsBearer bearer (q); + // lteHelper->ActivateDataRadioBearer (ueDevs, bearer); + } + + // Connect to trace sources in UEs + Config::Connect ("/NodeList/*/DeviceList/*/LteUeRrc/MasterInformationBlockReceived", + MakeCallback (&LteCellSelectionTestCase::MasterInformationBlockReceivedCallback, + this)); + + // Run simulation + Simulator::Stop (MilliSeconds (20)); + Simulator::Run (); + Simulator::Destroy (); + + // Tests + + // TODO + +} // end of void LteCellSelectionTestCase::DoRun () + + +void +LteCellSelectionTestCase::MasterInformationBlockReceivedCallback ( + std::string context, uint64_t imsi, uint16_t cellId, uint16_t rnti) +{ + NS_LOG_FUNCTION (this << context << imsi << cellId << rnti); +} + + +} // end of namespace ns3 diff --git a/src/lte/test/lte-test-cell-selection.h b/src/lte/test/lte-test-cell-selection.h new file mode 100644 index 000000000..f975e95e8 --- /dev/null +++ b/src/lte/test/lte-test-cell-selection.h @@ -0,0 +1,104 @@ +/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2013 University of Jyväskylä + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Budiarto Herman + * + */ + +#ifndef LTE_TEST_CELL_SELECTION_H +#define LTE_TEST_CELL_SELECTION_H + +#include +#include +#include +#include + +namespace ns3 { + + +/** + * \brief Test suite for executing the cell selection test cases in without-EPC + * and with-EPC scenarios. + * + * \sa ns3::LteCellSelectionTestCase + */ +class LteCellSelectionTestSuite : public TestSuite +{ +public: + LteCellSelectionTestSuite (); +}; + + +/** + * \brief Testing the initial cell selection procedure by UE at IDLE state in + * the beginning of simulation. + */ +class LteCellSelectionTestCase : public TestCase +{ +public: + /** + * \brief A set of input parameters for setting up a UE in the simulation. + */ + struct UeSetup_t + { + Vector position; ///< The position where the UE will be spawned in the simulation. + uint32_t plmnIdentity; ///< Public Land Mobile Network identity of the UE. + uint32_t csgIdentity; ///< Closed Subscriber Group identity of the UE. + uint16_t expectedCellId; ///< The cell ID that the UE is expected to attach to (0 means that the UE should not attach to any cell). + UeSetup_t (Vector position, uint32_t plmnIdentity, uint32_t csgIdentity, + uint16_t expectedCellId); + }; + + /** + * \brief Creates an instance of the initial cell selection test case. + * \param name name of this test + * \param isEpcMode set to true for setting up simulation with EPC enabled + * \param ueSetupList an array of UE setup parameters + */ + LteCellSelectionTestCase (std::string name, bool isEpcMode, + std::vector ueSetupList); + + virtual ~LteCellSelectionTestCase (); + +private: + /** + * \brief Setup the simulation according to the configuration set by the + * class constructor, run it, and verify the result. + */ + virtual void DoRun (); + + void MasterInformationBlockReceivedCallback (std::string context, + uint64_t imsi, uint16_t cellId, + uint16_t rnti); + + /** + * \brief If true, then the simulation should be set up with EPC enabled. + */ + bool m_isEpcMode; + + /** + * \brief The list of UE setups to be used during the test execution. + */ + std::vector m_ueSetupList; + +}; // end of class LteCellSelectionTestCase + + +} // end of namespace ns3 + + +#endif /* LTE_TEST_CELL_SELECTION_H */ diff --git a/src/lte/wscript b/src/lte/wscript index d5a3bc729..a52ed4526 100644 --- a/src/lte/wscript +++ b/src/lte/wscript @@ -142,6 +142,7 @@ def build(bld): 'test/test-lte-x2-handover-measures.cc', 'test/test-asn1-encoding.cc', 'test/lte-test-ue-measurements.cc', + 'test/lte-test-cell-selection.cc', 'test/test-lte-handover-delay.cc', ]