A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
lte-ffr-enhanced-algorithm.cc
Go to the documentation of this file.
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 
23 #include "ns3/ff-mac-common.h"
24 #include "ns3/lte-common.h"
25 #include "ns3/lte-vendor-specific-parameters.h"
26 #include <ns3/log.h>
27 #include "ns3/boolean.h"
28 #include <ns3/double.h>
29 #include <cfloat>
30 
31 NS_LOG_COMPONENT_DEFINE ("LteFfrEnhancedAlgorithm");
32 
33 namespace ns3 {
34 
35 NS_OBJECT_ENSURE_REGISTERED (LteFfrEnhancedAlgorithm);
36 
37 static const double SpectralEfficiencyForCqi[16] = {
38  0.0, // out of range
39  0.15, 0.23, 0.38, 0.6, 0.88, 1.18,
40  1.48, 1.91, 2.41,
41  2.73, 3.32, 3.9, 4.52, 5.12, 5.55
42 };
43 
45 {
46  uint8_t cellId;
47  uint8_t dlBandwidth;
48  uint8_t dlSubBandOffset;
52  { 1, 25, 0, 4, 4},
53  { 2, 25, 8, 4, 4},
54  { 3, 25, 16, 4, 4},
55  { 1, 50, 0, 9, 6},
56  { 2, 50, 15, 9, 6},
57  { 3, 50, 30, 9, 6},
58  { 1, 75, 0, 8, 16},
59  { 2, 75, 24, 8, 16},
60  { 3, 75, 48, 8, 16},
61  { 1, 100, 0, 16, 16},
62  { 2, 100, 32, 16, 16},
63  { 3, 100, 64, 16, 16}
64 };
65 
67 {
68  uint8_t cellId;
69  uint8_t ulBandwidth;
70  uint8_t ulSubBandOffset;
74  { 1, 25, 0, 4, 4},
75  { 2, 25, 8, 4, 4},
76  { 3, 25, 16, 4, 4},
77  { 1, 50, 0, 9, 6},
78  { 2, 50, 15, 9, 6},
79  { 3, 50, 30, 9, 6},
80  { 1, 75, 0, 8, 16},
81  { 2, 75, 24, 8, 16},
82  { 3, 75, 48, 8, 16},
83  { 1, 100, 0, 16, 16},
84  { 2, 100, 32, 16, 16},
85  { 3, 100, 64, 16, 16}
86 };
87 
88 const uint16_t NUM_DOWNLINK_CONFS (sizeof (g_ffrEnhancedDownlinkDefaultConfiguration) / sizeof (FfrEnhancedDownlinkDefaultConfiguration));
89 const uint16_t NUM_UPLINK_CONFS (sizeof (g_ffrEnhancedUplinkDefaultConfiguration) / sizeof (FfrEnhancedUplinkDefaultConfiguration));
90 
91 
93  : m_ffrSapUser (0),
94  m_ffrRrcSapUser (0),
95  m_measId (0)
96 {
97  NS_LOG_FUNCTION (this);
100 }
101 
102 
104 {
105  NS_LOG_FUNCTION (this);
106 }
107 
108 
109 void
111 {
112  NS_LOG_FUNCTION (this);
113  delete m_ffrSapProvider;
114  delete m_ffrRrcSapProvider;
115 }
116 
117 
118 TypeId
120 {
121  static TypeId tid = TypeId ("ns3::LteFfrEnhancedAlgorithm")
123  .AddConstructor<LteFfrEnhancedAlgorithm> ()
124  .AddAttribute ("UlSubBandOffset",
125  "Uplink SubBand Offset for this cell in number of Resource Block Groups",
126  UintegerValue (0),
127  MakeUintegerAccessor (&LteFfrEnhancedAlgorithm::m_ulSubBandOffset),
128  MakeUintegerChecker<uint8_t> ())
129  .AddAttribute ("UlReuse3SubBandwidth",
130  "Uplink Reuse 3 SubBandwidth Configuration in number of Resource Block Groups",
131  UintegerValue (4),
132  MakeUintegerAccessor (&LteFfrEnhancedAlgorithm::m_ulReuse3SubBandwidth),
133  MakeUintegerChecker<uint8_t> ())
134  .AddAttribute ("UlReuse1SubBandwidth",
135  "Uplink Reuse 1 SubBandwidth Configuration in number of Resource Block Groups",
136  UintegerValue (4),
137  MakeUintegerAccessor (&LteFfrEnhancedAlgorithm::m_ulReuse1SubBandwidth),
138  MakeUintegerChecker<uint8_t> ())
139  .AddAttribute ("DlSubBandOffset",
140  "Downlink SubBand Offset for this cell in number of Resource Block Groups",
141  UintegerValue (0),
142  MakeUintegerAccessor (&LteFfrEnhancedAlgorithm::m_dlSubBandOffset),
143  MakeUintegerChecker<uint8_t> ())
144  .AddAttribute ("DlReuse3SubBandwidth",
145  "Downlink Reuse 3 SubBandwidth Configuration in number of Resource Block Groups",
146  UintegerValue (4),
147  MakeUintegerAccessor (&LteFfrEnhancedAlgorithm::m_dlReuse3SubBandwidth),
148  MakeUintegerChecker<uint8_t> ())
149  .AddAttribute ("DlReuse1SubBandwidth",
150  "Downlink Reuse 1 SubBandwidth Configuration in number of Resource Block Groups",
151  UintegerValue (4),
152  MakeUintegerAccessor (&LteFfrEnhancedAlgorithm::m_dlReuse1SubBandwidth),
153  MakeUintegerChecker<uint8_t> ())
154  .AddAttribute ("RsrqThreshold",
155  "If the RSRQ of is worse than this threshold, UE should be served in Edge sub-band",
156  UintegerValue (26),
157  MakeUintegerAccessor (&LteFfrEnhancedAlgorithm::m_rsrqThreshold),
158  MakeUintegerChecker<uint8_t> ())
159  .AddAttribute ("CenterAreaPowerOffset",
160  "PdschConfigDedicated::Pa value for Center Sub-band, default value dB0",
161  UintegerValue (5),
162  MakeUintegerAccessor (&LteFfrEnhancedAlgorithm::m_centerAreaPowerOffset),
163  MakeUintegerChecker<uint8_t> ())
164  .AddAttribute ("EdgeAreaPowerOffset",
165  "PdschConfigDedicated::Pa value for Edge Sub-band, default value dB0",
166  UintegerValue (5),
167  MakeUintegerAccessor (&LteFfrEnhancedAlgorithm::m_edgeAreaPowerOffset),
168  MakeUintegerChecker<uint8_t> ())
169  .AddAttribute ("DlCqiThreshold",
170  "If the DL-CQI for RBG of is higher than this threshold, transmission on RBG is possible",
171  UintegerValue (15),
172  MakeUintegerAccessor (&LteFfrEnhancedAlgorithm::m_dlCqiThreshold),
173  MakeUintegerChecker<uint8_t> ())
174  .AddAttribute ("UlCqiThreshold",
175  "If the UL-CQI for RBG of is higher than this threshold, transmission on RBG is possible",
176  UintegerValue (15),
177  MakeUintegerAccessor (&LteFfrEnhancedAlgorithm::m_ulCqiThreshold),
178  MakeUintegerChecker <uint8_t> ())
179  .AddAttribute ("CenterAreaTpc",
180  "TPC value which will be set in DL-DCI for UEs in center area"
181  "Absolute mode is used, default value 1 is mapped to -1 according to"
182  "TS36.213 Table 5.1.1.1-2",
183  UintegerValue (1),
184  MakeUintegerAccessor (&LteFfrEnhancedAlgorithm::m_centerAreaTpc),
185  MakeUintegerChecker<uint8_t> ())
186  .AddAttribute ("EdgeAreaTpc",
187  "TPC value which will be set in DL-DCI for UEs in edge area"
188  "Absolute mode is used, default value 1 is mapped to -1 according to"
189  "TS36.213 Table 5.1.1.1-2",
190  UintegerValue (1),
191  MakeUintegerAccessor (&LteFfrEnhancedAlgorithm::m_edgeAreaTpc),
192  MakeUintegerChecker<uint8_t> ())
193  ;
194  return tid;
195 }
196 
197 
198 void
200 {
201  NS_LOG_FUNCTION (this << s);
202  m_ffrSapUser = s;
203 }
204 
205 
208 {
209  NS_LOG_FUNCTION (this);
210  return m_ffrSapProvider;
211 }
212 
213 void
215 {
216  NS_LOG_FUNCTION (this << s);
217  m_ffrRrcSapUser = s;
218 }
219 
220 
223 {
224  NS_LOG_FUNCTION (this);
225  return m_ffrRrcSapProvider;
226 }
227 
228 
229 void
231 {
232  NS_LOG_FUNCTION (this);
234 
235  NS_ASSERT_MSG (m_dlBandwidth > 24,"DlBandwidth must be at least 25 to use EFFR algorithm");
236  NS_ASSERT_MSG (m_ulBandwidth > 24,"UlBandwidth must be at least 25 to use EFFR algorithm");
237 
238  if (m_frCellTypeId != 0)
239  {
242  }
243 
244  NS_LOG_LOGIC (this << " requesting Event A1 measurements"
245  << " (threshold = 0" << ")");
246  LteRrcSap::ReportConfigEutra reportConfig;
249  reportConfig.threshold1.range = 0;
253 }
254 
255 void
257 {
258  NS_LOG_FUNCTION (this);
259  if (m_frCellTypeId != 0)
260  {
263  }
266  m_needReconfiguration = false;
267 }
268 
269 void
270 LteFfrEnhancedAlgorithm::SetDownlinkConfiguration (uint16_t cellId, uint8_t bandwidth)
271 {
272  NS_LOG_FUNCTION (this);
273  for (uint16_t i = 0; i < NUM_DOWNLINK_CONFS; ++i)
274  {
275  if ((g_ffrEnhancedDownlinkDefaultConfiguration[i].cellId == cellId)
277  {
281  }
282  }
283 }
284 
285 void
286 LteFfrEnhancedAlgorithm::SetUplinkConfiguration (uint16_t cellId, uint8_t bandwidth)
287 {
288  NS_LOG_FUNCTION (this);
289  for (uint16_t i = 0; i < NUM_UPLINK_CONFS; ++i)
290  {
291  if ((g_ffrEnhancedUplinkDefaultConfiguration[i].cellId == cellId)
293  {
297  }
298  }
299 }
300 
301 int
303 {
304  NS_LOG_FUNCTION (s);
305  NS_ASSERT_MSG (s >= 0.0, "negative spectral efficiency = " << s);
306  int cqi = 0;
307  while ((cqi < 15) && (SpectralEfficiencyForCqi[cqi + 1] < s))
308  {
309  ++cqi;
310  }
311  NS_LOG_LOGIC ("cqi = " << cqi);
312  return cqi;
313 }
314 
315 void
317 {
318  m_dlRbgMap.clear ();
319  m_dlReuse3RbgMap.clear ();
320  m_dlReuse1RbgMap.clear ();
321  m_dlPrimarySegmentRbgMap.clear ();
323 
324  int rbgSize = GetRbgSize (m_dlBandwidth);
325  m_dlRbgMap.resize (m_dlBandwidth / rbgSize, true);
326 
327  m_dlReuse3RbgMap.resize (m_dlBandwidth / rbgSize, false);
328  m_dlReuse1RbgMap.resize (m_dlBandwidth / rbgSize, false);
329  m_dlPrimarySegmentRbgMap.resize (m_dlBandwidth / rbgSize, false);
330  m_dlSecondarySegmentRbgMap.resize (m_dlBandwidth / rbgSize, true);
331 
332  NS_ASSERT_MSG (m_dlSubBandOffset <= m_dlBandwidth,"DlSubBandOffset higher than DlBandwidth");
334  "DlSubBandOffset + DlReuse3SubBandwidth + DlReuse1SubBandwidth higher than DlBandwidth");
335 
336  for (uint8_t i = 0; i < m_dlReuse3SubBandwidth / rbgSize; i++)
337  {
338  int offset = m_dlSubBandOffset / rbgSize;
339  uint8_t index = offset + i;
340  m_dlReuse3RbgMap[index] = true;
341  m_dlPrimarySegmentRbgMap[index] = true;
342  m_dlRbgMap[index] = false;
343  }
344 
345  for (uint8_t i = 0; i < m_dlReuse1SubBandwidth / rbgSize; i++)
346  {
347  int offset = (m_dlSubBandOffset + m_dlReuse3SubBandwidth) / rbgSize;
348  uint8_t index = offset + i;
349  m_dlReuse1RbgMap[index] = true;
350  m_dlPrimarySegmentRbgMap[index] = true;
351  m_dlSecondarySegmentRbgMap[index] = false;
352  m_dlRbgMap[index] = false;
353  }
354 
355  for (uint8_t i = 0; i < m_dlReuse3SubBandwidth / rbgSize; i++)
356  {
357  uint8_t offset = (m_dlReuse3SubBandwidth + m_dlReuse1SubBandwidth) / rbgSize;
358 
359  uint8_t index = 0 * offset + i;
360  m_dlSecondarySegmentRbgMap[index] = false;
361 
362  index = 1 * offset + i;
363  m_dlSecondarySegmentRbgMap[index] = false;
364 
365  index = 2 * offset + i;
366  m_dlSecondarySegmentRbgMap[index] = false;
367  }
368 }
369 
370 
371 void
373 {
374  m_ulRbgMap.clear ();
375  m_ulReuse3RbgMap.clear ();
376  m_ulReuse1RbgMap.clear ();
377  m_ulPrimarySegmentRbgMap.clear ();
379 
380  if (!m_enabledInUplink)
381  {
382  m_ulRbgMap.resize (m_ulBandwidth, false);
383  return;
384  }
385 
386  m_ulRbgMap.resize (m_ulBandwidth, true);
387  m_ulReuse3RbgMap.resize (m_ulBandwidth, false);
388  m_ulReuse1RbgMap.resize (m_ulBandwidth, false);
389  m_ulPrimarySegmentRbgMap.resize (m_ulBandwidth, false);
391 
392 
393  NS_ASSERT_MSG (m_ulSubBandOffset <= m_ulBandwidth, "UlSubBandOffset higher than UlBandwidth");
395  "UlSubBandOffset + UlReuse3SubBandwidth + UlReuse1SubBandwidth higher than UlBandwidth");
396 
397 
398  for (uint8_t i = 0; i < m_ulReuse3SubBandwidth; i++)
399  {
400  int offset = m_ulSubBandOffset;
401  uint8_t index = offset + i;
402  m_ulReuse3RbgMap[index] = true;
403  m_ulPrimarySegmentRbgMap[index] = true;
404  m_ulRbgMap[index] = false;
405  }
406 
407  for (uint8_t i = 0; i < m_ulReuse1SubBandwidth; i++)
408  {
409  int offset = (m_ulSubBandOffset + m_ulReuse3SubBandwidth);
410  uint8_t index = offset + i;
411  m_ulReuse1RbgMap[index] = true;
412  m_ulPrimarySegmentRbgMap[index] = true;
413  m_ulSecondarySegmentRbgMap[index] = false;
414  m_ulRbgMap[index] = false;
415  }
416 
417  for (uint8_t i = 0; i < m_ulReuse3SubBandwidth; i++)
418  {
419  uint8_t offset = m_ulReuse3SubBandwidth + m_ulReuse1SubBandwidth;
420 
421  uint8_t index = 0 * offset + i;
422  m_ulSecondarySegmentRbgMap[index] = false;
423 
424  index = 1 * offset + i;
425  m_ulSecondarySegmentRbgMap[index] = false;
426 
427  index = 2 * offset + i;
428  m_ulSecondarySegmentRbgMap[index] = false;
429 
430  }
431 }
432 
433 std::vector <bool>
435 {
436  NS_LOG_FUNCTION (this);
437 
439  {
440  Reconfigure ();
441  }
442 
443  if (m_dlRbgMap.empty ())
444  {
446  }
447 
448  std::vector <bool> rbgMap = m_dlRbgMap;
449 
450  std::map <uint16_t, std::vector<bool> >::iterator it;
451  for (it = m_dlRbgAvailableforUe.begin (); it != m_dlRbgAvailableforUe.end (); it++)
452  {
453  NS_LOG_INFO ("RNTI : " << it->first);
454  std::vector<bool> rbgAvailableMap = it->second;
455  for (uint32_t i = 0; i < rbgMap.size (); i++)
456  {
457  NS_LOG_INFO ("\t rbgId: " << i << " available " << (int)rbgAvailableMap.at (i));
458  if ( rbgAvailableMap.at (i) == true)
459  {
460  rbgMap.at (i) = false;
461  }
462  }
463  }
464 
465  return rbgMap;
466 }
467 
468 bool
470 {
471  NS_LOG_FUNCTION (this);
472 
473  bool isReuse3Rbg = m_dlReuse3RbgMap[rbgId];
474  bool isReuse1Rbg = m_dlReuse1RbgMap[rbgId];
475  bool isPrimarySegmentRbg = m_dlPrimarySegmentRbgMap[rbgId];
476  bool isSecondarySegmentRbg = m_dlSecondarySegmentRbgMap[rbgId];
477 
478  std::map< uint16_t, uint8_t >::iterator it = m_ues.find (rnti);
479  if (it == m_ues.end ())
480  {
481  m_ues.insert (std::pair< uint16_t, uint8_t > (rnti, AreaUnset));
482  }
483 
484  it = m_ues.find (rnti);
485 
486  //if UE area is unknown, serve UE in edge area RBGs
487  if (it->second == AreaUnset)
488  {
489  return isReuse3Rbg;
490  }
491 
492 
493  bool isCenterUe = false;
494  bool isEdgeUe = false;
495 
496  if (it->second == CenterArea )
497  {
498  isCenterUe = true;
499  }
500  else if (it->second == EdgeArea)
501  {
502  isEdgeUe = true;
503  }
504 
505  if (isPrimarySegmentRbg)
506  {
507  NS_LOG_INFO ("PRIMARY SEGMENT RNTI: " << rnti << " rbgId: " << rbgId );
508  return (isReuse1Rbg && isCenterUe) || (isReuse3Rbg && isEdgeUe);
509  }
510  else if (isSecondarySegmentRbg && isCenterUe)
511  {
512  //check if RB can be used by UE based on CQI information
513  NS_LOG_INFO ("SECONDARY SEGMENT RNTI: " << rnti << " rbgId: " << rbgId );
514  std::map <uint16_t, std::vector<bool> >::iterator it = m_dlRbgAvailableforUe.find (rnti);
515  if (it != m_dlRbgAvailableforUe.end ())
516  {
517  NS_LOG_INFO ("RNTI: " << rnti << " rbgId: " << rbgId << " available: " << it->second.at (rbgId));
518  if (it->second.at (rbgId) == true)
519  {
520  return true;
521  }
522  }
523  return false;
524  }
525 
526  return false;
527 }
528 
529 std::vector <bool>
531 {
532  NS_LOG_FUNCTION (this);
533 
534  if (m_ulRbgMap.empty ())
535  {
537  }
538 
539  if (!m_enabledInUplink)
540  {
541  return m_ulRbgMap;
542  }
543 
544  std::vector <bool> rbgMap = m_ulRbgMap;
545 
546  std::map <uint16_t, std::vector<bool> >::iterator it;
547  for (it = m_ulRbAvailableforUe.begin (); it != m_ulRbAvailableforUe.end (); it++)
548  {
549  NS_LOG_INFO ("RNTI : " << it->first);
550  std::vector<bool> rbAvailableMap = it->second;
551  for (uint32_t i = 0; i < rbgMap.size (); i++)
552  {
553  NS_LOG_INFO ("\t rbgId: " << i << " available " << (int)rbAvailableMap.at (i));
554  if ( rbAvailableMap.at (i) == true)
555  {
556  rbgMap.at (i) = false;
557  }
558  }
559  }
560 
561  return rbgMap;
562 }
563 
564 bool
566 {
567  NS_LOG_FUNCTION (this);
568 
569  if (!m_enabledInUplink)
570  {
571  return true;
572  }
573 
574  bool isReuse3Rbg = m_ulReuse3RbgMap[rbgId];
575  bool isReuse1Rbg = m_ulReuse1RbgMap[rbgId];
576  bool isPrimarySegmentRbg = m_ulPrimarySegmentRbgMap[rbgId];
577  bool isSecondarySegmentRbg = m_ulSecondarySegmentRbgMap[rbgId];
578 
579  std::map< uint16_t, uint8_t >::iterator it = m_ues.find (rnti);
580  if (it == m_ues.end ())
581  {
582  m_ues.insert (std::pair< uint16_t, uint8_t > (rnti, AreaUnset));
583  }
584 
585  it = m_ues.find (rnti);
586 
587  //if UE area is unknown, serve UE in edge area RBGs
588  if (it->second == AreaUnset)
589  {
590  return isReuse3Rbg;
591  }
592 
593  bool isCenterUe = false;
594  bool isEdgeUe = false;
595 
596  if (it->second == CenterArea )
597  {
598  isCenterUe = true;
599  }
600  else if (it->second == EdgeArea)
601  {
602  isEdgeUe = true;
603  }
604 
605  if (isPrimarySegmentRbg)
606  {
607  return (isReuse1Rbg && isCenterUe) || (isReuse3Rbg && isEdgeUe);
608  }
609  else if (isSecondarySegmentRbg && isCenterUe)
610  {
611  //check if RB can be used by UE based on CQI information
612  NS_LOG_INFO ("UL SECONDARY SEGMENT RNTI: " << rnti << " rbgId: " << rbgId );
613  std::map <uint16_t, std::vector<bool> >::iterator it = m_ulRbAvailableforUe.find (rnti);
614  if (it != m_ulRbAvailableforUe.end ())
615  {
616  NS_LOG_INFO ("RNTI: " << rnti << " rbgId: " << rbgId << " available: " << it->second.at (rbgId));
617  if (it->second.at (rbgId) == true)
618  {
619  return true;
620  }
621  }
622  return false;
623  }
624 
625  return false;
626 }
627 
628 void
630 {
631  NS_LOG_FUNCTION (this);
632 
633  m_dlCqi.clear ();
634  for (unsigned int i = 0; i < params.m_cqiList.size (); i++)
635  {
636  if ( params.m_cqiList.at (i).m_cqiType == CqiListElement_s::A30 )
637  {
638  NS_LOG_INFO ("subband CQI reporting high layer configured");
639  // subband CQI reporting high layer configured
640  std::map <uint16_t,SbMeasResult_s>::iterator it;
641  uint16_t rnti = params.m_cqiList.at (i).m_rnti;
642 
643  std::map< uint16_t, uint8_t >::iterator ueIt = m_ues.find (rnti);
644  if (ueIt != m_ues.end ())
645  {
646  if (ueIt->second != CenterArea )
647  {
648  continue;
649  }
650  }
651  else
652  {
653  continue;
654  }
655 
656  it = m_dlCqi.find (rnti);
657  if (it == m_dlCqi.end ())
658  {
659  // create the new entry
660  m_dlCqi.insert ( std::pair<uint16_t, SbMeasResult_s > (rnti, params.m_cqiList.at (i).m_sbMeasResult) );
661  }
662  else
663  {
664  // update the CQI value and refresh correspondent timer
665  (*it).second = params.m_cqiList.at (i).m_sbMeasResult;
666  }
667  }
668  else
669  {
670  NS_LOG_ERROR (this << " CQI type unknown");
671  }
672  }
673 
674  uint32_t rbgSize = GetRbgSize (m_dlBandwidth);
675  m_dlRbgAvailableforUe.clear ();
676  std::map <uint16_t,SbMeasResult_s>::iterator it;
677  for (it = m_dlCqi.begin (); it != m_dlCqi.end (); it++)
678  {
679  uint16_t rnti = it->first;
680  std::vector<bool> rbgAvailableMap;
681 
682  for (uint32_t i = 0; i < (*it).second.m_higherLayerSelected.size (); i++)
683  {
684  uint8_t rbgCqi = (*it).second.m_higherLayerSelected.at (i).m_sbCqi.at (0);
685 
686  if (i > m_dlBandwidth / rbgSize)
687  {
688  continue;
689  }
690  NS_LOG_INFO (this << " RNTI " << rnti << " RBG " << i << " DL-CQI: " << (int)rbgCqi);
691 
692  bool rbgAvailable = (rbgCqi > m_dlCqiThreshold) ? true : false;
693 
694  bool isSecondarySegmentRbg = false;
695  if (i < m_dlSecondarySegmentRbgMap.size ())
696  {
697  isSecondarySegmentRbg = m_dlSecondarySegmentRbgMap[i];
698  }
699 
700  rbgAvailable = (isSecondarySegmentRbg == true) ? rbgAvailable : false;
701 
702  rbgAvailableMap.push_back (rbgAvailable);
703  }
704 
705  m_dlRbgAvailableforUe.insert ( std::pair<uint16_t, std::vector<bool> > (rnti, rbgAvailableMap ) );
706  }
707 
708  m_ulRbAvailableforUe.clear ();
709  for (std::map<uint16_t, std::vector<bool> >::iterator it = m_dlRbgAvailableforUe.begin ();
710  it != m_dlRbgAvailableforUe.end (); it++)
711  {
712  uint16_t rnti = it->first;
713  std::vector<bool> dlRbgAvailableMap = it->second;
714  std::vector<bool> ulRbAvailableMap;
715  ulRbAvailableMap.resize (m_ulBandwidth, false);
716 
717  for (uint32_t j = 0; j < dlRbgAvailableMap.size (); j++)
718  {
719  uint32_t index = rbgSize * j;
720  for (uint32_t i = 0; i < rbgSize; i++)
721  {
722  index = index + i;
723  ulRbAvailableMap[index] = dlRbgAvailableMap[j];
724  }
725  }
726 
727  m_ulRbAvailableforUe.insert ( std::pair<uint16_t, std::vector<bool> > (rnti, ulRbAvailableMap ) );
728  }
729 
730  return;
731 }
732 
733 void
735 {
736  NS_LOG_FUNCTION (this);
737  if (params.m_ulCqi.m_type == UlCqi_s::SRS)
738  {
739  // get the RNTI from vendor specific parameters
740  uint16_t rnti = 0;
741  for (uint32_t j = 0; j < m_ulBandwidth; j++)
742  {
743  double sinr = LteFfConverter::fpS11dot3toDouble (params.m_ulCqi.m_sinr.at (j));
744  double s = log2 ( 1 + (
745  std::pow (10, sinr / 10 ) /
746  ( (-std::log (5.0 * 0.00005 )) / 1.5) ));
747  int cqi = GetCqiFromSpectralEfficiency (s);
748  NS_LOG_INFO (this << " RNTI " << rnti << " new SRS-CQI for RB " << j << " value " << sinr << " UL-CQI: " << cqi);
749  }
750  }
751 }
752 
753 void
754 LteFfrEnhancedAlgorithm::DoReportUlCqiInfo ( std::map <uint16_t, std::vector <double> > ulCqiMap )
755 {
756  NS_LOG_FUNCTION (this);
757  NS_LOG_WARN ("Method should not be called, because it is empty");
758 }
759 
760 double
761 LteFfrEnhancedAlgorithm::EstimateUlSinr (uint16_t rnti, uint16_t rb, std::map <uint16_t, std::vector <double> > ulCqiMap)
762 {
763  std::map <uint16_t, std::vector <double> >::iterator itCqi = ulCqiMap.find (rnti);
764  if (itCqi == ulCqiMap.end ())
765  {
766  // no cqi info about this UE
767  return (NO_SINR);
768  }
769  else
770  {
771  // take the average SINR value among the available
772  double sinrSum = 0;
773  int sinrNum = 0;
774  for (uint32_t i = 0; i < m_ulBandwidth; i++)
775  {
776  double sinr = (*itCqi).second.at (i);
777  if (sinr != NO_SINR)
778  {
779  sinrSum += sinr;
780  sinrNum++;
781  }
782  }
783  double estimatedSinr = (sinrNum > 0) ? (sinrSum / sinrNum) : DBL_MAX;
784  // store the value
785  (*itCqi).second.at (rb) = estimatedSinr;
786  return (estimatedSinr);
787  }
788 }
789 
790 uint8_t
792 {
793  NS_LOG_FUNCTION (this);
794 
795  if (!m_enabledInUplink)
796  {
797  return 1; // 1 is mapped to 0 for Accumulated mode, and to -1 in Absolute mode TS36.213 Table 5.1.1.1-2
798  }
799 
800  //TS36.213 Table 5.1.1.1-2
801  // TPC | Accumulated Mode | Absolute Mode
802  //------------------------------------------------
803  // 0 | -1 | -4
804  // 1 | 0 | -1
805  // 2 | 1 | 1
806  // 3 | 3 | 4
807  //------------------------------------------------
808  // here Absolute mode is used
809 
810  std::map< uint16_t, uint8_t >::iterator it = m_ues.find (rnti);
811  if (it == m_ues.end ())
812  {
813  return 1;
814  }
815 
816  if (it->second == EdgeArea )
817  {
818  return m_edgeAreaTpc;
819  }
820  else
821  {
822  return m_centerAreaTpc;
823  }
824 
825  return 1;
826 }
827 
828 uint8_t
830 {
831  NS_LOG_FUNCTION (this);
832 
833  uint8_t minContinuousUlBandwidth = m_ulBandwidth;
834 
835  if (!m_enabledInUplink)
836  {
837  return minContinuousUlBandwidth;
838  }
839 
840  minContinuousUlBandwidth =
841  ((m_ulReuse3SubBandwidth > 0 ) && (m_ulReuse3SubBandwidth < minContinuousUlBandwidth)) ? m_ulReuse3SubBandwidth : minContinuousUlBandwidth;
842 
843  minContinuousUlBandwidth =
844  ((m_ulReuse1SubBandwidth > 0 ) && (m_ulReuse1SubBandwidth < minContinuousUlBandwidth)) ? m_ulReuse1SubBandwidth : minContinuousUlBandwidth;
845 
846  NS_LOG_INFO ("minContinuousUlBandwidth: " << (int)minContinuousUlBandwidth);
847 
848  return minContinuousUlBandwidth;
849 }
850 
851 
852 void
854  LteRrcSap::MeasResults measResults)
855 {
856  NS_LOG_FUNCTION (this << rnti << (uint16_t) measResults.measId);
857  NS_LOG_INFO ("RNTI :" << rnti << " MeasId: " << (uint16_t) measResults.measId
858  << " RSRP: " << (uint16_t)measResults.rsrpResult
859  << " RSRQ: " << (uint16_t)measResults.rsrqResult);
860 
861  if (measResults.measId != m_measId)
862  {
863  NS_LOG_WARN ("Ignoring measId " << (uint16_t) measResults.measId);
864  }
865  else
866  {
867  std::map< uint16_t, uint8_t >::iterator it = m_ues.find (rnti);
868  if (it == m_ues.end ())
869  {
870  m_ues.insert (std::pair< uint16_t, uint8_t > (rnti, AreaUnset));
871  }
872 
873  it = m_ues.find (rnti);
874  if (measResults.rsrqResult < m_rsrqThreshold)
875  {
876  if (it->second != EdgeArea)
877  {
878  NS_LOG_INFO ("UE RNTI: " << rnti << " will be served in Edge sub-band");
879  it->second = EdgeArea;
880 
881  LteRrcSap::PdschConfigDedicated pdschConfigDedicated;
882  pdschConfigDedicated.pa = m_edgeAreaPowerOffset;
883  m_ffrRrcSapUser->SetPdschConfigDedicated (rnti, pdschConfigDedicated);
884  }
885  }
886  else
887  {
888  if (it->second != CenterArea)
889  {
890  NS_LOG_INFO ("UE RNTI: " << rnti << " will be served in Center sub-band");
891  it->second = CenterArea;
892 
893  LteRrcSap::PdschConfigDedicated pdschConfigDedicated;
894  pdschConfigDedicated.pa = m_centerAreaPowerOffset;
895  m_ffrRrcSapUser->SetPdschConfigDedicated (rnti, pdschConfigDedicated);
896  }
897  }
898  }
899 }
900 void
902 {
903  NS_LOG_FUNCTION (this);
904  NS_LOG_WARN ("Method should not be called, because it is empty");
905 }
906 
907 } // end of namespace ns3
RSRQ is used for the threshold.
Definition: lte-rrc-sap.h:315
Service Access Point (SAP) offered by the Frequency Reuse algorithm instance to the eNodeB RRC instan...
virtual uint8_t DoGetMinContinuousUlBandwidth()
DoGetMinContinuousUlBandwidth in number of RB.
Template for the implementation of the LteFfrRrcSapProvider as a member of an owner class of type C t...
virtual LteFfrRrcSapProvider * GetLteFfrRrcSapProvider()
Export the "provider" part of the LteFfrRrcSap interface.
Service Access Point (SAP) offered by the eNodeB RRC instance to the Frequency Reuse algorithm instan...
Definition: lte-ffr-sap.h:132
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
std::map< uint16_t, std::vector< bool > > m_dlRbgAvailableforUe
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register the class in the ns-3 factory.
Definition: object-base.h:38
virtual std::vector< bool > DoGetAvailableUlRbg()
Implementation of LteFfrSapProvider::GetAvailableUlRbg.
enum ns3::UlCqi_s::Type_e m_type
ThresholdEutra threshold1
Threshold for event A1, A2, A4, and A5.
Definition: lte-rrc-sap.h:339
Specifies criteria for triggering of an E-UTRA measurement reporting event.
Definition: lte-rrc-sap.h:321
LteFfrRrcSapProvider * m_ffrRrcSapProvider
std::vector< uint16_t > m_sinr
uint8_t m_ulBandwidth
uplink bandwidth in RBs
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:170
LteFfrEnhancedAlgorithm()
Creates a trivial ffr algorithm instance.
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:223
virtual bool DoIsDlRbgAvailableForUe(int i, uint16_t rnti)
Implementation of LteFfrSapProvider::IsDlRbgAvailableForUe.
virtual void SetLteFfrSapUser(LteFfrSapUser *s)
Set the "user" part of the LteFfrSap interface that this frequency reuse algorithm instance will inte...
virtual uint8_t AddUeMeasReportConfigForFfr(LteRrcSap::ReportConfigEutra reportConfig)=0
Request a certain reporting configuration to be fulfilled by the UEs attached to the eNodeB entity...
virtual void DoReportDlCqiInfo(const struct FfMacSchedSapProvider::SchedDlCqiInfoReqParameters &params)
DoReportDlCqiInfo.
virtual void DoDispose()
This method is called by Object::Dispose or by the object's destructor, whichever comes first...
static const struct ns3::FfrEnhancedUplinkDefaultConfiguration g_ffrEnhancedUplinkDefaultConfiguration[]
virtual void SetPdschConfigDedicated(uint16_t rnti, LteRrcSap::PdschConfigDedicated pdschConfigDedicated)=0
Instruct the eNodeB RRC entity to perform RrcConnectionReconfiguration to inform UE about new PdschCo...
Template for the implementation of the LteFfrSapProvider as a member of an owner class of type C to w...
Definition: lte-ffr-sap.h:146
virtual uint8_t DoGetTpc(uint16_t rnti)
DoGetTpc for UE.
std::map< uint16_t, SbMeasResult_s > m_dlCqi
Service Access Point (SAP) offered by the Frequency Reuse algorithm instance to the MAC Scheduler ins...
Definition: lte-ffr-sap.h:39
Hold an unsigned integer type.
Definition: uinteger.h:46
Ptr< SampleEmitter > s
bool m_enabledInUplink
If true FR algorithm will also work in Uplink.
bool m_needReconfiguration
If true FR algorithm will be reconfigured.
virtual void DoReportUeMeas(uint16_t rnti, LteRrcSap::MeasResults measResults)
Implementation of LteFfrRrcSapProvider::ReportUeMeas.
uint8_t m_dlBandwidth
downlink bandwidth in RBs
double EstimateUlSinr(uint16_t rnti, uint16_t rb, std::map< uint16_t, std::vector< double > > ulCqiMap)
virtual void DoReportUlCqiInfo(const struct FfMacSchedSapProvider::SchedUlCqiInfoReqParameters &params)
DoReportUlCqiInfo.
virtual void DoInitialize()
This method is called only once by Object::Initialize.
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:233
std::vector< struct CqiListElement_s > m_cqiList
static const struct ns3::FfrEnhancedDownlinkDefaultConfiguration g_ffrEnhancedDownlinkDefaultConfiguration[]
virtual std::vector< bool > DoGetAvailableDlRbg()
Implementation of LteFfrSapProvider::GetAvailableDlRbg.
Event A1: Serving becomes better than absolute threshold.
Definition: lte-rrc-sap.h:331
The abstract base class of a Frequency Reuse algorithm.
enum ns3::LteRrcSap::ReportConfigEutra::@73 eventId
Choice of E-UTRA event triggered reporting criteria.
uint8_t range
Value range used in RSRP/RSRQ threshold.
Definition: lte-rrc-sap.h:317
Service Access Point (SAP) offered by the eNodeB RRC instance to the Frequency Reuse algorithm instan...
virtual void DoRecvLoadInformation(EpcX2Sap::LoadInformationParams params)
DoRecvLoadInformation.
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition: assert.h:84
Parameters of the SCHED_DL_CQI_INFO_REQ primitive.
uint8_t m_frCellTypeId
FFR cell type ID for automatic configuration.
static double fpS11dot3toDouble(uint16_t val)
Definition: lte-common.cc:114
enum ns3::LteRrcSap::ReportConfigEutra::@77 reportInterval
Indicates the interval between periodical reports.
virtual void SetLteFfrRrcSapUser(LteFfrRrcSapUser *s)
Set the "user" part of the LteFfrRrcSap interface that this frequency reuse algorithm instance will i...
void SetUplinkConfiguration(uint16_t cellId, uint8_t bandwidth)
Parameters of the SCHED_UL_CQI_INFO_REQ primitive.
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition: log.h:203
std::map< uint16_t, uint8_t > m_ues
enum ns3::LteRrcSap::ReportConfigEutra::@75 triggerQuantity
The quantities used to evaluate the triggering condition for the event, see 3GPP TS 36...
virtual LteFfrSapProvider * GetLteFfrSapProvider()
Export the "provider" part of the LteFfrSap interface.
virtual bool DoIsUlRbgAvailableForUe(int i, uint16_t rnti)
Implementation of LteFfrSapProvider::IsUlRbgAvailableForUe.
int GetRbgSize(int dlbandwidth)
Get RBG size for DL Bandwidth according to table 7.1.6.1-1 of 36.213.
Parameters of the LOAD INFORMATION message.
Definition: epc-x2-sap.h:300
void SetDownlinkConfiguration(uint16_t cellId, uint8_t bandwidth)
#define NS_LOG_ERROR(msg)
Use NS_LOG to output a message of level LOG_ERROR.
Definition: log.h:193
Reference Signal Received Quality.
Definition: lte-rrc-sap.h:363
static const double SpectralEfficiencyForCqi[16]
Definition: lte-amc.cc:45
const uint16_t NUM_DOWNLINK_CONFS(sizeof(g_ffrEnhancedDownlinkDefaultConfiguration)/sizeof(FfrEnhancedDownlinkDefaultConfiguration))
enum ns3::LteRrcSap::ThresholdEutra::@71 choice
#define NO_SINR
a unique identifier for an interface.
Definition: type-id.h:49
TypeId SetParent(TypeId tid)
Definition: type-id.cc:610
const uint16_t NUM_UPLINK_CONFS(sizeof(g_ffrEnhancedUplinkDefaultConfiguration)/sizeof(FfrEnhancedUplinkDefaultConfiguration))
virtual void DoInitialize(void)
This method is called only once by Object::Initialize.
Definition: object.cc:342
virtual void Reconfigure()
Automatic FR reconfiguration.
std::map< uint16_t, std::vector< bool > > m_ulRbAvailableforUe