A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
lte-enb-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: Marco Miozzo <marco.miozzo@cttc.es>
19  * Nicola Baldo <nbaldo@cttc.es>
20  */
21 
22 
23 #include <ns3/log.h>
24 #include <ns3/pointer.h>
25 #include <ns3/packet.h>
26 
27 #include "lte-amc.h"
28 #include "ideal-control-messages.h"
29 #include "lte-enb-net-device.h"
30 #include "lte-ue-net-device.h"
31 
32 #include <ns3/lte-enb-mac.h>
33 #include <ns3/lte-radio-bearer-tag.h>
34 #include <ns3/lte-ue-phy.h>
35 
36 #include "ns3/lte-mac-sap.h"
37 #include <ns3/lte-common.h>
38 
39 
40 NS_LOG_COMPONENT_DEFINE ("LteEnbMac");
41 
42 namespace ns3 {
43 
44 
45 NS_OBJECT_ENSURE_REGISTERED (LteEnbMac);
46 
47 
48 
49 // //////////////////////////////////////
50 // member SAP forwarders
51 // //////////////////////////////////////
52 
53 
55 {
56 public:
58 
59  // inherited from LteEnbCmacSapProvider
60  virtual void ConfigureMac (uint8_t ulBandwidth, uint8_t dlBandwidth);
61  virtual void AddUe (uint16_t rnti);
62  virtual void AddLc (LcInfo lcinfo, LteMacSapUser* msu);
63  virtual void ReconfigureLc (LcInfo lcinfo);
64  virtual void ReleaseLc (uint16_t rnti, uint8_t lcid);
66 
67 private:
69 };
70 
71 
73  : m_mac (mac)
74 {
75 }
76 
77 void
78 EnbMacMemberLteEnbCmacSapProvider::ConfigureMac (uint8_t ulBandwidth, uint8_t dlBandwidth)
79 {
80  m_mac->DoConfigureMac (ulBandwidth, dlBandwidth);
81 }
82 
83 void
85 {
86  m_mac->DoAddUe (rnti);
87 }
88 
89 void
91 {
92  m_mac->DoAddLc (lcinfo, msu);
93 }
94 
95 void
97 {
98  m_mac->DoReconfigureLc (lcinfo);
99 }
100 
101 void
102 EnbMacMemberLteEnbCmacSapProvider::ReleaseLc (uint16_t rnti, uint8_t lcid)
103 {
104  m_mac->DoReleaseLc (rnti, lcid);
105 }
106 
107 void
109 {
111 }
112 
113 
114 
116 {
117 public:
119 
120 
121  virtual void SchedDlConfigInd (const struct SchedDlConfigIndParameters& params);
122  virtual void SchedUlConfigInd (const struct SchedUlConfigIndParameters& params);
123 private:
125 };
126 
127 
129  : m_mac (mac)
130 {
131 }
132 
133 
134 void
136 {
137  m_mac->DoSchedDlConfigInd (params);
138 }
139 
140 
141 
142 void
144 {
145  m_mac->DoSchedUlConfigInd (params);
146 }
147 
148 
149 
151 {
152 public:
154 
155  virtual void CschedCellConfigCnf (const struct CschedCellConfigCnfParameters& params);
156  virtual void CschedUeConfigCnf (const struct CschedUeConfigCnfParameters& params);
157  virtual void CschedLcConfigCnf (const struct CschedLcConfigCnfParameters& params);
158  virtual void CschedLcReleaseCnf (const struct CschedLcReleaseCnfParameters& params);
159  virtual void CschedUeReleaseCnf (const struct CschedUeReleaseCnfParameters& params);
160  virtual void CschedUeConfigUpdateInd (const struct CschedUeConfigUpdateIndParameters& params);
161  virtual void CschedCellConfigUpdateInd (const struct CschedCellConfigUpdateIndParameters& params);
162 
163 private:
165 };
166 
167 
169  : m_mac (mac)
170 {
171 }
172 
173 void
175 {
176  m_mac->DoCschedCellConfigCnf (params);
177 }
178 
179 void
181 {
182  m_mac->DoCschedUeConfigCnf (params);
183 }
184 
185 void
187 {
188  m_mac->DoCschedLcConfigCnf (params);
189 }
190 
191 void
193 {
194  m_mac->DoCschedLcReleaseCnf (params);
195 }
196 
197 void
199 {
200  m_mac->DoCschedUeReleaseCnf (params);
201 }
202 
203 void
205 {
207 }
208 
209 void
211 {
213 }
214 
215 
216 
217 // ---------- PHY-SAP
218 
219 
221 {
222 public:
224 
225  // inherited from LteEnbPhySapUser
226  virtual void ReceivePhyPdu (Ptr<Packet> p);
227  virtual void SubframeIndication (uint32_t frameNo, uint32_t subframeNo);
229  virtual void UlCqiReport (UlCqi_s ulcqi);
230 
231 private:
233 };
234 
236 {
237 }
238 
239 
240 void
242 {
243  m_mac->DoReceivePhyPdu (p);
244 }
245 
246 void
247 EnbMacMemberLteEnbPhySapUser::SubframeIndication (uint32_t frameNo, uint32_t subframeNo)
248 {
249  m_mac->DoSubframeIndication (frameNo, subframeNo);
250 }
251 
252 void
254 {
256 }
257 
258 void
260 {
261  m_mac->DoUlCqiReport (ulcqi);
262 }
263 
264 
265 // //////////////////////////////////////
266 // generic LteEnbMac methods
267 // //////////////////////////////////////
268 
269 
270 TypeId
272 {
273  static TypeId tid = TypeId ("ns3::LteEnbMac")
274  .SetParent<Object> ()
275  .AddConstructor<LteEnbMac> ()
276  .AddTraceSource ("DlScheduling",
277  "Information regarding DL scheduling.",
279  .AddTraceSource ("UlScheduling",
280  "Information regarding UL scheduling.",
282  ;
283 
284  return tid;
285 }
286 
287 
289 {
290  NS_LOG_FUNCTION (this);
296 }
297 
298 
300 {
301  NS_LOG_FUNCTION (this);
302 }
303 
304 void
306 {
307  NS_LOG_FUNCTION (this);
308  delete m_macSapProvider;
309  delete m_cmacSapProvider;
310  delete m_schedSapUser;
311  delete m_cschedSapUser;
312  delete m_enbPhySapUser;
313 }
314 
315 
316 void
318 {
319  m_schedSapProvider = s;
320 }
321 
324 {
325  return m_schedSapUser;
326 }
327 
328 void
330 {
332 }
333 
336 {
337  return m_cschedSapUser;
338 }
339 
340 
341 
342 void
344 {
345  m_macSapUser = s;
346 }
347 
350 {
351  return m_macSapProvider;
352 }
353 
354 void
356 {
357  m_cmacSapUser = s;
358 }
359 
362 {
363  return m_cmacSapProvider;
364 }
365 
366 void
368 {
370 }
371 
372 
375 {
376  return m_enbPhySapUser;
377 }
378 
379 
380 
381 void
382 LteEnbMac::DoSubframeIndication (uint32_t frameNo, uint32_t subframeNo)
383 {
384  NS_LOG_FUNCTION (this << " EnbMac - frame " << frameNo << " subframe " << subframeNo);
385 
386  // Store current frame / subframe number
387  m_frameNo = frameNo;
388  m_subframeNo = subframeNo;
389 
390 
391  // --- DOWNLINK ---
392  // Send Dl-CQI info to the scheduler
393  if (m_dlCqiReceived.size () > 0)
394  {
396  dlcqiInfoReq.m_sfnSf = ((0x3FF & frameNo) << 4) | (0xF & subframeNo);
397 
398  int cqiNum = m_dlCqiReceived.size ();
399  if (cqiNum > MAX_CQI_LIST)
400  {
401  cqiNum = MAX_CQI_LIST;
402  }
403  dlcqiInfoReq.m_cqiList.insert (dlcqiInfoReq.m_cqiList.begin (), m_dlCqiReceived.begin (), m_dlCqiReceived.end ());
404  m_dlCqiReceived.erase (m_dlCqiReceived.begin (), m_dlCqiReceived.end ());
405  m_schedSapProvider->SchedDlCqiInfoReq (dlcqiInfoReq);
406  }
407 
408 
409  // Get downlink transmission opportunities
410 // uint32_t dlSchedFrameNo = (0x3FF & (m_frameNo >> 4));
411 // uint32_t dlSchedSubframeNo = (0xF & m_subframeNo);
412  uint32_t dlSchedFrameNo = m_frameNo;
413  uint32_t dlSchedSubframeNo = m_subframeNo;
414  // NS_LOG_DEBUG (this << " sfn " << frameNo << " sbfn " << subframeNo);
415  if (dlSchedSubframeNo + m_macChTtiDelay > 10)
416  {
417  dlSchedFrameNo++;
418  dlSchedSubframeNo = (dlSchedSubframeNo + m_macChTtiDelay) % 10;
419  }
420  else
421  {
422  dlSchedSubframeNo = dlSchedSubframeNo + m_macChTtiDelay;
423  }
425  params.m_sfnSf = ((0x3FF & dlSchedFrameNo) << 4) | (0xF & dlSchedSubframeNo);
427 
428 
429  // --- UPLINK ---
430  // Send UL-CQI info to the scheduler
431  if (m_ulCqiReceived.size () > 0)
432  {
434  if (subframeNo>1)
435  {
436  ulcqiInfoReq.m_sfnSf = ((0x3FF & frameNo) << 4) | (0xF & subframeNo);
437  }
438  else
439  {
440  ulcqiInfoReq.m_sfnSf = ((0x3FF & (frameNo-1)) << 4) | (0xF & 10);
441  }
442  int cqiNum = m_ulCqiReceived.size ();
443  if (cqiNum >= 1)
444  {
445  ulcqiInfoReq.m_ulCqi = m_ulCqiReceived.at (cqiNum - 1);
446  if (cqiNum > 1)
447  {
448  // empty old ul cqi
449  while (m_ulCqiReceived.size () > 0)
450  {
451  m_ulCqiReceived.pop_back ();
452  }
453  }
454  m_schedSapProvider->SchedUlCqiInfoReq (ulcqiInfoReq);
455  }
456  }
457 
458  // Send BSR reports to the scheduler
459  if (m_ulCeReceived.size () > 0)
460  {
462  ulMacReq.m_sfnSf = ((0x3FF & frameNo) << 4) | (0xF & subframeNo);
463  ulMacReq.m_macCeList.insert (ulMacReq.m_macCeList.begin (), m_ulCeReceived.begin (), m_ulCeReceived.end ());
464  m_ulCeReceived.erase (m_ulCeReceived.begin (), m_ulCeReceived.end ());
466  }
467 
468 
469  // Get uplink transmission opportunities
470  uint32_t ulSchedFrameNo = m_frameNo;
471  uint32_t ulSchedSubframeNo = m_subframeNo;
472  // NS_LOG_DEBUG (this << " sfn " << frameNo << " sbfn " << subframeNo);
473  if (ulSchedSubframeNo + (m_macChTtiDelay+UL_PUSCH_TTIS_DELAY) > 10)
474  {
475  ulSchedFrameNo++;
476  ulSchedSubframeNo = (ulSchedSubframeNo + (m_macChTtiDelay+UL_PUSCH_TTIS_DELAY)) % 10;
477  }
478  else
479  {
480 // ulSchedSubframeNo = (ulSchedSubframeNo + (2*m_macChTtiDelay)) % 11;
481  ulSchedSubframeNo = ulSchedSubframeNo + (m_macChTtiDelay+UL_PUSCH_TTIS_DELAY);
482  }
484  ulparams.m_sfnSf = ((0x3FF & ulSchedFrameNo) << 4) | (0xF & ulSchedSubframeNo);
485 
486  std::map <uint16_t,UlInfoListElement_s>::iterator it;
487  for (it = m_ulInfoListElements.begin (); it != m_ulInfoListElements.end (); it++)
488  {
489  ulparams.m_ulInfoList.push_back ((*it).second);
490  }
492 
493 
494 
495 
496  // reset UL info
497  //std::map <uint16_t,UlInfoListElement_s>::iterator it;
498  for (it = m_ulInfoListElements.begin (); it != m_ulInfoListElements.end (); it++)
499  {
500  for (uint16_t i = 0; i < (*it).second.m_ulReception.size (); i++)
501  {
502  (*it).second.m_ulReception.at (i) = 0;
503  }
504  (*it).second.m_receptionStatus = UlInfoListElement_s::Ok;
505  (*it).second.m_tpc = 0;
506  }
507 }
508 
509 void
511 {
512  NS_LOG_FUNCTION (this << msg);
514  {
515  Ptr<DlCqiIdealControlMessage> dlcqi = DynamicCast<DlCqiIdealControlMessage> (msg);
517  }
518  else if (msg->GetMessageType () == IdealControlMessage::BSR)
519  {
520  Ptr<BsrIdealControlMessage> bsr = DynamicCast<BsrIdealControlMessage> (msg);
521  ReceiveBsrMessage (bsr->GetBsr ());
522  }
523  else
524  {
525  NS_LOG_LOGIC (this << " IdealControlMessage not recognized");
526  }
527 }
528 
529 
530 void
532 {
533  if (ulcqi.m_type == UlCqi_s::PUSCH)
534  {
535  NS_LOG_DEBUG (this << " eNB rxed an PUSCH UL-CQI");
536  }
537  // TODO store UL-CQI to send them to scheduler
538  m_ulCqiReceived.push_back (ulcqi);
539 }
540 
541 
542 void
544 {
545  NS_LOG_FUNCTION (this << msg);
546 
547  CqiListElement_s dlcqi = msg->GetDlCqi ();
548  NS_LOG_LOGIC (this << "Enb Received DL-CQI rnti" << dlcqi.m_rnti);
549  m_dlCqiReceived.push_back (dlcqi);
550 
551 }
552 
553 
554 void
556 {
557  NS_LOG_FUNCTION (this);
558 
559  m_ulCeReceived.push_back (bsr);
560 }
561 
562 
563 
564 void
566 {
567  NS_LOG_FUNCTION (this);
568  LteRadioBearerTag tag;
569  p->RemovePacketTag (tag);
570 
571  // store info of the packet received
572 
573  std::map <uint16_t,UlInfoListElement_s>::iterator it;
574 // u_int rnti = tag.GetRnti ();
575 // u_int lcid = tag.GetLcid ();
576  it = m_ulInfoListElements.find (tag.GetRnti ());
577  if (it == m_ulInfoListElements.end ())
578  {
579  // new RNTI
580  UlInfoListElement_s ulinfonew;
581  ulinfonew.m_rnti = tag.GetRnti ();
582  // always allocate full size of ulReception vector, initializing all elements to 0
583  ulinfonew.m_ulReception.assign (MAX_LC_LIST+1, 0);
584  // set the element for the current LCID
585  ulinfonew.m_ulReception.at (tag.GetLcid ()) = p->GetSize ();
587  ulinfonew.m_tpc = 0; // Tx power control not implemented at this stage
588  m_ulInfoListElements.insert (std::pair<uint16_t, UlInfoListElement_s > (tag.GetRnti (), ulinfonew));
589 
590  }
591  else
592  {
593  // existing RNTI: we just set the value for the current
594  // LCID. Note that the corresponding element had already been
595  // allocated previously.
596  NS_ASSERT_MSG ((*it).second.m_ulReception.at (tag.GetLcid ()) == 0, "would overwrite previously written ulReception element");
597  (*it).second.m_ulReception.at (tag.GetLcid ()) = p->GetSize ();
598  (*it).second.m_receptionStatus = UlInfoListElement_s::Ok;
599  }
600 
601 
602 
603  // forward the packet to the correspondent RLC
604  LteFlowId_t flow ( tag.GetRnti (), tag.GetLcid () );
605  std::map <LteFlowId_t, LteMacSapUser* >::iterator it2;
606  it2 = m_rlcAttached.find (flow);
607  NS_ASSERT_MSG (it2 != m_rlcAttached.end (), "UE not attached rnti=" << flow.m_rnti << " lcid=" << (uint32_t) flow.m_lcId);
608  (*it2).second->ReceivePdu (p);
609 
610 }
611 
612 
613 
614 
615 // ////////////////////////////////////////////
616 // CMAC SAP
617 // ////////////////////////////////////////////
618 
619 void
620 LteEnbMac::DoConfigureMac (uint8_t ulBandwidth, uint8_t dlBandwidth)
621 {
622  NS_LOG_FUNCTION (this << " ulBandwidth=" << (uint16_t) ulBandwidth << " dlBandwidth=" << (uint16_t) dlBandwidth);
624  // Configure the subset of parameters used by FfMacScheduler
625  params.m_ulBandwidth = ulBandwidth;
626  params.m_dlBandwidth = dlBandwidth;
628  // ...more parameters can be configured
630 }
631 
632 
633 void
634 LteEnbMac::DoAddUe (uint16_t rnti)
635 {
636  NS_LOG_FUNCTION (this << " rnti=" << rnti);
638  params.m_rnti = rnti;
639  params.m_transmissionMode = 0; // set to default value (SISO) for avoiding random initialization (valgrind error)
641 }
642 
643 
644 void
646 {
647  NS_LOG_FUNCTION (this);
648  std::map <LteFlowId_t, LteMacSapUser* >::iterator it;
649 
650  LteFlowId_t flow (lcinfo.rnti, lcinfo.lcId);
651 
652  it = m_rlcAttached.find (flow);
653  if (it == m_rlcAttached.end ())
654  {
655  m_rlcAttached.insert (std::pair<LteFlowId_t, LteMacSapUser* > (flow, msu));
656  }
657  else
658  {
659  NS_LOG_ERROR ("LC already exists");
660  }
661 
662 
664  params.m_rnti = lcinfo.rnti;
665  params.m_reconfigureFlag = false;
666 
668  lccle.m_logicalChannelIdentity = lcinfo.lcId;
669  lccle.m_logicalChannelGroup = lcinfo.lcGroup;
672  lccle.m_qci = lcinfo.qci;
673  lccle.m_eRabMaximulBitrateUl = lcinfo.mbrUl;
674  lccle.m_eRabMaximulBitrateDl = lcinfo.mbrDl;
675  lccle.m_eRabGuaranteedBitrateUl = lcinfo.gbrUl;
676  lccle.m_eRabGuaranteedBitrateDl = lcinfo.gbrDl;
677  params.m_logicalChannelConfigList.push_back (lccle);
678 
680 }
681 
682 void
684 {
685  NS_FATAL_ERROR ("not implemented");
686 }
687 
688 void
689 LteEnbMac::DoReleaseLc (uint16_t rnti, uint8_t lcid)
690 {
691  NS_FATAL_ERROR ("not implemented");
692 }
693 
694 
695 
696 // ////////////////////////////////////////////
697 // MAC SAP
698 // ////////////////////////////////////////////
699 
700 
701 void
703 {
704  NS_LOG_FUNCTION (this);
705  LteRadioBearerTag tag (params.rnti, params.lcid, params.layer);
706  params.pdu->AddPacketTag (tag);
707 // Ptr<PacketBurst> pb = CreateObject<PacketBurst> ();
708 // pb->AddPacket (params.pdu);
709 
711 }
712 
713 void
715 {
716  NS_LOG_FUNCTION (this);
718  req.m_rnti = params.rnti;
719  req.m_logicalChannelIdentity = params.lcid;
724  req.m_rlcStatusPduSize = params.statusPduSize;
726 }
727 
728 
729 
730 // ////////////////////////////////////////////
731 // SCHED SAP
732 // ////////////////////////////////////////////
733 
734 
735 
736 void
738 {
739  NS_LOG_FUNCTION (this);
740  // Create DL PHY PDU
741  Ptr<PacketBurst> pb = CreateObject<PacketBurst> ();
742  std::map <LteFlowId_t, LteMacSapUser* >::iterator it;
743 
744  for (unsigned int i = 0; i < ind.m_buildDataList.size (); i++)
745  {
746  for (unsigned int j = 0; j < ind.m_buildDataList.at (i).m_rlcPduList.size (); j++)
747  {
748  for (uint16_t k = 0; k < ind.m_buildDataList.at (i).m_rlcPduList.at (j).size (); k++)
749  {
750  LteFlowId_t flow (ind.m_buildDataList.at (i).m_rnti,
751  ind.m_buildDataList.at (i).m_rlcPduList.at (j).at (k).m_logicalChannelIdentity);
752  it = m_rlcAttached.find (flow);
753  NS_ASSERT_MSG (it != m_rlcAttached.end (), "rnti=" << flow.m_rnti << " lcid=" << (uint32_t) flow.m_lcId);
754  NS_LOG_DEBUG (this << " rnti= " << flow.m_rnti << " lcid= " << (uint32_t) flow.m_lcId << " layer= " << k);
755  (*it).second->NotifyTxOpportunity (ind.m_buildDataList.at (i).m_rlcPduList.at (j).at (k).m_size, k);
756  }
757  }
758  // send the relative DCI
759  Ptr<DlDciIdealControlMessage> msg = Create<DlDciIdealControlMessage> ();
760  msg->SetDci (ind.m_buildDataList.at (i).m_dci);
762  }
763 
764  // Fire the trace with the DL information
765  for ( uint32_t i = 0; i < ind.m_buildDataList.size (); i++ )
766  {
767  // Only one TB used
768  if (ind.m_buildDataList.at (i).m_dci.m_tbsSize.size () == 1)
769  {
770  m_dlScheduling (m_frameNo, m_subframeNo, ind.m_buildDataList.at (i).m_dci.m_rnti,
771  ind.m_buildDataList.at (i).m_dci.m_mcs.at (0),
772  ind.m_buildDataList.at (i).m_dci.m_tbsSize.at (0),
773  0, 0
774  );
775 
776  }
777  // Two TBs used
778  else if (ind.m_buildDataList.at (i).m_dci.m_tbsSize.size () == 2)
779  {
780  m_dlScheduling (m_frameNo, m_subframeNo, ind.m_buildDataList.at (i).m_dci.m_rnti,
781  ind.m_buildDataList.at (i).m_dci.m_mcs.at (0),
782  ind.m_buildDataList.at (i).m_dci.m_tbsSize.at (0),
783  ind.m_buildDataList.at (i).m_dci.m_mcs.at (1),
784  ind.m_buildDataList.at (i).m_dci.m_tbsSize.at (1)
785  );
786  }
787  else
788  {
789  NS_FATAL_ERROR ("Found element with more than two transport blocks");
790  }
791  }
792 }
793 
794 
795 void
797 {
798  NS_LOG_FUNCTION (this);
799 
800  for (unsigned int i = 0; i < ind.m_dciList.size (); i++)
801  {
802  // send the correspondent ul dci
803  Ptr<UlDciIdealControlMessage> msg = Create<UlDciIdealControlMessage> ();
804  msg->SetDci (ind.m_dciList.at (i));
806  }
807 
808  // Fire the trace with the UL information
809  for ( uint32_t i = 0; i < ind.m_dciList.size (); i++ )
810  {
811  m_ulScheduling (m_frameNo, m_subframeNo, ind.m_dciList.at (i).m_rnti,
812  ind.m_dciList.at (i).m_mcs, ind.m_dciList.at (i).m_tbSize);
813  }
814 
815 
816 
817 }
818 
819 
820 
821 
822 // ////////////////////////////////////////////
823 // CSCHED SAP
824 // ////////////////////////////////////////////
825 
826 
827 void
829 {
830  NS_LOG_FUNCTION (this);
831 }
832 
833 void
835 {
836  NS_LOG_FUNCTION (this);
837 }
838 
839 void
841 {
842  NS_LOG_FUNCTION (this);
843  // Call the CSCHED primitive
844  // m_cschedSap->LcConfigCompleted();
845 }
846 
847 void
849 {
850  NS_LOG_FUNCTION (this);
851 }
852 
853 void
855 {
856  NS_LOG_FUNCTION (this);
857 }
858 
859 void
861 {
862  NS_LOG_FUNCTION (this);
863  // propagates to RRC
864  LteUeConfig_t ueConfigUpdate;
865  ueConfigUpdate.m_rnti = params.m_rnti;
866  ueConfigUpdate.m_transmissionMode = params.m_transmissionMode;
867  m_cmacSapUser->RrcConfigurationUpdateInd (ueConfigUpdate);
868 }
869 
870 void
872 {
873  NS_LOG_FUNCTION (this);
874  // propagates to PHY layer
876  // propagates to scheduler
878  req.m_rnti = params.m_rnti;
881 }
882 
883 void
885 {
886  NS_LOG_FUNCTION (this);
887 }
888 
889 
890 } // namespace ns3