A Discrete-Event Network Simulator
API
lte-ue-rrc.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2011, 2012 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
3  * Copyright (c) 2018 Fraunhofer ESK : RLF extensions
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  * Vignesh Babu <ns3-dev@esk.fraunhofer.de> (RLF extensions)
24  */
25 
26 #include "lte-ue-rrc.h"
27 
28 #include "lte-common.h"
29 #include "lte-pdcp.h"
30 #include "lte-radio-bearer-info.h"
31 #include "lte-rlc-am.h"
32 #include "lte-rlc-tm.h"
33 #include "lte-rlc-um.h"
34 #include "lte-rlc.h"
35 
36 #include <ns3/fatal-error.h>
37 #include <ns3/log.h>
38 #include <ns3/object-factory.h>
39 #include <ns3/object-map.h>
40 #include <ns3/simulator.h>
41 
42 #include <cmath>
43 
44 namespace ns3
45 {
46 
47 NS_LOG_COMPONENT_DEFINE("LteUeRrc");
48 
50 // CMAC SAP forwarder
52 
55 {
56  public:
63 
64  void SetTemporaryCellRnti(uint16_t rnti) override;
65  void NotifyRandomAccessSuccessful() override;
66  void NotifyRandomAccessFailed() override;
67 
68  private:
70 };
71 
73  : m_rrc(rrc)
74 {
75 }
76 
77 void
79 {
81 }
82 
83 void
85 {
87 }
88 
89 void
91 {
93 }
94 
96 static const std::string g_ueRrcStateName[LteUeRrc::NUM_STATES] = {
97  "IDLE_START",
98  "IDLE_CELL_SEARCH",
99  "IDLE_WAIT_MIB_SIB1",
100  "IDLE_WAIT_MIB",
101  "IDLE_WAIT_SIB1",
102  "IDLE_CAMPED_NORMALLY",
103  "IDLE_WAIT_SIB2",
104  "IDLE_RANDOM_ACCESS",
105  "IDLE_CONNECTING",
106  "CONNECTED_NORMALLY",
107  "CONNECTED_HANDOVER",
108  "CONNECTED_PHY_PROBLEM",
109  "CONNECTED_REESTABLISHING",
110 };
111 
113 // ue RRC methods
115 
117 
119  : m_cmacSapProvider(0),
120  m_rrcSapUser(nullptr),
121  m_macSapProvider(nullptr),
122  m_asSapUser(nullptr),
123  m_ccmRrcSapProvider(nullptr),
124  m_state(IDLE_START),
125  m_imsi(0),
126  m_rnti(0),
127  m_cellId(0),
128  m_useRlcSm(true),
129  m_connectionPending(false),
130  m_hasReceivedMib(false),
131  m_hasReceivedSib1(false),
132  m_hasReceivedSib2(false),
133  m_csgWhiteList(0),
134  m_noOfSyncIndications(0),
135  m_leaveConnectedMode(false),
136  m_previousCellId(0),
137  m_connEstFailCountLimit(0),
138  m_connEstFailCount(0),
139  m_numberOfComponentCarriers(MIN_NO_CC)
140 {
141  NS_LOG_FUNCTION(this);
142  m_cphySapUser.push_back(new MemberLteUeCphySapUser<LteUeRrc>(this));
143  m_cmacSapUser.push_back(new UeMemberLteUeCmacSapUser(this));
144  m_cphySapProvider.push_back(nullptr);
145  m_cmacSapProvider.push_back(nullptr);
150 }
151 
153 {
154  NS_LOG_FUNCTION(this);
155 }
156 
157 void
159 {
160  NS_LOG_FUNCTION(this);
161  for (uint16_t i = 0; i < m_numberOfComponentCarriers; i++)
162  {
163  delete m_cphySapUser.at(i);
164  delete m_cmacSapUser.at(i);
165  }
166  m_cphySapUser.clear();
167  m_cmacSapUser.clear();
168  delete m_rrcSapProvider;
169  delete m_drbPdcpSapUser;
170  delete m_asSapProvider;
171  delete m_ccmRrcSapUser;
173  m_cphySapProvider.clear();
175  m_cmacSapProvider.clear();
176  m_drbMap.clear();
177 }
178 
179 TypeId
181 {
182  static TypeId tid =
183  TypeId("ns3::LteUeRrc")
184  .SetParent<Object>()
185  .SetGroupName("Lte")
186  .AddConstructor<LteUeRrc>()
187  .AddAttribute("DataRadioBearerMap",
188  "List of UE RadioBearerInfo for Data Radio Bearers by LCID.",
189  ObjectMapValue(),
191  MakeObjectMapChecker<LteDataRadioBearerInfo>())
192  .AddAttribute("Srb0",
193  "SignalingRadioBearerInfo for SRB0",
194  PointerValue(),
196  MakePointerChecker<LteSignalingRadioBearerInfo>())
197  .AddAttribute("Srb1",
198  "SignalingRadioBearerInfo for SRB1",
199  PointerValue(),
201  MakePointerChecker<LteSignalingRadioBearerInfo>())
202  .AddAttribute("CellId",
203  "Serving cell identifier",
204  UintegerValue(0), // unused, read-only attribute
206  MakeUintegerChecker<uint16_t>())
207  .AddAttribute("C-RNTI",
208  "Cell Radio Network Temporary Identifier",
209  UintegerValue(0), // unused, read-only attribute
211  MakeUintegerChecker<uint16_t>())
212  .AddAttribute(
213  "T300",
214  "Timer for the RRC Connection Establishment procedure "
215  "(i.e., the procedure is deemed as failed if it takes longer than this). "
216  "Standard values: 100ms, 200ms, 300ms, 400ms, 600ms, 1000ms, 1500ms, 2000ms",
218  100)), // see 3GPP 36.331 UE-TimersAndConstants & RLF-TimersAndConstants
221  .AddAttribute(
222  "T310",
223  "Timer for detecting the Radio link failure "
224  "(i.e., the radio link is deemed as failed if this timer expires). "
225  "Standard values: 0ms 50ms, 100ms, 200ms, 500ms, 1000ms, 2000ms",
227  1000)), // see 3GPP 36.331 UE-TimersAndConstants & RLF-TimersAndConstants
230  .AddAttribute(
231  "N310",
232  "This specifies the maximum number of out-of-sync indications. "
233  "Standard values: 1, 2, 3, 4, 6, 8, 10, 20",
234  UintegerValue(6), // see 3GPP 36.331 UE-TimersAndConstants & RLF-TimersAndConstants
236  MakeUintegerChecker<uint8_t>(1, 20))
237  .AddAttribute(
238  "N311",
239  "This specifies the maximum number of in-sync indications. "
240  "Standard values: 1, 2, 3, 4, 5, 6, 8, 10",
241  UintegerValue(2), // see 3GPP 36.331 UE-TimersAndConstants & RLF-TimersAndConstants
243  MakeUintegerChecker<uint8_t>(1, 10))
244  .AddTraceSource("MibReceived",
245  "trace fired upon reception of Master Information Block",
247  "ns3::LteUeRrc::MibSibHandoverTracedCallback")
248  .AddTraceSource("Sib1Received",
249  "trace fired upon reception of System Information Block Type 1",
251  "ns3::LteUeRrc::MibSibHandoverTracedCallback")
252  .AddTraceSource("Sib2Received",
253  "trace fired upon reception of System Information Block Type 2",
255  "ns3::LteUeRrc::ImsiCidRntiTracedCallback")
256  .AddTraceSource("StateTransition",
257  "trace fired upon every UE RRC state transition",
259  "ns3::LteUeRrc::StateTracedCallback")
260  .AddTraceSource("InitialCellSelectionEndOk",
261  "trace fired upon successful initial cell selection procedure",
263  "ns3::LteUeRrc::CellSelectionTracedCallback")
264  .AddTraceSource("InitialCellSelectionEndError",
265  "trace fired upon failed initial cell selection procedure",
267  "ns3::LteUeRrc::CellSelectionTracedCallback")
268  .AddTraceSource("RandomAccessSuccessful",
269  "trace fired upon successful completion of the random access procedure",
271  "ns3::LteUeRrc::ImsiCidRntiTracedCallback")
272  .AddTraceSource("RandomAccessError",
273  "trace fired upon failure of the random access procedure",
275  "ns3::LteUeRrc::ImsiCidRntiTracedCallback")
276  .AddTraceSource("ConnectionEstablished",
277  "trace fired upon successful RRC connection establishment",
279  "ns3::LteUeRrc::ImsiCidRntiTracedCallback")
280  .AddTraceSource("ConnectionTimeout",
281  "trace fired upon timeout RRC connection establishment because of T300",
283  "ns3::LteUeRrc::ImsiCidRntiCountTracedCallback")
284  .AddTraceSource("ConnectionReconfiguration",
285  "trace fired upon RRC connection reconfiguration",
287  "ns3::LteUeRrc::ImsiCidRntiTracedCallback")
288  .AddTraceSource("HandoverStart",
289  "trace fired upon start of a handover procedure",
291  "ns3::LteUeRrc::MibSibHandoverTracedCallback")
292  .AddTraceSource("HandoverEndOk",
293  "trace fired upon successful termination of a handover procedure",
295  "ns3::LteUeRrc::ImsiCidRntiTracedCallback")
296  .AddTraceSource("HandoverEndError",
297  "trace fired upon failure of a handover procedure",
299  "ns3::LteUeRrc::ImsiCidRntiTracedCallback")
300  .AddTraceSource("SCarrierConfigured",
301  "trace fired after configuring secondary carriers",
303  "ns3::LteUeRrc::SCarrierConfiguredTracedCallback")
304  .AddTraceSource("Srb1Created",
305  "trace fired after SRB1 is created",
307  "ns3::LteUeRrc::ImsiCidRntiTracedCallback")
308  .AddTraceSource("DrbCreated",
309  "trace fired after DRB is created",
311  "ns3::LteUeRrc::ImsiCidRntiLcIdTracedCallback")
312  .AddTraceSource("RadioLinkFailure",
313  "trace fired upon failure of radio link",
315  "ns3::LteUeRrc::ImsiCidRntiTracedCallback")
316  .AddTraceSource(
317  "PhySyncDetection",
318  "trace fired upon receiving in Sync or out of Sync indications from UE PHY",
320  "ns3::LteUeRrc::PhySyncDetectionTracedCallback");
321  return tid;
322 }
323 
324 void
326 {
327  NS_LOG_FUNCTION(this << s);
328  m_cphySapProvider.at(0) = s;
329 }
330 
331 void
333 {
334  NS_LOG_FUNCTION(this << s);
335  m_cphySapProvider.at(index) = s;
336 }
337 
340 {
341  NS_LOG_FUNCTION(this);
342  return m_cphySapUser.at(0);
343 }
344 
347 {
348  NS_LOG_FUNCTION(this);
349  return m_cphySapUser.at(index);
350 }
351 
352 void
354 {
355  NS_LOG_FUNCTION(this << s);
356  m_cmacSapProvider.at(0) = s;
357 }
358 
359 void
361 {
362  NS_LOG_FUNCTION(this << s);
363  m_cmacSapProvider.at(index) = s;
364 }
365 
368 {
369  NS_LOG_FUNCTION(this);
370  return m_cmacSapUser.at(0);
371 }
372 
375 {
376  NS_LOG_FUNCTION(this);
377  return m_cmacSapUser.at(index);
378 }
379 
380 void
382 {
383  NS_LOG_FUNCTION(this << s);
384  m_rrcSapUser = s;
385 }
386 
389 {
390  NS_LOG_FUNCTION(this);
391  return m_rrcSapProvider;
392 }
393 
394 void
396 {
397  NS_LOG_FUNCTION(this << s);
398  m_macSapProvider = s;
399 }
400 
401 void
403 {
404  NS_LOG_FUNCTION(this << s);
406 }
407 
410 {
411  NS_LOG_FUNCTION(this);
412  return m_ccmRrcSapUser;
413 }
414 
415 void
417 {
418  m_asSapUser = s;
419 }
420 
423 {
424  return m_asSapProvider;
425 }
426 
427 void
428 LteUeRrc::SetImsi(uint64_t imsi)
429 {
430  NS_LOG_FUNCTION(this << imsi);
431  m_imsi = imsi;
432 
433  // Communicate the IMSI to MACs and PHYs for all the component carriers
434  for (uint16_t i = 0; i < m_numberOfComponentCarriers; i++)
435  {
436  m_cmacSapProvider.at(i)->SetImsi(m_imsi);
437  m_cphySapProvider.at(i)->SetImsi(m_imsi);
438  }
439 }
440 
441 void
443 {
444  NS_LOG_FUNCTION(this << cellId);
445  m_previousCellId = cellId;
446 }
447 
448 uint64_t
450 {
451  return m_imsi;
452 }
453 
454 uint16_t
456 {
457  NS_LOG_FUNCTION(this);
458  return m_rnti;
459 }
460 
461 uint16_t
463 {
464  NS_LOG_FUNCTION(this);
465  return m_cellId;
466 }
467 
468 bool
469 LteUeRrc::IsServingCell(uint16_t cellId) const
470 {
471  NS_LOG_FUNCTION(this);
472  for (auto& cphySap : m_cphySapProvider)
473  {
474  if (cellId == cphySap->GetCellId())
475  {
476  return true;
477  }
478  }
479  return false;
480 }
481 
482 uint8_t
484 {
485  NS_LOG_FUNCTION(this);
486  return m_ulBandwidth;
487 }
488 
489 uint8_t
491 {
492  NS_LOG_FUNCTION(this);
493  return m_dlBandwidth;
494 }
495 
496 uint32_t
498 {
499  return m_dlEarfcn;
500 }
501 
502 uint32_t
504 {
505  NS_LOG_FUNCTION(this);
506  return m_ulEarfcn;
507 }
508 
511 {
512  NS_LOG_FUNCTION(this);
513  return m_state;
514 }
515 
516 uint16_t
518 {
519  NS_LOG_FUNCTION(this);
520  return m_previousCellId;
521 }
522 
523 void
525 {
526  NS_LOG_FUNCTION(this);
527  m_useRlcSm = val;
528 }
529 
530 void
532 {
533  NS_LOG_FUNCTION(this);
534 
535  // setup the UE side of SRB0
536  uint8_t lcid = 0;
537 
538  Ptr<LteRlc> rlc = CreateObject<LteRlcTm>()->GetObject<LteRlc>();
540  rlc->SetRnti(m_rnti);
541  rlc->SetLcId(lcid);
542 
543  m_srb0 = CreateObject<LteSignalingRadioBearerInfo>();
544  m_srb0->m_rlc = rlc;
545  m_srb0->m_srbIdentity = 0;
547  ueParams.srb0SapProvider = m_srb0->m_rlc->GetLteRlcSapProvider();
548  ueParams.srb1SapProvider = nullptr;
549  m_rrcSapUser->Setup(ueParams);
550 
551  // CCCH (LCID 0) is pre-configured, here is the hardcoded configuration:
553  lcConfig.priority = 0; // highest priority
554  lcConfig.prioritizedBitRateKbps = 65535; // maximum
555  lcConfig.bucketSizeDurationMs = 65535; // maximum
556  lcConfig.logicalChannelGroup = 0; // all SRBs mapped to LCG 0
557  LteMacSapUser* msu =
559  m_cmacSapProvider.at(0)->AddLc(lcid, lcConfig, msu);
560 }
561 
562 void
564 {
565  if (m_numberOfComponentCarriers < MIN_NO_CC || m_numberOfComponentCarriers > MAX_NO_CC)
566  {
567  // this check is needed in order to maintain backward compatibility with scripts and tests
568  // if case lte-helper is not used (like in several tests) the m_numberOfComponentCarriers
569  // is not set and then an error is raised
570  // In this case m_numberOfComponentCarriers is set to 1
572  }
574  {
575  for (uint16_t i = 1; i < m_numberOfComponentCarriers; i++)
576  {
577  m_cphySapUser.push_back(new MemberLteUeCphySapUser<LteUeRrc>(this));
578  m_cmacSapUser.push_back(new UeMemberLteUeCmacSapUser(this));
579  m_cphySapProvider.push_back(nullptr);
580  m_cmacSapProvider.push_back(nullptr);
581  }
582  }
583 }
584 
585 void
586 LteUeRrc::DoSendData(Ptr<Packet> packet, uint8_t bid)
587 {
588  NS_LOG_FUNCTION(this << packet);
589 
590  uint8_t drbid = Bid2Drbid(bid);
591 
592  if (drbid != 0)
593  {
594  auto it = m_drbMap.find(drbid);
595  NS_ASSERT_MSG(it != m_drbMap.end(), "could not find bearer with drbid == " << drbid);
596 
598  params.pdcpSdu = packet;
599  params.rnti = m_rnti;
600  params.lcid = it->second->m_logicalChannelIdentity;
601 
602  NS_LOG_LOGIC(this << " RNTI=" << m_rnti << " sending packet " << packet << " on DRBID "
603  << (uint32_t)drbid << " (LCID " << (uint32_t)params.lcid << ")"
604  << " (" << packet->GetSize() << " bytes)");
605  it->second->m_pdcp->GetLtePdcpSapProvider()->TransmitPdcpSdu(params);
606  }
607 }
608 
609 void
611 {
612  NS_LOG_FUNCTION(this);
613 
614  switch (m_state)
615  {
616  case IDLE_START:
617  case IDLE_CELL_SEARCH:
618  case IDLE_WAIT_MIB_SIB1:
619  case IDLE_WAIT_MIB:
620  case IDLE_WAIT_SIB1:
622  NS_LOG_INFO("already disconnected");
623  break;
624 
625  case IDLE_WAIT_SIB2:
626  case IDLE_CONNECTING:
627  NS_FATAL_ERROR("cannot abort connection setup procedure");
628  break;
629 
630  case CONNECTED_NORMALLY:
631  case CONNECTED_HANDOVER:
635  break;
636 
637  default: // i.e. IDLE_RANDOM_ACCESS
638  NS_FATAL_ERROR("method unexpected in state " << ToString(m_state));
639  break;
640  }
641 }
642 
643 void
645 {
646  NS_LOG_FUNCTION(this);
647  m_asSapUser->RecvData(params.pdcpSdu);
648 }
649 
650 void
652 {
653  NS_LOG_FUNCTION(this << rnti);
654  m_rnti = rnti;
655  m_srb0->m_rlc->SetRnti(m_rnti);
656  m_cphySapProvider.at(0)->SetRnti(m_rnti);
657 }
658 
659 void
661 {
662  NS_LOG_FUNCTION(this << m_imsi << ToString(m_state));
664 
665  switch (m_state)
666  {
667  case IDLE_RANDOM_ACCESS: {
668  // we just received a RAR with a T-C-RNTI and an UL grant
669  // send RRC connection request as message 3 of the random access procedure
672  msg.ueIdentity = m_imsi;
675  }
676  break;
677 
678  case CONNECTED_HANDOVER: {
682 
683  // 3GPP TS 36.331 section 5.5.6.1 Measurements related actions upon handover
684  for (auto measIdIt = m_varMeasConfig.measIdList.begin();
685  measIdIt != m_varMeasConfig.measIdList.end();
686  ++measIdIt)
687  {
688  VarMeasReportListClear(measIdIt->second.measId);
689  }
690 
692  m_cmacSapProvider.at(0)->NotifyConnectionSuccessful(); // RA successful during handover
694  }
695  break;
696 
697  default:
698  NS_FATAL_ERROR("unexpected event in state " << ToString(m_state));
699  break;
700  }
701 }
702 
703 void
705 {
706  NS_LOG_FUNCTION(this << m_imsi << ToString(m_state));
708 
709  switch (m_state)
710  {
711  case IDLE_RANDOM_ACCESS: {
714  }
715  break;
716 
717  case CONNECTED_HANDOVER: {
725  {
726  m_leaveConnectedMode = true;
729  // we should have called NotifyConnectionFailed
730  // but that method would immediately ask you UE to
731  // connect rather than doing cell selection again.
733  }
734  }
735  break;
736 
737  default:
738  NS_FATAL_ERROR("unexpected event in state " << ToString(m_state));
739  break;
740  }
741 }
742 
743 void
745 {
746  NS_LOG_FUNCTION(this << m_imsi << csgId);
747  m_csgWhiteList = csgId;
748 }
749 
750 void
752 {
753  NS_LOG_FUNCTION(this << m_imsi << dlEarfcn);
755  "cannot start cell selection from state " << ToString(m_state));
756  m_dlEarfcn = dlEarfcn;
757  m_cphySapProvider.at(0)->StartCellSearch(dlEarfcn);
759 }
760 
761 void
762 LteUeRrc::DoForceCampedOnEnb(uint16_t cellId, uint32_t dlEarfcn)
763 {
764  NS_LOG_FUNCTION(this << m_imsi << cellId << dlEarfcn);
765 
766  switch (m_state)
767  {
768  case IDLE_START:
769  m_cellId = cellId;
770  m_dlEarfcn = dlEarfcn;
771  m_cphySapProvider.at(0)->SynchronizeWithEnb(m_cellId, m_dlEarfcn);
773  break;
774 
775  case IDLE_CELL_SEARCH:
776  case IDLE_WAIT_MIB_SIB1:
777  case IDLE_WAIT_SIB1:
778  NS_FATAL_ERROR("cannot abort cell selection " << ToString(m_state));
779  break;
780 
781  case IDLE_WAIT_MIB:
782  NS_LOG_INFO("already forced to camp to cell " << m_cellId);
783  break;
784 
786  case IDLE_WAIT_SIB2:
787  case IDLE_RANDOM_ACCESS:
788  case IDLE_CONNECTING:
789  NS_LOG_INFO("already camped to cell " << m_cellId);
790  break;
791 
792  case CONNECTED_NORMALLY:
793  case CONNECTED_HANDOVER:
796  NS_LOG_INFO("already connected to cell " << m_cellId);
797  break;
798 
799  default:
800  NS_FATAL_ERROR("unexpected event in state " << ToString(m_state));
801  break;
802  }
803 }
804 
805 void
807 {
808  NS_LOG_FUNCTION(this << m_imsi);
809 
810  switch (m_state)
811  {
812  case IDLE_START:
813  case IDLE_CELL_SEARCH:
814  case IDLE_WAIT_MIB_SIB1:
815  case IDLE_WAIT_SIB1:
816  case IDLE_WAIT_MIB:
817  m_connectionPending = true;
818  break;
819 
821  m_connectionPending = true;
823  break;
824 
825  case IDLE_WAIT_SIB2:
826  case IDLE_RANDOM_ACCESS:
827  case IDLE_CONNECTING:
828  NS_LOG_INFO("already connecting");
829  break;
830 
831  case CONNECTED_NORMALLY:
833  case CONNECTED_HANDOVER:
834  NS_LOG_INFO("already connected");
835  break;
836 
837  default:
838  NS_FATAL_ERROR("unexpected event in state " << ToString(m_state));
839  break;
840  }
841 }
842 
843 // CPHY SAP methods
844 
845 void
847 {
849  m_cphySapProvider.at(0)->SetDlBandwidth(msg.dlBandwidth);
850  m_hasReceivedMib = true;
852 
853  switch (m_state)
854  {
855  case IDLE_WAIT_MIB:
856  // manual attachment
858  break;
859 
860  case IDLE_WAIT_MIB_SIB1:
861  // automatic attachment from Idle mode cell selection
863  break;
864 
865  default:
866  // do nothing extra
867  break;
868  }
869 }
870 
871 void
874 {
875  NS_LOG_FUNCTION(this);
876  switch (m_state)
877  {
878  case IDLE_WAIT_SIB1:
880  "Cell identity in SIB1 does not match with the originating cell");
881  m_hasReceivedSib1 = true;
882  m_lastSib1 = msg;
885  break;
886 
888  case IDLE_RANDOM_ACCESS:
889  case IDLE_CONNECTING:
890  case CONNECTED_NORMALLY:
891  case CONNECTED_HANDOVER:
895  "Cell identity in SIB1 does not match with the originating cell");
896  m_hasReceivedSib1 = true;
897  m_lastSib1 = msg;
899  break;
900 
901  case IDLE_WAIT_MIB_SIB1:
902  // MIB has not been received, so ignore this SIB1
903  break;
904 
905  default: // e.g. IDLE_START, IDLE_CELL_SEARCH, IDLE_WAIT_MIB, IDLE_WAIT_SIB2
906  // do nothing
907  break;
908  }
909 }
910 
911 void
913 {
914  NS_LOG_FUNCTION(this);
915 
916  // layer 3 filtering does not apply in IDLE mode
917  bool useLayer3Filtering = (m_state == CONNECTED_NORMALLY);
918  bool triggering = true;
919  for (auto newMeasIt = params.m_ueMeasurementsList.begin();
920  newMeasIt != params.m_ueMeasurementsList.end();
921  ++newMeasIt)
922  {
923  if (params.m_componentCarrierId != 0)
924  {
925  triggering = false; // report is triggered only when an event is on the primary carrier
926  // in this case the measurement received is related to secondary carriers
927  }
928  SaveUeMeasurements(newMeasIt->m_cellId,
929  newMeasIt->m_rsrp,
930  newMeasIt->m_rsrq,
931  useLayer3Filtering,
932  params.m_componentCarrierId);
933  }
934 
935  if (m_state == IDLE_CELL_SEARCH)
936  {
937  // start decoding BCH
939  }
940  else
941  {
942  if (triggering)
943  {
944  for (auto measIdIt = m_varMeasConfig.measIdList.begin();
945  measIdIt != m_varMeasConfig.measIdList.end();
946  ++measIdIt)
947  {
948  MeasurementReportTriggering(measIdIt->first);
949  }
950  }
951  }
952 
953 } // end of LteUeRrc::DoReportUeMeasurements
954 
955 // RRC SAP methods
956 
957 void
959 {
960  NS_LOG_FUNCTION(this << " RNTI " << m_rnti);
961  m_srb0->m_rlc->SetLteRlcSapUser(params.srb0SapUser);
962  if (m_srb1)
963  {
964  m_srb1->m_pdcp->SetLtePdcpSapUser(params.srb1SapUser);
965  }
966 }
967 
968 void
970 {
971  NS_LOG_FUNCTION(this << " RNTI " << m_rnti);
972 
973  if (msg.haveSib2)
974  {
975  switch (m_state)
976  {
978  case IDLE_WAIT_SIB2:
979  case IDLE_RANDOM_ACCESS:
980  case IDLE_CONNECTING:
981  case CONNECTED_NORMALLY:
982  case CONNECTED_HANDOVER:
985  m_hasReceivedSib2 = true;
990  rc.numberOfRaPreambles = msg.sib2.radioResourceConfigCommon.rachConfigCommon
992  rc.preambleTransMax = msg.sib2.radioResourceConfigCommon.rachConfigCommon
994  rc.raResponseWindowSize = msg.sib2.radioResourceConfigCommon.rachConfigCommon
996  rc.connEstFailCount =
998  m_connEstFailCountLimit = rc.connEstFailCount;
1000  "SIB2 msg contains wrong value " << m_connEstFailCountLimit
1001  << "of connEstFailCount");
1002  m_cmacSapProvider.at(0)->ConfigureRach(rc);
1003  m_cphySapProvider.at(0)->ConfigureUplink(m_ulEarfcn, m_ulBandwidth);
1004  m_cphySapProvider.at(0)->ConfigureReferenceSignalPower(
1006  if (m_state == IDLE_WAIT_SIB2)
1007  {
1009  StartConnection();
1010  }
1011  break;
1012 
1013  default: // IDLE_START, IDLE_CELL_SEARCH, IDLE_WAIT_MIB, IDLE_WAIT_MIB_SIB1, IDLE_WAIT_SIB1
1014  // do nothing
1015  break;
1016  }
1017  }
1018 }
1019 
1020 void
1022 {
1023  NS_LOG_FUNCTION(this << " RNTI " << m_rnti);
1024  switch (m_state)
1025  {
1026  case IDLE_CONNECTING: {
1028  m_connEstFailCount = 0;
1031  m_leaveConnectedMode = false;
1036  m_cmacSapProvider.at(0)->NotifyConnectionSuccessful();
1039  "Sync indications should be zero "
1040  "when a new RRC connection is established. Current value = "
1041  << (uint16_t)m_noOfSyncIndications);
1042  }
1043  break;
1044 
1045  default:
1046  NS_FATAL_ERROR("method unexpected in state " << ToString(m_state));
1047  break;
1048  }
1049 }
1050 
1051 void
1053 {
1054  NS_LOG_FUNCTION(this << " RNTI " << m_rnti);
1055  NS_LOG_INFO("DoRecvRrcConnectionReconfiguration haveNonCriticalExtension:"
1056  << msg.haveNonCriticalExtension);
1057  switch (m_state)
1058  {
1059  case CONNECTED_NORMALLY:
1060  if (msg.haveMobilityControlInfo)
1061  {
1062  NS_LOG_INFO("haveMobilityControlInfo == true");
1065  {
1066  ResetRlfParams();
1067  }
1070  // We should reset the MACs and PHYs for all the component carriers
1071  for (auto cmacSapProvider : m_cmacSapProvider)
1072  {
1073  cmacSapProvider->Reset();
1074  }
1075  for (auto cphySapProvider : m_cphySapProvider)
1076  {
1077  cphySapProvider->Reset();
1078  }
1081  m_cellId = mci.targetPhysCellId;
1084  m_cphySapProvider.at(0)->SynchronizeWithEnb(m_cellId, mci.carrierFreq.dlCarrierFreq);
1085  m_cphySapProvider.at(0)->SetDlBandwidth(mci.carrierBandwidth.dlBandwidth);
1086  m_cphySapProvider.at(0)->ConfigureUplink(mci.carrierFreq.ulCarrierFreq,
1089  m_srb0->m_rlc->SetRnti(m_rnti);
1090  NS_ASSERT_MSG(
1092  "handover is only supported with non-contention-based random access procedure");
1093  m_cmacSapProvider.at(0)->StartNonContentionBasedRandomAccessProcedure(
1094  m_rnti,
1097  m_cphySapProvider.at(0)->SetRnti(m_rnti);
1100 
1101  // we re-establish SRB1 by creating a new entity
1102  // note that we can't dispose the old entity now, because
1103  // it's in the current stack, so we would corrupt the stack
1104  // if we did so. Hence we schedule it for later disposal
1105  m_srb1Old = m_srb1;
1107  m_srb1 =
1108  nullptr; // new instance will be be created within ApplyRadioResourceConfigDedicated
1109 
1110  m_drbMap.clear(); // dispose all DRBs
1112  if (msg.haveNonCriticalExtension)
1113  {
1114  NS_LOG_DEBUG(this << "RNTI " << m_rnti
1115  << " Handover. Configuring secondary carriers");
1117  }
1118 
1119  if (msg.haveMeasConfig)
1120  {
1122  }
1123  // RRC connection reconfiguration completed will be sent
1124  // after handover is complete
1125  }
1126  else
1127  {
1128  NS_LOG_INFO("haveMobilityControlInfo == false");
1129  if (msg.haveNonCriticalExtension)
1130  {
1132  NS_LOG_DEBUG(this << "RNTI " << m_rnti << " Configured for CA");
1133  }
1135  {
1137  }
1138  if (msg.haveMeasConfig)
1139  {
1141  }
1146  }
1147  break;
1148 
1149  default:
1150  NS_FATAL_ERROR("method unexpected in state " << ToString(m_state));
1151  break;
1152  }
1153 }
1154 
1155 void
1157 {
1158  NS_LOG_FUNCTION(this << " RNTI " << m_rnti);
1159  switch (m_state)
1160  {
1161  case CONNECTED_REESTABLISHING: {
1169  }
1170  break;
1171 
1172  default:
1173  NS_FATAL_ERROR("method unexpected in state " << ToString(m_state));
1174  break;
1175  }
1176 }
1177 
1178 void
1181 {
1182  NS_LOG_FUNCTION(this << " RNTI " << m_rnti);
1183  switch (m_state)
1184  {
1185  case CONNECTED_REESTABLISHING: {
1190  m_asSapUser->NotifyConnectionReleased(); // Inform upper layers
1191  }
1192  break;
1193 
1194  default:
1195  NS_FATAL_ERROR("method unexpected in state " << ToString(m_state));
1196  break;
1197  }
1198 }
1199 
1200 void
1202 {
1203  NS_LOG_FUNCTION(this << " RNTI " << m_rnti);
1205 
1207  // release resources at UE
1208  if (!m_leaveConnectedMode)
1209  {
1210  m_leaveConnectedMode = true;
1214  }
1215 }
1216 
1217 void
1219 {
1220  NS_LOG_FUNCTION(this);
1222  for (uint16_t i = 0; i < m_numberOfComponentCarriers; i++)
1223  {
1224  m_cmacSapProvider.at(i)->Reset(); // reset the MAC
1225  }
1226  m_hasReceivedSib2 = false; // invalidate the previously received SIB2
1228  m_asSapUser->NotifyConnectionFailed(); // inform upper layer
1229 }
1230 
1231 void
1232 LteUeRrc::DoSetNumberOfComponentCarriers(uint16_t noOfComponentCarriers)
1233 {
1234  NS_LOG_FUNCTION(this);
1235  m_numberOfComponentCarriers = noOfComponentCarriers;
1236 }
1237 
1238 void
1240 {
1241  NS_LOG_FUNCTION(this);
1243 
1244  uint16_t maxRsrpCellId = 0;
1245  double maxRsrp = -std::numeric_limits<double>::infinity();
1246  double minRsrp = -140.0; // Minimum RSRP in dBm a UE can report
1247 
1248  for (auto it = m_storedMeasValues.begin(); it != m_storedMeasValues.end(); it++)
1249  {
1250  /*
1251  * This block attempts to find a cell with strongest RSRP and has not
1252  * yet been identified as "acceptable cell".
1253  */
1254  if (maxRsrp < it->second.rsrp && it->second.rsrp > minRsrp)
1255  {
1256  auto itCell = m_acceptableCell.find(it->first);
1257  if (itCell == m_acceptableCell.end())
1258  {
1259  maxRsrpCellId = it->first;
1260  maxRsrp = it->second.rsrp;
1261  }
1262  }
1263  }
1264 
1265  if (maxRsrpCellId == 0)
1266  {
1267  NS_LOG_WARN(this << " Cell search is unable to detect surrounding cell to attach to");
1268  }
1269  else
1270  {
1271  NS_LOG_LOGIC(this << " cell " << maxRsrpCellId
1272  << " is the strongest untried surrounding cell");
1273  m_cphySapProvider.at(0)->SynchronizeWithEnb(maxRsrpCellId, m_dlEarfcn);
1275  }
1276 
1277 } // end of void LteUeRrc::SynchronizeToStrongestCell ()
1278 
1279 void
1281 {
1282  NS_LOG_FUNCTION(this);
1286  uint16_t cellId = m_lastSib1.cellAccessRelatedInfo.cellIdentity;
1287 
1288  // Cell selection criteria evaluation
1289 
1290  bool isSuitableCell = false;
1291  bool isAcceptableCell = false;
1292  auto storedMeasIt = m_storedMeasValues.find(cellId);
1293  double qRxLevMeas = storedMeasIt->second.rsrp;
1294  double qRxLevMin =
1296  NS_LOG_LOGIC(this << " cell selection to cellId=" << cellId << " qrxlevmeas=" << qRxLevMeas
1297  << " dBm"
1298  << " qrxlevmin=" << qRxLevMin << " dBm");
1299 
1300  if (qRxLevMeas - qRxLevMin > 0)
1301  {
1302  isAcceptableCell = true;
1303 
1304  uint32_t cellCsgId = m_lastSib1.cellAccessRelatedInfo.csgIdentity;
1305  bool cellCsgIndication = m_lastSib1.cellAccessRelatedInfo.csgIndication;
1306 
1307  isSuitableCell = (!cellCsgIndication || cellCsgId == m_csgWhiteList);
1308 
1309  NS_LOG_LOGIC(this << " csg(ue/cell/indication)=" << m_csgWhiteList << "/" << cellCsgId
1310  << "/" << cellCsgIndication);
1311  }
1312 
1313  // Cell selection decision
1314 
1315  if (isSuitableCell)
1316  {
1317  m_cellId = cellId;
1318  m_cphySapProvider.at(0)->SynchronizeWithEnb(cellId, m_dlEarfcn);
1319  m_cphySapProvider.at(0)->SetDlBandwidth(m_dlBandwidth);
1321  // Once the UE is connected, m_connectionPending is
1322  // set to false. So, when RLF occurs and UE performs
1323  // cell selection upon leaving RRC_CONNECTED state,
1324  // the following call to DoConnect will make the
1325  // m_connectionPending to be true again. Thus,
1326  // upon calling SwitchToState (IDLE_CAMPED_NORMALLY)
1327  // UE state is instantly change to IDLE_WAIT_SIB2.
1328  // This will make the UE to read the SIB2 message
1329  // and start random access.
1330  if (!m_connectionPending)
1331  {
1332  NS_LOG_DEBUG("Calling DoConnect in state = " << ToString(m_state));
1333  DoConnect();
1334  }
1336  }
1337  else
1338  {
1339  // ignore the MIB and SIB1 received from this cell
1340  m_hasReceivedMib = false;
1341  m_hasReceivedSib1 = false;
1342 
1344 
1345  if (isAcceptableCell)
1346  {
1347  /*
1348  * The cells inserted into this list will not be considered for
1349  * subsequent cell search attempt.
1350  */
1351  m_acceptableCell.insert(cellId);
1352  }
1353 
1355  SynchronizeToStrongestCell(); // retry to a different cell
1356  }
1357 
1358 } // end of void LteUeRrc::EvaluateCellForSelection ()
1359 
1360 void
1363 {
1364  NS_LOG_FUNCTION(this);
1365 
1367 
1368  for (uint32_t sCellIndex : nonCec.sCellToReleaseList)
1369  {
1370  m_cphySapProvider.at(sCellIndex)->Reset();
1371  m_cmacSapProvider.at(sCellIndex)->Reset();
1372  }
1373 
1374  for (auto& scell : nonCec.sCellToAddModList)
1375  {
1376  uint8_t ccId = scell.sCellIndex;
1377 
1378  uint16_t physCellId = scell.cellIdentification.physCellId;
1379  uint16_t ulBand =
1380  scell.radioResourceConfigCommonSCell.ulConfiguration.ulFreqInfo.ulBandwidth;
1381  uint32_t ulEarfcn =
1382  scell.radioResourceConfigCommonSCell.ulConfiguration.ulFreqInfo.ulCarrierFreq;
1383  uint16_t dlBand = scell.radioResourceConfigCommonSCell.nonUlConfiguration.dlBandwidth;
1384  uint32_t dlEarfcn = scell.cellIdentification.dlCarrierFreq;
1385  uint8_t txMode = scell.radioResourceConfigDedicatedSCell.physicalConfigDedicatedSCell
1386  .antennaInfo.transmissionMode;
1387  uint16_t srsIndex = scell.radioResourceConfigDedicatedSCell.physicalConfigDedicatedSCell
1388  .soundingRsUlConfigDedicated.srsConfigIndex;
1389 
1390  m_cphySapProvider.at(ccId)->SynchronizeWithEnb(physCellId, dlEarfcn);
1391  m_cphySapProvider.at(ccId)->SetDlBandwidth(dlBand);
1392  m_cphySapProvider.at(ccId)->ConfigureUplink(ulEarfcn, ulBand);
1393  m_cphySapProvider.at(ccId)->ConfigureReferenceSignalPower(
1394  scell.radioResourceConfigCommonSCell.nonUlConfiguration.pdschConfigCommon
1395  .referenceSignalPower);
1396  m_cphySapProvider.at(ccId)->SetTransmissionMode(txMode);
1397  m_cphySapProvider.at(ccId)->SetRnti(m_rnti);
1398  m_cmacSapProvider.at(ccId)->SetRnti(m_rnti);
1399  // update PdschConfigDedicated (i.e. P_A value)
1400  LteRrcSap::PdschConfigDedicated pdschConfigDedicated =
1401  scell.radioResourceConfigDedicatedSCell.physicalConfigDedicatedSCell
1402  .pdschConfigDedicated;
1403  double paDouble = LteRrcSap::ConvertPdschConfigDedicated2Double(pdschConfigDedicated);
1404  m_cphySapProvider.at(ccId)->SetPa(paDouble);
1405  m_cphySapProvider.at(ccId)->SetSrsConfigurationIndex(srsIndex);
1406  }
1407 
1409 }
1410 
1411 void
1413 {
1414  NS_LOG_FUNCTION(this);
1416 
1417  if (pcd.haveAntennaInfoDedicated)
1418  {
1419  m_cphySapProvider.at(0)->SetTransmissionMode(pcd.antennaInfo.transmissionMode);
1420  }
1422  {
1423  m_cphySapProvider.at(0)->SetSrsConfigurationIndex(
1425  }
1426 
1427  if (pcd.havePdschConfigDedicated)
1428  {
1429  // update PdschConfigDedicated (i.e. P_A value)
1432  m_cphySapProvider.at(0)->SetPa(paDouble);
1433  }
1434 
1435  auto stamIt = rrcd.srbToAddModList.begin();
1436  if (stamIt != rrcd.srbToAddModList.end())
1437  {
1438  if (!m_srb1)
1439  {
1440  // SRB1 not setup yet
1442  "unexpected state " << ToString(m_state));
1443  NS_ASSERT_MSG(stamIt->srbIdentity == 1, "only SRB1 supported");
1444 
1445  const uint8_t lcid = 1; // fixed LCID for SRB1
1446 
1447  Ptr<LteRlc> rlc = CreateObject<LteRlcAm>();
1449  rlc->SetRnti(m_rnti);
1450  rlc->SetLcId(lcid);
1451 
1452  Ptr<LtePdcp> pdcp = CreateObject<LtePdcp>();
1453  pdcp->SetRnti(m_rnti);
1454  pdcp->SetLcId(lcid);
1455  pdcp->SetLtePdcpSapUser(m_drbPdcpSapUser);
1456  pdcp->SetLteRlcSapProvider(rlc->GetLteRlcSapProvider());
1457  rlc->SetLteRlcSapUser(pdcp->GetLteRlcSapUser());
1458 
1459  m_srb1 = CreateObject<LteSignalingRadioBearerInfo>();
1460  m_srb1->m_rlc = rlc;
1461  m_srb1->m_pdcp = pdcp;
1462  m_srb1->m_srbIdentity = 1;
1464 
1465  m_srb1->m_logicalChannelConfig.priority = stamIt->logicalChannelConfig.priority;
1466  m_srb1->m_logicalChannelConfig.prioritizedBitRateKbps =
1467  stamIt->logicalChannelConfig.prioritizedBitRateKbps;
1468  m_srb1->m_logicalChannelConfig.bucketSizeDurationMs =
1469  stamIt->logicalChannelConfig.bucketSizeDurationMs;
1470  m_srb1->m_logicalChannelConfig.logicalChannelGroup =
1471  stamIt->logicalChannelConfig.logicalChannelGroup;
1472 
1474  lcConfig.priority = stamIt->logicalChannelConfig.priority;
1475  lcConfig.prioritizedBitRateKbps = stamIt->logicalChannelConfig.prioritizedBitRateKbps;
1476  lcConfig.bucketSizeDurationMs = stamIt->logicalChannelConfig.bucketSizeDurationMs;
1477  lcConfig.logicalChannelGroup = stamIt->logicalChannelConfig.logicalChannelGroup;
1478  LteMacSapUser* msu =
1480  m_cmacSapProvider.at(0)->AddLc(lcid, lcConfig, msu);
1481  ++stamIt;
1482  NS_ASSERT_MSG(stamIt == rrcd.srbToAddModList.end(), "at most one SrbToAdd supported");
1483 
1485  ueParams.srb0SapProvider = m_srb0->m_rlc->GetLteRlcSapProvider();
1486  ueParams.srb1SapProvider = m_srb1->m_pdcp->GetLtePdcpSapProvider();
1487  m_rrcSapUser->Setup(ueParams);
1488  }
1489  else
1490  {
1491  NS_LOG_INFO("request to modify SRB1 (skipping as currently not implemented)");
1492  // would need to modify m_srb1, and then propagate changes to the MAC
1493  }
1494  }
1495 
1496  for (auto dtamIt = rrcd.drbToAddModList.begin(); dtamIt != rrcd.drbToAddModList.end(); ++dtamIt)
1497  {
1498  NS_LOG_INFO(this << " IMSI " << m_imsi << " adding/modifying DRBID "
1499  << (uint32_t)dtamIt->drbIdentity << " LC "
1500  << (uint32_t)dtamIt->logicalChannelIdentity);
1501  NS_ASSERT_MSG(dtamIt->logicalChannelIdentity > 2,
1502  "LCID value " << dtamIt->logicalChannelIdentity << " is reserved for SRBs");
1503 
1504  auto drbMapIt = m_drbMap.find(dtamIt->drbIdentity);
1505  if (drbMapIt == m_drbMap.end())
1506  {
1507  NS_LOG_INFO("New Data Radio Bearer");
1508 
1509  TypeId rlcTypeId;
1510  if (m_useRlcSm)
1511  {
1512  rlcTypeId = LteRlcSm::GetTypeId();
1513  }
1514  else
1515  {
1516  switch (dtamIt->rlcConfig.choice)
1517  {
1519  rlcTypeId = LteRlcAm::GetTypeId();
1520  break;
1521 
1523  rlcTypeId = LteRlcUm::GetTypeId();
1524  break;
1525 
1526  default:
1527  NS_FATAL_ERROR("unsupported RLC configuration");
1528  break;
1529  }
1530  }
1531 
1532  ObjectFactory rlcObjectFactory;
1533  rlcObjectFactory.SetTypeId(rlcTypeId);
1534  Ptr<LteRlc> rlc = rlcObjectFactory.Create()->GetObject<LteRlc>();
1536  rlc->SetRnti(m_rnti);
1537  rlc->SetLcId(dtamIt->logicalChannelIdentity);
1538 
1539  Ptr<LteDataRadioBearerInfo> drbInfo = CreateObject<LteDataRadioBearerInfo>();
1540  drbInfo->m_rlc = rlc;
1541  drbInfo->m_epsBearerIdentity = dtamIt->epsBearerIdentity;
1542  drbInfo->m_logicalChannelIdentity = dtamIt->logicalChannelIdentity;
1543  drbInfo->m_drbIdentity = dtamIt->drbIdentity;
1544 
1545  // we need PDCP only for real RLC, i.e., RLC/UM or RLC/AM
1546  // if we are using RLC/SM we don't care of anything above RLC
1547  if (rlcTypeId != LteRlcSm::GetTypeId())
1548  {
1549  Ptr<LtePdcp> pdcp = CreateObject<LtePdcp>();
1550  pdcp->SetRnti(m_rnti);
1551  pdcp->SetLcId(dtamIt->logicalChannelIdentity);
1552  pdcp->SetLtePdcpSapUser(m_drbPdcpSapUser);
1553  pdcp->SetLteRlcSapProvider(rlc->GetLteRlcSapProvider());
1554  rlc->SetLteRlcSapUser(pdcp->GetLteRlcSapUser());
1555  drbInfo->m_pdcp = pdcp;
1556  }
1557 
1558  m_bid2DrbidMap[dtamIt->epsBearerIdentity] = dtamIt->drbIdentity;
1559 
1560  m_drbMap.insert(
1561  std::pair<uint8_t, Ptr<LteDataRadioBearerInfo>>(dtamIt->drbIdentity, drbInfo));
1562 
1563  m_drbCreatedTrace(m_imsi, m_cellId, m_rnti, dtamIt->drbIdentity);
1564 
1566  lcConfig.priority = dtamIt->logicalChannelConfig.priority;
1567  lcConfig.prioritizedBitRateKbps = dtamIt->logicalChannelConfig.prioritizedBitRateKbps;
1568  lcConfig.bucketSizeDurationMs = dtamIt->logicalChannelConfig.bucketSizeDurationMs;
1569  lcConfig.logicalChannelGroup = dtamIt->logicalChannelConfig.logicalChannelGroup;
1570 
1571  NS_LOG_DEBUG(this << " UE RRC RNTI " << m_rnti << " Number Of Component Carriers "
1572  << m_numberOfComponentCarriers << " lcID "
1573  << (uint16_t)dtamIt->logicalChannelIdentity);
1574  // Call AddLc of UE component carrier manager
1575  std::vector<LteUeCcmRrcSapProvider::LcsConfig> lcOnCcMapping =
1576  m_ccmRrcSapProvider->AddLc(dtamIt->logicalChannelIdentity,
1577  lcConfig,
1578  rlc->GetLteMacSapUser());
1579 
1580  NS_LOG_DEBUG("Size of lcOnCcMapping vector " << lcOnCcMapping.size());
1581  auto itLcOnCcMapping = lcOnCcMapping.begin();
1582  NS_ASSERT_MSG(itLcOnCcMapping != lcOnCcMapping.end(),
1583  "Component carrier manager failed to add LC for data radio bearer");
1584 
1585  for (itLcOnCcMapping = lcOnCcMapping.begin(); itLcOnCcMapping != lcOnCcMapping.end();
1586  ++itLcOnCcMapping)
1587  {
1588  NS_LOG_DEBUG("RNTI " << m_rnti << " LCG id "
1589  << (uint16_t)itLcOnCcMapping->lcConfig.logicalChannelGroup
1590  << " ComponentCarrierId "
1591  << (uint16_t)itLcOnCcMapping->componentCarrierId);
1592  uint8_t index = itLcOnCcMapping->componentCarrierId;
1594  itLcOnCcMapping->lcConfig;
1595  LteMacSapUser* msu = itLcOnCcMapping->msu;
1596  m_cmacSapProvider.at(index)->AddLc(dtamIt->logicalChannelIdentity,
1597  lcConfigFromCcm,
1598  msu);
1599  }
1600 
1601  rlc->Initialize();
1602  }
1603  else
1604  {
1605  NS_LOG_INFO("request to modify existing DRBID");
1606  Ptr<LteDataRadioBearerInfo> drbInfo = drbMapIt->second;
1609  }
1610  }
1611 
1612  for (auto dtdmIt = rrcd.drbToReleaseList.begin(); dtdmIt != rrcd.drbToReleaseList.end();
1613  ++dtdmIt)
1614  {
1615  uint8_t drbid = *dtdmIt;
1616  NS_LOG_INFO(this << " IMSI " << m_imsi << " releasing DRB " << (uint32_t)drbid);
1617  auto it = m_drbMap.find(drbid);
1618  NS_ASSERT_MSG(it != m_drbMap.end(), "could not find bearer with given lcid");
1619  m_drbMap.erase(it);
1620  m_bid2DrbidMap.erase(drbid);
1621  // Remove LCID
1622  for (uint32_t i = 0; i < m_numberOfComponentCarriers; i++)
1623  {
1624  m_cmacSapProvider.at(i)->RemoveLc(drbid + 2);
1625  }
1626  }
1627 }
1628 
1629 void
1631 {
1632  NS_LOG_FUNCTION(this);
1633 
1634  // perform the actions specified in 3GPP TS 36.331 section 5.5.2.1
1635 
1636  // 3GPP TS 36.331 section 5.5.2.4 Measurement object removal
1637  for (auto it = mc.measObjectToRemoveList.begin(); it != mc.measObjectToRemoveList.end(); ++it)
1638  {
1639  uint8_t measObjectId = *it;
1640  NS_LOG_LOGIC(this << " deleting measObjectId " << (uint32_t)measObjectId);
1641  m_varMeasConfig.measObjectList.erase(measObjectId);
1642  auto measIdIt = m_varMeasConfig.measIdList.begin();
1643  while (measIdIt != m_varMeasConfig.measIdList.end())
1644  {
1645  if (measIdIt->second.measObjectId == measObjectId)
1646  {
1647  uint8_t measId = measIdIt->second.measId;
1648  NS_ASSERT(measId == measIdIt->first);
1649  NS_LOG_LOGIC(this << " deleting measId " << (uint32_t)measId
1650  << " because referring to measObjectId "
1651  << (uint32_t)measObjectId);
1652  // note: postfix operator preserves iterator validity
1653  m_varMeasConfig.measIdList.erase(measIdIt++);
1654  VarMeasReportListClear(measId);
1655  }
1656  else
1657  {
1658  ++measIdIt;
1659  }
1660  }
1661  }
1662 
1663  // 3GPP TS 36.331 section 5.5.2.5 Measurement object addition/ modification
1664  for (auto it = mc.measObjectToAddModList.begin(); it != mc.measObjectToAddModList.end(); ++it)
1665  {
1666  // simplifying assumptions
1667  NS_ASSERT_MSG(it->measObjectEutra.cellsToRemoveList.empty(),
1668  "cellsToRemoveList not supported");
1669  NS_ASSERT_MSG(it->measObjectEutra.cellsToAddModList.empty(),
1670  "cellsToAddModList not supported");
1671  NS_ASSERT_MSG(it->measObjectEutra.cellsToRemoveList.empty(),
1672  "blackCellsToRemoveList not supported");
1673  NS_ASSERT_MSG(it->measObjectEutra.blackCellsToAddModList.empty(),
1674  "blackCellsToAddModList not supported");
1675  NS_ASSERT_MSG(it->measObjectEutra.haveCellForWhichToReportCGI == false,
1676  "cellForWhichToReportCGI is not supported");
1677 
1678  uint8_t measObjectId = it->measObjectId;
1679  auto measObjectIt = m_varMeasConfig.measObjectList.find(measObjectId);
1680  if (measObjectIt != m_varMeasConfig.measObjectList.end())
1681  {
1682  NS_LOG_LOGIC("measObjectId " << (uint32_t)measObjectId << " exists, updating entry");
1683  measObjectIt->second = *it;
1684  for (auto measIdIt = m_varMeasConfig.measIdList.begin();
1685  measIdIt != m_varMeasConfig.measIdList.end();
1686  ++measIdIt)
1687  {
1688  if (measIdIt->second.measObjectId == measObjectId)
1689  {
1690  uint8_t measId = measIdIt->second.measId;
1691  NS_LOG_LOGIC(this << " found measId " << (uint32_t)measId
1692  << " referring to measObjectId " << (uint32_t)measObjectId);
1693  VarMeasReportListClear(measId);
1694  }
1695  }
1696  }
1697  else
1698  {
1699  NS_LOG_LOGIC("measObjectId " << (uint32_t)measObjectId << " is new, adding entry");
1700  m_varMeasConfig.measObjectList[measObjectId] = *it;
1701  }
1702  }
1703 
1704  // 3GPP TS 36.331 section 5.5.2.6 Reporting configuration removal
1705  for (auto it = mc.reportConfigToRemoveList.begin(); it != mc.reportConfigToRemoveList.end();
1706  ++it)
1707  {
1708  uint8_t reportConfigId = *it;
1709  NS_LOG_LOGIC(this << " deleting reportConfigId " << (uint32_t)reportConfigId);
1710  m_varMeasConfig.reportConfigList.erase(reportConfigId);
1711  auto measIdIt = m_varMeasConfig.measIdList.begin();
1712  while (measIdIt != m_varMeasConfig.measIdList.end())
1713  {
1714  if (measIdIt->second.reportConfigId == reportConfigId)
1715  {
1716  uint8_t measId = measIdIt->second.measId;
1717  NS_ASSERT(measId == measIdIt->first);
1718  NS_LOG_LOGIC(this << " deleting measId " << (uint32_t)measId
1719  << " because referring to reportConfigId "
1720  << (uint32_t)reportConfigId);
1721  // note: postfix operator preserves iterator validity
1722  m_varMeasConfig.measIdList.erase(measIdIt++);
1723  VarMeasReportListClear(measId);
1724  }
1725  else
1726  {
1727  ++measIdIt;
1728  }
1729  }
1730  }
1731 
1732  // 3GPP TS 36.331 section 5.5.2.7 Reporting configuration addition/ modification
1733  for (auto it = mc.reportConfigToAddModList.begin(); it != mc.reportConfigToAddModList.end();
1734  ++it)
1735  {
1736  // simplifying assumptions
1737  NS_ASSERT_MSG(it->reportConfigEutra.triggerType == LteRrcSap::ReportConfigEutra::EVENT,
1738  "only trigger type EVENT is supported");
1739 
1740  uint8_t reportConfigId = it->reportConfigId;
1741  auto reportConfigIt = m_varMeasConfig.reportConfigList.find(reportConfigId);
1742  if (reportConfigIt != m_varMeasConfig.reportConfigList.end())
1743  {
1744  NS_LOG_LOGIC("reportConfigId " << (uint32_t)reportConfigId
1745  << " exists, updating entry");
1746  m_varMeasConfig.reportConfigList[reportConfigId] = *it;
1747  for (auto measIdIt = m_varMeasConfig.measIdList.begin();
1748  measIdIt != m_varMeasConfig.measIdList.end();
1749  ++measIdIt)
1750  {
1751  if (measIdIt->second.reportConfigId == reportConfigId)
1752  {
1753  uint8_t measId = measIdIt->second.measId;
1754  NS_LOG_LOGIC(this << " found measId " << (uint32_t)measId
1755  << " referring to reportConfigId "
1756  << (uint32_t)reportConfigId);
1757  VarMeasReportListClear(measId);
1758  }
1759  }
1760  }
1761  else
1762  {
1763  NS_LOG_LOGIC("reportConfigId " << (uint32_t)reportConfigId << " is new, adding entry");
1764  m_varMeasConfig.reportConfigList[reportConfigId] = *it;
1765  }
1766  }
1767 
1768  // 3GPP TS 36.331 section 5.5.2.8 Quantity configuration
1769  if (mc.haveQuantityConfig)
1770  {
1771  NS_LOG_LOGIC(this << " setting quantityConfig");
1773  // Convey the filter coefficient to PHY layer so it can configure the power control
1774  // parameter
1775  for (uint16_t i = 0; i < m_numberOfComponentCarriers; i++)
1776  {
1777  m_cphySapProvider.at(i)->SetRsrpFilterCoefficient(
1779  }
1780  // we calculate here the coefficient a used for Layer 3 filtering, see 3GPP TS 36.331
1781  // section 5.5.3.2
1782  m_varMeasConfig.aRsrp = std::pow(0.5, mc.quantityConfig.filterCoefficientRSRP / 4.0);
1783  m_varMeasConfig.aRsrq = std::pow(0.5, mc.quantityConfig.filterCoefficientRSRQ / 4.0);
1784  NS_LOG_LOGIC(this << " new filter coefficients: aRsrp=" << m_varMeasConfig.aRsrp
1785  << ", aRsrq=" << m_varMeasConfig.aRsrq);
1786 
1787  for (auto measIdIt = m_varMeasConfig.measIdList.begin();
1788  measIdIt != m_varMeasConfig.measIdList.end();
1789  ++measIdIt)
1790  {
1791  VarMeasReportListClear(measIdIt->second.measId);
1792  }
1793  }
1794 
1795  // 3GPP TS 36.331 section 5.5.2.2 Measurement identity removal
1796  for (auto it = mc.measIdToRemoveList.begin(); it != mc.measIdToRemoveList.end(); ++it)
1797  {
1798  uint8_t measId = *it;
1799  NS_LOG_LOGIC(this << " deleting measId " << (uint32_t)measId);
1800  m_varMeasConfig.measIdList.erase(measId);
1801  VarMeasReportListClear(measId);
1802 
1803  // removing time-to-trigger queues
1804  m_enteringTriggerQueue.erase(measId);
1805  m_leavingTriggerQueue.erase(measId);
1806  }
1807 
1808  // 3GPP TS 36.331 section 5.5.2.3 Measurement identity addition/ modification
1809  for (auto it = mc.measIdToAddModList.begin(); it != mc.measIdToAddModList.end(); ++it)
1810  {
1811  NS_LOG_LOGIC(this << " measId " << (uint32_t)it->measId
1812  << " (measObjectId=" << (uint32_t)it->measObjectId
1813  << ", reportConfigId=" << (uint32_t)it->reportConfigId << ")");
1814  NS_ASSERT(m_varMeasConfig.measObjectList.find(it->measObjectId) !=
1816  NS_ASSERT(m_varMeasConfig.reportConfigList.find(it->reportConfigId) !=
1818  m_varMeasConfig.measIdList[it->measId] = *it; // side effect: create new entry if not exists
1819  auto measReportIt = m_varMeasReportList.find(it->measId);
1820  if (measReportIt != m_varMeasReportList.end())
1821  {
1822  measReportIt->second.periodicReportTimer.Cancel();
1823  m_varMeasReportList.erase(measReportIt);
1824  }
1825  NS_ASSERT(m_varMeasConfig.reportConfigList.find(it->reportConfigId)
1826  ->second.reportConfigEutra.triggerType !=
1828 
1829  // new empty queues for time-to-trigger
1830  std::list<PendingTrigger_t> s;
1831  m_enteringTriggerQueue[it->measId] = s;
1832  m_leavingTriggerQueue[it->measId] = s;
1833  }
1834 
1835  if (mc.haveMeasGapConfig)
1836  {
1837  NS_FATAL_ERROR("measurement gaps are currently not supported");
1838  }
1839 
1840  if (mc.haveSmeasure)
1841  {
1842  NS_FATAL_ERROR("s-measure is currently not supported");
1843  }
1844 
1845  if (mc.haveSpeedStatePars)
1846  {
1847  NS_FATAL_ERROR("SpeedStatePars are currently not supported");
1848  }
1849 }
1850 
1851 void
1853  double rsrp,
1854  double rsrq,
1855  bool useLayer3Filtering,
1856  uint8_t componentCarrierId)
1857 {
1858  NS_LOG_FUNCTION(this << cellId << +componentCarrierId << rsrp << rsrq << useLayer3Filtering);
1859 
1860  auto storedMeasIt = m_storedMeasValues.find(cellId);
1861 
1862  if (storedMeasIt != m_storedMeasValues.end())
1863  {
1864  if (useLayer3Filtering)
1865  {
1866  // F_n = (1-a) F_{n-1} + a M_n
1867  storedMeasIt->second.rsrp = (1 - m_varMeasConfig.aRsrp) * storedMeasIt->second.rsrp +
1868  m_varMeasConfig.aRsrp * rsrp;
1869 
1870  if (std::isnan(storedMeasIt->second.rsrq))
1871  {
1872  // the previous RSRQ measurements provided UE PHY are invalid
1873  storedMeasIt->second.rsrq = rsrq; // replace it with unfiltered value
1874  }
1875  else
1876  {
1877  storedMeasIt->second.rsrq =
1878  (1 - m_varMeasConfig.aRsrq) * storedMeasIt->second.rsrq +
1879  m_varMeasConfig.aRsrq * rsrq;
1880  }
1881  }
1882  else
1883  {
1884  storedMeasIt->second.rsrp = rsrp;
1885  storedMeasIt->second.rsrq = rsrq;
1886  }
1887  }
1888  else
1889  {
1890  // first value is always unfiltered
1891  MeasValues v;
1892  v.rsrp = rsrp;
1893  v.rsrq = rsrq;
1894  v.carrierFreq = m_cphySapProvider.at(componentCarrierId)->GetDlEarfcn();
1895 
1896  std::pair<uint16_t, MeasValues> val(cellId, v);
1897  auto ret = m_storedMeasValues.insert(val);
1898  NS_ASSERT_MSG(ret.second == true, "element already existed");
1899  storedMeasIt = ret.first;
1900  }
1901 
1902  NS_LOG_DEBUG(this << " IMSI " << m_imsi << " state " << ToString(m_state) << ", measured cell "
1903  << cellId << ", carrier component Id " << componentCarrierId << ", new RSRP "
1904  << rsrp << " stored " << storedMeasIt->second.rsrp << ", new RSRQ " << rsrq
1905  << " stored " << storedMeasIt->second.rsrq);
1906 
1907 } // end of void SaveUeMeasurements
1908 
1909 void
1911 {
1912  NS_LOG_FUNCTION(this << (uint16_t)measId);
1913 
1914  auto measIdIt = m_varMeasConfig.measIdList.find(measId);
1915  NS_ASSERT(measIdIt != m_varMeasConfig.measIdList.end());
1916  NS_ASSERT(measIdIt->first == measIdIt->second.measId);
1917 
1918  auto reportConfigIt = m_varMeasConfig.reportConfigList.find(measIdIt->second.reportConfigId);
1919  NS_ASSERT(reportConfigIt != m_varMeasConfig.reportConfigList.end());
1920  LteRrcSap::ReportConfigEutra& reportConfigEutra = reportConfigIt->second.reportConfigEutra;
1921 
1922  auto measObjectIt = m_varMeasConfig.measObjectList.find(measIdIt->second.measObjectId);
1923  NS_ASSERT(measObjectIt != m_varMeasConfig.measObjectList.end());
1924  LteRrcSap::MeasObjectEutra& measObjectEutra = measObjectIt->second.measObjectEutra;
1925 
1926  auto measReportIt = m_varMeasReportList.find(measId);
1927  bool isMeasIdInReportList = (measReportIt != m_varMeasReportList.end());
1928 
1929  // we don't check the purpose field, as it is only included for
1930  // triggerType == periodical, which is not supported
1932  "only triggerType == event is supported");
1933  // only EUTRA is supported, no need to check for it
1934 
1935  NS_LOG_LOGIC(this << " considering measId " << (uint32_t)measId);
1936  bool eventEntryCondApplicable = false;
1937  bool eventLeavingCondApplicable = false;
1938  ConcernedCells_t concernedCellsEntry;
1939  ConcernedCells_t concernedCellsLeaving;
1940 
1941  /*
1942  * Find which serving cell corresponds to measObjectEutra.carrierFreq
1943  * It is used, for example, by A1 event:
1944  * See TS 36.331 5.5.4.2: "for this measurement, consider the primary or
1945  * secondary cell that is configured on the frequency indicated in the
1946  * associated measObjectEUTRA to be the serving cell"
1947  */
1948  uint16_t servingCellId = 0;
1949  for (auto cphySapProvider : m_cphySapProvider)
1950  {
1951  if (cphySapProvider->GetDlEarfcn() == measObjectEutra.carrierFreq)
1952  {
1953  servingCellId = cphySapProvider->GetCellId();
1954  }
1955  }
1956 
1957  if (servingCellId == 0)
1958  {
1959  return;
1960  }
1961 
1962  switch (reportConfigEutra.eventId)
1963  {
1965  /*
1966  * Event A1 (Serving becomes better than threshold)
1967  * Please refer to 3GPP TS 36.331 Section 5.5.4.2
1968  */
1969 
1970  double ms; // Ms, the measurement result of the serving cell
1971  double thresh; // Thresh, the threshold parameter for this event
1972  // Hys, the hysteresis parameter for this event.
1973  double hys =
1975 
1976  switch (reportConfigEutra.triggerQuantity)
1977  {
1979  ms = m_storedMeasValues[servingCellId].rsrp;
1980 
1981  NS_ASSERT(reportConfigEutra.threshold1.choice ==
1983  thresh = EutranMeasurementMapping::RsrpRange2Dbm(reportConfigEutra.threshold1.range);
1984  break;
1986  ms = m_storedMeasValues[servingCellId].rsrq;
1987  NS_ASSERT(reportConfigEutra.threshold1.choice ==
1989  thresh = EutranMeasurementMapping::RsrqRange2Db(reportConfigEutra.threshold1.range);
1990  break;
1991  default:
1992  NS_FATAL_ERROR("unsupported triggerQuantity");
1993  break;
1994  }
1995 
1996  // Inequality A1-1 (Entering condition): Ms - Hys > Thresh
1997  bool entryCond = ms - hys > thresh;
1998 
1999  if (entryCond)
2000  {
2001  if (!isMeasIdInReportList)
2002  {
2003  concernedCellsEntry.push_back(servingCellId);
2004  eventEntryCondApplicable = true;
2005  }
2006  else
2007  {
2008  /*
2009  * This is to check that the triggered cell recorded in the
2010  * VarMeasReportList is the serving cell.
2011  */
2012  NS_ASSERT(measReportIt->second.cellsTriggeredList.find(servingCellId) !=
2013  measReportIt->second.cellsTriggeredList.end());
2014  }
2015  }
2016  else if (reportConfigEutra.timeToTrigger > 0)
2017  {
2018  CancelEnteringTrigger(measId);
2019  }
2020 
2021  // Inequality A1-2 (Leaving condition): Ms + Hys < Thresh
2022  bool leavingCond = ms + hys < thresh;
2023 
2024  if (leavingCond)
2025  {
2026  if (isMeasIdInReportList)
2027  {
2028  /*
2029  * This is to check that the triggered cell recorded in the
2030  * VarMeasReportList is the serving cell.
2031  */
2032  NS_ASSERT(measReportIt->second.cellsTriggeredList.find(m_cellId) !=
2033  measReportIt->second.cellsTriggeredList.end());
2034  concernedCellsLeaving.push_back(m_cellId);
2035  eventLeavingCondApplicable = true;
2036  }
2037  }
2038  else if (reportConfigEutra.timeToTrigger > 0)
2039  {
2040  CancelLeavingTrigger(measId);
2041  }
2042 
2043  NS_LOG_LOGIC(this << " event A1: serving cell " << servingCellId << " ms=" << ms
2044  << " thresh=" << thresh << " entryCond=" << entryCond
2045  << " leavingCond=" << leavingCond);
2046 
2047  } // end of case LteRrcSap::ReportConfigEutra::EVENT_A1
2048 
2049  break;
2050 
2052  /*
2053  * Event A2 (Serving becomes worse than threshold)
2054  * Please refer to 3GPP TS 36.331 Section 5.5.4.3
2055  */
2056 
2057  double ms; // Ms, the measurement result of the serving cell
2058  double thresh; // Thresh, the threshold parameter for this event
2059  // Hys, the hysteresis parameter for this event.
2060  double hys =
2062 
2063  switch (reportConfigEutra.triggerQuantity)
2064  {
2066  ms = m_storedMeasValues[servingCellId].rsrp;
2067  NS_ASSERT(reportConfigEutra.threshold1.choice ==
2069  thresh = EutranMeasurementMapping::RsrpRange2Dbm(reportConfigEutra.threshold1.range);
2070  break;
2072  ms = m_storedMeasValues[servingCellId].rsrq;
2073  NS_ASSERT(reportConfigEutra.threshold1.choice ==
2075  thresh = EutranMeasurementMapping::RsrqRange2Db(reportConfigEutra.threshold1.range);
2076  break;
2077  default:
2078  NS_FATAL_ERROR("unsupported triggerQuantity");
2079  break;
2080  }
2081 
2082  // Inequality A2-1 (Entering condition): Ms + Hys < Thresh
2083  bool entryCond = ms + hys < thresh;
2084 
2085  if (entryCond)
2086  {
2087  if (!isMeasIdInReportList)
2088  {
2089  concernedCellsEntry.push_back(servingCellId);
2090  eventEntryCondApplicable = true;
2091  }
2092  else
2093  {
2094  /*
2095  * This is to check that the triggered cell recorded in the
2096  * VarMeasReportList is the serving cell.
2097  */
2098  NS_ASSERT(measReportIt->second.cellsTriggeredList.find(servingCellId) !=
2099  measReportIt->second.cellsTriggeredList.end());
2100  }
2101  }
2102  else if (reportConfigEutra.timeToTrigger > 0)
2103  {
2104  CancelEnteringTrigger(measId);
2105  }
2106 
2107  // Inequality A2-2 (Leaving condition): Ms - Hys > Thresh
2108  bool leavingCond = ms - hys > thresh;
2109 
2110  if (leavingCond)
2111  {
2112  if (isMeasIdInReportList)
2113  {
2114  /*
2115  * This is to check that the triggered cell recorded in the
2116  * VarMeasReportList is the serving cell.
2117  */
2118  NS_ASSERT(measReportIt->second.cellsTriggeredList.find(servingCellId) !=
2119  measReportIt->second.cellsTriggeredList.end());
2120  concernedCellsLeaving.push_back(servingCellId);
2121  eventLeavingCondApplicable = true;
2122  }
2123  }
2124  else if (reportConfigEutra.timeToTrigger > 0)
2125  {
2126  CancelLeavingTrigger(measId);
2127  }
2128 
2129  NS_LOG_LOGIC(this << " event A2: serving cell " << servingCellId << " ms=" << ms
2130  << " thresh=" << thresh << " entryCond=" << entryCond
2131  << " leavingCond=" << leavingCond);
2132 
2133  } // end of case LteRrcSap::ReportConfigEutra::EVENT_A2
2134 
2135  break;
2136 
2138  /*
2139  * Event A3 (Neighbour becomes offset better than PCell)
2140  * Please refer to 3GPP TS 36.331 Section 5.5.4.4
2141  */
2142 
2143  double mn; // Mn, the measurement result of the neighbouring cell
2144  double ofn = measObjectEutra
2145  .offsetFreq; // Ofn, the frequency specific offset of the frequency of the
2146  double ocn = 0.0; // Ocn, the cell specific offset of the neighbour cell
2147  double mp; // Mp, the measurement result of the PCell
2148  double ofp = measObjectEutra
2149  .offsetFreq; // Ofp, the frequency specific offset of the primary frequency
2150  double ocp = 0.0; // Ocp, the cell specific offset of the PCell
2151  // Off, the offset parameter for this event.
2152  double off = EutranMeasurementMapping::IeValue2ActualA3Offset(reportConfigEutra.a3Offset);
2153  // Hys, the hysteresis parameter for this event.
2154  double hys =
2156 
2157  switch (reportConfigEutra.triggerQuantity)
2158  {
2160  mp = m_storedMeasValues[m_cellId].rsrp;
2161  NS_ASSERT(reportConfigEutra.threshold1.choice ==
2163  break;
2165  mp = m_storedMeasValues[m_cellId].rsrq;
2166  NS_ASSERT(reportConfigEutra.threshold1.choice ==
2168  break;
2169  default:
2170  NS_FATAL_ERROR("unsupported triggerQuantity");
2171  break;
2172  }
2173 
2174  for (auto storedMeasIt = m_storedMeasValues.begin();
2175  storedMeasIt != m_storedMeasValues.end();
2176  ++storedMeasIt)
2177  {
2178  uint16_t cellId = storedMeasIt->first;
2179  if (cellId == m_cellId)
2180  {
2181  continue;
2182  }
2183 
2184  // Only cell(s) on the frequency indicated in the associated measObject can trigger
2185  // event.
2186  if (m_storedMeasValues.at(cellId).carrierFreq != measObjectEutra.carrierFreq)
2187  {
2188  continue;
2189  }
2190 
2191  switch (reportConfigEutra.triggerQuantity)
2192  {
2194  mn = storedMeasIt->second.rsrp;
2195  break;
2197  mn = storedMeasIt->second.rsrq;
2198  break;
2199  default:
2200  NS_FATAL_ERROR("unsupported triggerQuantity");
2201  break;
2202  }
2203 
2204  bool hasTriggered =
2205  isMeasIdInReportList && (measReportIt->second.cellsTriggeredList.find(cellId) !=
2206  measReportIt->second.cellsTriggeredList.end());
2207 
2208  // Inequality A3-1 (Entering condition): Mn + Ofn + Ocn - Hys > Mp + Ofp + Ocp + Off
2209  bool entryCond = mn + ofn + ocn - hys > mp + ofp + ocp + off;
2210 
2211  if (entryCond)
2212  {
2213  if (!hasTriggered)
2214  {
2215  concernedCellsEntry.push_back(cellId);
2216  eventEntryCondApplicable = true;
2217  }
2218  }
2219  else if (reportConfigEutra.timeToTrigger > 0)
2220  {
2221  CancelEnteringTrigger(measId, cellId);
2222  }
2223 
2224  // Inequality A3-2 (Leaving condition): Mn + Ofn + Ocn + Hys < Mp + Ofp + Ocp + Off
2225  bool leavingCond = mn + ofn + ocn + hys < mp + ofp + ocp + off;
2226 
2227  if (leavingCond)
2228  {
2229  if (hasTriggered)
2230  {
2231  concernedCellsLeaving.push_back(cellId);
2232  eventLeavingCondApplicable = true;
2233  }
2234  }
2235  else if (reportConfigEutra.timeToTrigger > 0)
2236  {
2237  CancelLeavingTrigger(measId, cellId);
2238  }
2239 
2240  NS_LOG_LOGIC(this << " event A3: neighbor cell " << cellId << " mn=" << mn
2241  << " mp=" << mp << " offset=" << off << " entryCond=" << entryCond
2242  << " leavingCond=" << leavingCond);
2243 
2244  } // end of for (storedMeasIt)
2245 
2246  } // end of case LteRrcSap::ReportConfigEutra::EVENT_A3
2247 
2248  break;
2249 
2251  /*
2252  * Event A4 (Neighbour becomes better than threshold)
2253  * Please refer to 3GPP TS 36.331 Section 5.5.4.5
2254  */
2255 
2256  double mn; // Mn, the measurement result of the neighbouring cell
2257  double ofn = measObjectEutra
2258  .offsetFreq; // Ofn, the frequency specific offset of the frequency of the
2259  double ocn = 0.0; // Ocn, the cell specific offset of the neighbour cell
2260  double thresh; // Thresh, the threshold parameter for this event
2261  // Hys, the hysteresis parameter for this event.
2262  double hys =
2264 
2265  switch (reportConfigEutra.triggerQuantity)
2266  {
2268  NS_ASSERT(reportConfigEutra.threshold1.choice ==
2270  thresh = EutranMeasurementMapping::RsrpRange2Dbm(reportConfigEutra.threshold1.range);
2271  break;
2273  NS_ASSERT(reportConfigEutra.threshold1.choice ==
2275  thresh = EutranMeasurementMapping::RsrqRange2Db(reportConfigEutra.threshold1.range);
2276  break;
2277  default:
2278  NS_FATAL_ERROR("unsupported triggerQuantity");
2279  break;
2280  }
2281 
2282  for (auto storedMeasIt = m_storedMeasValues.begin();
2283  storedMeasIt != m_storedMeasValues.end();
2284  ++storedMeasIt)
2285  {
2286  uint16_t cellId = storedMeasIt->first;
2287  if (cellId == m_cellId)
2288  {
2289  continue;
2290  }
2291 
2292  switch (reportConfigEutra.triggerQuantity)
2293  {
2295  mn = storedMeasIt->second.rsrp;
2296  break;
2298  mn = storedMeasIt->second.rsrq;
2299  break;
2300  default:
2301  NS_FATAL_ERROR("unsupported triggerQuantity");
2302  break;
2303  }
2304 
2305  bool hasTriggered =
2306  isMeasIdInReportList && (measReportIt->second.cellsTriggeredList.find(cellId) !=
2307  measReportIt->second.cellsTriggeredList.end());
2308 
2309  // Inequality A4-1 (Entering condition): Mn + Ofn + Ocn - Hys > Thresh
2310  bool entryCond = mn + ofn + ocn - hys > thresh;
2311 
2312  if (entryCond)
2313  {
2314  if (!hasTriggered)
2315  {
2316  concernedCellsEntry.push_back(cellId);
2317  eventEntryCondApplicable = true;
2318  }
2319  }
2320  else if (reportConfigEutra.timeToTrigger > 0)
2321  {
2322  CancelEnteringTrigger(measId, cellId);
2323  }
2324 
2325  // Inequality A4-2 (Leaving condition): Mn + Ofn + Ocn + Hys < Thresh
2326  bool leavingCond = mn + ofn + ocn + hys < thresh;
2327 
2328  if (leavingCond)
2329  {
2330  if (hasTriggered)
2331  {
2332  concernedCellsLeaving.push_back(cellId);
2333  eventLeavingCondApplicable = true;
2334  }
2335  }
2336  else if (reportConfigEutra.timeToTrigger > 0)
2337  {
2338  CancelLeavingTrigger(measId, cellId);
2339  }
2340 
2341  NS_LOG_LOGIC(this << " event A4: neighbor cell " << cellId << " mn=" << mn
2342  << " thresh=" << thresh << " entryCond=" << entryCond
2343  << " leavingCond=" << leavingCond);
2344 
2345  } // end of for (storedMeasIt)
2346 
2347  } // end of case LteRrcSap::ReportConfigEutra::EVENT_A4
2348 
2349  break;
2350 
2352  /*
2353  * Event A5 (PCell becomes worse than threshold1 and neighbour
2354  * becomes better than threshold2)
2355  * Please refer to 3GPP TS 36.331 Section 5.5.4.6
2356  */
2357 
2358  double mp; // Mp, the measurement result of the PCell
2359  double mn; // Mn, the measurement result of the neighbouring cell
2360  double ofn = measObjectEutra
2361  .offsetFreq; // Ofn, the frequency specific offset of the frequency of the
2362  double ocn = 0.0; // Ocn, the cell specific offset of the neighbour cell
2363  double thresh1; // Thresh1, the threshold parameter for this event
2364  double thresh2; // Thresh2, the threshold parameter for this event
2365  // Hys, the hysteresis parameter for this event.
2366  double hys =
2368 
2369  switch (reportConfigEutra.triggerQuantity)
2370  {
2372  mp = m_storedMeasValues[m_cellId].rsrp;
2373  NS_ASSERT(reportConfigEutra.threshold1.choice ==
2375  NS_ASSERT(reportConfigEutra.threshold2.choice ==
2377  thresh1 = EutranMeasurementMapping::RsrpRange2Dbm(reportConfigEutra.threshold1.range);
2378  thresh2 = EutranMeasurementMapping::RsrpRange2Dbm(reportConfigEutra.threshold2.range);
2379  break;
2381  mp = m_storedMeasValues[m_cellId].rsrq;
2382  NS_ASSERT(reportConfigEutra.threshold1.choice ==
2384  NS_ASSERT(reportConfigEutra.threshold2.choice ==
2386  thresh1 = EutranMeasurementMapping::RsrqRange2Db(reportConfigEutra.threshold1.range);
2387  thresh2 = EutranMeasurementMapping::RsrqRange2Db(reportConfigEutra.threshold2.range);
2388  break;
2389  default:
2390  NS_FATAL_ERROR("unsupported triggerQuantity");
2391  break;
2392  }
2393 
2394  // Inequality A5-1 (Entering condition 1): Mp + Hys < Thresh1
2395  bool entryCond = mp + hys < thresh1;
2396 
2397  if (entryCond)
2398  {
2399  for (auto storedMeasIt = m_storedMeasValues.begin();
2400  storedMeasIt != m_storedMeasValues.end();
2401  ++storedMeasIt)
2402  {
2403  uint16_t cellId = storedMeasIt->first;
2404  if (cellId == m_cellId)
2405  {
2406  continue;
2407  }
2408 
2409  switch (reportConfigEutra.triggerQuantity)
2410  {
2412  mn = storedMeasIt->second.rsrp;
2413  break;
2415  mn = storedMeasIt->second.rsrq;
2416  break;
2417  default:
2418  NS_FATAL_ERROR("unsupported triggerQuantity");
2419  break;
2420  }
2421 
2422  bool hasTriggered =
2423  isMeasIdInReportList && (measReportIt->second.cellsTriggeredList.find(cellId) !=
2424  measReportIt->second.cellsTriggeredList.end());
2425 
2426  // Inequality A5-2 (Entering condition 2): Mn + Ofn + Ocn - Hys > Thresh2
2427 
2428  entryCond = mn + ofn + ocn - hys > thresh2;
2429 
2430  if (entryCond)
2431  {
2432  if (!hasTriggered)
2433  {
2434  concernedCellsEntry.push_back(cellId);
2435  eventEntryCondApplicable = true;
2436  }
2437  }
2438  else if (reportConfigEutra.timeToTrigger > 0)
2439  {
2440  CancelEnteringTrigger(measId, cellId);
2441  }
2442 
2443  NS_LOG_LOGIC(this << " event A5: neighbor cell " << cellId << " mn=" << mn
2444  << " mp=" << mp << " thresh2=" << thresh2
2445  << " thresh1=" << thresh1 << " entryCond=" << entryCond);
2446 
2447  } // end of for (storedMeasIt)
2448 
2449  } // end of if (entryCond)
2450  else
2451  {
2452  NS_LOG_LOGIC(this << " event A5: serving cell " << m_cellId << " mp=" << mp
2453  << " thresh1=" << thresh1 << " entryCond=" << entryCond);
2454 
2455  if (reportConfigEutra.timeToTrigger > 0)
2456  {
2457  CancelEnteringTrigger(measId);
2458  }
2459  }
2460 
2461  if (isMeasIdInReportList)
2462  {
2463  // Inequality A5-3 (Leaving condition 1): Mp - Hys > Thresh1
2464  bool leavingCond = mp - hys > thresh1;
2465 
2466  if (leavingCond)
2467  {
2468  if (reportConfigEutra.timeToTrigger == 0)
2469  {
2470  // leaving condition #2 does not have to be checked
2471 
2472  for (auto storedMeasIt = m_storedMeasValues.begin();
2473  storedMeasIt != m_storedMeasValues.end();
2474  ++storedMeasIt)
2475  {
2476  uint16_t cellId = storedMeasIt->first;
2477  if (cellId == m_cellId)
2478  {
2479  continue;
2480  }
2481 
2482  if (measReportIt->second.cellsTriggeredList.find(cellId) !=
2483  measReportIt->second.cellsTriggeredList.end())
2484  {
2485  concernedCellsLeaving.push_back(cellId);
2486  eventLeavingCondApplicable = true;
2487  }
2488  }
2489  } // end of if (reportConfigEutra.timeToTrigger == 0)
2490  else
2491  {
2492  // leaving condition #2 has to be checked to cancel time-to-trigger
2493 
2494  for (auto storedMeasIt = m_storedMeasValues.begin();
2495  storedMeasIt != m_storedMeasValues.end();
2496  ++storedMeasIt)
2497  {
2498  uint16_t cellId = storedMeasIt->first;
2499  if (cellId == m_cellId)
2500  {
2501  continue;
2502  }
2503 
2504  if (measReportIt->second.cellsTriggeredList.find(cellId) !=
2505  measReportIt->second.cellsTriggeredList.end())
2506  {
2507  switch (reportConfigEutra.triggerQuantity)
2508  {
2510  mn = storedMeasIt->second.rsrp;
2511  break;
2513  mn = storedMeasIt->second.rsrq;
2514  break;
2515  default:
2516  NS_FATAL_ERROR("unsupported triggerQuantity");
2517  break;
2518  }
2519 
2520  // Inequality A5-4 (Leaving condition 2): Mn + Ofn + Ocn + Hys < Thresh2
2521 
2522  leavingCond = mn + ofn + ocn + hys < thresh2;
2523 
2524  if (!leavingCond)
2525  {
2526  CancelLeavingTrigger(measId, cellId);
2527  }
2528 
2529  /*
2530  * Whatever the result of leaving condition #2, this
2531  * cell is still "in", because leaving condition #1
2532  * is already true.
2533  */
2534  concernedCellsLeaving.push_back(cellId);
2535  eventLeavingCondApplicable = true;
2536 
2537  NS_LOG_LOGIC(this << " event A5: neighbor cell " << cellId
2538  << " mn=" << mn << " mp=" << mp
2539  << " thresh2=" << thresh2 << " thresh1=" << thresh1
2540  << " leavingCond=" << leavingCond);
2541 
2542  } // end of if (measReportIt->second.cellsTriggeredList.find (cellId)
2543  // != measReportIt->second.cellsTriggeredList.end ())
2544 
2545  } // end of for (storedMeasIt)
2546 
2547  } // end of else of if (reportConfigEutra.timeToTrigger == 0)
2548 
2549  NS_LOG_LOGIC(this << " event A5: serving cell " << m_cellId << " mp=" << mp
2550  << " thresh1=" << thresh1 << " leavingCond=" << leavingCond);
2551 
2552  } // end of if (leavingCond)
2553  else
2554  {
2555  if (reportConfigEutra.timeToTrigger > 0)
2556  {
2557  CancelLeavingTrigger(measId);
2558  }
2559 
2560  // check leaving condition #2
2561 
2562  for (auto storedMeasIt = m_storedMeasValues.begin();
2563  storedMeasIt != m_storedMeasValues.end();
2564  ++storedMeasIt)
2565  {
2566  uint16_t cellId = storedMeasIt->first;
2567  if (cellId == m_cellId)
2568  {
2569  continue;
2570  }
2571 
2572  if (measReportIt->second.cellsTriggeredList.find(cellId) !=
2573  measReportIt->second.cellsTriggeredList.end())
2574  {
2575  switch (reportConfigEutra.triggerQuantity)
2576  {
2578  mn = storedMeasIt->second.rsrp;
2579  break;
2581  mn = storedMeasIt->second.rsrq;
2582  break;
2583  default:
2584  NS_FATAL_ERROR("unsupported triggerQuantity");
2585  break;
2586  }
2587 
2588  // Inequality A5-4 (Leaving condition 2): Mn + Ofn + Ocn + Hys < Thresh2
2589  leavingCond = mn + ofn + ocn + hys < thresh2;
2590 
2591  if (leavingCond)
2592  {
2593  concernedCellsLeaving.push_back(cellId);
2594  eventLeavingCondApplicable = true;
2595  }
2596 
2597  NS_LOG_LOGIC(this << " event A5: neighbor cell " << cellId << " mn=" << mn
2598  << " mp=" << mp << " thresh2=" << thresh2 << " thresh1="
2599  << thresh1 << " leavingCond=" << leavingCond);
2600 
2601  } // end of if (measReportIt->second.cellsTriggeredList.find (cellId)
2602  // != measReportIt->second.cellsTriggeredList.end ())
2603 
2604  } // end of for (storedMeasIt)
2605 
2606  } // end of else of if (leavingCond)
2607 
2608  } // end of if (isMeasIdInReportList)
2609 
2610  } // end of case LteRrcSap::ReportConfigEutra::EVENT_A5
2611 
2612  break;
2613 
2614  default:
2615  NS_FATAL_ERROR("unsupported eventId " << reportConfigEutra.eventId);
2616  break;
2617 
2618  } // switch (event type)
2619 
2620  NS_LOG_LOGIC(this << " eventEntryCondApplicable=" << eventEntryCondApplicable
2621  << " eventLeavingCondApplicable=" << eventLeavingCondApplicable);
2622 
2623  if (eventEntryCondApplicable)
2624  {
2625  if (reportConfigEutra.timeToTrigger == 0)
2626  {
2627  VarMeasReportListAdd(measId, concernedCellsEntry);
2628  }
2629  else
2630  {
2631  PendingTrigger_t t;
2632  t.measId = measId;
2633  t.concernedCells = concernedCellsEntry;
2634  t.timer = Simulator::Schedule(MilliSeconds(reportConfigEutra.timeToTrigger),
2636  this,
2637  measId,
2638  concernedCellsEntry);
2639  auto enteringTriggerIt = m_enteringTriggerQueue.find(measId);
2640  NS_ASSERT(enteringTriggerIt != m_enteringTriggerQueue.end());
2641  enteringTriggerIt->second.push_back(t);
2642  }
2643  }
2644 
2645  if (eventLeavingCondApplicable)
2646  {
2647  // reportOnLeave will only be set when eventId = eventA3
2648  bool reportOnLeave =
2649  (reportConfigEutra.eventId == LteRrcSap::ReportConfigEutra::EVENT_A3) &&
2650  reportConfigEutra.reportOnLeave;
2651 
2652  if (reportConfigEutra.timeToTrigger == 0)
2653  {
2654  VarMeasReportListErase(measId, concernedCellsLeaving, reportOnLeave);
2655  }
2656  else
2657  {
2658  PendingTrigger_t t;
2659  t.measId = measId;
2660  t.concernedCells = concernedCellsLeaving;
2661  t.timer = Simulator::Schedule(MilliSeconds(reportConfigEutra.timeToTrigger),
2663  this,
2664  measId,
2665  concernedCellsLeaving,
2666  reportOnLeave);
2667  auto leavingTriggerIt = m_leavingTriggerQueue.find(measId);
2668  NS_ASSERT(leavingTriggerIt != m_leavingTriggerQueue.end());
2669  leavingTriggerIt->second.push_back(t);
2670  }
2671  }
2672 
2673 } // end of void LteUeRrc::MeasurementReportTriggering (uint8_t measId)
2674 
2675 void
2677 {
2678  NS_LOG_FUNCTION(this << (uint16_t)measId);
2679 
2680  auto it1 = m_enteringTriggerQueue.find(measId);
2681  NS_ASSERT(it1 != m_enteringTriggerQueue.end());
2682 
2683  if (!it1->second.empty())
2684  {
2685  for (auto it2 = it1->second.begin(); it2 != it1->second.end(); ++it2)
2686  {
2687  NS_ASSERT(it2->measId == measId);
2688  NS_LOG_LOGIC(this << " canceling entering time-to-trigger event at "
2689  << Simulator::GetDelayLeft(it2->timer).GetSeconds());
2690  Simulator::Cancel(it2->timer);
2691  }
2692 
2693  it1->second.clear();
2694  }
2695 }
2696 
2697 void
2698 LteUeRrc::CancelEnteringTrigger(uint8_t measId, uint16_t cellId)
2699 {
2700  NS_LOG_FUNCTION(this << (uint16_t)measId << cellId);
2701 
2702  auto it1 = m_enteringTriggerQueue.find(measId);
2703  NS_ASSERT(it1 != m_enteringTriggerQueue.end());
2704 
2705  auto it2 = it1->second.begin();
2706  while (it2 != it1->second.end())
2707  {
2708  NS_ASSERT(it2->measId == measId);
2709 
2710  for (auto it3 = it2->concernedCells.begin(); it3 != it2->concernedCells.end(); ++it3)
2711  {
2712  if (*it3 == cellId)
2713  {
2714  it3 = it2->concernedCells.erase(it3);
2715  }
2716  }
2717 
2718  if (it2->concernedCells.empty())
2719  {
2720  NS_LOG_LOGIC(this << " canceling entering time-to-trigger event at "
2721  << Simulator::GetDelayLeft(it2->timer).GetSeconds());
2722  Simulator::Cancel(it2->timer);
2723  it2 = it1->second.erase(it2);
2724  }
2725  else
2726  {
2727  it2++;
2728  }
2729  }
2730 }
2731 
2732 void
2734 {
2735  NS_LOG_FUNCTION(this << (uint16_t)measId);
2736 
2737  auto it1 = m_leavingTriggerQueue.find(measId);
2738  NS_ASSERT(it1 != m_leavingTriggerQueue.end());
2739 
2740  if (!it1->second.empty())
2741  {
2742  for (auto it2 = it1->second.begin(); it2 != it1->second.end(); ++it2)
2743  {
2744  NS_ASSERT(it2->measId == measId);
2745  NS_LOG_LOGIC(this << " canceling leaving time-to-trigger event at "
2746  << Simulator::GetDelayLeft(it2->timer).GetSeconds());
2747  Simulator::Cancel(it2->timer);
2748  }
2749 
2750  it1->second.clear();
2751  }
2752 }
2753 
2754 void
2755 LteUeRrc::CancelLeavingTrigger(uint8_t measId, uint16_t cellId)
2756 {
2757  NS_LOG_FUNCTION(this << (uint16_t)measId << cellId);
2758 
2759  auto it1 = m_leavingTriggerQueue.find(measId);
2760  NS_ASSERT(it1 != m_leavingTriggerQueue.end());
2761 
2762  auto it2 = it1->second.begin();
2763  while (it2 != it1->second.end())
2764  {
2765  NS_ASSERT(it2->measId == measId);
2766 
2767  for (auto it3 = it2->concernedCells.begin(); it3 != it2->concernedCells.end(); ++it3)
2768  {
2769  if (*it3 == cellId)
2770  {
2771  it3 = it2->concernedCells.erase(it3);
2772  }
2773  }
2774 
2775  if (it2->concernedCells.empty())
2776  {
2777  NS_LOG_LOGIC(this << " canceling leaving time-to-trigger event at "
2778  << Simulator::GetDelayLeft(it2->timer).GetSeconds());
2779  Simulator::Cancel(it2->timer);
2780  it2 = it1->second.erase(it2);
2781  }
2782  else
2783  {
2784  it2++;
2785  }
2786  }
2787 }
2788 
2789 void
2790 LteUeRrc::VarMeasReportListAdd(uint8_t measId, ConcernedCells_t enteringCells)
2791 {
2792  NS_LOG_FUNCTION(this << (uint16_t)measId);
2793  NS_ASSERT(!enteringCells.empty());
2794 
2795  auto measReportIt = m_varMeasReportList.find(measId);
2796 
2797  if (measReportIt == m_varMeasReportList.end())
2798  {
2799  VarMeasReport r;
2800  r.measId = measId;
2801  std::pair<uint8_t, VarMeasReport> val(measId, r);
2802  auto ret = m_varMeasReportList.insert(val);
2803  NS_ASSERT_MSG(ret.second == true, "element already existed");
2804  measReportIt = ret.first;
2805  }
2806 
2807  NS_ASSERT(measReportIt != m_varMeasReportList.end());
2808 
2809  for (auto it = enteringCells.begin(); it != enteringCells.end(); ++it)
2810  {
2811  measReportIt->second.cellsTriggeredList.insert(*it);
2812  }
2813 
2814  NS_ASSERT(!measReportIt->second.cellsTriggeredList.empty());
2815 
2816  // #issue 224, schedule only when there is no periodic event scheduled already
2817  if (!measReportIt->second.periodicReportTimer.IsRunning())
2818  {
2819  measReportIt->second.numberOfReportsSent = 0;
2820  measReportIt->second.periodicReportTimer =
2823  this,
2824  measId);
2825  }
2826 
2827  auto enteringTriggerIt = m_enteringTriggerQueue.find(measId);
2828  NS_ASSERT(enteringTriggerIt != m_enteringTriggerQueue.end());
2829  if (!enteringTriggerIt->second.empty())
2830  {
2831  /*
2832  * Assumptions at this point:
2833  * - the call to this function was delayed by time-to-trigger;
2834  * - the time-to-trigger delay is fixed (not adaptive/dynamic); and
2835  * - the first element in the list is associated with this function call.
2836  */
2837  enteringTriggerIt->second.pop_front();
2838 
2839  if (!enteringTriggerIt->second.empty())
2840  {
2841  /*
2842  * To prevent the same set of cells triggering again in the future,
2843  * we clean up the time-to-trigger queue. This case might occur when
2844  * time-to-trigger > 200 ms.
2845  */
2846  for (auto it = enteringCells.begin(); it != enteringCells.end(); ++it)
2847  {
2848  CancelEnteringTrigger(measId, *it);
2849  }
2850  }
2851 
2852  } // end of if (!enteringTriggerIt->second.empty ())
2853 
2854 } // end of LteUeRrc::VarMeasReportListAdd
2855 
2856 void
2857 LteUeRrc::VarMeasReportListErase(uint8_t measId, ConcernedCells_t leavingCells, bool reportOnLeave)
2858 {
2859  NS_LOG_FUNCTION(this << (uint16_t)measId);
2860  NS_ASSERT(!leavingCells.empty());
2861 
2862  auto measReportIt = m_varMeasReportList.find(measId);
2863  NS_ASSERT(measReportIt != m_varMeasReportList.end());
2864 
2865  for (auto it = leavingCells.begin(); it != leavingCells.end(); ++it)
2866  {
2867  measReportIt->second.cellsTriggeredList.erase(*it);
2868  }
2869 
2870  if (reportOnLeave)
2871  {
2872  // runs immediately without UE_MEASUREMENT_REPORT_DELAY
2873  SendMeasurementReport(measId);
2874  }
2875 
2876  if (measReportIt->second.cellsTriggeredList.empty())
2877  {
2878  measReportIt->second.periodicReportTimer.Cancel();
2879  m_varMeasReportList.erase(measReportIt);
2880  }
2881 
2882  auto leavingTriggerIt = m_leavingTriggerQueue.find(measId);
2883  NS_ASSERT(leavingTriggerIt != m_leavingTriggerQueue.end());
2884  if (!leavingTriggerIt->second.empty())
2885  {
2886  /*
2887  * Assumptions at this point:
2888  * - the call to this function was delayed by time-to-trigger; and
2889  * - the time-to-trigger delay is fixed (not adaptive/dynamic); and
2890  * - the first element in the list is associated with this function call.
2891  */
2892  leavingTriggerIt->second.pop_front();
2893 
2894  if (!leavingTriggerIt->second.empty())
2895  {
2896  /*
2897  * To prevent the same set of cells triggering again in the future,
2898  * we clean up the time-to-trigger queue. This case might occur when
2899  * time-to-trigger > 200 ms.
2900  */
2901  for (auto it = leavingCells.begin(); it != leavingCells.end(); ++it)
2902  {
2903  CancelLeavingTrigger(measId, *it);
2904  }
2905  }
2906 
2907  } // end of if (!leavingTriggerIt->second.empty ())
2908 
2909 } // end of LteUeRrc::VarMeasReportListErase
2910 
2911 void
2913 {
2914  NS_LOG_FUNCTION(this << (uint16_t)measId);
2915 
2916  // remove the measurement reporting entry for this measId from the VarMeasReportList
2917  auto measReportIt = m_varMeasReportList.find(measId);
2918  if (measReportIt != m_varMeasReportList.end())
2919  {
2920  NS_LOG_LOGIC(this << " deleting existing report for measId " << (uint16_t)measId);
2921  measReportIt->second.periodicReportTimer.Cancel();
2922  m_varMeasReportList.erase(measReportIt);
2923  }
2924 
2925  CancelEnteringTrigger(measId);
2926  CancelLeavingTrigger(measId);
2927 }
2928 
2929 void
2931 {
2932  NS_LOG_FUNCTION(this << (uint16_t)measId);
2933  // 3GPP TS 36.331 section 5.5.5 Measurement reporting
2934 
2935  auto measIdIt = m_varMeasConfig.measIdList.find(measId);
2936  NS_ASSERT(measIdIt != m_varMeasConfig.measIdList.end());
2937 
2938  auto reportConfigIt = m_varMeasConfig.reportConfigList.find(measIdIt->second.reportConfigId);
2939  NS_ASSERT(reportConfigIt != m_varMeasConfig.reportConfigList.end());
2940  LteRrcSap::ReportConfigEutra& reportConfigEutra = reportConfigIt->second.reportConfigEutra;
2941 
2942  LteRrcSap::MeasurementReport measurementReport;
2943  LteRrcSap::MeasResults& measResults = measurementReport.measResults;
2944  measResults.measId = measId;
2945 
2946  auto measReportIt = m_varMeasReportList.find(measId);
2947  if (measReportIt == m_varMeasReportList.end())
2948  {
2949  NS_LOG_ERROR("no entry found in m_varMeasReportList for measId " << (uint32_t)measId);
2950  }
2951  else
2952  {
2953  auto servingMeasIt = m_storedMeasValues.find(m_cellId);
2954  NS_ASSERT(servingMeasIt != m_storedMeasValues.end());
2955  measResults.measResultPCell.rsrpResult =
2956  EutranMeasurementMapping::Dbm2RsrpRange(servingMeasIt->second.rsrp);
2957  measResults.measResultPCell.rsrqResult =
2958  EutranMeasurementMapping::Db2RsrqRange(servingMeasIt->second.rsrq);
2959  NS_LOG_INFO(this << " reporting serving cell "
2960  "RSRP "
2961  << +measResults.measResultPCell.rsrpResult << " ("
2962  << servingMeasIt->second.rsrp
2963  << " dBm) "
2964  "RSRQ "
2965  << +measResults.measResultPCell.rsrqResult << " ("
2966  << servingMeasIt->second.rsrq << " dB)");
2967 
2968  measResults.haveMeasResultServFreqList = false;
2969  for (uint16_t componentCarrierId = 1; componentCarrierId < m_numberOfComponentCarriers;
2970  componentCarrierId++)
2971  {
2972  const uint16_t cellId = m_cphySapProvider.at(componentCarrierId)->GetCellId();
2973  auto measValuesIt = m_storedMeasValues.find(cellId);
2974  if (measValuesIt != m_storedMeasValues.end())
2975  {
2976  measResults.haveMeasResultServFreqList = true;
2977  LteRrcSap::MeasResultServFreq measResultServFreq;
2978  measResultServFreq.servFreqId = componentCarrierId;
2979  measResultServFreq.haveMeasResultSCell = true;
2980  measResultServFreq.measResultSCell.rsrpResult =
2981  EutranMeasurementMapping::Dbm2RsrpRange(measValuesIt->second.rsrp);
2982  measResultServFreq.measResultSCell.rsrqResult =
2983  EutranMeasurementMapping::Db2RsrqRange(measValuesIt->second.rsrq);
2984  measResultServFreq.haveMeasResultBestNeighCell = false;
2985  measResults.measResultServFreqList.push_back(measResultServFreq);
2986  }
2987  }
2988 
2989  measResults.haveMeasResultNeighCells = false;
2990 
2991  if (!(measReportIt->second.cellsTriggeredList.empty()))
2992  {
2993  std::multimap<double, uint16_t> sortedNeighCells;
2994  for (auto cellsTriggeredIt = measReportIt->second.cellsTriggeredList.begin();
2995  cellsTriggeredIt != measReportIt->second.cellsTriggeredList.end();
2996  ++cellsTriggeredIt)
2997  {
2998  uint16_t cellId = *cellsTriggeredIt;
2999  if (cellId != m_cellId)
3000  {
3001  auto neighborMeasIt = m_storedMeasValues.find(cellId);
3002  double triggerValue;
3003  switch (reportConfigEutra.triggerQuantity)
3004  {
3006  triggerValue = neighborMeasIt->second.rsrp;
3007  break;
3009  triggerValue = neighborMeasIt->second.rsrq;
3010  break;
3011  default:
3012  NS_FATAL_ERROR("unsupported triggerQuantity");
3013  break;
3014  }
3015  sortedNeighCells.insert(std::pair<double, uint16_t>(triggerValue, cellId));
3016  }
3017  }
3018 
3019  std::multimap<double, uint16_t>::reverse_iterator sortedNeighCellsIt;
3020  uint32_t count;
3021  for (sortedNeighCellsIt = sortedNeighCells.rbegin(), count = 0;
3022  sortedNeighCellsIt != sortedNeighCells.rend() &&
3023  count < reportConfigEutra.maxReportCells;
3024  ++sortedNeighCellsIt, ++count)
3025  {
3026  uint16_t cellId = sortedNeighCellsIt->second;
3027  auto neighborMeasIt = m_storedMeasValues.find(cellId);
3028  NS_ASSERT(neighborMeasIt != m_storedMeasValues.end());
3029  LteRrcSap::MeasResultEutra measResultEutra;
3030  measResultEutra.physCellId = cellId;
3031  measResultEutra.haveCgiInfo = false;
3032  measResultEutra.haveRsrpResult = true;
3033  measResultEutra.rsrpResult =
3034  EutranMeasurementMapping::Dbm2RsrpRange(neighborMeasIt->second.rsrp);
3035  measResultEutra.haveRsrqResult = true;
3036  measResultEutra.rsrqResult =
3037  EutranMeasurementMapping::Db2RsrqRange(neighborMeasIt->second.rsrq);
3038  NS_LOG_INFO(this << " reporting neighbor cell "
3039  << (uint32_t)measResultEutra.physCellId << " RSRP "
3040  << (uint32_t)measResultEutra.rsrpResult << " ("
3041  << neighborMeasIt->second.rsrp << " dBm)"
3042  << " RSRQ " << (uint32_t)measResultEutra.rsrqResult << " ("
3043  << neighborMeasIt->second.rsrq << " dB)");
3044  measResults.measResultListEutra.push_back(measResultEutra);
3045  measResults.haveMeasResultNeighCells = true;
3046  }
3047  }
3048  else
3049  {
3050  NS_LOG_WARN(this << " cellsTriggeredList is empty");
3051  }
3052 
3053  /*
3054  * The current LteRrcSap implementation is broken in that it does not
3055  * allow for infinite values of reportAmount, which is probably the most
3056  * reasonable setting. So we just always assume infinite reportAmount.
3057  */
3058  measReportIt->second.numberOfReportsSent++;
3059  measReportIt->second.periodicReportTimer.Cancel();
3060 
3061  Time reportInterval;
3062  switch (reportConfigEutra.reportInterval)
3063  {
3065  reportInterval = MilliSeconds(120);
3066  break;
3068  reportInterval = MilliSeconds(240);
3069  break;
3071  reportInterval = MilliSeconds(480);
3072  break;
3074  reportInterval = MilliSeconds(640);
3075  break;
3077  reportInterval = MilliSeconds(1024);
3078  break;
3080  reportInterval = MilliSeconds(2048);
3081  break;
3083  reportInterval = MilliSeconds(5120);
3084  break;
3086  reportInterval = MilliSeconds(10240);
3087  break;
3089  reportInterval = Seconds(60);
3090  break;
3092  reportInterval = Seconds(360);
3093  break;
3095  reportInterval = Seconds(720);
3096  break;
3098  reportInterval = Seconds(1800);
3099  break;
3101  reportInterval = Seconds(3600);
3102  break;
3103  default:
3104  NS_FATAL_ERROR("Unsupported reportInterval "
3105  << (uint16_t)reportConfigEutra.reportInterval);
3106  break;
3107  }
3108 
3109  // schedule the next measurement reporting
3110  measReportIt->second.periodicReportTimer =
3111  Simulator::Schedule(reportInterval, &LteUeRrc::SendMeasurementReport, this, measId);
3112 
3113  // send the measurement report to eNodeB
3114  m_rrcSapUser->SendMeasurementReport(measurementReport);
3115  }
3116 }
3117 
3118 void
3120 {
3121  NS_LOG_FUNCTION(this << m_imsi);
3124  m_connectionPending = false; // reset the flag
3126  m_cmacSapProvider.at(0)->StartContentionBasedRandomAccessProcedure();
3127 }
3128 
3129 void
3131 {
3132  NS_LOG_FUNCTION(this << m_imsi);
3133  m_leaveConnectedMode = true;
3134  m_storedMeasValues.clear();
3135  ResetRlfParams();
3136 
3137  for (auto measIdIt = m_varMeasConfig.measIdList.begin();
3138  measIdIt != m_varMeasConfig.measIdList.end();
3139  ++measIdIt)
3140  {
3141  VarMeasReportListClear(measIdIt->second.measId);
3142  }
3143  m_varMeasConfig.measIdList.clear();
3144 
3146 
3147  for (uint32_t i = 0; i < m_numberOfComponentCarriers; i++)
3148  {
3149  m_cmacSapProvider.at(i)->Reset(); // reset the MAC
3150  }
3151 
3152  m_drbMap.clear();
3153  m_bid2DrbidMap.clear();
3154  m_srb1 = nullptr;
3155  m_hasReceivedMib = false;
3156  m_hasReceivedSib1 = false;
3157  m_hasReceivedSib2 = false;
3158 
3159  for (uint32_t i = 0; i < m_numberOfComponentCarriers; i++)
3160  {
3161  m_cphySapProvider.at(i)->ResetPhyAfterRlf(); // reset the PHY
3162  }
3165  // Save the cell id UE was attached to
3167  m_cellId = 0;
3168  m_rnti = 0;
3169  m_srb0->m_rlc->SetRnti(m_rnti);
3170 }
3171 
3172 void
3174 {
3175  NS_LOG_FUNCTION(this << m_imsi);
3178  {
3181  // Assumption: The eNB connection request timer would expire
3182  // before the expiration of T300 at UE. Upon which, the eNB deletes
3183  // the UE context. Therefore, here we don't need to send the UE context
3184  // deletion request to the eNB.
3186  m_connEstFailCount = 0;
3187  }
3188  else
3189  {
3190  for (uint16_t i = 0; i < m_numberOfComponentCarriers; i++)
3191  {
3192  m_cmacSapProvider.at(i)->Reset(); // reset the MAC
3193  }
3194  m_hasReceivedSib2 = false; // invalidate the previously received SIB2
3197  // Following call to UE NAS will force the UE to immediately
3198  // perform the random access to the same cell again.
3199  m_asSapUser->NotifyConnectionFailed(); // inform upper layer
3200  }
3201 }
3202 
3203 void
3205 {
3206  NS_LOG_FUNCTION(this);
3207  m_srb1Old = nullptr;
3208 }
3209 
3210 uint8_t
3212 {
3213  auto it = m_bid2DrbidMap.find(bid);
3214  // NS_ASSERT_MSG (it != m_bid2DrbidMap.end (), "could not find BID " << bid);
3215  if (it == m_bid2DrbidMap.end())
3216  {
3217  return 0;
3218  }
3219  else
3220  {
3221  return it->second;
3222  }
3223 }
3224 
3225 void
3227 {
3228  NS_LOG_FUNCTION(this << ToString(newState));
3229  State oldState = m_state;
3230  m_state = newState;
3231  NS_LOG_INFO(this << " IMSI " << m_imsi << " RNTI " << m_rnti << " UeRrc " << ToString(oldState)
3232  << " --> " << ToString(newState));
3233  m_stateTransitionTrace(m_imsi, m_cellId, m_rnti, oldState, newState);
3234 
3235  switch (newState)
3236  {
3237  case IDLE_START:
3239  {
3240  NS_LOG_INFO("Starting initial cell selection after RLF");
3241  }
3242  else
3243  {
3244  NS_FATAL_ERROR("cannot switch to an initial state");
3245  }
3246  break;
3247 
3248  case IDLE_CELL_SEARCH:
3249  case IDLE_WAIT_MIB_SIB1:
3250  case IDLE_WAIT_MIB:
3251  case IDLE_WAIT_SIB1:
3252  break;
3253 
3254  case IDLE_CAMPED_NORMALLY:
3255  if (m_connectionPending)
3256  {
3258  }
3259  break;
3260 
3261  case IDLE_WAIT_SIB2:
3262  if (m_hasReceivedSib2)
3263  {
3265  StartConnection();
3266  }
3267  break;
3268 
3269  case IDLE_RANDOM_ACCESS:
3270  case IDLE_CONNECTING:
3271  case CONNECTED_NORMALLY:
3272  case CONNECTED_HANDOVER:
3273  case CONNECTED_PHY_PROBLEM:
3275  break;
3276 
3277  default:
3278  break;
3279  }
3280 }
3281 
3282 void
3284 {
3285  NS_LOG_FUNCTION(this << m_imsi << m_rnti);
3290 }
3291 
3292 void
3294 {
3295  NS_LOG_FUNCTION(this << m_imsi);
3297  NS_LOG_INFO("noOfSyncIndications " << (uint16_t)m_noOfSyncIndications);
3300  {
3301  ResetRlfParams();
3302  }
3303 }
3304 
3305 void
3307 {
3308  NS_LOG_FUNCTION(this << m_imsi);
3310  NS_LOG_INFO(this << " Total Number of Sync indications from PHY "
3311  << (uint16_t)m_noOfSyncIndications << "N310 value : " << (uint16_t)m_n310);
3314  {
3318  {
3319  NS_LOG_INFO("t310 started");
3320  }
3321  m_cphySapProvider.at(0)->StartInSyncDetection();
3323  }
3324 }
3325 
3326 void
3328 {
3329  NS_LOG_FUNCTION(this << m_imsi);
3330 
3331  NS_LOG_DEBUG("The number of sync indication received by RRC from PHY: "
3332  << (uint16_t)m_noOfSyncIndications);
3334 }
3335 
3336 void
3338 {
3339  NS_LOG_FUNCTION(this << m_imsi);
3342  m_cphySapProvider.at(0)->ResetRlfParams();
3343 }
3344 
3345 const std::string
3347 {
3348  return g_ueRrcStateName[s];
3349 }
3350 
3351 } // namespace ns3
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:242
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:234
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:250
static double IeValue2ActualQRxLevMin(int8_t qRxLevMinIeValue)
Returns the actual value of an Q-RxLevMin parameter.
Definition: lte-common.cc:339
static double IeValue2ActualHysteresis(uint8_t hysteresisIeValue)
Returns the actual value of a hysteresis parameter.
Definition: lte-common.cc:278
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:258
static double IeValue2ActualA3Offset(int8_t a3OffsetIeValue)
Returns the actual value of an a3-Offset parameter.
Definition: lte-common.cc:308
void Cancel()
This method is syntactic sugar for the ns3::Simulator::Cancel method.
Definition: event-id.cc:55
bool IsRunning() const
This method is syntactic sugar for !IsExpired().
Definition: event-id.cc:76
This class implements the Access Stratum (AS) Service Access Point (SAP), i.e., the interface between...
Definition: lte-as-sap.h:39
This class implements the Access Stratum (AS) Service Access Point (SAP), i.e., the interface between...
Definition: lte-as-sap.h:98
virtual void NotifyConnectionFailed()=0
Notify the NAS that RRC Connection Establishment failed.
virtual void NotifyConnectionSuccessful()=0
Notify the NAS that RRC Connection Establishment was successful.
virtual void NotifyConnectionReleased()=0
Notify the NAS that RRC Connection was released.
virtual void RecvData(Ptr< Packet > packet)=0
receive a data packet
Service Access Point (SAP) offered by the MAC to the RLC See Femto Forum MAC Scheduler Interface Spec...
Definition: lte-mac-sap.h:36
Service Access Point (SAP) offered by the MAC to the RLC See Femto Forum MAC Scheduler Interface Spec...
Definition: lte-mac-sap.h:96
static TypeId GetTypeId()
Get the type ID.
Definition: lte-rlc-am.cc:87
This abstract base class defines the API to interact with the Radio Link Control (LTE_RLC) in LTE,...
Definition: lte-rlc.h:49
void SetLteRlcSapUser(LteRlcSapUser *s)
Definition: lte-rlc.cc:155
void SetRnti(uint16_t rnti)
Definition: lte-rlc.cc:134
void SetLteMacSapProvider(LteMacSapProvider *s)
Definition: lte-rlc.cc:169
LteMacSapUser * GetLteMacSapUser()
Definition: lte-rlc.cc:176
void SetLcId(uint8_t lcId)
Definition: lte-rlc.cc:141
LteRlcSapProvider * GetLteRlcSapProvider()
Definition: lte-rlc.cc:162
static TypeId GetTypeId()
Get the type ID.
Definition: lte-rlc.cc:197
static TypeId GetTypeId()
Get the type ID.
Definition: lte-rlc-um.cc:56
static double ConvertPdschConfigDedicated2Double(PdschConfigDedicated pdschConfigDedicated)
Convert PDSCH config dedicated function.
Definition: lte-rrc-sap.h:189
Service Access Point (SAP) offered by the UE component carrier manager to the UE RRC.
virtual std::vector< LteUeCcmRrcSapProvider::LcsConfig > AddLc(uint8_t lcId, LteUeCmacSapProvider::LogicalChannelConfig lcConfig, LteMacSapUser *msu)=0
add a new Logical Channel (LC)
virtual void Reset()=0
Reset LC maps.
virtual LteMacSapUser * ConfigureSignalBearer(uint8_t lcid, LteUeCmacSapProvider::LogicalChannelConfig lcConfig, LteMacSapUser *msu)=0
Add the Signal Bearer for a specific Ue in LteUeComponenCarrierManager.
Service Access Point (SAP) offered by the UE RRC to the UE CCM.
Service Access Point (SAP) offered by the UE MAC to the UE RRC.
Service Access Point (SAP) offered by the UE MAC to the UE RRC.
Service Access Point (SAP) offered by the UE PHY to the UE RRC for control purposes.
Service Access Point (SAP) offered by the UE PHY to the UE RRC for control purposes.
friend class MemberLteUeCcmRrcSapUser< LteUeRrc >
allow MemberLteUeCcmRrcSapUser<LteUeRrc> class friend access
Definition: lte-ue-rrc.h:91
void DoRecvRrcConnectionReconfiguration(LteRrcSap::RrcConnectionReconfiguration msg)
Part of the RRC protocol.
Definition: lte-ue-rrc.cc:1052
uint8_t m_lastRrcTransactionIdentifier
last RRC transaction identifier
Definition: lte-ue-rrc.h:819
bool m_connectionPending
True if a connection request by upper layers is pending.
Definition: lte-ue-rrc.h:934
bool m_hasReceivedSib1
True if SIB1 was received for the current cell.
Definition: lte-ue-rrc.h:938
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:2930
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:1127
void DoCompleteSetup(LteUeRrcSapProvider::CompleteSetupParameters params)
Part of the RRC protocol.
Definition: lte-ue-rrc.cc:958
void DoNotifyOutOfSync()
Do notify out of sync function.
Definition: lte-ue-rrc.cc:3306
LteUeCcmRrcSapUser * GetLteCcmRrcSapUser()
Get the Component Carrier Management SAP offered by this RRC.
Definition: lte-ue-rrc.cc:409
void DoRecvRrcConnectionReject(LteRrcSap::RrcConnectionReject msg)
Part of the RRC protocol.
Definition: lte-ue-rrc.cc:1218
uint16_t m_previousCellId
the cell id of the previous cell UE was attached to
Definition: lte-ue-rrc.h:1279
Ptr< LteSignalingRadioBearerInfo > m_srb1Old
SRB1 configuration before RRC connection reconfiguration.
Definition: lte-ue-rrc.h:806
static TypeId GetTypeId()
Get the type ID.
Definition: lte-ue-rrc.cc:180
void SwitchToState(State s)
Switch the UE RRC to the given state.
Definition: lte-ue-rrc.cc:3226
uint16_t GetRnti() const
Definition: lte-ue-rrc.cc:455
void DoDisconnect()
Disconnect function.
Definition: lte-ue-rrc.cc:610
LteMacSapProvider * m_macSapProvider
MAC SAP provider.
Definition: lte-ue-rrc.h:768
void DoNotifyRandomAccessFailed()
Notify random access failed function.
Definition: lte-ue-rrc.cc:704
TracedCallback< uint64_t, uint16_t, uint16_t, uint16_t > m_mibReceivedTrace
The MibReceived trace source.
Definition: lte-ue-rrc.h:834
LteUeCmacSapUser * GetLteUeCmacSapUser()
This function is overloaded to maintain backward compatibility.
Definition: lte-ue-rrc.cc:367
void SetLteUeCmacSapProvider(LteUeCmacSapProvider *s)
set the CMAC SAP this RRC should interact with
Definition: lte-ue-rrc.cc:353
uint64_t m_imsi
The unique UE identifier.
Definition: lte-ue-rrc.h:784
uint8_t m_n311
The 'N311' attribute.
Definition: lte-ue-rrc.h:1260
Ptr< LteSignalingRadioBearerInfo > m_srb0
The Srb0 attribute.
Definition: lte-ue-rrc.h:797
uint8_t m_connEstFailCountLimit
the counter value for T300 timer expiration received from the eNB
Definition: lte-ue-rrc.h:1281
LteUeCphySapUser * GetLteUeCphySapUser()
Definition: lte-ue-rrc.cc:339
void DoConnect()
Connect function.
Definition: lte-ue-rrc.cc:806
TracedCallback< uint64_t, uint16_t, uint16_t > m_handoverEndErrorTrace
The HandoverEndError trace source.
Definition: lte-ue-rrc.h:902
State
The states of the UE RRC entity.
Definition: lte-ue-rrc.h:99
@ CONNECTED_REESTABLISHING
Definition: lte-ue-rrc.h:112
@ IDLE_CAMPED_NORMALLY
Definition: lte-ue-rrc.h:105
@ CONNECTED_PHY_PROBLEM
Definition: lte-ue-rrc.h:111
TracedCallback< uint64_t, uint16_t, uint16_t, State, State > m_stateTransitionTrace
The StateTransition trace source.
Definition: lte-ue-rrc.h:851
VarMeasConfig m_varMeasConfig
Includes the accumulated configuration of the measurements to be performed by the UE.
Definition: lte-ue-rrc.h:976
friend class MemberLteUeRrcSapProvider< LteUeRrc >
allow MemberLteUeRrcSapProvider<LteUeRrc> class friend access
Definition: lte-ue-rrc.h:89
void ApplyMeasConfig(LteRrcSap::MeasConfig mc)
Update the current measurement configuration m_varMeasConfig.
Definition: lte-ue-rrc.cc:1630
LteRrcSap::PdschConfigDedicated m_pdschConfigDedicated
the PDSCH config dedicated
Definition: lte-ue-rrc.h:821
uint8_t m_n310
The 'N310' attribute.
Definition: lte-ue-rrc.h:1254
void SetUseRlcSm(bool val)
Definition: lte-ue-rrc.cc:524
TracedCallback< uint64_t, uint16_t > m_initialCellSelectionEndErrorTrace
The InitialCellSelectionEndError trace source.
Definition: lte-ue-rrc.h:861
EventId m_radioLinkFailureDetected
Time limit (given by m_t310) before the radio link is considered to have failed.
Definition: lte-ue-rrc.h:1271
void DoRecvRrcConnectionReestablishmentReject(LteRrcSap::RrcConnectionReestablishmentReject msg)
Part of the RRC protocol.
Definition: lte-ue-rrc.cc:1179
void DoNotifyRandomAccessSuccessful()
Notify random access successful function.
Definition: lte-ue-rrc.cc:660
LteUeRrcSapProvider * m_rrcSapProvider
RRC SAP provider.
Definition: lte-ue-rrc.h:766
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:2857
void DoRecvRrcConnectionSetup(LteRrcSap::RrcConnectionSetup msg)
Part of the RRC protocol.
Definition: lte-ue-rrc.cc:1021
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:2733
bool m_leaveConnectedMode
true if UE NAS ask UE RRC to leave connected mode, e.g., after RLF, i.e.
Definition: lte-ue-rrc.h:1276
void DoRecvRrcConnectionReestablishment(LteRrcSap::RrcConnectionReestablishment msg)
Part of the RRC protocol.
Definition: lte-ue-rrc.cc:1156
bool m_hasReceivedSib2
True if SIB2 was received for the current cell.
Definition: lte-ue-rrc.h:940
void SynchronizeToStrongestCell()
Go through the list of measurement results, choose the one with the strongest RSRP,...
Definition: lte-ue-rrc.cc:1239
std::map< uint8_t, uint8_t > m_bid2DrbidMap
bid to DR bid map
Definition: lte-ue-rrc.h:757
void SetLteUeCphySapProvider(LteUeCphySapProvider *s)
set the CPHY SAP this RRC should use to interact with the PHY
Definition: lte-ue-rrc.cc:325
std::vector< LteUeCmacSapProvider * > m_cmacSapProvider
UE CMac SAP provider.
Definition: lte-ue-rrc.h:763
State GetState() const
Definition: lte-ue-rrc.cc:510
uint32_t m_dlEarfcn
Downlink carrier frequency.
Definition: lte-ue-rrc.h:826
LteUeCcmRrcSapProvider * m_ccmRrcSapProvider
Interface to the LteUeComponentCarrierManage instance.
Definition: lte-ue-rrc.h:777
void DoSetCsgWhiteList(uint32_t csgId)
Set CSG white list function.
Definition: lte-ue-rrc.cc:744
void ApplyRadioResourceConfigDedicatedSecondaryCarrier(LteRrcSap::NonCriticalExtensionConfiguration nonCec)
Apply radio resource config dedicated secondary carrier.
Definition: lte-ue-rrc.cc:1361
LteAsSapProvider * GetAsSapProvider()
Definition: lte-ue-rrc.cc:422
void DoSetTemporaryCellRnti(uint16_t rnti)
Set temporary cell rnti function.
Definition: lte-ue-rrc.cc:651
void SetLteMacSapProvider(LteMacSapProvider *s)
set the MAC SAP provider.
Definition: lte-ue-rrc.cc:395
TracedCallback< uint64_t, uint16_t, uint16_t > m_radioLinkFailureTrace
The 'RadioLinkFailure' trace source.
Definition: lte-ue-rrc.h:931
uint64_t GetImsi() const
Definition: lte-ue-rrc.cc:449
uint32_t m_ulEarfcn
Uplink carrier frequency.
Definition: lte-ue-rrc.h:827
TracedCallback< uint64_t, uint16_t, uint16_t > m_connectionEstablishedTrace
The ConnectionEstablished trace source.
Definition: lte-ue-rrc.h:877
uint8_t GetDlBandwidth() const
Definition: lte-ue-rrc.cc:490
TracedCallback< uint64_t, uint16_t, uint16_t, uint16_t > m_sib1ReceivedTrace
The Sib1Received trace source.
Definition: lte-ue-rrc.h:840
TracedCallback< uint64_t, uint16_t, uint16_t > m_randomAccessErrorTrace
The RandomAccessError trace source.
Definition: lte-ue-rrc.h:872
uint32_t GetDlEarfcn() const
Definition: lte-ue-rrc.cc:497
std::list< LteRrcSap::SCellToAddMod > m_sCellToAddModList
Secondary carriers.
Definition: lte-ue-rrc.h:828
LtePdcpSapUser * m_drbPdcpSapUser
DRB PDCP SAP user.
Definition: lte-ue-rrc.h:769
TracedCallback< Ptr< LteUeRrc >, std::list< LteRrcSap::SCellToAddMod > > m_sCarrierConfiguredTrace
The SCarrierConfigured trace source.
Definition: lte-ue-rrc.h:908
void DoStartCellSelection(uint32_t dlEarfcn)
Start cell selection function.
Definition: lte-ue-rrc.cc:751
friend class MemberLteAsSapProvider< LteUeRrc >
allow MemberLteAsSapProvider<LteUeRrc> class friend access
Definition: lte-ue-rrc.h:85
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:817
TracedCallback< uint64_t, uint16_t, uint16_t > m_handoverEndOkTrace
The HandoverEndOk trace source.
Definition: lte-ue-rrc.h:897
TracedCallback< uint64_t, uint16_t, uint16_t, std::string, uint8_t > m_phySyncDetectionTrace
The 'PhySyncDetection' trace source.
Definition: lte-ue-rrc.h:926
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:1139
Time m_t310
The 'T310' attribute.
Definition: lte-ue-rrc.h:1248
friend class UeMemberLteUeCmacSapUser
allow UeMemberLteUeCmacSapUser class friend access
Definition: lte-ue-rrc.h:79
void RadioLinkFailureDetected()
Radio link failure detected function.
Definition: lte-ue-rrc.cc:3283
State m_state
The current UE RRC state.
Definition: lte-ue-rrc.h:781
std::vector< LteUeCphySapProvider * > m_cphySapProvider
UE CPhy SAP provider.
Definition: lte-ue-rrc.h:760
LteUeCcmRrcSapUser * m_ccmRrcSapUser
CCM RRC SAP user.
Definition: lte-ue-rrc.h:778
TracedCallback< uint64_t, uint16_t, uint16_t, uint8_t > m_drbCreatedTrace
The DrbCreated trace source.
Definition: lte-ue-rrc.h:920
uint16_t m_numberOfComponentCarriers
The number of component carriers.
Definition: lte-ue-rrc.h:1343
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:998
std::vector< LteUeCmacSapUser * > m_cmacSapUser
UE CMac SAP user.
Definition: lte-ue-rrc.h:762
TracedCallback< uint64_t, uint16_t, uint16_t > m_srb1CreatedTrace
The Srb1Created trace source.
Definition: lte-ue-rrc.h:914
TracedCallback< uint64_t, uint16_t > m_initialCellSelectionEndOkTrace
The InitialCellSelectionEndOk trace source.
Definition: lte-ue-rrc.h:856
uint8_t GetUlBandwidth() const
Definition: lte-ue-rrc.cc:483
void DoSendData(Ptr< Packet > packet, uint8_t bid)
Send data function.
Definition: lte-ue-rrc.cc:586
LteAsSapProvider * m_asSapProvider
AS SAP provider.
Definition: lte-ue-rrc.h:771
uint16_t m_rnti
The C-RNTI attribute.
Definition: lte-ue-rrc.h:788
uint8_t m_noOfSyncIndications
number of in-sync or out-of-sync indications coming from PHY layer
Definition: lte-ue-rrc.h:1273
uint16_t GetCellId() const
Definition: lte-ue-rrc.cc:462
void DoSetNumberOfComponentCarriers(uint16_t noOfComponentCarriers)
RRC CCM SAP USER Method.
Definition: lte-ue-rrc.cc:1232
~LteUeRrc() override
Destructor.
Definition: lte-ue-rrc.cc:152
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:2676
std::map< uint16_t, MeasValues > m_storedMeasValues
Internal storage of the latest measurement results from all detected detected cells,...
Definition: lte-ue-rrc.h:1080
void DoReportUeMeasurements(LteUeCphySapUser::UeMeasurementsParameters params)
Report UE measurements function.
Definition: lte-ue-rrc.cc:912
LteUeRrcSapUser * m_rrcSapUser
RRC SAP user.
Definition: lte-ue-rrc.h:765
TracedCallback< uint64_t, uint16_t, uint16_t > m_connectionReconfigurationTrace
The ConnectionReconfiguration trace source.
Definition: lte-ue-rrc.h:887
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:1910
void SaveUeMeasurements(uint16_t cellId, double rsrp, double rsrq, bool useLayer3Filtering, uint8_t componentCarrierId)
Keep the given measurement result as the latest measurement figures, to be utilised by UE RRC functio...
Definition: lte-ue-rrc.cc:1852
void SetLteCcmRrcSapProvider(LteUeCcmRrcSapProvider *s)
set the Component Carrier Management SAP this RRC should interact with
Definition: lte-ue-rrc.cc:402
TracedCallback< uint64_t, uint16_t, uint16_t > m_sib2ReceivedTrace
The Sib2Received trace source.
Definition: lte-ue-rrc.h:845
void LeaveConnectedMode()
Leave connected mode method Resets the UE back to an appropriate state depending on the nature of cau...
Definition: lte-ue-rrc.cc:3130
uint32_t GetUlEarfcn() const
Definition: lte-ue-rrc.cc:503
void VarMeasReportListClear(uint8_t measId)
Remove the reporting entry of the given measurement identity from m_varMeasReportList.
Definition: lte-ue-rrc.cc:2912
LteUeRrcSapProvider * GetLteUeRrcSapProvider()
Definition: lte-ue-rrc.cc:388
std::map< uint8_t, Ptr< LteDataRadioBearerInfo > > m_drbMap
The DataRadioBearerMap attribute.
Definition: lte-ue-rrc.h:811
uint16_t m_cellId
The CellId attribute.
Definition: lte-ue-rrc.h:792
uint8_t m_connEstFailCount
the counter to count T300 timer expiration
Definition: lte-ue-rrc.h:1284
void DoRecvMasterInformationBlock(uint16_t cellId, LteRrcSap::MasterInformationBlock msg)
Receive master information block function.
Definition: lte-ue-rrc.cc:846
void DoReceivePdcpSdu(LtePdcpSapUser::ReceivePdcpSduParameters params)
Receive PDCP SDU function.
Definition: lte-ue-rrc.cc:644
TracedCallback< uint64_t, uint16_t, uint16_t, uint8_t > m_connectionTimeoutTrace
The ConnectionTimeout trace source.
Definition: lte-ue-rrc.h:882
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:946
Time m_t300
The T300 attribute.
Definition: lte-ue-rrc.h:1226
EventId m_connectionTimeout
Invokes ConnectionEstablishmentTimeout() if RRC connection establishment procedure for this UE takes ...
Definition: lte-ue-rrc.h:1232
void VarMeasReportListAdd(uint8_t measId, ConcernedCells_t enteringCells)
Compose a new reporting entry of the given measurement identity, insert it into m_varMeasReportList,...
Definition: lte-ue-rrc.cc:2790
std::vector< LteUeCphySapUser * > m_cphySapUser
UE CPhy SAP user.
Definition: lte-ue-rrc.h:759
void ConnectionTimeout()
Invoked after timer T300 expires, notifying upper layers that RRC connection establishment procedure ...
Definition: lte-ue-rrc.cc:3173
bool m_hasReceivedMib
True if MIB was received for the current cell.
Definition: lte-ue-rrc.h:936
void DoRecvRrcConnectionRelease(LteRrcSap::RrcConnectionRelease msg)
Part of the RRC protocol.
Definition: lte-ue-rrc.cc:1201
std::list< uint16_t > ConcernedCells_t
List of cell IDs which are responsible for a certain trigger.
Definition: lte-ue-rrc.h:1003
void EvaluateCellForSelection()
Performs cell selection evaluation to the current serving cell.
Definition: lte-ue-rrc.cc:1280
void DoRecvSystemInformationBlockType1(uint16_t cellId, LteRrcSap::SystemInformationBlockType1 msg)
Receive system information block type 1 function.
Definition: lte-ue-rrc.cc:872
void StartConnection()
Start connection function.
Definition: lte-ue-rrc.cc:3119
void DoRecvSystemInformation(LteRrcSap::SystemInformation msg)
Part of the RRC protocol.
Definition: lte-ue-rrc.cc:969
void DoNotifyInSync()
Do notify in sync function.
Definition: lte-ue-rrc.cc:3293
uint16_t m_ulBandwidth
Uplink bandwidth in RBs.
Definition: lte-ue-rrc.h:824
LteUeRrc()
create an RRC instance for use within an ue
Definition: lte-ue-rrc.cc:118
uint32_t m_csgWhiteList
List of CSG ID which this UE entity has access to.
Definition: lte-ue-rrc.h:949
uint16_t GetPreviousCellId() const
Get the previous cell id.
Definition: lte-ue-rrc.cc:517
void InitializeSap()
Initialize SAP.
Definition: lte-ue-rrc.cc:563
void DisposeOldSrb1()
Dispose old SRB1.
Definition: lte-ue-rrc.cc:3204
void DoInitialize() override
Initialize() implementation.
Definition: lte-ue-rrc.cc:531
friend class LtePdcpSpecificLtePdcpSapUser< LteUeRrc >
allow LtePdcpSpecificLtePdcpSapUser<LteUeRrc> class friend access
Definition: lte-ue-rrc.h:83
TracedCallback< uint64_t, uint16_t, uint16_t > m_randomAccessSuccessfulTrace
The RandomAccessSuccessful trace source.
Definition: lte-ue-rrc.h:867
bool IsServingCell(uint16_t cellId) const
Definition: lte-ue-rrc.cc:469
LteRrcSap::SystemInformationBlockType1 m_lastSib1
Stored content of the last SIB1 received.
Definition: lte-ue-rrc.h:943
static const std::string ToString(LteUeRrc::State s)
Definition: lte-ue-rrc.cc:3346
void SetAsSapUser(LteAsSapUser *s)
Set the AS SAP user to interact with the NAS entity.
Definition: lte-ue-rrc.cc:416
void SetLteUeRrcSapUser(LteUeRrcSapUser *s)
set the RRC SAP this RRC should interact with
Definition: lte-ue-rrc.cc:381
uint16_t m_dlBandwidth
Downlink bandwidth in RBs.
Definition: lte-ue-rrc.h:823
Ptr< LteSignalingRadioBearerInfo > m_srb1
The Srb1 attribute.
Definition: lte-ue-rrc.h:801
LteAsSapUser * m_asSapUser
AS SAP user.
Definition: lte-ue-rrc.h:772
void SetImsi(uint64_t imsi)
Definition: lte-ue-rrc.cc:428
void DoForceCampedOnEnb(uint16_t cellId, uint32_t dlEarfcn)
Force camped on ENB function.
Definition: lte-ue-rrc.cc:762
void DoDispose() override
Destructor implementation.
Definition: lte-ue-rrc.cc:158
void StorePreviousCellId(uint16_t cellId)
Store the previous cell id.
Definition: lte-ue-rrc.cc:442
void ResetRlfParams()
Reset radio link failure parameters.
Definition: lte-ue-rrc.cc:3337
void DoResetSyncIndicationCounter()
Do reset sync indication counter function.
Definition: lte-ue-rrc.cc:3327
void ApplyRadioResourceConfigDedicated(LteRrcSap::RadioResourceConfigDedicated rrcd)
Apply radio resource config dedicated.
Definition: lte-ue-rrc.cc:1412
uint8_t Bid2Drbid(uint8_t bid)
Bid 2 DR bid.
Definition: lte-ue-rrc.cc:3211
TracedCallback< uint64_t, uint16_t, uint16_t, uint16_t > m_handoverStartTrace
The HandoverStart trace source.
Definition: lte-ue-rrc.h:892
Part of the RRC protocol.
Definition: lte-rrc-sap.h:1045
Part of the RRC protocol.
Definition: lte-rrc-sap.h:960
virtual void Setup(SetupParameters params)=0
Setup function.
virtual void SendRrcConnectionReconfigurationCompleted(RrcConnectionReconfigurationCompleted msg)=0
Send an RRCConnectionReconfigurationComplete message to the serving eNodeB during an RRC connection r...
virtual void SendMeasurementReport(MeasurementReport msg)=0
Send a MeasurementReport message to the serving eNodeB during a measurement reporting procedure (Sect...
virtual void SendIdealUeContextRemoveRequest(uint16_t rnti)=0
Send UE context remove request function.
virtual void SendRrcConnectionRequest(RrcConnectionRequest msg)=0
Send an _RRCConnectionRequest message to the serving eNodeB during an RRC connection establishment pr...
virtual void SendRrcConnectionSetupCompleted(RrcConnectionSetupCompleted msg)=0
Send an RRCConnectionSetupComplete message to the serving eNodeB during an RRC connection establishme...
Template for the implementation of the LteUeCphySapUser as a member of an owner class of type C to wh...
Instantiate subclasses of ns3::Object.
Ptr< Object > Create() const
Create an Object instance of the configured TypeId.
void SetTypeId(TypeId tid)
Set the TypeId of the Objects to be created by this factory.
A base class which provides memory management and object aggregation.
Definition: object.h:89
void Initialize()
Invoke DoInitialize on all Objects aggregated to this one.
Definition: object.cc:186
Ptr< T > GetObject() const
Get a pointer to the requested aggregated Object.
Definition: object.h:471
uint32_t GetSize() const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:861
Hold objects of type Ptr<T>.
Definition: pointer.h:37
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:571
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:285
static EventId ScheduleNow(FUNC f, Ts &&... args)
Schedule an event to expire Now.
Definition: simulator.h:605
static Time GetDelayLeft(const EventId &id)
Get the remaining time until this event will execute.
Definition: simulator.cc:217
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
double GetSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:403
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:931
UeMemberLteUeCmacSapUser class.
Definition: lte-ue-rrc.cc:55
UeMemberLteUeCmacSapUser(LteUeRrc *rrc)
Constructor.
Definition: lte-ue-rrc.cc:72
LteUeRrc * m_rrc
the RRC class
Definition: lte-ue-rrc.cc:69
void SetTemporaryCellRnti(uint16_t rnti) override
Definition: lte-ue-rrc.cc:78
void NotifyRandomAccessSuccessful() override
Notify the RRC that the MAC Random Access procedure completed successfully.
Definition: lte-ue-rrc.cc:84
void NotifyRandomAccessFailed() override
Notify the RRC that the MAC Random Access procedure failed.
Definition: lte-ue-rrc.cc:90
Hold an unsigned integer type.
Definition: uinteger.h:45
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:66
#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:86
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:179
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition: abort.h:108
#define NS_LOG_ERROR(msg)
Use NS_LOG to output a message of level LOG_ERROR.
Definition: log.h:254
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:268
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:282
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition: log.h:261
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:275
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:46
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1326
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1338
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Definition: nstime.h:1414
Ptr< const AttributeAccessor > MakePointerAccessor(T1 a1)
Definition: pointer.h:227
static const Time UE_MEASUREMENT_REPORT_DELAY
Artificial delay of UE measurements procedure.
Definition: lte-ue-rrc.h:63
static const std::string g_ueRrcStateName[LteUeRrc::NUM_STATES]
Map each of UE RRC states to its string representation.
Definition: lte-ue-rrc.cc:96
ObjectPtrContainerValue ObjectMapValue
ObjectMapValue is an alias for ObjectPtrContainerValue.
Definition: object-map.h:40
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:533
constexpr uint32_t MIN_NO_CC
Minimum number of carrier components allowed by 3GPP up to R13.
Definition: lte-common.h:36
constexpr uint32_t MAX_NO_CC
Maximum number of carrier components allowed by 3GPP up to R13.
Definition: lte-common.h:39
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Definition: uinteger.h:46
Ptr< const AttributeAccessor > MakeObjectMapAccessor(U T::*memberVariable)
MakeAccessorHelper implementation for ObjectVector.
Definition: object-map.h:76
Definition: second.py:1
params
Fit Fluctuating Two Ray model to the 3GPP TR 38.901 using the Anderson-Darling goodness-of-fit ##.
Parameters for LtePdcpSapProvider::TransmitPdcpSdu.
Definition: lte-pdcp-sap.h:44
Parameters for LtePdcpSapUser::ReceivePdcpSdu.
Definition: lte-pdcp-sap.h:77
uint8_t transmissionMode
transmission mode
Definition: lte-rrc-sap.h:151
uint16_t dlBandwidth
DL bandwidth.
Definition: lte-rrc-sap.h:580
uint16_t ulBandwidth
UL bandwidth.
Definition: lte-rrc-sap.h:581
uint32_t dlCarrierFreq
DL carrier frequency.
Definition: lte-rrc-sap.h:573
uint32_t ulCarrierFreq
UL carrier frequency.
Definition: lte-rrc-sap.h:574
int8_t qRxLevMin
INTEGER (-70..-22), actual value = IE value * 2 [dBm].
Definition: lte-rrc-sap.h:81
uint32_t ulCarrierFreq
UL carrier frequency.
Definition: lte-rrc-sap.h:88
uint16_t ulBandwidth
UL bandwidth.
Definition: lte-rrc-sap.h:89
MasterInformationBlock structure.
Definition: lte-rrc-sap.h:622
MeasConfig structure.
Definition: lte-rrc-sap.h:553
std::list< uint8_t > measIdToRemoveList
measure ID to remove list
Definition: lte-rrc-sap.h:558
std::list< MeasObjectToAddMod > measObjectToAddModList
measure object to add mod list
Definition: lte-rrc-sap.h:555
std::list< uint8_t > reportConfigToRemoveList
report config to remove list
Definition: lte-rrc-sap.h:556
std::list< uint8_t > measObjectToRemoveList
measure object to remove list
Definition: lte-rrc-sap.h:554
bool haveMeasGapConfig
have measure gap config?
Definition: lte-rrc-sap.h:562
QuantityConfig quantityConfig
quantity config
Definition: lte-rrc-sap.h:561
bool haveSmeasure
have S measure?
Definition: lte-rrc-sap.h:564
bool haveSpeedStatePars
have speed state parameters?
Definition: lte-rrc-sap.h:566
std::list< ReportConfigToAddMod > reportConfigToAddModList
report config to add mod list
Definition: lte-rrc-sap.h:557
std::list< MeasIdToAddMod > measIdToAddModList
measure ID to add mod list
Definition: lte-rrc-sap.h:559
bool haveQuantityConfig
have quantity config?
Definition: lte-rrc-sap.h:560
MeasObjectEutra structure.
Definition: lte-rrc-sap.h:336
int8_t offsetFreq
offset frequency
Definition: lte-rrc-sap.h:341
uint32_t carrierFreq
carrier frequency
Definition: lte-rrc-sap.h:337
MeasResultEutra structure.
Definition: lte-rrc-sap.h:680
uint8_t rsrqResult
RSRQ result.
Definition: lte-rrc-sap.h:687
uint8_t rsrpResult
RSRP result.
Definition: lte-rrc-sap.h:685
bool haveRsrpResult
have RSRP result
Definition: lte-rrc-sap.h:684
bool haveRsrqResult
have RSRQ result?
Definition: lte-rrc-sap.h:686
uint16_t physCellId
Phy cell ID.
Definition: lte-rrc-sap.h:681
bool haveCgiInfo
have CGI info?
Definition: lte-rrc-sap.h:682
uint8_t rsrqResult
the RSRQ result
Definition: lte-rrc-sap.h:675
uint8_t rsrpResult
the RSRP result
Definition: lte-rrc-sap.h:674
uint8_t rsrpResult
the RSRP result
Definition: lte-rrc-sap.h:693
uint8_t rsrqResult
the RSRQ result
Definition: lte-rrc-sap.h:694
MeasResultServFreq structure.
Definition: lte-rrc-sap.h:707
bool haveMeasResultSCell
have measResultSCell?
Definition: lte-rrc-sap.h:709
bool haveMeasResultBestNeighCell
have measResultBestNeighCell?
Definition: lte-rrc-sap.h:711
uint16_t servFreqId
serving cell index
Definition: lte-rrc-sap.h:708
MeasResultSCell measResultSCell
SCell measurement results.
Definition: lte-rrc-sap.h:710
MeasResults structure.
Definition: lte-rrc-sap.h:717
uint8_t measId
measure ID
Definition: lte-rrc-sap.h:718
bool haveMeasResultNeighCells
have measure result neighbor cells
Definition: lte-rrc-sap.h:720
std::list< MeasResultEutra > measResultListEutra
measure result list eutra
Definition: lte-rrc-sap.h:721
bool haveMeasResultServFreqList
has measResultServFreqList-r10
Definition: lte-rrc-sap.h:722
std::list< MeasResultServFreq > measResultServFreqList
MeasResultServFreqList-r10.
Definition: lte-rrc-sap.h:723
MeasResultPCell measResultPCell
measurement result primary cell
Definition: lte-rrc-sap.h:719
MeasurementReport structure.
Definition: lte-rrc-sap.h:948
MeasResults measResults
measure results
Definition: lte-rrc-sap.h:949
MobilityControlInfo structure.
Definition: lte-rrc-sap.h:593
RachConfigDedicated rachConfigDedicated
RACH config dedicated.
Definition: lte-rrc-sap.h:602
bool haveRachConfigDedicated
Have RACH config dedicated?
Definition: lte-rrc-sap.h:601
uint16_t newUeIdentity
new UE identity
Definition: lte-rrc-sap.h:599
bool haveCarrierBandwidth
have carrier bandwidth?
Definition: lte-rrc-sap.h:597
bool haveCarrierFreq
have carrier frequency?
Definition: lte-rrc-sap.h:595
CarrierBandwidthEutra carrierBandwidth
carrier bandwidth
Definition: lte-rrc-sap.h:598
CarrierFreqEutra carrierFreq
carrier frequency
Definition: lte-rrc-sap.h:596
uint16_t targetPhysCellId
target Phy cell ID
Definition: lte-rrc-sap.h:594
NonCriticalExtensionConfiguration structure.
Definition: lte-rrc-sap.h:874
std::list< uint8_t > sCellToReleaseList
SCell to release list.
Definition: lte-rrc-sap.h:876
std::list< SCellToAddMod > sCellToAddModList
SCell to add mod list.
Definition: lte-rrc-sap.h:875
int8_t referenceSignalPower
INTEGER (-60..50),.
Definition: lte-rrc-sap.h:157
PdschConfigDedicated structure.
Definition: lte-rrc-sap.h:163
PhysicalConfigDedicated structure.
Definition: lte-rrc-sap.h:226
PdschConfigDedicated pdschConfigDedicated
PDSCH config dedicated.
Definition: lte-rrc-sap.h:233
bool haveAntennaInfoDedicated
have antenna info dedicated?
Definition: lte-rrc-sap.h:230
SoundingRsUlConfigDedicated soundingRsUlConfigDedicated
sounding RS UL config dedicated
Definition: lte-rrc-sap.h:229
bool haveSoundingRsUlConfigDedicated
have sounding RS UL config dedicated?
Definition: lte-rrc-sap.h:227
bool havePdschConfigDedicated
have PDSCH config dedicated?
Definition: lte-rrc-sap.h:232
AntennaInfoDedicated antennaInfo
antenna info
Definition: lte-rrc-sap.h:231
uint8_t numberOfRaPreambles
number of RA preambles
Definition: lte-rrc-sap.h:256
uint8_t filterCoefficientRSRQ
filter coefficient RSRQ
Definition: lte-rrc-sap.h:308
uint8_t filterCoefficientRSRP
filter coefficient RSRP
Definition: lte-rrc-sap.h:307
uint8_t raResponseWindowSize
RA response window size.
Definition: lte-rrc-sap.h:263
uint8_t preambleTransMax
preamble transmit maximum
Definition: lte-rrc-sap.h:262
TxFailParam txFailParam
txFailParams
Definition: lte-rrc-sap.h:278
PreambleInfo preambleInfo
preamble info
Definition: lte-rrc-sap.h:276
RaSupervisionInfo raSupervisionInfo
RA supervision info.
Definition: lte-rrc-sap.h:277
uint8_t raPreambleIndex
RA preamble index.
Definition: lte-rrc-sap.h:587
uint8_t raPrachMaskIndex
RA PRACH mask index.
Definition: lte-rrc-sap.h:588
RachConfigCommon rachConfigCommon
RACH config common.
Definition: lte-rrc-sap.h:290
PdschConfigCommon pdschConfigCommon
PDSCH config common.
Definition: lte-rrc-sap.h:291
RadioResourceConfigDedicated structure.
Definition: lte-rrc-sap.h:296
PhysicalConfigDedicated physicalConfigDedicated
physical config dedicated
Definition: lte-rrc-sap.h:301
std::list< uint8_t > drbToReleaseList
DRB to release list.
Definition: lte-rrc-sap.h:299
std::list< DrbToAddMod > drbToAddModList
DRB to add mod list.
Definition: lte-rrc-sap.h:298
std::list< SrbToAddMod > srbToAddModList
SRB to add mod list.
Definition: lte-rrc-sap.h:297
Specifies criteria for triggering of an E-UTRA measurement reporting event.
Definition: lte-rrc-sap.h:373
bool reportOnLeave
Indicates whether or not the UE shall initiate the measurement reporting procedure when the leaving c...
Definition: lte-rrc-sap.h:399
uint8_t maxReportCells
Maximum number of cells, excluding the serving cell, to be included in the measurement report.
Definition: lte-rrc-sap.h:441
uint8_t hysteresis
Parameter used within the entry and leave condition of an event triggered reporting condition.
Definition: lte-rrc-sap.h:407
ThresholdEutra threshold2
Threshold for event A5.
Definition: lte-rrc-sap.h:394
enum ns3::LteRrcSap::ReportConfigEutra::@63 triggerType
Trigger enumeration.
enum ns3::LteRrcSap::ReportConfigEutra::@64 eventId
Event enumeration.
@ EVENT_A2
Event A2: Serving becomes worse than absolute threshold.
Definition: lte-rrc-sap.h:385
@ EVENT_A3
Event A3: Neighbour becomes amount of offset better than PCell.
Definition: lte-rrc-sap.h:386
@ EVENT_A4
Event A4: Neighbour becomes better than absolute threshold.
Definition: lte-rrc-sap.h:387
@ EVENT_A1
Event A1: Serving becomes better than absolute threshold.
Definition: lte-rrc-sap.h:384
@ EVENT_A5
Event A5: PCell becomes worse than absolute threshold1 AND Neighbour becomes better than another abso...
Definition: lte-rrc-sap.h:388
ThresholdEutra threshold1
Threshold for event A1, A2, A4, and A5.
Definition: lte-rrc-sap.h:393
enum ns3::LteRrcSap::ReportConfigEutra::@67 reportInterval
Report interval enumeration.
enum ns3::LteRrcSap::ReportConfigEutra::@65 triggerQuantity
Trigger type enumeration.
@ RSRP
Reference Signal Received Power.
Definition: lte-rrc-sap.h:425
@ RSRQ
Reference Signal Received Quality.
Definition: lte-rrc-sap.h:426
int8_t a3Offset
Offset value for Event A3.
Definition: lte-rrc-sap.h:403
uint16_t timeToTrigger
Time during which specific criteria for the event needs to be met in order to trigger a measurement r...
Definition: lte-rrc-sap.h:411
RrcConnectionReconfigurationCompleted structure.
Definition: lte-rrc-sap.h:898
uint8_t rrcTransactionIdentifier
RRC transaction identifier.
Definition: lte-rrc-sap.h:899
RrcConnectionReconfiguration structure.
Definition: lte-rrc-sap.h:881
uint8_t rrcTransactionIdentifier
RRC transaction identifier.
Definition: lte-rrc-sap.h:882
bool haveMobilityControlInfo
have mobility control info
Definition: lte-rrc-sap.h:885
NonCriticalExtensionConfiguration nonCriticalExtension
3GPP TS 36.331 v.11.10 R11 Sec.
Definition: lte-rrc-sap.h:893
bool haveRadioResourceConfigDedicated
have radio resource config dedicated
Definition: lte-rrc-sap.h:887
RadioResourceConfigDedicated radioResourceConfigDedicated
radio resource config dedicated
Definition: lte-rrc-sap.h:889
bool haveNonCriticalExtension
have critical extension?
Definition: lte-rrc-sap.h:890
MobilityControlInfo mobilityControlInfo
mobility control info
Definition: lte-rrc-sap.h:886
RrcConnectionReestablishment structure.
Definition: lte-rrc-sap.h:911
RrcConnectionReestablishmentReject structure.
Definition: lte-rrc-sap.h:925
RrcConnectionReject structure.
Definition: lte-rrc-sap.h:936
RrcConnectionRelease structure.
Definition: lte-rrc-sap.h:930
uint8_t rrcTransactionIdentifier
RRC transaction identifier.
Definition: lte-rrc-sap.h:931
RrcConnectionRequest structure.
Definition: lte-rrc-sap.h:730
RrcConnectionSetupCompleted structure.
Definition: lte-rrc-sap.h:744
uint8_t rrcTransactionIdentifier
RRC transaction identifier.
Definition: lte-rrc-sap.h:745
RrcConnectionSetup structure.
Definition: lte-rrc-sap.h:736
uint8_t rrcTransactionIdentifier
RRC transaction identifier.
Definition: lte-rrc-sap.h:737
RadioResourceConfigDedicated radioResourceConfigDedicated
radio resource config dedicated
Definition: lte-rrc-sap.h:739
uint16_t srsConfigIndex
SRS config index.
Definition: lte-rrc-sap.h:145
SystemInformationBlockType1 structure.
Definition: lte-rrc-sap.h:629
CellSelectionInfo cellSelectionInfo
cell selection info
Definition: lte-rrc-sap.h:631
CellAccessRelatedInfo cellAccessRelatedInfo
cell access related info
Definition: lte-rrc-sap.h:630
RadioResourceConfigCommonSib radioResourceConfigCommon
radio resource config common
Definition: lte-rrc-sap.h:637
SystemInformation structure.
Definition: lte-rrc-sap.h:643
SystemInformationBlockType2 sib2
SIB2.
Definition: lte-rrc-sap.h:645
enum ns3::LteRrcSap::ThresholdEutra::@62 choice
Threshold enumeration.
@ THRESHOLD_RSRP
RSRP is used for the threshold.
Definition: lte-rrc-sap.h:364
@ THRESHOLD_RSRQ
RSRQ is used for the threshold.
Definition: lte-rrc-sap.h:365
uint8_t range
Value range used in RSRP/RSRQ threshold.
Definition: lte-rrc-sap.h:368
uint8_t connEstFailCount
Number of times that the UE detects T300 expiry on the same cell.
Definition: lte-rrc-sap.h:269
uint16_t prioritizedBitRateKbps
prioritize bit rate Kbps
uint16_t bucketSizeDurationMs
bucket size duration ms
uint8_t logicalChannelGroup
logical channel group
UeMeasurementsParameters structure.
Represents a measurement result from a certain cell.
Definition: lte-ue-rrc.h:1061
uint32_t carrierFreq
Measurement object frequency.
Definition: lte-ue-rrc.h:1064
double rsrp
Measured RSRP in dBm.
Definition: lte-ue-rrc.h:1062
double rsrq
Measured RSRQ in dB.
Definition: lte-ue-rrc.h:1063
Represents a single triggered event from a measurement identity which reporting criteria have been fu...
Definition: lte-ue-rrc.h:1111
ConcernedCells_t concernedCells
The list of cells responsible for this trigger.
Definition: lte-ue-rrc.h:1113
EventId timer
The pending reporting event, scheduled at the end of the time-to-trigger.
Definition: lte-ue-rrc.h:1115
uint8_t measId
The measurement identity which raised the trigger.
Definition: lte-ue-rrc.h:1112
std::map< uint8_t, LteRrcSap::ReportConfigToAddMod > reportConfigList
report config list
Definition: lte-ue-rrc.h:964
LteRrcSap::QuantityConfig quantityConfig
quantity config
Definition: lte-ue-rrc.h:965
std::map< uint8_t, LteRrcSap::MeasObjectToAddMod > measObjectList
measure object list
Definition: lte-ue-rrc.h:963
std::map< uint8_t, LteRrcSap::MeasIdToAddMod > measIdList
measure ID list
Definition: lte-ue-rrc.h:962
Represents a single measurement reporting entry., which includes information about a measurement for ...
Definition: lte-ue-rrc.h:986
uint8_t measId
measure ID
Definition: lte-ue-rrc.h:987
CompleteSetupParameters structure.
Definition: lte-rrc-sap.h:1049
SetupParameters structure.
Definition: lte-rrc-sap.h:964
LteRlcSapProvider * srb0SapProvider
SRB0 SAP provider.
Definition: lte-rrc-sap.h:965
LtePdcpSapProvider * srb1SapProvider
SRB1 SAP provider.
Definition: lte-rrc-sap.h:966