18#include "ns3/packet-burst.h" 
   19#include "ns3/packet.h" 
   20#include "ns3/pointer.h" 
   21#include "ns3/random-variable-stream.h" 
   22#include "ns3/simulator.h" 
   51                                                      uint8_t prachMask) 
override;
 
   52    void SetRnti(uint16_t rnti) 
override;
 
   53    void AddLc(uint8_t lcId,
 
   56    void RemoveLc(uint8_t lcId) 
override;
 
   57    void Reset() 
override;
 
   59    void SetImsi(uint64_t imsi) 
override;
 
 
   73    m_mac->DoConfigureRach(rc);
 
 
   79    m_mac->DoStartContentionBasedRandomAccessProcedure();
 
 
   87    m_mac->DoStartNonContentionBasedRandomAccessProcedure(rnti, preambleId, prachMask);
 
 
   93    m_mac->DoSetRnti(rnti);
 
 
   99    m_mac->DoAddLc(lcId, lcConfig, msu);
 
 
  105    m_mac->DoRemoveLc(lcid);
 
 
  117    m_mac->DoNotifyConnectionSuccessful();
 
 
  123    m_mac->DoSetImsi(imsi);
 
 
  153    m_mac->DoTransmitPdu(params);
 
 
  159    m_mac->DoReportBufferStatus(params);
 
 
  192    m_mac->DoReceivePhyPdu(p);
 
 
  198    m_mac->DoSubframeIndication(frameNo, subframeNo);
 
 
  204    m_mac->DoReceiveLteControlMessage(msg);
 
 
  219            .AddTraceSource(
"RaResponseTimeout",
 
  220                            "trace fired upon RA response timeout",
 
  222                            "ns3::LteUeMac::RaResponseTimeoutTracedCallback")
 
 
  312    params.pdu->AddPacketTag(tag);
 
 
  328        (*it).second = params;
 
  333            std::pair<uint8_t, LteMacSapProvider::ReportBufferStatusParameters>(params.lcid,
 
 
  360    std::vector<uint32_t> queue(4, 0); 
 
  363        uint8_t lcid = it->first;
 
  367                          (((*it).second.txQueueSize == 0) && ((*it).second.retxQueueSize == 0) &&
 
  368                           ((*it).second.statusPduSize == 0)),
 
  369                      "BSR should not be used for LCID 0");
 
  370        uint8_t lcg = lcInfoMapIt->second.lcConfig.logicalChannelGroup;
 
  372            ((*it).second.txQueueSize + (*it).second.retxQueueSize + (*it).second.statusPduSize);
 
 
  396    bool contention = 
true;
 
 
  438                                     << 
", setting T-C-RNTI = " << raResponse.
m_rnti);
 
  448    const uint8_t lc0Lcid = 0;
 
  452    if ((lc0BsrIt != 
m_ulBsrReceived.end()) && (lc0BsrIt->second.txQueueSize > 0))
 
  455                      "segmentation of Message 3 is not allowed");
 
  463        txOpParams.
layer = 0;
 
  467        txOpParams.
lcid = lc0Lcid;
 
  468        lc0InfoIt->second.macSapUser->NotifyTxOpportunity(txOpParams);
 
  469        lc0BsrIt->second.txQueueSize = 0;
 
 
  487        NS_LOG_INFO(
"RAR timeout, preambleTransMax reached => giving up");
 
 
  543    NS_LOG_FUNCTION(
this << rnti << (uint16_t)preambleId << (uint16_t)prachMask);
 
  545                  "requested PRACH MASK = " << (
uint32_t)prachMask
 
  546                                            << 
", but only PRACH MASK = 0 is supported");
 
  550    bool contention = 
false;
 
 
  561                  "cannot add channel because LCID " << (uint16_t)lcId << 
