A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
epc-ue-nas.cc
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  */
20 
21 #include <ns3/fatal-error.h>
22 #include <ns3/log.h>
23 
24 #include <ns3/epc-helper.h>
25 
26 #include "lte-enb-net-device.h"
27 #include "epc-ue-nas.h"
28 #include "lte-as-sap.h"
29 
30 NS_LOG_COMPONENT_DEFINE ("EpcUeNas");
31 
32 namespace ns3 {
33 
34 
35 
36 
37 
38 const char* g_ueNasStateName[EpcUeNas::NUM_STATES] =
39  {
40  "OFF",
41  "ATTACHING",
42  "IDLE_REGISTERED",
43  "CONNECTING_TO_EPC",
44  "ACTIVE "
45  };
46 
47 std::string ToString (EpcUeNas::State s)
48 {
49  return std::string (g_ueNasStateName[s]);
50 }
51 
52 
53 
54 
55 NS_OBJECT_ENSURE_REGISTERED (EpcUeNas);
56 
58  : m_state (OFF),
59  m_asSapProvider (0),
60  m_bidCounter (0)
61 {
62  NS_LOG_FUNCTION (this);
63  m_asSapUser = new MemberLteAsSapUser<EpcUeNas> (this);
64 }
65 
66 
68 {
69  NS_LOG_FUNCTION (this);
70 }
71 
72 void
74 {
75  NS_LOG_FUNCTION (this);
76  delete m_asSapUser;
77 }
78 
79 TypeId
80 EpcUeNas::GetTypeId (void)
81 {
82  static TypeId tid = TypeId ("ns3::EpcUeNas")
83  .SetParent<Object> ()
84  .AddConstructor<EpcUeNas> ()
85  .AddTraceSource ("StateTransition",
86  "fired upon every UE NAS state transition",
87  MakeTraceSourceAccessor (&EpcUeNas::m_stateTransitionCallback))
88  ;
89  return tid;
90 }
91 
92 void
94 {
95  m_device = dev;
96 }
97 
98 void
99 EpcUeNas::SetImsi (uint64_t imsi)
100 {
101  m_imsi = imsi;
102 }
103 
104 void
106 {
107  m_asSapProvider = s;
108 }
109 
110 LteAsSapUser*
112 {
113  return m_asSapUser;
114 }
115 
116 void
118 {
119  m_forwardUpCallback = cb;
120 }
121 
122 void
123 EpcUeNas::Connect (uint16_t cellId, uint16_t earfcn)
124 {
125  NS_LOG_FUNCTION (this);
126 
127  // since RRC Idle Mode cell selection is not supported yet, we
128  // force the UE RRC to be camped on a specific eNB
129  m_asSapProvider->ForceCampedOnEnb (cellId, earfcn);
130 
131  // tell RRC to go into connected mode
132  m_asSapProvider->Connect ();
133 }
134 
135 
136 void
138 {
139  NS_LOG_FUNCTION (this);
140  m_asSapProvider->Disconnect ();
141  SwitchToState (OFF);
142 }
143 
144 
145 void
147 {
148  NS_LOG_FUNCTION (this);
149  switch (m_state)
150  {
151  case ACTIVE:
152  NS_FATAL_ERROR ("the necessary NAS signaling to activate a bearer after the initial context has already been setup is not implemented");
153  break;
154 
155  default:
156  BearerToBeActivated btba;
157  btba.bearer = bearer;
158  btba.tft = tft;
159  m_bearersToBeActivatedList.push_back (btba);
160  break;
161  }
162 }
163 
164 bool
166 {
167  NS_LOG_FUNCTION (this << packet);
168 
169  switch (m_state)
170  {
171  case ACTIVE:
172  {
173  uint32_t id = m_tftClassifier.Classify (packet, EpcTft::UPLINK);
174  NS_ASSERT ((id & 0xFFFFFF00) == 0);
175  uint8_t bid = (uint8_t) (id & 0x000000FF);
176  if (bid == 0)
177  {
178  return false;
179  }
180  else
181  {
182  m_asSapProvider->SendData (packet, bid);
183  return true;
184  }
185  }
186  break;
187 
188  default:
189  NS_LOG_WARN (this << " NAS OFF, discarding packet");
190  return false;
191  break;
192  }
193 }
194 
195 void
196 EpcUeNas::DoNotifyConnectionSuccessful ()
197 {
198  NS_LOG_FUNCTION (this);
199 
200  SwitchToState (ACTIVE); // will eventually activate dedicated bearers
201 }
202 
203 void
204 EpcUeNas::DoNotifyConnectionFailed ()
205 {
206  NS_FATAL_ERROR ("connection failed, it should not happen with the current model");
207 }
208 
209 void
210 EpcUeNas::DoRecvData (Ptr<Packet> packet)
211 {
212  NS_LOG_FUNCTION (this);
213  m_forwardUpCallback (packet);
214 }
215 
216 void
217 EpcUeNas::DoNotifyConnectionReleased ()
218 {
219  NS_LOG_FUNCTION (this);
220  SwitchToState (OFF);
221 }
222 
223 void
224 EpcUeNas::DoActivateEpsBearer (EpsBearer bearer, Ptr<EpcTft> tft)
225 {
226  NS_LOG_FUNCTION (this);
227  NS_ASSERT_MSG (m_bidCounter < 11, "cannot have more than 11 EPS bearers");
228  uint8_t bid = ++m_bidCounter;
229  m_tftClassifier.Add (tft, bid);
230 }
231 
232 void
233 EpcUeNas::SwitchToState (State newState)
234 {
235  NS_LOG_FUNCTION (this << newState);
236  State oldState = m_state;
237  m_state = newState;
238  NS_LOG_INFO ("IMSI " << m_imsi << " NAS " << ToString (oldState) << " --> " << ToString (newState));
239  m_stateTransitionCallback (oldState, newState);
240 
241  // actions to be done when entering a new state:
242  switch (m_state)
243  {
244  case ACTIVE:
245  for (std::list<BearerToBeActivated>::iterator it = m_bearersToBeActivatedList.begin ();
246  it != m_bearersToBeActivatedList.end ();
247  m_bearersToBeActivatedList.erase (it++))
248  {
249  DoActivateEpsBearer (it->bearer, it->tft);
250  }
251  break;
252 
253  default:
254  break;
255  }
256 
257 }
258 
259 
260 } // namespace ns3
261 
void ActivateEpsBearer(EpsBearer bearer, Ptr< EpcTft > tft)
Definition: epc-ue-nas.cc:146
smart pointer class similar to boost::intrusive_ptr
Definition: ptr.h:59
#define NS_LOG_FUNCTION(parameters)
Definition: log.h:311
Callback template class.
Definition: callback.h:369
void Add(Ptr< EpcTft > tft, uint32_t id)
#define NS_ASSERT(condition)
Definition: assert.h:64
#define NS_LOG_COMPONENT_DEFINE(name)
Definition: log.h:122
#define NS_LOG_INFO(msg)
Definition: log.h:264
uint32_t Classify(Ptr< Packet > p, EpcTft::Direction direction)
virtual void SendData(Ptr< Packet > packet, uint8_t bid)=0
#define NS_FATAL_ERROR(msg)
fatal error handling
Definition: fatal-error.h:72
LteAsSapUser * GetAsSapUser()
Definition: epc-ue-nas.cc:111
void SetDevice(Ptr< NetDevice > dev)
Definition: epc-ue-nas.cc:93
virtual void ForceCampedOnEnb(uint16_t cellId, uint16_t earfcn)=0
void Connect(uint16_t cellId, uint16_t earfcn)
Definition: epc-ue-nas.cc:123
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
bool Send(Ptr< Packet > p)
Definition: epc-ue-nas.cc:165
void Disconnect()
Definition: epc-ue-nas.cc:137
#define NS_ASSERT_MSG(condition, message)
Definition: assert.h:86
virtual ~EpcUeNas()
Definition: epc-ue-nas.cc:67
void SetForwardUpCallback(Callback< void, Ptr< Packet > > cb)
Definition: epc-ue-nas.cc:117
#define NS_LOG_WARN(msg)
Definition: log.h:246
virtual void Disconnect()=0
void SetAsSapProvider(LteAsSapProvider *s)
Definition: epc-ue-nas.cc:105
virtual void Connect(void)=0
a base class which provides memory management and object aggregation
Definition: object.h:63
void SetImsi(uint64_t imsi)
Definition: epc-ue-nas.cc:99
a unique identifier for an interface.
Definition: type-id.h:44
TypeId SetParent(TypeId tid)
Definition: type-id.cc:471
virtual void DoDispose(void)
Definition: epc-ue-nas.cc:73