diff -r cd0669085267 -r e9a27a8c6331 src/lte/model/lte-ue-mac.cc --- a/src/lte/model/lte-ue-mac.cc Mon Nov 28 12:30:41 2011 +0100 +++ b/src/lte/model/lte-ue-mac.cc Mon Nov 28 12:32:08 2011 +0100 @@ -31,6 +31,7 @@ #include "lte-mac-tag.h" #include #include +#include NS_LOG_COMPONENT_DEFINE ("LteUeMac"); @@ -161,7 +162,7 @@ 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::LteUeMac () + : m_bsrPeriodicity (MilliSeconds (1)), // ideal behavior + m_bsrLast (MilliSeconds (0)) + { NS_LOG_FUNCTION (this); m_macSapProvider = new UeMemberLteMacSapProvider (this); @@ -263,24 +267,51 @@ LteUeMac::DoReportBufferStatus (LteMacSapProvider::ReportBufferStatusParameters params) { NS_LOG_FUNCTION (this); + + std::map ::iterator it; + + + it = m_ulBsrReceived.find (params.lcid); + if (it!=m_ulBsrReceived.end ()) + { + // update entry + (*it).second = params.txQueueSize + params.retxQueueSize + params.statusPduSize; + } + else + { + 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; - // short BSR - int queue = params.txQueueSize; - int index = 0; - if (BufferSizeLevelBsr[63] < queue) + // 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++) { - index = 63; + 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); } - else - { - while (BufferSizeLevelBsr[index] < queue) - { - index++; - } - } - bsr.m_macCeValue.m_bufferStatus.push_back (index); // create the feedback to eNB Ptr msg = Create (); @@ -336,9 +367,33 @@ { 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 @@ } +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