diff --git a/src/lte/model/a2-a4-rsrq-handover-algorithm.h b/src/lte/model/a2-a4-rsrq-handover-algorithm.h index 9d252d92c..62012e6c4 100644 --- a/src/lte/model/a2-a4-rsrq-handover-algorithm.h +++ b/src/lte/model/a2-a4-rsrq-handover-algorithm.h @@ -31,53 +31,73 @@ namespace ns3 { /** - * \brief Implements the Handover Management SAP for a handover algorithm based - * on RSRQ, Event A2 and Event A4. + * \brief Handover algorithm implementation based on RSRQ measurements, Event + * A2 and Event A4. * - * Handover decision is primarily based on Event A2 measurements (serving cell's - * RSRQ becomes worse than threshold). The threshold used can be configured in - * the `ServingCellThreshold` attribute. When the event is triggered, the first - * condition of handover is fulfilled. + * Handover decision made by this algorithm is primarily based on Event A2 + * measurements (serving cell's RSRQ becomes worse than threshold). When the + * event is triggered, the first condition of handover is fulfilled. * * Event A4 measurements (neighbour cell's RSRQ becomes better than threshold) * are used to detect neighbouring cells and their respective RSRQ. When a * neighbouring cell's RSRQ is higher than the serving cell's RSRQ by a certain - * offset (configurable in the `NeighbourCellOffset` attribute), then the second - * condition of handover is fulfilled. + * offset, then the second condition of handover is fulfilled. * * When the first and second conditions above are fulfilled, the algorithm - * triggers a handover. + * informs the eNodeB RRC to trigger a handover. * - * Note that the attributes must be set before the handover algorithm object is - * instantiated in order for them to take effect, i.e. before calling - * LteHelper::InstallSingleEnbDevice. Subsequent changes to the attribute values - * after that will not have any effect. + * The threshold for Event A2 can be configured in the `ServingCellThreshold` + * attribute. The offset used in the second condition can also be configured by + * setting the `NeighbourCellOffset` attribute. + * + * The following code snippet is an example of using and configuring the + * handover algorithm in a simulation program: + * + * Ptr lteHelper = CreateObject (); + * + * NodeContainer enbNodes; + * // configure the nodes here... + * + * lteHelper->SetHandoverAlgorithmType ("ns3::A2A4RsrqHandoverAlgorithm"); + * lteHelper->SetHandoverAlgorithmAttribute ("ServingCellThreshold", + * UintegerValue (30)); + * lteHelper->SetHandoverAlgorithmAttribute ("NeighbourCellOffset", + * UintegerValue (1)); + * NetDeviceContainer enbLteDevs = lteHelper->InstallEnbDevice (enbNodes); + * + * \note Setting the handover algorithm type and attributes after the call to + * LteHelper::InstallEnbDevice does not have any effect to the devices + * that have already been installed. */ class A2A4RsrqHandoverAlgorithm : public LteHandoverAlgorithm { public: + /** + * \brief Creates an A2-A4-RSRQ handover algorithm instance. + */ A2A4RsrqHandoverAlgorithm (); + virtual ~A2A4RsrqHandoverAlgorithm (); // inherited from Object virtual void DoDispose (void); static TypeId GetTypeId (void); - // inherited from HandoverAlgorithm + // inherited from LteHandoverAlgorithm virtual void SetLteHandoverManagementSapUser (LteHandoverManagementSapUser* s); virtual LteHandoverManagementSapProvider* GetLteHandoverManagementSapProvider (); + // let the forwarder class access the protected and private members friend class MemberLteHandoverManagementSapProvider; protected: // inherited from Object virtual void DoInitialize (); -private: - - // Handover Management SAP implementation + // inherited from LteHandoverAlgorithm as a Handover Management SAP implementation void DoReportUeMeas (uint16_t rnti, LteRrcSap::MeasResults measResults); +private: // Internal methods void EvaluateHandover (uint16_t rnti, uint8_t servingCellRsrq); bool IsValidNeighbour (uint16_t cellId); @@ -92,6 +112,8 @@ private: * \brief Measurements reported by a UE for a cell ID. * * The values are quantized according 3GPP TS 36.133 section 9.1.4 and 9.1.7. + * + * \todo Instead of class, try using struct or SimpleRefCount. */ class UeMeasure : public Object { @@ -100,7 +122,6 @@ private: uint8_t m_rsrp; uint8_t m_rsrq; }; - /// \todo Instead of class, try using struct or SimpleRefCount for UeMeasure. // cellId typedef std::map > MeasurementRow_t; diff --git a/src/lte/model/a3-rsrp-handover-algorithm.h b/src/lte/model/a3-rsrp-handover-algorithm.h index 85c8617ec..4cf0ef83c 100644 --- a/src/lte/model/a3-rsrp-handover-algorithm.h +++ b/src/lte/model/a3-rsrp-handover-algorithm.h @@ -31,7 +31,8 @@ namespace ns3 { /** - * \brief A handover algorithm based on RSRP and Event A3. + * \brief Implementation of the strongest cell handover algorithm, based on RSRP + * measurements and Event A3. * * The algorithm utilizes Event A3 (Section 5.5.4.4 of 3GPP TS 36.331) UE * measurements and the Reference Signal Reference Power (RSRP). It is defined @@ -40,15 +41,35 @@ namespace ns3 { * * Handover margin (a.k.a. hysteresis) and time-to-trigger (TTT) can be * configured to delay the event triggering. The values of these parameters - * apply to all attached UEs. Note that these attributes must be set before the - * handover algorithm object is instantiated in order for them to take effect, - * i.e. before calling LteHelper::InstallSingleEnbDevice. Subsequent changes to - * the attribute values after that will not have any effect. + * apply to all attached UEs. + * + * The following code snippet is an example of using and configuring the + * handover algorithm in a simulation program: + * + * Ptr lteHelper = CreateObject (); + * + * NodeContainer enbNodes; + * // configure the nodes here... + * + * lteHelper->SetHandoverAlgorithmType ("ns3::A3RsrpHandoverAlgorithm"); + * lteHelper->SetHandoverAlgorithmAttribute ("Hysteresis", + * DoubleValue (3.0)); + * lteHelper->SetHandoverAlgorithmAttribute ("TimeToTrigger", + * TimeValue (MilliSeconds (256))); + * NetDeviceContainer enbLteDevs = lteHelper->InstallEnbDevice (enbNodes); + * + * \note Setting the handover algorithm type and attributes after the call to + * LteHelper::InstallEnbDevice does not have any effect to the devices + * that have already been installed. */ class A3RsrpHandoverAlgorithm : public LteHandoverAlgorithm { public: + /** + * \brief Creates a strongest cell handover algorithm instance. + */ A3RsrpHandoverAlgorithm (); + virtual ~A3RsrpHandoverAlgorithm (); // inherited from Object @@ -59,17 +80,17 @@ public: virtual void SetLteHandoverManagementSapUser (LteHandoverManagementSapUser* s); virtual LteHandoverManagementSapProvider* GetLteHandoverManagementSapProvider (); + // let the forwarder class access the protected and private members friend class MemberLteHandoverManagementSapProvider; protected: // inherited from Object virtual void DoInitialize (); -private: - - // Handover Management SAP implementation + // inherited from LteHandoverAlgorithm as a Handover Management SAP implementation void DoReportUeMeas (uint16_t rnti, LteRrcSap::MeasResults measResults); +private: // Internal method bool IsValidNeighbour (uint16_t cellId); diff --git a/src/lte/model/lte-anr-sap.h b/src/lte/model/lte-anr-sap.h index ac1081271..edbe15262 100644 --- a/src/lte/model/lte-anr-sap.h +++ b/src/lte/model/lte-anr-sap.h @@ -28,11 +28,11 @@ namespace ns3 { /** - * \brief Service Access Point (SAP) offered by the Automatic Neighbour Relation - * (ANR) function to the eNodeB RRC instance. + * \brief Service Access Point (SAP) offered by the ANR instance to the eNodeB + * RRC instance. * - * This is the ANR SAP Provider, i.e., the part of the SAP that contains the ANR - * methods called by the eNodeB RRC. + * This is the *ANR SAP Provider*, i.e., the part of the SAP that contains the + * ANR (Automatic Neighbour Relation) methods called by the eNodeB RRC instance. */ class LteAnrSapProvider { @@ -89,10 +89,10 @@ public: /** * \brief Service Access Point (SAP) offered by the eNodeB RRC instance to the - * Automatic Neighbour Relation (ANR) function. + * ANR instance. * - * This is the ANR SAP User, i.e., the part of the SAP that contains the eNodeB - * RRC methods called by the ANR. + * This is the *ANR SAP User*, i.e., the part of the SAP that contains the + * eNodeB RRC methods called by the ANR (Automatic Neighbour Relation) instance. */ class LteAnrSapUser { @@ -112,7 +112,7 @@ public: * configuration, the eNodeB RRC entity shall forward this report to the ANC * instance through the LteAnrSapProvider::ReportUeMeas SAP function. * - * This function is only valid before the simulation begins. + * \note This function is only valid before the simulation begins. */ virtual uint8_t AddUeMeasReportConfigForAnr (LteRrcSap::ReportConfigEutra reportConfig) = 0; diff --git a/src/lte/model/lte-anr.h b/src/lte/model/lte-anr.h index fe9b4f4c0..c15c5bc93 100644 --- a/src/lte/model/lte-anr.h +++ b/src/lte/model/lte-anr.h @@ -37,11 +37,48 @@ class LteNeighbourRelation; /** * \brief Automatic Neighbour Relation function. * - * Based on Section 22.3.2a and 22.3.3 of 3GPP TS 36.300. + * ANR is a conceptually a list of neighbouring cells called the Neighbour + * Relation Table (NRT). ANR has the capability of automatically inserting new + * entries into NRT based on measurement reports obtained from the eNodeB RRC + * instance. Besides this, ANR also supports manual insertion and accepts + * queries for the NRT content. + * + * The LteHelper class automatically installs one ANR instance for each eNodeB + * RRC instance. When installed, ANR will assist the eNodeB RRC's handover + * function, e.g., by preventing an X2-based handover execution if there is no + * X2 interface to the target neighbour cell. If this is not desired, it can be + * disabled by the following code sample: + * + * Config::SetDefault ("ns3::LteHelper::AnrEnabled", BooleanValue (false)); + * Ptr lteHelper = CreateObject (); + * + * The communication between an ANR instance and the eNodeB RRC instance is done + * through the *ANR SAP* interface. The ANR instance corresponds to the + * "provider" part of this interface, while the eNodeB RRC instance takes the + * role of the "user" part. The following code skeleton establishes the + * connection between both instances: + * + * Ptr u = ...; + * Ptr p = ...; + * u->SetLteAnrSapProvider (p->GetLteAnrSapProvider ()); + * p->SetLteAnrSapUser (u->GetLteAnrSapUser ()); + * + * However, user rarely needs to use the above code, since it has already been + * taken care by LteHelper::InstallEnbDevice. + * + * The current ANR model is inspired from Section 22.3.2a and 22.3.3 of 3GPP + * TS 36.300. + * + * \sa SetLteAnrSapProvider, SetLteAnrSapUser */ class LteAnr : public Object { public: + /** + * \brief Creates an ANR instance. + * \param the cell ID of the eNodeB instance whom this ANR instance is to be + * associated with + */ LteAnr (uint16_t servingCellId); virtual ~LteAnr (); @@ -52,20 +89,22 @@ public: /** * \brief Provide an advance information about a related neighbouring cell * and add it as a new Neighbour Relation entry. + * \param cellId the cell ID of the new neighbour * * This function simulates the Neighbour Relation addition operation by * network operations and maintenance, as depicted in Section 22.3.2a of * 3GPP TS 36.300. * - * An entry added by this function will have NoRemove flag set to TRUE and - * NoHo flag set to TRUE. Hence, the cell may not act as the target cell of a - * handover, unless a measurement report of the cell is received, which will - * update the NoHo flag to FALSE. + * An entry added by this function will have the NoRemove flag set to TRUE and + * the NoHo flag set to TRUE. Hence, the cell may not act as the target cell + * of a handover, unless a measurement report of the cell is received, which + * will update the NoHo flag to FALSE. */ void AddNeighbourRelation (uint16_t cellId); /** * \brief Remove an existing Neighbour Relation entry. + * \param the cell ID to be removed from the NRT * * This function simulates the Neighbour Relation removal operation by * network operations and maintenance, as depicted in Section 22.3.2a of @@ -74,19 +113,21 @@ public: void RemoveNeighbourRelation (uint16_t cellId); /** - * \brief Set the user part of the LteAnrSap that this ANR instance will - * interact with. Normally this part of the SAP is exported by the - * eNodeB RRC. - * \param s + * \brief Set the "user" part of the ANR SAP interface that this ANR instance + * will interact with. + * \param s a reference to the "user" part of the interface, typically a + * member of an LteEnbRrc instance */ virtual void SetLteAnrSapUser (LteAnrSapUser* s); /** - * - * \return the Provider part of the LteAnrSap provided by the ANR instance + * \brief Export the "provider" part of the ANR SAP interface. + * \return the reference to the "provider" part of the interface, typically to + * be kept by an LteEnbRrc instance */ virtual LteAnrSapProvider* GetLteAnrSapProvider (); + // let the forwarder class access the protected and private members friend class MemberLteAnrSapProvider; protected: @@ -94,18 +135,62 @@ protected: virtual void DoInitialize (); private: - // ANR SAP provider implementation + + // ANR SAP PROVIDER IMPLEMENTATION + + /** + * \brief Implementation of LteAnrSapProvider::ReportUeMeas. + * \param measResults a single report of one measurement identity + */ void DoReportUeMeas (LteRrcSap::MeasResults measResults); + + /** + * \brief Implementation of LteAnrSapProvider::AddNeighbourRelation. + * \param cellId the Physical Cell ID of the new neighbouring cell + */ void DoAddNeighbourRelation (uint16_t cellId); + + /** + * \brief Implementation of LteAnrSapProvider::GetNoRemove. + * \param cellId the Physical Cell ID of the neighbouring cell of interest + * \return if true, the Neighbour Relation shall *not* be removed from the NRT + */ bool DoGetNoRemove (uint16_t cellId) const; + + /** + * \brief Implementation of LteAnrSapProvider::GetNoHo. + * \param cellId the Physical Cell ID of the neighbouring cell of interest + * \return if true, the Neighbour Relation shall *not* be used by the eNodeB + * for handover reasons + */ bool DoGetNoHo (uint16_t cellId) const; + + /** + * \brief Implementation of LteAnrSapProvider::GetNoX2. + * \param cellId the Physical Cell ID of the neighbouring cell of interest + * \return if true, the Neighbour Relation shall *not* use an X2 interface in + * order to initiate procedures towards the eNodeB parenting the + * target cell + */ bool DoGetNoX2 (uint16_t cellId) const; - // ANR SAPs - LteAnrSapUser* m_anrSapUser; + // ANR SAP + + /** + * \brief Reference to the "provider" part of the ANR SAP interface, which is + * automatically created when this class instantiates. + */ LteAnrSapProvider* m_anrSapProvider; - // Class Attributes + /** + * \brief Reference to the "user" part of the ANR SAP interface, which is + * provided by the eNodeB RRC instance. + */ + LteAnrSapUser* m_anrSapUser; + + // ATTRIBUTE + + /// The attribute Threshold. uint8_t m_threshold; /** diff --git a/src/lte/model/lte-handover-algorithm.h b/src/lte/model/lte-handover-algorithm.h index 0eb6cc30d..0591d8cf6 100644 --- a/src/lte/model/lte-handover-algorithm.h +++ b/src/lte/model/lte-handover-algorithm.h @@ -33,9 +33,35 @@ class LteHandoverManagementSapProvider; /** - * \brief This abstract base class identifies the interface by means of which - * the helper object can plug on the eNodeB RRC a handover algorithm - * implementation. + * \brief The abstract base class of a handover algorithm that operates using + * the Handover Management SAP interface. + * + * Handover algorithm receives measurement reports from an eNode RRC instance + * and tells the eNodeB RRC instance when to do a handover. + * + * This class is an abstract class intended to be inherited by subclasses that + * implement its virtual methods. By inheriting from this abstract class, the + * subclasses gain the benefits of being compatible with the LteEnbNetDevice + * class, being accessible using namespace-based access through ns-3 Config + * subsystem, and being installed and configured by LteHelper class (see + * LteHelper::SetHandoverAlgorithmType and + * LteHelper::SetHandoverAlgorithmAttribute methods). + * + * The communication with the eNodeB RRC instance is done through the *Handover + * Management SAP* interface. The handover algorithm instance corresponds to the + * "provider" part of this interface, while the eNodeB RRC instance takes the + * role of the "user" part. The following code skeleton establishes the + * connection between both instances: + * + * Ptr u = ...; + * Ptr p = ...; + * u->SetLteHandoverManagementSapProvider (p->GetLteHandoverManagementSapProvider ()); + * p->SetLteHandoverManagementSapUser (u->GetLteHandoverManagementSapUser ()); + * + * However, user rarely needs to use the above code, since it has already been + * taken care by LteHelper::InstallEnbDevice. + * + * \sa LteHandoverManagementSapProvider, LteHandoverManagementSapUser */ class LteHandoverAlgorithm : public Object { @@ -48,20 +74,32 @@ public: static TypeId GetTypeId (void); /** - * \brief Set the user part of the Handover Management SAP that this handover - * algorithm will interact with. Normally this part of the SAP is - * exported by the eNodeB RRC. - * \param s + * \brief Set the "user" part of the Handover Management SAP interface that + * this handover algorithm instance will interact with. + * \param s a reference to the "user" part of the interface, typically a + * member of an LteEnbRrc instance */ virtual void SetLteHandoverManagementSapUser (LteHandoverManagementSapUser* s) = 0; /** - * - * \return the Provider part of the Handover Management SAP provided by the - * handover algorithm + * \brief Export the "provider" part of the Handover Management SAP interface. + * \return the reference to the "provider" part of the interface, typically to + * be kept by an LteEnbRrc instance */ virtual LteHandoverManagementSapProvider* GetLteHandoverManagementSapProvider () = 0; +protected: + + // HANDOVER MANAGEMENT SAP PROVIDER IMPLEMENTATION + + /** + * \brief Implementation of LteHandoverManagementSapProvider::ReportUeMeas. + * \param rnti Radio Network Temporary Identity, an integer identifying the UE + * where the report originates from + * \param measResults a single report of one measurement identity + */ + virtual void DoReportUeMeas (uint16_t rnti, LteRrcSap::MeasResults measResults) = 0; + }; // end of class LteHandoverAlgorithm diff --git a/src/lte/model/lte-handover-management-sap.h b/src/lte/model/lte-handover-management-sap.h index b2a15dffd..31d6f9440 100644 --- a/src/lte/model/lte-handover-management-sap.h +++ b/src/lte/model/lte-handover-management-sap.h @@ -28,8 +28,12 @@ namespace ns3 { /** - * \brief Service Access Point (SAP) used by the eNodeB RRC instance to send - * messages to the handover algorithm instance. + * \brief Service Access Point (SAP) offered by the handover algorithm instance + * to the eNodeB RRC instance. + * + * This is the *Handover Management SAP Provider*, i.e., the part of the SAP + * that contains the handover algorithm methods called by the eNodeB RRC + * instance. */ class LteHandoverManagementSapProvider { @@ -45,7 +49,7 @@ public: * The received measurement report is a result of the UE measurement * configuration previously configured by calling * LteHandoverManagementSapUser::AddUeMeasReportConfigForHandover. The report - * may be stored and utilized for the purpose of making handover decision. + * may be stored and utilised for the purpose of making handover decision. */ virtual void ReportUeMeas (uint16_t rnti, LteRrcSap::MeasResults measResults) = 0; @@ -54,8 +58,11 @@ public: /** - * \brief Service Access Point (SAP) used by the handover algorithm instance to - * send messages to the eNodeB RRC instance. + * \brief Service Access Point (SAP) offered by the eNodeB RRC instance to the + * handover algorithm instance. + * + * This is the *Handover Management SAP User*, i.e., the part of the SAP that + * contains the eNodeB RRC methods called by the handover algorithm instance. */ class LteHandoverManagementSapUser { @@ -76,7 +83,7 @@ public: * handover algorithm through the LteHandoverManagementSapProvider::ReportUeMeas * SAP function. * - * This function is only valid before the simulation begins. + * \note This function is only valid before the simulation begins. */ virtual uint8_t AddUeMeasReportConfigForHandover (LteRrcSap::ReportConfigEutra reportConfig) = 0; diff --git a/src/lte/model/lte-ue-cphy-sap.h b/src/lte/model/lte-ue-cphy-sap.h index 975329401..4839a3292 100644 --- a/src/lte/model/lte-ue-cphy-sap.h +++ b/src/lte/model/lte-ue-cphy-sap.h @@ -56,9 +56,11 @@ public: /** * \brief Tell the PHY entity to listen to PSS from surrounding cells and * measure the RSRP. + * \param dlEarfcn the downlink carrier frequency (EARFCN) to listen to * * This function will instruct this PHY instance to listen to the DL channel - * over the bandwidth of 6 RB. + * over the bandwidth of 6 RB at the frequency associated with the given + * EARFCN. * * After this, it will start receiving Primary Synchronization Signal (PSS) * and periodically returning measurement reports to RRC via @@ -69,7 +71,7 @@ public: /** * \brief Tell the PHY entity to synchronize with a given eNodeB over the * currently active EARFCN for communication purposes. - * \param cellId the ID of the eNodeB + * \param cellId the ID of the eNodeB to synchronize with * * By synchronizing, the PHY will start receiving various information * transmitted by the eNodeB. For instance, when receiving system information, @@ -86,7 +88,7 @@ public: /** * \brief Tell the PHY entity to align to the given EARFCN and synchronize * with a given eNodeB for communication purposes. - * \param cellId the ID of the eNodeB + * \param cellId the ID of the eNodeB to synchronize with * \param dlEarfcn the downlink carrier frequency (EARFCN) * * By synchronizing, the PHY will start receiving various information @@ -166,25 +168,35 @@ public: }; - /** + /** + * \brief Relay an MIB message from the PHY entity to the RRC layer. + * \param cellId the ID of the eNodeB where the message originates from + * \param mib the Master Information Block message * - * \param mib the Master Information Block received on the BCH + * This function is typically called after PHY receives an MIB message over + * the BCH. */ virtual void RecvMasterInformationBlock (uint16_t cellId, LteRrcSap::MasterInformationBlock mib) = 0; /** + * \brief Relay an SIB1 message from the PHY entity to the RRC layer. + * \param cellId the ID of the eNodeB where the message originates from + * \param mib the System Information Block Type 1 message * - * \param sib1 the System Information Block Type 1 received on the BCH + * This function is typically called after PHY receives an SIB1 message over + * the BCH. */ virtual void RecvSystemInformationBlockType1 (uint16_t cellId, LteRrcSap::SystemInformationBlockType1 sib1) = 0; /** - * - * \param params the structure containing the vector of cellId, RSRP and RSRQ + * \brief Send a report of RSRP and RSRQ values perceived from PSS by the PHY + * entity (after applying layer-1 filtering) to the RRC layer. + * \param params the structure containing a vector of cellId, RSRP and RSRQ */ virtual void ReportUeMeasurements (UeMeasurementsParameters params) = 0; + }; diff --git a/src/lte/model/lte-ue-phy.h b/src/lte/model/lte-ue-phy.h index 1a41ebd31..cb457eabe 100644 --- a/src/lte/model/lte-ue-phy.h +++ b/src/lte/model/lte-ue-phy.h @@ -246,7 +246,7 @@ private: * the RRC entity. * * Initially executed at +0.200s, and then repeatedly executed with - * periodicity as indicated by the UeMeasurementsFilterPeriod attribute. + * periodicity as indicated by the *UeMeasurementsFilterPeriod* attribute. */ void ReportUeMeasurements (); diff --git a/src/lte/model/lte-ue-rrc.h b/src/lte/model/lte-ue-rrc.h index b974ac4e3..6008bc180 100644 --- a/src/lte/model/lte-ue-rrc.h +++ b/src/lte/model/lte-ue-rrc.h @@ -38,7 +38,7 @@ namespace ns3 { /** - * \brief Artificial delay of UE measurements procedure + * \brief Artificial delay of UE measurements procedure. * * i.e. the period between the time layer-1-filtered measurements from PHY * layer is received and the earliest time the actual measurement report @@ -47,11 +47,11 @@ namespace ns3 { * This delay exists because of racing condition between several UE measurements * functions which happen to be scheduled at the same time. The delay ensures * that: - * - measurements (e.g. layer-3-filtering) is always performed before - * reporting, thus the latter always uses the newest layer-1-filtered - * measurements from PHY; and - * - time-to-trigger is always performed just before the reporting, so there - * would still be chance to cancel the reporting if necessary. + * - measurements (e.g., layer-3 filtering) are always performed before + * reporting, thus the latter always use the latest measured RSRP and RSRQ; + * and + * - time-to-trigger check is always performed before the reporting, so there + * would still be chance for it to cancel the reporting if necessary. */ static const Time UE_MEASUREMENTS_DELAY = MicroSeconds (1); @@ -284,20 +284,165 @@ private: void DoRecvRrcConnectionReject (LteRrcSap::RrcConnectionReject msg); - // internal methods + // INTERNAL METHODS + + /** + * \brief Go through the list of measurement results, choose the one with the + * strongest RSRP, and tell PHY to synchronize to it. + * + * \warning This function is a part of the *initial cell selection* procedure, + * hence must be only executed during IDLE mode. + */ + void SynchronizeToStrongestCell (); + + /** + * \brief Performs cell selection evaluation to the current serving cell. + * + * \warning This function is a part of the *initial cell selection* procedure, + * hence must be only executed during IDLE mode and specifically + * during the state when the UE just received the first SIB1 message + * from the serving cell. + * + * This function assumes that the required information for the evaluation + * procedure have been readily gathered, such as *measurement results*, MIB, + * and SIB1. Please refer to the LTE module's Design Documentation for more + * details on the evaluation process. + * + * If the cell passes the evaluation, the UE will immediately camp to it. + * Otherwise, the UE will pick another cell and restart the cell selection + * procedure. + */ + void EvaluateCellForSelection (); + + /** + * \brief Update the current measurement configuration #m_varMeasConfig. + * \param mc measurements to be performed by the UE + * + * Implements Section 5.5.2 "Measurement configuration" of 3GPP TS 36.331. + * The supported subfunctions are: + * - Measurement object removal + * - Measurement object addition/ modification + * - Reporting configuration removal + * - Reporting configuration addition/ modification + * - Quantity configuration + * - Measurement identity removal + * - Measurement identity addition/ modification + * + * The subfunctions that will be invoked are determined by the content of + * the given measurement configuration. + * + * Note the existence of some chain reaction behaviours: + * - Removal of measurement object or reporting configuration also removes any + * impacted measurement identities. + * - Removal of measurement identity also removes any associated *reporting + * entry* from #m_varMeasReportList. + * - Modification to measurement object or reporting configuration also + * removes any reporting entries of the impacted measurement identities + * from #m_varMeasReportList. + * - Modification to quantity configuration also removes all existing + * reporting entries from #m_varMeasReportList, regardless of measurement + * identity. + * + * Some unsupported features: + * - List of neighbouring cells + * - List of black cells + * - CGI reporting + * - Periodical reporting configuration + * - Measurement gaps + * - s-Measure + * - Speed-dependent scaling + * + * \warning There is a possibility that the input argument (of type + * LteRrcSap::MeasConfig) may contain information in fields related + * to the unsupported features. In such case, the function will raise + * an error. + * + * The measurement configuration given as an argument is typically provided by + * the serving eNodeB. It is transmitted through the RRC protocol when the UE + * joins the cell, e.g., by connection establishment or by incoming handover. + * The information inside the argument can be configured from the eNodeB side, + * which would then equally apply to all other UEs attached to the same + * eNodeB. See the LTE module's User Documentation for more information on + * configuring this. + * + * \sa LteRrcSap::MeasConfig, LteUeRrc::m_varMeasReportList + */ + void ApplyMeasConfig (LteRrcSap::MeasConfig mc); + + /** + * \brief Keep the given measurement result as the latest measurement figures, + * to be utilised by UE RRC functions. + * \param cellId the cell ID of the measured cell + * \param rsrp measured RSRP value to be saved (in dBm) + * \param rsrq measured RSRQ value to be saved (in dB) + * \param useLayer3Filtering + * \todo Remove the useLayer3Filtering argument + * + * Implements Section 5.5.3.2 "Layer 3 filtering" of 3GPP TS 36.331. *Layer-3 + * filtering* is applied to the given measurement results before saved to + * #m_storedMeasValues. The filtering is however disabled when the UE is in + * IDLE mode, i.e., saving unfiltered values. + * + * Layer-3 filtering is influenced by a filter coefficient, which determines + * the strength of the filtering. This coefficient is provided by the active + * *quantity configuration* in #m_varMeasConfig, which is configured by the + * LteUeRrc::ApplyMeasConfig. Details on how the coefficient works and how to + * modify it can be found in LTE module's Design Documentation. + * + * \sa LteUeRrc::m_storedMeasValues + */ 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); - /// 3GPP TS 36.331 section 5.5.3.2 Layer 3 filtering - void Layer3Filtering (uint16_t cellId, double rsrp, double rsrq); - /// 3GPP TS 36.331 section 5.5.4.1 Measurement report triggering - General + + /** + * \brief Evaluate the reporting criteria of a measurement identity and + * invoke some reporting actions based on the result. + * \param measId the measurement identity to be evaluated + * + * Implements Section 5.5.4.1 "Measurement report triggering - General" of + * 3GPP TS 36.331. This function take into use the latest measurement results + * and evaluate them against the *entering condition* and the *leaving + * condition* of the measurement identity's reporting criteria. The evaluation + * also take into account other defined criteria, such as *hysteresis* and + * *time-to-trigger*. + * + * The entering and leaving condition to be evaluated are determined by the + * *event type* of the measurement identity's reporting criteria. As defined + * in LteRrcSap::ReportConfigEutra, there 5 supported events. The gore details + * of these events can be found in Section 5.5.4 of 3GPP TS 36.331. + * + * An applicable entering condition (i.e., the condition evaluates to true) + * will insert a new *reporting entry* to #m_varMeasReportList, so + * *measurement reports* would be produced and submitted to eNodeB. On the + * other hand, an applicable leaving condition will remove the related + * reporting entry from #m_varMeasReportList, so submission of related + * measurement reports to eNodeB will be suspended. + */ void MeasurementReportTriggering (uint8_t measId); - /// 3GPP TS 36.331 section 5.5.5 Measurement reporting + + /** + * \brief Produce a proper measurement report from the given measurement + * identity's reporting entry in #m_varMeasReportList and then submit + * it to the serving eNodeB. + * \param measId the measurement identity which report is to be submitted. + * + * Implements Section 5.5.5 "Measurement reporting" of 3GPP TS 36.331. + * Producing a *measurement report* involves several tasks such as including + * the latest *measurement results* (RSRP and RSRQ) of the serving cells and + * some of the neighbouring cells, including the list of cells that triggered + * the reporting, and finally sorting the lists. + * + * Measurement report is submitted to the serving eNodeB through the *RRC + * protocol*. The LteUeRrcSapUser::SendMeasurementReport method of the *UE RRC + * SAP* facilitates this submission. + * + * After the submission, the function schedules the next execution of the same + * function. The period is determined by the *report interval* specified by + * the measurement identity's *reporting configuration*. + */ void SendMeasurementReport (uint8_t measId); + + void ApplyRadioResourceConfigDedicated (LteRrcSap::RadioResourceConfigDedicated rrcd); void StartConnection (); void LeaveConnectedMode (); void DisposeOldSrb1 (); @@ -380,8 +525,12 @@ private: /// List of cell ID of acceptable cells for cell selection that have been detected. std::set m_acceptableCell; + /// List of CSG ID which this UE entity has access to. uint32_t m_csgWhiteList; + + // INTERNAL DATA STRUCTURE RELATED TO UE MEASUREMENTS + /** * \brief Includes the accumulated configuration of the measurements to be * performed by the UE. @@ -399,11 +548,18 @@ private: double aRsrq; }; + /** + * \brief Includes the accumulated configuration of the measurements to be + * performed by the UE. + * + * Based on 3GPP TS 36.331 section 7.1. + */ VarMeasConfig m_varMeasConfig; /** - * \brief Includes information about a measurement for which the triggering - * conditions have been met. + * \brief Represents a single measurement reporting entry., which includes + * information about a measurement for which the triggering conditions + * have been met. * * Based on 3GPP TS 36.331 section 7.1. */ @@ -415,41 +571,209 @@ private: EventId periodicReportTimer; }; - // measId + /** + * \brief The list of active reporting entries, indexed by the measurement + * identity which triggered the reporting. Includes information about + * measurements for which the triggering conditions have been met. + */ std::map m_varMeasReportList; + /** + * \brief List of cell IDs which are responsible for a certain trigger. + */ typedef std::list ConcernedCells_t; + /** + * \brief Compose a new reporting entry of the given measurement identity, + * insert it into #m_varMeasReportList, and set it up for submission + * to eNodeB. + * \param measId the measurement identity which the new reporting entry will + * be based upon + * \param enteringCells the cells which are responsible for triggering the + * reporting (i.e., successfully fulfilling the entering + * condition of the measurement identity) and will be + * included in the measurement report. + * + * \note If an existing reporting entry with the same measurement identity has + * already existed in #m_varMeasReportList, the function will update it + * by adding the entering cells into the existing reporting entry. + * \note When time-to-trigger is enabled for this measurement identity, the + * function will also remove the related trigger from the + * #m_enteringTriggerQueue. + */ void VarMeasReportListAdd (uint8_t measId, ConcernedCells_t enteringCells); + + /** + * \brief Remove some cells from an existing reporting entry in + * #m_varMeasReportList. + * \param measId the measurement identity to be removed from + * #m_varMeasReportList, must already exists there, otherwise + * an error would be raised + * \param leavingCells the cells which are about to be removed + * \param reportOnLeave when true, will make the function send one last + * measurement report to eNodeB before removing it + * + * \note If a given cell is not found in the reporting entry, the function + * will quietly continue. + * \note If the removal has removed all the cells in the reporting entry, the + * function will remove the reporting entry as well. + * \note When time-to-trigger is enabled for this measurement identity, the + * function will also remove the related trigger from the + * #m_leavingTriggerQueue. + */ void VarMeasReportListErase (uint8_t measId, ConcernedCells_t leavingCells, bool reportOnLeave); + + /** + * \brief Remove the reporting entry of the given measurement identity from + * #m_varMeasReportList. + * \param measId the measurement identity to be removed from + * #m_varMeasReportList, must already exists there, otherwise + * an error would be raised + * + * Any events or triggers related with this measurement identity will be + * canceled as well. + */ void VarMeasReportListClear (uint8_t measId); + /** + * \brief Represents a measurement result from a certain cell. + */ struct MeasValues { - double rsrp; - double rsrq; - Time timestamp; + double rsrp; ///< Measured RSRP in dBm. + double rsrq; ///< Measured RSRQ in dB. + Time timestamp; ///< Not used. \todo Should be removed. }; - /////////cellId + /** + * \brief Internal storage of the latest measurement results from all detected + * detected cells, indexed by the cell ID where the measurement was + * taken from. + * + * Each *measurement result* comprises of RSRP (in dBm) and RSRQ (in dB). + * + * In IDLE mode, the measurement results are used by the *initial cell + * selection* procedure. While in CONNECTED mode, *layer-3 filtering* is + * applied to the measurement results and they are used by *UE measurements* + * function (LteUeRrc::MeasurementReportTriggering and + * LteUeRrc::SendMeasurementReport). + */ std::map m_storedMeasValues; + /** + * \brief Represents a single triggered event from a measurement identity + * which reporting criteria have been fulfilled, but delayed by + * time-to-trigger. + */ struct PendingTrigger_t { - uint8_t measId; - ConcernedCells_t concernedCells; - EventId timer; + uint8_t measId; ///< The measurement identity which raised the trigger. + ConcernedCells_t concernedCells; ///< The list of cells responsible for this trigger. + EventId timer; ///< The pending reporting event, scheduled at the end of the time-to-trigger. }; - // measId + /** + * \brief List of triggers that were raised because entering condition have + * been true, but are still delayed from reporting it by + * time-to-trigger. + * + * The list is indexed by the measurement identity where the trigger + * originates from. The enclosed event will run at the end of the + * time-to-trigger and insert a *reporting entry* to #m_varMeasReportList. + */ std::map > m_enteringTriggerQueue; - // measId + + /** + * \brief List of triggers that were raised because leaving condition have + * been true, but are still delayed from stopping the reporting by + * time-to-trigger. + * + * The list is indexed by the measurement identity where the trigger + * originates from. The enclosed event will run at the end of the + * time-to-trigger and remove the associated *reporting entry* from + * #m_varMeasReportList. + */ std::map > m_leavingTriggerQueue; + /** + * \brief Clear all the waiting triggers in #m_enteringTriggerQueue which are + * associated with the given measurement identity. + * \param measId the measurement identity to be processed, must already exists + * in #m_enteringTriggerQueue, otherwise an error would be + * raised + * + * \note The function may conclude that there is nothing to be removed. In + * this case, the function will simply ignore quietly. + * + * This function is used when the entering condition of the measurement + * identity becomes no longer true. Therefore all the waiting triggers for + * this measurement identity in #m_enteringTriggerQueue have become invalid + * and must be canceled. + * + * \sa LteUeRrc::m_enteringTriggerQueue + */ void CancelEnteringTrigger (uint8_t measId); + + /** + * \brief Remove a specific cell from the waiting triggers in + * #m_enteringTriggerQueue which belong to the given measurement + * identity. + * \param measId the measurement identity to be processed, must already exists + * in #m_enteringTriggerQueue, otherwise an error would be + * raised + * \param cellId the cell ID to be removed from the waiting triggers + * + * \note The function may conclude that there is nothing to be removed. In + * this case, the function will simply ignore quietly. + * + * This function is used when a specific neighbour cell no longer fulfills + * the entering condition of the measurement identity. Thus the cell must be + * removed from all the waiting triggers for this measurement identity in + * #m_enteringTriggerQueue. + * + * \sa LteUeRrc::m_enteringTriggerQueue + */ void CancelEnteringTrigger (uint8_t measId, uint16_t cellId); + + /** + * \brief Clear all the waiting triggers in #m_leavingTriggerQueue which are + * associated with the given measurement identity. + * \param measId the measurement identity to be processed, must already exists + * in #m_leavingTriggerQueue, otherwise an error would be + * raised + * + * \note The function may conclude that there is nothing to be removed. In + * this case, the function will simply ignore quietly. + * + * This function is used when the leaving condition of the measurement + * identity becomes no longer true. Therefore all the waiting triggers for + * this measurement identity in #m_leavingTriggerQueue have become invalid + * and must be canceled. + * + * \sa LteUeRrc::m_leavingTriggerQueue + */ void CancelLeavingTrigger (uint8_t measId); + + /** + * \brief Remove a specific cell from the waiting triggers in + * #m_leavingTriggerQueue which belong to the given measurement + * identity. + * \param measId the measurement identity to be processed, must already exists + * in #m_leavingTriggerQueue, otherwise an error would be + * raised + * \param cellId the cell ID to be removed from the waiting triggers + * + * \note The function may conclude that there is nothing to be removed. In + * this case, the function will simply ignore quietly. + * + * This function is used when a specific neighbour cell no longer fulfills + * the leaving condition of the measurement identity. Thus the cell must be + * removed from all the waiting triggers for this measurement identity in + * #m_leavingTriggerQueue. + * + * \sa LteUeRrc::m_leavingTriggerQueue + */ void CancelLeavingTrigger (uint8_t measId, uint16_t cellId); }; // end of class LteUeRrc diff --git a/src/lte/model/no-op-handover-algorithm.h b/src/lte/model/no-op-handover-algorithm.h index c8667496d..601c43cf9 100644 --- a/src/lte/model/no-op-handover-algorithm.h +++ b/src/lte/model/no-op-handover-algorithm.h @@ -30,13 +30,22 @@ namespace ns3 { /** - * \brief A sample implementation of the Handover Management SAP which simply - * does nothing. + * \brief Handover algorithm implementation which simply does nothing. + * + * Selecting this handover algorithm is equivalent to disabling automatic + * triggering of handover. This is the default choice. + * + * To enable automatic handover, please select another handover algorithm, i.e., + * another child class of LteHandoverAlgorithm. */ class NoOpHandoverAlgorithm : public LteHandoverAlgorithm { public: + /** + * \brief Creates a No-op handover algorithm instance. + */ NoOpHandoverAlgorithm (); + virtual ~NoOpHandoverAlgorithm (); // inherited from Object @@ -47,17 +56,17 @@ public: virtual void SetLteHandoverManagementSapUser (LteHandoverManagementSapUser* s); virtual LteHandoverManagementSapProvider* GetLteHandoverManagementSapProvider (); + // let the forwarder class access the protected and private members friend class MemberLteHandoverManagementSapProvider; protected: // inherited from Object virtual void DoInitialize (); -private: - - // Handover Management SAP implementation + // inherited from LteHandoverAlgorithm as a Handover Management SAP implementation void DoReportUeMeas (uint16_t rnti, LteRrcSap::MeasResults measResults); +private: // Handover Management SAPs LteHandoverManagementSapUser* m_handoverManagementSapUser; LteHandoverManagementSapProvider* m_handoverManagementSapProvider;