A Discrete-Event Network Simulator
API
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 namespace ns3 {
32 
33 NS_LOG_COMPONENT_DEFINE ("LteFfrEnhancedAlgorithm");
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  .SetGroupName("Lte")
124  .AddConstructor<LteFfrEnhancedAlgorithm> ()
125  .AddAttribute ("UlSubBandOffset",
126  "Uplink SubBand Offset for this cell in number of Resource Block Groups",
127  UintegerValue (0),
129  MakeUintegerChecker<uint8_t> ())
130  .AddAttribute ("UlReuse3SubBandwidth",
131  "Uplink Reuse 3 SubBandwidth Configuration in number of Resource Block Groups",
132  UintegerValue (4),
134  MakeUintegerChecker<uint8_t> ())
135  .AddAttribute ("UlReuse1SubBandwidth",
136  "Uplink Reuse 1 SubBandwidth Configuration in number of Resource Block Groups",
137  UintegerValue (4),
139  MakeUintegerChecker<uint8_t> ())
140  .AddAttribute ("DlSubBandOffset",
141  "Downlink SubBand Offset for this cell in number of Resource Block Groups",
142  UintegerValue (0),
144  MakeUintegerChecker<uint8_t> ())
145  .AddAttribute ("DlReuse3SubBandwidth",
146  "Downlink Reuse 3 SubBandwidth Configuration in number of Resource Block Groups",
147  UintegerValue (4),
149  MakeUintegerChecker<uint8_t> ())
150  .AddAttribute ("DlReuse1SubBandwidth",
151  "Downlink Reuse 1 SubBandwidth Configuration in number of Resource Block Groups",
152  UintegerValue (4),
154  MakeUintegerChecker<uint8_t> ())
155  .AddAttribute ("RsrqThreshold",
156  "If the RSRQ of is worse than this threshold, UE should be served in Edge sub-band",
157  UintegerValue (26),
159  MakeUintegerChecker<uint8_t> ())
160  .AddAttribute ("CenterAreaPowerOffset",
161  "PdschConfigDedicated::Pa value for Center Sub-band, default value dB0",
162  UintegerValue (5),
164  MakeUintegerChecker<uint8_t> ())
165  .AddAttribute ("EdgeAreaPowerOffset",
166  "PdschConfigDedicated::Pa value for Edge Sub-band, default value dB0",
167  UintegerValue (5),
169  MakeUintegerChecker<uint8_t> ())
170  .AddAttribute ("DlCqiThreshold",
171  "If the DL-CQI for RBG of is higher than this threshold, transmission on RBG is possible",
172  UintegerValue (15),
174  MakeUintegerChecker<uint8_t> ())
175  .AddAttribute ("UlCqiThreshold",
176  "If the UL-CQI for RBG of is higher than this threshold, transmission on RBG is possible",
177  UintegerValue (15),
179  MakeUintegerChecker <uint8_t> ())
180  .AddAttribute ("CenterAreaTpc",
181  "TPC value which will be set in DL-DCI for UEs in center area"
182  "Absolute mode is used, default value 1 is mapped to -1 according to"
183  "TS36.213 Table 5.1.1.1-2",
184  UintegerValue (1),
186  MakeUintegerChecker<uint8_t> ())
187  .AddAttribute ("EdgeAreaTpc",
188  "TPC value which will be set in DL-DCI for UEs in edge area"
189  "Absolute mode is used, default value 1 is mapped to -1 according to"
190  "TS36.213 Table 5.1.1.1-2",
191  UintegerValue (1),
193  MakeUintegerChecker<uint8_t> ())
194  ;
195  return tid;
196 }
197 
198 
199 void
201 {
202  NS_LOG_FUNCTION (this << s);
203  m_ffrSapUser = s;
204 }
205 
206 
209 {
210  NS_LOG_FUNCTION (this);
211  return m_ffrSapProvider;
212 }
213 
214 void
216 {
217  NS_LOG_FUNCTION (this << s);
218  m_ffrRrcSapUser = s;
219 }
220 
221 
224 {
225  NS_LOG_FUNCTION (this);
226  return m_ffrRrcSapProvider;
227 }
228 
229 
230 void
232 {
233  NS_LOG_FUNCTION (this);
235 
236  NS_ASSERT_MSG (m_dlBandwidth > 24,"DlBandwidth must be at least 25 to use EFFR algorithm");
237  NS_ASSERT_MSG (m_ulBandwidth > 24,"UlBandwidth must be at least 25 to use EFFR algorithm");
238 
239  if (m_frCellTypeId != 0)
240  {
243  }
244 
245  NS_LOG_LOGIC (this << " requesting Event A1 measurements"
246  << " (threshold = 0" << ")");
247  LteRrcSap::ReportConfigEutra reportConfig;
250  reportConfig.threshold1.range = 0;
254 }
255 
256 void
258 {
259  NS_LOG_FUNCTION (this);
260  if (m_frCellTypeId != 0)
261  {
264  }
267  m_needReconfiguration = false;
268 }
269 
270 void
271 LteFfrEnhancedAlgorithm::SetDownlinkConfiguration (uint16_t cellId, uint8_t bandwidth)
272 {
273  NS_LOG_FUNCTION (this);
274  for (uint16_t i = 0; i < NUM_DOWNLINK_CONFS; ++i)
275  {
276  if ((g_ffrEnhancedDownlinkDefaultConfiguration[i].cellId == cellId)
278  {
282  }
283  }
284 }
285 
286 void
287 LteFfrEnhancedAlgorithm::SetUplinkConfiguration (uint16_t cellId, uint8_t bandwidth)
288 {
289  NS_LOG_FUNCTION (this);
290  for (uint16_t i = 0; i < NUM_UPLINK_CONFS; ++i)
291  {
292  if ((g_ffrEnhancedUplinkDefaultConfiguration[i].cellId == cellId)
294  {
298  }
299  }
300 }
301 
302 int
304 {
305  NS_LOG_FUNCTION (s);
306  NS_ASSERT_MSG (s >= 0.0, "negative spectral efficiency = " << s);
307  int cqi = 0;
308  while ((cqi < 15) && (SpectralEfficiencyForCqi[cqi + 1] < s))
309  {
310  ++cqi;
311  }
312  NS_LOG_LOGIC ("cqi = " << cqi);
313  return cqi;
314 }
315 
316 void
318 {
319  m_dlRbgMap.clear ();
320  m_dlReuse3RbgMap.clear ();
321  m_dlReuse1RbgMap.clear ();
322  m_dlPrimarySegmentRbgMap.clear ();
324 
325  int rbgSize = GetRbgSize (m_dlBandwidth);
326  m_dlRbgMap.resize (m_dlBandwidth / rbgSize, true);
327 
328  m_dlReuse3RbgMap.resize (m_dlBandwidth / rbgSize, false);
329  m_dlReuse1RbgMap.resize (m_dlBandwidth / rbgSize, false);
330  m_dlPrimarySegmentRbgMap.resize (m_dlBandwidth / rbgSize, false);
331  m_dlSecondarySegmentRbgMap.resize (m_dlBandwidth / rbgSize, true);
332 
333  NS_ASSERT_MSG (m_dlSubBandOffset <= m_dlBandwidth,"DlSubBandOffset higher than DlBandwidth");
335  "DlSubBandOffset + DlReuse3SubBandwidth + DlReuse1SubBandwidth higher than DlBandwidth");
336 
337  for (uint8_t i = 0; i < m_dlReuse3SubBandwidth / rbgSize; i++)
338  {
339  int offset = m_dlSubBandOffset / rbgSize;
340  uint8_t index = offset + i;
341  m_dlReuse3RbgMap[index] = true;
342  m_dlPrimarySegmentRbgMap[index] = true;
343  m_dlRbgMap[index] = false;
344  }
345 
346  for (uint8_t i = 0; i < m_dlReuse1SubBandwidth / rbgSize; i++)
347  {
348  int offset = (m_dlSubBandOffset + m_dlReuse3SubBandwidth) / rbgSize;
349  uint8_t index = offset + i;
350  m_dlReuse1RbgMap[index] = true;
351  m_dlPrimarySegmentRbgMap[index] = true;
352  m_dlSecondarySegmentRbgMap[index] = false;
353  m_dlRbgMap[index] = false;
354  }
355 
356  for (uint8_t i = 0; i < m_dlReuse3SubBandwidth / rbgSize; i++)
357  {
358  uint8_t offset = (m_dlReuse3SubBandwidth + m_dlReuse1SubBandwidth) / rbgSize;
359 
360  uint8_t index = 0 * offset + i;
361  m_dlSecondarySegmentRbgMap[index] = false;
362 
363  index = 1 * offset + i;
364  m_dlSecondarySegmentRbgMap[index] = false;
365 
366  index = 2 * offset + i;
367  m_dlSecondarySegmentRbgMap[index] = false;
368  }
369 }
370 
371 
372 void
374 {
375  m_ulRbgMap.clear ();
376  m_ulReuse3RbgMap.clear ();
377  m_ulReuse1RbgMap.clear ();
378  m_ulPrimarySegmentRbgMap.clear ();
380 
381  if (!m_enabledInUplink)
382  {
383  m_ulRbgMap.resize (m_ulBandwidth, false);
384  return;
385  }
386 
387  m_ulRbgMap.resize (m_ulBandwidth, true);
388  m_ulReuse3RbgMap.resize (m_ulBandwidth, false);
389  m_ulReuse1RbgMap.resize (m_ulBandwidth, false);
390  m_ulPrimarySegmentRbgMap.resize (m_ulBandwidth, false);
392 
393 
394  NS_ASSERT_MSG (m_ulSubBandOffset <= m_ulBandwidth, "UlSubBandOffset higher than UlBandwidth");
396  "UlSubBandOffset + UlReuse3SubBandwidth + UlReuse1SubBandwidth higher than UlBandwidth");
397 
398 
399  for (uint8_t i = 0; i < m_ulReuse3SubBandwidth; i++)
400  {
401  int offset = m_ulSubBandOffset;
402  uint8_t index = offset + i;
403  m_ulReuse3RbgMap[index] = true;
404  m_ulPrimarySegmentRbgMap[index] = true;
405  m_ulRbgMap[index] = false;
406  }
407 
408  for (uint8_t i = 0; i < m_ulReuse1SubBandwidth; i++)
409  {
410  int offset = (m_ulSubBandOffset + m_ulReuse3SubBandwidth);
411  uint8_t index = offset + i;
412  m_ulReuse1RbgMap[index] = true;
413  m_ulPrimarySegmentRbgMap[index] = true;
414  m_ulSecondarySegmentRbgMap[index] = false;
415  m_ulRbgMap[index] = false;
416  }
417 
418  for (uint8_t i = 0; i < m_ulReuse3SubBandwidth; i++)
419  {
420  uint8_t offset = m_ulReuse3SubBandwidth + m_ulReuse1SubBandwidth;
421 
422  uint8_t index = 0 * offset + i;
423  m_ulSecondarySegmentRbgMap[index] = false;
424 
425  index = 1 * offset + i;
426  m_ulSecondarySegmentRbgMap[index] = false;
427 
428  index = 2 * offset + i;
429  m_ulSecondarySegmentRbgMap[index] = false;
430 
431  }
432 }
433 
434 std::vector <bool>
436 {
437  NS_LOG_FUNCTION (this);
438 
440  {
441  Reconfigure ();
442  }
443 
444  if (m_dlRbgMap.empty ())
445  {
447  }
448 
449  std::vector <bool> rbgMap = m_dlRbgMap;
450 
451  std::map <uint16_t, std::vector<bool> >::iterator it;
452  for (it = m_dlRbgAvailableforUe.begin (); it != m_dlRbgAvailableforUe.end (); it++)
453  {
454  NS_LOG_INFO ("RNTI : " << it->first);
455  std::vector<bool> rbgAvailableMap = it->second;
456  for (uint32_t i = 0; i < rbgMap.size (); i++)
457  {
458  NS_LOG_INFO ("\t rbgId: " << i << " available " << (int)rbgAvailableMap.at (i));
459  if ( rbgAvailableMap.at (i) == true)
460  {
461  rbgMap.at (i) = false;
462  }
463  }
464  }
465 
466  return rbgMap;
467 }
468 
469 bool
471 {
472  NS_LOG_FUNCTION (this);
473 
474  bool isReuse3Rbg = m_dlReuse3RbgMap[rbgId];
475  bool isReuse1Rbg = m_dlReuse1RbgMap[rbgId];
476  bool isPrimarySegmentRbg = m_dlPrimarySegmentRbgMap[rbgId];
477  bool isSecondarySegmentRbg = m_dlSecondarySegmentRbgMap[rbgId];
478 
479  std::map< uint16_t, uint8_t >::iterator it = m_ues.find (rnti);
480  if (it == m_ues.end ())
481  {
482  m_ues.insert (std::pair< uint16_t, uint8_t > (rnti, AreaUnset));
483  }
484 
485  it = m_ues.find (rnti);
486 
487  //if UE area is unknown, serve UE in edge area RBGs
488  if (it->second == AreaUnset)
489  {
490  return isReuse3Rbg;
491  }
492 
493 
494  bool isCenterUe = false;
495  bool isEdgeUe = false;
496 
497  if (it->second == CenterArea )
498  {
499  isCenterUe = true;
500  }
501  else if (it->second == EdgeArea)
502  {
503  isEdgeUe = true;
504  }
505 
506  if (isPrimarySegmentRbg)
507  {
508  NS_LOG_INFO ("PRIMARY SEGMENT RNTI: " << rnti << " rbgId: " << rbgId );
509  return (isReuse1Rbg && isCenterUe) || (isReuse3Rbg && isEdgeUe);
510  }
511  else if (isSecondarySegmentRbg && isCenterUe)
512  {
513  //check if RB can be used by UE based on CQI information
514  NS_LOG_INFO ("SECONDARY SEGMENT RNTI: " << rnti << " rbgId: " << rbgId );
515  std::map <uint16_t, std::vector<bool> >::iterator it = m_dlRbgAvailableforUe.find (rnti);
516  if (it != m_dlRbgAvailableforUe.end ())
517  {
518  NS_LOG_INFO ("RNTI: " << rnti << " rbgId: " << rbgId << " available: " << it->second.at (rbgId));
519  if (it->second.at (rbgId) == true)
520  {
521  return true;
522  }
523  }
524  return false;
525  }
526 
527  return false;
528 }
529 
530 std::vector <bool>
532 {
533  NS_LOG_FUNCTION (this);
534 
535  if (m_ulRbgMap.empty ())
536  {
538  }
539 
540  if (!m_enabledInUplink)
541  {
542  return m_ulRbgMap;
543  }
544 
545  std::vector <bool> rbgMap = m_ulRbgMap;
546 
547  std::map <uint16_t, std::vector<bool> >::iterator it;
548  for (it = m_ulRbAvailableforUe.begin (); it != m_ulRbAvailableforUe.end (); it++)
549  {
550  NS_LOG_INFO ("RNTI : " << it->first);
551  std::vector<bool> rbAvailableMap = it->second;
552  for (uint32_t i = 0; i < rbgMap.size (); i++)
553  {
554  NS_LOG_INFO ("\t rbgId: " << i << " available " << (int)rbAvailableMap.at (i));
555  if ( rbAvailableMap.at (i) == true)
556  {
557  rbgMap.at (i) = false;
558  }
559  }
560  }
561 
562  return rbgMap;
563 }
564 
565 bool
567 {
568  NS_LOG_FUNCTION (this);
569 
570  if (!m_enabledInUplink)
571  {
572  return true;
573  }
574 
575  bool isReuse3Rbg = m_ulReuse3RbgMap[rbgId];
576  bool isReuse1Rbg = m_ulReuse1RbgMap[rbgId];
577  bool isPrimarySegmentRbg = m_ulPrimarySegmentRbgMap[rbgId];
578  bool isSecondarySegmentRbg = m_ulSecondarySegmentRbgMap[rbgId];
579 
580  std::map< uint16_t, uint8_t >::iterator it = m_ues.find (rnti);
581  if (it == m_ues.end ())
582  {
583  m_ues.insert (std::pair< uint16_t, uint8_t > (rnti, AreaUnset));
584  }
585 
586  it = m_ues.find (rnti);
587 
588  //if UE area is unknown, serve UE in edge area RBGs
589  if (it->second == AreaUnset)
590  {
591  return isReuse3Rbg;
592  }
593 
594  bool isCenterUe = false;
595  bool isEdgeUe = false;
596 
597  if (it->second == CenterArea )
598  {
599  isCenterUe = true;
600  }
601  else if (it->second == EdgeArea)
602  {
603  isEdgeUe = true;
604  }
605 
606  if (isPrimarySegmentRbg)
607  {
608  return (isReuse1Rbg && isCenterUe) || (isReuse3Rbg && isEdgeUe);
609  }
610  else if (isSecondarySegmentRbg && isCenterUe)
611  {
612  //check if RB can be used by UE based on CQI information
613  NS_LOG_INFO ("UL SECONDARY SEGMENT RNTI: " << rnti << " rbgId: " << rbgId );
614  std::map <uint16_t, std::vector<bool> >::iterator it = m_ulRbAvailableforUe.find (rnti);
615  if (it != m_ulRbAvailableforUe.end ())
616  {
617  NS_LOG_INFO ("RNTI: " << rnti << " rbgId: " << rbgId << " available: " << it->second.at (rbgId));
618  if (it->second.at (rbgId) == true)
619  {
620  return true;
621  }
622  }
623  return false;
624  }
625 
626  return false;
627 }
628 
629 void
631 {
632  NS_LOG_FUNCTION (this);
633 
634  m_dlCqi.clear ();
635  for (unsigned int i = 0; i < params.m_cqiList.size (); i++)
636  {
637  if ( params.m_cqiList.at (i).m_cqiType == CqiListElement_s::A30 )
638  {
639  NS_LOG_INFO ("subband CQI reporting high layer configured");
640  // subband CQI reporting high layer configured
641  std::map <uint16_t,SbMeasResult_s>::iterator it;
642  uint16_t rnti = params.m_cqiList.at (i).m_rnti;
643 
644  std::map< uint16_t, uint8_t >::iterator ueIt = m_ues.find (rnti);
645  if (ueIt != m_ues.end ())
646  {
647  if (ueIt->second != CenterArea )
648  {
649  continue;
650  }
651  }
652  else
653  {
654  continue;
655  }
656 
657  it = m_dlCqi.find (rnti);
658  if (it == m_dlCqi.end ())
659  {
660  // create the new entry
661  m_dlCqi.insert ( std::pair<uint16_t, SbMeasResult_s > (rnti, params.m_cqiList.at (i).m_sbMeasResult) );
662  }
663  else
664  {
665  // update the CQI value and refresh correspondent timer
666  (*it).second = params.m_cqiList.at (i).m_sbMeasResult;
667  }
668  }
669  else
670  {
671  NS_LOG_ERROR (this << " CQI type unknown");
672  }
673  }
674 
675  uint32_t rbgSize = GetRbgSize (m_dlBandwidth);
676  m_dlRbgAvailableforUe.clear ();
677  std::map <uint16_t,SbMeasResult_s>::iterator it;
678  for (it = m_dlCqi.begin (); it != m_dlCqi.end (); it++)
679  {
680  uint16_t rnti = it->first;
681  std::vector<bool> rbgAvailableMap;
682 
683  for (uint32_t i = 0; i < (*it).second.m_higherLayerSelected.size (); i++)
684  {
685  uint8_t rbgCqi = (*it).second.m_higherLayerSelected.at (i).m_sbCqi.at (0);
686 
687  if (i > m_dlBandwidth / rbgSize)
688  {
689  continue;
690  }
691  NS_LOG_INFO (this << " RNTI " << rnti << " RBG " << i << " DL-CQI: " << (int)rbgCqi);
692 
693  bool rbgAvailable = (rbgCqi > m_dlCqiThreshold) ? true : false;
694 
695  bool isSecondarySegmentRbg = false;
696  if (i < m_dlSecondarySegmentRbgMap.size ())
697  {
698  isSecondarySegmentRbg = m_dlSecondarySegmentRbgMap[i];
699  }
700 
701  rbgAvailable = (isSecondarySegmentRbg == true) ? rbgAvailable : false;
702 
703  rbgAvailableMap.push_back (rbgAvailable);
704  }
705 
706  m_dlRbgAvailableforUe.insert ( std::pair<uint16_t, std::vector<bool> > (rnti, rbgAvailableMap ) );
707  }
708 
709  m_ulRbAvailableforUe.clear ();
710  for (std::map<uint16_t, std::vector<bool> >::iterator it = m_dlRbgAvailableforUe.begin ();
711  it != m_dlRbgAvailableforUe.end (); it++)
712  {
713  uint16_t rnti = it->first;
714  std::vector<bool> dlRbgAvailableMap = it->second;
715  std::vector<bool> ulRbAvailableMap;
716  ulRbAvailableMap.resize (m_ulBandwidth, false);
717 
718  for (uint32_t j = 0; j < dlRbgAvailableMap.size (); j++)
719  {
720  uint32_t index = rbgSize * j;
721  for (uint32_t i = 0; i < rbgSize; i++)
722  {
723  index = index + i;
724  ulRbAvailableMap[index] = dlRbgAvailableMap[j];
725  }
726  }
727 
728  m_ulRbAvailableforUe.insert ( std::pair<uint16_t, std::vector<bool> > (rnti, ulRbAvailableMap ) );
729  }
730 
731  return;
732 }
733 
734 void
736 {
737  NS_LOG_FUNCTION (this);
738  if (params.m_ulCqi.m_type == UlCqi_s::SRS)
739  {
740  // get the RNTI from vendor specific parameters
741  uint16_t rnti = 0;
742  for (uint32_t j = 0; j < m_ulBandwidth; j++)
743  {
744  double sinr = LteFfConverter::fpS11dot3toDouble (params.m_ulCqi.m_sinr.at (j));
745  double s = log2 ( 1 + (
746  std::pow (10, sinr / 10 ) /
747  ( (-std::log (5.0 * 0.00005 )) / 1.5) ));
748  int cqi = GetCqiFromSpectralEfficiency (s);
749  NS_LOG_INFO (this << " RNTI " << rnti << " new SRS-CQI for RB " << j << " value " << sinr << " UL-CQI: " << cqi);
750  }
751  }
752 }
753 
754 void
755 LteFfrEnhancedAlgorithm::DoReportUlCqiInfo ( std::map <uint16_t, std::vector <double> > ulCqiMap )
756 {
757  NS_LOG_FUNCTION (this);
758  NS_LOG_WARN ("Method should not be called, because it is empty");
759 }
760 
761 double
762 LteFfrEnhancedAlgorithm::EstimateUlSinr (uint16_t rnti, uint16_t rb, std::map <uint16_t, std::vector <double> > ulCqiMap)
763 {
764  std::map <uint16_t, std::vector <double> >::iterator itCqi = ulCqiMap.find (rnti);
765  if (itCqi == ulCqiMap.end ())
766  {
767  // no cqi info about this UE
768  return (NO_SINR);
769  }
770  else
771  {
772  // take the average SINR value among the available
773  double sinrSum = 0;
774  int sinrNum = 0;
775  for (uint32_t i = 0; i < m_ulBandwidth; i++)
776  {
777  double sinr = (*itCqi).second.at (i);
778  if (sinr != NO_SINR)
779  {
780  sinrSum += sinr;
781  sinrNum++;
782  }
783  }
784  double estimatedSinr = (sinrNum > 0) ? (sinrSum / sinrNum) : DBL_MAX;
785  // store the value
786  (*itCqi).second.at (rb) = estimatedSinr;
787  return (estimatedSinr);
788  }
789 }
790 
791 uint8_t
793 {
794  NS_LOG_FUNCTION (this);
795 
796  if (!m_enabledInUplink)
797  {
798  return 1; // 1 is mapped to 0 for Accumulated mode, and to -1 in Absolute mode TS36.213 Table 5.1.1.1-2
799  }
800 
801  //TS36.213 Table 5.1.1.1-2
802  // TPC | Accumulated Mode | Absolute Mode
803  //------------------------------------------------
804  // 0 | -1 | -4
805  // 1 | 0 | -1
806  // 2 | 1 | 1
807  // 3 | 3 | 4
808  //------------------------------------------------
809  // here Absolute mode is used
810 
811  std::map< uint16_t, uint8_t >::iterator it = m_ues.find (rnti);
812  if (it == m_ues.end ())
813  {
814  return 1;
815  }
816 
817  if (it->second == EdgeArea )
818  {
819  return m_edgeAreaTpc;
820  }
821  else
822  {
823  return m_centerAreaTpc;
824  }
825 
826  return 1;
827 }
828 
829 uint8_t
831 {
832  NS_LOG_FUNCTION (this);
833 
834  uint8_t minContinuousUlBandwidth = m_ulBandwidth;
835 
836  if (!m_enabledInUplink)
837  {
838  return minContinuousUlBandwidth;
839  }
840 
841  minContinuousUlBandwidth =
842  ((m_ulReuse3SubBandwidth > 0 ) && (m_ulReuse3SubBandwidth < minContinuousUlBandwidth)) ? m_ulReuse3SubBandwidth : minContinuousUlBandwidth;
843 
844  minContinuousUlBandwidth =
845  ((m_ulReuse1SubBandwidth > 0 ) && (m_ulReuse1SubBandwidth < minContinuousUlBandwidth)) ? m_ulReuse1SubBandwidth : minContinuousUlBandwidth;
846 
847  NS_LOG_INFO ("minContinuousUlBandwidth: " << (int)minContinuousUlBandwidth);
848 
849  return minContinuousUlBandwidth;
850 }
851 
852 
853 void
855  LteRrcSap::MeasResults measResults)
856 {
857  NS_LOG_FUNCTION (this << rnti << (uint16_t) measResults.measId);
858  NS_LOG_INFO ("RNTI :" << rnti << " MeasId: " << (uint16_t) measResults.measId
859  << " RSRP: " << (uint16_t)measResults.rsrpResult
860  << " RSRQ: " << (uint16_t)measResults.rsrqResult);
861 
862  if (measResults.measId != m_measId)
863  {
864  NS_LOG_WARN ("Ignoring measId " << (uint16_t) measResults.measId);
865  }
866  else
867  {
868  std::map< uint16_t, uint8_t >::iterator it = m_ues.find (rnti);
869  if (it == m_ues.end ())
870  {
871  m_ues.insert (std::pair< uint16_t, uint8_t > (rnti, AreaUnset));
872  }
873 
874  it = m_ues.find (rnti);
875  if (measResults.rsrqResult < m_rsrqThreshold)
876  {
877  if (it->second != EdgeArea)
878  {
879  NS_LOG_INFO ("UE RNTI: " << rnti << " will be served in Edge sub-band");
880  it->second = EdgeArea;
881 
882  LteRrcSap::PdschConfigDedicated pdschConfigDedicated;
883  pdschConfigDedicated.pa = m_edgeAreaPowerOffset;
884  m_ffrRrcSapUser->SetPdschConfigDedicated (rnti, pdschConfigDedicated);
885  }
886  }
887  else
888  {
889  if (it->second != CenterArea)
890  {
891  NS_LOG_INFO ("UE RNTI: " << rnti << " will be served in Center sub-band");
892  it->second = CenterArea;
893 
894  LteRrcSap::PdschConfigDedicated pdschConfigDedicated;
895  pdschConfigDedicated.pa = m_centerAreaPowerOffset;
896  m_ffrRrcSapUser->SetPdschConfigDedicated (rnti, pdschConfigDedicated);
897  }
898  }
899  }
900 }
901 void
903 {
904  NS_LOG_FUNCTION (this);
905  NS_LOG_WARN ("Method should not be called, because it is empty");
906 }
907 
908 } // end of namespace ns3
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.
virtual void DoInitialize(void)
Initialize() implementation.
Definition: object.cc:346
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 an Object subclass with the TypeId system.
Definition: object-base.h:44
enum ns3::LteRrcSap::ReportConfigEutra::@70 eventId
Choice of E-UTRA event triggered reporting criteria.
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:201
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:244
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()
Destructor implementation.
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
Reference Signal Received Quality.
Definition: lte-rrc-sap.h:363
Event A1: Serving becomes better than absolute threshold.
Definition: lte-rrc-sap.h:331
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:44
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()
Initialize() implementation.
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:252
std::vector< struct CqiListElement_s > m_cqiList
static const struct ns3::FfrEnhancedDownlinkDefaultConfiguration g_ffrEnhancedDownlinkDefaultConfiguration[]
virtual std::vector< bool > DoGetAvailableDlRbg()
Implementation of LteFfrSapProvider::GetAvailableDlRbg.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
The abstract base class of a Frequency Reuse algorithm.
uint8_t range
Value range used in RSRP/RSRQ threshold.
Definition: lte-rrc-sap.h:317
Enhanced Fractional Frequency Reuse algorithm implementation.
Service Access Point (SAP) offered by the eNodeB RRC instance to the Frequency Reuse algorithm instan...
virtual void DoRecvLoadInformation(EpcX2Sap::LoadInformationParams params)
DoRecvLoadInformation.
enum ns3::LteRrcSap::ReportConfigEutra::@72 triggerQuantity
The quantities used to evaluate the triggering condition for the event, see 3GPP TS 36...
#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:90
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:113
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:228
enum ns3::LteRrcSap::ThresholdEutra::@68 choice
std::map< uint16_t, uint8_t > m_ues
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
enum ns3::LteRrcSap::ReportConfigEutra::@74 reportInterval
Indicates the interval between periodical reports.
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:220
static const double SpectralEfficiencyForCqi[16]
Table of CQI index and its spectral efficiency.
Definition: lte-amc.cc:48
const uint16_t NUM_DOWNLINK_CONFS(sizeof(g_ffrEnhancedDownlinkDefaultConfiguration)/sizeof(FfrEnhancedDownlinkDefaultConfiguration))
RSRQ is used for the threshold.
Definition: lte-rrc-sap.h:315
#define NO_SINR
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
Definition: uinteger.h:45
a unique identifier for an interface.
Definition: type-id.h:58
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:826
const uint16_t NUM_UPLINK_CONFS(sizeof(g_ffrEnhancedUplinkDefaultConfiguration)/sizeof(FfrEnhancedUplinkDefaultConfiguration))
virtual void Reconfigure()
Automatic FR reconfiguration.
std::map< uint16_t, std::vector< bool > > m_ulRbAvailableforUe