15#include "ns3/boolean.h" 
   18#include "ns3/pointer.h" 
   19#include "ns3/simulator.h" 
   41    : m_cschedSapUser(nullptr),
 
   42      m_schedSapUser(nullptr),
 
 
   75        TypeId(
"ns3::RrFfMacScheduler")
 
   79            .AddAttribute(
"CqiTimerThreshold",
 
   80                          "The number of TTIs a CQI is valid (default 1000 - 1 sec.)",
 
   84            .AddAttribute(
"HarqEnabled",
 
   85                          "Activate/Deactivate the HARQ [by default is active].",
 
   89            .AddAttribute(
"UlGrantMcs",
 
   90                          "The MCS of the UL grant, must be [0..15] (default 0)",
 
 
  151                         << (uint16_t)params.m_transmissionMode);
 
  155        m_uesTxMode[params.m_rnti] = params.m_transmissionMode;
 
  159        dlHarqPrcStatus.resize(8, 0);
 
  162        dlHarqProcessesTimer.resize(8, 0);
 
  168        dlHarqRlcPdu.resize(2);
 
  169        dlHarqRlcPdu.at(0).resize(8);
 
  170        dlHarqRlcPdu.at(1).resize(8);
 
  174        ulHarqPrcStatus.resize(8, 0);
 
  182        (*it).second = params.m_transmissionMode;
 
 
  199    for (std::size_t i = 0; i < params.m_logicalChannelIdentity.size(); i++)
 
  204            if (((*it).m_rnti == params.m_rnti) &&
 
  205                ((*it).m_logicalChannelIdentity == params.m_logicalChannelIdentity.at(i)))
 
 
  236        if ((*it).m_rnti == params.m_rnti)
 
  238            NS_LOG_INFO(
this << 
" Erase RNTI " << (*it).m_rnti << 
" LC " 
  239                             << (uint16_t)(*it).m_logicalChannelIdentity);
 
 
  269        if (((*it).m_rnti == params.m_rnti) &&
 
  270            ((*it).m_logicalChannelIdentity == params.m_logicalChannelIdentity))
 
  282    NS_LOG_INFO(
this << 
" RNTI " << params.m_rnti << 
" LC " 
  283                     << (uint16_t)params.m_logicalChannelIdentity << 
" RLC tx size " 
  284                     << params.m_rlcTransmissionQueueSize << 
" RLC retx size " 
  285                     << params.m_rlcRetransmissionQueueSize << 
" RLC stat size " 
  286                     << params.m_rlcStatusPduSize);
 
 
  315    for (
int i = 0; i < 4; i++)
 
 
  346        NS_FATAL_ERROR(
"No Process Id Statusfound for this RNTI " << rnti);
 
  348    uint8_t i = (*it).second;
 
  352    } 
while (((*itStat).second.at(i) != 0) && (i != (*it).second));
 
  354    return (*itStat).second.at(i) == 0;
 
 
  375        NS_FATAL_ERROR(
"No Process Id Statusfound for this RNTI " << rnti);
 
  377    uint8_t i = (*it).second;
 
  381    } 
while (((*itStat).second.at(i) != 0) && (i != (*it).second));
 
  382    if ((*itStat).second.at(i) == 0)
 
  385        (*itStat).second.at(i) = 1;
 
 
  409                NS_LOG_INFO(
this << 
" Reset HARQ proc " << i << 
" for RNTI " << (*itTimers).first);
 
  414                                   << (*itTimers).first);
 
  416                (*itStat).second.at(i) = 0;
 
  417                (*itTimers).second.at(i) = 0;
 
  421                (*itTimers).second.at(i)++;
 
 
  431    NS_LOG_FUNCTION(
this << 
" DL Frame no. " << (params.m_sfnSf >> 4) << 
" subframe no. " 
  432                         << (0xF & params.m_sfnSf));
 
  441    std::vector<bool> rbgMap;
 
  442    uint16_t rbgAllocatedNum = 0;
 
  443    std::set<uint16_t> rntiAllocated;
 
  451        (*itProcId).second = ((*itProcId).second + 1) % 
HARQ_PROC_NUM;
 
  456    uint16_t rbStart = 0;
 
  460                          (*itRach).m_estimatedSize,
 
  461                      " Default UL Grant MCS does not allow to send RACH messages");
 
  463        newRar.
