LTE Automatic Neighbour Relation (ANR) function

This commit is contained in:
Budiarto Herman
2013-08-12 11:25:23 +03:00
parent a0dc2bf45b
commit c5d79310d3
12 changed files with 768 additions and 112 deletions

View File

@@ -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 @@ LteHelper::InstallSingleEnbDevice (Ptr<Node> n)
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 @@ LteHelper::InstallSingleEnbDevice (Ptr<Node> n)
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 @@ LteHelper::InstallSingleEnbDevice (Ptr<Node> n)
phy->SetLteEnbPhySapUser (mac->GetLteEnbPhySapUser ());
mac->SetLteEnbPhySapProvider (phy->GetLteEnbPhySapProvider ());
phy->SetLteEnbCphySapUser (rrc->GetLteEnbCphySapUser ());
rrc->SetLteEnbCphySapProvider (phy->GetLteEnbCphySapProvider ());
@@ -449,6 +453,7 @@ LteHelper::InstallSingleEnbDevice (Ptr<Node> n)
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 @@ LteHelper::DoHandoverRequest (Ptr<NetDevice> ueDev, Ptr<NetDevice> sourceEnbDev,
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 @@ void
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);
}

View File

@@ -101,10 +101,11 @@ A2RsrqHandoverAlgorithm::GetTypeId (void)
.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 @@ A2RsrqHandoverAlgorithm::DoInitialize ()
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 @@ A2RsrqHandoverAlgorithm::DoInitialize ()
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 ();
}

View File

@@ -42,8 +42,10 @@ public:
* 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 @@ public:
*
* 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.

View File

@@ -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

233
src/lte/model/lte-anr-sap.h Normal file
View File

@@ -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 */

236
src/lte/model/lte-anr.cc Normal file
View File

@@ -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

140
src/lte/model/lte-anr.h Normal file
View File

@@ -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 */

View File

@@ -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 @@ TypeId LteEnbNetDevice::GetTypeId (void)
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 (),

View File

@@ -41,6 +41,7 @@ class LteEnbMac;
class LteEnbRrc;
class FfMacScheduler;
class HandoverAlgorithm;
class LteAnr;
/**
@@ -149,6 +150,8 @@ private:
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 */

View File

@@ -113,7 +113,7 @@ public:
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 @@ EnbRrcMemberHandoverManagementSapUser::EnbRrcMemberHandoverManagementSapUser (Lt
}
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 @@ EnbRrcMemberHandoverManagementSapUser::TriggerHandover (uint16_t rnti,
///////////////////////////////////////////
// UeManager
///////////////////////////////////////////
const char* g_ueManagerStateName[UeManager::NUM_STATES] =
{
"INITIAL_RANDOM_ACCESS",
@@ -160,12 +165,6 @@ std::string ToString (UeManager::State s)
}
///////////////////////////////////////////
// UeManager
///////////////////////////////////////////
NS_OBJECT_ENSURE_REGISTERED (UeManager);
@@ -971,8 +970,9 @@ UeManager::RecvRrcConnectionReestablishmentComplete (LteRrcSap::RrcConnectionRee
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 @@ UeManager::RecvMeasurementReport (LteRrcSap::MeasurementReport msg)
<< " 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 @@ LteEnbRrc::LteEnbRrc ()
: 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 @@ LteEnbRrc::LteEnbRrc ()
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 @@ LteEnbRrc::DoDispose ()
m_ueMap.clear ();
delete m_cmacSapUser;
delete m_handoverManagementSapUser;
delete m_anrSapUser;
delete m_rrcSapProvider;
delete m_x2SapUser;
delete m_s1SapUser;
@@ -1506,6 +1470,20 @@ LteEnbRrc::GetHandoverManagementSapUser ()
return m_handoverManagementSapUser;
}
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)
{
@@ -2033,10 +2011,12 @@ LteEnbRrc::DoNotifyLcConfigResult (uint16_t rnti, uint8_t lcid, bool success)
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 @@ LteEnbRrc::DoTriggerHandover (uint16_t rnti, uint16_t targetCellId)
{
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 @@ LteEnbRrc::AddUe (UeManager::State state)
if ((rnti != 0) && (m_ueMap.find (rnti) == m_ueMap.end ()))
{
found = true;
break;
break;
}
}
@@ -2103,7 +2088,7 @@ LteEnbRrc::RemoveUe (uint16_t rnti)
}
// need to do this after UeManager has been deleted
RemoveSrsConfigurationIndex (srsCi);
}
}
TypeId
LteEnbRrc::GetRlcType (EpsBearer bearer)
@@ -2143,17 +2128,8 @@ LteEnbRrc::GetRlcType (EpsBearer bearer)
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

View File

@@ -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 LteUeRrc;
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 @@ private:
class HandoverManagementSapProvider;
class HandoverManagementSapUser;
class LteAnrSapProvider;
class LteAnrSapUser;
/**
@@ -452,6 +442,7 @@ class LteEnbRrc : public Object
friend class EnbRrcMemberLteEnbCmacSapUser;
friend class EnbRrcMemberHandoverManagementSapUser;
friend class MemberLteAnrSapUser<LteEnbRrc>;
friend class MemberLteEnbRrcSapProvider<LteEnbRrc>;
friend class MemberEpcEnbS1SapUser<LteEnbRrc>;
friend class EpcX2SpecificEpcX2SapUser<LteEnbRrc>;
@@ -519,6 +510,21 @@ public:
HandoverManagementSapUser* GetHandoverManagementSapUser ();
/**
* 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
*
@@ -705,7 +711,7 @@ private:
// 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 @@ private:
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 @@ private:
HandoverManagementSapUser* m_handoverManagementSapUser;
HandoverManagementSapProvider* m_handoverManagementSapProvider;
LteAnrSapUser* m_anrSapUser;
LteAnrSapProvider* m_anrSapProvider;
LteEnbRrcSapUser* m_rrcSapUser;
LteEnbRrcSapProvider* m_rrcSapProvider;
@@ -897,6 +910,9 @@ private:
*/
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 @@ private:
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

View File

@@ -101,6 +101,8 @@ def build(bld):
'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 @@ def build(bld):
'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']):