" is already present");
 
 
  615    p->RemovePacketTag(tag);
 
  626            it->second.macSapUser->ReceivePdu(rxPduParams);
 
 
  649            uint16_t activeLcs = 0;
 
  653                if (((*itBsr).second.statusPduSize > 0) || ((*itBsr).second.retxQueueSize > 0) ||
 
  654                    ((*itBsr).second.txQueueSize > 0))
 
  657                    if (((*itBsr).second.statusPduSize != 0) &&
 
  658                        ((*itBsr).second.statusPduSize < statusPduMinSize))
 
  660                        statusPduMinSize = (*itBsr).second.statusPduSize;
 
  662                    if (((*itBsr).second.statusPduSize != 0) && (statusPduMinSize == 0))
 
  664                        statusPduMinSize = (*itBsr).second.statusPduSize;
 
  670                NS_LOG_ERROR(
this << 
" No active flows for this UL-DCI");
 
  674            bool statusPduPriority = 
false;
 
  675            if ((statusPduMinSize != 0) && (bytesPerActiveLc < statusPduMinSize))
 
  678                statusPduPriority = 
true;
 
  679                NS_LOG_DEBUG(
this << 
" Reduced resource -> send only Status, b ytes " 
  680                                  << statusPduMinSize);
 
  681                if (dci.
m_tbSize < statusPduMinSize)
 
  683                    NS_FATAL_ERROR(
"Insufficient Tx Opportunity for sending a status message");
 
  687                              << dci.
m_tbSize << 
" => " << bytesPerActiveLc
 
  688                              << 
" bytes per active LC" 
  689                              << 
" statusPduMinSize " << statusPduMinSize);
 
  697                                  << 
" bytesPerActiveLc " << bytesPerActiveLc);
 
  699                    (((*itBsr).second.statusPduSize > 0) || ((*itBsr).second.retxQueueSize > 0) ||
 
  700                     ((*itBsr).second.txQueueSize > 0)))
 
  702                    if ((statusPduPriority) && ((*itBsr).second.statusPduSize == statusPduMinSize))
 
  704                        txOpParams.
bytes = (*itBsr).second.statusPduSize;
 
  705                        txOpParams.
layer = 0;
 
  709                        txOpParams.
lcid = (*it).first;
 
  710                        (*it).second.macSapUser->NotifyTxOpportunity(txOpParams);
 
  711                        NS_LOG_LOGIC(
this << 
"\t" << bytesPerActiveLc << 
" send  " 
  712                                          << (*itBsr).second.statusPduSize << 
" status bytes to LC " 
  713                                          << (
uint32_t)(*it).first << 
" statusQueue " 
  714                                          << (*itBsr).second.statusPduSize << 
" retxQueue" 
  715                                          << (*itBsr).second.retxQueueSize << 
" txQueue" 
  716                                          << (*itBsr).second.txQueueSize);
 
  717                        (*itBsr).second.statusPduSize = 0;
 
  722                        uint32_t bytesForThisLc = bytesPerActiveLc;
 
  723                        NS_LOG_LOGIC(
this << 
"\t" << bytesPerActiveLc << 
" bytes to LC " 
  724                                          << (
uint32_t)(*it).first << 
" statusQueue " 
  725                                          << (*itBsr).second.statusPduSize << 
" retxQueue" 
  726                                          << (*itBsr).second.retxQueueSize << 
" txQueue" 
  727                                          << (*itBsr).second.txQueueSize);
 
  728                        if (((*itBsr).second.statusPduSize > 0) &&
 
  729                            (bytesForThisLc > (*itBsr).second.statusPduSize))
 
  731                            txOpParams.
bytes = (*itBsr).second.statusPduSize;
 
  732                            txOpParams.
layer = 0;
 
  736                            txOpParams.
lcid = (*it).first;
 
  737                            (*it).second.macSapUser->NotifyTxOpportunity(txOpParams);
 
  738                            bytesForThisLc -= (*itBsr).second.statusPduSize;
 
  739                            NS_LOG_DEBUG(
this << 
" serve STATUS " << (*itBsr).second.statusPduSize);
 
  740                            (*itBsr).second.statusPduSize = 0;
 
  744                            if ((*itBsr).second.statusPduSize > bytesForThisLc)
 
  747                                    "Insufficient Tx Opportunity for sending a status message");
 
  751                        if ((bytesForThisLc > 7) 
 
  752                            && (((*itBsr).second.retxQueueSize > 0) ||
 
  753                                ((*itBsr).second.txQueueSize > 0)))
 
  755                            if ((*itBsr).second.retxQueueSize > 0)
 
  757                                NS_LOG_DEBUG(
this << 
" serve retx DATA, bytes " << bytesForThisLc);
 
  758                                txOpParams.
