1 /* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2011 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17  *
18  * Author: Nicola Baldo <nbaldo@cttc.es>
19  */
20 
21 
22 #ifndef EPS_BEARER
23 #define EPS_BEARER
24 
25 #include <ns3/uinteger.h>
26 #include <ns3/object-base.h>
27 #include <unordered_map>
28 
29 namespace ns3 {
30 
31 /**
32  * 3GPP TS 36.413 9.2.1.18 GBR QoS Information
33  *
34  */
35 struct GbrQosInformation
36 {
37   /**
38    * Default constructor, initializes member variables to zero or equivalent
39    */
40   GbrQosInformation ();
41 
42   uint64_t gbrDl;  /**< Guaranteed Bit Rate (bit/s) in downlink */
43   uint64_t gbrUl;  /**< Guaranteed Bit Rate (bit/s) in uplink */
44   uint64_t mbrDl;  /**< Maximum Bit Rate (bit/s) in downlink */
45   uint64_t mbrUl;  /**< Maximum Bit Rate (bit/s) in uplink */
46 };
47 
48 
49 /**
50  * 3GPP 23.203 Section 6.1.7.3 Allocation and Retention Priority characteristics
51  *
52  */
53 struct AllocationRetentionPriority
54 {
55   /**
56    * Default constructor, initializes member variables to zero or equivalent
57    */
58   AllocationRetentionPriority ();
59   uint8_t priorityLevel;     ///< 1-15; 1 = highest
60   bool preemptionCapability; ///< true if bearer can preempt others
61   bool preemptionVulnerability; ///< true if bearer can be preempted by others
62 };
63 
64 /**
65  * \brief This class contains the specification of EPS Bearers.
66  *
67  * See the following references:
68  * 3GPP TS 23.203, Section 4.7.2 The EPS bearer
69  * 3GPP TS 23.203, Section 4.7.3 Bearer level QoS parameters
70  * 3GPP TS 36.413 Section 9.2.1.15 E-RAB Level QoS Parameters
71  *
72  * It supports the selection of different specifications depending on the
73  * release. To change the release, change the attribute "Release". Please remember
74  * that we must expose to all releases the most recent Qci. Asking for Qci parameters
75  * for a release in which it has not been created will result in a crash.
76  *
77  * For example, if you select Release 11 (or if you don't select anything, as
78  * it is the default selection) and then ask for the packet error rate of
79  * the NGBR_MC_DELAY_SIGNAL Qci, the program will crash.
80  *
81  * Please note that from Release 8 (the latest when the LENA project finished)
82  * to Release 11, the bearers ID and requirements are the same. From Release 12,
83  * they started to change, and the latest version is now Release 15. However,
84  * we do not support intermediate types: in other words, you can select from
85  * Release 8 to Release 11, or Release 15. Any other value will result in a
86  * program crash.
87  *
88  * The release version only affect Bearer definitions. Other part of the LTE
89  * module are not affected when changing the Release attribute.
90  */
91 class EpsBearer : public ObjectBase
92 {
93 public:
94   /**
95    * \brief Get the type ID.
96    * \return the object TypeId
97    */
98   static TypeId GetTypeId (void);
99 
100   virtual TypeId GetInstanceTypeId (void) const override;
101 
102   /**
103    * QoS Class Indicator. See 3GPP 23.203 Section 6.1.7.2 for standard values.
104    * Updated to Release 15.
105    */
106   enum Qci : uint8_t
107   {
108     GBR_CONV_VOICE          = 1,    ///< GBR Conversational Voice
109     GBR_CONV_VIDEO          = 2,    ///< GBR Conversational Video (Live streaming)
110     GBR_GAMING              = 3,    ///< GBR Real Time Gaming
111     GBR_NON_CONV_VIDEO      = 4,    ///< GBR Non-Conversational Video (Buffered Streaming)
112     GBR_MC_PUSH_TO_TALK     = 65,   ///< GBR Mission Critical User Plane Push To Talk voice
113     GBR_NMC_PUSH_TO_TALK    = 66,   ///< GBR Non-Mission-Critical User Plane Push To Talk voice
114     GBR_MC_VIDEO            = 67,   ///< GBR Mission Critical Video User Plane
115     GBR_V2X                 = 75,   ///< GBR V2X Messages
116     NGBR_IMS                = 5,    ///< Non-GBR IMS Signalling
117     NGBR_VIDEO_TCP_OPERATOR = 6,    ///< Non-GBR TCP-based Video (Buffered Streaming, e.g., www, e-mail...)
118     NGBR_VOICE_VIDEO_GAMING = 7,    ///< Non-GBR Voice, Video, Interactive Streaming
119     NGBR_VIDEO_TCP_PREMIUM  = 8,    ///< Non-GBR TCP-based Video (Buffered Streaming, e.g., www, e-mail...)
120     NGBR_VIDEO_TCP_DEFAULT  = 9,    ///< Non-GBR TCP-based Video (Buffered Streaming, e.g., www, e-mail...)
121     NGBR_MC_DELAY_SIGNAL    = 69,   ///< Non-GBR Mission Critical Delay Sensitive Signalling (e.g., MC-PTT)
122     NGBR_MC_DATA            = 70,   ///< Non-GBR Mission Critical Data
123     NGBR_V2X                = 79,   ///< Non-GBR V2X Messages
124     NGBR_LOW_LAT_EMBB       = 80,   ///< Non-GBR Low Latency eMBB applications
125     DGBR_DISCRETE_AUT_SMALL = 82,   ///< Delay-Critical GBR Discrete Automation Small Packets (TS 22.261)
126     DGBR_DISCRETE_AUT_LARGE = 83,   ///< Delay-Critical GBR Discrete Automation Large Packets (TS 22.261)
127     DGBR_ITS                = 84,   ///< Delay-Critical GBR Intelligent Transport Systems (TS 22.261)
128     DGBR_ELECTRICITY        = 85,   ///< Delay-Critical GBR Electricity Distribution High Voltage (TS 22.261)
129   } qci; ///< Qos class indicator
130 
131   GbrQosInformation gbrQosInfo; ///< GBR QOS information
132   AllocationRetentionPriority arp; ///< allocation retention priority
133 
134   /**
135    * Default constructor. QCI will be initialized to NGBR_VIDEO_TCP_DEFAULT
136    *
137    */
138   EpsBearer ();
139 
140   /**
141    *
142    * @param x the QoS Class Indicator
143    *
144    */
145   EpsBearer (Qci x);
146 
147   /**
148    *
149    * @param x the QoS Class Indicator
150    * @param y the GbrQosInformation
151    *
152    */
153   EpsBearer (Qci x, GbrQosInformation y);
154 
155   /**
156    * \brief EpsBearer copy constructor
157    * \param o other instance
158    */
159   EpsBearer (const EpsBearer &o);
160 
161   /**
162     * \brief Deconstructor
163     */
~EpsBearer()164   virtual ~EpsBearer () { }
165 
166   /**
167    * \brief SetRelease
168    * \param release The release the user want for this bearer
169    *
170    * Releases introduces new types, and change values for existing ones.
171    * While we can't do much for the added type (we must expose them even
172    * if the user want to work with older releases) by calling this method
173    * we can, at least, select the specific parameters value the bearer returns.
174    *
175    * For instance, if the user select release 10 (the default) the priority
176    * of CONV_VIDEO will be 2. With release 15, such priority will be 20.
177    */
178   void SetRelease (uint8_t release);
179 
180   /**
181    * \brief GetRelease
182    * \return The release currently set for this bearer type
183    */
GetRelease()184   uint8_t GetRelease () const { return m_release; }
185 
186   /**
187    *
188    * @return true if the EPS Bearer is a Guaranteed Bit Rate bearer, false otherwise
189    */
190   bool IsGbr () const;
191 
192   /**
193    *
194    * @return the priority associated with the QCI of this bearer as per 3GPP 23.203 Section 6.1.7.2
195    */
196   uint8_t GetPriority () const;
197 
198   /**
199    *
200    *
201    *
202    * @return the packet delay budget associated with the QCI of this bearer as per 3GPP 23.203 Section 6.1.7.2
203    */
204   uint16_t GetPacketDelayBudgetMs () const;
205 
206   /**
207    *
208    *
209    *
210    * @return the packet error loss rate associated with the QCI of this bearer as per 3GPP 23.203 Section 6.1.7.2
211    */
212   double  GetPacketErrorLossRate () const;
213 
214 private:
215   /**
216    * \brief Hashing QCI
217    *
218    * Qci are just uint8_t, so that's how we calculate the hash. Unfortunately,
219    * we have to provide this struct because gcc 4.9 would not compile otherwise.
220    */
221   struct QciHash
222   {
223     /**
224      * \brief Hash the QCI like a normal uint8_t
225      * \param s Qci to hash
226      * \return Hash of Qci
227      */
228     std::size_t
operatorQciHash229     operator () (Qci const& s) const noexcept
230       {
231         return std::hash<uint8_t> {} (s);
232       }
233   };
234 
235   /**
236     * \brief Map between QCI and requirements
237     *
238     * The tuple is formed by: isGbr, priority, packet delay budget, packet error rate,
239     *  default maximum data burst, default averaging window (0 when does not apply)
240     */
241   typedef std::unordered_map<Qci, std::tuple<bool, uint8_t, uint16_t, double, uint32_t, uint32_t>, QciHash > BearerRequirementsMap;
242 
243   /**
244    * \brief Is the selected QCI GBR?
245    * \param map Map between QCI and requirements
246    * \param qci QCI to look for
247    * \return GBR flag for the selected CQI
248    */
249   static uint32_t
IsGbr(const BearerRequirementsMap & map,Qci qci)250   IsGbr (const BearerRequirementsMap &map, Qci qci) {return std::get<0> (map.at (qci));}
251 
252   /**
253    * \brief Get priority for the selected QCI
254    * \param map Map between QCI and requirements
255    * \param qci QCI to look for
256    * \return priority for the selected QCI
257    */
258   static uint8_t
GetPriority(const BearerRequirementsMap & map,Qci qci)259   GetPriority (const BearerRequirementsMap &map, Qci qci) {return std::get<1> (map.at (qci));}
260   /**
261    * \brief Get packet delay in ms for the selected QCI
262    * \param map Map between QCI and requirements
263    * \param qci QCI to look for
264    * \return packet delay in ms for the selected QCI
265    */
266   static uint16_t
GetPacketDelayBudgetMs(const BearerRequirementsMap & map,Qci qci)267   GetPacketDelayBudgetMs (const BearerRequirementsMap &map, Qci qci) {return std::get<2> (map.at (qci));}
268   /**
269    * \brief Get packet error rate for the selected QCI
270    * \param map Map between QCI and requirements
271    * \param qci QCI to look for
272    * \return packet error rate for the selected QCI
273    */
274   static double
GetPacketErrorLossRate(const BearerRequirementsMap & map,Qci qci)275   GetPacketErrorLossRate (const BearerRequirementsMap &map, Qci qci) {return std::get<3> (map.at (qci));}
276   /**
277    * \brief Get maximum data burst for the selected QCI
278    * \param map Map between QCI and requirements
279    * \param qci QCI to look for
280    * \return maximum data burst for the selected QCI
281    */
282   static uint32_t
GetMaxDataBurst(const BearerRequirementsMap & map,Qci qci)283   GetMaxDataBurst (const BearerRequirementsMap &map, Qci qci) {return std::get<4> (map.at (qci));}
284   /**
285    * \brief Get default averaging window for the selected QCI
286    * \param map Map between QCI and requirements
287    * \param qci QCI to look for
288    * \return default averaging window for the selected QCI
289    */
290   static uint32_t
GetAvgWindow(const BearerRequirementsMap & map,Qci qci)291   GetAvgWindow (const BearerRequirementsMap &map, Qci qci) {return std::get<5> (map.at (qci));}
292 
293   /**
294    * \brief Retrieve requirements for Rel. 11
295    * \return the BearerRequirementsMap for Release 11
296    *
297    * It returns a pointer to a non-const static data. That is not thread-safe,
298    * nor safe to do in general. However, a const-correct version would have
299    * to initialize two static maps, and then returning either one or the other.
300    * But that's a huge memory increase, and EpsBearer is used everywhere.
301    *
302    * To be revisited when GCC 4.9 will not be supported anymore.
303    */
304   static BearerRequirementsMap * GetRequirementsRel11 ();
305 
306   /**
307    * \brief Retrieve requirements for Rel. 15
308    * \return the BearerRequirementsMap for Release 15
309    *
310    * It returns a pointer to a non-const static data. That is not thread-safe,
311    * nor safe to do in general. However, a const-correct version would have
312    * to initialize two static maps, and then returning either one or the other.
313    * But that's a huge memory increase, and EpsBearer is used everywhere.
314    *
315    * To be revisited when GCC 4.9 will not be supported anymore.
316    */
317   static BearerRequirementsMap * GetRequirementsRel15 ();
318 
319   /**
320     * \brief Requirements pointer per bearer
321     *
322     * It will point to a static map.
323     */
324   BearerRequirementsMap *m_requirements;
325 
326   uint8_t m_release {30}; //!< Release (10 or 15)
327 };
328 
329 } // namespace ns3
330 
331 
332 #endif // EPS_BEARER
333