A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
lte-ue-mac.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2011 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation;
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 *
17 * Author: Nicola Baldo <nbaldo@cttc.es>
18 * Author: Marco Miozzo <mmiozzo@cttc.es>
19 */
20
21#include "lte-ue-mac.h"
22
23#include "ff-mac-common.h"
24#include "lte-common.h"
27
28#include <ns3/log.h>
29#include <ns3/packet-burst.h>
30#include <ns3/packet.h>
31#include <ns3/pointer.h>
32#include <ns3/random-variable-stream.h>
33#include <ns3/simulator.h>
34
35namespace ns3
36{
37
38NS_LOG_COMPONENT_DEFINE("LteUeMac");
39
41
43// SAP forwarders
45
48{
49 public:
56
57 // inherited from LteUeCmacSapProvider
58 void ConfigureRach(RachConfig rc) override;
61 uint8_t preambleId,
62 uint8_t prachMask) override;
63 void SetRnti(uint16_t rnti) override;
64 void AddLc(uint8_t lcId,
66 LteMacSapUser* msu) override;
67 void RemoveLc(uint8_t lcId) override;
68 void Reset() override;
69 void NotifyConnectionSuccessful() override;
70 void SetImsi(uint64_t imsi) override;
71
72 private:
74};
75
77 : m_mac(mac)
78{
79}
80
81void
83{
85}
86
87void
89{
91}
92
93void
95 uint8_t preambleId,
96 uint8_t prachMask)
97{
98 m_mac->DoStartNonContentionBasedRandomAccessProcedure(rnti, preambleId, prachMask);
99}
100
101void
103{
104 m_mac->DoSetRnti(rnti);
105}
106
107void
109{
110 m_mac->DoAddLc(lcId, lcConfig, msu);
111}
112
113void
115{
116 m_mac->DoRemoveLc(lcid);
117}
118
119void
121{
122 m_mac->DoReset();
123}
124
125void
127{
129}
130
131void
133{
134 m_mac->DoSetImsi(imsi);
135}
136
139{
140 public:
147
148 // inherited from LteMacSapProvider
149 void TransmitPdu(TransmitPduParameters params) override;
151
152 private:
154};
155
157 : m_mac(mac)
158{
159}
160
161void
163{
164 m_mac->DoTransmitPdu(params);
165}
166
167void
169{
171}
172
177{
178 public:
185
186 // inherited from LtePhySapUser
187 void ReceivePhyPdu(Ptr<Packet> p) override;
188 void SubframeIndication(uint32_t frameNo, uint32_t subframeNo) override;
190
191 private:
193};
194
196 : m_mac(mac)
197{
198}
199
200void
202{
204}
205
206void
208{
209 m_mac->DoSubframeIndication(frameNo, subframeNo);
210}
211
212void
214{
216}
217
219// LteUeMac methods
221
222TypeId
224{
225 static TypeId tid =
226 TypeId("ns3::LteUeMac")
227 .SetParent<Object>()
228 .SetGroupName("Lte")
229 .AddConstructor<LteUeMac>()
230 .AddTraceSource("RaResponseTimeout",
231 "trace fired upon RA response timeout",
233 "ns3::LteUeMac::RaResponseTimeoutTracedCallback")
234
235 ;
236 return tid;
237}
238
240 : m_bsrPeriodicity(MilliSeconds(1)), // ideal behavior
241 m_bsrLast(MilliSeconds(0)),
242 m_freshUlBsr(false),
243 m_harqProcessId(0),
244 m_rnti(0),
245 m_imsi(0),
246 m_rachConfigured(false),
247 m_waitingForRaResponse(false)
248
249{
250 NS_LOG_FUNCTION(this);
252 for (std::size_t i = 0; i < m_miUlHarqProcessesPacket.size(); i++)
253 {
254 Ptr<PacketBurst> pb = CreateObject<PacketBurst>();
255 m_miUlHarqProcessesPacket.at(i) = pb;
256 }
258
262 m_raPreambleUniformVariable = CreateObject<UniformRandomVariable>();
264}
265
267{
268 NS_LOG_FUNCTION(this);
269}
270
271void
273{
274 NS_LOG_FUNCTION(this);
276 delete m_macSapProvider;
277 delete m_cmacSapProvider;
278 delete m_uePhySapUser;
280}
281
284{
285 return m_uePhySapUser;
286}
287
288void
290{
292}
293
296{
297 return m_macSapProvider;
298}
299
300void
302{
303 m_cmacSapUser = s;
304}
305
308{
309 return m_cmacSapProvider;
310}
311
312void
314{
315 m_componentCarrierId = index;
316}
317
318void
320{
321 NS_LOG_FUNCTION(this);
322 NS_ASSERT_MSG(m_rnti == params.rnti, "RNTI mismatch between RLC and MAC");
323 LteRadioBearerTag tag(params.rnti, params.lcid, 0 /* UE works in SISO mode*/);
324 params.pdu->AddPacketTag(tag);
325 // store pdu in HARQ buffer
326 m_miUlHarqProcessesPacket.at(m_harqProcessId)->AddPacket(params.pdu);
328 m_uePhySapProvider->SendMacPdu(params.pdu);
329}
330
331void
333{
334 NS_LOG_FUNCTION(this << (uint32_t)params.lcid);
335
336 std::map<uint8_t, LteMacSapProvider::ReportBufferStatusParameters>::iterator it;
337
338 it = m_ulBsrReceived.find(params.lcid);
339 if (it != m_ulBsrReceived.end())
340 {
341 // update entry
342 (*it).second = params;
343 }
344 else
345 {
346 m_ulBsrReceived.insert(
347 std::pair<uint8_t, LteMacSapProvider::ReportBufferStatusParameters>(params.lcid,
348 params));
349 }
350 m_freshUlBsr = true;
351}
352
353void
355{
356 NS_LOG_FUNCTION(this);
357
358 if (m_rnti == 0)
359 {
360 NS_LOG_INFO("MAC not initialized, BSR deferred");
361 return;
362 }
363
364 if (m_ulBsrReceived.empty())
365 {
366 NS_LOG_INFO("No BSR report to transmit");
367 return;
368 }
370 bsr.m_rnti = m_rnti;
371 bsr.m_macCeType = MacCeListElement_s::BSR;
372
373 // BSR is reported for each LCG
374 std::map<uint8_t, LteMacSapProvider::ReportBufferStatusParameters>::iterator it;
375 std::vector<uint32_t> queue(4, 0); // one value per each of the 4 LCGs, initialized to 0
376 for (it = m_ulBsrReceived.begin(); it != m_ulBsrReceived.end(); it++)
377 {
378 uint8_t lcid = it->first;
379 std::map<uint8_t, LcInfo>::iterator lcInfoMapIt;
380 lcInfoMapIt = m_lcInfoMap.find(lcid);
381 NS_ASSERT(lcInfoMapIt != m_lcInfoMap.end());
382 NS_ASSERT_MSG((lcid != 0) ||
383 (((*it).second.txQueueSize == 0) && ((*it).second.retxQueueSize == 0) &&
384 ((*it).second.statusPduSize == 0)),
385 "BSR should not be used for LCID 0");
386 uint8_t lcg = lcInfoMapIt->second.lcConfig.logicalChannelGroup;
387 queue.at(lcg) +=
388 ((*it).second.txQueueSize + (*it).second.retxQueueSize + (*it).second.statusPduSize);
389 }
390
391 // FF API says that all 4 LCGs are always present
396
397 // create the feedback to eNB
398 Ptr<BsrLteControlMessage> msg = Create<BsrLteControlMessage>();
399 msg->SetBsr(bsr);
401}
402
403void
405{
406 NS_LOG_FUNCTION(this);
407 // 3GPP 36.321 5.1.1
408 NS_ASSERT_MSG(m_rachConfigured, "RACH not configured");
409 // assume that there is no Random Access Preambles group B
412 bool contention = true;
413 SendRaPreamble(contention);
414}
415
416void
418{
419 NS_LOG_FUNCTION(this << (uint32_t)m_raPreambleId << contention);
420 // Since regular UL LteControlMessages need m_ulConfigured = true in
421 // order to be sent by the UE, the rach preamble needs to be sent
422 // with a dedicated primitive (not
423 // m_uePhySapProvider->SendLteControlMessage (msg)) so that it can
424 // bypass the m_ulConfigured flag. This is reasonable, since In fact
425 // the RACH preamble is sent on 6RB bandwidth so the uplink
426 // bandwidth does not need to be configured.
427 NS_ASSERT(m_subframeNo > 0); // sanity check for subframe starting at 1
430 NS_LOG_INFO(this << " sent preamble id " << (uint32_t)m_raPreambleId << ", RA-RNTI "
431 << (uint32_t)m_raRnti);
432 // 3GPP 36.321 5.1.4
433 Time raWindowBegin = MilliSeconds(3);
437 Simulator::Schedule(raWindowEnd, &LteUeMac::RaResponseTimeout, this, contention);
438}
439
440void
442{
443 NS_LOG_FUNCTION(this);
445}
446
447void
449{
450 NS_LOG_FUNCTION(this);
453 NS_LOG_INFO("got RAR for RAPID " << (uint32_t)m_raPreambleId
454 << ", setting T-C-RNTI = " << raResponse.m_rnti);
455 m_rnti = raResponse.m_rnti;
457 // in principle we should wait for contention resolution,
458 // but in the current LTE model when two or more identical
459 // preambles are sent no one is received, so there is no need
460 // for contention resolution
462 // trigger tx opportunity for Message 3 over LC 0
463 // this is needed since Message 3's UL GRANT is in the RAR, not in UL-DCIs
464 const uint8_t lc0Lcid = 0;
465 std::map<uint8_t, LcInfo>::iterator lc0InfoIt = m_lcInfoMap.find(lc0Lcid);
466 NS_ASSERT(lc0InfoIt != m_lcInfoMap.end());
467 std::map<uint8_t, LteMacSapProvider::ReportBufferStatusParameters>::iterator lc0BsrIt =
468 m_ulBsrReceived.find(lc0Lcid);
469 if ((lc0BsrIt != m_ulBsrReceived.end()) && (lc0BsrIt->second.txQueueSize > 0))
470 {
471 NS_ASSERT_MSG(raResponse.m_grant.m_tbSize > lc0BsrIt->second.txQueueSize,
472 "segmentation of Message 3 is not allowed");
473 // this function can be called only from primary carrier
474 if (m_componentCarrierId > 0)
475 {
476 NS_FATAL_ERROR("Function called on wrong componentCarrier");
477 }
479 txOpParams.bytes = raResponse.m_grant.m_tbSize;
480 txOpParams.layer = 0;
481 txOpParams.harqId = 0;
483 txOpParams.rnti = m_rnti;
484 txOpParams.lcid = lc0Lcid;
485 lc0InfoIt->second.macSapUser->NotifyTxOpportunity(txOpParams);
486 lc0BsrIt->second.txQueueSize = 0;
487 }
488}
489
490void
492{
493 NS_LOG_FUNCTION(this << contention);
495 // 3GPP 36.321 5.1.4
497 // fire RA response timeout trace
499 contention,
503 {
504 NS_LOG_INFO("RAR timeout, preambleTransMax reached => giving up");
506 }
507 else
508 {
509 NS_LOG_INFO("RAR timeout, re-send preamble");
510 if (contention)
511 {
513 }
514 else
515 {
516 SendRaPreamble(contention);
517 }
518 }
519}
520
521void
523{
524 NS_LOG_FUNCTION(this);
525 m_rachConfig = rc;
526 m_rachConfigured = true;
527}
528
529void
531{
532 NS_LOG_FUNCTION(this);
533
534 // 3GPP 36.321 5.1.1
535 NS_ASSERT_MSG(m_rachConfigured, "RACH not configured");
539}
540
541void
543{
544 NS_LOG_FUNCTION(this);
545 m_rnti = rnti;
546}
547
548void
550{
551 NS_LOG_FUNCTION(this);
552 m_imsi = imsi;
553}
554
555void
557 uint8_t preambleId,
558 uint8_t prachMask)
559{
560 NS_LOG_FUNCTION(this << rnti << (uint16_t)preambleId << (uint16_t)prachMask);
561 NS_ASSERT_MSG(prachMask == 0,
562 "requested PRACH MASK = " << (uint32_t)prachMask
563 << ", but only PRACH MASK = 0 is supported");
564 m_rnti = rnti;
565 m_raPreambleId = preambleId;
567 bool contention = false;
568 SendRaPreamble(contention);
569}
570
571void
572LteUeMac::DoAddLc(uint8_t lcId,
574 LteMacSapUser* msu)
575{
576 NS_LOG_FUNCTION(this << " lcId" << (uint32_t)lcId);
577 NS_ASSERT_MSG(m_lcInfoMap.find(lcId) == m_lcInfoMap.end(),
578 "cannot add channel because LCID " << (uint16_t)lcId << " is already present");
579
580 LcInfo lcInfo;
581 lcInfo.lcConfig = lcConfig;
582 lcInfo.macSapUser = msu;
583 m_lcInfoMap[lcId] = lcInfo;
584}
585
586void
588{
589 NS_LOG_FUNCTION(this << " lcId" << lcId);
590 NS_ASSERT_MSG(m_lcInfoMap.find(lcId) != m_lcInfoMap.end(), "could not find LCID " << lcId);
591 m_lcInfoMap.erase(lcId);
592 m_ulBsrReceived.erase(lcId); // empty BSR buffer for this lcId
593}
594
595void
597{
598 NS_LOG_FUNCTION(this);
599 std::map<uint8_t, LcInfo>::iterator it = m_lcInfoMap.begin();
600 while (it != m_lcInfoMap.end())
601 {
602 // don't delete CCCH)
603 if (it->first == 0)
604 {
605 ++it;
606 }
607 else
608 {
609 // note: use of postfix operator preserves validity of iterator
610 m_lcInfoMap.erase(it++);
611 }
612 }
613 // note: rnti will be assigned by the eNB using RA response message
614 m_rnti = 0;
616 m_rachConfigured = false;
617 m_freshUlBsr = false;
618 m_ulBsrReceived.clear();
619}
620
621void
623{
624 NS_LOG_FUNCTION(this);
626}
627
628void
630{
632 p->RemovePacketTag(tag);
633 if (tag.GetRnti() == m_rnti)
634 {
635 // packet is for the current user
636 std::map<uint8_t, LcInfo>::const_iterator it = m_lcInfoMap.find(tag.GetLcid());
637 if (it != m_lcInfoMap.end())
638 {
640 rxPduParams.p = p;
641 rxPduParams.rnti = m_rnti;
642 rxPduParams.lcid = tag.GetLcid();
643 it->second.macSapUser->ReceivePdu(rxPduParams);
644 }
645 else
646 {
647 NS_LOG_WARN("received packet with unknown lcid " << (uint32_t)tag.GetLcid());
648 }
649 }
650}
651
652void
654{
655 NS_LOG_FUNCTION(this);
656 if (msg->GetMessageType() == LteControlMessage::UL_DCI)
657 {
658 Ptr<UlDciLteControlMessage> msg2 = DynamicCast<UlDciLteControlMessage>(msg);
659 UlDciListElement_s dci = msg2->GetDci();
660 if (dci.m_ndi == 1)
661 {
662 // New transmission -> empty pkt buffer queue (for deleting eventual pkts not acked )
663 Ptr<PacketBurst> pb = CreateObject<PacketBurst>();
665 // Retrieve data from RLC
666 std::map<uint8_t, LteMacSapProvider::ReportBufferStatusParameters>::iterator itBsr;
667 uint16_t activeLcs = 0;
668 uint32_t statusPduMinSize = 0;
669 for (itBsr = m_ulBsrReceived.begin(); itBsr != m_ulBsrReceived.end(); itBsr++)
670 {
671 if (((*itBsr).second.statusPduSize > 0) || ((*itBsr).second.retxQueueSize > 0) ||
672 ((*itBsr).second.txQueueSize > 0))
673 {
674 activeLcs++;
675 if (((*itBsr).second.statusPduSize != 0) &&
676 ((*itBsr).second.statusPduSize < statusPduMinSize))
677 {
678 statusPduMinSize = (*itBsr).second.statusPduSize;
679 }
680 if (((*itBsr).second.statusPduSize != 0) && (statusPduMinSize == 0))
681 {
682 statusPduMinSize = (*itBsr).second.statusPduSize;
683 }
684 }
685 }
686 if (activeLcs == 0)
687 {
688 NS_LOG_ERROR(this << " No active flows for this UL-DCI");
689 return;
690 }
691 std::map<uint8_t, LcInfo>::iterator it;
692 uint32_t bytesPerActiveLc = dci.m_tbSize / activeLcs;
693 bool statusPduPriority = false;
694 if ((statusPduMinSize != 0) && (bytesPerActiveLc < statusPduMinSize))
695 {
696 // send only the status PDU which has highest priority
697 statusPduPriority = true;
698 NS_LOG_DEBUG(this << " Reduced resource -> send only Status, b ytes "
699 << statusPduMinSize);
700 if (dci.m_tbSize < statusPduMinSize)
701 {
702 NS_FATAL_ERROR("Insufficient Tx Opportunity for sending a status message");
703 }
704 }
705 NS_LOG_LOGIC(this << " UE " << m_rnti << ": UL-CQI notified TxOpportunity of "
706 << dci.m_tbSize << " => " << bytesPerActiveLc
707 << " bytes per active LC"
708 << " statusPduMinSize " << statusPduMinSize);
709
711
712 for (it = m_lcInfoMap.begin(); it != m_lcInfoMap.end(); it++)
713 {
714 itBsr = m_ulBsrReceived.find((*it).first);
715 NS_LOG_DEBUG(this << " Processing LC " << (uint32_t)(*it).first
716 << " bytesPerActiveLc " << bytesPerActiveLc);
717 if ((itBsr != m_ulBsrReceived.end()) &&
718 (((*itBsr).second.statusPduSize > 0) || ((*itBsr).second.retxQueueSize > 0) ||
719 ((*itBsr).second.txQueueSize > 0)))
720 {
721 if ((statusPduPriority) && ((*itBsr).second.statusPduSize == statusPduMinSize))
722 {
723 txOpParams.bytes = (*itBsr).second.statusPduSize;
724 txOpParams.layer = 0;
725 txOpParams.harqId = 0;
727 txOpParams.rnti = m_rnti;
728 txOpParams.lcid = (*it).first;
729 (*it).second.macSapUser->NotifyTxOpportunity(txOpParams);
730 NS_LOG_LOGIC(this << "\t" << bytesPerActiveLc << " send "
731 << (*itBsr).second.statusPduSize << " status bytes to LC "
732 << (uint32_t)(*it).first << " statusQueue "
733 << (*itBsr).second.statusPduSize << " retxQueue"
734 << (*itBsr).second.retxQueueSize << " txQueue"
735 << (*itBsr).second.txQueueSize);
736 (*itBsr).second.statusPduSize = 0;
737 break;
738 }
739 else
740 {
741 uint32_t bytesForThisLc = bytesPerActiveLc;
742 NS_LOG_LOGIC(this << "\t" << bytesPerActiveLc << " bytes to LC "
743 << (uint32_t)(*it).first << " statusQueue "
744 << (*itBsr).second.statusPduSize << " retxQueue"
745 << (*itBsr).second.retxQueueSize << " txQueue"
746 << (*itBsr).second.txQueueSize);
747 if (((*itBsr).second.statusPduSize > 0) &&
748 (bytesForThisLc > (*itBsr).second.statusPduSize))
749 {
750 txOpParams.bytes = (*itBsr).second.statusPduSize;
751 txOpParams.layer = 0;
752 txOpParams.harqId = 0;
754 txOpParams.rnti = m_rnti;
755 txOpParams.lcid = (*it).first;
756 (*it).second.macSapUser->NotifyTxOpportunity(txOpParams);
757 bytesForThisLc -= (*itBsr).second.statusPduSize;
758 NS_LOG_DEBUG(this << " serve STATUS " << (*itBsr).second.statusPduSize);
759 (*itBsr).second.statusPduSize = 0;
760 }
761 else
762 {
763 if ((*itBsr).second.statusPduSize > bytesForThisLc)
764 {
766 "Insufficient Tx Opportunity for sending a status message");
767 }
768 }
769
770 if ((bytesForThisLc > 7) // 7 is the min TxOpportunity useful for Rlc
771 && (((*itBsr).second.retxQueueSize > 0) ||
772 ((*itBsr).second.txQueueSize > 0)))
773 {
774 if ((*itBsr).second.retxQueueSize > 0)
775 {
776 NS_LOG_DEBUG(this << " serve retx DATA, bytes " << bytesForThisLc);
777 txOpParams.bytes = bytesForThisLc;
778 txOpParams.layer = 0;
779 txOpParams.harqId = 0;
781 txOpParams.rnti = m_rnti;
782 txOpParams.lcid = (*it).first;
783 (*it).second.macSapUser->NotifyTxOpportunity(txOpParams);
784 if ((*itBsr).second.retxQueueSize >= bytesForThisLc)
785 {
786 (*itBsr).second.retxQueueSize -= bytesForThisLc;
787 }
788 else
789 {
790 (*itBsr).second.retxQueueSize = 0;
791 }
792 }
793 else if ((*itBsr).second.txQueueSize > 0)
794 {
795 uint16_t lcid = (*it).first;
796 uint32_t rlcOverhead;
797 if (lcid == 1)
798 {
799 // for SRB1 (using RLC AM) it's better to
800 // overestimate RLC overhead rather than
801 // underestimate it and risk unneeded
802 // segmentation which increases delay
803 rlcOverhead = 4;
804 }
805 else
806 {
807 // minimum RLC overhead due to header
808 rlcOverhead = 2;
809 }
810 NS_LOG_DEBUG(this << " serve tx DATA, bytes " << bytesForThisLc
811 << ", RLC overhead " << rlcOverhead);
812 txOpParams.bytes = bytesForThisLc;
813 txOpParams.layer = 0;
814 txOpParams.harqId = 0;
816 txOpParams.rnti = m_rnti;
817 txOpParams.lcid = (*it).first;
818 (*it).second.macSapUser->NotifyTxOpportunity(txOpParams);
819 if ((*itBsr).second.txQueueSize >= bytesForThisLc - rlcOverhead)
820 {
821 (*itBsr).second.txQueueSize -= bytesForThisLc - rlcOverhead;
822 }
823 else
824 {
825 (*itBsr).second.txQueueSize = 0;
826 }
827 }
828 }
829 else
830 {
831 if (((*itBsr).second.retxQueueSize > 0) ||
832 ((*itBsr).second.txQueueSize > 0))
833 {
834 // resend BSR info for updating eNB peer MAC
835 m_freshUlBsr = true;
836 }
837 }
838 NS_LOG_LOGIC(this << "\t" << bytesPerActiveLc << "\t new queues "
839 << (uint32_t)(*it).first << " statusQueue "
840 << (*itBsr).second.statusPduSize << " retxQueue"
841 << (*itBsr).second.retxQueueSize << " txQueue"
842 << (*itBsr).second.txQueueSize);
843 }
844 }
845 }
846 }
847 else
848 {
849 // HARQ retransmission -> retrieve data from HARQ buffer
850 NS_LOG_DEBUG(this << " UE MAC RETX HARQ " << (uint16_t)m_harqProcessId);
852 for (std::list<Ptr<Packet>>::const_iterator j = pb->Begin(); j != pb->End(); ++j)
853 {
854 Ptr<Packet> pkt = (*j)->Copy();
856 }
858 }
859 }
860 else if (msg->GetMessageType() == LteControlMessage::RAR)
861 {
863 {
864 Ptr<RarLteControlMessage> rarMsg = DynamicCast<RarLteControlMessage>(msg);
865 uint16_t raRnti = rarMsg->GetRaRnti();
866 NS_LOG_LOGIC(this << "got RAR with RA-RNTI " << (uint32_t)raRnti << ", expecting "
867 << (uint32_t)m_raRnti);
868 if (raRnti == m_raRnti) // RAR corresponds to TX subframe of preamble
869 {
870 for (std::list<RarLteControlMessage::Rar>::const_iterator it =
871 rarMsg->RarListBegin();
872 it != rarMsg->RarListEnd();
873 ++it)
874 {
875 if (it->rapId == m_raPreambleId) // RAR is for me
876 {
877 RecvRaResponse(it->rarPayload);
881 }
882 }
883 }
884 }
885 }
886 else
887 {
888 NS_LOG_WARN(this << " LteControlMessage not recognized");
889 }
890}
891
892void
894{
895 NS_LOG_FUNCTION(this);
896
897 for (std::size_t i = 0; i < m_miUlHarqProcessesPacketTimer.size(); i++)
898 {
899 if (m_miUlHarqProcessesPacketTimer.at(i) == 0)
900 {
901 if (m_miUlHarqProcessesPacket.at(i)->GetSize() > 0)
902 {
903 // timer expired: drop packets in buffer for this process
904 NS_LOG_INFO(this << " HARQ Proc Id " << i << " packets buffer expired");
905 Ptr<PacketBurst> emptyPb = CreateObject<PacketBurst>();
906 m_miUlHarqProcessesPacket.at(i) = emptyPb;
907 }
908 }
909 else
910 {
912 }
913 }
914}
915
916void
918{
919 NS_LOG_FUNCTION(this);
920 m_frameNo = frameNo;
921 m_subframeNo = subframeNo;
924 {
925 if (m_componentCarrierId == 0)
926 {
927 // Send BSR through primary carrier
929 }
931 m_freshUlBsr = false;
932 }
934}
935
936int64_t
938{
939 NS_LOG_FUNCTION(this << stream);
941 return 1;
942}
943
944} // namespace ns3
static uint8_t BufferSize2BsrId(uint32_t val)
Convert Buffer size to BSR ID.
Definition: lte-common.cc:183
void Cancel()
This method is syntactic sugar for the ns3::Simulator::Cancel method.
Definition: event-id.cc:55
Service Access Point (SAP) offered by the MAC to the RLC See Femto Forum MAC Scheduler Interface Spec...
Definition: lte-mac-sap.h:36
Service Access Point (SAP) offered by the MAC to the RLC See Femto Forum MAC Scheduler Interface Spec...
Definition: lte-mac-sap.h:96
Tag used to define the RNTI and LC id for each MAC packet trasmitted.
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.
virtual void NotifyRandomAccessFailed()=0
Notify the RRC that the MAC Random Access procedure failed.
virtual void NotifyRandomAccessSuccessful()=0
Notify the RRC that the MAC Random Access procedure completed successfully.
virtual void SetTemporaryCellRnti(uint16_t rnti)=0
uint8_t m_raRnti
RA RNTI.
Definition: lte-ue-mac.h:293
std::vector< Ptr< PacketBurst > > m_miUlHarqProcessesPacket
Packets under transmission of the UL HARQ processes.
Definition: lte-ue-mac.h:277
LteUePhySapUser * m_uePhySapUser
UE Phy SAP user.
Definition: lte-ue-mac.h:265
uint8_t m_componentCarrierId
component carrier Id --> used to address sap
Definition: lte-ue-mac.h:247
void RaResponseTimeout(bool contention)
RA response timeout function.
Definition: lte-ue-mac.cc:491
LteUeCmacSapProvider::RachConfig m_rachConfig
RACH configuration.
Definition: lte-ue-mac.h:284
uint32_t m_frameNo
frame number
Definition: lte-ue-mac.h:291
void DoSubframeIndication(uint32_t frameNo, uint32_t subframeNo)
Forwarded from LteUePhySapUser: trigger the start from a new frame.
Definition: lte-ue-mac.cc:917
void SendReportBufferStatus()
Send report buffer status.
Definition: lte-ue-mac.cc:354
void DoReportBufferStatus(LteMacSapProvider::ReportBufferStatusParameters params)
Report buffers status function.
Definition: lte-ue-mac.cc:332
TracedCallback< uint64_t, bool, uint8_t, uint8_t > m_raResponseTimeoutTrace
The RaResponseTimeout trace source.
Definition: lte-ue-mac.h:301
LteUePhySapProvider * m_uePhySapProvider
UE Phy SAP provider.
Definition: lte-ue-mac.h:264
void SetLteUePhySapProvider(LteUePhySapProvider *s)
Set the PHY SAP Provider.
Definition: lte-ue-mac.cc:289
Time m_bsrPeriodicity
BSR periodicity.
Definition: lte-ue-mac.h:270
void RefreshHarqProcessesPacketBuffer()
Refresh HARQ processes packet buffer function.
Definition: lte-ue-mac.cc:893
uint16_t m_imsi
IMSI.
Definition: lte-ue-mac.h:281
EventId m_noRaResponseReceivedEvent
no RA response received event ID
Definition: lte-ue-mac.h:288
LteUeCmacSapProvider * m_cmacSapProvider
CMAC SAP provider.
Definition: lte-ue-mac.h:262
uint8_t m_preambleTransmissionCounter
preamble tranamission counter
Definition: lte-ue-mac.h:286
Ptr< UniformRandomVariable > m_raPreambleUniformVariable
RA preamble random variable.
Definition: lte-ue-mac.h:289
void SetComponentCarrierId(uint8_t index)
Set the component carried ID.
Definition: lte-ue-mac.cc:313
int64_t AssignStreams(int64_t stream)
Assign a fixed random variable stream number to the random variables used by this model.
Definition: lte-ue-mac.cc:937
void DoConfigureRach(LteUeCmacSapProvider::RachConfig rc)
Configure RACH function.
Definition: lte-ue-mac.cc:522
LteUePhySapUser * GetLteUePhySapUser()
Get the PHY SAP user.
Definition: lte-ue-mac.cc:283
friend class UeMemberLteUePhySapUser
allow UeMemberLteUePhySapUser class friend access
Definition: lte-ue-mac.h:50
bool m_rachConfigured
is RACH configured?
Definition: lte-ue-mac.h:283
void DoRemoveLc(uint8_t lcId)
Remove LC function.
Definition: lte-ue-mac.cc:587
void RecvRaResponse(BuildRarListElement_s raResponse)
Receive the RA response function.
Definition: lte-ue-mac.cc:448
void DoReceivePhyPdu(Ptr< Packet > p)
Receive Phy PDU function.
Definition: lte-ue-mac.cc:629
uint8_t m_raPreambleId
RA preamble ID.
Definition: lte-ue-mac.h:285
void DoNotifyConnectionSuccessful()
Notify MAC about the successful RRC connection establishment.
Definition: lte-ue-mac.cc:622
Time m_bsrLast
BSR last.
Definition: lte-ue-mac.h:271
friend class UeMemberLteUeCmacSapProvider
allow UeMemberLteUeCmacSapProvider class friend access
Definition: lte-ue-mac.h:46
std::vector< uint8_t > m_miUlHarqProcessesPacketTimer
timer for packet life in the buffer
Definition: lte-ue-mac.h:278
void DoReceiveLteControlMessage(Ptr< LteControlMessage > msg)
Receive LTE control message function.
Definition: lte-ue-mac.cc:653
uint16_t m_rnti
RNTI.
Definition: lte-ue-mac.h:280
static TypeId GetTypeId()
Get the type ID.
Definition: lte-ue-mac.cc:223
void DoTransmitPdu(LteMacSapProvider::TransmitPduParameters params)
Transmit PDU function.
Definition: lte-ue-mac.cc:319
uint32_t m_subframeNo
subframe number
Definition: lte-ue-mac.h:292
std::map< uint8_t, LteMacSapProvider::ReportBufferStatusParameters > m_ulBsrReceived
BSR received from RLC (the last one)
Definition: lte-ue-mac.h:268
void DoDispose() override
Destructor implementation.
Definition: lte-ue-mac.cc:272
void DoReset()
Reset function.
Definition: lte-ue-mac.cc:596
~LteUeMac() override
Definition: lte-ue-mac.cc:266
LteUeCmacSapUser * m_cmacSapUser
CMAC SAP user.
Definition: lte-ue-mac.h:261
bool m_freshUlBsr
true when a BSR has been received in the last TTI
Definition: lte-ue-mac.h:273
LteMacSapProvider * GetLteMacSapProvider()
Get the LTE MAC SAP provider.
Definition: lte-ue-mac.cc:295
void DoStartNonContentionBasedRandomAccessProcedure(uint16_t rnti, uint8_t rapId, uint8_t prachMask)
Start non contention based random access procedure function.
Definition: lte-ue-mac.cc:556
LteUeCmacSapProvider * GetLteUeCmacSapProvider()
Get the LTE CMAC SAP provider.
Definition: lte-ue-mac.cc:307
bool m_waitingForRaResponse
waiting for RA response
Definition: lte-ue-mac.h:294
void DoAddLc(uint8_t lcId, LteUeCmacSapProvider::LogicalChannelConfig lcConfig, LteMacSapUser *msu)
Add LC function.
Definition: lte-ue-mac.cc:572
uint8_t m_harqProcessId
HARQ process ID.
Definition: lte-ue-mac.h:275
friend class UeMemberLteMacSapProvider
allow UeMemberLteMacSapProvider class friend access
Definition: lte-ue-mac.h:48
LteMacSapProvider * m_macSapProvider
MAC SAP provider.
Definition: lte-ue-mac.h:259
void RandomlySelectAndSendRaPreamble()
Randomly select and send RA preamble function.
Definition: lte-ue-mac.cc:404
void DoStartContentionBasedRandomAccessProcedure()
Start contention based random access procedure function.
Definition: lte-ue-mac.cc:530
uint16_t m_backoffParameter
backoff parameter
Definition: lte-ue-mac.h:287
void StartWaitingForRaResponse()
Start waiting for RA response function.
Definition: lte-ue-mac.cc:441
void DoSetRnti(uint16_t rnti)
Set RNTI.
Definition: lte-ue-mac.cc:542
void DoSetImsi(uint64_t imsi)
Set IMSI.
Definition: lte-ue-mac.cc:549
void SendRaPreamble(bool contention)
Send RA preamble function.
Definition: lte-ue-mac.cc:417
void SetLteUeCmacSapUser(LteUeCmacSapUser *s)
Set the LTE UE CMAC SAP user.
Definition: lte-ue-mac.cc:301
std::map< uint8_t, LcInfo > m_lcInfoMap
logical channel info map
Definition: lte-ue-mac.h:257
Service Access Point (SAP) offered by the UE-PHY to the UE-MAC.
virtual void SendLteControlMessage(Ptr< LteControlMessage > msg)=0
Send SendLteControlMessage (PDCCH map, CQI feedbacks) using the ideal control channel.
virtual void SendRachPreamble(uint32_t prachId, uint32_t raRnti)=0
Send a preamble on the PRACH.
virtual void NotifyConnectionSuccessful()=0
Notify PHY about the successful RRC connection establishment.
virtual void SendMacPdu(Ptr< Packet > p)=0
Send the MAC PDU to the channel.
Service Access Point (SAP) offered by the PHY to the MAC.
A base class which provides memory management and object aggregation.
Definition: object.h:89
virtual void DoDispose()
Destructor implementation.
Definition: object.cc:353
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:78
void SetStream(int64_t stream)
Specifies the stream number for the RngStream.
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:568
static Time Now()
Return the current simulation virtual time.
Definition: simulator.cc:199
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:936
UeMemberLteMacSapProvider class.
Definition: lte-ue-mac.cc:139
LteUeMac * m_mac
the UE MAC
Definition: lte-ue-mac.cc:153
void TransmitPdu(TransmitPduParameters params) override
send an RLC PDU to the MAC for transmission.
Definition: lte-ue-mac.cc:162
void ReportBufferStatus(ReportBufferStatusParameters params) override
Report the RLC buffer status to the MAC.
Definition: lte-ue-mac.cc:168
UeMemberLteMacSapProvider(LteUeMac *mac)
Constructor.
Definition: lte-ue-mac.cc:156
UeMemberLteUeCmacSapProvider class.
Definition: lte-ue-mac.cc:48
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...
Definition: lte-ue-mac.cc:94
LteUeMac * m_mac
the UE MAC
Definition: lte-ue-mac.cc:73
void SetImsi(uint64_t imsi) override
A method call by UE RRC to communicate the IMSI to the UE MAC.
Definition: lte-ue-mac.cc:132
void Reset() override
reset the MAC
Definition: lte-ue-mac.cc:120
void StartContentionBasedRandomAccessProcedure() override
tell the MAC to start a contention-based random access procedure, e.g., to perform RRC connection est...
Definition: lte-ue-mac.cc:88
void AddLc(uint8_t lcId, LteUeCmacSapProvider::LogicalChannelConfig lcConfig, LteMacSapUser *msu) override
add a new Logical Channel (LC)
Definition: lte-ue-mac.cc:108
void RemoveLc(uint8_t lcId) override
remove an existing LC
Definition: lte-ue-mac.cc:114
void SetRnti(uint16_t rnti) override
Definition: lte-ue-mac.cc:102
void ConfigureRach(RachConfig rc) override
Configure RACH function.
Definition: lte-ue-mac.cc:82
void NotifyConnectionSuccessful() override
Notify MAC about the successful RRC connection establishment.
Definition: lte-ue-mac.cc:126
UeMemberLteUeCmacSapProvider(LteUeMac *mac)
Constructor.
Definition: lte-ue-mac.cc:76
UeMemberLteUePhySapUser.
Definition: lte-ue-mac.cc:177
UeMemberLteUePhySapUser(LteUeMac *mac)
Constructor.
Definition: lte-ue-mac.cc:195
LteUeMac * m_mac
the UE MAC
Definition: lte-ue-mac.cc:192
void ReceiveLteControlMessage(Ptr< LteControlMessage > msg) override
Receive SendLteControlMessage (PDCCH map, CQI feedbacks) using the ideal control channel.
Definition: lte-ue-mac.cc:213
void ReceivePhyPdu(Ptr< Packet > p) override
Receive Phy Pdu function.
Definition: lte-ue-mac.cc:201
void SubframeIndication(uint32_t frameNo, uint32_t subframeNo) override
Trigger the start from a new frame (input from Phy layer)
Definition: lte-ue-mac.cc:207
uint32_t GetInteger(uint32_t min, uint32_t max)
Get the next random value drawn from the distribution.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:66
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition: assert.h:86
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:179
#define NS_LOG_ERROR(msg)
Use NS_LOG to output a message of level LOG_ERROR.
Definition: log.h:254
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:268
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:282
#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.
Definition: log.h:261
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:275
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:46
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1348
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
#define HARQ_PERIOD
Definition: lte-common.h:30
Every class exported by the ns3 library is enclosed in the ns3 namespace.
See section 4.3.10 buildRARListElement.
Parameters for LteMacSapProvider::ReportBufferStatus.
Definition: lte-mac-sap.h:69
Parameters for LteMacSapProvider::TransmitPdu.
Definition: lte-mac-sap.h:45
Parameters for LteMacSapUser::ReceivePdu.
Definition: lte-mac-sap.h:166
Ptr< Packet > p
the RLC PDU to be received
Definition: lte-mac-sap.h:187
uint8_t lcid
the logical channel id
Definition: lte-mac-sap.h:189
uint16_t rnti
the C-RNTI identifying the UE
Definition: lte-mac-sap.h:188
Parameters for LteMacSapUser::NotifyTxOpportunity.
Definition: lte-mac-sap.h:105
uint16_t rnti
the C-RNTI identifying the UE
Definition: lte-mac-sap.h:141
uint32_t bytes
the number of bytes to transmit
Definition: lte-mac-sap.h:137
uint8_t componentCarrierId
the component carrier id
Definition: lte-mac-sap.h:140
uint8_t layer
the layer of transmission (MIMO)
Definition: lte-mac-sap.h:138
uint8_t lcid
the logical channel id
Definition: lte-mac-sap.h:142
uint8_t raResponseWindowSize
RA response window size.
uint8_t preambleTransMax
preamble transmit maximum
uint8_t numberOfRaPreambles
number of RA preambles
LcInfo structure.
Definition: lte-ue-mac.h:252
LteUeCmacSapProvider::LogicalChannelConfig lcConfig
logical channel config
Definition: lte-ue-mac.h:253
LteMacSapUser * macSapUser
MAC SAP user.
Definition: lte-ue-mac.h:254
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.
uint16_t m_tbSize
size