diff --git a/src/lte/helper/lte-helper.cc b/src/lte/helper/lte-helper.cc index f11ade32f..2c48d8cfa 100644 --- a/src/lte/helper/lte-helper.cc +++ b/src/lte/helper/lte-helper.cc @@ -569,6 +569,30 @@ LteHelper::InstallSingleUeDevice (Ptr n) } +void +LteHelper::Attach (NetDeviceContainer ueDevices) +{ + NS_LOG_FUNCTION (this); + for (NetDeviceContainer::Iterator i = ueDevices.Begin (); i != ueDevices.End (); ++i) + { + Attach (*i); + } +} + +void +LteHelper::Attach (Ptr ueDevice) +{ + NS_LOG_FUNCTION (this); + + Ptr ueLteDevice = ueDevice->GetObject (); + if (ueLteDevice == 0) + { + NS_FATAL_ERROR ("The passed NetDevice must be an LteUeNetDevice"); + } + Ptr uePhy = ueLteDevice->GetPhy (); + uePhy->CellSearch (); +} + void LteHelper::Attach (NetDeviceContainer ueDevices, Ptr enbDevice) { @@ -596,7 +620,7 @@ LteHelper::Attach (Ptr ueDevice, Ptr enbDevice) // activate default EPS bearer m_epcHelper->ActivateEpsBearer (ueDevice, ueLteDevice->GetImsi (), EpcTft::Default (), EpsBearer (EpsBearer::NGBR_VIDEO_TCP_DEFAULT)); } - + // tricks needed for the simplified LTE-only simulations if (m_epcHelper == 0) { @@ -636,6 +660,43 @@ LteHelper::AttachToClosestEnb (Ptr ueDevice, NetDeviceContainer enbDe Attach (ueDevice, closestEnbDevice); } +void +LteHelper::Connect (NetDeviceContainer ueDevices) +{ + NS_LOG_FUNCTION (this); + for (NetDeviceContainer::Iterator i = ueDevices.Begin (); i != ueDevices.End (); ++i) + { + Connect (*i); + } +} + +void +LteHelper::Connect (Ptr ueDevice) +{ + NS_LOG_FUNCTION (this); + + Ptr ueLteDevice = ueDevice->GetObject (); + if (ueLteDevice == 0) + { + NS_FATAL_ERROR ("The passed NetDevice must be an LteUeNetDevice"); + } + + Ptr ueNas = ueLteDevice->GetNas (); + NS_ASSERT (ueNas != 0); + ueNas->Connect (); + + if (m_epcHelper == 0) + { + // TODO activate bearer for without-EPC simulation + } + else + { + // activate default EPS bearer + m_epcHelper->ActivateEpsBearer (ueDevice, ueLteDevice->GetImsi (), EpcTft::Default (), + EpsBearer (EpsBearer::NGBR_VIDEO_TCP_DEFAULT)); + } +} + void LteHelper::ActivateDedicatedEpsBearer (NetDeviceContainer ueDevices, EpsBearer bearer, Ptr tft) { diff --git a/src/lte/helper/lte-helper.h b/src/lte/helper/lte-helper.h index 3ad07bc4b..60e6f7cf1 100644 --- a/src/lte/helper/lte-helper.h +++ b/src/lte/helper/lte-helper.h @@ -173,6 +173,24 @@ public: */ NetDeviceContainer InstallUeDevice (NodeContainer c); + /** + * \brief Instruct a set of UE devices to attach to a suitable cell. + * \param ueDevices + * + * By calling this, the UE will start the initial cell selection procedure at + * the beginning of simulation. + */ + void Attach (NetDeviceContainer ueDevices); + + /** + * \brief Instruct a UE device to attach to a suitable cell. + * \param ueDevice + * + * By calling this, the UE will start the initial cell selection procedure at + * the beginning of simulation. + */ + void Attach (Ptr ueDevice); + /** * Attach a set of UE devices to a single eNB device * @@ -211,6 +229,28 @@ public: */ void AttachToClosestEnb (Ptr ueDevice, NetDeviceContainer enbDevices); + /** + * \brief Instruct a set of UE devices to switch to ACTIVE/CONNECTED state. + * \param ueDevices + * + * If this function is called when the UE is in a situation where performing + * a call is not possible (e.g. before the simulation begin), then the UE will + * attempt to connect at the earliest possible time (e.g. after it camps to a + * suitable cell). + */ + void Connect (NetDeviceContainer ueDevices); + + /** + * \brief Instruct a UE device to switch to ACTIVE/CONNECTED state. + * \param ueDevice + * + * If this function is called when the UE is in a situation where performing + * a call is not possible (e.g. before the simulation begin), then the UE will + * attempt to connect at the earliest possible time (e.g. after it camps to a + * suitable cell). + */ + void Connect (Ptr ueDevice); + /** * Activate a dedicated EPS bearer on a given set of UE devices * @@ -317,7 +357,7 @@ public: * Enable trace sinks for UL PHY layer */ void EnableUlPhyTraces (void); - + /** * Enable trace sinks for DL transmission PHY layer */ diff --git a/src/lte/model/epc-ue-nas.cc b/src/lte/model/epc-ue-nas.cc index a54cdc0de..b00d8e1a1 100644 --- a/src/lte/model/epc-ue-nas.cc +++ b/src/lte/model/epc-ue-nas.cc @@ -120,6 +120,15 @@ EpcUeNas::SetForwardUpCallback (Callback > cb) } void +EpcUeNas::Connect () +{ + NS_LOG_FUNCTION (this); + + // tell RRC to go into connected mode + m_asSapProvider->Connect (); +} + +void EpcUeNas::Connect (uint16_t cellId, uint16_t earfcn) { NS_LOG_FUNCTION (this); @@ -165,7 +174,7 @@ bool EpcUeNas::Send (Ptr packet) { NS_LOG_FUNCTION (this << packet); - + switch (m_state) { case ACTIVE: @@ -181,15 +190,15 @@ EpcUeNas::Send (Ptr packet) { m_asSapProvider->SendData (packet, bid); return true; - } + } } break; - default: + default: NS_LOG_WARN (this << " NAS OFF, discarding packet"); return false; break; - } + } } void diff --git a/src/lte/model/epc-ue-nas.h b/src/lte/model/epc-ue-nas.h index eed9821eb..fda378982 100644 --- a/src/lte/model/epc-ue-nas.h +++ b/src/lte/model/epc-ue-nas.h @@ -86,12 +86,24 @@ public: void SetForwardUpCallback (Callback > cb); /** - * instruct the NAS to go to ACTIVE state, i.e., EMM Registered + ECM Connected - * Since RRC Idle Mode cell selection is not supported yet, we - * force the UE RRC to be camped on a specific eNB. + * \brief Instruct the NAS to go to ACTIVE state * + * The end result is equivalent with EMM Registered + ECM Connected states. + * If this function is called when the UE is in a situation where connecting + * is not possible (e.g. before the simulation begin), then the UE will + * attempt to connect at the earliest possible time (e.g. after it camps to a + * suitable cell). + */ + void Connect (); + + /** + * \brief Instruct the NAS to camp to a specific cell and go to ACTIVE state. * \param cellId the id of the eNB to camp on * \param earfcn the DL frequency of the eNB + * + * The end result is equivalent with EMM Registered + ECM Connected states. + * Since RRC Idle Mode cell selection is not supported yet, we force the UE + * RRC to be camped on a specific eNB. */ void Connect (uint16_t cellId, uint16_t earfcn); @@ -137,7 +149,7 @@ public: private: - + // LTE AS SAP methods void DoNotifyConnectionSuccessful (); void DoNotifyConnectionFailed (); @@ -155,7 +167,7 @@ private: Ptr m_device; uint64_t m_imsi; - + LteAsSapProvider* m_asSapProvider; LteAsSapUser* m_asSapUser; diff --git a/src/lte/model/lte-ue-phy.cc b/src/lte/model/lte-ue-phy.cc index af1bc6a53..25983a8ce 100644 --- a/src/lte/model/lte-ue-phy.cc +++ b/src/lte/model/lte-ue-phy.cc @@ -279,8 +279,6 @@ LteUePhy::DoInitialize () { NS_LOG_FUNCTION (this); LtePhy::DoInitialize (); - DoSetDlBandwidth (6); // configure DL for receiving PSS - SwitchToState (CELL_SEARCH); } void @@ -674,6 +672,14 @@ LteUePhy::CreateDlCqiFeedbackMessage (const SpectrumValue& sinr) } +void +LteUePhy::CellSearch () +{ + DoSetDlBandwidth (6); // configure DL for receiving PSS + SwitchToState (CELL_SEARCH); +} + + void LteUePhy::ReportUeMeasurements () { @@ -1128,7 +1134,7 @@ LteUePhy::DoSetDlBandwidth (uint8_t dlBandwidth) break; } } - + Ptr noisePsd = LteSpectrumValueHelper::CreateNoisePowerSpectralDensity (m_dlEarfcn, m_dlBandwidth, m_noiseFigure); m_downlinkSpectrumPhy->SetNoisePowerSpectralDensity (noisePsd); m_downlinkSpectrumPhy->GetChannel ()->AddRx (m_downlinkSpectrumPhy); diff --git a/src/lte/model/lte-ue-phy.h b/src/lte/model/lte-ue-phy.h index 1da859816..1d30ac4a3 100644 --- a/src/lte/model/lte-ue-phy.h +++ b/src/lte/model/lte-ue-phy.h @@ -176,6 +176,15 @@ public: std::vector GetSubChannelsForReception (void); + /** + * \brief Listen to PSS from surrounding cells and measure the RSRP. + * + * This function will instruct this PHY instance to listen to the DL channel + * over the bandwidth of 6 RB. After this, it will start to receive Primary + * Synchronization Signal (PSS). + */ + void CellSearch (); + /** * \brief Create the DL CQI feedback from SINR values perceived at * the physical layer with the signal received from eNB @@ -216,7 +225,7 @@ public: * \brief Send the SRS signal in the last symbols of the frame */ void SendSrs (); - + /** * \brief PhySpectrum generated a new DL HARQ feedback */ diff --git a/src/lte/test/lte-test-cell-selection.cc b/src/lte/test/lte-test-cell-selection.cc index f801c6d7f..d8c60c9cf 100644 --- a/src/lte/test/lte-test-cell-selection.cc +++ b/src/lte/test/lte-test-cell-selection.cc @@ -71,25 +71,25 @@ LteCellSelectionTestSuite::LteCellSelectionTestSuite () x.clear (); // position x y z, plmn csg expectedCellId x.push_back (LteCellSelectionTestCase::UeSetup_t (Vector (80, 10, 0), 0, 0, 1)); AddTestCase (new LteCellSelectionTestCase ("[EPC] In front of cell 1", - true, x, MilliSeconds (206)), + true, x, MilliSeconds (261)), TestCase::QUICK); x.clear (); // position x y z, plmn csg expectedCellId x.push_back (LteCellSelectionTestCase::UeSetup_t (Vector (-80, 20, 0), 0, 0, 2)); AddTestCase (new LteCellSelectionTestCase ("[EPC] In front of cell 2", - true, x, MilliSeconds (206)), + true, x, MilliSeconds (261)), TestCase::QUICK); x.clear (); // position x y z, plmn csg expectedCellId x.push_back (LteCellSelectionTestCase::UeSetup_t (Vector (-80, 10, 0), 0, 0, 2)); AddTestCase (new LteCellSelectionTestCase ("[EPC] Behind cell 1", - true, x, MilliSeconds (206)), + true, x, MilliSeconds (261)), TestCase::QUICK); x.clear (); // position x y z, plmn csg expectedCellId x.push_back (LteCellSelectionTestCase::UeSetup_t (Vector (80, 20, 0), 0, 0, 1)); AddTestCase (new LteCellSelectionTestCase ("[EPC] Behind cell 2", - true, x, MilliSeconds (206)), + true, x, MilliSeconds (261)), TestCase::QUICK); } // end of LteCellSelectionTestSuite::LteCellSelectionTestSuite () @@ -244,7 +244,8 @@ LteCellSelectionTestCase::DoRun () ueStaticRouting->SetDefaultRoute (epcHelper->GetUeDefaultGatewayAddress (), 1); } - // TODO call LteHelper::Attach (ueDevs) + lteHelper->Attach (ueDevs); + lteHelper->Connect (ueDevs); } // end of if (m_isEpcMode) else @@ -285,9 +286,11 @@ LteCellSelectionTestCase::DoRun () uint16_t actualCellId = ueDev->GetRrc ()->GetCellId (); uint16_t expectedCellId = itSetup->expectedCellId; NS_TEST_ASSERT_MSG_EQ (actualCellId, expectedCellId, - "UE has attached to an unexpected cell (or not attached at all)"); + "UE has attached to an unexpected cell"); } + NS_TEST_ASSERT_MSG_EQ (m_lastState, 5, "UE is not at CONNECTED_NORMALLY state"); + Simulator::Destroy (); } // end of void LteCellSelectionTestCase::DoRun () @@ -321,6 +324,7 @@ LteCellSelectionTestCase::StateTransitionCallback (std::string context, { NS_LOG_FUNCTION (this << context << imsi << cellId << rnti << oldState << newState); + m_lastState = newState; } diff --git a/src/lte/test/lte-test-cell-selection.h b/src/lte/test/lte-test-cell-selection.h index 83c97d471..e8e27513e 100644 --- a/src/lte/test/lte-test-cell-selection.h +++ b/src/lte/test/lte-test-cell-selection.h @@ -112,13 +112,18 @@ private: /** * \brief The length of the simulation. * - * Typical simulation length is 206 milliseconds, which is the minimum time - * required for initial cell selection in default settings. Scenarios which - * expect failure in initial cell selection procedure might want to extend - * this to give the UE the chance to retry the procedure. + * The shortest possible simulation length for testing initial cell selection + * is 206 milliseconds. If RRC_CONNECTED state is required, then the length + * should be extended to 261 milliseconds in ideal RRC protocol, or at least + * 277 milliseconds in real RRC protocol. Moreover, scenarios which expect + * failure in initial cell selection procedure might want to extend this even + * further to give the UE the chance to retry the procedure. */ Time m_duration; + /// The current UE RRC state. + LteUeRrc::State m_lastState; + }; // end of class LteCellSelectionTestCase