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  * Modified by:
21  * Danilo Abrignani <danilo.abrignani@unibo.it> (Carrier Aggregation - GSoC 2015)
22  * Biljana Bojovic <biljana.bojovic@cttc.es> (Carrier Aggregation)
23  */
24 
25 #include "lte-ue-rrc.h"
26 
27 #include <ns3/fatal-error.h>
28 #include <ns3/log.h>
29 #include <ns3/object-map.h>
30 #include <ns3/object-factory.h>
31 #include <ns3/simulator.h>
32 
33 #include <ns3/lte-rlc.h>
34 #include <ns3/lte-rlc-tm.h>
35 #include <ns3/lte-rlc-um.h>
36 #include <ns3/lte-rlc-am.h>
37 #include <ns3/lte-pdcp.h>
38 #include <ns3/lte-radio-bearer-info.h>
39 
40 #include <cmath>
41 
42 namespace ns3 {
43 
44 NS_LOG_COMPONENT_DEFINE ("LteUeRrc");
45 
47 // CMAC SAP forwarder
49 
52 {
53 public:
60 
61  virtual void SetTemporaryCellRnti (uint16_t rnti);
62  virtual void NotifyRandomAccessSuccessful ();
63  virtual void NotifyRandomAccessFailed ();
64 
65 private:
67 };
68 
70  : m_rrc (rrc)
71 {
72 }
73 
74 void
76 {
78 }
79 
80 
81 void
83 {
85 }
86 
87 void
89 {
91 }
92 
93 
94 
95 
96 
97 
99 static const std::string g_ueRrcStateName[LteUeRrc::NUM_STATES] =
100 {
101  "IDLE_START",
102  "IDLE_CELL_SEARCH",
103  "IDLE_WAIT_MIB_SIB1",
104  "IDLE_WAIT_MIB",
105  "IDLE_WAIT_SIB1",
106  "IDLE_CAMPED_NORMALLY",
107  "IDLE_WAIT_SIB2",
108  "IDLE_RANDOM_ACCESS",
109  "IDLE_CONNECTING",
110  "CONNECTED_NORMALLY",
111  "CONNECTED_HANDOVER",
112  "CONNECTED_PHY_PROBLEM",
113  "CONNECTED_REESTABLISHING"
114 };
115 
120 static const std::string & ToString (LteUeRrc::State s)
121 {
122  return g_ueRrcStateName[s];
123 }
124 
125 
127 // ue RRC methods
129 
130 NS_OBJECT_ENSURE_REGISTERED (LteUeRrc);
131 
132 
134  : m_cmacSapProvider (0),
135  m_rrcSapUser (0),
136  m_macSapProvider (0),
137  m_asSapUser (0),
138  m_ccmRrcSapProvider (0),
139  m_state (IDLE_START),
140  m_imsi (0),
141  m_rnti (0),
142  m_cellId (0),
143  m_useRlcSm (true),
144  m_connectionPending (false),
145  m_hasReceivedMib (false),
146  m_hasReceivedSib1 (false),
147  m_hasReceivedSib2 (false),
148  m_csgWhiteList (0),
149  m_numberOfComponentCarriers (MIN_NO_CC)
150 {
151  NS_LOG_FUNCTION (this);
152  m_cphySapUser.push_back (new MemberLteUeCphySapUser<LteUeRrc> (this));
153  m_cmacSapUser.push_back (new UeMemberLteUeCmacSapUser (this));
154  m_cphySapProvider.push_back(0);
155  m_cmacSapProvider.push_back(0);
160 }
161 
163 {
164  NS_LOG_FUNCTION (this);
165 }
166 
167 void
169 {
170  NS_LOG_FUNCTION (this);
171  for ( uint16_t i = 0; i < m_numberOfComponentCarriers; i++)
172  {
173  delete m_cphySapUser.at(i);
174  delete m_cmacSapUser.at(i);
175  }
176  m_cphySapUser.clear ();
177  m_cmacSapUser.clear ();
178  delete m_rrcSapProvider;
179  delete m_drbPdcpSapUser;
180  delete m_asSapProvider;
181  delete m_ccmRrcSapUser;
183  m_cphySapProvider.clear();
185  m_cmacSapProvider.clear();
186  m_drbMap.clear ();
187 }
188 
189 TypeId
191 {
192  static TypeId tid = TypeId ("ns3::LteUeRrc")
193  .SetParent<Object> ()
194  .SetGroupName ("Lte")
195  .AddConstructor<LteUeRrc> ()
196  .AddAttribute ("DataRadioBearerMap", "List of UE RadioBearerInfo for Data Radio Bearers by LCID.",
197  ObjectMapValue (),
199  MakeObjectMapChecker<LteDataRadioBearerInfo> ())
200  .AddAttribute ("Srb0", "SignalingRadioBearerInfo for SRB0",
201  PointerValue (),
203  MakePointerChecker<LteSignalingRadioBearerInfo> ())
204  .AddAttribute ("Srb1", "SignalingRadioBearerInfo for SRB1",
205  PointerValue (),
207  MakePointerChecker<LteSignalingRadioBearerInfo> ())
208  .AddAttribute ("CellId",
209  "Serving cell identifier",
210  UintegerValue (0), // unused, read-only attribute
212  MakeUintegerChecker<uint16_t> ())
213  .AddAttribute ("C-RNTI",
214  "Cell Radio Network Temporary Identifier",
215  UintegerValue (0), // unused, read-only attribute
217  MakeUintegerChecker<uint16_t> ())
218  .AddAttribute ("T300",
219  "Timer for the RRC Connection Establishment procedure "
220  "(i.e., the procedure is deemed as failed if it takes longer than this)",
221  TimeValue (MilliSeconds (100)),
223  MakeTimeChecker ())
224  .AddTraceSource ("MibReceived",
225  "trace fired upon reception of Master Information Block",
227  "ns3::LteUeRrc::MibSibHandoverTracedCallback")
228  .AddTraceSource ("Sib1Received",
229  "trace fired upon reception of System Information Block Type 1",
231  "ns3::LteUeRrc::MibSibHandoverTracedCallback")
232  .AddTraceSource ("Sib2Received",
233  "trace fired upon reception of System Information Block Type 2",
235  "ns3::LteUeRrc::ImsiCidRntiTracedCallback")
236  .AddTraceSource ("StateTransition",
237  "trace fired upon every UE RRC state transition",
239  "ns3::LteUeRrc::StateTracedCallback")
240  .AddTraceSource ("InitialCellSelectionEndOk",
241  "trace fired upon successful initial cell selection procedure",
243  "ns3::LteUeRrc::CellSelectionTracedCallback")
244  .AddTraceSource ("InitialCellSelectionEndError",
245  "trace fired upon failed initial cell selection procedure",
247  "ns3::LteUeRrc::CellSelectionTracedCallback")
248  .AddTraceSource ("RandomAccessSuccessful",
249  "trace fired upon successful completion of the random access procedure",
251  "ns3::LteUeRrc::ImsiCidRntiTracedCallback")
252  .AddTraceSource ("RandomAccessError",
253  "trace fired upon failure of the random access procedure",
255  "ns3::LteUeRrc::ImsiCidRntiTracedCallback")
256  .AddTraceSource ("ConnectionEstablished",
257  "trace fired upon successful RRC connection establishment",
259  "ns3::LteUeRrc::ImsiCidRntiTracedCallback")
260  .AddTraceSource ("ConnectionTimeout",
261  "trace fired upon timeout RRC connection establishment because of T300",
263  "ns3::LteUeRrc::ImsiCidRntiTracedCallback")
264  .AddTraceSource ("ConnectionReconfiguration",
265  "trace fired upon RRC connection reconfiguration",
267  "ns3::LteUeRrc::ImsiCidRntiTracedCallback")
268  .AddTraceSource ("HandoverStart",
269  "trace fired upon start of a handover procedure",
271  "ns3::LteUeRrc::MibSibHandoverTracedCallback")
272  .AddTraceSource ("HandoverEndOk",
273  "trace fired upon successful termination of a handover procedure",
275  "ns3::LteUeRrc::ImsiCidRntiTracedCallback")
276  .AddTraceSource ("HandoverEndError",
277  "trace fired upon failure of a handover procedure",
279  "ns3::LteUeRrc::ImsiCidRntiTracedCallback")
280  .AddTraceSource ("SCarrierConfigured",
281  "trace fired after configuring secondary carriers",
283  "ns3::LteUeRrc::SCarrierConfiguredTracedCallback")
284  ;
285  return tid;
286 }
287 
288 
289 void
291 {
292  NS_LOG_FUNCTION (this << s);
293  m_cphySapProvider.at(0) = s;
294 }
295 
296 void
298 {
299  NS_LOG_FUNCTION (this << s);
300  m_cphySapProvider.at(index) = s;
301 }
302 
305 {
306  NS_LOG_FUNCTION (this);
307  return m_cphySapUser.at(0);
308 }
309 
312 {
313  NS_LOG_FUNCTION (this);
314  return m_cphySapUser.at(index);
315 }
316 
317 void
319 {
320  NS_LOG_FUNCTION (this << s);
321  m_cmacSapProvider.at (0) = s;
322 }
323 
324 void
326 {
327  NS_LOG_FUNCTION (this << s);
328  m_cmacSapProvider.at (index) = s;
329 }
330 
333 {
334  NS_LOG_FUNCTION (this);
335  return m_cmacSapUser.at (0);
336 }
337 
340 {
341  NS_LOG_FUNCTION (this);
342  return m_cmacSapUser.at (index);
343 }
344 
345 void
347 {
348  NS_LOG_FUNCTION (this << s);
349  m_rrcSapUser = s;
350 }
351 
354 {
355  NS_LOG_FUNCTION (this);
356  return m_rrcSapProvider;
357 }
358 
359 void
361 {
362  NS_LOG_FUNCTION (this << s);
363  m_macSapProvider = s;
364 }
365 
366 void
368 {
369  NS_LOG_FUNCTION (this << s);
371 }
372 
375 {
376  NS_LOG_FUNCTION (this);
377  return m_ccmRrcSapUser;
378 }
379 
380 void
382 {
383  m_asSapUser = s;
384 }
385 
388 {
389  return m_asSapProvider;
390 }
391 
392 void
393 LteUeRrc::SetImsi (uint64_t imsi)
394 {
395  NS_LOG_FUNCTION (this << imsi);
396  m_imsi = imsi;
397 }
398 
399 uint64_t
400 LteUeRrc::GetImsi (void) const
401 {
402  return m_imsi;
403 }
404 
405 uint16_t
407 {
408  NS_LOG_FUNCTION (this);
409  return m_rnti;
410 }
411 
412 uint16_t
414 {
415  NS_LOG_FUNCTION (this);
416  return m_cellId;
417 }
418 
419 
420 uint8_t
422 {
423  NS_LOG_FUNCTION (this);
424  return m_ulBandwidth;
425 }
426 
427 uint8_t
429 {
430  NS_LOG_FUNCTION (this);
431  return m_dlBandwidth;
432 }
433 
434 uint32_t
436 {
437  return m_dlEarfcn;
438 }
439 
440 uint32_t
442 {
443  NS_LOG_FUNCTION (this);
444  return m_ulEarfcn;
445 }
446 
448 LteUeRrc::GetState (void) const
449 {
450  NS_LOG_FUNCTION (this);
451  return m_state;
452 }
453 
454 void
456 {
457  NS_LOG_FUNCTION (this);
458  m_useRlcSm = val;
459 }
460 
461 
462 void
464 {
465  NS_LOG_FUNCTION (this);
466 
467  // setup the UE side of SRB0
468  uint8_t lcid = 0;
469 
470  Ptr<LteRlc> rlc = CreateObject<LteRlcTm> ()->GetObject<LteRlc> ();
472  rlc->SetRnti (m_rnti);
473  rlc->SetLcId (lcid);
474 
475  m_srb0 = CreateObject<LteSignalingRadioBearerInfo> ();
476  m_srb0->m_rlc = rlc;
477  m_srb0->m_srbIdentity = 0;
479  ueParams.srb0SapProvider = m_srb0->m_rlc->GetLteRlcSapProvider ();
480  ueParams.srb1SapProvider = 0;
481  m_rrcSapUser->Setup (ueParams);
482 
483  // CCCH (LCID 0) is pre-configured, here is the hardcoded configuration:
485  lcConfig.priority = 0; // highest priority
486  lcConfig.prioritizedBitRateKbps = 65535; // maximum
487  lcConfig.bucketSizeDurationMs = 65535; // maximum
488  lcConfig.logicalChannelGroup = 0; // all SRBs mapped to LCG 0
489  m_cmacSapProvider.at(0)->AddLc (lcid, lcConfig, rlc->GetLteMacSapUser ());
490 }
491 
492 void
494 {
495  if (m_numberOfComponentCarriers < MIN_NO_CC || m_numberOfComponentCarriers > MAX_NO_CC)
496  {
497  // this check is needed in order to maintain backward compatibility with scripts and tests
498  // if case lte-helper is not used (like in several tests) the m_numberOfComponentCarriers
499  // is not set and then an error is raised
500  // In this case m_numberOfComponentCarriers is set to 1
502  }
504  {
505  for ( uint16_t i = 1; i < m_numberOfComponentCarriers; i++)
506  {
507  m_cphySapUser.push_back(new MemberLteUeCphySapUser<LteUeRrc> (this));
508  m_cmacSapUser.push_back(new UeMemberLteUeCmacSapUser (this));
509  m_cphySapProvider.push_back(0);
510  m_cmacSapProvider.push_back(0);
511  }
512  }
513 }
514 
515 
516 void
517 LteUeRrc::DoSendData (Ptr<Packet> packet, uint8_t bid)
518 {
519  NS_LOG_FUNCTION (this << packet);
520 
521  uint8_t drbid = Bid2Drbid (bid);
522 
523  if (drbid != 0)
524  {
525  std::map<uint8_t, Ptr<LteDataRadioBearerInfo> >::iterator it = m_drbMap.find (drbid);
526  NS_ASSERT_MSG (it != m_drbMap.end (), "could not find bearer with drbid == " << drbid);
527 
529  params.pdcpSdu = packet;
530  params.rnti = m_rnti;
531  params.lcid = it->second->m_logicalChannelIdentity;
532 
533  NS_LOG_LOGIC (this << " RNTI=" << m_rnti << " sending packet " << packet
534  << " on DRBID " << (uint32_t) drbid
535  << " (LCID " << (uint32_t) params.lcid << ")"
536  << " (" << packet->GetSize () << " bytes)");
537  it->second->m_pdcp->GetLtePdcpSapProvider ()->TransmitPdcpSdu (params);
538  }
539 }
540 
541 
542 void
544 {
545  NS_LOG_FUNCTION (this);
546 
547  switch (m_state)
548  {
549  case IDLE_START:
550  case IDLE_CELL_SEARCH:
551  case IDLE_WAIT_MIB_SIB1:
552  case IDLE_WAIT_MIB:
553  case IDLE_WAIT_SIB1:
555  NS_LOG_INFO ("already disconnected");
556  break;
557 
558  case IDLE_WAIT_SIB2:
559  case IDLE_CONNECTING:
560  NS_FATAL_ERROR ("cannot abort connection setup procedure");
561  break;
562 
563  case CONNECTED_NORMALLY:
564  case CONNECTED_HANDOVER:
568  break;
569 
570  default: // i.e. IDLE_RANDOM_ACCESS
571  NS_FATAL_ERROR ("method unexpected in state " << ToString (m_state));
572  break;
573  }
574 }
575 
576 void
578 {
579  NS_LOG_FUNCTION (this);
580  m_asSapUser->RecvData (params.pdcpSdu);
581 }
582 
583 
584 void
586 {
587  NS_LOG_FUNCTION (this << rnti);
588  m_rnti = rnti;
589  m_srb0->m_rlc->SetRnti (m_rnti);
590  m_cphySapProvider.at(0)->SetRnti (m_rnti);
591 }
592 
593 void
595 {
596  NS_LOG_FUNCTION (this << m_imsi << ToString (m_state));
598 
599  switch (m_state)
600  {
601  case IDLE_RANDOM_ACCESS:
602  {
603  // we just received a RAR with a T-C-RNTI and an UL grant
604  // send RRC connection request as message 3 of the random access procedure
607  msg.ueIdentity = m_imsi;
611  this);
612  }
613  break;
614 
615  case CONNECTED_HANDOVER:
616  {
620 
621  // 3GPP TS 36.331 section 5.5.6.1 Measurements related actions upon handover
622  std::map<uint8_t, LteRrcSap::MeasIdToAddMod>::iterator measIdIt;
623  for (measIdIt = m_varMeasConfig.measIdList.begin ();
624  measIdIt != m_varMeasConfig.measIdList.end ();
625  ++measIdIt)
626  {
627  VarMeasReportListClear (measIdIt->second.measId);
628  }
629 
632  }
633  break;
634 
635  default:
636  NS_FATAL_ERROR ("unexpected event in state " << ToString (m_state));
637  break;
638  }
639 }
640 
641 void
643 {
644  NS_LOG_FUNCTION (this << m_imsi << ToString (m_state));
646 
647  switch (m_state)
648  {
649  case IDLE_RANDOM_ACCESS:
650  {
653  }
654  break;
655 
656  case CONNECTED_HANDOVER:
657  {
664  }
665  break;
666 
667  default:
668  NS_FATAL_ERROR ("unexpected event in state " << ToString (m_state));
669  break;
670  }
671 }
672 
673 
674 void
676 {
677  NS_LOG_FUNCTION (this << m_imsi << csgId);
678  m_csgWhiteList = csgId;
679 }
680 
681 void
683 {
684  NS_LOG_FUNCTION (this << m_imsi << dlEarfcn);
686  "cannot start cell selection from state " << ToString (m_state));
687  m_dlEarfcn = dlEarfcn;
688  m_cphySapProvider.at(0)->StartCellSearch (dlEarfcn);
690 }
691 
692 void
693 LteUeRrc::DoForceCampedOnEnb (uint16_t cellId, uint32_t dlEarfcn)
694 {
695  NS_LOG_FUNCTION (this << m_imsi << cellId << dlEarfcn);
696 
697  switch (m_state)
698  {
699  case IDLE_START:
700  m_cellId = cellId;
701  m_dlEarfcn = dlEarfcn;
702  m_cphySapProvider.at(0)->SynchronizeWithEnb (m_cellId, m_dlEarfcn);
704  break;
705 
706  case IDLE_CELL_SEARCH:
707  case IDLE_WAIT_MIB_SIB1:
708  case IDLE_WAIT_SIB1:
709  NS_FATAL_ERROR ("cannot abort cell selection " << ToString (m_state));
710  break;
711 
712  case IDLE_WAIT_MIB:
713  NS_LOG_INFO ("already forced to camp to cell " << m_cellId);
714  break;
715 
717  case IDLE_WAIT_SIB2:
718  case IDLE_RANDOM_ACCESS:
719  case IDLE_CONNECTING:
720  NS_LOG_INFO ("already camped to cell " << m_cellId);
721  break;
722 
723  case CONNECTED_NORMALLY:
724  case CONNECTED_HANDOVER:
727  NS_LOG_INFO ("already connected to cell " << m_cellId);
728  break;
729 
730  default:
731  NS_FATAL_ERROR ("unexpected event in state " << ToString (m_state));
732  break;
733  }
734 
735 }
736 
737 void
739 {
740  NS_LOG_FUNCTION (this << m_imsi);
741 
742  switch (m_state)
743  {
744  case IDLE_START:
745  case IDLE_CELL_SEARCH:
746  case IDLE_WAIT_MIB_SIB1:
747  case IDLE_WAIT_SIB1:
748  case IDLE_WAIT_MIB:
749  m_connectionPending = true;
750  break;
751 
753  m_connectionPending = true;
755  break;
756 
757  case IDLE_WAIT_SIB2:
758  case IDLE_RANDOM_ACCESS:
759  case IDLE_CONNECTING:
760  NS_LOG_INFO ("already connecting");
761  break;
762 
763  case CONNECTED_NORMALLY:
765  case CONNECTED_HANDOVER:
766  NS_LOG_INFO ("already connected");
767  break;
768 
769  default:
770  NS_FATAL_ERROR ("unexpected event in state " << ToString (m_state));
771  break;
772  }
773 }
774 
775 
776 
777 // CPHY SAP methods
778 
779 void
782 {
784  m_cphySapProvider.at(0)->SetDlBandwidth (msg.dlBandwidth);
785  m_hasReceivedMib = true;
787 
788  switch (m_state)
789  {
790  case IDLE_WAIT_MIB:
791  // manual attachment
793  break;
794 
795  case IDLE_WAIT_MIB_SIB1:
796  // automatic attachment from Idle mode cell selection
798  break;
799 
800  default:
801  // do nothing extra
802  break;
803  }
804 }
805 
806 void
809 {
810  NS_LOG_FUNCTION (this);
811  switch (m_state)
812  {
813  case IDLE_WAIT_SIB1:
815  "Cell identity in SIB1 does not match with the originating cell");
816  m_hasReceivedSib1 = true;
817  m_lastSib1 = msg;
820  break;
821 
823  case IDLE_RANDOM_ACCESS:
824  case IDLE_CONNECTING:
825  case CONNECTED_NORMALLY:
826  case CONNECTED_HANDOVER:
830  "Cell identity in SIB1 does not match with the originating cell");
831  m_hasReceivedSib1 = true;
832  m_lastSib1 = msg;
834  break;
835 
836  case IDLE_WAIT_MIB_SIB1:
837  // MIB has not been received, so ignore this SIB1
838  break;
839 
840  default: // e.g. IDLE_START, IDLE_CELL_SEARCH, IDLE_WAIT_MIB, IDLE_WAIT_SIB2
841  // do nothing
842  break;
843  }
844 }
845 
846 void
848 {
849  NS_LOG_FUNCTION (this);
850 
851  // layer 3 filtering does not apply in IDLE mode
852  bool useLayer3Filtering = (m_state == CONNECTED_NORMALLY);
853  bool triggering = true;
854  std::vector <LteUeCphySapUser::UeMeasurementsElement>::iterator newMeasIt;
855  for (newMeasIt = params.m_ueMeasurementsList.begin ();
856  newMeasIt != params.m_ueMeasurementsList.end (); ++newMeasIt)
857  {
858  if (params.m_componentCarrierId != 0)
859  {
860  triggering = false; // report is triggered only when an event is on the primary carrier
861  // in this case the measurement received is related to secondary carriers
862  // measurements related to secondary carriers are saved on a different portion of memory
863  SaveScellUeMeasurements (newMeasIt->m_cellId, newMeasIt->m_rsrp,
864  newMeasIt->m_rsrq, useLayer3Filtering,
865  params.m_componentCarrierId );
866  }
867  else
868  {
869  SaveUeMeasurements (newMeasIt->m_cellId, newMeasIt->m_rsrp,
870  newMeasIt->m_rsrq, useLayer3Filtering);
871  }
872  }
873 
874  if (m_state == IDLE_CELL_SEARCH)
875  {
876  // start decoding BCH
878  }
879  else
880  {
881  if (triggering)
882  {
883  std::map<uint8_t, LteRrcSap::MeasIdToAddMod>::iterator measIdIt;
884  for (measIdIt = m_varMeasConfig.measIdList.begin ();
885  measIdIt != m_varMeasConfig.measIdList.end (); ++measIdIt)
886  {
887  MeasurementReportTriggering (measIdIt->first);
888  }
889  }
890  }
891 
892 } // end of LteUeRrc::DoReportUeMeasurements
893 
894 
895 
896 // RRC SAP methods
897 
898 void
900 {
901  NS_LOG_FUNCTION (this << " RNTI " << m_rnti);
902  m_srb0->m_rlc->SetLteRlcSapUser (params.srb0SapUser);
903  if (m_srb1)
904  {
905  m_srb1->m_pdcp->SetLtePdcpSapUser (params.srb1SapUser);
906  }
907 }
908 
909 
910 void
912 {
913  NS_LOG_FUNCTION (this << " RNTI " << m_rnti);
914 
915  if (msg.haveSib2)
916  {
917  switch (m_state)
918  {
920  case IDLE_WAIT_SIB2:
921  case IDLE_RANDOM_ACCESS:
922  case IDLE_CONNECTING:
923  case CONNECTED_NORMALLY:
924  case CONNECTED_HANDOVER:
927  m_hasReceivedSib2 = true;
935  m_cmacSapProvider.at (0)->ConfigureRach (rc);
936  m_cphySapProvider.at (0)->ConfigureUplink (m_ulEarfcn, m_ulBandwidth);
937  m_cphySapProvider.at (0)->ConfigureReferenceSignalPower (msg.sib2.radioResourceConfigCommon.pdschConfigCommon.referenceSignalPower);
938  if (m_state == IDLE_WAIT_SIB2)
939  {
941  StartConnection ();
942  }
943  break;
944 
945  default: // IDLE_START, IDLE_CELL_SEARCH, IDLE_WAIT_MIB, IDLE_WAIT_MIB_SIB1, IDLE_WAIT_SIB1
946  // do nothing
947  break;
948  }
949  }
950 
951 }
952 
953 
954 void
956 {
957  NS_LOG_FUNCTION (this << " RNTI " << m_rnti);
958  switch (m_state)
959  {
960  case IDLE_CONNECTING:
961  {
970  }
971  break;
972 
973  default:
974  NS_FATAL_ERROR ("method unexpected in state " << ToString (m_state));
975  break;
976  }
977 }
978 
979 void
981 {
982  NS_LOG_FUNCTION (this << " RNTI " << m_rnti);
983  NS_LOG_INFO ("DoRecvRrcConnectionReconfiguration haveNonCriticalExtension:" << msg.haveNonCriticalExtension );
984  switch (m_state)
985  {
986  case CONNECTED_NORMALLY:
987  if (msg.haveMobilityControlInfo)
988  {
989  NS_LOG_INFO ("haveMobilityControlInfo == true");
993  m_cmacSapProvider.at(0)->Reset ();
994  m_cphySapProvider.at(0)->Reset ();
998  m_cphySapProvider.at(0)->SynchronizeWithEnb (m_cellId, mci.carrierFreq.dlCarrierFreq);
999  m_cphySapProvider.at(0)->SetDlBandwidth ( mci.carrierBandwidth.dlBandwidth);
1000  m_cphySapProvider.at(0)->ConfigureUplink (mci.carrierFreq.ulCarrierFreq, mci.carrierBandwidth.ulBandwidth);
1002  m_srb0->m_rlc->SetRnti (m_rnti);
1003  NS_ASSERT_MSG (mci.haveRachConfigDedicated, "handover is only supported with non-contention-based random access procedure");
1004  m_cmacSapProvider.at(0)->StartNonContentionBasedRandomAccessProcedure (m_rnti, mci.rachConfigDedicated.raPreambleIndex, mci.rachConfigDedicated.raPrachMaskIndex);
1005  m_cphySapProvider.at(0)->SetRnti (m_rnti);
1008 
1009  // we re-establish SRB1 by creating a new entity
1010  // note that we can't dispose the old entity now, because
1011  // it's in the current stack, so we would corrupt the stack
1012  // if we did so. Hence we schedule it for later disposal
1013  m_srb1Old = m_srb1;
1015  m_srb1 = 0; // new instance will be be created within ApplyRadioResourceConfigDedicated
1016 
1017  m_drbMap.clear (); // dispose all DRBs
1019 
1020  if (msg.haveMeasConfig)
1021  {
1023  }
1024  // RRC connection reconfiguration completed will be sent
1025  // after handover is complete
1026  }
1027  else
1028  {
1029  NS_LOG_INFO ("haveMobilityControlInfo == false");
1030  if (msg.haveNonCriticalExtension)
1031  {
1033  NS_LOG_FUNCTION ( this << "RNTI " << m_rnti << " Configured for CA" );
1034  }
1036  {
1038  }
1039  if (msg.haveMeasConfig)
1040  {
1042  }
1047  }
1048  break;
1049 
1050  default:
1051  NS_FATAL_ERROR ("method unexpected in state " << ToString (m_state));
1052  break;
1053  }
1054 }
1055 
1056 void
1058 {
1059  NS_LOG_FUNCTION (this << " RNTI " << m_rnti);
1060  switch (m_state)
1061  {
1063  {
1071  }
1072  break;
1073 
1074  default:
1075  NS_FATAL_ERROR ("method unexpected in state " << ToString (m_state));
1076  break;
1077  }
1078 }
1079 
1080 void
1082 {
1083  NS_LOG_FUNCTION (this << " RNTI " << m_rnti);
1084  switch (m_state)
1085  {
1087  {
1092  LeaveConnectedMode ();
1093  }
1094  break;
1095 
1096  default:
1097  NS_FATAL_ERROR ("method unexpected in state " << ToString (m_state));
1098  break;
1099  }
1100 }
1101 
1102 void
1104 {
1105  NS_LOG_FUNCTION (this << " RNTI " << m_rnti);
1107 }
1108 
1109 void
1111 {
1112  NS_LOG_FUNCTION (this);
1114 
1115  m_cmacSapProvider.at (0)->Reset (); // reset the MAC
1116  m_hasReceivedSib2 = false; // invalidate the previously received SIB2
1118  m_asSapUser->NotifyConnectionFailed (); // inform upper layer
1119 }
1120 
1121 
1122 
1123 void
1125 {
1126  NS_LOG_FUNCTION (this);
1128 
1129  uint16_t maxRsrpCellId = 0;
1130  double maxRsrp = -std::numeric_limits<double>::infinity ();
1131 
1132  std::map<uint16_t, MeasValues>::iterator it;
1133  for (it = m_storedMeasValues.begin (); it != m_storedMeasValues.end (); it++)
1134  {
1135  /*
1136  * This block attempts to find a cell with strongest RSRP and has not
1137  * yet been identified as "acceptable cell".
1138  */
1139  if (maxRsrp < it->second.rsrp)
1140  {
1141  std::set<uint16_t>::const_iterator itCell;
1142  itCell = m_acceptableCell.find (it->first);
1143  if (itCell == m_acceptableCell.end ())
1144  {
1145  maxRsrpCellId = it->first;
1146  maxRsrp = it->second.rsrp;
1147  }
1148  }
1149  }
1150 
1151  if (maxRsrpCellId == 0)
1152  {
1153  NS_LOG_WARN (this << " Cell search is unable to detect surrounding cell to attach to");
1154  }
1155  else
1156  {
1157  NS_LOG_LOGIC (this << " cell " << maxRsrpCellId
1158  << " is the strongest untried surrounding cell");
1159  m_cphySapProvider.at(0)->SynchronizeWithEnb (maxRsrpCellId, m_dlEarfcn);
1161  }
1162 
1163 } // end of void LteUeRrc::SynchronizeToStrongestCell ()
1164 
1165 
1166 void
1168 {
1169  NS_LOG_FUNCTION (this);
1173  uint16_t cellId = m_lastSib1.cellAccessRelatedInfo.cellIdentity;
1174 
1175  // Cell selection criteria evaluation
1176 
1177  bool isSuitableCell = false;
1178  bool isAcceptableCell = false;
1179  std::map<uint16_t, MeasValues>::iterator storedMeasIt = m_storedMeasValues.find (cellId);
1180  double qRxLevMeas = storedMeasIt->second.rsrp;
1182  NS_LOG_LOGIC (this << " cell selection to cellId=" << cellId
1183  << " qrxlevmeas=" << qRxLevMeas << " dBm"
1184  << " qrxlevmin=" << qRxLevMin << " dBm");
1185 
1186  if (qRxLevMeas - qRxLevMin > 0)
1187  {
1188  isAcceptableCell = true;
1189 
1190  uint32_t cellCsgId = m_lastSib1.cellAccessRelatedInfo.csgIdentity;
1191  bool cellCsgIndication = m_lastSib1.cellAccessRelatedInfo.csgIndication;
1192 
1193  isSuitableCell = (cellCsgIndication == false) || (cellCsgId == m_csgWhiteList);
1194 
1195  NS_LOG_LOGIC (this << " csg(ue/cell/indication)=" << m_csgWhiteList << "/"
1196  << cellCsgId << "/" << cellCsgIndication);
1197  }
1198 
1199  // Cell selection decision
1200 
1201  if (isSuitableCell)
1202  {
1203  m_cellId = cellId;
1204  m_cphySapProvider.at(0)->SynchronizeWithEnb (cellId, m_dlEarfcn);
1205  m_cphySapProvider.at(0)->SetDlBandwidth (m_dlBandwidth);
1208  }
1209  else
1210  {
1211  // ignore the MIB and SIB1 received from this cell
1212  m_hasReceivedMib = false;
1213  m_hasReceivedSib1 = false;
1214 
1216 
1217  if (isAcceptableCell)
1218  {
1219  /*
1220  * The cells inserted into this list will not be considered for
1221  * subsequent cell search attempt.
1222  */
1223  m_acceptableCell.insert (cellId);
1224  }
1225 
1227  SynchronizeToStrongestCell (); // retry to a different cell
1228  }
1229 
1230 } // end of void LteUeRrc::EvaluateCellForSelection ()
1231 
1232 
1233 void
1235 {
1236  NS_LOG_FUNCTION (this);
1237 
1239 
1240  for(std::list<LteRrcSap::SCellToAddMod>::iterator it = nonCec.sCellsToAddModList.begin(); it!=nonCec.sCellsToAddModList.end(); it++)
1241  {
1242  LteRrcSap::SCellToAddMod scell = *it;
1243  uint8_t ccId = scell.sCellIndex;
1244 
1245 
1246  uint16_t physCellId = scell.cellIdentification.physCellId;
1250  uint32_t dlEarfcn = scell.cellIdentification.dlCarrierFreq;
1253 
1254  m_cphySapProvider.at (ccId)->SynchronizeWithEnb (physCellId, dlEarfcn);
1255  m_cphySapProvider.at (ccId)->SetDlBandwidth (dlBand);
1256  m_cphySapProvider.at (ccId)->ConfigureUplink (ulEarfcn, ulBand);
1258  m_cphySapProvider.at (ccId)->SetTransmissionMode (txMode);
1259  m_cphySapProvider.at (ccId)->SetRnti(m_rnti);
1260  m_cmacSapProvider.at (ccId)->SetRnti(m_rnti);
1261  // update PdschConfigDedicated (i.e. P_A value)
1263  double paDouble = LteRrcSap::ConvertPdschConfigDedicated2Double (pdschConfigDedicated);
1264  m_cphySapProvider.at (ccId)->SetPa (paDouble);
1265  m_cphySapProvider.at (ccId)->SetSrsConfigurationIndex (srsIndex);
1266  }
1267 
1269 }
1270 
1271 void
1273 {
1274  NS_LOG_FUNCTION (this);
1276 
1277  if (pcd.haveAntennaInfoDedicated)
1278  {
1279  m_cphySapProvider.at(0)->SetTransmissionMode (pcd.antennaInfo.transmissionMode);
1280  }
1282  {
1283  m_cphySapProvider.at(0)->SetSrsConfigurationIndex (pcd.soundingRsUlConfigDedicated.srsConfigIndex);
1284  }
1285 
1286  if (pcd.havePdschConfigDedicated)
1287  {
1288  // update PdschConfigDedicated (i.e. P_A value)
1291  m_cphySapProvider.at(0)->SetPa (paDouble);
1292  }
1293 
1294  std::list<LteRrcSap::SrbToAddMod>::const_iterator stamIt = rrcd.srbToAddModList.begin ();
1295  if (stamIt != rrcd.srbToAddModList.end ())
1296  {
1297  if (m_srb1 == 0)
1298  {
1299  // SRB1 not setup yet
1301  "unexpected state " << ToString (m_state));
1302  NS_ASSERT_MSG (stamIt->srbIdentity == 1, "only SRB1 supported");
1303 
1304  const uint8_t lcid = 1; // fixed LCID for SRB1
1305 
1306  Ptr<LteRlc> rlc = CreateObject<LteRlcAm> ();
1308  rlc->SetRnti (m_rnti);
1309  rlc->SetLcId (lcid);
1310 
1311  Ptr<LtePdcp> pdcp = CreateObject<LtePdcp> ();
1312  pdcp->SetRnti (m_rnti);
1313  pdcp->SetLcId (lcid);
1314  pdcp->SetLtePdcpSapUser (m_drbPdcpSapUser);
1315  pdcp->SetLteRlcSapProvider (rlc->GetLteRlcSapProvider ());
1316  rlc->SetLteRlcSapUser (pdcp->GetLteRlcSapUser ());
1317 
1318  m_srb1 = CreateObject<LteSignalingRadioBearerInfo> ();
1319  m_srb1->m_rlc = rlc;
1320  m_srb1->m_pdcp = pdcp;
1321  m_srb1->m_srbIdentity = 1;
1322 
1323  m_srb1->m_logicalChannelConfig.priority = stamIt->logicalChannelConfig.priority;
1324  m_srb1->m_logicalChannelConfig.prioritizedBitRateKbps = stamIt->logicalChannelConfig.prioritizedBitRateKbps;
1325  m_srb1->m_logicalChannelConfig.bucketSizeDurationMs = stamIt->logicalChannelConfig.bucketSizeDurationMs;
1326  m_srb1->m_logicalChannelConfig.logicalChannelGroup = stamIt->logicalChannelConfig.logicalChannelGroup;
1327 
1329  lcConfig.priority = stamIt->logicalChannelConfig.priority;
1330  lcConfig.prioritizedBitRateKbps = stamIt->logicalChannelConfig.prioritizedBitRateKbps;
1331  lcConfig.bucketSizeDurationMs = stamIt->logicalChannelConfig.bucketSizeDurationMs;
1332  lcConfig.logicalChannelGroup = stamIt->logicalChannelConfig.logicalChannelGroup;
1333  m_cmacSapProvider.at (0)->AddLc (lcid, lcConfig, rlc->GetLteMacSapUser ());
1334  ++stamIt;
1335  NS_ASSERT_MSG (stamIt == rrcd.srbToAddModList.end (), "at most one SrbToAdd supported");
1336 
1338  ueParams.srb0SapProvider = m_srb0->m_rlc->GetLteRlcSapProvider ();
1339  ueParams.srb1SapProvider = m_srb1->m_pdcp->GetLtePdcpSapProvider ();
1340  m_rrcSapUser->Setup (ueParams);
1341  }
1342  else
1343  {
1344  NS_LOG_INFO ("request to modify SRB1 (skipping as currently not implemented)");
1345  // would need to modify m_srb1, and then propagate changes to the MAC
1346  }
1347  }
1348 
1349 
1350  std::list<LteRrcSap::DrbToAddMod>::const_iterator dtamIt;
1351  for (dtamIt = rrcd.drbToAddModList.begin ();
1352  dtamIt != rrcd.drbToAddModList.end ();
1353  ++dtamIt)
1354  {
1355  NS_LOG_INFO (this << " IMSI " << m_imsi << " adding/modifying DRBID " << (uint32_t) dtamIt->drbIdentity << " LC " << (uint32_t) dtamIt->logicalChannelIdentity);
1356  NS_ASSERT_MSG (dtamIt->logicalChannelIdentity > 2, "LCID value " << dtamIt->logicalChannelIdentity << " is reserved for SRBs");
1357 
1358  std::map<uint8_t, Ptr<LteDataRadioBearerInfo> >::iterator drbMapIt = m_drbMap.find (dtamIt->drbIdentity);
1359  if (drbMapIt == m_drbMap.end ())
1360  {
1361  NS_LOG_INFO ("New Data Radio Bearer");
1362 
1363  TypeId rlcTypeId;
1364  if (m_useRlcSm)
1365  {
1366  rlcTypeId = LteRlcSm::GetTypeId ();
1367  }
1368  else
1369  {
1370  switch (dtamIt->rlcConfig.choice)
1371  {
1373  rlcTypeId = LteRlcAm::GetTypeId ();
1374  break;
1375 
1377  rlcTypeId = LteRlcUm::GetTypeId ();
1378  break;
1379 
1380  default:
1381  NS_FATAL_ERROR ("unsupported RLC configuration");
1382  break;
1383  }
1384  }
1385 
1386  ObjectFactory rlcObjectFactory;
1387  rlcObjectFactory.SetTypeId (rlcTypeId);
1388  Ptr<LteRlc> rlc = rlcObjectFactory.Create ()->GetObject<LteRlc> ();
1390  rlc->SetRnti (m_rnti);
1391  rlc->SetLcId (dtamIt->logicalChannelIdentity);
1392 
1393  Ptr<LteDataRadioBearerInfo> drbInfo = CreateObject<LteDataRadioBearerInfo> ();
1394  drbInfo->m_rlc = rlc;
1395  drbInfo->m_epsBearerIdentity = dtamIt->epsBearerIdentity;
1396  drbInfo->m_logicalChannelIdentity = dtamIt->logicalChannelIdentity;
1397  drbInfo->m_drbIdentity = dtamIt->drbIdentity;
1398 
1399  // we need PDCP only for real RLC, i.e., RLC/UM or RLC/AM
1400  // if we are using RLC/SM we don't care of anything above RLC
1401  if (rlcTypeId != LteRlcSm::GetTypeId ())
1402  {
1403  Ptr<LtePdcp> pdcp = CreateObject<LtePdcp> ();
1404  pdcp->SetRnti (m_rnti);
1405  pdcp->SetLcId (dtamIt->logicalChannelIdentity);
1406  pdcp->SetLtePdcpSapUser (m_drbPdcpSapUser);
1407  pdcp->SetLteRlcSapProvider (rlc->GetLteRlcSapProvider ());
1408  rlc->SetLteRlcSapUser (pdcp->GetLteRlcSapUser ());
1409  drbInfo->m_pdcp = pdcp;
1410  }
1411 
1412  m_bid2DrbidMap[dtamIt->epsBearerIdentity] = dtamIt->drbIdentity;
1413 
1414  m_drbMap.insert (std::pair<uint8_t, Ptr<LteDataRadioBearerInfo> > (dtamIt->drbIdentity, drbInfo));
1415 
1416 
1418  lcConfig.priority = dtamIt->logicalChannelConfig.priority;
1419  lcConfig.prioritizedBitRateKbps = dtamIt->logicalChannelConfig.prioritizedBitRateKbps;
1420  lcConfig.bucketSizeDurationMs = dtamIt->logicalChannelConfig.bucketSizeDurationMs;
1421  lcConfig.logicalChannelGroup = dtamIt->logicalChannelConfig.logicalChannelGroup;
1422 
1423  for (uint32_t i = 0; i < m_numberOfComponentCarriers; i++)
1424  {
1425  m_cmacSapProvider.at (i)->AddLc (dtamIt->logicalChannelIdentity,
1426  lcConfig,
1427  rlc->GetLteMacSapUser ());
1428  }
1429  rlc->Initialize ();
1430  }
1431  else
1432  {
1433  NS_LOG_INFO ("request to modify existing DRBID");
1434  Ptr<LteDataRadioBearerInfo> drbInfo = drbMapIt->second;
1436  }
1437  }
1438 
1439  std::list<uint8_t>::iterator dtdmIt;
1440  for (dtdmIt = rrcd.drbToReleaseList.begin ();
1441  dtdmIt != rrcd.drbToReleaseList.end ();
1442  ++dtdmIt)
1443  {
1444  uint8_t drbid = *dtdmIt;
1445  NS_LOG_INFO (this << " IMSI " << m_imsi << " releasing DRB " << (uint32_t) drbid << drbid);
1446  std::map<uint8_t, Ptr<LteDataRadioBearerInfo> >::iterator it = m_drbMap.find (drbid);
1447  NS_ASSERT_MSG (it != m_drbMap.end (), "could not find bearer with given lcid");
1448  m_drbMap.erase (it);
1449  m_bid2DrbidMap.erase (drbid);
1450  //Remove LCID
1451  for (uint32_t i = 0; i < m_numberOfComponentCarriers; i++)
1452  {
1453  m_cmacSapProvider.at (i)->RemoveLc (drbid + 2);
1454  }
1455  }
1456 }
1457 
1458 
1459 void
1461 {
1462  NS_LOG_FUNCTION (this);
1463 
1464  // perform the actions specified in 3GPP TS 36.331 section 5.5.2.1
1465 
1466  // 3GPP TS 36.331 section 5.5.2.4 Measurement object removal
1467  for (std::list<uint8_t>::iterator it = mc.measObjectToRemoveList.begin ();
1468  it != mc.measObjectToRemoveList.end ();
1469  ++it)
1470  {
1471  uint8_t measObjectId = *it;
1472  NS_LOG_LOGIC (this << " deleting measObjectId " << (uint32_t) measObjectId);
1473  m_varMeasConfig.measObjectList.erase (measObjectId);
1474  std::map<uint8_t, LteRrcSap::MeasIdToAddMod>::iterator measIdIt = m_varMeasConfig.measIdList.begin ();
1475  while (measIdIt != m_varMeasConfig.measIdList.end ())
1476  {
1477  if (measIdIt->second.measObjectId == measObjectId)
1478  {
1479  uint8_t measId = measIdIt->second.measId;
1480  NS_ASSERT (measId == measIdIt->first);
1481  NS_LOG_LOGIC (this << " deleting measId " << (uint32_t) measId << " because referring to measObjectId " << (uint32_t) measObjectId);
1482  // note: postfix operator preserves iterator validity
1483  m_varMeasConfig.measIdList.erase (measIdIt++);
1484  VarMeasReportListClear (measId);
1485  }
1486  else
1487  {
1488  ++measIdIt;
1489  }
1490  }
1491 
1492  }
1493 
1494  // 3GPP TS 36.331 section 5.5.2.5 Measurement object addition/ modification
1495  for (std::list<LteRrcSap::MeasObjectToAddMod>::iterator it = mc.measObjectToAddModList.begin ();
1496  it != mc.measObjectToAddModList.end ();
1497  ++it)
1498  {
1499  // simplifying assumptions
1500  NS_ASSERT_MSG (it->measObjectEutra.cellsToRemoveList.empty (), "cellsToRemoveList not supported");
1501  NS_ASSERT_MSG (it->measObjectEutra.cellsToAddModList.empty (), "cellsToAddModList not supported");
1502  NS_ASSERT_MSG (it->measObjectEutra.cellsToRemoveList.empty (), "blackCellsToRemoveList not supported");
1503  NS_ASSERT_MSG (it->measObjectEutra.blackCellsToAddModList.empty (), "blackCellsToAddModList not supported");
1504  NS_ASSERT_MSG (it->measObjectEutra.haveCellForWhichToReportCGI == false, "cellForWhichToReportCGI is not supported");
1505 
1506  uint8_t measObjectId = it->measObjectId;
1507  std::map<uint8_t, LteRrcSap::MeasObjectToAddMod>::iterator measObjectIt = m_varMeasConfig.measObjectList.find (measObjectId);
1508  if (measObjectIt != m_varMeasConfig.measObjectList.end ())
1509  {
1510  NS_LOG_LOGIC ("measObjectId " << (uint32_t) measObjectId << " exists, updating entry");
1511  measObjectIt->second = *it;
1512  for (std::map<uint8_t, LteRrcSap::MeasIdToAddMod>::iterator measIdIt
1513  = m_varMeasConfig.measIdList.begin ();
1514  measIdIt != m_varMeasConfig.measIdList.end ();
1515  ++measIdIt)
1516  {
1517  if (measIdIt->second.measObjectId == measObjectId)
1518  {
1519  uint8_t measId = measIdIt->second.measId;
1520  NS_LOG_LOGIC (this << " found measId " << (uint32_t) measId << " referring to measObjectId " << (uint32_t) measObjectId);
1521  VarMeasReportListClear (measId);
1522  }
1523  }
1524  }
1525  else
1526  {
1527  NS_LOG_LOGIC ("measObjectId " << (uint32_t) measObjectId << " is new, adding entry");
1528  m_varMeasConfig.measObjectList[measObjectId] = *it;
1529  }
1530 
1531  }
1532 
1533  // 3GPP TS 36.331 section 5.5.2.6 Reporting configuration removal
1534  for (std::list<uint8_t>::iterator it = mc.reportConfigToRemoveList.begin ();
1535  it != mc.reportConfigToRemoveList.end ();
1536  ++it)
1537  {
1538  uint8_t reportConfigId = *it;
1539  NS_LOG_LOGIC (this << " deleting reportConfigId " << (uint32_t) reportConfigId);
1540  m_varMeasConfig.reportConfigList.erase (reportConfigId);
1541  std::map<uint8_t, LteRrcSap::MeasIdToAddMod>::iterator measIdIt = m_varMeasConfig.measIdList.begin ();
1542  while (measIdIt != m_varMeasConfig.measIdList.end ())
1543  {
1544  if (measIdIt->second.reportConfigId == reportConfigId)
1545  {
1546  uint8_t measId = measIdIt->second.measId;
1547  NS_ASSERT (measId == measIdIt->first);
1548  NS_LOG_LOGIC (this << " deleting measId " << (uint32_t) measId << " because referring to reportConfigId " << (uint32_t) reportConfigId);
1549  // note: postfix operator preserves iterator validity
1550  m_varMeasConfig.measIdList.erase (measIdIt++);
1551  VarMeasReportListClear (measId);
1552  }
1553  else
1554  {
1555  ++measIdIt;
1556  }
1557  }
1558 
1559  }
1560 
1561  // 3GPP TS 36.331 section 5.5.2.7 Reporting configuration addition/ modification
1562  for (std::list<LteRrcSap::ReportConfigToAddMod>::iterator it = mc.reportConfigToAddModList.begin ();
1563  it != mc.reportConfigToAddModList.end ();
1564  ++it)
1565  {
1566  // simplifying assumptions
1567  NS_ASSERT_MSG (it->reportConfigEutra.triggerType == LteRrcSap::ReportConfigEutra::EVENT,
1568  "only trigger type EVENT is supported");
1569 
1570  uint8_t reportConfigId = it->reportConfigId;
1571  std::map<uint8_t, LteRrcSap::ReportConfigToAddMod>::iterator reportConfigIt = m_varMeasConfig.reportConfigList.find (reportConfigId);
1572  if (reportConfigIt != m_varMeasConfig.reportConfigList.end ())
1573  {
1574  NS_LOG_LOGIC ("reportConfigId " << (uint32_t) reportConfigId << " exists, updating entry");
1575  m_varMeasConfig.reportConfigList[reportConfigId] = *it;
1576  for (std::map<uint8_t, LteRrcSap::MeasIdToAddMod>::iterator measIdIt
1577  = m_varMeasConfig.measIdList.begin ();
1578  measIdIt != m_varMeasConfig.measIdList.end ();
1579  ++measIdIt)
1580  {
1581  if (measIdIt->second.reportConfigId == reportConfigId)
1582  {
1583  uint8_t measId = measIdIt->second.measId;
1584  NS_LOG_LOGIC (this << " found measId " << (uint32_t) measId << " referring to reportConfigId " << (uint32_t) reportConfigId);
1585  VarMeasReportListClear (measId);
1586  }
1587  }
1588  }
1589  else
1590  {
1591  NS_LOG_LOGIC ("reportConfigId " << (uint32_t) reportConfigId << " is new, adding entry");
1592  m_varMeasConfig.reportConfigList[reportConfigId] = *it;
1593  }
1594 
1595  }
1596 
1597  // 3GPP TS 36.331 section 5.5.2.8 Quantity configuration
1598  if (mc.haveQuantityConfig)
1599  {
1600  NS_LOG_LOGIC (this << " setting quantityConfig");
1602  // we calculate here the coefficient a used for Layer 3 filtering, see 3GPP TS 36.331 section 5.5.3.2
1603  m_varMeasConfig.aRsrp = std::pow (0.5, mc.quantityConfig.filterCoefficientRSRP / 4.0);
1604  m_varMeasConfig.aRsrq = std::pow (0.5, mc.quantityConfig.filterCoefficientRSRQ / 4.0);
1605  NS_LOG_LOGIC (this << " new filter coefficients: aRsrp=" << m_varMeasConfig.aRsrp << ", aRsrq=" << m_varMeasConfig.aRsrq);
1606 
1607  for (std::map<uint8_t, LteRrcSap::MeasIdToAddMod>::iterator measIdIt
1608  = m_varMeasConfig.measIdList.begin ();
1609  measIdIt != m_varMeasConfig.measIdList.end ();
1610  ++measIdIt)
1611  {
1612  VarMeasReportListClear (measIdIt->second.measId);
1613  }
1614  }
1615 
1616  // 3GPP TS 36.331 section 5.5.2.2 Measurement identity removal
1617  for (std::list<uint8_t>::iterator it = mc.measIdToRemoveList.begin ();
1618  it != mc.measIdToRemoveList.end ();
1619  ++it)
1620  {
1621  uint8_t measId = *it;
1622  NS_LOG_LOGIC (this << " deleting measId " << (uint32_t) measId);
1623  m_varMeasConfig.measIdList.erase (measId);
1624  VarMeasReportListClear (measId);
1625 
1626  // removing time-to-trigger queues
1627  m_enteringTriggerQueue.erase (measId);
1628  m_leavingTriggerQueue.erase (measId);
1629  }
1630 
1631  // 3GPP TS 36.331 section 5.5.2.3 Measurement identity addition/ modification
1632  for (std::list<LteRrcSap::MeasIdToAddMod>::iterator it = mc.measIdToAddModList.begin ();
1633  it != mc.measIdToAddModList.end ();
1634  ++it)
1635  {
1636  NS_LOG_LOGIC (this << " measId " << (uint32_t) it->measId
1637  << " (measObjectId=" << (uint32_t) it->measObjectId
1638  << ", reportConfigId=" << (uint32_t) it->reportConfigId
1639  << ")");
1640  NS_ASSERT (m_varMeasConfig.measObjectList.find (it->measObjectId)
1641  != m_varMeasConfig.measObjectList.end ());
1642  NS_ASSERT (m_varMeasConfig.reportConfigList.find (it->reportConfigId)
1643  != m_varMeasConfig.reportConfigList.end ());
1644  m_varMeasConfig.measIdList[it->measId] = *it; // side effect: create new entry if not exists
1645  std::map<uint8_t, VarMeasReport>::iterator measReportIt = m_varMeasReportList.find (it->measId);
1646  if (measReportIt != m_varMeasReportList.end ())
1647  {
1648  measReportIt->second.periodicReportTimer.Cancel ();
1649  m_varMeasReportList.erase (measReportIt);
1650  }
1651  NS_ASSERT (m_varMeasConfig.reportConfigList.find (it->reportConfigId)
1652  ->second.reportConfigEutra.triggerType != LteRrcSap::ReportConfigEutra::PERIODICAL);
1653 
1654  // new empty queues for time-to-trigger
1655  std::list<PendingTrigger_t> s;
1656  m_enteringTriggerQueue[it->measId] = s;
1657  m_leavingTriggerQueue[it->measId] = s;
1658  }
1659 
1660  if (mc.haveMeasGapConfig)
1661  {
1662  NS_FATAL_ERROR ("measurement gaps are currently not supported");
1663  }
1664 
1665  if (mc.haveSmeasure)
1666  {
1667  NS_FATAL_ERROR ("s-measure is currently not supported");
1668  }
1669 
1670  if (mc.haveSpeedStatePars)
1671  {
1672  NS_FATAL_ERROR ("SpeedStatePars are currently not supported");
1673  }
1674 }
1675 
1676 void
1677 LteUeRrc::SaveUeMeasurements (uint16_t cellId, double rsrp, double rsrq,
1678  bool useLayer3Filtering)
1679 {
1680  NS_LOG_FUNCTION (this << cellId << rsrp << rsrq << useLayer3Filtering);
1681 
1682  std::map<uint16_t, MeasValues>::iterator storedMeasIt = m_storedMeasValues.find (cellId);
1683 
1684  if (storedMeasIt != m_storedMeasValues.end ())
1685  {
1686  if (useLayer3Filtering)
1687  {
1688  // F_n = (1-a) F_{n-1} + a M_n
1689  storedMeasIt->second.rsrp = (1 - m_varMeasConfig.aRsrp) * storedMeasIt->second.rsrp
1690  + m_varMeasConfig.aRsrp * rsrp;
1691 
1692  if (std::isnan (storedMeasIt->second.rsrq))
1693  {
1694  // the previous RSRQ measurements provided UE PHY are invalid
1695  storedMeasIt->second.rsrq = rsrq; // replace it with unfiltered value
1696  }
1697  else
1698  {
1699  storedMeasIt->second.rsrq = (1 - m_varMeasConfig.aRsrq) * storedMeasIt->second.rsrq
1700  + m_varMeasConfig.aRsrq * rsrq;
1701  }
1702  }
1703  else
1704  {
1705  storedMeasIt->second.rsrp = rsrp;
1706  storedMeasIt->second.rsrq = rsrq;
1707  }
1708  }
1709  else
1710  {
1711  // first value is always unfiltered
1712  MeasValues v;
1713  v.rsrp = rsrp;
1714  v.rsrq = rsrq;
1715  std::pair<uint16_t, MeasValues> val (cellId, v);
1716  std::pair<std::map<uint16_t, MeasValues>::iterator, bool>
1717  ret = m_storedMeasValues.insert (val);
1718  NS_ASSERT_MSG (ret.second == true, "element already existed");
1719  storedMeasIt = ret.first;
1720  }
1721 
1722  NS_LOG_DEBUG (this << " IMSI " << m_imsi << " state " << ToString (m_state)
1723  << ", measured cell " << m_cellId
1724  << ", new RSRP " << rsrp << " stored " << storedMeasIt->second.rsrp
1725  << ", new RSRQ " << rsrq << " stored " << storedMeasIt->second.rsrq);
1726  storedMeasIt->second.timestamp = Simulator::Now ();
1727 
1728 } // end of void SaveUeMeasurements
1729 
1730 void
1732 {
1733  NS_LOG_FUNCTION (this << (uint16_t) measId);
1734 
1735  std::map<uint8_t, LteRrcSap::MeasIdToAddMod>::iterator measIdIt =
1736  m_varMeasConfig.measIdList.find (measId);
1737  NS_ASSERT (measIdIt != m_varMeasConfig.measIdList.end ());
1738  NS_ASSERT (measIdIt->first == measIdIt->second.measId);
1739 
1740  std::map<uint8_t, LteRrcSap::ReportConfigToAddMod>::iterator
1741  reportConfigIt = m_varMeasConfig.reportConfigList.find (measIdIt->second.reportConfigId);
1742  NS_ASSERT (reportConfigIt != m_varMeasConfig.reportConfigList.end ());
1743  LteRrcSap::ReportConfigEutra& reportConfigEutra = reportConfigIt->second.reportConfigEutra;
1744 
1745  std::map<uint8_t, LteRrcSap::MeasObjectToAddMod>::iterator
1746  measObjectIt = m_varMeasConfig.measObjectList.find (measIdIt->second.measObjectId);
1747  NS_ASSERT (measObjectIt != m_varMeasConfig.measObjectList.end ());
1748  LteRrcSap::MeasObjectEutra& measObjectEutra = measObjectIt->second.measObjectEutra;
1749 
1750  std::map<uint8_t, VarMeasReport>::iterator
1751  measReportIt = m_varMeasReportList.find (measId);
1752  bool isMeasIdInReportList = (measReportIt != m_varMeasReportList.end ());
1753 
1754  // we don't check the purpose field, as it is only included for
1755  // triggerType == periodical, which is not supported
1756  NS_ASSERT_MSG (reportConfigEutra.triggerType
1758  "only triggerType == event is supported");
1759  // only EUTRA is supported, no need to check for it
1760 
1761  NS_LOG_LOGIC (this << " considering measId " << (uint32_t) measId);
1762  bool eventEntryCondApplicable = false;
1763  bool eventLeavingCondApplicable = false;
1764  ConcernedCells_t concernedCellsEntry;
1765  ConcernedCells_t concernedCellsLeaving;
1766 
1767  switch (reportConfigEutra.eventId)
1768  {
1770  {
1771  /*
1772  * Event A1 (Serving becomes better than threshold)
1773  * Please refer to 3GPP TS 36.331 Section 5.5.4.2
1774  */
1775 
1776  double ms; // Ms, the measurement result of the serving cell
1777  double thresh; // Thresh, the threshold parameter for this event
1778  // Hys, the hysteresis parameter for this event.
1779  double hys = EutranMeasurementMapping::IeValue2ActualHysteresis (reportConfigEutra.hysteresis);
1780 
1781  switch (reportConfigEutra.triggerQuantity)
1782  {
1784  ms = m_storedMeasValues[m_cellId].rsrp;
1785  NS_ASSERT (reportConfigEutra.threshold1.choice
1787  thresh = EutranMeasurementMapping::RsrpRange2Dbm (reportConfigEutra.threshold1.range);
1788  break;
1790  ms = m_storedMeasValues[m_cellId].rsrq;
1791  NS_ASSERT (reportConfigEutra.threshold1.choice
1793  thresh = EutranMeasurementMapping::RsrqRange2Db (reportConfigEutra.threshold1.range);
1794  break;
1795  default:
1796  NS_FATAL_ERROR ("unsupported triggerQuantity");
1797  break;
1798  }
1799 
1800  // Inequality A1-1 (Entering condition): Ms - Hys > Thresh
1801  bool entryCond = ms - hys > thresh;
1802 
1803  if (entryCond)
1804  {
1805  if (!isMeasIdInReportList)
1806  {
1807  concernedCellsEntry.push_back (m_cellId);
1808  eventEntryCondApplicable = true;
1809  }
1810  else
1811  {
1812  /*
1813  * This is to check that the triggered cell recorded in the
1814  * VarMeasReportList is the serving cell.
1815  */
1816  NS_ASSERT (measReportIt->second.cellsTriggeredList.find (m_cellId)
1817  != measReportIt->second.cellsTriggeredList.end ());
1818  }
1819  }
1820  else if (reportConfigEutra.timeToTrigger > 0)
1821  {
1822  CancelEnteringTrigger (measId);
1823  }
1824 
1825  // Inequality A1-2 (Leaving condition): Ms + Hys < Thresh
1826  bool leavingCond = ms + hys < thresh;
1827 
1828  if (leavingCond)
1829  {
1830  if (isMeasIdInReportList)
1831  {
1832  /*
1833  * This is to check that the triggered cell recorded in the
1834  * VarMeasReportList is the serving cell.
1835  */
1836  NS_ASSERT (measReportIt->second.cellsTriggeredList.find (m_cellId)
1837  != measReportIt->second.cellsTriggeredList.end ());
1838  concernedCellsLeaving.push_back (m_cellId);
1839  eventLeavingCondApplicable = true;
1840  }
1841  }
1842  else if (reportConfigEutra.timeToTrigger > 0)
1843  {
1844  CancelLeavingTrigger (measId);
1845  }
1846 
1847  NS_LOG_LOGIC (this << " event A1: serving cell " << m_cellId
1848  << " ms=" << ms << " thresh=" << thresh
1849  << " entryCond=" << entryCond
1850  << " leavingCond=" << leavingCond);
1851 
1852  } // end of case LteRrcSap::ReportConfigEutra::EVENT_A1
1853 
1854  break;
1855 
1857  {
1858  /*
1859  * Event A2 (Serving becomes worse than threshold)
1860  * Please refer to 3GPP TS 36.331 Section 5.5.4.3
1861  */
1862 
1863  double ms; // Ms, the measurement result of the serving cell
1864  double thresh; // Thresh, the threshold parameter for this event
1865  // Hys, the hysteresis parameter for this event.
1866  double hys = EutranMeasurementMapping::IeValue2ActualHysteresis (reportConfigEutra.hysteresis);
1867 
1868  switch (reportConfigEutra.triggerQuantity)
1869  {
1871  ms = m_storedMeasValues[m_cellId].rsrp;
1872  NS_ASSERT (reportConfigEutra.threshold1.choice
1874  thresh = EutranMeasurementMapping::RsrpRange2Dbm (reportConfigEutra.threshold1.range);
1875  break;
1877  ms = m_storedMeasValues[m_cellId].rsrq;
1878  NS_ASSERT (reportConfigEutra.threshold1.choice
1880  thresh = EutranMeasurementMapping::RsrqRange2Db (reportConfigEutra.threshold1.range);
1881  break;
1882  default:
1883  NS_FATAL_ERROR ("unsupported triggerQuantity");
1884  break;
1885  }
1886 
1887  // Inequality A2-1 (Entering condition): Ms + Hys < Thresh
1888  bool entryCond = ms + hys < thresh;
1889 
1890  if (entryCond)
1891  {
1892  if (!isMeasIdInReportList)
1893  {
1894  concernedCellsEntry.push_back (m_cellId);
1895  eventEntryCondApplicable = true;
1896  }
1897  else
1898  {
1899  /*
1900  * This is to check that the triggered cell recorded in the
1901  * VarMeasReportList is the serving cell.
1902  */
1903  NS_ASSERT (measReportIt->second.cellsTriggeredList.find (m_cellId)
1904  != measReportIt->second.cellsTriggeredList.end ());
1905  }
1906  }
1907  else if (reportConfigEutra.timeToTrigger > 0)
1908  {
1909  CancelEnteringTrigger (measId);
1910  }
1911 
1912  // Inequality A2-2 (Leaving condition): Ms - Hys > Thresh
1913  bool leavingCond = ms - hys > thresh;
1914 
1915  if (leavingCond)
1916  {
1917  if (isMeasIdInReportList)
1918  {
1919  /*
1920  * This is to check that the triggered cell recorded in the
1921  * VarMeasReportList is the serving cell.
1922  */
1923  NS_ASSERT (measReportIt->second.cellsTriggeredList.find (m_cellId)
1924  != measReportIt->second.cellsTriggeredList.end ());
1925  concernedCellsLeaving.push_back (m_cellId);
1926  eventLeavingCondApplicable = true;
1927  }
1928  }
1929  else if (reportConfigEutra.timeToTrigger > 0)
1930  {
1931  CancelLeavingTrigger (measId);
1932  }
1933 
1934  NS_LOG_LOGIC (this << " event A2: serving cell " << m_cellId
1935  << " ms=" << ms << " thresh=" << thresh
1936  << " entryCond=" << entryCond
1937  << " leavingCond=" << leavingCond);
1938 
1939  } // end of case LteRrcSap::ReportConfigEutra::EVENT_A2
1940 
1941  break;
1942 
1944  {
1945  /*
1946  * Event A3 (Neighbour becomes offset better than PCell)
1947  * Please refer to 3GPP TS 36.331 Section 5.5.4.4
1948  */
1949 
1950  double mn; // Mn, the measurement result of the neighbouring cell
1951  double ofn = measObjectEutra.offsetFreq; // Ofn, the frequency specific offset of the frequency of the
1952  double ocn = 0.0; // Ocn, the cell specific offset of the neighbour cell
1953  double mp; // Mp, the measurement result of the PCell
1954  double ofp = measObjectEutra.offsetFreq; // Ofp, the frequency specific offset of the primary frequency
1955  double ocp = 0.0; // Ocp, the cell specific offset of the PCell
1956  // Off, the offset parameter for this event.
1957  double off = EutranMeasurementMapping::IeValue2ActualA3Offset (reportConfigEutra.a3Offset);
1958  // Hys, the hysteresis parameter for this event.
1959  double hys = EutranMeasurementMapping::IeValue2ActualHysteresis (reportConfigEutra.hysteresis);
1960 
1961  switch (reportConfigEutra.triggerQuantity)
1962  {
1964  mp = m_storedMeasValues[m_cellId].rsrp;
1965  NS_ASSERT (reportConfigEutra.threshold1.choice
1967  break;
1969  mp = m_storedMeasValues[m_cellId].rsrq;
1970  NS_ASSERT (reportConfigEutra.threshold1.choice
1972  break;
1973  default:
1974  NS_FATAL_ERROR ("unsupported triggerQuantity");
1975  break;
1976  }
1977 
1978  for (std::map<uint16_t, MeasValues>::iterator storedMeasIt = m_storedMeasValues.begin ();
1979  storedMeasIt != m_storedMeasValues.end ();
1980  ++storedMeasIt)
1981  {
1982  uint16_t cellId = storedMeasIt->first;
1983  if (cellId == m_cellId)
1984  {
1985  continue;
1986  }
1987 
1988  switch (reportConfigEutra.triggerQuantity)
1989  {
1991  mn = storedMeasIt->second.rsrp;
1992  break;
1994  mn = storedMeasIt->second.rsrq;
1995  break;
1996  default:
1997  NS_FATAL_ERROR ("unsupported triggerQuantity");
1998  break;
1999  }
2000 
2001  bool hasTriggered = isMeasIdInReportList
2002  && (measReportIt->second.cellsTriggeredList.find (cellId)
2003  != measReportIt->second.cellsTriggeredList.end ());
2004 
2005  // Inequality A3-1 (Entering condition): Mn + Ofn + Ocn - Hys > Mp + Ofp + Ocp + Off
2006  bool entryCond = mn + ofn + ocn - hys > mp + ofp + ocp + off;
2007 
2008  if (entryCond)
2009  {
2010  if (!hasTriggered)
2011  {
2012  concernedCellsEntry.push_back (cellId);
2013  eventEntryCondApplicable = true;
2014  }
2015  }
2016  else if (reportConfigEutra.timeToTrigger > 0)
2017  {
2018  CancelEnteringTrigger (measId, cellId);
2019  }
2020 
2021  // Inequality A3-2 (Leaving condition): Mn + Ofn + Ocn + Hys < Mp + Ofp + Ocp + Off
2022  bool leavingCond = mn + ofn + ocn + hys < mp + ofp + ocp + off;
2023 
2024  if (leavingCond)
2025  {
2026  if (hasTriggered)
2027  {
2028  concernedCellsLeaving.push_back (cellId);
2029  eventLeavingCondApplicable = true;
2030  }
2031  }
2032  else if (reportConfigEutra.timeToTrigger > 0)
2033  {
2034  CancelLeavingTrigger (measId, cellId);
2035  }
2036 
2037  NS_LOG_LOGIC (this << " event A3: neighbor cell " << cellId
2038  << " mn=" << mn << " mp=" << mp << " offset=" << off
2039  << " entryCond=" << entryCond
2040  << " leavingCond=" << leavingCond);
2041 
2042  } // end of for (storedMeasIt)
2043 
2044  } // end of case LteRrcSap::ReportConfigEutra::EVENT_A3
2045 
2046  break;
2047 
2049  {
2050  /*
2051  * Event A4 (Neighbour becomes better than threshold)
2052  * Please refer to 3GPP TS 36.331 Section 5.5.4.5
2053  */
2054 
2055  double mn; // Mn, the measurement result of the neighbouring cell
2056  double ofn = measObjectEutra.offsetFreq; // Ofn, the frequency specific offset of the frequency of the
2057  double ocn = 0.0; // Ocn, the cell specific offset of the neighbour cell
2058  double thresh; // Thresh, the threshold parameter for this event
2059  // Hys, the hysteresis parameter for this event.
2060  double hys = EutranMeasurementMapping::IeValue2ActualHysteresis (reportConfigEutra.hysteresis);
2061 
2062  switch (reportConfigEutra.triggerQuantity)
2063  {
2065  NS_ASSERT (reportConfigEutra.threshold1.choice
2067  thresh = EutranMeasurementMapping::RsrpRange2Dbm (reportConfigEutra.threshold1.range);
2068  break;
2070  NS_ASSERT (reportConfigEutra.threshold1.choice
2072  thresh = EutranMeasurementMapping::RsrqRange2Db (reportConfigEutra.threshold1.range);
2073  break;
2074  default:
2075  NS_FATAL_ERROR ("unsupported triggerQuantity");
2076  break;
2077  }
2078 
2079  for (std::map<uint16_t, MeasValues>::iterator storedMeasIt = m_storedMeasValues.begin ();
2080  storedMeasIt != m_storedMeasValues.end ();
2081  ++storedMeasIt)
2082  {
2083  uint16_t cellId = storedMeasIt->first;
2084  if (cellId == m_cellId)
2085  {
2086  continue;
2087  }
2088 
2089  switch (reportConfigEutra.triggerQuantity)
2090  {
2092  mn = storedMeasIt->second.rsrp;
2093  break;
2095  mn = storedMeasIt->second.rsrq;
2096  break;
2097  default:
2098  NS_FATAL_ERROR ("unsupported triggerQuantity");
2099  break;
2100  }
2101 
2102  bool hasTriggered = isMeasIdInReportList
2103  && (measReportIt->second.cellsTriggeredList.find (cellId)
2104  != measReportIt->second.cellsTriggeredList.end ());
2105 
2106  // Inequality A4-1 (Entering condition): Mn + Ofn + Ocn - Hys > Thresh
2107  bool entryCond = mn + ofn + ocn - hys > thresh;
2108 
2109  if (entryCond)
2110  {
2111  if (!hasTriggered)
2112  {
2113  concernedCellsEntry.push_back (cellId);
2114  eventEntryCondApplicable = true;
2115  }
2116  }
2117  else if (reportConfigEutra.timeToTrigger > 0)
2118  {
2119  CancelEnteringTrigger (measId, cellId);
2120  }
2121 
2122  // Inequality A4-2 (Leaving condition): Mn + Ofn + Ocn + Hys < Thresh
2123  bool leavingCond = mn + ofn + ocn + hys < thresh;
2124 
2125  if (leavingCond)
2126  {
2127  if (hasTriggered)
2128  {
2129  concernedCellsLeaving.push_back (cellId);
2130  eventLeavingCondApplicable = true;
2131  }
2132  }
2133  else if (reportConfigEutra.timeToTrigger > 0)
2134  {
2135  CancelLeavingTrigger (measId, cellId);
2136  }
2137 
2138  NS_LOG_LOGIC (this << " event A4: neighbor cell " << cellId
2139  << " mn=" << mn << " thresh=" << thresh
2140  << " entryCond=" << entryCond
2141  << " leavingCond=" << leavingCond);
2142 
2143  } // end of for (storedMeasIt)
2144 
2145  } // end of case LteRrcSap::ReportConfigEutra::EVENT_A4
2146 
2147  break;
2148 
2150  {
2151  /*
2152  * Event A5 (PCell becomes worse than threshold1 and neighbour
2153  * becomes better than threshold2)
2154  * Please refer to 3GPP TS 36.331 Section 5.5.4.6
2155  */
2156 
2157  double mp; // Mp, the measurement result of the PCell
2158  double mn; // Mn, the measurement result of the neighbouring cell
2159  double ofn = measObjectEutra.offsetFreq; // Ofn, the frequency specific offset of the frequency of the
2160  double ocn = 0.0; // Ocn, the cell specific offset of the neighbour cell
2161  double thresh1; // Thresh1, the threshold parameter for this event
2162  double thresh2; // Thresh2, the threshold parameter for this event
2163  // Hys, the hysteresis parameter for this event.
2164  double hys = EutranMeasurementMapping::IeValue2ActualHysteresis (reportConfigEutra.hysteresis);
2165 
2166  switch (reportConfigEutra.triggerQuantity)
2167  {
2169  mp = m_storedMeasValues[m_cellId].rsrp;
2170  NS_ASSERT (reportConfigEutra.threshold1.choice
2172  NS_ASSERT (reportConfigEutra.threshold2.choice
2174  thresh1 = EutranMeasurementMapping::RsrpRange2Dbm (reportConfigEutra.threshold1.range);
2175  thresh2 = EutranMeasurementMapping::RsrpRange2Dbm (reportConfigEutra.threshold2.range);
2176  break;
2178  mp = m_storedMeasValues[m_cellId].rsrq;
2179  NS_ASSERT (reportConfigEutra.threshold1.choice
2181  NS_ASSERT (reportConfigEutra.threshold2.choice
2183  thresh1 = EutranMeasurementMapping::RsrqRange2Db (reportConfigEutra.threshold1.range);
2184  thresh2 = EutranMeasurementMapping::RsrqRange2Db (reportConfigEutra.threshold2.range);
2185  break;
2186  default:
2187  NS_FATAL_ERROR ("unsupported triggerQuantity");
2188  break;
2189  }
2190 
2191  // Inequality A5-1 (Entering condition 1): Mp + Hys < Thresh1
2192  bool entryCond = mp + hys < thresh1;
2193 
2194  if (entryCond)
2195  {
2196  for (std::map<uint16_t, MeasValues>::iterator storedMeasIt = m_storedMeasValues.begin ();
2197  storedMeasIt != m_storedMeasValues.end ();
2198  ++storedMeasIt)
2199  {
2200  uint16_t cellId = storedMeasIt->first;
2201  if (cellId == m_cellId)
2202  {
2203  continue;
2204  }
2205 
2206  switch (reportConfigEutra.triggerQuantity)
2207  {
2209  mn = storedMeasIt->second.rsrp;
2210  break;
2212  mn = storedMeasIt->second.rsrq;
2213  break;
2214  default:
2215  NS_FATAL_ERROR ("unsupported triggerQuantity");
2216  break;
2217  }
2218 
2219  bool hasTriggered = isMeasIdInReportList
2220  && (measReportIt->second.cellsTriggeredList.find (cellId)
2221  != measReportIt->second.cellsTriggeredList.end ());
2222 
2223  // Inequality A5-2 (Entering condition 2): Mn + Ofn + Ocn - Hys > Thresh2
2224 
2225  entryCond = mn + ofn + ocn - hys > thresh2;
2226 
2227  if (entryCond)
2228  {
2229  if (!hasTriggered)
2230  {
2231  concernedCellsEntry.push_back (cellId);
2232  eventEntryCondApplicable = true;
2233  }
2234  }
2235  else if (reportConfigEutra.timeToTrigger > 0)
2236  {
2237  CancelEnteringTrigger (measId, cellId);
2238  }
2239 
2240  NS_LOG_LOGIC (this << " event A5: neighbor cell " << cellId
2241  << " mn=" << mn << " mp=" << mp
2242  << " thresh2=" << thresh2
2243  << " thresh1=" << thresh1
2244  << " entryCond=" << entryCond);
2245 
2246  } // end of for (storedMeasIt)
2247 
2248  } // end of if (entryCond)
2249  else
2250  {
2251  NS_LOG_LOGIC (this << " event A5: serving cell " << m_cellId
2252  << " mp=" << mp << " thresh1=" << thresh1
2253  << " entryCond=" << entryCond);
2254 
2255  if (reportConfigEutra.timeToTrigger > 0)
2256  {
2257  CancelEnteringTrigger (measId);
2258  }
2259  }
2260 
2261  if (isMeasIdInReportList)
2262  {
2263  // Inequality A5-3 (Leaving condition 1): Mp - Hys > Thresh1
2264  bool leavingCond = mp - hys > thresh1;
2265 
2266  if (leavingCond)
2267  {
2268  if (reportConfigEutra.timeToTrigger == 0)
2269  {
2270  // leaving condition #2 does not have to be checked
2271 
2272  for (std::map<uint16_t, MeasValues>::iterator storedMeasIt = m_storedMeasValues.begin ();
2273  storedMeasIt != m_storedMeasValues.end ();
2274  ++storedMeasIt)
2275  {
2276  uint16_t cellId = storedMeasIt->first;
2277  if (cellId == m_cellId)
2278  {
2279  continue;
2280  }
2281 
2282  if (measReportIt->second.cellsTriggeredList.find (cellId)
2283  != measReportIt->second.cellsTriggeredList.end ())
2284  {
2285  concernedCellsLeaving.push_back (cellId);
2286  eventLeavingCondApplicable = true;
2287  }
2288  }
2289  } // end of if (reportConfigEutra.timeToTrigger == 0)
2290  else
2291  {
2292  // leaving condition #2 has to be checked to cancel time-to-trigger
2293 
2294  for (std::map<uint16_t, MeasValues>::iterator storedMeasIt = m_storedMeasValues.begin ();
2295  storedMeasIt != m_storedMeasValues.end ();
2296  ++storedMeasIt)
2297  {
2298  uint16_t cellId = storedMeasIt->first;
2299  if (cellId == m_cellId)
2300  {
2301  continue;
2302  }
2303 
2304  if (measReportIt->second.cellsTriggeredList.find (cellId)
2305  != measReportIt->second.cellsTriggeredList.end ())
2306  {
2307  switch (reportConfigEutra.triggerQuantity)
2308  {
2310  mn = storedMeasIt->second.rsrp;
2311  break;
2313  mn = storedMeasIt->second.rsrq;
2314  break;
2315  default:
2316  NS_FATAL_ERROR ("unsupported triggerQuantity");
2317  break;
2318  }
2319 
2320  // Inequality A5-4 (Leaving condition 2): Mn + Ofn + Ocn + Hys < Thresh2
2321 
2322  leavingCond = mn + ofn + ocn + hys < thresh2;
2323 
2324  if (!leavingCond)
2325  {
2326  CancelLeavingTrigger (measId, cellId);
2327  }
2328 
2329  /*
2330  * Whatever the result of leaving condition #2, this
2331  * cell is still "in", because leaving condition #1
2332  * is already true.
2333  */
2334  concernedCellsLeaving.push_back (cellId);
2335  eventLeavingCondApplicable = true;
2336 
2337  NS_LOG_LOGIC (this << " event A5: neighbor cell " << cellId
2338  << " mn=" << mn << " mp=" << mp
2339  << " thresh2=" << thresh2
2340  << " thresh1=" << thresh1
2341  << " leavingCond=" << leavingCond);
2342 
2343  } // end of if (measReportIt->second.cellsTriggeredList.find (cellId)
2344  // != measReportIt->second.cellsTriggeredList.end ())
2345 
2346  } // end of for (storedMeasIt)
2347 
2348  } // end of else of if (reportConfigEutra.timeToTrigger == 0)
2349 
2350  NS_LOG_LOGIC (this << " event A5: serving cell " << m_cellId
2351  << " mp=" << mp << " thresh1=" << thresh1
2352  << " leavingCond=" << leavingCond);
2353 
2354  } // end of if (leavingCond)
2355  else
2356  {
2357  if (reportConfigEutra.timeToTrigger > 0)
2358  {
2359  CancelLeavingTrigger (measId);
2360  }
2361 
2362  // check leaving condition #2
2363 
2364  for (std::map<uint16_t, MeasValues>::iterator storedMeasIt = m_storedMeasValues.begin ();
2365  storedMeasIt != m_storedMeasValues.end ();
2366  ++storedMeasIt)
2367  {
2368  uint16_t cellId = storedMeasIt->first;
2369  if (cellId == m_cellId)
2370  {
2371  continue;
2372  }
2373 
2374  if (measReportIt->second.cellsTriggeredList.find (cellId)
2375  != measReportIt->second.cellsTriggeredList.end ())
2376  {
2377  switch (reportConfigEutra.triggerQuantity)
2378  {
2380  mn = storedMeasIt->second.rsrp;
2381  break;
2383  mn = storedMeasIt->second.rsrq;
2384  break;
2385  default:
2386  NS_FATAL_ERROR ("unsupported triggerQuantity");
2387  break;
2388  }
2389 
2390  // Inequality A5-4 (Leaving condition 2): Mn + Ofn + Ocn + Hys < Thresh2
2391  leavingCond = mn + ofn + ocn + hys < thresh2;
2392 
2393  if (leavingCond)
2394  {
2395  concernedCellsLeaving.push_back (cellId);
2396  eventLeavingCondApplicable = true;
2397  }
2398 
2399  NS_LOG_LOGIC (this << " event A5: neighbor cell " << cellId
2400  << " mn=" << mn << " mp=" << mp
2401  << " thresh2=" << thresh2
2402  << " thresh1=" << thresh1
2403  << " leavingCond=" << leavingCond);
2404 
2405  } // end of if (measReportIt->second.cellsTriggeredList.find (cellId)
2406  // != measReportIt->second.cellsTriggeredList.end ())
2407 
2408  } // end of for (storedMeasIt)
2409 
2410  } // end of else of if (leavingCond)
2411 
2412  } // end of if (isMeasIdInReportList)
2413 
2414  } // end of case LteRrcSap::ReportConfigEutra::EVENT_A5
2415 
2416  break;
2417 
2418  default:
2419  NS_FATAL_ERROR ("unsupported eventId " << reportConfigEutra.eventId);
2420  break;
2421 
2422  } // switch (event type)
2423 
2424  NS_LOG_LOGIC (this << " eventEntryCondApplicable=" << eventEntryCondApplicable
2425  << " eventLeavingCondApplicable=" << eventLeavingCondApplicable);
2426 
2427  if (eventEntryCondApplicable)
2428  {
2429  if (reportConfigEutra.timeToTrigger == 0)
2430  {
2431  VarMeasReportListAdd (measId, concernedCellsEntry);
2432  }
2433  else
2434  {
2435  PendingTrigger_t t;
2436  t.measId = measId;
2437  t.concernedCells = concernedCellsEntry;
2438  t.timer = Simulator::Schedule (MilliSeconds (reportConfigEutra.timeToTrigger),
2440  measId, concernedCellsEntry);
2441  std::map<uint8_t, std::list<PendingTrigger_t> >::iterator
2442  enteringTriggerIt = m_enteringTriggerQueue.find (measId);
2443  NS_ASSERT (enteringTriggerIt != m_enteringTriggerQueue.end ());
2444  enteringTriggerIt->second.push_back (t);
2445  }
2446  }
2447 
2448  if (eventLeavingCondApplicable)
2449  {
2450  // reportOnLeave will only be set when eventId = eventA3
2451  bool reportOnLeave = (reportConfigEutra.eventId == LteRrcSap::ReportConfigEutra::EVENT_A3)
2452  && reportConfigEutra.reportOnLeave;
2453 
2454  if (reportConfigEutra.timeToTrigger == 0)
2455  {
2456  VarMeasReportListErase (measId, concernedCellsLeaving, reportOnLeave);
2457  }
2458  else
2459  {
2460  PendingTrigger_t t;
2461  t.measId = measId;
2462  t.concernedCells = concernedCellsLeaving;
2463  t.timer = Simulator::Schedule (MilliSeconds (reportConfigEutra.timeToTrigger),
2465  measId, concernedCellsLeaving, reportOnLeave);
2466  std::map<uint8_t, std::list<PendingTrigger_t> >::iterator
2467  leavingTriggerIt = m_leavingTriggerQueue.find (measId);
2468  NS_ASSERT (leavingTriggerIt != m_leavingTriggerQueue.end ());
2469  leavingTriggerIt->second.push_back (t);
2470  }
2471  }
2472 
2473 } // end of void LteUeRrc::MeasurementReportTriggering (uint8_t measId)
2474 
2475 void
2477 {
2478  NS_LOG_FUNCTION (this << (uint16_t) measId);
2479 
2480  std::map<uint8_t, std::list<PendingTrigger_t> >::iterator
2481  it1 = m_enteringTriggerQueue.find (measId);
2482  NS_ASSERT (it1 != m_enteringTriggerQueue.end ());
2483 
2484  if (!it1->second.empty ())
2485  {
2486  std::list<PendingTrigger_t>::iterator it2;
2487  for (it2 = it1->second.begin (); it2 != it1->second.end (); ++it2)
2488  {
2489  NS_ASSERT (it2->measId == measId);
2490  NS_LOG_LOGIC (this << " canceling entering time-to-trigger event at "
2491  << Simulator::GetDelayLeft (it2->timer).GetSeconds ());
2492  Simulator::Cancel (it2->timer);
2493  }
2494 
2495  it1->second.clear ();
2496  }
2497 }
2498 
2499 void
2500 LteUeRrc::CancelEnteringTrigger (uint8_t measId, uint16_t cellId)
2501 {
2502  NS_LOG_FUNCTION (this << (uint16_t) measId << cellId);
2503 
2504  std::map<uint8_t, std::list<PendingTrigger_t> >::iterator
2505  it1 = m_enteringTriggerQueue.find (measId);
2506  NS_ASSERT (it1 != m_enteringTriggerQueue.end ());
2507 
2508  std::list<PendingTrigger_t>::iterator it2 = it1->second.begin ();
2509  while (it2 != it1->second.end ())
2510  {
2511  NS_ASSERT (it2->measId == measId);
2512 
2513  ConcernedCells_t::iterator it3;
2514  for (it3 = it2->concernedCells.begin ();
2515  it3 != it2->concernedCells.end (); ++it3)
2516  {
2517  if (*it3 == cellId)
2518  {
2519  it3 = it2->concernedCells.erase (it3);
2520  }
2521  }
2522 
2523  if (it2->concernedCells.empty ())
2524  {
2525  NS_LOG_LOGIC (this << " canceling entering time-to-trigger event at "
2526  << Simulator::GetDelayLeft (it2->timer).GetSeconds ());
2527  Simulator::Cancel (it2->timer);
2528  it2 = it1->second.erase (it2);
2529  }
2530  else
2531  {
2532  it2++;
2533  }
2534  }
2535 }
2536 
2537 void
2539 {
2540  NS_LOG_FUNCTION (this << (uint16_t) measId);
2541 
2542  std::map<uint8_t, std::list<PendingTrigger_t> >::iterator
2543  it1 = m_leavingTriggerQueue.find (measId);
2544  NS_ASSERT (it1 != m_leavingTriggerQueue.end ());
2545 
2546  if (!it1->second.empty ())
2547  {
2548  std::list<PendingTrigger_t>::iterator it2;
2549  for (it2 = it1->second.begin (); it2 != it1->second.end (); ++it2)
2550  {
2551  NS_ASSERT (it2->measId == measId);
2552  NS_LOG_LOGIC (this << " canceling leaving time-to-trigger event at "
2553  << Simulator::GetDelayLeft (it2->timer).GetSeconds ());
2554  Simulator::Cancel (it2->timer);
2555  }
2556 
2557  it1->second.clear ();
2558  }
2559 }
2560 
2561 void
2562 LteUeRrc::CancelLeavingTrigger (uint8_t measId, uint16_t cellId)
2563 {
2564  NS_LOG_FUNCTION (this << (uint16_t) measId << cellId);
2565 
2566  std::map<uint8_t, std::list<PendingTrigger_t> >::iterator
2567  it1 = m_leavingTriggerQueue.find (measId);
2568  NS_ASSERT (it1 != m_leavingTriggerQueue.end ());
2569 
2570  std::list<PendingTrigger_t>::iterator it2 = it1->second.begin ();
2571  while (it2 != it1->second.end ())
2572  {
2573  NS_ASSERT (it2->measId == measId);
2574 
2575  ConcernedCells_t::iterator it3;
2576  for (it3 = it2->concernedCells.begin ();
2577  it3 != it2->concernedCells.end (); ++it3)
2578  {
2579  if (*it3 == cellId)
2580  {
2581  it3 = it2->concernedCells.erase (it3);
2582  }
2583  }
2584 
2585  if (it2->concernedCells.empty ())
2586  {
2587  NS_LOG_LOGIC (this << " canceling leaving time-to-trigger event at "
2588  << Simulator::GetDelayLeft (it2->timer).GetSeconds ());
2589  Simulator::Cancel (it2->timer);
2590  it2 = it1->second.erase (it2);
2591  }
2592  else
2593  {
2594  it2++;
2595  }
2596  }
2597 }
2598 
2599 void
2600 LteUeRrc::VarMeasReportListAdd (uint8_t measId, ConcernedCells_t enteringCells)
2601 {
2602  NS_LOG_FUNCTION (this << (uint16_t) measId);
2603  NS_ASSERT (!enteringCells.empty ());
2604 
2605  std::map<uint8_t, VarMeasReport>::iterator
2606  measReportIt = m_varMeasReportList.find (measId);
2607 
2608  if (measReportIt == m_varMeasReportList.end ())
2609  {
2610  VarMeasReport r;
2611  r.measId = measId;
2612  std::pair<uint8_t, VarMeasReport> val (measId, r);
2613  std::pair<std::map<uint8_t, VarMeasReport>::iterator, bool>
2614  ret = m_varMeasReportList.insert (val);
2615  NS_ASSERT_MSG (ret.second == true, "element already existed");
2616  measReportIt = ret.first;
2617  }
2618 
2619  NS_ASSERT (measReportIt != m_varMeasReportList.end ());
2620 
2621  for (ConcernedCells_t::const_iterator it = enteringCells.begin ();
2622  it != enteringCells.end ();
2623  ++it)
2624  {
2625  measReportIt->second.cellsTriggeredList.insert (*it);
2626  }
2627 
2628  NS_ASSERT (!measReportIt->second.cellsTriggeredList.empty ());
2629  measReportIt->second.numberOfReportsSent = 0;
2630  measReportIt->second.periodicReportTimer
2633  this, measId);
2634 
2635  std::map<uint8_t, std::list<PendingTrigger_t> >::iterator
2636  enteringTriggerIt = m_enteringTriggerQueue.find (measId);
2637  NS_ASSERT (enteringTriggerIt != m_enteringTriggerQueue.end ());
2638  if (!enteringTriggerIt->second.empty ())
2639  {
2640  /*
2641  * Assumptions at this point:
2642  * - the call to this function was delayed by time-to-trigger;
2643  * - the time-to-trigger delay is fixed (not adaptive/dynamic); and
2644  * - the first element in the list is associated with this function call.
2645  */
2646  enteringTriggerIt->second.pop_front ();
2647 
2648  if (!enteringTriggerIt->second.empty ())
2649  {
2650  /*
2651  * To prevent the same set of cells triggering again in the future,
2652  * we clean up the time-to-trigger queue. This case might occur when
2653  * time-to-trigger > 200 ms.
2654  */
2655  for (ConcernedCells_t::const_iterator it = enteringCells.begin ();
2656  it != enteringCells.end (); ++it)
2657  {
2658  CancelEnteringTrigger (measId, *it);
2659  }
2660  }
2661 
2662  } // end of if (!enteringTriggerIt->second.empty ())
2663 
2664 } // end of LteUeRrc::VarMeasReportListAdd
2665 
2666 void
2668  bool reportOnLeave)
2669 {
2670  NS_LOG_FUNCTION (this << (uint16_t) measId);
2671  NS_ASSERT (!leavingCells.empty ());
2672 
2673  std::map<uint8_t, VarMeasReport>::iterator
2674  measReportIt = m_varMeasReportList.find (measId);
2675  NS_ASSERT (measReportIt != m_varMeasReportList.end ());
2676 
2677  for (ConcernedCells_t::const_iterator it = leavingCells.begin ();
2678  it != leavingCells.end ();
2679  ++it)
2680  {
2681  measReportIt->second.cellsTriggeredList.erase (*it);
2682  }
2683 
2684  if (reportOnLeave)
2685  {
2686  // runs immediately without UE_MEASUREMENT_REPORT_DELAY
2687  SendMeasurementReport (measId);
2688  }
2689 
2690  if (measReportIt->second.cellsTriggeredList.empty ())
2691  {
2692  measReportIt->second.periodicReportTimer.Cancel ();
2693  m_varMeasReportList.erase (measReportIt);
2694  }
2695 
2696  std::map<uint8_t, std::list<PendingTrigger_t> >::iterator
2697  leavingTriggerIt = m_leavingTriggerQueue.find (measId);
2698  NS_ASSERT (leavingTriggerIt != m_leavingTriggerQueue.end ());
2699  if (!leavingTriggerIt->second.empty ())
2700  {
2701  /*
2702  * Assumptions at this point:
2703  * - the call to this function was delayed by time-to-trigger; and
2704  * - the time-to-trigger delay is fixed (not adaptive/dynamic); and
2705  * - the first element in the list is associated with this function call.
2706  */
2707  leavingTriggerIt->second.pop_front ();
2708 
2709  if (!leavingTriggerIt->second.empty ())
2710  {
2711  /*
2712  * To prevent the same set of cells triggering again in the future,
2713  * we clean up the time-to-trigger queue. This case might occur when
2714  * time-to-trigger > 200 ms.
2715  */
2716  for (ConcernedCells_t::const_iterator it = leavingCells.begin ();
2717  it != leavingCells.end (); ++it)
2718  {
2719  CancelLeavingTrigger (measId, *it);
2720  }
2721  }
2722 
2723  } // end of if (!leavingTriggerIt->second.empty ())
2724 
2725 } // end of LteUeRrc::VarMeasReportListErase
2726 
2727 void
2729 {
2730  NS_LOG_FUNCTION (this << (uint16_t) measId);
2731 
2732  // remove the measurement reporting entry for this measId from the VarMeasReportList
2733  std::map<uint8_t, VarMeasReport>::iterator
2734  measReportIt = m_varMeasReportList.find (measId);
2735  if (measReportIt != m_varMeasReportList.end ())
2736  {
2737  NS_LOG_LOGIC (this << " deleting existing report for measId " << (uint16_t) measId);
2738  measReportIt->second.periodicReportTimer.Cancel ();
2739  m_varMeasReportList.erase (measReportIt);
2740  }
2741 
2742  CancelEnteringTrigger (measId);
2743  CancelLeavingTrigger (measId);
2744 }
2745 
2746 void
2748 {
2749  NS_LOG_FUNCTION (this << (uint16_t) measId);
2750  // 3GPP TS 36.331 section 5.5.5 Measurement reporting
2751 
2752  std::map<uint8_t, LteRrcSap::MeasIdToAddMod>::iterator
2753  measIdIt = m_varMeasConfig.measIdList.find (measId);
2754  NS_ASSERT (measIdIt != m_varMeasConfig.measIdList.end ());
2755 
2756  std::map<uint8_t, LteRrcSap::ReportConfigToAddMod>::iterator
2757  reportConfigIt = m_varMeasConfig.reportConfigList.find (measIdIt->second.reportConfigId);
2758  NS_ASSERT (reportConfigIt != m_varMeasConfig.reportConfigList.end ());
2759  LteRrcSap::ReportConfigEutra& reportConfigEutra = reportConfigIt->second.reportConfigEutra;
2760 
2761  LteRrcSap::MeasurementReport measurementReport;
2762  LteRrcSap::MeasResults& measResults = measurementReport.measResults;
2763  measResults.measId = measId;
2764 
2765  std::map<uint16_t, MeasValues>::iterator servingMeasIt = m_storedMeasValues.find (m_cellId);
2766  NS_ASSERT (servingMeasIt != m_storedMeasValues.end ());
2767  measResults.rsrpResult = EutranMeasurementMapping::Dbm2RsrpRange (servingMeasIt->second.rsrp);
2768  measResults.rsrqResult = EutranMeasurementMapping::Db2RsrqRange (servingMeasIt->second.rsrq);
2769  NS_LOG_INFO (this << " reporting serving cell "
2770  "RSRP " << (uint32_t) measResults.rsrpResult << " (" << servingMeasIt->second.rsrp << " dBm) "
2771  "RSRQ " << (uint32_t) measResults.rsrqResult << " (" << servingMeasIt->second.rsrq << " dB)");
2772  measResults.haveMeasResultNeighCells = false;
2773  std::map<uint8_t, VarMeasReport>::iterator measReportIt = m_varMeasReportList.find (measId);
2774  if (measReportIt == m_varMeasReportList.end ())
2775  {
2776  NS_LOG_ERROR ("no entry found in m_varMeasReportList for measId " << (uint32_t) measId);
2777  }
2778  else
2779  {
2780  if (!(measReportIt->second.cellsTriggeredList.empty ()))
2781  {
2782  std::multimap<double, uint16_t> sortedNeighCells;
2783  for (std::set<uint16_t>::iterator cellsTriggeredIt = measReportIt->second.cellsTriggeredList.begin ();
2784  cellsTriggeredIt != measReportIt->second.cellsTriggeredList.end ();
2785  ++cellsTriggeredIt)
2786  {
2787  uint16_t cellId = *cellsTriggeredIt;
2788  if (cellId != m_cellId)
2789  {
2790  std::map<uint16_t, MeasValues>::iterator neighborMeasIt = m_storedMeasValues.find (cellId);
2791  double triggerValue;
2792  switch (reportConfigEutra.triggerQuantity)
2793  {
2795  triggerValue = neighborMeasIt->second.rsrp;
2796  break;
2798  triggerValue = neighborMeasIt->second.rsrq;
2799  break;
2800  default:
2801  NS_FATAL_ERROR ("unsupported triggerQuantity");
2802  break;
2803  }
2804  sortedNeighCells.insert (std::pair<double, uint16_t> (triggerValue, cellId));
2805  }
2806  }
2807 
2808  std::multimap<double, uint16_t>::reverse_iterator sortedNeighCellsIt;
2809  uint32_t count;
2810  for (sortedNeighCellsIt = sortedNeighCells.rbegin (), count = 0;
2811  sortedNeighCellsIt != sortedNeighCells.rend () && count < reportConfigEutra.maxReportCells;
2812  ++sortedNeighCellsIt, ++count)
2813  {
2814  uint16_t cellId = sortedNeighCellsIt->second;
2815  std::map<uint16_t, MeasValues>::iterator neighborMeasIt = m_storedMeasValues.find (cellId);
2816  NS_ASSERT (neighborMeasIt != m_storedMeasValues.end ());
2817  LteRrcSap::MeasResultEutra measResultEutra;
2818  measResultEutra.physCellId = cellId;
2819  measResultEutra.haveCgiInfo = false;
2820  measResultEutra.haveRsrpResult = true;
2821  measResultEutra.rsrpResult = EutranMeasurementMapping::Dbm2RsrpRange (neighborMeasIt->second.rsrp);
2822  measResultEutra.haveRsrqResult = true;
2823  measResultEutra.rsrqResult = EutranMeasurementMapping::Db2RsrqRange (neighborMeasIt->second.rsrq);
2824  NS_LOG_INFO (this << " reporting neighbor cell " << (uint32_t) measResultEutra.physCellId
2825  << " RSRP " << (uint32_t) measResultEutra.rsrpResult
2826  << " (" << neighborMeasIt->second.rsrp << " dBm)"
2827  << " RSRQ " << (uint32_t) measResultEutra.rsrqResult
2828  << " (" << neighborMeasIt->second.rsrq << " dB)");
2829  measResults.measResultListEutra.push_back (measResultEutra);
2830  measResults.haveMeasResultNeighCells = true;
2831  }
2832  }
2833  else
2834  {
2835  NS_LOG_WARN (this << " cellsTriggeredList is empty");
2836  }
2837 
2838  measResults.haveScellsMeas = false;
2839  std::map<uint16_t, MeasValues>::iterator sCellsMeasIt = m_storedScellMeasValues.begin ();
2840  if (sCellsMeasIt != m_storedScellMeasValues.end ())
2841  {
2842  measResults.haveScellsMeas = true;
2845 
2846 
2847  for ( sCellsMeasIt = m_storedScellMeasValues.begin ();
2848  sCellsMeasIt != m_storedScellMeasValues.end (); ++sCellsMeasIt)
2849  {
2850  LteRrcSap::MeasResultScell measResultScell;
2851  measResultScell.servFreqId = sCellsMeasIt->first;
2852  measResultScell.haveRsrpResult = true;
2853  measResultScell.haveRsrqResult = true;
2854  measResultScell.rsrpResult = EutranMeasurementMapping::Dbm2RsrpRange (sCellsMeasIt->second.rsrp);
2855  measResultScell.rsrqResult = EutranMeasurementMapping::Db2RsrqRange (sCellsMeasIt->second.rsrq);
2856  measResults.measScellResultList.measResultScell.push_back (measResultScell);
2857  }
2858  }
2859 
2860  /*
2861  * The current LteRrcSap implementation is broken in that it does not
2862  * allow for infinite values of reportAmount, which is probably the most
2863  * reasonable setting. So we just always assume infinite reportAmount.
2864  */
2865  measReportIt->second.numberOfReportsSent++;
2866  measReportIt->second.periodicReportTimer.Cancel ();
2867 
2868  Time reportInterval;
2869  switch (reportConfigEutra.reportInterval)
2870  {
2872  reportInterval = MilliSeconds (120);
2873  break;
2875  reportInterval = MilliSeconds (240);
2876  break;
2878  reportInterval = MilliSeconds (480);
2879  break;
2881  reportInterval = MilliSeconds (640);
2882  break;
2884  reportInterval = MilliSeconds (1024);
2885  break;
2887  reportInterval = MilliSeconds (2048);
2888  break;
2890  reportInterval = MilliSeconds (5120);
2891  break;
2893  reportInterval = MilliSeconds (10240);
2894  break;
2896  reportInterval = Seconds (60);
2897  break;
2899  reportInterval = Seconds (360);
2900  break;
2902  reportInterval = Seconds (720);
2903  break;
2905  reportInterval = Seconds (1800);
2906  break;
2908  reportInterval = Seconds (3600);
2909  break;
2910  default:
2911  NS_FATAL_ERROR ("Unsupported reportInterval " << (uint16_t) reportConfigEutra.reportInterval);
2912  break;
2913  }
2914 
2915  // schedule the next measurement reporting
2916  measReportIt->second.periodicReportTimer
2917  = Simulator::Schedule (reportInterval,
2919  this, measId);
2920 
2921  // send the measurement report to eNodeB
2922  m_rrcSapUser->SendMeasurementReport (measurementReport);
2923  }
2924 }
2925 
2926 void
2928 {
2929  NS_LOG_FUNCTION (this << m_imsi);
2932  m_connectionPending = false; // reset the flag
2934  m_cmacSapProvider.at (0)->StartContentionBasedRandomAccessProcedure ();
2935 }
2936 
2937 void
2939 {
2940  NS_LOG_FUNCTION (this << m_imsi);
2942  m_cmacSapProvider.at (0)->RemoveLc (1);
2943  std::map<uint8_t, Ptr<LteDataRadioBearerInfo> >::iterator it;
2944  for (it = m_drbMap.begin (); it != m_drbMap.end (); ++it)
2945  {
2946  m_cmacSapProvider.at (0)->RemoveLc (it->second->m_logicalChannelIdentity);
2947  }
2948  m_drbMap.clear ();
2949  m_bid2DrbidMap.clear ();
2950  m_srb1 = 0;
2952 }
2953 
2954 void
2956 {
2957  NS_LOG_FUNCTION (this << m_imsi);
2958  m_cmacSapProvider.at (0)->Reset (); // reset the MAC
2959  m_hasReceivedSib2 = false; // invalidate the previously received SIB2
2962  m_asSapUser->NotifyConnectionFailed (); // inform upper layer
2963 }
2964 
2965 void
2967 {
2968  NS_LOG_FUNCTION (this);
2969  m_srb1Old = 0;
2970 }
2971 
2972 uint8_t
2973 LteUeRrc::Bid2Drbid (uint8_t bid)
2974 {
2975  std::map<uint8_t, uint8_t>::iterator it = m_bid2DrbidMap.find (bid);
2976  //NS_ASSERT_MSG (it != m_bid2DrbidMap.end (), "could not find BID " << bid);
2977  if (it == m_bid2DrbidMap.end ())
2978  {
2979  return 0;
2980  }
2981  else
2982  {
2983  return it->second;
2984  }
2985 }
2986 
2987 void
2989 {
2990  NS_LOG_FUNCTION (this << ToString (newState));
2991  State oldState = m_state;
2992  m_state = newState;
2993  NS_LOG_INFO (this << " IMSI " << m_imsi << " RNTI " << m_rnti << " UeRrc "
2994  << ToString (oldState) << " --> " << ToString (newState));
2995  m_stateTransitionTrace (m_imsi, m_cellId, m_rnti, oldState, newState);
2996 
2997  switch (newState)
2998  {
2999  case IDLE_START:
3000  NS_FATAL_ERROR ("cannot switch to an initial state");
3001  break;
3002 
3003  case IDLE_CELL_SEARCH:
3004  case IDLE_WAIT_MIB_SIB1:
3005  case IDLE_WAIT_MIB:
3006  case IDLE_WAIT_SIB1:
3007  break;
3008 
3009  case IDLE_CAMPED_NORMALLY:
3010  if (m_connectionPending)
3011  {
3013  }
3014  break;
3015 
3016  case IDLE_WAIT_SIB2:
3017  if (m_hasReceivedSib2)
3018  {
3020  StartConnection ();
3021  }
3022  break;
3023 
3024  case IDLE_RANDOM_ACCESS:
3025  case IDLE_CONNECTING:
3026  case CONNECTED_NORMALLY:
3027  case CONNECTED_HANDOVER:
3028  case CONNECTED_PHY_PROBLEM:
3030  break;
3031 
3032  default:
3033  break;
3034  }
3035 }
3036 
3037 void
3038 LteUeRrc::DoComponentCarrierEnabling (std::vector<uint8_t> res)
3039  {
3040  NS_LOG_INFO (this);
3041  }
3042 
3043 void
3044 LteUeRrc::SaveScellUeMeasurements (uint16_t sCellId, double rsrp, double rsrq,
3045  bool useLayer3Filtering, uint16_t componentCarrierId)
3046 {
3047  NS_LOG_FUNCTION (this << sCellId << componentCarrierId << rsrp << rsrq << useLayer3Filtering);
3048  if (sCellId == m_cellId)
3049  {
3050 
3051  std::map<uint16_t, MeasValues>::iterator storedMeasIt = m_storedScellMeasValues.find (componentCarrierId);
3052 
3053  if (storedMeasIt != m_storedScellMeasValues.end ())
3054  {
3055  if (useLayer3Filtering)
3056  {
3057  // F_n = (1-a) F_{n-1} + a M_n
3058  storedMeasIt->second.rsrp = (1 - m_varMeasConfig.aRsrp) * storedMeasIt->second.rsrp
3059  + m_varMeasConfig.aRsrp * rsrp;
3060 
3061  if (std::isnan (storedMeasIt->second.rsrq))
3062  {
3063  // the previous RSRQ measurements provided UE PHY are invalid
3064  storedMeasIt->second.rsrq = rsrq; // replace it with unfiltered value
3065  }
3066  else
3067  {
3068  storedMeasIt->second.rsrq = (1 - m_varMeasConfig.aRsrq) * storedMeasIt->second.rsrq
3069  + m_varMeasConfig.aRsrq * rsrq;
3070  }
3071  }
3072  else
3073  {
3074  storedMeasIt->second.rsrp = rsrp;
3075  storedMeasIt->second.rsrq = rsrq;
3076  }
3077  }
3078  else
3079  {
3080  // first value is always unfiltered
3081  MeasValues v;
3082  v.rsrp = rsrp;
3083  v.rsrq = rsrq;
3084  std::pair<uint16_t, MeasValues> val (componentCarrierId, v);
3085  std::pair<std::map<uint16_t, MeasValues>::iterator, bool>
3086  ret = m_storedScellMeasValues.insert (val);
3087  NS_ASSERT_MSG (ret.second == true, "element already existed");
3088  storedMeasIt = ret.first;
3089  }
3090 
3091  NS_LOG_DEBUG (this << " IMSI " << m_imsi << " state " << ToString (m_state)
3092  << ", measured cell " << sCellId
3093  << ", carrier component Id " << componentCarrierId
3094  << ", new RSRP " << rsrp << " stored " << storedMeasIt->second.rsrp
3095  << ", new RSRQ " << rsrq << " stored " << storedMeasIt->second.rsrq);
3096  storedMeasIt->second.timestamp = Simulator::Now ();
3097  }
3098  else
3099  {
3100  NS_LOG_DEBUG (this << " IMSI " << m_imsi << "measurement on SCC from not serving cell ");
3101  }
3102 
3103 } // end of void SaveUeMeasurements
3104 
3105 
3106 } // namespace ns3
3107 
uint32_t sCellIndex
SCell index.
Definition: lte-rrc-sap.h:814
std::map< uint16_t, MeasValues > m_storedScellMeasValues
Internal storage of the latest measurement results from all detected detected Secondary carrier compo...
Definition: lte-ue-rrc.h:1034
static Time GetDelayLeft(const EventId &id)
Get the remaining time until this event will execute.
Definition: simulator.cc:258
MemberLteUeCcmRrcSapUser class.
RrcConnectionRequest structure.
Definition: lte-rrc-sap.h:685
uint64_t GetImsi(void) const
Definition: lte-ue-rrc.cc:400
uint8_t numberOfRaPreambles
number of RA preambles
PhysicalConfigDedicated structure.
Definition: lte-rrc-sap.h:216
bool haveNonCriticalExtension
have critical extension?
Definition: lte-rrc-sap.h:838
SCellToAddMod structure.
Definition: lte-rrc-sap.h:812
LtePdcpSapProvider * srb1SapProvider
SRB1 SAP provider.
Definition: lte-rrc-sap.h:916
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:102
uint8_t raResponseWindowSize
RA response window size.
RadioResourceConfigCommonSCell radioResourceConfigCommonSCell
radio resource config common SCell
Definition: lte-rrc-sap.h:816
CarrierFreqEutra carrierFreq
carrier frequency
Definition: lte-rrc-sap.h:555
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
PdschConfigDedicated pdschConfigDedicated
PDSCH config dedicated.
Definition: lte-rrc-sap.h:223
Part of the RRC protocol.
Definition: lte-rrc-sap.h:982
void DoRecvRrcConnectionSetup(LteRrcSap::RrcConnectionSetup msg)
Part of the RRC protocol.
Definition: lte-ue-rrc.cc:955
uint8_t m_componentCarrierId
component carrier ID
void DoRecvMasterInformationBlock(uint16_t cellId, LteRrcSap::MasterInformationBlock msg)
Receive master information block function.
Definition: lte-ue-rrc.cc:780
MeasurementReport structure.
Definition: lte-rrc-sap.h:894
std::map< uint8_t, LteRrcSap::MeasObjectToAddMod > measObjectList
measure object list
Definition: lte-ue-rrc.h:893
std::vector< struct UeMeasurementsElement > m_ueMeasurementsList
UE measurement list.
UeMemberLteUeCmacSapUser class.
Definition: lte-ue-rrc.cc:51
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:2476
void DoRecvSystemInformationBlockType1(uint16_t cellId, LteRrcSap::SystemInformationBlockType1 msg)
Receive system information block type 1 function.
Definition: lte-ue-rrc.cc:807
PdschConfigDedicated pdschConfigDedicated
PDSCH config dedicated.
Definition: lte-rrc-sap.h:784
Definition: second.py:1
void DoComponentCarrierEnabling(std::vector< uint8_t > res)
RRC CCM SAP USER Method.
Definition: lte-ue-rrc.cc:3038
static TypeId GetTypeId(void)
Get the type ID.
Definition: lte-ue-rrc.cc:190
MobilityControlInfo structure.
Definition: lte-rrc-sap.h:551
static double IeValue2ActualHysteresis(uint8_t hysteresisIeValue)
Returns the actual value of a hysteresis parameter.
Definition: lte-common.cc:288
std::list< MeasObjectToAddMod > measObjectToAddModList
measure object to add mod list
Definition: lte-rrc-sap.h:514
uint8_t GetDlBandwidth() const
Definition: lte-ue-rrc.cc:428
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:45
LtePdcpSapUser * m_drbPdcpSapUser
DRB PDCP SAP user.
Definition: lte-ue-rrc.h:721
void DoRecvSystemInformation(LteRrcSap::SystemInformation msg)
Part of the RRC protocol.
Definition: lte-ue-rrc.cc:911
uint16_t bucketSizeDurationMs
bucket size duration ms
uint8_t numberOfRaPreambles
number of RA preambles
Definition: lte-rrc-sap.h:247
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:831
Event A3: Neighbour becomes amount of offset better than PCell.
Definition: lte-rrc-sap.h:368
static double ConvertPdschConfigDedicated2Double(PdschConfigDedicated pdschConfigDedicated)
Convert PDSCH config dedicated function.
Definition: lte-rrc-sap.h:180
Template for the implementation of the LteUeCphySapUser as a member of an owner class of type C to wh...
SoundingRsUlConfigDedicated soundingRsUlConfigDedicated
sounding RS UL config dedicated
Definition: lte-rrc-sap.h:219
NS_ASSERT_MSG(false, "Ipv4AddressGenerator::MaskToIndex(): Impossible")
static TypeId GetTypeId(void)
Get the type ID.
Definition: lte-rlc.cc:189
RSRP is used for the threshold.
Definition: lte-rrc-sap.h:347
void SetAsSapUser(LteAsSapUser *s)
Set the AS SAP user to interact with the NAS entity.
Definition: lte-ue-rrc.cc:381
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:1731
QuantityConfig quantityConfig
quantity config
Definition: lte-rrc-sap.h:520
void DoRecvRrcConnectionReject(LteRrcSap::RrcConnectionReject msg)
Part of the RRC protocol.
Definition: lte-ue-rrc.cc:1110
std::list< uint8_t > reportConfigToRemoveList
report config to remove list
Definition: lte-rrc-sap.h:515
bool m_hasReceivedSib2
True if SIB2 was received for the current cell.
Definition: lte-ue-rrc.h:869
MeasObjectEutra structure.
Definition: lte-rrc-sap.h:318
std::list< MeasResultEutra > measResultListEutra
measure result list eutra
Definition: lte-rrc-sap.h:677
int8_t qRxLevMin
INTEGER (-70..-22), actual value = IE value * 2 [dBm].
Definition: lte-rrc-sap.h:83
std::map< uint8_t, Ptr< LteDataRadioBearerInfo > > m_drbMap
The DataRadioBearerMap attribute.
Definition: lte-ue-rrc.h:763
void ApplyMeasConfig(LteRrcSap::MeasConfig mc)
Update the current measurement configuration m_varMeasConfig.
Definition: lte-ue-rrc.cc:1460
Specifies criteria for triggering of an E-UTRA measurement reporting event.
Definition: lte-rrc-sap.h:354
virtual void DoDispose(void)
Destructor implementation.
Definition: lte-ue-rrc.cc:168
void SetUseRlcSm(bool val)
Definition: lte-ue-rrc.cc:455
double GetSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:355
virtual void SendRrcConnectionReconfigurationCompleted(RrcConnectionReconfigurationCompleted msg)=0
Send an RRCConnectionReconfigurationComplete message to the serving eNodeB during an RRC connection r...
uint16_t m_numberOfComponentCarriers
The number of component carriers.
Definition: lte-ue-rrc.h:1174
uint8_t measId
The measurement identity which raised the trigger.
Definition: lte-ue-rrc.h:1043
MeasConfig structure.
Definition: lte-rrc-sap.h:511
RadioResourceConfigDedicatedSCell radioResourceConfigDedicateSCell
radio resource config dedicated SCell
Definition: lte-rrc-sap.h:818
LteRrcSap::PdschConfigDedicated m_pdschConfigDedicated
the PDSCH condig dedicated
Definition: lte-ue-rrc.h:773
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file...
Definition: assert.h:67
std::list< SrbToAddMod > srbToAddModList
SRB to add mod list.
Definition: lte-rrc-sap.h:280
void DoSetTemporaryCellRnti(uint16_t rnti)
Set temporary cell rnti function.
Definition: lte-ue-rrc.cc:585
Represents a single triggered event from a measurement identity which reporting criteria have been fu...
Definition: lte-ue-rrc.h:1041
RadioResourceConfigDedicated radioResourceConfigDedicated
radio resource config dedicated
Definition: lte-rrc-sap.h:837
EventId m_connectionTimeout
Invokes ConnectionEstablishmentTimeout() if RRC connection establishment procedure for this UE takes ...
Definition: lte-ue-rrc.h:1162
LteUeRrc()
create an RRC instance for use within an ue
Definition: lte-ue-rrc.cc:133
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1022
std::list< uint8_t > measObjectToRemoveList
measure object to remove list
Definition: lte-rrc-sap.h:513
void SetTypeId(TypeId tid)
Set the TypeId of the Objects to be created by this factory.
Service Access Point (SAP) offered by the UE PHY to the UE RRC for control purposes.
std::vector< LteUeCmacSapProvider * > m_cmacSapProvider
UE CMac SAP provider.
Definition: lte-ue-rrc.h:715
PdschConfigCommon pdschConfigCommon
4: Physical configuration, physical channels pdsch-ConfigCommon-r10
Definition: lte-rrc-sap.h:740
virtual ~LteUeRrc()
Destructor.
Definition: lte-ue-rrc.cc:162
uint16_t srsConfigIndex
SRS config index.
Definition: lte-rrc-sap.h:137
uint16_t m_cellId
The CellId attribute.
Definition: lte-ue-rrc.h:744
EventId timer
The pending reporting event, scheduled at the end of the time-to-trigger.
Definition: lte-ue-rrc.h:1045
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:2538
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:278
virtual void NotifyRandomAccessSuccessful()
Notify the RRC that the MAC Random Access procedure completed successfully.
Definition: lte-ue-rrc.cc:82
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:162
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&#39;s associated function will not be invoked when it expires...
Definition: simulator.cc:346
This class implements the Access Stratum (AS) Service Access Point (SAP), i.e., the interface between...
Definition: lte-as-sap.h:41
bool haveCarrierFreq
have carrier frequency?
Definition: lte-rrc-sap.h:554
bool m_hasReceivedMib
True if MIB was received for the current cell.
Definition: lte-ue-rrc.h:865
RachConfigDedicated rachConfigDedicated
RACH config dedicated.
Definition: lte-rrc-sap.h:561
SetupParameters structure.
Definition: lte-rrc-sap.h:913
bool haveSmeasure
have S measure?
Definition: lte-rrc-sap.h:523
void DoRecvRrcConnectionReestablishmentReject(LteRrcSap::RrcConnectionReestablishmentReject msg)
Part of the RRC protocol.
Definition: lte-ue-rrc.cc:1081
uint8_t GetUlBandwidth() const
Definition: lte-ue-rrc.cc:421
uint32_t m_dlEarfcn
Downlink carrier frequency.
Definition: lte-ue-rrc.h:778
Reference Signal Received Quality.
Definition: lte-rrc-sap.h:400
void SetRnti(uint16_t rnti)
Definition: lte-rlc.cc:131
bool m_connectionPending
True if a connection request by upper layers is pending.
Definition: lte-ue-rrc.h:863
LtePdcpSapUser * srb1SapUser
SRB1 SAP user.
Definition: lte-rrc-sap.h:989
uint8_t rsrpResult
the RSRP result
Definition: lte-rrc-sap.h:645
void DoStartCellSelection(uint32_t dlEarfcn)
Start cell selection function.
Definition: lte-ue-rrc.cc:682
uint32_t ulCarrierFreq
UL carrier frequency.
Definition: lte-rrc-sap.h:90
bool m_hasReceivedSib1
True if SIB1 was received for the current cell.
Definition: lte-ue-rrc.h:867
LteMacSapProvider * m_macSapProvider
MAC SAP provider.
Definition: lte-ue-rrc.h:720
bool haveRadioResourceConfigDedicated
have radio resource config dedicated
Definition: lte-rrc-sap.h:836
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:446
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:260
virtual void SendRrcConnectionSetupCompleted(RrcConnectionSetupCompleted msg)=0
Send an RRCConnectionSetupComplete message to the serving eNodeB during an RRC connection establishme...
uint8_t rrcTransactionIdentifier
RRC transaction identifier.
Definition: lte-rrc-sap.h:831
uint8_t Bid2Drbid(uint8_t bid)
Bid 2 DR bid.
Definition: lte-ue-rrc.cc:2973
#define MIN_NO_CC
Definition: lte-enb-rrc.h:54
PreambleInfo preambleInfo
preamble info
Definition: lte-rrc-sap.h:260
uint8_t rsrpResult
RSRP result.
Definition: lte-rrc-sap.h:674
SystemInformation structure.
Definition: lte-rrc-sap.h:601
Parameters for LtePdcpSapUser::ReceivePdcpSdu.
Definition: lte-pdcp-sap.h:76
CellIdentification cellIdentification
cell identification
Definition: lte-rrc-sap.h:815
LteUeCmacSapUser * GetLteUeCmacSapUser()
This function is overloaded to maintain backward compatibility.
Definition: lte-ue-rrc.cc:332
uint16_t GetRnti() const
Definition: lte-ue-rrc.cc:406
uint8_t preambleTransMax
preamble transmit maximum
static const Time UE_MEASUREMENT_REPORT_DELAY
Artificial delay of UE measurements procedure.
Definition: lte-ue-rrc.h:65
LteRrcSap::QuantityConfig quantityConfig
quantity config
Definition: lte-ue-rrc.h:895
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:220
std::vector< LteUeCphySapProvider * > m_cphySapProvider
UE CPhy SAP provider.
Definition: lte-ue-rrc.h:712
static EventId Schedule(Time const &delay, MEM mem_ptr, OBJ obj)
Schedule an event to expire after delay.
Definition: simulator.h:1381
void SetLteUeRrcSapUser(LteUeRrcSapUser *s)
set the RRC SAP this RRC should interact with
Definition: lte-ue-rrc.cc:346
LteUeRrcSapUser * m_rrcSapUser
RRC SAP user.
Definition: lte-ue-rrc.h:717
uint8_t preambleTransMax
preamble transmit maximum
Definition: lte-rrc-sap.h:253
MeasResults measResults
measure results
Definition: lte-rrc-sap.h:896
FreqInfo ulFreqInfo
UL frequency info.
Definition: lte-rrc-sap.h:748
TracedCallback< uint64_t, uint16_t, uint16_t > m_handoverEndOkTrace
The HandoverEndOk trace source.
Definition: lte-ue-rrc.h:849
MeasResultScell structure.
Definition: lte-rrc-sap.h:641
State m_state
The current UE RRC state.
Definition: lte-ue-rrc.h:733
AttributeValue implementation for Time.
Definition: nstime.h:1076
Ptr< LteSignalingRadioBearerInfo > m_srb0
The Srb0 attribute.
Definition: lte-ue-rrc.h:749
Ptr< Object > Create(void) const
Create an Object instance of the configured TypeId.
ConcernedCells_t concernedCells
The list of cells responsible for this trigger.
Definition: lte-ue-rrc.h:1044
TracedCallback< Ptr< LteUeRrc >, std::list< LteRrcSap::SCellToAddMod > > m_sCarrierConfiguredTrace
The SCarrierConfigured trace source.
Definition: lte-ue-rrc.h:860
MeasResults structure.
Definition: lte-rrc-sap.h:671
uint64_t ueIdentity
UE identity.
Definition: lte-rrc-sap.h:687
static TypeId GetTypeId(void)
Get the type ID.
Definition: lte-rlc-um.cc:55
int8_t referenceSignalPower
INTEGER (-60..50),.
Definition: lte-rrc-sap.h:149
RrcConnectionReestablishment structure.
Definition: lte-rrc-sap.h:858
Represents a measurement result from a certain cell.
Definition: lte-ue-rrc.h:991
void DisposeOldSrb1()
Dispose old SRB1.
Definition: lte-ue-rrc.cc:2966
static double IeValue2ActualA3Offset(int8_t a3OffsetIeValue)
Returns the actual value of an a3-Offset parameter.
Definition: lte-common.cc:319
TracedCallback< uint64_t, uint16_t, uint16_t, uint16_t > m_handoverStartTrace
The HandoverStart trace source.
Definition: lte-ue-rrc.h:844
uint8_t rsrqResult
the RSRQ result
Definition: lte-rrc-sap.h:647
void DoRecvRrcConnectionReconfiguration(LteRrcSap::RrcConnectionReconfiguration msg)
Part of the RRC protocol.
Definition: lte-ue-rrc.cc:980
void DoRecvRrcConnectionReestablishment(LteRrcSap::RrcConnectionReestablishment msg)
Part of the RRC protocol.
Definition: lte-ue-rrc.cc:1057
uint8_t m_dlBandwidth
Downlink bandwidth in RBs.
Definition: lte-ue-rrc.h:775
Service Access Point (SAP) offered by the UE PHY to the UE RRC for control purposes.
CellAccessRelatedInfo cellAccessRelatedInfo
cell access related info
Definition: lte-rrc-sap.h:589
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:824
bool haveMeasurementResultsNeighCell
always false since not implemented
Definition: lte-rrc-sap.h:666
Service Access Point (SAP) offered by the UE RRC to the UE CCM.
NonUlConfiguration nonUlConfiguration
non UL configuration
Definition: lte-rrc-sap.h:800
uint8_t rrcTransactionIdentifier
RRC transaction identifier.
Definition: lte-rrc-sap.h:700
TracedCallback< uint64_t, uint16_t, uint16_t > m_sib2ReceivedTrace
The Sib2Received trace source.
Definition: lte-ue-rrc.h:797
Event A5: PCell becomes worse than absolute threshold1 AND Neighbour becomes better than another abso...
Definition: lte-rrc-sap.h:370
LteUeRrc * m_rrc
the RRC class
Definition: lte-ue-rrc.cc:66
void ConnectionTimeout()
Invoked after timer T300 expires, notifying upper layers that RRC connection establishment procedure ...
Definition: lte-ue-rrc.cc:2955
uint32_t dlCarrierFreq
ARFCN - valueEUTRA.
Definition: lte-rrc-sap.h:708
bool haveMeasGapConfig
have measure gap config?
Definition: lte-rrc-sap.h:521
void EvaluateCellForSelection()
Performs cell selection evaluation to the current serving cell.
Definition: lte-ue-rrc.cc:1167
MeasResultEutra structure.
Definition: lte-rrc-sap.h:629
std::list< MeasResultScell > measResultScell
measure results Scells
Definition: lte-rrc-sap.h:665
RrcConnectionReconfiguration structure.
Definition: lte-rrc-sap.h:829
std::list< MeasIdToAddMod > measIdToAddModList
measure ID to add mod list
Definition: lte-rrc-sap.h:518
bool haveRachConfigDedicated
Have RACH config dedicated?
Definition: lte-rrc-sap.h:560
uint8_t raPrachMaskIndex
RA PRACH mask index.
Definition: lte-rrc-sap.h:547
virtual void DoInitialize(void)
Initialize() implementation.
Definition: lte-ue-rrc.cc:463
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:1011
void SetLteCcmRrcSapProvider(LteUeCcmRrcSapProvider *s)
set the Component Carrier Management SAP this RRC should interact with
Definition: lte-ue-rrc.cc:367
PhysicalConfigDedicated physicalConfigDedicated
physical config dedicated
Definition: lte-rrc-sap.h:284
Ptr< LteSignalingRadioBearerInfo > m_srb1
The Srb1 attribute.
Definition: lte-ue-rrc.h:753
uint8_t measId
measure ID
Definition: lte-ue-rrc.h:917
uint8_t filterCoefficientRSRP
filter coefficient RSRP
Definition: lte-rrc-sap.h:290
bool haveRsrpResult
have RSRP result?
Definition: lte-rrc-sap.h:644
void SetLteUeCmacSapProvider(LteUeCmacSapProvider *s)
set the CMAC SAP this RRC should interact with
Definition: lte-ue-rrc.cc:318
RrcConnectionReconfigurationCompleted structure.
Definition: lte-rrc-sap.h:844
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:769
MeasResultServFreqList measScellResultList
measure SCell result list
Definition: lte-rrc-sap.h:679
Parameters for LtePdcpSapProvider::TransmitPdcpSdu.
Definition: lte-pdcp-sap.h:43
std::list< SCellToAddMod > sCellsToAddModList
SCell to add mod list.
Definition: lte-rrc-sap.h:824
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:166
uint32_t m_csgWhiteList
List of CSG ID which this UE entity has access to.
Definition: lte-ue-rrc.h:878
Service Access Point (SAP) offered by the UE MAC to the UE RRC.
uint8_t rrcTransactionIdentifier
RRC transaction identifier.
Definition: lte-rrc-sap.h:693
std::map< uint8_t, LteRrcSap::MeasIdToAddMod > measIdList
measure ID list
Definition: lte-ue-rrc.h:892
std::map< uint8_t, uint8_t > m_bid2DrbidMap
bid to DR bid map
Definition: lte-ue-rrc.h:709
void SetLteMacSapProvider(LteMacSapProvider *s)
set the MAC SAP provider.
Definition: lte-ue-rrc.cc:360
RrcConnectionSetupCompleted structure.
Definition: lte-rrc-sap.h:698
TracedCallback< uint64_t, uint16_t > m_initialCellSelectionEndOkTrace
The InitialCellSelectionEndOk trace source.
Definition: lte-ue-rrc.h:808
RadioResourceConfigDedicated radioResourceConfigDedicated
radio resource config dedicated
Definition: lte-rrc-sap.h:694
RrcConnectionSetup structure.
Definition: lte-rrc-sap.h:691
std::list< LteRrcSap::SCellToAddMod > m_sCellToAddModList
Secondary carriers.
Definition: lte-ue-rrc.h:780
uint8_t rrcTransactionIdentifier
RRC transaction identifier.
Definition: lte-rrc-sap.h:846
void SetLteUeCphySapProvider(LteUeCphySapProvider *s)
set the CPHY SAP this RRC should use to interact with the PHY
Definition: lte-ue-rrc.cc:290
void SwitchToState(State s)
Switch the UE RRC to the given state.
Definition: lte-ue-rrc.cc:2988
Ptr< T > GetObject(void) const
Get a pointer to the requested aggregated Object.
Definition: object.h:459
static double IeValue2ActualQRxLevMin(int8_t qRxLevMinIeValue)
Returns the actual value of an Q-RxLevMin parameter.
Definition: lte-common.cc:351
uint8_t raPreambleIndex
RA preamble index.
Definition: lte-rrc-sap.h:546
TracedCallback< uint64_t, uint16_t > m_initialCellSelectionEndErrorTrace
The InitialCellSelectionEndError trace source.
Definition: lte-ue-rrc.h:813
VarMeasConfig m_varMeasConfig
Includes the accumulated configuration of the measurements to be performed by the UE...
Definition: lte-ue-rrc.h:906
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:1069
SystemInformationBlockType1 structure.
Definition: lte-rrc-sap.h:587
std::vector< LteUeCphySapUser * > m_cphySapUser
UE CPhy SAP user.
Definition: lte-ue-rrc.h:711
std::map< uint8_t, LteRrcSap::ReportConfigToAddMod > reportConfigList
report config list
Definition: lte-ue-rrc.h:894
uint16_t servFreqId
service frequency ID
Definition: lte-rrc-sap.h:643
virtual void Setup(SetupParameters params)=0
Setup function.
uint16_t physCellId
Phy cell ID.
Definition: lte-rrc-sap.h:631
Every class exported by the ns3 library is enclosed in the ns3 namespace.
bool haveQuantityConfig
have quantity config?
Definition: lte-rrc-sap.h:519
Hold objects of type Ptr<T>.
Definition: pointer.h:36
void SetLteRlcSapUser(LteRlcSapUser *s)
Definition: lte-rlc.cc:145
uint16_t targetPhysCellId
target Phy cell ID
Definition: lte-rrc-sap.h:553
RrcConnectionReject structure.
Definition: lte-rrc-sap.h:882
LteAsSapUser * m_asSapUser
AS SAP user.
Definition: lte-ue-rrc.h:724
PhysicalConfigDedicatedSCell physicalConfigDedicatedSCell
physical config dedicated SCell
Definition: lte-rrc-sap.h:808
Template for the implementation of the LteUeRrcSapProvider as a member of an owner class of type C to...
Definition: lte-rrc-sap.h:1366
bool haveMobilityControlInfo
have mobility control info
Definition: lte-rrc-sap.h:834
void DoNotifyRandomAccessSuccessful()
Notify random access successful function.
Definition: lte-ue-rrc.cc:594
void SaveScellUeMeasurements(uint16_t cellId, double rsrp, double rsrq, bool useLayer3Filtering, uint16_t componentCarrierId)
keep the given measurement result as the latest measurement figures, to be utilised by UE RRC functio...
Definition: lte-ue-rrc.cc:3044
Reference Signal Received Power.
Definition: lte-rrc-sap.h:399
LteUeCcmRrcSapUser * m_ccmRrcSapUser
CCM RRC SAP user.
Definition: lte-ue-rrc.h:730
MasterInformationBlock structure.
Definition: lte-rrc-sap.h:580
bool haveMeasResultNeighCells
have measure result neighbor cells
Definition: lte-rrc-sap.h:676
uint16_t dlBandwidth
1: Cell characteristics
Definition: lte-rrc-sap.h:734
uint32_t physCellId
physical cell ID
Definition: lte-rrc-sap.h:707
uint8_t filterCoefficientRSRQ
filter coefficient RSRQ
Definition: lte-rrc-sap.h:291
bool havePdschConfigDedicated
have PDSCH config dedicated?
Definition: lte-rrc-sap.h:222
TracedCallback< uint64_t, uint16_t, uint16_t, uint16_t > m_sib1ReceivedTrace
The Sib1Received trace source.
Definition: lte-ue-rrc.h:792
uint16_t newUeIdentity
new UE identity
Definition: lte-rrc-sap.h:558
double rsrq
Measured RSRQ in dB.
Definition: lte-ue-rrc.h:994
uint8_t ulBandwidth
UL bandwidth.
Definition: lte-rrc-sap.h:91
void DoSendData(Ptr< Packet > packet, uint8_t bid)
Send data function.
Definition: lte-ue-rrc.cc:517
Service Access Point (SAP) offered by the UE MAC to the UE RRC.
void DoForceCampedOnEnb(uint16_t cellId, uint32_t dlEarfcn)
Force camped on ENB function.
Definition: lte-ue-rrc.cc:693
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:1570
LtePdcpSpecificLtePdcpSapUser class.
Definition: lte-pdcp-sap.h:132
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:1077
bool haveSoundingRsUlConfigDedicated
have sounding RS UL config dedicated?
Definition: lte-rrc-sap.h:218
RrcConnectionReestablishmentReject structure.
Definition: lte-rrc-sap.h:871
RadioResourceConfigCommonSib radioResourceConfigCommon
radio resource config common
Definition: lte-rrc-sap.h:596
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:249
LteRlcSapUser * srb0SapUser
SRB0 SAP user.
Definition: lte-rrc-sap.h:988
void SetLcId(uint8_t lcId)
Definition: lte-rlc.cc:138
void DoRecvRrcConnectionRelease(LteRrcSap::RrcConnectionRelease msg)
Part of the RRC protocol.
Definition: lte-ue-rrc.cc:1103
double rsrp
Measured RSRP in dBm.
Definition: lte-ue-rrc.h:993
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:2667
LteUeCcmRrcSapUser * GetLteCcmRrcSapUser()
Get the Component Carrier Management SAP offered by this RRC.
Definition: lte-ue-rrc.cc:374
NS_LOG_LOGIC("Net device "<< nd<< " is not bridged")
uint32_t dlCarrierFreq
DL carrier frequency.
Definition: lte-rrc-sap.h:532
CarrierBandwidthEutra carrierBandwidth
carrier bandwidth
Definition: lte-rrc-sap.h:557
LteUeCcmRrcSapProvider * m_ccmRrcSapProvider
Interface to the LteUeComponentCarrierManage instance.
Definition: lte-ue-rrc.h:729
uint8_t m_ulBandwidth
Uplink bandwidth in RBs.
Definition: lte-ue-rrc.h:776
LteUeCphySapUser * GetLteUeCphySapUser()
Definition: lte-ue-rrc.cc:304
TracedCallback< uint64_t, uint16_t, uint16_t > m_connectionReconfigurationTrace
The ConnectionReconfiguration trace source.
Definition: lte-ue-rrc.h:839
uint8_t measId
measure ID
Definition: lte-rrc-sap.h:673
Ptr< LteSignalingRadioBearerInfo > m_srb1Old
SRB1 configuration before RRC connection reconfiguration.
Definition: lte-ue-rrc.h:758
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:103
RachConfigCommon rachConfigCommon
RACH config common.
Definition: lte-rrc-sap.h:273
void StartConnection()
Start connetion function.
Definition: lte-ue-rrc.cc:2927
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:252
uint8_t raResponseWindowSize
RA response window size.
Definition: lte-rrc-sap.h:254
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:1677
uint16_t prioritizedBitRateKbps
prioritize bit rate Kbps
Service Access Point (SAP) offered by the UE component carrier manager to the UE RRC...
CellSelectionInfo cellSelectionInfo
cell selection info
Definition: lte-rrc-sap.h:590
bool haveCarrierBandwidth
have carrier bandwidth?
Definition: lte-rrc-sap.h:556
bool haveAntennaInfoDedicated
have antenna info dedicated?
Definition: lte-rrc-sap.h:220
uint8_t ulBandwidth
UL bandwidth.
Definition: lte-rrc-sap.h:540
static const std::string & ToString(EpcUeNas::State s)
Definition: epc-ue-nas.cc:50
if(desigRtr==addrLocal)
void DoSetCsgWhiteList(uint32_t csgId)
Set CSG white list function.
Definition: lte-ue-rrc.cc:675
std::vector< LteUeCmacSapUser * > m_cmacSapUser
UE CMac SAP user.
Definition: lte-ue-rrc.h:714
void DoNotifyRandomAccessFailed()
Notify random access failed function.
Definition: lte-ue-rrc.cc:642
NonCriticalExtensionConfiguration nonCriticalExtension
3GPP TS 36.331 v.11.10 R11 Sec. 6.2.2 pag. 147 (also known as ETSI TS 136 331 v.11.10 Feb-2015)
Definition: lte-rrc-sap.h:840
void DoCompleteSetup(LteUeRrcSapProvider::CompleteSetupParameters params)
Part of the RRC protocol.
Definition: lte-ue-rrc.cc:899
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition: log.h:262
LteUeRrcSapProvider * m_rrcSapProvider
RRC SAP provider.
Definition: lte-ue-rrc.h:718
void DoConnect()
Connect function.
Definition: lte-ue-rrc.cc:738
bool haveSpeedStatePars
have speed state parameters?
Definition: lte-rrc-sap.h:525
void ApplyRadioResourceConfigDedicated(LteRrcSap::RadioResourceConfigDedicated rrcd)
Apply radio resource config dedicated.
Definition: lte-ue-rrc.cc:1272
TracedCallback< uint64_t, uint16_t, uint16_t > m_connectionEstablishedTrace
The ConnectionEstablished trace source.
Definition: lte-ue-rrc.h:829
std::list< DrbToAddMod > drbToAddModList
DRB to add mod list.
Definition: lte-rrc-sap.h:281
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:928
virtual void NotifyConnectionFailed()=0
Notify the NAS that RRC Connection Establishment failed.
LteAsSapProvider * m_asSapProvider
AS SAP provider.
Definition: lte-ue-rrc.h:723
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:270
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1014
LteRlcSapProvider * srb0SapProvider
SRB0 SAP provider.
Definition: lte-rrc-sap.h:915
TracedCallback< uint64_t, uint16_t, uint16_t, uint16_t > m_mibReceivedTrace
The MibReceived trace source.
Definition: lte-ue-rrc.h:786
uint16_t m_rnti
The C-RNTI attribute.
Definition: lte-ue-rrc.h:740
uint64_t m_imsi
The unique UE identifier.
Definition: lte-ue-rrc.h:736
uint8_t transmissionMode
transmission mode
Definition: lte-rrc-sap.h:143
void ApplyRadioResourceConfigDedicatedSecondaryCarrier(LteRrcSap::NonCriticalExtensionConfiguration nonCec)
Apply radio resource config dedicated secondary carrier.
Definition: lte-ue-rrc.cc:1234
SystemInformationBlockType2 sib2
SIB2.
Definition: lte-rrc-sap.h:604
UeMeasurementsParameters structure.
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:875
void Cancel(void)
This method is syntactic sugar for the ns3::Simulator::Cancel method.
Definition: event-id.cc:53
Event A1: Serving becomes better than absolute threshold.
Definition: lte-rrc-sap.h:366
LteAsSapProvider * GetAsSapProvider()
Definition: lte-ue-rrc.cc:387
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)
Report UE measurements function.
Definition: lte-ue-rrc.cc:847
RSRQ is used for the threshold.
Definition: lte-rrc-sap.h:348
MobilityControlInfo mobilityControlInfo
mobility control info
Definition: lte-rrc-sap.h:835
Event A4: Neighbour becomes better than absolute threshold.
Definition: lte-rrc-sap.h:369
TracedCallback< uint64_t, uint16_t, uint16_t > m_connectionTimeoutTrace
The ConnectionTimeout trace source.
Definition: lte-ue-rrc.h:834
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:915
bool haveRsrqResult
have RSRQ result?
Definition: lte-rrc-sap.h:646
CompleteSetupParameters structure.
Definition: lte-rrc-sap.h:986
#define NS_LOG_ERROR(msg)
Use NS_LOG to output a message of level LOG_ERROR.
Definition: log.h:254
AntennaInfoDedicated antennaInfo
antenna info
Definition: lte-rrc-sap.h:221
LteRlcSapProvider * GetLteRlcSapProvider()
Definition: lte-rlc.cc:152
TracedCallback< uint64_t, uint16_t, uint16_t, State, State > m_stateTransitionTrace
The StateTransition trace source.
Definition: lte-ue-rrc.h:803
void SendMeasurementReport(uint8_t measId)
Produce a proper measurement report from the given measurement identity&#39;s reporting entry in m_varMea...
Definition: lte-ue-rrc.cc:2747
uint32_t GetDlEarfcn() const
Definition: lte-ue-rrc.cc:435
uint8_t rsrqResult
RSRQ result.
Definition: lte-rrc-sap.h:675
A base class which provides memory management and object aggregation.
Definition: object.h:87
PdschConfigCommon pdschConfigCommon
PDSCH config common.
Definition: lte-rrc-sap.h:274
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:1124
Container for a set of ns3::Object pointers.
void InitializeSap(void)
Initiaize SAP.
Definition: lte-ue-rrc.cc:493
void DoReceivePdcpSdu(LtePdcpSapUser::ReceivePdcpSduParameters params)
Receive PDCP SDU function.
Definition: lte-ue-rrc.cc:577
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:909
uint8_t dlBandwidth
DL bandwidth.
Definition: lte-rrc-sap.h:539
NonCriticalExtensionConfiguration structure.
Definition: lte-rrc-sap.h:822
uint32_t GetUlEarfcn() const
Definition: lte-ue-rrc.cc:441
RrcConnectionRelease structure.
Definition: lte-rrc-sap.h:876
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:268
PdschConfigDedicated structure.
Definition: lte-rrc-sap.h:154
virtual void RecvData(Ptr< Packet > packet)=0
receive a data packet
SoundingRsUlConfigDedicated soundingRsUlConfigDedicated
sounding RS UL config dedicated
Definition: lte-rrc-sap.h:793
UeMemberLteUeCmacSapUser(LteUeRrc *rrc)
Constructor.
Definition: lte-ue-rrc.cc:69
LteUeRrcSapProvider * GetLteUeRrcSapProvider()
Definition: lte-ue-rrc.cc:353
static const std::string g_ueRrcStateName[LteUeRrc::NUM_STATES]
Map each of UE RRC states to its string representation.
Definition: lte-ue-rrc.cc:99
std::list< uint16_t > ConcernedCells_t
List of cell IDs which are responsible for a certain trigger.
Definition: lte-ue-rrc.h:933
Time m_t300
The T300 attribute.
Definition: lte-ue-rrc.h:1156
UlConfiguration ulConfiguration
UL configuration.
Definition: lte-rrc-sap.h:802
Event A2: Serving becomes worse than absolute threshold.
Definition: lte-rrc-sap.h:367
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:2600
void DoDisconnect()
Disconnect function.
Definition: lte-ue-rrc.cc:543
virtual void SetTemporaryCellRnti(uint16_t rnti)
Definition: lte-ue-rrc.cc:75
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
#define MAX_NO_CC
Definition: lte-enb-rrc.h:55
TracedCallback< uint64_t, uint16_t, uint16_t > m_randomAccessSuccessfulTrace
The RandomAccessSuccessful trace source.
Definition: lte-ue-rrc.h:819
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:1057
std::list< uint8_t > measIdToRemoveList
measure ID to remove list
Definition: lte-rrc-sap.h:517
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:58
std::list< ReportConfigToAddMod > reportConfigToAddModList
report config to add mod list
Definition: lte-rrc-sap.h:516
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:915
std::list< uint8_t > drbToReleaseList
DRB to release list.
Definition: lte-rrc-sap.h:282
static TypeId GetTypeId(void)
Get the type ID.
Definition: lte-rlc-am.cc:88
void SetImsi(uint64_t imsi)
Definition: lte-ue-rrc.cc:393
uint8_t m_lastRrcTransactionIdentifier
last RRC transaction identifier
Definition: lte-ue-rrc.h:771
void Initialize(void)
Invoke DoInitialize on all Objects aggregated to this one.
Definition: object.cc:183
void VarMeasReportListClear(uint8_t measId)
Remove the reporting entry of the given measurement identity from m_varMeasReportList.
Definition: lte-ue-rrc.cc:2728
void LeaveConnectedMode()
Leave connected mode.
Definition: lte-ue-rrc.cc:2938
uint32_t m_ulEarfcn
Uplink carrier frequency.
Definition: lte-ue-rrc.h:779
TracedCallback< uint64_t, uint16_t, uint16_t > m_handoverEndErrorTrace
The HandoverEndError trace source.
Definition: lte-ue-rrc.h:854
RaSupervisionInfo raSupervisionInfo
RA supervision info.
Definition: lte-rrc-sap.h:261
LteRrcSap::SystemInformationBlockType1 m_lastSib1
Stored content of the last SIB1 received.
Definition: lte-ue-rrc.h:872
void SetLteMacSapProvider(LteMacSapProvider *s)
Definition: lte-rlc.cc:159
State GetState() const
Definition: lte-ue-rrc.cc:448
bool haveScellsMeas
has SCells measure
Definition: lte-rrc-sap.h:678
bool haveMeasurementResultsServingSCells
have measure results serving Scells
Definition: lte-rrc-sap.h:664
AntennaInfoDedicated antennaInfo
antenna info dedicated
Definition: lte-rrc-sap.h:781
virtual void NotifyRandomAccessFailed()
Notify the RRC that the MAC Random Access procedure failed.
Definition: lte-ue-rrc.cc:88
RadioResourceConfigDedicated structure.
Definition: lte-rrc-sap.h:278
uint32_t ulCarrierFreq
UL carrier frequency.
Definition: lte-rrc-sap.h:533
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:244
uint8_t logicalChannelGroup
logical channel group
uint16_t GetCellId() const
Definition: lte-ue-rrc.cc:413