A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
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.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 NS_LOG_COMPONENT_DEFINE ("LteUeMac");
41 
42 namespace ns3 {
43 
45  ;
46 
47 
49 // SAP forwarders
51 
52 
54 {
55 public:
57 
58  // inherited from LteUeCmacSapProvider
59  virtual void ConfigureRach (RachConfig rc);
61  virtual void StartNonContentionBasedRandomAccessProcedure (uint16_t rnti, uint8_t preambleId, uint8_t prachMask);
62  virtual void AddLc (uint8_t lcId, LteUeCmacSapProvider::LogicalChannelConfig lcConfig, LteMacSapUser* msu);
63  virtual void RemoveLc (uint8_t lcId);
64  virtual void Reset ();
65 
66 private:
68 };
69 
70 
72  : m_mac (mac)
73 {
74 }
75 
76 void
78 {
79  m_mac->DoConfigureRach (rc);
80 }
81 
82  void
84 {
86 }
87 
88  void
89 UeMemberLteUeCmacSapProvider::StartNonContentionBasedRandomAccessProcedure (uint16_t rnti, uint8_t preambleId, uint8_t prachMask)
90 {
91  m_mac->DoStartNonContentionBasedRandomAccessProcedure (rnti, preambleId, prachMask);
92 }
93 
94 
95 void
97 {
98  m_mac->DoAddLc (lcId, lcConfig, msu);
99 }
100 
101 void
103 {
104  m_mac->DoRemoveLc (lcid);
105 }
106 
107 void
109 {
110  m_mac->DoReset ();
111 }
112 
114 {
115 public:
117 
118  // inherited from LteMacSapProvider
119  virtual void TransmitPdu (TransmitPduParameters params);
120  virtual void ReportBufferStatus (ReportBufferStatusParameters params);
121 
122 private:
124 };
125 
126 
128  : m_mac (mac)
129 {
130 }
131 
132 void
134 {
135  m_mac->DoTransmitPdu (params);
136 }
137 
138 
139 void
141 {
142  m_mac->DoReportBufferStatus (params);
143 }
144 
145 
146 
147 
149 {
150 public:
152 
153  // inherited from LtePhySapUser
154  virtual void ReceivePhyPdu (Ptr<Packet> p);
155  virtual void SubframeIndication (uint32_t frameNo, uint32_t subframeNo);
157 
158 private:
160 };
161 
163 {
164 
165 }
166 
167 void
169 {
170  m_mac->DoReceivePhyPdu (p);
171 }
172 
173 
174 void
175 UeMemberLteUePhySapUser::SubframeIndication (uint32_t frameNo, uint32_t subframeNo)
176 {
177  m_mac->DoSubframeIndication (frameNo, subframeNo);
178 }
179 
180 void
182 {
184 }
185 
186 
187 
188 
190 // LteUeMac methods
192 
193 
194 TypeId
196 {
197  static TypeId tid = TypeId ("ns3::LteUeMac")
198  .SetParent<Object> ()
199  .AddConstructor<LteUeMac> ();
200  return tid;
201 }
202 
203 
205  : m_bsrPeriodicity (MilliSeconds (1)), // ideal behavior
206  m_bsrLast (MilliSeconds (0)),
207  m_freshUlBsr (false),
208  m_harqProcessId (0),
209  m_rnti (0),
210  m_rachConfigured (false),
211  m_waitingForRaResponse (false)
212 
213 {
214  NS_LOG_FUNCTION (this);
216  for (uint8_t i = 0; i < m_miUlHarqProcessesPacket.size (); i++)
217  {
218  Ptr<PacketBurst> pb = CreateObject <PacketBurst> ();
219  m_miUlHarqProcessesPacket.at (i) = pb;
220  }
222 
226  m_raPreambleUniformVariable = CreateObject<UniformRandomVariable> ();
227 }
228 
229 
231 {
232  NS_LOG_FUNCTION (this);
233 }
234 
235 void
237 {
238  NS_LOG_FUNCTION (this);
239  m_miUlHarqProcessesPacket.clear ();
240  delete m_macSapProvider;
241  delete m_cmacSapProvider;
242  delete m_uePhySapUser;
244 }
245 
246 
249 {
250  return m_uePhySapUser;
251 }
252 
253 void
255 {
257 }
258 
259 
262 {
263  return m_macSapProvider;
264 }
265 
266 void
268 {
269  m_cmacSapUser = s;
270 }
271 
274 {
275  return m_cmacSapProvider;
276 }
277 
278 
279 void
281 {
282  NS_LOG_FUNCTION (this);
283  NS_ASSERT_MSG (m_rnti == params.rnti, "RNTI mismatch between RLC and MAC");
284  LteRadioBearerTag tag (params.rnti, params.lcid, 0 /* UE works in SISO mode*/);
285  params.pdu->AddPacketTag (tag);
286  // store pdu in HARQ buffer
287  m_miUlHarqProcessesPacket.at (m_harqProcessId)->AddPacket (params.pdu);
290 }
291 
292 void
294 {
295  NS_LOG_FUNCTION (this << (uint32_t) params.lcid);
296 
297  std::map <uint8_t, LteMacSapProvider::ReportBufferStatusParameters>::iterator it;
298 
299 
300  it = m_ulBsrReceived.find (params.lcid);
301  if (it!=m_ulBsrReceived.end ())
302  {
303  // update entry
304  (*it).second = params;
305  }
306  else
307  {
308  m_ulBsrReceived.insert (std::pair<uint8_t, LteMacSapProvider::ReportBufferStatusParameters> (params.lcid, params));
309  }
310  m_freshUlBsr = true;
311 }
312 
313 
314 void
316 {
317  NS_LOG_FUNCTION (this);
318 
319  if (m_rnti == 0)
320  {
321  NS_LOG_INFO ("MAC not initialized, BSR deferred");
322  return;
323  }
324 
325  if (m_ulBsrReceived.size () == 0)
326  {
327  NS_LOG_INFO ("No BSR report to transmit");
328  return;
329  }
330  MacCeListElement_s bsr;
331  bsr.m_rnti = m_rnti;
333 
334  // BSR is reported for each LCG
335  std::map <uint8_t, LteMacSapProvider::ReportBufferStatusParameters>::iterator it;
336  std::vector<uint32_t> queue (4, 0); // one value per each of the 4 LCGs, initialized to 0
337  for (it = m_ulBsrReceived.begin (); it != m_ulBsrReceived.end (); it++)
338  {
339  uint8_t lcid = it->first;
340  std::map <uint8_t, LcInfo>::iterator lcInfoMapIt;
341  lcInfoMapIt = m_lcInfoMap.find (lcid);
342  NS_ASSERT (lcInfoMapIt != m_lcInfoMap.end ());
343  NS_ASSERT_MSG ((lcid != 0) || (((*it).second.txQueueSize == 0)
344  && ((*it).second.retxQueueSize == 0)
345  && ((*it).second.statusPduSize == 0)),
346  "BSR should not be used for LCID 0");
347  uint8_t lcg = lcInfoMapIt->second.lcConfig.logicalChannelGroup;
348  queue.at (lcg) += ((*it).second.txQueueSize + (*it).second.retxQueueSize + (*it).second.statusPduSize);
349  }
350 
351  // FF API says that all 4 LCGs are always present
356 
357  // create the feedback to eNB
358  Ptr<BsrLteControlMessage> msg = Create<BsrLteControlMessage> ();
359  msg->SetBsr (bsr);
361 
362 }
363 
364 void
366 {
367  NS_LOG_FUNCTION (this);
368  // 3GPP 36.321 5.1.1
369  NS_ASSERT_MSG (m_rachConfigured, "RACH not configured");
370  // assume that there is no Random Access Preambles group B
372  bool contention = true;
373  SendRaPreamble (contention);
374 }
375 
376 void
377 LteUeMac::SendRaPreamble (bool contention)
378 {
379  NS_LOG_FUNCTION (this << (uint32_t) m_raPreambleId << contention);
380  // Since regular UL LteControlMessages need m_ulConfigured = true in
381  // order to be sent by the UE, the rach preamble needs to be sent
382  // with a dedicated primitive (not
383  // m_uePhySapProvider->SendLteControlMessage (msg)) so that it can
384  // bypass the m_ulConfigured flag. This is reasonable, since In fact
385  // the RACH preamble is sent on 6RB bandwidth so the uplink
386  // bandwidth does not need to be configured.
387  NS_ASSERT (m_subframeNo > 0); // sanity check for subframe starting at 1
388  m_raRnti = m_subframeNo - 1;
390  NS_LOG_INFO (this << " sent preamble id " << (uint32_t) m_raPreambleId << ", RA-RNTI " << (uint32_t) m_raRnti);
391  // 3GPP 36.321 5.1.4
392  Time raWindowBegin = MilliSeconds (3);
393  Time raWindowEnd = MilliSeconds (3 + m_rachConfig.raResponseWindowSize);
396 }
397 
398 void
400 {
401  NS_LOG_FUNCTION (this);
402  m_waitingForRaResponse = true;
403 }
404 
405 void
407 {
408  NS_LOG_FUNCTION (this);
409  m_waitingForRaResponse = false;
411  NS_LOG_INFO ("got RAR for RAPID " << (uint32_t) m_raPreambleId << ", setting T-C-RNTI = " << raResponse.m_rnti);
412  m_rnti = raResponse.m_rnti;
414  // in principle we should wait for contention resolution,
415  // but in the current LTE model when two or more identical
416  // preambles are sent no one is received, so there is no need
417  // for contention resolution
419  // trigger tx opportunity for Message 3 over LC 0
420  // this is needed since Message 3's UL GRANT is in the RAR, not in UL-DCIs
421  const uint8_t lc0Lcid = 0;
422  std::map <uint8_t, LcInfo>::iterator lc0InfoIt = m_lcInfoMap.find (lc0Lcid);
423  NS_ASSERT (lc0InfoIt != m_lcInfoMap.end ());
424  std::map <uint8_t, LteMacSapProvider::ReportBufferStatusParameters>::iterator lc0BsrIt
425  = m_ulBsrReceived.find (lc0Lcid);
426  if ((lc0BsrIt != m_ulBsrReceived.end ())
427  && (lc0BsrIt->second.txQueueSize > 0))
428  {
429  NS_ASSERT_MSG (raResponse.m_grant.m_tbSize > lc0BsrIt->second.txQueueSize,
430  "segmentation of Message 3 is not allowed");
431  lc0InfoIt->second.macSapUser->NotifyTxOpportunity (raResponse.m_grant.m_tbSize, 0, 0);
432  lc0BsrIt->second.txQueueSize = 0;
433  }
434 }
435 
436 void
438 {
439  NS_LOG_FUNCTION (this << contention);
440  m_waitingForRaResponse = false;
441  // 3GPP 36.321 5.1.4
444  {
445  NS_LOG_INFO ("RAR timeout, preambleTransMax reached => giving up");
447  }
448  else
449  {
450  NS_LOG_INFO ("RAR timeout, re-send preamble");
451  if (contention)
452  {
454  }
455  else
456  {
457  SendRaPreamble (contention);
458  }
459  }
460 }
461 
462 void
464 {
465  NS_LOG_FUNCTION (this);
466  m_rachConfig = rc;
467  m_rachConfigured = true;
468 }
469 
470 void
472 {
473  NS_LOG_FUNCTION (this);
474 
475  // 3GPP 36.321 5.1.1
476  NS_ASSERT_MSG (m_rachConfigured, "RACH not configured");
478  m_backoffParameter = 0;
480 }
481 
482 void
483 LteUeMac::DoStartNonContentionBasedRandomAccessProcedure (uint16_t rnti, uint8_t preambleId, uint8_t prachMask)
484 {
485  NS_LOG_FUNCTION (this << " rnti" << rnti);
486  NS_ASSERT_MSG (prachMask == 0, "requested PRACH MASK = " << (uint32_t) prachMask << ", but only PRACH MASK = 0 is supported");
487  m_rnti = rnti;
488  m_raPreambleId = preambleId;
489  bool contention = false;
490  SendRaPreamble (contention);
491 }
492 
493 void
495 {
496  NS_LOG_FUNCTION (this << " lcId" << (uint32_t) lcId);
497  NS_ASSERT_MSG (m_lcInfoMap.find (lcId) == m_lcInfoMap.end (), "cannot add channel because LCID " << lcId << " is already present");
498 
499  LcInfo lcInfo;
500  lcInfo.lcConfig = lcConfig;
501  lcInfo.macSapUser = msu;
502  m_lcInfoMap[lcId] = lcInfo;
503 }
504 
505 void
506 LteUeMac::DoRemoveLc (uint8_t lcId)
507 {
508  NS_LOG_FUNCTION (this << " lcId" << lcId);
509  NS_ASSERT_MSG (m_lcInfoMap.find (lcId) != m_lcInfoMap.end (), "could not find LCID " << lcId);
510  m_lcInfoMap.erase (lcId);
511 }
512 
513 void
515 {
516  NS_LOG_FUNCTION (this);
517  std::map <uint8_t, LcInfo>::iterator it = m_lcInfoMap.begin ();
518  while (it != m_lcInfoMap.end ())
519  {
520  // don't delete CCCH)
521  if (it->first == 0)
522  {
523  ++it;
524  }
525  else
526  {
527  // note: use of postfix operator preserves validity of iterator
528  m_lcInfoMap.erase (it++);
529  }
530  }
531  m_rachConfigured = false;
532  m_freshUlBsr = false;
533  m_ulBsrReceived.clear ();
534 }
535 
536 void
538 {
539  LteRadioBearerTag tag;
540  p->RemovePacketTag (tag);
541  if (tag.GetRnti () == m_rnti)
542  {
543  // packet is for the current user
544  std::map <uint8_t, LcInfo>::const_iterator it = m_lcInfoMap.find (tag.GetLcid ());
545  NS_ASSERT_MSG (it != m_lcInfoMap.end (), "received packet with unknown lcid");
546  it->second.macSapUser->ReceivePdu (p);
547  }
548 }
549 
550 
551 void
553 {
554  NS_LOG_FUNCTION (this);
555  if (msg->GetMessageType () == LteControlMessage::UL_DCI)
556  {
557  Ptr<UlDciLteControlMessage> msg2 = DynamicCast<UlDciLteControlMessage> (msg);
558  UlDciListElement_s dci = msg2->GetDci ();
559  if (dci.m_ndi==1)
560  {
561  // New transmission -> emtpy pkt buffer queue (for deleting eventual pkts not acked )
562  Ptr<PacketBurst> pb = CreateObject <PacketBurst> ();
564  // Retrieve data from RLC
565  std::map <uint8_t, LteMacSapProvider::ReportBufferStatusParameters>::iterator itBsr;
566  uint16_t activeLcs = 0;
567  uint32_t statusPduMinSize = 0;
568  for (itBsr = m_ulBsrReceived.begin (); itBsr != m_ulBsrReceived.end (); itBsr++)
569  {
570  if (((*itBsr).second.statusPduSize > 0) || ((*itBsr).second.retxQueueSize > 0) || ((*itBsr).second.txQueueSize > 0))
571  {
572  activeLcs++;
573  if (((*itBsr).second.statusPduSize!=0)&&((*itBsr).second.statusPduSize < statusPduMinSize))
574  {
575  statusPduMinSize = (*itBsr).second.statusPduSize;
576  }
577  if (((*itBsr).second.statusPduSize!=0)&&(statusPduMinSize == 0))
578  {
579  statusPduMinSize = (*itBsr).second.statusPduSize;
580  }
581  }
582  }
583  if (activeLcs == 0)
584  {
585  NS_LOG_ERROR (this << " No active flows for this UL-DCI");
586  return;
587  }
588  std::map <uint8_t, LcInfo>::iterator it;
589  uint32_t bytesPerActiveLc = dci.m_tbSize / activeLcs;
590  bool statusPduPriority = false;
591  if ((statusPduMinSize != 0)&&(bytesPerActiveLc < statusPduMinSize))
592  {
593  // send only the status PDU which has highest priority
594  statusPduPriority = true;
595  NS_LOG_DEBUG (this << " Reduced resource -> send only Status, b ytes " << statusPduMinSize);
596  if (dci.m_tbSize < statusPduMinSize)
597  {
598  NS_FATAL_ERROR ("Insufficient Tx Opportunity for sending a status message");
599  }
600  }
601  NS_LOG_LOGIC (this << " UE " << m_rnti << ": UL-CQI notified TxOpportunity of " << dci.m_tbSize << " => " << bytesPerActiveLc << " bytes per active LC" << " statusPduMinSize " << statusPduMinSize);
602  for (it = m_lcInfoMap.begin (); it!=m_lcInfoMap.end (); it++)
603  {
604  itBsr = m_ulBsrReceived.find ((*it).first);
605  NS_LOG_DEBUG (this << " Processing LC " << (uint32_t)(*it).first << " bytesPerActiveLc " << bytesPerActiveLc);
606  if ( (itBsr!=m_ulBsrReceived.end ()) &&
607  ( ((*itBsr).second.statusPduSize > 0) ||
608  ((*itBsr).second.retxQueueSize > 0) ||
609  ((*itBsr).second.txQueueSize > 0)) )
610  {
611  if ((statusPduPriority) && ((*itBsr).second.statusPduSize == statusPduMinSize))
612  {
613  (*it).second.macSapUser->NotifyTxOpportunity ((*itBsr).second.statusPduSize, 0, 0);
614  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);
615  (*itBsr).second.statusPduSize = 0;
616  break;
617  }
618  else
619  {
620  uint32_t bytesForThisLc = bytesPerActiveLc;
621  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);
622  if (((*itBsr).second.statusPduSize > 0) && (bytesForThisLc > (*itBsr).second.statusPduSize))
623  {
624  (*it).second.macSapUser->NotifyTxOpportunity ((*itBsr).second.statusPduSize, 0, 0);
625  bytesForThisLc -= (*itBsr).second.statusPduSize;
626  NS_LOG_DEBUG (this << " serve STATUS " << (*itBsr).second.statusPduSize);
627  (*itBsr).second.statusPduSize = 0;
628  }
629  else
630  {
631  if ((*itBsr).second.statusPduSize>bytesForThisLc)
632  {
633  NS_FATAL_ERROR ("Insufficient Tx Opportunity for sending a status message");
634  }
635  }
636 
637  if ((bytesForThisLc > 7) && // 7 is the min TxOpportunity useful for Rlc
638  (((*itBsr).second.retxQueueSize > 0) ||
639  ((*itBsr).second.txQueueSize > 0)))
640  {
641  if ((*itBsr).second.retxQueueSize > 0)
642  {
643  NS_LOG_DEBUG (this << " serve retx DATA, bytes " << bytesForThisLc);
644  (*it).second.macSapUser->NotifyTxOpportunity (bytesForThisLc, 0, 0);
645  if ((*itBsr).second.retxQueueSize >= bytesForThisLc)
646  {
647  (*itBsr).second.retxQueueSize -= bytesForThisLc;
648  }
649  else
650  {
651  (*itBsr).second.retxQueueSize = 0;
652  }
653  }
654  else if ((*itBsr).second.txQueueSize > 0)
655  {
656  uint16_t lcid = (*it).first;
657  uint32_t rlcOverhead;
658  if (lcid == 1)
659  {
660  // for SRB1 (using RLC AM) it's better to
661  // overestimate RLC overhead rather than
662  // underestimate it and risk unneeded
663  // segmentation which increases delay
664  rlcOverhead = 4;
665  }
666  else
667  {
668  // minimum RLC overhead due to header
669  rlcOverhead = 2;
670  }
671  NS_LOG_DEBUG (this << " serve tx DATA, bytes " << bytesForThisLc << ", RLC overhead " << rlcOverhead);
672  (*it).second.macSapUser->NotifyTxOpportunity (bytesForThisLc, 0, 0);
673  if ((*itBsr).second.txQueueSize >= bytesForThisLc - rlcOverhead)
674  {
675  (*itBsr).second.txQueueSize -= bytesForThisLc - rlcOverhead;
676  }
677  else
678  {
679  (*itBsr).second.txQueueSize = 0;
680  }
681  }
682  }
683  else
684  {
685  if ( ((*itBsr).second.retxQueueSize > 0) || ((*itBsr).second.txQueueSize > 0))
686  {
687  // resend BSR info for updating eNB peer MAC
688  m_freshUlBsr = true;
689  }
690  }
691  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);
692  }
693 
694  }
695  }
696  }
697  else
698  {
699  // HARQ retransmission -> retrieve data from HARQ buffer
700  NS_LOG_DEBUG (this << " UE MAC RETX HARQ " << (uint16_t)m_harqProcessId);
701  Ptr<PacketBurst> pb = m_miUlHarqProcessesPacket.at (m_harqProcessId);
702  for (std::list<Ptr<Packet> >::const_iterator j = pb->Begin (); j != pb->End (); ++j)
703  {
704  Ptr<Packet> pkt = (*j)->Copy ();
706  }
707  m_miUlHarqProcessesPacketTimer.at (m_harqProcessId) = HARQ_PERIOD;
708  }
709 
710  }
711  else if (msg->GetMessageType () == LteControlMessage::RAR)
712  {
714  {
715  Ptr<RarLteControlMessage> rarMsg = DynamicCast<RarLteControlMessage> (msg);
716  uint16_t raRnti = rarMsg->GetRaRnti ();
717  NS_LOG_LOGIC (this << "got RAR with RA-RNTI " << (uint32_t) raRnti << ", expecting " << (uint32_t) m_raRnti);
718  if (raRnti == m_raRnti) // RAR corresponds to TX subframe of preamble
719  {
720  for (std::list<RarLteControlMessage::Rar>::const_iterator it = rarMsg->RarListBegin ();
721  it != rarMsg->RarListEnd ();
722  ++it)
723  {
724  if (it->rapId == m_raPreambleId) // RAR is for me
725  {
726  RecvRaResponse (it->rarPayload);
730  }
731  }
732  }
733  }
734  }
735  else
736  {
737  NS_LOG_WARN (this << " LteControlMessage not recognized");
738  }
739 }
740 
741 void
743 {
744  NS_LOG_FUNCTION (this);
745 
746  for (uint16_t i = 0; i < m_miUlHarqProcessesPacketTimer.size (); i++)
747  {
748  if (m_miUlHarqProcessesPacketTimer.at (i) == 0)
749  {
750  if (m_miUlHarqProcessesPacket.at (i)->GetSize () > 0)
751  {
752  // timer expired: drop packets in buffer for this process
753  NS_LOG_INFO (this << " HARQ Proc Id " << i << " packets buffer expired");
754  Ptr<PacketBurst> emptyPb = CreateObject <PacketBurst> ();
755  m_miUlHarqProcessesPacket.at (i) = emptyPb;
756  }
757  }
758  else
759  {
761  }
762  }
763 }
764 
765 
766 void
767 LteUeMac::DoSubframeIndication (uint32_t frameNo, uint32_t subframeNo)
768 {
769  NS_LOG_FUNCTION (this);
770  m_frameNo = frameNo;
771  m_subframeNo = subframeNo;
773  if ((Simulator::Now () >= m_bsrLast + m_bsrPeriodicity) && (m_freshUlBsr==true))
774  {
777  m_freshUlBsr = false;
779  }
780 }
781 
782 int64_t
783 LteUeMac::AssignStreams (int64_t stream)
784 {
785  NS_LOG_FUNCTION (this << stream);
787  return 1;
788 }
789 
790 } // namespace ns3
virtual void AddLc(uint8_t lcId, LteUeCmacSapProvider::LogicalChannelConfig lcConfig, LteMacSapUser *msu)
add a new Logical Channel (LC)
Definition: lte-ue-mac.cc:96
void DoStartNonContentionBasedRandomAccessProcedure(uint16_t rnti, uint8_t rapId, uint8_t prachMask)
Definition: lte-ue-mac.cc:483
LteUeCmacSapProvider::LogicalChannelConfig lcConfig
Definition: lte-ue-mac.h:120
uint8_t GetLcid(void) const
keep track of time values and allow control of global simulation resolution
Definition: nstime.h:81
void DoReset()
Definition: lte-ue-mac.cc:514
uint8_t m_raPreambleId
Definition: lte-ue-mac.h:150
#define NS_LOG_FUNCTION(parameters)
Definition: log.h:345
void SetStream(int64_t stream)
Specifies the stream number for this RNG stream.
virtual void TransmitPdu(TransmitPduParameters params)
send an RLC PDU to the MAC for transmission.
Definition: lte-ue-mac.cc:133
#define HARQ_PERIOD
Definition: lte-common.h:30
void SendRaPreamble(bool contention)
Definition: lte-ue-mac.cc:377
void StartWaitingForRaResponse()
Definition: lte-ue-mac.cc:399
uint32_t GetInteger(uint32_t min, uint32_t max)
Returns a random unsigned integer from a uniform distribution over the interval [min,max] including both ends.
void DoReceivePhyPdu(Ptr< Packet > p)
Definition: lte-ue-mac.cc:537
Ptr< UniformRandomVariable > m_raPreambleUniformVariable
Definition: lte-ue-mac.h:154
uint16_t GetRnti(void) const
LteUePhySapUser * m_uePhySapUser
Definition: lte-ue-mac.h:132
void AddPacketTag(const Tag &tag) const
Add a packet tag.
Definition: packet.cc:841
#define NS_ASSERT(condition)
Definition: assert.h:64
NS_OBJECT_ENSURE_REGISTERED(NullMessageSimulatorImpl)
void RaResponseTimeout(bool contention)
Definition: lte-ue-mac.cc:437
See section 4.3.2 ulDciListElement.
virtual void ReportBufferStatus(ReportBufferStatusParameters params)
Report the RLC buffer status to the MAC.
Definition: lte-ue-mac.cc:140
struct MacCeValue_u m_macCeValue
virtual void DoDispose(void)
This method is called by Object::Dispose or by the object's destructor, whichever comes first...
Definition: object.cc:336
#define NS_LOG_INFO(msg)
Definition: log.h:298
See section 4.3.10 buildRARListElement.
void DoAddLc(uint8_t lcId, LteUeCmacSapProvider::LogicalChannelConfig lcConfig, LteMacSapUser *msu)
Definition: lte-ue-mac.cc:494
void SetLteUePhySapProvider(LteUePhySapProvider *s)
Set the PHY SAP Provider.
Definition: lte-ue-mac.cc:254
virtual void SendRachPreamble(uint32_t prachId, uint32_t raRnti)=0
send a preamble on the PRACH
static EventId Schedule(Time const &time, MEM mem_ptr, OBJ obj)
Schedule an event to expire at the relative time "time" is reached.
Definition: simulator.h:824
Service Access Point (SAP) offered by the PHY to the MAC.
uint8_t lcid
the logical channel id corresponding to the sending RLC instance
Definition: lte-mac-sap.h:49
void DoStartContentionBasedRandomAccessProcedure()
Definition: lte-ue-mac.cc:471
void SendReportBufferStatus(void)
Definition: lte-ue-mac.cc:315
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:175
virtual ~LteUeMac()
Definition: lte-ue-mac.cc:230
#define NS_FATAL_ERROR(msg)
fatal error handling
Definition: fatal-error.h:72
uint16_t m_tbSize
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:83
void DoRemoveLc(uint8_t lcId)
Definition: lte-ue-mac.cc:506
Parameters for LteMacSapProvider::ReportBufferStatus.
Definition: lte-mac-sap.h:66
std::vector< uint8_t > m_miUlHarqProcessesPacketTimer
Definition: lte-ue-mac.h:144
friend class UeMemberLteUePhySapUser
Definition: lte-ue-mac.h:47
void SetLteUeCmacSapUser(LteUeCmacSapUser *s)
Definition: lte-ue-mac.cc:267
void DoTransmitPdu(LteMacSapProvider::TransmitPduParameters params)
Definition: lte-ue-mac.cc:280
virtual void ConfigureRach(RachConfig rc)
Definition: lte-ue-mac.cc:77
virtual void SetTemporaryCellRnti(uint16_t rnti)=0
friend class UeMemberLteMacSapProvider
Definition: lte-ue-mac.h:46
uint8_t m_harqProcessId
Definition: lte-ue-mac.h:142
static uint8_t BufferSize2BsrId(uint32_t val)
Definition: lte-common.cc:149
virtual void Reset()
reset the MAC
Definition: lte-ue-mac.cc:108
uint32_t m_frameNo
Definition: lte-ue-mac.h:156
bool m_waitingForRaResponse
Definition: lte-ue-mac.h:159
void DoReportBufferStatus(LteMacSapProvider::ReportBufferStatusParameters params)
Definition: lte-ue-mac.cc:293
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:89
virtual void SendMacPdu(Ptr< Packet > p)=0
Send the MAC PDU to the channel.
Ptr< SampleEmitter > s
uint16_t m_rnti
Definition: lte-ue-mac.h:146
LteUeCmacSapProvider * m_cmacSapProvider
Definition: lte-ue-mac.h:129
uint16_t rnti
the C-RNTI identifying the UE
Definition: lte-mac-sap.h:48
uint8_t m_raRnti
Definition: lte-ue-mac.h:158
std::vector< Ptr< PacketBurst > > m_miUlHarqProcessesPacket
Definition: lte-ue-mac.h:143
LteUeCmacSapProvider * GetLteUeCmacSapProvider(void)
Definition: lte-ue-mac.cc:273
Service Access Point (SAP) offered by the UE MAC to the UE RRC.
#define NS_LOG_LOGIC(msg)
Definition: log.h:368
void DoConfigureRach(LteUeCmacSapProvider::RachConfig rc)
Definition: lte-ue-mac.cc:463
#define list
virtual void NotifyRandomAccessSuccessful()=0
Notify the RRC that the MAC Random Access procedure completed successfully.
See section 4.3.14 macCEListElement.
void DoSubframeIndication(uint32_t frameNo, uint32_t subframeNo)
Forwarded from LteUePhySapUser: trigger the start from a new frame.
Definition: lte-ue-mac.cc:767
UeMemberLteUeCmacSapProvider(LteUeMac *mac)
Definition: lte-ue-mac.cc:71
void DoReceiveLteControlMessage(Ptr< LteControlMessage > msg)
Definition: lte-ue-mac.cc:552
Ptr< Packet > Copy(void) const
Definition: packet.cc:122
std::map< uint8_t, LcInfo > m_lcInfoMap
Definition: lte-ue-mac.h:124
virtual void SendLteControlMessage(Ptr< LteControlMessage > msg)=0
Send SendLteControlMessage (PDCCH map, CQI feedbacks) using the ideal control channel.
LteUePhySapUser * GetLteUePhySapUser()
Get the PHY SAP user.
Definition: lte-ue-mac.cc:248
LteMacSapProvider * GetLteMacSapProvider(void)
Definition: lte-ue-mac.cc:261
uint16_t m_backoffParameter
Definition: lte-ue-mac.h:152
static TypeId GetTypeId(void)
Definition: lte-ue-mac.cc:195
UeMemberLteUePhySapUser(LteUeMac *mac)
Definition: lte-ue-mac.cc:162
LteMacSapProvider * m_macSapProvider
Definition: lte-ue-mac.h:126
Service Access Point (SAP) offered by the UE MAC to the UE RRC.
uint8_t lcid
the logical channel id corresponding to the sending RLC instance
Definition: lte-mac-sap.h:69
virtual void ReceivePhyPdu(Ptr< Packet > p)
Called by the Phy to notify the MAC of the reception of a new PHY-PDU.
Definition: lte-ue-mac.cc:168
LteUePhySapProvider * m_uePhySapProvider
Definition: lte-ue-mac.h:131
static Time Now(void)
Return the "current simulation time".
Definition: simulator.cc:180
bool m_freshUlBsr
Definition: lte-ue-mac.h:140
virtual void RemoveLc(uint8_t lcId)
remove an existing LC
Definition: lte-ue-mac.cc:102
#define NS_ASSERT_MSG(condition, message)
Definition: assert.h:86
std::vector< uint8_t > m_bufferStatus
NS_LOG_COMPONENT_DEFINE("LteUeMac")
virtual void NotifyRandomAccessFailed()=0
Notify the RRC that the MAC Random Access procedure failed.
void RandomlySelectAndSendRaPreamble()
Definition: lte-ue-mac.cc:365
void RecvRaResponse(BuildRarListElement_s raResponse)
Definition: lte-ue-mac.cc:406
uint8_t m_preambleTransmissionCounter
Definition: lte-ue-mac.h:151
Service Access Point (SAP) offered by the MAC to the RLC See Femto Forum MAC Scheduler Interface Spec...
Definition: lte-mac-sap.h:94
EventId m_noRaResponseReceivedEvent
Definition: lte-ue-mac.h:153
#define NS_LOG_WARN(msg)
Definition: log.h:280
bool m_rachConfigured
Definition: lte-ue-mac.h:148
virtual void DoDispose(void)
This method is called by Object::Dispose or by the object's destructor, whichever comes first...
Definition: lte-ue-mac.cc:236
LteUeCmacSapProvider::RachConfig m_rachConfig
Definition: lte-ue-mac.h:149
Service Access Point (SAP) offered by the UE-PHY to the UE-MAC.
bool RemovePacketTag(Tag &tag)
Remove a packet tag.
Definition: packet.cc:848
#define NS_LOG_DEBUG(msg)
Definition: log.h:289
void Cancel(void)
This method is syntactic sugar for the ns3::Simulator::cancel method.
Definition: event-id.cc:47
Service Access Point (SAP) offered by the MAC to the RLC See Femto Forum MAC Scheduler Interface Spec...
Definition: lte-mac-sap.h:36
Tag used to define the RNTI and LC id for each MAC packet trasmitted.
enum ns3::MacCeListElement_s::MacCeType_e m_macCeType
Time m_bsrPeriodicity
Definition: lte-ue-mac.h:137
virtual void ReceiveLteControlMessage(Ptr< LteControlMessage > msg)
Receive SendLteControlMessage (PDCCH map, CQI feedbacks) using the ideal control channel.
Definition: lte-ue-mac.cc:181
#define NS_LOG_ERROR(msg)
Definition: log.h:271
uint32_t m_subframeNo
Definition: lte-ue-mac.h:157
std::map< uint8_t, LteMacSapProvider::ReportBufferStatusParameters > m_ulBsrReceived
Definition: lte-ue-mac.h:134
a base class which provides memory management and object aggregation
Definition: object.h:63
friend class UeMemberLteUeCmacSapProvider
Definition: lte-ue-mac.h:45
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:783
a unique identifier for an interface.
Definition: type-id.h:49
TypeId SetParent(TypeId tid)
Definition: type-id.cc:611
void RefreshHarqProcessesPacketBuffer(void)
Definition: lte-ue-mac.cc:742
UeMemberLteMacSapProvider(LteUeMac *mac)
Definition: lte-ue-mac.cc:127
LteUeCmacSapUser * m_cmacSapUser
Definition: lte-ue-mac.h:128
Parameters for LteMacSapProvider::TransmitPdu.
Definition: lte-mac-sap.h:45