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