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