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, uint32_t teid)
48
{
49
NS_LOG_FUNCTION
(
this
<< tft << teid);
50
return
m_tftClassifier.Add (tft, teid);
51
}
52
53
uint32_t
54
EpcSgwPgwApplication::UeInfo::Classify
(
Ptr<Packet>
p)
55
{
56
NS_LOG_FUNCTION
(
this
<< p);
57
// we hardcode DOWNLINK direction since the PGW is espected to
58
// classify only downlink packets (uplink packets will go to the
59
// internet without any classification).
60
return
m_tftClassifier.Classify (p,
EpcTft::DOWNLINK
);
61
}
62
63
Ipv4Address
64
EpcSgwPgwApplication::UeInfo::GetEnbAddr
()
65
{
66
return
m_enbAddr;
67
}
68
69
void
70
EpcSgwPgwApplication::UeInfo::SetEnbAddr
(
Ipv4Address
enbAddr)
71
{
72
m_enbAddr = enbAddr;
73
}
74
76
// EpcSgwPgwApplication
78
79
80
TypeId
81
EpcSgwPgwApplication::GetTypeId
(
void
)
82
{
83
static
TypeId
tid =
TypeId
(
"ns3::EpcSgwPgwApplication"
)
84
.
SetParent
<
Object
> ();
85
return
tid;
86
}
87
88
void
89
EpcSgwPgwApplication::DoDispose
()
90
{
91
m_s1uSocket
->
SetRecvCallback
(
MakeNullCallback
<
void
,
Ptr<Socket>
> ());
92
m_s1uSocket
= 0;
93
}
94
95
96
97
EpcSgwPgwApplication::EpcSgwPgwApplication
(
const
Ptr<VirtualNetDevice>
tunDevice,
const
Ptr<Socket>
s1uSocket)
98
:
m_s1uSocket
(s1uSocket),
99
m_tunDevice
(tunDevice),
100
m_gtpuUdpPort
(2152),
// fixed by the standard
101
m_teidCount
(0)
102
{
103
NS_LOG_FUNCTION
(
this
<< tunDevice << s1uSocket);
104
m_s1uSocket
->
SetRecvCallback
(
MakeCallback
(&
EpcSgwPgwApplication::RecvFromS1uSocket
,
this
));
105
}
106
107
108
EpcSgwPgwApplication::~EpcSgwPgwApplication
()
109
{
110
NS_LOG_FUNCTION_NOARGS
();
111
}
112
113
114
uint32_t
115
EpcSgwPgwApplication::ActivateS1Bearer
(
Ipv4Address
ueAddr,
Ipv4Address
enbAddr,
Ptr<EpcTft>
tft)
116
{
117
NS_LOG_FUNCTION
(
this
<< ueAddr << enbAddr << tft);
118
119
// simple sanity check. If you ever need more than 4M teids
120
// throughout your simulation, you'll need to implement a smarter teid
121
// management algorithm.
122
NS_ABORT_IF
(
m_teidCount
== 0xFFFFFFFF);
123
uint32_t teid = ++
m_teidCount
;
124
125
std::map<Ipv4Address, UeInfo>::iterator it =
m_ueInfoMap
.find (ueAddr);
126
if
(it ==
m_ueInfoMap
.end ())
127
{
128
// UE unknown, creating new entry
129
std::pair<std::map<Ipv4Address, UeInfo>::iterator,
bool
> ret;
130
ret =
m_ueInfoMap
.insert (std::pair <Ipv4Address, UeInfo> (ueAddr,
UeInfo
()));
131
it = ret.first;
132
it->second.SetEnbAddr (enbAddr);
133
}
134
135
it->second.AddBearer (tft, teid);
136
return
teid;
137
}
138
139
bool
140
EpcSgwPgwApplication::RecvFromTunDevice
(
Ptr<Packet>
packet,
const
Address
& source,
const
Address
& dest, uint16_t protocolNumber)
141
{
142
NS_LOG_FUNCTION
(
this
<< source << dest << packet << packet->
GetSize
());
143
144
// get IP address of UE
145
Ptr<Packet>
pCopy = packet->
Copy
();
146
Ipv4Header
ipv4Header;
147
pCopy->RemoveHeader (ipv4Header);
148
Ipv4Address
ueAddr = ipv4Header.
GetDestination
();
149
NS_LOG_LOGIC
(
"packet addressed to UE "
<< ueAddr);
150
151
// find corresponding UeInfo address
152
std::map<Ipv4Address, UeInfo>::iterator it =
m_ueInfoMap
.find (ueAddr);
153
if
(it ==
m_ueInfoMap
.end ())
154
{
155
NS_LOG_WARN
(
"unknown UE address "
<< ueAddr) ;
156
}
157
else
158
{
159
Ipv4Address
enbAddr = it->second.GetEnbAddr ();
160
uint32_t teid = it->second.Classify (packet);
161
if
(teid == 0)
162
{
163
NS_LOG_WARN
(
"no matching bearer for this packet"
);
164
}
165
else
166
{
167
SendToS1uSocket
(packet, enbAddr, teid);
168
}
169
}
170
// there is no reason why we should notify the TUN
171
// VirtualNetDevice that he failed to send the packet: if we receive
172
// any bogus packet, it will just be silently discarded.
173
const
bool
succeeded =
true
;
174
return
succeeded;
175
}
176
177
void
178
EpcSgwPgwApplication::RecvFromS1uSocket
(
Ptr<Socket>
socket)
179
{
180
NS_LOG_FUNCTION
(
this
<< socket);
181
NS_ASSERT
(socket ==
m_s1uSocket
);
182
Ptr<Packet>
packet = socket->
Recv
();
183
GtpuHeader
gtpu;
184
packet->
RemoveHeader
(gtpu);
185
uint32_t teid = gtpu.
GetTeid
();
186
187
// workaround for bug 231 https://www.nsnam.org/bugzilla/show_bug.cgi?id=231
188
SocketAddressTag
tag;
189
packet->
RemovePacketTag
(tag);
190
191
SendToTunDevice
(packet, teid);
192
}
193
194
void
195
EpcSgwPgwApplication::SendToTunDevice
(
Ptr<Packet>
packet, uint32_t teid)
196
{
197
NS_LOG_FUNCTION
(
this
<< packet << teid);
198
NS_LOG_LOGIC
(
" packet size: "
<< packet->
GetSize
() <<
" bytes"
);
199
m_tunDevice
->
Receive
(packet, 0x0800,
m_tunDevice
->
GetAddress
(),
m_tunDevice
->
GetAddress
(),
NetDevice::PACKET_HOST
);
200
}
201
202
void
203
EpcSgwPgwApplication::SendToS1uSocket
(
Ptr<Packet>
packet,
Ipv4Address
enbAddr, uint32_t teid)
204
{
205
NS_LOG_FUNCTION
(
this
<< packet << enbAddr << teid);
206
207
GtpuHeader
gtpu;
208
gtpu.
SetTeid
(teid);
209
// From 3GPP TS 29.281 v10.0.0 Section 5.1
210
// Length of the payload + the non obligatory GTP-U header
211
gtpu.
SetLength
(packet->
GetSize
() + gtpu.
GetSerializedSize
() - 8);
212
packet->
AddHeader
(gtpu);
213
uint32_t flags = 0;
214
m_s1uSocket
->
SendTo
(packet, flags,
InetSocketAddress
(enbAddr,
m_gtpuUdpPort
));
215
}
216
217
};
// namespace ns3
src
lte
model
epc-sgw-pgw-application.cc
Generated on Tue Oct 9 2012 16:45:40 for ns-3 by
1.8.1.2