23 #include <ns3/pointer.h>
26 #include <ns3/simulator.h>
27 #include <ns3/lte-amc.h>
28 #include <ns3/fdtbfq-ff-mac-scheduler.h>
29 #include <ns3/lte-vendor-specific-parameters.h>
30 #include <ns3/boolean.h>
31 #include <ns3/integer.h>
144 : m_scheduler (scheduler)
219 : m_cschedSapUser (0),
224 m_amc = CreateObject <LteAmc> ();
252 static TypeId tid =
TypeId (
"ns3::FdTbfqFfMacScheduler")
254 .AddConstructor<FdTbfqFfMacScheduler> ()
255 .AddAttribute (
"CqiTimerThreshold",
256 "The number of TTIs a CQI is valid (default 1000 - 1 sec.)",
259 MakeUintegerChecker<uint32_t> ())
260 .AddAttribute (
"DebtLimit",
261 "Flow debt limit (default -625000 bytes)",
264 MakeIntegerChecker<int> ())
265 .AddAttribute (
"CreditLimit",
266 "Flow credit limit (default 625000 bytes)",
269 MakeUintegerChecker<uint32_t> ())
270 .AddAttribute (
"TokenPoolSize",
271 "The maximum value of flow token pool (default 1 bytes)",
274 MakeUintegerChecker<uint32_t> ())
275 .AddAttribute (
"CreditableThreshold",
276 "Threshold of flow credit (default 0 bytes)",
279 MakeUintegerChecker<uint32_t> ())
281 .AddAttribute (
"HarqEnabled",
282 "Activate/Deactivate the HARQ [by default is active].",
285 MakeBooleanChecker ())
286 .AddAttribute (
"UlGrantMcs",
287 "The MCS of the UL grant, must be [0..15] (default 0)",
290 MakeUintegerChecker<uint8_t> ())
345 dlHarqPrcStatus.resize (8,0);
348 dlHarqProcessesTimer.resize (8,0);
351 dlHarqdci.resize (8);
354 dlHarqRlcPdu.resize (2);
355 dlHarqRlcPdu.at (0).resize (8);
356 dlHarqRlcPdu.at (1).resize (8);
360 ulHarqPrcStatus.resize (8,0);
363 ulHarqdci.resize (8);
378 std::map <uint16_t, fdtbfqsFlowPerf_t>::iterator it;
398 m_flowStatsDl.insert (std::pair<uint16_t, fdtbfqsFlowPerf_t> (params.
m_rnti, flowStatsDl));
409 m_flowStatsUl.insert (std::pair<uint16_t, fdtbfqsFlowPerf_t> (params.
m_rnti, flowStatsUl));
416 m_flowStatsDl[(*it).first].tokenGenerationRate = mbrDlInBytes;
417 m_flowStatsUl[(*it).first].tokenGenerationRate = mbrUlInBytes;
431 std::map<LteFlowId_t, FfMacSchedSapProvider::SchedDlRlcBufferReqParameters>::iterator it =
m_rlcBufferReq.begin ();
432 std::map<LteFlowId_t, FfMacSchedSapProvider::SchedDlRlcBufferReqParameters>::iterator temp;
467 std::map<LteFlowId_t, FfMacSchedSapProvider::SchedDlRlcBufferReqParameters>::iterator it =
m_rlcBufferReq.begin ();
468 std::map<LteFlowId_t, FfMacSchedSapProvider::SchedDlRlcBufferReqParameters>::iterator temp;
471 if ((*it).first.m_rnti == params.
m_rnti)
497 std::map <LteFlowId_t, FfMacSchedSapProvider::SchedDlRlcBufferReqParameters>::iterator it;
505 m_rlcBufferReq.insert (std::pair <LteFlowId_t, FfMacSchedSapProvider::SchedDlRlcBufferReqParameters> (flow, params));
509 (*it).second = params;
534 for (
int i = 0; i < 4; i++)
549 std::map <LteFlowId_t, FfMacSchedSapProvider::SchedDlRlcBufferReqParameters>::iterator it;
553 if (((*it).first.m_rnti == rnti) && (((*it).second.m_rlcTransmissionQueueSize > 0)
554 || ((*it).second.m_rlcRetransmissionQueueSize > 0)
555 || ((*it).second.m_rlcStatusPduSize > 0) ))
559 if ((*it).first.m_rnti > rnti)
582 NS_FATAL_ERROR (
"No Process Id Statusfound for this RNTI " << rnti);
584 uint8_t i = (*it).second;
589 while ( ((*itStat).second.at (i) != 0)&&(i != (*it).second));
590 if ((*itStat).second.at (i) == 0)
621 NS_FATAL_ERROR (
"No Process Id Statusfound for this RNTI " << rnti);
623 uint8_t i = (*it).second;
628 while ( ((*itStat).second.at (i) != 0)&&(i != (*it).second));
629 if ((*itStat).second.at (i) == 0)
632 (*itStat).second.at (i) = 1;
636 NS_FATAL_ERROR (
"No HARQ process available for RNTI " << rnti <<
" check before update with HarqProcessAvailability");
639 return ((*it).second);
648 std::map <uint16_t, DlHarqProcessesTimer_t>::iterator itTimers;
657 NS_LOG_DEBUG (
this <<
" Reset HARQ proc " << i <<
" for RNTI " << (*itTimers).first);
658 std::map <uint16_t, DlHarqProcessesStatus_t>::iterator itStat =
m_dlHarqProcessesStatus.find ((*itTimers).first);
661 NS_FATAL_ERROR (
"No Process Id Status found for this RNTI " << (*itTimers).first);
663 (*itStat).second.at (i) = 0;
664 (*itTimers).second.at (i) = 0;
668 (*itTimers).second.at (i)++;
691 std::map <uint16_t, std::vector <uint16_t> > allocationMap;
692 std::vector <bool> rbgMap;
693 uint16_t rbgAllocatedNum = 0;
694 std::set <uint16_t> rntiAllocated;
699 std::map <uint16_t, uint8_t>::iterator itProcId;
702 (*itProcId).second = ((*itProcId).second + 1) %
HARQ_PROC_NUM;
707 uint16_t rbStart = 0;
708 std::vector <struct RachListElement_s>::iterator itRach;
713 newRar.
m_rnti = (*itRach).m_rnti;
717 newRar.m_grant.m_rnti = newRar.m_rnti;
720 uint16_t tbSizeBits = 0;
727 if (tbSizeBits < (*itRach).m_estimatedSize)
732 newRar.m_grant.m_rbStart = rbStart;
733 newRar.m_grant.m_rbLen = rbLen;
734 newRar.m_grant.m_tbSize = tbSizeBits / 8;
735 newRar.m_grant.m_hopping =
false;
736 newRar.m_grant.m_tpc = 0;
737 newRar.m_grant.m_cqiRequest =
false;
738 newRar.m_grant.m_ulDelay =
false;
739 NS_LOG_INFO (
this <<
" UL grant allocated to RNTI " << (*itRach).m_rnti <<
" rbStart " << rbStart <<
" rbLen " << rbLen <<
" MCS " <<
m_ulGrantMcs <<
" tbSize " << newRar.m_grant.m_tbSize);
740 for (uint16_t i = rbStart; i < rbStart + rbLen; i++)
744 rbStart = rbStart + rbLen;
750 uldci.
m_rnti = newRar.m_rnti;
769 std::map <uint16_t, uint8_t>::iterator itProcId;
775 harqId = (*itProcId).second;
781 (*itDci).second.at (harqId) = uldci;
796 NS_LOG_INFO (
this <<
" Received DL-HARQ feedback");
812 std::vector <struct DlInfoListElement_s> dlInfoListUntxed;
816 if (itRnti != rntiAllocated.end ())
822 std::vector <bool> retx;
823 NS_LOG_INFO (
this <<
" Processing DLHARQ feedback");
827 retx.push_back (
false);
834 if (retx.at (0) || retx.at (1))
839 NS_LOG_INFO (
this <<
" HARQ retx RNTI " << rnti <<
" harqId " << (uint16_t)harqId);
848 if (dci.
m_rv.size () == 1)
850 rv = dci.
m_rv.at (0);
854 rv = (dci.
m_rv.at (0) > dci.
m_rv.at (1) ? dci.
m_rv.at (0) : dci.
m_rv.at (1));
860 NS_LOG_INFO (
"Maximum number of retransmissions reached -> drop process");
866 (*it).second.at (harqId) = 0;
872 for (uint16_t k = 0; k < (*itRlcPdu).second.size (); k++)
874 (*itRlcPdu).second.at (k).at (harqId).clear ();
880 std::vector <int> dciRbg;
883 for (
int j = 0; j < 32; j++)
887 dciRbg.push_back (j);
893 for (uint8_t j = 0; j < dciRbg.size (); j++)
895 if (rbgMap.at (dciRbg.at (j)) ==
true)
905 for (uint8_t j = 0; j < dciRbg.size (); j++)
907 rbgMap.at (dciRbg.at (j)) =
true;
908 NS_LOG_INFO (
"RBG " << dciRbg.at (j) <<
" assigned");
912 NS_LOG_INFO (
this <<
" Send retx in the same RBGs");
918 uint8_t rbgId = (dciRbg.at (dciRbg.size () - 1) + 1) % rbgNum;
919 uint8_t startRbg = dciRbg.at (dciRbg.size () - 1);
920 std::vector <bool> rbgMapCopy = rbgMap;
921 while ((j < dciRbg.size ())&&(startRbg != rbgId))
923 if (rbgMapCopy.at (rbgId) ==
false)
925 rbgMapCopy.at (rbgId) =
true;
926 dciRbg.at (j) = rbgId;
931 if (j == dciRbg.size ())
934 uint32_t rbgMask = 0;
935 for (uint16_t k = 0; k < dciRbg.size (); k++)
937 rbgMask = rbgMask + (0x1 << dciRbg.at (k));
942 NS_LOG_INFO (
this <<
" Move retx in RBGs " << dciRbg.size ());
947 dlInfoListUntxed.push_back (params.
m_dlInfoList.at (i));
948 NS_LOG_INFO (
this <<
" No resource for this retx -> buffer it");
956 NS_FATAL_ERROR (
"Unable to find RlcPdcList in HARQ buffer for RNTI " << rnti);
958 for (uint8_t j = 0; j < nLayers; j++)
962 if (j >= dci.
m_ndi.size ())
965 dci.
m_ndi.push_back (0);
966 dci.
m_rv.push_back (0);
967 dci.
m_mcs.push_back (0);
969 NS_LOG_INFO (
this <<
" layer " << (uint16_t)j <<
" no txed (MIMO transition)");
973 dci.
m_ndi.at (j) = 0;
975 (*itHarq).second.at (harqId).m_rv.at (j)++;
976 NS_LOG_INFO (
this <<
" layer " << (uint16_t)j <<
" RV " << (uint16_t)dci.
m_rv.at (j));
982 dci.
m_ndi.at (j) = 0;
984 dci.
m_mcs.at (j) = 0;
986 NS_LOG_INFO (
this <<
" layer " << (uint16_t)j <<
" no retx");
989 for (uint16_t k = 0; k < (*itRlcPdu).second.at (0).at (dci.
m_harqProcess).size (); k++)
991 std::vector <struct RlcPduListElement_s> rlcPduListPerLc;
992 for (uint8_t j = 0; j < nLayers; j++)
996 if (j < dci.
m_ndi.size ())
998 rlcPduListPerLc.push_back ((*itRlcPdu).second.at (j).at (dci.
m_harqProcess).at (k));
1003 if (rlcPduListPerLc.size () > 0)
1010 (*itHarq).second.at (harqId).
m_rv = dci.
m_rv;
1015 NS_FATAL_ERROR (
"Unable to find HARQ timer for RNTI " << (uint16_t)rnti);
1017 (*itHarqTimer).second.at (harqId) = 0;
1019 rntiAllocated.insert (rnti);
1036 for (uint16_t k = 0; k < (*itRlcPdu).second.size (); k++)
1045 if (rbgAllocatedNum == rbgNum)
1056 std::map <uint16_t, fdtbfqsFlowPerf_t>::iterator itStats;
1059 if ( (*itStats).second.tokenGenerationRate / 1000 + (*itStats).second.tokenPoolSize > (*itStats).second.maxTokenPoolSize )
1061 (*itStats).second.counter += (*itStats).second.tokenGenerationRate / 1000 - ( (*itStats).second.maxTokenPoolSize - (*itStats).second.tokenPoolSize );
1062 (*itStats).second.tokenPoolSize = (*itStats).second.maxTokenPoolSize;
1063 bankSize += (*itStats).second.tokenGenerationRate / 1000 - ( (*itStats).second.maxTokenPoolSize - (*itStats).second.tokenPoolSize );
1067 (*itStats).second.tokenPoolSize += (*itStats).second.tokenGenerationRate / 1000;
1071 std::set <uint16_t> allocatedRnti;
1072 std::set <uint8_t> allocatedRbg;
1075 while (totalRbg < rbgNum)
1078 std::map <uint16_t, fdtbfqsFlowPerf_t>::iterator it;
1079 std::map <uint16_t, fdtbfqsFlowPerf_t>::iterator itMax =
m_flowStatsDl.end ();
1080 double metricMax = 0.0;
1081 bool firstRnti =
true;
1084 std::set <uint16_t>::iterator itRnti = rntiAllocated.find ((*it).first);
1088 if (itRnti != rntiAllocated.end ())
1090 NS_LOG_DEBUG (
this <<
" RNTI discared for HARQ tx" << (uint16_t)(*it).first);
1094 NS_LOG_DEBUG (
this <<
" RNTI discared for HARQ id" << (uint16_t)(*it).first);
1104 std::set <uint16_t>::iterator rnti;
1105 rnti = allocatedRnti.find((*it).first);
1106 if (rnti != allocatedRnti.end ())
1111 double metric = ( ( (double)(*it).second.counter ) / ( (double)(*it).second.tokenGenerationRate ) );
1113 if (firstRnti ==
true)
1120 if (metric > metricMax)
1134 allocatedRnti.insert((*itMax).first);
1137 uint32_t budget = 0;
1140 budget = (*itMax).second.counter - (*itMax).second.debtLimit;
1141 if ( budget > (*itMax).second.burstCredit )
1142 budget = (*itMax).second.burstCredit;
1146 budget = budget + (*itMax).second.tokenPoolSize;
1157 uint32_t rlcBufSize = 0;
1159 std::map<LteFlowId_t, FfMacSchedSapProvider::SchedDlRlcBufferReqParameters>::iterator itRlcBuf;
1162 if ( (*itRlcBuf).first.m_rnti == (*itMax).first )
1163 lcid = (*itRlcBuf).first.m_lcId;
1168 rlcBufSize = (*itRlcBuf).second.m_rlcTransmissionQueueSize + (*itRlcBuf).second.m_rlcRetransmissionQueueSize + (*itRlcBuf).second.m_rlcStatusPduSize;
1169 if ( budget > rlcBufSize )
1170 budget = rlcBufSize;
1174 uint32_t bytesTxed = 0;
1175 uint32_t bytesTxedTmp = 0;
1177 while ( bytesTxed <= budget )
1181 std::map <uint16_t,SbMeasResult_s>::iterator itCqi;
1183 std::map <uint16_t,uint8_t>::iterator itTxMode;
1187 NS_FATAL_ERROR (
"No Transmission Mode info on user " << (*it).first);
1192 double achievableRateMax = 0.0;
1194 for (
int k = 0; k < rbgNum; k++)
1196 std::set <uint8_t>::iterator rbg;
1197 rbg = allocatedRbg.find (k);
1198 if (rbg != allocatedRbg.end ())
1201 if ( rbgMap.at (k) ==
true)
1204 std::vector <uint8_t> sbCqi;
1207 for (uint8_t k = 0; k < nLayer; k++)
1209 sbCqi.push_back (1);
1214 sbCqi = (*itCqi).second.m_higherLayerSelected.at (k).m_sbCqi;
1216 uint8_t cqi1 = sbCqi.at (0);
1218 if (sbCqi.size () > 1)
1220 cqi2 = sbCqi.at (1);
1223 if ((cqi1 > 0)||(cqi2 > 0))
1228 double achievableRate = 0.0;
1229 for (uint8_t j = 0; j < nLayer; j++)
1232 if (sbCqi.size () > j)
1234 mcs =
m_amc->GetMcsFromCqi (sbCqi.at (j));
1241 achievableRate += ((
m_amc->GetTbSizeFromMcs (mcs, rbgSize) / 8) / 0.001);
1244 if ( achievableRate > achievableRateMax )
1246 achievableRateMax = achievableRate;
1253 if ( rbgIndex == rbgNum)
1262 allocatedRbg.insert (rbgIndex);
1266 std::map <uint16_t, std::vector <uint16_t> >::iterator itMap;
1267 itMap = allocationMap.find ((*itMax).first);
1268 uint16_t RbgPerRnti;
1269 if (itMap == allocationMap.end ())
1272 std::vector <uint16_t> tempMap;
1273 tempMap.push_back (rbgIndex);
1274 allocationMap.insert (std::pair <uint16_t, std::vector <uint16_t> > ((*itMax).first, tempMap));
1275 itMap = allocationMap.find ((*itMax).first);
1279 (*itMap).second.push_back (rbgIndex);
1281 rbgMap.at (rbgIndex) =
true;
1283 RbgPerRnti = (*itMap).second.size();
1286 std::vector <uint8_t> worstCqi (2, 15);
1289 for (uint16_t k = 0; k < (*itMap).second.size (); k++)
1291 if ((*itCqi).second.m_higherLayerSelected.size () > (*itMap).second.at (k))
1293 for (uint8_t j = 0; j < nLayer; j++)
1295 if ((*itCqi).second.m_higherLayerSelected.at ((*itMap).second.at (k)).m_sbCqi.size () > j)
1297 if (((*itCqi).second.m_higherLayerSelected.at ((*itMap).second.at (k)).m_sbCqi.at (j)) < worstCqi.at (j))
1299 worstCqi.at (j) = ((*itCqi).second.m_higherLayerSelected.at ((*itMap).second.at (k)).m_sbCqi.at (j));
1305 worstCqi.at (j) = 1;
1311 for (uint8_t j = 0; j < nLayer; j++)
1313 worstCqi.at (j) = 1;
1320 for (uint8_t j = 0; j < nLayer; j++)
1322 worstCqi.at (j) = 1;
1326 bytesTxedTmp = bytesTxed;
1328 for (uint8_t j = 0; j < nLayer; j++)
1330 int tbSize = (
m_amc->GetTbSizeFromMcs (
m_amc->GetMcsFromCqi (worstCqi.at (j)), RbgPerRnti * rbgSize) / 8);
1331 bytesTxed += tbSize;
1337 if ( bytesTxed > budget )
1339 std::map <uint16_t, std::vector <uint16_t> >::iterator itMap;
1340 itMap = allocationMap.find ((*itMax).first);
1341 (*itMap).second.pop_back ();
1342 allocatedRbg.erase (rbgIndex);
1343 bytesTxed = bytesTxedTmp;
1345 rbgMap.at (rbgIndex) =
false;
1349 if ( bytesTxed <= (*itMax).second.tokenPoolSize )
1351 (*itMax).second.tokenPoolSize -= bytesTxed;
1355 (*itMax).second.counter = (*itMax).second.counter - ( bytesTxed - (*itMax).second.tokenPoolSize );
1356 (*itMax).second.tokenPoolSize = 0;
1357 if (
bankSize <= ( bytesTxed - (*itMax).second.tokenPoolSize ))
1366 std::map <uint16_t, std::vector <uint16_t> >::iterator itMap = allocationMap.begin ();
1367 while (itMap != allocationMap.end ())
1371 newEl.
m_rnti = (*itMap).first;
1374 newDci.
m_rnti = (*itMap).first;
1382 lcActives = (uint16_t)65535;
1384 uint16_t RgbPerRnti = (*itMap).second.size ();
1385 std::map <uint16_t,SbMeasResult_s>::iterator itCqi;
1387 std::map <uint16_t,uint8_t>::iterator itTxMode;
1391 NS_FATAL_ERROR (
"No Transmission Mode info on user " << (*itMap).first);
1394 std::vector <uint8_t> worstCqi (2, 15);
1397 for (uint16_t k = 0; k < (*itMap).second.size (); k++)
1399 if ((*itCqi).second.m_higherLayerSelected.size () > (*itMap).second.at (k))
1401 NS_LOG_INFO (
this <<
" RBG " << (*itMap).second.at (k) <<
" CQI " << (uint16_t)((*itCqi).second.m_higherLayerSelected.at ((*itMap).second.at (k)).m_sbCqi.at (0)) );
1402 for (uint8_t j = 0; j < nLayer; j++)
1404 if ((*itCqi).second.m_higherLayerSelected.at ((*itMap).second.at (k)).m_sbCqi.size () > j)
1406 if (((*itCqi).second.m_higherLayerSelected.at ((*itMap).second.at (k)).m_sbCqi.at (j)) < worstCqi.at (j))
1408 worstCqi.at (j) = ((*itCqi).second.m_higherLayerSelected.at ((*itMap).second.at (k)).m_sbCqi.at (j));
1414 worstCqi.at (j) = 1;
1420 for (uint8_t j = 0; j < nLayer; j++)
1422 worstCqi.at (j) = 1;
1429 for (uint8_t j = 0; j < nLayer; j++)
1431 worstCqi.at (j) = 1;
1434 for (uint8_t j = 0; j < nLayer; j++)
1436 NS_LOG_INFO (
this <<
" Layer " << (uint16_t)j <<
" CQI selected " << (uint16_t)worstCqi.at (j));
1438 uint32_t bytesTxed = 0;
1439 for (uint8_t j = 0; j < nLayer; j++)
1441 newDci.
m_mcs.push_back (
m_amc->GetMcsFromCqi (worstCqi.at (j)));
1442 int tbSize = (
m_amc->GetTbSizeFromMcs (newDci.
m_mcs.at (j), RgbPerRnti * rbgSize) / 8);
1444 NS_LOG_INFO (
this <<
" Layer " << (uint16_t)j <<
" MCS selected" <<
m_amc->GetMcsFromCqi (worstCqi.at (j)));
1445 bytesTxed += tbSize;
1450 uint32_t rbgMask = 0;
1451 for (uint16_t k = 0; k < (*itMap).second.size (); k++)
1453 rbgMask = rbgMask + (0x1 << (*itMap).second.at (k));
1454 NS_LOG_INFO (
this <<
" Allocated RBG " << (*itMap).second.at (k));
1459 std::map <LteFlowId_t, FfMacSchedSapProvider::SchedDlRlcBufferReqParameters>::iterator itBufReq;
1462 if (((*itBufReq).first.m_rnti == (*itMap).first)
1463 && (((*itBufReq).second.m_rlcTransmissionQueueSize > 0)
1464 || ((*itBufReq).second.m_rlcRetransmissionQueueSize > 0)
1465 || ((*itBufReq).second.m_rlcStatusPduSize > 0) ))
1467 std::vector <struct RlcPduListElement_s> newRlcPduLe;
1468 for (uint8_t j = 0; j < nLayer; j++)
1474 newRlcPduLe.push_back (newRlcEl);
1482 NS_FATAL_ERROR (
"Unable to find RlcPdcList in HARQ buffer for RNTI " << (*itMap).first);
1484 (*itRlcPdu).second.at (j).at (newDci.
m_harqProcess).push_back (newRlcEl);
1489 if ((*itBufReq).first.m_rnti > (*itMap).first)
1494 for (uint8_t j = 0; j < nLayer; j++)
1496 newDci.
m_ndi.push_back (1);
1497 newDci.
m_rv.push_back (0);
1500 newEl.
m_dci = newDci;
1549 for (
unsigned int i = 0; i < params.
m_cqiList.size (); i++)
1554 std::map <uint16_t,uint8_t>::iterator it;
1555 uint16_t rnti = params.
m_cqiList.at (i).m_rnti;
1560 m_p10CqiRxed.insert ( std::pair<uint16_t, uint8_t > (rnti, params.
m_cqiList.at (i).m_wbCqi.at (0)) );
1567 (*it).second = params.
m_cqiList.at (i).m_wbCqi.at (0);
1569 std::map <uint16_t,uint32_t>::iterator itTimers;
1577 std::map <uint16_t,SbMeasResult_s>::iterator it;
1578 uint16_t rnti = params.
m_cqiList.at (i).m_rnti;
1583 m_a30CqiRxed.insert ( std::pair<uint16_t, SbMeasResult_s > (rnti, params.
m_cqiList.at (i).m_sbMeasResult) );
1589 (*it).second = params.
m_cqiList.at (i).m_sbMeasResult;
1590 std::map <uint16_t,uint32_t>::iterator itTimers;
1608 std::map <uint16_t, std::vector <double> >::iterator itCqi =
m_ueCqi.find (rnti);
1622 double sinr = (*itCqi).second.at (i);
1629 double estimatedSinr = (sinrNum > 0) ? (sinrSum / sinrNum) : DBL_MAX;
1631 (*itCqi).second.at (rb) = estimatedSinr;
1632 return (estimatedSinr);
1645 std::vector <bool> rbMap;
1646 uint16_t rbAllocatedNum = 0;
1647 std::set <uint16_t> rntiAllocated;
1648 std::vector <uint16_t> rbgAllocationMap;
1659 if (rbgAllocationMap.at (i) != 0)
1661 rbMap.at (i) =
true;
1670 for (uint16_t i = 0; i < params.
m_ulInfoList.size (); i++)
1679 NS_LOG_ERROR (
"No info find in HARQ buffer for UE (might change eNB) " << rnti);
1682 NS_LOG_INFO (
this <<
" UL-HARQ retx RNTI " << rnti <<
" harqId " << (uint16_t)harqId <<
" i " << i <<
" size " << params.
m_ulInfoList.size ());
1686 NS_LOG_ERROR (
"No info find in HARQ buffer for UE (might change eNB) " << rnti);
1693 NS_LOG_ERROR (
"No info find in HARQ buffer for UE (might change eNB) " << rnti);
1695 if ((*itStat).second.at (harqId) >= 3)
1697 NS_LOG_INFO (
"Max number of retransmissions reached (UL)-> drop process");
1703 if (rbMap.at (j) ==
true)
1714 rbMap.at (j) =
true;
1715 rbgAllocationMap.at (j) = dci.
m_rnti;
1723 NS_LOG_INFO (
"Cannot allocate retx due to RACH allocations for UE " << rnti);
1728 (*itStat).second.at ((*itProcId).second) = (*itStat).second.at (harqId) + 1;
1729 (*itStat).second.at (harqId) = 0;
1730 (*itHarq).second.at ((*itProcId).second) = dci;
1732 rntiAllocated.insert (dci.
m_rnti);
1741 std::map <uint16_t,uint32_t>::iterator it;
1746 std::set <uint16_t>::iterator itRnti = rntiAllocated.find ((*it).first);
1748 if (((*it).second > 0)&&(itRnti == rntiAllocated.end ()))
1771 int rbAllocated = 0;
1773 std::map <uint16_t, fdtbfqsFlowPerf_t>::iterator itStats;
1795 std::set <uint16_t>::iterator itRnti = rntiAllocated.find ((*it).first);
1796 if ((itRnti != rntiAllocated.end ())||((*it).second == 0))
1799 NS_LOG_DEBUG (
this <<
" UE already allocated in HARQ -> discared, RNTI " << (*it).first);
1821 uldci.
m_rnti = (*it).first;
1823 bool allocated =
false;
1824 NS_LOG_INFO (
this <<
" RB Allocated " << rbAllocated <<
" rbPerFlow " << rbPerFlow <<
" flows " << nflows);
1829 for (uint16_t j = rbAllocated; j < rbAllocated + rbPerFlow; j++)
1831 if (rbMap.at (j) ==
true)
1841 for (uint16_t j = rbAllocated; j < rbAllocated + rbPerFlow; j++)
1843 rbMap.at (j) =
true;
1845 rbgAllocationMap.at (j) = (*it).first;
1847 rbAllocated += rbPerFlow;
1878 std::map <uint16_t, std::vector <double> >::iterator itCqi =
m_ueCqi.find ((*it).first);
1888 double minSinr = (*itCqi).second.at (uldci.
m_rbStart);
1895 double sinr = (*itCqi).second.at (i);
1900 if ((*itCqi).second.at (i) < minSinr)
1902 minSinr = (*itCqi).second.at (i);
1907 double s = log2 ( 1 + (
1908 std::pow (10, minSinr / 10 ) /
1909 ( (-std::log (5.0 * 0.00005 )) / 1.5) ));
1910 cqi =
m_amc->GetCqiFromSpectralEfficiency (s);
1923 rbgAllocationMap.at (i) = 0;
1949 std::map <uint16_t, uint8_t>::iterator itProcId;
1955 harqId = (*itProcId).second;
1961 (*itDci).second.at (harqId) = uldci;
1964 NS_LOG_INFO (
this <<
" UE Allocation RNTI " << (*it).first <<
" startPRB " << (uint32_t)uldci.
m_rbStart <<
" nPRB " << (uint32_t)uldci.
m_rbLen <<
" CQI " << cqi <<
" MCS " << (uint32_t)uldci.
m_mcs <<
" TBsize " << uldci.
m_tbSize <<
" RbAlloc " << rbAllocated <<
" harqId " << (uint16_t)harqId);
2007 std::map <uint16_t,uint32_t>::iterator it;
2009 for (
unsigned int i = 0; i < params.
m_macCeList.size (); i++)
2020 uint32_t buffer = 0;
2021 for (uint8_t lcg = 0; lcg < 4; ++lcg)
2023 uint8_t bsrId = params.
m_macCeList.at (i).m_macCeValue.m_bufferStatus.at (lcg);
2028 NS_LOG_LOGIC (
this <<
"RNTI=" << rnti <<
" buffer=" << buffer);
2033 m_ceBsrRxed.insert ( std::pair<uint16_t, uint32_t > (rnti, buffer));
2038 (*it).second = buffer;
2081 std::map <uint16_t, std::vector <uint16_t> >::iterator itMap;
2082 std::map <uint16_t, std::vector <double> >::iterator itCqi;
2083 NS_LOG_DEBUG (
this <<
" Collect PUSCH CQIs of Frame no. " << (params.
m_sfnSf >> 4) <<
" subframe no. " << (0xF & params.
m_sfnSf));
2089 for (uint32_t i = 0; i < (*itMap).second.size (); i++)
2093 itCqi =
m_ueCqi.find ((*itMap).second.at (i));
2097 std::vector <double> newCqi;
2102 newCqi.push_back (sinr);
2111 m_ueCqi.insert (std::pair <uint16_t, std::vector <double> > ((*itMap).second.at (i), newCqi));
2118 (*itCqi).second.at (i) = sinr;
2119 NS_LOG_DEBUG (
this <<
" RNTI " << (*itMap).second.at (i) <<
" RB " << i <<
" SINR " << sinr);
2121 std::map <uint16_t, uint32_t>::iterator itTimers;
2142 rnti = vsp->GetRnti ();
2145 std::map <uint16_t, std::vector <double> >::iterator itCqi;
2150 std::vector <double> newCqi;
2154 newCqi.push_back (sinr);
2155 NS_LOG_INFO (
this <<
" RNTI " << rnti <<
" new SRS-CQI for RB " << j <<
" value " << sinr);
2158 m_ueCqi.insert (std::pair <uint16_t, std::vector <double> > (rnti, newCqi));
2168 (*itCqi).second.at (j) = sinr;
2169 NS_LOG_INFO (
this <<
" RNTI " << rnti <<
" update SRS-CQI for RB " << j <<
" value " << sinr);
2172 std::map <uint16_t, uint32_t>::iterator itTimers;
2185 NS_FATAL_ERROR (
"FdTbfqFfMacScheduler supports only PUSCH and SRS UL-CQIs");
2198 std::map <uint16_t,uint32_t>::iterator itP10 =
m_p10CqiTimers.begin ();
2202 if ((*itP10).second == 0)
2205 std::map <uint16_t,uint8_t>::iterator itMap =
m_p10CqiRxed.find ((*itP10).first);
2207 NS_LOG_INFO (
this <<
" P10-CQI expired for user " << (*itP10).first);
2209 std::map <uint16_t,uint32_t>::iterator temp = itP10;
2221 std::map <uint16_t,uint32_t>::iterator itA30 =
m_a30CqiTimers.begin ();
2225 if ((*itA30).second == 0)
2228 std::map <uint16_t,SbMeasResult_s>::iterator itMap =
m_a30CqiRxed.find ((*itA30).first);
2230 NS_LOG_INFO (
this <<
" A30-CQI expired for user " << (*itA30).first);
2232 std::map <uint16_t,uint32_t>::iterator temp = itA30;
2251 std::map <uint16_t,uint32_t>::iterator itUl =
m_ueCqiTimers.begin ();
2255 if ((*itUl).second == 0)
2258 std::map <uint16_t, std::vector <double> >::iterator itMap =
m_ueCqi.find ((*itUl).first);
2259 NS_ASSERT_MSG (itMap !=
m_ueCqi.end (),
" Does not find CQI report for user " << (*itUl).first);
2260 NS_LOG_INFO (
this <<
" UL-CQI exired for user " << (*itUl).first);
2261 (*itMap).second.clear ();
2263 std::map <uint16_t,uint32_t>::iterator temp = itUl;
2280 std::map<LteFlowId_t, FfMacSchedSapProvider::SchedDlRlcBufferReqParameters>::iterator it;
2285 NS_LOG_INFO (
this <<
" UE " << rnti <<
" LC " << (uint16_t)lcid <<
" txqueue " << (*it).second.m_rlcTransmissionQueueSize <<
" retxqueue " << (*it).second.m_rlcRetransmissionQueueSize <<
" status " << (*it).second.m_rlcStatusPduSize <<
" decrease " << size);
2288 if (((*it).second.m_rlcStatusPduSize > 0) && (size >= (*it).second.m_rlcStatusPduSize))
2290 (*it).second.m_rlcStatusPduSize = 0;
2292 else if (((*it).second.m_rlcRetransmissionQueueSize > 0) && (size >= (*it).second.m_rlcRetransmissionQueueSize))
2294 (*it).second.m_rlcRetransmissionQueueSize = 0;
2296 else if ((*it).second.m_rlcTransmissionQueueSize > 0)
2298 uint32_t rlcOverhead;
2313 if ((*it).second.m_rlcTransmissionQueueSize <= size - rlcOverhead)
2315 (*it).second.m_rlcTransmissionQueueSize = 0;
2319 (*it).second.m_rlcTransmissionQueueSize -= size - rlcOverhead;
2325 NS_LOG_ERROR (
this <<
" Does not find DL RLC Buffer Report of UE " << rnti);
2334 std::map <uint16_t,uint32_t>::iterator it =
m_ceBsrRxed.find (rnti);
2337 NS_LOG_INFO (
this <<
" UE " << rnti <<
" size " << size <<
" BSR " << (*it).second);
2338 if ((*it).second >= size)
2340 (*it).second -= size;
2349 NS_LOG_ERROR (
this <<
" Does not find BSR report info of UE " << rnti);
2357 NS_LOG_FUNCTION (
this <<
" RNTI " << rnti <<
" txMode " << (uint16_t)txMode);
std::vector< struct UlInfoListElement_s > m_ulInfoList
See section 4.3.1 dlDciListElement.
std::map< uint16_t, uint32_t > m_a30CqiTimers
virtual void SetFfMacCschedSapUser(FfMacCschedSapUser *s)
set the user part of the FfMacCschedSap that this Scheduler will interact with.
void DoCschedCellConfigReq(const struct FfMacCschedSapProvider::CschedCellConfigReqParameters ¶ms)
uint32_t creditableThreshold
counter threshold that the flow cannot further borrow tokens from bank
smart pointer class similar to boost::intrusive_ptr
#define NS_LOG_FUNCTION(parameters)
std::map< uint16_t, uint8_t > m_uesTxMode
std::map< uint16_t, std::vector< double > > m_ueCqi
std::map< LteFlowId_t, FfMacSchedSapProvider::SchedDlRlcBufferReqParameters > m_rlcBufferReq
std::map< uint16_t, SbMeasResult_s > m_a30CqiRxed
int FdTbfqType0AllocationRbg[4]
Parameters of the CSCHED_UE_CONFIG_CNF primitive.
Parameters of the CSCHED_UE_RELEASE_REQ primitive.
void DoSchedUlNoiseInterferenceReq(const struct FfMacSchedSapProvider::SchedUlNoiseInterferenceReqParameters ¶ms)
void DoCschedLcConfigReq(const struct FfMacCschedSapProvider::CschedLcConfigReqParameters ¶ms)
std::map< uint16_t, UlHarqProcessesDciBuffer_t > m_ulHarqProcessesDciBuffer
enum ns3::UlCqi_s::Type_e m_type
void DoSchedUlSrInfoReq(const struct FfMacSchedSapProvider::SchedUlSrInfoReqParameters ¶ms)
std::vector< UlDciListElement_s > UlHarqProcessesDciBuffer_t
std::vector< struct LogicalChannelConfigListElement_s > m_logicalChannelConfigList
std::vector< uint16_t > m_sinr
void DoSchedDlPagingBufferReq(const struct FfMacSchedSapProvider::SchedDlPagingBufferReqParameters ¶ms)
std::vector< uint8_t > DlHarqProcessesTimer_t
#define NS_ASSERT(condition)
Hold a signed integer type.
int debtLimit
the maximum number of tokens connection i can borrow from the bank each time
NS_OBJECT_ENSURE_REGISTERED(NullMessageSimulatorImpl)
std::vector< uint8_t > m_mcs
void DoSchedDlCqiInfoReq(const struct FfMacSchedSapProvider::SchedDlCqiInfoReqParameters ¶ms)
See section 4.3.2 ulDciListElement.
bool m_harqOn
m_harqOn when false inhibit te HARQ mechanisms (by default active)
uint32_t tokenPoolSize
token generation rate ( byte/s )
std::vector< struct UlDciListElement_s > m_dciList
virtual void SchedDlRachInfoReq(const struct SchedDlRachInfoReqParameters ¶ms)
virtual void CschedLcConfigReq(const struct CschedLcConfigReqParameters ¶ms)
virtual void SchedDlCqiInfoReq(const struct SchedDlCqiInfoReqParameters ¶ms)
See section 4.3.10 buildRARListElement.
virtual void SchedUlSrInfoReq(const struct SchedUlSrInfoReqParameters ¶ms)
Parameters of the CSCHED_UE_CONFIG_UPDATE_IND primitive.
virtual void SchedUlNoiseInterferenceReq(const struct SchedUlNoiseInterferenceReqParameters ¶ms)
std::map< uint16_t, fdtbfqsFlowPerf_t > m_flowStatsUl
void DoSchedDlRachInfoReq(const struct FfMacSchedSapProvider::SchedDlRachInfoReqParameters ¶ms)
NS_LOG_COMPONENT_DEFINE("FdTbfqFfMacScheduler")
Parameters of the CSCHED_LC_RELEASE_REQ primitive.
std::vector< std::vector< struct RlcPduListElement_s > > m_rlcPduList
uint8_t m_transmissionMode
uint32_t m_cqiTimersThreshold
Parameters of the SCHED_DL_TRIGGER_REQ primitive.
uint8_t m_logicalChannelIdentity
#define NS_FATAL_ERROR(msg)
fatal error handling
virtual ~FdTbfqFfMacScheduler()
Destructor.
virtual void CschedUeReleaseReq(const struct CschedUeReleaseReqParameters ¶ms)
int LcActivePerFlow(uint16_t rnti)
virtual void SchedUlTriggerReq(const struct SchedUlTriggerReqParameters ¶ms)
std::vector< RlcPduList_t > DlHarqRlcPduListBuffer_t
Parameters of the SCHED_DL_MAC_BUFFER_REQ primitive.
Parameters of the SCHED_DL_PAGING_BUFFER_REQ primitive.
virtual void CschedUeConfigUpdateInd(const struct CschedUeConfigUpdateIndParameters ¶ms)=0
virtual void SetFfMacSchedSapUser(FfMacSchedSapUser *s)
set the user part of the FfMacSchedSap that this Scheduler will interact with.
std::vector< struct RachListElement_s > m_rachList
std::vector< struct VendorSpecificListElement_s > m_vendorSpecificList
FfMacSchedSapUser * m_schedSapUser
virtual void SchedDlRlcBufferReq(const struct SchedDlRlcBufferReqParameters ¶ms)
std::map< uint16_t, std::vector< uint16_t > > m_allocationMaps
std::map< uint16_t, DlHarqProcessesDciBuffer_t > m_dlHarqProcessesDciBuffer
virtual void SchedDlTriggerReq(const struct SchedDlTriggerReqParameters ¶ms)
uint8_t HarqProcessAvailability(uint16_t rnti)
Return the availability of free process for the RNTI specified.
static TypeId GetTypeId(void)
friend class FdTbfqSchedulerMemberCschedSapProvider
std::map< uint16_t, DlHarqProcessesTimer_t > m_dlHarqProcessesTimer
uint64_t packetArrivalRate
void DoCschedLcReleaseReq(const struct FfMacCschedSapProvider::CschedLcReleaseReqParameters ¶ms)
std::map< uint16_t, fdtbfqsFlowPerf_t > m_flowStatsDl
Parameters of the SCHED_UL_TRIGGER_REQ primitive.
Hold an unsigned integer type.
static uint8_t TxMode2LayerNum(uint8_t txMode)
std::vector< uint8_t > m_ndi
FfMacCschedSapProvider::CschedCellConfigReqParameters m_cschedCellConfig
virtual FfMacCschedSapProvider * GetFfMacCschedSapProvider()
virtual void CschedUeConfigCnf(const struct CschedUeConfigCnfParameters ¶ms)=0
std::vector< uint16_t > m_rachAllocationMap
std::map< uint16_t, uint32_t > m_p10CqiTimers
std::vector< uint8_t > m_logicalChannelIdentity
#define NS_LOG_LOGIC(msg)
Parameters of the SCHED_UL_NOISE_INTERFERENCE_REQ primitive.
uint8_t m_logicalChannelIdentity
std::vector< struct CqiListElement_s > m_cqiList
std::vector< struct DlInfoListElement_s > m_dlInfoList
void DoSchedDlRlcBufferReq(const struct FfMacSchedSapProvider::SchedDlRlcBufferReqParameters ¶ms)
std::map< uint16_t, uint32_t > m_ueCqiTimers
Implements the SCHED SAP and CSCHED SAP for a Frequency Domain Token Bank Fair Queue scheduler...
virtual void SchedDlConfigInd(const struct SchedDlConfigIndParameters ¶ms)=0
Parameters of the API primitives.
int8_t m_pdcchPowerOffset
std::vector< uint16_t > m_tbsSize
uint32_t m_creditableThreshold
See section 4.3.9 rlcPDU_ListElement.
void DoSchedUlMacCtrlInfoReq(const struct FfMacSchedSapProvider::SchedUlMacCtrlInfoReqParameters ¶ms)
FdTbfqFfMacScheduler * m_scheduler
std::vector< DlDciListElement_s > DlHarqProcessesDciBuffer_t
FdTbfqFfMacScheduler * m_scheduler
Parameters of the CSCHED_LC_CONFIG_REQ primitive.
virtual void CschedCellConfigReq(const struct CschedCellConfigReqParameters ¶ms)
CSCHED_CELL_CONFIG_REQ.
virtual void CschedLcReleaseReq(const struct CschedLcReleaseReqParameters ¶ms)
std::vector< uint8_t > m_rv
FdTbfqFfMacScheduler()
Constructor.
void RefreshHarqProcesses()
Refresh HARQ processes according to the timers.
std::map< uint16_t, uint8_t > m_dlHarqCurrentProcessId
FfMacCschedSapProvider * m_cschedSapProvider
uint64_t tokenGenerationRate
packet arrival rate( byte/s)
virtual void SchedUlConfigInd(const struct SchedUlConfigIndParameters ¶ms)=0
static Time Now(void)
Return the "current simulation time".
double EstimateUlSinr(uint16_t rnti, uint16_t rb)
std::map< uint16_t, DlHarqRlcPduListBuffer_t > m_dlHarqProcessesRlcPduListBuffer
UlCqiFilter_t m_ulCqiFilter
int GetRbgSize(int dlbandwidth)
This abstract base class identifies the interface by means of which the helper object can plug on the...
virtual void SchedDlMacBufferReq(const struct SchedDlMacBufferReqParameters ¶ms)
#define NS_ASSERT_MSG(condition, message)
uint8_t m_nrOfPdcchOfdmSymbols
Parameters of the SCHED_DL_CQI_INFO_REQ primitive.
std::vector< struct MacCeListElement_s > m_macCeList
Parameters of the API primitives.
uint32_t burstCredit
the number of token borrow or given to token bank
std::vector< struct RachListElement_s > m_rachList
static double fpS11dot3toDouble(uint16_t val)
int counter
maximum size of token pool (byte)
std::vector< uint8_t > UlHarqProcessesStatus_t
void DoSchedUlCqiInfoReq(const struct FfMacSchedSapProvider::SchedUlCqiInfoReqParameters ¶ms)
std::vector< uint8_t > DlHarqProcessesStatus_t
Parameters of the SCHED_UL_CQI_INFO_REQ primitive.
virtual void DoDispose(void)
This method is called by Object::Dispose or by the object's destructor, whichever comes first...
static uint32_t BsrId2BufferSize(uint8_t val)
uint8_t m_transmissionMode
void DoSchedDlTriggerReq(const struct FfMacSchedSapProvider::SchedDlTriggerReqParameters ¶ms)
FfMacSchedSapProvider * m_schedSapProvider
void RefreshDlCqiMaps(void)
Parameters of the API primitives.
Parameters of the SCHED_UL_MAC_CTRL_INFO_REQ primitive.
#define NS_LOG_DEBUG(msg)
std::map< uint16_t, UlHarqProcessesStatus_t > m_ulHarqProcessesStatus
void DoSchedDlMacBufferReq(const struct FfMacSchedSapProvider::SchedDlMacBufferReqParameters ¶ms)
FfMacCschedSapUser * m_cschedSapUser
void DoSchedUlTriggerReq(const struct FfMacSchedSapProvider::SchedUlTriggerReqParameters ¶ms)
std::vector< DlInfoListElement_s > m_dlInfoListBuffered
Parameters of the SCHED_UL_SR_INFO_REQ primitive.
FdTbfqSchedulerMemberSchedSapProvider()
#define NS_LOG_ERROR(msg)
Parameters of the SCHED_DL_RACH_INFO_REQ primitive.
Parameters of the SCHED_UL_CONFIG_IND primitive.
std::map< uint16_t, DlHarqProcessesStatus_t > m_dlHarqProcessesStatus
Parameters of the CSCHED_UE_CONFIG_REQ primitive.
std::map< uint16_t, uint8_t > m_ulHarqCurrentProcessId
virtual FfMacSchedSapProvider * GetFfMacSchedSapProvider()
uint32_t maxTokenPoolSize
current size of token pool (byte)
struct DlDciListElement_s m_dci
std::vector< struct BuildRarListElement_s > m_buildRarList
std::map< uint16_t, uint8_t > m_p10CqiRxed
void RefreshUlCqiMaps(void)
virtual void SchedUlCqiInfoReq(const struct SchedUlCqiInfoReqParameters ¶ms)
FdTbfqSchedulerMemberCschedSapProvider()
friend class FdTbfqSchedulerMemberSchedSapProvider
a unique identifier for an interface.
TypeId SetParent(TypeId tid)
void DoCschedUeReleaseReq(const struct FfMacCschedSapProvider::CschedUeReleaseReqParameters ¶ms)
void UpdateUlRlcBufferInfo(uint16_t rnti, uint16_t size)
virtual void SchedUlMacCtrlInfoReq(const struct SchedUlMacCtrlInfoReqParameters ¶ms)
void DoCschedUeConfigReq(const struct FfMacCschedSapProvider::CschedUeConfigReqParameters ¶ms)
uint8_t UpdateHarqProcessId(uint16_t rnti)
Update and return a new process Id for the RNTI specified.
std::map< uint16_t, uint32_t > m_ceBsrRxed
virtual void SchedDlPagingBufferReq(const struct SchedDlPagingBufferReqParameters ¶ms)
void UpdateDlRlcBufferInfo(uint16_t rnti, uint8_t lcid, uint16_t size)
void TransmissionModeConfigurationUpdate(uint16_t rnti, uint8_t txMode)
std::vector< struct BuildDataListElement_s > m_buildDataList
virtual void CschedUeConfigReq(const struct CschedUeConfigReqParameters ¶ms)
uint8_t m_ueTxAntennaSelection
See section 4.3.8 builDataListElement.