A Discrete-Event Network Simulator
API
lte-ue-rrc.cc
Go to the documentation of this file.
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  * Budiarto Herman <budiarto.herman@magister.fi>
20  */
21 
22 #include "lte-ue-rrc.h"
23 
24 #include <ns3/fatal-error.h>
25 #include <ns3/log.h>
26 #include <ns3/object-map.h>
27 #include <ns3/object-factory.h>
28 #include <ns3/simulator.h>
29 
30 #include <ns3/lte-rlc.h>
31 #include <ns3/lte-rlc-tm.h>
32 #include <ns3/lte-rlc-um.h>
33 #include <ns3/lte-rlc-am.h>
34 #include <ns3/lte-pdcp.h>
35 #include <ns3/lte-radio-bearer-info.h>
36 
37 #include <cmath>
38 
39 namespace ns3 {
40 
41 NS_LOG_COMPONENT_DEFINE ("LteUeRrc");
42 
44 // CMAC SAP forwarder
46 
48 {
49 public:
51 
52  virtual void SetTemporaryCellRnti (uint16_t rnti);
53  virtual void NotifyRandomAccessSuccessful ();
54  virtual void NotifyRandomAccessFailed ();
55 
56 private:
58 };
59 
61  : m_rrc (rrc)
62 {
63 }
64 
65 void
67 {
69 }
70 
71 
72 void
74 {
76 }
77 
78 void
80 {
82 }
83 
84 
85 
86 
87 
88 
90 static const std::string g_ueRrcStateName[LteUeRrc::NUM_STATES] =
91 {
92  "IDLE_START",
93  "IDLE_CELL_SEARCH",
94  "IDLE_WAIT_MIB_SIB1",
95  "IDLE_WAIT_MIB",
96  "IDLE_WAIT_SIB1",
97  "IDLE_CAMPED_NORMALLY",
98  "IDLE_WAIT_SIB2",
99  "IDLE_RANDOM_ACCESS",
100  "IDLE_CONNECTING",
101  "CONNECTED_NORMALLY",
102  "CONNECTED_HANDOVER",
103  "CONNECTED_PHY_PROBLEM",
104  "CONNECTED_REESTABLISHING"
105 };
106 
111 static const std::string & ToString (LteUeRrc::State s)
112 {
113  return g_ueRrcStateName[s];
114 }
115 
116 
118 // ue RRC methods
120 
121 NS_OBJECT_ENSURE_REGISTERED (LteUeRrc);
122 
123 
125  : m_cphySapProvider (0),
126  m_cmacSapProvider (0),
127  m_rrcSapUser (0),
128  m_macSapProvider (0),
129  m_asSapUser (0),
130  m_state (IDLE_START),
131  m_imsi (0),
132  m_rnti (0),
133  m_cellId (0),
134  m_useRlcSm (true),
135  m_connectionPending (false),
136  m_hasReceivedMib (false),
137  m_hasReceivedSib1 (false),
138  m_hasReceivedSib2 (false),
139  m_csgWhiteList (0)
140 {
141  NS_LOG_FUNCTION (this);
147 }
148 
149 
151 {
152  NS_LOG_FUNCTION (this);
153 }
154 
155 void
157 {
158  NS_LOG_FUNCTION (this);
159  delete m_cphySapUser;
160  delete m_cmacSapUser;
161  delete m_rrcSapProvider;
162  delete m_drbPdcpSapUser;
163  delete m_asSapProvider;
164  m_drbMap.clear ();
165 }
166 
167 TypeId
169 {
170  static TypeId tid = TypeId ("ns3::LteUeRrc")
171  .SetParent<Object> ()
172  .AddConstructor<LteUeRrc> ()
173  .AddAttribute ("DataRadioBearerMap", "List of UE RadioBearerInfo for Data Radio Bearers by LCID.",
174  ObjectMapValue (),
176  MakeObjectMapChecker<LteDataRadioBearerInfo> ())
177  .AddAttribute ("Srb0", "SignalingRadioBearerInfo for SRB0",
178  PointerValue (),
180  MakePointerChecker<LteSignalingRadioBearerInfo> ())
181  .AddAttribute ("Srb1", "SignalingRadioBearerInfo for SRB1",
182  PointerValue (),
184  MakePointerChecker<LteSignalingRadioBearerInfo> ())
185  .AddAttribute ("CellId",
186  "Serving cell identifier",
187  UintegerValue (0), // unused, read-only attribute
189  MakeUintegerChecker<uint16_t> ())
190  .AddAttribute ("C-RNTI",
191  "Cell Radio Network Temporary Identifier",
192  UintegerValue (0), // unused, read-only attribute
194  MakeUintegerChecker<uint16_t> ())
195  .AddAttribute ("T300",
196  "Timer for the RRC Connection Establishment procedure "
197  "(i.e., the procedure is deemed as failed if it takes longer than this)",
198  TimeValue (MilliSeconds (100)),
200  MakeTimeChecker ())
201  .AddTraceSource ("MibReceived",
202  "trace fired upon reception of Master Information Block",
204  "ns3::LteUeRrc::MibSibHandoverTracedCallback")
205  .AddTraceSource ("Sib1Received",
206  "trace fired upon reception of System Information Block Type 1",
208  "ns3::LteUeRrc::MibSibHandoverTracedCallback")
209  .AddTraceSource ("Sib2Received",
210  "trace fired upon reception of System Information Block Type 2",
212  "ns3::LteUeRrc::ImsiCidRntiTracedCallback")
213  .AddTraceSource ("StateTransition",
214  "trace fired upon every UE RRC state transition",
216  "ns3::LteUeRrc::StateTracedCallback")
217  .AddTraceSource ("InitialCellSelectionEndOk",
218  "trace fired upon successful initial cell selection procedure",
220  "ns3::LteUeRrc::CellSelectionTracedCallback")
221  .AddTraceSource ("InitialCellSelectionEndError",
222  "trace fired upon failed initial cell selection procedure",
224  "ns3::LteUeRrc::CellSelectionTracedCallback")
225  .AddTraceSource ("RandomAccessSuccessful",
226  "trace fired upon successful completion of the random access procedure",
228  "ns3::LteUeRrc::ImsiCidRntiTracedCallback")
229  .AddTraceSource ("RandomAccessError",
230  "trace fired upon failure of the random access procedure",
232  "ns3::LteUeRrc::ImsiCidRntiTracedCallback")
233  .AddTraceSource ("ConnectionEstablished",
234  "trace fired upon successful RRC connection establishment",
236  "ns3::LteUeRrc::ImsiCidRntiTracedCallback")
237  .AddTraceSource ("ConnectionTimeout",
238  "trace fired upon timeout RRC connection establishment because of T300",
240  "ns3::LteUeRrc::ImsiCidRntiTracedCallback")
241  .AddTraceSource ("ConnectionReconfiguration",
242  "trace fired upon RRC connection reconfiguration",
244  "ns3::LteUeRrc::ImsiCidRntiTracedCallback")
245  .AddTraceSource ("HandoverStart",
246  "trace fired upon start of a handover procedure",
248  "ns3::LteUeRrc::MibSibHandoverTracedCallback")
249  .AddTraceSource ("HandoverEndOk",
250  "trace fired upon successful termination of a handover procedure",
252  "ns3::LteUeRrc::ImsiCidRntiTracedCallback")
253  .AddTraceSource ("HandoverEndError",
254  "trace fired upon failure of a handover procedure",
256  "ns3::LteUeRrc::ImsiCidRntiTracedCallback")
257  ;
258  return tid;
259 }
260 
261 
262 void
264 {
265  NS_LOG_FUNCTION (this << s);
267 }
268 
271 {
272  NS_LOG_FUNCTION (this);
273  return m_cphySapUser;
274 }
275 
276 void
278 {
279  NS_LOG_FUNCTION (this << s);
281 }
282 
285 {
286  NS_LOG_FUNCTION (this);
287  return m_cmacSapUser;
288 }
289 
290 void
292 {
293  NS_LOG_FUNCTION (this << s);
294  m_rrcSapUser = s;
295 }
296 
299 {
300  NS_LOG_FUNCTION (this);
301  return m_rrcSapProvider;
302 }
303 
304 void
306 {
307  NS_LOG_FUNCTION (this << s);
309 }
310 
311 void
313 {
314  m_asSapUser = s;
315 }
316 
319 {
320  return m_asSapProvider;
321 }
322 
323 void
324 LteUeRrc::SetImsi (uint64_t imsi)
325 {
326  NS_LOG_FUNCTION (this << imsi);
327  m_imsi = imsi;
328 }
329 
330 uint64_t
331 LteUeRrc::GetImsi (void) const
332 {
333  return m_imsi;
334 }
335 
336 uint16_t
338 {
339  NS_LOG_FUNCTION (this);
340  return m_rnti;
341 }
342 
343 uint16_t
345 {
346  NS_LOG_FUNCTION (this);
347  return m_cellId;
348 }
349 
350 
351 uint8_t
353 {
354  NS_LOG_FUNCTION (this);
355  return m_ulBandwidth;
356 }
357 
358 uint8_t
360 {
361  NS_LOG_FUNCTION (this);
362  return m_dlBandwidth;
363 }
364 
365 uint16_t
367 {
368  return m_dlEarfcn;
369 }
370 
371 uint16_t
373 {
374  NS_LOG_FUNCTION (this);
375  return m_ulEarfcn;
376 }
377 
379 LteUeRrc::GetState (void) const
380 {
381  NS_LOG_FUNCTION (this);
382  return m_state;
383 }
384 
385 void
387 {
388  NS_LOG_FUNCTION (this);
389  m_useRlcSm = val;
390 }
391 
392 
393 void
395 {
396  NS_LOG_FUNCTION (this);
397 
398  // setup the UE side of SRB0
399  uint8_t lcid = 0;
400 
401  Ptr<LteRlc> rlc = CreateObject<LteRlcTm> ()->GetObject<LteRlc> ();
403  rlc->SetRnti (m_rnti);
404  rlc->SetLcId (lcid);
405 
406  m_srb0 = CreateObject<LteSignalingRadioBearerInfo> ();
407  m_srb0->m_rlc = rlc;
408  m_srb0->m_srbIdentity = 0;
410  ueParams.srb0SapProvider = m_srb0->m_rlc->GetLteRlcSapProvider ();
411  ueParams.srb1SapProvider = 0;
412  m_rrcSapUser->Setup (ueParams);
413 
414  // CCCH (LCID 0) is pre-configured, here is the hardcoded configuration:
416  lcConfig.priority = 0; // highest priority
417  lcConfig.prioritizedBitRateKbps = 65535; // maximum
418  lcConfig.bucketSizeDurationMs = 65535; // maximum
419  lcConfig.logicalChannelGroup = 0; // all SRBs mapped to LCG 0
420 
421  m_cmacSapProvider->AddLc (lcid, lcConfig, rlc->GetLteMacSapUser ());
422 
423 }
424 
425 
426 void
427 LteUeRrc::DoSendData (Ptr<Packet> packet, uint8_t bid)
428 {
429  NS_LOG_FUNCTION (this << packet);
430 
431  uint8_t drbid = Bid2Drbid (bid);
432 
433  if (drbid != 0)
434  {
435  std::map<uint8_t, Ptr<LteDataRadioBearerInfo> >::iterator it = m_drbMap.find (drbid);
436  NS_ASSERT_MSG (it != m_drbMap.end (), "could not find bearer with drbid == " << drbid);
437 
439  params.pdcpSdu = packet;
440  params.rnti = m_rnti;
441  params.lcid = it->second->m_logicalChannelIdentity;
442 
443  NS_LOG_LOGIC (this << " RNTI=" << m_rnti << " sending packet " << packet
444  << " on DRBID " << (uint32_t) drbid
445  << " (LCID " << (uint32_t) params.lcid << ")"
446  << " (" << packet->GetSize () << " bytes)");
447  it->second->m_pdcp->GetLtePdcpSapProvider ()->TransmitPdcpSdu (params);
448  }
449 }
450 
451 
452 void
454 {
455  NS_LOG_FUNCTION (this);
456 
457  switch (m_state)
458  {
459  case IDLE_START:
460  case IDLE_CELL_SEARCH:
461  case IDLE_WAIT_MIB_SIB1:
462  case IDLE_WAIT_MIB:
463  case IDLE_WAIT_SIB1:
465  NS_LOG_INFO ("already disconnected");
466  break;
467 
468  case IDLE_WAIT_SIB2:
469  case IDLE_CONNECTING:
470  NS_FATAL_ERROR ("cannot abort connection setup procedure");
471  break;
472 
473  case CONNECTED_NORMALLY:
474  case CONNECTED_HANDOVER:
478  break;
479 
480  default: // i.e. IDLE_RANDOM_ACCESS
481  NS_FATAL_ERROR ("method unexpected in state " << ToString (m_state));
482  break;
483  }
484 }
485 
486 void
488 {
489  NS_LOG_FUNCTION (this);
490  m_asSapUser->RecvData (params.pdcpSdu);
491 }
492 
493 
494 void
496 {
497  NS_LOG_FUNCTION (this << rnti);
498  m_rnti = rnti;
499  m_srb0->m_rlc->SetRnti (m_rnti);
501 }
502 
503 void
505 {
506  NS_LOG_FUNCTION (this << m_imsi << ToString (m_state));
508 
509  switch (m_state)
510  {
511  case IDLE_RANDOM_ACCESS:
512  {
513  // we just received a RAR with a T-C-RNTI and an UL grant
514  // send RRC connection request as message 3 of the random access procedure
517  msg.ueIdentity = m_imsi;
521  this);
522  }
523  break;
524 
525  case CONNECTED_HANDOVER:
526  {
530 
531  // 3GPP TS 36.331 section 5.5.6.1 Measurements related actions upon handover
532  std::map<uint8_t, LteRrcSap::MeasIdToAddMod>::iterator measIdIt;
533  for (measIdIt = m_varMeasConfig.measIdList.begin ();
534  measIdIt != m_varMeasConfig.measIdList.end ();
535  ++measIdIt)
536  {
537  VarMeasReportListClear (measIdIt->second.measId);
538  }
539 
542  }
543  break;
544 
545  default:
546  NS_FATAL_ERROR ("unexpected event in state " << ToString (m_state));
547  break;
548  }
549 }
550 
551 void
553 {
554  NS_LOG_FUNCTION (this << m_imsi << ToString (m_state));
556 
557  switch (m_state)
558  {
559  case IDLE_RANDOM_ACCESS:
560  {
563  }
564  break;
565 
566  case CONNECTED_HANDOVER:
567  {
574  }
575  break;
576 
577  default:
578  NS_FATAL_ERROR ("unexpected event in state " << ToString (m_state));
579  break;
580  }
581 }
582 
583 
584 void
586 {
587  NS_LOG_FUNCTION (this << m_imsi << csgId);
588  m_csgWhiteList = csgId;
589 }
590 
591 void
593 {
594  NS_LOG_FUNCTION (this << m_imsi << dlEarfcn);
596  "cannot start cell selection from state " << ToString (m_state));
597  m_dlEarfcn = dlEarfcn;
600 }
601 
602 void
603 LteUeRrc::DoForceCampedOnEnb (uint16_t cellId, uint16_t dlEarfcn)
604 {
605  NS_LOG_FUNCTION (this << m_imsi << cellId << dlEarfcn);
606 
607  switch (m_state)
608  {
609  case IDLE_START:
610  m_cellId = cellId;
611  m_dlEarfcn = dlEarfcn;
614  break;
615 
616  case IDLE_CELL_SEARCH:
617  case IDLE_WAIT_MIB_SIB1:
618  case IDLE_WAIT_SIB1:
619  NS_FATAL_ERROR ("cannot abort cell selection " << ToString (m_state));
620  break;
621 
622  case IDLE_WAIT_MIB:
623  NS_LOG_INFO ("already forced to camp to cell " << m_cellId);
624  break;
625 
627  case IDLE_WAIT_SIB2:
628  case IDLE_RANDOM_ACCESS:
629  case IDLE_CONNECTING:
630  NS_LOG_INFO ("already camped to cell " << m_cellId);
631  break;
632 
633  case CONNECTED_NORMALLY:
634  case CONNECTED_HANDOVER:
637  NS_LOG_INFO ("already connected to cell " << m_cellId);
638  break;
639 
640  default:
641  NS_FATAL_ERROR ("unexpected event in state " << ToString (m_state));
642  break;
643  }
644 
645 }
646 
647 void
649 {
650  NS_LOG_FUNCTION (this << m_imsi);
651 
652  switch (m_state)
653  {
654  case IDLE_START:
655  case IDLE_CELL_SEARCH:
656  case IDLE_WAIT_MIB_SIB1:
657  case IDLE_WAIT_SIB1:
658  case IDLE_WAIT_MIB:
659  m_connectionPending = true;
660  break;
661 
663  m_connectionPending = true;
665  break;
666 
667  case IDLE_WAIT_SIB2:
668  case IDLE_RANDOM_ACCESS:
669  case IDLE_CONNECTING:
670  NS_LOG_INFO ("already connecting");
671  break;
672 
673  case CONNECTED_NORMALLY:
675  case CONNECTED_HANDOVER:
676  NS_LOG_INFO ("already connected");
677  break;
678 
679  default:
680  NS_FATAL_ERROR ("unexpected event in state " << ToString (m_state));
681  break;
682  }
683 }
684 
685 
686 
687 // CPHY SAP methods
688 
689 void
692 {
695  m_hasReceivedMib = true;
697 
698  switch (m_state)
699  {
700  case IDLE_WAIT_MIB:
701  // manual attachment
703  break;
704 
705  case IDLE_WAIT_MIB_SIB1:
706  // automatic attachment from Idle mode cell selection
708  break;
709 
710  default:
711  // do nothing extra
712  break;
713  }
714 }
715 
716 void
719 {
720  switch (m_state)
721  {
722  case IDLE_WAIT_SIB1:
724  "Cell identity in SIB1 does not match with the originating cell");
725  m_hasReceivedSib1 = true;
726  m_lastSib1 = msg;
729  break;
730 
732  case IDLE_RANDOM_ACCESS:
733  case IDLE_CONNECTING:
734  case CONNECTED_NORMALLY:
735  case CONNECTED_HANDOVER:
739  "Cell identity in SIB1 does not match with the originating cell");
740  m_hasReceivedSib1 = true;
741  m_lastSib1 = msg;
743  break;
744 
745  case IDLE_WAIT_MIB_SIB1:
746  // MIB has not been received, so ignore this SIB1
747  break;
748 
749  default: // e.g. IDLE_START, IDLE_CELL_SEARCH, IDLE_WAIT_MIB, IDLE_WAIT_SIB2
750  // do nothing
751  break;
752  }
753 }
754 
755 void
757 {
758  NS_LOG_FUNCTION (this);
759 
760  // layer 3 filtering does not apply in IDLE mode
761  bool useLayer3Filtering = (m_state == CONNECTED_NORMALLY);
762 
763  std::vector <LteUeCphySapUser::UeMeasurementsElement>::iterator newMeasIt;
764  for (newMeasIt = params.m_ueMeasurementsList.begin ();
765  newMeasIt != params.m_ueMeasurementsList.end (); ++newMeasIt)
766  {
767  SaveUeMeasurements (newMeasIt->m_cellId, newMeasIt->m_rsrp,
768  newMeasIt->m_rsrq, useLayer3Filtering);
769  }
770 
771  if (m_state == IDLE_CELL_SEARCH)
772  {
773  // start decoding BCH
775  }
776  else
777  {
778  std::map<uint8_t, LteRrcSap::MeasIdToAddMod>::iterator measIdIt;
779  for (measIdIt = m_varMeasConfig.measIdList.begin ();
780  measIdIt != m_varMeasConfig.measIdList.end (); ++measIdIt)
781  {
782  MeasurementReportTriggering (measIdIt->first);
783  }
784  }
785 
786 } // end of LteUeRrc::DoReportUeMeasurements
787 
788 
789 
790 // RRC SAP methods
791 
792 void
794 {
795  NS_LOG_FUNCTION (this << " RNTI " << m_rnti);
796  m_srb0->m_rlc->SetLteRlcSapUser (params.srb0SapUser);
797  if (m_srb1)
798  {
799  m_srb1->m_pdcp->SetLtePdcpSapUser (params.srb1SapUser);
800  }
801 }
802 
803 
804 void
806 {
807  NS_LOG_FUNCTION (this << " RNTI " << m_rnti);
808 
809  if (msg.haveSib2)
810  {
811  switch (m_state)
812  {
814  case IDLE_WAIT_SIB2:
815  case IDLE_RANDOM_ACCESS:
816  case IDLE_CONNECTING:
817  case CONNECTED_NORMALLY:
818  case CONNECTED_HANDOVER:
821  m_hasReceivedSib2 = true;
832  if (m_state == IDLE_WAIT_SIB2)
833  {
835  StartConnection ();
836  }
837  break;
838 
839  default: // IDLE_START, IDLE_CELL_SEARCH, IDLE_WAIT_MIB, IDLE_WAIT_MIB_SIB1, IDLE_WAIT_SIB1
840  // do nothing
841  break;
842  }
843  }
844 
845 }
846 
847 
848 void
850 {
851  NS_LOG_FUNCTION (this << " RNTI " << m_rnti);
852  switch (m_state)
853  {
854  case IDLE_CONNECTING:
855  {
864  }
865  break;
866 
867  default:
868  NS_FATAL_ERROR ("method unexpected in state " << ToString (m_state));
869  break;
870  }
871 }
872 
873 void
875 {
876  NS_LOG_FUNCTION (this << " RNTI " << m_rnti);
877  switch (m_state)
878  {
879  case CONNECTED_NORMALLY:
880  if (msg.haveMobilityControlInfo)
881  {
882  NS_LOG_INFO ("haveMobilityControlInfo == true");
895  m_srb0->m_rlc->SetRnti (m_rnti);
896  NS_ASSERT_MSG (mci.haveRachConfigDedicated, "handover is only supported with non-contention-based random access procedure");
901 
902  // we re-establish SRB1 by creating a new entity
903  // note that we can't dispose the old entity now, because
904  // it's in the current stack, so we would corrupt the stack
905  // if we did so. Hence we schedule it for later disposal
906  m_srb1Old = m_srb1;
908  m_srb1 = 0; // new instance will be be created within ApplyRadioResourceConfigDedicated
909 
910  m_drbMap.clear (); // dispose all DRBs
912 
913  if (msg.haveMeasConfig)
914  {
916  }
917  // RRC connection reconfiguration completed will be sent
918  // after handover is complete
919  }
920  else
921  {
922  NS_LOG_INFO ("haveMobilityControlInfo == false");
924  {
926  }
927  if (msg.haveMeasConfig)
928  {
930  }
935  }
936  break;
937 
938  default:
939  NS_FATAL_ERROR ("method unexpected in state " << ToString (m_state));
940  break;
941  }
942 }
943 
944 void
946 {
947  NS_LOG_FUNCTION (this << " RNTI " << m_rnti);
948  switch (m_state)
949  {
951  {
959  }
960  break;
961 
962  default:
963  NS_FATAL_ERROR ("method unexpected in state " << ToString (m_state));
964  break;
965  }
966 }
967 
968 void
970 {
971  NS_LOG_FUNCTION (this << " RNTI " << m_rnti);
972  switch (m_state)
973  {
975  {
981  }
982  break;
983 
984  default:
985  NS_FATAL_ERROR ("method unexpected in state " << ToString (m_state));
986  break;
987  }
988 }
989 
990 void
992 {
993  NS_LOG_FUNCTION (this << " RNTI " << m_rnti);
995 }
996 
997 void
999 {
1000  NS_LOG_FUNCTION (this);
1002 
1003  m_cmacSapProvider->Reset (); // reset the MAC
1004  m_hasReceivedSib2 = false; // invalidate the previously received SIB2
1006  m_asSapUser->NotifyConnectionFailed (); // inform upper layer
1007 }
1008 
1009 
1010 
1011 void
1013 {
1014  NS_LOG_FUNCTION (this);
1016 
1017  uint16_t maxRsrpCellId = 0;
1018  double maxRsrp = -std::numeric_limits<double>::infinity ();
1019 
1020  std::map<uint16_t, MeasValues>::iterator it;
1021  for (it = m_storedMeasValues.begin (); it != m_storedMeasValues.end (); it++)
1022  {
1023  /*
1024  * This block attempts to find a cell with strongest RSRP and has not
1025  * yet been identified as "acceptable cell".
1026  */
1027  if (maxRsrp < it->second.rsrp)
1028  {
1029  std::set<uint16_t>::const_iterator itCell;
1030  itCell = m_acceptableCell.find (it->first);
1031  if (itCell == m_acceptableCell.end ())
1032  {
1033  maxRsrpCellId = it->first;
1034  maxRsrp = it->second.rsrp;
1035  }
1036  }
1037  }
1038 
1039  if (maxRsrpCellId == 0)
1040  {
1041  NS_LOG_WARN (this << " Cell search is unable to detect surrounding cell to attach to");
1042  }
1043  else
1044  {
1045  NS_LOG_LOGIC (this << " cell " << maxRsrpCellId
1046  << " is the strongest untried surrounding cell");
1049  }
1050 
1051 } // end of void LteUeRrc::SynchronizeToStrongestCell ()
1052 
1053 
1054 void
1056 {
1057  NS_LOG_FUNCTION (this);
1061  uint16_t cellId = m_lastSib1.cellAccessRelatedInfo.cellIdentity;
1062 
1063  // Cell selection criteria evaluation
1064 
1065  bool isSuitableCell = false;
1066  bool isAcceptableCell = false;
1067  std::map<uint16_t, MeasValues>::iterator storedMeasIt = m_storedMeasValues.find (cellId);
1068  double qRxLevMeas = storedMeasIt->second.rsrp;
1070  NS_LOG_LOGIC (this << " cell selection to cellId=" << cellId
1071  << " qrxlevmeas=" << qRxLevMeas << " dBm"
1072  << " qrxlevmin=" << qRxLevMin << " dBm");
1073 
1074  if (qRxLevMeas - qRxLevMin > 0)
1075  {
1076  isAcceptableCell = true;
1077 
1078  uint32_t cellCsgId = m_lastSib1.cellAccessRelatedInfo.csgIdentity;
1079  bool cellCsgIndication = m_lastSib1.cellAccessRelatedInfo.csgIndication;
1080 
1081  isSuitableCell = (cellCsgIndication == false) || (cellCsgId == m_csgWhiteList);
1082 
1083  NS_LOG_LOGIC (this << " csg(ue/cell/indication)=" << m_csgWhiteList << "/"
1084  << cellCsgId << "/" << cellCsgIndication);
1085  }
1086 
1087  // Cell selection decision
1088 
1089  if (isSuitableCell)
1090  {
1091  m_cellId = cellId;
1096  }
1097  else
1098  {
1099  // ignore the MIB and SIB1 received from this cell
1100  m_hasReceivedMib = false;
1101  m_hasReceivedSib1 = false;
1102 
1104 
1105  if (isAcceptableCell)
1106  {
1107  /*
1108  * The cells inserted into this list will not be considered for
1109  * subsequent cell search attempt.
1110  */
1111  m_acceptableCell.insert (cellId);
1112  }
1113 
1115  SynchronizeToStrongestCell (); // retry to a different cell
1116  }
1117 
1118 } // end of void LteUeRrc::EvaluateCellForSelection ()
1119 
1120 
1121 void
1123 {
1124  NS_LOG_FUNCTION (this);
1126 
1127  if (pcd.haveAntennaInfoDedicated)
1128  {
1130  }
1132  {
1134  }
1135 
1136  if (pcd.havePdschConfigDedicated)
1137  {
1138  // update PdschConfigDedicated (i.e. P_A value)
1141  m_cphySapProvider->SetPa (paDouble);
1142  }
1143 
1144  std::list<LteRrcSap::SrbToAddMod>::const_iterator stamIt = rrcd.srbToAddModList.begin ();
1145  if (stamIt != rrcd.srbToAddModList.end ())
1146  {
1147  if (m_srb1 == 0)
1148  {
1149  // SRB1 not setup yet
1151  "unexpected state " << ToString (m_state));
1152  NS_ASSERT_MSG (stamIt->srbIdentity == 1, "only SRB1 supported");
1153 
1154  const uint8_t lcid = 1; // fixed LCID for SRB1
1155 
1156  Ptr<LteRlc> rlc = CreateObject<LteRlcAm> ();
1158  rlc->SetRnti (m_rnti);
1159  rlc->SetLcId (lcid);
1160 
1161  Ptr<LtePdcp> pdcp = CreateObject<LtePdcp> ();
1162  pdcp->SetRnti (m_rnti);
1163  pdcp->SetLcId (lcid);
1164  pdcp->SetLtePdcpSapUser (m_drbPdcpSapUser);
1165  pdcp->SetLteRlcSapProvider (rlc->GetLteRlcSapProvider ());
1166  rlc->SetLteRlcSapUser (pdcp->GetLteRlcSapUser ());
1167 
1168  m_srb1 = CreateObject<LteSignalingRadioBearerInfo> ();
1169  m_srb1->m_rlc = rlc;
1170  m_srb1->m_pdcp = pdcp;
1171  m_srb1->m_srbIdentity = 1;
1172 
1173  m_srb1->m_logicalChannelConfig.priority = stamIt->logicalChannelConfig.priority;
1174  m_srb1->m_logicalChannelConfig.prioritizedBitRateKbps = stamIt->logicalChannelConfig.prioritizedBitRateKbps;
1175  m_srb1->m_logicalChannelConfig.bucketSizeDurationMs = stamIt->logicalChannelConfig.bucketSizeDurationMs;
1176  m_srb1->m_logicalChannelConfig.logicalChannelGroup = stamIt->logicalChannelConfig.logicalChannelGroup;
1177 
1179  lcConfig.priority = stamIt->logicalChannelConfig.priority;
1180  lcConfig.prioritizedBitRateKbps = stamIt->logicalChannelConfig.prioritizedBitRateKbps;
1181  lcConfig.bucketSizeDurationMs = stamIt->logicalChannelConfig.bucketSizeDurationMs;
1182  lcConfig.logicalChannelGroup = stamIt->logicalChannelConfig.logicalChannelGroup;
1183 
1184  m_cmacSapProvider->AddLc (lcid, lcConfig, rlc->GetLteMacSapUser ());
1185 
1186  ++stamIt;
1187  NS_ASSERT_MSG (stamIt == rrcd.srbToAddModList.end (), "at most one SrbToAdd supported");
1188 
1190  ueParams.srb0SapProvider = m_srb0->m_rlc->GetLteRlcSapProvider ();
1191  ueParams.srb1SapProvider = m_srb1->m_pdcp->GetLtePdcpSapProvider ();
1192  m_rrcSapUser->Setup (ueParams);
1193  }
1194  else
1195  {
1196  NS_LOG_INFO ("request to modify SRB1 (skipping as currently not implemented)");
1197  // would need to modify m_srb1, and then propagate changes to the MAC
1198  }
1199  }
1200 
1201 
1202  std::list<LteRrcSap::DrbToAddMod>::const_iterator dtamIt;
1203  for (dtamIt = rrcd.drbToAddModList.begin ();
1204  dtamIt != rrcd.drbToAddModList.end ();
1205  ++dtamIt)
1206  {
1207  NS_LOG_INFO (this << " IMSI " << m_imsi << " adding/modifying DRBID " << (uint32_t) dtamIt->drbIdentity << " LC " << (uint32_t) dtamIt->logicalChannelIdentity);
1208  NS_ASSERT_MSG (dtamIt->logicalChannelIdentity > 2, "LCID value " << dtamIt->logicalChannelIdentity << " is reserved for SRBs");
1209 
1210  std::map<uint8_t, Ptr<LteDataRadioBearerInfo> >::iterator drbMapIt = m_drbMap.find (dtamIt->drbIdentity);
1211  if (drbMapIt == m_drbMap.end ())
1212  {
1213  NS_LOG_INFO ("New Data Radio Bearer");
1214 
1215  TypeId rlcTypeId;
1216  if (m_useRlcSm)
1217  {
1218  rlcTypeId = LteRlcSm::GetTypeId ();
1219  }
1220  else
1221  {
1222  switch (dtamIt->rlcConfig.choice)
1223  {
1225  rlcTypeId = LteRlcAm::GetTypeId ();
1226  break;
1227 
1229  rlcTypeId = LteRlcUm::GetTypeId ();
1230  break;
1231 
1232  default:
1233  NS_FATAL_ERROR ("unsupported RLC configuration");
1234  break;
1235  }
1236  }
1237 
1238  ObjectFactory rlcObjectFactory;
1239  rlcObjectFactory.SetTypeId (rlcTypeId);
1240  Ptr<LteRlc> rlc = rlcObjectFactory.Create ()->GetObject<LteRlc> ();
1242  rlc->SetRnti (m_rnti);
1243  rlc->SetLcId (dtamIt->logicalChannelIdentity);
1244 
1245  Ptr<LteDataRadioBearerInfo> drbInfo = CreateObject<LteDataRadioBearerInfo> ();
1246  drbInfo->m_rlc = rlc;
1247  drbInfo->m_epsBearerIdentity = dtamIt->epsBearerIdentity;
1248  drbInfo->m_logicalChannelIdentity = dtamIt->logicalChannelIdentity;
1249  drbInfo->m_drbIdentity = dtamIt->drbIdentity;
1250 
1251  // we need PDCP only for real RLC, i.e., RLC/UM or RLC/AM
1252  // if we are using RLC/SM we don't care of anything above RLC
1253  if (rlcTypeId != LteRlcSm::GetTypeId ())
1254  {
1255  Ptr<LtePdcp> pdcp = CreateObject<LtePdcp> ();
1256  pdcp->SetRnti (m_rnti);
1257  pdcp->SetLcId (dtamIt->logicalChannelIdentity);
1258  pdcp->SetLtePdcpSapUser (m_drbPdcpSapUser);
1259  pdcp->SetLteRlcSapProvider (rlc->GetLteRlcSapProvider ());
1260  rlc->SetLteRlcSapUser (pdcp->GetLteRlcSapUser ());
1261  drbInfo->m_pdcp = pdcp;
1262  }
1263 
1264  m_bid2DrbidMap[dtamIt->epsBearerIdentity] = dtamIt->drbIdentity;
1265 
1266  m_drbMap.insert (std::pair<uint8_t, Ptr<LteDataRadioBearerInfo> > (dtamIt->drbIdentity, drbInfo));
1267 
1268 
1270  lcConfig.priority = dtamIt->logicalChannelConfig.priority;
1271  lcConfig.prioritizedBitRateKbps = dtamIt->logicalChannelConfig.prioritizedBitRateKbps;
1272  lcConfig.bucketSizeDurationMs = dtamIt->logicalChannelConfig.bucketSizeDurationMs;
1273  lcConfig.logicalChannelGroup = dtamIt->logicalChannelConfig.logicalChannelGroup;
1274 
1275  m_cmacSapProvider->AddLc (dtamIt->logicalChannelIdentity,
1276  lcConfig,
1277  rlc->GetLteMacSapUser ());
1278  rlc->Initialize ();
1279  }
1280  else
1281  {
1282  NS_LOG_INFO ("request to modify existing DRBID");
1283  Ptr<LteDataRadioBearerInfo> drbInfo = drbMapIt->second;
1285  }
1286  }
1287 
1288  std::list<uint8_t>::iterator dtdmIt;
1289  for (dtdmIt = rrcd.drbToReleaseList.begin ();
1290  dtdmIt != rrcd.drbToReleaseList.end ();
1291  ++dtdmIt)
1292  {
1293  uint8_t drbid = *dtdmIt;
1294  NS_LOG_INFO (this << " IMSI " << m_imsi << " releasing DRB " << (uint32_t) drbid << drbid);
1295  std::map<uint8_t, Ptr<LteDataRadioBearerInfo> >::iterator it = m_drbMap.find (drbid);
1296  NS_ASSERT_MSG (it != m_drbMap.end (), "could not find bearer with given lcid");
1297  m_drbMap.erase (it);
1298  m_bid2DrbidMap.erase (drbid);
1299  //Remove LCID
1300  m_cmacSapProvider->RemoveLc (drbid + 2);
1301  }
1302 }
1303 
1304 
1305 void
1307 {
1308  NS_LOG_FUNCTION (this);
1309 
1310  // perform the actions specified in 3GPP TS 36.331 section 5.5.2.1
1311 
1312  // 3GPP TS 36.331 section 5.5.2.4 Measurement object removal
1313  for (std::list<uint8_t>::iterator it = mc.measObjectToRemoveList.begin ();
1314  it != mc.measObjectToRemoveList.end ();
1315  ++it)
1316  {
1317  uint8_t measObjectId = *it;
1318  NS_LOG_LOGIC (this << " deleting measObjectId " << (uint32_t) measObjectId);
1319  m_varMeasConfig.measObjectList.erase (measObjectId);
1320  std::map<uint8_t, LteRrcSap::MeasIdToAddMod>::iterator measIdIt = m_varMeasConfig.measIdList.begin ();
1321  while (measIdIt != m_varMeasConfig.measIdList.end ())
1322  {
1323  if (measIdIt->second.measObjectId == measObjectId)
1324  {
1325  uint8_t measId = measIdIt->second.measId;
1326  NS_ASSERT (measId == measIdIt->first);
1327  NS_LOG_LOGIC (this << " deleting measId " << (uint32_t) measId << " because referring to measObjectId " << (uint32_t) measObjectId);
1328  // note: postfix operator preserves iterator validity
1329  m_varMeasConfig.measIdList.erase (measIdIt++);
1330  VarMeasReportListClear (measId);
1331  }
1332  else
1333  {
1334  ++measIdIt;
1335  }
1336  }
1337 
1338  }
1339 
1340  // 3GPP TS 36.331 section 5.5.2.5 Measurement object addition/ modification
1341  for (std::list<LteRrcSap::MeasObjectToAddMod>::iterator it = mc.measObjectToAddModList.begin ();
1342  it != mc.measObjectToAddModList.end ();
1343  ++it)
1344  {
1345  // simplifying assumptions
1346  NS_ASSERT_MSG (it->measObjectEutra.cellsToRemoveList.empty (), "cellsToRemoveList not supported");
1347  NS_ASSERT_MSG (it->measObjectEutra.cellsToAddModList.empty (), "cellsToAddModList not supported");
1348  NS_ASSERT_MSG (it->measObjectEutra.cellsToRemoveList.empty (), "blackCellsToRemoveList not supported");
1349  NS_ASSERT_MSG (it->measObjectEutra.blackCellsToAddModList.empty (), "blackCellsToAddModList not supported");
1350  NS_ASSERT_MSG (it->measObjectEutra.haveCellForWhichToReportCGI == false, "cellForWhichToReportCGI is not supported");
1351 
1352  uint8_t measObjectId = it->measObjectId;
1353  std::map<uint8_t, LteRrcSap::MeasObjectToAddMod>::iterator measObjectIt = m_varMeasConfig.measObjectList.find (measObjectId);
1354  if (measObjectIt != m_varMeasConfig.measObjectList.end ())
1355  {
1356  NS_LOG_LOGIC ("measObjectId " << (uint32_t) measObjectId << " exists, updating entry");
1357  measObjectIt->second = *it;
1358  for (std::map<uint8_t, LteRrcSap::MeasIdToAddMod>::iterator measIdIt
1359  = m_varMeasConfig.measIdList.begin ();
1360  measIdIt != m_varMeasConfig.measIdList.end ();
1361  ++measIdIt)
1362  {
1363  if (measIdIt->second.measObjectId == measObjectId)
1364  {
1365  uint8_t measId = measIdIt->second.measId;
1366  NS_LOG_LOGIC (this << " found measId " << (uint32_t) measId << " referring to measObjectId " << (uint32_t) measObjectId);
1367  VarMeasReportListClear (measId);
1368  }
1369  }
1370  }
1371  else
1372  {
1373  NS_LOG_LOGIC ("measObjectId " << (uint32_t) measObjectId << " is new, adding entry");
1374  m_varMeasConfig.measObjectList[measObjectId] = *it;
1375  }
1376 
1377  }
1378 
1379  // 3GPP TS 36.331 section 5.5.2.6 Reporting configuration removal
1380  for (std::list<uint8_t>::iterator it = mc.reportConfigToRemoveList.begin ();
1381  it != mc.reportConfigToRemoveList.end ();
1382  ++it)
1383  {
1384  uint8_t reportConfigId = *it;
1385  NS_LOG_LOGIC (this << " deleting reportConfigId " << (uint32_t) reportConfigId);
1386  m_varMeasConfig.reportConfigList.erase (reportConfigId);
1387  std::map<uint8_t, LteRrcSap::MeasIdToAddMod>::iterator measIdIt = m_varMeasConfig.measIdList.begin ();
1388  while (measIdIt != m_varMeasConfig.measIdList.end ())
1389  {
1390  if (measIdIt->second.reportConfigId == reportConfigId)
1391  {
1392  uint8_t measId = measIdIt->second.measId;
1393  NS_ASSERT (measId == measIdIt->first);
1394  NS_LOG_LOGIC (this << " deleting measId " << (uint32_t) measId << " because referring to reportConfigId " << (uint32_t) reportConfigId);
1395  // note: postfix operator preserves iterator validity
1396  m_varMeasConfig.measIdList.erase (measIdIt++);
1397  VarMeasReportListClear (measId);
1398  }
1399  else
1400  {
1401  ++measIdIt;
1402  }
1403  }
1404 
1405  }
1406 
1407  // 3GPP TS 36.331 section 5.5.2.7 Reporting configuration addition/ modification
1408  for (std::list<LteRrcSap::ReportConfigToAddMod>::iterator it = mc.reportConfigToAddModList.begin ();
1409  it != mc.reportConfigToAddModList.end ();
1410  ++it)
1411  {
1412  // simplifying assumptions
1413  NS_ASSERT_MSG (it->reportConfigEutra.triggerType == LteRrcSap::ReportConfigEutra::EVENT,
1414  "only trigger type EVENT is supported");
1415 
1416  uint8_t reportConfigId = it->reportConfigId;
1417  std::map<uint8_t, LteRrcSap::ReportConfigToAddMod>::iterator reportConfigIt = m_varMeasConfig.reportConfigList.find (reportConfigId);
1418  if (reportConfigIt != m_varMeasConfig.reportConfigList.end ())
1419  {
1420  NS_LOG_LOGIC ("reportConfigId " << (uint32_t) reportConfigId << " exists, updating entry");
1421  m_varMeasConfig.reportConfigList[reportConfigId] = *it;
1422  for (std::map<uint8_t, LteRrcSap::MeasIdToAddMod>::iterator measIdIt
1423  = m_varMeasConfig.measIdList.begin ();
1424  measIdIt != m_varMeasConfig.measIdList.end ();
1425  ++measIdIt)
1426  {
1427  if (measIdIt->second.reportConfigId == reportConfigId)
1428  {
1429  uint8_t measId = measIdIt->second.measId;
1430  NS_LOG_LOGIC (this << " found measId " << (uint32_t) measId << " referring to reportConfigId " << (uint32_t) reportConfigId);
1431  VarMeasReportListClear (measId);
1432  }
1433  }
1434  }
1435  else
1436  {
1437  NS_LOG_LOGIC ("reportConfigId " << (uint32_t) reportConfigId << " is new, adding entry");
1438  m_varMeasConfig.reportConfigList[reportConfigId] = *it;
1439  }
1440 
1441  }
1442 
1443  // 3GPP TS 36.331 section 5.5.2.8 Quantity configuration
1444  if (mc.haveQuantityConfig)
1445  {
1446  NS_LOG_LOGIC (this << " setting quantityConfig");
1448  // we calculate here the coefficient a used for Layer 3 filtering, see 3GPP TS 36.331 section 5.5.3.2
1449  m_varMeasConfig.aRsrp = std::pow (0.5, mc.quantityConfig.filterCoefficientRSRP / 4.0);
1450  m_varMeasConfig.aRsrq = std::pow (0.5, mc.quantityConfig.filterCoefficientRSRQ / 4.0);
1451  NS_LOG_LOGIC (this << " new filter coefficients: aRsrp=" << m_varMeasConfig.aRsrp << ", aRsrq=" << m_varMeasConfig.aRsrq);
1452 
1453  for (std::map<uint8_t, LteRrcSap::MeasIdToAddMod>::iterator measIdIt
1454  = m_varMeasConfig.measIdList.begin ();
1455  measIdIt != m_varMeasConfig.measIdList.end ();
1456  ++measIdIt)
1457  {
1458  VarMeasReportListClear (measIdIt->second.measId);
1459  }
1460  }
1461 
1462  // 3GPP TS 36.331 section 5.5.2.2 Measurement identity removal
1463  for (std::list<uint8_t>::iterator it = mc.measIdToRemoveList.begin ();
1464  it != mc.measIdToRemoveList.end ();
1465  ++it)
1466  {
1467  uint8_t measId = *it;
1468  NS_LOG_LOGIC (this << " deleting measId " << (uint32_t) measId);
1469  m_varMeasConfig.measIdList.erase (measId);
1470  VarMeasReportListClear (measId);
1471 
1472  // removing time-to-trigger queues
1473  m_enteringTriggerQueue.erase (measId);
1474  m_leavingTriggerQueue.erase (measId);
1475  }
1476 
1477  // 3GPP TS 36.331 section 5.5.2.3 Measurement identity addition/ modification
1478  for (std::list<LteRrcSap::MeasIdToAddMod>::iterator it = mc.measIdToAddModList.begin ();
1479  it != mc.measIdToAddModList.end ();
1480  ++it)
1481  {
1482  NS_LOG_LOGIC (this << " measId " << (uint32_t) it->measId
1483  << " (measObjectId=" << (uint32_t) it->measObjectId
1484  << ", reportConfigId=" << (uint32_t) it->reportConfigId
1485  << ")");
1486  NS_ASSERT (m_varMeasConfig.measObjectList.find (it->measObjectId)
1487  != m_varMeasConfig.measObjectList.end ());
1488  NS_ASSERT (m_varMeasConfig.reportConfigList.find (it->reportConfigId)
1489  != m_varMeasConfig.reportConfigList.end ());
1490  m_varMeasConfig.measIdList[it->measId] = *it; // side effect: create new entry if not exists
1491  std::map<uint8_t, VarMeasReport>::iterator measReportIt = m_varMeasReportList.find (it->measId);
1492  if (measReportIt != m_varMeasReportList.end ())
1493  {
1494  measReportIt->second.periodicReportTimer.Cancel ();
1495  m_varMeasReportList.erase (measReportIt);
1496  }
1497  NS_ASSERT (m_varMeasConfig.reportConfigList.find (it->reportConfigId)
1498  ->second.reportConfigEutra.triggerType != LteRrcSap::ReportConfigEutra::PERIODICAL);
1499 
1500  // new empty queues for time-to-trigger
1501  std::list<PendingTrigger_t> s;
1502  m_enteringTriggerQueue[it->measId] = s;
1503  m_leavingTriggerQueue[it->measId] = s;
1504  }
1505 
1506  if (mc.haveMeasGapConfig)
1507  {
1508  NS_FATAL_ERROR ("measurement gaps are currently not supported");
1509  }
1510 
1511  if (mc.haveSmeasure)
1512  {
1513  NS_FATAL_ERROR ("s-measure is currently not supported");
1514  }
1515 
1516  if (mc.haveSpeedStatePars)
1517  {
1518  NS_FATAL_ERROR ("SpeedStatePars are currently not supported");
1519  }
1520 }
1521 
1522 void
1523 LteUeRrc::SaveUeMeasurements (uint16_t cellId, double rsrp, double rsrq,
1524  bool useLayer3Filtering)
1525 {
1526  NS_LOG_FUNCTION (this << cellId << rsrp << rsrq << useLayer3Filtering);
1527 
1528  std::map<uint16_t, MeasValues>::iterator storedMeasIt = m_storedMeasValues.find (cellId);
1529 
1530  if (storedMeasIt != m_storedMeasValues.end ())
1531  {
1532  if (useLayer3Filtering)
1533  {
1534  // F_n = (1-a) F_{n-1} + a M_n
1535  storedMeasIt->second.rsrp = (1 - m_varMeasConfig.aRsrp) * storedMeasIt->second.rsrp
1536  + m_varMeasConfig.aRsrp * rsrp;
1537 
1538  if (std::isnan (storedMeasIt->second.rsrq))
1539  {
1540  // the previous RSRQ measurements provided UE PHY are invalid
1541  storedMeasIt->second.rsrq = rsrq; // replace it with unfiltered value
1542  }
1543  else
1544  {
1545  storedMeasIt->second.rsrq = (1 - m_varMeasConfig.aRsrq) * storedMeasIt->second.rsrq
1546  + m_varMeasConfig.aRsrq * rsrq;
1547  }
1548  }
1549  else
1550  {
1551  storedMeasIt->second.rsrp = rsrp;
1552  storedMeasIt->second.rsrq = rsrq;
1553  }
1554  }
1555  else
1556  {
1557  // first value is always unfiltered
1558  MeasValues v;
1559  v.rsrp = rsrp;
1560  v.rsrq = rsrq;
1561  std::pair<uint16_t, MeasValues> val (cellId, v);
1562  std::pair<std::map<uint16_t, MeasValues>::iterator, bool>
1563  ret = m_storedMeasValues.insert (val);
1564  NS_ASSERT_MSG (ret.second == true, "element already existed");
1565  storedMeasIt = ret.first;
1566  }
1567 
1568  NS_LOG_DEBUG (this << " IMSI " << m_imsi << " state " << ToString (m_state)
1569  << ", measured cell " << m_cellId
1570  << ", new RSRP " << rsrp << " stored " << storedMeasIt->second.rsrp
1571  << ", new RSRQ " << rsrq << " stored " << storedMeasIt->second.rsrq);
1572  storedMeasIt->second.timestamp = Simulator::Now ();
1573 
1574 } // end of void SaveUeMeasurements
1575 
1576 void
1578 {
1579  NS_LOG_FUNCTION (this << (uint16_t) measId);
1580 
1581  std::map<uint8_t, LteRrcSap::MeasIdToAddMod>::iterator measIdIt =
1582  m_varMeasConfig.measIdList.find (measId);
1583  NS_ASSERT (measIdIt != m_varMeasConfig.measIdList.end ());
1584  NS_ASSERT (measIdIt->first == measIdIt->second.measId);
1585 
1586  std::map<uint8_t, LteRrcSap::ReportConfigToAddMod>::iterator
1587  reportConfigIt = m_varMeasConfig.reportConfigList.find (measIdIt->second.reportConfigId);
1588  NS_ASSERT (reportConfigIt != m_varMeasConfig.reportConfigList.end ());
1589  LteRrcSap::ReportConfigEutra& reportConfigEutra = reportConfigIt->second.reportConfigEutra;
1590 
1591  std::map<uint8_t, LteRrcSap::MeasObjectToAddMod>::iterator
1592  measObjectIt = m_varMeasConfig.measObjectList.find (measIdIt->second.measObjectId);
1593  NS_ASSERT (measObjectIt != m_varMeasConfig.measObjectList.end ());
1594  LteRrcSap::MeasObjectEutra& measObjectEutra = measObjectIt->second.measObjectEutra;
1595 
1596  std::map<uint8_t, VarMeasReport>::iterator
1597  measReportIt = m_varMeasReportList.find (measId);
1598  bool isMeasIdInReportList = (measReportIt != m_varMeasReportList.end ());
1599 
1600  // we don't check the purpose field, as it is only included for
1601  // triggerType == periodical, which is not supported
1602  NS_ASSERT_MSG (reportConfigEutra.triggerType
1604  "only triggerType == event is supported");
1605  // only EUTRA is supported, no need to check for it
1606 
1607  NS_LOG_LOGIC (this << " considering measId " << (uint32_t) measId);
1608  bool eventEntryCondApplicable = false;
1609  bool eventLeavingCondApplicable = false;
1610  ConcernedCells_t concernedCellsEntry;
1611  ConcernedCells_t concernedCellsLeaving;
1612 
1613  switch (reportConfigEutra.eventId)
1614  {
1616  {
1617  /*
1618  * Event A1 (Serving becomes better than threshold)
1619  * Please refer to 3GPP TS 36.331 Section 5.5.4.2
1620  */
1621 
1622  double ms; // Ms, the measurement result of the serving cell
1623  double thresh; // Thresh, the threshold parameter for this event
1624  // Hys, the hysteresis parameter for this event.
1625  double hys = EutranMeasurementMapping::IeValue2ActualHysteresis (reportConfigEutra.hysteresis);
1626 
1627  switch (reportConfigEutra.triggerQuantity)
1628  {
1630  ms = m_storedMeasValues[m_cellId].rsrp;
1631  NS_ASSERT (reportConfigEutra.threshold1.choice
1633  thresh = EutranMeasurementMapping::RsrpRange2Dbm (reportConfigEutra.threshold1.range);
1634  break;
1636  ms = m_storedMeasValues[m_cellId].rsrq;
1637  NS_ASSERT (reportConfigEutra.threshold1.choice
1639  thresh = EutranMeasurementMapping::RsrqRange2Db (reportConfigEutra.threshold1.range);
1640  break;
1641  default:
1642  NS_FATAL_ERROR ("unsupported triggerQuantity");
1643  break;
1644  }
1645 
1646  // Inequality A1-1 (Entering condition): Ms - Hys > Thresh
1647  bool entryCond = ms - hys > thresh;
1648 
1649  if (entryCond)
1650  {
1651  if (!isMeasIdInReportList)
1652  {
1653  concernedCellsEntry.push_back (m_cellId);
1654  eventEntryCondApplicable = true;
1655  }
1656  else
1657  {
1658  /*
1659  * This is to check that the triggered cell recorded in the
1660  * VarMeasReportList is the serving cell.
1661  */
1662  NS_ASSERT (measReportIt->second.cellsTriggeredList.find (m_cellId)
1663  != measReportIt->second.cellsTriggeredList.end ());
1664  }
1665  }
1666  else if (reportConfigEutra.timeToTrigger > 0)
1667  {
1668  CancelEnteringTrigger (measId);
1669  }
1670 
1671  // Inequality A1-2 (Leaving condition): Ms + Hys < Thresh
1672  bool leavingCond = ms + hys < thresh;
1673 
1674  if (leavingCond)
1675  {
1676  if (isMeasIdInReportList)
1677  {
1678  /*
1679  * This is to check that the triggered cell recorded in the
1680  * VarMeasReportList is the serving cell.
1681  */
1682  NS_ASSERT (measReportIt->second.cellsTriggeredList.find (m_cellId)
1683  != measReportIt->second.cellsTriggeredList.end ());
1684  concernedCellsLeaving.push_back (m_cellId);
1685  eventLeavingCondApplicable = true;
1686  }
1687  }
1688  else if (reportConfigEutra.timeToTrigger > 0)
1689  {
1690  CancelLeavingTrigger (measId);
1691  }
1692 
1693  NS_LOG_LOGIC (this << " event A1: serving cell " << m_cellId
1694  << " ms=" << ms << " thresh=" << thresh
1695  << " entryCond=" << entryCond
1696  << " leavingCond=" << leavingCond);
1697 
1698  } // end of case LteRrcSap::ReportConfigEutra::EVENT_A1
1699 
1700  break;
1701 
1703  {
1704  /*
1705  * Event A2 (Serving becomes worse than threshold)
1706  * Please refer to 3GPP TS 36.331 Section 5.5.4.3
1707  */
1708 
1709  double ms; // Ms, the measurement result of the serving cell
1710  double thresh; // Thresh, the threshold parameter for this event
1711  // Hys, the hysteresis parameter for this event.
1712  double hys = EutranMeasurementMapping::IeValue2ActualHysteresis (reportConfigEutra.hysteresis);
1713 
1714  switch (reportConfigEutra.triggerQuantity)
1715  {
1717  ms = m_storedMeasValues[m_cellId].rsrp;
1718  NS_ASSERT (reportConfigEutra.threshold1.choice
1720  thresh = EutranMeasurementMapping::RsrpRange2Dbm (reportConfigEutra.threshold1.range);
1721  break;
1723  ms = m_storedMeasValues[m_cellId].rsrq;
1724  NS_ASSERT (reportConfigEutra.threshold1.choice
1726  thresh = EutranMeasurementMapping::RsrqRange2Db (reportConfigEutra.threshold1.range);
1727  break;
1728  default:
1729  NS_FATAL_ERROR ("unsupported triggerQuantity");
1730  break;
1731  }
1732 
1733  // Inequality A2-1 (Entering condition): Ms + Hys < Thresh
1734  bool entryCond = ms + hys < thresh;
1735 
1736  if (entryCond)
1737  {
1738  if (!isMeasIdInReportList)
1739  {
1740  concernedCellsEntry.push_back (m_cellId);
1741  eventEntryCondApplicable = true;
1742  }
1743  else
1744  {
1745  /*
1746  * This is to check that the triggered cell recorded in the
1747  * VarMeasReportList is the serving cell.
1748  */
1749  NS_ASSERT (measReportIt->second.cellsTriggeredList.find (m_cellId)
1750  != measReportIt->second.cellsTriggeredList.end ());
1751  }
1752  }
1753  else if (reportConfigEutra.timeToTrigger > 0)
1754  {
1755  CancelEnteringTrigger (measId);
1756  }
1757 
1758  // Inequality A2-2 (Leaving condition): Ms - Hys > Thresh
1759  bool leavingCond = ms - hys > thresh;
1760 
1761  if (leavingCond)
1762  {
1763  if (isMeasIdInReportList)
1764  {
1765  /*
1766  * This is to check that the triggered cell recorded in the
1767  * VarMeasReportList is the serving cell.
1768  */
1769  NS_ASSERT (measReportIt->second.cellsTriggeredList.find (m_cellId)
1770  != measReportIt->second.cellsTriggeredList.end ());
1771  concernedCellsLeaving.push_back (m_cellId);
1772  eventLeavingCondApplicable = true;
1773  }
1774  }
1775  else if (reportConfigEutra.timeToTrigger > 0)
1776  {
1777  CancelLeavingTrigger (measId);
1778  }
1779 
1780  NS_LOG_LOGIC (this << " event A2: serving cell " << m_cellId
1781  << " ms=" << ms << " thresh=" << thresh
1782  << " entryCond=" << entryCond
1783  << " leavingCond=" << leavingCond);
1784 
1785  } // end of case LteRrcSap::ReportConfigEutra::EVENT_A2
1786 
1787  break;
1788 
1790  {
1791  /*
1792  * Event A3 (Neighbour becomes offset better than PCell)
1793  * Please refer to 3GPP TS 36.331 Section 5.5.4.4
1794  */
1795 
1796  double mn; // Mn, the measurement result of the neighbouring cell
1797  double ofn = measObjectEutra.offsetFreq; // Ofn, the frequency specific offset of the frequency of the
1798  double ocn = 0.0; // Ocn, the cell specific offset of the neighbour cell
1799  double mp; // Mp, the measurement result of the PCell
1800  double ofp = measObjectEutra.offsetFreq; // Ofp, the frequency specific offset of the primary frequency
1801  double ocp = 0.0; // Ocp, the cell specific offset of the PCell
1802  // Off, the offset parameter for this event.
1803  double off = EutranMeasurementMapping::IeValue2ActualA3Offset (reportConfigEutra.a3Offset);
1804  // Hys, the hysteresis parameter for this event.
1805  double hys = EutranMeasurementMapping::IeValue2ActualHysteresis (reportConfigEutra.hysteresis);
1806 
1807  switch (reportConfigEutra.triggerQuantity)
1808  {
1810  mp = m_storedMeasValues[m_cellId].rsrp;
1811  NS_ASSERT (reportConfigEutra.threshold1.choice
1813  break;
1815  mp = m_storedMeasValues[m_cellId].rsrq;
1816  NS_ASSERT (reportConfigEutra.threshold1.choice
1818  break;
1819  default:
1820  NS_FATAL_ERROR ("unsupported triggerQuantity");
1821  break;
1822  }
1823 
1824  for (std::map<uint16_t, MeasValues>::iterator storedMeasIt = m_storedMeasValues.begin ();
1825  storedMeasIt != m_storedMeasValues.end ();
1826  ++storedMeasIt)
1827  {
1828  uint16_t cellId = storedMeasIt->first;
1829  if (cellId == m_cellId)
1830  {
1831  continue;
1832  }
1833 
1834  switch (reportConfigEutra.triggerQuantity)
1835  {
1837  mn = storedMeasIt->second.rsrp;
1838  break;
1840  mn = storedMeasIt->second.rsrq;
1841  break;
1842  default:
1843  NS_FATAL_ERROR ("unsupported triggerQuantity");
1844  break;
1845  }
1846 
1847  bool hasTriggered = isMeasIdInReportList
1848  && (measReportIt->second.cellsTriggeredList.find (cellId)
1849  != measReportIt->second.cellsTriggeredList.end ());
1850 
1851  // Inequality A3-1 (Entering condition): Mn + Ofn + Ocn - Hys > Mp + Ofp + Ocp + Off
1852  bool entryCond = mn + ofn + ocn - hys > mp + ofp + ocp + off;
1853 
1854  if (entryCond)
1855  {
1856  if (!hasTriggered)
1857  {
1858  concernedCellsEntry.push_back (cellId);
1859  eventEntryCondApplicable = true;
1860  }
1861  }
1862  else if (reportConfigEutra.timeToTrigger > 0)
1863  {
1864  CancelEnteringTrigger (measId, cellId);
1865  }
1866 
1867  // Inequality A3-2 (Leaving condition): Mn + Ofn + Ocn + Hys < Mp + Ofp + Ocp + Off
1868  bool leavingCond = mn + ofn + ocn + hys < mp + ofp + ocp + off;
1869 
1870  if (leavingCond)
1871  {
1872  if (hasTriggered)
1873  {
1874  concernedCellsLeaving.push_back (cellId);
1875  eventLeavingCondApplicable = true;
1876  }
1877  }
1878  else if (reportConfigEutra.timeToTrigger > 0)
1879  {
1880  CancelLeavingTrigger (measId, cellId);
1881  }
1882 
1883  NS_LOG_LOGIC (this << " event A3: neighbor cell " << cellId
1884  << " mn=" << mn << " mp=" << mp << " offset=" << off
1885  << " entryCond=" << entryCond
1886  << " leavingCond=" << leavingCond);
1887 
1888  } // end of for (storedMeasIt)
1889 
1890  } // end of case LteRrcSap::ReportConfigEutra::EVENT_A3
1891 
1892  break;
1893 
1895  {
1896  /*
1897  * Event A4 (Neighbour becomes better than threshold)
1898  * Please refer to 3GPP TS 36.331 Section 5.5.4.5
1899  */
1900 
1901  double mn; // Mn, the measurement result of the neighbouring cell
1902  double ofn = measObjectEutra.offsetFreq; // Ofn, the frequency specific offset of the frequency of the
1903  double ocn = 0.0; // Ocn, the cell specific offset of the neighbour cell
1904  double thresh; // Thresh, the threshold parameter for this event
1905  // Hys, the hysteresis parameter for this event.
1906  double hys = EutranMeasurementMapping::IeValue2ActualHysteresis (reportConfigEutra.hysteresis);
1907 
1908  switch (reportConfigEutra.triggerQuantity)
1909  {
1911  NS_ASSERT (reportConfigEutra.threshold1.choice
1913  thresh = EutranMeasurementMapping::RsrpRange2Dbm (reportConfigEutra.threshold1.range);
1914  break;
1916  NS_ASSERT (reportConfigEutra.threshold1.choice
1918  thresh = EutranMeasurementMapping::RsrqRange2Db (reportConfigEutra.threshold1.range);
1919  break;
1920  default:
1921  NS_FATAL_ERROR ("unsupported triggerQuantity");
1922  break;
1923  }
1924 
1925  for (std::map<uint16_t, MeasValues>::iterator storedMeasIt = m_storedMeasValues.begin ();
1926  storedMeasIt != m_storedMeasValues.end ();
1927  ++storedMeasIt)
1928  {
1929  uint16_t cellId = storedMeasIt->first;
1930  if (cellId == m_cellId)
1931  {
1932  continue;
1933  }
1934 
1935  switch (reportConfigEutra.triggerQuantity)
1936  {
1938  mn = storedMeasIt->second.rsrp;
1939  break;
1941  mn = storedMeasIt->second.rsrq;
1942  break;
1943  default:
1944  NS_FATAL_ERROR ("unsupported triggerQuantity");
1945  break;
1946  }
1947 
1948  bool hasTriggered = isMeasIdInReportList
1949  && (measReportIt->second.cellsTriggeredList.find (cellId)
1950  != measReportIt->second.cellsTriggeredList.end ());
1951 
1952  // Inequality A4-1 (Entering condition): Mn + Ofn + Ocn - Hys > Thresh
1953  bool entryCond = mn + ofn + ocn - hys > thresh;
1954 
1955  if (entryCond)
1956  {
1957  if (!hasTriggered)
1958  {
1959  concernedCellsEntry.push_back (cellId);
1960  eventEntryCondApplicable = true;
1961  }
1962  }
1963  else if (reportConfigEutra.timeToTrigger > 0)
1964  {
1965  CancelEnteringTrigger (measId, cellId);
1966  }
1967 
1968  // Inequality A4-2 (Leaving condition): Mn + Ofn + Ocn + Hys < Thresh
1969  bool leavingCond = mn + ofn + ocn + hys < thresh;
1970 
1971  if (leavingCond)
1972  {
1973  if (hasTriggered)
1974  {
1975  concernedCellsLeaving.push_back (cellId);
1976  eventLeavingCondApplicable = true;
1977  }
1978  }
1979  else if (reportConfigEutra.timeToTrigger > 0)
1980  {
1981  CancelLeavingTrigger (measId, cellId);
1982  }
1983 
1984  NS_LOG_LOGIC (this << " event A4: neighbor cell " << cellId
1985  << " mn=" << mn << " thresh=" << thresh
1986  << " entryCond=" << entryCond
1987  << " leavingCond=" << leavingCond);
1988 
1989  } // end of for (storedMeasIt)
1990 
1991  } // end of case LteRrcSap::ReportConfigEutra::EVENT_A4
1992 
1993  break;
1994 
1996  {
1997  /*
1998  * Event A5 (PCell becomes worse than threshold1 and neighbour
1999  * becomes better than threshold2)
2000  * Please refer to 3GPP TS 36.331 Section 5.5.4.6
2001  */
2002 
2003  double mp; // Mp, the measurement result of the PCell
2004  double mn; // Mn, the measurement result of the neighbouring cell
2005  double ofn = measObjectEutra.offsetFreq; // Ofn, the frequency specific offset of the frequency of the
2006  double ocn = 0.0; // Ocn, the cell specific offset of the neighbour cell
2007  double thresh1; // Thresh1, the threshold parameter for this event
2008  double thresh2; // Thresh2, the threshold parameter for this event
2009  // Hys, the hysteresis parameter for this event.
2010  double hys = EutranMeasurementMapping::IeValue2ActualHysteresis (reportConfigEutra.hysteresis);
2011 
2012  switch (reportConfigEutra.triggerQuantity)
2013  {
2015  mp = m_storedMeasValues[m_cellId].rsrp;
2016  NS_ASSERT (reportConfigEutra.threshold1.choice
2018  NS_ASSERT (reportConfigEutra.threshold2.choice
2020  thresh1 = EutranMeasurementMapping::RsrpRange2Dbm (reportConfigEutra.threshold1.range);
2021  thresh2 = EutranMeasurementMapping::RsrpRange2Dbm (reportConfigEutra.threshold2.range);
2022  break;
2024  mp = m_storedMeasValues[m_cellId].rsrq;
2025  NS_ASSERT (reportConfigEutra.threshold1.choice
2027  NS_ASSERT (reportConfigEutra.threshold2.choice
2029  thresh1 = EutranMeasurementMapping::RsrqRange2Db (reportConfigEutra.threshold1.range);
2030  thresh2 = EutranMeasurementMapping::RsrqRange2Db (reportConfigEutra.threshold2.range);
2031  break;
2032  default:
2033  NS_FATAL_ERROR ("unsupported triggerQuantity");
2034  break;
2035  }
2036 
2037  // Inequality A5-1 (Entering condition 1): Mp + Hys < Thresh1
2038  bool entryCond = mp + hys < thresh1;
2039 
2040  if (entryCond)
2041  {
2042  for (std::map<uint16_t, MeasValues>::iterator storedMeasIt = m_storedMeasValues.begin ();
2043  storedMeasIt != m_storedMeasValues.end ();
2044  ++storedMeasIt)
2045  {
2046  uint16_t cellId = storedMeasIt->first;
2047  if (cellId == m_cellId)
2048  {
2049  continue;
2050  }
2051 
2052  switch (reportConfigEutra.triggerQuantity)
2053  {
2055  mn = storedMeasIt->second.rsrp;
2056  break;
2058  mn = storedMeasIt->second.rsrq;
2059  break;
2060  default:
2061  NS_FATAL_ERROR ("unsupported triggerQuantity");
2062  break;
2063  }
2064 
2065  bool hasTriggered = isMeasIdInReportList
2066  && (measReportIt->second.cellsTriggeredList.find (cellId)
2067  != measReportIt->second.cellsTriggeredList.end ());
2068 
2069  // Inequality A5-2 (Entering condition 2): Mn + Ofn + Ocn - Hys > Thresh2
2070 
2071  entryCond = mn + ofn + ocn - hys > thresh2;
2072 
2073  if (entryCond)
2074  {
2075  if (!hasTriggered)
2076  {
2077  concernedCellsEntry.push_back (cellId);
2078  eventEntryCondApplicable = true;
2079  }
2080  }
2081  else if (reportConfigEutra.timeToTrigger > 0)
2082  {
2083  CancelEnteringTrigger (measId, cellId);
2084  }
2085 
2086  NS_LOG_LOGIC (this << " event A5: neighbor cell " << cellId
2087  << " mn=" << mn << " mp=" << mp
2088  << " thresh2=" << thresh2
2089  << " thresh1=" << thresh1
2090  << " entryCond=" << entryCond);
2091 
2092  } // end of for (storedMeasIt)
2093 
2094  } // end of if (entryCond)
2095  else
2096  {
2097  NS_LOG_LOGIC (this << " event A5: serving cell " << m_cellId
2098  << " mp=" << mp << " thresh1=" << thresh1
2099  << " entryCond=" << entryCond);
2100 
2101  if (reportConfigEutra.timeToTrigger > 0)
2102  {
2103  CancelEnteringTrigger (measId);
2104  }
2105  }
2106 
2107  if (isMeasIdInReportList)
2108  {
2109  // Inequality A5-3 (Leaving condition 1): Mp - Hys > Thresh1
2110  bool leavingCond = mp - hys > thresh1;
2111 
2112  if (leavingCond)
2113  {
2114  if (reportConfigEutra.timeToTrigger == 0)
2115  {
2116  // leaving condition #2 does not have to be checked
2117 
2118  for (std::map<uint16_t, MeasValues>::iterator storedMeasIt = m_storedMeasValues.begin ();
2119  storedMeasIt != m_storedMeasValues.end ();
2120  ++storedMeasIt)
2121  {
2122  uint16_t cellId = storedMeasIt->first;
2123  if (cellId == m_cellId)
2124  {
2125  continue;
2126  }
2127 
2128  if (measReportIt->second.cellsTriggeredList.find (cellId)
2129  != measReportIt->second.cellsTriggeredList.end ())
2130  {
2131  concernedCellsLeaving.push_back (cellId);
2132  eventLeavingCondApplicable = true;
2133  }
2134  }
2135  } // end of if (reportConfigEutra.timeToTrigger == 0)
2136  else
2137  {
2138  // leaving condition #2 has to be checked to cancel time-to-trigger
2139 
2140  for (std::map<uint16_t, MeasValues>::iterator storedMeasIt = m_storedMeasValues.begin ();
2141  storedMeasIt != m_storedMeasValues.end ();
2142  ++storedMeasIt)
2143  {
2144  uint16_t cellId = storedMeasIt->first;
2145  if (cellId == m_cellId)
2146  {
2147  continue;
2148  }
2149 
2150  if (measReportIt->second.cellsTriggeredList.find (cellId)
2151  != measReportIt->second.cellsTriggeredList.end ())
2152  {
2153  switch (reportConfigEutra.triggerQuantity)
2154  {
2156  mn = storedMeasIt->second.rsrp;
2157  break;
2159  mn = storedMeasIt->second.rsrq;
2160  break;
2161  default:
2162  NS_FATAL_ERROR ("unsupported triggerQuantity");
2163  break;
2164  }
2165 
2166  // Inequality A5-4 (Leaving condition 2): Mn + Ofn + Ocn + Hys < Thresh2
2167 
2168  leavingCond = mn + ofn + ocn + hys < thresh2;
2169 
2170  if (!leavingCond)
2171  {
2172  CancelLeavingTrigger (measId, cellId);
2173  }
2174 
2175  /*
2176  * Whatever the result of leaving condition #2, this
2177  * cell is still "in", because leaving condition #1
2178  * is already true.
2179  */
2180  concernedCellsLeaving.push_back (cellId);
2181  eventLeavingCondApplicable = true;
2182 
2183  NS_LOG_LOGIC (this << " event A5: neighbor cell " << cellId
2184  << " mn=" << mn << " mp=" << mp
2185  << " thresh2=" << thresh2
2186  << " thresh1=" << thresh1
2187  << " leavingCond=" << leavingCond);
2188 
2189  } // end of if (measReportIt->second.cellsTriggeredList.find (cellId)
2190  // != measReportIt->second.cellsTriggeredList.end ())
2191 
2192  } // end of for (storedMeasIt)
2193 
2194  } // end of else of if (reportConfigEutra.timeToTrigger == 0)
2195 
2196  NS_LOG_LOGIC (this << " event A5: serving cell " << m_cellId
2197  << " mp=" << mp << " thresh1=" << thresh1
2198  << " leavingCond=" << leavingCond);
2199 
2200  } // end of if (leavingCond)
2201  else
2202  {
2203  if (reportConfigEutra.timeToTrigger > 0)
2204  {
2205  CancelLeavingTrigger (measId);
2206  }
2207 
2208  // check leaving condition #2
2209 
2210  for (std::map<uint16_t, MeasValues>::iterator storedMeasIt = m_storedMeasValues.begin ();
2211  storedMeasIt != m_storedMeasValues.end ();
2212  ++storedMeasIt)
2213  {
2214  uint16_t cellId = storedMeasIt->first;
2215  if (cellId == m_cellId)
2216  {
2217  continue;
2218  }
2219 
2220  if (measReportIt->second.cellsTriggeredList.find (cellId)
2221  != measReportIt->second.cellsTriggeredList.end ())
2222  {
2223  switch (reportConfigEutra.triggerQuantity)
2224  {
2226  mn = storedMeasIt->second.rsrp;
2227  break;
2229  mn = storedMeasIt->second.rsrq;
2230  break;
2231  default:
2232  NS_FATAL_ERROR ("unsupported triggerQuantity");
2233  break;
2234  }
2235 
2236  // Inequality A5-4 (Leaving condition 2): Mn + Ofn + Ocn + Hys < Thresh2
2237  leavingCond = mn + ofn + ocn + hys < thresh2;
2238 
2239  if (leavingCond)
2240  {
2241  concernedCellsLeaving.push_back (cellId);
2242  eventLeavingCondApplicable = true;
2243  }
2244 
2245  NS_LOG_LOGIC (this << " event A5: neighbor cell " << cellId
2246  << " mn=" << mn << " mp=" << mp
2247  << " thresh2=" << thresh2
2248  << " thresh1=" << thresh1
2249  << " leavingCond=" << leavingCond);
2250 
2251  } // end of if (measReportIt->second.cellsTriggeredList.find (cellId)
2252  // != measReportIt->second.cellsTriggeredList.end ())
2253 
2254  } // end of for (storedMeasIt)
2255 
2256  } // end of else of if (leavingCond)
2257 
2258  } // end of if (isMeasIdInReportList)
2259 
2260  } // end of case LteRrcSap::ReportConfigEutra::EVENT_A5
2261 
2262  break;
2263 
2264  default:
2265  NS_FATAL_ERROR ("unsupported eventId " << reportConfigEutra.eventId);
2266  break;
2267 
2268  } // switch (event type)
2269 
2270  NS_LOG_LOGIC (this << " eventEntryCondApplicable=" << eventEntryCondApplicable
2271  << " eventLeavingCondApplicable=" << eventLeavingCondApplicable);
2272 
2273  if (eventEntryCondApplicable)
2274  {
2275  if (reportConfigEutra.timeToTrigger == 0)
2276  {
2277  VarMeasReportListAdd (measId, concernedCellsEntry);
2278  }
2279  else
2280  {
2281  PendingTrigger_t t;
2282  t.measId = measId;
2283  t.concernedCells = concernedCellsEntry;
2284  t.timer = Simulator::Schedule (MilliSeconds (reportConfigEutra.timeToTrigger),
2286  measId, concernedCellsEntry);
2287  std::map<uint8_t, std::list<PendingTrigger_t> >::iterator
2288  enteringTriggerIt = m_enteringTriggerQueue.find (measId);
2289  NS_ASSERT (enteringTriggerIt != m_enteringTriggerQueue.end ());
2290  enteringTriggerIt->second.push_back (t);
2291  }
2292  }
2293 
2294  if (eventLeavingCondApplicable)
2295  {
2296  // reportOnLeave will only be set when eventId = eventA3
2297  bool reportOnLeave = (reportConfigEutra.eventId == LteRrcSap::ReportConfigEutra::EVENT_A3)
2298  && reportConfigEutra.reportOnLeave;
2299 
2300  if (reportConfigEutra.timeToTrigger == 0)
2301  {
2302  VarMeasReportListErase (measId, concernedCellsLeaving, reportOnLeave);
2303  }
2304  else
2305  {
2306  PendingTrigger_t t;
2307  t.measId = measId;
2308  t.concernedCells = concernedCellsLeaving;
2309  t.timer = Simulator::Schedule (MilliSeconds (reportConfigEutra.timeToTrigger),
2311  measId, concernedCellsLeaving, reportOnLeave);
2312  std::map<uint8_t, std::list<PendingTrigger_t> >::iterator
2313  leavingTriggerIt = m_leavingTriggerQueue.find (measId);
2314  NS_ASSERT (leavingTriggerIt != m_leavingTriggerQueue.end ());
2315  leavingTriggerIt->second.push_back (t);
2316  }
2317  }
2318 
2319 } // end of void LteUeRrc::MeasurementReportTriggering (uint8_t measId)
2320 
2321 void
2323 {
2324  NS_LOG_FUNCTION (this << (uint16_t) measId);
2325 
2326  std::map<uint8_t, std::list<PendingTrigger_t> >::iterator
2327  it1 = m_enteringTriggerQueue.find (measId);
2328  NS_ASSERT (it1 != m_enteringTriggerQueue.end ());
2329 
2330  if (!it1->second.empty ())
2331  {
2332  std::list<PendingTrigger_t>::iterator it2;
2333  for (it2 = it1->second.begin (); it2 != it1->second.end (); ++it2)
2334  {
2335  NS_ASSERT (it2->measId == measId);
2336  NS_LOG_LOGIC (this << " canceling entering time-to-trigger event at "
2337  << Simulator::GetDelayLeft (it2->timer).GetSeconds ());
2338  Simulator::Cancel (it2->timer);
2339  }
2340 
2341  it1->second.clear ();
2342  }
2343 }
2344 
2345 void
2346 LteUeRrc::CancelEnteringTrigger (uint8_t measId, uint16_t cellId)
2347 {
2348  NS_LOG_FUNCTION (this << (uint16_t) measId << cellId);
2349 
2350  std::map<uint8_t, std::list<PendingTrigger_t> >::iterator
2351  it1 = m_enteringTriggerQueue.find (measId);
2352  NS_ASSERT (it1 != m_enteringTriggerQueue.end ());
2353 
2354  std::list<PendingTrigger_t>::iterator it2 = it1->second.begin ();
2355  while (it2 != it1->second.end ())
2356  {
2357  NS_ASSERT (it2->measId == measId);
2358 
2359  ConcernedCells_t::iterator it3;
2360  for (it3 = it2->concernedCells.begin ();
2361  it3 != it2->concernedCells.end (); ++it3)
2362  {
2363  if (*it3 == cellId)
2364  {
2365  it3 = it2->concernedCells.erase (it3);
2366  }
2367  }
2368 
2369  if (it2->concernedCells.empty ())
2370  {
2371  NS_LOG_LOGIC (this << " canceling entering time-to-trigger event at "
2372  << Simulator::GetDelayLeft (it2->timer).GetSeconds ());
2373  Simulator::Cancel (it2->timer);
2374  it2 = it1->second.erase (it2);
2375  }
2376  else
2377  {
2378  it2++;
2379  }
2380  }
2381 }
2382 
2383 void
2385 {
2386  NS_LOG_FUNCTION (this << (uint16_t) measId);
2387 
2388  std::map<uint8_t, std::list<PendingTrigger_t> >::iterator
2389  it1 = m_leavingTriggerQueue.find (measId);
2390  NS_ASSERT (it1 != m_leavingTriggerQueue.end ());
2391 
2392  if (!it1->second.empty ())
2393  {
2394  std::list<PendingTrigger_t>::iterator it2;
2395  for (it2 = it1->second.begin (); it2 != it1->second.end (); ++it2)
2396  {
2397  NS_ASSERT (it2->measId == measId);
2398  NS_LOG_LOGIC (this << " canceling leaving time-to-trigger event at "
2399  << Simulator::GetDelayLeft (it2->timer).GetSeconds ());
2400  Simulator::Cancel (it2->timer);
2401  }
2402 
2403  it1->second.clear ();
2404  }
2405 }
2406 
2407 void
2408 LteUeRrc::CancelLeavingTrigger (uint8_t measId, uint16_t cellId)
2409 {
2410  NS_LOG_FUNCTION (this << (uint16_t) measId << cellId);
2411 
2412  std::map<uint8_t, std::list<PendingTrigger_t> >::iterator
2413  it1 = m_leavingTriggerQueue.find (measId);
2414  NS_ASSERT (it1 != m_leavingTriggerQueue.end ());
2415 
2416  std::list<PendingTrigger_t>::iterator it2 = it1->second.begin ();
2417  while (it2 != it1->second.end ())
2418  {
2419  NS_ASSERT (it2->measId == measId);
2420 
2421  ConcernedCells_t::iterator it3;
2422  for (it3 = it2->concernedCells.begin ();
2423  it3 != it2->concernedCells.end (); ++it3)
2424  {
2425  if (*it3 == cellId)
2426  {
2427  it3 = it2->concernedCells.erase (it3);
2428  }
2429  }
2430 
2431  if (it2->concernedCells.empty ())
2432  {
2433  NS_LOG_LOGIC (this << " canceling leaving time-to-trigger event at "
2434  << Simulator::GetDelayLeft (it2->timer).GetSeconds ());
2435  Simulator::Cancel (it2->timer);
2436  it2 = it1->second.erase (it2);
2437  }
2438  else
2439  {
2440  it2++;
2441  }
2442  }
2443 }
2444 
2445 void
2446 LteUeRrc::VarMeasReportListAdd (uint8_t measId, ConcernedCells_t enteringCells)
2447 {
2448  NS_LOG_FUNCTION (this << (uint16_t) measId);
2449  NS_ASSERT (!enteringCells.empty ());
2450 
2451  std::map<uint8_t, VarMeasReport>::iterator
2452  measReportIt = m_varMeasReportList.find (measId);
2453 
2454  if (measReportIt == m_varMeasReportList.end ())
2455  {
2456  VarMeasReport r;
2457  r.measId = measId;
2458  std::pair<uint8_t, VarMeasReport> val (measId, r);
2459  std::pair<std::map<uint8_t, VarMeasReport>::iterator, bool>
2460  ret = m_varMeasReportList.insert (val);
2461  NS_ASSERT_MSG (ret.second == true, "element already existed");
2462  measReportIt = ret.first;
2463  }
2464 
2465  NS_ASSERT (measReportIt != m_varMeasReportList.end ());
2466 
2467  for (ConcernedCells_t::const_iterator it = enteringCells.begin ();
2468  it != enteringCells.end ();
2469  ++it)
2470  {
2471  measReportIt->second.cellsTriggeredList.insert (*it);
2472  }
2473 
2474  NS_ASSERT (!measReportIt->second.cellsTriggeredList.empty ());
2475  measReportIt->second.numberOfReportsSent = 0;
2476  measReportIt->second.periodicReportTimer
2479  this, measId);
2480 
2481  std::map<uint8_t, std::list<PendingTrigger_t> >::iterator
2482  enteringTriggerIt = m_enteringTriggerQueue.find (measId);
2483  NS_ASSERT (enteringTriggerIt != m_enteringTriggerQueue.end ());
2484  if (!enteringTriggerIt->second.empty ())
2485  {
2486  /*
2487  * Assumptions at this point:
2488  * - the call to this function was delayed by time-to-trigger;
2489  * - the time-to-trigger delay is fixed (not adaptive/dynamic); and
2490  * - the first element in the list is associated with this function call.
2491  */
2492  enteringTriggerIt->second.pop_front ();
2493 
2494  if (!enteringTriggerIt->second.empty ())
2495  {
2496  /*
2497  * To prevent the same set of cells triggering again in the future,
2498  * we clean up the time-to-trigger queue. This case might occur when
2499  * time-to-trigger > 200 ms.
2500  */
2501  for (ConcernedCells_t::const_iterator it = enteringCells.begin ();
2502  it != enteringCells.end (); ++it)
2503  {
2504  CancelEnteringTrigger (measId, *it);
2505  }
2506  }
2507 
2508  } // end of if (!enteringTriggerIt->second.empty ())
2509 
2510 } // end of LteUeRrc::VarMeasReportListAdd
2511 
2512 void
2514  bool reportOnLeave)
2515 {
2516  NS_LOG_FUNCTION (this << (uint16_t) measId);
2517  NS_ASSERT (!leavingCells.empty ());
2518 
2519  std::map<uint8_t, VarMeasReport>::iterator
2520  measReportIt = m_varMeasReportList.find (measId);
2521  NS_ASSERT (measReportIt != m_varMeasReportList.end ());
2522 
2523  for (ConcernedCells_t::const_iterator it = leavingCells.begin ();
2524  it != leavingCells.end ();
2525  ++it)
2526  {
2527  measReportIt->second.cellsTriggeredList.erase (*it);
2528  }
2529 
2530  if (reportOnLeave)
2531  {
2532  // runs immediately without UE_MEASUREMENT_REPORT_DELAY
2533  SendMeasurementReport (measId);
2534  }
2535 
2536  if (measReportIt->second.cellsTriggeredList.empty ())
2537  {
2538  measReportIt->second.periodicReportTimer.Cancel ();
2539  m_varMeasReportList.erase (measReportIt);
2540  }
2541 
2542  std::map<uint8_t, std::list<PendingTrigger_t> >::iterator
2543  leavingTriggerIt = m_leavingTriggerQueue.find (measId);
2544  NS_ASSERT (leavingTriggerIt != m_leavingTriggerQueue.end ());
2545  if (!leavingTriggerIt->second.empty ())
2546  {
2547  /*
2548  * Assumptions at this point:
2549  * - the call to this function was delayed by time-to-trigger; and
2550  * - the time-to-trigger delay is fixed (not adaptive/dynamic); and
2551  * - the first element in the list is associated with this function call.
2552  */
2553  leavingTriggerIt->second.pop_front ();
2554 
2555  if (!leavingTriggerIt->second.empty ())
2556  {
2557  /*
2558  * To prevent the same set of cells triggering again in the future,
2559  * we clean up the time-to-trigger queue. This case might occur when
2560  * time-to-trigger > 200 ms.
2561  */
2562  for (ConcernedCells_t::const_iterator it = leavingCells.begin ();
2563  it != leavingCells.end (); ++it)
2564  {
2565  CancelLeavingTrigger (measId, *it);
2566  }
2567  }
2568 
2569  } // end of if (!leavingTriggerIt->second.empty ())
2570 
2571 } // end of LteUeRrc::VarMeasReportListErase
2572 
2573 void
2575 {
2576  NS_LOG_FUNCTION (this << (uint16_t) measId);
2577 
2578  // remove the measurement reporting entry for this measId from the VarMeasReportList
2579  std::map<uint8_t, VarMeasReport>::iterator
2580  measReportIt = m_varMeasReportList.find (measId);
2581  if (measReportIt != m_varMeasReportList.end ())
2582  {
2583  NS_LOG_LOGIC (this << " deleting existing report for measId " << (uint16_t) measId);
2584  measReportIt->second.periodicReportTimer.Cancel ();
2585  m_varMeasReportList.erase (measReportIt);
2586  }
2587 
2588  CancelEnteringTrigger (measId);
2589  CancelLeavingTrigger (measId);
2590 }
2591 
2592 void
2594 {
2595  NS_LOG_FUNCTION (this << (uint16_t) measId);
2596  // 3GPP TS 36.331 section 5.5.5 Measurement reporting
2597 
2598  std::map<uint8_t, LteRrcSap::MeasIdToAddMod>::iterator
2599  measIdIt = m_varMeasConfig.measIdList.find (measId);
2600  NS_ASSERT (measIdIt != m_varMeasConfig.measIdList.end ());
2601 
2602  std::map<uint8_t, LteRrcSap::ReportConfigToAddMod>::iterator
2603  reportConfigIt = m_varMeasConfig.reportConfigList.find (measIdIt->second.reportConfigId);
2604  NS_ASSERT (reportConfigIt != m_varMeasConfig.reportConfigList.end ());
2605  LteRrcSap::ReportConfigEutra& reportConfigEutra = reportConfigIt->second.reportConfigEutra;
2606 
2607  LteRrcSap::MeasurementReport measurementReport;
2608  LteRrcSap::MeasResults& measResults = measurementReport.measResults;
2609  measResults.measId = measId;
2610 
2611  std::map<uint16_t, MeasValues>::iterator servingMeasIt = m_storedMeasValues.find (m_cellId);
2612  NS_ASSERT (servingMeasIt != m_storedMeasValues.end ());
2613  measResults.rsrpResult = EutranMeasurementMapping::Dbm2RsrpRange (servingMeasIt->second.rsrp);
2614  measResults.rsrqResult = EutranMeasurementMapping::Db2RsrqRange (servingMeasIt->second.rsrq);
2615  NS_LOG_INFO (this << " reporting serving cell "
2616  "RSRP " << (uint32_t) measResults.rsrpResult << " (" << servingMeasIt->second.rsrp << " dBm) "
2617  "RSRQ " << (uint32_t) measResults.rsrqResult << " (" << servingMeasIt->second.rsrq << " dB)");
2618  measResults.haveMeasResultNeighCells = false;
2619  std::map<uint8_t, VarMeasReport>::iterator measReportIt = m_varMeasReportList.find (measId);
2620  if (measReportIt == m_varMeasReportList.end ())
2621  {
2622  NS_LOG_ERROR ("no entry found in m_varMeasReportList for measId " << (uint32_t) measId);
2623  }
2624  else
2625  {
2626  if (!(measReportIt->second.cellsTriggeredList.empty ()))
2627  {
2628  std::multimap<double, uint16_t> sortedNeighCells;
2629  for (std::set<uint16_t>::iterator cellsTriggeredIt = measReportIt->second.cellsTriggeredList.begin ();
2630  cellsTriggeredIt != measReportIt->second.cellsTriggeredList.end ();
2631  ++cellsTriggeredIt)
2632  {
2633  uint16_t cellId = *cellsTriggeredIt;
2634  if (cellId != m_cellId)
2635  {
2636  std::map<uint16_t, MeasValues>::iterator neighborMeasIt = m_storedMeasValues.find (cellId);
2637  double triggerValue;
2638  switch (reportConfigEutra.triggerQuantity)
2639  {
2641  triggerValue = neighborMeasIt->second.rsrp;
2642  break;
2644  triggerValue = neighborMeasIt->second.rsrq;
2645  break;
2646  default:
2647  NS_FATAL_ERROR ("unsupported triggerQuantity");
2648  break;
2649  }
2650  sortedNeighCells.insert (std::pair<double, uint16_t> (triggerValue, cellId));
2651  }
2652  }
2653 
2654  std::multimap<double, uint16_t>::reverse_iterator sortedNeighCellsIt;
2655  uint32_t count;
2656  for (sortedNeighCellsIt = sortedNeighCells.rbegin (), count = 0;
2657  sortedNeighCellsIt != sortedNeighCells.rend () && count < reportConfigEutra.maxReportCells;
2658  ++sortedNeighCellsIt, ++count)
2659  {
2660  uint16_t cellId = sortedNeighCellsIt->second;
2661  std::map<uint16_t, MeasValues>::iterator neighborMeasIt = m_storedMeasValues.find (cellId);
2662  NS_ASSERT (neighborMeasIt != m_storedMeasValues.end ());
2663  LteRrcSap::MeasResultEutra measResultEutra;
2664  measResultEutra.physCellId = cellId;
2665  measResultEutra.haveCgiInfo = false;
2666  measResultEutra.haveRsrpResult = true;
2667  measResultEutra.rsrpResult = EutranMeasurementMapping::Dbm2RsrpRange (neighborMeasIt->second.rsrp);
2668  measResultEutra.haveRsrqResult = true;
2669  measResultEutra.rsrqResult = EutranMeasurementMapping::Db2RsrqRange (neighborMeasIt->second.rsrq);
2670  NS_LOG_INFO (this << " reporting neighbor cell " << (uint32_t) measResultEutra.physCellId
2671  << " RSRP " << (uint32_t) measResultEutra.rsrpResult
2672  << " (" << neighborMeasIt->second.rsrp << " dBm)"
2673  << " RSRQ " << (uint32_t) measResultEutra.rsrqResult
2674  << " (" << neighborMeasIt->second.rsrq << " dB)");
2675  measResults.measResultListEutra.push_back (measResultEutra);
2676  measResults.haveMeasResultNeighCells = true;
2677  }
2678  }
2679  else
2680  {
2681  NS_LOG_WARN (this << " cellsTriggeredList is empty");
2682  }
2683 
2684  /*
2685  * The current LteRrcSap implementation is broken in that it does not
2686  * allow for infinite values of reportAmount, which is probably the most
2687  * reasonable setting. So we just always assume infinite reportAmount.
2688  */
2689  measReportIt->second.numberOfReportsSent++;
2690  measReportIt->second.periodicReportTimer.Cancel ();
2691 
2692  Time reportInterval;
2693  switch (reportConfigEutra.reportInterval)
2694  {
2696  reportInterval = MilliSeconds (120);
2697  break;
2699  reportInterval = MilliSeconds (240);
2700  break;
2702  reportInterval = MilliSeconds (480);
2703  break;
2705  reportInterval = MilliSeconds (640);
2706  break;
2708  reportInterval = MilliSeconds (1024);
2709  break;
2711  reportInterval = MilliSeconds (2048);
2712  break;
2714  reportInterval = MilliSeconds (5120);
2715  break;
2717  reportInterval = MilliSeconds (10240);
2718  break;
2720  reportInterval = Seconds (60);
2721  break;
2723  reportInterval = Seconds (360);
2724  break;
2726  reportInterval = Seconds (720);
2727  break;
2729  reportInterval = Seconds (1800);
2730  break;
2732  reportInterval = Seconds (3600);
2733  break;
2734  default:
2735  NS_FATAL_ERROR ("Unsupported reportInterval " << (uint16_t) reportConfigEutra.reportInterval);
2736  break;
2737  }
2738 
2739  // schedule the next measurement reporting
2740  measReportIt->second.periodicReportTimer
2741  = Simulator::Schedule (reportInterval,
2743  this, measId);
2744 
2745  // send the measurement report to eNodeB
2746  m_rrcSapUser->SendMeasurementReport (measurementReport);
2747  }
2748 }
2749 
2750 void
2752 {
2753  NS_LOG_FUNCTION (this << m_imsi);
2756  m_connectionPending = false; // reset the flag
2759 }
2760 
2761 void
2763 {
2764  NS_LOG_FUNCTION (this << m_imsi);
2767  std::map<uint8_t, Ptr<LteDataRadioBearerInfo> >::iterator it;
2768  for (it = m_drbMap.begin (); it != m_drbMap.end (); ++it)
2769  {
2770  m_cmacSapProvider->RemoveLc (it->second->m_logicalChannelIdentity);
2771  }
2772  m_drbMap.clear ();
2773  m_bid2DrbidMap.clear ();
2774  m_srb1 = 0;
2776 }
2777 
2778 void
2780 {
2781  NS_LOG_FUNCTION (this << m_imsi);
2782  m_cmacSapProvider->Reset (); // reset the MAC
2783  m_hasReceivedSib2 = false; // invalidate the previously received SIB2
2786  m_asSapUser->NotifyConnectionFailed (); // inform upper layer
2787 }
2788 
2789 void
2791 {
2792  NS_LOG_FUNCTION (this);
2793  m_srb1Old = 0;
2794 }
2795 
2796 uint8_t
2797 LteUeRrc::Bid2Drbid (uint8_t bid)
2798 {
2799  std::map<uint8_t, uint8_t>::iterator it = m_bid2DrbidMap.find (bid);
2800  //NS_ASSERT_MSG (it != m_bid2DrbidMap.end (), "could not find BID " << bid);
2801  if (it == m_bid2DrbidMap.end ())
2802  {
2803  return 0;
2804  }
2805  else
2806  {
2807  return it->second;
2808  }
2809 }
2810 
2811 void
2813 {
2814  NS_LOG_FUNCTION (this << ToString (newState));
2815  State oldState = m_state;
2816  m_state = newState;
2817  NS_LOG_INFO (this << " IMSI " << m_imsi << " RNTI " << m_rnti << " UeRrc "
2818  << ToString (oldState) << " --> " << ToString (newState));
2819  m_stateTransitionTrace (m_imsi, m_cellId, m_rnti, oldState, newState);
2820 
2821  switch (newState)
2822  {
2823  case IDLE_START:
2824  NS_FATAL_ERROR ("cannot switch to an initial state");
2825  break;
2826 
2827  case IDLE_CELL_SEARCH:
2828  case IDLE_WAIT_MIB_SIB1:
2829  case IDLE_WAIT_MIB:
2830  case IDLE_WAIT_SIB1:
2831  break;
2832 
2833  case IDLE_CAMPED_NORMALLY:
2834  if (m_connectionPending)
2835  {
2837  }
2838  break;
2839 
2840  case IDLE_WAIT_SIB2:
2841  if (m_hasReceivedSib2)
2842  {
2844  StartConnection ();
2845  }
2846  break;
2847 
2848  case IDLE_RANDOM_ACCESS:
2849  case IDLE_CONNECTING:
2850  case CONNECTED_NORMALLY:
2851  case CONNECTED_HANDOVER:
2852  case CONNECTED_PHY_PROBLEM:
2854  break;
2855 
2856  default:
2857  break;
2858  }
2859 }
2860 
2861 
2862 
2863 
2864 } // namespace ns3
2865 
static Time GetDelayLeft(const EventId &id)
Get the remaining time until this event will execute.
Definition: simulator.cc:232
LtePdcpSapProvider * srb1SapProvider
Definition: lte-rrc-sap.h:677
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:95
virtual void Reset()=0
reset the PHY
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
PdschConfigDedicated pdschConfigDedicated
Definition: lte-rrc-sap.h:204
Part of the RRC protocol.
Definition: lte-rrc-sap.h:739
void DoRecvRrcConnectionSetup(LteRrcSap::RrcConnectionSetup msg)
Part of the RRC protocol. Implement the LteUeRrcSapProvider::RecvRrcConnectionSetup interface...
Definition: lte-ue-rrc.cc:849
void DoRecvMasterInformationBlock(uint16_t cellId, LteRrcSap::MasterInformationBlock msg)
Definition: lte-ue-rrc.cc:690
std::map< uint8_t, LteRrcSap::MeasObjectToAddMod > measObjectList
Definition: lte-ue-rrc.h:693
std::vector< struct UeMeasurementsElement > m_ueMeasurementsList
void CancelEnteringTrigger(uint8_t measId)
Clear all the waiting triggers in m_enteringTriggerQueue which are associated with the given measurem...
Definition: lte-ue-rrc.cc:2322
void DoRecvSystemInformationBlockType1(uint16_t cellId, LteRrcSap::SystemInformationBlockType1 msg)
Definition: lte-ue-rrc.cc:717
static TypeId GetTypeId(void)
Definition: lte-ue-rrc.cc:168
static double IeValue2ActualHysteresis(uint8_t hysteresisIeValue)
Returns the actual value of a hysteresis parameter.
Definition: lte-common.cc:245
std::list< MeasObjectToAddMod > measObjectToAddModList
Definition: lte-rrc-sap.h:463
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:44
LtePdcpSapUser * m_drbPdcpSapUser
Definition: lte-ue-rrc.h:534
void DoRecvSystemInformation(LteRrcSap::SystemInformation msg)
Part of the RRC protocol. Implement the LteUeRrcSapProvider::RecvSystemInformation interface...
Definition: lte-ue-rrc.cc:805
static double ConvertPdschConfigDedicated2Double(PdschConfigDedicated pdschConfigDedicated)
Definition: lte-rrc-sap.h:162
Template for the implementation of the LteUeCphySapUser as a member of an owner class of type C to wh...
SoundingRsUlConfigDedicated soundingRsUlConfigDedicated
Definition: lte-rrc-sap.h:200
static TypeId GetTypeId(void)
Definition: lte-rlc.cc:184
void SetAsSapUser(LteAsSapUser *s)
Set the AS SAP user to interact with the NAS entity.
Definition: lte-ue-rrc.cc:312
void MeasurementReportTriggering(uint8_t measId)
Evaluate the reporting criteria of a measurement identity and invoke some reporting actions based on ...
Definition: lte-ue-rrc.cc:1577
QuantityConfig quantityConfig
Definition: lte-rrc-sap.h:469
void DoRecvRrcConnectionReject(LteRrcSap::RrcConnectionReject msg)
Part of the RRC protocol. Implement the LteUeRrcSapProvider::RecvRrcConnectionReject interface...
Definition: lte-ue-rrc.cc:998
std::list< uint8_t > reportConfigToRemoveList
Definition: lte-rrc-sap.h:464
bool m_hasReceivedSib2
True if SIB2 was received for the current cell.
Definition: lte-ue-rrc.h:669
std::list< MeasResultEutra > measResultListEutra
Definition: lte-rrc-sap.h:582
int8_t qRxLevMin
INTEGER (-70..-22), actual value = IE value * 2 [dBm].
Definition: lte-rrc-sap.h:82
std::map< uint8_t, Ptr< LteDataRadioBearerInfo > > m_drbMap
The DataRadioBearerMap attribute.
Definition: lte-ue-rrc.h:570
void ApplyMeasConfig(LteRrcSap::MeasConfig mc)
Update the current measurement configuration m_varMeasConfig.
Definition: lte-ue-rrc.cc:1306
Specifies criteria for triggering of an E-UTRA measurement reporting event.
Definition: lte-rrc-sap.h:321
virtual void DoDispose(void)
Destructor implementation.
Definition: lte-ue-rrc.cc:156
void SetUseRlcSm(bool val)
Definition: lte-ue-rrc.cc:386
virtual void SendRrcConnectionReconfigurationCompleted(RrcConnectionReconfigurationCompleted msg)=0
Send an RRCConnectionReconfigurationComplete message to the serving eNodeB during an RRC connection r...
virtual void Reset()=0
reset the MAC
uint8_t measId
The measurement identity which raised the trigger.
Definition: lte-ue-rrc.h:820
RSRP is used for the threshold.
Definition: lte-rrc-sap.h:314
LteRrcSap::PdschConfigDedicated m_pdschConfigDedicated
Definition: lte-ue-rrc.h:580
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file...
Definition: assert.h:61
std::list< SrbToAddMod > srbToAddModList
Definition: lte-rrc-sap.h:253
void DoSetTemporaryCellRnti(uint16_t rnti)
Definition: lte-ue-rrc.cc:495
virtual void SetPa(double pa)=0
Represents a single triggered event from a measurement identity which reporting criteria have been fu...
Definition: lte-ue-rrc.h:818
RadioResourceConfigDedicated radioResourceConfigDedicated
Definition: lte-rrc-sap.h:611
EventId m_connectionTimeout
Invokes ConnectionEstablishmentTimeout() if RRC connection establishment procedure for this UE takes ...
Definition: lte-ue-rrc.h:939
LteUeRrc()
create an RRC instance for use within an ue
Definition: lte-ue-rrc.cc:124
#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:867
std::list< uint8_t > measObjectToRemoveList
Definition: lte-rrc-sap.h:462
void SetTypeId(TypeId tid)
Set the TypeId of the Objects to be created by this factory.
virtual void StartContentionBasedRandomAccessProcedure()=0
tell the MAC to start a contention-based random access procedure, e.g., to perform RRC connection est...
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:766
Service Access Point (SAP) offered by the UE PHY to the UE RRC for control purposes.
virtual void SynchronizeWithEnb(uint16_t cellId)=0
Tell the PHY entity to synchronize with a given eNodeB over the currently active EARFCN for communica...
virtual ~LteUeRrc()
Destructor.
Definition: lte-ue-rrc.cc:150
uint16_t m_cellId
The CellId attribute.
Definition: lte-ue-rrc.h:551
EventId timer
The pending reporting event, scheduled at the end of the time-to-trigger.
Definition: lte-ue-rrc.h:822
void CancelLeavingTrigger(uint8_t measId)
Clear all the waiting triggers in m_leavingTriggerQueue which are associated with the given measureme...
Definition: lte-ue-rrc.cc:2384
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:244
virtual void NotifyRandomAccessSuccessful()
Notify the RRC that the MAC Random Access procedure completed successfully.
Definition: lte-ue-rrc.cc:73
#define NS_FATAL_ERROR(msg)
Fatal error handling.
Definition: fatal-error.h:100
virtual void SetRnti(uint16_t rnti)=0
virtual void NotifyConnectionSuccessful()=0
Notify the NAS that RRC Connection Establishment was successful.
static void Cancel(const EventId &id)
Set the cancel bit on this event: the event's associated function will not be invoked when it expires...
Definition: simulator.cc:311
uint16_t GetUlEarfcn() const
Definition: lte-ue-rrc.cc:372
This class implements the Access Stratum (AS) Service Access Point (SAP), i.e., the interface between...
Definition: lte-as-sap.h:41
Event A2: Serving becomes worse than absolute threshold.
Definition: lte-rrc-sap.h:332
virtual void RemoveLc(uint8_t lcId)=0
remove an existing LC
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:819
bool m_hasReceivedMib
True if MIB was received for the current cell.
Definition: lte-ue-rrc.h:665
RachConfigDedicated rachConfigDedicated
Definition: lte-rrc-sap.h:506
void DoRecvRrcConnectionReestablishmentReject(LteRrcSap::RrcConnectionReestablishmentReject msg)
Part of the RRC protocol. Implement the LteUeRrcSapProvider::RecvRrcConnectionReestablishmentReject i...
Definition: lte-ue-rrc.cc:969
void SetRnti(uint16_t rnti)
Definition: lte-rlc.cc:126
bool m_connectionPending
True if a connection request by upper layers is pending.
Definition: lte-ue-rrc.h:663
RSRQ is used for the threshold.
Definition: lte-rrc-sap.h:315
bool m_hasReceivedSib1
True if SIB1 was received for the current cell.
Definition: lte-ue-rrc.h:667
LteMacSapProvider * m_macSapProvider
Definition: lte-ue-rrc.h:533
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:439
static double RsrqRange2Db(uint8_t range)
converts an RSRQ range to dB as per 3GPP TS 36.133 section 9.1.7 RSRQ Measurement Report Mapping ...
Definition: lte-common.cc:217
virtual void SendRrcConnectionSetupCompleted(RrcConnectionSetupCompleted msg)=0
Send an RRCConnectionSetupComplete message to the serving eNodeB during an RRC connection establishme...
uint8_t Bid2Drbid(uint8_t bid)
Definition: lte-ue-rrc.cc:2797
double GetSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:327
Parameters for LtePdcpSapUser::ReceivePdcpSdu.
Definition: lte-pdcp-sap.h:76
Event A5: PCell becomes worse than absolute threshold1 AND Neighbour becomes better than another abso...
Definition: lte-rrc-sap.h:335
LteUeCmacSapUser * GetLteUeCmacSapUser()
Definition: lte-ue-rrc.cc:284
friend class UeMemberLteUeCmacSapUser
Definition: lte-ue-rrc.h:73
static const Time UE_MEASUREMENT_REPORT_DELAY
Artificial delay of UE measurements procedure.
Definition: lte-ue-rrc.h:56
Reference Signal Received Quality.
Definition: lte-rrc-sap.h:363
LteRrcSap::QuantityConfig quantityConfig
Definition: lte-ue-rrc.h:695
Ptr< const AttributeAccessor > MakePointerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
Definition: pointer.h:210
void SetLteUeRrcSapUser(LteUeRrcSapUser *s)
set the RRC SAP this RRC should interact with
Definition: lte-ue-rrc.cc:291
LteUeRrcSapUser * m_rrcSapUser
Definition: lte-ue-rrc.h:530
TracedCallback< uint64_t, uint16_t, uint16_t > m_handoverEndOkTrace
The HandoverEndOk trace source.
Definition: lte-ue-rrc.h:655
State m_state
The current UE RRC state.
Definition: lte-ue-rrc.h:540
uint16_t m_dlEarfcn
Downlink carrier frequency.
Definition: lte-ue-rrc.h:585
AttributeValue implementation for Time.
Definition: nstime.h:921
Ptr< LteSignalingRadioBearerInfo > m_srb0
The Srb0 attribute.
Definition: lte-ue-rrc.h:556
virtual void ConfigureReferenceSignalPower(int8_t referenceSignalPower)=0
Configure referenceSignalPower.
ConcernedCells_t concernedCells
The list of cells responsible for this trigger.
Definition: lte-ue-rrc.h:821
static TypeId GetTypeId(void)
Definition: lte-rlc-um.cc:55
Represents a measurement result from a certain cell.
Definition: lte-ue-rrc.h:791
void DisposeOldSrb1()
Definition: lte-ue-rrc.cc:2790
static double IeValue2ActualA3Offset(int8_t a3OffsetIeValue)
Returns the actual value of an a3-Offset parameter.
Definition: lte-common.cc:276
Ptr< Object > Create(void) const
Create an Object instance of the configured TypeId.
TracedCallback< uint64_t, uint16_t, uint16_t, uint16_t > m_handoverStartTrace
The HandoverStart trace source.
Definition: lte-ue-rrc.h:650
void DoRecvRrcConnectionReconfiguration(LteRrcSap::RrcConnectionReconfiguration msg)
Part of the RRC protocol. Implement the LteUeRrcSapProvider::RecvRrcConnectionReconfiguration interfa...
Definition: lte-ue-rrc.cc:874
void DoRecvRrcConnectionReestablishment(LteRrcSap::RrcConnectionReestablishment msg)
Part of the RRC protocol. Implement the LteUeRrcSapProvider::RecvRrcConnectionReestablishment interfa...
Definition: lte-ue-rrc.cc:945
uint8_t m_dlBandwidth
Downlink bandwidth in RBs.
Definition: lte-ue-rrc.h:582
Service Access Point (SAP) offered by the UE PHY to the UE RRC for control purposes.
Hold an unsigned integer type.
Definition: uinteger.h:44
TracedCallback< uint64_t, uint16_t, uint16_t > m_randomAccessErrorTrace
The RandomAccessError trace source.
Definition: lte-ue-rrc.h:630
TracedCallback< uint64_t, uint16_t, uint16_t > m_sib2ReceivedTrace
The Sib2Received trace source.
Definition: lte-ue-rrc.h:603
Ptr< SampleEmitter > s
void ConnectionTimeout()
Invoked after timer T300 expires, notifying upper layers that RRC connection establishment procedure ...
Definition: lte-ue-rrc.cc:2779
void EvaluateCellForSelection()
Performs cell selection evaluation to the current serving cell.
Definition: lte-ue-rrc.cc:1055
std::list< MeasIdToAddMod > measIdToAddModList
Definition: lte-rrc-sap.h:467
Event A4: Neighbour becomes better than absolute threshold.
Definition: lte-rrc-sap.h:334
virtual void DoInitialize(void)
Initialize() implementation.
Definition: lte-ue-rrc.cc:394
std::map< uint16_t, MeasValues > m_storedMeasValues
Internal storage of the latest measurement results from all detected detected cells, indexed by the cell ID where the measurement was taken from.
Definition: lte-ue-rrc.h:811
PhysicalConfigDedicated physicalConfigDedicated
Definition: lte-rrc-sap.h:257
Ptr< LteSignalingRadioBearerInfo > m_srb1
The Srb1 attribute.
Definition: lte-ue-rrc.h:560
LteUeCphySapProvider * m_cphySapProvider
Definition: lte-ue-rrc.h:525
uint8_t GetUlBandwidth() const
Definition: lte-ue-rrc.cc:352
void SetLteUeCmacSapProvider(LteUeCmacSapProvider *s)
set the CMAC SAP this RRC should interact with
Definition: lte-ue-rrc.cc:277
bool m_useRlcSm
True if RLC SM is to be used, false if RLC UM/AM are to be used.
Definition: lte-ue-rrc.h:576
Parameters for LtePdcpSapProvider::TransmitPdcpSdu.
Definition: lte-pdcp-sap.h:43
Template for the implementation of the LteAsSapProvider as a member of an owner class of type C to wh...
Definition: lte-as-sap.h:147
LteMacSapUser * GetLteMacSapUser()
Definition: lte-rlc.cc:161
uint32_t m_csgWhiteList
List of CSG ID which this UE entity has access to.
Definition: lte-ue-rrc.h:678
Service Access Point (SAP) offered by the UE MAC to the UE RRC.
std::map< uint8_t, LteRrcSap::MeasIdToAddMod > measIdList
Definition: lte-ue-rrc.h:692
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:252
std::map< uint8_t, uint8_t > m_bid2DrbidMap
Definition: lte-ue-rrc.h:522
void SetLteMacSapProvider(LteMacSapProvider *s)
set the MAC SAP provider.
Definition: lte-ue-rrc.cc:305
TracedCallback< uint64_t, uint16_t > m_initialCellSelectionEndOkTrace
The InitialCellSelectionEndOk trace source.
Definition: lte-ue-rrc.h:614
RadioResourceConfigDedicated radioResourceConfigDedicated
Definition: lte-rrc-sap.h:595
void SetLteUeCphySapProvider(LteUeCphySapProvider *s)
set the CPHY SAP this RRC should use to interact with the PHY
Definition: lte-ue-rrc.cc:263
void SwitchToState(State s)
Switch the UE RRC to the given state.
Definition: lte-ue-rrc.cc:2812
static double IeValue2ActualQRxLevMin(int8_t qRxLevMinIeValue)
Returns the actual value of an Q-RxLevMin parameter.
Definition: lte-common.cc:308
TracedCallback< uint64_t, uint16_t > m_initialCellSelectionEndErrorTrace
The InitialCellSelectionEndError trace source.
Definition: lte-ue-rrc.h:619
VarMeasConfig m_varMeasConfig
Includes the accumulated configuration of the measurements to be performed by the UE...
Definition: lte-ue-rrc.h:706
std::map< uint8_t, std::list< PendingTrigger_t > > m_leavingTriggerQueue
List of triggers that were raised because leaving condition have been true, but are still delayed fro...
Definition: lte-ue-rrc.h:846
std::map< uint8_t, LteRrcSap::ReportConfigToAddMod > reportConfigList
Definition: lte-ue-rrc.h:694
LteUeCphySapUser * m_cphySapUser
Definition: lte-ue-rrc.h:524
virtual void Setup(SetupParameters params)=0
Every class exported by the ns3 library is enclosed in the ns3 namespace.
virtual void SetSrsConfigurationIndex(uint16_t srcCi)=0
Hold objects of type Ptr.
Definition: pointer.h:36
void SetLteRlcSapUser(LteRlcSapUser *s)
Definition: lte-rlc.cc:140
LteAsSapUser * m_asSapUser
Definition: lte-ue-rrc.h:537
Template for the implementation of the LteUeRrcSapProvider as a member of an owner class of type C to...
Definition: lte-rrc-sap.h:1076
virtual void StartCellSearch(uint16_t dlEarfcn)=0
Tell the PHY entity to listen to PSS from surrounding cells and measure the RSRP. ...
void DoNotifyRandomAccessSuccessful()
Definition: lte-ue-rrc.cc:504
uint8_t GetDlBandwidth() const
Definition: lte-ue-rrc.cc:359
uint16_t GetDlEarfcn() const
Definition: lte-ue-rrc.cc:366
TracedCallback< uint64_t, uint16_t, uint16_t, uint16_t > m_sib1ReceivedTrace
The Sib1Received trace source.
Definition: lte-ue-rrc.h:598
double rsrq
Measured RSRQ in dB.
Definition: lte-ue-rrc.h:794
void DoSendData(Ptr< Packet > packet, uint8_t bid)
Definition: lte-ue-rrc.cc:427
Service Access Point (SAP) offered by the UE MAC to the UE RRC.
This class implements the Access Stratum (AS) Service Access Point (SAP), i.e., the interface between...
Definition: lte-as-sap.h:105
static EventId ScheduleNow(MEM mem_ptr, OBJ obj)
Schedule an event to expire Now.
Definition: simulator.h:980
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
Definition: nstime.h:922
RadioResourceConfigCommonSib radioResourceConfigCommon
Definition: lte-rrc-sap.h:536
uint16_t m_ulEarfcn
Uplink carrier frequency.
Definition: lte-ue-rrc.h:586
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:223
void SetLcId(uint8_t lcId)
Definition: lte-rlc.cc:133
void DoRecvRrcConnectionRelease(LteRrcSap::RrcConnectionRelease msg)
Part of the RRC protocol. Implement the LteUeRrcSapProvider::RecvRrcConnectionRelease interface...
Definition: lte-ue-rrc.cc:991
Event A3: Neighbour becomes amount of offset better than PCell.
Definition: lte-rrc-sap.h:333
double rsrp
Measured RSRP in dBm.
Definition: lte-ue-rrc.h:793
virtual void AddLc(uint8_t lcId, LogicalChannelConfig lcConfig, LteMacSapUser *msu)=0
add a new Logical Channel (LC)
void VarMeasReportListErase(uint8_t measId, ConcernedCells_t leavingCells, bool reportOnLeave)
Remove some cells from an existing reporting entry in m_varMeasReportList.
Definition: lte-ue-rrc.cc:2513
CarrierBandwidthEutra carrierBandwidth
Definition: lte-rrc-sap.h:502
uint8_t m_ulBandwidth
Uplink bandwidth in RBs.
Definition: lte-ue-rrc.h:583
#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:84
LteUeCphySapUser * GetLteUeCphySapUser()
Definition: lte-ue-rrc.cc:270
TracedCallback< uint64_t, uint16_t, uint16_t > m_connectionReconfigurationTrace
The ConnectionReconfiguration trace source.
Definition: lte-ue-rrc.h:645
Reference Signal Received Power.
Definition: lte-rrc-sap.h:362
Ptr< LteSignalingRadioBearerInfo > m_srb1Old
SRB1 configuration before RRC connection reconfiguration.
Definition: lte-ue-rrc.h:565
virtual void SendMeasurementReport(MeasurementReport msg)=0
Send a MeasurementReport message to the serving eNodeB during a measurement reporting procedure (Sect...
State
The states of the UE RRC entity.
Definition: lte-ue-rrc.h:86
virtual void StartNonContentionBasedRandomAccessProcedure(uint16_t rnti, uint8_t rapId, uint8_t prachMask)=0
tell the MAC to start a non-contention-based random access procedure, e.g., as a consequence of hando...
virtual void SetDlBandwidth(uint8_t dlBandwidth)=0
uint64_t GetImsi(void) const
Definition: lte-ue-rrc.cc:331
void StartConnection()
Definition: lte-ue-rrc.cc:2751
Instantiate subclasses of ns3::Object.
static uint8_t Dbm2RsrpRange(double dbm)
convert an RSRP value in dBm to the corresponding range as per 3GPP TS 36.133 section 9...
Definition: lte-common.cc:209
uint16_t GetRnti() const
Definition: lte-ue-rrc.cc:337
void SaveUeMeasurements(uint16_t cellId, double rsrp, double rsrq, bool useLayer3Filtering)
Keep the given measurement result as the latest measurement figures, to be utilised by UE RRC functio...
Definition: lte-ue-rrc.cc:1523
virtual void SetTransmissionMode(uint8_t txMode)=0
static const std::string & ToString(EpcUeNas::State s)
Definition: epc-ue-nas.cc:50
void DoSetCsgWhiteList(uint32_t csgId)
Definition: lte-ue-rrc.cc:585
void DoNotifyRandomAccessFailed()
Definition: lte-ue-rrc.cc:552
void DoCompleteSetup(LteUeRrcSapProvider::CompleteSetupParameters params)
Part of the RRC protocol. Implement the LteUeRrcSapProvider::CompleteSetup interface.
Definition: lte-ue-rrc.cc:793
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition: log.h:228
LteUeRrcSapProvider * m_rrcSapProvider
Definition: lte-ue-rrc.h:531
void DoConnect()
Definition: lte-ue-rrc.cc:648
void ApplyRadioResourceConfigDedicated(LteRrcSap::RadioResourceConfigDedicated rrcd)
Definition: lte-ue-rrc.cc:1122
TracedCallback< uint64_t, uint16_t, uint16_t > m_connectionEstablishedTrace
The ConnectionEstablished trace source.
Definition: lte-ue-rrc.h:635
uint16_t GetCellId() const
Definition: lte-ue-rrc.cc:344
std::list< DrbToAddMod > drbToAddModList
Definition: lte-rrc-sap.h:254
virtual void NotifyConnectionReleased()=0
Notify the NAS that RRC Connection was released.
std::map< uint8_t, VarMeasReport > m_varMeasReportList
The list of active reporting entries, indexed by the measurement identity which triggered the reporti...
Definition: lte-ue-rrc.h:728
virtual void NotifyConnectionFailed()=0
Notify the NAS that RRC Connection Establishment failed.
LteAsSapProvider * m_asSapProvider
Definition: lte-ue-rrc.h:536
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:236
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:859
void Initialize(void)
Invoke DoInitialize on all Objects aggregated to this one.
Definition: object.cc:182
TracedCallback< uint64_t, uint16_t, uint16_t, uint16_t > m_mibReceivedTrace
The MibReceived trace source.
Definition: lte-ue-rrc.h:592
LteUeCmacSapProvider * m_cmacSapProvider
Definition: lte-ue-rrc.h:528
uint16_t m_rnti
The C-RNTI attribute.
Definition: lte-ue-rrc.h:547
uint64_t m_imsi
The unique UE identifier.
Definition: lte-ue-rrc.h:543
SystemInformationBlockType2 sib2
Definition: lte-rrc-sap.h:543
std::set< uint16_t > m_acceptableCell
List of cell ID of acceptable cells for cell selection that have been detected.
Definition: lte-ue-rrc.h:675
void Cancel(void)
This method is syntactic sugar for the ns3::Simulator::Cancel method.
Definition: event-id.cc:53
LteAsSapProvider * GetAsSapProvider()
Definition: lte-ue-rrc.cc:318
Service Access Point (SAP) offered by the MAC to the RLC See Femto Forum MAC Scheduler Interface Spec...
Definition: lte-mac-sap.h:36
void DoReportUeMeasurements(LteUeCphySapUser::UeMeasurementsParameters params)
Definition: lte-ue-rrc.cc:756
TracedCallback< uint64_t, uint16_t, uint16_t > m_connectionTimeoutTrace
The ConnectionTimeout trace source.
Definition: lte-ue-rrc.h:640
void DoStartCellSelection(uint16_t dlEarfcn)
Definition: lte-ue-rrc.cc:592
Ptr< const AttributeAccessor > MakeObjectMapAccessor(U T::*memberVariable)
MakeAccessorHelper implementation for ObjectVector.
Definition: object-map.h:80
Represents a single measurement reporting entry., which includes information about a measurement for ...
Definition: lte-ue-rrc.h:715
#define NS_LOG_ERROR(msg)
Use NS_LOG to output a message of level LOG_ERROR.
Definition: log.h:220
LteRlcSapProvider * GetLteRlcSapProvider()
Definition: lte-rlc.cc:147
TracedCallback< uint64_t, uint16_t, uint16_t, State, State > m_stateTransitionTrace
The StateTransition trace source.
Definition: lte-ue-rrc.h:609
void SendMeasurementReport(uint8_t measId)
Produce a proper measurement report from the given measurement identity's reporting entry in m_varMea...
Definition: lte-ue-rrc.cc:2593
A base class which provides memory management and object aggregation.
Definition: object.h:87
void SynchronizeToStrongestCell()
Go through the list of measurement results, choose the one with the strongest RSRP, and tell PHY to synchronize to it.
Definition: lte-ue-rrc.cc:1012
Container for a set of ns3::Object pointers.
void DoReceivePdcpSdu(LtePdcpSapUser::ReceivePdcpSduParameters params)
Definition: lte-ue-rrc.cc:487
virtual void SendRrcConnectionRequest(RrcConnectionRequest msg)=0
Send an _RRCConnectionRequest message to the serving eNodeB during an RRC connection establishment pr...
Part of the RRC protocol.
Definition: lte-rrc-sap.h:671
static uint8_t Db2RsrqRange(double db)
convert an RSRQ value in dB to the corresponding range as per 3GPP TS 36.133 section 9...
Definition: lte-common.cc:225
virtual void RecvData(Ptr< Packet > packet)=0
receive a data packet
State GetState() const
Definition: lte-ue-rrc.cc:379
UeMemberLteUeCmacSapUser(LteUeRrc *rrc)
Definition: lte-ue-rrc.cc:60
LteUeRrcSapProvider * GetLteUeRrcSapProvider()
Definition: lte-ue-rrc.cc:298
static const std::string g_ueRrcStateName[LteUeRrc::NUM_STATES]
Map each of UE RRC states to its string representation.
Definition: lte-ue-rrc.cc:90
std::list< uint16_t > ConcernedCells_t
List of cell IDs which are responsible for a certain trigger.
Definition: lte-ue-rrc.h:733
Time m_t300
The T300 attribute.
Definition: lte-ue-rrc.h:933
void VarMeasReportListAdd(uint8_t measId, ConcernedCells_t enteringCells)
Compose a new reporting entry of the given measurement identity, insert it into m_varMeasReportList, and set it up for submission to eNodeB.
Definition: lte-ue-rrc.cc:2446
void DoDisconnect()
Definition: lte-ue-rrc.cc:453
Ptr< T > GetObject(void) const
Get a pointer to the requested aggregated Object.
Definition: object.h:455
virtual void SetTemporaryCellRnti(uint16_t rnti)
Definition: lte-ue-rrc.cc:66
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
Definition: uinteger.h:45
TracedCallback< uint64_t, uint16_t, uint16_t > m_randomAccessSuccessfulTrace
The RandomAccessSuccessful trace source.
Definition: lte-ue-rrc.h:625
Event A1: Serving becomes better than absolute threshold.
Definition: lte-rrc-sap.h:331
std::map< uint8_t, std::list< PendingTrigger_t > > m_enteringTriggerQueue
List of triggers that were raised because entering condition have been true, but are still delayed fr...
Definition: lte-ue-rrc.h:834
std::list< uint8_t > measIdToRemoveList
Definition: lte-rrc-sap.h:466
This abstract base class defines the API to interact with the Radio Link Control (LTE_RLC) in LTE...
Definition: lte-rlc.h:50
a unique identifier for an interface.
Definition: type-id.h:51
virtual void ConfigureUplink(uint16_t ulEarfcn, uint8_t ulBandwidth)=0
Configure uplink (normally done after reception of SIB2)
std::list< ReportConfigToAddMod > reportConfigToAddModList
Definition: lte-rrc-sap.h:465
virtual void ConfigureRach(RachConfig rc)=0
TypeId SetParent(TypeId tid)
Definition: type-id.cc:631
static TypeId GetTypeId(void)
Definition: lte-rlc-am.cc:86
void SetImsi(uint64_t imsi)
Definition: lte-ue-rrc.cc:324
uint8_t m_lastRrcTransactionIdentifier
Definition: lte-ue-rrc.h:578
void VarMeasReportListClear(uint8_t measId)
Remove the reporting entry of the given measurement identity from m_varMeasReportList.
Definition: lte-ue-rrc.cc:2574
void LeaveConnectedMode()
Definition: lte-ue-rrc.cc:2762
TracedCallback< uint64_t, uint16_t, uint16_t > m_handoverEndErrorTrace
The HandoverEndError trace source.
Definition: lte-ue-rrc.h:660
RaSupervisionInfo raSupervisionInfo
Definition: lte-rrc-sap.h:237
LteRrcSap::SystemInformationBlockType1 m_lastSib1
Stored content of the last SIB1 received.
Definition: lte-ue-rrc.h:672
void SetLteMacSapProvider(LteMacSapProvider *s)
Definition: lte-rlc.cc:154
virtual void NotifyRandomAccessFailed()
Notify the RRC that the MAC Random Access procedure failed.
Definition: lte-ue-rrc.cc:79
LteUeCmacSapUser * m_cmacSapUser
Definition: lte-ue-rrc.h:527
static double RsrpRange2Dbm(uint8_t range)
converts an RSRP range to dBm as per 3GPP TS 36.133 section 9.1.4 RSRP Measurement Report Mapping ...
Definition: lte-common.cc:201
void DoForceCampedOnEnb(uint16_t cellId, uint16_t dlEarfcn)
Definition: lte-ue-rrc.cc:603