From 0273d706b04349b767c0afd596ab8fefc8b50f28 Mon Sep 17 00:00:00 2001
From: Natale Patriciello
Date: Wed, 24 Oct 2018 10:38:03 +0200
Subject: [PATCH 01/11] lte: EpsBearer uses a lookup table
Moving the existing switch/cases statement to a lookup in a lookup-table,
created with an unordered_map at compile time. The default values for the
lookup table are taken from Rel. 11, as they were in previous ns-3 releases.
---
src/lte/model/eps-bearer.cc | 129 ++++++++++--------------------------
src/lte/model/eps-bearer.h | 111 ++++++++++++++++++++++++++++---
2 files changed, 137 insertions(+), 103 deletions(-)
diff --git a/src/lte/model/eps-bearer.cc b/src/lte/model/eps-bearer.cc
index aa3c47e81..7782f52d7 100644
--- a/src/lte/model/eps-bearer.cc
+++ b/src/lte/model/eps-bearer.cc
@@ -45,131 +45,74 @@ AllocationRetentionPriority::AllocationRetentionPriority ()
EpsBearer::EpsBearer ()
: qci (NGBR_VIDEO_TCP_DEFAULT)
{
+ m_requirements = GetRequirementsRel11 ();
}
EpsBearer::EpsBearer (Qci x)
: qci (x)
{
+ m_requirements = GetRequirementsRel11 ();
}
EpsBearer::EpsBearer (Qci x, struct GbrQosInformation y)
: qci (x), gbrQosInfo (y)
{
+ m_requirements = GetRequirementsRel11 ();
}
bool
EpsBearer::IsGbr () const
{
- // 3GPP 23.203 Section 6.1.7.2
- switch (qci)
- {
- case GBR_CONV_VOICE:
- case GBR_CONV_VIDEO:
- case GBR_GAMING:
- case GBR_NON_CONV_VIDEO:
- return true;
- case NGBR_IMS:
- case NGBR_VIDEO_TCP_OPERATOR:
- case NGBR_VOICE_VIDEO_GAMING:
- case NGBR_VIDEO_TCP_PREMIUM:
- case NGBR_VIDEO_TCP_DEFAULT:
- return false;
- default:
- NS_FATAL_ERROR ("unknown QCI value " << qci);
- return false;
- }
+ return IsGbr (m_requirements, qci);
}
uint8_t
EpsBearer::GetPriority () const
{
- // 3GPP 23.203 Section 6.1.7.2
- switch (qci)
- {
- case GBR_CONV_VOICE:
- return 2;
- case GBR_CONV_VIDEO:
- return 4;
- case GBR_GAMING:
- return 3;
- case GBR_NON_CONV_VIDEO:
- return 5;
- case NGBR_IMS:
- return 1;
- case NGBR_VIDEO_TCP_OPERATOR:
- return 6;
- case NGBR_VOICE_VIDEO_GAMING:
- return 7;
- case NGBR_VIDEO_TCP_PREMIUM:
- return 8;
- case NGBR_VIDEO_TCP_DEFAULT:
- return 9;
- default:
- NS_FATAL_ERROR ("unknown QCI value " << qci);
- return 0;
- }
+ return GetPriority (m_requirements, qci);
}
uint16_t
EpsBearer::GetPacketDelayBudgetMs () const
{
- // 3GPP 23.203 Section 6.1.7.2
- switch (qci)
- {
- case GBR_CONV_VOICE:
- return 100;
- case GBR_CONV_VIDEO:
- return 150;
- case GBR_GAMING:
- return 50;
- case GBR_NON_CONV_VIDEO:
- return 300;
- case NGBR_IMS:
- return 100;
- case NGBR_VIDEO_TCP_OPERATOR:
- return 300;
- case NGBR_VOICE_VIDEO_GAMING:
- return 100;
- case NGBR_VIDEO_TCP_PREMIUM:
- return 300;
- case NGBR_VIDEO_TCP_DEFAULT:
- return 300;
- default:
- NS_FATAL_ERROR ("unknown QCI value " << qci);
- return 0;
- }
+ return GetPacketDelayBudgetMs (m_requirements, qci);
}
double
EpsBearer::GetPacketErrorLossRate () const
{
- // 3GPP 23.203 Section 6.1.7.2
- switch (qci)
- {
- case GBR_CONV_VOICE:
- return 1.0e-2;
- case GBR_CONV_VIDEO:
- return 1.0e-3;
- case GBR_GAMING:
- return 1.0e-3;
- case GBR_NON_CONV_VIDEO:
- return 1.0e-6;
- case NGBR_IMS:
- return 1.0e-6;
- case NGBR_VIDEO_TCP_OPERATOR:
- return 1.0e-6;
- case NGBR_VOICE_VIDEO_GAMING:
- return 1.0e-3;
- case NGBR_VIDEO_TCP_PREMIUM:
- return 1.0e-6;
- case NGBR_VIDEO_TCP_DEFAULT:
- return 1.0e-6;
- default:
- NS_FATAL_ERROR ("unknown QCI value " << qci);
- return 0;
- }
+ return GetPacketErrorLossRate (m_requirements, qci);
}
+EpsBearer::BearerRequirementsMap
+EpsBearer::GetRequirementsRel11 ()
+{
+ /* Needed to support GCC 4.9. Otherwise, use list constructors, for example:
+ * EpsBearer::BearerRequirementsMap
+ * EpsBearer::GetRequirementsRel15 ()
+ * {
+ * return
+ * {
+ * { GBR_CONV_VOICE , { true, 20, 100, 1.0e-2, 0, 2000} },
+ * ...
+ * };
+ * }
+ */
+ static EpsBearer::BearerRequirementsMap ret;
+ if (ret.size () == 0)
+ {
+ ret.insert (std::make_pair (GBR_CONV_VOICE, std::make_tuple (true, 2, 100, 1.0e-2, 0, 0)));
+ ret.insert (std::make_pair (GBR_CONV_VIDEO, std::make_tuple (true, 4, 150, 1.0e-3, 0, 0)));
+ ret.insert (std::make_pair (GBR_GAMING, std::make_tuple (true, 3, 50, 1.0e-3, 0, 0)));
+ ret.insert (std::make_pair (GBR_NON_CONV_VIDEO, std::make_tuple (true, 5, 300, 1.0e-6, 0, 0)));
+ ret.insert (std::make_pair (NGBR_IMS, std::make_tuple (false, 1, 100, 1.0e-6, 0, 0)));
+ ret.insert (std::make_pair (NGBR_VIDEO_TCP_OPERATOR, std::make_tuple (false, 6, 300, 1.0e-6, 0, 0)));
+ ret.insert (std::make_pair (NGBR_VOICE_VIDEO_GAMING, std::make_tuple (false, 7, 100, 1.0e-3, 0, 0)));
+ ret.insert (std::make_pair (NGBR_VIDEO_TCP_PREMIUM, std::make_tuple (false, 8, 300, 1.0e-6, 0, 0)));
+ ret.insert (std::make_pair (NGBR_VIDEO_TCP_DEFAULT, std::make_tuple (false, 9, 300, 1.0e-6, 0, 0)));
+ }
+ return ret;
+}
} // namespace ns3
diff --git a/src/lte/model/eps-bearer.h b/src/lte/model/eps-bearer.h
index c0bb27d58..72521e8fa 100644
--- a/src/lte/model/eps-bearer.h
+++ b/src/lte/model/eps-bearer.h
@@ -23,6 +23,7 @@
#define EPS_BEARER
#include
+#include
namespace ns3 {
@@ -73,18 +74,19 @@ struct EpsBearer
/**
* QoS Class Indicator. See 3GPP 23.203 Section 6.1.7.2 for standard values.
+ * Updated to Release 15.
*/
- enum Qci
+ enum Qci : uint8_t
{
- GBR_CONV_VOICE = 1,
- GBR_CONV_VIDEO = 2,
- GBR_GAMING = 3,
- GBR_NON_CONV_VIDEO = 4,
- NGBR_IMS = 5,
- NGBR_VIDEO_TCP_OPERATOR = 6,
- NGBR_VOICE_VIDEO_GAMING = 7,
- NGBR_VIDEO_TCP_PREMIUM = 8,
- NGBR_VIDEO_TCP_DEFAULT = 9,
+ GBR_CONV_VOICE = 1, ///< GBR Conversational Voice
+ GBR_CONV_VIDEO = 2, ///< GBR Conversational Video (Live streaming)
+ GBR_GAMING = 3, ///< GBR Real Time Gaming
+ GBR_NON_CONV_VIDEO = 4, ///< GBR Non-Conversational Video (Buffered Streaming)
+ NGBR_IMS = 5, ///< Non-GBR IMS Signalling
+ NGBR_VIDEO_TCP_OPERATOR = 6, ///< Non-GBR TCP-based Video (Buffered Streaming, e.g., www, e-mail...)
+ NGBR_VOICE_VIDEO_GAMING = 7, ///< Non-GBR Voice, Video, Interactive Streaming
+ NGBR_VIDEO_TCP_PREMIUM = 8, ///< Non-GBR TCP-based Video (Buffered Streaming, e.g., www, e-mail...)
+ NGBR_VIDEO_TCP_DEFAULT = 9, ///< Non-GBR TCP-based Video (Buffered Streaming, e.g., www, e-mail...)
} qci; ///< Qos class indicator
GbrQosInformation gbrQosInfo; ///< GBR QOS information
@@ -139,6 +141,95 @@ struct EpsBearer
*/
double GetPacketErrorLossRate () const;
+private:
+ /**
+ * \brief Hashing QCI
+ *
+ * Qci are just uint8_t, so that's how we calculate the hash. Unfortunately,
+ * we have to provide this struct because gcc 4.9 would not compile otherwise.
+ */
+ struct QciHash
+ {
+ /**
+ * \brief Hash the QCI like a normal uint8_t
+ * \param s Qci to hash
+ * \return Hash of Qci
+ */
+ std::size_t
+ operator () (Qci const& s) const noexcept
+ {
+ return std::hash {} (s);
+ }
+ };
+
+ /**
+ * \brief Map between QCI and requirements
+ *
+ * The tuple is formed by: isGbr, priority, packet delay budget, packet error rate,
+ * default maximum data burst, default averaging window (0 when does not apply)
+ */
+ typedef std::unordered_map, QciHash > BearerRequirementsMap;
+
+ /**
+ * \brief Is the selected QCI GBR?
+ * \param map Map between QCI and requirements
+ * \param qci QCI to look for
+ * \return GBR flag for the selected CQI
+ */
+ static uint32_t
+ IsGbr (const BearerRequirementsMap &map, Qci qci) {return std::get<0> (map.at (qci));}
+
+ /**
+ * \brief Get priority for the selected QCI
+ * \param map Map between QCI and requirements
+ * \param qci QCI to look for
+ * \return priority for the selected QCI
+ */
+ static uint8_t
+ GetPriority (const BearerRequirementsMap &map, Qci qci) {return std::get<1> (map.at (qci));}
+ /**
+ * \brief Get packet delay in ms for the selected QCI
+ * \param map Map between QCI and requirements
+ * \param qci QCI to look for
+ * \return packet delay in ms for the selected QCI
+ */
+ static uint16_t
+ GetPacketDelayBudgetMs (const BearerRequirementsMap &map, Qci qci) {return std::get<2> (map.at (qci));}
+ /**
+ * \brief Get packet error rate for the selected QCI
+ * \param map Map between QCI and requirements
+ * \param qci QCI to look for
+ * \return packet error rate for the selected QCI
+ */
+ static double
+ GetPacketErrorLossRate (const BearerRequirementsMap &map, Qci qci) {return std::get<3> (map.at (qci));}
+ /**
+ * \brief Get maximum data burst for the selected QCI
+ * \param map Map between QCI and requirements
+ * \param qci QCI to look for
+ * \return maximum data burst for the selected QCI
+ */
+ static uint32_t
+ GetMaxDataBurst (const BearerRequirementsMap &map, Qci qci) {return std::get<4> (map.at (qci));}
+ /**
+ * \brief Get default averaging window for the selected QCI
+ * \param map Map between QCI and requirements
+ * \param qci QCI to look for
+ * \return default averaging window for the selected QCI
+ */
+ static uint32_t
+ GetAvgWindow (const BearerRequirementsMap &map, Qci qci) {return std::get<5> (map.at (qci));}
+
+ /**
+ * \brief Retrieve requirements for Rel. 11
+ * \return the BearerRequirementsMap for Release 11
+ */
+ static BearerRequirementsMap GetRequirementsRel11 ();
+
+ /**
+ * \brief Requirements per bearer
+ */
+ BearerRequirementsMap m_requirements;
};
} // namespace ns3
From 6674e88fd6a0ef646b35899d8c42fe75c081bc75 Mon Sep 17 00:00:00 2001
From: Natale Patriciello
Date: Wed, 24 Oct 2018 10:38:53 +0200
Subject: [PATCH 02/11] lte: Added EpsBearer new values (updating it to Rel.
15)
Between Rel. x and Rel. 15 (Rel. x being the current one) some values have been
added. This commit adds these missing values.
---
src/lte/model/eps-bearer.cc | 33 +++++++++++++++++++++++++++++++++
src/lte/model/eps-bearer.h | 18 ++++++++++++++++++
2 files changed, 51 insertions(+)
diff --git a/src/lte/model/eps-bearer.cc b/src/lte/model/eps-bearer.cc
index 7782f52d7..e2b91dc37 100644
--- a/src/lte/model/eps-bearer.cc
+++ b/src/lte/model/eps-bearer.cc
@@ -115,4 +115,37 @@ EpsBearer::GetRequirementsRel11 ()
return ret;
}
+EpsBearer::BearerRequirementsMap
+EpsBearer::GetRequirementsRel15 ()
+{
+ // Needed to support GCC 4.9. Otherwise, use list constructors (see GetRequirementsRel10)
+ static EpsBearer::BearerRequirementsMap ret;
+
+ if (ret.size () == 0)
+ {
+ ret.insert (std::make_pair (GBR_CONV_VOICE, std::make_tuple (true, 20, 100, 1.0e-2, 0, 2000)));
+ ret.insert (std::make_pair (GBR_CONV_VIDEO, std::make_tuple (true, 40, 150, 1.0e-3, 0, 2000)));
+ ret.insert (std::make_pair (GBR_GAMING, std::make_tuple (true, 30, 50, 1.0e-3, 0, 2000)));
+ ret.insert (std::make_pair (GBR_NON_CONV_VIDEO, std::make_tuple (true, 50, 300, 1.0e-6, 0, 2000)));
+ ret.insert (std::make_pair (GBR_MC_PUSH_TO_TALK, std::make_tuple (true, 7, 75, 1.0e-2, 0, 2000)));
+ ret.insert (std::make_pair (GBR_NMC_PUSH_TO_TALK, std::make_tuple (true, 20, 100, 1.0e-2, 0, 2000)));
+ ret.insert (std::make_pair (GBR_MC_VIDEO, std::make_tuple (true, 15, 100, 1.0e-3, 0, 2000)));
+ ret.insert (std::make_pair (GBR_V2X, std::make_tuple (true, 25, 50, 1.0e-2, 0, 2000)));
+ ret.insert (std::make_pair (NGBR_IMS, std::make_tuple (false, 10, 100, 1.0e-6, 0, 0)));
+ ret.insert (std::make_pair (NGBR_VIDEO_TCP_OPERATOR, std::make_tuple (false, 60, 300, 1.0e-6, 0, 0)));
+ ret.insert (std::make_pair (NGBR_VOICE_VIDEO_GAMING, std::make_tuple (false, 70, 100, 1.0e-3, 0, 0)));
+ ret.insert (std::make_pair (NGBR_VIDEO_TCP_PREMIUM, std::make_tuple (false, 80, 300, 1.0e-6, 0, 0)));
+ ret.insert (std::make_pair (NGBR_VIDEO_TCP_DEFAULT, std::make_tuple (false, 90, 300, 1.0e-6, 0, 0)));
+ ret.insert (std::make_pair (NGBR_MC_DELAY_SIGNAL, std::make_tuple (false, 5, 60, 1.0e-6, 0, 0)));
+ ret.insert (std::make_pair (NGBR_MC_DATA, std::make_tuple (false, 55, 200, 1.0e-6, 0, 0)));
+ ret.insert (std::make_pair (NGBR_V2X, std::make_tuple (false, 65, 5, 1.0e-2, 0, 0)));
+ ret.insert (std::make_pair (NGBR_LOW_LAT_EMBB, std::make_tuple (false, 68, 10, 1.0e-6, 0, 0)));
+ ret.insert (std::make_pair (DGBR_DISCRETE_AUT_SMALL, std::make_tuple (false, 19, 10, 1.0e-4, 255, 2000)));
+ ret.insert (std::make_pair (DGBR_DISCRETE_AUT_LARGE, std::make_tuple (false, 22, 10, 1.0e-4, 1358, 2000)));
+ ret.insert (std::make_pair (DGBR_ITS, std::make_tuple (false, 24, 30, 1.0e-5, 1354, 2000)));
+ ret.insert (std::make_pair (DGBR_ELECTRICITY, std::make_tuple (false, 21, 5, 1.0e-5, 255, 2000)));
+ }
+ return ret;
+}
+
} // namespace ns3
diff --git a/src/lte/model/eps-bearer.h b/src/lte/model/eps-bearer.h
index 72521e8fa..a2c1b0e66 100644
--- a/src/lte/model/eps-bearer.h
+++ b/src/lte/model/eps-bearer.h
@@ -82,11 +82,23 @@ struct EpsBearer
GBR_CONV_VIDEO = 2, ///< GBR Conversational Video (Live streaming)
GBR_GAMING = 3, ///< GBR Real Time Gaming
GBR_NON_CONV_VIDEO = 4, ///< GBR Non-Conversational Video (Buffered Streaming)
+ GBR_MC_PUSH_TO_TALK = 65, ///< GBR Mission Critical User Plane Push To Talk voice
+ GBR_NMC_PUSH_TO_TALK = 66, ///< GBR Non-Mission-Critical User Plane Push To Talk voice
+ GBR_MC_VIDEO = 67, ///< GBR Mission Critical Video User Plane
+ GBR_V2X = 75, ///< GBR V2X Messages
NGBR_IMS = 5, ///< Non-GBR IMS Signalling
NGBR_VIDEO_TCP_OPERATOR = 6, ///< Non-GBR TCP-based Video (Buffered Streaming, e.g., www, e-mail...)
NGBR_VOICE_VIDEO_GAMING = 7, ///< Non-GBR Voice, Video, Interactive Streaming
NGBR_VIDEO_TCP_PREMIUM = 8, ///< Non-GBR TCP-based Video (Buffered Streaming, e.g., www, e-mail...)
NGBR_VIDEO_TCP_DEFAULT = 9, ///< Non-GBR TCP-based Video (Buffered Streaming, e.g., www, e-mail...)
+ NGBR_MC_DELAY_SIGNAL = 69, ///< Non-GBR Mission Critical Delay Sensitive Signalling (e.g., MC-PTT)
+ NGBR_MC_DATA = 70, ///< Non-GBR Mission Critical Data
+ NGBR_V2X = 79, ///< Non-GBR V2X Messages
+ NGBR_LOW_LAT_EMBB = 80, ///< Non-GBR Low Latency eMBB applications
+ DGBR_DISCRETE_AUT_SMALL = 82, ///< Delay-Critical GBR Discrete Automation Small Packets (TS 22.261)
+ DGBR_DISCRETE_AUT_LARGE = 83, ///< Delay-Critical GBR Discrete Automation Large Packets (TS 22.261)
+ DGBR_ITS = 84, ///< Delay-Critical GBR Intelligent Transport Systems (TS 22.261)
+ DGBR_ELECTRICITY = 85, ///< Delay-Critical GBR Electricity Distribution High Voltage (TS 22.261)
} qci; ///< Qos class indicator
GbrQosInformation gbrQosInfo; ///< GBR QOS information
@@ -226,6 +238,12 @@ private:
*/
static BearerRequirementsMap GetRequirementsRel11 ();
+ /**
+ * \brief Retrieve requirements for Rel. 15
+ * \return the BearerRequirementsMap for Release 15
+ */
+ static BearerRequirementsMap GetRequirementsRel15 ();
+
/**
* \brief Requirements per bearer
*/
From d3da3b8628d997d9a2beac1fced334b1d805cf11 Mon Sep 17 00:00:00 2001
From: Natale Patriciello
Date: Thu, 25 Oct 2018 15:20:47 +0200
Subject: [PATCH 03/11] lte: EpsBearer support run-time switching between Rel.
11 and Rel. 15
EpsBearer is now a ns-3 Object, and carries an attribute, "Release",
to switch between releases.
---
CHANGES.html | 1 +
src/lte/model/eps-bearer.cc | 91 +++++++++++++++++++++++++++++--------
src/lte/model/eps-bearer.h | 88 ++++++++++++++++++++++++++++++++---
3 files changed, 156 insertions(+), 24 deletions(-)
diff --git a/CHANGES.html b/CHANGES.html
index d21e57c5c..93bf948c8 100644
--- a/CHANGES.html
+++ b/CHANGES.html
@@ -54,6 +54,7 @@ us a note on ns-developers mailing list.
Changes from ns-3.29 to ns-3.30
New API:
+- Added the attribute Release to the class EpsBearer, to select the release (e.g., release 15)
- The attributes RegularWifiMac::HtSupported, RegularWifiMac::VhtSupported, RegularWifiMac::HeSupported, RegularWifiMac::RifsSupported, WifiPhy::ShortGuardEnabled, WifiPhy::GuardInterval and WifiPhy::GreenfieldEnabled have been deprecated. Intead, it is advised to use WifiNetDevice::HtConfiguration, WifiNetDevice::VhtConfiguration and WifiNetDevice::HeConfiguration.
- A new attribute WifiPhy::PostReceptionErrorModel has been added to force specific packet drops.
- A new attribute WifiPhy::PreambleDetectionModel has been added to decide whether PHY preambles are successfully detected.
diff --git a/src/lte/model/eps-bearer.cc b/src/lte/model/eps-bearer.cc
index e2b91dc37..825ecf40d 100644
--- a/src/lte/model/eps-bearer.cc
+++ b/src/lte/model/eps-bearer.cc
@@ -18,14 +18,13 @@
* Author: Nicola Baldo
*/
-
#include "eps-bearer.h"
-
#include
-
+#include
namespace ns3 {
+NS_OBJECT_ENSURE_REGISTERED (EpsBearer);
GbrQosInformation::GbrQosInformation ()
: gbrDl (0),
@@ -42,49 +41,105 @@ AllocationRetentionPriority::AllocationRetentionPriority ()
{
}
-EpsBearer::EpsBearer ()
- : qci (NGBR_VIDEO_TCP_DEFAULT)
+TypeId
+EpsBearer::GetTypeId (void)
{
- m_requirements = GetRequirementsRel11 ();
+ static TypeId tid = TypeId ("ns3::EpsBearer")
+ .SetParent ()
+ .SetGroupName("Lte")
+ .AddConstructor ()
+ .AddAttribute ("Release", "Change from 11 to 15 if you need bearer definition as per Release 15."
+ " Reference document: TS 23.203. The change does not impact other LTE code than "
+ " bearers definition.",
+ UintegerValue (11),
+ MakeUintegerAccessor (&EpsBearer::GetRelease,
+ &EpsBearer::SetRelease),
+ MakeUintegerChecker ())
+ ;
+ return tid;
+}
+
+TypeId
+EpsBearer::GetInstanceTypeId () const
+{
+ return EpsBearer::GetTypeId ();
+}
+
+EpsBearer::EpsBearer ()
+ : ObjectBase (),
+ qci (NGBR_VIDEO_TCP_DEFAULT)
+{
+
+ ObjectBase::ConstructSelf (AttributeConstructionList ());
}
EpsBearer::EpsBearer (Qci x)
- : qci (x)
+ : ObjectBase (),
+ qci (x)
{
- m_requirements = GetRequirementsRel11 ();
+ ObjectBase::ConstructSelf (AttributeConstructionList ());
}
EpsBearer::EpsBearer (Qci x, struct GbrQosInformation y)
- : qci (x), gbrQosInfo (y)
+ : ObjectBase (),
+ qci (x), gbrQosInfo (y)
{
- m_requirements = GetRequirementsRel11 ();
+ ObjectBase::ConstructSelf (AttributeConstructionList ());
+}
+
+EpsBearer::EpsBearer (const EpsBearer &o) : ObjectBase (o)
+{
+ qci = o.qci;
+ gbrQosInfo = o.gbrQosInfo;
+ ObjectBase::ConstructSelf (AttributeConstructionList ());
+}
+
+void
+EpsBearer::SetRelease(uint8_t release)
+{
+ switch (release)
+ {
+ case 8:
+ case 9:
+ case 10:
+ case 11:
+ m_requirements = GetRequirementsRel11 ();
+ break;
+ case 15:
+ m_requirements = GetRequirementsRel15 ();
+ break;
+ default:
+ NS_FATAL_ERROR ("Not recognized release " << static_cast (release) <<
+ " please use a value between 8 and 11, or 15");
+ }
+ m_release = release;
}
bool
EpsBearer::IsGbr () const
{
- return IsGbr (m_requirements, qci);
+ return IsGbr (*m_requirements, qci);
}
uint8_t
EpsBearer::GetPriority () const
{
- return GetPriority (m_requirements, qci);
+ return GetPriority (*m_requirements, qci);
}
uint16_t
EpsBearer::GetPacketDelayBudgetMs () const
{
- return GetPacketDelayBudgetMs (m_requirements, qci);
+ return GetPacketDelayBudgetMs (*m_requirements, qci);
}
double
EpsBearer::GetPacketErrorLossRate () const
{
- return GetPacketErrorLossRate (m_requirements, qci);
+ return GetPacketErrorLossRate (*m_requirements, qci);
}
-EpsBearer::BearerRequirementsMap
+EpsBearer::BearerRequirementsMap *
EpsBearer::GetRequirementsRel11 ()
{
/* Needed to support GCC 4.9. Otherwise, use list constructors, for example:
@@ -112,10 +167,10 @@ EpsBearer::GetRequirementsRel11 ()
ret.insert (std::make_pair (NGBR_VIDEO_TCP_PREMIUM, std::make_tuple (false, 8, 300, 1.0e-6, 0, 0)));
ret.insert (std::make_pair (NGBR_VIDEO_TCP_DEFAULT, std::make_tuple (false, 9, 300, 1.0e-6, 0, 0)));
}
- return ret;
+ return &ret;
}
-EpsBearer::BearerRequirementsMap
+EpsBearer::BearerRequirementsMap *
EpsBearer::GetRequirementsRel15 ()
{
// Needed to support GCC 4.9. Otherwise, use list constructors (see GetRequirementsRel10)
@@ -145,7 +200,7 @@ EpsBearer::GetRequirementsRel15 ()
ret.insert (std::make_pair (DGBR_ITS, std::make_tuple (false, 24, 30, 1.0e-5, 1354, 2000)));
ret.insert (std::make_pair (DGBR_ELECTRICITY, std::make_tuple (false, 21, 5, 1.0e-5, 255, 2000)));
}
- return ret;
+ return &ret;
}
} // namespace ns3
diff --git a/src/lte/model/eps-bearer.h b/src/lte/model/eps-bearer.h
index a2c1b0e66..604759a84 100644
--- a/src/lte/model/eps-bearer.h
+++ b/src/lte/model/eps-bearer.h
@@ -23,6 +23,7 @@
#define EPS_BEARER
#include
+#include
#include
namespace ns3 {
@@ -61,16 +62,42 @@ struct AllocationRetentionPriority
};
/**
- * This class contains the specification of EPS Bearers.
+ * \brief This class contains the specification of EPS Bearers.
*
* See the following references:
* 3GPP TS 23.203, Section 4.7.2 The EPS bearer
* 3GPP TS 23.203, Section 4.7.3 Bearer level QoS parameters
* 3GPP TS 36.413 Section 9.2.1.15 E-RAB Level QoS Parameters
*
+ * It supports the selection of different specifications depending on the
+ * release. To change the release, change the attribute "Release". Please remember
+ * that we must expose to all releases the most recent Qci. Asking for Qci parameters
+ * for a release in which it has not been created will result in a crash.
+ *
+ * For example, if you select Release 11 (or if you don't select anything, as
+ * it is the default selection) and then ask for the packet error rate of
+ * the NGBR_MC_DELAY_SIGNAL Qci, the program will crash.
+ *
+ * Please note that from Release 8 (the latest when the LENA project finished)
+ * to Release 11, the bearers ID and requirements are the same. From Release 12,
+ * they started to change, and the latest version is now Release 15. However,
+ * we do not support intermediate types: in other words, you can select from
+ * Release 8 to Release 11, or Release 15. Any other value will result in a
+ * program crash.
+ *
+ * The release version only affect Bearer definitions. Other part of the LTE
+ * module are not affected when changing the Release attribute.
*/
-struct EpsBearer
+class EpsBearer : public ObjectBase
{
+public:
+ /**
+ * \brief Get the type ID.
+ * \return the object TypeId
+ */
+ static TypeId GetTypeId (void);
+
+ virtual TypeId GetInstanceTypeId (void) const override;
/**
* QoS Class Indicator. See 3GPP 23.203 Section 6.1.7.2 for standard values.
@@ -125,6 +152,37 @@ struct EpsBearer
*/
EpsBearer (Qci x, GbrQosInformation y);
+ /**
+ * \brief EpsBearer copy constructor
+ * \param o other instance
+ */
+ EpsBearer (const EpsBearer &o);
+
+ /**
+ * \brief Deconstructor
+ */
+ virtual ~EpsBearer () { }
+
+ /**
+ * \brief SetRelease
+ * \param release The release the user want for this bearer
+ *
+ * Releases introduces new types, and change values for existing ones.
+ * While we can't do much for the added type (we must expose them even
+ * if the user want to work with older releases) by calling this method
+ * we can, at least, select the specific parameters value the bearer returns.
+ *
+ * For instance, if the user select release 10 (the default) the priority
+ * of CONV_VIDEO will be 2. With release 15, such priority will be 20.
+ */
+ void SetRelease (uint8_t release);
+
+ /**
+ * \brief GetRelease
+ * \return The release currently set for this bearer type
+ */
+ uint8_t GetRelease () const { return m_release; }
+
/**
*
* @return true if the EPS Bearer is a Guaranteed Bit Rate bearer, false otherwise
@@ -235,19 +293,37 @@ private:
/**
* \brief Retrieve requirements for Rel. 11
* \return the BearerRequirementsMap for Release 11
+ *
+ * It returns a pointer to a non-const static data. That is not thread-safe,
+ * nor safe to do in general. However, a const-correct version would have
+ * to initialize two static maps, and then returning either one or the other.
+ * But that's a huge memory increase, and EpsBearer is used everywhere.
+ *
+ * To be revisited when GCC 4.9 will not be supported anymore.
*/
- static BearerRequirementsMap GetRequirementsRel11 ();
+ static BearerRequirementsMap * GetRequirementsRel11 ();
/**
* \brief Retrieve requirements for Rel. 15
* \return the BearerRequirementsMap for Release 15
+ *
+ * It returns a pointer to a non-const static data. That is not thread-safe,
+ * nor safe to do in general. However, a const-correct version would have
+ * to initialize two static maps, and then returning either one or the other.
+ * But that's a huge memory increase, and EpsBearer is used everywhere.
+ *
+ * To be revisited when GCC 4.9 will not be supported anymore.
*/
- static BearerRequirementsMap GetRequirementsRel15 ();
+ static BearerRequirementsMap * GetRequirementsRel15 ();
/**
- * \brief Requirements per bearer
+ * \brief Requirements pointer per bearer
+ *
+ * It will point to a static map.
*/
- BearerRequirementsMap m_requirements;
+ BearerRequirementsMap *m_requirements;
+
+ uint8_t m_release {30}; //!< Release (10 or 15)
};
} // namespace ns3
From dab08d714dbc3c9925b00efe71f42edcf190afec Mon Sep 17 00:00:00 2001
From: Natale Patriciello
Date: Wed, 24 Oct 2018 14:59:36 +0200
Subject: [PATCH 04/11] lte: (fixed #2893) GetPgw in helpers must be const
Simple const-correctness enforcing.
---
RELEASE_NOTES | 1 +
src/lte/helper/emu-epc-helper.cc | 2 +-
src/lte/helper/emu-epc-helper.h | 2 +-
src/lte/helper/epc-helper.h | 2 +-
src/lte/helper/point-to-point-epc-helper.cc | 2 +-
src/lte/helper/point-to-point-epc-helper.h | 2 +-
6 files changed, 6 insertions(+), 5 deletions(-)
diff --git a/RELEASE_NOTES b/RELEASE_NOTES
index 8dd8915bd..f74cb57ae 100644
--- a/RELEASE_NOTES
+++ b/RELEASE_NOTES
@@ -32,6 +32,7 @@ Bugs fixed
- Bug 2992 - lte: Send method of the LteUeNetDevice doesn't use protocolNumber parameter
- Bug 2997 - lte: EpcTft::PacketFilter::Matches does not use ipv6 address to match an IP packet
- Bug 2860 - mobility: Set Z coordinate for position-allocation classes
+- Bug 2893 - lte: GetPgw in helper should be const
- Bug 3027 - lte: S1 signalling is done before RRC connection establishment is finished
Known issues
diff --git a/src/lte/helper/emu-epc-helper.cc b/src/lte/helper/emu-epc-helper.cc
index 6e5fded64..5c113acf2 100644
--- a/src/lte/helper/emu-epc-helper.cc
+++ b/src/lte/helper/emu-epc-helper.cc
@@ -402,7 +402,7 @@ EmuEpcHelper::ActivateEpsBearer (Ptr ueDevice, uint64_t imsi, Ptr
-EmuEpcHelper::GetPgwNode ()
+EmuEpcHelper::GetPgwNode () const
{
return m_sgwPgw;
}
diff --git a/src/lte/helper/emu-epc-helper.h b/src/lte/helper/emu-epc-helper.h
index 9f3126978..267dd737a 100644
--- a/src/lte/helper/emu-epc-helper.h
+++ b/src/lte/helper/emu-epc-helper.h
@@ -80,7 +80,7 @@ public:
virtual void AddUe (Ptr ueLteDevice, uint64_t imsi);
virtual void AddX2Interface (Ptr enbNode1, Ptr enbNode2);
virtual uint8_t ActivateEpsBearer (Ptr ueLteDevice, uint64_t imsi, Ptr tft, EpsBearer bearer);
- virtual Ptr GetPgwNode ();
+ virtual Ptr GetPgwNode () const;
virtual Ipv4InterfaceContainer AssignUeIpv4Address (NetDeviceContainer ueDevices);
virtual Ipv6InterfaceContainer AssignUeIpv6Address (NetDeviceContainer ueDevices);
virtual Ipv4Address GetUeDefaultGatewayAddress ();
diff --git a/src/lte/helper/epc-helper.h b/src/lte/helper/epc-helper.h
index 38b36d7c4..a75b626a1 100644
--- a/src/lte/helper/epc-helper.h
+++ b/src/lte/helper/epc-helper.h
@@ -120,7 +120,7 @@ public:
* intended for this method is to allow the user to configure the Gi
* interface of the PGW, i.e., to connect the PGW to the internet.
*/
- virtual Ptr GetPgwNode () = 0;
+ virtual Ptr GetPgwNode () const = 0;
/**
* Assign IPv4 addresses to UE devices
diff --git a/src/lte/helper/point-to-point-epc-helper.cc b/src/lte/helper/point-to-point-epc-helper.cc
index 380e7036b..fe6304e65 100644
--- a/src/lte/helper/point-to-point-epc-helper.cc
+++ b/src/lte/helper/point-to-point-epc-helper.cc
@@ -546,7 +546,7 @@ PointToPointEpcHelper::ActivateEpsBearer (Ptr ueDevice, uint64_t imsi
}
Ptr
-PointToPointEpcHelper::GetPgwNode ()
+PointToPointEpcHelper::GetPgwNode () const
{
return m_pgw;
}
diff --git a/src/lte/helper/point-to-point-epc-helper.h b/src/lte/helper/point-to-point-epc-helper.h
index 980d8bc78..b2e252aa5 100644
--- a/src/lte/helper/point-to-point-epc-helper.h
+++ b/src/lte/helper/point-to-point-epc-helper.h
@@ -77,7 +77,7 @@ public:
virtual void AddUe (Ptr ueLteDevice, uint64_t imsi);
virtual void AddX2Interface (Ptr enbNode1, Ptr enbNode2);
virtual uint8_t ActivateEpsBearer (Ptr ueLteDevice, uint64_t imsi, Ptr tft, EpsBearer bearer);
- virtual Ptr GetPgwNode ();
+ virtual Ptr GetPgwNode () const;
virtual Ipv4InterfaceContainer AssignUeIpv4Address (NetDeviceContainer ueDevices);
virtual Ipv6InterfaceContainer AssignUeIpv6Address (NetDeviceContainer ueDevices);
virtual Ipv4Address GetUeDefaultGatewayAddress ();
From 8fb0649c2bd4061a3ff88abd32fe6e8dd1f37476 Mon Sep 17 00:00:00 2001
From: Natale Patriciello
Date: Wed, 24 Oct 2018 15:00:48 +0200
Subject: [PATCH 05/11] lte: LteMacSap constructors for ReceivePduParameters
and TxOpportunityParameters created
Thanks to constructors, it is easier to create these structs. In particular, code like this
MyAwesomeStruct x;
x.value = 10;
x.another = 200;
...
AMethod (x);
can be replaced with
AMethod (MyAwesomeStruct (10, 200));
Reducing the amount of needed lines.
---
src/lte/model/lte-mac-sap.h | 41 +++++++++++++++++++++++++++++++++++++
1 file changed, 41 insertions(+)
diff --git a/src/lte/model/lte-mac-sap.h b/src/lte/model/lte-mac-sap.h
index c4ebd3bb6..ed0bd1057 100644
--- a/src/lte/model/lte-mac-sap.h
+++ b/src/lte/model/lte-mac-sap.h
@@ -102,6 +102,30 @@ public:
*/
struct TxOpportunityParameters
{
+ /**
+ * \brief TxOpportunityParameters constructor
+ * \param bytes Bytes
+ * \param layer Layer
+ * \param harqId HarqID
+ * \param ccId Component carrier ID
+ * \param rnti RNTI
+ * \param lcId Logical Channel ID
+ */
+ TxOpportunityParameters (uint32_t bytes, uint8_t layer, uint8_t harqId,
+ uint8_t ccId, uint16_t rnti, uint8_t lcId)
+ {
+ this->bytes = bytes;
+ this->layer = layer;
+ this->harqId = harqId;
+ this->componentCarrierId = ccId;
+ this->rnti = rnti;
+ this->lcid = lcId;
+ }
+ /**
+ * \brief TxOpportunityParameters default constructor (DEPRECATED)
+ */
+ TxOpportunityParameters () { }
+
uint32_t bytes; /**< the number of bytes to transmit */
uint8_t layer; /**< the layer of transmission (MIMO) */
uint8_t harqId; /**< the HARQ ID */
@@ -131,6 +155,23 @@ public:
*/
struct ReceivePduParameters
{
+ /**
+ * \brief ReceivePduParameters default constructor (DEPRECATED)
+ */
+ ReceivePduParameters () { }
+
+ /**
+ * \brief ReceivePduParameters constructor
+ * \param p Packet
+ * \param rnti RNTI
+ * \param lcid Logical Channel ID
+ */
+ ReceivePduParameters (const Ptr &p, uint16_t rnti, uint8_t lcid)
+ {
+ this->p = p;
+ this->rnti = rnti;
+ this->lcid = lcid;
+ }
Ptr p; /**< the RLC PDU to be received */
uint16_t rnti; /**< the C-RNTI identifying the UE */
uint8_t lcid; /**< the logical channel id */
From 90966b91267343a3b0b1b13d13e73f9c769ed63c Mon Sep 17 00:00:00 2001
From: Natale Patriciello
Date: Wed, 24 Oct 2018 15:07:52 +0200
Subject: [PATCH 06/11] lte: ComponentCarrier with cellId is now
ComponentCarrierBaseStation
For the NR module we have the necessity of implementing a different type of
ComponentCarrierEnb, which will be ComponentCarrierGnb. But, in some methods of
RRC, it is accepted only a pointer to ComponentCarrierEnb.
To solve this situation, since the only needed method from ComponentCarrierEnb
is GetCellId (), this commit creates a new class (ComponentCarrierBaseStation)
that provides the interface for setting and retrieving the cell id. Then, both
ComponentCarrier{Enb,Gnb} derives from ComponentCarrierBaseStation and everyone
is happy. I had to introduce DynamicCast all over the helper to make everything
working.
---
src/lte/helper/lte-helper.cc | 70 +++++++++++++-------------
src/lte/model/component-carrier-enb.cc | 46 ++++++++++++-----
src/lte/model/component-carrier-enb.h | 20 +-------
src/lte/model/component-carrier.h | 36 ++++++++++++-
src/lte/model/lte-enb-net-device.cc | 21 ++++----
src/lte/model/lte-enb-net-device.h | 10 ++--
src/lte/model/lte-enb-rrc.cc | 6 +--
src/lte/model/lte-enb-rrc.h | 6 +--
8 files changed, 124 insertions(+), 91 deletions(-)
diff --git a/src/lte/helper/lte-helper.cc b/src/lte/helper/lte-helper.cc
index dde823e4b..b68730cf8 100644
--- a/src/lte/helper/lte-helper.cc
+++ b/src/lte/helper/lte-helper.cc
@@ -518,7 +518,7 @@ LteHelper::InstallSingleEnbDevice (Ptr n)
m_noOfCcs << ")");
// create component carrier map for this eNb device
- std::map > ccMap;
+ std::map > ccMap;
for (std::map::iterator it = m_componentCarrierPhyParams.begin ();
it != m_componentCarrierPhyParams.end ();
++it)
@@ -539,7 +539,7 @@ LteHelper::InstallSingleEnbDevice (Ptr n)
NS_ABORT_MSG_IF (m_useCa && ccMap.size()<2, "You have to either specify carriers or disable carrier aggregation");
NS_ASSERT (ccMap.size () == m_noOfCcs);
- for (std::map >::iterator it = ccMap.begin (); it != ccMap.end (); ++it)
+ for (auto it = ccMap.begin (); it != ccMap.end (); ++it)
{
NS_LOG_DEBUG (this << "component carrier map size " << (uint16_t) ccMap.size ());
Ptr dlPhy = CreateObject ();
@@ -580,12 +580,10 @@ LteHelper::InstallSingleEnbDevice (Ptr n)
Ptr mac = CreateObject ();
Ptr sched = m_schedulerFactory.Create ();
Ptr ffrAlgorithm = m_ffrAlgorithmFactory.Create ();
- it->second->SetMac (mac);
- it->second->SetFfMacScheduler (sched);
- it->second->SetFfrAlgorithm (ffrAlgorithm);
-
- it->second->SetPhy (phy);
-
+ DynamicCast (it->second)->SetMac (mac);
+ DynamicCast (it->second)->SetFfMacScheduler (sched);
+ DynamicCast (it->second)->SetFfrAlgorithm (ffrAlgorithm);
+ DynamicCast (it->second)->SetPhy (phy);
}
Ptr rrc = CreateObject ();
@@ -642,41 +640,41 @@ LteHelper::InstallSingleEnbDevice (Ptr n)
rrc->SetLteMacSapProvider (ccmEnbManager->GetLteMacSapProvider ());
bool ccmTest;
- for (std::map >::iterator it = ccMap.begin (); it != ccMap.end (); ++it)
+ for (auto it = ccMap.begin (); it != ccMap.end (); ++it)
{
- it->second->GetPhy ()->SetLteEnbCphySapUser (rrc->GetLteEnbCphySapUser (it->first));
- rrc->SetLteEnbCphySapProvider (it->second->GetPhy ()->GetLteEnbCphySapProvider (), it->first);
+ DynamicCast (it->second)->GetPhy ()->SetLteEnbCphySapUser (rrc->GetLteEnbCphySapUser (it->first));
+ rrc->SetLteEnbCphySapProvider (DynamicCast (it->second)->GetPhy ()->GetLteEnbCphySapProvider (), it->first);
- rrc->SetLteEnbCmacSapProvider (it->second->GetMac ()->GetLteEnbCmacSapProvider (),it->first );
- it->second->GetMac ()->SetLteEnbCmacSapUser (rrc->GetLteEnbCmacSapUser (it->first));
+ rrc->SetLteEnbCmacSapProvider (DynamicCast (it->second)->GetMac ()->GetLteEnbCmacSapProvider (),it->first );
+ DynamicCast (it->second)->GetMac ()->SetLteEnbCmacSapUser (rrc->GetLteEnbCmacSapUser (it->first));
- it->second->GetPhy ()->SetComponentCarrierId (it->first);
- it->second->GetMac ()->SetComponentCarrierId (it->first);
+ DynamicCast (it->second)->GetPhy ()->SetComponentCarrierId (it->first);
+ DynamicCast (it->second)->GetMac ()->SetComponentCarrierId (it->first);
//FFR SAP
- it->second->GetFfMacScheduler ()->SetLteFfrSapProvider (it->second->GetFfrAlgorithm ()->GetLteFfrSapProvider ());
- it->second->GetFfrAlgorithm ()->SetLteFfrSapUser (it->second->GetFfMacScheduler ()->GetLteFfrSapUser ());
- rrc->SetLteFfrRrcSapProvider (it->second->GetFfrAlgorithm ()->GetLteFfrRrcSapProvider (), it->first);
- it->second->GetFfrAlgorithm ()->SetLteFfrRrcSapUser (rrc->GetLteFfrRrcSapUser (it->first));
+ DynamicCast (it->second)->GetFfMacScheduler ()->SetLteFfrSapProvider (DynamicCast (it->second)->GetFfrAlgorithm ()->GetLteFfrSapProvider ());
+ DynamicCast (it->second)->GetFfrAlgorithm ()->SetLteFfrSapUser (DynamicCast (it->second)->GetFfMacScheduler ()->GetLteFfrSapUser ());
+ rrc->SetLteFfrRrcSapProvider (DynamicCast (it->second)->GetFfrAlgorithm ()->GetLteFfrRrcSapProvider (), it->first);
+ DynamicCast (it->second)->GetFfrAlgorithm ()->SetLteFfrRrcSapUser (rrc->GetLteFfrRrcSapUser (it->first));
//FFR SAP END
// PHY <--> MAC SAP
- it->second->GetPhy ()->SetLteEnbPhySapUser (it->second->GetMac ()->GetLteEnbPhySapUser ());
- it->second->GetMac ()->SetLteEnbPhySapProvider (it->second->GetPhy ()->GetLteEnbPhySapProvider ());
+ DynamicCast (it->second)->GetPhy ()->SetLteEnbPhySapUser (DynamicCast (it->second)->GetMac ()->GetLteEnbPhySapUser ());
+ DynamicCast (it->second)->GetMac ()->SetLteEnbPhySapProvider (DynamicCast (it->second)->GetPhy ()->GetLteEnbPhySapProvider ());
// PHY <--> MAC SAP END
//Scheduler SAP
- it->second->GetMac ()->SetFfMacSchedSapProvider (it->second->GetFfMacScheduler ()->GetFfMacSchedSapProvider ());
- it->second->GetMac ()->SetFfMacCschedSapProvider (it->second->GetFfMacScheduler ()->GetFfMacCschedSapProvider ());
+ DynamicCast (it->second)->GetMac ()->SetFfMacSchedSapProvider (DynamicCast (it->second)->GetFfMacScheduler ()->GetFfMacSchedSapProvider ());
+ DynamicCast (it->second)->GetMac ()->SetFfMacCschedSapProvider (DynamicCast (it->second)->GetFfMacScheduler ()->GetFfMacCschedSapProvider ());
- it->second->GetFfMacScheduler ()->SetFfMacSchedSapUser (it->second->GetMac ()->GetFfMacSchedSapUser ());
- it->second->GetFfMacScheduler ()->SetFfMacCschedSapUser (it->second->GetMac ()->GetFfMacCschedSapUser ());
+ DynamicCast (it->second)->GetFfMacScheduler ()->SetFfMacSchedSapUser (DynamicCast (it->second)->GetMac ()->GetFfMacSchedSapUser ());
+ DynamicCast (it->second)->GetFfMacScheduler ()->SetFfMacCschedSapUser (DynamicCast (it->second)->GetMac ()->GetFfMacCschedSapUser ());
// Scheduler SAP END
- it->second->GetMac ()->SetLteCcmMacSapUser (ccmEnbManager->GetLteCcmMacSapUser ());
- ccmEnbManager->SetCcmMacSapProviders (it->first, it->second->GetMac ()->GetLteCcmMacSapProvider ());
+ DynamicCast (it->second)->GetMac ()->SetLteCcmMacSapUser (ccmEnbManager->GetLteCcmMacSapUser ());
+ ccmEnbManager->SetCcmMacSapProviders (it->first, DynamicCast (it->second)->GetMac ()->GetLteCcmMacSapProvider ());
// insert the pointer to the LteMacSapProvider interface of the MAC layer of the specific component carrier
- ccmTest = ccmEnbManager->SetMacSapProvider (it->first, it->second->GetMac ()->GetLteMacSapProvider());
+ ccmTest = ccmEnbManager->SetMacSapProvider (it->first, DynamicCast (it->second)->GetMac ()->GetLteMacSapProvider());
if (ccmTest == false)
{
@@ -690,10 +688,10 @@ LteHelper::InstallSingleEnbDevice (Ptr n)
dev->SetAttribute ("CellId", UintegerValue (cellId));
dev->SetAttribute ("LteEnbComponentCarrierManager", PointerValue (ccmEnbManager));
dev->SetCcMap (ccMap);
- std::map >::iterator it = ccMap.begin ();
+ std::map >::iterator it = ccMap.begin ();
dev->SetAttribute ("LteEnbRrc", PointerValue (rrc));
dev->SetAttribute ("LteHandoverAlgorithm", PointerValue (handoverAlgorithm));
- dev->SetAttribute ("LteFfrAlgorithm", PointerValue (it->second->GetFfrAlgorithm ()));
+ dev->SetAttribute ("LteFfrAlgorithm", PointerValue (DynamicCast (it->second)->GetFfrAlgorithm ()));
if (m_isAnrEnabled)
{
@@ -705,7 +703,7 @@ LteHelper::InstallSingleEnbDevice (Ptr n)
for (it = ccMap.begin (); it != ccMap.end (); ++it)
{
- Ptr ccPhy = it->second->GetPhy ();
+ Ptr ccPhy = DynamicCast (it->second)->GetPhy ();
ccPhy->SetDevice (dev);
ccPhy->GetUlSpectrumPhy ()->SetDevice (dev);
ccPhy->GetDlSpectrumPhy ()->SetDevice (dev);
@@ -736,7 +734,7 @@ LteHelper::InstallSingleEnbDevice (Ptr n)
for (it = ccMap.begin (); it != ccMap.end (); ++it)
{
- m_uplinkChannel->AddRx (it->second->GetPhy ()->GetUlSpectrumPhy ());
+ m_uplinkChannel->AddRx (DynamicCast(it->second)->GetPhy ()->GetUlSpectrumPhy ());
}
if (m_epcHelper != 0)
@@ -1459,11 +1457,11 @@ LteHelper::AssignStreams (NetDeviceContainer c, int64_t stream)
Ptr lteEnb = DynamicCast (netDevice);
if (lteEnb)
{
- std::map< uint8_t, Ptr > tmpMap = lteEnb->GetCcMap ();
- std::map< uint8_t, Ptr >::iterator it;
+ std::map< uint8_t, Ptr > tmpMap = lteEnb->GetCcMap ();
+ std::map< uint8_t, Ptr >::iterator it;
it = tmpMap.begin ();
- Ptr dlPhy = it->second->GetPhy ()->GetDownlinkSpectrumPhy ();
- Ptr ulPhy = it->second->GetPhy ()->GetUplinkSpectrumPhy ();
+ Ptr dlPhy = DynamicCast (it->second)->GetPhy ()->GetDownlinkSpectrumPhy ();
+ Ptr ulPhy = DynamicCast (it->second)->GetPhy ()->GetUplinkSpectrumPhy ();
currentStream += dlPhy->AssignStreams (currentStream);
currentStream += ulPhy->AssignStreams (currentStream);
}
diff --git a/src/lte/model/component-carrier-enb.cc b/src/lte/model/component-carrier-enb.cc
index 98c1f2dee..fb77e2c37 100644
--- a/src/lte/model/component-carrier-enb.cc
+++ b/src/lte/model/component-carrier-enb.cc
@@ -116,12 +116,6 @@ ComponentCarrierEnb::DoInitialize (void)
}
-uint16_t
-ComponentCarrierEnb::GetCellId ()
-{
- return m_cellId;
-}
-
Ptr
ComponentCarrierEnb::GetPhy ()
{
@@ -129,12 +123,6 @@ ComponentCarrierEnb::GetPhy ()
return m_phy;
}
-void
-ComponentCarrierEnb::SetCellId (uint16_t cellId)
-{
- NS_LOG_FUNCTION (this << cellId);
- m_cellId = cellId;
-}
void
ComponentCarrierEnb::SetPhy (Ptr s)
@@ -184,6 +172,40 @@ ComponentCarrierEnb::SetFfMacScheduler (Ptr s)
m_scheduler = s;
}
+TypeId ComponentCarrierBaseStation::GetTypeId (void)
+{
+ static TypeId
+ tid =
+ TypeId ("ns3::ComponentCarrierBaseStation")
+ .SetParent ()
+ .AddConstructor ()
+ ;
+ return tid;
+}
+
+ComponentCarrierBaseStation::ComponentCarrierBaseStation ()
+{
+ NS_LOG_FUNCTION (this);
+}
+
+ComponentCarrierBaseStation::~ComponentCarrierBaseStation (void)
+{
+ NS_LOG_FUNCTION (this);
+}
+
+uint16_t
+ComponentCarrierBaseStation::GetCellId ()
+{
+ return m_cellId;
+}
+
+void
+ComponentCarrierBaseStation::SetCellId (uint16_t cellId)
+{
+ NS_LOG_FUNCTION (this << cellId);
+ m_cellId = cellId;
+}
+
} // namespace ns3
diff --git a/src/lte/model/component-carrier-enb.h b/src/lte/model/component-carrier-enb.h
index ec381268c..da8780938 100644
--- a/src/lte/model/component-carrier-enb.h
+++ b/src/lte/model/component-carrier-enb.h
@@ -45,7 +45,7 @@ class LteFfrAlgorithm;
* LteEnbMac, LteFfrAlgorithm, and FfMacScheduler objects.
*
*/
-class ComponentCarrierEnb : public ComponentCarrier
+class ComponentCarrierEnb : public ComponentCarrierBaseStation
{
public:
/**
@@ -59,12 +59,6 @@ public:
virtual ~ComponentCarrierEnb (void);
virtual void DoDispose (void);
- /**
- * Get cell identifier
- * \return cell identifier
- */
- uint16_t GetCellId ();
-
/**
* \return a pointer to the physical layer.
*/
@@ -85,12 +79,6 @@ public:
*/
Ptr GetFfMacScheduler ();
- /**
- * Set physical cell identifier
- * \param cellId cell identifier
- */
- void SetCellId (uint16_t cellId);
-
/**
* Set the LteEnbPhy
* \param s a pointer to the LteEnbPhy
@@ -119,18 +107,12 @@ protected:
virtual void DoInitialize (void);
private:
-
- uint16_t m_cellId; ///< Cell identifier
Ptr m_phy; ///< the Phy instance of this eNodeB component carrier
Ptr m_mac; ///< the MAC instance of this eNodeB component carrier
Ptr m_scheduler; ///< the scheduler instance of this eNodeB component carrier
Ptr m_ffrAlgorithm; ///< the FFR algorithm instance of this eNodeB component carrier
-
-
};
} // namespace ns3
-
-
#endif /* COMPONENT_CARRIER_H */
diff --git a/src/lte/model/component-carrier.h b/src/lte/model/component-carrier.h
index c421ef94b..0eebfe8cc 100644
--- a/src/lte/model/component-carrier.h
+++ b/src/lte/model/component-carrier.h
@@ -35,12 +35,11 @@ namespace ns3 {
* \ingroup lte
*
* ComponentCarrier Object, it defines a single Carrier
- * This is the parent class for both ComponentCarrierEnb
+ * This is the parent class for both ComponentCarrierBaseStation
* and ComponentCarrierUe.
* This class contains the main physical configuration
* parameters for a carrier. Does not contain pointers to
* the MAC/PHY objects of the carrier.
-
*/
class ComponentCarrier : public Object
{
@@ -172,7 +171,40 @@ protected:
};
+/**
+ * \ingroup lte
+ *
+ * Defines a Base station, that is a ComponentCarrier but with a cell Id.
+ *
+ */
+class ComponentCarrierBaseStation : public ComponentCarrier
+{
+public:
+ /**
+ * \brief Get the type ID.
+ * \return the object TypeId
+ */
+ static TypeId GetTypeId (void);
+ ComponentCarrierBaseStation ();
+
+ virtual ~ComponentCarrierBaseStation (void);
+
+ /**
+ * Get cell identifier
+ * \return cell identifier
+ */
+ uint16_t GetCellId ();
+
+ /**
+ * Set physical cell identifier
+ * \param cellId cell identifier
+ */
+ void SetCellId (uint16_t cellId);
+
+protected:
+ uint16_t m_cellId; ///< Cell identifier
+};
} // namespace ns3
diff --git a/src/lte/model/lte-enb-net-device.cc b/src/lte/model/lte-enb-net-device.cc
index 7d6f21f4b..0dd7a7556 100644
--- a/src/lte/model/lte-enb-net-device.cc
+++ b/src/lte/model/lte-enb-net-device.cc
@@ -187,25 +187,25 @@ LteEnbNetDevice::DoDispose ()
Ptr
LteEnbNetDevice::GetMac () const
{
- return m_ccMap.at (0)->GetMac ();
+ return GetMac (0);
}
Ptr
LteEnbNetDevice::GetPhy () const
{
- return m_ccMap.at (0)->GetPhy ();
+ return GetPhy (0);
}
Ptr
-LteEnbNetDevice::GetMac (uint8_t index)
+LteEnbNetDevice::GetMac (uint8_t index) const
{
- return m_ccMap.at (index)->GetMac ();
+ return DynamicCast (m_ccMap.at (index))->GetMac ();
}
Ptr
-LteEnbNetDevice::GetPhy(uint8_t index)
+LteEnbNetDevice::GetPhy(uint8_t index) const
{
- return m_ccMap.at (index)->GetPhy ();
+ return DynamicCast (m_ccMap.at (index))->GetPhy ();
}
Ptr
@@ -347,14 +347,14 @@ LteEnbNetDevice::SetCsgIndication (bool csgIndication)
UpdateConfig (); // propagate the change to RRC level
}
-std::map < uint8_t, Ptr >
-LteEnbNetDevice::GetCcMap ()
+std::map < uint8_t, Ptr >
+LteEnbNetDevice::GetCcMap () const
{
return m_ccMap;
}
void
-LteEnbNetDevice::SetCcMap (std::map< uint8_t, Ptr > ccm)
+LteEnbNetDevice::SetCcMap (std::map< uint8_t, Ptr > ccm)
{
NS_ASSERT_MSG (!m_isConfigured, "attempt to set CC map after configuration");
m_ccMap = ccm;
@@ -366,8 +366,7 @@ LteEnbNetDevice::DoInitialize (void)
NS_LOG_FUNCTION (this);
m_isConstructed = true;
UpdateConfig ();
- std::map< uint8_t, Ptr >::iterator it;
- for (it = m_ccMap.begin (); it != m_ccMap.end (); ++it)
+ for (auto it = m_ccMap.begin (); it != m_ccMap.end (); ++it)
{
it->second->Initialize ();
}
diff --git a/src/lte/model/lte-enb-net-device.h b/src/lte/model/lte-enb-net-device.h
index 2038d61ce..8d0727ed8 100644
--- a/src/lte/model/lte-enb-net-device.h
+++ b/src/lte/model/lte-enb-net-device.h
@@ -79,7 +79,7 @@ public:
* \param index CC index
* \return a pointer to the MAC of the CC addressed by index.
*/
- Ptr GetMac (uint8_t index);
+ Ptr GetMac (uint8_t index) const;
/**
* \return a pointer to the physical layer of the PCC.
@@ -90,7 +90,7 @@ public:
* \param index SCC index
* \return a pointer to the physical layer of the SCC addressed by index.
*/
- Ptr GetPhy (uint8_t index);
+ Ptr GetPhy (uint8_t index) const;
/**
* \return a pointer to the Radio Resource Control instance of the eNB
@@ -204,14 +204,14 @@ public:
*
*/
- void SetCcMap (std::map< uint8_t, Ptr > ccm);
+ void SetCcMap (std::map< uint8_t, Ptr > ccm);
/**
* \returns The Component Carrier Map of the Enb.
*
*/
- std::map< uint8_t, Ptr > GetCcMap (void);
+ std::map< uint8_t, Ptr > GetCcMap (void) const;
protected:
// inherited from Object
@@ -253,7 +253,7 @@ private:
uint16_t m_csgId; ///< CSG ID
bool m_csgIndication; ///< CSG indication
- std::map < uint8_t, Ptr > m_ccMap; /**< ComponentCarrier map */
+ std::map < uint8_t, Ptr > m_ccMap; /**< ComponentCarrier map */
Ptr m_componentCarrierManager; ///< the component carrier manager of this eNb
diff --git a/src/lte/model/lte-enb-rrc.cc b/src/lte/model/lte-enb-rrc.cc
index 2942ff920..2211f9ef6 100644
--- a/src/lte/model/lte-enb-rrc.cc
+++ b/src/lte/model/lte-enb-rrc.cc
@@ -1460,7 +1460,7 @@ UeManager::BuildNonCriticalExtentionConfigurationCa ()
ccId++;
}
- Ptr eNbCcm = it.second;
+ Ptr eNbCcm = it.second;
LteRrcSap::SCellToAddMod component;
component.sCellIndex = ccId;
component.cellIdentification.physCellId = eNbCcm->GetCellId ();
@@ -1551,7 +1551,7 @@ LteEnbRrc::LteEnbRrc ()
}
void
-LteEnbRrc::ConfigureCarriers (std::map> ccPhyConf)
+LteEnbRrc::ConfigureCarriers (std::map> ccPhyConf)
{
NS_ASSERT_MSG (!m_carriersConfigured, "Secondary carriers can be configured only once.");
m_componentCarrierPhyConf = ccPhyConf;
@@ -2047,7 +2047,7 @@ LteEnbRrc::AddUeMeasReportConfig (LteRrcSap::ReportConfigEutra config)
}
void
-LteEnbRrc::ConfigureCell (std::map> ccPhyConf)
+LteEnbRrc::ConfigureCell (std::map> ccPhyConf)
{
auto it = ccPhyConf.begin ();
NS_ASSERT (it != ccPhyConf.end ());
diff --git a/src/lte/model/lte-enb-rrc.h b/src/lte/model/lte-enb-rrc.h
index fee531f52..44380fdb1 100644
--- a/src/lte/model/lte-enb-rrc.h
+++ b/src/lte/model/lte-enb-rrc.h
@@ -863,13 +863,13 @@ public:
*
* \param ccPhyConf the component carrier configuration
*/
- void ConfigureCell (std::map> ccPhyConf);
+ void ConfigureCell (std::map > ccPhyConf);
/**
* \brief Configure carriers.
* \param ccPhyConf the component carrier configuration
*/
- void ConfigureCarriers (std::map> ccPhyConf);
+ void ConfigureCarriers (std::map> ccPhyConf);
/**
* set the cell id of this eNB
@@ -1591,7 +1591,7 @@ private:
bool m_carriersConfigured; ///< are carriers configured
- std::map> m_componentCarrierPhyConf; ///< component carrier phy configuration
+ std::map> m_componentCarrierPhyConf; ///< component carrier phy configuration
}; // end of `class LteEnbRrc`
From 12e7e16754cb7594c70a4f027bc71cb2eb137314 Mon Sep 17 00:00:00 2001
From: Natale Patriciello
Date: Wed, 24 Oct 2018 20:15:56 +0200
Subject: [PATCH 07/11] lte: ComponentCarrier subclasses can override
Set{Dl,Ul}Bandwidth
These two methos are changed by the subclass in NR and mmWave module.
---
src/lte/model/component-carrier.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/lte/model/component-carrier.h b/src/lte/model/component-carrier.h
index 0eebfe8cc..6944e9eb3 100644
--- a/src/lte/model/component-carrier.h
+++ b/src/lte/model/component-carrier.h
@@ -63,7 +63,7 @@ public:
/**
* \param bw the uplink bandwidth in RBs
*/
- void SetUlBandwidth (uint8_t bw);
+ virtual void SetUlBandwidth (uint8_t bw);
/**
* \return the downlink bandwidth in RBs
@@ -73,7 +73,7 @@ public:
/**
* \param bw the downlink bandwidth in RBs
*/
- void SetDlBandwidth (uint8_t bw);
+ virtual void SetDlBandwidth (uint8_t bw);
/**
* \return the downlink carrier frequency (EARFCN)
From 6435c6d894fd6b67df055df4c7db3d4bb2464ce7 Mon Sep 17 00:00:00 2001
From: Natale Patriciello
Date: Thu, 25 Oct 2018 16:36:24 +0200
Subject: [PATCH 08/11] lte: Do not assume that the helper is setting all the
vectors
In lte-enb-rrc, in a lot of places there is the assumption that
vectors such as m_cphySapProvider, m_cmacSapProvider, m_ffrRrcSapProvider, are
filled by the helper.
That assumption does not hold with external modules: therefore, for a better
coexistence, check the size of these vector before doing any operation.
If there are elements in it, then execute; otherwise, just ignore.
---
src/lte/model/lte-enb-rrc.cc | 68 ++++++++++++++++++++++++++++--------
1 file changed, 54 insertions(+), 14 deletions(-)
diff --git a/src/lte/model/lte-enb-rrc.cc b/src/lte/model/lte-enb-rrc.cc
index 2211f9ef6..a1037a2a2 100644
--- a/src/lte/model/lte-enb-rrc.cc
+++ b/src/lte/model/lte-enb-rrc.cc
@@ -1108,7 +1108,7 @@ UeManager::RecvMeasurementReport (LteRrcSap::MeasurementReport msg)
m_rrc->m_anrSapProvider->ReportUeMeas (msg.measResults);
}
- if ((m_rrc->m_ffrRrcSapProvider.at (0) != 0)
+ if ((m_rrc->m_ffrRrcSapProvider.size () > 0)
&& (m_rrc->m_ffrMeasIds.find (measId) != m_rrc->m_ffrMeasIds.end ()))
{
// this measurement was requested by the FFR function
@@ -1545,9 +1545,6 @@ LteEnbRrc::LteEnbRrc ()
m_s1SapUser = new MemberEpcEnbS1SapUser (this);
m_cphySapUser.push_back (new MemberLteEnbCphySapUser (this));
m_ccmRrcSapUser = new MemberLteCcmRrcSapUser (this);
- m_cphySapProvider.push_back (0);
- m_cmacSapProvider.push_back (0);
- m_ffrRrcSapProvider.push_back (0);
}
void
@@ -1563,9 +1560,6 @@ LteEnbRrc::ConfigureCarriers (std::map
m_cphySapUser.push_back (new MemberLteEnbCphySapUser (this));
m_cmacSapUser.push_back (new EnbRrcMemberLteEnbCmacSapUser (this, i));
m_ffrRrcSapUser.push_back (new MemberLteFfrRrcSapUser (this));
- m_cphySapProvider.push_back (0);
- m_cmacSapProvider.push_back (0);
- m_ffrRrcSapProvider.push_back (0);
}
m_carriersConfigured = true;
Object::DoInitialize ();
@@ -1790,7 +1784,15 @@ void
LteEnbRrc::SetLteEnbCmacSapProvider (LteEnbCmacSapProvider * s, uint8_t pos)
{
NS_LOG_FUNCTION (this << s);
- m_cmacSapProvider.at (pos) = s;
+ if (m_cmacSapProvider.size () > pos)
+ {
+ m_cmacSapProvider.at (pos) = s;
+ }
+ else
+ {
+ m_cmacSapProvider.push_back (s);
+ NS_ABORT_IF (m_cmacSapProvider.size () - 1 != pos);
+ }
}
LteEnbCmacSapUser*
@@ -1853,14 +1855,33 @@ void
LteEnbRrc::SetLteFfrRrcSapProvider (LteFfrRrcSapProvider * s)
{
NS_LOG_FUNCTION (this << s);
- m_ffrRrcSapProvider.at (0) = s;
+ if (m_ffrRrcSapProvider.size () > 0)
+ {
+ m_ffrRrcSapProvider.at (0) = s;
+ }
+ else
+ {
+ m_ffrRrcSapProvider.push_back (s);
+ }
+
}
void
LteEnbRrc::SetLteFfrRrcSapProvider (LteFfrRrcSapProvider * s, uint8_t index)
{
NS_LOG_FUNCTION (this << s);
- m_ffrRrcSapProvider.at (index) = s;
+ if (m_ffrRrcSapProvider.size () > index)
+ {
+ m_ffrRrcSapProvider.at (index) = s;
+ }
+ else
+ {
+ m_ffrRrcSapProvider.push_back (s);
+ NS_ABORT_MSG_IF (m_ffrRrcSapProvider.size () - 1 != index,
+ "You meant to store the pointer at position " <<
+ static_cast (index) <<
+ " but it went to " << m_ffrRrcSapProvider.size () - 1);
+ }
}
LteFfrRrcSapUser*
@@ -1916,7 +1937,14 @@ void
LteEnbRrc::SetLteEnbCphySapProvider (LteEnbCphySapProvider * s)
{
NS_LOG_FUNCTION (this << s);
- m_cphySapProvider.at(0) = s;
+ if (m_cphySapProvider.size () > 0)
+ {
+ m_cphySapProvider.at (0) = s;
+ }
+ else
+ {
+ m_cphySapProvider.push_back (s);
+ }
}
LteEnbCphySapUser*
@@ -1930,7 +1958,15 @@ void
LteEnbRrc::SetLteEnbCphySapProvider (LteEnbCphySapProvider * s, uint8_t pos)
{
NS_LOG_FUNCTION (this << s);
- m_cphySapProvider.at(pos) = s;
+ if (m_cphySapProvider.size () > pos)
+ {
+ m_cphySapProvider.at(pos) = s;
+ }
+ else
+ {
+ m_cphySapProvider.push_back (s);
+ NS_ABORT_IF (m_cphySapProvider.size () - 1 != pos);
+ }
}
LteEnbCphySapUser*
@@ -2065,8 +2101,11 @@ LteEnbRrc::ConfigureCell (std::map> cc
m_cphySapProvider.at (it.first)->SetEarfcn (it.second->GetUlEarfcn (), it.second->GetDlEarfcn ());
m_cphySapProvider.at (it.first)->SetCellId (it.second->GetCellId ());
m_cmacSapProvider.at (it.first)->ConfigureMac (it.second->GetUlBandwidth (), it.second->GetDlBandwidth ());
- m_ffrRrcSapProvider.at (it.first)->SetCellId (it.second->GetCellId ());
- m_ffrRrcSapProvider.at (it.first)->SetBandwidth (it.second->GetUlBandwidth (), it.second->GetDlBandwidth ());
+ if (m_ffrRrcSapProvider.size () > it.first)
+ {
+ m_ffrRrcSapProvider.at (it.first)->SetCellId (it.second->GetCellId ());
+ m_ffrRrcSapProvider.at (it.first)->SetBandwidth (it.second->GetUlBandwidth (), it.second->GetDlBandwidth ());
+ }
}
m_dlEarfcn = dlEarfcn;
@@ -2481,6 +2520,7 @@ LteEnbRrc::DoRecvLoadInformation (EpcX2SapUser::LoadInformationParams params)
NS_LOG_LOGIC ("Number of cellInformationItems = " << params.cellInformationList.size ());
+ NS_ABORT_IF (m_ffrRrcSapProvider.size () == 0);
m_ffrRrcSapProvider.at (0)->RecvLoadInformation (params);
}
From 4bcf5feb5049551fd1c6c8fbbf3f3ae53956a364 Mon Sep 17 00:00:00 2001
From: Natale Patriciello
Date: Wed, 7 Nov 2018 08:02:23 +0100
Subject: [PATCH 09/11] lte: Making SimpleUeComponentCarrierManager inheritable
In this way it is possible to write extensions at UE side for deciding what
carrier has to be used.
---
src/lte/model/simple-ue-component-carrier-manager.h | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/lte/model/simple-ue-component-carrier-manager.h b/src/lte/model/simple-ue-component-carrier-manager.h
index a9ce82988..621cbdb24 100644
--- a/src/lte/model/simple-ue-component-carrier-manager.h
+++ b/src/lte/model/simple-ue-component-carrier-manager.h
@@ -87,7 +87,7 @@ protected:
* \brief Report buffer status function
* \param params LteMacSapProvider::ReportBufferStatusParameters
*/
- void DoReportBufferStatus (LteMacSapProvider::ReportBufferStatusParameters params);
+ virtual void DoReportBufferStatus (LteMacSapProvider::ReportBufferStatusParameters params);
/// Notify HARQ deliver failure
void DoNotifyHarqDeliveryFailure ();
// forwarded from LteMacSapUser
@@ -111,7 +111,7 @@ protected:
* \param msu the MSU
* \returns updated LC config list
*/
- std::vector DoAddLc (uint8_t lcId, LteUeCmacSapProvider::LogicalChannelConfig lcConfig, LteMacSapUser* msu);
+ virtual std::vector DoAddLc (uint8_t lcId, LteUeCmacSapProvider::LogicalChannelConfig lcConfig, LteMacSapUser* msu);
/**
* \brief Remove LC function
* \param lcid the LCID
@@ -125,14 +125,14 @@ protected:
* \param msu the MSU
* \returns LteMacSapUser *
*/
- LteMacSapUser* DoConfigureSignalBearer (uint8_t lcId, LteUeCmacSapProvider::LogicalChannelConfig lcConfig, LteMacSapUser* msu);
+ virtual LteMacSapUser* DoConfigureSignalBearer (uint8_t lcId, LteUeCmacSapProvider::LogicalChannelConfig lcConfig, LteMacSapUser* msu);
/**
* \brief Reset LC map
*
*/
void DoReset ();
-private:
+protected:
LteMacSapUser* m_ccmMacSapUser;//!< Interface to the UE RLC instance.
LteMacSapProvider* m_ccmMacSapProvider; //!< Receive API calls from the UE RLC instance
From 05dd0e53d302842c66f8b1a9c0dcf15d3e8c93d7 Mon Sep 17 00:00:00 2001
From: Natale Patriciello
Date: Fri, 9 Nov 2018 12:15:24 +0100
Subject: [PATCH 10/11] lte: Managing SR at SAP interface level.
SR is implemented in the NR module; for the moment, just add the possibility at
the interface level. LTE module will not do anything for the moment, waiting for
a feature addition at a later stage.
---
src/lte/model/lte-ccm-mac-sap.h | 37 ++++++++++++++++++-
src/lte/model/lte-enb-mac.h | 11 ++++++
.../model/no-op-component-carrier-manager.cc | 29 +++++++++++++++
.../model/no-op-component-carrier-manager.h | 17 +++++++--
4 files changed, 89 insertions(+), 5 deletions(-)
diff --git a/src/lte/model/lte-ccm-mac-sap.h b/src/lte/model/lte-ccm-mac-sap.h
index 6bb3cc3f6..ba7bc9646 100644
--- a/src/lte/model/lte-ccm-mac-sap.h
+++ b/src/lte/model/lte-ccm-mac-sap.h
@@ -53,6 +53,14 @@ public:
*/
virtual void ReportMacCeToScheduler (MacCeListElement_s bsr) = 0;
+ /**
+ * \brief Report SR to the right scheduler
+ * \param rnti RNTI of the user that requested the SR
+ *
+ * \see LteCcmMacSapUser::UlReceiveSr
+ */
+ virtual void ReportSrToScheduler (uint16_t rnti) = 0;
+
}; // end of class LteCcmMacSapProvider
@@ -79,6 +87,20 @@ public:
*/
virtual void UlReceiveMacCe (MacCeListElement_s bsr, uint8_t componentCarrierId) = 0;
+ /**
+ * \brief The MAC received a SR
+ * \param rnti RNTI of the UE that requested a SR
+ * \param componentCarrierId CC that received the SR
+ *
+ * NOTE: Not implemented in the LTE module. The FemtoForum API requires
+ * that this function gets as parameter a struct SchedUlSrInfoReqParameters.
+ * However, that struct has the SfnSf as a member: since it differs from
+ * LTE to mmwave/NR, and we don't have an effective strategy to deal with
+ * that, we limit the function to the only thing that the module have in
+ * common: the RNTI.
+ */
+ virtual void UlReceiveSr (uint16_t rnti, uint8_t componentCarrierId) = 0;
+
/**
* \brief Notifies component carrier manager about physical resource block occupancy
* \param prbOccupancy The physical resource block occupancy
@@ -100,7 +122,8 @@ public:
*/
MemberLteCcmMacSapProvider (C* owner);
// inherited from LteCcmRrcSapProvider
- virtual void ReportMacCeToScheduler (MacCeListElement_s bsr);
+ virtual void ReportMacCeToScheduler (MacCeListElement_s bsr) override;
+ virtual void ReportSrToScheduler (uint16_t rnti) override;
private:
C* m_owner; ///< the owner class
@@ -118,6 +141,11 @@ void MemberLteCcmMacSapProvider::ReportMacCeToScheduler (MacCeListElement_s b
m_owner->DoReportMacCeToScheduler (bsr);
}
+template
+void MemberLteCcmMacSapProvider::ReportSrToScheduler (uint16_t rnti)
+{
+ m_owner->DoReportSrToScheduler (rnti);
+}
/// MemberLteCcmMacSapUser class
template
@@ -132,6 +160,7 @@ public:
MemberLteCcmMacSapUser (C* owner);
// inherited from LteCcmRrcSapUser
virtual void UlReceiveMacCe (MacCeListElement_s bsr, uint8_t componentCarrierId);
+ virtual void UlReceiveSr (uint16_t rnti, uint8_t componentCarrierId);
virtual void NotifyPrbOccupancy (double prbOccupancy, uint8_t componentCarrierId);
// inherited from LteMacSapUser
virtual void NotifyTxOpportunity (LteMacSapUser::TxOpportunityParameters txOpParams);
@@ -155,6 +184,12 @@ void MemberLteCcmMacSapUser::UlReceiveMacCe (MacCeListElement_s bsr, uint8_t
m_owner->DoUlReceiveMacCe (bsr, componentCarrierId);
}
+template
+void MemberLteCcmMacSapUser::UlReceiveSr (uint16_t rnti, uint8_t componentCarrierId)
+{
+ m_owner->DoUlReceiveSr (rnti, componentCarrierId);
+}
+
template
void MemberLteCcmMacSapUser::NotifyPrbOccupancy (double prbOccupancy, uint8_t componentCarrierId)
{
diff --git a/src/lte/model/lte-enb-mac.h b/src/lte/model/lte-enb-mac.h
index d15ee6094..f25a65933 100644
--- a/src/lte/model/lte-enb-mac.h
+++ b/src/lte/model/lte-enb-mac.h
@@ -343,6 +343,17 @@ private:
* \param bsr the BSR
*/
void DoReportMacCeToScheduler (MacCeListElement_s bsr);
+
+ /**
+ * \brief Report SR to scheduler
+ * \param rnti RNTI of the UE that requested the SR
+ *
+ * Since SR is not implemented in LTE, this method does nothing.
+ */
+ void DoReportSrToScheduler (uint16_t rnti)
+ {
+ NS_UNUSED (rnti);
+ }
public:
/**
diff --git a/src/lte/model/no-op-component-carrier-manager.cc b/src/lte/model/no-op-component-carrier-manager.cc
index a58fae4f6..59e08989c 100644
--- a/src/lte/model/no-op-component-carrier-manager.cc
+++ b/src/lte/model/no-op-component-carrier-manager.cc
@@ -411,6 +411,18 @@ NoOpComponentCarrierManager::DoUlReceiveMacCe (MacCeListElement_s bsr, uint8_t c
}
}
+void
+NoOpComponentCarrierManager::DoUlReceiveSr (uint16_t rnti, uint8_t componentCarrierId)
+{
+ NS_LOG_FUNCTION (this);
+
+ auto sapIt = m_ccmMacSapProviderMap.find (componentCarrierId);
+ NS_ABORT_MSG_IF (sapIt == m_ccmMacSapProviderMap.end (),
+ "Sap not found in the CcmMacSapProviderMap");
+
+ sapIt->second->ReportSrToScheduler (rnti);
+}
+
//////////////////////////////////////////
@@ -515,4 +527,21 @@ RrComponentCarrierManager::DoUlReceiveMacCe (MacCeListElement_s bsr, uint8_t com
}
}
+void
+RrComponentCarrierManager::DoUlReceiveSr(uint16_t rnti, uint8_t componentCarrierId)
+{
+ NS_LOG_FUNCTION (this);
+ NS_UNUSED (componentCarrierId);
+ // split traffic in uplink equally among carriers
+ uint32_t numberOfCarriersForUe = m_enabledComponentCarrier.find (rnti)->second;
+
+ m_ccmMacSapProviderMap.find (m_lastCcIdForSr)->second->ReportSrToScheduler (rnti);
+
+ m_lastCcIdForSr++;
+ if (m_lastCcIdForSr > numberOfCarriersForUe - 1)
+ {
+ m_lastCcIdForSr = 0;
+ }
+}
+
} // end of namespace ns3
diff --git a/src/lte/model/no-op-component-carrier-manager.h b/src/lte/model/no-op-component-carrier-manager.h
index 9b524c118..6d2fca189 100644
--- a/src/lte/model/no-op-component-carrier-manager.h
+++ b/src/lte/model/no-op-component-carrier-manager.h
@@ -138,6 +138,12 @@ protected:
* \param componentCarrierId the component carrier ID
*/
virtual void DoUlReceiveMacCe (MacCeListElement_s bsr, uint8_t componentCarrierId);
+ /**
+ * \brief Forward uplink SR to CCM, called by MAC through CCM SAP interface.
+ * \param rnti RNTI of the UE that requested SR
+ * \param componentCarrierId the component carrier ID that forwarded the SR
+ */
+ virtual void DoUlReceiveSr (uint16_t rnti, uint8_t componentCarrierId);
/**
* \brief Function implements the function of the SAP interface of CCM instance which is used by MAC
* to notify the PRB occupancy reported by scheduler.
@@ -153,7 +159,7 @@ protected:
}; // end of class NoOpComponentCarrierManager
-/*
+/**
* \brief Component carrier manager implementation that splits traffic equally among carriers.
*/
class RrComponentCarrierManager : public NoOpComponentCarrierManager
@@ -161,7 +167,7 @@ class RrComponentCarrierManager : public NoOpComponentCarrierManager
public:
RrComponentCarrierManager ();
- virtual ~RrComponentCarrierManager ();
+ virtual ~RrComponentCarrierManager () override;
/**
* \brief Get the type ID.
* \return the object TypeId
@@ -171,9 +177,12 @@ public:
protected:
// Inherited methods
- virtual void DoReportBufferStatus (LteMacSapProvider::ReportBufferStatusParameters params);
- virtual void DoUlReceiveMacCe (MacCeListElement_s bsr, uint8_t componentCarrierId);
+ virtual void DoReportBufferStatus (LteMacSapProvider::ReportBufferStatusParameters params) override;
+ virtual void DoUlReceiveMacCe (MacCeListElement_s bsr, uint8_t componentCarrierId) override;
+ virtual void DoUlReceiveSr (uint16_t rnti, uint8_t componentCarrierId) override;
+private:
+ uint8_t m_lastCcIdForSr {0}; //!< Last CCID to which a SR was routed
}; // end of class RrComponentCarrierManager
} // end of namespace ns3
From da994d51c1f2b5846e17581f96c4389b8a8a3c68 Mon Sep 17 00:00:00 2001
From: Natale Patriciello
Date: Thu, 15 Nov 2018 18:12:12 +0100
Subject: [PATCH 11/11] spectrum: Add API to retrieve Values size and a single
value at any position
Values are stored as std::vector of double, but this vector can't be accessed,
even read-only. With this addition, it is possible to know how many elements
are inside the vector, and also to get a const reference to any element.
---
CHANGES.html | 4 ++++
src/spectrum/model/spectrum-value.cc | 11 ++++++++++-
src/spectrum/model/spectrum-value.h | 11 +++++++++++
3 files changed, 25 insertions(+), 1 deletion(-)
diff --git a/CHANGES.html b/CHANGES.html
index 93bf948c8..5ed2eec3f 100644
--- a/CHANGES.html
+++ b/CHANGES.html
@@ -76,6 +76,10 @@ us a note on ns-developers mailing list.
The WifiPhy attribute "CcaMode1Threshold" has been renamed to "CcaEdThreshold",
and the WifiPhy attribute "EnergyDetectionThreshold" has been replaced by a new attribute called "RxSensitivity"
+ -
+ It is now possible to know the size of the SpectrumValue underlying std::vector, as well as
+ accessing read-only every element of it.
+
Changes to build system:
diff --git a/src/spectrum/model/spectrum-value.cc b/src/spectrum/model/spectrum-value.cc
index b3bcadfd9..525b58d6e 100644
--- a/src/spectrum/model/spectrum-value.cc
+++ b/src/spectrum/model/spectrum-value.cc
@@ -692,8 +692,17 @@ SpectrumValue::operator>> (int n) const
return res;
}
+uint32_t
+SpectrumValue::GetValuesN () const
+{
+ return m_values.size ();
+}
-
+const double &
+SpectrumValue::ValuesAt (uint32_t pos) const
+{
+ return m_values.at (pos);
+}
} // namespace ns3
diff --git a/src/spectrum/model/spectrum-value.h b/src/spectrum/model/spectrum-value.h
index dd6c7ac55..73bde05e3 100644
--- a/src/spectrum/model/spectrum-value.h
+++ b/src/spectrum/model/spectrum-value.h
@@ -157,7 +157,18 @@ public:
*/
Values::iterator ValuesEnd ();
+ /**
+ * \brief Get the number of values stored in the array
+ * \return the values array size
+ */
+ uint32_t GetValuesN () const;
+ /**
+ * \brief Get the value element at the position
+ * \param pos position
+ * \return the value element in that position (with bounds checking)
+ */
+ const double & ValuesAt (uint32_t pos) const;
/**
* addition operator