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