Evaluation of cell selection criteria

This commit is contained in:
Budiarto Herman
2013-07-28 08:28:07 +03:00
parent 697755b1fe
commit dc3ef42bbd
13 changed files with 821 additions and 144 deletions

View File

@@ -600,11 +600,17 @@ LteHelper::Attach (Ptr<NetDevice> ueDevice)
{
NS_LOG_FUNCTION (this);
if (m_epcHelper == 0)
{
NS_FATAL_ERROR ("This function is not valid without properly configured EPC");
}
Ptr<LteUeNetDevice> ueLteDevice = ueDevice->GetObject<LteUeNetDevice> ();
if (ueLteDevice == 0)
{
NS_FATAL_ERROR ("The passed NetDevice must be an LteUeNetDevice");
}
Ptr<LteUePhy> uePhy = ueLteDevice->GetPhy ();
uePhy->CellSearch ();
}
@@ -867,6 +873,139 @@ LteHelper::ActivateDataRadioBearer (NetDeviceContainer ueDevices, EpsBearer bear
}
}
void
LteHelper::SetEnbPlmnId (NetDeviceContainer enbDevices, uint32_t plmnId)
{
for (NetDeviceContainer::Iterator i = enbDevices.Begin ();
i != enbDevices.End (); ++i)
{
SetEnbPlmnId (*i, plmnId);
}
}
void
LteHelper::SetEnbPlmnId (Ptr<NetDevice> enbDevice, uint32_t plmnId)
{
NS_LOG_FUNCTION (this << enbDevice << plmnId);
Ptr<LteEnbNetDevice> enbLteDevice = enbDevice->GetObject<LteEnbNetDevice> ();
if (enbLteDevice == 0)
{
NS_FATAL_ERROR ("The passed NetDevice must be an LteEnbNetDevice");
}
Ptr<LteEnbRrc> rrc = enbLteDevice->GetRrc ();
LteRrcSap::SystemInformationBlockType1 sib1 = rrc->GetSystemInformationBlockType1 ();
sib1.cellAccessRelatedInfo.plmnIdentityInfo.plmnIdentity = plmnId;
rrc->SetSystemInformationBlockType1 (sib1);
}
void
LteHelper::SetEnbCsgId (NetDeviceContainer enbDevices, uint32_t csgId,
bool csgIndication)
{
for (NetDeviceContainer::Iterator i = enbDevices.Begin ();
i != enbDevices.End (); ++i)
{
SetEnbCsgId (*i, csgId, csgIndication);
}
}
void
LteHelper::SetEnbCsgId (Ptr<NetDevice> enbDevice, uint32_t csgId,
bool csgIndication)
{
NS_LOG_FUNCTION (this << enbDevice << csgId << csgIndication);
Ptr<LteEnbNetDevice> enbLteDevice = enbDevice->GetObject<LteEnbNetDevice> ();
if (enbLteDevice == 0)
{
NS_FATAL_ERROR ("The passed NetDevice must be an LteEnbNetDevice");
}
Ptr<LteEnbRrc> rrc = enbLteDevice->GetRrc ();
LteRrcSap::SystemInformationBlockType1 sib1 = rrc->GetSystemInformationBlockType1 ();
sib1.cellAccessRelatedInfo.csgIdentity = csgId;
sib1.cellAccessRelatedInfo.csgIndication = csgIndication;
rrc->SetSystemInformationBlockType1 (sib1);
}
void
LteHelper::SetEnbQRxLevMin (NetDeviceContainer enbDevices, int8_t qRxLevMin)
{
for (NetDeviceContainer::Iterator i = enbDevices.Begin ();
i != enbDevices.End (); ++i)
{
SetEnbQRxLevMin (*i, qRxLevMin);
}
}
void
LteHelper::SetEnbQRxLevMin (Ptr<NetDevice> enbDevice, int8_t qRxLevMin)
{
NS_LOG_FUNCTION (this << enbDevice << (int16_t) qRxLevMin);
Ptr<LteEnbNetDevice> enbLteDevice = enbDevice->GetObject<LteEnbNetDevice> ();
if (enbLteDevice == 0)
{
NS_FATAL_ERROR ("The passed NetDevice must be an LteEnbNetDevice");
}
Ptr<LteEnbRrc> rrc = enbLteDevice->GetRrc ();
LteRrcSap::SystemInformationBlockType1 sib1 = rrc->GetSystemInformationBlockType1 ();
sib1.cellSelectionInfo.qRxLevMin = qRxLevMin;
rrc->SetSystemInformationBlockType1 (sib1);
}
void
LteHelper::SetUePlmnId (NetDeviceContainer ueDevices, uint32_t plmnId)
{
for (NetDeviceContainer::Iterator i = ueDevices.Begin ();
i != ueDevices.End (); ++i)
{
SetUePlmnId (*i, plmnId);
}
}
void
LteHelper::SetUePlmnId (Ptr<NetDevice> ueDevice, uint32_t plmnId)
{
NS_LOG_FUNCTION (this << ueDevice << plmnId);
Ptr<LteUeNetDevice> ueLteDevice = ueDevice->GetObject<LteUeNetDevice> ();
if (ueLteDevice == 0)
{
NS_FATAL_ERROR ("The passed NetDevice must be an LteUeNetDevice");
}
ueLteDevice->GetNas ()->SetPlmnId (plmnId);
}
void
LteHelper::SetUeCsgId (NetDeviceContainer ueDevices, uint32_t csgId)
{
for (NetDeviceContainer::Iterator i = ueDevices.Begin ();
i != ueDevices.End (); ++i)
{
SetUeCsgId (*i, csgId);
}
}
void
LteHelper::SetUeCsgId (Ptr<NetDevice> ueDevice, uint32_t csgId)
{
NS_LOG_FUNCTION (this << ueDevice << csgId);
Ptr<LteUeNetDevice> ueLteDevice = ueDevice->GetObject<LteUeNetDevice> ();
if (ueLteDevice == 0)
{
NS_FATAL_ERROR ("The passed NetDevice must be an LteUeNetDevice");
}
ueLteDevice->GetNas ()->SetCsgId (csgId);
}
void
LteHelper::EnableLogComponents (void)
{

View File

@@ -49,8 +49,8 @@ class PropagationLossModel;
class SpectrumPropagationLossModel;
/**
* Creation and configuration of LTE entities
*
* \ingroup lte
* \brief Creation and configuration of LTE entities
*/
class LteHelper : public Object
{
@@ -163,6 +163,7 @@ public:
* \param v the value of the attribute
*/
void SetSpectrumChannelAttribute (std::string n, const AttributeValue &v);
/**
* create a set of eNB devices
*
@@ -183,10 +184,11 @@ public:
/**
* \brief Instruct a set of UE devices to attach to a suitable cell.
* \param ueDevices
* \param ueDevices the set of UE devices to be attached
*
* By calling this, the UE will start the initial cell selection procedure at
* the beginning of simulation.
* By calling this, the UE will start the cell search and initial cell
* selection procedure at the beginning of simulation. Note that this function
* can only be used in EPC-enabled simulation.
*/
void Attach (NetDeviceContainer ueDevices);
@@ -194,8 +196,9 @@ public:
* \brief Instruct a UE device to attach to a suitable cell.
* \param ueDevice
*
* By calling this, the UE will start the initial cell selection procedure at
* the beginning of simulation.
* By calling this, the UE will start the cell search and initial cell
* selection procedure at the beginning of simulation. Note that this function
* can only be used in EPC-enabled simulation.
*/
void Attach (Ptr<NetDevice> ueDevice);
@@ -336,6 +339,206 @@ public:
*/
void SetFadingModelAttribute (std::string n, const AttributeValue &v);
/**
* \brief Associate the eNodeB devices with a particular network operator.
* \param enbDevices the set of eNodeB devices to be updated
* \param plmnId the intended Public Land Mobile Network identity
*
* PLMN identity is a number identifying a cellular network of one operator in
* one country. eNodeB is associated with a single PLMN identity, which will
* be used to limit access of UE to it, so that only UE with the same value of
* PLMN identity is allowed.
*
* If not set, eNodeB devices bear a default PLMN identity of 0.
*
* This restriction only applies to initial cell selection and EPC-enabled
* simulation.
*
* \sa SetUePlmnId(NetDeviceContainer, uint32_t)
*/
void SetEnbPlmnId (NetDeviceContainer enbDevices, uint32_t plmnId);
/**
* \brief Associate the eNodeB device with a particular network operator.
* \param enbDevice
* \param plmnId the intended Public Land Mobile Network identity
*
* PLMN identity is a number identifying a cellular network of one operator in
* one country. eNodeB is associated with a single PLMN identity, which will
* be used to limit access of UE to it, so that only UE with the same value of
* PLMN identity is allowed.
*
* If not set, eNodeB devices bear a default PLMN identity of 0.
*
* This restriction only applies to initial cell selection and EPC-enabled
* simulation.
*
* \sa SetUePlmnId(Ptr<NetDevice>, uint32_t)
*/
void SetEnbPlmnId (Ptr<NetDevice> enbDevice, uint32_t plmnId);
/**
* \brief Associate the eNodeB devices with a particular CSG information.
* \param enbDevices the set of eNodeB devices to be updated
* \param csgId the intended Closed Subscriber Group identity
* \param csgIndication if TRUE, only CSG members are allowed to access the
* cell
*
* CSG identity is a number identifying a Closed Subscriber Group which the
* cell belongs to. eNodeB is associated with a single CSG identity.
*
* The same CSG identity can also be associated to several UEs, which is
* equivalent as enlisting these UEs as the members of this particular CSG.
* When the CSG indication field is set to TRUE, only UEs which are members of
* the CSG (i.e. same CSG ID) can gain access to the eNodeB, therefore
* enforcing closed access mode. Otherwise, the eNodeB operates as a non-CSG
* cell and implements open access mode.
*
* If not set, eNodeB devices are non-CSG cells and bear a CSG identity of 0
* by default.
*
* This restriction only applies to initial cell selection and EPC-enabled
* simulation.
*
* \sa SetUeCsgId(NetDeviceContainer, uint32_t)
*/
void SetEnbCsgId (NetDeviceContainer enbDevices, uint32_t csgId,
bool csgIndication);
/**
* \brief Associate the eNodeB devices with a particular CSG information.
* \param enbDevice
* \param csgId the intended Closed Subscriber Group identity
* \param csgIndication if TRUE, only CSG members are allowed to access the
* cell
*
* CSG identity is a number identifying a Closed Subscriber Group which the
* cell belongs to. eNodeB is associated with a single CSG identity.
*
* The same CSG identity can also be associated to several UEs, which is
* equivalent as enlisting these UEs as the members of this particular CSG.
* When the CSG indication field is set to TRUE, only UEs which are members of
* the CSG (i.e. same CSG ID) can gain access to the eNodeB, therefore
* enforcing closed access mode. Otherwise, the eNodeB operates as a non-CSG
* cell and implements open access mode.
*
* If not set, eNodeB devices are non-CSG cells and bear a CSG identity of 0
* by default.
*
* This restriction only applies to initial cell selection and EPC-enabled
* simulation.
*
* \sa SetUeCsgId(Ptr<NetDevice>, uint32_t)
*/
void SetEnbCsgId (Ptr<NetDevice> enbDevice, uint32_t csgId,
bool csgIndication);
/**
* \brief Set the Q-RxLevMin parameter of the eNodeB devices to be used in
* cell selection.
* \param enbDevices the set of eNodeB devices to be updated
* \param qRxLevMin the IE value of Q-RxLevMin parameter, which is
*
* The Q-RxLevMin is a network parameter and is the required minimum RSRP
* level that UE must receive before it may gain access to this cell. The
* actual value of Q-RxLevMin is IE value * 2 [dBm].
*
* If not set, the default value is -70, which is the minimum possible value.
* This translates to a minimum RSRP of -140 dBm.
*
* This restriction only applies to initial cell selection and EPC-enabled
* simulation.
*/
void SetEnbQRxLevMin (NetDeviceContainer enbDevices, int8_t qRxLevMin);
/**
* \brief Set the Q-RxLevMin parameter of the eNodeB device to be used in
* cell selection.
* \param enbDevice
* \param qRxLevMin the IE value of Q-RxLevMin parameter, which is
*
* The Q-RxLevMin is a network parameter and is the required minimum RSRP
* level that UE must receive before it may gain access to this cell. The
* actual value of Q-RxLevMin is IE value * 2 [dBm].
*
* If not set, the default value is -70, which is the minimum possible value.
* This translates to a minimum RSRP of -140 dBm.
*
* This restriction only applies to initial cell selection and EPC-enabled
* simulation.
*/
void SetEnbQRxLevMin (Ptr<NetDevice> enbDevice, int8_t qRxLevMin);
/**
* \brief Associate the UE devices with a particular network operator.
* \param ueDevices the set of UE devices to be updated
* \param plmnId the intended Public Land Mobile Network identity
*
* UE is associated with a single PLMN identity. UE can only gain access to
* cells which bear the same PLMN identity.
*
* If not set, UE devices bear a default PLMN identity of 0.
*
* This restriction only applies to initial cell selection and EPC-enabled
* simulation.
*
* \sa SetEnbPlmnId(NetDeviceContainer, uint32_t)
*/
void SetUePlmnId (NetDeviceContainer ueDevices, uint32_t plmnId);
/**
* \brief Associate the UE device with a particular network operator.
* \param ueDevice
* \param plmnId the intended Public Land Mobile Network identity
*
* UE is associated with a single PLMN identity. UE can only gain access to
* cells which bear the same PLMN identity.
*
* If not set, UE devices bear a default PLMN identity of 0.
*
* This restriction only applies to initial cell selection and EPC-enabled
* simulation.
*
* \sa SetEnbPlmnId(Ptr<NetDevice>, uint32_t)
*/
void SetUePlmnId (Ptr<NetDevice> ueDevice, uint32_t plmnId);
/**
* \brief Enlist the UE devices as members of a particular CSG.
* \param ueDevices the set of UE devices to be updated
* \param csgId the intended Closed Subscriber Group identity
*
* UE is associated with a single CSG identity, and thus becoming a member of
* this particular CSG. As a result, the UE may gain access to cells which
* belong to this CSG. This does not revoke the UE's access to non-CSG cells.
*
* If not set, UE devices bear a default CSG identity of 0.
*
* This restriction only applies to initial cell selection and EPC-enabled
* simulation.
*
* \sa SetEnbCsgId(NetDeviceContainer, uint32_t, bool)
*/
void SetUeCsgId (NetDeviceContainer ueDevices, uint32_t csgId);
/**
* \brief Enlist the UE device as a member of a particular CSG.
* \param ueDevice
* \param csgId the intended Closed Subscriber Group identity
*
* UE is associated with a single CSG identity, and thus becoming a member of
* this particular CSG. As a result, the UE may gain access to cells which
* belong to this CSG. This does not revoke the UE's access to non-CSG cells.
*
* If not set, UE devices bear a default CSG identity of 0.
*
* This restriction only applies to initial cell selection and EPC-enabled
* simulation.
*
* \sa SetEnbCsgId(Ptr<NetDevice>, uint32_t, bool)
*/
void SetUeCsgId (Ptr<NetDevice> ueDevice, uint32_t csgId);
/**
* Enables logging for all components of the LENA architecture
*

View File

@@ -56,6 +56,8 @@ NS_OBJECT_ENSURE_REGISTERED (EpcUeNas);
EpcUeNas::EpcUeNas ()
: m_state (OFF),
m_plmnId (0),
m_csgId (0),
m_asSapProvider (0),
m_bidCounter (0)
{
@@ -73,7 +75,7 @@ void
EpcUeNas::DoDispose ()
{
NS_LOG_FUNCTION (this);
delete m_asSapUser;
delete m_asSapUser;
}
TypeId
@@ -101,19 +103,45 @@ EpcUeNas::SetImsi (uint64_t imsi)
m_imsi = imsi;
}
void
EpcUeNas::SetPlmnId (uint32_t plmnId)
{
m_plmnId = plmnId;
m_asSapProvider->SetSelectedPlmn (plmnId);
}
uint32_t
EpcUeNas::GetPlmnId () const
{
return m_plmnId;
}
void
EpcUeNas::SetCsgId (uint32_t csgId)
{
m_csgId = csgId;
m_asSapProvider->SetCsgWhiteList (csgId);
}
uint32_t
EpcUeNas::GetCsgId () const
{
return m_csgId;
}
void
EpcUeNas::SetAsSapProvider (LteAsSapProvider* s)
{
m_asSapProvider = s;
}
LteAsSapUser*
LteAsSapUser*
EpcUeNas::GetAsSapUser ()
{
return m_asSapUser;
}
void
void
EpcUeNas::SetForwardUpCallback (Callback <void, Ptr<Packet> > cb)
{
m_forwardUpCallback = cb;

View File

@@ -65,27 +65,51 @@ public:
void SetImsi (uint64_t imsi);
/**
*
* \param plmnId Public Land Mobile Network identity
*/
void SetPlmnId (uint32_t plmnId);
/**
*
* \return plmnId Public Land Mobile Network identity
*/
uint32_t GetPlmnId () const;
/**
*
* \param csgId Closed Subscriber Group identity
*/
void SetCsgId (uint32_t csgId);
/**
*
* \return csgId Closed Subscriber Group identity
*/
uint32_t GetCsgId () const;
/**
* Set the AS SAP provider to interact with the NAS entity
*
*
* \param s the AS SAP provider
*/
void SetAsSapProvider (LteAsSapProvider* s);
/**
*
*
/**
*
*
* \return the AS SAP user exported by this RRC
*/
LteAsSapUser* GetAsSapUser ();
/**
/**
* set the callback used to forward data packets up the stack
*
*
* \param cb the callback
*/
void SetForwardUpCallback (Callback <void, Ptr<Packet> > cb);
/**
/**
* \brief Instruct the NAS to go to ACTIVE state
*
* The end result is equivalent with EMM Registered + ECM Connected states.
@@ -168,6 +192,9 @@ private:
uint64_t m_imsi;
uint32_t m_plmnId;
uint32_t m_csgId;
LteAsSapProvider* m_asSapProvider;
LteAsSapUser* m_asSapUser;

View File

@@ -33,7 +33,7 @@ class LteEnbNetDevice;
/**
* This class implements the Access Stratum (AS) Service Access Point
* (SAP), i.e., the interface between the EpcUeNas and the LteUeRrc.
* In particular, this class implements the
* In particular, this class implements the
* Provider part of the SAP, i.e., the methods exported by the
* LteUeRrc and called by the EpcUeNas.
*
@@ -43,6 +43,22 @@ class LteAsSapProvider
public:
virtual ~LteAsSapProvider ();
/**
* \brief Set the selected Public Land Mobile Network identity to be used for
* cell selection.
*
* \param plmnId identity of the selected PLMN
*/
virtual void SetSelectedPlmn (uint32_t plmnId) = 0;
/**
* \brief Set the selected Closed Subscriber Group subscription list to be
* used for cell selection
*
* \param csgId identity of the subscribed CSG
*/
virtual void SetCsgWhiteList (uint32_t csgId) = 0;
/**
* Force the RRC to stay camped on a certain eNB
*
@@ -51,7 +67,7 @@ public:
* \param cellId the Cell ID identifying the eNB
*/
virtual void ForceCampedOnEnb (uint16_t cellId, uint16_t earfcn) = 0;
/**
* Tell the RRC to go into Connected Mode
*
@@ -74,7 +90,7 @@ public:
virtual void Disconnect () = 0;
};
/**
* This class implements the Access Stratum (AS) Service Access Point
@@ -132,8 +148,10 @@ public:
MemberLteAsSapProvider (C* owner);
// inherited from LteAsSapProvider
virtual void Connect (void);
virtual void SetSelectedPlmn (uint32_t plmnId);
virtual void SetCsgWhiteList (uint32_t csgId);
virtual void ForceCampedOnEnb (uint16_t cellId, uint16_t earfcn);
virtual void Connect (void);
virtual void SendData (Ptr<Packet> packet, uint8_t bid);
virtual void Disconnect ();
@@ -155,12 +173,25 @@ MemberLteAsSapProvider<C>::MemberLteAsSapProvider ()
template <class C>
void
MemberLteAsSapProvider<C>::SetSelectedPlmn (uint32_t plmnId)
{
m_owner->DoSetSelectedPlmn (plmnId);
}
template <class C>
void
MemberLteAsSapProvider<C>::SetCsgWhiteList (uint32_t csgId)
{
m_owner->DoSetCsgWhiteList (csgId);
}
template <class C>
void
MemberLteAsSapProvider<C>::ForceCampedOnEnb (uint16_t cellId, uint16_t earfcn)
{
m_owner->DoForceCampedOnEnb (cellId, earfcn);
}
template <class C>
void
MemberLteAsSapProvider<C>::Connect ()

View File

@@ -264,6 +264,27 @@ EutranMeasurementMapping::GetActualA3Offset (int8_t a3Offset)
return (static_cast<double> (a3Offset) * 0.5);
}
double
EutranMeasurementMapping::GetActualQRxLevMin (int8_t qRxLevMin)
{
if ((qRxLevMin < -70) || (qRxLevMin > -22))
{
NS_FATAL_ERROR ("The value " << qRxLevMin << " is out of the allowed range (-70..-22) for Q-RxLevMin");
}
return (static_cast<double> (qRxLevMin) * 2);
}
double
EutranMeasurementMapping::GetActualQQualMin (int8_t qQualMin)
{
if ((qQualMin < -34) || (qQualMin > -3))
{
NS_FATAL_ERROR ("The value " << qQualMin << " is out of the allowed range (-34..-3) for Q-QualMin");
}
return (static_cast<double> (qQualMin));
}
}; // namespace ns3

View File

@@ -220,19 +220,45 @@ public:
* \return hysteresis actual value in dB, which is IE value * 0.5 dB
*
* As per section 6.3.5 of 3GPP TS 36.331.
*
* \sa LteRrcSap::ReportConfigEutra
*/
static double GetActualHysteresis (uint8_t hysteresis);
/**
* \brief Returns the actual value of an a3-Offset parameter.
* \param IE value of hysteresis
* \param IE value of a3-offset
* \return a3-Offset actual value in dB, which is IE value * 0.5 dB
*
* As per section 6.3.5 of 3GPP TS 36.331.
*
* \sa LteRrcSap::ReportConfigEutra
*/
static double GetActualA3Offset (int8_t a3Offset);
};
/**
* \brief Returns the actual value of an Q-RxLevMin parameter.
* \param IE value of Q-RxLevMin
* \return Q-RxLevMin actual value in dBm, which is IE value * 2 dBm
*
* As per section 6.3.4 of 3GPP TS 36.331.
*
* \sa LteRrcSap::CellSelectionInfo
*/
static double GetActualQRxLevMin (int8_t qRxLevMin);
/**
* \brief Returns the actual value of an Q-QualMin parameter.
* \param IE value of Q-QualMin
* \return Q-QualMin actual value in dB, which is IE value dB
*
* As per section 6.3.4 of 3GPP TS 36.331.
*
* \sa LteRrcSap::CellSelectionInfo
*/
static double GetActualQQualMin (int8_t qQualMin);
}; // end of class EutranMeasurementMapping
}; // namespace ns3