bytes = bytesForThisLc;
 
  759                                txOpParams.
layer = 0;
 
  763                                txOpParams.
lcid = (*it).first;
 
  764                                (*it).second.macSapUser->NotifyTxOpportunity(txOpParams);
 
  765                                if ((*itBsr).second.retxQueueSize >= bytesForThisLc)
 
  767                                    (*itBsr).second.retxQueueSize -= bytesForThisLc;
 
  771                                    (*itBsr).second.retxQueueSize = 0;
 
  774                            else if ((*itBsr).second.txQueueSize > 0)
 
  776                                uint16_t lcid = (*it).first;
 
  791                                NS_LOG_DEBUG(
this << 
" serve tx DATA, bytes " << bytesForThisLc
 
  792                                                  << 
", RLC overhead " << rlcOverhead);
 
  793                                txOpParams.
bytes = bytesForThisLc;
 
  794                                txOpParams.
layer = 0;
 
  798                                txOpParams.
lcid = (*it).first;
 
  799                                (*it).second.macSapUser->NotifyTxOpportunity(txOpParams);
 
  800                                if ((*itBsr).second.txQueueSize >= bytesForThisLc - rlcOverhead)
 
  802                                    (*itBsr).second.txQueueSize -= bytesForThisLc - rlcOverhead;
 
  806                                    (*itBsr).second.txQueueSize = 0;
 
  812                            if (((*itBsr).second.retxQueueSize > 0) ||
 
  813                                ((*itBsr).second.txQueueSize > 0))
 
  819                        NS_LOG_LOGIC(
this << 
"\t" << bytesPerActiveLc << 
"\t new queues " 
  820                                          << (
uint32_t)(*it).first << 
" statusQueue " 
  821                                          << (*itBsr).second.statusPduSize << 
" retxQueue" 
  822                                          << (*itBsr).second.retxQueueSize << 
" txQueue" 
  823                                          << (*itBsr).second.txQueueSize);
 
  833            for (
auto j = pb->Begin(); j != pb->End(); ++j)
 
  846            uint16_t raRnti = rarMsg->GetRaRnti();
 
  851                for (
auto it = rarMsg->RarListBegin(); it != rarMsg->RarListEnd(); ++it)
 
  866        NS_LOG_WARN(
this << 
" LteControlMessage not recognized");
 
 
  882                NS_LOG_INFO(
this << 
" HARQ Proc Id " << i << 
" packets buffer expired");
 
 
static uint8_t BufferSize2BsrId(uint32_t val)
Convert Buffer size to BSR ID.
Service Access Point (SAP) offered by the MAC to the RLC See Femto Forum MAC Scheduler Interface Spec...
Service Access Point (SAP) offered by the MAC to the RLC See Femto Forum MAC Scheduler Interface Spec...
Tag used to define the RNTI and LC id for each MAC packet transmitted.
uint16_t GetRnti() const
Get RNTI function.
uint8_t GetLcid() const
Get LCID function.
Service Access Point (SAP) offered by the UE MAC to the UE RRC.
Service Access Point (SAP) offered by the UE MAC to the UE RRC.
std::vector< Ptr< PacketBurst > > m_miUlHarqProcessesPacket
Packets under transmission of the UL HARQ processes.
LteUePhySapUser * m_uePhySapUser
UE Phy SAP user.
uint8_t m_componentCarrierId
component carrier Id --> used to address sap
void RaResponseTimeout(bool contention)
RA response timeout function.
LteUeCmacSapProvider::RachConfig m_rachConfig
RACH configuration.
uint32_t m_frameNo
frame number
void DoSubframeIndication(uint32_t frameNo, uint32_t subframeNo)
Forwarded from LteUePhySapUser: trigger the start from a new frame.
void SendReportBufferStatus()
Send report buffer status.
void DoReportBufferStatus(LteMacSapProvider::ReportBufferStatusParameters params)
Report buffers status function.
TracedCallback< uint64_t, bool, uint8_t, uint8_t > m_raResponseTimeoutTrace
The RaResponseTimeout trace source.
LteUePhySapProvider * m_uePhySapProvider
UE Phy SAP provider.
void SetLteUePhySapProvider(LteUePhySapProvider *s)
Set the PHY SAP Provider.
Time m_bsrPeriodicity
BSR periodicity.
void RefreshHarqProcessesPacketBuffer()
Refresh HARQ processes packet buffer function.
EventId m_noRaResponseReceivedEvent
no RA response received event ID
LteUeCmacSapProvider * m_cmacSapProvider
CMAC SAP provider.
uint8_t m_preambleTransmissionCounter
preamble tranamission counter
Ptr< UniformRandomVariable > m_raPreambleUniformVariable
RA preamble random variable.
void SetComponentCarrierId(uint8_t index)
Set the component carried ID.
int64_t AssignStreams(int64_t stream)
Assign a fixed random variable stream number to the random variables used by this model.
void DoConfigureRach(LteUeCmacSapProvider::RachConfig rc)
Configure RACH function.
LteUePhySapUser * GetLteUePhySapUser()
Get the PHY SAP user.
friend class UeMemberLteUePhySapUser
allow UeMemberLteUePhySapUser class friend access
bool m_rachConfigured
is RACH configured?
void DoRemoveLc(uint8_t lcId)
Remove LC function.
void RecvRaResponse(BuildRarListElement_s raResponse)
Receive the RA response function.
void DoReceivePhyPdu(Ptr< Packet > p)
Receive Phy PDU function.
uint8_t m_raPreambleId
RA preamble ID.
void DoNotifyConnectionSuccessful()
Notify MAC about the successful RRC connection establishment.
friend class UeMemberLteUeCmacSapProvider
allow UeMemberLteUeCmacSapProvider class friend access
std::vector< uint8_t > m_miUlHarqProcessesPacketTimer
timer for packet life in the buffer
void DoReceiveLteControlMessage(Ptr< LteControlMessage > msg)
Receive LTE control message function.
static TypeId GetTypeId()
Get the type ID.
void DoTransmitPdu(LteMacSapProvider::TransmitPduParameters params)
Transmit PDU function.
uint32_t m_subframeNo
subframe number
std::map< uint8_t, LteMacSapProvider::ReportBufferStatusParameters > m_ulBsrReceived
BSR received from RLC (the last one)
void DoDispose() override
Destructor implementation.
void DoReset()
Reset function.
LteUeCmacSapUser * m_cmacSapUser
CMAC SAP user.
bool m_freshUlBsr
true when a BSR has been received in the last TTI
LteMacSapProvider * GetLteMacSapProvider()
Get the LTE MAC SAP provider.
void DoStartNonContentionBasedRandomAccessProcedure(uint16_t rnti, uint8_t rapId, uint8_t prachMask)
Start non contention based random access procedure function.
LteUeCmacSapProvider * GetLteUeCmacSapProvider()
Get the LTE CMAC SAP provider.
bool m_waitingForRaResponse
waiting for RA response
void DoAddLc(uint8_t lcId, LteUeCmacSapProvider::LogicalChannelConfig lcConfig, LteMacSapUser *msu)
Add LC function.
uint8_t m_harqProcessId
HARQ process ID.
friend class UeMemberLteMacSapProvider
allow UeMemberLteMacSapProvider class friend access
LteMacSapProvider * m_macSapProvider
MAC SAP provider.
void RandomlySelectAndSendRaPreamble()
Randomly select and send RA preamble function.
void DoStartContentionBasedRandomAccessProcedure()
Start contention based random access procedure function.
uint16_t m_backoffParameter
backoff parameter
void StartWaitingForRaResponse()
Start waiting for RA response function.
void DoSetRnti(uint16_t rnti)
Set RNTI.
void DoSetImsi(uint64_t imsi)
Set IMSI.
void SendRaPreamble(bool contention)
Send RA preamble function.
void SetLteUeCmacSapUser(LteUeCmacSapUser *s)
Set the LTE UE CMAC SAP user.
std::map< uint8_t, LcInfo > m_lcInfoMap
logical channel info map
Service Access Point (SAP) offered by the UE-PHY to the UE-MAC.
Service Access Point (SAP) offered by the PHY to the MAC.
virtual void DoDispose()
Destructor implementation.
Smart pointer class similar to boost::intrusive_ptr.
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
static Time Now()
Return the current simulation virtual time.
Simulation virtual time values and global simulation resolution.
a unique identifier for an interface.
TypeId SetParent(TypeId tid)
Set the parent TypeId.
LteUeMac * m_mac
the UE MAC
void TransmitPdu(TransmitPduParameters params) override
send an RLC PDU to the MAC for transmission.
void ReportBufferStatus(ReportBufferStatusParameters params) override
Report the RLC buffer status to the MAC.
UeMemberLteMacSapProvider(LteUeMac *mac)
Constructor.
void StartNonContentionBasedRandomAccessProcedure(uint16_t rnti, uint8_t preambleId, uint8_t prachMask) override
tell the MAC to start a non-contention-based random access procedure, e.g., as a consequence of hando...
LteUeMac * m_mac
the UE MAC
void SetImsi(uint64_t imsi) override
A method call by UE RRC to communicate the IMSI to the UE MAC.
void Reset() override
reset the MAC
void StartContentionBasedRandomAccessProcedure() override
tell the MAC to start a contention-based random access procedure, e.g., to perform RRC connection est...
void AddLc(uint8_t lcId, LteUeCmacSapProvider::LogicalChannelConfig lcConfig, LteMacSapUser *msu) override
add a new Logical Channel (LC)
void RemoveLc(uint8_t lcId) override
remove an existing LC
void SetRnti(uint16_t rnti) override
void ConfigureRach(RachConfig rc) override
Configure RACH function.
void NotifyConnectionSuccessful() override
Notify MAC about the successful RRC connection establishment.
UeMemberLteUeCmacSapProvider(LteUeMac *mac)
Constructor.
UeMemberLteUePhySapUser(LteUeMac *mac)
Constructor.
LteUeMac * m_mac
the UE MAC
void ReceiveLteControlMessage(Ptr< LteControlMessage > msg) override
Receive SendLteControlMessage (PDCCH map, CQI feedbacks) using the ideal control channel.
void ReceivePhyPdu(Ptr< Packet > p) override
Receive Phy Pdu function.
void SubframeIndication(uint32_t frameNo, uint32_t subframeNo) override
Trigger the start from a new frame (input from Phy layer)
#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...
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
#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_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
#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.
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Ptr< T1 > DynamicCast(const Ptr< T2 > &p)
Cast a Ptr.
See section 4.3.10 buildRARListElement.
Parameters for LteMacSapProvider::ReportBufferStatus.
Parameters for LteMacSapProvider::TransmitPdu.
Parameters for LteMacSapUser::ReceivePdu.
Ptr< Packet > p
the RLC PDU to be received
uint8_t lcid
the logical channel id
uint16_t rnti
the C-RNTI identifying the UE
Parameters for LteMacSapUser::NotifyTxOpportunity.
uint8_t harqId
the HARQ ID
uint16_t rnti
the C-RNTI identifying the UE
uint32_t bytes
the number of bytes to transmit
uint8_t componentCarrierId
the component carrier id
uint8_t layer
the layer of transmission (MIMO)
uint8_t lcid
the logical channel id
LogicalChannelConfig structure.
LteUeCmacSapProvider::LogicalChannelConfig lcConfig
logical channel config
LteMacSapUser * macSapUser
MAC SAP user.
See section 4.3.14 macCEListElement.
struct MacCeValue_u m_macCeValue
MAC CE value.
std::vector< uint8_t > m_bufferStatus
buffer status
See section 4.3.2 ulDciListElement.