25 #include <ns3/pointer.h>
26 #include <ns3/packet.h>
27 #include <ns3/packet-burst.h>
28 #include <ns3/random-variable.h>
33 #include <ns3/ff-mac-common.h>
34 #include <ns3/lte-control-messages.h>
35 #include <ns3/simulator.h>
36 #include <ns3/lte-common.h>
62 virtual void RemoveLc (uint8_t lcId);
63 virtual void Reset ();
198 .AddConstructor<LteUeMac> ();
204 : m_bsrPeriodicity (MilliSeconds (1)),
205 m_bsrLast (MilliSeconds (0)),
206 m_freshUlBsr (false),
209 m_rachConfigured (false),
210 m_waitingForRaResponse (false)
296 std::map <uint8_t, LteMacSapProvider::ReportBufferStatusParameters>::iterator it;
303 (*it).second = params;
307 m_ulBsrReceived.insert (std::pair<uint8_t, LteMacSapProvider::ReportBufferStatusParameters> (params.
lcid, params));
334 std::map <uint8_t, LteMacSapProvider::ReportBufferStatusParameters>::iterator it;
335 std::vector<uint32_t> queue (4, 0);
338 uint8_t lcid = it->first;
339 std::map <uint8_t, LcInfo>::iterator lcInfoMapIt;
342 uint8_t lcg = lcInfoMapIt->second.lcConfig.logicalChannelGroup;
343 queue.at (lcg) += ((*it).second.txQueueSize + (*it).second.retxQueueSize + (*it).second.statusPduSize);
367 bool contention =
true;
387 Time raWindowBegin = MilliSeconds (3);
425 NS_LOG_INFO (
"RAR timeout, preambleTransMax reached => giving up");
466 NS_ASSERT_MSG (prachMask == 0,
"requested PRACH MASK = " << (uint32_t) prachMask <<
", but only PRACH MASK = 0 is supported");
469 bool contention =
false;
481 lcInfo.macSapUser = msu;
497 std::map <uint8_t, LcInfo>::iterator it =
m_lcInfoMap.begin ();
526 it->second.macSapUser->ReceivePdu (p);
545 std::map <uint8_t, LteMacSapProvider::ReportBufferStatusParameters>::iterator itBsr;
546 uint16_t activeLcs = 0;
547 uint32_t statusPduMinSize = 0;
550 if (((*itBsr).second.statusPduSize > 0) || ((*itBsr).second.retxQueueSize > 0) || ((*itBsr).second.txQueueSize > 0))
553 if (((*itBsr).second.statusPduSize!=0)&&((*itBsr).second.statusPduSize < statusPduMinSize))
555 statusPduMinSize = (*itBsr).second.statusPduSize;
557 if (((*itBsr).second.statusPduSize!=0)&&(statusPduMinSize == 0))
559 statusPduMinSize = (*itBsr).second.statusPduSize;
565 NS_LOG_ERROR (
this <<
" No active flows for this UL-DCI");
568 std::map <uint8_t, LcInfo>::iterator it;
569 uint32_t bytesPerActiveLc = dci.m_tbSize / activeLcs;
570 bool statusPduPriority =
false;
571 if ((statusPduMinSize != 0)&&(bytesPerActiveLc < statusPduMinSize))
574 statusPduPriority =
true;
575 NS_LOG_DEBUG (
this <<
" Reduced resource -> send only Status, b ytes " << statusPduMinSize);
576 if (dci.m_tbSize < statusPduMinSize)
578 NS_FATAL_ERROR (
"Insufficient Tx Opportunity for sending a status message");
581 NS_LOG_LOGIC (
this <<
" UE " <<
m_rnti <<
": UL-CQI notified TxOpportunity of " << dci.m_tbSize <<
" => " << bytesPerActiveLc <<
" bytes per active LC" <<
" statusPduMinSize " << statusPduMinSize);
585 NS_LOG_DEBUG (
this <<
" Processing LC " << (uint32_t)(*it).first <<
" bytesPerActiveLc " << bytesPerActiveLc);
587 ( ((*itBsr).second.statusPduSize > 0) ||
588 ((*itBsr).second.retxQueueSize > 0) ||
589 ((*itBsr).second.txQueueSize > 0)) )
591 if ((statusPduPriority) && ((*itBsr).second.statusPduSize == statusPduMinSize))
593 (*it).second.macSapUser->NotifyTxOpportunity ((*itBsr).second.statusPduSize, 0, 0);
594 NS_LOG_LOGIC (
this <<
"\t" << bytesPerActiveLc <<
" send " << (*itBsr).second.statusPduSize <<
" status bytes to LC " << (uint32_t)(*it).first <<
" statusQueue " << (*itBsr).second.statusPduSize <<
" retxQueue" << (*itBsr).second.retxQueueSize <<
" txQueue" << (*itBsr).second.txQueueSize);
595 (*itBsr).second.statusPduSize = 0;
600 uint32_t bytesForThisLc = bytesPerActiveLc;
601 NS_LOG_LOGIC (
this <<
"\t" << bytesPerActiveLc <<
" bytes to LC " << (uint32_t)(*it).first <<
" statusQueue " << (*itBsr).second.statusPduSize <<
" retxQueue" << (*itBsr).second.retxQueueSize <<
" txQueue" << (*itBsr).second.txQueueSize);
602 if (((*itBsr).second.statusPduSize > 0) && (bytesForThisLc > (*itBsr).second.statusPduSize))
604 (*it).second.macSapUser->NotifyTxOpportunity ((*itBsr).second.statusPduSize, 0, 0);
605 bytesForThisLc -= (*itBsr).second.statusPduSize;
606 NS_LOG_DEBUG (
this <<
" serve STATUS " << (*itBsr).second.statusPduSize);
607 (*itBsr).second.statusPduSize = 0;
611 if ((*itBsr).second.statusPduSize>bytesForThisLc)
613 NS_FATAL_ERROR (
"Insufficient Tx Opportunity for sending a status message");
617 if ((bytesForThisLc > 7) &&
618 (((*itBsr).second.retxQueueSize > 0) ||
619 ((*itBsr).second.txQueueSize > 0)))
621 if ((*itBsr).second.retxQueueSize > 0)
623 NS_LOG_DEBUG (
this <<
" serve retx DATA, bytes " << bytesForThisLc);
624 (*it).second.macSapUser->NotifyTxOpportunity (bytesForThisLc, 0, 0);
625 if ((*itBsr).second.retxQueueSize >= bytesForThisLc)
627 (*itBsr).second.retxQueueSize -= bytesForThisLc;
631 (*itBsr).second.retxQueueSize = 0;
634 else if ((*itBsr).second.txQueueSize > 0)
636 uint16_t lcid = (*it).first;
637 uint32_t rlcOverhead;
651 NS_LOG_DEBUG (
this <<
" serve tx DATA, bytes " << bytesForThisLc <<
", RLC overhead " << rlcOverhead);
652 (*it).second.macSapUser->NotifyTxOpportunity (bytesForThisLc, 0, 0);
653 if ((*itBsr).second.txQueueSize >= bytesForThisLc - rlcOverhead)
655 (*itBsr).second.txQueueSize -= bytesForThisLc - rlcOverhead;
659 (*itBsr).second.txQueueSize = 0;
665 if ( ((*itBsr).second.retxQueueSize > 0) || ((*itBsr).second.txQueueSize > 0))
671 NS_LOG_LOGIC (
this <<
"\t" << bytesPerActiveLc <<
"\t new queues " << (uint32_t)(*it).first <<
" statusQueue " << (*itBsr).second.statusPduSize <<
" retxQueue" << (*itBsr).second.retxQueueSize <<
" txQueue" << (*itBsr).second.txQueueSize);
696 uint16_t raRnti = rarMsg->GetRaRnti ();
697 NS_LOG_LOGIC (
this <<
"got RAR with RA-RNTI " << (uint32_t) raRnti <<
", expecting " << (uint32_t)
m_raRnti);
698 if (raRnti == m_raRnti)
700 for (std::list<RarLteControlMessage::Rar>::const_iterator it = rarMsg->RarListBegin ();
701 it != rarMsg->RarListEnd ();
717 NS_LOG_WARN (
this <<
" LteControlMessage not recognized");
733 NS_LOG_INFO (
this <<
" HARQ Proc Id " << i <<
" packets buffer expired");
uint8_t numberOfRaPreambles
virtual void AddLc(uint8_t lcId, LteUeCmacSapProvider::LogicalChannelConfig lcConfig, LteMacSapUser *msu)
void DoStartNonContentionBasedRandomAccessProcedure(uint16_t rnti, uint8_t rapId, uint8_t prachMask)
LteUeCmacSapProvider::LogicalChannelConfig lcConfig
uint8_t GetLcid(void) const
keep track of time values and allow control of global simulation resolution
uint8_t raResponseWindowSize
#define NS_LOG_FUNCTION(parameters)
void SetStream(int64_t stream)
Specifies the stream number for this RNG stream.
virtual void TransmitPdu(TransmitPduParameters params)
void SendRaPreamble(bool contention)
void StartWaitingForRaResponse()
void DoReceivePhyPdu(Ptr< Packet > p)
Ptr< UniformRandomVariable > m_raPreambleUniformVariable
uint16_t GetRnti(void) const
LteUePhySapUser * m_uePhySapUser
void AddPacketTag(const Tag &tag) const
#define NS_ASSERT(condition)
void RaResponseTimeout(bool contention)
See section 4.3.2 ulDciListElement.
virtual void ReportBufferStatus(ReportBufferStatusParameters params)
struct MacCeValue_u m_macCeValue
virtual void DoDispose(void)
See section 4.3.10 buildRARListElement.
void DoAddLc(uint8_t lcId, LteUeCmacSapProvider::LogicalChannelConfig lcConfig, LteMacSapUser *msu)
void SetLteUePhySapProvider(LteUePhySapProvider *s)
Set the PHY SAP Provider.
virtual void SendRachPreamble(uint32_t prachId, uint32_t raRnti)=0
static EventId Schedule(Time const &time, MEM mem_ptr, OBJ obj)
void DoStartContentionBasedRandomAccessProcedure()
void SendReportBufferStatus(void)
virtual void SubframeIndication(uint32_t frameNo, uint32_t subframeNo)
Trigger the start from a new frame (input from Phy layer)
#define NS_FATAL_ERROR(msg)
fatal error handling
virtual void StartContentionBasedRandomAccessProcedure()
void DoRemoveLc(uint8_t lcId)
std::vector< uint8_t > m_miUlHarqProcessesPacketTimer
friend class UeMemberLteUePhySapUser
void SetLteUeCmacSapUser(LteUeCmacSapUser *s)
void DoTransmitPdu(LteMacSapProvider::TransmitPduParameters params)
virtual void ConfigureRach(RachConfig rc)
virtual void SetTemporaryCellRnti(uint16_t rnti)=0
friend class UeMemberLteMacSapProvider
static uint8_t BufferSize2BsrId(uint32_t val)
bool m_waitingForRaResponse
void DoReportBufferStatus(LteMacSapProvider::ReportBufferStatusParameters params)
virtual void StartNonContentionBasedRandomAccessProcedure(uint16_t rnti, uint8_t preambleId, uint8_t prachMask)
virtual void SendMacPdu(Ptr< Packet > p)=0
Send the MAC PDU to the channel.
LteUeCmacSapProvider * m_cmacSapProvider
NS_OBJECT_ENSURE_REGISTERED(AntennaModel)
std::vector< Ptr< PacketBurst > > m_miUlHarqProcessesPacket
LteUeCmacSapProvider * GetLteUeCmacSapProvider(void)
#define NS_LOG_LOGIC(msg)
void DoConfigureRach(LteUeCmacSapProvider::RachConfig rc)
virtual void NotifyRandomAccessSuccessful()=0
See section 4.3.14 macCEListElement.
void DoSubframeIndication(uint32_t frameNo, uint32_t subframeNo)
Forwarded from LteUePhySapUser: trigger the start from a new frame.
UeMemberLteUeCmacSapProvider(LteUeMac *mac)
void DoReceiveLteControlMessage(Ptr< LteControlMessage > msg)
Ptr< Packet > Copy(void) const
std::map< uint8_t, LcInfo > m_lcInfoMap
virtual void SendLteControlMessage(Ptr< LteControlMessage > msg)=0
Send SendLteControlMessage (PDCCH map, CQI feedbacks) using the ideal control channel.
LteUePhySapUser * GetLteUePhySapUser()
Get the PHY SAP user.
LteMacSapProvider * GetLteMacSapProvider(void)
uint16_t m_backoffParameter
static TypeId GetTypeId(void)
UeMemberLteUePhySapUser(LteUeMac *mac)
LteMacSapProvider * m_macSapProvider
virtual void ReceivePhyPdu(Ptr< Packet > p)
LteUePhySapProvider * m_uePhySapProvider
virtual void RemoveLc(uint8_t lcId)
#define NS_ASSERT_MSG(condition, message)
std::vector< uint8_t > m_bufferStatus
NS_LOG_COMPONENT_DEFINE("LteUeMac")
virtual void NotifyRandomAccessFailed()=0
void RandomlySelectAndSendRaPreamble()
void RecvRaResponse(BuildRarListElement_s raResponse)
uint8_t m_preambleTransmissionCounter
EventId m_noRaResponseReceivedEvent
virtual void DoDispose(void)
LteUeCmacSapProvider::RachConfig m_rachConfig
bool RemovePacketTag(Tag &tag)
#define NS_LOG_DEBUG(msg)
enum ns3::MacCeListElement_s::MacCeType_e m_macCeType
virtual void ReceiveLteControlMessage(Ptr< LteControlMessage > msg)
Receive SendLteControlMessage (PDCCH map, CQI feedbacks) using the ideal control channel.
#define NS_LOG_ERROR(msg)
std::map< uint8_t, LteMacSapProvider::ReportBufferStatusParameters > m_ulBsrReceived
a base class which provides memory management and object aggregation
friend class UeMemberLteUeCmacSapProvider
int64_t AssignStreams(int64_t stream)
a unique identifier for an interface.
TypeId SetParent(TypeId tid)
void RefreshHarqProcessesPacketBuffer(void)
UeMemberLteMacSapProvider(LteUeMac *mac)
LteUeCmacSapUser * m_cmacSapUser