View File

@@ -533,10 +533,10 @@ UeManager::PrepareHandover (uint16_t cellId)
hpi.asConfig.sourceRadioResourceConfig = GetRadioResourceConfigForHandoverPreparationInfo ();
hpi.asConfig.sourceMasterInformationBlock.dlBandwidth = m_rrc->m_dlBandwidth;
hpi.asConfig.sourceMasterInformationBlock.systemFrameNumber = 0;
hpi.asConfig.sourceSystemInformationBlockType1.cellAccessRelatedInfo.plmnIdentityInfo.plmnIdentity = 0;
hpi.asConfig.sourceSystemInformationBlockType1.cellAccessRelatedInfo.plmnIdentityInfo.plmnIdentity = m_rrc->m_sib1.cellAccessRelatedInfo.plmnIdentityInfo.plmnIdentity;
hpi.asConfig.sourceSystemInformationBlockType1.cellAccessRelatedInfo.cellIdentity = m_rrc->m_cellId;
hpi.asConfig.sourceSystemInformationBlockType1.cellAccessRelatedInfo.csgIndication = 0;
hpi.asConfig.sourceSystemInformationBlockType1.cellAccessRelatedInfo.csgIdentity = 0;
hpi.asConfig.sourceSystemInformationBlockType1.cellAccessRelatedInfo.csgIndication = m_rrc->m_sib1.cellAccessRelatedInfo.csgIndication;
hpi.asConfig.sourceSystemInformationBlockType1.cellAccessRelatedInfo.csgIdentity = m_rrc->m_sib1.cellAccessRelatedInfo.csgIdentity;
LteEnbCmacSapProvider::RachConfig rc = m_rrc->m_cmacSapProvider->GetRachConfig ();
hpi.asConfig.sourceSystemInformationBlockType2.radioResourceConfigCommon.rachConfigCommon.preambleInfo.numberOfRaPreambles = rc.numberOfRaPreambles;
hpi.asConfig.sourceSystemInformationBlockType2.radioResourceConfigCommon.rachConfigCommon.raSupervisionInfo.preambleTransMax = rc.preambleTransMax;
@@ -1657,18 +1657,14 @@ LteEnbRrc::ConfigureCell (uint8_t ulBandwidth, uint8_t dlBandwidth,
mib.dlBandwidth = m_dlBandwidth;
m_cphySapProvider->SetMasterInformationBlock (mib);
// Enabling SIB1 transmission
LteRrcSap::SystemInformationBlockType1 sib1;
sib1.cellAccessRelatedInfo.cellIdentity = cellId;
sib1.cellAccessRelatedInfo.csgIndication = false;
sib1.cellAccessRelatedInfo.csgIdentity = 0;
LteRrcSap::PlmnIdentityInfo plmnIdentityInfo;
plmnIdentityInfo.plmnIdentity = 0;
sib1.cellAccessRelatedInfo.plmnIdentityInfo = plmnIdentityInfo;
sib1.cellSelectionInfo.qQualMin = -34;
sib1.cellSelectionInfo.qRxLevMin = -70;
// TODO the above fields should not be hardcoded like this
m_cphySapProvider->SetSystemInformationBlockType1 (sib1);
// Enabling SIB1 transmission with default values
m_sib1.cellAccessRelatedInfo.cellIdentity = cellId;
m_sib1.cellAccessRelatedInfo.csgIndication = false;
m_sib1.cellAccessRelatedInfo.csgIdentity = 0;
m_sib1.cellAccessRelatedInfo.plmnIdentityInfo.plmnIdentity = 0;
m_sib1.cellSelectionInfo.qQualMin = -34; // not used, set as minimum value
m_sib1.cellSelectionInfo.qRxLevMin = -70; // set as minimum value
m_cphySapProvider->SetSystemInformationBlockType1 (m_sib1);
/*
* Enabling transmission of other SIB. The first time System Information is
@@ -1687,6 +1683,10 @@ void
LteEnbRrc::SetCellId (uint16_t cellId)
{
m_cellId = cellId;
// update SIB1 too
m_sib1.cellAccessRelatedInfo.cellIdentity = cellId;
m_cphySapProvider->SetSystemInformationBlockType1 (m_sib1);
}
bool
@@ -2145,6 +2145,19 @@ LteEnbRrc::AddX2Neighbour (uint16_t cellId)
m_neighbourRelationTable[cellId] = neighbourRelation;
}
LteRrcSap::SystemInformationBlockType1
LteEnbRrc::GetSystemInformationBlockType1 () const
{
return m_sib1;
}
void
LteEnbRrc::SetSystemInformationBlockType1 (LteRrcSap::SystemInformationBlockType1 sib1)
{
m_sib1 = sib1;
m_cphySapProvider->SetSystemInformationBlockType1 (sib1);
}
// from 3GPP TS 36.213 table 8.2-1 UE Specific SRS Periodicity
const uint8_t SRS_ENTRIES = 9;
@@ -2287,5 +2300,6 @@ LteEnbRrc::SendSystemInformation ()
Simulator::Schedule (m_systemInformationPeriodicity, &LteEnbRrc::SendSystemInformation, this);
}
} // namespace ns3

View File

@@ -766,6 +766,18 @@ public:
*/
uint32_t GetSrsPeriodicity () const;
/**
*
* \param sib1 System Information Block Type 1 to be broadcasted over BCH
*/
void SetSystemInformationBlockType1 (LteRrcSap::SystemInformationBlockType1 sib1);
/**
*
* \return the System Information Block Type 1 that is currently broadcasted over BCH
*/
LteRrcSap::SystemInformationBlockType1 GetSystemInformationBlockType1 () const;
private:
/**
@@ -843,6 +855,9 @@ private:
uint16_t m_ulBandwidth;
uint16_t m_lastAllocatedRnti;
/// the System Information Block Type 1 that is currently broadcasted over BCH
LteRrcSap::SystemInformationBlockType1 m_sib1;
std::map<uint16_t, Ptr<UeManager> > m_ueMap;
/**

View File

@@ -131,7 +131,9 @@ LteUeRrc::LteUeRrc ()
m_connectionPending (false),
m_hasReceivedMib (false),
m_hasReceivedSib1 (false),
m_hasReceivedSib2 (false)
m_hasReceivedSib2 (false),
m_selectedPlmn (0),
m_csgWhiteList (0)
{
NS_LOG_FUNCTION (this);
m_cphySapUser = new MemberLteUeCphySapUser<LteUeRrc> (this);
@@ -505,6 +507,20 @@ LteUeRrc::DoNotifyRandomAccessFailed ()
}
void
LteUeRrc::DoSetSelectedPlmn (uint32_t plmnId)
{
NS_LOG_FUNCTION (this << plmnId);
m_selectedPlmn = plmnId;
}
void
LteUeRrc::DoSetCsgWhiteList (uint32_t csgId)
{
NS_LOG_FUNCTION (this << csgId);
m_csgWhiteList = csgId;
}
void
LteUeRrc::DoForceCampedOnEnb (uint16_t cellId, uint16_t earfcn)
{
@@ -566,7 +582,7 @@ LteUeRrc::DoRecvMasterInformationBlock (uint16_t cellId,
if ((m_state == IDLE_CELL_SELECTION) && m_hasReceivedSib1)
{
InitialCellSelection ();
EvaluateCellForSelection ();
}
// manual attachment procedure may camp without SIB1
@@ -589,7 +605,7 @@ LteUeRrc::DoRecvSystemInformationBlockType1 (uint16_t cellId,
if (m_state == IDLE_CELL_SELECTION && m_hasReceivedMib)
{
InitialCellSelection ();
EvaluateCellForSelection ();
}
}
@@ -598,51 +614,23 @@ LteUeRrc::DoReportUeMeasurements (LteUeCphySapUser::UeMeasurementsParameters par
{
NS_LOG_FUNCTION (this);
bool useLayer3Filtering = (m_state == CONNECTED_NORMALLY);
std::vector <LteUeCphySapUser::UeMeasurementsElement>::iterator newMeasIt;
for (newMeasIt = params.m_ueMeasurementsList.begin ();
newMeasIt != params.m_ueMeasurementsList.end (); ++newMeasIt)
{
SaveUeMeasurements (newMeasIt->m_cellId, newMeasIt->m_rsrp,
newMeasIt->m_rsrq, useLayer3Filtering);
}
if (m_state == IDLE_CELL_SELECTION)
{
double maxRsrp = -std::numeric_limits<double>::infinity ();
uint16_t maxRsrpCellId = 0;
std::vector <LteUeCphySapUser::UeMeasurementsElement>::iterator newMeasIt;
for (newMeasIt = params.m_ueMeasurementsList.begin ();
newMeasIt != params.m_ueMeasurementsList.end (); ++newMeasIt)
{
/*
* This block attempts to find a cell with strongest RSRP and has not
* yet been identified as "acceptable cell".
*/
if (maxRsrp < newMeasIt->m_rsrp)
{
std::set<uint16_t>::const_iterator itCell;
itCell = m_acceptableCell.find (newMeasIt->m_cellId);
if (itCell == m_acceptableCell.end ())
{
maxRsrp = newMeasIt->m_rsrp;
maxRsrpCellId = newMeasIt->m_cellId;
}
}
}
if (maxRsrpCellId == 0)
{
NS_LOG_WARN (this << " Cell search has detected no surrounding cell");
}
else
{
m_cphySapProvider->SyncronizeWithEnb (maxRsrpCellId, m_dlEarfcn);
}
} // end of if (m_state == IDLE_CELL_SELECTION)
// start decoding BCH
SynchronizeToStrongestCell ();
}
else
{
std::vector <LteUeCphySapUser::UeMeasurementsElement>::iterator newMeasIt;
for (newMeasIt = params.m_ueMeasurementsList.begin ();
newMeasIt != params.m_ueMeasurementsList.end (); ++newMeasIt)
{
Layer3Filtering (newMeasIt->m_cellId, newMeasIt->m_rsrp,
newMeasIt->m_rsrq);
}
std::map<uint8_t, LteRrcSap::MeasIdToAddMod>::iterator measIdIt;
for (measIdIt = m_varMeasConfig.measIdList.begin ();
measIdIt != m_varMeasConfig.measIdList.end (); ++measIdIt)
@@ -840,7 +828,46 @@ LteUeRrc::DoRecvRrcConnectionReject (LteRrcSap::RrcConnectionReject msg)
void
LteUeRrc::InitialCellSelection ()
LteUeRrc::SynchronizeToStrongestCell ()
{
uint16_t maxRsrpCellId = 0;
double maxRsrp = -std::numeric_limits<double>::infinity ();
std::map<uint16_t, MeasValues>::iterator it;
for (it = m_storedMeasValues.begin (); it != m_storedMeasValues.end (); it++)
{
/*
* This block attempts to find a cell with strongest RSRP and has not
* yet been identified as "acceptable cell".
*/
if (maxRsrp < it->second.rsrp)
{
std::set<uint16_t>::const_iterator itCell;
itCell = m_acceptableCell.find (it->first);
if (itCell == m_acceptableCell.end ())
{
maxRsrpCellId = it->first;
maxRsrp = it->second.rsrp;
}
}
}
if (maxRsrpCellId == 0)
{
NS_LOG_WARN (this << " Cell search is unable to detect surrounding cell to attach to");
}
else
{
NS_LOG_LOGIC (this << " cell " << maxRsrpCellId
<< " is the strongest untried surrounding cell");
m_cphySapProvider->SyncronizeWithEnb (maxRsrpCellId, m_dlEarfcn);
}
} // end of void LteUeRrc::SynchronizeToStrongestCell ()
void
LteUeRrc::EvaluateCellForSelection ()
{
NS_LOG_FUNCTION (this);
NS_ASSERT (m_state == IDLE_CELL_SELECTION);
@@ -848,7 +875,36 @@ LteUeRrc::InitialCellSelection ()
NS_ASSERT (m_hasReceivedSib1);
uint16_t cellId = m_lastSib1.cellAccessRelatedInfo.cellIdentity;
bool isSuitableCell = true; // TODO evaluate cell selection criteria
// Cell selection criteria evaluation
bool isSuitableCell = false;
bool isAcceptableCell = false;
std::map<uint16_t, MeasValues>::iterator storedMeasIt = m_storedMeasValues.find (cellId);
double qRxLevMeas = storedMeasIt->second.rsrp;
double qRxLevMin = EutranMeasurementMapping::GetActualQRxLevMin (m_lastSib1.cellSelectionInfo.qRxLevMin);
NS_LOG_LOGIC (this << " cell selection to cellId=" << cellId
<< " qrxlevmeas=" << qRxLevMeas << " dBm"
<< " qrxlevmin=" << qRxLevMin << " dBm");
if (qRxLevMeas - qRxLevMin > 0)
{
isAcceptableCell = true;
uint32_t cellPlmnId = m_lastSib1.cellAccessRelatedInfo.plmnIdentityInfo.plmnIdentity;
uint32_t cellCsgId = m_lastSib1.cellAccessRelatedInfo.csgIdentity;
bool cellCsgIndication = m_lastSib1.cellAccessRelatedInfo.csgIndication;
bool isPlmnMatch = (cellPlmnId == m_selectedPlmn);
bool isCsgMatch = (cellCsgIndication == false)
|| (cellCsgId == m_csgWhiteList);
isSuitableCell = (isPlmnMatch && isCsgMatch);
NS_LOG_LOGIC (this << " plmn(ue/cell)=" << m_selectedPlmn << "/" << cellPlmnId
<< " csg(ue/cell/indication)=" << m_csgWhiteList << "/"
<< cellCsgId << "/" << cellCsgIndication);
}
// Cell selection decision
if (isSuitableCell)
{
@@ -868,15 +924,21 @@ LteUeRrc::InitialCellSelection ()
}
else
{
m_acceptableCell.insert (cellId);
// ignore the MIB and SIB1 received from this cell
m_hasReceivedMib = false;
m_hasReceivedSib1 = false;
m_initialCellSelectionEndErrorTrace (m_imsi, cellId);
/*
* As long as RRC state stays at IDLE_CELL_SELECTION, the cell selection
* process will repeat again after another call to DoReportUeMeasurements.
*/
if (isAcceptableCell)
{
m_acceptableCell.insert (cellId);
}
SynchronizeToStrongestCell (); // retry to a different cell
}
} // end of void LteUeRrc::InitialCellSelection ()
} // end of void LteUeRrc::EvaluateCellForSelection ()
void
@@ -1310,14 +1372,32 @@ LteUeRrc::ApplyMeasConfig (LteRrcSap::MeasConfig mc)
}
void
LteUeRrc::Layer3Filtering (uint16_t cellId, double rsrp, double rsrq)
LteUeRrc::SaveUeMeasurements (uint16_t cellId, double rsrp, double rsrq,
bool useLayer3Filtering)
{
NS_LOG_LOGIC (this << " CellId " << cellId << " RSRP " << rsrp << " RSRQ " << rsrq);
std::map<uint16_t, MeasValues>::iterator storedMeasIt = m_storedMeasValues.find (cellId);
if (storedMeasIt == m_storedMeasValues.end ())
std::map<uint16_t, MeasValues>::iterator storedMeasIt = m_storedMeasValues.find (cellId);;
if (storedMeasIt != m_storedMeasValues.end ())
{
// first value is unfiltered
if (useLayer3Filtering)
{
// F_n = (1-a) F_{n-1} + a M_n
storedMeasIt->second.rsrp = (1 - m_varMeasConfig.aRsrp) * storedMeasIt->second.rsrp
+ m_varMeasConfig.aRsrp * rsrp;
storedMeasIt->second.rsrq = (1 - m_varMeasConfig.aRsrq) * storedMeasIt->second.rsrq
+ m_varMeasConfig.aRsrq * rsrq;
}
else
{
storedMeasIt->second.rsrp = rsrp;
storedMeasIt->second.rsrq = rsrq;
}
}
else
{
// first value is always unfiltered
MeasValues v;
v.rsrp = rsrp;
v.rsrq = rsrq;
@@ -1327,17 +1407,10 @@ LteUeRrc::Layer3Filtering (uint16_t cellId, double rsrp, double rsrq)
NS_ASSERT_MSG (ret.second == true, "element already existed");
storedMeasIt = ret.first;
}
else
{
// F_n = (1-a) F_{n-1} + a M_n
storedMeasIt->second.rsrp = (1 - m_varMeasConfig.aRsrp) * storedMeasIt->second.rsrp
+ m_varMeasConfig.aRsrp * rsrp;
storedMeasIt->second.rsrq = (1 - m_varMeasConfig.aRsrq) * storedMeasIt->second.rsrq
+ m_varMeasConfig.aRsrq * rsrq;
}
storedMeasIt->second.timestamp = Simulator::Now ();
}
} // end of void SaveUeMeasurements
void
LteUeRrc::MeasurementReportTriggering (uint8_t measId)
@@ -2183,6 +2256,7 @@ LteUeRrc::CancelLeavingTrigger (uint8_t measId, uint16_t cellId)
void
LteUeRrc::VarMeasReportListAdd (uint8_t measId, ConcernedCells_t enteringCells)
{
NS_LOG_FUNCTION (this << (uint16_t) measId);
NS_ASSERT (!enteringCells.empty ());
std::map<uint8_t, VarMeasReport>::iterator
@@ -2264,6 +2338,7 @@ void
LteUeRrc::VarMeasReportListErase (uint8_t measId, ConcernedCells_t leavingCells,
bool reportOnLeave)
{
NS_LOG_FUNCTION (this << (uint16_t) measId);
NS_ASSERT (!leavingCells.empty ());
std::map<uint8_t, VarMeasReport>::iterator

View File

@@ -241,8 +241,8 @@ public:
*/
void SetUlEarfcn (uint16_t earfcn);
/**
*
/**
*
* \return the current state
*/
State GetState ();
@@ -267,6 +267,8 @@ private:
void DoNotifyRandomAccessFailed ();
// LTE AS SAP methods
void DoSetSelectedPlmn (uint32_t plmnId);
void DoSetCsgWhiteList (uint32_t csgId);
void DoForceCampedOnEnb (uint16_t cellId, uint16_t earfcn);
void DoConnect ();
void DoSendData (Ptr<Packet> packet, uint8_t bid);
@@ -291,7 +293,10 @@ private:
// internal methods
void InitialCellSelection ();
void SaveUeMeasurements (uint16_t cellId, double rsrp, double rsrq,
bool useLayer3Filtering);
void SynchronizeToStrongestCell ();
void EvaluateCellForSelection ();
void ApplyRadioResourceConfigDedicated (LteRrcSap::RadioResourceConfigDedicated rrcd);
/// 3GPP TS 36.331 section 5.5.2 Measurement configuration
void ApplyMeasConfig (LteRrcSap::MeasConfig mc);
@@ -377,6 +382,9 @@ private:
/// List of cell ID of acceptable cells for cell selection that have been detected.
std::set<uint16_t> m_acceptableCell;
uint32_t m_selectedPlmn;
uint32_t m_csgWhiteList;
/**
* \brief Includes the accumulated configuration of the measurements to be
* performed by the UE.

View File

@@ -38,8 +38,9 @@
#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>
#include <ns3/lte-enb-net-device.h>
#include <ns3/lte-enb-phy.h>
NS_LOG_COMPONENT_DEFINE ("LteCellSelectionTest");
@@ -54,7 +55,7 @@ namespace ns3 {
LteCellSelectionTestSuite::LteCellSelectionTestSuite ()
: TestSuite ("lte-cell-selection", SYSTEM)
{
//LogComponentEnableAll (LOG_PREFIX_ALL);
//LogComponentEnable ("LteCellSelectionTest", LOG_PREFIX_ALL);
//LogComponentEnable ("LteCellSelectionTest", LOG_FUNCTION);
//LogComponentEnable ("LteUePhy", LOG_INFO);
//LogComponentEnable ("LteUePhy", LOG_WARN);
@@ -64,32 +65,73 @@ LteCellSelectionTestSuite::LteCellSelectionTestSuite ()
//LogComponentEnable ("LteSpectrumPhy", LOG_LOGIC);
//LogComponentEnable ("LteSpectrumPhy", LOG_FUNCTION);
//LogComponentEnable ("LteEnbPhy", LOG_FUNCTION);
//LogComponentEnable ("LteUeRrc", LOG_FUNCTION);
//LogComponentEnable ("LteUeRrc", LOG_PREFIX_ALL);
//LogComponentEnable ("LteUeRrc", LOG_LOGIC);
//LogComponentEnable ("LteUeRrc", LOG_WARN);
std::vector<LteCellSelectionTestCase::UeSetup_t> x;
x.clear (); // position x y z, plmn csg expectedCellId
x.push_back (LteCellSelectionTestCase::UeSetup_t (Vector (80, 10, 0), 0, 0, 1));
AddTestCase (new LteCellSelectionTestCase ("[EPC] In front of cell 1",
true, x, MilliSeconds (261)),
TestCase::QUICK);
/*
* <-- <--
* ue1---CELL3 ue2---CELL4 ue3
* / /
* / /
* / --> --> /
* ue4 CELL1---ue5 CELL2---ue6
*/
x.clear (); // position x y z, plmn csg expectedCellId
x.push_back (LteCellSelectionTestCase::UeSetup_t (Vector (-80, 20, 0), 0, 0, 2));
AddTestCase (new LteCellSelectionTestCase ("[EPC] In front of cell 2",
true, x, MilliSeconds (261)),
x.push_back (LteCellSelectionTestCase::UeSetup_t (Vector (-80, 20, 0), 0, 0, 3));
x.push_back (LteCellSelectionTestCase::UeSetup_t (Vector ( 80, 20, 0), 0, 0, 4));
x.push_back (LteCellSelectionTestCase::UeSetup_t (Vector (240, 20, 0), 0, 0, 2));
x.push_back (LteCellSelectionTestCase::UeSetup_t (Vector (-80, 10, 0), 0, 0, 3));
x.push_back (LteCellSelectionTestCase::UeSetup_t (Vector ( 80, 10, 0), 0, 0, 1));
x.push_back (LteCellSelectionTestCase::UeSetup_t (Vector (240, 10, 0), 0, 0, 2));
AddTestCase (new LteCellSelectionTestCase ("[EPC] Open access",
true, false, false, x,
MilliSeconds (261)),
TestCase::QUICK);
/*
* <-- <--
* ue1---CELL3 ue2---CELL4 ue3
* (1) (1) (1) / (0) /(1)
* /-------------/ /
* / --> / --> /
* ue4 CELL1 ue5 CELL2---ue6
* (0) (1) (0) (0) (0)
*/
x.clear (); // position x y z, plmn csg expectedCellId
x.push_back (LteCellSelectionTestCase::UeSetup_t (Vector (-80, 10, 0), 0, 0, 2));
AddTestCase (new LteCellSelectionTestCase ("[EPC] Behind cell 1",
true, x, MilliSeconds (261)),
x.push_back (LteCellSelectionTestCase::UeSetup_t (Vector (-80, 20, 0), 0, 1, 3));
x.push_back (LteCellSelectionTestCase::UeSetup_t (Vector ( 80, 20, 0), 0, 1, 4));
x.push_back (LteCellSelectionTestCase::UeSetup_t (Vector (240, 20, 0), 0, 1, 2));
x.push_back (LteCellSelectionTestCase::UeSetup_t (Vector (-80, 10, 0), 0, 0, 4));
x.push_back (LteCellSelectionTestCase::UeSetup_t (Vector ( 80, 10, 0), 0, 0, 4));
x.push_back (LteCellSelectionTestCase::UeSetup_t (Vector (240, 10, 0), 0, 0, 2));
AddTestCase (new LteCellSelectionTestCase ("[EPC] Some CSG closed access 1",
true, false, true, x,
MilliSeconds (361)),
TestCase::QUICK);
x.clear (); // position x y z, plmn csg expectedCellId
x.push_back (LteCellSelectionTestCase::UeSetup_t (Vector (80, 20, 0), 0, 0, 1));
AddTestCase (new LteCellSelectionTestCase ("[EPC] Behind cell 2",
true, x, MilliSeconds (261)),
/*
* /-------------\
* / <-- \ <--
* ue1 CELL3 ue2---CELL4 ue3
* (0) / (1) (0) (0) /(0)
* / /
* / --> --> /
* ue4 CELL1---ue5 CELL2---ue6
* (1) (1) (1) (0) (1)
*/
x.clear (); // position x y z, plmn csg expectedCellId
x.push_back (LteCellSelectionTestCase::UeSetup_t (Vector (-80, 20, 0), 0, 0, 4));
x.push_back (LteCellSelectionTestCase::UeSetup_t (Vector ( 80, 20, 0), 0, 0, 4));
x.push_back (LteCellSelectionTestCase::UeSetup_t (Vector (240, 20, 0), 0, 0, 2));
x.push_back (LteCellSelectionTestCase::UeSetup_t (Vector (-80, 10, 0), 0, 1, 3));
x.push_back (LteCellSelectionTestCase::UeSetup_t (Vector ( 80, 10, 0), 0, 1, 1));
x.push_back (LteCellSelectionTestCase::UeSetup_t (Vector (240, 10, 0), 0, 1, 2));
AddTestCase (new LteCellSelectionTestCase ("[EPC] Some CSG closed access 2",
true, false, true, x,
MilliSeconds (361)),
TestCase::QUICK);
} // end of LteCellSelectionTestSuite::LteCellSelectionTestSuite ()
@@ -115,10 +157,12 @@ LteCellSelectionTestCase::UeSetup_t::UeSetup_t (Vector position,
LteCellSelectionTestCase::LteCellSelectionTestCase (
std::string name, bool isEpcMode, std::vector<UeSetup_t> ueSetupList,
Time duration)
: TestCase (name), m_isEpcMode (isEpcMode), m_ueSetupList (ueSetupList),
m_duration (duration), m_lastState (LteUeRrc::NUM_STATES)
std::string name, bool isEpcMode, bool hasPlmnDiversity, bool hasCsgDiversity,
std::vector<UeSetup_t> ueSetupList, Time duration)
: TestCase (name), m_isEpcMode (isEpcMode),
m_hasPlmnDiversity (hasPlmnDiversity), m_hasCsgDiversity (hasCsgDiversity),
m_ueSetupList (ueSetupList), m_duration (duration),
m_lastState (LteUeRrc::NUM_STATES)
{
NS_LOG_FUNCTION (this << GetName ());
}
@@ -151,25 +195,29 @@ LteCellSelectionTestCase::DoRun ()
/*
* 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
* + <--x <--x - Parabolic antenna model is used
* | Cell3 Cell4 - eNodeB 1 at ( 0, 10, 0), facing east
* 10 m | - eNodeB 2 at (160, 10, 0), facing east
* | - eNodeB 3 at ( 0, 20, 0), facing west
* + x--> x--> - eNodeB 4 at (160, 20, 0), facing west
* Cell1 Cell2 - UEs are placed according to input
* - UEs do not move during simulation
* +------ 160 m ------+
*/
// Create Nodes
NodeContainer enbNodes;
enbNodes.Create (2);
enbNodes.Create (4);
NodeContainer ueNodes;
uint16_t nUe = m_ueSetupList.size ();
ueNodes.Create (nUe);
// Assign nodes to position
Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator> ();
positionAlloc->Add (Vector (0.0, 10.0, 0.0));
positionAlloc->Add (Vector (0.0, 20.0, 0.0));
positionAlloc->Add (Vector ( 0.0, 10.0, 0.0));
positionAlloc->Add (Vector (160.0, 10.0, 0.0));
positionAlloc->Add (Vector ( 0.0, 20.0, 0.0));
positionAlloc->Add (Vector (160.0, 20.0, 0.0));
std::vector<UeSetup_t>::const_iterator itSetup;
for (itSetup = m_ueSetupList.begin (); itSetup != m_ueSetupList.end (); itSetup++)
@@ -190,17 +238,46 @@ LteCellSelectionTestCase::DoRun ()
NetDeviceContainer enbDevs;
lteHelper->SetEnbAntennaModelAttribute ("Orientation", DoubleValue (0));
enbDevs.Add (lteHelper->InstallEnbDevice (enbNodes.Get (0)));
lteHelper->SetEnbAntennaModelAttribute ("Orientation", DoubleValue (180));
enbDevs.Add (lteHelper->InstallEnbDevice (enbNodes.Get (1)));
lteHelper->SetEnbAntennaModelAttribute ("Orientation", DoubleValue (180));
enbDevs.Add (lteHelper->InstallEnbDevice (enbNodes.Get (2)));
enbDevs.Add (lteHelper->InstallEnbDevice (enbNodes.Get (3)));
/*
* Diversity of PLMN and CSG within cells (if enabled)
*
* Cell PLMN ID CSG ID CSG indication
* ==== ======= ====== ==============
* 1 0 1 true
* 2 0 0 false
* 3 1 1 true
* 4 1 0 false
*/
if (m_hasPlmnDiversity)
{
lteHelper->SetEnbPlmnId (enbDevs.Get (2), 1);
lteHelper->SetEnbPlmnId (enbDevs.Get (3), 1);
}
if (m_hasCsgDiversity)
{
lteHelper->SetEnbCsgId (enbDevs.Get (0), 1, true);
lteHelper->SetEnbCsgId (enbDevs.Get (2), 1, true);
}
NetDeviceContainer ueDevs;
ueDevs = lteHelper->InstallUeDevice (ueNodes);
// Set the PLMN and CSG ID
NS_ASSERT (m_ueSetupList.size () == ueDevs.GetN ());
NetDeviceContainer::Iterator itDev;
for (itSetup = m_ueSetupList.begin (); itSetup != m_ueSetupList.end (); itSetup++)
for (itSetup = m_ueSetupList.begin (), itDev = ueDevs.Begin ();
itSetup != m_ueSetupList.end () || itDev != ueDevs.End ();
itSetup++, itDev++)
{
// TODO
lteHelper->SetUePlmnId (*itDev, itSetup->plmnIdentity);
lteHelper->SetUeCsgId (*itDev, itSetup->csgIdentity);
}
if (m_isEpcMode)
@@ -286,7 +363,8 @@ LteCellSelectionTestCase::DoRun ()
uint16_t actualCellId = ueDev->GetRrc ()->GetCellId ();
uint16_t expectedCellId = itSetup->expectedCellId;
NS_TEST_ASSERT_MSG_EQ (actualCellId, expectedCellId,
"UE has attached to an unexpected cell");
"IMSI " << ueDev->GetImsi ()
<< " has attached to an unexpected cell");
}
NS_TEST_ASSERT_MSG_EQ (m_lastState, 5, "UE is not at CONNECTED_NORMALLY state");

View File

@@ -74,6 +74,7 @@ public:
* \param duration length of simulation
*/
LteCellSelectionTestCase (std::string name, bool isEpcMode,
bool hasPlmnDiversity, bool hasCsgDiversity,
std::vector<UeSetup_t> ueSetupList, Time duration);
virtual ~LteCellSelectionTestCase ();
@@ -104,6 +105,17 @@ private:
*/
bool m_isEpcMode;
/**
* \brief If true, then the north and south cells will be on their own PLMN.
*/
bool m_hasPlmnDiversity;
/**
* \brief If true, then the west cells in the simulation will be CSG cell,
* while the east cells will be non-CSG cells.
*/
bool m_hasCsgDiversity;
/**
* \brief The list of UE setups to be used during the test execution.
*/