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  ;
281  return tid;
282 }
283 
284 
285 void
287 {
288  NS_LOG_FUNCTION (this << s);
289  m_cphySapProvider.at(0) = s;
290 }
291 
292 void
294 {
295  NS_LOG_FUNCTION (this << s);
296  m_cphySapProvider.at(index) = s;
297 }
298 
301 {
302  NS_LOG_FUNCTION (this);
303  return m_cphySapUser.at(0);
304 }
305 
308 {
309  NS_LOG_FUNCTION (this);
310  return m_cphySapUser.at(index);
311 }
312 
313 void
315 {
316  NS_LOG_FUNCTION (this << s);
317  m_cmacSapProvider.at (0) = s;
318 }
319 
320 void
322 {
323  NS_LOG_FUNCTION (this << s);
324  m_cmacSapProvider.at (index) = s;
325 }
326 
329 {
330  NS_LOG_FUNCTION (this);
331  return m_cmacSapUser.at (0);
332 }
333 
336 {
337  NS_LOG_FUNCTION (this);
338  return m_cmacSapUser.at (index);
339 }
340 
341 void
343 {
344  NS_LOG_FUNCTION (this << s);
345  m_rrcSapUser = s;
346 }
347 
350 {
351  NS_LOG_FUNCTION (this);
352  return m_rrcSapProvider;
353 }
354 
355 void
357 {
358  NS_LOG_FUNCTION (this << s);
359  m_macSapProvider = s;
360 }
361 
362 void
364 {
365  NS_LOG_FUNCTION (this << s);
367 }
368 
371 {
372  NS_LOG_FUNCTION (this);
373  return m_ccmRrcSapUser;
374 }
375 
376 void
378 {
379  m_asSapUser = s;
380 }
381 
384 {
385  return m_asSapProvider;
386 }
387 
388 void
389 LteUeRrc::SetImsi (uint64_t imsi)
390 {
391  NS_LOG_FUNCTION (this << imsi);
392  m_imsi = imsi;
393 }
394 
395 uint64_t
396 LteUeRrc::GetImsi (void) const
397 {
398  return m_imsi;
399 }
400 
401 uint16_t
403 {
404  NS_LOG_FUNCTION (this);
405  return m_rnti;
406 }
407 
408 uint16_t
410 {
411  NS_LOG_FUNCTION (this);
412  return m_cellId;
413 }
414 
415 
416 uint8_t
418 {
419  NS_LOG_FUNCTION (this);
420  return m_ulBandwidth;
421 }
422 
423 uint8_t
425 {
426  NS_LOG_FUNCTION (this);
427  return m_dlBandwidth;
428 }
429 
430 uint32_t
432 {
433  return m_dlEarfcn;
434 }
435 
436 uint32_t
438 {
439  NS_LOG_FUNCTION (this);
440  return m_ulEarfcn;
441 }
442 
444 LteUeRrc::GetState (void) const
445 {
446  NS_LOG_FUNCTION (this);
447  return m_state;
448 }
449 
450 void
452 {
453  NS_LOG_FUNCTION (this);
454  m_useRlcSm = val;
455 }
456 
457 
458 void
460 {
461  NS_LOG_FUNCTION (this);
462 
463  // setup the UE side of SRB0
464  uint8_t lcid = 0;
465 
466  Ptr<LteRlc> rlc = CreateObject<LteRlcTm> ()->GetObject<LteRlc> ();
468  rlc->SetRnti (m_rnti);
469  rlc->SetLcId (lcid);
470 
471  m_srb0 = CreateObject<LteSignalingRadioBearerInfo> ();
472  m_srb0->m_rlc = rlc;
473  m_srb0->m_srbIdentity = 0;
475  ueParams.srb0SapProvider = m_srb0->m_rlc->GetLteRlcSapProvider ();
476  ueParams.srb1SapProvider = 0;
477  m_rrcSapUser->Setup (ueParams);
478 
479  // CCCH (LCID 0) is pre-configured, here is the hardcoded configuration:
481  lcConfig.priority = 0; // highest priority
482  lcConfig.prioritizedBitRateKbps = 65535; // maximum
483  lcConfig.bucketSizeDurationMs = 65535; // maximum
484  lcConfig.logicalChannelGroup = 0; // all SRBs mapped to LCG 0
485  m_cmacSapProvider.at(0)->AddLc (lcid, lcConfig, rlc->GetLteMacSapUser ());
486 }
487 
488 void
490 {
491  if (m_numberOfComponentCarriers < MIN_NO_CC || m_numberOfComponentCarriers > MAX_NO_CC)
492  {
493  // this check is neede in order to maintain backward compatibility with scripts and tests
494  // if case lte-helper is not used (like in several tests) the m_numberOfComponentCarriers
495  // is not set and then an error is rised
496  // In this case m_numberOfComponentCarriers is set to 1
498  }
500  {
501  for ( uint16_t i = 1; i < m_numberOfComponentCarriers; i++)
502  {
503  m_cphySapUser.push_back(new MemberLteUeCphySapUser<LteUeRrc> (this));
504  m_cmacSapUser.push_back(new UeMemberLteUeCmacSapUser (this));
505  m_cphySapProvider.push_back(0);
506  m_cmacSapProvider.push_back(0);
507  }
508  }
509 }
510 
511 
512 void
513 LteUeRrc::DoSendData (Ptr<Packet> packet, uint8_t bid)
514 {
515  NS_LOG_FUNCTION (this << packet);
516 
517  uint8_t drbid = Bid2Drbid (bid);
518 
519  if (drbid != 0)
520  {
521  std::map<uint8_t, Ptr<LteDataRadioBearerInfo> >::iterator it = m_drbMap.find (drbid);
522  NS_ASSERT_MSG (it != m_drbMap.end (), "could not find bearer with drbid == " << drbid);
523 
525  params.pdcpSdu = packet;
526  params.rnti = m_rnti;
527  params.lcid = it->second->m_logicalChannelIdentity;
528 
529  NS_LOG_LOGIC (this << " RNTI=" << m_rnti << " sending packet " << packet
530  << " on DRBID " << (uint32_t) drbid
531  << " (LCID " << (uint32_t) params.lcid << ")"
532  << " (" << packet->GetSize () << " bytes)");
533  it->second->m_pdcp->GetLtePdcpSapProvider ()->TransmitPdcpSdu (params);
534  }
535 }
536 
537 
538 void
540 {
541  NS_LOG_FUNCTION (this);
542 
543  switch (m_state)
544  {
545  case IDLE_START:
546  case IDLE_CELL_SEARCH:
547  case IDLE_WAIT_MIB_SIB1:
548  case IDLE_WAIT_MIB:
549  case IDLE_WAIT_SIB1:
551  NS_LOG_INFO ("already disconnected");
552  break;
553 
554  case IDLE_WAIT_SIB2:
555  case IDLE_CONNECTING:
556  NS_FATAL_ERROR ("cannot abort connection setup procedure");
557  break;
558 
559  case CONNECTED_NORMALLY:
560  case CONNECTED_HANDOVER:
564  break;
565 
566  default: // i.e. IDLE_RANDOM_ACCESS
567  NS_FATAL_ERROR ("method unexpected in state " << ToString (m_state));
568  break;
569  }
570 }
571 
572 void
574 {
575  NS_LOG_FUNCTION (this);
576  m_asSapUser->RecvData (params.pdcpSdu);
577 }
578 
579 
580 void
582 {
583  NS_LOG_FUNCTION (this << rnti);
584  m_rnti = rnti;
585  m_srb0->m_rlc->SetRnti (m_rnti);
586  m_cphySapProvider.at(0)->SetRnti (m_rnti);
587 }
588 
589 void
591 {
592  NS_LOG_FUNCTION (this << m_imsi << ToString (m_state));
594 
595  switch (m_state)
596  {
597  case IDLE_RANDOM_ACCESS:
598  {
599  // we just received a RAR with a T-C-RNTI and an UL grant
600  // send RRC connection request as message 3 of the random access procedure
603  msg.ueIdentity = m_imsi;
607  this);
608  }
609  break;
610 
611  case CONNECTED_HANDOVER:
612  {
616 
617  // 3GPP TS 36.331 section 5.5.6.1 Measurements related actions upon handover
618  std::map<uint8_t, LteRrcSap::MeasIdToAddMod>::iterator measIdIt;
619  for (measIdIt = m_varMeasConfig.measIdList.begin ();
620  measIdIt != m_varMeasConfig.measIdList.end ();
621  ++measIdIt)
622  {
623  VarMeasReportListClear (measIdIt->second.measId);
624  }
625 
628  }
629  break;
630 
631  default:
632  NS_FATAL_ERROR ("unexpected event in state " << ToString (m_state));
633  break;
634  }
635 }
636 
637 void
639 {
640  NS_LOG_FUNCTION (this << m_imsi << ToString (m_state));
642 
643  switch (m_state)
644  {
645  case IDLE_RANDOM_ACCESS:
646  {
649  }
650  break;
651 
652  case CONNECTED_HANDOVER:
653  {
660  }
661  break;
662 
663  default:
664  NS_FATAL_ERROR ("unexpected event in state " << ToString (m_state));
665  break;
666  }
667 }
668 
669 
670 void
672 {
673  NS_LOG_FUNCTION (this << m_imsi << csgId);
674  m_csgWhiteList = csgId;
675 }
676 
677 void
679 {
680  NS_LOG_FUNCTION (this << m_imsi << dlEarfcn);
682  "cannot start cell selection from state " << ToString (m_state));
683  m_dlEarfcn = dlEarfcn;
684  m_cphySapProvider.at(0)->StartCellSearch (dlEarfcn);
686 }
687 
688 void
689 LteUeRrc::DoForceCampedOnEnb (uint16_t cellId, uint32_t dlEarfcn)
690 {
691  NS_LOG_FUNCTION (this << m_imsi << cellId << dlEarfcn);
692 
693  switch (m_state)
694  {
695  case IDLE_START:
696  m_cellId = cellId;
697  m_dlEarfcn = dlEarfcn;
698  m_cphySapProvider.at(0)->SynchronizeWithEnb (m_cellId, m_dlEarfcn);
700  break;
701 
702  case IDLE_CELL_SEARCH:
703  case IDLE_WAIT_MIB_SIB1:
704  case IDLE_WAIT_SIB1:
705  NS_FATAL_ERROR ("cannot abort cell selection " << ToString (m_state));
706  break;
707 
708  case IDLE_WAIT_MIB:
709  NS_LOG_INFO ("already forced to camp to cell " << m_cellId);
710  break;
711 
713  case IDLE_WAIT_SIB2:
714  case IDLE_RANDOM_ACCESS:
715  case IDLE_CONNECTING:
716  NS_LOG_INFO ("already camped to cell " << m_cellId);
717  break;
718 
719  case CONNECTED_NORMALLY:
720  case CONNECTED_HANDOVER:
723  NS_LOG_INFO ("already connected to cell " << m_cellId);
724  break;
725 
726  default:
727  NS_FATAL_ERROR ("unexpected event in state " << ToString (m_state));
728  break;
729  }
730 
731 }
732 
733 void
735 {
736  NS_LOG_FUNCTION (this << m_imsi);
737 
738  switch (m_state)
739  {
740  case IDLE_START:
741  case IDLE_CELL_SEARCH:
742  case IDLE_WAIT_MIB_SIB1:
743  case IDLE_WAIT_SIB1:
744  case IDLE_WAIT_MIB:
745  m_connectionPending = true;
746  break;
747 
749  m_connectionPending = true;
751  break;
752 
753  case IDLE_WAIT_SIB2:
754  case IDLE_RANDOM_ACCESS:
755  case IDLE_CONNECTING:
756  NS_LOG_INFO ("already connecting");
757  break;
758 
759  case CONNECTED_NORMALLY:
761  case CONNECTED_HANDOVER:
762  NS_LOG_INFO ("already connected");
763  break;
764 
765  default:
766  NS_FATAL_ERROR ("unexpected event in state " << ToString (m_state));
767  break;
768  }
769 }
770 
771 
772 
773 // CPHY SAP methods
774 
775 void
778 {
780  m_cphySapProvider.at(0)->SetDlBandwidth (msg.dlBandwidth);
781  m_hasReceivedMib = true;
783 
784  switch (m_state)
785  {
786  case IDLE_WAIT_MIB:
787  // manual attachment
789  break;
790 
791  case IDLE_WAIT_MIB_SIB1:
792  // automatic attachment from Idle mode cell selection
794  break;
795 
796  default:
797  // do nothing extra
798  break;
799  }
800 }
801 
802 void
805 {
806  NS_LOG_FUNCTION (this);
807  switch (m_state)
808  {
809  case IDLE_WAIT_SIB1:
811  "Cell identity in SIB1 does not match with the originating cell");
812  m_hasReceivedSib1 = true;
813  m_lastSib1 = msg;
816  break;
817 
819  case IDLE_RANDOM_ACCESS:
820  case IDLE_CONNECTING:
821  case CONNECTED_NORMALLY:
822  case CONNECTED_HANDOVER:
826  "Cell identity in SIB1 does not match with the originating cell");
827  m_hasReceivedSib1 = true;
828  m_lastSib1 = msg;
830  break;
831 
832  case IDLE_WAIT_MIB_SIB1:
833  // MIB has not been received, so ignore this SIB1
834  break;
835 
836  default: // e.g. IDLE_START, IDLE_CELL_SEARCH, IDLE_WAIT_MIB, IDLE_WAIT_SIB2
837  // do nothing
838  break;
839  }
840 }
841 
842 void
844 {
845  NS_LOG_FUNCTION (this);
846 
847  // layer 3 filtering does not apply in IDLE mode
848  bool useLayer3Filtering = (m_state == CONNECTED_NORMALLY);
849  bool triggering = true;
850  std::vector <LteUeCphySapUser::UeMeasurementsElement>::iterator newMeasIt;
851  for (newMeasIt = params.m_ueMeasurementsList.begin ();
852  newMeasIt != params.m_ueMeasurementsList.end (); ++newMeasIt)
853  {
854  if (params.m_componentCarrierId != 0)
855  {
856  triggering = false; // report is triggered only when an event is on the primary carrier
857  // in this case the measurement received is related to secondary carriers
858  // measurements related to secondary carriers are saved on a different portion of memory
859  SaveScellUeMeasurements (newMeasIt->m_cellId, newMeasIt->m_rsrp,
860  newMeasIt->m_rsrq, useLayer3Filtering,
861  params.m_componentCarrierId );
862  }
863  else
864  {
865  SaveUeMeasurements (newMeasIt->m_cellId, newMeasIt->m_rsrp,
866  newMeasIt->m_rsrq, useLayer3Filtering);
867  }
868  }
869 
870  if (m_state == IDLE_CELL_SEARCH)
871  {
872  // start decoding BCH
874  }
875  else
876  {
877  if (triggering)
878  {
879  std::map<uint8_t, LteRrcSap::MeasIdToAddMod>::iterator measIdIt;
880  for (measIdIt = m_varMeasConfig.measIdList.begin ();
881  measIdIt != m_varMeasConfig.measIdList.end (); ++measIdIt)
882  {
883  MeasurementReportTriggering (measIdIt->first);
884  }
885  }
886  }
887 
888 } // end of LteUeRrc::DoReportUeMeasurements
889 
890 
891 
892 // RRC SAP methods
893 
894 void
896 {
897  NS_LOG_FUNCTION (this << " RNTI " << m_rnti);
898  m_srb0->m_rlc->SetLteRlcSapUser (params.srb0SapUser);
899  if (m_srb1)
900  {
901  m_srb1->m_pdcp->SetLtePdcpSapUser (params.srb1SapUser);
902  }
903 }
904 
905 
906 void
908 {
909  NS_LOG_FUNCTION (this << " RNTI " << m_rnti);
910 
911  if (msg.haveSib2)
912  {
913  switch (m_state)
914  {
916  case IDLE_WAIT_SIB2:
917  case IDLE_RANDOM_ACCESS:
918  case IDLE_CONNECTING:
919  case CONNECTED_NORMALLY:
920  case CONNECTED_HANDOVER:
923  m_hasReceivedSib2 = true;
931  m_cmacSapProvider.at (0)->ConfigureRach (rc);
932  m_cphySapProvider.at (0)->ConfigureUplink (m_ulEarfcn, m_ulBandwidth);
933  m_cphySapProvider.at (0)->ConfigureReferenceSignalPower (msg.sib2.radioResourceConfigCommon.pdschConfigCommon.referenceSignalPower);
934  if (m_state == IDLE_WAIT_SIB2)
935  {
937  StartConnection ();
938  }
939  break;
940 
941  default: // IDLE_START, IDLE_CELL_SEARCH, IDLE_WAIT_MIB, IDLE_WAIT_MIB_SIB1, IDLE_WAIT_SIB1
942  // do nothing
943  break;
944  }
945  }
946 
947 }
948 
949 
950 void
952 {
953  NS_LOG_FUNCTION (this << " RNTI " << m_rnti);
954  switch (m_state)
955  {
956  case IDLE_CONNECTING:
957  {
966  }
967  break;
968 
969  default:
970  NS_FATAL_ERROR ("method unexpected in state " << ToString (m_state));
971  break;
972  }
973 }
974 
975 void
977 {
978  NS_LOG_FUNCTION (this << " RNTI " << m_rnti);
979  NS_LOG_INFO ("DoRecvRrcConnectionReconfiguration haveNonCriticalExtension:" << msg.haveNonCriticalExtension );
980  switch (m_state)
981  {
982  case CONNECTED_NORMALLY:
983  if (msg.haveMobilityControlInfo)
984  {
985  NS_LOG_INFO ("haveMobilityControlInfo == true");
989  m_cmacSapProvider.at(0)->Reset ();
990  m_cphySapProvider.at(0)->Reset ();
994  m_cphySapProvider.at(0)->SynchronizeWithEnb (m_cellId, mci.carrierFreq.dlCarrierFreq);
995  m_cphySapProvider.at(0)->SetDlBandwidth ( mci.carrierBandwidth.dlBandwidth);
996  m_cphySapProvider.at(0)->ConfigureUplink (mci.carrierFreq.ulCarrierFreq, mci.carrierBandwidth.ulBandwidth);
998  m_srb0->m_rlc->SetRnti (m_rnti);
999  NS_ASSERT_MSG (mci.haveRachConfigDedicated, "handover is only supported with non-contention-based random access procedure");
1000  m_cmacSapProvider.at(0)->StartNonContentionBasedRandomAccessProcedure (m_rnti, mci.rachConfigDedicated.raPreambleIndex, mci.rachConfigDedicated.raPrachMaskIndex);
1001  m_cphySapProvider.at(0)->SetRnti (m_rnti);
1004 
1005  // we re-establish SRB1 by creating a new entity
1006  // note that we can't dispose the old entity now, because
1007  // it's in the current stack, so we would corrupt the stack
1008  // if we did so. Hence we schedule it for later disposal
1009  m_srb1Old = m_srb1;
1011  m_srb1 = 0; // new instance will be be created within ApplyRadioResourceConfigDedicated
1012 
1013  m_drbMap.clear (); // dispose all DRBs
1015 
1016  if (msg.haveMeasConfig)
1017  {
1019  }
1020  // RRC connection reconfiguration completed will be sent
1021  // after handover is complete
1022  }
1023  else
1024  {
1025  NS_LOG_INFO ("haveMobilityControlInfo == false");
1026  if (msg.haveNonCriticalExtension)
1027  {
1029  NS_LOG_FUNCTION ( this << "RNTI " << m_rnti << " Configured for CA" );
1030  }
1032  {
1034  }
1035  if (msg.haveMeasConfig)
1036  {
1038  }
1043  }
1044  break;
1045 
1046  default:
1047  NS_FATAL_ERROR ("method unexpected in state " << ToString (m_state));
1048  break;
1049  }
1050 }
1051 
1052 void
1054 {
1055  NS_LOG_FUNCTION (this << " RNTI " << m_rnti);
1056  switch (m_state)
1057  {
1059  {
1067  }
1068  break;
1069 
1070  default:
1071  NS_FATAL_ERROR ("method unexpected in state " << ToString (m_state));
1072  break;
1073  }
1074 }
1075 
1076 void
1078 {
1079  NS_LOG_FUNCTION (this << " RNTI " << m_rnti);
1080  switch (m_state)
1081  {
1083  {
1088  LeaveConnectedMode ();
1089  }
1090  break;
1091 
1092  default:
1093  NS_FATAL_ERROR ("method unexpected in state " << ToString (m_state));
1094  break;
1095  }
1096 }
1097 
1098 void
1100 {
1101  NS_LOG_FUNCTION (this << " RNTI " << m_rnti);
1103 }
1104 
1105 void
1107 {
1108  NS_LOG_FUNCTION (this);
1110 
1111  m_cmacSapProvider.at (0)->Reset (); // reset the MAC
1112  m_hasReceivedSib2 = false; // invalidate the previously received SIB2
1114  m_asSapUser->NotifyConnectionFailed (); // inform upper layer
1115 }
1116 
1117 
1118 
1119 void
1121 {
1122  NS_LOG_FUNCTION (this);
1124 
1125  uint16_t maxRsrpCellId = 0;
1126  double maxRsrp = -std::numeric_limits<double>::infinity ();
1127 
1128  std::map<uint16_t, MeasValues>::iterator it;
1129  for (it = m_storedMeasValues.begin (); it != m_storedMeasValues.end (); it++)
1130  {
1131  /*
1132  * This block attempts to find a cell with strongest RSRP and has not
1133  * yet been identified as "acceptable cell".
1134  */
1135  if (maxRsrp < it->second.rsrp)
1136  {
1137  std::set<uint16_t>::const_iterator itCell;
1138  itCell = m_acceptableCell.find (it->first);
1139  if (itCell == m_acceptableCell.end ())
1140  {
1141  maxRsrpCellId = it->first;
1142  maxRsrp = it->second.rsrp;
1143  }
1144  }
1145  }
1146 
1147  if (maxRsrpCellId == 0)
1148  {
1149  NS_LOG_WARN (this << " Cell search is unable to detect surrounding cell to attach to");
1150  }
1151  else
1152  {
1153  NS_LOG_LOGIC (this << " cell " << maxRsrpCellId
1154  << " is the strongest untried surrounding cell");
1155  m_cphySapProvider.at(0)->SynchronizeWithEnb (maxRsrpCellId, m_dlEarfcn);
1157  }
1158 
1159 } // end of void LteUeRrc::SynchronizeToStrongestCell ()
1160 
1161 
1162 void
1164 {
1165  NS_LOG_FUNCTION (this);
1169  uint16_t cellId = m_lastSib1.cellAccessRelatedInfo.cellIdentity;
1170 
1171  // Cell selection criteria evaluation
1172 
1173  bool isSuitableCell = false;
1174  bool isAcceptableCell = false;
1175  std::map<uint16_t, MeasValues>::iterator storedMeasIt = m_storedMeasValues.find (cellId);
1176  double qRxLevMeas = storedMeasIt->second.rsrp;
1178  NS_LOG_LOGIC (this << " cell selection to cellId=" << cellId
1179  << " qrxlevmeas=" << qRxLevMeas << " dBm"
1180  << " qrxlevmin=" << qRxLevMin << " dBm");
1181 
1182  if (qRxLevMeas - qRxLevMin > 0)
1183  {
1184  isAcceptableCell = true;
1185 
1186  uint32_t cellCsgId = m_lastSib1.cellAccessRelatedInfo.csgIdentity;
1187  bool cellCsgIndication = m_lastSib1.cellAccessRelatedInfo.csgIndication;
1188 
1189  isSuitableCell = (cellCsgIndication == false) || (cellCsgId == m_csgWhiteList);
1190 
1191  NS_LOG_LOGIC (this << " csg(ue/cell/indication)=" << m_csgWhiteList << "/"
1192  << cellCsgId << "/" << cellCsgIndication);
1193  }
1194 
1195  // Cell selection decision
1196 
1197  if (isSuitableCell)
1198  {
1199  m_cellId = cellId;
1200  m_cphySapProvider.at(0)->SynchronizeWithEnb (cellId, m_dlEarfcn);
1201  m_cphySapProvider.at(0)->SetDlBandwidth (m_dlBandwidth);
1204  }
1205  else
1206  {
1207  // ignore the MIB and SIB1 received from this cell
1208  m_hasReceivedMib = false;
1209  m_hasReceivedSib1 = false;
1210 
1212 
1213  if (isAcceptableCell)
1214  {
1215  /*
1216  * The cells inserted into this list will not be considered for
1217  * subsequent cell search attempt.
1218  */
1219  m_acceptableCell.insert (cellId);
1220  }
1221 
1223  SynchronizeToStrongestCell (); // retry to a different cell
1224  }
1225 
1226 } // end of void LteUeRrc::EvaluateCellForSelection ()
1227 
1228 
1229 void
1231 {
1232  NS_LOG_FUNCTION (this);
1233 
1234  for(std::list<LteRrcSap::SCellToAddMod>::iterator it = nonCec.sCellsToAddModList.begin(); it!=nonCec.sCellsToAddModList.end(); it++)
1235  {
1236  LteRrcSap::SCellToAddMod scell = *it;
1237  uint8_t ccId = scell.sCellIndex;
1238 
1239 
1240  uint16_t physCellId = scell.cellIdentification.physCellId;
1244  uint32_t dlEarfcn = scell.cellIdentification.dlCarrierFreq;
1247 
1248  m_cphySapProvider.at (ccId)->SynchronizeWithEnb (physCellId, dlEarfcn);
1249  m_cphySapProvider.at (ccId)->SetDlBandwidth (dlBand);
1250  m_cphySapProvider.at (ccId)->ConfigureUplink (ulEarfcn, ulBand);
1252  m_cphySapProvider.at (ccId)->SetTransmissionMode (txMode);
1253  m_cphySapProvider.at (ccId)->SetRnti(m_rnti);
1254  m_cmacSapProvider.at (ccId)->SetRnti(m_rnti);
1255  // update PdschConfigDedicated (i.e. P_A value)
1257  double paDouble = LteRrcSap::ConvertPdschConfigDedicated2Double (pdschConfigDedicated);
1258  m_cphySapProvider.at (ccId)->SetPa (paDouble);
1259  m_cphySapProvider.at (ccId)->SetSrsConfigurationIndex (srsIndex);
1260  }
1261 }
1262 
1263 void
1265 {
1266  NS_LOG_FUNCTION (this);
1268 
1269  if (pcd.haveAntennaInfoDedicated)
1270  {
1271  m_cphySapProvider.at(0)->SetTransmissionMode (pcd.antennaInfo.transmissionMode);
1272  }
1274  {
1275  m_cphySapProvider.at(0)->SetSrsConfigurationIndex (pcd.soundingRsUlConfigDedicated.srsConfigIndex);
1276  }
1277 
1278  if (pcd.havePdschConfigDedicated)
1279  {
1280  // update PdschConfigDedicated (i.e. P_A value)
1283  m_cphySapProvider.at(0)->SetPa (paDouble);
1284  }
1285 
1286  std::list<LteRrcSap::SrbToAddMod>::const_iterator stamIt = rrcd.srbToAddModList.begin ();
1287  if (stamIt != rrcd.srbToAddModList.end ())
1288  {
1289  if (m_srb1 == 0)
1290  {
1291  // SRB1 not setup yet
1293  "unexpected state " << ToString (m_state));
1294  NS_ASSERT_MSG (stamIt->srbIdentity == 1, "only SRB1 supported");
1295 
1296  const uint8_t lcid = 1; // fixed LCID for SRB1
1297 
1298  Ptr<LteRlc> rlc = CreateObject<LteRlcAm> ();
1300  rlc->SetRnti (m_rnti);
1301  rlc->SetLcId (lcid);
1302 
1303  Ptr<LtePdcp> pdcp = CreateObject<LtePdcp> ();
1304  pdcp->SetRnti (m_rnti);
1305  pdcp->SetLcId (lcid);
1306  pdcp->SetLtePdcpSapUser (m_drbPdcpSapUser);
1307  pdcp->SetLteRlcSapProvider (rlc->GetLteRlcSapProvider ());
1308  rlc->SetLteRlcSapUser (pdcp->GetLteRlcSapUser ());
1309 
1310  m_srb1 = CreateObject<LteSignalingRadioBearerInfo> ();
1311  m_srb1->m_rlc = rlc;
1312  m_srb1->m_pdcp = pdcp;
1313  m_srb1->m_srbIdentity = 1;
1314 
1315  m_srb1->m_logicalChannelConfig.priority = stamIt->logicalChannelConfig.priority;
1316  m_srb1->m_logicalChannelConfig.prioritizedBitRateKbps = stamIt->logicalChannelConfig.prioritizedBitRateKbps;
1317  m_srb1->m_logicalChannelConfig.bucketSizeDurationMs = stamIt->logicalChannelConfig.bucketSizeDurationMs;
1318  m_srb1->m_logicalChannelConfig.logicalChannelGroup = stamIt->logicalChannelConfig.logicalChannelGroup;
1319 
1321  lcConfig.priority = stamIt->logicalChannelConfig.priority;
1322  lcConfig.prioritizedBitRateKbps = stamIt->logicalChannelConfig.prioritizedBitRateKbps;
1323  lcConfig.bucketSizeDurationMs = stamIt->logicalChannelConfig.bucketSizeDurationMs;
1324  lcConfig.logicalChannelGroup = stamIt->logicalChannelConfig.logicalChannelGroup;
1325  m_cmacSapProvider.at (0)->AddLc (lcid, lcConfig, rlc->GetLteMacSapUser ());
1326  ++stamIt;
1327  NS_ASSERT_MSG (stamIt == rrcd.srbToAddModList.end (), "at most one SrbToAdd supported");
1328 
1330  ueParams.srb0SapProvider = m_srb0->m_rlc->GetLteRlcSapProvider ();
1331  ueParams.srb1SapProvider = m_srb1->m_pdcp->GetLtePdcpSapProvider ();
1332  m_rrcSapUser->Setup (ueParams);
1333  }
1334  else
1335  {
1336  NS_LOG_INFO ("request to modify SRB1 (skipping as currently not implemented)");
1337  // would need to modify m_srb1, and then propagate changes to the MAC
1338  }
1339  }
1340 
1341 
1342  std::list<LteRrcSap::DrbToAddMod>::const_iterator dtamIt;
1343  for (dtamIt = rrcd.drbToAddModList.begin ();
1344  dtamIt != rrcd.drbToAddModList.end ();
1345  ++dtamIt)
1346  {
1347  NS_LOG_INFO (this << " IMSI " << m_imsi << " adding/modifying DRBID " << (uint32_t) dtamIt->drbIdentity << " LC " << (uint32_t) dtamIt->logicalChannelIdentity);
1348  NS_ASSERT_MSG (dtamIt->logicalChannelIdentity > 2, "LCID value " << dtamIt->logicalChannelIdentity << " is reserved for SRBs");
1349 
1350  std::map<uint8_t, Ptr<LteDataRadioBearerInfo> >::iterator drbMapIt = m_drbMap.find (dtamIt->drbIdentity);
1351  if (drbMapIt == m_drbMap.end ())
1352  {
1353  NS_LOG_INFO ("New Data Radio Bearer");
1354 
1355  TypeId rlcTypeId;
1356  if (m_useRlcSm)
1357  {
1358  rlcTypeId = LteRlcSm::GetTypeId ();
1359  }
1360  else
1361  {
1362  switch (dtamIt->rlcConfig.choice)
1363  {
1365  rlcTypeId = LteRlcAm::GetTypeId ();
1366  break;
1367 
1369  rlcTypeId = LteRlcUm::GetTypeId ();
1370  break;
1371 
1372  default:
1373  NS_FATAL_ERROR ("unsupported RLC configuration");
1374  break;
1375  }
1376  }
1377 
1378  ObjectFactory rlcObjectFactory;
1379  rlcObjectFactory.SetTypeId (rlcTypeId);
1380  Ptr<LteRlc> rlc = rlcObjectFactory.Create ()->GetObject<LteRlc> ();
1382  rlc->SetRnti (m_rnti);
1383  rlc->SetLcId (dtamIt->logicalChannelIdentity);
1384 
1385  Ptr<LteDataRadioBearerInfo> drbInfo = CreateObject<LteDataRadioBearerInfo> ();
1386  drbInfo->m_rlc = rlc;
1387  drbInfo->m_epsBearerIdentity = dtamIt->epsBearerIdentity;
1388  drbInfo->m_logicalChannelIdentity = dtamIt->logicalChannelIdentity;
1389  drbInfo->m_drbIdentity = dtamIt->drbIdentity;
1390 
1391  // we need PDCP only for real RLC, i.e., RLC/UM or RLC/AM
1392  // if we are using RLC/SM we don't care of anything above RLC
1393  if (rlcTypeId != LteRlcSm::GetTypeId ())
1394  {
1395  Ptr<LtePdcp> pdcp = CreateObject<LtePdcp> ();
1396  pdcp->SetRnti (m_rnti);
1397  pdcp->SetLcId (dtamIt->logicalChannelIdentity);
1398  pdcp->SetLtePdcpSapUser (m_drbPdcpSapUser);
1399  pdcp->SetLteRlcSapProvider (rlc->GetLteRlcSapProvider ());
1400  rlc->SetLteRlcSapUser (pdcp->GetLteRlcSapUser ());
1401  drbInfo->m_pdcp = pdcp;
1402  }
1403 
1404  m_bid2DrbidMap[dtamIt->epsBearerIdentity] = dtamIt->drbIdentity;
1405 
1406  m_drbMap.insert (std::pair<uint8_t, Ptr<LteDataRadioBearerInfo> > (dtamIt->drbIdentity, drbInfo));
1407 
1408 
1410  lcConfig.priority = dtamIt->logicalChannelConfig.priority;
1411  lcConfig.prioritizedBitRateKbps = dtamIt->logicalChannelConfig.prioritizedBitRateKbps;
1412  lcConfig.bucketSizeDurationMs = dtamIt->logicalChannelConfig.bucketSizeDurationMs;
1413  lcConfig.logicalChannelGroup = dtamIt->logicalChannelConfig.logicalChannelGroup;
1414 
1415  for (uint32_t i = 0; i < m_numberOfComponentCarriers; i++)
1416  {
1417  m_cmacSapProvider.at (i)->AddLc (dtamIt->logicalChannelIdentity,
1418  lcConfig,
1419  rlc->GetLteMacSapUser ());
1420  }
1421  rlc->Initialize ();
1422  }
1423  else
1424  {
1425  NS_LOG_INFO ("request to modify existing DRBID");
1426  Ptr<LteDataRadioBearerInfo> drbInfo = drbMapIt->second;
1428  }
1429  }
1430 
1431  std::list<uint8_t>::iterator dtdmIt;
1432  for (dtdmIt = rrcd.drbToReleaseList.begin ();
1433  dtdmIt != rrcd.drbToReleaseList.end ();
1434  ++dtdmIt)
1435  {
1436  uint8_t drbid = *dtdmIt;
1437  NS_LOG_INFO (this << " IMSI " << m_imsi << " releasing DRB " << (uint32_t) drbid << drbid);
1438  std::map<uint8_t, Ptr<LteDataRadioBearerInfo> >::iterator it = m_drbMap.find (drbid);
1439  NS_ASSERT_MSG (it != m_drbMap.end (), "could not find bearer with given lcid");
1440  m_drbMap.erase (it);
1441  m_bid2DrbidMap.erase (drbid);
1442  //Remove LCID
1443  for (uint32_t i = 0; i < m_numberOfComponentCarriers; i++)
1444  {
1445  m_cmacSapProvider.at (i)->RemoveLc (drbid + 2);
1446  }
1447  }
1448 }
1449 
1450 
1451 void
1453 {
1454  NS_LOG_FUNCTION (this);
1455 
1456  // perform the actions specified in 3GPP TS 36.331 section 5.5.2.1
1457 
1458  // 3GPP TS 36.331 section 5.5.2.4 Measurement object removal
1459  for (std::list<uint8_t>::iterator it = mc.measObjectToRemoveList.begin ();
1460  it != mc.measObjectToRemoveList.end ();
1461  ++it)
1462  {
1463  uint8_t measObjectId = *it;
1464  NS_LOG_LOGIC (this << " deleting measObjectId " << (uint32_t) measObjectId);
1465  m_varMeasConfig.measObjectList.erase (measObjectId);
1466  std::map<uint8_t, LteRrcSap::MeasIdToAddMod>::iterator measIdIt = m_varMeasConfig.measIdList.begin ();
1467  while (measIdIt != m_varMeasConfig.measIdList.end ())
1468  {
1469  if (measIdIt->second.measObjectId == measObjectId)
1470  {
1471  uint8_t measId = measIdIt->second.measId;
1472  NS_ASSERT (measId == measIdIt->first);
1473  NS_LOG_LOGIC (this << " deleting measId " << (uint32_t) measId << " because referring to measObjectId " << (uint32_t) measObjectId);
1474  // note: postfix operator preserves iterator validity
1475  m_varMeasConfig.measIdList.erase (measIdIt++);
1476  VarMeasReportListClear (measId);
1477  }
1478  else
1479  {
1480  ++measIdIt;
1481  }
1482  }
1483 
1484  }
1485 
1486  // 3GPP TS 36.331 section 5.5.2.5 Measurement object addition/ modification
1487  for (std::list<LteRrcSap::MeasObjectToAddMod>::iterator it = mc.measObjectToAddModList.begin ();
1488  it != mc.measObjectToAddModList.end ();
1489  ++it)
1490  {
1491  // simplifying assumptions
1492  NS_ASSERT_MSG (it->measObjectEutra.cellsToRemoveList.empty (), "cellsToRemoveList not supported");
1493  NS_ASSERT_MSG (it->measObjectEutra.cellsToAddModList.empty (), "cellsToAddModList not supported");
1494  NS_ASSERT_MSG (it->measObjectEutra.cellsToRemoveList.empty (), "blackCellsToRemoveList not supported");
1495  NS_ASSERT_MSG (it->measObjectEutra.blackCellsToAddModList.empty (), "blackCellsToAddModList not supported");
1496  NS_ASSERT_MSG (it->measObjectEutra.haveCellForWhichToReportCGI == false, "cellForWhichToReportCGI is not supported");
1497 
1498  uint8_t measObjectId = it->measObjectId;
1499  std::map<uint8_t, LteRrcSap::MeasObjectToAddMod>::iterator measObjectIt = m_varMeasConfig.measObjectList.find (measObjectId);
1500  if (measObjectIt != m_varMeasConfig.measObjectList.end ())
1501  {
1502  NS_LOG_LOGIC ("measObjectId " << (uint32_t) measObjectId << " exists, updating entry");
1503  measObjectIt->second = *it;
1504  for (std::map<uint8_t, LteRrcSap::MeasIdToAddMod>::iterator measIdIt
1505  = m_varMeasConfig.measIdList.begin ();
1506  measIdIt != m_varMeasConfig.measIdList.end ();
1507  ++measIdIt)
1508  {
1509  if (measIdIt->second.measObjectId == measObjectId)
1510  {
1511  uint8_t measId = measIdIt->second.measId;
1512  NS_LOG_LOGIC (this << " found measId " << (uint32_t) measId << " referring to measObjectId " << (uint32_t) measObjectId);
1513  VarMeasReportListClear (measId);
1514  }
1515  }
1516  }
1517  else
1518  {
1519  NS_LOG_LOGIC ("measObjectId " << (uint32_t) measObjectId << " is new, adding entry");
1520  m_varMeasConfig.measObjectList[measObjectId] = *it;
1521  }
1522 
1523  }
1524 
1525  // 3GPP TS 36.331 section 5.5.2.6 Reporting configuration removal
1526  for (std::list<uint8_t>::iterator it = mc.reportConfigToRemoveList.begin ();
1527  it != mc.reportConfigToRemoveList.end ();
1528  ++it)
1529  {
1530  uint8_t reportConfigId = *it;
1531  NS_LOG_LOGIC (this << " deleting reportConfigId " << (uint32_t) reportConfigId);
1532  m_varMeasConfig.reportConfigList.erase (reportConfigId);
1533  std::map<uint8_t, LteRrcSap::MeasIdToAddMod>::iterator measIdIt = m_varMeasConfig.measIdList.begin ();
1534  while (measIdIt != m_varMeasConfig.measIdList.end ())
1535  {
1536  if (measIdIt->second.reportConfigId == reportConfigId)
1537  {
1538  uint8_t measId = measIdIt->second.measId;
1539  NS_ASSERT (measId == measIdIt->first);
1540  NS_LOG_LOGIC (this << " deleting measId " << (uint32_t) measId << " because referring to reportConfigId " << (uint32_t) reportConfigId);
1541  // note: postfix operator preserves iterator validity
1542  m_varMeasConfig.measIdList.erase (measIdIt++);
1543  VarMeasReportListClear (measId);
1544  }
1545  else
1546  {
1547  ++measIdIt;
1548  }
1549  }
1550 
1551  }
1552 
1553  // 3GPP TS 36.331 section 5.5.2.7 Reporting configuration addition/ modification
1554  for (std::list<LteRrcSap::ReportConfigToAddMod>::iterator it = mc.reportConfigToAddModList.begin ();
1555  it != mc.reportConfigToAddModList.end ();
1556  ++it)
1557  {
1558  // simplifying assumptions
1559  NS_ASSERT_MSG (it->reportConfigEutra.triggerType == LteRrcSap::ReportConfigEutra::EVENT,
1560  "only trigger type EVENT is supported");
1561 
1562  uint8_t reportConfigId = it->reportConfigId;
1563  std::map<uint8_t, LteRrcSap::ReportConfigToAddMod>::iterator reportConfigIt = m_varMeasConfig.reportConfigList.find (reportConfigId);
1564  if (reportConfigIt != m_varMeasConfig.reportConfigList.end ())
1565  {
1566  NS_LOG_LOGIC ("reportConfigId " << (uint32_t) reportConfigId << " exists, updating entry");
1567  m_varMeasConfig.reportConfigList[reportConfigId] = *it;
1568  for (std::map<uint8_t, LteRrcSap::MeasIdToAddMod>::iterator measIdIt
1569  = m_varMeasConfig.measIdList.begin ();
1570  measIdIt != m_varMeasConfig.measIdList.end ();
1571  ++measIdIt)
1572  {
1573  if (measIdIt->second.reportConfigId == reportConfigId)
1574  {
1575  uint8_t measId = measIdIt->second.measId;
1576  NS_LOG_LOGIC (this << " found measId " << (uint32_t) measId << " referring to reportConfigId " << (uint32_t) reportConfigId);
1577  VarMeasReportListClear (measId);
1578  }
1579  }
1580  }
1581  else
1582  {
1583  NS_LOG_LOGIC ("reportConfigId " << (uint32_t) reportConfigId << " is new, adding entry");
1584  m_varMeasConfig.reportConfigList[reportConfigId] = *it;
1585  }
1586 
1587  }
1588 
1589  // 3GPP TS 36.331 section 5.5.2.8 Quantity configuration
1590  if (mc.haveQuantityConfig)
1591  {
1592  NS_LOG_LOGIC (this << " setting quantityConfig");
1594  // we calculate here the coefficient a used for Layer 3 filtering, see 3GPP TS 36.331 section 5.5.3.2
1595  m_varMeasConfig.aRsrp = std::pow (0.5, mc.quantityConfig.filterCoefficientRSRP / 4.0);
1596  m_varMeasConfig.aRsrq = std::pow (0.5, mc.quantityConfig.filterCoefficientRSRQ / 4.0);
1597  NS_LOG_LOGIC (this << " new filter coefficients: aRsrp=" << m_varMeasConfig.aRsrp << ", aRsrq=" << m_varMeasConfig.aRsrq);
1598 
1599  for (std::map<uint8_t, LteRrcSap::MeasIdToAddMod>::iterator measIdIt
1600  = m_varMeasConfig.measIdList.begin ();
1601  measIdIt != m_varMeasConfig.measIdList.end ();
1602  ++measIdIt)
1603  {
1604  VarMeasReportListClear (measIdIt->second.measId);
1605  }
1606  }
1607 
1608  // 3GPP TS 36.331 section 5.5.2.2 Measurement identity removal
1609  for (std::list<uint8_t>::iterator it = mc.measIdToRemoveList.begin ();
1610  it != mc.measIdToRemoveList.end ();
1611  ++it)
1612  {
1613  uint8_t measId = *it;
1614  NS_LOG_LOGIC (this << " deleting measId " << (uint32_t) measId);
1615  m_varMeasConfig.measIdList.erase (measId);
1616  VarMeasReportListClear (measId);
1617 
1618  // removing time-to-trigger queues
1619  m_enteringTriggerQueue.erase (measId);
1620  m_leavingTriggerQueue.erase (measId);
1621  }
1622 
1623  // 3GPP TS 36.331 section 5.5.2.3 Measurement identity addition/ modification
1624  for (std::list<LteRrcSap::MeasIdToAddMod>::iterator it = mc.measIdToAddModList.begin ();
1625  it != mc.measIdToAddModList.end ();
1626  ++it)
1627  {
1628  NS_LOG_LOGIC (this << " measId " << (uint32_t) it->measId
1629  << " (measObjectId=" << (uint32_t) it->measObjectId
1630  << ", reportConfigId=" << (uint32_t) it->reportConfigId
1631  << ")");
1632  NS_ASSERT (m_varMeasConfig.measObjectList.find (it->measObjectId)
1633  != m_varMeasConfig.measObjectList.end ());
1634  NS_ASSERT (m_varMeasConfig.reportConfigList.find (it->reportConfigId)
1635  != m_varMeasConfig.reportConfigList.end ());
1636  m_varMeasConfig.measIdList[it->measId] = *it; // side effect: create new entry if not exists
1637  std::map<uint8_t, VarMeasReport>::iterator measReportIt = m_varMeasReportList.find (it->measId);
1638  if (measReportIt != m_varMeasReportList.end ())
1639  {
1640  measReportIt->second.periodicReportTimer.Cancel ();
1641  m_varMeasReportList.erase (measReportIt);
1642  }
1643  NS_ASSERT (m_varMeasConfig.reportConfigList.find (it->reportConfigId)
1644  ->second.reportConfigEutra.triggerType != LteRrcSap::ReportConfigEutra::PERIODICAL);
1645 
1646  // new empty queues for time-to-trigger
1647  std::list<PendingTrigger_t> s;
1648  m_enteringTriggerQueue[it->measId] = s;
1649  m_leavingTriggerQueue[it->measId] = s;
1650  }
1651 
1652  if (mc.haveMeasGapConfig)
1653  {
1654  NS_FATAL_ERROR ("measurement gaps are currently not supported");
1655  }
1656 
1657  if (mc.haveSmeasure)
1658  {
1659  NS_FATAL_ERROR ("s-measure is currently not supported");
1660  }
1661 
1662  if (mc.haveSpeedStatePars)
1663  {
1664  NS_FATAL_ERROR ("SpeedStatePars are currently not supported");
1665  }
1666 }
1667 
1668 void
1669 LteUeRrc::SaveUeMeasurements (uint16_t cellId, double rsrp, double rsrq,
1670  bool useLayer3Filtering)
1671 {
1672  NS_LOG_FUNCTION (this << cellId << rsrp << rsrq << useLayer3Filtering);
1673 
1674  std::map<uint16_t, MeasValues>::iterator storedMeasIt = m_storedMeasValues.find (cellId);
1675 
1676  if (storedMeasIt != m_storedMeasValues.end ())
1677  {
1678  if (useLayer3Filtering)
1679  {
1680  // F_n = (1-a) F_{n-1} + a M_n
1681  storedMeasIt->second.rsrp = (1 - m_varMeasConfig.aRsrp) * storedMeasIt->second.rsrp
1682  + m_varMeasConfig.aRsrp * rsrp;
1683 
1684  if (std::isnan (storedMeasIt->second.rsrq))
1685  {
1686  // the previous RSRQ measurements provided UE PHY are invalid
1687  storedMeasIt->second.rsrq = rsrq; // replace it with unfiltered value
1688  }
1689  else
1690  {
1691  storedMeasIt->second.rsrq = (1 - m_varMeasConfig.aRsrq) * storedMeasIt->second.rsrq
1692  + m_varMeasConfig.aRsrq * rsrq;
1693  }
1694  }
1695  else
1696  {
1697  storedMeasIt->second.rsrp = rsrp;
1698  storedMeasIt->second.rsrq = rsrq;
1699  }
1700  }
1701  else
1702  {
1703  // first value is always unfiltered
1704  MeasValues v;
1705  v.rsrp = rsrp;
1706  v.rsrq = rsrq;
1707  std::pair<uint16_t, MeasValues> val (cellId, v);
1708  std::pair<std::map<uint16_t, MeasValues>::iterator, bool>
1709  ret = m_storedMeasValues.insert (val);
1710  NS_ASSERT_MSG (ret.second == true, "element already existed");
1711  storedMeasIt = ret.first;
1712  }
1713 
1714  NS_LOG_DEBUG (this << " IMSI " << m_imsi << " state " << ToString (m_state)
1715  << ", measured cell " << m_cellId
1716  << ", new RSRP " << rsrp << " stored " << storedMeasIt->second.rsrp
1717  << ", new RSRQ " << rsrq << " stored " << storedMeasIt->second.rsrq);
1718  storedMeasIt->second.timestamp = Simulator::Now ();
1719 
1720 } // end of void SaveUeMeasurements
1721 
1722 void
1724 {
1725  NS_LOG_FUNCTION (this << (uint16_t) measId);
1726 
1727  std::map<uint8_t, LteRrcSap::MeasIdToAddMod>::iterator measIdIt =
1728  m_varMeasConfig.measIdList.find (measId);
1729  NS_ASSERT (measIdIt != m_varMeasConfig.measIdList.end ());
1730  NS_ASSERT (measIdIt->first == measIdIt->second.measId);
1731 
1732  std::map<uint8_t, LteRrcSap::ReportConfigToAddMod>::iterator
1733  reportConfigIt = m_varMeasConfig.reportConfigList.find (measIdIt->second.reportConfigId);
1734  NS_ASSERT (reportConfigIt != m_varMeasConfig.reportConfigList.end ());
1735  LteRrcSap::ReportConfigEutra& reportConfigEutra = reportConfigIt->second.reportConfigEutra;
1736 
1737  std::map<uint8_t, LteRrcSap::MeasObjectToAddMod>::iterator
1738  measObjectIt = m_varMeasConfig.measObjectList.find (measIdIt->second.measObjectId);
1739  NS_ASSERT (measObjectIt != m_varMeasConfig.measObjectList.end ());
1740  LteRrcSap::MeasObjectEutra& measObjectEutra = measObjectIt->second.measObjectEutra;
1741 
1742  std::map<uint8_t, VarMeasReport>::iterator
1743  measReportIt = m_varMeasReportList.find (measId);
1744  bool isMeasIdInReportList = (measReportIt != m_varMeasReportList.end ());
1745 
1746  // we don't check the purpose field, as it is only included for
1747  // triggerType == periodical, which is not supported
1748  NS_ASSERT_MSG (reportConfigEutra.triggerType
1750  "only triggerType == event is supported");
1751  // only EUTRA is supported, no need to check for it
1752 
1753  NS_LOG_LOGIC (this << " considering measId " << (uint32_t) measId);
1754  bool eventEntryCondApplicable = false;
1755  bool eventLeavingCondApplicable = false;
1756  ConcernedCells_t concernedCellsEntry;
1757  ConcernedCells_t concernedCellsLeaving;
1758 
1759  switch (reportConfigEutra.eventId)
1760  {
1762  {
1763  /*
1764  * Event A1 (Serving becomes better than threshold)
1765  * Please refer to 3GPP TS 36.331 Section 5.5.4.2
1766  */
1767 
1768  double ms; // Ms, the measurement result of the serving cell
1769  double thresh; // Thresh, the threshold parameter for this event
1770  // Hys, the hysteresis parameter for this event.
1771  double hys = EutranMeasurementMapping::IeValue2ActualHysteresis (reportConfigEutra.hysteresis);
1772 
1773  switch (reportConfigEutra.triggerQuantity)
1774  {
1776  ms = m_storedMeasValues[m_cellId].rsrp;
1777  NS_ASSERT (reportConfigEutra.threshold1.choice
1779  thresh = EutranMeasurementMapping::RsrpRange2Dbm (reportConfigEutra.threshold1.range);
1780  break;
1782  ms = m_storedMeasValues[m_cellId].rsrq;
1783  NS_ASSERT (reportConfigEutra.threshold1.choice
1785  thresh = EutranMeasurementMapping::RsrqRange2Db (reportConfigEutra.threshold1.range);
1786  break;
1787  default:
1788  NS_FATAL_ERROR ("unsupported triggerQuantity");
1789  break;
1790  }
1791 
1792  // Inequality A1-1 (Entering condition): Ms - Hys > Thresh
1793  bool entryCond = ms - hys > thresh;
1794 
1795  if (entryCond)
1796  {
1797  if (!isMeasIdInReportList)
1798  {
1799  concernedCellsEntry.push_back (m_cellId);
1800  eventEntryCondApplicable = true;
1801  }
1802  else
1803  {
1804  /*
1805  * This is to check that the triggered cell recorded in the
1806  * VarMeasReportList is the serving cell.
1807  */
1808  NS_ASSERT (measReportIt->second.cellsTriggeredList.find (m_cellId)
1809  != measReportIt->second.cellsTriggeredList.end ());
1810  }
1811  }
1812  else if (reportConfigEutra.timeToTrigger > 0)
1813  {
1814  CancelEnteringTrigger (measId);
1815  }
1816 
1817  // Inequality A1-2 (Leaving condition): Ms + Hys < Thresh
1818  bool leavingCond = ms + hys < thresh;
1819 
1820  if (leavingCond)
1821  {
1822  if (isMeasIdInReportList)
1823  {
1824  /*
1825  * This is to check that the triggered cell recorded in the
1826  * VarMeasReportList is the serving cell.
1827  */
1828  NS_ASSERT (measReportIt->second.cellsTriggeredList.find (m_cellId)
1829  != measReportIt->second.cellsTriggeredList.end ());
1830  concernedCellsLeaving.push_back (m_cellId);
1831  eventLeavingCondApplicable = true;
1832  }
1833  }
1834  else if (reportConfigEutra.timeToTrigger > 0)
1835  {
1836  CancelLeavingTrigger (measId);
1837  }
1838 
1839  NS_LOG_LOGIC (this << " event A1: serving cell " << m_cellId
1840  << " ms=" << ms << " thresh=" << thresh
1841  << " entryCond=" << entryCond
1842  << " leavingCond=" << leavingCond);
1843 
1844  } // end of case LteRrcSap::ReportConfigEutra::EVENT_A1
1845 
1846  break;
1847 
1849  {
1850  /*
1851  * Event A2 (Serving becomes worse than threshold)
1852  * Please refer to 3GPP TS 36.331 Section 5.5.4.3
1853  */
1854 
1855  double ms; // Ms, the measurement result of the serving cell
1856  double thresh; // Thresh, the threshold parameter for this event
1857  // Hys, the hysteresis parameter for this event.
1858  double hys = EutranMeasurementMapping::IeValue2ActualHysteresis (reportConfigEutra.hysteresis);
1859 
1860  switch (reportConfigEutra.triggerQuantity)
1861  {
1863  ms = m_storedMeasValues[m_cellId].rsrp;
1864  NS_ASSERT (reportConfigEutra.threshold1.choice
1866  thresh = EutranMeasurementMapping::RsrpRange2Dbm (reportConfigEutra.threshold1.range);
1867  break;
1869  ms = m_storedMeasValues[m_cellId].rsrq;
1870  NS_ASSERT (reportConfigEutra.threshold1.choice
1872  thresh = EutranMeasurementMapping::RsrqRange2Db (reportConfigEutra.threshold1.range);
1873  break;
1874  default:
1875  NS_FATAL_ERROR ("unsupported triggerQuantity");
1876  break;
1877  }
1878 
1879  // Inequality A2-1 (Entering condition): Ms + Hys < Thresh
1880  bool entryCond = ms + hys < thresh;
1881 
1882  if (entryCond)
1883  {
1884  if (!isMeasIdInReportList)
1885  {
1886  concernedCellsEntry.push_back (m_cellId);
1887  eventEntryCondApplicable = true;
1888  }
1889  else
1890  {
1891  /*
1892  * This is to check that the triggered cell recorded in the
1893  * VarMeasReportList is the serving cell.
1894  */
1895  NS_ASSERT (measReportIt->second.cellsTriggeredList.find (m_cellId)
1896  != measReportIt->second.cellsTriggeredList.end ());
1897  }
1898  }
1899  else if (reportConfigEutra.timeToTrigger > 0)
1900  {
1901  CancelEnteringTrigger (measId);
1902  }
1903 
1904  // Inequality A2-2 (Leaving condition): Ms - Hys > Thresh
1905  bool leavingCond = ms - hys > thresh;
1906 
1907  if (leavingCond)
1908  {
1909  if (isMeasIdInReportList)
1910  {
1911  /*
1912  * This is to check that the triggered cell recorded in the
1913  * VarMeasReportList is the serving cell.
1914  */
1915  NS_ASSERT (measReportIt->second.cellsTriggeredList.find (m_cellId)
1916  != measReportIt->second.cellsTriggeredList.end ());
1917  concernedCellsLeaving.push_back (m_cellId);
1918  eventLeavingCondApplicable = true;
1919  }
1920  }
1921  else if (reportConfigEutra.timeToTrigger > 0)
1922  {
1923  CancelLeavingTrigger (measId);
1924  }
1925 
1926  NS_LOG_LOGIC (this << " event A2: serving cell " << m_cellId
1927  << " ms=" << ms << " thresh=" << thresh
1928  << " entryCond=" << entryCond
1929  << " leavingCond=" << leavingCond);
1930 
1931  } // end of case LteRrcSap::ReportConfigEutra::EVENT_A2
1932 
1933  break;
1934 
1936  {
1937  /*
1938  * Event A3 (Neighbour becomes offset better than PCell)
1939  * Please refer to 3GPP TS 36.331 Section 5.5.4.4
1940  */
1941 
1942  double mn; // Mn, the measurement result of the neighbouring cell
1943  double ofn = measObjectEutra.offsetFreq; // Ofn, the frequency specific offset of the frequency of the
1944  double ocn = 0.0; // Ocn, the cell specific offset of the neighbour cell
1945  double mp; // Mp, the measurement result of the PCell
1946  double ofp = measObjectEutra.offsetFreq; // Ofp, the frequency specific offset of the primary frequency
1947  double ocp = 0.0; // Ocp, the cell specific offset of the PCell
1948  // Off, the offset parameter for this event.
1949  double off = EutranMeasurementMapping::IeValue2ActualA3Offset (reportConfigEutra.a3Offset);
1950  // Hys, the hysteresis parameter for this event.
1951  double hys = EutranMeasurementMapping::IeValue2ActualHysteresis (reportConfigEutra.hysteresis);
1952 
1953  switch (reportConfigEutra.triggerQuantity)
1954  {
1956  mp = m_storedMeasValues[m_cellId].rsrp;
1957  NS_ASSERT (reportConfigEutra.threshold1.choice
1959  break;
1961  mp = m_storedMeasValues[m_cellId].rsrq;
1962  NS_ASSERT (reportConfigEutra.threshold1.choice
1964  break;
1965  default:
1966  NS_FATAL_ERROR ("unsupported triggerQuantity");
1967  break;
1968  }
1969 
1970  for (std::map<uint16_t, MeasValues>::iterator storedMeasIt = m_storedMeasValues.begin ();
1971  storedMeasIt != m_storedMeasValues.end ();
1972  ++storedMeasIt)
1973  {
1974  uint16_t cellId = storedMeasIt->first;
1975  if (cellId == m_cellId)
1976  {
1977  continue;
1978  }
1979 
1980  switch (reportConfigEutra.triggerQuantity)
1981  {
1983  mn = storedMeasIt->second.rsrp;
1984  break;
1986  mn = storedMeasIt->second.rsrq;
1987  break;
1988  default:
1989  NS_FATAL_ERROR ("unsupported triggerQuantity");
1990  break;
1991  }
1992 
1993  bool hasTriggered = isMeasIdInReportList
1994  && (measReportIt->second.cellsTriggeredList.find (cellId)
1995  != measReportIt->second.cellsTriggeredList.end ());
1996 
1997  // Inequality A3-1 (Entering condition): Mn + Ofn + Ocn - Hys > Mp + Ofp + Ocp + Off
1998  bool entryCond = mn + ofn + ocn - hys > mp + ofp + ocp + off;
1999 
2000  if (entryCond)
2001  {
2002  if (!hasTriggered)
2003  {
2004  concernedCellsEntry.push_back (cellId);
2005  eventEntryCondApplicable = true;
2006  }
2007  }
2008  else if (reportConfigEutra.timeToTrigger > 0)
2009  {
2010  CancelEnteringTrigger (measId, cellId);
2011  }
2012 
2013  // Inequality A3-2 (Leaving condition): Mn + Ofn + Ocn + Hys < Mp + Ofp + Ocp + Off
2014  bool leavingCond = mn + ofn + ocn + hys < mp + ofp + ocp + off;
2015 
2016  if (leavingCond)
2017  {
2018  if (hasTriggered)
2019  {
2020  concernedCellsLeaving.push_back (cellId);
2021  eventLeavingCondApplicable = true;
2022  }
2023  }
2024  else if (reportConfigEutra.timeToTrigger > 0)
2025  {
2026  CancelLeavingTrigger (measId, cellId);
2027  }
2028 
2029  NS_LOG_LOGIC (this << " event A3: neighbor cell " << cellId
2030  << " mn=" << mn << " mp=" << mp << " offset=" << off
2031  << " entryCond=" << entryCond
2032  << " leavingCond=" << leavingCond);
2033 
2034  } // end of for (storedMeasIt)
2035 
2036  } // end of case LteRrcSap::ReportConfigEutra::EVENT_A3
2037 
2038  break;
2039 
2041  {
2042  /*
2043  * Event A4 (Neighbour becomes better than threshold)
2044  * Please refer to 3GPP TS 36.331 Section 5.5.4.5
2045  */
2046 
2047  double mn; // Mn, the measurement result of the neighbouring cell
2048  double ofn = measObjectEutra.offsetFreq; // Ofn, the frequency specific offset of the frequency of the
2049  double ocn = 0.0; // Ocn, the cell specific offset of the neighbour cell
2050  double thresh; // Thresh, the threshold parameter for this event
2051  // Hys, the hysteresis parameter for this event.
2052  double hys = EutranMeasurementMapping::IeValue2ActualHysteresis (reportConfigEutra.hysteresis);
2053 
2054  switch (reportConfigEutra.triggerQuantity)
2055  {
2057  NS_ASSERT (reportConfigEutra.threshold1.choice
2059  thresh = EutranMeasurementMapping::RsrpRange2Dbm (reportConfigEutra.threshold1.range);
2060  break;
2062  NS_ASSERT (reportConfigEutra.threshold1.choice
2064  thresh = EutranMeasurementMapping::RsrqRange2Db (reportConfigEutra.threshold1.range);
2065  break;
2066  default:
2067  NS_FATAL_ERROR ("unsupported triggerQuantity");
2068  break;
2069  }
2070 
2071  for (std::map<uint16_t, MeasValues>::iterator storedMeasIt = m_storedMeasValues.begin ();
2072  storedMeasIt != m_storedMeasValues.end ();
2073  ++storedMeasIt)
2074  {
2075  uint16_t cellId = storedMeasIt->first;
2076  if (cellId == m_cellId)
2077  {
2078  continue;
2079  }
2080 
2081  switch (reportConfigEutra.triggerQuantity)
2082  {
2084  mn = storedMeasIt->second.rsrp;
2085  break;
2087  mn = storedMeasIt->second.rsrq;
2088  break;
2089  default:
2090  NS_FATAL_ERROR ("unsupported triggerQuantity");
2091  break;
2092  }
2093 
2094  bool hasTriggered = isMeasIdInReportList
2095  && (measReportIt->second.cellsTriggeredList.find (cellId)
2096  != measReportIt->second.cellsTriggeredList.end ());
2097 
2098  // Inequality A4-1 (Entering condition): Mn + Ofn + Ocn - Hys > Thresh
2099  bool entryCond = mn + ofn + ocn - hys > thresh;
2100 
2101  if (entryCond)
2102  {
2103  if (!hasTriggered)
2104  {
2105  concernedCellsEntry.push_back (cellId);
2106  eventEntryCondApplicable = true;
2107  }
2108  }
2109  else if (reportConfigEutra.timeToTrigger > 0)
2110  {
2111  CancelEnteringTrigger (measId, cellId);
2112  }
2113 
2114  // Inequality A4-2 (Leaving condition): Mn + Ofn + Ocn + Hys < Thresh
2115  bool leavingCond = mn + ofn + ocn + hys < thresh;
2116 
2117  if (leavingCond)
2118  {
2119  if (hasTriggered)
2120  {
2121  concernedCellsLeaving.push_back (cellId);
2122  eventLeavingCondApplicable = true;
2123  }
2124  }
2125  else if (reportConfigEutra.timeToTrigger > 0)
2126  {
2127  CancelLeavingTrigger (measId, cellId);
2128  }
2129 
2130  NS_LOG_LOGIC (this << " event A4: neighbor cell " << cellId
2131  << " mn=" << mn << " thresh=" << thresh
2132  << " entryCond=" << entryCond
2133  << " leavingCond=" << leavingCond);
2134 
2135  } // end of for (storedMeasIt)
2136 
2137  } // end of case LteRrcSap::ReportConfigEutra::EVENT_A4
2138 
2139  break;
2140 
2142  {
2143  /*
2144  * Event A5 (PCell becomes worse than threshold1 and neighbour
2145  * becomes better than threshold2)
2146  * Please refer to 3GPP TS 36.331 Section 5.5.4.6
2147  */
2148 
2149  double mp; // Mp, the measurement result of the PCell
2150  double mn; // Mn, the measurement result of the neighbouring cell
2151  double ofn = measObjectEutra.offsetFreq; // Ofn, the frequency specific offset of the frequency of the
2152  double ocn = 0.0; // Ocn, the cell specific offset of the neighbour cell
2153  double thresh1; // Thresh1, the threshold parameter for this event
2154  double thresh2; // Thresh2, the threshold parameter for this event
2155  // Hys, the hysteresis parameter for this event.
2156  double hys = EutranMeasurementMapping::IeValue2ActualHysteresis (reportConfigEutra.hysteresis);
2157 
2158  switch (reportConfigEutra.triggerQuantity)
2159  {
2161  mp = m_storedMeasValues[m_cellId].rsrp;
2162  NS_ASSERT (reportConfigEutra.threshold1.choice
2164  NS_ASSERT (reportConfigEutra.threshold2.choice
2166  thresh1 = EutranMeasurementMapping::RsrpRange2Dbm (reportConfigEutra.threshold1.range);
2167  thresh2 = EutranMeasurementMapping::RsrpRange2Dbm (reportConfigEutra.threshold2.range);
2168  break;
2170  mp = m_storedMeasValues[m_cellId].rsrq;
2171  NS_ASSERT (reportConfigEutra.threshold1.choice
2173  NS_ASSERT (reportConfigEutra.threshold2.choice
2175  thresh1 = EutranMeasurementMapping::RsrqRange2Db (reportConfigEutra.threshold1.range);
2176  thresh2 = EutranMeasurementMapping::RsrqRange2Db (reportConfigEutra.threshold2.range);
2177  break;
2178  default:
2179  NS_FATAL_ERROR ("unsupported triggerQuantity");
2180  break;
2181  }
2182 
2183  // Inequality A5-1 (Entering condition 1): Mp + Hys < Thresh1
2184  bool entryCond = mp + hys < thresh1;
2185 
2186  if (entryCond)
2187  {
2188  for (std::map<uint16_t, MeasValues>::iterator storedMeasIt = m_storedMeasValues.begin ();
2189  storedMeasIt != m_storedMeasValues.end ();
2190  ++storedMeasIt)
2191  {
2192  uint16_t cellId = storedMeasIt->first;
2193  if (cellId == m_cellId)
2194  {
2195  continue;
2196  }
2197 
2198  switch (reportConfigEutra.triggerQuantity)
2199  {
2201  mn = storedMeasIt->second.rsrp;
2202  break;
2204  mn = storedMeasIt->second.rsrq;
2205  break;
2206  default:
2207  NS_FATAL_ERROR ("unsupported triggerQuantity");
2208  break;
2209  }
2210 
2211  bool hasTriggered = isMeasIdInReportList
2212  && (measReportIt->second.cellsTriggeredList.find (cellId)
2213  != measReportIt->second.cellsTriggeredList.end ());
2214 
2215  // Inequality A5-2 (Entering condition 2): Mn + Ofn + Ocn - Hys > Thresh2
2216 
2217  entryCond = mn + ofn + ocn - hys > thresh2;
2218 
2219  if (entryCond)
2220  {
2221  if (!hasTriggered)
2222  {
2223  concernedCellsEntry.push_back (cellId);
2224  eventEntryCondApplicable = true;
2225  }
2226  }
2227  else if (reportConfigEutra.timeToTrigger > 0)
2228  {
2229  CancelEnteringTrigger (measId, cellId);
2230  }
2231 
2232  NS_LOG_LOGIC (this << " event A5: neighbor cell " << cellId
2233  << " mn=" << mn << " mp=" << mp
2234  << " thresh2=" << thresh2
2235  << " thresh1=" << thresh1
2236  << " entryCond=" << entryCond);
2237 
2238  } // end of for (storedMeasIt)
2239 
2240  } // end of if (entryCond)
2241  else
2242  {
2243  NS_LOG_LOGIC (this << " event A5: serving cell " << m_cellId
2244  << " mp=" << mp << " thresh1=" << thresh1
2245  << " entryCond=" << entryCond);
2246 
2247  if (reportConfigEutra.timeToTrigger > 0)
2248  {
2249  CancelEnteringTrigger (measId);
2250  }
2251  }
2252 
2253  if (isMeasIdInReportList)
2254  {
2255  // Inequality A5-3 (Leaving condition 1): Mp - Hys > Thresh1
2256  bool leavingCond = mp - hys > thresh1;
2257 
2258  if (leavingCond)
2259  {
2260  if (reportConfigEutra.timeToTrigger == 0)
2261  {
2262  // leaving condition #2 does not have to be checked
2263 
2264  for (std::map<uint16_t, MeasValues>::iterator storedMeasIt = m_storedMeasValues.begin ();
2265  storedMeasIt != m_storedMeasValues.end ();
2266  ++storedMeasIt)
2267  {
2268  uint16_t cellId = storedMeasIt->first;
2269  if (cellId == m_cellId)
2270  {
2271  continue;
2272  }
2273 
2274  if (measReportIt->second.cellsTriggeredList.find (cellId)
2275  != measReportIt->second.cellsTriggeredList.end ())
2276  {
2277  concernedCellsLeaving.push_back (cellId);
2278  eventLeavingCondApplicable = true;
2279  }
2280  }
2281  } // end of if (reportConfigEutra.timeToTrigger == 0)
2282  else
2283  {
2284  // leaving condition #2 has to be checked to cancel time-to-trigger
2285 
2286  for (std::map<uint16_t, MeasValues>::iterator storedMeasIt = m_storedMeasValues.begin ();
2287  storedMeasIt != m_storedMeasValues.end ();
2288  ++storedMeasIt)
2289  {
2290  uint16_t cellId = storedMeasIt->first;
2291  if (cellId == m_cellId)
2292  {
2293  continue;
2294  }
2295 
2296  if (measReportIt->second.cellsTriggeredList.find (cellId)
2297  != measReportIt->second.cellsTriggeredList.end ())
2298  {
2299  switch (reportConfigEutra.triggerQuantity)
2300  {
2302  mn = storedMeasIt->second.rsrp;
2303  break;
2305  mn = storedMeasIt->second.rsrq;
2306  break;
2307  default:
2308  NS_FATAL_ERROR ("unsupported triggerQuantity");
2309  break;
2310  }
2311 
2312  // Inequality A5-4 (Leaving condition 2): Mn + Ofn + Ocn + Hys < Thresh2
2313 
2314  leavingCond = mn + ofn + ocn + hys < thresh2;
2315 
2316  if (!leavingCond)
2317  {
2318  CancelLeavingTrigger (measId, cellId);
2319  }
2320 
2321  /*
2322  * Whatever the result of leaving condition #2, this
2323  * cell is still "in", because leaving condition #1
2324  * is already true.
2325  */
2326  concernedCellsLeaving.push_back (cellId);
2327  eventLeavingCondApplicable = true;
2328 
2329  NS_LOG_LOGIC (this << " event A5: neighbor cell " << cellId
2330  << " mn=" << mn << " mp=" << mp
2331  << " thresh2=" << thresh2
2332  << " thresh1=" << thresh1
2333  << " leavingCond=" << leavingCond);
2334 
2335  } // end of if (measReportIt->second.cellsTriggeredList.find (cellId)
2336  // != measReportIt->second.cellsTriggeredList.end ())
2337 
2338  } // end of for (storedMeasIt)
2339 
2340  } // end of else of if (reportConfigEutra.timeToTrigger == 0)
2341 
2342  NS_LOG_LOGIC (this << " event A5: serving cell " << m_cellId
2343  << " mp=" << mp << " thresh1=" << thresh1
2344  << " leavingCond=" << leavingCond);
2345 
2346  } // end of if (leavingCond)
2347  else
2348  {
2349  if (reportConfigEutra.timeToTrigger > 0)
2350  {
2351  CancelLeavingTrigger (measId);
2352  }
2353 
2354  // check leaving condition #2
2355 
2356  for (std::map<uint16_t, MeasValues>::iterator storedMeasIt = m_storedMeasValues.begin ();
2357  storedMeasIt != m_storedMeasValues.end ();
2358  ++storedMeasIt)
2359  {
2360  uint16_t cellId = storedMeasIt->first;
2361  if (cellId == m_cellId)
2362  {
2363  continue;
2364  }
2365 
2366  if (measReportIt->second.cellsTriggeredList.find (cellId)
2367  != measReportIt->second.cellsTriggeredList.end ())
2368  {
2369  switch (reportConfigEutra.triggerQuantity)
2370  {
2372  mn = storedMeasIt->second.rsrp;
2373  break;
2375  mn = storedMeasIt->second.rsrq;
2376  break;
2377  default:
2378  NS_FATAL_ERROR ("unsupported triggerQuantity");
2379  break;
2380  }
2381 
2382  // Inequality A5-4 (Leaving condition 2): Mn + Ofn + Ocn + Hys < Thresh2
2383  leavingCond = mn + ofn + ocn + hys < thresh2;
2384 
2385  if (leavingCond)
2386  {
2387  concernedCellsLeaving.push_back (cellId);
2388  eventLeavingCondApplicable = true;
2389  }
2390 
2391  NS_LOG_LOGIC (this << " event A5: neighbor cell " << cellId
2392  << " mn=" << mn << " mp=" << mp
2393  << " thresh2=" << thresh2
2394  << " thresh1=" << thresh1
2395  << " leavingCond=" << leavingCond);
2396 
2397  } // end of if (measReportIt->second.cellsTriggeredList.find (cellId)
2398  // != measReportIt->second.cellsTriggeredList.end ())
2399 
2400  } // end of for (storedMeasIt)
2401 
2402  } // end of else of if (leavingCond)
2403 
2404  } // end of if (isMeasIdInReportList)
2405 
2406  } // end of case LteRrcSap::ReportConfigEutra::EVENT_A5
2407 
2408  break;
2409 
2410  default:
2411  NS_FATAL_ERROR ("unsupported eventId " << reportConfigEutra.eventId);
2412  break;
2413 
2414  } // switch (event type)
2415 
2416  NS_LOG_LOGIC (this << " eventEntryCondApplicable=" << eventEntryCondApplicable
2417  << " eventLeavingCondApplicable=" << eventLeavingCondApplicable);
2418 
2419  if (eventEntryCondApplicable)
2420  {
2421  if (reportConfigEutra.timeToTrigger == 0)
2422  {
2423  VarMeasReportListAdd (measId, concernedCellsEntry);
2424  }
2425  else
2426  {
2427  PendingTrigger_t t;
2428  t.measId = measId;
2429  t.concernedCells = concernedCellsEntry;
2430  t.timer = Simulator::Schedule (MilliSeconds (reportConfigEutra.timeToTrigger),
2432  measId, concernedCellsEntry);
2433  std::map<uint8_t, std::list<PendingTrigger_t> >::iterator
2434  enteringTriggerIt = m_enteringTriggerQueue.find (measId);
2435  NS_ASSERT (enteringTriggerIt != m_enteringTriggerQueue.end ());
2436  enteringTriggerIt->second.push_back (t);
2437  }
2438  }
2439 
2440  if (eventLeavingCondApplicable)
2441  {
2442  // reportOnLeave will only be set when eventId = eventA3
2443  bool reportOnLeave = (reportConfigEutra.eventId == LteRrcSap::ReportConfigEutra::EVENT_A3)
2444  && reportConfigEutra.reportOnLeave;
2445 
2446  if (reportConfigEutra.timeToTrigger == 0)
2447  {
2448  VarMeasReportListErase (measId, concernedCellsLeaving, reportOnLeave);
2449  }
2450  else
2451  {
2452  PendingTrigger_t t;
2453  t.measId = measId;
2454  t.concernedCells = concernedCellsLeaving;
2455  t.timer = Simulator::Schedule (MilliSeconds (reportConfigEutra.timeToTrigger),
2457  measId, concernedCellsLeaving, reportOnLeave);
2458  std::map<uint8_t, std::list<PendingTrigger_t> >::iterator
2459  leavingTriggerIt = m_leavingTriggerQueue.find (measId);
2460  NS_ASSERT (leavingTriggerIt != m_leavingTriggerQueue.end ());
2461  leavingTriggerIt->second.push_back (t);
2462  }
2463  }
2464 
2465 } // end of void LteUeRrc::MeasurementReportTriggering (uint8_t measId)
2466 
2467 void
2469 {
2470  NS_LOG_FUNCTION (this << (uint16_t) measId);
2471 
2472  std::map<uint8_t, std::list<PendingTrigger_t> >::iterator
2473  it1 = m_enteringTriggerQueue.find (measId);
2474  NS_ASSERT (it1 != m_enteringTriggerQueue.end ());
2475 
2476  if (!it1->second.empty ())
2477  {
2478  std::list<PendingTrigger_t>::iterator it2;
2479  for (it2 = it1->second.begin (); it2 != it1->second.end (); ++it2)
2480  {
2481  NS_ASSERT (it2->measId == measId);
2482  NS_LOG_LOGIC (this << " canceling entering time-to-trigger event at "
2483  << Simulator::GetDelayLeft (it2->timer).GetSeconds ());
2484  Simulator::Cancel (it2->timer);
2485  }
2486 
2487  it1->second.clear ();
2488  }
2489 }
2490 
2491 void
2492 LteUeRrc::CancelEnteringTrigger (uint8_t measId, uint16_t cellId)
2493 {
2494  NS_LOG_FUNCTION (this << (uint16_t) measId << cellId);
2495 
2496  std::map<uint8_t, std::list<PendingTrigger_t> >::iterator
2497  it1 = m_enteringTriggerQueue.find (measId);
2498  NS_ASSERT (it1 != m_enteringTriggerQueue.end ());
2499 
2500  std::list<PendingTrigger_t>::iterator it2 = it1->second.begin ();
2501  while (it2 != it1->second.end ())
2502  {
2503  NS_ASSERT (it2->measId == measId);
2504 
2505  ConcernedCells_t::iterator it3;
2506  for (it3 = it2->concernedCells.begin ();
2507  it3 != it2->concernedCells.end (); ++it3)
2508  {
2509  if (*it3 == cellId)
2510  {
2511  it3 = it2->concernedCells.erase (it3);
2512  }
2513  }
2514 
2515  if (it2->concernedCells.empty ())
2516  {
2517  NS_LOG_LOGIC (this << " canceling entering time-to-trigger event at "
2518  << Simulator::GetDelayLeft (it2->timer).GetSeconds ());
2519  Simulator::Cancel (it2->timer);
2520  it2 = it1->second.erase (it2);
2521  }
2522  else
2523  {
2524  it2++;
2525  }
2526  }
2527 }
2528 
2529 void
2531 {
2532  NS_LOG_FUNCTION (this << (uint16_t) measId);
2533 
2534  std::map<uint8_t, std::list<PendingTrigger_t> >::iterator
2535  it1 = m_leavingTriggerQueue.find (measId);
2536  NS_ASSERT (it1 != m_leavingTriggerQueue.end ());
2537 
2538  if (!it1->second.empty ())
2539  {
2540  std::list<PendingTrigger_t>::iterator it2;
2541  for (it2 = it1->second.begin (); it2 != it1->second.end (); ++it2)
2542  {
2543  NS_ASSERT (it2->measId == measId);
2544  NS_LOG_LOGIC (this << " canceling leaving time-to-trigger event at "
2545  << Simulator::GetDelayLeft (it2->timer).GetSeconds ());
2546  Simulator::Cancel (it2->timer);
2547  }
2548 
2549  it1->second.clear ();
2550  }
2551 }
2552 
2553 void
2554 LteUeRrc::CancelLeavingTrigger (uint8_t measId, uint16_t cellId)
2555 {
2556  NS_LOG_FUNCTION (this << (uint16_t) measId << cellId);
2557 
2558  std::map<uint8_t, std::list<PendingTrigger_t> >::iterator
2559  it1 = m_leavingTriggerQueue.find (measId);
2560  NS_ASSERT (it1 != m_leavingTriggerQueue.end ());
2561 
2562  std::list<PendingTrigger_t>::iterator it2 = it1->second.begin ();
2563  while (it2 != it1->second.end ())
2564  {
2565  NS_ASSERT (it2->measId == measId);
2566 
2567  ConcernedCells_t::iterator it3;
2568  for (it3 = it2->concernedCells.begin ();
2569  it3 != it2->concernedCells.end (); ++it3)
2570  {
2571  if (*it3 == cellId)
2572  {
2573  it3 = it2->concernedCells.erase (it3);
2574  }
2575  }
2576 
2577  if (it2->concernedCells.empty ())
2578  {
2579  NS_LOG_LOGIC (this << " canceling leaving time-to-trigger event at "
2580  << Simulator::GetDelayLeft (it2->timer).GetSeconds ());
2581  Simulator::Cancel (it2->timer);
2582  it2 = it1->second.erase (it2);
2583  }
2584  else
2585  {
2586  it2++;
2587  }
2588  }
2589 }
2590 
2591 void
2592 LteUeRrc::VarMeasReportListAdd (uint8_t measId, ConcernedCells_t enteringCells)
2593 {
2594  NS_LOG_FUNCTION (this << (uint16_t) measId);
2595  NS_ASSERT (!enteringCells.empty ());
2596 
2597  std::map<uint8_t, VarMeasReport>::iterator
2598  measReportIt = m_varMeasReportList.find (measId);
2599 
2600  if (measReportIt == m_varMeasReportList.end ())
2601  {
2602  VarMeasReport r;
2603  r.measId = measId;
2604  std::pair<uint8_t, VarMeasReport> val (measId, r);
2605  std::pair<std::map<uint8_t, VarMeasReport>::iterator, bool>
2606  ret = m_varMeasReportList.insert (val);
2607  NS_ASSERT_MSG (ret.second == true, "element already existed");
2608  measReportIt = ret.first;
2609  }
2610 
2611  NS_ASSERT (measReportIt != m_varMeasReportList.end ());
2612 
2613  for (ConcernedCells_t::const_iterator it = enteringCells.begin ();
2614  it != enteringCells.end ();
2615  ++it)
2616  {
2617  measReportIt->second.cellsTriggeredList.insert (*it);
2618  }
2619 
2620  NS_ASSERT (!measReportIt->second.cellsTriggeredList.empty ());
2621  measReportIt->second.numberOfReportsSent = 0;
2622  measReportIt->second.periodicReportTimer
2625  this, measId);
2626 
2627  std::map<uint8_t, std::list<PendingTrigger_t> >::iterator
2628  enteringTriggerIt = m_enteringTriggerQueue.find (measId);
2629  NS_ASSERT (enteringTriggerIt != m_enteringTriggerQueue.end ());
2630  if (!enteringTriggerIt->second.empty ())
2631  {
2632  /*
2633  * Assumptions at this point:
2634  * - the call to this function was delayed by time-to-trigger;
2635  * - the time-to-trigger delay is fixed (not adaptive/dynamic); and
2636  * - the first element in the list is associated with this function call.
2637  */
2638  enteringTriggerIt->second.pop_front ();
2639 
2640  if (!enteringTriggerIt->second.empty ())
2641  {
2642  /*
2643  * To prevent the same set of cells triggering again in the future,
2644  * we clean up the time-to-trigger queue. This case might occur when
2645  * time-to-trigger > 200 ms.
2646  */
2647  for (ConcernedCells_t::const_iterator it = enteringCells.begin ();
2648  it != enteringCells.end (); ++it)
2649  {
2650  CancelEnteringTrigger (measId, *it);
2651  }
2652  }
2653 
2654  } // end of if (!enteringTriggerIt->second.empty ())
2655 
2656 } // end of LteUeRrc::VarMeasReportListAdd
2657 
2658 void
2660  bool reportOnLeave)
2661 {
2662  NS_LOG_FUNCTION (this << (uint16_t) measId);
2663  NS_ASSERT (!leavingCells.empty ());
2664 
2665  std::map<uint8_t, VarMeasReport>::iterator
2666  measReportIt = m_varMeasReportList.find (measId);
2667  NS_ASSERT (measReportIt != m_varMeasReportList.end ());
2668 
2669  for (ConcernedCells_t::const_iterator it = leavingCells.begin ();
2670  it != leavingCells.end ();
2671  ++it)
2672  {
2673  measReportIt->second.cellsTriggeredList.erase (*it);
2674  }
2675 
2676  if (reportOnLeave)
2677  {
2678  // runs immediately without UE_MEASUREMENT_REPORT_DELAY
2679  SendMeasurementReport (measId);
2680  }
2681 
2682  if (measReportIt->second.cellsTriggeredList.empty ())
2683  {
2684  measReportIt->second.periodicReportTimer.Cancel ();
2685  m_varMeasReportList.erase (measReportIt);
2686  }
2687 
2688  std::map<uint8_t, std::list<PendingTrigger_t> >::iterator
2689  leavingTriggerIt = m_leavingTriggerQueue.find (measId);
2690  NS_ASSERT (leavingTriggerIt != m_leavingTriggerQueue.end ());
2691  if (!leavingTriggerIt->second.empty ())
2692  {
2693  /*
2694  * Assumptions at this point:
2695  * - the call to this function was delayed by time-to-trigger; and
2696  * - the time-to-trigger delay is fixed (not adaptive/dynamic); and
2697  * - the first element in the list is associated with this function call.
2698  */
2699  leavingTriggerIt->second.pop_front ();
2700 
2701  if (!leavingTriggerIt->second.empty ())
2702  {
2703  /*
2704  * To prevent the same set of cells triggering again in the future,
2705  * we clean up the time-to-trigger queue. This case might occur when
2706  * time-to-trigger > 200 ms.
2707  */
2708  for (ConcernedCells_t::const_iterator it = leavingCells.begin ();
2709  it != leavingCells.end (); ++it)
2710  {
2711  CancelLeavingTrigger (measId, *it);
2712  }
2713  }
2714 
2715  } // end of if (!leavingTriggerIt->second.empty ())
2716 
2717 } // end of LteUeRrc::VarMeasReportListErase
2718 
2719 void
2721 {
2722  NS_LOG_FUNCTION (this << (uint16_t) measId);
2723 
2724  // remove the measurement reporting entry for this measId from the VarMeasReportList
2725  std::map<uint8_t, VarMeasReport>::iterator
2726  measReportIt = m_varMeasReportList.find (measId);
2727  if (measReportIt != m_varMeasReportList.end ())
2728  {
2729  NS_LOG_LOGIC (this << " deleting existing report for measId " << (uint16_t) measId);
2730  measReportIt->second.periodicReportTimer.Cancel ();
2731  m_varMeasReportList.erase (measReportIt);
2732  }
2733 
2734  CancelEnteringTrigger (measId);
2735  CancelLeavingTrigger (measId);
2736 }
2737 
2738 void
2740 {
2741  NS_LOG_FUNCTION (this << (uint16_t) measId);
2742  // 3GPP TS 36.331 section 5.5.5 Measurement reporting
2743 
2744  std::map<uint8_t, LteRrcSap::MeasIdToAddMod>::iterator
2745  measIdIt = m_varMeasConfig.measIdList.find (measId);
2746  NS_ASSERT (measIdIt != m_varMeasConfig.measIdList.end ());
2747 
2748  std::map<uint8_t, LteRrcSap::ReportConfigToAddMod>::iterator
2749  reportConfigIt = m_varMeasConfig.reportConfigList.find (measIdIt->second.reportConfigId);
2750  NS_ASSERT (reportConfigIt != m_varMeasConfig.reportConfigList.end ());
2751  LteRrcSap::ReportConfigEutra& reportConfigEutra = reportConfigIt->second.reportConfigEutra;
2752 
2753  LteRrcSap::MeasurementReport measurementReport;
2754  LteRrcSap::MeasResults& measResults = measurementReport.measResults;
2755  measResults.measId = measId;
2756 
2757  std::map<uint16_t, MeasValues>::iterator servingMeasIt = m_storedMeasValues.find (m_cellId);
2758  NS_ASSERT (servingMeasIt != m_storedMeasValues.end ());
2759  measResults.rsrpResult = EutranMeasurementMapping::Dbm2RsrpRange (servingMeasIt->second.rsrp);
2760  measResults.rsrqResult = EutranMeasurementMapping::Db2RsrqRange (servingMeasIt->second.rsrq);
2761  NS_LOG_INFO (this << " reporting serving cell "
2762  "RSRP " << (uint32_t) measResults.rsrpResult << " (" << servingMeasIt->second.rsrp << " dBm) "
2763  "RSRQ " << (uint32_t) measResults.rsrqResult << " (" << servingMeasIt->second.rsrq << " dB)");
2764  measResults.haveMeasResultNeighCells = false;
2765  std::map<uint8_t, VarMeasReport>::iterator measReportIt = m_varMeasReportList.find (measId);
2766  if (measReportIt == m_varMeasReportList.end ())
2767  {
2768  NS_LOG_ERROR ("no entry found in m_varMeasReportList for measId " << (uint32_t) measId);
2769  }
2770  else
2771  {
2772  if (!(measReportIt->second.cellsTriggeredList.empty ()))
2773  {
2774  std::multimap<double, uint16_t> sortedNeighCells;
2775  for (std::set<uint16_t>::iterator cellsTriggeredIt = measReportIt->second.cellsTriggeredList.begin ();
2776  cellsTriggeredIt != measReportIt->second.cellsTriggeredList.end ();
2777  ++cellsTriggeredIt)
2778  {
2779  uint16_t cellId = *cellsTriggeredIt;
2780  if (cellId != m_cellId)
2781  {
2782  std::map<uint16_t, MeasValues>::iterator neighborMeasIt = m_storedMeasValues.find (cellId);
2783  double triggerValue;
2784  switch (reportConfigEutra.triggerQuantity)
2785  {
2787  triggerValue = neighborMeasIt->second.rsrp;
2788  break;
2790  triggerValue = neighborMeasIt->second.rsrq;
2791  break;
2792  default:
2793  NS_FATAL_ERROR ("unsupported triggerQuantity");
2794  break;
2795  }
2796  sortedNeighCells.insert (std::pair<double, uint16_t> (triggerValue, cellId));
2797  }
2798  }
2799 
2800  std::multimap<double, uint16_t>::reverse_iterator sortedNeighCellsIt;
2801  uint32_t count;
2802  for (sortedNeighCellsIt = sortedNeighCells.rbegin (), count = 0;
2803  sortedNeighCellsIt != sortedNeighCells.rend () && count < reportConfigEutra.maxReportCells;
2804  ++sortedNeighCellsIt, ++count)
2805  {
2806  uint16_t cellId = sortedNeighCellsIt->second;
2807  std::map<uint16_t, MeasValues>::iterator neighborMeasIt = m_storedMeasValues.find (cellId);
2808  NS_ASSERT (neighborMeasIt != m_storedMeasValues.end ());
2809  LteRrcSap::MeasResultEutra measResultEutra;
2810  measResultEutra.physCellId = cellId;
2811  measResultEutra.haveCgiInfo = false;
2812  measResultEutra.haveRsrpResult = true;
2813  measResultEutra.rsrpResult = EutranMeasurementMapping::Dbm2RsrpRange (neighborMeasIt->second.rsrp);
2814  measResultEutra.haveRsrqResult = true;
2815  measResultEutra.rsrqResult = EutranMeasurementMapping::Db2RsrqRange (neighborMeasIt->second.rsrq);
2816  NS_LOG_INFO (this << " reporting neighbor cell " << (uint32_t) measResultEutra.physCellId
2817  << " RSRP " << (uint32_t) measResultEutra.rsrpResult
2818  << " (" << neighborMeasIt->second.rsrp << " dBm)"
2819  << " RSRQ " << (uint32_t) measResultEutra.rsrqResult
2820  << " (" << neighborMeasIt->second.rsrq << " dB)");
2821  measResults.measResultListEutra.push_back (measResultEutra);
2822  measResults.haveMeasResultNeighCells = true;
2823  }
2824  }
2825  else
2826  {
2827  NS_LOG_WARN (this << " cellsTriggeredList is empty");
2828  }
2829 
2830  measResults.haveScellsMeas = false;
2831  std::map<uint16_t, MeasValues>::iterator sCellsMeasIt = m_storedScellMeasValues.begin ();
2832  if (sCellsMeasIt != m_storedScellMeasValues.end ())
2833  {
2834  measResults.haveScellsMeas = true;
2837 
2838 
2839  for ( sCellsMeasIt = m_storedScellMeasValues.begin ();
2840  sCellsMeasIt != m_storedScellMeasValues.end (); ++sCellsMeasIt)
2841  {
2842  LteRrcSap::MeasResultScell measResultScell;
2843  measResultScell.servFreqId = sCellsMeasIt->first;
2844  measResultScell.haveRsrpResult = true;
2845  measResultScell.haveRsrqResult = true;
2846  measResultScell.rsrpResult = EutranMeasurementMapping::Dbm2RsrpRange (sCellsMeasIt->second.rsrp);
2847  measResultScell.rsrqResult = EutranMeasurementMapping::Db2RsrqRange (sCellsMeasIt->second.rsrq);
2848  measResults.measScellResultList.measResultScell.push_back (measResultScell);
2849  }
2850  }
2851 
2852  /*
2853  * The current LteRrcSap implementation is broken in that it does not
2854  * allow for infinite values of reportAmount, which is probably the most
2855  * reasonable setting. So we just always assume infinite reportAmount.
2856  */
2857  measReportIt->second.numberOfReportsSent++;
2858  measReportIt->second.periodicReportTimer.Cancel ();
2859 
2860  Time reportInterval;
2861  switch (reportConfigEutra.reportInterval)
2862  {
2864  reportInterval = MilliSeconds (120);
2865  break;
2867  reportInterval = MilliSeconds (240);
2868  break;
2870  reportInterval = MilliSeconds (480);
2871  break;
2873  reportInterval = MilliSeconds (640);
2874  break;
2876  reportInterval = MilliSeconds (1024);
2877  break;
2879  reportInterval = MilliSeconds (2048);
2880  break;
2882  reportInterval = MilliSeconds (5120);
2883  break;
2885  reportInterval = MilliSeconds (10240);
2886  break;
2888  reportInterval = Seconds (60);
2889  break;
2891  reportInterval = Seconds (360);
2892  break;
2894  reportInterval = Seconds (720);
2895  break;
2897  reportInterval = Seconds (1800);
2898  break;
2900  reportInterval = Seconds (3600);
2901  break;
2902  default:
2903  NS_FATAL_ERROR ("Unsupported reportInterval " << (uint16_t) reportConfigEutra.reportInterval);
2904  break;
2905  }
2906 
2907  // schedule the next measurement reporting
2908  measReportIt->second.periodicReportTimer
2909  = Simulator::Schedule (reportInterval,
2911  this, measId);
2912 
2913  // send the measurement report to eNodeB
2914  m_rrcSapUser->SendMeasurementReport (measurementReport);
2915  }
2916 }
2917 
2918 void
2920 {
2921  NS_LOG_FUNCTION (this << m_imsi);
2924  m_connectionPending = false; // reset the flag
2926  m_cmacSapProvider.at (0)->StartContentionBasedRandomAccessProcedure ();
2927 }
2928 
2929 void
2931 {
2932  NS_LOG_FUNCTION (this << m_imsi);
2934  m_cmacSapProvider.at (0)->RemoveLc (1);
2935  std::map<uint8_t, Ptr<LteDataRadioBearerInfo> >::iterator it;
2936  for (it = m_drbMap.begin (); it != m_drbMap.end (); ++it)
2937  {
2938  m_cmacSapProvider.at (0)->RemoveLc (it->second->m_logicalChannelIdentity);
2939  }
2940  m_drbMap.clear ();
2941  m_bid2DrbidMap.clear ();
2942  m_srb1 = 0;
2944 }
2945 
2946 void
2948 {
2949  NS_LOG_FUNCTION (this << m_imsi);
2950  m_cmacSapProvider.at (0)->Reset (); // reset the MAC
2951  m_hasReceivedSib2 = false; // invalidate the previously received SIB2
2954  m_asSapUser->NotifyConnectionFailed (); // inform upper layer
2955 }
2956 
2957 void
2959 {
2960  NS_LOG_FUNCTION (this);
2961  m_srb1Old = 0;
2962 }
2963 
2964 uint8_t
2965 LteUeRrc::Bid2Drbid (uint8_t bid)
2966 {
2967  std::map<uint8_t, uint8_t>::iterator it = m_bid2DrbidMap.find (bid);
2968  //NS_ASSERT_MSG (it != m_bid2DrbidMap.end (), "could not find BID " << bid);
2969  if (it == m_bid2DrbidMap.end ())
2970  {
2971  return 0;
2972  }
2973  else
2974  {
2975  return it->second;
2976  }
2977 }
2978 
2979 void
2981 {
2982  NS_LOG_FUNCTION (this << ToString (newState));
2983  State oldState = m_state;
2984  m_state = newState;
2985  NS_LOG_INFO (this << " IMSI " << m_imsi << " RNTI " << m_rnti << " UeRrc "
2986  << ToString (oldState) << " --> " << ToString (newState));
2987  m_stateTransitionTrace (m_imsi, m_cellId, m_rnti, oldState, newState);
2988 
2989  switch (newState)
2990  {
2991  case IDLE_START:
2992  NS_FATAL_ERROR ("cannot switch to an initial state");
2993  break;
2994 
2995  case IDLE_CELL_SEARCH:
2996  case IDLE_WAIT_MIB_SIB1:
2997  case IDLE_WAIT_MIB:
2998  case IDLE_WAIT_SIB1:
2999  break;
3000 
3001  case IDLE_CAMPED_NORMALLY:
3002  if (m_connectionPending)
3003  {
3005  }
3006  break;
3007 
3008  case IDLE_WAIT_SIB2:
3009  if (m_hasReceivedSib2)
3010  {
3012  StartConnection ();
3013  }
3014  break;
3015 
3016  case IDLE_RANDOM_ACCESS:
3017  case IDLE_CONNECTING:
3018  case CONNECTED_NORMALLY:
3019  case CONNECTED_HANDOVER:
3020  case CONNECTED_PHY_PROBLEM:
3022  break;
3023 
3024  default:
3025  break;
3026  }
3027 }
3028 
3029 void
3030 LteUeRrc::DoComponentCarrierEnabling (std::vector<uint8_t> res)
3031  {
3032  NS_LOG_INFO (this);
3033  }
3034 
3035 void
3036 LteUeRrc::SaveScellUeMeasurements (uint16_t sCellId, double rsrp, double rsrq,
3037  bool useLayer3Filtering, uint16_t componentCarrierId)
3038 {
3039  NS_LOG_FUNCTION (this << sCellId << componentCarrierId << rsrp << rsrq << useLayer3Filtering);
3040  if (sCellId == m_cellId)
3041  {
3042 
3043  std::map<uint16_t, MeasValues>::iterator storedMeasIt = m_storedScellMeasValues.find (componentCarrierId);
3044 
3045  if (storedMeasIt != m_storedScellMeasValues.end ())
3046  {
3047  if (useLayer3Filtering)
3048  {
3049  // F_n = (1-a) F_{n-1} + a M_n
3050  storedMeasIt->second.rsrp = (1 - m_varMeasConfig.aRsrp) * storedMeasIt->second.rsrp
3051  + m_varMeasConfig.aRsrp * rsrp;
3052 
3053  if (std::isnan (storedMeasIt->second.rsrq))
3054  {
3055  // the previous RSRQ measurements provided UE PHY are invalid
3056  storedMeasIt->second.rsrq = rsrq; // replace it with unfiltered value
3057  }
3058  else
3059  {
3060  storedMeasIt->second.rsrq = (1 - m_varMeasConfig.aRsrq) * storedMeasIt->second.rsrq
3061  + m_varMeasConfig.aRsrq * rsrq;
3062  }
3063  }
3064  else
3065  {
3066  storedMeasIt->second.rsrp = rsrp;
3067  storedMeasIt->second.rsrq = rsrq;
3068  }
3069  }
3070  else
3071  {
3072  // first value is always unfiltered
3073  MeasValues v;
3074  v.rsrp = rsrp;
3075  v.rsrq = rsrq;
3076  std::pair<uint16_t, MeasValues> val (componentCarrierId, v);
3077  std::pair<std::map<uint16_t, MeasValues>::iterator, bool>
3078  ret = m_storedScellMeasValues.insert (val);
3079  NS_ASSERT_MSG (ret.second == true, "element already existed");
3080  storedMeasIt = ret.first;
3081  }
3082 
3083  NS_LOG_DEBUG (this << " IMSI " << m_imsi << " state " << ToString (m_state)
3084  << ", measured cell " << sCellId
3085  << ", carrier component Id " << componentCarrierId
3086  << ", new RSRP " << rsrp << " stored " << storedMeasIt->second.rsrp
3087  << ", new RSRQ " << rsrq << " stored " << storedMeasIt->second.rsrq);
3088  storedMeasIt->second.timestamp = Simulator::Now ();
3089  }
3090  else
3091  {
3092  NS_LOG_DEBUG (this << " IMSI " << m_imsi << "measurement on SCC from not serving cell ");
3093  }
3094 
3095 } // end of void SaveUeMeasurements
3096 
3097 
3098 } // namespace ns3
3099 
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:1018
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
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
Event A1: Serving becomes better than absolute threshold.
Definition: lte-rrc-sap.h:366
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:951
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:776
MeasurementReport structure.
Definition: lte-rrc-sap.h:894
std::map< uint8_t, LteRrcSap::MeasObjectToAddMod > measObjectList
measure object list
Definition: lte-ue-rrc.h:877
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:2468
void DoRecvSystemInformationBlockType1(uint16_t cellId, LteRrcSap::SystemInformationBlockType1 msg)
Receive system information block type 1 function.
Definition: lte-ue-rrc.cc:803
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:3030
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
#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:712
void DoRecvSystemInformation(LteRrcSap::SystemInformation msg)
Part of the RRC protocol.
Definition: lte-ue-rrc.cc:907
uint16_t bucketSizeDurationMs
bucket size duration ms
uint8_t numberOfRaPreambles
number of RA preambles
Definition: lte-rrc-sap.h:247
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
Ptr< T > GetObject(void) const
Get a pointer to the requested aggregated Object.
Definition: object.h:459
static TypeId GetTypeId(void)
Get the type ID.
Definition: lte-rlc.cc:189
void SetAsSapUser(LteAsSapUser *s)
Set the AS SAP user to interact with the NAS entity.
Definition: lte-ue-rrc.cc:377
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:1723
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:1106
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:853
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:754
void ApplyMeasConfig(LteRrcSap::MeasConfig mc)
Update the current measurement configuration m_varMeasConfig.
Definition: lte-ue-rrc.cc:1452
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:451
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:1158
uint8_t measId
The measurement identity which raised the trigger.
Definition: lte-ue-rrc.h:1027
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:764
#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:581
Represents a single triggered event from a measurement identity which reporting criteria have been fu...
Definition: lte-ue-rrc.h:1025
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:1146
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:201
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1001
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.
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:796
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:706
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:735
EventId timer
The pending reporting event, scheduled at the end of the time-to-trigger.
Definition: lte-ue-rrc.h:1029
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:2530
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:277
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's associated function will not be invoked when it expires...
Definition: simulator.cc:346
Event A5: PCell becomes worse than absolute threshold1 AND Neighbour becomes better than another abso...
Definition: lte-rrc-sap.h:370
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:849
RachConfigDedicated rachConfigDedicated
RACH config dedicated.
Definition: lte-rrc-sap.h:561
RSRP is used for the threshold.
Definition: lte-rrc-sap.h:347
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:1077
uint32_t m_dlEarfcn
Downlink carrier frequency.
Definition: lte-ue-rrc.h:769
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:847
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:678
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:851
LteMacSapProvider * m_macSapProvider
MAC SAP provider.
Definition: lte-ue-rrc.h:711
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:2965
#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
double GetSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:341
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:328
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:879
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:703
static EventId Schedule(Time const &delay, MEM mem_ptr, OBJ obj)
Schedule an event to expire after delay.
Definition: simulator.h:1375
void SetLteUeRrcSapUser(LteUeRrcSapUser *s)
set the RRC SAP this RRC should interact with
Definition: lte-ue-rrc.cc:342
LteUeRrcSapUser * m_rrcSapUser
RRC SAP user.
Definition: lte-ue-rrc.h:708
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:839
MeasResultScell structure.
Definition: lte-rrc-sap.h:641
State m_state
The current UE RRC state.
Definition: lte-ue-rrc.h:724
AttributeValue implementation for Time.
Definition: nstime.h:1055
Ptr< LteSignalingRadioBearerInfo > m_srb0
The Srb0 attribute.
Definition: lte-ue-rrc.h:740
ConcernedCells_t concernedCells
The list of cells responsible for this trigger.
Definition: lte-ue-rrc.h:1028
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:975
void DisposeOldSrb1()
Dispose old SRB1.
Definition: lte-ue-rrc.cc:2958
static double IeValue2ActualA3Offset(int8_t a3OffsetIeValue)
Returns the actual value of an a3-Offset parameter.
Definition: lte-common.cc:319
Ptr< Object > Create(void) const
Create an Object instance of the configured TypeId.
TracedCallback< uint64_t, uint16_t, uint16_t, uint16_t > m_handoverStartTrace
The HandoverStart trace source.
Definition: lte-ue-rrc.h:834
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:976
void DoRecvRrcConnectionReestablishment(LteRrcSap::RrcConnectionReestablishment msg)
Part of the RRC protocol.
Definition: lte-ue-rrc.cc:1053
uint8_t m_dlBandwidth
Downlink bandwidth in RBs.
Definition: lte-ue-rrc.h:766
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:814
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:787
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:2947
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:1163
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:459
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:995
void SetLteCcmRrcSapProvider(LteUeCcmRrcSapProvider *s)
set the Component Carrier Management SAP this RRC should interact with
Definition: lte-ue-rrc.cc:363
PhysicalConfigDedicated physicalConfigDedicated
physical config dedicated
Definition: lte-rrc-sap.h:284
Ptr< LteSignalingRadioBearerInfo > m_srb1
The Srb1 attribute.
Definition: lte-ue-rrc.h:744
uint8_t measId
measure ID
Definition: lte-ue-rrc.h:901
uint8_t filterCoefficientRSRP
filter coefficient RSRP
Definition: lte-rrc-sap.h:290
uint8_t GetUlBandwidth() const
Definition: lte-ue-rrc.cc:417
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:314
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:760
MeasResultServFreqList measScellResultList
measure SCell result list
Definition: lte-rrc-sap.h:679
RSRQ is used for the threshold.
Definition: lte-rrc-sap.h:348
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:862
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:876
std::map< uint8_t, uint8_t > m_bid2DrbidMap
bid to DR bid map
Definition: lte-ue-rrc.h:700
void SetLteMacSapProvider(LteMacSapProvider *s)
set the MAC SAP provider.
Definition: lte-ue-rrc.cc:356
RrcConnectionSetupCompleted structure.
Definition: lte-rrc-sap.h:698
TracedCallback< uint64_t, uint16_t > m_initialCellSelectionEndOkTrace
The InitialCellSelectionEndOk trace source.
Definition: lte-ue-rrc.h:798
RadioResourceConfigDedicated radioResourceConfigDedicated
radio resource config dedicated
Definition: lte-rrc-sap.h:694
RrcConnectionSetup structure.
Definition: lte-rrc-sap.h:691
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:286
void SwitchToState(State s)
Switch the UE RRC to the given state.
Definition: lte-ue-rrc.cc:2980
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:803
VarMeasConfig m_varMeasConfig
Includes the accumulated configuration of the measurements to be performed by the UE...
Definition: lte-ue-rrc.h:890
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:1053
SystemInformationBlockType1 structure.
Definition: lte-rrc-sap.h:587
std::vector< LteUeCphySapUser * > m_cphySapUser
UE CPhy SAP user.
Definition: lte-ue-rrc.h:702
std::map< uint8_t, LteRrcSap::ReportConfigToAddMod > reportConfigList
report config list
Definition: lte-ue-rrc.h:878
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.
Definition: pointer.h:36
Event A2: Serving becomes worse than absolute threshold.
Definition: lte-rrc-sap.h:367
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:715
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
uint32_t GetUlEarfcn() const
Definition: lte-ue-rrc.cc:437
bool haveMobilityControlInfo
have mobility control info
Definition: lte-rrc-sap.h:834
void DoNotifyRandomAccessSuccessful()
Notify random access successful function.
Definition: lte-ue-rrc.cc:590
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:3036
uint8_t GetDlBandwidth() const
Definition: lte-ue-rrc.cc:424
LteUeCcmRrcSapUser * m_ccmRrcSapUser
CCM RRC SAP user.
Definition: lte-ue-rrc.h:721
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:782
uint16_t newUeIdentity
new UE identity
Definition: lte-rrc-sap.h:558
double rsrq
Measured RSRQ in dB.
Definition: lte-ue-rrc.h:978
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:513
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:689
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:1564
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:1056
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:1099
double rsrp
Measured RSRP in dBm.
Definition: lte-ue-rrc.h:977
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:2659
LteUeCcmRrcSapUser * GetLteCcmRrcSapUser()
Get the Component Carrier Management SAP offered by this RRC.
Definition: lte-ue-rrc.cc:370
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:720
uint8_t m_ulBandwidth
Uplink bandwidth in RBs.
Definition: lte-ue-rrc.h:767
Event A4: Neighbour becomes better than absolute threshold.
Definition: lte-rrc-sap.h:369
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition: assert.h:90
LteUeCphySapUser * GetLteUeCphySapUser()
Definition: lte-ue-rrc.cc:300
Reference Signal Received Quality.
Definition: lte-rrc-sap.h:400
TracedCallback< uint64_t, uint16_t, uint16_t > m_connectionReconfigurationTrace
The ConnectionReconfiguration trace source.
Definition: lte-ue-rrc.h:829
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:749
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
uint64_t GetImsi(void) const
Definition: lte-ue-rrc.cc:396
RachConfigCommon rachConfigCommon
RACH config common.
Definition: lte-rrc-sap.h:273
void StartConnection()
Start connetion function.
Definition: lte-ue-rrc.cc:2919
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
uint16_t GetRnti() const
Definition: lte-ue-rrc.cc:402
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:1669
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:671
std::vector< LteUeCmacSapUser * > m_cmacSapUser
UE CMac SAP user.
Definition: lte-ue-rrc.h:705
void DoNotifyRandomAccessFailed()
Notify random access failed function.
Definition: lte-ue-rrc.cc:638
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:895
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition: log.h:261
LteUeRrcSapProvider * m_rrcSapProvider
RRC SAP provider.
Definition: lte-ue-rrc.h:709
void DoConnect()
Connect function.
Definition: lte-ue-rrc.cc:734
bool haveSpeedStatePars
have speed state parameters?
Definition: lte-rrc-sap.h:525
void ApplyRadioResourceConfigDedicated(LteRrcSap::RadioResourceConfigDedicated rrcd)
Apply radio resoure config dedicated.
Definition: lte-ue-rrc.cc:1264
TracedCallback< uint64_t, uint16_t, uint16_t > m_connectionEstablishedTrace
The ConnectionEstablished trace source.
Definition: lte-ue-rrc.h:819
uint16_t GetCellId() const
Definition: lte-ue-rrc.cc:409
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:912
virtual void NotifyConnectionFailed()=0
Notify the NAS that RRC Connection Establishment failed.
LteAsSapProvider * m_asSapProvider
AS SAP provider.
Definition: lte-ue-rrc.h:714
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:269
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:993
LteRlcSapProvider * srb0SapProvider
SRB0 SAP provider.
Definition: lte-rrc-sap.h:915
Reference Signal Received Power.
Definition: lte-rrc-sap.h:399
TracedCallback< uint64_t, uint16_t, uint16_t, uint16_t > m_mibReceivedTrace
The MibReceived trace source.
Definition: lte-ue-rrc.h:776
uint16_t m_rnti
The C-RNTI attribute.
Definition: lte-ue-rrc.h:731
uint64_t m_imsi
The unique UE identifier.
Definition: lte-ue-rrc.h:727
uint8_t transmissionMode
transmission mode
Definition: lte-rrc-sap.h:143
void ApplyRadioResourceConfigDedicatedSecondaryCarrier(LteRrcSap::NonCriticalExtensionConfiguration nonCec)
Apply radio resoure config dedicated secondary carrier.
Definition: lte-ue-rrc.cc:1230
SystemInformationBlockType2 sib2
SIB2.
Definition: lte-rrc-sap.h:604
UeMeasurementsParameters structure.
Event A3: Neighbour becomes amount of offset better than PCell.
Definition: lte-rrc-sap.h:368
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:859
void Cancel(void)
This method is syntactic sugar for the ns3::Simulator::Cancel method.
Definition: event-id.cc:53
LteAsSapProvider * GetAsSapProvider()
Definition: lte-ue-rrc.cc:383
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:843
MobilityControlInfo mobilityControlInfo
mobility control info
Definition: lte-rrc-sap.h:835
TracedCallback< uint64_t, uint16_t, uint16_t > m_connectionTimeoutTrace
The ConnectionTimeout trace source.
Definition: lte-ue-rrc.h:824
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:899
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:253
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:793
void SendMeasurementReport(uint8_t measId)
Produce a proper measurement report from the given measurement identity's reporting entry in m_varMea...
Definition: lte-ue-rrc.cc:2739
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:1120
Container for a set of ns3::Object pointers.
void InitializeSap(void)
Initiaize SAP.
Definition: lte-ue-rrc.cc:489
void DoReceivePdcpSdu(LtePdcpSapUser::ReceivePdcpSduParameters params)
Receive PDCP SDU function.
Definition: lte-ue-rrc.cc:573
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 GetDlEarfcn() const
Definition: lte-ue-rrc.cc:431
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
State GetState() const
Definition: lte-ue-rrc.cc:444
UeMemberLteUeCmacSapUser(LteUeRrc *rrc)
Constructor.
Definition: lte-ue-rrc.cc:69
LteUeRrcSapProvider * GetLteUeRrcSapProvider()
Definition: lte-ue-rrc.cc:349
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:917
Time m_t300
The T300 attribute.
Definition: lte-ue-rrc.h:1140
UlConfiguration ulConfiguration
UL configuration.
Definition: lte-rrc-sap.h:802
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:2592
void DoDisconnect()
Disconnect function.
Definition: lte-ue-rrc.cc:539
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:809
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:1041
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:914
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:389
uint8_t m_lastRrcTransactionIdentifier
last RRC transaction identifier
Definition: lte-ue-rrc.h:762
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:2720
void LeaveConnectedMode()
Leave connected mode.
Definition: lte-ue-rrc.cc:2930
uint32_t m_ulEarfcn
Uplink carrier frequency.
Definition: lte-ue-rrc.h:770
TracedCallback< uint64_t, uint16_t, uint16_t > m_handoverEndErrorTrace
The HandoverEndError trace source.
Definition: lte-ue-rrc.h:844
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:856
void SetLteMacSapProvider(LteMacSapProvider *s)
Definition: lte-rlc.cc:159
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