A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
lte-enb-rrc.cc
Go to the documentation of this file.
1 /* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2011 Centre Tecnologic de Telecomunicacions de Catalunya (CTTC)
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Author: Nicola Baldo <nbaldo@cttc.es>
19  * Marco Miozzo <mmiozzo@cttc.es>
20  * Manuel Requena <manuel.requena@cttc.es>
21  */
22 
23 #include "ns3/fatal-error.h"
24 #include "ns3/log.h"
25 #include "ns3/abort.h"
26 #include "ns3/pointer.h"
27 #include "ns3/object-map.h"
28 #include "ns3/object-factory.h"
29 #include "ns3/simulator.h"
30 
31 #include "lte-enb-rrc.h"
32 
33 #include "lte-enb-net-device.h"
34 #include "lte-radio-bearer-info.h"
35 #include "eps-bearer-tag.h"
36 #include "ff-mac-csched-sap.h"
37 #include "epc-enb-s1-sap.h"
38 
39 #include "lte-rlc.h"
40 #include "lte-rlc-tm.h"
41 #include "lte-rlc-um.h"
42 #include "lte-rlc-am.h"
43 #include "lte-pdcp.h"
44 #include "lte-pdcp-sap.h"
45 
46 #include <ns3/simulator.h>
47 
48 
49 
50 
51 NS_LOG_COMPONENT_DEFINE ("LteEnbRrc");
52 
53 
54 namespace ns3 {
55 
56 
57 // ///////////////////////////
58 // CMAC SAP forwarder
59 // ///////////////////////////
60 
62 {
63 public:
65 
66  virtual uint16_t AllocateTemporaryCellRnti ();
67  virtual void NotifyLcConfigResult (uint16_t rnti, uint8_t lcid, bool success);
68  virtual void RrcConfigurationUpdateInd (UeConfig params);
69 
70 private:
72 };
73 
75  : m_rrc (rrc)
76 {
77 }
78 
79 uint16_t
81 {
83 }
84 
85 void
86 EnbRrcMemberLteEnbCmacSapUser::NotifyLcConfigResult (uint16_t rnti, uint8_t lcid, bool success)
87 {
88  m_rrc->DoNotifyLcConfigResult (rnti, lcid, success);
89 }
90 
91 void
93 {
95 }
96 
97 
99  {
100  "INITIAL_RANDOM_ACCESS",
101  "CONNECTION_SETUP",
102  "CONNECTION_REJECTED",
103  "CONNECTED_NORMALLY",
104  "CONNECTION_RECONFIGURATION",
105  "CONNECTION_REESTABLISHMENT",
106  "HANDOVER_PREPARATION",
107  "HANDOVER_JOINING",
108  "HANDOVER_PATH_SWITCH",
109  "HANDOVER_LEAVING",
110  };
111 
112 std::string ToString (UeManager::State s)
113 {
114  return std::string (g_ueManagerStateName[s]);
115 }
116 
117 
118 
120 // UeManager
122 
123 
124 NS_OBJECT_ENSURE_REGISTERED (UeManager);
125 
126 
128 {
129  NS_FATAL_ERROR ("this constructor is not espected to be used");
130 }
131 
132 
134  : m_lastAllocatedDrbid (0),
135  m_rnti (rnti),
136  m_imsi (0),
137  m_lastRrcTransactionIdentifier (0),
138  m_rrc (rrc),
139  m_state (s),
140  m_pendingRrcConnectionReconfiguration (false),
141  m_sourceX2apId (0),
142  m_sourceCellId (0),
143  m_needTransmissionModeConfiguration (false)
144 {
145  NS_LOG_FUNCTION (this);
146 }
147 
148 void
150 {
151  NS_LOG_FUNCTION (this);
153 
160 
163 
164  // setup the eNB side of SRB0
165  {
166  uint8_t lcid = 0;
167 
168  Ptr<LteRlc> rlc = CreateObject<LteRlcTm> ()->GetObject<LteRlc> ();
170  rlc->SetRnti (m_rnti);
171  rlc->SetLcId (lcid);
172 
173  m_srb0 = CreateObject<LteSignalingRadioBearerInfo> ();
174  m_srb0->m_rlc = rlc;
175  m_srb0->m_srbIdentity = 0;
176  // no need to store logicalChannelConfig as SRB0 is pre-configured
177 
179  lcinfo.rnti = m_rnti;
180  lcinfo.lcId = lcid;
181  // leave the rest of lcinfo empty as CCCH (LCID 0) is pre-configured
182  m_rrc->m_cmacSapProvider->AddLc (lcinfo, rlc->GetLteMacSapUser ());
183 
184  }
185 
186  // setup the eNB side of SRB1; the UE side will be set up upon RRC connection establishment
187  {
188  uint8_t lcid = 1;
189 
190  Ptr<LteRlc> rlc = CreateObject<LteRlcAm> ()->GetObject<LteRlc> ();
192  rlc->SetRnti (m_rnti);
193  rlc->SetLcId (lcid);
194 
195  Ptr<LtePdcp> pdcp = CreateObject<LtePdcp> ();
196  pdcp->SetRnti (m_rnti);
197  pdcp->SetLcId (lcid);
200  rlc->SetLteRlcSapUser (pdcp->GetLteRlcSapUser ());
201 
202  m_srb1 = CreateObject<LteSignalingRadioBearerInfo> ();
203  m_srb1->m_rlc = rlc;
204  m_srb1->m_pdcp = pdcp;
205  m_srb1->m_srbIdentity = 1;
210 
212  lcinfo.rnti = m_rnti;
213  lcinfo.lcId = lcid;
214  lcinfo.lcGroup = 0; // all SRBs always mapped to LCG 0
215  lcinfo.qci = EpsBearer::GBR_CONV_VOICE; // not sure why the FF API requires a CQI even for SRBs...
216  lcinfo.isGbr = true;
217  lcinfo.mbrUl = 1e6;
218  lcinfo.mbrDl = 1e6;
219  lcinfo.gbrUl = 1e4;
220  lcinfo.gbrDl = 1e4;
221  m_rrc->m_cmacSapProvider->AddLc (lcinfo, rlc->GetLteMacSapUser ());
222  }
223 
227  m_rrc->m_rrcSapUser->SetupUe (m_rnti, ueParams);
228 
229  // configure MAC (and scheduler)
231  req.m_rnti = m_rnti;
234 
235  // configure PHY
238 
239  // schedule this UeManager instance to be deleted if the UE does not give any sign of life within a reasonable time
240  Time maxConnectionDelay;
241  switch (m_state)
242  {
244  // must account for reception of RAR and transmission of RRC CONNECTION REQUEST over UL GRANT
245  maxConnectionDelay = MilliSeconds (15);
246  break;
247  case HANDOVER_JOINING:
248  // must account for reception of X2 HO REQ ACK by source eNB,
249  // transmission of the Handover Command, and
250  // non-contention-based random access
251  maxConnectionDelay = MilliSeconds (50);
252  break;
253  default:
254  NS_FATAL_ERROR ("unspecified maxConnectionDelay for state " << ToString (m_state));
255  break;
256  }
258 }
259 
260 
262 {
263 }
264 
265 void
267 {
268  delete m_drbPdcpSapUser;
269  // delete eventual X2-U TEIDs
270  for (std::map <uint8_t, Ptr<LteDataRadioBearerInfo> >::iterator it = m_drbMap.begin ();
271  it != m_drbMap.end ();
272  ++it)
273  {
274  m_rrc->m_x2uTeidInfoMap.erase (it->second->m_gtpTeid);
275  }
276 }
277 
279 {
280  static TypeId tid = TypeId ("ns3::UeManager")
281  .SetParent<Object> ()
282  .AddConstructor<UeManager> ()
283  .AddAttribute ("DataRadioBearerMap", "List of UE DataRadioBearerInfo by DRBID.",
284  ObjectMapValue (),
286  MakeObjectMapChecker<LteDataRadioBearerInfo> ())
287  .AddAttribute ("Srb0", "SignalingRadioBearerInfo for SRB0",
288  PointerValue (),
289  MakePointerAccessor (&UeManager::m_srb0),
290  MakePointerChecker<LteSignalingRadioBearerInfo> ())
291  .AddAttribute ("Srb1", "SignalingRadioBearerInfo for SRB1",
292  PointerValue (),
293  MakePointerAccessor (&UeManager::m_srb1),
294  MakePointerChecker<LteSignalingRadioBearerInfo> ())
295  .AddAttribute ("C-RNTI",
296  "Cell Radio Network Temporary Identifier",
297  TypeId::ATTR_GET, // read-only attribute
298  UintegerValue (0), // unused, read-only attribute
299  MakeUintegerAccessor (&UeManager::m_rnti),
300  MakeUintegerChecker<uint16_t> ())
301  .AddTraceSource ("StateTransition",
302  "fired upon every UE state transition seen by the UeManager at the eNB RRC",
304  ;
305  return tid;
306 }
307 
308 void
309 UeManager::SetSource (uint16_t sourceCellId, uint16_t sourceX2apId)
310 {
311  m_sourceX2apId = sourceX2apId;
312  m_sourceCellId = sourceCellId;
313 }
314 
315 void
316 UeManager::SetImsi (uint64_t imsi)
317 {
318  m_imsi = imsi;
319 }
320 
321 void
322 UeManager::SetupDataRadioBearer (EpsBearer bearer, uint8_t bearerId, uint32_t gtpTeid, Ipv4Address transportLayerAddress)
323 {
324  NS_LOG_FUNCTION (this << (uint32_t) m_rnti);
325 
326  Ptr<LteDataRadioBearerInfo> drbInfo = CreateObject<LteDataRadioBearerInfo> ();
327  uint8_t drbid = AddDataRadioBearerInfo (drbInfo);
328  uint8_t lcid = Drbid2Lcid (drbid);
329  uint8_t bid = Drbid2Bid (drbid);
330  NS_ASSERT_MSG ( bearerId == 0 || bid == bearerId, "bearer ID mismatch (" << (uint32_t) bid << " != " << (uint32_t) bearerId << ", the assumption that ID are allocated in the same way by MME and RRC is not valid any more");
331  drbInfo->m_epsBearerIdentity = bid;
332  drbInfo->m_drbIdentity = drbid;
333  drbInfo->m_logicalChannelIdentity = lcid;
334  drbInfo->m_gtpTeid = gtpTeid;
335  drbInfo->m_transportLayerAddress = transportLayerAddress;
336 
337  if (m_state == HANDOVER_JOINING)
338  {
339  // setup TEIDs for receiving data eventually forwarded over X2-U
340  LteEnbRrc::X2uTeidInfo x2uTeidInfo;
341  x2uTeidInfo.rnti = m_rnti;
342  x2uTeidInfo.drbid = drbid;
343  std::pair<std::map<uint32_t, LteEnbRrc::X2uTeidInfo>::iterator, bool>
344  ret = m_rrc->m_x2uTeidInfoMap.insert (std::pair<uint32_t, LteEnbRrc::X2uTeidInfo> (gtpTeid, x2uTeidInfo));
345  NS_ASSERT_MSG (ret.second == true, "overwriting a pre-existing entry in m_x2uTeidInfoMap");
346  }
347 
348  TypeId rlcTypeId = m_rrc->GetRlcType (bearer);
349 
350  ObjectFactory rlcObjectFactory;
351  rlcObjectFactory.SetTypeId (rlcTypeId);
352  Ptr<LteRlc> rlc = rlcObjectFactory.Create ()->GetObject<LteRlc> ();
354  rlc->SetRnti (m_rnti);
355 
356  drbInfo->m_rlc = rlc;
357 
358  rlc->SetLcId (lcid);
359 
360  // we need PDCP only for real RLC, i.e., RLC/UM or RLC/AM
361  // if we are using RLC/SM we don't care of anything above RLC
362  if (rlcTypeId != LteRlcSm::GetTypeId ())
363  {
364  Ptr<LtePdcp> pdcp = CreateObject<LtePdcp> ();
365  pdcp->SetRnti (m_rnti);
366  pdcp->SetLcId (lcid);
369  rlc->SetLteRlcSapUser (pdcp->GetLteRlcSapUser ());
370  drbInfo->m_pdcp = pdcp;
371  }
372 
374  lcinfo.rnti = m_rnti;
375  lcinfo.lcId = lcid;
376  lcinfo.lcGroup = m_rrc->GetLogicalChannelGroup (bearer);
377  lcinfo.qci = bearer.qci;
378  lcinfo.isGbr = bearer.IsGbr ();
379  lcinfo.mbrUl = bearer.gbrQosInfo.mbrUl;
380  lcinfo.mbrDl = bearer.gbrQosInfo.mbrDl;
381  lcinfo.gbrUl = bearer.gbrQosInfo.gbrUl;
382  lcinfo.gbrDl = bearer.gbrQosInfo.gbrDl;
383  m_rrc->m_cmacSapProvider->AddLc (lcinfo, rlc->GetLteMacSapUser ());
384 
385  if (rlcTypeId == LteRlcAm::GetTypeId ())
386  {
388  }
389  else
390  {
392  }
393 
394  drbInfo->m_logicalChannelIdentity = lcid;
397  if (bearer.IsGbr ())
398  {
400  }
401  else
402  {
404  }
406 
408 }
409 
410 void
412 {
413  NS_LOG_FUNCTION (this << (uint32_t) m_rnti);
414  for (std::map <uint8_t, Ptr<LteDataRadioBearerInfo> >::iterator it = m_drbMap.begin ();
415  it != m_drbMap.end ();
416  ++it)
417  {
418  m_drbsToBeStarted.push_back (it->first);
419  }
420 }
421 
422 void
424 {
425  NS_LOG_FUNCTION (this << (uint32_t) m_rnti);
426  for (std::list <uint8_t>::iterator drbIdIt = m_drbsToBeStarted.begin ();
427  drbIdIt != m_drbsToBeStarted.end ();
428  ++drbIdIt)
429  {
430  std::map <uint8_t, Ptr<LteDataRadioBearerInfo> >::iterator drbIt = m_drbMap.find (*drbIdIt);
431  NS_ASSERT (drbIt != m_drbMap.end ());
432  drbIt->second->m_rlc->Initialize ();
433  if (drbIt->second->m_pdcp)
434  {
435  drbIt->second->m_pdcp->Initialize ();
436  }
437  }
438  m_drbsToBeStarted.clear ();
439 }
440 
441 
442 void
444 {
445  NS_LOG_FUNCTION (this << (uint32_t) m_rnti << (uint32_t) drbid);
446  uint8_t lcid = Drbid2Lcid (drbid);
447  std::map <uint8_t, Ptr<LteDataRadioBearerInfo> >::iterator it = m_drbMap.find (drbid);
448  NS_ASSERT_MSG (it != m_drbMap.end (), "request to remove radio bearer with unknown drbid " << drbid);
449 
450  // first delete eventual X2-U TEIDs
451  m_rrc->m_x2uTeidInfoMap.erase (it->second->m_gtpTeid);
452 
453  m_drbMap.erase (it);
455 
457  rrcd.havePhysicalConfigDedicated = false;
458  rrcd.drbToReleaseList.push_back (drbid);
459 
461  msg.haveMeasConfig = false;
462  msg.haveMobilityControlInfo = false;
463 
465 }
466 
467 
468 void
470 {
471  NS_LOG_FUNCTION (this);
472  switch (m_state)
473  {
475  case CONNECTION_SETUP:
479  case HANDOVER_JOINING:
480  case HANDOVER_LEAVING:
481  // a previous reconfiguration still ongoing, we need to wait for it to be finished
483  break;
484 
485  case CONNECTED_NORMALLY:
486  {
492  }
493  break;
494 
495  default:
496  NS_FATAL_ERROR ("method unexpected in state " << ToString (m_state));
497  break;
498  }
499 }
500 
501 void
502 UeManager::PrepareHandover (uint16_t cellId)
503 {
504  NS_LOG_FUNCTION (this << cellId);
505  switch (m_state)
506  {
507  case CONNECTED_NORMALLY:
508  {
509  m_targetCellId = cellId;
511  params.oldEnbUeX2apId = m_rnti;
513  params.sourceCellId = m_rrc->m_cellId;
514  params.targetCellId = cellId;
515  params.mmeUeS1apId = m_imsi;
516  params.ueAggregateMaxBitRateDownlink = 200 * 1000;
517  params.ueAggregateMaxBitRateUplink = 100 * 1000;
518  params.bearers = GetErabList ();
519 
541 
542  NS_LOG_LOGIC ("oldEnbUeX2apId = " << params.oldEnbUeX2apId);
543  NS_LOG_LOGIC ("sourceCellId = " << params.sourceCellId);
544  NS_LOG_LOGIC ("targetCellId = " << params.targetCellId);
545  NS_LOG_LOGIC ("mmmUeS1apId = " << params.oldEnbUeX2apId);
546  NS_LOG_LOGIC ("rrcContext = " << params.rrcContext);
547 
550  }
551  break;
552 
553  default:
554  NS_FATAL_ERROR ("method unexpected in state " << ToString (m_state));
555  break;
556  }
557 
558 }
559 
560 void
562 {
563  NS_LOG_FUNCTION (this);
564 
565  NS_ASSERT_MSG (params.notAdmittedBearers.empty (), "not admission of some bearers upon handover is not supported");
566  NS_ASSERT_MSG (params.admittedBearers.size () == m_drbMap.size (), "not enough bearers in admittedBearers");
567 
568  // note: the Handover command from the target eNB to the source eNB
569  // is expected to be sent transparently to the UE; however, here we
570  // decode the message and eventually reencode it. This way we can
571  // support both a real RRC protocol implementation and an ideal one
572  // without actual RRC protocol encoding.
573 
574  Ptr<Packet> encodedHandoverCommand = params.rrcContext;
575  LteRrcSap::RrcConnectionReconfiguration handoverCommand = m_rrc->m_rrcSapUser->DecodeHandoverCommand (encodedHandoverCommand);
578  NS_ASSERT (handoverCommand.haveMobilityControlInfo);
580 
582  sst.oldEnbUeX2apId = params.oldEnbUeX2apId;
583  sst.newEnbUeX2apId = params.newEnbUeX2apId;
584  sst.sourceCellId = params.sourceCellId;
585  sst.targetCellId = params.targetCellId;
586  for ( std::map <uint8_t, Ptr<LteDataRadioBearerInfo> >::iterator drbIt = m_drbMap.begin ();
587  drbIt != m_drbMap.end ();
588  ++drbIt)
589  {
590  // SN status transfer is only for AM RLC
591  if (0 != drbIt->second->m_rlc->GetObject<LteRlcAm> ())
592  {
593  LtePdcp::Status status = drbIt->second->m_pdcp->GetStatus ();
595  i.dlPdcpSn = status.txSn;
596  i.ulPdcpSn = status.rxSn;
597  sst.erabsSubjectToStatusTransferList.push_back (i);
598  }
599  }
601 }
602 
603 
606 {
607  NS_LOG_FUNCTION (this);
609 }
610 
613 {
614  NS_LOG_FUNCTION (this);
616 }
617 
618 void
620 {
621  NS_LOG_FUNCTION (this << p << (uint16_t) bid);
622  switch (m_state)
623  {
625  case CONNECTION_SETUP:
626  NS_LOG_WARN ("not connected, discarding packet");
627  return;
628  break;
629 
630  case CONNECTED_NORMALLY:
634  case HANDOVER_JOINING:
636  {
637  NS_LOG_LOGIC ("queueing data on PDCP for transmission over the air");
639  params.pdcpSdu = p;
640  params.rnti = m_rnti;
641  params.lcid = Bid2Lcid (bid);
642  uint8_t drbid = Bid2Drbid (bid);
644  pdcpSapProvider->TransmitPdcpSdu (params);
645  }
646  break;
647 
648  case HANDOVER_LEAVING:
649  {
650  NS_LOG_LOGIC ("forwarding data to target eNB over X2-U");
651  uint8_t drbid = Bid2Drbid (bid);
652  EpcX2Sap::UeDataParams params;
653  params.sourceCellId = m_rrc->m_cellId;
654  params.targetCellId = m_targetCellId;
655  params.gtpTeid = GetDataRadioBearerInfo (drbid)->m_gtpTeid;
656  params.ueData = p;
657  m_rrc->m_x2SapProvider->SendUeData (params);
658  }
659  break;
660 
661  default:
662  NS_FATAL_ERROR ("method unexpected in state " << ToString (m_state));
663  break;
664  }
665 }
666 
667 std::vector<EpcX2Sap::ErabToBeSetupItem>
669 {
670  NS_LOG_FUNCTION (this);
671  std::vector<EpcX2Sap::ErabToBeSetupItem> ret;
672  for (std::map <uint8_t, Ptr<LteDataRadioBearerInfo> >::iterator it = m_drbMap.begin ();
673  it != m_drbMap.end ();
674  ++it)
675  {
677  etbsi.erabId = it->second->m_epsBearerIdentity;
678  etbsi.erabLevelQosParameters = it->second->m_epsBearer;
679  etbsi.dlForwarding = false;
680  etbsi.transportLayerAddress = it->second->m_transportLayerAddress;
681  etbsi.gtpTeid = it->second->m_gtpTeid;
682  ret.push_back (etbsi);
683  }
684  return ret;
685 }
686 
687 void
689 {
690  NS_LOG_FUNCTION (this);
691  switch (m_state)
692  {
694  NS_LOG_INFO ("Send UE CONTEXT RELEASE from target eNB to source eNB");
695  EpcX2SapProvider::UeContextReleaseParams ueCtxReleaseParams;
696  ueCtxReleaseParams.oldEnbUeX2apId = m_sourceX2apId;
697  ueCtxReleaseParams.newEnbUeX2apId = m_rnti;
698  ueCtxReleaseParams.sourceCellId = m_sourceCellId;
699  m_rrc->m_x2SapProvider->SendUeContextRelease (ueCtxReleaseParams);
702  break;
703 
704  default:
705  NS_FATAL_ERROR ("method unexpected in state " << ToString (m_state));
706  break;
707  }
708 }
709 
710 void
712 {
713  NS_LOG_FUNCTION (this << cellId);
714  switch (m_state)
715  {
716  case HANDOVER_PREPARATION:
717  NS_ASSERT (cellId == m_targetCellId);
718  NS_LOG_INFO ("target eNB sent HO preparation failure, aborting HO");
720  break;
721 
722  default:
723  NS_FATAL_ERROR ("method unexpected in state " << ToString (m_state));
724  break;
725  }
726 }
727 
728 void
730 {
731  NS_LOG_FUNCTION (this);
732  for (std::vector<EpcX2Sap::ErabsSubjectToStatusTransferItem>::iterator erabIt
733  = params.erabsSubjectToStatusTransferList.begin ();
734  erabIt != params.erabsSubjectToStatusTransferList.end ();
735  ++erabIt)
736  {
737  // LtePdcp::Status status;
738  // status.txSn = erabIt->dlPdcpSn;
739  // status.rxSn = erabIt->ulPdcpSn;
740  // uint8_t drbId = Bid2Drbid (erabIt->erabId);
741  // std::map <uint8_t, Ptr<LteDataRadioBearerInfo> >::iterator drbIt = m_drbMap.find (drbId);
742  // NS_ASSERT_MSG (drbIt != m_drbMap.end (), "could not find DRBID " << (uint32_t) drbId);
743  // drbIt->second->m_pdcp->SetStatus (status);
744  }
745 }
746 
747 // methods forwarded from RRC SAP
748 
749 void
751 {
752  NS_LOG_FUNCTION (this);
755 }
756 
757 void
759 {
760  NS_LOG_FUNCTION (this);
761  switch (m_state)
762  {
763  case INITIAL_RANDOM_ACCESS:
764  {
765  if (m_rrc->m_admitRrcConnectionRequest == true)
766  {
768  m_imsi = msg.ueIdentity;
769  if (m_rrc->m_s1SapProvider != 0)
770  {
772  }
779  }
780  else
781  {
783  NS_LOG_INFO ("rejecting connection request for RNTI " << m_rnti);
785  rejectMsg.waitTime = 3;
787  Time maxRecvConnRejectDelay = MilliSeconds (30);
790  }
791  }
792  break;
793 
794  default:
795  NS_FATAL_ERROR ("method unexpected in state " << ToString (m_state));
796  break;
797  }
798 }
799 
800 void
802 {
803  NS_LOG_FUNCTION (this);
804  switch (m_state)
805  {
806  case CONNECTION_SETUP:
810  break;
811 
812  default:
813  NS_FATAL_ERROR ("method unexpected in state " << ToString (m_state));
814  break;
815  }
816 }
817 
818 void
820 {
821  NS_LOG_FUNCTION (this);
822  switch (m_state)
823  {
827  {
828  // configure MAC (and scheduler)
830  req.m_rnti = m_rnti;
833 
834  // configure PHY
836 
838  }
841  break;
842 
843  case HANDOVER_LEAVING:
844  NS_LOG_INFO ("ignoring RecvRrcConnectionReconfigurationCompleted in state " << ToString (m_state));
845  break;
846 
847  case HANDOVER_JOINING:
848  {
850  NS_LOG_INFO ("Send PATH SWITCH REQUEST to the MME");
852  params.rnti = m_rnti;
853  params.cellId = m_rrc->m_cellId;
854  params.mmeUeS1Id = m_imsi;
856  for (std::map <uint8_t, Ptr<LteDataRadioBearerInfo> >::iterator it = m_drbMap.begin ();
857  it != m_drbMap.end ();
858  ++it)
859  {
861  b.epsBearerId = it->second->m_epsBearerIdentity;
862  b.teid = it->second->m_gtpTeid;
863  params.bearersToBeSwitched.push_back (b);
864  }
866  }
867  break;
868 
869  default:
870  NS_FATAL_ERROR ("method unexpected in state " << ToString (m_state));
871  break;
872  }
873 }
874 
875 void
877 {
878  NS_LOG_FUNCTION (this);
884 }
885 
886 void
888 {
889  NS_LOG_FUNCTION (this);
891 }
892 
893 void
895 {
896  NS_LOG_FUNCTION (this);
897 }
898 
899 
900 // methods forwarded from CMAC SAP
901 
902 void
904 {
905  NS_LOG_FUNCTION (this << m_rnti);
906  // at this stage used only by the scheduler for updating txMode
907 
909 
911 
912  // reconfigure the UE RRC
914 }
915 
916 
917 // methods forwarded from PDCP SAP
918 
919 void
921 {
922  NS_LOG_FUNCTION (this);
923  if (params.lcid > 2)
924  {
925  // data radio bearer
926  EpsBearerTag tag;
927  tag.SetRnti (params.rnti);
928  tag.SetBid (Lcid2Bid (params.lcid));
929  params.pdcpSdu->AddPacketTag (tag);
931  }
932 }
933 
934 
935 uint16_t
937 {
938  return m_rnti;
939 }
940 
941 uint64_t
943 {
944  return m_imsi;
945 }
946 
947 uint16_t
949 {
951 }
952 
953 void
954 UeManager::SetSrsConfigurationIndex (uint16_t srsConfIndex)
955 {
956  NS_LOG_FUNCTION (this);
959  switch (m_state)
960  {
962  // do nothing, srs conf index will be correctly enforced upon
963  // RRC connection establishment
964  break;
965 
966  default:
968  break;
969  }
970 }
971 
974 {
975  return m_state;
976 }
977 
978 uint8_t
980 {
981  NS_LOG_FUNCTION (this);
982  const uint8_t MAX_DRB_ID = 32;
983  for (uint8_t drbid = (m_lastAllocatedDrbid + 1) % MAX_DRB_ID;
984  drbid != m_lastAllocatedDrbid;
985  drbid = (drbid + 1) % MAX_DRB_ID)
986  {
987  if (drbid != 0) // 0 is not allowed
988  {
989  if (m_drbMap.find (drbid) == m_drbMap.end ())
990  {
991  m_drbMap.insert (std::pair<uint8_t, Ptr<LteDataRadioBearerInfo> > (drbid, drbInfo));
992  drbInfo->m_drbIdentity = drbid;
993  m_lastAllocatedDrbid = drbid;
994  return drbid;
995  }
996  }
997  }
998  NS_FATAL_ERROR ("no more data radio bearer ids available");
999  return 0;
1000 }
1001 
1004 {
1005  NS_LOG_FUNCTION (this << (uint32_t) drbid);
1006  NS_ASSERT (0 != drbid);
1007  std::map<uint8_t, Ptr<LteDataRadioBearerInfo> >::iterator it = m_drbMap.find (drbid);
1008  NS_ABORT_IF (it == m_drbMap.end ());
1009  return it->second;
1010 }
1011 
1012 
1013 void
1015 {
1016  NS_LOG_FUNCTION (this << (uint32_t) drbid);
1017  std::map <uint8_t, Ptr<LteDataRadioBearerInfo> >::iterator it = m_drbMap.find (drbid);
1018  NS_ASSERT_MSG (it != m_drbMap.end (), "request to remove radio bearer with unknown drbid " << drbid);
1019  m_drbMap.erase (it);
1020 }
1021 
1022 
1025 {
1030  msg.haveMobilityControlInfo = false;
1031  msg.haveMeasConfig = false;
1032  return msg;
1033 }
1034 
1037 {
1039 
1040  if (m_srb1 != 0)
1041  {
1045  rrcd.srbToAddModList.push_back (stam);
1046  }
1047 
1048  for (std::map <uint8_t, Ptr<LteDataRadioBearerInfo> >::iterator it = m_drbMap.begin ();
1049  it != m_drbMap.end ();
1050  ++it)
1051  {
1053  dtam.epsBearerIdentity = it->second->m_epsBearerIdentity;
1054  dtam.drbIdentity = it->second->m_drbIdentity;
1055  dtam.rlcConfig = it->second->m_rlcConfig;
1056  dtam.logicalChannelIdentity = it->second->m_logicalChannelIdentity;
1057  dtam.logicalChannelConfig = it->second->m_logicalChannelConfig;
1058  rrcd.drbToAddModList.push_back (dtam);
1059  }
1060 
1061  rrcd.havePhysicalConfigDedicated = true;
1063  return rrcd;
1064 }
1065 
1066 uint8_t
1068 {
1070 }
1071 
1072 uint8_t
1074 {
1075  NS_ASSERT (lcid > 2);
1076  return lcid - 2;
1077 }
1078 
1079 uint8_t
1080 UeManager::Drbid2Lcid (uint8_t drbid)
1081 {
1082  return drbid + 2;
1083 }
1084 uint8_t
1085 UeManager::Lcid2Bid (uint8_t lcid)
1086 {
1087  NS_ASSERT (lcid > 2);
1088  return lcid - 2;
1089 }
1090 
1091 uint8_t
1092 UeManager::Bid2Lcid (uint8_t bid)
1093 {
1094  return bid + 2;
1095 }
1096 
1097 uint8_t
1098 UeManager::Drbid2Bid (uint8_t drbid)
1099 {
1100  return drbid;
1101 }
1102 
1103 uint8_t
1105 {
1106  return bid;
1107 }
1108 
1109 
1110 void
1112 {
1113  NS_LOG_FUNCTION (this << newState);
1114  State oldState = m_state;
1115  m_state = newState;
1116  NS_LOG_INFO ("IMSI " << m_imsi << " RNTI " << m_rnti << " UeManager " << ToString (oldState) << " --> " << ToString (newState));
1117  m_stateTransitionTrace (m_imsi, m_rrc->m_cellId, m_rnti, oldState, newState);
1118 
1119  switch (newState)
1120  {
1121  case INITIAL_RANDOM_ACCESS:
1122  case HANDOVER_JOINING:
1123  NS_FATAL_ERROR ("cannot switch to an initial state");
1124  break;
1125 
1126  case CONNECTION_SETUP:
1127  break;
1128 
1129  case CONNECTED_NORMALLY:
1130  {
1132  {
1134  }
1135  }
1136  break;
1137 
1139  break;
1140 
1142  break;
1143 
1144  case HANDOVER_LEAVING:
1145  break;
1146 
1147  default:
1148  break;
1149  }
1150 }
1151 
1152 
1153 
1154 // ///////////////////////////
1155 // eNB RRC methods
1156 // ///////////////////////////
1157 
1159 
1161  : m_x2SapProvider (0),
1162  m_cmacSapProvider (0),
1163  m_rrcSapUser (0),
1164  m_macSapProvider (0),
1165  m_s1SapProvider (0),
1166  m_cphySapProvider (0),
1167  m_configured (false),
1168  m_lastAllocatedRnti (0),
1169  m_srsCurrentPeriodicityId (0),
1170  m_lastAllocatedConfigurationIndex (0),
1171  m_reconfigureUes (false)
1172 {
1173  NS_LOG_FUNCTION (this);
1179 
1180 
1181 }
1182 
1183 
1185 {
1186  NS_LOG_FUNCTION (this);
1187 }
1188 
1189 
1190 void
1192 {
1193  NS_LOG_FUNCTION (this);
1194  m_ueMap.clear ();
1195  delete m_cmacSapUser;
1196  delete m_rrcSapProvider;
1197  delete m_x2SapUser;
1198  delete m_s1SapUser;
1199  delete m_cphySapUser;
1200 }
1201 
1202 TypeId
1204 {
1205  NS_LOG_FUNCTION ("LteEnbRrc::GetTypeId");
1206  static TypeId tid = TypeId ("ns3::LteEnbRrc")
1207  .SetParent<Object> ()
1208  .AddConstructor<LteEnbRrc> ()
1209  .AddAttribute ("UeMap", "List of UeManager by C-RNTI.",
1210  ObjectMapValue (),
1212  MakeObjectMapChecker<UeManager> ())
1213  .AddAttribute ("DefaultTransmissionMode",
1214  "The default UEs' transmission mode (0: SISO)",
1215  UintegerValue (0), // default tx-mode
1216  MakeUintegerAccessor (&LteEnbRrc::m_defaultTransmissionMode),
1217  MakeUintegerChecker<uint8_t> ())
1218  .AddAttribute ("EpsBearerToRlcMapping",
1219  "Specify which type of RLC will be used for each type of EPS bearer. ",
1222  MakeEnumChecker (RLC_SM_ALWAYS, "RlcSmAlways",
1223  RLC_UM_ALWAYS, "RlcUmAlways",
1224  RLC_AM_ALWAYS, "RlcAmAlways",
1225  PER_BASED, "PacketErrorRateBased"))
1226  .AddAttribute ("SystemInformationPeriodicity",
1227  "The interval for sending system information (Time value)",
1228  TimeValue (MilliSeconds (80)),
1229  MakeTimeAccessor (&LteEnbRrc::m_systemInformationPeriodicity),
1230  MakeTimeChecker ())
1231  .AddAttribute ("SrsPeriodicity",
1232  "The SRS periodicity in milliseconds",
1233  UintegerValue (40),
1234  MakeUintegerAccessor (&LteEnbRrc::SetSrsPeriodicity,
1236  MakeUintegerChecker<uint32_t> ())
1237  .AddAttribute ("AdmitHandoverRequest",
1238  "Whether to admit an X2 handover request from another eNB",
1239  BooleanValue (true),
1240  MakeBooleanAccessor (&LteEnbRrc::m_admitHandoverRequest),
1241  MakeBooleanChecker ())
1242  .AddAttribute ("AdmitRrcConnectionRequest",
1243  "Whether to admit a connection request from a Ue",
1244  BooleanValue (true),
1245  MakeBooleanAccessor (&LteEnbRrc::m_admitRrcConnectionRequest),
1246  MakeBooleanChecker ())
1247  .AddTraceSource ("NewUeContext",
1248  "trace fired upon creation of a new UE context",
1250  .AddTraceSource ("ConnectionEstablished",
1251  "trace fired upon successful RRC connection establishment",
1253  .AddTraceSource ("ConnectionReconfiguration",
1254  "trace fired upon RRC connection reconfiguration",
1256  .AddTraceSource ("HandoverStart",
1257  "trace fired upon start of a handover procedure",
1259  .AddTraceSource ("HandoverEndOk",
1260  "trace fired upon successful termination of a handover procedure",
1262  ;
1263  return tid;
1264 }
1265 
1266 void
1268 {
1269  NS_LOG_FUNCTION (this << s);
1270  m_x2SapProvider = s;
1271 }
1272 
1273 EpcX2SapUser*
1275 {
1276  NS_LOG_FUNCTION (this);
1277  return m_x2SapUser;
1278 }
1279 
1280 void
1282 {
1283  NS_LOG_FUNCTION (this << s);
1284  m_cmacSapProvider = s;
1285 }
1286 
1289 {
1290  NS_LOG_FUNCTION (this);
1291  return m_cmacSapUser;
1292 }
1293 
1294 void
1296 {
1297  NS_LOG_FUNCTION (this << s);
1298  m_rrcSapUser = s;
1299 }
1300 
1303 {
1304  NS_LOG_FUNCTION (this);
1305  return m_rrcSapProvider;
1306 }
1307 
1308 void
1310 {
1311  NS_LOG_FUNCTION (this);
1312  m_macSapProvider = s;
1313 }
1314 
1315 void
1317 {
1318  m_s1SapProvider = s;
1319 }
1320 
1321 
1324 {
1325  return m_s1SapUser;
1326 }
1327 
1328 void
1330 {
1331  NS_LOG_FUNCTION (this << s);
1332  m_cphySapProvider = s;
1333 }
1334 
1337 {
1338  NS_LOG_FUNCTION (this);
1339  return m_cphySapUser;
1340 }
1341 
1344 {
1345  NS_LOG_FUNCTION (this << (uint32_t) rnti);
1346  NS_ASSERT (0 != rnti);
1347  std::map<uint16_t, Ptr<UeManager> >::iterator it = m_ueMap.find (rnti);
1348  NS_ASSERT_MSG (it != m_ueMap.end (), "RNTI " << rnti << " not found in eNB with cellId " << m_cellId);
1349  return it->second;
1350 }
1351 
1352 void
1353 LteEnbRrc::ConfigureCell (uint8_t ulBandwidth, uint8_t dlBandwidth, uint16_t ulEarfcn, uint16_t dlEarfcn, uint16_t cellId)
1354 {
1355  NS_LOG_FUNCTION (this);
1357  m_cmacSapProvider->ConfigureMac (ulBandwidth, dlBandwidth);
1358  m_cphySapProvider->SetBandwidth (ulBandwidth, dlBandwidth);
1359  m_cphySapProvider->SetEarfcn (ulEarfcn, dlEarfcn);
1360  m_dlEarfcn = dlEarfcn;
1361  m_ulEarfcn = ulEarfcn;
1362  m_dlBandwidth = dlBandwidth;
1363  m_ulBandwidth = ulBandwidth;
1364  m_cellId = cellId;
1365  m_cphySapProvider->SetCellId (cellId);
1367  mib.dlBandwidth = m_dlBandwidth;
1369  m_configured = true;
1370 
1371  // the first time System Information is sent
1373 }
1374 
1375 
1376 void
1377 LteEnbRrc::SetCellId (uint16_t cellId)
1378 {
1379  m_cellId = cellId;
1380 }
1381 
1382 bool
1384 {
1385  NS_LOG_FUNCTION (this << packet);
1386 
1387  EpsBearerTag tag;
1388  bool found = packet->RemovePacketTag (tag);
1389  NS_ASSERT_MSG (found, "no EpsBearerTag found in packet to be sent");
1390  Ptr<UeManager> ueManager = GetUeManager (tag.GetRnti ());
1391  ueManager->SendData (tag.GetBid (), packet);
1392 
1393  return true;
1394 }
1395 
1396 void
1398 {
1399  m_forwardUpCallback = cb;
1400 }
1401 
1402 void
1404 {
1405  NS_LOG_FUNCTION (this << rnti);
1406  RemoveUe (rnti);
1407 }
1408 
1409 
1410 void
1411 LteEnbRrc::SendHandoverRequest (uint16_t rnti, uint16_t cellId)
1412 {
1413  NS_LOG_FUNCTION (this << rnti << cellId);
1414  NS_LOG_LOGIC ("Request to send HANDOVER REQUEST");
1416 
1417  Ptr<UeManager> ueManager = GetUeManager (rnti);
1418  ueManager->PrepareHandover (cellId);
1419 
1420 }
1421 
1422 void
1424 {
1425  NS_LOG_FUNCTION (this << rnti);
1426  GetUeManager (rnti)->CompleteSetupUe (params);
1427 }
1428 
1429 void
1431 {
1432  NS_LOG_FUNCTION (this << rnti);
1433 
1434  GetUeManager (rnti)->RecvRrcConnectionRequest (msg);
1435 }
1436 
1437 void
1439 {
1440  NS_LOG_FUNCTION (this << rnti);
1442 }
1443 
1444 void
1446 {
1447  NS_LOG_FUNCTION (this << rnti);
1449 }
1450 
1451 void
1453 {
1454  NS_LOG_FUNCTION (this << rnti);
1456 }
1457 
1458 void
1460 {
1461  NS_LOG_FUNCTION (this << rnti);
1463 }
1464 
1465 void
1467 {
1468  NS_LOG_FUNCTION (this << rnti);
1469  GetUeManager (rnti)->RecvMeasurementReport (msg);
1470 }
1471 
1472 void
1474 {
1475  Ptr<UeManager> ueManager = GetUeManager (request.rnti);
1476  ueManager->SetupDataRadioBearer (request.bearer, request.bearerId, request.gtpTeid, request.transportLayerAddress);
1477 }
1478 
1479 void
1481 {
1482  Ptr<UeManager> ueManager = GetUeManager (params.rnti);
1483  ueManager->SendUeContextRelease ();
1484 }
1485 
1486 void
1488 {
1489  NS_LOG_FUNCTION (this);
1490 
1491  NS_LOG_LOGIC ("Recv X2 message: HANDOVER REQUEST");
1492 
1493  NS_LOG_LOGIC ("oldEnbUeX2apId = " << req.oldEnbUeX2apId);
1494  NS_LOG_LOGIC ("sourceCellId = " << req.sourceCellId);
1495  NS_LOG_LOGIC ("targetCellId = " << req.targetCellId);
1496  NS_LOG_LOGIC ("mmeUeS1apId = " << req.mmeUeS1apId);
1497 
1498  NS_ASSERT (req.targetCellId == m_cellId);
1499 
1500  if (m_admitHandoverRequest == false)
1501  {
1502  NS_LOG_INFO ("rejecting handover request from cellId " << req.sourceCellId);
1504  res.oldEnbUeX2apId = req.oldEnbUeX2apId;
1505  res.sourceCellId = req.sourceCellId ;
1506  res.targetCellId = req.targetCellId ;
1507  res.cause = 0;
1508  res.criticalityDiagnostics = 0;
1510  return;
1511  }
1512 
1513  uint16_t rnti = AddUe (UeManager::HANDOVER_JOINING);
1515  if (anrcrv.valid == false)
1516  {
1517  NS_LOG_INFO (this << "failed to allocate a preamble for non-contention based RA => cannot accept HO");
1518  RemoveUe (rnti);
1519  NS_FATAL_ERROR ("should trigger HO Preparation Failure, but it is not implemented");
1520  return;
1521  }
1522 
1523  Ptr<UeManager> ueManager = GetUeManager (rnti);
1524  ueManager->SetSource (req.sourceCellId, req.oldEnbUeX2apId);
1525  ueManager->SetImsi (req.mmeUeS1apId);
1526 
1528  ackParams.oldEnbUeX2apId = req.oldEnbUeX2apId;
1529  ackParams.newEnbUeX2apId = rnti;
1530  ackParams.sourceCellId = req.sourceCellId;
1531  ackParams.targetCellId = req.targetCellId;
1532 
1533  for (std::vector <EpcX2Sap::ErabToBeSetupItem>::iterator it = req.bearers.begin ();
1534  it != req.bearers.end ();
1535  ++it)
1536  {
1537  ueManager->SetupDataRadioBearer (it->erabLevelQosParameters, it->erabId, it->gtpTeid, it->transportLayerAddress);
1539  i.erabId = it->erabId;
1540  ackParams.admittedBearers.push_back (i);
1541  }
1542 
1544  handoverCommand.haveMobilityControlInfo = true;
1545  handoverCommand.mobilityControlInfo.targetPhysCellId = m_cellId;
1546  handoverCommand.mobilityControlInfo.haveCarrierFreq = true;
1549  handoverCommand.mobilityControlInfo.haveCarrierBandwidth = true;
1552  handoverCommand.mobilityControlInfo.newUeIdentity = rnti;
1553  handoverCommand.mobilityControlInfo.haveRachConfigDedicated = true;
1556 
1561 
1562  Ptr<Packet> encodedHandoverCommand = m_rrcSapUser->EncodeHandoverCommand (handoverCommand);
1563 
1564  ackParams.rrcContext = encodedHandoverCommand;
1565 
1566  NS_LOG_LOGIC ("Send X2 message: HANDOVER REQUEST ACK");
1567 
1568  NS_LOG_LOGIC ("oldEnbUeX2apId = " << ackParams.oldEnbUeX2apId);
1569  NS_LOG_LOGIC ("newEnbUeX2apId = " << ackParams.newEnbUeX2apId);
1570  NS_LOG_LOGIC ("sourceCellId = " << ackParams.sourceCellId);
1571  NS_LOG_LOGIC ("targetCellId = " << ackParams.targetCellId);
1572 
1574 }
1575 
1576 void
1578 {
1579  NS_LOG_FUNCTION (this);
1580 
1581  NS_LOG_LOGIC ("Recv X2 message: HANDOVER REQUEST ACK");
1582 
1583  NS_LOG_LOGIC ("oldEnbUeX2apId = " << params.oldEnbUeX2apId);
1584  NS_LOG_LOGIC ("newEnbUeX2apId = " << params.newEnbUeX2apId);
1585  NS_LOG_LOGIC ("sourceCellId = " << params.sourceCellId);
1586  NS_LOG_LOGIC ("targetCellId = " << params.targetCellId);
1587 
1588  uint16_t rnti = params.oldEnbUeX2apId;
1589  Ptr<UeManager> ueManager = GetUeManager (rnti);
1590  ueManager->RecvHandoverRequestAck (params);
1591 }
1592 
1593 void
1595 {
1596  NS_LOG_FUNCTION (this);
1597 
1598  NS_LOG_LOGIC ("Recv X2 message: HANDOVER PREPARATION FAILURE");
1599 
1600  NS_LOG_LOGIC ("oldEnbUeX2apId = " << params.oldEnbUeX2apId);
1601  NS_LOG_LOGIC ("sourceCellId = " << params.sourceCellId);
1602  NS_LOG_LOGIC ("targetCellId = " << params.targetCellId);
1603  NS_LOG_LOGIC ("cause = " << params.cause);
1604  NS_LOG_LOGIC ("criticalityDiagnostics = " << params.criticalityDiagnostics);
1605 
1606  uint16_t rnti = params.oldEnbUeX2apId;
1607  Ptr<UeManager> ueManager = GetUeManager (rnti);
1608  ueManager->RecvHandoverPreparationFailure (params.targetCellId);
1609 }
1610 
1611 void
1613 {
1614  NS_LOG_FUNCTION (this);
1615 
1616  NS_LOG_LOGIC ("Recv X2 message: SN STATUS TRANSFER");
1617 
1618  NS_LOG_LOGIC ("oldEnbUeX2apId = " << params.oldEnbUeX2apId);
1619  NS_LOG_LOGIC ("newEnbUeX2apId = " << params.newEnbUeX2apId);
1620  NS_LOG_LOGIC ("erabsSubjectToStatusTransferList size = " << params.erabsSubjectToStatusTransferList.size ());
1621 
1622  uint16_t rnti = params.newEnbUeX2apId;
1623  Ptr<UeManager> ueManager = GetUeManager (rnti);
1624  ueManager->RecvSnStatusTransfer (params);
1625 }
1626 
1627 void
1629 {
1630  NS_LOG_FUNCTION (this);
1631 
1632  NS_LOG_LOGIC ("Recv X2 message: UE CONTEXT RELEASE");
1633 
1634  NS_LOG_LOGIC ("oldEnbUeX2apId = " << params.oldEnbUeX2apId);
1635  NS_LOG_LOGIC ("newEnbUeX2apId = " << params.newEnbUeX2apId);
1636 
1637  uint16_t rnti = params.oldEnbUeX2apId;
1638  RemoveUe (rnti);
1639 }
1640 
1641 void
1643 {
1644  NS_LOG_FUNCTION (this);
1645 
1646  NS_LOG_LOGIC ("Recv X2 message: LOAD INFORMATION");
1647 
1648  NS_LOG_LOGIC ("Number of cellInformationItems = " << params.cellInformationList.size ());
1649 
1650  NS_ASSERT ("Processing of LOAD INFORMATION X2 message IS NOT IMPLEMENTED");
1651 }
1652 
1653 void
1655 {
1656  NS_LOG_FUNCTION (this);
1657 
1658  NS_LOG_LOGIC ("Recv X2 message: RESOURCE STATUS UPDATE");
1659 
1660  NS_LOG_LOGIC ("Number of cellMeasurementResultItems = " << params.cellMeasurementResultList.size ());
1661 
1662  NS_ASSERT ("Processing of RESOURCE STATUS UPDATE X2 message IS NOT IMPLEMENTED");
1663 }
1664 
1665 void
1667 {
1668  NS_LOG_FUNCTION (this);
1669 
1670  NS_LOG_LOGIC ("Recv UE DATA FORWARDING through X2 interface");
1671  NS_LOG_LOGIC ("sourceCellId = " << params.sourceCellId);
1672  NS_LOG_LOGIC ("targetCellId = " << params.targetCellId);
1673  NS_LOG_LOGIC ("gtpTeid = " << params.gtpTeid);
1674  NS_LOG_LOGIC ("ueData = " << params.ueData);
1675  NS_LOG_LOGIC ("ueData size = " << params.ueData->GetSize ());
1676 
1677  std::map<uint32_t, X2uTeidInfo>::iterator
1678  teidInfoIt = m_x2uTeidInfoMap.find (params.gtpTeid);
1679  if (teidInfoIt != m_x2uTeidInfoMap.end ())
1680  {
1681  GetUeManager (teidInfoIt->second.rnti)->SendData (teidInfoIt->second.drbid, params.ueData);
1682  }
1683  else
1684  {
1685  NS_FATAL_ERROR ("X2-U data received but no X2uTeidInfo found");
1686  }
1687 }
1688 
1689 
1690 uint16_t
1692 {
1693  NS_LOG_FUNCTION (this);
1695 }
1696 
1697 void
1699 {
1700  Ptr<UeManager> ueManager = GetUeManager (cmacParams.m_rnti);
1701  ueManager->CmacUeConfigUpdateInd (cmacParams);
1702 }
1703 
1704 void
1705 LteEnbRrc::DoNotifyLcConfigResult (uint16_t rnti, uint8_t lcid, bool success)
1706 {
1707  NS_LOG_FUNCTION (this << (uint32_t) rnti);
1708  NS_FATAL_ERROR ("not implemented");
1709 }
1710 
1711 
1712 
1713 uint16_t
1715 {
1716  NS_LOG_FUNCTION (this);
1717  bool found = false;
1718  uint16_t rnti;
1719  for (rnti = m_lastAllocatedRnti;
1720  (rnti != m_lastAllocatedRnti - 1) && (!found);
1721  ++rnti)
1722  {
1723  if ((rnti != 0) && (m_ueMap.find (rnti) == m_ueMap.end ()))
1724  {
1725  found = true;
1726  break;
1727  }
1728  }
1729 
1730  NS_ASSERT_MSG (found, "no more RNTIs available (do you have more than 65535 UEs in a cell?)");
1731  m_lastAllocatedRnti = rnti;
1732  Ptr<UeManager> ueManager = CreateObject<UeManager> (this, rnti, state);
1733  m_ueMap.insert (std::pair<uint16_t, Ptr<UeManager> > (rnti, ueManager));
1734  ueManager->Initialize ();
1735  NS_LOG_DEBUG (this << " New UE RNTI " << rnti << " cellId " << m_cellId << " srs CI " << ueManager->GetSrsConfigurationIndex ());
1736  m_newUeContextTrace (m_cellId, rnti);
1737  return rnti;
1738 }
1739 
1740 void
1741 LteEnbRrc::RemoveUe (uint16_t rnti)
1742 {
1743  NS_LOG_FUNCTION (this << (uint32_t) rnti);
1744  std::map <uint16_t, Ptr<UeManager> >::iterator it = m_ueMap.find (rnti);
1745  NS_ASSERT_MSG (it != m_ueMap.end (), "request to remove UE info with unknown rnti " << rnti);
1746  uint16_t srsCi = (*it).second->GetSrsConfigurationIndex ();
1747  m_ueMap.erase (it);
1748  m_cmacSapProvider->RemoveUe (rnti);
1749  m_cphySapProvider->RemoveUe (rnti);
1750  if (m_s1SapProvider != 0)
1751  {
1753  }
1754  // need to do this after UeManager has been deleted
1755  RemoveSrsConfigurationIndex (srsCi);
1756  }
1757 
1758 TypeId
1760 {
1761  switch (m_epsBearerToRlcMapping)
1762  {
1763  case RLC_SM_ALWAYS:
1764  return LteRlcSm::GetTypeId ();
1765  break;
1766 
1767  case RLC_UM_ALWAYS:
1768  return LteRlcUm::GetTypeId ();
1769  break;
1770 
1771  case RLC_AM_ALWAYS:
1772  return LteRlcAm::GetTypeId ();
1773  break;
1774 
1775  case PER_BASED:
1776  if (bearer.GetPacketErrorLossRate () > 1.0e-5)
1777  {
1778  return LteRlcUm::GetTypeId ();
1779  }
1780  else
1781  {
1782  return LteRlcAm::GetTypeId ();
1783  }
1784  break;
1785 
1786  default:
1787  return LteRlcSm::GetTypeId ();
1788  break;
1789  }
1790 }
1791 
1792 
1793 
1794 
1795 // from 3GPP TS 36.213 table 8.2-1 UE Specific SRS Periodicity
1796 const uint8_t SRS_ENTRIES = 9;
1797 uint16_t g_srsPeriodicity[SRS_ENTRIES] = {0, 2, 5, 10, 20, 40, 80, 160, 320};
1798 uint16_t g_srsCiLow[SRS_ENTRIES] = {0, 0, 2, 7, 17, 37, 77, 157, 317};
1799 uint16_t g_srsCiHigh[SRS_ENTRIES] = {0, 1, 6, 16, 36, 76, 156, 316, 636};
1800 
1801 void
1803 {
1804  NS_LOG_FUNCTION (this << p);
1805  for (uint32_t id = 1; id < SRS_ENTRIES; ++id)
1806  {
1807  if (g_srsPeriodicity[id] == p)
1808  {
1810  return;
1811  }
1812  }
1813  // no match found
1814  std::ostringstream allowedValues;
1815  for (uint32_t id = 1; id < SRS_ENTRIES; ++id)
1816  {
1817  allowedValues << g_srsPeriodicity[id] << " ";
1818  }
1819  NS_FATAL_ERROR ("illecit SRS periodicity value " << p << ". Allowed values: " << allowedValues.str ());
1820 }
1821 
1822 uint32_t
1824 {
1825  NS_LOG_FUNCTION (this);
1829 }
1830 
1831 
1832 uint16_t
1834 {
1836  // SRS
1839  NS_LOG_DEBUG (this << " SRS p " << g_srsPeriodicity[m_srsCurrentPeriodicityId] << " set " << m_ueSrsConfigurationIndexSet.size ());
1841  {
1842  NS_FATAL_ERROR ("too many UEs (" << m_ueSrsConfigurationIndexSet.size () + 1
1843  << ") for current SRS periodicity "
1845  << ", consider increasing the value of ns3::LteEnbRrc::SrsPeriodicity");
1846  }
1847 
1848  if (m_ueSrsConfigurationIndexSet.empty ())
1849  {
1850  // first entry
1853  }
1854  else
1855  {
1856  // find a CI from the available ones
1857  std::set<uint16_t>::reverse_iterator rit = m_ueSrsConfigurationIndexSet.rbegin ();
1858  NS_ASSERT (rit != m_ueSrsConfigurationIndexSet.rend ());
1859  NS_LOG_DEBUG (this << " lower bound " << (*rit) << " of " << g_srsCiHigh[m_srsCurrentPeriodicityId]);
1860  if ((*rit) < g_srsCiHigh[m_srsCurrentPeriodicityId])
1861  {
1862  // got it from the upper bound
1863  m_lastAllocatedConfigurationIndex = (*rit) + 1;
1865  }
1866  else
1867  {
1868  // look for released ones
1869  for (uint16_t srcCi = g_srsCiLow[m_srsCurrentPeriodicityId]; srcCi < g_srsCiHigh[m_srsCurrentPeriodicityId]; srcCi++)
1870  {
1871  std::set<uint16_t>::iterator it = m_ueSrsConfigurationIndexSet.find (srcCi);
1872  if (it==m_ueSrsConfigurationIndexSet.end ())
1873  {
1875  m_ueSrsConfigurationIndexSet.insert (srcCi);
1876  break;
1877  }
1878  }
1879  }
1880  }
1882 
1883 }
1884 
1885 
1886 void
1888 {
1889  NS_LOG_FUNCTION (this << srcCi);
1890  std::set<uint16_t>::iterator it = m_ueSrsConfigurationIndexSet.find (srcCi);
1891  NS_ASSERT_MSG (it != m_ueSrsConfigurationIndexSet.end (), "request to remove unkwown SRS CI " << srcCi);
1892  m_ueSrsConfigurationIndexSet.erase (it);
1893 }
1894 
1895 uint8_t
1897 {
1898  if (bearer.IsGbr ())
1899  {
1900  return 1;
1901  }
1902  else
1903  {
1904  return 2;
1905  }
1906 }
1907 
1908 uint8_t
1910 {
1911  return bearer.qci;
1912 }
1913 
1914 void
1916 {
1917  NS_LOG_FUNCTION (this);
1918  // for simplicity, we use the same periodicity for all sibs
1919  // note that in real systems the periodicy of each sibs could be different
1921  si.haveSib2 = true;
1924 
1926  LteRrcSap::RachConfigCommon rachConfigCommon;
1928  rachConfigCommon.raSupervisionInfo.preambleTransMax = rc.preambleTransMax;
1930  si.sib2.radioResourceConfigCommon.rachConfigCommon = rachConfigCommon;
1931 
1934 }
1935 
1936 } // namespace ns3
1937