--- a/src/lte/helper/lte-helper.cc Mon Aug 12 09:29:23 2013 +0300
+++ b/src/lte/helper/lte-helper.cc Mon Aug 12 11:25:23 2013 +0300
@@ -44,6 +44,7 @@
#include <ns3/lte-ue-net-device.h>
#include <ns3/ff-mac-scheduler.h>
#include <ns3/handover-algorithm.h>
+#include <ns3/lte-anr.h>
#include <ns3/lte-rlc.h>
#include <ns3/lte-rlc-um.h>
#include <ns3/lte-rlc-am.h>
@@ -391,6 +392,7 @@
Ptr<LteEnbMac> mac = CreateObject<LteEnbMac> ();
Ptr<FfMacScheduler> sched = m_schedulerFactory.Create<FfMacScheduler> ();
Ptr<HandoverAlgorithm> handoverAlgorithm = m_handoverAlgorithmFactory.Create<HandoverAlgorithm> ();
+ Ptr<LteAnr> anr = CreateObject<LteAnr> ();
Ptr<LteEnbRrc> rrc = CreateObject<LteEnbRrc> ();
if (m_useIdealRrc)
@@ -428,6 +430,9 @@
rrc->SetHandoverManagementSapProvider (handoverAlgorithm->GetHandoverManagementSapProvider ());
handoverAlgorithm->SetHandoverManagementSapUser (rrc->GetHandoverManagementSapUser ());
+ rrc->SetLteAnrSapProvider (anr->GetLteAnrSapProvider ());
+ anr->SetLteAnrSapUser (rrc->GetLteAnrSapUser ());
+
mac->SetFfMacSchedSapProvider (sched->GetFfMacSchedSapProvider ());
mac->SetFfMacCschedSapProvider (sched->GetFfMacCschedSapProvider ());
@@ -437,7 +442,6 @@
phy->SetLteEnbPhySapUser (mac->GetLteEnbPhySapUser ());
mac->SetLteEnbPhySapProvider (phy->GetLteEnbPhySapProvider ());
-
phy->SetLteEnbCphySapUser (rrc->GetLteEnbCphySapUser ());
rrc->SetLteEnbCphySapProvider (phy->GetLteEnbCphySapProvider ());
@@ -449,6 +453,7 @@
dev->SetAttribute ("FfMacScheduler", PointerValue (sched));
dev->SetAttribute ("LteEnbRrc", PointerValue (rrc));
dev->SetAttribute ("HandoverAlgorithm", PointerValue (handoverAlgorithm));
+ dev->SetAttribute ("LteAnr", PointerValue (anr));
phy->SetDevice (dev);
dlPhy->SetDevice (dev);
@@ -858,7 +863,7 @@
uint16_t targetCellId = targetEnbDev->GetObject<LteEnbNetDevice> ()->GetCellId ();
Ptr<LteEnbRrc> sourceRrc = sourceEnbDev->GetObject<LteEnbNetDevice> ()->GetRrc ();
uint16_t rnti = ueDev->GetObject<LteUeNetDevice> ()->GetRrc ()->GetRnti ();
- sourceRrc->SendHandoverRequest (rnti, targetCellId);
+ sourceRrc->SendHandoverRequest (rnti, targetCellId);
}
@@ -869,7 +874,7 @@
LteHelper::ActivateDataRadioBearer (NetDeviceContainer ueDevices, EpsBearer bearer)
{
NS_LOG_FUNCTION (this);
- for (NetDeviceContainer::Iterator i = ueDevices.Begin (); i != ueDevices.End (); ++i)
+ for (NetDeviceContainer::Iterator i = ueDevices.Begin (); i != ueDevices.End (); ++i)
{
ActivateDataRadioBearer (*i, bearer);
}
--- a/src/lte/model/a2-rsrq-handover-algorithm.cc Mon Aug 12 09:29:23 2013 +0300
+++ b/src/lte/model/a2-rsrq-handover-algorithm.cc Mon Aug 12 11:25:23 2013 +0300
@@ -101,10 +101,11 @@
.SetParent<HandoverAlgorithm> ()
.AddConstructor<A2RsrqHandoverAlgorithm> ()
.AddAttribute ("ServingCellThreshold",
- "If serving cell is worse than this threshold, neighbour cells are consider for Handover",
+ "If the RSRQ of the serving cell is worse than this threshold, "
+ "neighbour cells are consider for handover",
UintegerValue (30),
MakeUintegerAccessor (&A2RsrqHandoverAlgorithm::m_servingCellThreshold),
- MakeUintegerChecker<uint8_t> ())
+ MakeUintegerChecker<uint8_t> (0, 34)) // RSRQ range is [0..34] as per Section 9.1.7 of 3GPP TS 36.133
.AddAttribute ("NeighbourCellOffset",
"Minimum offset between serving and best neighbour cell to trigger the Handover",
UintegerValue (1),
@@ -142,7 +143,7 @@
reportConfigA2.threshold1.range = m_servingCellThreshold;
reportConfigA2.triggerQuantity = LteRrcSap::ReportConfigEutra::RSRQ;
reportConfigA2.reportInterval = LteRrcSap::ReportConfigEutra::MS240;
- m_a2measId = m_handoverManagementSapUser->AddUeMeasReportConfig (reportConfigA2);
+ m_a2measId = m_handoverManagementSapUser->AddUeMeasReportConfigForHandover (reportConfigA2);
LteRrcSap::ReportConfigEutra reportConfigA4;
reportConfigA4.eventId = LteRrcSap::ReportConfigEutra::EVENT_A4;
@@ -150,7 +151,7 @@
reportConfigA4.threshold1.range = 0; // intentionally very low threshold
reportConfigA4.triggerQuantity = LteRrcSap::ReportConfigEutra::RSRQ;
reportConfigA4.reportInterval = LteRrcSap::ReportConfigEutra::MS480;
- m_a4measId = m_handoverManagementSapUser->AddUeMeasReportConfig (reportConfigA4);
+ m_a4measId = m_handoverManagementSapUser->AddUeMeasReportConfigForHandover (reportConfigA4);
HandoverAlgorithm::DoInitialize ();
}
--- a/src/lte/model/handover-management-sap.h Mon Aug 12 09:29:23 2013 +0300
+++ b/src/lte/model/handover-management-sap.h Mon Aug 12 11:25:23 2013 +0300
@@ -42,8 +42,10 @@
* where the report originates from
* \param measResults a single report of one measurement identity
*
- * The received measurement report may be stored and utilized for the purpose
- * of making handover decision.
+ * The received measurement report is a result of the UE measurement
+ * configuration previously configured by calling
+ * HandoverManagementSapUser::AddUeMeasReportConfigForHandover. The report
+ * may be stored and utilized for the purpose of making handover decision.
*/
virtual void ReportUeMeas (uint16_t rnti,
LteRrcSap::MeasResults measResults) = 0;
@@ -76,7 +78,7 @@
*
* This function is only valid before the simulation begins.
*/
- virtual uint8_t AddUeMeasReportConfig (LteRrcSap::ReportConfigEutra reportConfig) = 0;
+ virtual uint8_t AddUeMeasReportConfigForHandover (LteRrcSap::ReportConfigEutra reportConfig) = 0;
/**
* \brief Instruct the eNodeB RRC entity to prepare a handover.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lte/model/lte-anr-sap.cc Mon Aug 12 11:25:23 2013 +0300
@@ -0,0 +1,38 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2013 University of Jyvaskyla
+ *
+ * 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-anr-sap.h"
+
+
+namespace ns3 {
+
+
+LteAnrSapProvider::~LteAnrSapProvider ()
+{
+}
+
+
+LteAnrSapUser::~LteAnrSapUser ()
+{
+}
+
+
+} // end of namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lte/model/lte-anr-sap.h Mon Aug 12 11:25:23 2013 +0300
@@ -0,0 +1,233 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2013 University of Jyvaskyla
+ *
+ * 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_ANR_SAP_H
+#define LTE_ANR_SAP_H
+
+#include <ns3/lte-rrc-sap.h>
+
+namespace ns3 {
+
+
+/**
+ * \brief Service Access Point (SAP) offered by the Automatic Neighbour Relation
+ * (ANR) function to the eNodeB RRC instance.
+ *
+ * This is the ANR SAP Provider, i.e., the part of the SAP that contains the ANR
+ * methods called by the eNodeB RRC.
+ */
+class LteAnrSapProvider
+{
+public:
+ virtual ~LteAnrSapProvider ();
+
+ /**
+ * \brief Send a UE measurement report to the ANC instance.
+ * \param measResults a single report of one measurement identity
+ *
+ * The received measurement report is a result of the UE measurement
+ * configuration previously configured by calling
+ * LteAnrSapUser::AddUeMeasReportConfigForAnr. The report may be stored and
+ * utilized for the purpose of maintaining Neighbour Relation Table (NRT).
+ */
+ virtual void ReportUeMeas (LteRrcSap::MeasResults measResults) = 0;
+
+ /**
+ * \brief Add a new Neighbour Relation entry.
+ * \param cellId the Physical Cell ID of the new neighbouring cell
+ */
+ virtual void AddNeighbourRelation (uint16_t cellId) = 0;
+
+ /**
+ * \brief Get the value of *No Remove* field of a neighbouring cell from the
+ * Neighbour Relation Table (NRT).
+ * \param cellId the Physical Cell ID of the neighbouring cell of interest
+ * \return if true, the Neighbour Relation shall *not* be removed from the NRT
+ */
+ virtual bool GetNoRemove (uint16_t cellId) = 0;
+
+ /**
+ * \brief Get the value of *No HO* field of a neighbouring cell from the
+ * Neighbour Relation Table (NRT).
+ * \param cellId the Physical Cell ID of the neighbouring cell of interest
+ * \return if true, the Neighbour Relation shall *not* be used by the eNodeB
+ * for handover reasons
+ */
+ virtual bool GetNoHo (uint16_t cellId) = 0;
+
+ /**
+ * \brief Get the value of *No X2* field of a neighbouring cell from the
+ * Neighbour Relation Table (NRT).
+ * \param cellId the Physical Cell ID of the neighbouring cell of interest
+ * \return if true, the Neighbour Relation shall *not* use an X2 interface in
+ * order to initiate procedures towards the eNodeB parenting the
+ * target cell
+ */
+ virtual bool GetNoX2 (uint16_t cellId) = 0;
+
+}; // end of class LteAnrSapProvider
+
+
+
+/**
+ * \brief Service Access Point (SAP) offered by the eNodeB RRC instance to the
+ * Automatic Neighbour Relation (ANR) function.
+ *
+ * This is the ANR SAP User, i.e., the part of the SAP that contains the eNodeB
+ * RRC methods called by the ANR.
+ */
+class LteAnrSapUser
+{
+public:
+ virtual ~LteAnrSapUser ();
+
+ /**
+ * \brief Request a certain reporting configuration to be fulfilled by the UEs
+ * attached to the eNodeB entity.
+ * \param reportConfig the UE measurement reporting configuration
+ * \return the measurement identity associated with this newly added
+ * reporting configuration
+ *
+ * The eNodeB RRC entity is expected to configure the same reporting
+ * configuration in each of the attached UEs. When later in the simulation a
+ * UE measurement report is received from a UE as a result of this
+ * configuration, the eNodeB RRC entity shall forward this report to the ANC
+ * instance through the LteAnrSapProvider::ReportUeMeas SAP function.
+ *
+ * This function is only valid before the simulation begins.
+ */
+ virtual uint8_t AddUeMeasReportConfigForAnr (LteRrcSap::ReportConfigEutra reportConfig) = 0;
+
+}; // end of class LteAnrSapUser
+
+
+
+/**
+ * \brief Template for the implementation of the LteAnrSapProvider as a member
+ * of an owner class of type C to which all methods are forwarded.
+ */
+template <class C>
+class MemberLteAnrSapProvider : public LteAnrSapProvider
+{
+public:
+ MemberLteAnrSapProvider (C* owner);
+
+ // inherited from LteAnrSapProvider
+ virtual void ReportUeMeas (LteRrcSap::MeasResults measResults);
+ virtual void AddNeighbourRelation (uint16_t cellId);
+ virtual bool GetNoRemove (uint16_t cellId);
+ virtual bool GetNoHo (uint16_t cellId);
+ virtual bool GetNoX2 (uint16_t cellId);
+
+private:
+ MemberLteAnrSapProvider ();
+ C* m_owner;
+
+}; // end of class MemberLteAnrSapProvider
+
+
+template <class C>
+MemberLteAnrSapProvider<C>::MemberLteAnrSapProvider (C* owner)
+ : m_owner (owner)
+{
+}
+
+
+template <class C>
+void
+MemberLteAnrSapProvider<C>::ReportUeMeas (LteRrcSap::MeasResults measResults)
+{
+ m_owner->DoReportUeMeas (measResults);
+}
+
+
+template <class C>
+void
+MemberLteAnrSapProvider<C>::AddNeighbourRelation (uint16_t cellId)
+{
+ m_owner->DoAddNeighbourRelation (cellId);
+}
+
+
+template <class C>
+bool
+MemberLteAnrSapProvider<C>::GetNoRemove (uint16_t cellId)
+{
+ return m_owner->DoGetNoRemove (cellId);
+}
+
+
+template <class C>
+bool
+MemberLteAnrSapProvider<C>::GetNoHo (uint16_t cellId)
+{
+ return m_owner->DoGetNoHo (cellId);
+}
+
+
+template <class C>
+bool
+MemberLteAnrSapProvider<C>::GetNoX2 (uint16_t cellId)
+{
+ return m_owner->DoGetNoX2 (cellId);
+}
+
+
+
+/**
+ * \brief Template for the implementation of the LteAnrSapUser as a member of an
+ * owner class of type C to which all methods are forwarded.
+ */
+template <class C>
+class MemberLteAnrSapUser : public LteAnrSapUser
+{
+public:
+ MemberLteAnrSapUser (C* owner);
+
+ // inherited from LteAnrSapUser
+ virtual uint8_t AddUeMeasReportConfigForAnr (LteRrcSap::ReportConfigEutra reportConfig);
+
+private:
+ MemberLteAnrSapUser ();
+ C* m_owner;
+
+}; // end of class MemberLteAnrSapUser
+
+
+template <class C>
+MemberLteAnrSapUser<C>::MemberLteAnrSapUser (C* owner)
+ : m_owner (owner)
+{
+}
+
+
+template <class C>
+uint8_t
+MemberLteAnrSapUser<C>::AddUeMeasReportConfigForAnr (LteRrcSap::ReportConfigEutra reportConfig)
+{
+ return m_owner->DoAddUeMeasReportConfigForAnr (reportConfig);
+}
+
+
+} // end of namespace ns3
+
+
+#endif /* LTE_ANR_SAP_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lte/model/lte-anr.cc Mon Aug 12 11:25:23 2013 +0300
@@ -0,0 +1,236 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2013 University of Jyvaskyla
+ *
+ * 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-anr.h"
+#include <ns3/log.h>
+#include <ns3/uinteger.h>
+
+NS_LOG_COMPONENT_DEFINE ("LteAnr");
+
+namespace ns3 {
+
+NS_OBJECT_ENSURE_REGISTERED (LteAnr);
+
+
+LteAnr::LteAnr ()
+ : m_anrSapUser (0),
+ m_threshold (0),
+ m_measId (0)
+{
+ m_anrSapProvider = new MemberLteAnrSapProvider<LteAnr> (this);
+}
+
+
+LteAnr::~LteAnr ()
+{
+}
+
+
+void
+LteAnr::DoDispose ()
+{
+ delete m_anrSapProvider;
+ m_neighbourRelationTable.clear ();
+}
+
+
+TypeId
+LteAnr::GetTypeId (void)
+{
+ static TypeId tid = TypeId ("ns3::LteAnr")
+ .SetParent<Object> ()
+ .AddConstructor<LteAnr> ()
+ .AddAttribute ("Threshold",
+ "Minimum RSRQ range value required for detecting a neighbour cell",
+ UintegerValue (0),
+ MakeUintegerAccessor (&LteAnr::m_threshold),
+ MakeUintegerChecker<uint8_t> (0, 34)) // RSRQ range is [0..34] as per Section 9.1.7 of 3GPP TS 36.133
+ ;
+ return tid;
+}
+
+
+void
+LteAnr::AddNeighbourRelation (uint16_t cellId)
+{
+ NS_LOG_FUNCTION (this << cellId);
+
+ if (m_neighbourRelationTable.find (cellId) != m_neighbourRelationTable.end ())
+ {
+ NS_FATAL_ERROR ("There is already an entry in the NRT for cell ID " << cellId);
+ }
+
+ NeighbourRelation_t neighbourRelation;
+ neighbourRelation.noRemove = true;
+ neighbourRelation.noHo = true;
+ neighbourRelation.noX2 = false;
+ neighbourRelation.detectedAsNeighbour = false;
+ m_neighbourRelationTable[cellId] = neighbourRelation;
+}
+
+
+void
+LteAnr::RemoveNeighbourRelation (uint16_t cellId)
+{
+ NS_LOG_FUNCTION (this << cellId);
+
+ NeighbourRelationTable_t::iterator it = m_neighbourRelationTable.find (cellId);
+ if (it != m_neighbourRelationTable.end ())
+ {
+ NS_FATAL_ERROR ("Cell ID " << cellId << " cannot be found in NRT");
+ }
+
+ m_neighbourRelationTable.erase (it);
+}
+
+
+void
+LteAnr::SetLteAnrSapUser (LteAnrSapUser* s)
+{
+ m_anrSapUser = s;
+}
+
+
+LteAnrSapProvider*
+LteAnr::GetLteAnrSapProvider ()
+{
+ return m_anrSapProvider;
+}
+
+
+void
+LteAnr::DoInitialize ()
+{
+ LteRrcSap::ReportConfigEutra reportConfig;
+ reportConfig.eventId = LteRrcSap::ReportConfigEutra::EVENT_A4;
+ reportConfig.threshold1.choice = LteRrcSap::ThresholdEutra::THRESHOLD_RSRQ;
+ reportConfig.threshold1.range = m_threshold;
+ reportConfig.triggerQuantity = LteRrcSap::ReportConfigEutra::RSRQ;
+ reportConfig.reportInterval = LteRrcSap::ReportConfigEutra::MS480;
+ m_measId = m_anrSapUser->AddUeMeasReportConfigForAnr (reportConfig);
+}
+
+
+void
+LteAnr::DoReportUeMeas (LteRrcSap::MeasResults measResults)
+{
+ uint8_t measId = measResults.measId;
+ NS_LOG_FUNCTION (this << (uint16_t) measId);
+
+ if (measId != m_measId)
+ {
+ NS_LOG_WARN (this << " Skipping unexpected measurement identity " << (uint16_t) measId);
+ }
+ else
+ {
+ if (measResults.haveMeasResultNeighCells
+ && !(measResults.measResultListEutra.empty ()))
+ {
+ for (std::list <LteRrcSap::MeasResultEutra>::iterator it = measResults.measResultListEutra.begin ();
+ it != measResults.measResultListEutra.end ();
+ ++it)
+ {
+ // Keep new RSRQ value reported for the neighbour cell
+ NS_ASSERT_MSG (it->haveRsrqResult == true,
+ "RSRQ measure missing for cellId " << it->physCellId);
+
+ // Update Neighbour Relation Table
+ if (m_neighbourRelationTable.find (it->physCellId) != m_neighbourRelationTable.end ())
+ {
+ // Update neighbour info
+ NeighbourRelation_t neighbourRelation = m_neighbourRelationTable[it->physCellId];
+
+ if (neighbourRelation.noX2 == false)
+ {
+ neighbourRelation.noHo = false;
+ }
+ neighbourRelation.detectedAsNeighbour = true;
+ }
+ else // new neighbour
+ {
+ NeighbourRelation_t neighbourRelation;
+ neighbourRelation.noRemove = false;
+ neighbourRelation.noHo = true;
+ neighbourRelation.noX2 = true;
+ neighbourRelation.detectedAsNeighbour = true;
+ m_neighbourRelationTable[it->physCellId] = neighbourRelation;
+ }
+
+ } // end of for (it = measResults.measResultListEutra.begin ())
+
+ } // end of if (measResults.haveMeasResultNeighCells && !(measResults.measResultListEutra.empty ()))
+ else
+ {
+ NS_LOG_LOGIC ("WARNING");
+ // NS_ASSERT_MSG ("Event A4 received without measure results for neighbour cells");
+ // TODO Remove neighbours in the neighbourCellMeasures table
+ }
+
+ } // end of else of if (measId != m_measId)
+
+} // end of DoReportUeMeas
+
+
+void
+LteAnr::DoAddNeighbourRelation (uint16_t cellId)
+{
+ AddNeighbourRelation (cellId);
+}
+
+
+bool
+LteAnr::DoGetNoRemove (uint16_t cellId)
+{
+ NS_LOG_FUNCTION (this << cellId);
+ return Find (cellId)->noRemove;
+}
+
+
+bool
+LteAnr::DoGetNoHo (uint16_t cellId)
+{
+ NS_LOG_FUNCTION (this << cellId);
+ return Find (cellId)->noHo;
+}
+
+
+bool
+LteAnr::DoGetNoX2 (uint16_t cellId)
+{
+ NS_LOG_FUNCTION (this << cellId);
+ return Find (cellId)->noX2;
+}
+
+
+LteAnr::NeighbourRelation_t *
+LteAnr::Find (uint16_t cellId)
+{
+ NeighbourRelationTable_t::iterator it = m_neighbourRelationTable.find (cellId);
+ if (it == m_neighbourRelationTable.end ())
+ {
+ NS_FATAL_ERROR ("Cell ID " << cellId << " cannot be found in NRT");
+ }
+ return &(it->second);
+}
+
+
+} // end of namespace ns3
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lte/model/lte-anr.h Mon Aug 12 11:25:23 2013 +0300
@@ -0,0 +1,140 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2013 University of Jyvaskyla
+ *
+ * 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_ANR_H
+#define LTE_ANR_H
+
+#include <ns3/object.h>
+#include <ns3/lte-rrc-sap.h>
+#include <ns3/lte-anr-sap.h>
+#include <map>
+
+namespace ns3 {
+
+
+class LteAnrSapProvider;
+class LteAnrSapUser;
+class LteNeighbourRelation;
+
+/**
+ * \brief Automatic Neighbour Relation function.
+ *
+ * Based on Section 22.3.2a and 22.3.3 of 3GPP TS 36.300.
+ */
+class LteAnr : public Object
+{
+public:
+ LteAnr ();
+ virtual ~LteAnr ();
+
+ // inherited from Object
+ virtual void DoDispose (void);
+ static TypeId GetTypeId (void);
+
+ /**
+ * \brief Provide an advance information about a related neighbouring cell
+ * and add it as a new Neighbour Relation entry.
+ *
+ * This function simulates the Neighbour Relation addition operation by
+ * network operations and maintenance, as depicted in Section 22.3.2a of
+ * 3GPP TS 36.300.
+ *
+ * An entry added by this function will have NoRemove flag set to TRUE and
+ * NoHo flag set to TRUE. Hence, the cell may not act as the targel cell of a
+ * handover, unless a measurement report of the cell is received, which will
+ * update the NoHo flag to FALSE.
+ */
+ void AddNeighbourRelation (uint16_t cellId);
+
+ /**
+ * \brief Remove an existing Neighbour Relation entry.
+ *
+ * This function simulates the Neighbour Relation removal operation by
+ * network operations and maintenance, as depicted in Section 22.3.2a of
+ * 3GPP TS 36.300.
+ */
+ void RemoveNeighbourRelation (uint16_t cellId);
+
+ /**
+ * \brief Set the user part of the LteAnrSap that this ANR instance will
+ * interact with. Normally this part of the SAP is exported by the
+ * eNodeB RRC.
+ * \param s
+ */
+ virtual void SetLteAnrSapUser (LteAnrSapUser* s);
+
+ /**
+ *
+ * \return the Provider part of the LteAnrSap provided by the ANR instance
+ */
+ virtual LteAnrSapProvider* GetLteAnrSapProvider ();
+
+ friend class MemberLteAnrSapProvider<LteAnr>;
+
+protected:
+ // inherited from Object
+ virtual void DoInitialize ();
+
+private:
+ // ANR SAP provider implementation
+ void DoReportUeMeas (LteRrcSap::MeasResults measResults);
+ void DoAddNeighbourRelation (uint16_t cellId);
+ bool DoGetNoRemove (uint16_t cellId);
+ bool DoGetNoHo (uint16_t cellId);
+ bool DoGetNoX2 (uint16_t cellId);
+
+ // ANR SAPs
+ LteAnrSapUser* m_anrSapUser;
+ LteAnrSapProvider* m_anrSapProvider;
+
+ // Class Attributes
+ uint8_t m_threshold;
+
+ /**
+ * \brief Neighbour Relation between two eNodeBs (serving eNodeB and neighbour
+ * eNodeB).
+ */
+ struct NeighbourRelation_t
+ {
+ bool noRemove;
+ bool noHo;
+ bool noX2;
+ bool detectedAsNeighbour;
+ };
+
+ // cellId
+ typedef std::map<uint16_t, NeighbourRelation_t> NeighbourRelationTable_t;
+
+ NeighbourRelationTable_t m_neighbourRelationTable;
+
+ // internal methods
+ NeighbourRelation_t* Find (uint16_t cellId);
+
+ // The expected measurement identity
+ uint8_t m_measId;
+
+}; // end of class LteAnr
+
+
+} // end of namespace ns3
+
+
+#endif /* LTE_ANR_H */
--- a/src/lte/model/lte-enb-net-device.cc Mon Aug 12 09:29:23 2013 +0300
+++ b/src/lte/model/lte-enb-net-device.cc Mon Aug 12 11:25:23 2013 +0300
@@ -39,6 +39,7 @@
#include <ns3/lte-enb-phy.h>
#include <ns3/ff-mac-scheduler.h>
#include <ns3/handover-algorithm.h>
+#include <ns3/lte-anr.h>
#include <ns3/ipv4-l3-protocol.h>
#include <ns3/abort.h>
#include <ns3/log.h>
@@ -66,6 +67,11 @@
PointerValue (),
MakePointerAccessor (&LteEnbNetDevice::m_handoverAlgorithm),
MakePointerChecker <HandoverAlgorithm> ())
+ .AddAttribute ("LteAnr",
+ "The automatic neighbour relation function associated to this EnbNetDevice",
+ PointerValue (),
+ MakePointerAccessor (&LteEnbNetDevice::m_anr),
+ MakePointerChecker <LteAnr> ())
.AddAttribute ("LteEnbMac",
"The MAC associated to this EnbNetDevice",
PointerValue (),
--- a/src/lte/model/lte-enb-net-device.h Mon Aug 12 09:29:23 2013 +0300
+++ b/src/lte/model/lte-enb-net-device.h Mon Aug 12 11:25:23 2013 +0300
@@ -41,6 +41,7 @@
class LteEnbRrc;
class FfMacScheduler;
class HandoverAlgorithm;
+class LteAnr;
/**
@@ -149,6 +150,8 @@
Ptr<HandoverAlgorithm> m_handoverAlgorithm;
+ Ptr<LteAnr> m_anr;
+
uint16_t m_cellId; /**< Cell Identifer. Part of the CGI, see TS 29.274, section 8.21.1 */
uint8_t m_dlBandwidth; /**< downlink bandwidth in RBs */
--- a/src/lte/model/lte-enb-rrc.cc Mon Aug 12 09:29:23 2013 +0300
+++ b/src/lte/model/lte-enb-rrc.cc Mon Aug 12 11:25:23 2013 +0300
@@ -113,7 +113,7 @@
EnbRrcMemberHandoverManagementSapUser (LteEnbRrc* rrc);
// methods inherited from HandoverManagementSapUser go here
- virtual uint8_t AddUeMeasReportConfig (LteRrcSap::ReportConfigEutra reportConfig);
+ virtual uint8_t AddUeMeasReportConfigForHandover (LteRrcSap::ReportConfigEutra reportConfig);
virtual void TriggerHandover (uint16_t rnti, uint16_t targetCellId);
private:
@@ -126,9 +126,9 @@
}
uint8_t
-EnbRrcMemberHandoverManagementSapUser::AddUeMeasReportConfig (LteRrcSap::ReportConfigEutra reportConfig)
+EnbRrcMemberHandoverManagementSapUser::AddUeMeasReportConfigForHandover (LteRrcSap::ReportConfigEutra reportConfig)
{
- return m_rrc->DoAddUeMeasReportConfig (reportConfig);
+ return m_rrc->DoAddUeMeasReportConfigForHandover (reportConfig);
}
void
@@ -140,6 +140,11 @@
+///////////////////////////////////////////
+// UeManager
+///////////////////////////////////////////
+
+
const char* g_ueManagerStateName[UeManager::NUM_STATES] =
{
"INITIAL_RANDOM_ACCESS",
@@ -160,12 +165,6 @@
}
-
-///////////////////////////////////////////
-// UeManager
-///////////////////////////////////////////
-
-
NS_OBJECT_ENSURE_REGISTERED (UeManager);
@@ -971,8 +970,9 @@
void
UeManager::RecvMeasurementReport (LteRrcSap::MeasurementReport msg)
{
- NS_LOG_FUNCTION (this);
- NS_LOG_LOGIC ("measId " << (uint16_t) msg.measResults.measId
+ uint8_t measId = msg.measResults.measId;
+ NS_LOG_FUNCTION (this << (uint16_t) measId);
+ NS_LOG_LOGIC ("measId " << (uint16_t) measId
<< " haveMeasResultNeighCells " << msg.measResults.haveMeasResultNeighCells
<< " measResultListEutra " << msg.measResults.measResultListEutra.size ());
NS_LOG_LOGIC ("serving cellId " << m_rrc->m_cellId
@@ -988,57 +988,18 @@
<< " RSRQ " << (it->haveRsrqResult ? (uint16_t) it->rsrqResult : 255));
}
- /// Event A4 (Neighbour becomes better than threshold)
- if (msg.measResults.measId == 2) // TODO remove this hardcode
+ if (m_rrc->m_handoverMeasIds.find (measId) != m_rrc->m_handoverMeasIds.end ())
{
- // Update the NRT
- if (msg.measResults.haveMeasResultNeighCells
- && !(msg.measResults.measResultListEutra.empty ()))
- {
- for (std::list <LteRrcSap::MeasResultEutra>::iterator it = msg.measResults.measResultListEutra.begin ();
- it != msg.measResults.measResultListEutra.end ();
- ++it)
- {
- // Keep new RSRQ value reported for the neighbour cell
- NS_ASSERT_MSG (it->haveRsrqResult == true, "RSRQ measure missing for cellId " << it->physCellId);
-
- // Update Neighbour Relation Table
- if (m_rrc->m_neighbourRelationTable.find (it->physCellId) != m_rrc->m_neighbourRelationTable.end ())
- {
- // Update neighbour info
- Ptr<NeighbourRelation> neighbourRelation = m_rrc->m_neighbourRelationTable[it->physCellId];
- NS_ASSERT_MSG (neighbourRelation->m_physCellId == it->physCellId,
- "Wrong cellId " << neighbourRelation->m_physCellId);
-
- if (neighbourRelation->m_noX2 == false)
- {
- neighbourRelation->m_noHo = false;
- }
- neighbourRelation->m_detectedAsNeighbour = true;
- }
- else // new neighbour
- {
- Ptr<NeighbourRelation> neighbourRelation = CreateObject <NeighbourRelation> ();
- neighbourRelation->m_physCellId = it->physCellId;
- neighbourRelation->m_noRemove = false;
- neighbourRelation->m_noHo = true;
- neighbourRelation->m_noX2 = true;
- neighbourRelation->m_detectedAsNeighbour = true;
- m_rrc->m_neighbourRelationTable[it->physCellId] = neighbourRelation;
- }
- }
- }
- else
- {
- NS_LOG_LOGIC ("WARNING");
- // NS_ASSERT_MSG ("Event A4 received without measure results for neighbour cells");
- // TODO Remove neighbours in the neighbourCellMeasures table
- }
+ // this measurement was requested by the handover algorithm
+ m_rrc->m_handoverManagementSapProvider->ReportUeMeas (m_rnti,
+ msg.measResults);
}
- // forward the UE measurements report to the active handover algorithm
- m_rrc->m_handoverManagementSapProvider->ReportUeMeas (m_rnti,
- msg.measResults);
+ if (m_rrc->m_anrMeasIds.find (measId) != m_rrc->m_anrMeasIds.end ())
+ {
+ // this measurement was requested by the ANR function
+ m_rrc->m_anrSapProvider->ReportUeMeas (msg.measResults);
+ }
// fire a trace source
m_rrc->m_recvMeasurementReportTrace (m_imsi, m_rrc->m_cellId, m_rnti, msg);
@@ -1312,6 +1273,7 @@
: m_x2SapProvider (0),
m_cmacSapProvider (0),
m_handoverManagementSapProvider (0),
+ m_anrSapProvider (0),
m_rrcSapUser (0),
m_macSapProvider (0),
m_s1SapProvider (0),
@@ -1325,6 +1287,7 @@
NS_LOG_FUNCTION (this);
m_cmacSapUser = new EnbRrcMemberLteEnbCmacSapUser (this);
m_handoverManagementSapUser = new EnbRrcMemberHandoverManagementSapUser (this);
+ m_anrSapUser = new MemberLteAnrSapUser<LteEnbRrc> (this);
m_rrcSapProvider = new MemberLteEnbRrcSapProvider<LteEnbRrc> (this);
m_x2SapUser = new EpcX2SpecificEpcX2SapUser<LteEnbRrc> (this);
m_s1SapUser = new MemberEpcEnbS1SapUser<LteEnbRrc> (this);
@@ -1345,6 +1308,7 @@
m_ueMap.clear ();
delete m_cmacSapUser;
delete m_handoverManagementSapUser;
+ delete m_anrSapUser;
delete m_rrcSapProvider;
delete m_x2SapUser;
delete m_s1SapUser;
@@ -1507,6 +1471,20 @@
}
void
+LteEnbRrc::SetLteAnrSapProvider (LteAnrSapProvider * s)
+{
+ NS_LOG_FUNCTION (this << s);
+ m_anrSapProvider = s;
+}
+
+LteAnrSapUser*
+LteEnbRrc::GetLteAnrSapUser ()
+{
+ NS_LOG_FUNCTION (this);
+ return m_anrSapUser;
+}
+
+void
LteEnbRrc::SetLteEnbRrcSapUser (LteEnbRrcSapUser * s)
{
NS_LOG_FUNCTION (this << s);
@@ -2033,10 +2011,12 @@
uint8_t
-LteEnbRrc::DoAddUeMeasReportConfig (LteRrcSap::ReportConfigEutra reportConfig)
+LteEnbRrc::DoAddUeMeasReportConfigForHandover (LteRrcSap::ReportConfigEutra reportConfig)
{
NS_LOG_FUNCTION (this);
- return AddUeMeasReportConfig (reportConfig);
+ uint8_t measId = AddUeMeasReportConfig (reportConfig);
+ m_handoverMeasIds.insert (measId);
+ return measId;
}
void
@@ -2044,18 +2024,23 @@
{
NS_LOG_FUNCTION (this << rnti << targetCellId);
- std::map<uint16_t, Ptr<NeighbourRelation> >::iterator it;
- it = m_neighbourRelationTable.find (targetCellId);
- NS_ASSERT_MSG (it != m_neighbourRelationTable.end (),
- "Unable to find neighbouring cell with cell ID " << targetCellId);
-
// ensure that proper neighbour relationship exists between source and target cells
- if ((it->second->m_noHo == false) && (it->second->m_noX2 == false))
- {
+ if ((m_anrSapProvider->GetNoHo (targetCellId) == false)
+ && (m_anrSapProvider->GetNoX2 (targetCellId) == false))
+ {
Ptr<UeManager> ueManager = GetUeManager (rnti);
NS_ASSERT_MSG (ueManager != 0, "Cannot find UE context with RNTI " << rnti);
ueManager->PrepareHandover (targetCellId);
- }
+ }
+}
+
+uint8_t
+LteEnbRrc::DoAddUeMeasReportConfigForAnr (LteRrcSap::ReportConfigEutra reportConfig)
+{
+ NS_LOG_FUNCTION (this);
+ uint8_t measId = AddUeMeasReportConfig (reportConfig);
+ m_anrMeasIds.insert (measId);
+ return measId;
}
@@ -2073,7 +2058,7 @@
if ((rnti != 0) && (m_ueMap.find (rnti) == m_ueMap.end ()))
{
found = true;
- break;
+ break;
}
}
@@ -2103,7 +2088,7 @@
}
// need to do this after UeManager has been deleted
RemoveSrsConfigurationIndex (srsCi);
- }
+}
TypeId
LteEnbRrc::GetRlcType (EpsBearer bearer)
@@ -2143,17 +2128,8 @@
void
LteEnbRrc::AddX2Neighbour (uint16_t cellId)
{
- NS_LOG_FUNCTION (cellId);
- NS_ASSERT_MSG (m_neighbourRelationTable.find (cellId) == m_neighbourRelationTable.end (),
- "There is already an entry in the Neighbour Relation Table for cellId " << cellId);
-
- Ptr<NeighbourRelation> neighbourRelation = CreateObject <NeighbourRelation> ();
- neighbourRelation->m_physCellId = cellId;
- neighbourRelation->m_noRemove = true;
- neighbourRelation->m_noHo = true;
- neighbourRelation->m_noX2 = false;
- neighbourRelation->m_detectedAsNeighbour = false;
- m_neighbourRelationTable[cellId] = neighbourRelation;
+ NS_LOG_FUNCTION (this << cellId);
+ m_anrSapProvider->AddNeighbourRelation (cellId);
}
LteRrcSap::SystemInformationBlockType1
--- a/src/lte/model/lte-enb-rrc.h Mon Aug 12 09:29:23 2013 +0300
+++ b/src/lte/model/lte-enb-rrc.h Mon Aug 12 11:25:23 2013 +0300
@@ -34,6 +34,7 @@
#include <ns3/epc-enb-s1-sap.h>
#include <ns3/lte-enb-cphy-sap.h>
#include <ns3/lte-rrc-sap.h>
+#include <ns3/lte-anr-sap.h>
#include <ns3/traced-callback.h>
#include <ns3/event-id.h>
@@ -51,19 +52,6 @@
class LteEnbRrc;
-/**
- * Neighbour Relation between two eNBs (serving eNB and neighbour eNB)
- * See XXXXX for more info
- */
-class NeighbourRelation : public Object
-{
-public:
- uint16_t m_physCellId;
- bool m_noRemove;
- bool m_noHo;
- bool m_noX2;
- bool m_detectedAsNeighbour;
-};
/**
* Measurements reported by a UE for a cellId
@@ -440,6 +428,8 @@
class HandoverManagementSapProvider;
class HandoverManagementSapUser;
+class LteAnrSapProvider;
+class LteAnrSapUser;
/**
@@ -452,6 +442,7 @@
friend class EnbRrcMemberLteEnbCmacSapUser;
friend class EnbRrcMemberHandoverManagementSapUser;
+ friend class MemberLteAnrSapUser<LteEnbRrc>;
friend class MemberLteEnbRrcSapProvider<LteEnbRrc>;
friend class MemberEpcEnbS1SapUser<LteEnbRrc>;
friend class EpcX2SpecificEpcX2SapUser<LteEnbRrc>;
@@ -520,6 +511,21 @@
/**
+ * set the ANR SAP this RRC should interact with
+ *
+ * \param s the ANR SAP Provider to be used by this RRC
+ */
+ void SetLteAnrSapProvider (LteAnrSapProvider * s);
+
+ /**
+ * Get the ANR SAP offered by this RRC
+ * \return s the ANR SAP User interface offered to the ANR instance by this
+ * RRC
+ */
+ LteAnrSapUser* GetLteAnrSapUser ();
+
+
+ /**
* set the RRC SAP this RRC should interact with
*
* \param s the RRC SAP User to be used by this RRC
@@ -705,7 +711,7 @@
// RRC SAP methods
-
+
void DoCompleteSetupUe (uint16_t rnti, LteEnbRrcSapProvider::CompleteSetupUeParameters params);
void DoRecvRrcConnectionRequest (uint16_t rnti, LteRrcSap::RrcConnectionRequest msg);
void DoRecvRrcConnectionSetupCompleted (uint16_t rnti, LteRrcSap::RrcConnectionSetupCompleted msg);
@@ -735,12 +741,16 @@
uint16_t DoAllocateTemporaryCellRnti ();
void DoNotifyLcConfigResult (uint16_t rnti, uint8_t lcid, bool success);
void DoRrcConfigurationUpdateInd (LteEnbCmacSapUser::UeConfig params);
-
+
// Handover Management SAP methods
- uint8_t DoAddUeMeasReportConfig (LteRrcSap::ReportConfigEutra reportConfig);
+ uint8_t DoAddUeMeasReportConfigForHandover (LteRrcSap::ReportConfigEutra reportConfig);
void DoTriggerHandover (uint16_t rnti, uint16_t targetCellId);
+ // ANR SAP methods
+
+ uint8_t DoAddUeMeasReportConfigForAnr (LteRrcSap::ReportConfigEutra reportConfig);
+
// Internal methods
@@ -867,6 +877,9 @@
HandoverManagementSapUser* m_handoverManagementSapUser;
HandoverManagementSapProvider* m_handoverManagementSapProvider;
+ LteAnrSapUser* m_anrSapUser;
+ LteAnrSapProvider* m_anrSapProvider;
+
LteEnbRrcSapUser* m_rrcSapUser;
LteEnbRrcSapProvider* m_rrcSapProvider;
@@ -897,6 +910,9 @@
*/
LteRrcSap::MeasConfig m_ueMeasConfig;
+ std::set<uint8_t> m_handoverMeasIds;
+ std::set<uint8_t> m_anrMeasIds;
+
struct X2uTeidInfo
{
uint16_t rnti;
@@ -932,10 +948,6 @@
Time m_handoverJoiningTimeoutDuration;
Time m_handoverLeavingTimeoutDuration;
- // cellid
- std::map<uint16_t, Ptr<NeighbourRelation> > m_neighbourRelationTable;
-
-
// cellid rnti
TracedCallback<uint16_t, uint16_t> m_newUeContextTrace;
// imsi cellid rnti
--- a/src/lte/wscript Mon Aug 12 09:29:23 2013 +0300
+++ b/src/lte/wscript Mon Aug 12 11:25:23 2013 +0300
@@ -101,6 +101,8 @@
'model/handover-management-sap.cc',
'model/handover-algorithm.cc',
'model/a2-rsrq-handover-algorithm.cc',
+ 'model/lte-anr-sap.cc',
+ 'model/lte-anr.cc',
]
module_test = bld.create_ns3_module_test_library('lte')
@@ -249,6 +251,8 @@
'model/handover-management-sap.h',
'model/handover-algorithm.h',
'model/a2-rsrq-handover-algorithm.h',
+ 'model/lte-anr-sap.h',
+ 'model/lte-anr.h',
]
if (bld.env['ENABLE_EXAMPLES']):