m_rnti = (*itRach).m_rnti;
 
  470        uint16_t tbSizeBits = 0;
 
  472        while ((tbSizeBits < (*itRach).m_estimatedSize) &&
 
  478        if (tbSizeBits < (*itRach).m_estimatedSize)
 
  490        NS_LOG_INFO(
this << 
" UL grant allocated to RNTI " << (*itRach).m_rnti << 
" rbStart " 
  491                         << rbStart << 
" rbLen " << rbLen << 
" MCS " << (uint16_t)
m_ulGrantMcs 
  493        for (uint16_t i = rbStart; i < rbStart + rbLen; i++)
 
  526            harqId = (*itProcId).second;
 
  530                NS_FATAL_ERROR(
"Unable to find RNTI entry in UL DCI HARQ buffer for RNTI " 
  533            (*itDci).second.at(harqId) = uldci;
 
  536        rbStart = rbStart + rbLen;
 
  546        if (!params.m_dlInfoList.empty())
 
  550                                        params.m_dlInfoList.begin(),
 
  551                                        params.m_dlInfoList.end());
 
  556        if (!params.m_dlInfoList.empty())
 
  566    std::vector<DlInfoListElement_s> dlInfoListUntxed;
 
  570        if (itRnti != rntiAllocated.end())
 
  576        std::vector<bool> retx;
 
  577        NS_LOG_INFO(
this << 
" Processing DLHARQ feedback");
 
  582            retx.push_back(
false);
 
  591        if (retx.at(0) || retx.at(1))
 
  596            NS_LOG_INFO(
this << 
" HARQ retx RNTI " << rnti << 
" harqId " << (uint16_t)harqId);
 
  605            if (dci.
m_rv.size() == 1)
 
  617                NS_LOG_INFO(
"Max number of retransmissions reached -> drop process");
 
  621                    NS_LOG_ERROR(
"No info find in HARQ buffer for UE (might change eNB) " 
  624                (*it).second.at(harqId) = 0;
 
  628                    NS_FATAL_ERROR(
"Unable to find RlcPdcList in HARQ buffer for RNTI " 
  631                for (std::size_t k = 0; k < (*itRlcPdu).second.size(); k++)
 
  633                    (*itRlcPdu).second.at(k).at(harqId).clear();
 
  639            std::vector<int> dciRbg;
 
  642            for (
int j = 0; j < 32; j++)
 
  652            for (std::size_t j = 0; j < dciRbg.size(); j++)
 
  654                if (rbgMap.at(dciRbg.at(j)))
 
  664                for (std::size_t j = 0; j < dciRbg.size(); j++)
 
  666                    rbgMap.at(dciRbg.at(j)) = 
true;
 
  667                    NS_LOG_INFO(
"RBG " << dciRbg.at(j) << 
" assigned");
 
  671                NS_LOG_INFO(
this << 
" Send retx in the same RBGs");
 
  677                uint8_t rbgId = (dciRbg.at(dciRbg.size() - 1) + 1) % rbgNum;
 
  678                uint8_t startRbg = dciRbg.at(dciRbg.size() - 1);
 
  679                std::vector<bool> rbgMapCopy = rbgMap;
 
  680                while ((j < dciRbg.size()) && (startRbg != rbgId))
 
  682                    if (!rbgMapCopy.at(rbgId))
 
  684                        rbgMapCopy.at(rbgId) = 
true;
 
  685                        dciRbg.at(j) = rbgId;
 
  688                    rbgId = (rbgId + 1) % rbgNum;
 
  690                if (j == dciRbg.size())
 
  694                    for (std::size_t k = 0; k < dciRbg.size(); k++)
 
  696                        rbgMask = rbgMask + (0x1 << dciRbg.at(k));
 
  697                        NS_LOG_INFO(
this << 
" New allocated RBG " << dciRbg.at(k));
 
  707                    NS_LOG_INFO(
this << 
" No resource for this retx -> buffer it");
 
  715                NS_FATAL_ERROR(
"Unable to find RlcPdcList in HARQ buffer for RNTI " << rnti);
 
  717            for (std::size_t j = 0; j < nLayers; j++)
 
  721                    if (j >= dci.
m_ndi.size())
 
  724                        dci.
m_ndi.push_back(0);
 
  725                        dci.
m_rv.push_back(0);
 
  726                        dci.
m_mcs.push_back(0);
 
  729                                         << 
" no txed (MIMO transition)");
 
  735                        (*itHarq).second.at(harqId).m_rv.at(j)++;
 
  736                        NS_LOG_INFO(
this << 
" layer " << (uint16_t)j << 
" RV " 
  737                                         << (uint16_t)dci.
m_rv.at(j));
 
  747                    NS_LOG_INFO(
this << 
" layer " << (uint16_t)j << 
" no retx");
 
  751            for (std::size_t k = 0; k < (*itRlcPdu).second.at(0).at(dci.
m_harqProcess).size(); k++)
 
  753                std::vector<RlcPduListElement_s> rlcPduListPerLc;
 
  754                for (std::size_t j = 0; j < nLayers; j++)
 
  758                        if (j < dci.
m_ndi.size())
 
  760                            NS_LOG_INFO(
" layer " << (uint16_t)j << 
" tb size " 
  762                            rlcPduListPerLc.push_back(
 
  775                                                                    .m_logicalChannelIdentity;
 
  777                        rlcPduListPerLc.push_back(emptyElement);
 
  781                if (!rlcPduListPerLc.empty())
 
  788            (*itHarq).second.at(harqId).
m_rv = dci.
m_rv;
 
  793                NS_FATAL_ERROR(
"Unable to find HARQ timer for RNTI " << (uint16_t)rnti);
 
  795            (*itHarqTimer).second.at(harqId) = 0;
 
  797            rntiAllocated.insert(rnti);
 
  814                NS_FATAL_ERROR(
"Unable to find RlcPdcList in HARQ buffer for RNTI " 
  817            for (std::size_t k = 0; k < (*itRlcPdu).second.size(); k++)
 
  826    if (rbgAllocatedNum == rbgNum)
 
  837    std::list<FfMacSchedSapProvider::SchedDlRlcBufferReqParameters>::iterator it;
 
  841    std::map<uint16_t, uint8_t> lcActivesPerRnti; 
 
  845        auto itRnti = rntiAllocated.find((*it).m_rnti);
 
  846        if ((((*it).m_rlcTransmissionQueueSize > 0) || ((*it).m_rlcRetransmissionQueueSize > 0) ||
 
  847             ((*it).m_rlcStatusPduSize > 0)) &&
 
  848            (itRnti == rntiAllocated.end())             
 
  853                              << (uint16_t)(*it).m_logicalChannelIdentity << 
" is active, status  " 
  854                              << (*it).m_rlcStatusPduSize << 
" retx " 
  855                              << (*it).m_rlcRetransmissionQueueSize << 
" tx " 
  856                              << (*it).m_rlcTransmissionQueueSize);
 
  861                cqi = (*itCqi).second;
 
  871                auto itLcRnti = lcActivesPerRnti.find((*it).m_rnti);
 
  872                if (itLcRnti != lcActivesPerRnti.end())
 
  874                    (*itLcRnti).second++;
 
  878                    lcActivesPerRnti[(*it).m_rnti] = 1;
 
  896    int rbgPerTb = (nTbs > 0) ? ((rbgNum - rbgAllocatedNum) / nTbs) : INT_MAX;
 
  897    NS_LOG_INFO(
this << 
" Flows to be transmitted " << nflows << 
" rbgPerTb " << rbgPerTb);
 
  902    int rbgAllocated = 0;
 
  936        auto itLcRnti = lcActivesPerRnti.find((*it).m_rnti);
 
  937        auto itRnti = rntiAllocated.find((*it).m_rnti);
 
  938        if ((itLcRnti == lcActivesPerRnti.end()) || (itRnti != rntiAllocated.end()))
 
  941            uint16_t rntiDiscarded = (*it).m_rnti;
 
  944                if ((*it).m_rnti != rntiDiscarded)
 
  960            NS_FATAL_ERROR(
"No Transmission Mode info on user " << (*it).m_rnti);
 
  963        int lcNum = (*itLcRnti).second;
 
  966        newEl.
m_rnti = (*it).m_rnti;
 
  969        newDci.
m_rnti = (*it).m_rnti;
 
  974        for (uint8_t i = 0; i < nLayer; i++)
 
  978                newDci.
m_mcs.push_back(0); 
 
  982                newDci.
m_mcs.push_back(
m_amc->GetMcsFromCqi((*itCqi).second));
 
  985        int tbSize = (
m_amc->GetDlTbSizeFromMcs(newDci.
m_mcs.at(0), rbgPerTb * rbgSize) / 8);
 
  986        uint16_t rlcPduSize = tbSize / lcNum;
 
  987        while ((*it).m_rnti == newEl.
m_rnti)
 
  989            if (((*it).m_rlcTransmissionQueueSize > 0) ||
 
  990                ((*it).m_rlcRetransmissionQueueSize > 0) || ((*it).m_rlcStatusPduSize > 0))
 
  992                std::vector<RlcPduListElement_s> newRlcPduLe;
 
  993                for (uint8_t j = 0; j < nLayer; j++)
 
  998                                     << 
" size " << rlcPduSize << 
" ID " << (*it).m_rnti
 
  999                                     << 
" layer " << (uint16_t)j);
 
 1000                    newRlcEl.
m_size = rlcPduSize;
 
 1004                    newRlcPduLe.push_back(newRlcEl);
 
 1012                            NS_FATAL_ERROR(
"Unable to find RlcPdcList in HARQ buffer for RNTI " 
 1015                        (*itRlcPdu).second.at(j).at(newDci.
m_harqProcess).push_back(newRlcEl);
 
 1032                         << (uint16_t)(*itLcRnti).second << 
" bytes " << tbSize << 
" mcs " 
 1033                         << (uint16_t)newDci.
m_mcs.at(0) << 
" harqId " 
 1036        while (i < rbgPerTb)
 
 1038            if (!rbgMap.at(rbgAllocated))
 
 1040                rbgMask = rbgMask + (0x1 << rbgAllocated);
 
 1043                rbgMap.at(rbgAllocated) = 
true;
 
 1050        for (std::size_t i = 0; i < nLayer; i++)
 
 1053            newDci.
m_ndi.push_back(1);
 
 1054            newDci.
m_rv.push_back(0);
 
 1059        newEl.
m_dci = newDci;
 
 1066                NS_FATAL_ERROR(
"Unable to find RNTI entry in DCI HARQ buffer for RNTI " 
 1081        if (rbgAllocatedNum == rbgNum)
 
 
 1108    for (
unsigned int i = 0; i < params.m_cqiList.size(); i++)
 
 1114            uint16_t rnti = params.m_cqiList.at(i).m_rnti;
 
 1120                    params.m_cqiList.at(i).m_wbCqi.at(0); 
 
 1127                (*it).second = params.m_cqiList.at(i).m_wbCqi.at(0);
 
 
 1149    NS_LOG_FUNCTION(
this << 
" UL - Frame no. " << (params.m_sfnSf >> 4) << 
" subframe no. " 
 1150                         << (0xF & params.m_sfnSf) << 
" size " << params.m_ulInfoList.size());
 
 1156    std::vector<bool> rbMap;
 
 1157    std::set<uint16_t> rntiAllocated;
 
 1158    std::vector<uint16_t> rbgAllocationMap;
 
 1169        if (rbgAllocationMap.at(i) != 0)
 
 1179        for (std::size_t i = 0; i < params.m_ulInfoList.size(); i++)
 
 1184                uint16_t rnti = params.m_ulInfoList.at(i).m_rnti;
 
 1188                    NS_LOG_ERROR(
"No info find in HARQ buffer for UE (might change eNB) " << rnti);
 
 1191                NS_LOG_INFO(
this << 
" UL-HARQ retx RNTI " << rnti << 
" harqId " 
 1192                                 << (uint16_t)harqId);
 
 1196                    NS_LOG_ERROR(
"No info find in UL-HARQ buffer for UE (might change eNB) " 
 1203                    NS_LOG_ERROR(
"No info find in HARQ buffer for UE (might change eNB) " << rnti);
 
 1205                if ((*itStat).second.at(harqId) >= 3)
 
 1207                    NS_LOG_INFO(
"Max number of retransmissions reached (UL)-> drop process");
 
 1225                        rbgAllocationMap.at(j) = dci.
m_rnti;
 
 1230                                     << (*itStat).second.at(harqId) + 1);
 
 1234                    NS_LOG_INFO(
"Cannot allocate retx due to RACH allocations for UE " << rnti);
 
 1239                (*itStat).second.at((*itProcId).second) = (*itStat).second.at(harqId) + 1;
 
 1240                (*itStat).second.at(harqId) = 0;
 
 1241                (*itHarq).second.at((*itProcId).second) = dci;
 
 1243                rntiAllocated.insert(dci.
m_rnti);
 
 1248    std::map<uint16_t, uint32_t>::iterator it;
 
 1253        auto itRnti = rntiAllocated.find((*it).first);
 
 1255        NS_LOG_INFO(
this << 
" UE " << (*it).first << 
" queue " << (*it).second);
 
 1256        if (((*it).second > 0) && (itRnti == rntiAllocated.end()))
 
 1280    uint16_t rbAllocated = 0;
 
 1301    NS_LOG_INFO(
this << 
" NFlows " << nflows << 
" RB per Flow " << rbPerFlow);
 
 1304        auto itRnti = rntiAllocated.find((*it).first);
 
 1305        if ((itRnti != rntiAllocated.end()) || ((*it).second == 0))
 
 1327        NS_LOG_INFO(
this << 
" try to allocate " << (*it).first);
 
 1329        uldci.
m_rnti = (*it).first;
 
 1331        bool allocated = 
false;
 
 1332        NS_LOG_INFO(
this << 
" RB Allocated " << rbAllocated << 
" rbPerFlow " << rbPerFlow
 
 1333                         << 
" flows " << nflows);
 
 1339            for (
int j = rbAllocated; j < rbAllocated + rbPerFlow; j++)
 
 1351                for (
int j = rbAllocated; j < rbAllocated + rbPerFlow; j++)
 
 1355                    rbgAllocationMap.at(j) = (*it).first;
 
 1358                rbAllocated += rbPerFlow;
 
 1386        auto itCqi = 
m_ueCqi.find((*it).first);
 
 1392            NS_LOG_INFO(
this << 
" UE does not have ULCQI " << (*it).first);
 
 1398                            "CQI of RNTI = " << (*it).first << 
" has expired");
 
 1399            double minSinr = (*itCqi).second.at(uldci.
m_rbStart);
 
 1402                if ((*itCqi).second.at(i) < minSinr)
 
 1404                    minSinr = (*itCqi).second.at(i);
 
 1408            double s = log2(1 + (std::pow(10, minSinr / 10) / ((-std::log(5.0 * 0.00005)) / 1.5)));
 
 1410            cqi = 
m_amc->GetCqiFromSpectralEfficiency(s);
 
 1423                    rbgAllocationMap.at(i) = 0;
 
 1430            (
m_amc->GetUlTbSizeFromMcs(uldci.
m_mcs, rbPerFlow) / 8); 
 
 1455            harqId = (*itProcId).second;
 
 1459                NS_FATAL_ERROR(
"Unable to find RNTI entry in UL DCI HARQ buffer for RNTI " 
 1462            (*itDci).second.at(harqId) = uldci;
 
 1467                NS_LOG_ERROR(
"No info find in HARQ buffer for UE (might change eNB) " 
 1470            (*itStat).second.at(harqId) = 0;
 
 1473        NS_LOG_INFO(
this << 
" UL Allocation - UE " << (*it).first << 
" startPRB " 
 1475                         << 
" CQI " << cqi << 
" MCS " << (
uint32_t)uldci.
m_mcs << 
" TBsize " 
 1476                         << uldci.
m_tbSize << 
" harqId " << (uint16_t)harqId);
 
 1490    } 
while (((*it).first != 
m_nextRntiUl) && (rbPerFlow != 0));
 
 
 1517    for (
unsigned int i = 0; i < params.m_macCeList.size(); i++)
 
 1529            for (uint8_t lcg = 0; lcg < 4; ++lcg)
 
 1531                uint8_t bsrId = params.m_macCeList.at(i).m_macCeValue.m_bufferStatus.at(lcg);
 
 1535            uint16_t rnti = params.m_macCeList.at(i).m_rnti;
 
 1541                NS_LOG_INFO(
this << 
" Insert RNTI " << rnti << 
" queue " << buffer);
 
 1546                (*it).second = buffer;
 
 1547                NS_LOG_INFO(
this << 
" Update RNTI " << rnti << 
" queue " << buffer);
 
 
 1580    switch (params.m_ulCqi.m_type)
 
 1586            NS_LOG_INFO(
this << 
" Does not find info on allocation, size : " 
 1590        for (
uint32_t i = 0; i < (*itMap).second.size(); i++)
 
 1594            auto itCqi = 
m_ueCqi.find((*itMap).second.at(i));
 
 1598                std::vector<double> newCqi;
 
 1603                        newCqi.push_back(sinr);
 
 1608                        newCqi.push_back(30.0);
 
 1611                m_ueCqi[(*itMap).second.at(i)] = newCqi;
 
 1618                (*itCqi).second.at(i) = sinr;
 
 1631        NS_ASSERT(!params.m_vendorSpecificList.empty());
 
 1632        for (std::size_t i = 0; i < params.m_vendorSpecificList.size(); i++)
 
 1638                rnti = vsp->GetRnti();
 
 1641        auto itCqi = 
m_ueCqi.find(rnti);
 
 1645            std::vector<double> newCqi;
 
 1649                newCqi.push_back(sinr);
 
 1650                NS_LOG_INFO(
this << 
" RNTI " << rnti << 
" new SRS-CQI for RB  " << j << 
" value " 
 1663                (*itCqi).second.at(j) = sinr;
 
 1664                NS_LOG_INFO(
this << 
" RNTI " << rnti << 
" update SRS-CQI for RB  " << j << 
" value " 
 1676        NS_FATAL_ERROR(
"PfFfMacScheduler supports only PUSCH and SRS UL-CQIs");
 
 
 1692        NS_LOG_INFO(
this << 
" P10-CQI for user " << (*itP10).first << 
" is " 
 1694        if ((*itP10).second == 0)
 
 1699                          " Does not find CQI report for user " << (*itP10).first);
 
 1700            NS_LOG_INFO(
this << 
" P10-CQI exired for user " << (*itP10).first);
 
 
 1721        NS_LOG_INFO(
this << 
" UL-CQI for user " << (*itUl).first << 
" is " 
 1723        if ((*itUl).second == 0)
 
 1726            auto itMap = 
m_ueCqi.find((*itUl).first);
 
 1728                          " Does not find CQI report for user " << (*itUl).first);
 
 1729            NS_LOG_INFO(
this << 
" UL-CQI exired for user " << (*itUl).first);
 
 1730            (*itMap).second.clear();
 
 
 1750        if (((*it).m_rnti == rnti) && ((*it).m_logicalChannelIdentity == lcid))
 
 1752            NS_LOG_INFO(
this << 
" UE " << rnti << 
" LC " << (uint16_t)lcid << 
" txqueue " 
 1753                             << (*it).m_rlcTransmissionQueueSize << 
" retxqueue " 
 1754                             << (*it).m_rlcRetransmissionQueueSize << 
" status " 
 1755                             << (*it).m_rlcStatusPduSize << 
" decrease " << size);
 
 1758            if (((*it).m_rlcStatusPduSize > 0) && (size >= (*it).m_rlcStatusPduSize))
 
 1760                (*it).m_rlcStatusPduSize = 0;
 
 1762            else if (((*it).m_rlcRetransmissionQueueSize > 0) &&
 
 1763                     (size >= (*it).m_rlcRetransmissionQueueSize))
 
 1765                (*it).m_rlcRetransmissionQueueSize = 0;
 
 1767            else if ((*it).m_rlcTransmissionQueueSize > 0)
 
 1784                if ((*it).m_rlcTransmissionQueueSize <= size - rlcOverhead)
 
 1786                    (*it).m_rlcTransmissionQueueSize = 0;
 
 1790                    (*it).m_rlcTransmissionQueueSize -= size - rlcOverhead;
 
 
 1805        NS_LOG_INFO(
this << 
" Update RLC BSR UE " << rnti << 
" size " << size << 
" BSR " 
 1807        if ((*it).second >= size)
 
 1809            (*it).second -= size;
 
 1818        NS_LOG_ERROR(
this << 
" Does not find BSR report info of UE " << rnti);
 
 
 1825    NS_LOG_FUNCTION(
this << 
" RNTI " << rnti << 
" txMode " << (uint16_t)txMode);
 
 1827    params.m_rnti = rnti;
 
 1828    params.m_transmissionMode = txMode;
 
 
AttributeValue implementation for Boolean.
static uint32_t BsrId2BufferSize(uint8_t val)
Convert BSR ID to buffer size.
FfMacCschedSapUser class.
virtual void CschedUeConfigCnf(const CschedUeConfigCnfParameters ¶ms)=0
CSCHED_UE_CONFIG_CNF.
virtual void CschedUeConfigUpdateInd(const CschedUeConfigUpdateIndParameters ¶ms)=0
CSCHED_UE_UPDATE_IND.
virtual void SchedUlConfigInd(const SchedUlConfigIndParameters ¶ms)=0
SCHED_UL_CONFIG_IND.
virtual void SchedDlConfigInd(const SchedDlConfigIndParameters ¶ms)=0
SCHED_DL_CONFIG_IND.
This abstract base class identifies the interface by means of which the helper object can plug on the...
UlCqiFilter_t m_ulCqiFilter
UL CQI filter.
static double fpS11dot3toDouble(uint16_t val)
Convert from fixed point S11.3 notation to double.
Service Access Point (SAP) offered by the Frequency Reuse algorithm instance to the MAC Scheduler ins...
Service Access Point (SAP) offered by the eNodeB RRC instance to the Frequency Reuse algorithm instan...
Smart pointer class similar to boost::intrusive_ptr.
Implements the SCHED SAP and CSCHED SAP for a Round Robin scheduler.
friend class MemberCschedSapProvider< RrFfMacScheduler >
allow MemberCschedSapProvider<RrFfMacScheduler> class friend access
std::map< uint16_t, std::vector< uint16_t > > m_allocationMaps
Map of previous allocated UE per RBG (used to retrieve info from UL-CQI)
void DoSchedDlRlcBufferReq(const FfMacSchedSapProvider::SchedDlRlcBufferReqParameters ¶ms)
Sched DL RLC buffer request.
void DoSchedUlCqiInfoReq(const FfMacSchedSapProvider::SchedUlCqiInfoReqParameters ¶ms)
Sched UL CQI info request.
std::map< uint16_t, uint8_t > m_uesTxMode
txMode of the UEs
bool HarqProcessAvailability(uint16_t rnti)
Return the availability of free process for the RNTI specified.
RrFfMacScheduler()
Constructor.
void DoSchedDlTriggerReq(const FfMacSchedSapProvider::SchedDlTriggerReqParameters ¶ms)
Sched DL trigger request.
friend class MemberSchedSapProvider< RrFfMacScheduler >
allow MemberSchedSapProvider<RrFfMacScheduler> class friend access
void DoCschedLcReleaseReq(const FfMacCschedSapProvider::CschedLcReleaseReqParameters ¶ms)
CSched LC release request.
std::map< uint16_t, DlHarqProcessesStatus_t > m_dlHarqProcessesStatus
DL HARQ process status.
void DoCschedLcConfigReq(const FfMacCschedSapProvider::CschedLcConfigReqParameters ¶ms)
CSched LC config request.
void DoSchedUlSrInfoReq(const FfMacSchedSapProvider::SchedUlSrInfoReqParameters ¶ms)
Sched UL SRS info request.
~RrFfMacScheduler() override
Destructor.
std::map< uint16_t, uint8_t > m_p10CqiRxed
Map of UE's DL CQI P01 received.
FfMacSchedSapUser * m_schedSapUser
Sched SAP user.
FfMacSchedSapProvider * m_schedSapProvider
Sched SAP provider.
void SetFfMacCschedSapUser(FfMacCschedSapUser *s) override
set the user part of the FfMacCschedSap that this Scheduler will interact with.
void DoCschedUeConfigReq(const FfMacCschedSapProvider::CschedUeConfigReqParameters ¶ms)
CSched UE config request.
std::map< uint16_t, uint32_t > m_ceBsrRxed
Map of UE's buffer status reports received.
uint8_t UpdateHarqProcessId(uint16_t rnti)
Update and return a new process Id for the RNTI specified.
LteFfrSapUser * m_ffrSapUser
FFR SAP user.
uint32_t m_cqiTimersThreshold
LteFfrSapUser * GetLteFfrSapUser() override
std::map< uint16_t, DlHarqProcessesTimer_t > m_dlHarqProcessesTimer
DL HARQ process timer.
void DoSchedUlMacCtrlInfoReq(const FfMacSchedSapProvider::SchedUlMacCtrlInfoReqParameters ¶ms)
Sched UL MAC control info request.
void UpdateDlRlcBufferInfo(uint16_t rnti, uint8_t lcid, uint16_t size)
Update DL RLC buffer info function.
void DoSchedUlTriggerReq(const FfMacSchedSapProvider::SchedUlTriggerReqParameters ¶ms)
Sched UL trigger request.
void DoSchedUlNoiseInterferenceReq(const FfMacSchedSapProvider::SchedUlNoiseInterferenceReqParameters ¶ms)
Sched UL noise interference request.
std::vector< uint16_t > m_rachAllocationMap
RACH allocation map.
std::map< uint16_t, uint32_t > m_p10CqiTimers
Map of UE's timers on DL CQI P01 received.
LteFfrSapProvider * m_ffrSapProvider
FFR SAP provider.
FfMacCschedSapProvider * m_cschedSapProvider
CSched SAP provider.
int GetRbgSize(int dlbandwidth)
Get RBG size function.
void DoSchedDlMacBufferReq(const FfMacSchedSapProvider::SchedDlMacBufferReqParameters ¶ms)
Sched DL MAC buffer request.
std::map< uint16_t, DlHarqProcessesDciBuffer_t > m_dlHarqProcessesDciBuffer
DL HARQ process DCI buffer.
FfMacCschedSapUser * m_cschedSapUser
CSched SAP user.
std::map< uint16_t, uint8_t > m_dlHarqCurrentProcessId
DL HARQ current process ID.
std::map< uint16_t, std::vector< double > > m_ueCqi
Map of UEs' UL-CQI per RBG.
void DoCschedUeReleaseReq(const FfMacCschedSapProvider::CschedUeReleaseReqParameters ¶ms)
CSched UE release request.
std::list< FfMacSchedSapProvider::SchedDlRlcBufferReqParameters > m_rlcBufferReq
Vectors of UE's RLC info.
std::map< uint16_t, UlHarqProcessesStatus_t > m_ulHarqProcessesStatus
UL HARQ process status.
uint16_t m_nextRntiDl
RNTI of the next user to be served next scheduling in DL.
FfMacCschedSapProvider::CschedCellConfigReqParameters m_cschedCellConfig
CSched cell config.
std::vector< RachListElement_s > m_rachList
RACH list.
static bool SortRlcBufferReq(FfMacSchedSapProvider::SchedDlRlcBufferReqParameters i, FfMacSchedSapProvider::SchedDlRlcBufferReqParameters j)
Sort RLC buffer request function.
void RefreshHarqProcesses()
Refresh HARQ processes according to the timers.
void RefreshDlCqiMaps()
Refresh DL CQI maps function.
std::map< uint16_t, DlHarqRlcPduListBuffer_t > m_dlHarqProcessesRlcPduListBuffer
DL HARQ process RLC PDU list buffer.
FfMacCschedSapProvider * GetFfMacCschedSapProvider() override
void SetLteFfrSapProvider(LteFfrSapProvider *s) override
Set the Provider part of the LteFfrSap that this Scheduler will interact with.
bool m_harqOn
m_harqOn when false inhibit the HARQ mechanisms (by default active)
void DoSchedDlCqiInfoReq(const FfMacSchedSapProvider::SchedDlCqiInfoReqParameters ¶ms)
Sched DL CQI info request.
void DoCschedCellConfigReq(const FfMacCschedSapProvider::CschedCellConfigReqParameters ¶ms)
CSched cell config request.
void TransmissionModeConfigurationUpdate(uint16_t rnti, uint8_t txMode)
Transmission mode configuration update function.
uint8_t m_ulGrantMcs
MCS for UL grant (default 0)
static TypeId GetTypeId()
Get the type ID.
std::map< uint16_t, uint32_t > m_ueCqiTimers
Map of UEs' timers on UL-CQI per RBG.
std::map< uint16_t, uint8_t > m_ulHarqCurrentProcessId
UL HARQ current process ID.
void DoSchedDlPagingBufferReq(const FfMacSchedSapProvider::SchedDlPagingBufferReqParameters ¶ms)
Sched DL paging buffer request.
std::vector< DlInfoListElement_s > m_dlInfoListBuffered
HARQ retx buffered.
std::map< uint16_t, UlHarqProcessesDciBuffer_t > m_ulHarqProcessesDciBuffer
UL HARQ process DCI buffer.
void SetFfMacSchedSapUser(FfMacSchedSapUser *s) override
set the user part of the FfMacSchedSap that this Scheduler will interact with.
FfMacSchedSapProvider * GetFfMacSchedSapProvider() override
void RefreshUlCqiMaps()
Refresh UL CQI maps function.
void DoSchedDlRachInfoReq(const FfMacSchedSapProvider::SchedDlRachInfoReqParameters ¶ms)
Sched DL RACH info request.
void DoDispose() override
Destructor implementation.
void UpdateUlRlcBufferInfo(uint16_t rnti, uint16_t size)
Update UL RLC buffer info function.
uint16_t m_nextRntiUl
RNTI of the next user to be served next scheduling in UL.
static uint8_t TxMode2LayerNum(uint8_t txMode)
Transmit mode 2 layer number.
a unique identifier for an interface.
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Hold an unsigned integer type.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Ptr< const AttributeChecker > MakeBooleanChecker()
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Ptr< const AttributeChecker > MakeUintegerChecker()
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
#define NS_LOG_ERROR(msg)
Use NS_LOG to output a message of level LOG_ERROR.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
std::vector< uint8_t > DlHarqProcessesTimer_t
DL HARQ process timer vector.
std::vector< uint8_t > UlHarqProcessesStatus_t
UL HARQ process status vector.
std::vector< uint8_t > DlHarqProcessesStatus_t
DL HARQ process status vector.
Ptr< T1 > DynamicCast(const Ptr< T2 > &p)
Cast a Ptr.
std::vector< DlDciListElement_s > DlHarqProcessesDciBuffer_t
DL HARQ process DCI buffer vector.
constexpr uint32_t HARQ_DL_TIMEOUT
HARQ DL timeout.
constexpr uint32_t HARQ_PROC_NUM
Number of HARQ processes.
std::vector< RlcPduList_t > DlHarqRlcPduListBuffer_t
Vector of the 8 HARQ processes per UE.
std::vector< UlDciListElement_s > UlHarqProcessesDciBuffer_t
UL HARQ process DCI buffer vector.
static const int Type0AllocationRbg[4]
Type 0 RBG allocation (see table 7.1.6.1-1 of 3GPP TS 36.213)
See section 4.3.8 buildDataListElement.
std::vector< std::vector< struct RlcPduListElement_s > > m_rlcPduList
RLC PDU list.
struct DlDciListElement_s m_dci
DCI.
See section 4.3.10 buildRARListElement.
See section 4.3.1 dlDciListElement.
std::vector< uint8_t > m_ndi
New data indicator.
uint8_t m_harqProcess
HARQ process.
uint32_t m_rbBitmap
RB bitmap.
std::vector< uint8_t > m_mcs
MCS.
uint8_t m_resAlloc
The type of resource allocation.
std::vector< uint16_t > m_tbsSize
The TBs size.
std::vector< uint8_t > m_rv
Redundancy version.
uint8_t m_tpc
Tx power control command.
Parameters of the API primitives.
uint16_t m_dlBandwidth
DL bandwidth.
uint16_t m_ulBandwidth
UL bandwidth.
Parameters of the CSCHED_LC_CONFIG_REQ primitive.
Parameters of the CSCHED_LC_RELEASE_REQ primitive.
Parameters of the CSCHED_UE_CONFIG_REQ primitive.
Parameters of the CSCHED_UE_RELEASE_REQ primitive.
Parameters of the CSCHED_UE_CONFIG_CNF primitive.
Parameters of the CSCHED_UE_CONFIG_UPDATE_IND primitive.
Parameters of the SCHED_DL_CQI_INFO_REQ primitive.
Parameters of the SCHED_DL_MAC_BUFFER_REQ primitive.
Parameters of the SCHED_DL_PAGING_BUFFER_REQ primitive.
Parameters of the SCHED_DL_RACH_INFO_REQ primitive.
Parameters of the API primitives.
Parameters of the SCHED_DL_TRIGGER_REQ primitive.
Parameters of the SCHED_UL_CQI_INFO_REQ primitive.
Parameters of the SCHED_UL_MAC_CTRL_INFO_REQ primitive.
Parameters of the SCHED_UL_NOISE_INTERFERENCE_REQ primitive.
Parameters of the SCHED_UL_SR_INFO_REQ primitive.
Parameters of the SCHED_UL_TRIGGER_REQ primitive.
Parameters of the API primitives.
std::vector< BuildDataListElement_s > m_buildDataList
build data list
std::vector< BuildRarListElement_s > m_buildRarList
build rar list
uint8_t m_nrOfPdcchOfdmSymbols
number of PDCCH OFDM symbols
Parameters of the SCHED_UL_CONFIG_IND primitive.
std::vector< UlDciListElement_s > m_dciList
DCI list.
See section 4.3.9 rlcPDU_ListElement.
uint8_t m_logicalChannelIdentity
logical channel identity
See section 4.3.2 ulDciListElement.
int8_t m_pdcchPowerOffset
CCH power offset.
int8_t m_tpc
Tx power control command.
uint8_t m_dai
DL assignment index.
uint8_t m_cceIndex
Control Channel Element index.
uint8_t m_ulIndex
UL index.
uint8_t m_ueTxAntennaSelection
UE antenna selection.
bool m_cqiRequest
CQI request.
uint8_t m_freqHopping
freq hopping
uint8_t m_aggrLevel
The aggregation level.
int8_t m_tpc
Tx power control command.
bool m_cqiRequest
CQI request?