Evaluation of cell selection criteria
This commit is contained in:
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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
|
||||
*
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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 ()
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
/**
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user