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  */
21 
22 #include <ns3/fatal-error.h>
23 #include <ns3/log.h>
24 #include <ns3/abort.h>
25 #include "ns3/pointer.h"
26 #include "ns3/object-map.h"
27 #include "ns3/object-factory.h"
28 
29 #include "lte-enb-rrc.h"
30 #include "lte-rlc.h"
31 #include "lte-pdcp.h"
32 #include "lte-pdcp-sap.h"
33 #include "lte-radio-bearer-info.h"
34 #include "lte-radio-bearer-tag.h"
35 #include "ns3/object-map.h"
36 #include <ns3/ff-mac-csched-sap.h>
37 
38 // WILD HACK for UE-RRC direct communications
39 #include <ns3/node-list.h>
40 #include <ns3/node.h>
41 #include <ns3/lte-ue-net-device.h>
42 #include <ns3/lte-ue-rrc.h>
43 
44 
45 NS_LOG_COMPONENT_DEFINE ("LteEnbRrc");
46 
47 namespace ns3 {
48 
49 
50 
51 
52 
53 // ///////////////////////////
54 // CMAC SAP forwarder
55 // ///////////////////////////
56 
58 {
59 public:
61 
62  virtual void NotifyLcConfigResult (uint16_t rnti, uint8_t lcid, bool success);
63  virtual void RrcConfigurationUpdateInd (LteUeConfig_t params);
64 
65 private:
67 };
68 
70  : m_rrc (rrc)
71 {
72 }
73 
74 void
75 EnbRrcMemberLteEnbCmacSapUser::NotifyLcConfigResult (uint16_t rnti, uint8_t lcid, bool success)
76 {
77  m_rrc->DoNotifyLcConfigResult (rnti, lcid, success);
78 }
79 
80 void
82 {
84 }
85 
86 
88 // PDCP SAP Forwarder
90 
91 // not needed any more if the template works
92 
93 // class EnbRrcMemberLtePdcpSapUser : public LtePdcpSapUser
94 // {
95 // public:
96 // MemberLtePdcpSapUser (LteEnbRrc* rrc);
97 // virtual void ReceiveRrcPdu (Ptr<Packet> p);
98 // private:
99 // LteEnbRrc* m_rrc;
100 // };
101 
102 
103 // EnbRrcMemberLtePdcpSapUser::EnbRrcMemberLtePdcpSapUser (LteEnbRrc* rrc)
104 // : m_rrc (rrc)
105 // {
106 // }
107 
108 // void EnbRrcMemberLtePdcpSapUser::ReceiveRrcPdu (Ptr<Packet> p)
109 // {
110 // m_rrc->DoReceiveRrcPdu (p);
111 // }
112 
113 
114 
115 
117 // UeInfo
119 
120 
122 
124  : m_lastAllocatedId (0)
125 {
126  m_imsi = 0;
127 }
128 
129 UeInfo::UeInfo (uint64_t imsi)
130  : m_lastAllocatedId (0)
131 {
132  m_imsi = imsi;
133 }
134 
135 
136 
138 {
139  // Nothing to do here
140 }
141 
143 {
144  static TypeId tid = TypeId ("ns3::UeInfo")
145  .SetParent<Object> ()
146  .AddConstructor<UeInfo> ()
147  .AddAttribute ("RadioBearerMap", "List of UE RadioBearerInfo by LCID.",
148  ObjectMapValue (),
150  MakeObjectMapChecker<LteRadioBearerInfo> ())
151  ;
152  return tid;
153 }
154 
155 uint64_t
157 {
158  return m_imsi;
159 }
160 
161 uint8_t
163 {
164  NS_LOG_FUNCTION (this);
165  for (uint8_t lcid = m_lastAllocatedId; lcid != m_lastAllocatedId - 1; ++lcid)
166  {
167  if (lcid != 0)
168  {
169  if (m_rbMap.find (lcid) == m_rbMap.end ())
170  {
171  m_rbMap.insert (std::pair<uint8_t, Ptr<LteRadioBearerInfo> > (lcid, rbi));
172  m_lastAllocatedId = lcid;
173  return lcid;
174  }
175  }
176  }
177  NS_LOG_WARN ("no more logical channel ids available");
178  return 0;
179 }
180 
183 {
184  NS_LOG_FUNCTION (this << (uint32_t) lcid);
185  NS_ASSERT (0 != lcid);
186  std::map<uint8_t, Ptr<LteRadioBearerInfo> >::iterator it = m_rbMap.find (lcid);
187  NS_ABORT_IF (it == m_rbMap.end ());
188  return it->second;
189 }
190 
191 
192 void
194 {
195  NS_LOG_FUNCTION (this << (uint32_t) lcid);
196  std::map <uint8_t, Ptr<LteRadioBearerInfo> >::iterator it = m_rbMap.find (lcid);
197  NS_ASSERT_MSG (it != m_rbMap.end (), "request to remove radio bearer with unknown lcid " << lcid);
198  m_rbMap.erase (it);
199 }
200 
201 
202 
203 
204 
205 // ///////////////////////////
206 // eNB RRC methods
207 // ///////////////////////////
208 
210 
212  : m_cmacSapProvider (0),
213  m_ffMacSchedSapProvider (0),
214  m_macSapProvider (0),
215  m_configured (false),
216  m_lastAllocatedRnti (0)
217 {
218  NS_LOG_FUNCTION (this);
221 }
222 
223 
225 {
226  NS_LOG_FUNCTION (this);
227 }
228 
229 
230 void
232 {
233  NS_LOG_FUNCTION (this);
234  delete m_cmacSapUser;
235  delete m_pdcpSapUser;
236 }
237 
238 TypeId
240 {
241  NS_LOG_FUNCTION ("LteEnbRrc::GetTypeId");
242  static TypeId tid = TypeId ("ns3::LteEnbRrc")
243  .SetParent<Object> ()
244  .AddConstructor<LteEnbRrc> ()
245  .AddAttribute ("UeMap", "List of UE Info by C-RNTI.",
246  ObjectMapValue (),
248  MakeObjectMapChecker<UeInfo> ())
249  .AddAttribute ("DefaultTransmissionMode",
250  "The default UEs' transmission mode (0: SISO)",
251  UintegerValue (0), // default tx-mode
252  MakeUintegerAccessor (&LteEnbRrc::m_defaultTransmissionMode),
253  MakeUintegerChecker<uint8_t> ())
254 
255  ;
256  return tid;
257 }
258 
259 uint16_t
261 {
262  NS_LOG_FUNCTION (this);
263  return m_lastAllocatedRnti;
264 }
265 std::map<uint16_t,Ptr<UeInfo> > LteEnbRrc::GetUeMap (void) const
266 {
267  return m_ueMap;
268 }
269 
270 void LteEnbRrc::SetUeMap (std::map<uint16_t,Ptr<UeInfo> > ueMap)
271 {
272  this->m_ueMap = ueMap;
273 }
274 
275 
276 void
277 LteEnbRrc::SetLastAllocatedRnti (uint16_t lastAllocatedRnti)
278 {
279  NS_LOG_FUNCTION (this << lastAllocatedRnti);
280  m_lastAllocatedRnti = lastAllocatedRnti;
281 }
282 
283 
284 
285 void
287 {
288  NS_LOG_FUNCTION (this << s);
289  m_cmacSapProvider = s;
290 }
291 
294 {
295  NS_LOG_FUNCTION (this);
296  return m_cmacSapUser;
297 }
298 
299 void
301 {
302  NS_LOG_FUNCTION (this);
304 }
305 
306 
307 void
309 {
310  NS_LOG_FUNCTION (this);
311  m_macSapProvider = s;
312 }
313 
315 LteEnbRrc::GetLtePdcpSapProvider (uint16_t rnti, uint8_t lcid)
316 {
317  return GetUeInfo (rnti)->GetRadioBearer (lcid)->m_pdcp->GetLtePdcpSapProvider ();
318 }
319 
320 void
321 LteEnbRrc::ConfigureCell (uint8_t ulBandwidth, uint8_t dlBandwidth)
322 {
323  NS_LOG_FUNCTION (this);
325  m_cmacSapProvider->ConfigureMac (ulBandwidth, dlBandwidth);
326  m_configured = true;
327 }
328 
329 uint16_t
330 LteEnbRrc::AddUe (uint64_t imsi)
331 {
332  NS_LOG_FUNCTION (this << imsi);
333  // no Call Admission Control for now
334  uint16_t rnti = CreateUeInfo (imsi); // side effect: create UeInfo for this UE
335  NS_ASSERT_MSG (rnti != 0, "CreateUeInfo returned RNTI==0");
336  m_cmacSapProvider->AddUe (rnti);
337  return rnti;
338 }
339 
340 void
341 LteEnbRrc::RemoveUe (uint16_t rnti)
342 {
343  NS_LOG_FUNCTION (this << (uint32_t) rnti);
344  RemoveUeInfo (rnti);
345  NS_FATAL_ERROR ("missing RemoveUe method in CMAC SAP");
346 }
347 
348 uint8_t
349 LteEnbRrc::SetupRadioBearer (uint16_t rnti, EpsBearer bearer, TypeId rlcTypeId)
350 {
351  NS_LOG_FUNCTION (this << (uint32_t) rnti);
352  Ptr<UeInfo> ueInfo = GetUeInfo (rnti);
353 
354  // create RLC instance
355 
356  ObjectFactory rlcObjectFactory;
357  rlcObjectFactory.SetTypeId (rlcTypeId);
358  Ptr<LteRlc> rlc = rlcObjectFactory.Create ()->GetObject<LteRlc> ();
360  rlc->SetRnti (rnti);
361 
362  Ptr<LteRadioBearerInfo> rbInfo = CreateObject<LteRadioBearerInfo> ();
363  rbInfo->m_rlc = rlc;
364  uint8_t lcid = ueInfo->AddRadioBearer (rbInfo);
365  rlc->SetLcId (lcid);
366 
367  // we need PDCP only for real RLC, i.e., RLC/UM or RLC/AM
368  // if we are using RLC/SM we don't care of anything above RLC
369  if (rlcTypeId != LteRlcSm::GetTypeId ())
370  {
371  Ptr<LtePdcp> pdcp = CreateObject<LtePdcp> ();
372  pdcp->SetRnti (rnti);
373  pdcp->SetLcId (lcid);
376  rlc->SetLteRlcSapUser (pdcp->GetLteRlcSapUser ());
377  rbInfo->m_pdcp = pdcp;
378  }
379 
381  lcinfo.rnti = rnti;
382  lcinfo.lcId = lcid;
383  lcinfo.lcGroup = 0; // TBD
384  lcinfo.qci = bearer.qci;
385  lcinfo.isGbr = bearer.IsGbr ();
386  lcinfo.mbrUl = bearer.gbrQosInfo.mbrUl;
387  lcinfo.mbrDl = bearer.gbrQosInfo.mbrDl;
388  lcinfo.gbrUl = bearer.gbrQosInfo.gbrUl;
389  lcinfo.gbrDl = bearer.gbrQosInfo.gbrDl;
390  m_cmacSapProvider->AddLc (lcinfo, rlc->GetLteMacSapUser ());
391 
392  // Transmission mode settings
393  LteUeConfig_t ueConfig;
394  ueConfig.m_rnti = rnti;
396  DoRrcConfigurationUpdateInd (ueConfig);
397 
398  return lcid;
399 }
400 
401 void
402 LteEnbRrc::ReleaseRadioBearer (uint16_t rnti, uint8_t lcId)
403 {
404  NS_LOG_FUNCTION (this << (uint32_t) rnti);
405  Ptr<UeInfo> ueInfo = GetUeInfo (rnti);
406  ueInfo->RemoveRadioBearer (lcId);
407 }
408 
409 
410 
411 bool
413 {
414  NS_LOG_FUNCTION (this << packet);
415 
416  LteRadioBearerTag tag;
417  bool found = packet->RemovePacketTag (tag);
418  NS_ASSERT (found);
419 
421  params.rrcPdu = packet;
422  params.rnti = tag.GetRnti ();
423  params.lcid = tag.GetLcid ();
424  LtePdcpSapProvider* pdcpSapProvider = GetLtePdcpSapProvider (tag.GetRnti (), tag.GetLcid ());
425  pdcpSapProvider->TransmitRrcPdu (params);
426 
427  return true;
428 }
429 
430 void
432 {
433  m_forwardUpCallback = cb;
434 }
435 
436 
437 void
439 {
440  NS_LOG_FUNCTION (this);
441  // this tag is needed by the EpcEnbApplication to determine the S1 bearer that corresponds to this radio bearer
442  LteRadioBearerTag tag;
443  tag.SetRnti (params.rnti);
444  tag.SetLcid (params.lcid);
445  params.rrcPdu->AddPacketTag (tag);
446  m_forwardUpCallback (params.rrcPdu);
447 }
448 
449 
450 
451 void
452 LteEnbRrc::DoNotifyLcConfigResult (uint16_t rnti, uint8_t lcid, bool success)
453 {
454  NS_LOG_FUNCTION (this << (uint32_t) rnti);
455  NS_FATAL_ERROR ("not implemented");
456 }
457 
458 
459 
460 // /////////////////////////////////////////
461 // management of multiple UE info instances
462 // /////////////////////////////////////////
463 
464 
465 uint16_t
466 LteEnbRrc::CreateUeInfo (uint64_t imsi)
467 {
468  NS_LOG_FUNCTION (this << imsi);
469  for (uint16_t rnti = m_lastAllocatedRnti; rnti != m_lastAllocatedRnti - 1; ++rnti)
470  {
471  if (rnti != 0)
472  {
473  if (m_ueMap.find (rnti) == m_ueMap.end ())
474  {
475  m_lastAllocatedRnti = rnti;
476  m_ueMap.insert (std::pair<uint16_t, Ptr<UeInfo> > (rnti, CreateObject<UeInfo> (imsi)));
477  return rnti;
478  }
479  }
480  }
481  return 0;
482 }
483 
485 LteEnbRrc::GetUeInfo (uint16_t rnti)
486 {
487  NS_LOG_FUNCTION (this << (uint32_t) rnti);
488  NS_ASSERT (0 != rnti);
489  std::map<uint16_t, Ptr<UeInfo> >::iterator it = m_ueMap.find (rnti);
490  NS_ABORT_IF (it == m_ueMap.end ());
491  return it->second;
492 }
493 
494 void
495 LteEnbRrc::RemoveUeInfo (uint16_t rnti)
496 {
497  NS_LOG_FUNCTION (this << (uint32_t) rnti);
498  std::map <uint16_t, Ptr<UeInfo> >::iterator it = m_ueMap.find (rnti);
499  NS_ASSERT_MSG (it != m_ueMap.end (), "request to remove UE info with unknown rnti " << rnti);
500  m_ueMap.erase (it);
501 }
502 
503 
504 void
506 {
507  NS_LOG_FUNCTION (this);
508  // up tp now only for TxMode change
509  // update the peer UE-RRC on the change
510  NodeList::Iterator listEnd = NodeList::End ();
511  bool done = false;
512  for (NodeList::Iterator i = NodeList::Begin (); i != listEnd; i++)
513  {
514  Ptr<Node> node = *i;
515  int nDevs = node->GetNDevices ();
516  for (int j = 0; j < nDevs; j++)
517  {
518  Ptr<LteUeNetDevice> uedev = node->GetDevice (j)->GetObject <LteUeNetDevice> ();
519  if (!uedev)
520  {
521  continue;
522  }
523  else
524  {
525  Ptr<LteUeRrc> ueRrc = uedev->GetRrc ();
526  if (ueRrc->GetRnti () == params.m_rnti)
527  {
528  ueRrc->DoRrcConfigurationUpdateInd (params);
529  done = true;
530  }
531  else
532  {
533  continue;
534  }
535  }
536  }
537  }
538  NS_ASSERT_MSG (done , " Unable to find peer UE-RRC, RNTI " << params.m_rnti);
539  // answer to MAC (and scheduler)
541  req.m_rnti = params.m_rnti;
544 
545 }
546 
547 
548 
549 
550 } // namespace ns3
551