1 /* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
2 /*
3 * Copyright (c) 2014 Piotr Gawlowicz
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: Piotr Gawlowicz <gawlowicz.p@gmail.com>
19 *
20 */
21
22 #include "lte-fr-hard-algorithm.h"
23 #include <ns3/log.h>
24
25 namespace ns3 {
26
27 NS_LOG_COMPONENT_DEFINE ("LteFrHardAlgorithm");
28
29 NS_OBJECT_ENSURE_REGISTERED (LteFrHardAlgorithm);
30
31 /// FrHardDownlinkDefaultConfiguration structure
32 static const struct FrHardDownlinkDefaultConfiguration
33 {
34 uint8_t m_cellId; ///< cell ID
35 uint8_t m_dlBandwidth; ///< DL bandwidth
36 uint8_t m_dlOffset; ///< DL offset
37 uint8_t m_dlSubBand; ///< DL subband
38 } g_frHardDownlinkDefaultConfiguration[] = {
39 { 1, 15, 0, 4},
40 { 2, 15, 4, 4},
41 { 3, 15, 8, 6},
42 { 1, 25, 0, 8},
43 { 2, 25, 8, 8},
44 { 3, 25, 16, 9},
45 { 1, 50, 0, 16},
46 { 2, 50, 16, 16},
47 { 3, 50, 32, 18},
48 { 1, 75, 0, 24},
49 { 2, 75, 24, 24},
50 { 3, 75, 48, 27},
51 { 1, 100, 0, 32},
52 { 2, 100, 32, 32},
53 { 3, 100, 64, 36}
54 }; ///< the hard downlink default configuration
55
56 /// FrHardUplinkDefaultConfiguration structure
57 static const struct FrHardUplinkDefaultConfiguration
58 {
59 uint8_t m_cellId; ///< cell ID
60 uint8_t m_ulBandwidth; ///< UL bandwidth
61 uint8_t m_ulOffset; ///< Ul offset
62 uint8_t m_ulSubBand; ///< UL subband
63 } g_frHardUplinkDefaultConfiguration[] = {
64 { 1, 15, 0, 5},
65 { 2, 15, 5, 5},
66 { 3, 15, 10, 5},
67 { 1, 25, 0, 8},
68 { 2, 25, 8, 8},
69 { 3, 25, 16, 9},
70 { 1, 50, 0, 16},
71 { 2, 50, 16, 16},
72 { 3, 50, 32, 18},
73 { 1, 75, 0, 24},
74 { 2, 75, 24, 24},
75 { 3, 75, 48, 27},
76 { 1, 100, 0, 32},
77 { 2, 100, 32, 32},
78 { 3, 100, 64, 36}
79 }; ///< the hard uplink default configuration
80
81 /** \returns number of downlink configurations */
82 const uint16_t NUM_DOWNLINK_CONFS (sizeof (g_frHardDownlinkDefaultConfiguration) / sizeof (FrHardDownlinkDefaultConfiguration));
83 /** \returns number of uplink configurations */
84 const uint16_t NUM_UPLINK_CONFS (sizeof (g_frHardUplinkDefaultConfiguration) / sizeof (FrHardUplinkDefaultConfiguration));
85
LteFrHardAlgorithm()86 LteFrHardAlgorithm::LteFrHardAlgorithm ()
87 : m_ffrSapUser (0),
88 m_ffrRrcSapUser (0),
89 m_dlOffset (0),
90 m_dlSubBand (0),
91 m_ulOffset (0),
92 m_ulSubBand (0)
93 {
94 NS_LOG_FUNCTION (this);
95 m_ffrSapProvider = new MemberLteFfrSapProvider<LteFrHardAlgorithm> (this);
96 m_ffrRrcSapProvider = new MemberLteFfrRrcSapProvider<LteFrHardAlgorithm> (this);
97 }
98
99
~LteFrHardAlgorithm()100 LteFrHardAlgorithm::~LteFrHardAlgorithm ()
101 {
102 NS_LOG_FUNCTION (this);
103 }
104
105
106 void
DoDispose()107 LteFrHardAlgorithm::DoDispose ()
108 {
109 NS_LOG_FUNCTION (this);
110 delete m_ffrSapProvider;
111 delete m_ffrRrcSapProvider;
112 }
113
114
115 TypeId
GetTypeId()116 LteFrHardAlgorithm::GetTypeId ()
117 {
118 static TypeId tid = TypeId ("ns3::LteFrHardAlgorithm")
119 .SetParent<LteFfrAlgorithm> ()
120 .SetGroupName("Lte")
121 .AddConstructor<LteFrHardAlgorithm> ()
122 .AddAttribute ("UlSubBandOffset",
123 "Uplink Offset in number of Resource Block Groups",
124 UintegerValue (0),
125 MakeUintegerAccessor (&LteFrHardAlgorithm::m_ulOffset),
126 MakeUintegerChecker<uint8_t> ())
127 .AddAttribute ("UlSubBandwidth",
128 "Uplink Transmission SubBandwidth Configuration in number of Resource Block Groups",
129 UintegerValue (25),
130 MakeUintegerAccessor (&LteFrHardAlgorithm::m_ulSubBand),
131 MakeUintegerChecker<uint8_t> ())
132 .AddAttribute ("DlSubBandOffset",
133 "Downlink Offset in number of Resource Block Groups",
134 UintegerValue (0),
135 MakeUintegerAccessor (&LteFrHardAlgorithm::m_dlOffset),
136 MakeUintegerChecker<uint8_t> ())
137 .AddAttribute ("DlSubBandwidth",
138 "Downlink Transmission SubBandwidth Configuration in number of Resource Block Groups",
139 UintegerValue (25),
140 MakeUintegerAccessor (&LteFrHardAlgorithm::m_dlSubBand),
141 MakeUintegerChecker<uint8_t> ())
142 ;
143 return tid;
144 }
145
146
147 void
SetLteFfrSapUser(LteFfrSapUser * s)148 LteFrHardAlgorithm::SetLteFfrSapUser (LteFfrSapUser* s)
149 {
150 NS_LOG_FUNCTION (this << s);
151 m_ffrSapUser = s;
152 }
153
154
155 LteFfrSapProvider*
GetLteFfrSapProvider()156 LteFrHardAlgorithm::GetLteFfrSapProvider ()
157 {
158 NS_LOG_FUNCTION (this);
159 return m_ffrSapProvider;
160 }
161
162 void
SetLteFfrRrcSapUser(LteFfrRrcSapUser * s)163 LteFrHardAlgorithm::SetLteFfrRrcSapUser (LteFfrRrcSapUser* s)
164 {
165 NS_LOG_FUNCTION (this << s);
166 m_ffrRrcSapUser = s;
167 }
168
169
170 LteFfrRrcSapProvider*
GetLteFfrRrcSapProvider()171 LteFrHardAlgorithm::GetLteFfrRrcSapProvider ()
172 {
173 NS_LOG_FUNCTION (this);
174 return m_ffrRrcSapProvider;
175 }
176
177
178 void
DoInitialize()179 LteFrHardAlgorithm::DoInitialize ()
180 {
181 NS_LOG_FUNCTION (this);
182 LteFfrAlgorithm::DoInitialize ();
183
184 NS_ASSERT_MSG (m_dlBandwidth > 14,"DlBandwidth must be at least 15 to use FFR algorithms");
185 NS_ASSERT_MSG (m_ulBandwidth > 14,"UlBandwidth must be at least 15 to use FFR algorithms");
186
187 if (m_frCellTypeId != 0)
188 {
189 SetDownlinkConfiguration (m_frCellTypeId, m_dlBandwidth);
190 SetUplinkConfiguration (m_frCellTypeId, m_ulBandwidth);
191 }
192
193 }
194
195 void
Reconfigure()196 LteFrHardAlgorithm::Reconfigure ()
197 {
198 NS_LOG_FUNCTION (this);
199 if (m_frCellTypeId != 0)
200 {
201 SetDownlinkConfiguration (m_frCellTypeId, m_dlBandwidth);
202 SetUplinkConfiguration (m_frCellTypeId, m_ulBandwidth);
203 }
204 InitializeDownlinkRbgMaps ();
205 InitializeUplinkRbgMaps ();
206 m_needReconfiguration = false;
207 }
208
209 void
SetDownlinkConfiguration(uint16_t cellId,uint8_t bandwidth)210 LteFrHardAlgorithm::SetDownlinkConfiguration (uint16_t cellId, uint8_t bandwidth)
211 {
212 NS_LOG_FUNCTION (this);
213 for (uint16_t i = 0; i < NUM_DOWNLINK_CONFS; ++i)
214 {
215 if ((g_frHardDownlinkDefaultConfiguration[i].m_cellId == cellId)
216 && g_frHardDownlinkDefaultConfiguration[i].m_dlBandwidth == m_dlBandwidth)
217 {
218 m_dlOffset = g_frHardDownlinkDefaultConfiguration[i].m_dlOffset;
219 m_dlSubBand = g_frHardDownlinkDefaultConfiguration[i].m_dlSubBand;
220 }
221 }
222 }
223
224 void
SetUplinkConfiguration(uint16_t cellId,uint8_t bandwidth)225 LteFrHardAlgorithm::SetUplinkConfiguration (uint16_t cellId, uint8_t bandwidth)
226 {
227 NS_LOG_FUNCTION (this);
228 for (uint16_t i = 0; i < NUM_UPLINK_CONFS; ++i)
229 {
230 if ((g_frHardUplinkDefaultConfiguration[i].m_cellId == cellId)
231 && g_frHardUplinkDefaultConfiguration[i].m_ulBandwidth == m_ulBandwidth)
232 {
233 m_ulOffset = g_frHardUplinkDefaultConfiguration[i].m_ulOffset;
234 m_ulSubBand = g_frHardUplinkDefaultConfiguration[i].m_ulSubBand;
235 }
236 }
237 }
238
239 void
InitializeDownlinkRbgMaps()240 LteFrHardAlgorithm::InitializeDownlinkRbgMaps ()
241 {
242 m_dlRbgMap.clear ();
243
244 int rbgSize = GetRbgSize (m_dlBandwidth);
245 m_dlRbgMap.resize (m_dlBandwidth / rbgSize, true);
246
247 NS_ASSERT_MSG (m_dlOffset <= m_dlBandwidth,"DlOffset higher than DlBandwidth");
248 NS_ASSERT_MSG (m_dlSubBand <= m_dlBandwidth,"DlBandwidth higher than DlBandwidth");
249 NS_ASSERT_MSG ((m_dlOffset + m_dlSubBand) <= m_dlBandwidth,
250 "(DlOffset+DlSubBand) higher than DlBandwidth");
251
252 for (uint8_t i = m_dlOffset / rbgSize; i < (m_dlOffset / rbgSize + m_dlSubBand / rbgSize); i++)
253 {
254 m_dlRbgMap[i] = false;
255
256 }
257 }
258
259 void
InitializeUplinkRbgMaps()260 LteFrHardAlgorithm::InitializeUplinkRbgMaps ()
261 {
262 m_ulRbgMap.clear ();
263
264 if (!m_enabledInUplink)
265 {
266 m_ulRbgMap.resize (m_ulBandwidth, false);
267 return;
268 }
269
270 m_ulRbgMap.resize (m_ulBandwidth, true);
271
272 NS_ASSERT_MSG (m_ulOffset <= m_ulBandwidth,"UlOffset higher than UlBandwidth");
273 NS_ASSERT_MSG (m_ulSubBand <= m_ulBandwidth,"UlBandwidth higher than UlBandwidth");
274 NS_ASSERT_MSG ((m_ulOffset + m_ulSubBand) <= m_ulBandwidth,
275 "(UlOffset+UlSubBand) higher than UlBandwidth");
276
277 for (uint8_t i = m_ulOffset; i < (m_ulOffset + m_ulSubBand); i++)
278 {
279 m_ulRbgMap[i] = false;
280 }
281 }
282
283 std::vector <bool>
DoGetAvailableDlRbg()284 LteFrHardAlgorithm::DoGetAvailableDlRbg ()
285 {
286 NS_LOG_FUNCTION (this);
287
288 if (m_needReconfiguration)
289 {
290 Reconfigure ();
291 }
292
293 if (m_dlRbgMap.empty ())
294 {
295 InitializeDownlinkRbgMaps ();
296 }
297
298 return m_dlRbgMap;
299 }
300
301 bool
DoIsDlRbgAvailableForUe(int rbId,uint16_t rnti)302 LteFrHardAlgorithm::DoIsDlRbgAvailableForUe (int rbId, uint16_t rnti)
303 {
304 NS_LOG_FUNCTION (this);
305 return !m_dlRbgMap[rbId];
306 }
307
308 std::vector <bool>
DoGetAvailableUlRbg()309 LteFrHardAlgorithm::DoGetAvailableUlRbg ()
310 {
311 NS_LOG_FUNCTION (this);
312
313 if (m_ulRbgMap.empty ())
314 {
315 InitializeUplinkRbgMaps ();
316 }
317
318 return m_ulRbgMap;
319 }
320
321 bool
DoIsUlRbgAvailableForUe(int rbId,uint16_t rnti)322 LteFrHardAlgorithm::DoIsUlRbgAvailableForUe (int rbId, uint16_t rnti)
323 {
324 NS_LOG_FUNCTION (this);
325
326 if (!m_enabledInUplink)
327 {
328 return true;
329 }
330
331 return !m_ulRbgMap[rbId];
332 }
333
334 void
DoReportDlCqiInfo(const struct FfMacSchedSapProvider::SchedDlCqiInfoReqParameters & params)335 LteFrHardAlgorithm::DoReportDlCqiInfo (const struct FfMacSchedSapProvider::SchedDlCqiInfoReqParameters& params)
336 {
337 NS_LOG_FUNCTION (this);
338 NS_LOG_WARN ("Method should not be called, because it is empty");
339 }
340
341 void
DoReportUlCqiInfo(const struct FfMacSchedSapProvider::SchedUlCqiInfoReqParameters & params)342 LteFrHardAlgorithm::DoReportUlCqiInfo (const struct FfMacSchedSapProvider::SchedUlCqiInfoReqParameters& params)
343 {
344 NS_LOG_FUNCTION (this);
345 NS_LOG_WARN ("Method should not be called, because it is empty");
346 }
347
348 void
DoReportUlCqiInfo(std::map<uint16_t,std::vector<double>> ulCqiMap)349 LteFrHardAlgorithm::DoReportUlCqiInfo (std::map <uint16_t, std::vector <double> > ulCqiMap)
350 {
351 NS_LOG_FUNCTION (this);
352 NS_LOG_WARN ("Method should not be called, because it is empty");
353 }
354
355 uint8_t
DoGetTpc(uint16_t rnti)356 LteFrHardAlgorithm::DoGetTpc (uint16_t rnti)
357 {
358 NS_LOG_FUNCTION (this);
359 return 1; // 1 is mapped to 0 for Accumulated mode, and to -1 in Absolute mode TS36.213 Table 5.1.1.1-2
360 }
361
362 uint16_t
DoGetMinContinuousUlBandwidth()363 LteFrHardAlgorithm::DoGetMinContinuousUlBandwidth ()
364 {
365 NS_LOG_FUNCTION (this);
366
367 if (!m_enabledInUplink)
368 {
369 return m_ulBandwidth;
370 }
371
372 return m_ulSubBand;
373 }
374
375 void
DoReportUeMeas(uint16_t rnti,LteRrcSap::MeasResults measResults)376 LteFrHardAlgorithm::DoReportUeMeas (uint16_t rnti,
377 LteRrcSap::MeasResults measResults)
378 {
379 NS_LOG_FUNCTION (this << rnti << (uint16_t) measResults.measId);
380 NS_LOG_WARN ("Method should not be called, because it is empty");
381 }
382
383 void
DoRecvLoadInformation(EpcX2Sap::LoadInformationParams params)384 LteFrHardAlgorithm::DoRecvLoadInformation (EpcX2Sap::LoadInformationParams params)
385 {
386 NS_LOG_FUNCTION (this);
387 NS_LOG_WARN ("Method should not be called, because it is empty");
388 }
389
390 } // end of namespace ns3
391