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.
This commit is contained in:
Natale Patriciello
2018-10-24 10:38:03 +02:00
parent 4d0b5369c2
commit 0273d706b0
2 changed files with 137 additions and 103 deletions

View File

@@ -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

View File

@@ -23,6 +23,7 @@
#define EPS_BEARER
#include <ns3/uinteger.h>
#include <unordered_map>
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<uint8_t> {} (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<Qci, std::tuple<bool, uint8_t, uint16_t, double, uint32_t, uint32_t>, 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