--- a/src/lte/helper/lte-helper.cc Wed Jul 10 14:59:00 2013 +0300
+++ b/src/lte/helper/lte-helper.cc Tue Jul 16 09:43:01 2013 +0300
@@ -328,6 +328,9 @@
Ptr<LteSpectrumPhy> dlPhy = CreateObject<LteSpectrumPhy> ();
Ptr<LteSpectrumPhy> ulPhy = CreateObject<LteSpectrumPhy> ();
+ dlPhy->SetChannel (m_downlinkChannel);
+ ulPhy->SetChannel (m_uplinkChannel);
+
Ptr<LteEnbPhy> phy = CreateObject<LteEnbPhy> (dlPhy, ulPhy);
Ptr<LteHarqPhy> harq = Create<LteHarqPhy> ();
@@ -344,9 +347,6 @@
Ptr<LteInterferencePowerChunkProcessor> pInterf = Create<LteInterferencePowerChunkProcessor> (phy);
ulPhy->AddInterferenceDataChunkProcessor (pInterf); // for interference power tracing
- dlPhy->SetChannel (m_downlinkChannel);
- ulPhy->SetChannel (m_uplinkChannel);
-
Ptr<MobilityModel> mm = n->GetObject<MobilityModel> ();
NS_ASSERT_MSG (mm, "MobilityModel needs to be set on node before calling LteHelper::InstallUeDevice ()");
dlPhy->SetMobility (mm);
@@ -472,6 +472,9 @@
Ptr<LteSpectrumPhy> dlPhy = CreateObject<LteSpectrumPhy> ();
Ptr<LteSpectrumPhy> ulPhy = CreateObject<LteSpectrumPhy> ();
+ dlPhy->SetChannel (m_downlinkChannel);
+ ulPhy->SetChannel (m_uplinkChannel);
+
Ptr<LteUePhy> phy = CreateObject<LteUePhy> (dlPhy, ulPhy);
Ptr<LteHarqPhy> harq = Create<LteHarqPhy> ();
@@ -491,9 +494,6 @@
Ptr<LteDataSinrChunkProcessor> pData = Create<LteDataSinrChunkProcessor> (dlPhy);
dlPhy->AddDataSinrChunkProcessor (pData);
- dlPhy->SetChannel (m_downlinkChannel);
- ulPhy->SetChannel (m_uplinkChannel);
-
Ptr<MobilityModel> mm = n->GetObject<MobilityModel> ();
NS_ASSERT_MSG (mm, "MobilityModel needs to be set on node before calling LteHelper::InstallUeDevice ()");
dlPhy->SetMobility (mm);
--- a/src/lte/model/lte-control-messages.cc Wed Jul 10 14:59:00 2013 +0300
+++ b/src/lte/model/lte-control-messages.cc Tue Jul 16 09:43:01 2013 +0300
@@ -258,11 +258,33 @@
}
+// ----------------------------------------------------------------------------------------------------------
+
+
+
+Sib1LteControlMessage::Sib1LteControlMessage (void)
+{
+ SetMessageType (LteControlMessage::SIB1);
+}
+
+
+void
+Sib1LteControlMessage::SetSib1 (LteRrcSap::SystemInformationBlockType1 sib1)
+{
+ m_sib1 = sib1;
+}
+
+LteRrcSap::SystemInformationBlockType1
+Sib1LteControlMessage::GetSib1 () const
+{
+ return m_sib1;
+}
// ---------------------------------------------------------------------------
+
DlHarqFeedbackLteControlMessage::DlHarqFeedbackLteControlMessage (void)
{
SetMessageType (LteControlMessage::DL_HARQ);
--- a/src/lte/model/lte-control-messages.h Wed Jul 10 14:59:00 2013 +0300
+++ b/src/lte/model/lte-control-messages.h Tue Jul 16 09:43:01 2013 +0300
@@ -58,6 +58,7 @@
RACH_PREAMBLE, // Random Access Preamble
RAR, // Random Access Response
MIB, // Master Information Block
+ SIB1, // System Information Block Type 1
};
LteControlMessage (void);
@@ -465,3 +466,36 @@
} // namespace ns3
#endif // MIB_LTE_CONTROL_MESSAGES_H
+
+
+
+#ifndef SIB1_LTE_CONTROL_MESSAGES_H
+#define SIB1_LTE_CONTROL_MESSAGES_H
+
+#include <ns3/lte-rrc-sap.h>
+
+namespace ns3 {
+
+/**
+ * \ingroup lte
+ * \brief Model for broadcasting the System Information Block Type 1
+ */
+class Sib1LteControlMessage : public LteControlMessage
+{
+public:
+
+ Sib1LteControlMessage (void);
+
+ void SetSib1 (LteRrcSap::SystemInformationBlockType1 sib1);
+
+ LteRrcSap::SystemInformationBlockType1 GetSib1 () const;
+
+private:
+
+ LteRrcSap::SystemInformationBlockType1 m_sib1;
+
+};
+
+} // namespace ns3
+
+#endif // SIB1_LTE_CONTROL_MESSAGES_H
--- a/src/lte/model/lte-enb-cphy-sap.h Wed Jul 10 14:59:00 2013 +0300
+++ b/src/lte/model/lte-enb-cphy-sap.h Tue Jul 16 09:43:01 2013 +0300
@@ -96,6 +96,12 @@
* \param mib the Master Information Block to be sent on the BCH
*/
virtual void SetMasterInformationBlock (LteRrcSap::MasterInformationBlock mib) = 0;
+
+ /**
+ *
+ * \param sib1 the System Information Block Type 1 to be sent on the BCH
+ */
+ virtual void SetSystemInformationBlockType1 (LteRrcSap::SystemInformationBlockType1 sib1) = 0;
};
@@ -137,6 +143,7 @@
virtual void SetTransmissionMode (uint16_t rnti, uint8_t txMode);
virtual void SetSrsConfigurationIndex (uint16_t rnti, uint16_t srsCi);
virtual void SetMasterInformationBlock (LteRrcSap::MasterInformationBlock mib);
+ virtual void SetSystemInformationBlockType1 (LteRrcSap::SystemInformationBlockType1 sib1);
private:
MemberLteEnbCphySapProvider ();
@@ -211,6 +218,13 @@
m_owner->DoSetMasterInformationBlock (mib);
}
+template <class C>
+void
+MemberLteEnbCphySapProvider<C>::SetSystemInformationBlockType1 (LteRrcSap::SystemInformationBlockType1 sib1)
+{
+ m_owner->DoSetSystemInformationBlockType1 (sib1);
+}
+
/**
--- a/src/lte/model/lte-enb-phy.cc Wed Jul 10 14:59:00 2013 +0300
+++ b/src/lte/model/lte-enb-phy.cc Tue Jul 16 09:43:01 2013 +0300
@@ -525,6 +525,21 @@
NS_LOG_FUNCTION (this);
++m_nrSubFrames;
+
+ /*
+ * Send SIB1 at 6th subframe of every odd-numbered radio frame. This is
+ * equivalent with Section 5.2.1.2 of 3GPP TS 36.331, where it is specified
+ * "repetitions are scheduled in subframe #5 of all other radio frames for
+ * which SFN mod 2 = 0," except that 3GPP counts frames and subframes starting
+ * from 0, while ns-3 counts starting from 1.
+ */
+ if ((m_nrSubFrames == 6) && ((m_nrFrames % 2) == 1))
+ {
+ Ptr<Sib1LteControlMessage> msg = Create<Sib1LteControlMessage> ();
+ msg->SetSib1 (m_sib1);
+ m_controlMessagesQueue.at (0).push_back (msg);
+ }
+
if (m_srsPeriodicity>0)
{
// might be 0 in case the eNB has no UEs attached
@@ -974,6 +989,14 @@
void
+LteEnbPhy::DoSetSystemInformationBlockType1 (LteRrcSap::SystemInformationBlockType1 sib1)
+{
+ NS_LOG_FUNCTION (this);
+ m_sib1 = sib1;
+}
+
+
+void
LteEnbPhy::SetHarqPhyModule (Ptr<LteHarqPhy> harq)
{
m_harqPhyModule = harq;
--- a/src/lte/model/lte-enb-phy.h Wed Jul 10 14:59:00 2013 +0300
+++ b/src/lte/model/lte-enb-phy.h Tue Jul 16 09:43:01 2013 +0300
@@ -264,6 +264,7 @@
void DoSetTransmissionMode (uint16_t rnti, uint8_t txMode);
void DoSetSrsConfigurationIndex (uint16_t rnti, uint16_t srcCi);
void DoSetMasterInformationBlock (LteRrcSap::MasterInformationBlock mib);
+ void DoSetSystemInformationBlockType1 (LteRrcSap::SystemInformationBlockType1 sib1);
// LteEnbPhySapProvider forwarded methods
void DoSendMacPdu (Ptr<Packet> p);
@@ -301,6 +302,7 @@
uint16_t m_currentSrsOffset;
LteRrcSap::MasterInformationBlock m_mib;
+ LteRrcSap::SystemInformationBlockType1 m_sib1;
Ptr<LteHarqPhy> m_harqPhyModule;
--- a/src/lte/model/lte-rrc-protocol-ideal.cc Wed Jul 10 14:59:00 2013 +0300
+++ b/src/lte/model/lte-rrc-protocol-ideal.cc Tue Jul 16 09:43:01 2013 +0300
@@ -323,50 +323,6 @@
}
void
-LteEnbRrcProtocolIdeal::DoSendMasterInformationBlock (LteRrcSap::MasterInformationBlock msg)
-{
- NS_LOG_FUNCTION (this);
- for (std::map<uint16_t, LteUeRrcSapProvider*>::const_iterator it = m_enbRrcSapProviderMap.begin ();
- it != m_enbRrcSapProviderMap.end ();
- ++it)
- {
- Simulator::Schedule (RRC_IDEAL_MSG_DELAY,
- &LteUeRrcSapProvider::RecvMasterInformationBlock,
- it->second,
- msg);
- }
-}
-
-void
-LteEnbRrcProtocolIdeal::DoSendSystemInformationBlockType1 (LteRrcSap::SystemInformationBlockType1 msg)
-{
- NS_LOG_FUNCTION (this << m_cellId);
- // walk list of all nodes to get UEs with this cellId
- Ptr<LteUeRrc> ueRrc;
- for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
- {
- Ptr<Node> node = *i;
- int nDevs = node->GetNDevices ();
- for (int j = 0; j < nDevs; ++j)
- {
- Ptr<LteUeNetDevice> ueDev = node->GetDevice (j)->GetObject <LteUeNetDevice> ();
- if (ueDev != 0)
- {
- NS_LOG_LOGIC ("considering UE " << ueDev->GetImsi ());
- Ptr<LteUeRrc> ueRrc = ueDev->GetRrc ();
- if (ueRrc->GetCellId () == m_cellId)
- {
- Simulator::Schedule (RRC_IDEAL_MSG_DELAY,
- &LteUeRrcSapProvider::RecvSystemInformationBlockType1,
- ueRrc->GetLteUeRrcSapProvider (),
- msg);
- }
- }
- }
- }
-}
-
-void
LteEnbRrcProtocolIdeal::DoSendSystemInformation (LteRrcSap::SystemInformation msg)
{
NS_LOG_FUNCTION (this << m_cellId);
--- a/src/lte/model/lte-rrc-protocol-ideal.h Wed Jul 10 14:59:00 2013 +0300
+++ b/src/lte/model/lte-rrc-protocol-ideal.h Tue Jul 16 09:43:01 2013 +0300
@@ -116,8 +116,6 @@
// methods forwarded from LteEnbRrcSapUser
void DoSetupUe (uint16_t rnti, LteEnbRrcSapUser::SetupUeParameters params);
void DoRemoveUe (uint16_t rnti);
- void DoSendMasterInformationBlock (LteRrcSap::MasterInformationBlock msg);
- void DoSendSystemInformationBlockType1 (LteRrcSap::SystemInformationBlockType1 msg);
void DoSendSystemInformation (LteRrcSap::SystemInformation msg);
void SendSystemInformation (LteRrcSap::SystemInformation msg);
void DoSendRrcConnectionSetup (uint16_t rnti, LteRrcSap::RrcConnectionSetup msg);
--- a/src/lte/model/lte-rrc-protocol-real.cc Wed Jul 10 14:59:00 2013 +0300
+++ b/src/lte/model/lte-rrc-protocol-real.cc Tue Jul 16 09:43:01 2013 +0300
@@ -503,50 +503,6 @@
}
void
-LteEnbRrcProtocolReal::DoSendMasterInformationBlock (LteRrcSap::MasterInformationBlock msg)
-{
- NS_LOG_FUNCTION (this);
- for (std::map<uint16_t, LteUeRrcSapProvider*>::const_iterator it = m_enbRrcSapProviderMap.begin ();
- it != m_enbRrcSapProviderMap.end ();
- ++it)
- {
- Simulator::Schedule (RRC_REAL_MSG_DELAY,
- &LteUeRrcSapProvider::RecvMasterInformationBlock,
- it->second,
- msg);
- }
-}
-
-void
-LteEnbRrcProtocolReal::DoSendSystemInformationBlockType1 (LteRrcSap::SystemInformationBlockType1 msg)
-{
- NS_LOG_FUNCTION (this << m_cellId);
- // walk list of all nodes to get UEs with this cellId
- Ptr<LteUeRrc> ueRrc;
- for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
- {
- Ptr<Node> node = *i;
- int nDevs = node->GetNDevices ();
- for (int j = 0; j < nDevs; ++j)
- {
- Ptr<LteUeNetDevice> ueDev = node->GetDevice (j)->GetObject <LteUeNetDevice> ();
- if (ueDev != 0)
- {
- NS_LOG_LOGIC ("considering UE " << ueDev->GetImsi ());
- Ptr<LteUeRrc> ueRrc = ueDev->GetRrc ();
- if (ueRrc->GetCellId () == m_cellId)
- {
- Simulator::Schedule (RRC_REAL_MSG_DELAY,
- &LteUeRrcSapProvider::RecvSystemInformationBlockType1,
- ueRrc->GetLteUeRrcSapProvider (),
- msg);
- }
- }
- }
- }
-}
-
-void
LteEnbRrcProtocolReal::DoSendSystemInformation (LteRrcSap::SystemInformation msg)
{
NS_LOG_FUNCTION (this << m_cellId);
--- a/src/lte/model/lte-rrc-protocol-real.h Wed Jul 10 14:59:00 2013 +0300
+++ b/src/lte/model/lte-rrc-protocol-real.h Tue Jul 16 09:43:01 2013 +0300
@@ -128,8 +128,6 @@
// methods forwarded from LteEnbRrcSapUser
void DoSetupUe (uint16_t rnti, LteEnbRrcSapUser::SetupUeParameters params);
void DoRemoveUe (uint16_t rnti);
- void DoSendMasterInformationBlock (LteRrcSap::MasterInformationBlock msg);
- void DoSendSystemInformationBlockType1 (LteRrcSap::SystemInformationBlockType1 msg);
void DoSendSystemInformation (LteRrcSap::SystemInformation msg);
void SendSystemInformation (LteRrcSap::SystemInformation msg);
void DoSendRrcConnectionSetup (uint16_t rnti, LteRrcSap::RrcConnectionSetup msg);
--- a/src/lte/model/lte-rrc-sap.h Wed Jul 10 14:59:00 2013 +0300
+++ b/src/lte/model/lte-rrc-sap.h Tue Jul 16 09:43:01 2013 +0300
@@ -77,6 +77,12 @@
uint32_t csgIdentity;
};
+ struct CellSelectionInfo
+ {
+ int8_t qRxLevMin; ///< INTEGER (-70..-22), actual value = IE value * 2 [dBm].
+ int8_t qQualMin; ///< INTEGER (-34..-3), actual value = IE value [dB].
+ };
+
struct FreqInfo
{
uint16_t ulCarrierFreq;
@@ -459,6 +465,7 @@
struct SystemInformationBlockType1
{
CellAccessRelatedInfo cellAccessRelatedInfo;
+ CellSelectionInfo cellSelectionInfo;
};
struct SystemInformationBlockType2
@@ -633,8 +640,6 @@
};
virtual void CompleteSetup (CompleteSetupParameters params) = 0;
- virtual void RecvMasterInformationBlock (MasterInformationBlock msg) = 0;
- virtual void RecvSystemInformationBlockType1 (SystemInformationBlockType1 msg) = 0;
virtual void RecvSystemInformation (SystemInformation msg) = 0;
virtual void RecvRrcConnectionSetup (RrcConnectionSetup msg) = 0;
virtual void RecvRrcConnectionReconfiguration (RrcConnectionReconfiguration msg) = 0;
@@ -663,7 +668,6 @@
virtual void SetupUe (uint16_t rnti, SetupUeParameters params) = 0;
virtual void RemoveUe (uint16_t rnti) = 0;
- virtual void SendSystemInformationBlockType1 (SystemInformationBlockType1 msg) = 0;
virtual void SendSystemInformation (SystemInformation msg) = 0;
virtual void SendRrcConnectionSetup (uint16_t rnti, RrcConnectionSetup msg) = 0;
virtual void SendRrcConnectionReconfiguration (uint16_t rnti, RrcConnectionReconfiguration msg) = 0;
@@ -812,8 +816,6 @@
// methods inherited from LteUeRrcSapProvider go here
virtual void CompleteSetup (CompleteSetupParameters params);
- virtual void RecvMasterInformationBlock (MasterInformationBlock msg);
- virtual void RecvSystemInformationBlockType1 (SystemInformationBlockType1 msg);
virtual void RecvSystemInformation (SystemInformation msg);
virtual void RecvRrcConnectionSetup (RrcConnectionSetup msg);
virtual void RecvRrcConnectionReconfiguration (RrcConnectionReconfiguration msg);
@@ -847,20 +849,6 @@
template <class C>
void
-MemberLteUeRrcSapProvider<C>::RecvMasterInformationBlock (MasterInformationBlock msg)
-{
- Simulator::ScheduleNow (&C::DoRecvMasterInformationBlock, m_owner, msg);
-}
-
-template <class C>
-void
-MemberLteUeRrcSapProvider<C>::RecvSystemInformationBlockType1 (SystemInformationBlockType1 msg)
-{
- Simulator::ScheduleNow (&C::DoRecvSystemInformationBlockType1, m_owner, msg);
-}
-
-template <class C>
-void
MemberLteUeRrcSapProvider<C>::RecvSystemInformation (SystemInformation msg)
{
Simulator::ScheduleNow (&C::DoRecvSystemInformation, m_owner, msg);
@@ -924,8 +912,6 @@
virtual void SetupUe (uint16_t rnti, SetupUeParameters params);
virtual void RemoveUe (uint16_t rnti);
- virtual void SendMasterInformationBlock (MasterInformationBlock msg);
- virtual void SendSystemInformationBlockType1 (SystemInformationBlockType1 msg);
virtual void SendSystemInformation (SystemInformation msg);
virtual void SendRrcConnectionSetup (uint16_t rnti, RrcConnectionSetup msg);
virtual void SendRrcConnectionReconfiguration (uint16_t rnti, RrcConnectionReconfiguration msg);
@@ -970,20 +956,6 @@
template <class C>
void
-MemberLteEnbRrcSapUser<C>::SendMasterInformationBlock (MasterInformationBlock msg)
-{
- m_owner->DoSendMasterInformationBlock (msg);
-}
-
-template <class C>
-void
-MemberLteEnbRrcSapUser<C>::SendSystemInformationBlockType1 (SystemInformationBlockType1 msg)
-{
- m_owner->DoSendSystemInformationBlockType1 (msg);
-}
-
-template <class C>
-void
MemberLteEnbRrcSapUser<C>::SendSystemInformation (SystemInformation msg)
{
m_owner->DoSendSystemInformation (msg);
--- a/src/lte/model/lte-spectrum-phy.cc Wed Jul 10 14:59:00 2013 +0300
+++ b/src/lte/model/lte-spectrum-phy.cc Tue Jul 16 09:43:01 2013 +0300
@@ -114,6 +114,7 @@
LteSpectrumPhy::LteSpectrumPhy ()
: m_state (IDLE),
+ m_cellId (0),
m_transmissionMode (0),
m_layersNum (1)
{
--- a/src/lte/model/lte-ue-cphy-sap.h Wed Jul 10 14:59:00 2013 +0300
+++ b/src/lte/model/lte-ue-cphy-sap.h Tue Jul 16 09:43:01 2013 +0300
@@ -54,7 +54,25 @@
virtual void Reset () = 0;
/**
- * tell the PHY to synchronize with a given eNB for communication purposes
+ * \brief Tell the PHY to retry the cell search procedure with a different
+ * cell.
+ */
+ virtual void RetryCellSearch () = 0;
+
+ /**
+ * \brief Tell the PHY to perform normal communication with the cell that it
+ * is currently synchronized to.
+ *
+ * \sa SyncronizeWithEnb, SetDlBandwidth
+ */
+ virtual void Attach () = 0;
+
+ /**
+ * \brief Tell the PHY to synchronize with a given eNB for communication
+ * purposes. Initially, the PHY will be configured to listen to 6 RBs
+ * for BCH.
+ *
+ * SetDlBandwidth can be called afterwards to change the bandwidth.
*
* \param cellId the ID of the eNB
* \param dlEarfcn the carrier frequency (EARFCN) in downlink
@@ -133,6 +151,12 @@
/**
*
+ * \param sib1 the System Information Block Type 1 received on the BCH
+ */
+ virtual void RecvSystemInformationBlockType1 (LteRrcSap::SystemInformationBlockType1 sib1) = 0;
+
+ /**
+ *
* \param params the structure containing the vector of cellId, SRSP and RSRQ
*/
virtual void ReportUeMeasurements (UeMeasurementsParameters params) = 0;
@@ -154,6 +178,8 @@
// inherited from LteUeCphySapProvider
virtual void Reset ();
+ virtual void RetryCellSearch ();
+ virtual void Attach ();
virtual void SyncronizeWithEnb (uint16_t cellId, uint16_t dlEarfcn);
virtual void SetDlBandwidth (uint8_t ulBandwidth);
virtual void ConfigureUplink (uint16_t ulEarfcn, uint8_t ulBandwidth);
@@ -186,6 +212,20 @@
template <class C>
void
+MemberLteUeCphySapProvider<C>::RetryCellSearch ()
+{
+ m_owner->DoRetryCellSearch ();
+}
+
+template <class C>
+void
+MemberLteUeCphySapProvider<C>::Attach ()
+{
+ m_owner->DoAttach ();
+}
+
+template <class C>
+void
MemberLteUeCphySapProvider<C>::SyncronizeWithEnb (uint16_t cellId, uint16_t dlEarfcn)
{
m_owner->DoSyncronizeWithEnb (cellId, dlEarfcn);
@@ -241,7 +281,7 @@
// methods inherited from LteUeCphySapUser go here
virtual void RecvMasterInformationBlock (LteRrcSap::MasterInformationBlock mib);
-
+ virtual void RecvSystemInformationBlockType1 (LteRrcSap::SystemInformationBlockType1 sib1);
virtual void ReportUeMeasurements (LteUeCphySapUser::UeMeasurementsParameters params);
private:
@@ -269,6 +309,13 @@
template <class C>
void
+MemberLteUeCphySapUser<C>::RecvSystemInformationBlockType1 (LteRrcSap::SystemInformationBlockType1 sib1)
+{
+ m_owner->DoRecvSystemInformationBlockType1 (sib1);
+}
+
+template <class C>
+void
MemberLteUeCphySapUser<C>::ReportUeMeasurements (LteUeCphySapUser::UeMeasurementsParameters params)
{
m_owner->DoReportUeMeasurements (params);
--- a/src/lte/model/lte-ue-phy.cc Wed Jul 10 14:59:00 2013 +0300
+++ b/src/lte/model/lte-ue-phy.cc Tue Jul 16 09:43:01 2013 +0300
@@ -106,6 +106,18 @@
// LteUePhy methods
////////////////////////////////////////
+const char* g_uePhyStateName[LteUePhy::NUM_STATES] =
+ {
+ "CELL_SEARCH",
+ "DECODING_BCH",
+ "ATTACHED"
+ };
+
+std::string ToString (LteUePhy::State s)
+{
+ return std::string (g_uePhyStateName[s]);
+}
+
NS_OBJECT_ENSURE_REGISTERED (LteUePhy);
@@ -122,6 +134,7 @@
m_a30CqiPeriocity (MilliSeconds (1)), // ideal behavior
m_uePhySapUser (0),
m_ueCphySapUser (0),
+ m_state (CELL_SEARCH),
m_subframeNo (0),
m_rsReceivedPowerUpdated (false),
m_rsInterferencePowerUpdated (false),
@@ -255,6 +268,9 @@
.AddTraceSource ("ReportUeMeasurements",
"Report UE measurements RSRP (dBm) and RSRQ (dB).",
MakeTraceSourceAccessor (&LteUePhy::m_reportUeMeasurements))
+ .AddTraceSource ("StateTransition",
+ "Trace fired upon every UE PHY state transition",
+ MakeTraceSourceAccessor (&LteUePhy::m_stateTransitionTrace))
;
return tid;
}
@@ -408,12 +424,8 @@
{
NS_LOG_FUNCTION (this);
- if ((!(m_dlConfigured && m_ulConfigured)) || (m_rnti == 0))
- {
- // abort method, the UE is still not registered
- m_pssList.clear ();
- return;
- }
+ NS_ASSERT (m_state != CELL_SEARCH);
+ NS_ASSERT (m_cellId > 0);
// check periodic wideband CQI
if (Simulator::Now () > m_p10CqiLast + m_p10CqiPeriocity)
@@ -528,7 +540,7 @@
}
-
+
}
void
@@ -660,28 +672,68 @@
{
NS_LOG_FUNCTION (this << Simulator::Now ());
NS_LOG_DEBUG (this << " Report UE Measurements ");
+
LteUeCphySapUser::UeMeasurementsParameters ret;
+ double maxRsrp = -std::numeric_limits<double>::infinity ();
+ uint16_t maxRsrpCellId = 0;
+
std::map <uint16_t, UeMeasurementsElement>::iterator it;
for (it = m_UeMeasurementsMap.begin (); it != m_UeMeasurementsMap.end (); it++)
{
double avg_rsrp = (*it).second.rsrpSum / (double)(*it).second.rsrpNum;
double avg_rsrq = (*it).second.rsrqSum / (double)(*it).second.rsrqNum;
- NS_LOG_DEBUG (this << " CellId " << (*it).first << " RSRP " << avg_rsrp << " (nSamples " << (*it).second.rsrpNum << ") RSRQ " << avg_rsrq << " (nSamples " << (*it).second.rsrpNum << ")");
+ NS_LOG_DEBUG (this << " CellId " << (*it).first
+ << " RSRP " << avg_rsrp << " (nSamples " << (uint16_t)(*it).second.rsrpNum
+ << ") RSRQ " << avg_rsrq << " (nSamples " << (uint16_t)(*it).second.rsrpNum << ")");
+
+ if ((m_state == CELL_SEARCH) && (maxRsrp < avg_rsrp))
+ {
+ std::set<uint16_t>::const_iterator itSib1 = m_cellHasDecodedSib1.find (it->first);
+ if (itSib1 == m_cellHasDecodedSib1.end ())
+ {
+ std::set<uint16_t>::const_iterator itMib = m_cellHasDecodedMib.find (it->first);
+ if (itMib == m_cellHasDecodedMib.end ())
+ {
+ maxRsrp = avg_rsrp;
+ maxRsrpCellId = it->first;
+ /*
+ * The end result of this nested if block is to find a cell
+ * with strongest RSRP which MIB and SIB1 have not been
+ * received yet.
+ */
+ }
+ }
+ }
+
LteUeCphySapUser::UeMeasurementsElement newEl;
newEl.m_cellId = (*it).first;
newEl.m_rsrp = avg_rsrp;
newEl.m_rsrq = avg_rsrq;
ret.m_ueMeasurementsList.push_back (newEl);
+
// report to UE measurements trace
m_reportUeMeasurements (m_rnti, m_cellId, avg_rsrp, avg_rsrq, ((*it).first == m_cellId ? 1 : 0));
}
- m_ueCphySapUser-> ReportUeMeasurements(ret);
+
+ if (m_state == CELL_SEARCH)
+ {
+ if (maxRsrpCellId == 0)
+ {
+ NS_LOG_WARN (this << " Cell search has detected no surrounding cell");
+ }
+ else
+ {
+ DoSyncronizeWithEnb (maxRsrpCellId, m_dlEarfcn);
+ }
+ }
+
+ // report to RRC
+ m_ueCphySapUser-> ReportUeMeasurements (ret);
+
m_UeMeasurementsMap.clear ();
Simulator::Schedule (m_ueMeasurementsFilterPeriod, &LteUePhy::ReportUeMeasurements, this);
}
-
-
void
LteUePhy::DoSendLteControlMessage (Ptr<LteControlMessage> msg)
{
@@ -828,9 +880,25 @@
else if (msg->GetMessageType () == LteControlMessage::MIB)
{
NS_LOG_INFO ("received MIB");
+ NS_ASSERT (m_cellId > 0);
+ if (m_state == DECODING_BCH)
+ {
+ m_cellHasDecodedMib.insert (m_cellId);
+ }
Ptr<MibLteControlMessage> msg2 = DynamicCast<MibLteControlMessage> (msg);
m_ueCphySapUser->RecvMasterInformationBlock (msg2->GetMib ());
}
+ else if (msg->GetMessageType () == LteControlMessage::SIB1)
+ {
+ NS_LOG_INFO ("received SIB1");
+ NS_ASSERT (m_cellId > 0);
+ if (m_state == DECODING_BCH)
+ {
+ m_cellHasDecodedSib1.insert (m_cellId);
+ }
+ Ptr<Sib1LteControlMessage> msg2 = DynamicCast<Sib1LteControlMessage> (msg);
+ m_ueCphySapUser->RecvSystemInformationBlockType1 (msg2->GetSib1 ());
+ }
else
{
// pass the message to UE-MAC
@@ -847,14 +915,7 @@
LteUePhy::ReceivePss (uint16_t cellId, Ptr<SpectrumValue> p)
{
NS_LOG_FUNCTION (this << cellId << (*p));
- if (!m_dlConfigured)
- {
- // LteUePhy not yet configured -> skip measurement
- return;
- }
- m_pssReceived = true;
- PssElement el;
- el.cellId = cellId;
+
double sum = 0.0;
uint16_t nRB = 0;
Values::const_iterator itPi;
@@ -865,10 +926,57 @@
sum += powerTxW;
nRB++;
}
- el.pssPsdSum = sum;
- el.nRB = nRB;
- m_pssList.push_back (el);
-}
+
+ if (m_cellId == 0)
+ {
+ /*
+ * PHY is not synchronized to any cell, no RX is running, so interference
+ * value is not available and GenerateCtrlCqiReport will not be called.
+ * Utilize the PSS now for calculating RSRP measurements.
+ */
+ NS_LOG_DEBUG (this << " Process PSS RNTI 0 cellId 0");
+ double rsrp_dBm = 10 * log10 (1000 * (sum / (double)nRB));
+ NS_LOG_INFO (this << " PSS received from CellId " << cellId
+ << " has RSRP " << rsrp_dBm << " and RBnum " << nRB);
+ // Note that m_pssReceptionThreshold does not apply here
+
+ // store measurements
+ std::map <uint16_t, UeMeasurementsElement>::iterator itMeasMap = m_UeMeasurementsMap.find (cellId);
+ if (itMeasMap == m_UeMeasurementsMap.end ())
+ {
+ // insert new entry
+ UeMeasurementsElement newEl;
+ newEl.rsrpSum = rsrp_dBm;
+ newEl.rsrpNum = 1;
+ newEl.rsrqSum = 0; // RSRQ is not available
+ newEl.rsrqNum = 1;
+ m_UeMeasurementsMap.insert (std::pair <uint16_t, UeMeasurementsElement> (cellId, newEl));
+ }
+ else
+ {
+ (*itMeasMap).second.rsrpSum += rsrp_dBm;
+ (*itMeasMap).second.rsrpNum++;
+ (*itMeasMap).second.rsrqSum += 0; // RSRQ is not available
+ (*itMeasMap).second.rsrqNum++;
+ }
+
+ } // end of if (m_cellId == 0)
+ else
+ {
+ /*
+ * Collect the PSS for later processing in GenerateCtrlCqiReport
+ * (to be called from ChunkProcessor after RX is finished).
+ */
+ m_pssReceived = true;
+ PssElement el;
+ el.cellId = cellId;
+ el.pssPsdSum = sum;
+ el.nRB = nRB;
+ m_pssList.push_back (el);
+
+ } // end of else of if (m_cellId == 0)
+
+} // end of void LteUePhy::ReceivePss (uint16_t cellId, Ptr<SpectrumValue> p)
void
@@ -1005,25 +1113,50 @@
m_sendSrsEvent.Cancel ();
m_downlinkSpectrumPhy->Reset ();
m_uplinkSpectrumPhy->Reset ();
+
+ // configure DL for receiving PSS
+ m_dlEarfcn = 100; // TODO hardcoded value
+ m_noiseFigure = 9.0; // TODO hardcoded value
+ NS_ASSERT (m_downlinkSpectrumPhy->GetChannel () != 0);
+ DoSetDlBandwidth (6);
+
+ SwitchToState (CELL_SEARCH);
+
+} // end of void LteUePhy::DoReset ()
+
+void
+LteUePhy::DoRetryCellSearch ()
+{
+ NS_LOG_FUNCTION (this);
+ SwitchToState (CELL_SEARCH);
+}
+
+void
+LteUePhy::DoAttach ()
+{
+ NS_ASSERT_MSG (m_state == DECODING_BCH, "Unable to attach from state " << ToString (m_state));
+ m_cellHasDecodedMib.clear ();
+ m_cellHasDecodedSib1.clear ();
+ SwitchToState (ATTACHED);
}
void
LteUePhy::DoSyncronizeWithEnb (uint16_t cellId, uint16_t dlEarfcn)
{
- NS_LOG_FUNCTION (this << cellId);
+ NS_LOG_FUNCTION (this << cellId << dlEarfcn);
+
m_cellId = cellId;
m_dlEarfcn = dlEarfcn;
m_downlinkSpectrumPhy->SetCellId (cellId);
m_uplinkSpectrumPhy->SetCellId (cellId);
- // configure DL for receing the BCH with the minimum bandwith
- m_dlBandwidth = 6;
- Ptr<SpectrumValue> noisePsd = LteSpectrumValueHelper::CreateNoisePowerSpectralDensity (m_dlEarfcn, m_dlBandwidth, m_noiseFigure);
- m_downlinkSpectrumPhy->SetNoisePowerSpectralDensity (noisePsd);
- m_downlinkSpectrumPhy->GetChannel ()->AddRx (m_downlinkSpectrumPhy);
-
+ // configure DL for receiving the BCH with the minimum bandwidth
+ DoSetDlBandwidth (6);
+
m_dlConfigured = false;
m_ulConfigured = false;
+
+ SwitchToState (DECODING_BCH);
}
void
@@ -1186,4 +1319,25 @@
}
+LteUePhy::State
+LteUePhy::GetState ()
+{
+ NS_LOG_FUNCTION (this);
+ return m_state;
+}
+
+
+void
+LteUePhy::SwitchToState (State newState)
+{
+ NS_LOG_FUNCTION (this << newState);
+ State oldState = m_state;
+ m_state = newState;
+ NS_LOG_INFO (this << " cellId=" << m_cellId << " rnti=" << m_rnti
+ << " UePhy " << ToString (oldState)
+ << " --> " << ToString (newState));
+ m_stateTransitionTrace (m_cellId, m_rnti, oldState, newState);
+}
+
+
} // namespace ns3
--- a/src/lte/model/lte-ue-phy.h Wed Jul 10 14:59:00 2013 +0300
+++ b/src/lte/model/lte-ue-phy.h Tue Jul 16 09:43:01 2013 +0300
@@ -32,6 +32,7 @@
#include <ns3/lte-ue-cphy-sap.h>
#include <ns3/ptr.h>
#include <ns3/lte-amc.h>
+#include <set>
namespace ns3 {
@@ -54,6 +55,17 @@
public:
/**
+ * \brief The states of the UE PHY entity
+ */
+ enum State
+ {
+ CELL_SEARCH = 0,
+ DECODING_BCH,
+ ATTACHED,
+ NUM_STATES
+ };
+
+ /**
* @warning the default constructor should not be used
*/
LteUePhy ();
@@ -179,8 +191,6 @@
// callbacks for LteSpectrumPhy
virtual void ReceiveLteControlMessageList (std::list<Ptr<LteControlMessage> >);
virtual void ReceivePss (uint16_t cellId, Ptr<SpectrumValue> p);
-
-
@@ -214,6 +224,10 @@
*/
void SetHarqPhyModule (Ptr<LteHarqPhy> harq);
+ /**
+ * \return The current state
+ */
+ State GetState ();
@@ -232,8 +246,12 @@
void ReportUeMeasurements ();
+ void SwitchToState (State s);
+
// UE CPHY SAP methods
void DoReset ();
+ void DoRetryCellSearch ();
+ void DoAttach ();
void DoSyncronizeWithEnb (uint16_t cellId, uint16_t dlEarfcn);
void DoSetDlBandwidth (uint8_t ulBandwidth);
void DoConfigureUplink (uint16_t ulEarfcn, uint8_t ulBandwidth);
@@ -281,6 +299,10 @@
bool m_dlConfigured;
bool m_ulConfigured;
+ State m_state;
+ // cellid rnti
+ TracedCallback<uint16_t, uint16_t, State, State> m_stateTransitionTrace;
+
uint8_t m_subframeNo;
bool m_rsReceivedPowerUpdated;
@@ -312,6 +334,16 @@
Time m_ueMeasurementsFilterPeriod;
Time m_ueMeasurementsFilterLast;
+ /**
+ * \brief List of cell ID which MIB has been decoded by this UE PHY instance.
+ */
+ std::set<uint16_t> m_cellHasDecodedMib;
+
+ /**
+ * \brief List of cell ID which SIB1 has been decoded by this UE PHY instance.
+ */
+ std::set<uint16_t> m_cellHasDecodedSib1;
+
Ptr<LteHarqPhy> m_harqPhyModule;
uint32_t m_raPreambleId;
--- a/src/lte/model/lte-ue-rrc.cc Wed Jul 10 14:59:00 2013 +0300
+++ b/src/lte/model/lte-ue-rrc.cc Tue Jul 16 09:43:01 2013 +0300
@@ -187,6 +187,17 @@
UintegerValue (0), // unused, read-only attribute
MakeUintegerAccessor (&LteUeRrc::GetRnti),
MakeUintegerChecker<uint16_t> ())
+ .AddAttribute ("CellSearchRetryTimeout",
+ "Maximum number of retry attempts during the initial cell selection procedure to find a suitable cell",
+ UintegerValue (3),
+ MakeUintegerAccessor (&LteUeRrc::m_cellSearchRetryTimeout),
+ MakeUintegerChecker<uint16_t> (0))
+ .AddTraceSource ("MibReceived",
+ "trace fired upon reception of Master Information Block",
+ MakeTraceSourceAccessor (&LteUeRrc::m_mibReceivedTrace))
+ .AddTraceSource ("Sib1Received",
+ "trace fired upon reception of System Information Block Type 1",
+ MakeTraceSourceAccessor (&LteUeRrc::m_sib1ReceivedTrace))
.AddTraceSource ("StateTransition",
"trace fired upon every UE RRC state transition",
MakeTraceSourceAccessor (&LteUeRrc::m_stateTransitionTrace))
@@ -489,7 +500,8 @@
m_cellId = cellId;
m_dlEarfcn = earfcn;
- m_cphySapProvider->SyncronizeWithEnb (m_cellId, m_dlEarfcn);
+ m_cphySapProvider->SyncronizeWithEnb (m_cellId, m_dlEarfcn);
+ m_cphySapProvider->Attach ();
SwitchToState (IDLE_WAIT_SYSTEM_INFO);
}
@@ -535,9 +547,36 @@
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_CELL_SELECTION && m_receivedMib && m_receivedSib1)
+ {
+ InitialCellSelection ();
+ }
+
+ if (m_state == IDLE_WAIT_SYSTEM_INFO && m_receivedMib && m_receivedSib2)
+ {
+ SwitchToState (IDLE_CAMPED_NORMALLY);
+ }
+}
+
+void
+LteUeRrc::DoRecvSystemInformationBlockType1 (LteRrcSap::SystemInformationBlockType1 msg)
+{
+ NS_LOG_FUNCTION (this);
+ m_receivedSib1 = true;
+ m_lastSib1 = msg;
+ m_sib1ReceivedTrace (m_imsi, m_cellId, m_rnti);
+
+ if (m_state == IDLE_CELL_SELECTION && m_receivedMib && m_receivedSib1)
+ {
+ InitialCellSelection ();
+ }
+
if (m_state == IDLE_WAIT_SYSTEM_INFO && m_receivedMib && m_receivedSib2)
{
SwitchToState (IDLE_CAMPED_NORMALLY);
@@ -581,14 +620,6 @@
void
-LteUeRrc::DoRecvSystemInformationBlockType1 (LteRrcSap::SystemInformationBlockType1 msg)
-{
- NS_LOG_FUNCTION (this);
- // to be implemented
-}
-
-
-void
LteUeRrc::DoRecvSystemInformation (LteRrcSap::SystemInformation msg)
{
NS_LOG_FUNCTION (this);
@@ -756,6 +787,25 @@
+void
+LteUeRrc::InitialCellSelection ()
+{
+ NS_LOG_FUNCTION (this);
+ uint16_t cellId = m_lastSib1.cellAccessRelatedInfo.cellIdentity;
+ // TODO evaluate cell selection criteria
+ // TODO if passed, camp to that cell and switch to IDLE_CAMPED_NORMALLY
+ // TODO if not, call m_cphySapProvider->RetryCellSearch
+ // TODO if retry timeout is exceeded, stop the procedure here (in reality UE will connect to an acceptable cell, but we don't model it here)
+
+ m_cellId = cellId;
+ m_cphySapProvider->SyncronizeWithEnb (m_cellId, 100); // TODO hardcoded value
+ m_cphySapProvider->SetDlBandwidth (m_dlBandwidth);
+ m_cphySapProvider->Attach ();
+ SwitchToState (IDLE_CAMPED_NORMALLY);
+
+}
+
+
void
LteUeRrc::ApplyRadioResourceConfigDedicated (LteRrcSap::RadioResourceConfigDedicated rrcd)
{
--- a/src/lte/model/lte-ue-rrc.h Wed Jul 10 14:59:00 2013 +0300
+++ b/src/lte/model/lte-ue-rrc.h Tue Jul 16 09:43:01 2013 +0300
@@ -264,11 +264,11 @@
// CPHY SAP methods
void DoRecvMasterInformationBlock (LteRrcSap::MasterInformationBlock msg);
+ void DoRecvSystemInformationBlockType1 (LteRrcSap::SystemInformationBlockType1 msg);
void DoReportUeMeasurements (LteUeCphySapUser::UeMeasurementsParameters params);
// RRC SAP methods
void DoCompleteSetup (LteUeRrcSapProvider::CompleteSetupParameters params);
- void DoRecvSystemInformationBlockType1 (LteRrcSap::SystemInformationBlockType1 msg);
void DoRecvSystemInformation (LteRrcSap::SystemInformation msg);
void DoRecvRrcConnectionSetup (LteRrcSap::RrcConnectionSetup msg);
void DoRecvRrcConnectionReconfiguration (LteRrcSap::RrcConnectionReconfiguration msg);
@@ -279,6 +279,7 @@
// internal methods
+ void InitialCellSelection ();
void ApplyRadioResourceConfigDedicated (LteRrcSap::RadioResourceConfigDedicated rrcd);
/// 3GPP TS 36.331 section 5.5.2 Measurement configuration
void ApplyMeasConfig (LteRrcSap::MeasConfig mc);
@@ -322,6 +323,8 @@
Ptr<LteSignalingRadioBearerInfo> m_srb1Old;
std::map <uint8_t, Ptr<LteDataRadioBearerInfo> > m_drbMap;
+ uint8_t m_cellSearchRetryTimeout;
+
bool m_useRlcSm;
uint8_t m_lastRrcTransactionIdentifier;
@@ -333,6 +336,10 @@
uint16_t m_ulEarfcn; /**< uplink carrier frequency */
// imsi cellid rnti
+ TracedCallback<uint64_t, uint16_t, uint16_t> m_mibReceivedTrace;
+ // imsi cellid rnti
+ TracedCallback<uint64_t, uint16_t, uint16_t> m_sib1ReceivedTrace;
+ // imsi cellid rnti
TracedCallback<uint64_t, uint16_t, uint16_t, State, State> m_stateTransitionTrace;
// imsi cellid rnti
TracedCallback<uint64_t, uint16_t, uint16_t> m_randomAccessSuccessfulTrace;
@@ -347,8 +354,10 @@
bool m_connectionPending; /**< true if a connection request by upper layers is pending */
bool m_receivedMib; /**< true if MIB was received for the current cell */
+ bool m_receivedSib1; /**< true if SIB1 was received for the current cell */
bool m_receivedSib2; /**< true if SIB2 was received for the current cell */
+ LteRrcSap::SystemInformationBlockType1 m_lastSib1;
/**
* \brief Includes the accumulated configuration of the measurements to be
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lte/test/lte-test-cell-selection.cc Tue Jul 16 09:43:01 2013 +0300
@@ -0,0 +1,276 @@
+/* -*- 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 <buherman@student.jyu.fi>
+ *
+ */
+
+#include "lte-test-cell-selection.h"
+
+#include <ns3/simulator.h>
+#include <ns3/log.h>
+#include <ns3/boolean.h>
+
+#include <ns3/mobility-helper.h>
+#include <ns3/lte-helper.h>
+#include <ns3/epc-helper.h>
+#include <ns3/internet-stack-helper.h>
+#include <ns3/point-to-point-helper.h>
+#include <ns3/ipv4-address-helper.h>
+#include <ns3/ipv4-static-routing-helper.h>
+
+#include <ns3/node-container.h>
+#include <ns3/net-device-container.h>
+#include <ns3/ipv4-interface-container.h>
+
+#include <ns3/lte-enb-net-device.h>
+#include <ns3/lte-ue-net-device.h>
+
+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 ("LteUePhy", LOG_WARN);
+ //LogComponentEnable ("LteUePhy", LOG_DEBUG);
+ //LogComponentEnable ("LteUePhy", LOG_FUNCTION);
+ //LogComponentEnable ("LteSpectrumPhy", LOG_LOGIC);
+ //LogComponentEnable ("LteSpectrumPhy", LOG_FUNCTION);
+ //LogComponentEnable ("LteEnbPhy", LOG_FUNCTION);
+ LogComponentEnable ("LteUeRrc", LOG_FUNCTION);
+
+ std::vector<LteCellSelectionTestCase::UeSetup_t> 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<UeSetup_t> 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> lteHelper = CreateObject<LteHelper> ();
+ lteHelper->SetAttribute ("PathlossModel",
+ StringValue ("ns3::FriisSpectrumPropagationLossModel"));
+ lteHelper->SetAttribute ("UseIdealRrc", BooleanValue (true));
+
+ Ptr<EpcHelper> epcHelper;
+
+ if (m_isEpcMode)
+ {
+ epcHelper = CreateObject<EpcHelper> ();
+ lteHelper->SetEpcHelper (epcHelper);
+ }
+
+ /*
+ * 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<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator> ();
+ 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<UeSetup_t>::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)
+ {
+ // Create P-GW node
+ Ptr<Node> pgw = epcHelper->GetPgwNode ();
+
+ // Create a single RemoteHost
+ NodeContainer remoteHostContainer;
+ remoteHostContainer.Create (1);
+ Ptr<Node> 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<Ipv4StaticRouting> remoteHostStaticRouting = ipv4RoutingHelper.GetStaticRouting (remoteHost->GetObject<Ipv4> ());
+ 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<Node> ueNode = ueNodes.Get (u);
+ // Set the default gateway for the UE
+ Ptr<Ipv4StaticRouting> ueStaticRouting = ipv4RoutingHelper.GetStaticRouting (ueNode->GetObject<Ipv4> ());
+ ueStaticRouting->SetDefaultRoute (epcHelper->GetUeDefaultGatewayAddress (), 1);
+ }
+
+ // // TODO remove this
+ //lteHelper->Attach (ueDevs, enbDevs.Get (0));
+
+ } // 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/MibReceived",
+ MakeCallback (&LteCellSelectionTestCase::MibReceivedCallback,
+ this));
+
+ // Connect to trace sources in UEs
+ Config::Connect ("/NodeList/*/DeviceList/*/LteUeRrc/Sib1Received",
+ MakeCallback (&LteCellSelectionTestCase::Sib1ReceivedCallback,
+ this));
+
+ // Run simulation
+ Simulator::Stop (MilliSeconds (400));
+ Simulator::Run ();
+ Simulator::Destroy ();
+
+ // Tests
+
+ // TODO
+
+} // end of void LteCellSelectionTestCase::DoRun ()
+
+
+void
+LteCellSelectionTestCase::MibReceivedCallback (
+ std::string context, uint64_t imsi, uint16_t cellId, uint16_t rnti)
+{
+ NS_LOG_FUNCTION (this << context << imsi << cellId << rnti);
+}
+
+
+void
+LteCellSelectionTestCase::Sib1ReceivedCallback (
+ std::string context, uint64_t imsi, uint16_t cellId, uint16_t rnti)
+{
+ NS_LOG_FUNCTION (this << context << imsi << cellId << rnti);
+}
+
+
+} // end of namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lte/test/lte-test-cell-selection.h Tue Jul 16 09:43:01 2013 +0300
@@ -0,0 +1,105 @@
+/* -*- 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 <buherman@student.jyu.fi>
+ *
+ */
+
+#ifndef LTE_TEST_CELL_SELECTION_H
+#define LTE_TEST_CELL_SELECTION_H
+
+#include <ns3/test.h>
+#include <ns3/node-container.h>
+#include <ns3/vector.h>
+#include <vector>
+
+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<UeSetup_t> 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 MibReceivedCallback (std::string context, uint64_t imsi,
+ uint16_t cellId, uint16_t rnti);
+ void Sib1ReceivedCallback (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<UeSetup_t> m_ueSetupList;
+
+}; // end of class LteCellSelectionTestCase
+
+
+} // end of namespace ns3
+
+
+#endif /* LTE_TEST_CELL_SELECTION_H */
--- a/src/lte/wscript Wed Jul 10 14:59:00 2013 +0300
+++ b/src/lte/wscript Tue Jul 16 09:43:01 2013 +0300
@@ -142,6 +142,7 @@
'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',
]