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 
71 private:
73 };
74 
75 
77  : m_mac (mac)
78 {
79 }
80 
81 void
83 {
84  m_mac->DoConfigureRach (rc);
85 }
86 
87  void
89 {
91 }
92 
93  void
94 UeMemberLteUeCmacSapProvider::StartNonContentionBasedRandomAccessProcedure (uint16_t rnti, uint8_t preambleId, uint8_t prachMask)
95 {
96  m_mac->DoStartNonContentionBasedRandomAccessProcedure (rnti, preambleId, prachMask);
97 }
98 
99  void
101  {
102  m_mac->DoSetRnti (rnti);
103  }
104 
105 void
107 {
108  m_mac->DoAddLc (lcId, lcConfig, msu);
109 }
110 
111 void
113 {
114  m_mac->DoRemoveLc (lcid);
115 }
116 
117 void
119 {
120  m_mac->DoReset ();
121 }
122 
125 {
126 public:
133 
134  // inherited from LteMacSapProvider
135  virtual void TransmitPdu (TransmitPduParameters params);
136  virtual void ReportBufferStatus (ReportBufferStatusParameters params);
137 
138 private:
140 };
141 
142 
144  : m_mac (mac)
145 {
146 }
147 
148 void
150 {
151  m_mac->DoTransmitPdu (params);
152 }
153 
154 
155 void
157 {
158  m_mac->DoReportBufferStatus (params);
159 }
160 
161 
162 
167 {
168 public:
175 
176  // inherited from LtePhySapUser
177  virtual void ReceivePhyPdu (Ptr<Packet> p);
178  virtual void SubframeIndication (uint32_t frameNo, uint32_t subframeNo);
180 
181 private:
183 };
184 
186 {
187 
188 }
189 
190 void
192 {
193  m_mac->DoReceivePhyPdu (p);
194 }
195 
196 
197 void
198 UeMemberLteUePhySapUser::SubframeIndication (uint32_t frameNo, uint32_t subframeNo)
199 {
200  m_mac->DoSubframeIndication (frameNo, subframeNo);
201 }
202 
203 void
205 {
207 }
208 
209 
210 
211 
213 // LteUeMac methods
215 
216 
217 TypeId
219 {
220  static TypeId tid = TypeId ("ns3::LteUeMac")
221  .SetParent<Object> ()
222  .SetGroupName("Lte")
223  .AddConstructor<LteUeMac> ();
224  return tid;
225 }
226 
227 
229  : m_bsrPeriodicity (MilliSeconds (1)), // ideal behavior
230  m_bsrLast (MilliSeconds (0)),
231  m_freshUlBsr (false),
232  m_harqProcessId (0),
233  m_rnti (0),
234  m_rachConfigured (false),
235  m_waitingForRaResponse (false)
236 
237 {
238  NS_LOG_FUNCTION (this);
240  for (uint8_t i = 0; i < m_miUlHarqProcessesPacket.size (); i++)
241  {
242  Ptr<PacketBurst> pb = CreateObject <PacketBurst> ();
243  m_miUlHarqProcessesPacket.at (i) = pb;
244  }
246 
250  m_raPreambleUniformVariable = CreateObject<UniformRandomVariable> ();
252 }
253 
254 
256 {
257  NS_LOG_FUNCTION (this);
258 }
259 
260 void
262 {
263  NS_LOG_FUNCTION (this);
264  m_miUlHarqProcessesPacket.clear ();
265  delete m_macSapProvider;
266  delete m_cmacSapProvider;
267  delete m_uePhySapUser;
269 }
270 
271 
274 {
275  return m_uePhySapUser;
276 }
277 
278 void
280 {
281  m_uePhySapProvider = s;
282 }
283 
284 
287 {
288  return m_macSapProvider;
289 }
290 
291 void
293 {
294  m_cmacSapUser = s;
295 }
296 
299 {
300  return m_cmacSapProvider;
301 }
302 
303 void
305 {
306  m_componentCarrierId = index;
307 }
308 
309 void
311 {
312  NS_LOG_FUNCTION (this);
313  NS_ASSERT_MSG (m_rnti == params.rnti, "RNTI mismatch between RLC and MAC");
314  LteRadioBearerTag tag (params.rnti, params.lcid, 0 /* UE works in SISO mode*/);
315  params.pdu->AddPacketTag (tag);
316  // store pdu in HARQ buffer
317  m_miUlHarqProcessesPacket.at (m_harqProcessId)->AddPacket (params.pdu);
320 }
321 
322 void
324 {
325  NS_LOG_FUNCTION (this << (uint32_t) params.lcid);
326 
327  std::map <uint8_t, LteMacSapProvider::ReportBufferStatusParameters>::iterator it;
328 
329 
330  it = m_ulBsrReceived.find (params.lcid);
331  if (it != m_ulBsrReceived.end ())
332  {
333  // update entry
334  (*it).second = params;
335  }
336  else
337  {
338  m_ulBsrReceived.insert (std::pair<uint8_t, LteMacSapProvider::ReportBufferStatusParameters> (params.lcid, params));
339  }
340  m_freshUlBsr = true;
341 }
342 
343 
344 void
346 {
347  NS_LOG_FUNCTION (this);
348 
349  if (m_rnti == 0)
350  {
351  NS_LOG_INFO ("MAC not initialized, BSR deferred");
352  return;
353  }
354 
355  if (m_ulBsrReceived.size () == 0)
356  {
357  NS_LOG_INFO ("No BSR report to transmit");
358  return;
359  }
360  MacCeListElement_s bsr;
361  bsr.m_rnti = m_rnti;
363 
364  // BSR is reported for each LCG
365  std::map <uint8_t, LteMacSapProvider::ReportBufferStatusParameters>::iterator it;
366  std::vector<uint32_t> queue (4, 0); // one value per each of the 4 LCGs, initialized to 0
367  for (it = m_ulBsrReceived.begin (); it != m_ulBsrReceived.end (); it++)
368  {
369  uint8_t lcid = it->first;
370  std::map <uint8_t, LcInfo>::iterator lcInfoMapIt;
371  lcInfoMapIt = m_lcInfoMap.find (lcid);
372  NS_ASSERT (lcInfoMapIt != m_lcInfoMap.end ());
373  NS_ASSERT_MSG ((lcid != 0) || (((*it).second.txQueueSize == 0)
374  && ((*it).second.retxQueueSize == 0)
375  && ((*it).second.statusPduSize == 0)),
376  "BSR should not be used for LCID 0");
377  uint8_t lcg = lcInfoMapIt->second.lcConfig.logicalChannelGroup;
378  queue.at (lcg) += ((*it).second.txQueueSize + (*it).second.retxQueueSize + (*it).second.statusPduSize);
379  }
380 
381  // FF API says that all 4 LCGs are always present
386 
387  // create the feedback to eNB
388  Ptr<BsrLteControlMessage> msg = Create<BsrLteControlMessage> ();
389  msg->SetBsr (bsr);
391 
392 }
393 
394 void
396 {
397  NS_LOG_FUNCTION (this);
398  // 3GPP 36.321 5.1.1
399  NS_ASSERT_MSG (m_rachConfigured, "RACH not configured");
400  // assume that there is no Random Access Preambles group B
402  bool contention = true;
403  SendRaPreamble (contention);
404 }
405 
406 void
407 LteUeMac::SendRaPreamble (bool contention)
408 {
409  NS_LOG_FUNCTION (this << (uint32_t) m_raPreambleId << contention);
410  // Since regular UL LteControlMessages need m_ulConfigured = true in
411  // order to be sent by the UE, the rach preamble needs to be sent
412  // with a dedicated primitive (not
413  // m_uePhySapProvider->SendLteControlMessage (msg)) so that it can
414  // bypass the m_ulConfigured flag. This is reasonable, since In fact
415  // the RACH preamble is sent on 6RB bandwidth so the uplink
416  // bandwidth does not need to be configured.
417  NS_ASSERT (m_subframeNo > 0); // sanity check for subframe starting at 1
418  m_raRnti = m_subframeNo - 1;
420  NS_LOG_INFO (this << " sent preamble id " << (uint32_t) m_raPreambleId << ", RA-RNTI " << (uint32_t) m_raRnti);
421  // 3GPP 36.321 5.1.4
422  Time raWindowBegin = MilliSeconds (3);
426 }
427 
428 void
430 {
431  NS_LOG_FUNCTION (this);
432  m_waitingForRaResponse = true;
433 }
434 
435 void
437 {
438  NS_LOG_FUNCTION (this);
439  m_waitingForRaResponse = false;
441  NS_LOG_INFO ("got RAR for RAPID " << (uint32_t) m_raPreambleId << ", setting T-C-RNTI = " << raResponse.m_rnti);
442  m_rnti = raResponse.m_rnti;
444  // in principle we should wait for contention resolution,
445  // but in the current LTE model when two or more identical
446  // preambles are sent no one is received, so there is no need
447  // for contention resolution
449  // trigger tx opportunity for Message 3 over LC 0
450  // this is needed since Message 3's UL GRANT is in the RAR, not in UL-DCIs
451  const uint8_t lc0Lcid = 0;
452  std::map <uint8_t, LcInfo>::iterator lc0InfoIt = m_lcInfoMap.find (lc0Lcid);
453  NS_ASSERT (lc0InfoIt != m_lcInfoMap.end ());
454  std::map <uint8_t, LteMacSapProvider::ReportBufferStatusParameters>::iterator lc0BsrIt
455  = m_ulBsrReceived.find (lc0Lcid);
456  if ((lc0BsrIt != m_ulBsrReceived.end ())
457  && (lc0BsrIt->second.txQueueSize > 0))
458  {
459  NS_ASSERT_MSG (raResponse.m_grant.m_tbSize > lc0BsrIt->second.txQueueSize,
460  "segmentation of Message 3 is not allowed");
461  // this function can be called only from primary carrier
462  if (m_componentCarrierId > 0)
463  {
464  NS_FATAL_ERROR ("Function called on wrong componentCarrier");
465  }
466  lc0InfoIt->second.macSapUser->NotifyTxOpportunity (raResponse.m_grant.m_tbSize, 0, 0, m_componentCarrierId, m_rnti, lc0Lcid);
467  lc0BsrIt->second.txQueueSize = 0;
468  }
469 }
470 
471 void
473 {
474  NS_LOG_FUNCTION (this << contention);
475  m_waitingForRaResponse = false;
476  // 3GPP 36.321 5.1.4
479  {
480  NS_LOG_INFO ("RAR timeout, preambleTransMax reached => giving up");
482  }
483  else
484  {
485  NS_LOG_INFO ("RAR timeout, re-send preamble");
486  if (contention)
487  {
489  }
490  else
491  {
492  SendRaPreamble (contention);
493  }
494  }
495 }
496 
497 void
499 {
500  NS_LOG_FUNCTION (this);
501  m_rachConfig = rc;
502  m_rachConfigured = true;
503 }
504 
505 void
507 {
508  NS_LOG_FUNCTION (this);
509 
510  // 3GPP 36.321 5.1.1
511  NS_ASSERT_MSG (m_rachConfigured, "RACH not configured");
513  m_backoffParameter = 0;
515 }
516 
517 void
518 LteUeMac::DoSetRnti (uint16_t rnti)
519 {
520  NS_LOG_FUNCTION (this);
521  m_rnti = rnti;
522 }
523 
524 
525 void
526 LteUeMac::DoStartNonContentionBasedRandomAccessProcedure (uint16_t rnti, uint8_t preambleId, uint8_t prachMask)
527 {
528  NS_LOG_FUNCTION (this << " rnti" << rnti);
529  NS_ASSERT_MSG (prachMask == 0, "requested PRACH MASK = " << (uint32_t) prachMask << ", but only PRACH MASK = 0 is supported");
530  m_rnti = rnti;
531  m_raPreambleId = preambleId;
532  bool contention = false;
533  SendRaPreamble (contention);
534 }
535 
536 void
538 {
539  NS_LOG_FUNCTION (this << " lcId" << (uint32_t) lcId);
540  NS_ASSERT_MSG (m_lcInfoMap.find (lcId) == m_lcInfoMap.end (), "cannot add channel because LCID " << lcId << " is already present");
541 
542  LcInfo lcInfo;
543  lcInfo.lcConfig = lcConfig;
544  lcInfo.macSapUser = msu;
545  m_lcInfoMap[lcId] = lcInfo;
546 }
547 
548 void
549 LteUeMac::DoRemoveLc (uint8_t lcId)
550 {
551  NS_LOG_FUNCTION (this << " lcId" << lcId);
552  NS_ASSERT_MSG (m_lcInfoMap.find (lcId) != m_lcInfoMap.end (), "could not find LCID " << lcId);
553  m_lcInfoMap.erase (lcId);
554 }
555 
556 void
558 {
559  NS_LOG_FUNCTION (this);
560  std::map <uint8_t, LcInfo>::iterator it = m_lcInfoMap.begin ();
561  while (it != m_lcInfoMap.end ())
562  {
563  // don't delete CCCH)
564  if (it->first == 0)
565  {
566  ++it;
567  }
568  else
569  {
570  // note: use of postfix operator preserves validity of iterator
571  m_lcInfoMap.erase (it++);
572  }
573  }
574 
576  m_rachConfigured = false;
577  m_freshUlBsr = false;
578  m_ulBsrReceived.clear ();
579 }
580 
581 void
583 {
584  LteRadioBearerTag tag;
585  p->RemovePacketTag (tag);
586  if (tag.GetRnti () == m_rnti)
587  {
588  // packet is for the current user
589  std::map <uint8_t, LcInfo>::const_iterator it = m_lcInfoMap.find (tag.GetLcid ());
590  if (it != m_lcInfoMap.end ())
591  {
592  it->second.macSapUser->ReceivePdu (p, m_rnti, tag.GetLcid ());
593  }
594  else
595  {
596  NS_LOG_WARN ("received packet with unknown lcid " << (uint32_t) tag.GetLcid ());
597  }
598  }
599 }
600 
601 
602 void
604 {
605  NS_LOG_FUNCTION (this);
606  if (msg->GetMessageType () == LteControlMessage::UL_DCI)
607  {
608  Ptr<UlDciLteControlMessage> msg2 = DynamicCast<UlDciLteControlMessage> (msg);
609  UlDciListElement_s dci = msg2->GetDci ();
610  if (dci.m_ndi == 1)
611  {
612  // New transmission -> emtpy pkt buffer queue (for deleting eventual pkts not acked )
613  Ptr<PacketBurst> pb = CreateObject <PacketBurst> ();
615  // Retrieve data from RLC
616  std::map <uint8_t, LteMacSapProvider::ReportBufferStatusParameters>::iterator itBsr;
617  uint16_t activeLcs = 0;
618  uint32_t statusPduMinSize = 0;
619  for (itBsr = m_ulBsrReceived.begin (); itBsr != m_ulBsrReceived.end (); itBsr++)
620  {
621  if (((*itBsr).second.statusPduSize > 0) || ((*itBsr).second.retxQueueSize > 0) || ((*itBsr).second.txQueueSize > 0))
622  {
623  activeLcs++;
624  if (((*itBsr).second.statusPduSize != 0)&&((*itBsr).second.statusPduSize < statusPduMinSize))
625  {
626  statusPduMinSize = (*itBsr).second.statusPduSize;
627  }
628  if (((*itBsr).second.statusPduSize != 0)&&(statusPduMinSize == 0))
629  {
630  statusPduMinSize = (*itBsr).second.statusPduSize;
631  }
632  }
633  }
634  if (activeLcs == 0)
635  {
636  NS_LOG_ERROR (this << " No active flows for this UL-DCI");
637  return;
638  }
639  std::map <uint8_t, LcInfo>::iterator it;
640  uint32_t bytesPerActiveLc = dci.m_tbSize / activeLcs;
641  bool statusPduPriority = false;
642  if ((statusPduMinSize != 0)&&(bytesPerActiveLc < statusPduMinSize))
643  {
644  // send only the status PDU which has highest priority
645  statusPduPriority = true;
646  NS_LOG_DEBUG (this << " Reduced resource -> send only Status, b ytes " << statusPduMinSize);
647  if (dci.m_tbSize < statusPduMinSize)
648  {
649  NS_FATAL_ERROR ("Insufficient Tx Opportunity for sending a status message");
650  }
651  }
652  NS_LOG_LOGIC (this << " UE " << m_rnti << ": UL-CQI notified TxOpportunity of " << dci.m_tbSize << " => " << bytesPerActiveLc << " bytes per active LC" << " statusPduMinSize " << statusPduMinSize);
653  for (it = m_lcInfoMap.begin (); it != m_lcInfoMap.end (); it++)
654  {
655  itBsr = m_ulBsrReceived.find ((*it).first);
656  NS_LOG_DEBUG (this << " Processing LC " << (uint32_t)(*it).first << " bytesPerActiveLc " << bytesPerActiveLc);
657  if ( (itBsr != m_ulBsrReceived.end ())
658  && ( ((*itBsr).second.statusPduSize > 0)
659  || ((*itBsr).second.retxQueueSize > 0)
660  || ((*itBsr).second.txQueueSize > 0)) )
661  {
662  if ((statusPduPriority) && ((*itBsr).second.statusPduSize == statusPduMinSize))
663  {
664  (*it).second.macSapUser->NotifyTxOpportunity ((*itBsr).second.statusPduSize, 0, 0, m_componentCarrierId, m_rnti, (*it).first);
665  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);
666  (*itBsr).second.statusPduSize = 0;
667  break;
668  }
669  else
670  {
671  uint32_t bytesForThisLc = bytesPerActiveLc;
672  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);
673  if (((*itBsr).second.statusPduSize > 0) && (bytesForThisLc > (*itBsr).second.statusPduSize))
674  {
675  (*it).second.macSapUser->NotifyTxOpportunity ((*itBsr).second.statusPduSize, 0, 0, m_componentCarrierId, m_rnti, (*it).first);
676  bytesForThisLc -= (*itBsr).second.statusPduSize;
677  NS_LOG_DEBUG (this << " serve STATUS " << (*itBsr).second.statusPduSize);
678  (*itBsr).second.statusPduSize = 0;
679  }
680  else
681  {
682  if ((*itBsr).second.statusPduSize > bytesForThisLc)
683  {
684  NS_FATAL_ERROR ("Insufficient Tx Opportunity for sending a status message");
685  }
686  }
687 
688  if ((bytesForThisLc > 7) // 7 is the min TxOpportunity useful for Rlc
689  && (((*itBsr).second.retxQueueSize > 0)
690  || ((*itBsr).second.txQueueSize > 0)))
691  {
692  if ((*itBsr).second.retxQueueSize > 0)
693  {
694  NS_LOG_DEBUG (this << " serve retx DATA, bytes " << bytesForThisLc);
695  (*it).second.macSapUser->NotifyTxOpportunity (bytesForThisLc, 0, 0, m_componentCarrierId, m_rnti, (*it).first);
696  if ((*itBsr).second.retxQueueSize >= bytesForThisLc)
697  {
698  (*itBsr).second.retxQueueSize -= bytesForThisLc;
699  }
700  else
701  {
702  (*itBsr).second.retxQueueSize = 0;
703  }
704  }
705  else if ((*itBsr).second.txQueueSize > 0)
706  {
707  uint16_t lcid = (*it).first;
708  uint32_t rlcOverhead;
709  if (lcid == 1)
710  {
711  // for SRB1 (using RLC AM) it's better to
712  // overestimate RLC overhead rather than
713  // underestimate it and risk unneeded
714  // segmentation which increases delay
715  rlcOverhead = 4;
716  }
717  else
718  {
719  // minimum RLC overhead due to header
720  rlcOverhead = 2;
721  }
722  NS_LOG_DEBUG (this << " serve tx DATA, bytes " << bytesForThisLc << ", RLC overhead " << rlcOverhead);
723  (*it).second.macSapUser->NotifyTxOpportunity (bytesForThisLc, 0, 0, m_componentCarrierId, m_rnti, (*it).first);
724  if ((*itBsr).second.txQueueSize >= bytesForThisLc - rlcOverhead)
725  {
726  (*itBsr).second.txQueueSize -= bytesForThisLc - rlcOverhead;
727  }
728  else
729  {
730  (*itBsr).second.txQueueSize = 0;
731  }
732  }
733  }
734  else
735  {
736  if ( ((*itBsr).second.retxQueueSize > 0) || ((*itBsr).second.txQueueSize > 0))
737  {
738  // resend BSR info for updating eNB peer MAC
739  m_freshUlBsr = true;
740  }
741  }
742  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);
743  }
744 
745  }
746  }
747  }
748  else
749  {
750  // HARQ retransmission -> retrieve data from HARQ buffer
751  NS_LOG_DEBUG (this << " UE MAC RETX HARQ " << (uint16_t)m_harqProcessId);
752  Ptr<PacketBurst> pb = m_miUlHarqProcessesPacket.at (m_harqProcessId);
753  for (std::list<Ptr<Packet> >::const_iterator j = pb->Begin (); j != pb->End (); ++j)
754  {
755  Ptr<Packet> pkt = (*j)->Copy ();
757  }
758  m_miUlHarqProcessesPacketTimer.at (m_harqProcessId) = HARQ_PERIOD;
759  }
760 
761  }
762  else if (msg->GetMessageType () == LteControlMessage::RAR)
763  {
765  {
766  Ptr<RarLteControlMessage> rarMsg = DynamicCast<RarLteControlMessage> (msg);
767  uint16_t raRnti = rarMsg->GetRaRnti ();
768  NS_LOG_LOGIC (this << "got RAR with RA-RNTI " << (uint32_t) raRnti << ", expecting " << (uint32_t) m_raRnti);
769  if (raRnti == m_raRnti) // RAR corresponds to TX subframe of preamble
770  {
771  for (std::list<RarLteControlMessage::Rar>::const_iterator it = rarMsg->RarListBegin ();
772  it != rarMsg->RarListEnd ();
773  ++it)
774  {
775  if (it->rapId == m_raPreambleId) // RAR is for me
776  {
777  RecvRaResponse (it->rarPayload);
781  }
782  }
783  }
784  }
785  }
786  else
787  {
788  NS_LOG_WARN (this << " LteControlMessage not recognized");
789  }
790 }
791 
792 void
794 {
795  NS_LOG_FUNCTION (this);
796 
797  for (uint16_t i = 0; i < m_miUlHarqProcessesPacketTimer.size (); i++)
798  {
799  if (m_miUlHarqProcessesPacketTimer.at (i) == 0)
800  {
801  if (m_miUlHarqProcessesPacket.at (i)->GetSize () > 0)
802  {
803  // timer expired: drop packets in buffer for this process
804  NS_LOG_INFO (this << " HARQ Proc Id " << i << " packets buffer expired");
805  Ptr<PacketBurst> emptyPb = CreateObject <PacketBurst> ();
806  m_miUlHarqProcessesPacket.at (i) = emptyPb;
807  }
808  }
809  else
810  {
812  }
813  }
814 }
815 
816 
817 void
818 LteUeMac::DoSubframeIndication (uint32_t frameNo, uint32_t subframeNo)
819 {
820  NS_LOG_FUNCTION (this);
821  m_frameNo = frameNo;
822  m_subframeNo = subframeNo;
824  if ((Simulator::Now () >= m_bsrLast + m_bsrPeriodicity) && (m_freshUlBsr == true))
825  {
828  m_freshUlBsr = false;
830  }
831 }
832 
833 int64_t
834 LteUeMac::AssignStreams (int64_t stream)
835 {
836  NS_LOG_FUNCTION (this << stream);
838  return 1;
839 }
840 
841 } // namespace ns3
uint8_t numberOfRaPreambles
number of RA preambles
virtual void AddLc(uint8_t lcId, LteUeCmacSapProvider::LogicalChannelConfig lcConfig, LteMacSapUser *msu)
add a new Logical Channel (LC)
Definition: lte-ue-mac.cc:106
void DoStartNonContentionBasedRandomAccessProcedure(uint16_t rnti, uint8_t rapId, uint8_t prachMask)
Start non contention based random access procedure function.
Definition: lte-ue-mac.cc:526
LteUeCmacSapProvider::LogicalChannelConfig lcConfig
logical channel config
Definition: lte-ue-mac.h:222
uint8_t GetLcid(void) const
Get LCID function.
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:102
void DoReset()
Reset function.
Definition: lte-ue-mac.cc:557
uint8_t m_raPreambleId
RA preamble ID.
Definition: lte-ue-mac.h:252
uint8_t raResponseWindowSize
RA response window size.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
void SetStream(int64_t stream)
Specifies the stream number for the RngStream.
virtual void TransmitPdu(TransmitPduParameters params)
send an RLC PDU to the MAC for transmission.
Definition: lte-ue-mac.cc:149
#define HARQ_PERIOD
Definition: lte-common.h:30
void SendRaPreamble(bool contention)
Send RA preamble function.
Definition: lte-ue-mac.cc:407
void StartWaitingForRaResponse()
Start waiting for RA response function.
Definition: lte-ue-mac.cc:429
void DoReceivePhyPdu(Ptr< Packet > p)
Receive Phy PDU function.
Definition: lte-ue-mac.cc:582
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:45
Ptr< UniformRandomVariable > m_raPreambleUniformVariable
RA preamble random variable.
Definition: lte-ue-mac.h:256
uint16_t GetRnti(void) const
Get RNTI function.
LteUePhySapUser * m_uePhySapUser
UE Phy SAP user.
Definition: lte-ue-mac.h:234
void DoSetRnti(uint16_t rnti)
Set RNTI.
Definition: lte-ue-mac.cc:518
void AddPacketTag(const Tag &tag) const
Add a packet tag.
Definition: packet.cc:814
UeMemberLteMacSapProvider class.
Definition: lte-ue-mac.cc:124
#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_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:201
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1001
void RaResponseTimeout(bool contention)
RA response timeout function.
Definition: lte-ue-mac.cc:472
See section 4.3.2 ulDciListElement.
virtual void ReportBufferStatus(ReportBufferStatusParameters params)
Report the RLC buffer status to the MAC.
Definition: lte-ue-mac.cc:156
struct MacCeValue_u m_macCeValue
MAC CE value.
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:277
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:162
See section 4.3.10 buildRARListElement.
void DoAddLc(uint8_t lcId, LteUeCmacSapProvider::LogicalChannelConfig lcConfig, LteMacSapUser *msu)
Add LC function.
Definition: lte-ue-mac.cc:537
virtual void DoDispose(void)
Destructor implementation.
Definition: object.cc:346
void SetLteUePhySapProvider(LteUePhySapProvider *s)
Set the PHY SAP Provider.
Definition: lte-ue-mac.cc:279
virtual void SendRachPreamble(uint32_t prachId, uint32_t raRnti)=0
send a preamble on the PRACH
Service Access Point (SAP) offered by the PHY to the MAC.
UeMemberLteUeCmacSapProvider class.
Definition: lte-ue-mac.cc:52
uint8_t lcid
the logical channel id corresponding to the sending RLC instance
Definition: lte-mac-sap.h:49
void DoStartContentionBasedRandomAccessProcedure()
Start contention based random access procedure function.
Definition: lte-ue-mac.cc:506
void SendReportBufferStatus(void)
Send report buffer status.
Definition: lte-ue-mac.cc:345
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:198
virtual ~LteUeMac()
Definition: lte-ue-mac.cc:255
uint16_t m_tbSize
size
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:88
void DoRemoveLc(uint8_t lcId)
Remove LC function.
Definition: lte-ue-mac.cc:549
Parameters for LteMacSapProvider::ReportBufferStatus.
Definition: lte-mac-sap.h:67
std::vector< uint8_t > m_miUlHarqProcessesPacketTimer
timer for packet life in the buffer
Definition: lte-ue-mac.h:246
friend class UeMemberLteUePhySapUser
allow UeMemberLteUePhySapUser class friend access
Definition: lte-ue-mac.h:50
void SetLteUeCmacSapUser(LteUeCmacSapUser *s)
Set the LTE UE CMAC SAP user.
Definition: lte-ue-mac.cc:292
void DoTransmitPdu(LteMacSapProvider::TransmitPduParameters params)
Transmit PDU function.
Definition: lte-ue-mac.cc:310
virtual void ConfigureRach(RachConfig rc)
Configure RACH function.
Definition: lte-ue-mac.cc:82
virtual void SetTemporaryCellRnti(uint16_t rnti)=0
friend class UeMemberLteMacSapProvider
allow UeMemberLteMacSapProvider class friend access
Definition: lte-ue-mac.h:48
virtual uint32_t GetInteger(void)=0
Get the next random value as an integer drawn from the distribution.
uint8_t preambleTransMax
preamble transmit maximum
uint8_t m_harqProcessId
HARQ process ID.
Definition: lte-ue-mac.h:244
static EventId Schedule(Time const &delay, MEM mem_ptr, OBJ obj)
Schedule an event to expire after delay.
Definition: simulator.h:1375
static uint8_t BufferSize2BsrId(uint32_t val)
Convert Buffer size to BSR ID.
Definition: lte-common.cc:191
virtual void Reset()
reset the MAC
Definition: lte-ue-mac.cc:118
LteUeMac * m_mac
the UE MAC
Definition: lte-ue-mac.cc:139
uint32_t m_frameNo
frame number
Definition: lte-ue-mac.h:258
bool m_waitingForRaResponse
waiting for RA response
Definition: lte-ue-mac.h:261
void DoReportBufferStatus(LteMacSapProvider::ReportBufferStatusParameters params)
Report buffers status function.
Definition: lte-ue-mac.cc:323
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:94
virtual void SendMacPdu(Ptr< Packet > p)=0
Send the MAC PDU to the channel.
uint16_t m_rnti
RNTI.
Definition: lte-ue-mac.h:248
LteUeCmacSapProvider * m_cmacSapProvider
CMAC SAP provider.
Definition: lte-ue-mac.h:231
uint16_t rnti
the C-RNTI identifying the UE
Definition: lte-mac-sap.h:48
uint8_t m_raRnti
RA RNTI.
Definition: lte-ue-mac.h:260
std::vector< Ptr< PacketBurst > > m_miUlHarqProcessesPacket
Packets under trasmission of the UL HARQ processes.
Definition: lte-ue-mac.h:245
LteUeCmacSapProvider * GetLteUeCmacSapProvider(void)
Get the LTE CMAC SAP provider.
Definition: lte-ue-mac.cc:298
Service Access Point (SAP) offered by the UE MAC to the UE RRC.
tuple mac
Definition: third.py:92
void SetComponentCarrierId(uint8_t index)
Set the component carried ID.
Definition: lte-ue-mac.cc:304
void DoConfigureRach(LteUeCmacSapProvider::RachConfig rc)
Configure RACH function.
Definition: lte-ue-mac.cc:498
#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:818
UeMemberLteUeCmacSapProvider(LteUeMac *mac)
Constructor.
Definition: lte-ue-mac.cc:76
void DoReceiveLteControlMessage(Ptr< LteControlMessage > msg)
Receive LTE control message function.
Definition: lte-ue-mac.cc:603
Ptr< Packet > Copy(void) const
performs a COW copy of the packet.
Definition: packet.cc:121
std::map< uint8_t, LcInfo > m_lcInfoMap
logical channel info map
Definition: lte-ue-mac.h:226
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:273
Every class exported by the ns3 library is enclosed in the ns3 namespace.
LteMacSapProvider * GetLteMacSapProvider(void)
Get the LTE MAC SAP provider.
Definition: lte-ue-mac.cc:286
uint16_t m_backoffParameter
backoff parameter
Definition: lte-ue-mac.h:254
static TypeId GetTypeId(void)
Get the type ID.
Definition: lte-ue-mac.cc:218
UeMemberLteUePhySapUser(LteUeMac *mac)
Constructor.
Definition: lte-ue-mac.cc:185
LteMacSapProvider * m_macSapProvider
MAC SAP provider.
Definition: lte-ue-mac.h:228
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:70
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:191
LteUePhySapProvider * m_uePhySapProvider
UE Phy SAP provider.
Definition: lte-ue-mac.h:233
uint8_t m_componentCarrierId
component carrier Id –> used to address sap
Definition: lte-ue-mac.h:215
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:249
Time m_bsrLast
BSR last.
Definition: lte-ue-mac.h:240
bool m_freshUlBsr
true when a BSR has been received in the last TTI
Definition: lte-ue-mac.h:242
NS_LOG_LOGIC("Net device "<< nd<< " is not bridged")
virtual void RemoveLc(uint8_t lcId)
remove an existing LC
Definition: lte-ue-mac.cc:112
#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:90
virtual void SetRnti(uint16_t rnti)
Definition: lte-ue-mac.cc:100
std::vector< uint8_t > m_bufferStatus
buffer status
virtual void NotifyRandomAccessFailed()=0
Notify the RRC that the MAC Random Access procedure failed.
void RandomlySelectAndSendRaPreamble()
Randomly sleect and send RA preamble function.
Definition: lte-ue-mac.cc:395
void RecvRaResponse(BuildRarListElement_s raResponse)
Receive the RA response function.
Definition: lte-ue-mac.cc:436
uint8_t m_preambleTransmissionCounter
preamble tranamission counter
Definition: lte-ue-mac.h:253
Service Access Point (SAP) offered by the MAC to the RLC See Femto Forum MAC Scheduler Interface Spec...
Definition: lte-mac-sap.h:95
EventId m_noRaResponseReceivedEvent
no RA response received event ID
Definition: lte-ue-mac.h:255
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition: log.h:261
bool m_rachConfigured
is RACH configured?
Definition: lte-ue-mac.h:250
virtual void DoDispose(void)
Destructor implementation.
Definition: lte-ue-mac.cc:261
LteUeCmacSapProvider::RachConfig m_rachConfig
RACH configuration.
Definition: lte-ue-mac.h:251
Service Access Point (SAP) offered by the UE-PHY to the UE-MAC.
bool RemovePacketTag(Tag &tag)
Remove a packet tag.
Definition: packet.cc:821
LteUeMac * m_mac
the UE MAC
Definition: lte-ue-mac.cc:182
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:269
LteUeMac * m_mac
the UE MAC
Definition: lte-ue-mac.cc:72
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:36
LcInfo structure.
Definition: lte-ue-mac.h:220
Tag used to define the RNTI and LC id for each MAC packet trasmitted.
enum ns3::MacCeListElement_s::MacCeType_e m_macCeType
MAC CE type.
Time m_bsrPeriodicity
BSR periodicity.
Definition: lte-ue-mac.h:239
virtual void ReceiveLteControlMessage(Ptr< LteControlMessage > msg)
Receive SendLteControlMessage (PDCCH map, CQI feedbacks) using the ideal control channel.
Definition: lte-ue-mac.cc:204
UeMemberLteUePhySapUser.
Definition: lte-ue-mac.cc:166
#define NS_LOG_ERROR(msg)
Use NS_LOG to output a message of level LOG_ERROR.
Definition: log.h:253
uint32_t m_subframeNo
subframe number
Definition: lte-ue-mac.h:259
std::map< uint8_t, LteMacSapProvider::ReportBufferStatusParameters > m_ulBsrReceived
BSR received from RLC (the last one)
Definition: lte-ue-mac.h:236
A base class which provides memory management and object aggregation.
Definition: object.h:87
friend class UeMemberLteUeCmacSapProvider
allow UeMemberLteUeCmacSapProvider class friend access
Definition: lte-ue-mac.h:46
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:834
a unique identifier for an interface.
Definition: type-id.h:58
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:914
void RefreshHarqProcessesPacketBuffer(void)
Refresh HARQ processes packet buffer function.
Definition: lte-ue-mac.cc:793
UeMemberLteMacSapProvider(LteUeMac *mac)
Constructor.
Definition: lte-ue-mac.cc:143
LteUeCmacSapUser * m_cmacSapUser
CMAC SAP user.
Definition: lte-ue-mac.h:230
Parameters for LteMacSapProvider::TransmitPdu.
Definition: lte-mac-sap.h:45