A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
lte-ffr-enhanced-algorithm.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2014 Piotr Gawlowicz
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Piotr Gawlowicz <gawlowicz.p@gmail.com>
7 *
8 */
9
11
12#include "ff-mac-common.h"
13#include "lte-common.h"
14
15#include "ns3/boolean.h"
16#include <ns3/double.h>
17#include <ns3/log.h>
18
19#include <cfloat>
20
21namespace ns3
22{
23
24NS_LOG_COMPONENT_DEFINE("LteFfrEnhancedAlgorithm");
25
26NS_OBJECT_ENSURE_REGISTERED(LteFfrEnhancedAlgorithm);
27
28/// Spectral efficiency for CQI table
29static const double SpectralEfficiencyForCqi[16] = {
30 0.0, // out of range
31 0.15,
32 0.23,
33 0.38,
34 0.6,
35 0.88,
36 1.18,
37 1.48,
38 1.91,
39 2.41,
40 2.73,
41 3.32,
42 3.9,
43 4.52,
44 5.12,
45 5.55,
46};
47
48/// FfrEnhancedDownlinkDefaultConfiguration structure
50{
51 uint8_t cellId; ///< cell ID
52 uint8_t dlBandwidth; ///< DL bandwidth
53 uint8_t dlSubBandOffset; ///< DL subband offset
54 uint8_t dlReuse3SubBandwidth; ///< reuse 3 subbandwidth
55 uint8_t dlReuse1SubBandwidth; ///< reuse 1 subbandwidth
56};
57
58/// The enhanced downlink default configuration
60 {1, 25, 0, 4, 4},
61 {2, 25, 8, 4, 4},
62 {3, 25, 16, 4, 4},
63 {1, 50, 0, 9, 6},
64 {2, 50, 15, 9, 6},
65 {3, 50, 30, 9, 6},
66 {1, 75, 0, 8, 16},
67 {2, 75, 24, 8, 16},
68 {3, 75, 48, 8, 16},
69 {1, 100, 0, 16, 16},
70 {2, 100, 32, 16, 16},
71 {3, 100, 64, 16, 16},
72};
73
74/// FfrEnhancedUplinkDefaultConfiguration structure
76{
77 uint8_t cellId; ///< cell ID
78 uint8_t ulBandwidth; ///< UL bandwidth
79 uint8_t ulSubBandOffset; ///< UL subband offset
80 uint8_t ulReuse3SubBandwidth; ///< UL reuse 3 subbandwidth
81 uint8_t ulReuse1SubBandwidth; ///< UL reuse 1 subbandwidth
82};
83
84/// The enhanced uplink default configuration
86 {1, 25, 0, 4, 4},
87 {2, 25, 8, 4, 4},
88 {3, 25, 16, 4, 4},
89 {1, 50, 0, 9, 6},
90 {2, 50, 15, 9, 6},
91 {3, 50, 30, 9, 6},
92 {1, 75, 0, 8, 16},
93 {2, 75, 24, 8, 16},
94 {3, 75, 48, 8, 16},
95 {1, 100, 0, 16, 16},
96 {2, 100, 32, 16, 16},
97 {3, 100, 64, 16, 16},
98};
99
100/** \returns number of downlink configurations */
103/** \returns number of uplink configurations */
106
108 : m_ffrSapUser(nullptr),
109 m_ffrRrcSapUser(nullptr),
110 m_measId(0)
111{
112 NS_LOG_FUNCTION(this);
115}
116
121
122void
129
130TypeId
132{
133 static TypeId tid =
134 TypeId("ns3::LteFfrEnhancedAlgorithm")
136 .SetGroupName("Lte")
137 .AddConstructor<LteFfrEnhancedAlgorithm>()
138 .AddAttribute("UlSubBandOffset",
139 "Uplink SubBand Offset for this cell in number of Resource Block Groups",
140 UintegerValue(0),
143 .AddAttribute(
144 "UlReuse3SubBandwidth",
145 "Uplink Reuse 3 SubBandwidth Configuration in number of Resource Block Groups",
146 UintegerValue(4),
149 .AddAttribute(
150 "UlReuse1SubBandwidth",
151 "Uplink Reuse 1 SubBandwidth Configuration in number of Resource Block Groups",
152 UintegerValue(4),
155 .AddAttribute(
156 "DlSubBandOffset",
157 "Downlink SubBand Offset for this cell in number of Resource Block Groups",
158 UintegerValue(0),
161 .AddAttribute(
162 "DlReuse3SubBandwidth",
163 "Downlink Reuse 3 SubBandwidth Configuration in number of Resource Block Groups",
164 UintegerValue(4),
167 .AddAttribute(
168 "DlReuse1SubBandwidth",
169 "Downlink Reuse 1 SubBandwidth Configuration in number of Resource Block Groups",
170 UintegerValue(4),
173 .AddAttribute(
174 "RsrqThreshold",
175 "If the RSRQ of is worse than this threshold, UE should be served in Edge sub-band",
176 UintegerValue(26),
179 .AddAttribute("CenterAreaPowerOffset",
180 "PdschConfigDedicated::Pa value for Center Sub-band, default value dB0",
181 UintegerValue(5),
184 .AddAttribute("EdgeAreaPowerOffset",
185 "PdschConfigDedicated::Pa value for Edge Sub-band, default value dB0",
186 UintegerValue(5),
189 .AddAttribute("DlCqiThreshold",
190 "If the DL-CQI for RBG of is higher than this threshold, transmission on "
191 "RBG is possible",
192 UintegerValue(15),
195 .AddAttribute("UlCqiThreshold",
196 "If the UL-CQI for RBG of is higher than this threshold, transmission on "
197 "RBG is possible",
198 UintegerValue(15),
201 .AddAttribute("CenterAreaTpc",
202 "TPC value which will be set in DL-DCI for UEs in center area"
203 "Absolute mode is used, default value 1 is mapped to -1 according to"
204 "TS36.213 Table 5.1.1.1-2",
205 UintegerValue(1),
208 .AddAttribute("EdgeAreaTpc",
209 "TPC value which will be set in DL-DCI for UEs in edge area"
210 "Absolute mode is used, default value 1 is mapped to -1 according to"
211 "TS36.213 Table 5.1.1.1-2",
212 UintegerValue(1),
215 return tid;
216}
217
218void
224
231
232void
238
245
246void
248{
249 NS_LOG_FUNCTION(this);
251
252 NS_ASSERT_MSG(m_dlBandwidth > 24, "DlBandwidth must be at least 25 to use EFFR algorithm");
253 NS_ASSERT_MSG(m_ulBandwidth > 24, "UlBandwidth must be at least 25 to use EFFR algorithm");
254
255 if (m_frCellTypeId != 0)
256 {
259 }
260
261 NS_LOG_LOGIC(this << " requesting Event A1 measurements"
262 << " (threshold = 0"
263 << ")");
264 LteRrcSap::ReportConfigEutra reportConfig;
267 reportConfig.threshold1.range = 0;
271}
272
273void
286
287void
304
305void
322
323int
325{
327 NS_ASSERT_MSG(s >= 0.0, "negative spectral efficiency = " << s);
328 int cqi = 0;
329 while ((cqi < 15) && (SpectralEfficiencyForCqi[cqi + 1] < s))
330 {
331 ++cqi;
332 }
333 NS_LOG_LOGIC("cqi = " << cqi);
334 return cqi;
335}
336
337void
339{
340 m_dlRbgMap.clear();
341 m_dlReuse3RbgMap.clear();
342 m_dlReuse1RbgMap.clear();
345
346 int rbgSize = GetRbgSize(m_dlBandwidth);
347 m_dlRbgMap.resize(m_dlBandwidth / rbgSize, true);
348
349 m_dlReuse3RbgMap.resize(m_dlBandwidth / rbgSize, false);
350 m_dlReuse1RbgMap.resize(m_dlBandwidth / rbgSize, false);
351 m_dlPrimarySegmentRbgMap.resize(m_dlBandwidth / rbgSize, false);
352 m_dlSecondarySegmentRbgMap.resize(m_dlBandwidth / rbgSize, true);
353
354 NS_ASSERT_MSG(m_dlSubBandOffset <= m_dlBandwidth, "DlSubBandOffset higher than DlBandwidth");
357 "DlSubBandOffset + DlReuse3SubBandwidth + DlReuse1SubBandwidth higher than DlBandwidth");
358
359 for (int i = 0; i < m_dlReuse3SubBandwidth / rbgSize; i++)
360 {
361 int offset = m_dlSubBandOffset / rbgSize;
362 uint8_t index = offset + i;
363 m_dlReuse3RbgMap[index] = true;
364 m_dlPrimarySegmentRbgMap[index] = true;
365 m_dlRbgMap[index] = false;
366 }
367
368 for (int i = 0; i < m_dlReuse1SubBandwidth / rbgSize; i++)
369 {
370 int offset = (m_dlSubBandOffset + m_dlReuse3SubBandwidth) / rbgSize;
371 uint8_t index = offset + i;
372 m_dlReuse1RbgMap[index] = true;
373 m_dlPrimarySegmentRbgMap[index] = true;
374 m_dlSecondarySegmentRbgMap[index] = false;
375 m_dlRbgMap[index] = false;
376 }
377
378 for (int i = 0; i < m_dlReuse3SubBandwidth / rbgSize; i++)
379 {
380 uint8_t offset = (m_dlReuse3SubBandwidth + m_dlReuse1SubBandwidth) / rbgSize;
381
382 uint8_t index = 0 * offset + i;
383 m_dlSecondarySegmentRbgMap[index] = false;
384
385 index = 1 * offset + i;
386 m_dlSecondarySegmentRbgMap[index] = false;
387
388 index = 2 * offset + i;
389 m_dlSecondarySegmentRbgMap[index] = false;
390 }
391}
392
393void
395{
396 m_ulRbgMap.clear();
397 m_ulReuse3RbgMap.clear();
398 m_ulReuse1RbgMap.clear();
401
403 {
404 m_ulRbgMap.resize(m_ulBandwidth, false);
405 return;
406 }
407
408 m_ulRbgMap.resize(m_ulBandwidth, true);
409 m_ulReuse3RbgMap.resize(m_ulBandwidth, false);
410 m_ulReuse1RbgMap.resize(m_ulBandwidth, false);
413
414 NS_ASSERT_MSG(m_ulSubBandOffset <= m_ulBandwidth, "UlSubBandOffset higher than UlBandwidth");
417 "UlSubBandOffset + UlReuse3SubBandwidth + UlReuse1SubBandwidth higher than UlBandwidth");
418
419 for (uint8_t i = 0; i < m_ulReuse3SubBandwidth; i++)
420 {
421 int offset = m_ulSubBandOffset;
422 uint8_t index = offset + i;
423 m_ulReuse3RbgMap[index] = true;
424 m_ulPrimarySegmentRbgMap[index] = true;
425 m_ulRbgMap[index] = false;
426 }
427
428 for (uint8_t i = 0; i < m_ulReuse1SubBandwidth; i++)
429 {
431 uint8_t index = offset + i;
432 m_ulReuse1RbgMap[index] = true;
433 m_ulPrimarySegmentRbgMap[index] = true;
434 m_ulSecondarySegmentRbgMap[index] = false;
435 m_ulRbgMap[index] = false;
436 }
437
438 for (uint8_t i = 0; i < m_ulReuse3SubBandwidth; i++)
439 {
441
442 uint8_t index = 0 * offset + i;
443 m_ulSecondarySegmentRbgMap[index] = false;
444
445 index = 1 * offset + i;
446 m_ulSecondarySegmentRbgMap[index] = false;
447
448 index = 2 * offset + i;
449 m_ulSecondarySegmentRbgMap[index] = false;
450 }
451}
452
453std::vector<bool>
455{
456 NS_LOG_FUNCTION(this);
457
459 {
460 Reconfigure();
461 }
462
463 if (m_dlRbgMap.empty())
464 {
466 }
467
468 std::vector<bool> rbgMap = m_dlRbgMap;
469
470 for (auto it = m_dlRbgAvailableforUe.begin(); it != m_dlRbgAvailableforUe.end(); it++)
471 {
472 NS_LOG_INFO("RNTI : " << it->first);
473 std::vector<bool> rbgAvailableMap = it->second;
474 for (uint32_t i = 0; i < rbgMap.size(); i++)
475 {
476 NS_LOG_INFO("\t rbgId: " << i << " available " << (int)rbgAvailableMap.at(i));
477 if (rbgAvailableMap.at(i))
478 {
479 rbgMap.at(i) = false;
480 }
481 }
482 }
483
484 return rbgMap;
485}
486
487bool
489{
490 NS_LOG_FUNCTION(this);
491
492 bool isReuse3Rbg = m_dlReuse3RbgMap[rbgId];
493 bool isReuse1Rbg = m_dlReuse1RbgMap[rbgId];
494 bool isPrimarySegmentRbg = m_dlPrimarySegmentRbgMap[rbgId];
495 bool isSecondarySegmentRbg = m_dlSecondarySegmentRbgMap[rbgId];
496
497 auto it = m_ues.find(rnti);
498 if (it == m_ues.end())
499 {
500 m_ues.insert(std::pair<uint16_t, uint8_t>(rnti, AreaUnset));
501 }
502
503 it = m_ues.find(rnti);
504
505 // if UE area is unknown, serve UE in edge area RBGs
506 if (it->second == AreaUnset)
507 {
508 return isReuse3Rbg;
509 }
510
511 bool isCenterUe = false;
512 bool isEdgeUe = false;
513
514 if (it->second == CenterArea)
515 {
516 isCenterUe = true;
517 }
518 else if (it->second == EdgeArea)
519 {
520 isEdgeUe = true;
521 }
522
523 if (isPrimarySegmentRbg)
524 {
525 NS_LOG_INFO("PRIMARY SEGMENT RNTI: " << rnti << " rbgId: " << rbgId);
526 return (isReuse1Rbg && isCenterUe) || (isReuse3Rbg && isEdgeUe);
527 }
528 else if (isSecondarySegmentRbg && isCenterUe)
529 {
530 // check if RB can be used by UE based on CQI information
531 NS_LOG_INFO("SECONDARY SEGMENT RNTI: " << rnti << " rbgId: " << rbgId);
532 auto it = m_dlRbgAvailableforUe.find(rnti);
533 if (it != m_dlRbgAvailableforUe.end())
534 {
535 NS_LOG_INFO("RNTI: " << rnti << " rbgId: " << rbgId
536 << " available: " << it->second.at(rbgId));
537 if (it->second.at(rbgId))
538 {
539 return true;
540 }
541 }
542 return false;
543 }
544
545 return false;
546}
547
548std::vector<bool>
550{
551 NS_LOG_FUNCTION(this);
552
553 if (m_ulRbgMap.empty())
554 {
556 }
557
559 {
560 return m_ulRbgMap;
561 }
562
563 std::vector<bool> rbgMap = m_ulRbgMap;
564
565 for (auto it = m_ulRbAvailableforUe.begin(); it != m_ulRbAvailableforUe.end(); it++)
566 {
567 NS_LOG_INFO("RNTI : " << it->first);
568 std::vector<bool> rbAvailableMap = it->second;
569 for (uint32_t i = 0; i < rbgMap.size(); i++)
570 {
571 NS_LOG_INFO("\t rbgId: " << i << " available " << (int)rbAvailableMap.at(i));
572 if (rbAvailableMap.at(i))
573 {
574 rbgMap.at(i) = false;
575 }
576 }
577 }
578
579 return rbgMap;
580}
581
582bool
584{
585 NS_LOG_FUNCTION(this);
586
588 {
589 return true;
590 }
591
592 bool isReuse3Rbg = m_ulReuse3RbgMap[rbgId];
593 bool isReuse1Rbg = m_ulReuse1RbgMap[rbgId];
594 bool isPrimarySegmentRbg = m_ulPrimarySegmentRbgMap[rbgId];
595 bool isSecondarySegmentRbg = m_ulSecondarySegmentRbgMap[rbgId];
596
597 auto it = m_ues.find(rnti);
598 if (it == m_ues.end())
599 {
600 m_ues.insert(std::pair<uint16_t, uint8_t>(rnti, AreaUnset));
601 }
602
603 it = m_ues.find(rnti);
604
605 // if UE area is unknown, serve UE in edge area RBGs
606 if (it->second == AreaUnset)
607 {
608 return isReuse3Rbg;
609 }
610
611 bool isCenterUe = false;
612 bool isEdgeUe = false;
613
614 if (it->second == CenterArea)
615 {
616 isCenterUe = true;
617 }
618 else if (it->second == EdgeArea)
619 {
620 isEdgeUe = true;
621 }
622
623 if (isPrimarySegmentRbg)
624 {
625 return (isReuse1Rbg && isCenterUe) || (isReuse3Rbg && isEdgeUe);
626 }
627 else if (isSecondarySegmentRbg && isCenterUe)
628 {
629 // check if RB can be used by UE based on CQI information
630 NS_LOG_INFO("UL SECONDARY SEGMENT RNTI: " << rnti << " rbgId: " << rbgId);
631 auto it = m_ulRbAvailableforUe.find(rnti);
632 if (it != m_ulRbAvailableforUe.end())
633 {
634 NS_LOG_INFO("RNTI: " << rnti << " rbgId: " << rbgId
635 << " available: " << it->second.at(rbgId));
636 if (it->second.at(rbgId))
637 {
638 return true;
639 }
640 }
641 return false;
642 }
643
644 return false;
645}
646
647void
650{
651 NS_LOG_FUNCTION(this);
652
653 m_dlCqi.clear();
654 for (unsigned int i = 0; i < params.m_cqiList.size(); i++)
655 {
656 if (params.m_cqiList.at(i).m_cqiType == CqiListElement_s::A30)
657 {
658 NS_LOG_INFO("subband CQI reporting high layer configured");
659 // subband CQI reporting high layer configured
660 uint16_t rnti = params.m_cqiList.at(i).m_rnti;
661
662 auto ueIt = m_ues.find(rnti);
663 if (ueIt != m_ues.end())
664 {
665 if (ueIt->second != CenterArea)
666 {
667 continue;
668 }
669 }
670 else
671 {
672 continue;
673 }
674
675 auto it = m_dlCqi.find(rnti);
676 if (it == m_dlCqi.end())
677 {
678 // create the new entry
679 m_dlCqi.insert(
680 std::pair<uint16_t, SbMeasResult_s>(rnti,
681 params.m_cqiList.at(i).m_sbMeasResult));
682 }
683 else
684 {
685 // update the CQI value and refresh correspondent timer
686 (*it).second = params.m_cqiList.at(i).m_sbMeasResult;
687 }
688 }
689 else
690 {
691 NS_LOG_ERROR(this << " CQI type unknown");
692 }
693 }
694
696 m_dlRbgAvailableforUe.clear();
697 for (auto it = m_dlCqi.begin(); it != m_dlCqi.end(); it++)
698 {
699 uint16_t rnti = it->first;
700 std::vector<bool> rbgAvailableMap;
701
702 for (uint32_t i = 0; i < (*it).second.m_higherLayerSelected.size(); i++)
703 {
704 uint8_t rbgCqi = (*it).second.m_higherLayerSelected.at(i).m_sbCqi.at(0);
705
706 if (i > m_dlBandwidth / rbgSize)
707 {
708 continue;
709 }
710 NS_LOG_INFO(this << " RNTI " << rnti << " RBG " << i << " DL-CQI: " << (int)rbgCqi);
711
712 bool rbgAvailable = (rbgCqi > m_dlCqiThreshold);
713
714 bool isSecondarySegmentRbg = false;
715 if (i < m_dlSecondarySegmentRbgMap.size())
716 {
717 isSecondarySegmentRbg = m_dlSecondarySegmentRbgMap[i];
718 }
719
720 rbgAvailable = (isSecondarySegmentRbg ? rbgAvailable : false);
721
722 rbgAvailableMap.push_back(rbgAvailable);
723 }
724
725 m_dlRbgAvailableforUe.insert(std::pair<uint16_t, std::vector<bool>>(rnti, rbgAvailableMap));
726 }
727
728 m_ulRbAvailableforUe.clear();
729 for (auto it = m_dlRbgAvailableforUe.begin(); it != m_dlRbgAvailableforUe.end(); it++)
730 {
731 uint16_t rnti = it->first;
732 std::vector<bool> dlRbgAvailableMap = it->second;
733 std::vector<bool> ulRbAvailableMap;
734 ulRbAvailableMap.resize(m_ulBandwidth, false);
735
736 for (uint32_t j = 0; j < dlRbgAvailableMap.size(); j++)
737 {
738 uint32_t index = rbgSize * j;
739 for (uint32_t i = 0; i < rbgSize; i++)
740 {
741 index = index + i;
742 ulRbAvailableMap[index] = dlRbgAvailableMap[j];
743 }
744 }
745
746 m_ulRbAvailableforUe.insert(std::pair<uint16_t, std::vector<bool>>(rnti, ulRbAvailableMap));
747 }
748}
749
750void
753{
754 NS_LOG_FUNCTION(this);
755 if (params.m_ulCqi.m_type == UlCqi_s::SRS)
756 {
757 // get the RNTI from vendor specific parameters
758 uint16_t rnti = 0;
759 for (uint32_t j = 0; j < m_ulBandwidth; j++)
760 {
761 double sinr = LteFfConverter::fpS11dot3toDouble(params.m_ulCqi.m_sinr.at(j));
762 double s = log2(1 + (std::pow(10, sinr / 10) / ((-std::log(5.0 * 0.00005)) / 1.5)));
763 int cqi = GetCqiFromSpectralEfficiency(s);
764 NS_LOG_INFO(this << " RNTI " << rnti << " new SRS-CQI for RB " << j << " value "
765 << sinr << " UL-CQI: " << cqi);
766 }
767 }
768}
769
770void
771LteFfrEnhancedAlgorithm::DoReportUlCqiInfo(std::map<uint16_t, std::vector<double>> ulCqiMap)
772{
773 NS_LOG_FUNCTION(this);
774 NS_LOG_WARN("Method should not be called, because it is empty");
775}
776
777double
779 uint16_t rb,
780 std::map<uint16_t, std::vector<double>> ulCqiMap)
781{
782 auto itCqi = ulCqiMap.find(rnti);
783 if (itCqi == ulCqiMap.end())
784 {
785 // no cqi info about this UE
786 return NO_SINR;
787 }
788 else
789 {
790 // take the average SINR value among the available
791 double sinrSum = 0;
792 unsigned int sinrNum = 0;
793 for (uint32_t i = 0; i < m_ulBandwidth; i++)
794 {
795 double sinr = (*itCqi).second.at(i);
796 if (sinr != NO_SINR)
797 {
798 sinrSum += sinr;
799 sinrNum++;
800 }
801 }
802 double estimatedSinr = (sinrNum > 0) ? (sinrSum / sinrNum) : DBL_MAX;
803 // store the value
804 (*itCqi).second.at(rb) = estimatedSinr;
805 return estimatedSinr;
806 }
807}
808
809uint8_t
811{
812 NS_LOG_FUNCTION(this);
813
815 {
816 return 1; // 1 is mapped to 0 for Accumulated mode, and to -1 in Absolute mode TS36.213
817 // Table 5.1.1.1-2
818 }
819
820 // TS36.213 Table 5.1.1.1-2
821 // TPC | Accumulated Mode | Absolute Mode
822 //------------------------------------------------
823 // 0 | -1 | -4
824 // 1 | 0 | -1
825 // 2 | 1 | 1
826 // 3 | 3 | 4
827 //------------------------------------------------
828 // here Absolute mode is used
829
830 auto it = m_ues.find(rnti);
831 if (it == m_ues.end())
832 {
833 return 1;
834 }
835
836 if (it->second == EdgeArea)
837 {
838 return m_edgeAreaTpc;
839 }
840 else
841 {
842 return m_centerAreaTpc;
843 }
844
845 return 1;
846}
847
848uint16_t
850{
851 NS_LOG_FUNCTION(this);
852
853 uint8_t minContinuousUlBandwidth = m_ulBandwidth;
854
856 {
857 return minContinuousUlBandwidth;
858 }
859
860 minContinuousUlBandwidth =
861 ((m_ulReuse3SubBandwidth > 0) && (m_ulReuse3SubBandwidth < minContinuousUlBandwidth))
863 : minContinuousUlBandwidth;
864
865 minContinuousUlBandwidth =
866 ((m_ulReuse1SubBandwidth > 0) && (m_ulReuse1SubBandwidth < minContinuousUlBandwidth))
868 : minContinuousUlBandwidth;
869
870 NS_LOG_INFO("minContinuousUlBandwidth: " << (int)minContinuousUlBandwidth);
871
872 return minContinuousUlBandwidth;
873}
874
875void
877{
878 NS_LOG_FUNCTION(this << rnti << (uint16_t)measResults.measId);
879 NS_LOG_INFO("RNTI :" << rnti << " MeasId: " << (uint16_t)measResults.measId
880 << " RSRP: " << (uint16_t)measResults.measResultPCell.rsrpResult
881 << " RSRQ: " << (uint16_t)measResults.measResultPCell.rsrqResult);
882
883 if (measResults.measId != m_measId)
884 {
885 NS_LOG_WARN("Ignoring measId " << (uint16_t)measResults.measId);
886 }
887 else
888 {
889 auto it = m_ues.find(rnti);
890 if (it == m_ues.end())
891 {
892 m_ues.insert(std::pair<uint16_t, uint8_t>(rnti, AreaUnset));
893 }
894
895 it = m_ues.find(rnti);
897 {
898 if (it->second != EdgeArea)
899 {
900 NS_LOG_INFO("UE RNTI: " << rnti << " will be served in Edge sub-band");
901 it->second = EdgeArea;
902
903 LteRrcSap::PdschConfigDedicated pdschConfigDedicated;
904 pdschConfigDedicated.pa = m_edgeAreaPowerOffset;
905 m_ffrRrcSapUser->SetPdschConfigDedicated(rnti, pdschConfigDedicated);
906 }
907 }
908 else
909 {
910 if (it->second != CenterArea)
911 {
912 NS_LOG_INFO("UE RNTI: " << rnti << " will be served in Center sub-band");
913 it->second = CenterArea;
914
915 LteRrcSap::PdschConfigDedicated pdschConfigDedicated;
916 pdschConfigDedicated.pa = m_centerAreaPowerOffset;
917 m_ffrRrcSapUser->SetPdschConfigDedicated(rnti, pdschConfigDedicated);
918 }
919 }
920 }
921}
922
923void
925{
926 NS_LOG_FUNCTION(this);
927 NS_LOG_WARN("Method should not be called, because it is empty");
928}
929
930} // end of namespace ns3
static double fpS11dot3toDouble(uint16_t val)
Convert from fixed point S11.3 notation to double.
The abstract base class of a Frequency Reuse algorithm.
bool m_needReconfiguration
If true FR algorithm will be reconfigured.
uint8_t m_frCellTypeId
FFR cell type ID for automatic configuration.
int GetRbgSize(int dlbandwidth)
Get RBG size for DL Bandwidth according to table 7.1.6.1-1 of 36.213.
bool m_enabledInUplink
If true FR algorithm will also work in Uplink.
uint8_t m_dlBandwidth
downlink bandwidth in RBs
uint8_t m_ulBandwidth
uplink bandwidth in RBs
Enhanced Fractional Frequency Reuse algorithm implementation.
uint8_t m_ulSubBandOffset
UL subband offset.
void DoDispose() override
Destructor implementation.
void DoInitialize() override
Initialize() implementation.
void SetLteFfrSapUser(LteFfrSapUser *s) override
Set the "user" part of the LteFfrSap interface that this frequency reuse algorithm instance will inte...
uint8_t m_measId
The expected measurement identity.
LteFfrSapProvider * m_ffrSapProvider
FFR SAP provider.
void SetDownlinkConfiguration(uint16_t cellId, uint8_t bandwidth)
Set downlink configuration.
void InitializeDownlinkRbgMaps()
Initialize downlink RBG maps.
friend class MemberLteFfrSapProvider< LteFfrEnhancedAlgorithm >
let the forwarder class access the protected and private members
std::vector< bool > m_dlRbgMap
DL RBG map.
double EstimateUlSinr(uint16_t rnti, uint16_t rb, std::map< uint16_t, std::vector< double > > ulCqiMap)
Initialize uplink RBG maps.
static TypeId GetTypeId()
Get the type ID.
uint8_t m_dlSubBandOffset
DL subband offset.
uint8_t m_ulCqiThreshold
UL CQI threshold.
std::map< uint16_t, std::vector< bool > > m_dlRbgAvailableforUe
DL RBG available for UE.
void Reconfigure() override
Automatic FR reconfiguration.
std::vector< bool > m_dlSecondarySegmentRbgMap
DL secondary segment RBG map.
uint8_t m_centerAreaPowerOffset
Center area power offset.
uint8_t m_dlCqiThreshold
DL CQI threshold.
std::vector< bool > m_ulReuse1RbgMap
UL reuse 1 RBG map.
bool DoIsUlRbgAvailableForUe(int i, uint16_t rnti) override
Implementation of LteFfrSapProvider::IsUlRbgAvailableForUe.
std::vector< bool > m_dlPrimarySegmentRbgMap
DL primary segment RBG map.
std::vector< bool > DoGetAvailableUlRbg() override
Implementation of LteFfrSapProvider::GetAvailableUlRbg.
LteFfrRrcSapProvider * GetLteFfrRrcSapProvider() override
Export the "provider" part of the LteFfrRrcSap interface.
std::vector< bool > m_ulPrimarySegmentRbgMap
UL primary segment RBG map.
LteFfrSapProvider * GetLteFfrSapProvider() override
Export the "provider" part of the LteFfrSap interface.
uint8_t m_dlReuse1SubBandwidth
DL reuse 1 subband bandwidth.
LteFfrRrcSapUser * m_ffrRrcSapUser
FFR RRC SAP user.
std::vector< bool > m_dlReuse3RbgMap
DL reuse 3 RBG map.
friend class MemberLteFfrRrcSapProvider< LteFfrEnhancedAlgorithm >
let the forwarder class access the protected and private members
uint8_t DoGetTpc(uint16_t rnti) override
DoGetTpc for UE.
int GetCqiFromSpectralEfficiency(double s)
Get CQI from spectral efficiency.
std::vector< bool > m_ulReuse3RbgMap
UL reuse 3 RBG map.
std::map< uint16_t, SbMeasResult_s > m_dlCqi
Map of UE's DL CQI A30 received.
void SetUplinkConfiguration(uint16_t cellId, uint8_t bandwidth)
Set uplink configuration.
uint8_t m_ulReuse1SubBandwidth
UL reuse 1 subbandwidth.
LteFfrSapUser * m_ffrSapUser
FFR SAP user.
uint16_t DoGetMinContinuousUlBandwidth() override
DoGetMinContinuousUlBandwidth in number of RB.
LteFfrEnhancedAlgorithm()
Creates a trivial ffr algorithm instance.
std::map< uint16_t, uint8_t > m_ues
UEs.
void DoRecvLoadInformation(EpcX2Sap::LoadInformationParams params) override
DoRecvLoadInformation.
void DoReportUlCqiInfo(const FfMacSchedSapProvider::SchedUlCqiInfoReqParameters &params) override
DoReportUlCqiInfo.
std::map< uint16_t, std::vector< bool > > m_ulRbAvailableforUe
UL RB available for UE.
std::vector< bool > m_ulRbgMap
UL RBG Map.
LteFfrRrcSapProvider * m_ffrRrcSapProvider
FFR RRC SAP provider.
std::vector< bool > m_dlReuse1RbgMap
DL reuse 1 RBG map.
void InitializeUplinkRbgMaps()
Initialize uplink RBG maps.
void SetLteFfrRrcSapUser(LteFfrRrcSapUser *s) override
Set the "user" part of the LteFfrRrcSap interface that this frequency reuse algorithm instance will i...
void DoReportDlCqiInfo(const FfMacSchedSapProvider::SchedDlCqiInfoReqParameters &params) override
DoReportDlCqiInfo.
uint8_t m_ulReuse3SubBandwidth
UL reuse 3 subbandwidth.
std::vector< bool > m_ulSecondarySegmentRbgMap
UL secondary segment RBG map.
uint8_t m_edgeAreaPowerOffset
Edge area power offset.
bool DoIsDlRbgAvailableForUe(int i, uint16_t rnti) override
Implementation of LteFfrSapProvider::IsDlRbgAvailableForUe.
uint8_t m_dlReuse3SubBandwidth
DL reuse 3 subband bandwidth.
void DoReportUeMeas(uint16_t rnti, LteRrcSap::MeasResults measResults) override
Implementation of LteFfrRrcSapProvider::ReportUeMeas.
std::vector< bool > DoGetAvailableDlRbg() override
Implementation of LteFfrSapProvider::GetAvailableDlRbg.
Service Access Point (SAP) offered by the Frequency Reuse algorithm instance to the eNodeB RRC instan...
Service Access Point (SAP) offered by the eNodeB RRC instance to the Frequency Reuse algorithm instan...
virtual void SetPdschConfigDedicated(uint16_t rnti, LteRrcSap::PdschConfigDedicated pdschConfigDedicated)=0
Instruct the eNodeB RRC entity to perform RrcConnectionReconfiguration to inform UE about new PdschCo...
virtual uint8_t AddUeMeasReportConfigForFfr(LteRrcSap::ReportConfigEutra reportConfig)=0
Request a certain reporting configuration to be fulfilled by the UEs attached to the eNodeB entity.
Service Access Point (SAP) offered by the Frequency Reuse algorithm instance to the MAC Scheduler ins...
Definition lte-ffr-sap.h:29
Service Access Point (SAP) offered by the eNodeB RRC instance to the Frequency Reuse algorithm instan...
virtual void DoInitialize()
Initialize() implementation.
Definition object.cc:440
a unique identifier for an interface.
Definition type-id.h:48
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition type-id.cc:1001
Hold an unsigned integer type.
Definition uinteger.h:34
#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:75
#define NS_LOG_ERROR(msg)
Use NS_LOG to output a message of level LOG_ERROR.
Definition log.h:243
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition log.h:271
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition log.h:250
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition log.h:264
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition object-base.h:35
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Ptr< const AttributeChecker > MakeUintegerChecker()
Definition uinteger.h:85
constexpr double NO_SINR
Value for SINR outside the range defined by FF-API, used to indicate that there is no CQI for this el...
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Definition uinteger.h:35
const uint16_t NUM_DOWNLINK_CONFS(sizeof(g_ffrEnhancedDownlinkDefaultConfiguration)/sizeof(FfrEnhancedDownlinkDefaultConfiguration))
const uint16_t NUM_UPLINK_CONFS(sizeof(g_ffrEnhancedUplinkDefaultConfiguration)/sizeof(FfrEnhancedUplinkDefaultConfiguration))
static const double SpectralEfficiencyForCqi[16]
Table of CQI index and its spectral efficiency.
Definition lte-amc.cc:38
static const FfrEnhancedDownlinkDefaultConfiguration g_ffrEnhancedDownlinkDefaultConfiguration[]
The enhanced downlink default configuration.
static const FfrEnhancedUplinkDefaultConfiguration g_ffrEnhancedUplinkDefaultConfiguration[]
The enhanced uplink default configuration.
Parameters of the LOAD INFORMATION message.
Definition epc-x2-sap.h:295
Parameters of the SCHED_DL_CQI_INFO_REQ primitive.
Parameters of the SCHED_UL_CQI_INFO_REQ primitive.
uint8_t rsrqResult
the RSRQ result
uint8_t rsrpResult
the RSRP result
MeasResults structure.
uint8_t measId
measure ID
MeasResultPCell measResultPCell
measurement result primary cell
PdschConfigDedicated structure.
Specifies criteria for triggering of an E-UTRA measurement reporting event.
enum ns3::LteRrcSap::ReportConfigEutra::@62 eventId
Event enumeration.
@ RSRQ
Reference Signal Received Quality.
@ EVENT_A1
Event A1: Serving becomes better than absolute threshold.
enum ns3::LteRrcSap::ReportConfigEutra::@65 reportInterval
Report interval enumeration.
enum ns3::LteRrcSap::ReportConfigEutra::@63 triggerQuantity
Trigger type enumeration.
ThresholdEutra threshold1
Threshold for event A1, A2, A4, and A5.
@ THRESHOLD_RSRQ
RSRQ is used for the threshold.
enum ns3::LteRrcSap::ThresholdEutra::@60 choice
Threshold enumeration.
uint8_t range
Value range used in RSRP/RSRQ threshold.