From c4a84293d0cea5f594cc9de71e8563dab8e8148f Mon Sep 17 00:00:00 2001 From: mmiozzo Date: Mon, 28 Nov 2011 12:32:08 +0100 Subject: [PATCH] Uplink scheduler with multiple bearers (LCs) allocates in a Round Robin fashion the active ones --- src/lte/model/lte-enb-phy.cc | 2 - src/lte/model/lte-ue-mac.cc | 101 +++++++++++++++++++++++++++++------ src/lte/model/lte-ue-mac.h | 16 ++++++ src/lte/model/lte-ue-phy.cc | 3 ++ 4 files changed, 103 insertions(+), 19 deletions(-) diff --git a/src/lte/model/lte-enb-phy.cc b/src/lte/model/lte-enb-phy.cc index fefd16448..f9aae94a8 100644 --- a/src/lte/model/lte-enb-phy.cc +++ b/src/lte/model/lte-enb-phy.cc @@ -397,8 +397,6 @@ LteEnbPhy::StartSubFrame (void) } // trigger the MAC - Ptr macEntity = GetDevice ()->GetObject ()->GetMac (); - m_enbPhySapUser->SubframeIndication (m_nrFrames, m_nrSubFrames); diff --git a/src/lte/model/lte-ue-mac.cc b/src/lte/model/lte-ue-mac.cc index 3457e6db3..cf5431c08 100644 --- a/src/lte/model/lte-ue-mac.cc +++ b/src/lte/model/lte-ue-mac.cc @@ -31,6 +31,7 @@ #include "lte-mac-tag.h" #include #include +#include NS_LOG_COMPONENT_DEFINE ("LteUeMac"); @@ -161,7 +162,7 @@ UeMemberLteUePhySapUser::ReceivePhyPdu (Ptr p) void UeMemberLteUePhySapUser::SubframeIndication (uint32_t frameNo, uint32_t subframeNo) { - NS_LOG_LOGIC (this << " UE-MAC does not yet support this primitive"); + m_mac->DoSubframeIndication (frameNo, subframeNo); } void @@ -189,6 +190,9 @@ LteUeMac::GetTypeId (void) LteUeMac::LteUeMac () + : m_bsrPeriodicity (MilliSeconds (1)), // ideal behavior + m_bsrLast (MilliSeconds (0)) + { NS_LOG_FUNCTION (this); m_macSapProvider = new UeMemberLteMacSapProvider (this); @@ -263,24 +267,51 @@ void LteUeMac::DoReportBufferStatus (LteMacSapProvider::ReportBufferStatusParameters params) { NS_LOG_FUNCTION (this); - MacCeListElement_s bsr; - bsr.m_rnti = m_rnti; - bsr.m_macCeType = MacCeListElement_s::BSR; - // short BSR - int queue = params.txQueueSize; - int index = 0; - if (BufferSizeLevelBsr[63] < queue) + + std::map ::iterator it; + + + it = m_ulBsrReceived.find (params.lcid); + if (it!=m_ulBsrReceived.end ()) { - index = 63; + // update entry + (*it).second = params.txQueueSize + params.retxQueueSize + params.statusPduSize; } else { - while (BufferSizeLevelBsr[index] < queue) - { - index++; - } + m_ulBsrReceived.insert (std::pair (params.lcid, params.txQueueSize + params.retxQueueSize + params.statusPduSize)); + } +} + + +void +LteUeMac::SendReportBufferStatus (void) +{ + NS_LOG_FUNCTION (this); + MacCeListElement_s bsr; + bsr.m_rnti = m_rnti; + bsr.m_macCeType = MacCeListElement_s::BSR; + // BSR + std::map ::iterator it; + NS_ASSERT_MSG (m_ulBsrReceived.size () <=4, " Too many LCs (max is 4)"); + + for (it = m_ulBsrReceived.begin (); it != m_ulBsrReceived.end (); it++) + { + int queue = (*it).second; + int index = 0; + if (BufferSizeLevelBsr[63] < queue) + { + index = 63; + } + else + { + while (BufferSizeLevelBsr[index] < queue) + { + index++; + } + } + bsr.m_macCeValue.m_bufferStatus.push_back (index); } - bsr.m_macCeValue.m_bufferStatus.push_back (index); // create the feedback to eNB Ptr msg = Create (); @@ -336,9 +367,33 @@ LteUeMac::DoReceiveIdealControlMessage (Ptr msg) { Ptr msg2 = DynamicCast (msg); UlDciListElement_s dci = msg2->GetDci (); - std::map ::iterator it; - it = m_macSapUserMap.begin (); // use only the first LC --> UE-SCHEDULER?? - (*it).second->NotifyTxOpportunity (dci.m_tbSize); + std::map ::iterator itBsr; + NS_ASSERT_MSG (m_ulBsrReceived.size () <=4, " Too many LCs (max is 4)"); + int activeLcs = 0; + for (itBsr = m_ulBsrReceived.begin (); itBsr != m_ulBsrReceived.end (); itBsr++) + { + if ((*itBsr).second > 0) + { + activeLcs++; + } + } + if (activeLcs <= 0) + { + NS_LOG_ERROR (this << " No active flows for this UL-DCI"); + return; + } + std::map ::iterator it; + NS_LOG_FUNCTION (this << " UE: UL-CQI notified TxOpportunity of " << dci.m_tbSize); + for (it = m_macSapUserMap.begin (); it!=m_macSapUserMap.end (); it++) + { + itBsr = m_ulBsrReceived.find ((*it).first); + if (itBsr!=m_ulBsrReceived.end ()) + { + NS_LOG_FUNCTION (this << "\t" << dci.m_tbSize / m_macSapUserMap.size () << " bytes to LC " << (uint16_t)(*it).first << " queue " << (*itBsr).second); + (*it).second->NotifyTxOpportunity (dci.m_tbSize / activeLcs); + (*itBsr).second -= dci.m_tbSize / activeLcs; + } + } } else @@ -348,4 +403,16 @@ LteUeMac::DoReceiveIdealControlMessage (Ptr msg) } +void +LteUeMac::DoSubframeIndication (uint32_t frameNo, uint32_t subframeNo) +{ + NS_LOG_FUNCTION (this); + if (Simulator::Now () > m_bsrLast + m_bsrPeriodicity) + { + SendReportBufferStatus (); + m_bsrLast = Simulator::Now (); + } +} + + } // namespace ns3 diff --git a/src/lte/model/lte-ue-mac.h b/src/lte/model/lte-ue-mac.h index 26cba7264..1384af8b9 100644 --- a/src/lte/model/lte-ue-mac.h +++ b/src/lte/model/lte-ue-mac.h @@ -29,6 +29,7 @@ #include #include #include +#include namespace ns3 { @@ -62,6 +63,14 @@ public: * \param s a pointer to the PHY SAP Provider */ void SetLteUePhySapProvider (LteUePhySapProvider* s); + + /** + * \brief Forwarded from LteUePhySapUser: trigger the start from a new frame + * + * \param frameNo frame number + * \param subframeNo subframe number + */ + void DoSubframeIndication (uint32_t frameNo, uint32_t subframeNo); private: // forwarded from MAC SAP @@ -76,6 +85,8 @@ private: // forwarded from PHY SAP void DoReceivePhyPdu (Ptr p); void DoReceiveIdealControlMessage (Ptr msg); + + void SendReportBufferStatus (void); private: // end of temporary hack @@ -87,6 +98,11 @@ private: LteUePhySapProvider* m_uePhySapProvider; LteUePhySapUser* m_uePhySapUser; + + std::map m_ulBsrReceived; // BSR received from RLC (BSR up to now) + + Time m_bsrPeriodicity; + Time m_bsrLast; uint16_t m_rnti; diff --git a/src/lte/model/lte-ue-phy.cc b/src/lte/model/lte-ue-phy.cc index 2f7f074c5..0b98c57b9 100644 --- a/src/lte/model/lte-ue-phy.cc +++ b/src/lte/model/lte-ue-phy.cc @@ -491,6 +491,9 @@ LteUePhy::SubframeIndication (uint32_t frameNo, uint32_t subframeNo) { m_uplinkSpectrumPhy->StartTx (pb); } + + // trigger the MAC + m_uePhySapUser->SubframeIndication (frameNo, subframeNo); }