A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
lte-ue-rrc.cc
1 /* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2011, 2012 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  */
20 
21 #include <ns3/fatal-error.h>
22 #include <ns3/log.h>
23 #include <ns3/object-map.h>
24 #include <ns3/object-factory.h>
25 #include <ns3/node-list.h>
26 #include <ns3/node.h>
27 #include <ns3/simulator.h>
28 
29 #include "lte-ue-rrc.h"
30 #include "lte-enb-rrc.h"
31 #include "lte-rlc.h"
32 #include "lte-rlc-tm.h"
33 #include "lte-rlc-um.h"
34 #include "lte-rlc-am.h"
35 #include "lte-pdcp.h"
36 #include "lte-pdcp-sap.h"
37 #include "lte-radio-bearer-info.h"
38 #include "lte-as-sap.h"
39 #include "lte-enb-net-device.h"
40 
41 NS_LOG_COMPONENT_DEFINE ("LteUeRrc");
42 
43 namespace ns3 {
44 
45 
46 
48 // CMAC SAP forwarder
50 
52 {
53 public:
55 
56  virtual void SetTemporaryCellRnti (uint16_t rnti);
57  virtual void NotifyRandomAccessSuccessful ();
58  virtual void NotifyRandomAccessFailed ();
59 
60 private:
61  LteUeRrc* m_rrc;
62 };
63 
64 UeMemberLteUeCmacSapUser::UeMemberLteUeCmacSapUser (LteUeRrc* rrc)
65  : m_rrc (rrc)
66 {
67 }
68 
69 void
71 {
72  m_rrc->DoSetTemporaryCellRnti (rnti);
73 }
74 
75 
76 void
78 {
79  m_rrc->DoNotifyRandomAccessSuccessful ();
80 }
81 
82 void
84 {
85  m_rrc->DoNotifyRandomAccessFailed ();
86 }
87 
88 
89 
90 
91 
92 
93 
94 const char* g_ueRrcStateName[LteUeRrc::NUM_STATES] =
95  {
96  "IDLE_CELL_SELECTION",
97  "IDLE_WAIT_SYSTEM_INFO",
98  "IDLE_CAMPED_NORMALLY",
99  "IDLE_RANDOM_ACCESS",
100  "IDLE_CONNECTING",
101  "CONNECTED_NORMALLY",
102  "CONNECTED_REESTABLISHING",
103  "CONNECTED_HANDOVER"
104  };
105 
106 std::string ToString (LteUeRrc::State s)
107 {
108  return std::string (g_ueRrcStateName[s]);
109 }
110 
111 
113 // ue RRC methods
115 
116 NS_OBJECT_ENSURE_REGISTERED (LteUeRrc);
117 
118 
120  : m_cphySapProvider (0),
121  m_cmacSapProvider (0),
122  m_rrcSapUser (0),
123  m_macSapProvider (0),
124  m_asSapUser (0),
125  m_state (IDLE_CELL_SELECTION),
126  m_imsi (0),
127  m_rnti (0),
128  m_cellId (0),
129  m_useRlcSm (true),
130  m_connectionPending (0),
131  m_receivedMib (0),
132  m_receivedSib2 (0)
133 
134 {
135  NS_LOG_FUNCTION (this);
136  m_cphySapUser = new MemberLteUeCphySapUser<LteUeRrc> (this);
137  m_cmacSapUser = new UeMemberLteUeCmacSapUser (this);
138  m_rrcSapProvider = new MemberLteUeRrcSapProvider<LteUeRrc> (this);
139  m_drbPdcpSapUser = new LtePdcpSpecificLtePdcpSapUser<LteUeRrc> (this);
140  m_asSapProvider = new MemberLteAsSapProvider<LteUeRrc> (this);
141 }
142 
143 
145 {
146  NS_LOG_FUNCTION (this);
147 }
148 
149 void
151 {
152  NS_LOG_FUNCTION (this);
153  delete m_cphySapUser;
154  delete m_cmacSapUser;
155  delete m_rrcSapProvider;
156  delete m_drbPdcpSapUser;
157  delete m_asSapProvider;
158  m_drbMap.clear ();
159 }
160 
161 TypeId
162 LteUeRrc::GetTypeId (void)
163 {
164  static TypeId tid = TypeId ("ns3::LteUeRrc")
165  .SetParent<Object> ()
166  .AddConstructor<LteUeRrc> ()
167  .AddAttribute ("DataRadioBearerMap", "List of UE RadioBearerInfo for Data Radio Bearers by LCID.",
168  ObjectMapValue (),
169  MakeObjectMapAccessor (&LteUeRrc::m_drbMap),
170  MakeObjectMapChecker<LteDataRadioBearerInfo> ())
171  .AddAttribute ("Srb0", "SignalingRadioBearerInfo for SRB0",
172  PointerValue (),
173  MakePointerAccessor (&LteUeRrc::m_srb0),
174  MakePointerChecker<LteSignalingRadioBearerInfo> ())
175  .AddAttribute ("Srb1", "SignalingRadioBearerInfo for SRB1",
176  PointerValue (),
177  MakePointerAccessor (&LteUeRrc::m_srb1),
178  MakePointerChecker<LteSignalingRadioBearerInfo> ())
179  .AddAttribute ("CellId",
180  "Serving cell identifier",
181  UintegerValue (0), // unused, read-only attribute
182  MakeUintegerAccessor (&LteUeRrc::GetCellId),
183  MakeUintegerChecker<uint16_t> ())
184  .AddAttribute ("C-RNTI",
185  "Cell Radio Network Temporary Identifier",
186  UintegerValue (0), // unused, read-only attribute
187  MakeUintegerAccessor (&LteUeRrc::GetRnti),
188  MakeUintegerChecker<uint16_t> ())
189  .AddTraceSource ("StateTransition",
190  "trace fired upon every UE RRC state transition",
191  MakeTraceSourceAccessor (&LteUeRrc::m_stateTransitionTrace))
192  .AddTraceSource ("RandomAccessSuccessful",
193  "trace fired upon successful completion of the random access procedure",
194  MakeTraceSourceAccessor (&LteUeRrc::m_randomAccessSuccessfulTrace))
195  .AddTraceSource ("ConnectionEstablished",
196  "trace fired upon successful RRC connection establishment",
197  MakeTraceSourceAccessor (&LteUeRrc::m_connectionEstablishedTrace))
198  .AddTraceSource ("ConnectionReconfiguration",
199  "trace fired upon RRC connection reconfiguration",
200  MakeTraceSourceAccessor (&LteUeRrc::m_connectionReconfigurationTrace))
201  .AddTraceSource ("HandoverStart",
202  "trace fired upon start of a handover procedure",
203  MakeTraceSourceAccessor (&LteUeRrc::m_handoverStartTrace))
204  .AddTraceSource ("HandoverEndOk",
205  "trace fired upon successful termination of a handover procedure",
206  MakeTraceSourceAccessor (&LteUeRrc::m_handoverEndOkTrace))
207  ;
208  return tid;
209 }
210 
211 
212 void
214 {
215  NS_LOG_FUNCTION (this << s);
216  m_cphySapProvider = s;
217 }
218 
221 {
222  NS_LOG_FUNCTION (this);
223  return m_cphySapUser;
224 }
225 
226 void
228 {
229  NS_LOG_FUNCTION (this << s);
230  m_cmacSapProvider = s;
231 }
232 
235 {
236  NS_LOG_FUNCTION (this);
237  return m_cmacSapUser;
238 }
239 
240 void
242 {
243  NS_LOG_FUNCTION (this << s);
244  m_rrcSapUser = s;
245 }
246 
249 {
250  NS_LOG_FUNCTION (this);
251  return m_rrcSapProvider;
252 }
253 
254 void
256 {
257  NS_LOG_FUNCTION (this << s);
258  m_macSapProvider = s;
259 }
260 
261 void
263 {
264  m_asSapUser = s;
265 }
266 
269 {
270  return m_asSapProvider;
271 }
272 
273 void
274 LteUeRrc::SetImsi (uint64_t imsi)
275 {
276  NS_LOG_FUNCTION (this << imsi);
277  m_imsi = imsi;
278 }
279 
280 uint64_t
282 {
283  return m_imsi;
284 }
285 
286 uint16_t
288 {
289  NS_LOG_FUNCTION (this);
290  return m_rnti;
291 }
292 
293 uint16_t
295 {
296  NS_LOG_FUNCTION (this);
297  return m_cellId;
298 }
299 
300 
301 uint8_t
303 {
304  NS_LOG_FUNCTION (this);
305  return m_ulBandwidth;
306 }
307 
308 uint8_t
310 {
311  NS_LOG_FUNCTION (this);
312  return m_dlBandwidth;
313 }
314 
315 uint16_t
317 {
318  return m_dlEarfcn;
319 }
320 
321 uint16_t
323 {
324  NS_LOG_FUNCTION (this);
325  return m_ulEarfcn;
326 }
327 
328 
331 {
332  NS_LOG_FUNCTION (this);
333  return m_state;
334 }
335 
336 void
338 {
339  NS_LOG_FUNCTION (this);
340  m_useRlcSm = val;
341 }
342 
343 
344 void
346 {
347  NS_LOG_FUNCTION (this);
348 
349  // setup the UE side of SRB0
350  uint8_t lcid = 0;
351 
352  Ptr<LteRlc> rlc = CreateObject<LteRlcTm> ()->GetObject<LteRlc> ();
353  rlc->SetLteMacSapProvider (m_macSapProvider);
354  rlc->SetRnti (m_rnti);
355  rlc->SetLcId (lcid);
356 
357  m_srb0 = CreateObject<LteSignalingRadioBearerInfo> ();
358  m_srb0->m_rlc = rlc;
359  m_srb0->m_srbIdentity = 0;
361  ueParams.srb0SapProvider = m_srb0->m_rlc->GetLteRlcSapProvider ();
362  ueParams.srb1SapProvider = 0;
363  m_rrcSapUser->Setup (ueParams);
364 
365  // CCCH (LCID 0) is pre-configured, here is the hardcoded configuration:
367  lcConfig.priority = 0; // highest priority
368  lcConfig.prioritizedBitRateKbps = 65535; // maximum
369  lcConfig.bucketSizeDurationMs = 65535; // maximum
370  lcConfig.logicalChannelGroup = 0; // all SRBs mapped to LCG 0
371 
372  m_cmacSapProvider->AddLc (lcid, lcConfig, rlc->GetLteMacSapUser ());
373 
374 }
375 
376 
377 void
378 LteUeRrc::DoSendData (Ptr<Packet> packet, uint8_t bid)
379 {
380  NS_LOG_FUNCTION (this << packet);
381 
382 
383  uint8_t drbid = Bid2Drbid (bid);
384 
385  std::map<uint8_t, Ptr<LteDataRadioBearerInfo> >::iterator it = m_drbMap.find (drbid);
386  NS_ASSERT_MSG (it != m_drbMap.end (), "could not find bearer with drbid == " << drbid);
387 
389  params.pdcpSdu = packet;
390  params.rnti = m_rnti;
391  params.lcid = it->second->m_logicalChannelIdentity;
392 
393  NS_LOG_LOGIC (this << " RNTI=" << m_rnti << " sending " << packet << "on DRBID " << (uint32_t) drbid << " (LCID" << params.lcid << ")" << " (" << packet->GetSize () << " bytes)");
394  it->second->m_pdcp->GetLtePdcpSapProvider ()->TransmitPdcpSdu (params);
395 }
396 
397 void
398 LteUeRrc::DoDisconnect ()
399 {
400  NS_LOG_FUNCTION (this);
401 
402  switch (m_state)
403  {
404  case IDLE_CELL_SELECTION:
405  case IDLE_CAMPED_NORMALLY:
406  NS_LOG_INFO ("already disconnected");
407  break;
408 
409  case IDLE_CONNECTING:
410  NS_LOG_INFO ("aborting connection setup procedure");
411  SwitchToState (IDLE_CAMPED_NORMALLY);
412  break;
413 
414  case CONNECTED_NORMALLY:
415  case CONNECTED_REESTABLISHING:
416  case CONNECTED_HANDOVER:
417  LeaveConnectedMode ();
418  break;
419 
420  default:
421  NS_FATAL_ERROR ("method unexpected in state " << ToString (m_state));
422  break;
423  }
424 }
425 
426 void
427 LteUeRrc::DoReceivePdcpSdu (LtePdcpSapUser::ReceivePdcpSduParameters params)
428 {
429  NS_LOG_FUNCTION (this);
430  m_asSapUser->RecvData (params.pdcpSdu);
431 }
432 
433 
434 void
435 LteUeRrc::DoSetTemporaryCellRnti (uint16_t rnti)
436 {
437  NS_LOG_FUNCTION (this << rnti);
438  m_rnti = rnti;
439  m_srb0->m_rlc->SetRnti (m_rnti);
440  m_cphySapProvider->SetRnti (m_rnti);
441 }
442 
443 void
444 LteUeRrc::DoNotifyRandomAccessSuccessful ()
445 {
446  NS_LOG_FUNCTION (this << m_imsi << ToString (m_state));
447  m_randomAccessSuccessfulTrace (m_imsi, m_cellId, m_rnti);
448  switch (m_state)
449  {
450  case IDLE_RANDOM_ACCESS:
451  {
452  // we just received a RAR with a T-C-RNTI and an UL grant
453  // send RRC connection request as message 3 of the random access procedure
454  SwitchToState (IDLE_CONNECTING);
455  LteRrcSap::RrcConnectionRequest msg;
456  msg.ueIdentity = m_imsi;
457  m_rrcSapUser->SendRrcConnectionRequest (msg);
458  }
459  break;
460 
461  case CONNECTED_HANDOVER:
462  {
463  LteRrcSap::RrcConnectionReconfigurationCompleted msg;
464  msg.rrcTransactionIdentifier = m_lastRrcTransactionIdentifier;
465  m_rrcSapUser->SendRrcConnectionReconfigurationCompleted (msg);
466  SwitchToState (CONNECTED_NORMALLY);
467  m_handoverEndOkTrace (m_imsi, m_cellId, m_rnti);
468  }
469  break;
470 
471  default:
472  NS_FATAL_ERROR ("unexpected event in state " << ToString (m_state));
473  break;
474  }
475 }
476 
477 void
478 LteUeRrc::DoNotifyRandomAccessFailed ()
479 {
480  NS_LOG_FUNCTION (this);
481 }
482 
483 
484 void
485 LteUeRrc::DoForceCampedOnEnb (uint16_t cellId, uint16_t earfcn)
486 {
487  NS_LOG_FUNCTION (this << cellId << earfcn);
488 
489  m_cellId = cellId;
490  m_dlEarfcn = earfcn;
491  m_cphySapProvider->SyncronizeWithEnb (m_cellId, m_dlEarfcn);
492  SwitchToState (IDLE_WAIT_SYSTEM_INFO);
493 }
494 
495 void
496 LteUeRrc::DoConnect ()
497 {
498  NS_LOG_FUNCTION (this);
499  switch (m_state)
500  {
501  case IDLE_CELL_SELECTION:
502  case IDLE_WAIT_SYSTEM_INFO:
503  m_connectionPending = true;
504  break;
505 
506  case IDLE_CAMPED_NORMALLY:
507  StartConnection ();
508  break;
509 
510  case IDLE_RANDOM_ACCESS:
511  case IDLE_CONNECTING:
512  NS_LOG_WARN ("already connecting (state " << ToString (m_state) << ")");
513  break;
514 
515  case CONNECTED_NORMALLY:
516  case CONNECTED_REESTABLISHING:
517  case CONNECTED_HANDOVER:
518  NS_LOG_WARN ("already connected (state " << ToString (m_state) << ")");
519  break;
520 
521  default:
522  NS_FATAL_ERROR ("cannot connect while in state " << ToString (m_state));
523  break;
524  }
525 
526 
527 }
528 
529 
530 
531 // CPHY SAP methods
532 
533 void
534 LteUeRrc::DoRecvMasterInformationBlock (LteRrcSap::MasterInformationBlock msg)
535 {
536  NS_LOG_FUNCTION (this);
537  m_dlBandwidth = msg.dlBandwidth;
538  m_cphySapProvider->SetDlBandwidth (msg.dlBandwidth);
539  m_receivedMib = true;
540  if (m_state == IDLE_WAIT_SYSTEM_INFO && m_receivedMib && m_receivedSib2)
541  {
542  SwitchToState (IDLE_CAMPED_NORMALLY);
543  }
544 }
545 
546 
547 
548 // RRC SAP methods
549 
550 void
551 LteUeRrc::DoCompleteSetup (LteUeRrcSapProvider::CompleteSetupParameters params)
552 {
553  NS_LOG_FUNCTION (this);
554  m_srb0->m_rlc->SetLteRlcSapUser (params.srb0SapUser);
555  if (m_srb1)
556  {
557  m_srb1->m_pdcp->SetLtePdcpSapUser (params.srb1SapUser);
558  }
559 }
560 
561 
562 void
563 LteUeRrc::DoRecvSystemInformationBlockType1 (LteRrcSap::SystemInformationBlockType1 msg)
564 {
565  NS_LOG_FUNCTION (this);
566  // to be implemented
567 }
568 
569 
570 void
571 LteUeRrc::DoRecvSystemInformation (LteRrcSap::SystemInformation msg)
572 {
573  NS_LOG_FUNCTION (this);
574  if (msg.haveSib2)
575  {
576  m_receivedSib2 = true;
577  m_ulBandwidth = msg.sib2.freqInfo.ulBandwidth;
578  m_ulEarfcn = msg.sib2.freqInfo.ulCarrierFreq;
579  LteUeCmacSapProvider::RachConfig rc;
580  rc.numberOfRaPreambles = msg.sib2.radioResourceConfigCommon.rachConfigCommon.preambleInfo.numberOfRaPreambles;
581  rc.preambleTransMax = msg.sib2.radioResourceConfigCommon.rachConfigCommon.raSupervisionInfo.preambleTransMax;
582  rc.raResponseWindowSize = msg.sib2.radioResourceConfigCommon.rachConfigCommon.raSupervisionInfo.raResponseWindowSize;
583  m_cmacSapProvider->ConfigureRach (rc);
584  m_cphySapProvider->ConfigureUplink (m_ulEarfcn, m_ulBandwidth);
585  }
586  if (m_state == IDLE_WAIT_SYSTEM_INFO && m_receivedMib && m_receivedSib2)
587  {
588  SwitchToState (IDLE_CAMPED_NORMALLY);
589  }
590 }
591 
592 
593 void
594 LteUeRrc::DoRecvRrcConnectionSetup (LteRrcSap::RrcConnectionSetup msg)
595 {
596  NS_LOG_FUNCTION (this);
597  switch (m_state)
598  {
599  case IDLE_CONNECTING:
600  {
601  ApplyRadioResourceConfigDedicated (msg.radioResourceConfigDedicated);
602  SwitchToState (CONNECTED_NORMALLY);
603  LteRrcSap::RrcConnectionSetupCompleted msg2;
604  msg2.rrcTransactionIdentifier = msg.rrcTransactionIdentifier;
605  m_rrcSapUser->SendRrcConnectionSetupCompleted (msg2);
606  m_asSapUser->NotifyConnectionSuccessful ();
607  m_connectionEstablishedTrace (m_imsi, m_cellId, m_rnti);
608  }
609  break;
610 
611  default:
612  NS_FATAL_ERROR ("method unexpected in state " << ToString (m_state));
613  break;
614  }
615 }
616 
617 void
618 LteUeRrc::DoRecvRrcConnectionReconfiguration (LteRrcSap::RrcConnectionReconfiguration msg)
619 {
620  NS_LOG_FUNCTION (this << " RNTI " << m_rnti);
621  switch (m_state)
622  {
623  case CONNECTED_NORMALLY:
624  if (msg.haveMobilityControlInfo)
625  {
626  NS_LOG_INFO ("haveMobilityControlInfo == true");
627  SwitchToState (CONNECTED_HANDOVER);
628  const LteRrcSap::MobilityControlInfo& mci = msg.mobilityControlInfo;
629  m_handoverStartTrace (m_imsi, m_cellId, m_rnti, mci.targetPhysCellId);
630  m_cmacSapProvider->Reset ();
631  m_cphySapProvider->Reset ();
632  m_cellId = mci.targetPhysCellId;
633  NS_ASSERT (mci.haveCarrierFreq);
634  NS_ASSERT (mci.haveCarrierBandwidth);
635  m_cphySapProvider->SyncronizeWithEnb (m_cellId, mci.carrierFreq.dlCarrierFreq);
636  m_cphySapProvider->SetDlBandwidth ( mci.carrierBandwidth.dlBandwidth);
637  m_cphySapProvider->ConfigureUplink (mci.carrierFreq.ulCarrierFreq, mci.carrierBandwidth.ulBandwidth);
638  m_rnti = msg.mobilityControlInfo.newUeIdentity;
639  m_srb0->m_rlc->SetRnti (m_rnti);
640  NS_ASSERT_MSG (mci.haveRachConfigDedicated, "handover is only supported with non-contention-based random access procedure");
641  m_cmacSapProvider->StartNonContentionBasedRandomAccessProcedure (m_rnti, mci.rachConfigDedicated.raPreambleIndex, mci.rachConfigDedicated.raPrachMaskIndex);
642  m_cphySapProvider->SetRnti (m_rnti);
643  m_lastRrcTransactionIdentifier = msg.rrcTransactionIdentifier;
644  NS_ASSERT (msg.haveRadioResourceConfigDedicated);
645 
646  // we re-establish SRB1 by creating a new entity
647  // note that we can't dispose the old entity now, because
648  // it's in the current stack, so we would corrupt the stack
649  // if we did so. Hence we schedule it for later disposal
650  m_srb1Old = m_srb1;
651  Simulator::ScheduleNow (&LteUeRrc::DisposeOldSrb1, this);
652  m_srb1 = 0; // new instance will be be created within ApplyRadioResourceConfigDedicated
653 
654  m_drbMap.clear (); // dispose all DRBs
655  ApplyRadioResourceConfigDedicated (msg.radioResourceConfigDedicated);
656  // RRC connection reconfiguration completed will be sent
657  // after handover is complete
658  }
659  else
660  {
661  NS_LOG_INFO ("haveMobilityControlInfo == false");
662  if (msg.haveRadioResourceConfigDedicated)
663  {
664  ApplyRadioResourceConfigDedicated (msg.radioResourceConfigDedicated);
665  }
666  LteRrcSap::RrcConnectionReconfigurationCompleted msg2;
667  msg2.rrcTransactionIdentifier = msg.rrcTransactionIdentifier;
668  m_rrcSapUser->SendRrcConnectionReconfigurationCompleted (msg2);
669  m_connectionReconfigurationTrace (m_imsi, m_cellId, m_rnti);
670  }
671  break;
672 
673  default:
674  NS_FATAL_ERROR ("method unexpected in state " << ToString (m_state));
675  break;
676  }
677 }
678 
679 void
680 LteUeRrc::DoRecvRrcConnectionReestablishment (LteRrcSap::RrcConnectionReestablishment msg)
681 {
682  switch (m_state)
683  {
684  case CONNECTED_REESTABLISHING:
685  {
686  }
687  break;
688 
689  default:
690  NS_FATAL_ERROR ("method unexpected in state " << ToString (m_state));
691  break;
692  }
693 }
694 
695 void
696 LteUeRrc::DoRecvRrcConnectionReestablishmentReject (LteRrcSap::RrcConnectionReestablishmentReject msg)
697 {
698  NS_LOG_FUNCTION (this);
699  switch (m_state)
700  {
701  case CONNECTED_REESTABLISHING:
702  {
703  LeaveConnectedMode ();
704  }
705  break;
706 
707  default:
708  NS_FATAL_ERROR ("method unexpected in state " << ToString (m_state));
709  break;
710  }
711 }
712 
713 void
714 LteUeRrc::DoRecvRrcConnectionRelease (LteRrcSap::RrcConnectionRelease msg)
715 {
716  NS_LOG_FUNCTION (this);
717 }
718 
719 void
720 LteUeRrc::DoRecvRrcConnectionReject (LteRrcSap::RrcConnectionReject msg)
721 {
722  NS_LOG_FUNCTION (this);
723  m_cmacSapProvider->Reset ();
724  SwitchToState (IDLE_CAMPED_NORMALLY);
725 }
726 
727 
728 
729 void
730 LteUeRrc::ApplyRadioResourceConfigDedicated (LteRrcSap::RadioResourceConfigDedicated rrcd)
731 {
732  NS_LOG_FUNCTION (this);
733  const struct LteRrcSap::PhysicalConfigDedicated& pcd = rrcd.physicalConfigDedicated;
734 
735  if (pcd.haveAntennaInfoDedicated)
736  {
737  m_cphySapProvider->SetTransmissionMode (pcd.antennaInfo.transmissionMode);
738  }
739  if (pcd.haveSoundingRsUlConfigDedicated)
740  {
741  m_cphySapProvider->SetSrsConfigurationIndex (pcd.soundingRsUlConfigDedicated.srsConfigIndex);
742  }
743 
744  std::list<LteRrcSap::SrbToAddMod>::const_iterator stamIt = rrcd.srbToAddModList.begin ();
745  if (stamIt != rrcd.srbToAddModList.end ())
746  {
747  if (m_srb1 == 0)
748  {
749  // SRB1 not setup yet
750  NS_ASSERT_MSG ((m_state == IDLE_CONNECTING) || (m_state == CONNECTED_HANDOVER),
751  "unexpected state " << ToString (m_state));
752  NS_ASSERT_MSG (stamIt->srbIdentity == 1, "only SRB1 supported");
753 
754  const uint8_t lcid = 1; // fixed LCID for SRB1
755 
756  Ptr<LteRlc> rlc = CreateObject<LteRlcAm> ();
757  rlc->SetLteMacSapProvider (m_macSapProvider);
758  rlc->SetRnti (m_rnti);
759  rlc->SetLcId (lcid);
760 
761  Ptr<LtePdcp> pdcp = CreateObject<LtePdcp> ();
762  pdcp->SetRnti (m_rnti);
763  pdcp->SetLcId (lcid);
764  pdcp->SetLtePdcpSapUser (m_drbPdcpSapUser);
765  pdcp->SetLteRlcSapProvider (rlc->GetLteRlcSapProvider ());
766  rlc->SetLteRlcSapUser (pdcp->GetLteRlcSapUser ());
767 
768  m_srb1 = CreateObject<LteSignalingRadioBearerInfo> ();
769  m_srb1->m_rlc = rlc;
770  m_srb1->m_pdcp = pdcp;
771  m_srb1->m_srbIdentity = 1;
772 
773  m_srb1->m_logicalChannelConfig.priority = stamIt->logicalChannelConfig.priority;
774  m_srb1->m_logicalChannelConfig.prioritizedBitRateKbps = stamIt->logicalChannelConfig.prioritizedBitRateKbps;
775  m_srb1->m_logicalChannelConfig.bucketSizeDurationMs = stamIt->logicalChannelConfig.bucketSizeDurationMs;
776  m_srb1->m_logicalChannelConfig.logicalChannelGroup = stamIt->logicalChannelConfig.logicalChannelGroup;
777 
778  struct LteUeCmacSapProvider::LogicalChannelConfig lcConfig;
779  lcConfig.priority = stamIt->logicalChannelConfig.priority;
780  lcConfig.prioritizedBitRateKbps = stamIt->logicalChannelConfig.prioritizedBitRateKbps;
781  lcConfig.bucketSizeDurationMs = stamIt->logicalChannelConfig.bucketSizeDurationMs;
782  lcConfig.logicalChannelGroup = stamIt->logicalChannelConfig.logicalChannelGroup;
783 
784  m_cmacSapProvider->AddLc (lcid, lcConfig, rlc->GetLteMacSapUser ());
785 
786  ++stamIt;
787  NS_ASSERT_MSG (stamIt == rrcd.srbToAddModList.end (), "at most one SrbToAdd supported");
788 
789  LteUeRrcSapUser::SetupParameters ueParams;
790  ueParams.srb0SapProvider = m_srb0->m_rlc->GetLteRlcSapProvider ();
791  ueParams.srb1SapProvider = m_srb1->m_pdcp->GetLtePdcpSapProvider ();
792  m_rrcSapUser->Setup (ueParams);
793  }
794  else
795  {
796  NS_LOG_INFO ("request to modify SRB1 (skipping as currently not implemented)");
797  // would need to modify m_srb1, and then propagate changes to the MAC
798  }
799  }
800 
801 
802  std::list<LteRrcSap::DrbToAddMod>::const_iterator dtamIt;
803  for (dtamIt = rrcd.drbToAddModList.begin ();
804  dtamIt != rrcd.drbToAddModList.end ();
805  ++dtamIt)
806  {
807  NS_LOG_INFO (this << " IMSI " << m_imsi << " adding/modifying DRBID " << (uint32_t) dtamIt->drbIdentity << " LC " << (uint32_t) dtamIt->logicalChannelIdentity);
808  NS_ASSERT_MSG (dtamIt->logicalChannelIdentity > 2, "LCID value " << dtamIt->logicalChannelIdentity << " is reserved for SRBs");
809 
810  std::map<uint8_t, Ptr<LteDataRadioBearerInfo> >::iterator drbMapIt = m_drbMap.find (dtamIt->drbIdentity);
811  if (drbMapIt == m_drbMap.end ())
812  {
813  NS_LOG_INFO ("New Data Radio Bearer");
814 
815  TypeId rlcTypeId;
816  if (m_useRlcSm)
817  {
818  rlcTypeId = LteRlcSm::GetTypeId ();
819  }
820  else
821  {
822  switch (dtamIt->rlcConfig.choice)
823  {
824  case LteRrcSap::RlcConfig::AM:
825  rlcTypeId = LteRlcAm::GetTypeId ();
826  break;
827 
828  case LteRrcSap::RlcConfig::UM_BI_DIRECTIONAL:
829  rlcTypeId = LteRlcUm::GetTypeId ();
830  break;
831 
832  default:
833  NS_FATAL_ERROR ("unsupported RLC configuration");
834  break;
835  }
836  }
837 
838  ObjectFactory rlcObjectFactory;
839  rlcObjectFactory.SetTypeId (rlcTypeId);
840  Ptr<LteRlc> rlc = rlcObjectFactory.Create ()->GetObject<LteRlc> ();
841  rlc->SetLteMacSapProvider (m_macSapProvider);
842  rlc->SetRnti (m_rnti);
843  rlc->SetLcId (dtamIt->logicalChannelIdentity);
844 
845  Ptr<LteDataRadioBearerInfo> drbInfo = CreateObject<LteDataRadioBearerInfo> ();
846  drbInfo->m_rlc = rlc;
847  drbInfo->m_epsBearerIdentity = dtamIt->epsBearerIdentity;
848  drbInfo->m_logicalChannelIdentity = dtamIt->logicalChannelIdentity;
849  drbInfo->m_drbIdentity = dtamIt->drbIdentity;
850 
851  // we need PDCP only for real RLC, i.e., RLC/UM or RLC/AM
852  // if we are using RLC/SM we don't care of anything above RLC
853  if (rlcTypeId != LteRlcSm::GetTypeId ())
854  {
855  Ptr<LtePdcp> pdcp = CreateObject<LtePdcp> ();
856  pdcp->SetRnti (m_rnti);
857  pdcp->SetLcId (dtamIt->logicalChannelIdentity);
858  pdcp->SetLtePdcpSapUser (m_drbPdcpSapUser);
859  pdcp->SetLteRlcSapProvider (rlc->GetLteRlcSapProvider ());
860  rlc->SetLteRlcSapUser (pdcp->GetLteRlcSapUser ());
861  drbInfo->m_pdcp = pdcp;
862  }
863 
864  m_bid2DrbidMap[dtamIt->epsBearerIdentity] = dtamIt->drbIdentity;
865 
866  m_drbMap.insert (std::pair<uint8_t, Ptr<LteDataRadioBearerInfo> > (dtamIt->drbIdentity, drbInfo));
867 
868 
869  struct LteUeCmacSapProvider::LogicalChannelConfig lcConfig;
870  lcConfig.priority = dtamIt->logicalChannelConfig.priority;
871  lcConfig.prioritizedBitRateKbps = dtamIt->logicalChannelConfig.prioritizedBitRateKbps;
872  lcConfig.bucketSizeDurationMs = dtamIt->logicalChannelConfig.bucketSizeDurationMs;
873  lcConfig.logicalChannelGroup = dtamIt->logicalChannelConfig.logicalChannelGroup;
874 
875  m_cmacSapProvider->AddLc (dtamIt->logicalChannelIdentity,
876  lcConfig,
877  rlc->GetLteMacSapUser ());
878  rlc->Initialize ();
879  }
880  else
881  {
882  NS_LOG_INFO ("request to modify existing DRBID");
883  Ptr<LteDataRadioBearerInfo> drbInfo = drbMapIt->second;
884  // TODO: currently not implemented. Would need to modify drbInfo, and then propagate changes to the MAC
885  }
886  }
887 
888  std::list<uint8_t>::iterator dtdmIt;
889  for (dtdmIt = rrcd.drbToReleaseList.begin ();
890  dtdmIt != rrcd.drbToReleaseList.end ();
891  ++dtdmIt)
892  {
893  uint8_t drbid = *dtdmIt;
894  NS_LOG_INFO (this << " IMSI " << m_imsi << " releasing DRB " << (uint32_t) drbid << drbid);
895  std::map<uint8_t, Ptr<LteDataRadioBearerInfo> >::iterator it = m_drbMap.find (drbid);
896  NS_ASSERT_MSG (it != m_drbMap.end (), "could not find bearer with given lcid");
897  m_drbMap.erase (it);
898  m_bid2DrbidMap.erase (drbid);
899  }
900 }
901 
902 
903 void
904 LteUeRrc::StartConnection ()
905 {
906  NS_LOG_FUNCTION (this);
907  m_connectionPending = false;
908  SwitchToState (IDLE_RANDOM_ACCESS);
909  m_cmacSapProvider->StartContentionBasedRandomAccessProcedure ();
910 }
911 
912 void
913 LteUeRrc::LeaveConnectedMode ()
914 {
915  NS_LOG_FUNCTION (this << m_imsi);
916  m_asSapUser->NotifyConnectionReleased ();
917  m_cmacSapProvider->RemoveLc (1);
918  std::map<uint8_t, Ptr<LteDataRadioBearerInfo> >::iterator it;
919  for (it = m_drbMap.begin (); it != m_drbMap.end (); ++it)
920  {
921  m_cmacSapProvider->RemoveLc (it->second->m_logicalChannelIdentity);
922  }
923  m_drbMap.clear ();
924  m_bid2DrbidMap.clear ();
925  m_srb1 = 0;
926  SwitchToState (IDLE_CAMPED_NORMALLY);
927 }
928 
929 void
930 LteUeRrc::DisposeOldSrb1 ()
931 {
932  NS_LOG_FUNCTION (this);
933  m_srb1Old = 0;
934 }
935 
936 uint8_t
937 LteUeRrc::Bid2Drbid (uint8_t bid)
938 {
939  std::map<uint8_t, uint8_t>::iterator it = m_bid2DrbidMap.find (bid);
940  NS_ASSERT_MSG (it != m_bid2DrbidMap.end (), "could not find BID " << bid);
941  return it->second;
942 }
943 
944 
945 void
946 LteUeRrc::SwitchToState (State newState)
947 {
948  NS_LOG_FUNCTION (this << newState);
949  State oldState = m_state;
950  m_state = newState;
951  NS_LOG_INFO ("IMSI " << m_imsi << " RNTI " << m_rnti << " UeRrc " << ToString (oldState) << " --> " << ToString (newState));
952  m_stateTransitionTrace (m_imsi, m_cellId, m_rnti, oldState, newState);
953 
954  switch (newState)
955  {
956  case IDLE_CELL_SELECTION:
957  break;
958 
959  case IDLE_WAIT_SYSTEM_INFO:
960  break;
961 
962  case IDLE_CAMPED_NORMALLY:
964  {
965  StartConnection ();
966  }
967  break;
968 
969  case IDLE_RANDOM_ACCESS:
970  break;
971 
972  case IDLE_CONNECTING:
973  break;
974 
975  case CONNECTED_NORMALLY:
976  break;
977 
978  case CONNECTED_REESTABLISHING:
979  break;
980 
981  case CONNECTED_HANDOVER:
982  break;
983 
984  default:
985  break;
986  }
987 }
988 
989 
990 
991 
992 } // namespace ns3
993 
virtual void Reset()=0
smart pointer class similar to boost::intrusive_ptr
Definition: ptr.h:59
#define NS_LOG_FUNCTION(parameters)
Definition: log.h:311
void SetAsSapUser(LteAsSapUser *s)
Definition: lte-ue-rrc.cc:262
virtual void DoDispose(void)
Definition: lte-ue-rrc.cc:150
void SetUseRlcSm(bool val)
Definition: lte-ue-rrc.cc:337
virtual void Reset()=0
#define NS_ASSERT(condition)
Definition: assert.h:64
#define NS_LOG_COMPONENT_DEFINE(name)
Definition: log.h:122
virtual void StartContentionBasedRandomAccessProcedure()=0
uint32_t GetSize(void) const
Definition: packet.h:620
virtual ~LteUeRrc()
Definition: lte-ue-rrc.cc:144
#define NS_LOG_INFO(msg)
Definition: log.h:264
virtual void NotifyRandomAccessSuccessful()
Definition: lte-ue-rrc.cc:77
virtual void SetRnti(uint16_t rnti)=0
virtual void NotifyConnectionSuccessful()=0
uint16_t GetUlEarfcn() const
Definition: lte-ue-rrc.cc:322
virtual void RemoveLc(uint8_t lcId)=0
bool m_connectionPending
Definition: lte-ue-rrc.h:318
uint64_t GetImsi(void)
Definition: lte-ue-rrc.cc:281
#define NS_FATAL_ERROR(msg)
fatal error handling
Definition: fatal-error.h:72
LteUeCmacSapUser * GetLteUeCmacSapUser()
Definition: lte-ue-rrc.cc:234
void SetLteUeRrcSapUser(LteUeRrcSapUser *s)
Definition: lte-ue-rrc.cc:241
uint16_t m_dlEarfcn
Definition: lte-ue-rrc.h:302
uint8_t m_dlBandwidth
Definition: lte-ue-rrc.h:299
Hold an unsigned integer type.
Definition: uinteger.h:46
virtual void DoInitialize(void)
Definition: lte-ue-rrc.cc:345
uint8_t GetUlBandwidth() const
Definition: lte-ue-rrc.cc:302
void SetLteUeCmacSapProvider(LteUeCmacSapProvider *s)
Definition: lte-ue-rrc.cc:227
#define NS_LOG_LOGIC(msg)
Definition: log.h:334
void SetLteMacSapProvider(LteMacSapProvider *s)
Definition: lte-ue-rrc.cc:255
virtual void SyncronizeWithEnb(uint16_t cellId, uint16_t dlEarfcn)=0
void SetLteUeCphySapProvider(LteUeCphySapProvider *s)
Definition: lte-ue-rrc.cc:213
virtual void SetSrsConfigurationIndex(uint16_t srcCi)=0
hold objects of type Ptr<T>
Definition: pointer.h:33
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
uint8_t GetDlBandwidth() const
Definition: lte-ue-rrc.cc:309
uint16_t GetDlEarfcn() const
Definition: lte-ue-rrc.cc:316
static EventId ScheduleNow(MEM mem_ptr, OBJ obj)
Definition: simulator.h:981
uint16_t m_ulEarfcn
Definition: lte-ue-rrc.h:303
virtual void AddLc(uint8_t lcId, LogicalChannelConfig lcConfig, LteMacSapUser *msu)=0
uint8_t m_ulBandwidth
Definition: lte-ue-rrc.h:300
#define NS_ASSERT_MSG(condition, message)
Definition: assert.h:86
LteUeCphySapUser * GetLteUeCphySapUser()
Definition: lte-ue-rrc.cc:220
virtual void StartNonContentionBasedRandomAccessProcedure(uint16_t rnti, uint8_t rapId, uint8_t prachMask)=0
virtual void SetDlBandwidth(uint8_t dlBandwidth)=0
uint16_t GetRnti() const
Definition: lte-ue-rrc.cc:287
virtual void SetTransmissionMode(uint8_t txMode)=0
#define NS_LOG_WARN(msg)
Definition: log.h:246
uint16_t GetCellId() const
Definition: lte-ue-rrc.cc:294
virtual void NotifyConnectionReleased()=0
LteAsSapProvider * GetAsSapProvider()
Definition: lte-ue-rrc.cc:268
bool m_receivedSib2
Definition: lte-ue-rrc.h:320
a base class which provides memory management and object aggregation
Definition: object.h:63
contain a set of ns3::Object pointers.
virtual void RecvData(Ptr< Packet > packet)=0
LteUeRrcSapProvider * GetLteUeRrcSapProvider()
Definition: lte-ue-rrc.cc:248
virtual void SetTemporaryCellRnti(uint16_t rnti)
Definition: lte-ue-rrc.cc:70
a unique identifier for an interface.
Definition: type-id.h:44
virtual void ConfigureUplink(uint16_t ulEarfcn, uint8_t ulBandwidth)=0
TypeId SetParent(TypeId tid)
Definition: type-id.cc:471
void SetImsi(uint64_t imsi)
Definition: lte-ue-rrc.cc:274
virtual void NotifyRandomAccessFailed()
Definition: lte-ue-rrc.cc:83
bool m_receivedMib
Definition: lte-ue-rrc.h:319
State GetState()
Definition: lte-ue-rrc.cc:330