A Discrete-Event Network Simulator
Home
Tutorials ▼
English
Portuguese
Docs ▼
Wiki
Manual
Models
Develop ▼
API
Bugs
API
Main Page
Related Pages
Modules
Namespaces
Classes
Files
File List
File Members
All
Classes
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Properties
Friends
Macros
Groups
Pages
epc-sgw-pgw-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-sgw-pgw-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/epc-gtpu-header.h"
29
#include "ns3/abort.h"
30
31
namespace
ns3 {
32
33
NS_LOG_COMPONENT_DEFINE
(
"EpcSgwPgwApplication"
);
34
35
37
// UeInfo
39
40
41
EpcSgwPgwApplication::UeInfo::UeInfo
()
42
{
43
NS_LOG_FUNCTION
(
this
);
44
}
45
46
void
47
EpcSgwPgwApplication::UeInfo::AddBearer
(
Ptr<EpcTft>
tft, uint8_t bearerId, uint32_t teid)
48
{
49
NS_LOG_FUNCTION
(
this
<< tft << teid);
50
m_teidByBearerIdMap[bearerId] = teid;
51
return
m_tftClassifier.Add (tft, teid);
52
}
53
54
uint32_t
55
EpcSgwPgwApplication::UeInfo::Classify
(
Ptr<Packet>
p)
56
{
57
NS_LOG_FUNCTION
(
this
<< p);
58
// we hardcode DOWNLINK direction since the PGW is espected to
59
// classify only downlink packets (uplink packets will go to the
60
// internet without any classification).
61
return
m_tftClassifier.Classify (p,
EpcTft::DOWNLINK
);
62
}
63
64
Ipv4Address
65
EpcSgwPgwApplication::UeInfo::GetEnbAddr
()
66
{
67
return
m_enbAddr;
68
}
69
70
void
71
EpcSgwPgwApplication::UeInfo::SetEnbAddr
(
Ipv4Address
enbAddr)
72
{
73
m_enbAddr = enbAddr;
74
}
75
76
Ipv4Address
77
EpcSgwPgwApplication::UeInfo::GetUeAddr
()
78
{
79
return
m_ueAddr;
80
}
81
82
void
83
EpcSgwPgwApplication::UeInfo::SetUeAddr
(
Ipv4Address
ueAddr)
84
{
85
m_ueAddr = ueAddr;
86
}
87
89
// EpcSgwPgwApplication
91
92
93
TypeId
94
EpcSgwPgwApplication::GetTypeId
(
void
)
95
{
96
static
TypeId
tid =
TypeId
(
"ns3::EpcSgwPgwApplication"
)
97
.
SetParent
<
Object
> ();
98
return
tid;
99
}
100
101
void
102
EpcSgwPgwApplication::DoDispose
()
103
{
104
NS_LOG_FUNCTION
(
this
);
105
m_s1uSocket
->
SetRecvCallback
(
MakeNullCallback
<
void
,
Ptr<Socket>
> ());
106
m_s1uSocket
= 0;
107
delete
(
m_s11SapSgw
);
108
}
109
110
111
112
EpcSgwPgwApplication::EpcSgwPgwApplication
(
const
Ptr<VirtualNetDevice>
tunDevice,
const
Ptr<Socket>
s1uSocket)
113
:
m_s1uSocket
(s1uSocket),
114
m_tunDevice
(tunDevice),
115
m_gtpuUdpPort
(2152),
// fixed by the standard
116
m_teidCount
(0),
117
m_s11SapMme
(0)
118
{
119
NS_LOG_FUNCTION
(
this
<< tunDevice << s1uSocket);
120
m_s1uSocket
->
SetRecvCallback
(
MakeCallback
(&
EpcSgwPgwApplication::RecvFromS1uSocket
,
this
));
121
m_s11SapSgw
=
new
MemberEpcS11SapSgw<EpcSgwPgwApplication>
(
this
);
122
}
123
124
125
EpcSgwPgwApplication::~EpcSgwPgwApplication
()
126
{
127
NS_LOG_FUNCTION
(
this
);
128
}
129
130
131
bool
132
EpcSgwPgwApplication::RecvFromTunDevice
(
Ptr<Packet>
packet,
const
Address
& source,
const
Address
& dest, uint16_t protocolNumber)
133
{
134
NS_LOG_FUNCTION
(
this
<< source << dest << packet << packet->
GetSize
());
135
136
// get IP address of UE
137
Ptr<Packet>
pCopy = packet->
Copy
();
138
Ipv4Header
ipv4Header;
139
pCopy->RemoveHeader (ipv4Header);
140
Ipv4Address
ueAddr = ipv4Header.
GetDestination
();
141
NS_LOG_LOGIC
(
"packet addressed to UE "
<< ueAddr);
142
143
// find corresponding UeInfo address
144
std::map<Ipv4Address, Ptr<UeInfo> >::iterator it =
m_ueInfoByAddrMap
.find (ueAddr);
145
if
(it ==
m_ueInfoByAddrMap
.end ())
146
{
147
NS_LOG_WARN
(
"unknown UE address "
<< ueAddr) ;
148
}
149
else
150
{
151
Ipv4Address
enbAddr = it->second->GetEnbAddr ();
152
uint32_t teid = it->second->Classify (packet);
153
if
(teid == 0)
154
{
155
NS_LOG_WARN
(
"no matching bearer for this packet"
);
156
}
157
else
158
{
159
SendToS1uSocket
(packet, enbAddr, teid);
160
}
161
}
162
// there is no reason why we should notify the TUN
163
// VirtualNetDevice that he failed to send the packet: if we receive
164
// any bogus packet, it will just be silently discarded.
165
const
bool
succeeded =
true
;
166
return
succeeded;
167
}
168
169
void
170
EpcSgwPgwApplication::RecvFromS1uSocket
(
Ptr<Socket>
socket)
171
{
172
NS_LOG_FUNCTION
(
this
<< socket);
173
NS_ASSERT
(socket ==
m_s1uSocket
);
174
Ptr<Packet>
packet = socket->
Recv
();
175
GtpuHeader
gtpu;
176
packet->
RemoveHeader
(gtpu);
177
uint32_t teid = gtpu.
GetTeid
();
178
181
SocketAddressTag
tag;
182
packet->
RemovePacketTag
(tag);
183
184
SendToTunDevice
(packet, teid);
185
}
186
187
void
188
EpcSgwPgwApplication::SendToTunDevice
(
Ptr<Packet>
packet, uint32_t teid)
189
{
190
NS_LOG_FUNCTION
(
this
<< packet << teid);
191
NS_LOG_LOGIC
(
" packet size: "
<< packet->
GetSize
() <<
" bytes"
);
192
m_tunDevice
->
Receive
(packet, 0x0800,
m_tunDevice
->
GetAddress
(),
m_tunDevice
->
GetAddress
(),
NetDevice::PACKET_HOST
);
193
}
194
195
void
196
EpcSgwPgwApplication::SendToS1uSocket
(
Ptr<Packet>
packet,
Ipv4Address
enbAddr, uint32_t teid)
197
{
198
NS_LOG_FUNCTION
(
this
<< packet << enbAddr << teid);
199
200
GtpuHeader
gtpu;
201
gtpu.
SetTeid
(teid);
202
// From 3GPP TS 29.281 v10.0.0 Section 5.1
203
// Length of the payload + the non obligatory GTP-U header
204
gtpu.
SetLength
(packet->
GetSize
() + gtpu.
GetSerializedSize
() - 8);
205
packet->
AddHeader
(gtpu);
206
uint32_t flags = 0;
207
m_s1uSocket
->
SendTo
(packet, flags,
InetSocketAddress
(enbAddr,
m_gtpuUdpPort
));
208
}
209
210
211
void
212
EpcSgwPgwApplication::SetS11SapMme
(
EpcS11SapMme
*
s
)
213
{
214
m_s11SapMme
=
s
;
215
}
216
217
EpcS11SapSgw
*
218
EpcSgwPgwApplication::GetS11SapSgw
()
219
{
220
return
m_s11SapSgw
;
221
}
222
223
void
224
EpcSgwPgwApplication::AddEnb
(uint16_t cellId,
Ipv4Address
enbAddr,
Ipv4Address
sgwAddr)
225
{
226
NS_LOG_FUNCTION
(
this
<< cellId << enbAddr << sgwAddr);
227
EnbInfo
enbInfo;
228
enbInfo.
enbAddr
= enbAddr;
229
enbInfo.
sgwAddr
= sgwAddr;
230
m_enbInfoByCellId
[cellId] = enbInfo;
231
}
232
233
void
234
EpcSgwPgwApplication::AddUe
(uint64_t imsi)
235
{
236
NS_LOG_FUNCTION
(
this
<< imsi);
237
Ptr<UeInfo>
ueInfo = Create<UeInfo> ();
238
m_ueInfoByImsiMap
[imsi] = ueInfo;
239
}
240
241
void
242
EpcSgwPgwApplication::SetUeAddress
(uint64_t imsi,
Ipv4Address
ueAddr)
243
{
244
NS_LOG_FUNCTION
(
this
<< imsi << ueAddr);
245
std::map<uint64_t, Ptr<UeInfo> >::iterator ueit =
m_ueInfoByImsiMap
.find (imsi);
246
NS_ASSERT_MSG
(ueit !=
m_ueInfoByImsiMap
.end (),
"unknown IMSI "
<< imsi);
247
m_ueInfoByAddrMap
[ueAddr] = ueit->second;
248
ueit->second->SetUeAddr (ueAddr);
249
}
250
251
void
252
EpcSgwPgwApplication::DoCreateSessionRequest
(
EpcS11SapSgw::CreateSessionRequestMessage
req)
253
{
254
NS_LOG_FUNCTION
(
this
<< req.
imsi
);
255
std::map<uint64_t, Ptr<UeInfo> >::iterator ueit =
m_ueInfoByImsiMap
.find (req.
imsi
);
256
NS_ASSERT_MSG
(ueit !=
m_ueInfoByImsiMap
.end (),
"unknown IMSI "
<< req.
imsi
);
257
uint16_t cellId = req.
uli
.gci;
258
std::map<uint16_t, EnbInfo>::iterator enbit =
m_enbInfoByCellId
.find (cellId);
259
NS_ASSERT_MSG
(enbit !=
m_enbInfoByCellId
.end (),
"unknown CellId "
<< cellId);
260
Ipv4Address
enbAddr = enbit->second.enbAddr;
261
ueit->second->SetEnbAddr (enbAddr);
262
263
EpcS11SapMme::CreateSessionResponseMessage
res;
264
res.teid = req.
imsi
;
// trick to avoid the need for allocating TEIDs on the S11 interface
265
266
for
(std::list<EpcS11SapSgw::BearerContextToBeCreated>::iterator bit = req.
bearerContextsToBeCreated
.begin ();
267
bit != req.
bearerContextsToBeCreated
.end ();
268
++bit)
269
{
270
// simple sanity check. If you ever need more than 4M teids
271
// throughout your simulation, you'll need to implement a smarter teid
272
// management algorithm.
273
NS_ABORT_IF
(
m_teidCount
== 0xFFFFFFFF);
274
uint32_t teid = ++
m_teidCount
;
275
ueit->second->AddBearer (bit->tft, bit->epsBearerId, teid);
276
277
EpcS11SapMme::BearerContextCreated
bearerContext;
278
bearerContext.
sgwFteid
.
teid
= teid;
279
bearerContext.
sgwFteid
.
address
= enbit->second.sgwAddr;
280
bearerContext.
epsBearerId
= bit->epsBearerId;
281
bearerContext.
bearerLevelQos
= bit->bearerLevelQos;
282
bearerContext.
tft
= bit->tft;
283
res.
bearerContextsCreated
.push_back (bearerContext);
284
}
285
m_s11SapMme
->
CreateSessionResponse
(res);
286
287
}
288
289
void
290
EpcSgwPgwApplication::DoModifyBearerRequest
(
EpcS11SapSgw::ModifyBearerRequestMessage
req)
291
{
292
NS_LOG_FUNCTION
(
this
<< req.
teid
);
293
uint64_t imsi = req.
teid
;
// trick to avoid the need for allocating TEIDs on the S11 interface
294
std::map<uint64_t, Ptr<UeInfo> >::iterator ueit =
m_ueInfoByImsiMap
.find (imsi);
295
NS_ASSERT_MSG
(ueit !=
m_ueInfoByImsiMap
.end (),
"unknown IMSI "
<< imsi);
296
uint16_t cellId = req.
uli
.
gci
;
297
std::map<uint16_t, EnbInfo>::iterator enbit =
m_enbInfoByCellId
.find (cellId);
298
NS_ASSERT_MSG
(enbit !=
m_enbInfoByCellId
.end (),
"unknown CellId "
<< cellId);
299
Ipv4Address
enbAddr = enbit->second.enbAddr;
300
ueit->second->SetEnbAddr (enbAddr);
301
// no actual bearer modification: for now we just support the minimum needed for path switch request (handover)
302
EpcS11SapMme::ModifyBearerResponseMessage
res;
303
res.teid = imsi;
// trick to avoid the need for allocating TEIDs on the S11 interface
304
res.
cause
=
EpcS11SapMme::ModifyBearerResponseMessage::REQUEST_ACCEPTED
;
305
m_s11SapMme
->
ModifyBearerResponse
(res);
306
}
307
308
};
// namespace ns3
src
lte
model
epc-sgw-pgw-application.cc
Generated on Fri Aug 30 2013 01:42:53 for ns-3 by
1.8.1.2