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 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation;
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 *
17 * Author: Piotr Gawlowicz <gawlowicz.p@gmail.com>
18 *
19 */
20
22
23#include "ff-mac-common.h"
24#include "lte-common.h"
25
26#include "ns3/boolean.h"
27#include <ns3/double.h>
28#include <ns3/log.h>
29
30#include <cfloat>
31
32namespace ns3
33{
34
35NS_LOG_COMPONENT_DEFINE("LteFfrEnhancedAlgorithm");
36
37NS_OBJECT_ENSURE_REGISTERED(LteFfrEnhancedAlgorithm);
38
40static const double SpectralEfficiencyForCqi[16] = {
41 0.0, // out of range
42 0.15,
43 0.23,
44 0.38,
45 0.6,
46 0.88,
47 1.18,
48 1.48,
49 1.91,
50 2.41,
51 2.73,
52 3.32,
53 3.9,
54 4.52,
55 5.12,
56 5.55,
57};
58
61{
62 uint8_t cellId;
63 uint8_t dlBandwidth;
67};
68
71 {1, 25, 0, 4, 4},
72 {2, 25, 8, 4, 4},
73 {3, 25, 16, 4, 4},
74 {1, 50, 0, 9, 6},
75 {2, 50, 15, 9, 6},
76 {3, 50, 30, 9, 6},
77 {1, 75, 0, 8, 16},
78 {2, 75, 24, 8, 16},
79 {3, 75, 48, 8, 16},
80 {1, 100, 0, 16, 16},
81 {2, 100, 32, 16, 16},
82 {3, 100, 64, 16, 16},
83};
84
87{
88 uint8_t cellId;
89 uint8_t ulBandwidth;
93};
94
97 {1, 25, 0, 4, 4},
98 {2, 25, 8, 4, 4},
99 {3, 25, 16, 4, 4},
100 {1, 50, 0, 9, 6},
101 {2, 50, 15, 9, 6},
102 {3, 50, 30, 9, 6},
103 {1, 75, 0, 8, 16},
104 {2, 75, 24, 8, 16},
105 {3, 75, 48, 8, 16},
106 {1, 100, 0, 16, 16},
107 {2, 100, 32, 16, 16},
108 {3, 100, 64, 16, 16},
109};
110
117
119 : m_ffrSapUser(nullptr),
120 m_ffrRrcSapUser(nullptr),
121 m_measId(0)
122{
123 NS_LOG_FUNCTION(this);
126}
127
129{
130 NS_LOG_FUNCTION(this);
131}
132
133void
135{
136 NS_LOG_FUNCTION(this);
137 delete m_ffrSapProvider;
138 delete m_ffrRrcSapProvider;
139}
140
141TypeId
143{
144 static TypeId tid =
145 TypeId("ns3::LteFfrEnhancedAlgorithm")
147 .SetGroupName("Lte")
148 .AddConstructor<LteFfrEnhancedAlgorithm>()
149 .AddAttribute("UlSubBandOffset",
150 "Uplink SubBand Offset for this cell in number of Resource Block Groups",
151 UintegerValue(0),
153 MakeUintegerChecker<uint8_t>())
154 .AddAttribute(
155 "UlReuse3SubBandwidth",
156 "Uplink Reuse 3 SubBandwidth Configuration in number of Resource Block Groups",
157 UintegerValue(4),
159 MakeUintegerChecker<uint8_t>())
160 .AddAttribute(
161 "UlReuse1SubBandwidth",
162 "Uplink Reuse 1 SubBandwidth Configuration in number of Resource Block Groups",
163 UintegerValue(4),
165 MakeUintegerChecker<uint8_t>())
166 .AddAttribute(
167 "DlSubBandOffset",
168 "Downlink SubBand Offset for this cell in number of Resource Block Groups",
169 UintegerValue(0),
171 MakeUintegerChecker<uint8_t>())
172 .AddAttribute(
173 "DlReuse3SubBandwidth",
174 "Downlink Reuse 3 SubBandwidth Configuration in number of Resource Block Groups",
175 UintegerValue(4),
177 MakeUintegerChecker<uint8_t>())
178 .AddAttribute(
179 "DlReuse1SubBandwidth",
180 "Downlink Reuse 1 SubBandwidth Configuration in number of Resource Block Groups",
181 UintegerValue(4),
183 MakeUintegerChecker<uint8_t>())
184 .AddAttribute(
185 "RsrqThreshold",
186 "If the RSRQ of is worse than this threshold, UE should be served in Edge sub-band",
187 UintegerValue(26),
189 MakeUintegerChecker<uint8_t>())
190 .AddAttribute("CenterAreaPowerOffset",
191 "PdschConfigDedicated::Pa value for Center Sub-band, default value dB0",
192 UintegerValue(5),
194 MakeUintegerChecker<uint8_t>())
195 .AddAttribute("EdgeAreaPowerOffset",
196 "PdschConfigDedicated::Pa value for Edge Sub-band, default value dB0",
197 UintegerValue(5),
199 MakeUintegerChecker<uint8_t>())
200 .AddAttribute("DlCqiThreshold",
201 "If the DL-CQI for RBG of is higher than this threshold, transmission on "
202 "RBG is possible",
203 UintegerValue(15),
205 MakeUintegerChecker<uint8_t>())
206 .AddAttribute("UlCqiThreshold",
207 "If the UL-CQI for RBG of is higher than this threshold, transmission on "
208 "RBG is possible",
209 UintegerValue(15),
211 MakeUintegerChecker<uint8_t>())
212 .AddAttribute("CenterAreaTpc",
213 "TPC value which will be set in DL-DCI for UEs in center area"
214 "Absolute mode is used, default value 1 is mapped to -1 according to"
215 "TS36.213 Table 5.1.1.1-2",
216 UintegerValue(1),
218 MakeUintegerChecker<uint8_t>())
219 .AddAttribute("EdgeAreaTpc",
220 "TPC value which will be set in DL-DCI for UEs in edge area"
221 "Absolute mode is used, default value 1 is mapped to -1 according to"
222 "TS36.213 Table 5.1.1.1-2",
223 UintegerValue(1),
225 MakeUintegerChecker<uint8_t>());
226 return tid;
227}
228
229void
231{
232 NS_LOG_FUNCTION(this << s);
233 m_ffrSapUser = s;
234}
235
238{
239 NS_LOG_FUNCTION(this);
240 return m_ffrSapProvider;
241}
242
243void
245{
246 NS_LOG_FUNCTION(this << s);
247 m_ffrRrcSapUser = s;
248}
249
252{
253 NS_LOG_FUNCTION(this);
254 return m_ffrRrcSapProvider;
255}
256
257void
259{
260 NS_LOG_FUNCTION(this);
262
263 NS_ASSERT_MSG(m_dlBandwidth > 24, "DlBandwidth must be at least 25 to use EFFR algorithm");
264 NS_ASSERT_MSG(m_ulBandwidth > 24, "UlBandwidth must be at least 25 to use EFFR algorithm");
265
266 if (m_frCellTypeId != 0)
267 {
270 }
271
272 NS_LOG_LOGIC(this << " requesting Event A1 measurements"
273 << " (threshold = 0"
274 << ")");
275 LteRrcSap::ReportConfigEutra reportConfig;
278 reportConfig.threshold1.range = 0;
282}
283
284void
286{
287 NS_LOG_FUNCTION(this);
288 if (m_frCellTypeId != 0)
289 {
292 }
295 m_needReconfiguration = false;
296}
297
298void
299LteFfrEnhancedAlgorithm::SetDownlinkConfiguration(uint16_t cellId, uint8_t bandwidth)
300{
301 NS_LOG_FUNCTION(this);
302 for (uint16_t i = 0; i < NUM_DOWNLINK_CONFS; ++i)
303 {
304 if ((g_ffrEnhancedDownlinkDefaultConfiguration[i].cellId == cellId) &&
306 {
312 }
313 }
314}
315
316void
317LteFfrEnhancedAlgorithm::SetUplinkConfiguration(uint16_t cellId, uint8_t bandwidth)
318{
319 NS_LOG_FUNCTION(this);
320 for (uint16_t i = 0; i < NUM_UPLINK_CONFS; ++i)
321 {
322 if ((g_ffrEnhancedUplinkDefaultConfiguration[i].cellId == cellId) &&
324 {
330 }
331 }
332}
333
334int
336{
338 NS_ASSERT_MSG(s >= 0.0, "negative spectral efficiency = " << s);
339 int cqi = 0;
340 while ((cqi < 15) && (SpectralEfficiencyForCqi[cqi + 1] < s))
341 {
342 ++cqi;
343 }
344 NS_LOG_LOGIC("cqi = " << cqi);
345 return cqi;
346}
347
348void
350{
351 m_dlRbgMap.clear();
352 m_dlReuse3RbgMap.clear();
353 m_dlReuse1RbgMap.clear();
356
357 int rbgSize = GetRbgSize(m_dlBandwidth);
358 m_dlRbgMap.resize(m_dlBandwidth / rbgSize, true);
359
360 m_dlReuse3RbgMap.resize(m_dlBandwidth / rbgSize, false);
361 m_dlReuse1RbgMap.resize(m_dlBandwidth / rbgSize, false);
362 m_dlPrimarySegmentRbgMap.resize(m_dlBandwidth / rbgSize, false);
363 m_dlSecondarySegmentRbgMap.resize(m_dlBandwidth / rbgSize, true);
364
365 NS_ASSERT_MSG(m_dlSubBandOffset <= m_dlBandwidth, "DlSubBandOffset higher than DlBandwidth");
368 "DlSubBandOffset + DlReuse3SubBandwidth + DlReuse1SubBandwidth higher than DlBandwidth");
369
370 for (int i = 0; i < m_dlReuse3SubBandwidth / rbgSize; i++)
371 {
372 int offset = m_dlSubBandOffset / rbgSize;
373 uint8_t index = offset + i;
374 m_dlReuse3RbgMap[index] = true;
375 m_dlPrimarySegmentRbgMap[index] = true;
376 m_dlRbgMap[index] = false;
377 }
378
379 for (int i = 0; i < m_dlReuse1SubBandwidth / rbgSize; i++)
380 {
381 int offset = (m_dlSubBandOffset + m_dlReuse3SubBandwidth) / rbgSize;
382 uint8_t index = offset + i;
383 m_dlReuse1RbgMap[index] = true;
384 m_dlPrimarySegmentRbgMap[index] = true;
385 m_dlSecondarySegmentRbgMap[index] = false;
386 m_dlRbgMap[index] = false;
387 }
388
389 for (int i = 0; i < m_dlReuse3SubBandwidth / rbgSize; i++)
390 {
391 uint8_t offset = (m_dlReuse3SubBandwidth + m_dlReuse1SubBandwidth) / rbgSize;
392
393 uint8_t index = 0 * offset + i;
394 m_dlSecondarySegmentRbgMap[index] = false;
395
396 index = 1 * offset + i;
397 m_dlSecondarySegmentRbgMap[index] = false;
398
399 index = 2 * offset + i;
400 m_dlSecondarySegmentRbgMap[index] = false;
401 }
402}
403
404void
406{
407 m_ulRbgMap.clear();
408 m_ulReuse3RbgMap.clear();
409 m_ulReuse1RbgMap.clear();
412
414 {
415 m_ulRbgMap.resize(m_ulBandwidth, false);
416 return;
417 }
418
419 m_ulRbgMap.resize(m_ulBandwidth, true);
420 m_ulReuse3RbgMap.resize(m_ulBandwidth, false);
421 m_ulReuse1RbgMap.resize(m_ulBandwidth, false);
424
425 NS_ASSERT_MSG(m_ulSubBandOffset <= m_ulBandwidth, "UlSubBandOffset higher than UlBandwidth");
428 "UlSubBandOffset + UlReuse3SubBandwidth + UlReuse1SubBandwidth higher than UlBandwidth");
429
430 for (uint8_t i = 0; i < m_ulReuse3SubBandwidth; i++)
431 {
432 int offset = m_ulSubBandOffset;
433 uint8_t index = offset + i;
434 m_ulReuse3RbgMap[index] = true;
435 m_ulPrimarySegmentRbgMap[index] = true;
436 m_ulRbgMap[index] = false;
437 }
438
439 for (uint8_t i = 0; i < m_ulReuse1SubBandwidth; i++)
440 {
442 uint8_t index = offset + i;
443 m_ulReuse1RbgMap[index] = true;
444 m_ulPrimarySegmentRbgMap[index] = true;
445 m_ulSecondarySegmentRbgMap[index] = false;
446 m_ulRbgMap[index] = false;
447 }
448
449 for (uint8_t i = 0; i < m_ulReuse3SubBandwidth; i++)
450 {
452
453 uint8_t index = 0 * offset + i;
454 m_ulSecondarySegmentRbgMap[index] = false;
455
456 index = 1 * offset + i;
457 m_ulSecondarySegmentRbgMap[index] = false;
458
459 index = 2 * offset + i;
460 m_ulSecondarySegmentRbgMap[index] = false;
461 }
462}
463
464std::vector<bool>
466{
467 NS_LOG_FUNCTION(this);
468
470 {
471 Reconfigure();
472 }
473
474 if (m_dlRbgMap.empty())
475 {
477 }
478
479 std::vector<bool> rbgMap = m_dlRbgMap;
480
481 for (auto it = m_dlRbgAvailableforUe.begin(); it != m_dlRbgAvailableforUe.end(); it++)
482 {
483 NS_LOG_INFO("RNTI : " << it->first);
484 std::vector<bool> rbgAvailableMap = it->second;
485 for (uint32_t i = 0; i < rbgMap.size(); i++)
486 {
487 NS_LOG_INFO("\t rbgId: " << i << " available " << (int)rbgAvailableMap.at(i));
488 if (rbgAvailableMap.at(i))
489 {
490 rbgMap.at(i) = false;
491 }
492 }
493 }
494
495 return rbgMap;
496}
497
498bool
500{
501 NS_LOG_FUNCTION(this);
502
503 bool isReuse3Rbg = m_dlReuse3RbgMap[rbgId];
504 bool isReuse1Rbg = m_dlReuse1RbgMap[rbgId];
505 bool isPrimarySegmentRbg = m_dlPrimarySegmentRbgMap[rbgId];
506 bool isSecondarySegmentRbg = m_dlSecondarySegmentRbgMap[rbgId];
507
508 auto it = m_ues.find(rnti);
509 if (it == m_ues.end())
510 {
511 m_ues.insert(std::pair<uint16_t, uint8_t>(rnti, AreaUnset));
512 }
513
514 it = m_ues.find(rnti);
515
516 // if UE area is unknown, serve UE in edge area RBGs
517 if (it->second == AreaUnset)
518 {
519 return isReuse3Rbg;
520 }
521
522 bool isCenterUe = false;
523 bool isEdgeUe = false;
524
525 if (it->second == CenterArea)
526 {
527 isCenterUe = true;
528 }
529 else if (it->second == EdgeArea)
530 {
531 isEdgeUe = true;
532 }
533
534 if (isPrimarySegmentRbg)
535 {
536 NS_LOG_INFO("PRIMARY SEGMENT RNTI: " << rnti << " rbgId: " << rbgId);
537 return (isReuse1Rbg && isCenterUe) || (isReuse3Rbg && isEdgeUe);
538 }
539 else if (isSecondarySegmentRbg && isCenterUe)
540 {
541 // check if RB can be used by UE based on CQI information
542 NS_LOG_INFO("SECONDARY SEGMENT RNTI: " << rnti << " rbgId: " << rbgId);
543 auto it = m_dlRbgAvailableforUe.find(rnti);
544 if (it != m_dlRbgAvailableforUe.end())
545 {
546 NS_LOG_INFO("RNTI: " << rnti << " rbgId: " << rbgId
547 << " available: " << it->second.at(rbgId));
548 if (it->second.at(rbgId))
549 {
550 return true;
551 }
552 }
553 return false;
554 }
555
556 return false;
557}
558
559std::vector<bool>
561{
562 NS_LOG_FUNCTION(this);
563
564 if (m_ulRbgMap.empty())
565 {
567 }
568
570 {
571 return m_ulRbgMap;
572 }
573
574 std::vector<bool> rbgMap = m_ulRbgMap;
575
576 for (auto it = m_ulRbAvailableforUe.begin(); it != m_ulRbAvailableforUe.end(); it++)
577 {
578 NS_LOG_INFO("RNTI : " << it->first);
579 std::vector<bool> rbAvailableMap = it->second;
580 for (uint32_t i = 0; i < rbgMap.size(); i++)
581 {
582 NS_LOG_INFO("\t rbgId: " << i << " available " << (int)rbAvailableMap.at(i));
583 if (rbAvailableMap.at(i))
584 {
585 rbgMap.at(i) = false;
586 }
587 }
588 }
589
590 return rbgMap;
591}
592
593bool
595{
596 NS_LOG_FUNCTION(this);
597
599 {
600 return true;
601 }
602
603 bool isReuse3Rbg = m_ulReuse3RbgMap[rbgId];
604 bool isReuse1Rbg = m_ulReuse1RbgMap[rbgId];
605 bool isPrimarySegmentRbg = m_ulPrimarySegmentRbgMap[rbgId];
606 bool isSecondarySegmentRbg = m_ulSecondarySegmentRbgMap[rbgId];
607
608 auto it = m_ues.find(rnti);
609 if (it == m_ues.end())
610 {
611 m_ues.insert(std::pair<uint16_t, uint8_t>(rnti, AreaUnset));
612 }
613
614 it = m_ues.find(rnti);
615
616 // if UE area is unknown, serve UE in edge area RBGs
617 if (it->second == AreaUnset)
618 {
619 return isReuse3Rbg;
620 }
621
622 bool isCenterUe = false;
623 bool isEdgeUe = false;
624
625 if (it->second == CenterArea)
626 {
627 isCenterUe = true;
628 }
629 else if (it->second == EdgeArea)
630 {
631 isEdgeUe = true;
632 }
633
634 if (isPrimarySegmentRbg)
635 {
636 return (isReuse1Rbg && isCenterUe) || (isReuse3Rbg && isEdgeUe);
637 }
638 else if (isSecondarySegmentRbg && isCenterUe)
639 {
640 // check if RB can be used by UE based on CQI information
641 NS_LOG_INFO("UL SECONDARY SEGMENT RNTI: " << rnti << " rbgId: " << rbgId);
642 auto it = m_ulRbAvailableforUe.find(rnti);
643 if (it != m_ulRbAvailableforUe.end())
644 {
645 NS_LOG_INFO("RNTI: " << rnti << " rbgId: " << rbgId
646 << " available: " << it->second.at(rbgId));
647 if (it->second.at(rbgId))
648 {
649 return true;
650 }
651 }
652 return false;
653 }
654
655 return false;
656}
657
658void
661{
662 NS_LOG_FUNCTION(this);
663
664 m_dlCqi.clear();
665 for (unsigned int i = 0; i < params.m_cqiList.size(); i++)
666 {
667 if (params.m_cqiList.at(i).m_cqiType == CqiListElement_s::A30)
668 {
669 NS_LOG_INFO("subband CQI reporting high layer configured");
670 // subband CQI reporting high layer configured
671 uint16_t rnti = params.m_cqiList.at(i).m_rnti;
672
673 auto ueIt = m_ues.find(rnti);
674 if (ueIt != m_ues.end())
675 {
676 if (ueIt->second != CenterArea)
677 {
678 continue;
679 }
680 }
681 else
682 {
683 continue;
684 }
685
686 auto it = m_dlCqi.find(rnti);
687 if (it == m_dlCqi.end())
688 {
689 // create the new entry
690 m_dlCqi.insert(
691 std::pair<uint16_t, SbMeasResult_s>(rnti,
692 params.m_cqiList.at(i).m_sbMeasResult));
693 }
694 else
695 {
696 // update the CQI value and refresh correspondent timer
697 (*it).second = params.m_cqiList.at(i).m_sbMeasResult;
698 }
699 }
700 else
701 {
702 NS_LOG_ERROR(this << " CQI type unknown");
703 }
704 }
705
707 m_dlRbgAvailableforUe.clear();
708 for (auto it = m_dlCqi.begin(); it != m_dlCqi.end(); it++)
709 {
710 uint16_t rnti = it->first;
711 std::vector<bool> rbgAvailableMap;
712
713 for (uint32_t i = 0; i < (*it).second.m_higherLayerSelected.size(); i++)
714 {
715 uint8_t rbgCqi = (*it).second.m_higherLayerSelected.at(i).m_sbCqi.at(0);
716
717 if (i > m_dlBandwidth / rbgSize)
718 {
719 continue;
720 }
721 NS_LOG_INFO(this << " RNTI " << rnti << " RBG " << i << " DL-CQI: " << (int)rbgCqi);
722
723 bool rbgAvailable = (rbgCqi > m_dlCqiThreshold);
724
725 bool isSecondarySegmentRbg = false;
726 if (i < m_dlSecondarySegmentRbgMap.size())
727 {
728 isSecondarySegmentRbg = m_dlSecondarySegmentRbgMap[i];
729 }
730
731 rbgAvailable = (isSecondarySegmentRbg ? rbgAvailable : false);
732
733 rbgAvailableMap.push_back(rbgAvailable);
734 }
735
736 m_dlRbgAvailableforUe.insert(std::pair<uint16_t, std::vector<bool>>(rnti, rbgAvailableMap));
737 }
738
739 m_ulRbAvailableforUe.clear();
740 for (auto it = m_dlRbgAvailableforUe.begin(); it != m_dlRbgAvailableforUe.end(); it++)
741 {
742 uint16_t rnti = it->first;
743 std::vector<bool> dlRbgAvailableMap = it->second;
744 std::vector<bool> ulRbAvailableMap;
745 ulRbAvailableMap.resize(m_ulBandwidth, false);
746
747 for (uint32_t j = 0; j < dlRbgAvailableMap.size(); j++)
748 {
749 uint32_t index = rbgSize * j;
750 for (uint32_t i = 0; i < rbgSize; i++)
751 {
752 index = index + i;
753 ulRbAvailableMap[index] = dlRbgAvailableMap[j];
754 }
755 }
756
757 m_ulRbAvailableforUe.insert(std::pair<uint16_t, std::vector<bool>>(rnti, ulRbAvailableMap));
758 }
759}
760
761void
764{
765 NS_LOG_FUNCTION(this);
766 if (params.m_ulCqi.m_type == UlCqi_s::SRS)
767 {
768 // get the RNTI from vendor specific parameters
769 uint16_t rnti = 0;
770 for (uint32_t j = 0; j < m_ulBandwidth; j++)
771 {
772 double sinr = LteFfConverter::fpS11dot3toDouble(params.m_ulCqi.m_sinr.at(j));
773 double s = log2(1 + (std::pow(10, sinr / 10) / ((-std::log(5.0 * 0.00005)) / 1.5)));
774 int cqi = GetCqiFromSpectralEfficiency(s);
775 NS_LOG_INFO(this << " RNTI " << rnti << " new SRS-CQI for RB " << j << " value "
776 << sinr << " UL-CQI: " << cqi);
777 }
778 }
779}
780
781void
782LteFfrEnhancedAlgorithm::DoReportUlCqiInfo(std::map<uint16_t, std::vector<double>> ulCqiMap)
783{
784 NS_LOG_FUNCTION(this);
785 NS_LOG_WARN("Method should not be called, because it is empty");
786}
787
788double
790 uint16_t rb,
791 std::map<uint16_t, std::vector<double>> ulCqiMap)
792{
793 auto itCqi = ulCqiMap.find(rnti);
794 if (itCqi == ulCqiMap.end())
795 {
796 // no cqi info about this UE
797 return NO_SINR;
798 }
799 else
800 {
801 // take the average SINR value among the available
802 double sinrSum = 0;
803 unsigned int sinrNum = 0;
804 for (uint32_t i = 0; i < m_ulBandwidth; i++)
805 {
806 double sinr = (*itCqi).second.at(i);
807 if (sinr != NO_SINR)
808 {
809 sinrSum += sinr;
810 sinrNum++;
811 }
812 }
813 double estimatedSinr = (sinrNum > 0) ? (sinrSum / sinrNum) : DBL_MAX;
814 // store the value
815 (*itCqi).second.at(rb) = estimatedSinr;
816 return estimatedSinr;
817 }
818}
819
820uint8_t
822{
823 NS_LOG_FUNCTION(this);
824
826 {
827 return 1; // 1 is mapped to 0 for Accumulated mode, and to -1 in Absolute mode TS36.213
828 // Table 5.1.1.1-2
829 }
830
831 // TS36.213 Table 5.1.1.1-2
832 // TPC | Accumulated Mode | Absolute Mode
833 //------------------------------------------------
834 // 0 | -1 | -4
835 // 1 | 0 | -1
836 // 2 | 1 | 1
837 // 3 | 3 | 4
838 //------------------------------------------------
839 // here Absolute mode is used
840
841 auto it = m_ues.find(rnti);
842 if (it == m_ues.end())
843 {
844 return 1;
845 }
846
847 if (it->second == EdgeArea)
848 {
849 return m_edgeAreaTpc;
850 }
851 else
852 {
853 return m_centerAreaTpc;
854 }
855
856 return 1;
857}
858
859uint16_t
861{
862 NS_LOG_FUNCTION(this);
863
864 uint8_t minContinuousUlBandwidth = m_ulBandwidth;
865
867 {
868 return minContinuousUlBandwidth;
869 }
870
871 minContinuousUlBandwidth =
872 ((m_ulReuse3SubBandwidth > 0) && (m_ulReuse3SubBandwidth < minContinuousUlBandwidth))
874 : minContinuousUlBandwidth;
875
876 minContinuousUlBandwidth =
877 ((m_ulReuse1SubBandwidth > 0) && (m_ulReuse1SubBandwidth < minContinuousUlBandwidth))
879 : minContinuousUlBandwidth;
880
881 NS_LOG_INFO("minContinuousUlBandwidth: " << (int)minContinuousUlBandwidth);
882
883 return minContinuousUlBandwidth;
884}
885
886void
888{
889 NS_LOG_FUNCTION(this << rnti << (uint16_t)measResults.measId);
890 NS_LOG_INFO("RNTI :" << rnti << " MeasId: " << (uint16_t)measResults.measId
891 << " RSRP: " << (uint16_t)measResults.measResultPCell.rsrpResult
892 << " RSRQ: " << (uint16_t)measResults.measResultPCell.rsrqResult);
893
894 if (measResults.measId != m_measId)
895 {
896 NS_LOG_WARN("Ignoring measId " << (uint16_t)measResults.measId);
897 }
898 else
899 {
900 auto it = m_ues.find(rnti);
901 if (it == m_ues.end())
902 {
903 m_ues.insert(std::pair<uint16_t, uint8_t>(rnti, AreaUnset));
904 }
905
906 it = m_ues.find(rnti);
908 {
909 if (it->second != EdgeArea)
910 {
911 NS_LOG_INFO("UE RNTI: " << rnti << " will be served in Edge sub-band");
912 it->second = EdgeArea;
913
914 LteRrcSap::PdschConfigDedicated pdschConfigDedicated;
915 pdschConfigDedicated.pa = m_edgeAreaPowerOffset;
916 m_ffrRrcSapUser->SetPdschConfigDedicated(rnti, pdschConfigDedicated);
917 }
918 }
919 else
920 {
921 if (it->second != CenterArea)
922 {
923 NS_LOG_INFO("UE RNTI: " << rnti << " will be served in Center sub-band");
924 it->second = CenterArea;
925
926 LteRrcSap::PdschConfigDedicated pdschConfigDedicated;
927 pdschConfigDedicated.pa = m_centerAreaPowerOffset;
928 m_ffrRrcSapUser->SetPdschConfigDedicated(rnti, pdschConfigDedicated);
929 }
930 }
931 }
932}
933
934void
936{
937 NS_LOG_FUNCTION(this);
938 NS_LOG_WARN("Method should not be called, because it is empty");
939}
940
941} // end of namespace ns3
static double fpS11dot3toDouble(uint16_t val)
Convert from fixed point S11.3 notation to double.
Definition: lte-common.cc:151
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:40
Service Access Point (SAP) offered by the eNodeB RRC instance to the Frequency Reuse algorithm instan...
Definition: lte-ffr-sap.h:140
virtual void DoInitialize()
Initialize() implementation.
Definition: object.cc:451
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:932
Hold an unsigned integer type.
Definition: uinteger.h:45
#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:86
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Definition: uinteger.h:46
#define NS_LOG_ERROR(msg)
Use NS_LOG to output a message of level LOG_ERROR.
Definition: log.h:254
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:282
#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:261
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:275
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:46
Every class exported by the ns3 library is enclosed in the ns3 namespace.
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...
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:49
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:306
Parameters of the SCHED_DL_CQI_INFO_REQ primitive.
Parameters of the SCHED_UL_CQI_INFO_REQ primitive.
uint8_t rsrqResult
the RSRQ result
Definition: lte-rrc-sap.h:675
uint8_t rsrpResult
the RSRP result
Definition: lte-rrc-sap.h:674
MeasResults structure.
Definition: lte-rrc-sap.h:717
uint8_t measId
measure ID
Definition: lte-rrc-sap.h:718
MeasResultPCell measResultPCell
measurement result primary cell
Definition: lte-rrc-sap.h:719
PdschConfigDedicated structure.
Definition: lte-rrc-sap.h:163
Specifies criteria for triggering of an E-UTRA measurement reporting event.
Definition: lte-rrc-sap.h:373
enum ns3::LteRrcSap::ReportConfigEutra::@62 eventId
Event enumeration.
@ RSRQ
Reference Signal Received Quality.
Definition: lte-rrc-sap.h:426
@ EVENT_A1
Event A1: Serving becomes better than absolute threshold.
Definition: lte-rrc-sap.h:384
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.
Definition: lte-rrc-sap.h:393
@ THRESHOLD_RSRQ
RSRQ is used for the threshold.
Definition: lte-rrc-sap.h:365
enum ns3::LteRrcSap::ThresholdEutra::@60 choice
Threshold enumeration.
uint8_t range
Value range used in RSRP/RSRQ threshold.
Definition: lte-rrc-sap.h:368