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