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>
143 : m_scheduler (scheduler)
218 : m_cschedSapUser (0),
223 m_amc = CreateObject <LteAmc> ();
251 static TypeId tid =
TypeId (
"ns3::FdTbfqFfMacScheduler")
253 .AddConstructor<FdTbfqFfMacScheduler> ()
254 .AddAttribute (
"CqiTimerThreshold",
255 "The number of TTIs a CQI is valid (default 1000 - 1 sec.)",
258 MakeUintegerChecker<uint32_t> ())
259 .AddAttribute (
"DebtLimit",
260 "Flow debt limit (default -625000 bytes)",
263 MakeIntegerChecker<int> ())
264 .AddAttribute (
"CreditLimit",
265 "Flow credit limit (default 625000 bytes)",
268 MakeUintegerChecker<uint32_t> ())
269 .AddAttribute (
"TokenPoolSize",
270 "The maximum value of flow token pool (default 1 bytes)",
273 MakeUintegerChecker<uint32_t> ())
274 .AddAttribute (
"CreditableThreshold",
275 "Threshold of flow credit (default 0 bytes)",
278 MakeUintegerChecker<uint32_t> ())
280 .AddAttribute (
"HarqEnabled",
281 "Activate/Deactivate the HARQ [by default is active].",
284 MakeBooleanChecker ())
285 .AddAttribute (
"UlGrantMcs",
286 "The MCS of the UL grant, must be [0..15] (default 0)",
289 MakeUintegerChecker<uint8_t> ())
344 dlHarqPrcStatus.resize (8,0);
347 dlHarqProcessesTimer.resize (8,0);
350 dlHarqdci.resize (8);
353 dlHarqRlcPdu.resize (2);
354 dlHarqRlcPdu.at (0).resize (8);
355 dlHarqRlcPdu.at (1).resize (8);
359 ulHarqPrcStatus.resize (8,0);
362 ulHarqdci.resize (8);
377 std::map <uint16_t, fdtbfqsFlowPerf_t>::iterator it;
397 m_flowStatsDl.insert (std::pair<uint16_t, fdtbfqsFlowPerf_t> (params.
m_rnti, flowStatsDl));
408 m_flowStatsUl.insert (std::pair<uint16_t, fdtbfqsFlowPerf_t> (params.
m_rnti, flowStatsUl));
415 m_flowStatsDl[(*it).first].tokenGenerationRate = mbrDlInBytes;
416 m_flowStatsUl[(*it).first].tokenGenerationRate = mbrUlInBytes;
430 std::map<LteFlowId_t, FfMacSchedSapProvider::SchedDlRlcBufferReqParameters>::iterator it =
m_rlcBufferReq.begin ();
431 std::map<LteFlowId_t, FfMacSchedSapProvider::SchedDlRlcBufferReqParameters>::iterator temp;
466 std::map<LteFlowId_t, FfMacSchedSapProvider::SchedDlRlcBufferReqParameters>::iterator it =
m_rlcBufferReq.begin ();
467 std::map<LteFlowId_t, FfMacSchedSapProvider::SchedDlRlcBufferReqParameters>::iterator temp;
470 if ((*it).first.m_rnti == params.
m_rnti)
496 std::map <LteFlowId_t, FfMacSchedSapProvider::SchedDlRlcBufferReqParameters>::iterator it;
504 m_rlcBufferReq.insert (std::pair <LteFlowId_t, FfMacSchedSapProvider::SchedDlRlcBufferReqParameters> (flow, params));
508 (*it).second = params;
533 for (
int i = 0; i < 4; i++)
548 std::map <LteFlowId_t, FfMacSchedSapProvider::SchedDlRlcBufferReqParameters>::iterator it;
552 if (((*it).first.m_rnti == rnti) && (((*it).second.m_rlcTransmissionQueueSize > 0)
553 || ((*it).second.m_rlcRetransmissionQueueSize > 0)
554 || ((*it).second.m_rlcStatusPduSize > 0) ))
558 if ((*it).first.m_rnti > rnti)
581 NS_FATAL_ERROR (
"No Process Id Statusfound for this RNTI " << rnti);
583 uint8_t i = (*it).second;
588 while ( ((*itStat).second.at (i) != 0)&&(i != (*it).second));
589 if ((*itStat).second.at (i) == 0)
620 NS_FATAL_ERROR (
"No Process Id Statusfound for this RNTI " << rnti);
622 uint8_t i = (*it).second;
627 while ( ((*itStat).second.at (i) != 0)&&(i != (*it).second));
628 if ((*itStat).second.at (i) == 0)
631 (*itStat).second.at (i) = 1;
635 NS_FATAL_ERROR (
"No HARQ process available for RNTI " << rnti <<
" check before update with HarqProcessAvailability");
638 return ((*it).second);
647 std::map <uint16_t, DlHarqProcessesTimer_t>::iterator itTimers;
656 NS_LOG_DEBUG (
this <<
" Reset HARQ proc " << i <<
" for RNTI " << (*itTimers).first);
657 std::map <uint16_t, DlHarqProcessesStatus_t>::iterator itStat =
m_dlHarqProcessesStatus.find ((*itTimers).first);
660 NS_FATAL_ERROR (
"No Process Id Status found for this RNTI " << (*itTimers).first);
662 (*itStat).second.at (i) = 0;
663 (*itTimers).second.at (i) = 0;
667 (*itTimers).second.at (i)++;
690 std::map <uint16_t, std::vector <uint16_t> > allocationMap;
691 std::vector <bool> rbgMap;
692 uint16_t rbgAllocatedNum = 0;
693 std::set <uint16_t> rntiAllocated;
699 uint16_t rbStart = 0;
700 std::vector <struct RachListElement_s>::iterator itRach;
705 newRar.
m_rnti = (*itRach).m_rnti;
709 newRar.m_grant.m_rnti = newRar.m_rnti;
712 uint16_t tbSizeBits = 0;
719 if (tbSizeBits < (*itRach).m_estimatedSize)
724 newRar.m_grant.m_rbStart = rbStart;
725 newRar.m_grant.m_rbLen = rbLen;
726 newRar.m_grant.m_tbSize = tbSizeBits / 8;
727 newRar.m_grant.m_hopping =
false;
728 newRar.m_grant.m_tpc = 0;
729 newRar.m_grant.m_cqiRequest =
false;
730 newRar.m_grant.m_ulDelay =
false;
731 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);
732 for (uint16_t i = rbStart; i < rbStart + rbLen; i++)
736 rbStart = rbStart + rbLen;
750 NS_LOG_INFO (
this <<
" Received DL-HARQ feedback");
766 std::vector <struct DlInfoListElement_s> dlInfoListUntxed;
770 if (itRnti != rntiAllocated.end ())
776 std::vector <bool> retx;
777 NS_LOG_INFO (
this <<
" Processing DLHARQ feedback");
781 retx.push_back (
false);
788 if (retx.at (0) || retx.at (1))
793 NS_LOG_INFO (
this <<
" HARQ retx RNTI " << rnti <<
" harqId " << (uint16_t)harqId);
802 if (dci.
m_rv.size () == 1)
804 rv = dci.
m_rv.at (0);
808 rv = (dci.
m_rv.at (0) > dci.
m_rv.at (1) ? dci.
m_rv.at (0) : dci.
m_rv.at (1));
814 NS_LOG_INFO (
"Maximum number of retransmissions reached -> drop process");
820 (*it).second.at (harqId) = 0;
826 for (uint16_t k = 0; k < (*itRlcPdu).second.size (); k++)
828 (*itRlcPdu).second.at (k).at (harqId).clear ();
834 std::vector <int> dciRbg;
837 for (
int j = 0; j < 32; j++)
841 dciRbg.push_back (j);
847 for (uint8_t j = 0; j < dciRbg.size (); j++)
849 if (rbgMap.at (dciRbg.at (j)) ==
true)
859 for (uint8_t j = 0; j < dciRbg.size (); j++)
861 rbgMap.at (dciRbg.at (j)) =
true;
862 NS_LOG_INFO (
"RBG " << dciRbg.at (j) <<
" assigned");
866 NS_LOG_INFO (
this <<
" Send retx in the same RBGs");
872 uint8_t rbgId = (dciRbg.at (dciRbg.size () - 1) + 1) % rbgNum;
873 uint8_t startRbg = dciRbg.at (dciRbg.size () - 1);
874 std::vector <bool> rbgMapCopy = rbgMap;
875 while ((j < dciRbg.size ())&&(startRbg != rbgId))
877 if (rbgMapCopy.at (rbgId) ==
false)
879 rbgMapCopy.at (rbgId) =
true;
880 dciRbg.at (j) = rbgId;
885 if (j == dciRbg.size ())
888 uint32_t rbgMask = 0;
889 for (uint16_t k = 0; k < dciRbg.size (); k++)
891 rbgMask = rbgMask + (0x1 << dciRbg.at (k));
896 NS_LOG_INFO (
this <<
" Move retx in RBGs " << dciRbg.size ());
901 dlInfoListUntxed.push_back (params.
m_dlInfoList.at (i));
902 NS_LOG_INFO (
this <<
" No resource for this retx -> buffer it");
910 NS_FATAL_ERROR (
"Unable to find RlcPdcList in HARQ buffer for RNTI " << rnti);
912 for (uint8_t j = 0; j < nLayers; j++)
916 if (j >= dci.
m_ndi.size ())
919 dci.
m_ndi.push_back (0);
920 dci.
m_rv.push_back (0);
921 dci.
m_mcs.push_back (0);
923 NS_LOG_INFO (
this <<
" layer " << (uint16_t)j <<
" no txed (MIMO transition)");
927 dci.
m_ndi.at (j) = 0;
929 (*itHarq).second.at (harqId).m_rv.at (j)++;
930 NS_LOG_INFO (
this <<
" layer " << (uint16_t)j <<
" RV " << (uint16_t)dci.
m_rv.at (j));
936 dci.
m_ndi.at (j) = 0;
938 dci.
m_mcs.at (j) = 0;
940 NS_LOG_INFO (
this <<
" layer " << (uint16_t)j <<
" no retx");
943 for (uint16_t k = 0; k < (*itRlcPdu).second.at (0).at (dci.
m_harqProcess).size (); k++)
945 std::vector <struct RlcPduListElement_s> rlcPduListPerLc;
946 for (uint8_t j = 0; j < nLayers; j++)
950 if (j < dci.
m_ndi.size ())
952 rlcPduListPerLc.push_back ((*itRlcPdu).second.at (j).at (dci.
m_harqProcess).at (k));
957 if (rlcPduListPerLc.size () > 0)
964 (*itHarq).second.at (harqId).
m_rv = dci.
m_rv;
969 NS_FATAL_ERROR (
"Unable to find HARQ timer for RNTI " << (uint16_t)rnti);
971 (*itHarqTimer).second.at (harqId) = 0;
973 rntiAllocated.insert (rnti);
990 for (uint16_t k = 0; k < (*itRlcPdu).second.size (); k++)
1001 std::map <uint16_t, fdtbfqsFlowPerf_t>::iterator itStats;
1004 if ( (*itStats).second.tokenGenerationRate / 1000 + (*itStats).second.tokenPoolSize > (*itStats).second.maxTokenPoolSize )
1006 (*itStats).second.counter += (*itStats).second.tokenGenerationRate / 1000 - ( (*itStats).second.maxTokenPoolSize - (*itStats).second.tokenPoolSize );
1007 (*itStats).second.tokenPoolSize = (*itStats).second.maxTokenPoolSize;
1008 bankSize += (*itStats).second.tokenGenerationRate / 1000 - ( (*itStats).second.maxTokenPoolSize - (*itStats).second.tokenPoolSize );
1012 (*itStats).second.tokenPoolSize += (*itStats).second.tokenGenerationRate / 1000;
1016 std::set <uint16_t> allocatedRnti;
1017 std::set <uint8_t> allocatedRbg;
1020 while (totalRbg < rbgNum)
1023 std::map <uint16_t, fdtbfqsFlowPerf_t>::iterator it;
1024 std::map <uint16_t, fdtbfqsFlowPerf_t>::iterator itMax =
m_flowStatsDl.end ();
1025 double metricMax = 0.0;
1026 bool firstRnti =
true;
1029 std::set <uint16_t>::iterator itRnti = rntiAllocated.find ((*it).first);
1033 if (itRnti != rntiAllocated.end ())
1035 NS_LOG_DEBUG (
this <<
" RNTI discared for HARQ tx" << (uint16_t)(*it).first);
1039 NS_LOG_DEBUG (
this <<
" RNTI discared for HARQ id" << (uint16_t)(*it).first);
1049 std::set <uint16_t>::iterator rnti;
1050 rnti = allocatedRnti.find((*it).first);
1051 if (rnti != allocatedRnti.end ())
1056 double metric = ( ( (double)(*it).second.counter ) / ( (double)(*it).second.tokenGenerationRate ) );
1058 if (firstRnti ==
true)
1065 if (metric > metricMax)
1079 allocatedRnti.insert((*itMax).first);
1082 uint32_t budget = 0;
1085 budget = (*itMax).second.counter - (*itMax).second.debtLimit;
1086 if ( budget > (*itMax).second.burstCredit )
1087 budget = (*itMax).second.burstCredit;
1091 budget = budget + (*itMax).second.tokenPoolSize;
1102 uint32_t rlcBufSize = 0;
1104 std::map<LteFlowId_t, FfMacSchedSapProvider::SchedDlRlcBufferReqParameters>::iterator itRlcBuf;
1107 if ( (*itRlcBuf).first.m_rnti == (*itMax).first )
1108 lcid = (*itRlcBuf).first.m_lcId;
1113 rlcBufSize = (*itRlcBuf).second.m_rlcTransmissionQueueSize + (*itRlcBuf).second.m_rlcRetransmissionQueueSize + (*itRlcBuf).second.m_rlcStatusPduSize;
1114 if ( budget > rlcBufSize )
1115 budget = rlcBufSize;
1119 uint32_t bytesTxed = 0;
1120 uint32_t bytesTxedTmp = 0;
1122 while ( bytesTxed <= budget )
1126 std::map <uint16_t,SbMeasResult_s>::iterator itCqi;
1128 std::map <uint16_t,uint8_t>::iterator itTxMode;
1132 NS_FATAL_ERROR (
"No Transmission Mode info on user " << (*it).first);
1137 double achievableRateMax = 0.0;
1139 for (
int k = 0; k < rbgNum; k++)
1141 std::set <uint8_t>::iterator rbg;
1142 rbg = allocatedRbg.find (k);
1143 if (rbg != allocatedRbg.end ())
1146 if ( rbgMap.at (k) ==
true)
1149 std::vector <uint8_t> sbCqi;
1152 for (uint8_t k = 0; k < nLayer; k++)
1154 sbCqi.push_back (1);
1159 sbCqi = (*itCqi).second.m_higherLayerSelected.at (k).m_sbCqi;
1161 uint8_t cqi1 = sbCqi.at (0);
1163 if (sbCqi.size () > 1)
1165 cqi2 = sbCqi.at (1);
1168 if ((cqi1 > 0)||(cqi2 > 0))
1173 double achievableRate = 0.0;
1174 for (uint8_t j = 0; j < nLayer; j++)
1177 if (sbCqi.size () > j)
1179 mcs =
m_amc->GetMcsFromCqi (sbCqi.at (j));
1186 achievableRate += ((
m_amc->GetTbSizeFromMcs (mcs, rbgSize) / 8) / 0.001);
1189 if ( achievableRate > achievableRateMax )
1191 achievableRateMax = achievableRate;
1198 if ( rbgIndex == rbgNum)
1207 allocatedRbg.insert (rbgIndex);
1211 std::map <uint16_t, std::vector <uint16_t> >::iterator itMap;
1212 itMap = allocationMap.find ((*itMax).first);
1213 uint16_t RbgPerRnti;
1214 if (itMap == allocationMap.end ())
1217 std::vector <uint16_t> tempMap;
1218 tempMap.push_back (rbgIndex);
1219 allocationMap.insert (std::pair <uint16_t, std::vector <uint16_t> > ((*itMax).first, tempMap));
1220 itMap = allocationMap.find ((*itMax).first);
1224 (*itMap).second.push_back (rbgIndex);
1226 rbgMap.at (rbgIndex) =
true;
1228 RbgPerRnti = (*itMap).second.size();
1231 std::vector <uint8_t> worstCqi (2, 15);
1234 for (uint16_t k = 0; k < (*itMap).second.size (); k++)
1236 if ((*itCqi).second.m_higherLayerSelected.size () > (*itMap).second.at (k))
1238 for (uint8_t j = 0; j < nLayer; j++)
1240 if ((*itCqi).second.m_higherLayerSelected.at ((*itMap).second.at (k)).m_sbCqi.size () > j)
1242 if (((*itCqi).second.m_higherLayerSelected.at ((*itMap).second.at (k)).m_sbCqi.at (j)) < worstCqi.at (j))
1244 worstCqi.at (j) = ((*itCqi).second.m_higherLayerSelected.at ((*itMap).second.at (k)).m_sbCqi.at (j));
1250 worstCqi.at (j) = 1;
1256 for (uint8_t j = 0; j < nLayer; j++)
1258 worstCqi.at (j) = 1;
1265 for (uint8_t j = 0; j < nLayer; j++)
1267 worstCqi.at (j) = 1;
1271 bytesTxedTmp = bytesTxed;
1273 for (uint8_t j = 0; j < nLayer; j++)
1275 int tbSize = (
m_amc->GetTbSizeFromMcs (
m_amc->GetMcsFromCqi (worstCqi.at (j)), RbgPerRnti * rbgSize) / 8);
1276 bytesTxed += tbSize;
1282 if ( bytesTxed > budget )
1284 std::map <uint16_t, std::vector <uint16_t> >::iterator itMap;
1285 itMap = allocationMap.find ((*itMax).first);
1286 (*itMap).second.pop_back ();
1287 allocatedRbg.erase (rbgIndex);
1288 bytesTxed = bytesTxedTmp;
1290 rbgMap.at (rbgIndex) =
false;
1294 if ( bytesTxed <= (*itMax).second.tokenPoolSize )
1296 (*itMax).second.tokenPoolSize -= bytesTxed;
1300 (*itMax).second.counter = (*itMax).second.counter - ( bytesTxed - (*itMax).second.tokenPoolSize );
1301 (*itMax).second.tokenPoolSize = 0;
1302 if (
bankSize <= ( bytesTxed - (*itMax).second.tokenPoolSize ))
1311 std::map <uint16_t, std::vector <uint16_t> >::iterator itMap = allocationMap.begin ();
1312 while (itMap != allocationMap.end ())
1316 newEl.
m_rnti = (*itMap).first;
1319 newDci.
m_rnti = (*itMap).first;
1327 lcActives = (uint16_t)65535;
1329 uint16_t RgbPerRnti = (*itMap).second.size ();
1330 std::map <uint16_t,SbMeasResult_s>::iterator itCqi;
1332 std::map <uint16_t,uint8_t>::iterator itTxMode;
1336 NS_FATAL_ERROR (
"No Transmission Mode info on user " << (*itMap).first);
1339 std::vector <uint8_t> worstCqi (2, 15);
1342 for (uint16_t k = 0; k < (*itMap).second.size (); k++)
1344 if ((*itCqi).second.m_higherLayerSelected.size () > (*itMap).second.at (k))
1346 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)) );
1347 for (uint8_t j = 0; j < nLayer; j++)
1349 if ((*itCqi).second.m_higherLayerSelected.at ((*itMap).second.at (k)).m_sbCqi.size () > j)
1351 if (((*itCqi).second.m_higherLayerSelected.at ((*itMap).second.at (k)).m_sbCqi.at (j)) < worstCqi.at (j))
1353 worstCqi.at (j) = ((*itCqi).second.m_higherLayerSelected.at ((*itMap).second.at (k)).m_sbCqi.at (j));
1359 worstCqi.at (j) = 1;
1365 for (uint8_t j = 0; j < nLayer; j++)
1367 worstCqi.at (j) = 1;
1374 for (uint8_t j = 0; j < nLayer; j++)
1376 worstCqi.at (j) = 1;
1379 for (uint8_t j = 0; j < nLayer; j++)
1381 NS_LOG_INFO (
this <<
" Layer " << (uint16_t)j <<
" CQI selected " << (uint16_t)worstCqi.at (j));
1383 uint32_t bytesTxed = 0;
1384 for (uint8_t j = 0; j < nLayer; j++)
1386 newDci.
m_mcs.push_back (
m_amc->GetMcsFromCqi (worstCqi.at (j)));
1387 int tbSize = (
m_amc->GetTbSizeFromMcs (newDci.
m_mcs.at (j), RgbPerRnti * rbgSize) / 8);
1389 NS_LOG_INFO (
this <<
" Layer " << (uint16_t)j <<
" MCS selected" <<
m_amc->GetMcsFromCqi (worstCqi.at (j)));
1390 bytesTxed += tbSize;
1395 uint32_t rbgMask = 0;
1396 for (uint16_t k = 0; k < (*itMap).second.size (); k++)
1398 rbgMask = rbgMask + (0x1 << (*itMap).second.at (k));
1399 NS_LOG_INFO (
this <<
" Allocated RBG " << (*itMap).second.at (k));
1404 std::map <LteFlowId_t, FfMacSchedSapProvider::SchedDlRlcBufferReqParameters>::iterator itBufReq;
1407 if (((*itBufReq).first.m_rnti == (*itMap).first)
1408 && (((*itBufReq).second.m_rlcTransmissionQueueSize > 0)
1409 || ((*itBufReq).second.m_rlcRetransmissionQueueSize > 0)
1410 || ((*itBufReq).second.m_rlcStatusPduSize > 0) ))
1412 std::vector <struct RlcPduListElement_s> newRlcPduLe;
1413 for (uint8_t j = 0; j < nLayer; j++)
1419 newRlcPduLe.push_back (newRlcEl);
1427 NS_FATAL_ERROR (
"Unable to find RlcPdcList in HARQ buffer for RNTI " << (*itMap).first);
1429 (*itRlcPdu).second.at (j).at (newDci.
m_harqProcess).push_back (newRlcEl);
1434 if ((*itBufReq).first.m_rnti > (*itMap).first)
1439 for (uint8_t j = 0; j < nLayer; j++)
1441 newDci.
m_ndi.push_back (1);
1442 newDci.
m_rv.push_back (0);
1445 newEl.
m_dci = newDci;
1494 for (
unsigned int i = 0; i < params.
m_cqiList.size (); i++)
1499 std::map <uint16_t,uint8_t>::iterator it;
1500 uint16_t rnti = params.
m_cqiList.at (i).m_rnti;
1505 m_p10CqiRxed.insert ( std::pair<uint16_t, uint8_t > (rnti, params.
m_cqiList.at (i).m_wbCqi.at (0)) );
1512 (*it).second = params.
m_cqiList.at (i).m_wbCqi.at (0);
1514 std::map <uint16_t,uint32_t>::iterator itTimers;
1522 std::map <uint16_t,SbMeasResult_s>::iterator it;
1523 uint16_t rnti = params.
m_cqiList.at (i).m_rnti;
1528 m_a30CqiRxed.insert ( std::pair<uint16_t, SbMeasResult_s > (rnti, params.
m_cqiList.at (i).m_sbMeasResult) );
1534 (*it).second = params.
m_cqiList.at (i).m_sbMeasResult;
1535 std::map <uint16_t,uint32_t>::iterator itTimers;
1553 std::map <uint16_t, std::vector <double> >::iterator itCqi =
m_ueCqi.find (rnti);
1567 double sinr = (*itCqi).second.at (i);
1574 double estimatedSinr = (sinrNum > 0) ? (sinrSum / sinrNum) : DBL_MAX;
1576 (*itCqi).second.at (rb) = estimatedSinr;
1577 return (estimatedSinr);
1590 std::vector <bool> rbMap;
1591 uint16_t rbAllocatedNum = 0;
1592 std::set <uint16_t> rntiAllocated;
1593 std::vector <uint16_t> rbgAllocationMap;
1604 if (rbgAllocationMap.at (i) != 0)
1606 rbMap.at (i) =
true;
1616 std::map <uint16_t, uint8_t>::iterator itProcId;
1619 (*itProcId).second = ((*itProcId).second + 1) %
HARQ_PROC_NUM;
1622 for (uint16_t i = 0; i < params.
m_ulInfoList.size (); i++)
1631 NS_LOG_ERROR (
"No info find in HARQ buffer for UE (might change eNB) " << rnti);
1634 NS_LOG_INFO (
this <<
" UL-HARQ retx RNTI " << rnti <<
" harqId " << (uint16_t)harqId <<
" i " << i <<
" size " << params.
m_ulInfoList.size ());
1638 NS_LOG_ERROR (
"No info find in HARQ buffer for UE (might change eNB) " << rnti);
1645 NS_LOG_ERROR (
"No info find in HARQ buffer for UE (might change eNB) " << rnti);
1647 if ((*itStat).second.at (harqId) >= 3)
1649 NS_LOG_INFO (
"Max number of retransmissions reached (UL)-> drop process");
1655 if (rbMap.at (j) ==
true)
1666 rbMap.at (j) =
true;
1667 rbgAllocationMap.at (j) = dci.
m_rnti;
1675 NS_LOG_INFO (
"Cannot allocate retx due to RACH allocations for UE " << rnti);
1680 (*itStat).second.at ((*itProcId).second) = (*itStat).second.at (harqId) + 1;
1681 (*itStat).second.at (harqId) = 0;
1682 (*itHarq).second.at ((*itProcId).second) = dci;
1684 rntiAllocated.insert (dci.
m_rnti);
1693 std::map <uint16_t,uint32_t>::iterator it;
1698 std::set <uint16_t>::iterator itRnti = rntiAllocated.find ((*it).first);
1700 if (((*it).second > 0)&&(itRnti == rntiAllocated.end ()))
1723 int rbAllocated = 0;
1725 std::map <uint16_t, fdtbfqsFlowPerf_t>::iterator itStats;
1747 std::set <uint16_t>::iterator itRnti = rntiAllocated.find ((*it).first);
1748 if ((itRnti != rntiAllocated.end ())||((*it).second == 0))
1751 NS_LOG_DEBUG (
this <<
" UE already allocated in HARQ -> discared, RNTI " << (*it).first);
1773 uldci.
m_rnti = (*it).first;
1775 bool allocated =
false;
1776 NS_LOG_INFO (
this <<
" RB Allocated " << rbAllocated <<
" rbPerFlow " << rbPerFlow <<
" flows " << nflows);
1781 for (uint16_t j = rbAllocated; j < rbAllocated + rbPerFlow; j++)
1783 if (rbMap.at (j) ==
true)
1793 for (uint16_t j = rbAllocated; j < rbAllocated + rbPerFlow; j++)
1795 rbMap.at (j) =
true;
1797 rbgAllocationMap.at (j) = (*it).first;
1799 rbAllocated += rbPerFlow;
1830 std::map <uint16_t, std::vector <double> >::iterator itCqi =
m_ueCqi.find ((*it).first);
1840 double minSinr = (*itCqi).second.at (uldci.
m_rbStart);
1847 double sinr = (*itCqi).second.at (i);
1852 if ((*itCqi).second.at (i) < minSinr)
1854 minSinr = (*itCqi).second.at (i);
1859 double s = log2 ( 1 + (
1860 std::pow (10, minSinr / 10 ) /
1861 ( (-std::log (5.0 * 0.00005 )) / 1.5) ));
1862 cqi =
m_amc->GetCqiFromSpectralEfficiency (s);
1875 rbgAllocationMap.at (i) = 0;
1901 std::map <uint16_t, uint8_t>::iterator itProcId;
1907 harqId = (*itProcId).second;
1913 (*itDci).second.at (harqId) = uldci;
1916 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);
1959 std::map <uint16_t,uint32_t>::iterator it;
1961 for (
unsigned int i = 0; i < params.
m_macCeList.size (); i++)
1972 uint32_t buffer = 0;
1973 for (uint8_t lcg = 0; lcg < 4; ++lcg)
1975 uint8_t bsrId = params.
m_macCeList.at (i).m_macCeValue.m_bufferStatus.at (lcg);
1980 NS_LOG_LOGIC (
this <<
"RNTI=" << rnti <<
" buffer=" << buffer);
1985 m_ceBsrRxed.insert ( std::pair<uint16_t, uint32_t > (rnti, buffer));
1990 (*it).second = buffer;
2033 std::map <uint16_t, std::vector <uint16_t> >::iterator itMap;
2034 std::map <uint16_t, std::vector <double> >::iterator itCqi;
2035 NS_LOG_DEBUG (
this <<
" Collect PUSCH CQIs of Frame no. " << (params.
m_sfnSf >> 4) <<
" subframe no. " << (0xF & params.
m_sfnSf));
2041 for (uint32_t i = 0; i < (*itMap).second.size (); i++)
2045 itCqi =
m_ueCqi.find ((*itMap).second.at (i));
2049 std::vector <double> newCqi;
2054 newCqi.push_back (sinr);
2063 m_ueCqi.insert (std::pair <uint16_t, std::vector <double> > ((*itMap).second.at (i), newCqi));
2070 (*itCqi).second.at (i) = sinr;
2071 NS_LOG_DEBUG (
this <<
" RNTI " << (*itMap).second.at (i) <<
" RB " << i <<
" SINR " << sinr);
2073 std::map <uint16_t, uint32_t>::iterator itTimers;
2094 rnti = vsp->GetRnti ();
2097 std::map <uint16_t, std::vector <double> >::iterator itCqi;
2102 std::vector <double> newCqi;
2106 newCqi.push_back (sinr);
2107 NS_LOG_INFO (
this <<
" RNTI " << rnti <<
" new SRS-CQI for RB " << j <<
" value " << sinr);
2110 m_ueCqi.insert (std::pair <uint16_t, std::vector <double> > (rnti, newCqi));
2120 (*itCqi).second.at (j) = sinr;
2121 NS_LOG_INFO (
this <<
" RNTI " << rnti <<
" update SRS-CQI for RB " << j <<
" value " << sinr);
2124 std::map <uint16_t, uint32_t>::iterator itTimers;
2137 NS_FATAL_ERROR (
"FdTbfqFfMacScheduler supports only PUSCH and SRS UL-CQIs");
2150 std::map <uint16_t,uint32_t>::iterator itP10 =
m_p10CqiTimers.begin ();
2154 if ((*itP10).second == 0)
2157 std::map <uint16_t,uint8_t>::iterator itMap =
m_p10CqiRxed.find ((*itP10).first);
2159 NS_LOG_INFO (
this <<
" P10-CQI expired for user " << (*itP10).first);
2161 std::map <uint16_t,uint32_t>::iterator temp = itP10;
2173 std::map <uint16_t,uint32_t>::iterator itA30 =
m_a30CqiTimers.begin ();
2177 if ((*itA30).second == 0)
2180 std::map <uint16_t,SbMeasResult_s>::iterator itMap =
m_a30CqiRxed.find ((*itA30).first);
2182 NS_LOG_INFO (
this <<
" A30-CQI expired for user " << (*itA30).first);
2184 std::map <uint16_t,uint32_t>::iterator temp = itA30;
2203 std::map <uint16_t,uint32_t>::iterator itUl =
m_ueCqiTimers.begin ();
2207 if ((*itUl).second == 0)
2210 std::map <uint16_t, std::vector <double> >::iterator itMap =
m_ueCqi.find ((*itUl).first);
2211 NS_ASSERT_MSG (itMap !=
m_ueCqi.end (),
" Does not find CQI report for user " << (*itUl).first);
2212 NS_LOG_INFO (
this <<
" UL-CQI exired for user " << (*itUl).first);
2213 (*itMap).second.clear ();
2215 std::map <uint16_t,uint32_t>::iterator temp = itUl;
2232 std::map<LteFlowId_t, FfMacSchedSapProvider::SchedDlRlcBufferReqParameters>::iterator it;
2237 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);
2240 if (((*it).second.m_rlcStatusPduSize > 0) && (size >= (*it).second.m_rlcStatusPduSize))
2242 (*it).second.m_rlcStatusPduSize = 0;
2244 else if (((*it).second.m_rlcRetransmissionQueueSize > 0) && (size >= (*it).second.m_rlcRetransmissionQueueSize))
2246 (*it).second.m_rlcRetransmissionQueueSize = 0;
2248 else if ((*it).second.m_rlcTransmissionQueueSize > 0)
2250 uint32_t rlcOverhead;
2265 if ((*it).second.m_rlcTransmissionQueueSize <= size - rlcOverhead)
2267 (*it).second.m_rlcTransmissionQueueSize = 0;
2271 (*it).second.m_rlcTransmissionQueueSize -= size - rlcOverhead;
2277 NS_LOG_ERROR (
this <<
" Does not find DL RLC Buffer Report of UE " << rnti);
2286 std::map <uint16_t,uint32_t>::iterator it =
m_ceBsrRxed.find (rnti);
2289 NS_LOG_INFO (
this <<
" UE " << rnti <<
" size " << size <<
" BSR " << (*it).second);
2290 if ((*it).second >= size)
2292 (*it).second -= size;
2301 NS_LOG_ERROR (
this <<
" Does not find BSR report info of UE " << rnti);
2309 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)
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]
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
#define NS_LOG_COMPONENT_DEFINE(name)
std::vector< uint8_t > m_mcs
void DoSchedDlCqiInfoReq(const struct FfMacSchedSapProvider::SchedDlCqiInfoReqParameters ¶ms)
See section 4.3.2 ulDciListElement.
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)
virtual void SchedUlNoiseInterferenceReq(const struct SchedUlNoiseInterferenceReqParameters ¶ms)
std::map< uint16_t, fdtbfqsFlowPerf_t > m_flowStatsUl
void DoSchedDlRachInfoReq(const struct FfMacSchedSapProvider::SchedDlRachInfoReqParameters ¶ms)
std::vector< std::vector< struct RlcPduListElement_s > > m_rlcPduList
uint8_t m_transmissionMode
uint32_t m_cqiTimersThreshold
uint8_t m_logicalChannelIdentity
#define NS_FATAL_ERROR(msg)
fatal error handling
virtual ~FdTbfqFfMacScheduler()
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
virtual void CschedUeConfigUpdateInd(const struct CschedUeConfigUpdateIndParameters ¶ms)=0
virtual void SetFfMacSchedSapUser(FfMacSchedSapUser *s)
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
Hold an unsigned integer type.
static uint8_t TxMode2LayerNum(uint8_t txMode)
NS_OBJECT_ENSURE_REGISTERED(AntennaModel)
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)
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
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
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
double EstimateUlSinr(uint16_t rnti, uint16_t rb)
std::map< uint16_t, DlHarqRlcPduListBuffer_t > m_dlHarqProcessesRlcPduListBuffer
UlCqiFilter_t m_ulCqiFilter
int GetRbgSize(int dlbandwidth)
virtual void SchedDlMacBufferReq(const struct SchedDlMacBufferReqParameters ¶ms)
#define NS_ASSERT_MSG(condition, message)
uint8_t m_nrOfPdcchOfdmSymbols
std::vector< struct MacCeListElement_s > m_macCeList
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
virtual void DoDispose(void)
static uint32_t BsrId2BufferSize(uint8_t val)
uint8_t m_transmissionMode
void DoSchedDlTriggerReq(const struct FfMacSchedSapProvider::SchedDlTriggerReqParameters ¶ms)
FfMacSchedSapProvider * m_schedSapProvider
void RefreshDlCqiMaps(void)
#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
FdTbfqSchedulerMemberSchedSapProvider()
#define NS_LOG_ERROR(msg)
std::map< uint16_t, DlHarqProcessesStatus_t > m_dlHarqProcessesStatus
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.