A Discrete-Event Network Simulator
API
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"
25 #include "lte-control-messages.h"
26 #include "lte-radio-bearer-tag.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 
35 namespace ns3
36 {
37 
38 NS_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 
81 void
83 {
85 }
86 
87 void
89 {
91 }
92 
93 void
95  uint8_t preambleId,
96  uint8_t prachMask)
97 {
98  m_mac->DoStartNonContentionBasedRandomAccessProcedure(rnti, preambleId, prachMask);
99 }
100 
101 void
103 {
104  m_mac->DoSetRnti(rnti);
105 }
106 
107 void
109 {
110  m_mac->DoAddLc(lcId, lcConfig, msu);
111 }
112 
113 void
115 {
116  m_mac->DoRemoveLc(lcid);
117 }
118 
119 void
121 {
122  m_mac->DoReset();
123 }
124 
125 void
127 {
129 }
130 
131 void
133 {
134  m_mac->DoSetImsi(imsi);
135 }
136 
139 {
140  public:
147 
148  // inherited from LteMacSapProvider
151 
152  private:
154 };
155 
157  : m_mac(mac)
158 {
159 }
160 
161 void
163 {
165 }
166 
167 void
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 
200 void
202 {
204 }
205 
206 void
207 UeMemberLteUePhySapUser::SubframeIndication(uint32_t frameNo, uint32_t subframeNo)
208 {
209  m_mac->DoSubframeIndication(frameNo, subframeNo);
210 }
211 
212 void
214 {
216 }
217 
219 // LteUeMac methods
221 
222 TypeId
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 
271 void
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 
288 void
290 {
291  m_uePhySapProvider = s;
292 }
293 
296 {
297  return m_macSapProvider;
298 }
299 
300 void
302 {
303  m_cmacSapUser = s;
304 }
305 
308 {
309  return m_cmacSapProvider;
310 }
311 
312 void
314 {
315  m_componentCarrierId = index;
316 }
317 
318 void
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
329 }
330 
331 void
333 {
334  NS_LOG_FUNCTION(this << (uint32_t)params.lcid);
335 
336  auto it = m_ulBsrReceived.find(params.lcid);
337  if (it != m_ulBsrReceived.end())
338  {
339  // update entry
340  (*it).second = params;
341  }
342  else
343  {
344  m_ulBsrReceived.insert(
345  std::pair<uint8_t, LteMacSapProvider::ReportBufferStatusParameters>(params.lcid,
346  params));
347  }
348  m_freshUlBsr = true;
349 }
350 
351 void
353 {
354  NS_LOG_FUNCTION(this);
355 
356  if (m_rnti == 0)
357  {
358  NS_LOG_INFO("MAC not initialized, BSR deferred");
359  return;
360  }
361 
362  if (m_ulBsrReceived.empty())
363  {
364  NS_LOG_INFO("No BSR report to transmit");
365  return;
366  }
367  MacCeListElement_s bsr;
368  bsr.m_rnti = m_rnti;
369  bsr.m_macCeType = MacCeListElement_s::BSR;
370 
371  // BSR is reported for each LCG
372  std::vector<uint32_t> queue(4, 0); // one value per each of the 4 LCGs, initialized to 0
373  for (auto it = m_ulBsrReceived.begin(); it != m_ulBsrReceived.end(); it++)
374  {
375  uint8_t lcid = it->first;
376  auto lcInfoMapIt = m_lcInfoMap.find(lcid);
377  NS_ASSERT(lcInfoMapIt != m_lcInfoMap.end());
378  NS_ASSERT_MSG((lcid != 0) ||
379  (((*it).second.txQueueSize == 0) && ((*it).second.retxQueueSize == 0) &&
380  ((*it).second.statusPduSize == 0)),
381  "BSR should not be used for LCID 0");
382  uint8_t lcg = lcInfoMapIt->second.lcConfig.logicalChannelGroup;
383  queue.at(lcg) +=
384  ((*it).second.txQueueSize + (*it).second.retxQueueSize + (*it).second.statusPduSize);
385  }
386 
387  // FF API says that all 4 LCGs are always present
392 
393  // create the feedback to eNB
394  Ptr<BsrLteControlMessage> msg = Create<BsrLteControlMessage>();
395  msg->SetBsr(bsr);
397 }
398 
399 void
401 {
402  NS_LOG_FUNCTION(this);
403  // 3GPP 36.321 5.1.1
404  NS_ASSERT_MSG(m_rachConfigured, "RACH not configured");
405  // assume that there is no Random Access Preambles group B
408  bool contention = true;
409  SendRaPreamble(contention);
410 }
411 
412 void
413 LteUeMac::SendRaPreamble(bool contention)
414 {
415  NS_LOG_FUNCTION(this << (uint32_t)m_raPreambleId << contention);
416  // Since regular UL LteControlMessages need m_ulConfigured = true in
417  // order to be sent by the UE, the rach preamble needs to be sent
418  // with a dedicated primitive (not
419  // m_uePhySapProvider->SendLteControlMessage (msg)) so that it can
420  // bypass the m_ulConfigured flag. This is reasonable, since In fact
421  // the RACH preamble is sent on 6RB bandwidth so the uplink
422  // bandwidth does not need to be configured.
423  NS_ASSERT(m_subframeNo > 0); // sanity check for subframe starting at 1
424  m_raRnti = m_subframeNo - 1;
426  NS_LOG_INFO(this << " sent preamble id " << (uint32_t)m_raPreambleId << ", RA-RNTI "
427  << (uint32_t)m_raRnti);
428  // 3GPP 36.321 5.1.4
429  Time raWindowBegin = MilliSeconds(3);
433  Simulator::Schedule(raWindowEnd, &LteUeMac::RaResponseTimeout, this, contention);
434 }
435 
436 void
438 {
439  NS_LOG_FUNCTION(this);
440  m_waitingForRaResponse = true;
441 }
442 
443 void
445 {
446  NS_LOG_FUNCTION(this);
447  m_waitingForRaResponse = false;
449  NS_LOG_INFO("got RAR for RAPID " << (uint32_t)m_raPreambleId
450  << ", setting T-C-RNTI = " << raResponse.m_rnti);
451  m_rnti = raResponse.m_rnti;
453  // in principle we should wait for contention resolution,
454  // but in the current LTE model when two or more identical
455  // preambles are sent no one is received, so there is no need
456  // for contention resolution
458  // trigger tx opportunity for Message 3 over LC 0
459  // this is needed since Message 3's UL GRANT is in the RAR, not in UL-DCIs
460  const uint8_t lc0Lcid = 0;
461  auto lc0InfoIt = m_lcInfoMap.find(lc0Lcid);
462  NS_ASSERT(lc0InfoIt != m_lcInfoMap.end());
463  auto lc0BsrIt = m_ulBsrReceived.find(lc0Lcid);
464  if ((lc0BsrIt != m_ulBsrReceived.end()) && (lc0BsrIt->second.txQueueSize > 0))
465  {
466  NS_ASSERT_MSG(raResponse.m_grant.m_tbSize > lc0BsrIt->second.txQueueSize,
467  "segmentation of Message 3 is not allowed");
468  // this function can be called only from primary carrier
469  if (m_componentCarrierId > 0)
470  {
471  NS_FATAL_ERROR("Function called on wrong componentCarrier");
472  }
474  txOpParams.bytes = raResponse.m_grant.m_tbSize;
475  txOpParams.layer = 0;
476  txOpParams.harqId = 0;
478  txOpParams.rnti = m_rnti;
479  txOpParams.lcid = lc0Lcid;
480  lc0InfoIt->second.macSapUser->NotifyTxOpportunity(txOpParams);
481  lc0BsrIt->second.txQueueSize = 0;
482  }
483 }
484 
485 void
487 {
488  NS_LOG_FUNCTION(this << contention);
489  m_waitingForRaResponse = false;
490  // 3GPP 36.321 5.1.4
492  // fire RA response timeout trace
494  contention,
498  {
499  NS_LOG_INFO("RAR timeout, preambleTransMax reached => giving up");
501  }
502  else
503  {
504  NS_LOG_INFO("RAR timeout, re-send preamble");
505  if (contention)
506  {
508  }
509  else
510  {
511  SendRaPreamble(contention);
512  }
513  }
514 }
515 
516 void
518 {
519  NS_LOG_FUNCTION(this);
520  m_rachConfig = rc;
521  m_rachConfigured = true;
522 }
523 
524 void
526 {
527  NS_LOG_FUNCTION(this);
528 
529  // 3GPP 36.321 5.1.1
530  NS_ASSERT_MSG(m_rachConfigured, "RACH not configured");
532  m_backoffParameter = 0;
534 }
535 
536 void
537 LteUeMac::DoSetRnti(uint16_t rnti)
538 {
539  NS_LOG_FUNCTION(this);
540  m_rnti = rnti;
541 }
542 
543 void
544 LteUeMac::DoSetImsi(uint64_t imsi)
545 {
546  NS_LOG_FUNCTION(this);
547  m_imsi = imsi;
548 }
549 
550 void
552  uint8_t preambleId,
553  uint8_t prachMask)
554 {
555  NS_LOG_FUNCTION(this << rnti << (uint16_t)preambleId << (uint16_t)prachMask);
556  NS_ASSERT_MSG(prachMask == 0,
557  "requested PRACH MASK = " << (uint32_t)prachMask
558  << ", but only PRACH MASK = 0 is supported");
559  m_rnti = rnti;
560  m_raPreambleId = preambleId;
562  bool contention = false;
563  SendRaPreamble(contention);
564 }
565 
566 void
567 LteUeMac::DoAddLc(uint8_t lcId,
569  LteMacSapUser* msu)
570 {
571  NS_LOG_FUNCTION(this << " lcId" << (uint32_t)lcId);
572  NS_ASSERT_MSG(m_lcInfoMap.find(lcId) == m_lcInfoMap.end(),
573  "cannot add channel because LCID " << (uint16_t)lcId << " is already present");
574 
575  LcInfo lcInfo;
576  lcInfo.lcConfig = lcConfig;
577  lcInfo.macSapUser = msu;
578  m_lcInfoMap[lcId] = lcInfo;
579 }
580 
581 void
582 LteUeMac::DoRemoveLc(uint8_t lcId)
583 {
584  NS_LOG_FUNCTION(this << " lcId" << lcId);
585  NS_ASSERT_MSG(m_lcInfoMap.find(lcId) != m_lcInfoMap.end(), "could not find LCID " << lcId);
586  m_lcInfoMap.erase(lcId);
587  m_ulBsrReceived.erase(lcId); // empty BSR buffer for this lcId
588 }
589 
590 void
592 {
593  NS_LOG_FUNCTION(this);
594  auto it = m_lcInfoMap.begin();
595  while (it != m_lcInfoMap.end())
596  {
597  // don't delete CCCH)
598  if (it->first == 0)
599  {
600  ++it;
601  }
602  else
603  {
604  // note: use of postfix operator preserves validity of iterator
605  m_lcInfoMap.erase(it++);
606  }
607  }
608  // note: rnti will be assigned by the eNB using RA response message
609  m_rnti = 0;
611  m_rachConfigured = false;
612  m_freshUlBsr = false;
613  m_ulBsrReceived.clear();
614 }
615 
616 void
618 {
619  NS_LOG_FUNCTION(this);
621 }
622 
623 void
625 {
626  LteRadioBearerTag tag;
627  p->RemovePacketTag(tag);
628  if (tag.GetRnti() == m_rnti)
629  {
630  // packet is for the current user
631  auto it = m_lcInfoMap.find(tag.GetLcid());
632  if (it != m_lcInfoMap.end())
633  {
635  rxPduParams.p = p;
636  rxPduParams.rnti = m_rnti;
637  rxPduParams.lcid = tag.GetLcid();
638  it->second.macSapUser->ReceivePdu(rxPduParams);
639  }
640  else
641  {
642  NS_LOG_WARN("received packet with unknown lcid " << (uint32_t)tag.GetLcid());
643  }
644  }
645 }
646 
647 void
649 {
650  NS_LOG_FUNCTION(this);
651  if (msg->GetMessageType() == LteControlMessage::UL_DCI)
652  {
653  Ptr<UlDciLteControlMessage> msg2 = DynamicCast<UlDciLteControlMessage>(msg);
654  UlDciListElement_s dci = msg2->GetDci();
655  if (dci.m_ndi == 1)
656  {
657  // New transmission -> empty pkt buffer queue (for deleting eventual pkts not acked )
658  Ptr<PacketBurst> pb = CreateObject<PacketBurst>();
660  // Retrieve data from RLC
661  uint16_t activeLcs = 0;
662  uint32_t statusPduMinSize = 0;
663  for (auto itBsr = m_ulBsrReceived.begin(); itBsr != m_ulBsrReceived.end(); itBsr++)
664  {
665  if (((*itBsr).second.statusPduSize > 0) || ((*itBsr).second.retxQueueSize > 0) ||
666  ((*itBsr).second.txQueueSize > 0))
667  {
668  activeLcs++;
669  if (((*itBsr).second.statusPduSize != 0) &&
670  ((*itBsr).second.statusPduSize < statusPduMinSize))
671  {
672  statusPduMinSize = (*itBsr).second.statusPduSize;
673  }
674  if (((*itBsr).second.statusPduSize != 0) && (statusPduMinSize == 0))
675  {
676  statusPduMinSize = (*itBsr).second.statusPduSize;
677  }
678  }
679  }
680  if (activeLcs == 0)
681  {
682  NS_LOG_ERROR(this << " No active flows for this UL-DCI");
683  return;
684  }
685  uint32_t bytesPerActiveLc = dci.m_tbSize / activeLcs;
686  bool statusPduPriority = false;
687  if ((statusPduMinSize != 0) && (bytesPerActiveLc < statusPduMinSize))
688  {
689  // send only the status PDU which has highest priority
690  statusPduPriority = true;
691  NS_LOG_DEBUG(this << " Reduced resource -> send only Status, b ytes "
692  << statusPduMinSize);
693  if (dci.m_tbSize < statusPduMinSize)
694  {
695  NS_FATAL_ERROR("Insufficient Tx Opportunity for sending a status message");
696  }
697  }
698  NS_LOG_LOGIC(this << " UE " << m_rnti << ": UL-CQI notified TxOpportunity of "
699  << dci.m_tbSize << " => " << bytesPerActiveLc
700  << " bytes per active LC"
701  << " statusPduMinSize " << statusPduMinSize);
702 
704 
705  for (auto it = m_lcInfoMap.begin(); it != m_lcInfoMap.end(); it++)
706  {
707  auto itBsr = m_ulBsrReceived.find((*it).first);
708  NS_LOG_DEBUG(this << " Processing LC " << (uint32_t)(*it).first
709  << " bytesPerActiveLc " << bytesPerActiveLc);
710  if ((itBsr != m_ulBsrReceived.end()) &&
711  (((*itBsr).second.statusPduSize > 0) || ((*itBsr).second.retxQueueSize > 0) ||
712  ((*itBsr).second.txQueueSize > 0)))
713  {
714  if ((statusPduPriority) && ((*itBsr).second.statusPduSize == statusPduMinSize))
715  {
716  txOpParams.bytes = (*itBsr).second.statusPduSize;
717  txOpParams.layer = 0;
718  txOpParams.harqId = 0;
720  txOpParams.rnti = m_rnti;
721  txOpParams.lcid = (*it).first;
722  (*it).second.macSapUser->NotifyTxOpportunity(txOpParams);
723  NS_LOG_LOGIC(this << "\t" << bytesPerActiveLc << " send "
724  << (*itBsr).second.statusPduSize << " status bytes to LC "
725  << (uint32_t)(*it).first << " statusQueue "
726  << (*itBsr).second.statusPduSize << " retxQueue"
727  << (*itBsr).second.retxQueueSize << " txQueue"
728  << (*itBsr).second.txQueueSize);
729  (*itBsr).second.statusPduSize = 0;
730  break;
731  }
732  else
733  {
734  uint32_t bytesForThisLc = bytesPerActiveLc;
735  NS_LOG_LOGIC(this << "\t" << bytesPerActiveLc << " bytes to LC "
736  << (uint32_t)(*it).first << " statusQueue "
737  << (*itBsr).second.statusPduSize << " retxQueue"
738  << (*itBsr).second.retxQueueSize << " txQueue"
739  << (*itBsr).second.txQueueSize);
740  if (((*itBsr).second.statusPduSize > 0) &&
741  (bytesForThisLc > (*itBsr).second.statusPduSize))
742  {
743  txOpParams.bytes = (*itBsr).second.statusPduSize;
744  txOpParams.layer = 0;
745  txOpParams.harqId = 0;
747  txOpParams.rnti = m_rnti;
748  txOpParams.lcid = (*it).first;
749  (*it).second.macSapUser->NotifyTxOpportunity(txOpParams);
750  bytesForThisLc -= (*itBsr).second.statusPduSize;
751  NS_LOG_DEBUG(this << " serve STATUS " << (*itBsr).second.statusPduSize);
752  (*itBsr).second.statusPduSize = 0;
753  }
754  else
755  {
756  if ((*itBsr).second.statusPduSize > bytesForThisLc)
757  {
759  "Insufficient Tx Opportunity for sending a status message");
760  }
761  }
762 
763  if ((bytesForThisLc > 7) // 7 is the min TxOpportunity useful for Rlc
764  && (((*itBsr).second.retxQueueSize > 0) ||
765  ((*itBsr).second.txQueueSize > 0)))
766  {
767  if ((*itBsr).second.retxQueueSize > 0)
768  {
769  NS_LOG_DEBUG(this << " serve retx DATA, bytes " << bytesForThisLc);
770  txOpParams.bytes = bytesForThisLc;
771  txOpParams.layer = 0;
772  txOpParams.harqId = 0;
774  txOpParams.rnti = m_rnti;
775  txOpParams.lcid = (*it).first;
776  (*it).second.macSapUser->NotifyTxOpportunity(txOpParams);
777  if ((*itBsr).second.retxQueueSize >= bytesForThisLc)
778  {
779  (*itBsr).second.retxQueueSize -= bytesForThisLc;
780  }
781  else
782  {
783  (*itBsr).second.retxQueueSize = 0;
784  }
785  }
786  else if ((*itBsr).second.txQueueSize > 0)
787  {
788  uint16_t lcid = (*it).first;
789  uint32_t rlcOverhead;
790  if (lcid == 1)
791  {
792  // for SRB1 (using RLC AM) it's better to
793  // overestimate RLC overhead rather than
794  // underestimate it and risk unneeded
795  // segmentation which increases delay
796  rlcOverhead = 4;
797  }
798  else
799  {
800  // minimum RLC overhead due to header
801  rlcOverhead = 2;
802  }
803  NS_LOG_DEBUG(this << " serve tx DATA, bytes " << bytesForThisLc
804  << ", RLC overhead " << rlcOverhead);
805  txOpParams.bytes = bytesForThisLc;
806  txOpParams.layer = 0;
807  txOpParams.harqId = 0;
809  txOpParams.rnti = m_rnti;
810  txOpParams.lcid = (*it).first;
811  (*it).second.macSapUser->NotifyTxOpportunity(txOpParams);
812  if ((*itBsr).second.txQueueSize >= bytesForThisLc - rlcOverhead)
813  {
814  (*itBsr).second.txQueueSize -= bytesForThisLc - rlcOverhead;
815  }
816  else
817  {
818  (*itBsr).second.txQueueSize = 0;
819  }
820  }
821  }
822  else
823  {
824  if (((*itBsr).second.retxQueueSize > 0) ||
825  ((*itBsr).second.txQueueSize > 0))
826  {
827  // resend BSR info for updating eNB peer MAC
828  m_freshUlBsr = true;
829  }
830  }
831  NS_LOG_LOGIC(this << "\t" << bytesPerActiveLc << "\t new queues "
832  << (uint32_t)(*it).first << " statusQueue "
833  << (*itBsr).second.statusPduSize << " retxQueue"
834  << (*itBsr).second.retxQueueSize << " txQueue"
835  << (*itBsr).second.txQueueSize);
836  }
837  }
838  }
839  }
840  else
841  {
842  // HARQ retransmission -> retrieve data from HARQ buffer
843  NS_LOG_DEBUG(this << " UE MAC RETX HARQ " << (uint16_t)m_harqProcessId);
845  for (auto j = pb->Begin(); j != pb->End(); ++j)
846  {
847  Ptr<Packet> pkt = (*j)->Copy();
849  }
851  }
852  }
853  else if (msg->GetMessageType() == LteControlMessage::RAR)
854  {
856  {
857  Ptr<RarLteControlMessage> rarMsg = DynamicCast<RarLteControlMessage>(msg);
858  uint16_t raRnti = rarMsg->GetRaRnti();
859  NS_LOG_LOGIC(this << "got RAR with RA-RNTI " << (uint32_t)raRnti << ", expecting "
860  << (uint32_t)m_raRnti);
861  if (raRnti == m_raRnti) // RAR corresponds to TX subframe of preamble
862  {
863  for (auto it = rarMsg->RarListBegin(); it != rarMsg->RarListEnd(); ++it)
864  {
865  if (it->rapId == m_raPreambleId) // RAR is for me
866  {
867  RecvRaResponse(it->rarPayload);
871  }
872  }
873  }
874  }
875  }
876  else
877  {
878  NS_LOG_WARN(this << " LteControlMessage not recognized");
879  }
880 }
881 
882 void
884 {
885  NS_LOG_FUNCTION(this);
886 
887  for (std::size_t i = 0; i < m_miUlHarqProcessesPacketTimer.size(); i++)
888  {
889  if (m_miUlHarqProcessesPacketTimer.at(i) == 0)
890  {
891  if (m_miUlHarqProcessesPacket.at(i)->GetSize() > 0)
892  {
893  // timer expired: drop packets in buffer for this process
894  NS_LOG_INFO(this << " HARQ Proc Id " << i << " packets buffer expired");
895  Ptr<PacketBurst> emptyPb = CreateObject<PacketBurst>();
896  m_miUlHarqProcessesPacket.at(i) = emptyPb;
897  }
898  }
899  else
900  {
902  }
903  }
904 }
905 
906 void
907 LteUeMac::DoSubframeIndication(uint32_t frameNo, uint32_t subframeNo)
908 {
909  NS_LOG_FUNCTION(this);
910  m_frameNo = frameNo;
911  m_subframeNo = subframeNo;
914  {
915  if (m_componentCarrierId == 0)
916  {
917  // Send BSR through primary carrier
919  }
921  m_freshUlBsr = false;
922  }
924 }
925 
926 int64_t
927 LteUeMac::AssignStreams(int64_t stream)
928 {
929  NS_LOG_FUNCTION(this << stream);
931  return 1;
932 }
933 
934 } // 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 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.
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:486
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:907
void SendReportBufferStatus()
Send report buffer status.
Definition: lte-ue-mac.cc:352
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:883
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:927
void DoConfigureRach(LteUeCmacSapProvider::RachConfig rc)
Configure RACH function.
Definition: lte-ue-mac.cc:517
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:582
void RecvRaResponse(BuildRarListElement_s raResponse)
Receive the RA response function.
Definition: lte-ue-mac.cc:444
void DoReceivePhyPdu(Ptr< Packet > p)
Receive Phy PDU function.
Definition: lte-ue-mac.cc:624
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:617
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:648
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:591
~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:551
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:567
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:400
void DoStartContentionBasedRandomAccessProcedure()
Start contention based random access procedure function.
Definition: lte-ue-mac.cc:525
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:437
void DoSetRnti(uint16_t rnti)
Set RNTI.
Definition: lte-ue-mac.cc:537
void DoSetImsi(uint64_t imsi)
Set IMSI.
Definition: lte-ue-mac.cc:544
void SendRaPreamble(bool contention)
Send RA preamble function.
Definition: lte-ue-mac.cc:413
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:352
bool RemovePacketTag(Tag &tag)
Remove a packet tag.
Definition: packet.cc:967
Ptr< Packet > Copy() const
performs a COW copy of the packet.
Definition: packet.cc:131
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:571
static Time Now()
Return the current simulation virtual time.
Definition: simulator.cc:208
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:931
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:1338
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.
mac
Definition: third.py:92
params
Fit Fluctuating Two Ray model to the 3GPP TR 38.901 using the Anderson-Darling goodness-of-fit ##.
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