A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
epc-enb-application.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: Jaume Nin <jnin@cttc.cat>
19  * Nicola Baldo <nbaldo@cttc.cat>
20  */
21 
22 
23 #include "epc-enb-application.h"
24 #include "ns3/log.h"
25 #include "ns3/mac48-address.h"
26 #include "ns3/ipv4.h"
27 #include "ns3/inet-socket-address.h"
28 #include "ns3/uinteger.h"
29 
30 #include "epc-gtpu-header.h"
31 #include "eps-bearer-tag.h"
32 
33 
34 namespace ns3 {
35 
36 NS_LOG_COMPONENT_DEFINE ("EpcEnbApplication")
37  ;
38 
39 
41 {
42 }
43 
44 EpcEnbApplication::EpsFlowId_t::EpsFlowId_t (const uint16_t a, const uint8_t b)
45  : m_rnti (a),
46  m_bid (b)
47 {
48 }
49 
50 bool
52 {
53  return ( (a.m_rnti == b.m_rnti) && (a.m_bid == b.m_bid) );
54 }
55 
56 bool
58 {
59  return ( (a.m_rnti < b.m_rnti) || ( (a.m_rnti == b.m_rnti) && (a.m_bid < b.m_bid) ) );
60 }
61 
62 
63 TypeId
65 {
66  static TypeId tid = TypeId ("ns3::EpcEnbApplication")
67  .SetParent<Object> ();
68  return tid;
69 }
70 
71 void
73 {
74  NS_LOG_FUNCTION (this);
75  m_lteSocket = 0;
76  m_s1uSocket = 0;
77  delete m_s1SapProvider;
78  delete m_s1apSapEnb;
79 }
80 
81 
82 EpcEnbApplication::EpcEnbApplication (Ptr<Socket> lteSocket, Ptr<Socket> s1uSocket, Ipv4Address enbS1uAddress, Ipv4Address sgwS1uAddress, uint16_t cellId)
83  : m_lteSocket (lteSocket),
84  m_s1uSocket (s1uSocket),
85  m_enbS1uAddress (enbS1uAddress),
86  m_sgwS1uAddress (sgwS1uAddress),
87  m_gtpuUdpPort (2152), // fixed by the standard
88  m_s1SapUser (0),
89  m_s1apSapMme (0),
90  m_cellId (cellId)
91 {
92  NS_LOG_FUNCTION (this << lteSocket << s1uSocket << sgwS1uAddress);
97 }
98 
99 
101 {
102  NS_LOG_FUNCTION (this);
103 }
104 
105 
106 void
108 {
109  m_s1SapUser = s;
110 }
111 
112 
115 {
116  return m_s1SapProvider;
117 }
118 
119 void
121 {
122  m_s1apSapMme = s;
123 }
124 
125 
128 {
129  return m_s1apSapEnb;
130 }
131 
132 void
133 EpcEnbApplication::DoInitialUeMessage (uint64_t imsi, uint16_t rnti)
134 {
135  NS_LOG_FUNCTION (this);
136  // side effect: create entry if not exist
137  m_imsiRntiMap[imsi] = rnti;
138  m_s1apSapMme->InitialUeMessage (imsi, rnti, imsi, m_cellId);
139 }
140 
141 void
143 {
144  NS_LOG_FUNCTION (this);
145  uint16_t enbUeS1Id = params.rnti;
146  uint64_t mmeUeS1Id = params.mmeUeS1Id;
147  uint64_t imsi = mmeUeS1Id;
148  // side effect: create entry if not exist
149  m_imsiRntiMap[imsi] = params.rnti;
150 
151  uint16_t gci = params.cellId;
152  std::list<EpcS1apSapMme::ErabSwitchedInDownlinkItem> erabToBeSwitchedInDownlinkList;
153  for (std::list<EpcEnbS1SapProvider::BearerToBeSwitched>::iterator bit = params.bearersToBeSwitched.begin ();
154  bit != params.bearersToBeSwitched.end ();
155  ++bit)
156  {
157  EpsFlowId_t flowId;
158  flowId.m_rnti = params.rnti;
159  flowId.m_bid = bit->epsBearerId;
160  uint32_t teid = bit->teid;
161 
162  EpsFlowId_t rbid (params.rnti, bit->epsBearerId);
163  // side effect: create entries if not exist
164  m_rbidTeidMap[params.rnti][bit->epsBearerId] = teid;
165  m_teidRbidMap[teid] = rbid;
166 
168  erab.erabId = bit->epsBearerId;
170  erab.enbTeid = bit->teid;
171 
172  erabToBeSwitchedInDownlinkList.push_back (erab);
173  }
174  m_s1apSapMme->PathSwitchRequest (enbUeS1Id, mmeUeS1Id, gci, erabToBeSwitchedInDownlinkList);
175 }
176 
177 void
179 {
180  NS_LOG_FUNCTION (this << rnti);
181  std::map<uint16_t, std::map<uint8_t, uint32_t> >::iterator rntiIt = m_rbidTeidMap.find (rnti);
182  if (rntiIt != m_rbidTeidMap.end ())
183  {
184  for (std::map<uint8_t, uint32_t>::iterator bidIt = rntiIt->second.begin ();
185  bidIt != rntiIt->second.end ();
186  ++bidIt)
187  {
188  uint32_t teid = bidIt->second;
189  m_teidRbidMap.erase (teid);
190  }
191  m_rbidTeidMap.erase (rntiIt);
192  }
193 }
194 
195 void
196 EpcEnbApplication::DoInitialContextSetupRequest (uint64_t mmeUeS1Id, uint16_t enbUeS1Id, std::list<EpcS1apSapEnb::ErabToBeSetupItem> erabToBeSetupList)
197 {
198  NS_LOG_FUNCTION (this);
199 
200  for (std::list<EpcS1apSapEnb::ErabToBeSetupItem>::iterator erabIt = erabToBeSetupList.begin ();
201  erabIt != erabToBeSetupList.end ();
202  ++erabIt)
203  {
204  // request the RRC to setup a radio bearer
205 
206  uint64_t imsi = mmeUeS1Id;
207  std::map<uint64_t, uint16_t>::iterator imsiIt = m_imsiRntiMap.find (imsi);
208  NS_ASSERT_MSG (imsiIt != m_imsiRntiMap.end (), "unknown IMSI");
209  uint16_t rnti = imsiIt->second;
210 
212  params.rnti = rnti;
213  params.bearer = erabIt->erabLevelQosParameters;
214  params.bearerId = erabIt->erabId;
215  params.gtpTeid = erabIt->sgwTeid;
217 
218  EpsFlowId_t rbid (rnti, erabIt->erabId);
219  // side effect: create entries if not exist
220  m_rbidTeidMap[rnti][erabIt->erabId] = params.gtpTeid;
221  m_teidRbidMap[params.gtpTeid] = rbid;
222 
223  }
224 }
225 
226 void
227 EpcEnbApplication::DoPathSwitchRequestAcknowledge (uint64_t enbUeS1Id, uint64_t mmeUeS1Id, uint16_t gci, std::list<EpcS1apSapEnb::ErabSwitchedInUplinkItem> erabToBeSwitchedInUplinkList)
228 {
229  NS_LOG_FUNCTION (this);
230 
231  uint64_t imsi = mmeUeS1Id;
232  std::map<uint64_t, uint16_t>::iterator imsiIt = m_imsiRntiMap.find (imsi);
233  NS_ASSERT_MSG (imsiIt != m_imsiRntiMap.end (), "unknown IMSI");
234  uint16_t rnti = imsiIt->second;
236  params.rnti = rnti;
238 }
239 
240 void
242 {
243  NS_LOG_FUNCTION (this);
244  NS_ASSERT (socket == m_lteSocket);
245  Ptr<Packet> packet = socket->Recv ();
246 
249  SocketAddressTag satag;
250  packet->RemovePacketTag (satag);
251 
252  EpsBearerTag tag;
253  bool found = packet->RemovePacketTag (tag);
254  NS_ASSERT (found);
255  uint16_t rnti = tag.GetRnti ();
256  uint8_t bid = tag.GetBid ();
257  NS_LOG_LOGIC ("received packet with RNTI=" << (uint32_t) rnti << ", BID=" << (uint32_t) bid);
258  std::map<uint16_t, std::map<uint8_t, uint32_t> >::iterator rntiIt = m_rbidTeidMap.find (rnti);
259  if (rntiIt == m_rbidTeidMap.end ())
260  {
261  NS_LOG_WARN ("UE context not found, discarding packet");
262  }
263  else
264  {
265  std::map<uint8_t, uint32_t>::iterator bidIt = rntiIt->second.find (bid);
266  NS_ASSERT (bidIt != rntiIt->second.end ());
267  uint32_t teid = bidIt->second;
268  SendToS1uSocket (packet, teid);
269  }
270 }
271 
272 void
274 {
275  NS_LOG_FUNCTION (this << socket);
276  NS_ASSERT (socket == m_s1uSocket);
277  Ptr<Packet> packet = socket->Recv ();
278  GtpuHeader gtpu;
279  packet->RemoveHeader (gtpu);
280  uint32_t teid = gtpu.GetTeid ();
281  std::map<uint32_t, EpsFlowId_t>::iterator it = m_teidRbidMap.find (teid);
282  NS_ASSERT (it != m_teidRbidMap.end ());
283 
286  SocketAddressTag tag;
287  packet->RemovePacketTag (tag);
288 
289  SendToLteSocket (packet, it->second.m_rnti, it->second.m_bid);
290 }
291 
292 void
293 EpcEnbApplication::SendToLteSocket (Ptr<Packet> packet, uint16_t rnti, uint8_t bid)
294 {
295  NS_LOG_FUNCTION (this << packet << rnti << (uint16_t) bid << packet->GetSize ());
296  EpsBearerTag tag (rnti, bid);
297  packet->AddPacketTag (tag);
298  int sentBytes = m_lteSocket->Send (packet);
299  NS_ASSERT (sentBytes > 0);
300 }
301 
302 
303 void
305 {
306  NS_LOG_FUNCTION (this << packet << teid << packet->GetSize ());
307  GtpuHeader gtpu;
308  gtpu.SetTeid (teid);
309  // From 3GPP TS 29.281 v10.0.0 Section 5.1
310  // Length of the payload + the non obligatory GTP-U header
311  gtpu.SetLength (packet->GetSize () + gtpu.GetSerializedSize () - 8);
312  packet->AddHeader (gtpu);
313  uint32_t flags = 0;
315 }
316 
317 
318 }; // namespace ns3
uint32_t RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer.
Definition: packet.cc:268
Parameters passed to DataRadioBearerSetupRequest ()
This class implements the Service Access Point (SAP) between the LteEnbRrc and the EpcEnbApplication...
an Inet address class
#define NS_LOG_FUNCTION(parameters)
Definition: log.h:345
MME side of the S1-AP Service Access Point (SAP), provides the MME methods to be called when an S1-AP...
Definition: epc-s1ap-sap.h:48
EpcEnbApplication(Ptr< Socket > lteSocket, Ptr< Socket > s1uSocket, Ipv4Address enbS1uAddress, Ipv4Address sgwS1uAddress, uint16_t cellId)
Constructor.
This class implements the Service Access Point (SAP) between the LteEnbRrc and the EpcEnbApplication...
NS_LOG_COMPONENT_DEFINE("GrantedTimeWindowMpiInterface")
void DoPathSwitchRequest(EpcEnbS1SapProvider::PathSwitchRequestParameters params)
virtual void DataRadioBearerSetupRequest(DataRadioBearerSetupRequestParameters params)=0
request the setup of a DataRadioBearer
Ipv4Address m_enbS1uAddress
address of the eNB for S1-U communications
uint16_t rnti
the RNTI identifying the UE for which the DataRadioBearer is to be created
void AddPacketTag(const Tag &tag) const
Add a packet tag.
Definition: packet.cc:841
#define NS_ASSERT(condition)
Definition: assert.h:64
void DoDispose(void)
This method is called by Object::Dispose or by the object's destructor, whichever comes first...
Ipv4Address m_sgwS1uAddress
address of the SGW which terminates all S1-U tunnels
std::list< BearerToBeSwitched > bearersToBeSwitched
uint32_t GetSize(void) const
Definition: packet.h:650
Tag used to define the RNTI and EPS bearer ID for packets interchanged between the EpcEnbApplication ...
bool operator<(const Room &a, const Room &b)
EpsBearer bearer
the characteristics of the bearer to be set up
Ptr< Socket > m_lteSocket
raw packet socket to send and receive the packets to and from the LTE radio interface ...
uint8_t GetBid(void) const
uint16_t GetRnti(void) const
void SendToLteSocket(Ptr< Packet > packet, uint16_t rnti, uint8_t bid)
Send a packet to the UE via the LTE radio interface of the eNB.
EpcS1apSapEnb * GetS1apSapEnb()
void SendToS1uSocket(Ptr< Packet > packet, uint32_t teid)
Send a packet to the SGW via the S1-U interface.
void SetS1SapUser(EpcEnbS1SapUser *s)
Set the S1 SAP User.
eNB side of the S1-AP Service Access Point (SAP), provides the eNB methods to be called when an S1-AP...
Definition: epc-s1ap-sap.h:113
uint16_t m_gtpuUdpPort
UDP port to be used for GTP.
EpcS1apSapMme * m_s1apSapMme
MME side of the S1-AP SAP.
Ptr< SampleEmitter > s
void DoInitialUeMessage(uint64_t imsi, uint16_t rnti)
This class implements a tag that carries an address of a packet across the socket interface...
Definition: socket.h:948
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:1238
virtual void PathSwitchRequest(uint64_t enbUeS1Id, uint64_t mmeUeS1Id, uint16_t gci, std::list< ErabSwitchedInDownlinkItem > erabToBeSwitchedInDownlinkList)=0
PATH SWITCH REQUEST message, see 3GPP TS 36.413 9.1.5.8.
uint32_t gtpTeid
S1-bearer GTP tunnel endpoint identifier, see 36.423 9.2.1.
void SetRecvCallback(Callback< void, Ptr< Socket > >)
Notify application when new data is available to be read.
Definition: socket.cc:128
#define NS_LOG_LOGIC(msg)
Definition: log.h:368
virtual ~EpcEnbApplication(void)
Destructor.
void RecvFromLteSocket(Ptr< Socket > socket)
Method to be assigned to the recv callback of the LTE socket.
void DoInitialContextSetupRequest(uint64_t mmeUeS1Id, uint16_t enbUeS1Id, std::list< EpcS1apSapEnb::ErabToBeSetupItem > erabToBeSetupList)
void SetTeid(uint32_t m_teid)
static TypeId GetTypeId(void)
virtual Ptr< Packet > Recv(uint32_t maxSize, uint32_t flags)=0
Read data from the socket.
Template for the implementation of the EpcEnbS1SapProvider as a member of an owner class of type C to...
EpcEnbS1SapProvider * GetS1SapProvider()
uint32_t GetTeid() const
void RecvFromS1uSocket(Ptr< Socket > socket)
Method to be assigned to the recv callback of the S1-U socket.
EpcEnbS1SapUser * m_s1SapUser
User for the S1 SAP.
void DoUeContextRelease(uint16_t rnti)
std::map< uint32_t, EpsFlowId_t > m_teidRbidMap
map telling for each S1-U TEID the corresponding RNTI,BID
#define NS_ASSERT_MSG(condition, message)
Definition: assert.h:86
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:38
virtual void PathSwitchRequestAcknowledge(PathSwitchRequestAcknowledgeParameters params)=0
#define NS_LOG_WARN(msg)
Definition: log.h:280
bool RemovePacketTag(Tag &tag)
Remove a packet tag.
Definition: packet.cc:848
void DoPathSwitchRequestAcknowledge(uint64_t enbUeS1Id, uint64_t mmeUeS1Id, uint16_t cgi, std::list< EpcS1apSapEnb::ErabSwitchedInUplinkItem > erabToBeSwitchedInUplinkList)
bool operator==(const EventId &a, const EventId &b)
Definition: event-id.cc:89
virtual int SendTo(Ptr< Packet > p, uint32_t flags, const Address &toAddress)=0
Send data to a specified peer.
virtual void InitialUeMessage(uint64_t mmeUeS1Id, uint16_t enbUeS1Id, uint64_t stmsi, uint16_t ecgi)=0
a base class which provides memory management and object aggregation
Definition: object.h:63
EpcS1apSapEnb * m_s1apSapEnb
ENB side of the S1-AP SAP.
void SetS1apSapMme(EpcS1apSapMme *s)
Set the MME side of the S1-AP SAP.
virtual int Send(Ptr< Packet > p, uint32_t flags)=0
Send data (or dummy data) to the remote host.
std::map< uint16_t, std::map< uint8_t, uint32_t > > m_rbidTeidMap
map of maps telling for each RNTI and BID the corresponding S1-U TEID
a unique identifier for an interface.
Definition: type-id.h:49
TypeId SetParent(TypeId tid)
Definition: type-id.cc:611
std::map< uint64_t, uint16_t > m_imsiRntiMap
UE context info.
Ptr< Socket > m_s1uSocket
UDP socket to send and receive GTP-U the packets to and from the S1-U interface.
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:253
Template for the implementation of the EpcS1apSapEnb as a member of an owner class of type C to which...
Definition: epc-s1ap-sap.h:226
Implementation of the GTPv1-U Release 10 as per 3Gpp TS 29.281 document.
EpcEnbS1SapProvider * m_s1SapProvider
Provider for the S1 SAP.