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 "lte-radio-bearer-tag.h"
24 #include "lte-ue-net-device.h"
25 
26 #include <ns3/ff-mac-common.h>
27 #include <ns3/log.h>
28 #include <ns3/lte-common.h>
29 #include <ns3/lte-control-messages.h>
30 #include <ns3/packet-burst.h>
31 #include <ns3/packet.h>
32 #include <ns3/pointer.h>
33 #include <ns3/random-variable-stream.h>
34 #include <ns3/simulator.h>
35 
36 namespace ns3
37 {
38 
39 NS_LOG_COMPONENT_DEFINE("LteUeMac");
40 
42 
44 // SAP forwarders
46 
49 {
50  public:
57 
58  // inherited from LteUeCmacSapProvider
59  void ConfigureRach(RachConfig rc) override;
62  uint8_t preambleId,
63  uint8_t prachMask) override;
64  void SetRnti(uint16_t rnti) override;
65  void AddLc(uint8_t lcId,
67  LteMacSapUser* msu) override;
68  void RemoveLc(uint8_t lcId) override;
69  void Reset() override;
70  void NotifyConnectionSuccessful() override;
71  void SetImsi(uint64_t imsi) override;
72 
73  private:
75 };
76 
78  : m_mac(mac)
79 {
80 }
81 
82 void
84 {
86 }
87 
88 void
90 {
92 }
93 
94 void
96  uint8_t preambleId,
97  uint8_t prachMask)
98 {
99  m_mac->DoStartNonContentionBasedRandomAccessProcedure(rnti, preambleId, prachMask);
100 }
101 
102 void
104 {
105  m_mac->DoSetRnti(rnti);
106 }
107 
108 void
110 {
111  m_mac->DoAddLc(lcId, lcConfig, msu);
112 }
113 
114 void
116 {
117  m_mac->DoRemoveLc(lcid);
118 }
119 
120 void
122 {
123  m_mac->DoReset();
124 }
125 
126 void
128 {
130 }
131 
132 void
134 {
135  m_mac->DoSetImsi(imsi);
136 }
137 
140 {
141  public:
148 
149  // inherited from LteMacSapProvider
152 
153  private:
155 };
156 
158  : m_mac(mac)
159 {
160 }
161 
162 void
164 {
166 }
167 
168 void
170 {
172 }
173 
178 {
179  public:
186 
187  // inherited from LtePhySapUser
188  void ReceivePhyPdu(Ptr<Packet> p) override;
189  void SubframeIndication(uint32_t frameNo, uint32_t subframeNo) override;
191 
192  private:
194 };
195 
197  : m_mac(mac)
198 {
199 }
200 
201 void
203 {
205 }
206 
207 void
208 UeMemberLteUePhySapUser::SubframeIndication(uint32_t frameNo, uint32_t subframeNo)
209 {
210  m_mac->DoSubframeIndication(frameNo, subframeNo);
211 }
212 
213 void
215 {
217 }
218 
220 // LteUeMac methods
222 
223 TypeId
225 {
226  static TypeId tid =
227  TypeId("ns3::LteUeMac")
228  .SetParent<Object>()
229  .SetGroupName("Lte")
230  .AddConstructor<LteUeMac>()
231  .AddTraceSource("RaResponseTimeout",
232  "trace fired upon RA response timeout",
234  "ns3::LteUeMac::RaResponseTimeoutTracedCallback")
235 
236  ;
237  return tid;
238 }
239 
241  : m_bsrPeriodicity(MilliSeconds(1)), // ideal behavior
242  m_bsrLast(MilliSeconds(0)),
243  m_freshUlBsr(false),
244  m_harqProcessId(0),
245  m_rnti(0),
246  m_imsi(0),
247  m_rachConfigured(false),
248  m_waitingForRaResponse(false)
249 
250 {
251  NS_LOG_FUNCTION(this);
253  for (std::size_t i = 0; i < m_miUlHarqProcessesPacket.size(); i++)
254  {
255  Ptr<PacketBurst> pb = CreateObject<PacketBurst>();
256  m_miUlHarqProcessesPacket.at(i) = pb;
257  }
259 
263  m_raPreambleUniformVariable = CreateObject<UniformRandomVariable>();
265 }
266 
268 {
269  NS_LOG_FUNCTION(this);
270 }
271 
272 void
274 {
275  NS_LOG_FUNCTION(this);
277  delete m_macSapProvider;
278  delete m_cmacSapProvider;
279  delete m_uePhySapUser;
281 }
282 
285 {
286  return m_uePhySapUser;
287 }
288 
289 void
291 {
292  m_uePhySapProvider = s;
293 }
294 
297 {
298  return m_macSapProvider;
299 }
300 
301 void
303 {
304  m_cmacSapUser = s;
305 }
306 
309 {
310  return m_cmacSapProvider;
311 }
312 
313 void
315 {
316  m_componentCarrierId = index;
317 }
318 
319 void
321 {
322  NS_LOG_FUNCTION(this);
323  NS_ASSERT_MSG(m_rnti == params.rnti, "RNTI mismatch between RLC and MAC");
324  LteRadioBearerTag tag(params.rnti, params.lcid, 0 /* UE works in SISO mode*/);
325  params.pdu->AddPacketTag(tag);
326  // store pdu in HARQ buffer
330 }
331 
332 void
334 {
335  NS_LOG_FUNCTION(this << (uint32_t)params.lcid);
336 
337  std::map<uint8_t, LteMacSapProvider::ReportBufferStatusParameters>::iterator it;
338 
339  it = m_ulBsrReceived.find(params.lcid);
340  if (it != m_ulBsrReceived.end())
341  {
342  // update entry
343  (*it).second = params;
344  }
345  else
346  {
347  m_ulBsrReceived.insert(
348  std::pair<uint8_t, LteMacSapProvider::ReportBufferStatusParameters>(params.lcid,
349  params));
350  }
351  m_freshUlBsr = true;
352 }
353 
354 void
356 {
357  NS_LOG_FUNCTION(this);
358 
359  if (m_rnti == 0)
360  {
361  NS_LOG_INFO("MAC not initialized, BSR deferred");
362  return;
363  }
364 
365  if (m_ulBsrReceived.empty())
366  {
367  NS_LOG_INFO("No BSR report to transmit");
368  return;
369  }
370  MacCeListElement_s bsr;
371  bsr.m_rnti = m_rnti;
372  bsr.m_macCeType = MacCeListElement_s::BSR;
373 
374  // BSR is reported for each LCG
375  std::map<uint8_t, LteMacSapProvider::ReportBufferStatusParameters>::iterator it;
376  std::vector<uint32_t> queue(4, 0); // one value per each of the 4 LCGs, initialized to 0
377  for (it = m_ulBsrReceived.begin(); it != m_ulBsrReceived.end(); it++)
378  {
379  uint8_t lcid = it->first;
380  std::map<uint8_t, LcInfo>::iterator lcInfoMapIt;
381  lcInfoMapIt = m_lcInfoMap.find(lcid);
382  NS_ASSERT(lcInfoMapIt != m_lcInfoMap.end());
383  NS_ASSERT_MSG((lcid != 0) ||
384  (((*it).second.txQueueSize == 0) && ((*it).second.retxQueueSize == 0) &&
385  ((*it).second.statusPduSize == 0)),
386  "BSR should not be used for LCID 0");
387  uint8_t lcg = lcInfoMapIt->second.lcConfig.logicalChannelGroup;
388  queue.at(lcg) +=
389  ((*it).second.txQueueSize + (*it).second.retxQueueSize + (*it).second.statusPduSize);
390  }
391 
392  // FF API says that all 4 LCGs are always present
397 
398  // create the feedback to eNB
399  Ptr<BsrLteControlMessage> msg = Create<BsrLteControlMessage>();
400  msg->SetBsr(bsr);
402 }
403 
404 void
406 {
407  NS_LOG_FUNCTION(this);
408  // 3GPP 36.321 5.1.1
409  NS_ASSERT_MSG(m_rachConfigured, "RACH not configured");
410  // assume that there is no Random Access Preambles group B
413  bool contention = true;
414  SendRaPreamble(contention);
415 }
416 
417 void
418 LteUeMac::SendRaPreamble(bool contention)
419 {
420  NS_LOG_FUNCTION(this << (uint32_t)m_raPreambleId << contention);
421  // Since regular UL LteControlMessages need m_ulConfigured = true in
422  // order to be sent by the UE, the rach preamble needs to be sent
423  // with a dedicated primitive (not
424  // m_uePhySapProvider->SendLteControlMessage (msg)) so that it can
425  // bypass the m_ulConfigured flag. This is reasonable, since In fact
426  // the RACH preamble is sent on 6RB bandwidth so the uplink
427  // bandwidth does not need to be configured.
428  NS_ASSERT(m_subframeNo > 0); // sanity check for subframe starting at 1
429  m_raRnti = m_subframeNo - 1;
431  NS_LOG_INFO(this << " sent preamble id " << (uint32_t)m_raPreambleId << ", RA-RNTI "
432  << (uint32_t)m_raRnti);
433  // 3GPP 36.321 5.1.4
434  Time raWindowBegin = MilliSeconds(3);
438  Simulator::Schedule(raWindowEnd, &LteUeMac::RaResponseTimeout, this, contention);
439 }
440 
441 void
443 {
444  NS_LOG_FUNCTION(this);
445  m_waitingForRaResponse = true;
446 }
447 
448 void
450 {
451  NS_LOG_FUNCTION(this);
452  m_waitingForRaResponse = false;
454  NS_LOG_INFO("got RAR for RAPID " << (uint32_t)m_raPreambleId
455  << ", setting T-C-RNTI = " << raResponse.m_rnti);
456  m_rnti = raResponse.m_rnti;
458  // in principle we should wait for contention resolution,
459  // but in the current LTE model when two or more identical
460  // preambles are sent no one is received, so there is no need
461  // for contention resolution
463  // trigger tx opportunity for Message 3 over LC 0
464  // this is needed since Message 3's UL GRANT is in the RAR, not in UL-DCIs
465  const uint8_t lc0Lcid = 0;
466  std::map<uint8_t, LcInfo>::iterator lc0InfoIt = m_lcInfoMap.find(lc0Lcid);
467  NS_ASSERT(lc0InfoIt != m_lcInfoMap.end());
468  std::map<uint8_t, LteMacSapProvider::ReportBufferStatusParameters>::iterator lc0BsrIt =
469  m_ulBsrReceived.find(lc0Lcid);
470  if ((lc0BsrIt != m_ulBsrReceived.end()) && (lc0BsrIt->second.txQueueSize > 0))
471  {
472  NS_ASSERT_MSG(raResponse.m_grant.m_tbSize > lc0BsrIt->second.txQueueSize,
473  "segmentation of Message 3 is not allowed");
474  // this function can be called only from primary carrier
475  if (m_componentCarrierId > 0)
476  {
477  NS_FATAL_ERROR("Function called on wrong componentCarrier");
478  }
480  txOpParams.bytes = raResponse.m_grant.m_tbSize;
481  txOpParams.layer = 0;
482  txOpParams.harqId = 0;
484  txOpParams.rnti = m_rnti;
485  txOpParams.lcid = lc0Lcid;
486  lc0InfoIt->second.macSapUser->NotifyTxOpportunity(txOpParams);
487  lc0BsrIt->second.txQueueSize = 0;
488  }
489 }
490 
491 void
493 {
494  NS_LOG_FUNCTION(this << contention);
495  m_waitingForRaResponse = false;
496  // 3GPP 36.321 5.1.4
498  // fire RA response timeout trace
500  contention,
504  {
505  NS_LOG_INFO("RAR timeout, preambleTransMax reached => giving up");
507  }
508  else
509  {
510  NS_LOG_INFO("RAR timeout, re-send preamble");
511  if (contention)
512  {
514  }
515  else
516  {
517  SendRaPreamble(contention);
518  }
519  }
520 }
521 
522 void
524 {
525  NS_LOG_FUNCTION(this);
526  m_rachConfig = rc;
527  m_rachConfigured = true;
528 }
529 
530 void
532 {
533  NS_LOG_FUNCTION(this);
534 
535  // 3GPP 36.321 5.1.1
536  NS_ASSERT_MSG(m_rachConfigured, "RACH not configured");
538  m_backoffParameter = 0;
540 }
541 
542 void
543 LteUeMac::DoSetRnti(uint16_t rnti)
544 {
545  NS_LOG_FUNCTION(this);
546  m_rnti = rnti;
547 }
548 
549 void
550 LteUeMac::DoSetImsi(uint64_t imsi)
551 {
552  NS_LOG_FUNCTION(this);
553  m_imsi = imsi;
554 }
555 
556 void
558  uint8_t preambleId,
559  uint8_t prachMask)
560 {
561  NS_LOG_FUNCTION(this << rnti << (uint16_t)preambleId << (uint16_t)prachMask);
562  NS_ASSERT_MSG(prachMask == 0,
563  "requested PRACH MASK = " << (uint32_t)prachMask
564  << ", but only PRACH MASK = 0 is supported");
565  m_rnti = rnti;
566  m_raPreambleId = preambleId;
568  bool contention = false;
569  SendRaPreamble(contention);
570 }
571 
572 void
573 LteUeMac::DoAddLc(uint8_t lcId,
575  LteMacSapUser* msu)
576 {
577  NS_LOG_FUNCTION(this << " lcId" << (uint32_t)lcId);
578  NS_ASSERT_MSG(m_lcInfoMap.find(lcId) == m_lcInfoMap.end(),
579  "cannot add channel because LCID " << (uint16_t)lcId << " is already present");
580 
581  LcInfo lcInfo;
582  lcInfo.lcConfig = lcConfig;
583  lcInfo.macSapUser = msu;
584  m_lcInfoMap[lcId] = lcInfo;
585 }
586 
587 void
588 LteUeMac::DoRemoveLc(uint8_t lcId)
589 {
590  NS_LOG_FUNCTION(this << " lcId" << lcId);
591  NS_ASSERT_MSG(m_lcInfoMap.find(lcId) != m_lcInfoMap.end(), "could not find LCID " << lcId);
592  m_lcInfoMap.erase(lcId);
593  m_ulBsrReceived.erase(lcId); // empty BSR buffer for this lcId
594 }
595 
596 void
598 {
599  NS_LOG_FUNCTION(this);
600  std::map<uint8_t, LcInfo>::iterator it = m_lcInfoMap.begin();
601  while (it != m_lcInfoMap.end())
602  {
603  // don't delete CCCH)
604  if (it->first == 0)
605  {
606  ++it;
607  }
608  else
609  {
610  // note: use of postfix operator preserves validity of iterator
611  m_lcInfoMap.erase(it++);
612  }
613  }
614  // note: rnti will be assigned by the eNB using RA response message
615  m_rnti = 0;
617  m_rachConfigured = false;
618  m_freshUlBsr = false;
619  m_ulBsrReceived.clear();
620 }
621 
622 void
624 {
625  NS_LOG_FUNCTION(this);
627 }
628 
629 void
631 {
632  LteRadioBearerTag tag;
633  p->RemovePacketTag(tag);
634  if (tag.GetRnti() == m_rnti)
635  {
636  // packet is for the current user
637  std::map<uint8_t, LcInfo>::const_iterator it = m_lcInfoMap.find(tag.GetLcid());
638  if (it != m_lcInfoMap.end())
639  {
641  rxPduParams.p = p;
642  rxPduParams.rnti = m_rnti;
643  rxPduParams.lcid = tag.GetLcid();
644  it->second.macSapUser->ReceivePdu(rxPduParams);
645  }
646  else
647  {
648  NS_LOG_WARN("received packet with unknown lcid " << (uint32_t)tag.GetLcid());
649  }
650  }
651 }
652 
653 void
655 {
656  NS_LOG_FUNCTION(this);
657  if (msg->GetMessageType() == LteControlMessage::UL_DCI)
658  {
659  Ptr<UlDciLteControlMessage> msg2 = DynamicCast<UlDciLteControlMessage>(msg);
660  UlDciListElement_s dci = msg2->GetDci();
661  if (dci.m_ndi == 1)
662  {
663  // New transmission -> empty pkt buffer queue (for deleting eventual pkts not acked )
664  Ptr<PacketBurst> pb = CreateObject<PacketBurst>();
666  // Retrieve data from RLC
667  std::map<uint8_t, LteMacSapProvider::ReportBufferStatusParameters>::iterator itBsr;
668  uint16_t activeLcs = 0;
669  uint32_t statusPduMinSize = 0;
670  for (itBsr = m_ulBsrReceived.begin(); itBsr != m_ulBsrReceived.end(); itBsr++)
671  {
672  if (((*itBsr).second.statusPduSize > 0) || ((*itBsr).second.retxQueueSize > 0) ||
673  ((*itBsr).second.txQueueSize > 0))
674  {
675  activeLcs++;
676  if (((*itBsr).second.statusPduSize != 0) &&
677  ((*itBsr).second.statusPduSize < statusPduMinSize))
678  {
679  statusPduMinSize = (*itBsr).second.statusPduSize;
680  }
681  if (((*itBsr).second.statusPduSize != 0) && (statusPduMinSize == 0))
682  {
683  statusPduMinSize = (*itBsr).second.statusPduSize;
684  }
685  }
686  }
687  if (activeLcs == 0)
688  {
689  NS_LOG_ERROR(this << " No active flows for this UL-DCI");
690  return;
691  }
692  std::map<uint8_t, LcInfo>::iterator it;
693  uint32_t bytesPerActiveLc = dci.m_tbSize / activeLcs;
694  bool statusPduPriority = false;
695  if ((statusPduMinSize != 0) && (bytesPerActiveLc < statusPduMinSize))
696  {
697  // send only the status PDU which has highest priority
698  statusPduPriority = true;
699  NS_LOG_DEBUG(this << " Reduced resource -> send only Status, b ytes "
700  << statusPduMinSize);
701  if (dci.m_tbSize < statusPduMinSize)
702  {
703  NS_FATAL_ERROR("Insufficient Tx Opportunity for sending a status message");
704  }
705  }
706  NS_LOG_LOGIC(this << " UE " << m_rnti << ": UL-CQI notified TxOpportunity of "
707  << dci.m_tbSize << " => " << bytesPerActiveLc
708  << " bytes per active LC"
709  << " statusPduMinSize " << statusPduMinSize);
710 
712 
713  for (it = m_lcInfoMap.begin(); it != m_lcInfoMap.end(); it++)
714  {
715  itBsr = m_ulBsrReceived.find((*it).first);
716  NS_LOG_DEBUG(this << " Processing LC " << (uint32_t)(*it).first
717  << " bytesPerActiveLc " << bytesPerActiveLc);
718  if ((itBsr != m_ulBsrReceived.end()) &&
719  (((*itBsr).second.statusPduSize > 0) || ((*itBsr).second.retxQueueSize > 0) ||
720  ((*itBsr).second.txQueueSize > 0)))
721  {
722  if ((statusPduPriority) && ((*itBsr).second.statusPduSize == statusPduMinSize))
723  {
724  txOpParams.bytes = (*itBsr).second.statusPduSize;
725  txOpParams.layer = 0;
726  txOpParams.harqId = 0;
728  txOpParams.rnti = m_rnti;
729  txOpParams.lcid = (*it).first;
730  (*it).second.macSapUser->NotifyTxOpportunity(txOpParams);
731  NS_LOG_LOGIC(this << "\t" << bytesPerActiveLc << " send "
732  << (*itBsr).second.statusPduSize << " status bytes to LC "
733  << (uint32_t)(*it).first << " statusQueue "
734  << (*itBsr).second.statusPduSize << " retxQueue"
735  << (*itBsr).second.retxQueueSize << " txQueue"
736  << (*itBsr).second.txQueueSize);
737  (*itBsr).second.statusPduSize = 0;
738  break;
739  }
740  else
741  {
742  uint32_t bytesForThisLc = bytesPerActiveLc;
743  NS_LOG_LOGIC(this << "\t" << bytesPerActiveLc << " bytes to LC "
744  << (uint32_t)(*it).first << " statusQueue "
745  << (*itBsr).second.statusPduSize << " retxQueue"
746  << (*itBsr).second.retxQueueSize << " txQueue"
747  << (*itBsr).second.txQueueSize);
748  if (((*itBsr).second.statusPduSize > 0) &&
749  (bytesForThisLc > (*itBsr).second.statusPduSize))
750  {
751  txOpParams.bytes = (*itBsr).second.statusPduSize;
752  txOpParams.layer = 0;
753  txOpParams.harqId = 0;
755  txOpParams.rnti = m_rnti;
756  txOpParams.lcid = (*it).first;
757  (*it).second.macSapUser->NotifyTxOpportunity(txOpParams);
758  bytesForThisLc -= (*itBsr).second.statusPduSize;
759  NS_LOG_DEBUG(this << " serve STATUS " << (*itBsr).second.statusPduSize);
760  (*itBsr).second.statusPduSize = 0;
761  }
762  else
763  {
764  if ((*itBsr).second.statusPduSize > bytesForThisLc)
765  {
767  "Insufficient Tx Opportunity for sending a status message");
768  }
769  }
770 
771  if ((bytesForThisLc > 7) // 7 is the min TxOpportunity useful for Rlc
772  && (((*itBsr).second.retxQueueSize > 0) ||
773  ((*itBsr).second.txQueueSize > 0)))
774  {
775  if ((*itBsr).second.retxQueueSize > 0)
776  {
777  NS_LOG_DEBUG(this << " serve retx DATA, bytes " << bytesForThisLc);
778  txOpParams.bytes = bytesForThisLc;
779  txOpParams.layer = 0;
780  txOpParams.harqId = 0;
782  txOpParams.rnti = m_rnti;
783  txOpParams.lcid = (*it).first;
784  (*it).second.macSapUser->NotifyTxOpportunity(txOpParams);
785  if ((*itBsr).second.retxQueueSize >= bytesForThisLc)
786  {
787  (*itBsr).second.retxQueueSize -= bytesForThisLc;
788  }
789  else
790  {
791  (*itBsr).second.retxQueueSize = 0;
792  }
793  }
794  else if ((*itBsr).second.txQueueSize > 0)
795  {
796  uint16_t lcid = (*it).first;
797  uint32_t rlcOverhead;
798  if (lcid == 1)
799  {
800  // for SRB1 (using RLC AM) it's better to
801  // overestimate RLC overhead rather than
802  // underestimate it and risk unneeded
803  // segmentation which increases delay
804  rlcOverhead = 4;
805  }
806  else
807  {
808  // minimum RLC overhead due to header
809  rlcOverhead = 2;
810  }
811  NS_LOG_DEBUG(this << " serve tx DATA, bytes " << bytesForThisLc
812  << ", RLC overhead " << rlcOverhead);
813  txOpParams.bytes = bytesForThisLc;
814  txOpParams.layer = 0;
815  txOpParams.harqId = 0;
817  txOpParams.rnti = m_rnti;
818  txOpParams.lcid = (*it).first;
819  (*it).second.macSapUser->NotifyTxOpportunity(txOpParams);
820  if ((*itBsr).second.txQueueSize >= bytesForThisLc - rlcOverhead)
821  {
822  (*itBsr).second.txQueueSize -= bytesForThisLc - rlcOverhead;
823  }
824  else
825  {
826  (*itBsr).second.txQueueSize = 0;
827  }
828  }
829  }
830  else
831  {
832  if (((*itBsr).second.retxQueueSize > 0) ||
833  ((*itBsr).second.txQueueSize > 0))
834  {
835  // resend BSR info for updating eNB peer MAC
836  m_freshUlBsr = true;
837  }
838  }
839  NS_LOG_LOGIC(this << "\t" << bytesPerActiveLc << "\t new queues "
840  << (uint32_t)(*it).first << " statusQueue "
841  << (*itBsr).second.statusPduSize << " retxQueue"
842  << (*itBsr).second.retxQueueSize << " txQueue"
843  << (*itBsr).second.txQueueSize);
844  }
845  }
846  }
847  }
848  else
849  {
850  // HARQ retransmission -> retrieve data from HARQ buffer
851  NS_LOG_DEBUG(this << " UE MAC RETX HARQ " << (uint16_t)m_harqProcessId);
853  for (std::list<Ptr<Packet>>::const_iterator j = pb->Begin(); j != pb->End(); ++j)
854  {
855  Ptr<Packet> pkt = (*j)->Copy();
857  }
859  }
860  }
861  else if (msg->GetMessageType() == LteControlMessage::RAR)
862  {
864  {
865  Ptr<RarLteControlMessage> rarMsg = DynamicCast<RarLteControlMessage>(msg);
866  uint16_t raRnti = rarMsg->GetRaRnti();
867  NS_LOG_LOGIC(this << "got RAR with RA-RNTI " << (uint32_t)raRnti << ", expecting "
868  << (uint32_t)m_raRnti);
869  if (raRnti == m_raRnti) // RAR corresponds to TX subframe of preamble
870  {
871  for (std::list<RarLteControlMessage::Rar>::const_iterator it =
872  rarMsg->RarListBegin();
873  it != rarMsg->RarListEnd();
874  ++it)
875  {
876  if (it->rapId == m_raPreambleId) // RAR is for me
877  {
878  RecvRaResponse(it->rarPayload);
882  }
883  }
884  }
885  }
886  }
887  else
888  {
889  NS_LOG_WARN(this << " LteControlMessage not recognized");
890  }
891 }
892 
893 void
895 {
896  NS_LOG_FUNCTION(this);
897 
898  for (std::size_t i = 0; i < m_miUlHarqProcessesPacketTimer.size(); i++)
899  {
900  if (m_miUlHarqProcessesPacketTimer.at(i) == 0)
901  {
902  if (m_miUlHarqProcessesPacket.at(i)->GetSize() > 0)
903  {
904  // timer expired: drop packets in buffer for this process
905  NS_LOG_INFO(this << " HARQ Proc Id " << i << " packets buffer expired");
906  Ptr<PacketBurst> emptyPb = CreateObject<PacketBurst>();
907  m_miUlHarqProcessesPacket.at(i) = emptyPb;
908  }
909  }
910  else
911  {
913  }
914  }
915 }
916 
917 void
918 LteUeMac::DoSubframeIndication(uint32_t frameNo, uint32_t subframeNo)
919 {
920  NS_LOG_FUNCTION(this);
921  m_frameNo = frameNo;
922  m_subframeNo = subframeNo;
924  if ((Simulator::Now() >= m_bsrLast + m_bsrPeriodicity) && (m_freshUlBsr == true))
925  {
926  if (m_componentCarrierId == 0)
927  {
928  // Send BSR through primary carrier
930  }
932  m_freshUlBsr = false;
933  }
935 }
936 
937 int64_t
938 LteUeMac::AssignStreams(int64_t stream)
939 {
940  NS_LOG_FUNCTION(this << stream);
942  return 1;
943 }
944 
945 } // 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:291
std::vector< Ptr< PacketBurst > > m_miUlHarqProcessesPacket
Packets under transmission of the UL HARQ processes.
Definition: lte-ue-mac.h:275
LteUePhySapUser * m_uePhySapUser
UE Phy SAP user.
Definition: lte-ue-mac.h:263
uint8_t m_componentCarrierId
component carrier Id --> used to address sap
Definition: lte-ue-mac.h:245
void RaResponseTimeout(bool contention)
RA response timeout function.
Definition: lte-ue-mac.cc:492
LteUeCmacSapProvider::RachConfig m_rachConfig
RACH configuration.
Definition: lte-ue-mac.h:282
uint32_t m_frameNo
frame number
Definition: lte-ue-mac.h:289
void DoSubframeIndication(uint32_t frameNo, uint32_t subframeNo)
Forwarded from LteUePhySapUser: trigger the start from a new frame.
Definition: lte-ue-mac.cc:918
void SendReportBufferStatus()
Send report buffer status.
Definition: lte-ue-mac.cc:355
void DoReportBufferStatus(LteMacSapProvider::ReportBufferStatusParameters params)
Report buffers status function.
Definition: lte-ue-mac.cc:333
TracedCallback< uint64_t, bool, uint8_t, uint8_t > m_raResponseTimeoutTrace
The RaResponseTimeout trace source.
Definition: lte-ue-mac.h:299
LteUePhySapProvider * m_uePhySapProvider
UE Phy SAP provider.
Definition: lte-ue-mac.h:262
void SetLteUePhySapProvider(LteUePhySapProvider *s)
Set the PHY SAP Provider.
Definition: lte-ue-mac.cc:290
Time m_bsrPeriodicity
BSR periodicity.
Definition: lte-ue-mac.h:268
void RefreshHarqProcessesPacketBuffer()
Refresh HARQ processes packet buffer function.
Definition: lte-ue-mac.cc:894
uint16_t m_imsi
IMSI.
Definition: lte-ue-mac.h:279
EventId m_noRaResponseReceivedEvent
no RA response received event ID
Definition: lte-ue-mac.h:286
LteUeCmacSapProvider * m_cmacSapProvider
CMAC SAP provider.
Definition: lte-ue-mac.h:260
uint8_t m_preambleTransmissionCounter
preamble tranamission counter
Definition: lte-ue-mac.h:284
Ptr< UniformRandomVariable > m_raPreambleUniformVariable
RA preamble random variable.
Definition: lte-ue-mac.h:287
void SetComponentCarrierId(uint8_t index)
Set the component carried ID.
Definition: lte-ue-mac.cc:314
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:938
void DoConfigureRach(LteUeCmacSapProvider::RachConfig rc)
Configure RACH function.
Definition: lte-ue-mac.cc:523
LteUePhySapUser * GetLteUePhySapUser()
Get the PHY SAP user.
Definition: lte-ue-mac.cc:284
friend class UeMemberLteUePhySapUser
allow UeMemberLteUePhySapUser class friend access
Definition: lte-ue-mac.h:48
bool m_rachConfigured
is RACH configured?
Definition: lte-ue-mac.h:281
void DoRemoveLc(uint8_t lcId)
Remove LC function.
Definition: lte-ue-mac.cc:588
void RecvRaResponse(BuildRarListElement_s raResponse)
Receive the RA response function.
Definition: lte-ue-mac.cc:449
void DoReceivePhyPdu(Ptr< Packet > p)
Receive Phy PDU function.
Definition: lte-ue-mac.cc:630
uint8_t m_raPreambleId
RA preamble ID.
Definition: lte-ue-mac.h:283
void DoNotifyConnectionSuccessful()
Notify MAC about the successful RRC connection establishment.
Definition: lte-ue-mac.cc:623
Time m_bsrLast
BSR last.
Definition: lte-ue-mac.h:269
friend class UeMemberLteUeCmacSapProvider
allow UeMemberLteUeCmacSapProvider class friend access
Definition: lte-ue-mac.h:44
std::vector< uint8_t > m_miUlHarqProcessesPacketTimer
timer for packet life in the buffer
Definition: lte-ue-mac.h:276
void DoReceiveLteControlMessage(Ptr< LteControlMessage > msg)
Receive LTE control message function.
Definition: lte-ue-mac.cc:654
uint16_t m_rnti
RNTI.
Definition: lte-ue-mac.h:278
static TypeId GetTypeId()
Get the type ID.
Definition: lte-ue-mac.cc:224
void DoTransmitPdu(LteMacSapProvider::TransmitPduParameters params)
Transmit PDU function.
Definition: lte-ue-mac.cc:320
uint32_t m_subframeNo
subframe number
Definition: lte-ue-mac.h:290
std::map< uint8_t, LteMacSapProvider::ReportBufferStatusParameters > m_ulBsrReceived
BSR received from RLC (the last one)
Definition: lte-ue-mac.h:266
void DoDispose() override
Destructor implementation.
Definition: lte-ue-mac.cc:273
void DoReset()
Reset function.
Definition: lte-ue-mac.cc:597
~LteUeMac() override
Definition: lte-ue-mac.cc:267
LteUeCmacSapUser * m_cmacSapUser
CMAC SAP user.
Definition: lte-ue-mac.h:259
bool m_freshUlBsr
true when a BSR has been received in the last TTI
Definition: lte-ue-mac.h:271
LteMacSapProvider * GetLteMacSapProvider()
Get the LTE MAC SAP provider.
Definition: lte-ue-mac.cc:296
void DoStartNonContentionBasedRandomAccessProcedure(uint16_t rnti, uint8_t rapId, uint8_t prachMask)
Start non contention based random access procedure function.
Definition: lte-ue-mac.cc:557
LteUeCmacSapProvider * GetLteUeCmacSapProvider()
Get the LTE CMAC SAP provider.
Definition: lte-ue-mac.cc:308
bool m_waitingForRaResponse
waiting for RA response
Definition: lte-ue-mac.h:292
void DoAddLc(uint8_t lcId, LteUeCmacSapProvider::LogicalChannelConfig lcConfig, LteMacSapUser *msu)
Add LC function.
Definition: lte-ue-mac.cc:573
uint8_t m_harqProcessId
HARQ process ID.
Definition: lte-ue-mac.h:273
friend class UeMemberLteMacSapProvider
allow UeMemberLteMacSapProvider class friend access
Definition: lte-ue-mac.h:46
LteMacSapProvider * m_macSapProvider
MAC SAP provider.
Definition: lte-ue-mac.h:257
void RandomlySelectAndSendRaPreamble()
Randomly select and send RA preamble function.
Definition: lte-ue-mac.cc:405
void DoStartContentionBasedRandomAccessProcedure()
Start contention based random access procedure function.
Definition: lte-ue-mac.cc:531
uint16_t m_backoffParameter
backoff parameter
Definition: lte-ue-mac.h:285
void StartWaitingForRaResponse()
Start waiting for RA response function.
Definition: lte-ue-mac.cc:442
void DoSetRnti(uint16_t rnti)
Set RNTI.
Definition: lte-ue-mac.cc:543
void DoSetImsi(uint64_t imsi)
Set IMSI.
Definition: lte-ue-mac.cc:550
void SendRaPreamble(bool contention)
Send RA preamble function.
Definition: lte-ue-mac.cc:418
void SetLteUeCmacSapUser(LteUeCmacSapUser *s)
Set the LTE UE CMAC SAP user.
Definition: lte-ue-mac.cc:302
std::map< uint8_t, LcInfo > m_lcInfoMap
logical channel info map
Definition: lte-ue-mac.h:255
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
bool RemovePacketTag(Tag &tag)
Remove a packet tag.
Definition: packet.cc:986
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: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:60
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:935
UeMemberLteMacSapProvider class.
Definition: lte-ue-mac.cc:140
LteUeMac * m_mac
the UE MAC
Definition: lte-ue-mac.cc:154
void TransmitPdu(TransmitPduParameters params) override
send an RLC PDU to the MAC for transmission.
Definition: lte-ue-mac.cc:163
void ReportBufferStatus(ReportBufferStatusParameters params) override
Report the RLC buffer status to the MAC.
Definition: lte-ue-mac.cc:169
UeMemberLteMacSapProvider(LteUeMac *mac)
Constructor.
Definition: lte-ue-mac.cc:157
UeMemberLteUeCmacSapProvider class.
Definition: lte-ue-mac.cc:49
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:95
LteUeMac * m_mac
the UE MAC
Definition: lte-ue-mac.cc:74
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:133
void Reset() override
reset the MAC
Definition: lte-ue-mac.cc:121
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:89
void AddLc(uint8_t lcId, LteUeCmacSapProvider::LogicalChannelConfig lcConfig, LteMacSapUser *msu) override
add a new Logical Channel (LC)
Definition: lte-ue-mac.cc:109
void RemoveLc(uint8_t lcId) override
remove an existing LC
Definition: lte-ue-mac.cc:115
void SetRnti(uint16_t rnti) override
Definition: lte-ue-mac.cc:103
void ConfigureRach(RachConfig rc) override
Configure RACH function.
Definition: lte-ue-mac.cc:83
void NotifyConnectionSuccessful() override
Notify MAC about the successful RRC connection establishment.
Definition: lte-ue-mac.cc:127
UeMemberLteUeCmacSapProvider(LteUeMac *mac)
Constructor.
Definition: lte-ue-mac.cc:77
UeMemberLteUePhySapUser.
Definition: lte-ue-mac.cc:178
UeMemberLteUePhySapUser(LteUeMac *mac)
Constructor.
Definition: lte-ue-mac.cc:196
LteUeMac * m_mac
the UE MAC
Definition: lte-ue-mac.cc:193
void ReceiveLteControlMessage(Ptr< LteControlMessage > msg) override
Receive SendLteControlMessage (PDCCH map, CQI feedbacks) using the ideal control channel.
Definition: lte-ue-mac.cc:214
void ReceivePhyPdu(Ptr< Packet > p) override
Receive Phy Pdu function.
Definition: lte-ue-mac.cc:202
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:208
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.
mac
Definition: third.py:85
params
Fit Fluctuating Two Ray model to the 3GPP TR 38.901 using the Anderson-Darling goodness-of-fit ##.
#define list
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:250
LteUeCmacSapProvider::LogicalChannelConfig lcConfig
logical channel config
Definition: lte-ue-mac.h:251
LteMacSapUser * macSapUser
MAC SAP user.
Definition: lte-ue-mac.h:252
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